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)
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.
26 ;; Symbolic accesses. The order of this list must match that of
27 ;; enum riscv_symbol_type in riscv-protos.h.
36 ;; High part of PC-relative address.
39 ;; Floating-point unspecs.
50 (define_c_enum "unspecv" [
51 ;; Register save and restore.
55 ;; Floating-point unspecs.
59 ;; Blockage and synchronization.
66 [(RETURN_ADDR_REGNUM 1)
74 (include "predicates.md")
75 (include "constraints.md")
77 ;; ....................
81 ;; ....................
83 (define_attr "got" "unset,xgot_high,load"
84 (const_string "unset"))
86 ;; Classification of moves, extensions and truncations. Most values
87 ;; are as for "type" (see below) but there are also the following
88 ;; move-specific values:
90 ;; andi a single ANDI instruction
91 ;; shift_shift a shift left followed by a shift right
93 ;; This attribute is used to determine the instruction's length and
94 ;; scheduling type. For doubleword moves, the attribute always describes
95 ;; the split instructions; in some cases, it is more appropriate for the
96 ;; scheduling type to be "multi" instead.
97 (define_attr "move_type"
98 "unknown,load,fpload,store,fpstore,mtc,mfc,move,fmove,
99 const,logical,arith,andi,shift_shift"
100 (const_string "unknown"))
102 ;; Main data type used by the insn
103 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
104 (const_string "unknown"))
106 ;; True if the main data type is twice the size of a word.
107 (define_attr "dword_mode" "no,yes"
108 (cond [(and (eq_attr "mode" "DI,DF")
109 (eq (symbol_ref "TARGET_64BIT") (const_int 0)))
112 (and (eq_attr "mode" "TI,TF")
113 (ne (symbol_ref "TARGET_64BIT") (const_int 0)))
114 (const_string "yes")]
115 (const_string "no")))
117 ;; Classification of each insn.
118 ;; branch conditional branch
119 ;; jump unconditional jump
120 ;; call unconditional call
121 ;; load load instruction(s)
122 ;; fpload floating point load
123 ;; store store instruction(s)
124 ;; fpstore floating point store
125 ;; mtc transfer to coprocessor
126 ;; mfc transfer from coprocessor
127 ;; const load constant
128 ;; arith integer arithmetic instructions
129 ;; logical integer logical instructions
130 ;; shift integer shift instructions
131 ;; slt set less than instructions
132 ;; imul integer multiply
133 ;; idiv integer divide
134 ;; move integer register move (addi rd, rs1, 0)
135 ;; fmove floating point register move
136 ;; fadd floating point add/subtract
137 ;; fmul floating point multiply
138 ;; fmadd floating point multiply-add
139 ;; fdiv floating point divide
140 ;; fcmp floating point compare
141 ;; fcvt floating point convert
142 ;; fsqrt floating point square root
143 ;; multi multiword sequence (or user asm statements)
145 ;; ghost an instruction that produces no real code
147 "unknown,branch,jump,call,load,fpload,store,fpstore,
148 mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul,
149 fmadd,fdiv,fcmp,fcvt,fsqrt,multi,nop,ghost"
150 (cond [(eq_attr "got" "load") (const_string "load")
152 ;; If a doubleword move uses these expensive instructions,
153 ;; it is usually better to schedule them in the same way
154 ;; as the singleword form, rather than as "multi".
155 (eq_attr "move_type" "load") (const_string "load")
156 (eq_attr "move_type" "fpload") (const_string "fpload")
157 (eq_attr "move_type" "store") (const_string "store")
158 (eq_attr "move_type" "fpstore") (const_string "fpstore")
159 (eq_attr "move_type" "mtc") (const_string "mtc")
160 (eq_attr "move_type" "mfc") (const_string "mfc")
162 ;; These types of move are always single insns.
163 (eq_attr "move_type" "fmove") (const_string "fmove")
164 (eq_attr "move_type" "arith") (const_string "arith")
165 (eq_attr "move_type" "logical") (const_string "logical")
166 (eq_attr "move_type" "andi") (const_string "logical")
168 ;; These types of move are always split.
169 (eq_attr "move_type" "shift_shift")
170 (const_string "multi")
172 ;; These types of move are split for doubleword modes only.
173 (and (eq_attr "move_type" "move,const")
174 (eq_attr "dword_mode" "yes"))
175 (const_string "multi")
176 (eq_attr "move_type" "move") (const_string "move")
177 (eq_attr "move_type" "const") (const_string "const")]
178 (const_string "unknown")))
180 ;; Length of instruction in bytes.
181 (define_attr "length" ""
183 ;; Branches further than +/- 4 KiB require two instructions.
184 (eq_attr "type" "branch")
185 (if_then_else (and (le (minus (match_dup 0) (pc)) (const_int 4088))
186 (le (minus (pc) (match_dup 0)) (const_int 4092)))
190 ;; Conservatively assume calls take two instructions (AUIPC + JALR).
191 ;; The linker will opportunistically relax the sequence to JAL.
192 (eq_attr "type" "call") (const_int 8)
194 ;; "Ghost" instructions occupy no space.
195 (eq_attr "type" "ghost") (const_int 0)
197 (eq_attr "got" "load") (const_int 8)
199 (eq_attr "type" "fcmp") (const_int 8)
201 ;; SHIFT_SHIFTs are decomposed into two separate instructions.
202 (eq_attr "move_type" "shift_shift")
205 ;; Check for doubleword moves that are decomposed into two
207 (and (eq_attr "move_type" "mtc,mfc,move")
208 (eq_attr "dword_mode" "yes"))
211 ;; Doubleword CONST{,N} moves are split into two word
213 (and (eq_attr "move_type" "const")
214 (eq_attr "dword_mode" "yes"))
215 (symbol_ref "riscv_split_const_insns (operands[1]) * 4")
217 ;; Otherwise, constants, loads and stores are handled by external
219 (eq_attr "move_type" "load,fpload")
220 (symbol_ref "riscv_load_store_insns (operands[1], insn) * 4")
221 (eq_attr "move_type" "store,fpstore")
222 (symbol_ref "riscv_load_store_insns (operands[0], insn) * 4")
225 ;; Is copying of this instruction disallowed?
226 (define_attr "cannot_copy" "no,yes" (const_string "no"))
228 ;; Describe a user's asm statement.
229 (define_asm_attributes
230 [(set_attr "type" "multi")])
232 ;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
233 ;; from the same template.
234 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
236 ;; This mode iterator allows :P to be used for patterns that operate on
237 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
238 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
240 ;; Likewise, but for XLEN-sized quantities.
241 (define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")])
243 ;; Branches operate on XLEN-sized quantities, but for RV64 we accept
244 ;; QImode values so we can force zero-extension.
245 (define_mode_iterator BR [(QI "TARGET_64BIT") SI (DI "TARGET_64BIT")])
247 ;; 32-bit moves for which we provide move patterns.
248 (define_mode_iterator MOVE32 [SI])
250 ;; 64-bit modes for which we provide move patterns.
251 (define_mode_iterator MOVE64 [DI DF])
253 ;; Iterator for sub-32-bit integer modes.
254 (define_mode_iterator SHORT [QI HI])
256 ;; Iterator for HImode constant generation.
257 (define_mode_iterator HISI [HI SI])
259 ;; Iterator for QImode extension patterns.
260 (define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")])
262 ;; Iterator for extending loads.
263 (define_mode_iterator ZERO_EXTEND_LOAD [QI HI (SI "TARGET_64BIT")])
265 ;; Iterator for hardware integer modes narrower than XLEN.
266 (define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")])
268 ;; Iterator for hardware-supported integer modes.
269 (define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")])
271 ;; Iterator for hardware-supported floating-point modes.
272 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
273 (DF "TARGET_DOUBLE_FLOAT")])
275 ;; This attribute gives the length suffix for a sign- or zero-extension
277 (define_mode_attr size [(QI "b") (HI "h")])
279 ;; Mode attributes for loads.
280 (define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")])
282 ;; Instruction names for stores.
283 (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")])
285 ;; This attribute gives the best constraint to use for registers of
287 (define_mode_attr reg [(SI "d") (DI "d") (CC "d")])
289 ;; This attribute gives the format suffix for floating-point operations.
290 (define_mode_attr fmt [(SF "s") (DF "d")])
292 ;; This attribute gives the integer suffix for floating-point conversions.
293 (define_mode_attr ifmt [(SI "w") (DI "l")])
295 ;; This attribute gives the format suffix for atomic memory operations.
296 (define_mode_attr amo [(SI "w") (DI "d")])
298 ;; This attribute gives the upper-case mode name for one unit of a
299 ;; floating-point mode.
300 (define_mode_attr UNITMODE [(SF "SF") (DF "DF")])
302 ;; This attribute gives the integer mode that has half the size of
303 ;; the controlling mode.
304 (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
306 ;; Iterator and attributes for floating-point rounding instructions.
307 (define_int_iterator RINT [UNSPEC_LRINT UNSPEC_LROUND])
308 (define_int_attr rint_pattern [(UNSPEC_LRINT "rint") (UNSPEC_LROUND "round")])
309 (define_int_attr rint_rm [(UNSPEC_LRINT "dyn") (UNSPEC_LROUND "rmm")])
311 ;; Iterator and attributes for quiet comparisons.
312 (define_int_iterator QUIET_COMPARISON [UNSPEC_FLT_QUIET UNSPEC_FLE_QUIET])
313 (define_int_attr quiet_pattern [(UNSPEC_FLT_QUIET "lt") (UNSPEC_FLE_QUIET "le")])
315 ;; This code iterator allows signed and unsigned widening multiplications
316 ;; to use the same template.
317 (define_code_iterator any_extend [sign_extend zero_extend])
319 ;; This code iterator allows the two right shift instructions to be
320 ;; generated from the same template.
321 (define_code_iterator any_shiftrt [ashiftrt lshiftrt])
323 ;; This code iterator allows the three shift instructions to be generated
324 ;; from the same template.
325 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
327 ;; This code iterator allows the three bitwise instructions to be generated
328 ;; from the same template.
329 (define_code_iterator any_bitwise [and ior xor])
331 ;; This code iterator allows unsigned and signed division to be generated
332 ;; from the same template.
333 (define_code_iterator any_div [div udiv mod umod])
335 ;; This code iterator allows unsigned and signed modulus to be generated
336 ;; from the same template.
337 (define_code_iterator any_mod [mod umod])
339 ;; These code iterators allow the signed and unsigned scc operations to use
340 ;; the same template.
341 (define_code_iterator any_gt [gt gtu])
342 (define_code_iterator any_ge [ge geu])
343 (define_code_iterator any_lt [lt ltu])
344 (define_code_iterator any_le [le leu])
346 ;; <u> expands to an empty string when doing a signed operation and
347 ;; "u" when doing an unsigned operation.
348 (define_code_attr u [(sign_extend "") (zero_extend "u")
354 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
355 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
357 ;; <optab> expands to the name of the optab for a particular code.
358 (define_code_attr optab [(ashift "ashl")
375 ;; <insn> expands to the name of the insn that implements a particular code.
376 (define_code_attr insn [(ashift "sll")
389 ;; Ghost instructions produce no real code and introduce no hazards.
390 ;; They exist purely to express an effect on dataflow.
391 (define_insn_reservation "ghost" 0
392 (eq_attr "type" "ghost")
396 ;; ....................
400 ;; ....................
403 (define_insn "add<mode>3"
404 [(set (match_operand:ANYF 0 "register_operand" "=f")
405 (plus:ANYF (match_operand:ANYF 1 "register_operand" " f")
406 (match_operand:ANYF 2 "register_operand" " f")))]
408 "fadd.<fmt>\t%0,%1,%2"
409 [(set_attr "type" "fadd")
410 (set_attr "mode" "<UNITMODE>")])
412 (define_insn "addsi3"
413 [(set (match_operand:SI 0 "register_operand" "=r,r")
414 (plus:SI (match_operand:SI 1 "register_operand" " r,r")
415 (match_operand:SI 2 "arith_operand" " r,I")))]
417 { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
418 [(set_attr "type" "arith")
419 (set_attr "mode" "SI")])
421 (define_insn "adddi3"
422 [(set (match_operand:DI 0 "register_operand" "=r,r")
423 (plus:DI (match_operand:DI 1 "register_operand" " r,r")
424 (match_operand:DI 2 "arith_operand" " r,I")))]
427 [(set_attr "type" "arith")
428 (set_attr "mode" "DI")])
430 (define_insn "*addsi3_extended"
431 [(set (match_operand:DI 0 "register_operand" "=r,r")
433 (plus:SI (match_operand:SI 1 "register_operand" " r,r")
434 (match_operand:SI 2 "arith_operand" " r,I"))))]
437 [(set_attr "type" "arith")
438 (set_attr "mode" "SI")])
440 (define_insn "*addsi3_extended2"
441 [(set (match_operand:DI 0 "register_operand" "=r,r")
443 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" " r,r")
444 (match_operand:DI 2 "arith_operand" " r,I"))
448 [(set_attr "type" "arith")
449 (set_attr "mode" "SI")])
452 ;; ....................
456 ;; ....................
459 (define_insn "sub<mode>3"
460 [(set (match_operand:ANYF 0 "register_operand" "=f")
461 (minus:ANYF (match_operand:ANYF 1 "register_operand" " f")
462 (match_operand:ANYF 2 "register_operand" " f")))]
464 "fsub.<fmt>\t%0,%1,%2"
465 [(set_attr "type" "fadd")
466 (set_attr "mode" "<UNITMODE>")])
468 (define_insn "subdi3"
469 [(set (match_operand:DI 0 "register_operand" "= r")
470 (minus:DI (match_operand:DI 1 "reg_or_0_operand" " rJ")
471 (match_operand:DI 2 "register_operand" " r")))]
474 [(set_attr "type" "arith")
475 (set_attr "mode" "DI")])
477 (define_insn "subsi3"
478 [(set (match_operand:SI 0 "register_operand" "= r")
479 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
480 (match_operand:SI 2 "register_operand" " r")))]
482 { return TARGET_64BIT ? "subw\t%0,%z1,%2" : "sub\t%0,%z1,%2"; }
483 [(set_attr "type" "arith")
484 (set_attr "mode" "SI")])
486 (define_insn "*subsi3_extended"
487 [(set (match_operand:DI 0 "register_operand" "= r")
489 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
490 (match_operand:SI 2 "register_operand" " r"))))]
493 [(set_attr "type" "arith")
494 (set_attr "mode" "SI")])
496 (define_insn "*subsi3_extended2"
497 [(set (match_operand:DI 0 "register_operand" "=r")
499 (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" " r")
500 (match_operand:DI 2 "register_operand" " r"))
504 [(set_attr "type" "arith")
505 (set_attr "mode" "SI")])
508 ;; ....................
512 ;; ....................
515 (define_insn "mul<mode>3"
516 [(set (match_operand:ANYF 0 "register_operand" "=f")
517 (mult:ANYF (match_operand:ANYF 1 "register_operand" " f")
518 (match_operand:ANYF 2 "register_operand" " f")))]
520 "fmul.<fmt>\t%0,%1,%2"
521 [(set_attr "type" "fmul")
522 (set_attr "mode" "<UNITMODE>")])
524 (define_insn "mulsi3"
525 [(set (match_operand:SI 0 "register_operand" "=r")
526 (mult:SI (match_operand:SI 1 "register_operand" " r")
527 (match_operand:SI 2 "register_operand" " r")))]
529 { return TARGET_64BIT ? "mulw\t%0,%1,%2" : "mul\t%0,%1,%2"; }
530 [(set_attr "type" "imul")
531 (set_attr "mode" "SI")])
533 (define_insn "muldi3"
534 [(set (match_operand:DI 0 "register_operand" "=r")
535 (mult:DI (match_operand:DI 1 "register_operand" " r")
536 (match_operand:DI 2 "register_operand" " r")))]
537 "TARGET_MUL && TARGET_64BIT"
539 [(set_attr "type" "imul")
540 (set_attr "mode" "DI")])
542 (define_insn "*mulsi3_extended"
543 [(set (match_operand:DI 0 "register_operand" "=r")
545 (mult:SI (match_operand:SI 1 "register_operand" " r")
546 (match_operand:SI 2 "register_operand" " r"))))]
547 "TARGET_MUL && TARGET_64BIT"
549 [(set_attr "type" "imul")
550 (set_attr "mode" "SI")])
552 (define_insn "*mulsi3_extended2"
553 [(set (match_operand:DI 0 "register_operand" "=r")
555 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" " r")
556 (match_operand:DI 2 "register_operand" " r"))
558 "TARGET_MUL && TARGET_64BIT"
560 [(set_attr "type" "imul")
561 (set_attr "mode" "SI")])
564 ;; ........................
566 ;; MULTIPLICATION HIGH-PART
568 ;; ........................
572 (define_expand "<u>mulditi3"
573 [(set (match_operand:TI 0 "register_operand")
574 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
575 (any_extend:TI (match_operand:DI 2 "register_operand"))))]
576 "TARGET_MUL && TARGET_64BIT"
578 rtx low = gen_reg_rtx (DImode);
579 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
581 rtx high = gen_reg_rtx (DImode);
582 emit_insn (gen_<u>muldi3_highpart (high, operands[1], operands[2]));
584 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
585 emit_move_insn (gen_highpart (DImode, operands[0]), high);
589 (define_insn "<u>muldi3_highpart"
590 [(set (match_operand:DI 0 "register_operand" "=r")
593 (mult:TI (any_extend:TI
594 (match_operand:DI 1 "register_operand" " r"))
596 (match_operand:DI 2 "register_operand" " r")))
598 "TARGET_MUL && TARGET_64BIT"
600 [(set_attr "type" "imul")
601 (set_attr "mode" "DI")])
603 (define_expand "usmulditi3"
604 [(set (match_operand:TI 0 "register_operand")
605 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand"))
606 (sign_extend:TI (match_operand:DI 2 "register_operand"))))]
607 "TARGET_MUL && TARGET_64BIT"
609 rtx low = gen_reg_rtx (DImode);
610 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
612 rtx high = gen_reg_rtx (DImode);
613 emit_insn (gen_usmuldi3_highpart (high, operands[1], operands[2]));
615 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
616 emit_move_insn (gen_highpart (DImode, operands[0]), high);
620 (define_insn "usmuldi3_highpart"
621 [(set (match_operand:DI 0 "register_operand" "=r")
624 (mult:TI (zero_extend:TI
625 (match_operand:DI 1 "register_operand" "r"))
627 (match_operand:DI 2 "register_operand" " r")))
629 "TARGET_MUL && TARGET_64BIT"
631 [(set_attr "type" "imul")
632 (set_attr "mode" "DI")])
634 (define_expand "<u>mulsidi3"
635 [(set (match_operand:DI 0 "register_operand" "=r")
636 (mult:DI (any_extend:DI
637 (match_operand:SI 1 "register_operand" " r"))
639 (match_operand:SI 2 "register_operand" " r"))))]
640 "TARGET_MUL && !TARGET_64BIT"
642 rtx temp = gen_reg_rtx (SImode);
643 emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
644 emit_insn (gen_<u>mulsi3_highpart (riscv_subword (operands[0], true),
645 operands[1], operands[2]));
646 emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
650 (define_insn "<u>mulsi3_highpart"
651 [(set (match_operand:SI 0 "register_operand" "=r")
654 (mult:DI (any_extend:DI
655 (match_operand:SI 1 "register_operand" " r"))
657 (match_operand:SI 2 "register_operand" " r")))
659 "TARGET_MUL && !TARGET_64BIT"
661 [(set_attr "type" "imul")
662 (set_attr "mode" "SI")])
665 (define_expand "usmulsidi3"
666 [(set (match_operand:DI 0 "register_operand" "=r")
667 (mult:DI (zero_extend:DI
668 (match_operand:SI 1 "register_operand" " r"))
670 (match_operand:SI 2 "register_operand" " r"))))]
671 "TARGET_MUL && !TARGET_64BIT"
673 rtx temp = gen_reg_rtx (SImode);
674 emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
675 emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true),
676 operands[1], operands[2]));
677 emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
681 (define_insn "usmulsi3_highpart"
682 [(set (match_operand:SI 0 "register_operand" "=r")
685 (mult:DI (zero_extend:DI
686 (match_operand:SI 1 "register_operand" " r"))
688 (match_operand:SI 2 "register_operand" " r")))
690 "TARGET_MUL && !TARGET_64BIT"
692 [(set_attr "type" "imul")
693 (set_attr "mode" "SI")])
696 ;; ....................
698 ;; DIVISION and REMAINDER
700 ;; ....................
703 (define_insn "<optab>si3"
704 [(set (match_operand:SI 0 "register_operand" "=r")
705 (any_div:SI (match_operand:SI 1 "register_operand" " r")
706 (match_operand:SI 2 "register_operand" " r")))]
708 { return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2"; }
709 [(set_attr "type" "idiv")
710 (set_attr "mode" "SI")])
712 (define_insn "<optab>di3"
713 [(set (match_operand:DI 0 "register_operand" "=r")
714 (any_div:DI (match_operand:DI 1 "register_operand" " r")
715 (match_operand:DI 2 "register_operand" " r")))]
716 "TARGET_DIV && TARGET_64BIT"
717 "<insn>%i2\t%0,%1,%2"
718 [(set_attr "type" "idiv")
719 (set_attr "mode" "DI")])
721 (define_insn "*<optab>si3_extended"
722 [(set (match_operand:DI 0 "register_operand" "=r")
724 (any_div:SI (match_operand:SI 1 "register_operand" " r")
725 (match_operand:SI 2 "register_operand" " r"))))]
726 "TARGET_DIV && TARGET_64BIT"
727 "<insn>%i2w\t%0,%1,%2"
728 [(set_attr "type" "idiv")
729 (set_attr "mode" "DI")])
731 (define_insn "div<mode>3"
732 [(set (match_operand:ANYF 0 "register_operand" "=f")
733 (div:ANYF (match_operand:ANYF 1 "register_operand" " f")
734 (match_operand:ANYF 2 "register_operand" " f")))]
735 "TARGET_HARD_FLOAT && TARGET_FDIV"
736 "fdiv.<fmt>\t%0,%1,%2"
737 [(set_attr "type" "fdiv")
738 (set_attr "mode" "<UNITMODE>")])
741 ;; ....................
745 ;; ....................
747 (define_insn "sqrt<mode>2"
748 [(set (match_operand:ANYF 0 "register_operand" "=f")
749 (sqrt:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
750 "TARGET_HARD_FLOAT && TARGET_FDIV"
752 return "fsqrt.<fmt>\t%0,%1";
754 [(set_attr "type" "fsqrt")
755 (set_attr "mode" "<UNITMODE>")])
757 ;; Floating point multiply accumulate instructions.
760 (define_insn "fma<mode>4"
761 [(set (match_operand:ANYF 0 "register_operand" "=f")
762 (fma:ANYF (match_operand:ANYF 1 "register_operand" " f")
763 (match_operand:ANYF 2 "register_operand" " f")
764 (match_operand:ANYF 3 "register_operand" " f")))]
766 "fmadd.<fmt>\t%0,%1,%2,%3"
767 [(set_attr "type" "fmadd")
768 (set_attr "mode" "<UNITMODE>")])
771 (define_insn "fms<mode>4"
772 [(set (match_operand:ANYF 0 "register_operand" "=f")
773 (fma:ANYF (match_operand:ANYF 1 "register_operand" " f")
774 (match_operand:ANYF 2 "register_operand" " f")
775 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
777 "fmsub.<fmt>\t%0,%1,%2,%3"
778 [(set_attr "type" "fmadd")
779 (set_attr "mode" "<UNITMODE>")])
782 (define_insn "fnms<mode>4"
783 [(set (match_operand:ANYF 0 "register_operand" "=f")
785 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
786 (match_operand:ANYF 2 "register_operand" " f")
787 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
789 "fnmadd.<fmt>\t%0,%1,%2,%3"
790 [(set_attr "type" "fmadd")
791 (set_attr "mode" "<UNITMODE>")])
794 (define_insn "fnma<mode>4"
795 [(set (match_operand:ANYF 0 "register_operand" "=f")
797 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
798 (match_operand:ANYF 2 "register_operand" " f")
799 (match_operand:ANYF 3 "register_operand" " f")))]
801 "fnmsub.<fmt>\t%0,%1,%2,%3"
802 [(set_attr "type" "fmadd")
803 (set_attr "mode" "<UNITMODE>")])
805 ;; -(-a * b - c), modulo signed zeros
806 (define_insn "*fma<mode>4"
807 [(set (match_operand:ANYF 0 "register_operand" "=f")
810 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
811 (match_operand:ANYF 2 "register_operand" " f")
812 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
813 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
814 "fmadd.<fmt>\t%0,%1,%2,%3"
815 [(set_attr "type" "fmadd")
816 (set_attr "mode" "<UNITMODE>")])
818 ;; -(-a * b + c), modulo signed zeros
819 (define_insn "*fms<mode>4"
820 [(set (match_operand:ANYF 0 "register_operand" "=f")
823 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
824 (match_operand:ANYF 2 "register_operand" " f")
825 (match_operand:ANYF 3 "register_operand" " f"))))]
826 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
827 "fmsub.<fmt>\t%0,%1,%2,%3"
828 [(set_attr "type" "fmadd")
829 (set_attr "mode" "<UNITMODE>")])
831 ;; -(a * b + c), modulo signed zeros
832 (define_insn "*fnms<mode>4"
833 [(set (match_operand:ANYF 0 "register_operand" "=f")
836 (match_operand:ANYF 1 "register_operand" " f")
837 (match_operand:ANYF 2 "register_operand" " f")
838 (match_operand:ANYF 3 "register_operand" " f"))))]
839 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
840 "fnmadd.<fmt>\t%0,%1,%2,%3"
841 [(set_attr "type" "fmadd")
842 (set_attr "mode" "<UNITMODE>")])
844 ;; -(a * b - c), modulo signed zeros
845 (define_insn "*fnma<mode>4"
846 [(set (match_operand:ANYF 0 "register_operand" "=f")
849 (match_operand:ANYF 1 "register_operand" " f")
850 (match_operand:ANYF 2 "register_operand" " f")
851 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
852 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
853 "fnmsub.<fmt>\t%0,%1,%2,%3"
854 [(set_attr "type" "fmadd")
855 (set_attr "mode" "<UNITMODE>")])
858 ;; ....................
862 ;; ....................
864 (define_insn "abs<mode>2"
865 [(set (match_operand:ANYF 0 "register_operand" "=f")
866 (abs:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
869 [(set_attr "type" "fmove")
870 (set_attr "mode" "<UNITMODE>")])
872 (define_insn "copysign<mode>3"
873 [(set (match_operand:ANYF 0 "register_operand" "=f")
874 (unspec:ANYF [(match_operand:ANYF 1 "register_operand" " f")
875 (match_operand:ANYF 2 "register_operand" " f")]
878 "fsgnj.<fmt>\t%0,%1,%2"
879 [(set_attr "type" "fmove")
880 (set_attr "mode" "<UNITMODE>")])
882 (define_insn "neg<mode>2"
883 [(set (match_operand:ANYF 0 "register_operand" "=f")
884 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
887 [(set_attr "type" "fmove")
888 (set_attr "mode" "<UNITMODE>")])
891 ;; ....................
895 ;; ....................
897 (define_insn "smin<mode>3"
898 [(set (match_operand:ANYF 0 "register_operand" "=f")
899 (smin:ANYF (match_operand:ANYF 1 "register_operand" " f")
900 (match_operand:ANYF 2 "register_operand" " f")))]
902 "fmin.<fmt>\t%0,%1,%2"
903 [(set_attr "type" "fmove")
904 (set_attr "mode" "<UNITMODE>")])
906 (define_insn "smax<mode>3"
907 [(set (match_operand:ANYF 0 "register_operand" "=f")
908 (smax:ANYF (match_operand:ANYF 1 "register_operand" " f")
909 (match_operand:ANYF 2 "register_operand" " f")))]
911 "fmax.<fmt>\t%0,%1,%2"
912 [(set_attr "type" "fmove")
913 (set_attr "mode" "<UNITMODE>")])
916 ;; ....................
920 ;; ....................
923 ;; For RV64, we don't expose the SImode operations to the rtl expanders,
924 ;; but SImode versions exist for combine.
926 (define_insn "<optab><mode>3"
927 [(set (match_operand:X 0 "register_operand" "=r,r")
928 (any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
929 (match_operand:X 2 "arith_operand" " r,I")))]
931 "<insn>%i2\t%0,%1,%2"
932 [(set_attr "type" "logical")
933 (set_attr "mode" "<MODE>")])
935 (define_insn "*<optab>si3_internal"
936 [(set (match_operand:SI 0 "register_operand" "=r,r")
937 (any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r")
938 (match_operand:SI 2 "arith_operand" " r,I")))]
940 "<insn>%i2\t%0,%1,%2"
941 [(set_attr "type" "logical")
942 (set_attr "mode" "SI")])
944 (define_insn "one_cmpl<mode>2"
945 [(set (match_operand:X 0 "register_operand" "=r")
946 (not:X (match_operand:X 1 "register_operand" " r")))]
949 [(set_attr "type" "logical")
950 (set_attr "mode" "<MODE>")])
952 (define_insn "*one_cmplsi2_internal"
953 [(set (match_operand:SI 0 "register_operand" "=r")
954 (not:SI (match_operand:SI 1 "register_operand" " r")))]
957 [(set_attr "type" "logical")
958 (set_attr "mode" "SI")])
961 ;; ....................
965 ;; ....................
967 (define_insn "truncdfsf2"
968 [(set (match_operand:SF 0 "register_operand" "=f")
970 (match_operand:DF 1 "register_operand" " f")))]
971 "TARGET_DOUBLE_FLOAT"
973 [(set_attr "type" "fcvt")
974 (set_attr "mode" "SF")])
977 ;; ....................
981 ;; ....................
985 (define_insn_and_split "zero_extendsidi2"
986 [(set (match_operand:DI 0 "register_operand" "=r,r")
988 (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
993 "&& reload_completed && REG_P (operands[1])"
995 (ashift:DI (match_dup 1) (const_int 32)))
997 (lshiftrt:DI (match_dup 0) (const_int 32)))]
998 { operands[1] = gen_lowpart (DImode, operands[1]); }
999 [(set_attr "move_type" "shift_shift,load")
1000 (set_attr "mode" "DI")])
1002 (define_insn_and_split "zero_extendhi<GPR:mode>2"
1003 [(set (match_operand:GPR 0 "register_operand" "=r,r")
1005 (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
1010 "&& reload_completed && REG_P (operands[1])"
1012 (ashift:GPR (match_dup 1) (match_dup 2)))
1014 (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
1016 operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
1017 operands[2] = GEN_INT(GET_MODE_BITSIZE(<GPR:MODE>mode) - 16);
1019 [(set_attr "move_type" "shift_shift,load")
1020 (set_attr "mode" "<GPR:MODE>")])
1022 (define_insn "zero_extendqi<SUPERQI:mode>2"
1023 [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
1024 (zero_extend:SUPERQI
1025 (match_operand:QI 1 "nonimmediate_operand" " r,m")))]
1030 [(set_attr "move_type" "andi,load")
1031 (set_attr "mode" "<SUPERQI:MODE>")])
1034 ;; ....................
1038 ;; ....................
1040 (define_insn "extendsidi2"
1041 [(set (match_operand:DI 0 "register_operand" "=r,r")
1043 (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
1048 [(set_attr "move_type" "move,load")
1049 (set_attr "mode" "DI")])
1051 (define_insn_and_split "extend<SHORT:mode><SUPERQI:mode>2"
1052 [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
1053 (sign_extend:SUPERQI
1054 (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
1058 l<SHORT:size>\t%0,%1"
1059 "&& reload_completed && REG_P (operands[1])"
1060 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1061 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
1063 operands[0] = gen_lowpart (SImode, operands[0]);
1064 operands[1] = gen_lowpart (SImode, operands[1]);
1065 operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
1066 - GET_MODE_BITSIZE (<SHORT:MODE>mode));
1068 [(set_attr "move_type" "shift_shift,load")
1069 (set_attr "mode" "SI")])
1071 (define_insn "extendsfdf2"
1072 [(set (match_operand:DF 0 "register_operand" "=f")
1074 (match_operand:SF 1 "register_operand" " f")))]
1075 "TARGET_DOUBLE_FLOAT"
1077 [(set_attr "type" "fcvt")
1078 (set_attr "mode" "DF")])
1081 ;; ....................
1085 ;; ....................
1087 (define_insn "fix_trunc<ANYF:mode><GPR:mode>2"
1088 [(set (match_operand:GPR 0 "register_operand" "=r")
1090 (match_operand:ANYF 1 "register_operand" " f")))]
1092 "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,rtz"
1093 [(set_attr "type" "fcvt")
1094 (set_attr "mode" "<ANYF:MODE>")])
1096 (define_insn "fixuns_trunc<ANYF:mode><GPR:mode>2"
1097 [(set (match_operand:GPR 0 "register_operand" "=r")
1099 (match_operand:ANYF 1 "register_operand" " f")))]
1101 "fcvt.<GPR:ifmt>u.<ANYF:fmt> %0,%1,rtz"
1102 [(set_attr "type" "fcvt")
1103 (set_attr "mode" "<ANYF:MODE>")])
1105 (define_insn "float<GPR:mode><ANYF:mode>2"
1106 [(set (match_operand:ANYF 0 "register_operand" "= f")
1108 (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1110 "fcvt.<ANYF:fmt>.<GPR:ifmt>\t%0,%z1"
1111 [(set_attr "type" "fcvt")
1112 (set_attr "mode" "<ANYF:MODE>")])
1114 (define_insn "floatuns<GPR:mode><ANYF:mode>2"
1115 [(set (match_operand:ANYF 0 "register_operand" "= f")
1116 (unsigned_float:ANYF
1117 (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1119 "fcvt.<ANYF:fmt>.<GPR:ifmt>u\t%0,%z1"
1120 [(set_attr "type" "fcvt")
1121 (set_attr "mode" "<ANYF:MODE>")])
1123 (define_insn "l<rint_pattern><ANYF:mode><GPR:mode>2"
1124 [(set (match_operand:GPR 0 "register_operand" "=r")
1126 [(match_operand:ANYF 1 "register_operand" " f")]
1129 "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,<rint_rm>"
1130 [(set_attr "type" "fcvt")
1131 (set_attr "mode" "<ANYF:MODE>")])
1134 ;; ....................
1138 ;; ....................
1140 ;; Lower-level instructions for loading an address from the GOT.
1141 ;; We could use MEMs, but an unspec gives more optimization
1144 (define_insn "got_load<mode>"
1145 [(set (match_operand:P 0 "register_operand" "=r")
1147 [(match_operand:P 1 "symbolic_operand" "")]
1151 [(set_attr "got" "load")
1152 (set_attr "mode" "<MODE>")])
1154 (define_insn "tls_add_tp_le<mode>"
1155 [(set (match_operand:P 0 "register_operand" "=r")
1157 [(match_operand:P 1 "register_operand" "r")
1158 (match_operand:P 2 "register_operand" "r")
1159 (match_operand:P 3 "symbolic_operand" "")]
1162 "add\t%0,%1,%2,%%tprel_add(%3)"
1163 [(set_attr "type" "arith")
1164 (set_attr "mode" "<MODE>")])
1166 (define_insn "got_load_tls_gd<mode>"
1167 [(set (match_operand:P 0 "register_operand" "=r")
1169 [(match_operand:P 1 "symbolic_operand" "")]
1173 [(set_attr "got" "load")
1174 (set_attr "mode" "<MODE>")])
1176 (define_insn "got_load_tls_ie<mode>"
1177 [(set (match_operand:P 0 "register_operand" "=r")
1179 [(match_operand:P 1 "symbolic_operand" "")]
1183 [(set_attr "got" "load")
1184 (set_attr "mode" "<MODE>")])
1186 (define_insn "auipc<mode>"
1187 [(set (match_operand:P 0 "register_operand" "=r")
1189 [(match_operand:P 1 "symbolic_operand" "")
1190 (match_operand:P 2 "const_int_operand")
1194 ".LA%2: auipc\t%0,%h1"
1195 [(set_attr "type" "arith")
1196 (set_attr "cannot_copy" "yes")])
1198 ;; Instructions for adding the low 12 bits of an address to a register.
1199 ;; Operand 2 is the address: riscv_print_operand works out which relocation
1200 ;; should be applied.
1202 (define_insn "*low<mode>"
1203 [(set (match_operand:P 0 "register_operand" "=r")
1204 (lo_sum:P (match_operand:P 1 "register_operand" " r")
1205 (match_operand:P 2 "symbolic_operand" "")))]
1208 [(set_attr "type" "arith")
1209 (set_attr "mode" "<MODE>")])
1211 ;; Allow combine to split complex const_int load sequences, using operand 2
1212 ;; to store the intermediate results. See move_operand for details.
1214 [(set (match_operand:GPR 0 "register_operand")
1215 (match_operand:GPR 1 "splittable_const_int_operand"))
1216 (clobber (match_operand:GPR 2 "register_operand"))]
1220 riscv_move_integer (operands[2], operands[0], INTVAL (operands[1]));
1224 ;; Likewise, for symbolic operands.
1226 [(set (match_operand:P 0 "register_operand")
1227 (match_operand:P 1))
1228 (clobber (match_operand:P 2 "register_operand"))]
1229 "riscv_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
1230 [(set (match_dup 0) (match_dup 3))]
1232 riscv_split_symbol (operands[2], operands[1],
1233 MAX_MACHINE_MODE, &operands[3]);
1236 ;; 64-bit integer moves
1238 (define_expand "movdi"
1239 [(set (match_operand:DI 0 "")
1240 (match_operand:DI 1 ""))]
1243 if (riscv_legitimize_move (DImode, operands[0], operands[1]))
1247 (define_insn "*movdi_32bit"
1248 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m, *f,*f,*r,*f,*m")
1249 (match_operand:DI 1 "move_operand" " r,i,m,r,*J*r,*m,*f,*f,*f"))]
1251 && (register_operand (operands[0], DImode)
1252 || reg_or_0_operand (operands[1], DImode))"
1253 { return riscv_output_move (operands[0], operands[1]); }
1254 [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1255 (set_attr "mode" "DI")])
1257 (define_insn "*movdi_64bit"
1258 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, *f,*f,*r,*f,*m")
1259 (match_operand:DI 1 "move_operand" " r,T,m,rJ,*r*J,*m,*f,*f,*f"))]
1261 && (register_operand (operands[0], DImode)
1262 || reg_or_0_operand (operands[1], DImode))"
1263 { return riscv_output_move (operands[0], operands[1]); }
1264 [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1265 (set_attr "mode" "DI")])
1267 ;; 32-bit Integer moves
1269 (define_expand "mov<mode>"
1270 [(set (match_operand:MOVE32 0 "")
1271 (match_operand:MOVE32 1 ""))]
1274 if (riscv_legitimize_move (<MODE>mode, operands[0], operands[1]))
1278 (define_insn "*movsi_internal"
1279 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, *f,*f,*r,*m")
1280 (match_operand:SI 1 "move_operand" " r,T,m,rJ,*r*J,*m,*f,*f"))]
1281 "(register_operand (operands[0], SImode)
1282 || reg_or_0_operand (operands[1], SImode))"
1283 { return riscv_output_move (operands[0], operands[1]); }
1284 [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore")
1285 (set_attr "mode" "SI")])
1287 ;; 16-bit Integer moves
1289 ;; Unlike most other insns, the move insns can't be split with
1290 ;; different predicates, because register spilling and other parts of
1291 ;; the compiler, have memoized the insn number already.
1292 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
1294 (define_expand "movhi"
1295 [(set (match_operand:HI 0 "")
1296 (match_operand:HI 1 ""))]
1299 if (riscv_legitimize_move (HImode, operands[0], operands[1]))
1303 (define_insn "*movhi_internal"
1304 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r, m, *f,*r")
1305 (match_operand:HI 1 "move_operand" " r,T,m,rJ,*r*J,*f"))]
1306 "(register_operand (operands[0], HImode)
1307 || reg_or_0_operand (operands[1], HImode))"
1308 { return riscv_output_move (operands[0], operands[1]); }
1309 [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1310 (set_attr "mode" "HI")])
1312 ;; HImode constant generation; see riscv_move_integer for details.
1313 ;; si+si->hi without truncation is legal because of
1314 ;; TARGET_TRULY_NOOP_TRUNCATION.
1316 (define_insn "*add<mode>hi3"
1317 [(set (match_operand:HI 0 "register_operand" "=r,r")
1318 (plus:HI (match_operand:HISI 1 "register_operand" " r,r")
1319 (match_operand:HISI 2 "arith_operand" " r,I")))]
1321 { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
1322 [(set_attr "type" "arith")
1323 (set_attr "mode" "HI")])
1325 (define_insn "*xor<mode>hi3"
1326 [(set (match_operand:HI 0 "register_operand" "=r,r")
1327 (xor:HI (match_operand:HISI 1 "register_operand" " r,r")
1328 (match_operand:HISI 2 "arith_operand" " r,I")))]
1331 [(set_attr "type" "logical")
1332 (set_attr "mode" "HI")])
1334 ;; 8-bit Integer moves
1336 (define_expand "movqi"
1337 [(set (match_operand:QI 0 "")
1338 (match_operand:QI 1 ""))]
1341 if (riscv_legitimize_move (QImode, operands[0], operands[1]))
1345 (define_insn "*movqi_internal"
1346 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r, m, *f,*r")
1347 (match_operand:QI 1 "move_operand" " r,I,m,rJ,*r*J,*f"))]
1348 "(register_operand (operands[0], QImode)
1349 || reg_or_0_operand (operands[1], QImode))"
1350 { return riscv_output_move (operands[0], operands[1]); }
1351 [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1352 (set_attr "mode" "QI")])
1354 ;; 32-bit floating point moves
1356 (define_expand "movsf"
1357 [(set (match_operand:SF 0 "")
1358 (match_operand:SF 1 ""))]
1361 if (riscv_legitimize_move (SFmode, operands[0], operands[1]))
1365 (define_insn "*movsf_hardfloat"
1366 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r, *r,*r,*m")
1367 (match_operand:SF 1 "move_operand" " f,G,m,f,G,*r,*f,*G*r,*m,*r"))]
1369 && (register_operand (operands[0], SFmode)
1370 || reg_or_0_operand (operands[1], SFmode))"
1371 { return riscv_output_move (operands[0], operands[1]); }
1372 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1373 (set_attr "mode" "SF")])
1375 (define_insn "*movsf_softfloat"
1376 [(set (match_operand:SF 0 "nonimmediate_operand" "= r,r,m")
1377 (match_operand:SF 1 "move_operand" " Gr,m,r"))]
1379 && (register_operand (operands[0], SFmode)
1380 || reg_or_0_operand (operands[1], SFmode))"
1381 { return riscv_output_move (operands[0], operands[1]); }
1382 [(set_attr "move_type" "move,load,store")
1383 (set_attr "mode" "SF")])
1385 ;; 64-bit floating point moves
1387 (define_expand "movdf"
1388 [(set (match_operand:DF 0 "")
1389 (match_operand:DF 1 ""))]
1392 if (riscv_legitimize_move (DFmode, operands[0], operands[1]))
1396 ;; In RV32, we lack fmv.x.d and fmv.d.x. Go through memory instead.
1397 ;; (However, we can still use fcvt.d.w to zero a floating-point register.)
1398 (define_insn "*movdf_hardfloat_rv32"
1399 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m, *r,*r,*m")
1400 (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r*G,*m,*r"))]
1401 "!TARGET_64BIT && TARGET_DOUBLE_FLOAT
1402 && (register_operand (operands[0], DFmode)
1403 || reg_or_0_operand (operands[1], DFmode))"
1404 { return riscv_output_move (operands[0], operands[1]); }
1405 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,move,load,store")
1406 (set_attr "mode" "DF")])
1408 (define_insn "*movdf_hardfloat_rv64"
1409 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r, *r,*r,*m")
1410 (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r,*f,*r*G,*m,*r"))]
1411 "TARGET_64BIT && TARGET_DOUBLE_FLOAT
1412 && (register_operand (operands[0], DFmode)
1413 || reg_or_0_operand (operands[1], DFmode))"
1414 { return riscv_output_move (operands[0], operands[1]); }
1415 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1416 (set_attr "mode" "DF")])
1418 (define_insn "*movdf_softfloat"
1419 [(set (match_operand:DF 0 "nonimmediate_operand" "= r,r, m")
1420 (match_operand:DF 1 "move_operand" " rG,m,rG"))]
1421 "!TARGET_DOUBLE_FLOAT
1422 && (register_operand (operands[0], DFmode)
1423 || reg_or_0_operand (operands[1], DFmode))"
1424 { return riscv_output_move (operands[0], operands[1]); }
1425 [(set_attr "move_type" "move,load,store")
1426 (set_attr "mode" "DF")])
1429 [(set (match_operand:MOVE64 0 "nonimmediate_operand")
1430 (match_operand:MOVE64 1 "move_operand"))]
1432 && riscv_split_64bit_move_p (operands[0], operands[1])"
1435 riscv_split_doubleword_move (operands[0], operands[1]);
1439 (define_expand "movmemsi"
1440 [(parallel [(set (match_operand:BLK 0 "general_operand")
1441 (match_operand:BLK 1 "general_operand"))
1442 (use (match_operand:SI 2 ""))
1443 (use (match_operand:SI 3 "const_int_operand"))])]
1446 if (riscv_expand_block_move (operands[0], operands[1], operands[2]))
1452 ;; Expand in-line code to clear the instruction cache between operand[0] and
1454 (define_expand "clear_cache"
1455 [(match_operand 0 "pmode_register_operand")
1456 (match_operand 1 "pmode_register_operand")]
1459 #ifdef ICACHE_FLUSH_FUNC
1460 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, ICACHE_FLUSH_FUNC),
1461 LCT_NORMAL, VOIDmode, operands[0], Pmode,
1462 operands[1], Pmode, const0_rtx, Pmode);
1464 emit_insn (gen_fence_i ());
1469 (define_insn "fence"
1470 [(unspec_volatile [(const_int 0)] UNSPECV_FENCE)]
1474 (define_insn "fence_i"
1475 [(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)]
1480 ;; ....................
1484 ;; ....................
1486 ;; Use a QImode shift count, to avoid generating sign or zero extend
1487 ;; instructions for shift counts, and to avoid dropping subregs.
1488 ;; expand_shift_1 can do this automatically when SHIFT_COUNT_TRUNCATED is
1489 ;; defined, but use of that is discouraged.
1491 (define_insn "<optab>si3"
1492 [(set (match_operand:SI 0 "register_operand" "= r")
1494 (match_operand:SI 1 "register_operand" " r")
1495 (match_operand:QI 2 "arith_operand" " rI")))]
1498 if (GET_CODE (operands[2]) == CONST_INT)
1499 operands[2] = GEN_INT (INTVAL (operands[2])
1500 & (GET_MODE_BITSIZE (SImode) - 1));
1502 return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2";
1504 [(set_attr "type" "shift")
1505 (set_attr "mode" "SI")])
1507 (define_insn_and_split "<optab>si3_mask"
1508 [(set (match_operand:SI 0 "register_operand" "= r")
1510 (match_operand:SI 1 "register_operand" " r")
1513 (match_operand:SI 2 "register_operand" "r")
1514 (match_operand 3 "const_int_operand")) 0)))]
1515 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1516 == GET_MODE_BITSIZE (SImode)-1"
1520 (any_shift:SI (match_dup 1)
1522 "operands[2] = gen_lowpart (QImode, operands[2]);"
1523 [(set_attr "type" "shift")
1524 (set_attr "mode" "SI")])
1526 (define_insn_and_split "<optab>si3_mask_1"
1527 [(set (match_operand:SI 0 "register_operand" "= r")
1529 (match_operand:SI 1 "register_operand" " r")
1532 (match_operand:DI 2 "register_operand" "r")
1533 (match_operand 3 "const_int_operand")) 0)))]
1535 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1536 == GET_MODE_BITSIZE (SImode)-1"
1540 (any_shift:SI (match_dup 1)
1542 "operands[2] = gen_lowpart (QImode, operands[2]);"
1543 [(set_attr "type" "shift")
1544 (set_attr "mode" "SI")])
1546 (define_insn "<optab>di3"
1547 [(set (match_operand:DI 0 "register_operand" "= r")
1549 (match_operand:DI 1 "register_operand" " r")
1550 (match_operand:QI 2 "arith_operand" " rI")))]
1553 if (GET_CODE (operands[2]) == CONST_INT)
1554 operands[2] = GEN_INT (INTVAL (operands[2])
1555 & (GET_MODE_BITSIZE (DImode) - 1));
1557 return "<insn>%i2\t%0,%1,%2";
1559 [(set_attr "type" "shift")
1560 (set_attr "mode" "DI")])
1562 (define_insn_and_split "<optab>di3_mask"
1563 [(set (match_operand:DI 0 "register_operand" "= r")
1565 (match_operand:DI 1 "register_operand" " r")
1568 (match_operand:SI 2 "register_operand" "r")
1569 (match_operand 3 "const_int_operand")) 0)))]
1571 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1572 == GET_MODE_BITSIZE (DImode)-1"
1576 (any_shift:DI (match_dup 1)
1578 "operands[2] = gen_lowpart (QImode, operands[2]);"
1579 [(set_attr "type" "shift")
1580 (set_attr "mode" "DI")])
1582 (define_insn_and_split "<optab>di3_mask_1"
1583 [(set (match_operand:DI 0 "register_operand" "= r")
1585 (match_operand:DI 1 "register_operand" " r")
1588 (match_operand:DI 2 "register_operand" "r")
1589 (match_operand 3 "const_int_operand")) 0)))]
1591 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1592 == GET_MODE_BITSIZE (DImode)-1"
1596 (any_shift:DI (match_dup 1)
1598 "operands[2] = gen_lowpart (QImode, operands[2]);"
1599 [(set_attr "type" "shift")
1600 (set_attr "mode" "DI")])
1602 (define_insn "*<optab>si3_extend"
1603 [(set (match_operand:DI 0 "register_operand" "= r")
1605 (any_shift:SI (match_operand:SI 1 "register_operand" " r")
1606 (match_operand:QI 2 "arith_operand" " rI"))))]
1609 if (GET_CODE (operands[2]) == CONST_INT)
1610 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1612 return "<insn>%i2w\t%0,%1,%2";
1614 [(set_attr "type" "shift")
1615 (set_attr "mode" "SI")])
1617 (define_insn_and_split "*<optab>si3_extend_mask"
1618 [(set (match_operand:DI 0 "register_operand" "= r")
1621 (match_operand:SI 1 "register_operand" " r")
1624 (match_operand:SI 2 "register_operand" " r")
1625 (match_operand 3 "const_int_operand")) 0))))]
1627 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1628 == GET_MODE_BITSIZE (SImode)-1"
1633 (any_shift:SI (match_dup 1)
1635 "operands[2] = gen_lowpart (QImode, operands[2]);"
1636 [(set_attr "type" "shift")
1637 (set_attr "mode" "SI")])
1639 (define_insn_and_split "*<optab>si3_extend_mask_1"
1640 [(set (match_operand:DI 0 "register_operand" "= r")
1643 (match_operand:SI 1 "register_operand" " r")
1646 (match_operand:DI 2 "register_operand" " r")
1647 (match_operand 3 "const_int_operand")) 0))))]
1649 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1650 == GET_MODE_BITSIZE (SImode)-1"
1655 (any_shift:SI (match_dup 1)
1657 "operands[2] = gen_lowpart (QImode, operands[2]);"
1658 [(set_attr "type" "shift")
1659 (set_attr "mode" "SI")])
1661 ;; Non-canonical, but can be formed by ree when combine is not successful at
1662 ;; producing one of the two canonical patterns below.
1663 (define_insn "*lshrsi3_zero_extend_1"
1664 [(set (match_operand:DI 0 "register_operand" "=r")
1666 (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
1667 (match_operand 2 "const_int_operand"))))]
1668 "TARGET_64BIT && (INTVAL (operands[2]) & 0x1f) > 0"
1670 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1672 return "srliw\t%0,%1,%2";
1674 [(set_attr "type" "shift")
1675 (set_attr "mode" "SI")])
1677 ;; Canonical form for a zero-extend of a logical right shift.
1678 (define_insn "*lshrsi3_zero_extend_2"
1679 [(set (match_operand:DI 0 "register_operand" "=r")
1680 (zero_extract:DI (match_operand:DI 1 "register_operand" " r")
1681 (match_operand 2 "const_int_operand")
1682 (match_operand 3 "const_int_operand")))]
1683 "(TARGET_64BIT && (INTVAL (operands[3]) > 0)
1684 && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))"
1686 return "srliw\t%0,%1,%3";
1688 [(set_attr "type" "shift")
1689 (set_attr "mode" "SI")])
1691 ;; Canonical form for a zero-extend of a logical right shift when the
1692 ;; shift count is 31.
1693 (define_insn "*lshrsi3_zero_extend_3"
1694 [(set (match_operand:DI 0 "register_operand" "=r")
1695 (lt:DI (match_operand:SI 1 "register_operand" " r")
1699 return "srliw\t%0,%1,31";
1701 [(set_attr "type" "shift")
1702 (set_attr "mode" "SI")])
1705 ;; ....................
1707 ;; CONDITIONAL BRANCHES
1709 ;; ....................
1711 ;; Conditional branches
1713 (define_insn "*branch_order<mode>"
1716 (match_operator 1 "order_operator"
1717 [(match_operand:X 2 "register_operand" "r")
1718 (match_operand:X 3 "register_operand" "r")])
1719 (label_ref (match_operand 0 "" ""))
1723 [(set_attr "type" "branch")
1724 (set_attr "mode" "none")])
1726 (define_insn "*branch_zero<mode>"
1729 (match_operator 1 "signed_order_operator"
1730 [(match_operand:X 2 "register_operand" "r")
1732 (label_ref (match_operand 0 "" ""))
1736 [(set_attr "type" "branch")
1737 (set_attr "mode" "none")])
1739 ;; Used to implement built-in functions.
1740 (define_expand "condjump"
1742 (if_then_else (match_operand 0)
1743 (label_ref (match_operand 1))
1746 (define_expand "cbranch<mode>4"
1748 (if_then_else (match_operator 0 "comparison_operator"
1749 [(match_operand:BR 1 "register_operand")
1750 (match_operand:BR 2 "nonmemory_operand")])
1751 (label_ref (match_operand 3 ""))
1755 riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1756 operands[1], operands[2]);
1760 (define_expand "cbranch<mode>4"
1762 (if_then_else (match_operator 0 "fp_branch_comparison"
1763 [(match_operand:ANYF 1 "register_operand")
1764 (match_operand:ANYF 2 "register_operand")])
1765 (label_ref (match_operand 3 ""))
1769 riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1770 operands[1], operands[2]);
1774 (define_insn_and_split "*branch_on_bit<X:mode>"
1777 (match_operator 0 "equality_operator"
1778 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1780 (match_operand 3 "branch_on_bit_operand"))
1782 (label_ref (match_operand 1))
1784 (clobber (match_scratch:X 4 "=&r"))]
1789 (ashift:X (match_dup 2) (match_dup 3)))
1792 (match_op_dup 0 [(match_dup 4) (const_int 0)])
1793 (label_ref (match_operand 1))
1796 int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]);
1797 operands[3] = GEN_INT (shift);
1799 if (GET_CODE (operands[0]) == EQ)
1800 operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx);
1802 operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx);
1805 (define_insn_and_split "*branch_on_bit_range<X:mode>"
1808 (match_operator 0 "equality_operator"
1809 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1810 (match_operand 3 "branch_on_bit_operand")
1813 (label_ref (match_operand 1))
1815 (clobber (match_scratch:X 4 "=&r"))]
1820 (ashift:X (match_dup 2) (match_dup 3)))
1823 (match_op_dup 0 [(match_dup 4) (const_int 0)])
1824 (label_ref (match_operand 1))
1827 operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]));
1831 ;; ....................
1833 ;; SETTING A REGISTER FROM A COMPARISON
1835 ;; ....................
1837 ;; Destination is always set in SI mode.
1839 (define_expand "cstore<mode>4"
1840 [(set (match_operand:SI 0 "register_operand")
1841 (match_operator:SI 1 "order_operator"
1842 [(match_operand:GPR 2 "register_operand")
1843 (match_operand:GPR 3 "nonmemory_operand")]))]
1846 riscv_expand_int_scc (operands[0], GET_CODE (operands[1]), operands[2],
1851 (define_expand "cstore<mode>4"
1852 [(set (match_operand:SI 0 "register_operand")
1853 (match_operator:SI 1 "fp_scc_comparison"
1854 [(match_operand:ANYF 2 "register_operand")
1855 (match_operand:ANYF 3 "register_operand")]))]
1858 riscv_expand_float_scc (operands[0], GET_CODE (operands[1]), operands[2],
1863 (define_insn "*cstore<ANYF:mode><X:mode>4"
1864 [(set (match_operand:X 0 "register_operand" "=r")
1865 (match_operator:X 1 "fp_native_comparison"
1866 [(match_operand:ANYF 2 "register_operand" " f")
1867 (match_operand:ANYF 3 "register_operand" " f")]))]
1869 "f%C1.<fmt>\t%0,%2,%3"
1870 [(set_attr "type" "fcmp")
1871 (set_attr "mode" "<UNITMODE>")])
1873 (define_insn "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4"
1874 [(set (match_operand:X 0 "register_operand" "=r")
1876 [(match_operand:ANYF 1 "register_operand" " f")
1877 (match_operand:ANYF 2 "register_operand" " f")]
1879 (clobber (match_scratch:X 3 "=&r"))]
1881 "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3"
1882 [(set_attr "type" "fcmp")
1883 (set_attr "mode" "<UNITMODE>")
1884 (set (attr "length") (const_int 12))])
1886 (define_insn "*seq_zero_<X:mode><GPR:mode>"
1887 [(set (match_operand:GPR 0 "register_operand" "=r")
1888 (eq:GPR (match_operand:X 1 "register_operand" " r")
1892 [(set_attr "type" "slt")
1893 (set_attr "mode" "<X:MODE>")])
1895 (define_insn "*sne_zero_<X:mode><GPR:mode>"
1896 [(set (match_operand:GPR 0 "register_operand" "=r")
1897 (ne:GPR (match_operand:X 1 "register_operand" " r")
1901 [(set_attr "type" "slt")
1902 (set_attr "mode" "<X:MODE>")])
1904 (define_insn "*sgt<u>_<X:mode><GPR:mode>"
1905 [(set (match_operand:GPR 0 "register_operand" "= r")
1906 (any_gt:GPR (match_operand:X 1 "register_operand" " r")
1907 (match_operand:X 2 "reg_or_0_operand" " rJ")))]
1910 [(set_attr "type" "slt")
1911 (set_attr "mode" "<X:MODE>")])
1913 (define_insn "*sge<u>_<X:mode><GPR:mode>"
1914 [(set (match_operand:GPR 0 "register_operand" "=r")
1915 (any_ge:GPR (match_operand:X 1 "register_operand" " r")
1918 "slt%i2<u>\t%0,zero,%1"
1919 [(set_attr "type" "slt")
1920 (set_attr "mode" "<MODE>")])
1922 (define_insn "*slt<u>_<X:mode><GPR:mode>"
1923 [(set (match_operand:GPR 0 "register_operand" "= r")
1924 (any_lt:GPR (match_operand:X 1 "register_operand" " r")
1925 (match_operand:X 2 "arith_operand" " rI")))]
1927 "slt%i2<u>\t%0,%1,%2"
1928 [(set_attr "type" "slt")
1929 (set_attr "mode" "<MODE>")])
1931 (define_insn "*sle<u>_<X:mode><GPR:mode>"
1932 [(set (match_operand:GPR 0 "register_operand" "=r")
1933 (any_le:GPR (match_operand:X 1 "register_operand" " r")
1934 (match_operand:X 2 "sle_operand" "")))]
1937 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
1938 return "slt%i2<u>\t%0,%1,%2";
1940 [(set_attr "type" "slt")
1941 (set_attr "mode" "<MODE>")])
1944 ;; ....................
1946 ;; UNCONDITIONAL BRANCHES
1948 ;; ....................
1950 ;; Unconditional branches.
1954 (label_ref (match_operand 0 "" "")))]
1957 [(set_attr "type" "jump")
1958 (set_attr "mode" "none")])
1960 (define_expand "indirect_jump"
1961 [(set (pc) (match_operand 0 "register_operand"))]
1964 operands[0] = force_reg (Pmode, operands[0]);
1965 if (Pmode == SImode)
1966 emit_jump_insn (gen_indirect_jumpsi (operands[0]));
1968 emit_jump_insn (gen_indirect_jumpdi (operands[0]));
1972 (define_insn "indirect_jump<mode>"
1973 [(set (pc) (match_operand:P 0 "register_operand" "l"))]
1976 [(set_attr "type" "jump")
1977 (set_attr "mode" "none")])
1979 (define_expand "tablejump"
1980 [(set (pc) (match_operand 0 "register_operand" ""))
1981 (use (label_ref (match_operand 1 "" "")))]
1984 if (CASE_VECTOR_PC_RELATIVE)
1985 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1986 gen_rtx_LABEL_REF (Pmode, operands[1]),
1987 NULL_RTX, 0, OPTAB_DIRECT);
1989 if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode)
1990 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
1992 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
1996 (define_insn "tablejump<mode>"
1997 [(set (pc) (match_operand:GPR 0 "register_operand" "l"))
1998 (use (label_ref (match_operand 1 "" "")))]
2001 [(set_attr "type" "jump")
2002 (set_attr "mode" "none")])
2005 ;; ....................
2007 ;; Function prologue/epilogue
2009 ;; ....................
2012 (define_expand "prologue"
2016 riscv_expand_prologue ();
2020 ;; Block any insns from being moved before this point, since the
2021 ;; profiling call to mcount can use various registers that aren't
2022 ;; saved or used to pass arguments.
2024 (define_insn "blockage"
2025 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2028 [(set_attr "type" "ghost")
2029 (set_attr "mode" "none")])
2031 (define_expand "epilogue"
2035 riscv_expand_epilogue (false);
2039 (define_expand "sibcall_epilogue"
2043 riscv_expand_epilogue (true);
2047 ;; Trivial return. Make it look like a normal return insn as that
2048 ;; allows jump optimizations to work better.
2050 (define_expand "return"
2052 "riscv_can_use_return_insn ()"
2055 (define_insn "simple_return"
2059 return riscv_output_return ();
2061 [(set_attr "type" "jump")
2062 (set_attr "mode" "none")])
2066 (define_insn "simple_return_internal"
2068 (use (match_operand 0 "pmode_register_operand" ""))]
2071 [(set_attr "type" "jump")
2072 (set_attr "mode" "none")])
2074 ;; This is used in compiling the unwind routines.
2075 (define_expand "eh_return"
2076 [(use (match_operand 0 "general_operand"))]
2079 if (GET_MODE (operands[0]) != word_mode)
2080 operands[0] = convert_to_mode (word_mode, operands[0], 0);
2082 emit_insn (gen_eh_set_lr_di (operands[0]));
2084 emit_insn (gen_eh_set_lr_si (operands[0]));
2088 ;; Clobber the return address on the stack. We can't expand this
2089 ;; until we know where it will be put in the stack frame.
2091 (define_insn "eh_set_lr_si"
2092 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2093 (clobber (match_scratch:SI 1 "=&r"))]
2097 (define_insn "eh_set_lr_di"
2098 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2099 (clobber (match_scratch:DI 1 "=&r"))]
2104 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
2105 (clobber (match_scratch 1))]
2109 riscv_set_return_address (operands[0], operands[1]);
2114 ;; ....................
2118 ;; ....................
2120 (define_expand "sibcall"
2121 [(parallel [(call (match_operand 0 "")
2122 (match_operand 1 ""))
2123 (use (match_operand 2 "")) ;; next_arg_reg
2124 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
2127 rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2128 emit_call_insn (gen_sibcall_internal (target, operands[1]));
2132 (define_insn "sibcall_internal"
2133 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U"))
2134 (match_operand 1 "" ""))]
2135 "SIBLING_CALL_P (insn)"
2140 [(set_attr "type" "call")])
2142 (define_expand "sibcall_value"
2143 [(parallel [(set (match_operand 0 "")
2144 (call (match_operand 1 "")
2145 (match_operand 2 "")))
2146 (use (match_operand 3 ""))])] ;; next_arg_reg
2149 rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2150 emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2]));
2154 (define_insn "sibcall_value_internal"
2155 [(set (match_operand 0 "" "")
2156 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U"))
2157 (match_operand 2 "" "")))]
2158 "SIBLING_CALL_P (insn)"
2163 [(set_attr "type" "call")])
2165 (define_expand "call"
2166 [(parallel [(call (match_operand 0 "")
2167 (match_operand 1 ""))
2168 (use (match_operand 2 "")) ;; next_arg_reg
2169 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
2172 rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2173 emit_call_insn (gen_call_internal (target, operands[1]));
2177 (define_insn "call_internal"
2178 [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U"))
2179 (match_operand 1 "" ""))
2180 (clobber (reg:SI RETURN_ADDR_REGNUM))]
2186 [(set_attr "type" "call")])
2188 (define_expand "call_value"
2189 [(parallel [(set (match_operand 0 "")
2190 (call (match_operand 1 "")
2191 (match_operand 2 "")))
2192 (use (match_operand 3 ""))])] ;; next_arg_reg
2195 rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2196 emit_call_insn (gen_call_value_internal (operands[0], target, operands[2]));
2200 (define_insn "call_value_internal"
2201 [(set (match_operand 0 "" "")
2202 (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U"))
2203 (match_operand 2 "" "")))
2204 (clobber (reg:SI RETURN_ADDR_REGNUM))]
2210 [(set_attr "type" "call")])
2212 ;; Call subroutine returning any type.
2214 (define_expand "untyped_call"
2215 [(parallel [(call (match_operand 0 "")
2217 (match_operand 1 "")
2218 (match_operand 2 "")])]
2223 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2225 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2227 rtx set = XVECEXP (operands[2], 0, i);
2228 riscv_emit_move (SET_DEST (set), SET_SRC (set));
2231 emit_insn (gen_blockage ());
2239 [(set_attr "type" "nop")
2240 (set_attr "mode" "none")])
2243 [(trap_if (const_int 1) (const_int 0))]
2247 (define_insn "gpr_save"
2248 [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_SAVE)
2249 (clobber (reg:SI T0_REGNUM))
2250 (clobber (reg:SI T1_REGNUM))]
2252 { return riscv_output_gpr_save (INTVAL (operands[0])); })
2254 (define_insn "gpr_restore"
2255 [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_RESTORE)]
2257 "tail\t__riscv_restore_%0")
2259 (define_insn "gpr_restore_return"
2261 (use (match_operand 0 "pmode_register_operand" ""))
2266 (define_insn "riscv_frflags"
2267 [(set (match_operand:SI 0 "register_operand" "=r")
2268 (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))]
2272 (define_insn "riscv_fsflags"
2273 [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)]
2277 (define_insn "stack_tie<mode>"
2278 [(set (mem:BLK (scratch))
2279 (unspec:BLK [(match_operand:X 0 "register_operand" "r")
2280 (match_operand:X 1 "register_operand" "r")]
2284 [(set_attr "length" "0")]
2288 (include "peephole.md")
2290 (include "generic.md")