OSDN Git Service

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