PR rtl-optimization/88018
[official-gcc.git] / gcc / config / riscv / riscv.md
blobb6c20230ffdf203634d102d5da99c66b41ebc92a
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   ;; Interrupt handler instructions.
60   UNSPECV_MRET
61   UNSPECV_SRET
62   UNSPECV_URET
64   ;; Blockage and synchronization.
65   UNSPECV_BLOCKAGE
66   UNSPECV_FENCE
67   UNSPECV_FENCE_I
70 (define_constants
71   [(RETURN_ADDR_REGNUM          1)
72    (GP_REGNUM                   3)
73    (T0_REGNUM                   5)
74    (T1_REGNUM                   6)
75    (S0_REGNUM                   8)
76    (S1_REGNUM                   9)
77    (S2_REGNUM                   18)
79    (NORMAL_RETURN               0)
80    (SIBCALL_RETURN              1)
81    (EXCEPTION_RETURN            2)
84 (include "predicates.md")
85 (include "constraints.md")
87 ;; ....................
89 ;;      Attributes
91 ;; ....................
93 (define_attr "got" "unset,xgot_high,load"
94   (const_string "unset"))
96 ;; Classification of moves, extensions and truncations.  Most values
97 ;; are as for "type" (see below) but there are also the following
98 ;; move-specific values:
100 ;; andi         a single ANDI instruction
101 ;; shift_shift  a shift left followed by a shift right
103 ;; This attribute is used to determine the instruction's length and
104 ;; scheduling type.  For doubleword moves, the attribute always describes
105 ;; the split instructions; in some cases, it is more appropriate for the
106 ;; scheduling type to be "multi" instead.
107 (define_attr "move_type"
108   "unknown,load,fpload,store,fpstore,mtc,mfc,move,fmove,
109    const,logical,arith,andi,shift_shift"
110   (const_string "unknown"))
112 ;; Main data type used by the insn
113 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
114   (const_string "unknown"))
116 ;; True if the main data type is twice the size of a word.
117 (define_attr "dword_mode" "no,yes"
118   (cond [(and (eq_attr "mode" "DI,DF")
119               (eq (symbol_ref "TARGET_64BIT") (const_int 0)))
120          (const_string "yes")
122          (and (eq_attr "mode" "TI,TF")
123               (ne (symbol_ref "TARGET_64BIT") (const_int 0)))
124          (const_string "yes")]
125         (const_string "no")))
127 ;; Classification of each insn.
128 ;; branch       conditional branch
129 ;; jump         unconditional jump
130 ;; call         unconditional call
131 ;; load         load instruction(s)
132 ;; fpload       floating point load
133 ;; store        store instruction(s)
134 ;; fpstore      floating point store
135 ;; mtc          transfer to coprocessor
136 ;; mfc          transfer from coprocessor
137 ;; const        load constant
138 ;; arith        integer arithmetic instructions
139 ;; logical      integer logical instructions
140 ;; shift        integer shift instructions
141 ;; slt          set less than instructions
142 ;; imul         integer multiply 
143 ;; idiv         integer divide
144 ;; move         integer register move (addi rd, rs1, 0)
145 ;; fmove        floating point register move
146 ;; fadd         floating point add/subtract
147 ;; fmul         floating point multiply
148 ;; fmadd        floating point multiply-add
149 ;; fdiv         floating point divide
150 ;; fcmp         floating point compare
151 ;; fcvt         floating point convert
152 ;; fsqrt        floating point square root
153 ;; multi        multiword sequence (or user asm statements)
154 ;; nop          no operation
155 ;; ghost        an instruction that produces no real code
156 (define_attr "type"
157   "unknown,branch,jump,call,load,fpload,store,fpstore,
158    mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul,
159    fmadd,fdiv,fcmp,fcvt,fsqrt,multi,nop,ghost"
160   (cond [(eq_attr "got" "load") (const_string "load")
162          ;; If a doubleword move uses these expensive instructions,
163          ;; it is usually better to schedule them in the same way
164          ;; as the singleword form, rather than as "multi".
165          (eq_attr "move_type" "load") (const_string "load")
166          (eq_attr "move_type" "fpload") (const_string "fpload")
167          (eq_attr "move_type" "store") (const_string "store")
168          (eq_attr "move_type" "fpstore") (const_string "fpstore")
169          (eq_attr "move_type" "mtc") (const_string "mtc")
170          (eq_attr "move_type" "mfc") (const_string "mfc")
172          ;; These types of move are always single insns.
173          (eq_attr "move_type" "fmove") (const_string "fmove")
174          (eq_attr "move_type" "arith") (const_string "arith")
175          (eq_attr "move_type" "logical") (const_string "logical")
176          (eq_attr "move_type" "andi") (const_string "logical")
178          ;; These types of move are always split.
179          (eq_attr "move_type" "shift_shift")
180            (const_string "multi")
182          ;; These types of move are split for doubleword modes only.
183          (and (eq_attr "move_type" "move,const")
184               (eq_attr "dword_mode" "yes"))
185            (const_string "multi")
186          (eq_attr "move_type" "move") (const_string "move")
187          (eq_attr "move_type" "const") (const_string "const")]
188         (const_string "unknown")))
190 ;; Length of instruction in bytes.
191 (define_attr "length" ""
192    (cond [
193           ;; Branches further than +/- 4 KiB require two instructions.
194           (eq_attr "type" "branch")
195           (if_then_else (and (le (minus (match_dup 0) (pc)) (const_int 4088))
196                                   (le (minus (pc) (match_dup 0)) (const_int 4092)))
197           (const_int 4)
198           (const_int 8))
200           ;; Conservatively assume calls take two instructions (AUIPC + JALR).
201           ;; The linker will opportunistically relax the sequence to JAL.
202           (eq_attr "type" "call") (const_int 8)
204           ;; "Ghost" instructions occupy no space.
205           (eq_attr "type" "ghost") (const_int 0)
207           (eq_attr "got" "load") (const_int 8)
209           (eq_attr "type" "fcmp") (const_int 8)
211           ;; SHIFT_SHIFTs are decomposed into two separate instructions.
212           (eq_attr "move_type" "shift_shift")
213                 (const_int 8)
215           ;; Check for doubleword moves that are decomposed into two
216           ;; instructions.
217           (and (eq_attr "move_type" "mtc,mfc,move")
218                (eq_attr "dword_mode" "yes"))
219           (const_int 8)
221           ;; Doubleword CONST{,N} moves are split into two word
222           ;; CONST{,N} moves.
223           (and (eq_attr "move_type" "const")
224                (eq_attr "dword_mode" "yes"))
225           (symbol_ref "riscv_split_const_insns (operands[1]) * 4")
227           ;; Otherwise, constants, loads and stores are handled by external
228           ;; routines.
229           (eq_attr "move_type" "load,fpload")
230           (symbol_ref "riscv_load_store_insns (operands[1], insn) * 4")
231           (eq_attr "move_type" "store,fpstore")
232           (symbol_ref "riscv_load_store_insns (operands[0], insn) * 4")
233           ] (const_int 4)))
235 ;; Is copying of this instruction disallowed?
236 (define_attr "cannot_copy" "no,yes" (const_string "no"))
238 ;; Describe a user's asm statement.
239 (define_asm_attributes
240   [(set_attr "type" "multi")])
242 ;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
243 ;; from the same template.
244 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
246 ;; This mode iterator allows :P to be used for patterns that operate on
247 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
248 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
250 ;; Likewise, but for XLEN-sized quantities.
251 (define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")])
253 ;; Branches operate on XLEN-sized quantities, but for RV64 we accept
254 ;; QImode values so we can force zero-extension.
255 (define_mode_iterator BR [(QI "TARGET_64BIT") SI (DI "TARGET_64BIT")])
257 ;; 32-bit moves for which we provide move patterns.
258 (define_mode_iterator MOVE32 [SI])
260 ;; 64-bit modes for which we provide move patterns.
261 (define_mode_iterator MOVE64 [DI DF])
263 ;; Iterator for sub-32-bit integer modes.
264 (define_mode_iterator SHORT [QI HI])
266 ;; Iterator for HImode constant generation.
267 (define_mode_iterator HISI [HI SI])
269 ;; Iterator for QImode extension patterns.
270 (define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")])
272 ;; Iterator for hardware integer modes narrower than XLEN.
273 (define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")])
275 ;; Iterator for hardware-supported integer modes.
276 (define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")])
278 ;; Iterator for hardware-supported floating-point modes.
279 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
280                             (DF "TARGET_DOUBLE_FLOAT")])
282 ;; Iterator for floating-point modes that can be loaded into X registers.
283 (define_mode_iterator SOFTF [SF (DF "TARGET_64BIT")])
285 ;; This attribute gives the length suffix for a sign- or zero-extension
286 ;; instruction.
287 (define_mode_attr size [(QI "b") (HI "h")])
289 ;; Mode attributes for loads.
290 (define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")])
292 ;; Instruction names for integer loads that aren't explicitly sign or zero
293 ;; extended.  See riscv_output_move and LOAD_EXTEND_OP.
294 (define_mode_attr default_load [(QI "lbu") (HI "lhu") (SI "lw") (DI "ld")])
296 ;; Mode attribute for FP loads into integer registers.
297 (define_mode_attr softload [(SF "lw") (DF "ld")])
299 ;; Instruction names for stores.
300 (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")])
302 ;; Instruction names for FP stores from integer registers.
303 (define_mode_attr softstore [(SF "sw") (DF "sd")])
305 ;; This attribute gives the best constraint to use for registers of
306 ;; a given mode.
307 (define_mode_attr reg [(SI "d") (DI "d") (CC "d")])
309 ;; This attribute gives the format suffix for floating-point operations.
310 (define_mode_attr fmt [(SF "s") (DF "d")])
312 ;; This attribute gives the integer suffix for floating-point conversions.
313 (define_mode_attr ifmt [(SI "w") (DI "l")])
315 ;; This attribute gives the format suffix for atomic memory operations.
316 (define_mode_attr amo [(SI "w") (DI "d")])
318 ;; This attribute gives the upper-case mode name for one unit of a
319 ;; floating-point mode.
320 (define_mode_attr UNITMODE [(SF "SF") (DF "DF")])
322 ;; This attribute gives the integer mode that has half the size of
323 ;; the controlling mode.
324 (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
326 ;; Iterator and attributes for floating-point rounding instructions.
327 (define_int_iterator RINT [UNSPEC_LRINT UNSPEC_LROUND])
328 (define_int_attr rint_pattern [(UNSPEC_LRINT "rint") (UNSPEC_LROUND "round")])
329 (define_int_attr rint_rm [(UNSPEC_LRINT "dyn") (UNSPEC_LROUND "rmm")])
331 ;; Iterator and attributes for quiet comparisons.
332 (define_int_iterator QUIET_COMPARISON [UNSPEC_FLT_QUIET UNSPEC_FLE_QUIET])
333 (define_int_attr quiet_pattern [(UNSPEC_FLT_QUIET "lt") (UNSPEC_FLE_QUIET "le")])
335 ;; This code iterator allows signed and unsigned widening multiplications
336 ;; to use the same template.
337 (define_code_iterator any_extend [sign_extend zero_extend])
339 ;; This code iterator allows the two right shift instructions to be
340 ;; generated from the same template.
341 (define_code_iterator any_shiftrt [ashiftrt lshiftrt])
343 ;; This code iterator allows the three shift instructions to be generated
344 ;; from the same template.
345 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
347 ;; This code iterator allows the three bitwise instructions to be generated
348 ;; from the same template.
349 (define_code_iterator any_bitwise [and ior xor])
351 ;; This code iterator allows unsigned and signed division to be generated
352 ;; from the same template.
353 (define_code_iterator any_div [div udiv mod umod])
355 ;; This code iterator allows unsigned and signed modulus to be generated
356 ;; from the same template.
357 (define_code_iterator any_mod [mod umod])
359 ;; These code iterators allow the signed and unsigned scc operations to use
360 ;; the same template.
361 (define_code_iterator any_gt [gt gtu])
362 (define_code_iterator any_ge [ge geu])
363 (define_code_iterator any_lt [lt ltu])
364 (define_code_iterator any_le [le leu])
366 ;; <u> expands to an empty string when doing a signed operation and
367 ;; "u" when doing an unsigned operation.
368 (define_code_attr u [(sign_extend "") (zero_extend "u")
369                      (gt "") (gtu "u")
370                      (ge "") (geu "u")
371                      (lt "") (ltu "u")
372                      (le "") (leu "u")])
374 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
375 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
377 ;; <optab> expands to the name of the optab for a particular code.
378 (define_code_attr optab [(ashift "ashl")
379                          (ashiftrt "ashr")
380                          (lshiftrt "lshr")
381                          (div "div")
382                          (mod "mod")
383                          (udiv "udiv")
384                          (umod "umod")
385                          (ge "ge")
386                          (le "le")
387                          (gt "gt")
388                          (lt "lt")
389                          (ior "ior")
390                          (xor "xor")
391                          (and "and")
392                          (plus "add")
393                          (minus "sub")])
395 ;; <insn> expands to the name of the insn that implements a particular code.
396 (define_code_attr insn [(ashift "sll")
397                         (ashiftrt "sra")
398                         (lshiftrt "srl")
399                         (div "div")
400                         (mod "rem")
401                         (udiv "divu")
402                         (umod "remu")
403                         (ior "or")
404                         (xor "xor")
405                         (and "and")
406                         (plus "add")
407                         (minus "sub")])
409 ;; Ghost instructions produce no real code and introduce no hazards.
410 ;; They exist purely to express an effect on dataflow.
411 (define_insn_reservation "ghost" 0
412   (eq_attr "type" "ghost")
413   "nothing")
416 ;;  ....................
418 ;;      ADDITION
420 ;;  ....................
423 (define_insn "add<mode>3"
424   [(set (match_operand:ANYF            0 "register_operand" "=f")
425         (plus:ANYF (match_operand:ANYF 1 "register_operand" " f")
426                    (match_operand:ANYF 2 "register_operand" " f")))]
427   "TARGET_HARD_FLOAT"
428   "fadd.<fmt>\t%0,%1,%2"
429   [(set_attr "type" "fadd")
430    (set_attr "mode" "<UNITMODE>")])
432 (define_insn "addsi3"
433   [(set (match_operand:SI          0 "register_operand" "=r,r")
434         (plus:SI (match_operand:SI 1 "register_operand" " r,r")
435                  (match_operand:SI 2 "arith_operand"    " r,I")))]
436   ""
437   { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
438   [(set_attr "type" "arith")
439    (set_attr "mode" "SI")])
441 (define_insn "adddi3"
442   [(set (match_operand:DI          0 "register_operand" "=r,r")
443         (plus:DI (match_operand:DI 1 "register_operand" " r,r")
444                  (match_operand:DI 2 "arith_operand"    " r,I")))]
445   "TARGET_64BIT"
446   "add%i2\t%0,%1,%2"
447   [(set_attr "type" "arith")
448    (set_attr "mode" "DI")])
450 (define_insn "*addsi3_extended"
451   [(set (match_operand:DI               0 "register_operand" "=r,r")
452         (sign_extend:DI
453              (plus:SI (match_operand:SI 1 "register_operand" " r,r")
454                       (match_operand:SI 2 "arith_operand"    " r,I"))))]
455   "TARGET_64BIT"
456   "add%i2w\t%0,%1,%2"
457   [(set_attr "type" "arith")
458    (set_attr "mode" "SI")])
460 (define_insn "*addsi3_extended2"
461   [(set (match_operand:DI                       0 "register_operand" "=r,r")
462         (sign_extend:DI
463           (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" " r,r")
464                               (match_operand:DI 2 "arith_operand"    " r,I"))
465                      0)))]
466   "TARGET_64BIT"
467   "add%i2w\t%0,%1,%2"
468   [(set_attr "type" "arith")
469    (set_attr "mode" "SI")])
472 ;;  ....................
474 ;;      SUBTRACTION
476 ;;  ....................
479 (define_insn "sub<mode>3"
480   [(set (match_operand:ANYF             0 "register_operand" "=f")
481         (minus:ANYF (match_operand:ANYF 1 "register_operand" " f")
482                     (match_operand:ANYF 2 "register_operand" " f")))]
483   "TARGET_HARD_FLOAT"
484   "fsub.<fmt>\t%0,%1,%2"
485   [(set_attr "type" "fadd")
486    (set_attr "mode" "<UNITMODE>")])
488 (define_insn "subdi3"
489   [(set (match_operand:DI 0            "register_operand" "= r")
490         (minus:DI (match_operand:DI 1  "reg_or_0_operand" " rJ")
491                    (match_operand:DI 2 "register_operand" "  r")))]
492   "TARGET_64BIT"
493   "sub\t%0,%z1,%2"
494   [(set_attr "type" "arith")
495    (set_attr "mode" "DI")])
497 (define_insn "subsi3"
498   [(set (match_operand:SI           0 "register_operand" "= r")
499         (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
500                   (match_operand:SI 2 "register_operand" "  r")))]
501   ""
502   { return TARGET_64BIT ? "subw\t%0,%z1,%2" : "sub\t%0,%z1,%2"; }
503   [(set_attr "type" "arith")
504    (set_attr "mode" "SI")])
506 (define_insn "*subsi3_extended"
507   [(set (match_operand:DI               0 "register_operand" "= r")
508         (sign_extend:DI
509             (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
510                       (match_operand:SI 2 "register_operand" "  r"))))]
511   "TARGET_64BIT"
512   "subw\t%0,%z1,%2"
513   [(set_attr "type" "arith")
514    (set_attr "mode" "SI")])
516 (define_insn "*subsi3_extended2"
517   [(set (match_operand:DI                        0 "register_operand" "= r")
518         (sign_extend:DI
519           (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" " rJ")
520                                (match_operand:DI 2 "register_operand" "  r"))
521                      0)))]
522   "TARGET_64BIT"
523   "subw\t%0,%z1,%2"
524   [(set_attr "type" "arith")
525    (set_attr "mode" "SI")])
527 (define_insn "negdi2"
528   [(set (match_operand:DI         0 "register_operand" "=r")
529         (neg:DI (match_operand:DI 1 "register_operand" " r")))]
530   "TARGET_64BIT"
531   "neg\t%0,%1"
532   [(set_attr "type" "arith")
533    (set_attr "mode" "DI")])
535 (define_insn "negsi2"
536   [(set (match_operand:SI         0 "register_operand" "=r")
537         (neg:SI (match_operand:SI 1 "register_operand" " r")))]
538   ""
539   { return TARGET_64BIT ? "negw\t%0,%1" : "neg\t%0,%1"; }
540   [(set_attr "type" "arith")
541    (set_attr "mode" "SI")])
543 (define_insn "*negsi2_extended"
544   [(set (match_operand:DI          0 "register_operand" "=r")
545         (sign_extend:DI
546          (neg:SI (match_operand:SI 1 "register_operand" " r"))))]
547   "TARGET_64BIT"
548   "negw\t%0,%1"
549   [(set_attr "type" "arith")
550    (set_attr "mode" "SI")])
552 (define_insn "*negsi2_extended2"
553   [(set (match_operand:DI                     0 "register_operand" "=r")
554         (sign_extend:DI
555          (subreg:SI (neg:DI (match_operand:DI 1 "register_operand" " r"))
556                     0)))]
557   "TARGET_64BIT"
558   "negw\t%0,%1"
559   [(set_attr "type" "arith")
560    (set_attr "mode" "SI")])
563 ;;  ....................
565 ;;      MULTIPLICATION
567 ;;  ....................
570 (define_insn "mul<mode>3"
571   [(set (match_operand:ANYF               0 "register_operand" "=f")
572         (mult:ANYF (match_operand:ANYF    1 "register_operand" " f")
573                       (match_operand:ANYF 2 "register_operand" " f")))]
574   "TARGET_HARD_FLOAT"
575   "fmul.<fmt>\t%0,%1,%2"
576   [(set_attr "type" "fmul")
577    (set_attr "mode" "<UNITMODE>")])
579 (define_insn "mulsi3"
580   [(set (match_operand:SI          0 "register_operand" "=r")
581         (mult:SI (match_operand:SI 1 "register_operand" " r")
582                  (match_operand:SI 2 "register_operand" " r")))]
583   "TARGET_MUL"
584   { return TARGET_64BIT ? "mulw\t%0,%1,%2" : "mul\t%0,%1,%2"; }
585   [(set_attr "type" "imul")
586    (set_attr "mode" "SI")])
588 (define_insn "muldi3"
589   [(set (match_operand:DI          0 "register_operand" "=r")
590         (mult:DI (match_operand:DI 1 "register_operand" " r")
591                  (match_operand:DI 2 "register_operand" " r")))]
592   "TARGET_MUL && TARGET_64BIT"
593   "mul\t%0,%1,%2"
594   [(set_attr "type" "imul")
595    (set_attr "mode" "DI")])
597 (define_insn "*mulsi3_extended"
598   [(set (match_operand:DI              0 "register_operand" "=r")
599         (sign_extend:DI
600             (mult:SI (match_operand:SI 1 "register_operand" " r")
601                      (match_operand:SI 2 "register_operand" " r"))))]
602   "TARGET_MUL && TARGET_64BIT"
603   "mulw\t%0,%1,%2"
604   [(set_attr "type" "imul")
605    (set_attr "mode" "SI")])
607 (define_insn "*mulsi3_extended2"
608   [(set (match_operand:DI                       0 "register_operand" "=r")
609         (sign_extend:DI
610           (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" " r")
611                               (match_operand:DI 2 "register_operand" " r"))
612                      0)))]
613   "TARGET_MUL && TARGET_64BIT"
614   "mulw\t%0,%1,%2"
615   [(set_attr "type" "imul")
616    (set_attr "mode" "SI")])
619 ;;  ........................
621 ;;      MULTIPLICATION HIGH-PART
623 ;;  ........................
627 (define_expand "<u>mulditi3"
628   [(set (match_operand:TI                         0 "register_operand")
629         (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
630                  (any_extend:TI (match_operand:DI 2 "register_operand"))))]
631   "TARGET_MUL && TARGET_64BIT"
633   rtx low = gen_reg_rtx (DImode);
634   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
636   rtx high = gen_reg_rtx (DImode);
637   emit_insn (gen_<u>muldi3_highpart (high, operands[1], operands[2]));
639   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
640   emit_move_insn (gen_highpart (DImode, operands[0]), high);
641   DONE;
644 (define_insn "<u>muldi3_highpart"
645   [(set (match_operand:DI                0 "register_operand" "=r")
646         (truncate:DI
647           (lshiftrt:TI
648             (mult:TI (any_extend:TI
649                        (match_operand:DI 1 "register_operand" " r"))
650                      (any_extend:TI
651                        (match_operand:DI 2 "register_operand" " r")))
652             (const_int 64))))]
653   "TARGET_MUL && TARGET_64BIT"
654   "mulh<u>\t%0,%1,%2"
655   [(set_attr "type" "imul")
656    (set_attr "mode" "DI")])
658 (define_expand "usmulditi3"
659   [(set (match_operand:TI                          0 "register_operand")
660         (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand"))
661                  (sign_extend:TI (match_operand:DI 2 "register_operand"))))]
662   "TARGET_MUL && TARGET_64BIT"
664   rtx low = gen_reg_rtx (DImode);
665   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
667   rtx high = gen_reg_rtx (DImode);
668   emit_insn (gen_usmuldi3_highpart (high, operands[1], operands[2]));
670   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
671   emit_move_insn (gen_highpart (DImode, operands[0]), high);
672   DONE;
675 (define_insn "usmuldi3_highpart"
676   [(set (match_operand:DI                0 "register_operand" "=r")
677         (truncate:DI
678           (lshiftrt:TI
679             (mult:TI (zero_extend:TI
680                        (match_operand:DI 1 "register_operand"  "r"))
681                      (sign_extend:TI
682                        (match_operand:DI 2 "register_operand" " r")))
683             (const_int 64))))]
684   "TARGET_MUL && TARGET_64BIT"
685   "mulhsu\t%0,%2,%1"
686   [(set_attr "type" "imul")
687    (set_attr "mode" "DI")])
689 (define_expand "<u>mulsidi3"
690   [(set (match_operand:DI            0 "register_operand" "=r")
691         (mult:DI (any_extend:DI
692                    (match_operand:SI 1 "register_operand" " r"))
693                  (any_extend:DI
694                    (match_operand:SI 2 "register_operand" " r"))))]
695   "TARGET_MUL && !TARGET_64BIT"
697   rtx temp = gen_reg_rtx (SImode);
698   emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
699   emit_insn (gen_<u>mulsi3_highpart (riscv_subword (operands[0], true),
700                                      operands[1], operands[2]));
701   emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
702   DONE;
705 (define_insn "<u>mulsi3_highpart"
706   [(set (match_operand:SI                0 "register_operand" "=r")
707         (truncate:SI
708           (lshiftrt:DI
709             (mult:DI (any_extend:DI
710                        (match_operand:SI 1 "register_operand" " r"))
711                      (any_extend:DI
712                        (match_operand:SI 2 "register_operand" " r")))
713             (const_int 32))))]
714   "TARGET_MUL && !TARGET_64BIT"
715   "mulh<u>\t%0,%1,%2"
716   [(set_attr "type" "imul")
717    (set_attr "mode" "SI")])
720 (define_expand "usmulsidi3"
721   [(set (match_operand:DI            0 "register_operand" "=r")
722         (mult:DI (zero_extend:DI
723                    (match_operand:SI 1 "register_operand" " r"))
724                  (sign_extend:DI
725                    (match_operand:SI 2 "register_operand" " r"))))]
726   "TARGET_MUL && !TARGET_64BIT"
728   rtx temp = gen_reg_rtx (SImode);
729   emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
730   emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true),
731                                      operands[1], operands[2]));
732   emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
733   DONE;
736 (define_insn "usmulsi3_highpart"
737   [(set (match_operand:SI                0 "register_operand" "=r")
738         (truncate:SI
739           (lshiftrt:DI
740             (mult:DI (zero_extend:DI
741                        (match_operand:SI 1 "register_operand" " r"))
742                      (sign_extend:DI
743                        (match_operand:SI 2 "register_operand" " r")))
744             (const_int 32))))]
745   "TARGET_MUL && !TARGET_64BIT"
746   "mulhsu\t%0,%2,%1"
747   [(set_attr "type" "imul")
748    (set_attr "mode" "SI")])
751 ;;  ....................
753 ;;      DIVISION and REMAINDER
755 ;;  ....................
758 (define_insn "<optab>si3"
759   [(set (match_operand:SI             0 "register_operand" "=r")
760         (any_div:SI (match_operand:SI 1 "register_operand" " r")
761                     (match_operand:SI 2 "register_operand" " r")))]
762   "TARGET_DIV"
763   { return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2"; }
764   [(set_attr "type" "idiv")
765    (set_attr "mode" "SI")])
767 (define_insn "<optab>di3"
768   [(set (match_operand:DI             0 "register_operand" "=r")
769         (any_div:DI (match_operand:DI 1 "register_operand" " r")
770                     (match_operand:DI 2 "register_operand" " r")))]
771   "TARGET_DIV && TARGET_64BIT"
772   "<insn>%i2\t%0,%1,%2"
773   [(set_attr "type" "idiv")
774    (set_attr "mode" "DI")])
776 (define_insn "*<optab>si3_extended"
777   [(set (match_operand:DI                 0 "register_operand" "=r")
778         (sign_extend:DI
779             (any_div:SI (match_operand:SI 1 "register_operand" " r")
780                         (match_operand:SI 2 "register_operand" " r"))))]
781   "TARGET_DIV && TARGET_64BIT"
782   "<insn>%i2w\t%0,%1,%2"
783   [(set_attr "type" "idiv")
784    (set_attr "mode" "DI")])
786 (define_insn "div<mode>3"
787   [(set (match_operand:ANYF           0 "register_operand" "=f")
788         (div:ANYF (match_operand:ANYF 1 "register_operand" " f")
789                   (match_operand:ANYF 2 "register_operand" " f")))]
790   "TARGET_HARD_FLOAT && TARGET_FDIV"
791   "fdiv.<fmt>\t%0,%1,%2"
792   [(set_attr "type" "fdiv")
793    (set_attr "mode" "<UNITMODE>")])
796 ;;  ....................
798 ;;      SQUARE ROOT
800 ;;  ....................
802 (define_insn "sqrt<mode>2"
803   [(set (match_operand:ANYF            0 "register_operand" "=f")
804         (sqrt:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
805   "TARGET_HARD_FLOAT && TARGET_FDIV"
807     return "fsqrt.<fmt>\t%0,%1";
809   [(set_attr "type" "fsqrt")
810    (set_attr "mode" "<UNITMODE>")])
812 ;; Floating point multiply accumulate instructions.
814 ;; a * b + c
815 (define_insn "fma<mode>4"
816   [(set (match_operand:ANYF           0 "register_operand" "=f")
817         (fma:ANYF (match_operand:ANYF 1 "register_operand" " f")
818                   (match_operand:ANYF 2 "register_operand" " f")
819                   (match_operand:ANYF 3 "register_operand" " f")))]
820   "TARGET_HARD_FLOAT"
821   "fmadd.<fmt>\t%0,%1,%2,%3"
822   [(set_attr "type" "fmadd")
823    (set_attr "mode" "<UNITMODE>")])
825 ;; a * b - c
826 (define_insn "fms<mode>4"
827   [(set (match_operand:ANYF                     0 "register_operand" "=f")
828         (fma:ANYF (match_operand:ANYF           1 "register_operand" " f")
829                   (match_operand:ANYF           2 "register_operand" " f")
830                   (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
831   "TARGET_HARD_FLOAT"
832   "fmsub.<fmt>\t%0,%1,%2,%3"
833   [(set_attr "type" "fmadd")
834    (set_attr "mode" "<UNITMODE>")])
836 ;; -a * b - c
837 (define_insn "fnms<mode>4"
838   [(set (match_operand:ANYF               0 "register_operand" "=f")
839         (fma:ANYF
840             (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
841             (match_operand:ANYF           2 "register_operand" " f")
842             (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
843   "TARGET_HARD_FLOAT"
844   "fnmadd.<fmt>\t%0,%1,%2,%3"
845   [(set_attr "type" "fmadd")
846    (set_attr "mode" "<UNITMODE>")])
848 ;; -a * b + c
849 (define_insn "fnma<mode>4"
850   [(set (match_operand:ANYF               0 "register_operand" "=f")
851         (fma:ANYF
852             (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
853             (match_operand:ANYF           2 "register_operand" " f")
854             (match_operand:ANYF           3 "register_operand" " f")))]
855   "TARGET_HARD_FLOAT"
856   "fnmsub.<fmt>\t%0,%1,%2,%3"
857   [(set_attr "type" "fmadd")
858    (set_attr "mode" "<UNITMODE>")])
860 ;; -(-a * b - c), modulo signed zeros
861 (define_insn "*fma<mode>4"
862   [(set (match_operand:ANYF                   0 "register_operand" "=f")
863         (neg:ANYF
864             (fma:ANYF
865                 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
866                 (match_operand:ANYF           2 "register_operand" " f")
867                 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
868   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
869   "fmadd.<fmt>\t%0,%1,%2,%3"
870   [(set_attr "type" "fmadd")
871    (set_attr "mode" "<UNITMODE>")])
873 ;; -(-a * b + c), modulo signed zeros
874 (define_insn "*fms<mode>4"
875   [(set (match_operand:ANYF                   0 "register_operand" "=f")
876         (neg:ANYF
877             (fma:ANYF
878                 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
879                 (match_operand:ANYF           2 "register_operand" " f")
880                 (match_operand:ANYF           3 "register_operand" " f"))))]
881   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
882   "fmsub.<fmt>\t%0,%1,%2,%3"
883   [(set_attr "type" "fmadd")
884    (set_attr "mode" "<UNITMODE>")])
886 ;; -(a * b + c), modulo signed zeros
887 (define_insn "*fnms<mode>4"
888   [(set (match_operand:ANYF         0 "register_operand" "=f")
889         (neg:ANYF
890             (fma:ANYF
891                 (match_operand:ANYF 1 "register_operand" " f")
892                 (match_operand:ANYF 2 "register_operand" " f")
893                 (match_operand:ANYF 3 "register_operand" " f"))))]
894   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
895   "fnmadd.<fmt>\t%0,%1,%2,%3"
896   [(set_attr "type" "fmadd")
897    (set_attr "mode" "<UNITMODE>")])
899 ;; -(a * b - c), modulo signed zeros
900 (define_insn "*fnma<mode>4"
901   [(set (match_operand:ANYF                   0 "register_operand" "=f")
902         (neg:ANYF
903             (fma:ANYF
904                 (match_operand:ANYF           1 "register_operand" " f")
905                 (match_operand:ANYF           2 "register_operand" " f")
906                 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
907   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
908   "fnmsub.<fmt>\t%0,%1,%2,%3"
909   [(set_attr "type" "fmadd")
910    (set_attr "mode" "<UNITMODE>")])
913 ;;  ....................
915 ;;      SIGN INJECTION
917 ;;  ....................
919 (define_insn "abs<mode>2"
920   [(set (match_operand:ANYF           0 "register_operand" "=f")
921         (abs:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
922   "TARGET_HARD_FLOAT"
923   "fabs.<fmt>\t%0,%1"
924   [(set_attr "type" "fmove")
925    (set_attr "mode" "<UNITMODE>")])
927 (define_insn "copysign<mode>3"
928   [(set (match_operand:ANYF 0 "register_operand"               "=f")
929         (unspec:ANYF [(match_operand:ANYF 1 "register_operand" " f")
930                       (match_operand:ANYF 2 "register_operand" " f")]
931                      UNSPEC_COPYSIGN))]
932   "TARGET_HARD_FLOAT"
933   "fsgnj.<fmt>\t%0,%1,%2"
934   [(set_attr "type" "fmove")
935    (set_attr "mode" "<UNITMODE>")])
937 (define_insn "neg<mode>2"
938   [(set (match_operand:ANYF           0 "register_operand" "=f")
939         (neg:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
940   "TARGET_HARD_FLOAT"
941   "fneg.<fmt>\t%0,%1"
942   [(set_attr "type" "fmove")
943    (set_attr "mode" "<UNITMODE>")])
946 ;;  ....................
948 ;;      MIN/MAX
950 ;;  ....................
952 (define_insn "smin<mode>3"
953   [(set (match_operand:ANYF            0 "register_operand" "=f")
954         (smin:ANYF (match_operand:ANYF 1 "register_operand" " f")
955                    (match_operand:ANYF 2 "register_operand" " f")))]
956   "TARGET_HARD_FLOAT"
957   "fmin.<fmt>\t%0,%1,%2"
958   [(set_attr "type" "fmove")
959    (set_attr "mode" "<UNITMODE>")])
961 (define_insn "smax<mode>3"
962   [(set (match_operand:ANYF            0 "register_operand" "=f")
963         (smax:ANYF (match_operand:ANYF 1 "register_operand" " f")
964                    (match_operand:ANYF 2 "register_operand" " f")))]
965   "TARGET_HARD_FLOAT"
966   "fmax.<fmt>\t%0,%1,%2"
967   [(set_attr "type" "fmove")
968    (set_attr "mode" "<UNITMODE>")])
971 ;;  ....................
973 ;;      LOGICAL
975 ;;  ....................
978 ;; For RV64, we don't expose the SImode operations to the rtl expanders,
979 ;; but SImode versions exist for combine.
981 (define_insn "<optab><mode>3"
982   [(set (match_operand:X                0 "register_operand" "=r,r")
983         (any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
984                        (match_operand:X 2 "arith_operand"    " r,I")))]
985   ""
986   "<insn>%i2\t%0,%1,%2"
987   [(set_attr "type" "logical")
988    (set_attr "mode" "<MODE>")])
990 (define_insn "*<optab>si3_internal"
991   [(set (match_operand:SI                 0 "register_operand" "=r,r")
992         (any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r")
993                         (match_operand:SI 2 "arith_operand"    " r,I")))]
994   "TARGET_64BIT"
995   "<insn>%i2\t%0,%1,%2"
996   [(set_attr "type" "logical")
997    (set_attr "mode" "SI")])
999 (define_insn "one_cmpl<mode>2"
1000   [(set (match_operand:X        0 "register_operand" "=r")
1001         (not:X (match_operand:X 1 "register_operand" " r")))]
1002   ""
1003   "not\t%0,%1"
1004   [(set_attr "type" "logical")
1005    (set_attr "mode" "<MODE>")])
1007 (define_insn "*one_cmplsi2_internal"
1008   [(set (match_operand:SI         0 "register_operand" "=r")
1009         (not:SI (match_operand:SI 1 "register_operand" " r")))]
1010   "TARGET_64BIT"
1011   "not\t%0,%1"
1012   [(set_attr "type" "logical")
1013    (set_attr "mode" "SI")])
1016 ;;  ....................
1018 ;;      TRUNCATION
1020 ;;  ....................
1022 (define_insn "truncdfsf2"
1023   [(set (match_operand:SF     0 "register_operand" "=f")
1024         (float_truncate:SF
1025             (match_operand:DF 1 "register_operand" " f")))]
1026   "TARGET_DOUBLE_FLOAT"
1027   "fcvt.s.d\t%0,%1"
1028   [(set_attr "type" "fcvt")
1029    (set_attr "mode" "SF")])
1032 ;;  ....................
1034 ;;      ZERO EXTENSION
1036 ;;  ....................
1038 ;; Extension insns.
1040 (define_insn_and_split "zero_extendsidi2"
1041   [(set (match_operand:DI     0 "register_operand"     "=r,r")
1042         (zero_extend:DI
1043             (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
1044   "TARGET_64BIT"
1045   "@
1046    #
1047    lwu\t%0,%1"
1048   "&& reload_completed && REG_P (operands[1])"
1049   [(set (match_dup 0)
1050         (ashift:DI (match_dup 1) (const_int 32)))
1051    (set (match_dup 0)
1052         (lshiftrt:DI (match_dup 0) (const_int 32)))]
1053   { operands[1] = gen_lowpart (DImode, operands[1]); }
1054   [(set_attr "move_type" "shift_shift,load")
1055    (set_attr "mode" "DI")])
1057 (define_insn_and_split "zero_extendhi<GPR:mode>2"
1058   [(set (match_operand:GPR    0 "register_operand"     "=r,r")
1059         (zero_extend:GPR
1060             (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
1061   ""
1062   "@
1063    #
1064    lhu\t%0,%1"
1065   "&& reload_completed && REG_P (operands[1])"
1066   [(set (match_dup 0)
1067         (ashift:GPR (match_dup 1) (match_dup 2)))
1068    (set (match_dup 0)
1069         (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
1070   {
1071     operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
1072     operands[2] = GEN_INT(GET_MODE_BITSIZE(<GPR:MODE>mode) - 16);
1073   }
1074   [(set_attr "move_type" "shift_shift,load")
1075    (set_attr "mode" "<GPR:MODE>")])
1077 (define_insn "zero_extendqi<SUPERQI:mode>2"
1078   [(set (match_operand:SUPERQI 0 "register_operand"    "=r,r")
1079         (zero_extend:SUPERQI
1080             (match_operand:QI 1 "nonimmediate_operand" " r,m")))]
1081   ""
1082   "@
1083    andi\t%0,%1,0xff
1084    lbu\t%0,%1"
1085   [(set_attr "move_type" "andi,load")
1086    (set_attr "mode" "<SUPERQI:MODE>")])
1089 ;;  ....................
1091 ;;      SIGN EXTENSION
1093 ;;  ....................
1095 (define_insn "extendsidi2"
1096   [(set (match_operand:DI     0 "register_operand"     "=r,r")
1097         (sign_extend:DI
1098             (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
1099   "TARGET_64BIT"
1100   "@
1101    sext.w\t%0,%1
1102    lw\t%0,%1"
1103   [(set_attr "move_type" "move,load")
1104    (set_attr "mode" "DI")])
1106 (define_insn_and_split "extend<SHORT:mode><SUPERQI:mode>2"
1107   [(set (match_operand:SUPERQI   0 "register_operand"     "=r,r")
1108         (sign_extend:SUPERQI
1109             (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
1110   ""
1111   "@
1112    #
1113    l<SHORT:size>\t%0,%1"
1114   "&& reload_completed && REG_P (operands[1])"
1115   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1116    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
1118   operands[0] = gen_lowpart (SImode, operands[0]);
1119   operands[1] = gen_lowpart (SImode, operands[1]);
1120   operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
1121                          - GET_MODE_BITSIZE (<SHORT:MODE>mode));
1123   [(set_attr "move_type" "shift_shift,load")
1124    (set_attr "mode" "SI")])
1126 (define_insn "extendsfdf2"
1127   [(set (match_operand:DF     0 "register_operand" "=f")
1128         (float_extend:DF
1129             (match_operand:SF 1 "register_operand" " f")))]
1130   "TARGET_DOUBLE_FLOAT"
1131   "fcvt.d.s\t%0,%1"
1132   [(set_attr "type" "fcvt")
1133    (set_attr "mode" "DF")])
1136 ;;  ....................
1138 ;;      CONVERSIONS
1140 ;;  ....................
1142 (define_insn "fix_trunc<ANYF:mode><GPR:mode>2"
1143   [(set (match_operand:GPR      0 "register_operand" "=r")
1144         (fix:GPR
1145             (match_operand:ANYF 1 "register_operand" " f")))]
1146   "TARGET_HARD_FLOAT"
1147   "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,rtz"
1148   [(set_attr "type" "fcvt")
1149    (set_attr "mode" "<ANYF:MODE>")])
1151 (define_insn "fixuns_trunc<ANYF:mode><GPR:mode>2"
1152   [(set (match_operand:GPR      0 "register_operand" "=r")
1153         (unsigned_fix:GPR
1154             (match_operand:ANYF 1 "register_operand" " f")))]
1155   "TARGET_HARD_FLOAT"
1156   "fcvt.<GPR:ifmt>u.<ANYF:fmt> %0,%1,rtz"
1157   [(set_attr "type" "fcvt")
1158    (set_attr "mode" "<ANYF:MODE>")])
1160 (define_insn "float<GPR:mode><ANYF:mode>2"
1161   [(set (match_operand:ANYF    0 "register_operand" "= f")
1162         (float:ANYF
1163             (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1164   "TARGET_HARD_FLOAT"
1165   "fcvt.<ANYF:fmt>.<GPR:ifmt>\t%0,%z1"
1166   [(set_attr "type" "fcvt")
1167    (set_attr "mode" "<ANYF:MODE>")])
1169 (define_insn "floatuns<GPR:mode><ANYF:mode>2"
1170   [(set (match_operand:ANYF    0 "register_operand" "= f")
1171         (unsigned_float:ANYF
1172             (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1173   "TARGET_HARD_FLOAT"
1174   "fcvt.<ANYF:fmt>.<GPR:ifmt>u\t%0,%z1"
1175   [(set_attr "type" "fcvt")
1176    (set_attr "mode" "<ANYF:MODE>")])
1178 (define_insn "l<rint_pattern><ANYF:mode><GPR:mode>2"
1179   [(set (match_operand:GPR       0 "register_operand" "=r")
1180         (unspec:GPR
1181             [(match_operand:ANYF 1 "register_operand" " f")]
1182             RINT))]
1183   "TARGET_HARD_FLOAT"
1184   "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,<rint_rm>"
1185   [(set_attr "type" "fcvt")
1186    (set_attr "mode" "<ANYF:MODE>")])
1189 ;;  ....................
1191 ;;      DATA MOVEMENT
1193 ;;  ....................
1195 ;; Lower-level instructions for loading an address from the GOT.
1196 ;; We could use MEMs, but an unspec gives more optimization
1197 ;; opportunities.
1199 (define_insn "got_load<mode>"
1200    [(set (match_operand:P      0 "register_operand" "=r")
1201          (unspec:P
1202              [(match_operand:P 1 "symbolic_operand" "")]
1203              UNSPEC_LOAD_GOT))]
1204   ""
1205   "la\t%0,%1"
1206    [(set_attr "got" "load")
1207     (set_attr "mode" "<MODE>")])
1209 (define_insn "tls_add_tp_le<mode>"
1210   [(set (match_operand:P      0 "register_operand" "=r")
1211         (unspec:P
1212             [(match_operand:P 1 "register_operand" "r")
1213              (match_operand:P 2 "register_operand" "r")
1214              (match_operand:P 3 "symbolic_operand" "")]
1215             UNSPEC_TLS_LE))]
1216   ""
1217   "add\t%0,%1,%2,%%tprel_add(%3)"
1218   [(set_attr "type" "arith")
1219    (set_attr "mode" "<MODE>")])
1221 (define_insn "got_load_tls_gd<mode>"
1222   [(set (match_operand:P      0 "register_operand" "=r")
1223         (unspec:P
1224             [(match_operand:P 1 "symbolic_operand" "")]
1225             UNSPEC_TLS_GD))]
1226   ""
1227   "la.tls.gd\t%0,%1"
1228   [(set_attr "got" "load")
1229    (set_attr "mode" "<MODE>")])
1231 (define_insn "got_load_tls_ie<mode>"
1232   [(set (match_operand:P      0 "register_operand" "=r")
1233         (unspec:P
1234             [(match_operand:P 1 "symbolic_operand" "")]
1235             UNSPEC_TLS_IE))]
1236   ""
1237   "la.tls.ie\t%0,%1"
1238   [(set_attr "got" "load")
1239    (set_attr "mode" "<MODE>")])
1241 (define_insn "auipc<mode>"
1242   [(set (match_operand:P           0 "register_operand" "=r")
1243         (unspec:P
1244             [(match_operand:P      1 "symbolic_operand" "")
1245                   (match_operand:P 2 "const_int_operand")
1246                   (pc)]
1247             UNSPEC_AUIPC))]
1248   ""
1249   ".LA%2: auipc\t%0,%h1"
1250   [(set_attr "type" "arith")
1251    (set_attr "cannot_copy" "yes")])
1253 ;; Instructions for adding the low 12 bits of an address to a register.
1254 ;; Operand 2 is the address: riscv_print_operand works out which relocation
1255 ;; should be applied.
1257 (define_insn "*low<mode>"
1258   [(set (match_operand:P           0 "register_operand" "=r")
1259         (lo_sum:P (match_operand:P 1 "register_operand" " r")
1260                   (match_operand:P 2 "symbolic_operand" "")))]
1261   ""
1262   "addi\t%0,%1,%R2"
1263   [(set_attr "type" "arith")
1264    (set_attr "mode" "<MODE>")])
1266 ;; Allow combine to split complex const_int load sequences, using operand 2
1267 ;; to store the intermediate results.  See move_operand for details.
1268 (define_split
1269   [(set (match_operand:GPR 0 "register_operand")
1270         (match_operand:GPR 1 "splittable_const_int_operand"))
1271    (clobber (match_operand:GPR 2 "register_operand"))]
1272   ""
1273   [(const_int 0)]
1275   riscv_move_integer (operands[2], operands[0], INTVAL (operands[1]));
1276   DONE;
1279 ;; Likewise, for symbolic operands.
1280 (define_split
1281   [(set (match_operand:P 0 "register_operand")
1282         (match_operand:P 1))
1283    (clobber (match_operand:P 2 "register_operand"))]
1284   "riscv_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
1285   [(set (match_dup 0) (match_dup 3))]
1287   riscv_split_symbol (operands[2], operands[1],
1288                      MAX_MACHINE_MODE, &operands[3]);
1291 ;; 64-bit integer moves
1293 (define_expand "movdi"
1294   [(set (match_operand:DI 0 "")
1295         (match_operand:DI 1 ""))]
1296   ""
1298   if (riscv_legitimize_move (DImode, operands[0], operands[1]))
1299     DONE;
1302 (define_insn "*movdi_32bit"
1303   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,  *f,*f,*r,*f,*m")
1304         (match_operand:DI 1 "move_operand"         " r,i,m,r,*J*r,*m,*f,*f,*f"))]
1305   "!TARGET_64BIT
1306    && (register_operand (operands[0], DImode)
1307        || reg_or_0_operand (operands[1], DImode))"
1308   { return riscv_output_move (operands[0], operands[1]); }
1309   [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1310    (set_attr "mode" "DI")])
1312 (define_insn "*movdi_64bit"
1313   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*f,*r,*f,*m")
1314         (match_operand:DI 1 "move_operand"         " r,T,m,rJ,*r*J,*m,*f,*f,*f"))]
1315   "TARGET_64BIT
1316    && (register_operand (operands[0], DImode)
1317        || reg_or_0_operand (operands[1], DImode))"
1318   { return riscv_output_move (operands[0], operands[1]); }
1319   [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1320    (set_attr "mode" "DI")])
1322 ;; 32-bit Integer moves
1324 (define_expand "mov<mode>"
1325   [(set (match_operand:MOVE32 0 "")
1326         (match_operand:MOVE32 1 ""))]
1327   ""
1329   if (riscv_legitimize_move (<MODE>mode, operands[0], operands[1]))
1330     DONE;
1333 (define_insn "*movsi_internal"
1334   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*f,*r,*m")
1335         (match_operand:SI 1 "move_operand"         " r,T,m,rJ,*r*J,*m,*f,*f"))]
1336   "(register_operand (operands[0], SImode)
1337     || reg_or_0_operand (operands[1], SImode))"
1338   { return riscv_output_move (operands[0], operands[1]); }
1339   [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore")
1340    (set_attr "mode" "SI")])
1342 ;; 16-bit Integer moves
1344 ;; Unlike most other insns, the move insns can't be split with
1345 ;; different predicates, because register spilling and other parts of
1346 ;; the compiler, have memoized the insn number already.
1347 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
1349 (define_expand "movhi"
1350   [(set (match_operand:HI 0 "")
1351         (match_operand:HI 1 ""))]
1352   ""
1354   if (riscv_legitimize_move (HImode, operands[0], operands[1]))
1355     DONE;
1358 (define_insn "*movhi_internal"
1359   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*r")
1360         (match_operand:HI 1 "move_operand"         " r,T,m,rJ,*r*J,*f"))]
1361   "(register_operand (operands[0], HImode)
1362     || reg_or_0_operand (operands[1], HImode))"
1363   { return riscv_output_move (operands[0], operands[1]); }
1364   [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1365    (set_attr "mode" "HI")])
1367 ;; HImode constant generation; see riscv_move_integer for details.
1368 ;; si+si->hi without truncation is legal because of
1369 ;; TARGET_TRULY_NOOP_TRUNCATION.
1371 (define_insn "*add<mode>hi3"
1372   [(set (match_operand:HI            0 "register_operand" "=r,r")
1373         (plus:HI (match_operand:HISI 1 "register_operand" " r,r")
1374                  (match_operand:HISI 2 "arith_operand"    " r,I")))]
1375   ""
1376   { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
1377   [(set_attr "type" "arith")
1378    (set_attr "mode" "HI")])
1380 (define_insn "*xor<mode>hi3"
1381   [(set (match_operand:HI 0 "register_operand"           "=r,r")
1382         (xor:HI (match_operand:HISI 1 "register_operand" " r,r")
1383                 (match_operand:HISI 2 "arith_operand"    " r,I")))]
1384   ""
1385   "xor%i2\t%0,%1,%2"
1386   [(set_attr "type" "logical")
1387    (set_attr "mode" "HI")])
1389 ;; 8-bit Integer moves
1391 (define_expand "movqi"
1392   [(set (match_operand:QI 0 "")
1393         (match_operand:QI 1 ""))]
1394   ""
1396   if (riscv_legitimize_move (QImode, operands[0], operands[1]))
1397     DONE;
1400 (define_insn "*movqi_internal"
1401   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*r")
1402         (match_operand:QI 1 "move_operand"         " r,I,m,rJ,*r*J,*f"))]
1403   "(register_operand (operands[0], QImode)
1404     || reg_or_0_operand (operands[1], QImode))"
1405   { return riscv_output_move (operands[0], operands[1]); }
1406   [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1407    (set_attr "mode" "QI")])
1409 ;; 32-bit floating point moves
1411 (define_expand "movsf"
1412   [(set (match_operand:SF 0 "")
1413         (match_operand:SF 1 ""))]
1414   ""
1416   if (riscv_legitimize_move (SFmode, operands[0], operands[1]))
1417     DONE;
1420 (define_insn "*movsf_hardfloat"
1421   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,  *r,*r,*m")
1422         (match_operand:SF 1 "move_operand"         " f,G,m,f,G,*r,*f,*G*r,*m,*r"))]
1423   "TARGET_HARD_FLOAT
1424    && (register_operand (operands[0], SFmode)
1425        || reg_or_0_operand (operands[1], SFmode))"
1426   { return riscv_output_move (operands[0], operands[1]); }
1427   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1428    (set_attr "mode" "SF")])
1430 (define_insn "*movsf_softfloat"
1431   [(set (match_operand:SF 0 "nonimmediate_operand" "= r,r,m")
1432         (match_operand:SF 1 "move_operand"         " Gr,m,r"))]
1433   "!TARGET_HARD_FLOAT
1434    && (register_operand (operands[0], SFmode)
1435        || reg_or_0_operand (operands[1], SFmode))"
1436   { return riscv_output_move (operands[0], operands[1]); }
1437   [(set_attr "move_type" "move,load,store")
1438    (set_attr "mode" "SF")])
1440 ;; 64-bit floating point moves
1442 (define_expand "movdf"
1443   [(set (match_operand:DF 0 "")
1444         (match_operand:DF 1 ""))]
1445   ""
1447   if (riscv_legitimize_move (DFmode, operands[0], operands[1]))
1448     DONE;
1451 ;; In RV32, we lack fmv.x.d and fmv.d.x.  Go through memory instead.
1452 ;; (However, we can still use fcvt.d.w to zero a floating-point register.)
1453 (define_insn "*movdf_hardfloat_rv32"
1454   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,  *r,*r,*m")
1455         (match_operand:DF 1 "move_operand"         " f,G,m,f,G,*r*G,*m,*r"))]
1456   "!TARGET_64BIT && TARGET_DOUBLE_FLOAT
1457    && (register_operand (operands[0], DFmode)
1458        || reg_or_0_operand (operands[1], DFmode))"
1459   { return riscv_output_move (operands[0], operands[1]); }
1460   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,move,load,store")
1461    (set_attr "mode" "DF")])
1463 (define_insn "*movdf_hardfloat_rv64"
1464   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,  *r,*r,*m")
1465         (match_operand:DF 1 "move_operand"         " f,G,m,f,G,*r,*f,*r*G,*m,*r"))]
1466   "TARGET_64BIT && TARGET_DOUBLE_FLOAT
1467    && (register_operand (operands[0], DFmode)
1468        || reg_or_0_operand (operands[1], DFmode))"
1469   { return riscv_output_move (operands[0], operands[1]); }
1470   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1471    (set_attr "mode" "DF")])
1473 (define_insn "*movdf_softfloat"
1474   [(set (match_operand:DF 0 "nonimmediate_operand" "= r,r, m")
1475         (match_operand:DF 1 "move_operand"         " rG,m,rG"))]
1476   "!TARGET_DOUBLE_FLOAT
1477    && (register_operand (operands[0], DFmode)
1478        || reg_or_0_operand (operands[1], DFmode))"
1479   { return riscv_output_move (operands[0], operands[1]); }
1480   [(set_attr "move_type" "move,load,store")
1481    (set_attr "mode" "DF")])
1483 (define_split
1484   [(set (match_operand:MOVE64 0 "nonimmediate_operand")
1485         (match_operand:MOVE64 1 "move_operand"))]
1486   "reload_completed
1487    && riscv_split_64bit_move_p (operands[0], operands[1])"
1488   [(const_int 0)]
1490   riscv_split_doubleword_move (operands[0], operands[1]);
1491   DONE;
1494 (define_expand "movmemsi"
1495   [(parallel [(set (match_operand:BLK 0 "general_operand")
1496                    (match_operand:BLK 1 "general_operand"))
1497               (use (match_operand:SI 2 ""))
1498               (use (match_operand:SI 3 "const_int_operand"))])]
1499   ""
1501   if (riscv_expand_block_move (operands[0], operands[1], operands[2]))
1502     DONE;
1503   else
1504     FAIL;
1507 ;; Expand in-line code to clear the instruction cache between operand[0] and
1508 ;; operand[1].
1509 (define_expand "clear_cache"
1510   [(match_operand 0 "pmode_register_operand")
1511    (match_operand 1 "pmode_register_operand")]
1512   ""
1514 #ifdef ICACHE_FLUSH_FUNC
1515   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, ICACHE_FLUSH_FUNC),
1516                      LCT_NORMAL, VOIDmode, operands[0], Pmode,
1517                      operands[1], Pmode, const0_rtx, Pmode);
1518 #else
1519   emit_insn (gen_fence_i ());
1520 #endif
1521   DONE;
1524 (define_insn "fence"
1525   [(unspec_volatile [(const_int 0)] UNSPECV_FENCE)]
1526   ""
1527   "%|fence%-")
1529 (define_insn "fence_i"
1530   [(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)]
1531   ""
1532   "fence.i")
1535 ;;  ....................
1537 ;;      SHIFTS
1539 ;;  ....................
1541 ;; Use a QImode shift count, to avoid generating sign or zero extend
1542 ;; instructions for shift counts, and to avoid dropping subregs.
1543 ;; expand_shift_1 can do this automatically when SHIFT_COUNT_TRUNCATED is
1544 ;; defined, but use of that is discouraged.
1546 (define_insn "<optab>si3"
1547   [(set (match_operand:SI     0 "register_operand" "= r")
1548         (any_shift:SI
1549             (match_operand:SI 1 "register_operand" "  r")
1550             (match_operand:QI 2 "arith_operand"    " rI")))]
1551   ""
1553   if (GET_CODE (operands[2]) == CONST_INT)
1554     operands[2] = GEN_INT (INTVAL (operands[2])
1555                            & (GET_MODE_BITSIZE (SImode) - 1));
1557   return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2";
1559   [(set_attr "type" "shift")
1560    (set_attr "mode" "SI")])
1562 (define_insn_and_split "*<optab>si3_mask"
1563   [(set (match_operand:SI     0 "register_operand" "= r")
1564         (any_shift:SI
1565             (match_operand:SI 1 "register_operand" "  r")
1566             (subreg:QI
1567              (and:SI
1568               (match_operand:SI 2 "register_operand"  "r")
1569               (match_operand 3 "const_int_operand")) 0)))]
1570   "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1571    == GET_MODE_BITSIZE (SImode)-1"
1572   "#"
1573   "&& 1"
1574   [(set (match_dup 0)
1575         (any_shift:SI (match_dup 1)
1576                       (match_dup 2)))]
1577   "operands[2] = gen_lowpart (QImode, operands[2]);"
1578   [(set_attr "type" "shift")
1579    (set_attr "mode" "SI")])
1581 (define_insn_and_split "*<optab>si3_mask_1"
1582   [(set (match_operand:SI     0 "register_operand" "= r")
1583         (any_shift:SI
1584             (match_operand:SI 1 "register_operand" "  r")
1585             (subreg:QI
1586              (and:DI
1587               (match_operand:DI 2 "register_operand"  "r")
1588               (match_operand 3 "const_int_operand")) 0)))]
1589   "TARGET_64BIT
1590    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1591        == GET_MODE_BITSIZE (SImode)-1"
1592   "#"
1593   "&& 1"
1594   [(set (match_dup 0)
1595         (any_shift:SI (match_dup 1)
1596                       (match_dup 2)))]
1597   "operands[2] = gen_lowpart (QImode, operands[2]);"
1598   [(set_attr "type" "shift")
1599    (set_attr "mode" "SI")])
1601 (define_insn "<optab>di3"
1602   [(set (match_operand:DI 0 "register_operand"     "= r")
1603         (any_shift:DI
1604             (match_operand:DI 1 "register_operand" "  r")
1605             (match_operand:QI 2 "arith_operand"    " rI")))]
1606   "TARGET_64BIT"
1608   if (GET_CODE (operands[2]) == CONST_INT)
1609     operands[2] = GEN_INT (INTVAL (operands[2])
1610                            & (GET_MODE_BITSIZE (DImode) - 1));
1612   return "<insn>%i2\t%0,%1,%2";
1614   [(set_attr "type" "shift")
1615    (set_attr "mode" "DI")])
1617 (define_insn_and_split "*<optab>di3_mask"
1618   [(set (match_operand:DI     0 "register_operand" "= r")
1619         (any_shift:DI
1620             (match_operand:DI 1 "register_operand" "  r")
1621             (subreg:QI
1622              (and:SI
1623               (match_operand:SI 2 "register_operand"  "r")
1624               (match_operand 3 "const_int_operand")) 0)))]
1625   "TARGET_64BIT
1626    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1627        == GET_MODE_BITSIZE (DImode)-1"
1628   "#"
1629   "&& 1"
1630   [(set (match_dup 0)
1631         (any_shift:DI (match_dup 1)
1632                       (match_dup 2)))]
1633   "operands[2] = gen_lowpart (QImode, operands[2]);"
1634   [(set_attr "type" "shift")
1635    (set_attr "mode" "DI")])
1637 (define_insn_and_split "*<optab>di3_mask_1"
1638   [(set (match_operand:DI     0 "register_operand" "= r")
1639         (any_shift:DI
1640             (match_operand:DI 1 "register_operand" "  r")
1641             (subreg:QI
1642              (and:DI
1643               (match_operand:DI 2 "register_operand"  "r")
1644               (match_operand 3 "const_int_operand")) 0)))]
1645   "TARGET_64BIT
1646    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1647        == GET_MODE_BITSIZE (DImode)-1"
1648   "#"
1649   "&& 1"
1650   [(set (match_dup 0)
1651         (any_shift:DI (match_dup 1)
1652                       (match_dup 2)))]
1653   "operands[2] = gen_lowpart (QImode, operands[2]);"
1654   [(set_attr "type" "shift")
1655    (set_attr "mode" "DI")])
1657 (define_insn "*<optab>si3_extend"
1658   [(set (match_operand:DI                   0 "register_operand" "= r")
1659         (sign_extend:DI
1660             (any_shift:SI (match_operand:SI 1 "register_operand" "  r")
1661                           (match_operand:QI 2 "arith_operand"    " rI"))))]
1662   "TARGET_64BIT"
1664   if (GET_CODE (operands[2]) == CONST_INT)
1665     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1667   return "<insn>%i2w\t%0,%1,%2";
1669   [(set_attr "type" "shift")
1670    (set_attr "mode" "SI")])
1672 (define_insn_and_split "*<optab>si3_extend_mask"
1673   [(set (match_operand:DI                   0 "register_operand" "= r")
1674         (sign_extend:DI
1675             (any_shift:SI
1676              (match_operand:SI 1 "register_operand" "  r")
1677              (subreg:QI
1678               (and:SI
1679                (match_operand:SI 2 "register_operand" " r")
1680                (match_operand 3 "const_int_operand")) 0))))]
1681   "TARGET_64BIT
1682    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1683        == GET_MODE_BITSIZE (SImode)-1"
1684   "#"
1685   "&& 1"
1686   [(set (match_dup 0)
1687         (sign_extend:DI
1688          (any_shift:SI (match_dup 1)
1689                        (match_dup 2))))]
1690   "operands[2] = gen_lowpart (QImode, operands[2]);"
1691   [(set_attr "type" "shift")
1692    (set_attr "mode" "SI")])
1694 (define_insn_and_split "*<optab>si3_extend_mask_1"
1695   [(set (match_operand:DI                   0 "register_operand" "= r")
1696         (sign_extend:DI
1697             (any_shift:SI
1698              (match_operand:SI 1 "register_operand" "  r")
1699              (subreg:QI
1700               (and:DI
1701                (match_operand:DI 2 "register_operand" " r")
1702                (match_operand 3 "const_int_operand")) 0))))]
1703   "TARGET_64BIT
1704    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1705        == GET_MODE_BITSIZE (SImode)-1"
1706   "#"
1707   "&& 1"
1708   [(set (match_dup 0)
1709         (sign_extend:DI
1710          (any_shift:SI (match_dup 1)
1711                        (match_dup 2))))]
1712   "operands[2] = gen_lowpart (QImode, operands[2]);"
1713   [(set_attr "type" "shift")
1714    (set_attr "mode" "SI")])
1716 ;; Non-canonical, but can be formed by ree when combine is not successful at
1717 ;; producing one of the two canonical patterns below.
1718 (define_insn "*lshrsi3_zero_extend_1"
1719   [(set (match_operand:DI                   0 "register_operand" "=r")
1720         (zero_extend:DI
1721          (lshiftrt:SI (match_operand:SI     1 "register_operand" " r")
1722                       (match_operand        2 "const_int_operand"))))]
1723   "TARGET_64BIT && (INTVAL (operands[2]) & 0x1f) > 0"
1725   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1727   return "srliw\t%0,%1,%2";
1729   [(set_attr "type" "shift")
1730    (set_attr "mode" "SI")])
1732 ;; Canonical form for a zero-extend of a logical right shift.
1733 (define_insn "*lshrsi3_zero_extend_2"
1734   [(set (match_operand:DI                   0 "register_operand" "=r")
1735         (zero_extract:DI (match_operand:DI  1 "register_operand" " r")
1736                          (match_operand     2 "const_int_operand")
1737                          (match_operand     3 "const_int_operand")))]
1738   "(TARGET_64BIT && (INTVAL (operands[3]) > 0)
1739     && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))"
1741   return "srliw\t%0,%1,%3";
1743   [(set_attr "type" "shift")
1744    (set_attr "mode" "SI")])
1746 ;; Canonical form for a zero-extend of a logical right shift when the
1747 ;; shift count is 31.
1748 (define_insn "*lshrsi3_zero_extend_3"
1749   [(set (match_operand:DI                   0 "register_operand" "=r")
1750         (lt:DI (match_operand:SI            1 "register_operand" " r")
1751                (const_int 0)))]
1752   "TARGET_64BIT"
1754   return "srliw\t%0,%1,31";
1756   [(set_attr "type" "shift")
1757    (set_attr "mode" "SI")])
1759 ;; Handle AND with 2^N-1 for N from 12 to XLEN.  This can be split into
1760 ;; two logical shifts.  Otherwise it requires 3 instructions: lui,
1761 ;; xor/addi/srli, and.
1762 (define_split
1763   [(set (match_operand:GPR 0 "register_operand")
1764         (and:GPR (match_operand:GPR 1 "register_operand")
1765                  (match_operand:GPR 2 "p2m1_shift_operand")))]
1766   ""
1767  [(set (match_dup 0)
1768        (ashift:GPR (match_dup 1) (match_dup 2)))
1769   (set (match_dup 0)
1770        (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
1772   operands[2] = GEN_INT (BITS_PER_WORD
1773                          - exact_log2 (INTVAL (operands[2]) + 1));
1775   
1776 ;; Handle AND with 0xF...F0...0 where there are 32 to 63 zeros.  This can be
1777 ;; split into two shifts.  Otherwise it requires 3 instructions: li, sll, and.
1778 (define_split
1779   [(set (match_operand:DI 0 "register_operand")
1780         (and:DI (match_operand:DI 1 "register_operand")
1781                 (match_operand:DI 2 "high_mask_shift_operand")))]
1782   "TARGET_64BIT"
1783   [(set (match_dup 0)
1784         (lshiftrt:DI (match_dup 1) (match_dup 2)))
1785    (set (match_dup 0)
1786         (ashift:DI (match_dup 0) (match_dup 2)))]
1788   operands[2] = GEN_INT (ctz_hwi (INTVAL (operands[2])));
1792 ;;  ....................
1794 ;;      CONDITIONAL BRANCHES
1796 ;;  ....................
1798 ;; Conditional branches
1800 (define_insn "*branch_order<mode>"
1801   [(set (pc)
1802         (if_then_else
1803          (match_operator 1 "order_operator"
1804                          [(match_operand:X 2 "register_operand" "r")
1805                           (match_operand:X 3 "register_operand" "r")])
1806          (label_ref (match_operand 0 "" ""))
1807          (pc)))]
1808   ""
1809   "b%C1\t%2,%3,%0"
1810   [(set_attr "type" "branch")
1811    (set_attr "mode" "none")])
1813 (define_insn "*branch_zero<mode>"
1814   [(set (pc)
1815         (if_then_else
1816          (match_operator 1 "signed_order_operator"
1817                          [(match_operand:X 2 "register_operand" "r")
1818                           (const_int 0)])
1819          (label_ref (match_operand 0 "" ""))
1820          (pc)))]
1821   ""
1822   "b%C1z\t%2,%0"
1823   [(set_attr "type" "branch")
1824    (set_attr "mode" "none")])
1826 ;; Used to implement built-in functions.
1827 (define_expand "condjump"
1828   [(set (pc)
1829         (if_then_else (match_operand 0)
1830                       (label_ref (match_operand 1))
1831                       (pc)))])
1833 (define_expand "cbranch<mode>4"
1834   [(set (pc)
1835         (if_then_else (match_operator 0 "comparison_operator"
1836                       [(match_operand:BR 1 "register_operand")
1837                        (match_operand:BR 2 "nonmemory_operand")])
1838                       (label_ref (match_operand 3 ""))
1839                       (pc)))]
1840   ""
1842   riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1843                                    operands[1], operands[2]);
1844   DONE;
1847 (define_expand "cbranch<mode>4"
1848   [(set (pc)
1849         (if_then_else (match_operator 0 "fp_branch_comparison"
1850                        [(match_operand:ANYF 1 "register_operand")
1851                         (match_operand:ANYF 2 "register_operand")])
1852                       (label_ref (match_operand 3 ""))
1853                       (pc)))]
1854   "TARGET_HARD_FLOAT"
1856   riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1857                                    operands[1], operands[2]);
1858   DONE;
1861 (define_insn_and_split "*branch_on_bit<X:mode>"
1862   [(set (pc)
1863         (if_then_else
1864             (match_operator 0 "equality_operator"
1865                 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1866                                  (const_int 1)
1867                                  (match_operand 3 "branch_on_bit_operand"))
1868                                  (const_int 0)])
1869             (label_ref (match_operand 1))
1870             (pc)))
1871    (clobber (match_scratch:X 4 "=&r"))]
1872   ""
1873   "#"
1874   "reload_completed"
1875   [(set (match_dup 4)
1876         (ashift:X (match_dup 2) (match_dup 3)))
1877    (set (pc)
1878         (if_then_else
1879             (match_op_dup 0 [(match_dup 4) (const_int 0)])
1880             (label_ref (match_operand 1))
1881             (pc)))]
1883   int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]);
1884   operands[3] = GEN_INT (shift);
1886   if (GET_CODE (operands[0]) == EQ)
1887     operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx);
1888   else
1889     operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx);
1892 (define_insn_and_split "*branch_on_bit_range<X:mode>"
1893   [(set (pc)
1894         (if_then_else
1895             (match_operator 0 "equality_operator"
1896                 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1897                                  (match_operand 3 "branch_on_bit_operand")
1898                                  (const_int 0))
1899                                  (const_int 0)])
1900             (label_ref (match_operand 1))
1901             (pc)))
1902    (clobber (match_scratch:X 4 "=&r"))]
1903   ""
1904   "#"
1905   "reload_completed"
1906   [(set (match_dup 4)
1907         (ashift:X (match_dup 2) (match_dup 3)))
1908    (set (pc)
1909         (if_then_else
1910             (match_op_dup 0 [(match_dup 4) (const_int 0)])
1911             (label_ref (match_operand 1))
1912             (pc)))]
1914   operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]));
1918 ;;  ....................
1920 ;;      SETTING A REGISTER FROM A COMPARISON
1922 ;;  ....................
1924 ;; Destination is always set in SI mode.
1926 (define_expand "cstore<mode>4"
1927   [(set (match_operand:SI 0 "register_operand")
1928         (match_operator:SI 1 "order_operator"
1929             [(match_operand:GPR 2 "register_operand")
1930              (match_operand:GPR 3 "nonmemory_operand")]))]
1931   ""
1933   riscv_expand_int_scc (operands[0], GET_CODE (operands[1]), operands[2],
1934                         operands[3]);
1935   DONE;
1938 (define_expand "cstore<mode>4"
1939   [(set (match_operand:SI 0 "register_operand")
1940         (match_operator:SI 1 "fp_scc_comparison"
1941              [(match_operand:ANYF 2 "register_operand")
1942               (match_operand:ANYF 3 "register_operand")]))]
1943   "TARGET_HARD_FLOAT"
1945   riscv_expand_float_scc (operands[0], GET_CODE (operands[1]), operands[2],
1946                           operands[3]);
1947   DONE;
1950 (define_insn "*cstore<ANYF:mode><X:mode>4"
1951    [(set (match_operand:X         0 "register_operand" "=r")
1952          (match_operator:X 1 "fp_native_comparison"
1953              [(match_operand:ANYF 2 "register_operand" " f")
1954               (match_operand:ANYF 3 "register_operand" " f")]))]
1955   "TARGET_HARD_FLOAT"
1956   "f%C1.<fmt>\t%0,%2,%3"
1957   [(set_attr "type" "fcmp")
1958    (set_attr "mode" "<UNITMODE>")])
1960 (define_expand "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4"
1961    [(parallel [(set (match_operand:X      0 "register_operand")
1962                     (unspec:X
1963                      [(match_operand:ANYF 1 "register_operand")
1964                       (match_operand:ANYF 2 "register_operand")]
1965                      QUIET_COMPARISON))
1966                (clobber (match_scratch:X 3))])]
1967   "TARGET_HARD_FLOAT")
1969 (define_insn "*f<quiet_pattern>_quiet<ANYF:mode><X:mode>4_default"
1970    [(set (match_operand:X      0 "register_operand" "=r")
1971          (unspec:X
1972           [(match_operand:ANYF 1 "register_operand" " f")
1973            (match_operand:ANYF 2 "register_operand" " f")]
1974           QUIET_COMPARISON))
1975     (clobber (match_scratch:X 3 "=&r"))]
1976   "TARGET_HARD_FLOAT && ! HONOR_SNANS (<ANYF:MODE>mode)"
1977   "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3"
1978   [(set_attr "type" "fcmp")
1979    (set_attr "mode" "<UNITMODE>")
1980    (set (attr "length") (const_int 12))])
1982 (define_insn "*f<quiet_pattern>_quiet<ANYF:mode><X:mode>4_snan"
1983    [(set (match_operand:X      0 "register_operand" "=r")
1984          (unspec:X
1985           [(match_operand:ANYF 1 "register_operand" " f")
1986            (match_operand:ANYF 2 "register_operand" " f")]
1987           QUIET_COMPARISON))
1988     (clobber (match_scratch:X 3 "=&r"))]
1989   "TARGET_HARD_FLOAT && HONOR_SNANS (<ANYF:MODE>mode)"
1990   "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3\n\tfeq.<fmt>\tzero,%1,%2"
1991   [(set_attr "type" "fcmp")
1992    (set_attr "mode" "<UNITMODE>")
1993    (set (attr "length") (const_int 16))])
1995 (define_insn "*seq_zero_<X:mode><GPR:mode>"
1996   [(set (match_operand:GPR       0 "register_operand" "=r")
1997         (eq:GPR (match_operand:X 1 "register_operand" " r")
1998                 (const_int 0)))]
1999   ""
2000   "seqz\t%0,%1"
2001   [(set_attr "type" "slt")
2002    (set_attr "mode" "<X:MODE>")])
2004 (define_insn "*sne_zero_<X:mode><GPR:mode>"
2005   [(set (match_operand:GPR       0 "register_operand" "=r")
2006         (ne:GPR (match_operand:X 1 "register_operand" " r")
2007                 (const_int 0)))]
2008   ""
2009   "snez\t%0,%1"
2010   [(set_attr "type" "slt")
2011    (set_attr "mode" "<X:MODE>")])
2013 (define_insn "*sgt<u>_<X:mode><GPR:mode>"
2014   [(set (match_operand:GPR           0 "register_operand" "= r")
2015         (any_gt:GPR (match_operand:X 1 "register_operand" "  r")
2016                     (match_operand:X 2 "reg_or_0_operand" " rJ")))]
2017   ""
2018   "sgt<u>\t%0,%1,%z2"
2019   [(set_attr "type" "slt")
2020    (set_attr "mode" "<X:MODE>")])
2022 (define_insn "*sge<u>_<X:mode><GPR:mode>"
2023   [(set (match_operand:GPR           0 "register_operand" "=r")
2024         (any_ge:GPR (match_operand:X 1 "register_operand" " r")
2025                     (const_int 1)))]
2026   ""
2027   "slt%i2<u>\t%0,zero,%1"
2028   [(set_attr "type" "slt")
2029    (set_attr "mode" "<MODE>")])
2031 (define_insn "*slt<u>_<X:mode><GPR:mode>"
2032   [(set (match_operand:GPR           0 "register_operand" "= r")
2033         (any_lt:GPR (match_operand:X 1 "register_operand" "  r")
2034                     (match_operand:X 2 "arith_operand"    " rI")))]
2035   ""
2036   "slt%i2<u>\t%0,%1,%2"
2037   [(set_attr "type" "slt")
2038    (set_attr "mode" "<MODE>")])
2040 (define_insn "*sle<u>_<X:mode><GPR:mode>"
2041   [(set (match_operand:GPR           0 "register_operand" "=r")
2042         (any_le:GPR (match_operand:X 1 "register_operand" " r")
2043                     (match_operand:X 2 "sle_operand" "")))]
2044   ""
2046   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
2047   return "slt%i2<u>\t%0,%1,%2";
2049   [(set_attr "type" "slt")
2050    (set_attr "mode" "<MODE>")])
2053 ;;  ....................
2055 ;;      UNCONDITIONAL BRANCHES
2057 ;;  ....................
2059 ;; Unconditional branches.
2061 (define_insn "jump"
2062   [(set (pc)
2063         (label_ref (match_operand 0 "" "")))]
2064   ""
2065   "j\t%l0"
2066   [(set_attr "type"     "jump")
2067    (set_attr "mode"     "none")])
2069 (define_expand "indirect_jump"
2070   [(set (pc) (match_operand 0 "register_operand"))]
2071   ""
2073   operands[0] = force_reg (Pmode, operands[0]);
2074   if (Pmode == SImode)
2075     emit_jump_insn (gen_indirect_jumpsi (operands[0]));
2076   else
2077     emit_jump_insn (gen_indirect_jumpdi (operands[0]));
2078   DONE;
2081 (define_insn "indirect_jump<mode>"
2082   [(set (pc) (match_operand:P 0 "register_operand" "l"))]
2083   ""
2084   "jr\t%0"
2085   [(set_attr "type" "jump")
2086    (set_attr "mode" "none")])
2088 (define_expand "tablejump"
2089   [(set (pc) (match_operand 0 "register_operand" ""))
2090               (use (label_ref (match_operand 1 "" "")))]
2091   ""
2093   if (CASE_VECTOR_PC_RELATIVE)
2094       operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
2095                                          gen_rtx_LABEL_REF (Pmode, operands[1]),
2096                                          NULL_RTX, 0, OPTAB_DIRECT);
2098   if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode)
2099     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
2100   else
2101     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
2102   DONE;
2105 (define_insn "tablejump<mode>"
2106   [(set (pc) (match_operand:GPR 0 "register_operand" "l"))
2107    (use (label_ref (match_operand 1 "" "")))]
2108   ""
2109   "jr\t%0"
2110   [(set_attr "type" "jump")
2111    (set_attr "mode" "none")])
2114 ;;  ....................
2116 ;;      Function prologue/epilogue
2118 ;;  ....................
2121 (define_expand "prologue"
2122   [(const_int 1)]
2123   ""
2125   riscv_expand_prologue ();
2126   DONE;
2129 ;; Block any insns from being moved before this point, since the
2130 ;; profiling call to mcount can use various registers that aren't
2131 ;; saved or used to pass arguments.
2133 (define_insn "blockage"
2134   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2135   ""
2136   ""
2137   [(set_attr "type" "ghost")
2138    (set_attr "mode" "none")])
2140 (define_expand "epilogue"
2141   [(const_int 2)]
2142   ""
2144   riscv_expand_epilogue (NORMAL_RETURN);
2145   DONE;
2148 (define_expand "sibcall_epilogue"
2149   [(const_int 2)]
2150   ""
2152   riscv_expand_epilogue (SIBCALL_RETURN);
2153   DONE;
2156 ;; Trivial return.  Make it look like a normal return insn as that
2157 ;; allows jump optimizations to work better.
2159 (define_expand "return"
2160   [(simple_return)]
2161   "riscv_can_use_return_insn ()"
2162   "")
2164 (define_insn "simple_return"
2165   [(simple_return)]
2166   ""
2168   return riscv_output_return ();
2170   [(set_attr "type"     "jump")
2171    (set_attr "mode"     "none")])
2173 ;; Normal return.
2175 (define_insn "simple_return_internal"
2176   [(simple_return)
2177    (use (match_operand 0 "pmode_register_operand" ""))]
2178   ""
2179   "jr\t%0"
2180   [(set_attr "type"     "jump")
2181    (set_attr "mode"     "none")])
2183 ;; This is used in compiling the unwind routines.
2184 (define_expand "eh_return"
2185   [(use (match_operand 0 "general_operand"))]
2186   ""
2188   if (GET_MODE (operands[0]) != word_mode)
2189     operands[0] = convert_to_mode (word_mode, operands[0], 0);
2190   if (TARGET_64BIT)
2191     emit_insn (gen_eh_set_lr_di (operands[0]));
2192   else
2193     emit_insn (gen_eh_set_lr_si (operands[0]));
2195   emit_jump_insn (gen_eh_return_internal ());
2196   emit_barrier ();
2197   DONE;
2200 ;; Clobber the return address on the stack.  We can't expand this
2201 ;; until we know where it will be put in the stack frame.
2203 (define_insn "eh_set_lr_si"
2204   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2205    (clobber (match_scratch:SI 1 "=&r"))]
2206   "! TARGET_64BIT"
2207   "#")
2209 (define_insn "eh_set_lr_di"
2210   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2211    (clobber (match_scratch:DI 1 "=&r"))]
2212   "TARGET_64BIT"
2213   "#")
2215 (define_split
2216   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
2217    (clobber (match_scratch 1))]
2218   "reload_completed"
2219   [(const_int 0)]
2221   riscv_set_return_address (operands[0], operands[1]);
2222   DONE;
2225 (define_insn_and_split "eh_return_internal"
2226   [(eh_return)]
2227   ""
2228   "#"
2229   "epilogue_completed"
2230   [(const_int 0)]
2231   "riscv_expand_epilogue (EXCEPTION_RETURN); DONE;")
2234 ;;  ....................
2236 ;;      FUNCTION CALLS
2238 ;;  ....................
2240 (define_expand "sibcall"
2241   [(parallel [(call (match_operand 0 "")
2242                     (match_operand 1 ""))
2243               (use (match_operand 2 ""))        ;; next_arg_reg
2244               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
2245   ""
2247   rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2248   emit_call_insn (gen_sibcall_internal (target, operands[1]));
2249   DONE;
2252 (define_insn "sibcall_internal"
2253   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U"))
2254          (match_operand 1 "" ""))]
2255   "SIBLING_CALL_P (insn)"
2256   "@
2257    jr\t%0
2258    tail\t%0
2259    tail\t%0@plt"
2260   [(set_attr "type" "call")])
2262 (define_expand "sibcall_value"
2263   [(parallel [(set (match_operand 0 "")
2264                    (call (match_operand 1 "")
2265                          (match_operand 2 "")))
2266               (use (match_operand 3 ""))])]             ;; next_arg_reg
2267   ""
2269   rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2270   emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2]));
2271   DONE;
2274 (define_insn "sibcall_value_internal"
2275   [(set (match_operand 0 "" "")
2276         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U"))
2277               (match_operand 2 "" "")))]
2278   "SIBLING_CALL_P (insn)"
2279   "@
2280    jr\t%1
2281    tail\t%1
2282    tail\t%1@plt"
2283   [(set_attr "type" "call")])
2285 (define_expand "call"
2286   [(parallel [(call (match_operand 0 "")
2287                     (match_operand 1 ""))
2288               (use (match_operand 2 ""))        ;; next_arg_reg
2289               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
2290   ""
2292   rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2293   emit_call_insn (gen_call_internal (target, operands[1]));
2294   DONE;
2297 (define_insn "call_internal"
2298   [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U"))
2299          (match_operand 1 "" ""))
2300    (clobber (reg:SI RETURN_ADDR_REGNUM))]
2301   ""
2302   "@
2303    jalr\t%0
2304    call\t%0
2305    call\t%0@plt"
2306   [(set_attr "type" "call")])
2308 (define_expand "call_value"
2309   [(parallel [(set (match_operand 0 "")
2310                    (call (match_operand 1 "")
2311                          (match_operand 2 "")))
2312               (use (match_operand 3 ""))])]             ;; next_arg_reg
2313   ""
2315   rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2316   emit_call_insn (gen_call_value_internal (operands[0], target, operands[2]));
2317   DONE;
2320 (define_insn "call_value_internal"
2321   [(set (match_operand 0 "" "")
2322         (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U"))
2323               (match_operand 2 "" "")))
2324    (clobber (reg:SI RETURN_ADDR_REGNUM))]
2325   ""
2326   "@
2327    jalr\t%1
2328    call\t%1
2329    call\t%1@plt"
2330   [(set_attr "type" "call")])
2332 ;; Call subroutine returning any type.
2334 (define_expand "untyped_call"
2335   [(parallel [(call (match_operand 0 "")
2336                     (const_int 0))
2337               (match_operand 1 "")
2338               (match_operand 2 "")])]
2339   ""
2341   int i;
2343   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2345   for (i = 0; i < XVECLEN (operands[2], 0); i++)
2346     {
2347       rtx set = XVECEXP (operands[2], 0, i);
2348       riscv_emit_move (SET_DEST (set), SET_SRC (set));
2349     }
2351   emit_insn (gen_blockage ());
2352   DONE;
2355 (define_insn "nop"
2356   [(const_int 0)]
2357   ""
2358   "nop"
2359   [(set_attr "type"     "nop")
2360    (set_attr "mode"     "none")])
2362 (define_insn "trap"
2363   [(trap_if (const_int 1) (const_int 0))]
2364   ""
2365   "ebreak")
2367 (define_insn "gpr_save"
2368   [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_SAVE)
2369    (clobber (reg:SI T0_REGNUM))
2370    (clobber (reg:SI T1_REGNUM))]
2371   ""
2372   { return riscv_output_gpr_save (INTVAL (operands[0])); })
2374 (define_insn "gpr_restore"
2375   [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_RESTORE)]
2376   ""
2377   "tail\t__riscv_restore_%0")
2379 (define_insn "gpr_restore_return"
2380   [(return)
2381    (use (match_operand 0 "pmode_register_operand" ""))
2382    (const_int 0)]
2383   ""
2384   "")
2386 (define_insn "riscv_frflags"
2387   [(set (match_operand:SI 0 "register_operand" "=r")
2388         (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))]
2389   "TARGET_HARD_FLOAT"
2390   "frflags\t%0")
2392 (define_insn "riscv_fsflags"
2393   [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)]
2394   "TARGET_HARD_FLOAT"
2395   "fsflags\t%0")
2397 (define_insn "riscv_mret"
2398   [(return)
2399    (unspec_volatile [(const_int 0)] UNSPECV_MRET)]
2400   ""
2401   "mret")
2403 (define_insn "riscv_sret"
2404   [(return)
2405    (unspec_volatile [(const_int 0)] UNSPECV_SRET)]
2406   ""
2407   "sret")
2409 (define_insn "riscv_uret"
2410   [(return)
2411    (unspec_volatile [(const_int 0)] UNSPECV_URET)]
2412   ""
2413   "uret")
2415 (define_insn "stack_tie<mode>"
2416   [(set (mem:BLK (scratch))
2417         (unspec:BLK [(match_operand:X 0 "register_operand" "r")
2418                      (match_operand:X 1 "register_operand" "r")]
2419                     UNSPEC_TIE))]
2420   ""
2421   ""
2422   [(set_attr "length" "0")]
2425 (include "sync.md")
2426 (include "peephole.md")
2427 (include "pic.md")
2428 (include "generic.md")