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