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 hardware integer modes narrower than XLEN.
273 (define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")])
275 ;; Iterator for hardware-supported integer modes.
276 (define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")])
278 ;; Iterator for hardware-supported floating-point modes.
279 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
280 (DF "TARGET_DOUBLE_FLOAT")])
282 ;; Iterator for floating-point modes that can be loaded into X registers.
283 (define_mode_iterator SOFTF [SF (DF "TARGET_64BIT")])
285 ;; This attribute gives the length suffix for a sign- or zero-extension
287 (define_mode_attr size [(QI "b") (HI "h")])
289 ;; Mode attributes for loads.
290 (define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")])
292 ;; Instruction names for integer loads that aren't explicitly sign or zero
293 ;; extended. See riscv_output_move and LOAD_EXTEND_OP.
294 (define_mode_attr default_load [(QI "lbu") (HI "lhu") (SI "lw") (DI "ld")])
296 ;; Mode attribute for FP loads into integer registers.
297 (define_mode_attr softload [(SF "lw") (DF "ld")])
299 ;; Instruction names for stores.
300 (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")])
302 ;; Instruction names for FP stores from integer registers.
303 (define_mode_attr softstore [(SF "sw") (DF "sd")])
305 ;; This attribute gives the best constraint to use for registers of
307 (define_mode_attr reg [(SI "d") (DI "d") (CC "d")])
309 ;; This attribute gives the format suffix for floating-point operations.
310 (define_mode_attr fmt [(SF "s") (DF "d")])
312 ;; This attribute gives the integer suffix for floating-point conversions.
313 (define_mode_attr ifmt [(SI "w") (DI "l")])
315 ;; This attribute gives the format suffix for atomic memory operations.
316 (define_mode_attr amo [(SI "w") (DI "d")])
318 ;; This attribute gives the upper-case mode name for one unit of a
319 ;; floating-point mode.
320 (define_mode_attr UNITMODE [(SF "SF") (DF "DF")])
322 ;; This attribute gives the integer mode that has half the size of
323 ;; the controlling mode.
324 (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
326 ;; Iterator and attributes for floating-point rounding instructions.
327 (define_int_iterator RINT [UNSPEC_LRINT UNSPEC_LROUND])
328 (define_int_attr rint_pattern [(UNSPEC_LRINT "rint") (UNSPEC_LROUND "round")])
329 (define_int_attr rint_rm [(UNSPEC_LRINT "dyn") (UNSPEC_LROUND "rmm")])
331 ;; Iterator and attributes for quiet comparisons.
332 (define_int_iterator QUIET_COMPARISON [UNSPEC_FLT_QUIET UNSPEC_FLE_QUIET])
333 (define_int_attr quiet_pattern [(UNSPEC_FLT_QUIET "lt") (UNSPEC_FLE_QUIET "le")])
335 ;; This code iterator allows signed and unsigned widening multiplications
336 ;; to use the same template.
337 (define_code_iterator any_extend [sign_extend zero_extend])
339 ;; This code iterator allows the two right shift instructions to be
340 ;; generated from the same template.
341 (define_code_iterator any_shiftrt [ashiftrt lshiftrt])
343 ;; This code iterator allows the three shift instructions to be generated
344 ;; from the same template.
345 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
347 ;; This code iterator allows the three bitwise instructions to be generated
348 ;; from the same template.
349 (define_code_iterator any_bitwise [and ior xor])
351 ;; This code iterator allows unsigned and signed division to be generated
352 ;; from the same template.
353 (define_code_iterator any_div [div udiv mod umod])
355 ;; This code iterator allows unsigned and signed modulus to be generated
356 ;; from the same template.
357 (define_code_iterator any_mod [mod umod])
359 ;; These code iterators allow the signed and unsigned scc operations to use
360 ;; the same template.
361 (define_code_iterator any_gt [gt gtu])
362 (define_code_iterator any_ge [ge geu])
363 (define_code_iterator any_lt [lt ltu])
364 (define_code_iterator any_le [le leu])
366 ;; <u> expands to an empty string when doing a signed operation and
367 ;; "u" when doing an unsigned operation.
368 (define_code_attr u [(sign_extend "") (zero_extend "u")
374 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
375 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
377 ;; <optab> expands to the name of the optab for a particular code.
378 (define_code_attr optab [(ashift "ashl")
395 ;; <insn> expands to the name of the insn that implements a particular code.
396 (define_code_attr insn [(ashift "sll")
409 ;; Ghost instructions produce no real code and introduce no hazards.
410 ;; They exist purely to express an effect on dataflow.
411 (define_insn_reservation "ghost" 0
412 (eq_attr "type" "ghost")
416 ;; ....................
420 ;; ....................
423 (define_insn "add<mode>3"
424 [(set (match_operand:ANYF 0 "register_operand" "=f")
425 (plus:ANYF (match_operand:ANYF 1 "register_operand" " f")
426 (match_operand:ANYF 2 "register_operand" " f")))]
428 "fadd.<fmt>\t%0,%1,%2"
429 [(set_attr "type" "fadd")
430 (set_attr "mode" "<UNITMODE>")])
432 (define_insn "addsi3"
433 [(set (match_operand:SI 0 "register_operand" "=r,r")
434 (plus:SI (match_operand:SI 1 "register_operand" " r,r")
435 (match_operand:SI 2 "arith_operand" " r,I")))]
437 { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
438 [(set_attr "type" "arith")
439 (set_attr "mode" "SI")])
441 (define_insn "adddi3"
442 [(set (match_operand:DI 0 "register_operand" "=r,r")
443 (plus:DI (match_operand:DI 1 "register_operand" " r,r")
444 (match_operand:DI 2 "arith_operand" " r,I")))]
447 [(set_attr "type" "arith")
448 (set_attr "mode" "DI")])
450 (define_insn "*addsi3_extended"
451 [(set (match_operand:DI 0 "register_operand" "=r,r")
453 (plus:SI (match_operand:SI 1 "register_operand" " r,r")
454 (match_operand:SI 2 "arith_operand" " r,I"))))]
457 [(set_attr "type" "arith")
458 (set_attr "mode" "SI")])
460 (define_insn "*addsi3_extended2"
461 [(set (match_operand:DI 0 "register_operand" "=r,r")
463 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" " r,r")
464 (match_operand:DI 2 "arith_operand" " r,I"))
468 [(set_attr "type" "arith")
469 (set_attr "mode" "SI")])
472 ;; ....................
476 ;; ....................
479 (define_insn "sub<mode>3"
480 [(set (match_operand:ANYF 0 "register_operand" "=f")
481 (minus:ANYF (match_operand:ANYF 1 "register_operand" " f")
482 (match_operand:ANYF 2 "register_operand" " f")))]
484 "fsub.<fmt>\t%0,%1,%2"
485 [(set_attr "type" "fadd")
486 (set_attr "mode" "<UNITMODE>")])
488 (define_insn "subdi3"
489 [(set (match_operand:DI 0 "register_operand" "= r")
490 (minus:DI (match_operand:DI 1 "reg_or_0_operand" " rJ")
491 (match_operand:DI 2 "register_operand" " r")))]
494 [(set_attr "type" "arith")
495 (set_attr "mode" "DI")])
497 (define_insn "subsi3"
498 [(set (match_operand:SI 0 "register_operand" "= r")
499 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
500 (match_operand:SI 2 "register_operand" " r")))]
502 { return TARGET_64BIT ? "subw\t%0,%z1,%2" : "sub\t%0,%z1,%2"; }
503 [(set_attr "type" "arith")
504 (set_attr "mode" "SI")])
506 (define_insn "*subsi3_extended"
507 [(set (match_operand:DI 0 "register_operand" "= r")
509 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
510 (match_operand:SI 2 "register_operand" " r"))))]
513 [(set_attr "type" "arith")
514 (set_attr "mode" "SI")])
516 (define_insn "*subsi3_extended2"
517 [(set (match_operand:DI 0 "register_operand" "= r")
519 (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" " rJ")
520 (match_operand:DI 2 "register_operand" " r"))
524 [(set_attr "type" "arith")
525 (set_attr "mode" "SI")])
527 (define_insn "negdi2"
528 [(set (match_operand:DI 0 "register_operand" "=r")
529 (neg:DI (match_operand:DI 1 "register_operand" " r")))]
532 [(set_attr "type" "arith")
533 (set_attr "mode" "DI")])
535 (define_insn "negsi2"
536 [(set (match_operand:SI 0 "register_operand" "=r")
537 (neg:SI (match_operand:SI 1 "register_operand" " r")))]
539 { return TARGET_64BIT ? "negw\t%0,%1" : "neg\t%0,%1"; }
540 [(set_attr "type" "arith")
541 (set_attr "mode" "SI")])
543 (define_insn "*negsi2_extended"
544 [(set (match_operand:DI 0 "register_operand" "=r")
546 (neg:SI (match_operand:SI 1 "register_operand" " r"))))]
549 [(set_attr "type" "arith")
550 (set_attr "mode" "SI")])
552 (define_insn "*negsi2_extended2"
553 [(set (match_operand:DI 0 "register_operand" "=r")
555 (subreg:SI (neg:DI (match_operand:DI 1 "register_operand" " r"))
559 [(set_attr "type" "arith")
560 (set_attr "mode" "SI")])
563 ;; ....................
567 ;; ....................
570 (define_insn "mul<mode>3"
571 [(set (match_operand:ANYF 0 "register_operand" "=f")
572 (mult:ANYF (match_operand:ANYF 1 "register_operand" " f")
573 (match_operand:ANYF 2 "register_operand" " f")))]
575 "fmul.<fmt>\t%0,%1,%2"
576 [(set_attr "type" "fmul")
577 (set_attr "mode" "<UNITMODE>")])
579 (define_insn "mulsi3"
580 [(set (match_operand:SI 0 "register_operand" "=r")
581 (mult:SI (match_operand:SI 1 "register_operand" " r")
582 (match_operand:SI 2 "register_operand" " r")))]
584 { return TARGET_64BIT ? "mulw\t%0,%1,%2" : "mul\t%0,%1,%2"; }
585 [(set_attr "type" "imul")
586 (set_attr "mode" "SI")])
588 (define_insn "muldi3"
589 [(set (match_operand:DI 0 "register_operand" "=r")
590 (mult:DI (match_operand:DI 1 "register_operand" " r")
591 (match_operand:DI 2 "register_operand" " r")))]
592 "TARGET_MUL && TARGET_64BIT"
594 [(set_attr "type" "imul")
595 (set_attr "mode" "DI")])
597 (define_insn "*mulsi3_extended"
598 [(set (match_operand:DI 0 "register_operand" "=r")
600 (mult:SI (match_operand:SI 1 "register_operand" " r")
601 (match_operand:SI 2 "register_operand" " r"))))]
602 "TARGET_MUL && TARGET_64BIT"
604 [(set_attr "type" "imul")
605 (set_attr "mode" "SI")])
607 (define_insn "*mulsi3_extended2"
608 [(set (match_operand:DI 0 "register_operand" "=r")
610 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" " r")
611 (match_operand:DI 2 "register_operand" " r"))
613 "TARGET_MUL && TARGET_64BIT"
615 [(set_attr "type" "imul")
616 (set_attr "mode" "SI")])
619 ;; ........................
621 ;; MULTIPLICATION HIGH-PART
623 ;; ........................
627 (define_expand "<u>mulditi3"
628 [(set (match_operand:TI 0 "register_operand")
629 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
630 (any_extend:TI (match_operand:DI 2 "register_operand"))))]
631 "TARGET_MUL && TARGET_64BIT"
633 rtx low = gen_reg_rtx (DImode);
634 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
636 rtx high = gen_reg_rtx (DImode);
637 emit_insn (gen_<u>muldi3_highpart (high, operands[1], operands[2]));
639 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
640 emit_move_insn (gen_highpart (DImode, operands[0]), high);
644 (define_insn "<u>muldi3_highpart"
645 [(set (match_operand:DI 0 "register_operand" "=r")
648 (mult:TI (any_extend:TI
649 (match_operand:DI 1 "register_operand" " r"))
651 (match_operand:DI 2 "register_operand" " r")))
653 "TARGET_MUL && TARGET_64BIT"
655 [(set_attr "type" "imul")
656 (set_attr "mode" "DI")])
658 (define_expand "usmulditi3"
659 [(set (match_operand:TI 0 "register_operand")
660 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand"))
661 (sign_extend:TI (match_operand:DI 2 "register_operand"))))]
662 "TARGET_MUL && TARGET_64BIT"
664 rtx low = gen_reg_rtx (DImode);
665 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
667 rtx high = gen_reg_rtx (DImode);
668 emit_insn (gen_usmuldi3_highpart (high, operands[1], operands[2]));
670 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
671 emit_move_insn (gen_highpart (DImode, operands[0]), high);
675 (define_insn "usmuldi3_highpart"
676 [(set (match_operand:DI 0 "register_operand" "=r")
679 (mult:TI (zero_extend:TI
680 (match_operand:DI 1 "register_operand" "r"))
682 (match_operand:DI 2 "register_operand" " r")))
684 "TARGET_MUL && TARGET_64BIT"
686 [(set_attr "type" "imul")
687 (set_attr "mode" "DI")])
689 (define_expand "<u>mulsidi3"
690 [(set (match_operand:DI 0 "register_operand" "=r")
691 (mult:DI (any_extend:DI
692 (match_operand:SI 1 "register_operand" " r"))
694 (match_operand:SI 2 "register_operand" " r"))))]
695 "TARGET_MUL && !TARGET_64BIT"
697 rtx temp = gen_reg_rtx (SImode);
698 emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
699 emit_insn (gen_<u>mulsi3_highpart (riscv_subword (operands[0], true),
700 operands[1], operands[2]));
701 emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
705 (define_insn "<u>mulsi3_highpart"
706 [(set (match_operand:SI 0 "register_operand" "=r")
709 (mult:DI (any_extend:DI
710 (match_operand:SI 1 "register_operand" " r"))
712 (match_operand:SI 2 "register_operand" " r")))
714 "TARGET_MUL && !TARGET_64BIT"
716 [(set_attr "type" "imul")
717 (set_attr "mode" "SI")])
720 (define_expand "usmulsidi3"
721 [(set (match_operand:DI 0 "register_operand" "=r")
722 (mult:DI (zero_extend:DI
723 (match_operand:SI 1 "register_operand" " r"))
725 (match_operand:SI 2 "register_operand" " r"))))]
726 "TARGET_MUL && !TARGET_64BIT"
728 rtx temp = gen_reg_rtx (SImode);
729 emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
730 emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true),
731 operands[1], operands[2]));
732 emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
736 (define_insn "usmulsi3_highpart"
737 [(set (match_operand:SI 0 "register_operand" "=r")
740 (mult:DI (zero_extend:DI
741 (match_operand:SI 1 "register_operand" " r"))
743 (match_operand:SI 2 "register_operand" " r")))
745 "TARGET_MUL && !TARGET_64BIT"
747 [(set_attr "type" "imul")
748 (set_attr "mode" "SI")])
751 ;; ....................
753 ;; DIVISION and REMAINDER
755 ;; ....................
758 (define_insn "<optab>si3"
759 [(set (match_operand:SI 0 "register_operand" "=r")
760 (any_div:SI (match_operand:SI 1 "register_operand" " r")
761 (match_operand:SI 2 "register_operand" " r")))]
763 { return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2"; }
764 [(set_attr "type" "idiv")
765 (set_attr "mode" "SI")])
767 (define_insn "<optab>di3"
768 [(set (match_operand:DI 0 "register_operand" "=r")
769 (any_div:DI (match_operand:DI 1 "register_operand" " r")
770 (match_operand:DI 2 "register_operand" " r")))]
771 "TARGET_DIV && TARGET_64BIT"
772 "<insn>%i2\t%0,%1,%2"
773 [(set_attr "type" "idiv")
774 (set_attr "mode" "DI")])
776 (define_insn "*<optab>si3_extended"
777 [(set (match_operand:DI 0 "register_operand" "=r")
779 (any_div:SI (match_operand:SI 1 "register_operand" " r")
780 (match_operand:SI 2 "register_operand" " r"))))]
781 "TARGET_DIV && TARGET_64BIT"
782 "<insn>%i2w\t%0,%1,%2"
783 [(set_attr "type" "idiv")
784 (set_attr "mode" "DI")])
786 (define_insn "div<mode>3"
787 [(set (match_operand:ANYF 0 "register_operand" "=f")
788 (div:ANYF (match_operand:ANYF 1 "register_operand" " f")
789 (match_operand:ANYF 2 "register_operand" " f")))]
790 "TARGET_HARD_FLOAT && TARGET_FDIV"
791 "fdiv.<fmt>\t%0,%1,%2"
792 [(set_attr "type" "fdiv")
793 (set_attr "mode" "<UNITMODE>")])
796 ;; ....................
800 ;; ....................
802 (define_insn "sqrt<mode>2"
803 [(set (match_operand:ANYF 0 "register_operand" "=f")
804 (sqrt:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
805 "TARGET_HARD_FLOAT && TARGET_FDIV"
807 return "fsqrt.<fmt>\t%0,%1";
809 [(set_attr "type" "fsqrt")
810 (set_attr "mode" "<UNITMODE>")])
812 ;; Floating point multiply accumulate instructions.
815 (define_insn "fma<mode>4"
816 [(set (match_operand:ANYF 0 "register_operand" "=f")
817 (fma:ANYF (match_operand:ANYF 1 "register_operand" " f")
818 (match_operand:ANYF 2 "register_operand" " f")
819 (match_operand:ANYF 3 "register_operand" " f")))]
821 "fmadd.<fmt>\t%0,%1,%2,%3"
822 [(set_attr "type" "fmadd")
823 (set_attr "mode" "<UNITMODE>")])
826 (define_insn "fms<mode>4"
827 [(set (match_operand:ANYF 0 "register_operand" "=f")
828 (fma:ANYF (match_operand:ANYF 1 "register_operand" " f")
829 (match_operand:ANYF 2 "register_operand" " f")
830 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
832 "fmsub.<fmt>\t%0,%1,%2,%3"
833 [(set_attr "type" "fmadd")
834 (set_attr "mode" "<UNITMODE>")])
837 (define_insn "fnms<mode>4"
838 [(set (match_operand:ANYF 0 "register_operand" "=f")
840 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
841 (match_operand:ANYF 2 "register_operand" " f")
842 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
844 "fnmadd.<fmt>\t%0,%1,%2,%3"
845 [(set_attr "type" "fmadd")
846 (set_attr "mode" "<UNITMODE>")])
849 (define_insn "fnma<mode>4"
850 [(set (match_operand:ANYF 0 "register_operand" "=f")
852 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
853 (match_operand:ANYF 2 "register_operand" " f")
854 (match_operand:ANYF 3 "register_operand" " f")))]
856 "fnmsub.<fmt>\t%0,%1,%2,%3"
857 [(set_attr "type" "fmadd")
858 (set_attr "mode" "<UNITMODE>")])
860 ;; -(-a * b - c), modulo signed zeros
861 (define_insn "*fma<mode>4"
862 [(set (match_operand:ANYF 0 "register_operand" "=f")
865 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
866 (match_operand:ANYF 2 "register_operand" " f")
867 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
868 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
869 "fmadd.<fmt>\t%0,%1,%2,%3"
870 [(set_attr "type" "fmadd")
871 (set_attr "mode" "<UNITMODE>")])
873 ;; -(-a * b + c), modulo signed zeros
874 (define_insn "*fms<mode>4"
875 [(set (match_operand:ANYF 0 "register_operand" "=f")
878 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
879 (match_operand:ANYF 2 "register_operand" " f")
880 (match_operand:ANYF 3 "register_operand" " f"))))]
881 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
882 "fmsub.<fmt>\t%0,%1,%2,%3"
883 [(set_attr "type" "fmadd")
884 (set_attr "mode" "<UNITMODE>")])
886 ;; -(a * b + c), modulo signed zeros
887 (define_insn "*fnms<mode>4"
888 [(set (match_operand:ANYF 0 "register_operand" "=f")
891 (match_operand:ANYF 1 "register_operand" " f")
892 (match_operand:ANYF 2 "register_operand" " f")
893 (match_operand:ANYF 3 "register_operand" " f"))))]
894 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
895 "fnmadd.<fmt>\t%0,%1,%2,%3"
896 [(set_attr "type" "fmadd")
897 (set_attr "mode" "<UNITMODE>")])
899 ;; -(a * b - c), modulo signed zeros
900 (define_insn "*fnma<mode>4"
901 [(set (match_operand:ANYF 0 "register_operand" "=f")
904 (match_operand:ANYF 1 "register_operand" " f")
905 (match_operand:ANYF 2 "register_operand" " f")
906 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
907 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
908 "fnmsub.<fmt>\t%0,%1,%2,%3"
909 [(set_attr "type" "fmadd")
910 (set_attr "mode" "<UNITMODE>")])
913 ;; ....................
917 ;; ....................
919 (define_insn "abs<mode>2"
920 [(set (match_operand:ANYF 0 "register_operand" "=f")
921 (abs:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
924 [(set_attr "type" "fmove")
925 (set_attr "mode" "<UNITMODE>")])
927 (define_insn "copysign<mode>3"
928 [(set (match_operand:ANYF 0 "register_operand" "=f")
929 (unspec:ANYF [(match_operand:ANYF 1 "register_operand" " f")
930 (match_operand:ANYF 2 "register_operand" " f")]
933 "fsgnj.<fmt>\t%0,%1,%2"
934 [(set_attr "type" "fmove")
935 (set_attr "mode" "<UNITMODE>")])
937 (define_insn "neg<mode>2"
938 [(set (match_operand:ANYF 0 "register_operand" "=f")
939 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
942 [(set_attr "type" "fmove")
943 (set_attr "mode" "<UNITMODE>")])
946 ;; ....................
950 ;; ....................
952 (define_insn "smin<mode>3"
953 [(set (match_operand:ANYF 0 "register_operand" "=f")
954 (smin:ANYF (match_operand:ANYF 1 "register_operand" " f")
955 (match_operand:ANYF 2 "register_operand" " f")))]
957 "fmin.<fmt>\t%0,%1,%2"
958 [(set_attr "type" "fmove")
959 (set_attr "mode" "<UNITMODE>")])
961 (define_insn "smax<mode>3"
962 [(set (match_operand:ANYF 0 "register_operand" "=f")
963 (smax:ANYF (match_operand:ANYF 1 "register_operand" " f")
964 (match_operand:ANYF 2 "register_operand" " f")))]
966 "fmax.<fmt>\t%0,%1,%2"
967 [(set_attr "type" "fmove")
968 (set_attr "mode" "<UNITMODE>")])
971 ;; ....................
975 ;; ....................
978 ;; For RV64, we don't expose the SImode operations to the rtl expanders,
979 ;; but SImode versions exist for combine.
981 (define_insn "<optab><mode>3"
982 [(set (match_operand:X 0 "register_operand" "=r,r")
983 (any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
984 (match_operand:X 2 "arith_operand" " r,I")))]
986 "<insn>%i2\t%0,%1,%2"
987 [(set_attr "type" "logical")
988 (set_attr "mode" "<MODE>")])
990 (define_insn "*<optab>si3_internal"
991 [(set (match_operand:SI 0 "register_operand" "=r,r")
992 (any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r")
993 (match_operand:SI 2 "arith_operand" " r,I")))]
995 "<insn>%i2\t%0,%1,%2"
996 [(set_attr "type" "logical")
997 (set_attr "mode" "SI")])
999 (define_insn "one_cmpl<mode>2"
1000 [(set (match_operand:X 0 "register_operand" "=r")
1001 (not:X (match_operand:X 1 "register_operand" " r")))]
1004 [(set_attr "type" "logical")
1005 (set_attr "mode" "<MODE>")])
1007 (define_insn "*one_cmplsi2_internal"
1008 [(set (match_operand:SI 0 "register_operand" "=r")
1009 (not:SI (match_operand:SI 1 "register_operand" " r")))]
1012 [(set_attr "type" "logical")
1013 (set_attr "mode" "SI")])
1016 ;; ....................
1020 ;; ....................
1022 (define_insn "truncdfsf2"
1023 [(set (match_operand:SF 0 "register_operand" "=f")
1025 (match_operand:DF 1 "register_operand" " f")))]
1026 "TARGET_DOUBLE_FLOAT"
1028 [(set_attr "type" "fcvt")
1029 (set_attr "mode" "SF")])
1032 ;; ....................
1036 ;; ....................
1040 (define_insn_and_split "zero_extendsidi2"
1041 [(set (match_operand:DI 0 "register_operand" "=r,r")
1043 (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
1048 "&& reload_completed && REG_P (operands[1])"
1050 (ashift:DI (match_dup 1) (const_int 32)))
1052 (lshiftrt:DI (match_dup 0) (const_int 32)))]
1053 { operands[1] = gen_lowpart (DImode, operands[1]); }
1054 [(set_attr "move_type" "shift_shift,load")
1055 (set_attr "mode" "DI")])
1057 (define_insn_and_split "zero_extendhi<GPR:mode>2"
1058 [(set (match_operand:GPR 0 "register_operand" "=r,r")
1060 (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
1065 "&& reload_completed && REG_P (operands[1])"
1067 (ashift:GPR (match_dup 1) (match_dup 2)))
1069 (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
1071 operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
1072 operands[2] = GEN_INT(GET_MODE_BITSIZE(<GPR:MODE>mode) - 16);
1074 [(set_attr "move_type" "shift_shift,load")
1075 (set_attr "mode" "<GPR:MODE>")])
1077 (define_insn "zero_extendqi<SUPERQI:mode>2"
1078 [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
1079 (zero_extend:SUPERQI
1080 (match_operand:QI 1 "nonimmediate_operand" " r,m")))]
1085 [(set_attr "move_type" "andi,load")
1086 (set_attr "mode" "<SUPERQI:MODE>")])
1089 ;; ....................
1093 ;; ....................
1095 (define_insn "extendsidi2"
1096 [(set (match_operand:DI 0 "register_operand" "=r,r")
1098 (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
1103 [(set_attr "move_type" "move,load")
1104 (set_attr "mode" "DI")])
1106 (define_insn_and_split "extend<SHORT:mode><SUPERQI:mode>2"
1107 [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
1108 (sign_extend:SUPERQI
1109 (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
1113 l<SHORT:size>\t%0,%1"
1114 "&& reload_completed && REG_P (operands[1])"
1115 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1116 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
1118 operands[0] = gen_lowpart (SImode, operands[0]);
1119 operands[1] = gen_lowpart (SImode, operands[1]);
1120 operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
1121 - GET_MODE_BITSIZE (<SHORT:MODE>mode));
1123 [(set_attr "move_type" "shift_shift,load")
1124 (set_attr "mode" "SI")])
1126 (define_insn "extendsfdf2"
1127 [(set (match_operand:DF 0 "register_operand" "=f")
1129 (match_operand:SF 1 "register_operand" " f")))]
1130 "TARGET_DOUBLE_FLOAT"
1132 [(set_attr "type" "fcvt")
1133 (set_attr "mode" "DF")])
1136 ;; ....................
1140 ;; ....................
1142 (define_insn "fix_trunc<ANYF:mode><GPR:mode>2"
1143 [(set (match_operand:GPR 0 "register_operand" "=r")
1145 (match_operand:ANYF 1 "register_operand" " f")))]
1147 "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,rtz"
1148 [(set_attr "type" "fcvt")
1149 (set_attr "mode" "<ANYF:MODE>")])
1151 (define_insn "fixuns_trunc<ANYF:mode><GPR:mode>2"
1152 [(set (match_operand:GPR 0 "register_operand" "=r")
1154 (match_operand:ANYF 1 "register_operand" " f")))]
1156 "fcvt.<GPR:ifmt>u.<ANYF:fmt> %0,%1,rtz"
1157 [(set_attr "type" "fcvt")
1158 (set_attr "mode" "<ANYF:MODE>")])
1160 (define_insn "float<GPR:mode><ANYF:mode>2"
1161 [(set (match_operand:ANYF 0 "register_operand" "= f")
1163 (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1165 "fcvt.<ANYF:fmt>.<GPR:ifmt>\t%0,%z1"
1166 [(set_attr "type" "fcvt")
1167 (set_attr "mode" "<ANYF:MODE>")])
1169 (define_insn "floatuns<GPR:mode><ANYF:mode>2"
1170 [(set (match_operand:ANYF 0 "register_operand" "= f")
1171 (unsigned_float:ANYF
1172 (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1174 "fcvt.<ANYF:fmt>.<GPR:ifmt>u\t%0,%z1"
1175 [(set_attr "type" "fcvt")
1176 (set_attr "mode" "<ANYF:MODE>")])
1178 (define_insn "l<rint_pattern><ANYF:mode><GPR:mode>2"
1179 [(set (match_operand:GPR 0 "register_operand" "=r")
1181 [(match_operand:ANYF 1 "register_operand" " f")]
1184 "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,<rint_rm>"
1185 [(set_attr "type" "fcvt")
1186 (set_attr "mode" "<ANYF:MODE>")])
1189 ;; ....................
1193 ;; ....................
1195 ;; Lower-level instructions for loading an address from the GOT.
1196 ;; We could use MEMs, but an unspec gives more optimization
1199 (define_insn "got_load<mode>"
1200 [(set (match_operand:P 0 "register_operand" "=r")
1202 [(match_operand:P 1 "symbolic_operand" "")]
1206 [(set_attr "got" "load")
1207 (set_attr "mode" "<MODE>")])
1209 (define_insn "tls_add_tp_le<mode>"
1210 [(set (match_operand:P 0 "register_operand" "=r")
1212 [(match_operand:P 1 "register_operand" "r")
1213 (match_operand:P 2 "register_operand" "r")
1214 (match_operand:P 3 "symbolic_operand" "")]
1217 "add\t%0,%1,%2,%%tprel_add(%3)"
1218 [(set_attr "type" "arith")
1219 (set_attr "mode" "<MODE>")])
1221 (define_insn "got_load_tls_gd<mode>"
1222 [(set (match_operand:P 0 "register_operand" "=r")
1224 [(match_operand:P 1 "symbolic_operand" "")]
1228 [(set_attr "got" "load")
1229 (set_attr "mode" "<MODE>")])
1231 (define_insn "got_load_tls_ie<mode>"
1232 [(set (match_operand:P 0 "register_operand" "=r")
1234 [(match_operand:P 1 "symbolic_operand" "")]
1238 [(set_attr "got" "load")
1239 (set_attr "mode" "<MODE>")])
1241 (define_insn "auipc<mode>"
1242 [(set (match_operand:P 0 "register_operand" "=r")
1244 [(match_operand:P 1 "symbolic_operand" "")
1245 (match_operand:P 2 "const_int_operand")
1249 ".LA%2: auipc\t%0,%h1"
1250 [(set_attr "type" "arith")
1251 (set_attr "cannot_copy" "yes")])
1253 ;; Instructions for adding the low 12 bits of an address to a register.
1254 ;; Operand 2 is the address: riscv_print_operand works out which relocation
1255 ;; should be applied.
1257 (define_insn "*low<mode>"
1258 [(set (match_operand:P 0 "register_operand" "=r")
1259 (lo_sum:P (match_operand:P 1 "register_operand" " r")
1260 (match_operand:P 2 "symbolic_operand" "")))]
1263 [(set_attr "type" "arith")
1264 (set_attr "mode" "<MODE>")])
1266 ;; Allow combine to split complex const_int load sequences, using operand 2
1267 ;; to store the intermediate results. See move_operand for details.
1269 [(set (match_operand:GPR 0 "register_operand")
1270 (match_operand:GPR 1 "splittable_const_int_operand"))
1271 (clobber (match_operand:GPR 2 "register_operand"))]
1275 riscv_move_integer (operands[2], operands[0], INTVAL (operands[1]));
1279 ;; Likewise, for symbolic operands.
1281 [(set (match_operand:P 0 "register_operand")
1282 (match_operand:P 1))
1283 (clobber (match_operand:P 2 "register_operand"))]
1284 "riscv_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
1285 [(set (match_dup 0) (match_dup 3))]
1287 riscv_split_symbol (operands[2], operands[1],
1288 MAX_MACHINE_MODE, &operands[3]);
1291 ;; 64-bit integer moves
1293 (define_expand "movdi"
1294 [(set (match_operand:DI 0 "")
1295 (match_operand:DI 1 ""))]
1298 if (riscv_legitimize_move (DImode, operands[0], operands[1]))
1302 (define_insn "*movdi_32bit"
1303 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m, *f,*f,*r,*f,*m")
1304 (match_operand:DI 1 "move_operand" " r,i,m,r,*J*r,*m,*f,*f,*f"))]
1306 && (register_operand (operands[0], DImode)
1307 || reg_or_0_operand (operands[1], DImode))"
1308 { return riscv_output_move (operands[0], operands[1]); }
1309 [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1310 (set_attr "mode" "DI")])
1312 (define_insn "*movdi_64bit"
1313 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, *f,*f,*r,*f,*m")
1314 (match_operand:DI 1 "move_operand" " r,T,m,rJ,*r*J,*m,*f,*f,*f"))]
1316 && (register_operand (operands[0], DImode)
1317 || reg_or_0_operand (operands[1], DImode))"
1318 { return riscv_output_move (operands[0], operands[1]); }
1319 [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1320 (set_attr "mode" "DI")])
1322 ;; 32-bit Integer moves
1324 (define_expand "mov<mode>"
1325 [(set (match_operand:MOVE32 0 "")
1326 (match_operand:MOVE32 1 ""))]
1329 if (riscv_legitimize_move (<MODE>mode, operands[0], operands[1]))
1333 (define_insn "*movsi_internal"
1334 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, *f,*f,*r,*m")
1335 (match_operand:SI 1 "move_operand" " r,T,m,rJ,*r*J,*m,*f,*f"))]
1336 "(register_operand (operands[0], SImode)
1337 || reg_or_0_operand (operands[1], SImode))"
1338 { return riscv_output_move (operands[0], operands[1]); }
1339 [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore")
1340 (set_attr "mode" "SI")])
1342 ;; 16-bit Integer moves
1344 ;; Unlike most other insns, the move insns can't be split with
1345 ;; different predicates, because register spilling and other parts of
1346 ;; the compiler, have memoized the insn number already.
1347 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
1349 (define_expand "movhi"
1350 [(set (match_operand:HI 0 "")
1351 (match_operand:HI 1 ""))]
1354 if (riscv_legitimize_move (HImode, operands[0], operands[1]))
1358 (define_insn "*movhi_internal"
1359 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r, m, *f,*r")
1360 (match_operand:HI 1 "move_operand" " r,T,m,rJ,*r*J,*f"))]
1361 "(register_operand (operands[0], HImode)
1362 || reg_or_0_operand (operands[1], HImode))"
1363 { return riscv_output_move (operands[0], operands[1]); }
1364 [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1365 (set_attr "mode" "HI")])
1367 ;; HImode constant generation; see riscv_move_integer for details.
1368 ;; si+si->hi without truncation is legal because of
1369 ;; TARGET_TRULY_NOOP_TRUNCATION.
1371 (define_insn "*add<mode>hi3"
1372 [(set (match_operand:HI 0 "register_operand" "=r,r")
1373 (plus:HI (match_operand:HISI 1 "register_operand" " r,r")
1374 (match_operand:HISI 2 "arith_operand" " r,I")))]
1376 { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
1377 [(set_attr "type" "arith")
1378 (set_attr "mode" "HI")])
1380 (define_insn "*xor<mode>hi3"
1381 [(set (match_operand:HI 0 "register_operand" "=r,r")
1382 (xor:HI (match_operand:HISI 1 "register_operand" " r,r")
1383 (match_operand:HISI 2 "arith_operand" " r,I")))]
1386 [(set_attr "type" "logical")
1387 (set_attr "mode" "HI")])
1389 ;; 8-bit Integer moves
1391 (define_expand "movqi"
1392 [(set (match_operand:QI 0 "")
1393 (match_operand:QI 1 ""))]
1396 if (riscv_legitimize_move (QImode, operands[0], operands[1]))
1400 (define_insn "*movqi_internal"
1401 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r, m, *f,*r")
1402 (match_operand:QI 1 "move_operand" " r,I,m,rJ,*r*J,*f"))]
1403 "(register_operand (operands[0], QImode)
1404 || reg_or_0_operand (operands[1], QImode))"
1405 { return riscv_output_move (operands[0], operands[1]); }
1406 [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1407 (set_attr "mode" "QI")])
1409 ;; 32-bit floating point moves
1411 (define_expand "movsf"
1412 [(set (match_operand:SF 0 "")
1413 (match_operand:SF 1 ""))]
1416 if (riscv_legitimize_move (SFmode, operands[0], operands[1]))
1420 (define_insn "*movsf_hardfloat"
1421 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r, *r,*r,*m")
1422 (match_operand:SF 1 "move_operand" " f,G,m,f,G,*r,*f,*G*r,*m,*r"))]
1424 && (register_operand (operands[0], SFmode)
1425 || reg_or_0_operand (operands[1], SFmode))"
1426 { return riscv_output_move (operands[0], operands[1]); }
1427 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1428 (set_attr "mode" "SF")])
1430 (define_insn "*movsf_softfloat"
1431 [(set (match_operand:SF 0 "nonimmediate_operand" "= r,r,m")
1432 (match_operand:SF 1 "move_operand" " Gr,m,r"))]
1434 && (register_operand (operands[0], SFmode)
1435 || reg_or_0_operand (operands[1], SFmode))"
1436 { return riscv_output_move (operands[0], operands[1]); }
1437 [(set_attr "move_type" "move,load,store")
1438 (set_attr "mode" "SF")])
1440 ;; 64-bit floating point moves
1442 (define_expand "movdf"
1443 [(set (match_operand:DF 0 "")
1444 (match_operand:DF 1 ""))]
1447 if (riscv_legitimize_move (DFmode, operands[0], operands[1]))
1451 ;; In RV32, we lack fmv.x.d and fmv.d.x. Go through memory instead.
1452 ;; (However, we can still use fcvt.d.w to zero a floating-point register.)
1453 (define_insn "*movdf_hardfloat_rv32"
1454 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m, *r,*r,*m")
1455 (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r*G,*m,*r"))]
1456 "!TARGET_64BIT && TARGET_DOUBLE_FLOAT
1457 && (register_operand (operands[0], DFmode)
1458 || reg_or_0_operand (operands[1], DFmode))"
1459 { return riscv_output_move (operands[0], operands[1]); }
1460 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,move,load,store")
1461 (set_attr "mode" "DF")])
1463 (define_insn "*movdf_hardfloat_rv64"
1464 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r, *r,*r,*m")
1465 (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r,*f,*r*G,*m,*r"))]
1466 "TARGET_64BIT && TARGET_DOUBLE_FLOAT
1467 && (register_operand (operands[0], DFmode)
1468 || reg_or_0_operand (operands[1], DFmode))"
1469 { return riscv_output_move (operands[0], operands[1]); }
1470 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1471 (set_attr "mode" "DF")])
1473 (define_insn "*movdf_softfloat"
1474 [(set (match_operand:DF 0 "nonimmediate_operand" "= r,r, m")
1475 (match_operand:DF 1 "move_operand" " rG,m,rG"))]
1476 "!TARGET_DOUBLE_FLOAT
1477 && (register_operand (operands[0], DFmode)
1478 || reg_or_0_operand (operands[1], DFmode))"
1479 { return riscv_output_move (operands[0], operands[1]); }
1480 [(set_attr "move_type" "move,load,store")
1481 (set_attr "mode" "DF")])
1484 [(set (match_operand:MOVE64 0 "nonimmediate_operand")
1485 (match_operand:MOVE64 1 "move_operand"))]
1487 && riscv_split_64bit_move_p (operands[0], operands[1])"
1490 riscv_split_doubleword_move (operands[0], operands[1]);
1494 (define_expand "movmemsi"
1495 [(parallel [(set (match_operand:BLK 0 "general_operand")
1496 (match_operand:BLK 1 "general_operand"))
1497 (use (match_operand:SI 2 ""))
1498 (use (match_operand:SI 3 "const_int_operand"))])]
1501 if (riscv_expand_block_move (operands[0], operands[1], operands[2]))
1507 ;; Expand in-line code to clear the instruction cache between operand[0] and
1509 (define_expand "clear_cache"
1510 [(match_operand 0 "pmode_register_operand")
1511 (match_operand 1 "pmode_register_operand")]
1514 #ifdef ICACHE_FLUSH_FUNC
1515 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, ICACHE_FLUSH_FUNC),
1516 LCT_NORMAL, VOIDmode, operands[0], Pmode,
1517 operands[1], Pmode, const0_rtx, Pmode);
1519 emit_insn (gen_fence_i ());
1524 (define_insn "fence"
1525 [(unspec_volatile [(const_int 0)] UNSPECV_FENCE)]
1529 (define_insn "fence_i"
1530 [(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)]
1535 ;; ....................
1539 ;; ....................
1541 ;; Use a QImode shift count, to avoid generating sign or zero extend
1542 ;; instructions for shift counts, and to avoid dropping subregs.
1543 ;; expand_shift_1 can do this automatically when SHIFT_COUNT_TRUNCATED is
1544 ;; defined, but use of that is discouraged.
1546 (define_insn "<optab>si3"
1547 [(set (match_operand:SI 0 "register_operand" "= r")
1549 (match_operand:SI 1 "register_operand" " r")
1550 (match_operand:QI 2 "arith_operand" " rI")))]
1553 if (GET_CODE (operands[2]) == CONST_INT)
1554 operands[2] = GEN_INT (INTVAL (operands[2])
1555 & (GET_MODE_BITSIZE (SImode) - 1));
1557 return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2";
1559 [(set_attr "type" "shift")
1560 (set_attr "mode" "SI")])
1562 (define_insn_and_split "*<optab>si3_mask"
1563 [(set (match_operand:SI 0 "register_operand" "= r")
1565 (match_operand:SI 1 "register_operand" " r")
1568 (match_operand:SI 2 "register_operand" "r")
1569 (match_operand 3 "const_int_operand")) 0)))]
1570 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1571 == GET_MODE_BITSIZE (SImode)-1"
1575 (any_shift:SI (match_dup 1)
1577 "operands[2] = gen_lowpart (QImode, operands[2]);"
1578 [(set_attr "type" "shift")
1579 (set_attr "mode" "SI")])
1581 (define_insn_and_split "*<optab>si3_mask_1"
1582 [(set (match_operand:SI 0 "register_operand" "= r")
1584 (match_operand:SI 1 "register_operand" " r")
1587 (match_operand:DI 2 "register_operand" "r")
1588 (match_operand 3 "const_int_operand")) 0)))]
1590 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1591 == GET_MODE_BITSIZE (SImode)-1"
1595 (any_shift:SI (match_dup 1)
1597 "operands[2] = gen_lowpart (QImode, operands[2]);"
1598 [(set_attr "type" "shift")
1599 (set_attr "mode" "SI")])
1601 (define_insn "<optab>di3"
1602 [(set (match_operand:DI 0 "register_operand" "= r")
1604 (match_operand:DI 1 "register_operand" " r")
1605 (match_operand:QI 2 "arith_operand" " rI")))]
1608 if (GET_CODE (operands[2]) == CONST_INT)
1609 operands[2] = GEN_INT (INTVAL (operands[2])
1610 & (GET_MODE_BITSIZE (DImode) - 1));
1612 return "<insn>%i2\t%0,%1,%2";
1614 [(set_attr "type" "shift")
1615 (set_attr "mode" "DI")])
1617 (define_insn_and_split "*<optab>di3_mask"
1618 [(set (match_operand:DI 0 "register_operand" "= r")
1620 (match_operand:DI 1 "register_operand" " r")
1623 (match_operand:SI 2 "register_operand" "r")
1624 (match_operand 3 "const_int_operand")) 0)))]
1626 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1627 == GET_MODE_BITSIZE (DImode)-1"
1631 (any_shift:DI (match_dup 1)
1633 "operands[2] = gen_lowpart (QImode, operands[2]);"
1634 [(set_attr "type" "shift")
1635 (set_attr "mode" "DI")])
1637 (define_insn_and_split "*<optab>di3_mask_1"
1638 [(set (match_operand:DI 0 "register_operand" "= r")
1640 (match_operand:DI 1 "register_operand" " r")
1643 (match_operand:DI 2 "register_operand" "r")
1644 (match_operand 3 "const_int_operand")) 0)))]
1646 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1647 == GET_MODE_BITSIZE (DImode)-1"
1651 (any_shift:DI (match_dup 1)
1653 "operands[2] = gen_lowpart (QImode, operands[2]);"
1654 [(set_attr "type" "shift")
1655 (set_attr "mode" "DI")])
1657 (define_insn "*<optab>si3_extend"
1658 [(set (match_operand:DI 0 "register_operand" "= r")
1660 (any_shift:SI (match_operand:SI 1 "register_operand" " r")
1661 (match_operand:QI 2 "arith_operand" " rI"))))]
1664 if (GET_CODE (operands[2]) == CONST_INT)
1665 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1667 return "<insn>%i2w\t%0,%1,%2";
1669 [(set_attr "type" "shift")
1670 (set_attr "mode" "SI")])
1672 (define_insn_and_split "*<optab>si3_extend_mask"
1673 [(set (match_operand:DI 0 "register_operand" "= r")
1676 (match_operand:SI 1 "register_operand" " r")
1679 (match_operand:SI 2 "register_operand" " r")
1680 (match_operand 3 "const_int_operand")) 0))))]
1682 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1683 == GET_MODE_BITSIZE (SImode)-1"
1688 (any_shift:SI (match_dup 1)
1690 "operands[2] = gen_lowpart (QImode, operands[2]);"
1691 [(set_attr "type" "shift")
1692 (set_attr "mode" "SI")])
1694 (define_insn_and_split "*<optab>si3_extend_mask_1"
1695 [(set (match_operand:DI 0 "register_operand" "= r")
1698 (match_operand:SI 1 "register_operand" " r")
1701 (match_operand:DI 2 "register_operand" " r")
1702 (match_operand 3 "const_int_operand")) 0))))]
1704 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1705 == GET_MODE_BITSIZE (SImode)-1"
1710 (any_shift:SI (match_dup 1)
1712 "operands[2] = gen_lowpart (QImode, operands[2]);"
1713 [(set_attr "type" "shift")
1714 (set_attr "mode" "SI")])
1716 ;; Non-canonical, but can be formed by ree when combine is not successful at
1717 ;; producing one of the two canonical patterns below.
1718 (define_insn "*lshrsi3_zero_extend_1"
1719 [(set (match_operand:DI 0 "register_operand" "=r")
1721 (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
1722 (match_operand 2 "const_int_operand"))))]
1723 "TARGET_64BIT && (INTVAL (operands[2]) & 0x1f) > 0"
1725 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1727 return "srliw\t%0,%1,%2";
1729 [(set_attr "type" "shift")
1730 (set_attr "mode" "SI")])
1732 ;; Canonical form for a zero-extend of a logical right shift.
1733 (define_insn "*lshrsi3_zero_extend_2"
1734 [(set (match_operand:DI 0 "register_operand" "=r")
1735 (zero_extract:DI (match_operand:DI 1 "register_operand" " r")
1736 (match_operand 2 "const_int_operand")
1737 (match_operand 3 "const_int_operand")))]
1738 "(TARGET_64BIT && (INTVAL (operands[3]) > 0)
1739 && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))"
1741 return "srliw\t%0,%1,%3";
1743 [(set_attr "type" "shift")
1744 (set_attr "mode" "SI")])
1746 ;; Canonical form for a zero-extend of a logical right shift when the
1747 ;; shift count is 31.
1748 (define_insn "*lshrsi3_zero_extend_3"
1749 [(set (match_operand:DI 0 "register_operand" "=r")
1750 (lt:DI (match_operand:SI 1 "register_operand" " r")
1754 return "srliw\t%0,%1,31";
1756 [(set_attr "type" "shift")
1757 (set_attr "mode" "SI")])
1759 ;; Handle AND with 2^N-1 for N from 12 to XLEN. This can be split into
1760 ;; two logical shifts. Otherwise it requires 3 instructions: lui,
1761 ;; xor/addi/srli, and.
1763 [(set (match_operand:GPR 0 "register_operand")
1764 (and:GPR (match_operand:GPR 1 "register_operand")
1765 (match_operand:GPR 2 "p2m1_shift_operand")))]
1768 (ashift:GPR (match_dup 1) (match_dup 2)))
1770 (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
1772 operands[2] = GEN_INT (BITS_PER_WORD
1773 - exact_log2 (INTVAL (operands[2]) + 1));
1776 ;; Handle AND with 0xF...F0...0 where there are 32 to 63 zeros. This can be
1777 ;; split into two shifts. Otherwise it requires 3 instructions: li, sll, and.
1779 [(set (match_operand:DI 0 "register_operand")
1780 (and:DI (match_operand:DI 1 "register_operand")
1781 (match_operand:DI 2 "high_mask_shift_operand")))]
1784 (lshiftrt:DI (match_dup 1) (match_dup 2)))
1786 (ashift:DI (match_dup 0) (match_dup 2)))]
1788 operands[2] = GEN_INT (ctz_hwi (INTVAL (operands[2])));
1792 ;; ....................
1794 ;; CONDITIONAL BRANCHES
1796 ;; ....................
1798 ;; Conditional branches
1800 (define_insn "*branch_order<mode>"
1803 (match_operator 1 "order_operator"
1804 [(match_operand:X 2 "register_operand" "r")
1805 (match_operand:X 3 "register_operand" "r")])
1806 (label_ref (match_operand 0 "" ""))
1810 [(set_attr "type" "branch")
1811 (set_attr "mode" "none")])
1813 (define_insn "*branch_zero<mode>"
1816 (match_operator 1 "signed_order_operator"
1817 [(match_operand:X 2 "register_operand" "r")
1819 (label_ref (match_operand 0 "" ""))
1823 [(set_attr "type" "branch")
1824 (set_attr "mode" "none")])
1826 ;; Used to implement built-in functions.
1827 (define_expand "condjump"
1829 (if_then_else (match_operand 0)
1830 (label_ref (match_operand 1))
1833 (define_expand "cbranch<mode>4"
1835 (if_then_else (match_operator 0 "comparison_operator"
1836 [(match_operand:BR 1 "register_operand")
1837 (match_operand:BR 2 "nonmemory_operand")])
1838 (label_ref (match_operand 3 ""))
1842 riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1843 operands[1], operands[2]);
1847 (define_expand "cbranch<mode>4"
1849 (if_then_else (match_operator 0 "fp_branch_comparison"
1850 [(match_operand:ANYF 1 "register_operand")
1851 (match_operand:ANYF 2 "register_operand")])
1852 (label_ref (match_operand 3 ""))
1856 riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1857 operands[1], operands[2]);
1861 (define_insn_and_split "*branch_on_bit<X:mode>"
1864 (match_operator 0 "equality_operator"
1865 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1867 (match_operand 3 "branch_on_bit_operand"))
1869 (label_ref (match_operand 1))
1871 (clobber (match_scratch:X 4 "=&r"))]
1876 (ashift:X (match_dup 2) (match_dup 3)))
1879 (match_op_dup 0 [(match_dup 4) (const_int 0)])
1880 (label_ref (match_operand 1))
1883 int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]);
1884 operands[3] = GEN_INT (shift);
1886 if (GET_CODE (operands[0]) == EQ)
1887 operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx);
1889 operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx);
1892 (define_insn_and_split "*branch_on_bit_range<X:mode>"
1895 (match_operator 0 "equality_operator"
1896 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1897 (match_operand 3 "branch_on_bit_operand")
1900 (label_ref (match_operand 1))
1902 (clobber (match_scratch:X 4 "=&r"))]
1907 (ashift:X (match_dup 2) (match_dup 3)))
1910 (match_op_dup 0 [(match_dup 4) (const_int 0)])
1911 (label_ref (match_operand 1))
1914 operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]));
1918 ;; ....................
1920 ;; SETTING A REGISTER FROM A COMPARISON
1922 ;; ....................
1924 ;; Destination is always set in SI mode.
1926 (define_expand "cstore<mode>4"
1927 [(set (match_operand:SI 0 "register_operand")
1928 (match_operator:SI 1 "order_operator"
1929 [(match_operand:GPR 2 "register_operand")
1930 (match_operand:GPR 3 "nonmemory_operand")]))]
1933 riscv_expand_int_scc (operands[0], GET_CODE (operands[1]), operands[2],
1938 (define_expand "cstore<mode>4"
1939 [(set (match_operand:SI 0 "register_operand")
1940 (match_operator:SI 1 "fp_scc_comparison"
1941 [(match_operand:ANYF 2 "register_operand")
1942 (match_operand:ANYF 3 "register_operand")]))]
1945 riscv_expand_float_scc (operands[0], GET_CODE (operands[1]), operands[2],
1950 (define_insn "*cstore<ANYF:mode><X:mode>4"
1951 [(set (match_operand:X 0 "register_operand" "=r")
1952 (match_operator:X 1 "fp_native_comparison"
1953 [(match_operand:ANYF 2 "register_operand" " f")
1954 (match_operand:ANYF 3 "register_operand" " f")]))]
1956 "f%C1.<fmt>\t%0,%2,%3"
1957 [(set_attr "type" "fcmp")
1958 (set_attr "mode" "<UNITMODE>")])
1960 (define_expand "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4"
1961 [(parallel [(set (match_operand:X 0 "register_operand")
1963 [(match_operand:ANYF 1 "register_operand")
1964 (match_operand:ANYF 2 "register_operand")]
1966 (clobber (match_scratch:X 3))])]
1967 "TARGET_HARD_FLOAT")
1969 (define_insn "*f<quiet_pattern>_quiet<ANYF:mode><X:mode>4_default"
1970 [(set (match_operand:X 0 "register_operand" "=r")
1972 [(match_operand:ANYF 1 "register_operand" " f")
1973 (match_operand:ANYF 2 "register_operand" " f")]
1975 (clobber (match_scratch:X 3 "=&r"))]
1976 "TARGET_HARD_FLOAT && ! HONOR_SNANS (<ANYF:MODE>mode)"
1977 "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3"
1978 [(set_attr "type" "fcmp")
1979 (set_attr "mode" "<UNITMODE>")
1980 (set (attr "length") (const_int 12))])
1982 (define_insn "*f<quiet_pattern>_quiet<ANYF:mode><X:mode>4_snan"
1983 [(set (match_operand:X 0 "register_operand" "=r")
1985 [(match_operand:ANYF 1 "register_operand" " f")
1986 (match_operand:ANYF 2 "register_operand" " f")]
1988 (clobber (match_scratch:X 3 "=&r"))]
1989 "TARGET_HARD_FLOAT && HONOR_SNANS (<ANYF:MODE>mode)"
1990 "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3\n\tfeq.<fmt>\tzero,%1,%2"
1991 [(set_attr "type" "fcmp")
1992 (set_attr "mode" "<UNITMODE>")
1993 (set (attr "length") (const_int 16))])
1995 (define_insn "*seq_zero_<X:mode><GPR:mode>"
1996 [(set (match_operand:GPR 0 "register_operand" "=r")
1997 (eq:GPR (match_operand:X 1 "register_operand" " r")
2001 [(set_attr "type" "slt")
2002 (set_attr "mode" "<X:MODE>")])
2004 (define_insn "*sne_zero_<X:mode><GPR:mode>"
2005 [(set (match_operand:GPR 0 "register_operand" "=r")
2006 (ne:GPR (match_operand:X 1 "register_operand" " r")
2010 [(set_attr "type" "slt")
2011 (set_attr "mode" "<X:MODE>")])
2013 (define_insn "*sgt<u>_<X:mode><GPR:mode>"
2014 [(set (match_operand:GPR 0 "register_operand" "= r")
2015 (any_gt:GPR (match_operand:X 1 "register_operand" " r")
2016 (match_operand:X 2 "reg_or_0_operand" " rJ")))]
2019 [(set_attr "type" "slt")
2020 (set_attr "mode" "<X:MODE>")])
2022 (define_insn "*sge<u>_<X:mode><GPR:mode>"
2023 [(set (match_operand:GPR 0 "register_operand" "=r")
2024 (any_ge:GPR (match_operand:X 1 "register_operand" " r")
2027 "slt%i2<u>\t%0,zero,%1"
2028 [(set_attr "type" "slt")
2029 (set_attr "mode" "<MODE>")])
2031 (define_insn "*slt<u>_<X:mode><GPR:mode>"
2032 [(set (match_operand:GPR 0 "register_operand" "= r")
2033 (any_lt:GPR (match_operand:X 1 "register_operand" " r")
2034 (match_operand:X 2 "arith_operand" " rI")))]
2036 "slt%i2<u>\t%0,%1,%2"
2037 [(set_attr "type" "slt")
2038 (set_attr "mode" "<MODE>")])
2040 (define_insn "*sle<u>_<X:mode><GPR:mode>"
2041 [(set (match_operand:GPR 0 "register_operand" "=r")
2042 (any_le:GPR (match_operand:X 1 "register_operand" " r")
2043 (match_operand:X 2 "sle_operand" "")))]
2046 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
2047 return "slt%i2<u>\t%0,%1,%2";
2049 [(set_attr "type" "slt")
2050 (set_attr "mode" "<MODE>")])
2053 ;; ....................
2055 ;; UNCONDITIONAL BRANCHES
2057 ;; ....................
2059 ;; Unconditional branches.
2063 (label_ref (match_operand 0 "" "")))]
2066 [(set_attr "type" "jump")
2067 (set_attr "mode" "none")])
2069 (define_expand "indirect_jump"
2070 [(set (pc) (match_operand 0 "register_operand"))]
2073 operands[0] = force_reg (Pmode, operands[0]);
2074 if (Pmode == SImode)
2075 emit_jump_insn (gen_indirect_jumpsi (operands[0]));
2077 emit_jump_insn (gen_indirect_jumpdi (operands[0]));
2081 (define_insn "indirect_jump<mode>"
2082 [(set (pc) (match_operand:P 0 "register_operand" "l"))]
2085 [(set_attr "type" "jump")
2086 (set_attr "mode" "none")])
2088 (define_expand "tablejump"
2089 [(set (pc) (match_operand 0 "register_operand" ""))
2090 (use (label_ref (match_operand 1 "" "")))]
2093 if (CASE_VECTOR_PC_RELATIVE)
2094 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
2095 gen_rtx_LABEL_REF (Pmode, operands[1]),
2096 NULL_RTX, 0, OPTAB_DIRECT);
2098 if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode)
2099 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
2101 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
2105 (define_insn "tablejump<mode>"
2106 [(set (pc) (match_operand:GPR 0 "register_operand" "l"))
2107 (use (label_ref (match_operand 1 "" "")))]
2110 [(set_attr "type" "jump")
2111 (set_attr "mode" "none")])
2114 ;; ....................
2116 ;; Function prologue/epilogue
2118 ;; ....................
2121 (define_expand "prologue"
2125 riscv_expand_prologue ();
2129 ;; Block any insns from being moved before this point, since the
2130 ;; profiling call to mcount can use various registers that aren't
2131 ;; saved or used to pass arguments.
2133 (define_insn "blockage"
2134 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2137 [(set_attr "type" "ghost")
2138 (set_attr "mode" "none")])
2140 (define_expand "epilogue"
2144 riscv_expand_epilogue (NORMAL_RETURN);
2148 (define_expand "sibcall_epilogue"
2152 riscv_expand_epilogue (SIBCALL_RETURN);
2156 ;; Trivial return. Make it look like a normal return insn as that
2157 ;; allows jump optimizations to work better.
2159 (define_expand "return"
2161 "riscv_can_use_return_insn ()"
2164 (define_insn "simple_return"
2168 return riscv_output_return ();
2170 [(set_attr "type" "jump")
2171 (set_attr "mode" "none")])
2175 (define_insn "simple_return_internal"
2177 (use (match_operand 0 "pmode_register_operand" ""))]
2180 [(set_attr "type" "jump")
2181 (set_attr "mode" "none")])
2183 ;; This is used in compiling the unwind routines.
2184 (define_expand "eh_return"
2185 [(use (match_operand 0 "general_operand"))]
2188 if (GET_MODE (operands[0]) != word_mode)
2189 operands[0] = convert_to_mode (word_mode, operands[0], 0);
2191 emit_insn (gen_eh_set_lr_di (operands[0]));
2193 emit_insn (gen_eh_set_lr_si (operands[0]));
2195 emit_jump_insn (gen_eh_return_internal ());
2200 ;; Clobber the return address on the stack. We can't expand this
2201 ;; until we know where it will be put in the stack frame.
2203 (define_insn "eh_set_lr_si"
2204 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2205 (clobber (match_scratch:SI 1 "=&r"))]
2209 (define_insn "eh_set_lr_di"
2210 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2211 (clobber (match_scratch:DI 1 "=&r"))]
2216 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
2217 (clobber (match_scratch 1))]
2221 riscv_set_return_address (operands[0], operands[1]);
2225 (define_insn_and_split "eh_return_internal"
2229 "epilogue_completed"
2231 "riscv_expand_epilogue (EXCEPTION_RETURN); DONE;")
2234 ;; ....................
2238 ;; ....................
2240 (define_expand "sibcall"
2241 [(parallel [(call (match_operand 0 "")
2242 (match_operand 1 ""))
2243 (use (match_operand 2 "")) ;; next_arg_reg
2244 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
2247 rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2248 emit_call_insn (gen_sibcall_internal (target, operands[1]));
2252 (define_insn "sibcall_internal"
2253 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U"))
2254 (match_operand 1 "" ""))]
2255 "SIBLING_CALL_P (insn)"
2260 [(set_attr "type" "call")])
2262 (define_expand "sibcall_value"
2263 [(parallel [(set (match_operand 0 "")
2264 (call (match_operand 1 "")
2265 (match_operand 2 "")))
2266 (use (match_operand 3 ""))])] ;; next_arg_reg
2269 rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2270 emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2]));
2274 (define_insn "sibcall_value_internal"
2275 [(set (match_operand 0 "" "")
2276 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U"))
2277 (match_operand 2 "" "")))]
2278 "SIBLING_CALL_P (insn)"
2283 [(set_attr "type" "call")])
2285 (define_expand "call"
2286 [(parallel [(call (match_operand 0 "")
2287 (match_operand 1 ""))
2288 (use (match_operand 2 "")) ;; next_arg_reg
2289 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
2292 rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2293 emit_call_insn (gen_call_internal (target, operands[1]));
2297 (define_insn "call_internal"
2298 [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U"))
2299 (match_operand 1 "" ""))
2300 (clobber (reg:SI RETURN_ADDR_REGNUM))]
2306 [(set_attr "type" "call")])
2308 (define_expand "call_value"
2309 [(parallel [(set (match_operand 0 "")
2310 (call (match_operand 1 "")
2311 (match_operand 2 "")))
2312 (use (match_operand 3 ""))])] ;; next_arg_reg
2315 rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2316 emit_call_insn (gen_call_value_internal (operands[0], target, operands[2]));
2320 (define_insn "call_value_internal"
2321 [(set (match_operand 0 "" "")
2322 (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U"))
2323 (match_operand 2 "" "")))
2324 (clobber (reg:SI RETURN_ADDR_REGNUM))]
2330 [(set_attr "type" "call")])
2332 ;; Call subroutine returning any type.
2334 (define_expand "untyped_call"
2335 [(parallel [(call (match_operand 0 "")
2337 (match_operand 1 "")
2338 (match_operand 2 "")])]
2343 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2345 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2347 rtx set = XVECEXP (operands[2], 0, i);
2348 riscv_emit_move (SET_DEST (set), SET_SRC (set));
2351 emit_insn (gen_blockage ());
2359 [(set_attr "type" "nop")
2360 (set_attr "mode" "none")])
2363 [(trap_if (const_int 1) (const_int 0))]
2367 (define_insn "gpr_save"
2368 [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_SAVE)
2369 (clobber (reg:SI T0_REGNUM))
2370 (clobber (reg:SI T1_REGNUM))]
2372 { return riscv_output_gpr_save (INTVAL (operands[0])); })
2374 (define_insn "gpr_restore"
2375 [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_RESTORE)]
2377 "tail\t__riscv_restore_%0")
2379 (define_insn "gpr_restore_return"
2381 (use (match_operand 0 "pmode_register_operand" ""))
2386 (define_insn "riscv_frflags"
2387 [(set (match_operand:SI 0 "register_operand" "=r")
2388 (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))]
2392 (define_insn "riscv_fsflags"
2393 [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)]
2397 (define_insn "riscv_mret"
2399 (unspec_volatile [(const_int 0)] UNSPECV_MRET)]
2403 (define_insn "riscv_sret"
2405 (unspec_volatile [(const_int 0)] UNSPECV_SRET)]
2409 (define_insn "riscv_uret"
2411 (unspec_volatile [(const_int 0)] UNSPECV_URET)]
2415 (define_insn "stack_tie<mode>"
2416 [(set (mem:BLK (scratch))
2417 (unspec:BLK [(match_operand:X 0 "register_operand" "r")
2418 (match_operand:X 1 "register_operand" "r")]
2422 [(set_attr "length" "0")]
2426 (include "peephole.md")
2428 (include "generic.md")