OSDN Git Service

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