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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [mips/] [mips.md] - Blame information for rev 820

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

Line No. Rev Author Line
1 38 julius
;;  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, 2007 Free Software Foundation, Inc.
4
;;  Contributed by   A. Lichnewsky, lich@inria.inria.fr
5
;;  Changes by       Michael Meissner, meissner@osf.org
6
;;  64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
7
;;  Brendan Eich, brendan@microunity.com.
8
 
9
;; This file is part of GCC.
10
 
11
;; GCC is free software; you can redistribute it and/or modify
12
;; it under the terms of the GNU General Public License as published by
13
;; the Free Software Foundation; either version 3, or (at your option)
14
;; any later version.
15
 
16
;; GCC is distributed in the hope that it will be useful,
17
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
;; GNU General Public License for more details.
20
 
21
;; You should have received a copy of the GNU General Public License
22
;; along with GCC; see the file COPYING3.  If not see
23
;; .
24
 
25
(define_constants
26
  [(UNSPEC_LOAD_DF_LOW           0)
27
   (UNSPEC_LOAD_DF_HIGH          1)
28
   (UNSPEC_STORE_DF_HIGH         2)
29
   (UNSPEC_GET_FNADDR            3)
30
   (UNSPEC_BLOCKAGE              4)
31
   (UNSPEC_CPRESTORE             5)
32
   (UNSPEC_EH_RECEIVER           6)
33
   (UNSPEC_EH_RETURN             7)
34
   (UNSPEC_CONSTTABLE_INT        8)
35
   (UNSPEC_CONSTTABLE_FLOAT      9)
36
   (UNSPEC_ALIGN                14)
37
   (UNSPEC_HIGH                 17)
38
   (UNSPEC_LOAD_LEFT            18)
39
   (UNSPEC_LOAD_RIGHT           19)
40
   (UNSPEC_STORE_LEFT           20)
41
   (UNSPEC_STORE_RIGHT          21)
42
   (UNSPEC_LOADGP               22)
43
   (UNSPEC_LOAD_CALL            23)
44
   (UNSPEC_LOAD_GOT             24)
45
   (UNSPEC_GP                   25)
46
   (UNSPEC_MFHILO               26)
47
   (UNSPEC_TLS_LDM              27)
48
   (UNSPEC_TLS_GET_TP           28)
49
 
50
   (UNSPEC_ADDRESS_FIRST        100)
51
 
52
   (FAKE_CALL_REGNO             79)
53
 
54
   ;; For MIPS Paired-Singled Floating Point Instructions.
55
 
56
   (UNSPEC_MOVE_TF_PS           200)
57
   (UNSPEC_C                    201)
58
 
59
   ;; MIPS64/MIPS32R2 alnv.ps
60
   (UNSPEC_ALNV_PS              202)
61
 
62
   ;; MIPS-3D instructions
63
   (UNSPEC_CABS                 203)
64
 
65
   (UNSPEC_ADDR_PS              204)
66
   (UNSPEC_CVT_PW_PS            205)
67
   (UNSPEC_CVT_PS_PW            206)
68
   (UNSPEC_MULR_PS              207)
69
   (UNSPEC_ABS_PS               208)
70
 
71
   (UNSPEC_RSQRT1               209)
72
   (UNSPEC_RSQRT2               210)
73
   (UNSPEC_RECIP1               211)
74
   (UNSPEC_RECIP2               212)
75
   (UNSPEC_SINGLE_CC            213)
76
   (UNSPEC_SCC                  214)
77
 
78
   ;; MIPS DSP ASE Revision 0.98 3/24/2005
79
   (UNSPEC_ADDQ                 300)
80
   (UNSPEC_ADDQ_S               301)
81
   (UNSPEC_SUBQ                 302)
82
   (UNSPEC_SUBQ_S               303)
83
   (UNSPEC_ADDSC                304)
84
   (UNSPEC_ADDWC                305)
85
   (UNSPEC_MODSUB               306)
86
   (UNSPEC_RADDU_W_QB           307)
87
   (UNSPEC_ABSQ_S               308)
88
   (UNSPEC_PRECRQ_QB_PH         309)
89
   (UNSPEC_PRECRQ_PH_W          310)
90
   (UNSPEC_PRECRQ_RS_PH_W       311)
91
   (UNSPEC_PRECRQU_S_QB_PH      312)
92
   (UNSPEC_PRECEQ_W_PHL         313)
93
   (UNSPEC_PRECEQ_W_PHR         314)
94
   (UNSPEC_PRECEQU_PH_QBL       315)
95
   (UNSPEC_PRECEQU_PH_QBR       316)
96
   (UNSPEC_PRECEQU_PH_QBLA      317)
97
   (UNSPEC_PRECEQU_PH_QBRA      318)
98
   (UNSPEC_PRECEU_PH_QBL        319)
99
   (UNSPEC_PRECEU_PH_QBR        320)
100
   (UNSPEC_PRECEU_PH_QBLA       321)
101
   (UNSPEC_PRECEU_PH_QBRA       322)
102
   (UNSPEC_SHLL                 323)
103
   (UNSPEC_SHLL_S               324)
104
   (UNSPEC_SHRL_QB              325)
105
   (UNSPEC_SHRA_PH              326)
106
   (UNSPEC_SHRA_R               327)
107
   (UNSPEC_MULEU_S_PH_QBL       328)
108
   (UNSPEC_MULEU_S_PH_QBR       329)
109
   (UNSPEC_MULQ_RS_PH           330)
110
   (UNSPEC_MULEQ_S_W_PHL        331)
111
   (UNSPEC_MULEQ_S_W_PHR        332)
112
   (UNSPEC_DPAU_H_QBL           333)
113
   (UNSPEC_DPAU_H_QBR           334)
114
   (UNSPEC_DPSU_H_QBL           335)
115
   (UNSPEC_DPSU_H_QBR           336)
116
   (UNSPEC_DPAQ_S_W_PH          337)
117
   (UNSPEC_DPSQ_S_W_PH          338)
118
   (UNSPEC_MULSAQ_S_W_PH        339)
119
   (UNSPEC_DPAQ_SA_L_W          340)
120
   (UNSPEC_DPSQ_SA_L_W          341)
121
   (UNSPEC_MAQ_S_W_PHL          342)
122
   (UNSPEC_MAQ_S_W_PHR          343)
123
   (UNSPEC_MAQ_SA_W_PHL         344)
124
   (UNSPEC_MAQ_SA_W_PHR         345)
125
   (UNSPEC_BITREV               346)
126
   (UNSPEC_INSV                 347)
127
   (UNSPEC_REPL_QB              348)
128
   (UNSPEC_REPL_PH              349)
129
   (UNSPEC_CMP_EQ               350)
130
   (UNSPEC_CMP_LT               351)
131
   (UNSPEC_CMP_LE               352)
132
   (UNSPEC_CMPGU_EQ_QB          353)
133
   (UNSPEC_CMPGU_LT_QB          354)
134
   (UNSPEC_CMPGU_LE_QB          355)
135
   (UNSPEC_PICK                 356)
136
   (UNSPEC_PACKRL_PH            357)
137
   (UNSPEC_EXTR_W               358)
138
   (UNSPEC_EXTR_R_W             359)
139
   (UNSPEC_EXTR_RS_W            360)
140
   (UNSPEC_EXTR_S_H             361)
141
   (UNSPEC_EXTP                 362)
142
   (UNSPEC_EXTPDP               363)
143
   (UNSPEC_SHILO                364)
144
   (UNSPEC_MTHLIP               365)
145
   (UNSPEC_WRDSP                366)
146
   (UNSPEC_RDDSP                367)
147
  ]
148
)
149
 
150
(include "predicates.md")
151
(include "constraints.md")
152
 
153
;; ....................
154
;;
155
;;      Attributes
156
;;
157
;; ....................
158
 
159
(define_attr "got" "unset,xgot_high,load"
160
  (const_string "unset"))
161
 
162
;; For jal instructions, this attribute is DIRECT when the target address
163
;; is symbolic and INDIRECT when it is a register.
164
(define_attr "jal" "unset,direct,indirect"
165
  (const_string "unset"))
166
 
