RISC-V: Fix more splitters accidentally calling gen_reg_rtx.
[official-gcc.git] / gcc / config / riscv / riscv.md
blobd3c8f65974877e17631f2eaeef7380e066846986
1 ;; Machine description for RISC-V for GNU compiler.
2 ;; Copyright (C) 2011-2019 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,auipc,sfb_alu,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 ;; Microarchitectures we know how to tune for.
239 ;; Keep this in sync with enum riscv_microarchitecture.
240 (define_attr "tune"
241   "generic,sifive_7"
242   (const (symbol_ref "((enum attr_tune) riscv_microarchitecture)")))
244 ;; Describe a user's asm statement.
245 (define_asm_attributes
246   [(set_attr "type" "multi")])
248 ;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
249 ;; from the same template.
250 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
252 ;; This mode iterator allows :P to be used for patterns that operate on
253 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
254 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
256 ;; Likewise, but for XLEN-sized quantities.
257 (define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")])
259 ;; Branches operate on XLEN-sized quantities, but for RV64 we accept
260 ;; QImode values so we can force zero-extension.
261 (define_mode_iterator BR [(QI "TARGET_64BIT") SI (DI "TARGET_64BIT")])
263 ;; 32-bit moves for which we provide move patterns.
264 (define_mode_iterator MOVE32 [SI])
266 ;; 64-bit modes for which we provide move patterns.
267 (define_mode_iterator MOVE64 [DI DF])
269 ;; Iterator for sub-32-bit integer modes.
270 (define_mode_iterator SHORT [QI HI])
272 ;; Iterator for HImode constant generation.
273 (define_mode_iterator HISI [HI SI])
275 ;; Iterator for QImode extension patterns.
276 (define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")])
278 ;; Iterator for hardware integer modes narrower than XLEN.
279 (define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")])
281 ;; Iterator for hardware-supported integer modes.
282 (define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")])
284 ;; Iterator for hardware-supported floating-point modes.
285 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
286                             (DF "TARGET_DOUBLE_FLOAT")])
288 ;; Iterator for floating-point modes that can be loaded into X registers.
289 (define_mode_iterator SOFTF [SF (DF "TARGET_64BIT")])
291 ;; This attribute gives the length suffix for a sign- or zero-extension
292 ;; instruction.
293 (define_mode_attr size [(QI "b") (HI "h")])
295 ;; Mode attributes for loads.
296 (define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")])
298 ;; Instruction names for integer loads that aren't explicitly sign or zero
299 ;; extended.  See riscv_output_move and LOAD_EXTEND_OP.
300 (define_mode_attr default_load [(QI "lbu") (HI "lhu") (SI "lw") (DI "ld")])
302 ;; Mode attribute for FP loads into integer registers.
303 (define_mode_attr softload [(SF "lw") (DF "ld")])
305 ;; Instruction names for stores.
306 (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")])
308 ;; Instruction names for FP stores from integer registers.
309 (define_mode_attr softstore [(SF "sw") (DF "sd")])
311 ;; This attribute gives the best constraint to use for registers of
312 ;; a given mode.
313 (define_mode_attr reg [(SI "d") (DI "d") (CC "d")])
315 ;; This attribute gives the format suffix for floating-point operations.
316 (define_mode_attr fmt [(SF "s") (DF "d")])
318 ;; This attribute gives the integer suffix for floating-point conversions.
319 (define_mode_attr ifmt [(SI "w") (DI "l")])
321 ;; This attribute gives the format suffix for atomic memory operations.
322 (define_mode_attr amo [(SI "w") (DI "d")])
324 ;; This attribute gives the upper-case mode name for one unit of a
325 ;; floating-point mode.
326 (define_mode_attr UNITMODE [(SF "SF") (DF "DF")])
328 ;; This attribute gives the integer mode that has half the size of
329 ;; the controlling mode.
330 (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
332 ;; Iterator and attributes for floating-point rounding instructions.
333 (define_int_iterator RINT [UNSPEC_LRINT UNSPEC_LROUND])
334 (define_int_attr rint_pattern [(UNSPEC_LRINT "rint") (UNSPEC_LROUND "round")])
335 (define_int_attr rint_rm [(UNSPEC_LRINT "dyn") (UNSPEC_LROUND "rmm")])
337 ;; Iterator and attributes for quiet comparisons.
338 (define_int_iterator QUIET_COMPARISON [UNSPEC_FLT_QUIET UNSPEC_FLE_QUIET])
339 (define_int_attr quiet_pattern [(UNSPEC_FLT_QUIET "lt") (UNSPEC_FLE_QUIET "le")])
341 ;; This code iterator allows signed and unsigned widening multiplications
342 ;; to use the same template.
343 (define_code_iterator any_extend [sign_extend zero_extend])
345 ;; This code iterator allows the two right shift instructions to be
346 ;; generated from the same template.
347 (define_code_iterator any_shiftrt [ashiftrt lshiftrt])
349 ;; This code iterator allows the three shift instructions to be generated
350 ;; from the same template.
351 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
353 ;; This code iterator allows the three bitwise instructions to be generated
354 ;; from the same template.
355 (define_code_iterator any_bitwise [and ior xor])
357 ;; This code iterator allows unsigned and signed division to be generated
358 ;; from the same template.
359 (define_code_iterator any_div [div udiv mod umod])
361 ;; This code iterator allows unsigned and signed modulus to be generated
362 ;; from the same template.
363 (define_code_iterator any_mod [mod umod])
365 ;; These code iterators allow the signed and unsigned scc operations to use
366 ;; the same template.
367 (define_code_iterator any_gt [gt gtu])
368 (define_code_iterator any_ge [ge geu])
369 (define_code_iterator any_lt [lt ltu])
370 (define_code_iterator any_le [le leu])
372 ;; <u> expands to an empty string when doing a signed operation and
373 ;; "u" when doing an unsigned operation.
374 (define_code_attr u [(sign_extend "") (zero_extend "u")
375                      (gt "") (gtu "u")
376                      (ge "") (geu "u")
377                      (lt "") (ltu "u")
378                      (le "") (leu "u")])
380 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
381 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
383 ;; <optab> expands to the name of the optab for a particular code.
384 (define_code_attr optab [(ashift "ashl")
385                          (ashiftrt "ashr")
386                          (lshiftrt "lshr")
387                          (div "div")
388                          (mod "mod")
389                          (udiv "udiv")
390                          (umod "umod")
391                          (ge "ge")
392                          (le "le")
393                          (gt "gt")
394                          (lt "lt")
395                          (ior "ior")
396                          (xor "xor")
397                          (and "and")
398                          (plus "add")
399                          (minus "sub")])
401 ;; <insn> expands to the name of the insn that implements a particular code.
402 (define_code_attr insn [(ashift "sll")
403                         (ashiftrt "sra")
404                         (lshiftrt "srl")
405                         (div "div")
406                         (mod "rem")
407                         (udiv "divu")
408                         (umod "remu")
409                         (ior "or")
410                         (xor "xor")
411                         (and "and")
412                         (plus "add")
413                         (minus "sub")])
415 ;; Ghost instructions produce no real code and introduce no hazards.
416 ;; They exist purely to express an effect on dataflow.
417 (define_insn_reservation "ghost" 0
418   (eq_attr "type" "ghost")
419   "nothing")
422 ;;  ....................
424 ;;      ADDITION
426 ;;  ....................
429 (define_insn "add<mode>3"
430   [(set (match_operand:ANYF            0 "register_operand" "=f")
431         (plus:ANYF (match_operand:ANYF 1 "register_operand" " f")
432                    (match_operand:ANYF 2 "register_operand" " f")))]
433   "TARGET_HARD_FLOAT"
434   "fadd.<fmt>\t%0,%1,%2"
435   [(set_attr "type" "fadd")
436    (set_attr "mode" "<UNITMODE>")])
438 (define_insn "addsi3"
439   [(set (match_operand:SI          0 "register_operand" "=r,r")
440         (plus:SI (match_operand:SI 1 "register_operand" " r,r")
441                  (match_operand:SI 2 "arith_operand"    " r,I")))]
442   ""
443   { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
444   [(set_attr "type" "arith")
445    (set_attr "mode" "SI")])
447 (define_insn "adddi3"
448   [(set (match_operand:DI          0 "register_operand" "=r,r")
449         (plus:DI (match_operand:DI 1 "register_operand" " r,r")
450                  (match_operand:DI 2 "arith_operand"    " r,I")))]
451   "TARGET_64BIT"
452   "add%i2\t%0,%1,%2"
453   [(set_attr "type" "arith")
454    (set_attr "mode" "DI")])
456 (define_insn "*addsi3_extended"
457   [(set (match_operand:DI               0 "register_operand" "=r,r")
458         (sign_extend:DI
459              (plus:SI (match_operand:SI 1 "register_operand" " r,r")
460                       (match_operand:SI 2 "arith_operand"    " r,I"))))]
461   "TARGET_64BIT"
462   "add%i2w\t%0,%1,%2"
463   [(set_attr "type" "arith")
464    (set_attr "mode" "SI")])
466 (define_insn "*addsi3_extended2"
467   [(set (match_operand:DI                       0 "register_operand" "=r,r")
468         (sign_extend:DI
469           (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" " r,r")
470                               (match_operand:DI 2 "arith_operand"    " r,I"))
471                      0)))]
472   "TARGET_64BIT"
473   "add%i2w\t%0,%1,%2"
474   [(set_attr "type" "arith")
475    (set_attr "mode" "SI")])
478 ;;  ....................
480 ;;      SUBTRACTION
482 ;;  ....................
485 (define_insn "sub<mode>3"
486   [(set (match_operand:ANYF             0 "register_operand" "=f")
487         (minus:ANYF (match_operand:ANYF 1 "register_operand" " f")
488                     (match_operand:ANYF 2 "register_operand" " f")))]
489   "TARGET_HARD_FLOAT"
490   "fsub.<fmt>\t%0,%1,%2"
491   [(set_attr "type" "fadd")
492    (set_attr "mode" "<UNITMODE>")])
494 (define_insn "subdi3"
495   [(set (match_operand:DI 0            "register_operand" "= r")
496         (minus:DI (match_operand:DI 1  "reg_or_0_operand" " rJ")
497                    (match_operand:DI 2 "register_operand" "  r")))]
498   "TARGET_64BIT"
499   "sub\t%0,%z1,%2"
500   [(set_attr "type" "arith")
501    (set_attr "mode" "DI")])
503 (define_insn "subsi3"
504   [(set (match_operand:SI           0 "register_operand" "= r")
505         (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
506                   (match_operand:SI 2 "register_operand" "  r")))]
507   ""
508   { return TARGET_64BIT ? "subw\t%0,%z1,%2" : "sub\t%0,%z1,%2"; }
509   [(set_attr "type" "arith")
510    (set_attr "mode" "SI")])
512 (define_insn "*subsi3_extended"
513   [(set (match_operand:DI               0 "register_operand" "= r")
514         (sign_extend:DI
515             (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
516                       (match_operand:SI 2 "register_operand" "  r"))))]
517   "TARGET_64BIT"
518   "subw\t%0,%z1,%2"
519   [(set_attr "type" "arith")
520    (set_attr "mode" "SI")])
522 (define_insn "*subsi3_extended2"
523   [(set (match_operand:DI                        0 "register_operand" "= r")
524         (sign_extend:DI
525           (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" " rJ")
526                                (match_operand:DI 2 "register_operand" "  r"))
527                      0)))]
528   "TARGET_64BIT"
529   "subw\t%0,%z1,%2"
530   [(set_attr "type" "arith")
531    (set_attr "mode" "SI")])
533 (define_insn "negdi2"
534   [(set (match_operand:DI         0 "register_operand" "=r")
535         (neg:DI (match_operand:DI 1 "register_operand" " r")))]
536   "TARGET_64BIT"
537   "neg\t%0,%1"
538   [(set_attr "type" "arith")
539    (set_attr "mode" "DI")])
541 (define_insn "negsi2"
542   [(set (match_operand:SI         0 "register_operand" "=r")
543         (neg:SI (match_operand:SI 1 "register_operand" " r")))]
544   ""
545   { return TARGET_64BIT ? "negw\t%0,%1" : "neg\t%0,%1"; }
546   [(set_attr "type" "arith")
547    (set_attr "mode" "SI")])
549 (define_insn "*negsi2_extended"
550   [(set (match_operand:DI          0 "register_operand" "=r")
551         (sign_extend:DI
552          (neg:SI (match_operand:SI 1 "register_operand" " r"))))]
553   "TARGET_64BIT"
554   "negw\t%0,%1"
555   [(set_attr "type" "arith")
556    (set_attr "mode" "SI")])
558 (define_insn "*negsi2_extended2"
559   [(set (match_operand:DI                     0 "register_operand" "=r")
560         (sign_extend:DI
561          (subreg:SI (neg:DI (match_operand:DI 1 "register_operand" " r"))
562                     0)))]
563   "TARGET_64BIT"
564   "negw\t%0,%1"
565   [(set_attr "type" "arith")
566    (set_attr "mode" "SI")])
569 ;;  ....................
571 ;;      MULTIPLICATION
573 ;;  ....................
576 (define_insn "mul<mode>3"
577   [(set (match_operand:ANYF               0 "register_operand" "=f")
578         (mult:ANYF (match_operand:ANYF    1 "register_operand" " f")
579                       (match_operand:ANYF 2 "register_operand" " f")))]
580   "TARGET_HARD_FLOAT"
581   "fmul.<fmt>\t%0,%1,%2"
582   [(set_attr "type" "fmul")
583    (set_attr "mode" "<UNITMODE>")])
585 (define_insn "mulsi3"
586   [(set (match_operand:SI          0 "register_operand" "=r")
587         (mult:SI (match_operand:SI 1 "register_operand" " r")
588                  (match_operand:SI 2 "register_operand" " r")))]
589   "TARGET_MUL"
590   { return TARGET_64BIT ? "mulw\t%0,%1,%2" : "mul\t%0,%1,%2"; }
591   [(set_attr "type" "imul")
592    (set_attr "mode" "SI")])
594 (define_insn "muldi3"
595   [(set (match_operand:DI          0 "register_operand" "=r")
596         (mult:DI (match_operand:DI 1 "register_operand" " r")
597                  (match_operand:DI 2 "register_operand" " r")))]
598   "TARGET_MUL && TARGET_64BIT"
599   "mul\t%0,%1,%2"
600   [(set_attr "type" "imul")
601    (set_attr "mode" "DI")])
603 (define_insn "*mulsi3_extended"
604   [(set (match_operand:DI              0 "register_operand" "=r")
605         (sign_extend:DI
606             (mult:SI (match_operand:SI 1 "register_operand" " r")
607                      (match_operand:SI 2 "register_operand" " r"))))]
608   "TARGET_MUL && TARGET_64BIT"
609   "mulw\t%0,%1,%2"
610   [(set_attr "type" "imul")
611    (set_attr "mode" "SI")])
613 (define_insn "*mulsi3_extended2"
614   [(set (match_operand:DI                       0 "register_operand" "=r")
615         (sign_extend:DI
616           (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" " r")
617                               (match_operand:DI 2 "register_operand" " r"))
618                      0)))]
619   "TARGET_MUL && TARGET_64BIT"
620   "mulw\t%0,%1,%2"
621   [(set_attr "type" "imul")
622    (set_attr "mode" "SI")])
625 ;;  ........................
627 ;;      MULTIPLICATION HIGH-PART
629 ;;  ........................
633 (define_expand "<u>mulditi3"
634   [(set (match_operand:TI                         0 "register_operand")
635         (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
636                  (any_extend:TI (match_operand:DI 2 "register_operand"))))]
637   "TARGET_MUL && TARGET_64BIT"
639   rtx low = gen_reg_rtx (DImode);
640   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
642   rtx high = gen_reg_rtx (DImode);
643   emit_insn (gen_<u>muldi3_highpart (high, operands[1], operands[2]));
645   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
646   emit_move_insn (gen_highpart (DImode, operands[0]), high);
647   DONE;
650 (define_insn "<u>muldi3_highpart"
651   [(set (match_operand:DI                0 "register_operand" "=r")
652         (truncate:DI
653           (lshiftrt:TI
654             (mult:TI (any_extend:TI
655                        (match_operand:DI 1 "register_operand" " r"))
656                      (any_extend:TI
657                        (match_operand:DI 2 "register_operand" " r")))
658             (const_int 64))))]
659   "TARGET_MUL && TARGET_64BIT"
660   "mulh<u>\t%0,%1,%2"
661   [(set_attr "type" "imul")
662    (set_attr "mode" "DI")])
664 (define_expand "usmulditi3"
665   [(set (match_operand:TI                          0 "register_operand")
666         (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand"))
667                  (sign_extend:TI (match_operand:DI 2 "register_operand"))))]
668   "TARGET_MUL && TARGET_64BIT"
670   rtx low = gen_reg_rtx (DImode);
671   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
673   rtx high = gen_reg_rtx (DImode);
674   emit_insn (gen_usmuldi3_highpart (high, operands[1], operands[2]));
676   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
677   emit_move_insn (gen_highpart (DImode, operands[0]), high);
678   DONE;
681 (define_insn "usmuldi3_highpart"
682   [(set (match_operand:DI                0 "register_operand" "=r")
683         (truncate:DI
684           (lshiftrt:TI
685             (mult:TI (zero_extend:TI
686                        (match_operand:DI 1 "register_operand"  "r"))
687                      (sign_extend:TI
688                        (match_operand:DI 2 "register_operand" " r")))
689             (const_int 64))))]
690   "TARGET_MUL && TARGET_64BIT"
691   "mulhsu\t%0,%2,%1"
692   [(set_attr "type" "imul")
693    (set_attr "mode" "DI")])
695 (define_expand "<u>mulsidi3"
696   [(set (match_operand:DI            0 "register_operand" "=r")
697         (mult:DI (any_extend:DI
698                    (match_operand:SI 1 "register_operand" " r"))
699                  (any_extend:DI
700                    (match_operand:SI 2 "register_operand" " r"))))]
701   "TARGET_MUL && !TARGET_64BIT"
703   rtx temp = gen_reg_rtx (SImode);
704   emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
705   emit_insn (gen_<u>mulsi3_highpart (riscv_subword (operands[0], true),
706                                      operands[1], operands[2]));
707   emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
708   DONE;
711 (define_insn "<u>mulsi3_highpart"
712   [(set (match_operand:SI                0 "register_operand" "=r")
713         (truncate:SI
714           (lshiftrt:DI
715             (mult:DI (any_extend:DI
716                        (match_operand:SI 1 "register_operand" " r"))
717                      (any_extend:DI
718                        (match_operand:SI 2 "register_operand" " r")))
719             (const_int 32))))]
720   "TARGET_MUL && !TARGET_64BIT"
721   "mulh<u>\t%0,%1,%2"
722   [(set_attr "type" "imul")
723    (set_attr "mode" "SI")])
726 (define_expand "usmulsidi3"
727   [(set (match_operand:DI            0 "register_operand" "=r")
728         (mult:DI (zero_extend:DI
729                    (match_operand:SI 1 "register_operand" " r"))
730                  (sign_extend:DI
731                    (match_operand:SI 2 "register_operand" " r"))))]
732   "TARGET_MUL && !TARGET_64BIT"
734   rtx temp = gen_reg_rtx (SImode);
735   emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
736   emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true),
737                                      operands[1], operands[2]));
738   emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
739   DONE;
742 (define_insn "usmulsi3_highpart"
743   [(set (match_operand:SI                0 "register_operand" "=r")
744         (truncate:SI
745           (lshiftrt:DI
746             (mult:DI (zero_extend:DI
747                        (match_operand:SI 1 "register_operand" " r"))
748                      (sign_extend:DI
749                        (match_operand:SI 2 "register_operand" " r")))
750             (const_int 32))))]
751   "TARGET_MUL && !TARGET_64BIT"
752   "mulhsu\t%0,%2,%1"
753   [(set_attr "type" "imul")
754    (set_attr "mode" "SI")])
757 ;;  ....................
759 ;;      DIVISION and REMAINDER
761 ;;  ....................
764 (define_insn "<optab>si3"
765   [(set (match_operand:SI             0 "register_operand" "=r")
766         (any_div:SI (match_operand:SI 1 "register_operand" " r")
767                     (match_operand:SI 2 "register_operand" " r")))]
768   "TARGET_DIV"
769   { return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2"; }
770   [(set_attr "type" "idiv")
771    (set_attr "mode" "SI")])
773 (define_insn "<optab>di3"
774   [(set (match_operand:DI             0 "register_operand" "=r")
775         (any_div:DI (match_operand:DI 1 "register_operand" " r")
776                     (match_operand:DI 2 "register_operand" " r")))]
777   "TARGET_DIV && TARGET_64BIT"
778   "<insn>%i2\t%0,%1,%2"
779   [(set_attr "type" "idiv")
780    (set_attr "mode" "DI")])
782 (define_insn "*<optab>si3_extended"
783   [(set (match_operand:DI                 0 "register_operand" "=r")
784         (sign_extend:DI
785             (any_div:SI (match_operand:SI 1 "register_operand" " r")
786                         (match_operand:SI 2 "register_operand" " r"))))]
787   "TARGET_DIV && TARGET_64BIT"
788   "<insn>%i2w\t%0,%1,%2"
789   [(set_attr "type" "idiv")
790    (set_attr "mode" "DI")])
792 (define_insn "div<mode>3"
793   [(set (match_operand:ANYF           0 "register_operand" "=f")
794         (div:ANYF (match_operand:ANYF 1 "register_operand" " f")
795                   (match_operand:ANYF 2 "register_operand" " f")))]
796   "TARGET_HARD_FLOAT && TARGET_FDIV"
797   "fdiv.<fmt>\t%0,%1,%2"
798   [(set_attr "type" "fdiv")
799    (set_attr "mode" "<UNITMODE>")])
802 ;;  ....................
804 ;;      SQUARE ROOT
806 ;;  ....................
808 (define_insn "sqrt<mode>2"
809   [(set (match_operand:ANYF            0 "register_operand" "=f")
810         (sqrt:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
811   "TARGET_HARD_FLOAT && TARGET_FDIV"
813     return "fsqrt.<fmt>\t%0,%1";
815   [(set_attr "type" "fsqrt")
816    (set_attr "mode" "<UNITMODE>")])
818 ;; Floating point multiply accumulate instructions.
820 ;; a * b + c
821 (define_insn "fma<mode>4"
822   [(set (match_operand:ANYF           0 "register_operand" "=f")
823         (fma: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"
827   "fmadd.<fmt>\t%0,%1,%2,%3"
828   [(set_attr "type" "fmadd")
829    (set_attr "mode" "<UNITMODE>")])
831 ;; a * b - c
832 (define_insn "fms<mode>4"
833   [(set (match_operand:ANYF                     0 "register_operand" "=f")
834         (fma:ANYF (match_operand:ANYF           1 "register_operand" " f")
835                   (match_operand:ANYF           2 "register_operand" " f")
836                   (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
837   "TARGET_HARD_FLOAT"
838   "fmsub.<fmt>\t%0,%1,%2,%3"
839   [(set_attr "type" "fmadd")
840    (set_attr "mode" "<UNITMODE>")])
842 ;; -a * b - c
843 (define_insn "fnms<mode>4"
844   [(set (match_operand:ANYF               0 "register_operand" "=f")
845         (fma:ANYF
846             (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
847             (match_operand:ANYF           2 "register_operand" " f")
848             (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
849   "TARGET_HARD_FLOAT"
850   "fnmadd.<fmt>\t%0,%1,%2,%3"
851   [(set_attr "type" "fmadd")
852    (set_attr "mode" "<UNITMODE>")])
854 ;; -a * b + c
855 (define_insn "fnma<mode>4"
856   [(set (match_operand:ANYF               0 "register_operand" "=f")
857         (fma:ANYF
858             (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
859             (match_operand:ANYF           2 "register_operand" " f")
860             (match_operand:ANYF           3 "register_operand" " f")))]
861   "TARGET_HARD_FLOAT"
862   "fnmsub.<fmt>\t%0,%1,%2,%3"
863   [(set_attr "type" "fmadd")
864    (set_attr "mode" "<UNITMODE>")])
866 ;; -(-a * b - c), modulo signed zeros
867 (define_insn "*fma<mode>4"
868   [(set (match_operand:ANYF                   0 "register_operand" "=f")
869         (neg:ANYF
870             (fma:ANYF
871                 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
872                 (match_operand:ANYF           2 "register_operand" " f")
873                 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
874   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
875   "fmadd.<fmt>\t%0,%1,%2,%3"
876   [(set_attr "type" "fmadd")
877    (set_attr "mode" "<UNITMODE>")])
879 ;; -(-a * b + c), modulo signed zeros
880 (define_insn "*fms<mode>4"
881   [(set (match_operand:ANYF                   0 "register_operand" "=f")
882         (neg:ANYF
883             (fma:ANYF
884                 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
885                 (match_operand:ANYF           2 "register_operand" " f")
886                 (match_operand:ANYF           3 "register_operand" " f"))))]
887   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
888   "fmsub.<fmt>\t%0,%1,%2,%3"
889   [(set_attr "type" "fmadd")
890    (set_attr "mode" "<UNITMODE>")])
892 ;; -(a * b + c), modulo signed zeros
893 (define_insn "*fnms<mode>4"
894   [(set (match_operand:ANYF         0 "register_operand" "=f")
895         (neg:ANYF
896             (fma:ANYF
897                 (match_operand:ANYF 1 "register_operand" " f")
898                 (match_operand:ANYF 2 "register_operand" " f")
899                 (match_operand:ANYF 3 "register_operand" " f"))))]
900   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
901   "fnmadd.<fmt>\t%0,%1,%2,%3"
902   [(set_attr "type" "fmadd")
903    (set_attr "mode" "<UNITMODE>")])
905 ;; -(a * b - c), modulo signed zeros
906 (define_insn "*fnma<mode>4"
907   [(set (match_operand:ANYF                   0 "register_operand" "=f")
908         (neg:ANYF
909             (fma:ANYF
910                 (match_operand:ANYF           1 "register_operand" " f")
911                 (match_operand:ANYF           2 "register_operand" " f")
912                 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
913   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
914   "fnmsub.<fmt>\t%0,%1,%2,%3"
915   [(set_attr "type" "fmadd")
916    (set_attr "mode" "<UNITMODE>")])
919 ;;  ....................
921 ;;      SIGN INJECTION
923 ;;  ....................
925 (define_insn "abs<mode>2"
926   [(set (match_operand:ANYF           0 "register_operand" "=f")
927         (abs:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
928   "TARGET_HARD_FLOAT"
929   "fabs.<fmt>\t%0,%1"
930   [(set_attr "type" "fmove")
931    (set_attr "mode" "<UNITMODE>")])
933 (define_insn "copysign<mode>3"
934   [(set (match_operand:ANYF 0 "register_operand"               "=f")
935         (unspec:ANYF [(match_operand:ANYF 1 "register_operand" " f")
936                       (match_operand:ANYF 2 "register_operand" " f")]
937                      UNSPEC_COPYSIGN))]
938   "TARGET_HARD_FLOAT"
939   "fsgnj.<fmt>\t%0,%1,%2"
940   [(set_attr "type" "fmove")
941    (set_attr "mode" "<UNITMODE>")])
943 (define_insn "neg<mode>2"
944   [(set (match_operand:ANYF           0 "register_operand" "=f")
945         (neg:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
946   "TARGET_HARD_FLOAT"
947   "fneg.<fmt>\t%0,%1"
948   [(set_attr "type" "fmove")
949    (set_attr "mode" "<UNITMODE>")])
952 ;;  ....................
954 ;;      MIN/MAX
956 ;;  ....................
958 (define_insn "smin<mode>3"
959   [(set (match_operand:ANYF            0 "register_operand" "=f")
960         (smin:ANYF (match_operand:ANYF 1 "register_operand" " f")
961                    (match_operand:ANYF 2 "register_operand" " f")))]
962   "TARGET_HARD_FLOAT"
963   "fmin.<fmt>\t%0,%1,%2"
964   [(set_attr "type" "fmove")
965    (set_attr "mode" "<UNITMODE>")])
967 (define_insn "smax<mode>3"
968   [(set (match_operand:ANYF            0 "register_operand" "=f")
969         (smax:ANYF (match_operand:ANYF 1 "register_operand" " f")
970                    (match_operand:ANYF 2 "register_operand" " f")))]
971   "TARGET_HARD_FLOAT"
972   "fmax.<fmt>\t%0,%1,%2"
973   [(set_attr "type" "fmove")
974    (set_attr "mode" "<UNITMODE>")])
977 ;;  ....................
979 ;;      LOGICAL
981 ;;  ....................
984 ;; For RV64, we don't expose the SImode operations to the rtl expanders,
985 ;; but SImode versions exist for combine.
987 (define_insn "<optab><mode>3"
988   [(set (match_operand:X                0 "register_operand" "=r,r")
989         (any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
990                        (match_operand:X 2 "arith_operand"    " r,I")))]
991   ""
992   "<insn>%i2\t%0,%1,%2"
993   [(set_attr "type" "logical")
994    (set_attr "mode" "<MODE>")])
996 (define_insn "*<optab>si3_internal"
997   [(set (match_operand:SI                 0 "register_operand" "=r,r")
998         (any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r")
999                         (match_operand:SI 2 "arith_operand"    " r,I")))]
1000   "TARGET_64BIT"
1001   "<insn>%i2\t%0,%1,%2"
1002   [(set_attr "type" "logical")
1003    (set_attr "mode" "SI")])
1005 (define_insn "one_cmpl<mode>2"
1006   [(set (match_operand:X        0 "register_operand" "=r")
1007         (not:X (match_operand:X 1 "register_operand" " r")))]
1008   ""
1009   "not\t%0,%1"
1010   [(set_attr "type" "logical")
1011    (set_attr "mode" "<MODE>")])
1013 (define_insn "*one_cmplsi2_internal"
1014   [(set (match_operand:SI         0 "register_operand" "=r")
1015         (not:SI (match_operand:SI 1 "register_operand" " r")))]
1016   "TARGET_64BIT"
1017   "not\t%0,%1"
1018   [(set_attr "type" "logical")
1019    (set_attr "mode" "SI")])
1022 ;;  ....................
1024 ;;      TRUNCATION
1026 ;;  ....................
1028 (define_insn "truncdfsf2"
1029   [(set (match_operand:SF     0 "register_operand" "=f")
1030         (float_truncate:SF
1031             (match_operand:DF 1 "register_operand" " f")))]
1032   "TARGET_DOUBLE_FLOAT"
1033   "fcvt.s.d\t%0,%1"
1034   [(set_attr "type" "fcvt")
1035    (set_attr "mode" "SF")])
1038 ;;  ....................
1040 ;;      ZERO EXTENSION
1042 ;;  ....................
1044 ;; Extension insns.
1046 (define_insn_and_split "zero_extendsidi2"
1047   [(set (match_operand:DI     0 "register_operand"     "=r,r")
1048         (zero_extend:DI
1049             (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
1050   "TARGET_64BIT"
1051   "@
1052    #
1053    lwu\t%0,%1"
1054   "&& reload_completed
1055    && REG_P (operands[1])
1056    && !paradoxical_subreg_p (operands[0])"
1057   [(set (match_dup 0)
1058         (ashift:DI (match_dup 1) (const_int 32)))
1059    (set (match_dup 0)
1060         (lshiftrt:DI (match_dup 0) (const_int 32)))]
1061   { operands[1] = gen_lowpart (DImode, operands[1]); }
1062   [(set_attr "move_type" "shift_shift,load")
1063    (set_attr "mode" "DI")])
1065 (define_insn_and_split "zero_extendhi<GPR:mode>2"
1066   [(set (match_operand:GPR    0 "register_operand"     "=r,r")
1067         (zero_extend:GPR
1068             (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
1069   ""
1070   "@
1071    #
1072    lhu\t%0,%1"
1073   "&& reload_completed
1074    && REG_P (operands[1])
1075    && !paradoxical_subreg_p (operands[0])"
1076   [(set (match_dup 0)
1077         (ashift:GPR (match_dup 1) (match_dup 2)))
1078    (set (match_dup 0)
1079         (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
1080   {
1081     operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
1082     operands[2] = GEN_INT(GET_MODE_BITSIZE(<GPR:MODE>mode) - 16);
1083   }
1084   [(set_attr "move_type" "shift_shift,load")
1085    (set_attr "mode" "<GPR:MODE>")])
1087 (define_insn "zero_extendqi<SUPERQI:mode>2"
1088   [(set (match_operand:SUPERQI 0 "register_operand"    "=r,r")
1089         (zero_extend:SUPERQI
1090             (match_operand:QI 1 "nonimmediate_operand" " r,m")))]
1091   ""
1092   "@
1093    andi\t%0,%1,0xff
1094    lbu\t%0,%1"
1095   [(set_attr "move_type" "andi,load")
1096    (set_attr "mode" "<SUPERQI:MODE>")])
1099 ;;  ....................
1101 ;;      SIGN EXTENSION
1103 ;;  ....................
1105 (define_insn "extendsidi2"
1106   [(set (match_operand:DI     0 "register_operand"     "=r,r")
1107         (sign_extend:DI
1108             (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
1109   "TARGET_64BIT"
1110   "@
1111    sext.w\t%0,%1
1112    lw\t%0,%1"
1113   [(set_attr "move_type" "move,load")
1114    (set_attr "mode" "DI")])
1116 (define_insn_and_split "extend<SHORT:mode><SUPERQI:mode>2"
1117   [(set (match_operand:SUPERQI   0 "register_operand"     "=r,r")
1118         (sign_extend:SUPERQI
1119             (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
1120   ""
1121   "@
1122    #
1123    l<SHORT:size>\t%0,%1"
1124   "&& reload_completed
1125    && REG_P (operands[1])
1126    && !paradoxical_subreg_p (operands[0])"
1127   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1128    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
1130   operands[0] = gen_lowpart (SImode, operands[0]);
1131   operands[1] = gen_lowpart (SImode, operands[1]);
1132   operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
1133                          - GET_MODE_BITSIZE (<SHORT:MODE>mode));
1135   [(set_attr "move_type" "shift_shift,load")
1136    (set_attr "mode" "SI")])
1138 (define_insn "extendsfdf2"
1139   [(set (match_operand:DF     0 "register_operand" "=f")
1140         (float_extend:DF
1141             (match_operand:SF 1 "register_operand" " f")))]
1142   "TARGET_DOUBLE_FLOAT"
1143   "fcvt.d.s\t%0,%1"
1144   [(set_attr "type" "fcvt")
1145    (set_attr "mode" "DF")])
1148 ;;  ....................
1150 ;;      CONVERSIONS
1152 ;;  ....................
1154 (define_insn "fix_trunc<ANYF:mode><GPR:mode>2"
1155   [(set (match_operand:GPR      0 "register_operand" "=r")
1156         (fix:GPR
1157             (match_operand:ANYF 1 "register_operand" " f")))]
1158   "TARGET_HARD_FLOAT"
1159   "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,rtz"
1160   [(set_attr "type" "fcvt")
1161    (set_attr "mode" "<ANYF:MODE>")])
1163 (define_insn "fixuns_trunc<ANYF:mode><GPR:mode>2"
1164   [(set (match_operand:GPR      0 "register_operand" "=r")
1165         (unsigned_fix:GPR
1166             (match_operand:ANYF 1 "register_operand" " f")))]
1167   "TARGET_HARD_FLOAT"
1168   "fcvt.<GPR:ifmt>u.<ANYF:fmt> %0,%1,rtz"
1169   [(set_attr "type" "fcvt")
1170    (set_attr "mode" "<ANYF:MODE>")])
1172 (define_insn "float<GPR:mode><ANYF:mode>2"
1173   [(set (match_operand:ANYF    0 "register_operand" "= f")
1174         (float:ANYF
1175             (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1176   "TARGET_HARD_FLOAT"
1177   "fcvt.<ANYF:fmt>.<GPR:ifmt>\t%0,%z1"
1178   [(set_attr "type" "fcvt")
1179    (set_attr "mode" "<ANYF:MODE>")])
1181 (define_insn "floatuns<GPR:mode><ANYF:mode>2"
1182   [(set (match_operand:ANYF    0 "register_operand" "= f")
1183         (unsigned_float:ANYF
1184             (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1185   "TARGET_HARD_FLOAT"
1186   "fcvt.<ANYF:fmt>.<GPR:ifmt>u\t%0,%z1"
1187   [(set_attr "type" "fcvt")
1188    (set_attr "mode" "<ANYF:MODE>")])
1190 (define_insn "l<rint_pattern><ANYF:mode><GPR:mode>2"
1191   [(set (match_operand:GPR       0 "register_operand" "=r")
1192         (unspec:GPR
1193             [(match_operand:ANYF 1 "register_operand" " f")]
1194             RINT))]
1195   "TARGET_HARD_FLOAT"
1196   "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,<rint_rm>"
1197   [(set_attr "type" "fcvt")
1198    (set_attr "mode" "<ANYF:MODE>")])
1201 ;;  ....................
1203 ;;      DATA MOVEMENT
1205 ;;  ....................
1207 ;; Lower-level instructions for loading an address from the GOT.
1208 ;; We could use MEMs, but an unspec gives more optimization
1209 ;; opportunities.
1211 (define_insn "got_load<mode>"
1212    [(set (match_operand:P      0 "register_operand" "=r")
1213          (unspec:P
1214              [(match_operand:P 1 "symbolic_operand" "")]
1215              UNSPEC_LOAD_GOT))]
1216   ""
1217   "la\t%0,%1"
1218    [(set_attr "got" "load")
1219     (set_attr "mode" "<MODE>")])
1221 (define_insn "tls_add_tp_le<mode>"
1222   [(set (match_operand:P      0 "register_operand" "=r")
1223         (unspec:P
1224             [(match_operand:P 1 "register_operand" "r")
1225              (match_operand:P 2 "register_operand" "r")
1226              (match_operand:P 3 "symbolic_operand" "")]
1227             UNSPEC_TLS_LE))]
1228   ""
1229   "add\t%0,%1,%2,%%tprel_add(%3)"
1230   [(set_attr "type" "arith")
1231    (set_attr "mode" "<MODE>")])
1233 (define_insn "got_load_tls_gd<mode>"
1234   [(set (match_operand:P      0 "register_operand" "=r")
1235         (unspec:P
1236             [(match_operand:P 1 "symbolic_operand" "")]
1237             UNSPEC_TLS_GD))]
1238   ""
1239   "la.tls.gd\t%0,%1"
1240   [(set_attr "got" "load")
1241    (set_attr "mode" "<MODE>")])
1243 (define_insn "got_load_tls_ie<mode>"
1244   [(set (match_operand:P      0 "register_operand" "=r")
1245         (unspec:P
1246             [(match_operand:P 1 "symbolic_operand" "")]
1247             UNSPEC_TLS_IE))]
1248   ""
1249   "la.tls.ie\t%0,%1"
1250   [(set_attr "got" "load")
1251    (set_attr "mode" "<MODE>")])
1253 (define_insn "auipc<mode>"
1254   [(set (match_operand:P           0 "register_operand" "=r")
1255         (unspec:P
1256             [(match_operand:P      1 "symbolic_operand" "")
1257                   (match_operand:P 2 "const_int_operand")
1258                   (pc)]
1259             UNSPEC_AUIPC))]
1260   ""
1261   ".LA%2: auipc\t%0,%h1"
1262   [(set_attr "type" "auipc")
1263    (set_attr "cannot_copy" "yes")])
1265 ;; Instructions for adding the low 12 bits of an address to a register.
1266 ;; Operand 2 is the address: riscv_print_operand works out which relocation
1267 ;; should be applied.
1269 (define_insn "*low<mode>"
1270   [(set (match_operand:P           0 "register_operand" "=r")
1271         (lo_sum:P (match_operand:P 1 "register_operand" " r")
1272                   (match_operand:P 2 "symbolic_operand" "")))]
1273   ""
1274   "addi\t%0,%1,%R2"
1275   [(set_attr "type" "arith")
1276    (set_attr "mode" "<MODE>")])
1278 ;; Allow combine to split complex const_int load sequences, using operand 2
1279 ;; to store the intermediate results.  See move_operand for details.
1280 (define_split
1281   [(set (match_operand:GPR 0 "register_operand")
1282         (match_operand:GPR 1 "splittable_const_int_operand"))
1283    (clobber (match_operand:GPR 2 "register_operand"))]
1284   ""
1285   [(const_int 0)]
1287   riscv_move_integer (operands[2], operands[0], INTVAL (operands[1]),
1288                       <GPR:MODE>mode, TRUE);
1289   DONE;
1292 ;; Likewise, for symbolic operands.
1293 (define_split
1294   [(set (match_operand:P 0 "register_operand")
1295         (match_operand:P 1))
1296    (clobber (match_operand:P 2 "register_operand"))]
1297   "riscv_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL, TRUE)"
1298   [(set (match_dup 0) (match_dup 3))]
1300   riscv_split_symbol (operands[2], operands[1],
1301                       MAX_MACHINE_MODE, &operands[3], TRUE);
1304 ;; 64-bit integer moves
1306 (define_expand "movdi"
1307   [(set (match_operand:DI 0 "")
1308         (match_operand:DI 1 ""))]
1309   ""
1311   if (riscv_legitimize_move (DImode, operands[0], operands[1]))
1312     DONE;
1315 (define_insn "*movdi_32bit"
1316   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,  *f,*f,*r,*f,*m")
1317         (match_operand:DI 1 "move_operand"         " r,i,m,r,*J*r,*m,*f,*f,*f"))]
1318   "!TARGET_64BIT
1319    && (register_operand (operands[0], DImode)
1320        || reg_or_0_operand (operands[1], DImode))"
1321   { return riscv_output_move (operands[0], operands[1]); }
1322   [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1323    (set_attr "mode" "DI")])
1325 (define_insn "*movdi_64bit"
1326   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*f,*r,*f,*m")
1327         (match_operand:DI 1 "move_operand"         " r,T,m,rJ,*r*J,*m,*f,*f,*f"))]
1328   "TARGET_64BIT
1329    && (register_operand (operands[0], DImode)
1330        || reg_or_0_operand (operands[1], DImode))"
1331   { return riscv_output_move (operands[0], operands[1]); }
1332   [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1333    (set_attr "mode" "DI")])
1335 ;; 32-bit Integer moves
1337 (define_expand "mov<mode>"
1338   [(set (match_operand:MOVE32 0 "")
1339         (match_operand:MOVE32 1 ""))]
1340   ""
1342   if (riscv_legitimize_move (<MODE>mode, operands[0], operands[1]))
1343     DONE;
1346 (define_insn "*movsi_internal"
1347   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*f,*r,*m")
1348         (match_operand:SI 1 "move_operand"         " r,T,m,rJ,*r*J,*m,*f,*f"))]
1349   "(register_operand (operands[0], SImode)
1350     || reg_or_0_operand (operands[1], SImode))"
1351   { return riscv_output_move (operands[0], operands[1]); }
1352   [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore")
1353    (set_attr "mode" "SI")])
1355 ;; 16-bit Integer moves
1357 ;; Unlike most other insns, the move insns can't be split with
1358 ;; different predicates, because register spilling and other parts of
1359 ;; the compiler, have memoized the insn number already.
1360 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
1362 (define_expand "movhi"
1363   [(set (match_operand:HI 0 "")
1364         (match_operand:HI 1 ""))]
1365   ""
1367   if (riscv_legitimize_move (HImode, operands[0], operands[1]))
1368     DONE;
1371 (define_insn "*movhi_internal"
1372   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*r")
1373         (match_operand:HI 1 "move_operand"         " r,T,m,rJ,*r*J,*f"))]
1374   "(register_operand (operands[0], HImode)
1375     || reg_or_0_operand (operands[1], HImode))"
1376   { return riscv_output_move (operands[0], operands[1]); }
1377   [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1378    (set_attr "mode" "HI")])
1380 ;; HImode constant generation; see riscv_move_integer for details.
1381 ;; si+si->hi without truncation is legal because of
1382 ;; TARGET_TRULY_NOOP_TRUNCATION.
1384 (define_insn "*add<mode>hi3"
1385   [(set (match_operand:HI            0 "register_operand" "=r,r")
1386         (plus:HI (match_operand:HISI 1 "register_operand" " r,r")
1387                  (match_operand:HISI 2 "arith_operand"    " r,I")))]
1388   ""
1389   { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
1390   [(set_attr "type" "arith")
1391    (set_attr "mode" "HI")])
1393 (define_insn "*xor<mode>hi3"
1394   [(set (match_operand:HI 0 "register_operand"           "=r,r")
1395         (xor:HI (match_operand:HISI 1 "register_operand" " r,r")
1396                 (match_operand:HISI 2 "arith_operand"    " r,I")))]
1397   ""
1398   "xor%i2\t%0,%1,%2"
1399   [(set_attr "type" "logical")
1400    (set_attr "mode" "HI")])
1402 ;; 8-bit Integer moves
1404 (define_expand "movqi"
1405   [(set (match_operand:QI 0 "")
1406         (match_operand:QI 1 ""))]
1407   ""
1409   if (riscv_legitimize_move (QImode, operands[0], operands[1]))
1410     DONE;
1413 (define_insn "*movqi_internal"
1414   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*r")
1415         (match_operand:QI 1 "move_operand"         " r,I,m,rJ,*r*J,*f"))]
1416   "(register_operand (operands[0], QImode)
1417     || reg_or_0_operand (operands[1], QImode))"
1418   { return riscv_output_move (operands[0], operands[1]); }
1419   [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1420    (set_attr "mode" "QI")])
1422 ;; 32-bit floating point moves
1424 (define_expand "movsf"
1425   [(set (match_operand:SF 0 "")
1426         (match_operand:SF 1 ""))]
1427   ""
1429   if (riscv_legitimize_move (SFmode, operands[0], operands[1]))
1430     DONE;
1433 (define_insn "*movsf_hardfloat"
1434   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,  *r,*r,*m")
1435         (match_operand:SF 1 "move_operand"         " f,G,m,f,G,*r,*f,*G*r,*m,*r"))]
1436   "TARGET_HARD_FLOAT
1437    && (register_operand (operands[0], SFmode)
1438        || reg_or_0_operand (operands[1], SFmode))"
1439   { return riscv_output_move (operands[0], operands[1]); }
1440   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1441    (set_attr "mode" "SF")])
1443 (define_insn "*movsf_softfloat"
1444   [(set (match_operand:SF 0 "nonimmediate_operand" "= r,r,m")
1445         (match_operand:SF 1 "move_operand"         " Gr,m,r"))]
1446   "!TARGET_HARD_FLOAT
1447    && (register_operand (operands[0], SFmode)
1448        || reg_or_0_operand (operands[1], SFmode))"
1449   { return riscv_output_move (operands[0], operands[1]); }
1450   [(set_attr "move_type" "move,load,store")
1451    (set_attr "mode" "SF")])
1453 ;; 64-bit floating point moves
1455 (define_expand "movdf"
1456   [(set (match_operand:DF 0 "")
1457         (match_operand:DF 1 ""))]
1458   ""
1460   if (riscv_legitimize_move (DFmode, operands[0], operands[1]))
1461     DONE;
1464 ;; In RV32, we lack fmv.x.d and fmv.d.x.  Go through memory instead.
1465 ;; (However, we can still use fcvt.d.w to zero a floating-point register.)
1466 (define_insn "*movdf_hardfloat_rv32"
1467   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,  *r,*r,*m")
1468         (match_operand:DF 1 "move_operand"         " f,G,m,f,G,*r*G,*m,*r"))]
1469   "!TARGET_64BIT && TARGET_DOUBLE_FLOAT
1470    && (register_operand (operands[0], DFmode)
1471        || reg_or_0_operand (operands[1], DFmode))"
1472   { return riscv_output_move (operands[0], operands[1]); }
1473   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,move,load,store")
1474    (set_attr "mode" "DF")])
1476 (define_insn "*movdf_hardfloat_rv64"
1477   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,  *r,*r,*m")
1478         (match_operand:DF 1 "move_operand"         " f,G,m,f,G,*r,*f,*r*G,*m,*r"))]
1479   "TARGET_64BIT && TARGET_DOUBLE_FLOAT
1480    && (register_operand (operands[0], DFmode)
1481        || reg_or_0_operand (operands[1], DFmode))"
1482   { return riscv_output_move (operands[0], operands[1]); }
1483   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1484    (set_attr "mode" "DF")])
1486 (define_insn "*movdf_softfloat"
1487   [(set (match_operand:DF 0 "nonimmediate_operand" "= r,r, m")
1488         (match_operand:DF 1 "move_operand"         " rG,m,rG"))]
1489   "!TARGET_DOUBLE_FLOAT
1490    && (register_operand (operands[0], DFmode)
1491        || reg_or_0_operand (operands[1], DFmode))"
1492   { return riscv_output_move (operands[0], operands[1]); }
1493   [(set_attr "move_type" "move,load,store")
1494    (set_attr "mode" "DF")])
1496 (define_split
1497   [(set (match_operand:MOVE64 0 "nonimmediate_operand")
1498         (match_operand:MOVE64 1 "move_operand"))]
1499   "reload_completed
1500    && riscv_split_64bit_move_p (operands[0], operands[1])"
1501   [(const_int 0)]
1503   riscv_split_doubleword_move (operands[0], operands[1]);
1504   DONE;
1507 (define_expand "cpymemsi"
1508   [(parallel [(set (match_operand:BLK 0 "general_operand")
1509                    (match_operand:BLK 1 "general_operand"))
1510               (use (match_operand:SI 2 ""))
1511               (use (match_operand:SI 3 "const_int_operand"))])]
1512   ""
1514   if (riscv_expand_block_move (operands[0], operands[1], operands[2]))
1515     DONE;
1516   else
1517     FAIL;
1520 ;; Expand in-line code to clear the instruction cache between operand[0] and
1521 ;; operand[1].
1522 (define_expand "clear_cache"
1523   [(match_operand 0 "pmode_register_operand")
1524    (match_operand 1 "pmode_register_operand")]
1525   ""
1527 #ifdef ICACHE_FLUSH_FUNC
1528   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, ICACHE_FLUSH_FUNC),
1529                      LCT_NORMAL, VOIDmode, operands[0], Pmode,
1530                      operands[1], Pmode, const0_rtx, Pmode);
1531 #else
1532   emit_insn (gen_fence_i ());
1533 #endif
1534   DONE;
1537 (define_insn "fence"
1538   [(unspec_volatile [(const_int 0)] UNSPECV_FENCE)]
1539   ""
1540   "%|fence%-")
1542 (define_insn "fence_i"
1543   [(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)]
1544   ""
1545   "fence.i")
1548 ;;  ....................
1550 ;;      SHIFTS
1552 ;;  ....................
1554 ;; Use a QImode shift count, to avoid generating sign or zero extend
1555 ;; instructions for shift counts, and to avoid dropping subregs.
1556 ;; expand_shift_1 can do this automatically when SHIFT_COUNT_TRUNCATED is
1557 ;; defined, but use of that is discouraged.
1559 (define_insn "<optab>si3"
1560   [(set (match_operand:SI     0 "register_operand" "= r")
1561         (any_shift:SI
1562             (match_operand:SI 1 "register_operand" "  r")
1563             (match_operand:QI 2 "arith_operand"    " rI")))]
1564   ""
1566   if (GET_CODE (operands[2]) == CONST_INT)
1567     operands[2] = GEN_INT (INTVAL (operands[2])
1568                            & (GET_MODE_BITSIZE (SImode) - 1));
1570   return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2";
1572   [(set_attr "type" "shift")
1573    (set_attr "mode" "SI")])
1575 (define_insn_and_split "*<optab>si3_mask"
1576   [(set (match_operand:SI     0 "register_operand" "= r")
1577         (any_shift:SI
1578             (match_operand:SI 1 "register_operand" "  r")
1579             (subreg:QI
1580              (and:SI
1581               (match_operand:SI 2 "register_operand"  "r")
1582               (match_operand 3 "const_int_operand")) 0)))]
1583   "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1584    == GET_MODE_BITSIZE (SImode)-1"
1585   "#"
1586   "&& 1"
1587   [(set (match_dup 0)
1588         (any_shift:SI (match_dup 1)
1589                       (match_dup 2)))]
1590   "operands[2] = gen_lowpart (QImode, operands[2]);"
1591   [(set_attr "type" "shift")
1592    (set_attr "mode" "SI")])
1594 (define_insn_and_split "*<optab>si3_mask_1"
1595   [(set (match_operand:SI     0 "register_operand" "= r")
1596         (any_shift:SI
1597             (match_operand:SI 1 "register_operand" "  r")
1598             (subreg:QI
1599              (and:DI
1600               (match_operand:DI 2 "register_operand"  "r")
1601               (match_operand 3 "const_int_operand")) 0)))]
1602   "TARGET_64BIT
1603    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1604        == GET_MODE_BITSIZE (SImode)-1"
1605   "#"
1606   "&& 1"
1607   [(set (match_dup 0)
1608         (any_shift:SI (match_dup 1)
1609                       (match_dup 2)))]
1610   "operands[2] = gen_lowpart (QImode, operands[2]);"
1611   [(set_attr "type" "shift")
1612    (set_attr "mode" "SI")])
1614 (define_insn "<optab>di3"
1615   [(set (match_operand:DI 0 "register_operand"     "= r")
1616         (any_shift:DI
1617             (match_operand:DI 1 "register_operand" "  r")
1618             (match_operand:QI 2 "arith_operand"    " rI")))]
1619   "TARGET_64BIT"
1621   if (GET_CODE (operands[2]) == CONST_INT)
1622     operands[2] = GEN_INT (INTVAL (operands[2])
1623                            & (GET_MODE_BITSIZE (DImode) - 1));
1625   return "<insn>%i2\t%0,%1,%2";
1627   [(set_attr "type" "shift")
1628    (set_attr "mode" "DI")])
1630 (define_insn_and_split "*<optab>di3_mask"
1631   [(set (match_operand:DI     0 "register_operand" "= r")
1632         (any_shift:DI
1633             (match_operand:DI 1 "register_operand" "  r")
1634             (subreg:QI
1635              (and:SI
1636               (match_operand:SI 2 "register_operand"  "r")
1637               (match_operand 3 "const_int_operand")) 0)))]
1638   "TARGET_64BIT
1639    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1640        == GET_MODE_BITSIZE (DImode)-1"
1641   "#"
1642   "&& 1"
1643   [(set (match_dup 0)
1644         (any_shift:DI (match_dup 1)
1645                       (match_dup 2)))]
1646   "operands[2] = gen_lowpart (QImode, operands[2]);"
1647   [(set_attr "type" "shift")
1648    (set_attr "mode" "DI")])
1650 (define_insn_and_split "*<optab>di3_mask_1"
1651   [(set (match_operand:DI     0 "register_operand" "= r")
1652         (any_shift:DI
1653             (match_operand:DI 1 "register_operand" "  r")
1654             (subreg:QI
1655              (and:DI
1656               (match_operand:DI 2 "register_operand"  "r")
1657               (match_operand 3 "const_int_operand")) 0)))]
1658   "TARGET_64BIT
1659    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1660        == GET_MODE_BITSIZE (DImode)-1"
1661   "#"
1662   "&& 1"
1663   [(set (match_dup 0)
1664         (any_shift:DI (match_dup 1)
1665                       (match_dup 2)))]
1666   "operands[2] = gen_lowpart (QImode, operands[2]);"
1667   [(set_attr "type" "shift")
1668    (set_attr "mode" "DI")])
1670 (define_insn "*<optab>si3_extend"
1671   [(set (match_operand:DI                   0 "register_operand" "= r")
1672         (sign_extend:DI
1673             (any_shift:SI (match_operand:SI 1 "register_operand" "  r")
1674                           (match_operand:QI 2 "arith_operand"    " rI"))))]
1675   "TARGET_64BIT"
1677   if (GET_CODE (operands[2]) == CONST_INT)
1678     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1680   return "<insn>%i2w\t%0,%1,%2";
1682   [(set_attr "type" "shift")
1683    (set_attr "mode" "SI")])
1685 (define_insn_and_split "*<optab>si3_extend_mask"
1686   [(set (match_operand:DI                   0 "register_operand" "= r")
1687         (sign_extend:DI
1688             (any_shift:SI
1689              (match_operand:SI 1 "register_operand" "  r")
1690              (subreg:QI
1691               (and:SI
1692                (match_operand:SI 2 "register_operand" " r")
1693                (match_operand 3 "const_int_operand")) 0))))]
1694   "TARGET_64BIT
1695    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1696        == GET_MODE_BITSIZE (SImode)-1"
1697   "#"
1698   "&& 1"
1699   [(set (match_dup 0)
1700         (sign_extend:DI
1701          (any_shift:SI (match_dup 1)
1702                        (match_dup 2))))]
1703   "operands[2] = gen_lowpart (QImode, operands[2]);"
1704   [(set_attr "type" "shift")
1705    (set_attr "mode" "SI")])
1707 (define_insn_and_split "*<optab>si3_extend_mask_1"
1708   [(set (match_operand:DI                   0 "register_operand" "= r")
1709         (sign_extend:DI
1710             (any_shift:SI
1711              (match_operand:SI 1 "register_operand" "  r")
1712              (subreg:QI
1713               (and:DI
1714                (match_operand:DI 2 "register_operand" " r")
1715                (match_operand 3 "const_int_operand")) 0))))]
1716   "TARGET_64BIT
1717    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1718        == GET_MODE_BITSIZE (SImode)-1"
1719   "#"
1720   "&& 1"
1721   [(set (match_dup 0)
1722         (sign_extend:DI
1723          (any_shift:SI (match_dup 1)
1724                        (match_dup 2))))]
1725   "operands[2] = gen_lowpart (QImode, operands[2]);"
1726   [(set_attr "type" "shift")
1727    (set_attr "mode" "SI")])
1729 ;; Non-canonical, but can be formed by ree when combine is not successful at
1730 ;; producing one of the two canonical patterns below.
1731 (define_insn "*lshrsi3_zero_extend_1"
1732   [(set (match_operand:DI                   0 "register_operand" "=r")
1733         (zero_extend:DI
1734          (lshiftrt:SI (match_operand:SI     1 "register_operand" " r")
1735                       (match_operand        2 "const_int_operand"))))]
1736   "TARGET_64BIT && (INTVAL (operands[2]) & 0x1f) > 0"
1738   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1740   return "srliw\t%0,%1,%2";
1742   [(set_attr "type" "shift")
1743    (set_attr "mode" "SI")])
1745 ;; Canonical form for a zero-extend of a logical right shift.
1746 (define_insn "*lshrsi3_zero_extend_2"
1747   [(set (match_operand:DI                   0 "register_operand" "=r")
1748         (zero_extract:DI (match_operand:DI  1 "register_operand" " r")
1749                          (match_operand     2 "const_int_operand")
1750                          (match_operand     3 "const_int_operand")))]
1751   "(TARGET_64BIT && (INTVAL (operands[3]) > 0)
1752     && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))"
1754   return "srliw\t%0,%1,%3";
1756   [(set_attr "type" "shift")
1757    (set_attr "mode" "SI")])
1759 ;; Canonical form for a zero-extend of a logical right shift when the
1760 ;; shift count is 31.
1761 (define_insn "*lshrsi3_zero_extend_3"
1762   [(set (match_operand:DI                   0 "register_operand" "=r")
1763         (lt:DI (match_operand:SI            1 "register_operand" " r")
1764                (const_int 0)))]
1765   "TARGET_64BIT"
1767   return "srliw\t%0,%1,31";
1769   [(set_attr "type" "shift")
1770    (set_attr "mode" "SI")])
1772 ;; Handle AND with 2^N-1 for N from 12 to XLEN.  This can be split into
1773 ;; two logical shifts.  Otherwise it requires 3 instructions: lui,
1774 ;; xor/addi/srli, and.
1776 ;; Generating a temporary for the shift output gives better combiner results;
1777 ;; and also fixes a problem where op0 could be a paradoxical reg and shifting
1778 ;; by amounts larger than the size of the SUBREG_REG doesn't work.
1779 (define_split
1780   [(set (match_operand:GPR 0 "register_operand")
1781         (and:GPR (match_operand:GPR 1 "register_operand")
1782                  (match_operand:GPR 2 "p2m1_shift_operand")))
1783    (clobber (match_operand:GPR 3 "register_operand"))]
1784   ""
1785  [(set (match_dup 3)
1786        (ashift:GPR (match_dup 1) (match_dup 2)))
1787   (set (match_dup 0)
1788        (lshiftrt:GPR (match_dup 3) (match_dup 2)))]
1790   /* Op2 is a VOIDmode constant, so get the mode size from op1.  */
1791   operands[2] = GEN_INT (GET_MODE_BITSIZE (GET_MODE (operands[1]))
1792                          - exact_log2 (INTVAL (operands[2]) + 1));
1795 ;; Handle AND with 0xF...F0...0 where there are 32 to 63 zeros.  This can be
1796 ;; split into two shifts.  Otherwise it requires 3 instructions: li, sll, and.
1797 (define_split
1798   [(set (match_operand:DI 0 "register_operand")
1799         (and:DI (match_operand:DI 1 "register_operand")
1800                 (match_operand:DI 2 "high_mask_shift_operand")))
1801    (clobber (match_operand:DI 3 "register_operand"))]
1802   "TARGET_64BIT"
1803   [(set (match_dup 3)
1804         (lshiftrt:DI (match_dup 1) (match_dup 2)))
1805    (set (match_dup 0)
1806         (ashift:DI (match_dup 3) (match_dup 2)))]
1808   operands[2] = GEN_INT (ctz_hwi (INTVAL (operands[2])));
1812 ;;  ....................
1814 ;;      CONDITIONAL BRANCHES
1816 ;;  ....................
1818 ;; Conditional branches
1820 (define_insn "*branch<mode>"
1821   [(set (pc)
1822         (if_then_else
1823          (match_operator 1 "order_operator"
1824                          [(match_operand:X 2 "register_operand" "r")
1825                           (match_operand:X 3 "reg_or_0_operand" "rJ")])
1826          (label_ref (match_operand 0 "" ""))
1827          (pc)))]
1828   ""
1829   "b%C1\t%2,%z3,%0"
1830   [(set_attr "type" "branch")
1831    (set_attr "mode" "none")])
1833 ;; Patterns for implementations that optimize short forward branches.
1835 (define_expand "mov<mode>cc"
1836   [(set (match_operand:GPR 0 "register_operand")
1837         (if_then_else:GPR (match_operand 1 "comparison_operator")
1838                           (match_operand:GPR 2 "register_operand")
1839                           (match_operand:GPR 3 "sfb_alu_operand")))]
1840   "TARGET_SFB_ALU"
1842   rtx cmp = operands[1];
1843   /* We only handle word mode integer compares for now.  */
1844   if (GET_MODE (XEXP (cmp, 0)) != word_mode)
1845     FAIL;
1846   riscv_expand_conditional_move (operands[0], operands[2], operands[3],
1847                                  GET_CODE (cmp), XEXP (cmp, 0), XEXP (cmp, 1));
1848   DONE;
1851 (define_insn "*mov<GPR:mode><X:mode>cc"
1852   [(set (match_operand:GPR 0 "register_operand" "=r,r")
1853         (if_then_else:GPR
1854          (match_operator 5 "order_operator"
1855                 [(match_operand:X 1 "register_operand" "r,r")
1856                  (match_operand:X 2 "reg_or_0_operand" "rJ,rJ")])
1857          (match_operand:GPR 3 "register_operand" "0,0")
1858          (match_operand:GPR 4 "sfb_alu_operand" "rJ,IL")))]
1859   "TARGET_SFB_ALU"
1860   "@
1861    b%C5 %1,%z2,1f; mv %0,%z4; 1: # movcc
1862    b%C5 %1,%z2,1f; li %0,%4; 1: # movcc"
1863   [(set_attr "length" "8")
1864    (set_attr "type" "sfb_alu")
1865    (set_attr "mode" "<GPR:MODE>")])
1867 ;; Used to implement built-in functions.
1868 (define_expand "condjump"
1869   [(set (pc)
1870         (if_then_else (match_operand 0)
1871                       (label_ref (match_operand 1))
1872                       (pc)))])
1874 (define_expand "cbranch<mode>4"
1875   [(set (pc)
1876         (if_then_else (match_operator 0 "comparison_operator"
1877                       [(match_operand:BR 1 "register_operand")
1878                        (match_operand:BR 2 "nonmemory_operand")])
1879                       (label_ref (match_operand 3 ""))
1880                       (pc)))]
1881   ""
1883   riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1884                                    operands[1], operands[2]);
1885   DONE;
1888 (define_expand "cbranch<mode>4"
1889   [(set (pc)
1890         (if_then_else (match_operator 0 "fp_branch_comparison"
1891                        [(match_operand:ANYF 1 "register_operand")
1892                         (match_operand:ANYF 2 "register_operand")])
1893                       (label_ref (match_operand 3 ""))
1894                       (pc)))]
1895   "TARGET_HARD_FLOAT"
1897   riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1898                                    operands[1], operands[2]);
1899   DONE;
1902 (define_insn_and_split "*branch_on_bit<X:mode>"
1903   [(set (pc)
1904         (if_then_else
1905             (match_operator 0 "equality_operator"
1906                 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1907                                  (const_int 1)
1908                                  (match_operand 3 "branch_on_bit_operand"))
1909                                  (const_int 0)])
1910             (label_ref (match_operand 1))
1911             (pc)))
1912    (clobber (match_scratch:X 4 "=&r"))]
1913   ""
1914   "#"
1915   "reload_completed"
1916   [(set (match_dup 4)
1917         (ashift:X (match_dup 2) (match_dup 3)))
1918    (set (pc)
1919         (if_then_else
1920             (match_op_dup 0 [(match_dup 4) (const_int 0)])
1921             (label_ref (match_operand 1))
1922             (pc)))]
1924   int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]);
1925   operands[3] = GEN_INT (shift);
1927   if (GET_CODE (operands[0]) == EQ)
1928     operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx);
1929   else
1930     operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx);
1933 (define_insn_and_split "*branch_on_bit_range<X:mode>"
1934   [(set (pc)
1935         (if_then_else
1936             (match_operator 0 "equality_operator"
1937                 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1938                                  (match_operand 3 "branch_on_bit_operand")
1939                                  (const_int 0))
1940                                  (const_int 0)])
1941             (label_ref (match_operand 1))
1942             (pc)))
1943    (clobber (match_scratch:X 4 "=&r"))]
1944   ""
1945   "#"
1946   "reload_completed"
1947   [(set (match_dup 4)
1948         (ashift:X (match_dup 2) (match_dup 3)))
1949    (set (pc)
1950         (if_then_else
1951             (match_op_dup 0 [(match_dup 4) (const_int 0)])
1952             (label_ref (match_operand 1))
1953             (pc)))]
1955   operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]));
1959 ;;  ....................
1961 ;;      SETTING A REGISTER FROM A COMPARISON
1963 ;;  ....................
1965 ;; Destination is always set in SI mode.
1967 (define_expand "cstore<mode>4"
1968   [(set (match_operand:SI 0 "register_operand")
1969         (match_operator:SI 1 "order_operator"
1970             [(match_operand:GPR 2 "register_operand")
1971              (match_operand:GPR 3 "nonmemory_operand")]))]
1972   ""
1974   riscv_expand_int_scc (operands[0], GET_CODE (operands[1]), operands[2],
1975                         operands[3]);
1976   DONE;
1979 (define_expand "cstore<mode>4"
1980   [(set (match_operand:SI 0 "register_operand")
1981         (match_operator:SI 1 "fp_scc_comparison"
1982              [(match_operand:ANYF 2 "register_operand")
1983               (match_operand:ANYF 3 "register_operand")]))]
1984   "TARGET_HARD_FLOAT"
1986   riscv_expand_float_scc (operands[0], GET_CODE (operands[1]), operands[2],
1987                           operands[3]);
1988   DONE;
1991 (define_insn "*cstore<ANYF:mode><X:mode>4"
1992    [(set (match_operand:X         0 "register_operand" "=r")
1993          (match_operator:X 1 "fp_native_comparison"
1994              [(match_operand:ANYF 2 "register_operand" " f")
1995               (match_operand:ANYF 3 "register_operand" " f")]))]
1996   "TARGET_HARD_FLOAT"
1997   "f%C1.<fmt>\t%0,%2,%3"
1998   [(set_attr "type" "fcmp")
1999    (set_attr "mode" "<UNITMODE>")])
2001 (define_expand "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4"
2002    [(parallel [(set (match_operand:X      0 "register_operand")
2003                     (unspec:X
2004                      [(match_operand:ANYF 1 "register_operand")
2005                       (match_operand:ANYF 2 "register_operand")]
2006                      QUIET_COMPARISON))
2007                (clobber (match_scratch:X 3))])]
2008   "TARGET_HARD_FLOAT")
2010 (define_insn "*f<quiet_pattern>_quiet<ANYF:mode><X:mode>4_default"
2011    [(set (match_operand:X      0 "register_operand" "=r")
2012          (unspec:X
2013           [(match_operand:ANYF 1 "register_operand" " f")
2014            (match_operand:ANYF 2 "register_operand" " f")]
2015           QUIET_COMPARISON))
2016     (clobber (match_scratch:X 3 "=&r"))]
2017   "TARGET_HARD_FLOAT && ! HONOR_SNANS (<ANYF:MODE>mode)"
2018   "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3"
2019   [(set_attr "type" "fcmp")
2020    (set_attr "mode" "<UNITMODE>")
2021    (set (attr "length") (const_int 12))])
2023 (define_insn "*f<quiet_pattern>_quiet<ANYF:mode><X:mode>4_snan"
2024    [(set (match_operand:X      0 "register_operand" "=r")
2025          (unspec:X
2026           [(match_operand:ANYF 1 "register_operand" " f")
2027            (match_operand:ANYF 2 "register_operand" " f")]
2028           QUIET_COMPARISON))
2029     (clobber (match_scratch:X 3 "=&r"))]
2030   "TARGET_HARD_FLOAT && HONOR_SNANS (<ANYF:MODE>mode)"
2031   "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3\n\tfeq.<fmt>\tzero,%1,%2"
2032   [(set_attr "type" "fcmp")
2033    (set_attr "mode" "<UNITMODE>")
2034    (set (attr "length") (const_int 16))])
2036 (define_insn "*seq_zero_<X:mode><GPR:mode>"
2037   [(set (match_operand:GPR       0 "register_operand" "=r")
2038         (eq:GPR (match_operand:X 1 "register_operand" " r")
2039                 (const_int 0)))]
2040   ""
2041   "seqz\t%0,%1"
2042   [(set_attr "type" "slt")
2043    (set_attr "mode" "<X:MODE>")])
2045 (define_insn "*sne_zero_<X:mode><GPR:mode>"
2046   [(set (match_operand:GPR       0 "register_operand" "=r")
2047         (ne:GPR (match_operand:X 1 "register_operand" " r")
2048                 (const_int 0)))]
2049   ""
2050   "snez\t%0,%1"
2051   [(set_attr "type" "slt")
2052    (set_attr "mode" "<X:MODE>")])
2054 (define_insn "*sgt<u>_<X:mode><GPR:mode>"
2055   [(set (match_operand:GPR           0 "register_operand" "= r")
2056         (any_gt:GPR (match_operand:X 1 "register_operand" "  r")
2057                     (match_operand:X 2 "reg_or_0_operand" " rJ")))]
2058   ""
2059   "sgt<u>\t%0,%1,%z2"
2060   [(set_attr "type" "slt")
2061    (set_attr "mode" "<X:MODE>")])
2063 (define_insn "*sge<u>_<X:mode><GPR:mode>"
2064   [(set (match_operand:GPR           0 "register_operand" "=r")
2065         (any_ge:GPR (match_operand:X 1 "register_operand" " r")
2066                     (const_int 1)))]
2067   ""
2068   "slt%i2<u>\t%0,zero,%1"
2069   [(set_attr "type" "slt")
2070    (set_attr "mode" "<X:MODE>")])
2072 (define_insn "*slt<u>_<X:mode><GPR:mode>"
2073   [(set (match_operand:GPR           0 "register_operand" "= r")
2074         (any_lt:GPR (match_operand:X 1 "register_operand" "  r")
2075                     (match_operand:X 2 "arith_operand"    " rI")))]
2076   ""
2077   "slt%i2<u>\t%0,%1,%2"
2078   [(set_attr "type" "slt")
2079    (set_attr "mode" "<X:MODE>")])
2081 (define_insn "*sle<u>_<X:mode><GPR:mode>"
2082   [(set (match_operand:GPR           0 "register_operand" "=r")
2083         (any_le:GPR (match_operand:X 1 "register_operand" " r")
2084                     (match_operand:X 2 "sle_operand" "")))]
2085   ""
2087   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
2088   return "slt%i2<u>\t%0,%1,%2";
2090   [(set_attr "type" "slt")
2091    (set_attr "mode" "<X:MODE>")])
2094 ;;  ....................
2096 ;;      UNCONDITIONAL BRANCHES
2098 ;;  ....................
2100 ;; Unconditional branches.
2102 (define_insn "jump"
2103   [(set (pc)
2104         (label_ref (match_operand 0 "" "")))]
2105   ""
2106   "j\t%l0"
2107   [(set_attr "type"     "jump")
2108    (set_attr "mode"     "none")])
2110 (define_expand "indirect_jump"
2111   [(set (pc) (match_operand 0 "register_operand"))]
2112   ""
2114   operands[0] = force_reg (Pmode, operands[0]);
2115   if (Pmode == SImode)
2116     emit_jump_insn (gen_indirect_jumpsi (operands[0]));
2117   else
2118     emit_jump_insn (gen_indirect_jumpdi (operands[0]));
2119   DONE;
2122 (define_insn "indirect_jump<mode>"
2123   [(set (pc) (match_operand:P 0 "register_operand" "l"))]
2124   ""
2125   "jr\t%0"
2126   [(set_attr "type" "jump")
2127    (set_attr "mode" "none")])
2129 (define_expand "tablejump"
2130   [(set (pc) (match_operand 0 "register_operand" ""))
2131               (use (label_ref (match_operand 1 "" "")))]
2132   ""
2134   if (CASE_VECTOR_PC_RELATIVE)
2135       operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
2136                                          gen_rtx_LABEL_REF (Pmode, operands[1]),
2137                                          NULL_RTX, 0, OPTAB_DIRECT);
2139   if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode)
2140     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
2141   else
2142     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
2143   DONE;
2146 (define_insn "tablejump<mode>"
2147   [(set (pc) (match_operand:GPR 0 "register_operand" "l"))
2148    (use (label_ref (match_operand 1 "" "")))]
2149   ""
2150   "jr\t%0"
2151   [(set_attr "type" "jump")
2152    (set_attr "mode" "none")])
2155 ;;  ....................
2157 ;;      Function prologue/epilogue
2159 ;;  ....................
2162 (define_expand "prologue"
2163   [(const_int 1)]
2164   ""
2166   riscv_expand_prologue ();
2167   DONE;
2170 ;; Block any insns from being moved before this point, since the
2171 ;; profiling call to mcount can use various registers that aren't
2172 ;; saved or used to pass arguments.
2174 (define_insn "blockage"
2175   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2176   ""
2177   ""
2178   [(set_attr "type" "ghost")
2179    (set_attr "mode" "none")])
2181 (define_expand "epilogue"
2182   [(const_int 2)]
2183   ""
2185   riscv_expand_epilogue (NORMAL_RETURN);
2186   DONE;
2189 (define_expand "sibcall_epilogue"
2190   [(const_int 2)]
2191   ""
2193   riscv_expand_epilogue (SIBCALL_RETURN);
2194   DONE;
2197 ;; Trivial return.  Make it look like a normal return insn as that
2198 ;; allows jump optimizations to work better.
2200 (define_expand "return"
2201   [(simple_return)]
2202   "riscv_can_use_return_insn ()"
2203   "")
2205 (define_insn "simple_return"
2206   [(simple_return)]
2207   ""
2209   return riscv_output_return ();
2211   [(set_attr "type"     "jump")
2212    (set_attr "mode"     "none")])
2214 ;; Normal return.
2216 (define_insn "simple_return_internal"
2217   [(simple_return)
2218    (use (match_operand 0 "pmode_register_operand" ""))]
2219   ""
2220   "jr\t%0"
2221   [(set_attr "type"     "jump")
2222    (set_attr "mode"     "none")])
2224 ;; This is used in compiling the unwind routines.
2225 (define_expand "eh_return"
2226   [(use (match_operand 0 "general_operand"))]
2227   ""
2229   if (GET_MODE (operands[0]) != word_mode)
2230     operands[0] = convert_to_mode (word_mode, operands[0], 0);
2231   if (TARGET_64BIT)
2232     emit_insn (gen_eh_set_lr_di (operands[0]));
2233   else
2234     emit_insn (gen_eh_set_lr_si (operands[0]));
2236   emit_jump_insn (gen_eh_return_internal ());
2237   emit_barrier ();
2238   DONE;
2241 ;; Clobber the return address on the stack.  We can't expand this
2242 ;; until we know where it will be put in the stack frame.
2244 (define_insn "eh_set_lr_si"
2245   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2246    (clobber (match_scratch:SI 1 "=&r"))]
2247   "! TARGET_64BIT"
2248   "#")
2250 (define_insn "eh_set_lr_di"
2251   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2252    (clobber (match_scratch:DI 1 "=&r"))]
2253   "TARGET_64BIT"
2254   "#")
2256 (define_split
2257   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
2258    (clobber (match_scratch 1))]
2259   "reload_completed"
2260   [(const_int 0)]
2262   riscv_set_return_address (operands[0], operands[1]);
2263   DONE;
2266 (define_insn_and_split "eh_return_internal"
2267   [(eh_return)]
2268   ""
2269   "#"
2270   "epilogue_completed"
2271   [(const_int 0)]
2272   "riscv_expand_epilogue (EXCEPTION_RETURN); DONE;")
2275 ;;  ....................
2277 ;;      FUNCTION CALLS
2279 ;;  ....................
2281 (define_expand "sibcall"
2282   [(parallel [(call (match_operand 0 "")
2283                     (match_operand 1 ""))
2284               (use (match_operand 2 ""))        ;; next_arg_reg
2285               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
2286   ""
2288   rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2289   emit_call_insn (gen_sibcall_internal (target, operands[1]));
2290   DONE;
2293 (define_insn "sibcall_internal"
2294   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U"))
2295          (match_operand 1 "" ""))]
2296   "SIBLING_CALL_P (insn)"
2297   "@
2298    jr\t%0
2299    tail\t%0
2300    tail\t%0@plt"
2301   [(set_attr "type" "call")])
2303 (define_expand "sibcall_value"
2304   [(parallel [(set (match_operand 0 "")
2305                    (call (match_operand 1 "")
2306                          (match_operand 2 "")))
2307               (use (match_operand 3 ""))])]             ;; next_arg_reg
2308   ""
2310   rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2311   emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2]));
2312   DONE;
2315 (define_insn "sibcall_value_internal"
2316   [(set (match_operand 0 "" "")
2317         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U"))
2318               (match_operand 2 "" "")))]
2319   "SIBLING_CALL_P (insn)"
2320   "@
2321    jr\t%1
2322    tail\t%1
2323    tail\t%1@plt"
2324   [(set_attr "type" "call")])
2326 (define_expand "call"
2327   [(parallel [(call (match_operand 0 "")
2328                     (match_operand 1 ""))
2329               (use (match_operand 2 ""))        ;; next_arg_reg
2330               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
2331   ""
2333   rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2334   emit_call_insn (gen_call_internal (target, operands[1]));
2335   DONE;
2338 (define_insn "call_internal"
2339   [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U"))
2340          (match_operand 1 "" ""))
2341    (clobber (reg:SI RETURN_ADDR_REGNUM))]
2342   ""
2343   "@
2344    jalr\t%0
2345    call\t%0
2346    call\t%0@plt"
2347   [(set_attr "type" "call")])
2349 (define_expand "call_value"
2350   [(parallel [(set (match_operand 0 "")
2351                    (call (match_operand 1 "")
2352                          (match_operand 2 "")))
2353               (use (match_operand 3 ""))])]             ;; next_arg_reg
2354   ""
2356   rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2357   emit_call_insn (gen_call_value_internal (operands[0], target, operands[2]));
2358   DONE;
2361 (define_insn "call_value_internal"
2362   [(set (match_operand 0 "" "")
2363         (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U"))
2364               (match_operand 2 "" "")))
2365    (clobber (reg:SI RETURN_ADDR_REGNUM))]
2366   ""
2367   "@
2368    jalr\t%1
2369    call\t%1
2370    call\t%1@plt"
2371   [(set_attr "type" "call")])
2373 ;; Call subroutine returning any type.
2375 (define_expand "untyped_call"
2376   [(parallel [(call (match_operand 0 "")
2377                     (const_int 0))
2378               (match_operand 1 "")
2379               (match_operand 2 "")])]
2380   ""
2382   int i;
2384   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2386   for (i = 0; i < XVECLEN (operands[2], 0); i++)
2387     {
2388       rtx set = XVECEXP (operands[2], 0, i);
2389       riscv_emit_move (SET_DEST (set), SET_SRC (set));
2390     }
2392   emit_insn (gen_blockage ());
2393   DONE;
2396 (define_insn "nop"
2397   [(const_int 0)]
2398   ""
2399   "nop"
2400   [(set_attr "type"     "nop")
2401    (set_attr "mode"     "none")])
2403 (define_insn "trap"
2404   [(trap_if (const_int 1) (const_int 0))]
2405   ""
2406   "ebreak")
2408 (define_insn "gpr_save"
2409   [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_SAVE)
2410    (clobber (reg:SI T0_REGNUM))
2411    (clobber (reg:SI T1_REGNUM))]
2412   ""
2413   { return riscv_output_gpr_save (INTVAL (operands[0])); })
2415 (define_insn "gpr_restore"
2416   [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_RESTORE)]
2417   ""
2418   "tail\t__riscv_restore_%0")
2420 (define_insn "gpr_restore_return"
2421   [(return)
2422    (use (match_operand 0 "pmode_register_operand" ""))
2423    (const_int 0)]
2424   ""
2425   "")
2427 (define_insn "riscv_frflags"
2428   [(set (match_operand:SI 0 "register_operand" "=r")
2429         (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))]
2430   "TARGET_HARD_FLOAT"
2431   "frflags\t%0")
2433 (define_insn "riscv_fsflags"
2434   [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)]
2435   "TARGET_HARD_FLOAT"
2436   "fsflags\t%0")
2438 (define_insn "riscv_mret"
2439   [(return)
2440    (unspec_volatile [(const_int 0)] UNSPECV_MRET)]
2441   ""
2442   "mret")
2444 (define_insn "riscv_sret"
2445   [(return)
2446    (unspec_volatile [(const_int 0)] UNSPECV_SRET)]
2447   ""
2448   "sret")
2450 (define_insn "riscv_uret"
2451   [(return)
2452    (unspec_volatile [(const_int 0)] UNSPECV_URET)]
2453   ""
2454   "uret")
2456 (define_insn "stack_tie<mode>"
2457   [(set (mem:BLK (scratch))
2458         (unspec:BLK [(match_operand:X 0 "register_operand" "r")
2459                      (match_operand:X 1 "register_operand" "r")]
2460                     UNSPEC_TIE))]
2461   ""
2462   ""
2463   [(set_attr "length" "0")]
2466 ;; This fixes a failure with gcc.c-torture/execute/pr64242.c at -O2 for a
2467 ;; 32-bit target when using -mtune=sifive-7-series.  The first sched pass
2468 ;; runs before register elimination, and we have a non-obvious dependency
2469 ;; between a use of the soft fp and a set of the hard fp.  We fix this by
2470 ;; emitting a clobber using the hard fp between the two insns.
2471 (define_expand "restore_stack_nonlocal"
2472   [(match_operand 0 "register_operand")
2473    (match_operand 1 "memory_operand")]
2474   ""
2476   emit_move_insn (operands[0], operands[1]);
2477   /* Prevent the following hard fp restore from being moved before the move
2478      insn above which uses a copy of the soft fp reg.  */
2479   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
2480   DONE;
2483 (include "sync.md")
2484 (include "peephole.md")
2485 (include "pic.md")
2486 (include "generic.md")
2487 (include "sifive-7.md")