RISC-V: Add naked function support.
[official-gcc.git] / gcc / config / riscv / riscv.md
blobbffe78dd837f62da2e2ec17f3aa79697753f0e3f
1 ;; Machine description for RISC-V for GNU compiler.
2 ;; Copyright (C) 2011-2018 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 #ifdef ICACHE_FLUSH_FUNC
1460   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, ICACHE_FLUSH_FUNC),
1461                      LCT_NORMAL, VOIDmode, operands[0], Pmode,
1462                      operands[1], Pmode, const0_rtx, Pmode);
1463 #else
1464   emit_insn (gen_fence_i ());
1465 #endif
1466   DONE;
1469 (define_insn "fence"
1470   [(unspec_volatile [(const_int 0)] UNSPECV_FENCE)]
1471   ""
1472   "%|fence%-")
1474 (define_insn "fence_i"
1475   [(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)]
1476   ""
1477   "fence.i")
1480 ;;  ....................
1482 ;;      SHIFTS
1484 ;;  ....................
1486 (define_insn "<optab>si3"
1487   [(set (match_operand:SI     0 "register_operand" "= r")
1488         (any_shift:SI
1489             (match_operand:SI 1 "register_operand" "  r")
1490             (match_operand:SI 2 "arith_operand"    " rI")))]
1491   ""
1493   if (GET_CODE (operands[2]) == CONST_INT)
1494     operands[2] = GEN_INT (INTVAL (operands[2])
1495                            & (GET_MODE_BITSIZE (SImode) - 1));
1497   return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2";
1499   [(set_attr "type" "shift")
1500    (set_attr "mode" "SI")])
1502 (define_insn "<optab>di3"
1503   [(set (match_operand:DI 0 "register_operand"     "= r")
1504         (any_shift:DI
1505             (match_operand:DI 1 "register_operand" "  r")
1506             (match_operand:DI 2 "arith_operand"    " rI")))]
1507   "TARGET_64BIT"
1509   if (GET_CODE (operands[2]) == CONST_INT)
1510     operands[2] = GEN_INT (INTVAL (operands[2])
1511                            & (GET_MODE_BITSIZE (DImode) - 1));
1513   return "<insn>%i2\t%0,%1,%2";
1515   [(set_attr "type" "shift")
1516    (set_attr "mode" "DI")])
1518 (define_insn "*<optab>si3_extend"
1519   [(set (match_operand:DI                   0 "register_operand" "= r")
1520         (sign_extend:DI
1521             (any_shift:SI (match_operand:SI 1 "register_operand" "  r")
1522                           (match_operand:SI 2 "arith_operand"    " rI"))))]
1523   "TARGET_64BIT"
1525   if (GET_CODE (operands[2]) == CONST_INT)
1526     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1528   return "<insn>%i2w\t%0,%1,%2";
1530   [(set_attr "type" "shift")
1531    (set_attr "mode" "SI")])
1533 ;; Non-canonical, but can be formed by ree when combine is not successful at
1534 ;; producing one of the two canonical patterns below.
1535 (define_insn "*lshrsi3_zero_extend_1"
1536   [(set (match_operand:DI                   0 "register_operand" "=r")
1537         (zero_extend:DI
1538          (lshiftrt:SI (match_operand:SI     1 "register_operand" " r")
1539                       (match_operand:SI     2 "const_int_operand"))))]
1540   "TARGET_64BIT && (INTVAL (operands[2]) & 0x1f) > 0"
1542   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1544   return "srliw\t%0,%1,%2";
1546   [(set_attr "type" "shift")
1547    (set_attr "mode" "SI")])
1549 ;; Canonical form for a zero-extend of a logical right shift.
1550 (define_insn "*lshrsi3_zero_extend_2"
1551   [(set (match_operand:DI                   0 "register_operand" "=r")
1552         (zero_extract:DI (match_operand:DI  1 "register_operand" " r")
1553                          (match_operand     2 "const_int_operand")
1554                          (match_operand     3 "const_int_operand")))]
1555   "(TARGET_64BIT && (INTVAL (operands[3]) > 0)
1556     && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))"
1558   return "srliw\t%0,%1,%3";
1560   [(set_attr "type" "shift")
1561    (set_attr "mode" "SI")])
1563 ;; Canonical form for a zero-extend of a logical right shift when the
1564 ;; shift count is 31.
1565 (define_insn "*lshrsi3_zero_extend_3"
1566   [(set (match_operand:DI                   0 "register_operand" "=r")
1567         (lt:DI (match_operand:SI            1 "register_operand" " r")
1568                (const_int 0)))]
1569   "TARGET_64BIT"
1571   return "srliw\t%0,%1,31";
1573   [(set_attr "type" "shift")
1574    (set_attr "mode" "SI")])
1577 ;;  ....................
1579 ;;      CONDITIONAL BRANCHES
1581 ;;  ....................
1583 ;; Conditional branches
1585 (define_insn "*branch_order<mode>"
1586   [(set (pc)
1587         (if_then_else
1588          (match_operator 1 "order_operator"
1589                          [(match_operand:X 2 "register_operand" "r")
1590                           (match_operand:X 3 "register_operand" "r")])
1591          (label_ref (match_operand 0 "" ""))
1592          (pc)))]
1593   ""
1594   "b%C1\t%2,%3,%0"
1595   [(set_attr "type" "branch")
1596    (set_attr "mode" "none")])
1598 (define_insn "*branch_zero<mode>"
1599   [(set (pc)
1600         (if_then_else
1601          (match_operator 1 "signed_order_operator"
1602                          [(match_operand:X 2 "register_operand" "r")
1603                           (const_int 0)])
1604          (label_ref (match_operand 0 "" ""))
1605          (pc)))]
1606   ""
1607   "b%C1z\t%2,%0"
1608   [(set_attr "type" "branch")
1609    (set_attr "mode" "none")])
1611 ;; Used to implement built-in functions.
1612 (define_expand "condjump"
1613   [(set (pc)
1614         (if_then_else (match_operand 0)
1615                       (label_ref (match_operand 1))
1616                       (pc)))])
1618 (define_expand "cbranch<mode>4"
1619   [(set (pc)
1620         (if_then_else (match_operator 0 "comparison_operator"
1621                       [(match_operand:BR 1 "register_operand")
1622                        (match_operand:BR 2 "nonmemory_operand")])
1623                       (label_ref (match_operand 3 ""))
1624                       (pc)))]
1625   ""
1627   riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1628                                    operands[1], operands[2]);
1629   DONE;
1632 (define_expand "cbranch<mode>4"
1633   [(set (pc)
1634         (if_then_else (match_operator 0 "fp_branch_comparison"
1635                        [(match_operand:ANYF 1 "register_operand")
1636                         (match_operand:ANYF 2 "register_operand")])
1637                       (label_ref (match_operand 3 ""))
1638                       (pc)))]
1639   "TARGET_HARD_FLOAT"
1641   riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1642                                    operands[1], operands[2]);
1643   DONE;
1646 (define_insn_and_split "*branch_on_bit<X:mode>"
1647   [(set (pc)
1648         (if_then_else
1649             (match_operator 0 "equality_operator"
1650                 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1651                                  (const_int 1)
1652                                  (match_operand 3 "branch_on_bit_operand"))
1653                                  (const_int 0)])
1654             (label_ref (match_operand 1))
1655             (pc)))
1656    (clobber (match_scratch:X 4 "=&r"))]
1657   ""
1658   "#"
1659   "reload_completed"
1660   [(set (match_dup 4)
1661         (ashift:X (match_dup 2) (match_dup 3)))
1662    (set (pc)
1663         (if_then_else
1664             (match_op_dup 0 [(match_dup 4) (const_int 0)])
1665             (label_ref (match_operand 1))
1666             (pc)))]
1668   int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]);
1669   operands[3] = GEN_INT (shift);
1671   if (GET_CODE (operands[0]) == EQ)
1672     operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx);
1673   else
1674     operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx);
1677 (define_insn_and_split "*branch_on_bit_range<X:mode>"
1678   [(set (pc)
1679         (if_then_else
1680             (match_operator 0 "equality_operator"
1681                 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1682                                  (match_operand 3 "branch_on_bit_operand")
1683                                  (const_int 0))
1684                                  (const_int 0)])
1685             (label_ref (match_operand 1))
1686             (pc)))
1687    (clobber (match_scratch:X 4 "=&r"))]
1688   ""
1689   "#"
1690   "reload_completed"
1691   [(set (match_dup 4)
1692         (ashift:X (match_dup 2) (match_dup 3)))
1693    (set (pc)
1694         (if_then_else
1695             (match_op_dup 0 [(match_dup 4) (const_int 0)])
1696             (label_ref (match_operand 1))
1697             (pc)))]
1699   operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]));
1703 ;;  ....................
1705 ;;      SETTING A REGISTER FROM A COMPARISON
1707 ;;  ....................
1709 ;; Destination is always set in SI mode.
1711 (define_expand "cstore<mode>4"
1712   [(set (match_operand:SI 0 "register_operand")
1713         (match_operator:SI 1 "order_operator"
1714             [(match_operand:GPR 2 "register_operand")
1715              (match_operand:GPR 3 "nonmemory_operand")]))]
1716   ""
1718   riscv_expand_int_scc (operands[0], GET_CODE (operands[1]), operands[2],
1719                         operands[3]);
1720   DONE;
1723 (define_expand "cstore<mode>4"
1724   [(set (match_operand:SI 0 "register_operand")
1725         (match_operator:SI 1 "fp_scc_comparison"
1726              [(match_operand:ANYF 2 "register_operand")
1727               (match_operand:ANYF 3 "register_operand")]))]
1728   "TARGET_HARD_FLOAT"
1730   riscv_expand_float_scc (operands[0], GET_CODE (operands[1]), operands[2],
1731                           operands[3]);
1732   DONE;
1735 (define_insn "*cstore<ANYF:mode><X:mode>4"
1736    [(set (match_operand:X         0 "register_operand" "=r")
1737          (match_operator:X 1 "fp_native_comparison"
1738              [(match_operand:ANYF 2 "register_operand" " f")
1739               (match_operand:ANYF 3 "register_operand" " f")]))]
1740   "TARGET_HARD_FLOAT"
1741   "f%C1.<fmt>\t%0,%2,%3"
1742   [(set_attr "type" "fcmp")
1743    (set_attr "mode" "<UNITMODE>")])
1745 (define_insn "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4"
1746    [(set (match_operand:X         0 "register_operand" "=r")
1747          (unspec:X
1748              [(match_operand:ANYF 1 "register_operand" " f")
1749               (match_operand:ANYF 2 "register_operand" " f")]
1750              QUIET_COMPARISON))
1751     (clobber (match_scratch:X 3 "=&r"))]
1752   "TARGET_HARD_FLOAT"
1753   "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3"
1754   [(set_attr "type" "fcmp")
1755    (set_attr "mode" "<UNITMODE>")
1756    (set (attr "length") (const_int 12))])
1758 (define_insn "*seq_zero_<X:mode><GPR:mode>"
1759   [(set (match_operand:GPR       0 "register_operand" "=r")
1760         (eq:GPR (match_operand:X 1 "register_operand" " r")
1761                 (const_int 0)))]
1762   ""
1763   "seqz\t%0,%1"
1764   [(set_attr "type" "slt")
1765    (set_attr "mode" "<X:MODE>")])
1767 (define_insn "*sne_zero_<X:mode><GPR:mode>"
1768   [(set (match_operand:GPR       0 "register_operand" "=r")
1769         (ne:GPR (match_operand:X 1 "register_operand" " r")
1770                 (const_int 0)))]
1771   ""
1772   "snez\t%0,%1"
1773   [(set_attr "type" "slt")
1774    (set_attr "mode" "<X:MODE>")])
1776 (define_insn "*sgt<u>_<X:mode><GPR:mode>"
1777   [(set (match_operand:GPR           0 "register_operand" "= r")
1778         (any_gt:GPR (match_operand:X 1 "register_operand" "  r")
1779                     (match_operand:X 2 "reg_or_0_operand" " rJ")))]
1780   ""
1781   "sgt<u>\t%0,%1,%z2"
1782   [(set_attr "type" "slt")
1783    (set_attr "mode" "<X:MODE>")])
1785 (define_insn "*sge<u>_<X:mode><GPR:mode>"
1786   [(set (match_operand:GPR           0 "register_operand" "=r")
1787         (any_ge:GPR (match_operand:X 1 "register_operand" " r")
1788                     (const_int 1)))]
1789   ""
1790   "slt%i2<u>\t%0,zero,%1"
1791   [(set_attr "type" "slt")
1792    (set_attr "mode" "<MODE>")])
1794 (define_insn "*slt<u>_<X:mode><GPR:mode>"
1795   [(set (match_operand:GPR           0 "register_operand" "= r")
1796         (any_lt:GPR (match_operand:X 1 "register_operand" "  r")
1797                     (match_operand:X 2 "arith_operand"    " rI")))]
1798   ""
1799   "slt%i2<u>\t%0,%1,%2"
1800   [(set_attr "type" "slt")
1801    (set_attr "mode" "<MODE>")])
1803 (define_insn "*sle<u>_<X:mode><GPR:mode>"
1804   [(set (match_operand:GPR           0 "register_operand" "=r")
1805         (any_le:GPR (match_operand:X 1 "register_operand" " r")
1806                     (match_operand:X 2 "sle_operand" "")))]
1807   ""
1809   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
1810   return "slt%i2<u>\t%0,%1,%2";
1812   [(set_attr "type" "slt")
1813    (set_attr "mode" "<MODE>")])
1816 ;;  ....................
1818 ;;      UNCONDITIONAL BRANCHES
1820 ;;  ....................
1822 ;; Unconditional branches.
1824 (define_insn "jump"
1825   [(set (pc)
1826         (label_ref (match_operand 0 "" "")))]
1827   ""
1828   "j\t%l0"
1829   [(set_attr "type"     "jump")
1830    (set_attr "mode"     "none")])
1832 (define_expand "indirect_jump"
1833   [(set (pc) (match_operand 0 "register_operand"))]
1834   ""
1836   operands[0] = force_reg (Pmode, operands[0]);
1837   if (Pmode == SImode)
1838     emit_jump_insn (gen_indirect_jumpsi (operands[0]));
1839   else
1840     emit_jump_insn (gen_indirect_jumpdi (operands[0]));
1841   DONE;
1844 (define_insn "indirect_jump<mode>"
1845   [(set (pc) (match_operand:P 0 "register_operand" "l"))]
1846   ""
1847   "jr\t%0"
1848   [(set_attr "type" "jump")
1849    (set_attr "mode" "none")])
1851 (define_expand "tablejump"
1852   [(set (pc) (match_operand 0 "register_operand" ""))
1853               (use (label_ref (match_operand 1 "" "")))]
1854   ""
1856   if (CASE_VECTOR_PC_RELATIVE)
1857       operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1858                                          gen_rtx_LABEL_REF (Pmode, operands[1]),
1859                                          NULL_RTX, 0, OPTAB_DIRECT);
1861   if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode)
1862     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
1863   else
1864     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
1865   DONE;
1868 (define_insn "tablejump<mode>"
1869   [(set (pc) (match_operand:GPR 0 "register_operand" "l"))
1870    (use (label_ref (match_operand 1 "" "")))]
1871   ""
1872   "jr\t%0"
1873   [(set_attr "type" "jump")
1874    (set_attr "mode" "none")])
1877 ;;  ....................
1879 ;;      Function prologue/epilogue
1881 ;;  ....................
1884 (define_expand "prologue"
1885   [(const_int 1)]
1886   ""
1888   riscv_expand_prologue ();
1889   DONE;
1892 ;; Block any insns from being moved before this point, since the
1893 ;; profiling call to mcount can use various registers that aren't
1894 ;; saved or used to pass arguments.
1896 (define_insn "blockage"
1897   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
1898   ""
1899   ""
1900   [(set_attr "type" "ghost")
1901    (set_attr "mode" "none")])
1903 (define_expand "epilogue"
1904   [(const_int 2)]
1905   ""
1907   riscv_expand_epilogue (false);
1908   DONE;
1911 (define_expand "sibcall_epilogue"
1912   [(const_int 2)]
1913   ""
1915   riscv_expand_epilogue (true);
1916   DONE;
1919 ;; Trivial return.  Make it look like a normal return insn as that
1920 ;; allows jump optimizations to work better.
1922 (define_expand "return"
1923   [(simple_return)]
1924   "riscv_can_use_return_insn ()"
1925   "")
1927 (define_insn "simple_return"
1928   [(simple_return)]
1929   ""
1931   return riscv_output_return ();
1933   [(set_attr "type"     "jump")
1934    (set_attr "mode"     "none")])
1936 ;; Normal return.
1938 (define_insn "simple_return_internal"
1939   [(simple_return)
1940    (use (match_operand 0 "pmode_register_operand" ""))]
1941   ""
1942   "jr\t%0"
1943   [(set_attr "type"     "jump")
1944    (set_attr "mode"     "none")])
1946 ;; This is used in compiling the unwind routines.
1947 (define_expand "eh_return"
1948   [(use (match_operand 0 "general_operand"))]
1949   ""
1951   if (GET_MODE (operands[0]) != word_mode)
1952     operands[0] = convert_to_mode (word_mode, operands[0], 0);
1953   if (TARGET_64BIT)
1954     emit_insn (gen_eh_set_lr_di (operands[0]));
1955   else
1956     emit_insn (gen_eh_set_lr_si (operands[0]));
1957   DONE;
1960 ;; Clobber the return address on the stack.  We can't expand this
1961 ;; until we know where it will be put in the stack frame.
1963 (define_insn "eh_set_lr_si"
1964   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
1965    (clobber (match_scratch:SI 1 "=&r"))]
1966   "! TARGET_64BIT"
1967   "#")
1969 (define_insn "eh_set_lr_di"
1970   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
1971    (clobber (match_scratch:DI 1 "=&r"))]
1972   "TARGET_64BIT"
1973   "#")
1975 (define_split
1976   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
1977    (clobber (match_scratch 1))]
1978   "reload_completed"
1979   [(const_int 0)]
1981   riscv_set_return_address (operands[0], operands[1]);
1982   DONE;
1986 ;;  ....................
1988 ;;      FUNCTION CALLS
1990 ;;  ....................
1992 (define_expand "sibcall"
1993   [(parallel [(call (match_operand 0 "")
1994                     (match_operand 1 ""))
1995               (use (match_operand 2 ""))        ;; next_arg_reg
1996               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
1997   ""
1999   rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2000   emit_call_insn (gen_sibcall_internal (target, operands[1]));
2001   DONE;
2004 (define_insn "sibcall_internal"
2005   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U"))
2006          (match_operand 1 "" ""))]
2007   "SIBLING_CALL_P (insn)"
2008   "@
2009    jr\t%0
2010    tail\t%0
2011    tail\t%0@plt"
2012   [(set_attr "type" "call")])
2014 (define_expand "sibcall_value"
2015   [(parallel [(set (match_operand 0 "")
2016                    (call (match_operand 1 "")
2017                          (match_operand 2 "")))
2018               (use (match_operand 3 ""))])]             ;; next_arg_reg
2019   ""
2021   rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2022   emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2]));
2023   DONE;
2026 (define_insn "sibcall_value_internal"
2027   [(set (match_operand 0 "" "")
2028         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U"))
2029               (match_operand 2 "" "")))]
2030   "SIBLING_CALL_P (insn)"
2031   "@
2032    jr\t%1
2033    tail\t%1
2034    tail\t%1@plt"
2035   [(set_attr "type" "call")])
2037 (define_expand "call"
2038   [(parallel [(call (match_operand 0 "")
2039                     (match_operand 1 ""))
2040               (use (match_operand 2 ""))        ;; next_arg_reg
2041               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
2042   ""
2044   rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2045   emit_call_insn (gen_call_internal (target, operands[1]));
2046   DONE;
2049 (define_insn "call_internal"
2050   [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U"))
2051          (match_operand 1 "" ""))
2052    (clobber (reg:SI RETURN_ADDR_REGNUM))]
2053   ""
2054   "@
2055    jalr\t%0
2056    call\t%0
2057    call\t%0@plt"
2058   [(set_attr "type" "call")])
2060 (define_expand "call_value"
2061   [(parallel [(set (match_operand 0 "")
2062                    (call (match_operand 1 "")
2063                          (match_operand 2 "")))
2064               (use (match_operand 3 ""))])]             ;; next_arg_reg
2065   ""
2067   rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2068   emit_call_insn (gen_call_value_internal (operands[0], target, operands[2]));
2069   DONE;
2072 (define_insn "call_value_internal"
2073   [(set (match_operand 0 "" "")
2074         (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U"))
2075               (match_operand 2 "" "")))
2076    (clobber (reg:SI RETURN_ADDR_REGNUM))]
2077   ""
2078   "@
2079    jalr\t%1
2080    call\t%1
2081    call\t%1@plt"
2082   [(set_attr "type" "call")])
2084 ;; Call subroutine returning any type.
2086 (define_expand "untyped_call"
2087   [(parallel [(call (match_operand 0 "")
2088                     (const_int 0))
2089               (match_operand 1 "")
2090               (match_operand 2 "")])]
2091   ""
2093   int i;
2095   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2097   for (i = 0; i < XVECLEN (operands[2], 0); i++)
2098     {
2099       rtx set = XVECEXP (operands[2], 0, i);
2100       riscv_emit_move (SET_DEST (set), SET_SRC (set));
2101     }
2103   emit_insn (gen_blockage ());
2104   DONE;
2107 (define_insn "nop"
2108   [(const_int 0)]
2109   ""
2110   "nop"
2111   [(set_attr "type"     "nop")
2112    (set_attr "mode"     "none")])
2114 (define_insn "trap"
2115   [(trap_if (const_int 1) (const_int 0))]
2116   ""
2117   "ebreak")
2119 (define_insn "gpr_save"
2120   [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_SAVE)
2121    (clobber (reg:SI T0_REGNUM))
2122    (clobber (reg:SI T1_REGNUM))]
2123   ""
2124   { return riscv_output_gpr_save (INTVAL (operands[0])); })
2126 (define_insn "gpr_restore"
2127   [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_RESTORE)]
2128   ""
2129   "tail\t__riscv_restore_%0")
2131 (define_insn "gpr_restore_return"
2132   [(return)
2133    (use (match_operand 0 "pmode_register_operand" ""))
2134    (const_int 0)]
2135   ""
2136   "")
2138 (define_insn "riscv_frflags"
2139   [(set (match_operand:SI 0 "register_operand" "=r")
2140         (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))]
2141   "TARGET_HARD_FLOAT"
2142   "frflags %0")
2144 (define_insn "riscv_fsflags"
2145   [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)]
2146   "TARGET_HARD_FLOAT"
2147   "fsflags %0")
2149 (define_insn "stack_tie<mode>"
2150   [(set (mem:BLK (scratch))
2151         (unspec:BLK [(match_operand:X 0 "register_operand" "r")
2152                      (match_operand:X 1 "register_operand" "r")]
2153                     UNSPEC_TIE))]
2154   ""
2155   ""
2156   [(set_attr "length" "0")]
2159 (include "sync.md")
2160 (include "peephole.md")
2161 (include "pic.md")
2162 (include "generic.md")