* config/mips/mips.md (length): Don't use mips_fetch_insns for indexed
[official-gcc.git] / gcc / config / mips / mips.md
blobe42a607977fbff194b827b6cfdbbd0b144cea7a4
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_LOAD_LEFT            18)
40    (UNSPEC_LOAD_RIGHT           19)
41    (UNSPEC_STORE_LEFT           20)
42    (UNSPEC_STORE_RIGHT          21)
43    (UNSPEC_LOADGP               22)
44    (UNSPEC_LOAD_CALL            23)
45    (UNSPEC_LOAD_GOT             24)
46    (UNSPEC_GP                   25)
47    (UNSPEC_MFHILO               26)
49    (UNSPEC_ADDRESS_FIRST        100)
51    (FAKE_CALL_REGNO             79)])
53 (include "predicates.md")
55 ;; ....................
57 ;;      Attributes
59 ;; ....................
61 (define_attr "got" "unset,xgot_high,load"
62   (const_string "unset"))
64 ;; For jal instructions, this attribute is DIRECT when the target address
65 ;; is symbolic and INDIRECT when it is a register.
66 (define_attr "jal" "unset,direct,indirect"
67   (const_string "unset"))
69 ;; This attribute is YES if the instruction is a jal macro (not a
70 ;; real jal instruction).
72 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
73 ;; restore $gp.  Direct jals are also macros in NewABI PIC since they
74 ;; load the target address into $25.
75 (define_attr "jal_macro" "no,yes"
76   (cond [(eq_attr "jal" "direct")
77          (symbol_ref "TARGET_ABICALLS != 0")
78          (eq_attr "jal" "indirect")
79          (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
80         (const_string "no")))
82 ;; Classification of each insn.
83 ;; branch       conditional branch
84 ;; jump         unconditional jump
85 ;; call         unconditional call
86 ;; load         load instruction(s)
87 ;; fpload       floating point load
88 ;; fpidxload    floating point indexed load
89 ;; store        store instruction(s)
90 ;; fpstore      floating point store
91 ;; fpidxstore   floating point indexed store
92 ;; prefetch     memory prefetch (register + offset)
93 ;; prefetchx    memory indexed prefetch (register + register)
94 ;; condmove     conditional moves
95 ;; xfer         transfer to/from coprocessor
96 ;; mthilo       transfer to hi/lo registers
97 ;; mfhilo       transfer from hi/lo registers
98 ;; const        load constant
99 ;; arith        integer arithmetic and logical instructions
100 ;; shift        integer shift instructions
101 ;; slt          set less than instructions
102 ;; clz          the clz and clo instructions
103 ;; trap         trap if instructions
104 ;; imul         integer multiply
105 ;; imadd        integer multiply-add
106 ;; idiv         integer divide
107 ;; fmove        floating point register move
108 ;; fadd         floating point add/subtract
109 ;; fmul         floating point multiply
110 ;; fmadd        floating point multiply-add
111 ;; fdiv         floating point divide
112 ;; frdiv        floating point reciprocal divide
113 ;; fabs         floating point absolute value
114 ;; fneg         floating point negation
115 ;; fcmp         floating point compare
116 ;; fcvt         floating point convert
117 ;; fsqrt        floating point square root
118 ;; frsqrt       floating point reciprocal square root
119 ;; multi        multiword sequence (or user asm statements)
120 ;; nop          no operation
121 (define_attr "type"
122   "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,frdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
123   (cond [(eq_attr "jal" "!unset") (const_string "call")
124          (eq_attr "got" "load") (const_string "load")]
125         (const_string "unknown")))
127 ;; Main data type used by the insn
128 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
129   (const_string "unknown"))
131 ;; Is this an extended instruction in mips16 mode?
132 (define_attr "extended_mips16" "no,yes"
133   (const_string "no"))
135 ;; Length of instruction in bytes.
136 (define_attr "length" ""
137    (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
138           ;; If a branch is outside this range, we have a choice of two
139           ;; sequences.  For PIC, an out-of-range branch like:
140           ;;
141           ;;    bne     r1,r2,target
142           ;;    dslot
143           ;;
144           ;; becomes the equivalent of:
145           ;;
146           ;;    beq     r1,r2,1f
147           ;;    dslot
148           ;;    la      $at,target
149           ;;    jr      $at
150           ;;    nop
151           ;; 1:
152           ;;
153           ;; where the load address can be up to three instructions long
154           ;; (lw, nop, addiu).
155           ;;
156           ;; The non-PIC case is similar except that we use a direct
157           ;; jump instead of an la/jr pair.  Since the target of this
158           ;; jump is an absolute 28-bit bit address (the other bits
159           ;; coming from the address of the delay slot) this form cannot
160           ;; cross a 256MB boundary.  We could provide the option of
161           ;; using la/jr in this case too, but we do not do so at
162           ;; present.
163           ;;
164           ;; Note that this value does not account for the delay slot
165           ;; instruction, whose length is added separately.  If the RTL
166           ;; pattern has no explicit delay slot, mips_adjust_insn_length
167           ;; will add the length of the implicit nop.  The values for
168           ;; forward and backward branches will be different as well.
169           (eq_attr "type" "branch")
170           (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
171                       (le (minus (pc) (match_dup 1)) (const_int 131068)))
172                   (const_int 4)
173                  (ne (symbol_ref "flag_pic") (const_int 0))
174                  (const_int 24)
175                  ] (const_int 12))
177           (eq_attr "got" "load")
178           (const_int 4)
179           (eq_attr "got" "xgot_high")
180           (const_int 8)
182           (eq_attr "type" "const")
183           (symbol_ref "mips_const_insns (operands[1]) * 4")
184           (eq_attr "type" "load,fpload")
185           (symbol_ref "mips_fetch_insns (operands[1]) * 4")
186           (eq_attr "type" "store,fpstore")
187           (symbol_ref "mips_fetch_insns (operands[0]) * 4")
189           ;; In the worst case, a call macro will take 8 instructions:
190           ;;
191           ;;     lui $25,%call_hi(FOO)
192           ;;     addu $25,$25,$28
193           ;;     lw $25,%call_lo(FOO)($25)
194           ;;     nop
195           ;;     jalr $25
196           ;;     nop
197           ;;     lw $gp,X($sp)
198           ;;     nop
199           (eq_attr "jal_macro" "yes")
200           (const_int 32)
202           (and (eq_attr "extended_mips16" "yes")
203                (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
204           (const_int 8)
206           ;; Various VR4120 errata require a nop to be inserted after a macc
207           ;; instruction.  The assembler does this for us, so account for
208           ;; the worst-case length here.
209           (and (eq_attr "type" "imadd")
210                (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
211           (const_int 8)
213           ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
214           ;; the result of the second one is missed.  The assembler should work
215           ;; around this by inserting a nop after the first dmult.
216           (and (eq_attr "type" "imul")
217                (and (eq_attr "mode" "DI")
218                     (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
219           (const_int 8)
221           (eq_attr "type" "idiv")
222           (symbol_ref "mips_idiv_insns () * 4")
223           ] (const_int 4)))
225 ;; Attribute describing the processor.  This attribute must match exactly
226 ;; with the processor_type enumeration in mips.h.
227 (define_attr "cpu"
228   "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
229   (const (symbol_ref "mips_tune")))
231 ;; The type of hardware hazard associated with this instruction.
232 ;; DELAY means that the next instruction cannot read the result
233 ;; of this one.  HILO means that the next two instructions cannot
234 ;; write to HI or LO.
235 (define_attr "hazard" "none,delay,hilo"
236   (cond [(and (eq_attr "type" "load,fpload,fpidxload")
237               (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
238          (const_string "delay")
240          (and (eq_attr "type" "xfer")
241               (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
242          (const_string "delay")
244          (and (eq_attr "type" "fcmp")
245               (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
246          (const_string "delay")
248          ;; The r4000 multiplication patterns include an mflo instruction.
249          (and (eq_attr "type" "imul")
250               (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
251          (const_string "hilo")
253          (and (eq_attr "type" "mfhilo")
254               (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
255          (const_string "hilo")]
256         (const_string "none")))
258 ;; Is it a single instruction?
259 (define_attr "single_insn" "no,yes"
260   (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
262 ;; Can the instruction be put into a delay slot?
263 (define_attr "can_delay" "no,yes"
264   (if_then_else (and (eq_attr "type" "!branch,call,jump")
265                      (and (eq_attr "hazard" "none")
266                           (eq_attr "single_insn" "yes")))
267                 (const_string "yes")
268                 (const_string "no")))
270 ;; Attribute defining whether or not we can use the branch-likely instructions
271 (define_attr "branch_likely" "no,yes"
272   (const
273    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
274                  (const_string "yes")
275                  (const_string "no"))))
277 ;; True if an instruction might assign to hi or lo when reloaded.
278 ;; This is used by the TUNE_MACC_CHAINS code.
279 (define_attr "may_clobber_hilo" "no,yes"
280   (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
281                 (const_string "yes")
282                 (const_string "no")))
284 ;; Describe a user's asm statement.
285 (define_asm_attributes
286   [(set_attr "type" "multi")])
288 ;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
289 ;; from the same template.
290 (define_mode_macro GPR [SI (DI "TARGET_64BIT")])
292 ;; This mode macro allows :P to be used for patterns that operate on
293 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
294 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
296 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
297 ;; 32-bit version and "dsubu" in the 64-bit version.
298 (define_mode_attr d [(SI "") (DI "d")])
300 ;; Mode attributes for GPR loads and stores.
301 (define_mode_attr load [(SI "lw") (DI "ld")])
302 (define_mode_attr store [(SI "sw") (DI "sd")])
304 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
305 ;; are different.  Some forms of unextended addiu have an 8-bit immediate
306 ;; field but the equivalent daddiu has only a 5-bit field.
307 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
309 ;; This code macro allows all branch instructions to be generated from
310 ;; a single define_expand template.
311 (define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
312                              eq ne gt ge lt le gtu geu ltu leu])
314 ;; This code macro allows signed and unsigned widening multiplications
315 ;; to use the same template.
316 (define_code_macro any_extend [sign_extend zero_extend])
318 ;; <u> expands to an empty string when doing a signed operation and
319 ;; "u" when doing an unsigned operation.
320 (define_code_attr u [(sign_extend "") (zero_extend "u")])
322 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
323 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
325 ;; .........................
327 ;;      Branch, call and jump delay slots
329 ;; .........................
331 (define_delay (and (eq_attr "type" "branch")
332                    (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
333   [(eq_attr "can_delay" "yes")
334    (nil)
335    (and (eq_attr "branch_likely" "yes")
336         (eq_attr "can_delay" "yes"))])
338 (define_delay (eq_attr "type" "jump")
339   [(eq_attr "can_delay" "yes")
340    (nil)
341    (nil)])
343 (define_delay (and (eq_attr "type" "call")
344                    (eq_attr "jal_macro" "no"))
345   [(eq_attr "can_delay" "yes")
346    (nil)
347    (nil)])
349 ;; Pipeline descriptions.
351 ;; generic.md provides a fallback for processors without a specific
352 ;; pipeline description.  It is derived from the old define_function_unit
353 ;; version and uses the "alu" and "imuldiv" units declared below.
355 ;; Some of the processor-specific files are also derived from old
356 ;; define_function_unit descriptions and simply override the parts of
357 ;; generic.md that don't apply.  The other processor-specific files
358 ;; are self-contained.
359 (define_automaton "alu,imuldiv")
361 (define_cpu_unit "alu" "alu")
362 (define_cpu_unit "imuldiv" "imuldiv")
364 (include "3000.md")
365 (include "4000.md")
366 (include "4100.md")
367 (include "4130.md")
368 (include "4300.md")
369 (include "4600.md")
370 (include "5000.md")
371 (include "5400.md")
372 (include "5500.md")
373 (include "6000.md")
374 (include "7000.md")
375 (include "9000.md")
376 (include "sb1.md")
377 (include "sr71k.md")
378 (include "generic.md")
381 ;;  ....................
383 ;;      CONDITIONAL TRAPS
385 ;;  ....................
388 (define_insn "trap"
389   [(trap_if (const_int 1) (const_int 0))]
390   ""
392   if (ISA_HAS_COND_TRAP)
393     return "teq\t$0,$0";
394   else if (TARGET_MIPS16)
395     return "break 0";
396   else
397     return "break";
399   [(set_attr "type"     "trap")])
401 (define_expand "conditional_trap"
402   [(trap_if (match_operator 0 "comparison_operator"
403                             [(match_dup 2) (match_dup 3)])
404             (match_operand 1 "const_int_operand"))]
405   "ISA_HAS_COND_TRAP"
407   if (operands[1] == const0_rtx)
408     {
409       mips_gen_conditional_trap (operands);
410       DONE;
411     }
412   else
413     FAIL;
416 (define_insn ""
417   [(trap_if (match_operator 0 "trap_comparison_operator"
418                             [(match_operand:SI 1 "reg_or_0_operand" "dJ")
419                              (match_operand:SI 2 "arith_operand" "dI")])
420             (const_int 0))]
421   "ISA_HAS_COND_TRAP"
422   "t%C0\t%z1,%z2"
423   [(set_attr "type"     "trap")])
425 (define_insn ""
426   [(trap_if (match_operator 0 "trap_comparison_operator"
427                             [(match_operand:DI 1 "reg_or_0_operand" "dJ")
428                              (match_operand:DI 2 "arith_operand" "dI")])
429             (const_int 0))]
430   "TARGET_64BIT && ISA_HAS_COND_TRAP"
431   "t%C0\t%z1,%z2"
432   [(set_attr "type"     "trap")])
435 ;;  ....................
437 ;;      ADDITION
439 ;;  ....................
442 (define_insn "adddf3"
443   [(set (match_operand:DF 0 "register_operand" "=f")
444         (plus:DF (match_operand:DF 1 "register_operand" "f")
445                  (match_operand:DF 2 "register_operand" "f")))]
446   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
447   "add.d\t%0,%1,%2"
448   [(set_attr "type"     "fadd")
449    (set_attr "mode"     "DF")])
451 (define_insn "addsf3"
452   [(set (match_operand:SF 0 "register_operand" "=f")
453         (plus:SF (match_operand:SF 1 "register_operand" "f")
454                  (match_operand:SF 2 "register_operand" "f")))]
455   "TARGET_HARD_FLOAT"
456   "add.s\t%0,%1,%2"
457   [(set_attr "type"     "fadd")
458    (set_attr "mode"     "SF")])
460 (define_expand "add<mode>3"
461   [(set (match_operand:GPR 0 "register_operand")
462         (plus:GPR (match_operand:GPR 1 "register_operand")
463                   (match_operand:GPR 2 "arith_operand")))]
464   "")
466 (define_insn "*add<mode>3"
467   [(set (match_operand:GPR 0 "register_operand" "=d,d")
468         (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
469                   (match_operand:GPR 2 "arith_operand" "d,Q")))]
470   "!TARGET_MIPS16"
471   "@
472     <d>addu\t%0,%1,%2
473     <d>addiu\t%0,%1,%2"
474   [(set_attr "type" "arith")
475    (set_attr "mode" "<MODE>")])
477 ;; We need to recognize MIPS16 stack pointer additions explicitly, since
478 ;; we don't have a constraint for $sp.  These insns will be generated by
479 ;; the save_restore_insns functions.
481 (define_insn "*add<mode>3_sp1"
482   [(set (reg:GPR 29)
483         (plus:GPR (reg:GPR 29)
484                   (match_operand:GPR 0 "const_arith_operand" "")))]
485   "TARGET_MIPS16"
486   "<d>addiu\t%$,%$,%0"
487   [(set_attr "type" "arith")
488    (set_attr "mode" "<MODE>")
489    (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
490                                       (const_int 4)
491                                       (const_int 8)))])
493 (define_insn "*add<mode>3_sp2"
494   [(set (match_operand:GPR 0 "register_operand" "=d")
495         (plus:GPR (reg:GPR 29)
496                   (match_operand:GPR 1 "const_arith_operand" "")))]
497   "TARGET_MIPS16"
498   "<d>addiu\t%0,%$,%1"
499   [(set_attr "type" "arith")
500    (set_attr "mode" "<MODE>")
501    (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
502                                       (const_int 4)
503                                       (const_int 8)))])
505 (define_insn "*add<mode>3_mips16"
506   [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
507         (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
508                   (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
509   "TARGET_MIPS16"
510   "@
511     <d>addiu\t%0,%2
512     <d>addiu\t%0,%1,%2
513     <d>addu\t%0,%1,%2"
514   [(set_attr "type" "arith")
515    (set_attr "mode" "<MODE>")
516    (set_attr_alternative "length"
517                 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
518                                (const_int 4)
519                                (const_int 8))
520                  (if_then_else (match_operand 2 "m16_simm4_1")
521                                (const_int 4)
522                                (const_int 8))
523                  (const_int 4)])])
526 ;; On the mips16, we can sometimes split an add of a constant which is
527 ;; a 4 byte instruction into two adds which are both 2 byte
528 ;; instructions.  There are two cases: one where we are adding a
529 ;; constant plus a register to another register, and one where we are
530 ;; simply adding a constant to a register.
532 (define_split
533   [(set (match_operand:SI 0 "register_operand")
534         (plus:SI (match_dup 0)
535                  (match_operand:SI 1 "const_int_operand")))]
536   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
537    && GET_CODE (operands[0]) == REG
538    && M16_REG_P (REGNO (operands[0]))
539    && GET_CODE (operands[1]) == CONST_INT
540    && ((INTVAL (operands[1]) > 0x7f
541         && INTVAL (operands[1]) <= 0x7f + 0x7f)
542        || (INTVAL (operands[1]) < - 0x80
543            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
544   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
545    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
547   HOST_WIDE_INT val = INTVAL (operands[1]);
549   if (val >= 0)
550     {
551       operands[1] = GEN_INT (0x7f);
552       operands[2] = GEN_INT (val - 0x7f);
553     }
554   else
555     {
556       operands[1] = GEN_INT (- 0x80);
557       operands[2] = GEN_INT (val + 0x80);
558     }
561 (define_split
562   [(set (match_operand:SI 0 "register_operand")
563         (plus:SI (match_operand:SI 1 "register_operand")
564                  (match_operand:SI 2 "const_int_operand")))]
565   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
566    && GET_CODE (operands[0]) == REG
567    && M16_REG_P (REGNO (operands[0]))
568    && GET_CODE (operands[1]) == REG
569    && M16_REG_P (REGNO (operands[1]))
570    && REGNO (operands[0]) != REGNO (operands[1])
571    && GET_CODE (operands[2]) == CONST_INT
572    && ((INTVAL (operands[2]) > 0x7
573         && INTVAL (operands[2]) <= 0x7 + 0x7f)
574        || (INTVAL (operands[2]) < - 0x8
575            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
576   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
577    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
579   HOST_WIDE_INT val = INTVAL (operands[2]);
581   if (val >= 0)
582     {
583       operands[2] = GEN_INT (0x7);
584       operands[3] = GEN_INT (val - 0x7);
585     }
586   else
587     {
588       operands[2] = GEN_INT (- 0x8);
589       operands[3] = GEN_INT (val + 0x8);
590     }
593 (define_split
594   [(set (match_operand:DI 0 "register_operand")
595         (plus:DI (match_dup 0)
596                  (match_operand:DI 1 "const_int_operand")))]
597   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
598    && GET_CODE (operands[0]) == REG
599    && M16_REG_P (REGNO (operands[0]))
600    && GET_CODE (operands[1]) == CONST_INT
601    && ((INTVAL (operands[1]) > 0xf
602         && INTVAL (operands[1]) <= 0xf + 0xf)
603        || (INTVAL (operands[1]) < - 0x10
604            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
605   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
606    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
608   HOST_WIDE_INT val = INTVAL (operands[1]);
610   if (val >= 0)
611     {
612       operands[1] = GEN_INT (0xf);
613       operands[2] = GEN_INT (val - 0xf);
614     }
615   else
616     {
617       operands[1] = GEN_INT (- 0x10);
618       operands[2] = GEN_INT (val + 0x10);
619     }
622 (define_split
623   [(set (match_operand:DI 0 "register_operand")
624         (plus:DI (match_operand:DI 1 "register_operand")
625                  (match_operand:DI 2 "const_int_operand")))]
626   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
627    && GET_CODE (operands[0]) == REG
628    && M16_REG_P (REGNO (operands[0]))
629    && GET_CODE (operands[1]) == REG
630    && M16_REG_P (REGNO (operands[1]))
631    && REGNO (operands[0]) != REGNO (operands[1])
632    && GET_CODE (operands[2]) == CONST_INT
633    && ((INTVAL (operands[2]) > 0x7
634         && INTVAL (operands[2]) <= 0x7 + 0xf)
635        || (INTVAL (operands[2]) < - 0x8
636            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
637   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
638    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
640   HOST_WIDE_INT val = INTVAL (operands[2]);
642   if (val >= 0)
643     {
644       operands[2] = GEN_INT (0x7);
645       operands[3] = GEN_INT (val - 0x7);
646     }
647   else
648     {
649       operands[2] = GEN_INT (- 0x8);
650       operands[3] = GEN_INT (val + 0x8);
651     }
654 (define_insn "*addsi3_extended"
655   [(set (match_operand:DI 0 "register_operand" "=d,d")
656         (sign_extend:DI
657              (plus:SI (match_operand:SI 1 "register_operand" "d,d")
658                       (match_operand:SI 2 "arith_operand" "d,Q"))))]
659   "TARGET_64BIT && !TARGET_MIPS16"
660   "@
661     addu\t%0,%1,%2
662     addiu\t%0,%1,%2"
663   [(set_attr "type" "arith")
664    (set_attr "mode" "SI")])
666 ;; Split this insn so that the addiu splitters can have a crack at it.
667 ;; Use a conservative length estimate until the split.
668 (define_insn_and_split "*addsi3_extended_mips16"
669   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
670         (sign_extend:DI
671              (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
672                       (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
673   "TARGET_64BIT && TARGET_MIPS16"
674   "#"
675   "&& reload_completed"
676   [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
677   { operands[3] = gen_lowpart (SImode, operands[0]); }
678   [(set_attr "type" "arith")
679    (set_attr "mode" "SI")
680    (set_attr "extended_mips16" "yes")])
683 ;;  ....................
685 ;;      SUBTRACTION
687 ;;  ....................
690 (define_insn "subdf3"
691   [(set (match_operand:DF 0 "register_operand" "=f")
692         (minus:DF (match_operand:DF 1 "register_operand" "f")
693                   (match_operand:DF 2 "register_operand" "f")))]
694   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
695   "sub.d\t%0,%1,%2"
696   [(set_attr "type"     "fadd")
697    (set_attr "mode"     "DF")])
699 (define_insn "subsf3"
700   [(set (match_operand:SF 0 "register_operand" "=f")
701         (minus:SF (match_operand:SF 1 "register_operand" "f")
702                   (match_operand:SF 2 "register_operand" "f")))]
703   "TARGET_HARD_FLOAT"
704   "sub.s\t%0,%1,%2"
705   [(set_attr "type"     "fadd")
706    (set_attr "mode"     "SF")])
708 (define_insn "sub<mode>3"
709   [(set (match_operand:GPR 0 "register_operand" "=d")
710         (minus:GPR (match_operand:GPR 1 "register_operand" "d")
711                    (match_operand:GPR 2 "register_operand" "d")))]
712   ""
713   "<d>subu\t%0,%1,%2"
714   [(set_attr "type" "arith")
715    (set_attr "mode" "<MODE>")])
717 (define_insn "*subsi3_extended"
718   [(set (match_operand:DI 0 "register_operand" "=d")
719         (sign_extend:DI
720             (minus:SI (match_operand:SI 1 "register_operand" "d")
721                       (match_operand:SI 2 "register_operand" "d"))))]
722   "TARGET_64BIT"
723   "subu\t%0,%1,%2"
724   [(set_attr "type" "arith")
725    (set_attr "mode" "DI")])
728 ;;  ....................
730 ;;      MULTIPLICATION
732 ;;  ....................
735 (define_expand "muldf3"
736   [(set (match_operand:DF 0 "register_operand")
737         (mult:DF (match_operand:DF 1 "register_operand")
738                  (match_operand:DF 2 "register_operand")))]
739   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
740   "")
742 (define_insn "muldf3_internal"
743   [(set (match_operand:DF 0 "register_operand" "=f")
744         (mult:DF (match_operand:DF 1 "register_operand" "f")
745                  (match_operand:DF 2 "register_operand" "f")))]
746   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
747   "mul.d\t%0,%1,%2"
748   [(set_attr "type"     "fmul")
749    (set_attr "mode"     "DF")])
751 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
752 ;; operands may corrupt immediately following multiplies. This is a
753 ;; simple fix to insert NOPs.
755 (define_insn "muldf3_r4300"
756   [(set (match_operand:DF 0 "register_operand" "=f")
757         (mult:DF (match_operand:DF 1 "register_operand" "f")
758                  (match_operand:DF 2 "register_operand" "f")))]
759   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
760   "mul.d\t%0,%1,%2\;nop"
761   [(set_attr "type"     "fmul")
762    (set_attr "mode"     "DF")
763    (set_attr "length"   "8")])
765 (define_expand "mulsf3"
766   [(set (match_operand:SF 0 "register_operand")
767         (mult:SF (match_operand:SF 1 "register_operand")
768                  (match_operand:SF 2 "register_operand")))]
769   "TARGET_HARD_FLOAT"
770   "")
772 (define_insn "mulsf3_internal"
773   [(set (match_operand:SF 0 "register_operand" "=f")
774         (mult:SF (match_operand:SF 1 "register_operand" "f")
775                  (match_operand:SF 2 "register_operand" "f")))]
776   "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
777   "mul.s\t%0,%1,%2"
778   [(set_attr "type"     "fmul")
779    (set_attr "mode"     "SF")])
781 ;; See muldf3_r4300.
783 (define_insn "mulsf3_r4300"
784   [(set (match_operand:SF 0 "register_operand" "=f")
785         (mult:SF (match_operand:SF 1 "register_operand" "f")
786                  (match_operand:SF 2 "register_operand" "f")))]
787   "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
788   "mul.s\t%0,%1,%2\;nop"
789   [(set_attr "type"     "fmul")
790    (set_attr "mode"     "SF")
791    (set_attr "length"   "8")])
794 ;; The original R4000 has a cpu bug.  If a double-word or a variable
795 ;; shift executes while an integer multiplication is in progress, the
796 ;; shift may give an incorrect result.  Avoid this by keeping the mflo
797 ;; with the mult on the R4000.
799 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
800 ;; (also valid for MIPS R4000MC processors):
802 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
803 ;;      this errata description.
804 ;;      The following code sequence causes the R4000 to incorrectly
805 ;;      execute the Double Shift Right Arithmetic 32 (dsra32)
806 ;;      instruction.  If the dsra32 instruction is executed during an
807 ;;      integer multiply, the dsra32 will only shift by the amount in
808 ;;      specified in the instruction rather than the amount plus 32
809 ;;      bits.
810 ;;      instruction 1:          mult    rs,rt           integer multiply
811 ;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
812 ;;                                                      right arithmetic + 32
813 ;;      Workaround: A dsra32 instruction placed after an integer
814 ;;      multiply should not be one of the 11 instructions after the
815 ;;      multiply instruction."
817 ;; and:
819 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
820 ;;      the following description.
821 ;;      All extended shifts (shift by n+32) and variable shifts (32 and
822 ;;      64-bit versions) may produce incorrect results under the
823 ;;      following conditions:
824 ;;      1) An integer multiply is currently executing
825 ;;      2) These types of shift instructions are executed immediately
826 ;;         following an integer divide instruction.
827 ;;      Workaround:
828 ;;      1) Make sure no integer multiply is running wihen these
829 ;;         instruction are executed.  If this cannot be predicted at
830 ;;         compile time, then insert a "mfhi" to R0 instruction
831 ;;         immediately after the integer multiply instruction.  This
832 ;;         will cause the integer multiply to complete before the shift
833 ;;         is executed.
834 ;;      2) Separate integer divide and these two classes of shift
835 ;;         instructions by another instruction or a noop."
837 ;; These processors have PRId values of 0x00004220 and 0x00004300,
838 ;; respectively.
840 (define_expand "mul<mode>3"
841   [(set (match_operand:GPR 0 "register_operand")
842         (mult:GPR (match_operand:GPR 1 "register_operand")
843                   (match_operand:GPR 2 "register_operand")))]
844   ""
846   if (GENERATE_MULT3_<MODE>)
847     emit_insn (gen_mul<mode>3_mult3 (operands[0], operands[1], operands[2]));
848   else if (!TARGET_FIX_R4000)
849     emit_insn (gen_mul<mode>3_internal (operands[0], operands[1],
850                                         operands[2]));
851   else
852     emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
853   DONE;
856 (define_insn "mulsi3_mult3"
857   [(set (match_operand:SI 0 "register_operand" "=d,l")
858         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
859                  (match_operand:SI 2 "register_operand" "d,d")))
860    (clobber (match_scratch:SI 3 "=h,h"))
861    (clobber (match_scratch:SI 4 "=l,X"))]
862   "GENERATE_MULT3_SI"
864   if (which_alternative == 1)
865     return "mult\t%1,%2";
866   if (TARGET_MAD
867       || TARGET_MIPS5400
868       || TARGET_MIPS5500
869       || TARGET_MIPS7000
870       || TARGET_MIPS9000
871       || ISA_MIPS32
872       || ISA_MIPS32R2
873       || ISA_MIPS64)
874     return "mul\t%0,%1,%2";
875   return "mult\t%0,%1,%2";
877   [(set_attr "type" "imul")
878    (set_attr "mode" "SI")])
880 (define_insn "muldi3_mult3"
881   [(set (match_operand:DI 0 "register_operand" "=d")
882         (mult:DI (match_operand:DI 1 "register_operand" "d")
883                  (match_operand:DI 2 "register_operand" "d")))
884    (clobber (match_scratch:DI 3 "=h"))
885    (clobber (match_scratch:DI 4 "=l"))]
886   "TARGET_64BIT && GENERATE_MULT3_DI"
887   "dmult\t%0,%1,%2"
888   [(set_attr "type" "imul")
889    (set_attr "mode" "DI")])
891 ;; If a register gets allocated to LO, and we spill to memory, the reload
892 ;; will include a move from LO to a GPR.  Merge it into the multiplication
893 ;; if it can set the GPR directly.
895 ;; Operand 0: LO
896 ;; Operand 1: GPR (1st multiplication operand)
897 ;; Operand 2: GPR (2nd multiplication operand)
898 ;; Operand 3: HI
899 ;; Operand 4: GPR (destination)
900 (define_peephole2
901   [(parallel
902        [(set (match_operand:SI 0 "register_operand")
903              (mult:SI (match_operand:SI 1 "register_operand")
904                       (match_operand:SI 2 "register_operand")))
905         (clobber (match_operand:SI 3 "register_operand"))
906         (clobber (scratch:SI))])
907    (set (match_operand:SI 4 "register_operand")
908         (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
909   "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
910   [(parallel
911        [(set (match_dup 4)
912              (mult:SI (match_dup 1)
913                       (match_dup 2)))
914         (clobber (match_dup 3))
915         (clobber (match_dup 0))])])
917 (define_insn "mul<mode>3_internal"
918   [(set (match_operand:GPR 0 "register_operand" "=l")
919         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
920                   (match_operand:GPR 2 "register_operand" "d")))
921    (clobber (match_scratch:GPR 3 "=h"))]
922   "!TARGET_FIX_R4000"
923   "<d>mult\t%1,%2"
924   [(set_attr "type" "imul")
925    (set_attr "mode" "<MODE>")])
927 (define_insn "mul<mode>3_r4000"
928   [(set (match_operand:GPR 0 "register_operand" "=d")
929         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
930                   (match_operand:GPR 2 "register_operand" "d")))
931    (clobber (match_scratch:GPR 3 "=h"))
932    (clobber (match_scratch:GPR 4 "=l"))]
933   "TARGET_FIX_R4000"
934   "<d>mult\t%1,%2\;mflo\t%0"
935   [(set_attr "type" "imul")
936    (set_attr "mode" "<MODE>")
937    (set_attr "length" "8")])
939 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
940 ;; of "mult; mflo".  They have the same latency, but the first form gives
941 ;; us an extra cycle to compute the operands.
943 ;; Operand 0: LO
944 ;; Operand 1: GPR (1st multiplication operand)
945 ;; Operand 2: GPR (2nd multiplication operand)
946 ;; Operand 3: HI
947 ;; Operand 4: GPR (destination)
948 (define_peephole2
949   [(parallel
950        [(set (match_operand:SI 0 "register_operand")
951              (mult:SI (match_operand:SI 1 "register_operand")
952                       (match_operand:SI 2 "register_operand")))
953         (clobber (match_operand:SI 3 "register_operand"))])
954    (set (match_operand:SI 4 "register_operand")
955         (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
956   "ISA_HAS_MACC && !GENERATE_MULT3_SI"
957   [(set (match_dup 0)
958         (const_int 0))
959    (parallel
960        [(set (match_dup 0)
961              (plus:SI (mult:SI (match_dup 1)
962                                (match_dup 2))
963                       (match_dup 0)))
964         (set (match_dup 4)
965              (plus:SI (mult:SI (match_dup 1)
966                                (match_dup 2))
967                       (match_dup 0)))
968         (clobber (match_dup 3))])])
970 ;; Multiply-accumulate patterns
972 ;; For processors that can copy the output to a general register:
974 ;; The all-d alternative is needed because the combiner will find this
975 ;; pattern and then register alloc/reload will move registers around to
976 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
978 ;; The last alternative should be made slightly less desirable, but adding
979 ;; "?" to the constraint is too strong, and causes values to be loaded into
980 ;; LO even when that's more costly.  For now, using "*d" mostly does the
981 ;; trick.
982 (define_insn "*mul_acc_si"
983   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
984         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
985                           (match_operand:SI 2 "register_operand" "d,d,d"))
986                  (match_operand:SI 3 "register_operand" "0,l,*d")))
987    (clobber (match_scratch:SI 4 "=h,h,h"))
988    (clobber (match_scratch:SI 5 "=X,3,l"))
989    (clobber (match_scratch:SI 6 "=X,X,&d"))]
990   "(TARGET_MIPS3900
991    || ISA_HAS_MADD_MSUB)
992    && !TARGET_MIPS16"
994   static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
995   if (which_alternative == 2)
996     return "#";
997   if (ISA_HAS_MADD_MSUB && which_alternative != 0)
998     return "#";
999   return madd[which_alternative];
1001   [(set_attr "type"     "imadd,imadd,multi")
1002    (set_attr "mode"     "SI")
1003    (set_attr "length"   "4,4,8")])
1005 ;; Split the above insn if we failed to get LO allocated.
1006 (define_split
1007   [(set (match_operand:SI 0 "register_operand")
1008         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1009                           (match_operand:SI 2 "register_operand"))
1010                  (match_operand:SI 3 "register_operand")))
1011    (clobber (match_scratch:SI 4))
1012    (clobber (match_scratch:SI 5))
1013    (clobber (match_scratch:SI 6))]
1014   "reload_completed && !TARGET_DEBUG_D_MODE
1015    && GP_REG_P (true_regnum (operands[0]))
1016    && GP_REG_P (true_regnum (operands[3]))"
1017   [(parallel [(set (match_dup 6)
1018                    (mult:SI (match_dup 1) (match_dup 2)))
1019               (clobber (match_dup 4))
1020               (clobber (match_dup 5))])
1021    (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1022   "")
1024 ;; Splitter to copy result of MADD to a general register
1025 (define_split
1026   [(set (match_operand:SI                   0 "register_operand")
1027         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1028                           (match_operand:SI 2 "register_operand"))
1029                  (match_operand:SI          3 "register_operand")))
1030    (clobber (match_scratch:SI               4))
1031    (clobber (match_scratch:SI               5))
1032    (clobber (match_scratch:SI               6))]
1033   "reload_completed && !TARGET_DEBUG_D_MODE
1034    && GP_REG_P (true_regnum (operands[0]))
1035    && true_regnum (operands[3]) == LO_REGNUM"
1036   [(parallel [(set (match_dup 3)
1037                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1038                             (match_dup 3)))
1039               (clobber (match_dup 4))
1040               (clobber (match_dup 5))
1041               (clobber (match_dup 6))])
1042    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1043   "")
1045 (define_insn "*macc"
1046   [(set (match_operand:SI 0 "register_operand" "=l,d")
1047         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1048                           (match_operand:SI 2 "register_operand" "d,d"))
1049                  (match_operand:SI 3 "register_operand" "0,l")))
1050    (clobber (match_scratch:SI 4 "=h,h"))
1051    (clobber (match_scratch:SI 5 "=X,3"))]
1052   "ISA_HAS_MACC"
1054   if (which_alternative == 1)
1055     return "macc\t%0,%1,%2";
1056   else if (TARGET_MIPS5500)
1057     return "madd\t%1,%2";
1058   else
1059     /* The VR4130 assumes that there is a two-cycle latency between a macc
1060        that "writes" to $0 and an instruction that reads from it.  We avoid
1061        this by assigning to $1 instead.  */
1062     return "%[macc\t%@,%1,%2%]";
1064   [(set_attr "type" "imadd")
1065    (set_attr "mode" "SI")])
1067 (define_insn "*msac"
1068   [(set (match_operand:SI 0 "register_operand" "=l,d")
1069         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1070                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1071                            (match_operand:SI 3 "register_operand" "d,d"))))
1072    (clobber (match_scratch:SI 4 "=h,h"))
1073    (clobber (match_scratch:SI 5 "=X,1"))]
1074   "ISA_HAS_MSAC"
1076   if (which_alternative == 1)
1077     return "msac\t%0,%2,%3";
1078   else if (TARGET_MIPS5500)
1079     return "msub\t%2,%3";
1080   else
1081     return "msac\t$0,%2,%3";
1083   [(set_attr "type"     "imadd")
1084    (set_attr "mode"     "SI")])
1086 ;; An msac-like instruction implemented using negation and a macc.
1087 (define_insn_and_split "*msac_using_macc"
1088   [(set (match_operand:SI 0 "register_operand" "=l,d")
1089         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1090                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1091                            (match_operand:SI 3 "register_operand" "d,d"))))
1092    (clobber (match_scratch:SI 4 "=h,h"))
1093    (clobber (match_scratch:SI 5 "=X,1"))
1094    (clobber (match_scratch:SI 6 "=d,d"))]
1095   "ISA_HAS_MACC && !ISA_HAS_MSAC"
1096   "#"
1097   "&& reload_completed"
1098   [(set (match_dup 6)
1099         (neg:SI (match_dup 3)))
1100    (parallel
1101        [(set (match_dup 0)
1102              (plus:SI (mult:SI (match_dup 2)
1103                                (match_dup 6))
1104                       (match_dup 1)))
1105         (clobber (match_dup 4))
1106         (clobber (match_dup 5))])]
1107   ""
1108   [(set_attr "type"     "imadd")
1109    (set_attr "length"   "8")])
1111 ;; Patterns generated by the define_peephole2 below.
1113 (define_insn "*macc2"
1114   [(set (match_operand:SI 0 "register_operand" "=l")
1115         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1116                           (match_operand:SI 2 "register_operand" "d"))
1117                  (match_dup 0)))
1118    (set (match_operand:SI 3 "register_operand" "=d")
1119         (plus:SI (mult:SI (match_dup 1)
1120                           (match_dup 2))
1121                  (match_dup 0)))
1122    (clobber (match_scratch:SI 4 "=h"))]
1123   "ISA_HAS_MACC && reload_completed"
1124   "macc\t%3,%1,%2"
1125   [(set_attr "type"     "imadd")
1126    (set_attr "mode"     "SI")])
1128 (define_insn "*msac2"
1129   [(set (match_operand:SI 0 "register_operand" "=l")
1130         (minus:SI (match_dup 0)
1131                   (mult:SI (match_operand:SI 1 "register_operand" "d")
1132                            (match_operand:SI 2 "register_operand" "d"))))
1133    (set (match_operand:SI 3 "register_operand" "=d")
1134         (minus:SI (match_dup 0)
1135                   (mult:SI (match_dup 1)
1136                            (match_dup 2))))
1137    (clobber (match_scratch:SI 4 "=h"))]
1138   "ISA_HAS_MSAC && reload_completed"
1139   "msac\t%3,%1,%2"
1140   [(set_attr "type"     "imadd")
1141    (set_attr "mode"     "SI")])
1143 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1144 ;; Similarly msac.
1146 ;; Operand 0: LO
1147 ;; Operand 1: macc/msac
1148 ;; Operand 2: HI
1149 ;; Operand 3: GPR (destination)
1150 (define_peephole2
1151   [(parallel
1152        [(set (match_operand:SI 0 "register_operand")
1153              (match_operand:SI 1 "macc_msac_operand"))
1154         (clobber (match_operand:SI 2 "register_operand"))
1155         (clobber (scratch:SI))])
1156    (set (match_operand:SI 3 "register_operand")
1157         (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1158   ""
1159   [(parallel [(set (match_dup 0)
1160                    (match_dup 1))
1161               (set (match_dup 3)
1162                    (match_dup 1))
1163               (clobber (match_dup 2))])]
1164   "")
1166 ;; When we have a three-address multiplication instruction, it should
1167 ;; be faster to do a separate multiply and add, rather than moving
1168 ;; something into LO in order to use a macc instruction.
1170 ;; This peephole needs a scratch register to cater for the case when one
1171 ;; of the multiplication operands is the same as the destination.
1173 ;; Operand 0: GPR (scratch)
1174 ;; Operand 1: LO
1175 ;; Operand 2: GPR (addend)
1176 ;; Operand 3: GPR (destination)
1177 ;; Operand 4: macc/msac
1178 ;; Operand 5: HI
1179 ;; Operand 6: new multiplication
1180 ;; Operand 7: new addition/subtraction
1181 (define_peephole2
1182   [(match_scratch:SI 0 "d")
1183    (set (match_operand:SI 1 "register_operand")
1184         (match_operand:SI 2 "register_operand"))
1185    (match_dup 0)
1186    (parallel
1187        [(set (match_operand:SI 3 "register_operand")
1188              (match_operand:SI 4 "macc_msac_operand"))
1189         (clobber (match_operand:SI 5 "register_operand"))
1190         (clobber (match_dup 1))])]
1191   "GENERATE_MULT3_SI
1192    && true_regnum (operands[1]) == LO_REGNUM
1193    && peep2_reg_dead_p (2, operands[1])
1194    && GP_REG_P (true_regnum (operands[3]))"
1195   [(parallel [(set (match_dup 0)
1196                    (match_dup 6))
1197               (clobber (match_dup 5))
1198               (clobber (match_dup 1))])
1199    (set (match_dup 3)
1200         (match_dup 7))]
1202   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1203   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1204                                 operands[2], operands[0]);
1207 ;; Same as above, except LO is the initial target of the macc.
1209 ;; Operand 0: GPR (scratch)
1210 ;; Operand 1: LO
1211 ;; Operand 2: GPR (addend)
1212 ;; Operand 3: macc/msac
1213 ;; Operand 4: HI
1214 ;; Operand 5: GPR (destination)
1215 ;; Operand 6: new multiplication
1216 ;; Operand 7: new addition/subtraction
1217 (define_peephole2
1218   [(match_scratch:SI 0 "d")
1219    (set (match_operand:SI 1 "register_operand")
1220         (match_operand:SI 2 "register_operand"))
1221    (match_dup 0)
1222    (parallel
1223        [(set (match_dup 1)
1224              (match_operand:SI 3 "macc_msac_operand"))
1225         (clobber (match_operand:SI 4 "register_operand"))
1226         (clobber (scratch:SI))])
1227    (match_dup 0)
1228    (set (match_operand:SI 5 "register_operand")
1229         (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1230   "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1231   [(parallel [(set (match_dup 0)
1232                    (match_dup 6))
1233               (clobber (match_dup 4))
1234               (clobber (match_dup 1))])
1235    (set (match_dup 5)
1236         (match_dup 7))]
1238   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1239   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1240                                 operands[2], operands[0]);
1243 (define_insn "*mul_sub_si"
1244   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1245         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1246                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1247                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1248    (clobber (match_scratch:SI 4 "=h,h,h"))
1249    (clobber (match_scratch:SI 5 "=X,1,l"))
1250    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1251   "ISA_HAS_MADD_MSUB"
1252   "@
1253    msub\t%2,%3
1254    #
1255    #"
1256   [(set_attr "type"     "imadd,multi,multi")
1257    (set_attr "mode"     "SI")
1258    (set_attr "length"   "4,8,8")])
1260 ;; Split the above insn if we failed to get LO allocated.
1261 (define_split
1262   [(set (match_operand:SI 0 "register_operand")
1263         (minus:SI (match_operand:SI 1 "register_operand")
1264                   (mult:SI (match_operand:SI 2 "register_operand")
1265                            (match_operand:SI 3 "register_operand"))))
1266    (clobber (match_scratch:SI 4))
1267    (clobber (match_scratch:SI 5))
1268    (clobber (match_scratch:SI 6))]
1269   "reload_completed && !TARGET_DEBUG_D_MODE
1270    && GP_REG_P (true_regnum (operands[0]))
1271    && GP_REG_P (true_regnum (operands[1]))"
1272   [(parallel [(set (match_dup 6)
1273                    (mult:SI (match_dup 2) (match_dup 3)))
1274               (clobber (match_dup 4))
1275               (clobber (match_dup 5))])
1276    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1277   "")
1279 ;; Splitter to copy result of MSUB to a general register
1280 (define_split
1281   [(set (match_operand:SI 0 "register_operand")
1282         (minus:SI (match_operand:SI 1 "register_operand")
1283                   (mult:SI (match_operand:SI 2 "register_operand")
1284                            (match_operand:SI 3 "register_operand"))))
1285    (clobber (match_scratch:SI 4))
1286    (clobber (match_scratch:SI 5))
1287    (clobber (match_scratch:SI 6))]
1288   "reload_completed && !TARGET_DEBUG_D_MODE
1289    && GP_REG_P (true_regnum (operands[0]))
1290    && true_regnum (operands[1]) == LO_REGNUM"
1291   [(parallel [(set (match_dup 1)
1292                    (minus:SI (match_dup 1)
1293                              (mult:SI (match_dup 2) (match_dup 3))))
1294               (clobber (match_dup 4))
1295               (clobber (match_dup 5))
1296               (clobber (match_dup 6))])
1297    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1298   "")
1300 (define_insn "*muls"
1301   [(set (match_operand:SI                  0 "register_operand" "=l,d")
1302         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1303                          (match_operand:SI 2 "register_operand" "d,d"))))
1304    (clobber (match_scratch:SI              3                    "=h,h"))
1305    (clobber (match_scratch:SI              4                    "=X,l"))]
1306   "ISA_HAS_MULS"
1307   "@
1308    muls\t$0,%1,%2
1309    muls\t%0,%1,%2"
1310   [(set_attr "type"     "imul")
1311    (set_attr "mode"     "SI")])
1313 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1315 (define_expand "<u>mulsidi3"
1316   [(parallel
1317       [(set (match_operand:DI 0 "register_operand")
1318             (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1319                      (any_extend:DI (match_operand:SI 2 "register_operand"))))
1320        (clobber (scratch:DI))
1321        (clobber (scratch:DI))
1322        (clobber (scratch:DI))])]
1323   "!TARGET_64BIT || !TARGET_FIX_R4000"
1325   if (!TARGET_64BIT)
1326     {
1327       if (!TARGET_FIX_R4000)
1328         emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1329                                                    operands[2]));
1330       else
1331         emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1332                                                 operands[2]));
1333       DONE;
1334     }
1337 (define_insn "<u>mulsidi3_32bit_internal"
1338   [(set (match_operand:DI 0 "register_operand" "=x")
1339         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1340                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1341   "!TARGET_64BIT && !TARGET_FIX_R4000"
1342   "mult<u>\t%1,%2"
1343   [(set_attr "type" "imul")
1344    (set_attr "mode" "SI")])
1346 (define_insn "<u>mulsidi3_32bit_r4000"
1347   [(set (match_operand:DI 0 "register_operand" "=d")
1348         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1349                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1350    (clobber (match_scratch:DI 3 "=x"))]
1351   "!TARGET_64BIT && TARGET_FIX_R4000"
1352   "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1353   [(set_attr "type" "imul")
1354    (set_attr "mode" "SI")
1355    (set_attr "length" "12")])
1357 (define_insn_and_split "*<u>mulsidi3_64bit"
1358   [(set (match_operand:DI 0 "register_operand" "=d")
1359         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1360                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1361    (clobber (match_scratch:DI 3 "=l"))
1362    (clobber (match_scratch:DI 4 "=h"))
1363    (clobber (match_scratch:DI 5 "=d"))]
1364   "TARGET_64BIT && !TARGET_FIX_R4000"
1365   "#"
1366   "&& reload_completed"
1367   [(parallel
1368        [(set (match_dup 3)
1369              (sign_extend:DI
1370                 (mult:SI (match_dup 1)
1371                          (match_dup 2))))
1372         (set (match_dup 4)
1373              (ashiftrt:DI
1374                 (mult:DI (any_extend:DI (match_dup 1))
1375                          (any_extend:DI (match_dup 2)))
1376                 (const_int 32)))])
1378    ;; OP5 <- LO, OP0 <- HI
1379    (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1380    (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1382    ;; Zero-extend OP5.
1383    (set (match_dup 5)
1384         (ashift:DI (match_dup 5)
1385                    (const_int 32)))
1386    (set (match_dup 5)
1387         (lshiftrt:DI (match_dup 5)
1388                      (const_int 32)))
1390    ;; Shift OP0 into place.
1391    (set (match_dup 0)
1392         (ashift:DI (match_dup 0)
1393                    (const_int 32)))
1395    ;; OR the two halves together
1396    (set (match_dup 0)
1397         (ior:DI (match_dup 0)
1398                 (match_dup 5)))]
1399   ""
1400   [(set_attr "type" "imul")
1401    (set_attr "mode" "SI")
1402    (set_attr "length" "24")])
1404 (define_insn "*<u>mulsidi3_64bit_parts"
1405   [(set (match_operand:DI 0 "register_operand" "=l")
1406         (sign_extend:DI
1407            (mult:SI (match_operand:SI 2 "register_operand" "d")
1408                     (match_operand:SI 3 "register_operand" "d"))))
1409    (set (match_operand:DI 1 "register_operand" "=h")
1410         (ashiftrt:DI
1411            (mult:DI (any_extend:DI (match_dup 2))
1412                     (any_extend:DI (match_dup 3)))
1413            (const_int 32)))]
1414   "TARGET_64BIT && !TARGET_FIX_R4000"
1415   "mult<u>\t%2,%3"
1416   [(set_attr "type" "imul")
1417    (set_attr "mode" "SI")])
1419 ;; Widening multiply with negation.
1420 (define_insn "*muls<u>_di"
1421   [(set (match_operand:DI 0 "register_operand" "=x")
1422         (neg:DI
1423          (mult:DI
1424           (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1425           (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1426   "!TARGET_64BIT && ISA_HAS_MULS"
1427   "muls<u>\t$0,%1,%2"
1428   [(set_attr "type" "imul")
1429    (set_attr "mode" "SI")])
1431 (define_insn "*msac<u>_di"
1432   [(set (match_operand:DI 0 "register_operand" "=x")
1433         (minus:DI
1434            (match_operand:DI 3 "register_operand" "0")
1435            (mult:DI
1436               (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1437               (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1438   "!TARGET_64BIT && ISA_HAS_MSAC"
1440   if (TARGET_MIPS5500)
1441     return "msub<u>\t%1,%2";
1442   else
1443     return "msac<u>\t$0,%1,%2";
1445   [(set_attr "type" "imadd")
1446    (set_attr "mode" "SI")])
1448 ;; _highpart patterns
1450 (define_expand "<su>mulsi3_highpart"
1451   [(set (match_operand:SI 0 "register_operand")
1452         (truncate:SI
1453          (lshiftrt:DI
1454           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1455                    (any_extend:DI (match_operand:SI 2 "register_operand")))
1456           (const_int 32))))]
1457   "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1459   if (ISA_HAS_MULHI)
1460     emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1461                                                        operands[1],
1462                                                        operands[2]));
1463   else
1464     emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1465                                                  operands[2]));
1466   DONE;
1469 (define_insn "<su>mulsi3_highpart_internal"
1470   [(set (match_operand:SI 0 "register_operand" "=h")
1471         (truncate:SI
1472          (lshiftrt:DI
1473           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1474                    (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1475           (const_int 32))))
1476    (clobber (match_scratch:SI 3 "=l"))]
1477   "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1478   "mult<u>\t%1,%2"
1479   [(set_attr "type" "imul")
1480    (set_attr "mode" "SI")])
1482 (define_insn "<su>mulsi3_highpart_mulhi_internal"
1483   [(set (match_operand:SI 0 "register_operand" "=h,d")
1484         (truncate:SI
1485          (lshiftrt:DI
1486           (mult:DI
1487            (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1488            (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1489           (const_int 32))))
1490    (clobber (match_scratch:SI 3 "=l,l"))
1491    (clobber (match_scratch:SI 4 "=X,h"))]
1492   "ISA_HAS_MULHI"
1493   "@
1494    mult<u>\t%1,%2
1495    mulhi<u>\t%0,%1,%2"
1496   [(set_attr "type" "imul")
1497    (set_attr "mode" "SI")])
1499 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1500   [(set (match_operand:SI 0 "register_operand" "=h,d")
1501         (truncate:SI
1502          (lshiftrt:DI
1503           (neg:DI
1504            (mult:DI
1505             (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1506             (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1507           (const_int 32))))
1508    (clobber (match_scratch:SI 3 "=l,l"))
1509    (clobber (match_scratch:SI 4 "=X,h"))]
1510   "ISA_HAS_MULHI"
1511   "@
1512    mulshi<u>\t%.,%1,%2
1513    mulshi<u>\t%0,%1,%2"
1514   [(set_attr "type" "imul")
1515    (set_attr "mode" "SI")])
1517 ;; Disable unsigned multiplication for -mfix-vr4120.  This is for VR4120
1518 ;; errata MD(0), which says that dmultu does not always produce the
1519 ;; correct result.
1520 (define_insn "<su>muldi3_highpart"
1521   [(set (match_operand:DI 0 "register_operand" "=h")
1522         (truncate:DI
1523          (lshiftrt:TI
1524           (mult:TI
1525            (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1526            (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1527           (const_int 64))))
1528    (clobber (match_scratch:DI 3 "=l"))]
1529   "TARGET_64BIT && !TARGET_FIX_R4000
1530    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1531   "dmult<u>\t%1,%2"
1532   [(set_attr "type" "imul")
1533    (set_attr "mode" "DI")])
1535 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1536 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
1538 (define_insn "madsi"
1539   [(set (match_operand:SI 0 "register_operand" "+l")
1540         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1541                           (match_operand:SI 2 "register_operand" "d"))
1542                  (match_dup 0)))
1543    (clobber (match_scratch:SI 3 "=h"))]
1544   "TARGET_MAD"
1545   "mad\t%1,%2"
1546   [(set_attr "type"     "imadd")
1547    (set_attr "mode"     "SI")])
1549 (define_insn "*<su>mul_acc_di"
1550   [(set (match_operand:DI 0 "register_operand" "=x")
1551         (plus:DI
1552          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1553                   (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1554          (match_operand:DI 3 "register_operand" "0")))]
1555   "(TARGET_MAD || ISA_HAS_MACC)
1556    && !TARGET_64BIT"
1558   if (TARGET_MAD)
1559     return "mad<u>\t%1,%2";
1560   else if (TARGET_MIPS5500)
1561     return "madd<u>\t%1,%2";
1562   else
1563     /* See comment in *macc.  */
1564     return "%[macc<u>\t%@,%1,%2%]";
1566   [(set_attr "type" "imadd")
1567    (set_attr "mode" "SI")])
1569 ;; Floating point multiply accumulate instructions.
1571 (define_insn ""
1572   [(set (match_operand:DF 0 "register_operand" "=f")
1573         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1574                           (match_operand:DF 2 "register_operand" "f"))
1575                  (match_operand:DF 3 "register_operand" "f")))]
1576   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1577   "madd.d\t%0,%3,%1,%2"
1578   [(set_attr "type"     "fmadd")
1579    (set_attr "mode"     "DF")])
1581 (define_insn ""
1582   [(set (match_operand:SF 0 "register_operand" "=f")
1583         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1584                           (match_operand:SF 2 "register_operand" "f"))
1585                  (match_operand:SF 3 "register_operand" "f")))]
1586   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1587   "madd.s\t%0,%3,%1,%2"
1588   [(set_attr "type"     "fmadd")
1589    (set_attr "mode"     "SF")])
1591 (define_insn ""
1592   [(set (match_operand:DF 0 "register_operand" "=f")
1593         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1594                            (match_operand:DF 2 "register_operand" "f"))
1595                   (match_operand:DF 3 "register_operand" "f")))]
1596   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1597   "msub.d\t%0,%3,%1,%2"
1598   [(set_attr "type"     "fmadd")
1599    (set_attr "mode"     "DF")])
1601 (define_insn ""
1602   [(set (match_operand:SF 0 "register_operand" "=f")
1603         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1604                            (match_operand:SF 2 "register_operand" "f"))
1605                   (match_operand:SF 3 "register_operand" "f")))]
1607   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1608   "msub.s\t%0,%3,%1,%2"
1609   [(set_attr "type"     "fmadd")
1610    (set_attr "mode"     "SF")])
1612 (define_insn ""
1613   [(set (match_operand:DF 0 "register_operand" "=f")
1614         (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1615                                   (match_operand:DF 2 "register_operand" "f"))
1616                          (match_operand:DF 3 "register_operand" "f"))))]
1617   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1618    && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1619   "nmadd.d\t%0,%3,%1,%2"
1620   [(set_attr "type"     "fmadd")
1621    (set_attr "mode"     "DF")])
1623 (define_insn ""
1624   [(set (match_operand:DF 0 "register_operand" "=f")
1625         (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
1626                                    (match_operand:DF 2 "register_operand" "f"))
1627                   (match_operand:DF 3 "register_operand" "f")))]
1628   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1629    && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1630   "nmadd.d\t%0,%3,%1,%2"
1631   [(set_attr "type"     "fmadd")
1632    (set_attr "mode"     "DF")])
1634 (define_insn ""
1635   [(set (match_operand:SF 0 "register_operand" "=f")
1636         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1637                                   (match_operand:SF 2 "register_operand" "f"))
1638                          (match_operand:SF 3 "register_operand" "f"))))]
1639   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1640    && HONOR_SIGNED_ZEROS (SFmode)"
1641   "nmadd.s\t%0,%3,%1,%2"
1642   [(set_attr "type"     "fmadd")
1643    (set_attr "mode"     "SF")])
1645 (define_insn ""
1646   [(set (match_operand:SF 0 "register_operand" "=f")
1647         (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
1648                            (match_operand:SF 2 "register_operand" "f"))
1649                   (match_operand:SF 3 "register_operand" "f")))]
1650   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1651    && !HONOR_SIGNED_ZEROS (SFmode)"
1652   "nmadd.s\t%0,%3,%1,%2"
1653   [(set_attr "type"     "fmadd")
1654    (set_attr "mode"     "SF")])
1656 (define_insn ""
1657   [(set (match_operand:DF 0 "register_operand" "=f")
1658         (neg:DF (minus:DF (mult:DF (match_operand:DF 2 "register_operand" "f")
1659                                    (match_operand:DF 3 "register_operand" "f"))
1660                           (match_operand:DF 1 "register_operand" "f"))))]
1661   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1662    && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1663   "nmsub.d\t%0,%1,%2,%3"
1664   [(set_attr "type"     "fmadd")
1665    (set_attr "mode"     "DF")])
1667 (define_insn ""
1668   [(set (match_operand:DF 0 "register_operand" "=f")
1669         (minus:DF (match_operand:DF 1 "register_operand" "f")
1670                   (mult:DF (match_operand:DF 2 "register_operand" "f")
1671                            (match_operand:DF 3 "register_operand" "f"))))]
1672   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1673    && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1674   "nmsub.d\t%0,%1,%2,%3"
1675   [(set_attr "type"     "fmadd")
1676    (set_attr "mode"     "DF")])
1678 (define_insn ""
1679   [(set (match_operand:SF 0 "register_operand" "=f")
1680         (neg:SF (minus:SF (mult:SF (match_operand:SF 2 "register_operand" "f")
1681                                    (match_operand:SF 3 "register_operand" "f"))
1682                           (match_operand:SF 1 "register_operand" "f"))))]
1683   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1684    && HONOR_SIGNED_ZEROS (SFmode)"
1685   "nmsub.s\t%0,%1,%2,%3"
1686   [(set_attr "type"     "fmadd")
1687    (set_attr "mode"     "SF")])
1689 (define_insn ""
1690   [(set (match_operand:SF 0 "register_operand" "=f")
1691         (minus:SF (match_operand:SF 1 "register_operand" "f")
1692                   (mult:SF (match_operand:SF 2 "register_operand" "f")
1693                            (match_operand:SF 3 "register_operand" "f"))))]
1694   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1695    && !HONOR_SIGNED_ZEROS (SFmode)"
1696   "nmsub.s\t%0,%1,%2,%3"
1697   [(set_attr "type"     "fmadd")
1698    (set_attr "mode"     "SF")])
1701 ;;  ....................
1703 ;;      DIVISION and REMAINDER
1705 ;;  ....................
1708 (define_expand "divdf3"
1709   [(set (match_operand:DF 0 "register_operand")
1710         (div:DF (match_operand:DF 1 "reg_or_1_operand")
1711                 (match_operand:DF 2 "register_operand")))]
1712   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1714   if (const_1_operand (operands[1], DFmode))
1715     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1716       operands[1] = force_reg (DFmode, operands[1]);
1719 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
1721 ;; If an mfc1 or dmfc1 happens to access the floating point register
1722 ;; file at the same time a long latency operation (div, sqrt, recip,
1723 ;; sqrt) iterates an intermediate result back through the floating
1724 ;; point register file bypass, then instead returning the correct
1725 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1726 ;; result of the long latency operation.
1728 ;; The workaround is to insert an unconditional 'mov' from/to the
1729 ;; long latency op destination register.
1731 (define_insn "*divdf3"
1732   [(set (match_operand:DF 0 "register_operand" "=f")
1733         (div:DF (match_operand:DF 1 "register_operand" "f")
1734                 (match_operand:DF 2 "register_operand" "f")))]
1735   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1737   if (TARGET_FIX_SB1)
1738     return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
1739   else
1740     return "div.d\t%0,%1,%2";
1742   [(set_attr "type"     "fdiv")
1743    (set_attr "mode"     "DF")
1744    (set (attr "length")
1745         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1746                       (const_int 8)
1747                       (const_int 4)))])
1750 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
1752 ;; In certain cases, div.s and div.ps may have a rounding error
1753 ;; and/or wrong inexact flag.
1755 ;; Therefore, we only allow div.s if not working around SB-1 rev2
1756 ;; errata, or if working around those errata and a slight loss of
1757 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
1758 (define_expand "divsf3"
1759   [(set (match_operand:SF 0 "register_operand")
1760         (div:SF (match_operand:SF 1 "reg_or_1_operand")
1761                 (match_operand:SF 2 "register_operand")))]
1762   "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
1764   if (const_1_operand (operands[1], SFmode))
1765     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1766       operands[1] = force_reg (SFmode, operands[1]);
1769 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1770 ;; "divdf3" comment for details).
1772 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
1773 ;; "divsf3" comment for details).
1774 (define_insn "*divsf3"
1775   [(set (match_operand:SF 0 "register_operand" "=f")
1776         (div:SF (match_operand:SF 1 "register_operand" "f")
1777                 (match_operand:SF 2 "register_operand" "f")))]
1778   "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
1780   if (TARGET_FIX_SB1)
1781     return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
1782   else
1783     return "div.s\t%0,%1,%2";
1785   [(set_attr "type"     "fdiv")
1786    (set_attr "mode"     "SF")
1787    (set (attr "length")
1788         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1789                       (const_int 8)
1790                       (const_int 4)))])
1792 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1793 ;; "divdf3" comment for details).
1794 (define_insn ""
1795   [(set (match_operand:DF 0 "register_operand" "=f")
1796         (div:DF (match_operand:DF 1 "const_1_operand" "")
1797                 (match_operand:DF 2 "register_operand" "f")))]
1798   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
1800   if (TARGET_FIX_SB1)
1801     return "recip.d\t%0,%2\;mov.d\t%0,%0";
1802   else
1803     return "recip.d\t%0,%2";
1805   [(set_attr "type"     "frdiv")
1806    (set_attr "mode"     "DF")
1807    (set (attr "length")
1808         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1809                       (const_int 8)
1810                       (const_int 4)))])
1812 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1813 ;; "divdf3" comment for details).
1814 (define_insn ""
1815   [(set (match_operand:SF 0 "register_operand" "=f")
1816         (div:SF (match_operand:SF 1 "const_1_operand" "")
1817                 (match_operand:SF 2 "register_operand" "f")))]
1818   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
1820   if (TARGET_FIX_SB1)
1821     return "recip.s\t%0,%2\;mov.s\t%0,%0";
1822   else
1823     return "recip.s\t%0,%2";
1825   [(set_attr "type"     "frdiv")
1826    (set_attr "mode"     "SF")
1827    (set (attr "length")
1828         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1829                       (const_int 8)
1830                       (const_int 4)))])
1832 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
1833 ;; with negative operands.  We use special libgcc functions instead.
1834 (define_insn "divmod<mode>4"
1835   [(set (match_operand:GPR 0 "register_operand" "=l")
1836         (div:GPR (match_operand:GPR 1 "register_operand" "d")
1837                  (match_operand:GPR 2 "register_operand" "d")))
1838    (set (match_operand:GPR 3 "register_operand" "=h")
1839         (mod:GPR (match_dup 1)
1840                  (match_dup 2)))]
1841   "!TARGET_FIX_VR4120"
1842   { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1843   [(set_attr "type" "idiv")
1844    (set_attr "mode" "<MODE>")])
1846 (define_insn "udivmod<mode>4"
1847   [(set (match_operand:GPR 0 "register_operand" "=l")
1848         (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1849                   (match_operand:GPR 2 "register_operand" "d")))
1850    (set (match_operand:GPR 3 "register_operand" "=h")
1851         (umod:GPR (match_dup 1)
1852                   (match_dup 2)))]
1853   ""
1854   { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1855   [(set_attr "type" "idiv")
1856    (set_attr "mode" "<MODE>")])
1859 ;;  ....................
1861 ;;      SQUARE ROOT
1863 ;;  ....................
1865 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1866 ;; "divdf3" comment for details).
1867 (define_insn "sqrtdf2"
1868   [(set (match_operand:DF 0 "register_operand" "=f")
1869         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
1870   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
1872   if (TARGET_FIX_SB1)
1873     return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
1874   else
1875     return "sqrt.d\t%0,%1";
1877   [(set_attr "type"     "fsqrt")
1878    (set_attr "mode"     "DF")
1879    (set (attr "length")
1880         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1881                       (const_int 8)
1882                       (const_int 4)))])
1884 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1885 ;; "divdf3" comment for details).
1886 (define_insn "sqrtsf2"
1887   [(set (match_operand:SF 0 "register_operand" "=f")
1888         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
1889   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
1891   if (TARGET_FIX_SB1)
1892     return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
1893   else
1894     return "sqrt.s\t%0,%1";
1896   [(set_attr "type"     "fsqrt")
1897    (set_attr "mode"     "SF")
1898    (set (attr "length")
1899         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1900                       (const_int 8)
1901                       (const_int 4)))])
1903 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1904 ;; "divdf3" comment for details).
1905 (define_insn ""
1906   [(set (match_operand:DF 0 "register_operand" "=f")
1907         (div:DF (match_operand:DF 1 "const_1_operand" "")
1908                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
1909   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
1911   if (TARGET_FIX_SB1)
1912     return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
1913   else
1914     return "rsqrt.d\t%0,%2";
1916   [(set_attr "type"     "frsqrt")
1917    (set_attr "mode"     "DF")
1918    (set (attr "length")
1919         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1920                       (const_int 8)
1921                       (const_int 4)))])
1923 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1924 ;; "divdf3" comment for details).
1925 (define_insn ""
1926   [(set (match_operand:SF 0 "register_operand" "=f")
1927         (div:SF (match_operand:SF 1 "const_1_operand" "")
1928                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
1929   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
1931   if (TARGET_FIX_SB1)
1932     return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
1933   else
1934     return "rsqrt.s\t%0,%2";
1936   [(set_attr "type"     "frsqrt")
1937    (set_attr "mode"     "SF")
1938    (set (attr "length")
1939         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1940                       (const_int 8)
1941                       (const_int 4)))])
1943 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1944 ;; "divdf3" comment for details).
1945 (define_insn ""
1946   [(set (match_operand:DF 0 "register_operand" "=f")
1947         (sqrt:DF (div:DF (match_operand:DF 1 "const_1_operand" "")
1948                          (match_operand:DF 2 "register_operand" "f"))))]
1949   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
1951   if (TARGET_FIX_SB1)
1952     return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
1953   else
1954     return "rsqrt.d\t%0,%2";
1956   [(set_attr "type"     "frsqrt")
1957    (set_attr "mode"     "DF")
1958    (set (attr "length")
1959         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1960                       (const_int 8)
1961                       (const_int 4)))])
1963 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1964 ;; "divdf3" comment for details).
1965 (define_insn ""
1966   [(set (match_operand:SF 0 "register_operand" "=f")
1967         (sqrt:SF (div:SF (match_operand:SF 1 "const_1_operand" "")
1968                          (match_operand:SF 2 "register_operand" "f"))))]
1969   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
1971   if (TARGET_FIX_SB1)
1972     return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
1973   else
1974     return "rsqrt.s\t%0,%2";
1976   [(set_attr "type"     "frsqrt")
1977    (set_attr "mode"     "SF")
1978    (set (attr "length")
1979         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1980                       (const_int 8)
1981                       (const_int 4)))])
1984 ;;  ....................
1986 ;;      ABSOLUTE VALUE
1988 ;;  ....................
1990 ;; Do not use the integer abs macro instruction, since that signals an
1991 ;; exception on -2147483648 (sigh).
1993 (define_insn "abs<mode>2"
1994   [(set (match_operand:GPR 0 "register_operand" "=d")
1995         (abs:GPR (match_operand:GPR 1 "register_operand" "d")))]
1996   "!TARGET_MIPS16"
1998   if (REGNO (operands[0]) == REGNO (operands[1]) && GENERATE_BRANCHLIKELY)
1999     return "%(bltzl\t%1,1f\;<d>subu\t%0,%.,%0\n%~1:%)";
2000   else
2001     return "%(bgez\t%1,1f\;move\t%0,%1\;<d>subu\t%0,%.,%0\n%~1:%)";
2003   [(set_attr "type" "multi")
2004    (set_attr "mode" "<MODE>")
2005    (set_attr "length" "12")])
2007 (define_insn "absdf2"
2008   [(set (match_operand:DF 0 "register_operand" "=f")
2009         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2010   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2011   "abs.d\t%0,%1"
2012   [(set_attr "type"     "fabs")
2013    (set_attr "mode"     "DF")])
2015 (define_insn "abssf2"
2016   [(set (match_operand:SF 0 "register_operand" "=f")
2017         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2018   "TARGET_HARD_FLOAT"
2019   "abs.s\t%0,%1"
2020   [(set_attr "type"     "fabs")
2021    (set_attr "mode"     "SF")])
2024 ;;  ....................
2026 ;;      FIND FIRST BIT INSTRUCTION
2028 ;;  ....................
2031 (define_insn "ffs<mode>2"
2032   [(set (match_operand:GPR 0 "register_operand" "=&d")
2033         (ffs:GPR (match_operand:GPR 1 "register_operand" "d")))
2034    (clobber (match_scratch:GPR 2 "=&d"))
2035    (clobber (match_scratch:GPR 3 "=&d"))]
2036   "!TARGET_MIPS16"
2038   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2039     return "%(\
2040 move\t%0,%.\;\
2041 beq\t%1,%.,2f\n\
2042 %~1:\tand\t%2,%1,0x0001\;\
2043 <d>addu\t%0,%0,1\;\
2044 beq\t%2,%.,1b\;\
2045 <d>srl\t%1,%1,1\n\
2046 %~2:%)";
2048   return "%(\
2049 move\t%0,%.\;\
2050 move\t%3,%1\;\
2051 beq\t%3,%.,2f\n\
2052 %~1:\tand\t%2,%3,0x0001\;\
2053 <d>addu\t%0,%0,1\;\
2054 beq\t%2,%.,1b\;\
2055 <d>srl\t%3,%3,1\n\
2056 %~2:%)";
2058   [(set_attr "type" "multi")
2059    (set_attr "mode" "<MODE>")
2060    (set_attr "length" "28")])
2063 ;;  ...................
2065 ;;  Count leading zeroes.
2067 ;;  ...................
2070 (define_insn "clz<mode>2"
2071   [(set (match_operand:GPR 0 "register_operand" "=d")
2072         (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2073   "ISA_HAS_CLZ_CLO"
2074   "<d>clz\t%0,%1"
2075   [(set_attr "type" "clz")
2076    (set_attr "mode" "<MODE>")])
2079 ;;  ....................
2081 ;;      NEGATION and ONE'S COMPLEMENT
2083 ;;  ....................
2085 (define_insn "negsi2"
2086   [(set (match_operand:SI 0 "register_operand" "=d")
2087         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2088   ""
2090   if (TARGET_MIPS16)
2091     return "neg\t%0,%1";
2092   else
2093     return "subu\t%0,%.,%1";
2095   [(set_attr "type"     "arith")
2096    (set_attr "mode"     "SI")])
2098 (define_insn "negdi2"
2099   [(set (match_operand:DI 0 "register_operand" "=d")
2100         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2101   "TARGET_64BIT && !TARGET_MIPS16"
2102   "dsubu\t%0,%.,%1"
2103   [(set_attr "type"     "arith")
2104    (set_attr "mode"     "DI")])
2106 (define_insn "negdf2"
2107   [(set (match_operand:DF 0 "register_operand" "=f")
2108         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2109   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2110   "neg.d\t%0,%1"
2111   [(set_attr "type"     "fneg")
2112    (set_attr "mode"     "DF")])
2114 (define_insn "negsf2"
2115   [(set (match_operand:SF 0 "register_operand" "=f")
2116         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2117   "TARGET_HARD_FLOAT"
2118   "neg.s\t%0,%1"
2119   [(set_attr "type"     "fneg")
2120    (set_attr "mode"     "SF")])
2122 (define_insn "one_cmpl<mode>2"
2123   [(set (match_operand:GPR 0 "register_operand" "=d")
2124         (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2125   ""
2127   if (TARGET_MIPS16)
2128     return "not\t%0,%1";
2129   else
2130     return "nor\t%0,%.,%1";
2132   [(set_attr "type" "arith")
2133    (set_attr "mode" "<MODE>")])
2136 ;;  ....................
2138 ;;      LOGICAL
2140 ;;  ....................
2143 ;; Many of these instructions use trivial define_expands, because we
2144 ;; want to use a different set of constraints when TARGET_MIPS16.
2146 (define_expand "and<mode>3"
2147   [(set (match_operand:GPR 0 "register_operand")
2148         (and:GPR (match_operand:GPR 1 "register_operand")
2149                  (match_operand:GPR 2 "uns_arith_operand")))]
2150   ""
2152   if (TARGET_MIPS16)
2153     operands[2] = force_reg (<MODE>mode, operands[2]);
2156 (define_insn "*and<mode>3"
2157   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2158         (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2159                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2160   "!TARGET_MIPS16"
2161   "@
2162    and\t%0,%1,%2
2163    andi\t%0,%1,%x2"
2164   [(set_attr "type" "arith")
2165    (set_attr "mode" "<MODE>")])
2167 (define_insn "*and<mode>3_mips16"
2168   [(set (match_operand:GPR 0 "register_operand" "=d")
2169         (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2170                  (match_operand:GPR 2 "register_operand" "d")))]
2171   "TARGET_MIPS16"
2172   "and\t%0,%2"
2173   [(set_attr "type" "arith")
2174    (set_attr "mode" "<MODE>")])
2176 (define_expand "ior<mode>3"
2177   [(set (match_operand:GPR 0 "register_operand")
2178         (ior:GPR (match_operand:GPR 1 "register_operand")
2179                  (match_operand:GPR 2 "uns_arith_operand")))]
2180   ""
2182   if (TARGET_MIPS16)
2183     operands[2] = force_reg (<MODE>mode, operands[2]);
2186 (define_insn "*ior<mode>3"
2187   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2188         (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2189                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2190   "!TARGET_MIPS16"
2191   "@
2192    or\t%0,%1,%2
2193    ori\t%0,%1,%x2"
2194   [(set_attr "type" "arith")
2195    (set_attr "mode" "<MODE>")])
2197 (define_insn "*ior<mode>3_mips16"
2198   [(set (match_operand:GPR 0 "register_operand" "=d")
2199         (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2200                  (match_operand:GPR 2 "register_operand" "d")))]
2201   "TARGET_MIPS16"
2202   "or\t%0,%2"
2203   [(set_attr "type" "arith")
2204    (set_attr "mode" "<MODE>")])
2206 (define_expand "xor<mode>3"
2207   [(set (match_operand:GPR 0 "register_operand")
2208         (xor:GPR (match_operand:GPR 1 "register_operand")
2209                  (match_operand:GPR 2 "uns_arith_operand")))]
2210   ""
2211   "")
2213 (define_insn ""
2214   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2215         (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2216                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2217   "!TARGET_MIPS16"
2218   "@
2219    xor\t%0,%1,%2
2220    xori\t%0,%1,%x2"
2221   [(set_attr "type" "arith")
2222    (set_attr "mode" "<MODE>")])
2224 (define_insn ""
2225   [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2226         (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2227                  (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2228   "TARGET_MIPS16"
2229   "@
2230    xor\t%0,%2
2231    cmpi\t%1,%2
2232    cmp\t%1,%2"
2233   [(set_attr "type" "arith")
2234    (set_attr "mode" "<MODE>")
2235    (set_attr_alternative "length"
2236                 [(const_int 4)
2237                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2238                                (const_int 4)
2239                                (const_int 8))
2240                  (const_int 4)])])
2242 (define_insn "*nor<mode>3"
2243   [(set (match_operand:GPR 0 "register_operand" "=d")
2244         (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2245                  (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2246   "!TARGET_MIPS16"
2247   "nor\t%0,%1,%2"
2248   [(set_attr "type" "arith")
2249    (set_attr "mode" "<MODE>")])
2252 ;;  ....................
2254 ;;      TRUNCATION
2256 ;;  ....................
2260 (define_insn "truncdfsf2"
2261   [(set (match_operand:SF 0 "register_operand" "=f")
2262         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2263   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2264   "cvt.s.d\t%0,%1"
2265   [(set_attr "type"     "fcvt")
2266    (set_attr "mode"     "SF")])
2268 ;; Integer truncation patterns.  Truncating SImode values to smaller
2269 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
2270 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2271 ;; need to make sure that the lower 32 bits are properly sign-extended
2272 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2273 ;; smaller than SImode is equivalent to two separate truncations:
2275 ;;                        A       B
2276 ;;    DI ---> HI  ==  DI ---> SI ---> HI
2277 ;;    DI ---> QI  ==  DI ---> SI ---> QI
2279 ;; Step A needs a real instruction but step B does not.
2281 (define_insn "truncdisi2"
2282   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2283         (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2284   "TARGET_64BIT"
2285   "@
2286     sll\t%0,%1,0
2287     sw\t%1,%0"
2288   [(set_attr "type" "shift,store")
2289    (set_attr "mode" "SI")
2290    (set_attr "extended_mips16" "yes,*")])
2292 (define_insn "truncdihi2"
2293   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2294         (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2295   "TARGET_64BIT"
2296   "@
2297     sll\t%0,%1,0
2298     sh\t%1,%0"
2299   [(set_attr "type" "shift,store")
2300    (set_attr "mode" "SI")
2301    (set_attr "extended_mips16" "yes,*")])
2303 (define_insn "truncdiqi2"
2304   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2305         (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2306   "TARGET_64BIT"
2307   "@
2308     sll\t%0,%1,0
2309     sb\t%1,%0"
2310   [(set_attr "type" "shift,store")
2311    (set_attr "mode" "SI")
2312    (set_attr "extended_mips16" "yes,*")])
2314 ;; Combiner patterns to optimize shift/truncate combinations.
2316 (define_insn ""
2317   [(set (match_operand:SI 0 "register_operand" "=d")
2318         (truncate:SI
2319           (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2320                        (match_operand:DI 2 "const_arith_operand" ""))))]
2321   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2322   "dsra\t%0,%1,%2"
2323   [(set_attr "type" "shift")
2324    (set_attr "mode" "SI")])
2326 (define_insn ""
2327   [(set (match_operand:SI 0 "register_operand" "=d")
2328         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2329                                   (const_int 32))))]
2330   "TARGET_64BIT && !TARGET_MIPS16"
2331   "dsra\t%0,%1,32"
2332   [(set_attr "type" "shift")
2333    (set_attr "mode" "SI")])
2336 ;; Combiner patterns for truncate/sign_extend combinations.  They use
2337 ;; the shift/truncate patterns above.
2339 (define_insn_and_split ""
2340   [(set (match_operand:SI 0 "register_operand" "=d")
2341         (sign_extend:SI
2342             (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2343   "TARGET_64BIT && !TARGET_MIPS16"
2344   "#"
2345   "&& reload_completed"
2346   [(set (match_dup 2)
2347         (ashift:DI (match_dup 1)
2348                    (const_int 48)))
2349    (set (match_dup 0)
2350         (truncate:SI (ashiftrt:DI (match_dup 2)
2351                                   (const_int 48))))]
2352   { operands[2] = gen_lowpart (DImode, operands[0]); })
2354 (define_insn_and_split ""
2355   [(set (match_operand:SI 0 "register_operand" "=d")
2356         (sign_extend:SI
2357             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2358   "TARGET_64BIT && !TARGET_MIPS16"
2359   "#"
2360   "&& reload_completed"
2361   [(set (match_dup 2)
2362         (ashift:DI (match_dup 1)
2363                    (const_int 56)))
2364    (set (match_dup 0)
2365         (truncate:SI (ashiftrt:DI (match_dup 2)
2366                                   (const_int 56))))]
2367   { operands[2] = gen_lowpart (DImode, operands[0]); })
2370 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2372 (define_insn ""
2373   [(set (match_operand:SI 0 "register_operand" "=d")
2374         (zero_extend:SI (truncate:HI
2375                          (match_operand:DI 1 "register_operand" "d"))))]
2376   "TARGET_64BIT && !TARGET_MIPS16"
2377   "andi\t%0,%1,0xffff"
2378   [(set_attr "type"     "arith")
2379    (set_attr "mode"     "SI")])
2381 (define_insn ""
2382   [(set (match_operand:SI 0 "register_operand" "=d")
2383         (zero_extend:SI (truncate:QI
2384                          (match_operand:DI 1 "register_operand" "d"))))]
2385   "TARGET_64BIT && !TARGET_MIPS16"
2386   "andi\t%0,%1,0xff"
2387   [(set_attr "type"     "arith")
2388    (set_attr "mode"     "SI")])
2390 (define_insn ""
2391   [(set (match_operand:HI 0 "register_operand" "=d")
2392         (zero_extend:HI (truncate:QI
2393                          (match_operand:DI 1 "register_operand" "d"))))]
2394   "TARGET_64BIT && !TARGET_MIPS16"
2395   "andi\t%0,%1,0xff"
2396   [(set_attr "type"     "arith")
2397    (set_attr "mode"     "HI")])
2400 ;;  ....................
2402 ;;      ZERO EXTENSION
2404 ;;  ....................
2406 ;; Extension insns.
2407 ;; Those for integer source operand are ordered widest source type first.
2409 (define_insn_and_split "zero_extendsidi2"
2410   [(set (match_operand:DI 0 "register_operand" "=d")
2411         (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2412   "TARGET_64BIT"
2413   "#"
2414   "&& reload_completed"
2415   [(set (match_dup 0)
2416         (ashift:DI (match_dup 1) (const_int 32)))
2417    (set (match_dup 0)
2418         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2419   "operands[1] = gen_lowpart (DImode, operands[1]);"
2420   [(set_attr "type" "multi")
2421    (set_attr "mode" "DI")
2422    (set_attr "length" "8")])
2424 (define_insn "*zero_extendsidi2_mem"
2425   [(set (match_operand:DI 0 "register_operand" "=d")
2426         (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2427   "TARGET_64BIT"
2428   "lwu\t%0,%1"
2429   [(set_attr "type"     "load")
2430    (set_attr "mode"     "DI")])
2432 (define_expand "zero_extendhisi2"
2433   [(set (match_operand:SI 0 "register_operand")
2434         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2435   ""
2437   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2438     {
2439       rtx op = gen_lowpart (SImode, operands[1]);
2440       rtx temp = force_reg (SImode, GEN_INT (0xffff));
2442       emit_insn (gen_andsi3 (operands[0], op, temp));
2443       DONE;
2444     }
2447 (define_insn ""
2448   [(set (match_operand:SI 0 "register_operand" "=d,d")
2449         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2450   "!TARGET_MIPS16"
2451   "@
2452    andi\t%0,%1,0xffff
2453    lhu\t%0,%1"
2454   [(set_attr "type"     "arith,load")
2455    (set_attr "mode"     "SI")
2456    (set_attr "length"   "4,*")])
2458 (define_insn ""
2459   [(set (match_operand:SI 0 "register_operand" "=d")
2460         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2461   "TARGET_MIPS16"
2462   "lhu\t%0,%1"
2463   [(set_attr "type"     "load")
2464    (set_attr "mode"     "SI")])
2466 (define_expand "zero_extendhidi2"
2467   [(set (match_operand:DI 0 "register_operand")
2468         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2469   "TARGET_64BIT"
2471   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2472     {
2473       rtx op = gen_lowpart (DImode, operands[1]);
2474       rtx temp = force_reg (DImode, GEN_INT (0xffff));
2476       emit_insn (gen_anddi3 (operands[0], op, temp));
2477       DONE;
2478     }
2481 (define_insn ""
2482   [(set (match_operand:DI 0 "register_operand" "=d,d")
2483         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2484   "TARGET_64BIT && !TARGET_MIPS16"
2485   "@
2486    andi\t%0,%1,0xffff
2487    lhu\t%0,%1"
2488   [(set_attr "type"     "arith,load")
2489    (set_attr "mode"     "DI")
2490    (set_attr "length"   "4,*")])
2492 (define_insn ""
2493   [(set (match_operand:DI 0 "register_operand" "=d")
2494         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2495   "TARGET_64BIT && TARGET_MIPS16"
2496   "lhu\t%0,%1"
2497   [(set_attr "type"     "load")
2498    (set_attr "mode"     "DI")])
2500 (define_expand "zero_extendqihi2"
2501   [(set (match_operand:HI 0 "register_operand")
2502         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2503   ""
2505   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2506     {
2507       rtx op0 = gen_lowpart (SImode, operands[0]);
2508       rtx op1 = gen_lowpart (SImode, operands[1]);
2509       rtx temp = force_reg (SImode, GEN_INT (0xff));
2511       emit_insn (gen_andsi3 (op0, op1, temp));
2512       DONE;
2513     }
2516 (define_insn ""
2517   [(set (match_operand:HI 0 "register_operand" "=d,d")
2518         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2519   "!TARGET_MIPS16"
2520   "@
2521    andi\t%0,%1,0x00ff
2522    lbu\t%0,%1"
2523   [(set_attr "type"     "arith,load")
2524    (set_attr "mode"     "HI")
2525    (set_attr "length"   "4,*")])
2527 (define_insn ""
2528   [(set (match_operand:HI 0 "register_operand" "=d")
2529         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2530   "TARGET_MIPS16"
2531   "lbu\t%0,%1"
2532   [(set_attr "type"     "load")
2533    (set_attr "mode"     "HI")])
2535 (define_expand "zero_extendqisi2"
2536   [(set (match_operand:SI 0 "register_operand")
2537         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2538   ""
2540   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2541     {
2542       rtx op = gen_lowpart (SImode, operands[1]);
2543       rtx temp = force_reg (SImode, GEN_INT (0xff));
2545       emit_insn (gen_andsi3 (operands[0], op, temp));
2546       DONE;
2547     }
2550 (define_insn ""
2551   [(set (match_operand:SI 0 "register_operand" "=d,d")
2552         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2553   "!TARGET_MIPS16"
2554   "@
2555    andi\t%0,%1,0x00ff
2556    lbu\t%0,%1"
2557   [(set_attr "type"     "arith,load")
2558    (set_attr "mode"     "SI")
2559    (set_attr "length"   "4,*")])
2561 (define_insn ""
2562   [(set (match_operand:SI 0 "register_operand" "=d")
2563         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2564   "TARGET_MIPS16"
2565   "lbu\t%0,%1"
2566   [(set_attr "type"     "load")
2567    (set_attr "mode"     "SI")])
2569 (define_expand "zero_extendqidi2"
2570   [(set (match_operand:DI 0 "register_operand")
2571         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2572   "TARGET_64BIT"
2574   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2575     {
2576       rtx op = gen_lowpart (DImode, operands[1]);
2577       rtx temp = force_reg (DImode, GEN_INT (0xff));
2579       emit_insn (gen_anddi3 (operands[0], op, temp));
2580       DONE;
2581     }
2584 (define_insn ""
2585   [(set (match_operand:DI 0 "register_operand" "=d,d")
2586         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2587   "TARGET_64BIT && !TARGET_MIPS16"
2588   "@
2589    andi\t%0,%1,0x00ff
2590    lbu\t%0,%1"
2591   [(set_attr "type"     "arith,load")
2592    (set_attr "mode"     "DI")
2593    (set_attr "length"   "4,*")])
2595 (define_insn ""
2596   [(set (match_operand:DI 0 "register_operand" "=d")
2597         (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2598   "TARGET_64BIT && TARGET_MIPS16"
2599   "lbu\t%0,%1"
2600   [(set_attr "type"     "load")
2601    (set_attr "mode"     "DI")])
2604 ;;  ....................
2606 ;;      SIGN EXTENSION
2608 ;;  ....................
2610 ;; Extension insns.
2611 ;; Those for integer source operand are ordered widest source type first.
2613 ;; When TARGET_64BIT, all SImode integer registers should already be in
2614 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can
2615 ;; therefore get rid of register->register instructions if we constrain
2616 ;; the source to be in the same register as the destination.
2618 ;; The register alternative has type "arith" so that the pre-reload
2619 ;; scheduler will treat it as a move.  This reflects what happens if
2620 ;; the register alternative needs a reload.
2621 (define_insn_and_split "extendsidi2"
2622   [(set (match_operand:DI 0 "register_operand" "=d,d")
2623         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2624   "TARGET_64BIT"
2625   "@
2626    #
2627    lw\t%0,%1"
2628   "&& reload_completed && register_operand (operands[1], VOIDmode)"
2629   [(const_int 0)]
2631   emit_note (NOTE_INSN_DELETED);
2632   DONE;
2634   [(set_attr "type" "arith,load")
2635    (set_attr "mode" "DI")])
2637 ;; These patterns originally accepted general_operands, however, slightly
2638 ;; better code is generated by only accepting register_operands, and then
2639 ;; letting combine generate the lh and lb insns.
2641 ;; These expanders originally put values in registers first. We split
2642 ;; all non-mem patterns after reload.
2644 (define_expand "extendhidi2"
2645   [(set (match_operand:DI 0 "register_operand")
2646         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2647   "TARGET_64BIT"
2648   "")
2650 (define_insn "*extendhidi2"
2651   [(set (match_operand:DI 0 "register_operand" "=d")
2652         (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
2653   "TARGET_64BIT"
2654   "#")
2656 (define_split
2657   [(set (match_operand:DI 0 "register_operand")
2658         (sign_extend:DI (match_operand:HI 1 "register_operand")))]
2659   "TARGET_64BIT && reload_completed"
2660   [(set (match_dup 0)
2661         (ashift:DI (match_dup 1) (const_int 48)))
2662    (set (match_dup 0)
2663         (ashiftrt:DI (match_dup 0) (const_int 48)))]
2664   "operands[1] = gen_lowpart (DImode, operands[1]);")
2666 (define_insn "*extendhidi2_mem"
2667   [(set (match_operand:DI 0 "register_operand" "=d")
2668         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2669   "TARGET_64BIT"
2670   "lh\t%0,%1"
2671   [(set_attr "type"     "load")
2672    (set_attr "mode"     "DI")])
2674 (define_expand "extendhisi2"
2675   [(set (match_operand:SI 0 "register_operand")
2676         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2677   ""
2679   if (ISA_HAS_SEB_SEH)
2680     {
2681       emit_insn (gen_extendhisi2_hw (operands[0],
2682                                      force_reg (HImode, operands[1])));
2683       DONE;
2684     }
2687 (define_insn "*extendhisi2"
2688   [(set (match_operand:SI 0 "register_operand" "=d")
2689         (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
2690   ""
2691   "#")
2693 (define_split
2694   [(set (match_operand:SI 0 "register_operand")
2695         (sign_extend:SI (match_operand:HI 1 "register_operand")))]
2696   "reload_completed"
2697   [(set (match_dup 0)
2698         (ashift:SI (match_dup 1) (const_int 16)))
2699    (set (match_dup 0)
2700         (ashiftrt:SI (match_dup 0) (const_int 16)))]
2701   "operands[1] = gen_lowpart (SImode, operands[1]);")
2703 (define_insn "extendhisi2_mem"
2704   [(set (match_operand:SI 0 "register_operand" "=d")
2705         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2706   ""
2707   "lh\t%0,%1"
2708   [(set_attr "type"     "load")
2709    (set_attr "mode"     "SI")])
2711 (define_insn "extendhisi2_hw"
2712   [(set (match_operand:SI 0 "register_operand" "=r")
2713         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
2714   "ISA_HAS_SEB_SEH"
2715   "seh\t%0,%1"
2716   [(set_attr "type" "arith")
2717    (set_attr "mode" "SI")])
2719 (define_expand "extendqihi2"
2720   [(set (match_operand:HI 0 "register_operand")
2721         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2722   ""
2723   "")
2725 (define_insn "*extendqihi2"
2726   [(set (match_operand:HI 0 "register_operand" "=d")
2727         (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
2728   ""
2729   "#")
2731 (define_split
2732   [(set (match_operand:HI 0 "register_operand")
2733         (sign_extend:HI (match_operand:QI 1 "register_operand")))]
2734   "reload_completed"
2735   [(set (match_dup 0)
2736         (ashift:SI (match_dup 1) (const_int 24)))
2737    (set (match_dup 0)
2738         (ashiftrt:SI (match_dup 0) (const_int 24)))]
2739   "operands[0] = gen_lowpart (SImode, operands[0]);
2740    operands[1] = gen_lowpart (SImode, operands[1]);")
2742 (define_insn "*extendqihi2_internal_mem"
2743   [(set (match_operand:HI 0 "register_operand" "=d")
2744         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2745   ""
2746   "lb\t%0,%1"
2747   [(set_attr "type"     "load")
2748    (set_attr "mode"     "SI")])
2751 (define_expand "extendqisi2"
2752   [(set (match_operand:SI 0 "register_operand")
2753         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2754   ""
2756   if (ISA_HAS_SEB_SEH)
2757     {
2758       emit_insn (gen_extendqisi2_hw (operands[0],
2759                                      force_reg (QImode, operands[1])));
2760       DONE;
2761     }
2764 (define_insn "*extendqisi2"
2765   [(set (match_operand:SI 0 "register_operand" "=d")
2766         (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
2767   ""
2768   "#")
2770 (define_split
2771   [(set (match_operand:SI 0 "register_operand")
2772         (sign_extend:SI (match_operand:QI 1 "register_operand")))]
2773   "reload_completed"
2774   [(set (match_dup 0)
2775         (ashift:SI (match_dup 1) (const_int 24)))
2776    (set (match_dup 0)
2777         (ashiftrt:SI (match_dup 0) (const_int 24)))]
2778   "operands[1] = gen_lowpart (SImode, operands[1]);")
2780 (define_insn "*extendqisi2_mem"
2781   [(set (match_operand:SI 0 "register_operand" "=d")
2782         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2783   ""
2784   "lb\t%0,%1"
2785   [(set_attr "type"     "load")
2786    (set_attr "mode"     "SI")])
2788 (define_insn "extendqisi2_hw"
2789   [(set (match_operand:SI 0 "register_operand" "=r")
2790         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
2791   "ISA_HAS_SEB_SEH"
2792   "seb\t%0,%1"
2793   [(set_attr "type" "arith")
2794    (set_attr "mode" "SI")])
2796 (define_expand "extendqidi2"
2797   [(set (match_operand:DI 0 "register_operand")
2798         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2799   "TARGET_64BIT"
2800   "")
2802 (define_insn "*extendqidi2"
2803   [(set (match_operand:DI 0 "register_operand" "=d")
2804         (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
2805   "TARGET_64BIT"
2806   "#")
2808 (define_split
2809   [(set (match_operand:DI 0 "register_operand")
2810         (sign_extend:DI (match_operand:QI 1 "register_operand")))]
2811   "TARGET_64BIT && reload_completed"
2812   [(set (match_dup 0)
2813         (ashift:DI (match_dup 1) (const_int 56)))
2814    (set (match_dup 0)
2815         (ashiftrt:DI (match_dup 0) (const_int 56)))]
2816   "operands[1] = gen_lowpart (DImode, operands[1]);")
2818 (define_insn "*extendqidi2_mem"
2819   [(set (match_operand:DI 0 "register_operand" "=d")
2820         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2821   "TARGET_64BIT"
2822   "lb\t%0,%1"
2823   [(set_attr "type"     "load")
2824    (set_attr "mode"     "DI")])
2826 (define_insn "extendsfdf2"
2827   [(set (match_operand:DF 0 "register_operand" "=f")
2828         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2829   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2830   "cvt.d.s\t%0,%1"
2831   [(set_attr "type"     "fcvt")
2832    (set_attr "mode"     "DF")])
2835 ;;  ....................
2837 ;;      CONVERSIONS
2839 ;;  ....................
2841 (define_expand "fix_truncdfsi2"
2842   [(set (match_operand:SI 0 "register_operand")
2843         (fix:SI (match_operand:DF 1 "register_operand")))]
2844   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2846   if (!ISA_HAS_TRUNC_W)
2847     {
2848       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2849       DONE;
2850     }
2853 (define_insn "fix_truncdfsi2_insn"
2854   [(set (match_operand:SI 0 "register_operand" "=f")
2855         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2856   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2857   "trunc.w.d %0,%1"
2858   [(set_attr "type"     "fcvt")
2859    (set_attr "mode"     "DF")
2860    (set_attr "length"   "4")])
2862 (define_insn "fix_truncdfsi2_macro"
2863   [(set (match_operand:SI 0 "register_operand" "=f")
2864         (fix:SI (match_operand:DF 1 "register_operand" "f")))
2865    (clobber (match_scratch:DF 2 "=d"))]
2866   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2868   if (set_nomacro)
2869     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2870   else
2871     return "trunc.w.d %0,%1,%2";
2873   [(set_attr "type"     "fcvt")
2874    (set_attr "mode"     "DF")
2875    (set_attr "length"   "36")])
2877 (define_expand "fix_truncsfsi2"
2878   [(set (match_operand:SI 0 "register_operand")
2879         (fix:SI (match_operand:SF 1 "register_operand")))]
2880   "TARGET_HARD_FLOAT"
2882   if (!ISA_HAS_TRUNC_W)
2883     {
2884       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2885       DONE;
2886     }
2889 (define_insn "fix_truncsfsi2_insn"
2890   [(set (match_operand:SI 0 "register_operand" "=f")
2891         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2892   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2893   "trunc.w.s %0,%1"
2894   [(set_attr "type"     "fcvt")
2895    (set_attr "mode"     "DF")
2896    (set_attr "length"   "4")])
2898 (define_insn "fix_truncsfsi2_macro"
2899   [(set (match_operand:SI 0 "register_operand" "=f")
2900         (fix:SI (match_operand:SF 1 "register_operand" "f")))
2901    (clobber (match_scratch:SF 2 "=d"))]
2902   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2904   if (set_nomacro)
2905     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2906   else
2907     return "trunc.w.s %0,%1,%2";
2909   [(set_attr "type"     "fcvt")
2910    (set_attr "mode"     "DF")
2911    (set_attr "length"   "36")])
2914 (define_insn "fix_truncdfdi2"
2915   [(set (match_operand:DI 0 "register_operand" "=f")
2916         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2917   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2918   "trunc.l.d %0,%1"
2919   [(set_attr "type"     "fcvt")
2920    (set_attr "mode"     "DF")
2921    (set_attr "length"   "4")])
2924 (define_insn "fix_truncsfdi2"
2925   [(set (match_operand:DI 0 "register_operand" "=f")
2926         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2927   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2928   "trunc.l.s %0,%1"
2929   [(set_attr "type"     "fcvt")
2930    (set_attr "mode"     "SF")
2931    (set_attr "length"   "4")])
2934 (define_insn "floatsidf2"
2935   [(set (match_operand:DF 0 "register_operand" "=f")
2936         (float:DF (match_operand:SI 1 "register_operand" "f")))]
2937   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2938   "cvt.d.w\t%0,%1"
2939   [(set_attr "type"     "fcvt")
2940    (set_attr "mode"     "DF")
2941    (set_attr "length"   "4")])
2944 (define_insn "floatdidf2"
2945   [(set (match_operand:DF 0 "register_operand" "=f")
2946         (float:DF (match_operand:DI 1 "register_operand" "f")))]
2947   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2948   "cvt.d.l\t%0,%1"
2949   [(set_attr "type"     "fcvt")
2950    (set_attr "mode"     "DF")
2951    (set_attr "length"   "4")])
2954 (define_insn "floatsisf2"
2955   [(set (match_operand:SF 0 "register_operand" "=f")
2956         (float:SF (match_operand:SI 1 "register_operand" "f")))]
2957   "TARGET_HARD_FLOAT"
2958   "cvt.s.w\t%0,%1"
2959   [(set_attr "type"     "fcvt")
2960    (set_attr "mode"     "SF")
2961    (set_attr "length"   "4")])
2964 (define_insn "floatdisf2"
2965   [(set (match_operand:SF 0 "register_operand" "=f")
2966         (float:SF (match_operand:DI 1 "register_operand" "f")))]
2967   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2968   "cvt.s.l\t%0,%1"
2969   [(set_attr "type"     "fcvt")
2970    (set_attr "mode"     "SF")
2971    (set_attr "length"   "4")])
2974 (define_expand "fixuns_truncdfsi2"
2975   [(set (match_operand:SI 0 "register_operand")
2976         (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2977   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2979   rtx reg1 = gen_reg_rtx (DFmode);
2980   rtx reg2 = gen_reg_rtx (DFmode);
2981   rtx reg3 = gen_reg_rtx (SImode);
2982   rtx label1 = gen_label_rtx ();
2983   rtx label2 = gen_label_rtx ();
2984   REAL_VALUE_TYPE offset;
2986   real_2expN (&offset, 31);
2988   if (reg1)                     /* Turn off complaints about unreached code.  */
2989     {
2990       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2991       do_pending_stack_adjust ();
2993       emit_insn (gen_cmpdf (operands[1], reg1));
2994       emit_jump_insn (gen_bge (label1));
2996       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2997       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2998                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
2999       emit_barrier ();
3001       emit_label (label1);
3002       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3003       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3004                                      (BITMASK_HIGH, SImode)));
3006       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3007       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3009       emit_label (label2);
3011       /* Allow REG_NOTES to be set on last insn (labels don't have enough
3012          fields, and can't be used for REG_NOTES anyway).  */
3013       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3014       DONE;
3015     }
3019 (define_expand "fixuns_truncdfdi2"
3020   [(set (match_operand:DI 0 "register_operand")
3021         (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3022   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3024   rtx reg1 = gen_reg_rtx (DFmode);
3025   rtx reg2 = gen_reg_rtx (DFmode);
3026   rtx reg3 = gen_reg_rtx (DImode);
3027   rtx label1 = gen_label_rtx ();
3028   rtx label2 = gen_label_rtx ();
3029   REAL_VALUE_TYPE offset;
3031   real_2expN (&offset, 63);
3033   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3034   do_pending_stack_adjust ();
3036   emit_insn (gen_cmpdf (operands[1], reg1));
3037   emit_jump_insn (gen_bge (label1));
3039   emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3040   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3041                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3042   emit_barrier ();
3044   emit_label (label1);
3045   emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3046   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3047   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3049   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3050   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3052   emit_label (label2);
3054   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3055      fields, and can't be used for REG_NOTES anyway).  */
3056   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3057   DONE;
3061 (define_expand "fixuns_truncsfsi2"
3062   [(set (match_operand:SI 0 "register_operand")
3063         (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3064   "TARGET_HARD_FLOAT"
3066   rtx reg1 = gen_reg_rtx (SFmode);
3067   rtx reg2 = gen_reg_rtx (SFmode);
3068   rtx reg3 = gen_reg_rtx (SImode);
3069   rtx label1 = gen_label_rtx ();
3070   rtx label2 = gen_label_rtx ();
3071   REAL_VALUE_TYPE offset;
3073   real_2expN (&offset, 31);
3075   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3076   do_pending_stack_adjust ();
3078   emit_insn (gen_cmpsf (operands[1], reg1));
3079   emit_jump_insn (gen_bge (label1));
3081   emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3082   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3083                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3084   emit_barrier ();
3086   emit_label (label1);
3087   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3088   emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3089                                  (BITMASK_HIGH, SImode)));
3091   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3092   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3094   emit_label (label2);
3096   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3097      fields, and can't be used for REG_NOTES anyway).  */
3098   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3099   DONE;
3103 (define_expand "fixuns_truncsfdi2"
3104   [(set (match_operand:DI 0 "register_operand")
3105         (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3106   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3108   rtx reg1 = gen_reg_rtx (SFmode);
3109   rtx reg2 = gen_reg_rtx (SFmode);
3110   rtx reg3 = gen_reg_rtx (DImode);
3111   rtx label1 = gen_label_rtx ();
3112   rtx label2 = gen_label_rtx ();
3113   REAL_VALUE_TYPE offset;
3115   real_2expN (&offset, 63);
3117   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3118   do_pending_stack_adjust ();
3120   emit_insn (gen_cmpsf (operands[1], reg1));
3121   emit_jump_insn (gen_bge (label1));
3123   emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3124   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3125                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3126   emit_barrier ();
3128   emit_label (label1);
3129   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3130   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3131   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3133   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3134   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3136   emit_label (label2);
3138   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3139      fields, and can't be used for REG_NOTES anyway).  */
3140   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3141   DONE;
3145 ;;  ....................
3147 ;;      DATA MOVEMENT
3149 ;;  ....................
3151 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3153 (define_expand "extv"
3154   [(set (match_operand 0 "register_operand")
3155         (sign_extract (match_operand:QI 1 "memory_operand")
3156                       (match_operand 2 "immediate_operand")
3157                       (match_operand 3 "immediate_operand")))]
3158   "!TARGET_MIPS16"
3160   if (mips_expand_unaligned_load (operands[0], operands[1],
3161                                   INTVAL (operands[2]),
3162                                   INTVAL (operands[3])))
3163     DONE;
3164   else
3165     FAIL;
3168 (define_expand "extzv"
3169   [(set (match_operand 0 "register_operand")
3170         (zero_extract (match_operand:QI 1 "memory_operand")
3171                       (match_operand 2 "immediate_operand")
3172                       (match_operand 3 "immediate_operand")))]
3173   "!TARGET_MIPS16"
3175   if (mips_expand_unaligned_load (operands[0], operands[1],
3176                                   INTVAL (operands[2]),
3177                                   INTVAL (operands[3])))
3178     DONE;
3179   else
3180     FAIL;
3183 (define_expand "insv"
3184   [(set (zero_extract (match_operand:QI 0 "memory_operand")
3185                       (match_operand 1 "immediate_operand")
3186                       (match_operand 2 "immediate_operand"))
3187         (match_operand 3 "reg_or_0_operand"))]
3188   "!TARGET_MIPS16"
3190   if (mips_expand_unaligned_store (operands[0], operands[3],
3191                                    INTVAL (operands[1]),
3192                                    INTVAL (operands[2])))
3193     DONE;
3194   else
3195     FAIL;
3198 ;; Unaligned word moves generated by the bit field patterns.
3200 ;; As far as the rtl is concerned, both the left-part and right-part
3201 ;; instructions can access the whole field.  However, the real operand
3202 ;; refers to just the first or the last byte (depending on endianness).
3203 ;; We therefore use two memory operands to each instruction, one to
3204 ;; describe the rtl effect and one to use in the assembly output.
3206 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3207 ;; This allows us to use the standard length calculations for the "load"
3208 ;; and "store" type attributes.
3210 (define_insn "mov_<load>l"
3211   [(set (match_operand:GPR 0 "register_operand" "=d")
3212         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3213                      (match_operand:QI 2 "memory_operand" "m")]
3214                     UNSPEC_LOAD_LEFT))]
3215   "!TARGET_MIPS16"
3216   "<load>l\t%0,%2"
3217   [(set_attr "type" "load")
3218    (set_attr "mode" "<MODE>")
3219    (set_attr "hazard" "none")])
3221 (define_insn "mov_<load>r"
3222   [(set (match_operand:GPR 0 "register_operand" "=d")
3223         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3224                      (match_operand:QI 2 "memory_operand" "m")
3225                      (match_operand:GPR 3 "register_operand" "0")]
3226                     UNSPEC_LOAD_RIGHT))]
3227   "!TARGET_MIPS16"
3228   "<load>r\t%0,%2"
3229   [(set_attr "type" "load")
3230    (set_attr "mode" "<MODE>")])
3232 (define_insn "mov_<store>l"
3233   [(set (match_operand:BLK 0 "memory_operand" "=m")
3234         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3235                      (match_operand:QI 2 "memory_operand" "m")]
3236                     UNSPEC_STORE_LEFT))]
3237   "!TARGET_MIPS16"
3238   "<store>l\t%z1,%2"
3239   [(set_attr "type" "store")
3240    (set_attr "mode" "<MODE>")])
3242 (define_insn "mov_<store>r"
3243   [(set (match_operand:BLK 0 "memory_operand" "+m")
3244         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3245                      (match_operand:QI 2 "memory_operand" "m")
3246                      (match_dup 0)]
3247                     UNSPEC_STORE_RIGHT))]
3248   "!TARGET_MIPS16"
3249   "<store>r\t%z1,%2"
3250   [(set_attr "type" "store")
3251    (set_attr "mode" "<MODE>")])
3253 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3254 ;; The required value is:
3256 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3258 ;; which translates to:
3260 ;;      lui     op0,%highest(op1)
3261 ;;      daddiu  op0,op0,%higher(op1)
3262 ;;      dsll    op0,op0,16
3263 ;;      daddiu  op0,op0,%hi(op1)
3264 ;;      dsll    op0,op0,16
3265 (define_insn_and_split "*lea_high64"
3266   [(set (match_operand:DI 0 "register_operand" "=d")
3267         (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3268   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3269   "#"
3270   "&& reload_completed"
3271   [(set (match_dup 0) (high:DI (match_dup 2)))
3272    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3273    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3274    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3275    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3277   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3278   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3280   [(set_attr "length" "20")])
3282 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3283 ;; SYMBOL_GENERAL X will take 6 cycles.  This next pattern allows combine
3284 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3285 ;; used once.  We can then use the sequence:
3287 ;;      lui     op0,%highest(op1)
3288 ;;      lui     op2,%hi(op1)
3289 ;;      daddiu  op0,op0,%higher(op1)
3290 ;;      daddiu  op2,op2,%lo(op1)
3291 ;;      dsll32  op0,op0,0
3292 ;;      daddu   op0,op0,op2
3294 ;; which takes 4 cycles on most superscalar targets.
3295 (define_insn_and_split "*lea64"
3296   [(set (match_operand:DI 0 "register_operand" "=d")
3297         (match_operand:DI 1 "general_symbolic_operand" ""))
3298    (clobber (match_scratch:DI 2 "=&d"))]
3299   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3300   "#"
3301   "&& reload_completed"
3302   [(set (match_dup 0) (high:DI (match_dup 3)))
3303    (set (match_dup 2) (high:DI (match_dup 4)))
3304    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3305    (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3306    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3307    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3309   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3310   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3312   [(set_attr "length" "24")])
3314 ;; Insns to fetch a global symbol from a big GOT.
3316 (define_insn_and_split "*xgot_hi<mode>"
3317   [(set (match_operand:P 0 "register_operand" "=d")
3318         (high:P (match_operand:P 1 "global_got_operand" "")))]
3319   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3320   "#"
3321   "&& reload_completed"
3322   [(set (match_dup 0) (high:P (match_dup 2)))
3323    (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3325   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3326   operands[3] = pic_offset_table_rtx;
3328   [(set_attr "got" "xgot_high")
3329    (set_attr "mode" "<MODE>")])
3331 (define_insn_and_split "*xgot_lo<mode>"
3332   [(set (match_operand:P 0 "register_operand" "=d")
3333         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3334                   (match_operand:P 2 "global_got_operand" "")))]
3335   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3336   "#"
3337   "&& reload_completed"
3338   [(set (match_dup 0)
3339         (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3340   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3341   [(set_attr "got" "load")
3342    (set_attr "mode" "<MODE>")])
3344 ;; Insns to fetch a global symbol from a normal GOT.
3346 (define_insn_and_split "*got_disp<mode>"
3347   [(set (match_operand:P 0 "register_operand" "=d")
3348         (match_operand:P 1 "global_got_operand" ""))]
3349   "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3350   "#"
3351   "&& reload_completed"
3352   [(set (match_dup 0)
3353         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3355   operands[2] = pic_offset_table_rtx;
3356   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3358   [(set_attr "got" "load")
3359    (set_attr "mode" "<MODE>")])
3361 ;; Insns for loading the high part of a local symbol.
3363 (define_insn_and_split "*got_page<mode>"
3364   [(set (match_operand:P 0 "register_operand" "=d")
3365         (high:P (match_operand:P 1 "local_got_operand" "")))]
3366   "TARGET_EXPLICIT_RELOCS"
3367   "#"
3368   "&& reload_completed"
3369   [(set (match_dup 0)
3370         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3372   operands[2] = pic_offset_table_rtx;
3373   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3375   [(set_attr "got" "load")
3376    (set_attr "mode" "<MODE>")])
3378 ;; Lower-level instructions for loading an address from the GOT.
3379 ;; We could use MEMs, but an unspec gives more optimization
3380 ;; opportunities.
3382 (define_insn "*load_got<mode>"
3383   [(set (match_operand:P 0 "register_operand" "=d")
3384         (unspec:P [(match_operand:P 1 "register_operand" "d")
3385                    (match_operand:P 2 "immediate_operand" "")]
3386                   UNSPEC_LOAD_GOT))]
3387   "TARGET_ABICALLS"
3388   "<load>\t%0,%R2(%1)"
3389   [(set_attr "type" "load")
3390    (set_attr "mode" "<MODE>")
3391    (set_attr "length" "4")])
3393 ;; Instructions for adding the low 16 bits of an address to a register.
3394 ;; Operand 2 is the address: print_operand works out which relocation
3395 ;; should be applied.
3397 (define_insn "*low<mode>"
3398   [(set (match_operand:P 0 "register_operand" "=d")
3399         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3400                   (match_operand:P 2 "immediate_operand" "")))]
3401   "!TARGET_MIPS16"
3402   "<d>addiu\t%0,%1,%R2"
3403   [(set_attr "type" "arith")
3404    (set_attr "mode" "<MODE>")])
3406 (define_insn "*low<mode>_mips16"
3407   [(set (match_operand:P 0 "register_operand" "=d")
3408         (lo_sum:P (match_operand:P 1 "register_operand" "0")
3409                   (match_operand:P 2 "immediate_operand" "")))]
3410   "TARGET_MIPS16"
3411   "<d>addiu\t%0,%R2"
3412   [(set_attr "type" "arith")
3413    (set_attr "mode" "<MODE>")
3414    (set_attr "length" "8")])
3416 ;; 64-bit integer moves
3418 ;; Unlike most other insns, the move insns can't be split with
3419 ;; different predicates, because register spilling and other parts of
3420 ;; the compiler, have memoized the insn number already.
3422 (define_expand "movdi"
3423   [(set (match_operand:DI 0 "")
3424         (match_operand:DI 1 ""))]
3425   ""
3427   if (mips_legitimize_move (DImode, operands[0], operands[1]))
3428     DONE;
3431 ;; For mips16, we need a special case to handle storing $31 into
3432 ;; memory, since we don't have a constraint to match $31.  This
3433 ;; instruction can be generated by save_restore_insns.
3435 (define_insn "*mov<mode>_ra"
3436   [(set (match_operand:GPR 0 "stack_operand" "=m")
3437         (reg:GPR 31))]
3438   "TARGET_MIPS16"
3439   "<store>\t$31,%0"
3440   [(set_attr "type" "store")
3441    (set_attr "mode" "<MODE>")])
3443 (define_insn "*movdi_32bit"
3444   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
3445         (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
3446   "!TARGET_64BIT && !TARGET_MIPS16
3447    && (register_operand (operands[0], DImode)
3448        || reg_or_0_operand (operands[1], DImode))"
3449   { return mips_output_move (operands[0], operands[1]); }
3450   [(set_attr "type"     "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
3451    (set_attr "mode"     "DI")
3452    (set_attr "length"   "8,16,*,*,8,8,8,*,8,*")])
3454 (define_insn "*movdi_32bit_mips16"
3455   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3456         (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3457   "!TARGET_64BIT && TARGET_MIPS16
3458    && (register_operand (operands[0], DImode)
3459        || register_operand (operands[1], DImode))"
3460   { return mips_output_move (operands[0], operands[1]); }
3461   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store,mfhilo")
3462    (set_attr "mode"     "DI")
3463    (set_attr "length"   "8,8,8,8,12,*,*,8")])
3465 (define_insn "*movdi_64bit"
3466   [(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")
3467         (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"))]
3468   "TARGET_64BIT && !TARGET_MIPS16
3469    && (register_operand (operands[0], DImode)
3470        || reg_or_0_operand (operands[1], DImode))"
3471   { return mips_output_move (operands[0], operands[1]); }
3472   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
3473    (set_attr "mode"     "DI")
3474    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3476 (define_insn "*movdi_64bit_mips16"
3477   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3478         (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3479   "TARGET_64BIT && TARGET_MIPS16
3480    && (register_operand (operands[0], DImode)
3481        || register_operand (operands[1], DImode))"
3482   { return mips_output_move (operands[0], operands[1]); }
3483   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
3484    (set_attr "mode"     "DI")
3485    (set_attr_alternative "length"
3486                 [(const_int 4)
3487                  (const_int 4)
3488                  (const_int 4)
3489                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3490                                (const_int 4)
3491                                (const_int 8))
3492                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3493                                (const_int 8)
3494                                (const_int 12))
3495                  (const_string "*")
3496                  (const_string "*")
3497                  (const_string "*")])])
3500 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
3501 ;; when the original load is a 4 byte instruction but the add and the
3502 ;; load are 2 2 byte instructions.
3504 (define_split
3505   [(set (match_operand:DI 0 "register_operand")
3506         (mem:DI (plus:DI (match_dup 0)
3507                          (match_operand:DI 1 "const_int_operand"))))]
3508   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3509    && !TARGET_DEBUG_D_MODE
3510    && GET_CODE (operands[0]) == REG
3511    && M16_REG_P (REGNO (operands[0]))
3512    && GET_CODE (operands[1]) == CONST_INT
3513    && ((INTVAL (operands[1]) < 0
3514         && INTVAL (operands[1]) >= -0x10)
3515        || (INTVAL (operands[1]) >= 32 * 8
3516            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3517        || (INTVAL (operands[1]) >= 0
3518            && INTVAL (operands[1]) < 32 * 8
3519            && (INTVAL (operands[1]) & 7) != 0))"
3520   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3521    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3523   HOST_WIDE_INT val = INTVAL (operands[1]);
3525   if (val < 0)
3526     operands[2] = const0_rtx;
3527   else if (val >= 32 * 8)
3528     {
3529       int off = val & 7;
3531       operands[1] = GEN_INT (0x8 + off);
3532       operands[2] = GEN_INT (val - off - 0x8);
3533     }
3534   else
3535     {
3536       int off = val & 7;
3538       operands[1] = GEN_INT (off);
3539       operands[2] = GEN_INT (val - off);
3540     }
3543 ;; 32-bit Integer moves
3545 ;; Unlike most other insns, the move insns can't be split with
3546 ;; different predicates, because register spilling and other parts of
3547 ;; the compiler, have memoized the insn number already.
3549 (define_expand "movsi"
3550   [(set (match_operand:SI 0 "")
3551         (match_operand:SI 1 ""))]
3552   ""
3554   if (mips_legitimize_move (SImode, operands[0], operands[1]))
3555     DONE;
3558 ;; The difference between these two is whether or not ints are allowed
3559 ;; in FP registers (off by default, use -mdebugh to enable).
3561 (define_insn "*movsi_internal"
3562   [(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")
3563         (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"))]
3564   "!TARGET_MIPS16
3565    && (register_operand (operands[0], SImode)
3566        || reg_or_0_operand (operands[1], SImode))"
3567   { return mips_output_move (operands[0], operands[1]); }
3568   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
3569    (set_attr "mode"     "SI")
3570    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
3572 (define_insn "*movsi_mips16"
3573   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3574         (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3575   "TARGET_MIPS16
3576    && (register_operand (operands[0], SImode)
3577        || register_operand (operands[1], SImode))"
3578   { return mips_output_move (operands[0], operands[1]); }
3579   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
3580    (set_attr "mode"     "SI")
3581    (set_attr_alternative "length"
3582                 [(const_int 4)
3583                  (const_int 4)
3584                  (const_int 4)
3585                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3586                                (const_int 4)
3587                                (const_int 8))
3588                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3589                                (const_int 8)
3590                                (const_int 12))
3591                  (const_string "*")
3592                  (const_string "*")
3593                  (const_string "*")])])
3595 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
3596 ;; when the original load is a 4 byte instruction but the add and the
3597 ;; load are 2 2 byte instructions.
3599 (define_split
3600   [(set (match_operand:SI 0 "register_operand")
3601         (mem:SI (plus:SI (match_dup 0)
3602                          (match_operand:SI 1 "const_int_operand"))))]
3603   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3604    && GET_CODE (operands[0]) == REG
3605    && M16_REG_P (REGNO (operands[0]))
3606    && GET_CODE (operands[1]) == CONST_INT
3607    && ((INTVAL (operands[1]) < 0
3608         && INTVAL (operands[1]) >= -0x80)
3609        || (INTVAL (operands[1]) >= 32 * 4
3610            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3611        || (INTVAL (operands[1]) >= 0
3612            && INTVAL (operands[1]) < 32 * 4
3613            && (INTVAL (operands[1]) & 3) != 0))"
3614   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3615    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3617   HOST_WIDE_INT val = INTVAL (operands[1]);
3619   if (val < 0)
3620     operands[2] = const0_rtx;
3621   else if (val >= 32 * 4)
3622     {
3623       int off = val & 3;
3625       operands[1] = GEN_INT (0x7c + off);
3626       operands[2] = GEN_INT (val - off - 0x7c);
3627     }
3628   else
3629     {
3630       int off = val & 3;
3632       operands[1] = GEN_INT (off);
3633       operands[2] = GEN_INT (val - off);
3634     }
3637 ;; On the mips16, we can split a load of certain constants into a load
3638 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
3639 ;; instructions.
3641 (define_split
3642   [(set (match_operand:SI 0 "register_operand")
3643         (match_operand:SI 1 "const_int_operand"))]
3644   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3645    && GET_CODE (operands[0]) == REG
3646    && M16_REG_P (REGNO (operands[0]))
3647    && GET_CODE (operands[1]) == CONST_INT
3648    && INTVAL (operands[1]) >= 0x100
3649    && INTVAL (operands[1]) <= 0xff + 0x7f"
3650   [(set (match_dup 0) (match_dup 1))
3651    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3653   int val = INTVAL (operands[1]);
3655   operands[1] = GEN_INT (0xff);
3656   operands[2] = GEN_INT (val - 0xff);
3659 ;; This insn handles moving CCmode values.  It's really just a
3660 ;; slightly simplified copy of movsi_internal2, with additional cases
3661 ;; to move a condition register to a general register and to move
3662 ;; between the general registers and the floating point registers.
3664 (define_insn "movcc"
3665   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3666         (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3667   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3668   { return mips_output_move (operands[0], operands[1]); }
3669   [(set_attr "type"     "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
3670    (set_attr "mode"     "SI")
3671    (set_attr "length"   "8,4,*,*,4,4,4,*,*")])
3673 ;; Reload condition code registers.  reload_incc and reload_outcc
3674 ;; both handle moves from arbitrary operands into condition code
3675 ;; registers.  reload_incc handles the more common case in which
3676 ;; a source operand is constrained to be in a condition-code
3677 ;; register, but has not been allocated to one.
3679 ;; Sometimes, such as in movcc, we have a CCmode destination whose
3680 ;; constraints do not include 'z'.  reload_outcc handles the case
3681 ;; when such an operand is allocated to a condition-code register.
3683 ;; Note that reloads from a condition code register to some
3684 ;; other location can be done using ordinary moves.  Moving
3685 ;; into a GPR takes a single movcc, moving elsewhere takes
3686 ;; two.  We can leave these cases to the generic reload code.
3687 (define_expand "reload_incc"
3688   [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3689         (match_operand:CC 1 "general_operand" ""))
3690    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3691   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3693   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3694   DONE;
3697 (define_expand "reload_outcc"
3698   [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3699         (match_operand:CC 1 "register_operand" ""))
3700    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3701   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3703   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3704   DONE;
3707 ;; MIPS4 supports loading and storing a floating point register from
3708 ;; the sum of two general registers.  We use two versions for each of
3709 ;; these four instructions: one where the two general registers are
3710 ;; SImode, and one where they are DImode.  This is because general
3711 ;; registers will be in SImode when they hold 32 bit values, but,
3712 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
3713 ;; instructions will still work correctly.
3715 ;; ??? Perhaps it would be better to support these instructions by
3716 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
3717 ;; these instructions can only be used to load and store floating
3718 ;; point registers, that would probably cause trouble in reload.
3720 (define_insn "*lwxc1_<mode>"
3721   [(set (match_operand:SF 0 "register_operand" "=f")
3722         (mem:SF (plus:P (match_operand:P 1 "register_operand" "d")
3723                         (match_operand:P 2 "register_operand" "d"))))]
3724   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
3725   "lwxc1\t%0,%1(%2)"
3726   [(set_attr "type" "fpidxload")
3727    (set_attr "mode" "SF")])
3729 (define_insn "*ldxc1_<mode>"
3730   [(set (match_operand:DF 0 "register_operand" "=f")
3731         (mem:DF (plus:P (match_operand:P 1 "register_operand" "d")
3732                         (match_operand:P 2 "register_operand" "d"))))]
3733   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3734   "ldxc1\t%0,%1(%2)"
3735   [(set_attr "type" "fpidxload")
3736    (set_attr "mode" "DF")])
3738 (define_insn "*swxc1_<mode>"
3739   [(set (mem:SF (plus:P (match_operand:P 1 "register_operand" "d")
3740                         (match_operand:P 2 "register_operand" "d")))
3741         (match_operand:SF 0 "register_operand" "f"))]
3742   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
3743   "swxc1\t%0,%1(%2)"
3744   [(set_attr "type" "fpidxstore")
3745    (set_attr "mode" "SF")])
3747 (define_insn "*sdxc1_<mode>"
3748   [(set (mem:DF (plus:P (match_operand:P 1 "register_operand" "d")
3749                         (match_operand:P 2 "register_operand" "d")))
3750         (match_operand:DF 0 "register_operand" "f"))]
3751   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3752   "sdxc1\t%0,%1(%2)"
3753   [(set_attr "type" "fpidxstore")
3754    (set_attr "mode" "DF")])
3756 ;; 16-bit Integer moves
3758 ;; Unlike most other insns, the move insns can't be split with
3759 ;; different predicates, because register spilling and other parts of
3760 ;; the compiler, have memoized the insn number already.
3761 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3763 (define_expand "movhi"
3764   [(set (match_operand:HI 0 "")
3765         (match_operand:HI 1 ""))]
3766   ""
3768   if (mips_legitimize_move (HImode, operands[0], operands[1]))
3769     DONE;
3772 (define_insn "*movhi_internal"
3773   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3774         (match_operand:HI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3775   "!TARGET_MIPS16
3776    && (register_operand (operands[0], HImode)
3777        || reg_or_0_operand (operands[1], HImode))"
3778   "@
3779     move\t%0,%1
3780     li\t%0,%1
3781     lhu\t%0,%1
3782     sh\t%z1,%0
3783     mfc1\t%0,%1
3784     mtc1\t%1,%0
3785     mov.s\t%0,%1
3786     mt%0\t%1"
3787   [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3788    (set_attr "mode"     "HI")
3789    (set_attr "length"   "4,4,*,*,4,4,4,4")])
3791 (define_insn "*movhi_mips16"
3792   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3793         (match_operand:HI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3794   "TARGET_MIPS16
3795    && (register_operand (operands[0], HImode)
3796        || register_operand (operands[1], HImode))"
3797   "@
3798     move\t%0,%1
3799     move\t%0,%1
3800     move\t%0,%1
3801     li\t%0,%1
3802     #
3803     lhu\t%0,%1
3804     sh\t%1,%0"
3805   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
3806    (set_attr "mode"     "HI")
3807    (set_attr_alternative "length"
3808                 [(const_int 4)
3809                  (const_int 4)
3810                  (const_int 4)
3811                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3812                                (const_int 4)
3813                                (const_int 8))
3814                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3815                                (const_int 8)
3816                                (const_int 12))
3817                  (const_string "*")
3818                  (const_string "*")])])
3821 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
3822 ;; when the original load is a 4 byte instruction but the add and the
3823 ;; load are 2 2 byte instructions.
3825 (define_split
3826   [(set (match_operand:HI 0 "register_operand")
3827         (mem:HI (plus:SI (match_dup 0)
3828                          (match_operand:SI 1 "const_int_operand"))))]
3829   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3830    && GET_CODE (operands[0]) == REG
3831    && M16_REG_P (REGNO (operands[0]))
3832    && GET_CODE (operands[1]) == CONST_INT
3833    && ((INTVAL (operands[1]) < 0
3834         && INTVAL (operands[1]) >= -0x80)
3835        || (INTVAL (operands[1]) >= 32 * 2
3836            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
3837        || (INTVAL (operands[1]) >= 0
3838            && INTVAL (operands[1]) < 32 * 2
3839            && (INTVAL (operands[1]) & 1) != 0))"
3840   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3841    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
3843   HOST_WIDE_INT val = INTVAL (operands[1]);
3845   if (val < 0)
3846     operands[2] = const0_rtx;
3847   else if (val >= 32 * 2)
3848     {
3849       int off = val & 1;
3851       operands[1] = GEN_INT (0x7e + off);
3852       operands[2] = GEN_INT (val - off - 0x7e);
3853     }
3854   else
3855     {
3856       int off = val & 1;
3858       operands[1] = GEN_INT (off);
3859       operands[2] = GEN_INT (val - off);
3860     }
3863 ;; 8-bit Integer moves
3865 ;; Unlike most other insns, the move insns can't be split with
3866 ;; different predicates, because register spilling and other parts of
3867 ;; the compiler, have memoized the insn number already.
3868 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3870 (define_expand "movqi"
3871   [(set (match_operand:QI 0 "")
3872         (match_operand:QI 1 ""))]
3873   ""
3875   if (mips_legitimize_move (QImode, operands[0], operands[1]))
3876     DONE;
3879 (define_insn "*movqi_internal"
3880   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3881         (match_operand:QI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3882   "!TARGET_MIPS16
3883    && (register_operand (operands[0], QImode)
3884        || reg_or_0_operand (operands[1], QImode))"
3885   "@
3886     move\t%0,%1
3887     li\t%0,%1
3888     lbu\t%0,%1
3889     sb\t%z1,%0
3890     mfc1\t%0,%1
3891     mtc1\t%1,%0
3892     mov.s\t%0,%1
3893     mt%0\t%1"
3894   [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3895    (set_attr "mode"     "QI")
3896    (set_attr "length"   "4,4,*,*,4,4,4,4")])
3898 (define_insn "*movqi_mips16"
3899   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3900         (match_operand:QI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3901   "TARGET_MIPS16
3902    && (register_operand (operands[0], QImode)
3903        || register_operand (operands[1], QImode))"
3904   "@
3905     move\t%0,%1
3906     move\t%0,%1
3907     move\t%0,%1
3908     li\t%0,%1
3909     #
3910     lbu\t%0,%1
3911     sb\t%1,%0"
3912   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
3913    (set_attr "mode"     "QI")
3914    (set_attr "length"   "4,4,4,4,8,*,*")])
3916 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
3917 ;; when the original load is a 4 byte instruction but the add and the
3918 ;; load are 2 2 byte instructions.
3920 (define_split
3921   [(set (match_operand:QI 0 "register_operand")
3922         (mem:QI (plus:SI (match_dup 0)
3923                          (match_operand:SI 1 "const_int_operand"))))]
3924   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3925    && GET_CODE (operands[0]) == REG
3926    && M16_REG_P (REGNO (operands[0]))
3927    && GET_CODE (operands[1]) == CONST_INT
3928    && ((INTVAL (operands[1]) < 0
3929         && INTVAL (operands[1]) >= -0x80)
3930        || (INTVAL (operands[1]) >= 32
3931            && INTVAL (operands[1]) <= 31 + 0x7f))"
3932   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3933    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
3935   HOST_WIDE_INT val = INTVAL (operands[1]);
3937   if (val < 0)
3938     operands[2] = const0_rtx;
3939   else
3940     {
3941       operands[1] = GEN_INT (0x7f);
3942       operands[2] = GEN_INT (val - 0x7f);
3943     }
3946 ;; 32-bit floating point moves
3948 (define_expand "movsf"
3949   [(set (match_operand:SF 0 "")
3950         (match_operand:SF 1 ""))]
3951   ""
3953   if (mips_legitimize_move (SFmode, operands[0], operands[1]))
3954     DONE;
3957 (define_insn "*movsf_hardfloat"
3958   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
3959         (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
3960   "TARGET_HARD_FLOAT
3961    && (register_operand (operands[0], SFmode)
3962        || reg_or_0_operand (operands[1], SFmode))"
3963   { return mips_output_move (operands[0], operands[1]); }
3964   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
3965    (set_attr "mode"     "SF")
3966    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
3968 (define_insn "*movsf_softfloat"
3969   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
3970         (match_operand:SF 1 "move_operand" "Gd,m,d"))]
3971   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
3972    && (register_operand (operands[0], SFmode)
3973        || reg_or_0_operand (operands[1], SFmode))"
3974   { return mips_output_move (operands[0], operands[1]); }
3975   [(set_attr "type"     "arith,load,store")
3976    (set_attr "mode"     "SF")
3977    (set_attr "length"   "4,*,*")])
3979 (define_insn "*movsf_mips16"
3980   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
3981         (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
3982   "TARGET_MIPS16
3983    && (register_operand (operands[0], SFmode)
3984        || register_operand (operands[1], SFmode))"
3985   { return mips_output_move (operands[0], operands[1]); }
3986   [(set_attr "type"     "arith,arith,arith,load,store")
3987    (set_attr "mode"     "SF")
3988    (set_attr "length"   "4,4,4,*,*")])
3991 ;; 64-bit floating point moves
3993 (define_expand "movdf"
3994   [(set (match_operand:DF 0 "")
3995         (match_operand:DF 1 ""))]
3996   ""
3998   if (mips_legitimize_move (DFmode, operands[0], operands[1]))
3999     DONE;
4002 (define_insn "*movdf_hardfloat_64bit"
4003   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4004         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4005   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
4006    && (register_operand (operands[0], DFmode)
4007        || reg_or_0_operand (operands[1], DFmode))"
4008   { return mips_output_move (operands[0], operands[1]); }
4009   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4010    (set_attr "mode"     "DF")
4011    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
4013 (define_insn "*movdf_hardfloat_32bit"
4014   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4015         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4016   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
4017    && (register_operand (operands[0], DFmode)
4018        || reg_or_0_operand (operands[1], DFmode))"
4019   { return mips_output_move (operands[0], operands[1]); }
4020   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4021    (set_attr "mode"     "DF")
4022    (set_attr "length"   "4,8,*,*,8,8,8,*,*")])
4024 (define_insn "*movdf_softfloat"
4025   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
4026         (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
4027   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4028    && (register_operand (operands[0], DFmode)
4029        || reg_or_0_operand (operands[1], DFmode))"
4030   { return mips_output_move (operands[0], operands[1]); }
4031   [(set_attr "type"     "arith,load,store,xfer,xfer,fmove")
4032    (set_attr "mode"     "DF")
4033    (set_attr "length"   "8,*,*,4,4,4")])
4035 (define_insn "*movdf_mips16"
4036   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4037         (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4038   "TARGET_MIPS16
4039    && (register_operand (operands[0], DFmode)
4040        || register_operand (operands[1], DFmode))"
4041   { return mips_output_move (operands[0], operands[1]); }
4042   [(set_attr "type"     "arith,arith,arith,load,store")
4043    (set_attr "mode"     "DF")
4044    (set_attr "length"   "8,8,8,*,*")])
4046 (define_split
4047   [(set (match_operand:DI 0 "nonimmediate_operand")
4048         (match_operand:DI 1 "move_operand"))]
4049   "reload_completed && !TARGET_64BIT
4050    && mips_split_64bit_move_p (operands[0], operands[1])"
4051   [(const_int 0)]
4053   mips_split_64bit_move (operands[0], operands[1]);
4054   DONE;
4057 (define_split
4058   [(set (match_operand:DF 0 "nonimmediate_operand")
4059         (match_operand:DF 1 "move_operand"))]
4060   "reload_completed && !TARGET_64BIT
4061    && mips_split_64bit_move_p (operands[0], operands[1])"
4062   [(const_int 0)]
4064   mips_split_64bit_move (operands[0], operands[1]);
4065   DONE;
4068 ;; When generating mips16 code, split moves of negative constants into
4069 ;; a positive "li" followed by a negation.
4070 (define_split
4071   [(set (match_operand 0 "register_operand")
4072         (match_operand 1 "const_int_operand"))]
4073   "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4074   [(set (match_dup 2)
4075         (match_dup 3))
4076    (set (match_dup 2)
4077         (neg:SI (match_dup 2)))]
4079   operands[2] = gen_lowpart (SImode, operands[0]);
4080   operands[3] = GEN_INT (-INTVAL (operands[1]));
4083 ;; The HI and LO registers are not truly independent.  If we move an mthi
4084 ;; instruction before an mflo instruction, it will make the result of the
4085 ;; mflo unpredictable.  The same goes for mtlo and mfhi.
4087 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4088 ;; Operand 1 is the register we want, operand 2 is the other one.
4090 (define_insn "mfhilo_di"
4091   [(set (match_operand:DI 0 "register_operand" "=d,d")
4092         (unspec:DI [(match_operand:DI 1 "register_operand" "h,l")
4093                     (match_operand:DI 2 "register_operand" "l,h")]
4094                    UNSPEC_MFHILO))]
4095   "TARGET_64BIT"
4096   "mf%1\t%0"
4097   [(set_attr "type" "mfhilo")])
4099 (define_insn "mfhilo_si"
4100   [(set (match_operand:SI 0 "register_operand" "=d,d")
4101         (unspec:SI [(match_operand:SI 1 "register_operand" "h,l")
4102                     (match_operand:SI 2 "register_operand" "l,h")]
4103                    UNSPEC_MFHILO))]
4104   ""
4105   "mf%1\t%0"
4106   [(set_attr "type" "mfhilo")])
4108 ;; Patterns for loading or storing part of a paired floating point
4109 ;; register.  We need them because odd-numbered floating-point registers
4110 ;; are not fully independent: see mips_split_64bit_move.
4112 ;; Load the low word of operand 0 with operand 1.
4113 (define_insn "load_df_low"
4114   [(set (match_operand:DF 0 "register_operand" "=f,f")
4115         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
4116                    UNSPEC_LOAD_DF_LOW))]
4117   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4119   operands[0] = mips_subword (operands[0], 0);
4120   return mips_output_move (operands[0], operands[1]);
4122   [(set_attr "type"     "xfer,fpload")
4123    (set_attr "mode"     "SF")])
4125 ;; Load the high word of operand 0 from operand 1, preserving the value
4126 ;; in the low word.
4127 (define_insn "load_df_high"
4128   [(set (match_operand:DF 0 "register_operand" "=f,f")
4129         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
4130                     (match_operand:DF 2 "register_operand" "0,0")]
4131                    UNSPEC_LOAD_DF_HIGH))]
4132   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4134   operands[0] = mips_subword (operands[0], 1);
4135   return mips_output_move (operands[0], operands[1]);
4137   [(set_attr "type"     "xfer,fpload")
4138    (set_attr "mode"     "SF")])
4140 ;; Store the high word of operand 1 in operand 0.  The corresponding
4141 ;; low-word move is done in the normal way.
4142 (define_insn "store_df_high"
4143   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4144         (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4145                    UNSPEC_STORE_DF_HIGH))]
4146   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4148   operands[1] = mips_subword (operands[1], 1);
4149   return mips_output_move (operands[0], operands[1]);
4151   [(set_attr "type"     "xfer,fpstore")
4152    (set_attr "mode"     "SF")])
4154 ;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
4155 ;; of _gp from the start of this function.  Operand 1 is the incoming
4156 ;; function address.
4157 (define_insn_and_split "loadgp"
4158   [(unspec_volatile [(match_operand 0 "" "")
4159                      (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4160   "TARGET_ABICALLS && TARGET_NEWABI"
4161   "#"
4162   ""
4163   [(set (match_dup 2) (match_dup 3))
4164    (set (match_dup 2) (match_dup 4))
4165    (set (match_dup 2) (match_dup 5))]
4167   operands[2] = pic_offset_table_rtx;
4168   operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4169   operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4170   operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4172   [(set_attr "length" "12")])
4174 ;; The use of gp is hidden when not using explicit relocations.
4175 ;; This blockage instruction prevents the gp load from being
4176 ;; scheduled after an implicit use of gp.  It also prevents
4177 ;; the load from being deleted as dead.
4178 (define_insn "loadgp_blockage"
4179   [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4180   ""
4181   ""
4182   [(set_attr "type"     "unknown")
4183    (set_attr "mode"     "none")
4184    (set_attr "length"   "0")])
4186 ;; Emit a .cprestore directive, which normally expands to a single store
4187 ;; instruction.  Note that we continue to use .cprestore for explicit reloc
4188 ;; code so that jals inside inline asms will work correctly.
4189 (define_insn "cprestore"
4190   [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
4191                     UNSPEC_CPRESTORE)]
4192   ""
4194   if (set_nomacro && which_alternative == 1)
4195     return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4196   else
4197     return ".cprestore\t%0";
4199   [(set_attr "type" "store")
4200    (set_attr "length" "4,12")])
4202 ;; Block moves, see mips.c for more details.
4203 ;; Argument 0 is the destination
4204 ;; Argument 1 is the source
4205 ;; Argument 2 is the length
4206 ;; Argument 3 is the alignment
4208 (define_expand "movmemsi"
4209   [(parallel [(set (match_operand:BLK 0 "general_operand")
4210                    (match_operand:BLK 1 "general_operand"))
4211               (use (match_operand:SI 2 ""))
4212               (use (match_operand:SI 3 "const_int_operand"))])]
4213   "!TARGET_MIPS16 && !TARGET_MEMCPY"
4215   if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4216     DONE;
4217   else
4218     FAIL;
4222 ;;  ....................
4224 ;;      SHIFTS
4226 ;;  ....................
4228 ;; Many of these instructions use trivial define_expands, because we
4229 ;; want to use a different set of constraints when TARGET_MIPS16.
4231 (define_expand "ashlsi3"
4232   [(set (match_operand:SI 0 "register_operand")
4233         (ashift:SI (match_operand:SI 1 "register_operand")
4234                    (match_operand:SI 2 "arith_operand")))]
4235   ""
4237   /* On the mips16, a shift of more than 8 is a four byte instruction,
4238      so, for a shift between 8 and 16, it is just as fast to do two
4239      shifts of 8 or less.  If there is a lot of shifting going on, we
4240      may win in CSE.  Otherwise combine will put the shifts back
4241      together again.  This can be called by function_arg, so we must
4242      be careful not to allocate a new register if we've reached the
4243      reload pass.  */
4244   if (TARGET_MIPS16
4245       && optimize
4246       && GET_CODE (operands[2]) == CONST_INT
4247       && INTVAL (operands[2]) > 8
4248       && INTVAL (operands[2]) <= 16
4249       && ! reload_in_progress
4250       && ! reload_completed)
4251     {
4252       rtx temp = gen_reg_rtx (SImode);
4254       emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
4255       emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
4256                                         GEN_INT (INTVAL (operands[2]) - 8)));
4257       DONE;
4258     }
4261 (define_insn "ashlsi3_internal1"
4262   [(set (match_operand:SI 0 "register_operand" "=d")
4263         (ashift:SI (match_operand:SI 1 "register_operand" "d")
4264                    (match_operand:SI 2 "arith_operand" "dI")))]
4265   "!TARGET_MIPS16"
4267   if (GET_CODE (operands[2]) == CONST_INT)
4268     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4270   return "sll\t%0,%1,%2";
4272   [(set_attr "type"     "shift")
4273    (set_attr "mode"     "SI")])
4275 (define_insn "ashlsi3_internal1_extend"
4276   [(set (match_operand:DI 0 "register_operand" "=d")
4277        (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
4278                                   (match_operand:SI 2 "arith_operand" "dI"))))]
4279   "TARGET_64BIT && !TARGET_MIPS16"
4281   if (GET_CODE (operands[2]) == CONST_INT)
4282     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4284   return "sll\t%0,%1,%2";
4286   [(set_attr "type"    "shift")
4287    (set_attr "mode"    "DI")])
4290 (define_insn "ashlsi3_internal2"
4291   [(set (match_operand:SI 0 "register_operand" "=d,d")
4292         (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
4293                    (match_operand:SI 2 "arith_operand" "d,I")))]
4294   "TARGET_MIPS16"
4296   if (which_alternative == 0)
4297     return "sll\t%0,%2";
4299   if (GET_CODE (operands[2]) == CONST_INT)
4300     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4302   return "sll\t%0,%1,%2";
4304   [(set_attr "type"     "shift")
4305    (set_attr "mode"     "SI")
4306    (set_attr_alternative "length"
4307                 [(const_int 4)
4308                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4309                                (const_int 4)
4310                                (const_int 8))])])
4312 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4314 (define_split
4315   [(set (match_operand:SI 0 "register_operand")
4316         (ashift:SI (match_operand:SI 1 "register_operand")
4317                    (match_operand:SI 2 "const_int_operand")))]
4318   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4319    && GET_CODE (operands[2]) == CONST_INT
4320    && INTVAL (operands[2]) > 8
4321    && INTVAL (operands[2]) <= 16"
4322   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
4323    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4324   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4326 (define_expand "ashldi3"
4327   [(set (match_operand:DI 0 "register_operand")
4328         (ashift:DI (match_operand:DI 1 "register_operand")
4329                    (match_operand:SI 2 "arith_operand")))]
4330   "TARGET_64BIT"
4332   /* On the mips16, a shift of more than 8 is a four byte
4333      instruction, so, for a shift between 8 and 16, it is just as
4334      fast to do two shifts of 8 or less.  If there is a lot of
4335      shifting going on, we may win in CSE.  Otherwise combine will
4336      put the shifts back together again.  This can be called by
4337      function_arg, so we must be careful not to allocate a new
4338      register if we've reached the reload pass.  */
4339   if (TARGET_MIPS16
4340       && optimize
4341       && GET_CODE (operands[2]) == CONST_INT
4342       && INTVAL (operands[2]) > 8
4343       && INTVAL (operands[2]) <= 16
4344       && ! reload_in_progress
4345       && ! reload_completed)
4346     {
4347       rtx temp = gen_reg_rtx (DImode);
4349       emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
4350       emit_insn (gen_ashldi3_internal (operands[0], temp,
4351                                        GEN_INT (INTVAL (operands[2]) - 8)));
4352       DONE;
4353     }
4357 (define_insn "ashldi3_internal"
4358   [(set (match_operand:DI 0 "register_operand" "=d")
4359         (ashift:DI (match_operand:DI 1 "register_operand" "d")
4360                    (match_operand:SI 2 "arith_operand" "dI")))]
4361   "TARGET_64BIT && !TARGET_MIPS16"
4363   if (GET_CODE (operands[2]) == CONST_INT)
4364     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4366   return "dsll\t%0,%1,%2";
4368   [(set_attr "type"     "shift")
4369    (set_attr "mode"     "DI")])
4371 (define_insn ""
4372   [(set (match_operand:DI 0 "register_operand" "=d,d")
4373         (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4374                    (match_operand:SI 2 "arith_operand" "d,I")))]
4375   "TARGET_64BIT && TARGET_MIPS16"
4377   if (which_alternative == 0)
4378     return "dsll\t%0,%2";
4380   if (GET_CODE (operands[2]) == CONST_INT)
4381     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4383   return "dsll\t%0,%1,%2";
4385   [(set_attr "type"     "shift")
4386    (set_attr "mode"     "DI")
4387    (set_attr_alternative "length"
4388                 [(const_int 4)
4389                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4390                                (const_int 4)
4391                                (const_int 8))])])
4394 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4396 (define_split
4397   [(set (match_operand:DI 0 "register_operand")
4398         (ashift:DI (match_operand:DI 1 "register_operand")
4399                    (match_operand:SI 2 "const_int_operand")))]
4400   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
4401    && reload_completed
4402    && GET_CODE (operands[2]) == CONST_INT
4403    && INTVAL (operands[2]) > 8
4404    && INTVAL (operands[2]) <= 16"
4405   [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
4406    (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
4407   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4409 (define_expand "ashrsi3"
4410   [(set (match_operand:SI 0 "register_operand")
4411         (ashiftrt:SI (match_operand:SI 1 "register_operand")
4412                      (match_operand:SI 2 "arith_operand")))]
4413   ""
4415   /* On the mips16, a shift of more than 8 is a four byte instruction,
4416      so, for a shift between 8 and 16, it is just as fast to do two
4417      shifts of 8 or less.  If there is a lot of shifting going on, we
4418      may win in CSE.  Otherwise combine will put the shifts back
4419      together again.  */
4420   if (TARGET_MIPS16
4421       && optimize
4422       && GET_CODE (operands[2]) == CONST_INT
4423       && INTVAL (operands[2]) > 8
4424       && INTVAL (operands[2]) <= 16)
4425     {
4426       rtx temp = gen_reg_rtx (SImode);
4428       emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
4429       emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
4430                                         GEN_INT (INTVAL (operands[2]) - 8)));
4431       DONE;
4432     }
4435 (define_insn "ashrsi3_internal1"
4436   [(set (match_operand:SI 0 "register_operand" "=d")
4437         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
4438                      (match_operand:SI 2 "arith_operand" "dI")))]
4439   "!TARGET_MIPS16"
4441   if (GET_CODE (operands[2]) == CONST_INT)
4442     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4444   return "sra\t%0,%1,%2";
4446   [(set_attr "type"     "shift")
4447    (set_attr "mode"     "SI")])
4449 (define_insn "ashrsi3_internal2"
4450   [(set (match_operand:SI 0 "register_operand" "=d,d")
4451         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
4452                      (match_operand:SI 2 "arith_operand" "d,I")))]
4453   "TARGET_MIPS16"
4455   if (which_alternative == 0)
4456     return "sra\t%0,%2";
4458   if (GET_CODE (operands[2]) == CONST_INT)
4459     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4461   return "sra\t%0,%1,%2";
4463   [(set_attr "type"     "shift")
4464    (set_attr "mode"     "SI")
4465    (set_attr_alternative "length"
4466                 [(const_int 4)
4467                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4468                                (const_int 4)
4469                                (const_int 8))])])
4472 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4474 (define_split
4475   [(set (match_operand:SI 0 "register_operand")
4476         (ashiftrt:SI (match_operand:SI 1 "register_operand")
4477                      (match_operand:SI 2 "const_int_operand")))]
4478   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4479    && GET_CODE (operands[2]) == CONST_INT
4480    && INTVAL (operands[2]) > 8
4481    && INTVAL (operands[2]) <= 16"
4482   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
4483    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
4484   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4486 (define_expand "ashrdi3"
4487   [(set (match_operand:DI 0 "register_operand")
4488         (ashiftrt:DI (match_operand:DI 1 "register_operand")
4489                      (match_operand:SI 2 "arith_operand")))]
4490   "TARGET_64BIT"
4492   /* On the mips16, a shift of more than 8 is a four byte
4493      instruction, so, for a shift between 8 and 16, it is just as
4494      fast to do two shifts of 8 or less.  If there is a lot of
4495      shifting going on, we may win in CSE.  Otherwise combine will
4496      put the shifts back together again.  */
4497   if (TARGET_MIPS16
4498       && optimize
4499       && GET_CODE (operands[2]) == CONST_INT
4500       && INTVAL (operands[2]) > 8
4501       && INTVAL (operands[2]) <= 16)
4502     {
4503       rtx temp = gen_reg_rtx (DImode);
4505       emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
4506       emit_insn (gen_ashrdi3_internal (operands[0], temp,
4507                                        GEN_INT (INTVAL (operands[2]) - 8)));
4508       DONE;
4509     }
4513 (define_insn "ashrdi3_internal"
4514   [(set (match_operand:DI 0 "register_operand" "=d")
4515         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4516                      (match_operand:SI 2 "arith_operand" "dI")))]
4517   "TARGET_64BIT && !TARGET_MIPS16"
4519   if (GET_CODE (operands[2]) == CONST_INT)
4520     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4522   return "dsra\t%0,%1,%2";
4524   [(set_attr "type"     "shift")
4525    (set_attr "mode"     "DI")])
4527 (define_insn ""
4528   [(set (match_operand:DI 0 "register_operand" "=d,d")
4529         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4530                      (match_operand:SI 2 "arith_operand" "d,I")))]
4531   "TARGET_64BIT && TARGET_MIPS16"
4533   if (GET_CODE (operands[2]) == CONST_INT)
4534     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4536   return "dsra\t%0,%2";
4538   [(set_attr "type"     "shift")
4539    (set_attr "mode"     "DI")
4540    (set_attr_alternative "length"
4541                 [(const_int 4)
4542                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4543                                (const_int 4)
4544                                (const_int 8))])])
4546 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4548 (define_split
4549   [(set (match_operand:DI 0 "register_operand")
4550         (ashiftrt:DI (match_operand:DI 1 "register_operand")
4551                      (match_operand:SI 2 "const_int_operand")))]
4552   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
4553    && reload_completed
4554    && GET_CODE (operands[2]) == CONST_INT
4555    && INTVAL (operands[2]) > 8
4556    && INTVAL (operands[2]) <= 16"
4557   [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
4558    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
4559   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4561 (define_expand "lshrsi3"
4562   [(set (match_operand:SI 0 "register_operand")
4563         (lshiftrt:SI (match_operand:SI 1 "register_operand")
4564                      (match_operand:SI 2 "arith_operand")))]
4565   ""
4567   /* On the mips16, a shift of more than 8 is a four byte instruction,
4568      so, for a shift between 8 and 16, it is just as fast to do two
4569      shifts of 8 or less.  If there is a lot of shifting going on, we
4570      may win in CSE.  Otherwise combine will put the shifts back
4571      together again.  */
4572   if (TARGET_MIPS16
4573       && optimize
4574       && GET_CODE (operands[2]) == CONST_INT
4575       && INTVAL (operands[2]) > 8
4576       && INTVAL (operands[2]) <= 16)
4577     {
4578       rtx temp = gen_reg_rtx (SImode);
4580       emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
4581       emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
4582                                         GEN_INT (INTVAL (operands[2]) - 8)));
4583       DONE;
4584     }
4587 (define_insn "lshrsi3_internal1"
4588   [(set (match_operand:SI 0 "register_operand" "=d")
4589         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
4590                      (match_operand:SI 2 "arith_operand" "dI")))]
4591   "!TARGET_MIPS16"
4593   if (GET_CODE (operands[2]) == CONST_INT)
4594     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4596   return "srl\t%0,%1,%2";
4598   [(set_attr "type"     "shift")
4599    (set_attr "mode"     "SI")])
4601 (define_insn "lshrsi3_internal2"
4602   [(set (match_operand:SI 0 "register_operand" "=d,d")
4603         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
4604                      (match_operand:SI 2 "arith_operand" "d,I")))]
4605   "TARGET_MIPS16"
4607   if (which_alternative == 0)
4608     return "srl\t%0,%2";
4610   if (GET_CODE (operands[2]) == CONST_INT)
4611     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4613   return "srl\t%0,%1,%2";
4615   [(set_attr "type"     "shift")
4616    (set_attr "mode"     "SI")
4617    (set_attr_alternative "length"
4618                 [(const_int 4)
4619                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4620                                (const_int 4)
4621                                (const_int 8))])])
4624 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4626 (define_split
4627   [(set (match_operand:SI 0 "register_operand")
4628         (lshiftrt:SI (match_operand:SI 1 "register_operand")
4629                      (match_operand:SI 2 "const_int_operand")))]
4630   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4631    && GET_CODE (operands[2]) == CONST_INT
4632    && INTVAL (operands[2]) > 8
4633    && INTVAL (operands[2]) <= 16"
4634   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
4635    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4636   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4638 ;; If we load a byte on the mips16 as a bitfield, the resulting
4639 ;; sequence of instructions is too complicated for combine, because it
4640 ;; involves four instructions: a load, a shift, a constant load into a
4641 ;; register, and an and (the key problem here is that the mips16 does
4642 ;; not have and immediate).  We recognize a shift of a load in order
4643 ;; to make it simple enough for combine to understand.
4645 ;; The length here is the worst case: the length of the split version
4646 ;; will be more accurate.
4647 (define_insn_and_split ""
4648   [(set (match_operand:SI 0 "register_operand" "=d")
4649         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4650                      (match_operand:SI 2 "immediate_operand" "I")))]
4651   "TARGET_MIPS16"
4652   "#"
4653   ""
4654   [(set (match_dup 0) (match_dup 1))
4655    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4656   ""
4657   [(set_attr "type"     "load")
4658    (set_attr "mode"     "SI")
4659    (set_attr "length"   "16")])
4661 (define_expand "lshrdi3"
4662   [(set (match_operand:DI 0 "register_operand")
4663         (lshiftrt:DI (match_operand:DI 1 "register_operand")
4664                      (match_operand:SI 2 "arith_operand")))]
4665   "TARGET_64BIT"
4667   /* On the mips16, a shift of more than 8 is a four byte
4668      instruction, so, for a shift between 8 and 16, it is just as
4669      fast to do two shifts of 8 or less.  If there is a lot of
4670      shifting going on, we may win in CSE.  Otherwise combine will
4671      put the shifts back together again.  */
4672   if (TARGET_MIPS16
4673       && optimize
4674       && GET_CODE (operands[2]) == CONST_INT
4675       && INTVAL (operands[2]) > 8
4676       && INTVAL (operands[2]) <= 16)
4677     {
4678       rtx temp = gen_reg_rtx (DImode);
4680       emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
4681       emit_insn (gen_lshrdi3_internal (operands[0], temp,
4682                                        GEN_INT (INTVAL (operands[2]) - 8)));
4683       DONE;
4684     }
4688 (define_insn "lshrdi3_internal"
4689   [(set (match_operand:DI 0 "register_operand" "=d")
4690         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4691                      (match_operand:SI 2 "arith_operand" "dI")))]
4692   "TARGET_64BIT && !TARGET_MIPS16"
4694   if (GET_CODE (operands[2]) == CONST_INT)
4695     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4697   return "dsrl\t%0,%1,%2";
4699   [(set_attr "type"     "shift")
4700    (set_attr "mode"     "DI")])
4702 (define_insn ""
4703   [(set (match_operand:DI 0 "register_operand" "=d,d")
4704         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4705                      (match_operand:SI 2 "arith_operand" "d,I")))]
4706   "TARGET_64BIT && TARGET_MIPS16"
4708   if (GET_CODE (operands[2]) == CONST_INT)
4709     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4711   return "dsrl\t%0,%2";
4713   [(set_attr "type"     "shift")
4714    (set_attr "mode"     "DI")
4715    (set_attr_alternative "length"
4716                 [(const_int 4)
4717                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4718                                (const_int 4)
4719                                (const_int 8))])])
4721 (define_insn "rotrsi3"
4722   [(set (match_operand:SI              0 "register_operand" "=d")
4723         (rotatert:SI (match_operand:SI 1 "register_operand" "d")
4724                      (match_operand:SI 2 "arith_operand"    "dn")))]
4725   "ISA_HAS_ROTR_SI"
4727   if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
4728     return "rorv\t%0,%1,%2";
4730   if ((GET_CODE (operands[2]) == CONST_INT)
4731       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
4732     abort ();
4734   return "ror\t%0,%1,%2";
4736   [(set_attr "type"     "shift")
4737    (set_attr "mode"     "SI")])
4739 (define_insn "rotrdi3"
4740   [(set (match_operand:DI              0 "register_operand" "=d")
4741         (rotatert:DI (match_operand:DI 1 "register_operand" "d")
4742                      (match_operand:DI 2 "arith_operand"    "dn")))]
4743   "ISA_HAS_ROTR_DI"
4745   if (TARGET_SR71K)
4746     {
4747       if (GET_CODE (operands[2]) != CONST_INT)
4748         return "drorv\t%0,%1,%2";
4750       if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
4751         return "dror32\t%0,%1,%2";
4752     }
4754   if ((GET_CODE (operands[2]) == CONST_INT)
4755       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
4756     abort ();
4758   return "dror\t%0,%1,%2";
4760   [(set_attr "type"     "shift")
4761    (set_attr "mode"     "DI")])
4764 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4766 (define_split
4767   [(set (match_operand:DI 0 "register_operand")
4768         (lshiftrt:DI (match_operand:DI 1 "register_operand")
4769                      (match_operand:SI 2 "const_int_operand")))]
4770   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4771    && GET_CODE (operands[2]) == CONST_INT
4772    && INTVAL (operands[2]) > 8
4773    && INTVAL (operands[2]) <= 16"
4774   [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
4775    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
4776   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4779 ;;  ....................
4781 ;;      COMPARISONS
4783 ;;  ....................
4785 ;; Flow here is rather complex:
4787 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the arguments
4788 ;;      into cmp_operands[] but generates no RTL.
4790 ;;  2)  The appropriate branch define_expand is called, which then
4791 ;;      creates the appropriate RTL for the comparison and branch.
4792 ;;      Different CC modes are used, based on what type of branch is
4793 ;;      done, so that we can constrain things appropriately.  There
4794 ;;      are assumptions in the rest of GCC that break if we fold the
4795 ;;      operands into the branches for integer operations, and use cc0
4796 ;;      for floating point, so we use the fp status register instead.
4797 ;;      If needed, an appropriate temporary is created to hold the
4798 ;;      of the integer compare.
4800 (define_expand "cmpsi"
4801   [(set (cc0)
4802         (compare:CC (match_operand:SI 0 "register_operand")
4803                     (match_operand:SI 1 "nonmemory_operand")))]
4804   ""
4806   cmp_operands[0] = operands[0];
4807   cmp_operands[1] = operands[1];
4808   DONE;
4811 (define_expand "cmpdi"
4812   [(set (cc0)
4813         (compare:CC (match_operand:DI 0 "register_operand")
4814                     (match_operand:DI 1 "nonmemory_operand")))]
4815   "TARGET_64BIT"
4817   cmp_operands[0] = operands[0];
4818   cmp_operands[1] = operands[1];
4819   DONE;
4822 (define_expand "cmpdf"
4823   [(set (cc0)
4824         (compare:CC (match_operand:DF 0 "register_operand")
4825                     (match_operand:DF 1 "register_operand")))]
4826   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4828   cmp_operands[0] = operands[0];
4829   cmp_operands[1] = operands[1];
4830   DONE;
4833 (define_expand "cmpsf"
4834   [(set (cc0)
4835         (compare:CC (match_operand:SF 0 "register_operand")
4836                     (match_operand:SF 1 "register_operand")))]
4837   "TARGET_HARD_FLOAT"
4839   cmp_operands[0] = operands[0];
4840   cmp_operands[1] = operands[1];
4841   DONE;
4845 ;;  ....................
4847 ;;      CONDITIONAL BRANCHES
4849 ;;  ....................
4851 ;; Conditional branches on floating-point equality tests.
4853 (define_insn "branch_fp"
4854   [(set (pc)
4855         (if_then_else
4856          (match_operator:CC 0 "comparison_operator"
4857                             [(match_operand:CC 2 "register_operand" "z")
4858                              (const_int 0)])
4859          (label_ref (match_operand 1 "" ""))
4860          (pc)))]
4861   "TARGET_HARD_FLOAT"
4863   return mips_output_conditional_branch (insn,
4864                                          operands,
4865                                          /*two_operands_p=*/0,
4866                                          /*float_p=*/1,
4867                                          /*inverted_p=*/0,
4868                                          get_attr_length (insn));
4870   [(set_attr "type"     "branch")
4871    (set_attr "mode"     "none")])
4873 (define_insn "branch_fp_inverted"
4874   [(set (pc)
4875         (if_then_else
4876          (match_operator:CC 0 "comparison_operator"
4877                             [(match_operand:CC 2 "register_operand" "z")
4878                              (const_int 0)])
4879          (pc)
4880          (label_ref (match_operand 1 "" ""))))]
4881   "TARGET_HARD_FLOAT"
4883   return mips_output_conditional_branch (insn,
4884                                          operands,
4885                                          /*two_operands_p=*/0,
4886                                          /*float_p=*/1,
4887                                          /*inverted_p=*/1,
4888                                          get_attr_length (insn));
4890   [(set_attr "type"     "branch")
4891    (set_attr "mode"     "none")])
4893 ;; Conditional branches on comparisons with zero.
4895 (define_insn "branch_zero"
4896   [(set (pc)
4897         (if_then_else
4898          (match_operator:SI 0 "comparison_operator"
4899                             [(match_operand:SI 2 "register_operand" "d")
4900                              (const_int 0)])
4901         (label_ref (match_operand 1 "" ""))
4902         (pc)))]
4903   "!TARGET_MIPS16"
4905   return mips_output_conditional_branch (insn,
4906                                          operands,
4907                                          /*two_operands_p=*/0,
4908                                          /*float_p=*/0,
4909                                          /*inverted_p=*/0,
4910                                          get_attr_length (insn));
4912   [(set_attr "type"     "branch")
4913    (set_attr "mode"     "none")])
4915 (define_insn "branch_zero_inverted"
4916   [(set (pc)
4917         (if_then_else
4918          (match_operator:SI 0 "comparison_operator"
4919                             [(match_operand:SI 2 "register_operand" "d")
4920                              (const_int 0)])
4921         (pc)
4922         (label_ref (match_operand 1 "" ""))))]
4923   "!TARGET_MIPS16"
4925   return mips_output_conditional_branch (insn,
4926                                          operands,
4927                                          /*two_operands_p=*/0,
4928                                          /*float_p=*/0,
4929                                          /*inverted_p=*/1,
4930                                          get_attr_length (insn));
4932   [(set_attr "type"     "branch")
4933    (set_attr "mode"     "none")])
4935 (define_insn "branch_zero_di"
4936   [(set (pc)
4937         (if_then_else
4938          (match_operator:DI 0 "comparison_operator"
4939                             [(match_operand:DI 2 "register_operand" "d")
4940                              (const_int 0)])
4941         (label_ref (match_operand 1 "" ""))
4942         (pc)))]
4943   "!TARGET_MIPS16"
4945   return mips_output_conditional_branch (insn,
4946                                          operands,
4947                                          /*two_operands_p=*/0,
4948                                          /*float_p=*/0,
4949                                          /*inverted_p=*/0,
4950                                          get_attr_length (insn));
4952   [(set_attr "type"     "branch")
4953    (set_attr "mode"     "none")])
4955 (define_insn "branch_zero_di_inverted"
4956   [(set (pc)
4957         (if_then_else
4958          (match_operator:DI 0 "comparison_operator"
4959                             [(match_operand:DI 2 "register_operand" "d")
4960                              (const_int 0)])
4961         (pc)
4962         (label_ref (match_operand 1 "" ""))))]
4963   "!TARGET_MIPS16"
4965   return mips_output_conditional_branch (insn,
4966                                          operands,
4967                                          /*two_operands_p=*/0,
4968                                          /*float_p=*/0,
4969                                          /*inverted_p=*/1,
4970                                          get_attr_length (insn));
4972   [(set_attr "type"     "branch")
4973    (set_attr "mode"     "none")])
4975 ;; Conditional branch on equality comparison.
4977 (define_insn "branch_equality"
4978   [(set (pc)
4979         (if_then_else
4980          (match_operator:SI 0 "equality_operator"
4981                             [(match_operand:SI 2 "register_operand" "d")
4982                              (match_operand:SI 3 "register_operand" "d")])
4983          (label_ref (match_operand 1 "" ""))
4984          (pc)))]
4985   "!TARGET_MIPS16"
4987   return mips_output_conditional_branch (insn,
4988                                          operands,
4989                                          /*two_operands_p=*/1,
4990                                          /*float_p=*/0,
4991                                          /*inverted_p=*/0,
4992                                          get_attr_length (insn));
4994   [(set_attr "type"     "branch")
4995    (set_attr "mode"     "none")])
4997 (define_insn "branch_equality_di"
4998   [(set (pc)
4999         (if_then_else
5000          (match_operator:DI 0 "equality_operator"
5001                             [(match_operand:DI 2 "register_operand" "d")
5002                              (match_operand:DI 3 "register_operand" "d")])
5003         (label_ref (match_operand 1 "" ""))
5004         (pc)))]
5005   "!TARGET_MIPS16"
5007   return mips_output_conditional_branch (insn,
5008                                          operands,
5009                                          /*two_operands_p=*/1,
5010                                          /*float_p=*/0,
5011                                          /*inverted_p=*/0,
5012                                          get_attr_length (insn));
5014   [(set_attr "type"     "branch")
5015    (set_attr "mode"     "none")])
5017 (define_insn "branch_equality_inverted"
5018   [(set (pc)
5019         (if_then_else
5020          (match_operator:SI 0 "equality_operator"
5021                             [(match_operand:SI 2 "register_operand" "d")
5022                              (match_operand:SI 3 "register_operand" "d")])
5023          (pc)
5024          (label_ref (match_operand 1 "" ""))))]
5025   "!TARGET_MIPS16"
5027   return mips_output_conditional_branch (insn,
5028                                          operands,
5029                                          /*two_operands_p=*/1,
5030                                          /*float_p=*/0,
5031                                          /*inverted_p=*/1,
5032                                          get_attr_length (insn));
5034   [(set_attr "type"     "branch")
5035    (set_attr "mode"     "none")])
5037 (define_insn "branch_equality_di_inverted"
5038   [(set (pc)
5039         (if_then_else
5040          (match_operator:DI 0 "equality_operator"
5041                             [(match_operand:DI 2 "register_operand" "d")
5042                              (match_operand:DI 3 "register_operand" "d")])
5043         (pc)
5044         (label_ref (match_operand 1 "" ""))))]
5045   "!TARGET_MIPS16"
5047   return mips_output_conditional_branch (insn,
5048                                          operands,
5049                                          /*two_operands_p=*/1,
5050                                          /*float_p=*/0,
5051                                          /*inverted_p=*/1,
5052                                          get_attr_length (insn));
5054   [(set_attr "type"     "branch")
5055    (set_attr "mode"     "none")])
5057 ;; MIPS16 branches
5059 (define_insn ""
5060   [(set (pc)
5061         (if_then_else
5062          (match_operator:SI 0 "equality_operator"
5063                             [(match_operand:SI 1 "register_operand" "d,t")
5064                              (const_int 0)])
5065         (match_operand 2 "pc_or_label_operand" "")
5066         (match_operand 3 "pc_or_label_operand" "")))]
5067   "TARGET_MIPS16"
5069   if (operands[2] != pc_rtx)
5070     {
5071       if (which_alternative == 0)
5072         return "b%C0z\t%1,%2";
5073       else
5074         return "bt%C0z\t%2";
5075     }
5076   else
5077     {
5078       if (which_alternative == 0)
5079         return "b%N0z\t%1,%3";
5080       else
5081         return "bt%N0z\t%3";
5082     }
5084   [(set_attr "type"     "branch")
5085    (set_attr "mode"     "none")
5086    (set_attr "length"   "8")])
5088 (define_insn ""
5089   [(set (pc)
5090         (if_then_else
5091          (match_operator:DI 0 "equality_operator"
5092                             [(match_operand:DI 1 "register_operand" "d,t")
5093                              (const_int 0)])
5094         (match_operand 2 "pc_or_label_operand" "")
5095         (match_operand 3 "pc_or_label_operand" "")))]
5096   "TARGET_MIPS16"
5098   if (operands[2] != pc_rtx)
5099     {
5100       if (which_alternative == 0)
5101         return "b%C0z\t%1,%2";
5102       else
5103         return "bt%C0z\t%2";
5104     }
5105   else
5106     {
5107       if (which_alternative == 0)
5108         return "b%N0z\t%1,%3";
5109       else
5110         return "bt%N0z\t%3";
5111     }
5113   [(set_attr "type"     "branch")
5114    (set_attr "mode"     "none")
5115    (set_attr "length"   "8")])
5117 (define_expand "b<code>"
5118   [(set (pc)
5119         (if_then_else (any_cond:CC (cc0)
5120                                    (const_int 0))
5121                       (label_ref (match_operand 0 ""))
5122                       (pc)))]
5123   ""
5125   gen_conditional_branch (operands, <CODE>);
5126   DONE;
5130 ;;  ....................
5132 ;;      SETTING A REGISTER FROM A COMPARISON
5134 ;;  ....................
5136 (define_expand "seq"
5137   [(set (match_operand:SI 0 "register_operand")
5138         (eq:SI (match_dup 1)
5139                (match_dup 2)))]
5140   ""
5141   { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
5143 (define_insn "*seq_si"
5144   [(set (match_operand:SI 0 "register_operand" "=d")
5145         (eq:SI (match_operand:SI 1 "register_operand" "d")
5146                (const_int 0)))]
5147   "!TARGET_MIPS16"
5148   "sltu\t%0,%1,1"
5149   [(set_attr "type" "slt")
5150    (set_attr "mode" "SI")])
5152 (define_insn "*seq_si_mips16"
5153   [(set (match_operand:SI 0 "register_operand" "=t")
5154         (eq:SI (match_operand:SI 1 "register_operand" "d")
5155                (const_int 0)))]
5156   "TARGET_MIPS16"
5157   "sltu\t%1,1"
5158   [(set_attr "type" "slt")
5159    (set_attr "mode" "SI")])
5161 (define_insn "*seq_di"
5162   [(set (match_operand:DI 0 "register_operand" "=d")
5163         (eq:DI (match_operand:DI 1 "register_operand" "d")
5164                (const_int 0)))]
5165   "TARGET_64BIT && !TARGET_MIPS16"
5166   "sltu\t%0,%1,1"
5167   [(set_attr "type" "slt")
5168    (set_attr "mode" "DI")])
5170 (define_insn "*seq_di_mips16"
5171   [(set (match_operand:DI 0 "register_operand" "=t")
5172         (eq:DI (match_operand:DI 1 "register_operand" "d")
5173                (const_int 0)))]
5174   "TARGET_64BIT && TARGET_MIPS16"
5175   "sltu\t%1,1"
5176   [(set_attr "type" "slt")
5177    (set_attr "mode" "DI")])
5179 ;; "sne" uses sltu instructions in which the first operand is $0.
5180 ;; This isn't possible in mips16 code.
5182 (define_expand "sne"
5183   [(set (match_operand:SI 0 "register_operand")
5184         (ne:SI (match_dup 1)
5185                (match_dup 2)))]
5186   "!TARGET_MIPS16"
5187   { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
5189 (define_insn "*sne_si"
5190   [(set (match_operand:SI 0 "register_operand" "=d")
5191         (ne:SI (match_operand:SI 1 "register_operand" "d")
5192                (const_int 0)))]
5193   "!TARGET_MIPS16"
5194   "sltu\t%0,%.,%1"
5195   [(set_attr "type" "slt")
5196    (set_attr "mode" "SI")])
5198 (define_insn "*sne_di"
5199   [(set (match_operand:DI 0 "register_operand" "=d")
5200         (ne:DI (match_operand:DI 1 "register_operand" "d")
5201                (const_int 0)))]
5202   "TARGET_64BIT && !TARGET_MIPS16"
5203   "sltu\t%0,%.,%1"
5204   [(set_attr "type" "slt")
5205    (set_attr "mode" "DI")])
5207 (define_expand "sgt"
5208   [(set (match_operand:SI 0 "register_operand")
5209         (gt:SI (match_dup 1)
5210                (match_dup 2)))]
5211   ""
5212   { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
5214 (define_insn "*sgt_si"
5215   [(set (match_operand:SI 0 "register_operand" "=d")
5216         (gt:SI (match_operand:SI 1 "register_operand" "d")
5217                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
5218   "!TARGET_MIPS16"
5219   "slt\t%0,%z2,%1"
5220   [(set_attr "type" "slt")
5221    (set_attr "mode" "SI")])
5223 (define_insn "*sgt_si_mips16"
5224   [(set (match_operand:SI 0 "register_operand" "=t")
5225         (gt:SI (match_operand:SI 1 "register_operand" "d")
5226                (match_operand:SI 2 "register_operand" "d")))]
5227   "TARGET_MIPS16"
5228   "slt\t%2,%1"
5229   [(set_attr "type" "slt")
5230    (set_attr "mode" "SI")])
5232 (define_insn "*sgt_di"
5233   [(set (match_operand:DI 0 "register_operand" "=d")
5234         (gt:DI (match_operand:DI 1 "register_operand" "d")
5235                (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
5236   "TARGET_64BIT && !TARGET_MIPS16"
5237   "slt\t%0,%z2,%1"
5238   [(set_attr "type" "slt")
5239    (set_attr "mode" "DI")])
5241 (define_insn "*sgt_di_mips16"
5242   [(set (match_operand:DI 0 "register_operand" "=t")
5243         (gt:DI (match_operand:DI 1 "register_operand" "d")
5244                (match_operand:DI 2 "register_operand" "d")))]
5245   "TARGET_64BIT && TARGET_MIPS16"
5246   "slt\t%2,%1"
5247   [(set_attr "type" "slt")
5248    (set_attr "mode" "DI")])
5250 (define_expand "sge"
5251   [(set (match_operand:SI 0 "register_operand")
5252         (ge:SI (match_dup 1)
5253                (match_dup 2)))]
5254   ""
5255   { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
5257 (define_insn "*sge_si"
5258   [(set (match_operand:SI 0 "register_operand" "=d")
5259         (ge:SI (match_operand:SI 1 "register_operand" "d")
5260                (const_int 1)))]
5261   "!TARGET_MIPS16"
5262   "slt\t%0,%.,%1"
5263   [(set_attr "type" "slt")
5264    (set_attr "mode" "SI")])
5266 (define_insn "*sge_di"
5267   [(set (match_operand:DI 0 "register_operand" "=d")
5268         (ge:DI (match_operand:DI 1 "register_operand" "d")
5269                (const_int 1)))]
5270   "TARGET_64BIT && !TARGET_MIPS16"
5271   "slt\t%0,%.,%1"
5272   [(set_attr "type" "slt")
5273    (set_attr "mode" "DI")])
5275 (define_expand "slt"
5276   [(set (match_operand:SI 0 "register_operand")
5277         (lt:SI (match_dup 1)
5278                (match_dup 2)))]
5279   ""
5280   { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
5282 (define_insn "*slt_si"
5283   [(set (match_operand:SI 0 "register_operand" "=d")
5284         (lt:SI (match_operand:SI 1 "register_operand" "d")
5285                (match_operand:SI 2 "arith_operand" "dI")))]
5286   "!TARGET_MIPS16"
5287   "slt\t%0,%1,%2"
5288   [(set_attr "type" "slt")
5289    (set_attr "mode" "SI")])
5291 (define_insn "*slt_si_mips16"
5292   [(set (match_operand:SI 0 "register_operand" "=t,t")
5293         (lt:SI (match_operand:SI 1 "register_operand" "d,d")
5294                (match_operand:SI 2 "arith_operand" "d,I")))]
5295   "TARGET_MIPS16"
5296   "slt\t%1,%2"
5297   [(set_attr "type" "slt")
5298    (set_attr "mode" "SI")
5299    (set_attr_alternative "length"
5300                 [(const_int 4)
5301                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
5302                                (const_int 4)
5303                                (const_int 8))])])
5305 (define_insn "*slt_di"
5306   [(set (match_operand:DI 0 "register_operand" "=d")
5307         (lt:DI (match_operand:DI 1 "register_operand" "d")
5308                (match_operand:DI 2 "arith_operand" "dI")))]
5309   "TARGET_64BIT && !TARGET_MIPS16"
5310   "slt\t%0,%1,%2"
5311   [(set_attr "type" "slt")
5312    (set_attr "mode" "DI")])
5314 (define_insn "*slt_di_mips16"
5315   [(set (match_operand:DI 0 "register_operand" "=t,t")
5316         (lt:DI (match_operand:DI 1 "register_operand" "d,d")
5317                (match_operand:DI 2 "arith_operand" "d,I")))]
5318   "TARGET_64BIT && TARGET_MIPS16"
5319   "slt\t%1,%2"
5320   [(set_attr "type" "slt")
5321    (set_attr "mode" "DI")
5322    (set_attr_alternative "length"
5323                 [(const_int 4)
5324                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
5325                                (const_int 4)
5326                                (const_int 8))])])
5328 (define_expand "sle"
5329   [(set (match_operand:SI 0 "register_operand")
5330         (le:SI (match_dup 1)
5331                (match_dup 2)))]
5332   ""
5333   { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
5335 (define_insn "*sle_si"
5336   [(set (match_operand:SI 0 "register_operand" "=d")
5337         (le:SI (match_operand:SI 1 "register_operand" "d")
5338                (match_operand:SI 2 "sle_operand" "")))]
5339   "!TARGET_MIPS16"
5341   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5342   return "slt\t%0,%1,%2";
5344   [(set_attr "type" "slt")
5345    (set_attr "mode" "SI")])
5347 (define_insn "*sle_si_mips16"
5348   [(set (match_operand:SI 0 "register_operand" "=t")
5349         (le:SI (match_operand:SI 1 "register_operand" "d")
5350                (match_operand:SI 2 "sle_operand" "")))]
5351   "TARGET_MIPS16"
5353   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5354   return "slt\t%1,%2";
5356   [(set_attr "type" "slt")
5357    (set_attr "mode" "SI")
5358    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
5359                                       (const_int 4)
5360                                       (const_int 8)))])
5362 (define_insn "*sle_di"
5363   [(set (match_operand:DI 0 "register_operand" "=d")
5364         (le:DI (match_operand:DI 1 "register_operand" "d")
5365                (match_operand:DI 2 "sle_operand" "")))]
5366   "TARGET_64BIT && !TARGET_MIPS16"
5368   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5369   return "slt\t%0,%1,%2";
5371   [(set_attr "type" "slt")
5372    (set_attr "mode" "DI")])
5374 (define_insn "*sle_di_mips16"
5375   [(set (match_operand:DI 0 "register_operand" "=t")
5376         (le:DI (match_operand:DI 1 "register_operand" "d")
5377                (match_operand:DI 2 "sle_operand" "")))]
5378   "TARGET_64BIT && TARGET_MIPS16"
5380   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5381   return "slt\t%1,%2";
5383   [(set_attr "type" "slt")
5384    (set_attr "mode" "DI")
5385    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
5386                                       (const_int 4)
5387                                       (const_int 8)))])
5389 (define_expand "sgtu"
5390   [(set (match_operand:SI 0 "register_operand")
5391         (gtu:SI (match_dup 1)
5392                 (match_dup 2)))]
5393   ""
5394   { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
5396 (define_insn "*sgtu_si"
5397   [(set (match_operand:SI 0 "register_operand" "=d")
5398         (gtu:SI (match_operand:SI 1 "register_operand" "d")
5399                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
5400   "!TARGET_MIPS16"
5401   "sltu\t%0,%z2,%1"
5402   [(set_attr "type" "slt")
5403    (set_attr "mode" "SI")])
5405 (define_insn "*sgtu_si_mips16"
5406   [(set (match_operand:SI 0 "register_operand" "=t")
5407         (gtu:SI (match_operand:SI 1 "register_operand" "d")
5408                 (match_operand:SI 2 "register_operand" "d")))]
5409   "TARGET_MIPS16"
5410   "sltu\t%2,%1"
5411   [(set_attr "type" "slt")
5412    (set_attr "mode" "SI")])
5414 (define_insn "*sgtu_di"
5415   [(set (match_operand:DI 0 "register_operand" "=d")
5416         (gtu:DI (match_operand:DI 1 "register_operand" "d")
5417                 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
5418   "TARGET_64BIT && !TARGET_MIPS16"
5419   "sltu\t%0,%z2,%1"
5420   [(set_attr "type" "slt")
5421    (set_attr "mode" "DI")])
5423 (define_insn "*sgtu_di_mips16"
5424   [(set (match_operand:DI 0 "register_operand" "=t")
5425         (gtu:DI (match_operand:DI 1 "register_operand" "d")
5426                 (match_operand:DI 2 "register_operand" "d")))]
5427   "TARGET_64BIT && TARGET_MIPS16"
5428   "sltu\t%2,%1"
5429   [(set_attr "type" "slt")
5430    (set_attr "mode" "DI")])
5432 (define_expand "sgeu"
5433   [(set (match_operand:SI 0 "register_operand")
5434         (geu:SI (match_dup 1)
5435                 (match_dup 2)))]
5436   ""
5437   { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
5439 (define_insn "*sge_si"
5440   [(set (match_operand:SI 0 "register_operand" "=d")
5441         (geu:SI (match_operand:SI 1 "register_operand" "d")
5442                 (const_int 1)))]
5443   "!TARGET_MIPS16"
5444   "sltu\t%0,%.,%1"
5445   [(set_attr "type" "slt")
5446    (set_attr "mode" "SI")])
5448 (define_insn "*sge_di"
5449   [(set (match_operand:DI 0 "register_operand" "=d")
5450         (geu:DI (match_operand:DI 1 "register_operand" "d")
5451                 (const_int 1)))]
5452   "TARGET_64BIT && !TARGET_MIPS16"
5453   "sltu\t%0,%.,%1"
5454   [(set_attr "type" "slt")
5455    (set_attr "mode" "DI")])
5457 (define_expand "sltu"
5458   [(set (match_operand:SI 0 "register_operand")
5459         (ltu:SI (match_dup 1)
5460                 (match_dup 2)))]
5461   ""
5462   { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
5464 (define_insn "*sltu_si"
5465   [(set (match_operand:SI 0 "register_operand" "=d")
5466         (ltu:SI (match_operand:SI 1 "register_operand" "d")
5467                 (match_operand:SI 2 "arith_operand" "dI")))]
5468   "!TARGET_MIPS16"
5469   "sltu\t%0,%1,%2"
5470   [(set_attr "type" "slt")
5471    (set_attr "mode" "SI")])
5473 (define_insn "*sltu_si_mips16"
5474   [(set (match_operand:SI 0 "register_operand" "=t,t")
5475         (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
5476                 (match_operand:SI 2 "arith_operand" "d,I")))]
5477   "TARGET_MIPS16"
5478   "sltu\t%1,%2"
5479   [(set_attr "type" "slt")
5480    (set_attr "mode" "SI")
5481    (set_attr_alternative "length"
5482                 [(const_int 4)
5483                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
5484                                (const_int 4)
5485                                (const_int 8))])])
5487 (define_insn "*sltu_di"
5488   [(set (match_operand:DI 0 "register_operand" "=d")
5489         (ltu:DI (match_operand:DI 1 "register_operand" "d")
5490                 (match_operand:DI 2 "arith_operand" "dI")))]
5491   "TARGET_64BIT && !TARGET_MIPS16"
5492   "sltu\t%0,%1,%2"
5493   [(set_attr "type" "slt")
5494    (set_attr "mode" "DI")])
5496 (define_insn "*sltu_di_mips16"
5497   [(set (match_operand:DI 0 "register_operand" "=t,t")
5498         (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
5499                 (match_operand:DI 2 "arith_operand" "d,I")))]
5500   "TARGET_64BIT && TARGET_MIPS16"
5501   "sltu\t%1,%2"
5502   [(set_attr "type" "slt")
5503    (set_attr "mode" "DI")
5504    (set_attr_alternative "length"
5505                 [(const_int 4)
5506                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
5507                                (const_int 4)
5508                                (const_int 8))])])
5510 (define_expand "sleu"
5511   [(set (match_operand:SI 0 "register_operand")
5512         (leu:SI (match_dup 1)
5513                 (match_dup 2)))]
5514   ""
5515   { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
5517 (define_insn "*sleu_si"
5518   [(set (match_operand:SI 0 "register_operand" "=d")
5519         (leu:SI (match_operand:SI 1 "register_operand" "d")
5520                 (match_operand:SI 2 "sleu_operand" "")))]
5521   "!TARGET_MIPS16"
5523   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5524   return "sltu\t%0,%1,%2";
5526   [(set_attr "type" "slt")
5527    (set_attr "mode" "SI")])
5529 (define_insn "*sleu_si_mips16"
5530   [(set (match_operand:SI 0 "register_operand" "=t")
5531         (leu:SI (match_operand:SI 1 "register_operand" "d")
5532                 (match_operand:SI 2 "sleu_operand" "")))]
5533   "TARGET_MIPS16"
5535   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5536   return "sltu\t%1,%2";
5538   [(set_attr "type" "slt")
5539    (set_attr "mode" "SI")
5540    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
5541                                       (const_int 4)
5542                                       (const_int 8)))])
5544 (define_insn "*sleu_di"
5545   [(set (match_operand:DI 0 "register_operand" "=d")
5546         (leu:DI (match_operand:DI 1 "register_operand" "d")
5547                 (match_operand:DI 2 "sleu_operand" "")))]
5548   "TARGET_64BIT && !TARGET_MIPS16"
5550   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5551   return "sltu\t%0,%1,%2";
5553   [(set_attr "type" "slt")
5554    (set_attr "mode" "DI")])
5556 (define_insn "*sleu_di_mips16"
5557   [(set (match_operand:DI 0 "register_operand" "=t")
5558         (leu:DI (match_operand:DI 1 "register_operand" "d")
5559                 (match_operand:DI 2 "sleu_operand" "")))]
5560   "TARGET_64BIT && TARGET_MIPS16"
5562   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5563   return "sltu\t%1,%2";
5565   [(set_attr "type" "slt")
5566    (set_attr "mode" "DI")
5567    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
5568                                       (const_int 4)
5569                                       (const_int 8)))])
5572 ;;  ....................
5574 ;;      FLOATING POINT COMPARISONS
5576 ;;  ....................
5578 (define_insn "sunordered_df"
5579   [(set (match_operand:CC 0 "register_operand" "=z")
5580         (unordered:CC (match_operand:DF 1 "register_operand" "f")
5581                       (match_operand:DF 2 "register_operand" "f")))]
5582   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5583   "c.un.d\t%Z0%1,%2"
5584   [(set_attr "type" "fcmp")
5585    (set_attr "mode" "FPSW")])
5587 (define_insn "sunlt_df"
5588   [(set (match_operand:CC 0 "register_operand" "=z")
5589         (unlt:CC (match_operand:DF 1 "register_operand" "f")
5590                  (match_operand:DF 2 "register_operand" "f")))]
5591   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5592   "c.ult.d\t%Z0%1,%2"
5593   [(set_attr "type" "fcmp")
5594    (set_attr "mode" "FPSW")])
5596 (define_insn "suneq_df"
5597   [(set (match_operand:CC 0 "register_operand" "=z")
5598         (uneq:CC (match_operand:DF 1 "register_operand" "f")
5599                  (match_operand:DF 2 "register_operand" "f")))]
5600   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5601   "c.ueq.d\t%Z0%1,%2"
5602   [(set_attr "type" "fcmp")
5603    (set_attr "mode" "FPSW")])
5605 (define_insn "sunle_df"
5606   [(set (match_operand:CC 0 "register_operand" "=z")
5607         (unle:CC (match_operand:DF 1 "register_operand" "f")
5608                  (match_operand:DF 2 "register_operand" "f")))]
5609   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5610   "c.ule.d\t%Z0%1,%2"
5611   [(set_attr "type" "fcmp")
5612    (set_attr "mode" "FPSW")])
5614 (define_insn "seq_df"
5615   [(set (match_operand:CC 0 "register_operand" "=z")
5616         (eq:CC (match_operand:DF 1 "register_operand" "f")
5617                (match_operand:DF 2 "register_operand" "f")))]
5618   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5619   "c.eq.d\t%Z0%1,%2"
5620   [(set_attr "type" "fcmp")
5621    (set_attr "mode" "FPSW")])
5623 (define_insn "slt_df"
5624   [(set (match_operand:CC 0 "register_operand" "=z")
5625         (lt:CC (match_operand:DF 1 "register_operand" "f")
5626                (match_operand:DF 2 "register_operand" "f")))]
5627   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5628   "c.lt.d\t%Z0%1,%2"
5629   [(set_attr "type" "fcmp")
5630    (set_attr "mode" "FPSW")])
5632 (define_insn "sle_df"
5633   [(set (match_operand:CC 0 "register_operand" "=z")
5634         (le:CC (match_operand:DF 1 "register_operand" "f")
5635                (match_operand:DF 2 "register_operand" "f")))]
5636   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5637   "c.le.d\t%Z0%1,%2"
5638   [(set_attr "type" "fcmp")
5639    (set_attr "mode" "FPSW")])
5641 (define_insn "sgt_df"
5642   [(set (match_operand:CC 0 "register_operand" "=z")
5643         (gt:CC (match_operand:DF 1 "register_operand" "f")
5644                (match_operand:DF 2 "register_operand" "f")))]
5645   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5646   "c.lt.d\t%Z0%2,%1"
5647   [(set_attr "type" "fcmp")
5648    (set_attr "mode" "FPSW")])
5650 (define_insn "sge_df"
5651   [(set (match_operand:CC 0 "register_operand" "=z")
5652         (ge:CC (match_operand:DF 1 "register_operand" "f")
5653                (match_operand:DF 2 "register_operand" "f")))]
5654   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5655   "c.le.d\t%Z0%2,%1"
5656   [(set_attr "type" "fcmp")
5657    (set_attr "mode" "FPSW")])
5659 (define_insn "sunordered_sf"
5660   [(set (match_operand:CC 0 "register_operand" "=z")
5661         (unordered:CC (match_operand:SF 1 "register_operand" "f")
5662                       (match_operand:SF 2 "register_operand" "f")))]
5663   "TARGET_HARD_FLOAT"
5664   "c.un.s\t%Z0%1,%2"
5665   [(set_attr "type" "fcmp")
5666    (set_attr "mode" "FPSW")])
5668 (define_insn "sunlt_sf"
5669   [(set (match_operand:CC 0 "register_operand" "=z")
5670         (unlt:CC (match_operand:SF 1 "register_operand" "f")
5671                  (match_operand:SF 2 "register_operand" "f")))]
5672   "TARGET_HARD_FLOAT"
5673   "c.ult.s\t%Z0%1,%2"
5674   [(set_attr "type" "fcmp")
5675    (set_attr "mode" "FPSW")])
5677 (define_insn "suneq_sf"
5678   [(set (match_operand:CC 0 "register_operand" "=z")
5679         (uneq:CC (match_operand:SF 1 "register_operand" "f")
5680                  (match_operand:SF 2 "register_operand" "f")))]
5681   "TARGET_HARD_FLOAT"
5682   "c.ueq.s\t%Z0%1,%2"
5683   [(set_attr "type" "fcmp")
5684    (set_attr "mode" "FPSW")])
5686 (define_insn "sunle_sf"
5687   [(set (match_operand:CC 0 "register_operand" "=z")
5688         (unle:CC (match_operand:SF 1 "register_operand" "f")
5689                  (match_operand:SF 2 "register_operand" "f")))]
5690   "TARGET_HARD_FLOAT"
5691   "c.ule.s\t%Z0%1,%2"
5692   [(set_attr "type" "fcmp")
5693    (set_attr "mode" "FPSW")])
5695 (define_insn "seq_sf"
5696   [(set (match_operand:CC 0 "register_operand" "=z")
5697         (eq:CC (match_operand:SF 1 "register_operand" "f")
5698                (match_operand:SF 2 "register_operand" "f")))]
5699   "TARGET_HARD_FLOAT"
5700   "c.eq.s\t%Z0%1,%2"
5701   [(set_attr "type" "fcmp")
5702    (set_attr "mode" "FPSW")])
5704 (define_insn "slt_sf"
5705   [(set (match_operand:CC 0 "register_operand" "=z")
5706         (lt:CC (match_operand:SF 1 "register_operand" "f")
5707                (match_operand:SF 2 "register_operand" "f")))]
5708   "TARGET_HARD_FLOAT"
5709   "c.lt.s\t%Z0%1,%2"
5710   [(set_attr "type" "fcmp")
5711    (set_attr "mode" "FPSW")])
5713 (define_insn "sle_sf"
5714   [(set (match_operand:CC 0 "register_operand" "=z")
5715         (le:CC (match_operand:SF 1 "register_operand" "f")
5716                (match_operand:SF 2 "register_operand" "f")))]
5717   "TARGET_HARD_FLOAT"
5718   "c.le.s\t%Z0%1,%2"
5719   [(set_attr "type" "fcmp")
5720    (set_attr "mode" "FPSW")])
5722 (define_insn "sgt_sf"
5723   [(set (match_operand:CC 0 "register_operand" "=z")
5724         (gt:CC (match_operand:SF 1 "register_operand" "f")
5725                (match_operand:SF 2 "register_operand" "f")))]
5726   "TARGET_HARD_FLOAT"
5727   "c.lt.s\t%Z0%2,%1"
5728   [(set_attr "type" "fcmp")
5729    (set_attr "mode" "FPSW")])
5731 (define_insn "sge_sf"
5732   [(set (match_operand:CC 0 "register_operand" "=z")
5733         (ge:CC (match_operand:SF 1 "register_operand" "f")
5734                (match_operand:SF 2 "register_operand" "f")))]
5735   "TARGET_HARD_FLOAT"
5736   "c.le.s\t%Z0%2,%1"
5737   [(set_attr "type" "fcmp")
5738    (set_attr "mode" "FPSW")])
5741 ;;  ....................
5743 ;;      UNCONDITIONAL BRANCHES
5745 ;;  ....................
5747 ;; Unconditional branches.
5749 (define_insn "jump"
5750   [(set (pc)
5751         (label_ref (match_operand 0 "" "")))]
5752   "!TARGET_MIPS16"
5754   if (flag_pic)
5755     {
5756       if (get_attr_length (insn) <= 8)
5757         return "%*b\t%l0%/";
5758       else
5759         {
5760           output_asm_insn (mips_output_load_label (), operands);
5761           return "%*jr\t%@%/%]";
5762         }
5763     }
5764   else
5765     return "%*j\t%l0%/";
5767   [(set_attr "type"     "jump")
5768    (set_attr "mode"     "none")
5769    (set (attr "length")
5770         ;; We can't use `j' when emitting PIC.  Emit a branch if it's
5771         ;; in range, otherwise load the address of the branch target into
5772         ;; $at and then jump to it.
5773         (if_then_else
5774          (ior (eq (symbol_ref "flag_pic") (const_int 0))
5775               (lt (abs (minus (match_dup 0)
5776                               (plus (pc) (const_int 4))))
5777                   (const_int 131072)))
5778          (const_int 4) (const_int 16)))])
5780 ;; We need a different insn for the mips16, because a mips16 branch
5781 ;; does not have a delay slot.
5783 (define_insn ""
5784   [(set (pc)
5785         (label_ref (match_operand 0 "" "")))]
5786   "TARGET_MIPS16"
5787   "b\t%l0"
5788   [(set_attr "type"     "branch")
5789    (set_attr "mode"     "none")
5790    (set_attr "length"   "8")])
5792 (define_expand "indirect_jump"
5793   [(set (pc) (match_operand 0 "register_operand"))]
5794   ""
5796   rtx dest;
5798   dest = operands[0];
5799   if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
5800     operands[0] = copy_to_mode_reg (Pmode, dest);
5802   if (!(Pmode == DImode))
5803     emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
5804   else
5805     emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
5807   DONE;
5810 (define_insn "indirect_jump_internal1"
5811   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
5812   "!(Pmode == DImode)"
5813   "%*j\t%0%/"
5814   [(set_attr "type"     "jump")
5815    (set_attr "mode"     "none")])
5817 (define_insn "indirect_jump_internal2"
5818   [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
5819   "Pmode == DImode"
5820   "%*j\t%0%/"
5821   [(set_attr "type"     "jump")
5822    (set_attr "mode"     "none")])
5824 (define_expand "tablejump"
5825   [(set (pc)
5826         (match_operand 0 "register_operand"))
5827    (use (label_ref (match_operand 1 "")))]
5828   ""
5830   if (TARGET_MIPS16)
5831     {
5832       if (GET_MODE (operands[0]) != HImode)
5833         abort ();
5834       if (!(Pmode == DImode))
5835         emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
5836       else
5837         emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
5838       DONE;
5839     }
5841   if (GET_MODE (operands[0]) != ptr_mode)
5842     abort ();
5844   if (TARGET_GPWORD)
5845     operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
5846                                 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
5848   if (Pmode == SImode)
5849     emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
5850   else
5851     emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
5852   DONE;
5855 (define_insn "tablejump_internal1"
5856   [(set (pc)
5857         (match_operand:SI 0 "register_operand" "d"))
5858    (use (label_ref (match_operand 1 "" "")))]
5859   ""
5860   "%*j\t%0%/"
5861   [(set_attr "type"     "jump")
5862    (set_attr "mode"     "none")])
5864 (define_insn "tablejump_internal2"
5865   [(set (pc)
5866         (match_operand:DI 0 "register_operand" "d"))
5867    (use (label_ref (match_operand 1 "" "")))]
5868   "TARGET_64BIT"
5869   "%*j\t%0%/"
5870   [(set_attr "type"     "jump")
5871    (set_attr "mode"     "none")])
5873 (define_expand "tablejump_mips161"
5874   [(set (pc) (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand"))
5875                       (label_ref:SI (match_operand 1 ""))))]
5876   "TARGET_MIPS16 && !(Pmode == DImode)"
5878   rtx t1, t2, t3;
5880   t1 = gen_reg_rtx (SImode);
5881   t2 = gen_reg_rtx (SImode);
5882   t3 = gen_reg_rtx (SImode);
5883   emit_insn (gen_extendhisi2 (t1, operands[0]));
5884   emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
5885   emit_insn (gen_addsi3 (t3, t1, t2));
5886   emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
5887   DONE;
5890 (define_expand "tablejump_mips162"
5891   [(set (pc) (plus:DI (sign_extend:DI (match_operand:HI 0 "register_operand"))
5892                       (label_ref:DI (match_operand 1 ""))))]
5893   "TARGET_MIPS16 && Pmode == DImode"
5895   rtx t1, t2, t3;
5897   t1 = gen_reg_rtx (DImode);
5898   t2 = gen_reg_rtx (DImode);
5899   t3 = gen_reg_rtx (DImode);
5900   emit_insn (gen_extendhidi2 (t1, operands[0]));
5901   emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
5902   emit_insn (gen_adddi3 (t3, t1, t2));
5903   emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
5904   DONE;
5907 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
5908 ;; While it is possible to either pull it off the stack (in the
5909 ;; o32 case) or recalculate it given t9 and our target label,
5910 ;; it takes 3 or 4 insns to do so.
5912 (define_expand "builtin_setjmp_setup"
5913   [(use (match_operand 0 "register_operand"))]
5914   "TARGET_ABICALLS"
5916   rtx addr;
5918   addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
5919   emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
5920   DONE;
5923 ;; Restore the gp that we saved above.  Despite the earlier comment, it seems
5924 ;; that older code did recalculate the gp from $25.  Continue to jump through
5925 ;; $25 for compatibility (we lose nothing by doing so).
5927 (define_expand "builtin_longjmp"
5928   [(use (match_operand 0 "register_operand"))]
5929   "TARGET_ABICALLS"
5931   /* The elements of the buffer are, in order:  */
5932   int W = GET_MODE_SIZE (Pmode);
5933   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5934   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
5935   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
5936   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
5937   rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
5938   /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
5939      The target is bound to be using $28 as the global pointer
5940      but the current function might not be.  */
5941   rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
5943   /* This bit is similar to expand_builtin_longjmp except that it
5944      restores $gp as well.  */
5945   emit_move_insn (hard_frame_pointer_rtx, fp);
5946   emit_move_insn (pv, lab);
5947   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5948   emit_move_insn (gp, gpv);
5949   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5950   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5951   emit_insn (gen_rtx_USE (VOIDmode, gp));
5952   emit_indirect_jump (pv);
5953   DONE;
5957 ;;  ....................
5959 ;;      Function prologue/epilogue
5961 ;;  ....................
5964 (define_expand "prologue"
5965   [(const_int 1)]
5966   ""
5968   mips_expand_prologue ();
5969   DONE;
5972 ;; Block any insns from being moved before this point, since the
5973 ;; profiling call to mcount can use various registers that aren't
5974 ;; saved or used to pass arguments.
5976 (define_insn "blockage"
5977   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
5978   ""
5979   ""
5980   [(set_attr "type"     "unknown")
5981    (set_attr "mode"     "none")
5982    (set_attr "length"   "0")])
5984 (define_expand "epilogue"
5985   [(const_int 2)]
5986   ""
5988   mips_expand_epilogue (false);
5989   DONE;
5992 (define_expand "sibcall_epilogue"
5993   [(const_int 2)]
5994   ""
5996   mips_expand_epilogue (true);
5997   DONE;
6000 ;; Trivial return.  Make it look like a normal return insn as that
6001 ;; allows jump optimizations to work better.
6003 (define_insn "return"
6004   [(return)]
6005   "mips_can_use_return_insn ()"
6006   "%*j\t$31%/"
6007   [(set_attr "type"     "jump")
6008    (set_attr "mode"     "none")])
6010 ;; Normal return.
6012 (define_insn "return_internal"
6013   [(return)
6014    (use (match_operand 0 "pmode_register_operand" ""))]
6015   ""
6016   "%*j\t%0%/"
6017   [(set_attr "type"     "jump")
6018    (set_attr "mode"     "none")])
6020 ;; This is used in compiling the unwind routines.
6021 (define_expand "eh_return"
6022   [(use (match_operand 0 "general_operand"))]
6023   ""
6025   enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
6027   if (GET_MODE (operands[0]) != gpr_mode)
6028     operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
6029   if (TARGET_64BIT)
6030     emit_insn (gen_eh_set_lr_di (operands[0]));
6031   else
6032     emit_insn (gen_eh_set_lr_si (operands[0]));
6034   DONE;
6037 ;; Clobber the return address on the stack.  We can't expand this
6038 ;; until we know where it will be put in the stack frame.
6040 (define_insn "eh_set_lr_si"
6041   [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6042    (clobber (match_scratch:SI 1 "=&d"))]
6043   "! TARGET_64BIT"
6044   "#")
6046 (define_insn "eh_set_lr_di"
6047   [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6048    (clobber (match_scratch:DI 1 "=&d"))]
6049   "TARGET_64BIT"
6050   "#")
6052 (define_split
6053   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6054    (clobber (match_scratch 1))]
6055   "reload_completed && !TARGET_DEBUG_D_MODE"
6056   [(const_int 0)]
6058   mips_set_return_address (operands[0], operands[1]);
6059   DONE;
6062 (define_insn_and_split "exception_receiver"
6063   [(set (reg:SI 28)
6064         (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
6065   "TARGET_ABICALLS && TARGET_OLDABI"
6066   "#"
6067   "&& reload_completed"
6068   [(const_int 0)]
6070   mips_restore_gp ();
6071   DONE;
6073   [(set_attr "type"   "load")
6074    (set_attr "length" "12")])
6077 ;;  ....................
6079 ;;      FUNCTION CALLS
6081 ;;  ....................
6083 ;; Instructions to load a call address from the GOT.  The address might
6084 ;; point to a function or to a lazy binding stub.  In the latter case,
6085 ;; the stub will use the dynamic linker to resolve the function, which
6086 ;; in turn will change the GOT entry to point to the function's real
6087 ;; address.
6089 ;; This means that every call, even pure and constant ones, can
6090 ;; potentially modify the GOT entry.  And once a stub has been called,
6091 ;; we must not call it again.
6093 ;; We represent this restriction using an imaginary fixed register that
6094 ;; acts like a GOT version number.  By making the register call-clobbered,
6095 ;; we tell the target-independent code that the address could be changed
6096 ;; by any call insn.
6097 (define_insn "load_callsi"
6098   [(set (match_operand:SI 0 "register_operand" "=c")
6099         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6100                     (match_operand:SI 2 "immediate_operand" "")
6101                     (reg:SI FAKE_CALL_REGNO)]
6102                    UNSPEC_LOAD_CALL))]
6103   "TARGET_ABICALLS"
6104   "lw\t%0,%R2(%1)"
6105   [(set_attr "type" "load")
6106    (set_attr "length" "4")])
6108 (define_insn "load_calldi"
6109   [(set (match_operand:DI 0 "register_operand" "=c")
6110         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
6111                     (match_operand:DI 2 "immediate_operand" "")
6112                     (reg:DI FAKE_CALL_REGNO)]
6113                    UNSPEC_LOAD_CALL))]
6114   "TARGET_ABICALLS"
6115   "ld\t%0,%R2(%1)"
6116   [(set_attr "type" "load")
6117    (set_attr "length" "4")])
6119 ;; Sibling calls.  All these patterns use jump instructions.
6121 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
6122 ;; addresses if a direct jump is acceptable.  Since the 'S' constraint
6123 ;; is defined in terms of call_insn_operand, the same is true of the
6124 ;; constraints.
6126 ;; When we use an indirect jump, we need a register that will be
6127 ;; preserved by the epilogue.  Since TARGET_ABICALLS forces us to
6128 ;; use $25 for this purpose -- and $25 is never clobbered by the
6129 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
6131 (define_expand "sibcall"
6132   [(parallel [(call (match_operand 0 "")
6133                     (match_operand 1 ""))
6134               (use (match_operand 2 ""))        ;; next_arg_reg
6135               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
6136   "TARGET_SIBCALLS"
6138   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
6139   DONE;
6142 (define_insn "sibcall_internal"
6143   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
6144          (match_operand 1 "" ""))]
6145   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6146   "@
6147     %*jr\t%0%/
6148     %*j\t%0%/"
6149   [(set_attr "type" "call")])
6151 (define_expand "sibcall_value"
6152   [(parallel [(set (match_operand 0 "")
6153                    (call (match_operand 1 "")
6154                          (match_operand 2 "")))
6155               (use (match_operand 3 ""))])]             ;; next_arg_reg
6156   "TARGET_SIBCALLS"
6158   mips_expand_call (operands[0], XEXP (operands[1], 0),
6159                     operands[2], operands[3], true);
6160   DONE;
6163 (define_insn "sibcall_value_internal"
6164   [(set (match_operand 0 "register_operand" "=df,df")
6165         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6166               (match_operand 2 "" "")))]
6167   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6168   "@
6169     %*jr\t%1%/
6170     %*j\t%1%/"
6171   [(set_attr "type" "call")])
6173 (define_insn "sibcall_value_multiple_internal"
6174   [(set (match_operand 0 "register_operand" "=df,df")
6175         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6176               (match_operand 2 "" "")))
6177    (set (match_operand 3 "register_operand" "=df,df")
6178         (call (mem:SI (match_dup 1))
6179               (match_dup 2)))]
6180   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6181   "@
6182     %*jr\t%1%/
6183     %*j\t%1%/"
6184   [(set_attr "type" "call")])
6186 (define_expand "call"
6187   [(parallel [(call (match_operand 0 "")
6188                     (match_operand 1 ""))
6189               (use (match_operand 2 ""))        ;; next_arg_reg
6190               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
6191   ""
6193   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
6194   DONE;
6197 ;; This instruction directly corresponds to an assembly-language "jal".
6198 ;; There are four cases:
6200 ;;    - -mno-abicalls:
6201 ;;        Both symbolic and register destinations are OK.  The pattern
6202 ;;        always expands to a single mips instruction.
6204 ;;    - -mabicalls/-mno-explicit-relocs:
6205 ;;        Again, both symbolic and register destinations are OK.
6206 ;;        The call is treated as a multi-instruction black box.
6208 ;;    - -mabicalls/-mexplicit-relocs with n32 or n64:
6209 ;;        Only "jal $25" is allowed.  This expands to a single "jalr $25"
6210 ;;        instruction.
6212 ;;    - -mabicalls/-mexplicit-relocs with o32 or o64:
6213 ;;        Only "jal $25" is allowed.  The call is actually two instructions:
6214 ;;        "jalr $25" followed by an insn to reload $gp.
6216 ;; In the last case, we can generate the individual instructions with
6217 ;; a define_split.  There are several things to be wary of:
6219 ;;   - We can't expose the load of $gp before reload.  If we did,
6220 ;;     it might get removed as dead, but reload can introduce new
6221 ;;     uses of $gp by rematerializing constants.
6223 ;;   - We shouldn't restore $gp after calls that never return.
6224 ;;     It isn't valid to insert instructions between a noreturn
6225 ;;     call and the following barrier.
6227 ;;   - The splitter deliberately changes the liveness of $gp.  The unsplit
6228 ;;     instruction preserves $gp and so have no effect on its liveness.
6229 ;;     But once we generate the separate insns, it becomes obvious that
6230 ;;     $gp is not live on entry to the call.
6232 ;; ??? The operands[2] = insn check is a hack to make the original insn
6233 ;; available to the splitter.
6234 (define_insn_and_split "call_internal"
6235   [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
6236          (match_operand 1 "" ""))
6237    (clobber (reg:SI 31))]
6238   ""
6239   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
6240   "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
6241   [(const_int 0)]
6243   emit_call_insn (gen_call_split (operands[0], operands[1]));
6244   if (!find_reg_note (operands[2], REG_NORETURN, 0))
6245     mips_restore_gp ();
6246   DONE;
6248   [(set_attr "jal" "indirect,direct")
6249    (set_attr "extended_mips16" "no,yes")])
6251 (define_insn "call_split"
6252   [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
6253          (match_operand 1 "" ""))
6254    (clobber (reg:SI 31))
6255    (clobber (reg:SI 28))]
6256   "TARGET_SPLIT_CALLS"
6257   "%*jalr\t%0%/"
6258   [(set_attr "type" "call")])
6260 (define_expand "call_value"
6261   [(parallel [(set (match_operand 0 "")
6262                    (call (match_operand 1 "")
6263                          (match_operand 2 "")))
6264               (use (match_operand 3 ""))])]             ;; next_arg_reg
6265   ""
6267   mips_expand_call (operands[0], XEXP (operands[1], 0),
6268                     operands[2], operands[3], false);
6269   DONE;
6272 ;; See comment for call_internal.
6273 (define_insn_and_split "call_value_internal"
6274   [(set (match_operand 0 "register_operand" "=df,df")
6275         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6276               (match_operand 2 "" "")))
6277    (clobber (reg:SI 31))]
6278   ""
6279   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
6280   "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
6281   [(const_int 0)]
6283   emit_call_insn (gen_call_value_split (operands[0], operands[1],
6284                                         operands[2]));
6285   if (!find_reg_note (operands[3], REG_NORETURN, 0))
6286     mips_restore_gp ();
6287   DONE;
6289   [(set_attr "jal" "indirect,direct")
6290    (set_attr "extended_mips16" "no,yes")])
6292 (define_insn "call_value_split"
6293   [(set (match_operand 0 "register_operand" "=df")
6294         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
6295               (match_operand 2 "" "")))
6296    (clobber (reg:SI 31))
6297    (clobber (reg:SI 28))]
6298   "TARGET_SPLIT_CALLS"
6299   "%*jalr\t%1%/"
6300   [(set_attr "type" "call")])
6302 ;; See comment for call_internal.
6303 (define_insn_and_split "call_value_multiple_internal"
6304   [(set (match_operand 0 "register_operand" "=df,df")
6305         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6306               (match_operand 2 "" "")))
6307    (set (match_operand 3 "register_operand" "=df,df")
6308         (call (mem:SI (match_dup 1))
6309               (match_dup 2)))
6310    (clobber (reg:SI 31))]
6311   ""
6312   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
6313   "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
6314   [(const_int 0)]
6316   emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
6317                                                  operands[2], operands[3]));
6318   if (!find_reg_note (operands[4], REG_NORETURN, 0))
6319     mips_restore_gp ();
6320   DONE;
6322   [(set_attr "jal" "indirect,direct")
6323    (set_attr "extended_mips16" "no,yes")])
6325 (define_insn "call_value_multiple_split"
6326   [(set (match_operand 0 "register_operand" "=df")
6327         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
6328               (match_operand 2 "" "")))
6329    (set (match_operand 3 "register_operand" "=df")
6330         (call (mem:SI (match_dup 1))
6331               (match_dup 2)))
6332    (clobber (reg:SI 31))
6333    (clobber (reg:SI 28))]
6334   "TARGET_SPLIT_CALLS"
6335   "%*jalr\t%1%/"
6336   [(set_attr "type" "call")])
6338 ;; Call subroutine returning any type.
6340 (define_expand "untyped_call"
6341   [(parallel [(call (match_operand 0 "")
6342                     (const_int 0))
6343               (match_operand 1 "")
6344               (match_operand 2 "")])]
6345   ""
6347   int i;
6349   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6351   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6352     {
6353       rtx set = XVECEXP (operands[2], 0, i);
6354       emit_move_insn (SET_DEST (set), SET_SRC (set));
6355     }
6357   emit_insn (gen_blockage ());
6358   DONE;
6362 ;;  ....................
6364 ;;      MISC.
6366 ;;  ....................
6370 (define_expand "prefetch"
6371   [(prefetch (match_operand 0 "address_operand")
6372              (match_operand 1 "const_int_operand")
6373              (match_operand 2 "const_int_operand"))]
6374   "ISA_HAS_PREFETCH"
6376   if (symbolic_operand (operands[0], GET_MODE (operands[0])))
6377     operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
6380 (define_insn "prefetch_si_address"
6381   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
6382                       (match_operand:SI 3 "const_int_operand" "I"))
6383              (match_operand:SI 1 "const_int_operand" "n")
6384              (match_operand:SI 2 "const_int_operand" "n"))]
6385   "ISA_HAS_PREFETCH && Pmode == SImode"
6386   { return mips_emit_prefetch (operands); }
6387   [(set_attr "type" "prefetch")])
6389 (define_insn "prefetch_indexed_si"
6390   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
6391                       (match_operand:SI 3 "register_operand" "r"))
6392              (match_operand:SI 1 "const_int_operand" "n")
6393              (match_operand:SI 2 "const_int_operand" "n"))]
6394   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
6395   { return mips_emit_prefetch (operands); }
6396   [(set_attr "type" "prefetchx")])
6398 (define_insn "prefetch_si"
6399   [(prefetch (match_operand:SI 0 "register_operand" "r")
6400              (match_operand:SI 1 "const_int_operand" "n")
6401              (match_operand:SI 2 "const_int_operand" "n"))]
6402   "ISA_HAS_PREFETCH && Pmode == SImode"
6404   operands[3] = const0_rtx;
6405   return mips_emit_prefetch (operands);
6407   [(set_attr "type" "prefetch")])
6409 (define_insn "prefetch_di_address"
6410   [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
6411                       (match_operand:DI 3 "const_int_operand" "I"))
6412              (match_operand:DI 1 "const_int_operand" "n")
6413              (match_operand:DI 2 "const_int_operand" "n"))]
6414   "ISA_HAS_PREFETCH && Pmode == DImode"
6415   { return mips_emit_prefetch (operands); }
6416   [(set_attr "type" "prefetch")])
6418 (define_insn "prefetch_indexed_di"
6419   [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
6420                       (match_operand:DI 3 "register_operand" "r"))
6421              (match_operand:DI 1 "const_int_operand" "n")
6422              (match_operand:DI 2 "const_int_operand" "n"))]
6423   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
6424   { return mips_emit_prefetch (operands); }
6425   [(set_attr "type" "prefetchx")])
6427 (define_insn "prefetch_di"
6428   [(prefetch (match_operand:DI 0 "register_operand" "r")
6429              (match_operand:DI 1 "const_int_operand" "n")
6430              (match_operand:DI 2 "const_int_operand" "n"))]
6431   "ISA_HAS_PREFETCH && Pmode == DImode"
6433   operands[3] = const0_rtx;
6434   return mips_emit_prefetch (operands);
6436   [(set_attr "type" "prefetch")])
6438 (define_insn "nop"
6439   [(const_int 0)]
6440   ""
6441   "%(nop%)"
6442   [(set_attr "type"     "nop")
6443    (set_attr "mode"     "none")])
6445 ;; Like nop, but commented out when outside a .set noreorder block.
6446 (define_insn "hazard_nop"
6447   [(const_int 1)]
6448   ""
6449   {
6450     if (set_noreorder)
6451       return "nop";
6452     else
6453       return "#nop";
6454   }
6455   [(set_attr "type"     "nop")])
6457 ;; MIPS4 Conditional move instructions.
6459 (define_insn ""
6460   [(set (match_operand:SI 0 "register_operand" "=d,d")
6461         (if_then_else:SI
6462          (match_operator:SI 4 "equality_operator"
6463                             [(match_operand:SI 1 "register_operand" "d,d")
6464                              (const_int 0)])
6465          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
6466          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
6467   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
6468   "@
6469     mov%B4\t%0,%z2,%1
6470     mov%b4\t%0,%z3,%1"
6471   [(set_attr "type" "condmove")
6472    (set_attr "mode" "SI")])
6474 (define_insn ""
6475   [(set (match_operand:SI 0 "register_operand" "=d,d")
6476         (if_then_else:SI
6477          (match_operator:DI 4 "equality_operator"
6478                             [(match_operand:DI 1 "register_operand" "d,d")
6479                              (const_int 0)])
6480          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
6481          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
6482   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
6483   "@
6484     mov%B4\t%0,%z2,%1
6485     mov%b4\t%0,%z3,%1"
6486   [(set_attr "type" "condmove")
6487    (set_attr "mode" "SI")])
6489 (define_insn ""
6490   [(set (match_operand:SI 0 "register_operand" "=d,d")
6491         (if_then_else:SI
6492          (match_operator:CC 3 "equality_operator"
6493                             [(match_operand:CC 4 "register_operand" "z,z")
6494                              (const_int 0)])
6495          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
6496          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
6497   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6498   "@
6499     mov%T3\t%0,%z1,%4
6500     mov%t3\t%0,%z2,%4"
6501   [(set_attr "type" "condmove")
6502    (set_attr "mode" "SI")])
6504 (define_insn ""
6505   [(set (match_operand:DI 0 "register_operand" "=d,d")
6506         (if_then_else:DI
6507          (match_operator:SI 4 "equality_operator"
6508                             [(match_operand:SI 1 "register_operand" "d,d")
6509                              (const_int 0)])
6510          (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
6511          (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
6512   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
6513   "@
6514     mov%B4\t%0,%z2,%1
6515     mov%b4\t%0,%z3,%1"
6516   [(set_attr "type" "condmove")
6517    (set_attr "mode" "DI")])
6519 (define_insn ""
6520   [(set (match_operand:DI 0 "register_operand" "=d,d")
6521         (if_then_else:DI
6522          (match_operator:DI 4 "equality_operator"
6523                             [(match_operand:DI 1 "register_operand" "d,d")
6524                              (const_int 0)])
6525          (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
6526          (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
6527   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
6528   "@
6529     mov%B4\t%0,%z2,%1
6530     mov%b4\t%0,%z3,%1"
6531   [(set_attr "type" "condmove")
6532    (set_attr "mode" "DI")])
6534 (define_insn ""
6535   [(set (match_operand:DI 0 "register_operand" "=d,d")
6536         (if_then_else:DI
6537          (match_operator:CC 3 "equality_operator"
6538                             [(match_operand:CC 4 "register_operand" "z,z")
6539                              (const_int 0)])
6540          (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
6541          (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
6542   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
6543   "@
6544     mov%T3\t%0,%z1,%4
6545     mov%t3\t%0,%z2,%4"
6546   [(set_attr "type" "condmove")
6547    (set_attr "mode" "DI")])
6549 (define_insn ""
6550   [(set (match_operand:SF 0 "register_operand" "=f,f")
6551         (if_then_else:SF
6552          (match_operator:SI 4 "equality_operator"
6553                             [(match_operand:SI 1 "register_operand" "d,d")
6554                              (const_int 0)])
6555          (match_operand:SF 2 "register_operand" "f,0")
6556          (match_operand:SF 3 "register_operand" "0,f")))]
6557   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6558   "@
6559     mov%B4.s\t%0,%2,%1
6560     mov%b4.s\t%0,%3,%1"
6561   [(set_attr "type" "condmove")
6562    (set_attr "mode" "SF")])
6564 (define_insn ""
6565   [(set (match_operand:SF 0 "register_operand" "=f,f")
6566         (if_then_else:SF
6567          (match_operator:DI 4 "equality_operator"
6568                             [(match_operand:DI 1 "register_operand" "d,d")
6569                              (const_int 0)])
6570          (match_operand:SF 2 "register_operand" "f,0")
6571          (match_operand:SF 3 "register_operand" "0,f")))]
6572   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6573   "@
6574     mov%B4.s\t%0,%2,%1
6575     mov%b4.s\t%0,%3,%1"
6576   [(set_attr "type" "condmove")
6577    (set_attr "mode" "SF")])
6579 (define_insn ""
6580   [(set (match_operand:SF 0 "register_operand" "=f,f")
6581         (if_then_else:SF
6582          (match_operator:CC 3 "equality_operator"
6583                             [(match_operand:CC 4 "register_operand" "z,z")
6584                              (const_int 0)])
6585          (match_operand:SF 1 "register_operand" "f,0")
6586          (match_operand:SF 2 "register_operand" "0,f")))]
6587   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6588   "@
6589     mov%T3.s\t%0,%1,%4
6590     mov%t3.s\t%0,%2,%4"
6591   [(set_attr "type" "condmove")
6592    (set_attr "mode" "SF")])
6594 (define_insn ""
6595   [(set (match_operand:DF 0 "register_operand" "=f,f")
6596         (if_then_else:DF
6597          (match_operator:SI 4 "equality_operator"
6598                             [(match_operand:SI 1 "register_operand" "d,d")
6599                              (const_int 0)])
6600          (match_operand:DF 2 "register_operand" "f,0")
6601          (match_operand:DF 3 "register_operand" "0,f")))]
6602   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6603   "@
6604     mov%B4.d\t%0,%2,%1
6605     mov%b4.d\t%0,%3,%1"
6606   [(set_attr "type" "condmove")
6607    (set_attr "mode" "DF")])
6609 (define_insn ""
6610   [(set (match_operand:DF 0 "register_operand" "=f,f")
6611         (if_then_else:DF
6612          (match_operator:DI 4 "equality_operator"
6613                             [(match_operand:DI 1 "register_operand" "d,d")
6614                              (const_int 0)])
6615          (match_operand:DF 2 "register_operand" "f,0")
6616          (match_operand:DF 3 "register_operand" "0,f")))]
6617   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6618   "@
6619     mov%B4.d\t%0,%2,%1
6620     mov%b4.d\t%0,%3,%1"
6621   [(set_attr "type" "condmove")
6622    (set_attr "mode" "DF")])
6624 (define_insn ""
6625   [(set (match_operand:DF 0 "register_operand" "=f,f")
6626         (if_then_else:DF
6627          (match_operator:CC 3 "equality_operator"
6628                             [(match_operand:CC 4 "register_operand" "z,z")
6629                              (const_int 0)])
6630          (match_operand:DF 1 "register_operand" "f,0")
6631          (match_operand:DF 2 "register_operand" "0,f")))]
6632   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6633   "@
6634     mov%T3.d\t%0,%1,%4
6635     mov%t3.d\t%0,%2,%4"
6636   [(set_attr "type" "condmove")
6637    (set_attr "mode" "DF")])
6639 ;; These are the main define_expand's used to make conditional moves.
6641 (define_expand "movsicc"
6642   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6643    (set (match_operand:SI 0 "register_operand")
6644         (if_then_else:SI (match_dup 5)
6645                          (match_operand:SI 2 "reg_or_0_operand")
6646                          (match_operand:SI 3 "reg_or_0_operand")))]
6647   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
6649   gen_conditional_move (operands);
6650   DONE;
6653 (define_expand "movdicc"
6654   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6655    (set (match_operand:DI 0 "register_operand")
6656         (if_then_else:DI (match_dup 5)
6657                          (match_operand:DI 2 "reg_or_0_operand")
6658                          (match_operand:DI 3 "reg_or_0_operand")))]
6659   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
6661   gen_conditional_move (operands);
6662   DONE;
6665 (define_expand "movsfcc"
6666   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6667    (set (match_operand:SF 0 "register_operand")
6668         (if_then_else:SF (match_dup 5)
6669                          (match_operand:SF 2 "register_operand")
6670                          (match_operand:SF 3 "register_operand")))]
6671   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6673   gen_conditional_move (operands);
6674   DONE;
6677 (define_expand "movdfcc"
6678   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6679    (set (match_operand:DF 0 "register_operand")
6680         (if_then_else:DF (match_dup 5)
6681                          (match_operand:DF 2 "register_operand")
6682                          (match_operand:DF 3 "register_operand")))]
6683   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6685   gen_conditional_move (operands);
6686   DONE;
6690 ;;  ....................
6692 ;;      mips16 inline constant tables
6694 ;;  ....................
6697 (define_insn "consttable_int"
6698   [(unspec_volatile [(match_operand 0 "consttable_operand" "")
6699                      (match_operand 1 "const_int_operand" "")]
6700                     UNSPEC_CONSTTABLE_INT)]
6701   "TARGET_MIPS16"
6703   assemble_integer (operands[0], INTVAL (operands[1]),
6704                     BITS_PER_UNIT * INTVAL (operands[1]), 1);
6705   return "";
6707   [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
6709 (define_insn "consttable_float"
6710   [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
6711                     UNSPEC_CONSTTABLE_FLOAT)]
6712   "TARGET_MIPS16"
6714   REAL_VALUE_TYPE d;
6716   if (GET_CODE (operands[0]) != CONST_DOUBLE)
6717     abort ();
6718   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
6719   assemble_real (d, GET_MODE (operands[0]),
6720                  GET_MODE_BITSIZE (GET_MODE (operands[0])));
6721   return "";
6723   [(set (attr "length")
6724         (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
6726 (define_insn "align"
6727   [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
6728   ""
6729   ".align\t%0"
6730   [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
6732 (define_split
6733   [(match_operand 0 "small_data_pattern")]
6734   "reload_completed"
6735   [(match_dup 0)]
6736   { operands[0] = mips_rewrite_small_data (operands[0]); })