OSDN Git Service

Canonicalize mips nmadd/nmsub patterns.
[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
1908    && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1909   "nmadd.d\t%0,%3,%1,%2"
1910   [(set_attr "type"     "fmadd")
1911    (set_attr "mode"     "DF")])
1912
1913 (define_insn ""
1914   [(set (match_operand:DF 0 "register_operand" "=f")
1915         (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
1916                                    (match_operand:DF 2 "register_operand" "f"))
1917                   (match_operand:DF 3 "register_operand" "f")))]
1918   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1919    && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1920   "nmadd.d\t%0,%3,%1,%2"
1921   [(set_attr "type"     "fmadd")
1922    (set_attr "mode"     "DF")])
1923
1924 (define_insn ""
1925   [(set (match_operand:SF 0 "register_operand" "=f")
1926         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1927                                   (match_operand:SF 2 "register_operand" "f"))
1928                          (match_operand:SF 3 "register_operand" "f"))))]
1929   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1930    && HONOR_SIGNED_ZEROS (SFmode)"
1931   "nmadd.s\t%0,%3,%1,%2"
1932   [(set_attr "type"     "fmadd")
1933    (set_attr "mode"     "SF")])
1934
1935 (define_insn ""
1936   [(set (match_operand:SF 0 "register_operand" "=f")
1937         (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
1938                            (match_operand:SF 2 "register_operand" "f"))
1939                   (match_operand:SF 3 "register_operand" "f")))]
1940   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1941    && !HONOR_SIGNED_ZEROS (SFmode)"
1942   "nmadd.s\t%0,%3,%1,%2"
1943   [(set_attr "type"     "fmadd")
1944    (set_attr "mode"     "SF")])
1945
1946 (define_insn ""
1947   [(set (match_operand:DF 0 "register_operand" "=f")
1948         (neg:DF (minus:DF (mult:DF (match_operand:DF 2 "register_operand" "f")
1949                                    (match_operand:DF 3 "register_operand" "f"))
1950                           (match_operand:DF 1 "register_operand" "f"))))]
1951   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1952    && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1953   "nmsub.d\t%0,%1,%2,%3"
1954   [(set_attr "type"     "fmadd")
1955    (set_attr "mode"     "DF")])
1956
1957 (define_insn ""
1958   [(set (match_operand:DF 0 "register_operand" "=f")
1959         (minus:DF (match_operand:DF 1 "register_operand" "f")
1960                   (mult:DF (match_operand:DF 2 "register_operand" "f")
1961                            (match_operand:DF 3 "register_operand" "f"))))]
1962   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1963    && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1964   "nmsub.d\t%0,%1,%2,%3"
1965   [(set_attr "type"     "fmadd")
1966    (set_attr "mode"     "DF")])
1967
1968 (define_insn ""
1969   [(set (match_operand:SF 0 "register_operand" "=f")
1970         (neg:SF (minus:SF (mult:SF (match_operand:SF 2 "register_operand" "f")
1971                                    (match_operand:SF 3 "register_operand" "f"))
1972                           (match_operand:SF 1 "register_operand" "f"))))]
1973   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1974    && HONOR_SIGNED_ZEROS (SFmode)"
1975   "nmsub.s\t%0,%1,%2,%3"
1976   [(set_attr "type"     "fmadd")
1977    (set_attr "mode"     "SF")])
1978
1979 (define_insn ""
1980   [(set (match_operand:SF 0 "register_operand" "=f")
1981         (minus:SF (match_operand:SF 1 "register_operand" "f")
1982                   (mult:SF (match_operand:SF 2 "register_operand" "f")
1983                            (match_operand:SF 3 "register_operand" "f"))))]
1984   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1985    && !HONOR_SIGNED_ZEROS (SFmode)"
1986   "nmsub.s\t%0,%1,%2,%3"
1987   [(set_attr "type"     "fmadd")
1988    (set_attr "mode"     "SF")])
1989 \f
1990 ;;
1991 ;;  ....................
1992 ;;
1993 ;;      DIVISION and REMAINDER
1994 ;;
1995 ;;  ....................
1996 ;;
1997
1998 (define_expand "divdf3"
1999   [(set (match_operand:DF 0 "register_operand")
2000         (div:DF (match_operand:DF 1 "reg_or_1_operand")
2001                 (match_operand:DF 2 "register_operand")))]
2002   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2003 {
2004   if (const_1_operand (operands[1], DFmode))
2005     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2006       operands[1] = force_reg (DFmode, operands[1]);
2007 })
2008
2009 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
2010 ;;
2011 ;; If an mfc1 or dmfc1 happens to access the floating point register
2012 ;; file at the same time a long latency operation (div, sqrt, recip,
2013 ;; sqrt) iterates an intermediate result back through the floating
2014 ;; point register file bypass, then instead returning the correct
2015 ;; register value the mfc1 or dmfc1 operation returns the intermediate
2016 ;; result of the long latency operation.
2017 ;;
2018 ;; The workaround is to insert an unconditional 'mov' from/to the
2019 ;; long latency op destination register.
2020
2021 (define_insn "*divdf3"
2022   [(set (match_operand:DF 0 "register_operand" "=f")
2023         (div:DF (match_operand:DF 1 "register_operand" "f")
2024                 (match_operand:DF 2 "register_operand" "f")))]
2025   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2026 {
2027   if (TARGET_FIX_SB1)
2028     return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
2029   else
2030     return "div.d\t%0,%1,%2";
2031 }
2032   [(set_attr "type"     "fdiv")
2033    (set_attr "mode"     "DF")
2034    (set (attr "length")
2035         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2036                       (const_int 8)
2037                       (const_int 4)))])
2038
2039
2040 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
2041 ;;
2042 ;; In certain cases, div.s and div.ps may have a rounding error
2043 ;; and/or wrong inexact flag.
2044 ;;
2045 ;; Therefore, we only allow div.s if not working around SB-1 rev2
2046 ;; errata, or if working around those errata and a slight loss of
2047 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
2048 (define_expand "divsf3"
2049   [(set (match_operand:SF 0 "register_operand")
2050         (div:SF (match_operand:SF 1 "reg_or_1_operand")
2051                 (match_operand:SF 2 "register_operand")))]
2052   "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2053 {
2054   if (const_1_operand (operands[1], SFmode))
2055     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2056       operands[1] = force_reg (SFmode, operands[1]);
2057 })
2058
2059 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2060 ;; "divdf3" comment for details).
2061 ;;
2062 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
2063 ;; "divsf3" comment for details).
2064 (define_insn "*divsf3"
2065   [(set (match_operand:SF 0 "register_operand" "=f")
2066         (div:SF (match_operand:SF 1 "register_operand" "f")
2067                 (match_operand:SF 2 "register_operand" "f")))]
2068   "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2069 {
2070   if (TARGET_FIX_SB1)
2071     return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
2072   else
2073     return "div.s\t%0,%1,%2";
2074 }
2075   [(set_attr "type"     "fdiv")
2076    (set_attr "mode"     "SF")
2077    (set (attr "length")
2078         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2079                       (const_int 8)
2080                       (const_int 4)))])
2081
2082 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2083 ;; "divdf3" comment for details).
2084 (define_insn ""
2085   [(set (match_operand:DF 0 "register_operand" "=f")
2086         (div:DF (match_operand:DF 1 "const_1_operand" "")
2087                 (match_operand:DF 2 "register_operand" "f")))]
2088   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2089 {
2090   if (TARGET_FIX_SB1)
2091     return "recip.d\t%0,%2\;mov.d\t%0,%0";
2092   else
2093     return "recip.d\t%0,%2";
2094 }
2095   [(set_attr "type"     "fdiv")
2096    (set_attr "mode"     "DF")
2097    (set (attr "length")
2098         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2099                       (const_int 8)
2100                       (const_int 4)))])
2101
2102 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2103 ;; "divdf3" comment for details).
2104 (define_insn ""
2105   [(set (match_operand:SF 0 "register_operand" "=f")
2106         (div:SF (match_operand:SF 1 "const_1_operand" "")
2107                 (match_operand:SF 2 "register_operand" "f")))]
2108   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2109 {
2110   if (TARGET_FIX_SB1)
2111     return "recip.s\t%0,%2\;mov.s\t%0,%0";
2112   else
2113     return "recip.s\t%0,%2";
2114 }
2115   [(set_attr "type"     "fdiv")
2116    (set_attr "mode"     "SF")
2117    (set (attr "length")
2118         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2119                       (const_int 8)
2120                       (const_int 4)))])
2121
2122 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2123 ;; with negative operands.  We use special libgcc functions instead.
2124 (define_insn "divmodsi4"
2125   [(set (match_operand:SI 0 "register_operand" "=l")
2126         (div:SI (match_operand:SI 1 "register_operand" "d")
2127                 (match_operand:SI 2 "register_operand" "d")))
2128    (set (match_operand:SI 3 "register_operand" "=h")
2129         (mod:SI (match_dup 1)
2130                 (match_dup 2)))]
2131   "!TARGET_FIX_VR4120"
2132   { return mips_output_division ("div\t$0,%1,%2", operands); }
2133   [(set_attr "type"     "idiv")
2134    (set_attr "mode"     "SI")])
2135
2136 (define_insn "divmoddi4"
2137   [(set (match_operand:DI 0 "register_operand" "=l")
2138         (div:DI (match_operand:DI 1 "register_operand" "d")
2139                 (match_operand:DI 2 "register_operand" "d")))
2140    (set (match_operand:DI 3 "register_operand" "=h")
2141         (mod:DI (match_dup 1)
2142                 (match_dup 2)))]
2143   "TARGET_64BIT && !TARGET_FIX_VR4120"
2144   { return mips_output_division ("ddiv\t$0,%1,%2", operands); }
2145   [(set_attr "type"     "idiv")
2146    (set_attr "mode"     "DI")])
2147
2148 (define_insn "udivmodsi4"
2149   [(set (match_operand:SI 0 "register_operand" "=l")
2150         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2151                  (match_operand:SI 2 "register_operand" "d")))
2152    (set (match_operand:SI 3 "register_operand" "=h")
2153         (umod:SI (match_dup 1)
2154                  (match_dup 2)))]
2155   ""
2156   { return mips_output_division ("divu\t$0,%1,%2", operands); }
2157   [(set_attr "type"     "idiv")
2158    (set_attr "mode"     "SI")])
2159
2160 (define_insn "udivmoddi4"
2161   [(set (match_operand:DI 0 "register_operand" "=l")
2162         (udiv:DI (match_operand:DI 1 "register_operand" "d")
2163                  (match_operand:DI 2 "register_operand" "d")))
2164    (set (match_operand:DI 3 "register_operand" "=h")
2165         (umod:DI (match_dup 1)
2166                  (match_dup 2)))]
2167   "TARGET_64BIT"
2168   { return mips_output_division ("ddivu\t$0,%1,%2", operands); }
2169   [(set_attr "type"     "idiv")
2170    (set_attr "mode"     "DI")])
2171 \f
2172 ;;
2173 ;;  ....................
2174 ;;
2175 ;;      SQUARE ROOT
2176 ;;
2177 ;;  ....................
2178
2179 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2180 ;; "divdf3" comment for details).
2181 (define_insn "sqrtdf2"
2182   [(set (match_operand:DF 0 "register_operand" "=f")
2183         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2184   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2185 {
2186   if (TARGET_FIX_SB1)
2187     return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
2188   else
2189     return "sqrt.d\t%0,%1";
2190 }
2191   [(set_attr "type"     "fsqrt")
2192    (set_attr "mode"     "DF")
2193    (set (attr "length")
2194         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2195                       (const_int 8)
2196                       (const_int 4)))])
2197
2198 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2199 ;; "divdf3" comment for details).
2200 (define_insn "sqrtsf2"
2201   [(set (match_operand:SF 0 "register_operand" "=f")
2202         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2203   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2204 {
2205   if (TARGET_FIX_SB1)
2206     return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
2207   else
2208     return "sqrt.s\t%0,%1";
2209 }
2210   [(set_attr "type"     "fsqrt")
2211    (set_attr "mode"     "SF")
2212    (set (attr "length")
2213         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2214                       (const_int 8)
2215                       (const_int 4)))])
2216
2217 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2218 ;; "divdf3" comment for details).
2219 (define_insn ""
2220   [(set (match_operand:DF 0 "register_operand" "=f")
2221         (div:DF (match_operand:DF 1 "const_1_operand" "")
2222                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2223   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2224 {
2225   if (TARGET_FIX_SB1)
2226     return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2227   else
2228     return "rsqrt.d\t%0,%2";
2229 }
2230   [(set_attr "type"     "frsqrt")
2231    (set_attr "mode"     "DF")
2232    (set (attr "length")
2233         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2234                       (const_int 8)
2235                       (const_int 4)))])
2236
2237 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2238 ;; "divdf3" comment for details).
2239 (define_insn ""
2240   [(set (match_operand:SF 0 "register_operand" "=f")
2241         (div:SF (match_operand:SF 1 "const_1_operand" "")
2242                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2243   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2244 {
2245   if (TARGET_FIX_SB1)
2246     return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2247   else
2248     return "rsqrt.s\t%0,%2";
2249 }
2250   [(set_attr "type"     "frsqrt")
2251    (set_attr "mode"     "SF")
2252    (set (attr "length")
2253         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2254                       (const_int 8)
2255                       (const_int 4)))])
2256
2257 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2258 ;; "divdf3" comment for details).
2259 (define_insn ""
2260   [(set (match_operand:DF 0 "register_operand" "=f")
2261         (sqrt:DF (div:DF (match_operand:DF 1 "const_1_operand" "")
2262                          (match_operand:DF 2 "register_operand" "f"))))]
2263   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2264 {
2265   if (TARGET_FIX_SB1)
2266     return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2267   else
2268     return "rsqrt.d\t%0,%2";
2269 }
2270   [(set_attr "type"     "frsqrt")
2271    (set_attr "mode"     "DF")
2272    (set (attr "length")
2273         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2274                       (const_int 8)
2275                       (const_int 4)))])
2276
2277 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2278 ;; "divdf3" comment for details).
2279 (define_insn ""
2280   [(set (match_operand:SF 0 "register_operand" "=f")
2281         (sqrt:SF (div:SF (match_operand:SF 1 "const_1_operand" "")
2282                          (match_operand:SF 2 "register_operand" "f"))))]
2283   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2284 {
2285   if (TARGET_FIX_SB1)
2286     return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2287   else
2288     return "rsqrt.s\t%0,%2";
2289 }
2290   [(set_attr "type"     "frsqrt")
2291    (set_attr "mode"     "SF")
2292    (set (attr "length")
2293         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2294                       (const_int 8)
2295                       (const_int 4)))])
2296 \f
2297 ;;
2298 ;;  ....................
2299 ;;
2300 ;;      ABSOLUTE VALUE
2301 ;;
2302 ;;  ....................
2303
2304 ;; Do not use the integer abs macro instruction, since that signals an
2305 ;; exception on -2147483648 (sigh).
2306
2307 (define_insn "abssi2"
2308   [(set (match_operand:SI 0 "register_operand" "=d")
2309         (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2310   "!TARGET_MIPS16"
2311 {
2312   operands[2] = const0_rtx;
2313
2314   if (REGNO (operands[0]) == REGNO (operands[1]))
2315     {
2316       if (GENERATE_BRANCHLIKELY)
2317         return "%(bltzl\t%1,1f\;subu\t%0,%z2,%0\n%~1:%)";
2318       else
2319         return "bgez\t%1,1f%#\;subu\t%0,%z2,%0\n%~1:";
2320     }
2321   else
2322     return "%(bgez\t%1,1f\;move\t%0,%1\;subu\t%0,%z2,%0\n%~1:%)";
2323 }
2324   [(set_attr "type"     "multi")
2325    (set_attr "mode"     "SI")
2326    (set_attr "length"   "12")])
2327
2328 (define_insn "absdi2"
2329   [(set (match_operand:DI 0 "register_operand" "=d")
2330         (abs:DI (match_operand:DI 1 "register_operand" "d")))]
2331   "TARGET_64BIT && !TARGET_MIPS16"
2332 {
2333   unsigned int regno1;
2334   operands[2] = const0_rtx;
2335
2336   if (GET_CODE (operands[1]) == REG)
2337     regno1 = REGNO (operands[1]);
2338   else
2339     regno1 = REGNO (XEXP (operands[1], 0));
2340
2341   if (REGNO (operands[0]) == regno1)
2342     return "%(bltzl\t%1,1f\;dsubu\t%0,%z2,%0\n%~1:%)";
2343   else
2344     return "%(bgez\t%1,1f\;move\t%0,%1\;dsubu\t%0,%z2,%0\n%~1:%)";
2345 }
2346   [(set_attr "type"     "multi")
2347    (set_attr "mode"     "DI")
2348    (set_attr "length"   "12")])
2349
2350 (define_insn "absdf2"
2351   [(set (match_operand:DF 0 "register_operand" "=f")
2352         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2353   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2354   "abs.d\t%0,%1"
2355   [(set_attr "type"     "fabs")
2356    (set_attr "mode"     "DF")])
2357
2358 (define_insn "abssf2"
2359   [(set (match_operand:SF 0 "register_operand" "=f")
2360         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2361   "TARGET_HARD_FLOAT"
2362   "abs.s\t%0,%1"
2363   [(set_attr "type"     "fabs")
2364    (set_attr "mode"     "SF")])
2365 \f
2366 ;;
2367 ;;  ....................
2368 ;;
2369 ;;      FIND FIRST BIT INSTRUCTION
2370 ;;
2371 ;;  ....................
2372 ;;
2373
2374 (define_insn "ffssi2"
2375   [(set (match_operand:SI 0 "register_operand" "=&d")
2376         (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2377    (clobber (match_scratch:SI 2 "=&d"))
2378    (clobber (match_scratch:SI 3 "=&d"))]
2379   "!TARGET_MIPS16"
2380 {
2381   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2382     return "%(\
2383 move\t%0,%.\;\
2384 beq\t%1,%.,2f\n\
2385 %~1:\tand\t%2,%1,0x0001\;\
2386 addu\t%0,%0,1\;\
2387 beq\t%2,%.,1b\;\
2388 srl\t%1,%1,1\n\
2389 %~2:%)";
2390
2391   return "%(\
2392 move\t%0,%.\;\
2393 move\t%3,%1\;\
2394 beq\t%3,%.,2f\n\
2395 %~1:\tand\t%2,%3,0x0001\;\
2396 addu\t%0,%0,1\;\
2397 beq\t%2,%.,1b\;\
2398 srl\t%3,%3,1\n\
2399 %~2:%)";
2400 }
2401   [(set_attr "type"     "multi")
2402    (set_attr "mode"     "SI")
2403    (set_attr "length"   "28")])
2404
2405 (define_insn "ffsdi2"
2406   [(set (match_operand:DI 0 "register_operand" "=&d")
2407         (ffs:DI (match_operand:DI 1 "register_operand" "d")))
2408    (clobber (match_scratch:DI 2 "=&d"))
2409    (clobber (match_scratch:DI 3 "=&d"))]
2410   "TARGET_64BIT && !TARGET_MIPS16"
2411 {
2412   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2413     return "%(\
2414 move\t%0,%.\;\
2415 beq\t%1,%.,2f\n\
2416 %~1:\tand\t%2,%1,0x0001\;\
2417 daddu\t%0,%0,1\;\
2418 beq\t%2,%.,1b\;\
2419 dsrl\t%1,%1,1\n\
2420 %~2:%)";
2421
2422   return "%(\
2423 move\t%0,%.\;\
2424 move\t%3,%1\;\
2425 beq\t%3,%.,2f\n\
2426 %~1:\tand\t%2,%3,0x0001\;\
2427 daddu\t%0,%0,1\;\
2428 beq\t%2,%.,1b\;\
2429 dsrl\t%3,%3,1\n\
2430 %~2:%)";
2431 }
2432   [(set_attr "type"     "multi")
2433    (set_attr "mode"     "DI")
2434    (set_attr "length"   "28")])
2435 \f
2436 ;;
2437 ;;  ...................
2438 ;;
2439 ;;  Count leading zeroes.
2440 ;;
2441 ;;  ...................
2442 ;;
2443
2444 (define_insn "clzsi2"
2445   [(set (match_operand:SI 0 "register_operand" "=d")
2446         (clz:SI (match_operand:SI 1 "register_operand" "d")))]
2447   "ISA_HAS_CLZ_CLO"
2448   "clz\t%0,%1"
2449   [(set_attr "type" "clz")
2450    (set_attr "mode" "SI")])
2451
2452 (define_insn "clzdi2"
2453   [(set (match_operand:DI 0 "register_operand" "=d")
2454         (clz:DI (match_operand:DI 1 "register_operand" "d")))]
2455   "ISA_HAS_DCLZ_DCLO"
2456   "dclz\t%0,%1"
2457   [(set_attr "type" "clz")
2458    (set_attr "mode" "DI")])
2459 \f
2460 ;;
2461 ;;  ....................
2462 ;;
2463 ;;      NEGATION and ONE'S COMPLEMENT
2464 ;;
2465 ;;  ....................
2466
2467 (define_insn "negsi2"
2468   [(set (match_operand:SI 0 "register_operand" "=d")
2469         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2470   ""
2471 {
2472   if (TARGET_MIPS16)
2473     return "neg\t%0,%1";
2474   else
2475     return "subu\t%0,%.,%1";
2476 }
2477   [(set_attr "type"     "arith")
2478    (set_attr "mode"     "SI")])
2479
2480 (define_insn "negdi2"
2481   [(set (match_operand:DI 0 "register_operand" "=d")
2482         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2483   "TARGET_64BIT && !TARGET_MIPS16"
2484   "dsubu\t%0,%.,%1"
2485   [(set_attr "type"     "arith")
2486    (set_attr "mode"     "DI")])
2487
2488 (define_insn "negdf2"
2489   [(set (match_operand:DF 0 "register_operand" "=f")
2490         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2491   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2492   "neg.d\t%0,%1"
2493   [(set_attr "type"     "fneg")
2494    (set_attr "mode"     "DF")])
2495
2496 (define_insn "negsf2"
2497   [(set (match_operand:SF 0 "register_operand" "=f")
2498         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2499   "TARGET_HARD_FLOAT"
2500   "neg.s\t%0,%1"
2501   [(set_attr "type"     "fneg")
2502    (set_attr "mode"     "SF")])
2503
2504 (define_insn "one_cmplsi2"
2505   [(set (match_operand:SI 0 "register_operand" "=d")
2506         (not:SI (match_operand:SI 1 "register_operand" "d")))]
2507   ""
2508 {
2509   if (TARGET_MIPS16)
2510     return "not\t%0,%1";
2511   else
2512     return "nor\t%0,%.,%1";
2513 }
2514   [(set_attr "type"     "arith")
2515    (set_attr "mode"     "SI")])
2516
2517 (define_insn "one_cmpldi2"
2518   [(set (match_operand:DI 0 "register_operand" "=d")
2519         (not:DI (match_operand:DI 1 "register_operand" "d")))]
2520   "TARGET_64BIT"
2521 {
2522   if (TARGET_MIPS16)
2523     return "not\t%0,%1";
2524   else
2525     return "nor\t%0,%.,%1";
2526 }
2527   [(set_attr "type"     "arith")
2528    (set_attr "mode"     "DI")])
2529 \f
2530 ;;
2531 ;;  ....................
2532 ;;
2533 ;;      LOGICAL
2534 ;;
2535 ;;  ....................
2536 ;;
2537
2538 ;; Many of these instructions use trivial define_expands, because we
2539 ;; want to use a different set of constraints when TARGET_MIPS16.
2540
2541 (define_expand "andsi3"
2542   [(set (match_operand:SI 0 "register_operand")
2543         (and:SI (match_operand:SI 1 "uns_arith_operand")
2544                 (match_operand:SI 2 "uns_arith_operand")))]
2545   ""
2546 {
2547   if (TARGET_MIPS16)
2548     {
2549       operands[1] = force_reg (SImode, operands[1]);
2550       operands[2] = force_reg (SImode, operands[2]);
2551     }
2552 })
2553
2554 (define_insn ""
2555   [(set (match_operand:SI 0 "register_operand" "=d,d")
2556         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2557                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2558   "!TARGET_MIPS16"
2559   "@
2560    and\t%0,%1,%2
2561    andi\t%0,%1,%x2"
2562   [(set_attr "type"     "arith")
2563    (set_attr "mode"     "SI")])
2564
2565 (define_insn ""
2566   [(set (match_operand:SI 0 "register_operand" "=d")
2567         (and:SI (match_operand:SI 1 "register_operand" "%0")
2568                 (match_operand:SI 2 "register_operand" "d")))]
2569   "TARGET_MIPS16"
2570   "and\t%0,%2"
2571   [(set_attr "type"     "arith")
2572    (set_attr "mode"     "SI")])
2573
2574 (define_expand "anddi3"
2575   [(set (match_operand:DI 0 "register_operand")
2576         (and:DI (match_operand:DI 1 "register_operand")
2577                 (match_operand:DI 2 "uns_arith_operand")))]
2578   "TARGET_64BIT"
2579 {
2580   if (TARGET_MIPS16)
2581     {
2582       operands[1] = force_reg (DImode, operands[1]);
2583       operands[2] = force_reg (DImode, operands[2]);
2584     }
2585 })
2586
2587 (define_insn ""
2588   [(set (match_operand:DI 0 "register_operand" "=d,d")
2589         (and:DI (match_operand:DI 1 "register_operand" "d,d")
2590                 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2591   "TARGET_64BIT && !TARGET_MIPS16"
2592   "@
2593    and\t%0,%1,%2
2594    andi\t%0,%1,%x2"
2595   [(set_attr "type"     "arith")
2596    (set_attr "mode"     "DI")])
2597
2598 (define_insn ""
2599   [(set (match_operand:DI 0 "register_operand" "=d")
2600         (and:DI (match_operand:DI 1 "register_operand" "0")
2601                 (match_operand:DI 2 "register_operand" "d")))]
2602   "TARGET_64BIT && TARGET_MIPS16"
2603   "and\t%0,%2"
2604   [(set_attr "type"     "arith")
2605    (set_attr "mode"     "DI")])
2606
2607 (define_expand "iorsi3"
2608   [(set (match_operand:SI 0 "register_operand")
2609         (ior:SI (match_operand:SI 1 "uns_arith_operand")
2610                 (match_operand:SI 2 "uns_arith_operand")))]
2611   ""
2612 {
2613   if (TARGET_MIPS16)
2614     {
2615       operands[1] = force_reg (SImode, operands[1]);
2616       operands[2] = force_reg (SImode, operands[2]);
2617     }
2618 })
2619
2620 (define_insn ""
2621   [(set (match_operand:SI 0 "register_operand" "=d,d")
2622         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2623                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2624   "!TARGET_MIPS16"
2625   "@
2626    or\t%0,%1,%2
2627    ori\t%0,%1,%x2"
2628   [(set_attr "type"     "arith")
2629    (set_attr "mode"     "SI")])
2630
2631 (define_insn ""
2632   [(set (match_operand:SI 0 "register_operand" "=d")
2633         (ior:SI (match_operand:SI 1 "register_operand" "%0")
2634                 (match_operand:SI 2 "register_operand" "d")))]
2635   "TARGET_MIPS16"
2636   "or\t%0,%2"
2637   [(set_attr "type"     "arith")
2638    (set_attr "mode"     "SI")])
2639
2640 (define_expand "iordi3"
2641   [(set (match_operand:DI 0 "register_operand")
2642         (ior:DI (match_operand:DI 1 "register_operand")
2643                 (match_operand:DI 2 "uns_arith_operand")))]
2644   "TARGET_64BIT"
2645 {
2646   if (TARGET_MIPS16)
2647     {
2648       operands[1] = force_reg (DImode, operands[1]);
2649       operands[2] = force_reg (DImode, operands[2]);
2650     }
2651 })
2652
2653 (define_insn ""
2654   [(set (match_operand:DI 0 "register_operand" "=d,d")
2655         (ior:DI (match_operand:DI 1 "register_operand" "d,d")
2656                 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2657   "TARGET_64BIT && !TARGET_MIPS16"
2658   "@
2659    or\t%0,%1,%2
2660    ori\t%0,%1,%x2"
2661   [(set_attr "type"     "arith")
2662    (set_attr "mode"     "DI")])
2663
2664 (define_insn ""
2665   [(set (match_operand:DI 0 "register_operand" "=d")
2666         (ior:DI (match_operand:DI 1 "register_operand" "0")
2667                 (match_operand:DI 2 "register_operand" "d")))]
2668   "TARGET_64BIT && TARGET_MIPS16"
2669   "or\t%0,%2"
2670   [(set_attr "type"     "arith")
2671    (set_attr "mode"     "DI")])
2672
2673 (define_expand "xorsi3"
2674   [(set (match_operand:SI 0 "register_operand")
2675         (xor:SI (match_operand:SI 1 "uns_arith_operand")
2676                 (match_operand:SI 2 "uns_arith_operand")))]
2677   ""
2678   "")
2679
2680 (define_insn ""
2681   [(set (match_operand:SI 0 "register_operand" "=d,d")
2682         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2683                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2684   "!TARGET_MIPS16"
2685   "@
2686    xor\t%0,%1,%2
2687    xori\t%0,%1,%x2"
2688   [(set_attr "type"     "arith")
2689    (set_attr "mode"     "SI")])
2690
2691 (define_insn ""
2692   [(set (match_operand:SI 0 "register_operand" "=d,t,t")
2693         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
2694                 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
2695   "TARGET_MIPS16"
2696   "@
2697    xor\t%0,%2
2698    cmpi\t%1,%2
2699    cmp\t%1,%2"
2700   [(set_attr "type"     "arith")
2701    (set_attr "mode"     "SI")
2702    (set_attr_alternative "length"
2703                 [(const_int 4)
2704                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2705                                (const_int 4)
2706                                (const_int 8))
2707                  (const_int 4)])])
2708
2709 (define_expand "xordi3"
2710   [(set (match_operand:DI 0 "register_operand")
2711         (xor:DI (match_operand:DI 1 "register_operand")
2712                 (match_operand:DI 2 "uns_arith_operand")))]
2713   "TARGET_64BIT"
2714 {
2715   if (TARGET_MIPS16)
2716     {
2717       operands[1] = force_reg (DImode, operands[1]);
2718       operands[2] = force_reg (DImode, operands[2]);
2719     }
2720 })
2721
2722 (define_insn ""
2723   [(set (match_operand:DI 0 "register_operand" "=d,d")
2724         (xor:DI (match_operand:DI 1 "register_operand" "d,d")
2725                 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2726   "TARGET_64BIT && !TARGET_MIPS16"
2727   "@
2728    xor\t%0,%1,%2
2729    xori\t%0,%1,%x2"
2730   [(set_attr "type"     "arith")
2731    (set_attr "mode"     "DI")])
2732
2733 (define_insn ""
2734   [(set (match_operand:DI 0 "register_operand" "=d,t,t")
2735         (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
2736                 (match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
2737   "TARGET_64BIT && TARGET_MIPS16"
2738   "@
2739    xor\t%0,%2
2740    cmpi\t%1,%2
2741    cmp\t%1,%2"
2742   [(set_attr "type"     "arith")
2743    (set_attr "mode"     "DI")
2744    (set_attr_alternative "length"
2745                 [(const_int 4)
2746                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2747                                (const_int 4)
2748                                (const_int 8))
2749                  (const_int 4)])])
2750
2751 (define_insn "*norsi3"
2752   [(set (match_operand:SI 0 "register_operand" "=d")
2753         (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
2754                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
2755   "!TARGET_MIPS16"
2756   "nor\t%0,%z1,%z2"
2757   [(set_attr "type"     "arith")
2758    (set_attr "mode"     "SI")])
2759
2760 (define_insn "*nordi3"
2761   [(set (match_operand:DI 0 "register_operand" "=d")
2762         (and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
2763                 (not:DI (match_operand:DI 2 "register_operand" "d"))))]
2764   "TARGET_64BIT && !TARGET_MIPS16"
2765   "nor\t%0,%z1,%z2"
2766   [(set_attr "type"     "arith")
2767    (set_attr "mode"     "DI")])
2768 \f
2769 ;;
2770 ;;  ....................
2771 ;;
2772 ;;      TRUNCATION
2773 ;;
2774 ;;  ....................
2775
2776
2777
2778 (define_insn "truncdfsf2"
2779   [(set (match_operand:SF 0 "register_operand" "=f")
2780         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2781   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2782   "cvt.s.d\t%0,%1"
2783   [(set_attr "type"     "fcvt")
2784    (set_attr "mode"     "SF")])
2785
2786 ;; Integer truncation patterns.  Truncating SImode values to smaller
2787 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
2788 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2789 ;; need to make sure that the lower 32 bits are properly sign-extended
2790 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2791 ;; smaller than SImode is equivalent to two separate truncations:
2792 ;;
2793 ;;                        A       B
2794 ;;    DI ---> HI  ==  DI ---> SI ---> HI
2795 ;;    DI ---> QI  ==  DI ---> SI ---> QI
2796 ;;
2797 ;; Step A needs a real instruction but step B does not.
2798
2799 (define_insn "truncdisi2"
2800   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2801         (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2802   "TARGET_64BIT"
2803   "@
2804     sll\t%0,%1,0
2805     sw\t%1,%0"
2806   [(set_attr "type" "shift,store")
2807    (set_attr "mode" "SI")
2808    (set_attr "extended_mips16" "yes,*")])
2809
2810 (define_insn "truncdihi2"
2811   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2812         (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2813   "TARGET_64BIT"
2814   "@
2815     sll\t%0,%1,0
2816     sh\t%1,%0"
2817   [(set_attr "type" "shift,store")
2818    (set_attr "mode" "SI")
2819    (set_attr "extended_mips16" "yes,*")])
2820
2821 (define_insn "truncdiqi2"
2822   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2823         (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2824   "TARGET_64BIT"
2825   "@
2826     sll\t%0,%1,0
2827     sb\t%1,%0"
2828   [(set_attr "type" "shift,store")
2829    (set_attr "mode" "SI")
2830    (set_attr "extended_mips16" "yes,*")])
2831
2832 ;; Combiner patterns to optimize shift/truncate combinations.
2833
2834 (define_insn ""
2835   [(set (match_operand:SI 0 "register_operand" "=d")
2836         (truncate:SI
2837           (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2838                        (match_operand:DI 2 "const_arith_operand" ""))))]
2839   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2840   "dsra\t%0,%1,%2"
2841   [(set_attr "type" "shift")
2842    (set_attr "mode" "SI")])
2843
2844 (define_insn ""
2845   [(set (match_operand:SI 0 "register_operand" "=d")
2846         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2847                                   (const_int 32))))]
2848   "TARGET_64BIT && !TARGET_MIPS16"
2849   "dsra\t%0,%1,32"
2850   [(set_attr "type" "shift")
2851    (set_attr "mode" "SI")])
2852
2853
2854 ;; Combiner patterns for truncate/sign_extend combinations.  They use
2855 ;; the shift/truncate patterns above.
2856
2857 (define_insn_and_split ""
2858   [(set (match_operand:SI 0 "register_operand" "=d")
2859         (sign_extend:SI
2860             (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2861   "TARGET_64BIT && !TARGET_MIPS16"
2862   "#"
2863   "&& reload_completed"
2864   [(set (match_dup 2)
2865         (ashift:DI (match_dup 1)
2866                    (const_int 48)))
2867    (set (match_dup 0)
2868         (truncate:SI (ashiftrt:DI (match_dup 2)
2869                                   (const_int 48))))]
2870   { operands[2] = gen_lowpart (DImode, operands[0]); })
2871
2872 (define_insn_and_split ""
2873   [(set (match_operand:SI 0 "register_operand" "=d")
2874         (sign_extend:SI
2875             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2876   "TARGET_64BIT && !TARGET_MIPS16"
2877   "#"
2878   "&& reload_completed"
2879   [(set (match_dup 2)
2880         (ashift:DI (match_dup 1)
2881                    (const_int 56)))
2882    (set (match_dup 0)
2883         (truncate:SI (ashiftrt:DI (match_dup 2)
2884                                   (const_int 56))))]
2885   { operands[2] = gen_lowpart (DImode, operands[0]); })
2886
2887
2888 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2889
2890 (define_insn ""
2891   [(set (match_operand:SI 0 "register_operand" "=d")
2892         (zero_extend:SI (truncate:HI
2893                          (match_operand:DI 1 "register_operand" "d"))))]
2894   "TARGET_64BIT && !TARGET_MIPS16"
2895   "andi\t%0,%1,0xffff"
2896   [(set_attr "type"     "arith")
2897    (set_attr "mode"     "SI")])
2898
2899 (define_insn ""
2900   [(set (match_operand:SI 0 "register_operand" "=d")
2901         (zero_extend:SI (truncate:QI
2902                          (match_operand:DI 1 "register_operand" "d"))))]
2903   "TARGET_64BIT && !TARGET_MIPS16"
2904   "andi\t%0,%1,0xff"
2905   [(set_attr "type"     "arith")
2906    (set_attr "mode"     "SI")])
2907
2908 (define_insn ""
2909   [(set (match_operand:HI 0 "register_operand" "=d")
2910         (zero_extend:HI (truncate:QI
2911                          (match_operand:DI 1 "register_operand" "d"))))]
2912   "TARGET_64BIT && !TARGET_MIPS16"
2913   "andi\t%0,%1,0xff"
2914   [(set_attr "type"     "arith")
2915    (set_attr "mode"     "HI")])
2916 \f
2917 ;;
2918 ;;  ....................
2919 ;;
2920 ;;      ZERO EXTENSION
2921 ;;
2922 ;;  ....................
2923
2924 ;; Extension insns.
2925 ;; Those for integer source operand are ordered widest source type first.
2926
2927 (define_insn_and_split "zero_extendsidi2"
2928   [(set (match_operand:DI 0 "register_operand" "=d")
2929         (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2930   "TARGET_64BIT"
2931   "#"
2932   "&& reload_completed"
2933   [(set (match_dup 0)
2934         (ashift:DI (match_dup 1) (const_int 32)))
2935    (set (match_dup 0)
2936         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2937   "operands[1] = gen_lowpart (DImode, operands[1]);"
2938   [(set_attr "type" "multi")
2939    (set_attr "mode" "DI")
2940    (set_attr "length" "8")])
2941
2942 (define_insn "*zero_extendsidi2_mem"
2943   [(set (match_operand:DI 0 "register_operand" "=d")
2944         (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2945   "TARGET_64BIT"
2946   "lwu\t%0,%1"
2947   [(set_attr "type"     "load")
2948    (set_attr "mode"     "DI")])
2949
2950 (define_expand "zero_extendhisi2"
2951   [(set (match_operand:SI 0 "register_operand")
2952         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2953   ""
2954 {
2955   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2956     {
2957       rtx op = gen_lowpart (SImode, operands[1]);
2958       rtx temp = force_reg (SImode, GEN_INT (0xffff));
2959
2960       emit_insn (gen_andsi3 (operands[0], op, temp));
2961       DONE;
2962     }
2963 })
2964
2965 (define_insn ""
2966   [(set (match_operand:SI 0 "register_operand" "=d,d")
2967         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2968   "!TARGET_MIPS16"
2969   "@
2970    andi\t%0,%1,0xffff
2971    lhu\t%0,%1"
2972   [(set_attr "type"     "arith,load")
2973    (set_attr "mode"     "SI")
2974    (set_attr "length"   "4,*")])
2975
2976 (define_insn ""
2977   [(set (match_operand:SI 0 "register_operand" "=d")
2978         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2979   "TARGET_MIPS16"
2980   "lhu\t%0,%1"
2981   [(set_attr "type"     "load")
2982    (set_attr "mode"     "SI")])
2983
2984 (define_expand "zero_extendhidi2"
2985   [(set (match_operand:DI 0 "register_operand")
2986         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2987   "TARGET_64BIT"
2988 {
2989   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2990     {
2991       rtx op = gen_lowpart (DImode, operands[1]);
2992       rtx temp = force_reg (DImode, GEN_INT (0xffff));
2993
2994       emit_insn (gen_anddi3 (operands[0], op, temp));
2995       DONE;
2996     }
2997 })
2998
2999 (define_insn ""
3000   [(set (match_operand:DI 0 "register_operand" "=d,d")
3001         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
3002   "TARGET_64BIT && !TARGET_MIPS16"
3003   "@
3004    andi\t%0,%1,0xffff
3005    lhu\t%0,%1"
3006   [(set_attr "type"     "arith,load")
3007    (set_attr "mode"     "DI")
3008    (set_attr "length"   "4,*")])
3009
3010 (define_insn ""
3011   [(set (match_operand:DI 0 "register_operand" "=d")
3012         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3013   "TARGET_64BIT && TARGET_MIPS16"
3014   "lhu\t%0,%1"
3015   [(set_attr "type"     "load")
3016    (set_attr "mode"     "DI")])
3017
3018 (define_expand "zero_extendqihi2"
3019   [(set (match_operand:HI 0 "register_operand")
3020         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3021   ""
3022 {
3023   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3024     {
3025       rtx op0 = gen_lowpart (SImode, operands[0]);
3026       rtx op1 = gen_lowpart (SImode, operands[1]);
3027       rtx temp = force_reg (SImode, GEN_INT (0xff));
3028
3029       emit_insn (gen_andsi3 (op0, op1, temp));
3030       DONE;
3031     }
3032 })
3033
3034 (define_insn ""
3035   [(set (match_operand:HI 0 "register_operand" "=d,d")
3036         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3037   "!TARGET_MIPS16"
3038   "@
3039    andi\t%0,%1,0x00ff
3040    lbu\t%0,%1"
3041   [(set_attr "type"     "arith,load")
3042    (set_attr "mode"     "HI")
3043    (set_attr "length"   "4,*")])
3044
3045 (define_insn ""
3046   [(set (match_operand:HI 0 "register_operand" "=d")
3047         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3048   "TARGET_MIPS16"
3049   "lbu\t%0,%1"
3050   [(set_attr "type"     "load")
3051    (set_attr "mode"     "HI")])
3052
3053 (define_expand "zero_extendqisi2"
3054   [(set (match_operand:SI 0 "register_operand")
3055         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3056   ""
3057 {
3058   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3059     {
3060       rtx op = gen_lowpart (SImode, operands[1]);
3061       rtx temp = force_reg (SImode, GEN_INT (0xff));
3062
3063       emit_insn (gen_andsi3 (operands[0], op, temp));
3064       DONE;
3065     }
3066 })
3067
3068 (define_insn ""
3069   [(set (match_operand:SI 0 "register_operand" "=d,d")
3070         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3071   "!TARGET_MIPS16"
3072   "@
3073    andi\t%0,%1,0x00ff
3074    lbu\t%0,%1"
3075   [(set_attr "type"     "arith,load")
3076    (set_attr "mode"     "SI")
3077    (set_attr "length"   "4,*")])
3078
3079 (define_insn ""
3080   [(set (match_operand:SI 0 "register_operand" "=d")
3081         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3082   "TARGET_MIPS16"
3083   "lbu\t%0,%1"
3084   [(set_attr "type"     "load")
3085    (set_attr "mode"     "SI")])
3086
3087 (define_expand "zero_extendqidi2"
3088   [(set (match_operand:DI 0 "register_operand")
3089         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3090   "TARGET_64BIT"
3091 {
3092   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3093     {
3094       rtx op = gen_lowpart (DImode, operands[1]);
3095       rtx temp = force_reg (DImode, GEN_INT (0xff));
3096
3097       emit_insn (gen_anddi3 (operands[0], op, temp));
3098       DONE;
3099     }
3100 })
3101
3102 (define_insn ""
3103   [(set (match_operand:DI 0 "register_operand" "=d,d")
3104         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3105   "TARGET_64BIT && !TARGET_MIPS16"
3106   "@
3107    andi\t%0,%1,0x00ff
3108    lbu\t%0,%1"
3109   [(set_attr "type"     "arith,load")
3110    (set_attr "mode"     "DI")
3111    (set_attr "length"   "4,*")])
3112
3113 (define_insn ""
3114   [(set (match_operand:DI 0 "register_operand" "=d")
3115         (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3116   "TARGET_64BIT && TARGET_MIPS16"
3117   "lbu\t%0,%1"
3118   [(set_attr "type"     "load")
3119    (set_attr "mode"     "DI")])
3120 \f
3121 ;;
3122 ;;  ....................
3123 ;;
3124 ;;      SIGN EXTENSION
3125 ;;
3126 ;;  ....................
3127
3128 ;; Extension insns.
3129 ;; Those for integer source operand are ordered widest source type first.
3130
3131 ;; When TARGET_64BIT, all SImode integer registers should already be in
3132 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can
3133 ;; therefore get rid of register->register instructions if we constrain
3134 ;; the source to be in the same register as the destination.
3135 ;;
3136 ;; The register alternative has type "arith" so that the pre-reload
3137 ;; scheduler will treat it as a move.  This reflects what happens if
3138 ;; the register alternative needs a reload.
3139 (define_insn_and_split "extendsidi2"
3140   [(set (match_operand:DI 0 "register_operand" "=d,d")
3141         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
3142   "TARGET_64BIT"
3143   "@
3144    #
3145    lw\t%0,%1"
3146   "&& reload_completed && register_operand (operands[1], VOIDmode)"
3147   [(const_int 0)]
3148 {
3149   emit_note (NOTE_INSN_DELETED);
3150   DONE;
3151 }
3152   [(set_attr "type" "arith,load")
3153    (set_attr "mode" "DI")])
3154
3155 ;; These patterns originally accepted general_operands, however, slightly
3156 ;; better code is generated by only accepting register_operands, and then
3157 ;; letting combine generate the lh and lb insns.
3158
3159 ;; These expanders originally put values in registers first. We split
3160 ;; all non-mem patterns after reload.
3161
3162 (define_expand "extendhidi2"
3163   [(set (match_operand:DI 0 "register_operand")
3164         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
3165   "TARGET_64BIT"
3166   "")
3167
3168 (define_insn "*extendhidi2"
3169   [(set (match_operand:DI 0 "register_operand" "=d")
3170         (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
3171   "TARGET_64BIT"
3172   "#")
3173
3174 (define_split
3175   [(set (match_operand:DI 0 "register_operand")
3176         (sign_extend:DI (match_operand:HI 1 "register_operand")))]
3177   "TARGET_64BIT && reload_completed"
3178   [(set (match_dup 0)
3179         (ashift:DI (match_dup 1) (const_int 48)))
3180    (set (match_dup 0)
3181         (ashiftrt:DI (match_dup 0) (const_int 48)))]
3182   "operands[1] = gen_lowpart (DImode, operands[1]);")
3183
3184 (define_insn "*extendhidi2_mem"
3185   [(set (match_operand:DI 0 "register_operand" "=d")
3186         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3187   "TARGET_64BIT"
3188   "lh\t%0,%1"
3189   [(set_attr "type"     "load")
3190    (set_attr "mode"     "DI")])
3191
3192 (define_expand "extendhisi2"
3193   [(set (match_operand:SI 0 "register_operand")
3194         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
3195   ""
3196 {
3197   if (ISA_HAS_SEB_SEH)
3198     {
3199       emit_insn (gen_extendhisi2_hw (operands[0],
3200                                      force_reg (HImode, operands[1])));
3201       DONE;
3202     }
3203 })
3204
3205 (define_insn "*extendhisi2"
3206   [(set (match_operand:SI 0 "register_operand" "=d")
3207         (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
3208   ""
3209   "#")
3210
3211 (define_split
3212   [(set (match_operand:SI 0 "register_operand")
3213         (sign_extend:SI (match_operand:HI 1 "register_operand")))]
3214   "reload_completed"
3215   [(set (match_dup 0)
3216         (ashift:SI (match_dup 1) (const_int 16)))
3217    (set (match_dup 0)
3218         (ashiftrt:SI (match_dup 0) (const_int 16)))]
3219   "operands[1] = gen_lowpart (SImode, operands[1]);")
3220
3221 (define_insn "extendhisi2_mem"
3222   [(set (match_operand:SI 0 "register_operand" "=d")
3223         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3224   ""
3225   "lh\t%0,%1"
3226   [(set_attr "type"     "load")
3227    (set_attr "mode"     "SI")])
3228
3229 (define_insn "extendhisi2_hw"
3230   [(set (match_operand:SI 0 "register_operand" "=r")
3231         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
3232   "ISA_HAS_SEB_SEH"
3233   "seh\t%0,%1"
3234   [(set_attr "type" "arith")
3235    (set_attr "mode" "SI")])
3236
3237 (define_expand "extendqihi2"
3238   [(set (match_operand:HI 0 "register_operand")
3239         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3240   ""
3241   "")
3242
3243 (define_insn "*extendqihi2"
3244   [(set (match_operand:HI 0 "register_operand" "=d")
3245         (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
3246   ""
3247   "#")
3248
3249 (define_split
3250   [(set (match_operand:HI 0 "register_operand")
3251         (sign_extend:HI (match_operand:QI 1 "register_operand")))]
3252   "reload_completed"
3253   [(set (match_dup 0)
3254         (ashift:SI (match_dup 1) (const_int 24)))
3255    (set (match_dup 0)
3256         (ashiftrt:SI (match_dup 0) (const_int 24)))]
3257   "operands[0] = gen_lowpart (SImode, operands[0]);
3258    operands[1] = gen_lowpart (SImode, operands[1]);")
3259
3260 (define_insn "*extendqihi2_internal_mem"
3261   [(set (match_operand:HI 0 "register_operand" "=d")
3262         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3263   ""
3264   "lb\t%0,%1"
3265   [(set_attr "type"     "load")
3266    (set_attr "mode"     "SI")])
3267
3268
3269 (define_expand "extendqisi2"
3270   [(set (match_operand:SI 0 "register_operand")
3271         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3272   ""
3273 {
3274   if (ISA_HAS_SEB_SEH)
3275     {
3276       emit_insn (gen_extendqisi2_hw (operands[0],
3277                                      force_reg (QImode, operands[1])));
3278       DONE;
3279     }
3280 })
3281
3282 (define_insn "*extendqisi2"
3283   [(set (match_operand:SI 0 "register_operand" "=d")
3284         (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
3285   ""
3286   "#")
3287
3288 (define_split
3289   [(set (match_operand:SI 0 "register_operand")
3290         (sign_extend:SI (match_operand:QI 1 "register_operand")))]
3291   "reload_completed"
3292   [(set (match_dup 0)
3293         (ashift:SI (match_dup 1) (const_int 24)))
3294    (set (match_dup 0)
3295         (ashiftrt:SI (match_dup 0) (const_int 24)))]
3296   "operands[1] = gen_lowpart (SImode, operands[1]);")
3297
3298 (define_insn "*extendqisi2_mem"
3299   [(set (match_operand:SI 0 "register_operand" "=d")
3300         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3301   ""
3302   "lb\t%0,%1"
3303   [(set_attr "type"     "load")
3304    (set_attr "mode"     "SI")])
3305
3306 (define_insn "extendqisi2_hw"
3307   [(set (match_operand:SI 0 "register_operand" "=r")
3308         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
3309   "ISA_HAS_SEB_SEH"
3310   "seb\t%0,%1"
3311   [(set_attr "type" "arith")
3312    (set_attr "mode" "SI")])
3313
3314 (define_expand "extendqidi2"
3315   [(set (match_operand:DI 0 "register_operand")
3316         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3317   "TARGET_64BIT"
3318   "")
3319
3320 (define_insn "*extendqidi2"
3321   [(set (match_operand:DI 0 "register_operand" "=d")
3322         (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
3323   "TARGET_64BIT"
3324   "#")
3325
3326 (define_split
3327   [(set (match_operand:DI 0 "register_operand")
3328         (sign_extend:DI (match_operand:QI 1 "register_operand")))]
3329   "TARGET_64BIT && reload_completed"
3330   [(set (match_dup 0)
3331         (ashift:DI (match_dup 1) (const_int 56)))
3332    (set (match_dup 0)
3333         (ashiftrt:DI (match_dup 0) (const_int 56)))]
3334   "operands[1] = gen_lowpart (DImode, operands[1]);")
3335
3336 (define_insn "*extendqidi2_mem"
3337   [(set (match_operand:DI 0 "register_operand" "=d")
3338         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3339   "TARGET_64BIT"
3340   "lb\t%0,%1"
3341   [(set_attr "type"     "load")
3342    (set_attr "mode"     "DI")])
3343
3344 (define_insn "extendsfdf2"
3345   [(set (match_operand:DF 0 "register_operand" "=f")
3346         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3347   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3348   "cvt.d.s\t%0,%1"
3349   [(set_attr "type"     "fcvt")
3350    (set_attr "mode"     "DF")])
3351 \f
3352 ;;
3353 ;;  ....................
3354 ;;
3355 ;;      CONVERSIONS
3356 ;;
3357 ;;  ....................
3358
3359 (define_expand "fix_truncdfsi2"
3360   [(set (match_operand:SI 0 "register_operand")
3361         (fix:SI (match_operand:DF 1 "register_operand")))]
3362   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3363 {
3364   if (!ISA_HAS_TRUNC_W)
3365     {
3366       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3367       DONE;
3368     }
3369 })
3370
3371 (define_insn "fix_truncdfsi2_insn"
3372   [(set (match_operand:SI 0 "register_operand" "=f")
3373         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3374   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3375   "trunc.w.d %0,%1"
3376   [(set_attr "type"     "fcvt")
3377    (set_attr "mode"     "DF")
3378    (set_attr "length"   "4")])
3379
3380 (define_insn "fix_truncdfsi2_macro"
3381   [(set (match_operand:SI 0 "register_operand" "=f")
3382         (fix:SI (match_operand:DF 1 "register_operand" "f")))
3383    (clobber (match_scratch:DF 2 "=d"))]
3384   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3385 {
3386   if (set_nomacro)
3387     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3388   else
3389     return "trunc.w.d %0,%1,%2";
3390 }
3391   [(set_attr "type"     "fcvt")
3392    (set_attr "mode"     "DF")
3393    (set_attr "length"   "36")])
3394
3395 (define_expand "fix_truncsfsi2"
3396   [(set (match_operand:SI 0 "register_operand")
3397         (fix:SI (match_operand:SF 1 "register_operand")))]
3398   "TARGET_HARD_FLOAT"
3399 {
3400   if (!ISA_HAS_TRUNC_W)
3401     {
3402       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3403       DONE;
3404     }
3405 })
3406
3407 (define_insn "fix_truncsfsi2_insn"
3408   [(set (match_operand:SI 0 "register_operand" "=f")
3409         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3410   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3411   "trunc.w.s %0,%1"
3412   [(set_attr "type"     "fcvt")
3413    (set_attr "mode"     "DF")
3414    (set_attr "length"   "4")])
3415
3416 (define_insn "fix_truncsfsi2_macro"