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