167
;; This attribute is YES if the instruction is a jal macro (not a
168
;; real jal instruction).
169
;;
170
;; jal is always a macro for o32 and o64 abicalls because it includes an
171
;; instruction to restore $gp.  Direct jals are also macros for -mshared
172
;; abicalls because they first load the target address into $25.
173
(define_attr "jal_macro" "no,yes"
174
  (cond [(eq_attr "jal" "direct")
175
         (symbol_ref "TARGET_ABICALLS
176
                      && (TARGET_OLDABI || !TARGET_ABSOLUTE_ABICALLS)")
177
         (eq_attr "jal" "indirect")
178
         (symbol_ref "TARGET_ABICALLS && TARGET_OLDABI")]
179
        (const_string "no")))
180
 
181
;; Classification of each insn.
182
;; branch       conditional branch
183
;; jump         unconditional jump
184
;; call         unconditional call
185
;; load         load instruction(s)
186
;; fpload       floating point load
187
;; fpidxload    floating point indexed load
188
;; store        store instruction(s)
189
;; fpstore      floating point store
190
;; fpidxstore   floating point indexed store
191
;; prefetch     memory prefetch (register + offset)
192
;; prefetchx    memory indexed prefetch (register + register)
193
;; condmove     conditional moves
194
;; xfer         transfer to/from coprocessor
195
;; mthilo       transfer to hi/lo registers
196
;; mfhilo       transfer from hi/lo registers
197
;; const        load constant
198
;; arith        integer arithmetic and logical instructions
199
;; shift        integer shift instructions
200
;; slt          set less than instructions
201
;; clz          the clz and clo instructions
202
;; trap         trap if instructions
203
;; imul         integer multiply 2 operands
204
;; imul3        integer multiply 3 operands
205
;; imadd        integer multiply-add
206
;; idiv         integer divide
207
;; fmove        floating point register move
208
;; fadd         floating point add/subtract
209
;; fmul         floating point multiply
210
;; fmadd        floating point multiply-add
211
;; fdiv         floating point divide
212
;; frdiv        floating point reciprocal divide
213
;; frdiv1       floating point reciprocal divide step 1
214
;; frdiv2       floating point reciprocal divide step 2
215
;; fabs         floating point absolute value
216
;; fneg         floating point negation
217
;; fcmp         floating point compare
218
;; fcvt         floating point convert
219
;; fsqrt        floating point square root
220
;; frsqrt       floating point reciprocal square root
221
;; frsqrt1      floating point reciprocal square root step1
222
;; frsqrt2      floating point reciprocal square root step2
223
;; multi        multiword sequence (or user asm statements)
224
;; nop          no operation
225
(define_attr "type"
226
  "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imul3,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,multi,nop"
227
  (cond [(eq_attr "jal" "!unset") (const_string "call")
228
         (eq_attr "got" "load") (const_string "load")]
229
        (const_string "unknown")))
230
 
231
;; Main data type used by the insn
232
(define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
233
  (const_string "unknown"))
234
 
235
;; Mode for conversion types (fcvt)
236
;; I2S          integer to float single (SI/DI to SF)
237
;; I2D          integer to float double (SI/DI to DF)
238
;; S2I          float to integer (SF to SI/DI)
239
;; D2I          float to integer (DF to SI/DI)
240
;; D2S          double to float single
241
;; S2D          float single to double
242
 
243
(define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D"
244
  (const_string "unknown"))
245
 
246
;; Is this an extended instruction in mips16 mode?
247
(define_attr "extended_mips16" "no,yes"
248
  (const_string "no"))
249
 
250
;; Length of instruction in bytes.
251
(define_attr "length" ""
252
   (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
253
          ;; If a branch is outside this range, we have a choice of two
254
          ;; sequences.  For PIC, an out-of-range branch like:
255
          ;;
256
          ;;    bne     r1,r2,target
257
          ;;    dslot
258
          ;;
259
          ;; becomes the equivalent of:
260
          ;;
261
          ;;    beq     r1,r2,1f
262
          ;;    dslot
263
          ;;    la      $at,target
264
          ;;    jr      $at
265
          ;;    nop
266
          ;; 1:
267
          ;;
268
          ;; where the load address can be up to three instructions long
269
          ;; (lw, nop, addiu).
270
          ;;
271
          ;; The non-PIC case is similar except that we use a direct
272
          ;; jump instead of an la/jr pair.  Since the target of this
273
          ;; jump is an absolute 28-bit bit address (the other bits
274
          ;; coming from the address of the delay slot) this form cannot
275
          ;; cross a 256MB boundary.  We could provide the option of
276
          ;; using la/jr in this case too, but we do not do so at
277
          ;; present.
278
          ;;
279
          ;; Note that this value does not account for the delay slot
280
          ;; instruction, whose length is added separately.  If the RTL
281
          ;; pattern has no explicit delay slot, mips_adjust_insn_length
282
          ;; will add the length of the implicit nop.  The values for
283
          ;; forward and backward branches will be different as well.
284
          (eq_attr "type" "branch")
285
          (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
286
                      (le (minus (pc) (match_dup 1)) (const_int 131068)))
287
                  (const_int 4)
288
                 (ne (symbol_ref "flag_pic") (const_int 0))
289
                 (const_int 24)
290
                 ] (const_int 12))
291
 
292
          (eq_attr "got" "load")
293
          (const_int 4)
294
          (eq_attr "got" "xgot_high")
295
          (const_int 8)
296
 
297
          (eq_attr "type" "const")
298
          (symbol_ref "mips_const_insns (operands[1]) * 4")
299
          (eq_attr "type" "load,fpload")
300
          (symbol_ref "mips_fetch_insns (operands[1]) * 4")
301
          (eq_attr "type" "store,fpstore")
302
          (symbol_ref "mips_fetch_insns (operands[0]) * 4")
303
 
304
          ;; In the worst case, a call macro will take 8 instructions:
305
          ;;
306
          ;;     lui $25,%call_hi(FOO)
307
          ;;     addu $25,$25,$28
308
          ;;     lw $25,%call_lo(FOO)($25)
309
          ;;     nop
310
          ;;     jalr $25
311
          ;;     nop
312
          ;;     lw $gp,X($sp)
313
          ;;     nop
314
          (eq_attr "jal_macro" "yes")
315
          (const_int 32)
316
 
317
          (and (eq_attr "extended_mips16" "yes")
318
               (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
319
          (const_int 8)
320
 
321
          ;; Various VR4120 errata require a nop to be inserted after a macc
322
          ;; instruction.  The assembler does this for us, so account for
323
          ;; the worst-case length here.
324
          (and (eq_attr "type" "imadd")
325
               (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
326
          (const_int 8)
327
 
328
          ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
329
          ;; the result of the second one is missed.  The assembler should work
330
          ;; around this by inserting a nop after the first dmult.
331
          (and (eq_attr "type" "imul,imul3")
332
               (and (eq_attr "mode" "DI")
333
                    (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
334
          (const_int 8)
335
 
336
          (eq_attr "type" "idiv")
337
          (symbol_ref "mips_idiv_insns () * 4")
338
          ] (const_int 4)))
339
 
340
;; Attribute describing the processor.  This attribute must match exactly
341
;; with the processor_type enumeration in mips.h.
342
(define_attr "cpu"
343
  "r3000,4kc,4kp,5kc,5kf,20kc,24k,24kx,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000"
344
  (const (symbol_ref "mips_tune")))
345
 
346
;; The type of hardware hazard associated with this instruction.
347
;; DELAY means that the next instruction cannot read the result
348
;; of this one.  HILO means that the next two instructions cannot
349
;; write to HI or LO.
350
(define_attr "hazard" "none,delay,hilo"
351
  (cond [(and (eq_attr "type" "load,fpload,fpidxload")
352
              (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
353
         (const_string "delay")
354
 
355
         (and (eq_attr "type" "xfer")
356
              (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
357
         (const_string "delay")
358
 
359
         (and (eq_attr "type" "fcmp")
360
              (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
361
         (const_string "delay")
362
 
363
         ;; The r4000 multiplication patterns include an mflo instruction.
364
         (and (eq_attr "type" "imul")
365
              (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
366
         (const_string "hilo")
367
 
368
         (and (eq_attr "type" "mfhilo")
369
              (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
370
         (const_string "hilo")]
371
        (const_string "none")))
372
 
373
;; Is it a single instruction?
374
(define_attr "single_insn" "no,yes"
375
  (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
376
 
377
;; Can the instruction be put into a delay slot?
378
(define_attr "can_delay" "no,yes"
379
  (if_then_else (and (eq_attr "type" "!branch,call,jump")
380
                     (and (eq_attr "hazard" "none")
381
                          (eq_attr "single_insn" "yes")))
382
                (const_string "yes")
383
                (const_string "no")))
384
 
385
;; Attribute defining whether or not we can use the branch-likely instructions
386
(define_attr "branch_likely" "no,yes"
387
  (const
388
   (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
389
                 (const_string "yes")
390
                 (const_string "no"))))
391
 
392
;; True if an instruction might assign to hi or lo when reloaded.
393
;; This is used by the TUNE_MACC_CHAINS code.
394
(define_attr "may_clobber_hilo" "no,yes"
395
  (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthilo")
396
                (const_string "yes")
397
                (const_string "no")))
398
 
399
;; Describe a user's asm statement.
400
(define_asm_attributes
401
  [(set_attr "type" "multi")
402
   (set_attr "can_delay" "no")])
403
 
404
;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
405
;; from the same template.
406
(define_mode_macro GPR [SI (DI "TARGET_64BIT")])
407
 
408
;; This mode macro allows :P to be used for patterns that operate on
409
;; pointer-sized quantities.  Exactly one of the two alternatives will match.
410
(define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
411
 
412
;; This mode macro allows :MOVECC to be used anywhere that a
413
;; conditional-move-type condition is needed.
414
(define_mode_macro MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
415
 
416
;; This mode macro allows the QI and HI extension patterns to be defined from
417
;; the same template.
418
(define_mode_macro SHORT [QI HI])
419
 
420
;; This mode macro allows :ANYF to be used wherever a scalar or vector
421
;; floating-point mode is allowed.
422
(define_mode_macro ANYF [(SF "TARGET_HARD_FLOAT")
423
                         (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
424
                         (V2SF "TARGET_PAIRED_SINGLE_FLOAT")])
425
 
426
;; Like ANYF, but only applies to scalar modes.
427
(define_mode_macro SCALARF [(SF "TARGET_HARD_FLOAT")
428
                            (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
429
 
430
;; In GPR templates, a string like "subu" will expand to "subu" in the
431
;; 32-bit version and "dsubu" in the 64-bit version.
432
(define_mode_attr d [(SI "") (DI "d")])
433
 
434
;; This attribute gives the length suffix for a sign- or zero-extension
435
;; instruction.
436
(define_mode_attr size [(QI "b") (HI "h")])
437
 
438
;; This attributes gives the mode mask of a SHORT.
439
(define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
440
 
441
;; Mode attributes for GPR loads and stores.
442
(define_mode_attr load [(SI "lw") (DI "ld")])
443
(define_mode_attr store [(SI "sw") (DI "sd")])
444
 
445
;; Similarly for MIPS IV indexed FPR loads and stores.
446
(define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
447
(define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
448
 
449
;; The unextended ranges of the MIPS16 addiu and daddiu instructions
450
;; are different.  Some forms of unextended addiu have an 8-bit immediate
451
;; field but the equivalent daddiu has only a 5-bit field.
452
(define_mode_attr si8_di5 [(SI "8") (DI "5")])
453
 
454
;; This attribute gives the best constraint to use for registers of
455
;; a given mode.
456
(define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
457
 
458
;; This attribute gives the format suffix for floating-point operations.
459
(define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
460
 
461
;; This attribute gives the upper-case mode name for one unit of a
462
;; floating-point mode.
463
(define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
464
 
465
;; This attribute works around the early SB-1 rev2 core "F2" erratum:
466
;;
467
;; In certain cases, div.s and div.ps may have a rounding error
468
;; and/or wrong inexact flag.
469
;;
470
;; Therefore, we only allow div.s if not working around SB-1 rev2
471
;; errata or if a slight loss of precision is OK.
472
(define_mode_attr divide_condition
473
  [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")
474
   (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")])
475
 
476
; This attribute gives the condition for which sqrt instructions exist.
477
(define_mode_attr sqrt_condition
478
  [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")])
479
 
480
; This attribute gives the condition for which recip and rsqrt instructions
481
; exist.
482
(define_mode_attr recip_condition
483
  [(SF "ISA_HAS_FP4") (DF "ISA_HAS_FP4") (V2SF "TARGET_SB1")])
484
 
485
;; This code macro allows all branch instructions to be generated from
486
;; a single define_expand template.
487
(define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
488
                             eq ne gt ge lt le gtu geu ltu leu])
489
 
490
;; This code macro allows signed and unsigned widening multiplications
491
;; to use the same template.
492
(define_code_macro any_extend [sign_extend zero_extend])
493
 
494
;; This code macro allows the three shift instructions to be generated
495
;; from the same template.
496
(define_code_macro any_shift [ashift ashiftrt lshiftrt])
497
 
498
;; This code macro allows all native floating-point comparisons to be
499
;; generated from the same template.
500
(define_code_macro fcond [unordered uneq unlt unle eq lt le])
501
 
502
;; This code macro is used for comparisons that can be implemented
503
;; by swapping the operands.
504
(define_code_macro swapped_fcond [ge gt unge ungt])
505
 
506
;;  expands to an empty string when doing a signed operation and
507
;; "u" when doing an unsigned operation.
508
(define_code_attr u [(sign_extend "") (zero_extend "u")])
509
 
510
;;  is like , but the signed form expands to "s" rather than "".
511
(define_code_attr su [(sign_extend "s") (zero_extend "u")])
512
 
513
;;  expands to the name of the optab for a particular code.
514
(define_code_attr optab [(ashift "ashl")
515
                         (ashiftrt "ashr")
516
                         (lshiftrt "lshr")])
517
 
518
;;  expands to the name of the insn that implements a particular code.
519
(define_code_attr insn [(ashift "sll")
520
                        (ashiftrt "sra")
521
                        (lshiftrt "srl")])
522
 
523
;;  is the c.cond.fmt condition associated with a particular code.
524
(define_code_attr fcond [(unordered "un")
525
                         (uneq "ueq")
526
                         (unlt "ult")
527
                         (unle "ule")
528
                         (eq "eq")
529
                         (lt "lt")
530
                         (le "le")])
531
 
532
;; Similar, but for swapped conditions.
533
(define_code_attr swapped_fcond [(ge "le")
534
                                 (gt "lt")
535
                                 (unge "ule")
536
                                 (ungt "ult")])
537
 
538
;; .........................
539
;;
540
;;      Branch, call and jump delay slots
541
;;
542
;; .........................
543
 
544
(define_delay (and (eq_attr "type" "branch")
545
                   (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
546
  [(eq_attr "can_delay" "yes")
547
   (nil)
548
   (and (eq_attr "branch_likely" "yes")
549
        (eq_attr "can_delay" "yes"))])
550
 
551
(define_delay (eq_attr "type" "jump")
552
  [(eq_attr "can_delay" "yes")
553
   (nil)
554
   (nil)])
555
 
556
(define_delay (and (eq_attr "type" "call")
557
                   (eq_attr "jal_macro" "no"))
558
  [(eq_attr "can_delay" "yes")
559
   (nil)
560
   (nil)])
561
 
562
;; Pipeline descriptions.
563
;;
564
;; generic.md provides a fallback for processors without a specific
565
;; pipeline description.  It is derived from the old define_function_unit
566
;; version and uses the "alu" and "imuldiv" units declared below.
567
;;
568
;; Some of the processor-specific files are also derived from old
569
;; define_function_unit descriptions and simply override the parts of
570
;; generic.md that don't apply.  The other processor-specific files
571
;; are self-contained.
572
(define_automaton "alu,imuldiv")
573
 
574
(define_cpu_unit "alu" "alu")
575
(define_cpu_unit "imuldiv" "imuldiv")
576
 
577
(include "4k.md")
578
(include "5k.md")
579
(include "24k.md")
580
(include "3000.md")
581
(include "4000.md")
582
(include "4100.md")
583
(include "4130.md")
584
(include "4300.md")
585
(include "4600.md")
586
(include "5000.md")
587
(include "5400.md")
588
(include "5500.md")
589
(include "6000.md")
590
(include "7000.md")
591
(include "9000.md")
592
(include "sb1.md")
593
(include "sr71k.md")
594
(include "generic.md")
595
 
596
;;
597
;;  ....................
598
;;
599
;;      CONDITIONAL TRAPS
600
;;
601
;;  ....................
602
;;
603
 
604
(define_insn "trap"
605
  [(trap_if (const_int 1) (const_int 0))]
606
  ""
607
{
608
  if (ISA_HAS_COND_TRAP)
609
    return "teq\t$0,$0";
610
  else if (TARGET_MIPS16)
611
    return "break 0";
612
  else
613
    return "break";
614
}
615
  [(set_attr "type" "trap")])
616
 
617
(define_expand "conditional_trap"
618
  [(trap_if (match_operator 0 "comparison_operator"
619
                            [(match_dup 2) (match_dup 3)])
620
            (match_operand 1 "const_int_operand"))]
621
  "ISA_HAS_COND_TRAP"
622
{
623
  if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
624
      && operands[1] == const0_rtx)
625
    {
626
      mips_gen_conditional_trap (operands);
627
      DONE;
628
    }
629
  else
630
    FAIL;
631
})
632
 
633
(define_insn "*conditional_trap"
634
  [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
635
                                [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
636
                                 (match_operand:GPR 2 "arith_operand" "dI")])
637
            (const_int 0))]
638
  "ISA_HAS_COND_TRAP"
639
  "t%C0\t%z1,%2"
640
  [(set_attr "type" "trap")])
641
 
642
;;
643
;;  ....................
644
;;
645
;;      ADDITION
646
;;
647
;;  ....................
648
;;
649
 
650
(define_insn "add3"
651
  [(set (match_operand:ANYF 0 "register_operand" "=f")
652
        (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
653
                   (match_operand:ANYF 2 "register_operand" "f")))]
654
  ""
655
  "add.\t%0,%1,%2"
656
  [(set_attr "type" "fadd")
657
   (set_attr "mode" "")])
658
 
659
(define_expand "add3"
660
  [(set (match_operand:GPR 0 "register_operand")
661
        (plus:GPR (match_operand:GPR 1 "register_operand")
662
                  (match_operand:GPR 2 "arith_operand")))]
663
  "")
664
 
665
(define_insn "*add3"
666
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
667
        (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
668
                  (match_operand:GPR 2 "arith_operand" "d,Q")))]
669
  "!TARGET_MIPS16"
670
  "@
671
    addu\t%0,%1,%2
672
    addiu\t%0,%1,%2"
673
  [(set_attr "type" "arith")
674
   (set_attr "mode" "")])
675
 
676
;; We need to recognize MIPS16 stack pointer additions explicitly, since
677
;; we don't have a constraint for $sp.  These insns will be generated by
678
;; the save_restore_insns functions.
679
 
680
(define_insn "*add3_sp1"
681
  [(set (reg:GPR 29)
682
        (plus:GPR (reg:GPR 29)
683
                  (match_operand:GPR 0 "const_arith_operand" "")))]
684
  "TARGET_MIPS16"
685
  "addiu\t%$,%$,%0"
686
  [(set_attr "type" "arith")
687
   (set_attr "mode" "")
688
   (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
689
                                      (const_int 4)
690
                                      (const_int 8)))])
691
 
692
(define_insn "*add3_sp2"
693
  [(set (match_operand:GPR 0 "register_operand" "=d")
694
        (plus:GPR (reg:GPR 29)
695
                  (match_operand:GPR 1 "const_arith_operand" "")))]
696
  "TARGET_MIPS16"
697
  "addiu\t%0,%$,%1"
698
  [(set_attr "type" "arith")
699
   (set_attr "mode" "")
700
   (set (attr "length") (if_then_else (match_operand 1 "m16_uimm_4")
701
                                      (const_int 4)
702
                                      (const_int 8)))])
703
 
704
(define_insn "*add3_mips16"
705
  [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
706
        (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
707
                  (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
708
  "TARGET_MIPS16"
709
  "@
710
    addiu\t%0,%2
711
    addiu\t%0,%1,%2
712
    addu\t%0,%1,%2"
713
  [(set_attr "type" "arith")
714
   (set_attr "mode" "")
715
   (set_attr_alternative "length"
716
                [(if_then_else (match_operand 2 "m16_simm_1")
717
                               (const_int 4)
718
                               (const_int 8))
719
                 (if_then_else (match_operand 2 "m16_simm4_1")
720
                               (const_int 4)
721
                               (const_int 8))
722
                 (const_int 4)])])
723
 
724
 
725
;; On the mips16, we can sometimes split an add of a constant which is
726
;; a 4 byte instruction into two adds which are both 2 byte
727
;; instructions.  There are two cases: one where we are adding a
728
;; constant plus a register to another register, and one where we are
729
;; simply adding a constant to a register.
730
 
731
(define_split
732
  [(set (match_operand:SI 0 "register_operand")
733
        (plus:SI (match_dup 0)
734
                 (match_operand:SI 1 "const_int_operand")))]
735
  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
736
   && REG_P (operands[0])
737
   && M16_REG_P (REGNO (operands[0]))
738
   && GET_CODE (operands[1]) == CONST_INT
739
   && ((INTVAL (operands[1]) > 0x7f
740
        && INTVAL (operands[1]) <= 0x7f + 0x7f)
741
       || (INTVAL (operands[1]) < - 0x80
742
           && INTVAL (operands[1]) >= - 0x80 - 0x80))"
743
  [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
744
   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
745
{
746
  HOST_WIDE_INT val = INTVAL (operands[1]);
747
 
748
  if (val >= 0)
749
    {
750
      operands[1] = GEN_INT (0x7f);
751
      operands[2] = GEN_INT (val - 0x7f);
752
    }
753
  else
754
    {
755
      operands[1] = GEN_INT (- 0x80);
756
      operands[2] = GEN_INT (val + 0x80);
757
    }
758
})
759
 
760
(define_split
761
  [(set (match_operand:SI 0 "register_operand")
762
        (plus:SI (match_operand:SI 1 "register_operand")
763
                 (match_operand:SI 2 "const_int_operand")))]
764
  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
765
   && REG_P (operands[0])
766
   && M16_REG_P (REGNO (operands[0]))
767
   && REG_P (operands[1])
768
   && M16_REG_P (REGNO (operands[1]))
769
   && REGNO (operands[0]) != REGNO (operands[1])
770
   && GET_CODE (operands[2]) == CONST_INT
771
   && ((INTVAL (operands[2]) > 0x7
772
        && INTVAL (operands[2]) <= 0x7 + 0x7f)
773
       || (INTVAL (operands[2]) < - 0x8
774
           && INTVAL (operands[2]) >= - 0x8 - 0x80))"
775
  [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
776
   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
777
{
778
  HOST_WIDE_INT val = INTVAL (operands[2]);
779
 
780
  if (val >= 0)
781
    {
782
      operands[2] = GEN_INT (0x7);
783
      operands[3] = GEN_INT (val - 0x7);
784
    }
785
  else
786
    {
787
      operands[2] = GEN_INT (- 0x8);
788
      operands[3] = GEN_INT (val + 0x8);
789
    }
790
})
791
 
792
(define_split
793
  [(set (match_operand:DI 0 "register_operand")
794
        (plus:DI (match_dup 0)
795
                 (match_operand:DI 1 "const_int_operand")))]
796
  "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
797
   && REG_P (operands[0])
798
   && M16_REG_P (REGNO (operands[0]))
799
   && GET_CODE (operands[1]) == CONST_INT
800
   && ((INTVAL (operands[1]) > 0xf
801
        && INTVAL (operands[1]) <= 0xf + 0xf)
802
       || (INTVAL (operands[1]) < - 0x10
803
           && INTVAL (operands[1]) >= - 0x10 - 0x10))"
804
  [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
805
   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
806
{
807
  HOST_WIDE_INT val = INTVAL (operands[1]);
808
 
809
  if (val >= 0)
810
    {
811
      operands[1] = GEN_INT (0xf);
812
      operands[2] = GEN_INT (val - 0xf);
813
    }
814
  else
815
    {
816
      operands[1] = GEN_INT (- 0x10);
817
      operands[2] = GEN_INT (val + 0x10);
818
    }
819
})
820
 
821
(define_split
822
  [(set (match_operand:DI 0 "register_operand")
823
        (plus:DI (match_operand:DI 1 "register_operand")
824
                 (match_operand:DI 2 "const_int_operand")))]
825
  "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
826
   && REG_P (operands[0])
827
   && M16_REG_P (REGNO (operands[0]))
828
   && REG_P (operands[1])
829
   && M16_REG_P (REGNO (operands[1]))
830
   && REGNO (operands[0]) != REGNO (operands[1])
831
   && GET_CODE (operands[2]) == CONST_INT
832
   && ((INTVAL (operands[2]) > 0x7
833
        && INTVAL (operands[2]) <= 0x7 + 0xf)
834
       || (INTVAL (operands[2]) < - 0x8
835
           && INTVAL (operands[2]) >= - 0x8 - 0x10))"
836
  [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
837
   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
838
{
839
  HOST_WIDE_INT val = INTVAL (operands[2]);
840
 
841
  if (val >= 0)
842
    {
843
      operands[2] = GEN_INT (0x7);
844
      operands[3] = GEN_INT (val - 0x7);
845
    }
846
  else
847
    {
848
      operands[2] = GEN_INT (- 0x8);
849
      operands[3] = GEN_INT (val + 0x8);
850
    }
851
})
852
 
853
(define_insn "*addsi3_extended"
854
  [(set (match_operand:DI 0 "register_operand" "=d,d")
855
        (sign_extend:DI
856
             (plus:SI (match_operand:SI 1 "register_operand" "d,d")
857
                      (match_operand:SI 2 "arith_operand" "d,Q"))))]
858
  "TARGET_64BIT && !TARGET_MIPS16"
859
  "@
860
    addu\t%0,%1,%2
861
    addiu\t%0,%1,%2"
862
  [(set_attr "type" "arith")
863
   (set_attr "mode" "SI")])
864
 
865
;; Split this insn so that the addiu splitters can have a crack at it.
866
;; Use a conservative length estimate until the split.
867
(define_insn_and_split "*addsi3_extended_mips16"
868
  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
869
        (sign_extend:DI
870
             (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
871
                      (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
872
  "TARGET_64BIT && TARGET_MIPS16"
873
  "#"
874
  "&& reload_completed"
875
  [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
876
  { operands[3] = gen_lowpart (SImode, operands[0]); }
877
  [(set_attr "type" "arith")
878
   (set_attr "mode" "SI")
879
   (set_attr "extended_mips16" "yes")])
880
 
881
;;
882
;;  ....................
883
;;
884
;;      SUBTRACTION
885
;;
886
;;  ....................
887
;;
888
 
889
(define_insn "sub3"
890
  [(set (match_operand:ANYF 0 "register_operand" "=f")
891
        (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
892
                    (match_operand:ANYF 2 "register_operand" "f")))]
893
  ""
894
  "sub.\t%0,%1,%2"
895
  [(set_attr "type" "fadd")
896
   (set_attr "mode" "")])
897
 
898
(define_insn "sub3"
899
  [(set (match_operand:GPR 0 "register_operand" "=d")
900
        (minus:GPR (match_operand:GPR 1 "register_operand" "d")
901
                   (match_operand:GPR 2 "register_operand" "d")))]
902
  ""
903
  "subu\t%0,%1,%2"
904
  [(set_attr "type" "arith")
905
   (set_attr "mode" "")])
906
 
907
(define_insn "*subsi3_extended"
908
  [(set (match_operand:DI 0 "register_operand" "=d")
909
        (sign_extend:DI
910
            (minus:SI (match_operand:SI 1 "register_operand" "d")
911
                      (match_operand:SI 2 "register_operand" "d"))))]
912
  "TARGET_64BIT"
913
  "subu\t%0,%1,%2"
914
  [(set_attr "type" "arith")
915
   (set_attr "mode" "DI")])
916
 
917
;;
918
;;  ....................
919
;;
920
;;      MULTIPLICATION
921
;;
922
;;  ....................
923
;;
924
 
925
(define_expand "mul3"
926
  [(set (match_operand:SCALARF 0 "register_operand")
927
        (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
928
                      (match_operand:SCALARF 2 "register_operand")))]
929
  ""
930
  "")
931
 
932
(define_insn "*mul3"
933
  [(set (match_operand:SCALARF 0 "register_operand" "=f")
934
        (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
935
                      (match_operand:SCALARF 2 "register_operand" "f")))]
936
  "!TARGET_4300_MUL_FIX"
937
  "mul.\t%0,%1,%2"
938
  [(set_attr "type" "fmul")
939
   (set_attr "mode" "")])
940
 
941
;; Early VR4300 silicon has a CPU bug where multiplies with certain
942
;; operands may corrupt immediately following multiplies. This is a
943
;; simple fix to insert NOPs.
944
 
945
(define_insn "*mul3_r4300"
946
  [(set (match_operand:SCALARF 0 "register_operand" "=f")
947
        (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
948
                      (match_operand:SCALARF 2 "register_operand" "f")))]
949
  "TARGET_4300_MUL_FIX"
950
  "mul.\t%0,%1,%2\;nop"
951
  [(set_attr "type" "fmul")
952
   (set_attr "mode" "")
953
   (set_attr "length" "8")])
954
 
955
(define_insn "mulv2sf3"
956
  [(set (match_operand:V2SF 0 "register_operand" "=f")
957
        (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
958
                   (match_operand:V2SF 2 "register_operand" "f")))]
959
  "TARGET_PAIRED_SINGLE_FLOAT"
960
  "mul.ps\t%0,%1,%2"
961
  [(set_attr "type" "fmul")
962
   (set_attr "mode" "SF")])
963
 
964
;; The original R4000 has a cpu bug.  If a double-word or a variable
965
;; shift executes while an integer multiplication is in progress, the
966
;; shift may give an incorrect result.  Avoid this by keeping the mflo
967
;; with the mult on the R4000.
968
;;
969
;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
970
;; (also valid for MIPS R4000MC processors):
971
;;
972
;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
973
;;      this errata description.
974
;;      The following code sequence causes the R4000 to incorrectly
975
;;      execute the Double Shift Right Arithmetic 32 (dsra32)
976
;;      instruction.  If the dsra32 instruction is executed during an
977
;;      integer multiply, the dsra32 will only shift by the amount in
978
;;      specified in the instruction rather than the amount plus 32
979
;;      bits.
980
;;      instruction 1:          mult    rs,rt           integer multiply
981
;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
982
;;                                                      right arithmetic + 32
983
;;      Workaround: A dsra32 instruction placed after an integer
984
;;      multiply should not be one of the 11 instructions after the
985
;;      multiply instruction."
986
;;
987
;; and:
988
;;
989
;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
990
;;      the following description.
991
;;      All extended shifts (shift by n+32) and variable shifts (32 and
992
;;      64-bit versions) may produce incorrect results under the
993
;;      following conditions:
994
;;      1) An integer multiply is currently executing
995
;;      2) These types of shift instructions are executed immediately
996
;;         following an integer divide instruction.
997
;;      Workaround:
998
;;      1) Make sure no integer multiply is running wihen these
999
;;         instruction are executed.  If this cannot be predicted at
1000
;;         compile time, then insert a "mfhi" to R0 instruction
1001
;;         immediately after the integer multiply instruction.  This
1002
;;         will cause the integer multiply to complete before the shift
1003
;;         is executed.
1004
;;      2) Separate integer divide and these two classes of shift
1005
;;         instructions by another instruction or a noop."
1006
;;
1007
;; These processors have PRId values of 0x00004220 and 0x00004300,
1008
;; respectively.
1009
 
1010
(define_expand "mul3"
1011
  [(set (match_operand:GPR 0 "register_operand")
1012
        (mult:GPR (match_operand:GPR 1 "register_operand")
1013
                  (match_operand:GPR 2 "register_operand")))]
1014
  ""
1015
{
1016
  if (GENERATE_MULT3_)
1017
    emit_insn (gen_mul3_mult3 (operands[0], operands[1], operands[2]));
1018
  else if (!TARGET_FIX_R4000)
1019
    emit_insn (gen_mul3_internal (operands[0], operands[1],
1020
                                        operands[2]));
1021
  else
1022
    emit_insn (gen_mul3_r4000 (operands[0], operands[1], operands[2]));
1023
  DONE;
1024
})
1025
 
1026
(define_insn "mulsi3_mult3"
1027
  [(set (match_operand:SI 0 "register_operand" "=d,l")
1028
        (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1029
                 (match_operand:SI 2 "register_operand" "d,d")))
1030
   (clobber (match_scratch:SI 3 "=h,h"))
1031
   (clobber (match_scratch:SI 4 "=l,X"))]
1032
  "GENERATE_MULT3_SI"
1033
{
1034
  if (which_alternative == 1)
1035
    return "mult\t%1,%2";
1036
  if (TARGET_MAD
1037
      || TARGET_MIPS5400
1038
      || TARGET_MIPS5500
1039
      || TARGET_MIPS7000
1040
      || TARGET_MIPS9000
1041
      || ISA_MIPS32
1042
      || ISA_MIPS32R2
1043
      || ISA_MIPS64)
1044
    return "mul\t%0,%1,%2";
1045
  return "mult\t%0,%1,%2";
1046
}
1047
  [(set_attr "type" "imul3,imul")
1048
   (set_attr "mode" "SI")])
1049
 
1050
(define_insn "muldi3_mult3"
1051
  [(set (match_operand:DI 0 "register_operand" "=d")
1052
        (mult:DI (match_operand:DI 1 "register_operand" "d")
1053
                 (match_operand:DI 2 "register_operand" "d")))
1054
   (clobber (match_scratch:DI 3 "=h"))
1055
   (clobber (match_scratch:DI 4 "=l"))]
1056
  "TARGET_64BIT && GENERATE_MULT3_DI"
1057
  "dmult\t%0,%1,%2"
1058
  [(set_attr "type" "imul3")
1059
   (set_attr "mode" "DI")])
1060
 
1061
;; If a register gets allocated to LO, and we spill to memory, the reload
1062
;; will include a move from LO to a GPR.  Merge it into the multiplication
1063
;; if it can set the GPR directly.
1064
;;
1065
;; Operand 0: LO
1066
;; Operand 1: GPR (1st multiplication operand)
1067
;; Operand 2: GPR (2nd multiplication operand)
1068
;; Operand 3: HI
1069
;; Operand 4: GPR (destination)
1070
(define_peephole2
1071
  [(parallel
1072
       [(set (match_operand:SI 0 "register_operand")
1073
             (mult:SI (match_operand:SI 1 "register_operand")
1074
                      (match_operand:SI 2 "register_operand")))
1075
        (clobber (match_operand:SI 3 "register_operand"))
1076
        (clobber (scratch:SI))])
1077
   (set (match_operand:SI 4 "register_operand")
1078
        (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1079
  "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
1080
  [(parallel
1081
       [(set (match_dup 4)
1082
             (mult:SI (match_dup 1)
1083
                      (match_dup 2)))
1084
        (clobber (match_dup 3))
1085
        (clobber (match_dup 0))])])
1086
 
1087
(define_insn "mul3_internal"
1088
  [(set (match_operand:GPR 0 "register_operand" "=l")
1089
        (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1090
                  (match_operand:GPR 2 "register_operand" "d")))
1091
   (clobber (match_scratch:GPR 3 "=h"))]
1092
  "!TARGET_FIX_R4000"
1093
  "mult\t%1,%2"
1094
  [(set_attr "type" "imul")
1095
   (set_attr "mode" "")])
1096
 
1097
(define_insn "mul3_r4000"
1098
  [(set (match_operand:GPR 0 "register_operand" "=d")
1099
        (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1100
                  (match_operand:GPR 2 "register_operand" "d")))
1101
   (clobber (match_scratch:GPR 3 "=h"))
1102
   (clobber (match_scratch:GPR 4 "=l"))]
1103
  "TARGET_FIX_R4000"
1104
  "mult\t%1,%2\;mflo\t%0"
1105
  [(set_attr "type" "imul")
1106
   (set_attr "mode" "")
1107
   (set_attr "length" "8")])
1108
 
1109
;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1110
;; of "mult; mflo".  They have the same latency, but the first form gives
1111
;; us an extra cycle to compute the operands.
1112
 
1113
;; Operand 0: LO
1114
;; Operand 1: GPR (1st multiplication operand)
1115
;; Operand 2: GPR (2nd multiplication operand)
1116
;; Operand 3: HI
1117
;; Operand 4: GPR (destination)
1118
(define_peephole2
1119
  [(parallel
1120
       [(set (match_operand:SI 0 "register_operand")
1121
             (mult:SI (match_operand:SI 1 "register_operand")
1122
                      (match_operand:SI 2 "register_operand")))
1123
        (clobber (match_operand:SI 3 "register_operand"))])
1124
   (set (match_operand:SI 4 "register_operand")
1125
        (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1126
  "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1127
  [(set (match_dup 0)
1128
        (const_int 0))
1129
   (parallel
1130
       [(set (match_dup 0)
1131
             (plus:SI (mult:SI (match_dup 1)
1132
                               (match_dup 2))
1133
                      (match_dup 0)))
1134
        (set (match_dup 4)
1135
             (plus:SI (mult:SI (match_dup 1)
1136
                               (match_dup 2))
1137
                      (match_dup 0)))
1138
        (clobber (match_dup 3))])])
1139
 
1140
;; Multiply-accumulate patterns
1141
 
1142
;; For processors that can copy the output to a general register:
1143
;;
1144
;; The all-d alternative is needed because the combiner will find this
1145
;; pattern and then register alloc/reload will move registers around to
1146
;; make them fit, and we don't want to trigger unnecessary loads to LO.
1147
;;
1148
;; The last alternative should be made slightly less desirable, but adding
1149
;; "?" to the constraint is too strong, and causes values to be loaded into
1150
;; LO even when that's more costly.  For now, using "*d" mostly does the
1151
;; trick.
1152
(define_insn "*mul_acc_si"
1153
  [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1154
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1155
                          (match_operand:SI 2 "register_operand" "d,d,d"))
1156
                 (match_operand:SI 3 "register_operand" "0,l,*d")))
1157
   (clobber (match_scratch:SI 4 "=h,h,h"))
1158
   (clobber (match_scratch:SI 5 "=X,3,l"))
1159
   (clobber (match_scratch:SI 6 "=X,X,&d"))]
1160
  "(TARGET_MIPS3900
1161
   || ISA_HAS_MADD_MSUB)
1162
   && !TARGET_MIPS16"
1163
{
1164
  static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1165
  if (which_alternative == 2)
1166
    return "#";
1167
  if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1168
    return "#";
1169
  return madd[which_alternative];
1170
}
1171
  [(set_attr "type"     "imadd,imadd,multi")
1172
   (set_attr "mode"     "SI")
1173
   (set_attr "length"   "4,4,8")])
1174
 
1175
;; Split the above insn if we failed to get LO allocated.
1176
(define_split
1177
  [(set (match_operand:SI 0 "register_operand")
1178
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1179
                          (match_operand:SI 2 "register_operand"))
1180
                 (match_operand:SI 3 "register_operand")))
1181
   (clobber (match_scratch:SI 4))
1182
   (clobber (match_scratch:SI 5))
1183
   (clobber (match_scratch:SI 6))]
1184
  "reload_completed && !TARGET_DEBUG_D_MODE
1185
   && GP_REG_P (true_regnum (operands[0]))
1186
   && GP_REG_P (true_regnum (operands[3]))"
1187
  [(parallel [(set (match_dup 6)
1188
                   (mult:SI (match_dup 1) (match_dup 2)))
1189
              (clobber (match_dup 4))
1190
              (clobber (match_dup 5))])
1191
   (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1192
  "")
1193
 
1194
;; Splitter to copy result of MADD to a general register
1195
(define_split
1196
  [(set (match_operand:SI                   0 "register_operand")
1197
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1198
                          (match_operand:SI 2 "register_operand"))
1199
                 (match_operand:SI          3 "register_operand")))
1200
   (clobber (match_scratch:SI               4))
1201
   (clobber (match_scratch:SI               5))
1202
   (clobber (match_scratch:SI               6))]
1203
  "reload_completed && !TARGET_DEBUG_D_MODE
1204
   && GP_REG_P (true_regnum (operands[0]))
1205
   && true_regnum (operands[3]) == LO_REGNUM"
1206
  [(parallel [(set (match_dup 3)
1207
                   (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1208
                            (match_dup 3)))
1209
              (clobber (match_dup 4))
1210
              (clobber (match_dup 5))
1211
              (clobber (match_dup 6))])
1212
   (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1213
  "")
1214
 
1215
(define_insn "*macc"
1216
  [(set (match_operand:SI 0 "register_operand" "=l,d")
1217
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1218
                          (match_operand:SI 2 "register_operand" "d,d"))
1219
                 (match_operand:SI 3 "register_operand" "0,l")))
1220
   (clobber (match_scratch:SI 4 "=h,h"))
1221
   (clobber (match_scratch:SI 5 "=X,3"))]
1222
  "ISA_HAS_MACC"
1223
{
1224
  if (which_alternative == 1)
1225
    return "macc\t%0,%1,%2";
1226
  else if (TARGET_MIPS5500)
1227
    return "madd\t%1,%2";
1228
  else
1229
    /* The VR4130 assumes that there is a two-cycle latency between a macc
1230
       that "writes" to $0 and an instruction that reads from it.  We avoid
1231
       this by assigning to $1 instead.  */
1232
    return "%[macc\t%@,%1,%2%]";
1233
}
1234
  [(set_attr "type" "imadd")
1235
   (set_attr "mode" "SI")])
1236
 
1237
(define_insn "*msac"
1238
  [(set (match_operand:SI 0 "register_operand" "=l,d")
1239
        (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1240
                  (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1241
                           (match_operand:SI 3 "register_operand" "d,d"))))
1242
   (clobber (match_scratch:SI 4 "=h,h"))
1243
   (clobber (match_scratch:SI 5 "=X,1"))]
1244
  "ISA_HAS_MSAC"
1245
{
1246
  if (which_alternative == 1)
1247
    return "msac\t%0,%2,%3";
1248
  else if (TARGET_MIPS5500)
1249
    return "msub\t%2,%3";
1250
  else
1251
    return "msac\t$0,%2,%3";
1252
}
1253
  [(set_attr "type"     "imadd")
1254
   (set_attr "mode"     "SI")])
1255
 
1256
;; An msac-like instruction implemented using negation and a macc.
1257
(define_insn_and_split "*msac_using_macc"
1258
  [(set (match_operand:SI 0 "register_operand" "=l,d")
1259
        (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1260
                  (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1261
                           (match_operand:SI 3 "register_operand" "d,d"))))
1262
   (clobber (match_scratch:SI 4 "=h,h"))
1263
   (clobber (match_scratch:SI 5 "=X,1"))
1264
   (clobber (match_scratch:SI 6 "=d,d"))]
1265
  "ISA_HAS_MACC && !ISA_HAS_MSAC"
1266
  "#"
1267
  "&& reload_completed"
1268
  [(set (match_dup 6)
1269
        (neg:SI (match_dup 3)))
1270
   (parallel
1271
       [(set (match_dup 0)
1272
             (plus:SI (mult:SI (match_dup 2)
1273
                               (match_dup 6))
1274
                      (match_dup 1)))
1275
        (clobber (match_dup 4))
1276
        (clobber (match_dup 5))])]
1277
  ""
1278
  [(set_attr "type"     "imadd")
1279
   (set_attr "length"   "8")])
1280
 
1281
;; Patterns generated by the define_peephole2 below.
1282
 
1283
(define_insn "*macc2"
1284
  [(set (match_operand:SI 0 "register_operand" "=l")
1285
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1286
                          (match_operand:SI 2 "register_operand" "d"))
1287
                 (match_dup 0)))
1288
   (set (match_operand:SI 3 "register_operand" "=d")
1289
        (plus:SI (mult:SI (match_dup 1)
1290
                          (match_dup 2))
1291
                 (match_dup 0)))
1292
   (clobber (match_scratch:SI 4 "=h"))]
1293
  "ISA_HAS_MACC && reload_completed"
1294
  "macc\t%3,%1,%2"
1295
  [(set_attr "type"     "imadd")
1296
   (set_attr "mode"     "SI")])
1297
 
1298
(define_insn "*msac2"
1299
  [(set (match_operand:SI 0 "register_operand" "=l")
1300
        (minus:SI (match_dup 0)
1301
                  (mult:SI (match_operand:SI 1 "register_operand" "d")
1302
                           (match_operand:SI 2 "register_operand" "d"))))
1303
   (set (match_operand:SI 3 "register_operand" "=d")
1304
        (minus:SI (match_dup 0)
1305
                  (mult:SI (match_dup 1)
1306
                           (match_dup 2))))
1307
   (clobber (match_scratch:SI 4 "=h"))]
1308
  "ISA_HAS_MSAC && reload_completed"
1309
  "msac\t%3,%1,%2"
1310
  [(set_attr "type"     "imadd")
1311
   (set_attr "mode"     "SI")])
1312
 
1313
;; Convert macc $0,, & mflo  into macc ,,
1314
;; Similarly msac.
1315
;;
1316
;; Operand 0: LO
1317
;; Operand 1: macc/msac
1318
;; Operand 2: HI
1319
;; Operand 3: GPR (destination)
1320
(define_peephole2
1321
  [(parallel
1322
       [(set (match_operand:SI 0 "register_operand")
1323
             (match_operand:SI 1 "macc_msac_operand"))
1324
        (clobber (match_operand:SI 2 "register_operand"))
1325
        (clobber (scratch:SI))])
1326
   (set (match_operand:SI 3 "register_operand")
1327
        (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1328
  ""
1329
  [(parallel [(set (match_dup 0)
1330
                   (match_dup 1))
1331
              (set (match_dup 3)
1332
                   (match_dup 1))
1333
              (clobber (match_dup 2))])]
1334
  "")
1335
 
1336
;; When we have a three-address multiplication instruction, it should
1337
;; be faster to do a separate multiply and add, rather than moving
1338
;; something into LO in order to use a macc instruction.
1339
;;
1340
;; This peephole needs a scratch register to cater for the case when one
1341
;; of the multiplication operands is the same as the destination.
1342
;;
1343
;; Operand 0: GPR (scratch)
1344
;; Operand 1: LO
1345
;; Operand 2: GPR (addend)
1346
;; Operand 3: GPR (destination)
1347
;; Operand 4: macc/msac
1348
;; Operand 5: HI
1349
;; Operand 6: new multiplication
1350
;; Operand 7: new addition/subtraction
1351
(define_peephole2
1352
  [(match_scratch:SI 0 "d")
1353
   (set (match_operand:SI 1 "register_operand")
1354
        (match_operand:SI 2 "register_operand"))
1355
   (match_dup 0)
1356
   (parallel
1357
       [(set (match_operand:SI 3 "register_operand")
1358
             (match_operand:SI 4 "macc_msac_operand"))
1359
        (clobber (match_operand:SI 5 "register_operand"))
1360
        (clobber (match_dup 1))])]
1361
  "GENERATE_MULT3_SI
1362
   && true_regnum (operands[1]) == LO_REGNUM
1363
   && peep2_reg_dead_p (2, operands[1])
1364
   && GP_REG_P (true_regnum (operands[3]))"
1365
  [(parallel [(set (match_dup 0)
1366
                   (match_dup 6))
1367
              (clobber (match_dup 5))
1368
              (clobber (match_dup 1))])
1369
   (set (match_dup 3)
1370
        (match_dup 7))]
1371
{
1372
  operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1373
  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1374
                                operands[2], operands[0]);
1375
})
1376
 
1377
;; Same as above, except LO is the initial target of the macc.
1378
;;
1379
;; Operand 0: GPR (scratch)
1380
;; Operand 1: LO
1381
;; Operand 2: GPR (addend)
1382
;; Operand 3: macc/msac
1383
;; Operand 4: HI
1384
;; Operand 5: GPR (destination)
1385
;; Operand 6: new multiplication
1386
;; Operand 7: new addition/subtraction
1387
(define_peephole2
1388
  [(match_scratch:SI 0 "d")
1389
   (set (match_operand:SI 1 "register_operand")
1390
        (match_operand:SI 2 "register_operand"))
1391
   (match_dup 0)
1392
   (parallel
1393
       [(set (match_dup 1)
1394
             (match_operand:SI 3 "macc_msac_operand"))
1395
        (clobber (match_operand:SI 4 "register_operand"))
1396
        (clobber (scratch:SI))])
1397
   (match_dup 0)
1398
   (set (match_operand:SI 5 "register_operand")
1399
        (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1400
  "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1401
  [(parallel [(set (match_dup 0)
1402
                   (match_dup 6))
1403
              (clobber (match_dup 4))
1404
              (clobber (match_dup 1))])
1405
   (set (match_dup 5)
1406
        (match_dup 7))]
1407
{
1408
  operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1409
  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1410
                                operands[2], operands[0]);
1411
})
1412
 
1413
(define_insn "*mul_sub_si"
1414
  [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1415
        (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1416
                  (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1417
                           (match_operand:SI 3 "register_operand" "d,d,d"))))
1418
   (clobber (match_scratch:SI 4 "=h,h,h"))
1419
   (clobber (match_scratch:SI 5 "=X,1,l"))
1420
   (clobber (match_scratch:SI 6 "=X,X,&d"))]
1421
  "ISA_HAS_MADD_MSUB"
1422
  "@
1423
   msub\t%2,%3
1424
   #
1425
   #"
1426
  [(set_attr "type"     "imadd,multi,multi")
1427
   (set_attr "mode"     "SI")
1428
   (set_attr "length"   "4,8,8")])
1429
 
1430
;; Split the above insn if we failed to get LO allocated.
1431
(define_split
1432
  [(set (match_operand:SI 0 "register_operand")
1433
        (minus:SI (match_operand:SI 1 "register_operand")
1434
                  (mult:SI (match_operand:SI 2 "register_operand")
1435
                           (match_operand:SI 3 "register_operand"))))
1436
   (clobber (match_scratch:SI 4))
1437
   (clobber (match_scratch:SI 5))
1438
   (clobber (match_scratch:SI 6))]
1439
  "reload_completed && !TARGET_DEBUG_D_MODE
1440
   && GP_REG_P (true_regnum (operands[0]))
1441
   && GP_REG_P (true_regnum (operands[1]))"
1442
  [(parallel [(set (match_dup 6)
1443
                   (mult:SI (match_dup 2) (match_dup 3)))
1444
              (clobber (match_dup 4))
1445
              (clobber (match_dup 5))])
1446
   (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1447
  "")
1448
 
1449
;; Splitter to copy result of MSUB to a general register
1450
(define_split
1451
  [(set (match_operand:SI 0 "register_operand")
1452
        (minus:SI (match_operand:SI 1 "register_operand")
1453
                  (mult:SI (match_operand:SI 2 "register_operand")
1454
                           (match_operand:SI 3 "register_operand"))))
1455
   (clobber (match_scratch:SI 4))
1456
   (clobber (match_scratch:SI 5))
1457
   (clobber (match_scratch:SI 6))]
1458
  "reload_completed && !TARGET_DEBUG_D_MODE
1459
   && GP_REG_P (true_regnum (operands[0]))
1460
   && true_regnum (operands[1]) == LO_REGNUM"
1461
  [(parallel [(set (match_dup 1)
1462
                   (minus:SI (match_dup 1)
1463
                             (mult:SI (match_dup 2) (match_dup 3))))
1464
              (clobber (match_dup 4))
1465
              (clobber (match_dup 5))
1466
              (clobber (match_dup 6))])
1467
   (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1468
  "")
1469
 
1470
(define_insn "*muls"
1471
  [(set (match_operand:SI                  0 "register_operand" "=l,d")
1472
        (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1473
                         (match_operand:SI 2 "register_operand" "d,d"))))
1474
   (clobber (match_scratch:SI              3                    "=h,h"))
1475
   (clobber (match_scratch:SI              4                    "=X,l"))]
1476
  "ISA_HAS_MULS"
1477
  "@
1478
   muls\t$0,%1,%2
1479
   muls\t%0,%1,%2"
1480
  [(set_attr "type"     "imul,imul3")
1481
   (set_attr "mode"     "SI")])
1482
 
1483
;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1484
 
1485
(define_expand "mulsidi3"
1486
  [(parallel
1487
      [(set (match_operand:DI 0 "register_operand")
1488
            (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1489
                     (any_extend:DI (match_operand:SI 2 "register_operand"))))
1490
       (clobber (scratch:DI))
1491
       (clobber (scratch:DI))
1492
       (clobber (scratch:DI))])]
1493
  "!TARGET_64BIT || !TARGET_FIX_R4000"
1494
{
1495
  if (!TARGET_64BIT)
1496
    {
1497
      if (!TARGET_FIX_R4000)
1498
        emit_insn (gen_mulsidi3_32bit_internal (operands[0], operands[1],
1499
                                                   operands[2]));
1500
      else
1501
        emit_insn (gen_mulsidi3_32bit_r4000 (operands[0], operands[1],
1502
                                                operands[2]));
1503
      DONE;
1504
    }
1505
})
1506
 
1507
(define_insn "mulsidi3_32bit_internal"
1508
  [(set (match_operand:DI 0 "register_operand" "=x")
1509
        (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1510
                 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1511
  "!TARGET_64BIT && !TARGET_FIX_R4000"
1512
  "mult\t%1,%2"
1513
  [(set_attr "type" "imul")
1514
   (set_attr "mode" "SI")])
1515
 
1516
(define_insn "mulsidi3_32bit_r4000"
1517
  [(set (match_operand:DI 0 "register_operand" "=d")
1518
        (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1519
                 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1520
   (clobber (match_scratch:DI 3 "=x"))]
1521
  "!TARGET_64BIT && TARGET_FIX_R4000"
1522
  "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1523
  [(set_attr "type" "imul")
1524
   (set_attr "mode" "SI")
1525
   (set_attr "length" "12")])
1526
 
1527
(define_insn_and_split "*mulsidi3_64bit"
1528
  [(set (match_operand:DI 0 "register_operand" "=d")
1529
        (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1530
                 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1531
   (clobber (match_scratch:DI 3 "=l"))
1532
   (clobber (match_scratch:DI 4 "=h"))
1533
   (clobber (match_scratch:DI 5 "=d"))]
1534
  "TARGET_64BIT && !TARGET_FIX_R4000"
1535
  "#"
1536
  "&& reload_completed"
1537
  [(parallel
1538
       [(set (match_dup 3)
1539
             (sign_extend:DI
1540
                (mult:SI (match_dup 1)
1541
                         (match_dup 2))))
1542
        (set (match_dup 4)
1543
             (ashiftrt:DI
1544
                (mult:DI (any_extend:DI (match_dup 1))
1545
                         (any_extend:DI (match_dup 2)))
1546
                (const_int 32)))])
1547
 
1548
   ;; OP5 <- LO, OP0 <- HI
1549
   (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1550
   (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1551
 
1552
   ;; Zero-extend OP5.
1553
   (set (match_dup 5)
1554
        (ashift:DI (match_dup 5)
1555
                   (const_int 32)))
1556
   (set (match_dup 5)
1557
        (lshiftrt:DI (match_dup 5)
1558
                     (const_int 32)))
1559
 
1560
   ;; Shift OP0 into place.
1561
   (set (match_dup 0)
1562
        (ashift:DI (match_dup 0)
1563
                   (const_int 32)))
1564
 
1565
   ;; OR the two halves together
1566
   (set (match_dup 0)
1567
        (ior:DI (match_dup 0)
1568
                (match_dup 5)))]
1569
  ""
1570
  [(set_attr "type" "imul")
1571
   (set_attr "mode" "SI")
1572
   (set_attr "length" "24")])
1573
 
1574
(define_insn "*mulsidi3_64bit_parts"
1575
  [(set (match_operand:DI 0 "register_operand" "=l")
1576
        (sign_extend:DI
1577
           (mult:SI (match_operand:SI 2 "register_operand" "d")
1578
                    (match_operand:SI 3 "register_operand" "d"))))
1579
   (set (match_operand:DI 1 "register_operand" "=h")
1580
        (ashiftrt:DI
1581
           (mult:DI (any_extend:DI (match_dup 2))
1582
                    (any_extend:DI (match_dup 3)))
1583
           (const_int 32)))]
1584
  "TARGET_64BIT && !TARGET_FIX_R4000"
1585
  "mult\t%2,%3"
1586
  [(set_attr "type" "imul")
1587
   (set_attr "mode" "SI")])
1588
 
1589
;; Widening multiply with negation.
1590
(define_insn "*muls_di"
1591
  [(set (match_operand:DI 0 "register_operand" "=x")
1592
        (neg:DI
1593
         (mult:DI
1594
          (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1595
          (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1596
  "!TARGET_64BIT && ISA_HAS_MULS"
1597
  "muls\t$0,%1,%2"
1598
  [(set_attr "type" "imul")
1599
   (set_attr "mode" "SI")])
1600
 
1601
(define_insn "*msac_di"
1602
  [(set (match_operand:DI 0 "register_operand" "=x")
1603
        (minus:DI
1604
           (match_operand:DI 3 "register_operand" "0")
1605
           (mult:DI
1606
              (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1607
              (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1608
  "!TARGET_64BIT && ISA_HAS_MSAC"
1609
{
1610
  if (TARGET_MIPS5500)
1611
    return "msub\t%1,%2";
1612
  else
1613
    return "msac\t$0,%1,%2";
1614
}
1615
  [(set_attr "type" "imadd")
1616
   (set_attr "mode" "SI")])
1617
 
1618
;; _highpart patterns
1619
 
1620
(define_expand "mulsi3_highpart"
1621
  [(set (match_operand:SI 0 "register_operand")
1622
        (truncate:SI
1623
         (lshiftrt:DI
1624
          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1625
                   (any_extend:DI (match_operand:SI 2 "register_operand")))
1626
          (const_int 32))))]
1627
  "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1628
{
1629
  if (ISA_HAS_MULHI)
1630
    emit_insn (gen_mulsi3_highpart_mulhi_internal (operands[0],
1631
                                                       operands[1],
1632
                                                       operands[2]));
1633
  else
1634
    emit_insn (gen_mulsi3_highpart_internal (operands[0], operands[1],
1635
                                                 operands[2]));
1636
  DONE;
1637
})
1638
 
1639
(define_insn "mulsi3_highpart_internal"
1640
  [(set (match_operand:SI 0 "register_operand" "=h")
1641
        (truncate:SI
1642
         (lshiftrt:DI
1643
          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1644
                   (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1645
          (const_int 32))))
1646
   (clobber (match_scratch:SI 3 "=l"))]
1647
  "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1648
  "mult\t%1,%2"
1649
  [(set_attr "type" "imul")
1650
   (set_attr "mode" "SI")])
1651
 
1652
(define_insn "mulsi3_highpart_mulhi_internal"
1653
  [(set (match_operand:SI 0 "register_operand" "=h,d")
1654
        (truncate:SI
1655
         (lshiftrt:DI
1656
          (mult:DI
1657
           (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1658
           (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1659
          (const_int 32))))
1660
   (clobber (match_scratch:SI 3 "=l,l"))
1661
   (clobber (match_scratch:SI 4 "=X,h"))]
1662
  "ISA_HAS_MULHI"
1663
  "@
1664
   mult\t%1,%2
1665
   mulhi\t%0,%1,%2"
1666
  [(set_attr "type" "imul,imul3")
1667
   (set_attr "mode" "SI")])
1668
 
1669
(define_insn "*mulsi3_highpart_neg_mulhi_internal"
1670
  [(set (match_operand:SI 0 "register_operand" "=h,d")
1671
        (truncate:SI
1672
         (lshiftrt:DI
1673
          (neg:DI
1674
           (mult:DI
1675
            (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1676
            (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1677
          (const_int 32))))
1678
   (clobber (match_scratch:SI 3 "=l,l"))
1679
   (clobber (match_scratch:SI 4 "=X,h"))]
1680
  "ISA_HAS_MULHI"
1681
  "@
1682
   mulshi\t%.,%1,%2
1683
   mulshi\t%0,%1,%2"
1684
  [(set_attr "type" "imul,imul3")
1685
   (set_attr "mode" "SI")])
1686
 
1687
;; Disable unsigned multiplication for -mfix-vr4120.  This is for VR4120
1688
;; errata MD(0), which says that dmultu does not always produce the
1689
;; correct result.
1690
(define_insn "muldi3_highpart"
1691
  [(set (match_operand:DI 0 "register_operand" "=h")
1692
        (truncate:DI
1693
         (lshiftrt:TI
1694
          (mult:TI
1695
           (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1696
           (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1697
          (const_int 64))))
1698
   (clobber (match_scratch:DI 3 "=l"))]
1699
  "TARGET_64BIT && !TARGET_FIX_R4000
1700
   && !( == ZERO_EXTEND && TARGET_FIX_VR4120)"
1701
  "dmult\t%1,%2"
1702
  [(set_attr "type" "imul")
1703
   (set_attr "mode" "DI")])
1704
 
1705
;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1706
;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
1707
 
1708
(define_insn "madsi"
1709
  [(set (match_operand:SI 0 "register_operand" "+l")
1710
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1711
                          (match_operand:SI 2 "register_operand" "d"))
1712
                 (match_dup 0)))
1713
   (clobber (match_scratch:SI 3 "=h"))]
1714
  "TARGET_MAD"
1715
  "mad\t%1,%2"
1716
  [(set_attr "type"     "imadd")
1717
   (set_attr "mode"     "SI")])
1718
 
1719
(define_insn "*mul_acc_di"
1720
  [(set (match_operand:DI 0 "register_operand" "=x")
1721
        (plus:DI
1722
         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1723
                  (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1724
         (match_operand:DI 3 "register_operand" "0")))]
1725
  "(TARGET_MAD || ISA_HAS_MACC)
1726
   && !TARGET_64BIT"
1727
{
1728
  if (TARGET_MAD)
1729
    return "mad\t%1,%2";
1730
  else if (TARGET_MIPS5500)
1731
    return "madd\t%1,%2";
1732
  else
1733
    /* See comment in *macc.  */
1734
    return "%[macc\t%@,%1,%2%]";
1735
}
1736
  [(set_attr "type" "imadd")
1737
   (set_attr "mode" "SI")])
1738
 
1739
;; Floating point multiply accumulate instructions.
1740
 
1741
(define_insn "*madd"
1742
  [(set (match_operand:ANYF 0 "register_operand" "=f")
1743
        (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1744
                              (match_operand:ANYF 2 "register_operand" "f"))
1745
                   (match_operand:ANYF 3 "register_operand" "f")))]
1746
  "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1747
  "madd.\t%0,%3,%1,%2"
1748
  [(set_attr "type" "fmadd")
1749
   (set_attr "mode" "")])
1750
 
1751
(define_insn "*msub"
1752
  [(set (match_operand:ANYF 0 "register_operand" "=f")
1753
        (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1754
                               (match_operand:ANYF 2 "register_operand" "f"))
1755
                    (match_operand:ANYF 3 "register_operand" "f")))]
1756
  "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1757
  "msub.\t%0,%3,%1,%2"
1758
  [(set_attr "type" "fmadd")
1759
   (set_attr "mode" "")])
1760
 
1761
(define_insn "*nmadd"
1762
  [(set (match_operand:ANYF 0 "register_operand" "=f")
1763
        (neg:ANYF (plus:ANYF
1764
                   (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1765
                              (match_operand:ANYF 2 "register_operand" "f"))
1766
                   (match_operand:ANYF 3 "register_operand" "f"))))]
1767
  "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1768
   && HONOR_SIGNED_ZEROS (mode)
1769
   && !HONOR_NANS (mode)"
1770
  "nmadd.\t%0,%3,%1,%2"
1771
  [(set_attr "type" "fmadd")
1772
   (set_attr "mode" "")])
1773
 
1774
(define_insn "*nmadd_fastmath"
1775
  [(set (match_operand:ANYF 0 "register_operand" "=f")
1776
        (minus:ANYF
1777
         (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
1778
                    (match_operand:ANYF 2 "register_operand" "f"))
1779
         (match_operand:ANYF 3 "register_operand" "f")))]
1780
  "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1781
   && !HONOR_SIGNED_ZEROS (mode)
1782
   && !HONOR_NANS (mode)"
1783
  "nmadd.\t%0,%3,%1,%2"
1784
  [(set_attr "type" "fmadd")
1785
   (set_attr "mode" "")])
1786
 
1787
(define_insn "*nmsub"
1788
  [(set (match_operand:ANYF 0 "register_operand" "=f")
1789
        (neg:ANYF (minus:ANYF
1790
                   (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1791
                              (match_operand:ANYF 3 "register_operand" "f"))
1792
                   (match_operand:ANYF 1 "register_operand" "f"))))]
1793
  "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1794
   && HONOR_SIGNED_ZEROS (mode)
1795
   && !HONOR_NANS (mode)"
1796
  "nmsub.\t%0,%1,%2,%3"
1797
  [(set_attr "type" "fmadd")
1798
   (set_attr "mode" "")])
1799
 
1800
(define_insn "*nmsub_fastmath"
1801
  [(set (match_operand:ANYF 0 "register_operand" "=f")
1802
        (minus:ANYF
1803
         (match_operand:ANYF 1 "register_operand" "f")
1804
         (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1805
                    (match_operand:ANYF 3 "register_operand" "f"))))]
1806
  "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1807
   && !HONOR_SIGNED_ZEROS (mode)
1808
   && !HONOR_NANS (mode)"
1809
  "nmsub.\t%0,%1,%2,%3"
1810
  [(set_attr "type" "fmadd")
1811
   (set_attr "mode" "")])
1812
 
1813
;;
1814
;;  ....................
1815
;;
1816
;;      DIVISION and REMAINDER
1817
;;
1818
;;  ....................
1819
;;
1820
 
1821
(define_expand "div3"
1822
  [(set (match_operand:ANYF 0 "register_operand")
1823
        (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
1824
                  (match_operand:ANYF 2 "register_operand")))]
1825
  ""
1826
{
1827
  if (const_1_operand (operands[1], mode))
1828
    if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1829
      operands[1] = force_reg (mode, operands[1]);
1830
})
1831
 
1832
;; These patterns work around the early SB-1 rev2 core "F1" erratum:
1833
;;
1834
;; If an mfc1 or dmfc1 happens to access the floating point register
1835
;; file at the same time a long latency operation (div, sqrt, recip,
1836
;; sqrt) iterates an intermediate result back through the floating
1837
;; point register file bypass, then instead returning the correct
1838
;; register value the mfc1 or dmfc1 operation returns the intermediate
1839
;; result of the long latency operation.
1840
;;
1841
;; The workaround is to insert an unconditional 'mov' from/to the
1842
;; long latency op destination register.
1843
 
1844
(define_insn "*div3"
1845
  [(set (match_operand:ANYF 0 "register_operand" "=f")
1846
        (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
1847
                  (match_operand:ANYF 2 "register_operand" "f")))]
1848
  ""
1849
{
1850
  if (TARGET_FIX_SB1)
1851
    return "div.\t%0,%1,%2\;mov.\t%0,%0";
1852
  else
1853
    return "div.\t%0,%1,%2";
1854
}
1855
  [(set_attr "type" "fdiv")
1856
   (set_attr "mode" "")
1857
   (set (attr "length")
1858
        (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1859
                      (const_int 8)
1860
                      (const_int 4)))])
1861
 
1862
(define_insn "*recip3"
1863
  [(set (match_operand:ANYF 0 "register_operand" "=f")
1864
        (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1865
                  (match_operand:ANYF 2 "register_operand" "f")))]
1866
  " && flag_unsafe_math_optimizations"
1867
{
1868
  if (TARGET_FIX_SB1)
1869
    return "recip.\t%0,%2\;mov.\t%0,%0";
1870
  else
1871
    return "recip.\t%0,%2";
1872
}
1873
  [(set_attr "type" "frdiv")
1874
   (set_attr "mode" "")
1875
   (set (attr "length")
1876
        (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1877
                      (const_int 8)
1878
                      (const_int 4)))])
1879
 
1880
;; VR4120 errata MD(A1): signed division instructions do not work correctly
1881
;; with negative operands.  We use special libgcc functions instead.
1882
(define_insn "divmod4"
1883
  [(set (match_operand:GPR 0 "register_operand" "=l")
1884
        (div:GPR (match_operand:GPR 1 "register_operand" "d")
1885
                 (match_operand:GPR 2 "register_operand" "d")))
1886
   (set (match_operand:GPR 3 "register_operand" "=h")
1887
        (mod:GPR (match_dup 1)
1888
                 (match_dup 2)))]
1889
  "!TARGET_FIX_VR4120"
1890
  { return mips_output_division ("div\t$0,%1,%2", operands); }
1891
  [(set_attr "type" "idiv")
1892
   (set_attr "mode" "")])
1893
 
1894
(define_insn "udivmod4"
1895
  [(set (match_operand:GPR 0 "register_operand" "=l")
1896
        (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1897
                  (match_operand:GPR 2 "register_operand" "d")))
1898
   (set (match_operand:GPR 3 "register_operand" "=h")
1899
        (umod:GPR (match_dup 1)
1900
                  (match_dup 2)))]
1901
  ""
1902
  { return mips_output_division ("divu\t$0,%1,%2", operands); }
1903
  [(set_attr "type" "idiv")
1904
   (set_attr "mode" "")])
1905
 
1906
;;
1907
;;  ....................
1908
;;
1909
;;      SQUARE ROOT
1910
;;
1911
;;  ....................
1912
 
1913
;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
1914
;; "*div[sd]f3" comment for details).
1915
 
1916
(define_insn "sqrt2"
1917
  [(set (match_operand:ANYF 0 "register_operand" "=f")
1918
        (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1919
  ""
1920
{
1921
  if (TARGET_FIX_SB1)
1922
    return "sqrt.\t%0,%1\;mov.\t%0,%0";
1923
  else
1924
    return "sqrt.\t%0,%1";
1925
}
1926
  [(set_attr "type" "fsqrt")
1927
   (set_attr "mode" "")
1928
   (set (attr "length")
1929
        (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1930
                      (const_int 8)
1931
                      (const_int 4)))])
1932
 
1933
(define_insn "*rsqrta"
1934
  [(set (match_operand:ANYF 0 "register_operand" "=f")
1935
        (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1936
                  (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
1937
  " && flag_unsafe_math_optimizations"
1938
{
1939
  if (TARGET_FIX_SB1)
1940
    return "rsqrt.\t%0,%2\;mov.\t%0,%0";
1941
  else
1942
    return "rsqrt.\t%0,%2";
1943
}
1944
  [(set_attr "type" "frsqrt")
1945
   (set_attr "mode" "")
1946
   (set (attr "length")
1947
        (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1948
                      (const_int 8)
1949
                      (const_int 4)))])
1950
 
1951
(define_insn "*rsqrtb"
1952
  [(set (match_operand:ANYF 0 "register_operand" "=f")
1953
        (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1954
                             (match_operand:ANYF 2 "register_operand" "f"))))]
1955
  " && flag_unsafe_math_optimizations"
1956
{
1957
  if (TARGET_FIX_SB1)
1958
    return "rsqrt.\t%0,%2\;mov.\t%0,%0";
1959
  else
1960
    return "rsqrt.\t%0,%2";
1961
}
1962
  [(set_attr "type" "frsqrt")
1963
   (set_attr "mode" "")
1964
   (set (attr "length")
1965
        (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1966
                      (const_int 8)
1967
                      (const_int 4)))])
1968
 
1969
;;
1970
;;  ....................
1971
;;
1972
;;      ABSOLUTE VALUE
1973
;;
1974
;;  ....................
1975
 
1976
;; Do not use the integer abs macro instruction, since that signals an
1977
;; exception on -2147483648 (sigh).
1978
 
1979
;; abs.fmt is an arithmetic instruction and treats all NaN inputs as
1980
;; invalid; it does not clear their sign bits.  We therefore can't use
1981
;; abs.fmt if the signs of NaNs matter.
1982
 
1983
(define_insn "abs2"
1984
  [(set (match_operand:ANYF 0 "register_operand" "=f")
1985
        (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1986
  "!HONOR_NANS (mode)"
1987
  "abs.\t%0,%1"
1988
  [(set_attr "type" "fabs")
1989
   (set_attr "mode" "")])
1990
 
1991
;;
1992
;;  ...................
1993
;;
1994
;;  Count leading zeroes.
1995
;;
1996
;;  ...................
1997
;;
1998
 
1999
(define_insn "clz2"
2000
  [(set (match_operand:GPR 0 "register_operand" "=d")
2001
        (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2002
  "ISA_HAS_CLZ_CLO"
2003
  "clz\t%0,%1"
2004
  [(set_attr "type" "clz")
2005
   (set_attr "mode" "")])
2006
 
2007
;;
2008
;;  ....................
2009
;;
2010
;;      NEGATION and ONE'S COMPLEMENT
2011
;;
2012
;;  ....................
2013
 
2014
(define_insn "negsi2"
2015
  [(set (match_operand:SI 0 "register_operand" "=d")
2016
        (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2017
  ""
2018
{
2019
  if (TARGET_MIPS16)
2020
    return "neg\t%0,%1";
2021
  else
2022
    return "subu\t%0,%.,%1";
2023
}
2024
  [(set_attr "type"     "arith")
2025
   (set_attr "mode"     "SI")])
2026
 
2027
(define_insn "negdi2"
2028
  [(set (match_operand:DI 0 "register_operand" "=d")
2029
        (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2030
  "TARGET_64BIT && !TARGET_MIPS16"
2031
  "dsubu\t%0,%.,%1"
2032
  [(set_attr "type"     "arith")
2033
   (set_attr "mode"     "DI")])
2034
 
2035
;; neg.fmt is an arithmetic instruction and treats all NaN inputs as
2036
;; invalid; it does not flip their sign bit.  We therefore can't use
2037
;; neg.fmt if the signs of NaNs matter.
2038
 
2039
(define_insn "neg2"
2040
  [(set (match_operand:ANYF 0 "register_operand" "=f")
2041
        (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2042
  "!HONOR_NANS (mode)"
2043
  "neg.\t%0,%1"
2044
  [(set_attr "type" "fneg")
2045
   (set_attr "mode" "")])
2046
 
2047
(define_insn "one_cmpl2"
2048
  [(set (match_operand:GPR 0 "register_operand" "=d")
2049
        (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2050
  ""
2051
{
2052
  if (TARGET_MIPS16)
2053
    return "not\t%0,%1";
2054
  else
2055
    return "nor\t%0,%.,%1";
2056
}
2057
  [(set_attr "type" "arith")
2058
   (set_attr "mode" "")])
2059
 
2060
;;
2061
;;  ....................
2062
;;
2063
;;      LOGICAL
2064
;;
2065
;;  ....................
2066
;;
2067
 
2068
;; Many of these instructions use trivial define_expands, because we
2069
;; want to use a different set of constraints when TARGET_MIPS16.
2070
 
2071
(define_expand "and3"
2072
  [(set (match_operand:GPR 0 "register_operand")
2073
        (and:GPR (match_operand:GPR 1 "register_operand")
2074
                 (match_operand:GPR 2 "uns_arith_operand")))]
2075
  ""
2076
{
2077
  if (TARGET_MIPS16)
2078
    operands[2] = force_reg (mode, operands[2]);
2079
})
2080
 
2081
(define_insn "*and3"
2082
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2083
        (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2084
                 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2085
  "!TARGET_MIPS16"
2086
  "@
2087
   and\t%0,%1,%2
2088
   andi\t%0,%1,%x2"
2089
  [(set_attr "type" "arith")
2090
   (set_attr "mode" "")])
2091
 
2092
(define_insn "*and3_mips16"
2093
  [(set (match_operand:GPR 0 "register_operand" "=d")
2094
        (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2095
                 (match_operand:GPR 2 "register_operand" "d")))]
2096
  "TARGET_MIPS16"
2097
  "and\t%0,%2"
2098
  [(set_attr "type" "arith")
2099
   (set_attr "mode" "")])
2100
 
2101
(define_expand "ior3"
2102
  [(set (match_operand:GPR 0 "register_operand")
2103
        (ior:GPR (match_operand:GPR 1 "register_operand")
2104
                 (match_operand:GPR 2 "uns_arith_operand")))]
2105
  ""
2106
{
2107
  if (TARGET_MIPS16)
2108
    operands[2] = force_reg (mode, operands[2]);
2109
})
2110
 
2111
(define_insn "*ior3"
2112
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2113
        (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2114
                 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2115
  "!TARGET_MIPS16"
2116
  "@
2117
   or\t%0,%1,%2
2118
   ori\t%0,%1,%x2"
2119
  [(set_attr "type" "arith")
2120
   (set_attr "mode" "")])
2121
 
2122
(define_insn "*ior3_mips16"
2123
  [(set (match_operand:GPR 0 "register_operand" "=d")
2124
        (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2125
                 (match_operand:GPR 2 "register_operand" "d")))]
2126
  "TARGET_MIPS16"
2127
  "or\t%0,%2"
2128
  [(set_attr "type" "arith")
2129
   (set_attr "mode" "")])
2130
 
2131
(define_expand "xor3"
2132
  [(set (match_operand:GPR 0 "register_operand")
2133
        (xor:GPR (match_operand:GPR 1 "register_operand")
2134
                 (match_operand:GPR 2 "uns_arith_operand")))]
2135
  ""
2136
  "")
2137
 
2138
(define_insn ""
2139
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2140
        (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2141
                 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2142
  "!TARGET_MIPS16"
2143
  "@
2144
   xor\t%0,%1,%2
2145
   xori\t%0,%1,%x2"
2146
  [(set_attr "type" "arith")
2147
   (set_attr "mode" "")])
2148
 
2149
(define_insn ""
2150
  [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2151
        (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2152
                 (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2153
  "TARGET_MIPS16"
2154
  "@
2155
   xor\t%0,%2
2156
   cmpi\t%1,%2
2157
   cmp\t%1,%2"
2158
  [(set_attr "type" "arith")
2159
   (set_attr "mode" "")
2160
   (set_attr_alternative "length"
2161
                [(const_int 4)
2162
                 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2163
                               (const_int 4)
2164
                               (const_int 8))
2165
                 (const_int 4)])])
2166
 
2167
(define_insn "*nor3"
2168
  [(set (match_operand:GPR 0 "register_operand" "=d")
2169
        (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2170
                 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2171
  "!TARGET_MIPS16"
2172
  "nor\t%0,%1,%2"
2173
  [(set_attr "type" "arith")
2174
   (set_attr "mode" "")])
2175
 
2176
;;
2177
;;  ....................
2178
;;
2179
;;      TRUNCATION
2180
;;
2181
;;  ....................
2182
 
2183
 
2184
 
2185
(define_insn "truncdfsf2"
2186
  [(set (match_operand:SF 0 "register_operand" "=f")
2187
        (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2188
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2189
  "cvt.s.d\t%0,%1"
2190
  [(set_attr "type"     "fcvt")
2191
   (set_attr "cnv_mode" "D2S")
2192
   (set_attr "mode"     "SF")])
2193
 
2194
;; Integer truncation patterns.  Truncating SImode values to smaller
2195
;; modes is a no-op, as it is for most other GCC ports.  Truncating
2196
;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2197
;; need to make sure that the lower 32 bits are properly sign-extended
2198
;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2199
;; smaller than SImode is equivalent to two separate truncations:
2200
;;
2201
;;                        A       B
2202
;;    DI ---> HI  ==  DI ---> SI ---> HI
2203
;;    DI ---> QI  ==  DI ---> SI ---> QI
2204
;;
2205
;; Step A needs a real instruction but step B does not.
2206
 
2207
(define_insn "truncdisi2"
2208
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2209
        (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2210
  "TARGET_64BIT"
2211
  "@
2212
    sll\t%0,%1,0
2213
    sw\t%1,%0"
2214
  [(set_attr "type" "shift,store")
2215
   (set_attr "mode" "SI")
2216
   (set_attr "extended_mips16" "yes,*")])
2217
 
2218
(define_insn "truncdihi2"
2219
  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2220
        (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2221
  "TARGET_64BIT"
2222
  "@
2223
    sll\t%0,%1,0
2224
    sh\t%1,%0"
2225
  [(set_attr "type" "shift,store")
2226
   (set_attr "mode" "SI")
2227
   (set_attr "extended_mips16" "yes,*")])
2228
 
2229
(define_insn "truncdiqi2"
2230
  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2231
        (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2232
  "TARGET_64BIT"
2233
  "@
2234
    sll\t%0,%1,0
2235
    sb\t%1,%0"
2236
  [(set_attr "type" "shift,store")
2237
   (set_attr "mode" "SI")
2238
   (set_attr "extended_mips16" "yes,*")])
2239
 
2240
;; Combiner patterns to optimize shift/truncate combinations.
2241
 
2242
(define_insn ""
2243
  [(set (match_operand:SI 0 "register_operand" "=d")
2244
        (truncate:SI
2245
          (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2246
                       (match_operand:DI 2 "const_arith_operand" ""))))]
2247
  "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2248
  "dsra\t%0,%1,%2"
2249
  [(set_attr "type" "shift")
2250
   (set_attr "mode" "SI")])
2251
 
2252
(define_insn ""
2253
  [(set (match_operand:SI 0 "register_operand" "=d")
2254
        (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2255
                                  (const_int 32))))]
2256
  "TARGET_64BIT && !TARGET_MIPS16"
2257
  "dsra\t%0,%1,32"
2258
  [(set_attr "type" "shift")
2259
   (set_attr "mode" "SI")])
2260
 
2261
 
2262
;; Combiner patterns for truncate/sign_extend combinations.  They use
2263
;; the shift/truncate patterns above.
2264
 
2265
(define_insn_and_split ""
2266
  [(set (match_operand:SI 0 "register_operand" "=d")
2267
        (sign_extend:SI
2268
            (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2269
  "TARGET_64BIT && !TARGET_MIPS16"
2270
  "#"
2271
  "&& reload_completed"
2272
  [(set (match_dup 2)
2273
        (ashift:DI (match_dup 1)
2274
                   (const_int 48)))
2275
   (set (match_dup 0)
2276
        (truncate:SI (ashiftrt:DI (match_dup 2)
2277
                                  (const_int 48))))]
2278
  { operands[2] = gen_lowpart (DImode, operands[0]); })
2279
 
2280
(define_insn_and_split ""
2281
  [(set (match_operand:SI 0 "register_operand" "=d")
2282
        (sign_extend:SI
2283
            (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2284
  "TARGET_64BIT && !TARGET_MIPS16"
2285
  "#"
2286
  "&& reload_completed"
2287
  [(set (match_dup 2)
2288
        (ashift:DI (match_dup 1)
2289
                   (const_int 56)))
2290
   (set (match_dup 0)
2291
        (truncate:SI (ashiftrt:DI (match_dup 2)
2292
                                  (const_int 56))))]
2293
  { operands[2] = gen_lowpart (DImode, operands[0]); })
2294
 
2295
 
2296
;; Combiner patterns to optimize truncate/zero_extend combinations.
2297
 
2298
(define_insn ""
2299
  [(set (match_operand:SI 0 "register_operand" "=d")
2300
        (zero_extend:SI (truncate:HI
2301
                         (match_operand:DI 1 "register_operand" "d"))))]
2302
  "TARGET_64BIT && !TARGET_MIPS16"
2303
  "andi\t%0,%1,0xffff"
2304
  [(set_attr "type"     "arith")
2305
   (set_attr "mode"     "SI")])
2306
 
2307
(define_insn ""
2308
  [(set (match_operand:SI 0 "register_operand" "=d")
2309
        (zero_extend:SI (truncate:QI
2310
                         (match_operand:DI 1 "register_operand" "d"))))]
2311
  "TARGET_64BIT && !TARGET_MIPS16"
2312
  "andi\t%0,%1,0xff"
2313
  [(set_attr "type"     "arith")
2314
   (set_attr "mode"     "SI")])
2315
 
2316
(define_insn ""
2317
  [(set (match_operand:HI 0 "register_operand" "=d")
2318
        (zero_extend:HI (truncate:QI
2319
                         (match_operand:DI 1 "register_operand" "d"))))]
2320
  "TARGET_64BIT && !TARGET_MIPS16"
2321
  "andi\t%0,%1,0xff"
2322
  [(set_attr "type"     "arith")
2323
   (set_attr "mode"     "HI")])
2324
 
2325
;;
2326
;;  ....................
2327
;;
2328
;;      ZERO EXTENSION
2329
;;
2330
;;  ....................
2331
 
2332
;; Extension insns.
2333
 
2334
(define_insn_and_split "zero_extendsidi2"
2335
  [(set (match_operand:DI 0 "register_operand" "=d,d")
2336
        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
2337
  "TARGET_64BIT"
2338
  "@
2339
   #
2340
   lwu\t%0,%1"
2341
  "&& reload_completed && REG_P (operands[1])"
2342
  [(set (match_dup 0)
2343
        (ashift:DI (match_dup 1) (const_int 32)))
2344
   (set (match_dup 0)
2345
        (lshiftrt:DI (match_dup 0) (const_int 32)))]
2346
  { operands[1] = gen_lowpart (DImode, operands[1]); }
2347
  [(set_attr "type" "multi,load")
2348
   (set_attr "mode" "DI")
2349
   (set_attr "length" "8,*")])
2350
 
2351
;; Combine is not allowed to convert this insn into a zero_extendsidi2
2352
;; because of TRULY_NOOP_TRUNCATION.
2353
 
2354
(define_insn_and_split "*clear_upper32"
2355
  [(set (match_operand:DI 0 "register_operand" "=d,d")
2356
        (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
2357
                (const_int 4294967295)))]
2358
  "TARGET_64BIT"
2359
{
2360
  if (which_alternative == 0)
2361
    return "#";
2362
 
2363
  operands[1] = gen_lowpart (SImode, operands[1]);
2364
  return "lwu\t%0,%1";
2365
}
2366
  "&& reload_completed && REG_P (operands[1])"
2367
  [(set (match_dup 0)
2368
        (ashift:DI (match_dup 1) (const_int 32)))
2369
   (set (match_dup 0)
2370
        (lshiftrt:DI (match_dup 0) (const_int 32)))]
2371
  ""
2372
  [(set_attr "type" "multi,load")
2373
   (set_attr "mode" "DI")
2374
   (set_attr "length" "8,*")])
2375
 
2376
(define_expand "zero_extend2"
2377
  [(set (match_operand:GPR 0 "register_operand")
2378
        (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2379
  ""
2380
{
2381
  if (TARGET_MIPS16 && !GENERATE_MIPS16E
2382
      && !memory_operand (operands[1], mode))
2383
    {
2384
      emit_insn (gen_and3 (operands[0],
2385
                                     gen_lowpart (mode, operands[1]),
2386
                                     force_reg (mode,
2387
                                                GEN_INT ())));
2388
      DONE;
2389
    }
2390
})
2391
 
2392
(define_insn "*zero_extend2"
2393
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2394
        (zero_extend:GPR
2395
             (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2396
  "!TARGET_MIPS16"
2397
  "@
2398
   andi\t%0,%1,
2399
   lu\t%0,%1"
2400
  [(set_attr "type" "arith,load")
2401
   (set_attr "mode" "")])
2402
 
2403
(define_insn "*zero_extend2_mips16e"
2404
  [(set (match_operand:GPR 0 "register_operand" "=d")
2405
        (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
2406
  "GENERATE_MIPS16E"
2407
  "ze\t%0"
2408
  [(set_attr "type" "arith")
2409
   (set_attr "mode" "")])
2410
 
2411
(define_insn "*zero_extend2_mips16"
2412
  [(set (match_operand:GPR 0 "register_operand" "=d")
2413
        (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
2414
  "TARGET_MIPS16"
2415
  "lu\t%0,%1"
2416
  [(set_attr "type" "load")
2417
   (set_attr "mode" "")])
2418
 
2419
(define_expand "zero_extendqihi2"
2420
  [(set (match_operand:HI 0 "register_operand")
2421
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2422
  ""
2423
{
2424
  if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
2425
    {
2426
      emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
2427
                                       operands[1]));
2428
      DONE;
2429
    }
2430
})
2431
 
2432
(define_insn "*zero_extendqihi2"
2433
  [(set (match_operand:HI 0 "register_operand" "=d,d")
2434
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2435
  "!TARGET_MIPS16"
2436
  "@
2437
   andi\t%0,%1,0x00ff
2438
   lbu\t%0,%1"
2439
  [(set_attr "type" "arith,load")
2440
   (set_attr "mode" "HI")])
2441
 
2442
(define_insn "*zero_extendqihi2_mips16"
2443
  [(set (match_operand:HI 0 "register_operand" "=d")
2444
        (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2445
  "TARGET_MIPS16"
2446
  "lbu\t%0,%1"
2447
  [(set_attr "type" "load")
2448
   (set_attr "mode" "HI")])
2449
 
2450
;;
2451
;;  ....................
2452
;;
2453
;;      SIGN EXTENSION
2454
;;
2455
;;  ....................
2456
 
2457
;; Extension insns.
2458
;; Those for integer source operand are ordered widest source type first.
2459
 
2460
;; When TARGET_64BIT, all SImode integer registers should already be in
2461
;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can
2462
;; therefore get rid of register->register instructions if we constrain
2463
;; the source to be in the same register as the destination.
2464
;;
2465
;; The register alternative has type "arith" so that the pre-reload
2466
;; scheduler will treat it as a move.  This reflects what happens if
2467
;; the register alternative needs a reload.
2468
(define_insn_and_split "extendsidi2"
2469
  [(set (match_operand:DI 0 "register_operand" "=d,d")
2470
        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2471
  "TARGET_64BIT"
2472
  "@
2473
   #
2474
   lw\t%0,%1"
2475
  "&& reload_completed && register_operand (operands[1], VOIDmode)"
2476
  [(const_int 0)]
2477
{
2478
  emit_note (NOTE_INSN_DELETED);
2479
  DONE;
2480
}
2481
  [(set_attr "type" "arith,load")
2482
   (set_attr "mode" "DI")])
2483
 
2484
(define_expand "extend2"
2485
  [(set (match_operand:GPR 0 "register_operand")
2486
        (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2487
  "")
2488
 
2489
(define_insn "*extend2_mips16e"
2490
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2491
        (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
2492
  "GENERATE_MIPS16E"
2493
  "@
2494
   se\t%0
2495
   l\t%0,%1"
2496
  [(set_attr "type" "arith,load")
2497
   (set_attr "mode" "")])
2498
 
2499
(define_insn_and_split "*extend2"
2500
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2501
        (sign_extend:GPR
2502
             (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2503
  "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2504
  "@
2505
   #
2506
   l\t%0,%1"
2507
  "&& reload_completed && REG_P (operands[1])"
2508
  [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
2509
   (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
2510
{
2511
  operands[1] = gen_lowpart (mode, operands[1]);
2512
  operands[2] = GEN_INT (GET_MODE_BITSIZE (mode)
2513
                         - GET_MODE_BITSIZE (mode));
2514
}
2515
  [(set_attr "type" "arith,load")
2516
   (set_attr "mode" "")
2517
   (set_attr "length" "8,*")])
2518
 
2519
(define_insn "*extend2_se"
2520
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2521
        (sign_extend:GPR
2522
             (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2523
  "ISA_HAS_SEB_SEH"
2524
  "@
2525
   se\t%0,%1
2526
   l\t%0,%1"
2527
  [(set_attr "type" "arith,load")
2528
   (set_attr "mode" "")])
2529
 
2530
;; This pattern generates the same code as extendqisi2; split it into
2531
;; that form after reload.
2532
(define_insn_and_split "extendqihi2"
2533
  [(set (match_operand:HI 0 "register_operand" "=d,d")
2534
        (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2535
  ""
2536
  "#"
2537
  "reload_completed"
2538
  [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
2539
  { operands[0] = gen_lowpart (SImode, operands[0]); }
2540
  [(set_attr "type" "arith,load")
2541
   (set_attr "mode" "SI")
2542
   (set_attr "length" "8,*")])
2543
 
2544
(define_insn "extendsfdf2"
2545
  [(set (match_operand:DF 0 "register_operand" "=f")
2546
        (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2547
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2548
  "cvt.d.s\t%0,%1"
2549
  [(set_attr "type"     "fcvt")
2550
   (set_attr "cnv_mode" "S2D")
2551
   (set_attr "mode"     "DF")])
2552
 
2553
;;
2554
;;  ....................
2555
;;
2556
;;      CONVERSIONS
2557
;;
2558
;;  ....................
2559
 
2560
(define_expand "fix_truncdfsi2"
2561
  [(set (match_operand:SI 0 "register_operand")
2562
        (fix:SI (match_operand:DF 1 "register_operand")))]
2563
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2564
{
2565
  if (!ISA_HAS_TRUNC_W)
2566
    {
2567
      emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2568
      DONE;
2569
    }
2570
})
2571
 
2572
(define_insn "fix_truncdfsi2_insn"
2573
  [(set (match_operand:SI 0 "register_operand" "=f")
2574
        (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2575
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2576
  "trunc.w.d %0,%1"
2577
  [(set_attr "type"     "fcvt")
2578
   (set_attr "mode"     "DF")
2579
   (set_attr "cnv_mode" "D2I")
2580
   (set_attr "length"   "4")])
2581
 
2582
(define_insn "fix_truncdfsi2_macro"
2583
  [(set (match_operand:SI 0 "register_operand" "=f")
2584
        (fix:SI (match_operand:DF 1 "register_operand" "f")))
2585
   (clobber (match_scratch:DF 2 "=d"))]
2586
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2587
{
2588
  if (set_nomacro)
2589
    return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2590
  else
2591
    return "trunc.w.d %0,%1,%2";
2592
}
2593
  [(set_attr "type"     "fcvt")
2594
   (set_attr "mode"     "DF")
2595
   (set_attr "cnv_mode" "D2I")
2596
   (set_attr "length"   "36")])
2597
 
2598
(define_expand "fix_truncsfsi2"
2599
  [(set (match_operand:SI 0 "register_operand")
2600
        (fix:SI (match_operand:SF 1 "register_operand")))]
2601
  "TARGET_HARD_FLOAT"
2602
{
2603
  if (!ISA_HAS_TRUNC_W)
2604
    {
2605
      emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2606
      DONE;
2607
    }
2608
})
2609
 
2610
(define_insn "fix_truncsfsi2_insn"
2611
  [(set (match_operand:SI 0 "register_operand" "=f")
2612
        (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2613
  "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2614
  "trunc.w.s %0,%1"
2615
  [(set_attr "type"     "fcvt")
2616
   (set_attr "mode"     "SF")
2617
   (set_attr "cnv_mode" "S2I")
2618
   (set_attr "length"   "4")])
2619
 
2620
(define_insn "fix_truncsfsi2_macro"
2621
  [(set (match_operand:SI 0 "register_operand" "=f")
2622
        (fix:SI (match_operand:SF 1 "register_operand" "f")))
2623
   (clobber (match_scratch:SF 2 "=d"))]
2624
  "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2625
{
2626
  if (set_nomacro)
2627
    return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2628
  else
2629
    return "trunc.w.s %0,%1,%2";
2630
}
2631
  [(set_attr "type"     "fcvt")
2632
   (set_attr "mode"     "SF")
2633
   (set_attr "cnv_mode" "S2I")
2634
   (set_attr "length"   "36")])
2635
 
2636
 
2637
(define_insn "fix_truncdfdi2"
2638
  [(set (match_operand:DI 0 "register_operand" "=f")
2639
        (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2640
  "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2641
  "trunc.l.d %0,%1"
2642
  [(set_attr "type"     "fcvt")
2643
   (set_attr "mode"     "DF")
2644
   (set_attr "cnv_mode" "D2I")
2645
   (set_attr "length"   "4")])
2646
 
2647
 
2648
(define_insn "fix_truncsfdi2"
2649
  [(set (match_operand:DI 0 "register_operand" "=f")
2650
        (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2651
  "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2652
  "trunc.l.s %0,%1"
2653
  [(set_attr "type"     "fcvt")
2654
   (set_attr "mode"     "SF")
2655
   (set_attr "cnv_mode" "S2I")
2656
   (set_attr "length"   "4")])
2657
 
2658
 
2659
(define_insn "floatsidf2"
2660
  [(set (match_operand:DF 0 "register_operand" "=f")
2661
        (float:DF (match_operand:SI 1 "register_operand" "f")))]
2662
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2663
  "cvt.d.w\t%0,%1"
2664
  [(set_attr "type"     "fcvt")
2665
   (set_attr "mode"     "DF")
2666
   (set_attr "cnv_mode" "I2D")
2667
   (set_attr "length"   "4")])
2668
 
2669
 
2670
(define_insn "floatdidf2"
2671
  [(set (match_operand:DF 0 "register_operand" "=f")
2672
        (float:DF (match_operand:DI 1 "register_operand" "f")))]
2673
  "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2674
  "cvt.d.l\t%0,%1"
2675
  [(set_attr "type"     "fcvt")
2676
   (set_attr "mode"     "DF")
2677
   (set_attr "cnv_mode" "I2D")
2678
   (set_attr "length"   "4")])
2679
 
2680
 
2681
(define_insn "floatsisf2"
2682
  [(set (match_operand:SF 0 "register_operand" "=f")
2683
        (float:SF (match_operand:SI 1 "register_operand" "f")))]
2684
  "TARGET_HARD_FLOAT"
2685
  "cvt.s.w\t%0,%1"
2686
  [(set_attr "type"     "fcvt")
2687
   (set_attr "mode"     "SF")
2688
   (set_attr "cnv_mode" "I2S")
2689
   (set_attr "length"   "4")])
2690
 
2691
 
2692
(define_insn "floatdisf2"
2693
  [(set (match_operand:SF 0 "register_operand" "=f")
2694
        (float:SF (match_operand:DI 1 "register_operand" "f")))]
2695
  "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2696
  "cvt.s.l\t%0,%1"
2697
  [(set_attr "type"     "fcvt")
2698
   (set_attr "mode"     "SF")
2699
   (set_attr "cnv_mode" "I2S")
2700
   (set_attr "length"   "4")])
2701
 
2702
 
2703
(define_expand "fixuns_truncdfsi2"
2704
  [(set (match_operand:SI 0 "register_operand")
2705
        (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2706
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2707
{
2708
  rtx reg1 = gen_reg_rtx (DFmode);
2709
  rtx reg2 = gen_reg_rtx (DFmode);
2710
  rtx reg3 = gen_reg_rtx (SImode);
2711
  rtx label1 = gen_label_rtx ();
2712
  rtx label2 = gen_label_rtx ();
2713
  REAL_VALUE_TYPE offset;
2714
 
2715
  real_2expN (&offset, 31);
2716
 
2717
  if (reg1)                     /* Turn off complaints about unreached code.  */
2718
    {
2719
      emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2720
      do_pending_stack_adjust ();
2721
 
2722
      emit_insn (gen_cmpdf (operands[1], reg1));
2723
      emit_jump_insn (gen_bge (label1));
2724
 
2725
      emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2726
      emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2727
                                   gen_rtx_LABEL_REF (VOIDmode, label2)));
2728
      emit_barrier ();
2729
 
2730
      emit_label (label1);
2731
      emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2732
      emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2733
                                     (BITMASK_HIGH, SImode)));
2734
 
2735
      emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2736
      emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2737
 
2738
      emit_label (label2);
2739
 
2740
      /* Allow REG_NOTES to be set on last insn (labels don't have enough
2741
         fields, and can't be used for REG_NOTES anyway).  */
2742
      emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2743
      DONE;
2744
    }
2745
})
2746
 
2747
 
2748
(define_expand "fixuns_truncdfdi2"
2749
  [(set (match_operand:DI 0 "register_operand")
2750
        (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
2751
  "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2752
{
2753
  rtx reg1 = gen_reg_rtx (DFmode);
2754
  rtx reg2 = gen_reg_rtx (DFmode);
2755
  rtx reg3 = gen_reg_rtx (DImode);
2756
  rtx label1 = gen_label_rtx ();
2757
  rtx label2 = gen_label_rtx ();
2758
  REAL_VALUE_TYPE offset;
2759
 
2760
  real_2expN (&offset, 63);
2761
 
2762
  emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2763
  do_pending_stack_adjust ();
2764
 
2765
  emit_insn (gen_cmpdf (operands[1], reg1));
2766
  emit_jump_insn (gen_bge (label1));
2767
 
2768
  emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2769
  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2770
                               gen_rtx_LABEL_REF (VOIDmode, label2)));
2771
  emit_barrier ();
2772
 
2773
  emit_label (label1);
2774
  emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2775
  emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2776
  emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2777
 
2778
  emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2779
  emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2780
 
2781
  emit_label (label2);
2782
 
2783
  /* Allow REG_NOTES to be set on last insn (labels don't have enough
2784
     fields, and can't be used for REG_NOTES anyway).  */
2785
  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2786
  DONE;
2787
})
2788
 
2789
 
2790
(define_expand "fixuns_truncsfsi2"
2791
  [(set (match_operand:SI 0 "register_operand")
2792
        (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
2793
  "TARGET_HARD_FLOAT"
2794
{
2795
  rtx reg1 = gen_reg_rtx (SFmode);
2796
  rtx reg2 = gen_reg_rtx (SFmode);
2797
  rtx reg3 = gen_reg_rtx (SImode);
2798
  rtx label1 = gen_label_rtx ();
2799
  rtx label2 = gen_label_rtx ();
2800
  REAL_VALUE_TYPE offset;
2801
 
2802
  real_2expN (&offset, 31);
2803
 
2804
  emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2805
  do_pending_stack_adjust ();
2806
 
2807
  emit_insn (gen_cmpsf (operands[1], reg1));
2808
  emit_jump_insn (gen_bge (label1));
2809
 
2810
  emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2811
  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2812
                               gen_rtx_LABEL_REF (VOIDmode, label2)));
2813
  emit_barrier ();
2814
 
2815
  emit_label (label1);
2816
  emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2817
  emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2818
                                 (BITMASK_HIGH, SImode)));
2819
 
2820
  emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2821
  emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2822
 
2823
  emit_label (label2);
2824
 
2825
  /* Allow REG_NOTES to be set on last insn (labels don't have enough
2826
     fields, and can't be used for REG_NOTES anyway).  */
2827
  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2828
  DONE;
2829
})
2830
 
2831
 
2832
(define_expand "fixuns_truncsfdi2"
2833
  [(set (match_operand:DI 0 "register_operand")
2834
        (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
2835
  "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2836
{
2837
  rtx reg1 = gen_reg_rtx (SFmode);
2838
  rtx reg2 = gen_reg_rtx (SFmode);
2839
  rtx reg3 = gen_reg_rtx (DImode);
2840
  rtx label1 = gen_label_rtx ();
2841
  rtx label2 = gen_label_rtx ();
2842
  REAL_VALUE_TYPE offset;
2843
 
2844
  real_2expN (&offset, 63);
2845
 
2846
  emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2847
  do_pending_stack_adjust ();
2848
 
2849
  emit_insn (gen_cmpsf (operands[1], reg1));
2850
  emit_jump_insn (gen_bge (label1));
2851
 
2852
  emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
2853
  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2854
                               gen_rtx_LABEL_REF (VOIDmode, label2)));
2855
  emit_barrier ();
2856
 
2857
  emit_label (label1);
2858
  emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2859
  emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2860
  emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2861
 
2862
  emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
2863
  emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2864
 
2865
  emit_label (label2);
2866
 
2867
  /* Allow REG_NOTES to be set on last insn (labels don't have enough
2868
     fields, and can't be used for REG_NOTES anyway).  */
2869
  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2870
  DONE;
2871
})
2872
 
2873
;;
2874
;;  ....................
2875
;;
2876
;;      DATA MOVEMENT
2877
;;
2878
;;  ....................
2879
 
2880
;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
2881
 
2882
(define_expand "extv"
2883
  [(set (match_operand 0 "register_operand")
2884
        (sign_extract (match_operand:QI 1 "memory_operand")
2885
                      (match_operand 2 "immediate_operand")
2886
                      (match_operand 3 "immediate_operand")))]
2887
  "!TARGET_MIPS16"
2888
{
2889
  if (mips_expand_unaligned_load (operands[0], operands[1],
2890
                                  INTVAL (operands[2]),
2891
                                  INTVAL (operands[3])))
2892
    DONE;
2893
  else
2894
    FAIL;
2895
})
2896
 
2897
(define_expand "extzv"
2898
  [(set (match_operand 0 "register_operand")
2899
        (zero_extract (match_operand 1 "nonimmediate_operand")
2900
                      (match_operand 2 "immediate_operand")
2901
                      (match_operand 3 "immediate_operand")))]
2902
  "!TARGET_MIPS16"
2903
{
2904
  if (mips_expand_unaligned_load (operands[0], operands[1],
2905
                                  INTVAL (operands[2]),
2906
                                  INTVAL (operands[3])))
2907
    DONE;
2908
  else if (mips_use_ins_ext_p (operands[1], operands[2], operands[3]))
2909
    {
2910
      if (GET_MODE (operands[0]) == DImode)
2911
        emit_insn (gen_extzvdi (operands[0], operands[1], operands[2],
2912
                                operands[3]));
2913
      else
2914
        emit_insn (gen_extzvsi (operands[0], operands[1], operands[2],
2915
                                operands[3]));
2916
      DONE;
2917
    }
2918
  else
2919
    FAIL;
2920
})
2921
 
2922
(define_insn "extzv"
2923
  [(set (match_operand:GPR 0 "register_operand" "=d")
2924
        (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
2925
                          (match_operand:SI 2 "immediate_operand" "I")
2926
                          (match_operand:SI 3 "immediate_operand" "I")))]
2927
  "mips_use_ins_ext_p (operands[1], operands[2], operands[3])"
2928
  "ext\t%0,%1,%3,%2"
2929
  [(set_attr "type"     "arith")
2930
   (set_attr "mode"     "")])
2931
 
2932
 
2933
(define_expand "insv"
2934
  [(set (zero_extract (match_operand 0 "nonimmediate_operand")
2935
                      (match_operand 1 "immediate_operand")
2936
                      (match_operand 2 "immediate_operand"))
2937
        (match_operand 3 "reg_or_0_operand"))]
2938
  "!TARGET_MIPS16"
2939
{
2940
  if (mips_expand_unaligned_store (operands[0], operands[3],
2941
                                   INTVAL (operands[1]),
2942
                                   INTVAL (operands[2])))
2943
    DONE;
2944
  else if (mips_use_ins_ext_p (operands[0], operands[1], operands[2]))
2945
    {
2946
      if (GET_MODE (operands[0]) == DImode)
2947
        emit_insn (gen_insvdi (operands[0], operands[1], operands[2],
2948
                               operands[3]));
2949
      else
2950
        emit_insn (gen_insvsi (operands[0], operands[1], operands[2],
2951
                               operands[3]));
2952
      DONE;
2953
   }
2954
   else
2955
     FAIL;
2956
})
2957
 
2958
(define_insn "insv"
2959
  [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
2960
                          (match_operand:SI 1 "immediate_operand" "I")
2961
                          (match_operand:SI 2 "immediate_operand" "I"))
2962
        (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
2963
  "mips_use_ins_ext_p (operands[0], operands[1], operands[2])"
2964
  "ins\t%0,%z3,%2,%1"
2965
  [(set_attr "type"     "arith")
2966
   (set_attr "mode"     "")])
2967
 
2968
;; Unaligned word moves generated by the bit field patterns.
2969
;;
2970
;; As far as the rtl is concerned, both the left-part and right-part
2971
;; instructions can access the whole field.  However, the real operand
2972
;; refers to just the first or the last byte (depending on endianness).
2973
;; We therefore use two memory operands to each instruction, one to
2974
;; describe the rtl effect and one to use in the assembly output.
2975
;;
2976
;; Operands 0 and 1 are the rtl-level target and source respectively.
2977
;; This allows us to use the standard length calculations for the "load"
2978
;; and "store" type attributes.
2979
 
2980
(define_insn "mov_l"
2981
  [(set (match_operand:GPR 0 "register_operand" "=d")
2982
        (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
2983
                     (match_operand:QI 2 "memory_operand" "m")]
2984
                    UNSPEC_LOAD_LEFT))]
2985
  "!TARGET_MIPS16 && mips_mem_fits_mode_p (mode, operands[1])"
2986
  "l\t%0,%2"
2987
  [(set_attr "type" "load")
2988
   (set_attr "mode" "")])
2989
 
2990
(define_insn "mov_r"
2991
  [(set (match_operand:GPR 0 "register_operand" "=d")
2992
        (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
2993
                     (match_operand:QI 2 "memory_operand" "m")
2994
                     (match_operand:GPR 3 "register_operand" "0")]
2995
                    UNSPEC_LOAD_RIGHT))]
2996
  "!TARGET_MIPS16 && mips_mem_fits_mode_p (mode, operands[1])"
2997
  "r\t%0,%2"
2998
  [(set_attr "type" "load")
2999
   (set_attr "mode" "")])
3000
 
3001
(define_insn "mov_l"
3002
  [(set (match_operand:BLK 0 "memory_operand" "=m")
3003
        (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3004
                     (match_operand:QI 2 "memory_operand" "m")]
3005
                    UNSPEC_STORE_LEFT))]
3006
  "!TARGET_MIPS16 && mips_mem_fits_mode_p (mode, operands[0])"
3007
  "l\t%z1,%2"
3008
  [(set_attr "type" "store")
3009
   (set_attr "mode" "")])
3010
 
3011
(define_insn "mov_r"
3012
  [(set (match_operand:BLK 0 "memory_operand" "+m")
3013
        (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3014
                     (match_operand:QI 2 "memory_operand" "m")
3015
                     (match_dup 0)]
3016
                    UNSPEC_STORE_RIGHT))]
3017
  "!TARGET_MIPS16 && mips_mem_fits_mode_p (mode, operands[0])"
3018
  "r\t%z1,%2"
3019
  [(set_attr "type" "store")
3020
   (set_attr "mode" "")])
3021
 
3022
;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3023
;; The required value is:
3024
;;
3025
;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3026
;;
3027
;; which translates to:
3028
;;
3029
;;      lui     op0,%highest(op1)
3030
;;      daddiu  op0,op0,%higher(op1)
3031
;;      dsll    op0,op0,16
3032
;;      daddiu  op0,op0,%hi(op1)
3033
;;      dsll    op0,op0,16
3034
;;
3035
;; The split is deferred until after flow2 to allow the peephole2 below
3036
;; to take effect.
3037
(define_insn_and_split "*lea_high64"
3038
  [(set (match_operand:DI 0 "register_operand" "=d")
3039
        (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3040
  "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3041
  "#"
3042
  "&& flow2_completed"
3043
  [(set (match_dup 0) (high:DI (match_dup 2)))
3044
   (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3045
   (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3046
   (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3047
   (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3048
{
3049
  operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3050
  operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3051
}
3052
  [(set_attr "length" "20")])
3053
 
3054
;; Use a scratch register to reduce the latency of the above pattern
3055
;; on superscalar machines.  The optimized sequence is:
3056
;;
3057
;;      lui     op1,%highest(op2)
3058
;;      lui     op0,%hi(op2)
3059
;;      daddiu  op1,op1,%higher(op2)
3060
;;      dsll32  op1,op1,0
3061
;;      daddu   op1,op1,op0
3062
(define_peephole2
3063
  [(set (match_operand:DI 1 "register_operand")
3064
        (high:DI (match_operand:DI 2 "general_symbolic_operand")))
3065
   (match_scratch:DI 0 "d")]
3066
  "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3067
  [(set (match_dup 1) (high:DI (match_dup 3)))
3068
   (set (match_dup 0) (high:DI (match_dup 4)))
3069
   (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
3070
   (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
3071
   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
3072
{
3073
  operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
3074
  operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
3075
})
3076
 
3077
;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3078
;; SYMBOL_GENERAL X will take 6 cycles.  This next pattern allows combine
3079
;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3080
;; used once.  We can then use the sequence:
3081
;;
3082
;;      lui     op0,%highest(op1)
3083
;;      lui     op2,%hi(op1)
3084
;;      daddiu  op0,op0,%higher(op1)
3085
;;      daddiu  op2,op2,%lo(op1)
3086
;;      dsll32  op0,op0,0
3087
;;      daddu   op0,op0,op2
3088
;;
3089
;; which takes 4 cycles on most superscalar targets.
3090
(define_insn_and_split "*lea64"
3091
  [(set (match_operand:DI 0 "register_operand" "=d")
3092
        (match_operand:DI 1 "general_symbolic_operand" ""))
3093
   (clobber (match_scratch:DI 2 "=&d"))]
3094
  "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3095
  "#"
3096
  "&& reload_completed"
3097
  [(set (match_dup 0) (high:DI (match_dup 3)))
3098
   (set (match_dup 2) (high:DI (match_dup 4)))
3099
   (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3100
   (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3101
   (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3102
   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3103
{
3104
  operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3105
  operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3106
}
3107
  [(set_attr "length" "24")])
3108
 
3109
;; Insns to fetch a global symbol from a big GOT.
3110
 
3111
(define_insn_and_split "*xgot_hi"
3112
  [(set (match_operand:P 0 "register_operand" "=d")
3113
        (high:P (match_operand:P 1 "global_got_operand" "")))]
3114
  "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3115
  "#"
3116
  "&& reload_completed"
3117
  [(set (match_dup 0) (high:P (match_dup 2)))
3118
   (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3119
{
3120
  operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3121
  operands[3] = pic_offset_table_rtx;
3122
}
3123
  [(set_attr "got" "xgot_high")
3124
   (set_attr "mode" "")])
3125
 
3126
(define_insn_and_split "*xgot_lo"
3127
  [(set (match_operand:P 0 "register_operand" "=d")
3128
        (lo_sum:P (match_operand:P 1 "register_operand" "d")
3129
                  (match_operand:P 2 "global_got_operand" "")))]
3130
  "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3131
  "#"
3132
  "&& reload_completed"
3133
  [(set (match_dup 0)
3134
        (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3135
  { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3136
  [(set_attr "got" "load")
3137
   (set_attr "mode" "")])
3138
 
3139
;; Insns to fetch a global symbol from a normal GOT.
3140
 
3141
(define_insn_and_split "*got_disp"
3142
  [(set (match_operand:P 0 "register_operand" "=d")
3143
        (match_operand:P 1 "global_got_operand" ""))]
3144
  "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3145
  "#"
3146
  "&& reload_completed"
3147
  [(set (match_dup 0)
3148
        (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3149
{
3150
  operands[2] = pic_offset_table_rtx;
3151
  operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3152
}
3153
  [(set_attr "got" "load")
3154
   (set_attr "mode" "")])
3155
 
3156
;; Insns for loading the high part of a local symbol.
3157
 
3158
(define_insn_and_split "*got_page"
3159
  [(set (match_operand:P 0 "register_operand" "=d")
3160
        (high:P (match_operand:P 1 "local_got_operand" "")))]
3161
  "TARGET_EXPLICIT_RELOCS"
3162
  "#"
3163
  "&& reload_completed"
3164
  [(set (match_dup 0)
3165
        (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3166
{
3167
  operands[2] = pic_offset_table_rtx;
3168
  operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3169
}
3170
  [(set_attr "got" "load")
3171
   (set_attr "mode" "")])
3172
 
3173
;; Lower-level instructions for loading an address from the GOT.
3174
;; We could use MEMs, but an unspec gives more optimization
3175
;; opportunities.
3176
 
3177
(define_insn "load_got"
3178
  [(set (match_operand:P 0 "register_operand" "=d")
3179
        (unspec:P [(match_operand:P 1 "register_operand" "d")
3180
                   (match_operand:P 2 "immediate_operand" "")]
3181
                  UNSPEC_LOAD_GOT))]
3182
  ""
3183
  "\t%0,%R2(%1)"
3184
  [(set_attr "type" "load")
3185
   (set_attr "mode" "")
3186
   (set_attr "length" "4")])
3187
 
3188
;; Instructions for adding the low 16 bits of an address to a register.
3189
;; Operand 2 is the address: print_operand works out which relocation
3190
;; should be applied.
3191
 
3192
(define_insn "*low"
3193
  [(set (match_operand:P 0 "register_operand" "=d")
3194
        (lo_sum:P (match_operand:P 1 "register_operand" "d")
3195
                  (match_operand:P 2 "immediate_operand" "")))]
3196
  "!TARGET_MIPS16"
3197
  "addiu\t%0,%1,%R2"
3198
  [(set_attr "type" "arith")
3199
   (set_attr "mode" "")])
3200
 
3201
(define_insn "*low_mips16"
3202
  [(set (match_operand:P 0 "register_operand" "=d")
3203
        (lo_sum:P (match_operand:P 1 "register_operand" "0")
3204
                  (match_operand:P 2 "immediate_operand" "")))]
3205
  "TARGET_MIPS16"
3206
  "addiu\t%0,%R2"
3207
  [(set_attr "type" "arith")
3208
   (set_attr "mode" "")
3209
   (set_attr "length" "8")])
3210
 
3211
;; Allow combine to split complex const_int load sequences, using operand 2
3212
;; to store the intermediate results.  See move_operand for details.
3213
(define_split
3214
  [(set (match_operand:GPR 0 "register_operand")
3215
        (match_operand:GPR 1 "splittable_const_int_operand"))
3216
   (clobber (match_operand:GPR 2 "register_operand"))]
3217
  ""
3218
  [(const_int 0)]
3219
{
3220
  mips_move_integer (operands[0], operands[2], INTVAL (operands[1]));
3221
  DONE;
3222
})
3223
 
3224
;; Likewise, for symbolic operands.
3225
(define_split
3226
  [(set (match_operand:P 0 "register_operand")
3227
        (match_operand:P 1 "splittable_symbolic_operand"))
3228
   (clobber (match_operand:P 2 "register_operand"))]
3229
  ""
3230
  [(set (match_dup 0) (match_dup 1))]
3231
  { operands[1] = mips_split_symbol (operands[2], operands[1]); })
3232
 
3233
;; 64-bit integer moves
3234
 
3235
;; Unlike most other insns, the move insns can't be split with
3236
;; different predicates, because register spilling and other parts of
3237
;; the compiler, have memoized the insn number already.
3238
 
3239
(define_expand "movdi"
3240
  [(set (match_operand:DI 0 "")
3241
        (match_operand:DI 1 ""))]
3242
  ""
3243
{
3244
  if (mips_legitimize_move (DImode, operands[0], operands[1]))
3245
    DONE;
3246
})
3247
 
3248
;; For mips16, we need a special case to handle storing $31 into
3249
;; memory, since we don't have a constraint to match $31.  This
3250
;; instruction can be generated by save_restore_insns.
3251
 
3252
(define_insn "*mov_ra"
3253
  [(set (match_operand:GPR 0 "stack_operand" "=m")
3254
        (reg:GPR 31))]
3255
  "TARGET_MIPS16"
3256
  "\t$31,%0"
3257
  [(set_attr "type" "store")
3258
   (set_attr "mode" "")])
3259
 
3260
(define_insn "*movdi_32bit"
3261
  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*B*C*D,*B*C*D,*d,*m")
3262
        (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
3263
  "!TARGET_64BIT && !TARGET_MIPS16
3264
   && (register_operand (operands[0], DImode)
3265
       || reg_or_0_operand (operands[1], DImode))"
3266
  { return mips_output_move (operands[0], operands[1]); }
3267
  [(set_attr "type"     "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
3268
   (set_attr "mode"     "DI")
3269
   (set_attr "length"   "8,16,*,*,8,8,8,*,8,*")])
3270
 
3271
(define_insn "*movdi_32bit_mips16"
3272
  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3273
        (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3274
  "!TARGET_64BIT && TARGET_MIPS16
3275
   && (register_operand (operands[0], DImode)
3276
       || register_operand (operands[1], DImode))"
3277
  { return mips_output_move (operands[0], operands[1]); }
3278
  [(set_attr "type"     "arith,arith,arith,arith,arith,load,store,mfhilo")
3279
   (set_attr "mode"     "DI")
3280
   (set_attr "length"   "8,8,8,8,12,*,*,8")])
3281
 
3282
(define_insn "*movdi_64bit"
3283
  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*B*C*D,*B*C*D,*d,*m")
3284
        (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J*d,*d,*m,*B*C*D,*B*C*D"))]
3285
  "TARGET_64BIT && !TARGET_MIPS16
3286
   && (register_operand (operands[0], DImode)
3287
       || reg_or_0_operand (operands[1], DImode))"
3288
  { return mips_output_move (operands[0], operands[1]); }
3289
  [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
3290
   (set_attr "mode"     "DI")
3291
   (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3292
 
3293
(define_insn "*movdi_64bit_mips16"
3294
  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3295
        (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3296
  "TARGET_64BIT && TARGET_MIPS16
3297
   && (register_operand (operands[0], DImode)
3298
       || register_operand (operands[1], DImode))"
3299
  { return mips_output_move (operands[0], operands[1]); }
3300
  [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
3301
   (set_attr "mode"     "DI")
3302
   (set_attr_alternative "length"
3303
                [(const_int 4)
3304
                 (const_int 4)
3305
                 (const_int 4)
3306
                 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3307
                               (const_int 4)
3308
                               (const_int 8))
3309
                 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3310
                               (const_int 8)
3311
                               (const_int 12))
3312
                 (const_string "*")
3313
                 (const_string "*")
3314
                 (const_string "*")])])
3315
 
3316
 
3317
;; On the mips16, we can split ld $r,N($r) into an add and a load,
3318
;; when the original load is a 4 byte instruction but the add and the
3319
;; load are 2 2 byte instructions.
3320
 
3321
(define_split
3322
  [(set (match_operand:DI 0 "register_operand")
3323
        (mem:DI (plus:DI (match_dup 0)
3324
                         (match_operand:DI 1 "const_int_operand"))))]
3325
  "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3326
   && !TARGET_DEBUG_D_MODE
3327
   && REG_P (operands[0])
3328
   && M16_REG_P (REGNO (operands[0]))
3329
   && GET_CODE (operands[1]) == CONST_INT
3330
   && ((INTVAL (operands[1]) < 0
3331
        && INTVAL (operands[1]) >= -0x10)
3332
       || (INTVAL (operands[1]) >= 32 * 8
3333
           && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3334
       || (INTVAL (operands[1]) >= 0
3335
           && INTVAL (operands[1]) < 32 * 8
3336
           && (INTVAL (operands[1]) & 7) != 0))"
3337
  [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3338
   (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3339
{
3340
  HOST_WIDE_INT val = INTVAL (operands[1]);
3341
 
3342
  if (val < 0)
3343
    operands[2] = const0_rtx;
3344
  else if (val >= 32 * 8)
3345
    {
3346
      int off = val & 7;
3347
 
3348
      operands[1] = GEN_INT (0x8 + off);
3349
      operands[2] = GEN_INT (val - off - 0x8);
3350
    }
3351
  else
3352
    {
3353
      int off = val & 7;
3354
 
3355
      operands[1] = GEN_INT (off);
3356
      operands[2] = GEN_INT (val - off);
3357
    }
3358
})
3359
 
3360
;; 32-bit Integer moves
3361
 
3362
;; Unlike most other insns, the move insns can't be split with
3363
;; different predicates, because register spilling and other parts of
3364
;; the compiler, have memoized the insn number already.
3365
 
3366
(define_expand "movsi"
3367
  [(set (match_operand:SI 0 "")
3368
        (match_operand:SI 1 ""))]
3369
  ""
3370
{
3371
  if (mips_legitimize_move (SImode, operands[0], operands[1]))
3372
    DONE;
3373
})
3374
 
3375
;; The difference between these two is whether or not ints are allowed
3376
;; in FP registers (off by default, use -mdebugh to enable).
3377
 
3378
(define_insn "*movsi_internal"
3379
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*a,*d,*B*C*D,*B*C*D,*d,*m")
3380
        (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*A,*d,*m,*B*C*D,*B*C*D"))]
3381
  "!TARGET_MIPS16
3382
   && (register_operand (operands[0], SImode)
3383
       || reg_or_0_operand (operands[1], SImode))"
3384
  { return mips_output_move (operands[0], operands[1]); }
3385
  [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,mfhilo,xfer,load,xfer,store")
3386
   (set_attr "mode"     "SI")
3387
   (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")])
3388
 
3389
(define_insn "*movsi_mips16"
3390
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3391
        (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3392
  "TARGET_MIPS16
3393
   && (register_operand (operands[0], SImode)
3394
       || register_operand (operands[1], SImode))"
3395
  { return mips_output_move (operands[0], operands[1]); }
3396
  [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
3397
   (set_attr "mode"     "SI")
3398
   (set_attr_alternative "length"
3399
                [(const_int 4)
3400
                 (const_int 4)
3401
                 (const_int 4)
3402
                 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3403
                               (const_int 4)
3404
                               (const_int 8))
3405
                 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3406
                               (const_int 8)
3407
                               (const_int 12))
3408
                 (const_string "*")
3409
                 (const_string "*")
3410
                 (const_string "*")])])
3411
 
3412
;; On the mips16, we can split lw $r,N($r) into an add and a load,
3413
;; when the original load is a 4 byte instruction but the add and the
3414
;; load are 2 2 byte instructions.
3415
 
3416
(define_split
3417
  [(set (match_operand:SI 0 "register_operand")
3418
        (mem:SI (plus:SI (match_dup 0)
3419
                         (match_operand:SI 1 "const_int_operand"))))]
3420
  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3421
   && REG_P (operands[0])
3422
   && M16_REG_P (REGNO (operands[0]))
3423
   && GET_CODE (operands[1]) == CONST_INT
3424
   && ((INTVAL (operands[1]) < 0
3425
        && INTVAL (operands[1]) >= -0x80)
3426
       || (INTVAL (operands[1]) >= 32 * 4
3427
           && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3428
       || (INTVAL (operands[1]) >= 0
3429
           && INTVAL (operands[1]) < 32 * 4
3430
           && (INTVAL (operands[1]) & 3) != 0))"
3431
  [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3432
   (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3433
{
3434
  HOST_WIDE_INT val = INTVAL (operands[1]);
3435
 
3436
  if (val < 0)
3437
    operands[2] = const0_rtx;
3438
  else if (val >= 32 * 4)
3439
    {
3440
      int off = val & 3;
3441
 
3442
      operands[1] = GEN_INT (0x7c + off);
3443
      operands[2] = GEN_INT (val - off - 0x7c);
3444
    }
3445
  else
3446
    {
3447
      int off = val & 3;
3448
 
3449
      operands[1] = GEN_INT (off);
3450
      operands[2] = GEN_INT (val - off);
3451
    }
3452
})
3453
 
3454
;; On the mips16, we can split a load of certain constants into a load
3455
;; and an add.  This turns a 4 byte instruction into 2 2 byte
3456
;; instructions.
3457
 
3458
(define_split
3459
  [(set (match_operand:SI 0 "register_operand")
3460
        (match_operand:SI 1 "const_int_operand"))]
3461
  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3462
   && REG_P (operands[0])
3463
   && M16_REG_P (REGNO (operands[0]))
3464
   && GET_CODE (operands[1]) == CONST_INT
3465
   && INTVAL (operands[1]) >= 0x100
3466
   && INTVAL (operands[1]) <= 0xff + 0x7f"
3467
  [(set (match_dup 0) (match_dup 1))
3468
   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3469
{
3470
  int val = INTVAL (operands[1]);
3471
 
3472
  operands[1] = GEN_INT (0xff);
3473
  operands[2] = GEN_INT (val - 0xff);
3474
})
3475
 
3476
;; This insn handles moving CCmode values.  It's really just a
3477
;; slightly simplified copy of movsi_internal2, with additional cases
3478
;; to move a condition register to a general register and to move
3479
;; between the general registers and the floating point registers.
3480
 
3481
(define_insn "movcc"
3482
  [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3483
        (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3484
  "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3485
  { return mips_output_move (operands[0], operands[1]); }
3486
  [(set_attr "type"     "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
3487
   (set_attr "mode"     "SI")
3488
   (set_attr "length"   "8,4,*,*,4,4,4,*,*")])
3489
 
3490
;; Reload condition code registers.  reload_incc and reload_outcc
3491
;; both handle moves from arbitrary operands into condition code
3492
;; registers.  reload_incc handles the more common case in which
3493
;; a source operand is constrained to be in a condition-code
3494
;; register, but has not been allocated to one.
3495
;;
3496
;; Sometimes, such as in movcc, we have a CCmode destination whose
3497
;; constraints do not include 'z'.  reload_outcc handles the case
3498
;; when such an operand is allocated to a condition-code register.
3499
;;
3500
;; Note that reloads from a condition code register to some
3501
;; other location can be done using ordinary moves.  Moving
3502
;; into a GPR takes a single movcc, moving elsewhere takes
3503
;; two.  We can leave these cases to the generic reload code.
3504
(define_expand "reload_incc"
3505
  [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3506
        (match_operand:CC 1 "general_operand" ""))
3507
   (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3508
  "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3509
{
3510
  mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3511
  DONE;
3512
})
3513
 
3514
(define_expand "reload_outcc"
3515
  [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3516
        (match_operand:CC 1 "register_operand" ""))
3517
   (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3518
  "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3519
{
3520
  mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3521
  DONE;
3522
})
3523
 
3524
;; MIPS4 supports loading and storing a floating point register from
3525
;; the sum of two general registers.  We use two versions for each of
3526
;; these four instructions: one where the two general registers are
3527
;; SImode, and one where they are DImode.  This is because general
3528
;; registers will be in SImode when they hold 32 bit values, but,
3529
;; since the 32 bit values are always sign extended, the [ls][wd]xc1
3530
;; instructions will still work correctly.
3531
 
3532
;; ??? Perhaps it would be better to support these instructions by
3533
;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
3534
;; these instructions can only be used to load and store floating
3535
;; point registers, that would probably cause trouble in reload.
3536
 
3537
(define_insn "*_"
3538
  [(set (match_operand:ANYF 0 "register_operand" "=f")
3539
        (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3540
                          (match_operand:P 2 "register_operand" "d"))))]
3541
  "ISA_HAS_FP4"
3542
  "\t%0,%1(%2)"
3543
  [(set_attr "type" "fpidxload")
3544
   (set_attr "mode" "")])
3545
 
3546
(define_insn "*_"
3547
  [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3548
                          (match_operand:P 2 "register_operand" "d")))
3549
        (match_operand:ANYF 0 "register_operand" "f"))]
3550
  "ISA_HAS_FP4"
3551
  "\t%0,%1(%2)"
3552
  [(set_attr "type" "fpidxstore")
3553
   (set_attr "mode" "")])
3554
 
3555
;; 16-bit Integer moves
3556
 
3557
;; Unlike most other insns, the move insns can't be split with
3558
;; different predicates, because register spilling and other parts of
3559
;; the compiler, have memoized the insn number already.
3560
;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3561
 
3562
(define_expand "movhi"
3563
  [(set (match_operand:HI 0 "")
3564
        (match_operand:HI 1 ""))]
3565
  ""
3566
{
3567
  if (mips_legitimize_move (HImode, operands[0], operands[1]))
3568
    DONE;
3569
})
3570
 
3571
(define_insn "*movhi_internal"
3572
  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3573
        (match_operand:HI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3574
  "!TARGET_MIPS16
3575
   && (register_operand (operands[0], HImode)
3576
       || reg_or_0_operand (operands[1], HImode))"
3577
  "@
3578
    move\t%0,%1
3579
    li\t%0,%1
3580
    lhu\t%0,%1
3581
    sh\t%z1,%0
3582
    mfc1\t%0,%1
3583
    mtc1\t%1,%0
3584
    mov.s\t%0,%1
3585
    mt%0\t%1"
3586
  [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3587
   (set_attr "mode"     "HI")
3588
   (set_attr "length"   "4,4,*,*,4,4,4,4")])
3589
 
3590
(define_insn "*movhi_mips16"
3591
  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3592
        (match_operand:HI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3593
  "TARGET_MIPS16
3594
   && (register_operand (operands[0], HImode)
3595
       || register_operand (operands[1], HImode))"
3596
  "@
3597
    move\t%0,%1
3598
    move\t%0,%1
3599
    move\t%0,%1
3600
    li\t%0,%1
3601
    #
3602
    lhu\t%0,%1
3603
    sh\t%1,%0"
3604
  [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
3605
   (set_attr "mode"     "HI")
3606
   (set_attr_alternative "length"
3607
                [(const_int 4)
3608
                 (const_int 4)
3609
                 (const_int 4)
3610
                 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3611
                               (const_int 4)
3612
                               (const_int 8))
3613
                 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3614
                               (const_int 8)
3615
                               (const_int 12))
3616
                 (const_string "*")
3617
                 (const_string "*")])])
3618
 
3619
 
3620
;; On the mips16, we can split lh $r,N($r) into an add and a load,
3621
;; when the original load is a 4 byte instruction but the add and the
3622
;; load are 2 2 byte instructions.
3623
 
3624
(define_split
3625
  [(set (match_operand:HI 0 "register_operand")
3626
        (mem:HI (plus:SI (match_dup 0)
3627
                         (match_operand:SI 1 "const_int_operand"))))]
3628
  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3629
   && REG_P (operands[0])
3630
   && M16_REG_P (REGNO (operands[0]))
3631
   && GET_CODE (operands[1]) == CONST_INT
3632
   && ((INTVAL (operands[1]) < 0
3633
        && INTVAL (operands[1]) >= -0x80)
3634
       || (INTVAL (operands[1]) >= 32 * 2
3635
           && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
3636
       || (INTVAL (operands[1]) >= 0
3637
           && INTVAL (operands[1]) < 32 * 2
3638
           && (INTVAL (operands[1]) & 1) != 0))"
3639
  [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3640
   (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
3641
{
3642
  HOST_WIDE_INT val = INTVAL (operands[1]);
3643
 
3644
  if (val < 0)
3645
    operands[2] = const0_rtx;
3646
  else if (val >= 32 * 2)
3647
    {
3648
      int off = val & 1;
3649
 
3650
      operands[1] = GEN_INT (0x7e + off);
3651
      operands[2] = GEN_INT (val - off - 0x7e);
3652
    }
3653
  else
3654
    {
3655
      int off = val & 1;
3656
 
3657
      operands[1] = GEN_INT (off);
3658
      operands[2] = GEN_INT (val - off);
3659
    }
3660
})
3661
 
3662
;; 8-bit Integer moves
3663
 
3664
;; Unlike most other insns, the move insns can't be split with
3665
;; different predicates, because register spilling and other parts of
3666
;; the compiler, have memoized the insn number already.
3667
;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3668
 
3669
(define_expand "movqi"
3670
  [(set (match_operand:QI 0 "")
3671
        (match_operand:QI 1 ""))]
3672
  ""
3673
{
3674
  if (mips_legitimize_move (QImode, operands[0], operands[1]))
3675
    DONE;
3676
})
3677
 
3678
(define_insn "*movqi_internal"
3679
  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3680
        (match_operand:QI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3681
  "!TARGET_MIPS16
3682
   && (register_operand (operands[0], QImode)
3683
       || reg_or_0_operand (operands[1], QImode))"
3684
  "@
3685
    move\t%0,%1
3686
    li\t%0,%1
3687
    lbu\t%0,%1
3688
    sb\t%z1,%0
3689
    mfc1\t%0,%1
3690
    mtc1\t%1,%0
3691
    mov.s\t%0,%1
3692
    mt%0\t%1"
3693
  [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3694
   (set_attr "mode"     "QI")
3695
   (set_attr "length"   "4,4,*,*,4,4,4,4")])
3696
 
3697
(define_insn "*movqi_mips16"
3698
  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3699
        (match_operand:QI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3700
  "TARGET_MIPS16
3701
   && (register_operand (operands[0], QImode)
3702
       || register_operand (operands[1], QImode))"
3703
  "@
3704
    move\t%0,%1
3705
    move\t%0,%1
3706
    move\t%0,%1
3707
    li\t%0,%1
3708
    #
3709
    lbu\t%0,%1
3710
    sb\t%1,%0"
3711
  [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
3712
   (set_attr "mode"     "QI")
3713
   (set_attr "length"   "4,4,4,4,8,*,*")])
3714
 
3715
;; On the mips16, we can split lb $r,N($r) into an add and a load,
3716
;; when the original load is a 4 byte instruction but the add and the
3717
;; load are 2 2 byte instructions.
3718
 
3719
(define_split
3720
  [(set (match_operand:QI 0 "register_operand")
3721
        (mem:QI (plus:SI (match_dup 0)
3722
                         (match_operand:SI 1 "const_int_operand"))))]
3723
  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3724
   && REG_P (operands[0])
3725
   && M16_REG_P (REGNO (operands[0]))
3726
   && GET_CODE (operands[1]) == CONST_INT
3727
   && ((INTVAL (operands[1]) < 0
3728
        && INTVAL (operands[1]) >= -0x80)
3729
       || (INTVAL (operands[1]) >= 32
3730
           && INTVAL (operands[1]) <= 31 + 0x7f))"
3731
  [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3732
   (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
3733
{
3734
  HOST_WIDE_INT val = INTVAL (operands[1]);
3735
 
3736
  if (val < 0)
3737
    operands[2] = const0_rtx;
3738
  else
3739
    {
3740
      operands[1] = GEN_INT (0x7f);
3741
      operands[2] = GEN_INT (val - 0x7f);
3742
    }
3743
})
3744
 
3745
;; 32-bit floating point moves
3746
 
3747
(define_expand "movsf"
3748
  [(set (match_operand:SF 0 "")
3749
        (match_operand:SF 1 ""))]
3750
  ""
3751
{
3752
  if (mips_legitimize_move (SFmode, operands[0], operands[1]))
3753
    DONE;
3754
})
3755
 
3756
(define_insn "*movsf_hardfloat"
3757
  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3758
        (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))]
3759
  "TARGET_HARD_FLOAT
3760
   && (register_operand (operands[0], SFmode)
3761
       || reg_or_0_operand (operands[1], SFmode))"
3762
  { return mips_output_move (operands[0], operands[1]); }
3763
  [(set_attr "type"     "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3764
   (set_attr "mode"     "SF")
3765
   (set_attr "length"   "4,4,*,*,*,4,4,4,*,*")])
3766
 
3767
(define_insn "*movsf_softfloat"
3768
  [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
3769
        (match_operand:SF 1 "move_operand" "Gd,m,d"))]
3770
  "TARGET_SOFT_FLOAT && !TARGET_MIPS16
3771
   && (register_operand (operands[0], SFmode)
3772
       || reg_or_0_operand (operands[1], SFmode))"
3773
  { return mips_output_move (operands[0], operands[1]); }
3774
  [(set_attr "type"     "arith,load,store")
3775
   (set_attr "mode"     "SF")
3776
   (set_attr "length"   "4,*,*")])
3777
 
3778
(define_insn "*movsf_mips16"
3779
  [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
3780
        (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
3781
  "TARGET_MIPS16
3782
   && (register_operand (operands[0], SFmode)
3783
       || register_operand (operands[1], SFmode))"
3784
  { return mips_output_move (operands[0], operands[1]); }
3785
  [(set_attr "type"     "arith,arith,arith,load,store")
3786
   (set_attr "mode"     "SF")
3787
   (set_attr "length"   "4,4,4,*,*")])
3788
 
3789
 
3790
;; 64-bit floating point moves
3791
 
3792
(define_expand "movdf"
3793
  [(set (match_operand:DF 0 "")
3794
        (match_operand:DF 1 ""))]
3795
  ""
3796
{
3797
  if (mips_legitimize_move (DFmode, operands[0], operands[1]))
3798
    DONE;
3799
})
3800
 
3801
(define_insn "*movdf_hardfloat_64bit"
3802
  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3803
        (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3804
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
3805
   && (register_operand (operands[0], DFmode)
3806
       || reg_or_0_operand (operands[1], DFmode))"
3807
  { return mips_output_move (operands[0], operands[1]); }
3808
  [(set_attr "type"     "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3809
   (set_attr "mode"     "DF")
3810
   (set_attr "length"   "4,4,*,*,*,4,4,4,*,*")])
3811
 
3812
(define_insn "*movdf_hardfloat_32bit"
3813
  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3814
        (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3815
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
3816
   && (register_operand (operands[0], DFmode)
3817
       || reg_or_0_operand (operands[1], DFmode))"
3818
  { return mips_output_move (operands[0], operands[1]); }
3819
  [(set_attr "type"     "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3820
   (set_attr "mode"     "DF")
3821
   (set_attr "length"   "4,8,*,*,*,8,8,8,*,*")])
3822
 
3823
(define_insn "*movdf_softfloat"
3824
  [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
3825
        (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
3826
  "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
3827
   && (register_operand (operands[0], DFmode)
3828
       || reg_or_0_operand (operands[1], DFmode))"
3829
  { return mips_output_move (operands[0], operands[1]); }
3830
  [(set_attr "type"     "arith,load,store,xfer,xfer,fmove")
3831
   (set_attr "mode"     "DF")
3832
   (set_attr "length"   "8,*,*,4,4,4")])
3833
 
3834
(define_insn "*movdf_mips16"
3835
  [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
3836
        (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
3837
  "TARGET_MIPS16
3838
   && (register_operand (operands[0], DFmode)
3839
       || register_operand (operands[1], DFmode))"
3840
  { return mips_output_move (operands[0], operands[1]); }
3841
  [(set_attr "type"     "arith,arith,arith,load,store")
3842
   (set_attr "mode"     "DF")
3843
   (set_attr "length"   "8,8,8,*,*")])
3844
 
3845
(define_split
3846
  [(set (match_operand:DI 0 "nonimmediate_operand")
3847
        (match_operand:DI 1 "move_operand"))]
3848
  "reload_completed && !TARGET_64BIT
3849
   && mips_split_64bit_move_p (operands[0], operands[1])"
3850
  [(const_int 0)]
3851
{
3852
  mips_split_64bit_move (operands[0], operands[1]);
3853
  DONE;
3854
})
3855
 
3856
(define_split
3857
  [(set (match_operand:DF 0 "nonimmediate_operand")
3858
        (match_operand:DF 1 "move_operand"))]
3859
  "reload_completed && !TARGET_64BIT
3860
   && mips_split_64bit_move_p (operands[0], operands[1])"
3861
  [(const_int 0)]
3862
{
3863
  mips_split_64bit_move (operands[0], operands[1]);
3864
  DONE;
3865
})
3866
 
3867
;; When generating mips16 code, split moves of negative constants into
3868
;; a positive "li" followed by a negation.
3869
(define_split
3870
  [(set (match_operand 0 "register_operand")
3871
        (match_operand 1 "const_int_operand"))]
3872
  "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
3873
  [(set (match_dup 2)
3874
        (match_dup 3))
3875
   (set (match_dup 2)
3876
        (neg:SI (match_dup 2)))]
3877
{
3878
  operands[2] = gen_lowpart (SImode, operands[0]);
3879
  operands[3] = GEN_INT (-INTVAL (operands[1]));
3880
})
3881
 
3882
;; 64-bit paired-single floating point moves
3883
 
3884
(define_expand "movv2sf"
3885
  [(set (match_operand:V2SF 0)
3886
        (match_operand:V2SF 1))]
3887
  "TARGET_PAIRED_SINGLE_FLOAT"
3888
{
3889
  if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
3890
    DONE;
3891
})
3892
 
3893
(define_insn "movv2sf_hardfloat_64bit"
3894
  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3895
        (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
3896
  "TARGET_PAIRED_SINGLE_FLOAT
3897
   && TARGET_64BIT
3898
   && (register_operand (operands[0], V2SFmode)
3899
       || reg_or_0_operand (operands[1], V2SFmode))"
3900
  { return mips_output_move (operands[0], operands[1]); }
3901
  [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3902
   (set_attr "mode" "SF")
3903
   (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
3904
 
3905
;; The HI and LO registers are not truly independent.  If we move an mthi
3906
;; instruction before an mflo instruction, it will make the result of the
3907
;; mflo unpredictable.  The same goes for mtlo and mfhi.
3908
;;
3909
;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
3910
;; Operand 1 is the register we want, operand 2 is the other one.
3911
;;
3912
;; When generating VR4120 or VR4130 code, we use macc{,hi} and
3913
;; dmacc{,hi} instead of mfhi and mflo.  This avoids both the normal
3914
;; MIPS III hi/lo hazards and the errata related to -mfix-vr4130.
3915
 
3916
(define_expand "mfhilo_"
3917
  [(set (match_operand:GPR 0 "register_operand")
3918
        (unspec:GPR [(match_operand:GPR 1 "register_operand")
3919
                     (match_operand:GPR 2 "register_operand")]
3920
                    UNSPEC_MFHILO))])
3921
 
3922
(define_insn "*mfhilo_"
3923
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
3924
        (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
3925
                     (match_operand:GPR 2 "register_operand" "l,h")]
3926
                    UNSPEC_MFHILO))]
3927
  "!ISA_HAS_MACCHI"
3928
  "mf%1\t%0"
3929
  [(set_attr "type" "mfhilo")
3930
   (set_attr "mode" "")])
3931
 
3932
(define_insn "*mfhilo__macc"
3933
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
3934
        (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
3935
                     (match_operand:GPR 2 "register_operand" "l,h")]
3936
                    UNSPEC_MFHILO))]
3937
  "ISA_HAS_MACCHI"
3938
{
3939
  if (REGNO (operands[1]) == HI_REGNUM)
3940
    return "macchi\t%0,%.,%.";
3941
  else
3942
    return "macc\t%0,%.,%.";
3943
}
3944
  [(set_attr "type" "mfhilo")
3945
   (set_attr "mode" "")])
3946
 
3947
;; Patterns for loading or storing part of a paired floating point
3948
;; register.  We need them because odd-numbered floating-point registers
3949
;; are not fully independent: see mips_split_64bit_move.
3950
 
3951
;; Load the low word of operand 0 with operand 1.
3952
(define_insn "load_df_low"
3953
  [(set (match_operand:DF 0 "register_operand" "=f,f")
3954
        (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
3955
                   UNSPEC_LOAD_DF_LOW))]
3956
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3957
{
3958
  operands[0] = mips_subword (operands[0], 0);
3959
  return mips_output_move (operands[0], operands[1]);
3960
}
3961
  [(set_attr "type"     "xfer,fpload")
3962
   (set_attr "mode"     "SF")])
3963
 
3964
;; Load the high word of operand 0 from operand 1, preserving the value
3965
;; in the low word.
3966
(define_insn "load_df_high"
3967
  [(set (match_operand:DF 0 "register_operand" "=f,f")
3968
        (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
3969
                    (match_operand:DF 2 "register_operand" "0,0")]
3970
                   UNSPEC_LOAD_DF_HIGH))]
3971
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3972
{
3973
  operands[0] = mips_subword (operands[0], 1);
3974
  return mips_output_move (operands[0], operands[1]);
3975
}
3976
  [(set_attr "type"     "xfer,fpload")
3977
   (set_attr "mode"     "SF")])
3978
 
3979
;; Store the high word of operand 1 in operand 0.  The corresponding
3980
;; low-word move is done in the normal way.
3981
(define_insn "store_df_high"
3982
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
3983
        (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
3984
                   UNSPEC_STORE_DF_HIGH))]
3985
  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3986
{
3987
  operands[1] = mips_subword (operands[1], 1);
3988
  return mips_output_move (operands[0], operands[1]);
3989
}
3990
  [(set_attr "type"     "xfer,fpstore")
3991
   (set_attr "mode"     "SF")])
3992
 
3993
;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
3994
;; of _gp from the start of this function.  Operand 1 is the incoming
3995
;; function address.
3996
(define_insn_and_split "loadgp"
3997
  [(unspec_volatile [(match_operand 0 "" "")
3998
                     (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
3999
  "mips_current_loadgp_style () == LOADGP_NEWABI"
4000
  "#"
4001
  ""
4002
  [(set (match_dup 2) (match_dup 3))
4003
   (set (match_dup 2) (match_dup 4))
4004
   (set (match_dup 2) (match_dup 5))]
4005
{
4006
  operands[2] = pic_offset_table_rtx;
4007
  operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4008
  operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4009
  operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4010
}
4011
  [(set_attr "length" "12")])
4012
 
4013
;; Likewise, for -mno-shared code.  Operand 0 is the __gnu_local_gp symbol.
4014
(define_insn_and_split "loadgp_noshared"
4015
  [(unspec_volatile [(match_operand 0 "" "")] UNSPEC_LOADGP)]
4016
  "mips_current_loadgp_style () == LOADGP_ABSOLUTE"
4017
  "#"
4018
  ""
4019
  [(const_int 0)]
4020
{
4021
  emit_move_insn (pic_offset_table_rtx, operands[0]);
4022
  DONE;
4023
}
4024
  [(set_attr "length" "8")])
4025
 
4026
;; The use of gp is hidden when not using explicit relocations.
4027
;; This blockage instruction prevents the gp load from being
4028
;; scheduled after an implicit use of gp.  It also prevents
4029
;; the load from being deleted as dead.
4030
(define_insn "loadgp_blockage"
4031
  [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4032
  ""
4033
  ""
4034
  [(set_attr "type"     "unknown")
4035
   (set_attr "mode"     "none")
4036
   (set_attr "length"   "0")])
4037
 
4038
;; Emit a .cprestore directive, which normally expands to a single store
4039
;; instruction.  Note that we continue to use .cprestore for explicit reloc
4040
;; code so that jals inside inline asms will work correctly.
4041
(define_insn "cprestore"
4042
  [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
4043
                    UNSPEC_CPRESTORE)]
4044
  ""
4045
{
4046
  if (set_nomacro && which_alternative == 1)
4047
    return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4048
  else
4049
    return ".cprestore\t%0";
4050
}
4051
  [(set_attr "type" "store")
4052
   (set_attr "length" "4,12")])
4053
 
4054
;; Block moves, see mips.c for more details.
4055
;; Argument 0 is the destination
4056
;; Argument 1 is the source
4057
;; Argument 2 is the length
4058
;; Argument 3 is the alignment
4059
 
4060
(define_expand "movmemsi"
4061
  [(parallel [(set (match_operand:BLK 0 "general_operand")
4062
                   (match_operand:BLK 1 "general_operand"))
4063
              (use (match_operand:SI 2 ""))
4064
              (use (match_operand:SI 3 "const_int_operand"))])]
4065
  "!TARGET_MIPS16 && !TARGET_MEMCPY"
4066
{
4067
  if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4068
    DONE;
4069
  else
4070
    FAIL;
4071
})
4072
 
4073
;;
4074
;;  ....................
4075
;;
4076
;;      SHIFTS
4077
;;
4078
;;  ....................
4079
 
4080
(define_expand "3"
4081
  [(set (match_operand:GPR 0 "register_operand")
4082
        (any_shift:GPR (match_operand:GPR 1 "register_operand")
4083
                       (match_operand:SI 2 "arith_operand")))]
4084
  ""
4085
{
4086
  /* On the mips16, a shift of more than 8 is a four byte instruction,
4087
     so, for a shift between 8 and 16, it is just as fast to do two
4088
     shifts of 8 or less.  If there is a lot of shifting going on, we
4089
     may win in CSE.  Otherwise combine will put the shifts back
4090
     together again.  This can be called by function_arg, so we must
4091
     be careful not to allocate a new register if we've reached the
4092
     reload pass.  */
4093
  if (TARGET_MIPS16
4094
      && optimize
4095
      && GET_CODE (operands[2]) == CONST_INT
4096
      && INTVAL (operands[2]) > 8
4097
      && INTVAL (operands[2]) <= 16
4098
      && !reload_in_progress
4099
      && !reload_completed)
4100
    {
4101
      rtx temp = gen_reg_rtx (mode);
4102
 
4103
      emit_insn (gen_3 (temp, operands[1], GEN_INT (8)));
4104
      emit_insn (gen_3 (operands[0], temp,
4105
                                     GEN_INT (INTVAL (operands[2]) - 8)));
4106
      DONE;
4107
    }
4108
})
4109
 
4110
(define_insn "*3"
4111
  [(set (match_operand:GPR 0 "register_operand" "=d")
4112
        (any_shift:GPR (match_operand:GPR 1 "register_operand" "d")
4113
                       (match_operand:SI 2 "arith_operand" "dI")))]
4114
  "!TARGET_MIPS16"
4115
{
4116
  if (GET_CODE (operands[2]) == CONST_INT)
4117
    operands[2] = GEN_INT (INTVAL (operands[2])
4118
                           & (GET_MODE_BITSIZE (mode) - 1));
4119
 
4120
  return "\t%0,%1,%2";
4121
}
4122
  [(set_attr "type" "shift")
4123
   (set_attr "mode" "")])
4124
 
4125
(define_insn "*si3_extend"
4126
  [(set (match_operand:DI 0 "register_operand" "=d")
4127
        (sign_extend:DI
4128
           (any_shift:SI (match_operand:SI 1 "register_operand" "d")
4129
                         (match_operand:SI 2 "arith_operand" "dI"))))]
4130
  "TARGET_64BIT && !TARGET_MIPS16"
4131
{
4132
  if (GET_CODE (operands[2]) == CONST_INT)
4133
    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4134
 
4135
  return "\t%0,%1,%2";
4136
}
4137
  [(set_attr "type" "shift")
4138
   (set_attr "mode" "SI")])
4139
 
4140
(define_insn "*si3_mips16"
4141
  [(set (match_operand:SI 0 "register_operand" "=d,d")
4142
        (any_shift:SI (match_operand:SI 1 "register_operand" "0,d")
4143
                      (match_operand:SI 2 "arith_operand" "d,I")))]
4144
  "TARGET_MIPS16"
4145
{
4146
  if (which_alternative == 0)
4147
    return "\t%0,%2";
4148
 
4149
  operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4150
  return "\t%0,%1,%2";
4151
}
4152
  [(set_attr "type" "shift")
4153
   (set_attr "mode" "SI")
4154
   (set_attr_alternative "length"
4155
                [(const_int 4)
4156
                 (if_then_else (match_operand 2 "m16_uimm3_b")
4157
                               (const_int 4)
4158
                               (const_int 8))])])
4159
 
4160
;; We need separate DImode MIPS16 patterns because of the irregularity
4161
;; of right shifts.
4162
(define_insn "*ashldi3_mips16"
4163
  [(set (match_operand:DI 0 "register_operand" "=d,d")
4164
        (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4165
                   (match_operand:SI 2 "arith_operand" "d,I")))]
4166
  "TARGET_64BIT && TARGET_MIPS16"
4167
{
4168
  if (which_alternative == 0)
4169
    return "dsll\t%0,%2";
4170
 
4171
  operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4172
  return "dsll\t%0,%1,%2";
4173
}
4174
  [(set_attr "type" "shift")
4175
   (set_attr "mode" "DI")
4176
   (set_attr_alternative "length"
4177
                [(const_int 4)
4178
                 (if_then_else (match_operand 2 "m16_uimm3_b")
4179
                               (const_int 4)
4180
                               (const_int 8))])])
4181
 
4182
(define_insn "*ashrdi3_mips16"
4183
  [(set (match_operand:DI 0 "register_operand" "=d,d")
4184
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4185
                     (match_operand:SI 2 "arith_operand" "d,I")))]
4186
  "TARGET_64BIT && TARGET_MIPS16"
4187
{
4188
  if (GET_CODE (operands[2]) == CONST_INT)
4189
    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4190
 
4191
  return "dsra\t%0,%2";
4192
}
4193
  [(set_attr "type" "shift")
4194
   (set_attr "mode" "DI")
4195
   (set_attr_alternative "length"
4196
                [(const_int 4)
4197
                 (if_then_else (match_operand 2 "m16_uimm3_b")
4198
                               (const_int 4)
4199
                               (const_int 8))])])
4200
 
4201
(define_insn "*lshrdi3_mips16"
4202
  [(set (match_operand:DI 0 "register_operand" "=d,d")
4203
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4204
                     (match_operand:SI 2 "arith_operand" "d,I")))]
4205
  "TARGET_64BIT && TARGET_MIPS16"
4206
{
4207
  if (GET_CODE (operands[2]) == CONST_INT)
4208
    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4209
 
4210
  return "dsrl\t%0,%2";
4211
}
4212
  [(set_attr "type" "shift")
4213
   (set_attr "mode" "DI")
4214
   (set_attr_alternative "length"
4215
                [(const_int 4)
4216
                 (if_then_else (match_operand 2 "m16_uimm3_b")
4217
                               (const_int 4)
4218
                               (const_int 8))])])
4219
 
4220
;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4221
 
4222
(define_split
4223
  [(set (match_operand:GPR 0 "register_operand")
4224
        (any_shift:GPR (match_operand:GPR 1 "register_operand")
4225
                       (match_operand:GPR 2 "const_int_operand")))]
4226
  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4227
   && GET_CODE (operands[2]) == CONST_INT
4228
   && INTVAL (operands[2]) > 8
4229
   && INTVAL (operands[2]) <= 16"
4230
  [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
4231
   (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
4232
  { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4233
 
4234
;; If we load a byte on the mips16 as a bitfield, the resulting
4235
;; sequence of instructions is too complicated for combine, because it
4236
;; involves four instructions: a load, a shift, a constant load into a
4237
;; register, and an and (the key problem here is that the mips16 does
4238
;; not have and immediate).  We recognize a shift of a load in order
4239
;; to make it simple enough for combine to understand.
4240
;;
4241
;; The length here is the worst case: the length of the split version
4242
;; will be more accurate.
4243
(define_insn_and_split ""
4244
  [(set (match_operand:SI 0 "register_operand" "=d")
4245
        (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4246
                     (match_operand:SI 2 "immediate_operand" "I")))]
4247
  "TARGET_MIPS16"
4248
  "#"
4249
  ""
4250
  [(set (match_dup 0) (match_dup 1))
4251
   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4252
  ""
4253
  [(set_attr "type"     "load")
4254
   (set_attr "mode"     "SI")
4255
   (set_attr "length"   "16")])
4256
 
4257
(define_insn "rotr3"
4258
  [(set (match_operand:GPR 0 "register_operand" "=d")
4259
        (rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
4260
                      (match_operand:SI 2 "arith_operand" "dI")))]
4261
  "ISA_HAS_ROTR_"
4262
{
4263
  if (GET_CODE (operands[2]) == CONST_INT)
4264
    gcc_assert (INTVAL (operands[2]) >= 0
4265
                && INTVAL (operands[2]) < GET_MODE_BITSIZE (mode));
4266
 
4267
  return "ror\t%0,%1,%2";
4268
}
4269
  [(set_attr "type" "shift")
4270
   (set_attr "mode" "")])
4271
 
4272
;;
4273
;;  ....................
4274
;;
4275
;;      COMPARISONS
4276
;;
4277
;;  ....................
4278
 
4279
;; Flow here is rather complex:
4280
;;
4281
;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the arguments
4282
;;      into cmp_operands[] but generates no RTL.
4283
;;
4284
;;  2)  The appropriate branch define_expand is called, which then
4285
;;      creates the appropriate RTL for the comparison and branch.
4286
;;      Different CC modes are used, based on what type of branch is
4287
;;      done, so that we can constrain things appropriately.  There
4288
;;      are assumptions in the rest of GCC that break if we fold the
4289
;;      operands into the branches for integer operations, and use cc0
4290
;;      for floating point, so we use the fp status register instead.
4291
;;      If needed, an appropriate temporary is created to hold the
4292
;;      of the integer compare.
4293
 
4294
(define_expand "cmp"
4295
  [(set (cc0)
4296
        (compare:CC (match_operand:GPR 0 "register_operand")
4297
                    (match_operand:GPR 1 "nonmemory_operand")))]
4298
  ""
4299
{
4300
  cmp_operands[0] = operands[0];
4301
  cmp_operands[1] = operands[1];
4302
  DONE;
4303
})
4304
 
4305
(define_expand "cmp"
4306
  [(set (cc0)
4307
        (compare:CC (match_operand:SCALARF 0 "register_operand")
4308
                    (match_operand:SCALARF 1 "register_operand")))]
4309
  ""
4310
{
4311
  cmp_operands[0] = operands[0];
4312
  cmp_operands[1] = operands[1];
4313
  DONE;
4314
})
4315
 
4316
;;
4317
;;  ....................
4318
;;
4319
;;      CONDITIONAL BRANCHES
4320
;;
4321
;;  ....................
4322
 
4323
;; Conditional branches on floating-point equality tests.
4324
 
4325
(define_insn "*branch_fp"
4326
  [(set (pc)
4327
        (if_then_else
4328
         (match_operator 0 "equality_operator"
4329
                         [(match_operand:CC 2 "register_operand" "z")
4330
                          (const_int 0)])
4331
         (label_ref (match_operand 1 "" ""))
4332
         (pc)))]
4333
  "TARGET_HARD_FLOAT"
4334
{
4335
  return mips_output_conditional_branch (insn, operands,
4336
                                         MIPS_BRANCH ("b%F0", "%Z2%1"),
4337
                                         MIPS_BRANCH ("b%W0", "%Z2%1"));
4338
}
4339
  [(set_attr "type" "branch")
4340
   (set_attr "mode" "none")])
4341
 
4342
(define_insn "*branch_fp_inverted"
4343
  [(set (pc)
4344
        (if_then_else
4345
         (match_operator 0 "equality_operator"
4346
                         [(match_operand:CC 2 "register_operand" "z")
4347
                          (const_int 0)])
4348
         (pc)
4349
         (label_ref (match_operand 1 "" ""))))]
4350
  "TARGET_HARD_FLOAT"
4351
{
4352
  return mips_output_conditional_branch (insn, operands,
4353
                                         MIPS_BRANCH ("b%W0", "%Z2%1"),
4354
                                         MIPS_BRANCH ("b%F0", "%Z2%1"));
4355
}
4356
  [(set_attr "type" "branch")
4357
   (set_attr "mode" "none")])
4358
 
4359
;; Conditional branches on ordered comparisons with zero.
4360
 
4361
(define_insn "*branch_order"
4362
  [(set (pc)
4363
        (if_then_else
4364
         (match_operator 0 "order_operator"
4365
                         [(match_operand:GPR 2 "register_operand" "d")
4366
                          (const_int 0)])
4367
         (label_ref (match_operand 1 "" ""))
4368
         (pc)))]
4369
  "!TARGET_MIPS16"
4370
  { return mips_output_order_conditional_branch (insn, operands, false); }
4371
  [(set_attr "type" "branch")
4372
   (set_attr "mode" "none")])
4373
 
4374
(define_insn "*branch_order_inverted"
4375
  [(set (pc)
4376
        (if_then_else
4377
         (match_operator 0 "order_operator"
4378
                         [(match_operand:GPR 2 "register_operand" "d")
4379
                          (const_int 0)])
4380
         (pc)
4381
         (label_ref (match_operand 1 "" ""))))]
4382
  "!TARGET_MIPS16"
4383
  { return mips_output_order_conditional_branch (insn, operands, true); }
4384
  [(set_attr "type" "branch")
4385
   (set_attr "mode" "none")])
4386
 
4387
;; Conditional branch on equality comparison.
4388
 
4389
(define_insn "*branch_equality"
4390
  [(set (pc)
4391
        (if_then_else
4392
         (match_operator 0 "equality_operator"
4393
                         [(match_operand:GPR 2 "register_operand" "d")
4394
                          (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
4395
         (label_ref (match_operand 1 "" ""))
4396
         (pc)))]
4397
  "!TARGET_MIPS16"
4398
{
4399
  return mips_output_conditional_branch (insn, operands,
4400
                                         MIPS_BRANCH ("b%C0", "%2,%z3,%1"),
4401
                                         MIPS_BRANCH ("b%N0", "%2,%z3,%1"));
4402
}
4403
  [(set_attr "type" "branch")
4404
   (set_attr "mode" "none")])
4405
 
4406
(define_insn "*branch_equality_inverted"
4407
  [(set (pc)
4408
        (if_then_else
4409
         (match_operator 0 "equality_operator"
4410
                         [(match_operand:GPR 2 "register_operand" "d")
4411
                          (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
4412
         (pc)
4413
         (label_ref (match_operand 1 "" ""))))]
4414
  "!TARGET_MIPS16"
4415
{
4416
  return mips_output_conditional_branch (insn, operands,
4417
                                         MIPS_BRANCH ("b%N0", "%2,%z3,%1"),
4418
                                         MIPS_BRANCH ("b%C0", "%2,%z3,%1"));
4419
}
4420
  [(set_attr "type" "branch")
4421
   (set_attr "mode" "none")])
4422
 
4423
;; MIPS16 branches
4424
 
4425
(define_insn "*branch_equality_mips16"
4426
  [(set (pc)
4427
        (if_then_else
4428
         (match_operator 0 "equality_operator"
4429
                         [(match_operand:GPR 1 "register_operand" "d,t")
4430
                          (const_int 0)])
4431
         (match_operand 2 "pc_or_label_operand" "")
4432
         (match_operand 3 "pc_or_label_operand" "")))]
4433
  "TARGET_MIPS16"
4434
{
4435
  if (operands[2] != pc_rtx)
4436
    {
4437
      if (which_alternative == 0)
4438
        return "b%C0z\t%1,%2";
4439
      else
4440
        return "bt%C0z\t%2";
4441
    }
4442
  else
4443
    {
4444
      if (which_alternative == 0)
4445
        return "b%N0z\t%1,%3";
4446
      else
4447
        return "bt%N0z\t%3";
4448
    }
4449
}
4450
  [(set_attr "type" "branch")
4451
   (set_attr "mode" "none")
4452
   (set_attr "length" "8")])
4453
 
4454
(define_expand "b"
4455
  [(set (pc)
4456
        (if_then_else (any_cond:CC (cc0)
4457
                                   (const_int 0))
4458
                      (label_ref (match_operand 0 ""))
4459
                      (pc)))]
4460
  ""
4461
{
4462
  gen_conditional_branch (operands, );
4463
  DONE;
4464
})
4465
 
4466
;; Used to implement built-in functions.
4467
(define_expand "condjump"
4468
  [(set (pc)
4469
        (if_then_else (match_operand 0)
4470
                      (label_ref (match_operand 1))
4471
                      (pc)))])
4472
 
4473
;;
4474
;;  ....................
4475
;;
4476
;;      SETTING A REGISTER FROM A COMPARISON
4477
;;
4478
;;  ....................
4479
 
4480
(define_expand "seq"
4481
  [(set (match_operand:SI 0 "register_operand")
4482
        (eq:SI (match_dup 1)
4483
               (match_dup 2)))]
4484
  ""
4485
  { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
4486
 
4487
(define_insn "*seq_"
4488
  [(set (match_operand:GPR 0 "register_operand" "=d")
4489
        (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4490
                (const_int 0)))]
4491
  "!TARGET_MIPS16"
4492
  "sltu\t%0,%1,1"
4493
  [(set_attr "type" "slt")
4494
   (set_attr "mode" "")])
4495
 
4496
(define_insn "*seq__mips16"
4497
  [(set (match_operand:GPR 0 "register_operand" "=t")
4498
        (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4499
                (const_int 0)))]
4500
  "TARGET_MIPS16"
4501
  "sltu\t%1,1"
4502
  [(set_attr "type" "slt")
4503
   (set_attr "mode" "")])
4504
 
4505
;; "sne" uses sltu instructions in which the first operand is $0.
4506
;; This isn't possible in mips16 code.
4507
 
4508
(define_expand "sne"
4509
  [(set (match_operand:SI 0 "register_operand")
4510
        (ne:SI (match_dup 1)
4511
               (match_dup 2)))]
4512
  "!TARGET_MIPS16"
4513
  { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
4514
 
4515
(define_insn "*sne_"
4516
  [(set (match_operand:GPR 0 "register_operand" "=d")
4517
        (ne:GPR (match_operand:GPR 1 "register_operand" "d")
4518
                (const_int 0)))]
4519
  "!TARGET_MIPS16"
4520
  "sltu\t%0,%.,%1"
4521
  [(set_attr "type" "slt")
4522
   (set_attr "mode" "")])
4523
 
4524
(define_expand "sgt"
4525
  [(set (match_operand:SI 0 "register_operand")
4526
        (gt:SI (match_dup 1)
4527
               (match_dup 2)))]
4528
  ""
4529
  { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
4530
 
4531
(define_insn "*sgt_"
4532
  [(set (match_operand:GPR 0 "register_operand" "=d")
4533
        (gt:GPR (match_operand:GPR 1 "register_operand" "d")
4534
                (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4535
  "!TARGET_MIPS16"
4536
  "slt\t%0,%z2,%1"
4537
  [(set_attr "type" "slt")
4538
   (set_attr "mode" "")])
4539
 
4540
(define_insn "*sgt__mips16"
4541
  [(set (match_operand:GPR 0 "register_operand" "=t")
4542
        (gt:GPR (match_operand:GPR 1 "register_operand" "d")
4543
                (match_operand:GPR 2 "register_operand" "d")))]
4544
  "TARGET_MIPS16"
4545
  "slt\t%2,%1"
4546
  [(set_attr "type" "slt")
4547
   (set_attr "mode" "")])
4548
 
4549
(define_expand "sge"
4550
  [(set (match_operand:SI 0 "register_operand")
4551
        (ge:SI (match_dup 1)
4552
               (match_dup 2)))]
4553
  ""
4554
  { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
4555
 
4556
(define_insn "*sge_"
4557
  [(set (match_operand:GPR 0 "register_operand" "=d")
4558
        (ge:GPR (match_operand:GPR 1 "register_operand" "d")
4559
                (const_int 1)))]
4560
  "!TARGET_MIPS16"
4561
  "slt\t%0,%.,%1"
4562
  [(set_attr "type" "slt")
4563
   (set_attr "mode" "")])
4564
 
4565
(define_expand "slt"
4566
  [(set (match_operand:SI 0 "register_operand")
4567
        (lt:SI (match_dup 1)
4568
               (match_dup 2)))]
4569
  ""
4570
  { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
4571
 
4572
(define_insn "*slt_"
4573
  [(set (match_operand:GPR 0 "register_operand" "=d")
4574
        (lt:GPR (match_operand:GPR 1 "register_operand" "d")
4575
                (match_operand:GPR 2 "arith_operand" "dI")))]
4576
  "!TARGET_MIPS16"
4577
  "slt\t%0,%1,%2"
4578
  [(set_attr "type" "slt")
4579
   (set_attr "mode" "")])
4580
 
4581
(define_insn "*slt__mips16"
4582
  [(set (match_operand:GPR 0 "register_operand" "=t,t")
4583
        (lt:GPR (match_operand:GPR 1 "register_operand" "d,d")
4584
                (match_operand:GPR 2 "arith_operand" "d,I")))]
4585
  "TARGET_MIPS16"
4586
  "slt\t%1,%2"
4587
  [(set_attr "type" "slt")
4588
   (set_attr "mode" "")
4589
   (set_attr_alternative "length"
4590
                [(const_int 4)
4591
                 (if_then_else (match_operand 2 "m16_uimm8_1")
4592
                               (const_int 4)
4593
                               (const_int 8))])])
4594
 
4595
(define_expand "sle"
4596
  [(set (match_operand:SI 0 "register_operand")
4597
        (le:SI (match_dup 1)
4598
               (match_dup 2)))]
4599
  ""
4600
  { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
4601
 
4602
(define_insn "*sle_"
4603
  [(set (match_operand:GPR 0 "register_operand" "=d")
4604
        (le:GPR (match_operand:GPR 1 "register_operand" "d")
4605
                (match_operand:GPR 2 "sle_operand" "")))]
4606
  "!TARGET_MIPS16"
4607
{
4608
  operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4609
  return "slt\t%0,%1,%2";
4610
}
4611
  [(set_attr "type" "slt")
4612
   (set_attr "mode" "")])
4613
 
4614
(define_insn "*sle__mips16"
4615
  [(set (match_operand:GPR 0 "register_operand" "=t")
4616
        (le:GPR (match_operand:GPR 1 "register_operand" "d")
4617
                (match_operand:GPR 2 "sle_operand" "")))]
4618
  "TARGET_MIPS16"
4619
{
4620
  operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4621
  return "slt\t%1,%2";
4622
}
4623
  [(set_attr "type" "slt")
4624
   (set_attr "mode" "")
4625
   (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4626
                                      (const_int 4)
4627
                                      (const_int 8)))])
4628
 
4629
(define_expand "sgtu"
4630
  [(set (match_operand:SI 0 "register_operand")
4631
        (gtu:SI (match_dup 1)
4632
                (match_dup 2)))]
4633
  ""
4634
  { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
4635
 
4636
(define_insn "*sgtu_"
4637
  [(set (match_operand:GPR 0 "register_operand" "=d")
4638
        (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4639
                 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4640
  "!TARGET_MIPS16"
4641
  "sltu\t%0,%z2,%1"
4642
  [(set_attr "type" "slt")
4643
   (set_attr "mode" "")])
4644
 
4645
(define_insn "*sgtu__mips16"
4646
  [(set (match_operand:GPR 0 "register_operand" "=t")
4647
        (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4648
                 (match_operand:GPR 2 "register_operand" "d")))]
4649
  "TARGET_MIPS16"
4650
  "sltu\t%2,%1"
4651
  [(set_attr "type" "slt")
4652
   (set_attr "mode" "")])
4653
 
4654
(define_expand "sgeu"
4655
  [(set (match_operand:SI 0 "register_operand")
4656
        (geu:SI (match_dup 1)
4657
                (match_dup 2)))]
4658
  ""
4659
  { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
4660
 
4661
(define_insn "*sge_"
4662
  [(set (match_operand:GPR 0 "register_operand" "=d")
4663
        (geu:GPR (match_operand:GPR 1 "register_operand" "d")
4664
                 (const_int 1)))]
4665
  "!TARGET_MIPS16"
4666
  "sltu\t%0,%.,%1"
4667
  [(set_attr "type" "slt")
4668
   (set_attr "mode" "")])
4669
 
4670
(define_expand "sltu"
4671
  [(set (match_operand:SI 0 "register_operand")
4672
        (ltu:SI (match_dup 1)
4673
                (match_dup 2)))]
4674
  ""
4675
  { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
4676
 
4677
(define_insn "*sltu_"
4678
  [(set (match_operand:GPR 0 "register_operand" "=d")
4679
        (ltu:GPR (match_operand:GPR 1 "register_operand" "d")
4680
                 (match_operand:GPR 2 "arith_operand" "dI")))]
4681
  "!TARGET_MIPS16"
4682
  "sltu\t%0,%1,%2"
4683
  [(set_attr "type" "slt")
4684
   (set_attr "mode" "")])
4685
 
4686
(define_insn "*sltu__mips16"
4687
  [(set (match_operand:GPR 0 "register_operand" "=t,t")
4688
        (ltu:GPR (match_operand:GPR 1 "register_operand" "d,d")
4689
                 (match_operand:GPR 2 "arith_operand" "d,I")))]
4690
  "TARGET_MIPS16"
4691
  "sltu\t%1,%2"
4692
  [(set_attr "type" "slt")
4693
   (set_attr "mode" "")
4694
   (set_attr_alternative "length"
4695
                [(const_int 4)
4696
                 (if_then_else (match_operand 2 "m16_uimm8_1")
4697
                               (const_int 4)
4698
                               (const_int 8))])])
4699
 
4700
(define_expand "sleu"
4701
  [(set (match_operand:SI 0 "register_operand")
4702
        (leu:SI (match_dup 1)
4703
                (match_dup 2)))]
4704
  ""
4705
  { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
4706
 
4707
(define_insn "*sleu_"
4708
  [(set (match_operand:GPR 0 "register_operand" "=d")
4709
        (leu:GPR (match_operand:GPR 1 "register_operand" "d")
4710
                 (match_operand:GPR 2 "sleu_operand" "")))]
4711
  "!TARGET_MIPS16"
4712
{
4713
  operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4714
  return "sltu\t%0,%1,%2";
4715
}
4716
  [(set_attr "type" "slt")
4717
   (set_attr "mode" "")])
4718
 
4719
(define_insn "*sleu__mips16"
4720
  [(set (match_operand:GPR 0 "register_operand" "=t")
4721
        (leu:GPR (match_operand:GPR 1 "register_operand" "d")
4722
                 (match_operand:GPR 2 "sleu_operand" "")))]
4723
  "TARGET_MIPS16"
4724
{
4725
  operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4726
  return "sltu\t%1,%2";
4727
}
4728
  [(set_attr "type" "slt")
4729
   (set_attr "mode" "")
4730
   (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4731
                                      (const_int 4)
4732
                                      (const_int 8)))])
4733
 
4734
;;
4735
;;  ....................
4736
;;
4737
;;      FLOATING POINT COMPARISONS
4738
;;
4739
;;  ....................
4740
 
4741
(define_insn "s_"
4742
  [(set (match_operand:CC 0 "register_operand" "=z")
4743
        (fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
4744
                  (match_operand:SCALARF 2 "register_operand" "f")))]
4745
  ""
4746
  "c..\t%Z0%1,%2"
4747
  [(set_attr "type" "fcmp")
4748
   (set_attr "mode" "FPSW")])
4749
 
4750
(define_insn "s_"
4751
  [(set (match_operand:CC 0 "register_operand" "=z")
4752
        (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
4753
                          (match_operand:SCALARF 2 "register_operand" "f")))]
4754
  ""
4755
  "c..\t%Z0%2,%1"
4756
  [(set_attr "type" "fcmp")
4757
   (set_attr "mode" "FPSW")])
4758
 
4759
;;
4760
;;  ....................
4761
;;
4762
;;      UNCONDITIONAL BRANCHES
4763
;;
4764
;;  ....................
4765
 
4766
;; Unconditional branches.
4767
 
4768
(define_insn "jump"
4769
  [(set (pc)
4770
        (label_ref (match_operand 0 "" "")))]
4771
  "!TARGET_MIPS16"
4772
{
4773
  if (flag_pic)
4774
    {
4775
      if (get_attr_length (insn) <= 8)
4776
        return "%*b\t%l0%/";
4777
      else
4778
        {
4779
          output_asm_insn (mips_output_load_label (), operands);
4780
          return "%*jr\t%@%/%]";
4781
        }
4782
    }
4783
  else
4784
    return "%*j\t%l0%/";
4785
}
4786
  [(set_attr "type"     "jump")
4787
   (set_attr "mode"     "none")
4788
   (set (attr "length")
4789
        ;; We can't use `j' when emitting PIC.  Emit a branch if it's
4790
        ;; in range, otherwise load the address of the branch target into
4791
        ;; $at and then jump to it.
4792
        (if_then_else
4793
         (ior (eq (symbol_ref "flag_pic") (const_int 0))
4794
              (lt (abs (minus (match_dup 0)
4795
                              (plus (pc) (const_int 4))))
4796
                  (const_int 131072)))
4797
         (const_int 4) (const_int 16)))])
4798
 
4799
;; We need a different insn for the mips16, because a mips16 branch
4800
;; does not have a delay slot.
4801
 
4802
(define_insn ""
4803
  [(set (pc)
4804
        (label_ref (match_operand 0 "" "")))]
4805
  "TARGET_MIPS16"
4806
  "b\t%l0"
4807
  [(set_attr "type"     "branch")
4808
   (set_attr "mode"     "none")
4809
   (set_attr "length"   "8")])
4810
 
4811
(define_expand "indirect_jump"
4812
  [(set (pc) (match_operand 0 "register_operand"))]
4813
  ""
4814
{
4815
  operands[0] = force_reg (Pmode, operands[0]);
4816
  if (Pmode == SImode)
4817
    emit_jump_insn (gen_indirect_jumpsi (operands[0]));
4818
  else
4819
    emit_jump_insn (gen_indirect_jumpdi (operands[0]));
4820
  DONE;
4821
})
4822
 
4823
(define_insn "indirect_jump"
4824
  [(set (pc) (match_operand:P 0 "register_operand" "d"))]
4825
  ""
4826
  "%*j\t%0%/"
4827
  [(set_attr "type" "jump")
4828
   (set_attr "mode" "none")])
4829
 
4830
(define_expand "tablejump"
4831
  [(set (pc)
4832
        (match_operand 0 "register_operand"))
4833
   (use (label_ref (match_operand 1 "")))]
4834
  ""
4835
{
4836
  if (TARGET_MIPS16)
4837
    operands[0] = expand_binop (Pmode, add_optab,
4838
                                convert_to_mode (Pmode, operands[0], false),
4839
                                gen_rtx_LABEL_REF (Pmode, operands[1]),
4840
                                0, 0, OPTAB_WIDEN);
4841
  else if (TARGET_GPWORD)
4842
    operands[0] = expand_binop (Pmode, add_optab, operands[0],
4843
                                pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
4844
 
4845
  if (Pmode == SImode)
4846
    emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
4847
  else
4848
    emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
4849
  DONE;
4850
})
4851
 
4852
(define_insn "tablejump"
4853
  [(set (pc)
4854
        (match_operand:P 0 "register_operand" "d"))
4855
   (use (label_ref (match_operand 1 "" "")))]
4856
  ""
4857
  "%*j\t%0%/"
4858
  [(set_attr "type" "jump")
4859
   (set_attr "mode" "none")])
4860
 
4861
;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
4862
;; While it is possible to either pull it off the stack (in the
4863
;; o32 case) or recalculate it given t9 and our target label,
4864
;; it takes 3 or 4 insns to do so.
4865
 
4866
(define_expand "builtin_setjmp_setup"
4867
  [(use (match_operand 0 "register_operand"))]
4868
  "TARGET_ABICALLS"
4869
{
4870
  rtx addr;
4871
 
4872
  addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
4873
  emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
4874
  DONE;
4875
})
4876
 
4877
;; Restore the gp that we saved above.  Despite the earlier comment, it seems
4878
;; that older code did recalculate the gp from $25.  Continue to jump through
4879
;; $25 for compatibility (we lose nothing by doing so).
4880
 
4881
(define_expand "builtin_longjmp"
4882
  [(use (match_operand 0 "register_operand"))]
4883
  "TARGET_ABICALLS"
4884
{
4885
  /* The elements of the buffer are, in order:  */
4886
  int W = GET_MODE_SIZE (Pmode);
4887
  rtx fp = gen_rtx_MEM (Pmode, operands[0]);
4888
  rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
4889
  rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
4890
  rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
4891
  rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
4892
  /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
4893
     The target is bound to be using $28 as the global pointer
4894
     but the current function might not be.  */
4895
  rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
4896
 
4897
  /* This bit is similar to expand_builtin_longjmp except that it
4898
     restores $gp as well.  */
4899
  emit_move_insn (hard_frame_pointer_rtx, fp);
4900
  emit_move_insn (pv, lab);
4901
  emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
4902
  emit_move_insn (gp, gpv);
4903
  emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
4904
  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4905
  emit_insn (gen_rtx_USE (VOIDmode, gp));
4906
  emit_indirect_jump (pv);
4907
  DONE;
4908
})
4909
 
4910
;;
4911
;;  ....................
4912
;;
4913
;;      Function prologue/epilogue
4914
;;
4915
;;  ....................
4916
;;
4917
 
4918
(define_expand "prologue"
4919
  [(const_int 1)]
4920
  ""
4921
{
4922
  mips_expand_prologue ();
4923
  DONE;
4924
})
4925
 
4926
;; Block any insns from being moved before this point, since the
4927
;; profiling call to mcount can use various registers that aren't
4928
;; saved or used to pass arguments.
4929
 
4930
(define_insn "blockage"
4931
  [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
4932
  ""
4933
  ""
4934
  [(set_attr "type"     "unknown")
4935
   (set_attr "mode"     "none")
4936
   (set_attr "length"   "0")])
4937
 
4938
(define_expand "epilogue"
4939
  [(const_int 2)]
4940
  ""
4941
{
4942
  mips_expand_epilogue (false);
4943
  DONE;
4944
})
4945
 
4946
(define_expand "sibcall_epilogue"
4947
  [(const_int 2)]
4948
  ""
4949
{
4950
  mips_expand_epilogue (true);
4951
  DONE;
4952
})
4953
 
4954
;; Trivial return.  Make it look like a normal return insn as that
4955
;; allows jump optimizations to work better.
4956
 
4957
(define_insn "return"
4958
  [(return)]
4959
  "mips_can_use_return_insn ()"
4960
  "%*j\t$31%/"
4961
  [(set_attr "type"     "jump")
4962
   (set_attr "mode"     "none")])
4963
 
4964
;; Normal return.
4965
 
4966
(define_insn "return_internal"
4967
  [(return)
4968
   (use (match_operand 0 "pmode_register_operand" ""))]
4969
  ""
4970
  "%*j\t%0%/"
4971
  [(set_attr "type"     "jump")
4972
   (set_attr "mode"     "none")])
4973
 
4974
;; This is used in compiling the unwind routines.
4975
(define_expand "eh_return"
4976
  [(use (match_operand 0 "general_operand"))]
4977
  ""
4978
{
4979
  enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
4980
 
4981
  if (GET_MODE (operands[0]) != gpr_mode)
4982
    operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
4983
  if (TARGET_64BIT)
4984
    emit_insn (gen_eh_set_lr_di (operands[0]));
4985
  else
4986
    emit_insn (gen_eh_set_lr_si (operands[0]));
4987
 
4988
  DONE;
4989
})
4990
 
4991
;; Clobber the return address on the stack.  We can't expand this
4992
;; until we know where it will be put in the stack frame.
4993
 
4994
(define_insn "eh_set_lr_si"
4995
  [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
4996
   (clobber (match_scratch:SI 1 "=&d"))]
4997
  "! TARGET_64BIT"
4998
  "#")
4999
 
5000
(define_insn "eh_set_lr_di"
5001
  [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5002
   (clobber (match_scratch:DI 1 "=&d"))]
5003
  "TARGET_64BIT"
5004
  "#")
5005
 
5006
(define_split
5007
  [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
5008
   (clobber (match_scratch 1))]
5009
  "reload_completed && !TARGET_DEBUG_D_MODE"
5010
  [(const_int 0)]
5011
{
5012
  mips_set_return_address (operands[0], operands[1]);
5013
  DONE;
5014
})
5015
 
5016
(define_insn_and_split "exception_receiver"
5017
  [(set (reg:SI 28)
5018
        (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
5019
  "TARGET_ABICALLS && TARGET_OLDABI"
5020
  "#"
5021
  "&& reload_completed"
5022
  [(const_int 0)]
5023
{
5024
  mips_restore_gp ();
5025
  DONE;
5026
}
5027
  [(set_attr "type"   "load")
5028
   (set_attr "length" "12")])
5029
 
5030
;;
5031
;;  ....................
5032
;;
5033
;;      FUNCTION CALLS
5034
;;
5035
;;  ....................
5036
 
5037
;; Instructions to load a call address from the GOT.  The address might
5038
;; point to a function or to a lazy binding stub.  In the latter case,
5039
;; the stub will use the dynamic linker to resolve the function, which
5040
;; in turn will change the GOT entry to point to the function's real
5041
;; address.
5042
;;
5043
;; This means that every call, even pure and constant ones, can
5044
;; potentially modify the GOT entry.  And once a stub has been called,
5045
;; we must not call it again.
5046
;;
5047
;; We represent this restriction using an imaginary fixed register that
5048
;; acts like a GOT version number.  By making the register call-clobbered,
5049
;; we tell the target-independent code that the address could be changed
5050
;; by any call insn.
5051
(define_insn "load_call"
5052
  [(set (match_operand:P 0 "register_operand" "=c")
5053
        (unspec:P [(match_operand:P 1 "register_operand" "r")
5054
                   (match_operand:P 2 "immediate_operand" "")
5055
                   (reg:P FAKE_CALL_REGNO)]
5056
                  UNSPEC_LOAD_CALL))]
5057
  "TARGET_ABICALLS"
5058
  "\t%0,%R2(%1)"
5059
  [(set_attr "type" "load")
5060
   (set_attr "mode" "")
5061
   (set_attr "length" "4")])
5062
 
5063
;; Sibling calls.  All these patterns use jump instructions.
5064
 
5065
;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
5066
;; addresses if a direct jump is acceptable.  Since the 'S' constraint
5067
;; is defined in terms of call_insn_operand, the same is true of the
5068
;; constraints.
5069
 
5070
;; When we use an indirect jump, we need a register that will be
5071
;; preserved by the epilogue.  Since TARGET_ABICALLS forces us to
5072
;; use $25 for this purpose -- and $25 is never clobbered by the
5073
;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
5074
 
5075
(define_expand "sibcall"
5076
  [(parallel [(call (match_operand 0 "")
5077
                    (match_operand 1 ""))
5078
              (use (match_operand 2 ""))        ;; next_arg_reg
5079
              (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
5080
  "TARGET_SIBCALLS"
5081
{
5082
  mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
5083
  DONE;
5084
})
5085
 
5086
(define_insn "sibcall_internal"
5087
  [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
5088
         (match_operand 1 "" ""))]
5089
  "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5090
  { return MIPS_CALL ("j", operands, 0); }
5091
  [(set_attr "type" "call")])
5092
 
5093
(define_expand "sibcall_value"
5094
  [(parallel [(set (match_operand 0 "")
5095
                   (call (match_operand 1 "")
5096
                         (match_operand 2 "")))
5097
              (use (match_operand 3 ""))])]             ;; next_arg_reg
5098
  "TARGET_SIBCALLS"
5099
{
5100
  mips_expand_call (operands[0], XEXP (operands[1], 0),
5101
                    operands[2], operands[3], true);
5102
  DONE;
5103
})
5104
 
5105
(define_insn "sibcall_value_internal"
5106
  [(set (match_operand 0 "register_operand" "=df,df")
5107
        (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5108
              (match_operand 2 "" "")))]
5109
  "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5110
  { return MIPS_CALL ("j", operands, 1); }
5111
  [(set_attr "type" "call")])
5112
 
5113
(define_insn "sibcall_value_multiple_internal"
5114
  [(set (match_operand 0 "register_operand" "=df,df")
5115
        (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5116
              (match_operand 2 "" "")))
5117
   (set (match_operand 3 "register_operand" "=df,df")
5118
        (call (mem:SI (match_dup 1))
5119
              (match_dup 2)))]
5120
  "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5121
  { return MIPS_CALL ("j", operands, 1); }
5122
  [(set_attr "type" "call")])
5123
 
5124
(define_expand "call"
5125
  [(parallel [(call (match_operand 0 "")
5126
                    (match_operand 1 ""))
5127
              (use (match_operand 2 ""))        ;; next_arg_reg
5128
              (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
5129
  ""
5130
{
5131
  mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
5132
  DONE;
5133
})
5134
 
5135
;; This instruction directly corresponds to an assembly-language "jal".
5136
;; There are four cases:
5137
;;
5138
;;    - -mno-abicalls:
5139
;;        Both symbolic and register destinations are OK.  The pattern
5140
;;        always expands to a single mips instruction.
5141
;;
5142
;;    - -mabicalls/-mno-explicit-relocs:
5143
;;        Again, both symbolic and register destinations are OK.
5144
;;        The call is treated as a multi-instruction black box.
5145
;;
5146
;;    - -mabicalls/-mexplicit-relocs with n32 or n64:
5147
;;        Only "jal $25" is allowed.  This expands to a single "jalr $25"
5148
;;        instruction.
5149
;;
5150
;;    - -mabicalls/-mexplicit-relocs with o32 or o64:
5151
;;        Only "jal $25" is allowed.  The call is actually two instructions:
5152
;;        "jalr $25" followed by an insn to reload $gp.
5153
;;
5154
;; In the last case, we can generate the individual instructions with
5155
;; a define_split.  There are several things to be wary of:
5156
;;
5157
;;   - We can't expose the load of $gp before reload.  If we did,
5158
;;     it might get removed as dead, but reload can introduce new
5159
;;     uses of $gp by rematerializing constants.
5160
;;
5161
;;   - We shouldn't restore $gp after calls that never return.
5162
;;     It isn't valid to insert instructions between a noreturn
5163
;;     call and the following barrier.
5164
;;
5165
;;   - The splitter deliberately changes the liveness of $gp.  The unsplit
5166
;;     instruction preserves $gp and so have no effect on its liveness.
5167
;;     But once we generate the separate insns, it becomes obvious that
5168
;;     $gp is not live on entry to the call.
5169
;;
5170
;; ??? The operands[2] = insn check is a hack to make the original insn
5171
;; available to the splitter.
5172
(define_insn_and_split "call_internal"
5173
  [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
5174
         (match_operand 1 "" ""))
5175
   (clobber (reg:SI 31))]
5176
  ""
5177
  { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0); }
5178
  "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
5179
  [(const_int 0)]
5180
{
5181
  emit_call_insn (gen_call_split (operands[0], operands[1]));
5182
  if (!find_reg_note (operands[2], REG_NORETURN, 0))
5183
    mips_restore_gp ();
5184
  DONE;
5185
}
5186
  [(set_attr "jal" "indirect,direct")
5187
   (set_attr "extended_mips16" "no,yes")])
5188
 
5189
(define_insn "call_split"
5190
  [(call (mem:SI (match_operand 0 "call_insn_operand" "cS"))
5191
         (match_operand 1 "" ""))
5192
   (clobber (reg:SI 31))
5193
   (clobber (reg:SI 28))]
5194
  "TARGET_SPLIT_CALLS"
5195
  { return MIPS_CALL ("jal", operands, 0); }
5196
  [(set_attr "type" "call")])
5197
 
5198
(define_expand "call_value"
5199
  [(parallel [(set (match_operand 0 "")
5200
                   (call (match_operand 1 "")
5201
                         (match_operand 2 "")))
5202
              (use (match_operand 3 ""))])]             ;; next_arg_reg
5203
  ""
5204
{
5205
  mips_expand_call (operands[0], XEXP (operands[1], 0),
5206
                    operands[2], operands[3], false);
5207
  DONE;
5208
})
5209
 
5210
;; See comment for call_internal.
5211
(define_insn_and_split "call_value_internal"
5212
  [(set (match_operand 0 "register_operand" "=df,df")
5213
        (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5214
              (match_operand 2 "" "")))
5215
   (clobber (reg:SI 31))]
5216
  ""
5217
  { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
5218
  "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
5219
  [(const_int 0)]
5220
{
5221
  emit_call_insn (gen_call_value_split (operands[0], operands[1],
5222
                                        operands[2]));
5223
  if (!find_reg_note (operands[3], REG_NORETURN, 0))
5224
    mips_restore_gp ();
5225
  DONE;
5226
}
5227
  [(set_attr "jal" "indirect,direct")
5228
   (set_attr "extended_mips16" "no,yes")])
5229
 
5230
(define_insn "call_value_split"
5231
  [(set (match_operand 0 "register_operand" "=df")
5232
        (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
5233
              (match_operand 2 "" "")))
5234
   (clobber (reg:SI 31))
5235
   (clobber (reg:SI 28))]
5236
  "TARGET_SPLIT_CALLS"
5237
  { return MIPS_CALL ("jal", operands, 1); }
5238
  [(set_attr "type" "call")])
5239
 
5240
;; See comment for call_internal.
5241
(define_insn_and_split "call_value_multiple_internal"
5242
  [(set (match_operand 0 "register_operand" "=df,df")
5243
        (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5244
              (match_operand 2 "" "")))
5245
   (set (match_operand 3 "register_operand" "=df,df")
5246
        (call (mem:SI (match_dup 1))
5247
              (match_dup 2)))
5248
   (clobber (reg:SI 31))]
5249
  ""
5250
  { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
5251
  "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
5252
  [(const_int 0)]
5253
{
5254
  emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
5255
                                                 operands[2], operands[3]));
5256
  if (!find_reg_note (operands[4], REG_NORETURN, 0))
5257
    mips_restore_gp ();
5258
  DONE;
5259
}
5260
  [(set_attr "jal" "indirect,direct")
5261
   (set_attr "extended_mips16" "no,yes")])
5262
 
5263
(define_insn "call_value_multiple_split"
5264
  [(set (match_operand 0 "register_operand" "=df")
5265
        (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
5266
              (match_operand 2 "" "")))
5267
   (set (match_operand 3 "register_operand" "=df")
5268
        (call (mem:SI (match_dup 1))
5269
              (match_dup 2)))
5270
   (clobber (reg:SI 31))
5271
   (clobber (reg:SI 28))]
5272
  "TARGET_SPLIT_CALLS"
5273
  { return MIPS_CALL ("jal", operands, 1); }
5274
  [(set_attr "type" "call")])
5275
 
5276
;; Call subroutine returning any type.
5277
 
5278
(define_expand "untyped_call"
5279
  [(parallel [(call (match_operand 0 "")
5280
                    (const_int 0))
5281
              (match_operand 1 "")
5282
              (match_operand 2 "")])]
5283
  ""
5284
{
5285
  int i;
5286
 
5287
  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
5288
 
5289
  for (i = 0; i < XVECLEN (operands[2], 0); i++)
5290
    {
5291
      rtx set = XVECEXP (operands[2], 0, i);
5292
      emit_move_insn (SET_DEST (set), SET_SRC (set));
5293
    }
5294
 
5295
  emit_insn (gen_blockage ());
5296
  DONE;
5297
})
5298
 
5299
;;
5300
;;  ....................
5301
;;
5302
;;      MISC.
5303
;;
5304
;;  ....................
5305
;;
5306
 
5307
 
5308
(define_insn "prefetch"
5309
  [(prefetch (match_operand:QI 0 "address_operand" "p")
5310
             (match_operand 1 "const_int_operand" "n")
5311
             (match_operand 2 "const_int_operand" "n"))]
5312
  "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
5313
{
5314
  operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
5315
  return "pref\t%1,%a0";
5316
}
5317
  [(set_attr "type" "prefetch")])
5318
 
5319
(define_insn "*prefetch_indexed_"
5320
  [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
5321
                     (match_operand:P 1 "register_operand" "d"))
5322
             (match_operand 2 "const_int_operand" "n")
5323
             (match_operand 3 "const_int_operand" "n"))]
5324
  "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5325
{
5326
  operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
5327
  return "prefx\t%2,%1(%0)";
5328
}
5329
  [(set_attr "type" "prefetchx")])
5330
 
5331
(define_insn "nop"
5332
  [(const_int 0)]
5333
  ""
5334
  "%(nop%)"
5335
  [(set_attr "type"     "nop")
5336
   (set_attr "mode"     "none")])
5337
 
5338
;; Like nop, but commented out when outside a .set noreorder block.
5339
(define_insn "hazard_nop"
5340
  [(const_int 1)]
5341
  ""
5342
  {
5343
    if (set_noreorder)
5344
      return "nop";
5345
    else
5346
      return "#nop";
5347
  }
5348
  [(set_attr "type"     "nop")])
5349
 
5350
;; MIPS4 Conditional move instructions.
5351
 
5352
(define_insn "*mov_on_"
5353
  [(set (match_operand:GPR 0 "register_operand" "=d,d")
5354
        (if_then_else:GPR
5355
         (match_operator:MOVECC 4 "equality_operator"
5356
                [(match_operand:MOVECC 1 "register_operand" ",")
5357
                 (const_int 0)])
5358
         (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
5359
         (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
5360
  "ISA_HAS_CONDMOVE"
5361
  "@
5362
    mov%T4\t%0,%z2,%1
5363
    mov%t4\t%0,%z3,%1"
5364
  [(set_attr "type" "condmove")
5365
   (set_attr "mode" "")])
5366
 
5367
(define_insn "*mov_on_"
5368
  [(set (match_operand:SCALARF 0 "register_operand" "=f,f")
5369
        (if_then_else:SCALARF
5370
         (match_operator:MOVECC 4 "equality_operator"
5371
                [(match_operand:MOVECC 1 "register_operand" ",")
5372
                 (const_int 0)])
5373
         (match_operand:SCALARF 2 "register_operand" "f,0")
5374
         (match_operand:SCALARF 3 "register_operand" "0,f")))]
5375
  "ISA_HAS_CONDMOVE"
5376
  "@
5377
    mov%T4.\t%0,%2,%1
5378
    mov%t4.\t%0,%3,%1"
5379
  [(set_attr "type" "condmove")
5380
   (set_attr "mode" "")])
5381
 
5382
;; These are the main define_expand's used to make conditional moves.
5383
 
5384
(define_expand "movcc"
5385
  [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5386
   (set (match_operand:GPR 0 "register_operand")
5387
        (if_then_else:GPR (match_dup 5)
5388
                          (match_operand:GPR 2 "reg_or_0_operand")
5389
                          (match_operand:GPR 3 "reg_or_0_operand")))]
5390
  "ISA_HAS_CONDMOVE"
5391
{
5392
  gen_conditional_move (operands);
5393
  DONE;
5394
})
5395
 
5396
(define_expand "movcc"
5397
  [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5398
   (set (match_operand:SCALARF 0 "register_operand")
5399
        (if_then_else:SCALARF (match_dup 5)
5400
                              (match_operand:SCALARF 2 "register_operand")
5401
                              (match_operand:SCALARF 3 "register_operand")))]
5402
  "ISA_HAS_CONDMOVE"
5403
{
5404
  gen_conditional_move (operands);
5405
  DONE;
5406
})
5407
 
5408
;;
5409
;;  ....................
5410
;;
5411
;;      mips16 inline constant tables
5412
;;
5413
;;  ....................
5414
;;
5415
 
5416
(define_insn "consttable_int"
5417
  [(unspec_volatile [(match_operand 0 "consttable_operand" "")
5418
                     (match_operand 1 "const_int_operand" "")]
5419
                    UNSPEC_CONSTTABLE_INT)]
5420
  "TARGET_MIPS16"
5421
{
5422
  assemble_integer (operands[0], INTVAL (operands[1]),
5423
                    BITS_PER_UNIT * INTVAL (operands[1]), 1);
5424
  return "";
5425
}
5426
  [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
5427
 
5428
(define_insn "consttable_float"
5429
  [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
5430
                    UNSPEC_CONSTTABLE_FLOAT)]
5431
  "TARGET_MIPS16"
5432
{
5433
  REAL_VALUE_TYPE d;
5434
 
5435
  gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
5436
  REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
5437
  assemble_real (d, GET_MODE (operands[0]),
5438
                 GET_MODE_BITSIZE (GET_MODE (operands[0])));
5439
  return "";
5440
}
5441
  [(set (attr "length")
5442
        (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
5443
 
5444
(define_insn "align"
5445
  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
5446
  ""
5447
  ".align\t%0"
5448
  [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
5449
 
5450
(define_split
5451
  [(match_operand 0 "small_data_pattern")]
5452
  "reload_completed"
5453
  [(match_dup 0)]
5454
  { operands[0] = mips_rewrite_small_data (operands[0]); })
5455
 
5456
; Thread-Local Storage
5457
 
5458
; The TLS base pointer is accessed via "rdhwr $v1, $29".  No current
5459
; MIPS architecture defines this register, and no current
5460
; implementation provides it; instead, any OS which supports TLS is
5461
; expected to trap and emulate this instruction.  rdhwr is part of the
5462
; MIPS 32r2 specification, but we use it on any architecture because
5463
; we expect it to be emulated.  Use .set to force the assembler to
5464
; accept it.
5465
 
5466
(define_insn "tls_get_tp_"
5467
  [(set (match_operand:P 0 "register_operand" "=v")
5468
        (unspec:P [(const_int 0)]
5469
                  UNSPEC_TLS_GET_TP))]
5470
  "HAVE_AS_TLS && !TARGET_MIPS16"
5471
  ".set\tpush\;.set\tmips32r2\t\;rdhwr\t%0,$29\;.set\tpop"
5472
  [(set_attr "type" "unknown")
5473
   ; Since rdhwr always generates a trap for now, putting it in a delay
5474
   ; slot would make the kernel's emulation of it much slower.
5475
   (set_attr "can_delay" "no")
5476
   (set_attr "mode" "")])
5477
 
5478
; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
5479
 
5480
(include "mips-ps-3d.md")
5481
 
5482
; The MIPS DSP Instructions.
5483
 
5484
(include "mips-dsp.md")

powered by: WebSVN 2.1.0

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