OSDN Git Service

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