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

Subversion Repositories hf-risc

[/] [hf-risc/] [trunk/] [tools/] [build_mips_toolchain/] [mips.md] - Blame information for rev 13

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 serginhofr
;;  Mips.md          Machine Description for MIPS based processors
2
;;  Copyright (C) 1989-2014 Free Software Foundation, Inc.
3
;;  Contributed by   A. Lichnewsky, lich@inria.inria.fr
4
;;  Changes by       Michael Meissner, meissner@osf.org
5
;;  64-bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
6
;;  Brendan Eich, brendan@microunity.com.
7
 
8
;; This file is part of GCC.
9
 
10
;; GCC is free software; you can redistribute it and/or modify
11
;; it under the terms of the GNU General Public License as published by
12
;; the Free Software Foundation; either version 3, or (at your option)
13
;; any later version.
14
 
15
;; GCC is distributed in the hope that it will be useful,
16
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
;; GNU General Public License for more details.
19
 
20
;; You should have received a copy of the GNU General Public License
21
;; along with GCC; see the file COPYING3.  If not see
22
;; .
23
 
24
(define_enum "processor" [
25
  r3000
26
  4kc
27
  4kp
28
  5kc
29
  5kf
30
  20kc
31
  24kc
32
  24kf2_1
33
  24kf1_1
34
  74kc
35
  74kf2_1
36
  74kf1_1
37
  74kf3_2
38
  loongson_2e
39
  loongson_2f
40
  loongson_3a
41
  m4k
42
  octeon
43
  octeon2
44
  r3900
45
  r6000
46
  r4000
47
  r4100
48
  r4111
49
  r4120
50
  r4130
51
  r4300
52
  r4600
53
  r4650
54
  r4700
55
  r5000
56
  r5400
57
  r5500
58
  r5900
59
  r7000
60
  r8000
61
  r9000
62
  r10000
63
  sb1
64
  sb1a
65
  sr71000
66
  xlr
67
  xlp
68
])
69
 
70
(define_c_enum "unspec" [
71
  ;; Unaligned accesses.
72
  UNSPEC_LOAD_LEFT
73
  UNSPEC_LOAD_RIGHT
74
  UNSPEC_STORE_LEFT
75
  UNSPEC_STORE_RIGHT
76
 
77
  ;; Integer operations that are too cumbersome to describe directly.
78
  UNSPEC_WSBH
79
  UNSPEC_DSBH
80
  UNSPEC_DSHD
81
 
82
  ;; Floating-point moves.
83
  UNSPEC_LOAD_LOW
84
  UNSPEC_LOAD_HIGH
85
  UNSPEC_STORE_WORD
86
  UNSPEC_MFHC1
87
  UNSPEC_MTHC1
88
 
89
  ;; Floating-point environment.
90
  UNSPEC_GET_FCSR
91
  UNSPEC_SET_FCSR
92
 
93
  ;; HI/LO moves.
94
  UNSPEC_MFHI
95
  UNSPEC_MTHI
96
  UNSPEC_SET_HILO
97
 
98
  ;; GP manipulation.
99
  UNSPEC_LOADGP
100
  UNSPEC_COPYGP
101
  UNSPEC_MOVE_GP
102
  UNSPEC_POTENTIAL_CPRESTORE
103
  UNSPEC_CPRESTORE
104
  UNSPEC_RESTORE_GP
105
  UNSPEC_EH_RETURN
106
  UNSPEC_GP
107
  UNSPEC_SET_GOT_VERSION
108
  UNSPEC_UPDATE_GOT_VERSION
109
 
110
  ;; Symbolic accesses.
111
  UNSPEC_LOAD_CALL
112
  UNSPEC_LOAD_GOT
113
  UNSPEC_TLS_LDM
114
  UNSPEC_TLS_GET_TP
115
  UNSPEC_UNSHIFTED_HIGH
116
 
117
  ;; MIPS16 constant pools.
118
  UNSPEC_ALIGN
119
  UNSPEC_CONSTTABLE_INT
120
  UNSPEC_CONSTTABLE_FLOAT
121
 
122
  ;; Blockage and synchronisation.
123
  UNSPEC_BLOCKAGE
124
  UNSPEC_CLEAR_HAZARD
125
  UNSPEC_RDHWR
126
  UNSPEC_SYNCI
127
  UNSPEC_SYNC
128
 
129
  ;; Cache manipulation.
130
  UNSPEC_MIPS_CACHE
131
  UNSPEC_R10K_CACHE_BARRIER
132
 
133
  ;; Interrupt handling.
134
  UNSPEC_ERET
135
  UNSPEC_DERET
136
  UNSPEC_DI
137
  UNSPEC_EHB
138
  UNSPEC_RDPGPR
139
  UNSPEC_COP0
140
 
141
  ;; Used in a call expression in place of args_size.  It's present for PIC
142
  ;; indirect calls where it contains args_size and the function symbol.
143
  UNSPEC_CALL_ATTR
144
 
145
  ;; MIPS16 casesi jump table dispatch.
146
  UNSPEC_CASESI_DISPATCH
147
 
148
  ;; Stack checking.
149
  UNSPEC_PROBE_STACK_RANGE
150
])
151
 
152
(define_constants
153
  [(TLS_GET_TP_REGNUM           3)
154
   (GET_FCSR_REGNUM             2)
155
   (SET_FCSR_REGNUM             4)
156
   (MIPS16_T_REGNUM             24)
157
   (PIC_FUNCTION_ADDR_REGNUM    25)
158
   (RETURN_ADDR_REGNUM          31)
159
   (CPRESTORE_SLOT_REGNUM       76)
160
   (GOT_VERSION_REGNUM          79)
161
 
162
   ;; PIC long branch sequences are never longer than 100 bytes.
163
   (MAX_PIC_BRANCH_LENGTH       100)
164
  ]
165
)
166
 
167
(include "predicates.md")
168
(include "constraints.md")
169
 
170
;; ....................
171
;;
172
;;      Attributes
173
;;
174
;; ....................
175
 
176
(define_attr "got" "unset,xgot_high,load"
177
  (const_string "unset"))
178
 
179
;; For jal instructions, this attribute is DIRECT when the target address
180
;; is symbolic and INDIRECT when it is a register.
181
(define_attr "jal" "unset,direct,indirect"
182
  (const_string "unset"))
183
 
