OSDN Git Service

* doc/md.texi: Update documentation of MIPS constraints.
[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
51    (UNSPEC_ADDRESS_FIRST        100)
52
53    (FAKE_CALL_REGNO             79)
54
55    ;; For MIPS Paired-Singled Floating Point Instructions.
56
57    (UNSPEC_MOVE_TF_PS           200)
58    (UNSPEC_C                    201)
59
60    ;; MIPS64/MIPS32R2 alnv.ps
61    (UNSPEC_ALNV_PS              202)
62
63    ;; MIPS-3D instructions
64    (UNSPEC_CABS                 203)
65
66    (UNSPEC_ADDR_PS              204)
67    (UNSPEC_CVT_PW_PS            205)
68    (UNSPEC_CVT_PS_PW            206)
69    (UNSPEC_MULR_PS              207)
70
71    (UNSPEC_RSQRT1               208)
72    (UNSPEC_RSQRT2               209)
73    (UNSPEC_RECIP1               210)
74    (UNSPEC_RECIP2               211)
75
76    ;; MIPS DSP ASE Revision 0.98 3/24/2005
77    (UNSPEC_ADDQ                 300)
78    (UNSPEC_ADDQ_S               301)
79    (UNSPEC_SUBQ                 302)
80    (UNSPEC_SUBQ_S               303)
81    (UNSPEC_ADDSC                304)
82    (UNSPEC_ADDWC                305)
83    (UNSPEC_MODSUB               306)
84    (UNSPEC_RADDU_W_QB           307)
85    (UNSPEC_ABSQ_S               308)
86    (UNSPEC_PRECRQ_QB_PH         309)
87    (UNSPEC_PRECRQ_PH_W          310)
88    (UNSPEC_PRECRQ_RS_PH_W       311)
89    (UNSPEC_PRECRQU_S_QB_PH      312)
90    (UNSPEC_PRECEQ_W_PHL         313)
91    (UNSPEC_PRECEQ_W_PHR         314)
92    (UNSPEC_PRECEQU_PH_QBL       315)
93    (UNSPEC_PRECEQU_PH_QBR       316)
94    (UNSPEC_PRECEQU_PH_QBLA      317)
95    (UNSPEC_PRECEQU_PH_QBRA      318)
96    (UNSPEC_PRECEU_PH_QBL        319)
97    (UNSPEC_PRECEU_PH_QBR        320)
98    (UNSPEC_PRECEU_PH_QBLA       321)
99    (UNSPEC_PRECEU_PH_QBRA       322)
100    (UNSPEC_SHLL                 323)
101    (UNSPEC_SHLL_S               324)
102    (UNSPEC_SHRL_QB              325)
103    (UNSPEC_SHRA_PH              326)
104    (UNSPEC_SHRA_R               327)
105    (UNSPEC_MULEU_S_PH_QBL       328)
106    (UNSPEC_MULEU_S_PH_QBR       329)
107    (UNSPEC_MULQ_RS_PH           330)
108    (UNSPEC_MULEQ_S_W_PHL        331)
109    (UNSPEC_MULEQ_S_W_PHR        332)
110    (UNSPEC_DPAU_H_QBL           333)
111    (UNSPEC_DPAU_H_QBR           334)
112    (UNSPEC_DPSU_H_QBL           335)
113    (UNSPEC_DPSU_H_QBR           336)
114    (UNSPEC_DPAQ_S_W_PH          337)
115    (UNSPEC_DPSQ_S_W_PH          338)
116    (UNSPEC_MULSAQ_S_W_PH        339)
117    (UNSPEC_DPAQ_SA_L_W          340)
118    (UNSPEC_DPSQ_SA_L_W          341)
119    (UNSPEC_MAQ_S_W_PHL          342)
120    (UNSPEC_MAQ_S_W_PHR          343)
121    (UNSPEC_MAQ_SA_W_PHL         344)
122    (UNSPEC_MAQ_SA_W_PHR         345)
123    (UNSPEC_BITREV               346)
124    (UNSPEC_INSV                 347)
125    (UNSPEC_REPL_QB              348)
126    (UNSPEC_REPL_PH              349)
127    (UNSPEC_CMP_EQ               350)
128    (UNSPEC_CMP_LT               351)
129    (UNSPEC_CMP_LE               352)
130    (UNSPEC_CMPGU_EQ_QB          353)
131    (UNSPEC_CMPGU_LT_QB          354)
132    (UNSPEC_CMPGU_LE_QB          355)
133    (UNSPEC_PICK                 356)
134    (UNSPEC_PACKRL_PH            357)
135    (UNSPEC_EXTR_W               358)
136    (UNSPEC_EXTR_R_W             359)
137    (UNSPEC_EXTR_RS_W            360)
138    (UNSPEC_EXTR_S_H             361)
139    (UNSPEC_EXTP                 362)
140    (UNSPEC_EXTPDP               363)
141    (UNSPEC_SHILO                364)
142    (UNSPEC_MTHLIP               365)
143    (UNSPEC_WRDSP                366)
144    (UNSPEC_RDDSP                367)
145   ]
146 )
147
148 (include "predicates.md")
149 (include "constraints.md")
150 \f
151 ;; ....................
152 ;;
153 ;;      Attributes
154 ;;
155 ;; ....................
156
157 (define_attr "got" "unset,xgot_high,load"
158   (const_string "unset"))
159
160 ;; For jal instructions, this attribute is DIRECT when the target address
161 ;; is symbolic and INDIRECT when it is a register.
162 (define_attr "jal" "unset,direct,indirect"
163   (const_string "unset"))
164
165 ;; This attribute is YES if the instruction is a jal macro (not a
166 ;; real jal instruction).
167 ;;
168 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
169 ;; restore $gp.  Direct jals are also macros in NewABI PIC since they
170 ;; load the target address into $25.
171 (define_attr "jal_macro" "no,yes"
172   (cond [(eq_attr "jal" "direct")
173          (symbol_ref "TARGET_ABICALLS != 0")
174          (eq_attr "jal" "indirect")
175          (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
176         (const_string "no")))
177
178 ;; Classification of each insn.
179 ;; branch       conditional branch
180 ;; jump         unconditional jump
181 ;; call         unconditional call
182 ;; load         load instruction(s)
183 ;; fpload       floating point load
184 ;; fpidxload    floating point indexed load
185 ;; store        store instruction(s)
186 ;; fpstore      floating point store
187 ;; fpidxstore   floating point indexed store
188 ;; prefetch     memory prefetch (register + offset)
189 ;; prefetchx    memory indexed prefetch (register + register)
190 ;; condmove     conditional moves
191 ;; xfer         transfer to/from coprocessor
192 ;; mthilo       transfer to hi/lo registers
193 ;; mfhilo       transfer from hi/lo registers
194 ;; const        load constant
195 ;; arith        integer arithmetic and logical instructions
196 ;; shift        integer shift instructions
197 ;; slt          set less than instructions
198 ;; clz          the clz and clo instructions
199 ;; trap         trap if instructions
200 ;; imul         integer multiply 2 operands
201 ;; imul3        integer multiply 3 operands
202 ;; imadd        integer multiply-add
203 ;; idiv         integer divide
204 ;; fmove        floating point register move
205 ;; fadd         floating point add/subtract
206 ;; fmul         floating point multiply
207 ;; fmadd        floating point multiply-add
208 ;; fdiv         floating point divide
209 ;; frdiv        floating point reciprocal divide
210 ;; frdiv1       floating point reciprocal divide step 1
211 ;; frdiv2       floating point reciprocal divide step 2
212 ;; fabs         floating point absolute value
213 ;; fneg         floating point negation
214 ;; fcmp         floating point compare
215 ;; fcvt         floating point convert
216 ;; fsqrt        floating point square root
217 ;; frsqrt       floating point reciprocal square root
218 ;; frsqrt1      floating point reciprocal square root step1
219 ;; frsqrt2      floating point reciprocal square root step2
220 ;; multi        multiword sequence (or user asm statements)
221 ;; nop          no operation
222 (define_attr "type"
223   "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"
224   (cond [(eq_attr "jal" "!unset") (const_string "call")
225          (eq_attr "got" "load") (const_string "load")]
226         (const_string "unknown")))
227
228 ;; Main data type used by the insn
229 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
230   (const_string "unknown"))
231
232 ;; Mode for conversion types (fcvt)
233 ;; I2S          integer to float single (SI/DI to SF)
234 ;; I2D          integer to float double (SI/DI to DF)
235 ;; S2I          float to integer (SF to SI/DI)
236 ;; D2I          float to integer (DF to SI/DI)
237 ;; D2S          double to float single
238 ;; S2D          float single to double
239
240 (define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D" 
241   (const_string "unknown"))
242
243 ;; Is this an extended instruction in mips16 mode?
244 (define_attr "extended_mips16" "no,yes"
245   (const_string "no"))
246
247 ;; Length of instruction in bytes.
248 (define_attr "length" ""
249    (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
250           ;; If a branch is outside this range, we have a choice of two
251           ;; sequences.  For PIC, an out-of-range branch like:
252           ;;
253           ;;    bne     r1,r2,target
254           ;;    dslot
255           ;;
256           ;; becomes the equivalent of:
257           ;;
258           ;;    beq     r1,r2,1f
259           ;;    dslot
260           ;;    la      $at,target
261           ;;    jr      $at
262           ;;    nop
263           ;; 1:
264           ;;
265           ;; where the load address can be up to three instructions long
266           ;; (lw, nop, addiu).
267           ;;
268           ;; The non-PIC case is similar except that we use a direct
269           ;; jump instead of an la/jr pair.  Since the target of this
270           ;; jump is an absolute 28-bit bit address (the other bits
271           ;; coming from the address of the delay slot) this form cannot
272           ;; cross a 256MB boundary.  We could provide the option of
273           ;; using la/jr in this case too, but we do not do so at
274           ;; present.
275           ;;
276           ;; Note that this value does not account for the delay slot
277           ;; instruction, whose length is added separately.  If the RTL
278           ;; pattern has no explicit delay slot, mips_adjust_insn_length
279           ;; will add the length of the implicit nop.  The values for
280           ;; forward and backward branches will be different as well.
281           (eq_attr "type" "branch")
282           (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
283                       (le (minus (pc) (match_dup 1)) (const_int 131068)))
284                   (const_int 4)
285                  (ne (symbol_ref "flag_pic") (const_int 0))
286                  (const_int 24)
287                  ] (const_int 12))
288
289           (eq_attr "got" "load")
290           (const_int 4)
291           (eq_attr "got" "xgot_high")
292           (const_int 8)
293
294           (eq_attr "type" "const")
295           (symbol_ref "mips_const_insns (operands[1]) * 4")
296           (eq_attr "type" "load,fpload")
297           (symbol_ref "mips_fetch_insns (operands[1]) * 4")
298           (eq_attr "type" "store,fpstore")
299           (symbol_ref "mips_fetch_insns (operands[0]) * 4")
300
301           ;; In the worst case, a call macro will take 8 instructions:
302           ;;
303           ;;     lui $25,%call_hi(FOO)
304           ;;     addu $25,$25,$28
305           ;;     lw $25,%call_lo(FOO)($25)
306           ;;     nop
307           ;;     jalr $25
308           ;;     nop
309           ;;     lw $gp,X($sp)
310           ;;     nop
311           (eq_attr "jal_macro" "yes")
312           (const_int 32)
313
314           (and (eq_attr "extended_mips16" "yes")
315                (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
316           (const_int 8)
317
318           ;; Various VR4120 errata require a nop to be inserted after a macc
319           ;; instruction.  The assembler does this for us, so account for
320           ;; the worst-case length here.
321           (and (eq_attr "type" "imadd")
322                (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
323           (const_int 8)
324
325           ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
326           ;; the result of the second one is missed.  The assembler should work
327           ;; around this by inserting a nop after the first dmult.
328           (and (eq_attr "type" "imul,imul3")
329                (and (eq_attr "mode" "DI")
330                     (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
331           (const_int 8)
332
333           (eq_attr "type" "idiv")
334           (symbol_ref "mips_idiv_insns () * 4")
335           ] (const_int 4)))
336
337 ;; Attribute describing the processor.  This attribute must match exactly
338 ;; with the processor_type enumeration in mips.h.
339 (define_attr "cpu"
340   "r3000,4kc,4kp,5kc,5kf,20kc,24k,24kx,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
341   (const (symbol_ref "mips_tune")))
342
343 ;; The type of hardware hazard associated with this instruction.
344 ;; DELAY means that the next instruction cannot read the result
345 ;; of this one.  HILO means that the next two instructions cannot
346 ;; write to HI or LO.
347 (define_attr "hazard" "none,delay,hilo"
348   (cond [(and (eq_attr "type" "load,fpload,fpidxload")
349               (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
350          (const_string "delay")
351
352          (and (eq_attr "type" "xfer")
353               (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
354          (const_string "delay")
355
356          (and (eq_attr "type" "fcmp")
357               (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
358          (const_string "delay")
359
360          ;; The r4000 multiplication patterns include an mflo instruction.
361          (and (eq_attr "type" "imul")
362               (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
363          (const_string "hilo")
364
365          (and (eq_attr "type" "mfhilo")
366               (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
367          (const_string "hilo")]
368         (const_string "none")))
369
370 ;; Is it a single instruction?
371 (define_attr "single_insn" "no,yes"
372   (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
373
374 ;; Can the instruction be put into a delay slot?
375 (define_attr "can_delay" "no,yes"
376   (if_then_else (and (eq_attr "type" "!branch,call,jump")
377                      (and (eq_attr "hazard" "none")
378                           (eq_attr "single_insn" "yes")))
379                 (const_string "yes")
380                 (const_string "no")))
381
382 ;; Attribute defining whether or not we can use the branch-likely instructions
383 (define_attr "branch_likely" "no,yes"
384   (const
385    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
386                  (const_string "yes")
387                  (const_string "no"))))
388
389 ;; True if an instruction might assign to hi or lo when reloaded.
390 ;; This is used by the TUNE_MACC_CHAINS code.
391 (define_attr "may_clobber_hilo" "no,yes"
392   (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthilo")
393                 (const_string "yes")
394                 (const_string "no")))
395
396 ;; Describe a user's asm statement.
397 (define_asm_attributes
398   [(set_attr "type" "multi")
399    (set_attr "can_delay" "no")])
400 \f
401 ;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
402 ;; from the same template.
403 (define_mode_macro GPR [SI (DI "TARGET_64BIT")])
404
405 ;; This mode macro allows :P to be used for patterns that operate on
406 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
407 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
408
409 ;; This mode macro allows :MOVECC to be used anywhere that a
410 ;; conditional-move-type condition is needed.
411 (define_mode_macro MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
412
413 ;; This mode macro allows the QI and HI extension patterns to be defined from
414 ;; the same template.
415 (define_mode_macro SHORT [QI HI])
416
417 ;; This mode macro allows :ANYF to be used wherever a scalar or vector
418 ;; floating-point mode is allowed.
419 (define_mode_macro ANYF [(SF "TARGET_HARD_FLOAT")
420                          (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
421                          (V2SF "TARGET_PAIRED_SINGLE_FLOAT")])
422
423 ;; Like ANYF, but only applies to scalar modes.
424 (define_mode_macro SCALARF [(SF "TARGET_HARD_FLOAT")
425                             (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
426
427 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
428 ;; 32-bit version and "dsubu" in the 64-bit version.
429 (define_mode_attr d [(SI "") (DI "d")])
430
431 ;; This attribute gives the length suffix for a sign- or zero-extension
432 ;; instruction.
433 (define_mode_attr size [(QI "b") (HI "h")])
434
435 ;; This attributes gives the mode mask of a SHORT.
436 (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
437
438 ;; Mode attributes for GPR loads and stores.
439 (define_mode_attr load [(SI "lw") (DI "ld")])
440 (define_mode_attr store [(SI "sw") (DI "sd")])
441
442 ;; Similarly for MIPS IV indexed FPR loads and stores.
443 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
444 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
445
446 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
447 ;; are different.  Some forms of unextended addiu have an 8-bit immediate
448 ;; field but the equivalent daddiu has only a 5-bit field.
449 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
450
451 ;; This attribute gives the best constraint to use for registers of
452 ;; a given mode.
453 (define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
454
455 ;; This attribute gives the format suffix for floating-point operations.
456 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
457
458 ;; This attribute gives the upper-case mode name for one unit of a
459 ;; floating-point mode.
460 (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
461
462 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
463 ;;
464 ;; In certain cases, div.s and div.ps may have a rounding error
465 ;; and/or wrong inexact flag.
466 ;;
467 ;; Therefore, we only allow div.s if not working around SB-1 rev2
468 ;; errata or if a slight loss of precision is OK.
469 (define_mode_attr divide_condition
470   [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")
471    (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")])
472
473 ; This attribute gives the condition for which sqrt instructions exist.
474 (define_mode_attr sqrt_condition
475   [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")])
476
477 ; This attribute gives the condition for which recip and rsqrt instructions
478 ; exist.
479 (define_mode_attr recip_condition
480   [(SF "ISA_HAS_FP4") (DF "ISA_HAS_FP4") (V2SF "TARGET_SB1")])
481
482 ;; This code macro allows all branch instructions to be generated from
483 ;; a single define_expand template.
484 (define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
485                              eq ne gt ge lt le gtu geu ltu leu])
486
487 ;; This code macro allows signed and unsigned widening multiplications
488 ;; to use the same template.
489 (define_code_macro any_extend [sign_extend zero_extend])
490
491 ;; This code macro allows the three shift instructions to be generated
492 ;; from the same template.
493 (define_code_macro any_shift [ashift ashiftrt lshiftrt])
494
495 ;; This code macro allows all native floating-point comparisons to be
496 ;; generated from the same template.
497 (define_code_macro fcond [unordered uneq unlt unle eq lt le])
498
499 ;; This code macro is used for comparisons that can be implemented
500 ;; by swapping the operands.
501 (define_code_macro swapped_fcond [ge gt unge ungt])
502
503 ;; <u> expands to an empty string when doing a signed operation and
504 ;; "u" when doing an unsigned operation.
505 (define_code_attr u [(sign_extend "") (zero_extend "u")])
506
507 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
508 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
509
510 ;; <optab> expands to the name of the optab for a particular code.
511 (define_code_attr optab [(ashift "ashl")
512                          (ashiftrt "ashr")
513                          (lshiftrt "lshr")])
514
515 ;; <insn> expands to the name of the insn that implements a particular code.
516 (define_code_attr insn [(ashift "sll")
517                         (ashiftrt "sra")
518                         (lshiftrt "srl")])
519
520 ;; <fcond> is the c.cond.fmt condition associated with a particular code.
521 (define_code_attr fcond [(unordered "un")
522                          (uneq "ueq")
523                          (unlt "ult")
524                          (unle "ule")
525                          (eq "eq")
526                          (lt "lt")
527                          (le "le")])
528
529 ;; Similar, but for swapped conditions.
530 (define_code_attr swapped_fcond [(ge "le")
531                                  (gt "lt")
532                                  (unge "ule")
533                                  (ungt "ult")])
534 \f
535 ;; .........................
536 ;;
537 ;;      Branch, call and jump delay slots
538 ;;
539 ;; .........................
540
541 (define_delay (and (eq_attr "type" "branch")
542                    (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
543   [(eq_attr "can_delay" "yes")
544    (nil)
545    (and (eq_attr "branch_likely" "yes")
546         (eq_attr "can_delay" "yes"))])
547
548 (define_delay (eq_attr "type" "jump")
549   [(eq_attr "can_delay" "yes")
550    (nil)
551    (nil)])
552
553 (define_delay (and (eq_attr "type" "call")
554                    (eq_attr "jal_macro" "no"))
555   [(eq_attr "can_delay" "yes")
556    (nil)
557    (nil)])
558 \f
559 ;; Pipeline descriptions.
560 ;;
561 ;; generic.md provides a fallback for processors without a specific
562 ;; pipeline description.  It is derived from the old define_function_unit
563 ;; version and uses the "alu" and "imuldiv" units declared below.
564 ;;
565 ;; Some of the processor-specific files are also derived from old
566 ;; define_function_unit descriptions and simply override the parts of
567 ;; generic.md that don't apply.  The other processor-specific files
568 ;; are self-contained.
569 (define_automaton "alu,imuldiv")
570
571 (define_cpu_unit "alu" "alu")
572 (define_cpu_unit "imuldiv" "imuldiv")
573
574 (include "4k.md")
575 (include "5k.md")
576 (include "24k.md")
577 (include "3000.md")
578 (include "4000.md")
579 (include "4100.md")
580 (include "4130.md")
581 (include "4300.md")
582 (include "4600.md")
583 (include "5000.md")
584 (include "5400.md")
585 (include "5500.md")
586 (include "6000.md")
587 (include "7000.md")
588 (include "9000.md")
589 (include "sb1.md")
590 (include "sr71k.md")
591 (include "generic.md")
592 \f
593 ;;
594 ;;  ....................
595 ;;
596 ;;      CONDITIONAL TRAPS
597 ;;
598 ;;  ....................
599 ;;
600
601 (define_insn "trap"
602   [(trap_if (const_int 1) (const_int 0))]
603   ""
604 {
605   if (ISA_HAS_COND_TRAP)
606     return "teq\t$0,$0";
607   else if (TARGET_MIPS16)
608     return "break 0";
609   else
610     return "break";
611 }
612   [(set_attr "type" "trap")])
613
614 (define_expand "conditional_trap"
615   [(trap_if (match_operator 0 "comparison_operator"
616                             [(match_dup 2) (match_dup 3)])
617             (match_operand 1 "const_int_operand"))]
618   "ISA_HAS_COND_TRAP"
619 {
620   if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
621       && operands[1] == const0_rtx)
622     {
623       mips_gen_conditional_trap (operands);
624       DONE;
625     }
626   else
627     FAIL;
628 })
629
630 (define_insn "*conditional_trap<mode>"
631   [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
632                                 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
633                                  (match_operand:GPR 2 "arith_operand" "dI")])
634             (const_int 0))]
635   "ISA_HAS_COND_TRAP"
636   "t%C0\t%z1,%2"
637   [(set_attr "type" "trap")])
638 \f
639 ;;
640 ;;  ....................
641 ;;
642 ;;      ADDITION
643 ;;
644 ;;  ....................
645 ;;
646
647 (define_insn "add<mode>3"
648   [(set (match_operand:ANYF 0 "register_operand" "=f")
649         (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
650                    (match_operand:ANYF 2 "register_operand" "f")))]
651   ""
652   "add.<fmt>\t%0,%1,%2"
653   [(set_attr "type" "fadd")
654    (set_attr "mode" "<UNITMODE>")])
655
656 (define_expand "add<mode>3"
657   [(set (match_operand:GPR 0 "register_operand")
658         (plus:GPR (match_operand:GPR 1 "register_operand")
659                   (match_operand:GPR 2 "arith_operand")))]
660   "")
661
662 (define_insn "*add<mode>3"
663   [(set (match_operand:GPR 0 "register_operand" "=d,d")
664         (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
665                   (match_operand:GPR 2 "arith_operand" "d,Q")))]
666   "!TARGET_MIPS16"
667   "@
668     <d>addu\t%0,%1,%2
669     <d>addiu\t%0,%1,%2"
670   [(set_attr "type" "arith")
671    (set_attr "mode" "<MODE>")])
672
673 ;; We need to recognize MIPS16 stack pointer additions explicitly, since
674 ;; we don't have a constraint for $sp.  These insns will be generated by
675 ;; the save_restore_insns functions.
676
677 (define_insn "*add<mode>3_sp1"
678   [(set (reg:GPR 29)
679         (plus:GPR (reg:GPR 29)
680                   (match_operand:GPR 0 "const_arith_operand" "")))]
681   "TARGET_MIPS16"
682   "<d>addiu\t%$,%$,%0"
683   [(set_attr "type" "arith")
684    (set_attr "mode" "<MODE>")
685    (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
686                                       (const_int 4)
687                                       (const_int 8)))])
688
689 (define_insn "*add<mode>3_sp2"
690   [(set (match_operand:GPR 0 "register_operand" "=d")
691         (plus:GPR (reg:GPR 29)
692                   (match_operand:GPR 1 "const_arith_operand" "")))]
693   "TARGET_MIPS16"
694   "<d>addiu\t%0,%$,%1"
695   [(set_attr "type" "arith")
696    (set_attr "mode" "<MODE>")
697    (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
698                                       (const_int 4)
699                                       (const_int 8)))])
700
701 (define_insn "*add<mode>3_mips16"
702   [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
703         (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
704                   (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
705   "TARGET_MIPS16"
706   "@
707     <d>addiu\t%0,%2
708     <d>addiu\t%0,%1,%2
709     <d>addu\t%0,%1,%2"
710   [(set_attr "type" "arith")
711    (set_attr "mode" "<MODE>")
712    (set_attr_alternative "length"
713                 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
714                                (const_int 4)
715                                (const_int 8))
716                  (if_then_else (match_operand 2 "m16_simm4_1")
717                                (const_int 4)
718                                (const_int 8))
719                  (const_int 4)])])
720
721
722 ;; On the mips16, we can sometimes split an add of a constant which is
723 ;; a 4 byte instruction into two adds which are both 2 byte
724 ;; instructions.  There are two cases: one where we are adding a
725 ;; constant plus a register to another register, and one where we are
726 ;; simply adding a constant to a register.
727
728 (define_split
729   [(set (match_operand:SI 0 "register_operand")
730         (plus:SI (match_dup 0)
731                  (match_operand:SI 1 "const_int_operand")))]
732   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
733    && REG_P (operands[0])
734    && M16_REG_P (REGNO (operands[0]))
735    && GET_CODE (operands[1]) == CONST_INT
736    && ((INTVAL (operands[1]) > 0x7f
737         && INTVAL (operands[1]) <= 0x7f + 0x7f)
738        || (INTVAL (operands[1]) < - 0x80
739            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
740   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
741    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
742 {
743   HOST_WIDE_INT val = INTVAL (operands[1]);
744
745   if (val >= 0)
746     {
747       operands[1] = GEN_INT (0x7f);
748       operands[2] = GEN_INT (val - 0x7f);
749     }
750   else
751     {
752       operands[1] = GEN_INT (- 0x80);
753       operands[2] = GEN_INT (val + 0x80);
754     }
755 })
756
757 (define_split
758   [(set (match_operand:SI 0 "register_operand")
759         (plus:SI (match_operand:SI 1 "register_operand")
760                  (match_operand:SI 2 "const_int_operand")))]
761   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
762    && REG_P (operands[0])
763    && M16_REG_P (REGNO (operands[0]))
764    && REG_P (operands[1])
765    && M16_REG_P (REGNO (operands[1]))
766    && REGNO (operands[0]) != REGNO (operands[1])
767    && GET_CODE (operands[2]) == CONST_INT
768    && ((INTVAL (operands[2]) > 0x7
769         && INTVAL (operands[2]) <= 0x7 + 0x7f)
770        || (INTVAL (operands[2]) < - 0x8
771            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
772   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
773    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
774 {
775   HOST_WIDE_INT val = INTVAL (operands[2]);
776
777   if (val >= 0)
778     {
779       operands[2] = GEN_INT (0x7);
780       operands[3] = GEN_INT (val - 0x7);
781     }
782   else
783     {
784       operands[2] = GEN_INT (- 0x8);
785       operands[3] = GEN_INT (val + 0x8);
786     }
787 })
788
789 (define_split
790   [(set (match_operand:DI 0 "register_operand")
791         (plus:DI (match_dup 0)
792                  (match_operand:DI 1 "const_int_operand")))]
793   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
794    && REG_P (operands[0])
795    && M16_REG_P (REGNO (operands[0]))
796    && GET_CODE (operands[1]) == CONST_INT
797    && ((INTVAL (operands[1]) > 0xf
798         && INTVAL (operands[1]) <= 0xf + 0xf)
799        || (INTVAL (operands[1]) < - 0x10
800            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
801   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
802    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
803 {
804   HOST_WIDE_INT val = INTVAL (operands[1]);
805
806   if (val >= 0)
807     {
808       operands[1] = GEN_INT (0xf);
809       operands[2] = GEN_INT (val - 0xf);
810     }
811   else
812     {
813       operands[1] = GEN_INT (- 0x10);
814       operands[2] = GEN_INT (val + 0x10);
815     }
816 })
817
818 (define_split
819   [(set (match_operand:DI 0 "register_operand")
820         (plus:DI (match_operand:DI 1 "register_operand")
821                  (match_operand:DI 2 "const_int_operand")))]
822   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
823    && REG_P (operands[0])
824    && M16_REG_P (REGNO (operands[0]))
825    && REG_P (operands[1])
826    && M16_REG_P (REGNO (operands[1]))
827    && REGNO (operands[0]) != REGNO (operands[1])
828    && GET_CODE (operands[2]) == CONST_INT
829    && ((INTVAL (operands[2]) > 0x7
830         && INTVAL (operands[2]) <= 0x7 + 0xf)
831        || (INTVAL (operands[2]) < - 0x8
832            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
833   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
834    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
835 {
836   HOST_WIDE_INT val = INTVAL (operands[2]);
837
838   if (val >= 0)
839     {
840       operands[2] = GEN_INT (0x7);
841       operands[3] = GEN_INT (val - 0x7);
842     }
843   else
844     {
845       operands[2] = GEN_INT (- 0x8);
846       operands[3] = GEN_INT (val + 0x8);
847     }
848 })
849
850 (define_insn "*addsi3_extended"
851   [(set (match_operand:DI 0 "register_operand" "=d,d")
852         (sign_extend:DI
853              (plus:SI (match_operand:SI 1 "register_operand" "d,d")
854                       (match_operand:SI 2 "arith_operand" "d,Q"))))]
855   "TARGET_64BIT && !TARGET_MIPS16"
856   "@
857     addu\t%0,%1,%2
858     addiu\t%0,%1,%2"
859   [(set_attr "type" "arith")
860    (set_attr "mode" "SI")])
861
862 ;; Split this insn so that the addiu splitters can have a crack at it.
863 ;; Use a conservative length estimate until the split.
864 (define_insn_and_split "*addsi3_extended_mips16"
865   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
866         (sign_extend:DI
867              (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
868                       (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
869   "TARGET_64BIT && TARGET_MIPS16"
870   "#"
871   "&& reload_completed"
872   [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
873   { operands[3] = gen_lowpart (SImode, operands[0]); }
874   [(set_attr "type" "arith")
875    (set_attr "mode" "SI")
876    (set_attr "extended_mips16" "yes")])
877 \f
878 ;;
879 ;;  ....................
880 ;;
881 ;;      SUBTRACTION
882 ;;
883 ;;  ....................
884 ;;
885
886 (define_insn "sub<mode>3"
887   [(set (match_operand:ANYF 0 "register_operand" "=f")
888         (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
889                     (match_operand:ANYF 2 "register_operand" "f")))]
890   ""
891   "sub.<fmt>\t%0,%1,%2"
892   [(set_attr "type" "fadd")
893    (set_attr "mode" "<UNITMODE>")])
894
895 (define_insn "sub<mode>3"
896   [(set (match_operand:GPR 0 "register_operand" "=d")
897         (minus:GPR (match_operand:GPR 1 "register_operand" "d")
898                    (match_operand:GPR 2 "register_operand" "d")))]
899   ""
900   "<d>subu\t%0,%1,%2"
901   [(set_attr "type" "arith")
902    (set_attr "mode" "<MODE>")])
903
904 (define_insn "*subsi3_extended"
905   [(set (match_operand:DI 0 "register_operand" "=d")
906         (sign_extend:DI
907             (minus:SI (match_operand:SI 1 "register_operand" "d")
908                       (match_operand:SI 2 "register_operand" "d"))))]
909   "TARGET_64BIT"
910   "subu\t%0,%1,%2"
911   [(set_attr "type" "arith")
912    (set_attr "mode" "DI")])
913 \f
914 ;;
915 ;;  ....................
916 ;;
917 ;;      MULTIPLICATION
918 ;;
919 ;;  ....................
920 ;;
921
922 (define_expand "mul<mode>3"
923   [(set (match_operand:SCALARF 0 "register_operand")
924         (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
925                       (match_operand:SCALARF 2 "register_operand")))]
926   ""
927   "")
928
929 (define_insn "*mul<mode>3"
930   [(set (match_operand:SCALARF 0 "register_operand" "=f")
931         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
932                       (match_operand:SCALARF 2 "register_operand" "f")))]
933   "!TARGET_4300_MUL_FIX"
934   "mul.<fmt>\t%0,%1,%2"
935   [(set_attr "type" "fmul")
936    (set_attr "mode" "<MODE>")])
937
938 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
939 ;; operands may corrupt immediately following multiplies. This is a
940 ;; simple fix to insert NOPs.
941
942 (define_insn "*mul<mode>3_r4300"
943   [(set (match_operand:SCALARF 0 "register_operand" "=f")
944         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
945                       (match_operand:SCALARF 2 "register_operand" "f")))]
946   "TARGET_4300_MUL_FIX"
947   "mul.<fmt>\t%0,%1,%2\;nop"
948   [(set_attr "type" "fmul")
949    (set_attr "mode" "<MODE>")
950    (set_attr "length" "8")])
951
952 (define_insn "mulv2sf3"
953   [(set (match_operand:V2SF 0 "register_operand" "=f")
954         (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
955                    (match_operand:V2SF 2 "register_operand" "f")))]
956   "TARGET_PAIRED_SINGLE_FLOAT"
957   "mul.ps\t%0,%1,%2"
958   [(set_attr "type" "fmul")
959    (set_attr "mode" "SF")])
960
961 ;; The original R4000 has a cpu bug.  If a double-word or a variable
962 ;; shift executes while an integer multiplication is in progress, the
963 ;; shift may give an incorrect result.  Avoid this by keeping the mflo
964 ;; with the mult on the R4000.
965 ;;
966 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
967 ;; (also valid for MIPS R4000MC processors):
968 ;;
969 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
970 ;;      this errata description.
971 ;;      The following code sequence causes the R4000 to incorrectly
972 ;;      execute the Double Shift Right Arithmetic 32 (dsra32)
973 ;;      instruction.  If the dsra32 instruction is executed during an
974 ;;      integer multiply, the dsra32 will only shift by the amount in
975 ;;      specified in the instruction rather than the amount plus 32
976 ;;      bits.
977 ;;      instruction 1:          mult    rs,rt           integer multiply
978 ;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
979 ;;                                                      right arithmetic + 32
980 ;;      Workaround: A dsra32 instruction placed after an integer
981 ;;      multiply should not be one of the 11 instructions after the
982 ;;      multiply instruction."
983 ;;
984 ;; and:
985 ;;
986 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
987 ;;      the following description.
988 ;;      All extended shifts (shift by n+32) and variable shifts (32 and
989 ;;      64-bit versions) may produce incorrect results under the
990 ;;      following conditions:
991 ;;      1) An integer multiply is currently executing
992 ;;      2) These types of shift instructions are executed immediately
993 ;;         following an integer divide instruction.
994 ;;      Workaround:
995 ;;      1) Make sure no integer multiply is running wihen these
996 ;;         instruction are executed.  If this cannot be predicted at
997 ;;         compile time, then insert a "mfhi" to R0 instruction
998 ;;         immediately after the integer multiply instruction.  This
999 ;;         will cause the integer multiply to complete before the shift
1000 ;;         is executed.
1001 ;;      2) Separate integer divide and these two classes of shift
1002 ;;         instructions by another instruction or a noop."
1003 ;;
1004 ;; These processors have PRId values of 0x00004220 and 0x00004300,
1005 ;; respectively.
1006
1007 (define_expand "mul<mode>3"
1008   [(set (match_operand:GPR 0 "register_operand")
1009         (mult:GPR (match_operand:GPR 1 "register_operand")
1010                   (match_operand:GPR 2 "register_operand")))]
1011   ""
1012 {
1013   if (GENERATE_MULT3_<MODE>)
1014     emit_insn (gen_mul<mode>3_mult3 (operands[0], operands[1], operands[2]));
1015   else if (!TARGET_FIX_R4000)
1016     emit_insn (gen_mul<mode>3_internal (operands[0], operands[1],
1017                                         operands[2]));
1018   else
1019     emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
1020   DONE;
1021 })
1022
1023 (define_insn "mulsi3_mult3"
1024   [(set (match_operand:SI 0 "register_operand" "=d,l")
1025         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1026                  (match_operand:SI 2 "register_operand" "d,d")))
1027    (clobber (match_scratch:SI 3 "=h,h"))
1028    (clobber (match_scratch:SI 4 "=l,X"))]
1029   "GENERATE_MULT3_SI"
1030 {
1031   if (which_alternative == 1)
1032     return "mult\t%1,%2";
1033   if (TARGET_MAD
1034       || TARGET_MIPS5400
1035       || TARGET_MIPS5500
1036       || TARGET_MIPS7000
1037       || TARGET_MIPS9000
1038       || ISA_MIPS32
1039       || ISA_MIPS32R2
1040       || ISA_MIPS64)
1041     return "mul\t%0,%1,%2";
1042   return "mult\t%0,%1,%2";
1043 }
1044   [(set_attr "type" "imul3,imul")
1045    (set_attr "mode" "SI")])
1046
1047 (define_insn "muldi3_mult3"
1048   [(set (match_operand:DI 0 "register_operand" "=d")
1049         (mult:DI (match_operand:DI 1 "register_operand" "d")
1050                  (match_operand:DI 2 "register_operand" "d")))
1051    (clobber (match_scratch:DI 3 "=h"))
1052    (clobber (match_scratch:DI 4 "=l"))]
1053   "TARGET_64BIT && GENERATE_MULT3_DI"
1054   "dmult\t%0,%1,%2"
1055   [(set_attr "type" "imul3")
1056    (set_attr "mode" "DI")])
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   "GENERATE_MULT3_SI && 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 && !GENERATE_MULT3_SI"
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   "GENERATE_MULT3_SI
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   "GENERATE_MULT3_SI && 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   "nmadd.<fmt>\t%0,%3,%1,%2"
1767   [(set_attr "type" "fmadd")
1768    (set_attr "mode" "<UNITMODE>")])
1769
1770 (define_insn "*nmadd<mode>_fastmath"
1771   [(set (match_operand:ANYF 0 "register_operand" "=f")
1772         (minus:ANYF
1773          (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
1774                     (match_operand:ANYF 2 "register_operand" "f"))
1775          (match_operand:ANYF 3 "register_operand" "f")))]
1776   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1777    && !HONOR_SIGNED_ZEROS (<MODE>mode)"
1778   "nmadd.<fmt>\t%0,%3,%1,%2"
1779   [(set_attr "type" "fmadd")
1780    (set_attr "mode" "<UNITMODE>")])
1781
1782 (define_insn "*nmsub<mode>"
1783   [(set (match_operand:ANYF 0 "register_operand" "=f")
1784         (neg:ANYF (minus:ANYF
1785                    (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1786                               (match_operand:ANYF 3 "register_operand" "f"))
1787                    (match_operand:ANYF 1 "register_operand" "f"))))]
1788   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1789    && HONOR_SIGNED_ZEROS (<MODE>mode)"
1790   "nmsub.<fmt>\t%0,%1,%2,%3"
1791   [(set_attr "type" "fmadd")
1792    (set_attr "mode" "<UNITMODE>")])
1793
1794 (define_insn "*nmsub<mode>_fastmath"
1795   [(set (match_operand:ANYF 0 "register_operand" "=f")
1796         (minus:ANYF
1797          (match_operand:ANYF 1 "register_operand" "f")
1798          (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1799                     (match_operand:ANYF 3 "register_operand" "f"))))]
1800   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1801    && !HONOR_SIGNED_ZEROS (<MODE>mode)"
1802   "nmsub.<fmt>\t%0,%1,%2,%3"
1803   [(set_attr "type" "fmadd")
1804    (set_attr "mode" "<UNITMODE>")])
1805 \f
1806 ;;
1807 ;;  ....................
1808 ;;
1809 ;;      DIVISION and REMAINDER
1810 ;;
1811 ;;  ....................
1812 ;;
1813
1814 (define_expand "div<mode>3"
1815   [(set (match_operand:ANYF 0 "register_operand")
1816         (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
1817                   (match_operand:ANYF 2 "register_operand")))]
1818   "<divide_condition>"
1819 {
1820   if (const_1_operand (operands[1], <MODE>mode))
1821     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1822       operands[1] = force_reg (<MODE>mode, operands[1]);
1823 })
1824
1825 ;; These patterns work around the early SB-1 rev2 core "F1" erratum:
1826 ;;
1827 ;; If an mfc1 or dmfc1 happens to access the floating point register
1828 ;; file at the same time a long latency operation (div, sqrt, recip,
1829 ;; sqrt) iterates an intermediate result back through the floating
1830 ;; point register file bypass, then instead returning the correct
1831 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1832 ;; result of the long latency operation.
1833 ;;
1834 ;; The workaround is to insert an unconditional 'mov' from/to the
1835 ;; long latency op destination register.
1836
1837 (define_insn "*div<mode>3"
1838   [(set (match_operand:ANYF 0 "register_operand" "=f")
1839         (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
1840                   (match_operand:ANYF 2 "register_operand" "f")))]
1841   "<divide_condition>"
1842 {
1843   if (TARGET_FIX_SB1)
1844     return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
1845   else
1846     return "div.<fmt>\t%0,%1,%2";
1847 }
1848   [(set_attr "type" "fdiv")
1849    (set_attr "mode" "<UNITMODE>")
1850    (set (attr "length")
1851         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1852                       (const_int 8)
1853                       (const_int 4)))])
1854
1855 (define_insn "*recip<mode>3"
1856   [(set (match_operand:ANYF 0 "register_operand" "=f")
1857         (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1858                   (match_operand:ANYF 2 "register_operand" "f")))]
1859   "<recip_condition> && flag_unsafe_math_optimizations"
1860 {
1861   if (TARGET_FIX_SB1)
1862     return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1863   else
1864     return "recip.<fmt>\t%0,%2";
1865 }
1866   [(set_attr "type" "frdiv")
1867    (set_attr "mode" "<UNITMODE>")
1868    (set (attr "length")
1869         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1870                       (const_int 8)
1871                       (const_int 4)))])
1872
1873 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
1874 ;; with negative operands.  We use special libgcc functions instead.
1875 (define_insn "divmod<mode>4"
1876   [(set (match_operand:GPR 0 "register_operand" "=l")
1877         (div:GPR (match_operand:GPR 1 "register_operand" "d")
1878                  (match_operand:GPR 2 "register_operand" "d")))
1879    (set (match_operand:GPR 3 "register_operand" "=h")
1880         (mod:GPR (match_dup 1)
1881                  (match_dup 2)))]
1882   "!TARGET_FIX_VR4120"
1883   { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1884   [(set_attr "type" "idiv")
1885    (set_attr "mode" "<MODE>")])
1886
1887 (define_insn "udivmod<mode>4"
1888   [(set (match_operand:GPR 0 "register_operand" "=l")
1889         (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1890                   (match_operand:GPR 2 "register_operand" "d")))
1891    (set (match_operand:GPR 3 "register_operand" "=h")
1892         (umod:GPR (match_dup 1)
1893                   (match_dup 2)))]
1894   ""
1895   { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1896   [(set_attr "type" "idiv")
1897    (set_attr "mode" "<MODE>")])
1898 \f
1899 ;;
1900 ;;  ....................
1901 ;;
1902 ;;      SQUARE ROOT
1903 ;;
1904 ;;  ....................
1905
1906 ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
1907 ;; "*div[sd]f3" comment for details).
1908
1909 (define_insn "sqrt<mode>2"
1910   [(set (match_operand:ANYF 0 "register_operand" "=f")
1911         (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1912   "<sqrt_condition>"
1913 {
1914   if (TARGET_FIX_SB1)
1915     return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
1916   else
1917     return "sqrt.<fmt>\t%0,%1";
1918 }
1919   [(set_attr "type" "fsqrt")
1920    (set_attr "mode" "<UNITMODE>")
1921    (set (attr "length")
1922         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1923                       (const_int 8)
1924                       (const_int 4)))])
1925
1926 (define_insn "*rsqrt<mode>a"
1927   [(set (match_operand:ANYF 0 "register_operand" "=f")
1928         (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1929                   (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
1930   "<recip_condition> && flag_unsafe_math_optimizations"
1931 {
1932   if (TARGET_FIX_SB1)
1933     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1934   else
1935     return "rsqrt.<fmt>\t%0,%2";
1936 }
1937   [(set_attr "type" "frsqrt")
1938    (set_attr "mode" "<UNITMODE>")
1939    (set (attr "length")
1940         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1941                       (const_int 8)
1942                       (const_int 4)))])
1943
1944 (define_insn "*rsqrt<mode>b"
1945   [(set (match_operand:ANYF 0 "register_operand" "=f")
1946         (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1947                              (match_operand:ANYF 2 "register_operand" "f"))))]
1948   "<recip_condition> && flag_unsafe_math_optimizations"
1949 {
1950   if (TARGET_FIX_SB1)
1951     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1952   else
1953     return "rsqrt.<fmt>\t%0,%2";
1954 }
1955   [(set_attr "type" "frsqrt")
1956    (set_attr "mode" "<UNITMODE>")
1957    (set (attr "length")
1958         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1959                       (const_int 8)
1960                       (const_int 4)))])
1961 \f
1962 ;;
1963 ;;  ....................
1964 ;;
1965 ;;      ABSOLUTE VALUE
1966 ;;
1967 ;;  ....................
1968
1969 ;; Do not use the integer abs macro instruction, since that signals an
1970 ;; exception on -2147483648 (sigh).
1971
1972 (define_insn "abs<mode>2"
1973   [(set (match_operand:ANYF 0 "register_operand" "=f")
1974         (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1975   ""
1976   "abs.<fmt>\t%0,%1"
1977   [(set_attr "type" "fabs")
1978    (set_attr "mode" "<UNITMODE>")])
1979 \f
1980 ;;
1981 ;;  ...................
1982 ;;
1983 ;;  Count leading zeroes.
1984 ;;
1985 ;;  ...................
1986 ;;
1987
1988 (define_insn "clz<mode>2"
1989   [(set (match_operand:GPR 0 "register_operand" "=d")
1990         (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
1991   "ISA_HAS_CLZ_CLO"
1992   "<d>clz\t%0,%1"
1993   [(set_attr "type" "clz")
1994    (set_attr "mode" "<MODE>")])
1995 \f
1996 ;;
1997 ;;  ....................
1998 ;;
1999 ;;      NEGATION and ONE'S COMPLEMENT
2000 ;;
2001 ;;  ....................
2002
2003 (define_insn "negsi2"
2004   [(set (match_operand:SI 0 "register_operand" "=d")
2005         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2006   ""
2007 {
2008   if (TARGET_MIPS16)
2009     return "neg\t%0,%1";
2010   else
2011     return "subu\t%0,%.,%1";
2012 }
2013   [(set_attr "type"     "arith")
2014    (set_attr "mode"     "SI")])
2015
2016 (define_insn "negdi2"
2017   [(set (match_operand:DI 0 "register_operand" "=d")
2018         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2019   "TARGET_64BIT && !TARGET_MIPS16"
2020   "dsubu\t%0,%.,%1"
2021   [(set_attr "type"     "arith")
2022    (set_attr "mode"     "DI")])
2023
2024 (define_insn "neg<mode>2"
2025   [(set (match_operand:ANYF 0 "register_operand" "=f")
2026         (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2027   ""
2028   "neg.<fmt>\t%0,%1"
2029   [(set_attr "type" "fneg")
2030    (set_attr "mode" "<UNITMODE>")])
2031
2032 (define_insn "one_cmpl<mode>2"
2033   [(set (match_operand:GPR 0 "register_operand" "=d")
2034         (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2035   ""
2036 {
2037   if (TARGET_MIPS16)
2038     return "not\t%0,%1";
2039   else
2040     return "nor\t%0,%.,%1";
2041 }
2042   [(set_attr "type" "arith")
2043    (set_attr "mode" "<MODE>")])
2044 \f
2045 ;;
2046 ;;  ....................
2047 ;;
2048 ;;      LOGICAL
2049 ;;
2050 ;;  ....................
2051 ;;
2052
2053 ;; Many of these instructions use trivial define_expands, because we
2054 ;; want to use a different set of constraints when TARGET_MIPS16.
2055
2056 (define_expand "and<mode>3"
2057   [(set (match_operand:GPR 0 "register_operand")
2058         (and:GPR (match_operand:GPR 1 "register_operand")
2059                  (match_operand:GPR 2 "uns_arith_operand")))]
2060   ""
2061 {
2062   if (TARGET_MIPS16)
2063     operands[2] = force_reg (<MODE>mode, operands[2]);
2064 })
2065
2066 (define_insn "*and<mode>3"
2067   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2068         (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2069                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2070   "!TARGET_MIPS16"
2071   "@
2072    and\t%0,%1,%2
2073    andi\t%0,%1,%x2"
2074   [(set_attr "type" "arith")
2075    (set_attr "mode" "<MODE>")])
2076
2077 (define_insn "*and<mode>3_mips16"
2078   [(set (match_operand:GPR 0 "register_operand" "=d")
2079         (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2080                  (match_operand:GPR 2 "register_operand" "d")))]
2081   "TARGET_MIPS16"
2082   "and\t%0,%2"
2083   [(set_attr "type" "arith")
2084    (set_attr "mode" "<MODE>")])
2085
2086 (define_expand "ior<mode>3"
2087   [(set (match_operand:GPR 0 "register_operand")
2088         (ior:GPR (match_operand:GPR 1 "register_operand")
2089                  (match_operand:GPR 2 "uns_arith_operand")))]
2090   ""
2091 {
2092   if (TARGET_MIPS16)
2093     operands[2] = force_reg (<MODE>mode, operands[2]);
2094 })
2095
2096 (define_insn "*ior<mode>3"
2097   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2098         (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2099                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2100   "!TARGET_MIPS16"
2101   "@
2102    or\t%0,%1,%2
2103    ori\t%0,%1,%x2"
2104   [(set_attr "type" "arith")
2105    (set_attr "mode" "<MODE>")])
2106
2107 (define_insn "*ior<mode>3_mips16"
2108   [(set (match_operand:GPR 0 "register_operand" "=d")
2109         (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2110                  (match_operand:GPR 2 "register_operand" "d")))]
2111   "TARGET_MIPS16"
2112   "or\t%0,%2"
2113   [(set_attr "type" "arith")
2114    (set_attr "mode" "<MODE>")])
2115
2116 (define_expand "xor<mode>3"
2117   [(set (match_operand:GPR 0 "register_operand")
2118         (xor:GPR (match_operand:GPR 1 "register_operand")
2119                  (match_operand:GPR 2 "uns_arith_operand")))]
2120   ""
2121   "")
2122
2123 (define_insn ""
2124   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2125         (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2126                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2127   "!TARGET_MIPS16"
2128   "@
2129    xor\t%0,%1,%2
2130    xori\t%0,%1,%x2"
2131   [(set_attr "type" "arith")
2132    (set_attr "mode" "<MODE>")])
2133
2134 (define_insn ""
2135   [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2136         (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2137                  (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2138   "TARGET_MIPS16"
2139   "@
2140    xor\t%0,%2
2141    cmpi\t%1,%2
2142    cmp\t%1,%2"
2143   [(set_attr "type" "arith")
2144    (set_attr "mode" "<MODE>")
2145    (set_attr_alternative "length"
2146                 [(const_int 4)
2147                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2148                                (const_int 4)
2149                                (const_int 8))
2150                  (const_int 4)])])
2151
2152 (define_insn "*nor<mode>3"
2153   [(set (match_operand:GPR 0 "register_operand" "=d")
2154         (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2155                  (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2156   "!TARGET_MIPS16"
2157   "nor\t%0,%1,%2"
2158   [(set_attr "type" "arith")
2159    (set_attr "mode" "<MODE>")])
2160 \f
2161 ;;
2162 ;;  ....................
2163 ;;
2164 ;;      TRUNCATION
2165 ;;
2166 ;;  ....................
2167
2168
2169
2170 (define_insn "truncdfsf2"
2171   [(set (match_operand:SF 0 "register_operand" "=f")
2172         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2173   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2174   "cvt.s.d\t%0,%1"
2175   [(set_attr "type"     "fcvt")
2176    (set_attr "cnv_mode" "D2S")   
2177    (set_attr "mode"     "SF")])
2178
2179 ;; Integer truncation patterns.  Truncating SImode values to smaller
2180 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
2181 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2182 ;; need to make sure that the lower 32 bits are properly sign-extended
2183 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2184 ;; smaller than SImode is equivalent to two separate truncations:
2185 ;;
2186 ;;                        A       B
2187 ;;    DI ---> HI  ==  DI ---> SI ---> HI
2188 ;;    DI ---> QI  ==  DI ---> SI ---> QI
2189 ;;
2190 ;; Step A needs a real instruction but step B does not.
2191
2192 (define_insn "truncdisi2"
2193   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2194         (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2195   "TARGET_64BIT"
2196   "@
2197     sll\t%0,%1,0
2198     sw\t%1,%0"
2199   [(set_attr "type" "shift,store")
2200    (set_attr "mode" "SI")
2201    (set_attr "extended_mips16" "yes,*")])
2202
2203 (define_insn "truncdihi2"
2204   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2205         (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2206   "TARGET_64BIT"
2207   "@
2208     sll\t%0,%1,0
2209     sh\t%1,%0"
2210   [(set_attr "type" "shift,store")
2211    (set_attr "mode" "SI")
2212    (set_attr "extended_mips16" "yes,*")])
2213
2214 (define_insn "truncdiqi2"
2215   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2216         (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2217   "TARGET_64BIT"
2218   "@
2219     sll\t%0,%1,0
2220     sb\t%1,%0"
2221   [(set_attr "type" "shift,store")
2222    (set_attr "mode" "SI")
2223    (set_attr "extended_mips16" "yes,*")])
2224
2225 ;; Combiner patterns to optimize shift/truncate combinations.
2226
2227 (define_insn ""
2228   [(set (match_operand:SI 0 "register_operand" "=d")
2229         (truncate:SI
2230           (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2231                        (match_operand:DI 2 "const_arith_operand" ""))))]
2232   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2233   "dsra\t%0,%1,%2"
2234   [(set_attr "type" "shift")
2235    (set_attr "mode" "SI")])
2236
2237 (define_insn ""
2238   [(set (match_operand:SI 0 "register_operand" "=d")
2239         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2240                                   (const_int 32))))]
2241   "TARGET_64BIT && !TARGET_MIPS16"
2242   "dsra\t%0,%1,32"
2243   [(set_attr "type" "shift")
2244    (set_attr "mode" "SI")])
2245
2246
2247 ;; Combiner patterns for truncate/sign_extend combinations.  They use
2248 ;; the shift/truncate patterns above.
2249
2250 (define_insn_and_split ""
2251   [(set (match_operand:SI 0 "register_operand" "=d")
2252         (sign_extend:SI
2253             (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2254   "TARGET_64BIT && !TARGET_MIPS16"
2255   "#"
2256   "&& reload_completed"
2257   [(set (match_dup 2)
2258         (ashift:DI (match_dup 1)
2259                    (const_int 48)))
2260    (set (match_dup 0)
2261         (truncate:SI (ashiftrt:DI (match_dup 2)
2262                                   (const_int 48))))]
2263   { operands[2] = gen_lowpart (DImode, operands[0]); })
2264
2265 (define_insn_and_split ""
2266   [(set (match_operand:SI 0 "register_operand" "=d")
2267         (sign_extend:SI
2268             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2269   "TARGET_64BIT && !TARGET_MIPS16"
2270   "#"
2271   "&& reload_completed"
2272   [(set (match_dup 2)
2273         (ashift:DI (match_dup 1)
2274                    (const_int 56)))
2275    (set (match_dup 0)
2276         (truncate:SI (ashiftrt:DI (match_dup 2)
2277                                   (const_int 56))))]
2278   { operands[2] = gen_lowpart (DImode, operands[0]); })
2279
2280
2281 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2282
2283 (define_insn ""
2284   [(set (match_operand:SI 0 "register_operand" "=d")
2285         (zero_extend:SI (truncate:HI
2286                          (match_operand:DI 1 "register_operand" "d"))))]
2287   "TARGET_64BIT && !TARGET_MIPS16"
2288   "andi\t%0,%1,0xffff"
2289   [(set_attr "type"     "arith")
2290    (set_attr "mode"     "SI")])
2291
2292 (define_insn ""
2293   [(set (match_operand:SI 0 "register_operand" "=d")
2294         (zero_extend:SI (truncate:QI
2295                          (match_operand:DI 1 "register_operand" "d"))))]
2296   "TARGET_64BIT && !TARGET_MIPS16"
2297   "andi\t%0,%1,0xff"
2298   [(set_attr "type"     "arith")
2299    (set_attr "mode"     "SI")])
2300
2301 (define_insn ""
2302   [(set (match_operand:HI 0 "register_operand" "=d")
2303         (zero_extend:HI (truncate:QI
2304                          (match_operand:DI 1 "register_operand" "d"))))]
2305   "TARGET_64BIT && !TARGET_MIPS16"
2306   "andi\t%0,%1,0xff"
2307   [(set_attr "type"     "arith")
2308    (set_attr "mode"     "HI")])
2309 \f
2310 ;;
2311 ;;  ....................
2312 ;;
2313 ;;      ZERO EXTENSION
2314 ;;
2315 ;;  ....................
2316
2317 ;; Extension insns.
2318
2319 (define_insn_and_split "zero_extendsidi2"
2320   [(set (match_operand:DI 0 "register_operand" "=d,d")
2321         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
2322   "TARGET_64BIT"
2323   "@
2324    #
2325    lwu\t%0,%1"
2326   "&& reload_completed && REG_P (operands[1])"
2327   [(set (match_dup 0)
2328         (ashift:DI (match_dup 1) (const_int 32)))
2329    (set (match_dup 0)
2330         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2331   { operands[1] = gen_lowpart (DImode, operands[1]); }
2332   [(set_attr "type" "multi,load")
2333    (set_attr "mode" "DI")
2334    (set_attr "length" "8,*")])
2335
2336 ;; Combine is not allowed to convert this insn into a zero_extendsidi2
2337 ;; because of TRULY_NOOP_TRUNCATION.
2338
2339 (define_insn_and_split "*clear_upper32"
2340   [(set (match_operand:DI 0 "register_operand" "=d,d")
2341         (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
2342                 (const_int 4294967295)))]
2343   "TARGET_64BIT"
2344 {
2345   if (which_alternative == 0)
2346     return "#";
2347
2348   operands[1] = gen_lowpart (SImode, operands[1]);
2349   return "lwu\t%0,%1";
2350 }
2351   "&& reload_completed && REG_P (operands[1])"
2352   [(set (match_dup 0)
2353         (ashift:DI (match_dup 1) (const_int 32)))
2354    (set (match_dup 0)
2355         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2356   ""
2357   [(set_attr "type" "multi,load")
2358    (set_attr "mode" "DI")
2359    (set_attr "length" "8,*")])
2360
2361 (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
2362   [(set (match_operand:GPR 0 "register_operand")
2363         (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2364   ""
2365 {
2366   if (TARGET_MIPS16 && !GENERATE_MIPS16E
2367       && !memory_operand (operands[1], <SHORT:MODE>mode))
2368     {
2369       emit_insn (gen_and<GPR:mode>3 (operands[0],
2370                                      gen_lowpart (<GPR:MODE>mode, operands[1]),
2371                                      force_reg (<GPR:MODE>mode,
2372                                                 GEN_INT (<SHORT:mask>))));
2373       DONE;
2374     }
2375 })
2376
2377 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
2378   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2379         (zero_extend:GPR
2380              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2381   "!TARGET_MIPS16"
2382   "@
2383    andi\t%0,%1,<SHORT:mask>
2384    l<SHORT:size>u\t%0,%1"
2385   [(set_attr "type" "arith,load")
2386    (set_attr "mode" "<GPR:MODE>")])
2387
2388 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e"
2389   [(set (match_operand:GPR 0 "register_operand" "=d")
2390         (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
2391   "GENERATE_MIPS16E"
2392   "ze<SHORT:size>\t%0"
2393   [(set_attr "type" "arith")
2394    (set_attr "mode" "<GPR:MODE>")])
2395
2396 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16"
2397   [(set (match_operand:GPR 0 "register_operand" "=d")
2398         (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
2399   "TARGET_MIPS16"
2400   "l<SHORT:size>u\t%0,%1"
2401   [(set_attr "type" "load")
2402    (set_attr "mode" "<GPR:MODE>")])
2403
2404 (define_expand "zero_extendqihi2"
2405   [(set (match_operand:HI 0 "register_operand")
2406         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2407   ""
2408 {
2409   if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
2410     {
2411       emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
2412                                        operands[1]));
2413       DONE;
2414     }
2415 })
2416
2417 (define_insn "*zero_extendqihi2"
2418   [(set (match_operand:HI 0 "register_operand" "=d,d")
2419         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2420   "!TARGET_MIPS16"
2421   "@
2422    andi\t%0,%1,0x00ff
2423    lbu\t%0,%1"
2424   [(set_attr "type" "arith,load")
2425    (set_attr "mode" "HI")])
2426
2427 (define_insn "*zero_extendqihi2_mips16"
2428   [(set (match_operand:HI 0 "register_operand" "=d")
2429         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2430   "TARGET_MIPS16"
2431   "lbu\t%0,%1"
2432   [(set_attr "type" "load")
2433    (set_attr "mode" "HI")])
2434 \f
2435 ;;
2436 ;;  ....................
2437 ;;
2438 ;;      SIGN EXTENSION
2439 ;;
2440 ;;  ....................
2441
2442 ;; Extension insns.
2443 ;; Those for integer source operand are ordered widest source type first.
2444
2445 ;; When TARGET_64BIT, all SImode integer registers should already be in
2446 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can
2447 ;; therefore get rid of register->register instructions if we constrain
2448 ;; the source to be in the same register as the destination.
2449 ;;
2450 ;; The register alternative has type "arith" so that the pre-reload
2451 ;; scheduler will treat it as a move.  This reflects what happens if
2452 ;; the register alternative needs a reload.
2453 (define_insn_and_split "extendsidi2"
2454   [(set (match_operand:DI 0 "register_operand" "=d,d")
2455         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2456   "TARGET_64BIT"
2457   "@
2458    #
2459    lw\t%0,%1"
2460   "&& reload_completed && register_operand (operands[1], VOIDmode)"
2461   [(const_int 0)]
2462 {
2463   emit_note (NOTE_INSN_DELETED);
2464   DONE;
2465 }
2466   [(set_attr "type" "arith,load")
2467    (set_attr "mode" "DI")])
2468
2469 (define_expand "extend<SHORT:mode><GPR:mode>2"
2470   [(set (match_operand:GPR 0 "register_operand")
2471         (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2472   "")
2473
2474 (define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e"
2475   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2476         (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
2477   "GENERATE_MIPS16E"
2478   "@
2479    se<SHORT:size>\t%0
2480    l<SHORT:size>\t%0,%1"
2481   [(set_attr "type" "arith,load")
2482    (set_attr "mode" "<GPR:MODE>")])
2483
2484 (define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
2485   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2486         (sign_extend:GPR
2487              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2488   "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2489   "@
2490    #
2491    l<SHORT:size>\t%0,%1"
2492   "&& reload_completed && REG_P (operands[1])"
2493   [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
2494    (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
2495 {
2496   operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
2497   operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
2498                          - GET_MODE_BITSIZE (<SHORT:MODE>mode));
2499 }
2500   [(set_attr "type" "arith,load")
2501    (set_attr "mode" "<GPR:MODE>")
2502    (set_attr "length" "8,*")])
2503
2504 (define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
2505   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2506         (sign_extend:GPR
2507              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2508   "ISA_HAS_SEB_SEH"
2509   "@
2510    se<SHORT:size>\t%0,%1
2511    l<SHORT:size>\t%0,%1"
2512   [(set_attr "type" "arith,load")
2513    (set_attr "mode" "<GPR:MODE>")])
2514
2515 ;; This pattern generates the same code as extendqisi2; split it into
2516 ;; that form after reload.
2517 (define_insn_and_split "extendqihi2"
2518   [(set (match_operand:HI 0 "register_operand" "=d,d")
2519         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2520   ""
2521   "#"
2522   "reload_completed"
2523   [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
2524   { operands[0] = gen_lowpart (SImode, operands[0]); }
2525   [(set_attr "type" "arith,load")
2526    (set_attr "mode" "SI")
2527    (set_attr "length" "8,*")])
2528
2529 (define_insn "extendsfdf2"
2530   [(set (match_operand:DF 0 "register_operand" "=f")
2531         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2532   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2533   "cvt.d.s\t%0,%1"
2534   [(set_attr "type"     "fcvt")
2535    (set_attr "cnv_mode" "S2D")   
2536    (set_attr "mode"     "DF")])
2537 \f
2538 ;;
2539 ;;  ....................
2540 ;;
2541 ;;      CONVERSIONS
2542 ;;
2543 ;;  ....................
2544
2545 (define_expand "fix_truncdfsi2"
2546   [(set (match_operand:SI 0 "register_operand")
2547         (fix:SI (match_operand:DF 1 "register_operand")))]
2548   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2549 {
2550   if (!ISA_HAS_TRUNC_W)
2551     {
2552       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2553       DONE;
2554     }
2555 })
2556
2557 (define_insn "fix_truncdfsi2_insn"
2558   [(set (match_operand:SI 0 "register_operand" "=f")
2559         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2560   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2561   "trunc.w.d %0,%1"
2562   [(set_attr "type"     "fcvt")
2563    (set_attr "mode"     "DF")
2564    (set_attr "cnv_mode" "D2I")
2565    (set_attr "length"   "4")])
2566
2567 (define_insn "fix_truncdfsi2_macro"
2568   [(set (match_operand:SI 0 "register_operand" "=f")
2569         (fix:SI (match_operand:DF 1 "register_operand" "f")))
2570    (clobber (match_scratch:DF 2 "=d"))]
2571   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2572 {
2573   if (set_nomacro)
2574     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2575   else
2576     return "trunc.w.d %0,%1,%2";
2577 }
2578   [(set_attr "type"     "fcvt")
2579    (set_attr "mode"     "DF")
2580    (set_attr "cnv_mode" "D2I")
2581    (set_attr "length"   "36")])
2582
2583 (define_expand "fix_truncsfsi2"
2584   [(set (match_operand:SI 0 "register_operand")
2585         (fix:SI (match_operand:SF 1 "register_operand")))]
2586   "TARGET_HARD_FLOAT"
2587 {
2588   if (!ISA_HAS_TRUNC_W)
2589     {
2590       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2591       DONE;
2592     }
2593 })
2594
2595 (define_insn "fix_truncsfsi2_insn"
2596   [(set (match_operand:SI 0 "register_operand" "=f")
2597         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2598   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2599   "trunc.w.s %0,%1"
2600   [(set_attr "type"     "fcvt")
2601    (set_attr "mode"     "SF")
2602    (set_attr "cnv_mode" "S2I")
2603    (set_attr "length"   "4")])
2604
2605 (define_insn "fix_truncsfsi2_macro"
2606   [(set (match_operand:SI 0 "register_operand" "=f")
2607         (fix:SI (match_operand:SF 1 "register_operand" "f")))
2608    (clobber (match_scratch:SF 2 "=d"))]
2609   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2610 {
2611   if (set_nomacro)
2612     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2613   else
2614     return "trunc.w.s %0,%1,%2";
2615 }
2616   [(set_attr "type"     "fcvt")
2617    (set_attr "mode"     "SF")
2618    (set_attr "cnv_mode" "S2I")
2619    (set_attr "length"   "36")])
2620
2621
2622 (define_insn "fix_truncdfdi2"
2623   [(set (match_operand:DI 0 "register_operand" "=f")
2624         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2625   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2626   "trunc.l.d %0,%1"
2627   [(set_attr "type"     "fcvt")
2628    (set_attr "mode"     "DF")
2629    (set_attr "cnv_mode" "D2I")
2630    (set_attr "length"   "4")])
2631
2632
2633 (define_insn "fix_truncsfdi2"
2634   [(set (match_operand:DI 0 "register_operand" "=f")
2635         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2636   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2637   "trunc.l.s %0,%1"
2638   [(set_attr "type"     "fcvt")
2639    (set_attr "mode"     "SF")
2640    (set_attr "cnv_mode" "S2I")
2641    (set_attr "length"   "4")])
2642
2643
2644 (define_insn "floatsidf2"
2645   [(set (match_operand:DF 0 "register_operand" "=f")
2646         (float:DF (match_operand:SI 1 "register_operand" "f")))]
2647   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2648   "cvt.d.w\t%0,%1"
2649   [(set_attr "type"     "fcvt")
2650    (set_attr "mode"     "DF")
2651    (set_attr "cnv_mode" "I2D")   
2652    (set_attr "length"   "4")])
2653
2654
2655 (define_insn "floatdidf2"
2656   [(set (match_operand:DF 0 "register_operand" "=f")
2657         (float:DF (match_operand:DI 1 "register_operand" "f")))]
2658   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2659   "cvt.d.l\t%0,%1"
2660   [(set_attr "type"     "fcvt")
2661    (set_attr "mode"     "DF")
2662    (set_attr "cnv_mode" "I2D")   
2663    (set_attr "length"   "4")])
2664
2665
2666 (define_insn "floatsisf2"
2667   [(set (match_operand:SF 0 "register_operand" "=f")
2668         (float:SF (match_operand:SI 1 "register_operand" "f")))]
2669   "TARGET_HARD_FLOAT"
2670   "cvt.s.w\t%0,%1"
2671   [(set_attr "type"     "fcvt")
2672    (set_attr "mode"     "SF")
2673    (set_attr "cnv_mode" "I2S")   
2674    (set_attr "length"   "4")])
2675
2676
2677 (define_insn "floatdisf2"
2678   [(set (match_operand:SF 0 "register_operand" "=f")
2679         (float:SF (match_operand:DI 1 "register_operand" "f")))]
2680   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2681   "cvt.s.l\t%0,%1"
2682   [(set_attr "type"     "fcvt")
2683    (set_attr "mode"     "SF")
2684    (set_attr "cnv_mode" "I2S")   
2685    (set_attr "length"   "4")])
2686
2687
2688 (define_expand "fixuns_truncdfsi2"
2689   [(set (match_operand:SI 0 "register_operand")
2690         (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2691   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2692 {
2693   rtx reg1 = gen_reg_rtx (DFmode);
2694   rtx reg2 = gen_reg_rtx (DFmode);
2695   rtx reg3 = gen_reg_rtx (SImode);
2696   rtx label1 = gen_label_rtx ();
2697   rtx label2 = gen_label_rtx ();
2698   REAL_VALUE_TYPE offset;
2699
2700   real_2expN (&offset, 31);
2701
2702   if (reg1)                     /* Turn off complaints about unreached code.  */
2703     {
2704       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2705       do_pending_stack_adjust ();
2706
2707       emit_insn (gen_cmpdf (operands[1], reg1));
2708       emit_jump_insn (gen_bge (label1));
2709
2710       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2711       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2712                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
2713       emit_barrier ();
2714
2715       emit_label (label1);
2716       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2717       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2718                                      (BITMASK_HIGH, SImode)));
2719
2720       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2721       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2722
2723       emit_label (label2);
2724
2725       /* Allow REG_NOTES to be set on last insn (labels don't have enough
2726          fields, and can't be used for REG_NOTES anyway).  */
2727       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2728       DONE;
2729     }
2730 })
2731
2732
2733 (define_expand "fixuns_truncdfdi2"
2734   [(set (match_operand:DI 0 "register_operand")
2735         (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
2736   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2737 {
2738   rtx reg1 = gen_reg_rtx (DFmode);
2739   rtx reg2 = gen_reg_rtx (DFmode);
2740   rtx reg3 = gen_reg_rtx (DImode);
2741   rtx label1 = gen_label_rtx ();
2742   rtx label2 = gen_label_rtx ();
2743   REAL_VALUE_TYPE offset;
2744
2745   real_2expN (&offset, 63);
2746
2747   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2748   do_pending_stack_adjust ();
2749
2750   emit_insn (gen_cmpdf (operands[1], reg1));
2751   emit_jump_insn (gen_bge (label1));
2752
2753   emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2754   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2755                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2756   emit_barrier ();
2757
2758   emit_label (label1);
2759   emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2760   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2761   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2762
2763   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2764   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2765
2766   emit_label (label2);
2767
2768   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2769      fields, and can't be used for REG_NOTES anyway).  */
2770   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2771   DONE;
2772 })
2773
2774
2775 (define_expand "fixuns_truncsfsi2"
2776   [(set (match_operand:SI 0 "register_operand")
2777         (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
2778   "TARGET_HARD_FLOAT"
2779 {
2780   rtx reg1 = gen_reg_rtx (SFmode);
2781   rtx reg2 = gen_reg_rtx (SFmode);
2782   rtx reg3 = gen_reg_rtx (SImode);
2783   rtx label1 = gen_label_rtx ();
2784   rtx label2 = gen_label_rtx ();
2785   REAL_VALUE_TYPE offset;
2786
2787   real_2expN (&offset, 31);
2788
2789   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2790   do_pending_stack_adjust ();
2791
2792   emit_insn (gen_cmpsf (operands[1], reg1));
2793   emit_jump_insn (gen_bge (label1));
2794
2795   emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2796   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2797                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2798   emit_barrier ();
2799
2800   emit_label (label1);
2801   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2802   emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2803                                  (BITMASK_HIGH, SImode)));
2804
2805   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2806   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2807
2808   emit_label (label2);
2809
2810   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2811      fields, and can't be used for REG_NOTES anyway).  */
2812   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2813   DONE;
2814 })
2815
2816
2817 (define_expand "fixuns_truncsfdi2"
2818   [(set (match_operand:DI 0 "register_operand")
2819         (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
2820   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2821 {
2822   rtx reg1 = gen_reg_rtx (SFmode);
2823   rtx reg2 = gen_reg_rtx (SFmode);
2824   rtx reg3 = gen_reg_rtx (DImode);
2825   rtx label1 = gen_label_rtx ();
2826   rtx label2 = gen_label_rtx ();
2827   REAL_VALUE_TYPE offset;
2828
2829   real_2expN (&offset, 63);
2830
2831   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2832   do_pending_stack_adjust ();
2833
2834   emit_insn (gen_cmpsf (operands[1], reg1));
2835   emit_jump_insn (gen_bge (label1));
2836
2837   emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
2838   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2839                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2840   emit_barrier ();
2841
2842   emit_label (label1);
2843   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2844   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2845   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2846
2847   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
2848   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2849
2850   emit_label (label2);
2851
2852   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2853      fields, and can't be used for REG_NOTES anyway).  */
2854   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2855   DONE;
2856 })
2857 \f
2858 ;;
2859 ;;  ....................
2860 ;;
2861 ;;      DATA MOVEMENT
2862 ;;
2863 ;;  ....................
2864
2865 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
2866
2867 (define_expand "extv"
2868   [(set (match_operand 0 "register_operand")
2869         (sign_extract (match_operand:QI 1 "memory_operand")
2870                       (match_operand 2 "immediate_operand")
2871                       (match_operand 3 "immediate_operand")))]
2872   "!TARGET_MIPS16"
2873 {
2874   if (mips_expand_unaligned_load (operands[0], operands[1],
2875                                   INTVAL (operands[2]),
2876                                   INTVAL (operands[3])))
2877     DONE;
2878   else
2879     FAIL;
2880 })
2881
2882 (define_expand "extzv"
2883   [(set (match_operand 0 "register_operand")
2884         (zero_extract (match_operand 1 "nonimmediate_operand")
2885                       (match_operand 2 "immediate_operand")
2886                       (match_operand 3 "immediate_operand")))]
2887   "!TARGET_MIPS16"
2888 {
2889   if (mips_expand_unaligned_load (operands[0], operands[1],
2890                                   INTVAL (operands[2]),
2891                                   INTVAL (operands[3])))
2892     DONE;
2893   else if (mips_use_ins_ext_p (operands[1], operands[2], operands[3]))
2894     {
2895       if (GET_MODE (operands[0]) == DImode)
2896         emit_insn (gen_extzvdi (operands[0], operands[1], operands[2],
2897                                 operands[3]));
2898       else
2899         emit_insn (gen_extzvsi (operands[0], operands[1], operands[2],
2900                                 operands[3]));
2901       DONE;
2902     }
2903   else
2904     FAIL;
2905 })
2906
2907 (define_insn "extzv<mode>"
2908   [(set (match_operand:GPR 0 "register_operand" "=d")
2909         (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
2910                           (match_operand:SI 2 "immediate_operand" "I")
2911                           (match_operand:SI 3 "immediate_operand" "I")))]
2912   "mips_use_ins_ext_p (operands[1], operands[2], operands[3])"
2913   "<d>ext\t%0,%1,%3,%2"
2914   [(set_attr "type"     "arith")
2915    (set_attr "mode"     "<MODE>")])
2916
2917
2918 (define_expand "insv"
2919   [(set (zero_extract (match_operand 0 "nonimmediate_operand")
2920                       (match_operand 1 "immediate_operand")
2921                       (match_operand 2 "immediate_operand"))
2922         (match_operand 3 "reg_or_0_operand"))]
2923   "!TARGET_MIPS16"
2924 {
2925   if (mips_expand_unaligned_store (operands[0], operands[3],
2926                                    INTVAL (operands[1]),
2927                                    INTVAL (operands[2])))
2928     DONE;
2929   else if (mips_use_ins_ext_p (operands[0], operands[1], operands[2]))
2930     {
2931       if (GET_MODE (operands[0]) == DImode)
2932         emit_insn (gen_insvdi (operands[0], operands[1], operands[2],
2933                                operands[3]));
2934       else
2935         emit_insn (gen_insvsi (operands[0], operands[1], operands[2],
2936                                operands[3]));
2937       DONE;
2938    }
2939    else
2940      FAIL;
2941 })
2942
2943 (define_insn "insv<mode>"
2944   [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
2945                           (match_operand:SI 1 "immediate_operand" "I")
2946                           (match_operand:SI 2 "immediate_operand" "I"))
2947         (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
2948   "mips_use_ins_ext_p (operands[0], operands[1], operands[2])"
2949   "<d>ins\t%0,%z3,%2,%1"
2950   [(set_attr "type"     "arith")
2951    (set_attr "mode"     "<MODE>")])
2952
2953 ;; Unaligned word moves generated by the bit field patterns.
2954 ;;
2955 ;; As far as the rtl is concerned, both the left-part and right-part
2956 ;; instructions can access the whole field.  However, the real operand
2957 ;; refers to just the first or the last byte (depending on endianness).
2958 ;; We therefore use two memory operands to each instruction, one to
2959 ;; describe the rtl effect and one to use in the assembly output.
2960 ;;
2961 ;; Operands 0 and 1 are the rtl-level target and source respectively.
2962 ;; This allows us to use the standard length calculations for the "load"
2963 ;; and "store" type attributes.
2964
2965 (define_insn "mov_<load>l"
2966   [(set (match_operand:GPR 0 "register_operand" "=d")
2967         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
2968                      (match_operand:QI 2 "memory_operand" "m")]
2969                     UNSPEC_LOAD_LEFT))]
2970   "!TARGET_MIPS16"
2971   "<load>l\t%0,%2"
2972   [(set_attr "type" "load")
2973    (set_attr "mode" "<MODE>")])
2974
2975 (define_insn "mov_<load>r"
2976   [(set (match_operand:GPR 0 "register_operand" "=d")
2977         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
2978                      (match_operand:QI 2 "memory_operand" "m")
2979                      (match_operand:GPR 3 "register_operand" "0")]
2980                     UNSPEC_LOAD_RIGHT))]
2981   "!TARGET_MIPS16"
2982   "<load>r\t%0,%2"
2983   [(set_attr "type" "load")
2984    (set_attr "mode" "<MODE>")])
2985
2986 (define_insn "mov_<store>l"
2987   [(set (match_operand:BLK 0 "memory_operand" "=m")
2988         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
2989                      (match_operand:QI 2 "memory_operand" "m")]
2990                     UNSPEC_STORE_LEFT))]
2991   "!TARGET_MIPS16"
2992   "<store>l\t%z1,%2"
2993   [(set_attr "type" "store")
2994    (set_attr "mode" "<MODE>")])
2995
2996 (define_insn "mov_<store>r"
2997   [(set (match_operand:BLK 0 "memory_operand" "+m")
2998         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
2999                      (match_operand:QI 2 "memory_operand" "m")
3000                      (match_dup 0)]
3001                     UNSPEC_STORE_RIGHT))]
3002   "!TARGET_MIPS16"
3003   "<store>r\t%z1,%2"
3004   [(set_attr "type" "store")
3005    (set_attr "mode" "<MODE>")])
3006
3007 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3008 ;; The required value is:
3009 ;;
3010 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3011 ;;
3012 ;; which translates to:
3013 ;;
3014 ;;      lui     op0,%highest(op1)
3015 ;;      daddiu  op0,op0,%higher(op1)
3016 ;;      dsll    op0,op0,16
3017 ;;      daddiu  op0,op0,%hi(op1)
3018 ;;      dsll    op0,op0,16
3019 ;;
3020 ;; The split is deferred until after flow2 to allow the peephole2 below
3021 ;; to take effect.
3022 (define_insn_and_split "*lea_high64"
3023   [(set (match_operand:DI 0 "register_operand" "=d")
3024         (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3025   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3026   "#"
3027   "&& flow2_completed"
3028   [(set (match_dup 0) (high:DI (match_dup 2)))
3029    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3030    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3031    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3032    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3033 {
3034   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3035   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3036 }
3037   [(set_attr "length" "20")])
3038
3039 ;; Use a scratch register to reduce the latency of the above pattern
3040 ;; on superscalar machines.  The optimized sequence is:
3041 ;;
3042 ;;      lui     op1,%highest(op2)
3043 ;;      lui     op0,%hi(op2)
3044 ;;      daddiu  op1,op1,%higher(op2)
3045 ;;      dsll32  op1,op1,0
3046 ;;      daddu   op1,op1,op0
3047 (define_peephole2
3048   [(set (match_operand:DI 1 "register_operand")
3049         (high:DI (match_operand:DI 2 "general_symbolic_operand")))
3050    (match_scratch:DI 0 "d")]
3051   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3052   [(set (match_dup 1) (high:DI (match_dup 3)))
3053    (set (match_dup 0) (high:DI (match_dup 4)))
3054    (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
3055    (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
3056    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
3057 {
3058   operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
3059   operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
3060 })
3061
3062 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3063 ;; SYMBOL_GENERAL X will take 6 cycles.  This next pattern allows combine
3064 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3065 ;; used once.  We can then use the sequence:
3066 ;;
3067 ;;      lui     op0,%highest(op1)
3068 ;;      lui     op2,%hi(op1)
3069 ;;      daddiu  op0,op0,%higher(op1)
3070 ;;      daddiu  op2,op2,%lo(op1)
3071 ;;      dsll32  op0,op0,0
3072 ;;      daddu   op0,op0,op2
3073 ;;
3074 ;; which takes 4 cycles on most superscalar targets.
3075 (define_insn_and_split "*lea64"
3076   [(set (match_operand:DI 0 "register_operand" "=d")
3077         (match_operand:DI 1 "general_symbolic_operand" ""))
3078    (clobber (match_scratch:DI 2 "=&d"))]
3079   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3080   "#"
3081   "&& reload_completed"
3082   [(set (match_dup 0) (high:DI (match_dup 3)))
3083    (set (match_dup 2) (high:DI (match_dup 4)))
3084    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3085    (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3086    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3087    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3088 {
3089   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3090   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3091 }
3092   [(set_attr "length" "24")])
3093
3094 ;; Insns to fetch a global symbol from a big GOT.
3095
3096 (define_insn_and_split "*xgot_hi<mode>"
3097   [(set (match_operand:P 0 "register_operand" "=d")
3098         (high:P (match_operand:P 1 "global_got_operand" "")))]
3099   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3100   "#"
3101   "&& reload_completed"
3102   [(set (match_dup 0) (high:P (match_dup 2)))
3103    (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3104 {
3105   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3106   operands[3] = pic_offset_table_rtx;
3107 }
3108   [(set_attr "got" "xgot_high")
3109    (set_attr "mode" "<MODE>")])
3110
3111 (define_insn_and_split "*xgot_lo<mode>"
3112   [(set (match_operand:P 0 "register_operand" "=d")
3113         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3114                   (match_operand:P 2 "global_got_operand" "")))]
3115   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3116   "#"
3117   "&& reload_completed"
3118   [(set (match_dup 0)
3119         (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3120   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3121   [(set_attr "got" "load")
3122    (set_attr "mode" "<MODE>")])
3123
3124 ;; Insns to fetch a global symbol from a normal GOT.
3125
3126 (define_insn_and_split "*got_disp<mode>"
3127   [(set (match_operand:P 0 "register_operand" "=d")
3128         (match_operand:P 1 "global_got_operand" ""))]
3129   "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3130   "#"
3131   "&& reload_completed"
3132   [(set (match_dup 0)
3133         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3134 {
3135   operands[2] = pic_offset_table_rtx;
3136   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3137 }
3138   [(set_attr "got" "load")
3139    (set_attr "mode" "<MODE>")])
3140
3141 ;; Insns for loading the high part of a local symbol.
3142
3143 (define_insn_and_split "*got_page<mode>"
3144   [(set (match_operand:P 0 "register_operand" "=d")
3145         (high:P (match_operand:P 1 "local_got_operand" "")))]
3146   "TARGET_EXPLICIT_RELOCS"
3147   "#"
3148   "&& reload_completed"
3149   [(set (match_dup 0)
3150         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3151 {
3152   operands[2] = pic_offset_table_rtx;
3153   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3154 }
3155   [(set_attr "got" "load")
3156    (set_attr "mode" "<MODE>")])
3157
3158 ;; Lower-level instructions for loading an address from the GOT.
3159 ;; We could use MEMs, but an unspec gives more optimization
3160 ;; opportunities.
3161
3162 (define_insn "load_got<mode>"
3163   [(set (match_operand:P 0 "register_operand" "=d")
3164         (unspec:P [(match_operand:P 1 "register_operand" "d")
3165                    (match_operand:P 2 "immediate_operand" "")]
3166                   UNSPEC_LOAD_GOT))]
3167   ""
3168   "<load>\t%0,%R2(%1)"
3169   [(set_attr "type" "load")
3170    (set_attr "mode" "<MODE>")
3171    (set_attr "length" "4")])
3172
3173 ;; Instructions for adding the low 16 bits of an address to a register.
3174 ;; Operand 2 is the address: print_operand works out which relocation
3175 ;; should be applied.
3176
3177 (define_insn "*low<mode>"
3178   [(set (match_operand:P 0 "register_operand" "=d")
3179         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3180                   (match_operand:P 2 "immediate_operand" "")))]
3181   "!TARGET_MIPS16"
3182   "<d>addiu\t%0,%1,%R2"
3183   [(set_attr "type" "arith")
3184    (set_attr "mode" "<MODE>")])
3185
3186 (define_insn "*low<mode>_mips16"
3187   [(set (match_operand:P 0 "register_operand" "=d")
3188         (lo_sum:P (match_operand:P 1 "register_operand" "0")
3189                   (match_operand:P 2 "immediate_operand" "")))]
3190   "TARGET_MIPS16"
3191   "<d>addiu\t%0,%R2"
3192   [(set_attr "type" "arith")
3193    (set_attr "mode" "<MODE>")
3194    (set_attr "length" "8")])
3195
3196 ;; 64-bit integer moves
3197
3198 ;; Unlike most other insns, the move insns can't be split with
3199 ;; different predicates, because register spilling and other parts of
3200 ;; the compiler, have memoized the insn number already.
3201
3202 (define_expand "movdi"
3203   [(set (match_operand:DI 0 "")
3204         (match_operand:DI 1 ""))]
3205   ""
3206 {
3207   if (mips_legitimize_move (DImode, operands[0], operands[1]))
3208     DONE;
3209 })
3210
3211 ;; For mips16, we need a special case to handle storing $31 into
3212 ;; memory, since we don't have a constraint to match $31.  This
3213 ;; instruction can be generated by save_restore_insns.
3214
3215 (define_insn "*mov<mode>_ra"
3216   [(set (match_operand:GPR 0 "stack_operand" "=m")
3217         (reg:GPR 31))]
3218   "TARGET_MIPS16"
3219   "<store>\t$31,%0"
3220   [(set_attr "type" "store")
3221    (set_attr "mode" "<MODE>")])
3222
3223 (define_insn "*movdi_32bit"
3224   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*B*C*D,*B*C*D,*d,*m")
3225         (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
3226   "!TARGET_64BIT && !TARGET_MIPS16
3227    && (register_operand (operands[0], DImode)
3228        || reg_or_0_operand (operands[1], DImode))"
3229   { return mips_output_move (operands[0], operands[1]); }
3230   [(set_attr "type"     "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
3231    (set_attr "mode"     "DI")
3232    (set_attr "length"   "8,16,*,*,8,8,8,*,8,*")])
3233
3234 (define_insn "*movdi_32bit_mips16"
3235   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3236         (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3237   "!TARGET_64BIT && TARGET_MIPS16
3238    && (register_operand (operands[0], DImode)
3239        || register_operand (operands[1], DImode))"
3240   { return mips_output_move (operands[0], operands[1]); }
3241   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store,mfhilo")
3242    (set_attr "mode"     "DI")
3243    (set_attr "length"   "8,8,8,8,12,*,*,8")])
3244
3245 (define_insn "*movdi_64bit"
3246   [(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")
3247         (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"))]
3248   "TARGET_64BIT && !TARGET_MIPS16
3249    && (register_operand (operands[0], DImode)
3250        || reg_or_0_operand (operands[1], DImode))"
3251   { return mips_output_move (operands[0], operands[1]); }
3252   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
3253    (set_attr "mode"     "DI")
3254    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3255
3256 (define_insn "*movdi_64bit_mips16"
3257   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3258         (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3259   "TARGET_64BIT && TARGET_MIPS16
3260    && (register_operand (operands[0], DImode)
3261        || register_operand (operands[1], DImode))"
3262   { return mips_output_move (operands[0], operands[1]); }
3263   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
3264    (set_attr "mode"     "DI")
3265    (set_attr_alternative "length"
3266                 [(const_int 4)
3267                  (const_int 4)
3268                  (const_int 4)
3269                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3270                                (const_int 4)
3271                                (const_int 8))
3272                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3273                                (const_int 8)
3274                                (const_int 12))
3275                  (const_string "*")
3276                  (const_string "*")
3277                  (const_string "*")])])
3278
3279
3280 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
3281 ;; when the original load is a 4 byte instruction but the add and the
3282 ;; load are 2 2 byte instructions.
3283
3284 (define_split
3285   [(set (match_operand:DI 0 "register_operand")
3286         (mem:DI (plus:DI (match_dup 0)
3287                          (match_operand:DI 1 "const_int_operand"))))]
3288   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3289    && !TARGET_DEBUG_D_MODE
3290    && REG_P (operands[0])
3291    && M16_REG_P (REGNO (operands[0]))
3292    && GET_CODE (operands[1]) == CONST_INT
3293    && ((INTVAL (operands[1]) < 0
3294         && INTVAL (operands[1]) >= -0x10)
3295        || (INTVAL (operands[1]) >= 32 * 8
3296            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3297        || (INTVAL (operands[1]) >= 0
3298            && INTVAL (operands[1]) < 32 * 8
3299            && (INTVAL (operands[1]) & 7) != 0))"
3300   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3301    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3302 {
3303   HOST_WIDE_INT val = INTVAL (operands[1]);
3304
3305   if (val < 0)
3306     operands[2] = const0_rtx;
3307   else if (val >= 32 * 8)
3308     {
3309       int off = val & 7;
3310
3311       operands[1] = GEN_INT (0x8 + off);
3312       operands[2] = GEN_INT (val - off - 0x8);
3313     }
3314   else
3315     {
3316       int off = val & 7;
3317
3318       operands[1] = GEN_INT (off);
3319       operands[2] = GEN_INT (val - off);
3320     }
3321 })
3322
3323 ;; 32-bit Integer moves
3324
3325 ;; Unlike most other insns, the move insns can't be split with
3326 ;; different predicates, because register spilling and other parts of
3327 ;; the compiler, have memoized the insn number already.
3328
3329 (define_expand "movsi"
3330   [(set (match_operand:SI 0 "")
3331         (match_operand:SI 1 ""))]
3332   ""
3333 {
3334   if (mips_legitimize_move (SImode, operands[0], operands[1]))
3335     DONE;
3336 })
3337
3338 ;; The difference between these two is whether or not ints are allowed
3339 ;; in FP registers (off by default, use -mdebugh to enable).
3340
3341 (define_insn "*movsi_internal"
3342   [(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")
3343         (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"))]
3344   "!TARGET_MIPS16
3345    && (register_operand (operands[0], SImode)
3346        || reg_or_0_operand (operands[1], SImode))"
3347   { return mips_output_move (operands[0], operands[1]); }
3348   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,mfhilo,xfer,load,xfer,store")
3349    (set_attr "mode"     "SI")
3350    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")])
3351
3352 (define_insn "*movsi_mips16"
3353   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3354         (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3355   "TARGET_MIPS16
3356    && (register_operand (operands[0], SImode)
3357        || register_operand (operands[1], SImode))"
3358   { return mips_output_move (operands[0], operands[1]); }
3359   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
3360    (set_attr "mode"     "SI")
3361    (set_attr_alternative "length"
3362                 [(const_int 4)
3363                  (const_int 4)
3364                  (const_int 4)
3365                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3366                                (const_int 4)
3367                                (const_int 8))
3368                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3369                                (const_int 8)
3370                                (const_int 12))
3371                  (const_string "*")
3372                  (const_string "*")
3373                  (const_string "*")])])
3374
3375 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
3376 ;; when the original load is a 4 byte instruction but the add and the
3377 ;; load are 2 2 byte instructions.
3378
3379 (define_split
3380   [(set (match_operand:SI 0 "register_operand")
3381         (mem:SI (plus:SI (match_dup 0)
3382                          (match_operand:SI 1 "const_int_operand"))))]
3383   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3384    && REG_P (operands[0])
3385    && M16_REG_P (REGNO (operands[0]))
3386    && GET_CODE (operands[1]) == CONST_INT
3387    && ((INTVAL (operands[1]) < 0
3388         && INTVAL (operands[1]) >= -0x80)
3389        || (INTVAL (operands[1]) >= 32 * 4
3390            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3391        || (INTVAL (operands[1]) >= 0
3392            && INTVAL (operands[1]) < 32 * 4
3393            && (INTVAL (operands[1]) & 3) != 0))"
3394   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3395    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3396 {
3397   HOST_WIDE_INT val = INTVAL (operands[1]);
3398
3399   if (val < 0)