* config/mips/mips.md (cprestore): Provide two alternatives, one for
[official-gcc.git] / gcc / config / mips / mips.md
blob7c6771dd74996d6d93630ae2edb28d095c9d7133
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.
9 ;; This file is part of GCC.
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.
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.
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.
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)
53    (UNSPEC_ADDRESS_FIRST        100)
55    (FAKE_CALL_REGNO             79)])
57 ;; ....................
59 ;;      Attributes
61 ;; ....................
63 (define_attr "got" "unset,xgot_high,load"
64   (const_string "unset"))
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"))
71 ;; This attribute is YES if the instruction is a jal macro (not a
72 ;; real jal instruction).
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")))
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")))
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"))
132 ;; Is this an extended instruction in mips16 mode?
133 (define_attr "extended_mips16" "no,yes"
134   (const_string "no"))
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))
178           (eq_attr "got" "load")
179           (const_int 4)
180           (eq_attr "got" "xgot_high")
181           (const_int 8)
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")
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)
203           (and (eq_attr "extended_mips16" "yes")
204                (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
205           (const_int 8)
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)
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)
222           (eq_attr "type" "idiv")
223           (symbol_ref "mips_idiv_insns () * 4")
224           ] (const_int 4)))
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")))
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")
241          (and (eq_attr "type" "xfer")
242               (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
243          (const_string "delay")
245          (and (eq_attr "type" "fcmp")
246               (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
247          (const_string "delay")
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")
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")))
259 ;; Is it a single instruction?
260 (define_attr "single_insn" "no,yes"
261   (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
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")))
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"))))
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")))
285 ;; Describe a user's asm statement.
286 (define_asm_attributes
287   [(set_attr "type" "multi")])
289 ;; .........................
291 ;;      Branch, call and jump delay slots
293 ;; .........................
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"))])
302 (define_delay (eq_attr "type" "jump")
303   [(eq_attr "can_delay" "yes")
304    (nil)
305    (nil)])
307 (define_delay (and (eq_attr "type" "call")
308                    (eq_attr "jal_macro" "no"))
309   [(eq_attr "can_delay" "yes")
310    (nil)
311    (nil)])
313 ;; Pipeline descriptions.
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.
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")
325 (define_cpu_unit "alu" "alu")
326 (define_cpu_unit "imuldiv" "imuldiv")
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")
345 ;;  ....................
347 ;;      CONDITIONAL TRAPS
349 ;;  ....................
352 (define_insn "trap"
353   [(trap_if (const_int 1) (const_int 0))]
354   ""
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";
364   [(set_attr "type"     "trap")])
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"
372   if (operands[1] == const0_rtx)
373     {
374       mips_gen_conditional_trap (operands);
375       DONE;
376     }
377   else
378     FAIL;
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")])
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")])
400 ;;  ....................
402 ;;      ADDITION
404 ;;  ....................
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")])
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")])
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   "")
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")])
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.
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)))])
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)))])
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"
476   if (REGNO (operands[0]) == REGNO (operands[1]))
477     return "addu\t%0,%2";
478   else
479     return "addu\t%0,%1,%2";
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)])])
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.
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)))]
514   HOST_WIDE_INT val = INTVAL (operands[1]);
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     }
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)))]
546   HOST_WIDE_INT val = INTVAL (operands[2]);
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     }
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")
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")])
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.
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)))])
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)))])
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"
611   if (REGNO (operands[0]) == REGNO (operands[1]))
612     return "daddu\t%0,%2";
613   else
614     return "daddu\t%0,%1,%2";
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)])])
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.
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)))]
649   HOST_WIDE_INT val = INTVAL (operands[1]);
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     }
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)))]
681   HOST_WIDE_INT val = INTVAL (operands[2]);
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     }
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")])
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"
712   if (REGNO (operands[0]) == REGNO (operands[1]))
713     return "addu\t%0,%2";
714   else
715     return "addu\t%0,%1,%2";
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)])])
729 ;;  ....................
731 ;;      SUBTRACTION
733 ;;  ....................
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")])
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")])
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   "")
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")])
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")])
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")])
790 ;;  ....................
792 ;;      MULTIPLICATION
794 ;;  ....................
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   "")
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")])
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.
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")])
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   "")
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")])
843 ;; See muldf3_r4300.
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")])
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.
861 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
862 ;; (also valid for MIPS R4000MC processors):
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."
879 ;; and:
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."
899 ;; These processors have PRId values of 0x00004220 and 0x00004300,
900 ;; respectively.
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   ""
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;
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"
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";
939   [(set_attr "type"     "imul")
940    (set_attr "mode"     "SI")])
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.
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))])])
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")])
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")])
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.
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))])])
1021 ;; Multiply-accumulate patterns
1023 ;; For processors that can copy the output to a general register:
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.
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"
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];
1052   [(set_attr "type"     "imadd,imadd,multi")
1053    (set_attr "mode"     "SI")
1054    (set_attr "length"   "4,4,8")])
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   "")
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   "")
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"
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%]";
1115   [(set_attr "type" "imadd")
1116    (set_attr "mode" "SI")])
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"
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";
1134   [(set_attr "type"     "imadd")
1135    (set_attr "mode"     "SI")])
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")])
1162 ;; Patterns generated by the define_peephole2 below.
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")])
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")])
1194 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1195 ;; Similarly msac.
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   "")
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.
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.
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))]
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]);
1258 ;; Same as above, except LO is the initial target of the macc.
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))]
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]);
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")])
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   "")
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   "")
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")])
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"
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;
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")])
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")])
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")])
1412 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
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"
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     }
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")])
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")])
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)))])
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))
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)))
1495    ;; Shift OP0 into place.
1496    (set (match_dup 0)
1497         (ashift:DI (match_dup 0)
1498                    (const_int 32)))
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")])
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])"
1523   if (GET_CODE (operands[4]) == SIGN_EXTEND)
1524     return "mult\t%2,%3";
1525   else
1526     return "multu\t%2,%3";
1528   [(set_attr "type" "imul")
1529    (set_attr "mode" "SI")])
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"
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     }
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")])
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")])
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")])
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")])
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"
1610   if (TARGET_MIPS5500)
1611     return "msub\t%1,%2";
1612   else
1613     return "msac\t$0,%1,%2";
1615   [(set_attr "type"     "imadd")
1616    (set_attr "length"   "4")
1617    (set_attr "mode"     "SI")])
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"
1628   if (TARGET_MIPS5500)
1629     return "msubu\t%1,%2";
1630   else
1631     return "msacu\t$0,%1,%2";
1633   [(set_attr "type"     "imadd")
1634    (set_attr "length"   "4")
1635    (set_attr "mode"     "SI")])
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"
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;
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")])
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")])
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")])
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"
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;
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")])
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")])
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")])
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")])
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")])
1802 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1803 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
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")])
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"
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%]";
1833   [(set_attr "type"   "imadd")
1834    (set_attr "mode"   "SI")])
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"
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%]";
1854   [(set_attr "type"   "imadd")
1855    (set_attr "mode"   "SI")])
1857 ;; Floating point multiply accumulate instructions.
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")])
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")])
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")])
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")))]
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")])
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")])
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")])
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")])
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")])
1941 ;;  ....................
1943 ;;      DIVISION and REMAINDER
1945 ;;  ....................
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"
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]);
1959 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
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.
1968 ;; The workaround is to insert an unconditional 'mov' from/to the
1969 ;; long latency op destination register.
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"
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";
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)))])
1990 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
1992 ;; In certain cases, div.s and div.ps may have a rounding error
1993 ;; and/or wrong inexact flag.
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)"
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]);
2009 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2010 ;; "divdf3" comment for details).
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)"
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";
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)))])
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"
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";
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)))])
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"
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";
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)))])
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")])
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")])
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")])
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")])
2123 ;;  ....................
2125 ;;      SQUARE ROOT
2127 ;;  ....................
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"
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";
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)))])
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()"
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";
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)))])
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"
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";
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)))])
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"
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";
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)))])
2208 ;;  ....................
2210 ;;      ABSOLUTE VALUE
2212 ;;  ....................
2214 ;; Do not use the integer abs macro instruction, since that signals an
2215 ;; exception on -2147483648 (sigh).
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"
2222   operands[2] = const0_rtx;
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:%)";
2234   [(set_attr "type"     "multi")
2235    (set_attr "mode"     "SI")
2236    (set_attr "length"   "12")])
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"
2243   unsigned int regno1;
2244   operands[2] = const0_rtx;
2246   if (GET_CODE (operands[1]) == REG)
2247     regno1 = REGNO (operands[1]);
2248   else
2249     regno1 = REGNO (XEXP (operands[1], 0));
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:%)";
2256   [(set_attr "type"     "multi")
2257    (set_attr "mode"     "DI")
2258    (set_attr "length"   "12")])
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")])
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")])
2277 ;;  ....................
2279 ;;      FIND FIRST BIT INSTRUCTION
2281 ;;  ....................
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"
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:%)";
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:%)";
2311   [(set_attr "type"     "multi")
2312    (set_attr "mode"     "SI")
2313    (set_attr "length"   "28")])
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"
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:%)";
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:%)";
2342   [(set_attr "type"     "multi")
2343    (set_attr "mode"     "DI")
2344    (set_attr "length"   "28")])
2347 ;;  ...................
2349 ;;  Count leading zeroes.
2351 ;;  ...................
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")])
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")])
2371 ;;  ....................
2373 ;;      NEGATION and ONE'S COMPLEMENT
2375 ;;  ....................
2377 (define_insn "negsi2"
2378   [(set (match_operand:SI 0 "register_operand" "=d")
2379         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2380   ""
2382   if (TARGET_MIPS16)
2383     return "neg\t%0,%1";
2384   else
2385     return "subu\t%0,%.,%1";
2387   [(set_attr "type"     "arith")
2388    (set_attr "mode"     "SI")])
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")])
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")])
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")])
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   ""
2419   if (TARGET_MIPS16)
2420     return "not\t%0,%1";
2421   else
2422     return "nor\t%0,%.,%1";
2424   [(set_attr "type"     "arith")
2425    (set_attr "mode"     "SI")])
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"
2432   if (TARGET_MIPS16)
2433     return "not\t%0,%1";
2434   else
2435     return "nor\t%0,%.,%1";
2437   [(set_attr "type"     "arith")
2438    (set_attr "mode"     "DI")])
2441 ;;  ....................
2443 ;;      LOGICAL
2445 ;;  ....................
2448 ;; Many of these instructions use trivial define_expands, because we
2449 ;; want to use a different set of constraints when TARGET_MIPS16.
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   ""
2457   if (TARGET_MIPS16)
2458     {
2459       operands[1] = force_reg (SImode, operands[1]);
2460       operands[2] = force_reg (SImode, operands[2]);
2461     }
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")])
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")])
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"
2490   if (TARGET_MIPS16)
2491     {
2492       operands[1] = force_reg (DImode, operands[1]);
2493       operands[2] = force_reg (DImode, operands[2]);
2494     }
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")])
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")])
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   ""
2523   if (TARGET_MIPS16)
2524     {
2525       operands[1] = force_reg (SImode, operands[1]);
2526       operands[2] = force_reg (SImode, operands[2]);
2527     }
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")])
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")])
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"
2556   if (TARGET_MIPS16)
2557     {
2558       operands[1] = force_reg (DImode, operands[1]);
2559       operands[2] = force_reg (DImode, operands[2]);
2560     }
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")])
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")])
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   "")
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")])
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)])])
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"
2625   if (TARGET_MIPS16)
2626     {
2627       operands[1] = force_reg (DImode, operands[1]);
2628       operands[2] = force_reg (DImode, operands[2]);
2629     }
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")])
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)])])
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")])
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")])
2680 ;;  ....................
2682 ;;      TRUNCATION
2684 ;;  ....................
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")])
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:
2703 ;;                        A       B
2704 ;;    DI ---> HI  ==  DI ---> SI ---> HI
2705 ;;    DI ---> QI  ==  DI ---> SI ---> QI
2707 ;; Step A needs a real instruction but step B does not.
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,*")])
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,*")])
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,*")])
2742 ;; Combiner patterns to optimize shift/truncate combinations.
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")])
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")])
2763 ;; Combiner patterns for truncate/sign_extend combinations.  They use
2764 ;; the shift/truncate patterns above.
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]); })
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]); })
2797 ;; Combiner patterns to optimize truncate/zero_extend combinations.
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")])
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")])
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")])
2827 ;;  ....................
2829 ;;      ZERO EXTENSION
2831 ;;  ....................
2833 ;; Extension insns.
2834 ;; Those for integer source operand are ordered widest source type first.
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")])
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")])
2859 (define_expand "zero_extendhisi2"
2860   [(set (match_operand:SI 0 "register_operand")
2861         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2862   ""
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));
2869       emit_insn (gen_andsi3 (operands[0], op, temp));
2870       DONE;
2871     }
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,*")])
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")])
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"
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));
2903       emit_insn (gen_anddi3 (operands[0], op, temp));
2904       DONE;
2905     }
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,*")])
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")])
2927 (define_expand "zero_extendqihi2"
2928   [(set (match_operand:HI 0 "register_operand")
2929         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2930   ""
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));
2938       emit_insn (gen_andsi3 (op0, op1, temp));
2939       DONE;
2940     }
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,*")])
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")])
2962 (define_expand "zero_extendqisi2"
2963   [(set (match_operand:SI 0 "register_operand")
2964         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2965   ""
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));
2972       emit_insn (gen_andsi3 (operands[0], op, temp));
2973       DONE;
2974     }
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,*")])
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")])
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"
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));
3006       emit_insn (gen_anddi3 (operands[0], op, temp));
3007       DONE;
3008     }
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,*")])
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")])
3031 ;;  ....................
3033 ;;      SIGN EXTENSION
3035 ;;  ....................
3037 ;; Extension insns.
3038 ;; Those for integer source operand are ordered widest source type first.
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.
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)]
3058   emit_note (NOTE_INSN_DELETED);
3059   DONE;
3061   [(set_attr "type" "arith,load")
3062    (set_attr "mode" "DI")])
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.
3068 ;; These expanders originally put values in registers first. We split
3069 ;; all non-mem patterns after reload.
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   "")
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   "#")
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]);")
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")])
3101 (define_expand "extendhisi2"
3102   [(set (match_operand:SI 0 "register_operand")
3103         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
3104   ""
3106   if (ISA_HAS_SEB_SEH)
3107     {
3108       emit_insn (gen_extendhisi2_hw (operands[0],
3109                                      force_reg (HImode, operands[1])));
3110       DONE;
3111     }
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   "#")
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]);")
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")])
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")])
3146 (define_expand "extendqihi2"
3147   [(set (match_operand:HI 0 "register_operand")
3148         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3149   ""
3150   "")
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   "#")
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]);")
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")])
3178 (define_expand "extendqisi2"
3179   [(set (match_operand:SI 0 "register_operand")
3180         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3181   ""
3183   if (ISA_HAS_SEB_SEH)
3184     {
3185       emit_insn (gen_extendqisi2_hw (operands[0],
3186                                      force_reg (QImode, operands[1])));
3187       DONE;
3188     }
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   "#")
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]);")
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")])
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")])
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   "")
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   "#")
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]);")
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")])
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")])
3262 ;;  ....................
3264 ;;      CONVERSIONS
3266 ;;  ....................
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"
3273   if (!ISA_HAS_TRUNC_W)
3274     {
3275       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3276       DONE;
3277     }
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")])
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"
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";
3300   [(set_attr "type"     "fcvt")
3301    (set_attr "mode"     "DF")
3302    (set_attr "length"   "36")])
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"
3309   if (!ISA_HAS_TRUNC_W)
3310     {
3311       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3312       DONE;
3313     }
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")])
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"
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";
3336   [(set_attr "type"     "fcvt")
3337    (set_attr "mode"     "DF")
3338    (set_attr "length"   "36")])
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")])
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")])
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")])
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")])
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")])
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")])
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"
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;
3413   real_2expN (&offset, 31);
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 ();
3420       emit_insn (gen_cmpdf (operands[1], reg1));
3421       emit_jump_insn (gen_bge (label1));
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 ();
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)));
3433       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3434       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3436       emit_label (label2);
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     }
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"
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;
3458   real_2expN (&offset, 63);
3460   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3461   do_pending_stack_adjust ();
3463   emit_insn (gen_cmpdf (operands[1], reg1));
3464   emit_jump_insn (gen_bge (label1));
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 ();
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)));
3476   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3477   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3479   emit_label (label2);
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;
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"
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;
3500   real_2expN (&offset, 31);
3502   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3503   do_pending_stack_adjust ();
3505   emit_insn (gen_cmpsf (operands[1], reg1));
3506   emit_jump_insn (gen_bge (label1));
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 ();
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)));
3518   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3519   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3521   emit_label (label2);
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;
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"
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;
3542   real_2expN (&offset, 63);
3544   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3545   do_pending_stack_adjust ();
3547   emit_insn (gen_cmpsf (operands[1], reg1));
3548   emit_jump_insn (gen_bge (label1));
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 ();
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)));
3560   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3561   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3563   emit_label (label2);
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;
3572 ;;  ....................
3574 ;;      DATA MOVEMENT
3576 ;;  ....................
3578 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
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"
3587   if (mips_expand_unaligned_load (operands[0], operands[1],
3588                                   INTVAL (operands[2]),
3589                                   INTVAL (operands[3])))
3590     DONE;
3591   else
3592     FAIL;
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"
3602   if (mips_expand_unaligned_load (operands[0], operands[1],
3603                                   INTVAL (operands[2]),
3604                                   INTVAL (operands[3])))
3605     DONE;
3606   else
3607     FAIL;
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"
3617   if (mips_expand_unaligned_store (operands[0], operands[3],
3618                                    INTVAL (operands[1]),
3619                                    INTVAL (operands[2])))
3620     DONE;
3621   else
3622     FAIL;
3625 ;; Unaligned word moves generated by the bit field patterns.
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.
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.
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
3725 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3726 ;; The required value is:
3728 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3730 ;; which translates to:
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)))]
3749   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3750   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3752   [(set_attr "length" "20")])
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:
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
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)))]
3781   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3782   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3784   [(set_attr "length" "24")])
3786 ;; Insns to fetch a global symbol from a big GOT.
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)))]
3797   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3798   operands[3] = pic_offset_table_rtx;
3800   [(set_attr "got" "xgot_high")])
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")])
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)))]
3823   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3824   operands[3] = pic_offset_table_rtx;
3826   [(set_attr "got" "xgot_high")])
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")])
3840 ;; Insns to fetch a global symbol from a normal GOT.
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))]
3851   operands[2] = pic_offset_table_rtx;
3852   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3854   [(set_attr "got" "load")])
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))]
3865   operands[2] = pic_offset_table_rtx;
3866   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3868   [(set_attr "got" "load")])
3870 ;; Insns for loading the high part of a local symbol.
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))]
3881   operands[2] = pic_offset_table_rtx;
3882   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3884   [(set_attr "got" "load")])
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))]
3895   operands[2] = pic_offset_table_rtx;
3896   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3898   [(set_attr "got" "load")])
3900 ;; Lower-level instructions for loading an address from the GOT.
3901 ;; We could use MEMs, but an unspec gives more optimization
3902 ;; opportunities.
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")])
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")])
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.
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")])
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")])
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")])
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")])
3966 ;; 64-bit integer moves
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.
3972 (define_expand "movdi"
3973   [(set (match_operand:DI 0 "")
3974         (match_operand:DI 1 ""))]
3975   ""
3977   if (mips_legitimize_move (DImode, operands[0], operands[1]))
3978     DONE;
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.
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")])
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,*")])
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")])
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,*")])
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 "*")])])
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.
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))))]
4073   HOST_WIDE_INT val = INTVAL (operands[1]);
4075   if (val < 0)
4076     operands[2] = const0_rtx;
4077   else if (val >= 32 * 8)
4078     {
4079       int off = val & 7;
4081       operands[1] = GEN_INT (0x8 + off);
4082       operands[2] = GEN_INT (val - off - 0x8);
4083     }
4084   else
4085     {
4086       int off = val & 7;
4088       operands[1] = GEN_INT (off);
4089       operands[2] = GEN_INT (val - off);
4090     }
4093 ;; 32-bit Integer moves
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.
4099 (define_expand "movsi"
4100   [(set (match_operand:SI 0 "")
4101         (match_operand:SI 1 ""))]
4102   ""
4104   if (mips_legitimize_move (SImode, operands[0], operands[1]))
4105     DONE;
4108 ;; We can only store $ra directly into a small sp offset.
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")])
4118 ;; The difference between these two is whether or not ints are allowed
4119 ;; in FP registers (off by default, use -mdebugh to enable).
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,*")])
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 "*")])])
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.
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))))]
4177   HOST_WIDE_INT val = INTVAL (operands[1]);
4179   if (val < 0)
4180     operands[2] = const0_rtx;
4181   else if (val >= 32 * 4)
4182     {
4183       int off = val & 3;
4185       operands[1] = GEN_INT (0x7c + off);
4186       operands[2] = GEN_INT (val - off - 0x7c);
4187     }
4188   else
4189     {
4190       int off = val & 3;
4192       operands[1] = GEN_INT (off);
4193       operands[2] = GEN_INT (val - off);
4194     }
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.
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)))]
4213   int val = INTVAL (operands[1]);
4215   operands[1] = GEN_INT (0xff);
4216   operands[2] = GEN_INT (val - 0xff);
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.
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,*,*")])
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.
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.
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"
4253   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4254   DONE;
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"
4263   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4264   DONE;
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.
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.
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
4360 ;; 16-bit Integer moves
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.
4367 (define_expand "movhi"
4368   [(set (match_operand:HI 0 "")
4369         (match_operand:HI 1 ""))]
4370   ""
4372   if (mips_legitimize_move (HImode, operands[0], operands[1]))
4373     DONE;
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")])
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 "*")])])
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.
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))))]
4447   HOST_WIDE_INT val = INTVAL (operands[1]);
4449   if (val < 0)
4450     operands[2] = const0_rtx;
4451   else if (val >= 32 * 2)
4452     {
4453       int off = val & 1;
4455       operands[1] = GEN_INT (0x7e + off);
4456       operands[2] = GEN_INT (val - off - 0x7e);
4457     }
4458   else
4459     {
4460       int off = val & 1;
4462       operands[1] = GEN_INT (off);
4463       operands[2] = GEN_INT (val - off);
4464     }
4467 ;; 8-bit Integer moves
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.
4474 (define_expand "movqi"
4475   [(set (match_operand:QI 0 "")
4476         (match_operand:QI 1 ""))]
4477   ""
4479   if (mips_legitimize_move (QImode, operands[0], operands[1]))
4480     DONE;
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")])
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,*,*")])
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.
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))))]
4539   HOST_WIDE_INT val = INTVAL (operands[1]);
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     }
4550 ;; 32-bit floating point moves
4552 (define_expand "movsf"
4553   [(set (match_operand:SF 0 "")
4554         (match_operand:SF 1 ""))]
4555   ""
4557   if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4558     DONE;
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,*,*")])
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,*,*")])
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,*,*")])
4595 ;; 64-bit floating point moves
4597 (define_expand "movdf"
4598   [(set (match_operand:DF 0 "")
4599         (match_operand:DF 1 ""))]
4600   ""
4602   if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4603     DONE;
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,*,*")])
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,*,*")])
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")])
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,*,*")])
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)]
4657   mips_split_64bit_move (operands[0], operands[1]);
4658   DONE;
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)]
4668   mips_split_64bit_move (operands[0], operands[1]);
4669   DONE;
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)))]
4683   operands[2] = gen_lowpart (SImode, operands[0]);
4684   operands[3] = GEN_INT (-INTVAL (operands[1]));
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.
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.
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")])
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")])
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.
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"
4723   operands[0] = mips_subword (operands[0], 0);
4724   return mips_output_move (operands[0], operands[1]);
4726   [(set_attr "type"     "xfer,fpload")
4727    (set_attr "mode"     "SF")])
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"
4738   operands[0] = mips_subword (operands[0], 1);
4739   return mips_output_move (operands[0], operands[1]);
4741   [(set_attr "type"     "xfer,fpload")
4742    (set_attr "mode"     "SF")])
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"
4752   operands[1] = mips_subword (operands[1], 1);
4753   return mips_output_move (operands[0], operands[1]);
4755   [(set_attr "type"     "xfer,fpstore")
4756    (set_attr "mode"     "SF")])
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))]
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]);
4776   [(set_attr "length" "12")])
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")])
4790 ;; Emit a .cprestore directive, which normally expands to a single store
4791 ;; instruction.  Note that we continue to use .cprestore for explicit reloc
4792 ;; code so that jals inside inline asms will work correctly.
4793 (define_insn "cprestore"
4794   [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
4795                     UNSPEC_CPRESTORE)]
4796   ""
4798   if (set_nomacro && which_alternative == 1)
4799     return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4800   else
4801     return ".cprestore\t%0";
4803   [(set_attr "type" "store")
4804    (set_attr "length" "4,12")])
4806 ;; Block moves, see mips.c for more details.
4807 ;; Argument 0 is the destination
4808 ;; Argument 1 is the source
4809 ;; Argument 2 is the length
4810 ;; Argument 3 is the alignment
4812 (define_expand "movmemsi"
4813   [(parallel [(set (match_operand:BLK 0 "general_operand")
4814                    (match_operand:BLK 1 "general_operand"))
4815               (use (match_operand:SI 2 ""))
4816               (use (match_operand:SI 3 "const_int_operand"))])]
4817   "!TARGET_MIPS16 && !TARGET_MEMCPY"
4819   if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4820     DONE;
4821   else
4822     FAIL;
4826 ;;  ....................
4828 ;;      SHIFTS
4830 ;;  ....................
4832 ;; Many of these instructions use trivial define_expands, because we
4833 ;; want to use a different set of constraints when TARGET_MIPS16.
4835 (define_expand "ashlsi3"
4836   [(set (match_operand:SI 0 "register_operand")
4837         (ashift:SI (match_operand:SI 1 "register_operand")
4838                    (match_operand:SI 2 "arith_operand")))]
4839   ""
4841   /* On the mips16, a shift of more than 8 is a four byte instruction,
4842      so, for a shift between 8 and 16, it is just as fast to do two
4843      shifts of 8 or less.  If there is a lot of shifting going on, we
4844      may win in CSE.  Otherwise combine will put the shifts back
4845      together again.  This can be called by function_arg, so we must
4846      be careful not to allocate a new register if we've reached the
4847      reload pass.  */
4848   if (TARGET_MIPS16
4849       && optimize
4850       && GET_CODE (operands[2]) == CONST_INT
4851       && INTVAL (operands[2]) > 8
4852       && INTVAL (operands[2]) <= 16
4853       && ! reload_in_progress
4854       && ! reload_completed)
4855     {
4856       rtx temp = gen_reg_rtx (SImode);
4858       emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
4859       emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
4860                                         GEN_INT (INTVAL (operands[2]) - 8)));
4861       DONE;
4862     }
4865 (define_insn "ashlsi3_internal1"
4866   [(set (match_operand:SI 0 "register_operand" "=d")
4867         (ashift:SI (match_operand:SI 1 "register_operand" "d")
4868                    (match_operand:SI 2 "arith_operand" "dI")))]
4869   "!TARGET_MIPS16"
4871   if (GET_CODE (operands[2]) == CONST_INT)
4872     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4874   return "sll\t%0,%1,%2";
4876   [(set_attr "type"     "shift")
4877    (set_attr "mode"     "SI")])
4879 (define_insn "ashlsi3_internal1_extend"
4880   [(set (match_operand:DI 0 "register_operand" "=d")
4881        (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
4882                                   (match_operand:SI 2 "arith_operand" "dI"))))]
4883   "TARGET_64BIT && !TARGET_MIPS16"
4885   if (GET_CODE (operands[2]) == CONST_INT)
4886     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4888   return "sll\t%0,%1,%2";
4890   [(set_attr "type"    "shift")
4891    (set_attr "mode"    "DI")])
4894 (define_insn "ashlsi3_internal2"
4895   [(set (match_operand:SI 0 "register_operand" "=d,d")
4896         (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
4897                    (match_operand:SI 2 "arith_operand" "d,I")))]
4898   "TARGET_MIPS16"
4900   if (which_alternative == 0)
4901     return "sll\t%0,%2";
4903   if (GET_CODE (operands[2]) == CONST_INT)
4904     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4906   return "sll\t%0,%1,%2";
4908   [(set_attr "type"     "shift")
4909    (set_attr "mode"     "SI")
4910    (set_attr_alternative "length"
4911                 [(const_int 4)
4912                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4913                                (const_int 4)
4914                                (const_int 8))])])
4916 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4918 (define_split
4919   [(set (match_operand:SI 0 "register_operand")
4920         (ashift:SI (match_operand:SI 1 "register_operand")
4921                    (match_operand:SI 2 "const_int_operand")))]
4922   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4923    && GET_CODE (operands[2]) == CONST_INT
4924    && INTVAL (operands[2]) > 8
4925    && INTVAL (operands[2]) <= 16"
4926   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
4927    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4928   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4930 (define_expand "ashldi3"
4931   [(set (match_operand:DI 0 "register_operand")
4932         (ashift:DI (match_operand:DI 1 "register_operand")
4933                    (match_operand:SI 2 "arith_operand")))]
4934   "TARGET_64BIT"
4936   /* On the mips16, a shift of more than 8 is a four byte
4937      instruction, so, for a shift between 8 and 16, it is just as
4938      fast to do two shifts of 8 or less.  If there is a lot of
4939      shifting going on, we may win in CSE.  Otherwise combine will
4940      put the shifts back together again.  This can be called by
4941      function_arg, so we must be careful not to allocate a new
4942      register if we've reached the reload pass.  */
4943   if (TARGET_MIPS16
4944       && optimize
4945       && GET_CODE (operands[2]) == CONST_INT
4946       && INTVAL (operands[2]) > 8
4947       && INTVAL (operands[2]) <= 16
4948       && ! reload_in_progress
4949       && ! reload_completed)
4950     {
4951       rtx temp = gen_reg_rtx (DImode);
4953       emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
4954       emit_insn (gen_ashldi3_internal (operands[0], temp,
4955                                        GEN_INT (INTVAL (operands[2]) - 8)));
4956       DONE;
4957     }
4961 (define_insn "ashldi3_internal"
4962   [(set (match_operand:DI 0 "register_operand" "=d")
4963         (ashift:DI (match_operand:DI 1 "register_operand" "d")
4964                    (match_operand:SI 2 "arith_operand" "dI")))]
4965   "TARGET_64BIT && !TARGET_MIPS16"
4967   if (GET_CODE (operands[2]) == CONST_INT)
4968     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4970   return "dsll\t%0,%1,%2";
4972   [(set_attr "type"     "shift")
4973    (set_attr "mode"     "DI")])
4975 (define_insn ""
4976   [(set (match_operand:DI 0 "register_operand" "=d,d")
4977         (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4978                    (match_operand:SI 2 "arith_operand" "d,I")))]
4979   "TARGET_64BIT && TARGET_MIPS16"
4981   if (which_alternative == 0)
4982     return "dsll\t%0,%2";
4984   if (GET_CODE (operands[2]) == CONST_INT)
4985     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4987   return "dsll\t%0,%1,%2";
4989   [(set_attr "type"     "shift")
4990    (set_attr "mode"     "DI")
4991    (set_attr_alternative "length"
4992                 [(const_int 4)
4993                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4994                                (const_int 4)
4995                                (const_int 8))])])
4998 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5000 (define_split
5001   [(set (match_operand:DI 0 "register_operand")
5002         (ashift:DI (match_operand:DI 1 "register_operand")
5003                    (match_operand:SI 2 "const_int_operand")))]
5004   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5005    && reload_completed
5006    && GET_CODE (operands[2]) == CONST_INT
5007    && INTVAL (operands[2]) > 8
5008    && INTVAL (operands[2]) <= 16"
5009   [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
5010    (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
5011   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5013 (define_expand "ashrsi3"
5014   [(set (match_operand:SI 0 "register_operand")
5015         (ashiftrt:SI (match_operand:SI 1 "register_operand")
5016                      (match_operand:SI 2 "arith_operand")))]
5017   ""
5019   /* On the mips16, a shift of more than 8 is a four byte instruction,
5020      so, for a shift between 8 and 16, it is just as fast to do two
5021      shifts of 8 or less.  If there is a lot of shifting going on, we
5022      may win in CSE.  Otherwise combine will put the shifts back
5023      together again.  */
5024   if (TARGET_MIPS16
5025       && optimize
5026       && GET_CODE (operands[2]) == CONST_INT
5027       && INTVAL (operands[2]) > 8
5028       && INTVAL (operands[2]) <= 16)
5029     {
5030       rtx temp = gen_reg_rtx (SImode);
5032       emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5033       emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
5034                                         GEN_INT (INTVAL (operands[2]) - 8)));
5035       DONE;
5036     }
5039 (define_insn "ashrsi3_internal1"
5040   [(set (match_operand:SI 0 "register_operand" "=d")
5041         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
5042                      (match_operand:SI 2 "arith_operand" "dI")))]
5043   "!TARGET_MIPS16"
5045   if (GET_CODE (operands[2]) == CONST_INT)
5046     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5048   return "sra\t%0,%1,%2";
5050   [(set_attr "type"     "shift")
5051    (set_attr "mode"     "SI")])
5053 (define_insn "ashrsi3_internal2"
5054   [(set (match_operand:SI 0 "register_operand" "=d,d")
5055         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5056                      (match_operand:SI 2 "arith_operand" "d,I")))]
5057   "TARGET_MIPS16"
5059   if (which_alternative == 0)
5060     return "sra\t%0,%2";
5062   if (GET_CODE (operands[2]) == CONST_INT)
5063     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5065   return "sra\t%0,%1,%2";
5067   [(set_attr "type"     "shift")
5068    (set_attr "mode"     "SI")
5069    (set_attr_alternative "length"
5070                 [(const_int 4)
5071                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5072                                (const_int 4)
5073                                (const_int 8))])])
5076 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5078 (define_split
5079   [(set (match_operand:SI 0 "register_operand")
5080         (ashiftrt:SI (match_operand:SI 1 "register_operand")
5081                      (match_operand:SI 2 "const_int_operand")))]
5082   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5083    && GET_CODE (operands[2]) == CONST_INT
5084    && INTVAL (operands[2]) > 8
5085    && INTVAL (operands[2]) <= 16"
5086   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
5087    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
5088   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5090 (define_expand "ashrdi3"
5091   [(set (match_operand:DI 0 "register_operand")
5092         (ashiftrt:DI (match_operand:DI 1 "register_operand")
5093                      (match_operand:SI 2 "arith_operand")))]
5094   "TARGET_64BIT"
5096   /* On the mips16, a shift of more than 8 is a four byte
5097      instruction, so, for a shift between 8 and 16, it is just as
5098      fast to do two shifts of 8 or less.  If there is a lot of
5099      shifting going on, we may win in CSE.  Otherwise combine will
5100      put the shifts back together again.  */
5101   if (TARGET_MIPS16
5102       && optimize
5103       && GET_CODE (operands[2]) == CONST_INT
5104       && INTVAL (operands[2]) > 8
5105       && INTVAL (operands[2]) <= 16)
5106     {
5107       rtx temp = gen_reg_rtx (DImode);
5109       emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
5110       emit_insn (gen_ashrdi3_internal (operands[0], temp,
5111                                        GEN_INT (INTVAL (operands[2]) - 8)));
5112       DONE;
5113     }
5117 (define_insn "ashrdi3_internal"
5118   [(set (match_operand:DI 0 "register_operand" "=d")
5119         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5120                      (match_operand:SI 2 "arith_operand" "dI")))]
5121   "TARGET_64BIT && !TARGET_MIPS16"
5123   if (GET_CODE (operands[2]) == CONST_INT)
5124     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5126   return "dsra\t%0,%1,%2";
5128   [(set_attr "type"     "shift")
5129    (set_attr "mode"     "DI")])
5131 (define_insn ""
5132   [(set (match_operand:DI 0 "register_operand" "=d,d")
5133         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5134                      (match_operand:SI 2 "arith_operand" "d,I")))]
5135   "TARGET_64BIT && TARGET_MIPS16"
5137   if (GET_CODE (operands[2]) == CONST_INT)
5138     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5140   return "dsra\t%0,%2";
5142   [(set_attr "type"     "shift")
5143    (set_attr "mode"     "DI")
5144    (set_attr_alternative "length"
5145                 [(const_int 4)
5146                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5147                                (const_int 4)
5148                                (const_int 8))])])
5150 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5152 (define_split
5153   [(set (match_operand:DI 0 "register_operand")
5154         (ashiftrt:DI (match_operand:DI 1 "register_operand")
5155                      (match_operand:SI 2 "const_int_operand")))]
5156   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5157    && reload_completed
5158    && GET_CODE (operands[2]) == CONST_INT
5159    && INTVAL (operands[2]) > 8
5160    && INTVAL (operands[2]) <= 16"
5161   [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
5162    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
5163   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5165 (define_expand "lshrsi3"
5166   [(set (match_operand:SI 0 "register_operand")
5167         (lshiftrt:SI (match_operand:SI 1 "register_operand")
5168                      (match_operand:SI 2 "arith_operand")))]
5169   ""
5171   /* On the mips16, a shift of more than 8 is a four byte instruction,
5172      so, for a shift between 8 and 16, it is just as fast to do two
5173      shifts of 8 or less.  If there is a lot of shifting going on, we
5174      may win in CSE.  Otherwise combine will put the shifts back
5175      together again.  */
5176   if (TARGET_MIPS16
5177       && optimize
5178       && GET_CODE (operands[2]) == CONST_INT
5179       && INTVAL (operands[2]) > 8
5180       && INTVAL (operands[2]) <= 16)
5181     {
5182       rtx temp = gen_reg_rtx (SImode);
5184       emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5185       emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
5186                                         GEN_INT (INTVAL (operands[2]) - 8)));
5187       DONE;
5188     }
5191 (define_insn "lshrsi3_internal1"
5192   [(set (match_operand:SI 0 "register_operand" "=d")
5193         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
5194                      (match_operand:SI 2 "arith_operand" "dI")))]
5195   "!TARGET_MIPS16"
5197   if (GET_CODE (operands[2]) == CONST_INT)
5198     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5200   return "srl\t%0,%1,%2";
5202   [(set_attr "type"     "shift")
5203    (set_attr "mode"     "SI")])
5205 (define_insn "lshrsi3_internal2"
5206   [(set (match_operand:SI 0 "register_operand" "=d,d")
5207         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5208                      (match_operand:SI 2 "arith_operand" "d,I")))]
5209   "TARGET_MIPS16"
5211   if (which_alternative == 0)
5212     return "srl\t%0,%2";
5214   if (GET_CODE (operands[2]) == CONST_INT)
5215     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5217   return "srl\t%0,%1,%2";
5219   [(set_attr "type"     "shift")
5220    (set_attr "mode"     "SI")
5221    (set_attr_alternative "length"
5222                 [(const_int 4)
5223                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5224                                (const_int 4)
5225                                (const_int 8))])])
5228 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5230 (define_split
5231   [(set (match_operand:SI 0 "register_operand")
5232         (lshiftrt:SI (match_operand:SI 1 "register_operand")
5233                      (match_operand:SI 2 "const_int_operand")))]
5234   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5235    && GET_CODE (operands[2]) == CONST_INT
5236    && INTVAL (operands[2]) > 8
5237    && INTVAL (operands[2]) <= 16"
5238   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
5239    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5240   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5242 ;; If we load a byte on the mips16 as a bitfield, the resulting
5243 ;; sequence of instructions is too complicated for combine, because it
5244 ;; involves four instructions: a load, a shift, a constant load into a
5245 ;; register, and an and (the key problem here is that the mips16 does
5246 ;; not have and immediate).  We recognize a shift of a load in order
5247 ;; to make it simple enough for combine to understand.
5249 ;; The length here is the worst case: the length of the split version
5250 ;; will be more accurate.
5251 (define_insn_and_split ""
5252   [(set (match_operand:SI 0 "register_operand" "=d")
5253         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5254                      (match_operand:SI 2 "immediate_operand" "I")))]
5255   "TARGET_MIPS16"
5256   "#"
5257   ""
5258   [(set (match_dup 0) (match_dup 1))
5259    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5260   ""
5261   [(set_attr "type"     "load")
5262    (set_attr "mode"     "SI")
5263    (set_attr "length"   "16")])
5265 (define_expand "lshrdi3"
5266   [(set (match_operand:DI 0 "register_operand")
5267         (lshiftrt:DI (match_operand:DI 1 "register_operand")
5268                      (match_operand:SI 2 "arith_operand")))]
5269   "TARGET_64BIT"
5271   /* On the mips16, a shift of more than 8 is a four byte
5272      instruction, so, for a shift between 8 and 16, it is just as
5273      fast to do two shifts of 8 or less.  If there is a lot of
5274      shifting going on, we may win in CSE.  Otherwise combine will
5275      put the shifts back together again.  */
5276   if (TARGET_MIPS16
5277       && optimize
5278       && GET_CODE (operands[2]) == CONST_INT
5279       && INTVAL (operands[2]) > 8
5280       && INTVAL (operands[2]) <= 16)
5281     {
5282       rtx temp = gen_reg_rtx (DImode);
5284       emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
5285       emit_insn (gen_lshrdi3_internal (operands[0], temp,
5286                                        GEN_INT (INTVAL (operands[2]) - 8)));
5287       DONE;
5288     }
5292 (define_insn "lshrdi3_internal"
5293   [(set (match_operand:DI 0 "register_operand" "=d")
5294         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
5295                      (match_operand:SI 2 "arith_operand" "dI")))]
5296   "TARGET_64BIT && !TARGET_MIPS16"
5298   if (GET_CODE (operands[2]) == CONST_INT)
5299     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5301   return "dsrl\t%0,%1,%2";
5303   [(set_attr "type"     "shift")
5304    (set_attr "mode"     "DI")])
5306 (define_insn ""
5307   [(set (match_operand:DI 0 "register_operand" "=d,d")
5308         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5309                      (match_operand:SI 2 "arith_operand" "d,I")))]
5310   "TARGET_64BIT && TARGET_MIPS16"
5312   if (GET_CODE (operands[2]) == CONST_INT)
5313     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5315   return "dsrl\t%0,%2";
5317   [(set_attr "type"     "shift")
5318    (set_attr "mode"     "DI")
5319    (set_attr_alternative "length"
5320                 [(const_int 4)
5321                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5322                                (const_int 4)
5323                                (const_int 8))])])
5325 (define_insn "rotrsi3"
5326   [(set (match_operand:SI              0 "register_operand" "=d")
5327         (rotatert:SI (match_operand:SI 1 "register_operand" "d")
5328                      (match_operand:SI 2 "arith_operand"    "dn")))]
5329   "ISA_HAS_ROTR_SI"
5331   if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
5332     return "rorv\t%0,%1,%2";
5334   if ((GET_CODE (operands[2]) == CONST_INT)
5335       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
5336     abort ();
5338   return "ror\t%0,%1,%2";
5340   [(set_attr "type"     "shift")
5341    (set_attr "mode"     "SI")])
5343 (define_insn "rotrdi3"
5344   [(set (match_operand:DI              0 "register_operand" "=d")
5345         (rotatert:DI (match_operand:DI 1 "register_operand" "d")
5346                      (match_operand:DI 2 "arith_operand"    "dn")))]
5347   "ISA_HAS_ROTR_DI"
5349   if (TARGET_SR71K)
5350     {
5351       if (GET_CODE (operands[2]) != CONST_INT)
5352         return "drorv\t%0,%1,%2";
5354       if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
5355         return "dror32\t%0,%1,%2";
5356     }
5358   if ((GET_CODE (operands[2]) == CONST_INT)
5359       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
5360     abort ();
5362   return "dror\t%0,%1,%2";
5364   [(set_attr "type"     "shift")
5365    (set_attr "mode"     "DI")])
5368 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5370 (define_split
5371   [(set (match_operand:DI 0 "register_operand")
5372         (lshiftrt:DI (match_operand:DI 1 "register_operand")
5373                      (match_operand:SI 2 "const_int_operand")))]
5374   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5375    && GET_CODE (operands[2]) == CONST_INT
5376    && INTVAL (operands[2]) > 8
5377    && INTVAL (operands[2]) <= 16"
5378   [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
5379    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
5380   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5383 ;;  ....................
5385 ;;      COMPARISONS
5387 ;;  ....................
5389 ;; Flow here is rather complex:
5391 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the arguments
5392 ;;      into cmp_operands[] but generates no RTL.
5394 ;;  2)  The appropriate branch define_expand is called, which then
5395 ;;      creates the appropriate RTL for the comparison and branch.
5396 ;;      Different CC modes are used, based on what type of branch is
5397 ;;      done, so that we can constrain things appropriately.  There
5398 ;;      are assumptions in the rest of GCC that break if we fold the
5399 ;;      operands into the branches for integer operations, and use cc0
5400 ;;      for floating point, so we use the fp status register instead.
5401 ;;      If needed, an appropriate temporary is created to hold the
5402 ;;      of the integer compare.
5404 (define_expand "cmpsi"
5405   [(set (cc0)
5406         (compare:CC (match_operand:SI 0 "register_operand")
5407                     (match_operand:SI 1 "nonmemory_operand")))]
5408   ""
5410   cmp_operands[0] = operands[0];
5411   cmp_operands[1] = operands[1];
5412   DONE;
5415 (define_expand "cmpdi"
5416   [(set (cc0)
5417         (compare:CC (match_operand:DI 0 "register_operand")
5418                     (match_operand:DI 1 "nonmemory_operand")))]
5419   "TARGET_64BIT"
5421   cmp_operands[0] = operands[0];
5422   cmp_operands[1] = operands[1];
5423   DONE;
5426 (define_expand "cmpdf"
5427   [(set (cc0)
5428         (compare:CC (match_operand:DF 0 "register_operand")
5429                     (match_operand:DF 1 "register_operand")))]
5430   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5432   cmp_operands[0] = operands[0];
5433   cmp_operands[1] = operands[1];
5434   DONE;
5437 (define_expand "cmpsf"
5438   [(set (cc0)
5439         (compare:CC (match_operand:SF 0 "register_operand")
5440                     (match_operand:SF 1 "register_operand")))]
5441   "TARGET_HARD_FLOAT"
5443   cmp_operands[0] = operands[0];
5444   cmp_operands[1] = operands[1];
5445   DONE;
5449 ;;  ....................
5451 ;;      CONDITIONAL BRANCHES
5453 ;;  ....................
5455 ;; Conditional branches on floating-point equality tests.
5457 (define_insn "branch_fp"
5458   [(set (pc)
5459         (if_then_else
5460          (match_operator:CC 0 "cmp_op"
5461                             [(match_operand:CC 2 "register_operand" "z")
5462                              (const_int 0)])
5463          (label_ref (match_operand 1 "" ""))
5464          (pc)))]
5465   "TARGET_HARD_FLOAT"
5467   return mips_output_conditional_branch (insn,
5468                                          operands,
5469                                          /*two_operands_p=*/0,
5470                                          /*float_p=*/1,
5471                                          /*inverted_p=*/0,
5472                                          get_attr_length (insn));
5474   [(set_attr "type"     "branch")
5475    (set_attr "mode"     "none")])
5477 (define_insn "branch_fp_inverted"
5478   [(set (pc)
5479         (if_then_else
5480          (match_operator:CC 0 "cmp_op"
5481                             [(match_operand:CC 2 "register_operand" "z")
5482                              (const_int 0)])
5483          (pc)
5484          (label_ref (match_operand 1 "" ""))))]
5485   "TARGET_HARD_FLOAT"
5487   return mips_output_conditional_branch (insn,
5488                                          operands,
5489                                          /*two_operands_p=*/0,
5490                                          /*float_p=*/1,
5491                                          /*inverted_p=*/1,
5492                                          get_attr_length (insn));
5494   [(set_attr "type"     "branch")
5495    (set_attr "mode"     "none")])
5497 ;; Conditional branches on comparisons with zero.
5499 (define_insn "branch_zero"
5500   [(set (pc)
5501         (if_then_else
5502          (match_operator:SI 0 "cmp_op"
5503                             [(match_operand:SI 2 "register_operand" "d")
5504                              (const_int 0)])
5505         (label_ref (match_operand 1 "" ""))
5506         (pc)))]
5507   "!TARGET_MIPS16"
5509   return mips_output_conditional_branch (insn,
5510                                          operands,
5511                                          /*two_operands_p=*/0,
5512                                          /*float_p=*/0,
5513                                          /*inverted_p=*/0,
5514                                          get_attr_length (insn));
5516   [(set_attr "type"     "branch")
5517    (set_attr "mode"     "none")])
5519 (define_insn "branch_zero_inverted"
5520   [(set (pc)
5521         (if_then_else
5522          (match_operator:SI 0 "cmp_op"
5523                             [(match_operand:SI 2 "register_operand" "d")
5524                              (const_int 0)])
5525         (pc)
5526         (label_ref (match_operand 1 "" ""))))]
5527   "!TARGET_MIPS16"
5529   return mips_output_conditional_branch (insn,
5530                                          operands,
5531                                          /*two_operands_p=*/0,
5532                                          /*float_p=*/0,
5533                                          /*inverted_p=*/1,
5534                                          get_attr_length (insn));
5536   [(set_attr "type"     "branch")
5537    (set_attr "mode"     "none")])
5539 (define_insn "branch_zero_di"
5540   [(set (pc)
5541         (if_then_else
5542          (match_operator:DI 0 "cmp_op"
5543                             [(match_operand:DI 2 "register_operand" "d")
5544                              (const_int 0)])
5545         (label_ref (match_operand 1 "" ""))
5546         (pc)))]
5547   "!TARGET_MIPS16"
5549   return mips_output_conditional_branch (insn,
5550                                          operands,
5551                                          /*two_operands_p=*/0,
5552                                          /*float_p=*/0,
5553                                          /*inverted_p=*/0,
5554                                          get_attr_length (insn));
5556   [(set_attr "type"     "branch")
5557    (set_attr "mode"     "none")])
5559 (define_insn "branch_zero_di_inverted"
5560   [(set (pc)
5561         (if_then_else
5562          (match_operator:DI 0 "cmp_op"
5563                             [(match_operand:DI 2 "register_operand" "d")
5564                              (const_int 0)])
5565         (pc)
5566         (label_ref (match_operand 1 "" ""))))]
5567   "!TARGET_MIPS16"
5569   return mips_output_conditional_branch (insn,
5570                                          operands,
5571                                          /*two_operands_p=*/0,
5572                                          /*float_p=*/0,
5573                                          /*inverted_p=*/1,
5574                                          get_attr_length (insn));
5576   [(set_attr "type"     "branch")
5577    (set_attr "mode"     "none")])
5579 ;; Conditional branch on equality comparison.
5581 (define_insn "branch_equality"
5582   [(set (pc)
5583         (if_then_else
5584          (match_operator:SI 0 "equality_op"
5585                             [(match_operand:SI 2 "register_operand" "d")
5586                              (match_operand:SI 3 "register_operand" "d")])
5587          (label_ref (match_operand 1 "" ""))
5588          (pc)))]
5589   "!TARGET_MIPS16"
5591   return mips_output_conditional_branch (insn,
5592                                          operands,
5593                                          /*two_operands_p=*/1,
5594                                          /*float_p=*/0,
5595                                          /*inverted_p=*/0,
5596                                          get_attr_length (insn));
5598   [(set_attr "type"     "branch")
5599    (set_attr "mode"     "none")])
5601 (define_insn "branch_equality_di"
5602   [(set (pc)
5603         (if_then_else
5604          (match_operator:DI 0 "equality_op"
5605                             [(match_operand:DI 2 "register_operand" "d")
5606                              (match_operand:DI 3 "register_operand" "d")])
5607         (label_ref (match_operand 1 "" ""))
5608         (pc)))]
5609   "!TARGET_MIPS16"
5611   return mips_output_conditional_branch (insn,
5612                                          operands,
5613                                          /*two_operands_p=*/1,
5614                                          /*float_p=*/0,
5615                                          /*inverted_p=*/0,
5616                                          get_attr_length (insn));
5618   [(set_attr "type"     "branch")
5619    (set_attr "mode"     "none")])
5621 (define_insn "branch_equality_inverted"
5622   [(set (pc)
5623         (if_then_else
5624          (match_operator:SI 0 "equality_op"
5625                             [(match_operand:SI 2 "register_operand" "d")
5626                              (match_operand:SI 3 "register_operand" "d")])
5627          (pc)
5628          (label_ref (match_operand 1 "" ""))))]
5629   "!TARGET_MIPS16"
5631   return mips_output_conditional_branch (insn,
5632                                          operands,
5633                                          /*two_operands_p=*/1,
5634                                          /*float_p=*/0,
5635                                          /*inverted_p=*/1,
5636                                          get_attr_length (insn));
5638   [(set_attr "type"     "branch")
5639    (set_attr "mode"     "none")])
5641 (define_insn "branch_equality_di_inverted"
5642   [(set (pc)
5643         (if_then_else
5644          (match_operator:DI 0 "equality_op"
5645                             [(match_operand:DI 2 "register_operand" "d")
5646                              (match_operand:DI 3 "register_operand" "d")])
5647         (pc)
5648         (label_ref (match_operand 1 "" ""))))]
5649   "!TARGET_MIPS16"
5651   return mips_output_conditional_branch (insn,
5652                                          operands,
5653                                          /*two_operands_p=*/1,
5654                                          /*float_p=*/0,
5655                                          /*inverted_p=*/1,
5656                                          get_attr_length (insn));
5658   [(set_attr "type"     "branch")
5659    (set_attr "mode"     "none")])
5661 ;; MIPS16 branches
5663 (define_insn ""
5664   [(set (pc)
5665         (if_then_else (match_operator:SI 0 "equality_op"
5666                                          [(match_operand:SI 1 "register_operand" "d,t")
5667                                           (const_int 0)])
5668         (match_operand 2 "pc_or_label_operand" "")
5669         (match_operand 3 "pc_or_label_operand" "")))]
5670   "TARGET_MIPS16"
5672   if (operands[2] != pc_rtx)
5673     {
5674       if (which_alternative == 0)
5675         return "b%C0z\t%1,%2";
5676       else
5677         return "bt%C0z\t%2";
5678     }
5679   else
5680     {
5681       if (which_alternative == 0)
5682         return "b%N0z\t%1,%3";
5683       else
5684         return "bt%N0z\t%3";
5685     }
5687   [(set_attr "type"     "branch")
5688    (set_attr "mode"     "none")
5689    (set_attr "length"   "8")])
5691 (define_insn ""
5692   [(set (pc)
5693         (if_then_else (match_operator:DI 0 "equality_op"
5694                                          [(match_operand:DI 1 "register_operand" "d,t")
5695                                           (const_int 0)])
5696         (match_operand 2 "pc_or_label_operand" "")
5697         (match_operand 3 "pc_or_label_operand" "")))]
5698   "TARGET_MIPS16"
5700   if (operands[2] != pc_rtx)
5701     {
5702       if (which_alternative == 0)
5703         return "b%C0z\t%1,%2";
5704       else
5705         return "bt%C0z\t%2";
5706     }
5707   else
5708     {
5709       if (which_alternative == 0)
5710         return "b%N0z\t%1,%3";
5711       else
5712         return "bt%N0z\t%3";
5713     }
5715   [(set_attr "type"     "branch")
5716    (set_attr "mode"     "none")
5717    (set_attr "length"   "8")])
5719 (define_expand "bunordered"
5720   [(set (pc)
5721         (if_then_else (unordered:CC (cc0)
5722                                     (const_int 0))
5723                       (label_ref (match_operand 0 ""))
5724                       (pc)))]
5725   ""
5727   gen_conditional_branch (operands, UNORDERED);
5728   DONE;
5731 (define_expand "bordered"
5732   [(set (pc)
5733         (if_then_else (ordered:CC (cc0)
5734                                   (const_int 0))
5735                       (label_ref (match_operand 0 ""))
5736                       (pc)))]
5737   ""
5739   gen_conditional_branch (operands, ORDERED);
5740   DONE;
5743 (define_expand "bunlt"
5744   [(set (pc)
5745         (if_then_else (unlt:CC (cc0)
5746                                (const_int 0))
5747                       (label_ref (match_operand 0 ""))
5748                       (pc)))]
5749   ""
5751   gen_conditional_branch (operands, UNLT);
5752   DONE;
5755 (define_expand "bunge"
5756   [(set (pc)
5757         (if_then_else (unge:CC (cc0)
5758                                (const_int 0))
5759                       (label_ref (match_operand 0 ""))
5760                       (pc)))]
5761   ""
5763   gen_conditional_branch (operands, UNGE);
5764   DONE;
5767 (define_expand "buneq"
5768   [(set (pc)
5769         (if_then_else (uneq:CC (cc0)
5770                                (const_int 0))
5771                       (label_ref (match_operand 0 ""))
5772                       (pc)))]
5773   ""
5775   gen_conditional_branch (operands, UNEQ);
5776   DONE;
5779 (define_expand "bltgt"
5780   [(set (pc)
5781         (if_then_else (ltgt:CC (cc0)
5782                                (const_int 0))
5783                       (label_ref (match_operand 0 ""))
5784                       (pc)))]
5785   ""
5787   gen_conditional_branch (operands, LTGT);
5788   DONE;
5791 (define_expand "bunle"
5792   [(set (pc)
5793         (if_then_else (unle:CC (cc0)
5794                                (const_int 0))
5795                       (label_ref (match_operand 0 ""))
5796                       (pc)))]
5797   ""
5799   gen_conditional_branch (operands, UNLE);
5800   DONE;
5803 (define_expand "bungt"
5804   [(set (pc)
5805         (if_then_else (ungt:CC (cc0)
5806                                (const_int 0))
5807                       (label_ref (match_operand 0 ""))
5808                       (pc)))]
5809   ""
5811   gen_conditional_branch (operands, UNGT);
5812   DONE;
5815 (define_expand "beq"
5816   [(set (pc)
5817         (if_then_else (eq:CC (cc0)
5818                              (const_int 0))
5819                       (label_ref (match_operand 0 ""))
5820                       (pc)))]
5821   ""
5823   gen_conditional_branch (operands, EQ);
5824   DONE;
5827 (define_expand "bne"
5828   [(set (pc)
5829         (if_then_else (ne:CC (cc0)
5830                              (const_int 0))
5831                       (label_ref (match_operand 0 ""))
5832                       (pc)))]
5833   ""
5835   gen_conditional_branch (operands, NE);
5836   DONE;
5839 (define_expand "bgt"
5840   [(set (pc)
5841         (if_then_else (gt:CC (cc0)
5842                              (const_int 0))
5843                       (label_ref (match_operand 0 ""))
5844                       (pc)))]
5845   ""
5847   gen_conditional_branch (operands, GT);
5848   DONE;
5851 (define_expand "bge"
5852   [(set (pc)
5853         (if_then_else (ge:CC (cc0)
5854                              (const_int 0))
5855                       (label_ref (match_operand 0 ""))
5856                       (pc)))]
5857   ""
5859   gen_conditional_branch (operands, GE);
5860   DONE;
5863 (define_expand "blt"
5864   [(set (pc)
5865         (if_then_else (lt:CC (cc0)
5866                              (const_int 0))
5867                       (label_ref (match_operand 0 ""))
5868                       (pc)))]
5869   ""
5871   gen_conditional_branch (operands, LT);
5872   DONE;
5875 (define_expand "ble"
5876   [(set (pc)
5877         (if_then_else (le:CC (cc0)
5878                              (const_int 0))
5879                       (label_ref (match_operand 0 ""))
5880                       (pc)))]
5881   ""
5883   gen_conditional_branch (operands, LE);
5884   DONE;
5887 (define_expand "bgtu"
5888   [(set (pc)
5889         (if_then_else (gtu:CC (cc0)
5890                               (const_int 0))
5891                       (label_ref (match_operand 0 ""))
5892                       (pc)))]
5893   ""
5895   gen_conditional_branch (operands, GTU);
5896   DONE;
5899 (define_expand "bgeu"
5900   [(set (pc)
5901         (if_then_else (geu:CC (cc0)
5902                               (const_int 0))
5903                       (label_ref (match_operand 0 ""))
5904                       (pc)))]
5905   ""
5907   gen_conditional_branch (operands, GEU);
5908   DONE;
5911 (define_expand "bltu"
5912   [(set (pc)
5913         (if_then_else (ltu:CC (cc0)
5914                               (const_int 0))
5915                       (label_ref (match_operand 0 ""))
5916                       (pc)))]
5917   ""
5919   gen_conditional_branch (operands, LTU);
5920   DONE;
5923 (define_expand "bleu"
5924   [(set (pc)
5925         (if_then_else (leu:CC (cc0)
5926                               (const_int 0))
5927                       (label_ref (match_operand 0 ""))
5928                       (pc)))]
5929   ""
5931   gen_conditional_branch (operands, LEU);
5932   DONE;
5936 ;;  ....................
5938 ;;      SETTING A REGISTER FROM A COMPARISON
5940 ;;  ....................
5942 (define_expand "seq"
5943   [(set (match_operand:SI 0 "register_operand")
5944         (eq:SI (match_dup 1)
5945                (match_dup 2)))]
5946   ""
5947   { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
5949 (define_insn "*seq_si"
5950   [(set (match_operand:SI 0 "register_operand" "=d")
5951         (eq:SI (match_operand:SI 1 "register_operand" "d")
5952                (const_int 0)))]
5953   "!TARGET_MIPS16"
5954   "sltu\t%0,%1,1"
5955   [(set_attr "type" "slt")
5956    (set_attr "mode" "SI")])
5958 (define_insn "*seq_si_mips16"
5959   [(set (match_operand:SI 0 "register_operand" "=t")
5960         (eq:SI (match_operand:SI 1 "register_operand" "d")
5961                (const_int 0)))]
5962   "TARGET_MIPS16"
5963   "sltu\t%1,1"
5964   [(set_attr "type" "slt")
5965    (set_attr "mode" "SI")])
5967 (define_insn "*seq_di"
5968   [(set (match_operand:DI 0 "register_operand" "=d")
5969         (eq:DI (match_operand:DI 1 "register_operand" "d")
5970                (const_int 0)))]
5971   "TARGET_64BIT && !TARGET_MIPS16"
5972   "sltu\t%0,%1,1"
5973   [(set_attr "type" "slt")
5974    (set_attr "mode" "DI")])
5976 (define_insn "*seq_di_mips16"
5977   [(set (match_operand:DI 0 "register_operand" "=t")
5978         (eq:DI (match_operand:DI 1 "register_operand" "d")
5979                (const_int 0)))]
5980   "TARGET_64BIT && TARGET_MIPS16"
5981   "sltu\t%1,1"
5982   [(set_attr "type" "slt")
5983    (set_attr "mode" "DI")])
5985 ;; "sne" uses sltu instructions in which the first operand is $0.
5986 ;; This isn't possible in mips16 code.
5988 (define_expand "sne"
5989   [(set (match_operand:SI 0 "register_operand")
5990         (ne:SI (match_dup 1)
5991                (match_dup 2)))]
5992   "!TARGET_MIPS16"
5993   { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
5995 (define_insn "*sne_si"
5996   [(set (match_operand:SI 0 "register_operand" "=d")
5997         (ne:SI (match_operand:SI 1 "register_operand" "d")
5998                (const_int 0)))]
5999   "!TARGET_MIPS16"
6000   "sltu\t%0,%.,%1"
6001   [(set_attr "type" "slt")
6002    (set_attr "mode" "SI")])
6004 (define_insn "*sne_di"
6005   [(set (match_operand:DI 0 "register_operand" "=d")
6006         (ne:DI (match_operand:DI 1 "register_operand" "d")
6007                (const_int 0)))]
6008   "TARGET_64BIT && !TARGET_MIPS16"
6009   "sltu\t%0,%.,%1"
6010   [(set_attr "type" "slt")
6011    (set_attr "mode" "DI")])
6013 (define_expand "sgt"
6014   [(set (match_operand:SI 0 "register_operand")
6015         (gt:SI (match_dup 1)
6016                (match_dup 2)))]
6017   ""
6018   { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
6020 (define_insn "*sgt_si"
6021   [(set (match_operand:SI 0 "register_operand" "=d")
6022         (gt:SI (match_operand:SI 1 "register_operand" "d")
6023                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6024   "!TARGET_MIPS16"
6025   "slt\t%0,%z2,%1"
6026   [(set_attr "type" "slt")
6027    (set_attr "mode" "SI")])
6029 (define_insn "*sgt_si_mips16"
6030   [(set (match_operand:SI 0 "register_operand" "=t")
6031         (gt:SI (match_operand:SI 1 "register_operand" "d")
6032                (match_operand:SI 2 "register_operand" "d")))]
6033   "TARGET_MIPS16"
6034   "slt\t%2,%1"
6035   [(set_attr "type" "slt")
6036    (set_attr "mode" "SI")])
6038 (define_insn "*sgt_di"
6039   [(set (match_operand:DI 0 "register_operand" "=d")
6040         (gt:DI (match_operand:DI 1 "register_operand" "d")
6041                (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6042   "TARGET_64BIT && !TARGET_MIPS16"
6043   "slt\t%0,%z2,%1"
6044   [(set_attr "type" "slt")
6045    (set_attr "mode" "DI")])
6047 (define_insn "*sgt_di_mips16"
6048   [(set (match_operand:DI 0 "register_operand" "=t")
6049         (gt:DI (match_operand:DI 1 "register_operand" "d")
6050                (match_operand:DI 2 "register_operand" "d")))]
6051   "TARGET_64BIT && TARGET_MIPS16"
6052   "slt\t%2,%1"
6053   [(set_attr "type" "slt")
6054    (set_attr "mode" "DI")])
6056 (define_expand "sge"
6057   [(set (match_operand:SI 0 "register_operand")
6058         (ge:SI (match_dup 1)
6059                (match_dup 2)))]
6060   ""
6061   { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
6063 (define_insn "*sge_si"
6064   [(set (match_operand:SI 0 "register_operand" "=d")
6065         (ge:SI (match_operand:SI 1 "register_operand" "d")
6066                (const_int 1)))]
6067   "!TARGET_MIPS16"
6068   "slt\t%0,%.,%1"
6069   [(set_attr "type" "slt")
6070    (set_attr "mode" "SI")])
6072 (define_insn "*sge_di"
6073   [(set (match_operand:DI 0 "register_operand" "=d")
6074         (ge:DI (match_operand:DI 1 "register_operand" "d")
6075                (const_int 1)))]
6076   "TARGET_64BIT && !TARGET_MIPS16"
6077   "slt\t%0,%.,%1"
6078   [(set_attr "type" "slt")
6079    (set_attr "mode" "DI")])
6081 (define_expand "slt"
6082   [(set (match_operand:SI 0 "register_operand")
6083         (lt:SI (match_dup 1)
6084                (match_dup 2)))]
6085   ""
6086   { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
6088 (define_insn "*slt_si"
6089   [(set (match_operand:SI 0 "register_operand" "=d")
6090         (lt:SI (match_operand:SI 1 "register_operand" "d")
6091                (match_operand:SI 2 "arith_operand" "dI")))]
6092   "!TARGET_MIPS16"
6093   "slt\t%0,%1,%2"
6094   [(set_attr "type" "slt")
6095    (set_attr "mode" "SI")])
6097 (define_insn "*slt_si_mips16"
6098   [(set (match_operand:SI 0 "register_operand" "=t,t")
6099         (lt:SI (match_operand:SI 1 "register_operand" "d,d")
6100                (match_operand:SI 2 "arith_operand" "d,I")))]
6101   "TARGET_MIPS16"
6102   "slt\t%1,%2"
6103   [(set_attr "type" "slt")
6104    (set_attr "mode" "SI")
6105    (set_attr_alternative "length"
6106                 [(const_int 4)
6107                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6108                                (const_int 4)
6109                                (const_int 8))])])
6111 (define_insn "*slt_di"
6112   [(set (match_operand:DI 0 "register_operand" "=d")
6113         (lt:DI (match_operand:DI 1 "register_operand" "d")
6114                (match_operand:DI 2 "arith_operand" "dI")))]
6115   "TARGET_64BIT && !TARGET_MIPS16"
6116   "slt\t%0,%1,%2"
6117   [(set_attr "type" "slt")
6118    (set_attr "mode" "DI")])
6120 (define_insn "*slt_di_mips16"
6121   [(set (match_operand:DI 0 "register_operand" "=t,t")
6122         (lt:DI (match_operand:DI 1 "register_operand" "d,d")
6123                (match_operand:DI 2 "arith_operand" "d,I")))]
6124   "TARGET_64BIT && TARGET_MIPS16"
6125   "slt\t%1,%2"
6126   [(set_attr "type" "slt")
6127    (set_attr "mode" "DI")
6128    (set_attr_alternative "length"
6129                 [(const_int 4)
6130                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6131                                (const_int 4)
6132                                (const_int 8))])])
6134 (define_expand "sle"
6135   [(set (match_operand:SI 0 "register_operand")
6136         (le:SI (match_dup 1)
6137                (match_dup 2)))]
6138   ""
6139   { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
6141 (define_insn "*sle_si"
6142   [(set (match_operand:SI 0 "register_operand" "=d")
6143         (le:SI (match_operand:SI 1 "register_operand" "d")
6144                (match_operand:SI 2 "sle_operand" "")))]
6145   "!TARGET_MIPS16"
6147   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6148   return "slt\t%0,%1,%2";
6150   [(set_attr "type" "slt")
6151    (set_attr "mode" "SI")])
6153 (define_insn "*sle_si_mips16"
6154   [(set (match_operand:SI 0 "register_operand" "=t")
6155         (le:SI (match_operand:SI 1 "register_operand" "d")
6156                (match_operand:SI 2 "sle_operand" "")))]
6157   "TARGET_MIPS16"
6159   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6160   return "slt\t%1,%2";
6162   [(set_attr "type" "slt")
6163    (set_attr "mode" "SI")
6164    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6165                                       (const_int 4)
6166                                       (const_int 8)))])
6168 (define_insn "*sle_di"
6169   [(set (match_operand:DI 0 "register_operand" "=d")
6170         (le:DI (match_operand:DI 1 "register_operand" "d")
6171                (match_operand:DI 2 "sle_operand" "")))]
6172   "TARGET_64BIT && !TARGET_MIPS16"
6174   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6175   return "slt\t%0,%1,%2";
6177   [(set_attr "type" "slt")
6178    (set_attr "mode" "DI")])
6180 (define_insn "*sle_di_mips16"
6181   [(set (match_operand:DI 0 "register_operand" "=t")
6182         (le:DI (match_operand:DI 1 "register_operand" "d")
6183                (match_operand:DI 2 "sle_operand" "")))]
6184   "TARGET_64BIT && TARGET_MIPS16"
6186   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6187   return "slt\t%1,%2";
6189   [(set_attr "type" "slt")
6190    (set_attr "mode" "DI")
6191    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6192                                       (const_int 4)
6193                                       (const_int 8)))])
6195 (define_expand "sgtu"
6196   [(set (match_operand:SI 0 "register_operand")
6197         (gtu:SI (match_dup 1)
6198                 (match_dup 2)))]
6199   ""
6200   { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
6202 (define_insn "*sgtu_si"
6203   [(set (match_operand:SI 0 "register_operand" "=d")
6204         (gtu:SI (match_operand:SI 1 "register_operand" "d")
6205                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6206   "!TARGET_MIPS16"
6207   "sltu\t%0,%z2,%1"
6208   [(set_attr "type" "slt")
6209    (set_attr "mode" "SI")])
6211 (define_insn "*sgtu_si_mips16"
6212   [(set (match_operand:SI 0 "register_operand" "=t")
6213         (gtu:SI (match_operand:SI 1 "register_operand" "d")
6214                 (match_operand:SI 2 "register_operand" "d")))]
6215   "TARGET_MIPS16"
6216   "sltu\t%2,%1"
6217   [(set_attr "type" "slt")
6218    (set_attr "mode" "SI")])
6220 (define_insn "*sgtu_di"
6221   [(set (match_operand:DI 0 "register_operand" "=d")
6222         (gtu:DI (match_operand:DI 1 "register_operand" "d")
6223                 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6224   "TARGET_64BIT && !TARGET_MIPS16"
6225   "sltu\t%0,%z2,%1"
6226   [(set_attr "type" "slt")
6227    (set_attr "mode" "DI")])
6229 (define_insn "*sgtu_di_mips16"
6230   [(set (match_operand:DI 0 "register_operand" "=t")
6231         (gtu:DI (match_operand:DI 1 "register_operand" "d")
6232                 (match_operand:DI 2 "register_operand" "d")))]
6233   "TARGET_64BIT && TARGET_MIPS16"
6234   "sltu\t%2,%1"
6235   [(set_attr "type" "slt")
6236    (set_attr "mode" "DI")])
6238 (define_expand "sgeu"
6239   [(set (match_operand:SI 0 "register_operand")
6240         (geu:SI (match_dup 1)
6241                 (match_dup 2)))]
6242   ""
6243   { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
6245 (define_insn "*sge_si"
6246   [(set (match_operand:SI 0 "register_operand" "=d")
6247         (geu:SI (match_operand:SI 1 "register_operand" "d")
6248                 (const_int 1)))]
6249   "!TARGET_MIPS16"
6250   "sltu\t%0,%.,%1"
6251   [(set_attr "type" "slt")
6252    (set_attr "mode" "SI")])
6254 (define_insn "*sge_di"
6255   [(set (match_operand:DI 0 "register_operand" "=d")
6256         (geu:DI (match_operand:DI 1 "register_operand" "d")
6257                 (const_int 1)))]
6258   "TARGET_64BIT && !TARGET_MIPS16"
6259   "sltu\t%0,%.,%1"
6260   [(set_attr "type" "slt")
6261    (set_attr "mode" "DI")])
6263 (define_expand "sltu"
6264   [(set (match_operand:SI 0 "register_operand")
6265         (ltu:SI (match_dup 1)
6266                 (match_dup 2)))]
6267   ""
6268   { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
6270 (define_insn "*sltu_si"
6271   [(set (match_operand:SI 0 "register_operand" "=d")
6272         (ltu:SI (match_operand:SI 1 "register_operand" "d")
6273                 (match_operand:SI 2 "arith_operand" "dI")))]
6274   "!TARGET_MIPS16"
6275   "sltu\t%0,%1,%2"
6276   [(set_attr "type" "slt")
6277    (set_attr "mode" "SI")])
6279 (define_insn "*sltu_si_mips16"
6280   [(set (match_operand:SI 0 "register_operand" "=t,t")
6281         (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
6282                 (match_operand:SI 2 "arith_operand" "d,I")))]
6283   "TARGET_MIPS16"
6284   "sltu\t%1,%2"
6285   [(set_attr "type" "slt")
6286    (set_attr "mode" "SI")
6287    (set_attr_alternative "length"
6288                 [(const_int 4)
6289                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6290                                (const_int 4)
6291                                (const_int 8))])])
6293 (define_insn "*sltu_di"
6294   [(set (match_operand:DI 0 "register_operand" "=d")
6295         (ltu:DI (match_operand:DI 1 "register_operand" "d")
6296                 (match_operand:DI 2 "arith_operand" "dI")))]
6297   "TARGET_64BIT && !TARGET_MIPS16"
6298   "sltu\t%0,%1,%2"
6299   [(set_attr "type" "slt")
6300    (set_attr "mode" "DI")])
6302 (define_insn "*sltu_di_mips16"
6303   [(set (match_operand:DI 0 "register_operand" "=t,t")
6304         (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
6305                 (match_operand:DI 2 "arith_operand" "d,I")))]
6306   "TARGET_64BIT && TARGET_MIPS16"
6307   "sltu\t%1,%2"
6308   [(set_attr "type" "slt")
6309    (set_attr "mode" "DI")
6310    (set_attr_alternative "length"
6311                 [(const_int 4)
6312                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6313                                (const_int 4)
6314                                (const_int 8))])])
6316 (define_expand "sleu"
6317   [(set (match_operand:SI 0 "register_operand")
6318         (leu:SI (match_dup 1)
6319                 (match_dup 2)))]
6320   ""
6321   { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
6323 (define_insn "*sleu_si"
6324   [(set (match_operand:SI 0 "register_operand" "=d")
6325         (leu:SI (match_operand:SI 1 "register_operand" "d")
6326                 (match_operand:SI 2 "sleu_operand" "")))]
6327   "!TARGET_MIPS16"
6329   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6330   return "sltu\t%0,%1,%2";
6332   [(set_attr "type" "slt")
6333    (set_attr "mode" "SI")])
6335 (define_insn "*sleu_si_mips16"
6336   [(set (match_operand:SI 0 "register_operand" "=t")
6337         (leu:SI (match_operand:SI 1 "register_operand" "d")
6338                 (match_operand:SI 2 "sleu_operand" "")))]
6339   "TARGET_MIPS16"
6341   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6342   return "sltu\t%1,%2";
6344   [(set_attr "type" "slt")
6345    (set_attr "mode" "SI")
6346    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6347                                       (const_int 4)
6348                                       (const_int 8)))])
6350 (define_insn "*sleu_di"
6351   [(set (match_operand:DI 0 "register_operand" "=d")
6352         (leu:DI (match_operand:DI 1 "register_operand" "d")
6353                 (match_operand:DI 2 "sleu_operand" "")))]
6354   "TARGET_64BIT && !TARGET_MIPS16"
6356   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6357   return "sltu\t%0,%1,%2";
6359   [(set_attr "type" "slt")
6360    (set_attr "mode" "DI")])
6362 (define_insn "*sleu_di_mips16"
6363   [(set (match_operand:DI 0 "register_operand" "=t")
6364         (leu:DI (match_operand:DI 1 "register_operand" "d")
6365                 (match_operand:DI 2 "sleu_operand" "")))]
6366   "TARGET_64BIT && TARGET_MIPS16"
6368   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6369   return "sltu\t%1,%2";
6371   [(set_attr "type" "slt")
6372    (set_attr "mode" "DI")
6373    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6374                                       (const_int 4)
6375                                       (const_int 8)))])
6378 ;;  ....................
6380 ;;      FLOATING POINT COMPARISONS
6382 ;;  ....................
6384 (define_insn "sunordered_df"
6385   [(set (match_operand:CC 0 "register_operand" "=z")
6386         (unordered:CC (match_operand:DF 1 "register_operand" "f")
6387                       (match_operand:DF 2 "register_operand" "f")))]
6388   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6389   "c.un.d\t%Z0%1,%2"
6390   [(set_attr "type" "fcmp")
6391    (set_attr "mode" "FPSW")])
6393 (define_insn "sunlt_df"
6394   [(set (match_operand:CC 0 "register_operand" "=z")
6395         (unlt:CC (match_operand:DF 1 "register_operand" "f")
6396                  (match_operand:DF 2 "register_operand" "f")))]
6397   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6398   "c.ult.d\t%Z0%1,%2"
6399   [(set_attr "type" "fcmp")
6400    (set_attr "mode" "FPSW")])
6402 (define_insn "suneq_df"
6403   [(set (match_operand:CC 0 "register_operand" "=z")
6404         (uneq:CC (match_operand:DF 1 "register_operand" "f")
6405                  (match_operand:DF 2 "register_operand" "f")))]
6406   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6407   "c.ueq.d\t%Z0%1,%2"
6408   [(set_attr "type" "fcmp")
6409    (set_attr "mode" "FPSW")])
6411 (define_insn "sunle_df"
6412   [(set (match_operand:CC 0 "register_operand" "=z")
6413         (unle:CC (match_operand:DF 1 "register_operand" "f")
6414                  (match_operand:DF 2 "register_operand" "f")))]
6415   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6416   "c.ule.d\t%Z0%1,%2"
6417   [(set_attr "type" "fcmp")
6418    (set_attr "mode" "FPSW")])
6420 (define_insn "seq_df"
6421   [(set (match_operand:CC 0 "register_operand" "=z")
6422         (eq:CC (match_operand:DF 1 "register_operand" "f")
6423                (match_operand:DF 2 "register_operand" "f")))]
6424   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6425   "c.eq.d\t%Z0%1,%2"
6426   [(set_attr "type" "fcmp")
6427    (set_attr "mode" "FPSW")])
6429 (define_insn "slt_df"
6430   [(set (match_operand:CC 0 "register_operand" "=z")
6431         (lt:CC (match_operand:DF 1 "register_operand" "f")
6432                (match_operand:DF 2 "register_operand" "f")))]
6433   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6434   "c.lt.d\t%Z0%1,%2"
6435   [(set_attr "type" "fcmp")
6436    (set_attr "mode" "FPSW")])
6438 (define_insn "sle_df"
6439   [(set (match_operand:CC 0 "register_operand" "=z")
6440         (le:CC (match_operand:DF 1 "register_operand" "f")
6441                (match_operand:DF 2 "register_operand" "f")))]
6442   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6443   "c.le.d\t%Z0%1,%2"
6444   [(set_attr "type" "fcmp")
6445    (set_attr "mode" "FPSW")])
6447 (define_insn "sgt_df"
6448   [(set (match_operand:CC 0 "register_operand" "=z")
6449         (gt:CC (match_operand:DF 1 "register_operand" "f")
6450                (match_operand:DF 2 "register_operand" "f")))]
6451   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6452   "c.lt.d\t%Z0%2,%1"
6453   [(set_attr "type" "fcmp")
6454    (set_attr "mode" "FPSW")])
6456 (define_insn "sge_df"
6457   [(set (match_operand:CC 0 "register_operand" "=z")
6458         (ge:CC (match_operand:DF 1 "register_operand" "f")
6459                (match_operand:DF 2 "register_operand" "f")))]
6460   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6461   "c.le.d\t%Z0%2,%1"
6462   [(set_attr "type" "fcmp")
6463    (set_attr "mode" "FPSW")])
6465 (define_insn "sunordered_sf"
6466   [(set (match_operand:CC 0 "register_operand" "=z")
6467         (unordered:CC (match_operand:SF 1 "register_operand" "f")
6468                       (match_operand:SF 2 "register_operand" "f")))]
6469   "TARGET_HARD_FLOAT"
6470   "c.un.s\t%Z0%1,%2"
6471   [(set_attr "type" "fcmp")
6472    (set_attr "mode" "FPSW")])
6474 (define_insn "sunlt_sf"
6475   [(set (match_operand:CC 0 "register_operand" "=z")
6476         (unlt:CC (match_operand:SF 1 "register_operand" "f")
6477                  (match_operand:SF 2 "register_operand" "f")))]
6478   "TARGET_HARD_FLOAT"
6479   "c.ult.s\t%Z0%1,%2"
6480   [(set_attr "type" "fcmp")
6481    (set_attr "mode" "FPSW")])
6483 (define_insn "suneq_sf"
6484   [(set (match_operand:CC 0 "register_operand" "=z")
6485         (uneq:CC (match_operand:SF 1 "register_operand" "f")
6486                  (match_operand:SF 2 "register_operand" "f")))]
6487   "TARGET_HARD_FLOAT"
6488   "c.ueq.s\t%Z0%1,%2"
6489   [(set_attr "type" "fcmp")
6490    (set_attr "mode" "FPSW")])
6492 (define_insn "sunle_sf"
6493   [(set (match_operand:CC 0 "register_operand" "=z")
6494         (unle:CC (match_operand:SF 1 "register_operand" "f")
6495                  (match_operand:SF 2 "register_operand" "f")))]
6496   "TARGET_HARD_FLOAT"
6497   "c.ule.s\t%Z0%1,%2"
6498   [(set_attr "type" "fcmp")
6499    (set_attr "mode" "FPSW")])
6501 (define_insn "seq_sf"
6502   [(set (match_operand:CC 0 "register_operand" "=z")
6503         (eq:CC (match_operand:SF 1 "register_operand" "f")
6504                (match_operand:SF 2 "register_operand" "f")))]
6505   "TARGET_HARD_FLOAT"
6506   "c.eq.s\t%Z0%1,%2"
6507   [(set_attr "type" "fcmp")
6508    (set_attr "mode" "FPSW")])
6510 (define_insn "slt_sf"
6511   [(set (match_operand:CC 0 "register_operand" "=z")
6512         (lt:CC (match_operand:SF 1 "register_operand" "f")
6513                (match_operand:SF 2 "register_operand" "f")))]
6514   "TARGET_HARD_FLOAT"
6515   "c.lt.s\t%Z0%1,%2"
6516   [(set_attr "type" "fcmp")
6517    (set_attr "mode" "FPSW")])
6519 (define_insn "sle_sf"
6520   [(set (match_operand:CC 0 "register_operand" "=z")
6521         (le:CC (match_operand:SF 1 "register_operand" "f")
6522                (match_operand:SF 2 "register_operand" "f")))]
6523   "TARGET_HARD_FLOAT"
6524   "c.le.s\t%Z0%1,%2"
6525   [(set_attr "type" "fcmp")
6526    (set_attr "mode" "FPSW")])
6528 (define_insn "sgt_sf"
6529   [(set (match_operand:CC 0 "register_operand" "=z")
6530         (gt:CC (match_operand:SF 1 "register_operand" "f")
6531                (match_operand:SF 2 "register_operand" "f")))]
6532   "TARGET_HARD_FLOAT"
6533   "c.lt.s\t%Z0%2,%1"
6534   [(set_attr "type" "fcmp")
6535    (set_attr "mode" "FPSW")])
6537 (define_insn "sge_sf"
6538   [(set (match_operand:CC 0 "register_operand" "=z")
6539         (ge:CC (match_operand:SF 1 "register_operand" "f")
6540                (match_operand:SF 2 "register_operand" "f")))]
6541   "TARGET_HARD_FLOAT"
6542   "c.le.s\t%Z0%2,%1"
6543   [(set_attr "type" "fcmp")
6544    (set_attr "mode" "FPSW")])
6547 ;;  ....................
6549 ;;      UNCONDITIONAL BRANCHES
6551 ;;  ....................
6553 ;; Unconditional branches.
6555 (define_insn "jump"
6556   [(set (pc)
6557         (label_ref (match_operand 0 "" "")))]
6558   "!TARGET_MIPS16"
6560   if (flag_pic)
6561     {
6562       if (get_attr_length (insn) <= 8)
6563         return "%*b\t%l0%/";
6564       else
6565         {
6566           output_asm_insn (mips_output_load_label (), operands);
6567           return "%*jr\t%@%/%]";
6568         }
6569     }
6570   else
6571     return "%*j\t%l0%/";
6573   [(set_attr "type"     "jump")
6574    (set_attr "mode"     "none")
6575    (set (attr "length")
6576         ;; We can't use `j' when emitting PIC.  Emit a branch if it's
6577         ;; in range, otherwise load the address of the branch target into
6578         ;; $at and then jump to it.
6579         (if_then_else
6580          (ior (eq (symbol_ref "flag_pic") (const_int 0))
6581               (lt (abs (minus (match_dup 0)
6582                               (plus (pc) (const_int 4))))
6583                   (const_int 131072)))
6584          (const_int 4) (const_int 16)))])
6586 ;; We need a different insn for the mips16, because a mips16 branch
6587 ;; does not have a delay slot.
6589 (define_insn ""
6590   [(set (pc)
6591         (label_ref (match_operand 0 "" "")))]
6592   "TARGET_MIPS16"
6593   "b\t%l0"
6594   [(set_attr "type"     "branch")
6595    (set_attr "mode"     "none")
6596    (set_attr "length"   "8")])
6598 (define_expand "indirect_jump"
6599   [(set (pc) (match_operand 0 "register_operand"))]
6600   ""
6602   rtx dest;
6604   dest = operands[0];
6605   if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
6606     operands[0] = copy_to_mode_reg (Pmode, dest);
6608   if (!(Pmode == DImode))
6609     emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
6610   else
6611     emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
6613   DONE;
6616 (define_insn "indirect_jump_internal1"
6617   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
6618   "!(Pmode == DImode)"
6619   "%*j\t%0%/"
6620   [(set_attr "type"     "jump")
6621    (set_attr "mode"     "none")])
6623 (define_insn "indirect_jump_internal2"
6624   [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
6625   "Pmode == DImode"
6626   "%*j\t%0%/"
6627   [(set_attr "type"     "jump")
6628    (set_attr "mode"     "none")])
6630 (define_expand "tablejump"
6631   [(set (pc)
6632         (match_operand 0 "register_operand"))
6633    (use (label_ref (match_operand 1 "")))]
6634   ""
6636   if (TARGET_MIPS16)
6637     {
6638       if (GET_MODE (operands[0]) != HImode)
6639         abort ();
6640       if (!(Pmode == DImode))
6641         emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
6642       else
6643         emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
6644       DONE;
6645     }
6647   if (GET_MODE (operands[0]) != ptr_mode)
6648     abort ();
6650   if (TARGET_GPWORD)
6651     operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
6652                                 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
6654   if (Pmode == SImode)
6655     emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
6656   else
6657     emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
6658   DONE;
6661 (define_insn "tablejump_internal1"
6662   [(set (pc)
6663         (match_operand:SI 0 "register_operand" "d"))
6664    (use (label_ref (match_operand 1 "" "")))]
6665   ""
6666   "%*j\t%0%/"
6667   [(set_attr "type"     "jump")
6668    (set_attr "mode"     "none")])
6670 (define_insn "tablejump_internal2"
6671   [(set (pc)
6672         (match_operand:DI 0 "register_operand" "d"))
6673    (use (label_ref (match_operand 1 "" "")))]
6674   "TARGET_64BIT"
6675   "%*j\t%0%/"
6676   [(set_attr "type"     "jump")
6677    (set_attr "mode"     "none")])
6679 (define_expand "tablejump_mips161"
6680   [(set (pc) (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand"))
6681                       (label_ref:SI (match_operand 1 ""))))]
6682   "TARGET_MIPS16 && !(Pmode == DImode)"
6684   rtx t1, t2, t3;
6686   t1 = gen_reg_rtx (SImode);
6687   t2 = gen_reg_rtx (SImode);
6688   t3 = gen_reg_rtx (SImode);
6689   emit_insn (gen_extendhisi2 (t1, operands[0]));
6690   emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
6691   emit_insn (gen_addsi3 (t3, t1, t2));
6692   emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
6693   DONE;
6696 (define_expand "tablejump_mips162"
6697   [(set (pc) (plus:DI (sign_extend:DI (match_operand:HI 0 "register_operand"))
6698                       (label_ref:DI (match_operand 1 ""))))]
6699   "TARGET_MIPS16 && Pmode == DImode"
6701   rtx t1, t2, t3;
6703   t1 = gen_reg_rtx (DImode);
6704   t2 = gen_reg_rtx (DImode);
6705   t3 = gen_reg_rtx (DImode);
6706   emit_insn (gen_extendhidi2 (t1, operands[0]));
6707   emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
6708   emit_insn (gen_adddi3 (t3, t1, t2));
6709   emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
6710   DONE;
6713 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
6714 ;; While it is possible to either pull it off the stack (in the
6715 ;; o32 case) or recalculate it given t9 and our target label,
6716 ;; it takes 3 or 4 insns to do so.
6718 (define_expand "builtin_setjmp_setup"
6719   [(use (match_operand 0 "register_operand"))]
6720   "TARGET_ABICALLS"
6722   rtx addr;
6724   addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
6725   emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
6726   DONE;
6729 ;; Restore the gp that we saved above.  Despite the earlier comment, it seems
6730 ;; that older code did recalculate the gp from $25.  Continue to jump through
6731 ;; $25 for compatibility (we lose nothing by doing so).
6733 (define_expand "builtin_longjmp"
6734   [(use (match_operand 0 "register_operand"))]
6735   "TARGET_ABICALLS"
6737   /* The elements of the buffer are, in order:  */
6738   int W = GET_MODE_SIZE (Pmode);
6739   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6740   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
6741   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
6742   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
6743   rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6744   /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
6745      The target is bound to be using $28 as the global pointer
6746      but the current function might not be.  */
6747   rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
6749   /* This bit is similar to expand_builtin_longjmp except that it
6750      restores $gp as well.  */
6751   emit_move_insn (hard_frame_pointer_rtx, fp);
6752   emit_move_insn (pv, lab);
6753   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6754   emit_move_insn (gp, gpv);
6755   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6756   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6757   emit_insn (gen_rtx_USE (VOIDmode, gp));
6758   emit_indirect_jump (pv);
6759   DONE;
6763 ;;  ....................
6765 ;;      Function prologue/epilogue
6767 ;;  ....................
6770 (define_expand "prologue"
6771   [(const_int 1)]
6772   ""
6774   mips_expand_prologue ();
6775   DONE;
6778 ;; Block any insns from being moved before this point, since the
6779 ;; profiling call to mcount can use various registers that aren't
6780 ;; saved or used to pass arguments.
6782 (define_insn "blockage"
6783   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
6784   ""
6785   ""
6786   [(set_attr "type"     "unknown")
6787    (set_attr "mode"     "none")
6788    (set_attr "length"   "0")])
6790 (define_expand "epilogue"
6791   [(const_int 2)]
6792   ""
6794   mips_expand_epilogue (false);
6795   DONE;
6798 (define_expand "sibcall_epilogue"
6799   [(const_int 2)]
6800   ""
6802   mips_expand_epilogue (true);
6803   DONE;
6806 ;; Trivial return.  Make it look like a normal return insn as that
6807 ;; allows jump optimizations to work better.
6809 (define_insn "return"
6810   [(return)]
6811   "mips_can_use_return_insn ()"
6812   "%*j\t$31%/"
6813   [(set_attr "type"     "jump")
6814    (set_attr "mode"     "none")])
6816 ;; Normal return.
6818 (define_insn "return_internal"
6819   [(return)
6820    (use (match_operand 0 "pmode_register_operand" ""))]
6821   ""
6822   "%*j\t%0%/"
6823   [(set_attr "type"     "jump")
6824    (set_attr "mode"     "none")])
6826 ;; This is used in compiling the unwind routines.
6827 (define_expand "eh_return"
6828   [(use (match_operand 0 "general_operand"))]
6829   ""
6831   enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
6833   if (GET_MODE (operands[0]) != gpr_mode)
6834     operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
6835   if (TARGET_64BIT)
6836     emit_insn (gen_eh_set_lr_di (operands[0]));
6837   else
6838     emit_insn (gen_eh_set_lr_si (operands[0]));
6840   DONE;
6843 ;; Clobber the return address on the stack.  We can't expand this
6844 ;; until we know where it will be put in the stack frame.
6846 (define_insn "eh_set_lr_si"
6847   [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6848    (clobber (match_scratch:SI 1 "=&d"))]
6849   "! TARGET_64BIT"
6850   "#")
6852 (define_insn "eh_set_lr_di"
6853   [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6854    (clobber (match_scratch:DI 1 "=&d"))]
6855   "TARGET_64BIT"
6856   "#")
6858 (define_split
6859   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6860    (clobber (match_scratch 1))]
6861   "reload_completed && !TARGET_DEBUG_D_MODE"
6862   [(const_int 0)]
6864   mips_set_return_address (operands[0], operands[1]);
6865   DONE;
6868 (define_insn_and_split "exception_receiver"
6869   [(set (reg:SI 28)
6870         (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
6871   "TARGET_ABICALLS && TARGET_OLDABI"
6872   "#"
6873   "&& reload_completed"
6874   [(const_int 0)]
6876   mips_restore_gp ();
6877   DONE;
6879   [(set_attr "type"   "load")
6880    (set_attr "length" "12")])
6883 ;;  ....................
6885 ;;      FUNCTION CALLS
6887 ;;  ....................
6889 ;; Instructions to load a call address from the GOT.  The address might
6890 ;; point to a function or to a lazy binding stub.  In the latter case,
6891 ;; the stub will use the dynamic linker to resolve the function, which
6892 ;; in turn will change the GOT entry to point to the function's real
6893 ;; address.
6895 ;; This means that every call, even pure and constant ones, can
6896 ;; potentially modify the GOT entry.  And once a stub has been called,
6897 ;; we must not call it again.
6899 ;; We represent this restriction using an imaginary fixed register that
6900 ;; acts like a GOT version number.  By making the register call-clobbered,
6901 ;; we tell the target-independent code that the address could be changed
6902 ;; by any call insn.
6903 (define_insn "load_callsi"
6904   [(set (match_operand:SI 0 "register_operand" "=c")
6905         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6906                     (match_operand:SI 2 "immediate_operand" "")
6907                     (reg:SI FAKE_CALL_REGNO)]
6908                    UNSPEC_LOAD_CALL))]
6909   "TARGET_ABICALLS"
6910   "lw\t%0,%R2(%1)"
6911   [(set_attr "type" "load")
6912    (set_attr "length" "4")])
6914 (define_insn "load_calldi"
6915   [(set (match_operand:DI 0 "register_operand" "=c")
6916         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
6917                     (match_operand:DI 2 "immediate_operand" "")
6918                     (reg:DI FAKE_CALL_REGNO)]
6919                    UNSPEC_LOAD_CALL))]
6920   "TARGET_ABICALLS"
6921   "ld\t%0,%R2(%1)"
6922   [(set_attr "type" "load")
6923    (set_attr "length" "4")])
6925 ;; Sibling calls.  All these patterns use jump instructions.
6927 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
6928 ;; addresses if a direct jump is acceptable.  Since the 'S' constraint
6929 ;; is defined in terms of call_insn_operand, the same is true of the
6930 ;; constraints.
6932 ;; When we use an indirect jump, we need a register that will be
6933 ;; preserved by the epilogue.  Since TARGET_ABICALLS forces us to
6934 ;; use $25 for this purpose -- and $25 is never clobbered by the
6935 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
6937 (define_expand "sibcall"
6938   [(parallel [(call (match_operand 0 "")
6939                     (match_operand 1 ""))
6940               (use (match_operand 2 ""))        ;; next_arg_reg
6941               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
6942   "TARGET_SIBCALLS"
6944   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
6945   DONE;
6948 (define_insn "sibcall_internal"
6949   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
6950          (match_operand 1 "" ""))]
6951   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6952   "@
6953     %*jr\t%0%/
6954     %*j\t%0%/"
6955   [(set_attr "type" "call")])
6957 (define_expand "sibcall_value"
6958   [(parallel [(set (match_operand 0 "")
6959                    (call (match_operand 1 "")
6960                          (match_operand 2 "")))
6961               (use (match_operand 3 ""))])]             ;; next_arg_reg
6962   "TARGET_SIBCALLS"
6964   mips_expand_call (operands[0], XEXP (operands[1], 0),
6965                     operands[2], operands[3], true);
6966   DONE;
6969 (define_insn "sibcall_value_internal"
6970   [(set (match_operand 0 "register_operand" "=df,df")
6971         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6972               (match_operand 2 "" "")))]
6973   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6974   "@
6975     %*jr\t%1%/
6976     %*j\t%1%/"
6977   [(set_attr "type" "call")])
6979 (define_insn "sibcall_value_multiple_internal"
6980   [(set (match_operand 0 "register_operand" "=df,df")
6981         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6982               (match_operand 2 "" "")))
6983    (set (match_operand 3 "register_operand" "=df,df")
6984         (call (mem:SI (match_dup 1))
6985               (match_dup 2)))]
6986   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6987   "@
6988     %*jr\t%1%/
6989     %*j\t%1%/"
6990   [(set_attr "type" "call")])
6992 (define_expand "call"
6993   [(parallel [(call (match_operand 0 "")
6994                     (match_operand 1 ""))
6995               (use (match_operand 2 ""))        ;; next_arg_reg
6996               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
6997   ""
6999   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
7000   DONE;
7003 ;; This instruction directly corresponds to an assembly-language "jal".
7004 ;; There are four cases:
7006 ;;    - -mno-abicalls:
7007 ;;        Both symbolic and register destinations are OK.  The pattern
7008 ;;        always expands to a single mips instruction.
7010 ;;    - -mabicalls/-mno-explicit-relocs:
7011 ;;        Again, both symbolic and register destinations are OK.
7012 ;;        The call is treated as a multi-instruction black box.
7014 ;;    - -mabicalls/-mexplicit-relocs with n32 or n64:
7015 ;;        Only "jal $25" is allowed.  This expands to a single "jalr $25"
7016 ;;        instruction.
7018 ;;    - -mabicalls/-mexplicit-relocs with o32 or o64:
7019 ;;        Only "jal $25" is allowed.  The call is actually two instructions:
7020 ;;        "jalr $25" followed by an insn to reload $gp.
7022 ;; In the last case, we can generate the individual instructions with
7023 ;; a define_split.  There are several things to be wary of:
7025 ;;   - We can't expose the load of $gp before reload.  If we did,
7026 ;;     it might get removed as dead, but reload can introduce new
7027 ;;     uses of $gp by rematerializing constants.
7029 ;;   - We shouldn't restore $gp after calls that never return.
7030 ;;     It isn't valid to insert instructions between a noreturn
7031 ;;     call and the following barrier.
7033 ;;   - The splitter deliberately changes the liveness of $gp.  The unsplit
7034 ;;     instruction preserves $gp and so have no effect on its liveness.
7035 ;;     But once we generate the separate insns, it becomes obvious that
7036 ;;     $gp is not live on entry to the call.
7038 ;; ??? The operands[2] = insn check is a hack to make the original insn
7039 ;; available to the splitter.
7040 (define_insn_and_split "call_internal"
7041   [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
7042          (match_operand 1 "" ""))
7043    (clobber (reg:SI 31))]
7044   ""
7045   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
7046   "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
7047   [(const_int 0)]
7049   emit_call_insn (gen_call_split (operands[0], operands[1]));
7050   if (!find_reg_note (operands[2], REG_NORETURN, 0))
7051     mips_restore_gp ();
7052   DONE;
7054   [(set_attr "jal" "indirect,direct")
7055    (set_attr "extended_mips16" "no,yes")])
7057 (define_insn "call_split"
7058   [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
7059          (match_operand 1 "" ""))
7060    (clobber (reg:SI 31))
7061    (clobber (reg:SI 28))]
7062   "TARGET_SPLIT_CALLS"
7063   "%*jalr\t%0%/"
7064   [(set_attr "type" "call")])
7066 (define_expand "call_value"
7067   [(parallel [(set (match_operand 0 "")
7068                    (call (match_operand 1 "")
7069                          (match_operand 2 "")))
7070               (use (match_operand 3 ""))])]             ;; next_arg_reg
7071   ""
7073   mips_expand_call (operands[0], XEXP (operands[1], 0),
7074                     operands[2], operands[3], false);
7075   DONE;
7078 ;; See comment for call_internal.
7079 (define_insn_and_split "call_value_internal"
7080   [(set (match_operand 0 "register_operand" "=df,df")
7081         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7082               (match_operand 2 "" "")))
7083    (clobber (reg:SI 31))]
7084   ""
7085   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7086   "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
7087   [(const_int 0)]
7089   emit_call_insn (gen_call_value_split (operands[0], operands[1],
7090                                         operands[2]));
7091   if (!find_reg_note (operands[3], REG_NORETURN, 0))
7092     mips_restore_gp ();
7093   DONE;
7095   [(set_attr "jal" "indirect,direct")
7096    (set_attr "extended_mips16" "no,yes")])
7098 (define_insn "call_value_split"
7099   [(set (match_operand 0 "register_operand" "=df")
7100         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7101               (match_operand 2 "" "")))
7102    (clobber (reg:SI 31))
7103    (clobber (reg:SI 28))]
7104   "TARGET_SPLIT_CALLS"
7105   "%*jalr\t%1%/"
7106   [(set_attr "type" "call")])
7108 ;; See comment for call_internal.
7109 (define_insn_and_split "call_value_multiple_internal"
7110   [(set (match_operand 0 "register_operand" "=df,df")
7111         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7112               (match_operand 2 "" "")))
7113    (set (match_operand 3 "register_operand" "=df,df")
7114         (call (mem:SI (match_dup 1))
7115               (match_dup 2)))
7116    (clobber (reg:SI 31))]
7117   ""
7118   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7119   "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
7120   [(const_int 0)]
7122   emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
7123                                                  operands[2], operands[3]));
7124   if (!find_reg_note (operands[4], REG_NORETURN, 0))
7125     mips_restore_gp ();
7126   DONE;
7128   [(set_attr "jal" "indirect,direct")
7129    (set_attr "extended_mips16" "no,yes")])
7131 (define_insn "call_value_multiple_split"
7132   [(set (match_operand 0 "register_operand" "=df")
7133         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7134               (match_operand 2 "" "")))
7135    (set (match_operand 3 "register_operand" "=df")
7136         (call (mem:SI (match_dup 1))
7137               (match_dup 2)))
7138    (clobber (reg:SI 31))
7139    (clobber (reg:SI 28))]
7140   "TARGET_SPLIT_CALLS"
7141   "%*jalr\t%1%/"
7142   [(set_attr "type" "call")])
7144 ;; Call subroutine returning any type.
7146 (define_expand "untyped_call"
7147   [(parallel [(call (match_operand 0 "")
7148                     (const_int 0))
7149               (match_operand 1 "")
7150               (match_operand 2 "")])]
7151   ""
7153   int i;
7155   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
7157   for (i = 0; i < XVECLEN (operands[2], 0); i++)
7158     {
7159       rtx set = XVECEXP (operands[2], 0, i);
7160       emit_move_insn (SET_DEST (set), SET_SRC (set));
7161     }
7163   emit_insn (gen_blockage ());
7164   DONE;
7168 ;;  ....................
7170 ;;      MISC.
7172 ;;  ....................
7176 (define_expand "prefetch"
7177   [(prefetch (match_operand 0 "address_operand")
7178              (match_operand 1 "const_int_operand")
7179              (match_operand 2 "const_int_operand"))]
7180   "ISA_HAS_PREFETCH"
7182   if (symbolic_operand (operands[0], GET_MODE (operands[0])))
7183     operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
7186 (define_insn "prefetch_si_address"
7187   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7188                       (match_operand:SI 3 "const_int_operand" "I"))
7189              (match_operand:SI 1 "const_int_operand" "n")
7190              (match_operand:SI 2 "const_int_operand" "n"))]
7191   "ISA_HAS_PREFETCH && Pmode == SImode"
7192   { return mips_emit_prefetch (operands); }
7193   [(set_attr "type" "prefetch")])
7195 (define_insn "prefetch_indexed_si"
7196   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7197                       (match_operand:SI 3 "register_operand" "r"))
7198              (match_operand:SI 1 "const_int_operand" "n")
7199              (match_operand:SI 2 "const_int_operand" "n"))]
7200   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
7201   { return mips_emit_prefetch (operands); }
7202   [(set_attr "type" "prefetchx")])
7204 (define_insn "prefetch_si"
7205   [(prefetch (match_operand:SI 0 "register_operand" "r")
7206              (match_operand:SI 1 "const_int_operand" "n")
7207              (match_operand:SI 2 "const_int_operand" "n"))]
7208   "ISA_HAS_PREFETCH && Pmode == SImode"
7210   operands[3] = const0_rtx;
7211   return mips_emit_prefetch (operands);
7213   [(set_attr "type" "prefetch")])
7215 (define_insn "prefetch_di_address"
7216   [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7217                       (match_operand:DI 3 "const_int_operand" "I"))
7218              (match_operand:DI 1 "const_int_operand" "n")
7219              (match_operand:DI 2 "const_int_operand" "n"))]
7220   "ISA_HAS_PREFETCH && Pmode == DImode"
7221   { return mips_emit_prefetch (operands); }
7222   [(set_attr "type" "prefetch")])
7224 (define_insn "prefetch_indexed_di"
7225   [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7226                       (match_operand:DI 3 "register_operand" "r"))
7227              (match_operand:DI 1 "const_int_operand" "n")
7228              (match_operand:DI 2 "const_int_operand" "n"))]
7229   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
7230   { return mips_emit_prefetch (operands); }
7231   [(set_attr "type" "prefetchx")])
7233 (define_insn "prefetch_di"
7234   [(prefetch (match_operand:DI 0 "register_operand" "r")
7235              (match_operand:DI 1 "const_int_operand" "n")
7236              (match_operand:DI 2 "const_int_operand" "n"))]
7237   "ISA_HAS_PREFETCH && Pmode == DImode"
7239   operands[3] = const0_rtx;
7240   return mips_emit_prefetch (operands);
7242   [(set_attr "type" "prefetch")])
7244 (define_insn "nop"
7245   [(const_int 0)]
7246   ""
7247   "%(nop%)"
7248   [(set_attr "type"     "nop")
7249    (set_attr "mode"     "none")])
7251 ;; Like nop, but commented out when outside a .set noreorder block.
7252 (define_insn "hazard_nop"
7253   [(const_int 1)]
7254   ""
7255   {
7256     if (set_noreorder)
7257       return "nop";
7258     else
7259       return "#nop";
7260   }
7261   [(set_attr "type"     "nop")])
7263 ;; MIPS4 Conditional move instructions.
7265 (define_insn ""
7266   [(set (match_operand:SI 0 "register_operand" "=d,d")
7267         (if_then_else:SI
7268          (match_operator 4 "equality_op"
7269                          [(match_operand:SI 1 "register_operand" "d,d")
7270                           (const_int 0)])
7271          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7272          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7273   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7274   "@
7275     mov%B4\t%0,%z2,%1
7276     mov%b4\t%0,%z3,%1"
7277   [(set_attr "type" "condmove")
7278    (set_attr "mode" "SI")])
7280 (define_insn ""
7281   [(set (match_operand:SI 0 "register_operand" "=d,d")
7282         (if_then_else:SI
7283          (match_operator 4 "equality_op"
7284                          [(match_operand:DI 1 "register_operand" "d,d")
7285                           (const_int 0)])
7286          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7287          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7288   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7289   "@
7290     mov%B4\t%0,%z2,%1
7291     mov%b4\t%0,%z3,%1"
7292   [(set_attr "type" "condmove")
7293    (set_attr "mode" "SI")])
7295 (define_insn ""
7296   [(set (match_operand:SI 0 "register_operand" "=d,d")
7297         (if_then_else:SI
7298          (match_operator 3 "equality_op" [(match_operand:CC 4
7299                                                             "register_operand"
7300                                                             "z,z")
7301                                           (const_int 0)])
7302          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
7303          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
7304   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7305   "@
7306     mov%T3\t%0,%z1,%4
7307     mov%t3\t%0,%z2,%4"
7308   [(set_attr "type" "condmove")
7309    (set_attr "mode" "SI")])
7311 (define_insn ""
7312   [(set (match_operand:DI 0 "register_operand" "=d,d")
7313         (if_then_else:DI
7314          (match_operator 4 "equality_op"
7315                          [(match_operand:SI 1 "register_operand" "d,d")
7316                           (const_int 0)])
7317          (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7318          (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7319   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7320   "@
7321     mov%B4\t%0,%z2,%1
7322     mov%b4\t%0,%z3,%1"
7323   [(set_attr "type" "condmove")
7324    (set_attr "mode" "DI")])
7326 (define_insn ""
7327   [(set (match_operand:DI 0 "register_operand" "=d,d")
7328         (if_then_else:DI
7329          (match_operator 4 "equality_op"
7330                          [(match_operand:DI 1 "register_operand" "d,d")
7331                           (const_int 0)])
7332          (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7333          (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7334   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7335   "@
7336     mov%B4\t%0,%z2,%1
7337     mov%b4\t%0,%z3,%1"
7338   [(set_attr "type" "condmove")
7339    (set_attr "mode" "DI")])
7341 (define_insn ""
7342   [(set (match_operand:DI 0 "register_operand" "=d,d")
7343         (if_then_else:DI
7344          (match_operator 3 "equality_op" [(match_operand:CC 4
7345                                                             "register_operand"
7346                                                             "z,z")
7347                                           (const_int 0)])
7348          (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
7349          (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
7350   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
7351   "@
7352     mov%T3\t%0,%z1,%4
7353     mov%t3\t%0,%z2,%4"
7354   [(set_attr "type" "condmove")
7355    (set_attr "mode" "DI")])
7357 (define_insn ""
7358   [(set (match_operand:SF 0 "register_operand" "=f,f")
7359         (if_then_else:SF
7360          (match_operator 4 "equality_op"
7361                          [(match_operand:SI 1 "register_operand" "d,d")
7362                           (const_int 0)])
7363          (match_operand:SF 2 "register_operand" "f,0")
7364          (match_operand:SF 3 "register_operand" "0,f")))]
7365   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7366   "@
7367     mov%B4.s\t%0,%2,%1
7368     mov%b4.s\t%0,%3,%1"
7369   [(set_attr "type" "condmove")
7370    (set_attr "mode" "SF")])
7372 (define_insn ""
7373   [(set (match_operand:SF 0 "register_operand" "=f,f")
7374         (if_then_else:SF
7375          (match_operator 4 "equality_op"
7376                          [(match_operand:DI 1 "register_operand" "d,d")
7377                           (const_int 0)])
7378          (match_operand:SF 2 "register_operand" "f,0")
7379          (match_operand:SF 3 "register_operand" "0,f")))]
7380   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7381   "@
7382     mov%B4.s\t%0,%2,%1
7383     mov%b4.s\t%0,%3,%1"
7384   [(set_attr "type" "condmove")
7385    (set_attr "mode" "SF")])
7387 (define_insn ""
7388   [(set (match_operand:SF 0 "register_operand" "=f,f")
7389         (if_then_else:SF
7390          (match_operator 3 "equality_op" [(match_operand:CC 4
7391                                                             "register_operand"
7392                                                             "z,z")
7393                                           (const_int 0)])
7394          (match_operand:SF 1 "register_operand" "f,0")
7395          (match_operand:SF 2 "register_operand" "0,f")))]
7396   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7397   "@
7398     mov%T3.s\t%0,%1,%4
7399     mov%t3.s\t%0,%2,%4"
7400   [(set_attr "type" "condmove")
7401    (set_attr "mode" "SF")])
7403 (define_insn ""
7404   [(set (match_operand:DF 0 "register_operand" "=f,f")
7405         (if_then_else:DF
7406          (match_operator 4 "equality_op"
7407                          [(match_operand:SI 1 "register_operand" "d,d")
7408                           (const_int 0)])
7409          (match_operand:DF 2 "register_operand" "f,0")
7410          (match_operand:DF 3 "register_operand" "0,f")))]
7411   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7412   "@
7413     mov%B4.d\t%0,%2,%1
7414     mov%b4.d\t%0,%3,%1"
7415   [(set_attr "type" "condmove")
7416    (set_attr "mode" "DF")])
7418 (define_insn ""
7419   [(set (match_operand:DF 0 "register_operand" "=f,f")
7420         (if_then_else:DF
7421          (match_operator 4 "equality_op"
7422                          [(match_operand:DI 1 "register_operand" "d,d")
7423                           (const_int 0)])
7424          (match_operand:DF 2 "register_operand" "f,0")
7425          (match_operand:DF 3 "register_operand" "0,f")))]
7426   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7427   "@
7428     mov%B4.d\t%0,%2,%1
7429     mov%b4.d\t%0,%3,%1"
7430   [(set_attr "type" "condmove")
7431    (set_attr "mode" "DF")])
7433 (define_insn ""
7434   [(set (match_operand:DF 0 "register_operand" "=f,f")
7435         (if_then_else:DF
7436          (match_operator 3 "equality_op" [(match_operand:CC 4
7437                                                             "register_operand"
7438                                                             "z,z")
7439                                           (const_int 0)])
7440          (match_operand:DF 1 "register_operand" "f,0")
7441          (match_operand:DF 2 "register_operand" "0,f")))]
7442   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7443   "@
7444     mov%T3.d\t%0,%1,%4
7445     mov%t3.d\t%0,%2,%4"
7446   [(set_attr "type" "condmove")
7447    (set_attr "mode" "DF")])
7449 ;; These are the main define_expand's used to make conditional moves.
7451 (define_expand "movsicc"
7452   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7453    (set (match_operand:SI 0 "register_operand")
7454         (if_then_else:SI (match_dup 5)
7455                          (match_operand:SI 2 "reg_or_0_operand")
7456                          (match_operand:SI 3 "reg_or_0_operand")))]
7457   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7459   gen_conditional_move (operands);
7460   DONE;
7463 (define_expand "movdicc"
7464   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7465    (set (match_operand:DI 0 "register_operand")
7466         (if_then_else:DI (match_dup 5)
7467                          (match_operand:DI 2 "reg_or_0_operand")
7468                          (match_operand:DI 3 "reg_or_0_operand")))]
7469   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7471   gen_conditional_move (operands);
7472   DONE;
7475 (define_expand "movsfcc"
7476   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7477    (set (match_operand:SF 0 "register_operand")
7478         (if_then_else:SF (match_dup 5)
7479                          (match_operand:SF 2 "register_operand")
7480                          (match_operand:SF 3 "register_operand")))]
7481   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7483   gen_conditional_move (operands);
7484   DONE;
7487 (define_expand "movdfcc"
7488   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7489    (set (match_operand:DF 0 "register_operand")
7490         (if_then_else:DF (match_dup 5)
7491                          (match_operand:DF 2 "register_operand")
7492                          (match_operand:DF 3 "register_operand")))]
7493   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7495   gen_conditional_move (operands);
7496   DONE;
7500 ;;  ....................
7502 ;;      mips16 inline constant tables
7504 ;;  ....................
7507 (define_insn "consttable_int"
7508   [(unspec_volatile [(match_operand 0 "consttable_operand" "")
7509                      (match_operand 1 "const_int_operand" "")]
7510                     UNSPEC_CONSTTABLE_INT)]
7511   "TARGET_MIPS16"
7513   assemble_integer (operands[0], INTVAL (operands[1]),
7514                     BITS_PER_UNIT * INTVAL (operands[1]), 1);
7515   return "";
7517   [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
7519 (define_insn "consttable_float"
7520   [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
7521                     UNSPEC_CONSTTABLE_FLOAT)]
7522   "TARGET_MIPS16"
7524   REAL_VALUE_TYPE d;
7526   if (GET_CODE (operands[0]) != CONST_DOUBLE)
7527     abort ();
7528   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7529   assemble_real (d, GET_MODE (operands[0]),
7530                  GET_MODE_BITSIZE (GET_MODE (operands[0])));
7531   return "";
7533   [(set (attr "length")
7534         (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
7536 (define_insn "align"
7537   [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
7538   ""
7539   ".align\t%0"
7540   [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
7542 (define_split
7543   [(match_operand 0 "small_data_pattern")]
7544   "reload_completed"
7545   [(match_dup 0)]
7546   { operands[0] = mips_rewrite_small_data (operands[0]); })