OSDN Git Service

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