* gcc-interface/trans.c (process_freeze_entity): Be prepared for a
[official-gcc.git] / gcc / config / riscv / riscv.md
blobdb4fed48e539743b033ca8b4887782f8f4750911
1 ;; Machine description for RISC-V for GNU compiler.
2 ;; Copyright (C) 2011-2017 Free Software Foundation, Inc.
3 ;; Contributed by Andrew Waterman (andrew@sifive.com).
4 ;; Based on MIPS target for GNU compiler.
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.
22 (define_c_enum "unspec" [
23   ;; Override return address for exception handling.
24   UNSPEC_EH_RETURN
26   ;; Symbolic accesses.  The order of this list must match that of
27   ;; enum riscv_symbol_type in riscv-protos.h.
28   UNSPEC_ADDRESS_FIRST
29   UNSPEC_PCREL
30   UNSPEC_LOAD_GOT
31   UNSPEC_TLS
32   UNSPEC_TLS_LE
33   UNSPEC_TLS_IE
34   UNSPEC_TLS_GD
36   ;; High part of PC-relative address.
37   UNSPEC_AUIPC
39   ;; Floating-point unspecs.
40   UNSPEC_FLT_QUIET
41   UNSPEC_FLE_QUIET
42   UNSPEC_COPYSIGN
43   UNSPEC_LRINT
44   UNSPEC_LROUND
46   ;; Stack tie
47   UNSPEC_TIE
50 (define_c_enum "unspecv" [
51   ;; Register save and restore.
52   UNSPECV_GPR_SAVE
53   UNSPECV_GPR_RESTORE
55   ;; Floating-point unspecs.
56   UNSPECV_FRFLAGS
57   UNSPECV_FSFLAGS
59   ;; Blockage and synchronization.
60   UNSPECV_BLOCKAGE
61   UNSPECV_FENCE
62   UNSPECV_FENCE_I
65 (define_constants
66   [(RETURN_ADDR_REGNUM          1)
67    (T0_REGNUM                   5)
68    (T1_REGNUM                   6)
69    (S0_REGNUM                   8)
70    (S1_REGNUM                   9)
71    (S2_REGNUM                   18)
74 (include "predicates.md")
75 (include "constraints.md")
77 ;; ....................
79 ;;      Attributes
81 ;; ....................
83 (define_attr "got" "unset,xgot_high,load"
84   (const_string "unset"))
86 ;; Classification of moves, extensions and truncations.  Most values
87 ;; are as for "type" (see below) but there are also the following
88 ;; move-specific values:
90 ;; andi         a single ANDI instruction
91 ;; shift_shift  a shift left followed by a shift right
93 ;; This attribute is used to determine the instruction's length and
94 ;; scheduling type.  For doubleword moves, the attribute always describes
95 ;; the split instructions; in some cases, it is more appropriate for the
96 ;; scheduling type to be "multi" instead.
97 (define_attr "move_type"
98   "unknown,load,fpload,store,fpstore,mtc,mfc,move,fmove,
99    const,logical,arith,andi,shift_shift"
100   (const_string "unknown"))
102 ;; Main data type used by the insn
103 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
104   (const_string "unknown"))
106 ;; True if the main data type is twice the size of a word.
107 (define_attr "dword_mode" "no,yes"
108   (cond [(and (eq_attr "mode" "DI,DF")
109               (eq (symbol_ref "TARGET_64BIT") (const_int 0)))
110          (const_string "yes")
112          (and (eq_attr "mode" "TI,TF")
113               (ne (symbol_ref "TARGET_64BIT") (const_int 0)))
114          (const_string "yes")]
115         (const_string "no")))
117 ;; Classification of each insn.
118 ;; branch       conditional branch
119 ;; jump         unconditional jump
120 ;; call         unconditional call
121 ;; load         load instruction(s)
122 ;; fpload       floating point load
123 ;; store        store instruction(s)
124 ;; fpstore      floating point store
125 ;; mtc          transfer to coprocessor
126 ;; mfc          transfer from coprocessor
127 ;; const        load constant
128 ;; arith        integer arithmetic instructions
129 ;; logical      integer logical instructions
130 ;; shift        integer shift instructions
131 ;; slt          set less than instructions
132 ;; imul         integer multiply 
133 ;; idiv         integer divide
134 ;; move         integer register move (addi rd, rs1, 0)
135 ;; fmove        floating point register move
136 ;; fadd         floating point add/subtract
137 ;; fmul         floating point multiply
138 ;; fmadd        floating point multiply-add
139 ;; fdiv         floating point divide
140 ;; fcmp         floating point compare
141 ;; fcvt         floating point convert
142 ;; fsqrt        floating point square root
143 ;; multi        multiword sequence (or user asm statements)
144 ;; nop          no operation
145 ;; ghost        an instruction that produces no real code
146 (define_attr "type"
147   "unknown,branch,jump,call,load,fpload,store,fpstore,
148    mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul,
149    fmadd,fdiv,fcmp,fcvt,fsqrt,multi,nop,ghost"
150   (cond [(eq_attr "got" "load") (const_string "load")
152          ;; If a doubleword move uses these expensive instructions,
153          ;; it is usually better to schedule them in the same way
154          ;; as the singleword form, rather than as "multi".
155          (eq_attr "move_type" "load") (const_string "load")
156          (eq_attr "move_type" "fpload") (const_string "fpload")
157          (eq_attr "move_type" "store") (const_string "store")
158          (eq_attr "move_type" "fpstore") (const_string "fpstore")
159          (eq_attr "move_type" "mtc") (const_string "mtc")
160          (eq_attr "move_type" "mfc") (const_string "mfc")
162          ;; These types of move are always single insns.
163          (eq_attr "move_type" "fmove") (const_string "fmove")
164          (eq_attr "move_type" "arith") (const_string "arith")
165          (eq_attr "move_type" "logical") (const_string "logical")
166          (eq_attr "move_type" "andi") (const_string "logical")
168          ;; These types of move are always split.
169          (eq_attr "move_type" "shift_shift")
170            (const_string "multi")
172          ;; These types of move are split for doubleword modes only.
173          (and (eq_attr "move_type" "move,const")
174               (eq_attr "dword_mode" "yes"))
175            (const_string "multi")
176          (eq_attr "move_type" "move") (const_string "move")
177          (eq_attr "move_type" "const") (const_string "const")]
178         (const_string "unknown")))
180 ;; Length of instruction in bytes.
181 (define_attr "length" ""
182    (cond [
183           ;; Branches further than +/- 4 KiB require two instructions.
184           (eq_attr "type" "branch")
185           (if_then_else (and (le (minus (match_dup 0) (pc)) (const_int 4088))
186                                   (le (minus (pc) (match_dup 0)) (const_int 4092)))
187           (const_int 4)
188           (const_int 8))
190           ;; Conservatively assume calls take two instructions (AUIPC + JALR).
191           ;; The linker will opportunistically relax the sequence to JAL.
192           (eq_attr "type" "call") (const_int 8)
194           ;; "Ghost" instructions occupy no space.
195           (eq_attr "type" "ghost") (const_int 0)
197           (eq_attr "got" "load") (const_int 8)
199           (eq_attr "type" "fcmp") (const_int 8)
201           ;; SHIFT_SHIFTs are decomposed into two separate instructions.
202           (eq_attr "move_type" "shift_shift")
203                 (const_int 8)
205           ;; Check for doubleword moves that are decomposed into two
206           ;; instructions.
207           (and (eq_attr "move_type" "mtc,mfc,move")
208                (eq_attr "dword_mode" "yes"))
209           (const_int 8)
211           ;; Doubleword CONST{,N} moves are split into two word
212           ;; CONST{,N} moves.
213           (and (eq_attr "move_type" "const")
214                (eq_attr "dword_mode" "yes"))
215           (symbol_ref "riscv_split_const_insns (operands[1]) * 4")
217           ;; Otherwise, constants, loads and stores are handled by external
218           ;; routines.
219           (eq_attr "move_type" "load,fpload")
220           (symbol_ref "riscv_load_store_insns (operands[1], insn) * 4")
221           (eq_attr "move_type" "store,fpstore")
222           (symbol_ref "riscv_load_store_insns (operands[0], insn) * 4")
223           ] (const_int 4)))
225 ;; Is copying of this instruction disallowed?
226 (define_attr "cannot_copy" "no,yes" (const_string "no"))
228 ;; Describe a user's asm statement.
229 (define_asm_attributes
230   [(set_attr "type" "multi")])
232 ;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
233 ;; from the same template.
234 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
236 ;; This mode iterator allows :P to be used for patterns that operate on
237 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
238 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
240 ;; Likewise, but for XLEN-sized quantities.
241 (define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")])
243 ;; Branches operate on XLEN-sized quantities, but for RV64 we accept
244 ;; QImode values so we can force zero-extension.
245 (define_mode_iterator BR [(QI "TARGET_64BIT") SI (DI "TARGET_64BIT")])
247 ;; 32-bit moves for which we provide move patterns.
248 (define_mode_iterator MOVE32 [SI])
250 ;; 64-bit modes for which we provide move patterns.
251 (define_mode_iterator MOVE64 [DI DF])
253 ;; Iterator for sub-32-bit integer modes.
254 (define_mode_iterator SHORT [QI HI])
256 ;; Iterator for HImode constant generation.
257 (define_mode_iterator HISI [HI SI])
259 ;; Iterator for QImode extension patterns.
260 (define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")])
262 ;; Iterator for extending loads.
263 (define_mode_iterator ZERO_EXTEND_LOAD [QI HI (SI "TARGET_64BIT")])
265 ;; Iterator for hardware integer modes narrower than XLEN.
266 (define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")])
268 ;; Iterator for hardware-supported integer modes.
269 (define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")])
271 ;; Iterator for hardware-supported floating-point modes.
272 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
273                             (DF "TARGET_DOUBLE_FLOAT")])
275 ;; This attribute gives the length suffix for a sign- or zero-extension
276 ;; instruction.
277 (define_mode_attr size [(QI "b") (HI "h")])
279 ;; Mode attributes for loads.
280 (define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")])
282 ;; Instruction names for stores.
283 (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")])
285 ;; This attribute gives the best constraint to use for registers of
286 ;; a given mode.
287 (define_mode_attr reg [(SI "d") (DI "d") (CC "d")])
289 ;; This attribute gives the format suffix for floating-point operations.
290 (define_mode_attr fmt [(SF "s") (DF "d")])
292 ;; This attribute gives the integer suffix for floating-point conversions.
293 (define_mode_attr ifmt [(SI "w") (DI "l")])
295 ;; This attribute gives the format suffix for atomic memory operations.
296 (define_mode_attr amo [(SI "w") (DI "d")])
298 ;; This attribute gives the upper-case mode name for one unit of a
299 ;; floating-point mode.
300 (define_mode_attr UNITMODE [(SF "SF") (DF "DF")])
302 ;; This attribute gives the integer mode that has half the size of
303 ;; the controlling mode.
304 (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
306 ;; Iterator and attributes for floating-point rounding instructions.
307 (define_int_iterator RINT [UNSPEC_LRINT UNSPEC_LROUND])
308 (define_int_attr rint_pattern [(UNSPEC_LRINT "rint") (UNSPEC_LROUND "round")])
309 (define_int_attr rint_rm [(UNSPEC_LRINT "dyn") (UNSPEC_LROUND "rmm")])
311 ;; Iterator and attributes for quiet comparisons.
312 (define_int_iterator QUIET_COMPARISON [UNSPEC_FLT_QUIET UNSPEC_FLE_QUIET])
313 (define_int_attr quiet_pattern [(UNSPEC_FLT_QUIET "lt") (UNSPEC_FLE_QUIET "le")])
315 ;; This code iterator allows signed and unsigned widening multiplications
316 ;; to use the same template.
317 (define_code_iterator any_extend [sign_extend zero_extend])
319 ;; This code iterator allows the two right shift instructions to be
320 ;; generated from the same template.
321 (define_code_iterator any_shiftrt [ashiftrt lshiftrt])
323 ;; This code iterator allows the three shift instructions to be generated
324 ;; from the same template.
325 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
327 ;; This code iterator allows the three bitwise instructions to be generated
328 ;; from the same template.
329 (define_code_iterator any_bitwise [and ior xor])
331 ;; This code iterator allows unsigned and signed division to be generated
332 ;; from the same template.
333 (define_code_iterator any_div [div udiv mod umod])
335 ;; This code iterator allows unsigned and signed modulus to be generated
336 ;; from the same template.
337 (define_code_iterator any_mod [mod umod])
339 ;; These code iterators allow the signed and unsigned scc operations to use
340 ;; the same template.
341 (define_code_iterator any_gt [gt gtu])
342 (define_code_iterator any_ge [ge geu])
343 (define_code_iterator any_lt [lt ltu])
344 (define_code_iterator any_le [le leu])
346 ;; <u> expands to an empty string when doing a signed operation and
347 ;; "u" when doing an unsigned operation.
348 (define_code_attr u [(sign_extend "") (zero_extend "u")
349                      (gt "") (gtu "u")
350                      (ge "") (geu "u")
351                      (lt "") (ltu "u")
352                      (le "") (leu "u")])
354 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
355 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
357 ;; <optab> expands to the name of the optab for a particular code.
358 (define_code_attr optab [(ashift "ashl")
359                          (ashiftrt "ashr")
360                          (lshiftrt "lshr")
361                          (div "div")
362                          (mod "mod")
363                          (udiv "udiv")
364                          (umod "umod")
365                          (ge "ge")
366                          (le "le")
367                          (gt "gt")
368                          (lt "lt")
369                          (ior "ior")
370                          (xor "xor")
371                          (and "and")
372                          (plus "add")
373                          (minus "sub")])
375 ;; <insn> expands to the name of the insn that implements a particular code.
376 (define_code_attr insn [(ashift "sll")
377                         (ashiftrt "sra")
378                         (lshiftrt "srl")
379                         (div "div")
380                         (mod "rem")
381                         (udiv "divu")
382                         (umod "remu")
383                         (ior "or")
384                         (xor "xor")
385                         (and "and")
386                         (plus "add")
387                         (minus "sub")])
389 ;; Ghost instructions produce no real code and introduce no hazards.
390 ;; They exist purely to express an effect on dataflow.
391 (define_insn_reservation "ghost" 0
392   (eq_attr "type" "ghost")
393   "nothing")
396 ;;  ....................
398 ;;      ADDITION
400 ;;  ....................
403 (define_insn "add<mode>3"
404   [(set (match_operand:ANYF            0 "register_operand" "=f")
405         (plus:ANYF (match_operand:ANYF 1 "register_operand" " f")
406                    (match_operand:ANYF 2 "register_operand" " f")))]
407   "TARGET_HARD_FLOAT"
408   "fadd.<fmt>\t%0,%1,%2"
409   [(set_attr "type" "fadd")
410    (set_attr "mode" "<UNITMODE>")])
412 (define_insn "addsi3"
413   [(set (match_operand:SI          0 "register_operand" "=r,r")
414         (plus:SI (match_operand:SI 1 "register_operand" " r,r")
415                  (match_operand:SI 2 "arith_operand"    " r,I")))]
416   ""
417   { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
418   [(set_attr "type" "arith")
419    (set_attr "mode" "SI")])
421 (define_insn "adddi3"
422   [(set (match_operand:DI          0 "register_operand" "=r,r")
423         (plus:DI (match_operand:DI 1 "register_operand" " r,r")
424                  (match_operand:DI 2 "arith_operand"    " r,I")))]
425   "TARGET_64BIT"
426   "add%i2\t%0,%1,%2"
427   [(set_attr "type" "arith")
428    (set_attr "mode" "DI")])
430 (define_insn "*addsi3_extended"
431   [(set (match_operand:DI               0 "register_operand" "=r,r")
432         (sign_extend:DI
433              (plus:SI (match_operand:SI 1 "register_operand" " r,r")
434                       (match_operand:SI 2 "arith_operand"    " r,I"))))]
435   "TARGET_64BIT"
436   "add%i2w\t%0,%1,%2"
437   [(set_attr "type" "arith")
438    (set_attr "mode" "SI")])
440 (define_insn "*addsi3_extended2"
441   [(set (match_operand:DI                       0 "register_operand" "=r,r")
442         (sign_extend:DI
443           (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" " r,r")
444                               (match_operand:DI 2 "arith_operand"    " r,I"))
445                      0)))]
446   "TARGET_64BIT"
447   "add%i2w\t%0,%1,%2"
448   [(set_attr "type" "arith")
449    (set_attr "mode" "SI")])
452 ;;  ....................
454 ;;      SUBTRACTION
456 ;;  ....................
459 (define_insn "sub<mode>3"
460   [(set (match_operand:ANYF             0 "register_operand" "=f")
461         (minus:ANYF (match_operand:ANYF 1 "register_operand" " f")
462                     (match_operand:ANYF 2 "register_operand" " f")))]
463   "TARGET_HARD_FLOAT"
464   "fsub.<fmt>\t%0,%1,%2"
465   [(set_attr "type" "fadd")
466    (set_attr "mode" "<UNITMODE>")])
468 (define_insn "subdi3"
469   [(set (match_operand:DI 0            "register_operand" "= r")
470         (minus:DI (match_operand:DI 1  "reg_or_0_operand" " rJ")
471                    (match_operand:DI 2 "register_operand" "  r")))]
472   "TARGET_64BIT"
473   "sub\t%0,%z1,%2"
474   [(set_attr "type" "arith")
475    (set_attr "mode" "DI")])
477 (define_insn "subsi3"
478   [(set (match_operand:SI           0 "register_operand" "= r")
479         (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
480                   (match_operand:SI 2 "register_operand" "  r")))]
481   ""
482   { return TARGET_64BIT ? "subw\t%0,%z1,%2" : "sub\t%0,%z1,%2"; }
483   [(set_attr "type" "arith")
484    (set_attr "mode" "SI")])
486 (define_insn "*subsi3_extended"
487   [(set (match_operand:DI               0 "register_operand" "= r")
488         (sign_extend:DI
489             (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
490                       (match_operand:SI 2 "register_operand" "  r"))))]
491   "TARGET_64BIT"
492   "subw\t%0,%z1,%2"
493   [(set_attr "type" "arith")
494    (set_attr "mode" "SI")])
496 (define_insn "*subsi3_extended2"
497   [(set (match_operand:DI                        0 "register_operand" "=r")
498         (sign_extend:DI
499           (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" " r")
500                                (match_operand:DI 2 "register_operand" " r"))
501                      0)))]
502   "TARGET_64BIT"
503   "subw\t%0,%z1,%2"
504   [(set_attr "type" "arith")
505    (set_attr "mode" "SI")])
508 ;;  ....................
510 ;;      MULTIPLICATION
512 ;;  ....................
515 (define_insn "mul<mode>3"
516   [(set (match_operand:ANYF               0 "register_operand" "=f")
517         (mult:ANYF (match_operand:ANYF    1 "register_operand" " f")
518                       (match_operand:ANYF 2 "register_operand" " f")))]
519   "TARGET_HARD_FLOAT"
520   "fmul.<fmt>\t%0,%1,%2"
521   [(set_attr "type" "fmul")
522    (set_attr "mode" "<UNITMODE>")])
524 (define_insn "mulsi3"
525   [(set (match_operand:SI          0 "register_operand" "=r")
526         (mult:SI (match_operand:SI 1 "register_operand" " r")
527                  (match_operand:SI 2 "register_operand" " r")))]
528   "TARGET_MUL"
529   { return TARGET_64BIT ? "mulw\t%0,%1,%2" : "mul\t%0,%1,%2"; }
530   [(set_attr "type" "imul")
531    (set_attr "mode" "SI")])
533 (define_insn "muldi3"
534   [(set (match_operand:DI          0 "register_operand" "=r")
535         (mult:DI (match_operand:DI 1 "register_operand" " r")
536                  (match_operand:DI 2 "register_operand" " r")))]
537   "TARGET_MUL && TARGET_64BIT"
538   "mul\t%0,%1,%2"
539   [(set_attr "type" "imul")
540    (set_attr "mode" "DI")])
542 (define_insn "*mulsi3_extended"
543   [(set (match_operand:DI              0 "register_operand" "=r")
544         (sign_extend:DI
545             (mult:SI (match_operand:SI 1 "register_operand" " r")
546                      (match_operand:SI 2 "register_operand" " r"))))]
547   "TARGET_MUL && TARGET_64BIT"
548   "mulw\t%0,%1,%2"
549   [(set_attr "type" "imul")
550    (set_attr "mode" "SI")])
552 (define_insn "*mulsi3_extended2"
553   [(set (match_operand:DI                       0 "register_operand" "=r")
554         (sign_extend:DI
555           (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" " r")
556                               (match_operand:DI 2 "register_operand" " r"))
557                      0)))]
558   "TARGET_MUL && TARGET_64BIT"
559   "mulw\t%0,%1,%2"
560   [(set_attr "type" "imul")
561    (set_attr "mode" "SI")])
564 ;;  ........................
566 ;;      MULTIPLICATION HIGH-PART
568 ;;  ........................
572 (define_expand "<u>mulditi3"
573   [(set (match_operand:TI                         0 "register_operand")
574         (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
575                  (any_extend:TI (match_operand:DI 2 "register_operand"))))]
576   "TARGET_MUL && TARGET_64BIT"
578   rtx low = gen_reg_rtx (DImode);
579   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
581   rtx high = gen_reg_rtx (DImode);
582   emit_insn (gen_<u>muldi3_highpart (high, operands[1], operands[2]));
584   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
585   emit_move_insn (gen_highpart (DImode, operands[0]), high);
586   DONE;
589 (define_insn "<u>muldi3_highpart"
590   [(set (match_operand:DI                0 "register_operand" "=r")
591         (truncate:DI
592           (lshiftrt:TI
593             (mult:TI (any_extend:TI
594                        (match_operand:DI 1 "register_operand" " r"))
595                      (any_extend:TI
596                        (match_operand:DI 2 "register_operand" " r")))
597             (const_int 64))))]
598   "TARGET_MUL && TARGET_64BIT"
599   "mulh<u>\t%0,%1,%2"
600   [(set_attr "type" "imul")
601    (set_attr "mode" "DI")])
603 (define_expand "usmulditi3"
604   [(set (match_operand:TI                          0 "register_operand")
605         (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand"))
606                  (sign_extend:TI (match_operand:DI 2 "register_operand"))))]
607   "TARGET_MUL && TARGET_64BIT"
609   rtx low = gen_reg_rtx (DImode);
610   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
612   rtx high = gen_reg_rtx (DImode);
613   emit_insn (gen_usmuldi3_highpart (high, operands[1], operands[2]));
615   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
616   emit_move_insn (gen_highpart (DImode, operands[0]), high);
617   DONE;
620 (define_insn "usmuldi3_highpart"
621   [(set (match_operand:DI                0 "register_operand" "=r")
622         (truncate:DI
623           (lshiftrt:TI
624             (mult:TI (zero_extend:TI
625                        (match_operand:DI 1 "register_operand"  "r"))
626                      (sign_extend:TI
627                        (match_operand:DI 2 "register_operand" " r")))
628             (const_int 64))))]
629   "TARGET_MUL && TARGET_64BIT"
630   "mulhsu\t%0,%2,%1"
631   [(set_attr "type" "imul")
632    (set_attr "mode" "DI")])
634 (define_expand "<u>mulsidi3"
635   [(set (match_operand:DI            0 "register_operand" "=r")
636         (mult:DI (any_extend:DI
637                    (match_operand:SI 1 "register_operand" " r"))
638                  (any_extend:DI
639                    (match_operand:SI 2 "register_operand" " r"))))]
640   "TARGET_MUL && !TARGET_64BIT"
642   rtx temp = gen_reg_rtx (SImode);
643   emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
644   emit_insn (gen_<u>mulsi3_highpart (riscv_subword (operands[0], true),
645                                      operands[1], operands[2]));
646   emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
647   DONE;
650 (define_insn "<u>mulsi3_highpart"
651   [(set (match_operand:SI                0 "register_operand" "=r")
652         (truncate:SI
653           (lshiftrt:DI
654             (mult:DI (any_extend:DI
655                        (match_operand:SI 1 "register_operand" " r"))
656                      (any_extend:DI
657                        (match_operand:SI 2 "register_operand" " r")))
658             (const_int 32))))]
659   "TARGET_MUL && !TARGET_64BIT"
660   "mulh<u>\t%0,%1,%2"
661   [(set_attr "type" "imul")
662    (set_attr "mode" "SI")])
665 (define_expand "usmulsidi3"
666   [(set (match_operand:DI            0 "register_operand" "=r")
667         (mult:DI (zero_extend:DI
668                    (match_operand:SI 1 "register_operand" " r"))
669                  (sign_extend:DI
670                    (match_operand:SI 2 "register_operand" " r"))))]
671   "TARGET_MUL && !TARGET_64BIT"
673   rtx temp = gen_reg_rtx (SImode);
674   emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
675   emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true),
676                                      operands[1], operands[2]));
677   emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
678   DONE;
681 (define_insn "usmulsi3_highpart"
682   [(set (match_operand:SI                0 "register_operand" "=r")
683         (truncate:SI
684           (lshiftrt:DI
685             (mult:DI (zero_extend:DI
686                        (match_operand:SI 1 "register_operand" " r"))
687                      (sign_extend:DI
688                        (match_operand:SI 2 "register_operand" " r")))
689             (const_int 32))))]
690   "TARGET_MUL && !TARGET_64BIT"
691   "mulhsu\t%0,%2,%1"
692   [(set_attr "type" "imul")
693    (set_attr "mode" "SI")])
696 ;;  ....................
698 ;;      DIVISION and REMAINDER
700 ;;  ....................
703 (define_insn "<optab>si3"
704   [(set (match_operand:SI             0 "register_operand" "=r")
705         (any_div:SI (match_operand:SI 1 "register_operand" " r")
706                     (match_operand:SI 2 "register_operand" " r")))]
707   "TARGET_DIV"
708   { return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2"; }
709   [(set_attr "type" "idiv")
710    (set_attr "mode" "SI")])
712 (define_insn "<optab>di3"
713   [(set (match_operand:DI             0 "register_operand" "=r")
714         (any_div:DI (match_operand:DI 1 "register_operand" " r")
715                     (match_operand:DI 2 "register_operand" " r")))]
716   "TARGET_DIV && TARGET_64BIT"
717   "<insn>%i2\t%0,%1,%2"
718   [(set_attr "type" "idiv")
719    (set_attr "mode" "DI")])
721 (define_insn "*<optab>si3_extended"
722   [(set (match_operand:DI                 0 "register_operand" "=r")
723         (sign_extend:DI
724             (any_div:SI (match_operand:SI 1 "register_operand" " r")
725                         (match_operand:SI 2 "register_operand" " r"))))]
726   "TARGET_DIV && TARGET_64BIT"
727   "<insn>%i2w\t%0,%1,%2"
728   [(set_attr "type" "idiv")
729    (set_attr "mode" "DI")])
731 (define_insn "div<mode>3"
732   [(set (match_operand:ANYF           0 "register_operand" "=f")
733         (div:ANYF (match_operand:ANYF 1 "register_operand" " f")
734                   (match_operand:ANYF 2 "register_operand" " f")))]
735   "TARGET_HARD_FLOAT && TARGET_FDIV"
736   "fdiv.<fmt>\t%0,%1,%2"
737   [(set_attr "type" "fdiv")
738    (set_attr "mode" "<UNITMODE>")])
741 ;;  ....................
743 ;;      SQUARE ROOT
745 ;;  ....................
747 (define_insn "sqrt<mode>2"
748   [(set (match_operand:ANYF            0 "register_operand" "=f")
749         (sqrt:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
750   "TARGET_HARD_FLOAT && TARGET_FDIV"
752     return "fsqrt.<fmt>\t%0,%1";
754   [(set_attr "type" "fsqrt")
755    (set_attr "mode" "<UNITMODE>")])
757 ;; Floating point multiply accumulate instructions.
759 ;; a * b + c
760 (define_insn "fma<mode>4"
761   [(set (match_operand:ANYF           0 "register_operand" "=f")
762         (fma:ANYF (match_operand:ANYF 1 "register_operand" " f")
763                   (match_operand:ANYF 2 "register_operand" " f")
764                   (match_operand:ANYF 3 "register_operand" " f")))]
765   "TARGET_HARD_FLOAT"
766   "fmadd.<fmt>\t%0,%1,%2,%3"
767   [(set_attr "type" "fmadd")
768    (set_attr "mode" "<UNITMODE>")])
770 ;; a * b - c
771 (define_insn "fms<mode>4"
772   [(set (match_operand:ANYF                     0 "register_operand" "=f")
773         (fma:ANYF (match_operand:ANYF           1 "register_operand" " f")
774                   (match_operand:ANYF           2 "register_operand" " f")
775                   (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
776   "TARGET_HARD_FLOAT"
777   "fmsub.<fmt>\t%0,%1,%2,%3"
778   [(set_attr "type" "fmadd")
779    (set_attr "mode" "<UNITMODE>")])
781 ;; -a * b - c
782 (define_insn "fnms<mode>4"
783   [(set (match_operand:ANYF               0 "register_operand" "=f")
784         (fma:ANYF
785             (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
786             (match_operand:ANYF           2 "register_operand" " f")
787             (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
788   "TARGET_HARD_FLOAT"
789   "fnmadd.<fmt>\t%0,%1,%2,%3"
790   [(set_attr "type" "fmadd")
791    (set_attr "mode" "<UNITMODE>")])
793 ;; -a * b + c
794 (define_insn "fnma<mode>4"
795   [(set (match_operand:ANYF               0 "register_operand" "=f")
796         (fma:ANYF
797             (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
798             (match_operand:ANYF           2 "register_operand" " f")
799             (match_operand:ANYF           3 "register_operand" " f")))]
800   "TARGET_HARD_FLOAT"
801   "fnmsub.<fmt>\t%0,%1,%2,%3"
802   [(set_attr "type" "fmadd")
803    (set_attr "mode" "<UNITMODE>")])
805 ;; -(-a * b - c), modulo signed zeros
806 (define_insn "*fma<mode>4"
807   [(set (match_operand:ANYF                   0 "register_operand" "=f")
808         (neg:ANYF
809             (fma:ANYF
810                 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
811                 (match_operand:ANYF           2 "register_operand" " f")
812                 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
813   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
814   "fmadd.<fmt>\t%0,%1,%2,%3"
815   [(set_attr "type" "fmadd")
816    (set_attr "mode" "<UNITMODE>")])
818 ;; -(-a * b + c), modulo signed zeros
819 (define_insn "*fms<mode>4"
820   [(set (match_operand:ANYF                   0 "register_operand" "=f")
821         (neg:ANYF
822             (fma:ANYF
823                 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
824                 (match_operand:ANYF           2 "register_operand" " f")
825                 (match_operand:ANYF           3 "register_operand" " f"))))]
826   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
827   "fmsub.<fmt>\t%0,%1,%2,%3"
828   [(set_attr "type" "fmadd")
829    (set_attr "mode" "<UNITMODE>")])
831 ;; -(a * b + c), modulo signed zeros
832 (define_insn "*fnms<mode>4"
833   [(set (match_operand:ANYF         0 "register_operand" "=f")
834         (neg:ANYF
835             (fma:ANYF
836                 (match_operand:ANYF 1 "register_operand" " f")
837                 (match_operand:ANYF 2 "register_operand" " f")
838                 (match_operand:ANYF 3 "register_operand" " f"))))]
839   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
840   "fnmadd.<fmt>\t%0,%1,%2,%3"
841   [(set_attr "type" "fmadd")
842    (set_attr "mode" "<UNITMODE>")])
844 ;; -(a * b - c), modulo signed zeros
845 (define_insn "*fnma<mode>4"
846   [(set (match_operand:ANYF                   0 "register_operand" "=f")
847         (neg:ANYF
848             (fma:ANYF
849                 (match_operand:ANYF           1 "register_operand" " f")
850                 (match_operand:ANYF           2 "register_operand" " f")
851                 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
852   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
853   "fnmsub.<fmt>\t%0,%1,%2,%3"
854   [(set_attr "type" "fmadd")
855    (set_attr "mode" "<UNITMODE>")])
858 ;;  ....................
860 ;;      SIGN INJECTION
862 ;;  ....................
864 (define_insn "abs<mode>2"
865   [(set (match_operand:ANYF           0 "register_operand" "=f")
866         (abs:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
867   "TARGET_HARD_FLOAT"
868   "fabs.<fmt>\t%0,%1"
869   [(set_attr "type" "fmove")
870    (set_attr "mode" "<UNITMODE>")])
872 (define_insn "copysign<mode>3"
873   [(set (match_operand:ANYF 0 "register_operand"               "=f")
874         (unspec:ANYF [(match_operand:ANYF 1 "register_operand" " f")
875                       (match_operand:ANYF 2 "register_operand" " f")]
876                      UNSPEC_COPYSIGN))]
877   "TARGET_HARD_FLOAT"
878   "fsgnj.<fmt>\t%0,%1,%2"
879   [(set_attr "type" "fmove")
880    (set_attr "mode" "<UNITMODE>")])
882 (define_insn "neg<mode>2"
883   [(set (match_operand:ANYF           0 "register_operand" "=f")
884         (neg:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
885   "TARGET_HARD_FLOAT"
886   "fneg.<fmt>\t%0,%1"
887   [(set_attr "type" "fmove")
888    (set_attr "mode" "<UNITMODE>")])
891 ;;  ....................
893 ;;      MIN/MAX
895 ;;  ....................
897 (define_insn "smin<mode>3"
898   [(set (match_operand:ANYF            0 "register_operand" "=f")
899         (smin:ANYF (match_operand:ANYF 1 "register_operand" " f")
900                    (match_operand:ANYF 2 "register_operand" " f")))]
901   "TARGET_HARD_FLOAT"
902   "fmin.<fmt>\t%0,%1,%2"
903   [(set_attr "type" "fmove")
904    (set_attr "mode" "<UNITMODE>")])
906 (define_insn "smax<mode>3"
907   [(set (match_operand:ANYF            0 "register_operand" "=f")
908         (smax:ANYF (match_operand:ANYF 1 "register_operand" " f")
909                    (match_operand:ANYF 2 "register_operand" " f")))]
910   "TARGET_HARD_FLOAT"
911   "fmax.<fmt>\t%0,%1,%2"
912   [(set_attr "type" "fmove")
913    (set_attr "mode" "<UNITMODE>")])
916 ;;  ....................
918 ;;      LOGICAL
920 ;;  ....................
923 ;; For RV64, we don't expose the SImode operations to the rtl expanders,
924 ;; but SImode versions exist for combine.
926 (define_insn "<optab><mode>3"
927   [(set (match_operand:X                0 "register_operand" "=r,r")
928         (any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
929                        (match_operand:X 2 "arith_operand"    " r,I")))]
930   ""
931   "<insn>%i2\t%0,%1,%2"
932   [(set_attr "type" "logical")
933    (set_attr "mode" "<MODE>")])
935 (define_insn "*<optab>si3_internal"
936   [(set (match_operand:SI                 0 "register_operand" "=r,r")
937         (any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r")
938                         (match_operand:SI 2 "arith_operand"    " r,I")))]
939   "TARGET_64BIT"
940   "<insn>%i2\t%0,%1,%2"
941   [(set_attr "type" "logical")
942    (set_attr "mode" "SI")])
944 (define_insn "one_cmpl<mode>2"
945   [(set (match_operand:X        0 "register_operand" "=r")
946         (not:X (match_operand:X 1 "register_operand" " r")))]
947   ""
948   "not\t%0,%1"
949   [(set_attr "type" "logical")
950    (set_attr "mode" "<MODE>")])
952 (define_insn "*one_cmplsi2_internal"
953   [(set (match_operand:SI         0 "register_operand" "=r")
954         (not:SI (match_operand:SI 1 "register_operand" " r")))]
955   "TARGET_64BIT"
956   "not\t%0,%1"
957   [(set_attr "type" "logical")
958    (set_attr "mode" "SI")])
961 ;;  ....................
963 ;;      TRUNCATION
965 ;;  ....................
967 (define_insn "truncdfsf2"
968   [(set (match_operand:SF     0 "register_operand" "=f")
969         (float_truncate:SF
970             (match_operand:DF 1 "register_operand" " f")))]
971   "TARGET_DOUBLE_FLOAT"
972   "fcvt.s.d\t%0,%1"
973   [(set_attr "type" "fcvt")
974    (set_attr "mode" "SF")])
977 ;;  ....................
979 ;;      ZERO EXTENSION
981 ;;  ....................
983 ;; Extension insns.
985 (define_insn_and_split "zero_extendsidi2"
986   [(set (match_operand:DI     0 "register_operand"     "=r,r")
987         (zero_extend:DI
988             (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
989   "TARGET_64BIT"
990   "@
991    #
992    lwu\t%0,%1"
993   "&& reload_completed && REG_P (operands[1])"
994   [(set (match_dup 0)
995         (ashift:DI (match_dup 1) (const_int 32)))
996    (set (match_dup 0)
997         (lshiftrt:DI (match_dup 0) (const_int 32)))]
998   { operands[1] = gen_lowpart (DImode, operands[1]); }
999   [(set_attr "move_type" "shift_shift,load")
1000    (set_attr "mode" "DI")])
1002 (define_insn_and_split "zero_extendhi<GPR:mode>2"
1003   [(set (match_operand:GPR    0 "register_operand"     "=r,r")
1004         (zero_extend:GPR
1005             (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
1006   ""
1007   "@
1008    #
1009    lhu\t%0,%1"
1010   "&& reload_completed && REG_P (operands[1])"
1011   [(set (match_dup 0)
1012         (ashift:GPR (match_dup 1) (match_dup 2)))
1013    (set (match_dup 0)
1014         (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
1015   {
1016     operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
1017     operands[2] = GEN_INT(GET_MODE_BITSIZE(<GPR:MODE>mode) - 16);
1018   }
1019   [(set_attr "move_type" "shift_shift,load")
1020    (set_attr "mode" "<GPR:MODE>")])
1022 (define_insn "zero_extendqi<SUPERQI:mode>2"
1023   [(set (match_operand:SUPERQI 0 "register_operand"    "=r,r")
1024         (zero_extend:SUPERQI
1025             (match_operand:QI 1 "nonimmediate_operand" " r,m")))]
1026   ""
1027   "@
1028    andi\t%0,%1,0xff
1029    lbu\t%0,%1"
1030   [(set_attr "move_type" "andi,load")
1031    (set_attr "mode" "<SUPERQI:MODE>")])
1034 ;;  ....................
1036 ;;      SIGN EXTENSION
1038 ;;  ....................
1040 (define_insn "extendsidi2"
1041   [(set (match_operand:DI     0 "register_operand"     "=r,r")
1042         (sign_extend:DI
1043             (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
1044   "TARGET_64BIT"
1045   "@
1046    sext.w\t%0,%1
1047    lw\t%0,%1"
1048   [(set_attr "move_type" "move,load")
1049    (set_attr "mode" "DI")])
1051 (define_insn_and_split "extend<SHORT:mode><SUPERQI:mode>2"
1052   [(set (match_operand:SUPERQI   0 "register_operand"     "=r,r")
1053         (sign_extend:SUPERQI
1054             (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
1055   ""
1056   "@
1057    #
1058    l<SHORT:size>\t%0,%1"
1059   "&& reload_completed && REG_P (operands[1])"
1060   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1061    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
1063   operands[0] = gen_lowpart (SImode, operands[0]);
1064   operands[1] = gen_lowpart (SImode, operands[1]);
1065   operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
1066                          - GET_MODE_BITSIZE (<SHORT:MODE>mode));
1068   [(set_attr "move_type" "shift_shift,load")
1069    (set_attr "mode" "SI")])
1071 (define_insn "extendsfdf2"
1072   [(set (match_operand:DF     0 "register_operand" "=f")
1073         (float_extend:DF
1074             (match_operand:SF 1 "register_operand" " f")))]
1075   "TARGET_DOUBLE_FLOAT"
1076   "fcvt.d.s\t%0,%1"
1077   [(set_attr "type" "fcvt")
1078    (set_attr "mode" "DF")])
1081 ;;  ....................
1083 ;;      CONVERSIONS
1085 ;;  ....................
1087 (define_insn "fix_trunc<ANYF:mode><GPR:mode>2"
1088   [(set (match_operand:GPR      0 "register_operand" "=r")
1089         (fix:GPR
1090             (match_operand:ANYF 1 "register_operand" " f")))]
1091   "TARGET_HARD_FLOAT"
1092   "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,rtz"
1093   [(set_attr "type" "fcvt")
1094    (set_attr "mode" "<ANYF:MODE>")])
1096 (define_insn "fixuns_trunc<ANYF:mode><GPR:mode>2"
1097   [(set (match_operand:GPR      0 "register_operand" "=r")
1098         (unsigned_fix:GPR
1099             (match_operand:ANYF 1 "register_operand" " f")))]
1100   "TARGET_HARD_FLOAT"
1101   "fcvt.<GPR:ifmt>u.<ANYF:fmt> %0,%1,rtz"
1102   [(set_attr "type" "fcvt")
1103    (set_attr "mode" "<ANYF:MODE>")])
1105 (define_insn "float<GPR:mode><ANYF:mode>2"
1106   [(set (match_operand:ANYF    0 "register_operand" "= f")
1107         (float:ANYF
1108             (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1109   "TARGET_HARD_FLOAT"
1110   "fcvt.<ANYF:fmt>.<GPR:ifmt>\t%0,%z1"
1111   [(set_attr "type" "fcvt")
1112    (set_attr "mode" "<ANYF:MODE>")])
1114 (define_insn "floatuns<GPR:mode><ANYF:mode>2"
1115   [(set (match_operand:ANYF    0 "register_operand" "= f")
1116         (unsigned_float:ANYF
1117             (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1118   "TARGET_HARD_FLOAT"
1119   "fcvt.<ANYF:fmt>.<GPR:ifmt>u\t%0,%z1"
1120   [(set_attr "type" "fcvt")
1121    (set_attr "mode" "<ANYF:MODE>")])
1123 (define_insn "l<rint_pattern><ANYF:mode><GPR:mode>2"
1124   [(set (match_operand:GPR       0 "register_operand" "=r")
1125         (unspec:GPR
1126             [(match_operand:ANYF 1 "register_operand" " f")]
1127             RINT))]
1128   "TARGET_HARD_FLOAT"
1129   "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,<rint_rm>"
1130   [(set_attr "type" "fcvt")
1131    (set_attr "mode" "<ANYF:MODE>")])
1134 ;;  ....................
1136 ;;      DATA MOVEMENT
1138 ;;  ....................
1140 ;; Lower-level instructions for loading an address from the GOT.
1141 ;; We could use MEMs, but an unspec gives more optimization
1142 ;; opportunities.
1144 (define_insn "got_load<mode>"
1145    [(set (match_operand:P      0 "register_operand" "=r")
1146          (unspec:P
1147              [(match_operand:P 1 "symbolic_operand" "")]
1148              UNSPEC_LOAD_GOT))]
1149   ""
1150   "la\t%0,%1"
1151    [(set_attr "got" "load")
1152     (set_attr "mode" "<MODE>")])
1154 (define_insn "tls_add_tp_le<mode>"
1155   [(set (match_operand:P      0 "register_operand" "=r")
1156         (unspec:P
1157             [(match_operand:P 1 "register_operand" "r")
1158              (match_operand:P 2 "register_operand" "r")
1159              (match_operand:P 3 "symbolic_operand" "")]
1160             UNSPEC_TLS_LE))]
1161   ""
1162   "add\t%0,%1,%2,%%tprel_add(%3)"
1163   [(set_attr "type" "arith")
1164    (set_attr "mode" "<MODE>")])
1166 (define_insn "got_load_tls_gd<mode>"
1167   [(set (match_operand:P      0 "register_operand" "=r")
1168         (unspec:P
1169             [(match_operand:P 1 "symbolic_operand" "")]
1170             UNSPEC_TLS_GD))]
1171   ""
1172   "la.tls.gd\t%0,%1"
1173   [(set_attr "got" "load")
1174    (set_attr "mode" "<MODE>")])
1176 (define_insn "got_load_tls_ie<mode>"
1177   [(set (match_operand:P      0 "register_operand" "=r")
1178         (unspec:P
1179             [(match_operand:P 1 "symbolic_operand" "")]
1180             UNSPEC_TLS_IE))]
1181   ""
1182   "la.tls.ie\t%0,%1"
1183   [(set_attr "got" "load")
1184    (set_attr "mode" "<MODE>")])
1186 (define_insn "auipc<mode>"
1187   [(set (match_operand:P           0 "register_operand" "=r")
1188         (unspec:P
1189             [(match_operand:P      1 "symbolic_operand" "")
1190                   (match_operand:P 2 "const_int_operand")
1191                   (pc)]
1192             UNSPEC_AUIPC))]
1193   ""
1194   ".LA%2: auipc\t%0,%h1"
1195   [(set_attr "type" "arith")
1196    (set_attr "cannot_copy" "yes")])
1198 ;; Instructions for adding the low 12 bits of an address to a register.
1199 ;; Operand 2 is the address: riscv_print_operand works out which relocation
1200 ;; should be applied.
1202 (define_insn "*low<mode>"
1203   [(set (match_operand:P           0 "register_operand" "=r")
1204         (lo_sum:P (match_operand:P 1 "register_operand" " r")
1205                   (match_operand:P 2 "symbolic_operand" "")))]
1206   ""
1207   "addi\t%0,%1,%R2"
1208   [(set_attr "type" "arith")
1209    (set_attr "mode" "<MODE>")])
1211 ;; Allow combine to split complex const_int load sequences, using operand 2
1212 ;; to store the intermediate results.  See move_operand for details.
1213 (define_split
1214   [(set (match_operand:GPR 0 "register_operand")
1215         (match_operand:GPR 1 "splittable_const_int_operand"))
1216    (clobber (match_operand:GPR 2 "register_operand"))]
1217   ""
1218   [(const_int 0)]
1220   riscv_move_integer (operands[2], operands[0], INTVAL (operands[1]));
1221   DONE;
1224 ;; Likewise, for symbolic operands.
1225 (define_split
1226   [(set (match_operand:P 0 "register_operand")
1227         (match_operand:P 1))
1228    (clobber (match_operand:P 2 "register_operand"))]
1229   "riscv_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
1230   [(set (match_dup 0) (match_dup 3))]
1232   riscv_split_symbol (operands[2], operands[1],
1233                      MAX_MACHINE_MODE, &operands[3]);
1236 ;; 64-bit integer moves
1238 (define_expand "movdi"
1239   [(set (match_operand:DI 0 "")
1240         (match_operand:DI 1 ""))]
1241   ""
1243   if (riscv_legitimize_move (DImode, operands[0], operands[1]))
1244     DONE;
1247 (define_insn "*movdi_32bit"
1248   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,  *f,*f,*r,*f,*m")
1249         (match_operand:DI 1 "move_operand"         " r,i,m,r,*J*r,*m,*f,*f,*f"))]
1250   "!TARGET_64BIT
1251    && (register_operand (operands[0], DImode)
1252        || reg_or_0_operand (operands[1], DImode))"
1253   { return riscv_output_move (operands[0], operands[1]); }
1254   [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1255    (set_attr "mode" "DI")])
1257 (define_insn "*movdi_64bit"
1258   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*f,*r,*f,*m")
1259         (match_operand:DI 1 "move_operand"         " r,T,m,rJ,*r*J,*m,*f,*f,*f"))]
1260   "TARGET_64BIT
1261    && (register_operand (operands[0], DImode)
1262        || reg_or_0_operand (operands[1], DImode))"
1263   { return riscv_output_move (operands[0], operands[1]); }
1264   [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1265    (set_attr "mode" "DI")])
1267 ;; 32-bit Integer moves
1269 (define_expand "mov<mode>"
1270   [(set (match_operand:MOVE32 0 "")
1271         (match_operand:MOVE32 1 ""))]
1272   ""
1274   if (riscv_legitimize_move (<MODE>mode, operands[0], operands[1]))
1275     DONE;
1278 (define_insn "*movsi_internal"
1279   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*f,*r,*m")
1280         (match_operand:SI 1 "move_operand"         " r,T,m,rJ,*r*J,*m,*f,*f"))]
1281   "(register_operand (operands[0], SImode)
1282     || reg_or_0_operand (operands[1], SImode))"
1283   { return riscv_output_move (operands[0], operands[1]); }
1284   [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore")
1285    (set_attr "mode" "SI")])
1287 ;; 16-bit Integer moves
1289 ;; Unlike most other insns, the move insns can't be split with
1290 ;; different predicates, because register spilling and other parts of
1291 ;; the compiler, have memoized the insn number already.
1292 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
1294 (define_expand "movhi"
1295   [(set (match_operand:HI 0 "")
1296         (match_operand:HI 1 ""))]
1297   ""
1299   if (riscv_legitimize_move (HImode, operands[0], operands[1]))
1300     DONE;
1303 (define_insn "*movhi_internal"
1304   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*r")
1305         (match_operand:HI 1 "move_operand"         " r,T,m,rJ,*r*J,*f"))]
1306   "(register_operand (operands[0], HImode)
1307     || reg_or_0_operand (operands[1], HImode))"
1308   { return riscv_output_move (operands[0], operands[1]); }
1309   [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1310    (set_attr "mode" "HI")])
1312 ;; HImode constant generation; see riscv_move_integer for details.
1313 ;; si+si->hi without truncation is legal because of
1314 ;; TARGET_TRULY_NOOP_TRUNCATION.
1316 (define_insn "*add<mode>hi3"
1317   [(set (match_operand:HI            0 "register_operand" "=r,r")
1318         (plus:HI (match_operand:HISI 1 "register_operand" " r,r")
1319                  (match_operand:HISI 2 "arith_operand"    " r,I")))]
1320   ""
1321   { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
1322   [(set_attr "type" "arith")
1323    (set_attr "mode" "HI")])
1325 (define_insn "*xor<mode>hi3"
1326   [(set (match_operand:HI 0 "register_operand"           "=r,r")
1327         (xor:HI (match_operand:HISI 1 "register_operand" " r,r")
1328                 (match_operand:HISI 2 "arith_operand"    " r,I")))]
1329   ""
1330   "xor%i2\t%0,%1,%2"
1331   [(set_attr "type" "logical")
1332    (set_attr "mode" "HI")])
1334 ;; 8-bit Integer moves
1336 (define_expand "movqi"
1337   [(set (match_operand:QI 0 "")
1338         (match_operand:QI 1 ""))]
1339   ""
1341   if (riscv_legitimize_move (QImode, operands[0], operands[1]))
1342     DONE;
1345 (define_insn "*movqi_internal"
1346   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*r")
1347         (match_operand:QI 1 "move_operand"         " r,I,m,rJ,*r*J,*f"))]
1348   "(register_operand (operands[0], QImode)
1349     || reg_or_0_operand (operands[1], QImode))"
1350   { return riscv_output_move (operands[0], operands[1]); }
1351   [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1352    (set_attr "mode" "QI")])
1354 ;; 32-bit floating point moves
1356 (define_expand "movsf"
1357   [(set (match_operand:SF 0 "")
1358         (match_operand:SF 1 ""))]
1359   ""
1361   if (riscv_legitimize_move (SFmode, operands[0], operands[1]))
1362     DONE;
1365 (define_insn "*movsf_hardfloat"
1366   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,  *r,*r,*m")
1367         (match_operand:SF 1 "move_operand"         " f,G,m,f,G,*r,*f,*G*r,*m,*r"))]
1368   "TARGET_HARD_FLOAT
1369    && (register_operand (operands[0], SFmode)
1370        || reg_or_0_operand (operands[1], SFmode))"
1371   { return riscv_output_move (operands[0], operands[1]); }
1372   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1373    (set_attr "mode" "SF")])
1375 (define_insn "*movsf_softfloat"
1376   [(set (match_operand:SF 0 "nonimmediate_operand" "= r,r,m")
1377         (match_operand:SF 1 "move_operand"         " Gr,m,r"))]
1378   "!TARGET_HARD_FLOAT
1379    && (register_operand (operands[0], SFmode)
1380        || reg_or_0_operand (operands[1], SFmode))"
1381   { return riscv_output_move (operands[0], operands[1]); }
1382   [(set_attr "move_type" "move,load,store")
1383    (set_attr "mode" "SF")])
1385 ;; 64-bit floating point moves
1387 (define_expand "movdf"
1388   [(set (match_operand:DF 0 "")
1389         (match_operand:DF 1 ""))]
1390   ""
1392   if (riscv_legitimize_move (DFmode, operands[0], operands[1]))
1393     DONE;
1396 ;; In RV32, we lack fmv.x.d and fmv.d.x.  Go through memory instead.
1397 ;; (However, we can still use fcvt.d.w to zero a floating-point register.)
1398 (define_insn "*movdf_hardfloat_rv32"
1399   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,  *r,*r,*m")
1400         (match_operand:DF 1 "move_operand"         " f,G,m,f,G,*r*G,*m,*r"))]
1401   "!TARGET_64BIT && TARGET_DOUBLE_FLOAT
1402    && (register_operand (operands[0], DFmode)
1403        || reg_or_0_operand (operands[1], DFmode))"
1404   { return riscv_output_move (operands[0], operands[1]); }
1405   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,move,load,store")
1406    (set_attr "mode" "DF")])
1408 (define_insn "*movdf_hardfloat_rv64"
1409   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,  *r,*r,*m")
1410         (match_operand:DF 1 "move_operand"         " f,G,m,f,G,*r,*f,*r*G,*m,*r"))]
1411   "TARGET_64BIT && TARGET_DOUBLE_FLOAT
1412    && (register_operand (operands[0], DFmode)
1413        || reg_or_0_operand (operands[1], DFmode))"
1414   { return riscv_output_move (operands[0], operands[1]); }
1415   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1416    (set_attr "mode" "DF")])
1418 (define_insn "*movdf_softfloat"
1419   [(set (match_operand:DF 0 "nonimmediate_operand" "= r,r, m")
1420         (match_operand:DF 1 "move_operand"         " rG,m,rG"))]
1421   "!TARGET_DOUBLE_FLOAT
1422    && (register_operand (operands[0], DFmode)
1423        || reg_or_0_operand (operands[1], DFmode))"
1424   { return riscv_output_move (operands[0], operands[1]); }
1425   [(set_attr "move_type" "move,load,store")
1426    (set_attr "mode" "DF")])
1428 (define_split
1429   [(set (match_operand:MOVE64 0 "nonimmediate_operand")
1430         (match_operand:MOVE64 1 "move_operand"))]
1431   "reload_completed
1432    && riscv_split_64bit_move_p (operands[0], operands[1])"
1433   [(const_int 0)]
1435   riscv_split_doubleword_move (operands[0], operands[1]);
1436   DONE;
1439 (define_expand "movmemsi"
1440   [(parallel [(set (match_operand:BLK 0 "general_operand")
1441                    (match_operand:BLK 1 "general_operand"))
1442               (use (match_operand:SI 2 ""))
1443               (use (match_operand:SI 3 "const_int_operand"))])]
1444   ""
1446   if (riscv_expand_block_move (operands[0], operands[1], operands[2]))
1447     DONE;
1448   else
1449     FAIL;
1452 ;; Expand in-line code to clear the instruction cache between operand[0] and
1453 ;; operand[1].
1454 (define_expand "clear_cache"
1455   [(match_operand 0 "pmode_register_operand")
1456    (match_operand 1 "pmode_register_operand")]
1457   ""
1459   emit_insn (gen_fence_i ());
1460   DONE;
1463 (define_insn "fence"
1464   [(unspec_volatile [(const_int 0)] UNSPECV_FENCE)]
1465   ""
1466   "%|fence%-")
1468 (define_insn "fence_i"
1469   [(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)]
1470   ""
1471   "fence.i")
1474 ;;  ....................
1476 ;;      SHIFTS
1478 ;;  ....................
1480 (define_insn "<optab>si3"
1481   [(set (match_operand:SI     0 "register_operand" "= r")
1482         (any_shift:SI
1483             (match_operand:SI 1 "register_operand" "  r")
1484             (match_operand:SI 2 "arith_operand"    " rI")))]
1485   ""
1487   if (GET_CODE (operands[2]) == CONST_INT)
1488     operands[2] = GEN_INT (INTVAL (operands[2])
1489                            & (GET_MODE_BITSIZE (SImode) - 1));
1491   return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2";
1493   [(set_attr "type" "shift")
1494    (set_attr "mode" "SI")])
1496 (define_insn "<optab>di3"
1497   [(set (match_operand:DI 0 "register_operand"     "= r")
1498         (any_shift:DI
1499             (match_operand:DI 1 "register_operand" "  r")
1500             (match_operand:DI 2 "arith_operand"    " rI")))]
1501   "TARGET_64BIT"
1503   if (GET_CODE (operands[2]) == CONST_INT)
1504     operands[2] = GEN_INT (INTVAL (operands[2])
1505                            & (GET_MODE_BITSIZE (DImode) - 1));
1507   return "<insn>%i2\t%0,%1,%2";
1509   [(set_attr "type" "shift")
1510    (set_attr "mode" "DI")])
1512 (define_insn "*<optab>si3_extend"
1513   [(set (match_operand:DI                   0 "register_operand" "= r")
1514         (sign_extend:DI
1515             (any_shift:SI (match_operand:SI 1 "register_operand" "  r")
1516                           (match_operand:SI 2 "arith_operand"    " rI"))))]
1517   "TARGET_64BIT"
1519   if (GET_CODE (operands[2]) == CONST_INT)
1520     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1522   return "<insn>%i2w\t%0,%1,%2";
1524   [(set_attr "type" "shift")
1525    (set_attr "mode" "SI")])
1527 ;; Non-canonical, but can be formed by ree when combine is not successful at
1528 ;; producing one of the two canonical patterns below.
1529 (define_insn "*lshrsi3_zero_extend_1"
1530   [(set (match_operand:DI                   0 "register_operand" "=r")
1531         (zero_extend:DI
1532          (lshiftrt:SI (match_operand:SI     1 "register_operand" " r")
1533                       (match_operand:SI     2 "const_int_operand"))))]
1534   "TARGET_64BIT && (INTVAL (operands[2]) & 0x1f) > 0"
1536   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1538   return "srliw\t%0,%1,%2";
1540   [(set_attr "type" "shift")
1541    (set_attr "mode" "SI")])
1543 ;; Canonical form for a zero-extend of a logical right shift.
1544 (define_insn "*lshrsi3_zero_extend_2"
1545   [(set (match_operand:DI                   0 "register_operand" "=r")
1546         (zero_extract:DI (match_operand:DI  1 "register_operand" " r")
1547                          (match_operand     2 "const_int_operand")
1548                          (match_operand     3 "const_int_operand")))]
1549   "(TARGET_64BIT && (INTVAL (operands[3]) > 0)
1550     && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))"
1552   return "srliw\t%0,%1,%3";
1554   [(set_attr "type" "shift")
1555    (set_attr "mode" "SI")])
1557 ;; Canonical form for a zero-extend of a logical right shift when the
1558 ;; shift count is 31.
1559 (define_insn "*lshrsi3_zero_extend_3"
1560   [(set (match_operand:DI                   0 "register_operand" "=r")
1561         (lt:DI (match_operand:SI            1 "register_operand" " r")
1562                (const_int 0)))]
1563   "TARGET_64BIT"
1565   return "srliw\t%0,%1,31";
1567   [(set_attr "type" "shift")
1568    (set_attr "mode" "SI")])
1571 ;;  ....................
1573 ;;      CONDITIONAL BRANCHES
1575 ;;  ....................
1577 ;; Conditional branches
1579 (define_insn "*branch_order<mode>"
1580   [(set (pc)
1581         (if_then_else
1582          (match_operator 1 "order_operator"
1583                          [(match_operand:X 2 "register_operand" "r")
1584                           (match_operand:X 3 "register_operand" "r")])
1585          (label_ref (match_operand 0 "" ""))
1586          (pc)))]
1587   ""
1588   "b%C1\t%2,%3,%0"
1589   [(set_attr "type" "branch")
1590    (set_attr "mode" "none")])
1592 (define_insn "*branch_zero<mode>"
1593   [(set (pc)
1594         (if_then_else
1595          (match_operator 1 "signed_order_operator"
1596                          [(match_operand:X 2 "register_operand" "r")
1597                           (const_int 0)])
1598          (label_ref (match_operand 0 "" ""))
1599          (pc)))]
1600   ""
1601   "b%C1z\t%2,%0"
1602   [(set_attr "type" "branch")
1603    (set_attr "mode" "none")])
1605 ;; Used to implement built-in functions.
1606 (define_expand "condjump"
1607   [(set (pc)
1608         (if_then_else (match_operand 0)
1609                       (label_ref (match_operand 1))
1610                       (pc)))])
1612 (define_expand "cbranch<mode>4"
1613   [(set (pc)
1614         (if_then_else (match_operator 0 "comparison_operator"
1615                       [(match_operand:BR 1 "register_operand")
1616                        (match_operand:BR 2 "nonmemory_operand")])
1617                       (label_ref (match_operand 3 ""))
1618                       (pc)))]
1619   ""
1621   riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1622                                    operands[1], operands[2]);
1623   DONE;
1626 (define_expand "cbranch<mode>4"
1627   [(set (pc)
1628         (if_then_else (match_operator 0 "fp_branch_comparison"
1629                        [(match_operand:ANYF 1 "register_operand")
1630                         (match_operand:ANYF 2 "register_operand")])
1631                       (label_ref (match_operand 3 ""))
1632                       (pc)))]
1633   "TARGET_HARD_FLOAT"
1635   riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1636                                    operands[1], operands[2]);
1637   DONE;
1640 (define_insn_and_split "*branch_on_bit<X:mode>"
1641   [(set (pc)
1642         (if_then_else
1643             (match_operator 0 "equality_operator"
1644                 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1645                                  (const_int 1)
1646                                  (match_operand 3 "branch_on_bit_operand"))
1647                                  (const_int 0)])
1648             (label_ref (match_operand 1))
1649             (pc)))
1650    (clobber (match_scratch:X 4 "=&r"))]
1651   ""
1652   "#"
1653   "reload_completed"
1654   [(set (match_dup 4)
1655         (ashift:X (match_dup 2) (match_dup 3)))
1656    (set (pc)
1657         (if_then_else
1658             (match_op_dup 0 [(match_dup 4) (const_int 0)])
1659             (label_ref (match_operand 1))
1660             (pc)))]
1662   int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]);
1663   operands[3] = GEN_INT (shift);
1665   if (GET_CODE (operands[0]) == EQ)
1666     operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx);
1667   else
1668     operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx);
1671 (define_insn_and_split "*branch_on_bit_range<X:mode>"
1672   [(set (pc)
1673         (if_then_else
1674             (match_operator 0 "equality_operator"
1675                 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1676                                  (match_operand 3 "branch_on_bit_operand")
1677                                  (const_int 0))
1678                                  (const_int 0)])
1679             (label_ref (match_operand 1))
1680             (pc)))
1681    (clobber (match_scratch:X 4 "=&r"))]
1682   ""
1683   "#"
1684   "reload_completed"
1685   [(set (match_dup 4)
1686         (ashift:X (match_dup 2) (match_dup 3)))
1687    (set (pc)
1688         (if_then_else
1689             (match_op_dup 0 [(match_dup 4) (const_int 0)])
1690             (label_ref (match_operand 1))
1691             (pc)))]
1693   operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]));
1697 ;;  ....................
1699 ;;      SETTING A REGISTER FROM A COMPARISON
1701 ;;  ....................
1703 ;; Destination is always set in SI mode.
1705 (define_expand "cstore<mode>4"
1706   [(set (match_operand:SI 0 "register_operand")
1707         (match_operator:SI 1 "order_operator"
1708             [(match_operand:GPR 2 "register_operand")
1709              (match_operand:GPR 3 "nonmemory_operand")]))]
1710   ""
1712   riscv_expand_int_scc (operands[0], GET_CODE (operands[1]), operands[2],
1713                         operands[3]);
1714   DONE;
1717 (define_expand "cstore<mode>4"
1718   [(set (match_operand:SI 0 "register_operand")
1719         (match_operator:SI 1 "fp_scc_comparison"
1720              [(match_operand:ANYF 2 "register_operand")
1721               (match_operand:ANYF 3 "register_operand")]))]
1722   "TARGET_HARD_FLOAT"
1724   riscv_expand_float_scc (operands[0], GET_CODE (operands[1]), operands[2],
1725                           operands[3]);
1726   DONE;
1729 (define_insn "*cstore<ANYF:mode><X:mode>4"
1730    [(set (match_operand:X         0 "register_operand" "=r")
1731          (match_operator:X 1 "fp_native_comparison"
1732              [(match_operand:ANYF 2 "register_operand" " f")
1733               (match_operand:ANYF 3 "register_operand" " f")]))]
1734   "TARGET_HARD_FLOAT"
1735   "f%C1.<fmt>\t%0,%2,%3"
1736   [(set_attr "type" "fcmp")
1737    (set_attr "mode" "<UNITMODE>")])
1739 (define_insn "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4"
1740    [(set (match_operand:X         0 "register_operand" "=r")
1741          (unspec:X
1742              [(match_operand:ANYF 1 "register_operand" " f")
1743               (match_operand:ANYF 2 "register_operand" " f")]
1744              QUIET_COMPARISON))
1745     (clobber (match_scratch:X 3 "=&r"))]
1746   "TARGET_HARD_FLOAT"
1747   "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3"
1748   [(set_attr "type" "fcmp")
1749    (set_attr "mode" "<UNITMODE>")
1750    (set (attr "length") (const_int 12))])
1752 (define_insn "*seq_zero_<X:mode><GPR:mode>"
1753   [(set (match_operand:GPR       0 "register_operand" "=r")
1754         (eq:GPR (match_operand:X 1 "register_operand" " r")
1755                 (const_int 0)))]
1756   ""
1757   "seqz\t%0,%1"
1758   [(set_attr "type" "slt")
1759    (set_attr "mode" "<X:MODE>")])
1761 (define_insn "*sne_zero_<X:mode><GPR:mode>"
1762   [(set (match_operand:GPR       0 "register_operand" "=r")
1763         (ne:GPR (match_operand:X 1 "register_operand" " r")
1764                 (const_int 0)))]
1765   ""
1766   "snez\t%0,%1"
1767   [(set_attr "type" "slt")
1768    (set_attr "mode" "<X:MODE>")])
1770 (define_insn "*sgt<u>_<X:mode><GPR:mode>"
1771   [(set (match_operand:GPR           0 "register_operand" "= r")
1772         (any_gt:GPR (match_operand:X 1 "register_operand" "  r")
1773                     (match_operand:X 2 "reg_or_0_operand" " rJ")))]
1774   ""
1775   "sgt<u>\t%0,%1,%z2"
1776   [(set_attr "type" "slt")
1777    (set_attr "mode" "<X:MODE>")])
1779 (define_insn "*sge<u>_<X:mode><GPR:mode>"
1780   [(set (match_operand:GPR           0 "register_operand" "=r")
1781         (any_ge:GPR (match_operand:X 1 "register_operand" " r")
1782                     (const_int 1)))]
1783   ""
1784   "slt%i2<u>\t%0,zero,%1"
1785   [(set_attr "type" "slt")
1786    (set_attr "mode" "<MODE>")])
1788 (define_insn "*slt<u>_<X:mode><GPR:mode>"
1789   [(set (match_operand:GPR           0 "register_operand" "= r")
1790         (any_lt:GPR (match_operand:X 1 "register_operand" "  r")
1791                     (match_operand:X 2 "arith_operand"    " rI")))]
1792   ""
1793   "slt%i2<u>\t%0,%1,%2"
1794   [(set_attr "type" "slt")
1795    (set_attr "mode" "<MODE>")])
1797 (define_insn "*sle<u>_<X:mode><GPR:mode>"
1798   [(set (match_operand:GPR           0 "register_operand" "=r")
1799         (any_le:GPR (match_operand:X 1 "register_operand" " r")
1800                     (match_operand:X 2 "sle_operand" "")))]
1801   ""
1803   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
1804   return "slt%i2<u>\t%0,%1,%2";
1806   [(set_attr "type" "slt")
1807    (set_attr "mode" "<MODE>")])
1810 ;;  ....................
1812 ;;      UNCONDITIONAL BRANCHES
1814 ;;  ....................
1816 ;; Unconditional branches.
1818 (define_insn "jump"
1819   [(set (pc)
1820         (label_ref (match_operand 0 "" "")))]
1821   ""
1822   "j\t%l0"
1823   [(set_attr "type"     "jump")
1824    (set_attr "mode"     "none")])
1826 (define_expand "indirect_jump"
1827   [(set (pc) (match_operand 0 "register_operand"))]
1828   ""
1830   operands[0] = force_reg (Pmode, operands[0]);
1831   if (Pmode == SImode)
1832     emit_jump_insn (gen_indirect_jumpsi (operands[0]));
1833   else
1834     emit_jump_insn (gen_indirect_jumpdi (operands[0]));
1835   DONE;
1838 (define_insn "indirect_jump<mode>"
1839   [(set (pc) (match_operand:P 0 "register_operand" "l"))]
1840   ""
1841   "jr\t%0"
1842   [(set_attr "type" "jump")
1843    (set_attr "mode" "none")])
1845 (define_expand "tablejump"
1846   [(set (pc) (match_operand 0 "register_operand" ""))
1847               (use (label_ref (match_operand 1 "" "")))]
1848   ""
1850   if (CASE_VECTOR_PC_RELATIVE)
1851       operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1852                                          gen_rtx_LABEL_REF (Pmode, operands[1]),
1853                                          NULL_RTX, 0, OPTAB_DIRECT);
1855   if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode)
1856     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
1857   else
1858     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
1859   DONE;
1862 (define_insn "tablejump<mode>"
1863   [(set (pc) (match_operand:GPR 0 "register_operand" "l"))
1864    (use (label_ref (match_operand 1 "" "")))]
1865   ""
1866   "jr\t%0"
1867   [(set_attr "type" "jump")
1868    (set_attr "mode" "none")])
1871 ;;  ....................
1873 ;;      Function prologue/epilogue
1875 ;;  ....................
1878 (define_expand "prologue"
1879   [(const_int 1)]
1880   ""
1882   riscv_expand_prologue ();
1883   DONE;
1886 ;; Block any insns from being moved before this point, since the
1887 ;; profiling call to mcount can use various registers that aren't
1888 ;; saved or used to pass arguments.
1890 (define_insn "blockage"
1891   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
1892   ""
1893   ""
1894   [(set_attr "type" "ghost")
1895    (set_attr "mode" "none")])
1897 (define_expand "epilogue"
1898   [(const_int 2)]
1899   ""
1901   riscv_expand_epilogue (false);
1902   DONE;
1905 (define_expand "sibcall_epilogue"
1906   [(const_int 2)]
1907   ""
1909   riscv_expand_epilogue (true);
1910   DONE;
1913 ;; Trivial return.  Make it look like a normal return insn as that
1914 ;; allows jump optimizations to work better.
1916 (define_expand "return"
1917   [(simple_return)]
1918   "riscv_can_use_return_insn ()"
1919   "")
1921 (define_insn "simple_return"
1922   [(simple_return)]
1923   ""
1924   "ret"
1925   [(set_attr "type"     "jump")
1926    (set_attr "mode"     "none")])
1928 ;; Normal return.
1930 (define_insn "simple_return_internal"
1931   [(simple_return)
1932    (use (match_operand 0 "pmode_register_operand" ""))]
1933   ""
1934   "jr\t%0"
1935   [(set_attr "type"     "jump")
1936    (set_attr "mode"     "none")])
1938 ;; This is used in compiling the unwind routines.
1939 (define_expand "eh_return"
1940   [(use (match_operand 0 "general_operand"))]
1941   ""
1943   if (GET_MODE (operands[0]) != word_mode)
1944     operands[0] = convert_to_mode (word_mode, operands[0], 0);
1945   if (TARGET_64BIT)
1946     emit_insn (gen_eh_set_lr_di (operands[0]));
1947   else
1948     emit_insn (gen_eh_set_lr_si (operands[0]));
1949   DONE;
1952 ;; Clobber the return address on the stack.  We can't expand this
1953 ;; until we know where it will be put in the stack frame.
1955 (define_insn "eh_set_lr_si"
1956   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
1957    (clobber (match_scratch:SI 1 "=&r"))]
1958   "! TARGET_64BIT"
1959   "#")
1961 (define_insn "eh_set_lr_di"
1962   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
1963    (clobber (match_scratch:DI 1 "=&r"))]
1964   "TARGET_64BIT"
1965   "#")
1967 (define_split
1968   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
1969    (clobber (match_scratch 1))]
1970   "reload_completed"
1971   [(const_int 0)]
1973   riscv_set_return_address (operands[0], operands[1]);
1974   DONE;
1978 ;;  ....................
1980 ;;      FUNCTION CALLS
1982 ;;  ....................
1984 (define_expand "sibcall"
1985   [(parallel [(call (match_operand 0 "")
1986                     (match_operand 1 ""))
1987               (use (match_operand 2 ""))        ;; next_arg_reg
1988               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
1989   ""
1991   rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
1992   emit_call_insn (gen_sibcall_internal (target, operands[1]));
1993   DONE;
1996 (define_insn "sibcall_internal"
1997   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U"))
1998          (match_operand 1 "" ""))]
1999   "SIBLING_CALL_P (insn)"
2000   "@
2001    jr\t%0
2002    tail\t%0
2003    tail\t%0@plt"
2004   [(set_attr "type" "call")])
2006 (define_expand "sibcall_value"
2007   [(parallel [(set (match_operand 0 "")
2008                    (call (match_operand 1 "")
2009                          (match_operand 2 "")))
2010               (use (match_operand 3 ""))])]             ;; next_arg_reg
2011   ""
2013   rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2014   emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2]));
2015   DONE;
2018 (define_insn "sibcall_value_internal"
2019   [(set (match_operand 0 "" "")
2020         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U"))
2021               (match_operand 2 "" "")))]
2022   "SIBLING_CALL_P (insn)"
2023   "@
2024    jr\t%1
2025    tail\t%1
2026    tail\t%1@plt"
2027   [(set_attr "type" "call")])
2029 (define_expand "call"
2030   [(parallel [(call (match_operand 0 "")
2031                     (match_operand 1 ""))
2032               (use (match_operand 2 ""))        ;; next_arg_reg
2033               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
2034   ""
2036   rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2037   emit_call_insn (gen_call_internal (target, operands[1]));
2038   DONE;
2041 (define_insn "call_internal"
2042   [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U"))
2043          (match_operand 1 "" ""))
2044    (clobber (reg:SI RETURN_ADDR_REGNUM))]
2045   ""
2046   "@
2047    jalr\t%0
2048    call\t%0
2049    call\t%0@plt"
2050   [(set_attr "type" "call")])
2052 (define_expand "call_value"
2053   [(parallel [(set (match_operand 0 "")
2054                    (call (match_operand 1 "")
2055                          (match_operand 2 "")))
2056               (use (match_operand 3 ""))])]             ;; next_arg_reg
2057   ""
2059   rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2060   emit_call_insn (gen_call_value_internal (operands[0], target, operands[2]));
2061   DONE;
2064 (define_insn "call_value_internal"
2065   [(set (match_operand 0 "" "")
2066         (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U"))
2067               (match_operand 2 "" "")))
2068    (clobber (reg:SI RETURN_ADDR_REGNUM))]
2069   ""
2070   "@
2071    jalr\t%1
2072    call\t%1
2073    call\t%1@plt"
2074   [(set_attr "type" "call")])
2076 ;; Call subroutine returning any type.
2078 (define_expand "untyped_call"
2079   [(parallel [(call (match_operand 0 "")
2080                     (const_int 0))
2081               (match_operand 1 "")
2082               (match_operand 2 "")])]
2083   ""
2085   int i;
2087   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2089   for (i = 0; i < XVECLEN (operands[2], 0); i++)
2090     {
2091       rtx set = XVECEXP (operands[2], 0, i);
2092       riscv_emit_move (SET_DEST (set), SET_SRC (set));
2093     }
2095   emit_insn (gen_blockage ());
2096   DONE;
2099 (define_insn "nop"
2100   [(const_int 0)]
2101   ""
2102   "nop"
2103   [(set_attr "type"     "nop")
2104    (set_attr "mode"     "none")])
2106 (define_insn "trap"
2107   [(trap_if (const_int 1) (const_int 0))]
2108   ""
2109   "ebreak")
2111 (define_insn "gpr_save"
2112   [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_SAVE)
2113    (clobber (reg:SI T0_REGNUM))
2114    (clobber (reg:SI T1_REGNUM))]
2115   ""
2116   { return riscv_output_gpr_save (INTVAL (operands[0])); })
2118 (define_insn "gpr_restore"
2119   [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_RESTORE)]
2120   ""
2121   "tail\t__riscv_restore_%0")
2123 (define_insn "gpr_restore_return"
2124   [(return)
2125    (use (match_operand 0 "pmode_register_operand" ""))
2126    (const_int 0)]
2127   ""
2128   "")
2130 (define_insn "riscv_frflags"
2131   [(set (match_operand:SI 0 "register_operand" "=r")
2132         (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))]
2133   "TARGET_HARD_FLOAT"
2134   "frflags %0")
2136 (define_insn "riscv_fsflags"
2137   [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)]
2138   "TARGET_HARD_FLOAT"
2139   "fsflags %0")
2141 (define_insn "stack_tie<mode>"
2142   [(set (mem:BLK (scratch))
2143         (unspec:BLK [(match_operand:X 0 "register_operand" "r")
2144                      (match_operand:X 1 "register_operand" "r")]
2145                     UNSPEC_TIE))]
2146   ""
2147   ""
2148   [(set_attr "length" "0")]
2151 (include "sync.md")
2152 (include "peephole.md")
2153 (include "pic.md")
2154 (include "generic.md")