184
;; This attribute is YES if the instruction is a jal macro (not a
185
;; real jal instruction).
186
;;
187
;; jal is always a macro for TARGET_CALL_CLOBBERED_GP because it includes
188
;; an instruction to restore $gp.  Direct jals are also macros for
189
;; !TARGET_ABSOLUTE_JUMPS because they first load the target address
190
;; into a register.
191
(define_attr "jal_macro" "no,yes"
192
  (cond [(eq_attr "jal" "direct")
193
         (symbol_ref "(TARGET_CALL_CLOBBERED_GP || !TARGET_ABSOLUTE_JUMPS
194
                       ? JAL_MACRO_YES : JAL_MACRO_NO)")
195
         (eq_attr "jal" "indirect")
196
         (symbol_ref "(TARGET_CALL_CLOBBERED_GP
197
                       ? JAL_MACRO_YES : JAL_MACRO_NO)")]
198
        (const_string "no")))
199
 
200
;; Classification of moves, extensions and truncations.  Most values
201
;; are as for "type" (see below) but there are also the following
202
;; move-specific values:
203
;;
204
;; constN       move an N-constraint integer into a MIPS16 register
205
;; sll0         "sll DEST,SRC,0", which on 64-bit targets is guaranteed
206
;;              to produce a sign-extended DEST, even if SRC is not
207
;;              properly sign-extended
208
;; ext_ins      EXT, DEXT, INS or DINS instruction
209
;; andi         a single ANDI instruction
210
;; loadpool     move a constant into a MIPS16 register by loading it
211
;;              from the pool
212
;; shift_shift  a shift left followed by a shift right
213
;;
214
;; This attribute is used to determine the instruction's length and
215
;; scheduling type.  For doubleword moves, the attribute always describes
216
;; the split instructions; in some cases, it is more appropriate for the
217
;; scheduling type to be "multi" instead.
218
(define_attr "move_type"
219
  "unknown,load,fpload,store,fpstore,mtc,mfc,mtlo,mflo,imul,move,fmove,
220
   const,constN,signext,ext_ins,logical,arith,sll0,andi,loadpool,
221
   shift_shift"
222
  (const_string "unknown"))
223
 
224
(define_attr "alu_type" "unknown,add,sub,not,nor,and,or,xor"
225
  (const_string "unknown"))
226
 
227
;; Main data type used by the insn
228
(define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF,FPSW"
229
  (const_string "unknown"))
230
 
231
;; True if the main data type is twice the size of a word.
232
(define_attr "dword_mode" "no,yes"
233
  (cond [(and (eq_attr "mode" "DI,DF")
234
              (not (match_test "TARGET_64BIT")))
235
         (const_string "yes")
236
 
237
         (and (eq_attr "mode" "TI,TF")
238
              (match_test "TARGET_64BIT"))
239
         (const_string "yes")]
240
        (const_string "no")))
241
 
242
;; Attributes describing a sync loop.  These loops have the form:
243
;;
244
;;       if (RELEASE_BARRIER == YES) sync
245
;;    1: OLDVAL = *MEM
246
;;       if ((OLDVAL & INCLUSIVE_MASK) != REQUIRED_OLDVAL) goto 2
247
;;         CMP  = 0 [delay slot]
248
;;       $TMP1 = OLDVAL & EXCLUSIVE_MASK
249
;;       $TMP2 = INSN1 (OLDVAL, INSN1_OP2)
250
;;       $TMP3 = INSN2 ($TMP2, INCLUSIVE_MASK)
251
;;       $AT |= $TMP1 | $TMP3
252
;;       if (!commit (*MEM = $AT)) goto 1.
253
;;         if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot]
254
;;       CMP  = 1
255
;;       if (ACQUIRE_BARRIER == YES) sync
256
;;    2:
257
;;
258
;; where "$" values are temporaries and where the other values are
259
;; specified by the attributes below.  Values are specified as operand
260
;; numbers and insns are specified as enums.  If no operand number is
261
;; specified, the following values are used instead:
262
;;
263
;;    - OLDVAL: $AT
264
;;    - CMP: NONE
265
;;    - NEWVAL: $AT
266
;;    - INCLUSIVE_MASK: -1
267
;;    - REQUIRED_OLDVAL: OLDVAL & INCLUSIVE_MASK
268
;;    - EXCLUSIVE_MASK: 0
269
;;
270
;; MEM and INSN1_OP2 are required.
271
;;
272
;; Ideally, the operand attributes would be integers, with -1 meaning "none",
273
;; but the gen* programs don't yet support that.
274
(define_attr "sync_mem" "none,0,1,2,3,4,5" (const_string "none"))
275
(define_attr "sync_oldval" "none,0,1,2,3,4,5" (const_string "none"))
276
(define_attr "sync_cmp" "none,0,1,2,3,4,5" (const_string "none"))
277
(define_attr "sync_newval" "none,0,1,2,3,4,5" (const_string "none"))
278
(define_attr "sync_inclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
279
(define_attr "sync_exclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
280
(define_attr "sync_required_oldval" "none,0,1,2,3,4,5" (const_string "none"))
281
(define_attr "sync_insn1_op2" "none,0,1,2,3,4,5" (const_string "none"))
282
(define_attr "sync_insn1" "move,li,addu,addiu,subu,and,andi,or,ori,xor,xori"
283
  (const_string "move"))
284
(define_attr "sync_insn2" "nop,and,xor,not"
285
  (const_string "nop"))
286
;; Memory model specifier.
287
;; "0"-"9" values specify the operand that stores the memory model value.
288
;; "10" specifies MEMMODEL_ACQ_REL,
289
;; "11" specifies MEMMODEL_ACQUIRE.
290
(define_attr "sync_memmodel" "" (const_int 10))
291
 
292
;; Accumulator operand for madd patterns.
293
(define_attr "accum_in" "none,0,1,2,3,4,5" (const_string "none"))
294
 
295
;; Classification of each insn.
296
;; branch       conditional branch
297
;; jump         unconditional jump
298
;; call         unconditional call
299
;; load         load instruction(s)
300
;; fpload       floating point load
301
;; fpidxload    floating point indexed load
302
;; store        store instruction(s)
303
;; fpstore      floating point store
304
;; fpidxstore   floating point indexed store
305
;; prefetch     memory prefetch (register + offset)
306
;; prefetchx    memory indexed prefetch (register + register)
307
;; condmove     conditional moves
308
;; mtc          transfer to coprocessor
309
;; mfc          transfer from coprocessor
310
;; mthi         transfer to a hi register
311
;; mtlo         transfer to a lo register
312
;; mfhi         transfer from a hi register
313
;; mflo         transfer from a lo register
314
;; const        load constant
315
;; arith        integer arithmetic instructions
316
;; logical      integer logical instructions
317
;; shift        integer shift instructions
318
;; slt          set less than instructions
319
;; signext      sign extend instructions
320
;; clz          the clz and clo instructions
321
;; pop          the pop instruction
322
;; trap         trap if instructions
323
;; imul         integer multiply 2 operands
324
;; imul3        integer multiply 3 operands
325
;; imul3nc      integer multiply 3 operands without clobbering HI/LO
326
;; imadd        integer multiply-add
327
;; idiv         integer divide 2 operands
328
;; idiv3        integer divide 3 operands
329
;; move         integer register move ({,D}ADD{,U} with rt = 0)
330
;; fmove        floating point register move
331
;; fadd         floating point add/subtract
332
;; fmul         floating point multiply
333
;; fmadd        floating point multiply-add
334
;; fdiv         floating point divide
335
;; frdiv        floating point reciprocal divide
336
;; frdiv1       floating point reciprocal divide step 1
337
;; frdiv2       floating point reciprocal divide step 2
338
;; fabs         floating point absolute value
339
;; fneg         floating point negation
340
;; fcmp         floating point compare
341
;; fcvt         floating point convert
342
;; fsqrt        floating point square root
343
;; frsqrt       floating point reciprocal square root
344
;; frsqrt1      floating point reciprocal square root step1
345
;; frsqrt2      floating point reciprocal square root step2
346
;; dspmac       DSP MAC instructions not saturating the accumulator
347
;; dspmacsat    DSP MAC instructions that saturate the accumulator
348
;; accext       DSP accumulator extract instructions
349
;; accmod       DSP accumulator modify instructions
350
;; dspalu       DSP ALU instructions not saturating the result
351
;; dspalusat    DSP ALU instructions that saturate the result
352
;; multi        multiword sequence (or user asm statements)
353
;; atomic       atomic memory update instruction
354
;; syncloop     memory atomic operation implemented as a sync loop
355
;; nop          no operation
356
;; ghost        an instruction that produces no real code
357
;; multimem     microMIPS multiword load and store
358
(define_attr "type"
359
  "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,
360
   prefetch,prefetchx,condmove,mtc,mfc,mthi,mtlo,mfhi,mflo,const,arith,logical,
361
   shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move,
362
   fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,
363
   frsqrt,frsqrt1,frsqrt2,dspmac,dspmacsat,accext,accmod,dspalu,dspalusat,
364
   multi,atomic,syncloop,nop,ghost,multimem"
365
  (cond [(eq_attr "jal" "!unset") (const_string "call")
366
         (eq_attr "got" "load") (const_string "load")
367
 
368
         (eq_attr "alu_type" "add,sub") (const_string "arith")
369
 
370
         (eq_attr "alu_type" "not,nor,and,or,xor") (const_string "logical")
371
 
372
         ;; If a doubleword move uses these expensive instructions,
373
         ;; it is usually better to schedule them in the same way
374
         ;; as the singleword form, rather than as "multi".
375
         (eq_attr "move_type" "load") (const_string "load")
376
         (eq_attr "move_type" "fpload") (const_string "fpload")
377
         (eq_attr "move_type" "store") (const_string "store")
378
         (eq_attr "move_type" "fpstore") (const_string "fpstore")
379
         (eq_attr "move_type" "mtc") (const_string "mtc")
380
         (eq_attr "move_type" "mfc") (const_string "mfc")
381
         (eq_attr "move_type" "mtlo") (const_string "mtlo")
382
         (eq_attr "move_type" "mflo") (const_string "mflo")
383
 
384
         ;; These types of move are always single insns.
385
         (eq_attr "move_type" "imul") (const_string "imul")
386
         (eq_attr "move_type" "fmove") (const_string "fmove")
387
         (eq_attr "move_type" "loadpool") (const_string "load")
388
         (eq_attr "move_type" "signext") (const_string "signext")
389
         (eq_attr "move_type" "ext_ins") (const_string "arith")
390
         (eq_attr "move_type" "arith") (const_string "arith")
391
         (eq_attr "move_type" "logical") (const_string "logical")
392
         (eq_attr "move_type" "sll0") (const_string "shift")
393
         (eq_attr "move_type" "andi") (const_string "logical")
394
 
395
         ;; These types of move are always split.
396
         (eq_attr "move_type" "constN,shift_shift")
397
           (const_string "multi")
398
 
399
         ;; These types of move are split for doubleword modes only.
400
         (and (eq_attr "move_type" "move,const")
401
              (eq_attr "dword_mode" "yes"))
402
           (const_string "multi")
403
         (eq_attr "move_type" "move") (const_string "move")
404
         (eq_attr "move_type" "const") (const_string "const")
405
         (eq_attr "sync_mem" "!none") (const_string "syncloop")]
406
        (const_string "unknown")))
407
 
408
;; Mode for conversion types (fcvt)
409
;; I2S          integer to float single (SI/DI to SF)
410
;; I2D          integer to float double (SI/DI to DF)
411
;; S2I          float to integer (SF to SI/DI)
412
;; D2I          float to integer (DF to SI/DI)
413
;; D2S          double to float single
414
;; S2D          float single to double
415
 
416
(define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D"
417
  (const_string "unknown"))
418
 
419
;; Is this an extended instruction in mips16 mode?
420
(define_attr "extended_mips16" "no,yes"
421
  (if_then_else (ior ;; In general, constant-pool loads are extended
422
                     ;; instructions.  We don't yet optimize for 16-bit
423
                     ;; PC-relative references.
424
                     (eq_attr "move_type" "sll0,loadpool")
425
                     (eq_attr "jal" "direct")
426
                     (eq_attr "got" "load"))
427
                (const_string "yes")
428
                (const_string "no")))
429
 
430
(define_attr "compression" "none,all,micromips"
431
  (const_string "none"))
432
 
433
(define_attr "enabled" "no,yes"
434
  (if_then_else (ior (eq_attr "compression" "all,none")
435
                     (and (eq_attr "compression" "micromips")
436
                          (match_test "TARGET_MICROMIPS")))
437
                (const_string "yes")
438
                (const_string "no")))
439
 
440
;; The number of individual instructions that a non-branch pattern generates,
441
;; using units of BASE_INSN_LENGTH.
442
(define_attr "insn_count" ""
443
  (cond [;; "Ghost" instructions occupy no space.
444
         (eq_attr "type" "ghost")
445
         (const_int 0)
446
 
447
         ;; Extended instructions count as 2.
448
         (and (eq_attr "extended_mips16" "yes")
449
              (match_test "TARGET_MIPS16"))
450
         (const_int 2)
451
 
452
         ;; A GOT load followed by an add of $gp.  This is not used for MIPS16.
453
         (eq_attr "got" "xgot_high")
454
         (const_int 2)
455
 
456
         ;; SHIFT_SHIFTs are decomposed into two separate instructions.
457
         ;; They are extended instructions on MIPS16 targets.
458
         (eq_attr "move_type" "shift_shift")
459
         (if_then_else (match_test "TARGET_MIPS16")
460
                       (const_int 4)
461
                       (const_int 2))
462
 
463
         ;; Check for doubleword moves that are decomposed into two
464
         ;; instructions.  The individual instructions are unextended
465
         ;; MIPS16 ones.
466
         (and (eq_attr "move_type" "mtc,mfc,mtlo,mflo,move")
467
              (eq_attr "dword_mode" "yes"))
468
         (const_int 2)
469
 
470
         ;; Constants, loads and stores are handled by external routines.
471
         (and (eq_attr "move_type" "const,constN")
472
              (eq_attr "dword_mode" "yes"))
473
         (symbol_ref "mips_split_const_insns (operands[1])")
474
         (eq_attr "move_type" "const,constN")
475
         (symbol_ref "mips_const_insns (operands[1])")
476
         (eq_attr "move_type" "load,fpload")
477
         (symbol_ref "mips_load_store_insns (operands[1], insn)")
478
         (eq_attr "move_type" "store,fpstore")
479
         (symbol_ref "mips_load_store_insns (operands[0], insn)
480
                      + (TARGET_FIX_24K ? 1 : 0)")
481
 
482
         ;; In the worst case, a call macro will take 8 instructions:
483
         ;;
484
         ;;     lui $25,%call_hi(FOO)
485
         ;;     addu $25,$25,$28
486
         ;;     lw $25,%call_lo(FOO)($25)
487
         ;;     nop
488
         ;;     jalr $25
489
         ;;     nop
490
         ;;     lw $gp,X($sp)
491
         ;;     nop
492
         (eq_attr "jal_macro" "yes")
493
         (const_int 8)
494
 
495
         ;; Various VR4120 errata require a nop to be inserted after a macc
496
         ;; instruction.  The assembler does this for us, so account for
497
         ;; the worst-case length here.
498
         (and (eq_attr "type" "imadd")
499
              (match_test "TARGET_FIX_VR4120"))
500
         (const_int 2)
501
 
502
         ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
503
         ;; the result of the second one is missed.  The assembler should work
504
         ;; around this by inserting a nop after the first dmult.
505
         (and (eq_attr "type" "imul,imul3")
506
              (eq_attr "mode" "DI")
507
              (match_test "TARGET_FIX_VR4120"))
508
         (const_int 2)
509
 
510
         (eq_attr "type" "idiv,idiv3")
511
         (symbol_ref "mips_idiv_insns ()")
512
 
513
         (not (eq_attr "sync_mem" "none"))
514
         (symbol_ref "mips_sync_loop_insns (insn, operands)")]
515
        (const_int 1)))
516
 
517
;; Length of instruction in bytes.  The default is derived from "insn_count",
518
;; but there are special cases for branches (which must be handled here)
519
;; and for compressed single instructions.
520
(define_attr "length" ""
521
   (cond [(and (eq_attr "compression" "micromips,all")
522
               (eq_attr "dword_mode" "no")
523
               (match_test "TARGET_MICROMIPS"))
524
          (const_int 2)
525
 
526
          ;; Direct microMIPS branch instructions have a range of
527
          ;; [-0x10000,0xfffe], otherwise the range is [-0x20000,0x1fffc].
528
          ;; If a branch is outside this range, we have a choice of two
529
          ;; sequences.
530
          ;;
531
          ;; For PIC, an out-of-range branch like:
532
          ;;
533
          ;;    bne     r1,r2,target
534
          ;;    dslot
535
          ;;
536
          ;; becomes the equivalent of:
537
          ;;
538
          ;;    beq     r1,r2,1f
539
          ;;    dslot
540
          ;;    la      $at,target
541
          ;;    jr      $at
542
          ;;    nop
543
          ;; 1:
544
          ;;
545
          ;; The non-PIC case is similar except that we use a direct
546
          ;; jump instead of an la/jr pair.  Since the target of this
547
          ;; jump is an absolute 28-bit bit address (the other bits
548
          ;; coming from the address of the delay slot) this form cannot
549
          ;; cross a 256MB boundary.  We could provide the option of
550
          ;; using la/jr in this case too, but we do not do so at
551
          ;; present.
552
          ;;
553
          ;; The value we specify here does not account for the delay slot
554
          ;; instruction, whose length is added separately.  If the RTL
555
          ;; pattern has no explicit delay slot, mips_adjust_insn_length
556
          ;; will add the length of the implicit nop.  The range of
557
          ;; [-0x20000, 0x1fffc] from the address of the delay slot
558
          ;; therefore translates to a range of:
559
          ;;
560
          ;;    [-(0x20000 - sizeof (branch)), 0x1fffc - sizeof (slot)]
561
          ;; == [-0x1fffc, 0x1fff8]
562
          ;;
563
          ;; from the shorten_branches reference address.
564
          (and (eq_attr "type" "branch")
565
               (not (match_test "TARGET_MIPS16")))
566
          (cond [;; Any variant can handle the 17-bit range.
567
                 (and (le (minus (match_dup 0) (pc)) (const_int 65532))
568
                      (le (minus (pc) (match_dup 0)) (const_int 65534)))
569
                   (const_int 4)
570
 
571
                 ;; The 18-bit range is OK other than for microMIPS.
572
                 (and (not (match_test "TARGET_MICROMIPS"))
573
                      (and (le (minus (match_dup 0) (pc)) (const_int 131064))
574
                           (le (minus (pc) (match_dup 0)) (const_int 131068))))
575
                   (const_int 4)
576
 
577
                 ;; The non-PIC case: branch, first delay slot, and J.
578
                 (match_test "TARGET_ABSOLUTE_JUMPS")
579
                   (const_int 12)]
580
 
581
                 ;; Use MAX_PIC_BRANCH_LENGTH as a (gross) overestimate.
582
                 ;; mips_adjust_insn_length substitutes the correct length.
583
                 ;;
584
                 ;; Note that we can't simply use (symbol_ref ...) here
585
                 ;; because genattrtab needs to know the maximum length
586
                 ;; of an insn.
587
                 (const_int MAX_PIC_BRANCH_LENGTH))
588
 
589
          ;; An unextended MIPS16 branch has a range of [-0x100, 0xfe]
590
          ;; from the address of the following instruction, which leads
591
          ;; to a range of:
592
          ;;
593
          ;;    [-(0x100 - sizeof (branch)), 0xfe]
594
          ;; == [-0xfe, 0xfe]
595
          ;;
596
          ;; from the shorten_branches reference address.  Extended branches
597
          ;; likewise have a range of [-0x10000, 0xfffe] from the address
598
          ;; of the following instruction, which leads to a range of:
599
          ;;
600
          ;;    [-(0x10000 - sizeof (branch)), 0xfffe]
601
          ;; == [-0xfffc, 0xfffe]
602
          ;;
603
          ;; from the reference address.
604
          ;;
605
          ;; When a branch is out of range, mips_reorg splits it into a form
606
          ;; that uses in-range branches.  There are four basic sequences:
607
          ;;
608
          ;; (1) Absolute addressing with a readable text segment
609
          ;;     (32-bit addresses):
610
          ;;
611
          ;;     b... foo               2 bytes
612
          ;;     move $1,$2             2 bytes
613
          ;;     lw $2,label            2 bytes
614
          ;;     jr $2                  2 bytes
615
          ;;     move $2,$1             2 bytes
616
          ;;     .align 2               0 or 2 bytes
617
          ;; label:
618
          ;;     .word target           4 bytes
619
          ;; foo:
620
          ;;                            (16 bytes in the worst case)
621
          ;;
622
          ;; (2) Absolute addressing with a readable text segment
623
          ;;     (64-bit addresses):
624
          ;;
625
          ;;     b... foo               2 bytes
626
          ;;     move $1,$2             2 bytes
627
          ;;     ld $2,label            2 bytes
628
          ;;     jr $2                  2 bytes
629
          ;;     move $2,$1             2 bytes
630
          ;;     .align 3               0 to 6 bytes
631
          ;; label:
632
          ;;     .dword target          8 bytes
633
          ;; foo:
634
          ;;                            (24 bytes in the worst case)
635
          ;;
636
          ;; (3) Absolute addressing without a readable text segment
637
          ;;     (which requires 32-bit addresses at present):
638
          ;;
639
          ;;     b... foo               2 bytes
640
          ;;     move $1,$2             2 bytes
641
          ;;     lui $2,%hi(target)     4 bytes
642
          ;;     sll $2,8               2 bytes
643
          ;;     sll $2,8               2 bytes
644
          ;;     addiu $2,%lo(target)   4 bytes
645
          ;;     jr $2                  2 bytes
646
          ;;     move $2,$1             2 bytes
647
          ;; foo:
648
          ;;                            (20 bytes)
649
          ;;
650
          ;; (4) PIC addressing (which requires 32-bit addresses at present):
651
          ;;
652
          ;;     b... foo               2 bytes
653
          ;;     move $1,$2             2 bytes
654
          ;;     lw $2,cprestore        0, 2 or 4 bytes
655
          ;;     lw $2,%got(target)($2) 4 bytes
656
          ;;     addiu $2,%lo(target)   4 bytes
657
          ;;     jr $2                  2 bytes
658
          ;;     move $2,$1             2 bytes
659
          ;; foo:
660
          ;;                            (20 bytes in the worst case)
661
          (and (eq_attr "type" "branch")
662
               (match_test "TARGET_MIPS16"))
663
          (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
664
                      (le (minus (pc) (match_dup 0)) (const_int 254)))
665
                 (const_int 2)
666
                 (and (le (minus (match_dup 0) (pc)) (const_int 65534))
667
                      (le (minus (pc) (match_dup 0)) (const_int 65532)))
668
                 (const_int 4)
669
                 (and (match_test "TARGET_ABICALLS")
670
                      (not (match_test "TARGET_ABSOLUTE_ABICALLS")))
671
                 (const_int 20)
672
                 (match_test "Pmode == SImode")
673
                 (const_int 16)
674
                 ] (const_int 24))]
675
         (symbol_ref "get_attr_insn_count (insn) * BASE_INSN_LENGTH")))
676
 
677
;; Attribute describing the processor.
678
(define_enum_attr "cpu" "processor"
679
  (const (symbol_ref "mips_tune")))
680
 
681
;; The type of hardware hazard associated with this instruction.
682
;; DELAY means that the next instruction cannot read the result
683
;; of this one.  HILO means that the next two instructions cannot
684
;; write to HI or LO.
685
(define_attr "hazard" "none,delay,hilo"
686
  (cond [(and (eq_attr "type" "load,fpload,fpidxload")
687
              (match_test "ISA_HAS_LOAD_DELAY"))
688
         (const_string "delay")
689
 
690
         (and (eq_attr "type" "mfc,mtc")
691
              (match_test "ISA_HAS_XFER_DELAY"))
692
         (const_string "delay")
693
 
694
         (and (eq_attr "type" "fcmp")
695
              (match_test "ISA_HAS_FCMP_DELAY"))
696
         (const_string "delay")
697
 
698
         ;; The r4000 multiplication patterns include an mflo instruction.
699
         (and (eq_attr "type" "imul")
700
              (match_test "TARGET_FIX_R4000"))
701
         (const_string "hilo")
702
 
703
         (and (eq_attr "type" "mfhi,mflo")
704
              (not (match_test "ISA_HAS_HILO_INTERLOCKS")))
705
         (const_string "hilo")]
706
        (const_string "none")))
707
 
708
;; Can the instruction be put into a delay slot?
709
(define_attr "can_delay" "no,yes"
710
  (if_then_else (and (eq_attr "type" "!branch,call,jump")
711
                     (eq_attr "hazard" "none")
712
                     (match_test "get_attr_insn_count (insn) == 1"))
713
                (const_string "yes")
714
                (const_string "no")))
715
 
716
;; Attribute defining whether or not we can use the branch-likely
717
;; instructions.
718
(define_attr "branch_likely" "no,yes"
719
  (if_then_else (match_test "GENERATE_BRANCHLIKELY")
720
                (const_string "yes")
721
                (const_string "no")))
722
 
723
;; True if an instruction might assign to hi or lo when reloaded.
724
;; This is used by the TUNE_MACC_CHAINS code.
725
(define_attr "may_clobber_hilo" "no,yes"
726
  (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthi,mtlo")
727
                (const_string "yes")
728
                (const_string "no")))
729
 
730
;; Describe a user's asm statement.
731
(define_asm_attributes
732
  [(set_attr "type" "multi")
733
   (set_attr "can_delay" "no")])
734
 
735
;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
736
;; from the same template.
737
(define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
738
 
739
;; A copy of GPR that can be used when a pattern has two independent
740
;; modes.
741
(define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")])
742
 
743
(define_mode_iterator MOVEP1 [SI SF])
744
(define_mode_iterator MOVEP2 [SI SF])
745
 
746
;; This mode iterator allows :HILO to be used as the mode of the
747
;; concatenated HI and LO registers.
748
(define_mode_iterator HILO [(DI "!TARGET_64BIT") (TI "TARGET_64BIT")])
749
 
750
;; This mode iterator allows :P to be used for patterns that operate on
751
;; pointer-sized quantities.  Exactly one of the two alternatives will match.
752
(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
753
 
754
;; This mode iterator allows :MOVECC to be used anywhere that a
755
;; conditional-move-type condition is needed.
756
(define_mode_iterator MOVECC [SI (DI "TARGET_64BIT")
757
                              (CC "TARGET_HARD_FLOAT
758
                                   && !TARGET_LOONGSON_2EF
759
                                   && !TARGET_MIPS5900")])
760
 
761
;; 32-bit integer moves for which we provide move patterns.
762
(define_mode_iterator IMOVE32
763
  [SI
764
   (V2HI "TARGET_DSP")
765
   (V4QI "TARGET_DSP")
766
   (V2HQ "TARGET_DSP")
767
   (V2UHQ "TARGET_DSP")
768
   (V2HA "TARGET_DSP")
769
   (V2UHA "TARGET_DSP")
770
   (V4QQ "TARGET_DSP")
771
   (V4UQQ "TARGET_DSP")])
772
 
773
;; 64-bit modes for which we provide move patterns.
774
(define_mode_iterator MOVE64
775
  [DI DF
776
   (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")
777
   (V2SI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")
778
   (V4HI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")
779
   (V8QI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")])
780
 
781
;; 128-bit modes for which we provide move patterns on 64-bit targets.
782
(define_mode_iterator MOVE128 [TI TF])
783
 
784
;; This mode iterator allows the QI and HI extension patterns to be
785
;; defined from the same template.
786
(define_mode_iterator SHORT [QI HI])
787
 
788
;; Likewise the 64-bit truncate-and-shift patterns.
789
(define_mode_iterator SUBDI [QI HI SI])
790
 
791
;; This mode iterator allows :ANYF to be used wherever a scalar or vector
792
;; floating-point mode is allowed.
793
(define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
794
                            (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
795
                            (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")])
796
 
797
;; Like ANYF, but only applies to scalar modes.
798
(define_mode_iterator SCALARF [(SF "TARGET_HARD_FLOAT")
799
                               (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
800
 
801
;; A floating-point mode for which moves involving FPRs may need to be split.
802
(define_mode_iterator SPLITF
803
  [(DF "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
804
   (DI "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
805
   (V2SF "!TARGET_64BIT && TARGET_PAIRED_SINGLE_FLOAT")
806
   (V2SI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
807
   (V4HI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
808
   (V8QI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
809
   (TF "TARGET_64BIT && TARGET_FLOAT64")])
810
 
811
;; In GPR templates, a string like "subu" will expand to "subu" in the
812
;; 32-bit version and "dsubu" in the 64-bit version.
813
(define_mode_attr d [(SI "") (DI "d")
814
                     (QQ "") (HQ "") (SQ "") (DQ "d")
815
                     (UQQ "") (UHQ "") (USQ "") (UDQ "d")
816
                     (HA "") (SA "") (DA "d")
817
                     (UHA "") (USA "") (UDA "d")])
818
 
819
;; Same as d but upper-case.
820
(define_mode_attr D [(SI "") (DI "D")
821
                     (QQ "") (HQ "") (SQ "") (DQ "D")
822
                     (UQQ "") (UHQ "") (USQ "") (UDQ "D")
823
                     (HA "") (SA "") (DA "D")
824
                     (UHA "") (USA "") (UDA "D")])
825
 
826
;; This attribute gives the length suffix for a load or store instruction.
827
;; The same suffixes work for zero and sign extensions.
828
(define_mode_attr size [(QI "b") (HI "h") (SI "w") (DI "d")])
829
(define_mode_attr SIZE [(QI "B") (HI "H") (SI "W") (DI "D")])
830
 
831
;; This attributes gives the mode mask of a SHORT.
832
(define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
833
 
834
;; Mode attributes for GPR loads.
835
(define_mode_attr load [(SI "lw") (DI "ld")])
836
;; Instruction names for stores.
837
(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd")])
838
 
839
;; Similarly for MIPS IV indexed FPR loads and stores.
840
(define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
841
(define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
842
 
843
;; The unextended ranges of the MIPS16 addiu and daddiu instructions
844
;; are different.  Some forms of unextended addiu have an 8-bit immediate
845
;; field but the equivalent daddiu has only a 5-bit field.
846
(define_mode_attr si8_di5 [(SI "8") (DI "5")])
847
 
848
;; This attribute gives the best constraint to use for registers of
849
;; a given mode.
850
(define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
851
 
852
;; This attribute gives the format suffix for floating-point operations.
853
(define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
854
 
855
;; This attribute gives the upper-case mode name for one unit of a
856
;; floating-point mode.
857
(define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
858
 
859
;; This attribute gives the integer mode that has the same size as a
860
;; fixed-point mode.
861
(define_mode_attr IMODE [(QQ "QI") (HQ "HI") (SQ "SI") (DQ "DI")
862
                         (UQQ "QI") (UHQ "HI") (USQ "SI") (UDQ "DI")
863
                         (HA "HI") (SA "SI") (DA "DI")
864
                         (UHA "HI") (USA "SI") (UDA "DI")
865
                         (V4UQQ "SI") (V2UHQ "SI") (V2UHA "SI")
866
                         (V2HQ "SI") (V2HA "SI")])
867
 
868
;; This attribute gives the integer mode that has half the size of
869
;; the controlling mode.
870
(define_mode_attr HALFMODE [(DF "SI") (DI "SI") (V2SF "SI")
871
                            (V2SI "SI") (V4HI "SI") (V8QI "SI")
872
                            (TF "DI")])
873
 
874
;; This attribute works around the early SB-1 rev2 core "F2" erratum:
875
;;
876
;; In certain cases, div.s and div.ps may have a rounding error
877
;; and/or wrong inexact flag.
878
;;
879
;; Therefore, we only allow div.s if not working around SB-1 rev2
880
;; errata or if a slight loss of precision is OK.
881
(define_mode_attr divide_condition
882
  [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")
883
   (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")])
884
 
885
;; This attribute gives the conditions under which SQRT.fmt instructions
886
;; can be used.
887
(define_mode_attr sqrt_condition
888
  [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")])
889
 
890
;; This code iterator allows signed and unsigned widening multiplications
891
;; to use the same template.
892
(define_code_iterator any_extend [sign_extend zero_extend])
893
 
894
;; This code iterator allows the two right shift instructions to be
895
;; generated from the same template.
896
(define_code_iterator any_shiftrt [ashiftrt lshiftrt])
897
 
898
;; This code iterator allows the three shift instructions to be generated
899
;; from the same template.
900
(define_code_iterator any_shift [ashift ashiftrt lshiftrt])
901
 
902
;; This code iterator allows unsigned and signed division to be generated
903
;; from the same template.
904
(define_code_iterator any_div [div udiv])
905
 
906
;; This code iterator allows unsigned and signed modulus to be generated
907
;; from the same template.
908
(define_code_iterator any_mod [mod umod])
909
 
910
;; This code iterator allows all native floating-point comparisons to be
911
;; generated from the same template.
912
(define_code_iterator fcond [unordered uneq unlt unle eq lt le])
913
 
914
;; This code iterator is used for comparisons that can be implemented
915
;; by swapping the operands.
916
(define_code_iterator swapped_fcond [ge gt unge ungt])
917
 
918
;; Equality operators.
919
(define_code_iterator equality_op [eq ne])
920
 
921
;; These code iterators allow the signed and unsigned scc operations to use
922
;; the same template.
923
(define_code_iterator any_gt [gt gtu])
924
(define_code_iterator any_ge [ge geu])
925
(define_code_iterator any_lt [lt ltu])
926
(define_code_iterator any_le [le leu])
927
 
928
(define_code_iterator any_return [return simple_return])
929
 
930
;;  expands to an empty string when doing a signed operation and
931
;; "u" when doing an unsigned operation.
932
(define_code_attr u [(sign_extend "") (zero_extend "u")
933
                     (div "") (udiv "u")
934
                     (mod "") (umod "u")
935
                     (gt "") (gtu "u")
936
                     (ge "") (geu "u")
937
                     (lt "") (ltu "u")
938
                     (le "") (leu "u")])
939
 
940
;;  is like  except uppercase.
941
(define_code_attr U [(sign_extend "") (zero_extend "U")])
942
 
943
;;  is like , but the signed form expands to "s" rather than "".
944
(define_code_attr su [(sign_extend "s") (zero_extend "u")])
945
 
946
;;  expands to the name of the optab for a particular code.
947
(define_code_attr optab [(ashift "ashl")
948
                         (ashiftrt "ashr")
949
                         (lshiftrt "lshr")
950
                         (ior "ior")
951
                         (xor "xor")
952
                         (and "and")
953
                         (plus "add")
954
                         (minus "sub")
955
                         (return "return")
956
                         (simple_return "simple_return")])
957
 
958
;;  expands to the name of the insn that implements a particular code.
959
(define_code_attr insn [(ashift "sll")
960
                        (ashiftrt "sra")
961
                        (lshiftrt "srl")
962
                        (ior "or")
963
                        (xor "xor")
964
                        (and "and")
965
                        (plus "addu")
966
                        (minus "subu")])
967
 
968
;;  expands to the name of the insn that implements
969
;; a particular code to operate on immediate values.
970
(define_code_attr immediate_insn [(ior "ori")
971
                                  (xor "xori")
972
                                  (and "andi")])
973
 
974
(define_code_attr shift_compression [(ashift "micromips")
975
                                     (lshiftrt "micromips")
976
                                     (ashiftrt "none")])
977
 
978
;;  is the c.cond.fmt condition associated with a particular code.
979
(define_code_attr fcond [(unordered "un")
980
                         (uneq "ueq")
981
                         (unlt "ult")
982
                         (unle "ule")
983
                         (eq "eq")
984
                         (lt "lt")
985
                         (le "le")])
986
 
987
;; Similar, but for swapped conditions.
988
(define_code_attr swapped_fcond [(ge "le")
989
                                 (gt "lt")
990
                                 (unge "ule")
991
                                 (ungt "ult")])
992
 
993
;; The value of the bit when the branch is taken for branch_bit patterns.
994
;; Comparison is always against zero so this depends on the operator.
995
(define_code_attr bbv [(eq "0") (ne "1")])
996
 
997
;; This is the inverse value of bbv.
998
(define_code_attr bbinv [(eq "1") (ne "0")])
999
 
1000
;; .........................
1001
;;
1002
;;      Branch, call and jump delay slots
1003
;;
1004
;; .........................
1005
 
1006
(define_delay (and (eq_attr "type" "branch")
1007
                   (not (match_test "TARGET_MIPS16"))
1008
                   (eq_attr "branch_likely" "yes"))
1009
  [(eq_attr "can_delay" "yes")
1010
   (nil)
1011
   (eq_attr "can_delay" "yes")])
1012
 
1013
;; Branches that don't have likely variants do not annul on false.
1014
(define_delay (and (eq_attr "type" "branch")
1015
                   (not (match_test "TARGET_MIPS16"))
1016
                   (eq_attr "branch_likely" "no"))
1017
  [(eq_attr "can_delay" "yes")
1018
   (nil)
1019
   (nil)])
1020
 
1021
(define_delay (eq_attr "type" "jump")
1022
  [(eq_attr "can_delay" "yes")
1023
   (nil)
1024
   (nil)])
1025
 
1026
(define_delay (and (eq_attr "type" "call")
1027
                   (eq_attr "jal_macro" "no"))
1028
  [(eq_attr "can_delay" "yes")
1029
   (nil)
1030
   (nil)])
1031
 
1032
;; Pipeline descriptions.
1033
;;
1034
;; generic.md provides a fallback for processors without a specific
1035
;; pipeline description.  It is derived from the old define_function_unit
1036
;; version and uses the "alu" and "imuldiv" units declared below.
1037
;;
1038
;; Some of the processor-specific files are also derived from old
1039
;; define_function_unit descriptions and simply override the parts of
1040
;; generic.md that don't apply.  The other processor-specific files
1041
;; are self-contained.
1042
(define_automaton "alu,imuldiv")
1043
 
1044
(define_cpu_unit "alu" "alu")
1045
(define_cpu_unit "imuldiv" "imuldiv")
1046
 
1047
;; Ghost instructions produce no real code and introduce no hazards.
1048
;; They exist purely to express an effect on dataflow.
1049
(define_insn_reservation "ghost" 0
1050
  (eq_attr "type" "ghost")
1051
  "nothing")
1052
 
1053
(include "4k.md")
1054
(include "5k.md")
1055
(include "20kc.md")
1056
(include "24k.md")
1057
(include "74k.md")
1058
(include "3000.md")
1059
(include "4000.md")
1060
(include "4100.md")
1061
(include "4130.md")
1062
(include "4300.md")
1063
(include "4600.md")
1064
(include "5000.md")
1065
(include "5400.md")
1066
(include "5500.md")
1067
(include "6000.md")
1068
(include "7000.md")
1069
(include "9000.md")
1070
(include "10000.md")
1071
(include "loongson2ef.md")
1072
(include "loongson3a.md")
1073
(include "octeon.md")
1074
(include "sb1.md")
1075
(include "sr71k.md")
1076
(include "xlr.md")
1077
(include "xlp.md")
1078
(include "generic.md")
1079
 
1080
;;
1081
;;  ....................
1082
;;
1083
;;      CONDITIONAL TRAPS
1084
;;
1085
;;  ....................
1086
;;
1087
 
1088
(define_insn "trap"
1089
  [(trap_if (const_int 1) (const_int 0))]
1090
  ""
1091
{
1092
  if (ISA_HAS_COND_TRAP)
1093
    return "teq\t$0,$0";
1094
  else if (TARGET_MIPS16)
1095
    return "break 0";
1096
  else
1097
    return "break";
1098
}
1099
  [(set_attr "type" "trap")])
1100
 
1101
(define_expand "ctrap4"
1102
  [(trap_if (match_operator 0 "comparison_operator"
1103
                            [(match_operand:GPR 1 "reg_or_0_operand")
1104
                             (match_operand:GPR 2 "arith_operand")])
1105
            (match_operand 3 "const_0_operand"))]
1106
  "ISA_HAS_COND_TRAP"
1107
{
1108
  mips_expand_conditional_trap (operands[0]);
1109
  DONE;
1110
})
1111
 
1112
(define_insn "*conditional_trap"
1113
  [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
1114
                                [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
1115
                                 (match_operand:GPR 2 "arith_operand" "dI")])
1116
            (const_int 0))]
1117
  "ISA_HAS_COND_TRAP"
1118
  "t%C0\t%z1,%2"
1119
  [(set_attr "type" "trap")])
1120
 
1121
;;
1122
;;  ....................
1123
;;
1124
;;      ADDITION
1125
;;
1126
;;  ....................
1127
;;
1128
 
1129
(define_insn "add3"
1130
  [(set (match_operand:ANYF 0 "register_operand" "=f")
1131
        (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
1132
                   (match_operand:ANYF 2 "register_operand" "f")))]
1133
  ""
1134
  "add.\t%0,%1,%2"
1135
  [(set_attr "type" "fadd")
1136
   (set_attr "mode" "")])
1137
 
1138
(define_expand "add3"
1139
  [(set (match_operand:GPR 0 "register_operand")
1140
        (plus:GPR (match_operand:GPR 1 "register_operand")
1141
                  (match_operand:GPR 2 "arith_operand")))]
1142
  "")
1143
 
1144
(define_insn "*add3"
1145
  [(set (match_operand:GPR 0 "register_operand" "=!u,d,!u,!u,!ks,!d,d")
1146
        (plus:GPR (match_operand:GPR 1 "register_operand" "!u,d,!u,!ks,!ks,0,d")
1147
                  (match_operand:GPR 2 "arith_operand" "!u,d,Uead,Uuw6,Uesp,Usb4,Q")))]
1148
  "!TARGET_MIPS16"
1149
{
1150
  if (which_alternative == 0
1151
      || which_alternative == 1)
1152
    return "addu\t%0,%1,%2";
1153
  else
1154
    return "addiu\t%0,%1,%2";
1155
}
1156
  [(set_attr "alu_type" "add")
1157
   (set_attr "compression" "micromips,*,micromips,micromips,micromips,micromips,*")
1158
   (set_attr "mode" "")])
1159
 
1160
(define_insn "*add3_mips16"
1161
  [(set (match_operand:GPR 0 "register_operand" "=ks,ks,d,d,d,d,d,d,d")
1162
        (plus:GPR (match_operand:GPR 1 "register_operand" "ks,ks,ks,ks,0,0,d,d,d")
1163
                  (match_operand:GPR 2 "arith_operand" "Usd8,Q,Uuw,Q,Usb,Q,Usb4,O,d")))]
1164
  "TARGET_MIPS16"
1165
  "@
1166
    addiu\t%0,%2
1167
    addiu\t%0,%2
1168
    addiu\t%0,%1,%2
1169
    addiu\t%0,%1,%2
1170
    addiu\t%0,%2
1171
    addiu\t%0,%2
1172
    addiu\t%0,%1,%2
1173
    addiu\t%0,%1,%2
1174
    addu\t%0,%1,%2"
1175
  [(set_attr "alu_type" "add")
1176
   (set_attr "mode" "")
1177
   (set_attr "extended_mips16" "no,yes,no,yes,no,yes,no,yes,no")])
1178
 
1179
;; On the mips16, we can sometimes split an add of a constant which is
1180
;; a 4 byte instruction into two adds which are both 2 byte
1181
;; instructions.  There are two cases: one where we are adding a
1182
;; constant plus a register to another register, and one where we are
1183
;; simply adding a constant to a register.
1184
 
1185
(define_split
1186
  [(set (match_operand:SI 0 "d_operand")
1187
        (plus:SI (match_dup 0)
1188
                 (match_operand:SI 1 "const_int_operand")))]
1189
  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1190
   && ((INTVAL (operands[1]) > 0x7f
1191
        && INTVAL (operands[1]) <= 0x7f + 0x7f)
1192
       || (INTVAL (operands[1]) < - 0x80
1193
           && INTVAL (operands[1]) >= - 0x80 - 0x80))"
1194
  [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
1195
   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
1196
{
1197
  HOST_WIDE_INT val = INTVAL (operands[1]);
1198
 
1199
  if (val >= 0)
1200
    {
1201
      operands[1] = GEN_INT (0x7f);
1202
      operands[2] = GEN_INT (val - 0x7f);
1203
    }
1204
  else
1205
    {
1206
      operands[1] = GEN_INT (- 0x80);
1207
      operands[2] = GEN_INT (val + 0x80);
1208
    }
1209
})
1210
 
1211
(define_split
1212
  [(set (match_operand:SI 0 "d_operand")
1213
        (plus:SI (match_operand:SI 1 "d_operand")
1214
                 (match_operand:SI 2 "const_int_operand")))]
1215
  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1216
   && REGNO (operands[0]) != REGNO (operands[1])
1217
   && ((INTVAL (operands[2]) > 0x7
1218
        && INTVAL (operands[2]) <= 0x7 + 0x7f)
1219
       || (INTVAL (operands[2]) < - 0x8
1220
           && INTVAL (operands[2]) >= - 0x8 - 0x80))"
1221
  [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
1222
   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
1223
{
1224
  HOST_WIDE_INT val = INTVAL (operands[2]);
1225
 
1226
  if (val >= 0)
1227
    {
1228
      operands[2] = GEN_INT (0x7);
1229
      operands[3] = GEN_INT (val - 0x7);
1230
    }
1231
  else
1232
    {
1233
      operands[2] = GEN_INT (- 0x8);
1234
      operands[3] = GEN_INT (val + 0x8);
1235
    }
1236
})
1237
 
1238
(define_split
1239
  [(set (match_operand:DI 0 "d_operand")
1240
        (plus:DI (match_dup 0)
1241
                 (match_operand:DI 1 "const_int_operand")))]
1242
  "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1243
   && ((INTVAL (operands[1]) > 0xf
1244
        && INTVAL (operands[1]) <= 0xf + 0xf)
1245
       || (INTVAL (operands[1]) < - 0x10
1246
           && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1247
  [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1248
   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1249
{
1250
  HOST_WIDE_INT val = INTVAL (operands[1]);
1251
 
1252
  if (val >= 0)
1253
    {
1254
      operands[1] = GEN_INT (0xf);
1255
      operands[2] = GEN_INT (val - 0xf);
1256
    }
1257
  else
1258
    {
1259
      operands[1] = GEN_INT (- 0x10);
1260
      operands[2] = GEN_INT (val + 0x10);
1261
    }
1262
})
1263
 
1264
(define_split
1265
  [(set (match_operand:DI 0 "d_operand")
1266
        (plus:DI (match_operand:DI 1 "d_operand")
1267
                 (match_operand:DI 2 "const_int_operand")))]
1268
  "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1269
   && REGNO (operands[0]) != REGNO (operands[1])
1270
   && ((INTVAL (operands[2]) > 0x7
1271
        && INTVAL (operands[2]) <= 0x7 + 0xf)
1272
       || (INTVAL (operands[2]) < - 0x8
1273
           && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1274
  [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1275
   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1276
{
1277
  HOST_WIDE_INT val = INTVAL (operands[2]);
1278
 
1279
  if (val >= 0)
1280
    {
1281
      operands[2] = GEN_INT (0x7);
1282
      operands[3] = GEN_INT (val - 0x7);
1283
    }
1284
  else
1285
    {
1286
      operands[2] = GEN_INT (- 0x8);
1287
      operands[3] = GEN_INT (val + 0x8);
1288
    }
1289
})
1290
 
1291
(define_insn "*addsi3_extended"
1292
  [(set (match_operand:DI 0 "register_operand" "=d,d")
1293
        (sign_extend:DI
1294
             (plus:SI (match_operand:SI 1 "register_operand" "d,d")
1295
                      (match_operand:SI 2 "arith_operand" "d,Q"))))]
1296
  "TARGET_64BIT && !TARGET_MIPS16"
1297
  "@
1298
    addu\t%0,%1,%2
1299
    addiu\t%0,%1,%2"
1300
  [(set_attr "alu_type" "add")
1301
   (set_attr "mode" "SI")])
1302
 
1303
;; Split this insn so that the addiu splitters can have a crack at it.
1304
;; Use a conservative length estimate until the split.
1305
(define_insn_and_split "*addsi3_extended_mips16"
1306
  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1307
        (sign_extend:DI
1308
             (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1309
                      (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
1310
  "TARGET_64BIT && TARGET_MIPS16"
1311
  "#"
1312
  "&& reload_completed"
1313
  [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
1314
  { operands[3] = gen_lowpart (SImode, operands[0]); }
1315
  [(set_attr "alu_type" "add")
1316
   (set_attr "mode" "SI")
1317
   (set_attr "extended_mips16" "yes")])
1318
 
1319
;; Combiner patterns for unsigned byte-add.
1320
 
1321
(define_insn "*baddu_si_eb"
1322
  [(set (match_operand:SI 0 "register_operand" "=d")
1323
        (zero_extend:SI
1324
         (subreg:QI
1325
          (plus:SI (match_operand:SI 1 "register_operand" "d")
1326
                   (match_operand:SI 2 "register_operand" "d")) 3)))]
1327
  "ISA_HAS_BADDU && BYTES_BIG_ENDIAN"
1328
  "baddu\\t%0,%1,%2"
1329
  [(set_attr "alu_type" "add")])
1330
 
1331
(define_insn "*baddu_si_el"
1332
  [(set (match_operand:SI 0 "register_operand" "=d")
1333
        (zero_extend:SI
1334
         (subreg:QI
1335
          (plus:SI (match_operand:SI 1 "register_operand" "d")
1336
                   (match_operand:SI 2 "register_operand" "d")) 0)))]
1337
  "ISA_HAS_BADDU && !BYTES_BIG_ENDIAN"
1338
  "baddu\\t%0,%1,%2"
1339
  [(set_attr "alu_type" "add")])
1340
 
1341
(define_insn "*baddu_di"
1342
  [(set (match_operand:GPR 0 "register_operand" "=d")
1343
        (zero_extend:GPR
1344
         (truncate:QI
1345
          (plus:DI (match_operand:DI 1 "register_operand" "d")
1346
                   (match_operand:DI 2 "register_operand" "d")))))]
1347
  "ISA_HAS_BADDU && TARGET_64BIT"
1348
  "baddu\\t%0,%1,%2"
1349
  [(set_attr "alu_type" "add")])
1350
 
1351
;;
1352
;;  ....................
1353
;;
1354
;;      SUBTRACTION
1355
;;
1356
;;  ....................
1357
;;
1358
 
1359
(define_insn "sub3"
1360
  [(set (match_operand:ANYF 0 "register_operand" "=f")
1361
        (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
1362
                    (match_operand:ANYF 2 "register_operand" "f")))]
1363
  ""
1364
  "sub.\t%0,%1,%2"
1365
  [(set_attr "type" "fadd")
1366
   (set_attr "mode" "")])
1367
 
1368
(define_insn "sub3"
1369
  [(set (match_operand:GPR 0 "register_operand" "=!u,d")
1370
        (minus:GPR (match_operand:GPR 1 "register_operand" "!u,d")
1371
                   (match_operand:GPR 2 "register_operand" "!u,d")))]
1372
  ""
1373
  "subu\t%0,%1,%2"
1374
  [(set_attr "alu_type" "sub")
1375
   (set_attr "compression" "micromips,*")
1376
   (set_attr "mode" "")])
1377
 
1378
(define_insn "*subsi3_extended"
1379
  [(set (match_operand:DI 0 "register_operand" "=d")
1380
        (sign_extend:DI
1381
            (minus:SI (match_operand:SI 1 "register_operand" "d")
1382
                      (match_operand:SI 2 "register_operand" "d"))))]
1383
  "TARGET_64BIT"
1384
  "subu\t%0,%1,%2"
1385
  [(set_attr "alu_type" "sub")
1386
   (set_attr "mode" "DI")])
1387
 
1388
;;
1389
;;  ....................
1390
;;
1391
;;      MULTIPLICATION
1392
;;
1393
;;  ....................
1394
;;
1395
 
1396
(define_expand "mul3"
1397
  [(set (match_operand:SCALARF 0 "register_operand")
1398
        (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
1399
                      (match_operand:SCALARF 2 "register_operand")))]
1400
  "!TARGET_NO_HW_MULT"
1401
  "")
1402
 
1403
(define_insn "*mul3"
1404
  [(set (match_operand:SCALARF 0 "register_operand" "=f")
1405
        (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1406
                      (match_operand:SCALARF 2 "register_operand" "f")))]
1407
  "!TARGET_4300_MUL_FIX"
1408
  "mul.\t%0,%1,%2"
1409
  [(set_attr "type" "fmul")
1410
   (set_attr "mode" "")])
1411
 
1412
;; Early VR4300 silicon has a CPU bug where multiplies with certain
1413
;; operands may corrupt immediately following multiplies. This is a
1414
;; simple fix to insert NOPs.
1415
 
1416
(define_insn "*mul3_r4300"
1417
  [(set (match_operand:SCALARF 0 "register_operand" "=f")
1418
        (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1419
                      (match_operand:SCALARF 2 "register_operand" "f")))]
1420
  "TARGET_4300_MUL_FIX"
1421
  "mul.\t%0,%1,%2\;nop"
1422
  [(set_attr "type" "fmul")
1423
   (set_attr "mode" "")
1424
   (set_attr "insn_count" "2")])
1425
 
1426
(define_insn "mulv2sf3"
1427
  [(set (match_operand:V2SF 0 "register_operand" "=f")
1428
        (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
1429
                   (match_operand:V2SF 2 "register_operand" "f")))]
1430
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
1431
  "mul.ps\t%0,%1,%2"
1432
  [(set_attr "type" "fmul")
1433
   (set_attr "mode" "SF")])
1434
 
1435
;; The original R4000 has a cpu bug.  If a double-word or a variable
1436
;; shift executes while an integer multiplication is in progress, the
1437
;; shift may give an incorrect result.  Avoid this by keeping the mflo
1438
;; with the mult on the R4000.
1439
;;
1440
;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
1441
;; (also valid for MIPS R4000MC processors):
1442
;;
1443
;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
1444
;;      this errata description.
1445
;;      The following code sequence causes the R4000 to incorrectly
1446
;;      execute the Double Shift Right Arithmetic 32 (dsra32)
1447
;;      instruction.  If the dsra32 instruction is executed during an
1448
;;      integer multiply, the dsra32 will only shift by the amount in
1449
;;      specified in the instruction rather than the amount plus 32
1450
;;      bits.
1451
;;      instruction 1:          mult    rs,rt           integer multiply
1452
;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
1453
;;                                                      right arithmetic + 32
1454
;;      Workaround: A dsra32 instruction placed after an integer
1455
;;      multiply should not be one of the 11 instructions after the
1456
;;      multiply instruction."
1457
;;
1458
;; and:
1459
;;
1460
;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
1461
;;      the following description.
1462
;;      All extended shifts (shift by n+32) and variable shifts (32 and
1463
;;      64-bit versions) may produce incorrect results under the
1464
;;      following conditions:
1465
;;      1) An integer multiply is currently executing
1466
;;      2) These types of shift instructions are executed immediately
1467
;;         following an integer divide instruction.
1468
;;      Workaround:
1469
;;      1) Make sure no integer multiply is running wihen these
1470
;;         instruction are executed.  If this cannot be predicted at
1471
;;         compile time, then insert a "mfhi" to R0 instruction
1472
;;         immediately after the integer multiply instruction.  This
1473
;;         will cause the integer multiply to complete before the shift
1474
;;         is executed.
1475
;;      2) Separate integer divide and these two classes of shift
1476
;;         instructions by another instruction or a noop."
1477
;;
1478
;; These processors have PRId values of 0x00004220 and 0x00004300,
1479
;; respectively.
1480
 
1481
(define_expand "mul3"
1482
  [(set (match_operand:GPR 0 "register_operand")
1483
        (mult:GPR (match_operand:GPR 1 "register_operand")
1484
                  (match_operand:GPR 2 "register_operand")))]
1485
  "ISA_HAS_MULT && !TARGET_NO_HW_MULT"
1486
{
1487
  rtx lo;
1488
 
1489
  if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A)
1490
    emit_insn (gen_mul3_mul3_loongson (operands[0], operands[1],
1491
                                             operands[2]));
1492
  else if (ISA_HAS_MUL3)
1493
    emit_insn (gen_mul3_mul3 (operands[0], operands[1], operands[2]));
1494
  else if (TARGET_MIPS16)
1495
    {
1496
      lo = gen_rtx_REG (mode, LO_REGNUM);
1497
      emit_insn (gen_mul3_internal (lo, operands[1], operands[2]));
1498
      emit_move_insn (operands[0], lo);
1499
    }
1500
  else if (TARGET_FIX_R4000)
1501
    emit_insn (gen_mul3_r4000 (operands[0], operands[1], operands[2]));
1502
  else
1503
    emit_insn
1504
      (gen_mul3_internal (operands[0], operands[1], operands[2]));
1505
  DONE;
1506
})
1507
 
1508
(define_insn "mul3_mul3_loongson"
1509
  [(set (match_operand:GPR 0 "register_operand" "=d")
1510
        (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1511
                  (match_operand:GPR 2 "register_operand" "d")))]
1512
  "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A"
1513
{
1514
  if (TARGET_LOONGSON_2EF)
1515
    return "multu.g\t%0,%1,%2";
1516
  else
1517
    return "gsmultu\t%0,%1,%2";
1518
}
1519
  [(set_attr "type" "imul3nc")
1520
   (set_attr "mode" "")])
1521
 
1522
(define_insn "mul3_mul3"
1523
  [(set (match_operand:GPR 0 "register_operand" "=d,l")
1524
        (mult:GPR (match_operand:GPR 1 "register_operand" "d,d")
1525
                  (match_operand:GPR 2 "register_operand" "d,d")))
1526
   (clobber (match_scratch:GPR 3 "=l,X"))]
1527
  "ISA_HAS_MUL3"
1528
{
1529
  if (which_alternative == 1)
1530
    return "mult\t%1,%2";
1531
  if (mode == SImode && (TARGET_MIPS3900 || TARGET_MIPS5900))
1532
    return "mult\t%0,%1,%2";
1533
  return "mul\t%0,%1,%2";
1534
}
1535
  [(set_attr "type" "imul3,imul")
1536
   (set_attr "mode" "")])
1537
 
1538
;; If a register gets allocated to LO, and we spill to memory, the reload
1539
;; will include a move from LO to a GPR.  Merge it into the multiplication
1540
;; if it can set the GPR directly.
1541
;;
1542
;; Operand 0: LO
1543
;; Operand 1: GPR (1st multiplication operand)
1544
;; Operand 2: GPR (2nd multiplication operand)
1545
;; Operand 3: GPR (destination)
1546
(define_peephole2
1547
  [(parallel
1548
       [(set (match_operand:SI 0 "lo_operand")
1549
             (mult:SI (match_operand:SI 1 "d_operand")
1550
                      (match_operand:SI 2 "d_operand")))
1551
        (clobber (scratch:SI))])
1552
   (set (match_operand:SI 3 "d_operand")
1553
        (match_dup 0))]
1554
  "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[0])"
1555
  [(parallel
1556
       [(set (match_dup 3)
1557
             (mult:SI (match_dup 1)
1558
                      (match_dup 2)))
1559
        (clobber (match_dup 0))])])
1560
 
1561
(define_insn "mul3_internal"
1562
  [(set (match_operand:GPR 0 "muldiv_target_operand" "=l")
1563
        (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1564
                  (match_operand:GPR 2 "register_operand" "d")))]
1565
  "ISA_HAS_MULT && !TARGET_FIX_R4000"
1566
  "mult\t%1,%2"
1567
  [(set_attr "type" "imul")
1568
   (set_attr "mode" "")])
1569
 
1570
(define_insn "mul3_r4000"
1571
  [(set (match_operand:GPR 0 "register_operand" "=d")
1572
        (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1573
                  (match_operand:GPR 2 "register_operand" "d")))
1574
   (clobber (match_scratch:GPR 3 "=l"))]
1575
  "ISA_HAS_MULT && TARGET_FIX_R4000"
1576
  "mult\t%1,%2\;mflo\t%0"
1577
  [(set_attr "type" "imul")
1578
   (set_attr "mode" "")
1579
   (set_attr "insn_count" "2")])
1580
 
1581
;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1582
;; of "mult; mflo".  They have the same latency, but the first form gives
1583
;; us an extra cycle to compute the operands.
1584
 
1585
;; Operand 0: LO
1586
;; Operand 1: GPR (1st multiplication operand)
1587
;; Operand 2: GPR (2nd multiplication operand)
1588
;; Operand 3: GPR (destination)
1589
(define_peephole2
1590
  [(set (match_operand:SI 0 "lo_operand")
1591
        (mult:SI (match_operand:SI 1 "d_operand")
1592
                 (match_operand:SI 2 "d_operand")))
1593
   (set (match_operand:SI 3 "d_operand")
1594
        (match_dup 0))]
1595
  "ISA_HAS_MACC && !ISA_HAS_MUL3"
1596
  [(set (match_dup 0)
1597
        (const_int 0))
1598
   (parallel
1599
       [(set (match_dup 0)
1600
             (plus:SI (mult:SI (match_dup 1)
1601
                               (match_dup 2))
1602
                      (match_dup 0)))
1603
        (set (match_dup 3)
1604
             (plus:SI (mult:SI (match_dup 1)
1605
                               (match_dup 2))
1606
                      (match_dup 0)))])])
1607
 
1608
;; Multiply-accumulate patterns
1609
 
1610
;; This pattern is first matched by combine, which tries to use the
1611
;; pattern wherever it can.  We don't know until later whether it
1612
;; is actually profitable to use MADD over a "MUL; ADDIU" sequence,
1613
;; so we need to keep both options open.
1614
;;
1615
;; The second alternative has a "?" marker because it is generally
1616
;; one instruction more costly than the first alternative.  This "?"
1617
;; marker is enough to convey the relative costs to the register
1618
;; allocator.
1619
;;
1620
;; However, reload counts reloads of operands 4 and 5 in the same way as
1621
;; reloads of the other operands, even though operands 4 and 5 need no
1622
;; copy instructions.  Reload therefore thinks that the second alternative
1623
;; is two reloads more costly than the first.  We add "*?*?" to the first
1624
;; alternative as a counterweight.
1625
(define_insn "*mul_acc_si"
1626
  [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?")
1627
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1628
                          (match_operand:SI 2 "register_operand" "d,d"))
1629
                 (match_operand:SI 3 "register_operand" "0,d")))
1630
   (clobber (match_scratch:SI 4 "=X,l"))
1631
   (clobber (match_scratch:SI 5 "=X,&d"))]
1632
  "GENERATE_MADD_MSUB && !TARGET_MIPS16"
1633
  "@
1634
    madd\t%1,%2
1635
    #"
1636
  [(set_attr "type"     "imadd")
1637
   (set_attr "accum_in" "3")
1638
   (set_attr "mode"     "SI")
1639
   (set_attr "insn_count" "1,2")])
1640
 
1641
;; The same idea applies here.  The middle alternative needs one less
1642
;; clobber than the final alternative, so we add "*?" as a counterweight.
1643
(define_insn "*mul_acc_si_r3900"
1644
  [(set (match_operand:SI 0 "register_operand" "=l*?*?,d*?,d?")
1645
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1646
                          (match_operand:SI 2 "register_operand" "d,d,d"))
1647
                 (match_operand:SI 3 "register_operand" "0,l,d")))
1648
   (clobber (match_scratch:SI 4 "=X,3,l"))
1649
   (clobber (match_scratch:SI 5 "=X,X,&d"))]
1650
  "TARGET_MIPS3900 && !TARGET_MIPS16"
1651
  "@
1652
    madd\t%1,%2
1653
    madd\t%0,%1,%2
1654
    #"
1655
  [(set_attr "type"     "imadd")
1656
   (set_attr "accum_in" "3")
1657
   (set_attr "mode"     "SI")
1658
   (set_attr "insn_count" "1,1,2")])
1659
 
1660
;; Split *mul_acc_si if both the source and destination accumulator
1661
;; values are GPRs.
1662
(define_split
1663
  [(set (match_operand:SI 0 "d_operand")
1664
        (plus:SI (mult:SI (match_operand:SI 1 "d_operand")
1665
                          (match_operand:SI 2 "d_operand"))
1666
                 (match_operand:SI 3 "d_operand")))
1667
   (clobber (match_operand:SI 4 "lo_operand"))
1668
   (clobber (match_operand:SI 5 "d_operand"))]
1669
  "reload_completed"
1670
  [(parallel [(set (match_dup 5)
1671
                   (mult:SI (match_dup 1) (match_dup 2)))
1672
              (clobber (match_dup 4))])
1673
   (set (match_dup 0) (plus:SI (match_dup 5) (match_dup 3)))]
1674
  "")
1675
 
1676
(define_insn "*macc"
1677
  [(set (match_operand:SI 0 "register_operand" "=l,d")
1678
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1679
                          (match_operand:SI 2 "register_operand" "d,d"))
1680
                 (match_operand:SI 3 "register_operand" "0,l")))
1681
   (clobber (match_scratch:SI 4 "=X,3"))]
1682
  "ISA_HAS_MACC"
1683
{
1684
  if (which_alternative == 1)
1685
    return "macc\t%0,%1,%2";
1686
  else if (TARGET_MIPS5500)
1687
    return "madd\t%1,%2";
1688
  else
1689
    /* The VR4130 assumes that there is a two-cycle latency between a macc
1690
       that "writes" to $0 and an instruction that reads from it.  We avoid
1691
       this by assigning to $1 instead.  */
1692
    return "%[macc\t%@,%1,%2%]";
1693
}
1694
  [(set_attr "type" "imadd")
1695
   (set_attr "accum_in" "3")
1696
   (set_attr "mode" "SI")])
1697
 
1698
(define_insn "*msac"
1699
  [(set (match_operand:SI 0 "register_operand" "=l,d")
1700
        (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1701
                  (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1702
                           (match_operand:SI 3 "register_operand" "d,d"))))
1703
   (clobber (match_scratch:SI 4 "=X,1"))]
1704
  "ISA_HAS_MSAC"
1705
{
1706
  if (which_alternative == 1)
1707
    return "msac\t%0,%2,%3";
1708
  else if (TARGET_MIPS5500)
1709
    return "msub\t%2,%3";
1710
  else
1711
    return "msac\t$0,%2,%3";
1712
}
1713
  [(set_attr "type"     "imadd")
1714
   (set_attr "accum_in" "1")
1715
   (set_attr "mode"     "SI")])
1716
 
1717
;; An msac-like instruction implemented using negation and a macc.
1718
(define_insn_and_split "*msac_using_macc"
1719
  [(set (match_operand:SI 0 "register_operand" "=l,d")
1720
        (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1721
                  (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1722
                           (match_operand:SI 3 "register_operand" "d,d"))))
1723
   (clobber (match_scratch:SI 4 "=X,1"))
1724
   (clobber (match_scratch:SI 5 "=d,d"))]
1725
  "ISA_HAS_MACC && !ISA_HAS_MSAC"
1726
  "#"
1727
  "&& reload_completed"
1728
  [(set (match_dup 5)
1729
        (neg:SI (match_dup 3)))
1730
   (parallel
1731
       [(set (match_dup 0)
1732
             (plus:SI (mult:SI (match_dup 2)
1733
                               (match_dup 5))
1734
                      (match_dup 1)))
1735
        (clobber (match_dup 4))])]
1736
  ""
1737
  [(set_attr "type"     "imadd")
1738
   (set_attr "accum_in" "1")
1739
   (set_attr "insn_count" "2")])
1740
 
1741
;; Patterns generated by the define_peephole2 below.
1742
 
1743
(define_insn "*macc2"
1744
  [(set (match_operand:SI 0 "muldiv_target_operand" "=l")
1745
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1746
                          (match_operand:SI 2 "register_operand" "d"))
1747
                 (match_dup 0)))
1748
   (set (match_operand:SI 3 "register_operand" "=d")
1749
        (plus:SI (mult:SI (match_dup 1)
1750
                          (match_dup 2))
1751
                 (match_dup 0)))]
1752
  "ISA_HAS_MACC && reload_completed"
1753
  "macc\t%3,%1,%2"
1754
  [(set_attr "type"     "imadd")
1755
   (set_attr "accum_in" "0")
1756
   (set_attr "mode"     "SI")])
1757
 
1758
(define_insn "*msac2"
1759
  [(set (match_operand:SI 0 "muldiv_target_operand" "=l")
1760
        (minus:SI (match_dup 0)
1761
                  (mult:SI (match_operand:SI 1 "register_operand" "d")
1762
                           (match_operand:SI 2 "register_operand" "d"))))
1763
   (set (match_operand:SI 3 "register_operand" "=d")
1764
        (minus:SI (match_dup 0)
1765
                  (mult:SI (match_dup 1)
1766
                           (match_dup 2))))]
1767
  "ISA_HAS_MSAC && reload_completed"
1768
  "msac\t%3,%1,%2"
1769
  [(set_attr "type"     "imadd")
1770
   (set_attr "accum_in" "0")
1771
   (set_attr "mode"     "SI")])
1772
 
1773
;; Convert macc $0,, & mflo  into macc ,,
1774
;; Similarly msac.
1775
;;
1776
;; Operand 0: LO
1777
;; Operand 1: macc/msac
1778
;; Operand 2: GPR (destination)
1779
(define_peephole2
1780
  [(parallel
1781
       [(set (match_operand:SI 0 "lo_operand")
1782
             (match_operand:SI 1 "macc_msac_operand"))
1783
        (clobber (scratch:SI))])
1784
   (set (match_operand:SI 2 "d_operand")
1785
        (match_dup 0))]
1786
  ""
1787
  [(parallel [(set (match_dup 0)
1788
                   (match_dup 1))
1789
              (set (match_dup 2)
1790
                   (match_dup 1))])])
1791
 
1792
;; When we have a three-address multiplication instruction, it should
1793
;; be faster to do a separate multiply and add, rather than moving
1794
;; something into LO in order to use a macc instruction.
1795
;;
1796
;; This peephole needs a scratch register to cater for the case when one
1797
;; of the multiplication operands is the same as the destination.
1798
;;
1799
;; Operand 0: GPR (scratch)
1800
;; Operand 1: LO
1801
;; Operand 2: GPR (addend)
1802
;; Operand 3: GPR (destination)
1803
;; Operand 4: macc/msac
1804
;; Operand 5: new multiplication
1805
;; Operand 6: new addition/subtraction
1806
(define_peephole2
1807
  [(match_scratch:SI 0 "d")
1808
   (set (match_operand:SI 1 "lo_operand")
1809
        (match_operand:SI 2 "d_operand"))
1810
   (match_dup 0)
1811
   (parallel
1812
       [(set (match_operand:SI 3 "d_operand")
1813
             (match_operand:SI 4 "macc_msac_operand"))
1814
        (clobber (match_dup 1))])]
1815
  "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[1])"
1816
  [(parallel [(set (match_dup 0)
1817
                   (match_dup 5))
1818
              (clobber (match_dup 1))])
1819
   (set (match_dup 3)
1820
        (match_dup 6))]
1821
{
1822
  operands[5] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1823
  operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1824
                                operands[2], operands[0]);
1825
})
1826
 
1827
;; Same as above, except LO is the initial target of the macc.
1828
;;
1829
;; Operand 0: GPR (scratch)
1830
;; Operand 1: LO
1831
;; Operand 2: GPR (addend)
1832
;; Operand 3: macc/msac
1833
;; Operand 4: GPR (destination)
1834
;; Operand 5: new multiplication
1835
;; Operand 6: new addition/subtraction
1836
(define_peephole2
1837
  [(match_scratch:SI 0 "d")
1838
   (set (match_operand:SI 1 "lo_operand")
1839
        (match_operand:SI 2 "d_operand"))
1840
   (match_dup 0)
1841
   (parallel
1842
       [(set (match_dup 1)
1843
             (match_operand:SI 3 "macc_msac_operand"))
1844
        (clobber (scratch:SI))])
1845
   (match_dup 0)
1846
   (set (match_operand:SI 4 "d_operand")
1847
        (match_dup 1))]
1848
  "ISA_HAS_MUL3 && peep2_reg_dead_p (3, operands[1])"
1849
  [(parallel [(set (match_dup 0)
1850
                   (match_dup 5))
1851
              (clobber (match_dup 1))])
1852
   (set (match_dup 4)
1853
        (match_dup 6))]
1854
{
1855
  operands[5] = XEXP (operands[3], GET_CODE (operands[3]) == PLUS ? 0 : 1);
1856
  operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
1857
                                operands[2], operands[0]);
1858
})
1859
 
1860
;; See the comment above *mul_add_si for details.
1861
(define_insn "*mul_sub_si"
1862
  [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?")
1863
        (minus:SI (match_operand:SI 1 "register_operand" "0,d")
1864
                  (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1865
                           (match_operand:SI 3 "register_operand" "d,d"))))
1866
   (clobber (match_scratch:SI 4 "=X,l"))
1867
   (clobber (match_scratch:SI 5 "=X,&d"))]
1868
  "GENERATE_MADD_MSUB"
1869
  "@
1870
   msub\t%2,%3
1871
   #"
1872
  [(set_attr "type"     "imadd")
1873
   (set_attr "accum_in" "1")
1874
   (set_attr "mode"     "SI")
1875
   (set_attr "insn_count" "1,2")])
1876
 
1877
;; Split *mul_sub_si if both the source and destination accumulator
1878
;; values are GPRs.
1879
(define_split
1880
  [(set (match_operand:SI 0 "d_operand")
1881
        (minus:SI (match_operand:SI 1 "d_operand")
1882
                  (mult:SI (match_operand:SI 2 "d_operand")
1883
                           (match_operand:SI 3 "d_operand"))))
1884
   (clobber (match_operand:SI 4 "lo_operand"))
1885
   (clobber (match_operand:SI 5 "d_operand"))]
1886
  "reload_completed"
1887
  [(parallel [(set (match_dup 5)
1888
                   (mult:SI (match_dup 2) (match_dup 3)))
1889
              (clobber (match_dup 4))])
1890
   (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 5)))]
1891
  "")
1892
 
1893
(define_insn "*muls"
1894
  [(set (match_operand:SI 0 "register_operand" "=l,d")
1895
        (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1896
                         (match_operand:SI 2 "register_operand" "d,d"))))
1897
   (clobber (match_scratch:SI 3 "=X,l"))]
1898
  "ISA_HAS_MULS"
1899
  "@
1900
   muls\t$0,%1,%2
1901
   muls\t%0,%1,%2"
1902
  [(set_attr "type"     "imul,imul3")
1903
   (set_attr "mode"     "SI")])
1904
 
1905
(define_expand "mulsidi3"
1906
  [(set (match_operand:DI 0 "register_operand")
1907
        (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1908
                 (any_extend:DI (match_operand:SI 2 "register_operand"))))]
1909
  "mips_mulsidi3_gen_fn () != NULL && !TARGET_NO_HW_MULT"
1910
{
1911
  mulsidi3_gen_fn fn = mips_mulsidi3_gen_fn ();
1912
  emit_insn (fn (operands[0], operands[1], operands[2]));
1913
  DONE;
1914
})
1915
 
1916
(define_expand "mulsidi3_32bit_mips16"
1917
  [(set (match_operand:DI 0 "register_operand")
1918
        (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1919
                 (any_extend:DI (match_operand:SI 2 "register_operand"))))]
1920
  "!TARGET_64BIT && TARGET_MIPS16"
1921
{
1922
  rtx hilo;
1923
 
1924
  hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
1925
  emit_insn (gen_mulsidi3_32bit (hilo, operands[1], operands[2]));
1926
  emit_move_insn (operands[0], hilo);
1927
  DONE;
1928
})
1929
 
1930
;; As well as being named patterns, these instructions are used by the
1931
;; __builtin_mips_mult() functions.  We must always make those functions
1932
;; available if !TARGET_64BIT && ISA_HAS_DSP.
1933
(define_insn "mulsidi3_32bit"
1934
  [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
1935
        (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1936
                 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1937
  "!TARGET_64BIT && (!TARGET_FIX_R4000 || ISA_HAS_DSP) && !TARGET_NO_HW_MULT"
1938
{
1939
  if (ISA_HAS_DSP_MULT)
1940
    return "mult\t%q0,%1,%2";
1941
  else
1942
    return "mult\t%1,%2";
1943
}
1944
  [(set_attr "type" "imul")
1945
   (set_attr "mode" "SI")])
1946
 
1947
(define_insn "mulsidi3_32bit_r4000"
1948
  [(set (match_operand:DI 0 "register_operand" "=d")
1949
        (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1950
                 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1951
   (clobber (match_scratch:DI 3 "=x"))]
1952
  "!TARGET_64BIT && TARGET_FIX_R4000 && !ISA_HAS_DSP"
1953
  "mult\t%1,%2\;mflo\t%L0\;mfhi\t%M0"
1954
  [(set_attr "type" "imul")
1955
   (set_attr "mode" "SI")
1956
   (set_attr "insn_count" "3")])
1957
 
1958
(define_insn_and_split "mulsidi3_64bit"
1959
  [(set (match_operand:DI 0 "register_operand" "=d")
1960
        (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1961
                 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1962
   (clobber (match_scratch:TI 3 "=x"))
1963
   (clobber (match_scratch:DI 4 "=d"))]
1964
  "TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DMUL3 && !TARGET_MIPS16"
1965
  "#"
1966
  "&& reload_completed"
1967
  [(const_int 0)]
1968
{
1969
  emit_insn (gen_mulsidi3_64bit_split (operands[0], operands[1],
1970
                                          operands[2], operands[4]));
1971
  DONE;
1972
}
1973
  [(set_attr "type" "imul")
1974
   (set_attr "mode" "SI")
1975
   (set (attr "insn_count")
1976
        (if_then_else (match_test "ISA_HAS_EXT_INS")
1977
                      (const_int 4)
1978
                      (const_int 7)))])
1979
 
1980
(define_expand "mulsidi3_64bit_mips16"
1981
  [(set (match_operand:DI 0 "register_operand")
1982
        (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1983
                 (any_extend:DI (match_operand:SI 2 "register_operand"))))]
1984
  "TARGET_64BIT && TARGET_MIPS16"
1985
{
1986
  emit_insn (gen_mulsidi3_64bit_split (operands[0], operands[1],
1987
                                          operands[2], gen_reg_rtx (DImode)));
1988
  DONE;
1989
})
1990
 
1991
(define_expand "mulsidi3_64bit_split"
1992
  [(set (match_operand:DI 0 "register_operand")
1993
        (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1994
                 (any_extend:DI (match_operand:SI 2 "register_operand"))))
1995
   (clobber (match_operand:DI 3 "register_operand"))]
1996
  ""
1997
{
1998
  rtx hilo;
1999
 
2000
  hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2001
  emit_insn (gen_mulsidi3_64bit_hilo (hilo, operands[1], operands[2]));
2002
 
2003
  emit_move_insn (operands[0], gen_rtx_REG (DImode, LO_REGNUM));
2004
  emit_insn (gen_mfhidi_ti (operands[3], hilo));
2005
 
2006
  if (ISA_HAS_EXT_INS)
2007
    emit_insn (gen_insvdi (operands[0], GEN_INT (32), GEN_INT (32),
2008
                           operands[3]));
2009
  else
2010
    {
2011
      /* Zero-extend the low part.  */
2012
      mips_emit_binary (ASHIFT, operands[0], operands[0], GEN_INT (32));
2013
      mips_emit_binary (LSHIFTRT, operands[0], operands[0], GEN_INT (32));
2014
 
2015
      /* Shift the high part into place.  */
2016
      mips_emit_binary (ASHIFT, operands[3], operands[3], GEN_INT (32));
2017
 
2018
      /* OR the two halves together.  */
2019
      mips_emit_binary (IOR, operands[0], operands[0], operands[3]);
2020
    }
2021
  DONE;
2022
})
2023
 
2024
(define_insn "mulsidi3_64bit_hilo"
2025
  [(set (match_operand:TI 0 "muldiv_target_operand" "=x")
2026
        (unspec:TI
2027
          [(mult:DI
2028
             (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2029
             (any_extend:DI (match_operand:SI 2 "register_operand" "d")))]
2030
          UNSPEC_SET_HILO))]
2031
  "TARGET_64BIT && !TARGET_FIX_R4000"
2032
  "mult\t%1,%2"
2033
  [(set_attr "type" "imul")
2034
   (set_attr "mode" "SI")])
2035
 
2036
;; See comment before the ISA_HAS_DMUL3 case in mips_mulsidi3_gen_fn.
2037
(define_insn "mulsidi3_64bit_dmul"
2038
  [(set (match_operand:DI 0 "register_operand" "=d")
2039
        (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2040
                 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2041
   (clobber (match_scratch:DI 3 "=l"))]
2042
  "ISA_HAS_DMUL3"
2043
  "dmul\t%0,%1,%2"
2044
  [(set_attr "type" "imul3")
2045
   (set_attr "mode" "DI")])
2046
 
2047
;; Widening multiply with negation.
2048
(define_insn "*muls_di"
2049
  [(set (match_operand:DI 0 "muldiv_target_operand" "=x")
2050
        (neg:DI
2051
         (mult:DI
2052
          (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2053
          (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2054
  "!TARGET_64BIT && ISA_HAS_MULS"
2055
  "muls\t$0,%1,%2"
2056
  [(set_attr "type" "imul")
2057
   (set_attr "mode" "SI")])
2058
 
2059
;; As well as being named patterns, these instructions are used by the
2060
;; __builtin_mips_msub() functions.  We must always make those functions
2061
;; available if !TARGET_64BIT && ISA_HAS_DSP.
2062
;;
2063
;; This leads to a slight inconsistency.  We honor any tuning overrides
2064
;; in GENERATE_MADD_MSUB for -mno-dsp, but always ignore them for -mdsp,
2065
;; even if !ISA_HAS_DSP_MULT.
2066
(define_insn "msubsidi4"
2067
  [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
2068
        (minus:DI
2069
           (match_operand:DI 3 "muldiv_target_operand" "0")
2070
           (mult:DI
2071
              (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2072
              (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2073
  "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || ISA_HAS_DSP)"
2074
{
2075
  if (ISA_HAS_DSP_MULT)
2076
    return "msub\t%q0,%1,%2";
2077
  else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB)
2078
    return "msub\t%1,%2";
2079
  else
2080
    return "msac\t$0,%1,%2";
2081
}
2082
  [(set_attr "type" "imadd")
2083
   (set_attr "accum_in" "3")
2084
   (set_attr "mode" "SI")])
2085
 
2086
;; _highpart patterns
2087
 
2088
(define_expand "mulsi3_highpart"
2089
  [(set (match_operand:SI 0 "register_operand")
2090
        (truncate:SI
2091
         (lshiftrt:DI
2092
          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2093
                   (any_extend:DI (match_operand:SI 2 "register_operand")))
2094
          (const_int 32))))]
2095
  "!TARGET_NO_HW_MULT"
2096
{
2097
  if (ISA_HAS_MULHI)
2098
    emit_insn (gen_mulsi3_highpart_mulhi_internal (operands[0],
2099
                                                       operands[1],
2100
                                                       operands[2]));
2101
  else if (TARGET_MIPS16)
2102
    emit_insn (gen_mulsi3_highpart_split (operands[0], operands[1],
2103
                                              operands[2]));
2104
  else
2105
    emit_insn (gen_mulsi3_highpart_internal (operands[0], operands[1],
2106
                                                 operands[2]));
2107
  DONE;
2108
})
2109
 
2110
(define_insn_and_split "mulsi3_highpart_internal"
2111
  [(set (match_operand:SI 0 "register_operand" "=d")
2112
        (truncate:SI
2113
         (lshiftrt:DI
2114
          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2115
                   (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2116
          (const_int 32))))
2117
   (clobber (match_scratch:SI 3 "=l"))]
2118
  "!ISA_HAS_MULHI && !TARGET_MIPS16 && !TARGET_NO_HW_MULT"
2119
  { return TARGET_FIX_R4000 ? "mult\t%1,%2\n\tmfhi\t%0" : "#"; }
2120
  "&& reload_completed && !TARGET_FIX_R4000 && !TARGET_NO_HW_MULT"
2121
  [(const_int 0)]
2122
{
2123
  emit_insn (gen_mulsi3_highpart_split (operands[0], operands[1],
2124
                                            operands[2]));
2125
  DONE;
2126
}
2127
  [(set_attr "type" "imul")
2128
   (set_attr "mode" "SI")
2129
   (set_attr "insn_count" "2")])
2130
 
2131
(define_expand "mulsi3_highpart_split"
2132
  [(set (match_operand:SI 0 "register_operand")
2133
        (truncate:SI
2134
         (lshiftrt:DI
2135
          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2136
                   (any_extend:DI (match_operand:SI 2 "register_operand")))
2137
          (const_int 32))))]
2138
  ""
2139
{
2140
  rtx hilo;
2141
 
2142
  if (TARGET_64BIT)
2143
    {
2144
      hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2145
      emit_insn (gen_mulsidi3_64bit_hilo (hilo, operands[1], operands[2]));
2146
      emit_insn (gen_mfhisi_ti (operands[0], hilo));
2147
    }
2148
  else
2149
    {
2150
      hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
2151
      emit_insn (gen_mulsidi3_32bit (hilo, operands[1], operands[2]));
2152
      emit_insn (gen_mfhisi_di (operands[0], hilo));
2153
    }
2154
  DONE;
2155
})
2156
 
2157
(define_insn "mulsi3_highpart_mulhi_internal"
2158
  [(set (match_operand:SI 0 "register_operand" "=d")
2159
        (truncate:SI
2160
         (lshiftrt:DI
2161
          (mult:DI
2162
           (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2163
           (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2164
          (const_int 32))))
2165
   (clobber (match_scratch:SI 3 "=l"))]
2166
  "ISA_HAS_MULHI"
2167
  "mulhi\t%0,%1,%2"
2168
  [(set_attr "type" "imul3")
2169
   (set_attr "mode" "SI")])
2170
 
2171
(define_insn "*mulsi3_highpart_neg_mulhi_internal"
2172
  [(set (match_operand:SI 0 "register_operand" "=d")
2173
        (truncate:SI
2174
         (lshiftrt:DI
2175
          (neg:DI
2176
           (mult:DI
2177
            (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2178
            (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2179
          (const_int 32))))
2180
   (clobber (match_scratch:SI 3 "=l"))]
2181
  "ISA_HAS_MULHI"
2182
  "mulshi\t%0,%1,%2"
2183
  [(set_attr "type" "imul3")
2184
   (set_attr "mode" "SI")])
2185
 
2186
;; Disable unsigned multiplication for -mfix-vr4120.  This is for VR4120
2187
;; errata MD(0), which says that dmultu does not always produce the
2188
;; correct result.
2189
(define_expand "muldi3_highpart"
2190
  [(set (match_operand:DI 0 "register_operand")
2191
        (truncate:DI
2192
         (lshiftrt:TI
2193
          (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2194
                   (any_extend:TI (match_operand:DI 2 "register_operand")))
2195
          (const_int 64))))]
2196
  "ISA_HAS_DMULT && !( == ZERO_EXTEND && TARGET_FIX_VR4120)"
2197
{
2198
  if (TARGET_MIPS16)
2199
    emit_insn (gen_muldi3_highpart_split (operands[0], operands[1],
2200
                                              operands[2]));
2201
  else
2202
    emit_insn (gen_muldi3_highpart_internal (operands[0], operands[1],
2203
                                                 operands[2]));
2204
  DONE;
2205
})
2206
 
2207
(define_insn_and_split "muldi3_highpart_internal"
2208
  [(set (match_operand:DI 0 "register_operand" "=d")
2209
        (truncate:DI
2210
         (lshiftrt:TI
2211
          (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2212
                   (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
2213
          (const_int 64))))
2214
   (clobber (match_scratch:DI 3 "=l"))]
2215
  "ISA_HAS_DMULT
2216
   && !TARGET_MIPS16
2217
   && !( == ZERO_EXTEND && TARGET_FIX_VR4120)"
2218
  { return TARGET_FIX_R4000 ? "dmult\t%1,%2\n\tmfhi\t%0" : "#"; }
2219
  "&& reload_completed && !TARGET_FIX_R4000"
2220
  [(const_int 0)]
2221
{
2222
  emit_insn (gen_muldi3_highpart_split (operands[0], operands[1],
2223
                                            operands[2]));
2224
  DONE;
2225
}
2226
  [(set_attr "type" "imul")
2227
   (set_attr "mode" "DI")
2228
   (set_attr "insn_count" "2")])
2229
 
2230
(define_expand "muldi3_highpart_split"
2231
  [(set (match_operand:DI 0 "register_operand")
2232
        (truncate:DI
2233
         (lshiftrt:TI
2234
          (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2235
                   (any_extend:TI (match_operand:DI 2 "register_operand")))
2236
          (const_int 64))))]
2237
  ""
2238
{
2239
  rtx hilo;
2240
 
2241
  hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2242
  emit_insn (gen_mulditi3_internal (hilo, operands[1], operands[2]));
2243
  emit_insn (gen_mfhidi_ti (operands[0], hilo));
2244
  DONE;
2245
})
2246
 
2247
(define_expand "mulditi3"
2248
  [(set (match_operand:TI 0 "register_operand")
2249
        (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2250
                 (any_extend:TI (match_operand:DI 2 "register_operand"))))]
2251
  "ISA_HAS_DMULT && !( == ZERO_EXTEND && TARGET_FIX_VR4120)"
2252
{
2253
  rtx hilo;
2254
 
2255
  if (TARGET_MIPS16)
2256
    {
2257
      hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2258
      emit_insn (gen_mulditi3_internal (hilo, operands[1], operands[2]));
2259
      emit_move_insn (operands[0], hilo);
2260
    }
2261
  else if (TARGET_FIX_R4000)
2262
    emit_insn (gen_mulditi3_r4000 (operands[0], operands[1], operands[2]));
2263
  else
2264
    emit_insn (gen_mulditi3_internal (operands[0], operands[1],
2265
                                         operands[2]));
2266
  DONE;
2267
})
2268
 
2269
(define_insn "mulditi3_internal"
2270
  [(set (match_operand:TI 0 "muldiv_target_operand" "=x")
2271
        (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2272
                 (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))]
2273
  "ISA_HAS_DMULT
2274
   && !TARGET_FIX_R4000
2275
   && !( == ZERO_EXTEND && TARGET_FIX_VR4120)"
2276
  "dmult\t%1,%2"
2277
  [(set_attr "type" "imul")
2278
   (set_attr "mode" "DI")])
2279
 
2280
(define_insn "mulditi3_r4000"
2281
  [(set (match_operand:TI 0 "register_operand" "=d")
2282
        (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2283
                 (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))
2284
   (clobber (match_scratch:TI 3 "=x"))]
2285
  "ISA_HAS_DMULT
2286
   && TARGET_FIX_R4000
2287
   && !( == ZERO_EXTEND && TARGET_FIX_VR4120)"
2288
  "dmult\t%1,%2\;mflo\t%L0\;mfhi\t%M0"
2289
  [(set_attr "type" "imul")
2290
   (set_attr "mode" "DI")
2291
   (set_attr "insn_count" "3")])
2292
 
2293
;; The R4650 supports a 32-bit multiply/ 64-bit accumulate
2294
;; instruction.  The HI/LO registers are used as a 64-bit accumulator.
2295
 
2296
(define_insn "madsi"
2297
  [(set (match_operand:SI 0 "register_operand" "+l")
2298
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2299
                          (match_operand:SI 2 "register_operand" "d"))
2300
                 (match_dup 0)))]
2301
  "TARGET_MAD"
2302
  "mad\t%1,%2"
2303
  [(set_attr "type"     "imadd")
2304
   (set_attr "accum_in" "0")
2305
   (set_attr "mode"     "SI")])
2306
 
2307
;; See the comment above msubsidi4 for the relationship between
2308
;; ISA_HAS_DSP and ISA_HAS_DSP_MULT.
2309
(define_insn "maddsidi4"
2310
  [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
2311
        (plus:DI
2312
         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2313
                  (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2314
         (match_operand:DI 3 "muldiv_target_operand" "0")))]
2315
  "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || ISA_HAS_DSP)
2316
   && !TARGET_64BIT"
2317
{
2318
  if (TARGET_MAD)
2319
    return "mad\t%1,%2";
2320
  else if (ISA_HAS_DSP_MULT)
2321
    return "madd\t%q0,%1,%2";
2322
  else if (GENERATE_MADD_MSUB || TARGET_MIPS5500)
2323
    return "madd\t%1,%2";
2324
  else
2325
    /* See comment in *macc.  */
2326
    return "%[macc\t%@,%1,%2%]";
2327
}
2328
  [(set_attr "type" "imadd")
2329
   (set_attr "accum_in" "3")
2330
   (set_attr "mode" "SI")])
2331
 
2332
;; Floating point multiply accumulate instructions.
2333
 
2334
(define_insn "*madd4"
2335
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2336
        (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2337
                              (match_operand:ANYF 2 "register_operand" "f"))
2338
                   (match_operand:ANYF 3 "register_operand" "f")))]
2339
  "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD"
2340
  "madd.\t%0,%3,%1,%2"
2341
  [(set_attr "type" "fmadd")
2342
   (set_attr "accum_in" "3")
2343
   (set_attr "mode" "")])
2344
 
2345
(define_insn "*madd3"
2346
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2347
        (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2348
                              (match_operand:ANYF 2 "register_operand" "f"))
2349
                   (match_operand:ANYF 3 "register_operand" "0")))]
2350
  "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD"
2351
  "madd.\t%0,%1,%2"
2352
  [(set_attr "type" "fmadd")
2353
   (set_attr "accum_in" "3")
2354
   (set_attr "mode" "")])
2355
 
2356
(define_insn "*msub4"
2357
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2358
        (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2359
                               (match_operand:ANYF 2 "register_operand" "f"))
2360
                    (match_operand:ANYF 3 "register_operand" "f")))]
2361
  "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD"
2362
  "msub.\t%0,%3,%1,%2"
2363
  [(set_attr "type" "fmadd")
2364
   (set_attr "accum_in" "3")
2365
   (set_attr "mode" "")])
2366
 
2367
(define_insn "*msub3"
2368
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2369
        (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2370
                               (match_operand:ANYF 2 "register_operand" "f"))
2371
                    (match_operand:ANYF 3 "register_operand" "0")))]
2372
  "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD"
2373
  "msub.\t%0,%1,%2"
2374
  [(set_attr "type" "fmadd")
2375
   (set_attr "accum_in" "3")
2376
   (set_attr "mode" "")])
2377
 
2378
(define_insn "*nmadd4"
2379
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2380
        (neg:ANYF (plus:ANYF
2381
                   (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2382
                              (match_operand:ANYF 2 "register_operand" "f"))
2383
                   (match_operand:ANYF 3 "register_operand" "f"))))]
2384
  "ISA_HAS_NMADD4_NMSUB4
2385
   && TARGET_FUSED_MADD
2386
   && HONOR_SIGNED_ZEROS (mode)
2387
   && !HONOR_NANS (mode)"
2388
  "nmadd.\t%0,%3,%1,%2"
2389
  [(set_attr "type" "fmadd")
2390
   (set_attr "accum_in" "3")
2391
   (set_attr "mode" "")])
2392
 
2393
(define_insn "*nmadd3"
2394
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2395
        (neg:ANYF (plus:ANYF
2396
                   (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2397
                              (match_operand:ANYF 2 "register_operand" "f"))
2398
                   (match_operand:ANYF 3 "register_operand" "0"))))]
2399
  "ISA_HAS_NMADD3_NMSUB3
2400
   && TARGET_FUSED_MADD
2401
   && HONOR_SIGNED_ZEROS (mode)
2402
   && !HONOR_NANS (mode)"
2403
  "nmadd.\t%0,%1,%2"
2404
  [(set_attr "type" "fmadd")
2405
   (set_attr "accum_in" "3")
2406
   (set_attr "mode" "")])
2407
 
2408
(define_insn "*nmadd4_fastmath"
2409
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2410
        (minus:ANYF
2411
         (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
2412
                    (match_operand:ANYF 2 "register_operand" "f"))
2413
         (match_operand:ANYF 3 "register_operand" "f")))]
2414
  "ISA_HAS_NMADD4_NMSUB4
2415
   && TARGET_FUSED_MADD
2416
   && !HONOR_SIGNED_ZEROS (mode)
2417
   && !HONOR_NANS (mode)"
2418
  "nmadd.\t%0,%3,%1,%2"
2419
  [(set_attr "type" "fmadd")
2420
   (set_attr "accum_in" "3")
2421
   (set_attr "mode" "")])
2422
 
2423
(define_insn "*nmadd3_fastmath"
2424
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2425
        (minus:ANYF
2426
         (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
2427
                    (match_operand:ANYF 2 "register_operand" "f"))
2428
         (match_operand:ANYF 3 "register_operand" "0")))]
2429
  "ISA_HAS_NMADD3_NMSUB3
2430
   && TARGET_FUSED_MADD
2431
   && !HONOR_SIGNED_ZEROS (mode)
2432
   && !HONOR_NANS (mode)"
2433
  "nmadd.\t%0,%1,%2"
2434
  [(set_attr "type" "fmadd")
2435
   (set_attr "accum_in" "3")
2436
   (set_attr "mode" "")])
2437
 
2438
(define_insn "*nmsub4"
2439
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2440
        (neg:ANYF (minus:ANYF
2441
                   (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2442
                              (match_operand:ANYF 3 "register_operand" "f"))
2443
                   (match_operand:ANYF 1 "register_operand" "f"))))]
2444
  "ISA_HAS_NMADD4_NMSUB4
2445
   && TARGET_FUSED_MADD
2446
   && HONOR_SIGNED_ZEROS (mode)
2447
   && !HONOR_NANS (mode)"
2448
  "nmsub.\t%0,%1,%2,%3"
2449
  [(set_attr "type" "fmadd")
2450
   (set_attr "accum_in" "1")
2451
   (set_attr "mode" "")])
2452
 
2453
(define_insn "*nmsub3"
2454
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2455
        (neg:ANYF (minus:ANYF
2456
                   (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2457
                              (match_operand:ANYF 3 "register_operand" "f"))
2458
                   (match_operand:ANYF 1 "register_operand" "0"))))]
2459
  "ISA_HAS_NMADD3_NMSUB3
2460
   && TARGET_FUSED_MADD
2461
   && HONOR_SIGNED_ZEROS (mode)
2462
   && !HONOR_NANS (mode)"
2463
  "nmsub.\t%0,%1,%2"
2464
  [(set_attr "type" "fmadd")
2465
   (set_attr "accum_in" "1")
2466
   (set_attr "mode" "")])
2467
 
2468
(define_insn "*nmsub4_fastmath"
2469
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2470
        (minus:ANYF
2471
         (match_operand:ANYF 1 "register_operand" "f")
2472
         (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2473
                    (match_operand:ANYF 3 "register_operand" "f"))))]
2474
  "ISA_HAS_NMADD4_NMSUB4
2475
   && TARGET_FUSED_MADD
2476
   && !HONOR_SIGNED_ZEROS (mode)
2477
   && !HONOR_NANS (mode)"
2478
  "nmsub.\t%0,%1,%2,%3"
2479
  [(set_attr "type" "fmadd")
2480
   (set_attr "accum_in" "1")
2481
   (set_attr "mode" "")])
2482
 
2483
(define_insn "*nmsub3_fastmath"
2484
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2485
        (minus:ANYF
2486
         (match_operand:ANYF 1 "register_operand" "f")
2487
         (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2488
                    (match_operand:ANYF 3 "register_operand" "0"))))]
2489
  "ISA_HAS_NMADD3_NMSUB3
2490
   && TARGET_FUSED_MADD
2491
   && !HONOR_SIGNED_ZEROS (mode)
2492
   && !HONOR_NANS (mode)"
2493
  "nmsub.\t%0,%1,%2"
2494
  [(set_attr "type" "fmadd")
2495
   (set_attr "accum_in" "1")
2496
   (set_attr "mode" "")])
2497
 
2498
;;
2499
;;  ....................
2500
;;
2501
;;      DIVISION and REMAINDER
2502
;;
2503
;;  ....................
2504
;;
2505
 
2506
(define_expand "div3"
2507
  [(set (match_operand:ANYF 0 "register_operand")
2508
        (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
2509
                  (match_operand:ANYF 2 "register_operand")))]
2510
  ""
2511
{
2512
  if (const_1_operand (operands[1], mode))
2513
    if (!(ISA_HAS_FP_RECIP_RSQRT (mode)
2514
          && flag_unsafe_math_optimizations))
2515
      operands[1] = force_reg (mode, operands[1]);
2516
})
2517
 
2518
;; These patterns work around the early SB-1 rev2 core "F1" erratum:
2519
;;
2520
;; If an mfc1 or dmfc1 happens to access the floating point register
2521
;; file at the same time a long latency operation (div, sqrt, recip,
2522
;; sqrt) iterates an intermediate result back through the floating
2523
;; point register file bypass, then instead returning the correct
2524
;; register value the mfc1 or dmfc1 operation returns the intermediate
2525
;; result of the long latency operation.
2526
;;
2527
;; The workaround is to insert an unconditional 'mov' from/to the
2528
;; long latency op destination register.
2529
 
2530
(define_insn "*div3"
2531
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2532
        (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
2533
                  (match_operand:ANYF 2 "register_operand" "f")))]
2534
  ""
2535
{
2536
  if (TARGET_FIX_SB1)
2537
    return "div.\t%0,%1,%2\;mov.\t%0,%0";
2538
  else
2539
    return "div.\t%0,%1,%2";
2540
}
2541
  [(set_attr "type" "fdiv")
2542
   (set_attr "mode" "")
2543
   (set (attr "insn_count")
2544
        (if_then_else (match_test "TARGET_FIX_SB1")
2545
                      (const_int 2)
2546
                      (const_int 1)))])
2547
 
2548
(define_insn "*recip3"
2549
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2550
        (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2551
                  (match_operand:ANYF 2 "register_operand" "f")))]
2552
  "ISA_HAS_FP_RECIP_RSQRT (mode) && flag_unsafe_math_optimizations"
2553
{
2554
  if (TARGET_FIX_SB1)
2555
    return "recip.\t%0,%2\;mov.\t%0,%0";
2556
  else
2557
    return "recip.\t%0,%2";
2558
}
2559
  [(set_attr "type" "frdiv")
2560
   (set_attr "mode" "")
2561
   (set (attr "insn_count")
2562
        (if_then_else (match_test "TARGET_FIX_SB1")
2563
                      (const_int 2)
2564
                      (const_int 1)))])
2565
 
2566
;; VR4120 errata MD(A1): signed division instructions do not work correctly
2567
;; with negative operands.  We use special libgcc functions instead.
2568
(define_expand "divmod4"
2569
  [(parallel
2570
     [(set (match_operand:GPR 0 "register_operand")
2571
           (div:GPR (match_operand:GPR 1 "register_operand")
2572
                    (match_operand:GPR 2 "register_operand")))
2573
      (set (match_operand:GPR 3 "register_operand")
2574
           (mod:GPR (match_dup 1)
2575
                    (match_dup 2)))])]
2576
  "ISA_HAS_DIV && !TARGET_FIX_VR4120 && !TARGET_NO_HW_DIV"
2577
{
2578
  if (TARGET_MIPS16)
2579
    {
2580
      rtx lo = gen_rtx_REG (mode, LO_REGNUM);
2581
      emit_insn (gen_divmod4_mips16 (operands[0], operands[1],
2582
                                           operands[2], operands[3], lo));
2583
      DONE;
2584
    }
2585
})
2586
 
2587
(define_insn_and_split "*divmod4"
2588
  [(set (match_operand:GPR 0 "register_operand" "=l")
2589
        (div:GPR (match_operand:GPR 1 "register_operand" "d")
2590
                 (match_operand:GPR 2 "register_operand" "d")))
2591
   (set (match_operand:GPR 3 "register_operand" "=d")
2592
        (mod:GPR (match_dup 1)
2593
                 (match_dup 2)))]
2594
  "ISA_HAS_DIV && !TARGET_FIX_VR4120 && !TARGET_MIPS16 && !TARGET_NO_HW_DIV"
2595
  "#"
2596
  "&& reload_completed"
2597
  [(const_int 0)]
2598
{
2599
  emit_insn (gen_divmod4_split (operands[3], operands[1], operands[2]));
2600
  DONE;
2601
}
2602
 [(set_attr "type" "idiv")
2603
  (set_attr "mode" "")
2604
  (set_attr "insn_count" "2")])
2605
 
2606
;; Expand generates divmod instructions for individual division and modulus
2607
;; operations.  We then rely on CSE to reuse earlier divmods where possible.
2608
;; This means that, when generating MIPS16 code, it is better not to expose
2609
;; the fixed LO register until after CSE has finished.  However, it's still
2610
;; better to split before register allocation, so that we don't allocate
2611
;; one of the scarce MIPS16 registers to an unused result.
2612
(define_insn_and_split "divmod4_mips16"
2613
  [(set (match_operand:GPR 0 "register_operand" "=d")
2614
        (div:GPR (match_operand:GPR 1 "register_operand" "d")
2615
                 (match_operand:GPR 2 "register_operand" "d")))
2616
   (set (match_operand:GPR 3 "register_operand" "=d")
2617
        (mod:GPR (match_dup 1)
2618
                 (match_dup 2)))
2619
   (clobber (match_operand:GPR 4 "lo_operand" "=l"))]
2620
  "ISA_HAS_DIV && !TARGET_FIX_VR4120 && TARGET_MIPS16"
2621
  "#"
2622
  "&& cse_not_expected"
2623
  [(const_int 0)]
2624
{
2625
  emit_insn (gen_divmod4_split (operands[3], operands[1], operands[2]));
2626
  emit_move_insn (operands[0], operands[4]);
2627
  DONE;
2628
}
2629
 [(set_attr "type" "idiv")
2630
  (set_attr "mode" "")
2631
  (set_attr "insn_count" "3")])
2632
 
2633
(define_expand "udivmod4"
2634
  [(parallel
2635
     [(set (match_operand:GPR 0 "register_operand")
2636
           (udiv:GPR (match_operand:GPR 1 "register_operand")
2637
                     (match_operand:GPR 2 "register_operand")))
2638
      (set (match_operand:GPR 3 "register_operand")
2639
           (umod:GPR (match_dup 1)
2640
                     (match_dup 2)))])]
2641
  "ISA_HAS_DIV && !TARGET_FIX_VR4120 && !TARGET_NO_HW_DIV"
2642
{
2643
  if (TARGET_MIPS16)
2644
    {
2645
      rtx lo = gen_rtx_REG (mode, LO_REGNUM);
2646
      emit_insn (gen_udivmod4_mips16 (operands[0], operands[1],
2647
                                            operands[2], operands[3], lo));
2648
      DONE;
2649
    }
2650
})
2651
 
2652
(define_insn_and_split "*udivmod4"
2653
  [(set (match_operand:GPR 0 "register_operand" "=l")
2654
        (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
2655
                  (match_operand:GPR 2 "register_operand" "d")))
2656
   (set (match_operand:GPR 3 "register_operand" "=d")
2657
        (umod:GPR (match_dup 1)
2658
                  (match_dup 2)))]
2659
  "ISA_HAS_DIV && !TARGET_MIPS16 && !TARGET_NO_HW_DIV"
2660
  "#"
2661
  "reload_completed"
2662
  [(const_int 0)]
2663
{
2664
  emit_insn (gen_udivmod4_split (operands[3], operands[1], operands[2]));
2665
  DONE;
2666
}
2667
  [(set_attr "type" "idiv")
2668
   (set_attr "mode" "")
2669
   (set_attr "insn_count" "2")])
2670
 
2671
;; See the comment above "divmod4_mips16" for the split timing.
2672
(define_insn_and_split "udivmod4_mips16"
2673
  [(set (match_operand:GPR 0 "register_operand" "=d")
2674
        (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
2675
                  (match_operand:GPR 2 "register_operand" "d")))
2676
   (set (match_operand:GPR 3 "register_operand" "=d")
2677
        (umod:GPR (match_dup 1)
2678
                  (match_dup 2)))
2679
   (clobber (match_operand:GPR 4 "lo_operand" "=l"))]
2680
  "ISA_HAS_DIV && TARGET_MIPS16"
2681
  "#"
2682
  "cse_not_expected"
2683
  [(const_int 0)]
2684
{
2685
  emit_insn (gen_udivmod4_split (operands[3], operands[1], operands[2]));
2686
  emit_move_insn (operands[0], operands[4]);
2687
  DONE;
2688
}
2689
  [(set_attr "type" "idiv")
2690
   (set_attr "mode" "")
2691
   (set_attr "insn_count" "3")])
2692
 
2693
(define_expand "divmod4_split"
2694
  [(set (match_operand:GPR 0 "register_operand")
2695
        (any_mod:GPR (match_operand:GPR 1 "register_operand")
2696
                     (match_operand:GPR 2 "register_operand")))]
2697
  ""
2698
{
2699
  rtx hilo;
2700
 
2701
  if (TARGET_64BIT)
2702
    {
2703
      hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2704
      emit_insn (gen_divmod4_hilo_ti (hilo, operands[1],
2705
                                               operands[2]));
2706
      emit_insn (gen_mfhi_ti (operands[0], hilo));
2707
    }
2708
  else
2709
    {
2710
      hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
2711
      emit_insn (gen_divmod4_hilo_di (hilo, operands[1],
2712
                                               operands[2]));
2713
      emit_insn (gen_mfhi_di (operands[0], hilo));
2714
    }
2715
  DONE;
2716
})
2717
 
2718
(define_insn "divmod4_hilo_"
2719
  [(set (match_operand:HILO 0 "muldiv_target_operand" "=x")
2720
        (unspec:HILO
2721
          [(any_div:GPR (match_operand:GPR 1 "register_operand" "d")
2722
                        (match_operand:GPR 2 "register_operand" "d"))]
2723
          UNSPEC_SET_HILO))]
2724
  "ISA_HAS_DIV"
2725
  { return mips_output_division ("div\t%.,%1,%2", operands); }
2726
  [(set_attr "type" "idiv")
2727
   (set_attr "mode" "")])
2728
 
2729
;;
2730
;;  ....................
2731
;;
2732
;;      SQUARE ROOT
2733
;;
2734
;;  ....................
2735
 
2736
;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
2737
;; "*div[sd]f3" comment for details).
2738
 
2739
(define_insn "sqrt2"
2740
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2741
        (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2742
  ""
2743
{
2744
  if (TARGET_FIX_SB1)
2745
    return "sqrt.\t%0,%1\;mov.\t%0,%0";
2746
  else
2747
    return "sqrt.\t%0,%1";
2748
}
2749
  [(set_attr "type" "fsqrt")
2750
   (set_attr "mode" "")
2751
   (set (attr "insn_count")
2752
        (if_then_else (match_test "TARGET_FIX_SB1")
2753
                      (const_int 2)
2754
                      (const_int 1)))])
2755
 
2756
(define_insn "*rsqrta"
2757
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2758
        (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2759
                  (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
2760
  "ISA_HAS_FP_RECIP_RSQRT (mode) && flag_unsafe_math_optimizations"
2761
{
2762
  if (TARGET_FIX_SB1)
2763
    return "rsqrt.\t%0,%2\;mov.\t%0,%0";
2764
  else
2765
    return "rsqrt.\t%0,%2";
2766
}
2767
  [(set_attr "type" "frsqrt")
2768
   (set_attr "mode" "")
2769
   (set (attr "insn_count")
2770
        (if_then_else (match_test "TARGET_FIX_SB1")
2771
                      (const_int 2)
2772
                      (const_int 1)))])
2773
 
2774
(define_insn "*rsqrtb"
2775
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2776
        (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2777
                             (match_operand:ANYF 2 "register_operand" "f"))))]
2778
  "ISA_HAS_FP_RECIP_RSQRT (mode) && flag_unsafe_math_optimizations"
2779
{
2780
  if (TARGET_FIX_SB1)
2781
    return "rsqrt.\t%0,%2\;mov.\t%0,%0";
2782
  else
2783
    return "rsqrt.\t%0,%2";
2784
}
2785
  [(set_attr "type" "frsqrt")
2786
   (set_attr "mode" "")
2787
   (set (attr "insn_count")
2788
        (if_then_else (match_test "TARGET_FIX_SB1")
2789
                      (const_int 2)
2790
                      (const_int 1)))])
2791
 
2792
;;
2793
;;  ....................
2794
;;
2795
;;      ABSOLUTE VALUE
2796
;;
2797
;;  ....................
2798
 
2799
;; Do not use the integer abs macro instruction, since that signals an
2800
;; exception on -2147483648 (sigh).
2801
 
2802
;; The "legacy" (as opposed to "2008") form of ABS.fmt is an arithmetic
2803
;; instruction that treats all NaN inputs as invalid; it does not clear
2804
;; their sign bit.  We therefore can't use that form if the signs of
2805
;; NaNs matter.
2806
 
2807
(define_insn "abs2"
2808
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2809
        (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2810
  "mips_abs == MIPS_IEEE_754_2008 || !HONOR_NANS (mode)"
2811
  "abs.\t%0,%1"
2812
  [(set_attr "type" "fabs")
2813
   (set_attr "mode" "")])
2814
 
2815
;;
2816
;;  ...................
2817
;;
2818
;;  Count leading zeroes.
2819
;;
2820
;;  ...................
2821
;;
2822
 
2823
(define_insn "clz2"
2824
  [(set (match_operand:GPR 0 "register_operand" "=d")
2825
        (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2826
  "ISA_HAS_CLZ_CLO"
2827
  "clz\t%0,%1"
2828
  [(set_attr "type" "clz")
2829
   (set_attr "mode" "")])
2830
 
2831
;;
2832
;;  ...................
2833
;;
2834
;;  Count number of set bits.
2835
;;
2836
;;  ...................
2837
;;
2838
 
2839
(define_insn "popcount2"
2840
  [(set (match_operand:GPR 0 "register_operand" "=d")
2841
        (popcount:GPR (match_operand:GPR 1 "register_operand" "d")))]
2842
  "ISA_HAS_POP"
2843
  "pop\t%0,%1"
2844
  [(set_attr "type" "pop")
2845
   (set_attr "mode" "")])
2846
 
2847
;; The POP instruction is special as it does not take into account the upper
2848
;; 32bits and is documented that way.
2849
(define_insn "*popcountdi2_trunc"
2850
  [(set (match_operand:SI 0 "register_operand" "=d")
2851
       (popcount:SI (truncate:SI (match_operand:DI 1 "register_operand" "d"))))]
2852
  "ISA_HAS_POP && TARGET_64BIT"
2853
  "pop\t%0,%1"
2854
  [(set_attr "type" "pop")
2855
   (set_attr "mode" "SI")])
2856
 
2857
;;
2858
;;  ....................
2859
;;
2860
;;      NEGATION and ONE'S COMPLEMENT
2861
;;
2862
;;  ....................
2863
 
2864
(define_insn "negsi2"
2865
  [(set (match_operand:SI 0 "register_operand" "=d")
2866
        (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2867
  ""
2868
{
2869
  if (TARGET_MIPS16)
2870
    return "neg\t%0,%1";
2871
  else
2872
    return "subu\t%0,%.,%1";
2873
}
2874
  [(set_attr "alu_type" "sub")
2875
   (set_attr "mode"     "SI")])
2876
 
2877
(define_insn "negdi2"
2878
  [(set (match_operand:DI 0 "register_operand" "=d")
2879
        (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2880
  "TARGET_64BIT && !TARGET_MIPS16"
2881
  "dsubu\t%0,%.,%1"
2882
  [(set_attr "alu_type" "sub")
2883
   (set_attr "mode"     "DI")])
2884
 
2885
;; The "legacy" (as opposed to "2008") form of NEG.fmt is an arithmetic
2886
;; instruction that treats all NaN inputs as invalid; it does not flip
2887
;; their sign bit.  We therefore can't use that form if the signs of
2888
;; NaNs matter.
2889
 
2890
(define_insn "neg2"
2891
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2892
        (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2893
  "mips_abs == MIPS_IEEE_754_2008 || !HONOR_NANS (mode)"
2894
  "neg.\t%0,%1"
2895
  [(set_attr "type" "fneg")
2896
   (set_attr "mode" "")])
2897
 
2898
(define_insn "one_cmpl2"
2899
  [(set (match_operand:GPR 0 "register_operand" "=!u,d")
2900
        (not:GPR (match_operand:GPR 1 "register_operand" "!u,d")))]
2901
  ""
2902
{
2903
  if (TARGET_MIPS16)
2904
    return "not\t%0,%1";
2905
  else
2906
    return "nor\t%0,%.,%1";
2907
}
2908
  [(set_attr "alu_type" "not")
2909
   (set_attr "compression" "micromips,*")
2910
   (set_attr "mode" "")])
2911
 
2912
;;
2913
;;  ....................
2914
;;
2915
;;      LOGICAL
2916
;;
2917
;;  ....................
2918
;;
2919
 
2920
;; Many of these instructions use trivial define_expands, because we
2921
;; want to use a different set of constraints when TARGET_MIPS16.
2922
 
2923
(define_expand "and3"
2924
  [(set (match_operand:GPR 0 "register_operand")
2925
        (and:GPR (match_operand:GPR 1 "register_operand")
2926
                 (match_operand:GPR 2 "and_reg_operand")))])
2927
 
2928
;; The middle-end is not allowed to convert ANDing with 0xffff_ffff into a
2929
;; zero_extendsidi2 because of TRULY_NOOP_TRUNCATION, so handle these here.
2930
;; Note that this variant does not trigger for SI mode because we require
2931
;; a 64-bit HOST_WIDE_INT and 0xffff_ffff wouldn't be a canonical
2932
;; sign-extended SImode value.
2933
;;
2934
;; These are possible combinations for operand 1 and 2.  The table
2935
;; includes both MIPS and MIPS16 cases.  (r=register, mem=memory,
2936
;; 16=MIPS16, x=match, S=split):
2937
;;
2938
;;     \ op1    r/EXT   r/!EXT  mem   r/16   mem/16
2939
;;  op2
2940
;;
2941
;;  andi           x     x
2942
;;  0xff           x     x       x             x
2943
;;  0xffff         x     x       x             x
2944
;;  0xffff_ffff    x     S       x     S       x
2945
;;  low-bitmask    x
2946
;;  register       x     x
2947
;;  register =op1                      x
2948
 
2949
(define_insn "*and3"
2950
  [(set (match_operand:GPR 0 "register_operand" "=d,d,d,!u,d,d,d,!u,d")
2951
        (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "o,o,W,!u,d,d,d,0,d")
2952
                 (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Uean,K,Yx,Yw,!u,d")))]
2953
  "!TARGET_MIPS16 && and_operands_ok (mode, operands[1], operands[2])"
2954
{
2955
  int len;
2956
 
2957
  switch (which_alternative)
2958
    {
2959
    case 0:
2960
      operands[1] = gen_lowpart (QImode, operands[1]);
2961
      return "lbu\t%0,%1";
2962
    case 1:
2963
      operands[1] = gen_lowpart (HImode, operands[1]);
2964
      return "lhu\t%0,%1";
2965
    case 2:
2966
      operands[1] = gen_lowpart (SImode, operands[1]);
2967
      return "lwu\t%0,%1";
2968
    case 3:
2969
    case 4:
2970
      return "andi\t%0,%1,%x2";
2971
    case 5:
2972
      len = low_bitmask_len (mode, INTVAL (operands[2]));
2973
      operands[2] = GEN_INT (len);
2974
      return "ext\t%0,%1,0,%2";
2975
    case 6:
2976
      return "#";
2977
    case 7:
2978
    case 8:
2979
      return "and\t%0,%1,%2";
2980
    default:
2981
      gcc_unreachable ();
2982
    }
2983
}
2984
  [(set_attr "move_type" "load,load,load,andi,andi,ext_ins,shift_shift,logical,logical")
2985
   (set_attr "compression" "*,*,*,micromips,*,*,*,micromips,*")
2986
   (set_attr "mode" "")])
2987
 
2988
(define_insn "*and3_mips16"
2989
  [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
2990
        (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "%W,W,W,d,0")
2991
                 (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Yw,d")))]
2992
  "TARGET_MIPS16 && and_operands_ok (mode, operands[1], operands[2])"
2993
{
2994
  switch (which_alternative)
2995
    {
2996
    case 0:
2997
      operands[1] = gen_lowpart (QImode, operands[1]);
2998
      return "lbu\t%0,%1";
2999
    case 1:
3000
      operands[1] = gen_lowpart (HImode, operands[1]);
3001
      return "lhu\t%0,%1";
3002
    case 2:
3003
      operands[1] = gen_lowpart (SImode, operands[1]);
3004
      return "lwu\t%0,%1";
3005
    case 3:
3006
      return "#";
3007
    case 4:
3008
      return "and\t%0,%2";
3009
    default:
3010
      gcc_unreachable ();
3011
    }
3012
}
3013
  [(set_attr "move_type" "load,load,load,shift_shift,logical")
3014
   (set_attr "mode" "")])
3015
 
3016
(define_expand "ior3"
3017
  [(set (match_operand:GPR 0 "register_operand")
3018
        (ior:GPR (match_operand:GPR 1 "register_operand")
3019
                 (match_operand:GPR 2 "uns_arith_operand")))]
3020
  ""
3021
{
3022
  if (TARGET_MIPS16)
3023
    operands[2] = force_reg (mode, operands[2]);
3024
})
3025
 
3026
(define_insn "*ior3"
3027
  [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
3028
        (ior:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
3029
                 (match_operand:GPR 2 "uns_arith_operand" "!u,d,K")))]
3030
  "!TARGET_MIPS16"
3031
  "@
3032
   or\t%0,%1,%2
3033
   or\t%0,%1,%2
3034
   ori\t%0,%1,%x2"
3035
  [(set_attr "alu_type" "or")
3036
   (set_attr "compression" "micromips,*,*")
3037
   (set_attr "mode" "")])
3038
 
3039
(define_insn "*ior3_mips16"
3040
  [(set (match_operand:GPR 0 "register_operand" "=d")
3041
        (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
3042
                 (match_operand:GPR 2 "register_operand" "d")))]
3043
  "TARGET_MIPS16"
3044
  "or\t%0,%2"
3045
  [(set_attr "alu_type" "or")
3046
   (set_attr "mode" "")])
3047
 
3048
(define_expand "xor3"
3049
  [(set (match_operand:GPR 0 "register_operand")
3050
        (xor:GPR (match_operand:GPR 1 "register_operand")
3051
                 (match_operand:GPR 2 "uns_arith_operand")))]
3052
  ""
3053
  "")
3054
 
3055
(define_insn "*xor3"
3056
  [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
3057
        (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
3058
                 (match_operand:GPR 2 "uns_arith_operand" "!u,d,K")))]
3059
  "!TARGET_MIPS16"
3060
  "@
3061
   xor\t%0,%1,%2
3062
   xor\t%0,%1,%2
3063
   xori\t%0,%1,%x2"
3064
  [(set_attr "alu_type" "xor")
3065
   (set_attr "compression" "micromips,*,*")
3066
   (set_attr "mode" "")])
3067
 
3068
(define_insn "*xor3_mips16"
3069
  [(set (match_operand:GPR 0 "register_operand" "=d,t,t,t")
3070
        (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d,d")
3071
                 (match_operand:GPR 2 "uns_arith_operand" "d,Uub8,K,d")))]
3072
  "TARGET_MIPS16"
3073
  "@
3074
   xor\t%0,%2
3075
   cmpi\t%1,%2
3076
   cmpi\t%1,%2
3077
   cmp\t%1,%2"
3078
  [(set_attr "alu_type" "xor")
3079
   (set_attr "mode" "")
3080
   (set_attr "extended_mips16" "no,no,yes,no")])
3081
 
3082
(define_insn "*nor3"
3083
  [(set (match_operand:GPR 0 "register_operand" "=d")
3084
        (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
3085
                 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
3086
  "!TARGET_MIPS16"
3087
  "nor\t%0,%1,%2"
3088
  [(set_attr "alu_type" "nor")
3089
   (set_attr "mode" "")])
3090
 
3091
;;
3092
;;  ....................
3093
;;
3094
;;      TRUNCATION
3095
;;
3096
;;  ....................
3097
 
3098
 
3099
 
3100
(define_insn "truncdfsf2"
3101
  [(set (match_operand:SF 0 "register_operand" "=f")
3102
        (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3103
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3104
  "cvt.s.d\t%0,%1"
3105
  [(set_attr "type"     "fcvt")
3106
   (set_attr "cnv_mode" "D2S")
3107
   (set_attr "mode"     "SF")])
3108
 
3109
;; Integer truncation patterns.  Truncating SImode values to smaller
3110
;; modes is a no-op, as it is for most other GCC ports.  Truncating
3111
;; DImode values to SImode is not a no-op for TARGET_64BIT since we
3112
;; need to make sure that the lower 32 bits are properly sign-extended
3113
;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
3114
;; smaller than SImode is equivalent to two separate truncations:
3115
;;
3116
;;                        A       B
3117
;;    DI ---> HI  ==  DI ---> SI ---> HI
3118
;;    DI ---> QI  ==  DI ---> SI ---> QI
3119
;;
3120
;; Step A needs a real instruction but step B does not.
3121
 
3122
(define_insn "truncdi2"
3123
  [(set (match_operand:SUBDI 0 "nonimmediate_operand" "=d,m")
3124
        (truncate:SUBDI (match_operand:DI 1 "register_operand" "d,d")))]
3125
  "TARGET_64BIT"
3126
  "@
3127
    sll\t%0,%1,0
3128
    \t%1,%0"
3129
  [(set_attr "move_type" "sll0,store")
3130
   (set_attr "mode" "SI")])
3131
 
3132
;; Combiner patterns to optimize shift/truncate combinations.
3133
 
3134
(define_insn "*ashr_trunc"
3135
  [(set (match_operand:SUBDI 0 "register_operand" "=d")
3136
        (truncate:SUBDI
3137
          (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
3138
                       (match_operand:DI 2 "const_arith_operand" ""))))]
3139
  "TARGET_64BIT && !TARGET_MIPS16 && IN_RANGE (INTVAL (operands[2]), 32, 63)"
3140
  "dsra\t%0,%1,%2"
3141
  [(set_attr "type" "shift")
3142
   (set_attr "mode" "")])
3143
 
3144
(define_insn "*lshr32_trunc"
3145
  [(set (match_operand:SUBDI 0 "register_operand" "=d")
3146
        (truncate:SUBDI
3147
          (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
3148
                       (const_int 32))))]
3149
  "TARGET_64BIT && !TARGET_MIPS16"
3150
  "dsra\t%0,%1,32"
3151
  [(set_attr "type" "shift")
3152
   (set_attr "mode" "")])
3153
 
3154
;; Logical shift by more than 32 results in proper SI values so truncation is
3155
;; removed by the middle end.  Note that a logical shift by 32 is handled by
3156
;; the previous pattern.
3157
(define_insn "*_trunc_exts"
3158
  [(set (match_operand:SUBDI 0 "register_operand" "=d")
3159
        (truncate:SUBDI
3160
         (any_shiftrt:DI (match_operand:DI 1 "register_operand" "d")
3161
                         (match_operand:DI 2 "const_arith_operand" ""))))]
3162
  "ISA_HAS_EXTS && TARGET_64BIT && UINTVAL (operands[2]) < 32"
3163
  "exts\t%0,%1,%2,31"
3164
  [(set_attr "type" "arith")
3165
   (set_attr "mode" "")])
3166
 
3167
;;
3168
;;  ....................
3169
;;
3170
;;      ZERO EXTENSION
3171
;;
3172
;;  ....................
3173
 
3174
;; Extension insns.
3175
 
3176
(define_expand "zero_extendsidi2"
3177
  [(set (match_operand:DI 0 "register_operand")
3178
        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3179
  "TARGET_64BIT")
3180
 
3181
(define_insn_and_split "*zero_extendsidi2"
3182
  [(set (match_operand:DI 0 "register_operand" "=d,d")
3183
        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
3184
  "TARGET_64BIT && !ISA_HAS_EXT_INS"
3185
  "@
3186
   #
3187
   lwu\t%0,%1"
3188
  "&& reload_completed && REG_P (operands[1])"
3189
  [(set (match_dup 0)
3190
        (ashift:DI (match_dup 1) (const_int 32)))
3191
   (set (match_dup 0)
3192
        (lshiftrt:DI (match_dup 0) (const_int 32)))]
3193
  { operands[1] = gen_lowpart (DImode, operands[1]); }
3194
  [(set_attr "move_type" "shift_shift,load")
3195
   (set_attr "mode" "DI")])
3196
 
3197
(define_insn "*zero_extendsidi2_dext"
3198
  [(set (match_operand:DI 0 "register_operand" "=d,d")
3199
        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
3200
  "TARGET_64BIT && ISA_HAS_EXT_INS"
3201
  "@
3202
   dext\t%0,%1,0,32
3203
   lwu\t%0,%1"
3204
  [(set_attr "move_type" "arith,load")
3205
   (set_attr "mode" "DI")])
3206
 
3207
;; See the comment before the *and3 pattern why this is generated by
3208
;; combine.
3209
 
3210
(define_split
3211
  [(set (match_operand:DI 0 "register_operand")
3212
        (and:DI (match_operand:DI 1 "register_operand")
3213
                (const_int 4294967295)))]
3214
  "TARGET_64BIT && !ISA_HAS_EXT_INS && reload_completed"
3215
  [(set (match_dup 0)
3216
        (ashift:DI (match_dup 1) (const_int 32)))
3217
   (set (match_dup 0)
3218
        (lshiftrt:DI (match_dup 0) (const_int 32)))])
3219
 
3220
(define_expand "zero_extend2"
3221
  [(set (match_operand:GPR 0 "register_operand")
3222
        (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
3223
  ""
3224
{
3225
  if (TARGET_MIPS16 && !GENERATE_MIPS16E
3226
      && !memory_operand (operands[1], mode))
3227
    {
3228
      emit_insn (gen_and3 (operands[0],
3229
                                     gen_lowpart (mode, operands[1]),
3230
                                     force_reg (mode,
3231
                                                GEN_INT ())));
3232
      DONE;
3233
    }
3234
})
3235
 
3236
(define_insn "*zero_extend2"
3237
  [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
3238
        (zero_extend:GPR
3239
             (match_operand:SHORT 1 "nonimmediate_operand" "!u,d,m")))]
3240
  "!TARGET_MIPS16"
3241
  "@
3242
   andi\t%0,%1,
3243
   andi\t%0,%1,
3244
   lu\t%0,%1"
3245
  [(set_attr "move_type" "andi,andi,load")
3246
   (set_attr "compression" "micromips,*,*")
3247
   (set_attr "mode" "")])
3248
 
3249
(define_insn "*zero_extend2_mips16e"
3250
  [(set (match_operand:GPR 0 "register_operand" "=d")
3251
        (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
3252
  "GENERATE_MIPS16E"
3253
  "ze\t%0"
3254
  ;; This instruction is effectively a special encoding of ANDI.
3255
  [(set_attr "move_type" "andi")
3256
   (set_attr "mode" "")])
3257
 
3258
(define_insn "*zero_extend2_mips16"
3259
  [(set (match_operand:GPR 0 "register_operand" "=d")
3260
        (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
3261
  "TARGET_MIPS16"
3262
  "lu\t%0,%1"
3263
  [(set_attr "move_type" "load")
3264
   (set_attr "mode" "")])
3265
 
3266
(define_expand "zero_extendqihi2"
3267
  [(set (match_operand:HI 0 "register_operand")
3268
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3269
  ""
3270
{
3271
  if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
3272
    {
3273
      emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
3274
                                       operands[1]));
3275
      DONE;
3276
    }
3277
})
3278
 
3279
(define_insn "*zero_extendqihi2"
3280
  [(set (match_operand:HI 0 "register_operand" "=d,d")
3281
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3282
  "!TARGET_MIPS16"
3283
  "@
3284
   andi\t%0,%1,0x00ff
3285
   lbu\t%0,%1"
3286
  [(set_attr "move_type" "andi,load")
3287
   (set_attr "mode" "HI")])
3288
 
3289
(define_insn "*zero_extendqihi2_mips16"
3290
  [(set (match_operand:HI 0 "register_operand" "=d")
3291
        (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3292
  "TARGET_MIPS16"
3293
  "lbu\t%0,%1"
3294
  [(set_attr "move_type" "load")
3295
   (set_attr "mode" "HI")])
3296
 
3297
;; Combiner patterns to optimize truncate/zero_extend combinations.
3298
 
3299
(define_insn "*zero_extend_trunc"
3300
  [(set (match_operand:GPR 0 "register_operand" "=d")
3301
        (zero_extend:GPR
3302
            (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3303
  "TARGET_64BIT && !TARGET_MIPS16"
3304
{
3305
  operands[2] = GEN_INT (GET_MODE_MASK (mode));
3306
  return "andi\t%0,%1,%x2";
3307
}
3308
  [(set_attr "alu_type" "and")
3309
   (set_attr "mode" "")])
3310
 
3311
(define_insn "*zero_extendhi_truncqi"
3312
  [(set (match_operand:HI 0 "register_operand" "=d")
3313
        (zero_extend:HI
3314
            (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3315
  "TARGET_64BIT && !TARGET_MIPS16"
3316
  "andi\t%0,%1,0xff"
3317
  [(set_attr "alu_type" "and")
3318
   (set_attr "mode" "HI")])
3319
 
3320
;;
3321
;;  ....................
3322
;;
3323
;;      SIGN EXTENSION
3324
;;
3325
;;  ....................
3326
 
3327
;; Extension insns.
3328
;; Those for integer source operand are ordered widest source type first.
3329
 
3330
;; When TARGET_64BIT, all SImode integer and accumulator registers
3331
;; should already be in sign-extended form (see TRULY_NOOP_TRUNCATION
3332
;; and truncdisi2).  We can therefore get rid of register->register
3333
;; instructions if we constrain the source to be in the same register as
3334
;; the destination.
3335
;;
3336
;; Only the pre-reload scheduler sees the type of the register alternatives;
3337
;; we split them into nothing before the post-reload scheduler runs.
3338
;; These alternatives therefore have type "move" in order to reflect
3339
;; what happens if the two pre-reload operands cannot be tied, and are
3340
;; instead allocated two separate GPRs.  We don't distinguish between
3341
;; the GPR and LO cases because we don't usually know during pre-reload
3342
;; scheduling whether an operand will be LO or not.
3343
(define_insn_and_split "extendsidi2"
3344
  [(set (match_operand:DI 0 "register_operand" "=d,l,d")
3345
        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,0,m")))]
3346
  "TARGET_64BIT"
3347
  "@
3348
   #
3349
   #
3350
   lw\t%0,%1"
3351
  "&& reload_completed && register_operand (operands[1], VOIDmode)"
3352
  [(const_int 0)]
3353
{
3354
  emit_note (NOTE_INSN_DELETED);
3355
  DONE;
3356
}
3357
  [(set_attr "move_type" "move,move,load")
3358
   (set_attr "mode" "DI")])
3359
 
3360
(define_expand "extend2"
3361
  [(set (match_operand:GPR 0 "register_operand")
3362
        (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
3363
  "")
3364
 
3365
(define_insn "*extend2_mips16e"
3366
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
3367
        (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
3368
  "GENERATE_MIPS16E"
3369
  "@
3370
   se\t%0
3371
   l\t%0,%1"
3372
  [(set_attr "move_type" "signext,load")
3373
   (set_attr "mode" "")])
3374
 
3375
(define_insn_and_split "*extend2"
3376
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
3377
        (sign_extend:GPR
3378
             (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
3379
  "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
3380
  "@
3381
   #
3382
   l\t%0,%1"
3383
  "&& reload_completed && REG_P (operands[1])"
3384
  [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
3385
   (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
3386
{
3387
  operands[1] = gen_lowpart (mode, operands[1]);
3388
  operands[2] = GEN_INT (GET_MODE_BITSIZE (mode)
3389
                         - GET_MODE_BITSIZE (mode));
3390
}
3391
  [(set_attr "move_type" "shift_shift,load")
3392
   (set_attr "mode" "")])
3393
 
3394
(define_insn "*extend2_se"
3395
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
3396
        (sign_extend:GPR
3397
             (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
3398
  "ISA_HAS_SEB_SEH"
3399
  "@
3400
   se\t%0,%1
3401
   l\t%0,%1"
3402
  [(set_attr "move_type" "signext,load")
3403
   (set_attr "mode" "")])
3404
 
3405
(define_expand "extendqihi2"
3406
  [(set (match_operand:HI 0 "register_operand")
3407
        (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3408
  "")
3409
 
3410
(define_insn "*extendqihi2_mips16e"
3411
  [(set (match_operand:HI 0 "register_operand" "=d,d")
3412
        (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,m")))]
3413
  "GENERATE_MIPS16E"
3414
  "@
3415
   seb\t%0
3416
   lb\t%0,%1"
3417
  [(set_attr "move_type" "signext,load")
3418
   (set_attr "mode" "SI")])
3419
 
3420
(define_insn_and_split "*extendqihi2"
3421
  [(set (match_operand:HI 0 "register_operand" "=d,d")
3422
        (sign_extend:HI
3423
             (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3424
  "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
3425
  "@
3426
   #
3427
   lb\t%0,%1"
3428
  "&& reload_completed && REG_P (operands[1])"
3429
  [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
3430
   (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
3431
{
3432
  operands[0] = gen_lowpart (SImode, operands[0]);
3433
  operands[1] = gen_lowpart (SImode, operands[1]);
3434
  operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
3435
                         - GET_MODE_BITSIZE (QImode));
3436
}
3437
  [(set_attr "move_type" "shift_shift,load")
3438
   (set_attr "mode" "SI")])
3439
 
3440
(define_insn "*extendqihi2_seb"
3441
  [(set (match_operand:HI 0 "register_operand" "=d,d")
3442
        (sign_extend:HI
3443
             (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3444
  "ISA_HAS_SEB_SEH"
3445
  "@
3446
   seb\t%0,%1
3447
   lb\t%0,%1"
3448
  [(set_attr "move_type" "signext,load")
3449
   (set_attr "mode" "SI")])
3450
 
3451
;; Combiner patterns for truncate/sign_extend combinations.  The SI versions
3452
;; use the shift/truncate patterns.
3453
 
3454
(define_insn_and_split "*extenddi_truncate"
3455
  [(set (match_operand:DI 0 "register_operand" "=d")
3456
        (sign_extend:DI
3457
            (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3458
  "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3459
  "#"
3460
  "&& reload_completed"
3461
  [(set (match_dup 2)
3462
        (ashift:DI (match_dup 1)
3463
                   (match_dup 3)))
3464
   (set (match_dup 0)
3465
        (ashiftrt:DI (match_dup 2)
3466
                     (match_dup 3)))]
3467
{
3468
  operands[2] = gen_lowpart (DImode, operands[0]);
3469
  operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (mode));
3470
}
3471
  [(set_attr "move_type" "shift_shift")
3472
   (set_attr "mode" "DI")])
3473
 
3474
(define_insn_and_split "*extendsi_truncate"
3475
  [(set (match_operand:SI 0 "register_operand" "=d")
3476
        (sign_extend:SI
3477
            (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3478
  "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3479
  "#"
3480
  "&& reload_completed"
3481
  [(set (match_dup 2)
3482
        (ashift:DI (match_dup 1)
3483
                   (match_dup 3)))
3484
   (set (match_dup 0)
3485
        (truncate:SI (ashiftrt:DI (match_dup 2)
3486
                                  (match_dup 3))))]
3487
{
3488
  operands[2] = gen_lowpart (DImode, operands[0]);
3489
  operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (mode));
3490
}
3491
  [(set_attr "move_type" "shift_shift")
3492
   (set_attr "mode" "SI")])
3493
 
3494
(define_insn_and_split "*extendhi_truncateqi"
3495
  [(set (match_operand:HI 0 "register_operand" "=d")
3496
        (sign_extend:HI
3497
            (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3498
  "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3499
  "#"
3500
  "&& reload_completed"
3501
  [(set (match_dup 2)
3502
        (ashift:DI (match_dup 1)
3503
                   (const_int 56)))
3504
   (set (match_dup 0)
3505
        (truncate:HI (ashiftrt:DI (match_dup 2)
3506
                                  (const_int 56))))]
3507
{
3508
  operands[2] = gen_lowpart (DImode, operands[0]);
3509
}
3510
  [(set_attr "move_type" "shift_shift")
3511
   (set_attr "mode" "SI")])
3512
 
3513
(define_insn "*extend_truncate_exts"
3514
  [(set (match_operand:GPR 0 "register_operand" "=d")
3515
        (sign_extend:GPR
3516
            (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3517
  "TARGET_64BIT && !TARGET_MIPS16 && ISA_HAS_EXTS"
3518
{
3519
  operands[2] = GEN_INT (GET_MODE_BITSIZE (mode));
3520
  return "exts\t%0,%1,0,%m2";
3521
}
3522
  [(set_attr "type" "arith")
3523
   (set_attr "mode" "")])
3524
 
3525
(define_insn "*extendhi_truncateqi_exts"
3526
  [(set (match_operand:HI 0 "register_operand" "=d")
3527
        (sign_extend:HI
3528
            (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3529
  "TARGET_64BIT && !TARGET_MIPS16 && ISA_HAS_EXTS"
3530
  "exts\t%0,%1,0,7"
3531
  [(set_attr "type" "arith")
3532
   (set_attr "mode" "SI")])
3533
 
3534
(define_insn "extendsfdf2"
3535
  [(set (match_operand:DF 0 "register_operand" "=f")
3536
        (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3537
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3538
  "cvt.d.s\t%0,%1"
3539
  [(set_attr "type"     "fcvt")
3540
   (set_attr "cnv_mode" "S2D")
3541
   (set_attr "mode"     "DF")])
3542
 
3543
;;
3544
;;  ....................
3545
;;
3546
;;      CONVERSIONS
3547
;;
3548
;;  ....................
3549
 
3550
(define_expand "fix_truncdfsi2"
3551
  [(set (match_operand:SI 0 "register_operand")
3552
        (fix:SI (match_operand:DF 1 "register_operand")))]
3553
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3554
{
3555
  if (!ISA_HAS_TRUNC_W)
3556
    {
3557
      emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3558
      DONE;
3559
    }
3560
})
3561
 
3562
(define_insn "fix_truncdfsi2_insn"
3563
  [(set (match_operand:SI 0 "register_operand" "=f")
3564
        (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3565
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3566
  "trunc.w.d %0,%1"
3567
  [(set_attr "type"     "fcvt")
3568
   (set_attr "mode"     "DF")
3569
   (set_attr "cnv_mode" "D2I")])
3570
 
3571
(define_insn "fix_truncdfsi2_macro"
3572
  [(set (match_operand:SI 0 "register_operand" "=f")
3573
        (fix:SI (match_operand:DF 1 "register_operand" "f")))
3574
   (clobber (match_scratch:DF 2 "=d"))]
3575
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3576
{
3577
  if (mips_nomacro.nesting_level > 0)
3578
    return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3579
  else
3580
    return "trunc.w.d %0,%1,%2";
3581
}
3582
  [(set_attr "type"     "fcvt")
3583
   (set_attr "mode"     "DF")
3584
   (set_attr "cnv_mode" "D2I")
3585
   (set_attr "insn_count" "9")])
3586
 
3587
(define_expand "fix_truncsfsi2"
3588
  [(set (match_operand:SI 0 "register_operand")
3589
        (fix:SI (match_operand:SF 1 "register_operand")))]
3590
  "TARGET_HARD_FLOAT"
3591
{
3592
  if (!ISA_HAS_TRUNC_W)
3593
    {
3594
      emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3595
      DONE;
3596
    }
3597
})
3598
 
3599
(define_insn "fix_truncsfsi2_insn"
3600
  [(set (match_operand:SI 0 "register_operand" "=f")
3601
        (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3602
  "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3603
  "trunc.w.s %0,%1"
3604
  [(set_attr "type"     "fcvt")
3605
   (set_attr "mode"     "SF")
3606
   (set_attr "cnv_mode" "S2I")])
3607
 
3608
(define_insn "fix_truncsfsi2_macro"
3609
  [(set (match_operand:SI 0 "register_operand" "=f")
3610
        (fix:SI (match_operand:SF 1 "register_operand" "f")))
3611
   (clobber (match_scratch:SF 2 "=d"))]
3612
  "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3613
{
3614
  if (mips_nomacro.nesting_level > 0)
3615
    return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3616
  else
3617
    return "trunc.w.s %0,%1,%2";
3618
}
3619
  [(set_attr "type"     "fcvt")
3620
   (set_attr "mode"     "SF")
3621
   (set_attr "cnv_mode" "S2I")
3622
   (set_attr "insn_count" "9")])
3623
 
3624
 
3625
(define_insn "fix_truncdfdi2"
3626
  [(set (match_operand:DI 0 "register_operand" "=f")
3627
        (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3628
  "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3629
  "trunc.l.d %0,%1"
3630
  [(set_attr "type"     "fcvt")
3631
   (set_attr "mode"     "DF")
3632
   (set_attr "cnv_mode" "D2I")])
3633
 
3634
 
3635
(define_insn "fix_truncsfdi2"
3636
  [(set (match_operand:DI 0 "register_operand" "=f")
3637
        (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3638
  "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3639
  "trunc.l.s %0,%1"
3640
  [(set_attr "type"     "fcvt")
3641
   (set_attr "mode"     "SF")
3642
   (set_attr "cnv_mode" "S2I")])
3643
 
3644
 
3645
(define_insn "floatsidf2"
3646
  [(set (match_operand:DF 0 "register_operand" "=f")
3647
        (float:DF (match_operand:SI 1 "register_operand" "f")))]
3648
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3649
  "cvt.d.w\t%0,%1"
3650
  [(set_attr "type"     "fcvt")
3651
   (set_attr "mode"     "DF")
3652
   (set_attr "cnv_mode" "I2D")])
3653
 
3654
 
3655
(define_insn "floatdidf2"
3656
  [(set (match_operand:DF 0 "register_operand" "=f")
3657
        (float:DF (match_operand:DI 1 "register_operand" "f")))]
3658
  "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3659
  "cvt.d.l\t%0,%1"
3660
  [(set_attr "type"     "fcvt")
3661
   (set_attr "mode"     "DF")
3662
   (set_attr "cnv_mode" "I2D")])
3663
 
3664
 
3665
(define_insn "floatsisf2"
3666
  [(set (match_operand:SF 0 "register_operand" "=f")
3667
        (float:SF (match_operand:SI 1 "register_operand" "f")))]
3668
  "TARGET_HARD_FLOAT"
3669
  "cvt.s.w\t%0,%1"
3670
  [(set_attr "type"     "fcvt")
3671
   (set_attr "mode"     "SF")
3672
   (set_attr "cnv_mode" "I2S")])
3673
 
3674
 
3675
(define_insn "floatdisf2"
3676
  [(set (match_operand:SF 0 "register_operand" "=f")
3677
        (float:SF (match_operand:DI 1 "register_operand" "f")))]
3678
  "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3679
  "cvt.s.l\t%0,%1"
3680
  [(set_attr "type"     "fcvt")
3681
   (set_attr "mode"     "SF")
3682
   (set_attr "cnv_mode" "I2S")])
3683
 
3684
 
3685
(define_expand "fixuns_truncdfsi2"
3686
  [(set (match_operand:SI 0 "register_operand")
3687
        (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
3688
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3689
{
3690
  rtx reg1 = gen_reg_rtx (DFmode);
3691
  rtx reg2 = gen_reg_rtx (DFmode);
3692
  rtx reg3 = gen_reg_rtx (SImode);
3693
  rtx label1 = gen_label_rtx ();
3694
  rtx label2 = gen_label_rtx ();
3695
  rtx test;
3696
  REAL_VALUE_TYPE offset;
3697
 
3698
  real_2expN (&offset, 31, DFmode);
3699
 
3700
  if (reg1)                     /* Turn off complaints about unreached code.  */
3701
    {
3702
      mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3703
      do_pending_stack_adjust ();
3704
 
3705
      test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3706
      emit_jump_insn (gen_cbranchdf4 (test, operands[1], reg1, label1));
3707
 
3708
      emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3709
      emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3710
                                   gen_rtx_LABEL_REF (VOIDmode, label2)));
3711
      emit_barrier ();
3712
 
3713
      emit_label (label1);
3714
      mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3715
      mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
3716
                                     (BITMASK_HIGH, SImode)));
3717
 
3718
      emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3719
      emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3720
 
3721
      emit_label (label2);
3722
 
3723
      /* Allow REG_NOTES to be set on last insn (labels don't have enough
3724
         fields, and can't be used for REG_NOTES anyway).  */
3725
      emit_use (stack_pointer_rtx);
3726
      DONE;
3727
    }
3728
})
3729
 
3730
 
3731
(define_expand "fixuns_truncdfdi2"
3732
  [(set (match_operand:DI 0 "register_operand")
3733
        (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3734
  "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3735
{
3736
  rtx reg1 = gen_reg_rtx (DFmode);
3737
  rtx reg2 = gen_reg_rtx (DFmode);
3738
  rtx reg3 = gen_reg_rtx (DImode);
3739
  rtx label1 = gen_label_rtx ();
3740
  rtx label2 = gen_label_rtx ();
3741
  rtx test;
3742
  REAL_VALUE_TYPE offset;
3743
 
3744
  real_2expN (&offset, 63, DFmode);
3745
 
3746
  mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3747
  do_pending_stack_adjust ();
3748
 
3749
  test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3750
  emit_jump_insn (gen_cbranchdf4 (test, operands[1], reg1, label1));
3751
 
3752
  emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3753
  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3754
                               gen_rtx_LABEL_REF (VOIDmode, label2)));
3755
  emit_barrier ();
3756
 
3757
  emit_label (label1);
3758
  mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3759
  mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
3760
  emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3761
 
3762
  emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3763
  emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3764
 
3765
  emit_label (label2);
3766
 
3767
  /* Allow REG_NOTES to be set on last insn (labels don't have enough
3768
     fields, and can't be used for REG_NOTES anyway).  */
3769
  emit_use (stack_pointer_rtx);
3770
  DONE;
3771
})
3772
 
3773
 
3774
(define_expand "fixuns_truncsfsi2"
3775
  [(set (match_operand:SI 0 "register_operand")
3776
        (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3777
  "TARGET_HARD_FLOAT"
3778
{
3779
  rtx reg1 = gen_reg_rtx (SFmode);
3780
  rtx reg2 = gen_reg_rtx (SFmode);
3781
  rtx reg3 = gen_reg_rtx (SImode);
3782
  rtx label1 = gen_label_rtx ();
3783
  rtx label2 = gen_label_rtx ();
3784
  rtx test;
3785
  REAL_VALUE_TYPE offset;
3786
 
3787
  real_2expN (&offset, 31, SFmode);
3788
 
3789
  mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3790
  do_pending_stack_adjust ();
3791
 
3792
  test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3793
  emit_jump_insn (gen_cbranchsf4 (test, operands[1], reg1, label1));
3794
 
3795
  emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3796
  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3797
                               gen_rtx_LABEL_REF (VOIDmode, label2)));
3798
  emit_barrier ();
3799
 
3800
  emit_label (label1);
3801
  mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3802
  mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
3803
                                 (BITMASK_HIGH, SImode)));
3804
 
3805
  emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3806
  emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3807
 
3808
  emit_label (label2);
3809
 
3810
  /* Allow REG_NOTES to be set on last insn (labels don't have enough
3811
     fields, and can't be used for REG_NOTES anyway).  */
3812
  emit_use (stack_pointer_rtx);
3813
  DONE;
3814
})
3815
 
3816
 
3817
(define_expand "fixuns_truncsfdi2"
3818
  [(set (match_operand:DI 0 "register_operand")
3819
        (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3820
  "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3821
{
3822
  rtx reg1 = gen_reg_rtx (SFmode);
3823
  rtx reg2 = gen_reg_rtx (SFmode);
3824
  rtx reg3 = gen_reg_rtx (DImode);
3825
  rtx label1 = gen_label_rtx ();
3826
  rtx label2 = gen_label_rtx ();
3827
  rtx test;
3828
  REAL_VALUE_TYPE offset;
3829
 
3830
  real_2expN (&offset, 63, SFmode);
3831
 
3832
  mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3833
  do_pending_stack_adjust ();
3834
 
3835
  test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3836
  emit_jump_insn (gen_cbranchsf4 (test, operands[1], reg1, label1));
3837
 
3838
  emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3839
  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3840
                               gen_rtx_LABEL_REF (VOIDmode, label2)));
3841
  emit_barrier ();
3842
 
3843
  emit_label (label1);
3844
  mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3845
  mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
3846
  emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3847
 
3848
  emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3849
  emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3850
 
3851
  emit_label (label2);
3852
 
3853
  /* Allow REG_NOTES to be set on last insn (labels don't have enough
3854
     fields, and can't be used for REG_NOTES anyway).  */
3855
  emit_use (stack_pointer_rtx);
3856
  DONE;
3857
})
3858
 
3859
;;
3860
;;  ....................
3861
;;
3862
;;      DATA MOVEMENT
3863
;;
3864
;;  ....................
3865
 
3866
;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3867
 
3868
(define_expand "extvmisalign"
3869
  [(set (match_operand:GPR 0 "register_operand")
3870
        (sign_extract:GPR (match_operand:BLK 1 "memory_operand")
3871
                          (match_operand 2 "const_int_operand")
3872
                          (match_operand 3 "const_int_operand")))]
3873
  "!TARGET_MIPS16 && !TARGET_PATFREE"
3874
{
3875
  if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3876
                                         INTVAL (operands[2]),
3877
                                         INTVAL (operands[3]),
3878
                                         /*unsigned=*/ false))
3879
    DONE;
3880
  else
3881
    FAIL;
3882
})
3883
 
3884
(define_expand "extv"
3885
  [(set (match_operand:GPR 0 "register_operand")
3886
        (sign_extract:GPR (match_operand:GPR 1 "register_operand")
3887
                          (match_operand 2 "const_int_operand")
3888
                          (match_operand 3 "const_int_operand")))]
3889
  "ISA_HAS_EXTS"
3890
{
3891
  if (UINTVAL (operands[2]) > 32)
3892
    FAIL;
3893
})
3894
 
3895
(define_insn "*extv"
3896
  [(set (match_operand:GPR 0 "register_operand" "=d")
3897
        (sign_extract:GPR (match_operand:GPR 1 "register_operand" "d")
3898
                          (match_operand 2 "const_int_operand" "")
3899
                          (match_operand 3 "const_int_operand" "")))]
3900
  "ISA_HAS_EXTS && UINTVAL (operands[2]) <= 32"
3901
  "exts\t%0,%1,%3,%m2"
3902
  [(set_attr "type"     "arith")
3903
   (set_attr "mode"     "")])
3904
 
3905
(define_expand "extzvmisalign"
3906
  [(set (match_operand:GPR 0 "register_operand")
3907
        (zero_extract:GPR (match_operand:BLK 1 "memory_operand")
3908
                          (match_operand 2 "const_int_operand")
3909
                          (match_operand 3 "const_int_operand")))]
3910
  "!TARGET_MIPS16 && !TARGET_PATFREE"
3911
{
3912
  if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3913
                                         INTVAL (operands[2]),
3914
                                         INTVAL (operands[3]),
3915
                                         /*unsigned=*/ true))
3916
    DONE;
3917
  else
3918
    FAIL;
3919
})
3920
 
3921
(define_expand "extzv"
3922
  [(set (match_operand:GPR 0 "register_operand")
3923
        (zero_extract:GPR (match_operand:GPR 1 "register_operand")
3924
                          (match_operand 2 "const_int_operand")
3925
                          (match_operand 3 "const_int_operand")))]
3926
  ""
3927
{
3928
  if (!mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
3929
                           INTVAL (operands[3])))
3930
    FAIL;
3931
})
3932
 
3933
(define_insn "*extzv"
3934
  [(set (match_operand:GPR 0 "register_operand" "=d")
3935
        (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
3936
                          (match_operand 2 "const_int_operand" "")
3937
                          (match_operand 3 "const_int_operand" "")))]
3938
  "mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
3939
                       INTVAL (operands[3]))"
3940
  "ext\t%0,%1,%3,%2"
3941
  [(set_attr "type"     "arith")
3942
   (set_attr "mode"     "")])
3943
 
3944
(define_insn "*extzv_truncsi_exts"
3945
  [(set (match_operand:SI 0 "register_operand" "=d")
3946
        (truncate:SI
3947
         (zero_extract:DI (match_operand:DI 1 "register_operand" "d")
3948
                          (match_operand 2 "const_int_operand" "")
3949
                          (match_operand 3 "const_int_operand" ""))))]
3950
  "ISA_HAS_EXTS && TARGET_64BIT && IN_RANGE (INTVAL (operands[2]), 32, 63)"
3951
  "exts\t%0,%1,%3,31"
3952
  [(set_attr "type"     "arith")
3953
   (set_attr "mode"     "SI")])
3954
 
3955
 
3956
(define_expand "insvmisalign"
3957
  [(set (zero_extract:GPR (match_operand:BLK 0 "memory_operand")
3958
                          (match_operand 1 "const_int_operand")
3959
                          (match_operand 2 "const_int_operand"))
3960
        (match_operand:GPR 3 "reg_or_0_operand"))]
3961
  "!TARGET_MIPS16 && !TARGET_PATFREE"
3962
{
3963
  if (mips_expand_ins_as_unaligned_store (operands[0], operands[3],
3964
                                          INTVAL (operands[1]),
3965
                                          INTVAL (operands[2])))
3966
    DONE;
3967
  else
3968
    FAIL;
3969
})
3970
 
3971
(define_expand "insv"
3972
  [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand")
3973
                          (match_operand 1 "const_int_operand")
3974
                          (match_operand 2 "const_int_operand"))
3975
        (match_operand:GPR 3 "reg_or_0_operand"))]
3976
  ""
3977
{
3978
  if (!mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
3979
                           INTVAL (operands[2])))
3980
    FAIL;
3981
})
3982
 
3983
(define_insn "*insv"
3984
  [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
3985
                          (match_operand:SI 1 "const_int_operand" "")
3986
                          (match_operand:SI 2 "const_int_operand" ""))
3987
        (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
3988
  "mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
3989
                       INTVAL (operands[2]))"
3990
  "ins\t%0,%z3,%2,%1"
3991
  [(set_attr "type"     "arith")
3992
   (set_attr "mode"     "")])
3993
 
3994
;; Combiner pattern for cins (clear and insert bit field).  We can
3995
;; implement mask-and-shift-left operation with this.  Note that if
3996
;; the upper bit of the mask is set in an SImode operation, the mask
3997
;; itself will be sign-extended.  mask_low_and_shift_len will
3998
;; therefore be greater than our threshold of 32.
3999
 
4000
(define_insn "*cins"
4001
  [(set (match_operand:GPR 0 "register_operand" "=d")
4002
        (and:GPR
4003
         (ashift:GPR (match_operand:GPR 1 "register_operand" "d")
4004
                     (match_operand:GPR 2 "const_int_operand" ""))
4005
         (match_operand:GPR 3 "const_int_operand" "")))]
4006
  "ISA_HAS_CINS
4007
   && mask_low_and_shift_p (mode, operands[3], operands[2], 32)"
4008
{
4009
  operands[3] =
4010
    GEN_INT (mask_low_and_shift_len (mode, operands[3], operands[2]));
4011
  return "cins\t%0,%1,%2,%m3";
4012
}
4013
  [(set_attr "type"     "shift")
4014
   (set_attr "mode"     "")])
4015
 
4016
;; Unaligned word moves generated by the bit field patterns.
4017
;;
4018
;; As far as the rtl is concerned, both the left-part and right-part
4019
;; instructions can access the whole field.  However, the real operand
4020
;; refers to just the first or the last byte (depending on endianness).
4021
;; We therefore use two memory operands to each instruction, one to
4022
;; describe the rtl effect and one to use in the assembly output.
4023
;;
4024
;; Operands 0 and 1 are the rtl-level target and source respectively.
4025
;; This allows us to use the standard length calculations for the "load"
4026
;; and "store" type attributes.
4027
 
4028
(define_insn "mov_l"
4029
  [(set (match_operand:GPR 0 "register_operand" "=d")
4030
        (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
4031
                     (match_operand:QI 2 "memory_operand" "ZC")]
4032
                    UNSPEC_LOAD_LEFT))]
4033
  "!TARGET_MIPS16 && !TARGET_PATFREE && mips_mem_fits_mode_p (mode, operands[1])"
4034
  "l\t%0,%2"
4035
  [(set_attr "move_type" "load")
4036
   (set_attr "mode" "")])
4037
 
4038
(define_insn "mov_r"
4039
  [(set (match_operand:GPR 0 "register_operand" "=d")
4040
        (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
4041
                     (match_operand:QI 2 "memory_operand" "ZC")
4042
                     (match_operand:GPR 3 "register_operand" "0")]
4043
                    UNSPEC_LOAD_RIGHT))]
4044
  "!TARGET_MIPS16 && !TARGET_PATFREE && mips_mem_fits_mode_p (mode, operands[1])"
4045
  "r\t%0,%2"
4046
  [(set_attr "move_type" "load")
4047
   (set_attr "mode" "")])
4048
 
4049
(define_insn "mov_l"
4050
  [(set (match_operand:BLK 0 "memory_operand" "=m")
4051
        (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
4052
                     (match_operand:QI 2 "memory_operand" "ZC")]
4053
                    UNSPEC_STORE_LEFT))]
4054
  "!TARGET_MIPS16 && !TARGET_PATFREE && mips_mem_fits_mode_p (mode, operands[0])"
4055
  "l\t%z1,%2"
4056
  [(set_attr "move_type" "store")
4057
   (set_attr "mode" "")])
4058
 
4059
(define_insn "mov_r"
4060
  [(set (match_operand:BLK 0 "memory_operand" "+m")
4061
        (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
4062
                     (match_operand:QI 2 "memory_operand" "ZC")
4063
                     (match_dup 0)]
4064
                    UNSPEC_STORE_RIGHT))]
4065
  "!TARGET_MIPS16 && !TARGET_PATFREE && mips_mem_fits_mode_p (mode, operands[0])"
4066
  "r\t%z1,%2"
4067
  [(set_attr "move_type" "store")
4068
   (set_attr "mode" "")])
4069
 
4070
;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE.
4071
;; The required value is:
4072
;;
4073
;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
4074
;;
4075
;; which translates to:
4076
;;
4077
;;      lui     op0,%highest(op1)
4078
;;      daddiu  op0,op0,%higher(op1)
4079
;;      dsll    op0,op0,16
4080
;;      daddiu  op0,op0,%hi(op1)
4081
;;      dsll    op0,op0,16
4082
;;
4083
;; The split is deferred until after flow2 to allow the peephole2 below
4084
;; to take effect.
4085
(define_insn_and_split "*lea_high64"
4086
  [(set (match_operand:DI 0 "register_operand" "=d")
4087
        (high:DI (match_operand:DI 1 "absolute_symbolic_operand" "")))]
4088
  "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
4089
  "#"
4090
  "&& epilogue_completed"
4091
  [(set (match_dup 0) (high:DI (match_dup 2)))
4092
   (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
4093
   (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
4094
   (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4095
   (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
4096
{
4097
  operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4098
  operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
4099
}
4100
  [(set_attr "insn_count" "5")])
4101
 
4102
;; Use a scratch register to reduce the latency of the above pattern
4103
;; on superscalar machines.  The optimized sequence is:
4104
;;
4105
;;      lui     op1,%highest(op2)
4106
;;      lui     op0,%hi(op2)
4107
;;      daddiu  op1,op1,%higher(op2)
4108
;;      dsll32  op1,op1,0
4109
;;      daddu   op1,op1,op0
4110
(define_peephole2
4111
  [(set (match_operand:DI 1 "d_operand")
4112
        (high:DI (match_operand:DI 2 "absolute_symbolic_operand")))
4113
   (match_scratch:DI 0 "d")]
4114
  "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
4115
  [(set (match_dup 1) (high:DI (match_dup 3)))
4116
   (set (match_dup 0) (high:DI (match_dup 4)))
4117
   (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
4118
   (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
4119
   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
4120
{
4121
  operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
4122
  operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
4123
})
4124
 
4125
;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
4126
;; SYMBOL_ABSOLUTE X will take 6 cycles.  This next pattern allows combine
4127
;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
4128
;; used once.  We can then use the sequence:
4129
;;
4130
;;      lui     op0,%highest(op1)
4131
;;      lui     op2,%hi(op1)
4132
;;      daddiu  op0,op0,%higher(op1)
4133
;;      daddiu  op2,op2,%lo(op1)
4134
;;      dsll32  op0,op0,0
4135
;;      daddu   op0,op0,op2
4136
;;
4137
;; which takes 4 cycles on most superscalar targets.
4138
(define_insn_and_split "*lea64"
4139
  [(set (match_operand:DI 0 "register_operand" "=d")
4140
        (match_operand:DI 1 "absolute_symbolic_operand" ""))
4141
   (clobber (match_scratch:DI 2 "=&d"))]
4142
  "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
4143
  "#"
4144
  "&& reload_completed"
4145
  [(set (match_dup 0) (high:DI (match_dup 3)))
4146
   (set (match_dup 2) (high:DI (match_dup 4)))
4147
   (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4148
   (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
4149
   (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
4150
   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
4151
{
4152
  operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4153
  operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
4154
}
4155
  [(set_attr "insn_count" "6")])
4156
 
4157
;; Split HIGHs into:
4158
;;
4159
;;      li op0,%hi(sym)
4160
;;      sll op0,16
4161
;;
4162
;; on MIPS16 targets.
4163
(define_split
4164
  [(set (match_operand:P 0 "d_operand")
4165
        (high:P (match_operand:P 1 "symbolic_operand_with_high")))]
4166
  "TARGET_MIPS16 && reload_completed"
4167
  [(set (match_dup 0) (unspec:P [(match_dup 1)] UNSPEC_UNSHIFTED_HIGH))
4168
   (set (match_dup 0) (ashift:P (match_dup 0) (const_int 16)))])
4169
 
4170
(define_insn "*unshifted_high"
4171
  [(set (match_operand:P 0 "d_operand" "=d")
4172
        (unspec:P [(match_operand:P 1 "symbolic_operand_with_high")]
4173
                  UNSPEC_UNSHIFTED_HIGH))]
4174
  ""
4175
  "li\t%0,%h1"
4176
  [(set_attr "extended_mips16" "yes")])
4177
 
4178
;; Insns to fetch a symbol from a big GOT.
4179
 
4180
(define_insn_and_split "*xgot_hi"
4181
  [(set (match_operand:P 0 "register_operand" "=d")
4182
        (high:P (match_operand:P 1 "got_disp_operand" "")))]
4183
  "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4184
  "#"
4185
  "&& reload_completed"
4186
  [(set (match_dup 0) (high:P (match_dup 2)))
4187
   (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
4188
{
4189
  operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
4190
  operands[3] = pic_offset_table_rtx;
4191
}
4192
  [(set_attr "got" "xgot_high")
4193
   (set_attr "mode" "")])
4194
 
4195
(define_insn_and_split "*xgot_lo"
4196
  [(set (match_operand:P 0 "register_operand" "=d")
4197
        (lo_sum:P (match_operand:P 1 "register_operand" "d")
4198
                  (match_operand:P 2 "got_disp_operand" "")))]
4199
  "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4200
  "#"
4201
  "&& reload_completed"
4202
  [(set (match_dup 0)
4203
        (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
4204
  { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_DISP); }
4205
  [(set_attr "got" "load")
4206
   (set_attr "mode" "")])
4207
 
4208
;; Insns to fetch a symbol from a normal GOT.
4209
 
4210
(define_insn_and_split "*got_disp"
4211
  [(set (match_operand:P 0 "register_operand" "=d")
4212
        (match_operand:P 1 "got_disp_operand" ""))]
4213
  "TARGET_EXPLICIT_RELOCS && !mips_split_p[SYMBOL_GOT_DISP]"
4214
  "#"
4215
  "&& reload_completed"
4216
  [(set (match_dup 0) (match_dup 2))]
4217
  { operands[2] = mips_got_load (NULL, operands[1], SYMBOL_GOTOFF_DISP); }
4218
  [(set_attr "got" "load")
4219
   (set_attr "mode" "")])
4220
 
4221
;; Insns for loading the "page" part of a page/ofst address from the GOT.
4222
 
4223
(define_insn_and_split "*got_page"
4224
  [(set (match_operand:P 0 "register_operand" "=d")
4225
        (high:P (match_operand:P 1 "got_page_ofst_operand" "")))]
4226
  "TARGET_EXPLICIT_RELOCS && !mips_split_hi_p[SYMBOL_GOT_PAGE_OFST]"
4227
  "#"
4228
  "&& reload_completed"
4229
  [(set (match_dup 0) (match_dup 2))]
4230
  { operands[2] = mips_got_load (NULL, operands[1], SYMBOL_GOTOFF_PAGE); }
4231
  [(set_attr "got" "load")
4232
   (set_attr "mode" "")])
4233
 
4234
;; Convenience expander that generates the rhs of a load_got insn.
4235
(define_expand "unspec_got_"
4236
  [(unspec:P [(match_operand:P 0)
4237
              (match_operand:P 1)] UNSPEC_LOAD_GOT)])
4238
 
4239
;; Lower-level instructions for loading an address from the GOT.
4240
;; We could use MEMs, but an unspec gives more optimization
4241
;; opportunities.
4242
 
4243
(define_insn "load_got"
4244
  [(set (match_operand:P 0 "register_operand" "=d")
4245
        (unspec:P [(match_operand:P 1 "register_operand" "d")
4246
                   (match_operand:P 2 "immediate_operand" "")]
4247
                  UNSPEC_LOAD_GOT))]
4248
  ""
4249
  "\t%0,%R2(%1)"
4250
  [(set_attr "got" "load")
4251
   (set_attr "mode" "")])
4252
 
4253
;; Instructions for adding the low 16 bits of an address to a register.
4254
;; Operand 2 is the address: mips_print_operand works out which relocation
4255
;; should be applied.
4256
 
4257
(define_insn "*low"
4258
  [(set (match_operand:P 0 "register_operand" "=d")
4259
        (lo_sum:P (match_operand:P 1 "register_operand" "d")
4260
                  (match_operand:P 2 "immediate_operand" "")))]
4261
  "!TARGET_MIPS16"
4262
  "addiu\t%0,%1,%R2"
4263
  [(set_attr "alu_type" "add")
4264
   (set_attr "mode" "")])
4265
 
4266
(define_insn "*low_mips16"
4267
  [(set (match_operand:P 0 "register_operand" "=d")
4268
        (lo_sum:P (match_operand:P 1 "register_operand" "0")
4269
                  (match_operand:P 2 "immediate_operand" "")))]
4270
  "TARGET_MIPS16"
4271
  "addiu\t%0,%R2"
4272
  [(set_attr "alu_type" "add")
4273
   (set_attr "mode" "")
4274
   (set_attr "extended_mips16" "yes")])
4275
 
4276
;; Expose MIPS16 uses of the global pointer after reload if the function
4277
;; is responsible for setting up the register itself.
4278
(define_split
4279
  [(set (match_operand:GPR 0 "d_operand")
4280
        (const:GPR (unspec:GPR [(const_int 0)] UNSPEC_GP)))]
4281
  "TARGET_MIPS16 && TARGET_USE_GOT && reload_completed"
4282
  [(set (match_dup 0) (match_dup 1))]
4283
  { operands[1] = pic_offset_table_rtx; })
4284
 
4285
;; Allow combine to split complex const_int load sequences, using operand 2
4286
;; to store the intermediate results.  See move_operand for details.
4287
(define_split
4288
  [(set (match_operand:GPR 0 "register_operand")
4289
        (match_operand:GPR 1 "splittable_const_int_operand"))
4290
   (clobber (match_operand:GPR 2 "register_operand"))]
4291
  ""
4292
  [(const_int 0)]
4293
{
4294
  mips_move_integer (operands[2], operands[0], INTVAL (operands[1]));
4295
  DONE;
4296
})
4297
 
4298
;; Likewise, for symbolic operands.
4299
(define_split
4300
  [(set (match_operand:P 0 "register_operand")
4301
        (match_operand:P 1))
4302
   (clobber (match_operand:P 2 "register_operand"))]
4303
  "mips_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
4304
  [(set (match_dup 0) (match_dup 3))]
4305
{
4306
  mips_split_symbol (operands[2], operands[1],
4307
                     MAX_MACHINE_MODE, &operands[3]);
4308
})
4309
 
4310
;; 64-bit integer moves
4311
 
4312
;; Unlike most other insns, the move insns can't be split with
4313
;; different predicates, because register spilling and other parts of
4314
;; the compiler, have memoized the insn number already.
4315
 
4316
(define_expand "movdi"
4317
  [(set (match_operand:DI 0 "")
4318
        (match_operand:DI 1 ""))]
4319
  ""
4320
{
4321
  if (mips_legitimize_move (DImode, operands[0], operands[1]))
4322
    DONE;
4323
})
4324
 
4325
;; For mips16, we need a special case to handle storing $31 into
4326
;; memory, since we don't have a constraint to match $31.  This
4327
;; instruction can be generated by save_restore_insns.
4328
 
4329
(define_insn "*mov_ra"
4330
  [(set (match_operand:GPR 0 "stack_operand" "=m")
4331
        (reg:GPR RETURN_ADDR_REGNUM))]
4332
  "TARGET_MIPS16"
4333
  "\t$31,%0"
4334
  [(set_attr "move_type" "store")
4335
   (set_attr "mode" "")])
4336
 
4337
(define_insn "*movdi_32bit"
4338
  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*a,*d,*f,*f,*d,*m,*B*C*D,*B*C*D,*d,*m")
4339
        (match_operand:DI 1 "move_operand" "d,i,m,d,*J,*d,*a,*J*d,*m,*f,*f,*d,*m,*B*C*D,*B*C*D"))]
4340
  "!TARGET_64BIT && !TARGET_MIPS16
4341
   && (register_operand (operands[0], DImode)
4342
       || reg_or_0_operand (operands[1], DImode))"
4343
  { return mips_output_move (operands[0], operands[1]); }
4344
  [(set_attr "move_type" "move,const,load,store,imul,mtlo,mflo,mtc,fpload,mfc,fpstore,mtc,fpload,mfc,fpstore")
4345
   (set (attr "mode")
4346
        (if_then_else (eq_attr "move_type" "imul")
4347
                      (const_string "SI")
4348
                      (const_string "DI")))])
4349
 
4350
(define_insn "*movdi_32bit_mips16"
4351
  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4352
        (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4353
  "!TARGET_64BIT && TARGET_MIPS16
4354
   && (register_operand (operands[0], DImode)
4355
       || register_operand (operands[1], DImode))"
4356
  { return mips_output_move (operands[0], operands[1]); }
4357
  [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4358
   (set_attr "mode" "DI")])
4359
 
4360
(define_insn "*movdi_64bit"
4361
  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*d,*m,*a,*d,*B*C*D,*B*C*D,*d,*m")
4362
        (match_operand:DI 1 "move_operand" "d,Yd,Yf,m,dJ,*d*J,*m,*f,*f,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
4363
  "TARGET_64BIT && !TARGET_MIPS16
4364
   && (register_operand (operands[0], DImode)
4365
       || reg_or_0_operand (operands[1], DImode))"
4366
  { return mips_output_move (operands[0], operands[1]); }
4367
  [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mtlo,mflo,mtc,fpload,mfc,fpstore")
4368
   (set_attr "mode" "DI")])
4369
 
4370
(define_insn "*movdi_64bit_mips16"
4371
  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m,*d")
4372
        (match_operand:DI 1 "move_operand" "d,d,y,K,N,Yd,kf,m,d,*a"))]
4373
  "TARGET_64BIT && TARGET_MIPS16
4374
   && (register_operand (operands[0], DImode)
4375
       || register_operand (operands[1], DImode))"
4376
  { return mips_output_move (operands[0], operands[1]); }
4377
  [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mflo")
4378
   (set_attr "mode" "DI")])
4379
 
4380
;; On the mips16, we can split ld $r,N($r) into an add and a load,
4381
;; when the original load is a 4 byte instruction but the add and the
4382
;; load are 2 2 byte instructions.
4383
 
4384
(define_split
4385
  [(set (match_operand:DI 0 "d_operand")
4386
        (mem:DI (plus:DI (match_dup 0)
4387
                         (match_operand:DI 1 "const_int_operand"))))]
4388
  "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4389
   && !TARGET_DEBUG_D_MODE
4390
   && ((INTVAL (operands[1]) < 0
4391
        && INTVAL (operands[1]) >= -0x10)
4392
       || (INTVAL (operands[1]) >= 32 * 8
4393
           && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4394
       || (INTVAL (operands[1]) >= 0
4395
           && INTVAL (operands[1]) < 32 * 8
4396
           && (INTVAL (operands[1]) & 7) != 0))"
4397
  [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4398
   (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4399
{
4400
  HOST_WIDE_INT val = INTVAL (operands[1]);
4401
 
4402
  if (val < 0)
4403
    operands[2] = const0_rtx;
4404
  else if (val >= 32 * 8)
4405
    {
4406
      int off = val & 7;
4407
 
4408
      operands[1] = GEN_INT (0x8 + off);
4409
      operands[2] = GEN_INT (val - off - 0x8);
4410
    }
4411
  else
4412
    {
4413
      int off = val & 7;
4414
 
4415
      operands[1] = GEN_INT (off);
4416
      operands[2] = GEN_INT (val - off);
4417
    }
4418
})
4419
 
4420
;; 32-bit Integer moves
4421
 
4422
;; Unlike most other insns, the move insns can't be split with
4423
;; different predicates, because register spilling and other parts of
4424
;; the compiler, have memoized the insn number already.
4425
 
4426
(define_expand "mov"
4427
  [(set (match_operand:IMOVE32 0 "")
4428
        (match_operand:IMOVE32 1 ""))]
4429
  ""
4430
{
4431
  if (mips_legitimize_move (mode, operands[0], operands[1]))
4432
    DONE;
4433
})
4434
 
4435
;; The difference between these two is whether or not ints are allowed
4436
;; in FP registers (off by default, use -mdebugh to enable).
4437
 
4438
(define_insn "*mov_internal"
4439
  [(set (match_operand:IMOVE32 0 "nonimmediate_operand" "=d,!u,!u,d,e,!u,!ks,d,ZS,ZT,m,*f,*f,*d,*m,*d,*z,*a,*d,*B*C*D,*B*C*D,*d,*m")
4440
        (match_operand:IMOVE32 1 "move_operand" "d,J,Udb7,Yd,Yf,ZT,ZS,m,!ks,!u,dJ,*d*J,*m,*f,*f,*z,*d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
4441
  "!TARGET_MIPS16
4442
   && (register_operand (operands[0], mode)
4443
       || reg_or_0_operand (operands[1], mode))"
4444
  { return mips_output_move (operands[0], operands[1]); }
4445
  [(set_attr "move_type" "move,move,const,const,const,load,load,load,store,store,store,mtc,fpload,mfc,fpstore,mfc,mtc,mtlo,mflo,mtc,fpload,mfc,fpstore")
4446
   (set_attr "compression" "all,micromips,micromips,*,*,micromips,micromips,*,micromips,micromips,*,*,*,*,*,*,*,*,*,*,*,*,*")
4447
   (set_attr "mode" "SI")])
4448
 
4449
(define_insn "*mov_mips16"
4450
  [(set (match_operand:IMOVE32 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m,*d")
4451
        (match_operand:IMOVE32 1 "move_operand" "d,d,y,K,N,Yd,kf,m,d,*a"))]
4452
  "TARGET_MIPS16
4453
   && (register_operand (operands[0], mode)
4454
       || register_operand (operands[1], mode))"
4455
  { return mips_output_move (operands[0], operands[1]); }
4456
  [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mflo")
4457
   (set_attr "mode" "SI")])
4458
 
4459
;; On the mips16, we can split lw $r,N($r) into an add and a load,
4460
;; when the original load is a 4 byte instruction but the add and the
4461
;; load are 2 2 byte instructions.
4462
 
4463
(define_split
4464
  [(set (match_operand:SI 0 "d_operand")
4465
        (mem:SI (plus:SI (match_dup 0)
4466
                         (match_operand:SI 1 "const_int_operand"))))]
4467
  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4468
   && ((INTVAL (operands[1]) < 0
4469
        && INTVAL (operands[1]) >= -0x80)
4470
       || (INTVAL (operands[1]) >= 32 * 4
4471
           && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4472
       || (INTVAL (operands[1]) >= 0
4473
           && INTVAL (operands[1]) < 32 * 4
4474
           && (INTVAL (operands[1]) & 3) != 0))"
4475
  [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4476
   (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4477
{
4478
  HOST_WIDE_INT val = INTVAL (operands[1]);
4479
 
4480
  if (val < 0)
4481
    operands[2] = const0_rtx;
4482
  else if (val >= 32 * 4)
4483
    {
4484
      int off = val & 3;
4485
 
4486
      operands[1] = GEN_INT (0x7c + off);
4487
      operands[2] = GEN_INT (val - off - 0x7c);
4488
    }
4489
  else
4490
    {
4491
      int off = val & 3;
4492
 
4493
      operands[1] = GEN_INT (off);
4494
      operands[2] = GEN_INT (val - off);
4495
    }
4496
})
4497
 
4498
;; On the mips16, we can split a load of certain constants into a load
4499
;; and an add.  This turns a 4 byte instruction into 2 2 byte
4500
;; instructions.
4501
 
4502
(define_split
4503
  [(set (match_operand:SI 0 "d_operand")
4504
        (match_operand:SI 1 "const_int_operand"))]
4505
  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4506
   && INTVAL (operands[1]) >= 0x100
4507
   && INTVAL (operands[1]) <= 0xff + 0x7f"
4508
  [(set (match_dup 0) (match_dup 1))
4509
   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4510
{
4511
  int val = INTVAL (operands[1]);
4512
 
4513
  operands[1] = GEN_INT (0xff);
4514
  operands[2] = GEN_INT (val - 0xff);
4515
})
4516
 
4517
;; MIPS4 supports loading and storing a floating point register from
4518
;; the sum of two general registers.  We use two versions for each of
4519
;; these four instructions: one where the two general registers are
4520
;; SImode, and one where they are DImode.  This is because general
4521
;; registers will be in SImode when they hold 32-bit values, but,
4522
;; since the 32-bit values are always sign extended, the [ls][wd]xc1
4523
;; instructions will still work correctly.
4524
 
4525
;; ??? Perhaps it would be better to support these instructions by
4526
;; modifying TARGET_LEGITIMATE_ADDRESS_P and friends.  However, since
4527
;; these instructions can only be used to load and store floating
4528
;; point registers, that would probably cause trouble in reload.
4529
 
4530
(define_insn "*_"
4531
  [(set (match_operand:ANYF 0 "register_operand" "=f")
4532
        (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
4533
                          (match_operand:P 2 "register_operand" "d"))))]
4534
  "ISA_HAS_LXC1_SXC1"
4535
  "\t%0,%1(%2)"
4536
  [(set_attr "type" "fpidxload")
4537
   (set_attr "mode" "")])
4538
 
4539
(define_insn "*_"
4540
  [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
4541
                          (match_operand:P 2 "register_operand" "d")))
4542
        (match_operand:ANYF 0 "register_operand" "f"))]
4543
  "ISA_HAS_LXC1_SXC1"
4544
  "\t%0,%1(%2)"
4545
  [(set_attr "type" "fpidxstore")
4546
   (set_attr "mode" "")])
4547
 
4548
;; Scaled indexed address load.
4549
;; Per md.texi, we only need to look for a pattern with multiply in the
4550
;; address expression, not shift.
4551
 
4552
(define_insn "*lwxs"
4553
  [(set (match_operand:IMOVE32 0 "register_operand" "=d")
4554
        (mem:IMOVE32
4555
          (plus:P (mult:P (match_operand:P 1 "register_operand" "d")
4556
                          (const_int 4))
4557
                  (match_operand:P 2 "register_operand" "d"))))]
4558
  "ISA_HAS_LWXS"
4559
  "lwxs\t%0,%1(%2)"
4560
  [(set_attr "type"     "load")
4561
   (set_attr "mode"     "SI")])
4562
 
4563
;; 16-bit Integer moves
4564
 
4565
;; Unlike most other insns, the move insns can't be split with
4566
;; different predicates, because register spilling and other parts of
4567
;; the compiler, have memoized the insn number already.
4568
;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4569
 
4570
(define_expand "movhi"
4571
  [(set (match_operand:HI 0 "")
4572
        (match_operand:HI 1 ""))]
4573
  ""
4574
{
4575
  if (mips_legitimize_move (HImode, operands[0], operands[1]))
4576
    DONE;
4577
})
4578
 
4579
(define_insn "*movhi_internal"
4580
  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,!u,d,!u,d,ZU,m,*a,*d")
4581
        (match_operand:HI 1 "move_operand"         "d,J,I,ZU,m,!u,dJ,*d*J,*a"))]
4582
  "!TARGET_MIPS16
4583
   && (register_operand (operands[0], HImode)
4584
       || reg_or_0_operand (operands[1], HImode))"
4585
  { return mips_output_move (operands[0], operands[1]); }
4586
  [(set_attr "move_type" "move,const,const,load,load,store,store,mtlo,mflo")
4587
   (set_attr "compression" "all,micromips,*,micromips,*,micromips,*,*,*")
4588
   (set_attr "mode" "HI")])
4589
 
4590
(define_insn "*movhi_mips16"
4591
  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4592
        (match_operand:HI 1 "move_operand"         "d,d,y,K,N,m,d,*a"))]
4593
  "TARGET_MIPS16
4594
   && (register_operand (operands[0], HImode)
4595
       || register_operand (operands[1], HImode))"
4596
  { return mips_output_move (operands[0], operands[1]); }
4597
  [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4598
   (set_attr "mode" "HI")])
4599
 
4600
;; On the mips16, we can split lh $r,N($r) into an add and a load,
4601
;; when the original load is a 4 byte instruction but the add and the
4602
;; load are 2 2 byte instructions.
4603
 
4604
(define_split
4605
  [(set (match_operand:HI 0 "d_operand")
4606
        (mem:HI (plus:SI (match_dup 0)
4607
                         (match_operand:SI 1 "const_int_operand"))))]
4608
  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4609
   && ((INTVAL (operands[1]) < 0
4610
        && INTVAL (operands[1]) >= -0x80)
4611
       || (INTVAL (operands[1]) >= 32 * 2
4612
           && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4613
       || (INTVAL (operands[1]) >= 0
4614
           && INTVAL (operands[1]) < 32 * 2
4615
           && (INTVAL (operands[1]) & 1) != 0))"
4616
  [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4617
   (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4618
{
4619
  HOST_WIDE_INT val = INTVAL (operands[1]);
4620
 
4621
  if (val < 0)
4622
    operands[2] = const0_rtx;
4623
  else if (val >= 32 * 2)
4624
    {
4625
      int off = val & 1;
4626
 
4627
      operands[1] = GEN_INT (0x7e + off);
4628
      operands[2] = GEN_INT (val - off - 0x7e);
4629
    }
4630
  else
4631
    {
4632
      int off = val & 1;
4633
 
4634
      operands[1] = GEN_INT (off);
4635
      operands[2] = GEN_INT (val - off);
4636
    }
4637
})
4638
 
4639
;; 8-bit Integer moves
4640
 
4641
;; Unlike most other insns, the move insns can't be split with
4642
;; different predicates, because register spilling and other parts of
4643
;; the compiler, have memoized the insn number already.
4644
;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4645
 
4646
(define_expand "movqi"
4647
  [(set (match_operand:QI 0 "")
4648
        (match_operand:QI 1 ""))]
4649
  ""
4650
{
4651
  if (mips_legitimize_move (QImode, operands[0], operands[1]))
4652
    DONE;
4653
})
4654
 
4655
(define_insn "*movqi_internal"
4656
  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,!u,d,!u,d,ZV,m,*a,*d")
4657
        (match_operand:QI 1 "move_operand"         "d,J,I,ZW,m,!u,dJ,*d*J,*a"))]
4658
  "!TARGET_MIPS16
4659
   && (register_operand (operands[0], QImode)
4660
       || reg_or_0_operand (operands[1], QImode))"
4661
  { return mips_output_move (operands[0], operands[1]); }
4662
  [(set_attr "move_type" "move,const,const,load,load,store,store,mtlo,mflo")
4663
   (set_attr "compression" "all,micromips,*,micromips,*,micromips,*,*,*")
4664
   (set_attr "mode" "QI")])
4665
 
4666
(define_insn "*movqi_mips16"
4667
  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4668
        (match_operand:QI 1 "move_operand"         "d,d,y,K,N,m,d,*a"))]
4669
  "TARGET_MIPS16
4670
   && (register_operand (operands[0], QImode)
4671
       || register_operand (operands[1], QImode))"
4672
  { return mips_output_move (operands[0], operands[1]); }
4673
  [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4674
   (set_attr "mode" "QI")])
4675
 
4676
;; On the mips16, we can split lb $r,N($r) into an add and a load,
4677
;; when the original load is a 4 byte instruction but the add and the
4678
;; load are 2 2 byte instructions.
4679
 
4680
(define_split
4681
  [(set (match_operand:QI 0 "d_operand")
4682
        (mem:QI (plus:SI (match_dup 0)
4683
                         (match_operand:SI 1 "const_int_operand"))))]
4684
  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4685
   && ((INTVAL (operands[1]) < 0
4686
        && INTVAL (operands[1]) >= -0x80)
4687
       || (INTVAL (operands[1]) >= 32
4688
           && INTVAL (operands[1]) <= 31 + 0x7f))"
4689
  [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4690
   (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4691
{
4692
  HOST_WIDE_INT val = INTVAL (operands[1]);
4693
 
4694
  if (val < 0)
4695
    operands[2] = const0_rtx;
4696
  else
4697
    {
4698
      operands[1] = GEN_INT (0x7f);
4699
      operands[2] = GEN_INT (val - 0x7f);
4700
    }
4701
})
4702
 
4703
;; 32-bit floating point moves
4704
 
4705
(define_expand "movsf"
4706
  [(set (match_operand:SF 0 "")
4707
        (match_operand:SF 1 ""))]
4708
  ""
4709
{
4710
  if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4711
    DONE;
4712
})
4713
 
4714
(define_insn "*movsf_hardfloat"
4715
  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4716
        (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))]
4717
  "TARGET_HARD_FLOAT
4718
   && (register_operand (operands[0], SFmode)
4719
       || reg_or_0_operand (operands[1], SFmode))"
4720
  { return mips_output_move (operands[0], operands[1]); }
4721
  [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4722
   (set_attr "mode" "SF")])
4723
 
4724
(define_insn "*movsf_softfloat"
4725
  [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4726
        (match_operand:SF 1 "move_operand" "Gd,m,d"))]
4727
  "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4728
   && (register_operand (operands[0], SFmode)
4729
       || reg_or_0_operand (operands[1], SFmode))"
4730
  { return mips_output_move (operands[0], operands[1]); }
4731
  [(set_attr "move_type" "move,load,store")
4732
   (set_attr "mode" "SF")])
4733
 
4734
(define_insn "*movsf_mips16"
4735
  [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4736
        (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
4737
  "TARGET_MIPS16
4738
   && (register_operand (operands[0], SFmode)
4739
       || register_operand (operands[1], SFmode))"
4740
  { return mips_output_move (operands[0], operands[1]); }
4741
  [(set_attr "move_type" "move,move,move,load,store")
4742
   (set_attr "mode" "SF")])
4743
 
4744
;; 64-bit floating point moves
4745
 
4746
(define_expand "movdf"
4747
  [(set (match_operand:DF 0 "")
4748
        (match_operand:DF 1 ""))]
4749
  ""
4750
{
4751
  if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4752
    DONE;
4753
})
4754
 
4755
(define_insn "*movdf_hardfloat"
4756
  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4757
        (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
4758
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
4759
   && (register_operand (operands[0], DFmode)
4760
       || reg_or_0_operand (operands[1], DFmode))"
4761
  { return mips_output_move (operands[0], operands[1]); }
4762
  [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4763
   (set_attr "mode" "DF")])
4764
 
4765
(define_insn "*movdf_softfloat"
4766
  [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m")
4767
        (match_operand:DF 1 "move_operand" "dG,m,dG"))]
4768
  "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4769
   && (register_operand (operands[0], DFmode)
4770
       || reg_or_0_operand (operands[1], DFmode))"
4771
  { return mips_output_move (operands[0], operands[1]); }
4772
  [(set_attr "move_type" "move,load,store")
4773
   (set_attr "mode" "DF")])
4774
 
4775
(define_insn "*movdf_mips16"
4776
  [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4777
        (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4778
  "TARGET_MIPS16
4779
   && (register_operand (operands[0], DFmode)
4780
       || register_operand (operands[1], DFmode))"
4781
  { return mips_output_move (operands[0], operands[1]); }
4782
  [(set_attr "move_type" "move,move,move,load,store")
4783
   (set_attr "mode" "DF")])
4784
 
4785
;; 128-bit integer moves
4786
 
4787
(define_expand "movti"
4788
  [(set (match_operand:TI 0)
4789
        (match_operand:TI 1))]
4790
  "TARGET_64BIT"
4791
{
4792
  if (mips_legitimize_move (TImode, operands[0], operands[1]))
4793
    DONE;
4794
})
4795
 
4796
(define_insn "*movti"
4797
  [(set (match_operand:TI 0 "nonimmediate_operand" "=d,d,d,m,*a,*a,*d")
4798
        (match_operand:TI 1 "move_operand" "d,i,m,dJ,*J,*d,*a"))]
4799
  "TARGET_64BIT
4800
   && !TARGET_MIPS16
4801
   && (register_operand (operands[0], TImode)
4802
       || reg_or_0_operand (operands[1], TImode))"
4803
  { return mips_output_move (operands[0], operands[1]); }
4804
  [(set_attr "move_type" "move,const,load,store,imul,mtlo,mflo")
4805
   (set (attr "mode")
4806
        (if_then_else (eq_attr "move_type" "imul")
4807
                      (const_string "SI")
4808
                      (const_string "TI")))])
4809
 
4810
(define_insn "*movti_mips16"
4811
  [(set (match_operand:TI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4812
        (match_operand:TI 1 "move_operand" "d,d,y,K,N,m,d,*a"))]
4813
  "TARGET_64BIT
4814
   && TARGET_MIPS16
4815
   && (register_operand (operands[0], TImode)
4816
       || register_operand (operands[1], TImode))"
4817
  "#"
4818
  [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4819
   (set_attr "mode" "TI")])
4820
 
4821
;; 128-bit floating point moves
4822
 
4823
(define_expand "movtf"
4824
  [(set (match_operand:TF 0)
4825
        (match_operand:TF 1))]
4826
  "TARGET_64BIT"
4827
{
4828
  if (mips_legitimize_move (TFmode, operands[0], operands[1]))
4829
    DONE;
4830
})
4831
 
4832
;; This pattern handles both hard- and soft-float cases.
4833
(define_insn "*movtf"
4834
  [(set (match_operand:TF 0 "nonimmediate_operand" "=d,d,m,f,d,f,m")
4835
        (match_operand:TF 1 "move_operand" "dG,m,dG,dG,f,m,f"))]
4836
  "TARGET_64BIT
4837
   && !TARGET_MIPS16
4838
   && (register_operand (operands[0], TFmode)
4839
       || reg_or_0_operand (operands[1], TFmode))"
4840
  "#"
4841
  [(set_attr "move_type" "move,load,store,mtc,mfc,fpload,fpstore")
4842
   (set_attr "mode" "TF")])
4843
 
4844
(define_insn "*movtf_mips16"
4845
  [(set (match_operand:TF 0 "nonimmediate_operand" "=d,y,d,d,m")
4846
        (match_operand:TF 1 "move_operand" "d,d,y,m,d"))]
4847
  "TARGET_64BIT
4848
   && TARGET_MIPS16
4849
   && (register_operand (operands[0], TFmode)
4850
       || register_operand (operands[1], TFmode))"
4851
  "#"
4852
  [(set_attr "move_type" "move,move,move,load,store")
4853
   (set_attr "mode" "TF")])
4854
 
4855
(define_split
4856
  [(set (match_operand:MOVE64 0 "nonimmediate_operand")
4857
        (match_operand:MOVE64 1 "move_operand"))]
4858
  "reload_completed && mips_split_move_insn_p (operands[0], operands[1], insn)"
4859
  [(const_int 0)]
4860
{
4861
  mips_split_move_insn (operands[0], operands[1], curr_insn);
4862
  DONE;
4863
})
4864
 
4865
(define_split
4866
  [(set (match_operand:MOVE128 0 "nonimmediate_operand")
4867
        (match_operand:MOVE128 1 "move_operand"))]
4868
  "reload_completed && mips_split_move_insn_p (operands[0], operands[1], insn)"
4869
  [(const_int 0)]
4870
{
4871
  mips_split_move_insn (operands[0], operands[1], curr_insn);
4872
  DONE;
4873
})
4874
 
4875
;; When generating mips16 code, split moves of negative constants into
4876
;; a positive "li" followed by a negation.
4877
(define_split
4878
  [(set (match_operand 0 "d_operand")
4879
        (match_operand 1 "const_int_operand"))]
4880
  "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4881
  [(set (match_dup 2)
4882
        (match_dup 3))
4883
   (set (match_dup 2)
4884
        (neg:SI (match_dup 2)))]
4885
{
4886
  operands[2] = gen_lowpart (SImode, operands[0]);
4887
  operands[3] = GEN_INT (-INTVAL (operands[1]));
4888
})
4889
 
4890
;; 64-bit paired-single floating point moves
4891
 
4892
(define_expand "movv2sf"
4893
  [(set (match_operand:V2SF 0)
4894
        (match_operand:V2SF 1))]
4895
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
4896
{
4897
  if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
4898
    DONE;
4899
})
4900
 
4901
(define_insn "*movv2sf"
4902
  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4903
        (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
4904
  "TARGET_HARD_FLOAT
4905
   && TARGET_PAIRED_SINGLE_FLOAT
4906
   && (register_operand (operands[0], V2SFmode)
4907
       || reg_or_0_operand (operands[1], V2SFmode))"
4908
  { return mips_output_move (operands[0], operands[1]); }
4909
  [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4910
   (set_attr "mode" "DF")])
4911
 
4912
;; Extract the high part of a HI/LO value.  See mips_hard_regno_mode_ok_p
4913
;; for the reason why we can't just use (reg:GPR HI_REGNUM).
4914
;;
4915
;; When generating VR4120 or VR4130 code, we use MACCHI and DMACCHI
4916
;; instead of MFHI.  This avoids both the normal MIPS III hi/lo hazards
4917
;; and the errata related to -mfix-vr4130.
4918
(define_insn "mfhi_"
4919
  [(set (match_operand:GPR 0 "register_operand" "=d")
4920
        (unspec:GPR [(match_operand:HILO 1 "hilo_operand" "x")]
4921
                    UNSPEC_MFHI))]
4922
  ""
4923
  { return ISA_HAS_MACCHI ? "macchi\t%0,%.,%." : "mfhi\t%0"; }
4924
  [(set_attr "type" "mfhi")
4925
   (set_attr "mode" "")])
4926
 
4927
;; Set the high part of a HI/LO value, given that the low part has
4928
;; already been set.  See mips_hard_regno_mode_ok_p for the reason
4929
;; why we can't just use (reg:GPR HI_REGNUM).
4930
(define_insn "mthi_"
4931
  [(set (match_operand:HILO 0 "register_operand" "=x")
4932
        (unspec:HILO [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
4933
                      (match_operand:GPR 2 "register_operand" "l")]
4934
                     UNSPEC_MTHI))]
4935
  ""
4936
  "mthi\t%z1"
4937
  [(set_attr "type" "mthi")
4938
   (set_attr "mode" "SI")])
4939
 
4940
;; Emit a doubleword move in which exactly one of the operands is
4941
;; a floating-point register.  We can't just emit two normal moves
4942
;; because of the constraints imposed by the FPU register model;
4943
;; see mips_cannot_change_mode_class for details.  Instead, we keep
4944
;; the FPR whole and use special patterns to refer to each word of
4945
;; the other operand.
4946
 
4947
(define_expand "move_doubleword_fpr"
4948
  [(set (match_operand:SPLITF 0)
4949
        (match_operand:SPLITF 1))]
4950
  ""
4951
{
4952
  if (FP_REG_RTX_P (operands[0]))
4953
    {
4954
      rtx low = mips_subword (operands[1], 0);
4955
      rtx high = mips_subword (operands[1], 1);
4956
      emit_insn (gen_load_low (operands[0], low));
4957
      if (TARGET_FLOAT64 && !TARGET_64BIT)
4958
        emit_insn (gen_mthc1 (operands[0], high, operands[0]));
4959
      else
4960
        emit_insn (gen_load_high (operands[0], high, operands[0]));
4961
    }
4962
  else
4963
    {
4964
      rtx low = mips_subword (operands[0], 0);
4965
      rtx high = mips_subword (operands[0], 1);
4966
      emit_insn (gen_store_word (low, operands[1], const0_rtx));
4967
      if (TARGET_FLOAT64 && !TARGET_64BIT)
4968
        emit_insn (gen_mfhc1 (high, operands[1]));
4969
      else
4970
        emit_insn (gen_store_word (high, operands[1], const1_rtx));
4971
    }
4972
  DONE;
4973
})
4974
 
4975
;; Load the low word of operand 0 with operand 1.
4976
(define_insn "load_low"
4977
  [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
4978
        (unspec:SPLITF [(match_operand: 1 "general_operand" "dJ,m")]
4979
                       UNSPEC_LOAD_LOW))]
4980
  "TARGET_HARD_FLOAT"
4981
{
4982
  operands[0] = mips_subword (operands[0], 0);
4983
  return mips_output_move (operands[0], operands[1]);
4984
}
4985
  [(set_attr "move_type" "mtc,fpload")
4986
   (set_attr "mode" "")])
4987
 
4988
;; Load the high word of operand 0 from operand 1, preserving the value
4989
;; in the low word.
4990
(define_insn "load_high"
4991
  [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
4992
        (unspec:SPLITF [(match_operand: 1 "general_operand" "dJ,m")
4993
                        (match_operand:SPLITF 2 "register_operand" "0,0")]
4994
                       UNSPEC_LOAD_HIGH))]
4995
  "TARGET_HARD_FLOAT"
4996
{
4997
  operands[0] = mips_subword (operands[0], 1);
4998
  return mips_output_move (operands[0], operands[1]);
4999
}
5000
  [(set_attr "move_type" "mtc,fpload")
5001
   (set_attr "mode" "")])
5002
 
5003
;; Store one word of operand 1 in operand 0.  Operand 2 is 1 to store the
5004
;; high word and 0 to store the low word.
5005
(define_insn "store_word"
5006
  [(set (match_operand: 0 "nonimmediate_operand" "=d,m")
5007
        (unspec: [(match_operand:SPLITF 1 "register_operand" "f,f")
5008
                            (match_operand 2 "const_int_operand")]
5009
                           UNSPEC_STORE_WORD))]
5010
  "TARGET_HARD_FLOAT"
5011
{
5012
  operands[1] = mips_subword (operands[1], INTVAL (operands[2]));
5013
  return mips_output_move (operands[0], operands[1]);
5014
}
5015
  [(set_attr "move_type" "mfc,fpstore")
5016
   (set_attr "mode" "")])
5017
 
5018
;; Move operand 1 to the high word of operand 0 using mthc1, preserving the
5019
;; value in the low word.
5020
(define_insn "mthc1"
5021
  [(set (match_operand:SPLITF 0 "register_operand" "=f")
5022
        (unspec:SPLITF [(match_operand: 1 "reg_or_0_operand" "dJ")
5023
                        (match_operand:SPLITF 2 "register_operand" "0")]
5024
                       UNSPEC_MTHC1))]
5025
  "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
5026
  "mthc1\t%z1,%0"
5027
  [(set_attr "move_type" "mtc")
5028
   (set_attr "mode" "")])
5029
 
5030
;; Move high word of operand 1 to operand 0 using mfhc1.
5031
(define_insn "mfhc1"
5032
  [(set (match_operand: 0 "register_operand" "=d")
5033
        (unspec: [(match_operand:SPLITF 1 "register_operand" "f")]
5034
                            UNSPEC_MFHC1))]
5035
  "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
5036
  "mfhc1\t%0,%1"
5037
  [(set_attr "move_type" "mfc")
5038
   (set_attr "mode" "")])
5039
 
5040
;; Move a constant that satisfies CONST_GP_P into operand 0.
5041
(define_expand "load_const_gp_"
5042
  [(set (match_operand:P 0 "register_operand" "=d")
5043
        (const:P (unspec:P [(const_int 0)] UNSPEC_GP)))])
5044
 
5045
;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
5046
;; of _gp from the start of this function.  Operand 1 is the incoming
5047
;; function address.
5048
(define_insn_and_split "loadgp_newabi_"
5049
  [(set (match_operand:P 0 "register_operand" "=&d")
5050
        (unspec:P [(match_operand:P 1)
5051
                   (match_operand:P 2 "register_operand" "d")]
5052
                  UNSPEC_LOADGP))]
5053
  "mips_current_loadgp_style () == LOADGP_NEWABI"
5054
  { return mips_must_initialize_gp_p () ? "#" : ""; }
5055
  "&& mips_must_initialize_gp_p ()"
5056
  [(set (match_dup 0) (match_dup 3))
5057
   (set (match_dup 0) (match_dup 4))
5058
   (set (match_dup 0) (match_dup 5))]
5059
{
5060
  operands[3] = gen_rtx_HIGH (Pmode, operands[1]);
5061
  operands[4] = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
5062
  operands[5] = gen_rtx_LO_SUM (Pmode, operands[0], operands[1]);
5063
}
5064
  [(set_attr "type" "ghost")])
5065
 
5066
;; Likewise, for -mno-shared code.  Operand 0 is the __gnu_local_gp symbol.
5067
(define_insn_and_split "loadgp_absolute_"
5068
  [(set (match_operand:P 0 "register_operand" "=d")
5069
        (unspec:P [(match_operand:P 1)] UNSPEC_LOADGP))]
5070
  "mips_current_loadgp_style () == LOADGP_ABSOLUTE"
5071
  { return mips_must_initialize_gp_p () ? "#" : ""; }
5072
  "&& mips_must_initialize_gp_p ()"
5073
  [(const_int 0)]
5074
{
5075
  mips_emit_move (operands[0], operands[1]);
5076
  DONE;
5077
}
5078
  [(set_attr "type" "ghost")])
5079
 
5080
;; This blockage instruction prevents the gp load from being
5081
;; scheduled after an implicit use of gp.  It also prevents
5082
;; the load from being deleted as dead.
5083
(define_insn "loadgp_blockage"
5084
  [(unspec_volatile [(reg:SI 28)] UNSPEC_BLOCKAGE)]
5085
  ""
5086
  ""
5087
  [(set_attr "type" "ghost")])
5088
 
5089
;; Initialize $gp for RTP PIC.  Operand 0 is the __GOTT_BASE__ symbol
5090
;; and operand 1 is the __GOTT_INDEX__ symbol.
5091
(define_insn_and_split "loadgp_rtp_"
5092
  [(set (match_operand:P 0 "register_operand" "=d")
5093
        (unspec:P [(match_operand:P 1 "symbol_ref_operand")
5094
                   (match_operand:P 2 "symbol_ref_operand")]
5095
                  UNSPEC_LOADGP))]
5096
  "mips_current_loadgp_style () == LOADGP_RTP"
5097
  { return mips_must_initialize_gp_p () ? "#" : ""; }
5098
  "&& mips_must_initialize_gp_p ()"
5099
  [(set (match_dup 0) (high:P (match_dup 3)))
5100
   (set (match_dup 0) (unspec:P [(match_dup 0)
5101
                                 (match_dup 3)] UNSPEC_LOAD_GOT))
5102
   (set (match_dup 0) (unspec:P [(match_dup 0)
5103
                                 (match_dup 4)] UNSPEC_LOAD_GOT))]
5104
{
5105
  operands[3] = mips_unspec_address (operands[1], SYMBOL_ABSOLUTE);
5106
  operands[4] = mips_unspec_address (operands[2], SYMBOL_HALF);
5107
}
5108
  [(set_attr "type" "ghost")])
5109
 
5110
;; Initialize the global pointer for MIPS16 code.  Operand 0 is the
5111
;; global pointer and operand 1 is the MIPS16 register that holds
5112
;; the required value.
5113
(define_insn_and_split "copygp_mips16_"
5114
  [(set (match_operand:P 0 "register_operand" "=y")
5115
        (unspec:P [(match_operand:P 1 "register_operand" "d")]
5116
                  UNSPEC_COPYGP))]
5117
  "TARGET_MIPS16"
5118
  { return mips_must_initialize_gp_p () ? "#" : ""; }
5119
  "&& mips_must_initialize_gp_p ()"
5120
  [(set (match_dup 0) (match_dup 1))]
5121
  ""
5122
  [(set_attr "type" "ghost")])
5123
 
5124
;; A placeholder for where the cprestore instruction should go,
5125
;; if we decide we need one.  Operand 0 and operand 1 are as for
5126
;; "cprestore".  Operand 2 is a register that holds the gp value.
5127
;;
5128
;; The "cprestore" pattern requires operand 2 to be pic_offset_table_rtx,
5129
;; otherwise any register that holds the correct value will do.
5130
(define_insn_and_split "potential_cprestore_"
5131
  [(set (match_operand:P 0 "cprestore_save_slot_operand" "=X,X")
5132
        (unspec:P [(match_operand:P 1 "const_int_operand" "I,i")
5133
                   (match_operand:P 2 "register_operand" "d,d")]
5134
                  UNSPEC_POTENTIAL_CPRESTORE))
5135
   (clobber (match_operand:P 3 "scratch_operand" "=X,&d"))]
5136
  "!TARGET_CPRESTORE_DIRECTIVE || operands[2] == pic_offset_table_rtx"
5137
  { return mips_must_initialize_gp_p () ? "#" : ""; }
5138
  "mips_must_initialize_gp_p ()"
5139
  [(const_int 0)]
5140
{
5141
  mips_save_gp_to_cprestore_slot (operands[0], operands[1],
5142
                                  operands[2], operands[3]);
5143
  DONE;
5144
}
5145
  [(set_attr "type" "ghost")])
5146
 
5147
;; Emit a .cprestore directive, which normally expands to a single store
5148
;; instruction.  Operand 0 is a (possibly illegitimate) sp-based MEM
5149
;; for the cprestore slot.  Operand 1 is the offset of the slot from
5150
;; the stack pointer.  (This is redundant with operand 0, but it makes
5151
;; things a little simpler.)
5152
(define_insn "cprestore_"
5153
  [(set (match_operand:P 0 "cprestore_save_slot_operand" "=X,X")
5154
        (unspec:P [(match_operand:P 1 "const_int_operand" "I,i")
5155
                   (reg:P 28)]
5156
                  UNSPEC_CPRESTORE))]
5157
  "TARGET_CPRESTORE_DIRECTIVE"
5158
{
5159
  if (mips_nomacro.nesting_level > 0 && which_alternative == 1)
5160
    return ".set\tmacro\;.cprestore\t%1\;.set\tnomacro";
5161
  else
5162
    return ".cprestore\t%1";
5163
}
5164
  [(set_attr "type" "store")
5165
   (set_attr "insn_count" "1,3")])
5166
 
5167
(define_insn "use_cprestore_"
5168
  [(set (reg:P CPRESTORE_SLOT_REGNUM)
5169
        (match_operand:P 0 "cprestore_load_slot_operand"))]
5170
  ""
5171
  ""
5172
  [(set_attr "type" "ghost")])
5173
 
5174
;; Expand in-line code to clear the instruction cache between operand[0] and
5175
;; operand[1].
5176
(define_expand "clear_cache"
5177
  [(match_operand 0 "pmode_register_operand")
5178
   (match_operand 1 "pmode_register_operand")]
5179
  ""
5180
  "
5181
{
5182
  if (TARGET_SYNCI)
5183
    {
5184
      mips_expand_synci_loop (operands[0], operands[1]);
5185
      emit_insn (gen_sync ());
5186
      emit_insn (PMODE_INSN (gen_clear_hazard, ()));
5187
    }
5188
  else if (mips_cache_flush_func && mips_cache_flush_func[0])
5189
    {
5190
      rtx len = gen_reg_rtx (Pmode);
5191
      emit_insn (gen_sub3_insn (len, operands[1], operands[0]));
5192
      MIPS_ICACHE_SYNC (operands[0], len);
5193
    }
5194
  DONE;
5195
}")
5196
 
5197
(define_insn "sync"
5198
  [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
5199
  "GENERATE_SYNC"
5200
  { return mips_output_sync (); })
5201
 
5202
(define_insn "synci"
5203
  [(unspec_volatile [(match_operand 0 "pmode_register_operand" "d")]
5204
                    UNSPEC_SYNCI)]
5205
  "TARGET_SYNCI"
5206
  "synci\t0(%0)")
5207
 
5208
(define_insn "rdhwr_synci_step_"
5209
  [(set (match_operand:P 0 "register_operand" "=d")
5210
        (unspec_volatile [(const_int 1)]
5211
        UNSPEC_RDHWR))]
5212
  "ISA_HAS_SYNCI"
5213
  "rdhwr\t%0,$1")
5214
 
5215
(define_insn "clear_hazard_"
5216
  [(unspec_volatile [(const_int 0)] UNSPEC_CLEAR_HAZARD)
5217
   (clobber (reg:P RETURN_ADDR_REGNUM))]
5218
  "ISA_HAS_SYNCI"
5219
{
5220
  return "%(%
5221
         "\tnop\n"
5222
         "1:\taddiu\t$31,$31,12\n"
5223
         "\tjr.hb\t$31\n"
5224
         "\tnop%>%)";
5225
}
5226
  [(set_attr "insn_count" "5")])
5227
 
5228
;; Cache operations for R4000-style caches.
5229
(define_insn "mips_cache"
5230
  [(set (mem:BLK (scratch))
5231
        (unspec:BLK [(match_operand:SI 0 "const_int_operand")
5232
                     (match_operand:QI 1 "address_operand" "p")]
5233
                    UNSPEC_MIPS_CACHE))]
5234
  "ISA_HAS_CACHE"
5235
  "cache\t%X0,%a1")
5236
 
5237
;; Similar, but with the operands hard-coded to an R10K cache barrier
5238
;; operation.  We keep the pattern distinct so that we can identify
5239
;; cache operations inserted by -mr10k-cache-barrier=, and so that
5240
;; the operation is never inserted into a delay slot.
5241
(define_insn "r10k_cache_barrier"
5242
  [(set (mem:BLK (scratch))
5243
        (unspec:BLK [(const_int 0)] UNSPEC_R10K_CACHE_BARRIER))]
5244
  "ISA_HAS_CACHE"
5245
  "cache\t0x14,0(%$)"
5246
  [(set_attr "can_delay" "no")])
5247
 
5248
;; Block moves, see mips.c for more details.
5249
;; Argument 0 is the destination
5250
;; Argument 1 is the source
5251
;; Argument 2 is the length
5252
;; Argument 3 is the alignment
5253
 
5254
(define_expand "movmemsi"
5255
  [(parallel [(set (match_operand:BLK 0 "general_operand")
5256
                   (match_operand:BLK 1 "general_operand"))
5257
              (use (match_operand:SI 2 ""))
5258
              (use (match_operand:SI 3 "const_int_operand"))])]
5259
  "!TARGET_MIPS16 && !TARGET_MEMCPY"
5260
{
5261
  if (mips_expand_block_move (operands[0], operands[1], operands[2]))
5262
    DONE;
5263
  else
5264
    FAIL;
5265
})
5266
 
5267
;;
5268
;;  ....................
5269
;;
5270
;;      SHIFTS
5271
;;
5272
;;  ....................
5273
 
5274
(define_expand "3"
5275
  [(set (match_operand:GPR 0 "register_operand")
5276
        (any_shift:GPR (match_operand:GPR 1 "register_operand")
5277
                       (match_operand:SI 2 "arith_operand")))]
5278
  ""
5279
{
5280
  /* On the mips16, a shift of more than 8 is a four byte instruction,
5281
     so, for a shift between 8 and 16, it is just as fast to do two
5282
     shifts of 8 or less.  If there is a lot of shifting going on, we
5283
     may win in CSE.  Otherwise combine will put the shifts back
5284
     together again.  This can be called by mips_function_arg, so we must
5285
     be careful not to allocate a new register if we've reached the
5286
     reload pass.  */
5287
  if (TARGET_MIPS16
5288
      && optimize
5289
      && CONST_INT_P (operands[2])
5290
      && INTVAL (operands[2]) > 8
5291
      && INTVAL (operands[2]) <= 16
5292
      && !reload_in_progress
5293
      && !reload_completed)
5294
    {
5295
      rtx temp = gen_reg_rtx (mode);
5296
 
5297
      emit_insn (gen_3 (temp, operands[1], GEN_INT (8)));
5298
      emit_insn (gen_3 (operands[0], temp,
5299
                                     GEN_INT (INTVAL (operands[2]) - 8)));
5300
      DONE;
5301
    }
5302
})
5303
 
5304
(define_insn "*3"
5305
  [(set (match_operand:GPR 0 "register_operand" "=!u,d")
5306
        (any_shift:GPR (match_operand:GPR 1 "register_operand" "!u,d")
5307
                       (match_operand:SI 2 "arith_operand" "Uib3,dI")))]
5308
  "!TARGET_MIPS16"
5309
{
5310
  if (CONST_INT_P (operands[2]))
5311
    operands[2] = GEN_INT (INTVAL (operands[2])
5312
                           & (GET_MODE_BITSIZE (mode) - 1));
5313
 
5314
  return "\t%0,%1,%2";
5315
}
5316
  [(set_attr "type" "shift")
5317
   (set_attr "compression" ",none")
5318
   (set_attr "mode" "")])
5319
 
5320
(define_insn "*si3_extend"
5321
  [(set (match_operand:DI 0 "register_operand" "=d")
5322
        (sign_extend:DI
5323
           (any_shift:SI (match_operand:SI 1 "register_operand" "d")
5324
                         (match_operand:SI 2 "arith_operand" "dI"))))]
5325
  "TARGET_64BIT && !TARGET_MIPS16"
5326
{
5327
  if (CONST_INT_P (operands[2]))
5328
    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5329
 
5330
  return "\t%0,%1,%2";
5331
}
5332
  [(set_attr "type" "shift")
5333
   (set_attr "mode" "SI")])
5334
 
5335
(define_insn "*si3_mips16"
5336
  [(set (match_operand:SI 0 "register_operand" "=d,d,d")
5337
        (any_shift:SI (match_operand:SI 1 "register_operand" "0,d,d")
5338
                      (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5339
  "TARGET_MIPS16"
5340
{
5341
  if (which_alternative == 0)
5342
    return "\t%0,%2";
5343
 
5344
  operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5345
  return "\t%0,%1,%2";
5346
}
5347
  [(set_attr "type" "shift")
5348
   (set_attr "mode" "SI")
5349
   (set_attr "extended_mips16" "no,no,yes")])
5350
 
5351
;; We need separate DImode MIPS16 patterns because of the irregularity
5352
;; of right shifts.
5353
(define_insn "*ashldi3_mips16"
5354
  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
5355
        (ashift:DI (match_operand:DI 1 "register_operand" "0,d,d")
5356
                   (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5357
  "TARGET_64BIT && TARGET_MIPS16"
5358
{
5359
  if (which_alternative == 0)
5360
    return "dsll\t%0,%2";
5361
 
5362
  operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5363
  return "dsll\t%0,%1,%2";
5364
}
5365
  [(set_attr "type" "shift")
5366
   (set_attr "mode" "DI")
5367
   (set_attr "extended_mips16" "no,no,yes")])
5368
 
5369
(define_insn "*ashrdi3_mips16"
5370
  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
5371
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0,0")
5372
                     (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5373
  "TARGET_64BIT && TARGET_MIPS16"
5374
{
5375
  if (CONST_INT_P (operands[2]))
5376
    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5377
 
5378
  return "dsra\t%0,%2";
5379
}
5380
  [(set_attr "type" "shift")
5381
   (set_attr "mode" "DI")
5382
   (set_attr "extended_mips16" "no,no,yes")])
5383
 
5384
(define_insn "*lshrdi3_mips16"
5385
  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
5386
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,0")
5387
                     (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5388
  "TARGET_64BIT && TARGET_MIPS16"
5389
{
5390
  if (CONST_INT_P (operands[2]))
5391
    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5392
 
5393
  return "dsrl\t%0,%2";
5394
}
5395
  [(set_attr "type" "shift")
5396
   (set_attr "mode" "DI")
5397
   (set_attr "extended_mips16" "no,no,yes")])
5398
 
5399
;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5400
 
5401
(define_split
5402
  [(set (match_operand:GPR 0 "d_operand")
5403
        (any_shift:GPR (match_operand:GPR 1 "d_operand")
5404
                       (match_operand:GPR 2 "const_int_operand")))]
5405
  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5406
   && INTVAL (operands[2]) > 8
5407
   && INTVAL (operands[2]) <= 16"
5408
  [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
5409
   (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
5410
  { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5411
 
5412
;; If we load a byte on the mips16 as a bitfield, the resulting
5413
;; sequence of instructions is too complicated for combine, because it
5414
;; involves four instructions: a load, a shift, a constant load into a
5415
;; register, and an and (the key problem here is that the mips16 does
5416
;; not have and immediate).  We recognize a shift of a load in order
5417
;; to make it simple enough for combine to understand.
5418
;;
5419
;; The instruction count here is the worst case.
5420
(define_insn_and_split ""
5421
  [(set (match_operand:SI 0 "register_operand" "=d")
5422
        (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5423
                     (match_operand:SI 2 "immediate_operand" "I")))]
5424
  "TARGET_MIPS16"
5425
  "#"
5426
  ""
5427
  [(set (match_dup 0) (match_dup 1))
5428
   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5429
  ""
5430
  [(set_attr "type"     "load")
5431
   (set_attr "mode"     "SI")
5432
   (set (attr "insn_count")
5433
        (symbol_ref "mips_load_store_insns (operands[1], insn) + 2"))])
5434
 
5435
(define_insn "rotr3"
5436
  [(set (match_operand:GPR 0 "register_operand" "=d")
5437
        (rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
5438
                      (match_operand:SI 2 "arith_operand" "dI")))]
5439
  "ISA_HAS_ROR"
5440
{
5441
  if (CONST_INT_P (operands[2]))
5442
    gcc_assert (INTVAL (operands[2]) >= 0
5443
                && INTVAL (operands[2]) < GET_MODE_BITSIZE (mode));
5444
 
5445
  return "ror\t%0,%1,%2";
5446
}
5447
  [(set_attr "type" "shift")
5448
   (set_attr "mode" "")])
5449
 
5450
(define_insn "bswaphi2"
5451
  [(set (match_operand:HI 0 "register_operand" "=d")
5452
        (bswap:HI (match_operand:HI 1 "register_operand" "d")))]
5453
  "ISA_HAS_WSBH"
5454
  "wsbh\t%0,%1"
5455
  [(set_attr "type" "shift")])
5456
 
5457
(define_insn_and_split "bswapsi2"
5458
  [(set (match_operand:SI 0 "register_operand" "=d")
5459
        (bswap:SI (match_operand:SI 1 "register_operand" "d")))]
5460
  "ISA_HAS_WSBH && ISA_HAS_ROR"
5461
  "#"
5462
  ""
5463
  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_WSBH))
5464
   (set (match_dup 0) (rotatert:SI (match_dup 0) (const_int 16)))]
5465
  ""
5466
  [(set_attr "insn_count" "2")])
5467
 
5468
(define_insn_and_split "bswapdi2"
5469
  [(set (match_operand:DI 0 "register_operand" "=d")
5470
        (bswap:DI (match_operand:DI 1 "register_operand" "d")))]
5471
  "TARGET_64BIT && ISA_HAS_WSBH"
5472
  "#"
5473
  ""
5474
  [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_DSBH))
5475
   (set (match_dup 0) (unspec:DI [(match_dup 0)] UNSPEC_DSHD))]
5476
  ""
5477
  [(set_attr "insn_count" "2")])
5478
 
5479
(define_insn "wsbh"
5480
  [(set (match_operand:SI 0 "register_operand" "=d")
5481
        (unspec:SI [(match_operand:SI 1 "register_operand" "d")] UNSPEC_WSBH))]
5482
  "ISA_HAS_WSBH"
5483
  "wsbh\t%0,%1"
5484
  [(set_attr "type" "shift")])
5485
 
5486
(define_insn "dsbh"
5487
  [(set (match_operand:DI 0 "register_operand" "=d")
5488
        (unspec:DI [(match_operand:DI 1 "register_operand" "d")] UNSPEC_DSBH))]
5489
  "TARGET_64BIT && ISA_HAS_WSBH"
5490
  "dsbh\t%0,%1"
5491
  [(set_attr "type" "shift")])
5492
 
5493
(define_insn "dshd"
5494
  [(set (match_operand:DI 0 "register_operand" "=d")
5495
        (unspec:DI [(match_operand:DI 1 "register_operand" "d")] UNSPEC_DSHD))]
5496
  "TARGET_64BIT && ISA_HAS_WSBH"
5497
  "dshd\t%0,%1"
5498
  [(set_attr "type" "shift")])
5499
 
5500
;;
5501
;;  ....................
5502
;;
5503
;;      CONDITIONAL BRANCHES
5504
;;
5505
;;  ....................
5506
 
5507
;; Conditional branches on floating-point equality tests.
5508
 
5509
(define_insn "*branch_fp"
5510
  [(set (pc)
5511
        (if_then_else
5512
         (match_operator 1 "equality_operator"
5513
                         [(match_operand:CC 2 "register_operand" "z")
5514
                          (const_int 0)])
5515
         (label_ref (match_operand 0 "" ""))
5516
         (pc)))]
5517
  "TARGET_HARD_FLOAT"
5518
{
5519
  return mips_output_conditional_branch (insn, operands,
5520
                                         MIPS_BRANCH ("b%F1", "%Z2%0"),
5521
                                         MIPS_BRANCH ("b%W1", "%Z2%0"));
5522
}
5523
  [(set_attr "type" "branch")])
5524
 
5525
(define_insn "*branch_fp_inverted"
5526
  [(set (pc)
5527
        (if_then_else
5528
         (match_operator 1 "equality_operator"
5529
                         [(match_operand:CC 2 "register_operand" "z")
5530
                          (const_int 0)])
5531
         (pc)
5532
         (label_ref (match_operand 0 "" ""))))]
5533
  "TARGET_HARD_FLOAT"
5534
{
5535
  return mips_output_conditional_branch (insn, operands,
5536
                                         MIPS_BRANCH ("b%W1", "%Z2%0"),
5537
                                         MIPS_BRANCH ("b%F1", "%Z2%0"));
5538
}
5539
  [(set_attr "type" "branch")])
5540
 
5541
;; Conditional branches on ordered comparisons with zero.
5542
 
5543
(define_insn "*branch_order"
5544
  [(set (pc)
5545
        (if_then_else
5546
         (match_operator 1 "order_operator"
5547
                         [(match_operand:GPR 2 "register_operand" "d")
5548
                          (const_int 0)])
5549
         (label_ref (match_operand 0 "" ""))
5550
         (pc)))]
5551
  "!TARGET_MIPS16"
5552
  { return mips_output_order_conditional_branch (insn, operands, false); }
5553
  [(set_attr "type" "branch")])
5554
 
5555
(define_insn "*branch_order_inverted"
5556
  [(set (pc)
5557
        (if_then_else
5558
         (match_operator 1 "order_operator"
5559
                         [(match_operand:GPR 2 "register_operand" "d")
5560
                          (const_int 0)])
5561
         (pc)
5562
         (label_ref (match_operand 0 "" ""))))]
5563
  "!TARGET_MIPS16"
5564
  { return mips_output_order_conditional_branch (insn, operands, true); }
5565
  [(set_attr "type" "branch")])
5566
 
5567
;; Conditional branch on equality comparison.
5568
 
5569
(define_insn "*branch_equality"
5570
  [(set (pc)
5571
        (if_then_else
5572
         (match_operator 1 "equality_operator"
5573
                         [(match_operand:GPR 2 "register_operand" "d")
5574
                          (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
5575
         (label_ref (match_operand 0 "" ""))
5576
         (pc)))]
5577
  "!TARGET_MIPS16"
5578
{
5579
  /* For a simple BNEZ or BEQZ microMIPS branch.  */
5580
  if (TARGET_MICROMIPS
5581
      && operands[3] == const0_rtx
5582
      && get_attr_length (insn) <= 8)
5583
    return mips_output_conditional_branch (insn, operands,
5584
                                           "%*b%C1z%:\t%2,%0",
5585
                                           "%*b%N1z%:\t%2,%0");
5586
 
5587
  return mips_output_conditional_branch (insn, operands,
5588
                                         MIPS_BRANCH ("b%C1", "%2,%z3,%0"),
5589
                                         MIPS_BRANCH ("b%N1", "%2,%z3,%0"));
5590
}
5591
  [(set_attr "type" "branch")])
5592
 
5593
(define_insn "*branch_equality_inverted"
5594
  [(set (pc)
5595
        (if_then_else
5596
         (match_operator 1 "equality_operator"
5597
                         [(match_operand:GPR 2 "register_operand" "d")
5598
                          (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
5599
         (pc)
5600
         (label_ref (match_operand 0 "" ""))))]
5601
  "!TARGET_MIPS16"
5602
{
5603
  /* For a simple BNEZ or BEQZ microMIPS branch.  */
5604
  if (TARGET_MICROMIPS
5605
      && operands[3] == const0_rtx
5606
      && get_attr_length (insn) <= 8)
5607
    return mips_output_conditional_branch (insn, operands,
5608
                                           "%*b%N0z%:\t%2,%1",
5609
                                           "%*b%C0z%:\t%2,%1");
5610
 
5611
  return mips_output_conditional_branch (insn, operands,
5612
                                         MIPS_BRANCH ("b%N1", "%2,%z3,%0"),
5613
                                         MIPS_BRANCH ("b%C1", "%2,%z3,%0"));
5614
}
5615
  [(set_attr "type" "branch")])
5616
 
5617
;; MIPS16 branches
5618
 
5619
(define_insn "*branch_equality_mips16"
5620
  [(set (pc)
5621
        (if_then_else
5622
         (match_operator 1 "equality_operator"
5623
                         [(match_operand:GPR 2 "register_operand" "d,t")
5624
                          (const_int 0)])
5625
         (label_ref (match_operand 0 "" ""))
5626
         (pc)))]
5627
  "TARGET_MIPS16"
5628
  "@
5629
   b%C1z\t%2,%0
5630
   bt%C1z\t%0"
5631
  [(set_attr "type" "branch")])
5632
 
5633
(define_insn "*branch_equality_mips16_inverted"
5634
  [(set (pc)
5635
        (if_then_else
5636
         (match_operator 1 "equality_operator"
5637
                         [(match_operand:GPR 2 "register_operand" "d,t")
5638
                          (const_int 0)])
5639
         (pc)
5640
         (label_ref (match_operand 0 "" ""))))]
5641
  "TARGET_MIPS16"
5642
  "@
5643
   b%N1z\t%2,%0
5644
   bt%N1z\t%0"
5645
  [(set_attr "type" "branch")])
5646
 
5647
(define_expand "cbranch4"
5648
  [(set (pc)
5649
        (if_then_else (match_operator 0 "comparison_operator"
5650
                       [(match_operand:GPR 1 "register_operand")
5651
                        (match_operand:GPR 2 "nonmemory_operand")])
5652
                      (label_ref (match_operand 3 ""))
5653
                      (pc)))]
5654
  ""
5655
{
5656
  mips_expand_conditional_branch (operands);
5657
  DONE;
5658
})
5659
 
5660
(define_expand "cbranch4"
5661
  [(set (pc)
5662
        (if_then_else (match_operator 0 "comparison_operator"
5663
                       [(match_operand:SCALARF 1 "register_operand")
5664
                        (match_operand:SCALARF 2 "register_operand")])
5665
                      (label_ref (match_operand 3 ""))
5666
                      (pc)))]
5667
  ""
5668
{
5669
  mips_expand_conditional_branch (operands);
5670
  DONE;
5671
})
5672
 
5673
;; Used to implement built-in functions.
5674
(define_expand "condjump"
5675
  [(set (pc)
5676
        (if_then_else (match_operand 0)
5677
                      (label_ref (match_operand 1))
5678
                      (pc)))])
5679
 
5680
;; Branch if bit is set/clear.
5681
 
5682
(define_insn "*branch_bit"
5683
  [(set (pc)
5684
        (if_then_else
5685
         (equality_op (zero_extract:GPR
5686
                       (match_operand:GPR 1 "register_operand" "d")
5687
                       (const_int 1)
5688
                       (match_operand 2 "const_int_operand" ""))
5689
                      (const_int 0))
5690
         (label_ref (match_operand 0 ""))
5691
         (pc)))]
5692
  "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (mode)"
5693
{
5694
  return
5695
    mips_output_conditional_branch (insn, operands,
5696
                                    MIPS_BRANCH ("bbit", "%1,%2,%0"),
5697
                                    MIPS_BRANCH ("bbit", "%1,%2,%0"));
5698
}
5699
  [(set_attr "type"          "branch")
5700
   (set_attr "branch_likely" "no")])
5701
 
5702
(define_insn "*branch_bit_inverted"
5703
  [(set (pc)
5704
        (if_then_else
5705
         (equality_op (zero_extract:GPR
5706
                       (match_operand:GPR 1 "register_operand" "d")
5707
                       (const_int 1)
5708
                       (match_operand 2 "const_int_operand" ""))
5709
                      (const_int 0))
5710
         (pc)
5711
         (label_ref (match_operand 0 ""))))]
5712
  "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (mode)"
5713
{
5714
  return
5715
    mips_output_conditional_branch (insn, operands,
5716
                                    MIPS_BRANCH ("bbit", "%1,%2,%0"),
5717
                                    MIPS_BRANCH ("bbit", "%1,%2,%0"));
5718
}
5719
  [(set_attr "type"          "branch")
5720
   (set_attr "branch_likely" "no")])
5721
 
5722
;;
5723
;;  ....................
5724
;;
5725
;;      SETTING A REGISTER FROM A COMPARISON
5726
;;
5727
;;  ....................
5728
 
5729
;; Destination is always set in SI mode.
5730
 
5731
(define_expand "cstore4"
5732
  [(set (match_operand:SI 0 "register_operand")
5733
        (match_operator:SI 1 "mips_cstore_operator"
5734
         [(match_operand:GPR 2 "register_operand")
5735
          (match_operand:GPR 3 "nonmemory_operand")]))]
5736
  ""
5737
{
5738
  mips_expand_scc (operands);
5739
  DONE;
5740
})
5741
 
5742
(define_insn "*seq_zero_"
5743
  [(set (match_operand:GPR2 0 "register_operand" "=d")
5744
        (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
5745
                 (const_int 0)))]
5746
  "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5747
  "sltu\t%0,%1,1"
5748
  [(set_attr "type" "slt")
5749
   (set_attr "mode" "")])
5750
 
5751
(define_insn "*seq_zero__mips16"
5752
  [(set (match_operand:GPR2 0 "register_operand" "=t")
5753
        (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
5754
                 (const_int 0)))]
5755
  "TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5756
  "sltu\t%1,1"
5757
  [(set_attr "type" "slt")
5758
   (set_attr "mode" "")])
5759
 
5760
;; Generate sltiu unless using seq results in better code.
5761
(define_insn "*seq__seq"
5762
  [(set (match_operand:GPR2 0 "register_operand" "=d,d,d")
5763
        (eq:GPR2 (match_operand:GPR 1 "register_operand" "%d,d,d")
5764
                 (match_operand:GPR 2 "reg_imm10_operand" "d,J,YB")))]
5765
  "ISA_HAS_SEQ_SNE"
5766
  "@
5767
   seq\t%0,%1,%2
5768
   sltiu\t%0,%1,1
5769
   seqi\t%0,%1,%2"
5770
  [(set_attr "type" "slt")
5771
   (set_attr "mode" "")])
5772
 
5773
(define_insn "*sne_zero_"
5774
  [(set (match_operand:GPR2 0 "register_operand" "=d")
5775
        (ne:GPR2 (match_operand:GPR 1 "register_operand" "d")
5776
                 (const_int 0)))]
5777
  "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5778
  "sltu\t%0,%.,%1"
5779
  [(set_attr "type" "slt")
5780
   (set_attr "mode" "")])
5781
 
5782
;; Generate sltu unless using sne results in better code.
5783
(define_insn "*sne__sne"
5784
  [(set (match_operand:GPR2 0 "register_operand" "=d,d,d")
5785
        (ne:GPR2 (match_operand:GPR 1 "register_operand" "%d,d,d")
5786
                 (match_operand:GPR 2 "reg_imm10_operand" "d,J,YB")))]
5787
  "ISA_HAS_SEQ_SNE"
5788
  "@
5789
   sne\t%0,%1,%2
5790
   sltu\t%0,%.,%1
5791
   snei\t%0,%1,%2"
5792
  [(set_attr "type" "slt")
5793
   (set_attr "mode" "")])
5794
 
5795
(define_insn "*sgt_"
5796
  [(set (match_operand:GPR2 0 "register_operand" "=d")
5797
        (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5798
                     (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
5799
  "!TARGET_MIPS16"
5800
  "slt\t%0,%z2,%1"
5801
  [(set_attr "type" "slt")
5802
   (set_attr "mode" "")])
5803
 
5804
(define_insn "*sgt__mips16"
5805
  [(set (match_operand:GPR2 0 "register_operand" "=t")
5806
        (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5807
                     (match_operand:GPR 2 "register_operand" "d")))]
5808
  "TARGET_MIPS16"
5809
  "slt\t%2,%1"
5810
  [(set_attr "type" "slt")
5811
   (set_attr "mode" "")])
5812
 
5813
(define_insn "*sge_"
5814
  [(set (match_operand:GPR2 0 "register_operand" "=d")
5815
        (any_ge:GPR2 (match_operand:GPR 1 "register_operand" "d")
5816
                     (const_int 1)))]
5817
  "!TARGET_MIPS16"
5818
  "slt\t%0,%.,%1"
5819
  [(set_attr "type" "slt")
5820
   (set_attr "mode" "")])
5821
 
5822
(define_insn "*slt_"
5823
  [(set (match_operand:GPR2 0 "register_operand" "=d")
5824
        (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5825
                     (match_operand:GPR 2 "arith_operand" "dI")))]
5826
  "!TARGET_MIPS16"
5827
  "slt\t%0,%1,%2"
5828
  [(set_attr "type" "slt")
5829
   (set_attr "mode" "")])
5830
 
5831
(define_insn "*slt__mips16"
5832
  [(set (match_operand:GPR2 0 "register_operand" "=t,t,t")
5833
        (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d,d,d")
5834
                     (match_operand:GPR 2 "arith_operand" "d,Uub8,I")))]
5835
  "TARGET_MIPS16"
5836
  "slt\t%1,%2"
5837
  [(set_attr "type" "slt")
5838
   (set_attr "mode" "")
5839
   (set_attr "extended_mips16" "no,no,yes")])
5840
 
5841
(define_insn "*sle_"
5842
  [(set (match_operand:GPR2 0 "register_operand" "=d")
5843
        (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d")
5844
                     (match_operand:GPR 2 "sle_operand" "")))]
5845
  "!TARGET_MIPS16"
5846
{
5847
  operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5848
  return "slt\t%0,%1,%2";
5849
}
5850
  [(set_attr "type" "slt")
5851
   (set_attr "mode" "")])
5852
 
5853
(define_insn "*sle__mips16"
5854
  [(set (match_operand:GPR2 0 "register_operand" "=t,t")
5855
        (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d,d")
5856
                     (match_operand:GPR 2 "sle_operand" "Udb8,i")))]
5857
  "TARGET_MIPS16"
5858
{
5859
  operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5860
  return "slt\t%1,%2";
5861
}
5862
  [(set_attr "type" "slt")
5863
   (set_attr "mode" "")
5864
   (set_attr "extended_mips16" "no,yes")])
5865
 
5866
;;
5867
;;  ....................
5868
;;
5869
;;      FLOATING POINT COMPARISONS
5870
;;
5871
;;  ....................
5872
 
5873
(define_insn "s_"
5874
  [(set (match_operand:CC 0 "register_operand" "=z")
5875
        (fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
5876
                  (match_operand:SCALARF 2 "register_operand" "f")))]
5877
  ""
5878
  "c..\t%Z0%1,%2"
5879
  [(set_attr "type" "fcmp")
5880
   (set_attr "mode" "FPSW")])
5881
 
5882
(define_insn "s_"
5883
  [(set (match_operand:CC 0 "register_operand" "=z")
5884
        (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
5885
                          (match_operand:SCALARF 2 "register_operand" "f")))]
5886
  ""
5887
  "c..\t%Z0%2,%1"
5888
  [(set_attr "type" "fcmp")
5889
   (set_attr "mode" "FPSW")])
5890
 
5891
;;
5892
;;  ....................
5893
;;
5894
;;      UNCONDITIONAL BRANCHES
5895
;;
5896
;;  ....................
5897
 
5898
;; Unconditional branches.
5899
 
5900
(define_expand "jump"
5901
  [(set (pc)
5902
        (label_ref (match_operand 0)))])
5903
 
5904
(define_insn "*jump_absolute"
5905
  [(set (pc)
5906
        (label_ref (match_operand 0)))]
5907
  "!TARGET_MIPS16 && TARGET_ABSOLUTE_JUMPS"
5908
{
5909
  /* Use a branch for microMIPS.  The assembler will choose
5910
     a 16-bit branch, a 32-bit branch, or a 32-bit jump.  */
5911
  if (TARGET_MICROMIPS && !TARGET_ABICALLS_PIC2)
5912
    return "%*b\t%l0%/";
5913
  else
5914
    return MIPS_ABSOLUTE_JUMP ("%*j\t%l0%/");
5915
}
5916
  [(set_attr "type" "jump")])
5917
 
5918
(define_insn "*jump_pic"
5919
  [(set (pc)
5920
        (label_ref (match_operand 0)))]
5921
  "!TARGET_MIPS16 && !TARGET_ABSOLUTE_JUMPS"
5922
{
5923
  if (get_attr_length (insn) <= 8)
5924
    return "%*b\t%l0%/";
5925
  else
5926
    {
5927
      mips_output_load_label (operands[0]);
5928
      return "%*jr\t%@%/%]";
5929
    }
5930
}
5931
  [(set_attr "type" "branch")])
5932
 
5933
;; We need a different insn for the mips16, because a mips16 branch
5934
;; does not have a delay slot.
5935
 
5936
(define_insn "*jump_mips16"
5937
  [(set (pc)
5938
        (label_ref (match_operand 0 "" "")))]
5939
  "TARGET_MIPS16"
5940
  "b\t%l0"
5941
  [(set_attr "type" "branch")
5942
   (set (attr "length")
5943
        ;; This calculation is like the normal branch one, but the
5944
        ;; range of the unextended instruction is [-0x800, 0x7fe] rather
5945
        ;; than [-0x100, 0xfe].  This translates to a range of:
5946
        ;;
5947
        ;;    [-(0x800 - sizeof (branch)), 0x7fe]
5948
        ;; == [-0x7fe, 0x7fe]
5949
        ;;
5950
        ;; from the shorten_branches reference address.  Long-branch
5951
        ;; sequences will replace this one, so the minimum length
5952
        ;; is one instruction shorter than for conditional branches.
5953
        (cond [(and (le (minus (match_dup 0) (pc)) (const_int 2046))
5954
                    (le (minus (pc) (match_dup 0)) (const_int 2046)))
5955
               (const_int 2)
5956
               (and (le (minus (match_dup 0) (pc)) (const_int 65534))
5957
                    (le (minus (pc) (match_dup 0)) (const_int 65532)))
5958
               (const_int 4)
5959
               (and (match_test "TARGET_ABICALLS")
5960
                    (not (match_test "TARGET_ABSOLUTE_ABICALLS")))
5961
               (const_int 18)
5962
               (match_test "Pmode == SImode")
5963
               (const_int 14)
5964
               ] (const_int 22)))])
5965
 
5966
(define_expand "indirect_jump"
5967
  [(set (pc) (match_operand 0 "register_operand"))]
5968
  ""
5969
{
5970
  operands[0] = force_reg (Pmode, operands[0]);
5971
  emit_jump_insn (PMODE_INSN (gen_indirect_jump, (operands[0])));
5972
  DONE;
5973
})
5974
 
5975
(define_insn "indirect_jump_"
5976
  [(set (pc) (match_operand:P 0 "register_operand" "d"))]
5977
  ""
5978
{
5979
  if (TARGET_MICROMIPS)
5980
    return "%*jr%:\t%0";
5981
  else
5982
    return "%*j\t%0%/";
5983
}
5984
  [(set_attr "type" "jump")
5985
   (set_attr "mode" "none")])
5986
 
5987
;; A combined jump-and-move instruction, used for MIPS16 long-branch
5988
;; sequences.  Having a dedicated pattern is more convenient than
5989
;; creating a SEQUENCE for this special case.
5990
(define_insn "indirect_jump_and_restore_"
5991
  [(set (pc) (match_operand:P 1 "register_operand" "d"))
5992
   (set (match_operand:P 0 "register_operand" "=d")
5993
        (match_operand:P 2 "register_operand" "y"))]
5994
  ""
5995
  "%(%%)"
5996
  [(set_attr "type" "multi")
5997
   (set_attr "extended_mips16" "yes")])
5998
 
5999
(define_expand "tablejump"
6000
  [(set (pc)
6001
        (match_operand 0 "register_operand"))
6002
   (use (label_ref (match_operand 1 "")))]
6003
  "!TARGET_MIPS16_SHORT_JUMP_TABLES"
6004
{
6005
  if (TARGET_GPWORD)
6006
    operands[0] = expand_binop (Pmode, add_optab, operands[0],
6007
                                pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
6008
  else if (TARGET_RTP_PIC)
6009
    {
6010
      /* When generating RTP PIC, we use case table entries that are relative
6011
         to the start of the function.  Add the function's address to the
6012
         value we loaded.  */
6013
      rtx start = get_hard_reg_initial_val (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6014
      operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
6015
                                  start, 0, 0, OPTAB_WIDEN);
6016
    }
6017
 
6018
  emit_jump_insn (PMODE_INSN (gen_tablejump, (operands[0], operands[1])));
6019
  DONE;
6020
})
6021
 
6022
(define_insn "tablejump_"
6023
  [(set (pc)
6024
        (match_operand:P 0 "register_operand" "d"))
6025
   (use (label_ref (match_operand 1 "" "")))]
6026
  ""
6027
{
6028
  if (TARGET_MICROMIPS)
6029
    return "%*jr%:\t%0";
6030
  else
6031
    return "%*j\t%0%/";
6032
}
6033
  [(set_attr "type" "jump")
6034
   (set_attr "mode" "none")])
6035
 
6036
;; For MIPS16, we don't know whether a given jump table will use short or
6037
;; word-sized offsets until late in compilation, when we are able to determine
6038
;; the sizes of the insns which comprise the containing function.  This
6039
;; necessitates the use of the casesi rather than the tablejump pattern, since
6040
;; the latter tries to calculate the index of the offset to jump through early
6041
;; in compilation, i.e. at expand time, when nothing is known about the
6042
;; eventual function layout.
6043
 
6044
(define_expand "casesi"
6045
  [(match_operand:SI 0 "register_operand" "")   ; index to jump on
6046
   (match_operand:SI 1 "const_int_operand" "")  ; lower bound
6047
   (match_operand:SI 2 "const_int_operand" "")  ; total range
6048
   (match_operand 3 "" "")                      ; table label
6049
   (match_operand 4 "" "")]                     ; out of range label
6050
  "TARGET_MIPS16_SHORT_JUMP_TABLES"
6051
{
6052
  if (operands[1] != const0_rtx)
6053
    {
6054
      rtx reg = gen_reg_rtx (SImode);
6055
      rtx offset = gen_int_mode (-INTVAL (operands[1]), SImode);
6056
 
6057
      if (!arith_operand (offset, SImode))
6058
        offset = force_reg (SImode, offset);
6059
 
6060
      emit_insn (gen_addsi3 (reg, operands[0], offset));
6061
      operands[0] = reg;
6062
    }
6063
 
6064
  if (!arith_operand (operands[0], SImode))
6065
    operands[0] = force_reg (SImode, operands[0]);
6066
 
6067
  operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6068
 
6069
  emit_jump_insn (PMODE_INSN (gen_casesi_internal_mips16,
6070
                              (operands[0], operands[2],
6071
                               operands[3], operands[4])));
6072
 
6073
  DONE;
6074
})
6075
 
6076
(define_insn "casesi_internal_mips16_"
6077
  [(set (pc)
6078
     (if_then_else
6079
       (leu (match_operand:SI 0 "register_operand" "d")
6080
            (match_operand:SI 1 "arith_operand" "dI"))
6081
       (unspec:P
6082
        [(match_dup 0)
6083
         (label_ref (match_operand 2 "" ""))]
6084
        UNSPEC_CASESI_DISPATCH)
6085
       (label_ref (match_operand 3 "" ""))))
6086
   (clobber (match_scratch:P 4 "=d"))
6087
   (clobber (match_scratch:P 5 "=d"))
6088
   (clobber (reg:SI MIPS16_T_REGNUM))]
6089
  "TARGET_MIPS16_SHORT_JUMP_TABLES"
6090
{
6091
  rtx diff_vec = PATTERN (NEXT_INSN (operands[2]));
6092
 
6093
  gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
6094
 
6095
  output_asm_insn ("sltu\t%0, %1", operands);
6096
  output_asm_insn ("bteqz\t%3", operands);
6097
 
6098
  switch (GET_MODE (diff_vec))
6099
    {
6100
    case HImode:
6101
      output_asm_insn ("sll\t%5, %0, 1", operands);
6102
      output_asm_insn ("la\t%4, %2", operands);
6103
      output_asm_insn ("addu\t%5, %4, %5", operands);
6104
      output_asm_insn ("lh\t%5, 0(%5)", operands);
6105
      break;
6106
 
6107
    case SImode:
6108
      output_asm_insn ("sll\t%5, %0, 2", operands);
6109
      output_asm_insn ("la\t%4, %2", operands);
6110
      output_asm_insn ("addu\t%5, %4, %5", operands);
6111
      output_asm_insn ("lw\t%5, 0(%5)", operands);
6112
      break;
6113
 
6114
    default:
6115
      gcc_unreachable ();
6116
    }
6117
 
6118
  output_asm_insn ("addu\t%4, %4, %5", operands);
6119
 
6120
  return "j\t%4";
6121
}
6122
  [(set_attr "insn_count" "16")])
6123
 
6124
;; For TARGET_USE_GOT, we save the gp in the jmp_buf as well.
6125
;; While it is possible to either pull it off the stack (in the
6126
;; o32 case) or recalculate it given t9 and our target label,
6127
;; it takes 3 or 4 insns to do so.
6128
 
6129
(define_expand "builtin_setjmp_setup"
6130
  [(use (match_operand 0 "register_operand"))]
6131
  "TARGET_USE_GOT"
6132
{
6133
  rtx addr;
6134
 
6135
  addr = plus_constant (Pmode, operands[0], GET_MODE_SIZE (Pmode) * 3);
6136
  mips_emit_move (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
6137
  DONE;
6138
})
6139
 
6140
;; Restore the gp that we saved above.  Despite the earlier comment, it seems
6141
;; that older code did recalculate the gp from $25.  Continue to jump through
6142
;; $25 for compatibility (we lose nothing by doing so).
6143
 
6144
(define_expand "builtin_longjmp"
6145
  [(use (match_operand 0 "register_operand"))]
6146
  "TARGET_USE_GOT"
6147
{
6148
  /* The elements of the buffer are, in order:  */
6149
  int W = GET_MODE_SIZE (Pmode);
6150
  rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6151
  rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 1*W));
6152
  rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 2*W));
6153
  rtx gpv = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 3*W));
6154
  rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6155
  /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
6156
     The target is bound to be using $28 as the global pointer
6157
     but the current function might not be.  */
6158
  rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
6159
 
6160
  /* This bit is similar to expand_builtin_longjmp except that it
6161
     restores $gp as well.  */
6162
  mips_emit_move (hard_frame_pointer_rtx, fp);
6163
  mips_emit_move (pv, lab);
6164
  emit_stack_restore (SAVE_NONLOCAL, stack);
6165
  mips_emit_move (gp, gpv);
6166
  emit_use (hard_frame_pointer_rtx);
6167
  emit_use (stack_pointer_rtx);
6168
  emit_use (gp);
6169
  emit_indirect_jump (pv);
6170
  DONE;
6171
})
6172
 
6173
;;
6174
;;  ....................
6175
;;
6176
;;      Function prologue/epilogue
6177
;;
6178
;;  ....................
6179
;;
6180
 
6181
(define_expand "prologue"
6182
  [(const_int 1)]
6183
  ""
6184
{
6185
  mips_expand_prologue ();
6186
  DONE;
6187
})
6188
 
6189
;; Block any insns from being moved before this point, since the
6190
;; profiling call to mcount can use various registers that aren't
6191
;; saved or used to pass arguments.
6192
 
6193
(define_insn "blockage"
6194
  [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
6195
  ""
6196
  ""
6197
  [(set_attr "type" "ghost")
6198
   (set_attr "mode" "none")])
6199
 
6200
(define_insn "probe_stack_range_"
6201
  [(set (match_operand:P 0 "register_operand" "=d")
6202
        (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6203
                            (match_operand:P 2 "register_operand" "d")]
6204
                            UNSPEC_PROBE_STACK_RANGE))]
6205
  ""
6206
 { return mips_output_probe_stack_range (operands[0], operands[2]); }
6207
  [(set_attr "type" "unknown")
6208
   (set_attr "can_delay" "no")
6209
   (set_attr "mode" "")])
6210
 
6211
(define_expand "epilogue"
6212
  [(const_int 2)]
6213
  ""
6214
{
6215
  mips_expand_epilogue (false);
6216
  DONE;
6217
})
6218
 
6219
(define_expand "sibcall_epilogue"
6220
  [(const_int 2)]
6221
  ""
6222
{
6223
  mips_expand_epilogue (true);
6224
  DONE;
6225
})
6226
 
6227
;; Trivial return.  Make it look like a normal return insn as that
6228
;; allows jump optimizations to work better.
6229
 
6230
(define_expand "return"
6231
  [(simple_return)]
6232
  "mips_can_use_return_insn ()"
6233
  { mips_expand_before_return (); })
6234
 
6235
(define_expand "simple_return"
6236
  [(simple_return)]
6237
  ""
6238
  { mips_expand_before_return (); })
6239
 
6240
(define_insn "*"
6241
  [(any_return)]
6242
  ""
6243
  {
6244
    if (TARGET_MICROMIPS)
6245
      return "%*jr%:\t$31";
6246
    else
6247
      return "%*j\t$31%/";
6248
  }
6249
  [(set_attr "type"     "jump")
6250
   (set_attr "mode"     "none")])
6251
 
6252
;; Normal return.
6253
 
6254
(define_insn "_internal"
6255
  [(any_return)
6256
   (use (match_operand 0 "pmode_register_operand" ""))]
6257
  ""
6258
{
6259
  if (TARGET_MICROMIPS)
6260
    return "%*jr%:\t%0";
6261
  else
6262
    return "%*j\t%0%/";
6263
}
6264
  [(set_attr "type"     "jump")
6265
   (set_attr "mode"     "none")])
6266
 
6267
;; Exception return.
6268
(define_insn "mips_eret"
6269
  [(return)
6270
   (unspec_volatile [(const_int 0)] UNSPEC_ERET)]
6271
  ""
6272
  "eret"
6273
  [(set_attr "type"     "trap")
6274
   (set_attr "mode"     "none")])
6275
 
6276
;; Debug exception return.
6277
(define_insn "mips_deret"
6278
  [(return)
6279
   (unspec_volatile [(const_int 0)] UNSPEC_DERET)]
6280
  ""
6281
  "deret"
6282
  [(set_attr "type"     "trap")
6283
   (set_attr "mode"     "none")])
6284
 
6285
;; Disable interrupts.
6286
(define_insn "mips_di"
6287
  [(unspec_volatile [(const_int 0)] UNSPEC_DI)]
6288
  ""
6289
  "di"
6290
  [(set_attr "type"     "trap")
6291
   (set_attr "mode"     "none")])
6292
 
6293
;; Execution hazard barrier.
6294
(define_insn "mips_ehb"
6295
  [(unspec_volatile [(const_int 0)] UNSPEC_EHB)]
6296
  ""
6297
  "ehb"
6298
  [(set_attr "type"     "trap")
6299
   (set_attr "mode"     "none")])
6300
 
6301
;; Read GPR from previous shadow register set.
6302
(define_insn "mips_rdpgpr"
6303
  [(set (match_operand:SI 0 "register_operand" "=d")
6304
        (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d")]
6305
                            UNSPEC_RDPGPR))]
6306
  ""
6307
  "rdpgpr\t%0,%1"
6308
  [(set_attr "type"     "move")
6309
   (set_attr "mode"     "SI")])
6310
 
6311
;; Move involving COP0 registers.
6312
(define_insn "cop0_move"
6313
  [(set (match_operand:SI 0 "register_operand" "=B,d")
6314
        (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d,B")]
6315
                            UNSPEC_COP0))]
6316
  ""
6317
{ return mips_output_move (operands[0], operands[1]); }
6318
  [(set_attr "type"     "mtc,mfc")
6319
   (set_attr "mode"     "SI")])
6320
 
6321
;; This is used in compiling the unwind routines.
6322
(define_expand "eh_return"
6323
  [(use (match_operand 0 "general_operand"))]
6324
  ""
6325
{
6326
  if (GET_MODE (operands[0]) != word_mode)
6327
    operands[0] = convert_to_mode (word_mode, operands[0], 0);
6328
  if (TARGET_64BIT)
6329
    emit_insn (gen_eh_set_lr_di (operands[0]));
6330
  else
6331
    emit_insn (gen_eh_set_lr_si (operands[0]));
6332
  DONE;
6333
})
6334
 
6335
;; Clobber the return address on the stack.  We can't expand this
6336
;; until we know where it will be put in the stack frame.
6337
 
6338
(define_insn "eh_set_lr_si"
6339
  [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6340
   (clobber (match_scratch:SI 1 "=&d"))]
6341
  "! TARGET_64BIT"
6342
  "#")
6343
 
6344
(define_insn "eh_set_lr_di"
6345
  [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6346
   (clobber (match_scratch:DI 1 "=&d"))]
6347
  "TARGET_64BIT"
6348
  "#")
6349
 
6350
(define_split
6351
  [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6352
   (clobber (match_scratch 1))]
6353
  "reload_completed"
6354
  [(const_int 0)]
6355
{
6356
  mips_set_return_address (operands[0], operands[1]);
6357
  DONE;
6358
})
6359
 
6360
(define_expand "exception_receiver"
6361
  [(const_int 0)]
6362
  "TARGET_USE_GOT"
6363
{
6364
  /* See the comment above load_call for details.  */
6365
  emit_insn (gen_set_got_version ());
6366
 
6367
  /* If we have a call-clobbered $gp, restore it from its save slot.  */
6368
  if (HAVE_restore_gp_si)
6369
    emit_insn (gen_restore_gp_si ());
6370
  else if (HAVE_restore_gp_di)
6371
    emit_insn (gen_restore_gp_di ());
6372
  DONE;
6373
})
6374
 
6375
(define_expand "nonlocal_goto_receiver"
6376
  [(const_int 0)]
6377
  "TARGET_USE_GOT"
6378
{
6379
  /* See the comment above load_call for details.  */
6380
  emit_insn (gen_set_got_version ());
6381
  DONE;
6382
})
6383
 
6384
;; Restore $gp from its .cprestore stack slot.  The instruction remains
6385
;; volatile until all uses of $28 are exposed.
6386
(define_insn_and_split "restore_gp_"
6387
  [(set (reg:P 28)
6388
        (unspec_volatile:P [(const_int 0)] UNSPEC_RESTORE_GP))
6389
   (clobber (match_scratch:P 0 "=&d"))]
6390
  "TARGET_CALL_CLOBBERED_GP"
6391
  "#"
6392
  "&& epilogue_completed"
6393
  [(const_int 0)]
6394
{
6395
  mips_restore_gp_from_cprestore_slot (operands[0]);
6396
  DONE;
6397
}
6398
  [(set_attr "type" "ghost")])
6399
 
6400
;; Move between $gp and its register save slot.
6401
(define_insn_and_split "move_gp"
6402
  [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,m")
6403
        (unspec:GPR [(match_operand:GPR 1 "move_operand" "m,d")]
6404
                    UNSPEC_MOVE_GP))]
6405
  ""
6406
  { return mips_must_initialize_gp_p () ? "#" : ""; }
6407
  "mips_must_initialize_gp_p ()"
6408
  [(const_int 0)]
6409
{
6410
  mips_emit_move (operands[0], operands[1]);
6411
  DONE;
6412
}
6413
  [(set_attr "type" "ghost")])
6414
 
6415
;;
6416
;;  ....................
6417
;;
6418
;;      FUNCTION CALLS
6419
;;
6420
;;  ....................
6421
 
6422
;; Instructions to load a call address from the GOT.  The address might
6423
;; point to a function or to a lazy binding stub.  In the latter case,
6424
;; the stub will use the dynamic linker to resolve the function, which
6425
;; in turn will change the GOT entry to point to the function's real
6426
;; address.
6427
;;
6428
;; This means that every call, even pure and constant ones, can
6429
;; potentially modify the GOT entry.  And once a stub has been called,
6430
;; we must not call it again.
6431
;;
6432
;; We represent this restriction using an imaginary, fixed, call-saved
6433
;; register called GOT_VERSION_REGNUM.  The idea is to make the register
6434
;; live throughout the function and to change its value after every
6435
;; potential call site.  This stops any rtx value that uses the register
6436
;; from being computed before an earlier call.  To do this, we:
6437
;;
6438
;;    - Ensure that the register is live on entry to the function,
6439
;;      so that it is never thought to be used uninitalized.
6440
;;
6441
;;    - Ensure that the register is live on exit from the function,
6442
;;      so that it is live throughout.
6443
;;
6444
;;    - Make each call (lazily-bound or not) use the current value
6445
;;      of GOT_VERSION_REGNUM, so that updates of the register are
6446
;;      not moved across call boundaries.
6447
;;
6448
;;    - Add "ghost" definitions of the register to the beginning of
6449
;;      blocks reached by EH and ABNORMAL_CALL edges, because those
6450
;;      edges may involve calls that normal paths don't.  (E.g. the
6451
;;      unwinding code that handles a non-call exception may change
6452
;;      lazily-bound GOT entries.)  We do this by making the
6453
;;      exception_receiver and nonlocal_goto_receiver expanders emit
6454
;;      a set_got_version instruction.
6455
;;
6456
;;    - After each call (lazily-bound or not), use a "ghost"
6457
;;      update_got_version instruction to change the register's value.
6458
;;      This instruction mimics the _possible_ effect of the dynamic
6459
;;      resolver during the call and it remains live even if the call
6460
;;      itself becomes dead.
6461
;;
6462
;;    - Leave GOT_VERSION_REGNUM out of all register classes.
6463
;;      The register is therefore not a valid register_operand
6464
;;      and cannot be moved to or from other registers.
6465
 
6466
(define_insn "load_call"
6467
  [(set (match_operand:P 0 "register_operand" "=d")
6468
        (unspec:P [(match_operand:P 1 "register_operand" "d")
6469
                   (match_operand:P 2 "immediate_operand" "")
6470
                   (reg:SI GOT_VERSION_REGNUM)] UNSPEC_LOAD_CALL))]
6471
  "TARGET_USE_GOT"
6472
  "\t%0,%R2(%1)"
6473
  [(set_attr "got" "load")
6474
   (set_attr "mode" "")])
6475
 
6476
(define_insn "set_got_version"
6477
  [(set (reg:SI GOT_VERSION_REGNUM)
6478
        (unspec_volatile:SI [(const_int 0)] UNSPEC_SET_GOT_VERSION))]
6479
  "TARGET_USE_GOT"
6480
  ""
6481
  [(set_attr "type" "ghost")])
6482
 
6483
(define_insn "update_got_version"
6484
  [(set (reg:SI GOT_VERSION_REGNUM)
6485
        (unspec:SI [(reg:SI GOT_VERSION_REGNUM)] UNSPEC_UPDATE_GOT_VERSION))]
6486
  "TARGET_USE_GOT"
6487
  ""
6488
  [(set_attr "type" "ghost")])
6489
 
6490
;; Sibling calls.  All these patterns use jump instructions.
6491
 
6492
;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
6493
;; addresses if a direct jump is acceptable.  Since the 'S' constraint
6494
;; is defined in terms of call_insn_operand, the same is true of the
6495
;; constraints.
6496
 
6497
;; When we use an indirect jump, we need a register that will be
6498
;; preserved by the epilogue.  Since TARGET_USE_PIC_FN_ADDR_REG forces
6499
;; us to use $25 for this purpose -- and $25 is never clobbered by the
6500
;; epilogue -- we might as well use it for !TARGET_USE_PIC_FN_ADDR_REG
6501
;; as well.
6502
 
6503
(define_expand "sibcall"
6504
  [(parallel [(call (match_operand 0 "")
6505
                    (match_operand 1 ""))
6506
              (use (match_operand 2 ""))        ;; next_arg_reg
6507
              (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
6508
  "TARGET_SIBCALLS"
6509
{
6510
  mips_expand_call (MIPS_CALL_SIBCALL, NULL_RTX, XEXP (operands[0], 0),
6511
                    operands[1], operands[2], false);
6512
  DONE;
6513
})
6514
 
6515
(define_insn "sibcall_internal"
6516
  [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
6517
         (match_operand 1 "" ""))]
6518
  "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6519
{
6520
  if (TARGET_MICROMIPS)
6521
    return MICROMIPS_J ("j", operands, 0);
6522
  else
6523
    return MIPS_CALL ("j", operands, 0, 1);
6524
}
6525
  [(set_attr "jal" "indirect,direct")
6526
   (set_attr "jal_macro" "no")])
6527
 
6528
(define_expand "sibcall_value"
6529
  [(parallel [(set (match_operand 0 "")
6530
                   (call (match_operand 1 "")
6531
                         (match_operand 2 "")))
6532
              (use (match_operand 3 ""))])]             ;; next_arg_reg
6533
  "TARGET_SIBCALLS"
6534
{
6535
  mips_expand_call (MIPS_CALL_SIBCALL, operands[0], XEXP (operands[1], 0),
6536
                    operands[2], operands[3], false);
6537
  DONE;
6538
})
6539
 
6540
(define_insn "sibcall_value_internal"
6541
  [(set (match_operand 0 "register_operand" "")
6542
        (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6543
              (match_operand 2 "" "")))]
6544
  "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6545
{
6546
  if (TARGET_MICROMIPS)
6547
    return MICROMIPS_J ("j", operands, 1);
6548
  else
6549
    return MIPS_CALL ("j", operands, 1, 2);
6550
}
6551
  [(set_attr "jal" "indirect,direct")
6552
   (set_attr "jal_macro" "no")])
6553
 
6554
(define_insn "sibcall_value_multiple_internal"
6555
  [(set (match_operand 0 "register_operand" "")
6556
        (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6557
              (match_operand 2 "" "")))
6558
   (set (match_operand 3 "register_operand" "")
6559
        (call (mem:SI (match_dup 1))
6560
              (match_dup 2)))]
6561
  "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6562
{
6563
  if (TARGET_MICROMIPS)
6564
    return MICROMIPS_J ("j", operands, 1);
6565
  else
6566
    return MIPS_CALL ("j", operands, 1, 2);
6567
}
6568
  [(set_attr "jal" "indirect,direct")
6569
   (set_attr "jal_macro" "no")])
6570
 
6571
(define_expand "call"
6572
  [(parallel [(call (match_operand 0 "")
6573
                    (match_operand 1 ""))
6574
              (use (match_operand 2 ""))        ;; next_arg_reg
6575
              (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
6576
  ""
6577
{
6578
  mips_expand_call (MIPS_CALL_NORMAL, NULL_RTX, XEXP (operands[0], 0),
6579
                    operands[1], operands[2], false);
6580
  DONE;
6581
})
6582
 
6583
;; This instruction directly corresponds to an assembly-language "jal".
6584
;; There are four cases:
6585
;;
6586
;;    - -mno-abicalls:
6587
;;        Both symbolic and register destinations are OK.  The pattern
6588
;;        always expands to a single mips instruction.
6589
;;
6590
;;    - -mabicalls/-mno-explicit-relocs:
6591
;;        Again, both symbolic and register destinations are OK.
6592
;;        The call is treated as a multi-instruction black box.
6593
;;
6594
;;    - -mabicalls/-mexplicit-relocs with n32 or n64:
6595
;;        Only "jal $25" is allowed.  This expands to a single "jalr $25"
6596
;;        instruction.
6597
;;
6598
;;    - -mabicalls/-mexplicit-relocs with o32 or o64:
6599
;;        Only "jal $25" is allowed.  The call is actually two instructions:
6600
;;        "jalr $25" followed by an insn to reload $gp.
6601
;;
6602
;; In the last case, we can generate the individual instructions with
6603
;; a define_split.  There are several things to be wary of:
6604
;;
6605
;;   - We can't expose the load of $gp before reload.  If we did,
6606
;;     it might get removed as dead, but reload can introduce new
6607
;;     uses of $gp by rematerializing constants.
6608
;;
6609
;;   - We shouldn't restore $gp after calls that never return.
6610
;;     It isn't valid to insert instructions between a noreturn
6611
;;     call and the following barrier.
6612
;;
6613
;;   - The splitter deliberately changes the liveness of $gp.  The unsplit
6614
;;     instruction preserves $gp and so have no effect on its liveness.
6615
;;     But once we generate the separate insns, it becomes obvious that
6616
;;     $gp is not live on entry to the call.
6617
;;
6618
(define_insn_and_split "call_internal"
6619
  [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
6620
         (match_operand 1 "" ""))
6621
   (clobber (reg:SI RETURN_ADDR_REGNUM))]
6622
  ""
6623
  { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, 1); }
6624
  "reload_completed && TARGET_SPLIT_CALLS"
6625
  [(const_int 0)]
6626
{
6627
  mips_split_call (curr_insn, gen_call_split (operands[0], operands[1]));
6628
  DONE;
6629
}
6630
  [(set_attr "jal" "indirect,direct")])
6631
 
6632
(define_insn "call_split"
6633
  [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
6634
         (match_operand 1 "" ""))
6635
   (clobber (reg:SI RETURN_ADDR_REGNUM))
6636
   (clobber (reg:SI 28))]
6637
  "TARGET_SPLIT_CALLS"
6638
  { return MIPS_CALL ("jal", operands, 0, 1); }
6639
  [(set_attr "jal" "indirect,direct")
6640
   (set_attr "jal_macro" "no")])
6641
 
6642
;; A pattern for calls that must be made directly.  It is used for
6643
;; MIPS16 calls that the linker may need to redirect to a hard-float
6644
;; stub; the linker relies on the call relocation type to detect when
6645
;; such redirection is needed.
6646
(define_insn_and_split "call_internal_direct"
6647
  [(call (mem:SI (match_operand 0 "const_call_insn_operand"))
6648
         (match_operand 1))
6649
   (const_int 1)
6650
   (clobber (reg:SI RETURN_ADDR_REGNUM))]
6651
  ""
6652
  { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, -1); }
6653
  "reload_completed && TARGET_SPLIT_CALLS"
6654
  [(const_int 0)]
6655
{
6656
  mips_split_call (curr_insn,
6657
                   gen_call_direct_split (operands[0], operands[1]));
6658
  DONE;
6659
}
6660
  [(set_attr "jal" "direct")])
6661
 
6662
(define_insn "call_direct_split"
6663
  [(call (mem:SI (match_operand 0 "const_call_insn_operand"))
6664
         (match_operand 1))
6665
   (const_int 1)
6666
   (clobber (reg:SI RETURN_ADDR_REGNUM))
6667
   (clobber (reg:SI 28))]
6668
  "TARGET_SPLIT_CALLS"
6669
  { return MIPS_CALL ("jal", operands, 0, -1); }
6670
  [(set_attr "jal" "direct")
6671
   (set_attr "jal_macro" "no")])
6672
 
6673
(define_expand "call_value"
6674
  [(parallel [(set (match_operand 0 "")
6675
                   (call (match_operand 1 "")
6676
                         (match_operand 2 "")))
6677
              (use (match_operand 3 ""))])]             ;; next_arg_reg
6678
  ""
6679
{
6680
  mips_expand_call (MIPS_CALL_NORMAL, operands[0], XEXP (operands[1], 0),
6681
                    operands[2], operands[3], false);
6682
  DONE;
6683
})
6684
 
6685
;; See comment for call_internal.
6686
(define_insn_and_split "call_value_internal"
6687
  [(set (match_operand 0 "register_operand" "")
6688
        (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6689
              (match_operand 2 "" "")))
6690
   (clobber (reg:SI RETURN_ADDR_REGNUM))]
6691
  ""
6692
  { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); }
6693
  "reload_completed && TARGET_SPLIT_CALLS"
6694
  [(const_int 0)]
6695
{
6696
  mips_split_call (curr_insn,
6697
                   gen_call_value_split (operands[0], operands[1],
6698
                                         operands[2]));
6699
  DONE;
6700
}
6701
  [(set_attr "jal" "indirect,direct")])
6702
 
6703
(define_insn "call_value_split"
6704
  [(set (match_operand 0 "register_operand" "")
6705
        (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6706
              (match_operand 2 "" "")))
6707
   (clobber (reg:SI RETURN_ADDR_REGNUM))
6708
   (clobber (reg:SI 28))]
6709
  "TARGET_SPLIT_CALLS"
6710
  { return MIPS_CALL ("jal", operands, 1, 2); }
6711
  [(set_attr "jal" "indirect,direct")
6712
   (set_attr "jal_macro" "no")])
6713
 
6714
;; See call_internal_direct.
6715
(define_insn_and_split "call_value_internal_direct"
6716
  [(set (match_operand 0 "register_operand")
6717
        (call (mem:SI (match_operand 1 "const_call_insn_operand"))
6718
              (match_operand 2)))
6719
   (const_int 1)
6720
   (clobber (reg:SI RETURN_ADDR_REGNUM))]
6721
  ""
6722
  { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, -1); }
6723
  "reload_completed && TARGET_SPLIT_CALLS"
6724
  [(const_int 0)]
6725
{
6726
  mips_split_call (curr_insn,
6727
                   gen_call_value_direct_split (operands[0], operands[1],
6728
                                                operands[2]));
6729
  DONE;
6730
}
6731
  [(set_attr "jal" "direct")])
6732
 
6733
(define_insn "call_value_direct_split"
6734
  [(set (match_operand 0 "register_operand")
6735
        (call (mem:SI (match_operand 1 "const_call_insn_operand"))
6736
              (match_operand 2)))
6737
   (const_int 1)
6738
   (clobber (reg:SI RETURN_ADDR_REGNUM))
6739
   (clobber (reg:SI 28))]
6740
  "TARGET_SPLIT_CALLS"
6741
  { return MIPS_CALL ("jal", operands, 1, -1); }
6742
  [(set_attr "jal" "direct")
6743
   (set_attr "jal_macro" "no")])
6744
 
6745
;; See comment for call_internal.
6746
(define_insn_and_split "call_value_multiple_internal"
6747
  [(set (match_operand 0 "register_operand" "")
6748
        (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6749
              (match_operand 2 "" "")))
6750
   (set (match_operand 3 "register_operand" "")
6751
        (call (mem:SI (match_dup 1))
6752
              (match_dup 2)))
6753
   (clobber (reg:SI RETURN_ADDR_REGNUM))]
6754
  ""
6755
  { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); }
6756
  "reload_completed && TARGET_SPLIT_CALLS"
6757
  [(const_int 0)]
6758
{
6759
  mips_split_call (curr_insn,
6760
                   gen_call_value_multiple_split (operands[0], operands[1],
6761
                                                  operands[2], operands[3]));
6762
  DONE;
6763
}
6764
  [(set_attr "jal" "indirect,direct")])
6765
 
6766
(define_insn "call_value_multiple_split"
6767
  [(set (match_operand 0 "register_operand" "")
6768
        (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6769
              (match_operand 2 "" "")))
6770
   (set (match_operand 3 "register_operand" "")
6771
        (call (mem:SI (match_dup 1))
6772
              (match_dup 2)))
6773
   (clobber (reg:SI RETURN_ADDR_REGNUM))
6774
   (clobber (reg:SI 28))]
6775
  "TARGET_SPLIT_CALLS"
6776
  { return MIPS_CALL ("jal", operands, 1, 2); }
6777
  [(set_attr "jal" "indirect,direct")
6778
   (set_attr "jal_macro" "no")])
6779
 
6780
;; Call subroutine returning any type.
6781
 
6782
(define_expand "untyped_call"
6783
  [(parallel [(call (match_operand 0 "")
6784
                    (const_int 0))
6785
              (match_operand 1 "")
6786
              (match_operand 2 "")])]
6787
  ""
6788
{
6789
  int i;
6790
 
6791
  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6792
 
6793
  for (i = 0; i < XVECLEN (operands[2], 0); i++)
6794
    {
6795
      rtx set = XVECEXP (operands[2], 0, i);
6796
      mips_emit_move (SET_DEST (set), SET_SRC (set));
6797
    }
6798
 
6799
  emit_insn (gen_blockage ());
6800
  DONE;
6801
})
6802
 
6803
;;
6804
;;  ....................
6805
;;
6806
;;      MISC.
6807
;;
6808
;;  ....................
6809
;;
6810
 
6811
 
6812
(define_insn "prefetch"
6813
  [(prefetch (match_operand:QI 0 "address_operand" "ZD")
6814
             (match_operand 1 "const_int_operand" "n")
6815
             (match_operand 2 "const_int_operand" "n"))]
6816
  "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
6817
{
6818
  if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A)
6819
    {
6820
      /* Loongson 2[ef] and Loongson 3a use load to $0 for prefetching.  */
6821
      if (TARGET_64BIT)
6822
        return "ld\t$0,%a0";
6823
      else
6824
        return "lw\t$0,%a0";
6825
    }
6826
  operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
6827
  return "pref\t%1,%a0";
6828
}
6829
  [(set_attr "type" "prefetch")])
6830
 
6831
(define_insn "*prefetch_indexed_"
6832
  [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
6833
                     (match_operand:P 1 "register_operand" "d"))
6834
             (match_operand 2 "const_int_operand" "n")
6835
             (match_operand 3 "const_int_operand" "n"))]
6836
  "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6837
{
6838
  operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
6839
  return "prefx\t%2,%1(%0)";
6840
}
6841
  [(set_attr "type" "prefetchx")])
6842
 
6843
(define_insn "nop"
6844
  [(const_int 0)]
6845
  ""
6846
  "%(nop%)"
6847
  [(set_attr "type"     "nop")
6848
   (set_attr "mode"     "none")])
6849
 
6850
;; Like nop, but commented out when outside a .set noreorder block.
6851
(define_insn "hazard_nop"
6852
  [(const_int 1)]
6853
  ""
6854
  {
6855
    if (mips_noreorder.nesting_level > 0)
6856
      return "nop";
6857
    else
6858
      return "#nop";
6859
  }
6860
  [(set_attr "type"     "nop")])
6861
 
6862
;; MIPS4 Conditional move instructions.
6863
 
6864
(define_insn "*mov_on_"
6865
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
6866
        (if_then_else:GPR
6867
         (match_operator 4 "equality_operator"
6868
                [(match_operand:MOVECC 1 "register_operand" ",")
6869
                 (const_int 0)])
6870
         (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
6871
         (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
6872
  "ISA_HAS_CONDMOVE"
6873
  "@
6874
    mov%T4\t%0,%z2,%1
6875
    mov%t4\t%0,%z3,%1"
6876
  [(set_attr "type" "condmove")
6877
   (set_attr "mode" "")])
6878
 
6879
(define_insn "*mov_on__ne"
6880
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
6881
       (if_then_else:GPR
6882
        (match_operand:GPR2 1 "register_operand" ",")
6883
        (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
6884
        (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
6885
  "ISA_HAS_CONDMOVE"
6886
  "@
6887
    movn\t%0,%z2,%1
6888
    movz\t%0,%z3,%1"
6889
  [(set_attr "type" "condmove")
6890
   (set_attr "mode" "")])
6891
 
6892
(define_insn "*mov_on_"
6893
  [(set (match_operand:SCALARF 0 "register_operand" "=f,f")
6894
        (if_then_else:SCALARF
6895
         (match_operator 4 "equality_operator"
6896
                [(match_operand:MOVECC 1 "register_operand" ",")
6897
                 (const_int 0)])
6898
         (match_operand:SCALARF 2 "register_operand" "f,0")
6899
         (match_operand:SCALARF 3 "register_operand" "0,f")))]
6900
  "ISA_HAS_FP_CONDMOVE"
6901
  "@
6902
    mov%T4.\t%0,%2,%1
6903
    mov%t4.\t%0,%3,%1"
6904
  [(set_attr "type" "condmove")
6905
   (set_attr "mode" "")])
6906
 
6907
;; These are the main define_expand's used to make conditional moves.
6908
 
6909
(define_expand "movcc"
6910
  [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6911
   (set (match_operand:GPR 0 "register_operand")
6912
        (if_then_else:GPR (match_dup 5)
6913
                          (match_operand:GPR 2 "reg_or_0_operand")
6914
                          (match_operand:GPR 3 "reg_or_0_operand")))]
6915
  "ISA_HAS_CONDMOVE"
6916
{
6917
  mips_expand_conditional_move (operands);
6918
  DONE;
6919
})
6920
 
6921
(define_expand "movcc"
6922
  [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6923
   (set (match_operand:SCALARF 0 "register_operand")
6924
        (if_then_else:SCALARF (match_dup 5)
6925
                              (match_operand:SCALARF 2 "register_operand")
6926
                              (match_operand:SCALARF 3 "register_operand")))]
6927
  "ISA_HAS_FP_CONDMOVE"
6928
{
6929
  mips_expand_conditional_move (operands);
6930
  DONE;
6931
})
6932
 
6933
;;
6934
;;  ....................
6935
;;
6936
;;      mips16 inline constant tables
6937
;;
6938
;;  ....................
6939
;;
6940
 
6941
(define_insn "consttable_tls_reloc"
6942
  [(unspec_volatile [(match_operand 0 "tls_reloc_operand" "")
6943
                     (match_operand 1 "const_int_operand" "")]
6944
                    UNSPEC_CONSTTABLE_INT)]
6945
  "TARGET_MIPS16_PCREL_LOADS"
6946
  { return mips_output_tls_reloc_directive (&operands[0]); }
6947
  [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
6948
 
6949
(define_insn "consttable_int"
6950
  [(unspec_volatile [(match_operand 0 "consttable_operand" "")
6951
                     (match_operand 1 "const_int_operand" "")]
6952
                    UNSPEC_CONSTTABLE_INT)]
6953
  "TARGET_MIPS16"
6954
{
6955
  assemble_integer (mips_strip_unspec_address (operands[0]),
6956
                    INTVAL (operands[1]),
6957
                    BITS_PER_UNIT * INTVAL (operands[1]), 1);
6958
  return "";
6959
}
6960
  [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
6961
 
6962
(define_insn "consttable_float"
6963
  [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
6964
                    UNSPEC_CONSTTABLE_FLOAT)]
6965
  "TARGET_MIPS16"
6966
{
6967
  REAL_VALUE_TYPE d;
6968
 
6969
  gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
6970
  REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
6971
  assemble_real (d, GET_MODE (operands[0]),
6972
                 GET_MODE_BITSIZE (GET_MODE (operands[0])));
6973
  return "";
6974
}
6975
  [(set (attr "length")
6976
        (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
6977
 
6978
(define_insn "align"
6979
  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
6980
  ""
6981
  ".align\t%0"
6982
  [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
6983
 
6984
(define_split
6985
  [(match_operand 0 "small_data_pattern")]
6986
  "reload_completed"
6987
  [(match_dup 0)]
6988
  { operands[0] = mips_rewrite_small_data (operands[0]); })
6989
 
6990
;;
6991
;;  ....................
6992
;;
6993
;;      MIPS16e Save/Restore
6994
;;
6995
;;  ....................
6996
;;
6997
 
6998
(define_insn "*mips16e_save_restore"
6999
  [(match_parallel 0 ""
7000
       [(set (match_operand:SI 1 "register_operand")
7001
             (plus:SI (match_dup 1)
7002
                      (match_operand:SI 2 "const_int_operand")))])]
7003
  "operands[1] == stack_pointer_rtx
7004
   && mips16e_save_restore_pattern_p (operands[0], INTVAL (operands[2]), NULL)"
7005
  { return mips16e_output_save_restore (operands[0], INTVAL (operands[2])); }
7006
  [(set_attr "type" "arith")
7007
   (set_attr "extended_mips16" "yes")])
7008
 
7009
;; Thread-Local Storage
7010
 
7011
;; The TLS base pointer is accessed via "rdhwr $3, $29".  No current
7012
;; MIPS architecture defines this register, and no current
7013
;; implementation provides it; instead, any OS which supports TLS is
7014
;; expected to trap and emulate this instruction.  rdhwr is part of the
7015
;; MIPS 32r2 specification, but we use it on any architecture because
7016
;; we expect it to be emulated.  Use .set to force the assembler to
7017
;; accept it.
7018
;;
7019
;; We do not use a constraint to force the destination to be $3
7020
;; because $3 can appear explicitly as a function return value.
7021
;; If we leave the use of $3 implicit in the constraints until
7022
;; reload, we may end up making a $3 return value live across
7023
;; the instruction, leading to a spill failure when reloading it.
7024
(define_insn_and_split "tls_get_tp_"
7025
  [(set (match_operand:P 0 "register_operand" "=d")
7026
        (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))
7027
   (clobber (reg:P TLS_GET_TP_REGNUM))]
7028
  "HAVE_AS_TLS && !TARGET_MIPS16"
7029
  "#"
7030
  "&& reload_completed"
7031
  [(set (reg:P TLS_GET_TP_REGNUM)
7032
        (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))
7033
   (set (match_dup 0) (reg:P TLS_GET_TP_REGNUM))]
7034
  ""
7035
  [(set_attr "type" "unknown")
7036
   (set_attr "mode" "")
7037
   (set_attr "insn_count" "2")])
7038
 
7039
(define_insn "*tls_get_tp__split"
7040
  [(set (reg:P TLS_GET_TP_REGNUM)
7041
        (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))]
7042
  "HAVE_AS_TLS && !TARGET_MIPS16"
7043
  ".set\tpush\;.set\tmips32r2\t\;rdhwr\t$3,$29\;.set\tpop"
7044
  [(set_attr "type" "unknown")
7045
   ; Since rdhwr always generates a trap for now, putting it in a delay
7046
   ; slot would make the kernel's emulation of it much slower.
7047
   (set_attr "can_delay" "no")
7048
   (set_attr "mode" "")])
7049
 
7050
;; In MIPS16 mode, the TLS base pointer is accessed by a
7051
;; libgcc helper function __mips16_rdhwr(), as 'rdhwr' is not
7052
;; accessible in MIPS16.
7053
;;
7054
;; This is not represented as a call insn, to avoid the
7055
;; unnecesarry clobbering of caller-save registers by a
7056
;; function consisting only of: "rdhwr $3,$29; j $31; nop;"
7057
;;
7058
;; A $25 clobber is added to cater for a $25 load stub added by the
7059
;; linker to __mips16_rdhwr when the call is made from non-PIC code.
7060
 
7061
(define_insn_and_split "tls_get_tp_mips16_"
7062
  [(set (match_operand:P 0 "register_operand" "=d")
7063
        (unspec:P [(match_operand:P 1 "call_insn_operand" "dS")]
7064
                  UNSPEC_TLS_GET_TP))
7065
   (clobber (reg:P TLS_GET_TP_REGNUM))
7066
   (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7067
   (clobber (reg:P RETURN_ADDR_REGNUM))]
7068
  "HAVE_AS_TLS && TARGET_MIPS16"
7069
  "#"
7070
  "&& reload_completed"
7071
  [(parallel [(set (reg:P TLS_GET_TP_REGNUM)
7072
                   (unspec:P [(match_dup 1)] UNSPEC_TLS_GET_TP))
7073
              (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7074
              (clobber (reg:P RETURN_ADDR_REGNUM))])
7075
   (set (match_dup 0) (reg:P TLS_GET_TP_REGNUM))]
7076
  ""
7077
  [(set_attr "type" "multi")
7078
   (set_attr "insn_count" "4")
7079
   (set_attr "mode" "")])
7080
 
7081
(define_insn "*tls_get_tp_mips16_call_"
7082
  [(set (reg:P TLS_GET_TP_REGNUM)
7083
        (unspec:P [(match_operand:P 0 "call_insn_operand" "dS")]
7084
                  UNSPEC_TLS_GET_TP))
7085
   (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7086
   (clobber (reg:P RETURN_ADDR_REGNUM))]
7087
  "HAVE_AS_TLS && TARGET_MIPS16"
7088
  { return MIPS_CALL ("jal", operands, 0, -1); }
7089
  [(set_attr "type" "call")
7090
   (set_attr "insn_count" "3")
7091
   (set_attr "mode" "")])
7092
 
7093
;; Named pattern for expanding thread pointer reference.
7094
(define_expand "get_thread_pointer"
7095
  [(match_operand:P 0 "register_operand" "=d")]
7096
  "HAVE_AS_TLS"
7097
{
7098
  mips_expand_thread_pointer (operands[0]);
7099
  DONE;
7100
})
7101
 
7102
;; __builtin_mips_get_fcsr: move the FCSR into operand 0.
7103
(define_expand "mips_get_fcsr"
7104
  [(set (match_operand:SI 0 "register_operand")
7105
        (unspec_volatile [(const_int 0)] UNSPEC_GET_FCSR))]
7106
  "TARGET_HARD_FLOAT_ABI"
7107
{
7108
  if (TARGET_MIPS16)
7109
    {
7110
      mips16_expand_get_fcsr (operands[0]);
7111
      DONE;
7112
    }
7113
})
7114
 
7115
(define_insn "*mips_get_fcsr"
7116
  [(set (match_operand:SI 0 "register_operand" "=d")
7117
        (unspec_volatile [(const_int 0)] UNSPEC_GET_FCSR))]
7118
  "TARGET_HARD_FLOAT"
7119
  "cfc1\t%0,$31")
7120
 
7121
;; See tls_get_tp_mips16_ for why this form is used.
7122
(define_insn "mips_get_fcsr_mips16_"
7123
  [(set (reg:SI GET_FCSR_REGNUM)
7124
        (unspec:SI [(match_operand:P 0 "call_insn_operand" "dS")]
7125
                   UNSPEC_GET_FCSR))
7126
   (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7127
   (clobber (reg:P RETURN_ADDR_REGNUM))]
7128
  "TARGET_HARD_FLOAT_ABI && TARGET_MIPS16"
7129
  { return MIPS_CALL ("jal", operands, 0, -1); }
7130
  [(set_attr "type" "call")
7131
   (set_attr "insn_count" "3")])
7132
 
7133
;; __builtin_mips_set_fcsr: move operand 0 into the FCSR.
7134
(define_expand "mips_set_fcsr"
7135
  [(unspec_volatile [(match_operand:SI 0 "register_operand")]
7136
                    UNSPEC_SET_FCSR)]
7137
  "TARGET_HARD_FLOAT_ABI"
7138
{
7139
  if (TARGET_MIPS16)
7140
    {
7141
      mips16_expand_set_fcsr (operands[0]);
7142
      DONE;
7143
    }
7144
})
7145
 
7146
(define_insn "*mips_set_fcsr"
7147
  [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
7148
                    UNSPEC_SET_FCSR)]
7149
  "TARGET_HARD_FLOAT"
7150
  "ctc1\t%0,$31")
7151
 
7152
;; See tls_get_tp_mips16_ for why this form is used.
7153
(define_insn "mips_set_fcsr_mips16_"
7154
  [(unspec_volatile:SI [(match_operand:P 0 "call_insn_operand" "dS")
7155
                        (reg:SI SET_FCSR_REGNUM)] UNSPEC_SET_FCSR)
7156
   (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7157
   (clobber (reg:P RETURN_ADDR_REGNUM))]
7158
  "TARGET_HARD_FLOAT_ABI && TARGET_MIPS16"
7159
  { return MIPS_CALL ("jal", operands, 0, -1); }
7160
  [(set_attr "type" "call")
7161
   (set_attr "insn_count" "3")])
7162
 
7163
;; Synchronization instructions.
7164
 
7165
(include "sync.md")
7166
 
7167
; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
7168
 
7169
(include "mips-ps-3d.md")
7170
 
7171
; The MIPS DSP Instructions.
7172
 
7173
(include "mips-dsp.md")
7174
 
7175
; The MIPS DSP REV 2 Instructions.
7176
 
7177
(include "mips-dspr2.md")
7178
 
7179
; MIPS fixed-point instructions.
7180
(include "mips-fixed.md")
7181
 
7182
; microMIPS patterns.
7183
(include "micromips.md")
7184
 
7185
; ST-Microelectronics Loongson-2E/2F-specific patterns.
7186
(include "loongson.md")
7187
 
7188
(define_c_enum "unspec" [
7189
  UNSPEC_ADDRESS_FIRST
7190
])

powered by: WebSVN 2.1.0

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