OSDN Git Service

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