OpenCores
URL https://opencores.org/ocsvn/hf-risc/hf-risc/trunk

Subversion Repositories hf-risc

[/] [hf-risc/] [trunk/] [tools/] [riscv-gnu-toolchain-master/] [gcc/] [gcc/] [config/] [riscv/] [riscv.md] - Blame information for rev 13

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.