* gimplify.c (nonlocal_vlas): Delete.
[official-gcc.git] / gcc / config / riscv / riscv.md
bloba5940dcc4253edfdca937d786700cf2e86b99763
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)
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   ;; Interrupt handler instructions.
60   UNSPECV_MRET
61   UNSPECV_SRET
62   UNSPECV_URET
64   ;; Blockage and synchronization.
65   UNSPECV_BLOCKAGE
66   UNSPECV_FENCE
67   UNSPECV_FENCE_I
70 (define_constants
71   [(RETURN_ADDR_REGNUM          1)
72    (GP_REGNUM                   3)
73    (T0_REGNUM                   5)
74    (T1_REGNUM                   6)
75    (S0_REGNUM                   8)
76    (S1_REGNUM                   9)
77    (S2_REGNUM                   18)
79    (NORMAL_RETURN               0)
80    (SIBCALL_RETURN              1)
81    (EXCEPTION_RETURN            2)
84 (include "predicates.md")
85 (include "constraints.md")
87 ;; ....................
89 ;;      Attributes
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)))
120          (const_string "yes")
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)
154 ;; nop          no operation
155 ;; ghost        an instruction that produces no real code
156 (define_attr "type"
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" ""
192    (cond [
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)))
197           (const_int 4)
198           (const_int 8))
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")
213                 (const_int 8)
215           ;; Check for doubleword moves that are decomposed into two
216           ;; instructions.
217           (and (eq_attr "move_type" "mtc,mfc,move")
218                (eq_attr "dword_mode" "yes"))
219           (const_int 8)
221           ;; Doubleword CONST{,N} moves are split into two word
222           ;; CONST{,N} moves.
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
228           ;; routines.
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")
233           ] (const_int 4)))
235 ;; Is copying of this instruction disallowed?
236 (define_attr "cannot_copy" "no,yes" (const_string "no"))
238 ;; Describe a user's asm statement.
239 (define_asm_attributes
240   [(set_attr "type" "multi")])
242 ;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
243 ;; from the same template.
244 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
246 ;; This mode iterator allows :P to be used for patterns that operate on
247 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
248 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
250 ;; Likewise, but for XLEN-sized quantities.
251 (define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")])
253 ;; Branches operate on XLEN-sized quantities, but for RV64 we accept
254 ;; QImode values so we can force zero-extension.
255 (define_mode_iterator BR [(QI "TARGET_64BIT") SI (DI "TARGET_64BIT")])
257 ;; 32-bit moves for which we provide move patterns.
258 (define_mode_iterator MOVE32 [SI])
260 ;; 64-bit modes for which we provide move patterns.
261 (define_mode_iterator MOVE64 [DI DF])
263 ;; Iterator for sub-32-bit integer modes.
264 (define_mode_iterator SHORT [QI HI])
266 ;; Iterator for HImode constant generation.
267 (define_mode_iterator HISI [HI SI])
269 ;; Iterator for QImode extension patterns.
270 (define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")])
272 ;; Iterator for extending loads.
273 (define_mode_iterator ZERO_EXTEND_LOAD [QI HI (SI "TARGET_64BIT")])
275 ;; Iterator for hardware integer modes narrower than XLEN.
276 (define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")])
278 ;; Iterator for hardware-supported integer modes.
279 (define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")])
281 ;; Iterator for hardware-supported floating-point modes.
282 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
283                             (DF "TARGET_DOUBLE_FLOAT")])
285 ;; This attribute gives the length suffix for a sign- or zero-extension
286 ;; instruction.
287 (define_mode_attr size [(QI "b") (HI "h")])
289 ;; Mode attributes for loads.
290 (define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")])
292 ;; Instruction names for stores.
293 (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")])
295 ;; This attribute gives the best constraint to use for registers of
296 ;; a given mode.
297 (define_mode_attr reg [(SI "d") (DI "d") (CC "d")])
299 ;; This attribute gives the format suffix for floating-point operations.
300 (define_mode_attr fmt [(SF "s") (DF "d")])
302 ;; This attribute gives the integer suffix for floating-point conversions.
303 (define_mode_attr ifmt [(SI "w") (DI "l")])
305 ;; This attribute gives the format suffix for atomic memory operations.
306 (define_mode_attr amo [(SI "w") (DI "d")])
308 ;; This attribute gives the upper-case mode name for one unit of a
309 ;; floating-point mode.
310 (define_mode_attr UNITMODE [(SF "SF") (DF "DF")])
312 ;; This attribute gives the integer mode that has half the size of
313 ;; the controlling mode.
314 (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
316 ;; Iterator and attributes for floating-point rounding instructions.
317 (define_int_iterator RINT [UNSPEC_LRINT UNSPEC_LROUND])
318 (define_int_attr rint_pattern [(UNSPEC_LRINT "rint") (UNSPEC_LROUND "round")])
319 (define_int_attr rint_rm [(UNSPEC_LRINT "dyn") (UNSPEC_LROUND "rmm")])
321 ;; Iterator and attributes for quiet comparisons.
322 (define_int_iterator QUIET_COMPARISON [UNSPEC_FLT_QUIET UNSPEC_FLE_QUIET])
323 (define_int_attr quiet_pattern [(UNSPEC_FLT_QUIET "lt") (UNSPEC_FLE_QUIET "le")])
325 ;; This code iterator allows signed and unsigned widening multiplications
326 ;; to use the same template.
327 (define_code_iterator any_extend [sign_extend zero_extend])
329 ;; This code iterator allows the two right shift instructions to be
330 ;; generated from the same template.
331 (define_code_iterator any_shiftrt [ashiftrt lshiftrt])
333 ;; This code iterator allows the three shift instructions to be generated
334 ;; from the same template.
335 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
337 ;; This code iterator allows the three bitwise instructions to be generated
338 ;; from the same template.
339 (define_code_iterator any_bitwise [and ior xor])
341 ;; This code iterator allows unsigned and signed division to be generated
342 ;; from the same template.
343 (define_code_iterator any_div [div udiv mod umod])
345 ;; This code iterator allows unsigned and signed modulus to be generated
346 ;; from the same template.
347 (define_code_iterator any_mod [mod umod])
349 ;; These code iterators allow the signed and unsigned scc operations to use
350 ;; the same template.
351 (define_code_iterator any_gt [gt gtu])
352 (define_code_iterator any_ge [ge geu])
353 (define_code_iterator any_lt [lt ltu])
354 (define_code_iterator any_le [le leu])
356 ;; <u> expands to an empty string when doing a signed operation and
357 ;; "u" when doing an unsigned operation.
358 (define_code_attr u [(sign_extend "") (zero_extend "u")
359                      (gt "") (gtu "u")
360                      (ge "") (geu "u")
361                      (lt "") (ltu "u")
362                      (le "") (leu "u")])
364 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
365 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
367 ;; <optab> expands to the name of the optab for a particular code.
368 (define_code_attr optab [(ashift "ashl")
369                          (ashiftrt "ashr")
370                          (lshiftrt "lshr")
371                          (div "div")
372                          (mod "mod")
373                          (udiv "udiv")
374                          (umod "umod")
375                          (ge "ge")
376                          (le "le")
377                          (gt "gt")
378                          (lt "lt")
379                          (ior "ior")
380                          (xor "xor")
381                          (and "and")
382                          (plus "add")
383                          (minus "sub")])
385 ;; <insn> expands to the name of the insn that implements a particular code.
386 (define_code_attr insn [(ashift "sll")
387                         (ashiftrt "sra")
388                         (lshiftrt "srl")
389                         (div "div")
390                         (mod "rem")
391                         (udiv "divu")
392                         (umod "remu")
393                         (ior "or")
394                         (xor "xor")
395                         (and "and")
396                         (plus "add")
397                         (minus "sub")])
399 ;; Ghost instructions produce no real code and introduce no hazards.
400 ;; They exist purely to express an effect on dataflow.
401 (define_insn_reservation "ghost" 0
402   (eq_attr "type" "ghost")
403   "nothing")
406 ;;  ....................
408 ;;      ADDITION
410 ;;  ....................
413 (define_insn "add<mode>3"
414   [(set (match_operand:ANYF            0 "register_operand" "=f")
415         (plus:ANYF (match_operand:ANYF 1 "register_operand" " f")
416                    (match_operand:ANYF 2 "register_operand" " f")))]
417   "TARGET_HARD_FLOAT"
418   "fadd.<fmt>\t%0,%1,%2"
419   [(set_attr "type" "fadd")
420    (set_attr "mode" "<UNITMODE>")])
422 (define_insn "addsi3"
423   [(set (match_operand:SI          0 "register_operand" "=r,r")
424         (plus:SI (match_operand:SI 1 "register_operand" " r,r")
425                  (match_operand:SI 2 "arith_operand"    " r,I")))]
426   ""
427   { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
428   [(set_attr "type" "arith")
429    (set_attr "mode" "SI")])
431 (define_insn "adddi3"
432   [(set (match_operand:DI          0 "register_operand" "=r,r")
433         (plus:DI (match_operand:DI 1 "register_operand" " r,r")
434                  (match_operand:DI 2 "arith_operand"    " r,I")))]
435   "TARGET_64BIT"
436   "add%i2\t%0,%1,%2"
437   [(set_attr "type" "arith")
438    (set_attr "mode" "DI")])
440 (define_insn "*addsi3_extended"
441   [(set (match_operand:DI               0 "register_operand" "=r,r")
442         (sign_extend:DI
443              (plus:SI (match_operand:SI 1 "register_operand" " r,r")
444                       (match_operand:SI 2 "arith_operand"    " r,I"))))]
445   "TARGET_64BIT"
446   "add%i2w\t%0,%1,%2"
447   [(set_attr "type" "arith")
448    (set_attr "mode" "SI")])
450 (define_insn "*addsi3_extended2"
451   [(set (match_operand:DI                       0 "register_operand" "=r,r")
452         (sign_extend:DI
453           (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" " r,r")
454                               (match_operand:DI 2 "arith_operand"    " r,I"))
455                      0)))]
456   "TARGET_64BIT"
457   "add%i2w\t%0,%1,%2"
458   [(set_attr "type" "arith")
459    (set_attr "mode" "SI")])
462 ;;  ....................
464 ;;      SUBTRACTION
466 ;;  ....................
469 (define_insn "sub<mode>3"
470   [(set (match_operand:ANYF             0 "register_operand" "=f")
471         (minus:ANYF (match_operand:ANYF 1 "register_operand" " f")
472                     (match_operand:ANYF 2 "register_operand" " f")))]
473   "TARGET_HARD_FLOAT"
474   "fsub.<fmt>\t%0,%1,%2"
475   [(set_attr "type" "fadd")
476    (set_attr "mode" "<UNITMODE>")])
478 (define_insn "subdi3"
479   [(set (match_operand:DI 0            "register_operand" "= r")
480         (minus:DI (match_operand:DI 1  "reg_or_0_operand" " rJ")
481                    (match_operand:DI 2 "register_operand" "  r")))]
482   "TARGET_64BIT"
483   "sub\t%0,%z1,%2"
484   [(set_attr "type" "arith")
485    (set_attr "mode" "DI")])
487 (define_insn "subsi3"
488   [(set (match_operand:SI           0 "register_operand" "= r")
489         (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
490                   (match_operand:SI 2 "register_operand" "  r")))]
491   ""
492   { return TARGET_64BIT ? "subw\t%0,%z1,%2" : "sub\t%0,%z1,%2"; }
493   [(set_attr "type" "arith")
494    (set_attr "mode" "SI")])
496 (define_insn "*subsi3_extended"
497   [(set (match_operand:DI               0 "register_operand" "= r")
498         (sign_extend:DI
499             (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
500                       (match_operand:SI 2 "register_operand" "  r"))))]
501   "TARGET_64BIT"
502   "subw\t%0,%z1,%2"
503   [(set_attr "type" "arith")
504    (set_attr "mode" "SI")])
506 (define_insn "*subsi3_extended2"
507   [(set (match_operand:DI                        0 "register_operand" "=r")
508         (sign_extend:DI
509           (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" " r")
510                                (match_operand:DI 2 "register_operand" " r"))
511                      0)))]
512   "TARGET_64BIT"
513   "subw\t%0,%z1,%2"
514   [(set_attr "type" "arith")
515    (set_attr "mode" "SI")])
518 ;;  ....................
520 ;;      MULTIPLICATION
522 ;;  ....................
525 (define_insn "mul<mode>3"
526   [(set (match_operand:ANYF               0 "register_operand" "=f")
527         (mult:ANYF (match_operand:ANYF    1 "register_operand" " f")
528                       (match_operand:ANYF 2 "register_operand" " f")))]
529   "TARGET_HARD_FLOAT"
530   "fmul.<fmt>\t%0,%1,%2"
531   [(set_attr "type" "fmul")
532    (set_attr "mode" "<UNITMODE>")])
534 (define_insn "mulsi3"
535   [(set (match_operand:SI          0 "register_operand" "=r")
536         (mult:SI (match_operand:SI 1 "register_operand" " r")
537                  (match_operand:SI 2 "register_operand" " r")))]
538   "TARGET_MUL"
539   { return TARGET_64BIT ? "mulw\t%0,%1,%2" : "mul\t%0,%1,%2"; }
540   [(set_attr "type" "imul")
541    (set_attr "mode" "SI")])
543 (define_insn "muldi3"
544   [(set (match_operand:DI          0 "register_operand" "=r")
545         (mult:DI (match_operand:DI 1 "register_operand" " r")
546                  (match_operand:DI 2 "register_operand" " r")))]
547   "TARGET_MUL && TARGET_64BIT"
548   "mul\t%0,%1,%2"
549   [(set_attr "type" "imul")
550    (set_attr "mode" "DI")])
552 (define_insn "*mulsi3_extended"
553   [(set (match_operand:DI              0 "register_operand" "=r")
554         (sign_extend:DI
555             (mult:SI (match_operand:SI 1 "register_operand" " r")
556                      (match_operand:SI 2 "register_operand" " r"))))]
557   "TARGET_MUL && TARGET_64BIT"
558   "mulw\t%0,%1,%2"
559   [(set_attr "type" "imul")
560    (set_attr "mode" "SI")])
562 (define_insn "*mulsi3_extended2"
563   [(set (match_operand:DI                       0 "register_operand" "=r")
564         (sign_extend:DI
565           (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" " r")
566                               (match_operand:DI 2 "register_operand" " r"))
567                      0)))]
568   "TARGET_MUL && TARGET_64BIT"
569   "mulw\t%0,%1,%2"
570   [(set_attr "type" "imul")
571    (set_attr "mode" "SI")])
574 ;;  ........................
576 ;;      MULTIPLICATION HIGH-PART
578 ;;  ........................
582 (define_expand "<u>mulditi3"
583   [(set (match_operand:TI                         0 "register_operand")
584         (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
585                  (any_extend:TI (match_operand:DI 2 "register_operand"))))]
586   "TARGET_MUL && TARGET_64BIT"
588   rtx low = gen_reg_rtx (DImode);
589   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
591   rtx high = gen_reg_rtx (DImode);
592   emit_insn (gen_<u>muldi3_highpart (high, operands[1], operands[2]));
594   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
595   emit_move_insn (gen_highpart (DImode, operands[0]), high);
596   DONE;
599 (define_insn "<u>muldi3_highpart"
600   [(set (match_operand:DI                0 "register_operand" "=r")
601         (truncate:DI
602           (lshiftrt:TI
603             (mult:TI (any_extend:TI
604                        (match_operand:DI 1 "register_operand" " r"))
605                      (any_extend:TI
606                        (match_operand:DI 2 "register_operand" " r")))
607             (const_int 64))))]
608   "TARGET_MUL && TARGET_64BIT"
609   "mulh<u>\t%0,%1,%2"
610   [(set_attr "type" "imul")
611    (set_attr "mode" "DI")])
613 (define_expand "usmulditi3"
614   [(set (match_operand:TI                          0 "register_operand")
615         (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand"))
616                  (sign_extend:TI (match_operand:DI 2 "register_operand"))))]
617   "TARGET_MUL && TARGET_64BIT"
619   rtx low = gen_reg_rtx (DImode);
620   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
622   rtx high = gen_reg_rtx (DImode);
623   emit_insn (gen_usmuldi3_highpart (high, operands[1], operands[2]));
625   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
626   emit_move_insn (gen_highpart (DImode, operands[0]), high);
627   DONE;
630 (define_insn "usmuldi3_highpart"
631   [(set (match_operand:DI                0 "register_operand" "=r")
632         (truncate:DI
633           (lshiftrt:TI
634             (mult:TI (zero_extend:TI
635                        (match_operand:DI 1 "register_operand"  "r"))
636                      (sign_extend:TI
637                        (match_operand:DI 2 "register_operand" " r")))
638             (const_int 64))))]
639   "TARGET_MUL && TARGET_64BIT"
640   "mulhsu\t%0,%2,%1"
641   [(set_attr "type" "imul")
642    (set_attr "mode" "DI")])
644 (define_expand "<u>mulsidi3"
645   [(set (match_operand:DI            0 "register_operand" "=r")
646         (mult:DI (any_extend:DI
647                    (match_operand:SI 1 "register_operand" " r"))
648                  (any_extend:DI
649                    (match_operand:SI 2 "register_operand" " r"))))]
650   "TARGET_MUL && !TARGET_64BIT"
652   rtx temp = gen_reg_rtx (SImode);
653   emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
654   emit_insn (gen_<u>mulsi3_highpart (riscv_subword (operands[0], true),
655                                      operands[1], operands[2]));
656   emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
657   DONE;
660 (define_insn "<u>mulsi3_highpart"
661   [(set (match_operand:SI                0 "register_operand" "=r")
662         (truncate:SI
663           (lshiftrt:DI
664             (mult:DI (any_extend:DI
665                        (match_operand:SI 1 "register_operand" " r"))
666                      (any_extend:DI
667                        (match_operand:SI 2 "register_operand" " r")))
668             (const_int 32))))]
669   "TARGET_MUL && !TARGET_64BIT"
670   "mulh<u>\t%0,%1,%2"
671   [(set_attr "type" "imul")
672    (set_attr "mode" "SI")])
675 (define_expand "usmulsidi3"
676   [(set (match_operand:DI            0 "register_operand" "=r")
677         (mult:DI (zero_extend:DI
678                    (match_operand:SI 1 "register_operand" " r"))
679                  (sign_extend:DI
680                    (match_operand:SI 2 "register_operand" " r"))))]
681   "TARGET_MUL && !TARGET_64BIT"
683   rtx temp = gen_reg_rtx (SImode);
684   emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
685   emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true),
686                                      operands[1], operands[2]));
687   emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
688   DONE;
691 (define_insn "usmulsi3_highpart"
692   [(set (match_operand:SI                0 "register_operand" "=r")
693         (truncate:SI
694           (lshiftrt:DI
695             (mult:DI (zero_extend:DI
696                        (match_operand:SI 1 "register_operand" " r"))
697                      (sign_extend:DI
698                        (match_operand:SI 2 "register_operand" " r")))
699             (const_int 32))))]
700   "TARGET_MUL && !TARGET_64BIT"
701   "mulhsu\t%0,%2,%1"
702   [(set_attr "type" "imul")
703    (set_attr "mode" "SI")])
706 ;;  ....................
708 ;;      DIVISION and REMAINDER
710 ;;  ....................
713 (define_insn "<optab>si3"
714   [(set (match_operand:SI             0 "register_operand" "=r")
715         (any_div:SI (match_operand:SI 1 "register_operand" " r")
716                     (match_operand:SI 2 "register_operand" " r")))]
717   "TARGET_DIV"
718   { return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2"; }
719   [(set_attr "type" "idiv")
720    (set_attr "mode" "SI")])
722 (define_insn "<optab>di3"
723   [(set (match_operand:DI             0 "register_operand" "=r")
724         (any_div:DI (match_operand:DI 1 "register_operand" " r")
725                     (match_operand:DI 2 "register_operand" " r")))]
726   "TARGET_DIV && TARGET_64BIT"
727   "<insn>%i2\t%0,%1,%2"
728   [(set_attr "type" "idiv")
729    (set_attr "mode" "DI")])
731 (define_insn "*<optab>si3_extended"
732   [(set (match_operand:DI                 0 "register_operand" "=r")
733         (sign_extend:DI
734             (any_div:SI (match_operand:SI 1 "register_operand" " r")
735                         (match_operand:SI 2 "register_operand" " r"))))]
736   "TARGET_DIV && TARGET_64BIT"
737   "<insn>%i2w\t%0,%1,%2"
738   [(set_attr "type" "idiv")
739    (set_attr "mode" "DI")])
741 (define_insn "div<mode>3"
742   [(set (match_operand:ANYF           0 "register_operand" "=f")
743         (div:ANYF (match_operand:ANYF 1 "register_operand" " f")
744                   (match_operand:ANYF 2 "register_operand" " f")))]
745   "TARGET_HARD_FLOAT && TARGET_FDIV"
746   "fdiv.<fmt>\t%0,%1,%2"
747   [(set_attr "type" "fdiv")
748    (set_attr "mode" "<UNITMODE>")])
751 ;;  ....................
753 ;;      SQUARE ROOT
755 ;;  ....................
757 (define_insn "sqrt<mode>2"
758   [(set (match_operand:ANYF            0 "register_operand" "=f")
759         (sqrt:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
760   "TARGET_HARD_FLOAT && TARGET_FDIV"
762     return "fsqrt.<fmt>\t%0,%1";
764   [(set_attr "type" "fsqrt")
765    (set_attr "mode" "<UNITMODE>")])
767 ;; Floating point multiply accumulate instructions.
769 ;; a * b + c
770 (define_insn "fma<mode>4"
771   [(set (match_operand:ANYF           0 "register_operand" "=f")
772         (fma:ANYF (match_operand:ANYF 1 "register_operand" " f")
773                   (match_operand:ANYF 2 "register_operand" " f")
774                   (match_operand:ANYF 3 "register_operand" " f")))]
775   "TARGET_HARD_FLOAT"
776   "fmadd.<fmt>\t%0,%1,%2,%3"
777   [(set_attr "type" "fmadd")
778    (set_attr "mode" "<UNITMODE>")])
780 ;; a * b - c
781 (define_insn "fms<mode>4"
782   [(set (match_operand:ANYF                     0 "register_operand" "=f")
783         (fma:ANYF (match_operand:ANYF           1 "register_operand" " f")
784                   (match_operand:ANYF           2 "register_operand" " f")
785                   (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
786   "TARGET_HARD_FLOAT"
787   "fmsub.<fmt>\t%0,%1,%2,%3"
788   [(set_attr "type" "fmadd")
789    (set_attr "mode" "<UNITMODE>")])
791 ;; -a * b - c
792 (define_insn "fnms<mode>4"
793   [(set (match_operand:ANYF               0 "register_operand" "=f")
794         (fma:ANYF
795             (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
796             (match_operand:ANYF           2 "register_operand" " f")
797             (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
798   "TARGET_HARD_FLOAT"
799   "fnmadd.<fmt>\t%0,%1,%2,%3"
800   [(set_attr "type" "fmadd")
801    (set_attr "mode" "<UNITMODE>")])
803 ;; -a * b + c
804 (define_insn "fnma<mode>4"
805   [(set (match_operand:ANYF               0 "register_operand" "=f")
806         (fma:ANYF
807             (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
808             (match_operand:ANYF           2 "register_operand" " f")
809             (match_operand:ANYF           3 "register_operand" " f")))]
810   "TARGET_HARD_FLOAT"
811   "fnmsub.<fmt>\t%0,%1,%2,%3"
812   [(set_attr "type" "fmadd")
813    (set_attr "mode" "<UNITMODE>")])
815 ;; -(-a * b - c), modulo signed zeros
816 (define_insn "*fma<mode>4"
817   [(set (match_operand:ANYF                   0 "register_operand" "=f")
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                 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
823   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
824   "fmadd.<fmt>\t%0,%1,%2,%3"
825   [(set_attr "type" "fmadd")
826    (set_attr "mode" "<UNITMODE>")])
828 ;; -(-a * b + c), modulo signed zeros
829 (define_insn "*fms<mode>4"
830   [(set (match_operand:ANYF                   0 "register_operand" "=f")
831         (neg:ANYF
832             (fma:ANYF
833                 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
834                 (match_operand:ANYF           2 "register_operand" " f")
835                 (match_operand:ANYF           3 "register_operand" " f"))))]
836   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
837   "fmsub.<fmt>\t%0,%1,%2,%3"
838   [(set_attr "type" "fmadd")
839    (set_attr "mode" "<UNITMODE>")])
841 ;; -(a * b + c), modulo signed zeros
842 (define_insn "*fnms<mode>4"
843   [(set (match_operand:ANYF         0 "register_operand" "=f")
844         (neg:ANYF
845             (fma:ANYF
846                 (match_operand:ANYF 1 "register_operand" " f")
847                 (match_operand:ANYF 2 "register_operand" " f")
848                 (match_operand:ANYF 3 "register_operand" " f"))))]
849   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
850   "fnmadd.<fmt>\t%0,%1,%2,%3"
851   [(set_attr "type" "fmadd")
852    (set_attr "mode" "<UNITMODE>")])
854 ;; -(a * b - c), modulo signed zeros
855 (define_insn "*fnma<mode>4"
856   [(set (match_operand:ANYF                   0 "register_operand" "=f")
857         (neg:ANYF
858             (fma:ANYF
859                 (match_operand:ANYF           1 "register_operand" " f")
860                 (match_operand:ANYF           2 "register_operand" " f")
861                 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
862   "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
863   "fnmsub.<fmt>\t%0,%1,%2,%3"
864   [(set_attr "type" "fmadd")
865    (set_attr "mode" "<UNITMODE>")])
868 ;;  ....................
870 ;;      SIGN INJECTION
872 ;;  ....................
874 (define_insn "abs<mode>2"
875   [(set (match_operand:ANYF           0 "register_operand" "=f")
876         (abs:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
877   "TARGET_HARD_FLOAT"
878   "fabs.<fmt>\t%0,%1"
879   [(set_attr "type" "fmove")
880    (set_attr "mode" "<UNITMODE>")])
882 (define_insn "copysign<mode>3"
883   [(set (match_operand:ANYF 0 "register_operand"               "=f")
884         (unspec:ANYF [(match_operand:ANYF 1 "register_operand" " f")
885                       (match_operand:ANYF 2 "register_operand" " f")]
886                      UNSPEC_COPYSIGN))]
887   "TARGET_HARD_FLOAT"
888   "fsgnj.<fmt>\t%0,%1,%2"
889   [(set_attr "type" "fmove")
890    (set_attr "mode" "<UNITMODE>")])
892 (define_insn "neg<mode>2"
893   [(set (match_operand:ANYF           0 "register_operand" "=f")
894         (neg:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
895   "TARGET_HARD_FLOAT"
896   "fneg.<fmt>\t%0,%1"
897   [(set_attr "type" "fmove")
898    (set_attr "mode" "<UNITMODE>")])
901 ;;  ....................
903 ;;      MIN/MAX
905 ;;  ....................
907 (define_insn "smin<mode>3"
908   [(set (match_operand:ANYF            0 "register_operand" "=f")
909         (smin:ANYF (match_operand:ANYF 1 "register_operand" " f")
910                    (match_operand:ANYF 2 "register_operand" " f")))]
911   "TARGET_HARD_FLOAT"
912   "fmin.<fmt>\t%0,%1,%2"
913   [(set_attr "type" "fmove")
914    (set_attr "mode" "<UNITMODE>")])
916 (define_insn "smax<mode>3"
917   [(set (match_operand:ANYF            0 "register_operand" "=f")
918         (smax:ANYF (match_operand:ANYF 1 "register_operand" " f")
919                    (match_operand:ANYF 2 "register_operand" " f")))]
920   "TARGET_HARD_FLOAT"
921   "fmax.<fmt>\t%0,%1,%2"
922   [(set_attr "type" "fmove")
923    (set_attr "mode" "<UNITMODE>")])
926 ;;  ....................
928 ;;      LOGICAL
930 ;;  ....................
933 ;; For RV64, we don't expose the SImode operations to the rtl expanders,
934 ;; but SImode versions exist for combine.
936 (define_insn "<optab><mode>3"
937   [(set (match_operand:X                0 "register_operand" "=r,r")
938         (any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
939                        (match_operand:X 2 "arith_operand"    " r,I")))]
940   ""
941   "<insn>%i2\t%0,%1,%2"
942   [(set_attr "type" "logical")
943    (set_attr "mode" "<MODE>")])
945 (define_insn "*<optab>si3_internal"
946   [(set (match_operand:SI                 0 "register_operand" "=r,r")
947         (any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r")
948                         (match_operand:SI 2 "arith_operand"    " r,I")))]
949   "TARGET_64BIT"
950   "<insn>%i2\t%0,%1,%2"
951   [(set_attr "type" "logical")
952    (set_attr "mode" "SI")])
954 (define_insn "one_cmpl<mode>2"
955   [(set (match_operand:X        0 "register_operand" "=r")
956         (not:X (match_operand:X 1 "register_operand" " r")))]
957   ""
958   "not\t%0,%1"
959   [(set_attr "type" "logical")
960    (set_attr "mode" "<MODE>")])
962 (define_insn "*one_cmplsi2_internal"
963   [(set (match_operand:SI         0 "register_operand" "=r")
964         (not:SI (match_operand:SI 1 "register_operand" " r")))]
965   "TARGET_64BIT"
966   "not\t%0,%1"
967   [(set_attr "type" "logical")
968    (set_attr "mode" "SI")])
971 ;;  ....................
973 ;;      TRUNCATION
975 ;;  ....................
977 (define_insn "truncdfsf2"
978   [(set (match_operand:SF     0 "register_operand" "=f")
979         (float_truncate:SF
980             (match_operand:DF 1 "register_operand" " f")))]
981   "TARGET_DOUBLE_FLOAT"
982   "fcvt.s.d\t%0,%1"
983   [(set_attr "type" "fcvt")
984    (set_attr "mode" "SF")])
987 ;;  ....................
989 ;;      ZERO EXTENSION
991 ;;  ....................
993 ;; Extension insns.
995 (define_insn_and_split "zero_extendsidi2"
996   [(set (match_operand:DI     0 "register_operand"     "=r,r")
997         (zero_extend:DI
998             (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
999   "TARGET_64BIT"
1000   "@
1001    #
1002    lwu\t%0,%1"
1003   "&& reload_completed && REG_P (operands[1])"
1004   [(set (match_dup 0)
1005         (ashift:DI (match_dup 1) (const_int 32)))
1006    (set (match_dup 0)
1007         (lshiftrt:DI (match_dup 0) (const_int 32)))]
1008   { operands[1] = gen_lowpart (DImode, operands[1]); }
1009   [(set_attr "move_type" "shift_shift,load")
1010    (set_attr "mode" "DI")])
1012 (define_insn_and_split "zero_extendhi<GPR:mode>2"
1013   [(set (match_operand:GPR    0 "register_operand"     "=r,r")
1014         (zero_extend:GPR
1015             (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
1016   ""
1017   "@
1018    #
1019    lhu\t%0,%1"
1020   "&& reload_completed && REG_P (operands[1])"
1021   [(set (match_dup 0)
1022         (ashift:GPR (match_dup 1) (match_dup 2)))
1023    (set (match_dup 0)
1024         (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
1025   {
1026     operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
1027     operands[2] = GEN_INT(GET_MODE_BITSIZE(<GPR:MODE>mode) - 16);
1028   }
1029   [(set_attr "move_type" "shift_shift,load")
1030    (set_attr "mode" "<GPR:MODE>")])
1032 (define_insn "zero_extendqi<SUPERQI:mode>2"
1033   [(set (match_operand:SUPERQI 0 "register_operand"    "=r,r")
1034         (zero_extend:SUPERQI
1035             (match_operand:QI 1 "nonimmediate_operand" " r,m")))]
1036   ""
1037   "@
1038    andi\t%0,%1,0xff
1039    lbu\t%0,%1"
1040   [(set_attr "move_type" "andi,load")
1041    (set_attr "mode" "<SUPERQI:MODE>")])
1044 ;;  ....................
1046 ;;      SIGN EXTENSION
1048 ;;  ....................
1050 (define_insn "extendsidi2"
1051   [(set (match_operand:DI     0 "register_operand"     "=r,r")
1052         (sign_extend:DI
1053             (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
1054   "TARGET_64BIT"
1055   "@
1056    sext.w\t%0,%1
1057    lw\t%0,%1"
1058   [(set_attr "move_type" "move,load")
1059    (set_attr "mode" "DI")])
1061 (define_insn_and_split "extend<SHORT:mode><SUPERQI:mode>2"
1062   [(set (match_operand:SUPERQI   0 "register_operand"     "=r,r")
1063         (sign_extend:SUPERQI
1064             (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
1065   ""
1066   "@
1067    #
1068    l<SHORT:size>\t%0,%1"
1069   "&& reload_completed && REG_P (operands[1])"
1070   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1071    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
1073   operands[0] = gen_lowpart (SImode, operands[0]);
1074   operands[1] = gen_lowpart (SImode, operands[1]);
1075   operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
1076                          - GET_MODE_BITSIZE (<SHORT:MODE>mode));
1078   [(set_attr "move_type" "shift_shift,load")
1079    (set_attr "mode" "SI")])
1081 (define_insn "extendsfdf2"
1082   [(set (match_operand:DF     0 "register_operand" "=f")
1083         (float_extend:DF
1084             (match_operand:SF 1 "register_operand" " f")))]
1085   "TARGET_DOUBLE_FLOAT"
1086   "fcvt.d.s\t%0,%1"
1087   [(set_attr "type" "fcvt")
1088    (set_attr "mode" "DF")])
1091 ;;  ....................
1093 ;;      CONVERSIONS
1095 ;;  ....................
1097 (define_insn "fix_trunc<ANYF:mode><GPR:mode>2"
1098   [(set (match_operand:GPR      0 "register_operand" "=r")
1099         (fix:GPR
1100             (match_operand:ANYF 1 "register_operand" " f")))]
1101   "TARGET_HARD_FLOAT"
1102   "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,rtz"
1103   [(set_attr "type" "fcvt")
1104    (set_attr "mode" "<ANYF:MODE>")])
1106 (define_insn "fixuns_trunc<ANYF:mode><GPR:mode>2"
1107   [(set (match_operand:GPR      0 "register_operand" "=r")
1108         (unsigned_fix:GPR
1109             (match_operand:ANYF 1 "register_operand" " f")))]
1110   "TARGET_HARD_FLOAT"
1111   "fcvt.<GPR:ifmt>u.<ANYF:fmt> %0,%1,rtz"
1112   [(set_attr "type" "fcvt")
1113    (set_attr "mode" "<ANYF:MODE>")])
1115 (define_insn "float<GPR:mode><ANYF:mode>2"
1116   [(set (match_operand:ANYF    0 "register_operand" "= f")
1117         (float:ANYF
1118             (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1119   "TARGET_HARD_FLOAT"
1120   "fcvt.<ANYF:fmt>.<GPR:ifmt>\t%0,%z1"
1121   [(set_attr "type" "fcvt")
1122    (set_attr "mode" "<ANYF:MODE>")])
1124 (define_insn "floatuns<GPR:mode><ANYF:mode>2"
1125   [(set (match_operand:ANYF    0 "register_operand" "= f")
1126         (unsigned_float:ANYF
1127             (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1128   "TARGET_HARD_FLOAT"
1129   "fcvt.<ANYF:fmt>.<GPR:ifmt>u\t%0,%z1"
1130   [(set_attr "type" "fcvt")
1131    (set_attr "mode" "<ANYF:MODE>")])
1133 (define_insn "l<rint_pattern><ANYF:mode><GPR:mode>2"
1134   [(set (match_operand:GPR       0 "register_operand" "=r")
1135         (unspec:GPR
1136             [(match_operand:ANYF 1 "register_operand" " f")]
1137             RINT))]
1138   "TARGET_HARD_FLOAT"
1139   "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,<rint_rm>"
1140   [(set_attr "type" "fcvt")
1141    (set_attr "mode" "<ANYF:MODE>")])
1144 ;;  ....................
1146 ;;      DATA MOVEMENT
1148 ;;  ....................
1150 ;; Lower-level instructions for loading an address from the GOT.
1151 ;; We could use MEMs, but an unspec gives more optimization
1152 ;; opportunities.
1154 (define_insn "got_load<mode>"
1155    [(set (match_operand:P      0 "register_operand" "=r")
1156          (unspec:P
1157              [(match_operand:P 1 "symbolic_operand" "")]
1158              UNSPEC_LOAD_GOT))]
1159   ""
1160   "la\t%0,%1"
1161    [(set_attr "got" "load")
1162     (set_attr "mode" "<MODE>")])
1164 (define_insn "tls_add_tp_le<mode>"
1165   [(set (match_operand:P      0 "register_operand" "=r")
1166         (unspec:P
1167             [(match_operand:P 1 "register_operand" "r")
1168              (match_operand:P 2 "register_operand" "r")
1169              (match_operand:P 3 "symbolic_operand" "")]
1170             UNSPEC_TLS_LE))]
1171   ""
1172   "add\t%0,%1,%2,%%tprel_add(%3)"
1173   [(set_attr "type" "arith")
1174    (set_attr "mode" "<MODE>")])
1176 (define_insn "got_load_tls_gd<mode>"
1177   [(set (match_operand:P      0 "register_operand" "=r")
1178         (unspec:P
1179             [(match_operand:P 1 "symbolic_operand" "")]
1180             UNSPEC_TLS_GD))]
1181   ""
1182   "la.tls.gd\t%0,%1"
1183   [(set_attr "got" "load")
1184    (set_attr "mode" "<MODE>")])
1186 (define_insn "got_load_tls_ie<mode>"
1187   [(set (match_operand:P      0 "register_operand" "=r")
1188         (unspec:P
1189             [(match_operand:P 1 "symbolic_operand" "")]
1190             UNSPEC_TLS_IE))]
1191   ""
1192   "la.tls.ie\t%0,%1"
1193   [(set_attr "got" "load")
1194    (set_attr "mode" "<MODE>")])
1196 (define_insn "auipc<mode>"
1197   [(set (match_operand:P           0 "register_operand" "=r")
1198         (unspec:P
1199             [(match_operand:P      1 "symbolic_operand" "")
1200                   (match_operand:P 2 "const_int_operand")
1201                   (pc)]
1202             UNSPEC_AUIPC))]
1203   ""
1204   ".LA%2: auipc\t%0,%h1"
1205   [(set_attr "type" "arith")
1206    (set_attr "cannot_copy" "yes")])
1208 ;; Instructions for adding the low 12 bits of an address to a register.
1209 ;; Operand 2 is the address: riscv_print_operand works out which relocation
1210 ;; should be applied.
1212 (define_insn "*low<mode>"
1213   [(set (match_operand:P           0 "register_operand" "=r")
1214         (lo_sum:P (match_operand:P 1 "register_operand" " r")
1215                   (match_operand:P 2 "symbolic_operand" "")))]
1216   ""
1217   "addi\t%0,%1,%R2"
1218   [(set_attr "type" "arith")
1219    (set_attr "mode" "<MODE>")])
1221 ;; Allow combine to split complex const_int load sequences, using operand 2
1222 ;; to store the intermediate results.  See move_operand for details.
1223 (define_split
1224   [(set (match_operand:GPR 0 "register_operand")
1225         (match_operand:GPR 1 "splittable_const_int_operand"))
1226    (clobber (match_operand:GPR 2 "register_operand"))]
1227   ""
1228   [(const_int 0)]
1230   riscv_move_integer (operands[2], operands[0], INTVAL (operands[1]));
1231   DONE;
1234 ;; Likewise, for symbolic operands.
1235 (define_split
1236   [(set (match_operand:P 0 "register_operand")
1237         (match_operand:P 1))
1238    (clobber (match_operand:P 2 "register_operand"))]
1239   "riscv_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
1240   [(set (match_dup 0) (match_dup 3))]
1242   riscv_split_symbol (operands[2], operands[1],
1243                      MAX_MACHINE_MODE, &operands[3]);
1246 ;; 64-bit integer moves
1248 (define_expand "movdi"
1249   [(set (match_operand:DI 0 "")
1250         (match_operand:DI 1 ""))]
1251   ""
1253   if (riscv_legitimize_move (DImode, operands[0], operands[1]))
1254     DONE;
1257 (define_insn "*movdi_32bit"
1258   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,  *f,*f,*r,*f,*m")
1259         (match_operand:DI 1 "move_operand"         " r,i,m,r,*J*r,*m,*f,*f,*f"))]
1260   "!TARGET_64BIT
1261    && (register_operand (operands[0], DImode)
1262        || reg_or_0_operand (operands[1], DImode))"
1263   { return riscv_output_move (operands[0], operands[1]); }
1264   [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1265    (set_attr "mode" "DI")])
1267 (define_insn "*movdi_64bit"
1268   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*f,*r,*f,*m")
1269         (match_operand:DI 1 "move_operand"         " r,T,m,rJ,*r*J,*m,*f,*f,*f"))]
1270   "TARGET_64BIT
1271    && (register_operand (operands[0], DImode)
1272        || reg_or_0_operand (operands[1], DImode))"
1273   { return riscv_output_move (operands[0], operands[1]); }
1274   [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1275    (set_attr "mode" "DI")])
1277 ;; 32-bit Integer moves
1279 (define_expand "mov<mode>"
1280   [(set (match_operand:MOVE32 0 "")
1281         (match_operand:MOVE32 1 ""))]
1282   ""
1284   if (riscv_legitimize_move (<MODE>mode, operands[0], operands[1]))
1285     DONE;
1288 (define_insn "*movsi_internal"
1289   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*f,*r,*m")
1290         (match_operand:SI 1 "move_operand"         " r,T,m,rJ,*r*J,*m,*f,*f"))]
1291   "(register_operand (operands[0], SImode)
1292     || reg_or_0_operand (operands[1], SImode))"
1293   { return riscv_output_move (operands[0], operands[1]); }
1294   [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore")
1295    (set_attr "mode" "SI")])
1297 ;; 16-bit Integer moves
1299 ;; Unlike most other insns, the move insns can't be split with
1300 ;; different predicates, because register spilling and other parts of
1301 ;; the compiler, have memoized the insn number already.
1302 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
1304 (define_expand "movhi"
1305   [(set (match_operand:HI 0 "")
1306         (match_operand:HI 1 ""))]
1307   ""
1309   if (riscv_legitimize_move (HImode, operands[0], operands[1]))
1310     DONE;
1313 (define_insn "*movhi_internal"
1314   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*r")
1315         (match_operand:HI 1 "move_operand"         " r,T,m,rJ,*r*J,*f"))]
1316   "(register_operand (operands[0], HImode)
1317     || reg_or_0_operand (operands[1], HImode))"
1318   { return riscv_output_move (operands[0], operands[1]); }
1319   [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1320    (set_attr "mode" "HI")])
1322 ;; HImode constant generation; see riscv_move_integer for details.
1323 ;; si+si->hi without truncation is legal because of
1324 ;; TARGET_TRULY_NOOP_TRUNCATION.
1326 (define_insn "*add<mode>hi3"
1327   [(set (match_operand:HI            0 "register_operand" "=r,r")
1328         (plus:HI (match_operand:HISI 1 "register_operand" " r,r")
1329                  (match_operand:HISI 2 "arith_operand"    " r,I")))]
1330   ""
1331   { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
1332   [(set_attr "type" "arith")
1333    (set_attr "mode" "HI")])
1335 (define_insn "*xor<mode>hi3"
1336   [(set (match_operand:HI 0 "register_operand"           "=r,r")
1337         (xor:HI (match_operand:HISI 1 "register_operand" " r,r")
1338                 (match_operand:HISI 2 "arith_operand"    " r,I")))]
1339   ""
1340   "xor%i2\t%0,%1,%2"
1341   [(set_attr "type" "logical")
1342    (set_attr "mode" "HI")])
1344 ;; 8-bit Integer moves
1346 (define_expand "movqi"
1347   [(set (match_operand:QI 0 "")
1348         (match_operand:QI 1 ""))]
1349   ""
1351   if (riscv_legitimize_move (QImode, operands[0], operands[1]))
1352     DONE;
1355 (define_insn "*movqi_internal"
1356   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*r")
1357         (match_operand:QI 1 "move_operand"         " r,I,m,rJ,*r*J,*f"))]
1358   "(register_operand (operands[0], QImode)
1359     || reg_or_0_operand (operands[1], QImode))"
1360   { return riscv_output_move (operands[0], operands[1]); }
1361   [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1362    (set_attr "mode" "QI")])
1364 ;; 32-bit floating point moves
1366 (define_expand "movsf"
1367   [(set (match_operand:SF 0 "")
1368         (match_operand:SF 1 ""))]
1369   ""
1371   if (riscv_legitimize_move (SFmode, operands[0], operands[1]))
1372     DONE;
1375 (define_insn "*movsf_hardfloat"
1376   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,  *r,*r,*m")
1377         (match_operand:SF 1 "move_operand"         " f,G,m,f,G,*r,*f,*G*r,*m,*r"))]
1378   "TARGET_HARD_FLOAT
1379    && (register_operand (operands[0], SFmode)
1380        || reg_or_0_operand (operands[1], SFmode))"
1381   { return riscv_output_move (operands[0], operands[1]); }
1382   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1383    (set_attr "mode" "SF")])
1385 (define_insn "*movsf_softfloat"
1386   [(set (match_operand:SF 0 "nonimmediate_operand" "= r,r,m")
1387         (match_operand:SF 1 "move_operand"         " Gr,m,r"))]
1388   "!TARGET_HARD_FLOAT
1389    && (register_operand (operands[0], SFmode)
1390        || reg_or_0_operand (operands[1], SFmode))"
1391   { return riscv_output_move (operands[0], operands[1]); }
1392   [(set_attr "move_type" "move,load,store")
1393    (set_attr "mode" "SF")])
1395 ;; 64-bit floating point moves
1397 (define_expand "movdf"
1398   [(set (match_operand:DF 0 "")
1399         (match_operand:DF 1 ""))]
1400   ""
1402   if (riscv_legitimize_move (DFmode, operands[0], operands[1]))
1403     DONE;
1406 ;; In RV32, we lack fmv.x.d and fmv.d.x.  Go through memory instead.
1407 ;; (However, we can still use fcvt.d.w to zero a floating-point register.)
1408 (define_insn "*movdf_hardfloat_rv32"
1409   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,  *r,*r,*m")
1410         (match_operand:DF 1 "move_operand"         " f,G,m,f,G,*r*G,*m,*r"))]
1411   "!TARGET_64BIT && TARGET_DOUBLE_FLOAT
1412    && (register_operand (operands[0], DFmode)
1413        || reg_or_0_operand (operands[1], DFmode))"
1414   { return riscv_output_move (operands[0], operands[1]); }
1415   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,move,load,store")
1416    (set_attr "mode" "DF")])
1418 (define_insn "*movdf_hardfloat_rv64"
1419   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,  *r,*r,*m")
1420         (match_operand:DF 1 "move_operand"         " f,G,m,f,G,*r,*f,*r*G,*m,*r"))]
1421   "TARGET_64BIT && TARGET_DOUBLE_FLOAT
1422    && (register_operand (operands[0], DFmode)
1423        || reg_or_0_operand (operands[1], DFmode))"
1424   { return riscv_output_move (operands[0], operands[1]); }
1425   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1426    (set_attr "mode" "DF")])
1428 (define_insn "*movdf_softfloat"
1429   [(set (match_operand:DF 0 "nonimmediate_operand" "= r,r, m")
1430         (match_operand:DF 1 "move_operand"         " rG,m,rG"))]
1431   "!TARGET_DOUBLE_FLOAT
1432    && (register_operand (operands[0], DFmode)
1433        || reg_or_0_operand (operands[1], DFmode))"
1434   { return riscv_output_move (operands[0], operands[1]); }
1435   [(set_attr "move_type" "move,load,store")
1436    (set_attr "mode" "DF")])
1438 (define_split
1439   [(set (match_operand:MOVE64 0 "nonimmediate_operand")
1440         (match_operand:MOVE64 1 "move_operand"))]
1441   "reload_completed
1442    && riscv_split_64bit_move_p (operands[0], operands[1])"
1443   [(const_int 0)]
1445   riscv_split_doubleword_move (operands[0], operands[1]);
1446   DONE;
1449 (define_expand "movmemsi"
1450   [(parallel [(set (match_operand:BLK 0 "general_operand")
1451                    (match_operand:BLK 1 "general_operand"))
1452               (use (match_operand:SI 2 ""))
1453               (use (match_operand:SI 3 "const_int_operand"))])]
1454   ""
1456   if (riscv_expand_block_move (operands[0], operands[1], operands[2]))
1457     DONE;
1458   else
1459     FAIL;
1462 ;; Expand in-line code to clear the instruction cache between operand[0] and
1463 ;; operand[1].
1464 (define_expand "clear_cache"
1465   [(match_operand 0 "pmode_register_operand")
1466    (match_operand 1 "pmode_register_operand")]
1467   ""
1469 #ifdef ICACHE_FLUSH_FUNC
1470   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, ICACHE_FLUSH_FUNC),
1471                      LCT_NORMAL, VOIDmode, operands[0], Pmode,
1472                      operands[1], Pmode, const0_rtx, Pmode);
1473 #else
1474   emit_insn (gen_fence_i ());
1475 #endif
1476   DONE;
1479 (define_insn "fence"
1480   [(unspec_volatile [(const_int 0)] UNSPECV_FENCE)]
1481   ""
1482   "%|fence%-")
1484 (define_insn "fence_i"
1485   [(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)]
1486   ""
1487   "fence.i")
1490 ;;  ....................
1492 ;;      SHIFTS
1494 ;;  ....................
1496 ;; Use a QImode shift count, to avoid generating sign or zero extend
1497 ;; instructions for shift counts, and to avoid dropping subregs.
1498 ;; expand_shift_1 can do this automatically when SHIFT_COUNT_TRUNCATED is
1499 ;; defined, but use of that is discouraged.
1501 (define_insn "<optab>si3"
1502   [(set (match_operand:SI     0 "register_operand" "= r")
1503         (any_shift:SI
1504             (match_operand:SI 1 "register_operand" "  r")
1505             (match_operand:QI 2 "arith_operand"    " rI")))]
1506   ""
1508   if (GET_CODE (operands[2]) == CONST_INT)
1509     operands[2] = GEN_INT (INTVAL (operands[2])
1510                            & (GET_MODE_BITSIZE (SImode) - 1));
1512   return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2";
1514   [(set_attr "type" "shift")
1515    (set_attr "mode" "SI")])
1517 (define_insn_and_split "*<optab>si3_mask"
1518   [(set (match_operand:SI     0 "register_operand" "= r")
1519         (any_shift:SI
1520             (match_operand:SI 1 "register_operand" "  r")
1521             (subreg:QI
1522              (and:SI
1523               (match_operand:SI 2 "register_operand"  "r")
1524               (match_operand 3 "const_int_operand")) 0)))]
1525   "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1526    == GET_MODE_BITSIZE (SImode)-1"
1527   "#"
1528   "&& 1"
1529   [(set (match_dup 0)
1530         (any_shift:SI (match_dup 1)
1531                       (match_dup 2)))]
1532   "operands[2] = gen_lowpart (QImode, operands[2]);"
1533   [(set_attr "type" "shift")
1534    (set_attr "mode" "SI")])
1536 (define_insn_and_split "*<optab>si3_mask_1"
1537   [(set (match_operand:SI     0 "register_operand" "= r")
1538         (any_shift:SI
1539             (match_operand:SI 1 "register_operand" "  r")
1540             (subreg:QI
1541              (and:DI
1542               (match_operand:DI 2 "register_operand"  "r")
1543               (match_operand 3 "const_int_operand")) 0)))]
1544   "TARGET_64BIT
1545    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1546        == GET_MODE_BITSIZE (SImode)-1"
1547   "#"
1548   "&& 1"
1549   [(set (match_dup 0)
1550         (any_shift:SI (match_dup 1)
1551                       (match_dup 2)))]
1552   "operands[2] = gen_lowpart (QImode, operands[2]);"
1553   [(set_attr "type" "shift")
1554    (set_attr "mode" "SI")])
1556 (define_insn "<optab>di3"
1557   [(set (match_operand:DI 0 "register_operand"     "= r")
1558         (any_shift:DI
1559             (match_operand:DI 1 "register_operand" "  r")
1560             (match_operand:QI 2 "arith_operand"    " rI")))]
1561   "TARGET_64BIT"
1563   if (GET_CODE (operands[2]) == CONST_INT)
1564     operands[2] = GEN_INT (INTVAL (operands[2])
1565                            & (GET_MODE_BITSIZE (DImode) - 1));
1567   return "<insn>%i2\t%0,%1,%2";
1569   [(set_attr "type" "shift")
1570    (set_attr "mode" "DI")])
1572 (define_insn_and_split "*<optab>di3_mask"
1573   [(set (match_operand:DI     0 "register_operand" "= r")
1574         (any_shift:DI
1575             (match_operand:DI 1 "register_operand" "  r")
1576             (subreg:QI
1577              (and:SI
1578               (match_operand:SI 2 "register_operand"  "r")
1579               (match_operand 3 "const_int_operand")) 0)))]
1580   "TARGET_64BIT
1581    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1582        == GET_MODE_BITSIZE (DImode)-1"
1583   "#"
1584   "&& 1"
1585   [(set (match_dup 0)
1586         (any_shift:DI (match_dup 1)
1587                       (match_dup 2)))]
1588   "operands[2] = gen_lowpart (QImode, operands[2]);"
1589   [(set_attr "type" "shift")
1590    (set_attr "mode" "DI")])
1592 (define_insn_and_split "*<optab>di3_mask_1"
1593   [(set (match_operand:DI     0 "register_operand" "= r")
1594         (any_shift:DI
1595             (match_operand:DI 1 "register_operand" "  r")
1596             (subreg:QI
1597              (and:DI
1598               (match_operand:DI 2 "register_operand"  "r")
1599               (match_operand 3 "const_int_operand")) 0)))]
1600   "TARGET_64BIT
1601    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1602        == GET_MODE_BITSIZE (DImode)-1"
1603   "#"
1604   "&& 1"
1605   [(set (match_dup 0)
1606         (any_shift:DI (match_dup 1)
1607                       (match_dup 2)))]
1608   "operands[2] = gen_lowpart (QImode, operands[2]);"
1609   [(set_attr "type" "shift")
1610    (set_attr "mode" "DI")])
1612 (define_insn "*<optab>si3_extend"
1613   [(set (match_operand:DI                   0 "register_operand" "= r")
1614         (sign_extend:DI
1615             (any_shift:SI (match_operand:SI 1 "register_operand" "  r")
1616                           (match_operand:QI 2 "arith_operand"    " rI"))))]
1617   "TARGET_64BIT"
1619   if (GET_CODE (operands[2]) == CONST_INT)
1620     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1622   return "<insn>%i2w\t%0,%1,%2";
1624   [(set_attr "type" "shift")
1625    (set_attr "mode" "SI")])
1627 (define_insn_and_split "*<optab>si3_extend_mask"
1628   [(set (match_operand:DI                   0 "register_operand" "= r")
1629         (sign_extend:DI
1630             (any_shift:SI
1631              (match_operand:SI 1 "register_operand" "  r")
1632              (subreg:QI
1633               (and:SI
1634                (match_operand:SI 2 "register_operand" " r")
1635                (match_operand 3 "const_int_operand")) 0))))]
1636   "TARGET_64BIT
1637    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1638        == GET_MODE_BITSIZE (SImode)-1"
1639   "#"
1640   "&& 1"
1641   [(set (match_dup 0)
1642         (sign_extend:DI
1643          (any_shift:SI (match_dup 1)
1644                        (match_dup 2))))]
1645   "operands[2] = gen_lowpart (QImode, operands[2]);"
1646   [(set_attr "type" "shift")
1647    (set_attr "mode" "SI")])
1649 (define_insn_and_split "*<optab>si3_extend_mask_1"
1650   [(set (match_operand:DI                   0 "register_operand" "= r")
1651         (sign_extend:DI
1652             (any_shift:SI
1653              (match_operand:SI 1 "register_operand" "  r")
1654              (subreg:QI
1655               (and:DI
1656                (match_operand:DI 2 "register_operand" " r")
1657                (match_operand 3 "const_int_operand")) 0))))]
1658   "TARGET_64BIT
1659    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1660        == GET_MODE_BITSIZE (SImode)-1"
1661   "#"
1662   "&& 1"
1663   [(set (match_dup 0)
1664         (sign_extend:DI
1665          (any_shift:SI (match_dup 1)
1666                        (match_dup 2))))]
1667   "operands[2] = gen_lowpart (QImode, operands[2]);"
1668   [(set_attr "type" "shift")
1669    (set_attr "mode" "SI")])
1671 ;; Non-canonical, but can be formed by ree when combine is not successful at
1672 ;; producing one of the two canonical patterns below.
1673 (define_insn "*lshrsi3_zero_extend_1"
1674   [(set (match_operand:DI                   0 "register_operand" "=r")
1675         (zero_extend:DI
1676          (lshiftrt:SI (match_operand:SI     1 "register_operand" " r")
1677                       (match_operand        2 "const_int_operand"))))]
1678   "TARGET_64BIT && (INTVAL (operands[2]) & 0x1f) > 0"
1680   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1682   return "srliw\t%0,%1,%2";
1684   [(set_attr "type" "shift")
1685    (set_attr "mode" "SI")])
1687 ;; Canonical form for a zero-extend of a logical right shift.
1688 (define_insn "*lshrsi3_zero_extend_2"
1689   [(set (match_operand:DI                   0 "register_operand" "=r")
1690         (zero_extract:DI (match_operand:DI  1 "register_operand" " r")
1691                          (match_operand     2 "const_int_operand")
1692                          (match_operand     3 "const_int_operand")))]
1693   "(TARGET_64BIT && (INTVAL (operands[3]) > 0)
1694     && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))"
1696   return "srliw\t%0,%1,%3";
1698   [(set_attr "type" "shift")
1699    (set_attr "mode" "SI")])
1701 ;; Canonical form for a zero-extend of a logical right shift when the
1702 ;; shift count is 31.
1703 (define_insn "*lshrsi3_zero_extend_3"
1704   [(set (match_operand:DI                   0 "register_operand" "=r")
1705         (lt:DI (match_operand:SI            1 "register_operand" " r")
1706                (const_int 0)))]
1707   "TARGET_64BIT"
1709   return "srliw\t%0,%1,31";
1711   [(set_attr "type" "shift")
1712    (set_attr "mode" "SI")])
1715 ;;  ....................
1717 ;;      CONDITIONAL BRANCHES
1719 ;;  ....................
1721 ;; Conditional branches
1723 (define_insn "*branch_order<mode>"
1724   [(set (pc)
1725         (if_then_else
1726          (match_operator 1 "order_operator"
1727                          [(match_operand:X 2 "register_operand" "r")
1728                           (match_operand:X 3 "register_operand" "r")])
1729          (label_ref (match_operand 0 "" ""))
1730          (pc)))]
1731   ""
1732   "b%C1\t%2,%3,%0"
1733   [(set_attr "type" "branch")
1734    (set_attr "mode" "none")])
1736 (define_insn "*branch_zero<mode>"
1737   [(set (pc)
1738         (if_then_else
1739          (match_operator 1 "signed_order_operator"
1740                          [(match_operand:X 2 "register_operand" "r")
1741                           (const_int 0)])
1742          (label_ref (match_operand 0 "" ""))
1743          (pc)))]
1744   ""
1745   "b%C1z\t%2,%0"
1746   [(set_attr "type" "branch")
1747    (set_attr "mode" "none")])
1749 ;; Used to implement built-in functions.
1750 (define_expand "condjump"
1751   [(set (pc)
1752         (if_then_else (match_operand 0)
1753                       (label_ref (match_operand 1))
1754                       (pc)))])
1756 (define_expand "cbranch<mode>4"
1757   [(set (pc)
1758         (if_then_else (match_operator 0 "comparison_operator"
1759                       [(match_operand:BR 1 "register_operand")
1760                        (match_operand:BR 2 "nonmemory_operand")])
1761                       (label_ref (match_operand 3 ""))
1762                       (pc)))]
1763   ""
1765   riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1766                                    operands[1], operands[2]);
1767   DONE;
1770 (define_expand "cbranch<mode>4"
1771   [(set (pc)
1772         (if_then_else (match_operator 0 "fp_branch_comparison"
1773                        [(match_operand:ANYF 1 "register_operand")
1774                         (match_operand:ANYF 2 "register_operand")])
1775                       (label_ref (match_operand 3 ""))
1776                       (pc)))]
1777   "TARGET_HARD_FLOAT"
1779   riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1780                                    operands[1], operands[2]);
1781   DONE;
1784 (define_insn_and_split "*branch_on_bit<X:mode>"
1785   [(set (pc)
1786         (if_then_else
1787             (match_operator 0 "equality_operator"
1788                 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1789                                  (const_int 1)
1790                                  (match_operand 3 "branch_on_bit_operand"))
1791                                  (const_int 0)])
1792             (label_ref (match_operand 1))
1793             (pc)))
1794    (clobber (match_scratch:X 4 "=&r"))]
1795   ""
1796   "#"
1797   "reload_completed"
1798   [(set (match_dup 4)
1799         (ashift:X (match_dup 2) (match_dup 3)))
1800    (set (pc)
1801         (if_then_else
1802             (match_op_dup 0 [(match_dup 4) (const_int 0)])
1803             (label_ref (match_operand 1))
1804             (pc)))]
1806   int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]);
1807   operands[3] = GEN_INT (shift);
1809   if (GET_CODE (operands[0]) == EQ)
1810     operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx);
1811   else
1812     operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx);
1815 (define_insn_and_split "*branch_on_bit_range<X:mode>"
1816   [(set (pc)
1817         (if_then_else
1818             (match_operator 0 "equality_operator"
1819                 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1820                                  (match_operand 3 "branch_on_bit_operand")
1821                                  (const_int 0))
1822                                  (const_int 0)])
1823             (label_ref (match_operand 1))
1824             (pc)))
1825    (clobber (match_scratch:X 4 "=&r"))]
1826   ""
1827   "#"
1828   "reload_completed"
1829   [(set (match_dup 4)
1830         (ashift:X (match_dup 2) (match_dup 3)))
1831    (set (pc)
1832         (if_then_else
1833             (match_op_dup 0 [(match_dup 4) (const_int 0)])
1834             (label_ref (match_operand 1))
1835             (pc)))]
1837   operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]));
1841 ;;  ....................
1843 ;;      SETTING A REGISTER FROM A COMPARISON
1845 ;;  ....................
1847 ;; Destination is always set in SI mode.
1849 (define_expand "cstore<mode>4"
1850   [(set (match_operand:SI 0 "register_operand")
1851         (match_operator:SI 1 "order_operator"
1852             [(match_operand:GPR 2 "register_operand")
1853              (match_operand:GPR 3 "nonmemory_operand")]))]
1854   ""
1856   riscv_expand_int_scc (operands[0], GET_CODE (operands[1]), operands[2],
1857                         operands[3]);
1858   DONE;
1861 (define_expand "cstore<mode>4"
1862   [(set (match_operand:SI 0 "register_operand")
1863         (match_operator:SI 1 "fp_scc_comparison"
1864              [(match_operand:ANYF 2 "register_operand")
1865               (match_operand:ANYF 3 "register_operand")]))]
1866   "TARGET_HARD_FLOAT"
1868   riscv_expand_float_scc (operands[0], GET_CODE (operands[1]), operands[2],
1869                           operands[3]);
1870   DONE;
1873 (define_insn "*cstore<ANYF:mode><X:mode>4"
1874    [(set (match_operand:X         0 "register_operand" "=r")
1875          (match_operator:X 1 "fp_native_comparison"
1876              [(match_operand:ANYF 2 "register_operand" " f")
1877               (match_operand:ANYF 3 "register_operand" " f")]))]
1878   "TARGET_HARD_FLOAT"
1879   "f%C1.<fmt>\t%0,%2,%3"
1880   [(set_attr "type" "fcmp")
1881    (set_attr "mode" "<UNITMODE>")])
1883 (define_insn "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4"
1884    [(set (match_operand:X         0 "register_operand" "=r")
1885          (unspec:X
1886              [(match_operand:ANYF 1 "register_operand" " f")
1887               (match_operand:ANYF 2 "register_operand" " f")]
1888              QUIET_COMPARISON))
1889     (clobber (match_scratch:X 3 "=&r"))]
1890   "TARGET_HARD_FLOAT"
1891   "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3"
1892   [(set_attr "type" "fcmp")
1893    (set_attr "mode" "<UNITMODE>")
1894    (set (attr "length") (const_int 12))])
1896 (define_insn "*seq_zero_<X:mode><GPR:mode>"
1897   [(set (match_operand:GPR       0 "register_operand" "=r")
1898         (eq:GPR (match_operand:X 1 "register_operand" " r")
1899                 (const_int 0)))]
1900   ""
1901   "seqz\t%0,%1"
1902   [(set_attr "type" "slt")
1903    (set_attr "mode" "<X:MODE>")])
1905 (define_insn "*sne_zero_<X:mode><GPR:mode>"
1906   [(set (match_operand:GPR       0 "register_operand" "=r")
1907         (ne:GPR (match_operand:X 1 "register_operand" " r")
1908                 (const_int 0)))]
1909   ""
1910   "snez\t%0,%1"
1911   [(set_attr "type" "slt")
1912    (set_attr "mode" "<X:MODE>")])
1914 (define_insn "*sgt<u>_<X:mode><GPR:mode>"
1915   [(set (match_operand:GPR           0 "register_operand" "= r")
1916         (any_gt:GPR (match_operand:X 1 "register_operand" "  r")
1917                     (match_operand:X 2 "reg_or_0_operand" " rJ")))]
1918   ""
1919   "sgt<u>\t%0,%1,%z2"
1920   [(set_attr "type" "slt")
1921    (set_attr "mode" "<X:MODE>")])
1923 (define_insn "*sge<u>_<X:mode><GPR:mode>"
1924   [(set (match_operand:GPR           0 "register_operand" "=r")
1925         (any_ge:GPR (match_operand:X 1 "register_operand" " r")
1926                     (const_int 1)))]
1927   ""
1928   "slt%i2<u>\t%0,zero,%1"
1929   [(set_attr "type" "slt")
1930    (set_attr "mode" "<MODE>")])
1932 (define_insn "*slt<u>_<X:mode><GPR:mode>"
1933   [(set (match_operand:GPR           0 "register_operand" "= r")
1934         (any_lt:GPR (match_operand:X 1 "register_operand" "  r")
1935                     (match_operand:X 2 "arith_operand"    " rI")))]
1936   ""
1937   "slt%i2<u>\t%0,%1,%2"
1938   [(set_attr "type" "slt")
1939    (set_attr "mode" "<MODE>")])
1941 (define_insn "*sle<u>_<X:mode><GPR:mode>"
1942   [(set (match_operand:GPR           0 "register_operand" "=r")
1943         (any_le:GPR (match_operand:X 1 "register_operand" " r")
1944                     (match_operand:X 2 "sle_operand" "")))]
1945   ""
1947   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
1948   return "slt%i2<u>\t%0,%1,%2";
1950   [(set_attr "type" "slt")
1951    (set_attr "mode" "<MODE>")])
1954 ;;  ....................
1956 ;;      UNCONDITIONAL BRANCHES
1958 ;;  ....................
1960 ;; Unconditional branches.
1962 (define_insn "jump"
1963   [(set (pc)
1964         (label_ref (match_operand 0 "" "")))]
1965   ""
1966   "j\t%l0"
1967   [(set_attr "type"     "jump")
1968    (set_attr "mode"     "none")])
1970 (define_expand "indirect_jump"
1971   [(set (pc) (match_operand 0 "register_operand"))]
1972   ""
1974   operands[0] = force_reg (Pmode, operands[0]);
1975   if (Pmode == SImode)
1976     emit_jump_insn (gen_indirect_jumpsi (operands[0]));
1977   else
1978     emit_jump_insn (gen_indirect_jumpdi (operands[0]));
1979   DONE;
1982 (define_insn "indirect_jump<mode>"
1983   [(set (pc) (match_operand:P 0 "register_operand" "l"))]
1984   ""
1985   "jr\t%0"
1986   [(set_attr "type" "jump")
1987    (set_attr "mode" "none")])
1989 (define_expand "tablejump"
1990   [(set (pc) (match_operand 0 "register_operand" ""))
1991               (use (label_ref (match_operand 1 "" "")))]
1992   ""
1994   if (CASE_VECTOR_PC_RELATIVE)
1995       operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1996                                          gen_rtx_LABEL_REF (Pmode, operands[1]),
1997                                          NULL_RTX, 0, OPTAB_DIRECT);
1999   if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode)
2000     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
2001   else
2002     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
2003   DONE;
2006 (define_insn "tablejump<mode>"
2007   [(set (pc) (match_operand:GPR 0 "register_operand" "l"))
2008    (use (label_ref (match_operand 1 "" "")))]
2009   ""
2010   "jr\t%0"
2011   [(set_attr "type" "jump")
2012    (set_attr "mode" "none")])
2015 ;;  ....................
2017 ;;      Function prologue/epilogue
2019 ;;  ....................
2022 (define_expand "prologue"
2023   [(const_int 1)]
2024   ""
2026   riscv_expand_prologue ();
2027   DONE;
2030 ;; Block any insns from being moved before this point, since the
2031 ;; profiling call to mcount can use various registers that aren't
2032 ;; saved or used to pass arguments.
2034 (define_insn "blockage"
2035   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2036   ""
2037   ""
2038   [(set_attr "type" "ghost")
2039    (set_attr "mode" "none")])
2041 (define_expand "epilogue"
2042   [(const_int 2)]
2043   ""
2045   riscv_expand_epilogue (NORMAL_RETURN);
2046   DONE;
2049 (define_expand "sibcall_epilogue"
2050   [(const_int 2)]
2051   ""
2053   riscv_expand_epilogue (SIBCALL_RETURN);
2054   DONE;
2057 ;; Trivial return.  Make it look like a normal return insn as that
2058 ;; allows jump optimizations to work better.
2060 (define_expand "return"
2061   [(simple_return)]
2062   "riscv_can_use_return_insn ()"
2063   "")
2065 (define_insn "simple_return"
2066   [(simple_return)]
2067   ""
2069   return riscv_output_return ();
2071   [(set_attr "type"     "jump")
2072    (set_attr "mode"     "none")])
2074 ;; Normal return.
2076 (define_insn "simple_return_internal"
2077   [(simple_return)
2078    (use (match_operand 0 "pmode_register_operand" ""))]
2079   ""
2080   "jr\t%0"
2081   [(set_attr "type"     "jump")
2082    (set_attr "mode"     "none")])
2084 ;; This is used in compiling the unwind routines.
2085 (define_expand "eh_return"
2086   [(use (match_operand 0 "general_operand"))]
2087   ""
2089   if (GET_MODE (operands[0]) != word_mode)
2090     operands[0] = convert_to_mode (word_mode, operands[0], 0);
2091   if (TARGET_64BIT)
2092     emit_insn (gen_eh_set_lr_di (operands[0]));
2093   else
2094     emit_insn (gen_eh_set_lr_si (operands[0]));
2096   emit_jump_insn (gen_eh_return_internal ());
2097   emit_barrier ();
2098   DONE;
2101 ;; Clobber the return address on the stack.  We can't expand this
2102 ;; until we know where it will be put in the stack frame.
2104 (define_insn "eh_set_lr_si"
2105   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2106    (clobber (match_scratch:SI 1 "=&r"))]
2107   "! TARGET_64BIT"
2108   "#")
2110 (define_insn "eh_set_lr_di"
2111   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2112    (clobber (match_scratch:DI 1 "=&r"))]
2113   "TARGET_64BIT"
2114   "#")
2116 (define_split
2117   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
2118    (clobber (match_scratch 1))]
2119   "reload_completed"
2120   [(const_int 0)]
2122   riscv_set_return_address (operands[0], operands[1]);
2123   DONE;
2126 (define_insn_and_split "eh_return_internal"
2127   [(eh_return)]
2128   ""
2129   "#"
2130   "epilogue_completed"
2131   [(const_int 0)]
2132   "riscv_expand_epilogue (EXCEPTION_RETURN); DONE;")
2135 ;;  ....................
2137 ;;      FUNCTION CALLS
2139 ;;  ....................
2141 (define_expand "sibcall"
2142   [(parallel [(call (match_operand 0 "")
2143                     (match_operand 1 ""))
2144               (use (match_operand 2 ""))        ;; next_arg_reg
2145               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
2146   ""
2148   rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2149   emit_call_insn (gen_sibcall_internal (target, operands[1]));
2150   DONE;
2153 (define_insn "sibcall_internal"
2154   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U"))
2155          (match_operand 1 "" ""))]
2156   "SIBLING_CALL_P (insn)"
2157   "@
2158    jr\t%0
2159    tail\t%0
2160    tail\t%0@plt"
2161   [(set_attr "type" "call")])
2163 (define_expand "sibcall_value"
2164   [(parallel [(set (match_operand 0 "")
2165                    (call (match_operand 1 "")
2166                          (match_operand 2 "")))
2167               (use (match_operand 3 ""))])]             ;; next_arg_reg
2168   ""
2170   rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2171   emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2]));
2172   DONE;
2175 (define_insn "sibcall_value_internal"
2176   [(set (match_operand 0 "" "")
2177         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U"))
2178               (match_operand 2 "" "")))]
2179   "SIBLING_CALL_P (insn)"
2180   "@
2181    jr\t%1
2182    tail\t%1
2183    tail\t%1@plt"
2184   [(set_attr "type" "call")])
2186 (define_expand "call"
2187   [(parallel [(call (match_operand 0 "")
2188                     (match_operand 1 ""))
2189               (use (match_operand 2 ""))        ;; next_arg_reg
2190               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
2191   ""
2193   rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2194   emit_call_insn (gen_call_internal (target, operands[1]));
2195   DONE;
2198 (define_insn "call_internal"
2199   [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U"))
2200          (match_operand 1 "" ""))
2201    (clobber (reg:SI RETURN_ADDR_REGNUM))]
2202   ""
2203   "@
2204    jalr\t%0
2205    call\t%0
2206    call\t%0@plt"
2207   [(set_attr "type" "call")])
2209 (define_expand "call_value"
2210   [(parallel [(set (match_operand 0 "")
2211                    (call (match_operand 1 "")
2212                          (match_operand 2 "")))
2213               (use (match_operand 3 ""))])]             ;; next_arg_reg
2214   ""
2216   rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2217   emit_call_insn (gen_call_value_internal (operands[0], target, operands[2]));
2218   DONE;
2221 (define_insn "call_value_internal"
2222   [(set (match_operand 0 "" "")
2223         (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U"))
2224               (match_operand 2 "" "")))
2225    (clobber (reg:SI RETURN_ADDR_REGNUM))]
2226   ""
2227   "@
2228    jalr\t%1
2229    call\t%1
2230    call\t%1@plt"
2231   [(set_attr "type" "call")])
2233 ;; Call subroutine returning any type.
2235 (define_expand "untyped_call"
2236   [(parallel [(call (match_operand 0 "")
2237                     (const_int 0))
2238               (match_operand 1 "")
2239               (match_operand 2 "")])]
2240   ""
2242   int i;
2244   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2246   for (i = 0; i < XVECLEN (operands[2], 0); i++)
2247     {
2248       rtx set = XVECEXP (operands[2], 0, i);
2249       riscv_emit_move (SET_DEST (set), SET_SRC (set));
2250     }
2252   emit_insn (gen_blockage ());
2253   DONE;
2256 (define_insn "nop"
2257   [(const_int 0)]
2258   ""
2259   "nop"
2260   [(set_attr "type"     "nop")
2261    (set_attr "mode"     "none")])
2263 (define_insn "trap"
2264   [(trap_if (const_int 1) (const_int 0))]
2265   ""
2266   "ebreak")
2268 (define_insn "gpr_save"
2269   [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_SAVE)
2270    (clobber (reg:SI T0_REGNUM))
2271    (clobber (reg:SI T1_REGNUM))]
2272   ""
2273   { return riscv_output_gpr_save (INTVAL (operands[0])); })
2275 (define_insn "gpr_restore"
2276   [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_RESTORE)]
2277   ""
2278   "tail\t__riscv_restore_%0")
2280 (define_insn "gpr_restore_return"
2281   [(return)
2282    (use (match_operand 0 "pmode_register_operand" ""))
2283    (const_int 0)]
2284   ""
2285   "")
2287 (define_insn "riscv_frflags"
2288   [(set (match_operand:SI 0 "register_operand" "=r")
2289         (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))]
2290   "TARGET_HARD_FLOAT"
2291   "frflags\t%0")
2293 (define_insn "riscv_fsflags"
2294   [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)]
2295   "TARGET_HARD_FLOAT"
2296   "fsflags\t%0")
2298 (define_insn "riscv_mret"
2299   [(unspec_volatile [(const_int 0)] UNSPECV_MRET)]
2300   ""
2301   "mret")
2303 (define_insn "riscv_sret"
2304   [(unspec_volatile [(const_int 0)] UNSPECV_SRET)]
2305   ""
2306   "sret")
2308 (define_insn "riscv_uret"
2309   [(unspec_volatile [(const_int 0)] UNSPECV_URET)]
2310   ""
2311   "uret")
2313 (define_insn "stack_tie<mode>"
2314   [(set (mem:BLK (scratch))
2315         (unspec:BLK [(match_operand:X 0 "register_operand" "r")
2316                      (match_operand:X 1 "register_operand" "r")]
2317                     UNSPEC_TIE))]
2318   ""
2319   ""
2320   [(set_attr "length" "0")]
2323 (include "sync.md")
2324 (include "peephole.md")
2325 (include "pic.md")
2326 (include "generic.md")