1;; Machine description for RISC-V for GNU compiler.
2;; Copyright (C) 2011-2020 Free Software Foundation, Inc.
3;; Contributed by Andrew Waterman (andrew@sifive.com).
4;; Based on MIPS target for GNU compiler.
5
6;; This file is part of GCC.
7
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.
12
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.
17
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/>.
21
22(define_c_enum "unspec" [
23  ;; Override return address for exception handling.
24  UNSPEC_EH_RETURN
25
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
35
36  ;; High part of PC-relative address.
37  UNSPEC_AUIPC
38
39  ;; Floating-point unspecs.
40  UNSPEC_FLT_QUIET
41  UNSPEC_FLE_QUIET
42  UNSPEC_COPYSIGN
43  UNSPEC_LRINT
44  UNSPEC_LROUND
45
46  ;; Stack tie
47  UNSPEC_TIE
48])
49
50(define_c_enum "unspecv" [
51  ;; Register save and restore.
52  UNSPECV_GPR_SAVE
53  UNSPECV_GPR_RESTORE
54
55  ;; Floating-point unspecs.
56  UNSPECV_FRFLAGS
57  UNSPECV_FSFLAGS
58
59  ;; Interrupt handler instructions.
60  UNSPECV_MRET
61  UNSPECV_SRET
62  UNSPECV_URET
63
64  ;; Blockage and synchronization.
65  UNSPECV_BLOCKAGE
66  UNSPECV_FENCE
67  UNSPECV_FENCE_I
68])
69
70(define_constants
71  [(RETURN_ADDR_REGNUM		1)
72   (GP_REGNUM 			3)
73   (TP_REGNUM			4)
74   (T0_REGNUM			5)
75   (T1_REGNUM			6)
76   (S0_REGNUM			8)
77   (S1_REGNUM			9)
78   (S2_REGNUM			18)
79   (S3_REGNUM			19)
80   (S4_REGNUM			20)
81   (S5_REGNUM			21)
82   (S6_REGNUM			22)
83   (S7_REGNUM			23)
84   (S8_REGNUM			24)
85   (S9_REGNUM			25)
86   (S10_REGNUM			26)
87   (S11_REGNUM			27)
88
89   (NORMAL_RETURN		0)
90   (SIBCALL_RETURN		1)
91   (EXCEPTION_RETURN		2)
92])
93
94(include "predicates.md")
95(include "constraints.md")
96
97;; ....................
98;;
99;;	Attributes
100;;
101;; ....................
102
103(define_attr "got" "unset,xgot_high,load"
104  (const_string "unset"))
105
106;; Classification of moves, extensions and truncations.  Most values
107;; are as for "type" (see below) but there are also the following
108;; move-specific values:
109;;
110;; andi		a single ANDI instruction
111;; shift_shift	a shift left followed by a shift right
112;;
113;; This attribute is used to determine the instruction's length and
114;; scheduling type.  For doubleword moves, the attribute always describes
115;; the split instructions; in some cases, it is more appropriate for the
116;; scheduling type to be "multi" instead.
117(define_attr "move_type"
118  "unknown,load,fpload,store,fpstore,mtc,mfc,move,fmove,
119   const,logical,arith,andi,shift_shift"
120  (const_string "unknown"))
121
122;; Main data type used by the insn
123(define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
124  (const_string "unknown"))
125
126;; True if the main data type is twice the size of a word.
127(define_attr "dword_mode" "no,yes"
128  (cond [(and (eq_attr "mode" "DI,DF")
129	      (eq (symbol_ref "TARGET_64BIT") (const_int 0)))
130	 (const_string "yes")
131
132	 (and (eq_attr "mode" "TI,TF")
133	      (ne (symbol_ref "TARGET_64BIT") (const_int 0)))
134	 (const_string "yes")]
135	(const_string "no")))
136
137;; Classification of each insn.
138;; branch	conditional branch
139;; jump		unconditional jump
140;; call		unconditional call
141;; load		load instruction(s)
142;; fpload	floating point load
143;; store	store instruction(s)
144;; fpstore	floating point store
145;; mtc		transfer to coprocessor
146;; mfc		transfer from coprocessor
147;; const	load constant
148;; arith	integer arithmetic instructions
149;; logical      integer logical instructions
150;; shift	integer shift instructions
151;; slt		set less than instructions
152;; imul		integer multiply
153;; idiv		integer divide
154;; move		integer register move (addi rd, rs1, 0)
155;; fmove	floating point register move
156;; fadd		floating point add/subtract
157;; fmul		floating point multiply
158;; fmadd	floating point multiply-add
159;; fdiv		floating point divide
160;; fcmp		floating point compare
161;; fcvt		floating point convert
162;; fsqrt	floating point square root
163;; multi	multiword sequence (or user asm statements)
164;; nop		no operation
165;; ghost	an instruction that produces no real code
166(define_attr "type"
167  "unknown,branch,jump,call,load,fpload,store,fpstore,
168   mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul,
169   fmadd,fdiv,fcmp,fcvt,fsqrt,multi,auipc,sfb_alu,nop,ghost"
170  (cond [(eq_attr "got" "load") (const_string "load")
171
172	 ;; If a doubleword move uses these expensive instructions,
173	 ;; it is usually better to schedule them in the same way
174	 ;; as the singleword form, rather than as "multi".
175	 (eq_attr "move_type" "load") (const_string "load")
176	 (eq_attr "move_type" "fpload") (const_string "fpload")
177	 (eq_attr "move_type" "store") (const_string "store")
178	 (eq_attr "move_type" "fpstore") (const_string "fpstore")
179	 (eq_attr "move_type" "mtc") (const_string "mtc")
180	 (eq_attr "move_type" "mfc") (const_string "mfc")
181
182	 ;; These types of move are always single insns.
183	 (eq_attr "move_type" "fmove") (const_string "fmove")
184	 (eq_attr "move_type" "arith") (const_string "arith")
185	 (eq_attr "move_type" "logical") (const_string "logical")
186	 (eq_attr "move_type" "andi") (const_string "logical")
187
188	 ;; These types of move are always split.
189	 (eq_attr "move_type" "shift_shift")
190	   (const_string "multi")
191
192	 ;; These types of move are split for doubleword modes only.
193	 (and (eq_attr "move_type" "move,const")
194	      (eq_attr "dword_mode" "yes"))
195	   (const_string "multi")
196	 (eq_attr "move_type" "move") (const_string "move")
197	 (eq_attr "move_type" "const") (const_string "const")]
198	(const_string "unknown")))
199
200;; Length of instruction in bytes.
201(define_attr "length" ""
202   (cond [
203	  ;; Branches further than +/- 4 KiB require two instructions.
204	  (eq_attr "type" "branch")
205	  (if_then_else (and (le (minus (match_dup 0) (pc)) (const_int 4088))
206				  (le (minus (pc) (match_dup 0)) (const_int 4092)))
207	  (const_int 4)
208	  (const_int 8))
209
210	  ;; Conservatively assume calls take two instructions (AUIPC + JALR).
211	  ;; The linker will opportunistically relax the sequence to JAL.
212	  (eq_attr "type" "call") (const_int 8)
213
214	  ;; "Ghost" instructions occupy no space.
215	  (eq_attr "type" "ghost") (const_int 0)
216
217	  (eq_attr "got" "load") (const_int 8)
218
219	  (eq_attr "type" "fcmp") (const_int 8)
220
221	  ;; SHIFT_SHIFTs are decomposed into two separate instructions.
222	  (eq_attr "move_type" "shift_shift")
223		(const_int 8)
224
225	  ;; Check for doubleword moves that are decomposed into two
226	  ;; instructions.
227	  (and (eq_attr "move_type" "mtc,mfc,move")
228	       (eq_attr "dword_mode" "yes"))
229	  (const_int 8)
230
231	  ;; Doubleword CONST{,N} moves are split into two word
232	  ;; CONST{,N} moves.
233	  (and (eq_attr "move_type" "const")
234	       (eq_attr "dword_mode" "yes"))
235	  (symbol_ref "riscv_split_const_insns (operands[1]) * 4")
236
237	  ;; Otherwise, constants, loads and stores are handled by external
238	  ;; routines.
239	  (eq_attr "move_type" "load,fpload")
240	  (symbol_ref "riscv_load_store_insns (operands[1], insn) * 4")
241	  (eq_attr "move_type" "store,fpstore")
242	  (symbol_ref "riscv_load_store_insns (operands[0], insn) * 4")
243	  ] (const_int 4)))
244
245;; Is copying of this instruction disallowed?
246(define_attr "cannot_copy" "no,yes" (const_string "no"))
247
248;; Microarchitectures we know how to tune for.
249;; Keep this in sync with enum riscv_microarchitecture.
250(define_attr "tune"
251  "generic,sifive_7"
252  (const (symbol_ref "((enum attr_tune) riscv_microarchitecture)")))
253
254;; Describe a user's asm statement.
255(define_asm_attributes
256  [(set_attr "type" "multi")])
257
258;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
259;; from the same template.
260(define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
261
262;; This mode iterator allows :P to be used for patterns that operate on
263;; pointer-sized quantities.  Exactly one of the two alternatives will match.
264(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
265
266;; Likewise, but for XLEN-sized quantities.
267(define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")])
268
269;; Branches operate on XLEN-sized quantities, but for RV64 we accept
270;; QImode values so we can force zero-extension.
271(define_mode_iterator BR [(QI "TARGET_64BIT") SI (DI "TARGET_64BIT")])
272
273;; 32-bit moves for which we provide move patterns.
274(define_mode_iterator MOVE32 [SI])
275
276;; 64-bit modes for which we provide move patterns.
277(define_mode_iterator MOVE64 [DI DF])
278
279;; Iterator for sub-32-bit integer modes.
280(define_mode_iterator SHORT [QI HI])
281
282;; Iterator for HImode constant generation.
283(define_mode_iterator HISI [HI SI])
284
285;; Iterator for QImode extension patterns.
286(define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")])
287
288;; Iterator for hardware integer modes narrower than XLEN.
289(define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")])
290
291;; Iterator for hardware-supported integer modes.
292(define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")])
293
294;; Iterator for hardware-supported floating-point modes.
295(define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
296			    (DF "TARGET_DOUBLE_FLOAT")])
297
298;; Iterator for floating-point modes that can be loaded into X registers.
299(define_mode_iterator SOFTF [SF (DF "TARGET_64BIT")])
300
301;; This attribute gives the length suffix for a sign- or zero-extension
302;; instruction.
303(define_mode_attr size [(QI "b") (HI "h")])
304
305;; Mode attributes for loads.
306(define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")])
307
308;; Instruction names for integer loads that aren't explicitly sign or zero
309;; extended.  See riscv_output_move and LOAD_EXTEND_OP.
310(define_mode_attr default_load [(QI "lbu") (HI "lhu") (SI "lw") (DI "ld")])
311
312;; Mode attribute for FP loads into integer registers.
313(define_mode_attr softload [(SF "lw") (DF "ld")])
314
315;; Instruction names for stores.
316(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")])
317
318;; Instruction names for FP stores from integer registers.
319(define_mode_attr softstore [(SF "sw") (DF "sd")])
320
321;; This attribute gives the best constraint to use for registers of
322;; a given mode.
323(define_mode_attr reg [(SI "d") (DI "d") (CC "d")])
324
325;; This attribute gives the format suffix for floating-point operations.
326(define_mode_attr fmt [(SF "s") (DF "d")])
327
328;; This attribute gives the integer suffix for floating-point conversions.
329(define_mode_attr ifmt [(SI "w") (DI "l")])
330
331;; This attribute gives the format suffix for atomic memory operations.
332(define_mode_attr amo [(SI "w") (DI "d")])
333
334;; This attribute gives the upper-case mode name for one unit of a
335;; floating-point mode.
336(define_mode_attr UNITMODE [(SF "SF") (DF "DF")])
337
338;; This attribute gives the integer mode that has half the size of
339;; the controlling mode.
340(define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
341
342;; Iterator and attributes for floating-point rounding instructions.
343(define_int_iterator RINT [UNSPEC_LRINT UNSPEC_LROUND])
344(define_int_attr rint_pattern [(UNSPEC_LRINT "rint") (UNSPEC_LROUND "round")])
345(define_int_attr rint_rm [(UNSPEC_LRINT "dyn") (UNSPEC_LROUND "rmm")])
346
347;; Iterator and attributes for quiet comparisons.
348(define_int_iterator QUIET_COMPARISON [UNSPEC_FLT_QUIET UNSPEC_FLE_QUIET])
349(define_int_attr quiet_pattern [(UNSPEC_FLT_QUIET "lt") (UNSPEC_FLE_QUIET "le")])
350
351;; This code iterator allows signed and unsigned widening multiplications
352;; to use the same template.
353(define_code_iterator any_extend [sign_extend zero_extend])
354
355;; This code iterator allows the two right shift instructions to be
356;; generated from the same template.
357(define_code_iterator any_shiftrt [ashiftrt lshiftrt])
358
359;; This code iterator allows the three shift instructions to be generated
360;; from the same template.
361(define_code_iterator any_shift [ashift ashiftrt lshiftrt])
362
363;; This code iterator allows the three bitwise instructions to be generated
364;; from the same template.
365(define_code_iterator any_bitwise [and ior xor])
366
367;; This code iterator allows unsigned and signed division to be generated
368;; from the same template.
369(define_code_iterator any_div [div udiv mod umod])
370
371;; This code iterator allows unsigned and signed modulus to be generated
372;; from the same template.
373(define_code_iterator any_mod [mod umod])
374
375;; These code iterators allow the signed and unsigned scc operations to use
376;; the same template.
377(define_code_iterator any_gt [gt gtu])
378(define_code_iterator any_ge [ge geu])
379(define_code_iterator any_lt [lt ltu])
380(define_code_iterator any_le [le leu])
381
382;; <u> expands to an empty string when doing a signed operation and
383;; "u" when doing an unsigned operation.
384(define_code_attr u [(sign_extend "") (zero_extend "u")
385		     (gt "") (gtu "u")
386		     (ge "") (geu "u")
387		     (lt "") (ltu "u")
388		     (le "") (leu "u")])
389
390;; <su> is like <u>, but the signed form expands to "s" rather than "".
391(define_code_attr su [(sign_extend "s") (zero_extend "u")])
392
393;; <optab> expands to the name of the optab for a particular code.
394(define_code_attr optab [(ashift "ashl")
395			 (ashiftrt "ashr")
396			 (lshiftrt "lshr")
397			 (div "div")
398			 (mod "mod")
399			 (udiv "udiv")
400			 (umod "umod")
401			 (ge "ge")
402			 (le "le")
403			 (gt "gt")
404			 (lt "lt")
405			 (ior "ior")
406			 (xor "xor")
407			 (and "and")
408			 (plus "add")
409			 (minus "sub")])
410
411;; <insn> expands to the name of the insn that implements a particular code.
412(define_code_attr insn [(ashift "sll")
413			(ashiftrt "sra")
414			(lshiftrt "srl")
415			(div "div")
416			(mod "rem")
417			(udiv "divu")
418			(umod "remu")
419			(ior "or")
420			(xor "xor")
421			(and "and")
422			(plus "add")
423			(minus "sub")])
424
425;; Ghost instructions produce no real code and introduce no hazards.
426;; They exist purely to express an effect on dataflow.
427(define_insn_reservation "ghost" 0
428  (eq_attr "type" "ghost")
429  "nothing")
430
431;;
432;;  ....................
433;;
434;;	ADDITION
435;;
436;;  ....................
437;;
438
439(define_insn "add<mode>3"
440  [(set (match_operand:ANYF            0 "register_operand" "=f")
441	(plus:ANYF (match_operand:ANYF 1 "register_operand" " f")
442		   (match_operand:ANYF 2 "register_operand" " f")))]
443  "TARGET_HARD_FLOAT"
444  "fadd.<fmt>\t%0,%1,%2"
445  [(set_attr "type" "fadd")
446   (set_attr "mode" "<UNITMODE>")])
447
448(define_insn "addsi3"
449  [(set (match_operand:SI          0 "register_operand" "=r,r")
450	(plus:SI (match_operand:SI 1 "register_operand" " r,r")
451		 (match_operand:SI 2 "arith_operand"    " r,I")))]
452  ""
453  { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
454  [(set_attr "type" "arith")
455   (set_attr "mode" "SI")])
456
457(define_insn "adddi3"
458  [(set (match_operand:DI          0 "register_operand" "=r,r")
459	(plus:DI (match_operand:DI 1 "register_operand" " r,r")
460		 (match_operand:DI 2 "arith_operand"    " r,I")))]
461  "TARGET_64BIT"
462  "add%i2\t%0,%1,%2"
463  [(set_attr "type" "arith")
464   (set_attr "mode" "DI")])
465
466(define_insn "*addsi3_extended"
467  [(set (match_operand:DI               0 "register_operand" "=r,r")
468	(sign_extend:DI
469	     (plus:SI (match_operand:SI 1 "register_operand" " r,r")
470		      (match_operand:SI 2 "arith_operand"    " r,I"))))]
471  "TARGET_64BIT"
472  "add%i2w\t%0,%1,%2"
473  [(set_attr "type" "arith")
474   (set_attr "mode" "SI")])
475
476(define_insn "*addsi3_extended2"
477  [(set (match_operand:DI                       0 "register_operand" "=r,r")
478	(sign_extend:DI
479	  (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" " r,r")
480			      (match_operand:DI 2 "arith_operand"    " r,I"))
481		     0)))]
482  "TARGET_64BIT"
483  "add%i2w\t%0,%1,%2"
484  [(set_attr "type" "arith")
485   (set_attr "mode" "SI")])
486
487;;
488;;  ....................
489;;
490;;	SUBTRACTION
491;;
492;;  ....................
493;;
494
495(define_insn "sub<mode>3"
496  [(set (match_operand:ANYF             0 "register_operand" "=f")
497	(minus:ANYF (match_operand:ANYF 1 "register_operand" " f")
498		    (match_operand:ANYF 2 "register_operand" " f")))]
499  "TARGET_HARD_FLOAT"
500  "fsub.<fmt>\t%0,%1,%2"
501  [(set_attr "type" "fadd")
502   (set_attr "mode" "<UNITMODE>")])
503
504(define_insn "subdi3"
505  [(set (match_operand:DI 0            "register_operand" "= r")
506	(minus:DI (match_operand:DI 1  "reg_or_0_operand" " rJ")
507		   (match_operand:DI 2 "register_operand" "  r")))]
508  "TARGET_64BIT"
509  "sub\t%0,%z1,%2"
510  [(set_attr "type" "arith")
511   (set_attr "mode" "DI")])
512
513(define_insn "subsi3"
514  [(set (match_operand:SI           0 "register_operand" "= r")
515	(minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
516		  (match_operand:SI 2 "register_operand" "  r")))]
517  ""
518  { return TARGET_64BIT ? "subw\t%0,%z1,%2" : "sub\t%0,%z1,%2"; }
519  [(set_attr "type" "arith")
520   (set_attr "mode" "SI")])
521
522(define_insn "*subsi3_extended"
523  [(set (match_operand:DI               0 "register_operand" "= r")
524	(sign_extend:DI
525	    (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ")
526		      (match_operand:SI 2 "register_operand" "  r"))))]
527  "TARGET_64BIT"
528  "subw\t%0,%z1,%2"
529  [(set_attr "type" "arith")
530   (set_attr "mode" "SI")])
531
532(define_insn "*subsi3_extended2"
533  [(set (match_operand:DI                        0 "register_operand" "= r")
534	(sign_extend:DI
535	  (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" " rJ")
536			       (match_operand:DI 2 "register_operand" "  r"))
537		     0)))]
538  "TARGET_64BIT"
539  "subw\t%0,%z1,%2"
540  [(set_attr "type" "arith")
541   (set_attr "mode" "SI")])
542
543(define_insn "negdi2"
544  [(set (match_operand:DI         0 "register_operand" "=r")
545	(neg:DI (match_operand:DI 1 "register_operand" " r")))]
546  "TARGET_64BIT"
547  "neg\t%0,%1"
548  [(set_attr "type" "arith")
549   (set_attr "mode" "DI")])
550
551(define_insn "negsi2"
552  [(set (match_operand:SI         0 "register_operand" "=r")
553	(neg:SI (match_operand:SI 1 "register_operand" " r")))]
554  ""
555  { return TARGET_64BIT ? "negw\t%0,%1" : "neg\t%0,%1"; }
556  [(set_attr "type" "arith")
557   (set_attr "mode" "SI")])
558
559(define_insn "*negsi2_extended"
560  [(set (match_operand:DI          0 "register_operand" "=r")
561	(sign_extend:DI
562	 (neg:SI (match_operand:SI 1 "register_operand" " r"))))]
563  "TARGET_64BIT"
564  "negw\t%0,%1"
565  [(set_attr "type" "arith")
566   (set_attr "mode" "SI")])
567
568(define_insn "*negsi2_extended2"
569  [(set (match_operand:DI                     0 "register_operand" "=r")
570	(sign_extend:DI
571	 (subreg:SI (neg:DI (match_operand:DI 1 "register_operand" " r"))
572	 	    0)))]
573  "TARGET_64BIT"
574  "negw\t%0,%1"
575  [(set_attr "type" "arith")
576   (set_attr "mode" "SI")])
577
578;;
579;;  ....................
580;;
581;;	MULTIPLICATION
582;;
583;;  ....................
584;;
585
586(define_insn "mul<mode>3"
587  [(set (match_operand:ANYF               0 "register_operand" "=f")
588	(mult:ANYF (match_operand:ANYF    1 "register_operand" " f")
589		      (match_operand:ANYF 2 "register_operand" " f")))]
590  "TARGET_HARD_FLOAT"
591  "fmul.<fmt>\t%0,%1,%2"
592  [(set_attr "type" "fmul")
593   (set_attr "mode" "<UNITMODE>")])
594
595(define_insn "mulsi3"
596  [(set (match_operand:SI          0 "register_operand" "=r")
597	(mult:SI (match_operand:SI 1 "register_operand" " r")
598		 (match_operand:SI 2 "register_operand" " r")))]
599  "TARGET_MUL"
600  { return TARGET_64BIT ? "mulw\t%0,%1,%2" : "mul\t%0,%1,%2"; }
601  [(set_attr "type" "imul")
602   (set_attr "mode" "SI")])
603
604(define_insn "muldi3"
605  [(set (match_operand:DI          0 "register_operand" "=r")
606	(mult:DI (match_operand:DI 1 "register_operand" " r")
607		 (match_operand:DI 2 "register_operand" " r")))]
608  "TARGET_MUL && TARGET_64BIT"
609  "mul\t%0,%1,%2"
610  [(set_attr "type" "imul")
611   (set_attr "mode" "DI")])
612
613(define_insn "*mulsi3_extended"
614  [(set (match_operand:DI              0 "register_operand" "=r")
615	(sign_extend:DI
616	    (mult:SI (match_operand:SI 1 "register_operand" " r")
617		     (match_operand:SI 2 "register_operand" " r"))))]
618  "TARGET_MUL && TARGET_64BIT"
619  "mulw\t%0,%1,%2"
620  [(set_attr "type" "imul")
621   (set_attr "mode" "SI")])
622
623(define_insn "*mulsi3_extended2"
624  [(set (match_operand:DI                       0 "register_operand" "=r")
625	(sign_extend:DI
626	  (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" " r")
627			      (match_operand:DI 2 "register_operand" " r"))
628		     0)))]
629  "TARGET_MUL && TARGET_64BIT"
630  "mulw\t%0,%1,%2"
631  [(set_attr "type" "imul")
632   (set_attr "mode" "SI")])
633
634;;
635;;  ........................
636;;
637;;	MULTIPLICATION HIGH-PART
638;;
639;;  ........................
640;;
641
642
643(define_expand "<u>mulditi3"
644  [(set (match_operand:TI                         0 "register_operand")
645	(mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
646		 (any_extend:TI (match_operand:DI 2 "register_operand"))))]
647  "TARGET_MUL && TARGET_64BIT"
648{
649  rtx low = gen_reg_rtx (DImode);
650  emit_insn (gen_muldi3 (low, operands[1], operands[2]));
651
652  rtx high = gen_reg_rtx (DImode);
653  emit_insn (gen_<u>muldi3_highpart (high, operands[1], operands[2]));
654
655  emit_move_insn (gen_lowpart (DImode, operands[0]), low);
656  emit_move_insn (gen_highpart (DImode, operands[0]), high);
657  DONE;
658})
659
660(define_insn "<u>muldi3_highpart"
661  [(set (match_operand:DI                0 "register_operand" "=r")
662	(truncate:DI
663	  (lshiftrt:TI
664	    (mult:TI (any_extend:TI
665		       (match_operand:DI 1 "register_operand" " r"))
666		     (any_extend:TI
667		       (match_operand:DI 2 "register_operand" " r")))
668	    (const_int 64))))]
669  "TARGET_MUL && TARGET_64BIT"
670  "mulh<u>\t%0,%1,%2"
671  [(set_attr "type" "imul")
672   (set_attr "mode" "DI")])
673
674(define_expand "usmulditi3"
675  [(set (match_operand:TI                          0 "register_operand")
676	(mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand"))
677		 (sign_extend:TI (match_operand:DI 2 "register_operand"))))]
678  "TARGET_MUL && TARGET_64BIT"
679{
680  rtx low = gen_reg_rtx (DImode);
681  emit_insn (gen_muldi3 (low, operands[1], operands[2]));
682
683  rtx high = gen_reg_rtx (DImode);
684  emit_insn (gen_usmuldi3_highpart (high, operands[1], operands[2]));
685
686  emit_move_insn (gen_lowpart (DImode, operands[0]), low);
687  emit_move_insn (gen_highpart (DImode, operands[0]), high);
688  DONE;
689})
690
691(define_insn "usmuldi3_highpart"
692  [(set (match_operand:DI                0 "register_operand" "=r")
693	(truncate:DI
694	  (lshiftrt:TI
695	    (mult:TI (zero_extend:TI
696		       (match_operand:DI 1 "register_operand"  "r"))
697		     (sign_extend:TI
698		       (match_operand:DI 2 "register_operand" " r")))
699	    (const_int 64))))]
700  "TARGET_MUL && TARGET_64BIT"
701  "mulhsu\t%0,%2,%1"
702  [(set_attr "type" "imul")
703   (set_attr "mode" "DI")])
704
705(define_expand "<u>mulsidi3"
706  [(set (match_operand:DI            0 "register_operand" "=r")
707	(mult:DI (any_extend:DI
708		   (match_operand:SI 1 "register_operand" " r"))
709		 (any_extend:DI
710		   (match_operand:SI 2 "register_operand" " r"))))]
711  "TARGET_MUL && !TARGET_64BIT"
712{
713  rtx temp = gen_reg_rtx (SImode);
714  emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
715  emit_insn (gen_<u>mulsi3_highpart (riscv_subword (operands[0], true),
716				     operands[1], operands[2]));
717  emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
718  DONE;
719})
720
721(define_insn "<u>mulsi3_highpart"
722  [(set (match_operand:SI                0 "register_operand" "=r")
723	(truncate:SI
724	  (lshiftrt:DI
725	    (mult:DI (any_extend:DI
726		       (match_operand:SI 1 "register_operand" " r"))
727		     (any_extend:DI
728		       (match_operand:SI 2 "register_operand" " r")))
729	    (const_int 32))))]
730  "TARGET_MUL && !TARGET_64BIT"
731  "mulh<u>\t%0,%1,%2"
732  [(set_attr "type" "imul")
733   (set_attr "mode" "SI")])
734
735
736(define_expand "usmulsidi3"
737  [(set (match_operand:DI            0 "register_operand" "=r")
738	(mult:DI (zero_extend:DI
739		   (match_operand:SI 1 "register_operand" " r"))
740		 (sign_extend:DI
741		   (match_operand:SI 2 "register_operand" " r"))))]
742  "TARGET_MUL && !TARGET_64BIT"
743{
744  rtx temp = gen_reg_rtx (SImode);
745  emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
746  emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true),
747				     operands[1], operands[2]));
748  emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
749  DONE;
750})
751
752(define_insn "usmulsi3_highpart"
753  [(set (match_operand:SI                0 "register_operand" "=r")
754	(truncate:SI
755	  (lshiftrt:DI
756	    (mult:DI (zero_extend:DI
757		       (match_operand:SI 1 "register_operand" " r"))
758		     (sign_extend:DI
759		       (match_operand:SI 2 "register_operand" " r")))
760	    (const_int 32))))]
761  "TARGET_MUL && !TARGET_64BIT"
762  "mulhsu\t%0,%2,%1"
763  [(set_attr "type" "imul")
764   (set_attr "mode" "SI")])
765
766;;
767;;  ....................
768;;
769;;	DIVISION and REMAINDER
770;;
771;;  ....................
772;;
773
774(define_insn "<optab>si3"
775  [(set (match_operand:SI             0 "register_operand" "=r")
776	(any_div:SI (match_operand:SI 1 "register_operand" " r")
777		    (match_operand:SI 2 "register_operand" " r")))]
778  "TARGET_DIV"
779  { return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2"; }
780  [(set_attr "type" "idiv")
781   (set_attr "mode" "SI")])
782
783(define_insn "<optab>di3"
784  [(set (match_operand:DI             0 "register_operand" "=r")
785	(any_div:DI (match_operand:DI 1 "register_operand" " r")
786		    (match_operand:DI 2 "register_operand" " r")))]
787  "TARGET_DIV && TARGET_64BIT"
788  "<insn>%i2\t%0,%1,%2"
789  [(set_attr "type" "idiv")
790   (set_attr "mode" "DI")])
791
792(define_insn "*<optab>si3_extended"
793  [(set (match_operand:DI                 0 "register_operand" "=r")
794	(sign_extend:DI
795	    (any_div:SI (match_operand:SI 1 "register_operand" " r")
796			(match_operand:SI 2 "register_operand" " r"))))]
797  "TARGET_DIV && TARGET_64BIT"
798  "<insn>%i2w\t%0,%1,%2"
799  [(set_attr "type" "idiv")
800   (set_attr "mode" "DI")])
801
802(define_insn "div<mode>3"
803  [(set (match_operand:ANYF           0 "register_operand" "=f")
804	(div:ANYF (match_operand:ANYF 1 "register_operand" " f")
805		  (match_operand:ANYF 2 "register_operand" " f")))]
806  "TARGET_HARD_FLOAT && TARGET_FDIV"
807  "fdiv.<fmt>\t%0,%1,%2"
808  [(set_attr "type" "fdiv")
809   (set_attr "mode" "<UNITMODE>")])
810
811;;
812;;  ....................
813;;
814;;	SQUARE ROOT
815;;
816;;  ....................
817
818(define_insn "sqrt<mode>2"
819  [(set (match_operand:ANYF            0 "register_operand" "=f")
820	(sqrt:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
821  "TARGET_HARD_FLOAT && TARGET_FDIV"
822{
823    return "fsqrt.<fmt>\t%0,%1";
824}
825  [(set_attr "type" "fsqrt")
826   (set_attr "mode" "<UNITMODE>")])
827
828;; Floating point multiply accumulate instructions.
829
830;; a * b + c
831(define_insn "fma<mode>4"
832  [(set (match_operand:ANYF           0 "register_operand" "=f")
833	(fma: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"
837  "fmadd.<fmt>\t%0,%1,%2,%3"
838  [(set_attr "type" "fmadd")
839   (set_attr "mode" "<UNITMODE>")])
840
841;; a * b - c
842(define_insn "fms<mode>4"
843  [(set (match_operand:ANYF                     0 "register_operand" "=f")
844	(fma:ANYF (match_operand:ANYF           1 "register_operand" " f")
845		  (match_operand:ANYF           2 "register_operand" " f")
846		  (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
847  "TARGET_HARD_FLOAT"
848  "fmsub.<fmt>\t%0,%1,%2,%3"
849  [(set_attr "type" "fmadd")
850   (set_attr "mode" "<UNITMODE>")])
851
852;; -a * b - c
853(define_insn "fnms<mode>4"
854  [(set (match_operand:ANYF               0 "register_operand" "=f")
855	(fma:ANYF
856	    (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
857	    (match_operand:ANYF           2 "register_operand" " f")
858	    (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))]
859  "TARGET_HARD_FLOAT"
860  "fnmadd.<fmt>\t%0,%1,%2,%3"
861  [(set_attr "type" "fmadd")
862   (set_attr "mode" "<UNITMODE>")])
863
864;; -a * b + c
865(define_insn "fnma<mode>4"
866  [(set (match_operand:ANYF               0 "register_operand" "=f")
867	(fma:ANYF
868	    (neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
869	    (match_operand:ANYF           2 "register_operand" " f")
870	    (match_operand:ANYF           3 "register_operand" " f")))]
871  "TARGET_HARD_FLOAT"
872  "fnmsub.<fmt>\t%0,%1,%2,%3"
873  [(set_attr "type" "fmadd")
874   (set_attr "mode" "<UNITMODE>")])
875
876;; -(-a * b - c), modulo signed zeros
877(define_insn "*fma<mode>4"
878  [(set (match_operand:ANYF                   0 "register_operand" "=f")
879	(neg:ANYF
880	    (fma:ANYF
881		(neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
882		(match_operand:ANYF           2 "register_operand" " f")
883		(neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
884  "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
885  "fmadd.<fmt>\t%0,%1,%2,%3"
886  [(set_attr "type" "fmadd")
887   (set_attr "mode" "<UNITMODE>")])
888
889;; -(-a * b + c), modulo signed zeros
890(define_insn "*fms<mode>4"
891  [(set (match_operand:ANYF                   0 "register_operand" "=f")
892	(neg:ANYF
893	    (fma:ANYF
894		(neg:ANYF (match_operand:ANYF 1 "register_operand" " f"))
895		(match_operand:ANYF           2 "register_operand" " f")
896		(match_operand:ANYF           3 "register_operand" " f"))))]
897  "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
898  "fmsub.<fmt>\t%0,%1,%2,%3"
899  [(set_attr "type" "fmadd")
900   (set_attr "mode" "<UNITMODE>")])
901
902;; -(a * b + c), modulo signed zeros
903(define_insn "*fnms<mode>4"
904  [(set (match_operand:ANYF         0 "register_operand" "=f")
905	(neg:ANYF
906	    (fma:ANYF
907		(match_operand:ANYF 1 "register_operand" " f")
908		(match_operand:ANYF 2 "register_operand" " f")
909		(match_operand:ANYF 3 "register_operand" " f"))))]
910  "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
911  "fnmadd.<fmt>\t%0,%1,%2,%3"
912  [(set_attr "type" "fmadd")
913   (set_attr "mode" "<UNITMODE>")])
914
915;; -(a * b - c), modulo signed zeros
916(define_insn "*fnma<mode>4"
917  [(set (match_operand:ANYF                   0 "register_operand" "=f")
918	(neg:ANYF
919	    (fma:ANYF
920		(match_operand:ANYF           1 "register_operand" " f")
921		(match_operand:ANYF           2 "register_operand" " f")
922		(neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))]
923  "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
924  "fnmsub.<fmt>\t%0,%1,%2,%3"
925  [(set_attr "type" "fmadd")
926   (set_attr "mode" "<UNITMODE>")])
927
928;;
929;;  ....................
930;;
931;;	SIGN INJECTION
932;;
933;;  ....................
934
935(define_insn "abs<mode>2"
936  [(set (match_operand:ANYF           0 "register_operand" "=f")
937	(abs:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
938  "TARGET_HARD_FLOAT"
939  "fabs.<fmt>\t%0,%1"
940  [(set_attr "type" "fmove")
941   (set_attr "mode" "<UNITMODE>")])
942
943(define_insn "copysign<mode>3"
944  [(set (match_operand:ANYF 0 "register_operand"               "=f")
945	(unspec:ANYF [(match_operand:ANYF 1 "register_operand" " f")
946		      (match_operand:ANYF 2 "register_operand" " f")]
947		     UNSPEC_COPYSIGN))]
948  "TARGET_HARD_FLOAT"
949  "fsgnj.<fmt>\t%0,%1,%2"
950  [(set_attr "type" "fmove")
951   (set_attr "mode" "<UNITMODE>")])
952
953(define_insn "neg<mode>2"
954  [(set (match_operand:ANYF           0 "register_operand" "=f")
955	(neg:ANYF (match_operand:ANYF 1 "register_operand" " f")))]
956  "TARGET_HARD_FLOAT"
957  "fneg.<fmt>\t%0,%1"
958  [(set_attr "type" "fmove")
959   (set_attr "mode" "<UNITMODE>")])
960
961;;
962;;  ....................
963;;
964;;	MIN/MAX
965;;
966;;  ....................
967
968(define_insn "smin<mode>3"
969  [(set (match_operand:ANYF            0 "register_operand" "=f")
970	(smin:ANYF (match_operand:ANYF 1 "register_operand" " f")
971		   (match_operand:ANYF 2 "register_operand" " f")))]
972  "TARGET_HARD_FLOAT"
973  "fmin.<fmt>\t%0,%1,%2"
974  [(set_attr "type" "fmove")
975   (set_attr "mode" "<UNITMODE>")])
976
977(define_insn "smax<mode>3"
978  [(set (match_operand:ANYF            0 "register_operand" "=f")
979	(smax:ANYF (match_operand:ANYF 1 "register_operand" " f")
980		   (match_operand:ANYF 2 "register_operand" " f")))]
981  "TARGET_HARD_FLOAT"
982  "fmax.<fmt>\t%0,%1,%2"
983  [(set_attr "type" "fmove")
984   (set_attr "mode" "<UNITMODE>")])
985
986;;
987;;  ....................
988;;
989;;	LOGICAL
990;;
991;;  ....................
992;;
993
994;; For RV64, we don't expose the SImode operations to the rtl expanders,
995;; but SImode versions exist for combine.
996
997(define_insn "<optab><mode>3"
998  [(set (match_operand:X                0 "register_operand" "=r,r")
999	(any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
1000		       (match_operand:X 2 "arith_operand"    " r,I")))]
1001  ""
1002  "<insn>%i2\t%0,%1,%2"
1003  [(set_attr "type" "logical")
1004   (set_attr "mode" "<MODE>")])
1005
1006(define_insn "*<optab>si3_internal"
1007  [(set (match_operand:SI                 0 "register_operand" "=r,r")
1008	(any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r")
1009			(match_operand:SI 2 "arith_operand"    " r,I")))]
1010  "TARGET_64BIT"
1011  "<insn>%i2\t%0,%1,%2"
1012  [(set_attr "type" "logical")
1013   (set_attr "mode" "SI")])
1014
1015(define_insn "one_cmpl<mode>2"
1016  [(set (match_operand:X        0 "register_operand" "=r")
1017	(not:X (match_operand:X 1 "register_operand" " r")))]
1018  ""
1019  "not\t%0,%1"
1020  [(set_attr "type" "logical")
1021   (set_attr "mode" "<MODE>")])
1022
1023(define_insn "*one_cmplsi2_internal"
1024  [(set (match_operand:SI         0 "register_operand" "=r")
1025	(not:SI (match_operand:SI 1 "register_operand" " r")))]
1026  "TARGET_64BIT"
1027  "not\t%0,%1"
1028  [(set_attr "type" "logical")
1029   (set_attr "mode" "SI")])
1030
1031;;
1032;;  ....................
1033;;
1034;;	TRUNCATION
1035;;
1036;;  ....................
1037
1038(define_insn "truncdfsf2"
1039  [(set (match_operand:SF     0 "register_operand" "=f")
1040	(float_truncate:SF
1041	    (match_operand:DF 1 "register_operand" " f")))]
1042  "TARGET_DOUBLE_FLOAT"
1043  "fcvt.s.d\t%0,%1"
1044  [(set_attr "type" "fcvt")
1045   (set_attr "mode" "SF")])
1046
1047;;
1048;;  ....................
1049;;
1050;;	ZERO EXTENSION
1051;;
1052;;  ....................
1053
1054;; Extension insns.
1055
1056(define_insn_and_split "zero_extendsidi2"
1057  [(set (match_operand:DI     0 "register_operand"     "=r,r")
1058	(zero_extend:DI
1059	    (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
1060  "TARGET_64BIT"
1061  "@
1062   #
1063   lwu\t%0,%1"
1064  "&& reload_completed
1065   && REG_P (operands[1])
1066   && !paradoxical_subreg_p (operands[0])"
1067  [(set (match_dup 0)
1068	(ashift:DI (match_dup 1) (const_int 32)))
1069   (set (match_dup 0)
1070	(lshiftrt:DI (match_dup 0) (const_int 32)))]
1071  { operands[1] = gen_lowpart (DImode, operands[1]); }
1072  [(set_attr "move_type" "shift_shift,load")
1073   (set_attr "mode" "DI")])
1074
1075(define_insn_and_split "zero_extendhi<GPR:mode>2"
1076  [(set (match_operand:GPR    0 "register_operand"     "=r,r")
1077	(zero_extend:GPR
1078	    (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
1079  ""
1080  "@
1081   #
1082   lhu\t%0,%1"
1083  "&& reload_completed
1084   && REG_P (operands[1])
1085   && !paradoxical_subreg_p (operands[0])"
1086  [(set (match_dup 0)
1087	(ashift:GPR (match_dup 1) (match_dup 2)))
1088   (set (match_dup 0)
1089	(lshiftrt:GPR (match_dup 0) (match_dup 2)))]
1090  {
1091    operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
1092    operands[2] = GEN_INT(GET_MODE_BITSIZE(<GPR:MODE>mode) - 16);
1093  }
1094  [(set_attr "move_type" "shift_shift,load")
1095   (set_attr "mode" "<GPR:MODE>")])
1096
1097(define_insn "zero_extendqi<SUPERQI:mode>2"
1098  [(set (match_operand:SUPERQI 0 "register_operand"    "=r,r")
1099	(zero_extend:SUPERQI
1100	    (match_operand:QI 1 "nonimmediate_operand" " r,m")))]
1101  ""
1102  "@
1103   andi\t%0,%1,0xff
1104   lbu\t%0,%1"
1105  [(set_attr "move_type" "andi,load")
1106   (set_attr "mode" "<SUPERQI:MODE>")])
1107
1108;;
1109;;  ....................
1110;;
1111;;	SIGN EXTENSION
1112;;
1113;;  ....................
1114
1115(define_insn "extendsidi2"
1116  [(set (match_operand:DI     0 "register_operand"     "=r,r")
1117	(sign_extend:DI
1118	    (match_operand:SI 1 "nonimmediate_operand" " r,m")))]
1119  "TARGET_64BIT"
1120  "@
1121   sext.w\t%0,%1
1122   lw\t%0,%1"
1123  [(set_attr "move_type" "move,load")
1124   (set_attr "mode" "DI")])
1125
1126(define_insn_and_split "extend<SHORT:mode><SUPERQI:mode>2"
1127  [(set (match_operand:SUPERQI   0 "register_operand"     "=r,r")
1128	(sign_extend:SUPERQI
1129	    (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
1130  ""
1131  "@
1132   #
1133   l<SHORT:size>\t%0,%1"
1134  "&& reload_completed
1135   && REG_P (operands[1])
1136   && !paradoxical_subreg_p (operands[0])"
1137  [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1138   (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
1139{
1140  operands[0] = gen_lowpart (SImode, operands[0]);
1141  operands[1] = gen_lowpart (SImode, operands[1]);
1142  operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
1143			 - GET_MODE_BITSIZE (<SHORT:MODE>mode));
1144}
1145  [(set_attr "move_type" "shift_shift,load")
1146   (set_attr "mode" "SI")])
1147
1148(define_insn "extendsfdf2"
1149  [(set (match_operand:DF     0 "register_operand" "=f")
1150	(float_extend:DF
1151	    (match_operand:SF 1 "register_operand" " f")))]
1152  "TARGET_DOUBLE_FLOAT"
1153  "fcvt.d.s\t%0,%1"
1154  [(set_attr "type" "fcvt")
1155   (set_attr "mode" "DF")])
1156
1157;;
1158;;  ....................
1159;;
1160;;	CONVERSIONS
1161;;
1162;;  ....................
1163
1164(define_insn "fix_trunc<ANYF:mode><GPR:mode>2"
1165  [(set (match_operand:GPR      0 "register_operand" "=r")
1166	(fix:GPR
1167	    (match_operand:ANYF 1 "register_operand" " f")))]
1168  "TARGET_HARD_FLOAT"
1169  "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,rtz"
1170  [(set_attr "type" "fcvt")
1171   (set_attr "mode" "<ANYF:MODE>")])
1172
1173(define_insn "fixuns_trunc<ANYF:mode><GPR:mode>2"
1174  [(set (match_operand:GPR      0 "register_operand" "=r")
1175	(unsigned_fix:GPR
1176	    (match_operand:ANYF 1 "register_operand" " f")))]
1177  "TARGET_HARD_FLOAT"
1178  "fcvt.<GPR:ifmt>u.<ANYF:fmt> %0,%1,rtz"
1179  [(set_attr "type" "fcvt")
1180   (set_attr "mode" "<ANYF:MODE>")])
1181
1182(define_insn "float<GPR:mode><ANYF:mode>2"
1183  [(set (match_operand:ANYF    0 "register_operand" "= f")
1184	(float:ANYF
1185	    (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1186  "TARGET_HARD_FLOAT"
1187  "fcvt.<ANYF:fmt>.<GPR:ifmt>\t%0,%z1"
1188  [(set_attr "type" "fcvt")
1189   (set_attr "mode" "<ANYF:MODE>")])
1190
1191(define_insn "floatuns<GPR:mode><ANYF:mode>2"
1192  [(set (match_operand:ANYF    0 "register_operand" "= f")
1193	(unsigned_float:ANYF
1194	    (match_operand:GPR 1 "reg_or_0_operand" " rJ")))]
1195  "TARGET_HARD_FLOAT"
1196  "fcvt.<ANYF:fmt>.<GPR:ifmt>u\t%0,%z1"
1197  [(set_attr "type" "fcvt")
1198   (set_attr "mode" "<ANYF:MODE>")])
1199
1200(define_insn "l<rint_pattern><ANYF:mode><GPR:mode>2"
1201  [(set (match_operand:GPR       0 "register_operand" "=r")
1202	(unspec:GPR
1203	    [(match_operand:ANYF 1 "register_operand" " f")]
1204	    RINT))]
1205  "TARGET_HARD_FLOAT"
1206  "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,<rint_rm>"
1207  [(set_attr "type" "fcvt")
1208   (set_attr "mode" "<ANYF:MODE>")])
1209
1210;;
1211;;  ....................
1212;;
1213;;	DATA MOVEMENT
1214;;
1215;;  ....................
1216
1217;; Lower-level instructions for loading an address from the GOT.
1218;; We could use MEMs, but an unspec gives more optimization
1219;; opportunities.
1220
1221(define_insn "got_load<mode>"
1222   [(set (match_operand:P      0 "register_operand" "=r")
1223	 (unspec:P
1224	     [(match_operand:P 1 "symbolic_operand" "")]
1225	     UNSPEC_LOAD_GOT))]
1226  ""
1227  "la\t%0,%1"
1228   [(set_attr "got" "load")
1229    (set_attr "mode" "<MODE>")])
1230
1231(define_insn "tls_add_tp_le<mode>"
1232  [(set (match_operand:P      0 "register_operand" "=r")
1233	(unspec:P
1234	    [(match_operand:P 1 "register_operand" "r")
1235	     (match_operand:P 2 "register_operand" "r")
1236	     (match_operand:P 3 "symbolic_operand" "")]
1237	    UNSPEC_TLS_LE))]
1238  ""
1239  "add\t%0,%1,%2,%%tprel_add(%3)"
1240  [(set_attr "type" "arith")
1241   (set_attr "mode" "<MODE>")])
1242
1243(define_insn "got_load_tls_gd<mode>"
1244  [(set (match_operand:P      0 "register_operand" "=r")
1245	(unspec:P
1246	    [(match_operand:P 1 "symbolic_operand" "")]
1247	    UNSPEC_TLS_GD))]
1248  ""
1249  "la.tls.gd\t%0,%1"
1250  [(set_attr "got" "load")
1251   (set_attr "mode" "<MODE>")])
1252
1253(define_insn "got_load_tls_ie<mode>"
1254  [(set (match_operand:P      0 "register_operand" "=r")
1255	(unspec:P
1256	    [(match_operand:P 1 "symbolic_operand" "")]
1257	    UNSPEC_TLS_IE))]
1258  ""
1259  "la.tls.ie\t%0,%1"
1260  [(set_attr "got" "load")
1261   (set_attr "mode" "<MODE>")])
1262
1263(define_insn "auipc<mode>"
1264  [(set (match_operand:P           0 "register_operand" "=r")
1265	(unspec:P
1266	    [(match_operand:P      1 "symbolic_operand" "")
1267		  (match_operand:P 2 "const_int_operand")
1268		  (pc)]
1269	    UNSPEC_AUIPC))]
1270  ""
1271  ".LA%2: auipc\t%0,%h1"
1272  [(set_attr "type" "auipc")
1273   (set_attr "cannot_copy" "yes")])
1274
1275;; Instructions for adding the low 12 bits of an address to a register.
1276;; Operand 2 is the address: riscv_print_operand works out which relocation
1277;; should be applied.
1278
1279(define_insn "*low<mode>"
1280  [(set (match_operand:P           0 "register_operand" "=r")
1281	(lo_sum:P (match_operand:P 1 "register_operand" " r")
1282		  (match_operand:P 2 "symbolic_operand" "")))]
1283  ""
1284  "addi\t%0,%1,%R2"
1285  [(set_attr "type" "arith")
1286   (set_attr "mode" "<MODE>")])
1287
1288;; Allow combine to split complex const_int load sequences, using operand 2
1289;; to store the intermediate results.  See move_operand for details.
1290(define_split
1291  [(set (match_operand:GPR 0 "register_operand")
1292	(match_operand:GPR 1 "splittable_const_int_operand"))
1293   (clobber (match_operand:GPR 2 "register_operand"))]
1294  ""
1295  [(const_int 0)]
1296{
1297  riscv_move_integer (operands[2], operands[0], INTVAL (operands[1]),
1298		      <GPR:MODE>mode, TRUE);
1299  DONE;
1300})
1301
1302;; Likewise, for symbolic operands.
1303(define_split
1304  [(set (match_operand:P 0 "register_operand")
1305	(match_operand:P 1))
1306   (clobber (match_operand:P 2 "register_operand"))]
1307  "riscv_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL, TRUE)"
1308  [(set (match_dup 0) (match_dup 3))]
1309{
1310  riscv_split_symbol (operands[2], operands[1],
1311		      MAX_MACHINE_MODE, &operands[3], TRUE);
1312})
1313
1314;; 64-bit integer moves
1315
1316(define_expand "movdi"
1317  [(set (match_operand:DI 0 "")
1318	(match_operand:DI 1 ""))]
1319  ""
1320{
1321  if (riscv_legitimize_move (DImode, operands[0], operands[1]))
1322    DONE;
1323})
1324
1325(define_insn "*movdi_32bit"
1326  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,  *f,*f,*r,*f,*m")
1327	(match_operand:DI 1 "move_operand"         " r,i,m,r,*J*r,*m,*f,*f,*f"))]
1328  "!TARGET_64BIT
1329   && (register_operand (operands[0], DImode)
1330       || reg_or_0_operand (operands[1], DImode))"
1331  { return riscv_output_move (operands[0], operands[1]); }
1332  [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1333   (set_attr "mode" "DI")])
1334
1335(define_insn "*movdi_64bit"
1336  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*f,*r,*f,*m")
1337	(match_operand:DI 1 "move_operand"         " r,T,m,rJ,*r*J,*m,*f,*f,*f"))]
1338  "TARGET_64BIT
1339   && (register_operand (operands[0], DImode)
1340       || reg_or_0_operand (operands[1], DImode))"
1341  { return riscv_output_move (operands[0], operands[1]); }
1342  [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
1343   (set_attr "mode" "DI")])
1344
1345;; 32-bit Integer moves
1346
1347(define_expand "mov<mode>"
1348  [(set (match_operand:MOVE32 0 "")
1349	(match_operand:MOVE32 1 ""))]
1350  ""
1351{
1352  if (riscv_legitimize_move (<MODE>mode, operands[0], operands[1]))
1353    DONE;
1354})
1355
1356(define_insn "*movsi_internal"
1357  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*f,*r,*m")
1358	(match_operand:SI 1 "move_operand"         " r,T,m,rJ,*r*J,*m,*f,*f"))]
1359  "(register_operand (operands[0], SImode)
1360    || reg_or_0_operand (operands[1], SImode))"
1361  { return riscv_output_move (operands[0], operands[1]); }
1362  [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore")
1363   (set_attr "mode" "SI")])
1364
1365;; 16-bit Integer moves
1366
1367;; Unlike most other insns, the move insns can't be split with
1368;; different predicates, because register spilling and other parts of
1369;; the compiler, have memoized the insn number already.
1370;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
1371
1372(define_expand "movhi"
1373  [(set (match_operand:HI 0 "")
1374	(match_operand:HI 1 ""))]
1375  ""
1376{
1377  if (riscv_legitimize_move (HImode, operands[0], operands[1]))
1378    DONE;
1379})
1380
1381(define_insn "*movhi_internal"
1382  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*r")
1383	(match_operand:HI 1 "move_operand"	   " r,T,m,rJ,*r*J,*f"))]
1384  "(register_operand (operands[0], HImode)
1385    || reg_or_0_operand (operands[1], HImode))"
1386  { return riscv_output_move (operands[0], operands[1]); }
1387  [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1388   (set_attr "mode" "HI")])
1389
1390;; HImode constant generation; see riscv_move_integer for details.
1391;; si+si->hi without truncation is legal because of
1392;; TARGET_TRULY_NOOP_TRUNCATION.
1393
1394(define_insn "*add<mode>hi3"
1395  [(set (match_operand:HI            0 "register_operand" "=r,r")
1396	(plus:HI (match_operand:HISI 1 "register_operand" " r,r")
1397		 (match_operand:HISI 2 "arith_operand"    " r,I")))]
1398  ""
1399  { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; }
1400  [(set_attr "type" "arith")
1401   (set_attr "mode" "HI")])
1402
1403(define_insn "*xor<mode>hi3"
1404  [(set (match_operand:HI 0 "register_operand"           "=r,r")
1405	(xor:HI (match_operand:HISI 1 "register_operand" " r,r")
1406		(match_operand:HISI 2 "arith_operand"    " r,I")))]
1407  ""
1408  "xor%i2\t%0,%1,%2"
1409  [(set_attr "type" "logical")
1410   (set_attr "mode" "HI")])
1411
1412;; 8-bit Integer moves
1413
1414(define_expand "movqi"
1415  [(set (match_operand:QI 0 "")
1416	(match_operand:QI 1 ""))]
1417  ""
1418{
1419  if (riscv_legitimize_move (QImode, operands[0], operands[1]))
1420    DONE;
1421})
1422
1423(define_insn "*movqi_internal"
1424  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r, m,  *f,*r")
1425	(match_operand:QI 1 "move_operand"         " r,I,m,rJ,*r*J,*f"))]
1426  "(register_operand (operands[0], QImode)
1427    || reg_or_0_operand (operands[1], QImode))"
1428  { return riscv_output_move (operands[0], operands[1]); }
1429  [(set_attr "move_type" "move,const,load,store,mtc,mfc")
1430   (set_attr "mode" "QI")])
1431
1432;; 32-bit floating point moves
1433
1434(define_expand "movsf"
1435  [(set (match_operand:SF 0 "")
1436	(match_operand:SF 1 ""))]
1437  ""
1438{
1439  if (riscv_legitimize_move (SFmode, operands[0], operands[1]))
1440    DONE;
1441})
1442
1443(define_insn "*movsf_hardfloat"
1444  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,  *r,*r,*m")
1445	(match_operand:SF 1 "move_operand"         " f,G,m,f,G,*r,*f,*G*r,*m,*r"))]
1446  "TARGET_HARD_FLOAT
1447   && (register_operand (operands[0], SFmode)
1448       || reg_or_0_operand (operands[1], SFmode))"
1449  { return riscv_output_move (operands[0], operands[1]); }
1450  [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1451   (set_attr "mode" "SF")])
1452
1453(define_insn "*movsf_softfloat"
1454  [(set (match_operand:SF 0 "nonimmediate_operand" "= r,r,m")
1455	(match_operand:SF 1 "move_operand"         " Gr,m,r"))]
1456  "!TARGET_HARD_FLOAT
1457   && (register_operand (operands[0], SFmode)
1458       || reg_or_0_operand (operands[1], SFmode))"
1459  { return riscv_output_move (operands[0], operands[1]); }
1460  [(set_attr "move_type" "move,load,store")
1461   (set_attr "mode" "SF")])
1462
1463;; 64-bit floating point moves
1464
1465(define_expand "movdf"
1466  [(set (match_operand:DF 0 "")
1467	(match_operand:DF 1 ""))]
1468  ""
1469{
1470  if (riscv_legitimize_move (DFmode, operands[0], operands[1]))
1471    DONE;
1472})
1473
1474;; In RV32, we lack fmv.x.d and fmv.d.x.  Go through memory instead.
1475;; (However, we can still use fcvt.d.w to zero a floating-point register.)
1476(define_insn "*movdf_hardfloat_rv32"
1477  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,  *r,*r,*m")
1478	(match_operand:DF 1 "move_operand"         " f,G,m,f,G,*r*G,*m,*r"))]
1479  "!TARGET_64BIT && TARGET_DOUBLE_FLOAT
1480   && (register_operand (operands[0], DFmode)
1481       || reg_or_0_operand (operands[1], DFmode))"
1482  { return riscv_output_move (operands[0], operands[1]); }
1483  [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,move,load,store")
1484   (set_attr "mode" "DF")])
1485
1486(define_insn "*movdf_hardfloat_rv64"
1487  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,  *r,*r,*m")
1488	(match_operand:DF 1 "move_operand"         " f,G,m,f,G,*r,*f,*r*G,*m,*r"))]
1489  "TARGET_64BIT && TARGET_DOUBLE_FLOAT
1490   && (register_operand (operands[0], DFmode)
1491       || reg_or_0_operand (operands[1], DFmode))"
1492  { return riscv_output_move (operands[0], operands[1]); }
1493  [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
1494   (set_attr "mode" "DF")])
1495
1496(define_insn "*movdf_softfloat"
1497  [(set (match_operand:DF 0 "nonimmediate_operand" "= r,r, m")
1498	(match_operand:DF 1 "move_operand"         " rG,m,rG"))]
1499  "!TARGET_DOUBLE_FLOAT
1500   && (register_operand (operands[0], DFmode)
1501       || reg_or_0_operand (operands[1], DFmode))"
1502  { return riscv_output_move (operands[0], operands[1]); }
1503  [(set_attr "move_type" "move,load,store")
1504   (set_attr "mode" "DF")])
1505
1506(define_split
1507  [(set (match_operand:MOVE64 0 "nonimmediate_operand")
1508	(match_operand:MOVE64 1 "move_operand"))]
1509  "reload_completed
1510   && riscv_split_64bit_move_p (operands[0], operands[1])"
1511  [(const_int 0)]
1512{
1513  riscv_split_doubleword_move (operands[0], operands[1]);
1514  DONE;
1515})
1516
1517(define_expand "cpymemsi"
1518  [(parallel [(set (match_operand:BLK 0 "general_operand")
1519		   (match_operand:BLK 1 "general_operand"))
1520	      (use (match_operand:SI 2 ""))
1521	      (use (match_operand:SI 3 "const_int_operand"))])]
1522  ""
1523{
1524  if (riscv_expand_block_move (operands[0], operands[1], operands[2]))
1525    DONE;
1526  else
1527    FAIL;
1528})
1529
1530;; Expand in-line code to clear the instruction cache between operand[0] and
1531;; operand[1].
1532(define_expand "clear_cache"
1533  [(match_operand 0 "pmode_register_operand")
1534   (match_operand 1 "pmode_register_operand")]
1535  ""
1536{
1537#ifdef ICACHE_FLUSH_FUNC
1538  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, ICACHE_FLUSH_FUNC),
1539		     LCT_NORMAL, VOIDmode, operands[0], Pmode,
1540		     operands[1], Pmode, const0_rtx, Pmode);
1541#else
1542  emit_insn (gen_fence_i ());
1543#endif
1544  DONE;
1545})
1546
1547(define_insn "fence"
1548  [(unspec_volatile [(const_int 0)] UNSPECV_FENCE)]
1549  ""
1550  "%|fence%-")
1551
1552(define_insn "fence_i"
1553  [(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)]
1554  ""
1555  "fence.i")
1556
1557;;
1558;;  ....................
1559;;
1560;;	SHIFTS
1561;;
1562;;  ....................
1563
1564;; Use a QImode shift count, to avoid generating sign or zero extend
1565;; instructions for shift counts, and to avoid dropping subregs.
1566;; expand_shift_1 can do this automatically when SHIFT_COUNT_TRUNCATED is
1567;; defined, but use of that is discouraged.
1568
1569(define_insn "<optab>si3"
1570  [(set (match_operand:SI     0 "register_operand" "= r")
1571	(any_shift:SI
1572	    (match_operand:SI 1 "register_operand" "  r")
1573	    (match_operand:QI 2 "arith_operand"    " rI")))]
1574  ""
1575{
1576  if (GET_CODE (operands[2]) == CONST_INT)
1577    operands[2] = GEN_INT (INTVAL (operands[2])
1578			   & (GET_MODE_BITSIZE (SImode) - 1));
1579
1580  return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2";
1581}
1582  [(set_attr "type" "shift")
1583   (set_attr "mode" "SI")])
1584
1585(define_insn_and_split "*<optab>si3_mask"
1586  [(set (match_operand:SI     0 "register_operand" "= r")
1587	(any_shift:SI
1588	    (match_operand:SI 1 "register_operand" "  r")
1589	    (subreg:QI
1590	     (and:SI
1591	      (match_operand:SI 2 "register_operand"  "r")
1592	      (match_operand 3 "const_int_operand")) 0)))]
1593  "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1594   == GET_MODE_BITSIZE (SImode)-1"
1595  "#"
1596  "&& 1"
1597  [(set (match_dup 0)
1598	(any_shift:SI (match_dup 1)
1599		      (match_dup 2)))]
1600  "operands[2] = gen_lowpart (QImode, operands[2]);"
1601  [(set_attr "type" "shift")
1602   (set_attr "mode" "SI")])
1603
1604(define_insn_and_split "*<optab>si3_mask_1"
1605  [(set (match_operand:SI     0 "register_operand" "= r")
1606	(any_shift:SI
1607	    (match_operand:SI 1 "register_operand" "  r")
1608	    (subreg:QI
1609	     (and:DI
1610	      (match_operand:DI 2 "register_operand"  "r")
1611	      (match_operand 3 "const_int_operand")) 0)))]
1612  "TARGET_64BIT
1613   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1614       == GET_MODE_BITSIZE (SImode)-1"
1615  "#"
1616  "&& 1"
1617  [(set (match_dup 0)
1618	(any_shift:SI (match_dup 1)
1619		      (match_dup 2)))]
1620  "operands[2] = gen_lowpart (QImode, operands[2]);"
1621  [(set_attr "type" "shift")
1622   (set_attr "mode" "SI")])
1623
1624(define_insn "<optab>di3"
1625  [(set (match_operand:DI 0 "register_operand"     "= r")
1626	(any_shift:DI
1627	    (match_operand:DI 1 "register_operand" "  r")
1628	    (match_operand:QI 2 "arith_operand"    " rI")))]
1629  "TARGET_64BIT"
1630{
1631  if (GET_CODE (operands[2]) == CONST_INT)
1632    operands[2] = GEN_INT (INTVAL (operands[2])
1633			   & (GET_MODE_BITSIZE (DImode) - 1));
1634
1635  return "<insn>%i2\t%0,%1,%2";
1636}
1637  [(set_attr "type" "shift")
1638   (set_attr "mode" "DI")])
1639
1640(define_insn_and_split "*<optab>di3_mask"
1641  [(set (match_operand:DI     0 "register_operand" "= r")
1642	(any_shift:DI
1643	    (match_operand:DI 1 "register_operand" "  r")
1644	    (subreg:QI
1645	     (and:SI
1646	      (match_operand:SI 2 "register_operand"  "r")
1647	      (match_operand 3 "const_int_operand")) 0)))]
1648  "TARGET_64BIT
1649   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1650       == GET_MODE_BITSIZE (DImode)-1"
1651  "#"
1652  "&& 1"
1653  [(set (match_dup 0)
1654	(any_shift:DI (match_dup 1)
1655		      (match_dup 2)))]
1656  "operands[2] = gen_lowpart (QImode, operands[2]);"
1657  [(set_attr "type" "shift")
1658   (set_attr "mode" "DI")])
1659
1660(define_insn_and_split "*<optab>di3_mask_1"
1661  [(set (match_operand:DI     0 "register_operand" "= r")
1662	(any_shift:DI
1663	    (match_operand:DI 1 "register_operand" "  r")
1664	    (subreg:QI
1665	     (and:DI
1666	      (match_operand:DI 2 "register_operand"  "r")
1667	      (match_operand 3 "const_int_operand")) 0)))]
1668  "TARGET_64BIT
1669   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1))
1670       == GET_MODE_BITSIZE (DImode)-1"
1671  "#"
1672  "&& 1"
1673  [(set (match_dup 0)
1674	(any_shift:DI (match_dup 1)
1675		      (match_dup 2)))]
1676  "operands[2] = gen_lowpart (QImode, operands[2]);"
1677  [(set_attr "type" "shift")
1678   (set_attr "mode" "DI")])
1679
1680(define_insn "*<optab>si3_extend"
1681  [(set (match_operand:DI                   0 "register_operand" "= r")
1682	(sign_extend:DI
1683	    (any_shift:SI (match_operand:SI 1 "register_operand" "  r")
1684			  (match_operand:QI 2 "arith_operand"    " rI"))))]
1685  "TARGET_64BIT"
1686{
1687  if (GET_CODE (operands[2]) == CONST_INT)
1688    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1689
1690  return "<insn>%i2w\t%0,%1,%2";
1691}
1692  [(set_attr "type" "shift")
1693   (set_attr "mode" "SI")])
1694
1695(define_insn_and_split "*<optab>si3_extend_mask"
1696  [(set (match_operand:DI                   0 "register_operand" "= r")
1697	(sign_extend:DI
1698	    (any_shift:SI
1699	     (match_operand:SI 1 "register_operand" "  r")
1700	     (subreg:QI
1701	      (and:SI
1702	       (match_operand:SI 2 "register_operand" " r")
1703	       (match_operand 3 "const_int_operand")) 0))))]
1704  "TARGET_64BIT
1705   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1706       == GET_MODE_BITSIZE (SImode)-1"
1707  "#"
1708  "&& 1"
1709  [(set (match_dup 0)
1710	(sign_extend:DI
1711	 (any_shift:SI (match_dup 1)
1712		       (match_dup 2))))]
1713  "operands[2] = gen_lowpart (QImode, operands[2]);"
1714  [(set_attr "type" "shift")
1715   (set_attr "mode" "SI")])
1716
1717(define_insn_and_split "*<optab>si3_extend_mask_1"
1718  [(set (match_operand:DI                   0 "register_operand" "= r")
1719	(sign_extend:DI
1720	    (any_shift:SI
1721	     (match_operand:SI 1 "register_operand" "  r")
1722	     (subreg:QI
1723	      (and:DI
1724	       (match_operand:DI 2 "register_operand" " r")
1725	       (match_operand 3 "const_int_operand")) 0))))]
1726  "TARGET_64BIT
1727   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
1728       == GET_MODE_BITSIZE (SImode)-1"
1729  "#"
1730  "&& 1"
1731  [(set (match_dup 0)
1732	(sign_extend:DI
1733	 (any_shift:SI (match_dup 1)
1734		       (match_dup 2))))]
1735  "operands[2] = gen_lowpart (QImode, operands[2]);"
1736  [(set_attr "type" "shift")
1737   (set_attr "mode" "SI")])
1738
1739;; Non-canonical, but can be formed by ree when combine is not successful at
1740;; producing one of the two canonical patterns below.
1741(define_insn "*lshrsi3_zero_extend_1"
1742  [(set (match_operand:DI                   0 "register_operand" "=r")
1743	(zero_extend:DI
1744	 (lshiftrt:SI (match_operand:SI     1 "register_operand" " r")
1745		      (match_operand        2 "const_int_operand"))))]
1746  "TARGET_64BIT && (INTVAL (operands[2]) & 0x1f) > 0"
1747{
1748  operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1749
1750  return "srliw\t%0,%1,%2";
1751}
1752  [(set_attr "type" "shift")
1753   (set_attr "mode" "SI")])
1754
1755;; Canonical form for a zero-extend of a logical right shift.
1756(define_insn "*lshrsi3_zero_extend_2"
1757  [(set (match_operand:DI                   0 "register_operand" "=r")
1758	(zero_extract:DI (match_operand:DI  1 "register_operand" " r")
1759			 (match_operand     2 "const_int_operand")
1760			 (match_operand     3 "const_int_operand")))]
1761  "(TARGET_64BIT && (INTVAL (operands[3]) > 0)
1762    && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))"
1763{
1764  return "srliw\t%0,%1,%3";
1765}
1766  [(set_attr "type" "shift")
1767   (set_attr "mode" "SI")])
1768
1769;; Canonical form for a zero-extend of a logical right shift when the
1770;; shift count is 31.
1771(define_insn "*lshrsi3_zero_extend_3"
1772  [(set (match_operand:DI                   0 "register_operand" "=r")
1773	(lt:DI (match_operand:SI            1 "register_operand" " r")
1774	       (const_int 0)))]
1775  "TARGET_64BIT"
1776{
1777  return "srliw\t%0,%1,31";
1778}
1779  [(set_attr "type" "shift")
1780   (set_attr "mode" "SI")])
1781
1782;; Handle AND with 2^N-1 for N from 12 to XLEN.  This can be split into
1783;; two logical shifts.  Otherwise it requires 3 instructions: lui,
1784;; xor/addi/srli, and.
1785
1786;; Generating a temporary for the shift output gives better combiner results;
1787;; and also fixes a problem where op0 could be a paradoxical reg and shifting
1788;; by amounts larger than the size of the SUBREG_REG doesn't work.
1789(define_split
1790  [(set (match_operand:GPR 0 "register_operand")
1791	(and:GPR (match_operand:GPR 1 "register_operand")
1792		 (match_operand:GPR 2 "p2m1_shift_operand")))
1793   (clobber (match_operand:GPR 3 "register_operand"))]
1794  ""
1795 [(set (match_dup 3)
1796       (ashift:GPR (match_dup 1) (match_dup 2)))
1797  (set (match_dup 0)
1798       (lshiftrt:GPR (match_dup 3) (match_dup 2)))]
1799{
1800  /* Op2 is a VOIDmode constant, so get the mode size from op1.  */
1801  operands[2] = GEN_INT (GET_MODE_BITSIZE (GET_MODE (operands[1]))
1802			 - exact_log2 (INTVAL (operands[2]) + 1));
1803})
1804
1805;; Handle AND with 0xF...F0...0 where there are 32 to 63 zeros.  This can be
1806;; split into two shifts.  Otherwise it requires 3 instructions: li, sll, and.
1807(define_split
1808  [(set (match_operand:DI 0 "register_operand")
1809	(and:DI (match_operand:DI 1 "register_operand")
1810		(match_operand:DI 2 "high_mask_shift_operand")))
1811   (clobber (match_operand:DI 3 "register_operand"))]
1812  "TARGET_64BIT"
1813  [(set (match_dup 3)
1814	(lshiftrt:DI (match_dup 1) (match_dup 2)))
1815   (set (match_dup 0)
1816	(ashift:DI (match_dup 3) (match_dup 2)))]
1817{
1818  operands[2] = GEN_INT (ctz_hwi (INTVAL (operands[2])));
1819})
1820
1821;;
1822;;  ....................
1823;;
1824;;	CONDITIONAL BRANCHES
1825;;
1826;;  ....................
1827
1828;; Conditional branches
1829
1830(define_insn "*branch<mode>"
1831  [(set (pc)
1832	(if_then_else
1833	 (match_operator 1 "order_operator"
1834			 [(match_operand:X 2 "register_operand" "r")
1835			  (match_operand:X 3 "reg_or_0_operand" "rJ")])
1836	 (label_ref (match_operand 0 "" ""))
1837	 (pc)))]
1838  ""
1839  "b%C1\t%2,%z3,%0"
1840  [(set_attr "type" "branch")
1841   (set_attr "mode" "none")])
1842
1843;; Patterns for implementations that optimize short forward branches.
1844
1845(define_expand "mov<mode>cc"
1846  [(set (match_operand:GPR 0 "register_operand")
1847	(if_then_else:GPR (match_operand 1 "comparison_operator")
1848			  (match_operand:GPR 2 "register_operand")
1849			  (match_operand:GPR 3 "sfb_alu_operand")))]
1850  "TARGET_SFB_ALU"
1851{
1852  rtx cmp = operands[1];
1853  /* We only handle word mode integer compares for now.  */
1854  if (GET_MODE (XEXP (cmp, 0)) != word_mode)
1855    FAIL;
1856  riscv_expand_conditional_move (operands[0], operands[2], operands[3],
1857				 GET_CODE (cmp), XEXP (cmp, 0), XEXP (cmp, 1));
1858  DONE;
1859})
1860
1861(define_insn "*mov<GPR:mode><X:mode>cc"
1862  [(set (match_operand:GPR 0 "register_operand" "=r,r")
1863	(if_then_else:GPR
1864	 (match_operator 5 "order_operator"
1865		[(match_operand:X 1 "register_operand" "r,r")
1866		 (match_operand:X 2 "reg_or_0_operand" "rJ,rJ")])
1867	 (match_operand:GPR 3 "register_operand" "0,0")
1868	 (match_operand:GPR 4 "sfb_alu_operand" "rJ,IL")))]
1869  "TARGET_SFB_ALU"
1870  "@
1871   b%C5 %1,%z2,1f; mv %0,%z4; 1: # movcc
1872   b%C5 %1,%z2,1f; li %0,%4; 1: # movcc"
1873  [(set_attr "length" "8")
1874   (set_attr "type" "sfb_alu")
1875   (set_attr "mode" "<GPR:MODE>")])
1876
1877;; Used to implement built-in functions.
1878(define_expand "condjump"
1879  [(set (pc)
1880	(if_then_else (match_operand 0)
1881		      (label_ref (match_operand 1))
1882		      (pc)))])
1883
1884(define_expand "cbranch<mode>4"
1885  [(set (pc)
1886	(if_then_else (match_operator 0 "comparison_operator"
1887		      [(match_operand:BR 1 "register_operand")
1888		       (match_operand:BR 2 "nonmemory_operand")])
1889		      (label_ref (match_operand 3 ""))
1890		      (pc)))]
1891  ""
1892{
1893  riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1894				   operands[1], operands[2]);
1895  DONE;
1896})
1897
1898(define_expand "cbranch<mode>4"
1899  [(set (pc)
1900	(if_then_else (match_operator 0 "fp_branch_comparison"
1901		       [(match_operand:ANYF 1 "register_operand")
1902			(match_operand:ANYF 2 "register_operand")])
1903		      (label_ref (match_operand 3 ""))
1904		      (pc)))]
1905  "TARGET_HARD_FLOAT"
1906{
1907  riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1908				   operands[1], operands[2]);
1909  DONE;
1910})
1911
1912(define_insn_and_split "*branch_on_bit<X:mode>"
1913  [(set (pc)
1914	(if_then_else
1915	    (match_operator 0 "equality_operator"
1916	        [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1917				 (const_int 1)
1918				 (match_operand 3 "branch_on_bit_operand"))
1919				 (const_int 0)])
1920	    (label_ref (match_operand 1))
1921	    (pc)))
1922   (clobber (match_scratch:X 4 "=&r"))]
1923  ""
1924  "#"
1925  "reload_completed"
1926  [(set (match_dup 4)
1927	(ashift:X (match_dup 2) (match_dup 3)))
1928   (set (pc)
1929	(if_then_else
1930	    (match_op_dup 0 [(match_dup 4) (const_int 0)])
1931	    (label_ref (match_operand 1))
1932	    (pc)))]
1933{
1934  int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]);
1935  operands[3] = GEN_INT (shift);
1936
1937  if (GET_CODE (operands[0]) == EQ)
1938    operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx);
1939  else
1940    operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx);
1941})
1942
1943(define_insn_and_split "*branch_on_bit_range<X:mode>"
1944  [(set (pc)
1945	(if_then_else
1946	    (match_operator 0 "equality_operator"
1947		[(zero_extract:X (match_operand:X 2 "register_operand" "r")
1948				 (match_operand 3 "branch_on_bit_operand")
1949				 (const_int 0))
1950				 (const_int 0)])
1951	    (label_ref (match_operand 1))
1952	    (pc)))
1953   (clobber (match_scratch:X 4 "=&r"))]
1954  ""
1955  "#"
1956  "reload_completed"
1957  [(set (match_dup 4)
1958	(ashift:X (match_dup 2) (match_dup 3)))
1959   (set (pc)
1960	(if_then_else
1961	    (match_op_dup 0 [(match_dup 4) (const_int 0)])
1962	    (label_ref (match_operand 1))
1963	    (pc)))]
1964{
1965  operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]));
1966})
1967
1968;;
1969;;  ....................
1970;;
1971;;	SETTING A REGISTER FROM A COMPARISON
1972;;
1973;;  ....................
1974
1975;; Destination is always set in SI mode.
1976
1977(define_expand "cstore<mode>4"
1978  [(set (match_operand:SI 0 "register_operand")
1979	(match_operator:SI 1 "order_operator"
1980	    [(match_operand:GPR 2 "register_operand")
1981	     (match_operand:GPR 3 "nonmemory_operand")]))]
1982  ""
1983{
1984  riscv_expand_int_scc (operands[0], GET_CODE (operands[1]), operands[2],
1985			operands[3]);
1986  DONE;
1987})
1988
1989(define_expand "cstore<mode>4"
1990  [(set (match_operand:SI 0 "register_operand")
1991	(match_operator:SI 1 "fp_scc_comparison"
1992	     [(match_operand:ANYF 2 "register_operand")
1993	      (match_operand:ANYF 3 "register_operand")]))]
1994  "TARGET_HARD_FLOAT"
1995{
1996  riscv_expand_float_scc (operands[0], GET_CODE (operands[1]), operands[2],
1997			  operands[3]);
1998  DONE;
1999})
2000
2001(define_insn "*cstore<ANYF:mode><X:mode>4"
2002   [(set (match_operand:X         0 "register_operand" "=r")
2003	 (match_operator:X 1 "fp_native_comparison"
2004	     [(match_operand:ANYF 2 "register_operand" " f")
2005	      (match_operand:ANYF 3 "register_operand" " f")]))]
2006  "TARGET_HARD_FLOAT"
2007  "f%C1.<fmt>\t%0,%2,%3"
2008  [(set_attr "type" "fcmp")
2009   (set_attr "mode" "<UNITMODE>")])
2010
2011(define_expand "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4"
2012   [(parallel [(set (match_operand:X      0 "register_operand")
2013		    (unspec:X
2014		     [(match_operand:ANYF 1 "register_operand")
2015		      (match_operand:ANYF 2 "register_operand")]
2016		     QUIET_COMPARISON))
2017	       (clobber (match_scratch:X 3))])]
2018  "TARGET_HARD_FLOAT")
2019
2020(define_insn "*f<quiet_pattern>_quiet<ANYF:mode><X:mode>4_default"
2021   [(set (match_operand:X      0 "register_operand" "=r")
2022	 (unspec:X
2023	  [(match_operand:ANYF 1 "register_operand" " f")
2024	   (match_operand:ANYF 2 "register_operand" " f")]
2025	  QUIET_COMPARISON))
2026    (clobber (match_scratch:X 3 "=&r"))]
2027  "TARGET_HARD_FLOAT && ! HONOR_SNANS (<ANYF:MODE>mode)"
2028  "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3"
2029  [(set_attr "type" "fcmp")
2030   (set_attr "mode" "<UNITMODE>")
2031   (set (attr "length") (const_int 12))])
2032
2033(define_insn "*f<quiet_pattern>_quiet<ANYF:mode><X:mode>4_snan"
2034   [(set (match_operand:X      0 "register_operand" "=r")
2035	 (unspec:X
2036	  [(match_operand:ANYF 1 "register_operand" " f")
2037	   (match_operand:ANYF 2 "register_operand" " f")]
2038	  QUIET_COMPARISON))
2039    (clobber (match_scratch:X 3 "=&r"))]
2040  "TARGET_HARD_FLOAT && HONOR_SNANS (<ANYF:MODE>mode)"
2041  "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3\n\tfeq.<fmt>\tzero,%1,%2"
2042  [(set_attr "type" "fcmp")
2043   (set_attr "mode" "<UNITMODE>")
2044   (set (attr "length") (const_int 16))])
2045
2046(define_insn "*seq_zero_<X:mode><GPR:mode>"
2047  [(set (match_operand:GPR       0 "register_operand" "=r")
2048	(eq:GPR (match_operand:X 1 "register_operand" " r")
2049		(const_int 0)))]
2050  ""
2051  "seqz\t%0,%1"
2052  [(set_attr "type" "slt")
2053   (set_attr "mode" "<X:MODE>")])
2054
2055(define_insn "*sne_zero_<X:mode><GPR:mode>"
2056  [(set (match_operand:GPR       0 "register_operand" "=r")
2057	(ne:GPR (match_operand:X 1 "register_operand" " r")
2058		(const_int 0)))]
2059  ""
2060  "snez\t%0,%1"
2061  [(set_attr "type" "slt")
2062   (set_attr "mode" "<X:MODE>")])
2063
2064(define_insn "*sgt<u>_<X:mode><GPR:mode>"
2065  [(set (match_operand:GPR           0 "register_operand" "= r")
2066	(any_gt:GPR (match_operand:X 1 "register_operand" "  r")
2067		    (match_operand:X 2 "reg_or_0_operand" " rJ")))]
2068  ""
2069  "sgt<u>\t%0,%1,%z2"
2070  [(set_attr "type" "slt")
2071   (set_attr "mode" "<X:MODE>")])
2072
2073(define_insn "*sge<u>_<X:mode><GPR:mode>"
2074  [(set (match_operand:GPR           0 "register_operand" "=r")
2075	(any_ge:GPR (match_operand:X 1 "register_operand" " r")
2076		    (const_int 1)))]
2077  ""
2078  "slt%i2<u>\t%0,zero,%1"
2079  [(set_attr "type" "slt")
2080   (set_attr "mode" "<X:MODE>")])
2081
2082(define_insn "*slt<u>_<X:mode><GPR:mode>"
2083  [(set (match_operand:GPR           0 "register_operand" "= r")
2084	(any_lt:GPR (match_operand:X 1 "register_operand" "  r")
2085		    (match_operand:X 2 "arith_operand"    " rI")))]
2086  ""
2087  "slt%i2<u>\t%0,%1,%2"
2088  [(set_attr "type" "slt")
2089   (set_attr "mode" "<X:MODE>")])
2090
2091(define_insn "*sle<u>_<X:mode><GPR:mode>"
2092  [(set (match_operand:GPR           0 "register_operand" "=r")
2093	(any_le:GPR (match_operand:X 1 "register_operand" " r")
2094		    (match_operand:X 2 "sle_operand" "")))]
2095  ""
2096{
2097  operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
2098  return "slt%i2<u>\t%0,%1,%2";
2099}
2100  [(set_attr "type" "slt")
2101   (set_attr "mode" "<X:MODE>")])
2102
2103;;
2104;;  ....................
2105;;
2106;;	UNCONDITIONAL BRANCHES
2107;;
2108;;  ....................
2109
2110;; Unconditional branches.
2111
2112(define_insn "jump"
2113  [(set (pc)
2114	(label_ref (match_operand 0 "" "")))]
2115  ""
2116  "j\t%l0"
2117  [(set_attr "type"	"jump")
2118   (set_attr "mode"	"none")])
2119
2120(define_expand "indirect_jump"
2121  [(set (pc) (match_operand 0 "register_operand"))]
2122  ""
2123{
2124  operands[0] = force_reg (Pmode, operands[0]);
2125  if (Pmode == SImode)
2126    emit_jump_insn (gen_indirect_jumpsi (operands[0]));
2127  else
2128    emit_jump_insn (gen_indirect_jumpdi (operands[0]));
2129  DONE;
2130})
2131
2132(define_insn "indirect_jump<mode>"
2133  [(set (pc) (match_operand:P 0 "register_operand" "l"))]
2134  ""
2135  "jr\t%0"
2136  [(set_attr "type" "jump")
2137   (set_attr "mode" "none")])
2138
2139(define_expand "tablejump"
2140  [(set (pc) (match_operand 0 "register_operand" ""))
2141	      (use (label_ref (match_operand 1 "" "")))]
2142  ""
2143{
2144  if (CASE_VECTOR_PC_RELATIVE)
2145      operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
2146					 gen_rtx_LABEL_REF (Pmode, operands[1]),
2147					 NULL_RTX, 0, OPTAB_DIRECT);
2148
2149  if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode)
2150    emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
2151  else
2152    emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
2153  DONE;
2154})
2155
2156(define_insn "tablejump<mode>"
2157  [(set (pc) (match_operand:GPR 0 "register_operand" "l"))
2158   (use (label_ref (match_operand 1 "" "")))]
2159  ""
2160  "jr\t%0"
2161  [(set_attr "type" "jump")
2162   (set_attr "mode" "none")])
2163
2164;;
2165;;  ....................
2166;;
2167;;	Function prologue/epilogue
2168;;
2169;;  ....................
2170;;
2171
2172(define_expand "prologue"
2173  [(const_int 1)]
2174  ""
2175{
2176  riscv_expand_prologue ();
2177  DONE;
2178})
2179
2180;; Block any insns from being moved before this point, since the
2181;; profiling call to mcount can use various registers that aren't
2182;; saved or used to pass arguments.
2183
2184(define_insn "blockage"
2185  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2186  ""
2187  ""
2188  [(set_attr "type" "ghost")
2189   (set_attr "mode" "none")])
2190
2191(define_expand "epilogue"
2192  [(const_int 2)]
2193  ""
2194{
2195  riscv_expand_epilogue (NORMAL_RETURN);
2196  DONE;
2197})
2198
2199(define_expand "sibcall_epilogue"
2200  [(const_int 2)]
2201  ""
2202{
2203  riscv_expand_epilogue (SIBCALL_RETURN);
2204  DONE;
2205})
2206
2207;; Trivial return.  Make it look like a normal return insn as that
2208;; allows jump optimizations to work better.
2209
2210(define_expand "return"
2211  [(simple_return)]
2212  "riscv_can_use_return_insn ()"
2213  "")
2214
2215(define_insn "simple_return"
2216  [(simple_return)]
2217  ""
2218{
2219  return riscv_output_return ();
2220}
2221  [(set_attr "type"	"jump")
2222   (set_attr "mode"	"none")])
2223
2224;; Normal return.
2225
2226(define_insn "simple_return_internal"
2227  [(simple_return)
2228   (use (match_operand 0 "pmode_register_operand" ""))]
2229  ""
2230  "jr\t%0"
2231  [(set_attr "type"	"jump")
2232   (set_attr "mode"	"none")])
2233
2234;; This is used in compiling the unwind routines.
2235(define_expand "eh_return"
2236  [(use (match_operand 0 "general_operand"))]
2237  ""
2238{
2239  if (GET_MODE (operands[0]) != word_mode)
2240    operands[0] = convert_to_mode (word_mode, operands[0], 0);
2241  if (TARGET_64BIT)
2242    emit_insn (gen_eh_set_lr_di (operands[0]));
2243  else
2244    emit_insn (gen_eh_set_lr_si (operands[0]));
2245
2246  emit_jump_insn (gen_eh_return_internal ());
2247  emit_barrier ();
2248  DONE;
2249})
2250
2251;; Clobber the return address on the stack.  We can't expand this
2252;; until we know where it will be put in the stack frame.
2253
2254(define_insn "eh_set_lr_si"
2255  [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2256   (clobber (match_scratch:SI 1 "=&r"))]
2257  "! TARGET_64BIT"
2258  "#")
2259
2260(define_insn "eh_set_lr_di"
2261  [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
2262   (clobber (match_scratch:DI 1 "=&r"))]
2263  "TARGET_64BIT"
2264  "#")
2265
2266(define_split
2267  [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
2268   (clobber (match_scratch 1))]
2269  "reload_completed"
2270  [(const_int 0)]
2271{
2272  riscv_set_return_address (operands[0], operands[1]);
2273  DONE;
2274})
2275
2276(define_insn_and_split "eh_return_internal"
2277  [(eh_return)]
2278  ""
2279  "#"
2280  "epilogue_completed"
2281  [(const_int 0)]
2282  "riscv_expand_epilogue (EXCEPTION_RETURN); DONE;")
2283
2284;;
2285;;  ....................
2286;;
2287;;	FUNCTION CALLS
2288;;
2289;;  ....................
2290
2291(define_expand "sibcall"
2292  [(parallel [(call (match_operand 0 "")
2293		    (match_operand 1 ""))
2294	      (use (match_operand 2 ""))	;; next_arg_reg
2295	      (use (match_operand 3 ""))])]	;; struct_value_size_rtx
2296  ""
2297{
2298  rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2299  emit_call_insn (gen_sibcall_internal (target, operands[1]));
2300  DONE;
2301})
2302
2303(define_insn "sibcall_internal"
2304  [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U"))
2305	 (match_operand 1 "" ""))]
2306  "SIBLING_CALL_P (insn)"
2307  "@
2308   jr\t%0
2309   tail\t%0
2310   tail\t%0@plt"
2311  [(set_attr "type" "call")])
2312
2313(define_expand "sibcall_value"
2314  [(parallel [(set (match_operand 0 "")
2315		   (call (match_operand 1 "")
2316			 (match_operand 2 "")))
2317	      (use (match_operand 3 ""))])]		;; next_arg_reg
2318  ""
2319{
2320  rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2321  emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2]));
2322  DONE;
2323})
2324
2325(define_insn "sibcall_value_internal"
2326  [(set (match_operand 0 "" "")
2327	(call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U"))
2328	      (match_operand 2 "" "")))]
2329  "SIBLING_CALL_P (insn)"
2330  "@
2331   jr\t%1
2332   tail\t%1
2333   tail\t%1@plt"
2334  [(set_attr "type" "call")])
2335
2336(define_expand "call"
2337  [(parallel [(call (match_operand 0 "")
2338		    (match_operand 1 ""))
2339	      (use (match_operand 2 ""))	;; next_arg_reg
2340	      (use (match_operand 3 ""))])]	;; struct_value_size_rtx
2341  ""
2342{
2343  rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
2344  emit_call_insn (gen_call_internal (target, operands[1]));
2345  DONE;
2346})
2347
2348(define_insn "call_internal"
2349  [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U"))
2350	 (match_operand 1 "" ""))
2351   (clobber (reg:SI RETURN_ADDR_REGNUM))]
2352  ""
2353  "@
2354   jalr\t%0
2355   call\t%0
2356   call\t%0@plt"
2357  [(set_attr "type" "call")])
2358
2359(define_expand "call_value"
2360  [(parallel [(set (match_operand 0 "")
2361		   (call (match_operand 1 "")
2362			 (match_operand 2 "")))
2363	      (use (match_operand 3 ""))])]		;; next_arg_reg
2364  ""
2365{
2366  rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2367  emit_call_insn (gen_call_value_internal (operands[0], target, operands[2]));
2368  DONE;
2369})
2370
2371(define_insn "call_value_internal"
2372  [(set (match_operand 0 "" "")
2373	(call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U"))
2374	      (match_operand 2 "" "")))
2375   (clobber (reg:SI RETURN_ADDR_REGNUM))]
2376  ""
2377  "@
2378   jalr\t%1
2379   call\t%1
2380   call\t%1@plt"
2381  [(set_attr "type" "call")])
2382
2383;; Call subroutine returning any type.
2384
2385(define_expand "untyped_call"
2386  [(parallel [(call (match_operand 0 "")
2387		    (const_int 0))
2388	      (match_operand 1 "")
2389	      (match_operand 2 "")])]
2390  ""
2391{
2392  int i;
2393
2394  emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2395
2396  for (i = 0; i < XVECLEN (operands[2], 0); i++)
2397    {
2398      rtx set = XVECEXP (operands[2], 0, i);
2399      riscv_emit_move (SET_DEST (set), SET_SRC (set));
2400    }
2401
2402  emit_insn (gen_blockage ());
2403  DONE;
2404})
2405
2406(define_insn "nop"
2407  [(const_int 0)]
2408  ""
2409  "nop"
2410  [(set_attr "type"	"nop")
2411   (set_attr "mode"	"none")])
2412
2413(define_insn "trap"
2414  [(trap_if (const_int 1) (const_int 0))]
2415  ""
2416  "ebreak")
2417
2418;; Must use the registers that we save to prevent the rename reg optimization
2419;; pass from using them before the gpr_save pattern when shrink wrapping
2420;; occurs.  See bug 95252 for instance.
2421
2422(define_insn "gpr_save"
2423  [(match_parallel 1 "gpr_save_operation"
2424     [(unspec_volatile [(match_operand 0 "const_int_operand")]
2425	               UNSPECV_GPR_SAVE)])]
2426  ""
2427  "call\tt0,__riscv_save_%0")
2428
2429(define_insn "gpr_restore"
2430  [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_RESTORE)]
2431  ""
2432  "tail\t__riscv_restore_%0")
2433
2434(define_insn "gpr_restore_return"
2435  [(return)
2436   (use (match_operand 0 "pmode_register_operand" ""))
2437   (const_int 0)]
2438  ""
2439  "")
2440
2441(define_insn "riscv_frflags"
2442  [(set (match_operand:SI 0 "register_operand" "=r")
2443	(unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))]
2444  "TARGET_HARD_FLOAT"
2445  "frflags\t%0")
2446
2447(define_insn "riscv_fsflags"
2448  [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)]
2449  "TARGET_HARD_FLOAT"
2450  "fsflags\t%0")
2451
2452(define_insn "riscv_mret"
2453  [(return)
2454   (unspec_volatile [(const_int 0)] UNSPECV_MRET)]
2455  ""
2456  "mret")
2457
2458(define_insn "riscv_sret"
2459  [(return)
2460   (unspec_volatile [(const_int 0)] UNSPECV_SRET)]
2461  ""
2462  "sret")
2463
2464(define_insn "riscv_uret"
2465  [(return)
2466   (unspec_volatile [(const_int 0)] UNSPECV_URET)]
2467  ""
2468  "uret")
2469
2470(define_insn "stack_tie<mode>"
2471  [(set (mem:BLK (scratch))
2472	(unspec:BLK [(match_operand:X 0 "register_operand" "r")
2473		     (match_operand:X 1 "register_operand" "r")]
2474		    UNSPEC_TIE))]
2475  ""
2476  ""
2477  [(set_attr "length" "0")]
2478)
2479
2480;; This fixes a failure with gcc.c-torture/execute/pr64242.c at -O2 for a
2481;; 32-bit target when using -mtune=sifive-7-series.  The first sched pass
2482;; runs before register elimination, and we have a non-obvious dependency
2483;; between a use of the soft fp and a set of the hard fp.  We fix this by
2484;; emitting a clobber using the hard fp between the two insns.
2485(define_expand "restore_stack_nonlocal"
2486  [(match_operand 0 "register_operand")
2487   (match_operand 1 "memory_operand")]
2488  ""
2489{
2490  emit_move_insn (operands[0], operands[1]);
2491  /* Prevent the following hard fp restore from being moved before the move
2492     insn above which uses a copy of the soft fp reg.  */
2493  emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
2494  DONE;
2495})
2496
2497;; Named pattern for expanding thread pointer reference.
2498(define_expand "get_thread_pointer<mode>"
2499  [(set (match_operand:P 0 "register_operand" "=r")
2500	(reg:P TP_REGNUM))]
2501  ""
2502{})
2503
2504(include "sync.md")
2505(include "peephole.md")
2506(include "pic.md")
2507(include "generic.md")
2508(include "sifive-7.md")
2509