OSDN Git Service

* config/mips/mips-protos.h (mips_gp_save_slot): Remove.
[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 \f
57 ;; ....................
58 ;;
59 ;;      Attributes
60 ;;
61 ;; ....................
62
63 (define_attr "got" "unset,xgot_high,load"
64   (const_string "unset"))
65
66 ;; For jal instructions, this attribute is DIRECT when the target address
67 ;; is symbolic and INDIRECT when it is a register.
68 (define_attr "jal" "unset,direct,indirect"
69   (const_string "unset"))
70
71 ;; This attribute is YES if the instruction is a jal macro (not a
72 ;; real jal instruction).
73 ;;
74 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
75 ;; restore $gp.  Direct jals are also macros in NewABI PIC since they
76 ;; load the target address into $25.
77 (define_attr "jal_macro" "no,yes"
78   (cond [(eq_attr "jal" "direct")
79          (symbol_ref "TARGET_ABICALLS != 0")
80          (eq_attr "jal" "indirect")
81          (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
82         (const_string "no")))
83
84 ;; Classification of each insn.
85 ;; branch       conditional branch
86 ;; jump         unconditional jump
87 ;; call         unconditional call
88 ;; load         load instruction(s)
89 ;; fpload       floating point load
90 ;; fpidxload    floating point indexed load
91 ;; store        store instruction(s)
92 ;; fpstore      floating point store
93 ;; fpidxstore   floating point indexed store
94 ;; prefetch     memory prefetch (register + offset)
95 ;; prefetchx    memory indexed prefetch (register + register)
96 ;; condmove     conditional moves
97 ;; xfer         transfer to/from coprocessor
98 ;; mthilo       transfer to hi/lo registers
99 ;; mfhilo       transfer from hi/lo registers
100 ;; const        load constant
101 ;; arith        integer arithmetic and logical instructions
102 ;; shift        integer shift instructions
103 ;; slt          set less than instructions
104 ;; clz          the clz and clo instructions
105 ;; trap         trap if instructions
106 ;; imul         integer multiply
107 ;; imadd        integer multiply-add
108 ;; idiv         integer divide
109 ;; fmove        floating point register move
110 ;; fadd         floating point add/subtract
111 ;; fmul         floating point multiply
112 ;; fmadd        floating point multiply-add
113 ;; fdiv         floating point divide
114 ;; fabs         floating point absolute value
115 ;; fneg         floating point negation
116 ;; fcmp         floating point compare
117 ;; fcvt         floating point convert
118 ;; fsqrt        floating point square root
119 ;; frsqrt       floating point reciprocal square root
120 ;; multi        multiword sequence (or user asm statements)
121 ;; nop          no operation
122 (define_attr "type"
123   "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
124   (cond [(eq_attr "jal" "!unset") (const_string "call")
125          (eq_attr "got" "load") (const_string "load")]
126         (const_string "unknown")))
127
128 ;; Main data type used by the insn
129 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
130   (const_string "unknown"))
131
132 ;; Is this an extended instruction in mips16 mode?
133 (define_attr "extended_mips16" "no,yes"
134   (const_string "no"))
135
136 ;; Length of instruction in bytes.
137 (define_attr "length" ""
138    (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
139           ;; If a branch is outside this range, we have a choice of two
140           ;; sequences.  For PIC, an out-of-range branch like:
141           ;;
142           ;;    bne     r1,r2,target
143           ;;    dslot
144           ;;
145           ;; becomes the equivalent of:
146           ;;
147           ;;    beq     r1,r2,1f
148           ;;    dslot
149           ;;    la      $at,target
150           ;;    jr      $at
151           ;;    nop
152           ;; 1:
153           ;;
154           ;; where the load address can be up to three instructions long
155           ;; (lw, nop, addiu).
156           ;;
157           ;; The non-PIC case is similar except that we use a direct
158           ;; jump instead of an la/jr pair.  Since the target of this
159           ;; jump is an absolute 28-bit bit address (the other bits
160           ;; coming from the address of the delay slot) this form cannot
161           ;; cross a 256MB boundary.  We could provide the option of
162           ;; using la/jr in this case too, but we do not do so at
163           ;; present.
164           ;;
165           ;; Note that this value does not account for the delay slot
166           ;; instruction, whose length is added separately.  If the RTL
167           ;; pattern has no explicit delay slot, mips_adjust_insn_length
168           ;; will add the length of the implicit nop.  The values for
169           ;; forward and backward branches will be different as well.
170           (eq_attr "type" "branch")
171           (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
172                       (le (minus (pc) (match_dup 1)) (const_int 131068)))
173                   (const_int 4)
174                  (ne (symbol_ref "flag_pic") (const_int 0))
175                  (const_int 24)
176                  ] (const_int 12))
177
178           (eq_attr "got" "load")
179           (const_int 4)
180           (eq_attr "got" "xgot_high")
181           (const_int 8)
182
183           (eq_attr "type" "const")
184           (symbol_ref "mips_const_insns (operands[1]) * 4")
185           (eq_attr "type" "load,fpload,fpidxload")
186           (symbol_ref "mips_fetch_insns (operands[1]) * 4")
187           (eq_attr "type" "store,fpstore,fpidxstore")
188           (symbol_ref "mips_fetch_insns (operands[0]) * 4")
189
190           ;; In the worst case, a call macro will take 8 instructions:
191           ;;
192           ;;     lui $25,%call_hi(FOO)
193           ;;     addu $25,$25,$28
194           ;;     lw $25,%call_lo(FOO)($25)
195           ;;     nop
196           ;;     jalr $25
197           ;;     nop
198           ;;     lw $gp,X($sp)
199           ;;     nop
200           (eq_attr "jal_macro" "yes")
201           (const_int 32)
202
203           (and (eq_attr "extended_mips16" "yes")
204                (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
205           (const_int 8)
206
207           ;; Various VR4120 errata require a nop to be inserted after a macc
208           ;; instruction.  The assembler does this for us, so account for
209           ;; the worst-case length here.
210           (and (eq_attr "type" "imadd")
211                (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
212           (const_int 8)
213
214           ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
215           ;; the result of the second one is missed.  The assembler should work
216           ;; around this by inserting a nop after the first dmult.
217           (and (eq_attr "type" "imul")
218                (and (eq_attr "mode" "DI")
219                     (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
220           (const_int 8)
221
222           (eq_attr "type" "idiv")
223           (symbol_ref "mips_idiv_insns () * 4")
224           ] (const_int 4)))
225
226 ;; Attribute describing the processor.  This attribute must match exactly
227 ;; with the processor_type enumeration in mips.h.
228 (define_attr "cpu"
229   "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
230   (const (symbol_ref "mips_tune")))
231
232 ;; The type of hardware hazard associated with this instruction.
233 ;; DELAY means that the next instruction cannot read the result
234 ;; of this one.  HILO means that the next two instructions cannot
235 ;; write to HI or LO.
236 (define_attr "hazard" "none,delay,hilo"
237   (cond [(and (eq_attr "type" "load,fpload,fpidxload")
238               (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
239          (const_string "delay")
240
241          (and (eq_attr "type" "xfer")
242               (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
243          (const_string "delay")
244
245          (and (eq_attr "type" "fcmp")
246               (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
247          (const_string "delay")
248
249          ;; The r4000 multiplication patterns include an mflo instruction.
250          (and (eq_attr "type" "imul")
251               (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
252          (const_string "hilo")
253
254          (and (eq_attr "type" "mfhilo")
255               (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
256          (const_string "hilo")]
257         (const_string "none")))
258
259 ;; Is it a single instruction?
260 (define_attr "single_insn" "no,yes"
261   (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
262
263 ;; Can the instruction be put into a delay slot?
264 (define_attr "can_delay" "no,yes"
265   (if_then_else (and (eq_attr "type" "!branch,call,jump")
266                      (and (eq_attr "hazard" "none")
267                           (eq_attr "single_insn" "yes")))
268                 (const_string "yes")
269                 (const_string "no")))
270
271 ;; Attribute defining whether or not we can use the branch-likely instructions
272 (define_attr "branch_likely" "no,yes"
273   (const
274    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
275                  (const_string "yes")
276                  (const_string "no"))))
277
278 ;; True if an instruction might assign to hi or lo when reloaded.
279 ;; This is used by the TUNE_MACC_CHAINS code.
280 (define_attr "may_clobber_hilo" "no,yes"
281   (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
282                 (const_string "yes")
283                 (const_string "no")))
284
285 ;; Describe a user's asm statement.
286 (define_asm_attributes
287   [(set_attr "type" "multi")])
288 \f
289 ;; .........................
290 ;;
291 ;;      Branch, call and jump delay slots
292 ;;
293 ;; .........................
294
295 (define_delay (and (eq_attr "type" "branch")
296                    (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
297   [(eq_attr "can_delay" "yes")
298    (nil)
299    (and (eq_attr "branch_likely" "yes")
300         (eq_attr "can_delay" "yes"))])
301
302 (define_delay (eq_attr "type" "jump")
303   [(eq_attr "can_delay" "yes")
304    (nil)
305    (nil)])
306
307 (define_delay (and (eq_attr "type" "call")
308                    (eq_attr "jal_macro" "no"))
309   [(eq_attr "can_delay" "yes")
310    (nil)
311    (nil)])
312 \f
313 ;; Pipeline descriptions.
314 ;;
315 ;; generic.md provides a fallback for processors without a specific
316 ;; pipeline description.  It is derived from the old define_function_unit
317 ;; version and uses the "alu" and "imuldiv" units declared below.
318 ;;
319 ;; Some of the processor-specific files are also derived from old
320 ;; define_function_unit descriptions and simply override the parts of
321 ;; generic.md that don't apply.  The other processor-specific files
322 ;; are self-contained.
323 (define_automaton "alu,imuldiv")
324
325 (define_cpu_unit "alu" "alu")
326 (define_cpu_unit "imuldiv" "imuldiv")
327
328 (include "3000.md")
329 (include "4000.md")
330 (include "4100.md")
331 (include "4130.md")
332 (include "4300.md")
333 (include "4600.md")
334 (include "5000.md")
335 (include "5400.md")
336 (include "5500.md")
337 (include "6000.md")
338 (include "7000.md")
339 (include "9000.md")
340 (include "sb1.md")
341 (include "sr71k.md")
342 (include "generic.md")
343 \f
344 ;;
345 ;;  ....................
346 ;;
347 ;;      CONDITIONAL TRAPS
348 ;;
349 ;;  ....................
350 ;;
351
352 (define_insn "trap"
353   [(trap_if (const_int 1) (const_int 0))]
354   ""
355 {
356   if (ISA_HAS_COND_TRAP)
357     return "teq\t$0,$0";
358   /* The IRIX 6 O32 assembler requires the first break operand.  */
359   else if (TARGET_MIPS16 || !TARGET_GAS)
360     return "break 0";
361   else
362     return "break";
363 }
364   [(set_attr "type"     "trap")])
365
366 (define_expand "conditional_trap"
367   [(trap_if (match_operator 0 "cmp_op"
368                             [(match_dup 2) (match_dup 3)])
369             (match_operand 1 "const_int_operand"))]
370   "ISA_HAS_COND_TRAP"
371 {
372   if (operands[1] == const0_rtx)
373     {
374       mips_gen_conditional_trap (operands);
375       DONE;
376     }
377   else
378     FAIL;
379 })
380
381 (define_insn ""
382   [(trap_if (match_operator 0 "trap_cmp_op"
383                             [(match_operand:SI 1 "reg_or_0_operand" "dJ")
384                              (match_operand:SI 2 "arith_operand" "dI")])
385             (const_int 0))]
386   "ISA_HAS_COND_TRAP"
387   "t%C0\t%z1,%z2"
388   [(set_attr "type"     "trap")])
389
390 (define_insn ""
391   [(trap_if (match_operator 0 "trap_cmp_op"
392                             [(match_operand:DI 1 "reg_or_0_operand" "dJ")
393                              (match_operand:DI 2 "arith_operand" "dI")])
394             (const_int 0))]
395   "TARGET_64BIT && ISA_HAS_COND_TRAP"
396   "t%C0\t%z1,%z2"
397   [(set_attr "type"     "trap")])
398 \f
399 ;;
400 ;;  ....................
401 ;;
402 ;;      ADDITION
403 ;;
404 ;;  ....................
405 ;;
406
407 (define_insn "adddf3"
408   [(set (match_operand:DF 0 "register_operand" "=f")
409         (plus:DF (match_operand:DF 1 "register_operand" "f")
410                  (match_operand:DF 2 "register_operand" "f")))]
411   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
412   "add.d\t%0,%1,%2"
413   [(set_attr "type"     "fadd")
414    (set_attr "mode"     "DF")])
415
416 (define_insn "addsf3"
417   [(set (match_operand:SF 0 "register_operand" "=f")
418         (plus:SF (match_operand:SF 1 "register_operand" "f")
419                  (match_operand:SF 2 "register_operand" "f")))]
420   "TARGET_HARD_FLOAT"
421   "add.s\t%0,%1,%2"
422   [(set_attr "type"     "fadd")
423    (set_attr "mode"     "SF")])
424
425 (define_expand "addsi3"
426   [(set (match_operand:SI 0 "register_operand")
427         (plus:SI (match_operand:SI 1 "reg_or_0_operand")
428                  (match_operand:SI 2 "arith_operand")))]
429   "")
430
431 (define_insn "addsi3_internal"
432   [(set (match_operand:SI 0 "register_operand" "=d,d")
433         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
434                  (match_operand:SI 2 "arith_operand" "d,Q")))]
435   "!TARGET_MIPS16"
436   "@
437     addu\t%0,%z1,%2
438     addiu\t%0,%z1,%2"
439   [(set_attr "type"     "arith")
440    (set_attr "mode"     "SI")])
441
442 ;; For the mips16, we need to recognize stack pointer additions
443 ;; explicitly, since we don't have a constraint for $sp.  These insns
444 ;; will be generated by the save_restore_insns functions.
445
446 (define_insn ""
447   [(set (reg:SI 29)
448         (plus:SI (reg:SI 29)
449                  (match_operand:SI 0 "small_int" "I")))]
450   "TARGET_MIPS16"
451   "addu\t%$,%$,%0"
452   [(set_attr "type"     "arith")
453    (set_attr "mode"     "SI")
454    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
455                                       (const_int 4)
456                                       (const_int 8)))])
457
458 (define_insn ""
459   [(set (match_operand:SI 0 "register_operand" "=d")
460         (plus:SI (reg:SI 29)
461                  (match_operand:SI 1 "small_int" "I")))]
462   "TARGET_MIPS16"
463   "addu\t%0,%$,%1"
464   [(set_attr "type"     "arith")
465    (set_attr "mode"     "SI")
466    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4")
467                                       (const_int 4)
468                                       (const_int 8)))])
469
470 (define_insn ""
471   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
472         (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
473                  (match_operand:SI 2 "arith_operand" "Q,O,d")))]
474   "TARGET_MIPS16"
475 {
476   if (REGNO (operands[0]) == REGNO (operands[1]))
477     return "addu\t%0,%2";
478   else
479     return "addu\t%0,%1,%2";
480 }
481   [(set_attr "type"     "arith")
482    (set_attr "mode"     "SI")
483    (set_attr_alternative "length"
484                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
485                                (const_int 4)
486                                (const_int 8))
487                  (if_then_else (match_operand:VOID 2 "m16_simm4_1")
488                                (const_int 4)
489                                (const_int 8))
490                  (const_int 4)])])
491
492
493 ;; On the mips16, we can sometimes split an add of a constant which is
494 ;; a 4 byte instruction into two adds which are both 2 byte
495 ;; instructions.  There are two cases: one where we are adding a
496 ;; constant plus a register to another register, and one where we are
497 ;; simply adding a constant to a register.
498
499 (define_split
500   [(set (match_operand:SI 0 "register_operand")
501         (plus:SI (match_dup 0)
502                  (match_operand:SI 1 "const_int_operand")))]
503   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
504    && GET_CODE (operands[0]) == REG
505    && M16_REG_P (REGNO (operands[0]))
506    && GET_CODE (operands[1]) == CONST_INT
507    && ((INTVAL (operands[1]) > 0x7f
508         && INTVAL (operands[1]) <= 0x7f + 0x7f)
509        || (INTVAL (operands[1]) < - 0x80
510            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
511   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
512    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
513 {
514   HOST_WIDE_INT val = INTVAL (operands[1]);
515
516   if (val >= 0)
517     {
518       operands[1] = GEN_INT (0x7f);
519       operands[2] = GEN_INT (val - 0x7f);
520     }
521   else
522     {
523       operands[1] = GEN_INT (- 0x80);
524       operands[2] = GEN_INT (val + 0x80);
525     }
526 })
527
528 (define_split
529   [(set (match_operand:SI 0 "register_operand")
530         (plus:SI (match_operand:SI 1 "register_operand")
531                  (match_operand:SI 2 "const_int_operand")))]
532   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
533    && GET_CODE (operands[0]) == REG
534    && M16_REG_P (REGNO (operands[0]))
535    && GET_CODE (operands[1]) == REG
536    && M16_REG_P (REGNO (operands[1]))
537    && REGNO (operands[0]) != REGNO (operands[1])
538    && GET_CODE (operands[2]) == CONST_INT
539    && ((INTVAL (operands[2]) > 0x7
540         && INTVAL (operands[2]) <= 0x7 + 0x7f)
541        || (INTVAL (operands[2]) < - 0x8
542            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
543   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
544    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
545 {
546   HOST_WIDE_INT val = INTVAL (operands[2]);
547
548   if (val >= 0)
549     {
550       operands[2] = GEN_INT (0x7);
551       operands[3] = GEN_INT (val - 0x7);
552     }
553   else
554     {
555       operands[2] = GEN_INT (- 0x8);
556       operands[3] = GEN_INT (val + 0x8);
557     }
558 })
559
560 (define_expand "adddi3"
561   [(set (match_operand:DI 0 "register_operand")
562         (plus:DI (match_operand:DI 1 "register_operand")
563                  (match_operand:DI 2 "arith_operand")))]
564   "TARGET_64BIT")
565
566 (define_insn "adddi3_internal"
567   [(set (match_operand:DI 0 "register_operand" "=d,d")
568         (plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")
569                  (match_operand:DI 2 "arith_operand" "d,Q")))]
570   "TARGET_64BIT && !TARGET_MIPS16"
571   "@
572     daddu\t%0,%z1,%2
573     daddiu\t%0,%z1,%2"
574   [(set_attr "type"     "arith")
575    (set_attr "mode"     "DI")])
576
577 ;; For the mips16, we need to recognize stack pointer additions
578 ;; explicitly, since we don't have a constraint for $sp.  These insns
579 ;; will be generated by the save_restore_insns functions.
580
581 (define_insn ""
582   [(set (reg:DI 29)
583         (plus:DI (reg:DI 29)
584                  (match_operand:DI 0 "small_int" "I")))]
585   "TARGET_MIPS16 && TARGET_64BIT"
586   "daddu\t%$,%$,%0"
587   [(set_attr "type"     "arith")
588    (set_attr "mode"     "DI")
589    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
590                                       (const_int 4)
591                                       (const_int 8)))])
592
593 (define_insn ""
594   [(set (match_operand:DI 0 "register_operand" "=d")
595         (plus:DI (reg:DI 29)
596                  (match_operand:DI 1 "small_int" "I")))]
597   "TARGET_MIPS16 && TARGET_64BIT"
598   "daddu\t%0,%$,%1"
599   [(set_attr "type"     "arith")
600    (set_attr "mode"     "DI")
601    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4")
602                                       (const_int 4)
603                                       (const_int 8)))])
604
605 (define_insn ""
606   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
607         (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
608                  (match_operand:DI 2 "arith_operand" "Q,O,d")))]
609   "TARGET_MIPS16 && TARGET_64BIT"
610 {
611   if (REGNO (operands[0]) == REGNO (operands[1]))
612     return "daddu\t%0,%2";
613   else
614     return "daddu\t%0,%1,%2";
615 }
616   [(set_attr "type"     "arith")
617    (set_attr "mode"     "DI")
618    (set_attr_alternative "length"
619                 [(if_then_else (match_operand:VOID 2 "m16_simm5_1")
620                                (const_int 4)
621                                (const_int 8))
622                  (if_then_else (match_operand:VOID 2 "m16_simm4_1")
623                                (const_int 4)
624                                (const_int 8))
625                  (const_int 4)])])
626
627
628 ;; On the mips16, we can sometimes split an add of a constant which is
629 ;; a 4 byte instruction into two adds which are both 2 byte
630 ;; instructions.  There are two cases: one where we are adding a
631 ;; constant plus a register to another register, and one where we are
632 ;; simply adding a constant to a register.
633
634 (define_split
635   [(set (match_operand:DI 0 "register_operand")
636         (plus:DI (match_dup 0)
637                  (match_operand:DI 1 "const_int_operand")))]
638   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
639    && GET_CODE (operands[0]) == REG
640    && M16_REG_P (REGNO (operands[0]))
641    && GET_CODE (operands[1]) == CONST_INT
642    && ((INTVAL (operands[1]) > 0xf
643         && INTVAL (operands[1]) <= 0xf + 0xf)
644        || (INTVAL (operands[1]) < - 0x10
645            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
646   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
647    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
648 {
649   HOST_WIDE_INT val = INTVAL (operands[1]);
650
651   if (val >= 0)
652     {
653       operands[1] = GEN_INT (0xf);
654       operands[2] = GEN_INT (val - 0xf);
655     }
656   else
657     {
658       operands[1] = GEN_INT (- 0x10);
659       operands[2] = GEN_INT (val + 0x10);
660     }
661 })
662
663 (define_split
664   [(set (match_operand:DI 0 "register_operand")
665         (plus:DI (match_operand:DI 1 "register_operand")
666                  (match_operand:DI 2 "const_int_operand")))]
667   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
668    && GET_CODE (operands[0]) == REG
669    && M16_REG_P (REGNO (operands[0]))
670    && GET_CODE (operands[1]) == REG
671    && M16_REG_P (REGNO (operands[1]))
672    && REGNO (operands[0]) != REGNO (operands[1])
673    && GET_CODE (operands[2]) == CONST_INT
674    && ((INTVAL (operands[2]) > 0x7
675         && INTVAL (operands[2]) <= 0x7 + 0xf)
676        || (INTVAL (operands[2]) < - 0x8
677            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
678   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
679    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
680 {
681   HOST_WIDE_INT val = INTVAL (operands[2]);
682
683   if (val >= 0)
684     {
685       operands[2] = GEN_INT (0x7);
686       operands[3] = GEN_INT (val - 0x7);
687     }
688   else
689     {
690       operands[2] = GEN_INT (- 0x8);
691       operands[3] = GEN_INT (val + 0x8);
692     }
693 })
694
695 (define_insn "addsi3_internal_2"
696   [(set (match_operand:DI 0 "register_operand" "=d,d")
697         (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
698                                  (match_operand:SI 2 "arith_operand" "d,Q"))))]
699   "TARGET_64BIT && !TARGET_MIPS16"
700   "@
701     addu\t%0,%z1,%2
702     addiu\t%0,%z1,%2"
703   [(set_attr "type"     "arith")
704    (set_attr "mode"     "SI")])
705
706 (define_insn ""
707   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
708         (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
709                                  (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
710   "TARGET_MIPS16 && TARGET_64BIT"
711 {
712   if (REGNO (operands[0]) == REGNO (operands[1]))
713     return "addu\t%0,%2";
714   else
715     return "addu\t%0,%1,%2";
716 }
717   [(set_attr "type"     "arith")
718    (set_attr "mode"     "SI")
719    (set_attr_alternative "length"
720                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
721                                (const_int 4)
722                                (const_int 8))
723                  (if_then_else (match_operand:VOID 2 "m16_simm4_1")
724                                (const_int 4)
725                                (const_int 8))
726                  (const_int 4)])])
727 \f
728 ;;
729 ;;  ....................
730 ;;
731 ;;      SUBTRACTION
732 ;;
733 ;;  ....................
734 ;;
735
736 (define_insn "subdf3"
737   [(set (match_operand:DF 0 "register_operand" "=f")
738         (minus:DF (match_operand:DF 1 "register_operand" "f")
739                   (match_operand:DF 2 "register_operand" "f")))]
740   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
741   "sub.d\t%0,%1,%2"
742   [(set_attr "type"     "fadd")
743    (set_attr "mode"     "DF")])
744
745 (define_insn "subsf3"
746   [(set (match_operand:SF 0 "register_operand" "=f")
747         (minus:SF (match_operand:SF 1 "register_operand" "f")
748                   (match_operand:SF 2 "register_operand" "f")))]
749   "TARGET_HARD_FLOAT"
750   "sub.s\t%0,%1,%2"
751   [(set_attr "type"     "fadd")
752    (set_attr "mode"     "SF")])
753
754 (define_expand "subsi3"
755   [(set (match_operand:SI 0 "register_operand")
756         (minus:SI (match_operand:SI 1 "register_operand")
757                   (match_operand:SI 2 "register_operand")))]
758   ""
759   "")
760
761 (define_insn "subsi3_internal"
762   [(set (match_operand:SI 0 "register_operand" "=d")
763         (minus:SI (match_operand:SI 1 "register_operand" "d")
764                   (match_operand:SI 2 "register_operand" "d")))]
765   ""
766   "subu\t%0,%z1,%2"
767   [(set_attr "type"     "arith")
768    (set_attr "mode"     "SI")])
769
770 (define_insn "subdi3"
771   [(set (match_operand:DI 0 "register_operand" "=d")
772         (minus:DI (match_operand:DI 1 "register_operand" "d")
773                   (match_operand:DI 2 "register_operand" "d")))]
774   "TARGET_64BIT"
775   "dsubu\t%0,%1,%2"
776   [(set_attr "type"     "arith")
777    (set_attr "mode"     "DI")])
778
779 (define_insn "subsi3_internal_2"
780   [(set (match_operand:DI 0 "register_operand" "=d")
781         (sign_extend:DI
782             (minus:SI (match_operand:SI 1 "register_operand" "d")
783                       (match_operand:SI 2 "register_operand" "d"))))]
784   "TARGET_64BIT"
785   "subu\t%0,%1,%2"
786   [(set_attr "type"     "arith")
787    (set_attr "mode"     "DI")])
788 \f
789 ;;
790 ;;  ....................
791 ;;
792 ;;      MULTIPLICATION
793 ;;
794 ;;  ....................
795 ;;
796
797 (define_expand "muldf3"
798   [(set (match_operand:DF 0 "register_operand")
799         (mult:DF (match_operand:DF 1 "register_operand")
800                  (match_operand:DF 2 "register_operand")))]
801   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
802   "")
803
804 (define_insn "muldf3_internal"
805   [(set (match_operand:DF 0 "register_operand" "=f")
806         (mult:DF (match_operand:DF 1 "register_operand" "f")
807                  (match_operand:DF 2 "register_operand" "f")))]
808   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
809   "mul.d\t%0,%1,%2"
810   [(set_attr "type"     "fmul")
811    (set_attr "mode"     "DF")])
812
813 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
814 ;; operands may corrupt immediately following multiplies. This is a
815 ;; simple fix to insert NOPs.
816
817 (define_insn "muldf3_r4300"
818   [(set (match_operand:DF 0 "register_operand" "=f")
819         (mult:DF (match_operand:DF 1 "register_operand" "f")
820                  (match_operand:DF 2 "register_operand" "f")))]
821   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
822   "mul.d\t%0,%1,%2\;nop"
823   [(set_attr "type"     "fmul")
824    (set_attr "mode"     "DF")
825    (set_attr "length"   "8")])
826
827 (define_expand "mulsf3"
828   [(set (match_operand:SF 0 "register_operand")
829         (mult:SF (match_operand:SF 1 "register_operand")
830                  (match_operand:SF 2 "register_operand")))]
831   "TARGET_HARD_FLOAT"
832   "")
833
834 (define_insn "mulsf3_internal"
835   [(set (match_operand:SF 0 "register_operand" "=f")
836         (mult:SF (match_operand:SF 1 "register_operand" "f")
837                  (match_operand:SF 2 "register_operand" "f")))]
838   "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
839   "mul.s\t%0,%1,%2"
840   [(set_attr "type"     "fmul")
841    (set_attr "mode"     "SF")])
842
843 ;; See muldf3_r4300.
844
845 (define_insn "mulsf3_r4300"
846   [(set (match_operand:SF 0 "register_operand" "=f")
847         (mult:SF (match_operand:SF 1 "register_operand" "f")
848                  (match_operand:SF 2 "register_operand" "f")))]
849   "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
850   "mul.s\t%0,%1,%2\;nop"
851   [(set_attr "type"     "fmul")
852    (set_attr "mode"     "SF")
853    (set_attr "length"   "8")])
854
855
856 ;; The original R4000 has a cpu bug.  If a double-word or a variable
857 ;; shift executes while an integer multiplication is in progress, the
858 ;; shift may give an incorrect result.  Avoid this by keeping the mflo
859 ;; with the mult on the R4000.
860 ;;
861 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
862 ;; (also valid for MIPS R4000MC processors):
863 ;;
864 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
865 ;;      this errata description.
866 ;;      The following code sequence causes the R4000 to incorrectly
867 ;;      execute the Double Shift Right Arithmetic 32 (dsra32)
868 ;;      instruction.  If the dsra32 instruction is executed during an
869 ;;      integer multiply, the dsra32 will only shift by the amount in
870 ;;      specified in the instruction rather than the amount plus 32
871 ;;      bits.
872 ;;      instruction 1:          mult    rs,rt           integer multiply
873 ;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
874 ;;                                                      right arithmetic + 32
875 ;;      Workaround: A dsra32 instruction placed after an integer
876 ;;      multiply should not be one of the 11 instructions after the
877 ;;      multiply instruction."
878 ;;
879 ;; and:
880 ;;
881 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
882 ;;      the following description.
883 ;;      All extended shifts (shift by n+32) and variable shifts (32 and
884 ;;      64-bit versions) may produce incorrect results under the
885 ;;      following conditions:
886 ;;      1) An integer multiply is currently executing
887 ;;      2) These types of shift instructions are executed immediately
888 ;;         following an integer divide instruction.
889 ;;      Workaround:
890 ;;      1) Make sure no integer multiply is running wihen these
891 ;;         instruction are executed.  If this cannot be predicted at
892 ;;         compile time, then insert a "mfhi" to R0 instruction
893 ;;         immediately after the integer multiply instruction.  This
894 ;;         will cause the integer multiply to complete before the shift
895 ;;         is executed.
896 ;;      2) Separate integer divide and these two classes of shift
897 ;;         instructions by another instruction or a noop."
898 ;;
899 ;; These processors have PRId values of 0x00004220 and 0x00004300,
900 ;; respectively.
901
902 (define_expand "mulsi3"
903   [(set (match_operand:SI 0 "register_operand")
904         (mult:SI (match_operand:SI 1 "register_operand")
905                  (match_operand:SI 2 "register_operand")))]
906   ""
907 {
908   if (GENERATE_MULT3_SI || TARGET_MAD)
909     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
910   else if (!TARGET_FIX_R4000)
911     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
912   else
913     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
914   DONE;
915 })
916
917 (define_insn "mulsi3_mult3"
918   [(set (match_operand:SI 0 "register_operand" "=d,l")
919         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
920                  (match_operand:SI 2 "register_operand" "d,d")))
921    (clobber (match_scratch:SI 3 "=h,h"))
922    (clobber (match_scratch:SI 4 "=l,X"))]
923   "GENERATE_MULT3_SI
924    || TARGET_MAD"
925 {
926   if (which_alternative == 1)
927     return "mult\t%1,%2";
928   if (TARGET_MAD
929       || TARGET_MIPS5400
930       || TARGET_MIPS5500
931       || TARGET_MIPS7000
932       || TARGET_MIPS9000
933       || ISA_MIPS32
934       || ISA_MIPS32R2
935       || ISA_MIPS64)
936     return "mul\t%0,%1,%2";
937   return "mult\t%0,%1,%2";
938 }
939   [(set_attr "type"     "imul")
940    (set_attr "mode"     "SI")])
941
942 ;; If a register gets allocated to LO, and we spill to memory, the reload
943 ;; will include a move from LO to a GPR.  Merge it into the multiplication
944 ;; if it can set the GPR directly.
945 ;;
946 ;; Operand 0: LO
947 ;; Operand 1: GPR (1st multiplication operand)
948 ;; Operand 2: GPR (2nd multiplication operand)
949 ;; Operand 3: HI
950 ;; Operand 4: GPR (destination)
951 (define_peephole2
952   [(parallel
953        [(set (match_operand:SI 0 "register_operand")
954              (mult:SI (match_operand:SI 1 "register_operand")
955                       (match_operand:SI 2 "register_operand")))
956         (clobber (match_operand:SI 3 "register_operand"))
957         (clobber (scratch:SI))])
958    (set (match_operand:SI 4 "register_operand")
959         (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
960   "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
961   [(parallel
962        [(set (match_dup 4)
963              (mult:SI (match_dup 1)
964                       (match_dup 2)))
965         (clobber (match_dup 3))
966         (clobber (match_dup 0))])])
967
968 (define_insn "mulsi3_internal"
969   [(set (match_operand:SI 0 "register_operand" "=l")
970         (mult:SI (match_operand:SI 1 "register_operand" "d")
971                  (match_operand:SI 2 "register_operand" "d")))
972    (clobber (match_scratch:SI 3 "=h"))]
973   "!TARGET_FIX_R4000"
974   "mult\t%1,%2"
975   [(set_attr "type"     "imul")
976    (set_attr "mode"     "SI")])
977
978 (define_insn "mulsi3_r4000"
979   [(set (match_operand:SI 0 "register_operand" "=d")
980         (mult:SI (match_operand:SI 1 "register_operand" "d")
981                  (match_operand:SI 2 "register_operand" "d")))
982    (clobber (match_scratch:SI 3 "=h"))
983    (clobber (match_scratch:SI 4 "=l"))]
984   "TARGET_FIX_R4000"
985   "mult\t%1,%2\;mflo\t%0"
986   [(set_attr "type"     "imul")
987    (set_attr "mode"     "SI")
988    (set_attr "length"   "8")])
989
990 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
991 ;; of "mult; mflo".  They have the same latency, but the first form gives
992 ;; us an extra cycle to compute the operands.
993
994 ;; Operand 0: LO
995 ;; Operand 1: GPR (1st multiplication operand)
996 ;; Operand 2: GPR (2nd multiplication operand)
997 ;; Operand 3: HI
998 ;; Operand 4: GPR (destination)
999 (define_peephole2
1000   [(parallel
1001        [(set (match_operand:SI 0 "register_operand")
1002              (mult:SI (match_operand:SI 1 "register_operand")
1003                       (match_operand:SI 2 "register_operand")))
1004         (clobber (match_operand:SI 3 "register_operand"))])
1005    (set (match_operand:SI 4 "register_operand")
1006         (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1007   "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1008   [(set (match_dup 0)
1009         (const_int 0))
1010    (parallel
1011        [(set (match_dup 0)
1012              (plus:SI (mult:SI (match_dup 1)
1013                                (match_dup 2))
1014                       (match_dup 0)))
1015         (set (match_dup 4)
1016              (plus:SI (mult:SI (match_dup 1)
1017                                (match_dup 2))
1018                       (match_dup 0)))
1019         (clobber (match_dup 3))])])
1020
1021 ;; Multiply-accumulate patterns
1022
1023 ;; For processors that can copy the output to a general register:
1024 ;;
1025 ;; The all-d alternative is needed because the combiner will find this
1026 ;; pattern and then register alloc/reload will move registers around to
1027 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1028 ;;
1029 ;; The last alternative should be made slightly less desirable, but adding
1030 ;; "?" to the constraint is too strong, and causes values to be loaded into
1031 ;; LO even when that's more costly.  For now, using "*d" mostly does the
1032 ;; trick.
1033 (define_insn "*mul_acc_si"
1034   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1035         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1036                           (match_operand:SI 2 "register_operand" "d,d,d"))
1037                  (match_operand:SI 3 "register_operand" "0,l,*d")))
1038    (clobber (match_scratch:SI 4 "=h,h,h"))
1039    (clobber (match_scratch:SI 5 "=X,3,l"))
1040    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1041   "(TARGET_MIPS3900
1042    || ISA_HAS_MADD_MSUB)
1043    && !TARGET_MIPS16"
1044 {
1045   static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1046   if (which_alternative == 2)
1047     return "#";
1048   if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1049     return "#";
1050   return madd[which_alternative];
1051 }
1052   [(set_attr "type"     "imadd,imadd,multi")
1053    (set_attr "mode"     "SI")
1054    (set_attr "length"   "4,4,8")])
1055
1056 ;; Split the above insn if we failed to get LO allocated.
1057 (define_split
1058   [(set (match_operand:SI 0 "register_operand")
1059         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1060                           (match_operand:SI 2 "register_operand"))
1061                  (match_operand:SI 3 "register_operand")))
1062    (clobber (match_scratch:SI 4))
1063    (clobber (match_scratch:SI 5))
1064    (clobber (match_scratch:SI 6))]
1065   "reload_completed && !TARGET_DEBUG_D_MODE
1066    && GP_REG_P (true_regnum (operands[0]))
1067    && GP_REG_P (true_regnum (operands[3]))"
1068   [(parallel [(set (match_dup 6)
1069                    (mult:SI (match_dup 1) (match_dup 2)))
1070               (clobber (match_dup 4))
1071               (clobber (match_dup 5))])
1072    (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1073   "")
1074
1075 ;; Splitter to copy result of MADD to a general register
1076 (define_split
1077   [(set (match_operand:SI                   0 "register_operand")
1078         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1079                           (match_operand:SI 2 "register_operand"))
1080                  (match_operand:SI          3 "register_operand")))
1081    (clobber (match_scratch:SI               4))
1082    (clobber (match_scratch:SI               5))
1083    (clobber (match_scratch:SI               6))]
1084   "reload_completed && !TARGET_DEBUG_D_MODE
1085    && GP_REG_P (true_regnum (operands[0]))
1086    && true_regnum (operands[3]) == LO_REGNUM"
1087   [(parallel [(set (match_dup 3)
1088                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1089                             (match_dup 3)))
1090               (clobber (match_dup 4))
1091               (clobber (match_dup 5))
1092               (clobber (match_dup 6))])
1093    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1094   "")
1095
1096 (define_insn "*macc"
1097   [(set (match_operand:SI 0 "register_operand" "=l,d")
1098         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1099                           (match_operand:SI 2 "register_operand" "d,d"))
1100                  (match_operand:SI 3 "register_operand" "0,l")))
1101    (clobber (match_scratch:SI 4 "=h,h"))
1102    (clobber (match_scratch:SI 5 "=X,3"))]
1103   "ISA_HAS_MACC"
1104 {
1105   if (which_alternative == 1)
1106     return "macc\t%0,%1,%2";
1107   else if (TARGET_MIPS5500)
1108     return "madd\t%1,%2";
1109   else
1110     /* The VR4130 assumes that there is a two-cycle latency between a macc
1111        that "writes" to $0 and an instruction that reads from it.  We avoid
1112        this by assigning to $1 instead.  */
1113     return "%[macc\t%@,%1,%2%]";
1114 }
1115   [(set_attr "type" "imadd")
1116    (set_attr "mode" "SI")])
1117
1118 (define_insn "*msac"
1119   [(set (match_operand:SI 0 "register_operand" "=l,d")
1120         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1121                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1122                            (match_operand:SI 3 "register_operand" "d,d"))))
1123    (clobber (match_scratch:SI 4 "=h,h"))
1124    (clobber (match_scratch:SI 5 "=X,1"))]
1125   "ISA_HAS_MSAC"
1126 {
1127   if (which_alternative == 1)
1128     return "msac\t%0,%2,%3";
1129   else if (TARGET_MIPS5500)
1130     return "msub\t%2,%3";
1131   else
1132     return "msac\t$0,%2,%3";
1133 }
1134   [(set_attr "type"     "imadd")
1135    (set_attr "mode"     "SI")])
1136
1137 ;; An msac-like instruction implemented using negation and a macc.
1138 (define_insn_and_split "*msac_using_macc"
1139   [(set (match_operand:SI 0 "register_operand" "=l,d")
1140         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1141                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1142                            (match_operand:SI 3 "register_operand" "d,d"))))
1143    (clobber (match_scratch:SI 4 "=h,h"))
1144    (clobber (match_scratch:SI 5 "=X,1"))
1145    (clobber (match_scratch:SI 6 "=d,d"))]
1146   "ISA_HAS_MACC && !ISA_HAS_MSAC"
1147   "#"
1148   "&& reload_completed"
1149   [(set (match_dup 6)
1150         (neg:SI (match_dup 3)))
1151    (parallel
1152        [(set (match_dup 0)
1153              (plus:SI (mult:SI (match_dup 2)
1154                                (match_dup 6))
1155                       (match_dup 1)))
1156         (clobber (match_dup 4))
1157         (clobber (match_dup 5))])]
1158   ""
1159   [(set_attr "type"     "imadd")
1160    (set_attr "length"   "8")])
1161
1162 ;; Patterns generated by the define_peephole2 below.
1163
1164 (define_insn "*macc2"
1165   [(set (match_operand:SI 0 "register_operand" "=l")
1166         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1167                           (match_operand:SI 2 "register_operand" "d"))
1168                  (match_dup 0)))
1169    (set (match_operand:SI 3 "register_operand" "=d")
1170         (plus:SI (mult:SI (match_dup 1)
1171                           (match_dup 2))
1172                  (match_dup 0)))
1173    (clobber (match_scratch:SI 4 "=h"))]
1174   "ISA_HAS_MACC && reload_completed"
1175   "macc\t%3,%1,%2"
1176   [(set_attr "type"     "imadd")
1177    (set_attr "mode"     "SI")])
1178
1179 (define_insn "*msac2"
1180   [(set (match_operand:SI 0 "register_operand" "=l")
1181         (minus:SI (match_dup 0)
1182                   (mult:SI (match_operand:SI 1 "register_operand" "d")
1183                            (match_operand:SI 2 "register_operand" "d"))))
1184    (set (match_operand:SI 3 "register_operand" "=d")
1185         (minus:SI (match_dup 0)
1186                   (mult:SI (match_dup 1)
1187                            (match_dup 2))))
1188    (clobber (match_scratch:SI 4 "=h"))]
1189   "ISA_HAS_MSAC && reload_completed"
1190   "msac\t%3,%1,%2"
1191   [(set_attr "type"     "imadd")
1192    (set_attr "mode"     "SI")])
1193
1194 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1195 ;; Similarly msac.
1196 ;;
1197 ;; Operand 0: LO
1198 ;; Operand 1: macc/msac
1199 ;; Operand 2: HI
1200 ;; Operand 3: GPR (destination)
1201 (define_peephole2
1202   [(parallel
1203        [(set (match_operand:SI 0 "register_operand")
1204              (match_operand:SI 1 "macc_msac_operand"))
1205         (clobber (match_operand:SI 2 "register_operand"))
1206         (clobber (scratch:SI))])
1207    (set (match_operand:SI 3 "register_operand")
1208         (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1209   ""
1210   [(parallel [(set (match_dup 0)
1211                    (match_dup 1))
1212               (set (match_dup 3)
1213                    (match_dup 1))
1214               (clobber (match_dup 2))])]
1215   "")
1216
1217 ;; When we have a three-address multiplication instruction, it should
1218 ;; be faster to do a separate multiply and add, rather than moving
1219 ;; something into LO in order to use a macc instruction.
1220 ;;
1221 ;; This peephole needs a scratch register to cater for the case when one
1222 ;; of the multiplication operands is the same as the destination.
1223 ;;
1224 ;; Operand 0: GPR (scratch)
1225 ;; Operand 1: LO
1226 ;; Operand 2: GPR (addend)
1227 ;; Operand 3: GPR (destination)
1228 ;; Operand 4: macc/msac
1229 ;; Operand 5: HI
1230 ;; Operand 6: new multiplication
1231 ;; Operand 7: new addition/subtraction
1232 (define_peephole2
1233   [(match_scratch:SI 0 "d")
1234    (set (match_operand:SI 1 "register_operand")
1235         (match_operand:SI 2 "register_operand"))
1236    (match_dup 0)
1237    (parallel
1238        [(set (match_operand:SI 3 "register_operand")
1239              (match_operand:SI 4 "macc_msac_operand"))
1240         (clobber (match_operand:SI 5 "register_operand"))
1241         (clobber (match_dup 1))])]
1242   "GENERATE_MULT3_SI
1243    && true_regnum (operands[1]) == LO_REGNUM
1244    && peep2_reg_dead_p (2, operands[1])
1245    && GP_REG_P (true_regnum (operands[3]))"
1246   [(parallel [(set (match_dup 0)
1247                    (match_dup 6))
1248               (clobber (match_dup 5))
1249               (clobber (match_dup 1))])
1250    (set (match_dup 3)
1251         (match_dup 7))]
1252 {
1253   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1254   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1255                                 operands[2], operands[0]);
1256 })
1257
1258 ;; Same as above, except LO is the initial target of the macc.
1259 ;;
1260 ;; Operand 0: GPR (scratch)
1261 ;; Operand 1: LO
1262 ;; Operand 2: GPR (addend)
1263 ;; Operand 3: macc/msac
1264 ;; Operand 4: HI
1265 ;; Operand 5: GPR (destination)
1266 ;; Operand 6: new multiplication
1267 ;; Operand 7: new addition/subtraction
1268 (define_peephole2
1269   [(match_scratch:SI 0 "d")
1270    (set (match_operand:SI 1 "register_operand")
1271         (match_operand:SI 2 "register_operand"))
1272    (match_dup 0)
1273    (parallel
1274        [(set (match_dup 1)
1275              (match_operand:SI 3 "macc_msac_operand"))
1276         (clobber (match_operand:SI 4 "register_operand"))
1277         (clobber (scratch:SI))])
1278    (match_dup 0)
1279    (set (match_operand:SI 5 "register_operand")
1280         (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1281   "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1282   [(parallel [(set (match_dup 0)
1283                    (match_dup 6))
1284               (clobber (match_dup 4))
1285               (clobber (match_dup 1))])
1286    (set (match_dup 5)
1287         (match_dup 7))]
1288 {
1289   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1290   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1291                                 operands[2], operands[0]);
1292 })
1293
1294 (define_insn "*mul_sub_si"
1295   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1296         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1297                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1298                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1299    (clobber (match_scratch:SI 4 "=h,h,h"))
1300    (clobber (match_scratch:SI 5 "=X,1,l"))
1301    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1302   "ISA_HAS_MADD_MSUB"
1303   "@
1304    msub\t%2,%3
1305    #
1306    #"
1307   [(set_attr "type"     "imadd,multi,multi")
1308    (set_attr "mode"     "SI")
1309    (set_attr "length"   "4,8,8")])
1310
1311 ;; Split the above insn if we failed to get LO allocated.
1312 (define_split
1313   [(set (match_operand:SI 0 "register_operand")
1314         (minus:SI (match_operand:SI 1 "register_operand")
1315                   (mult:SI (match_operand:SI 2 "register_operand")
1316                            (match_operand:SI 3 "register_operand"))))
1317    (clobber (match_scratch:SI 4))
1318    (clobber (match_scratch:SI 5))
1319    (clobber (match_scratch:SI 6))]
1320   "reload_completed && !TARGET_DEBUG_D_MODE
1321    && GP_REG_P (true_regnum (operands[0]))
1322    && GP_REG_P (true_regnum (operands[1]))"
1323   [(parallel [(set (match_dup 6)
1324                    (mult:SI (match_dup 2) (match_dup 3)))
1325               (clobber (match_dup 4))
1326               (clobber (match_dup 5))])
1327    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1328   "")
1329
1330 ;; Splitter to copy result of MSUB to a general register
1331 (define_split
1332   [(set (match_operand:SI 0 "register_operand")
1333         (minus:SI (match_operand:SI 1 "register_operand")
1334                   (mult:SI (match_operand:SI 2 "register_operand")
1335                            (match_operand:SI 3 "register_operand"))))
1336    (clobber (match_scratch:SI 4))
1337    (clobber (match_scratch:SI 5))
1338    (clobber (match_scratch:SI 6))]
1339   "reload_completed && !TARGET_DEBUG_D_MODE
1340    && GP_REG_P (true_regnum (operands[0]))
1341    && true_regnum (operands[1]) == LO_REGNUM"
1342   [(parallel [(set (match_dup 1)
1343                    (minus:SI (match_dup 1)
1344                              (mult:SI (match_dup 2) (match_dup 3))))
1345               (clobber (match_dup 4))
1346               (clobber (match_dup 5))
1347               (clobber (match_dup 6))])
1348    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1349   "")
1350
1351 (define_insn "*muls"
1352   [(set (match_operand:SI                  0 "register_operand" "=l,d")
1353         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1354                          (match_operand:SI 2 "register_operand" "d,d"))))
1355    (clobber (match_scratch:SI              3                    "=h,h"))
1356    (clobber (match_scratch:SI              4                    "=X,l"))]
1357   "ISA_HAS_MULS"
1358   "@
1359    muls\t$0,%1,%2
1360    muls\t%0,%1,%2"
1361   [(set_attr "type"     "imul")
1362    (set_attr "mode"     "SI")])
1363
1364 (define_expand "muldi3"
1365   [(set (match_operand:DI 0 "register_operand")
1366         (mult:DI (match_operand:DI 1 "register_operand")
1367                  (match_operand:DI 2 "register_operand")))]
1368   "TARGET_64BIT"
1369 {
1370   if (GENERATE_MULT3_DI)
1371     emit_insn (gen_muldi3_mult3 (operands[0], operands[1], operands[2]));
1372   else if (!TARGET_FIX_R4000)
1373     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1374   else
1375     emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
1376   DONE;
1377 })
1378
1379 (define_insn "muldi3_mult3"
1380   [(set (match_operand:DI 0 "register_operand" "=d")
1381         (mult:DI (match_operand:DI 1 "register_operand" "d")
1382                  (match_operand:DI 2 "register_operand" "d")))
1383    (clobber (match_scratch:DI 3 "=h"))
1384    (clobber (match_scratch:DI 4 "=l"))]
1385   "TARGET_64BIT && GENERATE_MULT3_DI"
1386   "dmult\t%0,%1,%2"
1387   [(set_attr "type"     "imul")
1388    (set_attr "mode"     "DI")])
1389
1390 (define_insn "muldi3_internal"
1391   [(set (match_operand:DI 0 "register_operand" "=l")
1392         (mult:DI (match_operand:DI 1 "register_operand" "d")
1393                  (match_operand:DI 2 "register_operand" "d")))
1394    (clobber (match_scratch:DI 3 "=h"))]
1395   "TARGET_64BIT && !TARGET_FIX_R4000"
1396   "dmult\t%1,%2"
1397   [(set_attr "type"     "imul")
1398    (set_attr "mode"     "DI")])
1399
1400 (define_insn "muldi3_r4000"
1401   [(set (match_operand:DI 0 "register_operand" "=d")
1402         (mult:DI (match_operand:DI 1 "register_operand" "d")
1403                  (match_operand:DI 2 "register_operand" "d")))
1404    (clobber (match_scratch:DI 3 "=h"))
1405    (clobber (match_scratch:DI 4 "=l"))]
1406   "TARGET_64BIT && TARGET_FIX_R4000"
1407   "dmult\t%1,%2\;mflo\t%0"
1408   [(set_attr "type"     "imul")
1409    (set_attr "mode"     "DI")
1410    (set_attr "length"   "8")])
1411
1412 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1413
1414 (define_expand "mulsidi3"
1415   [(parallel
1416       [(set (match_operand:DI 0 "register_operand")
1417             (mult:DI
1418                (sign_extend:DI (match_operand:SI 1 "register_operand"))
1419                (sign_extend:DI (match_operand:SI 2 "register_operand"))))
1420        (clobber (scratch:DI))
1421        (clobber (scratch:DI))
1422        (clobber (scratch:DI))])]
1423   "!TARGET_64BIT || !TARGET_FIX_R4000"
1424 {
1425   if (!TARGET_64BIT)
1426     {
1427       if (!TARGET_FIX_R4000)
1428         emit_insn (gen_mulsidi3_32bit_internal (operands[0], operands[1],
1429                                                 operands[2]));
1430       else
1431         emit_insn (gen_mulsidi3_32bit_r4000 (operands[0], operands[1],
1432                                              operands[2]));
1433       DONE;
1434     }
1435 })
1436
1437 (define_insn "mulsidi3_32bit_internal"
1438   [(set (match_operand:DI 0 "register_operand" "=x")
1439         (mult:DI
1440            (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1441            (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1442   "!TARGET_64BIT && !TARGET_FIX_R4000"
1443   "mult\t%1,%2"
1444   [(set_attr "type"     "imul")
1445    (set_attr "mode"     "SI")])
1446
1447 (define_insn "mulsidi3_32bit_r4000"
1448   [(set (match_operand:DI 0 "register_operand" "=d")
1449         (mult:DI
1450            (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1451            (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1452    (clobber (match_scratch:DI 3 "=x"))]
1453   "!TARGET_64BIT && TARGET_FIX_R4000"
1454   "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1455   [(set_attr "type"     "imul")
1456    (set_attr "mode"     "SI")
1457    (set_attr "length"   "12")])
1458
1459 (define_insn_and_split "*mulsidi3_64bit"
1460   [(set (match_operand:DI 0 "register_operand" "=d")
1461         (mult:DI (match_operator:DI 1 "extend_operator"
1462                     [(match_operand:SI 3 "register_operand" "d")])
1463                  (match_operator:DI 2 "extend_operator"
1464                     [(match_operand:SI 4 "register_operand" "d")])))
1465    (clobber (match_scratch:DI 5 "=l"))
1466    (clobber (match_scratch:DI 6 "=h"))
1467    (clobber (match_scratch:DI 7 "=d"))]
1468   "TARGET_64BIT && !TARGET_FIX_R4000
1469    && GET_CODE (operands[1]) == GET_CODE (operands[2])"
1470   "#"
1471   "&& reload_completed"
1472   [(parallel
1473        [(set (match_dup 5)
1474              (sign_extend:DI
1475                 (mult:SI (match_dup 3)
1476                          (match_dup 4))))
1477         (set (match_dup 6)
1478              (ashiftrt:DI
1479                 (mult:DI (match_dup 1)
1480                          (match_dup 2))
1481                 (const_int 32)))])
1482
1483    ;; OP7 <- LO, OP0 <- HI
1484    (set (match_dup 7) (unspec:DI [(match_dup 5) (match_dup 6)] UNSPEC_MFHILO))
1485    (set (match_dup 0) (unspec:DI [(match_dup 6) (match_dup 5)] UNSPEC_MFHILO))
1486
1487    ;; Zero-extend OP7.
1488    (set (match_dup 7)
1489         (ashift:DI (match_dup 7)
1490                    (const_int 32)))
1491    (set (match_dup 7)
1492         (lshiftrt:DI (match_dup 7)
1493                      (const_int 32)))
1494
1495    ;; Shift OP0 into place.
1496    (set (match_dup 0)
1497         (ashift:DI (match_dup 0)
1498                    (const_int 32)))
1499
1500    ;; OR the two halves together
1501    (set (match_dup 0)
1502         (ior:DI (match_dup 0)
1503                 (match_dup 7)))]
1504   ""
1505   [(set_attr "type"     "imul")
1506    (set_attr "mode"     "SI")
1507    (set_attr "length"   "24")])
1508
1509 (define_insn "*mulsidi3_64bit_parts"
1510   [(set (match_operand:DI 0 "register_operand" "=l")
1511         (sign_extend:DI
1512            (mult:SI (match_operand:SI 2 "register_operand" "d")
1513                     (match_operand:SI 3 "register_operand" "d"))))
1514    (set (match_operand:DI 1 "register_operand" "=h")
1515         (ashiftrt:DI
1516            (mult:DI
1517               (match_operator:DI 4 "extend_operator" [(match_dup 2)])
1518               (match_operator:DI 5 "extend_operator" [(match_dup 3)]))
1519            (const_int 32)))]
1520   "TARGET_64BIT && !TARGET_FIX_R4000
1521    && GET_CODE (operands[4]) == GET_CODE (operands[5])"
1522 {
1523   if (GET_CODE (operands[4]) == SIGN_EXTEND)
1524     return "mult\t%2,%3";
1525   else
1526     return "multu\t%2,%3";
1527 }
1528   [(set_attr "type" "imul")
1529    (set_attr "mode" "SI")])
1530
1531 (define_expand "umulsidi3"
1532   [(parallel
1533       [(set (match_operand:DI 0 "register_operand")
1534             (mult:DI
1535                (zero_extend:DI (match_operand:SI 1 "register_operand"))
1536                (zero_extend:DI (match_operand:SI 2 "register_operand"))))
1537        (clobber (scratch:DI))
1538        (clobber (scratch:DI))
1539        (clobber (scratch:DI))])]
1540   "!TARGET_64BIT || !TARGET_FIX_R4000"
1541 {
1542   if (!TARGET_64BIT)
1543     {
1544       if (!TARGET_FIX_R4000)
1545         emit_insn (gen_umulsidi3_32bit_internal (operands[0], operands[1],
1546                                                  operands[2]));
1547       else
1548         emit_insn (gen_umulsidi3_32bit_r4000 (operands[0], operands[1],
1549                                               operands[2]));
1550       DONE;
1551     }
1552 })
1553
1554 (define_insn "umulsidi3_32bit_internal"
1555   [(set (match_operand:DI 0 "register_operand" "=x")
1556         (mult:DI
1557            (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1558            (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1559   "!TARGET_64BIT && !TARGET_FIX_R4000"
1560   "multu\t%1,%2"
1561   [(set_attr "type"     "imul")
1562    (set_attr "mode"     "SI")])
1563
1564 (define_insn "umulsidi3_32bit_r4000"
1565   [(set (match_operand:DI 0 "register_operand" "=d")
1566         (mult:DI
1567            (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1568            (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1569    (clobber (match_scratch:DI 3 "=x"))]
1570   "!TARGET_64BIT && TARGET_FIX_R4000"
1571   "multu\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1572   [(set_attr "type"     "imul")
1573    (set_attr "mode"     "SI")
1574    (set_attr "length"   "12")])
1575
1576 ;; Widening multiply with negation.
1577 (define_insn "*muls_di"
1578   [(set (match_operand:DI 0 "register_operand" "=x")
1579         (neg:DI
1580          (mult:DI
1581           (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1582           (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1583   "!TARGET_64BIT && ISA_HAS_MULS"
1584   "muls\t$0,%1,%2"
1585   [(set_attr "type"     "imul")
1586    (set_attr "length"   "4")
1587    (set_attr "mode"     "SI")])
1588
1589 (define_insn "*umuls_di"
1590   [(set (match_operand:DI 0 "register_operand" "=x")
1591         (neg:DI
1592          (mult:DI
1593           (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1594           (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1595   "!TARGET_64BIT && ISA_HAS_MULS"
1596   "mulsu\t$0,%1,%2"
1597   [(set_attr "type"     "imul")
1598    (set_attr "length"   "4")
1599    (set_attr "mode"     "SI")])
1600
1601 (define_insn "*smsac_di"
1602   [(set (match_operand:DI 0 "register_operand" "=x")
1603         (minus:DI
1604            (match_operand:DI 3 "register_operand" "0")
1605            (mult:DI
1606               (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1607               (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1608   "!TARGET_64BIT && ISA_HAS_MSAC"
1609 {
1610   if (TARGET_MIPS5500)
1611     return "msub\t%1,%2";
1612   else
1613     return "msac\t$0,%1,%2";
1614 }
1615   [(set_attr "type"     "imadd")
1616    (set_attr "length"   "4")
1617    (set_attr "mode"     "SI")])
1618
1619 (define_insn "*umsac_di"
1620   [(set (match_operand:DI 0 "register_operand" "=x")
1621         (minus:DI
1622            (match_operand:DI 3 "register_operand" "0")
1623            (mult:DI
1624               (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1625               (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1626   "!TARGET_64BIT && ISA_HAS_MSAC"
1627 {
1628   if (TARGET_MIPS5500)
1629     return "msubu\t%1,%2";
1630   else
1631     return "msacu\t$0,%1,%2";
1632 }
1633   [(set_attr "type"     "imadd")
1634    (set_attr "length"   "4")
1635    (set_attr "mode"     "SI")])
1636
1637 ;; _highpart patterns
1638 (define_expand "umulsi3_highpart"
1639   [(set (match_operand:SI 0 "register_operand")
1640         (truncate:SI
1641          (lshiftrt:DI
1642           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"))
1643                    (zero_extend:DI (match_operand:SI 2 "register_operand")))
1644           (const_int 32))))]
1645   "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1646 {
1647   if (ISA_HAS_MULHI)
1648     emit_insn (gen_umulsi3_highpart_mulhi_internal (operands[0], operands[1],
1649                                                     operands[2]));
1650   else
1651     emit_insn (gen_umulsi3_highpart_internal (operands[0], operands[1],
1652                                               operands[2]));
1653   DONE;
1654 })
1655
1656 (define_insn "umulsi3_highpart_internal"
1657   [(set (match_operand:SI 0 "register_operand" "=h")
1658         (truncate:SI
1659          (lshiftrt:DI
1660           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1661                    (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1662           (const_int 32))))
1663    (clobber (match_scratch:SI 3 "=l"))]
1664   "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1665   "multu\t%1,%2"
1666   [(set_attr "type"   "imul")
1667    (set_attr "mode"   "SI")
1668    (set_attr "length" "4")])
1669
1670 (define_insn "umulsi3_highpart_mulhi_internal"
1671   [(set (match_operand:SI 0 "register_operand" "=h,d")
1672         (truncate:SI
1673          (lshiftrt:DI
1674           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1675                    (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1676           (const_int 32))))
1677    (clobber (match_scratch:SI 3 "=l,l"))
1678    (clobber (match_scratch:SI 4 "=X,h"))]
1679   "ISA_HAS_MULHI"
1680   "@
1681    multu\t%1,%2
1682    mulhiu\t%0,%1,%2"
1683   [(set_attr "type"   "imul")
1684    (set_attr "mode"   "SI")
1685    (set_attr "length" "4")])
1686
1687 (define_insn "umulsi3_highpart_neg_mulhi_internal"
1688   [(set (match_operand:SI 0 "register_operand" "=h,d")
1689         (truncate:SI
1690          (lshiftrt:DI
1691           (neg:DI
1692            (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1693                     (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1694           (const_int 32))))
1695    (clobber (match_scratch:SI 3 "=l,l"))
1696    (clobber (match_scratch:SI 4 "=X,h"))]
1697   "ISA_HAS_MULHI"
1698   "@
1699    mulshiu\t%.,%1,%2
1700    mulshiu\t%0,%1,%2"
1701   [(set_attr "type"   "imul")
1702    (set_attr "mode"   "SI")
1703    (set_attr "length" "4")])
1704
1705 (define_expand "smulsi3_highpart"
1706   [(set (match_operand:SI 0 "register_operand")
1707         (truncate:SI
1708          (lshiftrt:DI
1709           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"))
1710                    (sign_extend:DI (match_operand:SI 2 "register_operand")))
1711          (const_int 32))))]
1712   "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1713 {
1714   if (ISA_HAS_MULHI)
1715     emit_insn (gen_smulsi3_highpart_mulhi_internal (operands[0], operands[1],
1716                                                     operands[2]));
1717   else
1718     emit_insn (gen_smulsi3_highpart_internal (operands[0], operands[1],
1719                                               operands[2]));
1720   DONE;
1721 })
1722
1723 (define_insn "smulsi3_highpart_internal"
1724   [(set (match_operand:SI 0 "register_operand" "=h")
1725         (truncate:SI
1726          (lshiftrt:DI
1727           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1728                    (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1729           (const_int 32))))
1730    (clobber (match_scratch:SI 3 "=l"))]
1731   "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1732   "mult\t%1,%2"
1733   [(set_attr "type"     "imul")
1734    (set_attr "mode"     "SI")
1735    (set_attr "length"   "4")])
1736
1737 (define_insn "smulsi3_highpart_mulhi_internal"
1738   [(set (match_operand:SI 0 "register_operand" "=h,d")
1739         (truncate:SI
1740          (lshiftrt:DI
1741           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1742                    (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1743           (const_int 32))))
1744    (clobber (match_scratch:SI 3 "=l,l"))
1745    (clobber (match_scratch:SI 4 "=X,h"))]
1746   "ISA_HAS_MULHI"
1747   "@
1748    mult\t%1,%2
1749    mulhi\t%0,%1,%2"
1750   [(set_attr "type"   "imul")
1751    (set_attr "mode"   "SI")
1752    (set_attr "length" "4")])
1753
1754 (define_insn "smulsi3_highpart_neg_mulhi_internal"
1755   [(set (match_operand:SI 0 "register_operand" "=h,d")
1756         (truncate:SI
1757          (lshiftrt:DI
1758           (neg:DI
1759            (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1760                     (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1761           (const_int 32))))
1762    (clobber (match_scratch:SI 3 "=l,l"))
1763    (clobber (match_scratch:SI 4 "=X,h"))]
1764   "ISA_HAS_MULHI"
1765   "@
1766    mulshi\t%.,%1,%2
1767    mulshi\t%0,%1,%2"
1768   [(set_attr "type"   "imul")
1769    (set_attr "mode"   "SI")])
1770
1771 (define_insn "smuldi3_highpart"
1772   [(set (match_operand:DI 0 "register_operand" "=h")
1773         (truncate:DI
1774          (lshiftrt:TI
1775           (mult:TI
1776            (sign_extend:TI (match_operand:DI 1 "register_operand" "d"))
1777            (sign_extend:TI (match_operand:DI 2 "register_operand" "d")))
1778          (const_int 64))))
1779    (clobber (match_scratch:DI 3 "=l"))]
1780   "TARGET_64BIT && !TARGET_FIX_R4000"
1781   "dmult\t%1,%2"
1782   [(set_attr "type"     "imul")
1783    (set_attr "mode"     "DI")])
1784
1785 ;; Disable this pattern for -mfix-vr4120.  This is for VR4120 errata MD(0),
1786 ;; which says that dmultu does not always produce the correct result.
1787 (define_insn "umuldi3_highpart"
1788   [(set (match_operand:DI 0 "register_operand" "=h")
1789         (truncate:DI
1790          (lshiftrt:TI
1791           (mult:TI
1792            (zero_extend:TI (match_operand:DI 1 "register_operand" "d"))
1793            (zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
1794           (const_int 64))))
1795    (clobber (match_scratch:DI 3 "=l"))]
1796   "TARGET_64BIT && !TARGET_FIX_R4000 && !TARGET_FIX_VR4120"
1797   "dmultu\t%1,%2"
1798   [(set_attr "type"     "imul")
1799    (set_attr "mode"     "DI")])
1800
1801
1802 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1803 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
1804
1805 (define_insn "madsi"
1806   [(set (match_operand:SI 0 "register_operand" "+l")
1807         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1808                           (match_operand:SI 2 "register_operand" "d"))
1809                  (match_dup 0)))
1810    (clobber (match_scratch:SI 3 "=h"))]
1811   "TARGET_MAD"
1812   "mad\t%1,%2"
1813   [(set_attr "type"     "imadd")
1814    (set_attr "mode"     "SI")])
1815
1816 (define_insn "*umul_acc_di"
1817   [(set (match_operand:DI 0 "register_operand" "=x")
1818         (plus:DI
1819          (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1820                   (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1821          (match_operand:DI 3 "register_operand" "0")))]
1822   "(TARGET_MAD || ISA_HAS_MACC)
1823    && !TARGET_64BIT"
1824 {
1825   if (TARGET_MAD)
1826     return "madu\t%1,%2";
1827   else if (TARGET_MIPS5500)
1828     return "maddu\t%1,%2";
1829   else
1830     /* See comment in *macc.  */
1831     return "%[maccu\t%@,%1,%2%]";
1832 }
1833   [(set_attr "type"   "imadd")
1834    (set_attr "mode"   "SI")])
1835
1836
1837 (define_insn "*smul_acc_di"
1838   [(set (match_operand:DI 0 "register_operand" "=x")
1839         (plus:DI
1840          (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1841                   (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1842          (match_operand:DI 3 "register_operand" "0")))]
1843   "(TARGET_MAD || ISA_HAS_MACC)
1844    && !TARGET_64BIT"
1845 {
1846   if (TARGET_MAD)
1847     return "mad\t%1,%2";
1848   else if (TARGET_MIPS5500)
1849     return "madd\t%1,%2";
1850   else
1851     /* See comment in *macc.  */
1852     return "%[macc\t%@,%1,%2%]";
1853 }
1854   [(set_attr "type"   "imadd")
1855    (set_attr "mode"   "SI")])
1856
1857 ;; Floating point multiply accumulate instructions.
1858
1859 (define_insn ""
1860   [(set (match_operand:DF 0 "register_operand" "=f")
1861         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1862                           (match_operand:DF 2 "register_operand" "f"))
1863                  (match_operand:DF 3 "register_operand" "f")))]
1864   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1865   "madd.d\t%0,%3,%1,%2"
1866   [(set_attr "type"     "fmadd")
1867    (set_attr "mode"     "DF")])
1868
1869 (define_insn ""
1870   [(set (match_operand:SF 0 "register_operand" "=f")
1871         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1872                           (match_operand:SF 2 "register_operand" "f"))
1873                  (match_operand:SF 3 "register_operand" "f")))]
1874   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1875   "madd.s\t%0,%3,%1,%2"
1876   [(set_attr "type"     "fmadd")
1877    (set_attr "mode"     "SF")])
1878
1879 (define_insn ""
1880   [(set (match_operand:DF 0 "register_operand" "=f")
1881         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1882                            (match_operand:DF 2 "register_operand" "f"))
1883                   (match_operand:DF 3 "register_operand" "f")))]
1884   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1885   "msub.d\t%0,%3,%1,%2"
1886   [(set_attr "type"     "fmadd")
1887    (set_attr "mode"     "DF")])
1888
1889 (define_insn ""
1890   [(set (match_operand:SF 0 "register_operand" "=f")
1891         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1892                            (match_operand:SF 2 "register_operand" "f"))
1893                   (match_operand:SF 3 "register_operand" "f")))]
1894
1895   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1896   "msub.s\t%0,%3,%1,%2"
1897   [(set_attr "type"     "fmadd")
1898    (set_attr "mode"     "SF")])
1899
1900 (define_insn ""
1901   [(set (match_operand:DF 0 "register_operand" "=f")
1902         (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1903                                   (match_operand:DF 2 "register_operand" "f"))
1904                          (match_operand:DF 3 "register_operand" "f"))))]
1905   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1906   "nmadd.d\t%0,%3,%1,%2"
1907   [(set_attr "type"     "fmadd")
1908    (set_attr "mode"     "DF")])
1909
1910 (define_insn ""
1911   [(set (match_operand:SF 0 "register_operand" "=f")
1912         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1913                                   (match_operand:SF 2 "register_operand" "f"))
1914                          (match_operand:SF 3 "register_operand" "f"))))]
1915   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1916   "nmadd.s\t%0,%3,%1,%2"
1917   [(set_attr "type"     "fmadd")
1918    (set_attr "mode"     "SF")])
1919
1920 (define_insn ""
1921   [(set (match_operand:DF 0 "register_operand" "=f")
1922         (minus:DF (match_operand:DF 1 "register_operand" "f")
1923                   (mult:DF (match_operand:DF 2 "register_operand" "f")
1924                            (match_operand:DF 3 "register_operand" "f"))))]
1925   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1926   "nmsub.d\t%0,%1,%2,%3"
1927   [(set_attr "type"     "fmadd")
1928    (set_attr "mode"     "DF")])
1929
1930 (define_insn ""
1931   [(set (match_operand:SF 0 "register_operand" "=f")
1932         (minus:SF (match_operand:SF 1 "register_operand" "f")
1933                   (mult:SF (match_operand:SF 2 "register_operand" "f")
1934                            (match_operand:SF 3 "register_operand" "f"))))]
1935   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1936   "nmsub.s\t%0,%1,%2,%3"
1937   [(set_attr "type"     "fmadd")
1938    (set_attr "mode"     "SF")])
1939 \f
1940 ;;
1941 ;;  ....................
1942 ;;
1943 ;;      DIVISION and REMAINDER
1944 ;;
1945 ;;  ....................
1946 ;;
1947
1948 (define_expand "divdf3"
1949   [(set (match_operand:DF 0 "register_operand")
1950         (div:DF (match_operand:DF 1 "reg_or_const_float_1_operand")
1951                 (match_operand:DF 2 "register_operand")))]
1952   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1953 {
1954   if (const_float_1_operand (operands[1], DFmode))
1955     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1956       operands[1] = force_reg (DFmode, operands[1]);
1957 })
1958
1959 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
1960 ;;
1961 ;; If an mfc1 or dmfc1 happens to access the floating point register
1962 ;; file at the same time a long latency operation (div, sqrt, recip,
1963 ;; sqrt) iterates an intermediate result back through the floating
1964 ;; point register file bypass, then instead returning the correct
1965 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1966 ;; result of the long latency operation.
1967 ;;
1968 ;; The workaround is to insert an unconditional 'mov' from/to the
1969 ;; long latency op destination register.
1970
1971 (define_insn "*divdf3"
1972   [(set (match_operand:DF 0 "register_operand" "=f")
1973         (div:DF (match_operand:DF 1 "register_operand" "f")
1974                 (match_operand:DF 2 "register_operand" "f")))]
1975   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1976 {
1977   if (TARGET_FIX_SB1)
1978     return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
1979   else
1980     return "div.d\t%0,%1,%2";
1981 }
1982   [(set_attr "type"     "fdiv")
1983    (set_attr "mode"     "DF")
1984    (set (attr "length")
1985         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1986                       (const_int 8)
1987                       (const_int 4)))])
1988
1989
1990 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
1991 ;;
1992 ;; In certain cases, div.s and div.ps may have a rounding error
1993 ;; and/or wrong inexact flag.
1994 ;;
1995 ;; Therefore, we only allow div.s if not working around SB-1 rev2
1996 ;; errata, or if working around those errata and a slight loss of
1997 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
1998 (define_expand "divsf3"
1999   [(set (match_operand:SF 0 "register_operand")
2000         (div:SF (match_operand:SF 1 "reg_or_const_float_1_operand")
2001                 (match_operand:SF 2 "register_operand")))]
2002   "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2003 {
2004   if (const_float_1_operand (operands[1], SFmode))
2005     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2006       operands[1] = force_reg (SFmode, operands[1]);
2007 })
2008
2009 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2010 ;; "divdf3" comment for details).
2011 ;;
2012 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
2013 ;; "divsf3" comment for details).
2014 (define_insn "*divsf3"
2015   [(set (match_operand:SF 0 "register_operand" "=f")
2016         (div:SF (match_operand:SF 1 "register_operand" "f")
2017                 (match_operand:SF 2 "register_operand" "f")))]
2018   "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2019 {
2020   if (TARGET_FIX_SB1)
2021     return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
2022   else
2023     return "div.s\t%0,%1,%2";
2024 }
2025   [(set_attr "type"     "fdiv")
2026    (set_attr "mode"     "SF")
2027    (set (attr "length")
2028         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2029                       (const_int 8)
2030                       (const_int 4)))])
2031
2032 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2033 ;; "divdf3" comment for details).
2034 (define_insn ""
2035   [(set (match_operand:DF 0 "register_operand" "=f")
2036         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2037                 (match_operand:DF 2 "register_operand" "f")))]
2038   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2039 {
2040   if (TARGET_FIX_SB1)
2041     return "recip.d\t%0,%2\;mov.d\t%0,%0";
2042   else
2043     return "recip.d\t%0,%2";
2044 }
2045   [(set_attr "type"     "fdiv")
2046    (set_attr "mode"     "DF")
2047    (set (attr "length")
2048         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2049                       (const_int 8)
2050                       (const_int 4)))])
2051
2052 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2053 ;; "divdf3" comment for details).
2054 (define_insn ""
2055   [(set (match_operand:SF 0 "register_operand" "=f")
2056         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2057                 (match_operand:SF 2 "register_operand" "f")))]
2058   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2059 {
2060   if (TARGET_FIX_SB1)
2061     return "recip.s\t%0,%2\;mov.s\t%0,%0";
2062   else
2063     return "recip.s\t%0,%2";
2064 }
2065   [(set_attr "type"     "fdiv")
2066    (set_attr "mode"     "SF")
2067    (set (attr "length")
2068         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2069                       (const_int 8)
2070                       (const_int 4)))])
2071
2072 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2073 ;; with negative operands.  We use special libgcc functions instead.
2074 (define_insn "divmodsi4"
2075   [(set (match_operand:SI 0 "register_operand" "=l")
2076         (div:SI (match_operand:SI 1 "register_operand" "d")
2077                 (match_operand:SI 2 "register_operand" "d")))
2078    (set (match_operand:SI 3 "register_operand" "=h")
2079         (mod:SI (match_dup 1)
2080                 (match_dup 2)))]
2081   "!TARGET_FIX_VR4120"
2082   { return mips_output_division ("div\t$0,%1,%2", operands); }
2083   [(set_attr "type"     "idiv")
2084    (set_attr "mode"     "SI")])
2085
2086 (define_insn "divmoddi4"
2087   [(set (match_operand:DI 0 "register_operand" "=l")
2088         (div:DI (match_operand:DI 1 "register_operand" "d")
2089                 (match_operand:DI 2 "register_operand" "d")))
2090    (set (match_operand:DI 3 "register_operand" "=h")
2091         (mod:DI (match_dup 1)
2092                 (match_dup 2)))]
2093   "TARGET_64BIT && !TARGET_FIX_VR4120"
2094   { return mips_output_division ("ddiv\t$0,%1,%2", operands); }
2095   [(set_attr "type"     "idiv")
2096    (set_attr "mode"     "DI")])
2097
2098 (define_insn "udivmodsi4"
2099   [(set (match_operand:SI 0 "register_operand" "=l")
2100         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2101                  (match_operand:SI 2 "register_operand" "d")))
2102    (set (match_operand:SI 3 "register_operand" "=h")
2103         (umod:SI (match_dup 1)
2104                  (match_dup 2)))]
2105   ""
2106   { return mips_output_division ("divu\t$0,%1,%2", operands); }
2107   [(set_attr "type"     "idiv")
2108    (set_attr "mode"     "SI")])
2109
2110 (define_insn "udivmoddi4"
2111   [(set (match_operand:DI 0 "register_operand" "=l")
2112         (udiv:DI (match_operand:DI 1 "register_operand" "d")
2113                  (match_operand:DI 2 "register_operand" "d")))
2114    (set (match_operand:DI 3 "register_operand" "=h")
2115         (umod:DI (match_dup 1)
2116                  (match_dup 2)))]
2117   "TARGET_64BIT"
2118   { return mips_output_division ("ddivu\t$0,%1,%2", operands); }
2119   [(set_attr "type"     "idiv")
2120    (set_attr "mode"     "DI")])
2121 \f
2122 ;;
2123 ;;  ....................
2124 ;;
2125 ;;      SQUARE ROOT
2126 ;;
2127 ;;  ....................
2128
2129 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2130 ;; "divdf3" comment for details).
2131 (define_insn "sqrtdf2"
2132   [(set (match_operand:DF 0 "register_operand" "=f")
2133         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2134   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2135 {
2136   if (TARGET_FIX_SB1)
2137     return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
2138   else
2139     return "sqrt.d\t%0,%1";
2140 }
2141   [(set_attr "type"     "fsqrt")
2142    (set_attr "mode"     "DF")
2143    (set (attr "length")
2144         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2145                       (const_int 8)
2146                       (const_int 4)))])
2147
2148 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2149 ;; "divdf3" comment for details).
2150 (define_insn "sqrtsf2"
2151   [(set (match_operand:SF 0 "register_operand" "=f")
2152         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2153   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2154 {
2155   if (TARGET_FIX_SB1)
2156     return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
2157   else
2158     return "sqrt.s\t%0,%1";
2159 }
2160   [(set_attr "type"     "fsqrt")
2161    (set_attr "mode"     "SF")
2162    (set (attr "length")
2163         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2164                       (const_int 8)
2165                       (const_int 4)))])
2166
2167 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2168 ;; "divdf3" comment for details).
2169 (define_insn ""
2170   [(set (match_operand:DF 0 "register_operand" "=f")
2171         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2172                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2173   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2174 {
2175   if (TARGET_FIX_SB1)
2176     return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2177   else
2178     return "rsqrt.d\t%0,%2";
2179 }
2180   [(set_attr "type"     "frsqrt")
2181    (set_attr "mode"     "DF")
2182    (set (attr "length")
2183         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2184                       (const_int 8)
2185                       (const_int 4)))])
2186
2187 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2188 ;; "divdf3" comment for details).
2189 (define_insn ""
2190   [(set (match_operand:SF 0 "register_operand" "=f")
2191         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2192                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2193   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2194 {
2195   if (TARGET_FIX_SB1)
2196     return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2197   else
2198     return "rsqrt.s\t%0,%2";
2199 }
2200   [(set_attr "type"     "frsqrt")
2201    (set_attr "mode"     "SF")
2202    (set (attr "length")
2203         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2204                       (const_int 8)
2205                       (const_int 4)))])
2206 \f
2207 ;;
2208 ;;  ....................
2209 ;;
2210 ;;      ABSOLUTE VALUE
2211 ;;
2212 ;;  ....................
2213
2214 ;; Do not use the integer abs macro instruction, since that signals an
2215 ;; exception on -2147483648 (sigh).
2216
2217 (define_insn "abssi2"
2218   [(set (match_operand:SI 0 "register_operand" "=d")
2219         (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2220   "!TARGET_MIPS16"
2221 {
2222   operands[2] = const0_rtx;
2223
2224   if (REGNO (operands[0]) == REGNO (operands[1]))
2225     {
2226       if (GENERATE_BRANCHLIKELY)
2227         return "%(bltzl\t%1,1f\;subu\t%0,%z2,%0\n%~1:%)";
2228       else
2229         return "bgez\t%1,1f%#\;subu\t%0,%z2,%0\n%~1:";
2230     }
2231   else
2232     return "%(bgez\t%1,1f\;move\t%0,%1\;subu\t%0,%z2,%0\n%~1:%)";
2233 }
2234   [(set_attr "type"     "multi")
2235    (set_attr "mode"     "SI")
2236    (set_attr "length"   "12")])
2237
2238 (define_insn "absdi2"
2239   [(set (match_operand:DI 0 "register_operand" "=d")
2240         (abs:DI (match_operand:DI 1 "register_operand" "d")))]
2241   "TARGET_64BIT && !TARGET_MIPS16"
2242 {
2243   unsigned int regno1;
2244   operands[2] = const0_rtx;
2245
2246   if (GET_CODE (operands[1]) == REG)
2247     regno1 = REGNO (operands[1]);
2248   else
2249     regno1 = REGNO (XEXP (operands[1], 0));
2250
2251   if (REGNO (operands[0]) == regno1)
2252     return "%(bltzl\t%1,1f\;dsubu\t%0,%z2,%0\n%~1:%)";
2253   else
2254     return "%(bgez\t%1,1f\;move\t%0,%1\;dsubu\t%0,%z2,%0\n%~1:%)";
2255 }
2256   [(set_attr "type"     "multi")
2257    (set_attr "mode"     "DI")
2258    (set_attr "length"   "12")])
2259
2260 (define_insn "absdf2"
2261   [(set (match_operand:DF 0 "register_operand" "=f")
2262         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2263   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2264   "abs.d\t%0,%1"
2265   [(set_attr "type"     "fabs")
2266    (set_attr "mode"     "DF")])
2267
2268 (define_insn "abssf2"
2269   [(set (match_operand:SF 0 "register_operand" "=f")
2270         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2271   "TARGET_HARD_FLOAT"
2272   "abs.s\t%0,%1"
2273   [(set_attr "type"     "fabs")
2274    (set_attr "mode"     "SF")])
2275 \f
2276 ;;
2277 ;;  ....................
2278 ;;
2279 ;;      FIND FIRST BIT INSTRUCTION
2280 ;;
2281 ;;  ....................
2282 ;;
2283
2284 (define_insn "ffssi2"
2285   [(set (match_operand:SI 0 "register_operand" "=&d")
2286         (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2287    (clobber (match_scratch:SI 2 "=&d"))
2288    (clobber (match_scratch:SI 3 "=&d"))]
2289   "!TARGET_MIPS16"
2290 {
2291   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2292     return "%(\
2293 move\t%0,%.\;\
2294 beq\t%1,%.,2f\n\
2295 %~1:\tand\t%2,%1,0x0001\;\
2296 addu\t%0,%0,1\;\
2297 beq\t%2,%.,1b\;\
2298 srl\t%1,%1,1\n\
2299 %~2:%)";
2300
2301   return "%(\
2302 move\t%0,%.\;\
2303 move\t%3,%1\;\
2304 beq\t%3,%.,2f\n\
2305 %~1:\tand\t%2,%3,0x0001\;\
2306 addu\t%0,%0,1\;\
2307 beq\t%2,%.,1b\;\
2308 srl\t%3,%3,1\n\
2309 %~2:%)";
2310 }
2311   [(set_attr "type"     "multi")
2312    (set_attr "mode"     "SI")
2313    (set_attr "length"   "28")])
2314
2315 (define_insn "ffsdi2"
2316   [(set (match_operand:DI 0 "register_operand" "=&d")
2317         (ffs:DI (match_operand:DI 1 "register_operand" "d")))
2318    (clobber (match_scratch:DI 2 "=&d"))
2319    (clobber (match_scratch:DI 3 "=&d"))]
2320   "TARGET_64BIT && !TARGET_MIPS16"
2321 {
2322   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2323     return "%(\
2324 move\t%0,%.\;\
2325 beq\t%1,%.,2f\n\
2326 %~1:\tand\t%2,%1,0x0001\;\
2327 daddu\t%0,%0,1\;\
2328 beq\t%2,%.,1b\;\
2329 dsrl\t%1,%1,1\n\
2330 %~2:%)";
2331
2332   return "%(\
2333 move\t%0,%.\;\
2334 move\t%3,%1\;\
2335 beq\t%3,%.,2f\n\
2336 %~1:\tand\t%2,%3,0x0001\;\
2337 daddu\t%0,%0,1\;\
2338 beq\t%2,%.,1b\;\
2339 dsrl\t%3,%3,1\n\
2340 %~2:%)";
2341 }
2342   [(set_attr "type"     "multi")
2343    (set_attr "mode"     "DI")
2344    (set_attr "length"   "28")])
2345 \f
2346 ;;
2347 ;;  ...................
2348 ;;
2349 ;;  Count leading zeroes.
2350 ;;
2351 ;;  ...................
2352 ;;
2353
2354 (define_insn "clzsi2"
2355   [(set (match_operand:SI 0 "register_operand" "=d")
2356         (clz:SI (match_operand:SI 1 "register_operand" "d")))]
2357   "ISA_HAS_CLZ_CLO"
2358   "clz\t%0,%1"
2359   [(set_attr "type" "clz")
2360    (set_attr "mode" "SI")])
2361
2362 (define_insn "clzdi2"
2363   [(set (match_operand:DI 0 "register_operand" "=d")
2364         (clz:DI (match_operand:DI 1 "register_operand" "d")))]
2365   "ISA_HAS_DCLZ_DCLO"
2366   "dclz\t%0,%1"
2367   [(set_attr "type" "clz")
2368    (set_attr "mode" "DI")])
2369 \f
2370 ;;
2371 ;;  ....................
2372 ;;
2373 ;;      NEGATION and ONE'S COMPLEMENT
2374 ;;
2375 ;;  ....................
2376
2377 (define_insn "negsi2"
2378   [(set (match_operand:SI 0 "register_operand" "=d")
2379         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2380   ""
2381 {
2382   if (TARGET_MIPS16)
2383     return "neg\t%0,%1";
2384   else
2385     return "subu\t%0,%.,%1";
2386 }
2387   [(set_attr "type"     "arith")
2388    (set_attr "mode"     "SI")])
2389
2390 (define_insn "negdi2"
2391   [(set (match_operand:DI 0 "register_operand" "=d")
2392         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2393   "TARGET_64BIT && !TARGET_MIPS16"
2394   "dsubu\t%0,%.,%1"
2395   [(set_attr "type"     "arith")
2396    (set_attr "mode"     "DI")])
2397
2398 (define_insn "negdf2"
2399   [(set (match_operand:DF 0 "register_operand" "=f")
2400         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2401   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2402   "neg.d\t%0,%1"
2403   [(set_attr "type"     "fneg")
2404    (set_attr "mode"     "DF")])
2405
2406 (define_insn "negsf2"
2407   [(set (match_operand:SF 0 "register_operand" "=f")
2408         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2409   "TARGET_HARD_FLOAT"
2410   "neg.s\t%0,%1"
2411   [(set_attr "type"     "fneg")
2412    (set_attr "mode"     "SF")])
2413
2414 (define_insn "one_cmplsi2"
2415   [(set (match_operand:SI 0 "register_operand" "=d")
2416         (not:SI (match_operand:SI 1 "register_operand" "d")))]
2417   ""
2418 {
2419   if (TARGET_MIPS16)
2420     return "not\t%0,%1";
2421   else
2422     return "nor\t%0,%.,%1";
2423 }
2424   [(set_attr "type"     "arith")
2425    (set_attr "mode"     "SI")])
2426
2427 (define_insn "one_cmpldi2"
2428   [(set (match_operand:DI 0 "register_operand" "=d")
2429         (not:DI (match_operand:DI 1 "register_operand" "d")))]
2430   "TARGET_64BIT"
2431 {
2432   if (TARGET_MIPS16)
2433     return "not\t%0,%1";
2434   else
2435     return "nor\t%0,%.,%1";
2436 }
2437   [(set_attr "type"     "arith")
2438    (set_attr "mode"     "DI")])
2439 \f
2440 ;;
2441 ;;  ....................
2442 ;;
2443 ;;      LOGICAL
2444 ;;
2445 ;;  ....................
2446 ;;
2447
2448 ;; Many of these instructions use trivial define_expands, because we
2449 ;; want to use a different set of constraints when TARGET_MIPS16.
2450
2451 (define_expand "andsi3"
2452   [(set (match_operand:SI 0 "register_operand")
2453         (and:SI (match_operand:SI 1 "uns_arith_operand")
2454                 (match_operand:SI 2 "uns_arith_operand")))]
2455   ""
2456 {
2457   if (TARGET_MIPS16)
2458     {
2459       operands[1] = force_reg (SImode, operands[1]);
2460       operands[2] = force_reg (SImode, operands[2]);
2461     }
2462 })
2463
2464 (define_insn ""
2465   [(set (match_operand:SI 0 "register_operand" "=d,d")
2466         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2467                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2468   "!TARGET_MIPS16"
2469   "@
2470    and\t%0,%1,%2
2471    andi\t%0,%1,%x2"
2472   [(set_attr "type"     "arith")
2473    (set_attr "mode"     "SI")])
2474
2475 (define_insn ""
2476   [(set (match_operand:SI 0 "register_operand" "=d")
2477         (and:SI (match_operand:SI 1 "register_operand" "%0")
2478                 (match_operand:SI 2 "register_operand" "d")))]
2479   "TARGET_MIPS16"
2480   "and\t%0,%2"
2481   [(set_attr "type"     "arith")
2482    (set_attr "mode"     "SI")])
2483
2484 (define_expand "anddi3"
2485   [(set (match_operand:DI 0 "register_operand")
2486         (and:DI (match_operand:DI 1 "register_operand")
2487                 (match_operand:DI 2 "uns_arith_operand")))]
2488   "TARGET_64BIT"
2489 {
2490   if (TARGET_MIPS16)
2491     {
2492       operands[1] = force_reg (DImode, operands[1]);
2493       operands[2] = force_reg (DImode, operands[2]);
2494     }
2495 })
2496
2497 (define_insn ""
2498   [(set (match_operand:DI 0 "register_operand" "=d,d")
2499         (and:DI (match_operand:DI 1 "register_operand" "d,d")
2500                 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2501   "TARGET_64BIT && !TARGET_MIPS16"
2502   "@
2503    and\t%0,%1,%2
2504    andi\t%0,%1,%x2"
2505   [(set_attr "type"     "arith")
2506    (set_attr "mode"     "DI")])
2507
2508 (define_insn ""
2509   [(set (match_operand:DI 0 "register_operand" "=d")
2510         (and:DI (match_operand:DI 1 "register_operand" "0")
2511                 (match_operand:DI 2 "register_operand" "d")))]
2512   "TARGET_64BIT && TARGET_MIPS16"
2513   "and\t%0,%2"
2514   [(set_attr "type"     "arith")
2515    (set_attr "mode"     "DI")])
2516
2517 (define_expand "iorsi3"
2518   [(set (match_operand:SI 0 "register_operand")
2519         (ior:SI (match_operand:SI 1 "uns_arith_operand")
2520                 (match_operand:SI 2 "uns_arith_operand")))]
2521   ""
2522 {
2523   if (TARGET_MIPS16)
2524     {
2525       operands[1] = force_reg (SImode, operands[1]);
2526       operands[2] = force_reg (SImode, operands[2]);
2527     }
2528 })
2529
2530 (define_insn ""
2531   [(set (match_operand:SI 0 "register_operand" "=d,d")
2532         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2533                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2534   "!TARGET_MIPS16"
2535   "@
2536    or\t%0,%1,%2
2537    ori\t%0,%1,%x2"
2538   [(set_attr "type"     "arith")
2539    (set_attr "mode"     "SI")])
2540
2541 (define_insn ""
2542   [(set (match_operand:SI 0 "register_operand" "=d")
2543         (ior:SI (match_operand:SI 1 "register_operand" "%0")
2544                 (match_operand:SI 2 "register_operand" "d")))]
2545   "TARGET_MIPS16"
2546   "or\t%0,%2"
2547   [(set_attr "type"     "arith")
2548    (set_attr "mode"     "SI")])
2549
2550 (define_expand "iordi3"
2551   [(set (match_operand:DI 0 "register_operand")
2552         (ior:DI (match_operand:DI 1 "register_operand")
2553                 (match_operand:DI 2 "uns_arith_operand")))]
2554   "TARGET_64BIT"
2555 {
2556   if (TARGET_MIPS16)
2557     {
2558       operands[1] = force_reg (DImode, operands[1]);
2559       operands[2] = force_reg (DImode, operands[2]);
2560     }
2561 })
2562
2563 (define_insn ""
2564   [(set (match_operand:DI 0 "register_operand" "=d,d")
2565         (ior:DI (match_operand:DI 1 "register_operand" "d,d")
2566                 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2567   "TARGET_64BIT && !TARGET_MIPS16"
2568   "@
2569    or\t%0,%1,%2
2570    ori\t%0,%1,%x2"
2571   [(set_attr "type"     "arith")
2572    (set_attr "mode"     "DI")])
2573
2574 (define_insn ""
2575   [(set (match_operand:DI 0 "register_operand" "=d")
2576         (ior:DI (match_operand:DI 1 "register_operand" "0")
2577                 (match_operand:DI 2 "register_operand" "d")))]
2578   "TARGET_64BIT && TARGET_MIPS16"
2579   "or\t%0,%2"
2580   [(set_attr "type"     "arith")
2581    (set_attr "mode"     "DI")])
2582
2583 (define_expand "xorsi3"
2584   [(set (match_operand:SI 0 "register_operand")
2585         (xor:SI (match_operand:SI 1 "uns_arith_operand")
2586                 (match_operand:SI 2 "uns_arith_operand")))]
2587   ""
2588   "")
2589
2590 (define_insn ""
2591   [(set (match_operand:SI 0 "register_operand" "=d,d")
2592         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2593                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2594   "!TARGET_MIPS16"
2595   "@
2596    xor\t%0,%1,%2
2597    xori\t%0,%1,%x2"
2598   [(set_attr "type"     "arith")
2599    (set_attr "mode"     "SI")])
2600
2601 (define_insn ""
2602   [(set (match_operand:SI 0 "register_operand" "=d,t,t")
2603         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
2604                 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
2605   "TARGET_MIPS16"
2606   "@
2607    xor\t%0,%2
2608    cmpi\t%1,%2
2609    cmp\t%1,%2"
2610   [(set_attr "type"     "arith")
2611    (set_attr "mode"     "SI")
2612    (set_attr_alternative "length"
2613                 [(const_int 4)
2614                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2615                                (const_int 4)
2616                                (const_int 8))
2617                  (const_int 4)])])
2618
2619 (define_expand "xordi3"
2620   [(set (match_operand:DI 0 "register_operand")
2621         (xor:DI (match_operand:DI 1 "register_operand")
2622                 (match_operand:DI 2 "uns_arith_operand")))]
2623   "TARGET_64BIT"
2624 {
2625   if (TARGET_MIPS16)
2626     {
2627       operands[1] = force_reg (DImode, operands[1]);
2628       operands[2] = force_reg (DImode, operands[2]);
2629     }
2630 })
2631
2632 (define_insn ""
2633   [(set (match_operand:DI 0 "register_operand" "=d,d")
2634         (xor:DI (match_operand:DI 1 "register_operand" "d,d")
2635                 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2636   "TARGET_64BIT && !TARGET_MIPS16"
2637   "@
2638    xor\t%0,%1,%2
2639    xori\t%0,%1,%x2"
2640   [(set_attr "type"     "arith")
2641    (set_attr "mode"     "DI")])
2642
2643 (define_insn ""
2644   [(set (match_operand:DI 0 "register_operand" "=d,t,t")
2645         (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
2646                 (match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
2647   "TARGET_64BIT && TARGET_MIPS16"
2648   "@
2649    xor\t%0,%2
2650    cmpi\t%1,%2
2651    cmp\t%1,%2"
2652   [(set_attr "type"     "arith")
2653    (set_attr "mode"     "DI")
2654    (set_attr_alternative "length"
2655                 [(const_int 4)
2656                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2657                                (const_int 4)
2658                                (const_int 8))
2659                  (const_int 4)])])
2660
2661 (define_insn "*norsi3"
2662   [(set (match_operand:SI 0 "register_operand" "=d")
2663         (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
2664                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
2665   "!TARGET_MIPS16"
2666   "nor\t%0,%z1,%z2"
2667   [(set_attr "type"     "arith")
2668    (set_attr "mode"     "SI")])
2669
2670 (define_insn "*nordi3"
2671   [(set (match_operand:DI 0 "register_operand" "=d")
2672         (and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
2673                 (not:DI (match_operand:DI 2 "register_operand" "d"))))]
2674   "TARGET_64BIT && !TARGET_MIPS16"
2675   "nor\t%0,%z1,%z2"
2676   [(set_attr "type"     "arith")
2677    (set_attr "mode"     "DI")])
2678 \f
2679 ;;
2680 ;;  ....................
2681 ;;
2682 ;;      TRUNCATION
2683 ;;
2684 ;;  ....................
2685
2686
2687
2688 (define_insn "truncdfsf2"
2689   [(set (match_operand:SF 0 "register_operand" "=f")
2690         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2691   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2692   "cvt.s.d\t%0,%1"
2693   [(set_attr "type"     "fcvt")
2694    (set_attr "mode"     "SF")])
2695
2696 ;; Integer truncation patterns.  Truncating SImode values to smaller
2697 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
2698 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2699 ;; need to make sure that the lower 32 bits are properly sign-extended
2700 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2701 ;; smaller than SImode is equivalent to two separate truncations:
2702 ;;
2703 ;;                        A       B
2704 ;;    DI ---> HI  ==  DI ---> SI ---> HI
2705 ;;    DI ---> QI  ==  DI ---> SI ---> QI
2706 ;;
2707 ;; Step A needs a real instruction but step B does not.
2708
2709 (define_insn "truncdisi2"
2710   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2711         (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2712   "TARGET_64BIT"
2713   "@
2714     sll\t%0,%1,0
2715     sw\t%1,%0"
2716   [(set_attr "type" "shift,store")
2717    (set_attr "mode" "SI")
2718    (set_attr "extended_mips16" "yes,*")])
2719
2720 (define_insn "truncdihi2"
2721   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2722         (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2723   "TARGET_64BIT"
2724   "@
2725     sll\t%0,%1,0
2726     sh\t%1,%0"
2727   [(set_attr "type" "shift,store")
2728    (set_attr "mode" "SI")
2729    (set_attr "extended_mips16" "yes,*")])
2730
2731 (define_insn "truncdiqi2"
2732   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2733         (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2734   "TARGET_64BIT"
2735   "@
2736     sll\t%0,%1,0
2737     sb\t%1,%0"
2738   [(set_attr "type" "shift,store")
2739    (set_attr "mode" "SI")
2740    (set_attr "extended_mips16" "yes,*")])
2741
2742 ;; Combiner patterns to optimize shift/truncate combinations.
2743
2744 (define_insn ""
2745   [(set (match_operand:SI 0 "register_operand" "=d")
2746         (truncate:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2747                                   (match_operand:DI 2 "small_int" "I"))))]
2748   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2749   "dsra\t%0,%1,%2"
2750   [(set_attr "type" "shift")
2751    (set_attr "mode" "SI")])
2752
2753 (define_insn ""
2754   [(set (match_operand:SI 0 "register_operand" "=d")
2755         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2756                                   (const_int 32))))]
2757   "TARGET_64BIT && !TARGET_MIPS16"
2758   "dsra\t%0,%1,32"
2759   [(set_attr "type" "shift")
2760    (set_attr "mode" "SI")])
2761
2762
2763 ;; Combiner patterns for truncate/sign_extend combinations.  They use
2764 ;; the shift/truncate patterns above.
2765
2766 (define_insn_and_split ""
2767   [(set (match_operand:SI 0 "register_operand" "=d")
2768         (sign_extend:SI
2769             (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2770   "TARGET_64BIT && !TARGET_MIPS16"
2771   "#"
2772   "&& reload_completed"
2773   [(set (match_dup 2)
2774         (ashift:DI (match_dup 1)
2775                    (const_int 48)))
2776    (set (match_dup 0)
2777         (truncate:SI (ashiftrt:DI (match_dup 2)
2778                                   (const_int 48))))]
2779   { operands[2] = gen_lowpart (DImode, operands[0]); })
2780
2781 (define_insn_and_split ""
2782   [(set (match_operand:SI 0 "register_operand" "=d")
2783         (sign_extend:SI
2784             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2785   "TARGET_64BIT && !TARGET_MIPS16"
2786   "#"
2787   "&& reload_completed"
2788   [(set (match_dup 2)
2789         (ashift:DI (match_dup 1)
2790                    (const_int 56)))
2791    (set (match_dup 0)
2792         (truncate:SI (ashiftrt:DI (match_dup 2)
2793                                   (const_int 56))))]
2794   { operands[2] = gen_lowpart (DImode, operands[0]); })
2795
2796
2797 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2798
2799 (define_insn ""
2800   [(set (match_operand:SI 0 "register_operand" "=d")
2801         (zero_extend:SI (truncate:HI
2802                          (match_operand:DI 1 "register_operand" "d"))))]
2803   "TARGET_64BIT && !TARGET_MIPS16"
2804   "andi\t%0,%1,0xffff"
2805   [(set_attr "type"     "arith")
2806    (set_attr "mode"     "SI")])
2807
2808 (define_insn ""
2809   [(set (match_operand:SI 0 "register_operand" "=d")
2810         (zero_extend:SI (truncate:QI
2811                          (match_operand:DI 1 "register_operand" "d"))))]
2812   "TARGET_64BIT && !TARGET_MIPS16"
2813   "andi\t%0,%1,0xff"
2814   [(set_attr "type"     "arith")
2815    (set_attr "mode"     "SI")])
2816
2817 (define_insn ""
2818   [(set (match_operand:HI 0 "register_operand" "=d")
2819         (zero_extend:HI (truncate:QI
2820                          (match_operand:DI 1 "register_operand" "d"))))]
2821   "TARGET_64BIT && !TARGET_MIPS16"
2822   "andi\t%0,%1,0xff"
2823   [(set_attr "type"     "arith")
2824    (set_attr "mode"     "HI")])
2825 \f
2826 ;;
2827 ;;  ....................
2828 ;;
2829 ;;      ZERO EXTENSION
2830 ;;
2831 ;;  ....................
2832
2833 ;; Extension insns.
2834 ;; Those for integer source operand are ordered widest source type first.
2835
2836 (define_insn_and_split "zero_extendsidi2"
2837   [(set (match_operand:DI 0 "register_operand" "=d")
2838         (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2839   "TARGET_64BIT"
2840   "#"
2841   "&& reload_completed"
2842   [(set (match_dup 0)
2843         (ashift:DI (match_dup 1) (const_int 32)))
2844    (set (match_dup 0)
2845         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2846   "operands[1] = gen_lowpart (DImode, operands[1]);"
2847   [(set_attr "type" "multi")
2848    (set_attr "mode" "DI")
2849    (set_attr "length" "8")])
2850
2851 (define_insn "*zero_extendsidi2_mem"
2852   [(set (match_operand:DI 0 "register_operand" "=d")
2853         (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2854   "TARGET_64BIT"
2855   "lwu\t%0,%1"
2856   [(set_attr "type"     "load")
2857    (set_attr "mode"     "DI")])
2858
2859 (define_expand "zero_extendhisi2"
2860   [(set (match_operand:SI 0 "register_operand")
2861         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2862   ""
2863 {
2864   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2865     {
2866       rtx op = gen_lowpart (SImode, operands[1]);
2867       rtx temp = force_reg (SImode, GEN_INT (0xffff));
2868
2869       emit_insn (gen_andsi3 (operands[0], op, temp));
2870       DONE;
2871     }
2872 })
2873
2874 (define_insn ""
2875   [(set (match_operand:SI 0 "register_operand" "=d,d")
2876         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2877   "!TARGET_MIPS16"
2878   "@
2879    andi\t%0,%1,0xffff
2880    lhu\t%0,%1"
2881   [(set_attr "type"     "arith,load")
2882    (set_attr "mode"     "SI")
2883    (set_attr "length"   "4,*")])
2884
2885 (define_insn ""
2886   [(set (match_operand:SI 0 "register_operand" "=d")
2887         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2888   "TARGET_MIPS16"
2889   "lhu\t%0,%1"
2890   [(set_attr "type"     "load")
2891    (set_attr "mode"     "SI")])
2892
2893 (define_expand "zero_extendhidi2"
2894   [(set (match_operand:DI 0 "register_operand")
2895         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2896   "TARGET_64BIT"
2897 {
2898   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2899     {
2900       rtx op = gen_lowpart (DImode, operands[1]);
2901       rtx temp = force_reg (DImode, GEN_INT (0xffff));
2902
2903       emit_insn (gen_anddi3 (operands[0], op, temp));
2904       DONE;
2905     }
2906 })
2907
2908 (define_insn ""
2909   [(set (match_operand:DI 0 "register_operand" "=d,d")
2910         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2911   "TARGET_64BIT && !TARGET_MIPS16"
2912   "@
2913    andi\t%0,%1,0xffff
2914    lhu\t%0,%1"
2915   [(set_attr "type"     "arith,load")
2916    (set_attr "mode"     "DI")
2917    (set_attr "length"   "4,*")])
2918
2919 (define_insn ""
2920   [(set (match_operand:DI 0 "register_operand" "=d")
2921         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2922   "TARGET_64BIT && TARGET_MIPS16"
2923   "lhu\t%0,%1"
2924   [(set_attr "type"     "load")
2925    (set_attr "mode"     "DI")])
2926
2927 (define_expand "zero_extendqihi2"
2928   [(set (match_operand:HI 0 "register_operand")
2929         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2930   ""
2931 {
2932   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2933     {
2934       rtx op0 = gen_lowpart (SImode, operands[0]);
2935       rtx op1 = gen_lowpart (SImode, operands[1]);
2936       rtx temp = force_reg (SImode, GEN_INT (0xff));
2937
2938       emit_insn (gen_andsi3 (op0, op1, temp));
2939       DONE;
2940     }
2941 })
2942
2943 (define_insn ""
2944   [(set (match_operand:HI 0 "register_operand" "=d,d")
2945         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2946   "!TARGET_MIPS16"
2947   "@
2948    andi\t%0,%1,0x00ff
2949    lbu\t%0,%1"
2950   [(set_attr "type"     "arith,load")
2951    (set_attr "mode"     "HI")
2952    (set_attr "length"   "4,*")])
2953
2954 (define_insn ""
2955   [(set (match_operand:HI 0 "register_operand" "=d")
2956         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2957   "TARGET_MIPS16"
2958   "lbu\t%0,%1"
2959   [(set_attr "type"     "load")
2960    (set_attr "mode"     "HI")])
2961
2962 (define_expand "zero_extendqisi2"
2963   [(set (match_operand:SI 0 "register_operand")
2964         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2965   ""
2966 {
2967   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2968     {
2969       rtx op = gen_lowpart (SImode, operands[1]);
2970       rtx temp = force_reg (SImode, GEN_INT (0xff));
2971
2972       emit_insn (gen_andsi3 (operands[0], op, temp));
2973       DONE;
2974     }
2975 })
2976
2977 (define_insn ""
2978   [(set (match_operand:SI 0 "register_operand" "=d,d")
2979         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2980   "!TARGET_MIPS16"
2981   "@
2982    andi\t%0,%1,0x00ff
2983    lbu\t%0,%1"
2984   [(set_attr "type"     "arith,load")
2985    (set_attr "mode"     "SI")
2986    (set_attr "length"   "4,*")])
2987
2988 (define_insn ""
2989   [(set (match_operand:SI 0 "register_operand" "=d")
2990         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2991   "TARGET_MIPS16"
2992   "lbu\t%0,%1"
2993   [(set_attr "type"     "load")
2994    (set_attr "mode"     "SI")])
2995
2996 (define_expand "zero_extendqidi2"
2997   [(set (match_operand:DI 0 "register_operand")
2998         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2999   "TARGET_64BIT"
3000 {
3001   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3002     {
3003       rtx op = gen_lowpart (DImode, operands[1]);
3004       rtx temp = force_reg (DImode, GEN_INT (0xff));
3005
3006       emit_insn (gen_anddi3 (operands[0], op, temp));
3007       DONE;
3008     }
3009 })
3010
3011 (define_insn ""
3012   [(set (match_operand:DI 0 "register_operand" "=d,d")
3013         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3014   "TARGET_64BIT && !TARGET_MIPS16"
3015   "@
3016    andi\t%0,%1,0x00ff
3017    lbu\t%0,%1"
3018   [(set_attr "type"     "arith,load")
3019    (set_attr "mode"     "DI")
3020    (set_attr "length"   "4,*")])
3021
3022 (define_insn ""
3023   [(set (match_operand:DI 0 "register_operand" "=d")
3024         (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3025   "TARGET_64BIT && TARGET_MIPS16"
3026   "lbu\t%0,%1"
3027   [(set_attr "type"     "load")
3028    (set_attr "mode"     "DI")])
3029 \f
3030 ;;
3031 ;;  ....................
3032 ;;
3033 ;;      SIGN EXTENSION
3034 ;;
3035 ;;  ....................
3036
3037 ;; Extension insns.
3038 ;; Those for integer source operand are ordered widest source type first.
3039
3040 ;; When TARGET_64BIT, all SImode integer registers should already be in
3041 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can
3042 ;; therefore get rid of register->register instructions if we constrain
3043 ;; the source to be in the same register as the destination.
3044 ;;
3045 ;; The register alternative has type "arith" so that the pre-reload
3046 ;; scheduler will treat it as a move.  This reflects what happens if
3047 ;; the register alternative needs a reload.
3048 (define_insn_and_split "extendsidi2"
3049   [(set (match_operand:DI 0 "register_operand" "=d,d")
3050         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
3051   "TARGET_64BIT"
3052   "@
3053    #
3054    lw\t%0,%1"
3055   "&& reload_completed && register_operand (operands[1], VOIDmode)"
3056   [(const_int 0)]
3057 {
3058   emit_note (NOTE_INSN_DELETED);
3059   DONE;
3060 }
3061   [(set_attr "type" "arith,load")
3062    (set_attr "mode" "DI")])
3063
3064 ;; These patterns originally accepted general_operands, however, slightly
3065 ;; better code is generated by only accepting register_operands, and then
3066 ;; letting combine generate the lh and lb insns.
3067
3068 ;; These expanders originally put values in registers first. We split
3069 ;; all non-mem patterns after reload.
3070
3071 (define_expand "extendhidi2"
3072   [(set (match_operand:DI 0 "register_operand")
3073         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
3074   "TARGET_64BIT"
3075   "")
3076
3077 (define_insn "*extendhidi2"
3078   [(set (match_operand:DI 0 "register_operand" "=d")
3079         (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
3080   "TARGET_64BIT"
3081   "#")
3082
3083 (define_split
3084   [(set (match_operand:DI 0 "register_operand")
3085         (sign_extend:DI (match_operand:HI 1 "register_operand")))]
3086   "TARGET_64BIT && reload_completed"
3087   [(set (match_dup 0)
3088         (ashift:DI (match_dup 1) (const_int 48)))
3089    (set (match_dup 0)
3090         (ashiftrt:DI (match_dup 0) (const_int 48)))]
3091   "operands[1] = gen_lowpart (DImode, operands[1]);")
3092
3093 (define_insn "*extendhidi2_mem"
3094   [(set (match_operand:DI 0 "register_operand" "=d")
3095         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3096   "TARGET_64BIT"
3097   "lh\t%0,%1"
3098   [(set_attr "type"     "load")
3099    (set_attr "mode"     "DI")])
3100
3101 (define_expand "extendhisi2"
3102   [(set (match_operand:SI 0 "register_operand")
3103         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
3104   ""
3105 {
3106   if (ISA_HAS_SEB_SEH)
3107     {
3108       emit_insn (gen_extendhisi2_hw (operands[0],
3109                                      force_reg (HImode, operands[1])));
3110       DONE;
3111     }
3112 })
3113
3114 (define_insn "*extendhisi2"
3115   [(set (match_operand:SI 0 "register_operand" "=d")
3116         (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
3117   ""
3118   "#")
3119
3120 (define_split
3121   [(set (match_operand:SI 0 "register_operand")
3122         (sign_extend:SI (match_operand:HI 1 "register_operand")))]
3123   "reload_completed"
3124   [(set (match_dup 0)
3125         (ashift:SI (match_dup 1) (const_int 16)))
3126    (set (match_dup 0)
3127         (ashiftrt:SI (match_dup 0) (const_int 16)))]
3128   "operands[1] = gen_lowpart (SImode, operands[1]);")
3129
3130 (define_insn "extendhisi2_mem"
3131   [(set (match_operand:SI 0 "register_operand" "=d")
3132         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3133   ""
3134   "lh\t%0,%1"
3135   [(set_attr "type"     "load")
3136    (set_attr "mode"     "SI")])
3137
3138 (define_insn "extendhisi2_hw"
3139   [(set (match_operand:SI 0 "register_operand" "=r")
3140         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
3141   "ISA_HAS_SEB_SEH"
3142   "seh\t%0,%1"
3143   [(set_attr "type" "arith")
3144    (set_attr "mode" "SI")])
3145
3146 (define_expand "extendqihi2"
3147   [(set (match_operand:HI 0 "register_operand")
3148         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3149   ""
3150   "")
3151
3152 (define_insn "*extendqihi2"
3153   [(set (match_operand:HI 0 "register_operand" "=d")
3154         (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
3155   ""
3156   "#")
3157
3158 (define_split
3159   [(set (match_operand:HI 0 "register_operand")
3160         (sign_extend:HI (match_operand:QI 1 "register_operand")))]
3161   "reload_completed"
3162   [(set (match_dup 0)
3163         (ashift:SI (match_dup 1) (const_int 24)))
3164    (set (match_dup 0)
3165         (ashiftrt:SI (match_dup 0) (const_int 24)))]
3166   "operands[0] = gen_lowpart (SImode, operands[0]);
3167    operands[1] = gen_lowpart (SImode, operands[1]);")
3168
3169 (define_insn "*extendqihi2_internal_mem"
3170   [(set (match_operand:HI 0 "register_operand" "=d")
3171         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3172   ""
3173   "lb\t%0,%1"
3174   [(set_attr "type"     "load")
3175    (set_attr "mode"     "SI")])
3176
3177
3178 (define_expand "extendqisi2"
3179   [(set (match_operand:SI 0 "register_operand")
3180         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3181   ""
3182 {
3183   if (ISA_HAS_SEB_SEH)
3184     {
3185       emit_insn (gen_extendqisi2_hw (operands[0],
3186                                      force_reg (QImode, operands[1])));
3187       DONE;
3188     }
3189 })
3190
3191 (define_insn "*extendqisi2"
3192   [(set (match_operand:SI 0 "register_operand" "=d")
3193         (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
3194   ""
3195   "#")
3196
3197 (define_split
3198   [(set (match_operand:SI 0 "register_operand")
3199         (sign_extend:SI (match_operand:QI 1 "register_operand")))]
3200   "reload_completed"
3201   [(set (match_dup 0)
3202         (ashift:SI (match_dup 1) (const_int 24)))
3203    (set (match_dup 0)
3204         (ashiftrt:SI (match_dup 0) (const_int 24)))]
3205   "operands[1] = gen_lowpart (SImode, operands[1]);")
3206
3207 (define_insn "*extendqisi2_mem"
3208   [(set (match_operand:SI 0 "register_operand" "=d")
3209         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3210   ""
3211   "lb\t%0,%1"
3212   [(set_attr "type"     "load")
3213    (set_attr "mode"     "SI")])
3214
3215 (define_insn "extendqisi2_hw"
3216   [(set (match_operand:SI 0 "register_operand" "=r")
3217         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
3218   "ISA_HAS_SEB_SEH"
3219   "seb\t%0,%1"
3220   [(set_attr "type" "arith")
3221    (set_attr "mode" "SI")])
3222
3223 (define_expand "extendqidi2"
3224   [(set (match_operand:DI 0 "register_operand")
3225         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3226   "TARGET_64BIT"
3227   "")
3228
3229 (define_insn "*extendqidi2"
3230   [(set (match_operand:DI 0 "register_operand" "=d")
3231         (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
3232   "TARGET_64BIT"
3233   "#")
3234
3235 (define_split
3236   [(set (match_operand:DI 0 "register_operand")
3237         (sign_extend:DI (match_operand:QI 1 "register_operand")))]
3238   "TARGET_64BIT && reload_completed"
3239   [(set (match_dup 0)
3240         (ashift:DI (match_dup 1) (const_int 56)))
3241    (set (match_dup 0)
3242         (ashiftrt:DI (match_dup 0) (const_int 56)))]
3243   "operands[1] = gen_lowpart (DImode, operands[1]);")
3244
3245 (define_insn "*extendqidi2_mem"
3246   [(set (match_operand:DI 0 "register_operand" "=d")
3247         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3248   "TARGET_64BIT"
3249   "lb\t%0,%1"
3250   [(set_attr "type"     "load")
3251    (set_attr "mode"     "DI")])
3252
3253 (define_insn "extendsfdf2"
3254   [(set (match_operand:DF 0 "register_operand" "=f")
3255         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3256   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3257   "cvt.d.s\t%0,%1"
3258   [(set_attr "type"     "fcvt")
3259    (set_attr "mode"     "DF")])
3260 \f
3261 ;;
3262 ;;  ....................
3263 ;;
3264 ;;      CONVERSIONS
3265 ;;
3266 ;;  ....................
3267
3268 (define_expand "fix_truncdfsi2"
3269   [(set (match_operand:SI 0 "register_operand")
3270         (fix:SI (match_operand:DF 1 "register_operand")))]
3271   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3272 {
3273   if (!ISA_HAS_TRUNC_W)
3274     {
3275       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3276       DONE;
3277     }
3278 })
3279
3280 (define_insn "fix_truncdfsi2_insn"
3281   [(set (match_operand:SI 0 "register_operand" "=f")
3282         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3283   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3284   "trunc.w.d %0,%1"
3285   [(set_attr "type"     "fcvt")
3286    (set_attr "mode"     "DF")
3287    (set_attr "length"   "4")])
3288
3289 (define_insn "fix_truncdfsi2_macro"
3290   [(set (match_operand:SI 0 "register_operand" "=f")
3291         (fix:SI (match_operand:DF 1 "register_operand" "f")))
3292    (clobber (match_scratch:DF 2 "=d"))]
3293   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3294 {
3295   if (set_nomacro)
3296     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3297   else
3298     return "trunc.w.d %0,%1,%2";
3299 }
3300   [(set_attr "type"     "fcvt")
3301    (set_attr "mode"     "DF")
3302    (set_attr "length"   "36")])
3303
3304 (define_expand "fix_truncsfsi2"
3305   [(set (match_operand:SI 0 "register_operand")
3306         (fix:SI (match_operand:SF 1 "register_operand")))]
3307   "TARGET_HARD_FLOAT"
3308 {
3309   if (!ISA_HAS_TRUNC_W)
3310     {
3311       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3312       DONE;
3313     }
3314 })
3315
3316 (define_insn "fix_truncsfsi2_insn"
3317   [(set (match_operand:SI 0 "register_operand" "=f")
3318         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3319   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3320   "trunc.w.s %0,%1"
3321   [(set_attr "type"     "fcvt")
3322    (set_attr "mode"     "DF")
3323    (set_attr "length"   "4")])
3324
3325 (define_insn "fix_truncsfsi2_macro"
3326   [(set (match_operand:SI 0 "register_operand" "=f")
3327         (fix:SI (match_operand:SF 1 "register_operand" "f")))
3328    (clobber (match_scratch:SF 2 "=d"))]
3329   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3330 {
3331   if (set_nomacro)
3332     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3333   else
3334     return "trunc.w.s %0,%1,%2";
3335 }
3336   [(set_attr "type"     "fcvt")
3337    (set_attr "mode"     "DF")
3338    (set_attr "length"   "36")])
3339
3340
3341 (define_insn "fix_truncdfdi2"
3342   [(set (match_operand:DI 0 "register_operand" "=f")
3343         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3344   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3345   "trunc.l.d %0,%1"
3346   [(set_attr "type"     "fcvt")
3347    (set_attr "mode"     "DF")
3348    (set_attr "length"   "4")])
3349
3350
3351 (define_insn "fix_truncsfdi2"
3352   [(set (match_operand:DI 0 "register_operand" "=f")
3353         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3354   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3355   "trunc.l.s %0,%1"
3356   [(set_attr "type"     "fcvt")
3357    (set_attr "mode"     "SF")
3358    (set_attr "length"   "4")])
3359
3360
3361 (define_insn "floatsidf2"
3362   [(set (match_operand:DF 0 "register_operand" "=f")
3363         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3364   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3365   "cvt.d.w\t%0,%1"
3366   [(set_attr "type"     "fcvt")
3367    (set_attr "mode"     "DF")
3368    (set_attr "length"   "4")])
3369
3370
3371 (define_insn "floatdidf2"
3372   [(set (match_operand:DF 0 "register_operand" "=f")
3373         (float:DF (match_operand:DI 1 "register_operand" "f")))]
3374   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3375   "cvt.d.l\t%0,%1"
3376   [(set_attr "type"     "fcvt")
3377    (set_attr "mode"     "DF")
3378    (set_attr "length"   "4")])
3379
3380
3381 (define_insn "floatsisf2"
3382   [(set (match_operand:SF 0 "register_operand" "=f")
3383         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3384   "TARGET_HARD_FLOAT"
3385   "cvt.s.w\t%0,%1"
3386   [(set_attr "type"     "fcvt")
3387    (set_attr "mode"     "SF")
3388    (set_attr "length"   "4")])
3389
3390
3391 (define_insn "floatdisf2"
3392   [(set (match_operand:SF 0 "register_operand" "=f")
3393         (float:SF (match_operand:DI 1 "register_operand" "f")))]
3394   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3395   "cvt.s.l\t%0,%1"
3396   [(set_attr "type"     "fcvt")
3397    (set_attr "mode"     "SF")
3398    (set_attr "length"   "4")])
3399
3400
3401 (define_expand "fixuns_truncdfsi2"
3402   [(set (match_operand:SI 0 "register_operand")
3403         (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
3404   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3405 {
3406   rtx reg1 = gen_reg_rtx (DFmode);
3407   rtx reg2 = gen_reg_rtx (DFmode);
3408   rtx reg3 = gen_reg_rtx (SImode);
3409   rtx label1 = gen_label_rtx ();
3410   rtx label2 = gen_label_rtx ();
3411   REAL_VALUE_TYPE offset;
3412
3413   real_2expN (&offset, 31);
3414
3415   if (reg1)                     /* Turn off complaints about unreached code.  */
3416     {
3417       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3418       do_pending_stack_adjust ();
3419
3420       emit_insn (gen_cmpdf (operands[1], reg1));
3421       emit_jump_insn (gen_bge (label1));
3422
3423       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3424       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3425                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
3426       emit_barrier ();
3427
3428       emit_label (label1);
3429       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3430       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3431                                      (BITMASK_HIGH, SImode)));
3432
3433       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3434       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3435
3436       emit_label (label2);
3437
3438       /* Allow REG_NOTES to be set on last insn (labels don't have enough
3439          fields, and can't be used for REG_NOTES anyway).  */
3440       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3441       DONE;
3442     }
3443 })
3444
3445
3446 (define_expand "fixuns_truncdfdi2"
3447   [(set (match_operand:DI 0 "register_operand")
3448         (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3449   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3450 {
3451   rtx reg1 = gen_reg_rtx (DFmode);
3452   rtx reg2 = gen_reg_rtx (DFmode);
3453   rtx reg3 = gen_reg_rtx (DImode);
3454   rtx label1 = gen_label_rtx ();
3455   rtx label2 = gen_label_rtx ();
3456   REAL_VALUE_TYPE offset;
3457
3458   real_2expN (&offset, 63);
3459
3460   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3461   do_pending_stack_adjust ();
3462
3463   emit_insn (gen_cmpdf (operands[1], reg1));
3464   emit_jump_insn (gen_bge (label1));
3465
3466   emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3467   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3468                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3469   emit_barrier ();
3470
3471   emit_label (label1);
3472   emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3473   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3474   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3475
3476   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3477   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3478
3479   emit_label (label2);
3480
3481   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3482      fields, and can't be used for REG_NOTES anyway).  */
3483   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3484   DONE;
3485 })
3486
3487
3488 (define_expand "fixuns_truncsfsi2"
3489   [(set (match_operand:SI 0 "register_operand")
3490         (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3491   "TARGET_HARD_FLOAT"
3492 {
3493   rtx reg1 = gen_reg_rtx (SFmode);
3494   rtx reg2 = gen_reg_rtx (SFmode);
3495   rtx reg3 = gen_reg_rtx (SImode);
3496   rtx label1 = gen_label_rtx ();
3497   rtx label2 = gen_label_rtx ();
3498   REAL_VALUE_TYPE offset;
3499
3500   real_2expN (&offset, 31);
3501
3502   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3503   do_pending_stack_adjust ();
3504
3505   emit_insn (gen_cmpsf (operands[1], reg1));
3506   emit_jump_insn (gen_bge (label1));
3507
3508   emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3509   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3510                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3511   emit_barrier ();
3512
3513   emit_label (label1);
3514   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3515   emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3516                                  (BITMASK_HIGH, SImode)));
3517
3518   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3519   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3520
3521   emit_label (label2);
3522
3523   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3524      fields, and can't be used for REG_NOTES anyway).  */
3525   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3526   DONE;
3527 })
3528
3529
3530 (define_expand "fixuns_truncsfdi2"
3531   [(set (match_operand:DI 0 "register_operand")
3532         (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3533   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3534 {
3535   rtx reg1 = gen_reg_rtx (SFmode);
3536   rtx reg2 = gen_reg_rtx (SFmode);
3537   rtx reg3 = gen_reg_rtx (DImode);
3538   rtx label1 = gen_label_rtx ();
3539   rtx label2 = gen_label_rtx ();
3540   REAL_VALUE_TYPE offset;
3541
3542   real_2expN (&offset, 63);
3543
3544   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3545   do_pending_stack_adjust ();
3546
3547   emit_insn (gen_cmpsf (operands[1], reg1));
3548   emit_jump_insn (gen_bge (label1));
3549
3550   emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3551   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3552                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3553   emit_barrier ();
3554
3555   emit_label (label1);
3556   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3557   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3558   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3559
3560   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3561   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3562
3563   emit_label (label2);
3564
3565   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3566      fields, and can't be used for REG_NOTES anyway).  */
3567   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3568   DONE;
3569 })
3570 \f
3571 ;;
3572 ;;  ....................
3573 ;;
3574 ;;      DATA MOVEMENT
3575 ;;
3576 ;;  ....................
3577
3578 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3579
3580 (define_expand "extv"
3581   [(set (match_operand 0 "register_operand")
3582         (sign_extract (match_operand:QI 1 "memory_operand")
3583                       (match_operand 2 "immediate_operand")
3584                       (match_operand 3 "immediate_operand")))]
3585   "!TARGET_MIPS16"
3586 {
3587   if (mips_expand_unaligned_load (operands[0], operands[1],
3588                                   INTVAL (operands[2]),
3589                                   INTVAL (operands[3])))
3590     DONE;
3591   else
3592     FAIL;
3593 })
3594
3595 (define_expand "extzv"
3596   [(set (match_operand 0 "register_operand")
3597         (zero_extract (match_operand:QI 1 "memory_operand")
3598                       (match_operand 2 "immediate_operand")
3599                       (match_operand 3 "immediate_operand")))]
3600   "!TARGET_MIPS16"
3601 {
3602   if (mips_expand_unaligned_load (operands[0], operands[1],
3603                                   INTVAL (operands[2]),
3604                                   INTVAL (operands[3])))
3605     DONE;
3606   else
3607     FAIL;
3608 })
3609
3610 (define_expand "insv"
3611   [(set (zero_extract (match_operand:QI 0 "memory_operand")
3612                       (match_operand 1 "immediate_operand")
3613                       (match_operand 2 "immediate_operand"))
3614         (match_operand 3 "reg_or_0_operand"))]
3615   "!TARGET_MIPS16"
3616 {
3617   if (mips_expand_unaligned_store (operands[0], operands[3],
3618                                    INTVAL (operands[1]),
3619                                    INTVAL (operands[2])))
3620     DONE;
3621   else
3622     FAIL;
3623 })
3624
3625 ;; Unaligned word moves generated by the bit field patterns.
3626 ;;
3627 ;; As far as the rtl is concerned, both the left-part and right-part
3628 ;; instructions can access the whole field.  However, the real operand
3629 ;; refers to just the first or the last byte (depending on endianness).
3630 ;; We therefore use two memory operands to each instruction, one to
3631 ;; describe the rtl effect and one to use in the assembly output.
3632 ;;
3633 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3634 ;; This allows us to use the standard length calculations for the "load"
3635 ;; and "store" type attributes.
3636
3637 (define_insn "mov_lwl"
3638   [(set (match_operand:SI 0 "register_operand" "=d")
3639         (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3640                     (match_operand:QI 2 "memory_operand" "m")]
3641                    UNSPEC_LWL))]
3642   "!TARGET_MIPS16"
3643   "lwl\t%0,%2"
3644   [(set_attr "type" "load")
3645    (set_attr "mode" "SI")
3646    (set_attr "hazard" "none")])
3647
3648 (define_insn "mov_lwr"
3649   [(set (match_operand:SI 0 "register_operand" "=d")
3650         (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3651                     (match_operand:QI 2 "memory_operand" "m")
3652                     (match_operand:SI 3 "register_operand" "0")]
3653                    UNSPEC_LWR))]
3654   "!TARGET_MIPS16"
3655   "lwr\t%0,%2"
3656   [(set_attr "type" "load")
3657    (set_attr "mode" "SI")])
3658
3659
3660 (define_insn "mov_swl"
3661   [(set (match_operand:BLK 0 "memory_operand" "=m")
3662         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3663                      (match_operand:QI 2 "memory_operand" "m")]
3664                     UNSPEC_SWL))]
3665   "!TARGET_MIPS16"
3666   "swl\t%z1,%2"
3667   [(set_attr "type" "store")
3668    (set_attr "mode" "SI")])
3669
3670 (define_insn "mov_swr"
3671   [(set (match_operand:BLK 0 "memory_operand" "+m")
3672         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3673                      (match_operand:QI 2 "memory_operand" "m")
3674                      (match_dup 0)]
3675                     UNSPEC_SWR))]
3676   "!TARGET_MIPS16"
3677   "swr\t%z1,%2"
3678   [(set_attr "type" "store")
3679    (set_attr "mode" "SI")])
3680
3681
3682 (define_insn "mov_ldl"
3683   [(set (match_operand:DI 0 "register_operand" "=d")
3684         (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3685                     (match_operand:QI 2 "memory_operand" "m")]
3686                    UNSPEC_LDL))]
3687   "TARGET_64BIT && !TARGET_MIPS16"
3688   "ldl\t%0,%2"
3689   [(set_attr "type" "load")
3690    (set_attr "mode" "DI")])
3691
3692 (define_insn "mov_ldr"
3693   [(set (match_operand:DI 0 "register_operand" "=d")
3694         (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3695                     (match_operand:QI 2 "memory_operand" "m")
3696                     (match_operand:DI 3 "register_operand" "0")]
3697                    UNSPEC_LDR))]
3698   "TARGET_64BIT && !TARGET_MIPS16"
3699   "ldr\t%0,%2"
3700   [(set_attr "type" "load")
3701    (set_attr "mode" "DI")])
3702
3703
3704 (define_insn "mov_sdl"
3705   [(set (match_operand:BLK 0 "memory_operand" "=m")
3706         (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3707                      (match_operand:QI 2 "memory_operand" "m")]
3708                     UNSPEC_SDL))]
3709   "TARGET_64BIT && !TARGET_MIPS16"
3710   "sdl\t%z1,%2"
3711   [(set_attr "type" "store")
3712    (set_attr "mode" "DI")])
3713
3714 (define_insn "mov_sdr"
3715   [(set (match_operand:BLK 0 "memory_operand" "+m")
3716         (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3717                      (match_operand:QI 2 "memory_operand" "m")
3718                      (match_dup 0)]
3719                     UNSPEC_SDR))]
3720   "TARGET_64BIT && !TARGET_MIPS16"
3721   "sdr\t%z1,%2"
3722   [(set_attr "type" "store")
3723    (set_attr "mode" "DI")])
3724
3725 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3726 ;; The required value is:
3727 ;;
3728 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3729 ;;
3730 ;; which translates to:
3731 ;;
3732 ;;      lui     op0,%highest(op1)
3733 ;;      daddiu  op0,op0,%higher(op1)
3734 ;;      dsll    op0,op0,16
3735 ;;      daddiu  op0,op0,%hi(op1)
3736 ;;      dsll    op0,op0,16
3737 (define_insn_and_split "*lea_high64"
3738   [(set (match_operand:DI 0 "register_operand" "=d")
3739         (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3740   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3741   "#"
3742   "&& reload_completed"
3743   [(set (match_dup 0) (high:DI (match_dup 2)))
3744    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3745    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3746    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3747    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3748 {
3749   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3750   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3751 }
3752   [(set_attr "length" "20")])
3753
3754 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3755 ;; SYMBOL_GENERAL X will take 6 cycles.  This next pattern allows combine
3756 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3757 ;; used once.  We can then use the sequence:
3758 ;;
3759 ;;      lui     op0,%highest(op1)
3760 ;;      lui     op2,%hi(op1)
3761 ;;      daddiu  op0,op0,%higher(op1)
3762 ;;      daddiu  op2,op2,%lo(op1)
3763 ;;      dsll32  op0,op0,0
3764 ;;      daddu   op0,op0,op2
3765 ;;
3766 ;; which takes 4 cycles on most superscalar targets.
3767 (define_insn_and_split "*lea64"
3768   [(set (match_operand:DI 0 "register_operand" "=d")
3769         (match_operand:DI 1 "general_symbolic_operand" ""))
3770    (clobber (match_scratch:DI 2 "=&d"))]
3771   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3772   "#"
3773   "&& reload_completed"
3774   [(set (match_dup 0) (high:DI (match_dup 3)))
3775    (set (match_dup 2) (high:DI (match_dup 4)))
3776    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3777    (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3778    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3779    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3780 {
3781   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3782   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3783 }
3784   [(set_attr "length" "24")])
3785
3786 ;; Insns to fetch a global symbol from a big GOT.
3787
3788 (define_insn_and_split "*xgot_hisi"
3789   [(set (match_operand:SI 0 "register_operand" "=d")
3790         (high:SI (match_operand:SI 1 "global_got_operand" "")))]
3791   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3792   "#"
3793   "&& reload_completed"
3794   [(set (match_dup 0) (high:SI (match_dup 2)))
3795    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
3796 {
3797   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3798   operands[3] = pic_offset_table_rtx;
3799 }
3800   [(set_attr "got" "xgot_high")])
3801
3802 (define_insn_and_split "*xgot_losi"
3803   [(set (match_operand:SI 0 "register_operand" "=d")
3804         (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
3805                    (match_operand:SI 2 "global_got_operand" "")))]
3806   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3807   "#"
3808   "&& reload_completed"
3809   [(set (match_dup 0)
3810         (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3811   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3812   [(set_attr "got" "load")])
3813
3814 (define_insn_and_split "*xgot_hidi"
3815   [(set (match_operand:DI 0 "register_operand" "=d")
3816         (high:DI (match_operand:DI 1 "global_got_operand" "")))]
3817   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3818   "#"
3819   "&& reload_completed"
3820   [(set (match_dup 0) (high:DI (match_dup 2)))
3821    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
3822 {
3823   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3824   operands[3] = pic_offset_table_rtx;
3825 }
3826   [(set_attr "got" "xgot_high")])
3827
3828 (define_insn_and_split "*xgot_lodi"
3829   [(set (match_operand:DI 0 "register_operand" "=d")
3830         (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
3831                    (match_operand:DI 2 "global_got_operand" "")))]
3832   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3833   "#"
3834   "&& reload_completed"
3835   [(set (match_dup 0)
3836         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3837   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3838   [(set_attr "got" "load")])
3839
3840 ;; Insns to fetch a global symbol from a normal GOT.
3841
3842 (define_insn_and_split "*got_dispsi"
3843   [(set (match_operand:SI 0 "register_operand" "=d")
3844         (match_operand:SI 1 "global_got_operand" ""))]
3845   "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3846   "#"
3847   "&& reload_completed"
3848   [(set (match_dup 0)
3849         (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3850 {
3851   operands[2] = pic_offset_table_rtx;
3852   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3853 }
3854   [(set_attr "got" "load")])
3855
3856 (define_insn_and_split "*got_dispdi"
3857   [(set (match_operand:DI 0 "register_operand" "=d")
3858         (match_operand:DI 1 "global_got_operand" ""))]
3859   "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3860   "#"
3861   "&& reload_completed"
3862   [(set (match_dup 0)
3863         (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3864 {
3865   operands[2] = pic_offset_table_rtx;
3866   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3867 }
3868   [(set_attr "got" "load")])
3869
3870 ;; Insns for loading the high part of a local symbol.
3871
3872 (define_insn_and_split "*got_pagesi"
3873   [(set (match_operand:SI 0 "register_operand" "=d")
3874         (high:SI (match_operand:SI 1 "local_got_operand" "")))]
3875   "TARGET_EXPLICIT_RELOCS"
3876   "#"
3877   "&& reload_completed"
3878   [(set (match_dup 0)
3879         (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3880 {
3881   operands[2] = pic_offset_table_rtx;
3882   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3883 }
3884   [(set_attr "got" "load")])
3885
3886 (define_insn_and_split "*got_pagedi"
3887   [(set (match_operand:DI 0 "register_operand" "=d")
3888         (high:DI (match_operand:DI 1 "local_got_operand" "")))]
3889   "TARGET_EXPLICIT_RELOCS"
3890   "#"
3891   "&& reload_completed"
3892   [(set (match_dup 0)
3893         (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3894 {
3895   operands[2] = pic_offset_table_rtx;
3896   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3897 }
3898   [(set_attr "got" "load")])
3899
3900 ;; Lower-level instructions for loading an address from the GOT.
3901 ;; We could use MEMs, but an unspec gives more optimization
3902 ;; opportunities.
3903
3904 (define_insn "*load_gotsi"
3905   [(set (match_operand:SI 0 "register_operand" "=d")
3906         (unspec:SI [(match_operand:SI 1 "register_operand" "d")
3907                     (match_operand:SI 2 "immediate_operand" "")]
3908                    UNSPEC_LOAD_GOT))]
3909   "TARGET_ABICALLS"
3910   "lw\t%0,%R2(%1)"
3911   [(set_attr "type" "load")
3912    (set_attr "length" "4")])
3913
3914 (define_insn "*load_gotdi"
3915   [(set (match_operand:DI 0 "register_operand" "=d")
3916         (unspec:DI [(match_operand:DI 1 "register_operand" "d")
3917                     (match_operand:DI 2 "immediate_operand" "")]
3918                    UNSPEC_LOAD_GOT))]
3919   "TARGET_ABICALLS"
3920   "ld\t%0,%R2(%1)"
3921   [(set_attr "type" "load")
3922    (set_attr "length" "4")])
3923
3924 ;; Instructions for adding the low 16 bits of an address to a register.
3925 ;; Operand 2 is the address: print_operand works out which relocation
3926 ;; should be applied.
3927
3928 (define_insn "*lowsi"
3929   [(set (match_operand:SI 0 "register_operand" "=d")
3930         (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
3931                    (match_operand:SI 2 "immediate_operand" "")))]
3932   "!TARGET_MIPS16"
3933   "addiu\t%0,%1,%R2"
3934   [(set_attr "type"     "arith")
3935    (set_attr "mode"     "SI")])
3936
3937 (define_insn "*lowdi"
3938   [(set (match_operand:DI 0 "register_operand" "=d")
3939         (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
3940                    (match_operand:DI 2 "immediate_operand" "")))]
3941   "!TARGET_MIPS16 && TARGET_64BIT"
3942   "daddiu\t%0,%1,%R2"
3943   [(set_attr "type"     "arith")
3944    (set_attr "mode"     "DI")])
3945
3946 (define_insn "*lowsi_mips16"
3947   [(set (match_operand:SI 0 "register_operand" "=d")
3948         (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
3949                    (match_operand:SI 2 "immediate_operand" "")))]
3950   "TARGET_MIPS16"
3951   "addiu\t%0,%R2"
3952   [(set_attr "type"     "arith")
3953    (set_attr "mode"     "SI")
3954    (set_attr "length"   "8")])
3955
3956 (define_insn "*lowdi_mips16"
3957   [(set (match_operand:DI 0 "register_operand" "=d")
3958         (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
3959                    (match_operand:DI 2 "immediate_operand" "")))]
3960   "TARGET_MIPS16 && TARGET_64BIT"
3961   "daddiu\t%0,%R2"
3962   [(set_attr "type"     "arith")
3963    (set_attr "mode"     "DI")
3964    (set_attr "length"   "8")])
3965
3966 ;; 64-bit integer moves
3967
3968 ;; Unlike most other insns, the move insns can't be split with
3969 ;; different predicates, because register spilling and other parts of
3970 ;; the compiler, have memoized the insn number already.
3971
3972 (define_expand "movdi"
3973   [(set (match_operand:DI 0 "")
3974         (match_operand:DI 1 ""))]
3975   ""
3976 {
3977   if (mips_legitimize_move (DImode, operands[0], operands[1]))
3978     DONE;
3979 })
3980
3981 ;; For mips16, we need a special case to handle storing $31 into
3982 ;; memory, since we don't have a constraint to match $31.  This
3983 ;; instruction can be generated by save_restore_insns.
3984
3985 (define_insn ""
3986   [(set (match_operand:DI 0 "stack_operand" "=m")
3987         (reg:DI 31))]
3988   "TARGET_MIPS16 && TARGET_64BIT"
3989   "sd\t$31,%0"
3990   [(set_attr "type"     "store")
3991    (set_attr "mode"     "DI")])
3992
3993 (define_insn "*movdi_32bit"
3994   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
3995         (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
3996   "!TARGET_64BIT && !TARGET_MIPS16
3997    && (register_operand (operands[0], DImode)
3998        || reg_or_0_operand (operands[1], DImode))"
3999   { return mips_output_move (operands[0], operands[1]); }
4000   [(set_attr "type"     "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
4001    (set_attr "mode"     "DI")
4002    (set_attr "length"   "8,16,*,*,8,8,8,*,8,*")])
4003
4004 (define_insn "*movdi_32bit_mips16"
4005   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4006         (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4007   "!TARGET_64BIT && TARGET_MIPS16
4008    && (register_operand (operands[0], DImode)
4009        || register_operand (operands[1], DImode))"
4010   { return mips_output_move (operands[0], operands[1]); }
4011   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store,mfhilo")
4012    (set_attr "mode"     "DI")
4013    (set_attr "length"   "8,8,8,8,12,*,*,8")])
4014
4015 (define_insn "*movdi_64bit"
4016   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*B*C*D,*B*C*D,*d,*m")
4017         (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J*d,*d,*m,*B*C*D,*B*C*D"))]
4018   "TARGET_64BIT && !TARGET_MIPS16
4019    && (register_operand (operands[0], DImode)
4020        || reg_or_0_operand (operands[1], DImode))"
4021   { return mips_output_move (operands[0], operands[1]); }
4022   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
4023    (set_attr "mode"     "DI")
4024    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
4025
4026 (define_insn "*movdi_64bit_mips16"
4027   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4028         (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4029   "TARGET_64BIT && TARGET_MIPS16
4030    && (register_operand (operands[0], DImode)
4031        || register_operand (operands[1], DImode))"
4032   { return mips_output_move (operands[0], operands[1]); }
4033   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
4034    (set_attr "mode"     "DI")
4035    (set_attr_alternative "length"
4036                 [(const_int 4)
4037                  (const_int 4)
4038                  (const_int 4)
4039                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4040                                (const_int 4)
4041                                (const_int 8))
4042                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4043                                (const_int 8)
4044                                (const_int 12))
4045                  (const_string "*")
4046                  (const_string "*")
4047                  (const_string "*")])])
4048
4049
4050 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4051 ;; when the original load is a 4 byte instruction but the add and the
4052 ;; load are 2 2 byte instructions.
4053
4054 (define_split
4055   [(set (match_operand:DI 0 "register_operand")
4056         (mem:DI (plus:DI (match_dup 0)
4057                          (match_operand:DI 1 "const_int_operand"))))]
4058   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4059    && !TARGET_DEBUG_D_MODE
4060    && GET_CODE (operands[0]) == REG
4061    && M16_REG_P (REGNO (operands[0]))
4062    && GET_CODE (operands[1]) == CONST_INT
4063    && ((INTVAL (operands[1]) < 0
4064         && INTVAL (operands[1]) >= -0x10)
4065        || (INTVAL (operands[1]) >= 32 * 8
4066            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4067        || (INTVAL (operands[1]) >= 0
4068            && INTVAL (operands[1]) < 32 * 8
4069            && (INTVAL (operands[1]) & 7) != 0))"
4070   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4071    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4072 {
4073   HOST_WIDE_INT val = INTVAL (operands[1]);
4074
4075   if (val < 0)
4076     operands[2] = const0_rtx;
4077   else if (val >= 32 * 8)
4078     {
4079       int off = val & 7;
4080
4081       operands[1] = GEN_INT (0x8 + off);
4082       operands[2] = GEN_INT (val - off - 0x8);
4083     }
4084   else
4085     {
4086       int off = val & 7;
4087
4088       operands[1] = GEN_INT (off);
4089       operands[2] = GEN_INT (val - off);
4090     }
4091 })
4092
4093 ;; 32-bit Integer moves
4094
4095 ;; Unlike most other insns, the move insns can't be split with
4096 ;; different predicates, because register spilling and other parts of
4097 ;; the compiler, have memoized the insn number already.
4098
4099 (define_expand "movsi"
4100   [(set (match_operand:SI 0 "")
4101         (match_operand:SI 1 ""))]
4102   ""
4103 {
4104   if (mips_legitimize_move (SImode, operands[0], operands[1]))
4105     DONE;
4106 })
4107
4108 ;; We can only store $ra directly into a small sp offset.
4109
4110 (define_insn ""
4111   [(set (match_operand:SI 0 "stack_operand" "=m")
4112         (reg:SI 31))]
4113   "TARGET_MIPS16"
4114   "sw\t$31,%0"
4115   [(set_attr "type"     "store")
4116    (set_attr "mode"     "SI")])
4117
4118 ;; The difference between these two is whether or not ints are allowed
4119 ;; in FP registers (off by default, use -mdebugh to enable).
4120
4121 (define_insn "*movsi_internal"
4122   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*B*C*D,*B*C*D,*d,*m")
4123         (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*d,*m,*B*C*D,*B*C*D"))]
4124   "!TARGET_MIPS16
4125    && (register_operand (operands[0], SImode)
4126        || reg_or_0_operand (operands[1], SImode))"
4127   { return mips_output_move (operands[0], operands[1]); }
4128   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
4129    (set_attr "mode"     "SI")
4130    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
4131
4132 (define_insn "*movsi_mips16"
4133   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4134         (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4135   "TARGET_MIPS16
4136    && (register_operand (operands[0], SImode)
4137        || register_operand (operands[1], SImode))"
4138   { return mips_output_move (operands[0], operands[1]); }
4139   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
4140    (set_attr "mode"     "SI")
4141    (set_attr_alternative "length"
4142                 [(const_int 4)
4143                  (const_int 4)
4144                  (const_int 4)
4145                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4146                                (const_int 4)
4147                                (const_int 8))
4148                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4149                                (const_int 8)
4150                                (const_int 12))
4151                  (const_string "*")
4152                  (const_string "*")
4153                  (const_string "*")])])
4154
4155 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4156 ;; when the original load is a 4 byte instruction but the add and the
4157 ;; load are 2 2 byte instructions.
4158
4159 (define_split
4160   [(set (match_operand:SI 0 "register_operand")
4161         (mem:SI (plus:SI (match_dup 0)
4162                          (match_operand:SI 1 "const_int_operand"))))]
4163   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4164    && GET_CODE (operands[0]) == REG
4165    && M16_REG_P (REGNO (operands[0]))
4166    && GET_CODE (operands[1]) == CONST_INT
4167    && ((INTVAL (operands[1]) < 0
4168         && INTVAL (operands[1]) >= -0x80)
4169        || (INTVAL (operands[1]) >= 32 * 4
4170            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4171        || (INTVAL (operands[1]) >= 0
4172            && INTVAL (operands[1]) < 32 * 4
4173            && (INTVAL (operands[1]) & 3) != 0))"
4174   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4175    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4176 {
4177   HOST_WIDE_INT val = INTVAL (operands[1]);
4178
4179   if (val < 0)
4180     operands[2] = const0_rtx;
4181   else if (val >= 32 * 4)
4182     {
4183       int off = val & 3;
4184
4185       operands[1] = GEN_INT (0x7c + off);
4186       operands[2] = GEN_INT (val - off - 0x7c);
4187     }
4188   else
4189     {
4190       int off = val & 3;
4191
4192       operands[1] = GEN_INT (off);
4193       operands[2] = GEN_INT (val - off);
4194     }
4195 })
4196
4197 ;; On the mips16, we can split a load of certain constants into a load
4198 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
4199 ;; instructions.
4200
4201 (define_split
4202   [(set (match_operand:SI 0 "register_operand")
4203         (match_operand:SI 1 "const_int_operand"))]
4204   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4205    && GET_CODE (operands[0]) == REG
4206    && M16_REG_P (REGNO (operands[0]))
4207    && GET_CODE (operands[1]) == CONST_INT
4208    && INTVAL (operands[1]) >= 0x100
4209    && INTVAL (operands[1]) <= 0xff + 0x7f"
4210   [(set (match_dup 0) (match_dup 1))
4211    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4212 {
4213   int val = INTVAL (operands[1]);
4214
4215   operands[1] = GEN_INT (0xff);
4216   operands[2] = GEN_INT (val - 0xff);
4217 })
4218
4219 ;; This insn handles moving CCmode values.  It's really just a
4220 ;; slightly simplified copy of movsi_internal2, with additional cases
4221 ;; to move a condition register to a general register and to move
4222 ;; between the general registers and the floating point registers.
4223
4224 (define_insn "movcc"
4225   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
4226         (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
4227   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4228   { return mips_output_move (operands[0], operands[1]); }
4229   [(set_attr "type"     "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
4230    (set_attr "mode"     "SI")
4231    (set_attr "length"   "8,4,*,*,4,4,4,*,*")])
4232
4233 ;; Reload condition code registers.  reload_incc and reload_outcc
4234 ;; both handle moves from arbitrary operands into condition code
4235 ;; registers.  reload_incc handles the more common case in which
4236 ;; a source operand is constrained to be in a condition-code
4237 ;; register, but has not been allocated to one.
4238 ;;
4239 ;; Sometimes, such as in movcc, we have a CCmode destination whose
4240 ;; constraints do not include 'z'.  reload_outcc handles the case
4241 ;; when such an operand is allocated to a condition-code register.
4242 ;;
4243 ;; Note that reloads from a condition code register to some
4244 ;; other location can be done using ordinary moves.  Moving
4245 ;; into a GPR takes a single movcc, moving elsewhere takes
4246 ;; two.  We can leave these cases to the generic reload code.
4247 (define_expand "reload_incc"
4248   [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4249         (match_operand:CC 1 "general_operand" ""))
4250    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4251   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4252 {
4253   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4254   DONE;
4255 })
4256
4257 (define_expand "reload_outcc"
4258   [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4259         (match_operand:CC 1 "register_operand" ""))
4260    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4261   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4262 {
4263   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4264   DONE;
4265 })
4266
4267 ;; MIPS4 supports loading and storing a floating point register from
4268 ;; the sum of two general registers.  We use two versions for each of
4269 ;; these four instructions: one where the two general registers are
4270 ;; SImode, and one where they are DImode.  This is because general
4271 ;; registers will be in SImode when they hold 32 bit values, but,
4272 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
4273 ;; instructions will still work correctly.
4274
4275 ;; ??? Perhaps it would be better to support these instructions by
4276 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
4277 ;; these instructions can only be used to load and store floating
4278 ;; point registers, that would probably cause trouble in reload.
4279
4280 (define_insn ""
4281   [(set (match_operand:SF 0 "register_operand" "=f")
4282         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4283                          (match_operand:SI 2 "register_operand" "d"))))]
4284   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4285   "lwxc1\t%0,%1(%2)"
4286   [(set_attr "type"     "fpidxload")
4287    (set_attr "mode"     "SF")
4288    (set_attr "length"   "4")])
4289
4290 (define_insn ""
4291   [(set (match_operand:SF 0 "register_operand" "=f")
4292         (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4293                          (match_operand:DI 2 "register_operand" "d"))))]
4294   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4295   "lwxc1\t%0,%1(%2)"
4296   [(set_attr "type"     "fpidxload")
4297    (set_attr "mode"     "SF")
4298    (set_attr "length"   "4")])
4299
4300 (define_insn ""
4301   [(set (match_operand:DF 0 "register_operand" "=f")
4302         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4303                          (match_operand:SI 2 "register_operand" "d"))))]
4304   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4305   "ldxc1\t%0,%1(%2)"
4306   [(set_attr "type"     "fpidxload")
4307    (set_attr "mode"     "DF")
4308    (set_attr "length"   "4")])
4309
4310 (define_insn ""
4311   [(set (match_operand:DF 0 "register_operand" "=f")
4312         (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4313                          (match_operand:DI 2 "register_operand" "d"))))]
4314   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4315   "ldxc1\t%0,%1(%2)"
4316   [(set_attr "type"     "fpidxload")
4317    (set_attr "mode"     "DF")
4318    (set_attr "length"   "4")])
4319
4320 (define_insn ""
4321   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4322                          (match_operand:SI 2 "register_operand" "d")))
4323         (match_operand:SF 0 "register_operand" "f"))]
4324   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4325   "swxc1\t%0,%1(%2)"
4326   [(set_attr "type"     "fpidxstore")
4327    (set_attr "mode"     "SF")
4328    (set_attr "length"   "4")])
4329
4330 (define_insn ""
4331   [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4332                          (match_operand:DI 2 "register_operand" "d")))
4333         (match_operand:SF 0 "register_operand" "f"))]
4334   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4335   "swxc1\t%0,%1(%2)"
4336   [(set_attr "type"     "fpidxstore")
4337    (set_attr "mode"     "SF")
4338    (set_attr "length"   "4")])
4339
4340 (define_insn ""
4341   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4342                          (match_operand:SI 2 "register_operand" "d")))
4343         (match_operand:DF 0 "register_operand" "f"))]
4344   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4345   "sdxc1\t%0,%1(%2)"
4346   [(set_attr "type"     "fpidxstore")
4347    (set_attr "mode"     "DF")
4348    (set_attr "length"   "4")])
4349
4350 (define_insn ""
4351   [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4352                          (match_operand:DI 2 "register_operand" "d")))
4353         (match_operand:DF 0 "register_operand" "f"))]
4354   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4355   "sdxc1\t%0,%1(%2)"
4356   [(set_attr "type"     "fpidxstore")
4357    (set_attr "mode"     "DF")
4358    (set_attr "length"   "4")])
4359
4360 ;; 16-bit Integer moves
4361
4362 ;; Unlike most other insns, the move insns can't be split with
4363 ;; different predicates, because register spilling and other parts of
4364 ;; the compiler, have memoized the insn number already.
4365 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4366
4367 (define_expand "movhi"
4368   [(set (match_operand:HI 0 "")
4369         (match_operand:HI 1 ""))]
4370   ""
4371 {
4372   if (mips_legitimize_move (HImode, operands[0], operands[1]))
4373     DONE;
4374 })
4375
4376 (define_insn "*movhi_internal"
4377   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4378         (match_operand:HI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
4379   "!TARGET_MIPS16
4380    && (register_operand (operands[0], HImode)
4381        || reg_or_0_operand (operands[1], HImode))"
4382   "@
4383     move\t%0,%1
4384     li\t%0,%1
4385     lhu\t%0,%1
4386     sh\t%z1,%0
4387     mfc1\t%0,%1
4388     mtc1\t%1,%0
4389     mov.s\t%0,%1
4390     mt%0\t%1"
4391   [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4392    (set_attr "mode"     "HI")
4393    (set_attr "length"   "4,4,*,*,4,4,4,4")])
4394
4395 (define_insn "*movhi_mips16"
4396   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4397         (match_operand:HI 1 "move_operand"         "d,d,y,K,N,m,d"))]
4398   "TARGET_MIPS16
4399    && (register_operand (operands[0], HImode)
4400        || register_operand (operands[1], HImode))"
4401   "@
4402     move\t%0,%1
4403     move\t%0,%1
4404     move\t%0,%1
4405     li\t%0,%1
4406     #
4407     lhu\t%0,%1
4408     sh\t%1,%0"
4409   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
4410    (set_attr "mode"     "HI")
4411    (set_attr_alternative "length"
4412                 [(const_int 4)
4413                  (const_int 4)
4414                  (const_int 4)
4415                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4416                                (const_int 4)
4417                                (const_int 8))
4418                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4419                                (const_int 8)
4420                                (const_int 12))
4421                  (const_string "*")
4422                  (const_string "*")])])
4423
4424
4425 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4426 ;; when the original load is a 4 byte instruction but the add and the
4427 ;; load are 2 2 byte instructions.
4428
4429 (define_split
4430   [(set (match_operand:HI 0 "register_operand")
4431         (mem:HI (plus:SI (match_dup 0)
4432                          (match_operand:SI 1 "const_int_operand"))))]
4433   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4434    && GET_CODE (operands[0]) == REG
4435    && M16_REG_P (REGNO (operands[0]))
4436    && GET_CODE (operands[1]) == CONST_INT
4437    && ((INTVAL (operands[1]) < 0
4438         && INTVAL (operands[1]) >= -0x80)
4439        || (INTVAL (operands[1]) >= 32 * 2
4440            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4441        || (INTVAL (operands[1]) >= 0
4442            && INTVAL (operands[1]) < 32 * 2
4443            && (INTVAL (operands[1]) & 1) != 0))"
4444   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4445    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4446 {
4447   HOST_WIDE_INT val = INTVAL (operands[1]);
4448
4449   if (val < 0)
4450     operands[2] = const0_rtx;
4451   else if (val >= 32 * 2)
4452     {
4453       int off = val & 1;
4454
4455       operands[1] = GEN_INT (0x7e + off);
4456       operands[2] = GEN_INT (val - off - 0x7e);
4457     }
4458   else
4459     {
4460       int off = val & 1;
4461
4462       operands[1] = GEN_INT (off);
4463       operands[2] = GEN_INT (val - off);
4464     }
4465 })
4466
4467 ;; 8-bit Integer moves
4468
4469 ;; Unlike most other insns, the move insns can't be split with
4470 ;; different predicates, because register spilling and other parts of
4471 ;; the compiler, have memoized the insn number already.
4472 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4473
4474 (define_expand "movqi"
4475   [(set (match_operand:QI 0 "")
4476         (match_operand:QI 1 ""))]
4477   ""
4478 {
4479   if (mips_legitimize_move (QImode, operands[0], operands[1]))
4480     DONE;
4481 })
4482
4483 (define_insn "*movqi_internal"
4484   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4485         (match_operand:QI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
4486   "!TARGET_MIPS16
4487    && (register_operand (operands[0], QImode)
4488        || reg_or_0_operand (operands[1], QImode))"
4489   "@
4490     move\t%0,%1
4491     li\t%0,%1
4492     lbu\t%0,%1
4493     sb\t%z1,%0
4494     mfc1\t%0,%1
4495     mtc1\t%1,%0
4496     mov.s\t%0,%1
4497     mt%0\t%1"
4498   [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4499    (set_attr "mode"     "QI")
4500    (set_attr "length"   "4,4,*,*,4,4,4,4")])
4501
4502 (define_insn "*movqi_mips16"
4503   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4504         (match_operand:QI 1 "move_operand"         "d,d,y,K,N,m,d"))]
4505   "TARGET_MIPS16
4506    && (register_operand (operands[0], QImode)
4507        || register_operand (operands[1], QImode))"
4508   "@
4509     move\t%0,%1
4510     move\t%0,%1
4511     move\t%0,%1
4512     li\t%0,%1
4513     #
4514     lbu\t%0,%1
4515     sb\t%1,%0"
4516   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
4517    (set_attr "mode"     "QI")
4518    (set_attr "length"   "4,4,4,4,8,*,*")])
4519
4520 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
4521 ;; when the original load is a 4 byte instruction but the add and the
4522 ;; load are 2 2 byte instructions.
4523
4524 (define_split
4525   [(set (match_operand:QI 0 "register_operand")
4526         (mem:QI (plus:SI (match_dup 0)
4527                          (match_operand:SI 1 "const_int_operand"))))]
4528   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4529    && GET_CODE (operands[0]) == REG
4530    && M16_REG_P (REGNO (operands[0]))
4531    && GET_CODE (operands[1]) == CONST_INT
4532    && ((INTVAL (operands[1]) < 0
4533         && INTVAL (operands[1]) >= -0x80)
4534        || (INTVAL (operands[1]) >= 32
4535            && INTVAL (operands[1]) <= 31 + 0x7f))"
4536   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4537    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4538 {
4539   HOST_WIDE_INT val = INTVAL (operands[1]);
4540
4541   if (val < 0)
4542     operands[2] = const0_rtx;
4543   else
4544     {
4545       operands[1] = GEN_INT (0x7f);
4546       operands[2] = GEN_INT (val - 0x7f);
4547     }
4548 })
4549
4550 ;; 32-bit floating point moves
4551
4552 (define_expand "movsf"
4553   [(set (match_operand:SF 0 "")
4554         (match_operand:SF 1 ""))]
4555   ""
4556 {
4557   if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4558     DONE;
4559 })
4560
4561 (define_insn "*movsf_hardfloat"
4562   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4563         (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
4564   "TARGET_HARD_FLOAT
4565    && (register_operand (operands[0], SFmode)
4566        || reg_or_0_operand (operands[1], SFmode))"
4567   { return mips_output_move (operands[0], operands[1]); }
4568   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4569    (set_attr "mode"     "SF")
4570    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
4571
4572 (define_insn "*movsf_softfloat"
4573   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4574         (match_operand:SF 1 "move_operand" "Gd,m,d"))]
4575   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4576    && (register_operand (operands[0], SFmode)
4577        || reg_or_0_operand (operands[1], SFmode))"
4578   { return mips_output_move (operands[0], operands[1]); }
4579   [(set_attr "type"     "arith,load,store")
4580    (set_attr "mode"     "SF")
4581    (set_attr "length"   "4,*,*")])
4582
4583 (define_insn "*movsf_mips16"
4584   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4585         (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
4586   "TARGET_MIPS16
4587    && (register_operand (operands[0], SFmode)
4588        || register_operand (operands[1], SFmode))"
4589   { return mips_output_move (operands[0], operands[1]); }
4590   [(set_attr "type"     "arith,arith,arith,load,store")
4591    (set_attr "mode"     "SF")
4592    (set_attr "length"   "4,4,4,*,*")])
4593
4594
4595 ;; 64-bit floating point moves
4596
4597 (define_expand "movdf"
4598   [(set (match_operand:DF 0 "")
4599         (match_operand:DF 1 ""))]
4600   ""
4601 {
4602   if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4603     DONE;
4604 })
4605
4606 (define_insn "*movdf_hardfloat_64bit"
4607   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4608         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4609   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
4610    && (register_operand (operands[0], DFmode)
4611        || reg_or_0_operand (operands[1], DFmode))"
4612   { return mips_output_move (operands[0], operands[1]); }
4613   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4614    (set_attr "mode"     "DF")
4615    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
4616
4617 (define_insn "*movdf_hardfloat_32bit"
4618   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4619         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4620   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
4621    && (register_operand (operands[0], DFmode)
4622        || reg_or_0_operand (operands[1], DFmode))"
4623   { return mips_output_move (operands[0], operands[1]); }
4624   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4625    (set_attr "mode"     "DF")
4626    (set_attr "length"   "4,8,*,*,8,8,8,*,*")])
4627
4628 (define_insn "*movdf_softfloat"
4629   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
4630         (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
4631   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4632    && (register_operand (operands[0], DFmode)
4633        || reg_or_0_operand (operands[1], DFmode))"
4634   { return mips_output_move (operands[0], operands[1]); }
4635   [(set_attr "type"     "arith,load,store,xfer,xfer,fmove")
4636    (set_attr "mode"     "DF")
4637    (set_attr "length"   "8,*,*,4,4,4")])
4638
4639 (define_insn "*movdf_mips16"
4640   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4641         (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4642   "TARGET_MIPS16
4643    && (register_operand (operands[0], DFmode)
4644        || register_operand (operands[1], DFmode))"
4645   { return mips_output_move (operands[0], operands[1]); }
4646   [(set_attr "type"     "arith,arith,arith,load,store")
4647    (set_attr "mode"     "DF")
4648    (set_attr "length"   "8,8,8,*,*")])
4649
4650 (define_split
4651   [(set (match_operand:DI 0 "nonimmediate_operand")
4652         (match_operand:DI 1 "move_operand"))]
4653   "reload_completed && !TARGET_64BIT
4654    && mips_split_64bit_move_p (operands[0], operands[1])"
4655   [(const_int 0)]
4656 {
4657   mips_split_64bit_move (operands[0], operands[1]);
4658   DONE;
4659 })
4660
4661 (define_split
4662   [(set (match_operand:DF 0 "nonimmediate_operand")
4663         (match_operand:DF 1 "move_operand"))]
4664   "reload_completed && !TARGET_64BIT
4665    && mips_split_64bit_move_p (operands[0], operands[1])"
4666   [(const_int 0)]
4667 {
4668   mips_split_64bit_move (operands[0], operands[1]);
4669   DONE;
4670 })
4671
4672 ;; When generating mips16 code, split moves of negative constants into
4673 ;; a positive "li" followed by a negation.
4674 (define_split
4675   [(set (match_operand 0 "register_operand")
4676         (match_operand 1 "const_int_operand"))]
4677   "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4678   [(set (match_dup 2)
4679         (match_dup 3))
4680    (set (match_dup 2)
4681         (neg:SI (match_dup 2)))]
4682 {
4683   operands[2] = gen_lowpart (SImode, operands[0]);
4684   operands[3] = GEN_INT (-INTVAL (operands[1]));
4685 })
4686
4687 ;; The HI and LO registers are not truly independent.  If we move an mthi
4688 ;; instruction before an mflo instruction, it will make the result of the
4689 ;; mflo unpredictable.  The same goes for mtlo and mfhi.
4690 ;;
4691 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4692 ;; Operand 1 is the register we want, operand 2 is the other one.
4693
4694 (define_insn "mfhilo_di"
4695   [(set (match_operand:DI 0 "register_operand" "=d,d")
4696         (unspec:DI [(match_operand:DI 1 "register_operand" "h,l")
4697                     (match_operand:DI 2 "register_operand" "l,h")]
4698                    UNSPEC_MFHILO))]
4699   "TARGET_64BIT"
4700   "mf%1\t%0"
4701   [(set_attr "type" "mfhilo")])
4702
4703 (define_insn "mfhilo_si"
4704   [(set (match_operand:SI 0 "register_operand" "=d,d")
4705         (unspec:SI [(match_operand:SI 1 "register_operand" "h,l")
4706                     (match_operand:SI 2 "register_operand" "l,h")]
4707                    UNSPEC_MFHILO))]
4708   ""
4709   "mf%1\t%0"
4710   [(set_attr "type" "mfhilo")])
4711
4712 ;; Patterns for loading or storing part of a paired floating point
4713 ;; register.  We need them because odd-numbered floating-point registers
4714 ;; are not fully independent: see mips_split_64bit_move.
4715
4716 ;; Load the low word of operand 0 with operand 1.
4717 (define_insn "load_df_low"
4718   [(set (match_operand:DF 0 "register_operand" "=f,f")
4719         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
4720                    UNSPEC_LOAD_DF_LOW))]
4721   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4722 {
4723   operands[0] = mips_subword (operands[0], 0);
4724   return mips_output_move (operands[0], operands[1]);
4725 }
4726   [(set_attr "type"     "xfer,fpload")
4727    (set_attr "mode"     "SF")])
4728
4729 ;; Load the high word of operand 0 from operand 1, preserving the value
4730 ;; in the low word.
4731 (define_insn "load_df_high"
4732   [(set (match_operand:DF 0 "register_operand" "=f,f")
4733         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
4734                     (match_operand:DF 2 "register_operand" "0,0")]
4735                    UNSPEC_LOAD_DF_HIGH))]
4736   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4737 {
4738   operands[0] = mips_subword (operands[0], 1);
4739   return mips_output_move (operands[0], operands[1]);
4740 }
4741   [(set_attr "type"     "xfer,fpload")
4742    (set_attr "mode"     "SF")])
4743
4744 ;; Store the high word of operand 1 in operand 0.  The corresponding
4745 ;; low-word move is done in the normal way.
4746 (define_insn "store_df_high"
4747   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4748         (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4749                    UNSPEC_STORE_DF_HIGH))]
4750   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4751 {
4752   operands[1] = mips_subword (operands[1], 1);
4753   return mips_output_move (operands[0], operands[1]);
4754 }
4755   [(set_attr "type"     "xfer,fpstore")
4756    (set_attr "mode"     "SF")])
4757
4758 ;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
4759 ;; of _gp from the start of this function.  Operand 1 is the incoming
4760 ;; function address.
4761 (define_insn_and_split "loadgp"
4762   [(unspec_volatile [(match_operand 0 "" "")
4763                      (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4764   "TARGET_ABICALLS && TARGET_NEWABI"
4765   "#"
4766   ""
4767   [(set (match_dup 2) (match_dup 3))
4768    (set (match_dup 2) (match_dup 4))
4769    (set (match_dup 2) (match_dup 5))]
4770 {
4771   operands[2] = pic_offset_table_rtx;
4772   operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4773   operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4774   operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4775 }
4776   [(set_attr "length" "12")])
4777
4778 ;; The use of gp is hidden when not using explicit relocations.
4779 ;; This blockage instruction prevents the gp load from being
4780 ;; scheduled after an implicit use of gp.  It also prevents
4781 ;; the load from being deleted as dead.
4782 (define_insn "loadgp_blockage"
4783   [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4784   ""
4785   ""
4786   [(set_attr "type"     "unknown")
4787    (set_attr "mode"     "none")
4788    (set_attr "length"   "0")])
4789
4790 ;; Emit a .cprestore directive, which expands to a single store instruction.
4791 ;; Note that we continue to use .cprestore for explicit reloc code so that
4792 ;; jals inside inlines asms will work correctly.
4793 (define_insn "cprestore"
4794   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
4795                     UNSPEC_CPRESTORE)]
4796   ""
4797   ".cprestore\t%0"
4798   [(set_attr "type" "store")
4799    (set_attr "length" "4")])
4800 \f
4801 ;; Block moves, see mips.c for more details.
4802 ;; Argument 0 is the destination
4803 ;; Argument 1 is the source
4804 ;; Argument 2 is the length
4805 ;; Argument 3 is the alignment
4806
4807 (define_expand "movmemsi"
4808   [(parallel [(set (match_operand:BLK 0 "general_operand")
4809                    (match_operand:BLK 1 "general_operand"))
4810               (use (match_operand:SI 2 ""))
4811               (use (match_operand:SI 3 "const_int_operand"))])]
4812   "!TARGET_MIPS16 && !TARGET_MEMCPY"
4813 {
4814   if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4815     DONE;
4816   else
4817     FAIL;
4818 })
4819 \f
4820 ;;
4821 ;;  ....................
4822 ;;
4823 ;;      SHIFTS
4824 ;;
4825 ;;  ....................
4826
4827 ;; Many of these instructions use trivial define_expands, because we
4828 ;; want to use a different set of constraints when TARGET_MIPS16.
4829
4830 (define_expand "ashlsi3"
4831   [(set (match_operand:SI 0 "register_operand")
4832         (ashift:SI (match_operand:SI 1 "register_operand")
4833                    (match_operand:SI 2 "arith_operand")))]
4834   ""
4835 {
4836   /* On the mips16, a shift of more than 8 is a four byte instruction,
4837      so, for a shift between 8 and 16, it is just as fast to do two
4838      shifts of 8 or less.  If there is a lot of shifting going on, we
4839      may win in CSE.  Otherwise combine will put the shifts back
4840      together again.  This can be called by function_arg, so we must
4841      be careful not to allocate a new register if we've reached the
4842      reload pass.  */
4843   if (TARGET_MIPS16
4844       && optimize
4845       && GET_CODE (operands[2]) == CONST_INT
4846       && INTVAL (operands[2]) > 8
4847       && INTVAL (operands[2]) <= 16
4848       && ! reload_in_progress
4849       && ! reload_completed)
4850     {
4851       rtx temp = gen_reg_rtx (SImode);
4852
4853       emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
4854       emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
4855                                         GEN_INT (INTVAL (operands[2]) - 8)));
4856       DONE;
4857     }
4858 })
4859
4860 (define_insn "ashlsi3_internal1"
4861   [(set (match_operand:SI 0 "register_operand" "=d")
4862         (ashift:SI (match_operand:SI 1 "register_operand" "d")
4863                    (match_operand:SI 2 "arith_operand" "dI")))]
4864   "!TARGET_MIPS16"
4865 {
4866   if (GET_CODE (operands[2]) == CONST_INT)
4867     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4868
4869   return "sll\t%0,%1,%2";
4870 }
4871   [(set_attr "type"     "shift")
4872    (set_attr "mode"     "SI")])
4873
4874 (define_insn "ashlsi3_internal1_extend"
4875   [(set (match_operand:DI 0 "register_operand" "=d")
4876        (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
4877                                   (match_operand:SI 2 "arith_operand" "dI"))))]
4878   "TARGET_64BIT && !TARGET_MIPS16"
4879 {
4880   if (GET_CODE (operands[2]) == CONST_INT)
4881     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4882
4883   return "sll\t%0,%1,%2";
4884 }
4885   [(set_attr "type"    "shift")
4886    (set_attr "mode"    "DI")])
4887
4888
4889 (define_insn "ashlsi3_internal2"
4890   [(set (match_operand:SI 0 "register_operand" "=d,d")
4891         (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
4892                    (match_operand:SI 2 "arith_operand" "d,I")))]
4893   "TARGET_MIPS16"
4894 {
4895   if (which_alternative == 0)
4896     return "sll\t%0,%2";
4897
4898   if (GET_CODE (operands[2]) == CONST_INT)
4899     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4900
4901   return "sll\t%0,%1,%2";
4902 }
4903   [(set_attr "type"     "shift")
4904    (set_attr "mode"     "SI")
4905    (set_attr_alternative "length"
4906                 [(const_int 4)
4907                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4908                                (const_int 4)
4909                                (const_int 8))])])
4910
4911 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4912
4913 (define_split
4914   [(set (match_operand:SI 0 "register_operand")
4915         (ashift:SI (match_operand:SI 1 "register_operand")
4916                    (match_operand:SI 2 "const_int_operand")))]
4917   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4918    && GET_CODE (operands[2]) == CONST_INT
4919    && INTVAL (operands[2]) > 8
4920    && INTVAL (operands[2]) <= 16"
4921   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
4922    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4923   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4924
4925 (define_expand "ashldi3"
4926   [(set (match_operand:DI 0 "register_operand")
4927         (ashift:DI (match_operand:DI 1 "register_operand")
4928                    (match_operand:SI 2 "arith_operand")))]
4929   "TARGET_64BIT"
4930 {
4931   /* On the mips16, a shift of more than 8 is a four byte
4932      instruction, so, for a shift between 8 and 16, it is just as
4933      fast to do two shifts of 8 or less.  If there is a lot of
4934      shifting going on, we may win in CSE.  Otherwise combine will
4935      put the shifts back together again.  This can be called by
4936      function_arg, so we must be careful not to allocate a new
4937      register if we've reached the reload pass.  */
4938   if (TARGET_MIPS16
4939       && optimize
4940       && GET_CODE (operands[2]) == CONST_INT
4941       && INTVAL (operands[2]) > 8
4942       && INTVAL (operands[2]) <= 16
4943       && ! reload_in_progress
4944       && ! reload_completed)
4945     {
4946       rtx temp = gen_reg_rtx (DImode);
4947
4948       emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
4949       emit_insn (gen_ashldi3_internal (operands[0], temp,
4950                                        GEN_INT (INTVAL (operands[2]) - 8)));
4951       DONE;
4952     }
4953 })
4954
4955
4956 (define_insn "ashldi3_internal"
4957   [(set (match_operand:DI 0 "register_operand" "=d")
4958         (ashift:DI (match_operand:DI 1 "register_operand" "d")
4959                    (match_operand:SI 2 "arith_operand" "dI")))]
4960   "TARGET_64BIT && !TARGET_MIPS16"
4961 {
4962   if (GET_CODE (operands[2]) == CONST_INT)
4963     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4964
4965   return "dsll\t%0,%1,%2";
4966 }
4967   [(set_attr "type"     "shift")
4968    (set_attr "mode"     "DI")])
4969
4970 (define_insn ""
4971   [(set (match_operand:DI 0 "register_operand" "=d,d")
4972         (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4973                    (match_operand:SI 2 "arith_operand" "d,I")))]
4974   "TARGET_64BIT && TARGET_MIPS16"
4975 {
4976   if (which_alternative == 0)
4977     return "dsll\t%0,%2";
4978
4979   if (GET_CODE (operands[2]) == CONST_INT)
4980     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4981
4982   return "dsll\t%0,%1,%2";
4983 }
4984   [(set_attr "type"     "shift")
4985    (set_attr "mode"     "DI")
4986    (set_attr_alternative "length"
4987                 [(const_int 4)
4988                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4989                                (const_int 4)
4990                                (const_int 8))])])
4991
4992
4993 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4994
4995 (define_split
4996   [(set (match_operand:DI 0 "register_operand")
4997         (ashift:DI (match_operand:DI 1 "register_operand")
4998                    (match_operand:SI 2 "const_int_operand")))]
4999   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5000    && reload_completed
5001    && GET_CODE (operands[2]) == CONST_INT
5002    && INTVAL (operands[2]) > 8
5003    && INTVAL (operands[2]) <= 16"
5004   [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
5005    (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
5006   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5007
5008 (define_expand "ashrsi3"
5009   [(set (match_operand:SI 0 "register_operand")
5010         (ashiftrt:SI (match_operand:SI 1 "register_operand")
5011                      (match_operand:SI 2 "arith_operand")))]
5012   ""
5013 {
5014   /* On the mips16, a shift of more than 8 is a four byte instruction,
5015      so, for a shift between 8 and 16, it is just as fast to do two
5016      shifts of 8 or less.  If there is a lot of shifting going on, we
5017      may win in CSE.  Otherwise combine will put the shifts back
5018      together again.  */
5019   if (TARGET_MIPS16
5020       && optimize
5021       && GET_CODE (operands[2]) == CONST_INT
5022       && INTVAL (operands[2]) > 8
5023       && INTVAL (operands[2]) <= 16)
5024     {
5025       rtx temp = gen_reg_rtx (SImode);
5026
5027       emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5028       emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
5029                                         GEN_INT (INTVAL (operands[2]) - 8)));
5030       DONE;
5031     }
5032 })
5033
5034 (define_insn "ashrsi3_internal1"
5035   [(set (match_operand:SI 0 "register_operand" "=d")
5036         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
5037                      (match_operand:SI 2 "arith_operand" "dI")))]
5038   "!TARGET_MIPS16"
5039 {
5040   if (GET_CODE (operands[2]) == CONST_INT)
5041     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5042
5043   return "sra\t%0,%1,%2";
5044 }
5045   [(set_attr "type"     "shift")
5046    (set_attr "mode"     "SI")])
5047
5048 (define_insn "ashrsi3_internal2"
5049   [(set (match_operand:SI 0 "register_operand" "=d,d")
5050         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5051                      (match_operand:SI 2 "arith_operand" "d,I")))]
5052   "TARGET_MIPS16"
5053 {
5054   if (which_alternative == 0)
5055     return "sra\t%0,%2";
5056
5057   if (GET_CODE (operands[2]) == CONST_INT)
5058     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5059
5060   return "sra\t%0,%1,%2";
5061 }
5062   [(set_attr "type"     "shift")
5063    (set_attr "mode"     "SI")
5064    (set_attr_alternative "length"
5065                 [(const_int 4)
5066                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5067                                (const_int 4)
5068                                (const_int 8))])])
5069
5070
5071 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5072
5073 (define_split
5074   [(set (match_operand:SI 0 "register_operand")
5075         (ashiftrt:SI (match_operand:SI 1 "register_operand")
5076                      (match_operand:SI 2 "const_int_operand")))]
5077   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5078    && GET_CODE (operands[2]) == CONST_INT
5079    && INTVAL (operands[2]) > 8
5080    && INTVAL (operands[2]) <= 16"
5081   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
5082    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
5083   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5084
5085 (define_expand "ashrdi3"
5086   [(set (match_operand:DI 0 "register_operand")
5087         (ashiftrt:DI (match_operand:DI 1 "register_operand")
5088                      (match_operand:SI 2 "arith_operand")))]
5089   "TARGET_64BIT"
5090 {
5091   /* On the mips16, a shift of more than 8 is a four byte
5092      instruction, so, for a shift between 8 and 16, it is just as
5093      fast to do two shifts of 8 or less.  If there is a lot of
5094      shifting going on, we may win in CSE.  Otherwise combine will
5095      put the shifts back together again.  */
5096   if (TARGET_MIPS16
5097       && optimize
5098       && GET_CODE (operands[2]) == CONST_INT
5099       && INTVAL (operands[2]) > 8
5100       && INTVAL (operands[2]) <= 16)
5101     {
5102       rtx temp = gen_reg_rtx (DImode);
5103
5104       emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
5105       emit_insn (gen_ashrdi3_internal (operands[0], temp,
5106                                        GEN_INT (INTVAL (operands[2]) - 8)));
5107       DONE;
5108     }
5109 })
5110
5111
5112 (define_insn "ashrdi3_internal"
5113   [(set (match_operand:DI 0 "register_operand" "=d")
5114         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5115                      (match_operand:SI 2 "arith_operand" "dI")))]
5116   "TARGET_64BIT && !TARGET_MIPS16"
5117 {
5118   if (GET_CODE (operands[2]) == CONST_INT)
5119     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5120
5121   return "dsra\t%0,%1,%2";
5122 }
5123   [(set_attr "type"     "shift")
5124    (set_attr "mode"     "DI")])
5125
5126 (define_insn ""
5127   [(set (match_operand:DI 0 "register_operand" "=d,d")
5128         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5129                      (match_operand:SI 2 "arith_operand" "d,I")))]
5130   "TARGET_64BIT && TARGET_MIPS16"
5131 {
5132   if (GET_CODE (operands[2]) == CONST_INT)
5133     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5134
5135   return "dsra\t%0,%2";
5136 }
5137   [(set_attr "type"     "shift")
5138    (set_attr "mode"     "DI")
5139    (set_attr_alternative "length"
5140                 [(const_int 4)
5141                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5142                                (const_int 4)
5143                                (const_int 8))])])
5144
5145 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5146
5147 (define_split
5148   [(set (match_operand:DI 0 "register_operand")
5149         (ashiftrt:DI (match_operand:DI 1 "register_operand")
5150                      (match_operand:SI 2 "const_int_operand")))]
5151   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5152    && reload_completed
5153    && GET_CODE (operands[2]) == CONST_INT
5154    && INTVAL (operands[2]) > 8
5155    && INTVAL (operands[2]) <= 16"
5156   [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
5157    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
5158   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5159
5160 (define_expand "lshrsi3"
5161   [(set (match_operand:SI 0 "register_operand")
5162         (lshiftrt:SI (match_operand:SI 1 "register_operand")
5163                      (match_operand:SI 2 "arith_operand")))]
5164   ""
5165 {
5166   /* On the mips16, a shift of more than 8 is a four byte instruction,
5167      so, for a shift between 8 and 16, it is just as fast to do two
5168      shifts of 8 or less.  If there is a lot of shifting going on, we
5169      may win in CSE.  Otherwise combine will put the shifts back
5170      together again.  */
5171   if (TARGET_MIPS16
5172       && optimize
5173       && GET_CODE (operands[2]) == CONST_INT
5174       && INTVAL (operands[2]) > 8
5175       && INTVAL (operands[2]) <= 16)
5176     {
5177       rtx temp = gen_reg_rtx (SImode);
5178
5179       emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5180       emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
5181                                         GEN_INT (INTVAL (operands[2]) - 8)));
5182       DONE;
5183     }
5184 })
5185
5186 (define_insn "lshrsi3_internal1"
5187   [(set (match_operand:SI 0 "register_operand" "=d")
5188         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
5189                      (match_operand:SI 2 "arith_operand" "dI")))]
5190   "!TARGET_MIPS16"
5191 {
5192   if (GET_CODE (operands[2]) == CONST_INT)
5193     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5194
5195   return "srl\t%0,%1,%2";
5196 }
5197   [(set_attr "type"     "shift")
5198    (set_attr "mode"     "SI")])
5199
5200 (define_insn "lshrsi3_internal2"
5201   [(set (match_operand:SI 0 "register_operand" "=d,d")
5202         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5203                      (match_operand:SI 2 "arith_operand" "d,I")))]
5204   "TARGET_MIPS16"
5205 {
5206   if (which_alternative == 0)
5207     return "srl\t%0,%2";
5208
5209   if (GET_CODE (operands[2]) == CONST_INT)
5210     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5211
5212   return "srl\t%0,%1,%2";
5213 }
5214   [(set_attr "type"     "shift")
5215    (set_attr "mode"     "SI")
5216    (set_attr_alternative "length"
5217                 [(const_int 4)
5218                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5219                                (const_int 4)
5220                                (const_int 8))])])
5221
5222
5223 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5224
5225 (define_split
5226   [(set (match_operand:SI 0 "register_operand")
5227         (lshiftrt:SI (match_operand:SI 1 "register_operand")
5228                      (match_operand:SI 2 "const_int_operand")))]
5229   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5230    && GET_CODE (operands[2]) == CONST_INT
5231    && INTVAL (operands[2]) > 8
5232    && INTVAL (operands[2]) <= 16"
5233   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
5234    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5235   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5236
5237 ;; If we load a byte on the mips16 as a bitfield, the resulting
5238 ;; sequence of instructions is too complicated for combine, because it
5239 ;; involves four instructions: a load, a shift, a constant load into a
5240 ;; register, and an and (the key problem here is that the mips16 does
5241 ;; not have and immediate).  We recognize a shift of a load in order
5242 ;; to make it simple enough for combine to understand.
5243 ;;
5244 ;; The length here is the worst case: the length of the split version
5245 ;; will be more accurate.
5246 (define_insn_and_split ""
5247   [(set (match_operand:SI 0 "register_operand" "=d")
5248         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5249                      (match_operand:SI 2 "immediate_operand" "I")))]
5250   "TARGET_MIPS16"
5251   "#"
5252   ""
5253   [(set (match_dup 0) (match_dup 1))
5254    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5255   ""
5256   [(set_attr "type"     "load")
5257    (set_attr "mode"     "SI")
5258    (set_attr "length"   "16")])
5259
5260 (define_expand "lshrdi3"
5261   [(set (match_operand:DI 0 "register_operand")
5262         (lshiftrt:DI (match_operand:DI 1 "register_operand")
5263                      (match_operand:SI 2 "arith_operand")))]
5264   "TARGET_64BIT"
5265 {
5266   /* On the mips16, a shift of more than 8 is a four byte
5267      instruction, so, for a shift between 8 and 16, it is just as
5268      fast to do two shifts of 8 or less.  If there is a lot of
5269      shifting going on, we may win in CSE.  Otherwise combine will
5270      put the shifts back together again.  */
5271   if (TARGET_MIPS16
5272       && optimize
5273       && GET_CODE (operands[2]) == CONST_INT
5274       && INTVAL (operands[2]) > 8
5275       && INTVAL (operands[2]) <= 16)
5276     {
5277       rtx temp = gen_reg_rtx (DImode);
5278
5279       emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
5280       emit_insn (gen_lshrdi3_internal (operands[0], temp,
5281                                        GEN_INT (INTVAL (operands[2]) - 8)));
5282       DONE;
5283     }
5284 })
5285
5286
5287 (define_insn "lshrdi3_internal"
5288   [(set (match_operand:DI 0 "register_operand" "=d")
5289         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
5290                      (match_operand:SI 2 "arith_operand" "dI")))]
5291   "TARGET_64BIT && !TARGET_MIPS16"
5292 {
5293   if (GET_CODE (operands[2]) == CONST_INT)
5294     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5295
5296   return "dsrl\t%0,%1,%2";
5297 }
5298   [(set_attr "type"     "shift")
5299    (set_attr "mode"     "DI")])
5300
5301 (define_insn ""
5302   [(set (match_operand:DI 0 "register_operand" "=d,d")
5303         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5304                      (match_operand:SI 2 "arith_operand" "d,I")))]
5305   "TARGET_64BIT && TARGET_MIPS16"
5306 {
5307   if (GET_CODE (operands[2]) == CONST_INT)
5308     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5309
5310   return "dsrl\t%0,%2";
5311 }
5312   [(set_attr "type"     "shift")
5313    (set_attr "mode"     "DI")
5314    (set_attr_alternative "length"
5315                 [(const_int 4)
5316                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5317                                (const_int 4)
5318                                (const_int 8))])])
5319
5320 (define_insn "rotrsi3"
5321   [(set (match_operand:SI              0 "register_operand" "=d")
5322         (rotatert:SI (match_operand:SI 1 "register_operand" "d")
5323                      (match_operand:SI 2 "arith_operand"    "dn")))]
5324   "ISA_HAS_ROTR_SI"
5325 {
5326   if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
5327     return "rorv\t%0,%1,%2";
5328
5329   if ((GET_CODE (operands[2]) == CONST_INT)
5330       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
5331     abort ();
5332
5333   return "ror\t%0,%1,%2";
5334 }
5335   [(set_attr "type"     "shift")
5336    (set_attr "mode"     "SI")])
5337
5338 (define_insn "rotrdi3"
5339   [(set (match_operand:DI              0 "register_operand" "=d")
5340         (rotatert:DI (match_operand:DI 1 "register_operand" "d")
5341                      (match_operand:DI 2 "arith_operand"    "dn")))]
5342   "ISA_HAS_ROTR_DI"
5343 {
5344   if (TARGET_SR71K)
5345     {
5346       if (GET_CODE (operands[2]) != CONST_INT)
5347         return "drorv\t%0,%1,%2";
5348
5349       if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
5350         return "dror32\t%0,%1,%2";
5351     }
5352
5353   if ((GET_CODE (operands[2]) == CONST_INT)
5354       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
5355     abort ();
5356
5357   return "dror\t%0,%1,%2";
5358 }
5359   [(set_attr "type"     "shift")
5360    (set_attr "mode"     "DI")])
5361
5362
5363 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5364
5365 (define_split
5366   [(set (match_operand:DI 0 "register_operand")
5367         (lshiftrt:DI (match_operand:DI 1 "register_operand")
5368                      (match_operand:SI 2 "const_int_operand")))]
5369   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5370    && GET_CODE (operands[2]) == CONST_INT
5371    && INTVAL (operands[2]) > 8
5372    && INTVAL (operands[2]) <= 16"
5373   [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
5374    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
5375   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5376 \f
5377 ;;
5378 ;;  ....................
5379 ;;
5380 ;;      COMPARISONS
5381 ;;
5382 ;;  ....................
5383
5384 ;; Flow here is rather complex:
5385 ;;
5386 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the arguments
5387 ;;      into cmp_operands[] but generates no RTL.
5388 ;;
5389 ;;  2)  The appropriate branch define_expand is called, which then
5390 ;;      creates the appropriate RTL for the comparison and branch.
5391 ;;      Different CC modes are used, based on what type of branch is
5392 ;;      done, so that we can constrain things appropriately.  There
5393 ;;      are assumptions in the rest of GCC that break if we fold the
5394 ;;      operands into the branches for integer operations, and use cc0
5395 ;;      for floating point, so we use the fp status register instead.
5396 ;;      If needed, an appropriate temporary is created to hold the
5397 ;;      of the integer compare.
5398
5399 (define_expand "cmpsi"
5400   [(set (cc0)
5401         (compare:CC (match_operand:SI 0 "register_operand")
5402                     (match_operand:SI 1 "nonmemory_operand")))]
5403   ""
5404 {
5405   cmp_operands[0] = operands[0];
5406   cmp_operands[1] = operands[1];
5407   DONE;
5408 })
5409
5410 (define_expand "cmpdi"
5411   [(set (cc0)
5412         (compare:CC (match_operand:DI 0 "register_operand")
5413                     (match_operand:DI 1 "nonmemory_operand")))]
5414   "TARGET_64BIT"
5415 {
5416   cmp_operands[0] = operands[0];
5417   cmp_operands[1] = operands[1];
5418   DONE;
5419 })
5420
5421 (define_expand "cmpdf"
5422   [(set (cc0)
5423         (compare:CC (match_operand:DF 0 "register_operand")
5424                     (match_operand:DF 1 "register_operand")))]
5425   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5426 {
5427   cmp_operands[0] = operands[0];
5428   cmp_operands[1] = operands[1];
5429   DONE;
5430 })
5431
5432 (define_expand "cmpsf"
5433   [(set (cc0)
5434         (compare:CC (match_operand:SF 0 "register_operand")
5435                     (match_operand:SF 1 "register_operand")))]
5436   "TARGET_HARD_FLOAT"
5437 {
5438   cmp_operands[0] = operands[0];
5439   cmp_operands[1] = operands[1];
5440   DONE;
5441 })
5442 \f
5443 ;;
5444 ;;  ....................
5445 ;;
5446 ;;      CONDITIONAL BRANCHES
5447 ;;
5448 ;;  ....................
5449
5450 ;; Conditional branches on floating-point equality tests.
5451
5452 (define_insn "branch_fp"
5453   [(set (pc)
5454         (if_then_else
5455          (match_operator:CC 0 "cmp_op"
5456                             [(match_operand:CC 2 "register_operand" "z")
5457                              (const_int 0)])
5458          (label_ref (match_operand 1 "" ""))
5459          (pc)))]
5460   "TARGET_HARD_FLOAT"
5461 {
5462   return mips_output_conditional_branch (insn,
5463                                          operands,
5464                                          /*two_operands_p=*/0,
5465                                          /*float_p=*/1,
5466                                          /*inverted_p=*/0,
5467                                          get_attr_length (insn));
5468 }
5469   [(set_attr "type"     "branch")
5470    (set_attr "mode"     "none")])
5471
5472 (define_insn "branch_fp_inverted"
5473   [(set (pc)
5474         (if_then_else
5475          (match_operator:CC 0 "cmp_op"
5476                             [(match_operand:CC 2 "register_operand" "z")
5477                              (const_int 0)])
5478          (pc)
5479          (label_ref (match_operand 1 "" ""))))]
5480   "TARGET_HARD_FLOAT"
5481 {
5482   return mips_output_conditional_branch (insn,
5483                                          operands,
5484                                          /*two_operands_p=*/0,
5485                                          /*float_p=*/1,
5486                                          /*inverted_p=*/1,
5487                                          get_attr_length (insn));
5488 }
5489   [(set_attr "type"     "branch")
5490    (set_attr "mode"     "none")])
5491
5492 ;; Conditional branches on comparisons with zero.
5493
5494 (define_insn "branch_zero"
5495   [(set (pc)
5496         (if_then_else
5497          (match_operator:SI 0 "cmp_op"
5498                             [(match_operand:SI 2 "register_operand" "d")
5499                              (const_int 0)])
5500         (label_ref (match_operand 1 "" ""))
5501         (pc)))]
5502   "!TARGET_MIPS16"
5503 {
5504   return mips_output_conditional_branch (insn,
5505                                          operands,
5506                                          /*two_operands_p=*/0,
5507                                          /*float_p=*/0,
5508                                          /*inverted_p=*/0,
5509                                          get_attr_length (insn));
5510 }
5511   [(set_attr "type"     "branch")
5512    (set_attr "mode"     "none")])
5513
5514 (define_insn "branch_zero_inverted"
5515   [(set (pc)
5516         (if_then_else
5517          (match_operator:SI 0 "cmp_op"
5518                             [(match_operand:SI 2 "register_operand" "d")
5519                              (const_int 0)])
5520         (pc)
5521         (label_ref (match_operand 1 "" ""))))]
5522   "!TARGET_MIPS16"
5523 {
5524   return mips_output_conditional_branch (insn,
5525                                          operands,
5526                                          /*two_operands_p=*/0,
5527                                          /*float_p=*/0,
5528                                          /*inverted_p=*/1,
5529                                          get_attr_length (insn));
5530 }
5531   [(set_attr "type"     "branch")
5532    (set_attr "mode"     "none")])
5533
5534 (define_insn "branch_zero_di"
5535   [(set (pc)
5536         (if_then_else
5537          (match_operator:DI 0 "cmp_op"
5538                             [(match_operand:DI 2 "register_operand" "d")
5539                              (const_int 0)])
5540         (label_ref (match_operand 1 "" ""))
5541         (pc)))]
5542   "!TARGET_MIPS16"
5543 {
5544   return mips_output_conditional_branch (insn,
5545                                          operands,
5546                                          /*two_operands_p=*/0,
5547                                          /*float_p=*/0,
5548                                          /*inverted_p=*/0,
5549                                          get_attr_length (insn));
5550 }
5551   [(set_attr "type"     "branch")
5552    (set_attr "mode"     "none")])
5553
5554 (define_insn "branch_zero_di_inverted"
5555   [(set (pc)
5556         (if_then_else
5557          (match_operator:DI 0 "cmp_op"
5558                             [(match_operand:DI 2 "register_operand" "d")
5559                              (const_int 0)])
5560         (pc)
5561         (label_ref (match_operand 1 "" ""))))]
5562   "!TARGET_MIPS16"
5563 {
5564   return mips_output_conditional_branch (insn,
5565                                          operands,
5566                                          /*two_operands_p=*/0,
5567                                          /*float_p=*/0,
5568                                          /*inverted_p=*/1,
5569                                          get_attr_length (insn));
5570 }
5571   [(set_attr "type"     "branch")
5572    (set_attr "mode"     "none")])
5573
5574 ;; Conditional branch on equality comparison.
5575
5576 (define_insn "branch_equality"
5577   [(set (pc)
5578         (if_then_else
5579          (match_operator:SI 0 "equality_op"
5580                             [(match_operand:SI 2 "register_operand" "d")
5581                              (match_operand:SI 3 "register_operand" "d")])
5582          (label_ref (match_operand 1 "" ""))
5583          (pc)))]
5584   "!TARGET_MIPS16"
5585 {
5586   return mips_output_conditional_branch (insn,
5587                                          operands,
5588                                          /*two_operands_p=*/1,
5589                                          /*float_p=*/0,
5590                                          /*inverted_p=*/0,
5591                                          get_attr_length (insn));
5592 }
5593   [(set_attr "type"     "branch")
5594    (set_attr "mode"     "none")])
5595
5596 (define_insn "branch_equality_di"
5597   [(set (pc)
5598         (if_then_else
5599          (match_operator:DI 0 "equality_op"
5600                             [(match_operand:DI 2 "register_operand" "d")
5601                              (match_operand:DI 3 "register_operand" "d")])
5602         (label_ref (match_operand 1 "" ""))
5603         (pc)))]
5604   "!TARGET_MIPS16"
5605 {
5606   return mips_output_conditional_branch (insn,
5607                                          operands,
5608                                          /*two_operands_p=*/1,
5609                                          /*float_p=*/0,
5610                                          /*inverted_p=*/0,
5611                                          get_attr_length (insn));
5612 }
5613   [(set_attr "type"     "branch")
5614    (set_attr "mode"     "none")])
5615
5616 (define_insn "branch_equality_inverted"
5617   [(set (pc)
5618         (if_then_else
5619          (match_operator:SI 0 "equality_op"
5620                             [(match_operand:SI 2 "register_operand" "d")
5621                              (match_operand:SI 3 "register_operand" "d")])
5622          (pc)
5623          (label_ref (match_operand 1 "" ""))))]
5624   "!TARGET_MIPS16"
5625 {
5626   return mips_output_conditional_branch (insn,
5627                                          operands,
5628                                          /*two_operands_p=*/1,
5629                                          /*float_p=*/0,
5630                                          /*inverted_p=*/1,
5631                                          get_attr_length (insn));
5632 }
5633   [(set_attr "type"     "branch")
5634    (set_attr "mode"     "none")])
5635
5636 (define_insn "branch_equality_di_inverted"
5637   [(set (pc)
5638         (if_then_else
5639          (match_operator:DI 0 "equality_op"
5640                             [(match_operand:DI 2 "register_operand" "d")
5641                              (match_operand:DI 3 "register_operand" "d")])
5642         (pc)
5643         (label_ref (match_operand 1 "" ""))))]
5644   "!TARGET_MIPS16"
5645 {
5646   return mips_output_conditional_branch (insn,
5647                                          operands,
5648                                          /*two_operands_p=*/1,
5649                                          /*float_p=*/0,
5650                                          /*inverted_p=*/1,
5651                                          get_attr_length (insn));
5652 }
5653   [(set_attr "type"     "branch")
5654    (set_attr "mode"     "none")])
5655
5656 ;; MIPS16 branches
5657
5658 (define_insn ""
5659   [(set (pc)
5660         (if_then_else (match_operator:SI 0 "equality_op"
5661                                          [(match_operand:SI 1 "register_operand" "d,t")
5662                                           (const_int 0)])
5663         (match_operand 2 "pc_or_label_operand" "")
5664         (match_operand 3 "pc_or_label_operand" "")))]
5665   "TARGET_MIPS16"
5666 {
5667   if (operands[2] != pc_rtx)
5668     {
5669       if (which_alternative == 0)
5670         return "b%C0z\t%1,%2";
5671       else
5672         return "bt%C0z\t%2";
5673     }
5674   else
5675     {
5676       if (which_alternative == 0)
5677         return "b%N0z\t%1,%3";
5678       else
5679         return "bt%N0z\t%3";
5680     }
5681 }
5682   [(set_attr "type"     "branch")
5683    (set_attr "mode"     "none")
5684    (set_attr "length"   "8")])
5685
5686 (define_insn ""
5687   [(set (pc)
5688         (if_then_else (match_operator:DI 0 "equality_op"
5689                                          [(match_operand:DI 1 "register_operand" "d,t")
5690                                           (const_int 0)])
5691         (match_operand 2 "pc_or_label_operand" "")
5692         (match_operand 3 "pc_or_label_operand" "")))]
5693   "TARGET_MIPS16"
5694 {
5695   if (operands[2] != pc_rtx)
5696     {
5697       if (which_alternative == 0)
5698         return "b%C0z\t%1,%2";
5699       else
5700         return "bt%C0z\t%2";
5701     }
5702   else
5703     {
5704       if (which_alternative == 0)
5705         return "b%N0z\t%1,%3";
5706       else
5707         return "bt%N0z\t%3";
5708     }
5709 }
5710   [(set_attr "type"     "branch")
5711    (set_attr "mode"     "none")
5712    (set_attr "length"   "8")])
5713
5714 (define_expand "bunordered"
5715   [(set (pc)
5716         (if_then_else (unordered:CC (cc0)
5717                                     (const_int 0))
5718                       (label_ref (match_operand 0 ""))
5719                       (pc)))]
5720   ""
5721 {
5722   gen_conditional_branch (operands, UNORDERED);
5723   DONE;
5724 })
5725
5726 (define_expand "bordered"
5727   [(set (pc)
5728         (if_then_else (ordered:CC (cc0)
5729                                   (const_int 0))
5730                       (label_ref (match_operand 0 ""))
5731                       (pc)))]
5732   ""
5733 {
5734   gen_conditional_branch (operands, ORDERED);
5735   DONE;
5736 })
5737
5738 (define_expand "bunlt"
5739   [(set (pc)
5740         (if_then_else (unlt:CC (cc0)
5741                                (const_int 0))
5742                       (label_ref (match_operand 0 ""))
5743                       (pc)))]
5744   ""
5745 {
5746   gen_conditional_branch (operands, UNLT);
5747   DONE;
5748 })
5749
5750 (define_expand "bunge"
5751   [(set (pc)
5752         (if_then_else (unge:CC (cc0)
5753                                (const_int 0))
5754                       (label_ref (match_operand 0 ""))
5755                       (pc)))]
5756   ""
5757 {
5758   gen_conditional_branch (operands, UNGE);
5759   DONE;
5760 })
5761
5762 (define_expand "buneq"
5763   [(set (pc)
5764         (if_then_else (uneq:CC (cc0)
5765                                (const_int 0))
5766                       (label_ref (match_operand 0 ""))
5767                       (pc)))]
5768   ""
5769 {
5770   gen_conditional_branch (operands, UNEQ);
5771   DONE;
5772 })
5773
5774 (define_expand "bltgt"
5775   [(set (pc)
5776         (if_then_else (ltgt:CC (cc0)
5777                                (const_int 0))
5778                       (label_ref (match_operand 0 ""))
5779                       (pc)))]
5780   ""
5781 {
5782   gen_conditional_branch (operands, LTGT);
5783   DONE;
5784 })
5785
5786 (define_expand "bunle"
5787   [(set (pc)
5788         (if_then_else (unle:CC (cc0)
5789                                (const_int 0))
5790                       (label_ref (match_operand 0 ""))
5791                       (pc)))]
5792   ""
5793 {
5794   gen_conditional_branch (operands, UNLE);
5795   DONE;
5796 })
5797
5798 (define_expand "bungt"
5799   [(set (pc)
5800         (if_then_else (ungt:CC (cc0)
5801                                (const_int 0))
5802                       (label_ref (match_operand 0 ""))
5803                       (pc)))]
5804   ""
5805 {
5806   gen_conditional_branch (operands, UNGT);
5807   DONE;
5808 })
5809
5810 (define_expand "beq"
5811   [(set (pc)
5812         (if_then_else (eq:CC (cc0)
5813                              (const_int 0))
5814                       (label_ref (match_operand 0 ""))
5815                       (pc)))]
5816   ""
5817 {
5818   gen_conditional_branch (operands, EQ);
5819   DONE;
5820 })
5821
5822 (define_expand "bne"
5823   [(set (pc)
5824         (if_then_else (ne:CC (cc0)
5825                              (const_int 0))
5826                       (label_ref (match_operand 0 ""))
5827                       (pc)))]
5828   ""
5829 {
5830   gen_conditional_branch (operands, NE);
5831   DONE;
5832 })
5833
5834 (define_expand "bgt"
5835   [(set (pc)
5836         (if_then_else (gt:CC (cc0)
5837                              (const_int 0))
5838                       (label_ref (match_operand 0 ""))
5839                       (pc)))]
5840   ""
5841 {
5842   gen_conditional_branch (operands, GT);
5843   DONE;
5844 })
5845
5846 (define_expand "bge"
5847   [(set (pc)
5848         (if_then_else (ge:CC (cc0)
5849                              (const_int 0))
5850                       (label_ref (match_operand 0 ""))
5851                       (pc)))]
5852   ""
5853 {
5854   gen_conditional_branch (operands, GE);
5855   DONE;
5856 })
5857
5858 (define_expand "blt"
5859   [(set (pc)
5860         (if_then_else (lt:CC (cc0)
5861                              (const_int 0))
5862                       (label_ref (match_operand 0 ""))
5863                       (pc)))]
5864   ""
5865 {
5866   gen_conditional_branch (operands, LT);
5867   DONE;
5868 })
5869
5870 (define_expand "ble"
5871   [(set (pc)
5872         (if_then_else (le:CC (cc0)
5873                              (const_int 0))
5874                       (label_ref (match_operand 0 ""))
5875                       (pc)))]
5876   ""
5877 {
5878   gen_conditional_branch (operands, LE);
5879   DONE;
5880 })
5881
5882 (define_expand "bgtu"
5883   [(set (pc)
5884         (if_then_else (gtu:CC (cc0)
5885                               (const_int 0))
5886                       (label_ref (match_operand 0 ""))
5887                       (pc)))]
5888   ""
5889 {
5890   gen_conditional_branch (operands, GTU);
5891   DONE;
5892 })
5893
5894 (define_expand "bgeu"
5895   [(set (pc)
5896         (if_then_else (geu:CC (cc0)
5897                               (const_int 0))
5898                       (label_ref (match_operand 0 ""))
5899                       (pc)))]
5900   ""
5901 {
5902   gen_conditional_branch (operands, GEU);
5903   DONE;
5904 })
5905
5906 (define_expand "bltu"
5907   [(set (pc)
5908         (if_then_else (ltu:CC (cc0)
5909                               (const_int 0))
5910                       (label_ref (match_operand 0 ""))
5911                       (pc)))]
5912   ""
5913 {
5914   gen_conditional_branch (operands, LTU);
5915   DONE;
5916 })
5917
5918 (define_expand "bleu"
5919   [(set (pc)
5920         (if_then_else (leu:CC (cc0)
5921                               (const_int 0))
5922                       (label_ref (match_operand 0 ""))
5923                       (pc)))]
5924   ""
5925 {
5926   gen_conditional_branch (operands, LEU);
5927   DONE;
5928 })
5929 \f
5930 ;;
5931 ;;  ....................
5932 ;;
5933 ;;      SETTING A REGISTER FROM A COMPARISON
5934 ;;
5935 ;;  ....................
5936
5937 (define_expand "seq"
5938   [(set (match_operand:SI 0 "register_operand")
5939         (eq:SI (match_dup 1)
5940                (match_dup 2)))]
5941   ""
5942   { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
5943
5944 (define_insn "*seq_si"
5945   [(set (match_operand:SI 0 "register_operand" "=d")
5946         (eq:SI (match_operand:SI 1 "register_operand" "d")
5947                (const_int 0)))]
5948   "!TARGET_MIPS16"
5949   "sltu\t%0,%1,1"
5950   [(set_attr "type" "slt")
5951    (set_attr "mode" "SI")])
5952
5953 (define_insn "*seq_si_mips16"
5954   [(set (match_operand:SI 0 "register_operand" "=t")
5955         (eq:SI (match_operand:SI 1 "register_operand" "d")
5956                (const_int 0)))]
5957   "TARGET_MIPS16"
5958   "sltu\t%1,1"
5959   [(set_attr "type" "slt")
5960    (set_attr "mode" "SI")])
5961
5962 (define_insn "*seq_di"
5963   [(set (match_operand:DI 0 "register_operand" "=d")
5964         (eq:DI (match_operand:DI 1 "register_operand" "d")
5965                (const_int 0)))]
5966   "TARGET_64BIT && !TARGET_MIPS16"
5967   "sltu\t%0,%1,1"
5968   [(set_attr "type" "slt")
5969    (set_attr "mode" "DI")])
5970
5971 (define_insn "*seq_di_mips16"
5972   [(set (match_operand:DI 0 "register_operand" "=t")
5973         (eq:DI (match_operand:DI 1 "register_operand" "d")
5974                (const_int 0)))]
5975   "TARGET_64BIT && TARGET_MIPS16"
5976   "sltu\t%1,1"
5977   [(set_attr "type" "slt")
5978    (set_attr "mode" "DI")])
5979
5980 ;; "sne" uses sltu instructions in which the first operand is $0.
5981 ;; This isn't possible in mips16 code.
5982
5983 (define_expand "sne"
5984   [(set (match_operand:SI 0 "register_operand")
5985         (ne:SI (match_dup 1)
5986                (match_dup 2)))]
5987   "!TARGET_MIPS16"
5988   { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
5989
5990 (define_insn "*sne_si"
5991   [(set (match_operand:SI 0 "register_operand" "=d")
5992         (ne:SI (match_operand:SI 1 "register_operand" "d")
5993                (const_int 0)))]
5994   "!TARGET_MIPS16"
5995   "sltu\t%0,%.,%1"
5996   [(set_attr "type" "slt")
5997    (set_attr "mode" "SI")])
5998
5999 (define_insn "*sne_di"
6000   [(set (match_operand:DI 0 "register_operand" "=d")
6001         (ne:DI (match_operand:DI 1 "register_operand" "d")
6002                (const_int 0)))]
6003   "TARGET_64BIT && !TARGET_MIPS16"
6004   "sltu\t%0,%.,%1"
6005   [(set_attr "type" "slt")
6006    (set_attr "mode" "DI")])
6007
6008 (define_expand "sgt"
6009   [(set (match_operand:SI 0 "register_operand")
6010         (gt:SI (match_dup 1)
6011                (match_dup 2)))]
6012   ""
6013   { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
6014
6015 (define_insn "*sgt_si"
6016   [(set (match_operand:SI 0 "register_operand" "=d")
6017         (gt:SI (match_operand:SI 1 "register_operand" "d")
6018                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6019   "!TARGET_MIPS16"
6020   "slt\t%0,%z2,%1"
6021   [(set_attr "type" "slt")
6022    (set_attr "mode" "SI")])
6023
6024 (define_insn "*sgt_si_mips16"
6025   [(set (match_operand:SI 0 "register_operand" "=t")
6026         (gt:SI (match_operand:SI 1 "register_operand" "d")
6027                (match_operand:SI 2 "register_operand" "d")))]
6028   "TARGET_MIPS16"
6029   "slt\t%2,%1"
6030   [(set_attr "type" "slt")
6031    (set_attr "mode" "SI")])
6032
6033 (define_insn "*sgt_di"
6034   [(set (match_operand:DI 0 "register_operand" "=d")
6035         (gt:DI (match_operand:DI 1 "register_operand" "d")
6036                (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6037   "TARGET_64BIT && !TARGET_MIPS16"
6038   "slt\t%0,%z2,%1"
6039   [(set_attr "type" "slt")
6040    (set_attr "mode" "DI")])
6041
6042 (define_insn "*sgt_di_mips16"
6043   [(set (match_operand:DI 0 "register_operand" "=t")
6044         (gt:DI (match_operand:DI 1 "register_operand" "d")
6045                (match_operand:DI 2 "register_operand" "d")))]
6046   "TARGET_64BIT && TARGET_MIPS16"
6047   "slt\t%2,%1"
6048   [(set_attr "type" "slt")
6049    (set_attr "mode" "DI")])
6050
6051 (define_expand "sge"
6052   [(set (match_operand:SI 0 "register_operand")
6053         (ge:SI (match_dup 1)
6054                (match_dup 2)))]
6055   ""
6056   { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
6057
6058 (define_insn "*sge_si"
6059   [(set (match_operand:SI 0 "register_operand" "=d")
6060         (ge:SI (match_operand:SI 1 "register_operand" "d")
6061                (const_int 1)))]
6062   "!TARGET_MIPS16"
6063   "slt\t%0,%.,%1"
6064   [(set_attr "type" "slt")
6065    (set_attr "mode" "SI")])
6066
6067 (define_insn "*sge_di"
6068   [(set (match_operand:DI 0 "register_operand" "=d")
6069         (ge:DI (match_operand:DI 1 "register_operand" "d")
6070                (const_int 1)))]
6071   "TARGET_64BIT && !TARGET_MIPS16"
6072   "slt\t%0,%.,%1"
6073   [(set_attr "type" "slt")
6074    (set_attr "mode" "DI")])
6075
6076 (define_expand "slt"
6077   [(set (match_operand:SI 0 "register_operand")
6078         (lt:SI (match_dup 1)
6079                (match_dup 2)))]
6080   ""
6081   { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
6082
6083 (define_insn "*slt_si"
6084   [(set (match_operand:SI 0 "register_operand" "=d")
6085         (lt:SI (match_operand:SI 1 "register_operand" "d")
6086                (match_operand:SI 2 "arith_operand" "dI")))]
6087   "!TARGET_MIPS16"
6088   "slt\t%0,%1,%2"
6089   [(set_attr "type" "slt")
6090    (set_attr "mode" "SI")])
6091
6092 (define_insn "*slt_si_mips16"
6093   [(set (match_operand:SI 0 "register_operand" "=t,t")
6094         (lt:SI (match_operand:SI 1 "register_operand" "d,d")
6095                (match_operand:SI 2 "arith_operand" "d,I")))]
6096   "TARGET_MIPS16"
6097   "slt\t%1,%2"
6098   [(set_attr "type" "slt")
6099    (set_attr "mode" "SI")
6100    (set_attr_alternative "length"
6101                 [(const_int 4)
6102                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6103                                (const_int 4)
6104                                (const_int 8))])])
6105
6106 (define_insn "*slt_di"
6107   [(set (match_operand:DI 0 "register_operand" "=d")
6108         (lt:DI (match_operand:DI 1 "register_operand" "d")
6109                (match_operand:DI 2 "arith_operand" "dI")))]
6110   "TARGET_64BIT && !TARGET_MIPS16"
6111   "slt\t%0,%1,%2"
6112   [(set_attr "type" "slt")
6113    (set_attr "mode" "DI")])
6114
6115 (define_insn "*slt_di_mips16"
6116   [(set (match_operand:DI 0 "register_operand" "=t,t")
6117         (lt:DI (match_operand:DI 1 "register_operand" "d,d")
6118                (match_operand:DI 2 "arith_operand" "d,I")))]
6119   "TARGET_64BIT && TARGET_MIPS16"
6120   "slt\t%1,%2"
6121   [(set_attr "type" "slt")
6122    (set_attr "mode" "DI")
6123    (set_attr_alternative "length"
6124                 [(const_int 4)
6125                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6126                                (const_int 4)
6127                                (const_int 8))])])
6128
6129 (define_expand "sle"
6130   [(set (match_operand:SI 0 "register_operand")
6131         (le:SI (match_dup 1)
6132                (match_dup 2)))]
6133   ""
6134   { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
6135
6136 (define_insn "*sle_si"
6137   [(set (match_operand:SI 0 "register_operand" "=d")
6138         (le:SI (match_operand:SI 1 "register_operand" "d")
6139                (match_operand:SI 2 "sle_operand" "")))]
6140   "!TARGET_MIPS16"
6141 {
6142   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6143   return "slt\t%0,%1,%2";
6144 }
6145   [(set_attr "type" "slt")
6146    (set_attr "mode" "SI")])
6147
6148 (define_insn "*sle_si_mips16"
6149   [(set (match_operand:SI 0 "register_operand" "=t")
6150         (le:SI (match_operand:SI 1 "register_operand" "d")
6151                (match_operand:SI 2 "sle_operand" "")))]
6152   "TARGET_MIPS16"
6153 {
6154   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6155   return "slt\t%1,%2";
6156 }
6157   [(set_attr "type" "slt")
6158    (set_attr "mode" "SI")
6159    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6160                                       (const_int 4)
6161                                       (const_int 8)))])
6162
6163 (define_insn "*sle_di"
6164   [(set (match_operand:DI 0 "register_operand" "=d")
6165         (le:DI (match_operand:DI 1 "register_operand" "d")
6166                (match_operand:DI 2 "sle_operand" "")))]
6167   "TARGET_64BIT && !TARGET_MIPS16"
6168 {
6169   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6170   return "slt\t%0,%1,%2";
6171 }
6172   [(set_attr "type" "slt")
6173    (set_attr "mode" "DI")])
6174
6175 (define_insn "*sle_di_mips16"
6176   [(set (match_operand:DI 0 "register_operand" "=t")
6177         (le:DI (match_operand:DI 1 "register_operand" "d")
6178                (match_operand:DI 2 "sle_operand" "")))]
6179   "TARGET_64BIT && TARGET_MIPS16"
6180 {
6181   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6182   return "slt\t%1,%2";
6183 }
6184   [(set_attr "type" "slt")
6185    (set_attr "mode" "DI")
6186    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6187                                       (const_int 4)
6188                                       (const_int 8)))])
6189
6190 (define_expand "sgtu"
6191   [(set (match_operand:SI 0 "register_operand")
6192         (gtu:SI (match_dup 1)
6193                 (match_dup 2)))]
6194   ""
6195   { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
6196
6197 (define_insn "*sgtu_si"
6198   [(set (match_operand:SI 0 "register_operand" "=d")
6199         (gtu:SI (match_operand:SI 1 "register_operand" "d")
6200                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6201   "!TARGET_MIPS16"
6202   "sltu\t%0,%z2,%1"
6203   [(set_attr "type" "slt")
6204    (set_attr "mode" "SI")])
6205
6206 (define_insn "*sgtu_si_mips16"
6207   [(set (match_operand:SI 0 "register_operand" "=t")
6208         (gtu:SI (match_operand:SI 1 "register_operand" "d")
6209                 (match_operand:SI 2 "register_operand" "d")))]
6210   "TARGET_MIPS16"
6211   "sltu\t%2,%1"
6212   [(set_attr "type" "slt")
6213    (set_attr "mode" "SI")])
6214
6215 (define_insn "*sgtu_di"
6216   [(set (match_operand:DI 0 "register_operand" "=d")
6217         (gtu:DI (match_operand:DI 1 "register_operand" "d")
6218                 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6219   "TARGET_64BIT && !TARGET_MIPS16"
6220   "sltu\t%0,%z2,%1"
6221   [(set_attr "type" "slt")
6222    (set_attr "mode" "DI")])
6223
6224 (define_insn "*sgtu_di_mips16"
6225   [(set (match_operand:DI 0 "register_operand" "=t")
6226         (gtu:DI (match_operand:DI 1 "register_operand" "d")
6227                 (match_operand:DI 2 "register_operand" "d")))]
6228   "TARGET_64BIT && TARGET_MIPS16"
6229   "sltu\t%2,%1"
6230   [(set_attr "type" "slt")
6231    (set_attr "mode" "DI")])
6232
6233 (define_expand "sgeu"
6234   [(set (match_operand:SI 0 "register_operand")
6235         (geu:SI (match_dup 1)
6236                 (match_dup 2)))]
6237   ""
6238   { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
6239
6240 (define_insn "*sge_si"
6241   [(set (match_operand:SI 0 "register_operand" "=d")
6242         (geu:SI (match_operand:SI 1 "register_operand" "d")
6243                 (const_int 1)))]
6244   "!TARGET_MIPS16"
6245   "sltu\t%0,%.,%1"
6246   [(set_attr "type" "slt")
6247    (set_attr "mode" "SI")])
6248
6249 (define_insn "*sge_di"
6250   [(set (match_operand:DI 0 "register_operand" "=d")
6251         (geu:DI (match_operand:DI 1 "register_operand" "d")
6252                 (const_int 1)))]
6253   "TARGET_64BIT && !TARGET_MIPS16"
6254   "sltu\t%0,%.,%1"
6255   [(set_attr "type" "slt")
6256    (set_attr "mode" "DI")])
6257
6258 (define_expand "sltu"
6259   [(set (match_operand:SI 0 "register_operand")
6260         (ltu:SI (match_dup 1)
6261                 (match_dup 2)))]
6262   ""
6263   { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
6264
6265 (define_insn "*sltu_si"
6266   [(set (match_operand:SI 0 "register_operand" "=d")
6267         (ltu:SI (match_operand:SI 1 "register_operand" "d")
6268                 (match_operand:SI 2 "arith_operand" "dI")))]
6269   "!TARGET_MIPS16"
6270   "sltu\t%0,%1,%2"
6271   [(set_attr "type" "slt")
6272    (set_attr "mode" "SI")])
6273
6274 (define_insn "*sltu_si_mips16"
6275   [(set (match_operand:SI 0 "register_operand" "=t,t")
6276         (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
6277                 (match_operand:SI 2 "arith_operand" "d,I")))]
6278   "TARGET_MIPS16"
6279   "sltu\t%1,%2"
6280   [(set_attr "type" "slt")
6281    (set_attr "mode" "SI")
6282    (set_attr_alternative "length"
6283                 [(const_int 4)
6284                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6285                                (const_int 4)
6286                                (const_int 8))])])
6287
6288 (define_insn "*sltu_di"
6289   [(set (match_operand:DI 0 "register_operand" "=d")
6290         (ltu:DI (match_operand:DI 1 "register_operand" "d")
6291                 (match_operand:DI 2 "arith_operand" "dI")))]
6292   "TARGET_64BIT && !TARGET_MIPS16"
6293   "sltu\t%0,%1,%2"
6294   [(set_attr "type" "slt")
6295    (set_attr "mode" "DI")])
6296
6297 (define_insn "*sltu_di_mips16"
6298   [(set (match_operand:DI 0 "register_operand" "=t,t")
6299         (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
6300                 (match_operand:DI 2 "arith_operand" "d,I")))]
6301   "TARGET_64BIT && TARGET_MIPS16"
6302   "sltu\t%1,%2"
6303   [(set_attr "type" "slt")
6304    (set_attr "mode" "DI")
6305    (set_attr_alternative "length"
6306                 [(const_int 4)
6307                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6308                                (const_int 4)
6309                                (const_int 8))])])
6310
6311 (define_expand "sleu"
6312   [(set (match_operand:SI 0 "register_operand")
6313         (leu:SI (match_dup 1)
6314                 (match_dup 2)))]
6315   ""
6316   { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
6317
6318 (define_insn "*sleu_si"
6319   [(set (match_operand:SI 0 "register_operand" "=d")
6320         (leu:SI (match_operand:SI 1 "register_operand" "d")
6321                 (match_operand:SI 2 "sleu_operand" "")))]
6322   "!TARGET_MIPS16"
6323 {
6324   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6325   return "sltu\t%0,%1,%2";
6326 }
6327   [(set_attr "type" "slt")
6328    (set_attr "mode" "SI")])
6329
6330 (define_insn "*sleu_si_mips16"
6331   [(set (match_operand:SI 0 "register_operand" "=t")
6332         (leu:SI (match_operand:SI 1 "register_operand" "d")
6333                 (match_operand:SI 2 "sleu_operand" "")))]
6334   "TARGET_MIPS16"
6335 {
6336   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6337   return "sltu\t%1,%2";
6338 }
6339   [(set_attr "type" "slt")
6340    (set_attr "mode" "SI")
6341    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6342                                       (const_int 4)
6343                                       (const_int 8)))])
6344
6345 (define_insn "*sleu_di"
6346   [(set (match_operand:DI 0 "register_operand" "=d")
6347         (leu:DI (match_operand:DI 1 "register_operand" "d")
6348                 (match_operand:DI 2 "sleu_operand" "")))]
6349   "TARGET_64BIT && !TARGET_MIPS16"
6350 {
6351   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6352   return "sltu\t%0,%1,%2";
6353 }
6354   [(set_attr "type" "slt")
6355    (set_attr "mode" "DI")])
6356
6357 (define_insn "*sleu_di_mips16"
6358   [(set (match_operand:DI 0 "register_operand" "=t")
6359         (leu:DI (match_operand:DI 1 "register_operand" "d")
6360                 (match_operand:DI 2 "sleu_operand" "")))]
6361   "TARGET_64BIT && TARGET_MIPS16"
6362 {
6363   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6364   return "sltu\t%1,%2";
6365 }
6366   [(set_attr "type" "slt")
6367    (set_attr "mode" "DI")
6368    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6369                                       (const_int 4)
6370                                       (const_int 8)))])
6371 \f
6372 ;;
6373 ;;  ....................
6374 ;;
6375 ;;      FLOATING POINT COMPARISONS
6376 ;;
6377 ;;  ....................
6378
6379 (define_insn "sunordered_df"
6380   [(set (match_operand:CC 0 "register_operand" "=z")
6381         (unordered:CC (match_operand:DF 1 "register_operand" "f")
6382                       (match_operand:DF 2 "register_operand" "f")))]
6383   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6384   "c.un.d\t%Z0%1,%2"
6385   [(set_attr "type" "fcmp")
6386    (set_attr "mode" "FPSW")])
6387
6388 (define_insn "sunlt_df"
6389   [(set (match_operand:CC 0 "register_operand" "=z")
6390         (unlt:CC (match_operand:DF 1 "register_operand" "f")
6391                  (match_operand:DF 2 "register_operand" "f")))]
6392   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6393   "c.ult.d\t%Z0%1,%2"
6394   [(set_attr "type" "fcmp")
6395    (set_attr "mode" "FPSW")])
6396
6397 (define_insn "suneq_df"
6398   [(set (match_operand:CC 0 "register_operand" "=z")
6399         (uneq:CC (match_operand:DF 1 "register_operand" "f")
6400                  (match_operand:DF 2 "register_operand" "f")))]
6401   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6402   "c.ueq.d\t%Z0%1,%2"
6403   [(set_attr "type" "fcmp")
6404    (set_attr "mode" "FPSW")])
6405
6406 (define_insn "sunle_df"
6407   [(set (match_operand:CC 0 "register_operand" "=z")
6408         (unle:CC (match_operand:DF 1 "register_operand" "f")
6409                  (match_operand:DF 2 "register_operand" "f")))]
6410   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6411   "c.ule.d\t%Z0%1,%2"
6412   [(set_attr "type" "fcmp")
6413    (set_attr "mode" "FPSW")])
6414
6415 (define_insn "seq_df"
6416   [(set (match_operand:CC 0 "register_operand" "=z")
6417         (eq:CC (match_operand:DF 1 "register_operand" "f")
6418                (match_operand:DF 2 "register_operand" "f")))]
6419   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6420   "c.eq.d\t%Z0%1,%2"
6421   [(set_attr "type" "fcmp")
6422    (set_attr "mode" "FPSW")])
6423
6424 (define_insn "slt_df"
6425   [(set (match_operand:CC 0 "register_operand" "=z")
6426         (lt:CC (match_operand:DF 1 "register_operand" "f")
6427                (match_operand:DF 2 "register_operand" "f")))]
6428   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6429   "c.lt.d\t%Z0%1,%2"
6430   [(set_attr "type" "fcmp")
6431    (set_attr "mode" "FPSW")])
6432
6433 (define_insn "sle_df"
6434   [(set (match_operand:CC 0 "register_operand" "=z")
6435         (le:CC (match_operand:DF 1 "register_operand" "f")
6436                (match_operand:DF 2 "register_operand" "f")))]
6437   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6438   "c.le.d\t%Z0%1,%2"
6439   [(set_attr "type" "fcmp")
6440    (set_attr "mode" "FPSW")])
6441
6442 (define_insn "sgt_df"
6443   [(set (match_operand:CC 0 "register_operand" "=z")
6444         (gt:CC (match_operand:DF 1 "register_operand" "f")
6445                (match_operand:DF 2 "register_operand" "f")))]
6446   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6447   "c.lt.d\t%Z0%2,%1"
6448   [(set_attr "type" "fcmp")
6449    (set_attr "mode" "FPSW")])
6450
6451 (define_insn "sge_df"
6452   [(set (match_operand:CC 0 "register_operand" "=z")
6453         (ge:CC (match_operand:DF 1 "register_operand" "f")
6454                (match_operand:DF 2 "register_operand" "f")))]
6455   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6456   "c.le.d\t%Z0%2,%1"
6457   [(set_attr "type" "fcmp")
6458    (set_attr "mode" "FPSW")])
6459
6460 (define_insn "sunordered_sf"
6461   [(set (match_operand:CC 0 "register_operand" "=z")
6462         (unordered:CC (match_operand:SF 1 "register_operand" "f")
6463                       (match_operand:SF 2 "register_operand" "f")))]
6464   "TARGET_HARD_FLOAT"
6465   "c.un.s\t%Z0%1,%2"
6466   [(set_attr "type" "fcmp")
6467    (set_attr "mode" "FPSW")])
6468
6469 (define_insn "sunlt_sf"
6470   [(set (match_operand:CC 0 "register_operand" "=z")
6471         (unlt:CC (match_operand:SF 1 "register_operand" "f")
6472                  (match_operand:SF 2 "register_operand" "f")))]
6473   "TARGET_HARD_FLOAT"
6474   "c.ult.s\t%Z0%1,%2"
6475   [(set_attr "type" "fcmp")
6476    (set_attr "mode" "FPSW")])
6477
6478 (define_insn "suneq_sf"
6479   [(set (match_operand:CC 0 "register_operand" "=z")
6480         (uneq:CC (match_operand:SF 1 "register_operand" "f")
6481                  (match_operand:SF 2 "register_operand" "f")))]
6482   "TARGET_HARD_FLOAT"
6483   "c.ueq.s\t%Z0%1,%2"
6484   [(set_attr "type" "fcmp")
6485    (set_attr "mode" "FPSW")])
6486
6487 (define_insn "sunle_sf"
6488   [(set (match_operand:CC 0 "register_operand" "=z")
6489         (unle:CC (match_operand:SF 1 "register_operand" "f")
6490                  (match_operand:SF 2 "register_operand" "f")))]
6491   "TARGET_HARD_FLOAT"
6492   "c.ule.s\t%Z0%1,%2"
6493   [(set_attr "type" "fcmp")
6494    (set_attr "mode" "FPSW")])
6495
6496 (define_insn "seq_sf"
6497   [(set (match_operand:CC 0 "register_operand" "=z")
6498         (eq:CC (match_operand:SF 1 "register_operand" "f")
6499                (match_operand:SF 2 "register_operand" "f")))]
6500   "TARGET_HARD_FLOAT"
6501   "c.eq.s\t%Z0%1,%2"
6502   [(set_attr "type" "fcmp")
6503    (set_attr "mode" "FPSW")])
6504
6505 (define_insn "slt_sf"
6506   [(set (match_operand:CC 0 "register_operand" "=z")
6507         (lt:CC (match_operand:SF 1 "register_operand" "f")
6508                (match_operand:SF 2 "register_operand" "f")))]
6509   "TARGET_HARD_FLOAT"
6510   "c.lt.s\t%Z0%1,%2"
6511   [(set_attr "type" "fcmp")
6512    (set_attr "mode" "FPSW")])
6513
6514 (define_insn "sle_sf"
6515   [(set (match_operand:CC 0 "register_operand" "=z")
6516         (le:CC (match_operand:SF 1 "register_operand" "f")
6517                (match_operand:SF 2 "register_operand" "f")))]
6518   "TARGET_HARD_FLOAT"
6519   "c.le.s\t%Z0%1,%2"
6520   [(set_attr "type" "fcmp")
6521    (set_attr "mode" "FPSW")])
6522
6523 (define_insn "sgt_sf"
6524   [(set (match_operand:CC 0 "register_operand" "=z")
6525         (gt:CC (match_operand:SF 1 "register_operand" "f")
6526                (match_operand:SF 2 "register_operand" "f")))]
6527   "TARGET_HARD_FLOAT"
6528   "c.lt.s\t%Z0%2,%1"
6529   [(set_attr "type" "fcmp")
6530    (set_attr "mode" "FPSW")])
6531
6532 (define_insn "sge_sf"
6533   [(set (match_operand:CC 0 "register_operand" "=z")
6534         (ge:CC (match_operand:SF 1 "register_operand" "f")
6535                (match_operand:SF 2 "register_operand" "f")))]
6536   "TARGET_HARD_FLOAT"
6537   "c.le.s\t%Z0%2,%1"
6538   [(set_attr "type" "fcmp")
6539    (set_attr "mode" "FPSW")])
6540 \f
6541 ;;
6542 ;;  ....................
6543 ;;
6544 ;;      UNCONDITIONAL BRANCHES
6545 ;;
6546 ;;  ....................
6547
6548 ;; Unconditional branches.
6549
6550 (define_insn "jump"
6551   [(set (pc)
6552         (label_ref (match_operand 0 "" "")))]
6553   "!TARGET_MIPS16"
6554 {
6555   if (flag_pic)
6556     {
6557       if (get_attr_length (insn) <= 8)
6558         return "%*b\t%l0%/";
6559       else
6560         {
6561           output_asm_insn (mips_output_load_label (), operands);
6562           return "%*jr\t%@%/%]";
6563         }
6564     }
6565   else
6566     return "%*j\t%l0%/";
6567 }
6568   [(set_attr "type"     "jump")
6569    (set_attr "mode"     "none")
6570    (set (attr "length")
6571         ;; We can't use `j' when emitting PIC.  Emit a branch if it's
6572         ;; in range, otherwise load the address of the branch target into
6573         ;; $at and then jump to it.
6574         (if_then_else
6575          (ior (eq (symbol_ref "flag_pic") (const_int 0))
6576               (lt (abs (minus (match_dup 0)
6577                               (plus (pc) (const_int 4))))
6578                   (const_int 131072)))
6579          (const_int 4) (const_int 16)))])
6580
6581 ;; We need a different insn for the mips16, because a mips16 branch
6582 ;; does not have a delay slot.
6583
6584 (define_insn ""
6585   [(set (pc)
6586         (label_ref (match_operand 0 "" "")))]
6587   "TARGET_MIPS16"
6588   "b\t%l0"
6589   [(set_attr "type"     "branch")
6590    (set_attr "mode"     "none")
6591    (set_attr "length"   "8")])
6592
6593 (define_expand "indirect_jump"
6594   [(set (pc) (match_operand 0 "register_operand"))]
6595   ""
6596 {
6597   rtx dest;
6598
6599   dest = operands[0];
6600   if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
6601     operands[0] = copy_to_mode_reg (Pmode, dest);
6602
6603   if (!(Pmode == DImode))
6604     emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
6605   else
6606     emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
6607
6608   DONE;
6609 })
6610
6611 (define_insn "indirect_jump_internal1"
6612   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
6613   "!(Pmode == DImode)"
6614   "%*j\t%0%/"
6615   [(set_attr "type"     "jump")
6616    (set_attr "mode"     "none")])
6617
6618 (define_insn "indirect_jump_internal2"
6619   [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
6620   "Pmode == DImode"
6621   "%*j\t%0%/"
6622   [(set_attr "type"     "jump")
6623    (set_attr "mode"     "none")])
6624
6625 (define_expand "tablejump"
6626   [(set (pc)
6627         (match_operand 0 "register_operand"))
6628    (use (label_ref (match_operand 1 "")))]
6629   ""
6630 {
6631   if (TARGET_MIPS16)
6632     {
6633       if (GET_MODE (operands[0]) != HImode)
6634         abort ();
6635       if (!(Pmode == DImode))
6636         emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
6637       else
6638         emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
6639       DONE;
6640     }
6641
6642   if (GET_MODE (operands[0]) != ptr_mode)
6643     abort ();
6644
6645   if (TARGET_GPWORD)
6646     operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
6647                                 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
6648
6649   if (Pmode == SImode)
6650     emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
6651   else
6652     emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
6653   DONE;
6654 })
6655
6656 (define_insn "tablejump_internal1"
6657   [(set (pc)
6658         (match_operand:SI 0 "register_operand" "d"))
6659    (use (label_ref (match_operand 1 "" "")))]
6660   ""
6661   "%*j\t%0%/"
6662   [(set_attr "type"     "jump")
6663    (set_attr "mode"     "none")])
6664
6665 (define_insn "tablejump_internal2"
6666   [(set (pc)
6667         (match_operand:DI 0 "register_operand" "d"))
6668    (use (label_ref (match_operand 1 "" "")))]
6669   "TARGET_64BIT"
6670   "%*j\t%0%/"
6671   [(set_attr "type"     "jump")
6672    (set_attr "mode"     "none")])
6673
6674 (define_expand "tablejump_mips161"
6675   [(set (pc) (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand"))
6676                       (label_ref:SI (match_operand 1 ""))))]
6677   "TARGET_MIPS16 && !(Pmode == DImode)"
6678 {
6679   rtx t1, t2, t3;
6680
6681   t1 = gen_reg_rtx (SImode);
6682   t2 = gen_reg_rtx (SImode);
6683   t3 = gen_reg_rtx (SImode);
6684   emit_insn (gen_extendhisi2 (t1, operands[0]));
6685   emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
6686   emit_insn (gen_addsi3 (t3, t1, t2));
6687   emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
6688   DONE;
6689 })
6690
6691 (define_expand "tablejump_mips162"
6692   [(set (pc) (plus:DI (sign_extend:DI (match_operand:HI 0 "register_operand"))
6693                       (label_ref:DI (match_operand 1 ""))))]
6694   "TARGET_MIPS16 && Pmode == DImode"
6695 {
6696   rtx t1, t2, t3;
6697
6698   t1 = gen_reg_rtx (DImode);
6699   t2 = gen_reg_rtx (DImode);
6700   t3 = gen_reg_rtx (DImode);
6701   emit_insn (gen_extendhidi2 (t1, operands[0]));
6702   emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
6703   emit_insn (gen_adddi3 (t3, t1, t2));
6704   emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
6705   DONE;
6706 })
6707
6708 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
6709 ;; While it is possible to either pull it off the stack (in the
6710 ;; o32 case) or recalculate it given t9 and our target label,
6711 ;; it takes 3 or 4 insns to do so.
6712
6713 (define_expand "builtin_setjmp_setup"
6714   [(use (match_operand 0 "register_operand"))]
6715   "TARGET_ABICALLS"
6716 {
6717   rtx addr;
6718
6719   addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
6720   emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
6721   DONE;
6722 })
6723
6724 ;; Restore the gp that we saved above.  Despite the earlier comment, it seems
6725 ;; that older code did recalculate the gp from $25.  Continue to jump through
6726 ;; $25 for compatibility (we lose nothing by doing so).
6727
6728 (define_expand "builtin_longjmp"
6729   [(use (match_operand 0 "register_operand"))]
6730   "TARGET_ABICALLS"
6731 {
6732   /* The elements of the buffer are, in order:  */
6733   int W = GET_MODE_SIZE (Pmode);
6734   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6735   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
6736   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
6737   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
6738   rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6739   /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
6740      The target is bound to be using $28 as the global pointer
6741      but the current function might not be.  */
6742   rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
6743
6744   /* This bit is similar to expand_builtin_longjmp except that it
6745      restores $gp as well.  */
6746   emit_move_insn (hard_frame_pointer_rtx, fp);
6747   emit_move_insn (pv, lab);
6748   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6749   emit_move_insn (gp, gpv);
6750   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6751   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6752   emit_insn (gen_rtx_USE (VOIDmode, gp));
6753   emit_indirect_jump (pv);
6754   DONE;
6755 })
6756 \f
6757 ;;
6758 ;;  ....................
6759 ;;
6760 ;;      Function prologue/epilogue
6761 ;;
6762 ;;  ....................
6763 ;;
6764
6765 (define_expand "prologue"
6766   [(const_int 1)]
6767   ""
6768 {
6769   mips_expand_prologue ();
6770   DONE;
6771 })
6772
6773 ;; Block any insns from being moved before this point, since the
6774 ;; profiling call to mcount can use various registers that aren't
6775 ;; saved or used to pass arguments.
6776
6777 (define_insn "blockage"
6778   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
6779   ""
6780   ""
6781   [(set_attr "type"     "unknown")
6782    (set_attr "mode"     "none")
6783    (set_attr "length"   "0")])
6784
6785 (define_expand "epilogue"
6786   [(const_int 2)]
6787   ""
6788 {
6789   mips_expand_epilogue (false);
6790   DONE;
6791 })
6792
6793 (define_expand "sibcall_epilogue"
6794   [(const_int 2)]
6795   ""
6796 {
6797   mips_expand_epilogue (true);
6798   DONE;
6799 })
6800
6801 ;; Trivial return.  Make it look like a normal return insn as that
6802 ;; allows jump optimizations to work better.
6803
6804 (define_insn "return"
6805   [(return)]
6806   "mips_can_use_return_insn ()"
6807   "%*j\t$31%/"
6808   [(set_attr "type"     "jump")
6809    (set_attr "mode"     "none")])
6810
6811 ;; Normal return.
6812
6813 (define_insn "return_internal"
6814   [(return)
6815    (use (match_operand 0 "pmode_register_operand" ""))]
6816   ""
6817   "%*j\t%0%/"
6818   [(set_attr "type"     "jump")
6819    (set_attr "mode"     "none")])
6820
6821 ;; This is used in compiling the unwind routines.
6822 (define_expand "eh_return"
6823   [(use (match_operand 0 "general_operand"))]
6824   ""
6825 {
6826   enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
6827
6828   if (GET_MODE (operands[0]) != gpr_mode)
6829     operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
6830   if (TARGET_64BIT)
6831     emit_insn (gen_eh_set_lr_di (operands[0]));
6832   else
6833     emit_insn (gen_eh_set_lr_si (operands[0]));
6834
6835   DONE;
6836 })
6837
6838 ;; Clobber the return address on the stack.  We can't expand this
6839 ;; until we know where it will be put in the stack frame.
6840
6841 (define_insn "eh_set_lr_si"
6842   [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6843    (clobber (match_scratch:SI 1 "=&d"))]
6844   "! TARGET_64BIT"
6845   "#")
6846
6847 (define_insn "eh_set_lr_di"
6848   [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6849    (clobber (match_scratch:DI 1 "=&d"))]
6850   "TARGET_64BIT"
6851   "#")
6852
6853 (define_split
6854   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6855    (clobber (match_scratch 1))]
6856   "reload_completed && !TARGET_DEBUG_D_MODE"
6857   [(const_int 0)]
6858 {
6859   mips_set_return_address (operands[0], operands[1]);
6860   DONE;
6861 })
6862
6863 (define_insn_and_split "exception_receiver"
6864   [(set (reg:SI 28)
6865         (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
6866   "TARGET_ABICALLS && TARGET_OLDABI"
6867   "#"
6868   "&& reload_completed"
6869   [(const_int 0)]
6870 {
6871   mips_restore_gp ();
6872   DONE;
6873 }
6874   [(set_attr "type"   "load")
6875    (set_attr "length" "12")])
6876 \f
6877 ;;
6878 ;;  ....................
6879 ;;
6880 ;;      FUNCTION CALLS
6881 ;;
6882 ;;  ....................
6883
6884 ;; Instructions to load a call address from the GOT.  The address might
6885 ;; point to a function or to a lazy binding stub.  In the latter case,
6886 ;; the stub will use the dynamic linker to resolve the function, which
6887 ;; in turn will change the GOT entry to point to the function's real
6888 ;; address.
6889 ;;
6890 ;; This means that every call, even pure and constant ones, can
6891 ;; potentially modify the GOT entry.  And once a stub has been called,
6892 ;; we must not call it again.
6893 ;;
6894 ;; We represent this restriction using an imaginary fixed register that
6895 ;; acts like a GOT version number.  By making the register call-clobbered,
6896 ;; we tell the target-independent code that the address could be changed
6897 ;; by any call insn.
6898 (define_insn "load_callsi"
6899   [(set (match_operand:SI 0 "register_operand" "=c")
6900         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6901                     (match_operand:SI 2 "immediate_operand" "")
6902                     (reg:SI FAKE_CALL_REGNO)]
6903                    UNSPEC_LOAD_CALL))]
6904   "TARGET_ABICALLS"
6905   "lw\t%0,%R2(%1)"
6906   [(set_attr "type" "load")
6907    (set_attr "length" "4")])
6908
6909 (define_insn "load_calldi"
6910   [(set (match_operand:DI 0 "register_operand" "=c")
6911         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
6912                     (match_operand:DI 2 "immediate_operand" "")
6913                     (reg:DI FAKE_CALL_REGNO)]
6914                    UNSPEC_LOAD_CALL))]
6915   "TARGET_ABICALLS"
6916   "ld\t%0,%R2(%1)"
6917   [(set_attr "type" "load")
6918    (set_attr "length" "4")])
6919
6920 ;; Sibling calls.  All these patterns use jump instructions.
6921
6922 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
6923 ;; addresses if a direct jump is acceptable.  Since the 'S' constraint
6924 ;; is defined in terms of call_insn_operand, the same is true of the
6925 ;; constraints.
6926
6927 ;; When we use an indirect jump, we need a register that will be
6928 ;; preserved by the epilogue.  Since TARGET_ABICALLS forces us to
6929 ;; use $25 for this purpose -- and $25 is never clobbered by the
6930 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
6931
6932 (define_expand "sibcall"
6933   [(parallel [(call (match_operand 0 "")
6934                     (match_operand 1 ""))
6935               (use (match_operand 2 ""))        ;; next_arg_reg
6936               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
6937   "TARGET_SIBCALLS"
6938 {
6939   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
6940   DONE;
6941 })
6942
6943 (define_insn "sibcall_internal"
6944   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
6945          (match_operand 1 "" ""))]
6946   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6947   "@
6948     %*jr\t%0%/
6949     %*j\t%0%/"
6950   [(set_attr "type" "call")])
6951
6952 (define_expand "sibcall_value"
6953   [(parallel [(set (match_operand 0 "")
6954                    (call (match_operand 1 "")
6955                          (match_operand 2 "")))
6956               (use (match_operand 3 ""))])]             ;; next_arg_reg
6957   "TARGET_SIBCALLS"
6958 {
6959   mips_expand_call (operands[0], XEXP (operands[1], 0),
6960                     operands[2], operands[3], true);
6961   DONE;
6962 })
6963
6964 (define_insn "sibcall_value_internal"
6965   [(set (match_operand 0 "register_operand" "=df,df")
6966         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6967               (match_operand 2 "" "")))]
6968   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6969   "@
6970     %*jr\t%1%/
6971     %*j\t%1%/"
6972   [(set_attr "type" "call")])
6973
6974 (define_insn "sibcall_value_multiple_internal"
6975   [(set (match_operand 0 "register_operand" "=df,df")
6976         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6977               (match_operand 2 "" "")))
6978    (set (match_operand 3 "register_operand" "=df,df")
6979         (call (mem:SI (match_dup 1))
6980               (match_dup 2)))]
6981   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6982   "@
6983     %*jr\t%1%/
6984     %*j\t%1%/"
6985   [(set_attr "type" "call")])
6986
6987 (define_expand "call"
6988   [(parallel [(call (match_operand 0 "")
6989                     (match_operand 1 ""))
6990               (use (match_operand 2 ""))        ;; next_arg_reg
6991               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
6992   ""
6993 {
6994   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
6995   DONE;
6996 })
6997
6998 ;; This instruction directly corresponds to an assembly-language "jal".
6999 ;; There are four cases:
7000 ;;
7001 ;;    - -mno-abicalls:
7002 ;;        Both symbolic and register destinations are OK.  The pattern
7003 ;;        always expands to a single mips instruction.
7004 ;;
7005 ;;    - -mabicalls/-mno-explicit-relocs:
7006 ;;        Again, both symbolic and register destinations are OK.
7007 ;;        The call is treated as a multi-instruction black box.
7008 ;;
7009 ;;    - -mabicalls/-mexplicit-relocs with n32 or n64:
7010 ;;        Only "jal $25" is allowed.  This expands to a single "jalr $25"
7011 ;;        instruction.
7012 ;;
7013 ;;    - -mabicalls/-mexplicit-relocs with o32 or o64:
7014 ;;        Only "jal $25" is allowed.  The call is actually two instructions:
7015 ;;        "jalr $25" followed by an insn to reload $gp.
7016 ;;
7017 ;; In the last case, we can generate the individual instructions with
7018 ;; a define_split.  There are several things to be wary of:
7019 ;;
7020 ;;   - We can't expose the load of $gp before reload.  If we did,
7021 ;;     it might get removed as dead, but reload can introduce new
7022 ;;     uses of $gp by rematerializing constants.
7023 ;;
7024 ;;   - We shouldn't restore $gp after calls that never return.
7025 ;;     It isn't valid to insert instructions between a noreturn
7026 ;;     call and the following barrier.
7027 ;;
7028 ;;   - The splitter deliberately changes the liveness of $gp.  The unsplit
7029 ;;     instruction preserves $gp and so have no effect on its liveness.
7030 ;;     But once we generate the separate insns, it becomes obvious that
7031 ;;     $gp is not live on entry to the call.
7032 ;;
7033 ;; ??? The operands[2] = insn check is a hack to make the original insn
7034 ;; available to the splitter.
7035 (define_insn_and_split "call_internal"
7036   [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
7037          (match_operand 1 "" ""))
7038    (clobber (reg:SI 31))]
7039   ""
7040   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
7041   "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
7042   [(const_int 0)]
7043 {
7044   emit_call_insn (gen_call_split (operands[0], operands[1]));
7045   if (!find_reg_note (operands[2], REG_NORETURN, 0))
7046     mips_restore_gp ();
7047   DONE;
7048 }
7049   [(set_attr "jal" "indirect,direct")
7050    (set_attr "extended_mips16" "no,yes")])
7051
7052 (define_insn "call_split"
7053   [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
7054          (match_operand 1 "" ""))
7055    (clobber (reg:SI 31))
7056    (clobber (reg:SI 28))]
7057   "TARGET_SPLIT_CALLS"
7058   "%*jalr\t%0%/"
7059   [(set_attr "type" "call")])
7060
7061 (define_expand "call_value"
7062   [(parallel [(set (match_operand 0 "")
7063                    (call (match_operand 1 "")
7064                          (match_operand 2 "")))
7065               (use (match_operand 3 ""))])]             ;; next_arg_reg
7066   ""
7067 {
7068   mips_expand_call (operands[0], XEXP (operands[1], 0),
7069                     operands[2], operands[3], false);
7070   DONE;
7071 })
7072
7073 ;; See comment for call_internal.
7074 (define_insn_and_split "call_value_internal"
7075   [(set (match_operand 0 "register_operand" "=df,df")
7076         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7077               (match_operand 2 "" "")))
7078    (clobber (reg:SI 31))]
7079   ""
7080   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7081   "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
7082   [(const_int 0)]
7083 {
7084   emit_call_insn (gen_call_value_split (operands[0], operands[1],
7085                                         operands[2]));
7086   if (!find_reg_note (operands[3], REG_NORETURN, 0))
7087     mips_restore_gp ();
7088   DONE;
7089 }
7090   [(set_attr "jal" "indirect,direct")
7091    (set_attr "extended_mips16" "no,yes")])
7092
7093 (define_insn "call_value_split"
7094   [(set (match_operand 0 "register_operand" "=df")
7095         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7096               (match_operand 2 "" "")))
7097    (clobber (reg:SI 31))
7098    (clobber (reg:SI 28))]
7099   "TARGET_SPLIT_CALLS"
7100   "%*jalr\t%1%/"
7101   [(set_attr "type" "call")])
7102
7103 ;; See comment for call_internal.
7104 (define_insn_and_split "call_value_multiple_internal"
7105   [(set (match_operand 0 "register_operand" "=df,df")
7106         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7107               (match_operand 2 "" "")))
7108    (set (match_operand 3 "register_operand" "=df,df")
7109         (call (mem:SI (match_dup 1))
7110               (match_dup 2)))
7111    (clobber (reg:SI 31))]
7112   ""
7113   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7114   "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
7115   [(const_int 0)]
7116 {
7117   emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
7118                                                  operands[2], operands[3]));
7119   if (!find_reg_note (operands[4], REG_NORETURN, 0))
7120     mips_restore_gp ();
7121   DONE;
7122 }
7123   [(set_attr "jal" "indirect,direct")
7124    (set_attr "extended_mips16" "no,yes")])
7125
7126 (define_insn "call_value_multiple_split"
7127   [(set (match_operand 0 "register_operand" "=df")
7128         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7129               (match_operand 2 "" "")))
7130    (set (match_operand 3 "register_operand" "=df")
7131         (call (mem:SI (match_dup 1))
7132               (match_dup 2)))
7133    (clobber (reg:SI 31))
7134    (clobber (reg:SI 28))]
7135   "TARGET_SPLIT_CALLS"
7136   "%*jalr\t%1%/"
7137   [(set_attr "type" "call")])
7138
7139 ;; Call subroutine returning any type.
7140
7141 (define_expand "untyped_call"
7142   [(parallel [(call (match_operand 0 "")
7143                     (const_int 0))
7144               (match_operand 1 "")
7145               (match_operand 2 "")])]
7146   ""
7147 {
7148   int i;
7149
7150   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
7151
7152   for (i = 0; i < XVECLEN (operands[2], 0); i++)
7153     {
7154       rtx set = XVECEXP (operands[2], 0, i);
7155       emit_move_insn (SET_DEST (set), SET_SRC (set));
7156     }
7157
7158   emit_insn (gen_blockage ());
7159   DONE;
7160 })
7161 \f
7162 ;;
7163 ;;  ....................
7164 ;;
7165 ;;      MISC.
7166 ;;
7167 ;;  ....................
7168 ;;
7169
7170
7171 (define_expand "prefetch"
7172   [(prefetch (match_operand 0 "address_operand")
7173              (match_operand 1 "const_int_operand")
7174              (match_operand 2 "const_int_operand"))]
7175   "ISA_HAS_PREFETCH"
7176 {
7177   if (symbolic_operand (operands[0], GET_MODE (operands[0])))
7178     operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
7179 })
7180
7181 (define_insn "prefetch_si_address"
7182   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7183                       (match_operand:SI 3 "const_int_operand" "I"))
7184              (match_operand:SI 1 "const_int_operand" "n")
7185              (match_operand:SI 2 "const_int_operand" "n"))]
7186   "ISA_HAS_PREFETCH && Pmode == SImode"
7187   { return mips_emit_prefetch (operands); }
7188   [(set_attr "type" "prefetch")])
7189
7190 (define_insn "prefetch_indexed_si"
7191   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7192                       (match_operand:SI 3 "register_operand" "r"))
7193              (match_operand:SI 1 "const_int_operand" "n")
7194              (match_operand:SI 2 "const_int_operand" "n"))]
7195   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
7196   { return mips_emit_prefetch (operands); }
7197   [(set_attr "type" "prefetchx")])
7198
7199 (define_insn "prefetch_si"
7200   [(prefetch (match_operand:SI 0 "register_operand" "r")
7201              (match_operand:SI 1 "const_int_operand" "n")
7202              (match_operand:SI 2 "const_int_operand" "n"))]
7203   "ISA_HAS_PREFETCH && Pmode == SImode"
7204 {
7205   operands[3] = const0_rtx;
7206   return mips_emit_prefetch (operands);
7207 }
7208   [(set_attr "type" "prefetch")])
7209
7210 (define_insn "prefetch_di_address"
7211   [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7212                       (match_operand:DI 3 "const_int_operand" "I"))
7213              (match_operand:DI 1 "const_int_operand" "n")
7214              (match_operand:DI 2 "const_int_operand" "n"))]
7215   "ISA_HAS_PREFETCH && Pmode == DImode"
7216   { return mips_emit_prefetch (operands); }
7217   [(set_attr "type" "prefetch")])
7218
7219 (define_insn "prefetch_indexed_di"
7220   [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7221                       (match_operand:DI 3 "register_operand" "r"))
7222              (match_operand:DI 1 "const_int_operand" "n")
7223              (match_operand:DI 2 "const_int_operand" "n"))]
7224   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
7225   { return mips_emit_prefetch (operands); }
7226   [(set_attr "type" "prefetchx")])
7227
7228 (define_insn "prefetch_di"
7229   [(prefetch (match_operand:DI 0 "register_operand" "r")
7230              (match_operand:DI 1 "const_int_operand" "n")
7231              (match_operand:DI 2 "const_int_operand" "n"))]
7232   "ISA_HAS_PREFETCH && Pmode == DImode"
7233 {
7234   operands[3] = const0_rtx;
7235   return mips_emit_prefetch (operands);
7236 }
7237   [(set_attr "type" "prefetch")])
7238
7239 (define_insn "nop"
7240   [(const_int 0)]
7241   ""
7242   "%(nop%)"
7243   [(set_attr "type"     "nop")
7244    (set_attr "mode"     "none")])
7245
7246 ;; Like nop, but commented out when outside a .set noreorder block.
7247 (define_insn "hazard_nop"
7248   [(const_int 1)]
7249   ""
7250   {
7251     if (set_noreorder)
7252       return "nop";
7253     else
7254       return "#nop";
7255   }
7256   [(set_attr "type"     "nop")])
7257 \f
7258 ;; MIPS4 Conditional move instructions.
7259
7260 (define_insn ""
7261   [(set (match_operand:SI 0 "register_operand" "=d,d")
7262         (if_then_else:SI
7263          (match_operator 4 "equality_op"
7264                          [(match_operand:SI 1 "register_operand" "d,d")
7265                           (const_int 0)])
7266          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7267          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7268   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7269   "@
7270     mov%B4\t%0,%z2,%1
7271     mov%b4\t%0,%z3,%1"
7272   [(set_attr "type" "condmove")
7273    (set_attr "mode" "SI")])
7274
7275 (define_insn ""
7276   [(set (match_operand:SI 0 "register_operand" "=d,d")
7277         (if_then_else:SI
7278          (match_operator 4 "equality_op"
7279                          [(match_operand:DI 1 "register_operand" "d,d")
7280                           (const_int 0)])
7281          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7282          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7283   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7284   "@
7285     mov%B4\t%0,%z2,%1
7286     mov%b4\t%0,%z3,%1"
7287   [(set_attr "type" "condmove")
7288    (set_attr "mode" "SI")])
7289
7290 (define_insn ""
7291   [(set (match_operand:SI 0 "register_operand" "=d,d")
7292         (if_then_else:SI
7293          (match_operator 3 "equality_op" [(match_operand:CC 4
7294                                                             "register_operand"
7295                                                             "z,z")
7296                                           (const_int 0)])
7297          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
7298          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
7299   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7300   "@
7301     mov%T3\t%0,%z1,%4
7302     mov%t3\t%0,%z2,%4"
7303   [(set_attr "type" "condmove")
7304    (set_attr "mode" "SI")])
7305
7306 (define_insn ""
7307   [(set (match_operand:DI 0 "register_operand" "=d,d")
7308         (if_then_else:DI
7309          (match_operator 4 "equality_op"
7310                          [(match_operand:SI 1 "register_operand" "d,d")
7311                           (const_int 0)])
7312          (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7313          (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7314   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7315   "@
7316     mov%B4\t%0,%z2,%1
7317     mov%b4\t%0,%z3,%1"
7318   [(set_attr "type" "condmove")
7319    (set_attr "mode" "DI")])
7320
7321 (define_insn ""
7322   [(set (match_operand:DI 0 "register_operand" "=d,d")
7323         (if_then_else:DI
7324          (match_operator 4 "equality_op"
7325                          [(match_operand:DI 1 "register_operand" "d,d")
7326                           (const_int 0)])
7327          (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7328          (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7329   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7330   "@
7331     mov%B4\t%0,%z2,%1
7332     mov%b4\t%0,%z3,%1"
7333   [(set_attr "type" "condmove")
7334    (set_attr "mode" "DI")])
7335
7336 (define_insn ""
7337   [(set (match_operand:DI 0 "register_operand" "=d,d")
7338         (if_then_else:DI
7339          (match_operator 3 "equality_op" [(match_operand:CC 4
7340                                                             "register_operand"
7341                                                             "z,z")
7342                                           (const_int 0)])
7343          (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
7344          (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
7345   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
7346   "@
7347     mov%T3\t%0,%z1,%4
7348     mov%t3\t%0,%z2,%4"
7349   [(set_attr "type" "condmove")
7350    (set_attr "mode" "DI")])
7351
7352 (define_insn ""
7353   [(set (match_operand:SF 0 "register_operand" "=f,f")
7354         (if_then_else:SF
7355          (match_operator 4 "equality_op"
7356                          [(match_operand:SI 1 "register_operand" "d,d")
7357                           (const_int 0)])
7358          (match_operand:SF 2 "register_operand" "f,0")
7359          (match_operand:SF 3 "register_operand" "0,f")))]
7360   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7361   "@
7362     mov%B4.s\t%0,%2,%1
7363     mov%b4.s\t%0,%3,%1"
7364   [(set_attr "type" "condmove")
7365    (set_attr "mode" "SF")])
7366
7367 (define_insn ""
7368   [(set (match_operand:SF 0 "register_operand" "=f,f")
7369         (if_then_else:SF
7370          (match_operator 4 "equality_op"
7371                          [(match_operand:DI 1 "register_operand" "d,d")
7372                           (const_int 0)])
7373          (match_operand:SF 2 "register_operand" "f,0")
7374          (match_operand:SF 3 "register_operand" "0,f")))]
7375   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7376   "@
7377     mov%B4.s\t%0,%2,%1
7378     mov%b4.s\t%0,%3,%1"
7379   [(set_attr "type" "condmove")
7380    (set_attr "mode" "SF")])
7381
7382 (define_insn ""
7383   [(set (match_operand:SF 0 "register_operand" "=f,f")
7384         (if_then_else:SF
7385          (match_operator 3 "equality_op" [(match_operand:CC 4
7386                                                             "register_operand"
7387                                                             "z,z")
7388                                           (const_int 0)])
7389          (match_operand:SF 1 "register_operand" "f,0")
7390          (match_operand:SF 2 "register_operand" "0,f")))]
7391   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7392   "@
7393     mov%T3.s\t%0,%1,%4
7394     mov%t3.s\t%0,%2,%4"
7395   [(set_attr "type" "condmove")
7396    (set_attr "mode" "SF")])
7397
7398 (define_insn ""
7399   [(set (match_operand:DF 0 "register_operand" "=f,f")
7400         (if_then_else:DF
7401          (match_operator 4 "equality_op"
7402                          [(match_operand:SI 1 "register_operand" "d,d")
7403                           (const_int 0)])
7404          (match_operand:DF 2 "register_operand" "f,0")
7405          (match_operand:DF 3 "register_operand" "0,f")))]
7406   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7407   "@
7408     mov%B4.d\t%0,%2,%1
7409     mov%b4.d\t%0,%3,%1"
7410   [(set_attr "type" "condmove")
7411    (set_attr "mode" "DF")])
7412
7413 (define_insn ""
7414   [(set (match_operand:DF 0 "register_operand" "=f,f")
7415         (if_then_else:DF
7416          (match_operator 4 "equality_op"
7417                          [(match_operand:DI 1 "register_operand" "d,d")
7418                           (const_int 0)])
7419          (match_operand:DF 2 "register_operand" "f,0")
7420          (match_operand:DF 3 "register_operand" "0,f")))]
7421   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7422   "@
7423     mov%B4.d\t%0,%2,%1
7424     mov%b4.d\t%0,%3,%1"
7425   [(set_attr "type" "condmove")
7426    (set_attr "mode" "DF")])
7427
7428 (define_insn ""
7429   [(set (match_operand:DF 0 "register_operand" "=f,f")
7430         (if_then_else:DF
7431          (match_operator 3 "equality_op" [(match_operand:CC 4
7432                                                             "register_operand"
7433                                                             "z,z")
7434                                           (const_int 0)])
7435          (match_operand:DF 1 "register_operand" "f,0")
7436          (match_operand:DF 2 "register_operand" "0,f")))]
7437   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7438   "@
7439     mov%T3.d\t%0,%1,%4
7440     mov%t3.d\t%0,%2,%4"
7441   [(set_attr "type" "condmove")
7442    (set_attr "mode" "DF")])
7443
7444 ;; These are the main define_expand's used to make conditional moves.
7445
7446 (define_expand "movsicc"
7447   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7448    (set (match_operand:SI 0 "register_operand")
7449         (if_then_else:SI (match_dup 5)
7450                          (match_operand:SI 2 "reg_or_0_operand")
7451                          (match_operand:SI 3 "reg_or_0_operand")))]
7452   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7453 {
7454   gen_conditional_move (operands);
7455   DONE;
7456 })
7457
7458 (define_expand "movdicc"
7459   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7460    (set (match_operand:DI 0 "register_operand")
7461         (if_then_else:DI (match_dup 5)
7462                          (match_operand:DI 2 "reg_or_0_operand")
7463                          (match_operand:DI 3 "reg_or_0_operand")))]
7464   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7465 {
7466   gen_conditional_move (operands);
7467   DONE;
7468 })
7469
7470 (define_expand "movsfcc"
7471   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7472    (set (match_operand:SF 0 "register_operand")
7473         (if_then_else:SF (match_dup 5)
7474                          (match_operand:SF 2 "register_operand")
7475                          (match_operand:SF 3 "register_operand")))]
7476   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7477 {
7478   gen_conditional_move (operands);
7479   DONE;
7480 })
7481
7482 (define_expand "movdfcc"
7483   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7484    (set (match_operand:DF 0 "register_operand")
7485         (if_then_else:DF (match_dup 5)
7486                          (match_operand:DF 2 "register_operand")
7487                          (match_operand:DF 3 "register_operand")))]
7488   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7489 {
7490   gen_conditional_move (operands);
7491   DONE;
7492 })
7493 \f
7494 ;;
7495 ;;  ....................
7496 ;;
7497 ;;      mips16 inline constant tables
7498 ;;
7499 ;;  ....................
7500 ;;
7501
7502 (define_insn "consttable_int"
7503   [(unspec_volatile [(match_operand 0 "consttable_operand" "")
7504                      (match_operand 1 "const_int_operand" "")]
7505                     UNSPEC_CONSTTABLE_INT)]
7506   "TARGET_MIPS16"
7507 {
7508   assemble_integer (operands[0], INTVAL (operands[1]),
7509                     BITS_PER_UNIT * INTVAL (operands[1]), 1);
7510   return "";
7511 }
7512   [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
7513
7514 (define_insn "consttable_float"
7515   [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
7516                     UNSPEC_CONSTTABLE_FLOAT)]
7517   "TARGET_MIPS16"
7518 {
7519   REAL_VALUE_TYPE d;
7520
7521   if (GET_CODE (operands[0]) != CONST_DOUBLE)
7522     abort ();
7523   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7524   assemble_real (d, GET_MODE (operands[0]),
7525                  GET_MODE_BITSIZE (GET_MODE (operands[0])));
7526   return "";
7527 }
7528   [(set (attr "length")
7529         (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
7530
7531 (define_insn "align"
7532   [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
7533   ""
7534   ".align\t%0"
7535   [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
7536 \f
7537 (define_split
7538   [(match_operand 0 "small_data_pattern")]
7539   "reload_completed"
7540   [(match_dup 0)]
7541   { operands[0] = mips_rewrite_small_data (operands[0]); })