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