OSDN Git Service

2008-06-15 Mark Shinwell <shinwell@codesourcery.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / mips / mips.md
1 ;;  Mips.md          Machine Description for MIPS based processors
2 ;;  Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;;  1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;;  Free Software Foundation, Inc.
5 ;;  Contributed by   A. Lichnewsky, lich@inria.inria.fr
6 ;;  Changes by       Michael Meissner, meissner@osf.org
7 ;;  64-bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
8 ;;  Brendan Eich, brendan@microunity.com.
9
10 ;; This file is part of GCC.
11
12 ;; GCC is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; any later version.
16
17 ;; GCC is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ;; GNU General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GCC; see the file COPYING3.  If not see
24 ;; <http://www.gnu.org/licenses/>.
25
26 (define_constants
27   [(UNSPEC_LOAD_LOW              0)
28    (UNSPEC_LOAD_HIGH             1)
29    (UNSPEC_STORE_WORD            2)
30    (UNSPEC_GET_FNADDR            3)
31    (UNSPEC_BLOCKAGE              4)
32    (UNSPEC_CPRESTORE             5)
33    (UNSPEC_RESTORE_GP            6)
34    (UNSPEC_EH_RETURN             7)
35    (UNSPEC_CONSTTABLE_INT        8)
36    (UNSPEC_CONSTTABLE_FLOAT      9)
37    (UNSPEC_ALIGN                14)
38    (UNSPEC_HIGH                 17)
39    (UNSPEC_LOAD_LEFT            18)
40    (UNSPEC_LOAD_RIGHT           19)
41    (UNSPEC_STORE_LEFT           20)
42    (UNSPEC_STORE_RIGHT          21)
43    (UNSPEC_LOADGP               22)
44    (UNSPEC_LOAD_CALL            23)
45    (UNSPEC_LOAD_GOT             24)
46    (UNSPEC_GP                   25)
47    (UNSPEC_MFHI                 26)
48    (UNSPEC_MTHI                 27)
49    (UNSPEC_SET_HILO             28)
50    (UNSPEC_TLS_LDM              29)
51    (UNSPEC_TLS_GET_TP           30)
52    (UNSPEC_MFHC1                31)
53    (UNSPEC_MTHC1                32)
54    (UNSPEC_CLEAR_HAZARD         33)
55    (UNSPEC_RDHWR                34)
56    (UNSPEC_SYNCI                35)
57    (UNSPEC_SYNC                 36)
58    (UNSPEC_COMPARE_AND_SWAP     37)
59    (UNSPEC_COMPARE_AND_SWAP_12  38)
60    (UNSPEC_SYNC_OLD_OP          39)
61    (UNSPEC_SYNC_NEW_OP          40)
62    (UNSPEC_SYNC_NEW_OP_12       41)
63    (UNSPEC_SYNC_OLD_OP_12       42)
64    (UNSPEC_SYNC_EXCHANGE        43)
65    (UNSPEC_SYNC_EXCHANGE_12     44)
66    (UNSPEC_MEMORY_BARRIER       45)
67    (UNSPEC_SET_GOT_VERSION      46)
68    (UNSPEC_UPDATE_GOT_VERSION   47)
69    
70    (UNSPEC_ADDRESS_FIRST        100)
71
72    (GOT_VERSION_REGNUM          79)
73
74    ;; For MIPS Paired-Singled Floating Point Instructions.
75
76    (UNSPEC_MOVE_TF_PS           200)
77    (UNSPEC_C                    201)
78
79    ;; MIPS64/MIPS32R2 alnv.ps
80    (UNSPEC_ALNV_PS              202)
81
82    ;; MIPS-3D instructions
83    (UNSPEC_CABS                 203)
84
85    (UNSPEC_ADDR_PS              204)
86    (UNSPEC_CVT_PW_PS            205)
87    (UNSPEC_CVT_PS_PW            206)
88    (UNSPEC_MULR_PS              207)
89    (UNSPEC_ABS_PS               208)
90
91    (UNSPEC_RSQRT1               209)
92    (UNSPEC_RSQRT2               210)
93    (UNSPEC_RECIP1               211)
94    (UNSPEC_RECIP2               212)
95    (UNSPEC_SINGLE_CC            213)
96    (UNSPEC_SCC                  214)
97
98    ;; MIPS DSP ASE Revision 0.98 3/24/2005
99    (UNSPEC_ADDQ                 300)
100    (UNSPEC_ADDQ_S               301)
101    (UNSPEC_SUBQ                 302)
102    (UNSPEC_SUBQ_S               303)
103    (UNSPEC_ADDSC                304)
104    (UNSPEC_ADDWC                305)
105    (UNSPEC_MODSUB               306)
106    (UNSPEC_RADDU_W_QB           307)
107    (UNSPEC_ABSQ_S               308)
108    (UNSPEC_PRECRQ_QB_PH         309)
109    (UNSPEC_PRECRQ_PH_W          310)
110    (UNSPEC_PRECRQ_RS_PH_W       311)
111    (UNSPEC_PRECRQU_S_QB_PH      312)
112    (UNSPEC_PRECEQ_W_PHL         313)
113    (UNSPEC_PRECEQ_W_PHR         314)
114    (UNSPEC_PRECEQU_PH_QBL       315)
115    (UNSPEC_PRECEQU_PH_QBR       316)
116    (UNSPEC_PRECEQU_PH_QBLA      317)
117    (UNSPEC_PRECEQU_PH_QBRA      318)
118    (UNSPEC_PRECEU_PH_QBL        319)
119    (UNSPEC_PRECEU_PH_QBR        320)
120    (UNSPEC_PRECEU_PH_QBLA       321)
121    (UNSPEC_PRECEU_PH_QBRA       322)
122    (UNSPEC_SHLL                 323)
123    (UNSPEC_SHLL_S               324)
124    (UNSPEC_SHRL_QB              325)
125    (UNSPEC_SHRA_PH              326)
126    (UNSPEC_SHRA_R               327)
127    (UNSPEC_MULEU_S_PH_QBL       328)
128    (UNSPEC_MULEU_S_PH_QBR       329)
129    (UNSPEC_MULQ_RS_PH           330)
130    (UNSPEC_MULEQ_S_W_PHL        331)
131    (UNSPEC_MULEQ_S_W_PHR        332)
132    (UNSPEC_DPAU_H_QBL           333)
133    (UNSPEC_DPAU_H_QBR           334)
134    (UNSPEC_DPSU_H_QBL           335)
135    (UNSPEC_DPSU_H_QBR           336)
136    (UNSPEC_DPAQ_S_W_PH          337)
137    (UNSPEC_DPSQ_S_W_PH          338)
138    (UNSPEC_MULSAQ_S_W_PH        339)
139    (UNSPEC_DPAQ_SA_L_W          340)
140    (UNSPEC_DPSQ_SA_L_W          341)
141    (UNSPEC_MAQ_S_W_PHL          342)
142    (UNSPEC_MAQ_S_W_PHR          343)
143    (UNSPEC_MAQ_SA_W_PHL         344)
144    (UNSPEC_MAQ_SA_W_PHR         345)
145    (UNSPEC_BITREV               346)
146    (UNSPEC_INSV                 347)
147    (UNSPEC_REPL_QB              348)
148    (UNSPEC_REPL_PH              349)
149    (UNSPEC_CMP_EQ               350)
150    (UNSPEC_CMP_LT               351)
151    (UNSPEC_CMP_LE               352)
152    (UNSPEC_CMPGU_EQ_QB          353)
153    (UNSPEC_CMPGU_LT_QB          354)
154    (UNSPEC_CMPGU_LE_QB          355)
155    (UNSPEC_PICK                 356)
156    (UNSPEC_PACKRL_PH            357)
157    (UNSPEC_EXTR_W               358)
158    (UNSPEC_EXTR_R_W             359)
159    (UNSPEC_EXTR_RS_W            360)
160    (UNSPEC_EXTR_S_H             361)
161    (UNSPEC_EXTP                 362)
162    (UNSPEC_EXTPDP               363)
163    (UNSPEC_SHILO                364)
164    (UNSPEC_MTHLIP               365)
165    (UNSPEC_WRDSP                366)
166    (UNSPEC_RDDSP                367)
167
168    ;; MIPS DSP ASE REV 2 Revision 0.02 11/24/2006
169    (UNSPEC_ABSQ_S_QB            400)
170    (UNSPEC_ADDU_PH              401)
171    (UNSPEC_ADDU_S_PH            402)
172    (UNSPEC_ADDUH_QB             403)
173    (UNSPEC_ADDUH_R_QB           404)
174    (UNSPEC_APPEND               405)
175    (UNSPEC_BALIGN               406)
176    (UNSPEC_CMPGDU_EQ_QB         407)
177    (UNSPEC_CMPGDU_LT_QB         408)
178    (UNSPEC_CMPGDU_LE_QB         409)
179    (UNSPEC_DPA_W_PH             410)
180    (UNSPEC_DPS_W_PH             411)
181    (UNSPEC_MADD                 412)
182    (UNSPEC_MADDU                413)
183    (UNSPEC_MSUB                 414)
184    (UNSPEC_MSUBU                415)
185    (UNSPEC_MUL_PH               416)
186    (UNSPEC_MUL_S_PH             417)
187    (UNSPEC_MULQ_RS_W            418)
188    (UNSPEC_MULQ_S_PH            419)
189    (UNSPEC_MULQ_S_W             420)
190    (UNSPEC_MULSA_W_PH           421)
191    (UNSPEC_MULT                 422)
192    (UNSPEC_MULTU                423)
193    (UNSPEC_PRECR_QB_PH          424)
194    (UNSPEC_PRECR_SRA_PH_W       425)
195    (UNSPEC_PRECR_SRA_R_PH_W     426)
196    (UNSPEC_PREPEND              427)
197    (UNSPEC_SHRA_QB              428)
198    (UNSPEC_SHRA_R_QB            429)
199    (UNSPEC_SHRL_PH              430)
200    (UNSPEC_SUBU_PH              431)
201    (UNSPEC_SUBU_S_PH            432)
202    (UNSPEC_SUBUH_QB             433)
203    (UNSPEC_SUBUH_R_QB           434)
204    (UNSPEC_ADDQH_PH             435)
205    (UNSPEC_ADDQH_R_PH           436)
206    (UNSPEC_ADDQH_W              437)
207    (UNSPEC_ADDQH_R_W            438)
208    (UNSPEC_SUBQH_PH             439)
209    (UNSPEC_SUBQH_R_PH           440)
210    (UNSPEC_SUBQH_W              441)
211    (UNSPEC_SUBQH_R_W            442)
212    (UNSPEC_DPAX_W_PH            443)
213    (UNSPEC_DPSX_W_PH            444)
214    (UNSPEC_DPAQX_S_W_PH         445)
215    (UNSPEC_DPAQX_SA_W_PH        446)
216    (UNSPEC_DPSQX_S_W_PH         447)
217    (UNSPEC_DPSQX_SA_W_PH        448)
218
219    ;; ST Microelectronics Loongson-2E/2F.
220    (UNSPEC_LOONGSON_PAVG        500)
221    (UNSPEC_LOONGSON_PCMPEQ      501)
222    (UNSPEC_LOONGSON_PCMPGT      502)
223    (UNSPEC_LOONGSON_PEXTR       503)
224    (UNSPEC_LOONGSON_PINSR_0     504)
225    (UNSPEC_LOONGSON_PINSR_1     505)
226    (UNSPEC_LOONGSON_PINSR_2     506)
227    (UNSPEC_LOONGSON_PINSR_3     507)
228    (UNSPEC_LOONGSON_PMADD       508)
229    (UNSPEC_LOONGSON_PMOVMSK     509)
230    (UNSPEC_LOONGSON_PMULHU      510)
231    (UNSPEC_LOONGSON_PMULH       511)
232    (UNSPEC_LOONGSON_PMULL       512)
233    (UNSPEC_LOONGSON_PMULU       513)
234    (UNSPEC_LOONGSON_PASUBUB     514)
235    (UNSPEC_LOONGSON_BIADD       515)
236    (UNSPEC_LOONGSON_PSADBH      516)
237    (UNSPEC_LOONGSON_PSHUFH      517)
238    (UNSPEC_LOONGSON_PUNPCKH     518)
239    (UNSPEC_LOONGSON_PUNPCKL     519)
240    (UNSPEC_LOONGSON_PADDD       520)
241    (UNSPEC_LOONGSON_PSUBD       521)
242   ]
243 )
244
245 (include "predicates.md")
246 (include "constraints.md")
247 \f
248 ;; ....................
249 ;;
250 ;;      Attributes
251 ;;
252 ;; ....................
253
254 (define_attr "got" "unset,xgot_high,load"
255   (const_string "unset"))
256
257 ;; For jal instructions, this attribute is DIRECT when the target address
258 ;; is symbolic and INDIRECT when it is a register.
259 (define_attr "jal" "unset,direct,indirect"
260   (const_string "unset"))
261
262 ;; This attribute is YES if the instruction is a jal macro (not a
263 ;; real jal instruction).
264 ;;
265 ;; jal is always a macro for TARGET_CALL_CLOBBERED_GP because it includes
266 ;; an instruction to restore $gp.  Direct jals are also macros for
267 ;; flag_pic && !TARGET_ABSOLUTE_ABICALLS because they first load
268 ;; the target address into a register.
269 (define_attr "jal_macro" "no,yes"
270   (cond [(eq_attr "jal" "direct")
271          (symbol_ref "TARGET_CALL_CLOBBERED_GP
272                       || (flag_pic && !TARGET_ABSOLUTE_ABICALLS)")
273          (eq_attr "jal" "indirect")
274          (symbol_ref "TARGET_CALL_CLOBBERED_GP")]
275         (const_string "no")))
276
277 ;; Classification of each insn.
278 ;; branch       conditional branch
279 ;; jump         unconditional jump
280 ;; call         unconditional call
281 ;; load         load instruction(s)
282 ;; fpload       floating point load
283 ;; fpidxload    floating point indexed load
284 ;; store        store instruction(s)
285 ;; fpstore      floating point store
286 ;; fpidxstore   floating point indexed store
287 ;; prefetch     memory prefetch (register + offset)
288 ;; prefetchx    memory indexed prefetch (register + register)
289 ;; condmove     conditional moves
290 ;; mfc          transfer from coprocessor
291 ;; mtc          transfer to coprocessor
292 ;; mthilo       transfer to hi/lo registers
293 ;; mfhilo       transfer from hi/lo registers
294 ;; const        load constant
295 ;; arith        integer arithmetic instructions
296 ;; logical      integer logical instructions
297 ;; shift        integer shift instructions
298 ;; slt          set less than instructions
299 ;; signext      sign extend instructions
300 ;; clz          the clz and clo instructions
301 ;; trap         trap if instructions
302 ;; imul         integer multiply 2 operands
303 ;; imul3        integer multiply 3 operands
304 ;; imadd        integer multiply-add
305 ;; idiv         integer divide
306 ;; move         integer register move ({,D}ADD{,U} with rt = 0)
307 ;; fmove        floating point register move
308 ;; fadd         floating point add/subtract
309 ;; fmul         floating point multiply
310 ;; fmadd        floating point multiply-add
311 ;; fdiv         floating point divide
312 ;; frdiv        floating point reciprocal divide
313 ;; frdiv1       floating point reciprocal divide step 1
314 ;; frdiv2       floating point reciprocal divide step 2
315 ;; fabs         floating point absolute value
316 ;; fneg         floating point negation
317 ;; fcmp         floating point compare
318 ;; fcvt         floating point convert
319 ;; fsqrt        floating point square root
320 ;; frsqrt       floating point reciprocal square root
321 ;; frsqrt1      floating point reciprocal square root step1
322 ;; frsqrt2      floating point reciprocal square root step2
323 ;; multi        multiword sequence (or user asm statements)
324 ;; nop          no operation
325 ;; ghost        an instruction that produces no real code
326 (define_attr "type"
327   "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,mfc,mtc,mthilo,mfhilo,const,arith,logical,shift,slt,signext,clz,trap,imul,imul3,imadd,idiv,move,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,multi,nop,ghost"
328   (cond [(eq_attr "jal" "!unset") (const_string "call")
329          (eq_attr "got" "load") (const_string "load")]
330         (const_string "unknown")))
331
332 ;; Main data type used by the insn
333 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
334   (const_string "unknown"))
335
336 ;; Mode for conversion types (fcvt)
337 ;; I2S          integer to float single (SI/DI to SF)
338 ;; I2D          integer to float double (SI/DI to DF)
339 ;; S2I          float to integer (SF to SI/DI)
340 ;; D2I          float to integer (DF to SI/DI)
341 ;; D2S          double to float single
342 ;; S2D          float single to double
343
344 (define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D" 
345   (const_string "unknown"))
346
347 ;; Is this an extended instruction in mips16 mode?
348 (define_attr "extended_mips16" "no,yes"
349   (const_string "no"))
350
351 ;; Length of instruction in bytes.
352 (define_attr "length" ""
353    (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
354           ;; If a branch is outside this range, we have a choice of two
355           ;; sequences.  For PIC, an out-of-range branch like:
356           ;;
357           ;;    bne     r1,r2,target
358           ;;    dslot
359           ;;
360           ;; becomes the equivalent of:
361           ;;
362           ;;    beq     r1,r2,1f
363           ;;    dslot
364           ;;    la      $at,target
365           ;;    jr      $at
366           ;;    nop
367           ;; 1:
368           ;;
369           ;; where the load address can be up to three instructions long
370           ;; (lw, nop, addiu).
371           ;;
372           ;; The non-PIC case is similar except that we use a direct
373           ;; jump instead of an la/jr pair.  Since the target of this
374           ;; jump is an absolute 28-bit bit address (the other bits
375           ;; coming from the address of the delay slot) this form cannot
376           ;; cross a 256MB boundary.  We could provide the option of
377           ;; using la/jr in this case too, but we do not do so at
378           ;; present.
379           ;;
380           ;; Note that this value does not account for the delay slot
381           ;; instruction, whose length is added separately.  If the RTL
382           ;; pattern has no explicit delay slot, mips_adjust_insn_length
383           ;; will add the length of the implicit nop.  The values for
384           ;; forward and backward branches will be different as well.
385           (eq_attr "type" "branch")
386           (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
387                       (le (minus (pc) (match_dup 1)) (const_int 131068)))
388                   (const_int 4)
389                  (ne (symbol_ref "flag_pic") (const_int 0))
390                  (const_int 24)
391                  ] (const_int 12))
392
393           (eq_attr "got" "load")
394           (const_int 4)
395           (eq_attr "got" "xgot_high")
396           (const_int 8)
397
398           (eq_attr "type" "const")
399           (symbol_ref "mips_const_insns (operands[1]) * 4")
400           (eq_attr "type" "load,fpload")
401           (symbol_ref "mips_load_store_insns (operands[1], insn) * 4")
402           (eq_attr "type" "store,fpstore")
403           (symbol_ref "mips_load_store_insns (operands[0], insn) * 4")
404
405           ;; In the worst case, a call macro will take 8 instructions:
406           ;;
407           ;;     lui $25,%call_hi(FOO)
408           ;;     addu $25,$25,$28
409           ;;     lw $25,%call_lo(FOO)($25)
410           ;;     nop
411           ;;     jalr $25
412           ;;     nop
413           ;;     lw $gp,X($sp)
414           ;;     nop
415           (eq_attr "jal_macro" "yes")
416           (const_int 32)
417
418           (and (eq_attr "extended_mips16" "yes")
419                (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
420           (const_int 8)
421
422           ;; Various VR4120 errata require a nop to be inserted after a macc
423           ;; instruction.  The assembler does this for us, so account for
424           ;; the worst-case length here.
425           (and (eq_attr "type" "imadd")
426                (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
427           (const_int 8)
428
429           ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
430           ;; the result of the second one is missed.  The assembler should work
431           ;; around this by inserting a nop after the first dmult.
432           (and (eq_attr "type" "imul,imul3")
433                (and (eq_attr "mode" "DI")
434                     (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
435           (const_int 8)
436
437           (eq_attr "type" "idiv")
438           (symbol_ref "mips_idiv_insns () * 4")
439           ] (const_int 4)))
440
441 ;; Attribute describing the processor.  This attribute must match exactly
442 ;; with the processor_type enumeration in mips.h.
443 (define_attr "cpu"
444   "r3000,4kc,4kp,5kc,5kf,20kc,24kc,24kf2_1,24kf1_1,74kc,74kf2_1,74kf1_1,74kf3_2,loongson2e,loongson2f,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000,xlr"
445   (const (symbol_ref "mips_tune")))
446
447 ;; The type of hardware hazard associated with this instruction.
448 ;; DELAY means that the next instruction cannot read the result
449 ;; of this one.  HILO means that the next two instructions cannot
450 ;; write to HI or LO.
451 (define_attr "hazard" "none,delay,hilo"
452   (cond [(and (eq_attr "type" "load,fpload,fpidxload")
453               (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
454          (const_string "delay")
455
456          (and (eq_attr "type" "mfc,mtc")
457               (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
458          (const_string "delay")
459
460          (and (eq_attr "type" "fcmp")
461               (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
462          (const_string "delay")
463
464          ;; The r4000 multiplication patterns include an mflo instruction.
465          (and (eq_attr "type" "imul")
466               (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
467          (const_string "hilo")
468
469          (and (eq_attr "type" "mfhilo")
470               (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
471          (const_string "hilo")]
472         (const_string "none")))
473
474 ;; Is it a single instruction?
475 (define_attr "single_insn" "no,yes"
476   (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
477
478 ;; Can the instruction be put into a delay slot?
479 (define_attr "can_delay" "no,yes"
480   (if_then_else (and (eq_attr "type" "!branch,call,jump")
481                      (and (eq_attr "hazard" "none")
482                           (eq_attr "single_insn" "yes")))
483                 (const_string "yes")
484                 (const_string "no")))
485
486 ;; Attribute defining whether or not we can use the branch-likely instructions
487 (define_attr "branch_likely" "no,yes"
488   (const
489    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
490                  (const_string "yes")
491                  (const_string "no"))))
492
493 ;; True if an instruction might assign to hi or lo when reloaded.
494 ;; This is used by the TUNE_MACC_CHAINS code.
495 (define_attr "may_clobber_hilo" "no,yes"
496   (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthilo")
497                 (const_string "yes")
498                 (const_string "no")))
499
500 ;; Describe a user's asm statement.
501 (define_asm_attributes
502   [(set_attr "type" "multi")
503    (set_attr "can_delay" "no")])
504 \f
505 ;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
506 ;; from the same template.
507 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
508
509 ;; A copy of GPR that can be used when a pattern has two independent
510 ;; modes.
511 (define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")])
512
513 ;; This mode iterator allows :HILO to be used as the mode of the
514 ;; concatenated HI and LO registers.
515 (define_mode_iterator HILO [(DI "!TARGET_64BIT") (TI "TARGET_64BIT")])
516
517 ;; This mode iterator allows :P to be used for patterns that operate on
518 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
519 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
520
521 ;; This mode iterator allows :MOVECC to be used anywhere that a
522 ;; conditional-move-type condition is needed.
523 (define_mode_iterator MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
524
525 ;; 64-bit modes for which we provide move patterns.
526 (define_mode_iterator MOVE64
527   [DI DF
528    (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")
529    (V2SI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")
530    (V4HI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")
531    (V8QI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")])
532
533 ;; 128-bit modes for which we provide move patterns on 64-bit targets.
534 (define_mode_iterator MOVE128 [TI TF])
535
536 ;; This mode iterator allows the QI and HI extension patterns to be
537 ;; defined from the same template.
538 (define_mode_iterator SHORT [QI HI])
539
540 ;; Likewise the 64-bit truncate-and-shift patterns.
541 (define_mode_iterator SUBDI [QI HI SI])
542
543 ;; This mode iterator allows :ANYF to be used wherever a scalar or vector
544 ;; floating-point mode is allowed.
545 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
546                             (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
547                             (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")])
548
549 ;; Like ANYF, but only applies to scalar modes.
550 (define_mode_iterator SCALARF [(SF "TARGET_HARD_FLOAT")
551                                (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
552
553 ;; A floating-point mode for which moves involving FPRs may need to be split.
554 (define_mode_iterator SPLITF
555   [(DF "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
556    (DI "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
557    (V2SF "!TARGET_64BIT && TARGET_PAIRED_SINGLE_FLOAT")
558    (V2SI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
559    (V4HI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
560    (V8QI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
561    (TF "TARGET_64BIT && TARGET_FLOAT64")])
562
563 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
564 ;; 32-bit version and "dsubu" in the 64-bit version.
565 (define_mode_attr d [(SI "") (DI "d")
566                      (QQ "") (HQ "") (SQ "") (DQ "d")
567                      (UQQ "") (UHQ "") (USQ "") (UDQ "d")
568                      (HA "") (SA "") (DA "d")
569                      (UHA "") (USA "") (UDA "d")])
570
571 ;; This attribute gives the length suffix for a sign- or zero-extension
572 ;; instruction.
573 (define_mode_attr size [(QI "b") (HI "h")])
574
575 ;; This attributes gives the mode mask of a SHORT.
576 (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
577
578 ;; Mode attributes for GPR loads and stores.
579 (define_mode_attr load [(SI "lw") (DI "ld")])
580 (define_mode_attr store [(SI "sw") (DI "sd")])
581
582 ;; Similarly for MIPS IV indexed FPR loads and stores.
583 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
584 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
585
586 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
587 ;; are different.  Some forms of unextended addiu have an 8-bit immediate
588 ;; field but the equivalent daddiu has only a 5-bit field.
589 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
590
591 ;; This attribute gives the best constraint to use for registers of
592 ;; a given mode.
593 (define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
594
595 ;; This attribute gives the format suffix for floating-point operations.
596 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
597
598 ;; This attribute gives the upper-case mode name for one unit of a
599 ;; floating-point mode.
600 (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
601
602 ;; This attribute gives the integer mode that has the same size as a
603 ;; fixed-point mode.
604 (define_mode_attr IMODE [(QQ "QI") (HQ "HI") (SQ "SI") (DQ "DI")
605                          (UQQ "QI") (UHQ "HI") (USQ "SI") (UDQ "DI")
606                          (HA "HI") (SA "SI") (DA "DI")
607                          (UHA "HI") (USA "SI") (UDA "DI")
608                          (V4UQQ "SI") (V2UHQ "SI") (V2UHA "SI")
609                          (V2HQ "SI") (V2HA "SI")])
610
611 ;; This attribute gives the integer mode that has half the size of
612 ;; the controlling mode.
613 (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (V2SF "SI")
614                             (V2SI "SI") (V4HI "SI") (V8QI "SI")
615                             (TF "DI")])
616
617 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
618 ;;
619 ;; In certain cases, div.s and div.ps may have a rounding error
620 ;; and/or wrong inexact flag.
621 ;;
622 ;; Therefore, we only allow div.s if not working around SB-1 rev2
623 ;; errata or if a slight loss of precision is OK.
624 (define_mode_attr divide_condition
625   [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")
626    (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")])
627
628 ;; This attribute gives the conditions under which SQRT.fmt instructions
629 ;; can be used.
630 (define_mode_attr sqrt_condition
631   [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")])
632
633 ;; This attribute gives the conditions under which RECIP.fmt and RSQRT.fmt
634 ;; instructions can be used.  The MIPS32 and MIPS64 ISAs say that RECIP.D
635 ;; and RSQRT.D are unpredictable when doubles are stored in pairs of FPRs,
636 ;; so for safety's sake, we apply this restriction to all targets.
637 (define_mode_attr recip_condition
638   [(SF "ISA_HAS_FP4")
639    (DF "ISA_HAS_FP4 && TARGET_FLOAT64")
640    (V2SF "TARGET_SB1")])
641
642 ;; This code iterator allows all branch instructions to be generated from
643 ;; a single define_expand template.
644 (define_code_iterator any_cond [unordered ordered unlt unge uneq ltgt unle ungt
645                                 eq ne gt ge lt le gtu geu ltu leu])
646
647 ;; This code iterator allows signed and unsigned widening multiplications
648 ;; to use the same template.
649 (define_code_iterator any_extend [sign_extend zero_extend])
650
651 ;; This code iterator allows the three shift instructions to be generated
652 ;; from the same template.
653 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
654
655 ;; This code iterator allows unsigned and signed division to be generated
656 ;; from the same template.
657 (define_code_iterator any_div [div udiv])
658
659 ;; This code iterator allows all native floating-point comparisons to be
660 ;; generated from the same template.
661 (define_code_iterator fcond [unordered uneq unlt unle eq lt le])
662
663 ;; This code iterator is used for comparisons that can be implemented
664 ;; by swapping the operands.
665 (define_code_iterator swapped_fcond [ge gt unge ungt])
666
667 ;; These code iterators allow the signed and unsigned scc operations to use
668 ;; the same template.
669 (define_code_iterator any_gt [gt gtu])
670 (define_code_iterator any_ge [ge geu])
671 (define_code_iterator any_lt [lt ltu])
672 (define_code_iterator any_le [le leu])
673
674 ;; <u> expands to an empty string when doing a signed operation and
675 ;; "u" when doing an unsigned operation.
676 (define_code_attr u [(sign_extend "") (zero_extend "u")
677                      (div "") (udiv "u")
678                      (gt "") (gtu "u")
679                      (ge "") (geu "u")
680                      (lt "") (ltu "u")
681                      (le "") (leu "u")])
682
683 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
684 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
685
686 ;; <optab> expands to the name of the optab for a particular code.
687 (define_code_attr optab [(ashift "ashl")
688                          (ashiftrt "ashr")
689                          (lshiftrt "lshr")
690                          (ior "ior")
691                          (xor "xor")
692                          (and "and")
693                          (plus "add")
694                          (minus "sub")])
695
696 ;; <insn> expands to the name of the insn that implements a particular code.
697 (define_code_attr insn [(ashift "sll")
698                         (ashiftrt "sra")
699                         (lshiftrt "srl")
700                         (ior "or")
701                         (xor "xor")
702                         (and "and")
703                         (plus "addu")
704                         (minus "subu")])
705
706 ;; <fcond> is the c.cond.fmt condition associated with a particular code.
707 (define_code_attr fcond [(unordered "un")
708                          (uneq "ueq")
709                          (unlt "ult")
710                          (unle "ule")
711                          (eq "eq")
712                          (lt "lt")
713                          (le "le")])
714
715 ;; Similar, but for swapped conditions.
716 (define_code_attr swapped_fcond [(ge "le")
717                                  (gt "lt")
718                                  (unge "ule")
719                                  (ungt "ult")])
720
721 ;; Atomic fetch bitwise operations.
722 (define_code_iterator fetchop_bit [ior xor and])
723
724 ;; <immediate_insn> expands to the name of the insn that implements
725 ;; a particular code to operate in immediate values.
726 (define_code_attr immediate_insn [(ior "ori") (xor "xori") (and "andi")])
727
728 ;; Atomic HI and QI operations
729 (define_code_iterator atomic_hiqi_op [plus minus ior xor and])
730 \f
731 ;; .........................
732 ;;
733 ;;      Branch, call and jump delay slots
734 ;;
735 ;; .........................
736
737 (define_delay (and (eq_attr "type" "branch")
738                    (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
739   [(eq_attr "can_delay" "yes")
740    (nil)
741    (and (eq_attr "branch_likely" "yes")
742         (eq_attr "can_delay" "yes"))])
743
744 (define_delay (eq_attr "type" "jump")
745   [(eq_attr "can_delay" "yes")
746    (nil)
747    (nil)])
748
749 (define_delay (and (eq_attr "type" "call")
750                    (eq_attr "jal_macro" "no"))
751   [(eq_attr "can_delay" "yes")
752    (nil)
753    (nil)])
754 \f
755 ;; Pipeline descriptions.
756 ;;
757 ;; generic.md provides a fallback for processors without a specific
758 ;; pipeline description.  It is derived from the old define_function_unit
759 ;; version and uses the "alu" and "imuldiv" units declared below.
760 ;;
761 ;; Some of the processor-specific files are also derived from old
762 ;; define_function_unit descriptions and simply override the parts of
763 ;; generic.md that don't apply.  The other processor-specific files
764 ;; are self-contained.
765 (define_automaton "alu,imuldiv")
766
767 (define_cpu_unit "alu" "alu")
768 (define_cpu_unit "imuldiv" "imuldiv")
769
770 ;; Ghost instructions produce no real code and introduce no hazards.
771 ;; They exist purely to express an effect on dataflow.
772 (define_insn_reservation "ghost" 0
773   (eq_attr "type" "ghost")
774   "nothing")
775
776 (include "4k.md")
777 (include "5k.md")
778 (include "20kc.md")
779 (include "24k.md")
780 (include "74k.md")
781 (include "3000.md")
782 (include "4000.md")
783 (include "4100.md")
784 (include "4130.md")
785 (include "4300.md")
786 (include "4600.md")
787 (include "5000.md")
788 (include "5400.md")
789 (include "5500.md")
790 (include "6000.md")
791 (include "7000.md")
792 (include "9000.md")
793 (include "sb1.md")
794 (include "sr71k.md")
795 (include "xlr.md")
796 (include "generic.md")
797 \f
798 ;;
799 ;;  ....................
800 ;;
801 ;;      CONDITIONAL TRAPS
802 ;;
803 ;;  ....................
804 ;;
805
806 (define_insn "trap"
807   [(trap_if (const_int 1) (const_int 0))]
808   ""
809 {
810   if (ISA_HAS_COND_TRAP)
811     return "teq\t$0,$0";
812   else if (TARGET_MIPS16)
813     return "break 0";
814   else
815     return "break";
816 }
817   [(set_attr "type" "trap")])
818
819 (define_expand "conditional_trap"
820   [(trap_if (match_operator 0 "comparison_operator"
821                             [(match_dup 2) (match_dup 3)])
822             (match_operand 1 "const_int_operand"))]
823   "ISA_HAS_COND_TRAP"
824 {
825   if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
826       && operands[1] == const0_rtx)
827     {
828       mips_expand_conditional_trap (GET_CODE (operands[0]));
829       DONE;
830     }
831   FAIL;
832 })
833
834 (define_insn "*conditional_trap<mode>"
835   [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
836                                 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
837                                  (match_operand:GPR 2 "arith_operand" "dI")])
838             (const_int 0))]
839   "ISA_HAS_COND_TRAP"
840   "t%C0\t%z1,%2"
841   [(set_attr "type" "trap")])
842 \f
843 ;;
844 ;;  ....................
845 ;;
846 ;;      ADDITION
847 ;;
848 ;;  ....................
849 ;;
850
851 (define_insn "add<mode>3"
852   [(set (match_operand:ANYF 0 "register_operand" "=f")
853         (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
854                    (match_operand:ANYF 2 "register_operand" "f")))]
855   ""
856   "add.<fmt>\t%0,%1,%2"
857   [(set_attr "type" "fadd")
858    (set_attr "mode" "<UNITMODE>")])
859
860 (define_expand "add<mode>3"
861   [(set (match_operand:GPR 0 "register_operand")
862         (plus:GPR (match_operand:GPR 1 "register_operand")
863                   (match_operand:GPR 2 "arith_operand")))]
864   "")
865
866 (define_insn "*add<mode>3"
867   [(set (match_operand:GPR 0 "register_operand" "=d,d")
868         (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
869                   (match_operand:GPR 2 "arith_operand" "d,Q")))]
870   "!TARGET_MIPS16"
871   "@
872     <d>addu\t%0,%1,%2
873     <d>addiu\t%0,%1,%2"
874   [(set_attr "type" "arith")
875    (set_attr "mode" "<MODE>")])
876
877 (define_insn "*add<mode>3_mips16"
878   [(set (match_operand:GPR 0 "register_operand" "=ks,d,d,d,d")
879         (plus:GPR (match_operand:GPR 1 "register_operand" "ks,ks,0,d,d")
880                   (match_operand:GPR 2 "arith_operand" "Q,Q,Q,O,d")))]
881   "TARGET_MIPS16"
882   "@
883     <d>addiu\t%0,%2
884     <d>addiu\t%0,%1,%2
885     <d>addiu\t%0,%2
886     <d>addiu\t%0,%1,%2
887     <d>addu\t%0,%1,%2"
888   [(set_attr "type" "arith")
889    (set_attr "mode" "<MODE>")
890    (set_attr_alternative "length"
891                 [(if_then_else (match_operand 2 "m16_simm8_8")
892                                (const_int 4)
893                                (const_int 8))
894                  (if_then_else (match_operand 2 "m16_uimm<si8_di5>_4")
895                                (const_int 4)
896                                (const_int 8))
897                  (if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
898                                (const_int 4)
899                                (const_int 8))
900                  (if_then_else (match_operand 2 "m16_simm4_1")
901                                (const_int 4)
902                                (const_int 8))
903                  (const_int 4)])])
904
905 ;; On the mips16, we can sometimes split an add of a constant which is
906 ;; a 4 byte instruction into two adds which are both 2 byte
907 ;; instructions.  There are two cases: one where we are adding a
908 ;; constant plus a register to another register, and one where we are
909 ;; simply adding a constant to a register.
910
911 (define_split
912   [(set (match_operand:SI 0 "d_operand")
913         (plus:SI (match_dup 0)
914                  (match_operand:SI 1 "const_int_operand")))]
915   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
916    && ((INTVAL (operands[1]) > 0x7f
917         && INTVAL (operands[1]) <= 0x7f + 0x7f)
918        || (INTVAL (operands[1]) < - 0x80
919            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
920   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
921    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
922 {
923   HOST_WIDE_INT val = INTVAL (operands[1]);
924
925   if (val >= 0)
926     {
927       operands[1] = GEN_INT (0x7f);
928       operands[2] = GEN_INT (val - 0x7f);
929     }
930   else
931     {
932       operands[1] = GEN_INT (- 0x80);
933       operands[2] = GEN_INT (val + 0x80);
934     }
935 })
936
937 (define_split
938   [(set (match_operand:SI 0 "d_operand")
939         (plus:SI (match_operand:SI 1 "d_operand")
940                  (match_operand:SI 2 "const_int_operand")))]
941   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
942    && REGNO (operands[0]) != REGNO (operands[1])
943    && ((INTVAL (operands[2]) > 0x7
944         && INTVAL (operands[2]) <= 0x7 + 0x7f)
945        || (INTVAL (operands[2]) < - 0x8
946            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
947   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
948    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
949 {
950   HOST_WIDE_INT val = INTVAL (operands[2]);
951
952   if (val >= 0)
953     {
954       operands[2] = GEN_INT (0x7);
955       operands[3] = GEN_INT (val - 0x7);
956     }
957   else
958     {
959       operands[2] = GEN_INT (- 0x8);
960       operands[3] = GEN_INT (val + 0x8);
961     }
962 })
963
964 (define_split
965   [(set (match_operand:DI 0 "d_operand")
966         (plus:DI (match_dup 0)
967                  (match_operand:DI 1 "const_int_operand")))]
968   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
969    && ((INTVAL (operands[1]) > 0xf
970         && INTVAL (operands[1]) <= 0xf + 0xf)
971        || (INTVAL (operands[1]) < - 0x10
972            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
973   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
974    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
975 {
976   HOST_WIDE_INT val = INTVAL (operands[1]);
977
978   if (val >= 0)
979     {
980       operands[1] = GEN_INT (0xf);
981       operands[2] = GEN_INT (val - 0xf);
982     }
983   else
984     {
985       operands[1] = GEN_INT (- 0x10);
986       operands[2] = GEN_INT (val + 0x10);
987     }
988 })
989
990 (define_split
991   [(set (match_operand:DI 0 "d_operand")
992         (plus:DI (match_operand:DI 1 "d_operand")
993                  (match_operand:DI 2 "const_int_operand")))]
994   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
995    && REGNO (operands[0]) != REGNO (operands[1])
996    && ((INTVAL (operands[2]) > 0x7
997         && INTVAL (operands[2]) <= 0x7 + 0xf)
998        || (INTVAL (operands[2]) < - 0x8
999            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1000   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1001    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1002 {
1003   HOST_WIDE_INT val = INTVAL (operands[2]);
1004
1005   if (val >= 0)
1006     {
1007       operands[2] = GEN_INT (0x7);
1008       operands[3] = GEN_INT (val - 0x7);
1009     }
1010   else
1011     {
1012       operands[2] = GEN_INT (- 0x8);
1013       operands[3] = GEN_INT (val + 0x8);
1014     }
1015 })
1016
1017 (define_insn "*addsi3_extended"
1018   [(set (match_operand:DI 0 "register_operand" "=d,d")
1019         (sign_extend:DI
1020              (plus:SI (match_operand:SI 1 "register_operand" "d,d")
1021                       (match_operand:SI 2 "arith_operand" "d,Q"))))]
1022   "TARGET_64BIT && !TARGET_MIPS16"
1023   "@
1024     addu\t%0,%1,%2
1025     addiu\t%0,%1,%2"
1026   [(set_attr "type" "arith")
1027    (set_attr "mode" "SI")])
1028
1029 ;; Split this insn so that the addiu splitters can have a crack at it.
1030 ;; Use a conservative length estimate until the split.
1031 (define_insn_and_split "*addsi3_extended_mips16"
1032   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1033         (sign_extend:DI
1034              (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1035                       (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
1036   "TARGET_64BIT && TARGET_MIPS16"
1037   "#"
1038   "&& reload_completed"
1039   [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
1040   { operands[3] = gen_lowpart (SImode, operands[0]); }
1041   [(set_attr "type" "arith")
1042    (set_attr "mode" "SI")
1043    (set_attr "extended_mips16" "yes")])
1044 \f
1045 ;;
1046 ;;  ....................
1047 ;;
1048 ;;      SUBTRACTION
1049 ;;
1050 ;;  ....................
1051 ;;
1052
1053 (define_insn "sub<mode>3"
1054   [(set (match_operand:ANYF 0 "register_operand" "=f")
1055         (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
1056                     (match_operand:ANYF 2 "register_operand" "f")))]
1057   ""
1058   "sub.<fmt>\t%0,%1,%2"
1059   [(set_attr "type" "fadd")
1060    (set_attr "mode" "<UNITMODE>")])
1061
1062 (define_insn "sub<mode>3"
1063   [(set (match_operand:GPR 0 "register_operand" "=d")
1064         (minus:GPR (match_operand:GPR 1 "register_operand" "d")
1065                    (match_operand:GPR 2 "register_operand" "d")))]
1066   ""
1067   "<d>subu\t%0,%1,%2"
1068   [(set_attr "type" "arith")
1069    (set_attr "mode" "<MODE>")])
1070
1071 (define_insn "*subsi3_extended"
1072   [(set (match_operand:DI 0 "register_operand" "=d")
1073         (sign_extend:DI
1074             (minus:SI (match_operand:SI 1 "register_operand" "d")
1075                       (match_operand:SI 2 "register_operand" "d"))))]
1076   "TARGET_64BIT"
1077   "subu\t%0,%1,%2"
1078   [(set_attr "type" "arith")
1079    (set_attr "mode" "DI")])
1080 \f
1081 ;;
1082 ;;  ....................
1083 ;;
1084 ;;      MULTIPLICATION
1085 ;;
1086 ;;  ....................
1087 ;;
1088
1089 (define_expand "mul<mode>3"
1090   [(set (match_operand:SCALARF 0 "register_operand")
1091         (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
1092                       (match_operand:SCALARF 2 "register_operand")))]
1093   ""
1094   "")
1095
1096 (define_insn "*mul<mode>3"
1097   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1098         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1099                       (match_operand:SCALARF 2 "register_operand" "f")))]
1100   "!TARGET_4300_MUL_FIX"
1101   "mul.<fmt>\t%0,%1,%2"
1102   [(set_attr "type" "fmul")
1103    (set_attr "mode" "<MODE>")])
1104
1105 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
1106 ;; operands may corrupt immediately following multiplies. This is a
1107 ;; simple fix to insert NOPs.
1108
1109 (define_insn "*mul<mode>3_r4300"
1110   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1111         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1112                       (match_operand:SCALARF 2 "register_operand" "f")))]
1113   "TARGET_4300_MUL_FIX"
1114   "mul.<fmt>\t%0,%1,%2\;nop"
1115   [(set_attr "type" "fmul")
1116    (set_attr "mode" "<MODE>")
1117    (set_attr "length" "8")])
1118
1119 (define_insn "mulv2sf3"
1120   [(set (match_operand:V2SF 0 "register_operand" "=f")
1121         (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
1122                    (match_operand:V2SF 2 "register_operand" "f")))]
1123   "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
1124   "mul.ps\t%0,%1,%2"
1125   [(set_attr "type" "fmul")
1126    (set_attr "mode" "SF")])
1127
1128 ;; The original R4000 has a cpu bug.  If a double-word or a variable
1129 ;; shift executes while an integer multiplication is in progress, the
1130 ;; shift may give an incorrect result.  Avoid this by keeping the mflo
1131 ;; with the mult on the R4000.
1132 ;;
1133 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
1134 ;; (also valid for MIPS R4000MC processors):
1135 ;;
1136 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
1137 ;;      this errata description.
1138 ;;      The following code sequence causes the R4000 to incorrectly
1139 ;;      execute the Double Shift Right Arithmetic 32 (dsra32)
1140 ;;      instruction.  If the dsra32 instruction is executed during an
1141 ;;      integer multiply, the dsra32 will only shift by the amount in
1142 ;;      specified in the instruction rather than the amount plus 32
1143 ;;      bits.
1144 ;;      instruction 1:          mult    rs,rt           integer multiply
1145 ;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
1146 ;;                                                      right arithmetic + 32
1147 ;;      Workaround: A dsra32 instruction placed after an integer
1148 ;;      multiply should not be one of the 11 instructions after the
1149 ;;      multiply instruction."
1150 ;;
1151 ;; and:
1152 ;;
1153 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
1154 ;;      the following description.
1155 ;;      All extended shifts (shift by n+32) and variable shifts (32 and
1156 ;;      64-bit versions) may produce incorrect results under the
1157 ;;      following conditions:
1158 ;;      1) An integer multiply is currently executing
1159 ;;      2) These types of shift instructions are executed immediately
1160 ;;         following an integer divide instruction.
1161 ;;      Workaround:
1162 ;;      1) Make sure no integer multiply is running wihen these
1163 ;;         instruction are executed.  If this cannot be predicted at
1164 ;;         compile time, then insert a "mfhi" to R0 instruction
1165 ;;         immediately after the integer multiply instruction.  This
1166 ;;         will cause the integer multiply to complete before the shift
1167 ;;         is executed.
1168 ;;      2) Separate integer divide and these two classes of shift
1169 ;;         instructions by another instruction or a noop."
1170 ;;
1171 ;; These processors have PRId values of 0x00004220 and 0x00004300,
1172 ;; respectively.
1173
1174 (define_expand "mulsi3"
1175   [(set (match_operand:SI 0 "register_operand")
1176         (mult:SI (match_operand:SI 1 "register_operand")
1177                  (match_operand:SI 2 "register_operand")))]
1178   ""
1179 {
1180   if (ISA_HAS_MUL3)
1181     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1182   else if (TARGET_FIX_R4000)
1183     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1184   else
1185     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1186   DONE;
1187 })
1188
1189 (define_expand "muldi3"
1190   [(set (match_operand:DI 0 "register_operand")
1191         (mult:DI (match_operand:DI 1 "register_operand")
1192                  (match_operand:DI 2 "register_operand")))]
1193   "TARGET_64BIT"
1194 {
1195   if (TARGET_FIX_R4000)
1196     emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
1197   else
1198     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1199   DONE;
1200 })
1201
1202 (define_insn "mulsi3_mult3"
1203   [(set (match_operand:SI 0 "register_operand" "=d,l")
1204         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1205                  (match_operand:SI 2 "register_operand" "d,d")))
1206    (clobber (match_scratch:SI 3 "=l,X"))]
1207   "ISA_HAS_MUL3"
1208 {
1209   if (which_alternative == 1)
1210     return "mult\t%1,%2";
1211   if (TARGET_MIPS3900)
1212     return "mult\t%0,%1,%2";
1213   return "mul\t%0,%1,%2";
1214 }
1215   [(set_attr "type" "imul3,imul")
1216    (set_attr "mode" "SI")])
1217
1218 ;; If a register gets allocated to LO, and we spill to memory, the reload
1219 ;; will include a move from LO to a GPR.  Merge it into the multiplication
1220 ;; if it can set the GPR directly.
1221 ;;
1222 ;; Operand 0: LO
1223 ;; Operand 1: GPR (1st multiplication operand)
1224 ;; Operand 2: GPR (2nd multiplication operand)
1225 ;; Operand 3: GPR (destination)
1226 (define_peephole2
1227   [(parallel
1228        [(set (match_operand:SI 0 "lo_operand")
1229              (mult:SI (match_operand:SI 1 "d_operand")
1230                       (match_operand:SI 2 "d_operand")))
1231         (clobber (scratch:SI))])
1232    (set (match_operand:SI 3 "d_operand")
1233         (match_dup 0))]
1234   "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[0])"
1235   [(parallel
1236        [(set (match_dup 3)
1237              (mult:SI (match_dup 1)
1238                       (match_dup 2)))
1239         (clobber (match_dup 0))])])
1240
1241 (define_insn "mul<mode>3_internal"
1242   [(set (match_operand:GPR 0 "register_operand" "=l")
1243         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1244                   (match_operand:GPR 2 "register_operand" "d")))]
1245   "!TARGET_FIX_R4000"
1246   "<d>mult\t%1,%2"
1247   [(set_attr "type" "imul")
1248    (set_attr "mode" "<MODE>")])
1249
1250 (define_insn "mul<mode>3_r4000"
1251   [(set (match_operand:GPR 0 "register_operand" "=d")
1252         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1253                   (match_operand:GPR 2 "register_operand" "d")))
1254    (clobber (match_scratch:GPR 3 "=l"))]
1255   "TARGET_FIX_R4000"
1256   "<d>mult\t%1,%2\;mflo\t%0"
1257   [(set_attr "type" "imul")
1258    (set_attr "mode" "<MODE>")
1259    (set_attr "length" "8")])
1260
1261 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1262 ;; of "mult; mflo".  They have the same latency, but the first form gives
1263 ;; us an extra cycle to compute the operands.
1264
1265 ;; Operand 0: LO
1266 ;; Operand 1: GPR (1st multiplication operand)
1267 ;; Operand 2: GPR (2nd multiplication operand)
1268 ;; Operand 3: GPR (destination)
1269 (define_peephole2
1270   [(set (match_operand:SI 0 "lo_operand")
1271         (mult:SI (match_operand:SI 1 "d_operand")
1272                  (match_operand:SI 2 "d_operand")))
1273    (set (match_operand:SI 3 "d_operand")
1274         (match_dup 0))]
1275   "ISA_HAS_MACC && !ISA_HAS_MUL3"
1276   [(set (match_dup 0)
1277         (const_int 0))
1278    (parallel
1279        [(set (match_dup 0)
1280              (plus:SI (mult:SI (match_dup 1)
1281                                (match_dup 2))
1282                       (match_dup 0)))
1283         (set (match_dup 3)
1284              (plus:SI (mult:SI (match_dup 1)
1285                                (match_dup 2))
1286                       (match_dup 0)))])])
1287
1288 ;; Multiply-accumulate patterns
1289
1290 ;; For processors that can copy the output to a general register:
1291 ;;
1292 ;; The all-d alternative is needed because the combiner will find this
1293 ;; pattern and then register alloc/reload will move registers around to
1294 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1295 ;;
1296 ;; The last alternative should be made slightly less desirable, but adding
1297 ;; "?" to the constraint is too strong, and causes values to be loaded into
1298 ;; LO even when that's more costly.  For now, using "*d" mostly does the
1299 ;; trick.
1300 (define_insn "*mul_acc_si"
1301   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1302         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1303                           (match_operand:SI 2 "register_operand" "d,d,d"))
1304                  (match_operand:SI 3 "register_operand" "0,l,*d")))
1305    (clobber (match_scratch:SI 4 "=X,3,l"))
1306    (clobber (match_scratch:SI 5 "=X,X,&d"))]
1307   "(TARGET_MIPS3900
1308    || GENERATE_MADD_MSUB)
1309    && !TARGET_MIPS16"
1310 {
1311   static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1312   if (which_alternative == 2)
1313     return "#";
1314   if (GENERATE_MADD_MSUB && which_alternative != 0)
1315     return "#";
1316   return madd[which_alternative];
1317 }
1318   [(set_attr "type"     "imadd")
1319    (set_attr "mode"     "SI")
1320    (set_attr "length"   "4,4,8")])
1321
1322 ;; Split *mul_acc_si if both the source and destination accumulator
1323 ;; values are GPRs.
1324 (define_split
1325   [(set (match_operand:SI 0 "d_operand")
1326         (plus:SI (mult:SI (match_operand:SI 1 "d_operand")
1327                           (match_operand:SI 2 "d_operand"))
1328                  (match_operand:SI 3 "d_operand")))
1329    (clobber (match_operand:SI 4 "lo_operand"))
1330    (clobber (match_operand:SI 5 "d_operand"))]
1331   "reload_completed"
1332   [(parallel [(set (match_dup 5)
1333                    (mult:SI (match_dup 1) (match_dup 2)))
1334               (clobber (match_dup 4))])
1335    (set (match_dup 0) (plus:SI (match_dup 5) (match_dup 3)))]
1336   "")
1337
1338 ;; Split *mul_acc_si if the destination accumulator value is in a GPR
1339 ;; and the source accumulator value is in LO.
1340 (define_split
1341   [(set (match_operand:SI 0 "d_operand")
1342         (plus:SI (mult:SI (match_operand:SI 1 "d_operand")
1343                           (match_operand:SI 2 "d_operand"))
1344                  (match_operand:SI 3 "lo_operand")))
1345    (clobber (match_dup 3))
1346    (clobber (scratch:SI))]
1347   "reload_completed"
1348   [(parallel [(set (match_dup 3)
1349                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1350                             (match_dup 3)))
1351               (clobber (scratch:SI))
1352               (clobber (scratch:SI))])
1353    (set (match_dup 0) (match_dup 3))])
1354
1355 (define_insn "*macc"
1356   [(set (match_operand:SI 0 "register_operand" "=l,d")
1357         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1358                           (match_operand:SI 2 "register_operand" "d,d"))
1359                  (match_operand:SI 3 "register_operand" "0,l")))
1360    (clobber (match_scratch:SI 4 "=X,3"))]
1361   "ISA_HAS_MACC"
1362 {
1363   if (which_alternative == 1)
1364     return "macc\t%0,%1,%2";
1365   else if (TARGET_MIPS5500)
1366     return "madd\t%1,%2";
1367   else
1368     /* The VR4130 assumes that there is a two-cycle latency between a macc
1369        that "writes" to $0 and an instruction that reads from it.  We avoid
1370        this by assigning to $1 instead.  */
1371     return "%[macc\t%@,%1,%2%]";
1372 }
1373   [(set_attr "type" "imadd")
1374    (set_attr "mode" "SI")])
1375
1376 (define_insn "*msac"
1377   [(set (match_operand:SI 0 "register_operand" "=l,d")
1378         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1379                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1380                            (match_operand:SI 3 "register_operand" "d,d"))))
1381    (clobber (match_scratch:SI 4 "=X,1"))]
1382   "ISA_HAS_MSAC"
1383 {
1384   if (which_alternative == 1)
1385     return "msac\t%0,%2,%3";
1386   else if (TARGET_MIPS5500)
1387     return "msub\t%2,%3";
1388   else
1389     return "msac\t$0,%2,%3";
1390 }
1391   [(set_attr "type"     "imadd")
1392    (set_attr "mode"     "SI")])
1393
1394 ;; An msac-like instruction implemented using negation and a macc.
1395 (define_insn_and_split "*msac_using_macc"
1396   [(set (match_operand:SI 0 "register_operand" "=l,d")
1397         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1398                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1399                            (match_operand:SI 3 "register_operand" "d,d"))))
1400    (clobber (match_scratch:SI 4 "=X,1"))
1401    (clobber (match_scratch:SI 5 "=d,d"))]
1402   "ISA_HAS_MACC && !ISA_HAS_MSAC"
1403   "#"
1404   "&& reload_completed"
1405   [(set (match_dup 5)
1406         (neg:SI (match_dup 3)))
1407    (parallel
1408        [(set (match_dup 0)
1409              (plus:SI (mult:SI (match_dup 2)
1410                                (match_dup 5))
1411                       (match_dup 1)))
1412         (clobber (match_dup 4))])]
1413   ""
1414   [(set_attr "type"     "imadd")
1415    (set_attr "length"   "8")])
1416
1417 ;; Patterns generated by the define_peephole2 below.
1418
1419 (define_insn "*macc2"
1420   [(set (match_operand:SI 0 "register_operand" "=l")
1421         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1422                           (match_operand:SI 2 "register_operand" "d"))
1423                  (match_dup 0)))
1424    (set (match_operand:SI 3 "register_operand" "=d")
1425         (plus:SI (mult:SI (match_dup 1)
1426                           (match_dup 2))
1427                  (match_dup 0)))]
1428   "ISA_HAS_MACC && reload_completed"
1429   "macc\t%3,%1,%2"
1430   [(set_attr "type"     "imadd")
1431    (set_attr "mode"     "SI")])
1432
1433 (define_insn "*msac2"
1434   [(set (match_operand:SI 0 "register_operand" "=l")
1435         (minus:SI (match_dup 0)
1436                   (mult:SI (match_operand:SI 1 "register_operand" "d")
1437                            (match_operand:SI 2 "register_operand" "d"))))
1438    (set (match_operand:SI 3 "register_operand" "=d")
1439         (minus:SI (match_dup 0)
1440                   (mult:SI (match_dup 1)
1441                            (match_dup 2))))]
1442   "ISA_HAS_MSAC && reload_completed"
1443   "msac\t%3,%1,%2"
1444   [(set_attr "type"     "imadd")
1445    (set_attr "mode"     "SI")])
1446
1447 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1448 ;; Similarly msac.
1449 ;;
1450 ;; Operand 0: LO
1451 ;; Operand 1: macc/msac
1452 ;; Operand 2: GPR (destination)
1453 (define_peephole2
1454   [(parallel
1455        [(set (match_operand:SI 0 "lo_operand")
1456              (match_operand:SI 1 "macc_msac_operand"))
1457         (clobber (scratch:SI))])
1458    (set (match_operand:SI 2 "d_operand")
1459         (match_dup 0))]
1460   ""
1461   [(parallel [(set (match_dup 0)
1462                    (match_dup 1))
1463               (set (match_dup 2)
1464                    (match_dup 1))])])
1465
1466 ;; When we have a three-address multiplication instruction, it should
1467 ;; be faster to do a separate multiply and add, rather than moving
1468 ;; something into LO in order to use a macc instruction.
1469 ;;
1470 ;; This peephole needs a scratch register to cater for the case when one
1471 ;; of the multiplication operands is the same as the destination.
1472 ;;
1473 ;; Operand 0: GPR (scratch)
1474 ;; Operand 1: LO
1475 ;; Operand 2: GPR (addend)
1476 ;; Operand 3: GPR (destination)
1477 ;; Operand 4: macc/msac
1478 ;; Operand 5: new multiplication
1479 ;; Operand 6: new addition/subtraction
1480 (define_peephole2
1481   [(match_scratch:SI 0 "d")
1482    (set (match_operand:SI 1 "lo_operand")
1483         (match_operand:SI 2 "d_operand"))
1484    (match_dup 0)
1485    (parallel
1486        [(set (match_operand:SI 3 "d_operand")
1487              (match_operand:SI 4 "macc_msac_operand"))
1488         (clobber (match_dup 1))])]
1489   "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[1])"
1490   [(parallel [(set (match_dup 0)
1491                    (match_dup 5))
1492               (clobber (match_dup 1))])
1493    (set (match_dup 3)
1494         (match_dup 6))]
1495 {
1496   operands[5] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1497   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1498                                 operands[2], operands[0]);
1499 })
1500
1501 ;; Same as above, except LO is the initial target of the macc.
1502 ;;
1503 ;; Operand 0: GPR (scratch)
1504 ;; Operand 1: LO
1505 ;; Operand 2: GPR (addend)
1506 ;; Operand 3: macc/msac
1507 ;; Operand 4: GPR (destination)
1508 ;; Operand 5: new multiplication
1509 ;; Operand 6: new addition/subtraction
1510 (define_peephole2
1511   [(match_scratch:SI 0 "d")
1512    (set (match_operand:SI 1 "lo_operand")
1513         (match_operand:SI 2 "d_operand"))
1514    (match_dup 0)
1515    (parallel
1516        [(set (match_dup 1)
1517              (match_operand:SI 3 "macc_msac_operand"))
1518         (clobber (scratch:SI))])
1519    (match_dup 0)
1520    (set (match_operand:SI 4 "d_operand")
1521         (match_dup 1))]
1522   "ISA_HAS_MUL3 && peep2_reg_dead_p (3, operands[1])"
1523   [(parallel [(set (match_dup 0)
1524                    (match_dup 5))
1525               (clobber (match_dup 1))])
1526    (set (match_dup 4)
1527         (match_dup 6))]
1528 {
1529   operands[5] = XEXP (operands[3], GET_CODE (operands[3]) == PLUS ? 0 : 1);
1530   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
1531                                 operands[2], operands[0]);
1532 })
1533
1534 (define_insn "*mul_sub_si"
1535   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1536         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1537                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1538                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1539    (clobber (match_scratch:SI 4 "=X,1,l"))
1540    (clobber (match_scratch:SI 5 "=X,X,&d"))]
1541   "GENERATE_MADD_MSUB"
1542   "@
1543    msub\t%2,%3
1544    #
1545    #"
1546   [(set_attr "type"     "imadd")
1547    (set_attr "mode"     "SI")
1548    (set_attr "length"   "4,8,8")])
1549
1550 ;; Split *mul_sub_si if both the source and destination accumulator
1551 ;; values are GPRs.
1552 (define_split
1553   [(set (match_operand:SI 0 "d_operand")
1554         (minus:SI (match_operand:SI 1 "d_operand")
1555                   (mult:SI (match_operand:SI 2 "d_operand")
1556                            (match_operand:SI 3 "d_operand"))))
1557    (clobber (match_operand:SI 4 "lo_operand"))
1558    (clobber (match_operand:SI 5 "d_operand"))]
1559   "reload_completed"
1560   [(parallel [(set (match_dup 5)
1561                    (mult:SI (match_dup 2) (match_dup 3)))
1562               (clobber (match_dup 4))])
1563    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 5)))]
1564   "")
1565
1566 ;; Split *mul_acc_si if the destination accumulator value is in a GPR
1567 ;; and the source accumulator value is in LO.
1568 (define_split
1569   [(set (match_operand:SI 0 "d_operand")
1570         (minus:SI (match_operand:SI 1 "lo_operand")
1571                   (mult:SI (match_operand:SI 2 "d_operand")
1572                            (match_operand:SI 3 "d_operand"))))
1573    (clobber (match_dup 1))
1574    (clobber (scratch:SI))]
1575   "reload_completed"
1576   [(parallel [(set (match_dup 1)
1577                    (minus:SI (match_dup 1)
1578                              (mult:SI (match_dup 2) (match_dup 3))))
1579               (clobber (scratch:SI))
1580               (clobber (scratch:SI))])
1581    (set (match_dup 0) (match_dup 1))]
1582   "")
1583
1584 (define_insn "*muls"
1585   [(set (match_operand:SI 0 "register_operand" "=l,d")
1586         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1587                          (match_operand:SI 2 "register_operand" "d,d"))))
1588    (clobber (match_scratch:SI 3 "=X,l"))]
1589   "ISA_HAS_MULS"
1590   "@
1591    muls\t$0,%1,%2
1592    muls\t%0,%1,%2"
1593   [(set_attr "type"     "imul,imul3")
1594    (set_attr "mode"     "SI")])
1595
1596 (define_expand "<u>mulsidi3"
1597   [(set (match_operand:DI 0 "register_operand")
1598         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1599                  (any_extend:DI (match_operand:SI 2 "register_operand"))))]
1600   "!TARGET_64BIT || !TARGET_FIX_R4000"
1601 {
1602   if (TARGET_64BIT)
1603     emit_insn (gen_<u>mulsidi3_64bit (operands[0], operands[1], operands[2]));
1604   else if (TARGET_FIX_R4000)
1605     emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1606                                             operands[2]));
1607   else
1608     emit_insn (gen_<u>mulsidi3_32bit (operands[0], operands[1], operands[2]));
1609   DONE;
1610 })
1611
1612 (define_insn "<u>mulsidi3_32bit"
1613   [(set (match_operand:DI 0 "register_operand" "=x")
1614         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1615                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1616   "!TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DSPR2"
1617   "mult<u>\t%1,%2"
1618   [(set_attr "type" "imul")
1619    (set_attr "mode" "SI")])
1620
1621 (define_insn "<u>mulsidi3_32bit_r4000"
1622   [(set (match_operand:DI 0 "register_operand" "=d")
1623         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1624                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1625    (clobber (match_scratch:DI 3 "=x"))]
1626   "!TARGET_64BIT && TARGET_FIX_R4000"
1627   "mult<u>\t%1,%2\;mflo\t%L0\;mfhi\t%M0"
1628   [(set_attr "type" "imul")
1629    (set_attr "mode" "SI")
1630    (set_attr "length" "12")])
1631
1632 (define_insn_and_split "<u>mulsidi3_64bit"
1633   [(set (match_operand:DI 0 "register_operand" "=d")
1634         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1635                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1636    (clobber (match_scratch:TI 3 "=x"))
1637    (clobber (match_scratch:DI 4 "=d"))]
1638   "TARGET_64BIT && !TARGET_FIX_R4000"
1639   "#"
1640   "&& reload_completed"
1641   [(set (match_dup 3)
1642         (unspec:TI [(mult:DI (any_extend:DI (match_dup 1))
1643                              (any_extend:DI (match_dup 2)))]
1644                    UNSPEC_SET_HILO))
1645
1646    ;; OP4 <- LO, OP0 <- HI
1647    (set (match_dup 4) (match_dup 5))
1648    (set (match_dup 0) (unspec:DI [(match_dup 3)] UNSPEC_MFHI))
1649
1650    ;; Zero-extend OP4.
1651    (set (match_dup 4)
1652         (ashift:DI (match_dup 4)
1653                    (const_int 32)))
1654    (set (match_dup 4)
1655         (lshiftrt:DI (match_dup 4)
1656                      (const_int 32)))
1657
1658    ;; Shift OP0 into place.
1659    (set (match_dup 0)
1660         (ashift:DI (match_dup 0)
1661                    (const_int 32)))
1662
1663    ;; OR the two halves together
1664    (set (match_dup 0)
1665         (ior:DI (match_dup 0)
1666                 (match_dup 4)))]
1667   { operands[5] = gen_rtx_REG (DImode, LO_REGNUM); }
1668   [(set_attr "type" "imul")
1669    (set_attr "mode" "SI")
1670    (set_attr "length" "24")])
1671
1672 (define_insn "<u>mulsidi3_64bit_hilo"
1673   [(set (match_operand:TI 0 "register_operand" "=x")
1674         (unspec:TI
1675           [(mult:DI
1676              (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1677              (any_extend:DI (match_operand:SI 2 "register_operand" "d")))]
1678           UNSPEC_SET_HILO))]
1679   "TARGET_64BIT && !TARGET_FIX_R4000"
1680   "mult<u>\t%1,%2"
1681   [(set_attr "type" "imul")
1682    (set_attr "mode" "SI")])
1683
1684 ;; Widening multiply with negation.
1685 (define_insn "*muls<u>_di"
1686   [(set (match_operand:DI 0 "register_operand" "=x")
1687         (neg:DI
1688          (mult:DI
1689           (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1690           (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1691   "!TARGET_64BIT && ISA_HAS_MULS"
1692   "muls<u>\t$0,%1,%2"
1693   [(set_attr "type" "imul")
1694    (set_attr "mode" "SI")])
1695
1696 (define_insn "<u>msubsidi4"
1697   [(set (match_operand:DI 0 "register_operand" "=ka")
1698         (minus:DI
1699            (match_operand:DI 3 "register_operand" "0")
1700            (mult:DI
1701               (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1702               (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1703   "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || ISA_HAS_DSPR2)"
1704 {
1705   if (ISA_HAS_DSPR2)
1706     return "msub<u>\t%q0,%1,%2";
1707   else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB)
1708     return "msub<u>\t%1,%2";
1709   else
1710     return "msac<u>\t$0,%1,%2";
1711 }
1712   [(set_attr "type" "imadd")
1713    (set_attr "mode" "SI")])
1714
1715 ;; _highpart patterns
1716
1717 (define_expand "<su>mulsi3_highpart"
1718   [(set (match_operand:SI 0 "register_operand")
1719         (truncate:SI
1720          (lshiftrt:DI
1721           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1722                    (any_extend:DI (match_operand:SI 2 "register_operand")))
1723           (const_int 32))))]
1724   ""
1725 {
1726   if (ISA_HAS_MULHI)
1727     emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1728                                                        operands[1],
1729                                                        operands[2]));
1730   else
1731     emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1732                                                  operands[2]));
1733   DONE;
1734 })
1735
1736 (define_insn_and_split "<su>mulsi3_highpart_internal"
1737   [(set (match_operand:SI 0 "register_operand" "=d")
1738         (truncate:SI
1739          (lshiftrt:DI
1740           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1741                    (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1742           (const_int 32))))
1743    (clobber (match_scratch:SI 3 "=l"))]
1744   "!ISA_HAS_MULHI"
1745   { return TARGET_FIX_R4000 ? "mult<u>\t%1,%2\n\tmfhi\t%0" : "#"; }
1746   "&& reload_completed && !TARGET_FIX_R4000"
1747   [(const_int 0)]
1748 {
1749   rtx hilo;
1750
1751   if (TARGET_64BIT)
1752     {
1753       hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
1754       emit_insn (gen_<u>mulsidi3_64bit_hilo (hilo, operands[1], operands[2]));
1755       emit_insn (gen_mfhisi_ti (operands[0], hilo));
1756     }
1757   else
1758     {
1759       hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
1760       emit_insn (gen_<u>mulsidi3_32bit (hilo, operands[1], operands[2]));
1761       emit_insn (gen_mfhisi_di (operands[0], hilo));
1762     }
1763   DONE;
1764 }
1765   [(set_attr "type" "imul")
1766    (set_attr "mode" "SI")
1767    (set_attr "length" "8")])
1768
1769 (define_insn "<su>mulsi3_highpart_mulhi_internal"
1770   [(set (match_operand:SI 0 "register_operand" "=d")
1771         (truncate:SI
1772          (lshiftrt:DI
1773           (mult:DI
1774            (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1775            (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1776           (const_int 32))))
1777    (clobber (match_scratch:SI 3 "=l"))]
1778   "ISA_HAS_MULHI"
1779   "mulhi<u>\t%0,%1,%2"
1780   [(set_attr "type" "imul3")
1781    (set_attr "mode" "SI")])
1782
1783 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1784   [(set (match_operand:SI 0 "register_operand" "=d")
1785         (truncate:SI
1786          (lshiftrt:DI
1787           (neg:DI
1788            (mult:DI
1789             (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1790             (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1791           (const_int 32))))
1792    (clobber (match_scratch:SI 3 "=l"))]
1793   "ISA_HAS_MULHI"
1794   "mulshi<u>\t%0,%1,%2"
1795   [(set_attr "type" "imul3")
1796    (set_attr "mode" "SI")])
1797
1798 ;; Disable unsigned multiplication for -mfix-vr4120.  This is for VR4120
1799 ;; errata MD(0), which says that dmultu does not always produce the
1800 ;; correct result.
1801 (define_insn_and_split "<su>muldi3_highpart"
1802   [(set (match_operand:DI 0 "register_operand" "=d")
1803         (truncate:DI
1804          (lshiftrt:TI
1805           (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1806                    (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1807           (const_int 64))))
1808    (clobber (match_scratch:DI 3 "=l"))]
1809   "TARGET_64BIT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1810   { return TARGET_FIX_R4000 ? "dmult<u>\t%1,%2\n\tmfhi\t%0" : "#"; }
1811   "&& reload_completed && !TARGET_FIX_R4000"
1812   [(const_int 0)]
1813 {
1814   rtx hilo;
1815
1816   hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
1817   emit_insn (gen_<u>mulditi3_internal (hilo, operands[1], operands[2]));
1818   emit_insn (gen_mfhidi_ti (operands[0], hilo));
1819   DONE;
1820 }
1821   [(set_attr "type" "imul")
1822    (set_attr "mode" "DI")
1823    (set_attr "length" "8")])
1824
1825 (define_expand "<u>mulditi3"
1826   [(set (match_operand:TI 0 "register_operand")
1827         (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
1828                  (any_extend:TI (match_operand:DI 2 "register_operand"))))]
1829   "TARGET_64BIT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1830 {
1831   if (TARGET_FIX_R4000)
1832     emit_insn (gen_<u>mulditi3_r4000 (operands[0], operands[1], operands[2]));
1833   else
1834     emit_insn (gen_<u>mulditi3_internal (operands[0], operands[1],
1835                                          operands[2]));
1836   DONE;
1837 })
1838
1839 (define_insn "<u>mulditi3_internal"
1840   [(set (match_operand:TI 0 "register_operand" "=x")
1841         (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1842                  (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))]
1843   "TARGET_64BIT
1844    && !TARGET_FIX_R4000
1845    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1846   "dmult<u>\t%1,%2"
1847   [(set_attr "type" "imul")
1848    (set_attr "mode" "DI")])
1849
1850 (define_insn "<u>mulditi3_r4000"
1851   [(set (match_operand:TI 0 "register_operand" "=d")
1852         (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1853                  (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))
1854    (clobber (match_scratch:TI 3 "=x"))]
1855   "TARGET_64BIT
1856    && TARGET_FIX_R4000
1857    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1858   "dmult<u>\t%1,%2\;mflo\t%L0\;mfhi\t%M0"
1859   [(set_attr "type" "imul")
1860    (set_attr "mode" "DI")
1861    (set_attr "length" "12")])
1862
1863 ;; The R4650 supports a 32-bit multiply/ 64-bit accumulate
1864 ;; instruction.  The HI/LO registers are used as a 64-bit accumulator.
1865
1866 (define_insn "madsi"
1867   [(set (match_operand:SI 0 "register_operand" "+l")
1868         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1869                           (match_operand:SI 2 "register_operand" "d"))
1870                  (match_dup 0)))]
1871   "TARGET_MAD"
1872   "mad\t%1,%2"
1873   [(set_attr "type"     "imadd")
1874    (set_attr "mode"     "SI")])
1875
1876 (define_insn "<u>maddsidi4"
1877   [(set (match_operand:DI 0 "register_operand" "=ka")
1878         (plus:DI
1879          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1880                   (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1881          (match_operand:DI 3 "register_operand" "0")))]
1882   "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || ISA_HAS_DSPR2)
1883    && !TARGET_64BIT"
1884 {
1885   if (TARGET_MAD)
1886     return "mad<u>\t%1,%2";
1887   else if (ISA_HAS_DSPR2)
1888     return "madd<u>\t%q0,%1,%2";
1889   else if (GENERATE_MADD_MSUB || TARGET_MIPS5500)
1890     return "madd<u>\t%1,%2";
1891   else
1892     /* See comment in *macc.  */
1893     return "%[macc<u>\t%@,%1,%2%]";
1894 }
1895   [(set_attr "type" "imadd")
1896    (set_attr "mode" "SI")])
1897
1898 ;; Floating point multiply accumulate instructions.
1899
1900 (define_insn "*madd<mode>"
1901   [(set (match_operand:ANYF 0 "register_operand" "=f")
1902         (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1903                               (match_operand:ANYF 2 "register_operand" "f"))
1904                    (match_operand:ANYF 3 "register_operand" "f")))]
1905   "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1906   "madd.<fmt>\t%0,%3,%1,%2"
1907   [(set_attr "type" "fmadd")
1908    (set_attr "mode" "<UNITMODE>")])
1909
1910 (define_insn "*msub<mode>"
1911   [(set (match_operand:ANYF 0 "register_operand" "=f")
1912         (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1913                                (match_operand:ANYF 2 "register_operand" "f"))
1914                     (match_operand:ANYF 3 "register_operand" "f")))]
1915   "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1916   "msub.<fmt>\t%0,%3,%1,%2"
1917   [(set_attr "type" "fmadd")
1918    (set_attr "mode" "<UNITMODE>")])
1919
1920 (define_insn "*nmadd<mode>"
1921   [(set (match_operand:ANYF 0 "register_operand" "=f")
1922         (neg:ANYF (plus:ANYF
1923                    (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1924                               (match_operand:ANYF 2 "register_operand" "f"))
1925                    (match_operand:ANYF 3 "register_operand" "f"))))]
1926   "ISA_HAS_NMADD_NMSUB (<MODE>mode)
1927    && TARGET_FUSED_MADD
1928    && HONOR_SIGNED_ZEROS (<MODE>mode)
1929    && !HONOR_NANS (<MODE>mode)"
1930   "nmadd.<fmt>\t%0,%3,%1,%2"
1931   [(set_attr "type" "fmadd")
1932    (set_attr "mode" "<UNITMODE>")])
1933
1934 (define_insn "*nmadd<mode>_fastmath"
1935   [(set (match_operand:ANYF 0 "register_operand" "=f")
1936         (minus:ANYF
1937          (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
1938                     (match_operand:ANYF 2 "register_operand" "f"))
1939          (match_operand:ANYF 3 "register_operand" "f")))]
1940   "ISA_HAS_NMADD_NMSUB (<MODE>mode)
1941    && TARGET_FUSED_MADD
1942    && !HONOR_SIGNED_ZEROS (<MODE>mode)
1943    && !HONOR_NANS (<MODE>mode)"
1944   "nmadd.<fmt>\t%0,%3,%1,%2"
1945   [(set_attr "type" "fmadd")
1946    (set_attr "mode" "<UNITMODE>")])
1947
1948 (define_insn "*nmsub<mode>"
1949   [(set (match_operand:ANYF 0 "register_operand" "=f")
1950         (neg:ANYF (minus:ANYF
1951                    (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1952                               (match_operand:ANYF 3 "register_operand" "f"))
1953                    (match_operand:ANYF 1 "register_operand" "f"))))]
1954   "ISA_HAS_NMADD_NMSUB (<MODE>mode)
1955    && TARGET_FUSED_MADD
1956    && HONOR_SIGNED_ZEROS (<MODE>mode)
1957    && !HONOR_NANS (<MODE>mode)"
1958   "nmsub.<fmt>\t%0,%1,%2,%3"
1959   [(set_attr "type" "fmadd")
1960    (set_attr "mode" "<UNITMODE>")])
1961
1962 (define_insn "*nmsub<mode>_fastmath"
1963   [(set (match_operand:ANYF 0 "register_operand" "=f")
1964         (minus:ANYF
1965          (match_operand:ANYF 1 "register_operand" "f")
1966          (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1967                     (match_operand:ANYF 3 "register_operand" "f"))))]
1968   "ISA_HAS_NMADD_NMSUB (<MODE>mode)
1969    && TARGET_FUSED_MADD
1970    && !HONOR_SIGNED_ZEROS (<MODE>mode)
1971    && !HONOR_NANS (<MODE>mode)"
1972   "nmsub.<fmt>\t%0,%1,%2,%3"
1973   [(set_attr "type" "fmadd")
1974    (set_attr "mode" "<UNITMODE>")])
1975 \f
1976 ;;
1977 ;;  ....................
1978 ;;
1979 ;;      DIVISION and REMAINDER
1980 ;;
1981 ;;  ....................
1982 ;;
1983
1984 (define_expand "div<mode>3"
1985   [(set (match_operand:ANYF 0 "register_operand")
1986         (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
1987                   (match_operand:ANYF 2 "register_operand")))]
1988   "<divide_condition>"
1989 {
1990   if (const_1_operand (operands[1], <MODE>mode))
1991     if (!(<recip_condition> && flag_unsafe_math_optimizations))
1992       operands[1] = force_reg (<MODE>mode, operands[1]);
1993 })
1994
1995 ;; These patterns work around the early SB-1 rev2 core "F1" erratum:
1996 ;;
1997 ;; If an mfc1 or dmfc1 happens to access the floating point register
1998 ;; file at the same time a long latency operation (div, sqrt, recip,
1999 ;; sqrt) iterates an intermediate result back through the floating
2000 ;; point register file bypass, then instead returning the correct
2001 ;; register value the mfc1 or dmfc1 operation returns the intermediate
2002 ;; result of the long latency operation.
2003 ;;
2004 ;; The workaround is to insert an unconditional 'mov' from/to the
2005 ;; long latency op destination register.
2006
2007 (define_insn "*div<mode>3"
2008   [(set (match_operand:ANYF 0 "register_operand" "=f")
2009         (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
2010                   (match_operand:ANYF 2 "register_operand" "f")))]
2011   "<divide_condition>"
2012 {
2013   if (TARGET_FIX_SB1)
2014     return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
2015   else
2016     return "div.<fmt>\t%0,%1,%2";
2017 }
2018   [(set_attr "type" "fdiv")
2019    (set_attr "mode" "<UNITMODE>")
2020    (set (attr "length")
2021         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2022                       (const_int 8)
2023                       (const_int 4)))])
2024
2025 (define_insn "*recip<mode>3"
2026   [(set (match_operand:ANYF 0 "register_operand" "=f")
2027         (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2028                   (match_operand:ANYF 2 "register_operand" "f")))]
2029   "<recip_condition> && flag_unsafe_math_optimizations"
2030 {
2031   if (TARGET_FIX_SB1)
2032     return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2033   else
2034     return "recip.<fmt>\t%0,%2";
2035 }
2036   [(set_attr "type" "frdiv")
2037    (set_attr "mode" "<UNITMODE>")
2038    (set (attr "length")
2039         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2040                       (const_int 8)
2041                       (const_int 4)))])
2042
2043 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2044 ;; with negative operands.  We use special libgcc functions instead.
2045 (define_insn_and_split "divmod<mode>4"
2046   [(set (match_operand:GPR 0 "register_operand" "=l")
2047         (div:GPR (match_operand:GPR 1 "register_operand" "d")
2048                  (match_operand:GPR 2 "register_operand" "d")))
2049    (set (match_operand:GPR 3 "register_operand" "=d")
2050         (mod:GPR (match_dup 1)
2051                  (match_dup 2)))]
2052   "!TARGET_FIX_VR4120"
2053   "#"
2054   "&& reload_completed"
2055   [(const_int 0)]
2056 {
2057   rtx hilo;
2058
2059   if (TARGET_64BIT)
2060     {
2061       hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2062       emit_insn (gen_divmod<mode>4_hilo_ti (hilo, operands[1], operands[2]));
2063       emit_insn (gen_mfhi<mode>_ti (operands[3], hilo));
2064     }
2065   else
2066     {
2067       hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
2068       emit_insn (gen_divmod<mode>4_hilo_di (hilo, operands[1], operands[2]));
2069       emit_insn (gen_mfhi<mode>_di (operands[3], hilo));
2070     }
2071   DONE;
2072 }
2073  [(set_attr "type" "idiv")
2074   (set_attr "mode" "<MODE>")
2075   (set_attr "length" "8")])
2076
2077 (define_insn_and_split "udivmod<mode>4"
2078   [(set (match_operand:GPR 0 "register_operand" "=l")
2079         (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
2080                   (match_operand:GPR 2 "register_operand" "d")))
2081    (set (match_operand:GPR 3 "register_operand" "=d")
2082         (umod:GPR (match_dup 1)
2083                   (match_dup 2)))]
2084   ""
2085   "#"
2086   "reload_completed"
2087   [(const_int 0)]
2088 {
2089   rtx hilo;
2090
2091   if (TARGET_64BIT)
2092     {
2093       hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2094       emit_insn (gen_udivmod<mode>4_hilo_ti (hilo, operands[1], operands[2]));
2095       emit_insn (gen_mfhi<mode>_ti (operands[3], hilo));
2096     }
2097   else
2098     {
2099       hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
2100       emit_insn (gen_udivmod<mode>4_hilo_di (hilo, operands[1], operands[2]));
2101       emit_insn (gen_mfhi<mode>_di (operands[3], hilo));
2102     }
2103   DONE;
2104 }
2105  [(set_attr "type" "idiv")
2106   (set_attr "mode" "<MODE>")
2107   (set_attr "length" "8")])
2108
2109 (define_insn "<u>divmod<GPR:mode>4_hilo_<HILO:mode>"
2110   [(set (match_operand:HILO 0 "register_operand" "=x")
2111         (unspec:HILO
2112           [(any_div:GPR (match_operand:GPR 1 "register_operand" "d")
2113                         (match_operand:GPR 2 "register_operand" "d"))]
2114           UNSPEC_SET_HILO))]
2115   ""
2116   { return mips_output_division ("<GPR:d>div<u>\t%.,%1,%2", operands); }
2117   [(set_attr "type" "idiv")
2118    (set_attr "mode" "<GPR:MODE>")])
2119 \f
2120 ;;
2121 ;;  ....................
2122 ;;
2123 ;;      SQUARE ROOT
2124 ;;
2125 ;;  ....................
2126
2127 ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
2128 ;; "*div[sd]f3" comment for details).
2129
2130 (define_insn "sqrt<mode>2"
2131   [(set (match_operand:ANYF 0 "register_operand" "=f")
2132         (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2133   "<sqrt_condition>"
2134 {
2135   if (TARGET_FIX_SB1)
2136     return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
2137   else
2138     return "sqrt.<fmt>\t%0,%1";
2139 }
2140   [(set_attr "type" "fsqrt")
2141    (set_attr "mode" "<UNITMODE>")
2142    (set (attr "length")
2143         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2144                       (const_int 8)
2145                       (const_int 4)))])
2146
2147 (define_insn "*rsqrt<mode>a"
2148   [(set (match_operand:ANYF 0 "register_operand" "=f")
2149         (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2150                   (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
2151   "<recip_condition> && flag_unsafe_math_optimizations"
2152 {
2153   if (TARGET_FIX_SB1)
2154     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2155   else
2156     return "rsqrt.<fmt>\t%0,%2";
2157 }
2158   [(set_attr "type" "frsqrt")
2159    (set_attr "mode" "<UNITMODE>")
2160    (set (attr "length")
2161         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2162                       (const_int 8)
2163                       (const_int 4)))])
2164
2165 (define_insn "*rsqrt<mode>b"
2166   [(set (match_operand:ANYF 0 "register_operand" "=f")
2167         (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2168                              (match_operand:ANYF 2 "register_operand" "f"))))]
2169   "<recip_condition> && flag_unsafe_math_optimizations"
2170 {
2171   if (TARGET_FIX_SB1)
2172     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2173   else
2174     return "rsqrt.<fmt>\t%0,%2";
2175 }
2176   [(set_attr "type" "frsqrt")
2177    (set_attr "mode" "<UNITMODE>")
2178    (set (attr "length")
2179         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2180                       (const_int 8)
2181                       (const_int 4)))])
2182 \f
2183 ;;
2184 ;;  ....................
2185 ;;
2186 ;;      ABSOLUTE VALUE
2187 ;;
2188 ;;  ....................
2189
2190 ;; Do not use the integer abs macro instruction, since that signals an
2191 ;; exception on -2147483648 (sigh).
2192
2193 ;; abs.fmt is an arithmetic instruction and treats all NaN inputs as
2194 ;; invalid; it does not clear their sign bits.  We therefore can't use
2195 ;; abs.fmt if the signs of NaNs matter.
2196
2197 (define_insn "abs<mode>2"
2198   [(set (match_operand:ANYF 0 "register_operand" "=f")
2199         (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2200   "!HONOR_NANS (<MODE>mode)"
2201   "abs.<fmt>\t%0,%1"
2202   [(set_attr "type" "fabs")
2203    (set_attr "mode" "<UNITMODE>")])
2204 \f
2205 ;;
2206 ;;  ...................
2207 ;;
2208 ;;  Count leading zeroes.
2209 ;;
2210 ;;  ...................
2211 ;;
2212
2213 (define_insn "clz<mode>2"
2214   [(set (match_operand:GPR 0 "register_operand" "=d")
2215         (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2216   "ISA_HAS_CLZ_CLO"
2217   "<d>clz\t%0,%1"
2218   [(set_attr "type" "clz")
2219    (set_attr "mode" "<MODE>")])
2220 \f
2221 ;;
2222 ;;  ....................
2223 ;;
2224 ;;      NEGATION and ONE'S COMPLEMENT
2225 ;;
2226 ;;  ....................
2227
2228 (define_insn "negsi2"
2229   [(set (match_operand:SI 0 "register_operand" "=d")
2230         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2231   ""
2232 {
2233   if (TARGET_MIPS16)
2234     return "neg\t%0,%1";
2235   else
2236     return "subu\t%0,%.,%1";
2237 }
2238   [(set_attr "type"     "arith")
2239    (set_attr "mode"     "SI")])
2240
2241 (define_insn "negdi2"
2242   [(set (match_operand:DI 0 "register_operand" "=d")
2243         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2244   "TARGET_64BIT && !TARGET_MIPS16"
2245   "dsubu\t%0,%.,%1"
2246   [(set_attr "type"     "arith")
2247    (set_attr "mode"     "DI")])
2248
2249 ;; neg.fmt is an arithmetic instruction and treats all NaN inputs as
2250 ;; invalid; it does not flip their sign bit.  We therefore can't use
2251 ;; neg.fmt if the signs of NaNs matter.
2252
2253 (define_insn "neg<mode>2"
2254   [(set (match_operand:ANYF 0 "register_operand" "=f")
2255         (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2256   "!HONOR_NANS (<MODE>mode)"
2257   "neg.<fmt>\t%0,%1"
2258   [(set_attr "type" "fneg")
2259    (set_attr "mode" "<UNITMODE>")])
2260
2261 (define_insn "one_cmpl<mode>2"
2262   [(set (match_operand:GPR 0 "register_operand" "=d")
2263         (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2264   ""
2265 {
2266   if (TARGET_MIPS16)
2267     return "not\t%0,%1";
2268   else
2269     return "nor\t%0,%.,%1";
2270 }
2271   [(set_attr "type" "logical")
2272    (set_attr "mode" "<MODE>")])
2273 \f
2274 ;;
2275 ;;  ....................
2276 ;;
2277 ;;      LOGICAL
2278 ;;
2279 ;;  ....................
2280 ;;
2281
2282 ;; Many of these instructions use trivial define_expands, because we
2283 ;; want to use a different set of constraints when TARGET_MIPS16.
2284
2285 (define_expand "and<mode>3"
2286   [(set (match_operand:GPR 0 "register_operand")
2287         (and:GPR (match_operand:GPR 1 "register_operand")
2288                  (match_operand:GPR 2 "uns_arith_operand")))]
2289   ""
2290 {
2291   if (TARGET_MIPS16)
2292     operands[2] = force_reg (<MODE>mode, operands[2]);
2293 })
2294
2295 (define_insn "*and<mode>3"
2296   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2297         (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2298                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2299   "!TARGET_MIPS16"
2300   "@
2301    and\t%0,%1,%2
2302    andi\t%0,%1,%x2"
2303   [(set_attr "type" "logical")
2304    (set_attr "mode" "<MODE>")])
2305
2306 (define_insn "*and<mode>3_mips16"
2307   [(set (match_operand:GPR 0 "register_operand" "=d")
2308         (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2309                  (match_operand:GPR 2 "register_operand" "d")))]
2310   "TARGET_MIPS16"
2311   "and\t%0,%2"
2312   [(set_attr "type" "logical")
2313    (set_attr "mode" "<MODE>")])
2314
2315 (define_expand "ior<mode>3"
2316   [(set (match_operand:GPR 0 "register_operand")
2317         (ior:GPR (match_operand:GPR 1 "register_operand")
2318                  (match_operand:GPR 2 "uns_arith_operand")))]
2319   ""
2320 {
2321   if (TARGET_MIPS16)
2322     operands[2] = force_reg (<MODE>mode, operands[2]);
2323 })
2324
2325 (define_insn "*ior<mode>3"
2326   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2327         (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2328                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2329   "!TARGET_MIPS16"
2330   "@
2331    or\t%0,%1,%2
2332    ori\t%0,%1,%x2"
2333   [(set_attr "type" "logical")
2334    (set_attr "mode" "<MODE>")])
2335
2336 (define_insn "*ior<mode>3_mips16"
2337   [(set (match_operand:GPR 0 "register_operand" "=d")
2338         (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2339                  (match_operand:GPR 2 "register_operand" "d")))]
2340   "TARGET_MIPS16"
2341   "or\t%0,%2"
2342   [(set_attr "type" "logical")
2343    (set_attr "mode" "<MODE>")])
2344
2345 (define_expand "xor<mode>3"
2346   [(set (match_operand:GPR 0 "register_operand")
2347         (xor:GPR (match_operand:GPR 1 "register_operand")
2348                  (match_operand:GPR 2 "uns_arith_operand")))]
2349   ""
2350   "")
2351
2352 (define_insn ""
2353   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2354         (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2355                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2356   "!TARGET_MIPS16"
2357   "@
2358    xor\t%0,%1,%2
2359    xori\t%0,%1,%x2"
2360   [(set_attr "type" "logical")
2361    (set_attr "mode" "<MODE>")])
2362
2363 (define_insn ""
2364   [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2365         (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2366                  (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2367   "TARGET_MIPS16"
2368   "@
2369    xor\t%0,%2
2370    cmpi\t%1,%2
2371    cmp\t%1,%2"
2372   [(set_attr "type" "logical,arith,arith")
2373    (set_attr "mode" "<MODE>")
2374    (set_attr_alternative "length"
2375                 [(const_int 4)
2376                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2377                                (const_int 4)
2378                                (const_int 8))
2379                  (const_int 4)])])
2380
2381 (define_insn "*nor<mode>3"
2382   [(set (match_operand:GPR 0 "register_operand" "=d")
2383         (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2384                  (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2385   "!TARGET_MIPS16"
2386   "nor\t%0,%1,%2"
2387   [(set_attr "type" "logical")
2388    (set_attr "mode" "<MODE>")])
2389 \f
2390 ;;
2391 ;;  ....................
2392 ;;
2393 ;;      TRUNCATION
2394 ;;
2395 ;;  ....................
2396
2397
2398
2399 (define_insn "truncdfsf2"
2400   [(set (match_operand:SF 0 "register_operand" "=f")
2401         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2402   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2403   "cvt.s.d\t%0,%1"
2404   [(set_attr "type"     "fcvt")
2405    (set_attr "cnv_mode" "D2S")   
2406    (set_attr "mode"     "SF")])
2407
2408 ;; Integer truncation patterns.  Truncating SImode values to smaller
2409 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
2410 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2411 ;; need to make sure that the lower 32 bits are properly sign-extended
2412 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2413 ;; smaller than SImode is equivalent to two separate truncations:
2414 ;;
2415 ;;                        A       B
2416 ;;    DI ---> HI  ==  DI ---> SI ---> HI
2417 ;;    DI ---> QI  ==  DI ---> SI ---> QI
2418 ;;
2419 ;; Step A needs a real instruction but step B does not.
2420
2421 (define_insn "truncdisi2"
2422   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2423         (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2424   "TARGET_64BIT"
2425   "@
2426     sll\t%0,%1,0
2427     sw\t%1,%0"
2428   [(set_attr "type" "shift,store")
2429    (set_attr "mode" "SI")
2430    (set_attr "extended_mips16" "yes,*")])
2431
2432 (define_insn "truncdihi2"
2433   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2434         (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2435   "TARGET_64BIT"
2436   "@
2437     sll\t%0,%1,0
2438     sh\t%1,%0"
2439   [(set_attr "type" "shift,store")
2440    (set_attr "mode" "SI")
2441    (set_attr "extended_mips16" "yes,*")])
2442
2443 (define_insn "truncdiqi2"
2444   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2445         (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2446   "TARGET_64BIT"
2447   "@
2448     sll\t%0,%1,0
2449     sb\t%1,%0"
2450   [(set_attr "type" "shift,store")
2451    (set_attr "mode" "SI")
2452    (set_attr "extended_mips16" "yes,*")])
2453
2454 ;; Combiner patterns to optimize shift/truncate combinations.
2455
2456 (define_insn ""
2457   [(set (match_operand:SUBDI 0 "register_operand" "=d")
2458         (truncate:SUBDI
2459           (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2460                        (match_operand:DI 2 "const_arith_operand" ""))))]
2461   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2462   "dsra\t%0,%1,%2"
2463   [(set_attr "type" "shift")
2464    (set_attr "mode" "SI")])
2465
2466 (define_insn ""
2467   [(set (match_operand:SUBDI 0 "register_operand" "=d")
2468         (truncate:SUBDI
2469           (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2470                        (const_int 32))))]
2471   "TARGET_64BIT && !TARGET_MIPS16"
2472   "dsra\t%0,%1,32"
2473   [(set_attr "type" "shift")
2474    (set_attr "mode" "SI")])
2475
2476
2477 ;; Combiner patterns for truncate/sign_extend combinations.  The SI versions
2478 ;; use the shift/truncate patterns above.
2479
2480 (define_insn_and_split "*extenddi_truncate<mode>"
2481   [(set (match_operand:DI 0 "register_operand" "=d")
2482         (sign_extend:DI
2483             (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
2484   "TARGET_64BIT && !TARGET_MIPS16"
2485   "#"
2486   "&& reload_completed"
2487   [(set (match_dup 2)
2488         (ashift:DI (match_dup 1)
2489                    (match_dup 3)))
2490    (set (match_dup 0)
2491         (ashiftrt:DI (match_dup 2)
2492                      (match_dup 3)))]
2493 {
2494   operands[2] = gen_lowpart (DImode, operands[0]);
2495   operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
2496 })
2497
2498 (define_insn_and_split "*extendsi_truncate<mode>"
2499   [(set (match_operand:SI 0 "register_operand" "=d")
2500         (sign_extend:SI
2501             (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
2502   "TARGET_64BIT && !TARGET_MIPS16"
2503   "#"
2504   "&& reload_completed"
2505   [(set (match_dup 2)
2506         (ashift:DI (match_dup 1)
2507                    (match_dup 3)))
2508    (set (match_dup 0)
2509         (truncate:SI (ashiftrt:DI (match_dup 2)
2510                                   (match_dup 3))))]
2511 {
2512   operands[2] = gen_lowpart (DImode, operands[0]);
2513   operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
2514 })
2515
2516 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2517
2518 (define_insn "*zero_extend<mode>_trunchi"
2519   [(set (match_operand:GPR 0 "register_operand" "=d")
2520         (zero_extend:GPR
2521             (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2522   "TARGET_64BIT && !TARGET_MIPS16"
2523   "andi\t%0,%1,0xffff"
2524   [(set_attr "type" "logical")
2525    (set_attr "mode" "<MODE>")])
2526
2527 (define_insn "*zero_extend<mode>_truncqi"
2528   [(set (match_operand:GPR 0 "register_operand" "=d")
2529         (zero_extend:GPR
2530             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2531   "TARGET_64BIT && !TARGET_MIPS16"
2532   "andi\t%0,%1,0xff"
2533   [(set_attr "type" "logical")
2534    (set_attr "mode" "<MODE>")])
2535
2536 (define_insn ""
2537   [(set (match_operand:HI 0 "register_operand" "=d")
2538         (zero_extend:HI
2539             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2540   "TARGET_64BIT && !TARGET_MIPS16"
2541   "andi\t%0,%1,0xff"
2542   [(set_attr "type" "logical")
2543    (set_attr "mode" "HI")])
2544 \f
2545 ;;
2546 ;;  ....................
2547 ;;
2548 ;;      ZERO EXTENSION
2549 ;;
2550 ;;  ....................
2551
2552 ;; Extension insns.
2553
2554 (define_insn_and_split "zero_extendsidi2"
2555   [(set (match_operand:DI 0 "register_operand" "=d,d")
2556         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
2557   "TARGET_64BIT"
2558   "@
2559    #
2560    lwu\t%0,%1"
2561   "&& reload_completed && REG_P (operands[1])"
2562   [(set (match_dup 0)
2563         (ashift:DI (match_dup 1) (const_int 32)))
2564    (set (match_dup 0)
2565         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2566   { operands[1] = gen_lowpart (DImode, operands[1]); }
2567   [(set_attr "type" "multi,load")
2568    (set_attr "mode" "DI")
2569    (set_attr "length" "8,*")])
2570
2571 ;; Combine is not allowed to convert this insn into a zero_extendsidi2
2572 ;; because of TRULY_NOOP_TRUNCATION.
2573
2574 (define_insn_and_split "*clear_upper32"
2575   [(set (match_operand:DI 0 "register_operand" "=d,d")
2576         (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,W")
2577                 (const_int 4294967295)))]
2578   "TARGET_64BIT"
2579 {
2580   if (which_alternative == 0)
2581     return "#";
2582
2583   operands[1] = gen_lowpart (SImode, operands[1]);
2584   return "lwu\t%0,%1";
2585 }
2586   "&& reload_completed && REG_P (operands[1])"
2587   [(set (match_dup 0)
2588         (ashift:DI (match_dup 1) (const_int 32)))
2589    (set (match_dup 0)
2590         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2591   ""
2592   [(set_attr "type" "multi,load")
2593    (set_attr "mode" "DI")
2594    (set_attr "length" "8,*")])
2595
2596 (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
2597   [(set (match_operand:GPR 0 "register_operand")
2598         (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2599   ""
2600 {
2601   if (TARGET_MIPS16 && !GENERATE_MIPS16E
2602       && !memory_operand (operands[1], <SHORT:MODE>mode))
2603     {
2604       emit_insn (gen_and<GPR:mode>3 (operands[0],
2605                                      gen_lowpart (<GPR:MODE>mode, operands[1]),
2606                                      force_reg (<GPR:MODE>mode,
2607                                                 GEN_INT (<SHORT:mask>))));
2608       DONE;
2609     }
2610 })
2611
2612 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
2613   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2614         (zero_extend:GPR
2615              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2616   "!TARGET_MIPS16"
2617   "@
2618    andi\t%0,%1,<SHORT:mask>
2619    l<SHORT:size>u\t%0,%1"
2620   [(set_attr "type" "logical,load")
2621    (set_attr "mode" "<GPR:MODE>")])
2622
2623 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e"
2624   [(set (match_operand:GPR 0 "register_operand" "=d")
2625         (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
2626   "GENERATE_MIPS16E"
2627   "ze<SHORT:size>\t%0"
2628   [(set_attr "type" "arith")
2629    (set_attr "mode" "<GPR:MODE>")])
2630
2631 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16"
2632   [(set (match_operand:GPR 0 "register_operand" "=d")
2633         (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
2634   "TARGET_MIPS16"
2635   "l<SHORT:size>u\t%0,%1"
2636   [(set_attr "type" "load")
2637    (set_attr "mode" "<GPR:MODE>")])
2638
2639 (define_expand "zero_extendqihi2"
2640   [(set (match_operand:HI 0 "register_operand")
2641         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2642   ""
2643 {
2644   if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
2645     {
2646       emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
2647                                        operands[1]));
2648       DONE;
2649     }
2650 })
2651
2652 (define_insn "*zero_extendqihi2"
2653   [(set (match_operand:HI 0 "register_operand" "=d,d")
2654         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2655   "!TARGET_MIPS16"
2656   "@
2657    andi\t%0,%1,0x00ff
2658    lbu\t%0,%1"
2659   [(set_attr "type" "logical,load")
2660    (set_attr "mode" "HI")])
2661
2662 (define_insn "*zero_extendqihi2_mips16"
2663   [(set (match_operand:HI 0 "register_operand" "=d")
2664         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2665   "TARGET_MIPS16"
2666   "lbu\t%0,%1"
2667   [(set_attr "type" "load")
2668    (set_attr "mode" "HI")])
2669 \f
2670 ;;
2671 ;;  ....................
2672 ;;
2673 ;;      SIGN EXTENSION
2674 ;;
2675 ;;  ....................
2676
2677 ;; Extension insns.
2678 ;; Those for integer source operand are ordered widest source type first.
2679
2680 ;; When TARGET_64BIT, all SImode integer registers should already be in
2681 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can
2682 ;; therefore get rid of register->register instructions if we constrain
2683 ;; the source to be in the same register as the destination.
2684 ;;
2685 ;; The register alternative has type "arith" so that the pre-reload
2686 ;; scheduler will treat it as a move.  This reflects what happens if
2687 ;; the register alternative needs a reload.
2688 (define_insn_and_split "extendsidi2"
2689   [(set (match_operand:DI 0 "register_operand" "=d,d")
2690         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2691   "TARGET_64BIT"
2692   "@
2693    #
2694    lw\t%0,%1"
2695   "&& reload_completed && register_operand (operands[1], VOIDmode)"
2696   [(const_int 0)]
2697 {
2698   emit_note (NOTE_INSN_DELETED);
2699   DONE;
2700 }
2701   [(set_attr "type" "arith,load")
2702    (set_attr "mode" "DI")])
2703
2704 (define_expand "extend<SHORT:mode><GPR:mode>2"
2705   [(set (match_operand:GPR 0 "register_operand")
2706         (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2707   "")
2708
2709 (define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e"
2710   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2711         (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
2712   "GENERATE_MIPS16E"
2713   "@
2714    se<SHORT:size>\t%0
2715    l<SHORT:size>\t%0,%1"
2716   [(set_attr "type" "signext,load")
2717    (set_attr "mode" "<GPR:MODE>")])
2718
2719 (define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
2720   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2721         (sign_extend:GPR
2722              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2723   "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2724   "@
2725    #
2726    l<SHORT:size>\t%0,%1"
2727   "&& reload_completed && REG_P (operands[1])"
2728   [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
2729    (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
2730 {
2731   operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
2732   operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
2733                          - GET_MODE_BITSIZE (<SHORT:MODE>mode));
2734 }
2735   [(set_attr "type" "arith,load")
2736    (set_attr "mode" "<GPR:MODE>")
2737    (set_attr "length" "8,*")])
2738
2739 (define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
2740   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2741         (sign_extend:GPR
2742              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2743   "ISA_HAS_SEB_SEH"
2744   "@
2745    se<SHORT:size>\t%0,%1
2746    l<SHORT:size>\t%0,%1"
2747   [(set_attr "type" "signext,load")
2748    (set_attr "mode" "<GPR:MODE>")])
2749
2750 (define_expand "extendqihi2"
2751   [(set (match_operand:HI 0 "register_operand")
2752         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2753   "")
2754
2755 (define_insn "*extendqihi2_mips16e"
2756   [(set (match_operand:HI 0 "register_operand" "=d,d")
2757         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,m")))]
2758   "GENERATE_MIPS16E"
2759   "@
2760    seb\t%0
2761    lb\t%0,%1"
2762   [(set_attr "type" "signext,load")
2763    (set_attr "mode" "SI")])
2764
2765 (define_insn_and_split "*extendqihi2"
2766   [(set (match_operand:HI 0 "register_operand" "=d,d")
2767         (sign_extend:HI
2768              (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2769   "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2770   "@
2771    #
2772    lb\t%0,%1"
2773   "&& reload_completed && REG_P (operands[1])"
2774   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2775    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
2776 {
2777   operands[0] = gen_lowpart (SImode, operands[0]);
2778   operands[1] = gen_lowpart (SImode, operands[1]);
2779   operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
2780                          - GET_MODE_BITSIZE (QImode));
2781 }
2782   [(set_attr "type" "multi,load")
2783    (set_attr "mode" "SI")
2784    (set_attr "length" "8,*")])
2785
2786 (define_insn "*extendqihi2_seb"
2787   [(set (match_operand:HI 0 "register_operand" "=d,d")
2788         (sign_extend:HI
2789              (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2790   "ISA_HAS_SEB_SEH"
2791   "@
2792    seb\t%0,%1
2793    lb\t%0,%1"
2794   [(set_attr "type" "signext,load")
2795    (set_attr "mode" "SI")])
2796
2797 (define_insn "extendsfdf2"
2798   [(set (match_operand:DF 0 "register_operand" "=f")
2799         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2800   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2801   "cvt.d.s\t%0,%1"
2802   [(set_attr "type"     "fcvt")
2803    (set_attr "cnv_mode" "S2D")   
2804    (set_attr "mode"     "DF")])
2805 \f
2806 ;;
2807 ;;  ....................
2808 ;;
2809 ;;      CONVERSIONS
2810 ;;
2811 ;;  ....................
2812
2813 (define_expand "fix_truncdfsi2"
2814   [(set (match_operand:SI 0 "register_operand")
2815         (fix:SI (match_operand:DF 1 "register_operand")))]
2816   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2817 {
2818   if (!ISA_HAS_TRUNC_W)
2819     {
2820       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2821       DONE;
2822     }
2823 })
2824
2825 (define_insn "fix_truncdfsi2_insn"
2826   [(set (match_operand:SI 0 "register_operand" "=f")
2827         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2828   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2829   "trunc.w.d %0,%1"
2830   [(set_attr "type"     "fcvt")
2831    (set_attr "mode"     "DF")
2832    (set_attr "cnv_mode" "D2I")
2833    (set_attr "length"   "4")])
2834
2835 (define_insn "fix_truncdfsi2_macro"
2836   [(set (match_operand:SI 0 "register_operand" "=f")
2837         (fix:SI (match_operand:DF 1 "register_operand" "f")))
2838    (clobber (match_scratch:DF 2 "=d"))]
2839   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2840 {
2841   if (set_nomacro)
2842     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2843   else
2844     return "trunc.w.d %0,%1,%2";
2845 }
2846   [(set_attr "type"     "fcvt")
2847    (set_attr "mode"     "DF")
2848    (set_attr "cnv_mode" "D2I")
2849    (set_attr "length"   "36")])
2850
2851 (define_expand "fix_truncsfsi2"
2852   [(set (match_operand:SI 0 "register_operand")
2853         (fix:SI (match_operand:SF 1 "register_operand")))]
2854   "TARGET_HARD_FLOAT"
2855 {
2856   if (!ISA_HAS_TRUNC_W)
2857     {
2858       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2859       DONE;
2860     }
2861 })
2862
2863 (define_insn "fix_truncsfsi2_insn"
2864   [(set (match_operand:SI 0 "register_operand" "=f")
2865         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2866   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2867   "trunc.w.s %0,%1"
2868   [(set_attr "type"     "fcvt")
2869    (set_attr "mode"     "SF")
2870    (set_attr "cnv_mode" "S2I")
2871    (set_attr "length"   "4")])
2872
2873 (define_insn "fix_truncsfsi2_macro"
2874   [(set (match_operand:SI 0 "register_operand" "=f")
2875         (fix:SI (match_operand:SF 1 "register_operand" "f")))
2876    (clobber (match_scratch:SF 2 "=d"))]
2877   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2878 {
2879   if (set_nomacro)
2880     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2881   else
2882     return "trunc.w.s %0,%1,%2";
2883 }
2884   [(set_attr "type"     "fcvt")
2885    (set_attr "mode"     "SF")
2886    (set_attr "cnv_mode" "S2I")
2887    (set_attr "length"   "36")])
2888
2889
2890 (define_insn "fix_truncdfdi2"
2891   [(set (match_operand:DI 0 "register_operand" "=f")
2892         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2893   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2894   "trunc.l.d %0,%1"
2895   [(set_attr "type"     "fcvt")
2896    (set_attr "mode"     "DF")
2897    (set_attr "cnv_mode" "D2I")
2898    (set_attr "length"   "4")])
2899
2900
2901 (define_insn "fix_truncsfdi2"
2902   [(set (match_operand:DI 0 "register_operand" "=f")
2903         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2904   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2905   "trunc.l.s %0,%1"
2906   [(set_attr "type"     "fcvt")
2907    (set_attr "mode"     "SF")
2908    (set_attr "cnv_mode" "S2I")
2909    (set_attr "length"   "4")])
2910
2911
2912 (define_insn "floatsidf2"
2913   [(set (match_operand:DF 0 "register_operand" "=f")
2914         (float:DF (match_operand:SI 1 "register_operand" "f")))]
2915   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2916   "cvt.d.w\t%0,%1"
2917   [(set_attr "type"     "fcvt")
2918    (set_attr "mode"     "DF")
2919    (set_attr "cnv_mode" "I2D")   
2920    (set_attr "length"   "4")])
2921
2922
2923 (define_insn "floatdidf2"
2924   [(set (match_operand:DF 0 "register_operand" "=f")
2925         (float:DF (match_operand:DI 1 "register_operand" "f")))]
2926   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2927   "cvt.d.l\t%0,%1"
2928   [(set_attr "type"     "fcvt")
2929    (set_attr "mode"     "DF")
2930    (set_attr "cnv_mode" "I2D")   
2931    (set_attr "length"   "4")])
2932
2933
2934 (define_insn "floatsisf2"
2935   [(set (match_operand:SF 0 "register_operand" "=f")
2936         (float:SF (match_operand:SI 1 "register_operand" "f")))]
2937   "TARGET_HARD_FLOAT"
2938   "cvt.s.w\t%0,%1"
2939   [(set_attr "type"     "fcvt")
2940    (set_attr "mode"     "SF")
2941    (set_attr "cnv_mode" "I2S")   
2942    (set_attr "length"   "4")])
2943
2944
2945 (define_insn "floatdisf2"
2946   [(set (match_operand:SF 0 "register_operand" "=f")
2947         (float:SF (match_operand:DI 1 "register_operand" "f")))]
2948   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2949   "cvt.s.l\t%0,%1"
2950   [(set_attr "type"     "fcvt")
2951    (set_attr "mode"     "SF")
2952    (set_attr "cnv_mode" "I2S")   
2953    (set_attr "length"   "4")])
2954
2955
2956 (define_expand "fixuns_truncdfsi2"
2957   [(set (match_operand:SI 0 "register_operand")
2958         (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2959   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2960 {
2961   rtx reg1 = gen_reg_rtx (DFmode);
2962   rtx reg2 = gen_reg_rtx (DFmode);
2963   rtx reg3 = gen_reg_rtx (SImode);
2964   rtx label1 = gen_label_rtx ();
2965   rtx label2 = gen_label_rtx ();
2966   REAL_VALUE_TYPE offset;
2967
2968   real_2expN (&offset, 31, DFmode);
2969
2970   if (reg1)                     /* Turn off complaints about unreached code.  */
2971     {
2972       mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2973       do_pending_stack_adjust ();
2974
2975       emit_insn (gen_cmpdf (operands[1], reg1));
2976       emit_jump_insn (gen_bge (label1));
2977
2978       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2979       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2980                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
2981       emit_barrier ();
2982
2983       emit_label (label1);
2984       mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2985       mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
2986                                      (BITMASK_HIGH, SImode)));
2987
2988       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2989       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2990
2991       emit_label (label2);
2992
2993       /* Allow REG_NOTES to be set on last insn (labels don't have enough
2994          fields, and can't be used for REG_NOTES anyway).  */
2995       emit_use (stack_pointer_rtx);
2996       DONE;
2997     }
2998 })
2999
3000
3001 (define_expand "fixuns_truncdfdi2"
3002   [(set (match_operand:DI 0 "register_operand")
3003         (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3004   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3005 {
3006   rtx reg1 = gen_reg_rtx (DFmode);
3007   rtx reg2 = gen_reg_rtx (DFmode);
3008   rtx reg3 = gen_reg_rtx (DImode);
3009   rtx label1 = gen_label_rtx ();
3010   rtx label2 = gen_label_rtx ();
3011   REAL_VALUE_TYPE offset;
3012
3013   real_2expN (&offset, 63, DFmode);
3014
3015   mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3016   do_pending_stack_adjust ();
3017
3018   emit_insn (gen_cmpdf (operands[1], reg1));
3019   emit_jump_insn (gen_bge (label1));
3020
3021   emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3022   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3023                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3024   emit_barrier ();
3025
3026   emit_label (label1);
3027   mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3028   mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
3029   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3030
3031   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3032   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3033
3034   emit_label (label2);
3035
3036   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3037      fields, and can't be used for REG_NOTES anyway).  */
3038   emit_use (stack_pointer_rtx);
3039   DONE;
3040 })
3041
3042
3043 (define_expand "fixuns_truncsfsi2"
3044   [(set (match_operand:SI 0 "register_operand")
3045         (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3046   "TARGET_HARD_FLOAT"
3047 {
3048   rtx reg1 = gen_reg_rtx (SFmode);
3049   rtx reg2 = gen_reg_rtx (SFmode);
3050   rtx reg3 = gen_reg_rtx (SImode);
3051   rtx label1 = gen_label_rtx ();
3052   rtx label2 = gen_label_rtx ();
3053   REAL_VALUE_TYPE offset;
3054
3055   real_2expN (&offset, 31, SFmode);
3056
3057   mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3058   do_pending_stack_adjust ();
3059
3060   emit_insn (gen_cmpsf (operands[1], reg1));
3061   emit_jump_insn (gen_bge (label1));
3062
3063   emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3064   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3065                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3066   emit_barrier ();
3067
3068   emit_label (label1);
3069   mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3070   mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
3071                                  (BITMASK_HIGH, SImode)));
3072
3073   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3074   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3075
3076   emit_label (label2);
3077
3078   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3079      fields, and can't be used for REG_NOTES anyway).  */
3080   emit_use (stack_pointer_rtx);
3081   DONE;
3082 })
3083
3084
3085 (define_expand "fixuns_truncsfdi2"
3086   [(set (match_operand:DI 0 "register_operand")
3087         (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3088   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3089 {
3090   rtx reg1 = gen_reg_rtx (SFmode);
3091   rtx reg2 = gen_reg_rtx (SFmode);
3092   rtx reg3 = gen_reg_rtx (DImode);
3093   rtx label1 = gen_label_rtx ();
3094   rtx label2 = gen_label_rtx ();
3095   REAL_VALUE_TYPE offset;
3096
3097   real_2expN (&offset, 63, SFmode);
3098
3099   mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3100   do_pending_stack_adjust ();
3101
3102   emit_insn (gen_cmpsf (operands[1], reg1));
3103   emit_jump_insn (gen_bge (label1));
3104
3105   emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3106   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3107                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3108   emit_barrier ();
3109
3110   emit_label (label1);
3111   mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3112   mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
3113   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3114
3115   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3116   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3117
3118   emit_label (label2);
3119
3120   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3121      fields, and can't be used for REG_NOTES anyway).  */
3122   emit_use (stack_pointer_rtx);
3123   DONE;
3124 })
3125 \f
3126 ;;
3127 ;;  ....................
3128 ;;
3129 ;;      DATA MOVEMENT
3130 ;;
3131 ;;  ....................
3132
3133 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3134
3135 (define_expand "extv"
3136   [(set (match_operand 0 "register_operand")
3137         (sign_extract (match_operand:QI 1 "memory_operand")
3138                       (match_operand 2 "immediate_operand")
3139                       (match_operand 3 "immediate_operand")))]
3140   "!TARGET_MIPS16"
3141 {
3142   if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3143                                          INTVAL (operands[2]),
3144                                          INTVAL (operands[3])))
3145     DONE;
3146   else
3147     FAIL;
3148 })
3149
3150 (define_expand "extzv"
3151   [(set (match_operand 0 "register_operand")
3152         (zero_extract (match_operand 1 "nonimmediate_operand")
3153                       (match_operand 2 "immediate_operand")
3154                       (match_operand 3 "immediate_operand")))]
3155   "!TARGET_MIPS16"
3156 {
3157   if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3158                                          INTVAL (operands[2]),
3159                                          INTVAL (operands[3])))
3160     DONE;
3161   else if (mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
3162                                INTVAL (operands[3])))
3163     {
3164       if (GET_MODE (operands[0]) == DImode)
3165         emit_insn (gen_extzvdi (operands[0], operands[1], operands[2],
3166                                 operands[3]));
3167       else
3168         emit_insn (gen_extzvsi (operands[0], operands[1], operands[2],
3169                                 operands[3]));
3170       DONE;
3171     }
3172   else
3173     FAIL;
3174 })
3175
3176 (define_insn "extzv<mode>"
3177   [(set (match_operand:GPR 0 "register_operand" "=d")
3178         (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
3179                           (match_operand:SI 2 "immediate_operand" "I")
3180                           (match_operand:SI 3 "immediate_operand" "I")))]
3181   "mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
3182                        INTVAL (operands[3]))"
3183   "<d>ext\t%0,%1,%3,%2"
3184   [(set_attr "type"     "arith")
3185    (set_attr "mode"     "<MODE>")])
3186
3187
3188 (define_expand "insv"
3189   [(set (zero_extract (match_operand 0 "nonimmediate_operand")
3190                       (match_operand 1 "immediate_operand")
3191                       (match_operand 2 "immediate_operand"))
3192         (match_operand 3 "reg_or_0_operand"))]
3193   "!TARGET_MIPS16"
3194 {
3195   if (mips_expand_ins_as_unaligned_store (operands[0], operands[3],
3196                                           INTVAL (operands[1]),
3197                                           INTVAL (operands[2])))
3198     DONE;
3199   else if (mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
3200                                INTVAL (operands[2])))
3201     {
3202       if (GET_MODE (operands[0]) == DImode)
3203         emit_insn (gen_insvdi (operands[0], operands[1], operands[2],
3204                                operands[3]));
3205       else
3206         emit_insn (gen_insvsi (operands[0], operands[1], operands[2],
3207                                operands[3]));
3208       DONE;
3209    }
3210    else
3211      FAIL;
3212 })
3213
3214 (define_insn "insv<mode>"
3215   [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
3216                           (match_operand:SI 1 "immediate_operand" "I")
3217                           (match_operand:SI 2 "immediate_operand" "I"))
3218         (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
3219   "mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
3220                        INTVAL (operands[2]))"
3221   "<d>ins\t%0,%z3,%2,%1"
3222   [(set_attr "type"     "arith")
3223    (set_attr "mode"     "<MODE>")])
3224
3225 ;; Unaligned word moves generated by the bit field patterns.
3226 ;;
3227 ;; As far as the rtl is concerned, both the left-part and right-part
3228 ;; instructions can access the whole field.  However, the real operand
3229 ;; refers to just the first or the last byte (depending on endianness).
3230 ;; We therefore use two memory operands to each instruction, one to
3231 ;; describe the rtl effect and one to use in the assembly output.
3232 ;;
3233 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3234 ;; This allows us to use the standard length calculations for the "load"
3235 ;; and "store" type attributes.
3236
3237 (define_insn "mov_<load>l"
3238   [(set (match_operand:GPR 0 "register_operand" "=d")
3239         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3240                      (match_operand:QI 2 "memory_operand" "m")]
3241                     UNSPEC_LOAD_LEFT))]
3242   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
3243   "<load>l\t%0,%2"
3244   [(set_attr "type" "load")
3245    (set_attr "mode" "<MODE>")])
3246
3247 (define_insn "mov_<load>r"
3248   [(set (match_operand:GPR 0 "register_operand" "=d")
3249         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3250                      (match_operand:QI 2 "memory_operand" "m")
3251                      (match_operand:GPR 3 "register_operand" "0")]
3252                     UNSPEC_LOAD_RIGHT))]
3253   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
3254   "<load>r\t%0,%2"
3255   [(set_attr "type" "load")
3256    (set_attr "mode" "<MODE>")])
3257
3258 (define_insn "mov_<store>l"
3259   [(set (match_operand:BLK 0 "memory_operand" "=m")
3260         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3261                      (match_operand:QI 2 "memory_operand" "m")]
3262                     UNSPEC_STORE_LEFT))]
3263   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3264   "<store>l\t%z1,%2"
3265   [(set_attr "type" "store")
3266    (set_attr "mode" "<MODE>")])
3267
3268 (define_insn "mov_<store>r"
3269   [(set (match_operand:BLK 0 "memory_operand" "+m")
3270         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3271                      (match_operand:QI 2 "memory_operand" "m")
3272                      (match_dup 0)]
3273                     UNSPEC_STORE_RIGHT))]
3274   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3275   "<store>r\t%z1,%2"
3276   [(set_attr "type" "store")
3277    (set_attr "mode" "<MODE>")])
3278
3279 ;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE.
3280 ;; The required value is:
3281 ;;
3282 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3283 ;;
3284 ;; which translates to:
3285 ;;
3286 ;;      lui     op0,%highest(op1)
3287 ;;      daddiu  op0,op0,%higher(op1)
3288 ;;      dsll    op0,op0,16
3289 ;;      daddiu  op0,op0,%hi(op1)
3290 ;;      dsll    op0,op0,16
3291 ;;
3292 ;; The split is deferred until after flow2 to allow the peephole2 below
3293 ;; to take effect.
3294 (define_insn_and_split "*lea_high64"
3295   [(set (match_operand:DI 0 "register_operand" "=d")
3296         (high:DI (match_operand:DI 1 "absolute_symbolic_operand" "")))]
3297   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3298   "#"
3299   "&& epilogue_completed"
3300   [(set (match_dup 0) (high:DI (match_dup 2)))
3301    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3302    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3303    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3304    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3305 {
3306   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3307   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3308 }
3309   [(set_attr "length" "20")])
3310
3311 ;; Use a scratch register to reduce the latency of the above pattern
3312 ;; on superscalar machines.  The optimized sequence is:
3313 ;;
3314 ;;      lui     op1,%highest(op2)
3315 ;;      lui     op0,%hi(op2)
3316 ;;      daddiu  op1,op1,%higher(op2)
3317 ;;      dsll32  op1,op1,0
3318 ;;      daddu   op1,op1,op0
3319 (define_peephole2
3320   [(set (match_operand:DI 1 "d_operand")
3321         (high:DI (match_operand:DI 2 "absolute_symbolic_operand")))
3322    (match_scratch:DI 0 "d")]
3323   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3324   [(set (match_dup 1) (high:DI (match_dup 3)))
3325    (set (match_dup 0) (high:DI (match_dup 4)))
3326    (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
3327    (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
3328    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
3329 {
3330   operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
3331   operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
3332 })
3333
3334 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3335 ;; SYMBOL_ABSOLUTE X will take 6 cycles.  This next pattern allows combine
3336 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3337 ;; used once.  We can then use the sequence:
3338 ;;
3339 ;;      lui     op0,%highest(op1)
3340 ;;      lui     op2,%hi(op1)
3341 ;;      daddiu  op0,op0,%higher(op1)
3342 ;;      daddiu  op2,op2,%lo(op1)
3343 ;;      dsll32  op0,op0,0
3344 ;;      daddu   op0,op0,op2
3345 ;;
3346 ;; which takes 4 cycles on most superscalar targets.
3347 (define_insn_and_split "*lea64"
3348   [(set (match_operand:DI 0 "register_operand" "=d")
3349         (match_operand:DI 1 "absolute_symbolic_operand" ""))
3350    (clobber (match_scratch:DI 2 "=&d"))]
3351   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3352   "#"
3353   "&& reload_completed"
3354   [(set (match_dup 0) (high:DI (match_dup 3)))
3355    (set (match_dup 2) (high:DI (match_dup 4)))
3356    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3357    (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3358    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3359    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3360 {
3361   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3362   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3363 }
3364   [(set_attr "length" "24")])
3365
3366 ;; Split HIGHs into:
3367 ;;
3368 ;;      li op0,%hi(sym)
3369 ;;      sll op0,16
3370 ;;
3371 ;; on MIPS16 targets.
3372 (define_split
3373   [(set (match_operand:SI 0 "d_operand")
3374         (high:SI (match_operand:SI 1 "absolute_symbolic_operand")))]
3375   "TARGET_MIPS16 && reload_completed"
3376   [(set (match_dup 0) (match_dup 2))
3377    (set (match_dup 0) (ashift:SI (match_dup 0) (const_int 16)))]
3378 {
3379   operands[2] = mips_unspec_address (operands[1], SYMBOL_32_HIGH);
3380 })
3381
3382 ;; Insns to fetch a symbol from a big GOT.
3383
3384 (define_insn_and_split "*xgot_hi<mode>"
3385   [(set (match_operand:P 0 "register_operand" "=d")
3386         (high:P (match_operand:P 1 "got_disp_operand" "")))]
3387   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3388   "#"
3389   "&& reload_completed"
3390   [(set (match_dup 0) (high:P (match_dup 2)))
3391    (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3392 {
3393   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
3394   operands[3] = pic_offset_table_rtx;
3395 }
3396   [(set_attr "got" "xgot_high")
3397    (set_attr "mode" "<MODE>")])
3398
3399 (define_insn_and_split "*xgot_lo<mode>"
3400   [(set (match_operand:P 0 "register_operand" "=d")
3401         (lo_sum:P&