OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [mips/] [mips.md] - Blame information for rev 735

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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