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