comparison gcc/config/riscv/riscv.md @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 ;; Machine description for RISC-V for GNU compiler.
2 ;; Copyright (C) 2011-2017 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 ? "addw\t%0,%1,%2" : "add\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\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 "addw\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 "addw\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>w\t%0,%1,%2" : "<insn>\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>\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>w\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>\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>\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 and\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 ? "addw\t%0,%1,%2" : "add\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\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 ;; Expand in-line code to clear the instruction cache between operand[0] and
1440 ;; operand[1].
1441 (define_expand "clear_cache"
1442 [(match_operand 0 "pmode_register_operand")
1443 (match_operand 1 "pmode_register_operand")]
1444 ""
1445 {
1446 emit_insn (gen_fence_i ());
1447 DONE;
1448 })
1449
1450 (define_insn "fence"
1451 [(unspec_volatile [(const_int 0)] UNSPECV_FENCE)]
1452 ""
1453 "%|fence%-")
1454
1455 (define_insn "fence_i"
1456 [(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)]
1457 ""
1458 "fence.i")
1459
1460 ;;
1461 ;; ....................
1462 ;;
1463 ;; SHIFTS
1464 ;;
1465 ;; ....................
1466
1467 (define_insn "<optab>si3"
1468 [(set (match_operand:SI 0 "register_operand" "= r")
1469 (any_shift:SI
1470 (match_operand:SI 1 "register_operand" " r")
1471 (match_operand:SI 2 "arith_operand" " rI")))]
1472 ""
1473 {
1474 if (GET_CODE (operands[2]) == CONST_INT)
1475 operands[2] = GEN_INT (INTVAL (operands[2])
1476 & (GET_MODE_BITSIZE (SImode) - 1));
1477
1478 return TARGET_64BIT ? "<insn>w\t%0,%1,%2" : "<insn>\t%0,%1,%2";
1479 }
1480 [(set_attr "type" "shift")
1481 (set_attr "mode" "SI")])
1482
1483 (define_insn "<optab>di3"
1484 [(set (match_operand:DI 0 "register_operand" "= r")
1485 (any_shift:DI
1486 (match_operand:DI 1 "register_operand" " r")
1487 (match_operand:DI 2 "arith_operand" " rI")))]
1488 "TARGET_64BIT"
1489 {
1490 if (GET_CODE (operands[2]) == CONST_INT)
1491 operands[2] = GEN_INT (INTVAL (operands[2])
1492 & (GET_MODE_BITSIZE (DImode) - 1));
1493
1494 return "<insn>\t%0,%1,%2";
1495 }
1496 [(set_attr "type" "shift")
1497 (set_attr "mode" "DI")])
1498
1499 (define_insn "*<optab>si3_extend"
1500 [(set (match_operand:DI 0 "register_operand" "= r")
1501 (sign_extend:DI
1502 (any_shift:SI (match_operand:SI 1 "register_operand" " r")
1503 (match_operand:SI 2 "arith_operand" " rI"))))]
1504 "TARGET_64BIT"
1505 {
1506 if (GET_CODE (operands[2]) == CONST_INT)
1507 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
1508
1509 return "<insn>w\t%0,%1,%2";
1510 }
1511 [(set_attr "type" "shift")
1512 (set_attr "mode" "SI")])
1513
1514 ;;
1515 ;; ....................
1516 ;;
1517 ;; CONDITIONAL BRANCHES
1518 ;;
1519 ;; ....................
1520
1521 ;; Conditional branches
1522
1523 (define_insn "*branch_order<mode>"
1524 [(set (pc)
1525 (if_then_else
1526 (match_operator 1 "order_operator"
1527 [(match_operand:X 2 "register_operand" "r")
1528 (match_operand:X 3 "register_operand" "r")])
1529 (label_ref (match_operand 0 "" ""))
1530 (pc)))]
1531 ""
1532 "b%C1\t%2,%3,%0"
1533 [(set_attr "type" "branch")
1534 (set_attr "mode" "none")])
1535
1536 (define_insn "*branch_zero<mode>"
1537 [(set (pc)
1538 (if_then_else
1539 (match_operator 1 "signed_order_operator"
1540 [(match_operand:X 2 "register_operand" "r")
1541 (const_int 0)])
1542 (label_ref (match_operand 0 "" ""))
1543 (pc)))]
1544 ""
1545 "b%C1z\t%2,%0"
1546 [(set_attr "type" "branch")
1547 (set_attr "mode" "none")])
1548
1549 ;; Used to implement built-in functions.
1550 (define_expand "condjump"
1551 [(set (pc)
1552 (if_then_else (match_operand 0)
1553 (label_ref (match_operand 1))
1554 (pc)))])
1555
1556 (define_expand "cbranch<mode>4"
1557 [(set (pc)
1558 (if_then_else (match_operator 0 "comparison_operator"
1559 [(match_operand:BR 1 "register_operand")
1560 (match_operand:BR 2 "nonmemory_operand")])
1561 (label_ref (match_operand 3 ""))
1562 (pc)))]
1563 ""
1564 {
1565 riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1566 operands[1], operands[2]);
1567 DONE;
1568 })
1569
1570 (define_expand "cbranch<mode>4"
1571 [(set (pc)
1572 (if_then_else (match_operator 0 "fp_branch_comparison"
1573 [(match_operand:ANYF 1 "register_operand")
1574 (match_operand:ANYF 2 "register_operand")])
1575 (label_ref (match_operand 3 ""))
1576 (pc)))]
1577 "TARGET_HARD_FLOAT"
1578 {
1579 riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
1580 operands[1], operands[2]);
1581 DONE;
1582 })
1583
1584 (define_insn_and_split "*branch_on_bit<X:mode>"
1585 [(set (pc)
1586 (if_then_else
1587 (match_operator 0 "equality_operator"
1588 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1589 (const_int 1)
1590 (match_operand 3 "branch_on_bit_operand"))
1591 (const_int 0)])
1592 (label_ref (match_operand 1))
1593 (pc)))
1594 (clobber (match_scratch:X 4 "=&r"))]
1595 ""
1596 "#"
1597 "reload_completed"
1598 [(set (match_dup 4)
1599 (ashift:X (match_dup 2) (match_dup 3)))
1600 (set (pc)
1601 (if_then_else
1602 (match_op_dup 0 [(match_dup 4) (const_int 0)])
1603 (label_ref (match_operand 1))
1604 (pc)))]
1605 {
1606 int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]);
1607 operands[3] = GEN_INT (shift);
1608
1609 if (GET_CODE (operands[0]) == EQ)
1610 operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx);
1611 else
1612 operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx);
1613 })
1614
1615 (define_insn_and_split "*branch_on_bit_range<X:mode>"
1616 [(set (pc)
1617 (if_then_else
1618 (match_operator 0 "equality_operator"
1619 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
1620 (match_operand 3 "branch_on_bit_operand")
1621 (const_int 0))
1622 (const_int 0)])
1623 (label_ref (match_operand 1))
1624 (pc)))
1625 (clobber (match_scratch:X 4 "=&r"))]
1626 ""
1627 "#"
1628 "reload_completed"
1629 [(set (match_dup 4)
1630 (ashift:X (match_dup 2) (match_dup 3)))
1631 (set (pc)
1632 (if_then_else
1633 (match_op_dup 0 [(match_dup 4) (const_int 0)])
1634 (label_ref (match_operand 1))
1635 (pc)))]
1636 {
1637 operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]));
1638 })
1639
1640 ;;
1641 ;; ....................
1642 ;;
1643 ;; SETTING A REGISTER FROM A COMPARISON
1644 ;;
1645 ;; ....................
1646
1647 ;; Destination is always set in SI mode.
1648
1649 (define_expand "cstore<mode>4"
1650 [(set (match_operand:SI 0 "register_operand")
1651 (match_operator:SI 1 "order_operator"
1652 [(match_operand:GPR 2 "register_operand")
1653 (match_operand:GPR 3 "nonmemory_operand")]))]
1654 ""
1655 {
1656 riscv_expand_int_scc (operands[0], GET_CODE (operands[1]), operands[2],
1657 operands[3]);
1658 DONE;
1659 })
1660
1661 (define_expand "cstore<mode>4"
1662 [(set (match_operand:SI 0 "register_operand")
1663 (match_operator:SI 1 "fp_scc_comparison"
1664 [(match_operand:ANYF 2 "register_operand")
1665 (match_operand:ANYF 3 "register_operand")]))]
1666 "TARGET_HARD_FLOAT"
1667 {
1668 riscv_expand_float_scc (operands[0], GET_CODE (operands[1]), operands[2],
1669 operands[3]);
1670 DONE;
1671 })
1672
1673 (define_insn "*cstore<ANYF:mode><X:mode>4"
1674 [(set (match_operand:X 0 "register_operand" "=r")
1675 (match_operator:X 1 "fp_native_comparison"
1676 [(match_operand:ANYF 2 "register_operand" " f")
1677 (match_operand:ANYF 3 "register_operand" " f")]))]
1678 "TARGET_HARD_FLOAT"
1679 "f%C1.<fmt>\t%0,%2,%3"
1680 [(set_attr "type" "fcmp")
1681 (set_attr "mode" "<UNITMODE>")])
1682
1683 (define_insn "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4"
1684 [(set (match_operand:X 0 "register_operand" "=r")
1685 (unspec:X
1686 [(match_operand:ANYF 1 "register_operand" " f")
1687 (match_operand:ANYF 2 "register_operand" " f")]
1688 QUIET_COMPARISON))
1689 (clobber (match_scratch:X 3 "=&r"))]
1690 "TARGET_HARD_FLOAT"
1691 "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3"
1692 [(set_attr "type" "fcmp")
1693 (set_attr "mode" "<UNITMODE>")
1694 (set (attr "length") (const_int 12))])
1695
1696 (define_insn "*seq_zero_<X:mode><GPR:mode>"
1697 [(set (match_operand:GPR 0 "register_operand" "=r")
1698 (eq:GPR (match_operand:X 1 "register_operand" " r")
1699 (const_int 0)))]
1700 ""
1701 "seqz\t%0,%1"
1702 [(set_attr "type" "slt")
1703 (set_attr "mode" "<X:MODE>")])
1704
1705 (define_insn "*sne_zero_<X:mode><GPR:mode>"
1706 [(set (match_operand:GPR 0 "register_operand" "=r")
1707 (ne:GPR (match_operand:X 1 "register_operand" " r")
1708 (const_int 0)))]
1709 ""
1710 "snez\t%0,%1"
1711 [(set_attr "type" "slt")
1712 (set_attr "mode" "<X:MODE>")])
1713
1714 (define_insn "*sgt<u>_<X:mode><GPR:mode>"
1715 [(set (match_operand:GPR 0 "register_operand" "= r")
1716 (any_gt:GPR (match_operand:X 1 "register_operand" " r")
1717 (match_operand:X 2 "reg_or_0_operand" " rJ")))]
1718 ""
1719 "sgt<u>\t%0,%1,%z2"
1720 [(set_attr "type" "slt")
1721 (set_attr "mode" "<X:MODE>")])
1722
1723 (define_insn "*sge<u>_<X:mode><GPR:mode>"
1724 [(set (match_operand:GPR 0 "register_operand" "=r")
1725 (any_ge:GPR (match_operand:X 1 "register_operand" " r")
1726 (const_int 1)))]
1727 ""
1728 "slt<u>\t%0,zero,%1"
1729 [(set_attr "type" "slt")
1730 (set_attr "mode" "<MODE>")])
1731
1732 (define_insn "*slt<u>_<X:mode><GPR:mode>"
1733 [(set (match_operand:GPR 0 "register_operand" "= r")
1734 (any_lt:GPR (match_operand:X 1 "register_operand" " r")
1735 (match_operand:X 2 "arith_operand" " rI")))]
1736 ""
1737 "slt<u>\t%0,%1,%2"
1738 [(set_attr "type" "slt")
1739 (set_attr "mode" "<MODE>")])
1740
1741 (define_insn "*sle<u>_<X:mode><GPR:mode>"
1742 [(set (match_operand:GPR 0 "register_operand" "=r")
1743 (any_le:GPR (match_operand:X 1 "register_operand" " r")
1744 (match_operand:X 2 "sle_operand" "")))]
1745 ""
1746 {
1747 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
1748 return "slt<u>\t%0,%1,%2";
1749 }
1750 [(set_attr "type" "slt")
1751 (set_attr "mode" "<MODE>")])
1752
1753 ;;
1754 ;; ....................
1755 ;;
1756 ;; UNCONDITIONAL BRANCHES
1757 ;;
1758 ;; ....................
1759
1760 ;; Unconditional branches.
1761
1762 (define_insn "jump"
1763 [(set (pc)
1764 (label_ref (match_operand 0 "" "")))]
1765 ""
1766 "j\t%l0"
1767 [(set_attr "type" "jump")
1768 (set_attr "mode" "none")])
1769
1770 (define_expand "indirect_jump"
1771 [(set (pc) (match_operand 0 "register_operand"))]
1772 ""
1773 {
1774 operands[0] = force_reg (Pmode, operands[0]);
1775 if (Pmode == SImode)
1776 emit_jump_insn (gen_indirect_jumpsi (operands[0]));
1777 else
1778 emit_jump_insn (gen_indirect_jumpdi (operands[0]));
1779 DONE;
1780 })
1781
1782 (define_insn "indirect_jump<mode>"
1783 [(set (pc) (match_operand:P 0 "register_operand" "l"))]
1784 ""
1785 "jr\t%0"
1786 [(set_attr "type" "jump")
1787 (set_attr "mode" "none")])
1788
1789 (define_expand "tablejump"
1790 [(set (pc) (match_operand 0 "register_operand" ""))
1791 (use (label_ref (match_operand 1 "" "")))]
1792 ""
1793 {
1794 if (CASE_VECTOR_PC_RELATIVE)
1795 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1796 gen_rtx_LABEL_REF (Pmode, operands[1]),
1797 NULL_RTX, 0, OPTAB_DIRECT);
1798
1799 if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode)
1800 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
1801 else
1802 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
1803 DONE;
1804 })
1805
1806 (define_insn "tablejump<mode>"
1807 [(set (pc) (match_operand:GPR 0 "register_operand" "l"))
1808 (use (label_ref (match_operand 1 "" "")))]
1809 ""
1810 "jr\t%0"
1811 [(set_attr "type" "jump")
1812 (set_attr "mode" "none")])
1813
1814 ;;
1815 ;; ....................
1816 ;;
1817 ;; Function prologue/epilogue
1818 ;;
1819 ;; ....................
1820 ;;
1821
1822 (define_expand "prologue"
1823 [(const_int 1)]
1824 ""
1825 {
1826 riscv_expand_prologue ();
1827 DONE;
1828 })
1829
1830 ;; Block any insns from being moved before this point, since the
1831 ;; profiling call to mcount can use various registers that aren't
1832 ;; saved or used to pass arguments.
1833
1834 (define_insn "blockage"
1835 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
1836 ""
1837 ""
1838 [(set_attr "type" "ghost")
1839 (set_attr "mode" "none")])
1840
1841 (define_expand "epilogue"
1842 [(const_int 2)]
1843 ""
1844 {
1845 riscv_expand_epilogue (false);
1846 DONE;
1847 })
1848
1849 (define_expand "sibcall_epilogue"
1850 [(const_int 2)]
1851 ""
1852 {
1853 riscv_expand_epilogue (true);
1854 DONE;
1855 })
1856
1857 ;; Trivial return. Make it look like a normal return insn as that
1858 ;; allows jump optimizations to work better.
1859
1860 (define_expand "return"
1861 [(simple_return)]
1862 "riscv_can_use_return_insn ()"
1863 "")
1864
1865 (define_insn "simple_return"
1866 [(simple_return)]
1867 ""
1868 "ret"
1869 [(set_attr "type" "jump")
1870 (set_attr "mode" "none")])
1871
1872 ;; Normal return.
1873
1874 (define_insn "simple_return_internal"
1875 [(simple_return)
1876 (use (match_operand 0 "pmode_register_operand" ""))]
1877 ""
1878 "jr\t%0"
1879 [(set_attr "type" "jump")
1880 (set_attr "mode" "none")])
1881
1882 ;; This is used in compiling the unwind routines.
1883 (define_expand "eh_return"
1884 [(use (match_operand 0 "general_operand"))]
1885 ""
1886 {
1887 if (GET_MODE (operands[0]) != word_mode)
1888 operands[0] = convert_to_mode (word_mode, operands[0], 0);
1889 if (TARGET_64BIT)
1890 emit_insn (gen_eh_set_lr_di (operands[0]));
1891 else
1892 emit_insn (gen_eh_set_lr_si (operands[0]));
1893 DONE;
1894 })
1895
1896 ;; Clobber the return address on the stack. We can't expand this
1897 ;; until we know where it will be put in the stack frame.
1898
1899 (define_insn "eh_set_lr_si"
1900 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
1901 (clobber (match_scratch:SI 1 "=&r"))]
1902 "! TARGET_64BIT"
1903 "#")
1904
1905 (define_insn "eh_set_lr_di"
1906 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
1907 (clobber (match_scratch:DI 1 "=&r"))]
1908 "TARGET_64BIT"
1909 "#")
1910
1911 (define_split
1912 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
1913 (clobber (match_scratch 1))]
1914 "reload_completed"
1915 [(const_int 0)]
1916 {
1917 riscv_set_return_address (operands[0], operands[1]);
1918 DONE;
1919 })
1920
1921 ;;
1922 ;; ....................
1923 ;;
1924 ;; FUNCTION CALLS
1925 ;;
1926 ;; ....................
1927
1928 (define_expand "sibcall"
1929 [(parallel [(call (match_operand 0 "")
1930 (match_operand 1 ""))
1931 (use (match_operand 2 "")) ;; next_arg_reg
1932 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
1933 ""
1934 {
1935 rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
1936 emit_call_insn (gen_sibcall_internal (target, operands[1]));
1937 DONE;
1938 })
1939
1940 (define_insn "sibcall_internal"
1941 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U"))
1942 (match_operand 1 "" ""))]
1943 "SIBLING_CALL_P (insn)"
1944 "@
1945 jr\t%0
1946 tail\t%0
1947 tail\t%0@plt"
1948 [(set_attr "type" "call")])
1949
1950 (define_expand "sibcall_value"
1951 [(parallel [(set (match_operand 0 "")
1952 (call (match_operand 1 "")
1953 (match_operand 2 "")))
1954 (use (match_operand 3 ""))])] ;; next_arg_reg
1955 ""
1956 {
1957 rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
1958 emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2]));
1959 DONE;
1960 })
1961
1962 (define_insn "sibcall_value_internal"
1963 [(set (match_operand 0 "" "")
1964 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U"))
1965 (match_operand 2 "" "")))]
1966 "SIBLING_CALL_P (insn)"
1967 "@
1968 jr\t%1
1969 tail\t%1
1970 tail\t%1@plt"
1971 [(set_attr "type" "call")])
1972
1973 (define_expand "call"
1974 [(parallel [(call (match_operand 0 "")
1975 (match_operand 1 ""))
1976 (use (match_operand 2 "")) ;; next_arg_reg
1977 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
1978 ""
1979 {
1980 rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
1981 emit_call_insn (gen_call_internal (target, operands[1]));
1982 DONE;
1983 })
1984
1985 (define_insn "call_internal"
1986 [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U"))
1987 (match_operand 1 "" ""))
1988 (clobber (reg:SI RETURN_ADDR_REGNUM))]
1989 ""
1990 "@
1991 jalr\t%0
1992 call\t%0
1993 call\t%0@plt"
1994 [(set_attr "type" "call")])
1995
1996 (define_expand "call_value"
1997 [(parallel [(set (match_operand 0 "")
1998 (call (match_operand 1 "")
1999 (match_operand 2 "")))
2000 (use (match_operand 3 ""))])] ;; next_arg_reg
2001 ""
2002 {
2003 rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
2004 emit_call_insn (gen_call_value_internal (operands[0], target, operands[2]));
2005 DONE;
2006 })
2007
2008 (define_insn "call_value_internal"
2009 [(set (match_operand 0 "" "")
2010 (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U"))
2011 (match_operand 2 "" "")))
2012 (clobber (reg:SI RETURN_ADDR_REGNUM))]
2013 ""
2014 "@
2015 jalr\t%1
2016 call\t%1
2017 call\t%1@plt"
2018 [(set_attr "type" "call")])
2019
2020 ;; Call subroutine returning any type.
2021
2022 (define_expand "untyped_call"
2023 [(parallel [(call (match_operand 0 "")
2024 (const_int 0))
2025 (match_operand 1 "")
2026 (match_operand 2 "")])]
2027 ""
2028 {
2029 int i;
2030
2031 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2032
2033 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2034 {
2035 rtx set = XVECEXP (operands[2], 0, i);
2036 riscv_emit_move (SET_DEST (set), SET_SRC (set));
2037 }
2038
2039 emit_insn (gen_blockage ());
2040 DONE;
2041 })
2042
2043 (define_insn "nop"
2044 [(const_int 0)]
2045 ""
2046 "nop"
2047 [(set_attr "type" "nop")
2048 (set_attr "mode" "none")])
2049
2050 (define_insn "trap"
2051 [(trap_if (const_int 1) (const_int 0))]
2052 ""
2053 "ebreak")
2054
2055 (define_insn "gpr_save"
2056 [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_SAVE)
2057 (clobber (reg:SI T0_REGNUM))
2058 (clobber (reg:SI T1_REGNUM))]
2059 ""
2060 { return riscv_output_gpr_save (INTVAL (operands[0])); })
2061
2062 (define_insn "gpr_restore"
2063 [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_RESTORE)]
2064 ""
2065 "tail\t__riscv_restore_%0")
2066
2067 (define_insn "gpr_restore_return"
2068 [(return)
2069 (use (match_operand 0 "pmode_register_operand" ""))
2070 (const_int 0)]
2071 ""
2072 "")
2073
2074 (define_insn "riscv_frflags"
2075 [(set (match_operand:SI 0 "register_operand" "=r")
2076 (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))]
2077 "TARGET_HARD_FLOAT"
2078 "frflags %0")
2079
2080 (define_insn "riscv_fsflags"
2081 [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)]
2082 "TARGET_HARD_FLOAT"
2083 "fsflags %0")
2084
2085 (define_insn "stack_tie<mode>"
2086 [(set (mem:BLK (scratch))
2087 (unspec:BLK [(match_operand:X 0 "register_operand" "r")
2088 (match_operand:X 1 "register_operand" "r")]
2089 UNSPEC_TIE))]
2090 ""
2091 ""
2092 [(set_attr "length" "0")]
2093 )
2094
2095 (include "sync.md")
2096 (include "peephole.md")
2097 (include "pic.md")
2098 (include "generic.md")