OSDN Git Service

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