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 ;; Interrupt handler instructions.
62 ;; Blockage and synchronization.
69 [(RETURN_ADDR_REGNUM 1)
78 (include "predicates.md")
79 (include "constraints.md")
81 ;; ....................
85 ;; ....................
87 (define_attr "got" "unset,xgot_high,load"
88 (const_string "unset"))
90 ;; Classification of moves, extensions and truncations. Most values
91 ;; are as for "type" (see below) but there are also the following
92 ;; move-specific values:
94 ;; andi a single ANDI instruction
95 ;; shift_shift a shift left followed by a shift right
97 ;; This attribute is used to determine the instruction's length and
98 ;; scheduling type. For doubleword moves, the attribute always describes
99 ;; the split instructions; in some cases, it is more appropriate for the
100 ;; scheduling type to be "multi" instead.
101 (define_attr "move_type"
102 "unknown,load,fpload,store,fpstore,mtc,mfc,move,fmove,
103 const,logical,arith,andi,shift_shift"
104 (const_string "unknown"))
106 ;; Main data type used by the insn
107 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
108 (const_string "unknown"))
110 ;; True if the main data type is twice the size of a word.
111 (define_attr "dword_mode" "no,yes"
112 (cond [(and (eq_attr "mode" "DI,DF")
113 (eq (symbol_ref "TARGET_64BIT") (const_int 0)))
116 (and (eq_attr "mode" "TI,TF")
117 (ne (symbol_ref "TARGET_64BIT") (const_int 0)))
118 (const_string "yes")]
119 (const_string "no")))
121 ;; Classification of each insn.
122 ;; branch conditional branch
123 ;; jump unconditional jump
124 ;; call unconditional call
125 ;; load load instruction(s)
126 ;; fpload floating point load
127 ;; store store instruction(s)
128 ;; fpstore floating point store
129 ;; mtc transfer to coprocessor
130 ;; mfc transfer from coprocessor
131 ;; const load constant
132 ;; arith integer arithmetic instructions
133 ;; logical integer logical instructions
134 ;; shift integer shift instructions
135 ;; slt set less than instructions
136 ;; imul integer multiply
137 ;; idiv integer divide
138 ;; move integer register move (addi rd, rs1, 0)
139 ;; fmove floating point register move
140 ;; fadd floating point add/subtract
141 ;; fmul floating point multiply
142 ;; fmadd floating point multiply-add
143 ;; fdiv floating point divide
144 ;; fcmp floating point compare
145 ;; fcvt floating point convert
146 ;; fsqrt floating point square root
147 ;; multi multiword sequence (or user asm statements)
149 ;; ghost an instruction that produces no real code
151 "unknown,branch,jump,call,load,fpload,store,fpstore,
152 mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul,
153 fmadd,fdiv,fcmp,fcvt,fsqrt,multi,nop,ghost"
154 (cond [(eq_attr "got" "load") (const_string "load")
156 ;; If a doubleword move uses these expensive instructions,
157 ;; it is usually better to schedule them in the same way
158 ;; as the singleword form, rather than as "multi".
159 (eq_attr "move_type" "load") (const_string "load")
160 (eq_attr "move_type" "fpload") (const_string "fpload")
161 (eq_attr "move_type" "store") (const_string "store")
162 (eq_attr "move_type" "fpstore") (const_string "fpstore")
163 (eq_attr "move_type" "mtc") (const_string "mtc")
164 (eq_attr "move_type" "mfc") (const_string "mfc")
166 ;; These types of move are always single insns.
167 (eq_attr "move_type" "fmove") (const_string "fmove")
168 (eq_attr "move_type" "arith") (const_string "arith")
169 (eq_attr "move_type" "logical") (const_string "logical")
170 (eq_attr "move_type" "andi") (const_string "logical")
172 ;; These types of move are always split.
173 (eq_attr "move_type" "shift_shift")
174 (const_string "multi")
176 ;; These types of move are split for doubleword modes only.
177 (and (eq_attr "move_type" "move,const")
178 (eq_attr "dword_mode" "yes"))
179 (const_string "multi")
180 (eq_attr "move_type" "move") (const_string "move")
181 (eq_attr "move_type" "const") (const_string "const")]
182 (const_string "unknown")))
184 ;; Length of instruction in bytes.
185 (define_attr "length" ""
187 ;; Branches further than +/- 4 KiB require two instructions.
188 (eq_attr "type" "branch")
189 (if_then_else (and (le (minus (match_dup 0) (pc)) (const_int 4088))
190 (le (minus (pc) (match_dup 0)) (const_int 4092)))
194 ;; Conservatively assume calls take two instructions (AUIPC + JALR).
195 ;; The linker will opportunistically relax the sequence to JAL.
196 (eq_attr "type" "call") (const_int 8)
198 ;; "Ghost" instructions occupy no space.
199 (eq_attr "type" "ghost") (const_int 0)
201 (eq_attr "got" "load") (const_int 8)
203 (eq_attr "type" "fcmp") (const_int 8)
205 ;; SHIFT_SHIFTs are decomposed into two separate instructions.
206 (eq_attr "move_type" "shift_shift")
209 ;; Check for doubleword moves that are decomposed into two
211 (and (eq_attr "move_type" "mtc,mfc,move")
212 (eq_attr "dword_mode" "yes"))
215 ;; Doubleword CONST{,N} moves are split into two word
217 (and (eq_attr "move_type" "const")
218 (eq_attr "dword_mode" "yes"))
219 (symbol_ref "riscv_split_const_insns (operands[1]) * 4")
221 ;; Otherwise, constants, loads and stores are handled by external
223 (eq_attr "move_type" "load,fpload")
224 (symbol_ref "riscv_load_store_insns (operands[1], insn) * 4")
225 (eq_attr "move_type" "store,fpstore")
226 (symbol_ref "riscv_load_store_insns (operands[0], insn) * 4")
229 ;; Is copying of this instruction disallowed?
230 (define_attr "cannot_copy" "no,yes" (const_string "no"))
232 ;; Describe a user's asm statement.
233 (define_asm_attributes
234 [(set_attr "type" "multi")])
236 ;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
237 ;; from the same template.
238 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
240 ;; This mode iterator allows :P to be used for patterns that operate on
241 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
242 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
244 ;; Likewise, but for XLEN-sized quantities.
245 (define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")])
247 ;; Branches operate on XLEN-sized quantities, but for RV64 we accept
248 ;; QImode values so we can force zero-extension.
249 (define_mode_iterator BR [(QI "TARGET_64BIT") SI (DI "TARGET_64BIT")])
251 ;; 32-bit moves for which we provide move patterns.
252 (define_mode_iterator MOVE32 [SI])
254 ;; 64-bit modes for which we provide move patterns.
255 (define_mode_iterator MOVE64 [DI DF])
257 ;; Iterator for sub-32-bit integer modes.
258 (define_mode_iterator SHORT [QI HI])
260 ;; Iterator for HImode constant generation.
261 (define_mode_iterator HISI [HI SI])
263 ;; Iterator for QImode extension patterns.
264 (define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")])
266 ;; Iterator for extending loads.
267 (define_mode_iterator ZERO_EXTEND_LOAD [QI HI (SI "TARGET_64BIT")])
269 ;; Iterator for hardware integer modes narrower than XLEN.
270 (define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")])
272 ;; Iterator for hardware-supported integer modes.
273 (define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")])
275 ;; Iterator for hardware-supported floating-point modes.
276 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
277 (DF "TARGET_DOUBLE_FLOAT")])
279 ;; This attribute gives the length suffix for a sign- or zero-extension
281 (define_mode_attr size [(QI "b") (HI "h")])
283 ;; Mode attributes for loads.
284 (define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")])
286 ;; Instruction names for stores.
287 (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")])
289 ;; This attribute gives the best constraint to use for registers of
291 (define_mode_attr reg [(SI "d") (DI "d") (CC "d")])
293 ;; This attribute gives the format suffix for floating-point operations.
294 (define_mode_attr fmt [(SF "s") (DF "d")])
296 ;; This attribute gives the integer suffix for floating-point conversions.
297 (define_mode_attr ifmt [(SI "w") (DI "l")])
299 ;; This attribute gives the format suffix for atomic memory operations.
300 (define_mode_attr amo [(SI "w") (DI "d")])
302 ;; This attribute gives the upper-case mode name for one unit of a
303 ;; floating-point mode.
304 (define_mode_attr UNITMODE [(SF "SF") (DF "DF")])
306 ;; This attribute gives the integer mode that has half the size of
307 ;; the controlling mode.
308 (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
310 ;; Iterator and attributes for floating-point rounding instructions.
311 (define_int_iterator RINT [UNSPEC_LRINT UNSPEC_LROUND])
312 (define_int_attr rint_pattern [(UNSPEC_LRINT "rint") (UNSPEC_LROUND "round")])
313 (define_int_attr rint_rm [(UNSPEC_LRINT "dyn") (UNSPEC_LROUND "rmm")])
315 ;; Iterator and attributes for quiet comparisons.
316 (define_int_iterator QUIET_COMPARISON [UNSPEC_FLT_QUIET UNSPEC_FLE_QUIET])
317 (define_int_attr quiet_pattern [(UNSPEC_FLT_QUIET "lt") (UNSPEC_FLE_QUIET "le")])
319 ;; This code iterator allows signed and unsigned widening multiplications
320 ;; to use the same template.
321 (define_code_iterator any_extend [sign_extend zero_extend])
323 ;; This code iterator allows the two right shift instructions to be
324 ;; generated from the same template.
325 (define_code_iterator any_shiftrt [ashiftrt lshiftrt])
327 ;; This code iterator allows the three shift instructions to be generated
328 ;; from the same template.
329 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
331 ;; This code iterator allows the three bitwise instructions to be generated
332 ;; from the same template.
333 (define_code_iterator any_bitwise [and ior xor])
335 ;; This code iterator allows unsigned and signed division to be generated
336 ;; from the same template.
337 (define_code_iterator any_div [div udiv mod umod])
339 ;; This code iterator allows unsigned and signed modulus to be generated
340 ;; from the same template.
341 (define_code_iterator any_mod [mod umod])
343 ;; These code iterators allow the signed and unsigned scc operations to use
344 ;; the same template.
345 (define_code_iterator any_gt [gt gtu])
346 (define_code_iterator any_ge [ge geu])
347 (define_code_iterator any_lt [lt ltu])
348 (define_code_iterator any_le [le leu])
350 ;; <u> expands to an empty string when doing a signed operation and
351 ;; "u" when doing an unsigned operation.
352 (define_code_attr u [(sign_extend "") (zero_extend "u")
358 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
359 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
361 ;; <optab> expands to the name of the optab for a particular code.
362 (define_code_attr optab [(ashift "ashl")
379 ;; <insn> expands to the name of the insn that implements a particular code.
380 (define_code_attr insn [(ashift "sll")
393 ;; Ghost instructions produce no real code and introduce no hazards.
394 ;; They exist purely to express an effect on dataflow.
395 (define_insn_reservation "ghost" 0
396 (eq_attr "type" "ghost")
400 ;; ....................
404 ;; ....................
407 (define_insn "add<mode>3"
408 [(set (match_operand:ANYF 0 "register_operand" "=f")
409 (plus:ANYF (match_operand:ANYF 1 "register_operand" " f")
410 (match_operand:ANYF 2 "register_operand" " f")))]
412 "fadd.<fmt>\t%0,%1,%2"
413 [(set_attr "type" "fadd")
414 (set_attr "mode" "<UNITMODE>")])
416 (define_insn "addsi3"
417 [(set (match_operand:SI 0 "register_operand" "=r,r")
418 (plus:SI (match_operand:SI 1 "register_operand" " r,r")
419 (match_operand:SI 2 "arith_operand" " r,I")))]
421 { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
422 [(set_attr "type" "arith")
423 (set_attr "mode" "SI")])
425 (define_insn "adddi3"
426 [(set (match_operand:DI 0 "register_operand" "=r,r")
427 (plus:DI (match_operand:DI 1 "register_operand" " r,r")
428 (match_operand:DI 2 "arith_operand" " r,I")))]
431 [(set_attr "type" "arith")
432 (set_attr "mode" "DI")])
434 (define_insn "*addsi3_extended"
435 [(set (match_operand:DI 0 "register_operand" "=r,r")
437 (plus:SI (match_operand:SI 1 "register_operand" " r,r")
438 (match_operand:SI 2 "arith_operand" " r,I"))))]
441 [(set_attr "type" "arith")
442 (set_attr "mode" "SI")])
444 (define_insn "*addsi3_extended2"
445 [(set (match_operand:DI 0 "register_operand" "=r,r")
447 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" " r,r")
448 (match_operand:DI 2 "arith_operand" " r,I"))
452 [(set_attr "type" "arith")
453 (set_attr "mode" "SI")])
456 ;; ....................
460 ;; ....................
463 (define_insn "sub<mode>3"
464 [(set (match_operand:ANYF 0 "register_operand" "=f")
465 (minus:ANYF (match_operand:ANYF 1 "register_operand" " f")
466 (match_operand:ANYF 2 "register_operand" " f")))]
468 "fsub.<fmt>\t%0,%1,%2"
469 [(set_attr "type" "fadd")
470 (set_attr "mode" "<UNITMODE>")])
472 (define_insn "subdi3"
473 [(set (match_operand:DI 0 "register_operand" "= r")
474 (minus:DI (match_operand:DI 1 "reg_or_0_operand" " rJ")
475 (match_operand:DI 2 "register_operand" " r")))]
478 [(set_attr "type" "arith")
479 (set_attr "mode" "DI")])
481 (define_insn "subsi3"
482 [(set (match_operand:SI 0 "register_operand" "= r")
483 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
484 (match_operand:SI 2 "register_operand" " r")))]
486 { return TARGET_64BIT ? "subw\t%0,%z1,%2" : "sub\t%0,%z1,%2"; }
487 [(set_attr "type" "arith")
488 (set_attr "mode" "SI")])
490 (define_insn "*subsi3_extended"
491 [(set (match_operand:DI 0 "register_operand" "= r")
493 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
494 (match_operand:SI 2 "register_operand" " r"))))]
497 [(set_attr "type" "arith")
498 (set_attr "mode" "SI")])
500 (define_insn "*subsi3_extended2"
501 [(set (match_operand:DI 0 "register_operand" "=r")
503 (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" " r")
504 (match_operand:DI 2 "register_operand" " r"))
508 [(set_attr "type" "arith")
509 (set_attr "mode" "SI")])
512 ;; ....................
516 ;; ....................
519 (define_insn "mul<mode>3"
520 [(set (match_operand:ANYF 0 "register_operand" "=f")
521 (mult:ANYF (match_operand:ANYF 1 "register_operand" " f")
522 (match_operand:ANYF 2 "register_operand" " f")))]
524 "fmul.<fmt>\t%0,%1,%2"
525 [(set_attr "type" "fmul")
526 (set_attr "mode" "<UNITMODE>")])
528 (define_insn "mulsi3"
529 [(set (match_operand:SI 0 "register_operand" "=r")
530 (mult:SI (match_operand:SI 1 "register_operand" " r")
531 (match_operand:SI 2 "register_operand" " r")))]
533 { return TARGET_64BIT ? "mulw\t%0,%1,%2" : "mul\t%0,%1,%2"; }
534 [(set_attr "type" "imul")
535 (set_attr "mode" "SI")])
537 (define_insn "muldi3"
538 [(set (match_operand:DI 0 "register_operand" "=r")
539 (mult:DI (match_operand:DI 1 "register_operand" " r")
540 (match_operand:DI 2 "register_operand" " r")))]
541 "TARGET_MUL && TARGET_64BIT"
543 [(set_attr "type" "imul")
544 (set_attr "mode" "DI")])
546 (define_insn "*mulsi3_extended"
547 [(set (match_operand:DI 0 "register_operand" "=r")
549 (mult:SI (match_operand:SI 1 "register_operand" " r")
550 (match_operand:SI 2 "register_operand" " r"))))]
551 "TARGET_MUL && TARGET_64BIT"
553 [(set_attr "type" "imul")
554 (set_attr "mode" "SI")])
556 (define_insn "*mulsi3_extended2"
557 [(set (match_operand:DI 0 "register_operand" "=r")
559 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" " r")
560 (match_operand:DI 2 "register_operand" " r"))
562 "TARGET_MUL && TARGET_64BIT"
564 [(set_attr "type" "imul")
565 (set_attr "mode" "SI")])
568 ;; ........................
570 ;; MULTIPLICATION HIGH-PART
572 ;; ........................
576 (define_expand "<u>mulditi3"
577 [(set (match_operand:TI 0 "register_operand")
578 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
579 (any_extend:TI (match_operand:DI 2 "register_operand"))))]
580 "TARGET_MUL && TARGET_64BIT"
582 rtx low = gen_reg_rtx (DImode);
583 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
585 rtx high = gen_reg_rtx (DImode);
586 emit_insn (gen_<u>muldi3_highpart (high, operands[1], operands[2]));
588 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
589 emit_move_insn (gen_highpart (DImode, operands[0]), high);
593 (define_insn "<u>muldi3_highpart"
594 [(set (match_operand:DI 0 "register_operand" "=r")
597 (mult:TI (any_extend:TI
598 (match_operand:DI 1 "register_operand" " r"))
600 (match_operand:DI 2 "register_operand" " r")))
602 "TARGET_MUL && TARGET_64BIT"
604 [(set_attr "type" "imul")
605 (set_attr "mode" "DI")])
607 (define_expand "usmulditi3"
608 [(set (match_operand:TI 0 "register_operand")
609 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand"))
610 (sign_extend:TI (match_operand:DI 2 "register_operand"))))]
611 "TARGET_MUL && TARGET_64BIT"
613 rtx low = gen_reg_rtx (DImode);
614 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
616 rtx high = gen_reg_rtx (DImode);
617 emit_insn (gen_usmuldi3_highpart (high, operands[1], operands[2]));
619 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
620 emit_move_insn (gen_highpart (DImode, operands[0]), high);
624 (define_insn "usmuldi3_highpart"
625 [(set (match_operand:DI 0 "register_operand" "=r")
628 (mult:TI (zero_extend:TI
629 (match_operand:DI 1 "register_operand" "r"))
631 (match_operand:DI 2 "register_operand" " r")))
633 "TARGET_MUL && TARGET_64BIT"
635 [(set_attr "type" "imul")
636 (set_attr "mode" "DI")])
638 (define_expand "<u>mulsidi3"
639 [(set (match_operand:DI 0 "register_operand" "=r")
640 (mult:DI (any_extend:DI
641 (match_operand:SI 1 "register_operand" " r"))
643 (match_operand:SI 2 "register_operand" " r"))))]
644 "TARGET_MUL && !TARGET_64BIT"
646 rtx temp = gen_reg_rtx (SImode);
647 emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
648 emit_insn (gen_<u>mulsi3_highpart (riscv_subword (operands[0], true),
649 operands[1], operands[2]));
650 emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
654 (define_insn "<u>mulsi3_highpart"
655 [(set (match_operand:SI 0 "register_operand" "=r")
658 (mult:DI (any_extend:DI
659 (match_operand:SI 1 "register_operand" " r"))
661 (match_operand:SI 2 "register_operand" " r")))
663 "TARGET_MUL && !TARGET_64BIT"
665 [(set_attr "type" "imul")
666 (set_attr "mode" "SI")])
669 (define_expand "usmulsidi3"
670 [(set (match_operand:DI 0 "register_operand" "=r")
671 (mult:DI (zero_extend:DI
672 (match_operand:SI 1 "register_operand" " r"))
674 (match_operand:SI 2 "register_operand" " r"))))]
675 "TARGET_MUL && !TARGET_64BIT"
677 rtx temp = gen_reg_rtx (SImode);
678 emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
679 emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true),
680 operands[1], operands[2]));
681 emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
685 (define_insn "usmulsi3_highpart"
686 [(set (match_operand:SI 0 "register_operand" "=r")
689 (mult:DI (zero_extend:DI
690 (match_operand:SI 1 "register_operand" " r"))
692 (match_operand:SI 2 "register_operand" " r")))
694 "TARGET_MUL && !TARGET_64BIT"
696 [(set_attr "type" "imul")
697 (set_attr "mode" "SI")])
700 ;; ....................
702 ;; DIVISION and REMAINDER
704 ;; ....................
707 (define_insn "<optab>si3"
708 [(set (match_operand:SI 0 "register_operand" "=r")
709 (any_div:SI (match_operand:SI 1 "register_operand" " r")
710 (match_operand:SI 2 "register_operand" " r")))]
712 { return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2"; }
713 [(set_attr "type" "idiv")
714 (set_attr "mode" "SI")])
716 (define_insn "<optab>di3"
717 [(set (match_operand:DI 0 "register_operand" "=r")
718 (any_div:DI (match_operand:DI 1 "register_operand" " r")
719 (match_operand:DI 2 "register_operand" " r")))]
720 "TARGET_DIV && TARGET_64BIT"
721 "<insn>%i2\t%0,%1,%2"
722 [(set_attr "type" "idiv")
723 (set_attr "mode" "DI")])
725 (define_insn "*<optab>si3_extended"
726 [(set (match_operand:DI 0 "register_operand" "=r")
728 (any_div:SI (match_operand:SI 1 "register_operand" " r")
729 (match_operand:SI 2 "register_operand" " r"))))]
730 "TARGET_DIV && TARGET_64BIT"
731 "<insn>%i2w\t%0,%1,%2"
732 [(set_attr "type" "idiv")
733 (set_attr "mode" "DI")])
735 (define_insn "div<mode>3"
736 [(set (match_operand:ANYF 0 "register_operand" "=f")
737 (div:ANYF (match_operand:ANYF 1 "register_operand" " f")
738 (match_operand:ANYF 2 "register_operand" " f")))]
739 "TARGET_HARD_FLOAT && TARGET_FDIV"
740 "fdiv.<fmt>\t%0,%1,%2"
741 [(set_attr "type" "fdiv")
742 (set_attr "mode" "<UNITMODE>")])
745 ;; ....................
749 ;; ....................
751 (define_insn "sqrt<mode>2"
752 [(set (match_operand:ANYF 0 "register_operand" "=f")
753 (sqrt:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
754 "TARGET_HARD_FLOAT && TARGET_FDIV"
756 return "fsqrt.<fmt>\t%0,%1";
758 [(set_attr "type" "fsqrt")
759 (set_attr "mode" "<UNITMODE>")])
761 ;; Floating point multiply accumulate instructions.
764 (define_insn "fma<mode>4"
765 [(set (match_operand:ANYF 0 "register_operand" "=f")
766 (fma:ANYF (match_operand:ANYF 1 "register_operand" " f")
767 (match_operand:ANYF 2 "register_operand" " f")
768 (match_operand:ANYF 3 "register_operand" " f")))]
770 "fmadd.<fmt>\t%0,%1,%2,%3"
771 [(set_attr "type" "fmadd")
772 (set_attr "mode" "<UNITMODE>")])
775 (define_insn "fms<mode>4"
776 [(set (match_operand:ANYF 0 "register_operand" "=f")
777 (fma:ANYF (match_operand:ANYF 1 "register_operand" " f")
778 (match_operand:ANYF 2 "register_operand" " f")
779 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
781 "fmsub.<fmt>\t%0,%1,%2,%3"
782 [(set_attr "type" "fmadd")
783 (set_attr "mode" "<UNITMODE>")])
786 (define_insn "fnms<mode>4"
787 [(set (match_operand:ANYF 0 "register_operand" "=f")
789 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
790 (match_operand:ANYF 2 "register_operand" " f")
791 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
793 "fnmadd.<fmt>\t%0,%1,%2,%3"
794 [(set_attr "type" "fmadd")
795 (set_attr "mode" "<UNITMODE>")])
798 (define_insn "fnma<mode>4"
799 [(set (match_operand:ANYF 0 "register_operand" "=f")
801 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
802 (match_operand:ANYF 2 "register_operand" " f")
803 (match_operand:ANYF 3 "register_operand" " f")))]
805 "fnmsub.<fmt>\t%0,%1,%2,%3"
806 [(set_attr "type" "fmadd")
807 (set_attr "mode" "<UNITMODE>")])
809 ;; -(-a * b - c), modulo signed zeros
810 (define_insn "*fma<mode>4"
811 [(set (match_operand:ANYF 0 "register_operand" "=f")
814 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
815 (match_operand:ANYF 2 "register_operand" " f")
816 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
817 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
818 "fmadd.<fmt>\t%0,%1,%2,%3"
819 [(set_attr "type" "fmadd")
820 (set_attr "mode" "<UNITMODE>")])
822 ;; -(-a * b + c), modulo signed zeros
823 (define_insn "*fms<mode>4"
824 [(set (match_operand:ANYF 0 "register_operand" "=f")
827 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
828 (match_operand:ANYF 2 "register_operand" " f")
829 (match_operand:ANYF 3 "register_operand" " f"))))]
830 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
831 "fmsub.<fmt>\t%0,%1,%2,%3"
832 [(set_attr "type" "fmadd")
833 (set_attr "mode" "<UNITMODE>")])
835 ;; -(a * b + c), modulo signed zeros
836 (define_insn "*fnms<mode>4"
837 [(set (match_operand:ANYF 0 "register_operand" "=f")
840 (match_operand:ANYF 1 "register_operand" " f")
841 (match_operand:ANYF 2 "register_operand" " f")
842 (match_operand:ANYF 3 "register_operand" " f"))))]
843 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
844 "fnmadd.<fmt>\t%0,%1,%2,%3"
845 [(set_attr "type" "fmadd")
846 (set_attr "mode" "<UNITMODE>")])
848 ;; -(a * b - c), modulo signed zeros
849 (define_insn "*fnma<mode>4"
850 [(set (match_operand:ANYF 0 "register_operand" "=f")
853 (match_operand:ANYF 1 "register_operand" " f")
854 (match_operand:ANYF 2 "register_operand" " f")
855 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
856 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
857 "fnmsub.<fmt>\t%0,%1,%2,%3"
858 [(set_attr "type" "fmadd")
859 (set_attr "mode" "<UNITMODE>")])
862 ;; ....................
866 ;; ....................
868 (define_insn "abs<mode>2"
869 [(set (match_operand:ANYF 0 "register_operand" "=f")
870 (abs:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
873 [(set_attr "type" "fmove")
874 (set_attr "mode" "<UNITMODE>")])
876 (define_insn "copysign<mode>3"
877 [(set (match_operand:ANYF 0 "register_operand" "=f")
878 (unspec:ANYF [(match_operand:ANYF 1 "register_operand" " f")
879 (match_operand:ANYF 2 "register_operand" " f")]
882 "fsgnj.<fmt>\t%0,%1,%2"
883 [(set_attr "type" "fmove")
884 (set_attr "mode" "<UNITMODE>")])
886 (define_insn "neg<mode>2"
887 [(set (match_operand:ANYF 0 "register_operand" "=f")
888 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
891 [(set_attr "type" "fmove")
892 (set_attr "mode" "<UNITMODE>")])
895 ;; ....................
899 ;; ....................
901 (define_insn "smin<mode>3"
902 [(set (match_operand:ANYF 0 "register_operand" "=f")
903 (smin:ANYF (match_operand:ANYF 1 "register_operand" " f")
904 (match_operand:ANYF 2 "register_operand" " f")))]
906 "fmin.<fmt>\t%0,%1,%2"
907 [(set_attr "type" "fmove")
908 (set_attr "mode" "<UNITMODE>")])
910 (define_insn "smax<mode>3"
911 [(set (match_operand:ANYF 0 "register_operand" "=f")
912 (smax:ANYF (match_operand:ANYF 1 "register_operand" " f")
913 (match_operand:ANYF 2 "register_operand" " f")))]
915 "fmax.<fmt>\t%0,%1,%2"
916 [(set_attr "type" "fmove")
917 (set_attr "mode" "<UNITMODE>")])
920 ;; ....................
924 ;; ....................
927 ;; For RV64, we don't expose the SImode operations to the rtl expanders,
928 ;; but SImode versions exist for combine.
930 (define_insn "<optab><mode>3"
931 [(set (match_operand:X 0 "register_operand" "=r,r")
932 (any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
933 (match_operand:X 2 "arith_operand" " r,I")))]
935 "<insn>%i2\t%0,%1,%2"
936 [(set_attr "type" "logical")
937 (set_attr "mode" "<MODE>")])
939 (define_insn "*<optab>si3_internal"
940 [(set (match_operand:SI 0 "register_operand" "=r,r")
941 (any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r")
942 (match_operand:SI 2 "arith_operand" " r,I")))]
944 "<insn>%i2\t%0,%1,%2"
945 [(set_attr "type" "logical")
946 (set_attr "mode" "SI")])
948 (define_insn "one_cmpl<mode>2"
949 [(set (match_operand:X 0 "register_operand" "=r")
950 (not:X (match_operand:X 1 "register_operand" " r")))]
953 [(set_attr "type" "logical")
954 (set_attr "mode" "<MODE>")])
956 (define_insn "*one_cmplsi2_internal"
957 [(set (match_operand:SI 0 "register_operand" "=r")
958 (not:SI (match_operand:SI 1 "register_operand" " r")))]
961 [(set_attr "type" "logical")
962 (set_attr "mode" "SI")])
965 ;; ....................
969 ;; ....................
971 (define_insn "truncdfsf2"
972 [(set (match_operand:SF 0 "register_operand" "=f")
974 (match_operand:DF 1 "register_operand" " f")))]
975 "TARGET_DOUBLE_FLOAT"
977 [(set_attr "type" "fcvt")
978 (set_attr "mode" "SF")])
981 ;; ....................
985 ;; ....................
989 (define_insn_and_split "zero_extendsidi2"
990 [(set (match_operand:DI 0 "register_operand" "=r,r")
992 (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
997 "&& reload_completed && REG_P (operands[1])"
999 (ashift:DI (match_dup 1) (const_int 32)))
1001 (lshiftrt:DI (match_dup 0) (const_int 32)))]
1002 { operands[1] = gen_lowpart (DImode, operands[1]); }
1003 [(set_attr "move_type" "shift_shift,load")
1004 (set_attr "mode" "DI")])
1006 (define_insn_and_split "zero_extendhi<GPR:mode>2"
1007 [(set (match_operand:GPR 0 "register_operand" "=r,r")
1009 (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
1014 "&& reload_completed && REG_P (operands[1])"
1016 (ashift:GPR (match_dup 1) (match_dup 2)))
1018 (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
1020 operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
1021 operands[2] = GEN_INT(GET_MODE_BITSIZE(<GPR:MODE>mode) - 16);
1023 [(set_attr "move_type" "shift_shift,load")
1024 (set_attr "mode" "<GPR:MODE>")])
1026 (define_insn "zero_extendqi<SUPERQI:mode>2"
1027 [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
1028 (zero_extend:SUPERQI
1029 (match_operand:QI 1 "nonimmediate_operand" " r,m")))]
1034 [(set_attr "move_type" "andi,load")
1035 (set_attr "mode" "<SUPERQI:MODE>")])
1038 ;; ....................
1042 ;; ....................
1044 (define_insn "extendsidi2"
1045 [(set (match_operand:DI 0 "register_operand" "=r,r")
1047 (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
1052 [(set_attr "move_type" "move,load")
1053 (set_attr "mode" "DI")])
1055 (define_insn_and_split "extend<SHORT:mode><SUPERQI:mode>2"
1056 [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
1057 (sign_extend:SUPERQI
1058 (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
1062 l<SHORT:size>\t%0,%1"
1063 "&& reload_completed && REG_P (operands[1])"
1064 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1065 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
1067 operands[0] = gen_lowpart (SImode, operands[0]);
1068 operands[1] = gen_lowpart (SImode, operands[1]);
1069 operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
1070 - GET_MODE_BITSIZE (<SHORT:MODE>mode));
1072 [(set_attr "move_type" "shift_shift,load")
1073 (set_attr "mode" "SI")])
1075 (define_insn "extendsfdf2"
1076 [(set (match_operand:DF 0 "register_operand" "=f")
1078 (match_operand:SF 1 "register_operand" " f")))]
1079 "TARGET_DOUBLE_FLOAT"
1081 [(set_attr "type" "fcvt")
1082 (set_attr "mode" "DF")])
1085 ;; ....................
1089 ;; ....................
1091 (define_insn "fix_trunc<ANYF:mode><GPR:mode>2"
1092 [(set (match_operand:GPR 0 "register_operand" "=r")
1094 (match_operand:ANYF 1 "register_operand" " f")))]
1096 "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,rtz"
1097 [(set_attr "type" "fcvt")
1098 (set_attr "mode" "<ANYF:MODE>")])
1100 (define_insn "fixuns_trunc<ANYF:mode><GPR:mode>2"
1101 [(set (match_operand:GPR 0 "register_operand" "=r")
1103 (match_operand:ANYF 1 "register_operand" " f")))]
1105 "fcvt.<GPR:ifmt>u.<ANYF:fmt> %0,%1,rtz"
1106 [(set_attr "type" "fcvt")
1107 (set_attr "mode" "<ANYF:MODE>")])
1109 (define_insn "float<GPR:mode><ANYF:mode>2"
1110 [(set (match_operand:ANYF 0 "register_operand" "= f")
1112 (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1114 "fcvt.<ANYF:fmt>.<GPR:ifmt>\t%0,%z1"
1115 [(set_attr "type" "fcvt")
1116 (set_attr "mode" "<ANYF:MODE>")])
1118 (define_insn "floatuns<GPR:mode><ANYF:mode>2"
1119 [(set (match_operand:ANYF 0 "register_operand" "= f")
1120 (unsigned_float:ANYF
1121 (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1123 "fcvt.<ANYF:fmt>.<GPR:ifmt>u\t%0,%z1"
1124 [(set_attr "type" "fcvt")
1125 (set_attr "mode" "<ANYF:MODE>")])
1127 (define_insn "l<rint_pattern><ANYF:mode><GPR:mode>2"
1128 [(set (match_operand:GPR 0 "register_operand" "=r")
1130 [(match_operand:ANYF 1 "register_operand" " f")]
1133 "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,<rint_rm>"
1134 [(set_attr "type" "fcvt")
1135 (set_attr "mode" "<ANYF:MODE>")])
1138 ;; ....................
1142 ;; ....................
1144 ;; Lower-level instructions for loading an address from the GOT.
1145 ;; We could use MEMs, but an unspec gives more optimization
1148 (define_insn "got_load<mode>"
1149 [(set (match_operand:P 0 "register_operand" "=r")
1151 [(match_operand:P 1 "symbolic_operand" "")]
1155 [(set_attr "got" "load")
1156 (set_attr "mode" "<MODE>")])
1158 (define_insn "tls_add_tp_le<mode>"
1159 [(set (match_operand:P 0 "register_operand" "=r")
1161 [(match_operand:P 1 "register_operand" "r")
1162 (match_operand:P 2 "register_operand" "r")
1163 (match_operand:P 3 "symbolic_operand" "")]
1166 "add\t%0,%1,%2,%%tprel_add(%3)"
1167 [(set_attr "type" "arith")
1168 (set_attr "mode" "<MODE>")])
1170 (define_insn "got_load_tls_gd<mode>"
1171 [(set (match_operand:P 0 "register_operand" "=r")
1173 [(match_operand:P 1 "symbolic_operand" "")]
1177 [(set_attr "got" "load")
1178 (set_attr "mode" "<MODE>")])
1180 (define_insn "got_load_tls_ie<mode>"
1181 [(set (match_operand:P 0 "register_operand" "=r")
1183 [(match_operand:P 1 "symbolic_operand" "")]
1187 [(set_attr "got" "load")
1188 (set_attr "mode" "<MODE>")])
1190 (define_insn "auipc<mode>"
1191 [(set (match_operand:P 0 "register_operand" "=r")
1193 [(match_operand:P 1 "symbolic_operand" "")
1194 (match_operand:P 2 "const_int_operand")
1198 ".LA%2: auipc\t%0,%h1"
1199 [(set_attr "type" "arith")
1200 (set_attr "cannot_copy" "yes")])
1202 ;; Instructions for adding the low 12 bits of an address to a register.
1203 ;; Operand 2 is the address: riscv_print_operand works out which relocation
1204 ;; should be applied.
1206 (define_insn "*low<mode>"
1207 [(set (match_operand:P 0 "register_operand" "=r")
1208 (lo_sum:P (match_operand:P 1 "register_operand" " r")
1209 (match_operand:P 2 "symbolic_operand" "")))]
1212 [(set_attr "type" "arith")
1213 (set_attr "mode" "<MODE>")])
1215 ;; Allow combine to split complex const_int load sequences, using operand 2
1216 ;; to store the intermediate results. See move_operand for details.
1218 [(set (match_operand:GPR 0 "register_operand")
1219 (match_operand:GPR 1 "splittable_const_int_operand"))
1220 (clobber (match_operand:GPR 2 "register_operand"))]
1224 riscv_move_integer (operands[2], operands[0], INTVAL (operands[1]));
1228 ;; Likewise, for symbolic operands.
1230 [(set (match_operand:P 0 "register_operand")
1231 (match_operand:P 1))
1232 (clobber (match_operand:P 2 "register_operand"))]
1233 "riscv_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
1234 [(set (match_dup 0) (match_dup 3))]
1236 riscv_split_symbol (operands[2], operands[1],
1237 MAX_MACHINE_MODE, &operands[3]);
1240 ;; 64-bit integer moves
1242 (define_expand "movdi"
1243 [(set (match_operand:DI 0 "")
1244 (match_operand:DI 1 ""))]
1247 if (riscv_legitimize_move (DImode, operands[0], operands[1]))
1251 (define_insn "*movdi_32bit"
1252 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m, *f,*f,*r,*f,*m")
1253 (match_operand:DI 1 "move_operand" " r,i,m,r,*J*r,*m,*f,*f,*f"))]
1255 && (register_operand (operands[0], DImode)
1256 || reg_or_0_operand (operands[1], DImode))"
1257 { return riscv_output_move (operands[0], operands[1]); }
1258 [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1259 (set_attr "mode" "DI")])
1261 (define_insn "*movdi_64bit"
1262 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, *f,*f,*r,*f,*m")
1263 (match_operand:DI 1 "move_operand" " r,T,m,rJ,*r*J,*m,*f,*f,*f"))]
1265 && (register_operand (operands[0], DImode)
1266 || reg_or_0_operand (operands[1], DImode))"
1267 { return riscv_output_move (operands[0], operands[1]); }
1268 [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1269 (set_attr "mode" "DI")])
1271 ;; 32-bit Integer moves
1273 (define_expand "mov<mode>"
1274 [(set (match_operand:MOVE32 0 "")
1275 (match_operand:MOVE32 1 ""))]
1278 if (riscv_legitimize_move (<MODE>mode, operands[0], operands[1]))
1282 (define_insn "*movsi_internal"
1283 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, *f,*f,*r,*m")
1284 (match_operand:SI 1 "move_operand" " r,T,m,rJ,*r*J,*m,*f,*f"))]
1285 "(register_operand (operands[0], SImode)
1286 || reg_or_0_operand (operands[1], SImode))"
1287 { return riscv_output_move (operands[0], operands[1]); }
1288 [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore")
1289 (set_attr "mode" "SI")])
1291 ;; 16-bit Integer moves
1293 ;; Unlike most other insns, the move insns can't be split with
1294 ;; different predicates, because register spilling and other parts of
1295 ;; the compiler, have memoized the insn number already.
1296 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
1298 (define_expand "movhi"
1299 [(set (match_operand:HI 0 "")
1300 (match_operand:HI 1 ""))]
1303 if (riscv_legitimize_move (HImode, operands[0], operands[1]))
1307 (define_insn "*movhi_internal"
1308 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r, m, *f,*r")
1309 (match_operand:HI 1 "move_operand" " r,T,m,rJ,*r*J,*f"))]
1310 "(register_operand (operands[0], HImode)
1311 || reg_or_0_operand (operands[1], HImode))"
1312 { return riscv_output_move (operands[0], operands[1]); }
1313 [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1314 (set_attr "mode" "HI")])
1316 ;; HImode constant generation; see riscv_move_integer for details.
1317 ;; si+si->hi without truncation is legal because of
1318 ;; TARGET_TRULY_NOOP_TRUNCATION.
1320 (define_insn "*add<mode>hi3"
1321 [(set (match_operand:HI 0 "register_operand" "=r,r")
1322 (plus:HI (match_operand:HISI 1 "register_operand" " r,r")
1323 (match_operand:HISI 2 "arith_operand" " r,I")))]
1325 { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
1326 [(set_attr "type" "arith")
1327 (set_attr "mode" "HI")])
1329 (define_insn "*xor<mode>hi3"
1330 [(set (match_operand:HI 0 "register_operand" "=r,r")
1331 (xor:HI (match_operand:HISI 1 "register_operand" " r,r")
1332 (match_operand:HISI 2 "arith_operand" " r,I")))]
1335 [(set_attr "type" "logical")
1336 (set_attr "mode" "HI")])
1338 ;; 8-bit Integer moves
1340 (define_expand "movqi"
1341 [(set (match_operand:QI 0 "")
1342 (match_operand:QI 1 ""))]
1345 if (riscv_legitimize_move (QImode, operands[0], operands[1]))
1349 (define_insn "*movqi_internal"
1350 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r, m, *f,*r")
1351 (match_operand:QI 1 "move_operand" " r,I,m,rJ,*r*J,*f"))]
1352 "(register_operand (operands[0], QImode)
1353 || reg_or_0_operand (operands[1], QImode))"
1354 { return riscv_output_move (operands[0], operands[1]); }
1355 [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1356 (set_attr "mode" "QI")])
1358 ;; 32-bit floating point moves
1360 (define_expand "movsf"
1361 [(set (match_operand:SF 0 "")
1362 (match_operand:SF 1 ""))]
1365 if (riscv_legitimize_move (SFmode, operands[0], operands[1]))
1369 (define_insn "*movsf_hardfloat"
1370 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r, *r,*r,*m")
1371 (match_operand:SF 1 "move_operand" " f,G,m,f,G,*r,*f,*G*r,*m,*r"))]
1373 && (register_operand (operands[0], SFmode)
1374 || reg_or_0_operand (operands[1], SFmode))"
1375 { return riscv_output_move (operands[0], operands[1]); }
1376 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1377 (set_attr "mode" "SF")])
1379 (define_insn "*movsf_softfloat"
1380 [(set (match_operand:SF 0 "nonimmediate_operand" "= r,r,m")
1381 (match_operand:SF 1 "move_operand" " Gr,m,r"))]
1383 && (register_operand (operands[0], SFmode)
1384 || reg_or_0_operand (operands[1], SFmode))"
1385 { return riscv_output_move (operands[0], operands[1]); }
1386 [(set_attr "move_type" "move,load,store")
1387 (set_attr "mode" "SF")])
1389 ;; 64-bit floating point moves
1391 (define_expand "movdf"
1392 [(set (match_operand:DF 0 "")
1393 (match_operand:DF 1 ""))]
1396 if (riscv_legitimize_move (DFmode, operands[0], operands[1]))
1400 ;; In RV32, we lack fmv.x.d and fmv.d.x. Go through memory instead.
1401 ;; (However, we can still use fcvt.d.w to zero a floating-point register.)
1402 (define_insn "*movdf_hardfloat_rv32"
1403 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m, *r,*r,*m")
1404 (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r*G,*m,*r"))]
1405 "!TARGET_64BIT && TARGET_DOUBLE_FLOAT
1406 && (register_operand (operands[0], DFmode)
1407 || reg_or_0_operand (operands[1], DFmode))"
1408 { return riscv_output_move (operands[0], operands[1]); }
1409 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,move,load,store")
1410 (set_attr "mode" "DF")])
1412 (define_insn "*movdf_hardfloat_rv64"
1413 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r, *r,*r,*m")
1414 (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r,*f,*r*G,*m,*r"))]
1415 "TARGET_64BIT && TARGET_DOUBLE_FLOAT
1416 && (register_operand (operands[0], DFmode)
1417 || reg_or_0_operand (operands[1], DFmode))"
1418 { return riscv_output_move (operands[0], operands[1]); }
1419 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1420 (set_attr "mode" "DF")])
1422 (define_insn "*movdf_softfloat"
1423 [(set (match_operand:DF 0 "nonimmediate_operand" "= r,r, m")
1424 (match_operand:DF 1 "move_operand" " rG,m,rG"))]
1425 "!TARGET_DOUBLE_FLOAT
1426 && (register_operand (operands[0], DFmode)
1427 || reg_or_0_operand (operands[1], DFmode))"
1428 { return riscv_output_move (operands[0], operands[1]); }
1429 [(set_attr "move_type" "move,load,store")
1430 (set_attr "mode" "DF")])
1433 [(set (match_operand:MOVE64 0 "nonimmediate_operand")
1434 (match_operand:MOVE64 1 "move_operand"))]
1436 && riscv_split_64bit_move_p (operands[0], operands[1])"
1439 riscv_split_doubleword_move (operands[0], operands[1]);
1443 (define_expand "movmemsi"
1444 [(parallel [(set (match_operand:BLK 0 "general_operand")
1445 (match_operand:BLK 1 "general_operand"))
1446 (use (match_operand:SI 2 ""))
1447 (use (match_operand:SI 3 "const_int_operand"))])]
1450 if (riscv_expand_block_move (operands[0], operands[1], operands[2]))
1456 ;; Expand in-line code to clear the instruction cache between operand[0] and
1458 (define_expand "clear_cache"
1459 [(match_operand 0 "pmode_register_operand")
1460 (match_operand 1 "pmode_register_operand")]
1463 #ifdef ICACHE_FLUSH_FUNC
1464 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, ICACHE_FLUSH_FUNC),
1465 LCT_NORMAL, VOIDmode, operands[0], Pmode,
1466 operands[1], Pmode, const0_rtx, Pmode);
1468 emit_insn (gen_fence_i ());
1473 (define_insn "fence"
1474 [(unspec_volatile [(const_int 0)] UNSPECV_FENCE)]
1478 (define_insn "fence_i"
1479 [(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)]
1484 ;; ....................
1488 ;; ....................
1490 ;; Use a QImode shift count, to avoid generating sign or zero extend
1491 ;; instructions for shift counts, and to avoid dropping subregs.
1492 ;; expand_shift_1 can do this automatically when SHIFT_COUNT_TRUNCATED is
1493 ;; defined, but use of that is discouraged.
1495 (define_insn "<optab>si3"
1496 [(set (match_operand:SI 0 "register_operand" "= r")
1498 (match_operand:SI 1 "register_operand" " r")
1499 (match_operand:QI 2 "arith_operand" " rI")))]
1502 if (GET_CODE (operands[2]) == CONST_INT)
1503 operands[2] = GEN_INT (INTVAL (operands[2])
1504 & (GET_MODE_BITSIZE (SImode) - 1));
1506 return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2";
1508 [(set_attr "type" "shift")
1509 (set_attr "mode" "SI")])
1511 (define_insn_and_split "*<optab>si3_mask"
1512 [(set (match_operand:SI 0 "register_operand" "= r")
1514 (match_operand:SI 1 "register_operand" " r")
1517 (match_operand:SI 2 "register_operand" "r")
1518 (match_operand 3 "const_int_operand")) 0)))]
1519 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1520 == GET_MODE_BITSIZE (SImode)-1"
1524 (any_shift:SI (match_dup 1)
1526 "operands[2] = gen_lowpart (QImode, operands[2]);"
1527 [(set_attr "type" "shift")
1528 (set_attr "mode" "SI")])
1530 (define_insn_and_split "*<optab>si3_mask_1"
1531 [(set (match_operand:SI 0 "register_operand" "= r")
1533 (match_operand:SI 1 "register_operand" " r")
1536 (match_operand:DI 2 "register_operand" "r")
1537 (match_operand 3 "const_int_operand")) 0)))]
1539 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1540 == GET_MODE_BITSIZE (SImode)-1"
1544 (any_shift:SI (match_dup 1)
1546 "operands[2] = gen_lowpart (QImode, operands[2]);"
1547 [(set_attr "type" "shift")
1548 (set_attr "mode" "SI")])
1550 (define_insn "<optab>di3"
1551 [(set (match_operand:DI 0 "register_operand" "= r")
1553 (match_operand:DI 1 "register_operand" " r")
1554 (match_operand:QI 2 "arith_operand" " rI")))]
1557 if (GET_CODE (operands[2]) == CONST_INT)
1558 operands[2] = GEN_INT (INTVAL (operands[2])
1559 & (GET_MODE_BITSIZE (DImode) - 1));
1561 return "<insn>%i2\t%0,%1,%2";
1563 [(set_attr "type" "shift")
1564 (set_attr "mode" "DI")])
1566 (define_insn_and_split "*<optab>di3_mask"
1567 [(set (match_operand:DI 0 "register_operand" "= r")
1569 (match_operand:DI 1 "register_operand" " r")
1572 (match_operand:SI 2 "register_operand" "r")
1573 (match_operand 3 "const_int_operand")) 0)))]
1575 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1576 == GET_MODE_BITSIZE (DImode)-1"
1580 (any_shift:DI (match_dup 1)
1582 "operands[2] = gen_lowpart (QImode, operands[2]);"
1583 [(set_attr "type" "shift")
1584 (set_attr "mode" "DI")])
1586 (define_insn_and_split "*<optab>di3_mask_1"
1587 [(set (match_operand:DI 0 "register_operand" "= r")
1589 (match_operand:DI 1 "register_operand" " r")
1592 (match_operand:DI 2 "register_operand" "r")
1593 (match_operand 3 "const_int_operand")) 0)))]
1595 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1596 == GET_MODE_BITSIZE (DImode)-1"
1600 (any_shift:DI (match_dup 1)
1602 "operands[2] = gen_lowpart (QImode, operands[2]);"
1603 [(set_attr "type" "shift")
1604 (set_attr "mode" "DI")])
1606 (define_insn "*<optab>si3_extend"
1607 [(set (match_operand:DI 0 "register_operand" "= r")
1609 (any_shift:SI (match_operand:SI 1 "register_operand" " r")
1610 (match_operand:QI 2 "arith_operand" " rI"))))]
1613 if (GET_CODE (operands[2]) == CONST_INT)
1614 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1616 return "<insn>%i2w\t%0,%1,%2";
1618 [(set_attr "type" "shift")
1619 (set_attr "mode" "SI")])
1621 (define_insn_and_split "*<optab>si3_extend_mask"
1622 [(set (match_operand:DI 0 "register_operand" "= r")
1625 (match_operand:SI 1 "register_operand" " r")
1628 (match_operand:SI 2 "register_operand" " r")
1629 (match_operand 3 "const_int_operand")) 0))))]
1631 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1632 == GET_MODE_BITSIZE (SImode)-1"
1637 (any_shift:SI (match_dup 1)
1639 "operands[2] = gen_lowpart (QImode, operands[2]);"
1640 [(set_attr "type" "shift")
1641 (set_attr "mode" "SI")])
1643 (define_insn_and_split "*<optab>si3_extend_mask_1"
1644 [(set (match_operand:DI 0 "register_operand" "= r")
1647 (match_operand:SI 1 "register_operand" " r")
1650 (match_operand:DI 2 "register_operand" " r")
1651 (match_operand 3 "const_int_operand")) 0))))]
1653 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1654 == GET_MODE_BITSIZE (SImode)-1"
1659 (any_shift:SI (match_dup 1)
1661 "operands[2] = gen_lowpart (QImode, operands[2]);"
1662 [(set_attr "type" "shift")
1663 (set_attr "mode" "SI")])
1665 ;; Non-canonical, but can be formed by ree when combine is not successful at
1666 ;; producing one of the two canonical patterns below.
1667 (define_insn "*lshrsi3_zero_extend_1"
1668 [(set (match_operand:DI 0 "register_operand" "=r")
1670 (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
1671 (match_operand 2 "const_int_operand"))))]
1672 "TARGET_64BIT && (INTVAL (operands[2]) & 0x1f) > 0"
1674 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1676 return "srliw\t%0,%1,%2";
1678 [(set_attr "type" "shift")
1679 (set_attr "mode" "SI")])
1681 ;; Canonical form for a zero-extend of a logical right shift.
1682 (define_insn "*lshrsi3_zero_extend_2"
1683 [(set (match_operand:DI 0 "register_operand" "=r")
1684 (zero_extract:DI (match_operand:DI 1 "register_operand" " r")
1685 (match_operand 2 "const_int_operand")
1686 (match_operand 3 "const_int_operand")))]
1687 "(TARGET_64BIT && (INTVAL (operands[3]) > 0)
1688 && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))"
1690 return "srliw\t%0,%1,%3";
1692 [(set_attr "type" "shift")
1693 (set_attr "mode" "SI")])
1695 ;; Canonical form for a zero-extend of a logical right shift when the
1696 ;; shift count is 31.
1697 (define_insn "*lshrsi3_zero_extend_3"
1698 [(set (match_operand:DI 0 "register_operand" "=r")
1699 (lt:DI (match_operand:SI 1 "register_operand" " r")
1703 return "srliw\t%0,%1,31";
1705 [(set_attr "type" "shift")
1706 (set_attr "mode" "SI")])
1709 ;; ....................
1711 ;; CONDITIONAL BRANCHES
1713 ;; ....................
1715 ;; Conditional branches
1717 (define_insn "*branch_order<mode>"
1720 (match_operator 1 "order_operator"
1721 [(match_operand:X 2 "register_operand" "r")
1722 (match_operand:X 3 "register_operand" "r")])
1723 (label_ref (match_operand 0 "" ""))
1727 [(set_attr "type" "branch")
1728 (set_attr "mode" "none")])
1730 (define_insn "*branch_zero<mode>"
1733 (match_operator 1 "signed_order_operator"
1734 [(match_operand:X 2 "register_operand" "r")
1736 (label_ref (match_operand 0 "" ""))
1740 [(set_attr "type" "branch")
1741 (set_attr "mode" "none")])
1743 ;; Used to implement built-in functions.
1744 (define_expand "condjump"
1746 (if_then_else (match_operand 0)
1747 (label_ref (match_operand 1))
1750 (define_expand "cbranch<mode>4"
1752 (if_then_else (match_operator 0 "comparison_operator"
1753 [(match_operand:BR 1 "register_operand")
1754 (match_operand:BR 2 "nonmemory_operand")])
1755 (label_ref (match_operand 3 ""))
1759 riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1760 operands[1], operands[2]);
1764 (define_expand "cbranch<mode>4"
1766 (if_then_else (match_operator 0 "fp_branch_comparison"
1767 [(match_operand:ANYF 1 "register_operand")
1768 (match_operand:ANYF 2 "register_operand")])
1769 (label_ref (match_operand 3 ""))
1773 riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1774 operands[1], operands[2]);
1778 (define_insn_and_split "*branch_on_bit<X:mode>"
1781 (match_operator 0 "equality_operator"
1782 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1784 (match_operand 3 "branch_on_bit_operand"))
1786 (label_ref (match_operand 1))
1788 (clobber (match_scratch:X 4 "=&r"))]
1793 (ashift:X (match_dup 2) (match_dup 3)))
1796 (match_op_dup 0 [(match_dup 4) (const_int 0)])
1797 (label_ref (match_operand 1))
1800 int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]);
1801 operands[3] = GEN_INT (shift);
1803 if (GET_CODE (operands[0]) == EQ)
1804 operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx);
1806 operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx);
1809 (define_insn_and_split "*branch_on_bit_range<X:mode>"
1812 (match_operator 0 "equality_operator"
1813 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1814 (match_operand 3 "branch_on_bit_operand")
1817 (label_ref (match_operand 1))
1819 (clobber (match_scratch:X 4 "=&r"))]
1824 (ashift:X (match_dup 2) (match_dup 3)))
1827 (match_op_dup 0 [(match_dup 4) (const_int 0)])
1828 (label_ref (match_operand 1))
1831 operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]));
1835 ;; ....................
1837 ;; SETTING A REGISTER FROM A COMPARISON
1839 ;; ....................
1841 ;; Destination is always set in SI mode.
1843 (define_expand "cstore<mode>4"
1844 [(set (match_operand:SI 0 "register_operand")
1845 (match_operator:SI 1 "order_operator"
1846 [(match_operand:GPR 2 "register_operand")
1847 (match_operand:GPR 3 "nonmemory_operand")]))]
1850 riscv_expand_int_scc (operands[0], GET_CODE (operands[1]), operands[2],
1855 (define_expand "cstore<mode>4"
1856 [(set (match_operand:SI 0 "register_operand")
1857 (match_operator:SI 1 "fp_scc_comparison"
1858 [(match_operand:ANYF 2 "register_operand")
1859 (match_operand:ANYF 3 "register_operand")]))]
1862 riscv_expand_float_scc (operands[0], GET_CODE (operands[1]), operands[2],
1867 (define_insn "*cstore<ANYF:mode><X:mode>4"
1868 [(set (match_operand:X 0 "register_operand" "=r")
1869 (match_operator:X 1 "fp_native_comparison"
1870 [(match_operand:ANYF 2 "register_operand" " f")
1871 (match_operand:ANYF 3 "register_operand" " f")]))]
1873 "f%C1.<fmt>\t%0,%2,%3"
1874 [(set_attr "type" "fcmp")
1875 (set_attr "mode" "<UNITMODE>")])
1877 (define_insn "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4"
1878 [(set (match_operand:X 0 "register_operand" "=r")
1880 [(match_operand:ANYF 1 "register_operand" " f")
1881 (match_operand:ANYF 2 "register_operand" " f")]
1883 (clobber (match_scratch:X 3 "=&r"))]
1885 "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3"
1886 [(set_attr "type" "fcmp")
1887 (set_attr "mode" "<UNITMODE>")
1888 (set (attr "length") (const_int 12))])
1890 (define_insn "*seq_zero_<X:mode><GPR:mode>"
1891 [(set (match_operand:GPR 0 "register_operand" "=r")
1892 (eq:GPR (match_operand:X 1 "register_operand" " r")
1896 [(set_attr "type" "slt")
1897 (set_attr "mode" "<X:MODE>")])
1899 (define_insn "*sne_zero_<X:mode><GPR:mode>"
1900 [(set (match_operand:GPR 0 "register_operand" "=r")
1901 (ne:GPR (match_operand:X 1 "register_operand" " r")
1905 [(set_attr "type" "slt")
1906 (set_attr "mode" "<X:MODE>")])
1908 (define_insn "*sgt<u>_<X:mode><GPR:mode>"
1909 [(set (match_operand:GPR 0 "register_operand" "= r")
1910 (any_gt:GPR (match_operand:X 1 "register_operand" " r")
1911 (match_operand:X 2 "reg_or_0_operand" " rJ")))]
1914 [(set_attr "type" "slt")
1915 (set_attr "mode" "<X:MODE>")])
1917 (define_insn "*sge<u>_<X:mode><GPR:mode>"
1918 [(set (match_operand:GPR 0 "register_operand" "=r")
1919 (any_ge:GPR (match_operand:X 1 "register_operand" " r")
1922 "slt%i2<u>\t%0,zero,%1"
1923 [(set_attr "type" "slt")
1924 (set_attr "mode" "<MODE>")])
1926 (define_insn "*slt<u>_<X:mode><GPR:mode>"
1927 [(set (match_operand:GPR 0 "register_operand" "= r")
1928 (any_lt:GPR (match_operand:X 1 "register_operand" " r")
1929 (match_operand:X 2 "arith_operand" " rI")))]
1931 "slt%i2<u>\t%0,%1,%2"
1932 [(set_attr "type" "slt")
1933 (set_attr "mode" "<MODE>")])
1935 (define_insn "*sle<u>_<X:mode><GPR:mode>"
1936 [(set (match_operand:GPR 0 "register_operand" "=r")
1937 (any_le:GPR (match_operand:X 1 "register_operand" " r")
1938 (match_operand:X 2 "sle_operand" "")))]
1941 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
1942 return "slt%i2<u>\t%0,%1,%2";
1944 [(set_attr "type" "slt")
1945 (set_attr "mode" "<MODE>")])
1948 ;; ....................
1950 ;; UNCONDITIONAL BRANCHES
1952 ;; ....................
1954 ;; Unconditional branches.
1958 (label_ref (match_operand 0 "" "")))]
1961 [(set_attr "type" "jump")
1962 (set_attr "mode" "none")])
1964 (define_expand "indirect_jump"
1965 [(set (pc) (match_operand 0 "register_operand"))]
1968 operands[0] = force_reg (Pmode, operands[0]);
1969 if (Pmode == SImode)
1970 emit_jump_insn (gen_indirect_jumpsi (operands[0]));
1972 emit_jump_insn (gen_indirect_jumpdi (operands[0]));
1976 (define_insn "indirect_jump<mode>"
1977 [(set (pc) (match_operand:P 0 "register_operand" "l"))]
1980 [(set_attr "type" "jump")
1981 (set_attr "mode" "none")])
1983 (define_expand "tablejump"
1984 [(set (pc) (match_operand 0 "register_operand" ""))
1985 (use (label_ref (match_operand 1 "" "")))]
1988 if (CASE_VECTOR_PC_RELATIVE)
1989 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1990 gen_rtx_LABEL_REF (Pmode, operands[1]),
1991 NULL_RTX, 0, OPTAB_DIRECT);
1993 if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode)
1994 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
1996 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
2000 (define_insn "tablejump<mode>"
2001 [(set (pc) (match_operand:GPR 0 "register_operand" "l"))
2002 (use (label_ref (match_operand 1 "" "")))]
2005 [(set_attr "type" "jump")
2006 (set_attr "mode" "none")])
2009 ;; ....................
2011 ;; Function prologue/epilogue
2013 ;; ....................
2016 (define_expand "prologue"
2020 riscv_expand_prologue ();
2024 ;; Block any insns from being moved before this point, since the
2025 ;; profiling call to mcount can use various registers that aren't
2026 ;; saved or used to pass arguments.
2028 (define_insn "blockage"
2029 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2032 [(set_attr "type" "ghost")
2033 (set_attr "mode" "none")])
2035 (define_expand "epilogue"
2039 riscv_expand_epilogue (false);
2043 (define_expand "sibcall_epilogue"
2047 riscv_expand_epilogue (true);
2051 ;; Trivial return. Make it look like a normal return insn as that
2052 ;; allows jump optimizations to work better.
2054 (define_expand "return"
2056 "riscv_can_use_return_insn ()"
2059 (define_insn "simple_return"
2063 return riscv_output_return ();
2065 [(set_attr "type" "jump")
2066 (set_attr "mode" "none")])
2070 (define_insn "simple_return_internal"
2072 (use (match_operand 0 "pmode_register_operand" ""))]
2075 [(set_attr "type" "jump")
2076 (set_attr "mode" "none")])
2078 ;; This is used in compiling the unwind routines.
2079 (define_expand "eh_return"
2080 [(use (match_operand 0 "general_operand"))]
2083 if (GET_MODE (operands[0]) != word_mode)
2084 operands[0] = convert_to_mode (word_mode, operands[0], 0);
2086 emit_insn (gen_eh_set_lr_di (operands[0]));
2088 emit_insn (gen_eh_set_lr_si (operands[0]));
2092 ;; Clobber the return address on the stack. We can't expand this
2093 ;; until we know where it will be put in the stack frame.
2095 (define_insn "eh_set_lr_si"
2096 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2097 (clobber (match_scratch:SI 1 "=&r"))]
2101 (define_insn "eh_set_lr_di"
2102 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2103 (clobber (match_scratch:DI 1 "=&r"))]
2108 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
2109 (clobber (match_scratch 1))]
2113 riscv_set_return_address (operands[0], operands[1]);
2118 ;; ....................
2122 ;; ....................
2124 (define_expand "sibcall"
2125 [(parallel [(call (match_operand 0 "")
2126 (match_operand 1 ""))
2127 (use (match_operand 2 "")) ;; next_arg_reg
2128 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
2131 rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2132 emit_call_insn (gen_sibcall_internal (target, operands[1]));
2136 (define_insn "sibcall_internal"
2137 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U"))
2138 (match_operand 1 "" ""))]
2139 "SIBLING_CALL_P (insn)"
2144 [(set_attr "type" "call")])
2146 (define_expand "sibcall_value"
2147 [(parallel [(set (match_operand 0 "")
2148 (call (match_operand 1 "")
2149 (match_operand 2 "")))
2150 (use (match_operand 3 ""))])] ;; next_arg_reg
2153 rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2154 emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2]));
2158 (define_insn "sibcall_value_internal"
2159 [(set (match_operand 0 "" "")
2160 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U"))
2161 (match_operand 2 "" "")))]
2162 "SIBLING_CALL_P (insn)"
2167 [(set_attr "type" "call")])
2169 (define_expand "call"
2170 [(parallel [(call (match_operand 0 "")
2171 (match_operand 1 ""))
2172 (use (match_operand 2 "")) ;; next_arg_reg
2173 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
2176 rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2177 emit_call_insn (gen_call_internal (target, operands[1]));
2181 (define_insn "call_internal"
2182 [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U"))
2183 (match_operand 1 "" ""))
2184 (clobber (reg:SI RETURN_ADDR_REGNUM))]
2190 [(set_attr "type" "call")])
2192 (define_expand "call_value"
2193 [(parallel [(set (match_operand 0 "")
2194 (call (match_operand 1 "")
2195 (match_operand 2 "")))
2196 (use (match_operand 3 ""))])] ;; next_arg_reg
2199 rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2200 emit_call_insn (gen_call_value_internal (operands[0], target, operands[2]));
2204 (define_insn "call_value_internal"
2205 [(set (match_operand 0 "" "")
2206 (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U"))
2207 (match_operand 2 "" "")))
2208 (clobber (reg:SI RETURN_ADDR_REGNUM))]
2214 [(set_attr "type" "call")])
2216 ;; Call subroutine returning any type.
2218 (define_expand "untyped_call"
2219 [(parallel [(call (match_operand 0 "")
2221 (match_operand 1 "")
2222 (match_operand 2 "")])]
2227 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2229 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2231 rtx set = XVECEXP (operands[2], 0, i);
2232 riscv_emit_move (SET_DEST (set), SET_SRC (set));
2235 emit_insn (gen_blockage ());
2243 [(set_attr "type" "nop")
2244 (set_attr "mode" "none")])
2247 [(trap_if (const_int 1) (const_int 0))]
2251 (define_insn "gpr_save"
2252 [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_SAVE)
2253 (clobber (reg:SI T0_REGNUM))
2254 (clobber (reg:SI T1_REGNUM))]
2256 { return riscv_output_gpr_save (INTVAL (operands[0])); })
2258 (define_insn "gpr_restore"
2259 [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_RESTORE)]
2261 "tail\t__riscv_restore_%0")
2263 (define_insn "gpr_restore_return"
2265 (use (match_operand 0 "pmode_register_operand" ""))
2270 (define_insn "riscv_frflags"
2271 [(set (match_operand:SI 0 "register_operand" "=r")
2272 (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))]
2276 (define_insn "riscv_fsflags"
2277 [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)]
2281 (define_insn "riscv_mret"
2282 [(unspec_volatile [(const_int 0)] UNSPECV_MRET)]
2286 (define_insn "stack_tie<mode>"
2287 [(set (mem:BLK (scratch))
2288 (unspec:BLK [(match_operand:X 0 "register_operand" "r")
2289 (match_operand:X 1 "register_operand" "r")]
2293 [(set_attr "length" "0")]
2297 (include "peephole.md")
2299 (include "generic.md")