OSDN Git Service

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