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.
64 ;; Blockage and synchronization.
71 [(RETURN_ADDR_REGNUM 1)
84 (include "predicates.md")
85 (include "constraints.md")
87 ;; ....................
91 ;; ....................
93 (define_attr "got" "unset,xgot_high,load"
94 (const_string "unset"))
96 ;; Classification of moves, extensions and truncations. Most values
97 ;; are as for "type" (see below) but there are also the following
98 ;; move-specific values:
100 ;; andi a single ANDI instruction
101 ;; shift_shift a shift left followed by a shift right
103 ;; This attribute is used to determine the instruction's length and
104 ;; scheduling type. For doubleword moves, the attribute always describes
105 ;; the split instructions; in some cases, it is more appropriate for the
106 ;; scheduling type to be "multi" instead.
107 (define_attr "move_type"
108 "unknown,load,fpload,store,fpstore,mtc,mfc,move,fmove,
109 const,logical,arith,andi,shift_shift"
110 (const_string "unknown"))
112 ;; Main data type used by the insn
113 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
114 (const_string "unknown"))
116 ;; True if the main data type is twice the size of a word.
117 (define_attr "dword_mode" "no,yes"
118 (cond [(and (eq_attr "mode" "DI,DF")
119 (eq (symbol_ref "TARGET_64BIT") (const_int 0)))
122 (and (eq_attr "mode" "TI,TF")
123 (ne (symbol_ref "TARGET_64BIT") (const_int 0)))
124 (const_string "yes")]
125 (const_string "no")))
127 ;; Classification of each insn.
128 ;; branch conditional branch
129 ;; jump unconditional jump
130 ;; call unconditional call
131 ;; load load instruction(s)
132 ;; fpload floating point load
133 ;; store store instruction(s)
134 ;; fpstore floating point store
135 ;; mtc transfer to coprocessor
136 ;; mfc transfer from coprocessor
137 ;; const load constant
138 ;; arith integer arithmetic instructions
139 ;; logical integer logical instructions
140 ;; shift integer shift instructions
141 ;; slt set less than instructions
142 ;; imul integer multiply
143 ;; idiv integer divide
144 ;; move integer register move (addi rd, rs1, 0)
145 ;; fmove floating point register move
146 ;; fadd floating point add/subtract
147 ;; fmul floating point multiply
148 ;; fmadd floating point multiply-add
149 ;; fdiv floating point divide
150 ;; fcmp floating point compare
151 ;; fcvt floating point convert
152 ;; fsqrt floating point square root
153 ;; multi multiword sequence (or user asm statements)
155 ;; ghost an instruction that produces no real code
157 "unknown,branch,jump,call,load,fpload,store,fpstore,
158 mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul,
159 fmadd,fdiv,fcmp,fcvt,fsqrt,multi,nop,ghost"
160 (cond [(eq_attr "got" "load") (const_string "load")
162 ;; If a doubleword move uses these expensive instructions,
163 ;; it is usually better to schedule them in the same way
164 ;; as the singleword form, rather than as "multi".
165 (eq_attr "move_type" "load") (const_string "load")
166 (eq_attr "move_type" "fpload") (const_string "fpload")
167 (eq_attr "move_type" "store") (const_string "store")
168 (eq_attr "move_type" "fpstore") (const_string "fpstore")
169 (eq_attr "move_type" "mtc") (const_string "mtc")
170 (eq_attr "move_type" "mfc") (const_string "mfc")
172 ;; These types of move are always single insns.
173 (eq_attr "move_type" "fmove") (const_string "fmove")
174 (eq_attr "move_type" "arith") (const_string "arith")
175 (eq_attr "move_type" "logical") (const_string "logical")
176 (eq_attr "move_type" "andi") (const_string "logical")
178 ;; These types of move are always split.
179 (eq_attr "move_type" "shift_shift")
180 (const_string "multi")
182 ;; These types of move are split for doubleword modes only.
183 (and (eq_attr "move_type" "move,const")
184 (eq_attr "dword_mode" "yes"))
185 (const_string "multi")
186 (eq_attr "move_type" "move") (const_string "move")
187 (eq_attr "move_type" "const") (const_string "const")]
188 (const_string "unknown")))
190 ;; Length of instruction in bytes.
191 (define_attr "length" ""
193 ;; Branches further than +/- 4 KiB require two instructions.
194 (eq_attr "type" "branch")
195 (if_then_else (and (le (minus (match_dup 0) (pc)) (const_int 4088))
196 (le (minus (pc) (match_dup 0)) (const_int 4092)))
200 ;; Conservatively assume calls take two instructions (AUIPC + JALR).
201 ;; The linker will opportunistically relax the sequence to JAL.
202 (eq_attr "type" "call") (const_int 8)
204 ;; "Ghost" instructions occupy no space.
205 (eq_attr "type" "ghost") (const_int 0)
207 (eq_attr "got" "load") (const_int 8)
209 (eq_attr "type" "fcmp") (const_int 8)
211 ;; SHIFT_SHIFTs are decomposed into two separate instructions.
212 (eq_attr "move_type" "shift_shift")
215 ;; Check for doubleword moves that are decomposed into two
217 (and (eq_attr "move_type" "mtc,mfc,move")
218 (eq_attr "dword_mode" "yes"))
221 ;; Doubleword CONST{,N} moves are split into two word
223 (and (eq_attr "move_type" "const")
224 (eq_attr "dword_mode" "yes"))
225 (symbol_ref "riscv_split_const_insns (operands[1]) * 4")
227 ;; Otherwise, constants, loads and stores are handled by external
229 (eq_attr "move_type" "load,fpload")
230 (symbol_ref "riscv_load_store_insns (operands[1], insn) * 4")
231 (eq_attr "move_type" "store,fpstore")
232 (symbol_ref "riscv_load_store_insns (operands[0], insn) * 4")
235 ;; Is copying of this instruction disallowed?
236 (define_attr "cannot_copy" "no,yes" (const_string "no"))
238 ;; Describe a user's asm statement.
239 (define_asm_attributes
240 [(set_attr "type" "multi")])
242 ;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
243 ;; from the same template.
244 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
246 ;; This mode iterator allows :P to be used for patterns that operate on
247 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
248 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
250 ;; Likewise, but for XLEN-sized quantities.
251 (define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")])
253 ;; Branches operate on XLEN-sized quantities, but for RV64 we accept
254 ;; QImode values so we can force zero-extension.
255 (define_mode_iterator BR [(QI "TARGET_64BIT") SI (DI "TARGET_64BIT")])
257 ;; 32-bit moves for which we provide move patterns.
258 (define_mode_iterator MOVE32 [SI])
260 ;; 64-bit modes for which we provide move patterns.
261 (define_mode_iterator MOVE64 [DI DF])
263 ;; Iterator for sub-32-bit integer modes.
264 (define_mode_iterator SHORT [QI HI])
266 ;; Iterator for HImode constant generation.
267 (define_mode_iterator HISI [HI SI])
269 ;; Iterator for QImode extension patterns.
270 (define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")])
272 ;; Iterator for extending loads.
273 (define_mode_iterator ZERO_EXTEND_LOAD [QI HI (SI "TARGET_64BIT")])
275 ;; Iterator for hardware integer modes narrower than XLEN.
276 (define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")])
278 ;; Iterator for hardware-supported integer modes.
279 (define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")])
281 ;; Iterator for hardware-supported floating-point modes.
282 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
283 (DF "TARGET_DOUBLE_FLOAT")])
285 ;; This attribute gives the length suffix for a sign- or zero-extension
287 (define_mode_attr size [(QI "b") (HI "h")])
289 ;; Mode attributes for loads.
290 (define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")])
292 ;; Instruction names for stores.
293 (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")])
295 ;; This attribute gives the best constraint to use for registers of
297 (define_mode_attr reg [(SI "d") (DI "d") (CC "d")])
299 ;; This attribute gives the format suffix for floating-point operations.
300 (define_mode_attr fmt [(SF "s") (DF "d")])
302 ;; This attribute gives the integer suffix for floating-point conversions.
303 (define_mode_attr ifmt [(SI "w") (DI "l")])
305 ;; This attribute gives the format suffix for atomic memory operations.
306 (define_mode_attr amo [(SI "w") (DI "d")])
308 ;; This attribute gives the upper-case mode name for one unit of a
309 ;; floating-point mode.
310 (define_mode_attr UNITMODE [(SF "SF") (DF "DF")])
312 ;; This attribute gives the integer mode that has half the size of
313 ;; the controlling mode.
314 (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
316 ;; Iterator and attributes for floating-point rounding instructions.
317 (define_int_iterator RINT [UNSPEC_LRINT UNSPEC_LROUND])
318 (define_int_attr rint_pattern [(UNSPEC_LRINT "rint") (UNSPEC_LROUND "round")])
319 (define_int_attr rint_rm [(UNSPEC_LRINT "dyn") (UNSPEC_LROUND "rmm")])
321 ;; Iterator and attributes for quiet comparisons.
322 (define_int_iterator QUIET_COMPARISON [UNSPEC_FLT_QUIET UNSPEC_FLE_QUIET])
323 (define_int_attr quiet_pattern [(UNSPEC_FLT_QUIET "lt") (UNSPEC_FLE_QUIET "le")])
325 ;; This code iterator allows signed and unsigned widening multiplications
326 ;; to use the same template.
327 (define_code_iterator any_extend [sign_extend zero_extend])
329 ;; This code iterator allows the two right shift instructions to be
330 ;; generated from the same template.
331 (define_code_iterator any_shiftrt [ashiftrt lshiftrt])
333 ;; This code iterator allows the three shift instructions to be generated
334 ;; from the same template.
335 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
337 ;; This code iterator allows the three bitwise instructions to be generated
338 ;; from the same template.
339 (define_code_iterator any_bitwise [and ior xor])
341 ;; This code iterator allows unsigned and signed division to be generated
342 ;; from the same template.
343 (define_code_iterator any_div [div udiv mod umod])
345 ;; This code iterator allows unsigned and signed modulus to be generated
346 ;; from the same template.
347 (define_code_iterator any_mod [mod umod])
349 ;; These code iterators allow the signed and unsigned scc operations to use
350 ;; the same template.
351 (define_code_iterator any_gt [gt gtu])
352 (define_code_iterator any_ge [ge geu])
353 (define_code_iterator any_lt [lt ltu])
354 (define_code_iterator any_le [le leu])
356 ;; <u> expands to an empty string when doing a signed operation and
357 ;; "u" when doing an unsigned operation.
358 (define_code_attr u [(sign_extend "") (zero_extend "u")
364 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
365 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
367 ;; <optab> expands to the name of the optab for a particular code.
368 (define_code_attr optab [(ashift "ashl")
385 ;; <insn> expands to the name of the insn that implements a particular code.
386 (define_code_attr insn [(ashift "sll")
399 ;; Ghost instructions produce no real code and introduce no hazards.
400 ;; They exist purely to express an effect on dataflow.
401 (define_insn_reservation "ghost" 0
402 (eq_attr "type" "ghost")
406 ;; ....................
410 ;; ....................
413 (define_insn "add<mode>3"
414 [(set (match_operand:ANYF 0 "register_operand" "=f")
415 (plus:ANYF (match_operand:ANYF 1 "register_operand" " f")
416 (match_operand:ANYF 2 "register_operand" " f")))]
418 "fadd.<fmt>\t%0,%1,%2"
419 [(set_attr "type" "fadd")
420 (set_attr "mode" "<UNITMODE>")])
422 (define_insn "addsi3"
423 [(set (match_operand:SI 0 "register_operand" "=r,r")
424 (plus:SI (match_operand:SI 1 "register_operand" " r,r")
425 (match_operand:SI 2 "arith_operand" " r,I")))]
427 { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
428 [(set_attr "type" "arith")
429 (set_attr "mode" "SI")])
431 (define_insn "adddi3"
432 [(set (match_operand:DI 0 "register_operand" "=r,r")
433 (plus:DI (match_operand:DI 1 "register_operand" " r,r")
434 (match_operand:DI 2 "arith_operand" " r,I")))]
437 [(set_attr "type" "arith")
438 (set_attr "mode" "DI")])
440 (define_insn "*addsi3_extended"
441 [(set (match_operand:DI 0 "register_operand" "=r,r")
443 (plus:SI (match_operand:SI 1 "register_operand" " r,r")
444 (match_operand:SI 2 "arith_operand" " r,I"))))]
447 [(set_attr "type" "arith")
448 (set_attr "mode" "SI")])
450 (define_insn "*addsi3_extended2"
451 [(set (match_operand:DI 0 "register_operand" "=r,r")
453 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" " r,r")
454 (match_operand:DI 2 "arith_operand" " r,I"))
458 [(set_attr "type" "arith")
459 (set_attr "mode" "SI")])
462 ;; ....................
466 ;; ....................
469 (define_insn "sub<mode>3"
470 [(set (match_operand:ANYF 0 "register_operand" "=f")
471 (minus:ANYF (match_operand:ANYF 1 "register_operand" " f")
472 (match_operand:ANYF 2 "register_operand" " f")))]
474 "fsub.<fmt>\t%0,%1,%2"
475 [(set_attr "type" "fadd")
476 (set_attr "mode" "<UNITMODE>")])
478 (define_insn "subdi3"
479 [(set (match_operand:DI 0 "register_operand" "= r")
480 (minus:DI (match_operand:DI 1 "reg_or_0_operand" " rJ")
481 (match_operand:DI 2 "register_operand" " r")))]
484 [(set_attr "type" "arith")
485 (set_attr "mode" "DI")])
487 (define_insn "subsi3"
488 [(set (match_operand:SI 0 "register_operand" "= r")
489 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
490 (match_operand:SI 2 "register_operand" " r")))]
492 { return TARGET_64BIT ? "subw\t%0,%z1,%2" : "sub\t%0,%z1,%2"; }
493 [(set_attr "type" "arith")
494 (set_attr "mode" "SI")])
496 (define_insn "*subsi3_extended"
497 [(set (match_operand:DI 0 "register_operand" "= r")
499 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
500 (match_operand:SI 2 "register_operand" " r"))))]
503 [(set_attr "type" "arith")
504 (set_attr "mode" "SI")])
506 (define_insn "*subsi3_extended2"
507 [(set (match_operand:DI 0 "register_operand" "=r")
509 (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" " r")
510 (match_operand:DI 2 "register_operand" " r"))
514 [(set_attr "type" "arith")
515 (set_attr "mode" "SI")])
518 ;; ....................
522 ;; ....................
525 (define_insn "mul<mode>3"
526 [(set (match_operand:ANYF 0 "register_operand" "=f")
527 (mult:ANYF (match_operand:ANYF 1 "register_operand" " f")
528 (match_operand:ANYF 2 "register_operand" " f")))]
530 "fmul.<fmt>\t%0,%1,%2"
531 [(set_attr "type" "fmul")
532 (set_attr "mode" "<UNITMODE>")])
534 (define_insn "mulsi3"
535 [(set (match_operand:SI 0 "register_operand" "=r")
536 (mult:SI (match_operand:SI 1 "register_operand" " r")
537 (match_operand:SI 2 "register_operand" " r")))]
539 { return TARGET_64BIT ? "mulw\t%0,%1,%2" : "mul\t%0,%1,%2"; }
540 [(set_attr "type" "imul")
541 (set_attr "mode" "SI")])
543 (define_insn "muldi3"
544 [(set (match_operand:DI 0 "register_operand" "=r")
545 (mult:DI (match_operand:DI 1 "register_operand" " r")
546 (match_operand:DI 2 "register_operand" " r")))]
547 "TARGET_MUL && TARGET_64BIT"
549 [(set_attr "type" "imul")
550 (set_attr "mode" "DI")])
552 (define_insn "*mulsi3_extended"
553 [(set (match_operand:DI 0 "register_operand" "=r")
555 (mult:SI (match_operand:SI 1 "register_operand" " r")
556 (match_operand:SI 2 "register_operand" " r"))))]
557 "TARGET_MUL && TARGET_64BIT"
559 [(set_attr "type" "imul")
560 (set_attr "mode" "SI")])
562 (define_insn "*mulsi3_extended2"
563 [(set (match_operand:DI 0 "register_operand" "=r")
565 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" " r")
566 (match_operand:DI 2 "register_operand" " r"))
568 "TARGET_MUL && TARGET_64BIT"
570 [(set_attr "type" "imul")
571 (set_attr "mode" "SI")])
574 ;; ........................
576 ;; MULTIPLICATION HIGH-PART
578 ;; ........................
582 (define_expand "<u>mulditi3"
583 [(set (match_operand:TI 0 "register_operand")
584 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
585 (any_extend:TI (match_operand:DI 2 "register_operand"))))]
586 "TARGET_MUL && TARGET_64BIT"
588 rtx low = gen_reg_rtx (DImode);
589 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
591 rtx high = gen_reg_rtx (DImode);
592 emit_insn (gen_<u>muldi3_highpart (high, operands[1], operands[2]));
594 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
595 emit_move_insn (gen_highpart (DImode, operands[0]), high);
599 (define_insn "<u>muldi3_highpart"
600 [(set (match_operand:DI 0 "register_operand" "=r")
603 (mult:TI (any_extend:TI
604 (match_operand:DI 1 "register_operand" " r"))
606 (match_operand:DI 2 "register_operand" " r")))
608 "TARGET_MUL && TARGET_64BIT"
610 [(set_attr "type" "imul")
611 (set_attr "mode" "DI")])
613 (define_expand "usmulditi3"
614 [(set (match_operand:TI 0 "register_operand")
615 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand"))
616 (sign_extend:TI (match_operand:DI 2 "register_operand"))))]
617 "TARGET_MUL && TARGET_64BIT"
619 rtx low = gen_reg_rtx (DImode);
620 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
622 rtx high = gen_reg_rtx (DImode);
623 emit_insn (gen_usmuldi3_highpart (high, operands[1], operands[2]));
625 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
626 emit_move_insn (gen_highpart (DImode, operands[0]), high);
630 (define_insn "usmuldi3_highpart"
631 [(set (match_operand:DI 0 "register_operand" "=r")
634 (mult:TI (zero_extend:TI
635 (match_operand:DI 1 "register_operand" "r"))
637 (match_operand:DI 2 "register_operand" " r")))
639 "TARGET_MUL && TARGET_64BIT"
641 [(set_attr "type" "imul")
642 (set_attr "mode" "DI")])
644 (define_expand "<u>mulsidi3"
645 [(set (match_operand:DI 0 "register_operand" "=r")
646 (mult:DI (any_extend:DI
647 (match_operand:SI 1 "register_operand" " r"))
649 (match_operand:SI 2 "register_operand" " r"))))]
650 "TARGET_MUL && !TARGET_64BIT"
652 rtx temp = gen_reg_rtx (SImode);
653 emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
654 emit_insn (gen_<u>mulsi3_highpart (riscv_subword (operands[0], true),
655 operands[1], operands[2]));
656 emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
660 (define_insn "<u>mulsi3_highpart"
661 [(set (match_operand:SI 0 "register_operand" "=r")
664 (mult:DI (any_extend:DI
665 (match_operand:SI 1 "register_operand" " r"))
667 (match_operand:SI 2 "register_operand" " r")))
669 "TARGET_MUL && !TARGET_64BIT"
671 [(set_attr "type" "imul")
672 (set_attr "mode" "SI")])
675 (define_expand "usmulsidi3"
676 [(set (match_operand:DI 0 "register_operand" "=r")
677 (mult:DI (zero_extend:DI
678 (match_operand:SI 1 "register_operand" " r"))
680 (match_operand:SI 2 "register_operand" " r"))))]
681 "TARGET_MUL && !TARGET_64BIT"
683 rtx temp = gen_reg_rtx (SImode);
684 emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
685 emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true),
686 operands[1], operands[2]));
687 emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
691 (define_insn "usmulsi3_highpart"
692 [(set (match_operand:SI 0 "register_operand" "=r")
695 (mult:DI (zero_extend:DI
696 (match_operand:SI 1 "register_operand" " r"))
698 (match_operand:SI 2 "register_operand" " r")))
700 "TARGET_MUL && !TARGET_64BIT"
702 [(set_attr "type" "imul")
703 (set_attr "mode" "SI")])
706 ;; ....................
708 ;; DIVISION and REMAINDER
710 ;; ....................
713 (define_insn "<optab>si3"
714 [(set (match_operand:SI 0 "register_operand" "=r")
715 (any_div:SI (match_operand:SI 1 "register_operand" " r")
716 (match_operand:SI 2 "register_operand" " r")))]
718 { return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2"; }
719 [(set_attr "type" "idiv")
720 (set_attr "mode" "SI")])
722 (define_insn "<optab>di3"
723 [(set (match_operand:DI 0 "register_operand" "=r")
724 (any_div:DI (match_operand:DI 1 "register_operand" " r")
725 (match_operand:DI 2 "register_operand" " r")))]
726 "TARGET_DIV && TARGET_64BIT"
727 "<insn>%i2\t%0,%1,%2"
728 [(set_attr "type" "idiv")
729 (set_attr "mode" "DI")])
731 (define_insn "*<optab>si3_extended"
732 [(set (match_operand:DI 0 "register_operand" "=r")
734 (any_div:SI (match_operand:SI 1 "register_operand" " r")
735 (match_operand:SI 2 "register_operand" " r"))))]
736 "TARGET_DIV && TARGET_64BIT"
737 "<insn>%i2w\t%0,%1,%2"
738 [(set_attr "type" "idiv")
739 (set_attr "mode" "DI")])
741 (define_insn "div<mode>3"
742 [(set (match_operand:ANYF 0 "register_operand" "=f")
743 (div:ANYF (match_operand:ANYF 1 "register_operand" " f")
744 (match_operand:ANYF 2 "register_operand" " f")))]
745 "TARGET_HARD_FLOAT && TARGET_FDIV"
746 "fdiv.<fmt>\t%0,%1,%2"
747 [(set_attr "type" "fdiv")
748 (set_attr "mode" "<UNITMODE>")])
751 ;; ....................
755 ;; ....................
757 (define_insn "sqrt<mode>2"
758 [(set (match_operand:ANYF 0 "register_operand" "=f")
759 (sqrt:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
760 "TARGET_HARD_FLOAT && TARGET_FDIV"
762 return "fsqrt.<fmt>\t%0,%1";
764 [(set_attr "type" "fsqrt")
765 (set_attr "mode" "<UNITMODE>")])
767 ;; Floating point multiply accumulate instructions.
770 (define_insn "fma<mode>4"
771 [(set (match_operand:ANYF 0 "register_operand" "=f")
772 (fma:ANYF (match_operand:ANYF 1 "register_operand" " f")
773 (match_operand:ANYF 2 "register_operand" " f")
774 (match_operand:ANYF 3 "register_operand" " f")))]
776 "fmadd.<fmt>\t%0,%1,%2,%3"
777 [(set_attr "type" "fmadd")
778 (set_attr "mode" "<UNITMODE>")])
781 (define_insn "fms<mode>4"
782 [(set (match_operand:ANYF 0 "register_operand" "=f")
783 (fma:ANYF (match_operand:ANYF 1 "register_operand" " f")
784 (match_operand:ANYF 2 "register_operand" " f")
785 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
787 "fmsub.<fmt>\t%0,%1,%2,%3"
788 [(set_attr "type" "fmadd")
789 (set_attr "mode" "<UNITMODE>")])
792 (define_insn "fnms<mode>4"
793 [(set (match_operand:ANYF 0 "register_operand" "=f")
795 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
796 (match_operand:ANYF 2 "register_operand" " f")
797 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
799 "fnmadd.<fmt>\t%0,%1,%2,%3"
800 [(set_attr "type" "fmadd")
801 (set_attr "mode" "<UNITMODE>")])
804 (define_insn "fnma<mode>4"
805 [(set (match_operand:ANYF 0 "register_operand" "=f")
807 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
808 (match_operand:ANYF 2 "register_operand" " f")
809 (match_operand:ANYF 3 "register_operand" " f")))]
811 "fnmsub.<fmt>\t%0,%1,%2,%3"
812 [(set_attr "type" "fmadd")
813 (set_attr "mode" "<UNITMODE>")])
815 ;; -(-a * b - c), modulo signed zeros
816 (define_insn "*fma<mode>4"
817 [(set (match_operand:ANYF 0 "register_operand" "=f")
820 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
821 (match_operand:ANYF 2 "register_operand" " f")
822 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
823 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
824 "fmadd.<fmt>\t%0,%1,%2,%3"
825 [(set_attr "type" "fmadd")
826 (set_attr "mode" "<UNITMODE>")])
828 ;; -(-a * b + c), modulo signed zeros
829 (define_insn "*fms<mode>4"
830 [(set (match_operand:ANYF 0 "register_operand" "=f")
833 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
834 (match_operand:ANYF 2 "register_operand" " f")
835 (match_operand:ANYF 3 "register_operand" " f"))))]
836 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
837 "fmsub.<fmt>\t%0,%1,%2,%3"
838 [(set_attr "type" "fmadd")
839 (set_attr "mode" "<UNITMODE>")])
841 ;; -(a * b + c), modulo signed zeros
842 (define_insn "*fnms<mode>4"
843 [(set (match_operand:ANYF 0 "register_operand" "=f")
846 (match_operand:ANYF 1 "register_operand" " f")
847 (match_operand:ANYF 2 "register_operand" " f")
848 (match_operand:ANYF 3 "register_operand" " f"))))]
849 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
850 "fnmadd.<fmt>\t%0,%1,%2,%3"
851 [(set_attr "type" "fmadd")
852 (set_attr "mode" "<UNITMODE>")])
854 ;; -(a * b - c), modulo signed zeros
855 (define_insn "*fnma<mode>4"
856 [(set (match_operand:ANYF 0 "register_operand" "=f")
859 (match_operand:ANYF 1 "register_operand" " f")
860 (match_operand:ANYF 2 "register_operand" " f")
861 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
862 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
863 "fnmsub.<fmt>\t%0,%1,%2,%3"
864 [(set_attr "type" "fmadd")
865 (set_attr "mode" "<UNITMODE>")])
868 ;; ....................
872 ;; ....................
874 (define_insn "abs<mode>2"
875 [(set (match_operand:ANYF 0 "register_operand" "=f")
876 (abs:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
879 [(set_attr "type" "fmove")
880 (set_attr "mode" "<UNITMODE>")])
882 (define_insn "copysign<mode>3"
883 [(set (match_operand:ANYF 0 "register_operand" "=f")
884 (unspec:ANYF [(match_operand:ANYF 1 "register_operand" " f")
885 (match_operand:ANYF 2 "register_operand" " f")]
888 "fsgnj.<fmt>\t%0,%1,%2"
889 [(set_attr "type" "fmove")
890 (set_attr "mode" "<UNITMODE>")])
892 (define_insn "neg<mode>2"
893 [(set (match_operand:ANYF 0 "register_operand" "=f")
894 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
897 [(set_attr "type" "fmove")
898 (set_attr "mode" "<UNITMODE>")])
901 ;; ....................
905 ;; ....................
907 (define_insn "smin<mode>3"
908 [(set (match_operand:ANYF 0 "register_operand" "=f")
909 (smin:ANYF (match_operand:ANYF 1 "register_operand" " f")
910 (match_operand:ANYF 2 "register_operand" " f")))]
912 "fmin.<fmt>\t%0,%1,%2"
913 [(set_attr "type" "fmove")
914 (set_attr "mode" "<UNITMODE>")])
916 (define_insn "smax<mode>3"
917 [(set (match_operand:ANYF 0 "register_operand" "=f")
918 (smax:ANYF (match_operand:ANYF 1 "register_operand" " f")
919 (match_operand:ANYF 2 "register_operand" " f")))]
921 "fmax.<fmt>\t%0,%1,%2"
922 [(set_attr "type" "fmove")
923 (set_attr "mode" "<UNITMODE>")])
926 ;; ....................
930 ;; ....................
933 ;; For RV64, we don't expose the SImode operations to the rtl expanders,
934 ;; but SImode versions exist for combine.
936 (define_insn "<optab><mode>3"
937 [(set (match_operand:X 0 "register_operand" "=r,r")
938 (any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
939 (match_operand:X 2 "arith_operand" " r,I")))]
941 "<insn>%i2\t%0,%1,%2"
942 [(set_attr "type" "logical")
943 (set_attr "mode" "<MODE>")])
945 (define_insn "*<optab>si3_internal"
946 [(set (match_operand:SI 0 "register_operand" "=r,r")
947 (any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r")
948 (match_operand:SI 2 "arith_operand" " r,I")))]
950 "<insn>%i2\t%0,%1,%2"
951 [(set_attr "type" "logical")
952 (set_attr "mode" "SI")])
954 (define_insn "one_cmpl<mode>2"
955 [(set (match_operand:X 0 "register_operand" "=r")
956 (not:X (match_operand:X 1 "register_operand" " r")))]
959 [(set_attr "type" "logical")
960 (set_attr "mode" "<MODE>")])
962 (define_insn "*one_cmplsi2_internal"
963 [(set (match_operand:SI 0 "register_operand" "=r")
964 (not:SI (match_operand:SI 1 "register_operand" " r")))]
967 [(set_attr "type" "logical")
968 (set_attr "mode" "SI")])
971 ;; ....................
975 ;; ....................
977 (define_insn "truncdfsf2"
978 [(set (match_operand:SF 0 "register_operand" "=f")
980 (match_operand:DF 1 "register_operand" " f")))]
981 "TARGET_DOUBLE_FLOAT"
983 [(set_attr "type" "fcvt")
984 (set_attr "mode" "SF")])
987 ;; ....................
991 ;; ....................
995 (define_insn_and_split "zero_extendsidi2"
996 [(set (match_operand:DI 0 "register_operand" "=r,r")
998 (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
1003 "&& reload_completed && REG_P (operands[1])"
1005 (ashift:DI (match_dup 1) (const_int 32)))
1007 (lshiftrt:DI (match_dup 0) (const_int 32)))]
1008 { operands[1] = gen_lowpart (DImode, operands[1]); }
1009 [(set_attr "move_type" "shift_shift,load")
1010 (set_attr "mode" "DI")])
1012 (define_insn_and_split "zero_extendhi<GPR:mode>2"
1013 [(set (match_operand:GPR 0 "register_operand" "=r,r")
1015 (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
1020 "&& reload_completed && REG_P (operands[1])"
1022 (ashift:GPR (match_dup 1) (match_dup 2)))
1024 (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
1026 operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
1027 operands[2] = GEN_INT(GET_MODE_BITSIZE(<GPR:MODE>mode) - 16);
1029 [(set_attr "move_type" "shift_shift,load")
1030 (set_attr "mode" "<GPR:MODE>")])
1032 (define_insn "zero_extendqi<SUPERQI:mode>2"
1033 [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
1034 (zero_extend:SUPERQI
1035 (match_operand:QI 1 "nonimmediate_operand" " r,m")))]
1040 [(set_attr "move_type" "andi,load")
1041 (set_attr "mode" "<SUPERQI:MODE>")])
1044 ;; ....................
1048 ;; ....................
1050 (define_insn "extendsidi2"
1051 [(set (match_operand:DI 0 "register_operand" "=r,r")
1053 (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
1058 [(set_attr "move_type" "move,load")
1059 (set_attr "mode" "DI")])
1061 (define_insn_and_split "extend<SHORT:mode><SUPERQI:mode>2"
1062 [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
1063 (sign_extend:SUPERQI
1064 (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
1068 l<SHORT:size>\t%0,%1"
1069 "&& reload_completed && REG_P (operands[1])"
1070 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1071 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
1073 operands[0] = gen_lowpart (SImode, operands[0]);
1074 operands[1] = gen_lowpart (SImode, operands[1]);
1075 operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
1076 - GET_MODE_BITSIZE (<SHORT:MODE>mode));
1078 [(set_attr "move_type" "shift_shift,load")
1079 (set_attr "mode" "SI")])
1081 (define_insn "extendsfdf2"
1082 [(set (match_operand:DF 0 "register_operand" "=f")
1084 (match_operand:SF 1 "register_operand" " f")))]
1085 "TARGET_DOUBLE_FLOAT"
1087 [(set_attr "type" "fcvt")
1088 (set_attr "mode" "DF")])
1091 ;; ....................
1095 ;; ....................
1097 (define_insn "fix_trunc<ANYF:mode><GPR:mode>2"
1098 [(set (match_operand:GPR 0 "register_operand" "=r")
1100 (match_operand:ANYF 1 "register_operand" " f")))]
1102 "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,rtz"
1103 [(set_attr "type" "fcvt")
1104 (set_attr "mode" "<ANYF:MODE>")])
1106 (define_insn "fixuns_trunc<ANYF:mode><GPR:mode>2"
1107 [(set (match_operand:GPR 0 "register_operand" "=r")
1109 (match_operand:ANYF 1 "register_operand" " f")))]
1111 "fcvt.<GPR:ifmt>u.<ANYF:fmt> %0,%1,rtz"
1112 [(set_attr "type" "fcvt")
1113 (set_attr "mode" "<ANYF:MODE>")])
1115 (define_insn "float<GPR:mode><ANYF:mode>2"
1116 [(set (match_operand:ANYF 0 "register_operand" "= f")
1118 (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1120 "fcvt.<ANYF:fmt>.<GPR:ifmt>\t%0,%z1"
1121 [(set_attr "type" "fcvt")
1122 (set_attr "mode" "<ANYF:MODE>")])
1124 (define_insn "floatuns<GPR:mode><ANYF:mode>2"
1125 [(set (match_operand:ANYF 0 "register_operand" "= f")
1126 (unsigned_float:ANYF
1127 (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1129 "fcvt.<ANYF:fmt>.<GPR:ifmt>u\t%0,%z1"
1130 [(set_attr "type" "fcvt")
1131 (set_attr "mode" "<ANYF:MODE>")])
1133 (define_insn "l<rint_pattern><ANYF:mode><GPR:mode>2"
1134 [(set (match_operand:GPR 0 "register_operand" "=r")
1136 [(match_operand:ANYF 1 "register_operand" " f")]
1139 "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,<rint_rm>"
1140 [(set_attr "type" "fcvt")
1141 (set_attr "mode" "<ANYF:MODE>")])
1144 ;; ....................
1148 ;; ....................
1150 ;; Lower-level instructions for loading an address from the GOT.
1151 ;; We could use MEMs, but an unspec gives more optimization
1154 (define_insn "got_load<mode>"
1155 [(set (match_operand:P 0 "register_operand" "=r")
1157 [(match_operand:P 1 "symbolic_operand" "")]
1161 [(set_attr "got" "load")
1162 (set_attr "mode" "<MODE>")])
1164 (define_insn "tls_add_tp_le<mode>"
1165 [(set (match_operand:P 0 "register_operand" "=r")
1167 [(match_operand:P 1 "register_operand" "r")
1168 (match_operand:P 2 "register_operand" "r")
1169 (match_operand:P 3 "symbolic_operand" "")]
1172 "add\t%0,%1,%2,%%tprel_add(%3)"
1173 [(set_attr "type" "arith")
1174 (set_attr "mode" "<MODE>")])
1176 (define_insn "got_load_tls_gd<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 "got_load_tls_ie<mode>"
1187 [(set (match_operand:P 0 "register_operand" "=r")
1189 [(match_operand:P 1 "symbolic_operand" "")]
1193 [(set_attr "got" "load")
1194 (set_attr "mode" "<MODE>")])
1196 (define_insn "auipc<mode>"
1197 [(set (match_operand:P 0 "register_operand" "=r")
1199 [(match_operand:P 1 "symbolic_operand" "")
1200 (match_operand:P 2 "const_int_operand")
1204 ".LA%2: auipc\t%0,%h1"
1205 [(set_attr "type" "arith")
1206 (set_attr "cannot_copy" "yes")])
1208 ;; Instructions for adding the low 12 bits of an address to a register.
1209 ;; Operand 2 is the address: riscv_print_operand works out which relocation
1210 ;; should be applied.
1212 (define_insn "*low<mode>"
1213 [(set (match_operand:P 0 "register_operand" "=r")
1214 (lo_sum:P (match_operand:P 1 "register_operand" " r")
1215 (match_operand:P 2 "symbolic_operand" "")))]
1218 [(set_attr "type" "arith")
1219 (set_attr "mode" "<MODE>")])
1221 ;; Allow combine to split complex const_int load sequences, using operand 2
1222 ;; to store the intermediate results. See move_operand for details.
1224 [(set (match_operand:GPR 0 "register_operand")
1225 (match_operand:GPR 1 "splittable_const_int_operand"))
1226 (clobber (match_operand:GPR 2 "register_operand"))]
1230 riscv_move_integer (operands[2], operands[0], INTVAL (operands[1]));
1234 ;; Likewise, for symbolic operands.
1236 [(set (match_operand:P 0 "register_operand")
1237 (match_operand:P 1))
1238 (clobber (match_operand:P 2 "register_operand"))]
1239 "riscv_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
1240 [(set (match_dup 0) (match_dup 3))]
1242 riscv_split_symbol (operands[2], operands[1],
1243 MAX_MACHINE_MODE, &operands[3]);
1246 ;; 64-bit integer moves
1248 (define_expand "movdi"
1249 [(set (match_operand:DI 0 "")
1250 (match_operand:DI 1 ""))]
1253 if (riscv_legitimize_move (DImode, operands[0], operands[1]))
1257 (define_insn "*movdi_32bit"
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,i,m,r,*J*r,*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 (define_insn "*movdi_64bit"
1268 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, *f,*f,*r,*f,*m")
1269 (match_operand:DI 1 "move_operand" " r,T,m,rJ,*r*J,*m,*f,*f,*f"))]
1271 && (register_operand (operands[0], DImode)
1272 || reg_or_0_operand (operands[1], DImode))"
1273 { return riscv_output_move (operands[0], operands[1]); }
1274 [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1275 (set_attr "mode" "DI")])
1277 ;; 32-bit Integer moves
1279 (define_expand "mov<mode>"
1280 [(set (match_operand:MOVE32 0 "")
1281 (match_operand:MOVE32 1 ""))]
1284 if (riscv_legitimize_move (<MODE>mode, operands[0], operands[1]))
1288 (define_insn "*movsi_internal"
1289 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, *f,*f,*r,*m")
1290 (match_operand:SI 1 "move_operand" " r,T,m,rJ,*r*J,*m,*f,*f"))]
1291 "(register_operand (operands[0], SImode)
1292 || reg_or_0_operand (operands[1], SImode))"
1293 { return riscv_output_move (operands[0], operands[1]); }
1294 [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore")
1295 (set_attr "mode" "SI")])
1297 ;; 16-bit Integer moves
1299 ;; Unlike most other insns, the move insns can't be split with
1300 ;; different predicates, because register spilling and other parts of
1301 ;; the compiler, have memoized the insn number already.
1302 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
1304 (define_expand "movhi"
1305 [(set (match_operand:HI 0 "")
1306 (match_operand:HI 1 ""))]
1309 if (riscv_legitimize_move (HImode, operands[0], operands[1]))
1313 (define_insn "*movhi_internal"
1314 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r, m, *f,*r")
1315 (match_operand:HI 1 "move_operand" " r,T,m,rJ,*r*J,*f"))]
1316 "(register_operand (operands[0], HImode)
1317 || reg_or_0_operand (operands[1], HImode))"
1318 { return riscv_output_move (operands[0], operands[1]); }
1319 [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1320 (set_attr "mode" "HI")])
1322 ;; HImode constant generation; see riscv_move_integer for details.
1323 ;; si+si->hi without truncation is legal because of
1324 ;; TARGET_TRULY_NOOP_TRUNCATION.
1326 (define_insn "*add<mode>hi3"
1327 [(set (match_operand:HI 0 "register_operand" "=r,r")
1328 (plus:HI (match_operand:HISI 1 "register_operand" " r,r")
1329 (match_operand:HISI 2 "arith_operand" " r,I")))]
1331 { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
1332 [(set_attr "type" "arith")
1333 (set_attr "mode" "HI")])
1335 (define_insn "*xor<mode>hi3"
1336 [(set (match_operand:HI 0 "register_operand" "=r,r")
1337 (xor:HI (match_operand:HISI 1 "register_operand" " r,r")
1338 (match_operand:HISI 2 "arith_operand" " r,I")))]
1341 [(set_attr "type" "logical")
1342 (set_attr "mode" "HI")])
1344 ;; 8-bit Integer moves
1346 (define_expand "movqi"
1347 [(set (match_operand:QI 0 "")
1348 (match_operand:QI 1 ""))]
1351 if (riscv_legitimize_move (QImode, operands[0], operands[1]))
1355 (define_insn "*movqi_internal"
1356 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r, m, *f,*r")
1357 (match_operand:QI 1 "move_operand" " r,I,m,rJ,*r*J,*f"))]
1358 "(register_operand (operands[0], QImode)
1359 || reg_or_0_operand (operands[1], QImode))"
1360 { return riscv_output_move (operands[0], operands[1]); }
1361 [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1362 (set_attr "mode" "QI")])
1364 ;; 32-bit floating point moves
1366 (define_expand "movsf"
1367 [(set (match_operand:SF 0 "")
1368 (match_operand:SF 1 ""))]
1371 if (riscv_legitimize_move (SFmode, operands[0], operands[1]))
1375 (define_insn "*movsf_hardfloat"
1376 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r, *r,*r,*m")
1377 (match_operand:SF 1 "move_operand" " f,G,m,f,G,*r,*f,*G*r,*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" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1383 (set_attr "mode" "SF")])
1385 (define_insn "*movsf_softfloat"
1386 [(set (match_operand:SF 0 "nonimmediate_operand" "= r,r,m")
1387 (match_operand:SF 1 "move_operand" " Gr,m,r"))]
1389 && (register_operand (operands[0], SFmode)
1390 || reg_or_0_operand (operands[1], SFmode))"
1391 { return riscv_output_move (operands[0], operands[1]); }
1392 [(set_attr "move_type" "move,load,store")
1393 (set_attr "mode" "SF")])
1395 ;; 64-bit floating point moves
1397 (define_expand "movdf"
1398 [(set (match_operand:DF 0 "")
1399 (match_operand:DF 1 ""))]
1402 if (riscv_legitimize_move (DFmode, operands[0], operands[1]))
1406 ;; In RV32, we lack fmv.x.d and fmv.d.x. Go through memory instead.
1407 ;; (However, we can still use fcvt.d.w to zero a floating-point register.)
1408 (define_insn "*movdf_hardfloat_rv32"
1409 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m, *r,*r,*m")
1410 (match_operand:DF 1 "move_operand" " f,G,m,f,G,*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,move,load,store")
1416 (set_attr "mode" "DF")])
1418 (define_insn "*movdf_hardfloat_rv64"
1419 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r, *r,*r,*m")
1420 (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r,*f,*r*G,*m,*r"))]
1421 "TARGET_64BIT && 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" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1426 (set_attr "mode" "DF")])
1428 (define_insn "*movdf_softfloat"
1429 [(set (match_operand:DF 0 "nonimmediate_operand" "= r,r, m")
1430 (match_operand:DF 1 "move_operand" " rG,m,rG"))]
1431 "!TARGET_DOUBLE_FLOAT
1432 && (register_operand (operands[0], DFmode)
1433 || reg_or_0_operand (operands[1], DFmode))"
1434 { return riscv_output_move (operands[0], operands[1]); }
1435 [(set_attr "move_type" "move,load,store")
1436 (set_attr "mode" "DF")])
1439 [(set (match_operand:MOVE64 0 "nonimmediate_operand")
1440 (match_operand:MOVE64 1 "move_operand"))]
1442 && riscv_split_64bit_move_p (operands[0], operands[1])"
1445 riscv_split_doubleword_move (operands[0], operands[1]);
1449 (define_expand "movmemsi"
1450 [(parallel [(set (match_operand:BLK 0 "general_operand")
1451 (match_operand:BLK 1 "general_operand"))
1452 (use (match_operand:SI 2 ""))
1453 (use (match_operand:SI 3 "const_int_operand"))])]
1456 if (riscv_expand_block_move (operands[0], operands[1], operands[2]))
1462 ;; Expand in-line code to clear the instruction cache between operand[0] and
1464 (define_expand "clear_cache"
1465 [(match_operand 0 "pmode_register_operand")
1466 (match_operand 1 "pmode_register_operand")]
1469 #ifdef ICACHE_FLUSH_FUNC
1470 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, ICACHE_FLUSH_FUNC),
1471 LCT_NORMAL, VOIDmode, operands[0], Pmode,
1472 operands[1], Pmode, const0_rtx, Pmode);
1474 emit_insn (gen_fence_i ());
1479 (define_insn "fence"
1480 [(unspec_volatile [(const_int 0)] UNSPECV_FENCE)]
1484 (define_insn "fence_i"
1485 [(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)]
1490 ;; ....................
1494 ;; ....................
1496 ;; Use a QImode shift count, to avoid generating sign or zero extend
1497 ;; instructions for shift counts, and to avoid dropping subregs.
1498 ;; expand_shift_1 can do this automatically when SHIFT_COUNT_TRUNCATED is
1499 ;; defined, but use of that is discouraged.
1501 (define_insn "<optab>si3"
1502 [(set (match_operand:SI 0 "register_operand" "= r")
1504 (match_operand:SI 1 "register_operand" " r")
1505 (match_operand:QI 2 "arith_operand" " rI")))]
1508 if (GET_CODE (operands[2]) == CONST_INT)
1509 operands[2] = GEN_INT (INTVAL (operands[2])
1510 & (GET_MODE_BITSIZE (SImode) - 1));
1512 return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2";
1514 [(set_attr "type" "shift")
1515 (set_attr "mode" "SI")])
1517 (define_insn_and_split "*<optab>si3_mask"
1518 [(set (match_operand:SI 0 "register_operand" "= r")
1520 (match_operand:SI 1 "register_operand" " r")
1523 (match_operand:SI 2 "register_operand" "r")
1524 (match_operand 3 "const_int_operand")) 0)))]
1525 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1526 == GET_MODE_BITSIZE (SImode)-1"
1530 (any_shift:SI (match_dup 1)
1532 "operands[2] = gen_lowpart (QImode, operands[2]);"
1533 [(set_attr "type" "shift")
1534 (set_attr "mode" "SI")])
1536 (define_insn_and_split "*<optab>si3_mask_1"
1537 [(set (match_operand:SI 0 "register_operand" "= r")
1539 (match_operand:SI 1 "register_operand" " r")
1542 (match_operand:DI 2 "register_operand" "r")
1543 (match_operand 3 "const_int_operand")) 0)))]
1545 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1546 == GET_MODE_BITSIZE (SImode)-1"
1550 (any_shift:SI (match_dup 1)
1552 "operands[2] = gen_lowpart (QImode, operands[2]);"
1553 [(set_attr "type" "shift")
1554 (set_attr "mode" "SI")])
1556 (define_insn "<optab>di3"
1557 [(set (match_operand:DI 0 "register_operand" "= r")
1559 (match_operand:DI 1 "register_operand" " r")
1560 (match_operand:QI 2 "arith_operand" " rI")))]
1563 if (GET_CODE (operands[2]) == CONST_INT)
1564 operands[2] = GEN_INT (INTVAL (operands[2])
1565 & (GET_MODE_BITSIZE (DImode) - 1));
1567 return "<insn>%i2\t%0,%1,%2";
1569 [(set_attr "type" "shift")
1570 (set_attr "mode" "DI")])
1572 (define_insn_and_split "*<optab>di3_mask"
1573 [(set (match_operand:DI 0 "register_operand" "= r")
1575 (match_operand:DI 1 "register_operand" " r")
1578 (match_operand:SI 2 "register_operand" "r")
1579 (match_operand 3 "const_int_operand")) 0)))]
1581 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1582 == GET_MODE_BITSIZE (DImode)-1"
1586 (any_shift:DI (match_dup 1)
1588 "operands[2] = gen_lowpart (QImode, operands[2]);"
1589 [(set_attr "type" "shift")
1590 (set_attr "mode" "DI")])
1592 (define_insn_and_split "*<optab>di3_mask_1"
1593 [(set (match_operand:DI 0 "register_operand" "= r")
1595 (match_operand:DI 1 "register_operand" " r")
1598 (match_operand:DI 2 "register_operand" "r")
1599 (match_operand 3 "const_int_operand")) 0)))]
1601 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1602 == GET_MODE_BITSIZE (DImode)-1"
1606 (any_shift:DI (match_dup 1)
1608 "operands[2] = gen_lowpart (QImode, operands[2]);"
1609 [(set_attr "type" "shift")
1610 (set_attr "mode" "DI")])
1612 (define_insn "*<optab>si3_extend"
1613 [(set (match_operand:DI 0 "register_operand" "= r")
1615 (any_shift:SI (match_operand:SI 1 "register_operand" " r")
1616 (match_operand:QI 2 "arith_operand" " rI"))))]
1619 if (GET_CODE (operands[2]) == CONST_INT)
1620 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1622 return "<insn>%i2w\t%0,%1,%2";
1624 [(set_attr "type" "shift")
1625 (set_attr "mode" "SI")])
1627 (define_insn_and_split "*<optab>si3_extend_mask"
1628 [(set (match_operand:DI 0 "register_operand" "= r")
1631 (match_operand:SI 1 "register_operand" " r")
1634 (match_operand:SI 2 "register_operand" " r")
1635 (match_operand 3 "const_int_operand")) 0))))]
1637 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1638 == GET_MODE_BITSIZE (SImode)-1"
1643 (any_shift:SI (match_dup 1)
1645 "operands[2] = gen_lowpart (QImode, operands[2]);"
1646 [(set_attr "type" "shift")
1647 (set_attr "mode" "SI")])
1649 (define_insn_and_split "*<optab>si3_extend_mask_1"
1650 [(set (match_operand:DI 0 "register_operand" "= r")
1653 (match_operand:SI 1 "register_operand" " r")
1656 (match_operand:DI 2 "register_operand" " r")
1657 (match_operand 3 "const_int_operand")) 0))))]
1659 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1660 == GET_MODE_BITSIZE (SImode)-1"
1665 (any_shift:SI (match_dup 1)
1667 "operands[2] = gen_lowpart (QImode, operands[2]);"
1668 [(set_attr "type" "shift")
1669 (set_attr "mode" "SI")])
1671 ;; Non-canonical, but can be formed by ree when combine is not successful at
1672 ;; producing one of the two canonical patterns below.
1673 (define_insn "*lshrsi3_zero_extend_1"
1674 [(set (match_operand:DI 0 "register_operand" "=r")
1676 (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
1677 (match_operand 2 "const_int_operand"))))]
1678 "TARGET_64BIT && (INTVAL (operands[2]) & 0x1f) > 0"
1680 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1682 return "srliw\t%0,%1,%2";
1684 [(set_attr "type" "shift")
1685 (set_attr "mode" "SI")])
1687 ;; Canonical form for a zero-extend of a logical right shift.
1688 (define_insn "*lshrsi3_zero_extend_2"
1689 [(set (match_operand:DI 0 "register_operand" "=r")
1690 (zero_extract:DI (match_operand:DI 1 "register_operand" " r")
1691 (match_operand 2 "const_int_operand")
1692 (match_operand 3 "const_int_operand")))]
1693 "(TARGET_64BIT && (INTVAL (operands[3]) > 0)
1694 && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))"
1696 return "srliw\t%0,%1,%3";
1698 [(set_attr "type" "shift")
1699 (set_attr "mode" "SI")])
1701 ;; Canonical form for a zero-extend of a logical right shift when the
1702 ;; shift count is 31.
1703 (define_insn "*lshrsi3_zero_extend_3"
1704 [(set (match_operand:DI 0 "register_operand" "=r")
1705 (lt:DI (match_operand:SI 1 "register_operand" " r")
1709 return "srliw\t%0,%1,31";
1711 [(set_attr "type" "shift")
1712 (set_attr "mode" "SI")])
1714 ;; Handle AND with 2^N-1 for N from 12 to XLEN. This can be split into
1715 ;; two logical shifts. Otherwise it requires 3 instructions: lui,
1716 ;; xor/addi/srli, and.
1718 [(set (match_operand:GPR 0 "register_operand")
1719 (and:GPR (match_operand:GPR 1 "register_operand")
1720 (match_operand:GPR 2 "p2m1_shift_operand")))]
1723 (ashift:GPR (match_dup 1) (match_dup 2)))
1725 (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
1727 operands[2] = GEN_INT (BITS_PER_WORD
1728 - exact_log2 (INTVAL (operands[2]) + 1));
1731 ;; Handle AND with 0xF...F0...0 where there are 32 to 63 zeros. This can be
1732 ;; split into two shifts. Otherwise it requires 3 instructions: li, sll, and.
1734 [(set (match_operand:DI 0 "register_operand")
1735 (and:DI (match_operand:DI 1 "register_operand")
1736 (match_operand:DI 2 "high_mask_shift_operand")))]
1739 (lshiftrt:DI (match_dup 1) (match_dup 2)))
1741 (ashift:DI (match_dup 0) (match_dup 2)))]
1743 operands[2] = GEN_INT (ctz_hwi (INTVAL (operands[2])));
1747 ;; ....................
1749 ;; CONDITIONAL BRANCHES
1751 ;; ....................
1753 ;; Conditional branches
1755 (define_insn "*branch_order<mode>"
1758 (match_operator 1 "order_operator"
1759 [(match_operand:X 2 "register_operand" "r")
1760 (match_operand:X 3 "register_operand" "r")])
1761 (label_ref (match_operand 0 "" ""))
1765 [(set_attr "type" "branch")
1766 (set_attr "mode" "none")])
1768 (define_insn "*branch_zero<mode>"
1771 (match_operator 1 "signed_order_operator"
1772 [(match_operand:X 2 "register_operand" "r")
1774 (label_ref (match_operand 0 "" ""))
1778 [(set_attr "type" "branch")
1779 (set_attr "mode" "none")])
1781 ;; Used to implement built-in functions.
1782 (define_expand "condjump"
1784 (if_then_else (match_operand 0)
1785 (label_ref (match_operand 1))
1788 (define_expand "cbranch<mode>4"
1790 (if_then_else (match_operator 0 "comparison_operator"
1791 [(match_operand:BR 1 "register_operand")
1792 (match_operand:BR 2 "nonmemory_operand")])
1793 (label_ref (match_operand 3 ""))
1797 riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1798 operands[1], operands[2]);
1802 (define_expand "cbranch<mode>4"
1804 (if_then_else (match_operator 0 "fp_branch_comparison"
1805 [(match_operand:ANYF 1 "register_operand")
1806 (match_operand:ANYF 2 "register_operand")])
1807 (label_ref (match_operand 3 ""))
1811 riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1812 operands[1], operands[2]);
1816 (define_insn_and_split "*branch_on_bit<X:mode>"
1819 (match_operator 0 "equality_operator"
1820 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1822 (match_operand 3 "branch_on_bit_operand"))
1824 (label_ref (match_operand 1))
1826 (clobber (match_scratch:X 4 "=&r"))]
1831 (ashift:X (match_dup 2) (match_dup 3)))
1834 (match_op_dup 0 [(match_dup 4) (const_int 0)])
1835 (label_ref (match_operand 1))
1838 int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]);
1839 operands[3] = GEN_INT (shift);
1841 if (GET_CODE (operands[0]) == EQ)
1842 operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx);
1844 operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx);
1847 (define_insn_and_split "*branch_on_bit_range<X:mode>"
1850 (match_operator 0 "equality_operator"
1851 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1852 (match_operand 3 "branch_on_bit_operand")
1855 (label_ref (match_operand 1))
1857 (clobber (match_scratch:X 4 "=&r"))]
1862 (ashift:X (match_dup 2) (match_dup 3)))
1865 (match_op_dup 0 [(match_dup 4) (const_int 0)])
1866 (label_ref (match_operand 1))
1869 operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]));
1873 ;; ....................
1875 ;; SETTING A REGISTER FROM A COMPARISON
1877 ;; ....................
1879 ;; Destination is always set in SI mode.
1881 (define_expand "cstore<mode>4"
1882 [(set (match_operand:SI 0 "register_operand")
1883 (match_operator:SI 1 "order_operator"
1884 [(match_operand:GPR 2 "register_operand")
1885 (match_operand:GPR 3 "nonmemory_operand")]))]
1888 riscv_expand_int_scc (operands[0], GET_CODE (operands[1]), operands[2],
1893 (define_expand "cstore<mode>4"
1894 [(set (match_operand:SI 0 "register_operand")
1895 (match_operator:SI 1 "fp_scc_comparison"
1896 [(match_operand:ANYF 2 "register_operand")
1897 (match_operand:ANYF 3 "register_operand")]))]
1900 riscv_expand_float_scc (operands[0], GET_CODE (operands[1]), operands[2],
1905 (define_insn "*cstore<ANYF:mode><X:mode>4"
1906 [(set (match_operand:X 0 "register_operand" "=r")
1907 (match_operator:X 1 "fp_native_comparison"
1908 [(match_operand:ANYF 2 "register_operand" " f")
1909 (match_operand:ANYF 3 "register_operand" " f")]))]
1911 "f%C1.<fmt>\t%0,%2,%3"
1912 [(set_attr "type" "fcmp")
1913 (set_attr "mode" "<UNITMODE>")])
1915 (define_insn "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4"
1916 [(set (match_operand:X 0 "register_operand" "=r")
1918 [(match_operand:ANYF 1 "register_operand" " f")
1919 (match_operand:ANYF 2 "register_operand" " f")]
1921 (clobber (match_scratch:X 3 "=&r"))]
1923 "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3"
1924 [(set_attr "type" "fcmp")
1925 (set_attr "mode" "<UNITMODE>")
1926 (set (attr "length") (const_int 12))])
1928 (define_insn "*seq_zero_<X:mode><GPR:mode>"
1929 [(set (match_operand:GPR 0 "register_operand" "=r")
1930 (eq:GPR (match_operand:X 1 "register_operand" " r")
1934 [(set_attr "type" "slt")
1935 (set_attr "mode" "<X:MODE>")])
1937 (define_insn "*sne_zero_<X:mode><GPR:mode>"
1938 [(set (match_operand:GPR 0 "register_operand" "=r")
1939 (ne:GPR (match_operand:X 1 "register_operand" " r")
1943 [(set_attr "type" "slt")
1944 (set_attr "mode" "<X:MODE>")])
1946 (define_insn "*sgt<u>_<X:mode><GPR:mode>"
1947 [(set (match_operand:GPR 0 "register_operand" "= r")
1948 (any_gt:GPR (match_operand:X 1 "register_operand" " r")
1949 (match_operand:X 2 "reg_or_0_operand" " rJ")))]
1952 [(set_attr "type" "slt")
1953 (set_attr "mode" "<X:MODE>")])
1955 (define_insn "*sge<u>_<X:mode><GPR:mode>"
1956 [(set (match_operand:GPR 0 "register_operand" "=r")
1957 (any_ge:GPR (match_operand:X 1 "register_operand" " r")
1960 "slt%i2<u>\t%0,zero,%1"
1961 [(set_attr "type" "slt")
1962 (set_attr "mode" "<MODE>")])
1964 (define_insn "*slt<u>_<X:mode><GPR:mode>"
1965 [(set (match_operand:GPR 0 "register_operand" "= r")
1966 (any_lt:GPR (match_operand:X 1 "register_operand" " r")
1967 (match_operand:X 2 "arith_operand" " rI")))]
1969 "slt%i2<u>\t%0,%1,%2"
1970 [(set_attr "type" "slt")
1971 (set_attr "mode" "<MODE>")])
1973 (define_insn "*sle<u>_<X:mode><GPR:mode>"
1974 [(set (match_operand:GPR 0 "register_operand" "=r")
1975 (any_le:GPR (match_operand:X 1 "register_operand" " r")
1976 (match_operand:X 2 "sle_operand" "")))]
1979 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
1980 return "slt%i2<u>\t%0,%1,%2";
1982 [(set_attr "type" "slt")
1983 (set_attr "mode" "<MODE>")])
1986 ;; ....................
1988 ;; UNCONDITIONAL BRANCHES
1990 ;; ....................
1992 ;; Unconditional branches.
1996 (label_ref (match_operand 0 "" "")))]
1999 [(set_attr "type" "jump")
2000 (set_attr "mode" "none")])
2002 (define_expand "indirect_jump"
2003 [(set (pc) (match_operand 0 "register_operand"))]
2006 operands[0] = force_reg (Pmode, operands[0]);
2007 if (Pmode == SImode)
2008 emit_jump_insn (gen_indirect_jumpsi (operands[0]));
2010 emit_jump_insn (gen_indirect_jumpdi (operands[0]));
2014 (define_insn "indirect_jump<mode>"
2015 [(set (pc) (match_operand:P 0 "register_operand" "l"))]
2018 [(set_attr "type" "jump")
2019 (set_attr "mode" "none")])
2021 (define_expand "tablejump"
2022 [(set (pc) (match_operand 0 "register_operand" ""))
2023 (use (label_ref (match_operand 1 "" "")))]
2026 if (CASE_VECTOR_PC_RELATIVE)
2027 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
2028 gen_rtx_LABEL_REF (Pmode, operands[1]),
2029 NULL_RTX, 0, OPTAB_DIRECT);
2031 if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode)
2032 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
2034 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
2038 (define_insn "tablejump<mode>"
2039 [(set (pc) (match_operand:GPR 0 "register_operand" "l"))
2040 (use (label_ref (match_operand 1 "" "")))]
2043 [(set_attr "type" "jump")
2044 (set_attr "mode" "none")])
2047 ;; ....................
2049 ;; Function prologue/epilogue
2051 ;; ....................
2054 (define_expand "prologue"
2058 riscv_expand_prologue ();
2062 ;; Block any insns from being moved before this point, since the
2063 ;; profiling call to mcount can use various registers that aren't
2064 ;; saved or used to pass arguments.
2066 (define_insn "blockage"
2067 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2070 [(set_attr "type" "ghost")
2071 (set_attr "mode" "none")])
2073 (define_expand "epilogue"
2077 riscv_expand_epilogue (NORMAL_RETURN);
2081 (define_expand "sibcall_epilogue"
2085 riscv_expand_epilogue (SIBCALL_RETURN);
2089 ;; Trivial return. Make it look like a normal return insn as that
2090 ;; allows jump optimizations to work better.
2092 (define_expand "return"
2094 "riscv_can_use_return_insn ()"
2097 (define_insn "simple_return"
2101 return riscv_output_return ();
2103 [(set_attr "type" "jump")
2104 (set_attr "mode" "none")])
2108 (define_insn "simple_return_internal"
2110 (use (match_operand 0 "pmode_register_operand" ""))]
2113 [(set_attr "type" "jump")
2114 (set_attr "mode" "none")])
2116 ;; This is used in compiling the unwind routines.
2117 (define_expand "eh_return"
2118 [(use (match_operand 0 "general_operand"))]
2121 if (GET_MODE (operands[0]) != word_mode)
2122 operands[0] = convert_to_mode (word_mode, operands[0], 0);
2124 emit_insn (gen_eh_set_lr_di (operands[0]));
2126 emit_insn (gen_eh_set_lr_si (operands[0]));
2128 emit_jump_insn (gen_eh_return_internal ());
2133 ;; Clobber the return address on the stack. We can't expand this
2134 ;; until we know where it will be put in the stack frame.
2136 (define_insn "eh_set_lr_si"
2137 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2138 (clobber (match_scratch:SI 1 "=&r"))]
2142 (define_insn "eh_set_lr_di"
2143 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2144 (clobber (match_scratch:DI 1 "=&r"))]
2149 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
2150 (clobber (match_scratch 1))]
2154 riscv_set_return_address (operands[0], operands[1]);
2158 (define_insn_and_split "eh_return_internal"
2162 "epilogue_completed"
2164 "riscv_expand_epilogue (EXCEPTION_RETURN); DONE;")
2167 ;; ....................
2171 ;; ....................
2173 (define_expand "sibcall"
2174 [(parallel [(call (match_operand 0 "")
2175 (match_operand 1 ""))
2176 (use (match_operand 2 "")) ;; next_arg_reg
2177 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
2180 rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2181 emit_call_insn (gen_sibcall_internal (target, operands[1]));
2185 (define_insn "sibcall_internal"
2186 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U"))
2187 (match_operand 1 "" ""))]
2188 "SIBLING_CALL_P (insn)"
2193 [(set_attr "type" "call")])
2195 (define_expand "sibcall_value"
2196 [(parallel [(set (match_operand 0 "")
2197 (call (match_operand 1 "")
2198 (match_operand 2 "")))
2199 (use (match_operand 3 ""))])] ;; next_arg_reg
2202 rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2203 emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2]));
2207 (define_insn "sibcall_value_internal"
2208 [(set (match_operand 0 "" "")
2209 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U"))
2210 (match_operand 2 "" "")))]
2211 "SIBLING_CALL_P (insn)"
2216 [(set_attr "type" "call")])
2218 (define_expand "call"
2219 [(parallel [(call (match_operand 0 "")
2220 (match_operand 1 ""))
2221 (use (match_operand 2 "")) ;; next_arg_reg
2222 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
2225 rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2226 emit_call_insn (gen_call_internal (target, operands[1]));
2230 (define_insn "call_internal"
2231 [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U"))
2232 (match_operand 1 "" ""))
2233 (clobber (reg:SI RETURN_ADDR_REGNUM))]
2239 [(set_attr "type" "call")])
2241 (define_expand "call_value"
2242 [(parallel [(set (match_operand 0 "")
2243 (call (match_operand 1 "")
2244 (match_operand 2 "")))
2245 (use (match_operand 3 ""))])] ;; next_arg_reg
2248 rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2249 emit_call_insn (gen_call_value_internal (operands[0], target, operands[2]));
2253 (define_insn "call_value_internal"
2254 [(set (match_operand 0 "" "")
2255 (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U"))
2256 (match_operand 2 "" "")))
2257 (clobber (reg:SI RETURN_ADDR_REGNUM))]
2263 [(set_attr "type" "call")])
2265 ;; Call subroutine returning any type.
2267 (define_expand "untyped_call"
2268 [(parallel [(call (match_operand 0 "")
2270 (match_operand 1 "")
2271 (match_operand 2 "")])]
2276 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2278 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2280 rtx set = XVECEXP (operands[2], 0, i);
2281 riscv_emit_move (SET_DEST (set), SET_SRC (set));
2284 emit_insn (gen_blockage ());
2292 [(set_attr "type" "nop")
2293 (set_attr "mode" "none")])
2296 [(trap_if (const_int 1) (const_int 0))]
2300 (define_insn "gpr_save"
2301 [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_SAVE)
2302 (clobber (reg:SI T0_REGNUM))
2303 (clobber (reg:SI T1_REGNUM))]
2305 { return riscv_output_gpr_save (INTVAL (operands[0])); })
2307 (define_insn "gpr_restore"
2308 [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_RESTORE)]
2310 "tail\t__riscv_restore_%0")
2312 (define_insn "gpr_restore_return"
2314 (use (match_operand 0 "pmode_register_operand" ""))
2319 (define_insn "riscv_frflags"
2320 [(set (match_operand:SI 0 "register_operand" "=r")
2321 (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))]
2325 (define_insn "riscv_fsflags"
2326 [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)]
2330 (define_insn "riscv_mret"
2332 (unspec_volatile [(const_int 0)] UNSPECV_MRET)]
2336 (define_insn "riscv_sret"
2338 (unspec_volatile [(const_int 0)] UNSPECV_SRET)]
2342 (define_insn "riscv_uret"
2344 (unspec_volatile [(const_int 0)] UNSPECV_URET)]
2348 (define_insn "stack_tie<mode>"
2349 [(set (mem:BLK (scratch))
2350 (unspec:BLK [(match_operand:X 0 "register_operand" "r")
2351 (match_operand:X 1 "register_operand" "r")]
2355 [(set_attr "length" "0")]
2359 (include "peephole.md")
2361 (include "generic.md")