OSDN Git Service

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