gcc/ChangeLog:
[official-gcc.git] / gcc / config / riscv / riscv.md
blob18dba3beea1de87c2346ba99cad7c5f6e764d50e
1 ;; Machine description for RISC-V for GNU compiler.
2 ;; Copyright (C) 2011-2017 Free Software Foundation, Inc.
3 ;; Contributed by Andrew Waterman (andrew@sifive.com).
4 ;; Based on MIPS target for GNU compiler.
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.
22 (define_c_enum "unspec" [
23   ;; Override return address for exception handling.
24   UNSPEC_EH_RETURN
26   ;; Symbolic accesses.  The order of this list must match that of
27   ;; enum riscv_symbol_type in riscv-protos.h.
28   UNSPEC_ADDRESS_FIRST
29   UNSPEC_PCREL
30   UNSPEC_LOAD_GOT
31   UNSPEC_TLS
32   UNSPEC_TLS_LE
33   UNSPEC_TLS_IE
34   UNSPEC_TLS_GD
36   ;; High part of PC-relative address.
37   UNSPEC_AUIPC
39   ;; Floating-point unspecs.
40   UNSPEC_FLT_QUIET
41   UNSPEC_FLE_QUIET
42   UNSPEC_COPYSIGN
43   UNSPEC_LRINT
44   UNSPEC_LROUND
46   ;; Stack tie
47   UNSPEC_TIE
50 (define_c_enum "unspecv" [
51   ;; Register save and restore.
52   UNSPECV_GPR_SAVE
53   UNSPECV_GPR_RESTORE
55   ;; Floating-point unspecs.
56   UNSPECV_FRFLAGS
57   UNSPECV_FSFLAGS
59   ;; Blockage and synchronization.
60   UNSPECV_BLOCKAGE
61   UNSPECV_FENCE
62   UNSPECV_FENCE_I
65 (define_constants
66   [(RETURN_ADDR_REGNUM          1)
67    (T0_REGNUM                   5)
68    (T1_REGNUM                   6)
69    (S0_REGNUM                   8)
70    (S1_REGNUM                   9)
71    (S2_REGNUM                   18)
74 (include "predicates.md")
75 (include "constraints.md")
77 ;; ....................
79 ;;      Attributes
81 ;; ....................
83 (define_attr "got" "unset,xgot_high,load"
84   (const_string "unset"))
86 ;; Classification of moves, extensions and truncations.  Most values
87 ;; are as for "type" (see below) but there are also the following
88 ;; move-specific values:
90 ;; andi         a single ANDI instruction
91 ;; shift_shift  a shift left followed by a shift right
93 ;; This attribute is used to determine the instruction's length and
94 ;; scheduling type.  For doubleword moves, the attribute always describes
95 ;; the split instructions; in some cases, it is more appropriate for the
96 ;; scheduling type to be "multi" instead.
97 (define_attr "move_type"
98   "unknown,load,fpload,store,fpstore,mtc,mfc,move,fmove,
99    const,logical,arith,andi,shift_shift"
100   (const_string "unknown"))
102 ;; Main data type used by the insn
103 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
104   (const_string "unknown"))
106 ;; True if the main data type is twice the size of a word.
107 (define_attr "dword_mode" "no,yes"
108   (cond [(and (eq_attr "mode" "DI,DF")
109               (eq (symbol_ref "TARGET_64BIT") (const_int 0)))
110          (const_string "yes")
112          (and (eq_attr "mode" "TI,TF")
113               (ne (symbol_ref "TARGET_64BIT") (const_int 0)))
114          (const_string "yes")]
115         (const_string "no")))
117 ;; Classification of each insn.
118 ;; branch       conditional branch
119 ;; jump         unconditional jump
120 ;; call         unconditional call
121 ;; load         load instruction(s)
122 ;; fpload       floating point load
123 ;; store        store instruction(s)
124 ;; fpstore      floating point store
125 ;; mtc          transfer to coprocessor
126 ;; mfc          transfer from coprocessor
127 ;; const        load constant
128 ;; arith        integer arithmetic instructions
129 ;; logical      integer logical instructions
130 ;; shift        integer shift instructions
131 ;; slt          set less than instructions
132 ;; imul         integer multiply 
133 ;; idiv         integer divide
134 ;; move         integer register move (addi rd, rs1, 0)
135 ;; fmove        floating point register move
136 ;; fadd         floating point add/subtract
137 ;; fmul         floating point multiply
138 ;; fmadd        floating point multiply-add
139 ;; fdiv         floating point divide
140 ;; fcmp         floating point compare
141 ;; fcvt         floating point convert
142 ;; fsqrt        floating point square root
143 ;; multi        multiword sequence (or user asm statements)
144 ;; nop          no operation
145 ;; ghost        an instruction that produces no real code
146 (define_attr "type"
147   "unknown,branch,jump,call,load,fpload,store,fpstore,
148    mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul,
149    fmadd,fdiv,fcmp,fcvt,fsqrt,multi,nop,ghost"
150   (cond [(eq_attr "got" "load") (const_string "load")
152          ;; If a doubleword move uses these expensive instructions,
153          ;; it is usually better to schedule them in the same way
154          ;; as the singleword form, rather than as "multi".
155          (eq_attr "move_type" "load") (const_string "load")
156          (eq_attr "move_type" "fpload") (const_string "fpload")
157          (eq_attr "move_type" "store") (const_string "store")
158          (eq_attr "move_type" "fpstore") (const_string "fpstore")
159          (eq_attr "move_type" "mtc") (const_string "mtc")
160          (eq_attr "move_type" "mfc") (const_string "mfc")
162          ;; These types of move are always single insns.
163          (eq_attr "move_type" "fmove") (const_string "fmove")
164          (eq_attr "move_type" "arith") (const_string "arith")
165          (eq_attr "move_type" "logical") (const_string "logical")
166          (eq_attr "move_type" "andi") (const_string "logical")
168          ;; These types of move are always split.
169          (eq_attr "move_type" "shift_shift")
170            (const_string "multi")
172          ;; These types of move are split for doubleword modes only.
173          (and (eq_attr "move_type" "move,const")
174               (eq_attr "dword_mode" "yes"))
175            (const_string "multi")
176          (eq_attr "move_type" "move") (const_string "move")
177          (eq_attr "move_type" "const") (const_string "const")]
178         (const_string "unknown")))
180 ;; Length of instruction in bytes.
181 (define_attr "length" ""
182    (cond [
183           ;; Branches further than +/- 4 KiB require two instructions.
184           (eq_attr "type" "branch")
185           (if_then_else (and (le (minus (match_dup 0) (pc)) (const_int 4088))
186                                   (le (minus (pc) (match_dup 0)) (const_int 4092)))
187           (const_int 4)
188           (const_int 8))
190           ;; Conservatively assume calls take two instructions (AUIPC + JALR).
191           ;; The linker will opportunistically relax the sequence to JAL.
192           (eq_attr "type" "call") (const_int 8)
194           ;; "Ghost" instructions occupy no space.
195           (eq_attr "type" "ghost") (const_int 0)
197           (eq_attr "got" "load") (const_int 8)
199           (eq_attr "type" "fcmp") (const_int 8)
201           ;; SHIFT_SHIFTs are decomposed into two separate instructions.
202           (eq_attr "move_type" "shift_shift")
203                 (const_int 8)
205           ;; Check for doubleword moves that are decomposed into two
206           ;; instructions.
207           (and (eq_attr "move_type" "mtc,mfc,move")
208                (eq_attr "dword_mode" "yes"))
209           (const_int 8)
211           ;; Doubleword CONST{,N} moves are split into two word
212           ;; CONST{,N} moves.
213           (and (eq_attr "move_type" "const")
214                (eq_attr "dword_mode" "yes"))
215           (symbol_ref "riscv_split_const_insns (operands[1]) * 4")
217           ;; Otherwise, constants, loads and stores are handled by external
218           ;; routines.
219           (eq_attr "move_type" "load,fpload")
220           (symbol_ref "riscv_load_store_insns (operands[1], insn) * 4")
221           (eq_attr "move_type" "store,fpstore")
222           (symbol_ref "riscv_load_store_insns (operands[0], insn) * 4")
223           ] (const_int 4)))
225 ;; Is copying of this instruction disallowed?
226 (define_attr "cannot_copy" "no,yes" (const_string "no"))
228 ;; Describe a user's asm statement.
229 (define_asm_attributes
230   [(set_attr "type" "multi")])
232 ;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
233 ;; from the same template.
234 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
236 ;; This mode iterator allows :P to be used for patterns that operate on
237 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
238 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
240 ;; Likewise, but for XLEN-sized quantities.
241 (define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")])
243 ;; Branches operate on XLEN-sized quantities, but for RV64 we accept
244 ;; QImode values so we can force zero-extension.
245 (define_mode_iterator BR [(QI "TARGET_64BIT") SI (DI "TARGET_64BIT")])
247 ;; 32-bit moves for which we provide move patterns.
248 (define_mode_iterator MOVE32 [SI])
250 ;; 64-bit modes for which we provide move patterns.
251 (define_mode_iterator MOVE64 [DI DF])
253 ;; Iterator for sub-32-bit integer modes.
254 (define_mode_iterator SHORT [QI HI])
256 ;; Iterator for HImode constant generation.
257 (define_mode_iterator HISI [HI SI])
259 ;; Iterator for QImode extension patterns.
260 (define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")])
262 ;; Iterator for hardware integer modes narrower than XLEN.
263 (define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")])
265 ;; Iterator for hardware-supported integer modes.
266 (define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")])
268 ;; Iterator for hardware-supported floating-point modes.
269 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
270                             (DF "TARGET_DOUBLE_FLOAT")])
272 ;; This attribute gives the length suffix for a sign- or zero-extension
273 ;; instruction.
274 (define_mode_attr size [(QI "b") (HI "h")])
276 ;; Mode attributes for loads.
277 (define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")])
279 ;; Instruction names for stores.
280 (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")])
282 ;; This attribute gives the best constraint to use for registers of
283 ;; a given mode.
284 (define_mode_attr reg [(SI "d") (DI "d") (CC "d")])
286 ;; This attribute gives the format suffix for floating-point operations.
287 (define_mode_attr fmt [(SF "s") (DF "d")])
289 ;; This attribute gives the integer suffix for floating-point conversions.
290 (define_mode_attr ifmt [(SI "w") (DI "l")])
292 ;; This attribute gives the format suffix for atomic memory operations.
293 (define_mode_attr amo [(SI "w") (DI "d")])
295 ;; This attribute gives the upper-case mode name for one unit of a
296 ;; floating-point mode.
297 (define_mode_attr UNITMODE [(SF "SF") (DF "DF")])
299 ;; This attribute gives the integer mode that has half the size of
300 ;; the controlling mode.
301 (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
303 ;; Iterator and attributes for floating-point rounding instructions.
304 (define_int_iterator RINT [UNSPEC_LRINT UNSPEC_LROUND])
305 (define_int_attr rint_pattern [(UNSPEC_LRINT "rint") (UNSPEC_LROUND "round")])
306 (define_int_attr rint_rm [(UNSPEC_LRINT "dyn") (UNSPEC_LROUND "rmm")])
308 ;; Iterator and attributes for quiet comparisons.
309 (define_int_iterator QUIET_COMPARISON [UNSPEC_FLT_QUIET UNSPEC_FLE_QUIET])
310 (define_int_attr quiet_pattern [(UNSPEC_FLT_QUIET "lt") (UNSPEC_FLE_QUIET "le")])
312 ;; This code iterator allows signed and unsigned widening multiplications
313 ;; to use the same template.
314 (define_code_iterator any_extend [sign_extend zero_extend])
316 ;; This code iterator allows the two right shift instructions to be
317 ;; generated from the same template.
318 (define_code_iterator any_shiftrt [ashiftrt lshiftrt])
320 ;; This code iterator allows the three shift instructions to be generated
321 ;; from the same template.
322 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
324 ;; This code iterator allows the three bitwise instructions to be generated
325 ;; from the same template.
326 (define_code_iterator any_bitwise [and ior xor])
328 ;; This code iterator allows unsigned and signed division to be generated
329 ;; from the same template.
330 (define_code_iterator any_div [div udiv mod umod])
332 ;; This code iterator allows unsigned and signed modulus to be generated
333 ;; from the same template.
334 (define_code_iterator any_mod [mod umod])
336 ;; These code iterators allow the signed and unsigned scc operations to use
337 ;; the same template.
338 (define_code_iterator any_gt [gt gtu])
339 (define_code_iterator any_ge [ge geu])
340 (define_code_iterator any_lt [lt ltu])
341 (define_code_iterator any_le [le leu])
343 ;; <u> expands to an empty string when doing a signed operation and
344 ;; "u" when doing an unsigned operation.
345 (define_code_attr u [(sign_extend "") (zero_extend "u")
346                      (gt "") (gtu "u")
347                      (ge "") (geu "u")
348                      (lt "") (ltu "u")
349                      (le "") (leu "u")])
351 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
352 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
354 ;; <optab> expands to the name of the optab for a particular code.
355 (define_code_attr optab [(ashift "ashl")
356                          (ashiftrt "ashr")
357                          (lshiftrt "lshr")
358                          (div "div")
359                          (mod "mod")
360                          (udiv "udiv")
361                          (umod "umod")
362                          (ge "ge")
363                          (le "le")
364                          (gt "gt")
365                          (lt "lt")
366                          (ior "ior")
367                          (xor "xor")
368                          (and "and")
369                          (plus "add")
370                          (minus "sub")])
372 ;; <insn> expands to the name of the insn that implements a particular code.
373 (define_code_attr insn [(ashift "sll")
374                         (ashiftrt "sra")
375                         (lshiftrt "srl")
376                         (div "div")
377                         (mod "rem")
378                         (udiv "divu")
379                         (umod "remu")
380                         (ior "or")
381                         (xor "xor")
382                         (and "and")
383                         (plus "add")
384                         (minus "sub")])
386 ;; Ghost instructions produce no real code and introduce no hazards.
387 ;; They exist purely to express an effect on dataflow.
388 (define_insn_reservation "ghost" 0
389   (eq_attr "type" "ghost")
390   "nothing")
393 ;;  ....................
395 ;;      ADDITION
397 ;;  ....................
400 (define_insn "add<mode>3"
401   [(set (match_operand:ANYF            0 "register_operand" "=f")
402         (plus:ANYF (match_operand:ANYF 1 "register_operand" " f")
403                    (match_operand:ANYF 2 "register_operand" " f")))]
404   "TARGET_HARD_FLOAT"
405   "fadd.<fmt>\t%0,%1,%2"
406   [(set_attr "type" "fadd")
407    (set_attr "mode" "<UNITMODE>")])
409 (define_insn "addsi3"
410   [(set (match_operand:SI          0 "register_operand" "=r,r")
411         (plus:SI (match_operand:SI 1 "register_operand" " r,r")
412                  (match_operand:SI 2 "arith_operand"    " r,I")))]
413   ""
414   { return TARGET_64BIT ? "addw\t%0,%1,%2" : "add\t%0,%1,%2"; }
415   [(set_attr "type" "arith")
416    (set_attr "mode" "SI")])
418 (define_insn "adddi3"
419   [(set (match_operand:DI          0 "register_operand" "=r,r")
420         (plus:DI (match_operand:DI 1 "register_operand" " r,r")
421                  (match_operand:DI 2 "arith_operand"    " r,I")))]
422   "TARGET_64BIT"
423   "add\t%0,%1,%2"
424   [(set_attr "type" "arith")
425    (set_attr "mode" "DI")])
427 (define_insn "*addsi3_extended"
428   [(set (match_operand:DI               0 "register_operand" "=r,r")
429         (sign_extend:DI
430              (plus:SI (match_operand:SI 1 "register_operand" " r,r")
431                       (match_operand:SI 2 "arith_operand"    " r,I"))))]
432   "TARGET_64BIT"
433   "addw\t%0,%1,%2"
434   [(set_attr "type" "arith")
435    (set_attr "mode" "SI")])
437 (define_insn "*addsi3_extended2"
438   [(set (match_operand:DI                       0 "register_operand" "=r,r")
439         (sign_extend:DI
440           (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" " r,r")
441                               (match_operand:DI 2 "arith_operand"    " r,I"))
442                      0)))]
443   "TARGET_64BIT"
444   "addw\t%0,%1,%2"
445   [(set_attr "type" "arith")
446    (set_attr "mode" "SI")])
449 ;;  ....................
451 ;;      SUBTRACTION
453 ;;  ....................
456 (define_insn "sub<mode>3"
457   [(set (match_operand:ANYF             0 "register_operand" "=f")
458         (minus:ANYF (match_operand:ANYF 1 "register_operand" " f")
459                     (match_operand:ANYF 2 "register_operand" " f")))]
460   "TARGET_HARD_FLOAT"
461   "fsub.<fmt>\t%0,%1,%2"
462   [(set_attr "type" "fadd")
463    (set_attr "mode" "<UNITMODE>")])
465 (define_insn "subdi3"
466   [(set (match_operand:DI 0            "register_operand" "= r")
467         (minus:DI (match_operand:DI 1  "reg_or_0_operand" " rJ")
468                    (match_operand:DI 2 "register_operand" "  r")))]
469   "TARGET_64BIT"
470   "sub\t%0,%z1,%2"
471   [(set_attr "type" "arith")
472    (set_attr "mode" "DI")])
474 (define_insn "subsi3"
475   [(set (match_operand:SI           0 "register_operand" "= r")
476         (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
477                   (match_operand:SI 2 "register_operand" "  r")))]
478   ""
479   { return TARGET_64BIT ? "subw\t%0,%z1,%2" : "sub\t%0,%z1,%2"; }
480   [(set_attr "type" "arith")
481    (set_attr "mode" "SI")])
483 (define_insn "*subsi3_extended"
484   [(set (match_operand:DI               0 "register_operand" "= r")
485         (sign_extend:DI
486             (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
487                       (match_operand:SI 2 "register_operand" "  r"))))]
488   "TARGET_64BIT"
489   "subw\t%0,%z1,%2"
490   [(set_attr "type" "arith")
491    (set_attr "mode" "SI")])
493 (define_insn "*subsi3_extended2"
494   [(set (match_operand:DI                        0 "register_operand" "=r")
495         (sign_extend:DI
496           (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" " r")
497                                (match_operand:DI 2 "register_operand" " r"))
498                      0)))]
499   "TARGET_64BIT"
500   "subw\t%0,%z1,%2"
501   [(set_attr "type" "arith")
502    (set_attr "mode" "SI")])
505 ;;  ....................
507 ;;      MULTIPLICATION
509 ;;  ....................
512 (define_insn "mul<mode>3"
513   [(set (match_operand:ANYF               0 "register_operand" "=f")
514         (mult:ANYF (match_operand:ANYF    1 "register_operand" " f")
515                       (match_operand:ANYF 2 "register_operand" " f")))]
516   "TARGET_HARD_FLOAT"
517   "fmul.<fmt>\t%0,%1,%2"
518   [(set_attr "type" "fmul")
519    (set_attr "mode" "<UNITMODE>")])
521 (define_insn "mulsi3"
522   [(set (match_operand:SI          0 "register_operand" "=r")
523         (mult:SI (match_operand:SI 1 "register_operand" " r")
524                  (match_operand:SI 2 "register_operand" " r")))]
525   "TARGET_MUL"
526   { return TARGET_64BIT ? "mulw\t%0,%1,%2" : "mul\t%0,%1,%2"; }
527   [(set_attr "type" "imul")
528    (set_attr "mode" "SI")])
530 (define_insn "muldi3"
531   [(set (match_operand:DI          0 "register_operand" "=r")
532         (mult:DI (match_operand:DI 1 "register_operand" " r")
533                  (match_operand:DI 2 "register_operand" " r")))]
534   "TARGET_MUL && TARGET_64BIT"
535   "mul\t%0,%1,%2"
536   [(set_attr "type" "imul")
537    (set_attr "mode" "DI")])
539 (define_insn "*mulsi3_extended"
540   [(set (match_operand:DI              0 "register_operand" "=r")
541         (sign_extend:DI
542             (mult:SI (match_operand:SI 1 "register_operand" " r")
543                      (match_operand:SI 2 "register_operand" " r"))))]
544   "TARGET_MUL && TARGET_64BIT"
545   "mulw\t%0,%1,%2"
546   [(set_attr "type" "imul")
547    (set_attr "mode" "SI")])
549 (define_insn "*mulsi3_extended2"
550   [(set (match_operand:DI                       0 "register_operand" "=r")
551         (sign_extend:DI
552           (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" " r")
553                               (match_operand:DI 2 "register_operand" " r"))
554                      0)))]
555   "TARGET_MUL && TARGET_64BIT"
556   "mulw\t%0,%1,%2"
557   [(set_attr "type" "imul")
558    (set_attr "mode" "SI")])
561 ;;  ........................
563 ;;      MULTIPLICATION HIGH-PART
565 ;;  ........................
569 (define_expand "<u>mulditi3"
570   [(set (match_operand:TI                         0 "register_operand")
571         (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
572                  (any_extend:TI (match_operand:DI 2 "register_operand"))))]
573   "TARGET_MUL && TARGET_64BIT"
575   rtx low = gen_reg_rtx (DImode);
576   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
578   rtx high = gen_reg_rtx (DImode);
579   emit_insn (gen_<u>muldi3_highpart (high, operands[1], operands[2]));
581   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
582   emit_move_insn (gen_highpart (DImode, operands[0]), high);
583   DONE;
586 (define_insn "<u>muldi3_highpart"
587   [(set (match_operand:DI                0 "register_operand" "=r")
588         (truncate:DI
589           (lshiftrt:TI
590             (mult:TI (any_extend:TI
591                        (match_operand:DI 1 "register_operand" " r"))
592                      (any_extend:TI
593                        (match_operand:DI 2 "register_operand" " r")))
594             (const_int 64))))]
595   "TARGET_MUL && TARGET_64BIT"
596   "mulh<u>\t%0,%1,%2"
597   [(set_attr "type" "imul")
598    (set_attr "mode" "DI")])
600 (define_expand "usmulditi3"
601   [(set (match_operand:TI                          0 "register_operand")
602         (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand"))
603                  (sign_extend:TI (match_operand:DI 2 "register_operand"))))]
604   "TARGET_MUL && TARGET_64BIT"
606   rtx low = gen_reg_rtx (DImode);
607   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
609   rtx high = gen_reg_rtx (DImode);
610   emit_insn (gen_usmuldi3_highpart (high, operands[1], operands[2]));
612   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
613   emit_move_insn (gen_highpart (DImode, operands[0]), high);
614   DONE;
617 (define_insn "usmuldi3_highpart"
618   [(set (match_operand:DI                0 "register_operand" "=r")
619         (truncate:DI
620           (lshiftrt:TI
621             (mult:TI (zero_extend:TI
622                        (match_operand:DI 1 "register_operand"  "r"))
623                      (sign_extend:TI
624                        (match_operand:DI 2 "register_operand" " r")))
625             (const_int 64))))]
626   "TARGET_MUL && TARGET_64BIT"
627   "mulhsu\t%0,%2,%1"
628   [(set_attr "type" "imul")
629    (set_attr "mode" "DI")])
631 (define_expand "<u>mulsidi3"
632   [(set (match_operand:DI            0 "register_operand" "=r")
633         (mult:DI (any_extend:DI
634                    (match_operand:SI 1 "register_operand" " r"))
635                  (any_extend:DI
636                    (match_operand:SI 2 "register_operand" " r"))))]
637   "TARGET_MUL && !TARGET_64BIT"
639   rtx temp = gen_reg_rtx (SImode);
640   emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
641   emit_insn (gen_<u>mulsi3_highpart (riscv_subword (operands[0], true),
642                                      operands[1], operands[2]));
643   emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
644   DONE;
647 (define_insn "<u>mulsi3_highpart"
648   [(set (match_operand:SI                0 "register_operand" "=r")
649         (truncate:SI
650           (lshiftrt:DI
651             (mult:DI (any_extend:DI
652                        (match_operand:SI 1 "register_operand" " r"))
653                      (any_extend:DI
654                        (match_operand:SI 2 "register_operand" " r")))
655             (const_int 32))))]
656   "TARGET_MUL && !TARGET_64BIT"
657   "mulh<u>\t%0,%1,%2"
658   [(set_attr "type" "imul")
659    (set_attr "mode" "SI")])
662 (define_expand "usmulsidi3"
663   [(set (match_operand:DI            0 "register_operand" "=r")
664         (mult:DI (zero_extend:DI
665                    (match_operand:SI 1 "register_operand" " r"))
666                  (sign_extend:DI
667                    (match_operand:SI 2 "register_operand" " r"))))]
668   "TARGET_MUL && !TARGET_64BIT"
670   rtx temp = gen_reg_rtx (SImode);
671   emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
672   emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true),
673                                      operands[1], operands[2]));
674   emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
675   DONE;
678 (define_insn "usmulsi3_highpart"
679   [(set (match_operand:SI                0 "register_operand" "=r")
680         (truncate:SI
681           (lshiftrt:DI
682             (mult:DI (zero_extend:DI
683                        (match_operand:SI 1 "register_operand" " r"))
684                      (sign_extend:DI
685                        (match_operand:SI 2 "register_operand" " r")))
686             (const_int 32))))]
687   "TARGET_MUL && !TARGET_64BIT"
688   "mulhsu\t%0,%2,%1"
689   [(set_attr "type" "imul")
690    (set_attr "mode" "SI")])
693 ;;  ....................
695 ;;      DIVISION and REMAINDER
697 ;;  ....................
700 (define_insn "<optab>si3"
701   [(set (match_operand:SI             0 "register_operand" "=r")
702         (any_div:SI (match_operand:SI 1 "register_operand" " r")
703                     (match_operand:SI 2 "register_operand" " r")))]
704   "TARGET_DIV"
705   { return TARGET_64BIT ? "<insn>w\t%0,%1,%2" : "<insn>\t%0,%1,%2"; }
706   [(set_attr "type" "idiv")
707    (set_attr "mode" "SI")])
709 (define_insn "<optab>di3"
710   [(set (match_operand:DI             0 "register_operand" "=r")
711         (any_div:DI (match_operand:DI 1 "register_operand" " r")
712                     (match_operand:DI 2 "register_operand" " r")))]
713   "TARGET_DIV && TARGET_64BIT"
714   "<insn>\t%0,%1,%2"
715   [(set_attr "type" "idiv")
716    (set_attr "mode" "DI")])
718 (define_insn "*<optab>si3_extended"
719   [(set (match_operand:DI                 0 "register_operand" "=r")
720         (sign_extend:DI
721             (any_div:SI (match_operand:SI 1 "register_operand" " r")
722                         (match_operand:SI 2 "register_operand" " r"))))]
723   "TARGET_DIV && TARGET_64BIT"
724   "<insn>w\t%0,%1,%2"
725   [(set_attr "type" "idiv")
726    (set_attr "mode" "DI")])
728 (define_insn "div<mode>3"
729   [(set (match_operand:ANYF           0 "register_operand" "=f")
730         (div:ANYF (match_operand:ANYF 1 "register_operand" " f")
731                   (match_operand:ANYF 2 "register_operand" " f")))]
732   "TARGET_HARD_FLOAT && TARGET_FDIV"
733   "fdiv.<fmt>\t%0,%1,%2"
734   [(set_attr "type" "fdiv")
735    (set_attr "mode" "<UNITMODE>")])
738 ;;  ....................
740 ;;      SQUARE ROOT
742 ;;  ....................
744 (define_insn "sqrt<mode>2"
745   [(set (match_operand:ANYF            0 "register_operand" "=f")
746         (sqrt:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
747   "TARGET_HARD_FLOAT && TARGET_FDIV"
749     return "fsqrt.<fmt>\t%0,%1";
751   [(set_attr "type" "fsqrt")
752    (set_attr "mode" "<UNITMODE>")])
754 ;; Floating point multiply accumulate instructions.
756 ;; a * b + c
757 (define_insn "fma<mode>4"
758   [(set (match_operand:ANYF           0 "register_operand" "=f")
759         (fma:ANYF (match_operand:ANYF 1 "register_operand" " f")
760                   (match_operand:ANYF 2 "register_operand" " f")
761                   (match_operand:ANYF 3 "register_operand" " f")))]
762   "TARGET_HARD_FLOAT"
763   "fmadd.<fmt>\t%0,%1,%2,%3"
764   [(set_attr "type" "fmadd")
765    (set_attr "mode" "<UNITMODE>")])
767 ;; a * b - c
768 (define_insn "fms<mode>4"
769   [(set (match_operand:ANYF                     0 "register_operand" "=f")
770         (fma:ANYF (match_operand:ANYF           1 "register_operand" " f")
771                   (match_operand:ANYF           2 "register_operand" " f")
772                   (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
773   "TARGET_HARD_FLOAT"
774   "fmsub.<fmt>\t%0,%1,%2,%3"
775   [(set_attr "type" "fmadd")
776    (set_attr "mode" "<UNITMODE>")])
778 ;; -a * b - c
779 (define_insn "fnms<mode>4"
780   [(set (match_operand:ANYF               0 "register_operand" "=f")
781         (fma:ANYF
782             (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
783             (match_operand:ANYF           2 "register_operand" " f")
784             (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
785   "TARGET_HARD_FLOAT"
786   "fnmadd.<fmt>\t%0,%1,%2,%3"
787   [(set_attr "type" "fmadd")
788    (set_attr "mode" "<UNITMODE>")])
790 ;; -a * b + c
791 (define_insn "fnma<mode>4"
792   [(set (match_operand:ANYF               0 "register_operand" "=f")
793         (fma:ANYF
794             (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
795             (match_operand:ANYF           2 "register_operand" " f")
796             (match_operand:ANYF           3 "register_operand" " f")))]
797   "TARGET_HARD_FLOAT"
798   "fnmsub.<fmt>\t%0,%1,%2,%3"
799   [(set_attr "type" "fmadd")
800    (set_attr "mode" "<UNITMODE>")])
802 ;; -(-a * b - c), modulo signed zeros
803 (define_insn "*fma<mode>4"
804   [(set (match_operand:ANYF                   0 "register_operand" "=f")
805         (neg:ANYF
806             (fma:ANYF
807                 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
808                 (match_operand:ANYF           2 "register_operand" " f")
809                 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
810   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
811   "fmadd.<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 "*fms<mode>4"
817   [(set (match_operand:ANYF                   0 "register_operand" "=f")
818         (neg:ANYF
819             (fma:ANYF
820                 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
821                 (match_operand:ANYF           2 "register_operand" " f")
822                 (match_operand:ANYF           3 "register_operand" " f"))))]
823   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
824   "fmsub.<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 "*fnms<mode>4"
830   [(set (match_operand:ANYF         0 "register_operand" "=f")
831         (neg:ANYF
832             (fma:ANYF
833                 (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   "fnmadd.<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 "*fnma<mode>4"
843   [(set (match_operand:ANYF                   0 "register_operand" "=f")
844         (neg:ANYF
845             (fma:ANYF
846                 (match_operand:ANYF           1 "register_operand" " f")
847                 (match_operand:ANYF           2 "register_operand" " f")
848                 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
849   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
850   "fnmsub.<fmt>\t%0,%1,%2,%3"
851   [(set_attr "type" "fmadd")
852    (set_attr "mode" "<UNITMODE>")])
855 ;;  ....................
857 ;;      SIGN INJECTION
859 ;;  ....................
861 (define_insn "abs<mode>2"
862   [(set (match_operand:ANYF           0 "register_operand" "=f")
863         (abs:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
864   "TARGET_HARD_FLOAT"
865   "fabs.<fmt>\t%0,%1"
866   [(set_attr "type" "fmove")
867    (set_attr "mode" "<UNITMODE>")])
869 (define_insn "copysign<mode>3"
870   [(set (match_operand:ANYF 0 "register_operand"               "=f")
871         (unspec:ANYF [(match_operand:ANYF 1 "register_operand" " f")
872                       (match_operand:ANYF 2 "register_operand" " f")]
873                      UNSPEC_COPYSIGN))]
874   "TARGET_HARD_FLOAT"
875   "fsgnj.<fmt>\t%0,%1,%2"
876   [(set_attr "type" "fmove")
877    (set_attr "mode" "<UNITMODE>")])
879 (define_insn "neg<mode>2"
880   [(set (match_operand:ANYF           0 "register_operand" "=f")
881         (neg:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
882   "TARGET_HARD_FLOAT"
883   "fneg.<fmt>\t%0,%1"
884   [(set_attr "type" "fmove")
885    (set_attr "mode" "<UNITMODE>")])
888 ;;  ....................
890 ;;      MIN/MAX
892 ;;  ....................
894 (define_insn "smin<mode>3"
895   [(set (match_operand:ANYF            0 "register_operand" "=f")
896         (smin:ANYF (match_operand:ANYF 1 "register_operand" " f")
897                    (match_operand:ANYF 2 "register_operand" " f")))]
898   "TARGET_HARD_FLOAT"
899   "fmin.<fmt>\t%0,%1,%2"
900   [(set_attr "type" "fmove")
901    (set_attr "mode" "<UNITMODE>")])
903 (define_insn "smax<mode>3"
904   [(set (match_operand:ANYF            0 "register_operand" "=f")
905         (smax:ANYF (match_operand:ANYF 1 "register_operand" " f")
906                    (match_operand:ANYF 2 "register_operand" " f")))]
907   "TARGET_HARD_FLOAT"
908   "fmax.<fmt>\t%0,%1,%2"
909   [(set_attr "type" "fmove")
910    (set_attr "mode" "<UNITMODE>")])
913 ;;  ....................
915 ;;      LOGICAL
917 ;;  ....................
920 ;; For RV64, we don't expose the SImode operations to the rtl expanders,
921 ;; but SImode versions exist for combine.
923 (define_insn "<optab><mode>3"
924   [(set (match_operand:X                0 "register_operand" "=r,r")
925         (any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
926                        (match_operand:X 2 "arith_operand"    " r,I")))]
927   ""
928   "<insn>\t%0,%1,%2"
929   [(set_attr "type" "logical")
930    (set_attr "mode" "<MODE>")])
932 (define_insn "*<optab>si3_internal"
933   [(set (match_operand:SI                 0 "register_operand" "=r,r")
934         (any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r")
935                         (match_operand:SI 2 "arith_operand"    " r,I")))]
936   "TARGET_64BIT"
937   "<insn>\t%0,%1,%2"
938   [(set_attr "type" "logical")
939    (set_attr "mode" "SI")])
941 (define_insn "one_cmpl<mode>2"
942   [(set (match_operand:X        0 "register_operand" "=r")
943         (not:X (match_operand:X 1 "register_operand" " r")))]
944   ""
945   "not\t%0,%1"
946   [(set_attr "type" "logical")
947    (set_attr "mode" "<MODE>")])
949 (define_insn "*one_cmplsi2_internal"
950   [(set (match_operand:SI         0 "register_operand" "=r")
951         (not:SI (match_operand:SI 1 "register_operand" " r")))]
952   "TARGET_64BIT"
953   "not\t%0,%1"
954   [(set_attr "type" "logical")
955    (set_attr "mode" "SI")])
958 ;;  ....................
960 ;;      TRUNCATION
962 ;;  ....................
964 (define_insn "truncdfsf2"
965   [(set (match_operand:SF     0 "register_operand" "=f")
966         (float_truncate:SF
967             (match_operand:DF 1 "register_operand" " f")))]
968   "TARGET_DOUBLE_FLOAT"
969   "fcvt.s.d\t%0,%1"
970   [(set_attr "type" "fcvt")
971    (set_attr "mode" "SF")])
974 ;;  ....................
976 ;;      ZERO EXTENSION
978 ;;  ....................
980 ;; Extension insns.
982 (define_insn_and_split "zero_extendsidi2"
983   [(set (match_operand:DI     0 "register_operand"     "=r,r")
984         (zero_extend:DI
985             (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
986   "TARGET_64BIT"
987   "@
988    #
989    lwu\t%0,%1"
990   "&& reload_completed && REG_P (operands[1])"
991   [(set (match_dup 0)
992         (ashift:DI (match_dup 1) (const_int 32)))
993    (set (match_dup 0)
994         (lshiftrt:DI (match_dup 0) (const_int 32)))]
995   { operands[1] = gen_lowpart (DImode, operands[1]); }
996   [(set_attr "move_type" "shift_shift,load")
997    (set_attr "mode" "DI")])
999 (define_insn_and_split "zero_extendhi<GPR:mode>2"
1000   [(set (match_operand:GPR    0 "register_operand"     "=r,r")
1001         (zero_extend:GPR
1002             (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
1003   ""
1004   "@
1005    #
1006    lhu\t%0,%1"
1007   "&& reload_completed && REG_P (operands[1])"
1008   [(set (match_dup 0)
1009         (ashift:GPR (match_dup 1) (match_dup 2)))
1010    (set (match_dup 0)
1011         (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
1012   {
1013     operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
1014     operands[2] = GEN_INT(GET_MODE_BITSIZE(<GPR:MODE>mode) - 16);
1015   }
1016   [(set_attr "move_type" "shift_shift,load")
1017    (set_attr "mode" "<GPR:MODE>")])
1019 (define_insn "zero_extendqi<SUPERQI:mode>2"
1020   [(set (match_operand:SUPERQI 0 "register_operand"    "=r,r")
1021         (zero_extend:SUPERQI
1022             (match_operand:QI 1 "nonimmediate_operand" " r,m")))]
1023   ""
1024   "@
1025    and\t%0,%1,0xff
1026    lbu\t%0,%1"
1027   [(set_attr "move_type" "andi,load")
1028    (set_attr "mode" "<SUPERQI:MODE>")])
1031 ;;  ....................
1033 ;;      SIGN EXTENSION
1035 ;;  ....................
1037 (define_insn "extendsidi2"
1038   [(set (match_operand:DI     0 "register_operand"     "=r,r")
1039         (sign_extend:DI
1040             (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
1041   "TARGET_64BIT"
1042   "@
1043    sext.w\t%0,%1
1044    lw\t%0,%1"
1045   [(set_attr "move_type" "move,load")
1046    (set_attr "mode" "DI")])
1048 (define_insn_and_split "extend<SHORT:mode><SUPERQI:mode>2"
1049   [(set (match_operand:SUPERQI   0 "register_operand"     "=r,r")
1050         (sign_extend:SUPERQI
1051             (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
1052   ""
1053   "@
1054    #
1055    l<SHORT:size>\t%0,%1"
1056   "&& reload_completed && REG_P (operands[1])"
1057   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1058    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
1060   operands[0] = gen_lowpart (SImode, operands[0]);
1061   operands[1] = gen_lowpart (SImode, operands[1]);
1062   operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
1063                          - GET_MODE_BITSIZE (<SHORT:MODE>mode));
1065   [(set_attr "move_type" "shift_shift,load")
1066    (set_attr "mode" "SI")])
1068 (define_insn "extendsfdf2"
1069   [(set (match_operand:DF     0 "register_operand" "=f")
1070         (float_extend:DF
1071             (match_operand:SF 1 "register_operand" " f")))]
1072   "TARGET_DOUBLE_FLOAT"
1073   "fcvt.d.s\t%0,%1"
1074   [(set_attr "type" "fcvt")
1075    (set_attr "mode" "DF")])
1078 ;;  ....................
1080 ;;      CONVERSIONS
1082 ;;  ....................
1084 (define_insn "fix_trunc<ANYF:mode><GPR:mode>2"
1085   [(set (match_operand:GPR      0 "register_operand" "=r")
1086         (fix:GPR
1087             (match_operand:ANYF 1 "register_operand" " f")))]
1088   "TARGET_HARD_FLOAT"
1089   "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,rtz"
1090   [(set_attr "type" "fcvt")
1091    (set_attr "mode" "<ANYF:MODE>")])
1093 (define_insn "fixuns_trunc<ANYF:mode><GPR:mode>2"
1094   [(set (match_operand:GPR      0 "register_operand" "=r")
1095         (unsigned_fix:GPR
1096             (match_operand:ANYF 1 "register_operand" " f")))]
1097   "TARGET_HARD_FLOAT"
1098   "fcvt.<GPR:ifmt>u.<ANYF:fmt> %0,%1,rtz"
1099   [(set_attr "type" "fcvt")
1100    (set_attr "mode" "<ANYF:MODE>")])
1102 (define_insn "float<GPR:mode><ANYF:mode>2"
1103   [(set (match_operand:ANYF    0 "register_operand" "= f")
1104         (float:ANYF
1105             (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1106   "TARGET_HARD_FLOAT"
1107   "fcvt.<ANYF:fmt>.<GPR:ifmt>\t%0,%z1"
1108   [(set_attr "type" "fcvt")
1109    (set_attr "mode" "<ANYF:MODE>")])
1111 (define_insn "floatuns<GPR:mode><ANYF:mode>2"
1112   [(set (match_operand:ANYF    0 "register_operand" "= f")
1113         (unsigned_float:ANYF
1114             (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1115   "TARGET_HARD_FLOAT"
1116   "fcvt.<ANYF:fmt>.<GPR:ifmt>u\t%0,%z1"
1117   [(set_attr "type" "fcvt")
1118    (set_attr "mode" "<ANYF:MODE>")])
1120 (define_insn "l<rint_pattern><ANYF:mode><GPR:mode>2"
1121   [(set (match_operand:GPR       0 "register_operand" "=r")
1122         (unspec:GPR
1123             [(match_operand:ANYF 1 "register_operand" " f")]
1124             RINT))]
1125   "TARGET_HARD_FLOAT"
1126   "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,<rint_rm>"
1127   [(set_attr "type" "fcvt")
1128    (set_attr "mode" "<ANYF:MODE>")])
1131 ;;  ....................
1133 ;;      DATA MOVEMENT
1135 ;;  ....................
1137 ;; Lower-level instructions for loading an address from the GOT.
1138 ;; We could use MEMs, but an unspec gives more optimization
1139 ;; opportunities.
1141 (define_insn "got_load<mode>"
1142    [(set (match_operand:P      0 "register_operand" "=r")
1143          (unspec:P
1144              [(match_operand:P 1 "symbolic_operand" "")]
1145              UNSPEC_LOAD_GOT))]
1146   ""
1147   "la\t%0,%1"
1148    [(set_attr "got" "load")
1149     (set_attr "mode" "<MODE>")])
1151 (define_insn "tls_add_tp_le<mode>"
1152   [(set (match_operand:P      0 "register_operand" "=r")
1153         (unspec:P
1154             [(match_operand:P 1 "register_operand" "r")
1155              (match_operand:P 2 "register_operand" "r")
1156              (match_operand:P 3 "symbolic_operand" "")]
1157             UNSPEC_TLS_LE))]
1158   ""
1159   "add\t%0,%1,%2,%%tprel_add(%3)"
1160   [(set_attr "type" "arith")
1161    (set_attr "mode" "<MODE>")])
1163 (define_insn "got_load_tls_gd<mode>"
1164   [(set (match_operand:P      0 "register_operand" "=r")
1165         (unspec:P
1166             [(match_operand:P 1 "symbolic_operand" "")]
1167             UNSPEC_TLS_GD))]
1168   ""
1169   "la.tls.gd\t%0,%1"
1170   [(set_attr "got" "load")
1171    (set_attr "mode" "<MODE>")])
1173 (define_insn "got_load_tls_ie<mode>"
1174   [(set (match_operand:P      0 "register_operand" "=r")
1175         (unspec:P
1176             [(match_operand:P 1 "symbolic_operand" "")]
1177             UNSPEC_TLS_IE))]
1178   ""
1179   "la.tls.ie\t%0,%1"
1180   [(set_attr "got" "load")
1181    (set_attr "mode" "<MODE>")])
1183 (define_insn "auipc<mode>"
1184   [(set (match_operand:P           0 "register_operand" "=r")
1185         (unspec:P
1186             [(match_operand:P      1 "symbolic_operand" "")
1187                   (match_operand:P 2 "const_int_operand")
1188                   (pc)]
1189             UNSPEC_AUIPC))]
1190   ""
1191   ".LA%2: auipc\t%0,%h1"
1192   [(set_attr "type" "arith")
1193    (set_attr "cannot_copy" "yes")])
1195 ;; Instructions for adding the low 12 bits of an address to a register.
1196 ;; Operand 2 is the address: riscv_print_operand works out which relocation
1197 ;; should be applied.
1199 (define_insn "*low<mode>"
1200   [(set (match_operand:P           0 "register_operand" "=r")
1201         (lo_sum:P (match_operand:P 1 "register_operand" " r")
1202                   (match_operand:P 2 "symbolic_operand" "")))]
1203   ""
1204   "addi\t%0,%1,%R2"
1205   [(set_attr "type" "arith")
1206    (set_attr "mode" "<MODE>")])
1208 ;; Allow combine to split complex const_int load sequences, using operand 2
1209 ;; to store the intermediate results.  See move_operand for details.
1210 (define_split
1211   [(set (match_operand:GPR 0 "register_operand")
1212         (match_operand:GPR 1 "splittable_const_int_operand"))
1213    (clobber (match_operand:GPR 2 "register_operand"))]
1214   ""
1215   [(const_int 0)]
1217   riscv_move_integer (operands[2], operands[0], INTVAL (operands[1]));
1218   DONE;
1221 ;; Likewise, for symbolic operands.
1222 (define_split
1223   [(set (match_operand:P 0 "register_operand")
1224         (match_operand:P 1))
1225    (clobber (match_operand:P 2 "register_operand"))]
1226   "riscv_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
1227   [(set (match_dup 0) (match_dup 3))]
1229   riscv_split_symbol (operands[2], operands[1],
1230                      MAX_MACHINE_MODE, &operands[3]);
1233 ;; 64-bit integer moves
1235 (define_expand "movdi"
1236   [(set (match_operand:DI 0 "")
1237         (match_operand:DI 1 ""))]
1238   ""
1240   if (riscv_legitimize_move (DImode, operands[0], operands[1]))
1241     DONE;
1244 (define_insn "*movdi_32bit"
1245   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,  *f,*f,*r,*f,*m")
1246         (match_operand:DI 1 "move_operand"         " r,i,m,r,*J*r,*m,*f,*f,*f"))]
1247   "!TARGET_64BIT
1248    && (register_operand (operands[0], DImode)
1249        || reg_or_0_operand (operands[1], DImode))"
1250   { return riscv_output_move (operands[0], operands[1]); }
1251   [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1252    (set_attr "mode" "DI")])
1254 (define_insn "*movdi_64bit"
1255   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*f,*r,*f,*m")
1256         (match_operand:DI 1 "move_operand"         " r,T,m,rJ,*r*J,*m,*f,*f,*f"))]
1257   "TARGET_64BIT
1258    && (register_operand (operands[0], DImode)
1259        || reg_or_0_operand (operands[1], DImode))"
1260   { return riscv_output_move (operands[0], operands[1]); }
1261   [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1262    (set_attr "mode" "DI")])
1264 ;; 32-bit Integer moves
1266 (define_expand "mov<mode>"
1267   [(set (match_operand:MOVE32 0 "")
1268         (match_operand:MOVE32 1 ""))]
1269   ""
1271   if (riscv_legitimize_move (<MODE>mode, operands[0], operands[1]))
1272     DONE;
1275 (define_insn "*movsi_internal"
1276   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*f,*r,*m")
1277         (match_operand:SI 1 "move_operand"         " r,T,m,rJ,*r*J,*m,*f,*f"))]
1278   "(register_operand (operands[0], SImode)
1279     || reg_or_0_operand (operands[1], SImode))"
1280   { return riscv_output_move (operands[0], operands[1]); }
1281   [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore")
1282    (set_attr "mode" "SI")])
1284 ;; 16-bit Integer moves
1286 ;; Unlike most other insns, the move insns can't be split with
1287 ;; different predicates, because register spilling and other parts of
1288 ;; the compiler, have memoized the insn number already.
1289 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
1291 (define_expand "movhi"
1292   [(set (match_operand:HI 0 "")
1293         (match_operand:HI 1 ""))]
1294   ""
1296   if (riscv_legitimize_move (HImode, operands[0], operands[1]))
1297     DONE;
1300 (define_insn "*movhi_internal"
1301   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*r")
1302         (match_operand:HI 1 "move_operand"         " r,T,m,rJ,*r*J,*f"))]
1303   "(register_operand (operands[0], HImode)
1304     || reg_or_0_operand (operands[1], HImode))"
1305   { return riscv_output_move (operands[0], operands[1]); }
1306   [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1307    (set_attr "mode" "HI")])
1309 ;; HImode constant generation; see riscv_move_integer for details.
1310 ;; si+si->hi without truncation is legal because of TRULY_NOOP_TRUNCATION.
1312 (define_insn "*add<mode>hi3"
1313   [(set (match_operand:HI            0 "register_operand" "=r,r")
1314         (plus:HI (match_operand:HISI 1 "register_operand" " r,r")
1315                  (match_operand:HISI 2 "arith_operand"    " r,I")))]
1316   ""
1317   { return TARGET_64BIT ? "addw\t%0,%1,%2" : "add\t%0,%1,%2"; }
1318   [(set_attr "type" "arith")
1319    (set_attr "mode" "HI")])
1321 (define_insn "*xor<mode>hi3"
1322   [(set (match_operand:HI 0 "register_operand"           "=r,r")
1323         (xor:HI (match_operand:HISI 1 "register_operand" " r,r")
1324                 (match_operand:HISI 2 "arith_operand"    " r,I")))]
1325   ""
1326   "xor\t%0,%1,%2"
1327   [(set_attr "type" "logical")
1328    (set_attr "mode" "HI")])
1330 ;; 8-bit Integer moves
1332 (define_expand "movqi"
1333   [(set (match_operand:QI 0 "")
1334         (match_operand:QI 1 ""))]
1335   ""
1337   if (riscv_legitimize_move (QImode, operands[0], operands[1]))
1338     DONE;
1341 (define_insn "*movqi_internal"
1342   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*r")
1343         (match_operand:QI 1 "move_operand"         " r,I,m,rJ,*r*J,*f"))]
1344   "(register_operand (operands[0], QImode)
1345     || reg_or_0_operand (operands[1], QImode))"
1346   { return riscv_output_move (operands[0], operands[1]); }
1347   [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1348    (set_attr "mode" "QI")])
1350 ;; 32-bit floating point moves
1352 (define_expand "movsf"
1353   [(set (match_operand:SF 0 "")
1354         (match_operand:SF 1 ""))]
1355   ""
1357   if (riscv_legitimize_move (SFmode, operands[0], operands[1]))
1358     DONE;
1361 (define_insn "*movsf_hardfloat"
1362   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,  *r,*r,*m")
1363         (match_operand:SF 1 "move_operand"         " f,G,m,f,G,*r,*f,*G*r,*m,*r"))]
1364   "TARGET_HARD_FLOAT
1365    && (register_operand (operands[0], SFmode)
1366        || reg_or_0_operand (operands[1], SFmode))"
1367   { return riscv_output_move (operands[0], operands[1]); }
1368   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1369    (set_attr "mode" "SF")])
1371 (define_insn "*movsf_softfloat"
1372   [(set (match_operand:SF 0 "nonimmediate_operand" "= r,r,m")
1373         (match_operand:SF 1 "move_operand"         " Gr,m,r"))]
1374   "!TARGET_HARD_FLOAT
1375    && (register_operand (operands[0], SFmode)
1376        || reg_or_0_operand (operands[1], SFmode))"
1377   { return riscv_output_move (operands[0], operands[1]); }
1378   [(set_attr "move_type" "move,load,store")
1379    (set_attr "mode" "SF")])
1381 ;; 64-bit floating point moves
1383 (define_expand "movdf"
1384   [(set (match_operand:DF 0 "")
1385         (match_operand:DF 1 ""))]
1386   ""
1388   if (riscv_legitimize_move (DFmode, operands[0], operands[1]))
1389     DONE;
1392 ;; In RV32, we lack fmv.x.d and fmv.d.x.  Go through memory instead.
1393 ;; (However, we can still use fcvt.d.w to zero a floating-point register.)
1394 (define_insn "*movdf_hardfloat_rv32"
1395   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,  *r,*r,*m")
1396         (match_operand:DF 1 "move_operand"         " f,G,m,f,G,*r*G,*m,*r"))]
1397   "!TARGET_64BIT && TARGET_DOUBLE_FLOAT
1398    && (register_operand (operands[0], DFmode)
1399        || reg_or_0_operand (operands[1], DFmode))"
1400   { return riscv_output_move (operands[0], operands[1]); }
1401   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,move,load,store")
1402    (set_attr "mode" "DF")])
1404 (define_insn "*movdf_hardfloat_rv64"
1405   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,  *r,*r,*m")
1406         (match_operand:DF 1 "move_operand"         " f,G,m,f,G,*r,*f,*r*G,*m,*r"))]
1407   "TARGET_64BIT && TARGET_DOUBLE_FLOAT
1408    && (register_operand (operands[0], DFmode)
1409        || reg_or_0_operand (operands[1], DFmode))"
1410   { return riscv_output_move (operands[0], operands[1]); }
1411   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1412    (set_attr "mode" "DF")])
1414 (define_insn "*movdf_softfloat"
1415   [(set (match_operand:DF 0 "nonimmediate_operand" "= r,r, m")
1416         (match_operand:DF 1 "move_operand"         " rG,m,rG"))]
1417   "!TARGET_DOUBLE_FLOAT
1418    && (register_operand (operands[0], DFmode)
1419        || reg_or_0_operand (operands[1], DFmode))"
1420   { return riscv_output_move (operands[0], operands[1]); }
1421   [(set_attr "move_type" "move,load,store")
1422    (set_attr "mode" "DF")])
1424 (define_split
1425   [(set (match_operand:MOVE64 0 "nonimmediate_operand")
1426         (match_operand:MOVE64 1 "move_operand"))]
1427   "reload_completed
1428    && riscv_split_64bit_move_p (operands[0], operands[1])"
1429   [(const_int 0)]
1431   riscv_split_doubleword_move (operands[0], operands[1]);
1432   DONE;
1435 ;; Expand in-line code to clear the instruction cache between operand[0] and
1436 ;; operand[1].
1437 (define_expand "clear_cache"
1438   [(match_operand 0 "pmode_register_operand")
1439    (match_operand 1 "pmode_register_operand")]
1440   ""
1442   emit_insn (gen_fence_i ());
1443   DONE;
1446 (define_insn "fence"
1447   [(unspec_volatile [(const_int 0)] UNSPECV_FENCE)]
1448   ""
1449   "%|fence%-")
1451 (define_insn "fence_i"
1452   [(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)]
1453   ""
1454   "fence.i")
1457 ;;  ....................
1459 ;;      SHIFTS
1461 ;;  ....................
1463 (define_insn "<optab>si3"
1464   [(set (match_operand:SI     0 "register_operand" "= r")
1465         (any_shift:SI
1466             (match_operand:SI 1 "register_operand" "  r")
1467             (match_operand:SI 2 "arith_operand"    " rI")))]
1468   ""
1470   if (GET_CODE (operands[2]) == CONST_INT)
1471     operands[2] = GEN_INT (INTVAL (operands[2])
1472                            & (GET_MODE_BITSIZE (SImode) - 1));
1474   return TARGET_64BIT ? "<insn>w\t%0,%1,%2" : "<insn>\t%0,%1,%2";
1476   [(set_attr "type" "shift")
1477    (set_attr "mode" "SI")])
1479 (define_insn "<optab>di3"
1480   [(set (match_operand:DI 0 "register_operand"     "= r")
1481         (any_shift:DI
1482             (match_operand:DI 1 "register_operand" "  r")
1483             (match_operand:DI 2 "arith_operand"    " rI")))]
1484   "TARGET_64BIT"
1486   if (GET_CODE (operands[2]) == CONST_INT)
1487     operands[2] = GEN_INT (INTVAL (operands[2])
1488                            & (GET_MODE_BITSIZE (DImode) - 1));
1490   return "<insn>\t%0,%1,%2";
1492   [(set_attr "type" "shift")
1493    (set_attr "mode" "DI")])
1495 (define_insn "*<optab>si3_extend"
1496   [(set (match_operand:DI                   0 "register_operand" "= r")
1497         (sign_extend:DI
1498             (any_shift:SI (match_operand:SI 1 "register_operand" "  r")
1499                           (match_operand:SI 2 "arith_operand"    " rI"))))]
1500   "TARGET_64BIT"
1502   if (GET_CODE (operands[2]) == CONST_INT)
1503     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1505   return "<insn>w\t%0,%1,%2";
1507   [(set_attr "type" "shift")
1508    (set_attr "mode" "SI")])
1511 ;;  ....................
1513 ;;      CONDITIONAL BRANCHES
1515 ;;  ....................
1517 ;; Conditional branches
1519 (define_insn "*branch_order<mode>"
1520   [(set (pc)
1521         (if_then_else
1522          (match_operator 1 "order_operator"
1523                          [(match_operand:X 2 "register_operand" "r")
1524                           (match_operand:X 3 "register_operand" "r")])
1525          (label_ref (match_operand 0 "" ""))
1526          (pc)))]
1527   ""
1528   "b%C1\t%2,%3,%0"
1529   [(set_attr "type" "branch")
1530    (set_attr "mode" "none")])
1532 (define_insn "*branch_zero<mode>"
1533   [(set (pc)
1534         (if_then_else
1535          (match_operator 1 "signed_order_operator"
1536                          [(match_operand:X 2 "register_operand" "r")
1537                           (const_int 0)])
1538          (label_ref (match_operand 0 "" ""))
1539          (pc)))]
1540   ""
1541   "b%C1z\t%2,%0"
1542   [(set_attr "type" "branch")
1543    (set_attr "mode" "none")])
1545 ;; Used to implement built-in functions.
1546 (define_expand "condjump"
1547   [(set (pc)
1548         (if_then_else (match_operand 0)
1549                       (label_ref (match_operand 1))
1550                       (pc)))])
1552 (define_expand "cbranch<mode>4"
1553   [(set (pc)
1554         (if_then_else (match_operator 0 "comparison_operator"
1555                       [(match_operand:BR 1 "register_operand")
1556                        (match_operand:BR 2 "nonmemory_operand")])
1557                       (label_ref (match_operand 3 ""))
1558                       (pc)))]
1559   ""
1561   riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1562                                    operands[1], operands[2]);
1563   DONE;
1566 (define_expand "cbranch<mode>4"
1567   [(set (pc)
1568         (if_then_else (match_operator 0 "fp_branch_comparison"
1569                        [(match_operand:ANYF 1 "register_operand")
1570                         (match_operand:ANYF 2 "register_operand")])
1571                       (label_ref (match_operand 3 ""))
1572                       (pc)))]
1573   "TARGET_HARD_FLOAT"
1575   riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1576                                    operands[1], operands[2]);
1577   DONE;
1580 (define_insn_and_split "*branch_on_bit<X:mode>"
1581   [(set (pc)
1582         (if_then_else
1583             (match_operator 0 "equality_operator"
1584                 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1585                                  (const_int 1)
1586                                  (match_operand 3 "branch_on_bit_operand"))
1587                                  (const_int 0)])
1588             (label_ref (match_operand 1))
1589             (pc)))
1590    (clobber (match_scratch:X 4 "=&r"))]
1591   ""
1592   "#"
1593   "reload_completed"
1594   [(set (match_dup 4)
1595         (ashift:X (match_dup 2) (match_dup 3)))
1596    (set (pc)
1597         (if_then_else
1598             (match_op_dup 0 [(match_dup 4) (const_int 0)])
1599             (label_ref (match_operand 1))
1600             (pc)))]
1602   int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]);
1603   operands[3] = GEN_INT (shift);
1605   if (GET_CODE (operands[0]) == EQ)
1606     operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx);
1607   else
1608     operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx);
1611 (define_insn_and_split "*branch_on_bit_range<X:mode>"
1612   [(set (pc)
1613         (if_then_else
1614             (match_operator 0 "equality_operator"
1615                 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1616                                  (match_operand 3 "branch_on_bit_operand")
1617                                  (const_int 0))
1618                                  (const_int 0)])
1619             (label_ref (match_operand 1))
1620             (pc)))
1621    (clobber (match_scratch:X 4 "=&r"))]
1622   ""
1623   "#"
1624   "reload_completed"
1625   [(set (match_dup 4)
1626         (ashift:X (match_dup 2) (match_dup 3)))
1627    (set (pc)
1628         (if_then_else
1629             (match_op_dup 0 [(match_dup 4) (const_int 0)])
1630             (label_ref (match_operand 1))
1631             (pc)))]
1633   operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]));
1637 ;;  ....................
1639 ;;      SETTING A REGISTER FROM A COMPARISON
1641 ;;  ....................
1643 ;; Destination is always set in SI mode.
1645 (define_expand "cstore<mode>4"
1646   [(set (match_operand:SI 0 "register_operand")
1647         (match_operator:SI 1 "order_operator"
1648             [(match_operand:GPR 2 "register_operand")
1649              (match_operand:GPR 3 "nonmemory_operand")]))]
1650   ""
1652   riscv_expand_int_scc (operands[0], GET_CODE (operands[1]), operands[2],
1653                         operands[3]);
1654   DONE;
1657 (define_expand "cstore<mode>4"
1658   [(set (match_operand:SI 0 "register_operand")
1659         (match_operator:SI 1 "fp_scc_comparison"
1660              [(match_operand:ANYF 2 "register_operand")
1661               (match_operand:ANYF 3 "register_operand")]))]
1662   "TARGET_HARD_FLOAT"
1664   riscv_expand_float_scc (operands[0], GET_CODE (operands[1]), operands[2],
1665                           operands[3]);
1666   DONE;
1669 (define_insn "*cstore<ANYF:mode><X:mode>4"
1670    [(set (match_operand:X         0 "register_operand" "=r")
1671          (match_operator:X 1 "fp_native_comparison"
1672              [(match_operand:ANYF 2 "register_operand" " f")
1673               (match_operand:ANYF 3 "register_operand" " f")]))]
1674   "TARGET_HARD_FLOAT"
1675   "f%C1.<fmt>\t%0,%2,%3"
1676   [(set_attr "type" "fcmp")
1677    (set_attr "mode" "<UNITMODE>")])
1679 (define_insn "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4"
1680    [(set (match_operand:X         0 "register_operand" "=r")
1681          (unspec:X
1682              [(match_operand:ANYF 1 "register_operand" " f")
1683               (match_operand:ANYF 2 "register_operand" " f")]
1684              QUIET_COMPARISON))
1685     (clobber (match_scratch:X 3 "=&r"))]
1686   "TARGET_HARD_FLOAT"
1687   "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3"
1688   [(set_attr "type" "fcmp")
1689    (set_attr "mode" "<UNITMODE>")
1690    (set (attr "length") (const_int 12))])
1692 (define_insn "*seq_zero_<X:mode><GPR:mode>"
1693   [(set (match_operand:GPR       0 "register_operand" "=r")
1694         (eq:GPR (match_operand:X 1 "register_operand" " r")
1695                 (const_int 0)))]
1696   ""
1697   "seqz\t%0,%1"
1698   [(set_attr "type" "slt")
1699    (set_attr "mode" "<X:MODE>")])
1701 (define_insn "*sne_zero_<X:mode><GPR:mode>"
1702   [(set (match_operand:GPR       0 "register_operand" "=r")
1703         (ne:GPR (match_operand:X 1 "register_operand" " r")
1704                 (const_int 0)))]
1705   ""
1706   "snez\t%0,%1"
1707   [(set_attr "type" "slt")
1708    (set_attr "mode" "<X:MODE>")])
1710 (define_insn "*sgt<u>_<X:mode><GPR:mode>"
1711   [(set (match_operand:GPR           0 "register_operand" "= r")
1712         (any_gt:GPR (match_operand:X 1 "register_operand" "  r")
1713                     (match_operand:X 2 "reg_or_0_operand" " rJ")))]
1714   ""
1715   "sgt<u>\t%0,%1,%z2"
1716   [(set_attr "type" "slt")
1717    (set_attr "mode" "<X:MODE>")])
1719 (define_insn "*sge<u>_<X:mode><GPR:mode>"
1720   [(set (match_operand:GPR           0 "register_operand" "=r")
1721         (any_ge:GPR (match_operand:X 1 "register_operand" " r")
1722                     (const_int 1)))]
1723   ""
1724   "slt<u>\t%0,zero,%1"
1725   [(set_attr "type" "slt")
1726    (set_attr "mode" "<MODE>")])
1728 (define_insn "*slt<u>_<X:mode><GPR:mode>"
1729   [(set (match_operand:GPR           0 "register_operand" "= r")
1730         (any_lt:GPR (match_operand:X 1 "register_operand" "  r")
1731                     (match_operand:X 2 "arith_operand"    " rI")))]
1732   ""
1733   "slt<u>\t%0,%1,%2"
1734   [(set_attr "type" "slt")
1735    (set_attr "mode" "<MODE>")])
1737 (define_insn "*sle<u>_<X:mode><GPR:mode>"
1738   [(set (match_operand:GPR           0 "register_operand" "=r")
1739         (any_le:GPR (match_operand:X 1 "register_operand" " r")
1740                     (match_operand:X 2 "sle_operand" "")))]
1741   ""
1743   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
1744   return "slt<u>\t%0,%1,%2";
1746   [(set_attr "type" "slt")
1747    (set_attr "mode" "<MODE>")])
1750 ;;  ....................
1752 ;;      UNCONDITIONAL BRANCHES
1754 ;;  ....................
1756 ;; Unconditional branches.
1758 (define_insn "jump"
1759   [(set (pc)
1760         (label_ref (match_operand 0 "" "")))]
1761   ""
1762   "j\t%l0"
1763   [(set_attr "type"     "jump")
1764    (set_attr "mode"     "none")])
1766 (define_expand "indirect_jump"
1767   [(set (pc) (match_operand 0 "register_operand"))]
1768   ""
1770   operands[0] = force_reg (Pmode, operands[0]);
1771   if (Pmode == SImode)
1772     emit_jump_insn (gen_indirect_jumpsi (operands[0]));
1773   else
1774     emit_jump_insn (gen_indirect_jumpdi (operands[0]));
1775   DONE;
1778 (define_insn "indirect_jump<mode>"
1779   [(set (pc) (match_operand:P 0 "register_operand" "l"))]
1780   ""
1781   "jr\t%0"
1782   [(set_attr "type" "jump")
1783    (set_attr "mode" "none")])
1785 (define_expand "tablejump"
1786   [(set (pc) (match_operand 0 "register_operand" ""))
1787               (use (label_ref (match_operand 1 "" "")))]
1788   ""
1790   if (CASE_VECTOR_PC_RELATIVE)
1791       operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1792                                          gen_rtx_LABEL_REF (Pmode, operands[1]),
1793                                          NULL_RTX, 0, OPTAB_DIRECT);
1795   if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode)
1796     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
1797   else
1798     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
1799   DONE;
1802 (define_insn "tablejump<mode>"
1803   [(set (pc) (match_operand:GPR 0 "register_operand" "l"))
1804    (use (label_ref (match_operand 1 "" "")))]
1805   ""
1806   "jr\t%0"
1807   [(set_attr "type" "jump")
1808    (set_attr "mode" "none")])
1811 ;;  ....................
1813 ;;      Function prologue/epilogue
1815 ;;  ....................
1818 (define_expand "prologue"
1819   [(const_int 1)]
1820   ""
1822   riscv_expand_prologue ();
1823   DONE;
1826 ;; Block any insns from being moved before this point, since the
1827 ;; profiling call to mcount can use various registers that aren't
1828 ;; saved or used to pass arguments.
1830 (define_insn "blockage"
1831   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
1832   ""
1833   ""
1834   [(set_attr "type" "ghost")
1835    (set_attr "mode" "none")])
1837 (define_expand "epilogue"
1838   [(const_int 2)]
1839   ""
1841   riscv_expand_epilogue (false);
1842   DONE;
1845 (define_expand "sibcall_epilogue"
1846   [(const_int 2)]
1847   ""
1849   riscv_expand_epilogue (true);
1850   DONE;
1853 ;; Trivial return.  Make it look like a normal return insn as that
1854 ;; allows jump optimizations to work better.
1856 (define_expand "return"
1857   [(simple_return)]
1858   "riscv_can_use_return_insn ()"
1859   "")
1861 (define_insn "simple_return"
1862   [(simple_return)]
1863   ""
1864   "ret"
1865   [(set_attr "type"     "jump")
1866    (set_attr "mode"     "none")])
1868 ;; Normal return.
1870 (define_insn "simple_return_internal"
1871   [(simple_return)
1872    (use (match_operand 0 "pmode_register_operand" ""))]
1873   ""
1874   "jr\t%0"
1875   [(set_attr "type"     "jump")
1876    (set_attr "mode"     "none")])
1878 ;; This is used in compiling the unwind routines.
1879 (define_expand "eh_return"
1880   [(use (match_operand 0 "general_operand"))]
1881   ""
1883   if (GET_MODE (operands[0]) != word_mode)
1884     operands[0] = convert_to_mode (word_mode, operands[0], 0);
1885   if (TARGET_64BIT)
1886     emit_insn (gen_eh_set_lr_di (operands[0]));
1887   else
1888     emit_insn (gen_eh_set_lr_si (operands[0]));
1889   DONE;
1892 ;; Clobber the return address on the stack.  We can't expand this
1893 ;; until we know where it will be put in the stack frame.
1895 (define_insn "eh_set_lr_si"
1896   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
1897    (clobber (match_scratch:SI 1 "=&r"))]
1898   "! TARGET_64BIT"
1899   "#")
1901 (define_insn "eh_set_lr_di"
1902   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
1903    (clobber (match_scratch:DI 1 "=&r"))]
1904   "TARGET_64BIT"
1905   "#")
1907 (define_split
1908   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
1909    (clobber (match_scratch 1))]
1910   "reload_completed"
1911   [(const_int 0)]
1913   riscv_set_return_address (operands[0], operands[1]);
1914   DONE;
1918 ;;  ....................
1920 ;;      FUNCTION CALLS
1922 ;;  ....................
1924 (define_expand "sibcall"
1925   [(parallel [(call (match_operand 0 "")
1926                     (match_operand 1 ""))
1927               (use (match_operand 2 ""))        ;; next_arg_reg
1928               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
1929   ""
1931   rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
1932   emit_call_insn (gen_sibcall_internal (target, operands[1]));
1933   DONE;
1936 (define_insn "sibcall_internal"
1937   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U"))
1938          (match_operand 1 "" ""))]
1939   "SIBLING_CALL_P (insn)"
1940   "@
1941    jr\t%0
1942    tail\t%0
1943    tail\t%0@plt"
1944   [(set_attr "type" "call")])
1946 (define_expand "sibcall_value"
1947   [(parallel [(set (match_operand 0 "")
1948                    (call (match_operand 1 "")
1949                          (match_operand 2 "")))
1950               (use (match_operand 3 ""))])]             ;; next_arg_reg
1951   ""
1953   rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
1954   emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2]));
1955   DONE;
1958 (define_insn "sibcall_value_internal"
1959   [(set (match_operand 0 "" "")
1960         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U"))
1961               (match_operand 2 "" "")))]
1962   "SIBLING_CALL_P (insn)"
1963   "@
1964    jr\t%1
1965    tail\t%1
1966    tail\t%1@plt"
1967   [(set_attr "type" "call")])
1969 (define_expand "call"
1970   [(parallel [(call (match_operand 0 "")
1971                     (match_operand 1 ""))
1972               (use (match_operand 2 ""))        ;; next_arg_reg
1973               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
1974   ""
1976   rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
1977   emit_call_insn (gen_call_internal (target, operands[1]));
1978   DONE;
1981 (define_insn "call_internal"
1982   [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U"))
1983          (match_operand 1 "" ""))
1984    (clobber (reg:SI RETURN_ADDR_REGNUM))]
1985   ""
1986   "@
1987    jalr\t%0
1988    call\t%0
1989    call\t%0@plt"
1990   [(set_attr "type" "call")])
1992 (define_expand "call_value"
1993   [(parallel [(set (match_operand 0 "")
1994                    (call (match_operand 1 "")
1995                          (match_operand 2 "")))
1996               (use (match_operand 3 ""))])]             ;; next_arg_reg
1997   ""
1999   rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2000   emit_call_insn (gen_call_value_internal (operands[0], target, operands[2]));
2001   DONE;
2004 (define_insn "call_value_internal"
2005   [(set (match_operand 0 "" "")
2006         (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U"))
2007               (match_operand 2 "" "")))
2008    (clobber (reg:SI RETURN_ADDR_REGNUM))]
2009   ""
2010   "@
2011    jalr\t%1
2012    call\t%1
2013    call\t%1@plt"
2014   [(set_attr "type" "call")])
2016 ;; Call subroutine returning any type.
2018 (define_expand "untyped_call"
2019   [(parallel [(call (match_operand 0 "")
2020                     (const_int 0))
2021               (match_operand 1 "")
2022               (match_operand 2 "")])]
2023   ""
2025   int i;
2027   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2029   for (i = 0; i < XVECLEN (operands[2], 0); i++)
2030     {
2031       rtx set = XVECEXP (operands[2], 0, i);
2032       riscv_emit_move (SET_DEST (set), SET_SRC (set));
2033     }
2035   emit_insn (gen_blockage ());
2036   DONE;
2039 (define_insn "nop"
2040   [(const_int 0)]
2041   ""
2042   "nop"
2043   [(set_attr "type"     "nop")
2044    (set_attr "mode"     "none")])
2046 (define_insn "trap"
2047   [(trap_if (const_int 1) (const_int 0))]
2048   ""
2049   "ebreak")
2051 (define_insn "gpr_save"
2052   [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_SAVE)
2053    (clobber (reg:SI T0_REGNUM))
2054    (clobber (reg:SI T1_REGNUM))]
2055   ""
2056   { return riscv_output_gpr_save (INTVAL (operands[0])); })
2058 (define_insn "gpr_restore"
2059   [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_RESTORE)]
2060   ""
2061   "tail\t__riscv_restore_%0")
2063 (define_insn "gpr_restore_return"
2064   [(return)
2065    (use (match_operand 0 "pmode_register_operand" ""))
2066    (const_int 0)]
2067   ""
2068   "")
2070 (define_insn "riscv_frflags"
2071   [(set (match_operand:SI 0 "register_operand" "=r")
2072         (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))]
2073   "TARGET_HARD_FLOAT"
2074   "frflags %0")
2076 (define_insn "riscv_fsflags"
2077   [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)]
2078   "TARGET_HARD_FLOAT"
2079   "fsflags %0")
2081 (define_insn "stack_tie<mode>"
2082   [(set (mem:BLK (scratch))
2083         (unspec:BLK [(match_operand:X 0 "register_operand" "r")
2084                      (match_operand:X 1 "register_operand" "r")]
2085                     UNSPEC_TIE))]
2086   ""
2087   ""
2088   [(set_attr "length" "0")]
2091 (include "sync.md")
2092 (include "peephole.md")
2093 (include "pic.md")
2094 (include "generic.md")