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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [mips/] [mips.md] - Blame information for rev 298

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

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

powered by: WebSVN 2.1.0

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