* config/mips/mips.c (mips_gen_conditional_trap): Fix mode.
[official-gcc.git] / gcc / config / mips / mips.md
blob46ec8cf1be1ced0f62ac335d51b2ad954735d8fd
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 (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
408       && operands[1] == const0_rtx)
409     {
410       mips_gen_conditional_trap (operands);
411       DONE;
412     }
413   else
414     FAIL;
417 (define_insn "*conditional_trap<mode>"
418   [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
419                                 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
420                                  (match_operand:GPR 2 "arith_operand" "dI")])
421             (const_int 0))]
422   "ISA_HAS_COND_TRAP"
423   "t%C0\t%z1,%2"
424   [(set_attr "type" "trap")])
427 ;;  ....................
429 ;;      ADDITION
431 ;;  ....................
434 (define_insn "adddf3"
435   [(set (match_operand:DF 0 "register_operand" "=f")
436         (plus:DF (match_operand:DF 1 "register_operand" "f")
437                  (match_operand:DF 2 "register_operand" "f")))]
438   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
439   "add.d\t%0,%1,%2"
440   [(set_attr "type"     "fadd")
441    (set_attr "mode"     "DF")])
443 (define_insn "addsf3"
444   [(set (match_operand:SF 0 "register_operand" "=f")
445         (plus:SF (match_operand:SF 1 "register_operand" "f")
446                  (match_operand:SF 2 "register_operand" "f")))]
447   "TARGET_HARD_FLOAT"
448   "add.s\t%0,%1,%2"
449   [(set_attr "type"     "fadd")
450    (set_attr "mode"     "SF")])
452 (define_expand "add<mode>3"
453   [(set (match_operand:GPR 0 "register_operand")
454         (plus:GPR (match_operand:GPR 1 "register_operand")
455                   (match_operand:GPR 2 "arith_operand")))]
456   "")
458 (define_insn "*add<mode>3"
459   [(set (match_operand:GPR 0 "register_operand" "=d,d")
460         (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
461                   (match_operand:GPR 2 "arith_operand" "d,Q")))]
462   "!TARGET_MIPS16"
463   "@
464     <d>addu\t%0,%1,%2
465     <d>addiu\t%0,%1,%2"
466   [(set_attr "type" "arith")
467    (set_attr "mode" "<MODE>")])
469 ;; We need to recognize MIPS16 stack pointer additions explicitly, since
470 ;; we don't have a constraint for $sp.  These insns will be generated by
471 ;; the save_restore_insns functions.
473 (define_insn "*add<mode>3_sp1"
474   [(set (reg:GPR 29)
475         (plus:GPR (reg:GPR 29)
476                   (match_operand:GPR 0 "const_arith_operand" "")))]
477   "TARGET_MIPS16"
478   "<d>addiu\t%$,%$,%0"
479   [(set_attr "type" "arith")
480    (set_attr "mode" "<MODE>")
481    (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
482                                       (const_int 4)
483                                       (const_int 8)))])
485 (define_insn "*add<mode>3_sp2"
486   [(set (match_operand:GPR 0 "register_operand" "=d")
487         (plus:GPR (reg:GPR 29)
488                   (match_operand:GPR 1 "const_arith_operand" "")))]
489   "TARGET_MIPS16"
490   "<d>addiu\t%0,%$,%1"
491   [(set_attr "type" "arith")
492    (set_attr "mode" "<MODE>")
493    (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
494                                       (const_int 4)
495                                       (const_int 8)))])
497 (define_insn "*add<mode>3_mips16"
498   [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
499         (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
500                   (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
501   "TARGET_MIPS16"
502   "@
503     <d>addiu\t%0,%2
504     <d>addiu\t%0,%1,%2
505     <d>addu\t%0,%1,%2"
506   [(set_attr "type" "arith")
507    (set_attr "mode" "<MODE>")
508    (set_attr_alternative "length"
509                 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
510                                (const_int 4)
511                                (const_int 8))
512                  (if_then_else (match_operand 2 "m16_simm4_1")
513                                (const_int 4)
514                                (const_int 8))
515                  (const_int 4)])])
518 ;; On the mips16, we can sometimes split an add of a constant which is
519 ;; a 4 byte instruction into two adds which are both 2 byte
520 ;; instructions.  There are two cases: one where we are adding a
521 ;; constant plus a register to another register, and one where we are
522 ;; simply adding a constant to a register.
524 (define_split
525   [(set (match_operand:SI 0 "register_operand")
526         (plus:SI (match_dup 0)
527                  (match_operand:SI 1 "const_int_operand")))]
528   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
529    && GET_CODE (operands[0]) == REG
530    && M16_REG_P (REGNO (operands[0]))
531    && GET_CODE (operands[1]) == CONST_INT
532    && ((INTVAL (operands[1]) > 0x7f
533         && INTVAL (operands[1]) <= 0x7f + 0x7f)
534        || (INTVAL (operands[1]) < - 0x80
535            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
536   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
537    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
539   HOST_WIDE_INT val = INTVAL (operands[1]);
541   if (val >= 0)
542     {
543       operands[1] = GEN_INT (0x7f);
544       operands[2] = GEN_INT (val - 0x7f);
545     }
546   else
547     {
548       operands[1] = GEN_INT (- 0x80);
549       operands[2] = GEN_INT (val + 0x80);
550     }
553 (define_split
554   [(set (match_operand:SI 0 "register_operand")
555         (plus:SI (match_operand:SI 1 "register_operand")
556                  (match_operand:SI 2 "const_int_operand")))]
557   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
558    && GET_CODE (operands[0]) == REG
559    && M16_REG_P (REGNO (operands[0]))
560    && GET_CODE (operands[1]) == REG
561    && M16_REG_P (REGNO (operands[1]))
562    && REGNO (operands[0]) != REGNO (operands[1])
563    && GET_CODE (operands[2]) == CONST_INT
564    && ((INTVAL (operands[2]) > 0x7
565         && INTVAL (operands[2]) <= 0x7 + 0x7f)
566        || (INTVAL (operands[2]) < - 0x8
567            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
568   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
569    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
571   HOST_WIDE_INT val = INTVAL (operands[2]);
573   if (val >= 0)
574     {
575       operands[2] = GEN_INT (0x7);
576       operands[3] = GEN_INT (val - 0x7);
577     }
578   else
579     {
580       operands[2] = GEN_INT (- 0x8);
581       operands[3] = GEN_INT (val + 0x8);
582     }
585 (define_split
586   [(set (match_operand:DI 0 "register_operand")
587         (plus:DI (match_dup 0)
588                  (match_operand:DI 1 "const_int_operand")))]
589   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
590    && GET_CODE (operands[0]) == REG
591    && M16_REG_P (REGNO (operands[0]))
592    && GET_CODE (operands[1]) == CONST_INT
593    && ((INTVAL (operands[1]) > 0xf
594         && INTVAL (operands[1]) <= 0xf + 0xf)
595        || (INTVAL (operands[1]) < - 0x10
596            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
597   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
598    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
600   HOST_WIDE_INT val = INTVAL (operands[1]);
602   if (val >= 0)
603     {
604       operands[1] = GEN_INT (0xf);
605       operands[2] = GEN_INT (val - 0xf);
606     }
607   else
608     {
609       operands[1] = GEN_INT (- 0x10);
610       operands[2] = GEN_INT (val + 0x10);
611     }
614 (define_split
615   [(set (match_operand:DI 0 "register_operand")
616         (plus:DI (match_operand:DI 1 "register_operand")
617                  (match_operand:DI 2 "const_int_operand")))]
618   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
619    && GET_CODE (operands[0]) == REG
620    && M16_REG_P (REGNO (operands[0]))
621    && GET_CODE (operands[1]) == REG
622    && M16_REG_P (REGNO (operands[1]))
623    && REGNO (operands[0]) != REGNO (operands[1])
624    && GET_CODE (operands[2]) == CONST_INT
625    && ((INTVAL (operands[2]) > 0x7
626         && INTVAL (operands[2]) <= 0x7 + 0xf)
627        || (INTVAL (operands[2]) < - 0x8
628            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
629   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
630    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
632   HOST_WIDE_INT val = INTVAL (operands[2]);
634   if (val >= 0)
635     {
636       operands[2] = GEN_INT (0x7);
637       operands[3] = GEN_INT (val - 0x7);
638     }
639   else
640     {
641       operands[2] = GEN_INT (- 0x8);
642       operands[3] = GEN_INT (val + 0x8);
643     }
646 (define_insn "*addsi3_extended"
647   [(set (match_operand:DI 0 "register_operand" "=d,d")
648         (sign_extend:DI
649              (plus:SI (match_operand:SI 1 "register_operand" "d,d")
650                       (match_operand:SI 2 "arith_operand" "d,Q"))))]
651   "TARGET_64BIT && !TARGET_MIPS16"
652   "@
653     addu\t%0,%1,%2
654     addiu\t%0,%1,%2"
655   [(set_attr "type" "arith")
656    (set_attr "mode" "SI")])
658 ;; Split this insn so that the addiu splitters can have a crack at it.
659 ;; Use a conservative length estimate until the split.
660 (define_insn_and_split "*addsi3_extended_mips16"
661   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
662         (sign_extend:DI
663              (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
664                       (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
665   "TARGET_64BIT && TARGET_MIPS16"
666   "#"
667   "&& reload_completed"
668   [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
669   { operands[3] = gen_lowpart (SImode, operands[0]); }
670   [(set_attr "type" "arith")
671    (set_attr "mode" "SI")
672    (set_attr "extended_mips16" "yes")])
675 ;;  ....................
677 ;;      SUBTRACTION
679 ;;  ....................
682 (define_insn "subdf3"
683   [(set (match_operand:DF 0 "register_operand" "=f")
684         (minus:DF (match_operand:DF 1 "register_operand" "f")
685                   (match_operand:DF 2 "register_operand" "f")))]
686   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
687   "sub.d\t%0,%1,%2"
688   [(set_attr "type"     "fadd")
689    (set_attr "mode"     "DF")])
691 (define_insn "subsf3"
692   [(set (match_operand:SF 0 "register_operand" "=f")
693         (minus:SF (match_operand:SF 1 "register_operand" "f")
694                   (match_operand:SF 2 "register_operand" "f")))]
695   "TARGET_HARD_FLOAT"
696   "sub.s\t%0,%1,%2"
697   [(set_attr "type"     "fadd")
698    (set_attr "mode"     "SF")])
700 (define_insn "sub<mode>3"
701   [(set (match_operand:GPR 0 "register_operand" "=d")
702         (minus:GPR (match_operand:GPR 1 "register_operand" "d")
703                    (match_operand:GPR 2 "register_operand" "d")))]
704   ""
705   "<d>subu\t%0,%1,%2"
706   [(set_attr "type" "arith")
707    (set_attr "mode" "<MODE>")])
709 (define_insn "*subsi3_extended"
710   [(set (match_operand:DI 0 "register_operand" "=d")
711         (sign_extend:DI
712             (minus:SI (match_operand:SI 1 "register_operand" "d")
713                       (match_operand:SI 2 "register_operand" "d"))))]
714   "TARGET_64BIT"
715   "subu\t%0,%1,%2"
716   [(set_attr "type" "arith")
717    (set_attr "mode" "DI")])
720 ;;  ....................
722 ;;      MULTIPLICATION
724 ;;  ....................
727 (define_expand "muldf3"
728   [(set (match_operand:DF 0 "register_operand")
729         (mult:DF (match_operand:DF 1 "register_operand")
730                  (match_operand:DF 2 "register_operand")))]
731   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
732   "")
734 (define_insn "muldf3_internal"
735   [(set (match_operand:DF 0 "register_operand" "=f")
736         (mult:DF (match_operand:DF 1 "register_operand" "f")
737                  (match_operand:DF 2 "register_operand" "f")))]
738   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
739   "mul.d\t%0,%1,%2"
740   [(set_attr "type"     "fmul")
741    (set_attr "mode"     "DF")])
743 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
744 ;; operands may corrupt immediately following multiplies. This is a
745 ;; simple fix to insert NOPs.
747 (define_insn "muldf3_r4300"
748   [(set (match_operand:DF 0 "register_operand" "=f")
749         (mult:DF (match_operand:DF 1 "register_operand" "f")
750                  (match_operand:DF 2 "register_operand" "f")))]
751   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
752   "mul.d\t%0,%1,%2\;nop"
753   [(set_attr "type"     "fmul")
754    (set_attr "mode"     "DF")
755    (set_attr "length"   "8")])
757 (define_expand "mulsf3"
758   [(set (match_operand:SF 0 "register_operand")
759         (mult:SF (match_operand:SF 1 "register_operand")
760                  (match_operand:SF 2 "register_operand")))]
761   "TARGET_HARD_FLOAT"
762   "")
764 (define_insn "mulsf3_internal"
765   [(set (match_operand:SF 0 "register_operand" "=f")
766         (mult:SF (match_operand:SF 1 "register_operand" "f")
767                  (match_operand:SF 2 "register_operand" "f")))]
768   "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
769   "mul.s\t%0,%1,%2"
770   [(set_attr "type"     "fmul")
771    (set_attr "mode"     "SF")])
773 ;; See muldf3_r4300.
775 (define_insn "mulsf3_r4300"
776   [(set (match_operand:SF 0 "register_operand" "=f")
777         (mult:SF (match_operand:SF 1 "register_operand" "f")
778                  (match_operand:SF 2 "register_operand" "f")))]
779   "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
780   "mul.s\t%0,%1,%2\;nop"
781   [(set_attr "type"     "fmul")
782    (set_attr "mode"     "SF")
783    (set_attr "length"   "8")])
786 ;; The original R4000 has a cpu bug.  If a double-word or a variable
787 ;; shift executes while an integer multiplication is in progress, the
788 ;; shift may give an incorrect result.  Avoid this by keeping the mflo
789 ;; with the mult on the R4000.
791 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
792 ;; (also valid for MIPS R4000MC processors):
794 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
795 ;;      this errata description.
796 ;;      The following code sequence causes the R4000 to incorrectly
797 ;;      execute the Double Shift Right Arithmetic 32 (dsra32)
798 ;;      instruction.  If the dsra32 instruction is executed during an
799 ;;      integer multiply, the dsra32 will only shift by the amount in
800 ;;      specified in the instruction rather than the amount plus 32
801 ;;      bits.
802 ;;      instruction 1:          mult    rs,rt           integer multiply
803 ;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
804 ;;                                                      right arithmetic + 32
805 ;;      Workaround: A dsra32 instruction placed after an integer
806 ;;      multiply should not be one of the 11 instructions after the
807 ;;      multiply instruction."
809 ;; and:
811 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
812 ;;      the following description.
813 ;;      All extended shifts (shift by n+32) and variable shifts (32 and
814 ;;      64-bit versions) may produce incorrect results under the
815 ;;      following conditions:
816 ;;      1) An integer multiply is currently executing
817 ;;      2) These types of shift instructions are executed immediately
818 ;;         following an integer divide instruction.
819 ;;      Workaround:
820 ;;      1) Make sure no integer multiply is running wihen these
821 ;;         instruction are executed.  If this cannot be predicted at
822 ;;         compile time, then insert a "mfhi" to R0 instruction
823 ;;         immediately after the integer multiply instruction.  This
824 ;;         will cause the integer multiply to complete before the shift
825 ;;         is executed.
826 ;;      2) Separate integer divide and these two classes of shift
827 ;;         instructions by another instruction or a noop."
829 ;; These processors have PRId values of 0x00004220 and 0x00004300,
830 ;; respectively.
832 (define_expand "mul<mode>3"
833   [(set (match_operand:GPR 0 "register_operand")
834         (mult:GPR (match_operand:GPR 1 "register_operand")
835                   (match_operand:GPR 2 "register_operand")))]
836   ""
838   if (GENERATE_MULT3_<MODE>)
839     emit_insn (gen_mul<mode>3_mult3 (operands[0], operands[1], operands[2]));
840   else if (!TARGET_FIX_R4000)
841     emit_insn (gen_mul<mode>3_internal (operands[0], operands[1],
842                                         operands[2]));
843   else
844     emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
845   DONE;
848 (define_insn "mulsi3_mult3"
849   [(set (match_operand:SI 0 "register_operand" "=d,l")
850         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
851                  (match_operand:SI 2 "register_operand" "d,d")))
852    (clobber (match_scratch:SI 3 "=h,h"))
853    (clobber (match_scratch:SI 4 "=l,X"))]
854   "GENERATE_MULT3_SI"
856   if (which_alternative == 1)
857     return "mult\t%1,%2";
858   if (TARGET_MAD
859       || TARGET_MIPS5400
860       || TARGET_MIPS5500
861       || TARGET_MIPS7000
862       || TARGET_MIPS9000
863       || ISA_MIPS32
864       || ISA_MIPS32R2
865       || ISA_MIPS64)
866     return "mul\t%0,%1,%2";
867   return "mult\t%0,%1,%2";
869   [(set_attr "type" "imul")
870    (set_attr "mode" "SI")])
872 (define_insn "muldi3_mult3"
873   [(set (match_operand:DI 0 "register_operand" "=d")
874         (mult:DI (match_operand:DI 1 "register_operand" "d")
875                  (match_operand:DI 2 "register_operand" "d")))
876    (clobber (match_scratch:DI 3 "=h"))
877    (clobber (match_scratch:DI 4 "=l"))]
878   "TARGET_64BIT && GENERATE_MULT3_DI"
879   "dmult\t%0,%1,%2"
880   [(set_attr "type" "imul")
881    (set_attr "mode" "DI")])
883 ;; If a register gets allocated to LO, and we spill to memory, the reload
884 ;; will include a move from LO to a GPR.  Merge it into the multiplication
885 ;; if it can set the GPR directly.
887 ;; Operand 0: LO
888 ;; Operand 1: GPR (1st multiplication operand)
889 ;; Operand 2: GPR (2nd multiplication operand)
890 ;; Operand 3: HI
891 ;; Operand 4: GPR (destination)
892 (define_peephole2
893   [(parallel
894        [(set (match_operand:SI 0 "register_operand")
895              (mult:SI (match_operand:SI 1 "register_operand")
896                       (match_operand:SI 2 "register_operand")))
897         (clobber (match_operand:SI 3 "register_operand"))
898         (clobber (scratch:SI))])
899    (set (match_operand:SI 4 "register_operand")
900         (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
901   "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
902   [(parallel
903        [(set (match_dup 4)
904              (mult:SI (match_dup 1)
905                       (match_dup 2)))
906         (clobber (match_dup 3))
907         (clobber (match_dup 0))])])
909 (define_insn "mul<mode>3_internal"
910   [(set (match_operand:GPR 0 "register_operand" "=l")
911         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
912                   (match_operand:GPR 2 "register_operand" "d")))
913    (clobber (match_scratch:GPR 3 "=h"))]
914   "!TARGET_FIX_R4000"
915   "<d>mult\t%1,%2"
916   [(set_attr "type" "imul")
917    (set_attr "mode" "<MODE>")])
919 (define_insn "mul<mode>3_r4000"
920   [(set (match_operand:GPR 0 "register_operand" "=d")
921         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
922                   (match_operand:GPR 2 "register_operand" "d")))
923    (clobber (match_scratch:GPR 3 "=h"))
924    (clobber (match_scratch:GPR 4 "=l"))]
925   "TARGET_FIX_R4000"
926   "<d>mult\t%1,%2\;mflo\t%0"
927   [(set_attr "type" "imul")
928    (set_attr "mode" "<MODE>")
929    (set_attr "length" "8")])
931 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
932 ;; of "mult; mflo".  They have the same latency, but the first form gives
933 ;; us an extra cycle to compute the operands.
935 ;; Operand 0: LO
936 ;; Operand 1: GPR (1st multiplication operand)
937 ;; Operand 2: GPR (2nd multiplication operand)
938 ;; Operand 3: HI
939 ;; Operand 4: GPR (destination)
940 (define_peephole2
941   [(parallel
942        [(set (match_operand:SI 0 "register_operand")
943              (mult:SI (match_operand:SI 1 "register_operand")
944                       (match_operand:SI 2 "register_operand")))
945         (clobber (match_operand:SI 3 "register_operand"))])
946    (set (match_operand:SI 4 "register_operand")
947         (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
948   "ISA_HAS_MACC && !GENERATE_MULT3_SI"
949   [(set (match_dup 0)
950         (const_int 0))
951    (parallel
952        [(set (match_dup 0)
953              (plus:SI (mult:SI (match_dup 1)
954                                (match_dup 2))
955                       (match_dup 0)))
956         (set (match_dup 4)
957              (plus:SI (mult:SI (match_dup 1)
958                                (match_dup 2))
959                       (match_dup 0)))
960         (clobber (match_dup 3))])])
962 ;; Multiply-accumulate patterns
964 ;; For processors that can copy the output to a general register:
966 ;; The all-d alternative is needed because the combiner will find this
967 ;; pattern and then register alloc/reload will move registers around to
968 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
970 ;; The last alternative should be made slightly less desirable, but adding
971 ;; "?" to the constraint is too strong, and causes values to be loaded into
972 ;; LO even when that's more costly.  For now, using "*d" mostly does the
973 ;; trick.
974 (define_insn "*mul_acc_si"
975   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
976         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
977                           (match_operand:SI 2 "register_operand" "d,d,d"))
978                  (match_operand:SI 3 "register_operand" "0,l,*d")))
979    (clobber (match_scratch:SI 4 "=h,h,h"))
980    (clobber (match_scratch:SI 5 "=X,3,l"))
981    (clobber (match_scratch:SI 6 "=X,X,&d"))]
982   "(TARGET_MIPS3900
983    || ISA_HAS_MADD_MSUB)
984    && !TARGET_MIPS16"
986   static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
987   if (which_alternative == 2)
988     return "#";
989   if (ISA_HAS_MADD_MSUB && which_alternative != 0)
990     return "#";
991   return madd[which_alternative];
993   [(set_attr "type"     "imadd,imadd,multi")
994    (set_attr "mode"     "SI")
995    (set_attr "length"   "4,4,8")])
997 ;; Split the above insn if we failed to get LO allocated.
998 (define_split
999   [(set (match_operand:SI 0 "register_operand")
1000         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1001                           (match_operand:SI 2 "register_operand"))
1002                  (match_operand:SI 3 "register_operand")))
1003    (clobber (match_scratch:SI 4))
1004    (clobber (match_scratch:SI 5))
1005    (clobber (match_scratch:SI 6))]
1006   "reload_completed && !TARGET_DEBUG_D_MODE
1007    && GP_REG_P (true_regnum (operands[0]))
1008    && GP_REG_P (true_regnum (operands[3]))"
1009   [(parallel [(set (match_dup 6)
1010                    (mult:SI (match_dup 1) (match_dup 2)))
1011               (clobber (match_dup 4))
1012               (clobber (match_dup 5))])
1013    (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1014   "")
1016 ;; Splitter to copy result of MADD to a general register
1017 (define_split
1018   [(set (match_operand:SI                   0 "register_operand")
1019         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1020                           (match_operand:SI 2 "register_operand"))
1021                  (match_operand:SI          3 "register_operand")))
1022    (clobber (match_scratch:SI               4))
1023    (clobber (match_scratch:SI               5))
1024    (clobber (match_scratch:SI               6))]
1025   "reload_completed && !TARGET_DEBUG_D_MODE
1026    && GP_REG_P (true_regnum (operands[0]))
1027    && true_regnum (operands[3]) == LO_REGNUM"
1028   [(parallel [(set (match_dup 3)
1029                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1030                             (match_dup 3)))
1031               (clobber (match_dup 4))
1032               (clobber (match_dup 5))
1033               (clobber (match_dup 6))])
1034    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1035   "")
1037 (define_insn "*macc"
1038   [(set (match_operand:SI 0 "register_operand" "=l,d")
1039         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1040                           (match_operand:SI 2 "register_operand" "d,d"))
1041                  (match_operand:SI 3 "register_operand" "0,l")))
1042    (clobber (match_scratch:SI 4 "=h,h"))
1043    (clobber (match_scratch:SI 5 "=X,3"))]
1044   "ISA_HAS_MACC"
1046   if (which_alternative == 1)
1047     return "macc\t%0,%1,%2";
1048   else if (TARGET_MIPS5500)
1049     return "madd\t%1,%2";
1050   else
1051     /* The VR4130 assumes that there is a two-cycle latency between a macc
1052        that "writes" to $0 and an instruction that reads from it.  We avoid
1053        this by assigning to $1 instead.  */
1054     return "%[macc\t%@,%1,%2%]";
1056   [(set_attr "type" "imadd")
1057    (set_attr "mode" "SI")])
1059 (define_insn "*msac"
1060   [(set (match_operand:SI 0 "register_operand" "=l,d")
1061         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1062                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1063                            (match_operand:SI 3 "register_operand" "d,d"))))
1064    (clobber (match_scratch:SI 4 "=h,h"))
1065    (clobber (match_scratch:SI 5 "=X,1"))]
1066   "ISA_HAS_MSAC"
1068   if (which_alternative == 1)
1069     return "msac\t%0,%2,%3";
1070   else if (TARGET_MIPS5500)
1071     return "msub\t%2,%3";
1072   else
1073     return "msac\t$0,%2,%3";
1075   [(set_attr "type"     "imadd")
1076    (set_attr "mode"     "SI")])
1078 ;; An msac-like instruction implemented using negation and a macc.
1079 (define_insn_and_split "*msac_using_macc"
1080   [(set (match_operand:SI 0 "register_operand" "=l,d")
1081         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1082                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1083                            (match_operand:SI 3 "register_operand" "d,d"))))
1084    (clobber (match_scratch:SI 4 "=h,h"))
1085    (clobber (match_scratch:SI 5 "=X,1"))
1086    (clobber (match_scratch:SI 6 "=d,d"))]
1087   "ISA_HAS_MACC && !ISA_HAS_MSAC"
1088   "#"
1089   "&& reload_completed"
1090   [(set (match_dup 6)
1091         (neg:SI (match_dup 3)))
1092    (parallel
1093        [(set (match_dup 0)
1094              (plus:SI (mult:SI (match_dup 2)
1095                                (match_dup 6))
1096                       (match_dup 1)))
1097         (clobber (match_dup 4))
1098         (clobber (match_dup 5))])]
1099   ""
1100   [(set_attr "type"     "imadd")
1101    (set_attr "length"   "8")])
1103 ;; Patterns generated by the define_peephole2 below.
1105 (define_insn "*macc2"
1106   [(set (match_operand:SI 0 "register_operand" "=l")
1107         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1108                           (match_operand:SI 2 "register_operand" "d"))
1109                  (match_dup 0)))
1110    (set (match_operand:SI 3 "register_operand" "=d")
1111         (plus:SI (mult:SI (match_dup 1)
1112                           (match_dup 2))
1113                  (match_dup 0)))
1114    (clobber (match_scratch:SI 4 "=h"))]
1115   "ISA_HAS_MACC && reload_completed"
1116   "macc\t%3,%1,%2"
1117   [(set_attr "type"     "imadd")
1118    (set_attr "mode"     "SI")])
1120 (define_insn "*msac2"
1121   [(set (match_operand:SI 0 "register_operand" "=l")
1122         (minus:SI (match_dup 0)
1123                   (mult:SI (match_operand:SI 1 "register_operand" "d")
1124                            (match_operand:SI 2 "register_operand" "d"))))
1125    (set (match_operand:SI 3 "register_operand" "=d")
1126         (minus:SI (match_dup 0)
1127                   (mult:SI (match_dup 1)
1128                            (match_dup 2))))
1129    (clobber (match_scratch:SI 4 "=h"))]
1130   "ISA_HAS_MSAC && reload_completed"
1131   "msac\t%3,%1,%2"
1132   [(set_attr "type"     "imadd")
1133    (set_attr "mode"     "SI")])
1135 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1136 ;; Similarly msac.
1138 ;; Operand 0: LO
1139 ;; Operand 1: macc/msac
1140 ;; Operand 2: HI
1141 ;; Operand 3: GPR (destination)
1142 (define_peephole2
1143   [(parallel
1144        [(set (match_operand:SI 0 "register_operand")
1145              (match_operand:SI 1 "macc_msac_operand"))
1146         (clobber (match_operand:SI 2 "register_operand"))
1147         (clobber (scratch:SI))])
1148    (set (match_operand:SI 3 "register_operand")
1149         (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1150   ""
1151   [(parallel [(set (match_dup 0)
1152                    (match_dup 1))
1153               (set (match_dup 3)
1154                    (match_dup 1))
1155               (clobber (match_dup 2))])]
1156   "")
1158 ;; When we have a three-address multiplication instruction, it should
1159 ;; be faster to do a separate multiply and add, rather than moving
1160 ;; something into LO in order to use a macc instruction.
1162 ;; This peephole needs a scratch register to cater for the case when one
1163 ;; of the multiplication operands is the same as the destination.
1165 ;; Operand 0: GPR (scratch)
1166 ;; Operand 1: LO
1167 ;; Operand 2: GPR (addend)
1168 ;; Operand 3: GPR (destination)
1169 ;; Operand 4: macc/msac
1170 ;; Operand 5: HI
1171 ;; Operand 6: new multiplication
1172 ;; Operand 7: new addition/subtraction
1173 (define_peephole2
1174   [(match_scratch:SI 0 "d")
1175    (set (match_operand:SI 1 "register_operand")
1176         (match_operand:SI 2 "register_operand"))
1177    (match_dup 0)
1178    (parallel
1179        [(set (match_operand:SI 3 "register_operand")
1180              (match_operand:SI 4 "macc_msac_operand"))
1181         (clobber (match_operand:SI 5 "register_operand"))
1182         (clobber (match_dup 1))])]
1183   "GENERATE_MULT3_SI
1184    && true_regnum (operands[1]) == LO_REGNUM
1185    && peep2_reg_dead_p (2, operands[1])
1186    && GP_REG_P (true_regnum (operands[3]))"
1187   [(parallel [(set (match_dup 0)
1188                    (match_dup 6))
1189               (clobber (match_dup 5))
1190               (clobber (match_dup 1))])
1191    (set (match_dup 3)
1192         (match_dup 7))]
1194   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1195   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1196                                 operands[2], operands[0]);
1199 ;; Same as above, except LO is the initial target of the macc.
1201 ;; Operand 0: GPR (scratch)
1202 ;; Operand 1: LO
1203 ;; Operand 2: GPR (addend)
1204 ;; Operand 3: macc/msac
1205 ;; Operand 4: HI
1206 ;; Operand 5: GPR (destination)
1207 ;; Operand 6: new multiplication
1208 ;; Operand 7: new addition/subtraction
1209 (define_peephole2
1210   [(match_scratch:SI 0 "d")
1211    (set (match_operand:SI 1 "register_operand")
1212         (match_operand:SI 2 "register_operand"))
1213    (match_dup 0)
1214    (parallel
1215        [(set (match_dup 1)
1216              (match_operand:SI 3 "macc_msac_operand"))
1217         (clobber (match_operand:SI 4 "register_operand"))
1218         (clobber (scratch:SI))])
1219    (match_dup 0)
1220    (set (match_operand:SI 5 "register_operand")
1221         (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1222   "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1223   [(parallel [(set (match_dup 0)
1224                    (match_dup 6))
1225               (clobber (match_dup 4))
1226               (clobber (match_dup 1))])
1227    (set (match_dup 5)
1228         (match_dup 7))]
1230   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1231   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1232                                 operands[2], operands[0]);
1235 (define_insn "*mul_sub_si"
1236   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1237         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1238                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1239                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1240    (clobber (match_scratch:SI 4 "=h,h,h"))
1241    (clobber (match_scratch:SI 5 "=X,1,l"))
1242    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1243   "ISA_HAS_MADD_MSUB"
1244   "@
1245    msub\t%2,%3
1246    #
1247    #"
1248   [(set_attr "type"     "imadd,multi,multi")
1249    (set_attr "mode"     "SI")
1250    (set_attr "length"   "4,8,8")])
1252 ;; Split the above insn if we failed to get LO allocated.
1253 (define_split
1254   [(set (match_operand:SI 0 "register_operand")
1255         (minus:SI (match_operand:SI 1 "register_operand")
1256                   (mult:SI (match_operand:SI 2 "register_operand")
1257                            (match_operand:SI 3 "register_operand"))))
1258    (clobber (match_scratch:SI 4))
1259    (clobber (match_scratch:SI 5))
1260    (clobber (match_scratch:SI 6))]
1261   "reload_completed && !TARGET_DEBUG_D_MODE
1262    && GP_REG_P (true_regnum (operands[0]))
1263    && GP_REG_P (true_regnum (operands[1]))"
1264   [(parallel [(set (match_dup 6)
1265                    (mult:SI (match_dup 2) (match_dup 3)))
1266               (clobber (match_dup 4))
1267               (clobber (match_dup 5))])
1268    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1269   "")
1271 ;; Splitter to copy result of MSUB to a general register
1272 (define_split
1273   [(set (match_operand:SI 0 "register_operand")
1274         (minus:SI (match_operand:SI 1 "register_operand")
1275                   (mult:SI (match_operand:SI 2 "register_operand")
1276                            (match_operand:SI 3 "register_operand"))))
1277    (clobber (match_scratch:SI 4))
1278    (clobber (match_scratch:SI 5))
1279    (clobber (match_scratch:SI 6))]
1280   "reload_completed && !TARGET_DEBUG_D_MODE
1281    && GP_REG_P (true_regnum (operands[0]))
1282    && true_regnum (operands[1]) == LO_REGNUM"
1283   [(parallel [(set (match_dup 1)
1284                    (minus:SI (match_dup 1)
1285                              (mult:SI (match_dup 2) (match_dup 3))))
1286               (clobber (match_dup 4))
1287               (clobber (match_dup 5))
1288               (clobber (match_dup 6))])
1289    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1290   "")
1292 (define_insn "*muls"
1293   [(set (match_operand:SI                  0 "register_operand" "=l,d")
1294         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1295                          (match_operand:SI 2 "register_operand" "d,d"))))
1296    (clobber (match_scratch:SI              3                    "=h,h"))
1297    (clobber (match_scratch:SI              4                    "=X,l"))]
1298   "ISA_HAS_MULS"
1299   "@
1300    muls\t$0,%1,%2
1301    muls\t%0,%1,%2"
1302   [(set_attr "type"     "imul")
1303    (set_attr "mode"     "SI")])
1305 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1307 (define_expand "<u>mulsidi3"
1308   [(parallel
1309       [(set (match_operand:DI 0 "register_operand")
1310             (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1311                      (any_extend:DI (match_operand:SI 2 "register_operand"))))
1312        (clobber (scratch:DI))
1313        (clobber (scratch:DI))
1314        (clobber (scratch:DI))])]
1315   "!TARGET_64BIT || !TARGET_FIX_R4000"
1317   if (!TARGET_64BIT)
1318     {
1319       if (!TARGET_FIX_R4000)
1320         emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1321                                                    operands[2]));
1322       else
1323         emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1324                                                 operands[2]));
1325       DONE;
1326     }
1329 (define_insn "<u>mulsidi3_32bit_internal"
1330   [(set (match_operand:DI 0 "register_operand" "=x")
1331         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1332                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1333   "!TARGET_64BIT && !TARGET_FIX_R4000"
1334   "mult<u>\t%1,%2"
1335   [(set_attr "type" "imul")
1336    (set_attr "mode" "SI")])
1338 (define_insn "<u>mulsidi3_32bit_r4000"
1339   [(set (match_operand:DI 0 "register_operand" "=d")
1340         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1341                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1342    (clobber (match_scratch:DI 3 "=x"))]
1343   "!TARGET_64BIT && TARGET_FIX_R4000"
1344   "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1345   [(set_attr "type" "imul")
1346    (set_attr "mode" "SI")
1347    (set_attr "length" "12")])
1349 (define_insn_and_split "*<u>mulsidi3_64bit"
1350   [(set (match_operand:DI 0 "register_operand" "=d")
1351         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1352                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1353    (clobber (match_scratch:DI 3 "=l"))
1354    (clobber (match_scratch:DI 4 "=h"))
1355    (clobber (match_scratch:DI 5 "=d"))]
1356   "TARGET_64BIT && !TARGET_FIX_R4000"
1357   "#"
1358   "&& reload_completed"
1359   [(parallel
1360        [(set (match_dup 3)
1361              (sign_extend:DI
1362                 (mult:SI (match_dup 1)
1363                          (match_dup 2))))
1364         (set (match_dup 4)
1365              (ashiftrt:DI
1366                 (mult:DI (any_extend:DI (match_dup 1))
1367                          (any_extend:DI (match_dup 2)))
1368                 (const_int 32)))])
1370    ;; OP5 <- LO, OP0 <- HI
1371    (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1372    (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1374    ;; Zero-extend OP5.
1375    (set (match_dup 5)
1376         (ashift:DI (match_dup 5)
1377                    (const_int 32)))
1378    (set (match_dup 5)
1379         (lshiftrt:DI (match_dup 5)
1380                      (const_int 32)))
1382    ;; Shift OP0 into place.
1383    (set (match_dup 0)
1384         (ashift:DI (match_dup 0)
1385                    (const_int 32)))
1387    ;; OR the two halves together
1388    (set (match_dup 0)
1389         (ior:DI (match_dup 0)
1390                 (match_dup 5)))]
1391   ""
1392   [(set_attr "type" "imul")
1393    (set_attr "mode" "SI")
1394    (set_attr "length" "24")])
1396 (define_insn "*<u>mulsidi3_64bit_parts"
1397   [(set (match_operand:DI 0 "register_operand" "=l")
1398         (sign_extend:DI
1399            (mult:SI (match_operand:SI 2 "register_operand" "d")
1400                     (match_operand:SI 3 "register_operand" "d"))))
1401    (set (match_operand:DI 1 "register_operand" "=h")
1402         (ashiftrt:DI
1403            (mult:DI (any_extend:DI (match_dup 2))
1404                     (any_extend:DI (match_dup 3)))
1405            (const_int 32)))]
1406   "TARGET_64BIT && !TARGET_FIX_R4000"
1407   "mult<u>\t%2,%3"
1408   [(set_attr "type" "imul")
1409    (set_attr "mode" "SI")])
1411 ;; Widening multiply with negation.
1412 (define_insn "*muls<u>_di"
1413   [(set (match_operand:DI 0 "register_operand" "=x")
1414         (neg:DI
1415          (mult:DI
1416           (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1417           (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1418   "!TARGET_64BIT && ISA_HAS_MULS"
1419   "muls<u>\t$0,%1,%2"
1420   [(set_attr "type" "imul")
1421    (set_attr "mode" "SI")])
1423 (define_insn "*msac<u>_di"
1424   [(set (match_operand:DI 0 "register_operand" "=x")
1425         (minus:DI
1426            (match_operand:DI 3 "register_operand" "0")
1427            (mult:DI
1428               (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1429               (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1430   "!TARGET_64BIT && ISA_HAS_MSAC"
1432   if (TARGET_MIPS5500)
1433     return "msub<u>\t%1,%2";
1434   else
1435     return "msac<u>\t$0,%1,%2";
1437   [(set_attr "type" "imadd")
1438    (set_attr "mode" "SI")])
1440 ;; _highpart patterns
1442 (define_expand "<su>mulsi3_highpart"
1443   [(set (match_operand:SI 0 "register_operand")
1444         (truncate:SI
1445          (lshiftrt:DI
1446           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1447                    (any_extend:DI (match_operand:SI 2 "register_operand")))
1448           (const_int 32))))]
1449   "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1451   if (ISA_HAS_MULHI)
1452     emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1453                                                        operands[1],
1454                                                        operands[2]));
1455   else
1456     emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1457                                                  operands[2]));
1458   DONE;
1461 (define_insn "<su>mulsi3_highpart_internal"
1462   [(set (match_operand:SI 0 "register_operand" "=h")
1463         (truncate:SI
1464          (lshiftrt:DI
1465           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1466                    (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1467           (const_int 32))))
1468    (clobber (match_scratch:SI 3 "=l"))]
1469   "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1470   "mult<u>\t%1,%2"
1471   [(set_attr "type" "imul")
1472    (set_attr "mode" "SI")])
1474 (define_insn "<su>mulsi3_highpart_mulhi_internal"
1475   [(set (match_operand:SI 0 "register_operand" "=h,d")
1476         (truncate:SI
1477          (lshiftrt:DI
1478           (mult:DI
1479            (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1480            (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1481           (const_int 32))))
1482    (clobber (match_scratch:SI 3 "=l,l"))
1483    (clobber (match_scratch:SI 4 "=X,h"))]
1484   "ISA_HAS_MULHI"
1485   "@
1486    mult<u>\t%1,%2
1487    mulhi<u>\t%0,%1,%2"
1488   [(set_attr "type" "imul")
1489    (set_attr "mode" "SI")])
1491 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1492   [(set (match_operand:SI 0 "register_operand" "=h,d")
1493         (truncate:SI
1494          (lshiftrt:DI
1495           (neg:DI
1496            (mult:DI
1497             (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1498             (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1499           (const_int 32))))
1500    (clobber (match_scratch:SI 3 "=l,l"))
1501    (clobber (match_scratch:SI 4 "=X,h"))]
1502   "ISA_HAS_MULHI"
1503   "@
1504    mulshi<u>\t%.,%1,%2
1505    mulshi<u>\t%0,%1,%2"
1506   [(set_attr "type" "imul")
1507    (set_attr "mode" "SI")])
1509 ;; Disable unsigned multiplication for -mfix-vr4120.  This is for VR4120
1510 ;; errata MD(0), which says that dmultu does not always produce the
1511 ;; correct result.
1512 (define_insn "<su>muldi3_highpart"
1513   [(set (match_operand:DI 0 "register_operand" "=h")
1514         (truncate:DI
1515          (lshiftrt:TI
1516           (mult:TI
1517            (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1518            (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1519           (const_int 64))))
1520    (clobber (match_scratch:DI 3 "=l"))]
1521   "TARGET_64BIT && !TARGET_FIX_R4000
1522    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1523   "dmult<u>\t%1,%2"
1524   [(set_attr "type" "imul")
1525    (set_attr "mode" "DI")])
1527 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1528 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
1530 (define_insn "madsi"
1531   [(set (match_operand:SI 0 "register_operand" "+l")
1532         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1533                           (match_operand:SI 2 "register_operand" "d"))
1534                  (match_dup 0)))
1535    (clobber (match_scratch:SI 3 "=h"))]
1536   "TARGET_MAD"
1537   "mad\t%1,%2"
1538   [(set_attr "type"     "imadd")
1539    (set_attr "mode"     "SI")])
1541 (define_insn "*<su>mul_acc_di"
1542   [(set (match_operand:DI 0 "register_operand" "=x")
1543         (plus:DI
1544          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1545                   (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1546          (match_operand:DI 3 "register_operand" "0")))]
1547   "(TARGET_MAD || ISA_HAS_MACC)
1548    && !TARGET_64BIT"
1550   if (TARGET_MAD)
1551     return "mad<u>\t%1,%2";
1552   else if (TARGET_MIPS5500)
1553     return "madd<u>\t%1,%2";
1554   else
1555     /* See comment in *macc.  */
1556     return "%[macc<u>\t%@,%1,%2%]";
1558   [(set_attr "type" "imadd")
1559    (set_attr "mode" "SI")])
1561 ;; Floating point multiply accumulate instructions.
1563 (define_insn ""
1564   [(set (match_operand:DF 0 "register_operand" "=f")
1565         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1566                           (match_operand:DF 2 "register_operand" "f"))
1567                  (match_operand:DF 3 "register_operand" "f")))]
1568   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1569   "madd.d\t%0,%3,%1,%2"
1570   [(set_attr "type"     "fmadd")
1571    (set_attr "mode"     "DF")])
1573 (define_insn ""
1574   [(set (match_operand:SF 0 "register_operand" "=f")
1575         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1576                           (match_operand:SF 2 "register_operand" "f"))
1577                  (match_operand:SF 3 "register_operand" "f")))]
1578   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1579   "madd.s\t%0,%3,%1,%2"
1580   [(set_attr "type"     "fmadd")
1581    (set_attr "mode"     "SF")])
1583 (define_insn ""
1584   [(set (match_operand:DF 0 "register_operand" "=f")
1585         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1586                            (match_operand:DF 2 "register_operand" "f"))
1587                   (match_operand:DF 3 "register_operand" "f")))]
1588   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1589   "msub.d\t%0,%3,%1,%2"
1590   [(set_attr "type"     "fmadd")
1591    (set_attr "mode"     "DF")])
1593 (define_insn ""
1594   [(set (match_operand:SF 0 "register_operand" "=f")
1595         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1596                            (match_operand:SF 2 "register_operand" "f"))
1597                   (match_operand:SF 3 "register_operand" "f")))]
1599   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1600   "msub.s\t%0,%3,%1,%2"
1601   [(set_attr "type"     "fmadd")
1602    (set_attr "mode"     "SF")])
1604 (define_insn ""
1605   [(set (match_operand:DF 0 "register_operand" "=f")
1606         (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1607                                   (match_operand:DF 2 "register_operand" "f"))
1608                          (match_operand:DF 3 "register_operand" "f"))))]
1609   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1610    && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1611   "nmadd.d\t%0,%3,%1,%2"
1612   [(set_attr "type"     "fmadd")
1613    (set_attr "mode"     "DF")])
1615 (define_insn ""
1616   [(set (match_operand:DF 0 "register_operand" "=f")
1617         (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
1618                                    (match_operand:DF 2 "register_operand" "f"))
1619                   (match_operand:DF 3 "register_operand" "f")))]
1620   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1621    && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1622   "nmadd.d\t%0,%3,%1,%2"
1623   [(set_attr "type"     "fmadd")
1624    (set_attr "mode"     "DF")])
1626 (define_insn ""
1627   [(set (match_operand:SF 0 "register_operand" "=f")
1628         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1629                                   (match_operand:SF 2 "register_operand" "f"))
1630                          (match_operand:SF 3 "register_operand" "f"))))]
1631   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1632    && HONOR_SIGNED_ZEROS (SFmode)"
1633   "nmadd.s\t%0,%3,%1,%2"
1634   [(set_attr "type"     "fmadd")
1635    (set_attr "mode"     "SF")])
1637 (define_insn ""
1638   [(set (match_operand:SF 0 "register_operand" "=f")
1639         (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
1640                            (match_operand:SF 2 "register_operand" "f"))
1641                   (match_operand:SF 3 "register_operand" "f")))]
1642   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1643    && !HONOR_SIGNED_ZEROS (SFmode)"
1644   "nmadd.s\t%0,%3,%1,%2"
1645   [(set_attr "type"     "fmadd")
1646    (set_attr "mode"     "SF")])
1648 (define_insn ""
1649   [(set (match_operand:DF 0 "register_operand" "=f")
1650         (neg:DF (minus:DF (mult:DF (match_operand:DF 2 "register_operand" "f")
1651                                    (match_operand:DF 3 "register_operand" "f"))
1652                           (match_operand:DF 1 "register_operand" "f"))))]
1653   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1654    && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1655   "nmsub.d\t%0,%1,%2,%3"
1656   [(set_attr "type"     "fmadd")
1657    (set_attr "mode"     "DF")])
1659 (define_insn ""
1660   [(set (match_operand:DF 0 "register_operand" "=f")
1661         (minus:DF (match_operand:DF 1 "register_operand" "f")
1662                   (mult:DF (match_operand:DF 2 "register_operand" "f")
1663                            (match_operand:DF 3 "register_operand" "f"))))]
1664   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1665    && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1666   "nmsub.d\t%0,%1,%2,%3"
1667   [(set_attr "type"     "fmadd")
1668    (set_attr "mode"     "DF")])
1670 (define_insn ""
1671   [(set (match_operand:SF 0 "register_operand" "=f")
1672         (neg:SF (minus:SF (mult:SF (match_operand:SF 2 "register_operand" "f")
1673                                    (match_operand:SF 3 "register_operand" "f"))
1674                           (match_operand:SF 1 "register_operand" "f"))))]
1675   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1676    && HONOR_SIGNED_ZEROS (SFmode)"
1677   "nmsub.s\t%0,%1,%2,%3"
1678   [(set_attr "type"     "fmadd")
1679    (set_attr "mode"     "SF")])
1681 (define_insn ""
1682   [(set (match_operand:SF 0 "register_operand" "=f")
1683         (minus:SF (match_operand:SF 1 "register_operand" "f")
1684                   (mult:SF (match_operand:SF 2 "register_operand" "f")
1685                            (match_operand:SF 3 "register_operand" "f"))))]
1686   "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1687    && !HONOR_SIGNED_ZEROS (SFmode)"
1688   "nmsub.s\t%0,%1,%2,%3"
1689   [(set_attr "type"     "fmadd")
1690    (set_attr "mode"     "SF")])
1693 ;;  ....................
1695 ;;      DIVISION and REMAINDER
1697 ;;  ....................
1700 (define_expand "divdf3"
1701   [(set (match_operand:DF 0 "register_operand")
1702         (div:DF (match_operand:DF 1 "reg_or_1_operand")
1703                 (match_operand:DF 2 "register_operand")))]
1704   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1706   if (const_1_operand (operands[1], DFmode))
1707     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1708       operands[1] = force_reg (DFmode, operands[1]);
1711 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
1713 ;; If an mfc1 or dmfc1 happens to access the floating point register
1714 ;; file at the same time a long latency operation (div, sqrt, recip,
1715 ;; sqrt) iterates an intermediate result back through the floating
1716 ;; point register file bypass, then instead returning the correct
1717 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1718 ;; result of the long latency operation.
1720 ;; The workaround is to insert an unconditional 'mov' from/to the
1721 ;; long latency op destination register.
1723 (define_insn "*divdf3"
1724   [(set (match_operand:DF 0 "register_operand" "=f")
1725         (div:DF (match_operand:DF 1 "register_operand" "f")
1726                 (match_operand:DF 2 "register_operand" "f")))]
1727   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1729   if (TARGET_FIX_SB1)
1730     return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
1731   else
1732     return "div.d\t%0,%1,%2";
1734   [(set_attr "type"     "fdiv")
1735    (set_attr "mode"     "DF")
1736    (set (attr "length")
1737         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1738                       (const_int 8)
1739                       (const_int 4)))])
1742 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
1744 ;; In certain cases, div.s and div.ps may have a rounding error
1745 ;; and/or wrong inexact flag.
1747 ;; Therefore, we only allow div.s if not working around SB-1 rev2
1748 ;; errata, or if working around those errata and a slight loss of
1749 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
1750 (define_expand "divsf3"
1751   [(set (match_operand:SF 0 "register_operand")
1752         (div:SF (match_operand:SF 1 "reg_or_1_operand")
1753                 (match_operand:SF 2 "register_operand")))]
1754   "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
1756   if (const_1_operand (operands[1], SFmode))
1757     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1758       operands[1] = force_reg (SFmode, operands[1]);
1761 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1762 ;; "divdf3" comment for details).
1764 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
1765 ;; "divsf3" comment for details).
1766 (define_insn "*divsf3"
1767   [(set (match_operand:SF 0 "register_operand" "=f")
1768         (div:SF (match_operand:SF 1 "register_operand" "f")
1769                 (match_operand:SF 2 "register_operand" "f")))]
1770   "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
1772   if (TARGET_FIX_SB1)
1773     return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
1774   else
1775     return "div.s\t%0,%1,%2";
1777   [(set_attr "type"     "fdiv")
1778    (set_attr "mode"     "SF")
1779    (set (attr "length")
1780         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1781                       (const_int 8)
1782                       (const_int 4)))])
1784 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1785 ;; "divdf3" comment for details).
1786 (define_insn ""
1787   [(set (match_operand:DF 0 "register_operand" "=f")
1788         (div:DF (match_operand:DF 1 "const_1_operand" "")
1789                 (match_operand:DF 2 "register_operand" "f")))]
1790   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
1792   if (TARGET_FIX_SB1)
1793     return "recip.d\t%0,%2\;mov.d\t%0,%0";
1794   else
1795     return "recip.d\t%0,%2";
1797   [(set_attr "type"     "frdiv")
1798    (set_attr "mode"     "DF")
1799    (set (attr "length")
1800         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1801                       (const_int 8)
1802                       (const_int 4)))])
1804 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1805 ;; "divdf3" comment for details).
1806 (define_insn ""
1807   [(set (match_operand:SF 0 "register_operand" "=f")
1808         (div:SF (match_operand:SF 1 "const_1_operand" "")
1809                 (match_operand:SF 2 "register_operand" "f")))]
1810   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
1812   if (TARGET_FIX_SB1)
1813     return "recip.s\t%0,%2\;mov.s\t%0,%0";
1814   else
1815     return "recip.s\t%0,%2";
1817   [(set_attr "type"     "frdiv")
1818    (set_attr "mode"     "SF")
1819    (set (attr "length")
1820         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1821                       (const_int 8)
1822                       (const_int 4)))])
1824 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
1825 ;; with negative operands.  We use special libgcc functions instead.
1826 (define_insn "divmod<mode>4"
1827   [(set (match_operand:GPR 0 "register_operand" "=l")
1828         (div:GPR (match_operand:GPR 1 "register_operand" "d")
1829                  (match_operand:GPR 2 "register_operand" "d")))
1830    (set (match_operand:GPR 3 "register_operand" "=h")
1831         (mod:GPR (match_dup 1)
1832                  (match_dup 2)))]
1833   "!TARGET_FIX_VR4120"
1834   { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1835   [(set_attr "type" "idiv")
1836    (set_attr "mode" "<MODE>")])
1838 (define_insn "udivmod<mode>4"
1839   [(set (match_operand:GPR 0 "register_operand" "=l")
1840         (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1841                   (match_operand:GPR 2 "register_operand" "d")))
1842    (set (match_operand:GPR 3 "register_operand" "=h")
1843         (umod:GPR (match_dup 1)
1844                   (match_dup 2)))]
1845   ""
1846   { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1847   [(set_attr "type" "idiv")
1848    (set_attr "mode" "<MODE>")])
1851 ;;  ....................
1853 ;;      SQUARE ROOT
1855 ;;  ....................
1857 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1858 ;; "divdf3" comment for details).
1859 (define_insn "sqrtdf2"
1860   [(set (match_operand:DF 0 "register_operand" "=f")
1861         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
1862   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
1864   if (TARGET_FIX_SB1)
1865     return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
1866   else
1867     return "sqrt.d\t%0,%1";
1869   [(set_attr "type"     "fsqrt")
1870    (set_attr "mode"     "DF")
1871    (set (attr "length")
1872         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1873                       (const_int 8)
1874                       (const_int 4)))])
1876 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1877 ;; "divdf3" comment for details).
1878 (define_insn "sqrtsf2"
1879   [(set (match_operand:SF 0 "register_operand" "=f")
1880         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
1881   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
1883   if (TARGET_FIX_SB1)
1884     return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
1885   else
1886     return "sqrt.s\t%0,%1";
1888   [(set_attr "type"     "fsqrt")
1889    (set_attr "mode"     "SF")
1890    (set (attr "length")
1891         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1892                       (const_int 8)
1893                       (const_int 4)))])
1895 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1896 ;; "divdf3" comment for details).
1897 (define_insn ""
1898   [(set (match_operand:DF 0 "register_operand" "=f")
1899         (div:DF (match_operand:DF 1 "const_1_operand" "")
1900                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
1901   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
1903   if (TARGET_FIX_SB1)
1904     return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
1905   else
1906     return "rsqrt.d\t%0,%2";
1908   [(set_attr "type"     "frsqrt")
1909    (set_attr "mode"     "DF")
1910    (set (attr "length")
1911         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1912                       (const_int 8)
1913                       (const_int 4)))])
1915 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1916 ;; "divdf3" comment for details).
1917 (define_insn ""
1918   [(set (match_operand:SF 0 "register_operand" "=f")
1919         (div:SF (match_operand:SF 1 "const_1_operand" "")
1920                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
1921   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
1923   if (TARGET_FIX_SB1)
1924     return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
1925   else
1926     return "rsqrt.s\t%0,%2";
1928   [(set_attr "type"     "frsqrt")
1929    (set_attr "mode"     "SF")
1930    (set (attr "length")
1931         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1932                       (const_int 8)
1933                       (const_int 4)))])
1935 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1936 ;; "divdf3" comment for details).
1937 (define_insn ""
1938   [(set (match_operand:DF 0 "register_operand" "=f")
1939         (sqrt:DF (div:DF (match_operand:DF 1 "const_1_operand" "")
1940                          (match_operand:DF 2 "register_operand" "f"))))]
1941   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
1943   if (TARGET_FIX_SB1)
1944     return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
1945   else
1946     return "rsqrt.d\t%0,%2";
1948   [(set_attr "type"     "frsqrt")
1949    (set_attr "mode"     "DF")
1950    (set (attr "length")
1951         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1952                       (const_int 8)
1953                       (const_int 4)))])
1955 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1956 ;; "divdf3" comment for details).
1957 (define_insn ""
1958   [(set (match_operand:SF 0 "register_operand" "=f")
1959         (sqrt:SF (div:SF (match_operand:SF 1 "const_1_operand" "")
1960                          (match_operand:SF 2 "register_operand" "f"))))]
1961   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
1963   if (TARGET_FIX_SB1)
1964     return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
1965   else
1966     return "rsqrt.s\t%0,%2";
1968   [(set_attr "type"     "frsqrt")
1969    (set_attr "mode"     "SF")
1970    (set (attr "length")
1971         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1972                       (const_int 8)
1973                       (const_int 4)))])
1976 ;;  ....................
1978 ;;      ABSOLUTE VALUE
1980 ;;  ....................
1982 ;; Do not use the integer abs macro instruction, since that signals an
1983 ;; exception on -2147483648 (sigh).
1985 (define_insn "abs<mode>2"
1986   [(set (match_operand:GPR 0 "register_operand" "=d")
1987         (abs:GPR (match_operand:GPR 1 "register_operand" "d")))]
1988   "!TARGET_MIPS16"
1990   if (REGNO (operands[0]) == REGNO (operands[1]) && GENERATE_BRANCHLIKELY)
1991     return "%(bltzl\t%1,1f\;<d>subu\t%0,%.,%0\n%~1:%)";
1992   else
1993     return "%(bgez\t%1,1f\;move\t%0,%1\;<d>subu\t%0,%.,%0\n%~1:%)";
1995   [(set_attr "type" "multi")
1996    (set_attr "mode" "<MODE>")
1997    (set_attr "length" "12")])
1999 (define_insn "absdf2"
2000   [(set (match_operand:DF 0 "register_operand" "=f")
2001         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2002   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2003   "abs.d\t%0,%1"
2004   [(set_attr "type"     "fabs")
2005    (set_attr "mode"     "DF")])
2007 (define_insn "abssf2"
2008   [(set (match_operand:SF 0 "register_operand" "=f")
2009         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2010   "TARGET_HARD_FLOAT"
2011   "abs.s\t%0,%1"
2012   [(set_attr "type"     "fabs")
2013    (set_attr "mode"     "SF")])
2016 ;;  ....................
2018 ;;      FIND FIRST BIT INSTRUCTION
2020 ;;  ....................
2023 (define_insn "ffs<mode>2"
2024   [(set (match_operand:GPR 0 "register_operand" "=&d")
2025         (ffs:GPR (match_operand:GPR 1 "register_operand" "d")))
2026    (clobber (match_scratch:GPR 2 "=&d"))
2027    (clobber (match_scratch:GPR 3 "=&d"))]
2028   "!TARGET_MIPS16"
2030   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2031     return "%(\
2032 move\t%0,%.\;\
2033 beq\t%1,%.,2f\n\
2034 %~1:\tand\t%2,%1,0x0001\;\
2035 <d>addu\t%0,%0,1\;\
2036 beq\t%2,%.,1b\;\
2037 <d>srl\t%1,%1,1\n\
2038 %~2:%)";
2040   return "%(\
2041 move\t%0,%.\;\
2042 move\t%3,%1\;\
2043 beq\t%3,%.,2f\n\
2044 %~1:\tand\t%2,%3,0x0001\;\
2045 <d>addu\t%0,%0,1\;\
2046 beq\t%2,%.,1b\;\
2047 <d>srl\t%3,%3,1\n\
2048 %~2:%)";
2050   [(set_attr "type" "multi")
2051    (set_attr "mode" "<MODE>")
2052    (set_attr "length" "28")])
2055 ;;  ...................
2057 ;;  Count leading zeroes.
2059 ;;  ...................
2062 (define_insn "clz<mode>2"
2063   [(set (match_operand:GPR 0 "register_operand" "=d")
2064         (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2065   "ISA_HAS_CLZ_CLO"
2066   "<d>clz\t%0,%1"
2067   [(set_attr "type" "clz")
2068    (set_attr "mode" "<MODE>")])
2071 ;;  ....................
2073 ;;      NEGATION and ONE'S COMPLEMENT
2075 ;;  ....................
2077 (define_insn "negsi2"
2078   [(set (match_operand:SI 0 "register_operand" "=d")
2079         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2080   ""
2082   if (TARGET_MIPS16)
2083     return "neg\t%0,%1";
2084   else
2085     return "subu\t%0,%.,%1";
2087   [(set_attr "type"     "arith")
2088    (set_attr "mode"     "SI")])
2090 (define_insn "negdi2"
2091   [(set (match_operand:DI 0 "register_operand" "=d")
2092         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2093   "TARGET_64BIT && !TARGET_MIPS16"
2094   "dsubu\t%0,%.,%1"
2095   [(set_attr "type"     "arith")
2096    (set_attr "mode"     "DI")])
2098 (define_insn "negdf2"
2099   [(set (match_operand:DF 0 "register_operand" "=f")
2100         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2101   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2102   "neg.d\t%0,%1"
2103   [(set_attr "type"     "fneg")
2104    (set_attr "mode"     "DF")])
2106 (define_insn "negsf2"
2107   [(set (match_operand:SF 0 "register_operand" "=f")
2108         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2109   "TARGET_HARD_FLOAT"
2110   "neg.s\t%0,%1"
2111   [(set_attr "type"     "fneg")
2112    (set_attr "mode"     "SF")])
2114 (define_insn "one_cmpl<mode>2"
2115   [(set (match_operand:GPR 0 "register_operand" "=d")
2116         (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2117   ""
2119   if (TARGET_MIPS16)
2120     return "not\t%0,%1";
2121   else
2122     return "nor\t%0,%.,%1";
2124   [(set_attr "type" "arith")
2125    (set_attr "mode" "<MODE>")])
2128 ;;  ....................
2130 ;;      LOGICAL
2132 ;;  ....................
2135 ;; Many of these instructions use trivial define_expands, because we
2136 ;; want to use a different set of constraints when TARGET_MIPS16.
2138 (define_expand "and<mode>3"
2139   [(set (match_operand:GPR 0 "register_operand")
2140         (and:GPR (match_operand:GPR 1 "register_operand")
2141                  (match_operand:GPR 2 "uns_arith_operand")))]
2142   ""
2144   if (TARGET_MIPS16)
2145     operands[2] = force_reg (<MODE>mode, operands[2]);
2148 (define_insn "*and<mode>3"
2149   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2150         (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2151                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2152   "!TARGET_MIPS16"
2153   "@
2154    and\t%0,%1,%2
2155    andi\t%0,%1,%x2"
2156   [(set_attr "type" "arith")
2157    (set_attr "mode" "<MODE>")])
2159 (define_insn "*and<mode>3_mips16"
2160   [(set (match_operand:GPR 0 "register_operand" "=d")
2161         (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2162                  (match_operand:GPR 2 "register_operand" "d")))]
2163   "TARGET_MIPS16"
2164   "and\t%0,%2"
2165   [(set_attr "type" "arith")
2166    (set_attr "mode" "<MODE>")])
2168 (define_expand "ior<mode>3"
2169   [(set (match_operand:GPR 0 "register_operand")
2170         (ior:GPR (match_operand:GPR 1 "register_operand")
2171                  (match_operand:GPR 2 "uns_arith_operand")))]
2172   ""
2174   if (TARGET_MIPS16)
2175     operands[2] = force_reg (<MODE>mode, operands[2]);
2178 (define_insn "*ior<mode>3"
2179   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2180         (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2181                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2182   "!TARGET_MIPS16"
2183   "@
2184    or\t%0,%1,%2
2185    ori\t%0,%1,%x2"
2186   [(set_attr "type" "arith")
2187    (set_attr "mode" "<MODE>")])
2189 (define_insn "*ior<mode>3_mips16"
2190   [(set (match_operand:GPR 0 "register_operand" "=d")
2191         (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2192                  (match_operand:GPR 2 "register_operand" "d")))]
2193   "TARGET_MIPS16"
2194   "or\t%0,%2"
2195   [(set_attr "type" "arith")
2196    (set_attr "mode" "<MODE>")])
2198 (define_expand "xor<mode>3"
2199   [(set (match_operand:GPR 0 "register_operand")
2200         (xor:GPR (match_operand:GPR 1 "register_operand")
2201                  (match_operand:GPR 2 "uns_arith_operand")))]
2202   ""
2203   "")
2205 (define_insn ""
2206   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2207         (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2208                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2209   "!TARGET_MIPS16"
2210   "@
2211    xor\t%0,%1,%2
2212    xori\t%0,%1,%x2"
2213   [(set_attr "type" "arith")
2214    (set_attr "mode" "<MODE>")])
2216 (define_insn ""
2217   [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2218         (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2219                  (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2220   "TARGET_MIPS16"
2221   "@
2222    xor\t%0,%2
2223    cmpi\t%1,%2
2224    cmp\t%1,%2"
2225   [(set_attr "type" "arith")
2226    (set_attr "mode" "<MODE>")
2227    (set_attr_alternative "length"
2228                 [(const_int 4)
2229                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2230                                (const_int 4)
2231                                (const_int 8))
2232                  (const_int 4)])])
2234 (define_insn "*nor<mode>3"
2235   [(set (match_operand:GPR 0 "register_operand" "=d")
2236         (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2237                  (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2238   "!TARGET_MIPS16"
2239   "nor\t%0,%1,%2"
2240   [(set_attr "type" "arith")
2241    (set_attr "mode" "<MODE>")])
2244 ;;  ....................
2246 ;;      TRUNCATION
2248 ;;  ....................
2252 (define_insn "truncdfsf2"
2253   [(set (match_operand:SF 0 "register_operand" "=f")
2254         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2255   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2256   "cvt.s.d\t%0,%1"
2257   [(set_attr "type"     "fcvt")
2258    (set_attr "mode"     "SF")])
2260 ;; Integer truncation patterns.  Truncating SImode values to smaller
2261 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
2262 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2263 ;; need to make sure that the lower 32 bits are properly sign-extended
2264 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2265 ;; smaller than SImode is equivalent to two separate truncations:
2267 ;;                        A       B
2268 ;;    DI ---> HI  ==  DI ---> SI ---> HI
2269 ;;    DI ---> QI  ==  DI ---> SI ---> QI
2271 ;; Step A needs a real instruction but step B does not.
2273 (define_insn "truncdisi2"
2274   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2275         (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2276   "TARGET_64BIT"
2277   "@
2278     sll\t%0,%1,0
2279     sw\t%1,%0"
2280   [(set_attr "type" "shift,store")
2281    (set_attr "mode" "SI")
2282    (set_attr "extended_mips16" "yes,*")])
2284 (define_insn "truncdihi2"
2285   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2286         (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2287   "TARGET_64BIT"
2288   "@
2289     sll\t%0,%1,0
2290     sh\t%1,%0"
2291   [(set_attr "type" "shift,store")
2292    (set_attr "mode" "SI")
2293    (set_attr "extended_mips16" "yes,*")])
2295 (define_insn "truncdiqi2"
2296   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2297         (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2298   "TARGET_64BIT"
2299   "@
2300     sll\t%0,%1,0
2301     sb\t%1,%0"
2302   [(set_attr "type" "shift,store")
2303    (set_attr "mode" "SI")
2304    (set_attr "extended_mips16" "yes,*")])
2306 ;; Combiner patterns to optimize shift/truncate combinations.
2308 (define_insn ""
2309   [(set (match_operand:SI 0 "register_operand" "=d")
2310         (truncate:SI
2311           (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2312                        (match_operand:DI 2 "const_arith_operand" ""))))]
2313   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2314   "dsra\t%0,%1,%2"
2315   [(set_attr "type" "shift")
2316    (set_attr "mode" "SI")])
2318 (define_insn ""
2319   [(set (match_operand:SI 0 "register_operand" "=d")
2320         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2321                                   (const_int 32))))]
2322   "TARGET_64BIT && !TARGET_MIPS16"
2323   "dsra\t%0,%1,32"
2324   [(set_attr "type" "shift")
2325    (set_attr "mode" "SI")])
2328 ;; Combiner patterns for truncate/sign_extend combinations.  They use
2329 ;; the shift/truncate patterns above.
2331 (define_insn_and_split ""
2332   [(set (match_operand:SI 0 "register_operand" "=d")
2333         (sign_extend:SI
2334             (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2335   "TARGET_64BIT && !TARGET_MIPS16"
2336   "#"
2337   "&& reload_completed"
2338   [(set (match_dup 2)
2339         (ashift:DI (match_dup 1)
2340                    (const_int 48)))
2341    (set (match_dup 0)
2342         (truncate:SI (ashiftrt:DI (match_dup 2)
2343                                   (const_int 48))))]
2344   { operands[2] = gen_lowpart (DImode, operands[0]); })
2346 (define_insn_and_split ""
2347   [(set (match_operand:SI 0 "register_operand" "=d")
2348         (sign_extend:SI
2349             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2350   "TARGET_64BIT && !TARGET_MIPS16"
2351   "#"
2352   "&& reload_completed"
2353   [(set (match_dup 2)
2354         (ashift:DI (match_dup 1)
2355                    (const_int 56)))
2356    (set (match_dup 0)
2357         (truncate:SI (ashiftrt:DI (match_dup 2)
2358                                   (const_int 56))))]
2359   { operands[2] = gen_lowpart (DImode, operands[0]); })
2362 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2364 (define_insn ""
2365   [(set (match_operand:SI 0 "register_operand" "=d")
2366         (zero_extend:SI (truncate:HI
2367                          (match_operand:DI 1 "register_operand" "d"))))]
2368   "TARGET_64BIT && !TARGET_MIPS16"
2369   "andi\t%0,%1,0xffff"
2370   [(set_attr "type"     "arith")
2371    (set_attr "mode"     "SI")])
2373 (define_insn ""
2374   [(set (match_operand:SI 0 "register_operand" "=d")
2375         (zero_extend:SI (truncate:QI
2376                          (match_operand:DI 1 "register_operand" "d"))))]
2377   "TARGET_64BIT && !TARGET_MIPS16"
2378   "andi\t%0,%1,0xff"
2379   [(set_attr "type"     "arith")
2380    (set_attr "mode"     "SI")])
2382 (define_insn ""
2383   [(set (match_operand:HI 0 "register_operand" "=d")
2384         (zero_extend:HI (truncate:QI
2385                          (match_operand:DI 1 "register_operand" "d"))))]
2386   "TARGET_64BIT && !TARGET_MIPS16"
2387   "andi\t%0,%1,0xff"
2388   [(set_attr "type"     "arith")
2389    (set_attr "mode"     "HI")])
2392 ;;  ....................
2394 ;;      ZERO EXTENSION
2396 ;;  ....................
2398 ;; Extension insns.
2399 ;; Those for integer source operand are ordered widest source type first.
2401 (define_insn_and_split "zero_extendsidi2"
2402   [(set (match_operand:DI 0 "register_operand" "=d")
2403         (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2404   "TARGET_64BIT"
2405   "#"
2406   "&& reload_completed"
2407   [(set (match_dup 0)
2408         (ashift:DI (match_dup 1) (const_int 32)))
2409    (set (match_dup 0)
2410         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2411   "operands[1] = gen_lowpart (DImode, operands[1]);"
2412   [(set_attr "type" "multi")
2413    (set_attr "mode" "DI")
2414    (set_attr "length" "8")])
2416 (define_insn "*zero_extendsidi2_mem"
2417   [(set (match_operand:DI 0 "register_operand" "=d")
2418         (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2419   "TARGET_64BIT"
2420   "lwu\t%0,%1"
2421   [(set_attr "type"     "load")
2422    (set_attr "mode"     "DI")])
2424 (define_expand "zero_extendhisi2"
2425   [(set (match_operand:SI 0 "register_operand")
2426         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2427   ""
2429   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2430     {
2431       rtx op = gen_lowpart (SImode, operands[1]);
2432       rtx temp = force_reg (SImode, GEN_INT (0xffff));
2434       emit_insn (gen_andsi3 (operands[0], op, temp));
2435       DONE;
2436     }
2439 (define_insn ""
2440   [(set (match_operand:SI 0 "register_operand" "=d,d")
2441         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2442   "!TARGET_MIPS16"
2443   "@
2444    andi\t%0,%1,0xffff
2445    lhu\t%0,%1"
2446   [(set_attr "type"     "arith,load")
2447    (set_attr "mode"     "SI")
2448    (set_attr "length"   "4,*")])
2450 (define_insn ""
2451   [(set (match_operand:SI 0 "register_operand" "=d")
2452         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2453   "TARGET_MIPS16"
2454   "lhu\t%0,%1"
2455   [(set_attr "type"     "load")
2456    (set_attr "mode"     "SI")])
2458 (define_expand "zero_extendhidi2"
2459   [(set (match_operand:DI 0 "register_operand")
2460         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2461   "TARGET_64BIT"
2463   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2464     {
2465       rtx op = gen_lowpart (DImode, operands[1]);
2466       rtx temp = force_reg (DImode, GEN_INT (0xffff));
2468       emit_insn (gen_anddi3 (operands[0], op, temp));
2469       DONE;
2470     }
2473 (define_insn ""
2474   [(set (match_operand:DI 0 "register_operand" "=d,d")
2475         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2476   "TARGET_64BIT && !TARGET_MIPS16"
2477   "@
2478    andi\t%0,%1,0xffff
2479    lhu\t%0,%1"
2480   [(set_attr "type"     "arith,load")
2481    (set_attr "mode"     "DI")
2482    (set_attr "length"   "4,*")])
2484 (define_insn ""
2485   [(set (match_operand:DI 0 "register_operand" "=d")
2486         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2487   "TARGET_64BIT && TARGET_MIPS16"
2488   "lhu\t%0,%1"
2489   [(set_attr "type"     "load")
2490    (set_attr "mode"     "DI")])
2492 (define_expand "zero_extendqihi2"
2493   [(set (match_operand:HI 0 "register_operand")
2494         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2495   ""
2497   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2498     {
2499       rtx op0 = gen_lowpart (SImode, operands[0]);
2500       rtx op1 = gen_lowpart (SImode, operands[1]);
2501       rtx temp = force_reg (SImode, GEN_INT (0xff));
2503       emit_insn (gen_andsi3 (op0, op1, temp));
2504       DONE;
2505     }
2508 (define_insn ""
2509   [(set (match_operand:HI 0 "register_operand" "=d,d")
2510         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2511   "!TARGET_MIPS16"
2512   "@
2513    andi\t%0,%1,0x00ff
2514    lbu\t%0,%1"
2515   [(set_attr "type"     "arith,load")
2516    (set_attr "mode"     "HI")
2517    (set_attr "length"   "4,*")])
2519 (define_insn ""
2520   [(set (match_operand:HI 0 "register_operand" "=d")
2521         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2522   "TARGET_MIPS16"
2523   "lbu\t%0,%1"
2524   [(set_attr "type"     "load")
2525    (set_attr "mode"     "HI")])
2527 (define_expand "zero_extendqisi2"
2528   [(set (match_operand:SI 0 "register_operand")
2529         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2530   ""
2532   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2533     {
2534       rtx op = gen_lowpart (SImode, operands[1]);
2535       rtx temp = force_reg (SImode, GEN_INT (0xff));
2537       emit_insn (gen_andsi3 (operands[0], op, temp));
2538       DONE;
2539     }
2542 (define_insn ""
2543   [(set (match_operand:SI 0 "register_operand" "=d,d")
2544         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2545   "!TARGET_MIPS16"
2546   "@
2547    andi\t%0,%1,0x00ff
2548    lbu\t%0,%1"
2549   [(set_attr "type"     "arith,load")
2550    (set_attr "mode"     "SI")
2551    (set_attr "length"   "4,*")])
2553 (define_insn ""
2554   [(set (match_operand:SI 0 "register_operand" "=d")
2555         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2556   "TARGET_MIPS16"
2557   "lbu\t%0,%1"
2558   [(set_attr "type"     "load")
2559    (set_attr "mode"     "SI")])
2561 (define_expand "zero_extendqidi2"
2562   [(set (match_operand:DI 0 "register_operand")
2563         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2564   "TARGET_64BIT"
2566   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2567     {
2568       rtx op = gen_lowpart (DImode, operands[1]);
2569       rtx temp = force_reg (DImode, GEN_INT (0xff));
2571       emit_insn (gen_anddi3 (operands[0], op, temp));
2572       DONE;
2573     }
2576 (define_insn ""
2577   [(set (match_operand:DI 0 "register_operand" "=d,d")
2578         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2579   "TARGET_64BIT && !TARGET_MIPS16"
2580   "@
2581    andi\t%0,%1,0x00ff
2582    lbu\t%0,%1"
2583   [(set_attr "type"     "arith,load")
2584    (set_attr "mode"     "DI")
2585    (set_attr "length"   "4,*")])
2587 (define_insn ""
2588   [(set (match_operand:DI 0 "register_operand" "=d")
2589         (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2590   "TARGET_64BIT && TARGET_MIPS16"
2591   "lbu\t%0,%1"
2592   [(set_attr "type"     "load")
2593    (set_attr "mode"     "DI")])
2596 ;;  ....................
2598 ;;      SIGN EXTENSION
2600 ;;  ....................
2602 ;; Extension insns.
2603 ;; Those for integer source operand are ordered widest source type first.
2605 ;; When TARGET_64BIT, all SImode integer registers should already be in
2606 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can
2607 ;; therefore get rid of register->register instructions if we constrain
2608 ;; the source to be in the same register as the destination.
2610 ;; The register alternative has type "arith" so that the pre-reload
2611 ;; scheduler will treat it as a move.  This reflects what happens if
2612 ;; the register alternative needs a reload.
2613 (define_insn_and_split "extendsidi2"
2614   [(set (match_operand:DI 0 "register_operand" "=d,d")
2615         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2616   "TARGET_64BIT"
2617   "@
2618    #
2619    lw\t%0,%1"
2620   "&& reload_completed && register_operand (operands[1], VOIDmode)"
2621   [(const_int 0)]
2623   emit_note (NOTE_INSN_DELETED);
2624   DONE;
2626   [(set_attr "type" "arith,load")
2627    (set_attr "mode" "DI")])
2629 ;; These patterns originally accepted general_operands, however, slightly
2630 ;; better code is generated by only accepting register_operands, and then
2631 ;; letting combine generate the lh and lb insns.
2633 ;; These expanders originally put values in registers first. We split
2634 ;; all non-mem patterns after reload.
2636 (define_expand "extendhidi2"
2637   [(set (match_operand:DI 0 "register_operand")
2638         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2639   "TARGET_64BIT"
2640   "")
2642 (define_insn "*extendhidi2"
2643   [(set (match_operand:DI 0 "register_operand" "=d")
2644         (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
2645   "TARGET_64BIT"
2646   "#")
2648 (define_split
2649   [(set (match_operand:DI 0 "register_operand")
2650         (sign_extend:DI (match_operand:HI 1 "register_operand")))]
2651   "TARGET_64BIT && reload_completed"
2652   [(set (match_dup 0)
2653         (ashift:DI (match_dup 1) (const_int 48)))
2654    (set (match_dup 0)
2655         (ashiftrt:DI (match_dup 0) (const_int 48)))]
2656   "operands[1] = gen_lowpart (DImode, operands[1]);")
2658 (define_insn "*extendhidi2_mem"
2659   [(set (match_operand:DI 0 "register_operand" "=d")
2660         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2661   "TARGET_64BIT"
2662   "lh\t%0,%1"
2663   [(set_attr "type"     "load")
2664    (set_attr "mode"     "DI")])
2666 (define_expand "extendhisi2"
2667   [(set (match_operand:SI 0 "register_operand")
2668         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2669   ""
2671   if (ISA_HAS_SEB_SEH)
2672     {
2673       emit_insn (gen_extendhisi2_hw (operands[0],
2674                                      force_reg (HImode, operands[1])));
2675       DONE;
2676     }
2679 (define_insn "*extendhisi2"
2680   [(set (match_operand:SI 0 "register_operand" "=d")
2681         (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
2682   ""
2683   "#")
2685 (define_split
2686   [(set (match_operand:SI 0 "register_operand")
2687         (sign_extend:SI (match_operand:HI 1 "register_operand")))]
2688   "reload_completed"
2689   [(set (match_dup 0)
2690         (ashift:SI (match_dup 1) (const_int 16)))
2691    (set (match_dup 0)
2692         (ashiftrt:SI (match_dup 0) (const_int 16)))]
2693   "operands[1] = gen_lowpart (SImode, operands[1]);")
2695 (define_insn "extendhisi2_mem"
2696   [(set (match_operand:SI 0 "register_operand" "=d")
2697         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2698   ""
2699   "lh\t%0,%1"
2700   [(set_attr "type"     "load")
2701    (set_attr "mode"     "SI")])
2703 (define_insn "extendhisi2_hw"
2704   [(set (match_operand:SI 0 "register_operand" "=r")
2705         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
2706   "ISA_HAS_SEB_SEH"
2707   "seh\t%0,%1"
2708   [(set_attr "type" "arith")
2709    (set_attr "mode" "SI")])
2711 (define_expand "extendqihi2"
2712   [(set (match_operand:HI 0 "register_operand")
2713         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2714   ""
2715   "")
2717 (define_insn "*extendqihi2"
2718   [(set (match_operand:HI 0 "register_operand" "=d")
2719         (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
2720   ""
2721   "#")
2723 (define_split
2724   [(set (match_operand:HI 0 "register_operand")
2725         (sign_extend:HI (match_operand:QI 1 "register_operand")))]
2726   "reload_completed"
2727   [(set (match_dup 0)
2728         (ashift:SI (match_dup 1) (const_int 24)))
2729    (set (match_dup 0)
2730         (ashiftrt:SI (match_dup 0) (const_int 24)))]
2731   "operands[0] = gen_lowpart (SImode, operands[0]);
2732    operands[1] = gen_lowpart (SImode, operands[1]);")
2734 (define_insn "*extendqihi2_internal_mem"
2735   [(set (match_operand:HI 0 "register_operand" "=d")
2736         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2737   ""
2738   "lb\t%0,%1"
2739   [(set_attr "type"     "load")
2740    (set_attr "mode"     "SI")])
2743 (define_expand "extendqisi2"
2744   [(set (match_operand:SI 0 "register_operand")
2745         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2746   ""
2748   if (ISA_HAS_SEB_SEH)
2749     {
2750       emit_insn (gen_extendqisi2_hw (operands[0],
2751                                      force_reg (QImode, operands[1])));
2752       DONE;
2753     }
2756 (define_insn "*extendqisi2"
2757   [(set (match_operand:SI 0 "register_operand" "=d")
2758         (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
2759   ""
2760   "#")
2762 (define_split
2763   [(set (match_operand:SI 0 "register_operand")
2764         (sign_extend:SI (match_operand:QI 1 "register_operand")))]
2765   "reload_completed"
2766   [(set (match_dup 0)
2767         (ashift:SI (match_dup 1) (const_int 24)))
2768    (set (match_dup 0)
2769         (ashiftrt:SI (match_dup 0) (const_int 24)))]
2770   "operands[1] = gen_lowpart (SImode, operands[1]);")
2772 (define_insn "*extendqisi2_mem"
2773   [(set (match_operand:SI 0 "register_operand" "=d")
2774         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2775   ""
2776   "lb\t%0,%1"
2777   [(set_attr "type"     "load")
2778    (set_attr "mode"     "SI")])
2780 (define_insn "extendqisi2_hw"
2781   [(set (match_operand:SI 0 "register_operand" "=r")
2782         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
2783   "ISA_HAS_SEB_SEH"
2784   "seb\t%0,%1"
2785   [(set_attr "type" "arith")
2786    (set_attr "mode" "SI")])
2788 (define_expand "extendqidi2"
2789   [(set (match_operand:DI 0 "register_operand")
2790         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2791   "TARGET_64BIT"
2792   "")
2794 (define_insn "*extendqidi2"
2795   [(set (match_operand:DI 0 "register_operand" "=d")
2796         (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
2797   "TARGET_64BIT"
2798   "#")
2800 (define_split
2801   [(set (match_operand:DI 0 "register_operand")
2802         (sign_extend:DI (match_operand:QI 1 "register_operand")))]
2803   "TARGET_64BIT && reload_completed"
2804   [(set (match_dup 0)
2805         (ashift:DI (match_dup 1) (const_int 56)))
2806    (set (match_dup 0)
2807         (ashiftrt:DI (match_dup 0) (const_int 56)))]
2808   "operands[1] = gen_lowpart (DImode, operands[1]);")
2810 (define_insn "*extendqidi2_mem"
2811   [(set (match_operand:DI 0 "register_operand" "=d")
2812         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2813   "TARGET_64BIT"
2814   "lb\t%0,%1"
2815   [(set_attr "type"     "load")
2816    (set_attr "mode"     "DI")])
2818 (define_insn "extendsfdf2"
2819   [(set (match_operand:DF 0 "register_operand" "=f")
2820         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2821   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2822   "cvt.d.s\t%0,%1"
2823   [(set_attr "type"     "fcvt")
2824    (set_attr "mode"     "DF")])
2827 ;;  ....................
2829 ;;      CONVERSIONS
2831 ;;  ....................
2833 (define_expand "fix_truncdfsi2"
2834   [(set (match_operand:SI 0 "register_operand")
2835         (fix:SI (match_operand:DF 1 "register_operand")))]
2836   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2838   if (!ISA_HAS_TRUNC_W)
2839     {
2840       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2841       DONE;
2842     }
2845 (define_insn "fix_truncdfsi2_insn"
2846   [(set (match_operand:SI 0 "register_operand" "=f")
2847         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2848   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2849   "trunc.w.d %0,%1"
2850   [(set_attr "type"     "fcvt")
2851    (set_attr "mode"     "DF")
2852    (set_attr "length"   "4")])
2854 (define_insn "fix_truncdfsi2_macro"
2855   [(set (match_operand:SI 0 "register_operand" "=f")
2856         (fix:SI (match_operand:DF 1 "register_operand" "f")))
2857    (clobber (match_scratch:DF 2 "=d"))]
2858   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2860   if (set_nomacro)
2861     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2862   else
2863     return "trunc.w.d %0,%1,%2";
2865   [(set_attr "type"     "fcvt")
2866    (set_attr "mode"     "DF")
2867    (set_attr "length"   "36")])
2869 (define_expand "fix_truncsfsi2"
2870   [(set (match_operand:SI 0 "register_operand")
2871         (fix:SI (match_operand:SF 1 "register_operand")))]
2872   "TARGET_HARD_FLOAT"
2874   if (!ISA_HAS_TRUNC_W)
2875     {
2876       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2877       DONE;
2878     }
2881 (define_insn "fix_truncsfsi2_insn"
2882   [(set (match_operand:SI 0 "register_operand" "=f")
2883         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2884   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2885   "trunc.w.s %0,%1"
2886   [(set_attr "type"     "fcvt")
2887    (set_attr "mode"     "DF")
2888    (set_attr "length"   "4")])
2890 (define_insn "fix_truncsfsi2_macro"
2891   [(set (match_operand:SI 0 "register_operand" "=f")
2892         (fix:SI (match_operand:SF 1 "register_operand" "f")))
2893    (clobber (match_scratch:SF 2 "=d"))]
2894   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2896   if (set_nomacro)
2897     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2898   else
2899     return "trunc.w.s %0,%1,%2";
2901   [(set_attr "type"     "fcvt")
2902    (set_attr "mode"     "DF")
2903    (set_attr "length"   "36")])
2906 (define_insn "fix_truncdfdi2"
2907   [(set (match_operand:DI 0 "register_operand" "=f")
2908         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2909   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2910   "trunc.l.d %0,%1"
2911   [(set_attr "type"     "fcvt")
2912    (set_attr "mode"     "DF")
2913    (set_attr "length"   "4")])
2916 (define_insn "fix_truncsfdi2"
2917   [(set (match_operand:DI 0 "register_operand" "=f")
2918         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2919   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2920   "trunc.l.s %0,%1"
2921   [(set_attr "type"     "fcvt")
2922    (set_attr "mode"     "SF")
2923    (set_attr "length"   "4")])
2926 (define_insn "floatsidf2"
2927   [(set (match_operand:DF 0 "register_operand" "=f")
2928         (float:DF (match_operand:SI 1 "register_operand" "f")))]
2929   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2930   "cvt.d.w\t%0,%1"
2931   [(set_attr "type"     "fcvt")
2932    (set_attr "mode"     "DF")
2933    (set_attr "length"   "4")])
2936 (define_insn "floatdidf2"
2937   [(set (match_operand:DF 0 "register_operand" "=f")
2938         (float:DF (match_operand:DI 1 "register_operand" "f")))]
2939   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2940   "cvt.d.l\t%0,%1"
2941   [(set_attr "type"     "fcvt")
2942    (set_attr "mode"     "DF")
2943    (set_attr "length"   "4")])
2946 (define_insn "floatsisf2"
2947   [(set (match_operand:SF 0 "register_operand" "=f")
2948         (float:SF (match_operand:SI 1 "register_operand" "f")))]
2949   "TARGET_HARD_FLOAT"
2950   "cvt.s.w\t%0,%1"
2951   [(set_attr "type"     "fcvt")
2952    (set_attr "mode"     "SF")
2953    (set_attr "length"   "4")])
2956 (define_insn "floatdisf2"
2957   [(set (match_operand:SF 0 "register_operand" "=f")
2958         (float:SF (match_operand:DI 1 "register_operand" "f")))]
2959   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2960   "cvt.s.l\t%0,%1"
2961   [(set_attr "type"     "fcvt")
2962    (set_attr "mode"     "SF")
2963    (set_attr "length"   "4")])
2966 (define_expand "fixuns_truncdfsi2"
2967   [(set (match_operand:SI 0 "register_operand")
2968         (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2969   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2971   rtx reg1 = gen_reg_rtx (DFmode);
2972   rtx reg2 = gen_reg_rtx (DFmode);
2973   rtx reg3 = gen_reg_rtx (SImode);
2974   rtx label1 = gen_label_rtx ();
2975   rtx label2 = gen_label_rtx ();
2976   REAL_VALUE_TYPE offset;
2978   real_2expN (&offset, 31);
2980   if (reg1)                     /* Turn off complaints about unreached code.  */
2981     {
2982       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2983       do_pending_stack_adjust ();
2985       emit_insn (gen_cmpdf (operands[1], reg1));
2986       emit_jump_insn (gen_bge (label1));
2988       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2989       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2990                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
2991       emit_barrier ();
2993       emit_label (label1);
2994       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2995       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2996                                      (BITMASK_HIGH, SImode)));
2998       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2999       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3001       emit_label (label2);
3003       /* Allow REG_NOTES to be set on last insn (labels don't have enough
3004          fields, and can't be used for REG_NOTES anyway).  */
3005       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3006       DONE;
3007     }
3011 (define_expand "fixuns_truncdfdi2"
3012   [(set (match_operand:DI 0 "register_operand")
3013         (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3014   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3016   rtx reg1 = gen_reg_rtx (DFmode);
3017   rtx reg2 = gen_reg_rtx (DFmode);
3018   rtx reg3 = gen_reg_rtx (DImode);
3019   rtx label1 = gen_label_rtx ();
3020   rtx label2 = gen_label_rtx ();
3021   REAL_VALUE_TYPE offset;
3023   real_2expN (&offset, 63);
3025   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3026   do_pending_stack_adjust ();
3028   emit_insn (gen_cmpdf (operands[1], reg1));
3029   emit_jump_insn (gen_bge (label1));
3031   emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3032   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3033                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3034   emit_barrier ();
3036   emit_label (label1);
3037   emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3038   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3039   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3041   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3042   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3044   emit_label (label2);
3046   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3047      fields, and can't be used for REG_NOTES anyway).  */
3048   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3049   DONE;
3053 (define_expand "fixuns_truncsfsi2"
3054   [(set (match_operand:SI 0 "register_operand")
3055         (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3056   "TARGET_HARD_FLOAT"
3058   rtx reg1 = gen_reg_rtx (SFmode);
3059   rtx reg2 = gen_reg_rtx (SFmode);
3060   rtx reg3 = gen_reg_rtx (SImode);
3061   rtx label1 = gen_label_rtx ();
3062   rtx label2 = gen_label_rtx ();
3063   REAL_VALUE_TYPE offset;
3065   real_2expN (&offset, 31);
3067   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3068   do_pending_stack_adjust ();
3070   emit_insn (gen_cmpsf (operands[1], reg1));
3071   emit_jump_insn (gen_bge (label1));
3073   emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3074   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3075                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3076   emit_barrier ();
3078   emit_label (label1);
3079   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3080   emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3081                                  (BITMASK_HIGH, SImode)));
3083   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3084   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3086   emit_label (label2);
3088   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3089      fields, and can't be used for REG_NOTES anyway).  */
3090   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3091   DONE;
3095 (define_expand "fixuns_truncsfdi2"
3096   [(set (match_operand:DI 0 "register_operand")
3097         (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3098   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3100   rtx reg1 = gen_reg_rtx (SFmode);
3101   rtx reg2 = gen_reg_rtx (SFmode);
3102   rtx reg3 = gen_reg_rtx (DImode);
3103   rtx label1 = gen_label_rtx ();
3104   rtx label2 = gen_label_rtx ();
3105   REAL_VALUE_TYPE offset;
3107   real_2expN (&offset, 63);
3109   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3110   do_pending_stack_adjust ();
3112   emit_insn (gen_cmpsf (operands[1], reg1));
3113   emit_jump_insn (gen_bge (label1));
3115   emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3116   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3117                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3118   emit_barrier ();
3120   emit_label (label1);
3121   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3122   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3123   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3125   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3126   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3128   emit_label (label2);
3130   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3131      fields, and can't be used for REG_NOTES anyway).  */
3132   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3133   DONE;
3137 ;;  ....................
3139 ;;      DATA MOVEMENT
3141 ;;  ....................
3143 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3145 (define_expand "extv"
3146   [(set (match_operand 0 "register_operand")
3147         (sign_extract (match_operand:QI 1 "memory_operand")
3148                       (match_operand 2 "immediate_operand")
3149                       (match_operand 3 "immediate_operand")))]
3150   "!TARGET_MIPS16"
3152   if (mips_expand_unaligned_load (operands[0], operands[1],
3153                                   INTVAL (operands[2]),
3154                                   INTVAL (operands[3])))
3155     DONE;
3156   else
3157     FAIL;
3160 (define_expand "extzv"
3161   [(set (match_operand 0 "register_operand")
3162         (zero_extract (match_operand:QI 1 "memory_operand")
3163                       (match_operand 2 "immediate_operand")
3164                       (match_operand 3 "immediate_operand")))]
3165   "!TARGET_MIPS16"
3167   if (mips_expand_unaligned_load (operands[0], operands[1],
3168                                   INTVAL (operands[2]),
3169                                   INTVAL (operands[3])))
3170     DONE;
3171   else
3172     FAIL;
3175 (define_expand "insv"
3176   [(set (zero_extract (match_operand:QI 0 "memory_operand")
3177                       (match_operand 1 "immediate_operand")
3178                       (match_operand 2 "immediate_operand"))
3179         (match_operand 3 "reg_or_0_operand"))]
3180   "!TARGET_MIPS16"
3182   if (mips_expand_unaligned_store (operands[0], operands[3],
3183                                    INTVAL (operands[1]),
3184                                    INTVAL (operands[2])))
3185     DONE;
3186   else
3187     FAIL;
3190 ;; Unaligned word moves generated by the bit field patterns.
3192 ;; As far as the rtl is concerned, both the left-part and right-part
3193 ;; instructions can access the whole field.  However, the real operand
3194 ;; refers to just the first or the last byte (depending on endianness).
3195 ;; We therefore use two memory operands to each instruction, one to
3196 ;; describe the rtl effect and one to use in the assembly output.
3198 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3199 ;; This allows us to use the standard length calculations for the "load"
3200 ;; and "store" type attributes.
3202 (define_insn "mov_<load>l"
3203   [(set (match_operand:GPR 0 "register_operand" "=d")
3204         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3205                      (match_operand:QI 2 "memory_operand" "m")]
3206                     UNSPEC_LOAD_LEFT))]
3207   "!TARGET_MIPS16"
3208   "<load>l\t%0,%2"
3209   [(set_attr "type" "load")
3210    (set_attr "mode" "<MODE>")
3211    (set_attr "hazard" "none")])
3213 (define_insn "mov_<load>r"
3214   [(set (match_operand:GPR 0 "register_operand" "=d")
3215         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3216                      (match_operand:QI 2 "memory_operand" "m")
3217                      (match_operand:GPR 3 "register_operand" "0")]
3218                     UNSPEC_LOAD_RIGHT))]
3219   "!TARGET_MIPS16"
3220   "<load>r\t%0,%2"
3221   [(set_attr "type" "load")
3222    (set_attr "mode" "<MODE>")])
3224 (define_insn "mov_<store>l"
3225   [(set (match_operand:BLK 0 "memory_operand" "=m")
3226         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3227                      (match_operand:QI 2 "memory_operand" "m")]
3228                     UNSPEC_STORE_LEFT))]
3229   "!TARGET_MIPS16"
3230   "<store>l\t%z1,%2"
3231   [(set_attr "type" "store")
3232    (set_attr "mode" "<MODE>")])
3234 (define_insn "mov_<store>r"
3235   [(set (match_operand:BLK 0 "memory_operand" "+m")
3236         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3237                      (match_operand:QI 2 "memory_operand" "m")
3238                      (match_dup 0)]
3239                     UNSPEC_STORE_RIGHT))]
3240   "!TARGET_MIPS16"
3241   "<store>r\t%z1,%2"
3242   [(set_attr "type" "store")
3243    (set_attr "mode" "<MODE>")])
3245 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3246 ;; The required value is:
3248 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3250 ;; which translates to:
3252 ;;      lui     op0,%highest(op1)
3253 ;;      daddiu  op0,op0,%higher(op1)
3254 ;;      dsll    op0,op0,16
3255 ;;      daddiu  op0,op0,%hi(op1)
3256 ;;      dsll    op0,op0,16
3257 (define_insn_and_split "*lea_high64"
3258   [(set (match_operand:DI 0 "register_operand" "=d")
3259         (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3260   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3261   "#"
3262   "&& reload_completed"
3263   [(set (match_dup 0) (high:DI (match_dup 2)))
3264    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3265    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3266    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3267    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3269   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3270   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3272   [(set_attr "length" "20")])
3274 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3275 ;; SYMBOL_GENERAL X will take 6 cycles.  This next pattern allows combine
3276 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3277 ;; used once.  We can then use the sequence:
3279 ;;      lui     op0,%highest(op1)
3280 ;;      lui     op2,%hi(op1)
3281 ;;      daddiu  op0,op0,%higher(op1)
3282 ;;      daddiu  op2,op2,%lo(op1)
3283 ;;      dsll32  op0,op0,0
3284 ;;      daddu   op0,op0,op2
3286 ;; which takes 4 cycles on most superscalar targets.
3287 (define_insn_and_split "*lea64"
3288   [(set (match_operand:DI 0 "register_operand" "=d")
3289         (match_operand:DI 1 "general_symbolic_operand" ""))
3290    (clobber (match_scratch:DI 2 "=&d"))]
3291   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3292   "#"
3293   "&& reload_completed"
3294   [(set (match_dup 0) (high:DI (match_dup 3)))
3295    (set (match_dup 2) (high:DI (match_dup 4)))
3296    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3297    (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3298    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3299    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3301   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3302   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3304   [(set_attr "length" "24")])
3306 ;; Insns to fetch a global symbol from a big GOT.
3308 (define_insn_and_split "*xgot_hi<mode>"
3309   [(set (match_operand:P 0 "register_operand" "=d")
3310         (high:P (match_operand:P 1 "global_got_operand" "")))]
3311   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3312   "#"
3313   "&& reload_completed"
3314   [(set (match_dup 0) (high:P (match_dup 2)))
3315    (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3317   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3318   operands[3] = pic_offset_table_rtx;
3320   [(set_attr "got" "xgot_high")
3321    (set_attr "mode" "<MODE>")])
3323 (define_insn_and_split "*xgot_lo<mode>"
3324   [(set (match_operand:P 0 "register_operand" "=d")
3325         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3326                   (match_operand:P 2 "global_got_operand" "")))]
3327   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3328   "#"
3329   "&& reload_completed"
3330   [(set (match_dup 0)
3331         (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3332   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3333   [(set_attr "got" "load")
3334    (set_attr "mode" "<MODE>")])
3336 ;; Insns to fetch a global symbol from a normal GOT.
3338 (define_insn_and_split "*got_disp<mode>"
3339   [(set (match_operand:P 0 "register_operand" "=d")
3340         (match_operand:P 1 "global_got_operand" ""))]
3341   "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3342   "#"
3343   "&& reload_completed"
3344   [(set (match_dup 0)
3345         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3347   operands[2] = pic_offset_table_rtx;
3348   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3350   [(set_attr "got" "load")
3351    (set_attr "mode" "<MODE>")])
3353 ;; Insns for loading the high part of a local symbol.
3355 (define_insn_and_split "*got_page<mode>"
3356   [(set (match_operand:P 0 "register_operand" "=d")
3357         (high:P (match_operand:P 1 "local_got_operand" "")))]
3358   "TARGET_EXPLICIT_RELOCS"
3359   "#"
3360   "&& reload_completed"
3361   [(set (match_dup 0)
3362         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3364   operands[2] = pic_offset_table_rtx;
3365   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3367   [(set_attr "got" "load")
3368    (set_attr "mode" "<MODE>")])
3370 ;; Lower-level instructions for loading an address from the GOT.
3371 ;; We could use MEMs, but an unspec gives more optimization
3372 ;; opportunities.
3374 (define_insn "*load_got<mode>"
3375   [(set (match_operand:P 0 "register_operand" "=d")
3376         (unspec:P [(match_operand:P 1 "register_operand" "d")
3377                    (match_operand:P 2 "immediate_operand" "")]
3378                   UNSPEC_LOAD_GOT))]
3379   "TARGET_ABICALLS"
3380   "<load>\t%0,%R2(%1)"
3381   [(set_attr "type" "load")
3382    (set_attr "mode" "<MODE>")
3383    (set_attr "length" "4")])
3385 ;; Instructions for adding the low 16 bits of an address to a register.
3386 ;; Operand 2 is the address: print_operand works out which relocation
3387 ;; should be applied.
3389 (define_insn "*low<mode>"
3390   [(set (match_operand:P 0 "register_operand" "=d")
3391         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3392                   (match_operand:P 2 "immediate_operand" "")))]
3393   "!TARGET_MIPS16"
3394   "<d>addiu\t%0,%1,%R2"
3395   [(set_attr "type" "arith")
3396    (set_attr "mode" "<MODE>")])
3398 (define_insn "*low<mode>_mips16"
3399   [(set (match_operand:P 0 "register_operand" "=d")
3400         (lo_sum:P (match_operand:P 1 "register_operand" "0")
3401                   (match_operand:P 2 "immediate_operand" "")))]
3402   "TARGET_MIPS16"
3403   "<d>addiu\t%0,%R2"
3404   [(set_attr "type" "arith")
3405    (set_attr "mode" "<MODE>")
3406    (set_attr "length" "8")])
3408 ;; 64-bit integer moves
3410 ;; Unlike most other insns, the move insns can't be split with
3411 ;; different predicates, because register spilling and other parts of
3412 ;; the compiler, have memoized the insn number already.
3414 (define_expand "movdi"
3415   [(set (match_operand:DI 0 "")
3416         (match_operand:DI 1 ""))]
3417   ""
3419   if (mips_legitimize_move (DImode, operands[0], operands[1]))
3420     DONE;
3423 ;; For mips16, we need a special case to handle storing $31 into
3424 ;; memory, since we don't have a constraint to match $31.  This
3425 ;; instruction can be generated by save_restore_insns.
3427 (define_insn "*mov<mode>_ra"
3428   [(set (match_operand:GPR 0 "stack_operand" "=m")
3429         (reg:GPR 31))]
3430   "TARGET_MIPS16"
3431   "<store>\t$31,%0"
3432   [(set_attr "type" "store")
3433    (set_attr "mode" "<MODE>")])
3435 (define_insn "*movdi_32bit"
3436   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
3437         (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
3438   "!TARGET_64BIT && !TARGET_MIPS16
3439    && (register_operand (operands[0], DImode)
3440        || reg_or_0_operand (operands[1], DImode))"
3441   { return mips_output_move (operands[0], operands[1]); }
3442   [(set_attr "type"     "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
3443    (set_attr "mode"     "DI")
3444    (set_attr "length"   "8,16,*,*,8,8,8,*,8,*")])
3446 (define_insn "*movdi_32bit_mips16"
3447   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3448         (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3449   "!TARGET_64BIT && TARGET_MIPS16
3450    && (register_operand (operands[0], DImode)
3451        || register_operand (operands[1], DImode))"
3452   { return mips_output_move (operands[0], operands[1]); }
3453   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store,mfhilo")
3454    (set_attr "mode"     "DI")
3455    (set_attr "length"   "8,8,8,8,12,*,*,8")])
3457 (define_insn "*movdi_64bit"
3458   [(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")
3459         (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"))]
3460   "TARGET_64BIT && !TARGET_MIPS16
3461    && (register_operand (operands[0], DImode)
3462        || reg_or_0_operand (operands[1], DImode))"
3463   { return mips_output_move (operands[0], operands[1]); }
3464   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
3465    (set_attr "mode"     "DI")
3466    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3468 (define_insn "*movdi_64bit_mips16"
3469   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3470         (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3471   "TARGET_64BIT && TARGET_MIPS16
3472    && (register_operand (operands[0], DImode)
3473        || register_operand (operands[1], DImode))"
3474   { return mips_output_move (operands[0], operands[1]); }
3475   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
3476    (set_attr "mode"     "DI")
3477    (set_attr_alternative "length"
3478                 [(const_int 4)
3479                  (const_int 4)
3480                  (const_int 4)
3481                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3482                                (const_int 4)
3483                                (const_int 8))
3484                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3485                                (const_int 8)
3486                                (const_int 12))
3487                  (const_string "*")
3488                  (const_string "*")
3489                  (const_string "*")])])
3492 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
3493 ;; when the original load is a 4 byte instruction but the add and the
3494 ;; load are 2 2 byte instructions.
3496 (define_split
3497   [(set (match_operand:DI 0 "register_operand")
3498         (mem:DI (plus:DI (match_dup 0)
3499                          (match_operand:DI 1 "const_int_operand"))))]
3500   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3501    && !TARGET_DEBUG_D_MODE
3502    && GET_CODE (operands[0]) == REG
3503    && M16_REG_P (REGNO (operands[0]))
3504    && GET_CODE (operands[1]) == CONST_INT
3505    && ((INTVAL (operands[1]) < 0
3506         && INTVAL (operands[1]) >= -0x10)
3507        || (INTVAL (operands[1]) >= 32 * 8
3508            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3509        || (INTVAL (operands[1]) >= 0
3510            && INTVAL (operands[1]) < 32 * 8
3511            && (INTVAL (operands[1]) & 7) != 0))"
3512   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3513    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3515   HOST_WIDE_INT val = INTVAL (operands[1]);
3517   if (val < 0)
3518     operands[2] = const0_rtx;
3519   else if (val >= 32 * 8)
3520     {
3521       int off = val & 7;
3523       operands[1] = GEN_INT (0x8 + off);
3524       operands[2] = GEN_INT (val - off - 0x8);
3525     }
3526   else
3527     {
3528       int off = val & 7;
3530       operands[1] = GEN_INT (off);
3531       operands[2] = GEN_INT (val - off);
3532     }
3535 ;; 32-bit Integer moves
3537 ;; Unlike most other insns, the move insns can't be split with
3538 ;; different predicates, because register spilling and other parts of
3539 ;; the compiler, have memoized the insn number already.
3541 (define_expand "movsi"
3542   [(set (match_operand:SI 0 "")
3543         (match_operand:SI 1 ""))]
3544   ""
3546   if (mips_legitimize_move (SImode, operands[0], operands[1]))
3547     DONE;
3550 ;; The difference between these two is whether or not ints are allowed
3551 ;; in FP registers (off by default, use -mdebugh to enable).
3553 (define_insn "*movsi_internal"
3554   [(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")
3555         (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"))]
3556   "!TARGET_MIPS16
3557    && (register_operand (operands[0], SImode)
3558        || reg_or_0_operand (operands[1], SImode))"
3559   { return mips_output_move (operands[0], operands[1]); }
3560   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
3561    (set_attr "mode"     "SI")
3562    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
3564 (define_insn "*movsi_mips16"
3565   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3566         (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3567   "TARGET_MIPS16
3568    && (register_operand (operands[0], SImode)
3569        || register_operand (operands[1], SImode))"
3570   { return mips_output_move (operands[0], operands[1]); }
3571   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
3572    (set_attr "mode"     "SI")
3573    (set_attr_alternative "length"
3574                 [(const_int 4)
3575                  (const_int 4)
3576                  (const_int 4)
3577                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3578                                (const_int 4)
3579                                (const_int 8))
3580                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3581                                (const_int 8)
3582                                (const_int 12))
3583                  (const_string "*")
3584                  (const_string "*")
3585                  (const_string "*")])])
3587 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
3588 ;; when the original load is a 4 byte instruction but the add and the
3589 ;; load are 2 2 byte instructions.
3591 (define_split
3592   [(set (match_operand:SI 0 "register_operand")
3593         (mem:SI (plus:SI (match_dup 0)
3594                          (match_operand:SI 1 "const_int_operand"))))]
3595   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3596    && GET_CODE (operands[0]) == REG
3597    && M16_REG_P (REGNO (operands[0]))
3598    && GET_CODE (operands[1]) == CONST_INT
3599    && ((INTVAL (operands[1]) < 0
3600         && INTVAL (operands[1]) >= -0x80)
3601        || (INTVAL (operands[1]) >= 32 * 4
3602            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3603        || (INTVAL (operands[1]) >= 0
3604            && INTVAL (operands[1]) < 32 * 4
3605            && (INTVAL (operands[1]) & 3) != 0))"
3606   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3607    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3609   HOST_WIDE_INT val = INTVAL (operands[1]);
3611   if (val < 0)
3612     operands[2] = const0_rtx;
3613   else if (val >= 32 * 4)
3614     {
3615       int off = val & 3;
3617       operands[1] = GEN_INT (0x7c + off);
3618       operands[2] = GEN_INT (val - off - 0x7c);
3619     }
3620   else
3621     {
3622       int off = val & 3;
3624       operands[1] = GEN_INT (off);
3625       operands[2] = GEN_INT (val - off);
3626     }
3629 ;; On the mips16, we can split a load of certain constants into a load
3630 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
3631 ;; instructions.
3633 (define_split
3634   [(set (match_operand:SI 0 "register_operand")
3635         (match_operand:SI 1 "const_int_operand"))]
3636   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3637    && GET_CODE (operands[0]) == REG
3638    && M16_REG_P (REGNO (operands[0]))
3639    && GET_CODE (operands[1]) == CONST_INT
3640    && INTVAL (operands[1]) >= 0x100
3641    && INTVAL (operands[1]) <= 0xff + 0x7f"
3642   [(set (match_dup 0) (match_dup 1))
3643    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3645   int val = INTVAL (operands[1]);
3647   operands[1] = GEN_INT (0xff);
3648   operands[2] = GEN_INT (val - 0xff);
3651 ;; This insn handles moving CCmode values.  It's really just a
3652 ;; slightly simplified copy of movsi_internal2, with additional cases
3653 ;; to move a condition register to a general register and to move
3654 ;; between the general registers and the floating point registers.
3656 (define_insn "movcc"
3657   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3658         (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3659   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3660   { return mips_output_move (operands[0], operands[1]); }
3661   [(set_attr "type"     "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
3662    (set_attr "mode"     "SI")
3663    (set_attr "length"   "8,4,*,*,4,4,4,*,*")])
3665 ;; Reload condition code registers.  reload_incc and reload_outcc
3666 ;; both handle moves from arbitrary operands into condition code
3667 ;; registers.  reload_incc handles the more common case in which
3668 ;; a source operand is constrained to be in a condition-code
3669 ;; register, but has not been allocated to one.
3671 ;; Sometimes, such as in movcc, we have a CCmode destination whose
3672 ;; constraints do not include 'z'.  reload_outcc handles the case
3673 ;; when such an operand is allocated to a condition-code register.
3675 ;; Note that reloads from a condition code register to some
3676 ;; other location can be done using ordinary moves.  Moving
3677 ;; into a GPR takes a single movcc, moving elsewhere takes
3678 ;; two.  We can leave these cases to the generic reload code.
3679 (define_expand "reload_incc"
3680   [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3681         (match_operand:CC 1 "general_operand" ""))
3682    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3683   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3685   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3686   DONE;
3689 (define_expand "reload_outcc"
3690   [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3691         (match_operand:CC 1 "register_operand" ""))
3692    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3693   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3695   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3696   DONE;
3699 ;; MIPS4 supports loading and storing a floating point register from
3700 ;; the sum of two general registers.  We use two versions for each of
3701 ;; these four instructions: one where the two general registers are
3702 ;; SImode, and one where they are DImode.  This is because general
3703 ;; registers will be in SImode when they hold 32 bit values, but,
3704 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
3705 ;; instructions will still work correctly.
3707 ;; ??? Perhaps it would be better to support these instructions by
3708 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
3709 ;; these instructions can only be used to load and store floating
3710 ;; point registers, that would probably cause trouble in reload.
3712 (define_insn "*lwxc1_<mode>"
3713   [(set (match_operand:SF 0 "register_operand" "=f")
3714         (mem:SF (plus:P (match_operand:P 1 "register_operand" "d")
3715                         (match_operand:P 2 "register_operand" "d"))))]
3716   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
3717   "lwxc1\t%0,%1(%2)"
3718   [(set_attr "type" "fpidxload")
3719    (set_attr "mode" "SF")])
3721 (define_insn "*ldxc1_<mode>"
3722   [(set (match_operand:DF 0 "register_operand" "=f")
3723         (mem:DF (plus:P (match_operand:P 1 "register_operand" "d")
3724                         (match_operand:P 2 "register_operand" "d"))))]
3725   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3726   "ldxc1\t%0,%1(%2)"
3727   [(set_attr "type" "fpidxload")
3728    (set_attr "mode" "DF")])
3730 (define_insn "*swxc1_<mode>"
3731   [(set (mem:SF (plus:P (match_operand:P 1 "register_operand" "d")
3732                         (match_operand:P 2 "register_operand" "d")))
3733         (match_operand:SF 0 "register_operand" "f"))]
3734   "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
3735   "swxc1\t%0,%1(%2)"
3736   [(set_attr "type" "fpidxstore")
3737    (set_attr "mode" "SF")])
3739 (define_insn "*sdxc1_<mode>"
3740   [(set (mem:DF (plus:P (match_operand:P 1 "register_operand" "d")
3741                         (match_operand:P 2 "register_operand" "d")))
3742         (match_operand:DF 0 "register_operand" "f"))]
3743   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3744   "sdxc1\t%0,%1(%2)"
3745   [(set_attr "type" "fpidxstore")
3746    (set_attr "mode" "DF")])
3748 ;; 16-bit Integer moves
3750 ;; Unlike most other insns, the move insns can't be split with
3751 ;; different predicates, because register spilling and other parts of
3752 ;; the compiler, have memoized the insn number already.
3753 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3755 (define_expand "movhi"
3756   [(set (match_operand:HI 0 "")
3757         (match_operand:HI 1 ""))]
3758   ""
3760   if (mips_legitimize_move (HImode, operands[0], operands[1]))
3761     DONE;
3764 (define_insn "*movhi_internal"
3765   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3766         (match_operand:HI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3767   "!TARGET_MIPS16
3768    && (register_operand (operands[0], HImode)
3769        || reg_or_0_operand (operands[1], HImode))"
3770   "@
3771     move\t%0,%1
3772     li\t%0,%1
3773     lhu\t%0,%1
3774     sh\t%z1,%0
3775     mfc1\t%0,%1
3776     mtc1\t%1,%0
3777     mov.s\t%0,%1
3778     mt%0\t%1"
3779   [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3780    (set_attr "mode"     "HI")
3781    (set_attr "length"   "4,4,*,*,4,4,4,4")])
3783 (define_insn "*movhi_mips16"
3784   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3785         (match_operand:HI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3786   "TARGET_MIPS16
3787    && (register_operand (operands[0], HImode)
3788        || register_operand (operands[1], HImode))"
3789   "@
3790     move\t%0,%1
3791     move\t%0,%1
3792     move\t%0,%1
3793     li\t%0,%1
3794     #
3795     lhu\t%0,%1
3796     sh\t%1,%0"
3797   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
3798    (set_attr "mode"     "HI")
3799    (set_attr_alternative "length"
3800                 [(const_int 4)
3801                  (const_int 4)
3802                  (const_int 4)
3803                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3804                                (const_int 4)
3805                                (const_int 8))
3806                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3807                                (const_int 8)
3808                                (const_int 12))
3809                  (const_string "*")
3810                  (const_string "*")])])
3813 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
3814 ;; when the original load is a 4 byte instruction but the add and the
3815 ;; load are 2 2 byte instructions.
3817 (define_split
3818   [(set (match_operand:HI 0 "register_operand")
3819         (mem:HI (plus:SI (match_dup 0)
3820                          (match_operand:SI 1 "const_int_operand"))))]
3821   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3822    && GET_CODE (operands[0]) == REG
3823    && M16_REG_P (REGNO (operands[0]))
3824    && GET_CODE (operands[1]) == CONST_INT
3825    && ((INTVAL (operands[1]) < 0
3826         && INTVAL (operands[1]) >= -0x80)
3827        || (INTVAL (operands[1]) >= 32 * 2
3828            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
3829        || (INTVAL (operands[1]) >= 0
3830            && INTVAL (operands[1]) < 32 * 2
3831            && (INTVAL (operands[1]) & 1) != 0))"
3832   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3833    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
3835   HOST_WIDE_INT val = INTVAL (operands[1]);
3837   if (val < 0)
3838     operands[2] = const0_rtx;
3839   else if (val >= 32 * 2)
3840     {
3841       int off = val & 1;
3843       operands[1] = GEN_INT (0x7e + off);
3844       operands[2] = GEN_INT (val - off - 0x7e);
3845     }
3846   else
3847     {
3848       int off = val & 1;
3850       operands[1] = GEN_INT (off);
3851       operands[2] = GEN_INT (val - off);
3852     }
3855 ;; 8-bit Integer moves
3857 ;; Unlike most other insns, the move insns can't be split with
3858 ;; different predicates, because register spilling and other parts of
3859 ;; the compiler, have memoized the insn number already.
3860 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3862 (define_expand "movqi"
3863   [(set (match_operand:QI 0 "")
3864         (match_operand:QI 1 ""))]
3865   ""
3867   if (mips_legitimize_move (QImode, operands[0], operands[1]))
3868     DONE;
3871 (define_insn "*movqi_internal"
3872   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3873         (match_operand:QI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3874   "!TARGET_MIPS16
3875    && (register_operand (operands[0], QImode)
3876        || reg_or_0_operand (operands[1], QImode))"
3877   "@
3878     move\t%0,%1
3879     li\t%0,%1
3880     lbu\t%0,%1
3881     sb\t%z1,%0
3882     mfc1\t%0,%1
3883     mtc1\t%1,%0
3884     mov.s\t%0,%1
3885     mt%0\t%1"
3886   [(set_attr "type"     "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3887    (set_attr "mode"     "QI")
3888    (set_attr "length"   "4,4,*,*,4,4,4,4")])
3890 (define_insn "*movqi_mips16"
3891   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3892         (match_operand:QI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3893   "TARGET_MIPS16
3894    && (register_operand (operands[0], QImode)
3895        || register_operand (operands[1], QImode))"
3896   "@
3897     move\t%0,%1
3898     move\t%0,%1
3899     move\t%0,%1
3900     li\t%0,%1
3901     #
3902     lbu\t%0,%1
3903     sb\t%1,%0"
3904   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store")
3905    (set_attr "mode"     "QI")
3906    (set_attr "length"   "4,4,4,4,8,*,*")])
3908 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
3909 ;; when the original load is a 4 byte instruction but the add and the
3910 ;; load are 2 2 byte instructions.
3912 (define_split
3913   [(set (match_operand:QI 0 "register_operand")
3914         (mem:QI (plus:SI (match_dup 0)
3915                          (match_operand:SI 1 "const_int_operand"))))]
3916   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3917    && GET_CODE (operands[0]) == REG
3918    && M16_REG_P (REGNO (operands[0]))
3919    && GET_CODE (operands[1]) == CONST_INT
3920    && ((INTVAL (operands[1]) < 0
3921         && INTVAL (operands[1]) >= -0x80)
3922        || (INTVAL (operands[1]) >= 32
3923            && INTVAL (operands[1]) <= 31 + 0x7f))"
3924   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3925    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
3927   HOST_WIDE_INT val = INTVAL (operands[1]);
3929   if (val < 0)
3930     operands[2] = const0_rtx;
3931   else
3932     {
3933       operands[1] = GEN_INT (0x7f);
3934       operands[2] = GEN_INT (val - 0x7f);
3935     }
3938 ;; 32-bit floating point moves
3940 (define_expand "movsf"
3941   [(set (match_operand:SF 0 "")
3942         (match_operand:SF 1 ""))]
3943   ""
3945   if (mips_legitimize_move (SFmode, operands[0], operands[1]))
3946     DONE;
3949 (define_insn "*movsf_hardfloat"
3950   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
3951         (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
3952   "TARGET_HARD_FLOAT
3953    && (register_operand (operands[0], SFmode)
3954        || reg_or_0_operand (operands[1], SFmode))"
3955   { return mips_output_move (operands[0], operands[1]); }
3956   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
3957    (set_attr "mode"     "SF")
3958    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
3960 (define_insn "*movsf_softfloat"
3961   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
3962         (match_operand:SF 1 "move_operand" "Gd,m,d"))]
3963   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
3964    && (register_operand (operands[0], SFmode)
3965        || reg_or_0_operand (operands[1], SFmode))"
3966   { return mips_output_move (operands[0], operands[1]); }
3967   [(set_attr "type"     "arith,load,store")
3968    (set_attr "mode"     "SF")
3969    (set_attr "length"   "4,*,*")])
3971 (define_insn "*movsf_mips16"
3972   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
3973         (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
3974   "TARGET_MIPS16
3975    && (register_operand (operands[0], SFmode)
3976        || register_operand (operands[1], SFmode))"
3977   { return mips_output_move (operands[0], operands[1]); }
3978   [(set_attr "type"     "arith,arith,arith,load,store")
3979    (set_attr "mode"     "SF")
3980    (set_attr "length"   "4,4,4,*,*")])
3983 ;; 64-bit floating point moves
3985 (define_expand "movdf"
3986   [(set (match_operand:DF 0 "")
3987         (match_operand:DF 1 ""))]
3988   ""
3990   if (mips_legitimize_move (DFmode, operands[0], operands[1]))
3991     DONE;
3994 (define_insn "*movdf_hardfloat_64bit"
3995   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
3996         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
3997   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
3998    && (register_operand (operands[0], DFmode)
3999        || reg_or_0_operand (operands[1], DFmode))"
4000   { return mips_output_move (operands[0], operands[1]); }
4001   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4002    (set_attr "mode"     "DF")
4003    (set_attr "length"   "4,4,*,*,4,4,4,*,*")])
4005 (define_insn "*movdf_hardfloat_32bit"
4006   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4007         (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4008   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
4009    && (register_operand (operands[0], DFmode)
4010        || reg_or_0_operand (operands[1], DFmode))"
4011   { return mips_output_move (operands[0], operands[1]); }
4012   [(set_attr "type"     "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4013    (set_attr "mode"     "DF")
4014    (set_attr "length"   "4,8,*,*,8,8,8,*,*")])
4016 (define_insn "*movdf_softfloat"
4017   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
4018         (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
4019   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4020    && (register_operand (operands[0], DFmode)
4021        || reg_or_0_operand (operands[1], DFmode))"
4022   { return mips_output_move (operands[0], operands[1]); }
4023   [(set_attr "type"     "arith,load,store,xfer,xfer,fmove")
4024    (set_attr "mode"     "DF")
4025    (set_attr "length"   "8,*,*,4,4,4")])
4027 (define_insn "*movdf_mips16"
4028   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4029         (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4030   "TARGET_MIPS16
4031    && (register_operand (operands[0], DFmode)
4032        || register_operand (operands[1], DFmode))"
4033   { return mips_output_move (operands[0], operands[1]); }
4034   [(set_attr "type"     "arith,arith,arith,load,store")
4035    (set_attr "mode"     "DF")
4036    (set_attr "length"   "8,8,8,*,*")])
4038 (define_split
4039   [(set (match_operand:DI 0 "nonimmediate_operand")
4040         (match_operand:DI 1 "move_operand"))]
4041   "reload_completed && !TARGET_64BIT
4042    && mips_split_64bit_move_p (operands[0], operands[1])"
4043   [(const_int 0)]
4045   mips_split_64bit_move (operands[0], operands[1]);
4046   DONE;
4049 (define_split
4050   [(set (match_operand:DF 0 "nonimmediate_operand")
4051         (match_operand:DF 1 "move_operand"))]
4052   "reload_completed && !TARGET_64BIT
4053    && mips_split_64bit_move_p (operands[0], operands[1])"
4054   [(const_int 0)]
4056   mips_split_64bit_move (operands[0], operands[1]);
4057   DONE;
4060 ;; When generating mips16 code, split moves of negative constants into
4061 ;; a positive "li" followed by a negation.
4062 (define_split
4063   [(set (match_operand 0 "register_operand")
4064         (match_operand 1 "const_int_operand"))]
4065   "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4066   [(set (match_dup 2)
4067         (match_dup 3))
4068    (set (match_dup 2)
4069         (neg:SI (match_dup 2)))]
4071   operands[2] = gen_lowpart (SImode, operands[0]);
4072   operands[3] = GEN_INT (-INTVAL (operands[1]));
4075 ;; The HI and LO registers are not truly independent.  If we move an mthi
4076 ;; instruction before an mflo instruction, it will make the result of the
4077 ;; mflo unpredictable.  The same goes for mtlo and mfhi.
4079 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4080 ;; Operand 1 is the register we want, operand 2 is the other one.
4082 (define_insn "mfhilo_<mode>"
4083   [(set (match_operand:GPR 0 "register_operand" "=d,d")
4084         (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
4085                      (match_operand:GPR 2 "register_operand" "l,h")]
4086                     UNSPEC_MFHILO))]
4087   ""
4088   "mf%1\t%0"
4089   [(set_attr "type" "mfhilo")
4090    (set_attr "mode" "<MODE>")])
4092 ;; Patterns for loading or storing part of a paired floating point
4093 ;; register.  We need them because odd-numbered floating-point registers
4094 ;; are not fully independent: see mips_split_64bit_move.
4096 ;; Load the low word of operand 0 with operand 1.
4097 (define_insn "load_df_low"
4098   [(set (match_operand:DF 0 "register_operand" "=f,f")
4099         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
4100                    UNSPEC_LOAD_DF_LOW))]
4101   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4103   operands[0] = mips_subword (operands[0], 0);
4104   return mips_output_move (operands[0], operands[1]);
4106   [(set_attr "type"     "xfer,fpload")
4107    (set_attr "mode"     "SF")])
4109 ;; Load the high word of operand 0 from operand 1, preserving the value
4110 ;; in the low word.
4111 (define_insn "load_df_high"
4112   [(set (match_operand:DF 0 "register_operand" "=f,f")
4113         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
4114                     (match_operand:DF 2 "register_operand" "0,0")]
4115                    UNSPEC_LOAD_DF_HIGH))]
4116   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4118   operands[0] = mips_subword (operands[0], 1);
4119   return mips_output_move (operands[0], operands[1]);
4121   [(set_attr "type"     "xfer,fpload")
4122    (set_attr "mode"     "SF")])
4124 ;; Store the high word of operand 1 in operand 0.  The corresponding
4125 ;; low-word move is done in the normal way.
4126 (define_insn "store_df_high"
4127   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4128         (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4129                    UNSPEC_STORE_DF_HIGH))]
4130   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4132   operands[1] = mips_subword (operands[1], 1);
4133   return mips_output_move (operands[0], operands[1]);
4135   [(set_attr "type"     "xfer,fpstore")
4136    (set_attr "mode"     "SF")])
4138 ;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
4139 ;; of _gp from the start of this function.  Operand 1 is the incoming
4140 ;; function address.
4141 (define_insn_and_split "loadgp"
4142   [(unspec_volatile [(match_operand 0 "" "")
4143                      (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4144   "TARGET_ABICALLS && TARGET_NEWABI"
4145   "#"
4146   ""
4147   [(set (match_dup 2) (match_dup 3))
4148    (set (match_dup 2) (match_dup 4))
4149    (set (match_dup 2) (match_dup 5))]
4151   operands[2] = pic_offset_table_rtx;
4152   operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4153   operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4154   operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4156   [(set_attr "length" "12")])
4158 ;; The use of gp is hidden when not using explicit relocations.
4159 ;; This blockage instruction prevents the gp load from being
4160 ;; scheduled after an implicit use of gp.  It also prevents
4161 ;; the load from being deleted as dead.
4162 (define_insn "loadgp_blockage"
4163   [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4164   ""
4165   ""
4166   [(set_attr "type"     "unknown")
4167    (set_attr "mode"     "none")
4168    (set_attr "length"   "0")])
4170 ;; Emit a .cprestore directive, which normally expands to a single store
4171 ;; instruction.  Note that we continue to use .cprestore for explicit reloc
4172 ;; code so that jals inside inline asms will work correctly.
4173 (define_insn "cprestore"
4174   [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
4175                     UNSPEC_CPRESTORE)]
4176   ""
4178   if (set_nomacro && which_alternative == 1)
4179     return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4180   else
4181     return ".cprestore\t%0";
4183   [(set_attr "type" "store")
4184    (set_attr "length" "4,12")])
4186 ;; Block moves, see mips.c for more details.
4187 ;; Argument 0 is the destination
4188 ;; Argument 1 is the source
4189 ;; Argument 2 is the length
4190 ;; Argument 3 is the alignment
4192 (define_expand "movmemsi"
4193   [(parallel [(set (match_operand:BLK 0 "general_operand")
4194                    (match_operand:BLK 1 "general_operand"))
4195               (use (match_operand:SI 2 ""))
4196               (use (match_operand:SI 3 "const_int_operand"))])]
4197   "!TARGET_MIPS16 && !TARGET_MEMCPY"
4199   if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4200     DONE;
4201   else
4202     FAIL;
4206 ;;  ....................
4208 ;;      SHIFTS
4210 ;;  ....................
4212 ;; Many of these instructions use trivial define_expands, because we
4213 ;; want to use a different set of constraints when TARGET_MIPS16.
4215 (define_expand "ashlsi3"
4216   [(set (match_operand:SI 0 "register_operand")
4217         (ashift:SI (match_operand:SI 1 "register_operand")
4218                    (match_operand:SI 2 "arith_operand")))]
4219   ""
4221   /* On the mips16, a shift of more than 8 is a four byte instruction,
4222      so, for a shift between 8 and 16, it is just as fast to do two
4223      shifts of 8 or less.  If there is a lot of shifting going on, we
4224      may win in CSE.  Otherwise combine will put the shifts back
4225      together again.  This can be called by function_arg, so we must
4226      be careful not to allocate a new register if we've reached the
4227      reload pass.  */
4228   if (TARGET_MIPS16
4229       && optimize
4230       && GET_CODE (operands[2]) == CONST_INT
4231       && INTVAL (operands[2]) > 8
4232       && INTVAL (operands[2]) <= 16
4233       && ! reload_in_progress
4234       && ! reload_completed)
4235     {
4236       rtx temp = gen_reg_rtx (SImode);
4238       emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
4239       emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
4240                                         GEN_INT (INTVAL (operands[2]) - 8)));
4241       DONE;
4242     }
4245 (define_insn "ashlsi3_internal1"
4246   [(set (match_operand:SI 0 "register_operand" "=d")
4247         (ashift:SI (match_operand:SI 1 "register_operand" "d")
4248                    (match_operand:SI 2 "arith_operand" "dI")))]
4249   "!TARGET_MIPS16"
4251   if (GET_CODE (operands[2]) == CONST_INT)
4252     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4254   return "sll\t%0,%1,%2";
4256   [(set_attr "type"     "shift")
4257    (set_attr "mode"     "SI")])
4259 (define_insn "ashlsi3_internal1_extend"
4260   [(set (match_operand:DI 0 "register_operand" "=d")
4261        (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
4262                                   (match_operand:SI 2 "arith_operand" "dI"))))]
4263   "TARGET_64BIT && !TARGET_MIPS16"
4265   if (GET_CODE (operands[2]) == CONST_INT)
4266     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4268   return "sll\t%0,%1,%2";
4270   [(set_attr "type"    "shift")
4271    (set_attr "mode"    "DI")])
4274 (define_insn "ashlsi3_internal2"
4275   [(set (match_operand:SI 0 "register_operand" "=d,d")
4276         (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
4277                    (match_operand:SI 2 "arith_operand" "d,I")))]
4278   "TARGET_MIPS16"
4280   if (which_alternative == 0)
4281     return "sll\t%0,%2";
4283   if (GET_CODE (operands[2]) == CONST_INT)
4284     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4286   return "sll\t%0,%1,%2";
4288   [(set_attr "type"     "shift")
4289    (set_attr "mode"     "SI")
4290    (set_attr_alternative "length"
4291                 [(const_int 4)
4292                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4293                                (const_int 4)
4294                                (const_int 8))])])
4296 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4298 (define_split
4299   [(set (match_operand:SI 0 "register_operand")
4300         (ashift:SI (match_operand:SI 1 "register_operand")
4301                    (match_operand:SI 2 "const_int_operand")))]
4302   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4303    && GET_CODE (operands[2]) == CONST_INT
4304    && INTVAL (operands[2]) > 8
4305    && INTVAL (operands[2]) <= 16"
4306   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
4307    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4308   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4310 (define_expand "ashldi3"
4311   [(set (match_operand:DI 0 "register_operand")
4312         (ashift:DI (match_operand:DI 1 "register_operand")
4313                    (match_operand:SI 2 "arith_operand")))]
4314   "TARGET_64BIT"
4316   /* On the mips16, a shift of more than 8 is a four byte
4317      instruction, so, for a shift between 8 and 16, it is just as
4318      fast to do two shifts of 8 or less.  If there is a lot of
4319      shifting going on, we may win in CSE.  Otherwise combine will
4320      put the shifts back together again.  This can be called by
4321      function_arg, so we must be careful not to allocate a new
4322      register if we've reached the reload pass.  */
4323   if (TARGET_MIPS16
4324       && optimize
4325       && GET_CODE (operands[2]) == CONST_INT
4326       && INTVAL (operands[2]) > 8
4327       && INTVAL (operands[2]) <= 16
4328       && ! reload_in_progress
4329       && ! reload_completed)
4330     {
4331       rtx temp = gen_reg_rtx (DImode);
4333       emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
4334       emit_insn (gen_ashldi3_internal (operands[0], temp,
4335                                        GEN_INT (INTVAL (operands[2]) - 8)));
4336       DONE;
4337     }
4341 (define_insn "ashldi3_internal"
4342   [(set (match_operand:DI 0 "register_operand" "=d")
4343         (ashift:DI (match_operand:DI 1 "register_operand" "d")
4344                    (match_operand:SI 2 "arith_operand" "dI")))]
4345   "TARGET_64BIT && !TARGET_MIPS16"
4347   if (GET_CODE (operands[2]) == CONST_INT)
4348     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4350   return "dsll\t%0,%1,%2";
4352   [(set_attr "type"     "shift")
4353    (set_attr "mode"     "DI")])
4355 (define_insn ""
4356   [(set (match_operand:DI 0 "register_operand" "=d,d")
4357         (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4358                    (match_operand:SI 2 "arith_operand" "d,I")))]
4359   "TARGET_64BIT && TARGET_MIPS16"
4361   if (which_alternative == 0)
4362     return "dsll\t%0,%2";
4364   if (GET_CODE (operands[2]) == CONST_INT)
4365     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4367   return "dsll\t%0,%1,%2";
4369   [(set_attr "type"     "shift")
4370    (set_attr "mode"     "DI")
4371    (set_attr_alternative "length"
4372                 [(const_int 4)
4373                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4374                                (const_int 4)
4375                                (const_int 8))])])
4378 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4380 (define_split
4381   [(set (match_operand:DI 0 "register_operand")
4382         (ashift:DI (match_operand:DI 1 "register_operand")
4383                    (match_operand:SI 2 "const_int_operand")))]
4384   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
4385    && reload_completed
4386    && GET_CODE (operands[2]) == CONST_INT
4387    && INTVAL (operands[2]) > 8
4388    && INTVAL (operands[2]) <= 16"
4389   [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
4390    (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
4391   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4393 (define_expand "ashrsi3"
4394   [(set (match_operand:SI 0 "register_operand")
4395         (ashiftrt:SI (match_operand:SI 1 "register_operand")
4396                      (match_operand:SI 2 "arith_operand")))]
4397   ""
4399   /* On the mips16, a shift of more than 8 is a four byte instruction,
4400      so, for a shift between 8 and 16, it is just as fast to do two
4401      shifts of 8 or less.  If there is a lot of shifting going on, we
4402      may win in CSE.  Otherwise combine will put the shifts back
4403      together again.  */
4404   if (TARGET_MIPS16
4405       && optimize
4406       && GET_CODE (operands[2]) == CONST_INT
4407       && INTVAL (operands[2]) > 8
4408       && INTVAL (operands[2]) <= 16)
4409     {
4410       rtx temp = gen_reg_rtx (SImode);
4412       emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
4413       emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
4414                                         GEN_INT (INTVAL (operands[2]) - 8)));
4415       DONE;
4416     }
4419 (define_insn "ashrsi3_internal1"
4420   [(set (match_operand:SI 0 "register_operand" "=d")
4421         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
4422                      (match_operand:SI 2 "arith_operand" "dI")))]
4423   "!TARGET_MIPS16"
4425   if (GET_CODE (operands[2]) == CONST_INT)
4426     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4428   return "sra\t%0,%1,%2";
4430   [(set_attr "type"     "shift")
4431    (set_attr "mode"     "SI")])
4433 (define_insn "ashrsi3_internal2"
4434   [(set (match_operand:SI 0 "register_operand" "=d,d")
4435         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
4436                      (match_operand:SI 2 "arith_operand" "d,I")))]
4437   "TARGET_MIPS16"
4439   if (which_alternative == 0)
4440     return "sra\t%0,%2";
4442   if (GET_CODE (operands[2]) == CONST_INT)
4443     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4445   return "sra\t%0,%1,%2";
4447   [(set_attr "type"     "shift")
4448    (set_attr "mode"     "SI")
4449    (set_attr_alternative "length"
4450                 [(const_int 4)
4451                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4452                                (const_int 4)
4453                                (const_int 8))])])
4456 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4458 (define_split
4459   [(set (match_operand:SI 0 "register_operand")
4460         (ashiftrt:SI (match_operand:SI 1 "register_operand")
4461                      (match_operand:SI 2 "const_int_operand")))]
4462   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4463    && GET_CODE (operands[2]) == CONST_INT
4464    && INTVAL (operands[2]) > 8
4465    && INTVAL (operands[2]) <= 16"
4466   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
4467    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
4468   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4470 (define_expand "ashrdi3"
4471   [(set (match_operand:DI 0 "register_operand")
4472         (ashiftrt:DI (match_operand:DI 1 "register_operand")
4473                      (match_operand:SI 2 "arith_operand")))]
4474   "TARGET_64BIT"
4476   /* On the mips16, a shift of more than 8 is a four byte
4477      instruction, so, for a shift between 8 and 16, it is just as
4478      fast to do two shifts of 8 or less.  If there is a lot of
4479      shifting going on, we may win in CSE.  Otherwise combine will
4480      put the shifts back together again.  */
4481   if (TARGET_MIPS16
4482       && optimize
4483       && GET_CODE (operands[2]) == CONST_INT
4484       && INTVAL (operands[2]) > 8
4485       && INTVAL (operands[2]) <= 16)
4486     {
4487       rtx temp = gen_reg_rtx (DImode);
4489       emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
4490       emit_insn (gen_ashrdi3_internal (operands[0], temp,
4491                                        GEN_INT (INTVAL (operands[2]) - 8)));
4492       DONE;
4493     }
4497 (define_insn "ashrdi3_internal"
4498   [(set (match_operand:DI 0 "register_operand" "=d")
4499         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4500                      (match_operand:SI 2 "arith_operand" "dI")))]
4501   "TARGET_64BIT && !TARGET_MIPS16"
4503   if (GET_CODE (operands[2]) == CONST_INT)
4504     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4506   return "dsra\t%0,%1,%2";
4508   [(set_attr "type"     "shift")
4509    (set_attr "mode"     "DI")])
4511 (define_insn ""
4512   [(set (match_operand:DI 0 "register_operand" "=d,d")
4513         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4514                      (match_operand:SI 2 "arith_operand" "d,I")))]
4515   "TARGET_64BIT && TARGET_MIPS16"
4517   if (GET_CODE (operands[2]) == CONST_INT)
4518     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4520   return "dsra\t%0,%2";
4522   [(set_attr "type"     "shift")
4523    (set_attr "mode"     "DI")
4524    (set_attr_alternative "length"
4525                 [(const_int 4)
4526                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4527                                (const_int 4)
4528                                (const_int 8))])])
4530 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4532 (define_split
4533   [(set (match_operand:DI 0 "register_operand")
4534         (ashiftrt:DI (match_operand:DI 1 "register_operand")
4535                      (match_operand:SI 2 "const_int_operand")))]
4536   "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
4537    && reload_completed
4538    && GET_CODE (operands[2]) == CONST_INT
4539    && INTVAL (operands[2]) > 8
4540    && INTVAL (operands[2]) <= 16"
4541   [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
4542    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
4543   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4545 (define_expand "lshrsi3"
4546   [(set (match_operand:SI 0 "register_operand")
4547         (lshiftrt:SI (match_operand:SI 1 "register_operand")
4548                      (match_operand:SI 2 "arith_operand")))]
4549   ""
4551   /* On the mips16, a shift of more than 8 is a four byte instruction,
4552      so, for a shift between 8 and 16, it is just as fast to do two
4553      shifts of 8 or less.  If there is a lot of shifting going on, we
4554      may win in CSE.  Otherwise combine will put the shifts back
4555      together again.  */
4556   if (TARGET_MIPS16
4557       && optimize
4558       && GET_CODE (operands[2]) == CONST_INT
4559       && INTVAL (operands[2]) > 8
4560       && INTVAL (operands[2]) <= 16)
4561     {
4562       rtx temp = gen_reg_rtx (SImode);
4564       emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
4565       emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
4566                                         GEN_INT (INTVAL (operands[2]) - 8)));
4567       DONE;
4568     }
4571 (define_insn "lshrsi3_internal1"
4572   [(set (match_operand:SI 0 "register_operand" "=d")
4573         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
4574                      (match_operand:SI 2 "arith_operand" "dI")))]
4575   "!TARGET_MIPS16"
4577   if (GET_CODE (operands[2]) == CONST_INT)
4578     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4580   return "srl\t%0,%1,%2";
4582   [(set_attr "type"     "shift")
4583    (set_attr "mode"     "SI")])
4585 (define_insn "lshrsi3_internal2"
4586   [(set (match_operand:SI 0 "register_operand" "=d,d")
4587         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
4588                      (match_operand:SI 2 "arith_operand" "d,I")))]
4589   "TARGET_MIPS16"
4591   if (which_alternative == 0)
4592     return "srl\t%0,%2";
4594   if (GET_CODE (operands[2]) == CONST_INT)
4595     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4597   return "srl\t%0,%1,%2";
4599   [(set_attr "type"     "shift")
4600    (set_attr "mode"     "SI")
4601    (set_attr_alternative "length"
4602                 [(const_int 4)
4603                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4604                                (const_int 4)
4605                                (const_int 8))])])
4608 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4610 (define_split
4611   [(set (match_operand:SI 0 "register_operand")
4612         (lshiftrt:SI (match_operand:SI 1 "register_operand")
4613                      (match_operand:SI 2 "const_int_operand")))]
4614   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4615    && GET_CODE (operands[2]) == CONST_INT
4616    && INTVAL (operands[2]) > 8
4617    && INTVAL (operands[2]) <= 16"
4618   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
4619    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4620   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4622 ;; If we load a byte on the mips16 as a bitfield, the resulting
4623 ;; sequence of instructions is too complicated for combine, because it
4624 ;; involves four instructions: a load, a shift, a constant load into a
4625 ;; register, and an and (the key problem here is that the mips16 does
4626 ;; not have and immediate).  We recognize a shift of a load in order
4627 ;; to make it simple enough for combine to understand.
4629 ;; The length here is the worst case: the length of the split version
4630 ;; will be more accurate.
4631 (define_insn_and_split ""
4632   [(set (match_operand:SI 0 "register_operand" "=d")
4633         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4634                      (match_operand:SI 2 "immediate_operand" "I")))]
4635   "TARGET_MIPS16"
4636   "#"
4637   ""
4638   [(set (match_dup 0) (match_dup 1))
4639    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4640   ""
4641   [(set_attr "type"     "load")
4642    (set_attr "mode"     "SI")
4643    (set_attr "length"   "16")])
4645 (define_expand "lshrdi3"
4646   [(set (match_operand:DI 0 "register_operand")
4647         (lshiftrt:DI (match_operand:DI 1 "register_operand")
4648                      (match_operand:SI 2 "arith_operand")))]
4649   "TARGET_64BIT"
4651   /* On the mips16, a shift of more than 8 is a four byte
4652      instruction, so, for a shift between 8 and 16, it is just as
4653      fast to do two shifts of 8 or less.  If there is a lot of
4654      shifting going on, we may win in CSE.  Otherwise combine will
4655      put the shifts back together again.  */
4656   if (TARGET_MIPS16
4657       && optimize
4658       && GET_CODE (operands[2]) == CONST_INT
4659       && INTVAL (operands[2]) > 8
4660       && INTVAL (operands[2]) <= 16)
4661     {
4662       rtx temp = gen_reg_rtx (DImode);
4664       emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
4665       emit_insn (gen_lshrdi3_internal (operands[0], temp,
4666                                        GEN_INT (INTVAL (operands[2]) - 8)));
4667       DONE;
4668     }
4672 (define_insn "lshrdi3_internal"
4673   [(set (match_operand:DI 0 "register_operand" "=d")
4674         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4675                      (match_operand:SI 2 "arith_operand" "dI")))]
4676   "TARGET_64BIT && !TARGET_MIPS16"
4678   if (GET_CODE (operands[2]) == CONST_INT)
4679     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4681   return "dsrl\t%0,%1,%2";
4683   [(set_attr "type"     "shift")
4684    (set_attr "mode"     "DI")])
4686 (define_insn ""
4687   [(set (match_operand:DI 0 "register_operand" "=d,d")
4688         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4689                      (match_operand:SI 2 "arith_operand" "d,I")))]
4690   "TARGET_64BIT && TARGET_MIPS16"
4692   if (GET_CODE (operands[2]) == CONST_INT)
4693     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4695   return "dsrl\t%0,%2";
4697   [(set_attr "type"     "shift")
4698    (set_attr "mode"     "DI")
4699    (set_attr_alternative "length"
4700                 [(const_int 4)
4701                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4702                                (const_int 4)
4703                                (const_int 8))])])
4705 (define_insn "rotrsi3"
4706   [(set (match_operand:SI              0 "register_operand" "=d")
4707         (rotatert:SI (match_operand:SI 1 "register_operand" "d")
4708                      (match_operand:SI 2 "arith_operand"    "dn")))]
4709   "ISA_HAS_ROTR_SI"
4711   if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
4712     return "rorv\t%0,%1,%2";
4714   if ((GET_CODE (operands[2]) == CONST_INT)
4715       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
4716     abort ();
4718   return "ror\t%0,%1,%2";
4720   [(set_attr "type"     "shift")
4721    (set_attr "mode"     "SI")])
4723 (define_insn "rotrdi3"
4724   [(set (match_operand:DI              0 "register_operand" "=d")
4725         (rotatert:DI (match_operand:DI 1 "register_operand" "d")
4726                      (match_operand:DI 2 "arith_operand"    "dn")))]
4727   "ISA_HAS_ROTR_DI"
4729   if (TARGET_SR71K)
4730     {
4731       if (GET_CODE (operands[2]) != CONST_INT)
4732         return "drorv\t%0,%1,%2";
4734       if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
4735         return "dror32\t%0,%1,%2";
4736     }
4738   if ((GET_CODE (operands[2]) == CONST_INT)
4739       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
4740     abort ();
4742   return "dror\t%0,%1,%2";
4744   [(set_attr "type"     "shift")
4745    (set_attr "mode"     "DI")])
4748 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4750 (define_split
4751   [(set (match_operand:DI 0 "register_operand")
4752         (lshiftrt:DI (match_operand:DI 1 "register_operand")
4753                      (match_operand:SI 2 "const_int_operand")))]
4754   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4755    && GET_CODE (operands[2]) == CONST_INT
4756    && INTVAL (operands[2]) > 8
4757    && INTVAL (operands[2]) <= 16"
4758   [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
4759    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
4760   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4763 ;;  ....................
4765 ;;      COMPARISONS
4767 ;;  ....................
4769 ;; Flow here is rather complex:
4771 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the arguments
4772 ;;      into cmp_operands[] but generates no RTL.
4774 ;;  2)  The appropriate branch define_expand is called, which then
4775 ;;      creates the appropriate RTL for the comparison and branch.
4776 ;;      Different CC modes are used, based on what type of branch is
4777 ;;      done, so that we can constrain things appropriately.  There
4778 ;;      are assumptions in the rest of GCC that break if we fold the
4779 ;;      operands into the branches for integer operations, and use cc0
4780 ;;      for floating point, so we use the fp status register instead.
4781 ;;      If needed, an appropriate temporary is created to hold the
4782 ;;      of the integer compare.
4784 (define_expand "cmp<mode>"
4785   [(set (cc0)
4786         (compare:CC (match_operand:GPR 0 "register_operand")
4787                     (match_operand:GPR 1 "nonmemory_operand")))]
4788   ""
4790   cmp_operands[0] = operands[0];
4791   cmp_operands[1] = operands[1];
4792   DONE;
4795 (define_expand "cmpdf"
4796   [(set (cc0)
4797         (compare:CC (match_operand:DF 0 "register_operand")
4798                     (match_operand:DF 1 "register_operand")))]
4799   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4801   cmp_operands[0] = operands[0];
4802   cmp_operands[1] = operands[1];
4803   DONE;
4806 (define_expand "cmpsf"
4807   [(set (cc0)
4808         (compare:CC (match_operand:SF 0 "register_operand")
4809                     (match_operand:SF 1 "register_operand")))]
4810   "TARGET_HARD_FLOAT"
4812   cmp_operands[0] = operands[0];
4813   cmp_operands[1] = operands[1];
4814   DONE;
4818 ;;  ....................
4820 ;;      CONDITIONAL BRANCHES
4822 ;;  ....................
4824 ;; Conditional branches on floating-point equality tests.
4826 (define_insn "branch_fp"
4827   [(set (pc)
4828         (if_then_else
4829          (match_operator:CC 0 "comparison_operator"
4830                             [(match_operand:CC 2 "register_operand" "z")
4831                              (const_int 0)])
4832          (label_ref (match_operand 1 "" ""))
4833          (pc)))]
4834   "TARGET_HARD_FLOAT"
4836   return mips_output_conditional_branch (insn,
4837                                          operands,
4838                                          /*two_operands_p=*/0,
4839                                          /*float_p=*/1,
4840                                          /*inverted_p=*/0,
4841                                          get_attr_length (insn));
4843   [(set_attr "type"     "branch")
4844    (set_attr "mode"     "none")])
4846 (define_insn "branch_fp_inverted"
4847   [(set (pc)
4848         (if_then_else
4849          (match_operator:CC 0 "comparison_operator"
4850                             [(match_operand:CC 2 "register_operand" "z")
4851                              (const_int 0)])
4852          (pc)
4853          (label_ref (match_operand 1 "" ""))))]
4854   "TARGET_HARD_FLOAT"
4856   return mips_output_conditional_branch (insn,
4857                                          operands,
4858                                          /*two_operands_p=*/0,
4859                                          /*float_p=*/1,
4860                                          /*inverted_p=*/1,
4861                                          get_attr_length (insn));
4863   [(set_attr "type"     "branch")
4864    (set_attr "mode"     "none")])
4866 ;; Conditional branches on comparisons with zero.
4868 (define_insn "*branch_zero<mode>"
4869   [(set (pc)
4870         (if_then_else
4871          (match_operator:GPR 0 "comparison_operator"
4872                              [(match_operand:GPR 2 "register_operand" "d")
4873                               (const_int 0)])
4874          (label_ref (match_operand 1 "" ""))
4875          (pc)))]
4876   "!TARGET_MIPS16"
4878   return mips_output_conditional_branch (insn,
4879                                          operands,
4880                                          /*two_operands_p=*/0,
4881                                          /*float_p=*/0,
4882                                          /*inverted_p=*/0,
4883                                          get_attr_length (insn));
4885   [(set_attr "type" "branch")
4886    (set_attr "mode" "none")])
4888 (define_insn "*branch_zero<mode>_inverted"
4889   [(set (pc)
4890         (if_then_else
4891          (match_operator:GPR 0 "comparison_operator"
4892                              [(match_operand:GPR 2 "register_operand" "d")
4893                               (const_int 0)])
4894          (pc)
4895          (label_ref (match_operand 1 "" ""))))]
4896   "!TARGET_MIPS16"
4898   return mips_output_conditional_branch (insn,
4899                                          operands,
4900                                          /*two_operands_p=*/0,
4901                                          /*float_p=*/0,
4902                                          /*inverted_p=*/1,
4903                                          get_attr_length (insn));
4905   [(set_attr "type" "branch")
4906    (set_attr "mode" "none")])
4908 ;; Conditional branch on equality comparison.
4910 (define_insn "*branch_equality<mode>"
4911   [(set (pc)
4912         (if_then_else
4913          (match_operator:GPR 0 "equality_operator"
4914                              [(match_operand:GPR 2 "register_operand" "d")
4915                               (match_operand:GPR 3 "register_operand" "d")])
4916          (label_ref (match_operand 1 "" ""))
4917          (pc)))]
4918   "!TARGET_MIPS16"
4920   return mips_output_conditional_branch (insn,
4921                                          operands,
4922                                          /*two_operands_p=*/1,
4923                                          /*float_p=*/0,
4924                                          /*inverted_p=*/0,
4925                                          get_attr_length (insn));
4927   [(set_attr "type" "branch")
4928    (set_attr "mode" "none")])
4930 (define_insn "*branch_equality<mode>_inverted"
4931   [(set (pc)
4932         (if_then_else
4933          (match_operator:GPR 0 "equality_operator"
4934                              [(match_operand:GPR 2 "register_operand" "d")
4935                               (match_operand:GPR 3 "register_operand" "d")])
4936          (pc)
4937          (label_ref (match_operand 1 "" ""))))]
4938   "!TARGET_MIPS16"
4940   return mips_output_conditional_branch (insn,
4941                                          operands,
4942                                          /*two_operands_p=*/1,
4943                                          /*float_p=*/0,
4944                                          /*inverted_p=*/1,
4945                                          get_attr_length (insn));
4947   [(set_attr "type" "branch")
4948    (set_attr "mode" "none")])
4950 ;; MIPS16 branches
4952 (define_insn "*branch_equality<mode>_mips16"
4953   [(set (pc)
4954         (if_then_else
4955          (match_operator:GPR 0 "equality_operator"
4956                              [(match_operand:GPR 1 "register_operand" "d,t")
4957                               (const_int 0)])
4958          (match_operand 2 "pc_or_label_operand" "")
4959          (match_operand 3 "pc_or_label_operand" "")))]
4960   "TARGET_MIPS16"
4962   if (operands[2] != pc_rtx)
4963     {
4964       if (which_alternative == 0)
4965         return "b%C0z\t%1,%2";
4966       else
4967         return "bt%C0z\t%2";
4968     }
4969   else
4970     {
4971       if (which_alternative == 0)
4972         return "b%N0z\t%1,%3";
4973       else
4974         return "bt%N0z\t%3";
4975     }
4977   [(set_attr "type" "branch")
4978    (set_attr "mode" "none")
4979    (set_attr "length" "8")])
4981 (define_expand "b<code>"
4982   [(set (pc)
4983         (if_then_else (any_cond:CC (cc0)
4984                                    (const_int 0))
4985                       (label_ref (match_operand 0 ""))
4986                       (pc)))]
4987   ""
4989   gen_conditional_branch (operands, <CODE>);
4990   DONE;
4994 ;;  ....................
4996 ;;      SETTING A REGISTER FROM A COMPARISON
4998 ;;  ....................
5000 (define_expand "seq"
5001   [(set (match_operand:SI 0 "register_operand")
5002         (eq:SI (match_dup 1)
5003                (match_dup 2)))]
5004   ""
5005   { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
5007 (define_insn "*seq_<mode>"
5008   [(set (match_operand:GPR 0 "register_operand" "=d")
5009         (eq:GPR (match_operand:GPR 1 "register_operand" "d")
5010                 (const_int 0)))]
5011   "!TARGET_MIPS16"
5012   "sltu\t%0,%1,1"
5013   [(set_attr "type" "slt")
5014    (set_attr "mode" "<MODE>")])
5016 (define_insn "*seq_<mode>_mips16"
5017   [(set (match_operand:GPR 0 "register_operand" "=t")
5018         (eq:GPR (match_operand:GPR 1 "register_operand" "d")
5019                 (const_int 0)))]
5020   "TARGET_MIPS16"
5021   "sltu\t%1,1"
5022   [(set_attr "type" "slt")
5023    (set_attr "mode" "<MODE>")])
5025 ;; "sne" uses sltu instructions in which the first operand is $0.
5026 ;; This isn't possible in mips16 code.
5028 (define_expand "sne"
5029   [(set (match_operand:SI 0 "register_operand")
5030         (ne:SI (match_dup 1)
5031                (match_dup 2)))]
5032   "!TARGET_MIPS16"
5033   { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
5035 (define_insn "*sne_<mode>"
5036   [(set (match_operand:GPR 0 "register_operand" "=d")
5037         (ne:GPR (match_operand:GPR 1 "register_operand" "d")
5038                 (const_int 0)))]
5039   "!TARGET_MIPS16"
5040   "sltu\t%0,%.,%1"
5041   [(set_attr "type" "slt")
5042    (set_attr "mode" "<MODE>")])
5044 (define_expand "sgt"
5045   [(set (match_operand:SI 0 "register_operand")
5046         (gt:SI (match_dup 1)
5047                (match_dup 2)))]
5048   ""
5049   { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
5051 (define_insn "*sgt_<mode>"
5052   [(set (match_operand:GPR 0 "register_operand" "=d")
5053         (gt:GPR (match_operand:GPR 1 "register_operand" "d")
5054                 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
5055   "!TARGET_MIPS16"
5056   "slt\t%0,%z2,%1"
5057   [(set_attr "type" "slt")
5058    (set_attr "mode" "<MODE>")])
5060 (define_insn "*sgt_<mode>_mips16"
5061   [(set (match_operand:GPR 0 "register_operand" "=t")
5062         (gt:GPR (match_operand:GPR 1 "register_operand" "d")
5063                 (match_operand:GPR 2 "register_operand" "d")))]
5064   "TARGET_MIPS16"
5065   "slt\t%2,%1"
5066   [(set_attr "type" "slt")
5067    (set_attr "mode" "<MODE>")])
5069 (define_expand "sge"
5070   [(set (match_operand:SI 0 "register_operand")
5071         (ge:SI (match_dup 1)
5072                (match_dup 2)))]
5073   ""
5074   { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
5076 (define_insn "*sge_<mode>"
5077   [(set (match_operand:GPR 0 "register_operand" "=d")
5078         (ge:GPR (match_operand:GPR 1 "register_operand" "d")
5079                 (const_int 1)))]
5080   "!TARGET_MIPS16"
5081   "slt\t%0,%.,%1"
5082   [(set_attr "type" "slt")
5083    (set_attr "mode" "<MODE>")])
5085 (define_expand "slt"
5086   [(set (match_operand:SI 0 "register_operand")
5087         (lt:SI (match_dup 1)
5088                (match_dup 2)))]
5089   ""
5090   { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
5092 (define_insn "*slt_<mode>"
5093   [(set (match_operand:GPR 0 "register_operand" "=d")
5094         (lt:GPR (match_operand:GPR 1 "register_operand" "d")
5095                 (match_operand:GPR 2 "arith_operand" "dI")))]
5096   "!TARGET_MIPS16"
5097   "slt\t%0,%1,%2"
5098   [(set_attr "type" "slt")
5099    (set_attr "mode" "<MODE>")])
5101 (define_insn "*slt_<mode>_mips16"
5102   [(set (match_operand:GPR 0 "register_operand" "=t,t")
5103         (lt:GPR (match_operand:GPR 1 "register_operand" "d,d")
5104                 (match_operand:GPR 2 "arith_operand" "d,I")))]
5105   "TARGET_MIPS16"
5106   "slt\t%1,%2"
5107   [(set_attr "type" "slt")
5108    (set_attr "mode" "<MODE>")
5109    (set_attr_alternative "length"
5110                 [(const_int 4)
5111                  (if_then_else (match_operand 2 "m16_uimm8_1")
5112                                (const_int 4)
5113                                (const_int 8))])])
5115 (define_expand "sle"
5116   [(set (match_operand:SI 0 "register_operand")
5117         (le:SI (match_dup 1)
5118                (match_dup 2)))]
5119   ""
5120   { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
5122 (define_insn "*sle_<mode>"
5123   [(set (match_operand:GPR 0 "register_operand" "=d")
5124         (le:GPR (match_operand:GPR 1 "register_operand" "d")
5125                 (match_operand:GPR 2 "sle_operand" "")))]
5126   "!TARGET_MIPS16"
5128   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5129   return "slt\t%0,%1,%2";
5131   [(set_attr "type" "slt")
5132    (set_attr "mode" "<MODE>")])
5134 (define_insn "*sle_<mode>_mips16"
5135   [(set (match_operand:GPR 0 "register_operand" "=t")
5136         (le:GPR (match_operand:GPR 1 "register_operand" "d")
5137                 (match_operand:GPR 2 "sle_operand" "")))]
5138   "TARGET_MIPS16"
5140   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5141   return "slt\t%1,%2";
5143   [(set_attr "type" "slt")
5144    (set_attr "mode" "<MODE>")
5145    (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
5146                                       (const_int 4)
5147                                       (const_int 8)))])
5149 (define_expand "sgtu"
5150   [(set (match_operand:SI 0 "register_operand")
5151         (gtu:SI (match_dup 1)
5152                 (match_dup 2)))]
5153   ""
5154   { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
5156 (define_insn "*sgtu_<mode>"
5157   [(set (match_operand:GPR 0 "register_operand" "=d")
5158         (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
5159                  (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
5160   "!TARGET_MIPS16"
5161   "sltu\t%0,%z2,%1"
5162   [(set_attr "type" "slt")
5163    (set_attr "mode" "<MODE>")])
5165 (define_insn "*sgtu_<mode>_mips16"
5166   [(set (match_operand:GPR 0 "register_operand" "=t")
5167         (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
5168                  (match_operand:GPR 2 "register_operand" "d")))]
5169   "TARGET_MIPS16"
5170   "sltu\t%2,%1"
5171   [(set_attr "type" "slt")
5172    (set_attr "mode" "<MODE>")])
5174 (define_expand "sgeu"
5175   [(set (match_operand:SI 0 "register_operand")
5176         (geu:SI (match_dup 1)
5177                 (match_dup 2)))]
5178   ""
5179   { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
5181 (define_insn "*sge_<mode>"
5182   [(set (match_operand:GPR 0 "register_operand" "=d")
5183         (geu:GPR (match_operand:GPR 1 "register_operand" "d")
5184                  (const_int 1)))]
5185   "!TARGET_MIPS16"
5186   "sltu\t%0,%.,%1"
5187   [(set_attr "type" "slt")
5188    (set_attr "mode" "<MODE>")])
5190 (define_expand "sltu"
5191   [(set (match_operand:SI 0 "register_operand")
5192         (ltu:SI (match_dup 1)
5193                 (match_dup 2)))]
5194   ""
5195   { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
5197 (define_insn "*sltu_<mode>"
5198   [(set (match_operand:GPR 0 "register_operand" "=d")
5199         (ltu:GPR (match_operand:GPR 1 "register_operand" "d")
5200                  (match_operand:GPR 2 "arith_operand" "dI")))]
5201   "!TARGET_MIPS16"
5202   "sltu\t%0,%1,%2"
5203   [(set_attr "type" "slt")
5204    (set_attr "mode" "<MODE>")])
5206 (define_insn "*sltu_<mode>_mips16"
5207   [(set (match_operand:GPR 0 "register_operand" "=t,t")
5208         (ltu:GPR (match_operand:GPR 1 "register_operand" "d,d")
5209                  (match_operand:GPR 2 "arith_operand" "d,I")))]
5210   "TARGET_MIPS16"
5211   "sltu\t%1,%2"
5212   [(set_attr "type" "slt")
5213    (set_attr "mode" "<MODE>")
5214    (set_attr_alternative "length"
5215                 [(const_int 4)
5216                  (if_then_else (match_operand 2 "m16_uimm8_1")
5217                                (const_int 4)
5218                                (const_int 8))])])
5220 (define_expand "sleu"
5221   [(set (match_operand:SI 0 "register_operand")
5222         (leu:SI (match_dup 1)
5223                 (match_dup 2)))]
5224   ""
5225   { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
5227 (define_insn "*sleu_<mode>"
5228   [(set (match_operand:GPR 0 "register_operand" "=d")
5229         (leu:GPR (match_operand:GPR 1 "register_operand" "d")
5230                  (match_operand:GPR 2 "sleu_operand" "")))]
5231   "!TARGET_MIPS16"
5233   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5234   return "sltu\t%0,%1,%2";
5236   [(set_attr "type" "slt")
5237    (set_attr "mode" "<MODE>")])
5239 (define_insn "*sleu_<mode>_mips16"
5240   [(set (match_operand:GPR 0 "register_operand" "=t")
5241         (leu:GPR (match_operand:GPR 1 "register_operand" "d")
5242                  (match_operand:GPR 2 "sleu_operand" "")))]
5243   "TARGET_MIPS16"
5245   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5246   return "sltu\t%1,%2";
5248   [(set_attr "type" "slt")
5249    (set_attr "mode" "<MODE>")
5250    (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
5251                                       (const_int 4)
5252                                       (const_int 8)))])
5255 ;;  ....................
5257 ;;      FLOATING POINT COMPARISONS
5259 ;;  ....................
5261 (define_insn "sunordered_df"
5262   [(set (match_operand:CC 0 "register_operand" "=z")
5263         (unordered:CC (match_operand:DF 1 "register_operand" "f")
5264                       (match_operand:DF 2 "register_operand" "f")))]
5265   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5266   "c.un.d\t%Z0%1,%2"
5267   [(set_attr "type" "fcmp")
5268    (set_attr "mode" "FPSW")])
5270 (define_insn "sunlt_df"
5271   [(set (match_operand:CC 0 "register_operand" "=z")
5272         (unlt:CC (match_operand:DF 1 "register_operand" "f")
5273                  (match_operand:DF 2 "register_operand" "f")))]
5274   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5275   "c.ult.d\t%Z0%1,%2"
5276   [(set_attr "type" "fcmp")
5277    (set_attr "mode" "FPSW")])
5279 (define_insn "suneq_df"
5280   [(set (match_operand:CC 0 "register_operand" "=z")
5281         (uneq:CC (match_operand:DF 1 "register_operand" "f")
5282                  (match_operand:DF 2 "register_operand" "f")))]
5283   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5284   "c.ueq.d\t%Z0%1,%2"
5285   [(set_attr "type" "fcmp")
5286    (set_attr "mode" "FPSW")])
5288 (define_insn "sunle_df"
5289   [(set (match_operand:CC 0 "register_operand" "=z")
5290         (unle:CC (match_operand:DF 1 "register_operand" "f")
5291                  (match_operand:DF 2 "register_operand" "f")))]
5292   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5293   "c.ule.d\t%Z0%1,%2"
5294   [(set_attr "type" "fcmp")
5295    (set_attr "mode" "FPSW")])
5297 (define_insn "seq_df"
5298   [(set (match_operand:CC 0 "register_operand" "=z")
5299         (eq:CC (match_operand:DF 1 "register_operand" "f")
5300                (match_operand:DF 2 "register_operand" "f")))]
5301   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5302   "c.eq.d\t%Z0%1,%2"
5303   [(set_attr "type" "fcmp")
5304    (set_attr "mode" "FPSW")])
5306 (define_insn "slt_df"
5307   [(set (match_operand:CC 0 "register_operand" "=z")
5308         (lt:CC (match_operand:DF 1 "register_operand" "f")
5309                (match_operand:DF 2 "register_operand" "f")))]
5310   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5311   "c.lt.d\t%Z0%1,%2"
5312   [(set_attr "type" "fcmp")
5313    (set_attr "mode" "FPSW")])
5315 (define_insn "sle_df"
5316   [(set (match_operand:CC 0 "register_operand" "=z")
5317         (le:CC (match_operand:DF 1 "register_operand" "f")
5318                (match_operand:DF 2 "register_operand" "f")))]
5319   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5320   "c.le.d\t%Z0%1,%2"
5321   [(set_attr "type" "fcmp")
5322    (set_attr "mode" "FPSW")])
5324 (define_insn "sgt_df"
5325   [(set (match_operand:CC 0 "register_operand" "=z")
5326         (gt:CC (match_operand:DF 1 "register_operand" "f")
5327                (match_operand:DF 2 "register_operand" "f")))]
5328   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5329   "c.lt.d\t%Z0%2,%1"
5330   [(set_attr "type" "fcmp")
5331    (set_attr "mode" "FPSW")])
5333 (define_insn "sge_df"
5334   [(set (match_operand:CC 0 "register_operand" "=z")
5335         (ge:CC (match_operand:DF 1 "register_operand" "f")
5336                (match_operand:DF 2 "register_operand" "f")))]
5337   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5338   "c.le.d\t%Z0%2,%1"
5339   [(set_attr "type" "fcmp")
5340    (set_attr "mode" "FPSW")])
5342 (define_insn "sunordered_sf"
5343   [(set (match_operand:CC 0 "register_operand" "=z")
5344         (unordered:CC (match_operand:SF 1 "register_operand" "f")
5345                       (match_operand:SF 2 "register_operand" "f")))]
5346   "TARGET_HARD_FLOAT"
5347   "c.un.s\t%Z0%1,%2"
5348   [(set_attr "type" "fcmp")
5349    (set_attr "mode" "FPSW")])
5351 (define_insn "sunlt_sf"
5352   [(set (match_operand:CC 0 "register_operand" "=z")
5353         (unlt:CC (match_operand:SF 1 "register_operand" "f")
5354                  (match_operand:SF 2 "register_operand" "f")))]
5355   "TARGET_HARD_FLOAT"
5356   "c.ult.s\t%Z0%1,%2"
5357   [(set_attr "type" "fcmp")
5358    (set_attr "mode" "FPSW")])
5360 (define_insn "suneq_sf"
5361   [(set (match_operand:CC 0 "register_operand" "=z")
5362         (uneq:CC (match_operand:SF 1 "register_operand" "f")
5363                  (match_operand:SF 2 "register_operand" "f")))]
5364   "TARGET_HARD_FLOAT"
5365   "c.ueq.s\t%Z0%1,%2"
5366   [(set_attr "type" "fcmp")
5367    (set_attr "mode" "FPSW")])
5369 (define_insn "sunle_sf"
5370   [(set (match_operand:CC 0 "register_operand" "=z")
5371         (unle:CC (match_operand:SF 1 "register_operand" "f")
5372                  (match_operand:SF 2 "register_operand" "f")))]
5373   "TARGET_HARD_FLOAT"
5374   "c.ule.s\t%Z0%1,%2"
5375   [(set_attr "type" "fcmp")
5376    (set_attr "mode" "FPSW")])
5378 (define_insn "seq_sf"
5379   [(set (match_operand:CC 0 "register_operand" "=z")
5380         (eq:CC (match_operand:SF 1 "register_operand" "f")
5381                (match_operand:SF 2 "register_operand" "f")))]
5382   "TARGET_HARD_FLOAT"
5383   "c.eq.s\t%Z0%1,%2"
5384   [(set_attr "type" "fcmp")
5385    (set_attr "mode" "FPSW")])
5387 (define_insn "slt_sf"
5388   [(set (match_operand:CC 0 "register_operand" "=z")
5389         (lt:CC (match_operand:SF 1 "register_operand" "f")
5390                (match_operand:SF 2 "register_operand" "f")))]
5391   "TARGET_HARD_FLOAT"
5392   "c.lt.s\t%Z0%1,%2"
5393   [(set_attr "type" "fcmp")
5394    (set_attr "mode" "FPSW")])
5396 (define_insn "sle_sf"
5397   [(set (match_operand:CC 0 "register_operand" "=z")
5398         (le:CC (match_operand:SF 1 "register_operand" "f")
5399                (match_operand:SF 2 "register_operand" "f")))]
5400   "TARGET_HARD_FLOAT"
5401   "c.le.s\t%Z0%1,%2"
5402   [(set_attr "type" "fcmp")
5403    (set_attr "mode" "FPSW")])
5405 (define_insn "sgt_sf"
5406   [(set (match_operand:CC 0 "register_operand" "=z")
5407         (gt:CC (match_operand:SF 1 "register_operand" "f")
5408                (match_operand:SF 2 "register_operand" "f")))]
5409   "TARGET_HARD_FLOAT"
5410   "c.lt.s\t%Z0%2,%1"
5411   [(set_attr "type" "fcmp")
5412    (set_attr "mode" "FPSW")])
5414 (define_insn "sge_sf"
5415   [(set (match_operand:CC 0 "register_operand" "=z")
5416         (ge:CC (match_operand:SF 1 "register_operand" "f")
5417                (match_operand:SF 2 "register_operand" "f")))]
5418   "TARGET_HARD_FLOAT"
5419   "c.le.s\t%Z0%2,%1"
5420   [(set_attr "type" "fcmp")
5421    (set_attr "mode" "FPSW")])
5424 ;;  ....................
5426 ;;      UNCONDITIONAL BRANCHES
5428 ;;  ....................
5430 ;; Unconditional branches.
5432 (define_insn "jump"
5433   [(set (pc)
5434         (label_ref (match_operand 0 "" "")))]
5435   "!TARGET_MIPS16"
5437   if (flag_pic)
5438     {
5439       if (get_attr_length (insn) <= 8)
5440         return "%*b\t%l0%/";
5441       else
5442         {
5443           output_asm_insn (mips_output_load_label (), operands);
5444           return "%*jr\t%@%/%]";
5445         }
5446     }
5447   else
5448     return "%*j\t%l0%/";
5450   [(set_attr "type"     "jump")
5451    (set_attr "mode"     "none")
5452    (set (attr "length")
5453         ;; We can't use `j' when emitting PIC.  Emit a branch if it's
5454         ;; in range, otherwise load the address of the branch target into
5455         ;; $at and then jump to it.
5456         (if_then_else
5457          (ior (eq (symbol_ref "flag_pic") (const_int 0))
5458               (lt (abs (minus (match_dup 0)
5459                               (plus (pc) (const_int 4))))
5460                   (const_int 131072)))
5461          (const_int 4) (const_int 16)))])
5463 ;; We need a different insn for the mips16, because a mips16 branch
5464 ;; does not have a delay slot.
5466 (define_insn ""
5467   [(set (pc)
5468         (label_ref (match_operand 0 "" "")))]
5469   "TARGET_MIPS16"
5470   "b\t%l0"
5471   [(set_attr "type"     "branch")
5472    (set_attr "mode"     "none")
5473    (set_attr "length"   "8")])
5475 (define_expand "indirect_jump"
5476   [(set (pc) (match_operand 0 "register_operand"))]
5477   ""
5479   operands[0] = force_reg (Pmode, operands[0]);
5480   if (Pmode == SImode)
5481     emit_jump_insn (gen_indirect_jumpsi (operands[0]));
5482   else
5483     emit_jump_insn (gen_indirect_jumpdi (operands[0]));
5484   DONE;
5487 (define_insn "indirect_jump<mode>"
5488   [(set (pc) (match_operand:P 0 "register_operand" "d"))]
5489   ""
5490   "%*j\t%0%/"
5491   [(set_attr "type" "jump")
5492    (set_attr "mode" "none")])
5494 (define_expand "tablejump"
5495   [(set (pc)
5496         (match_operand 0 "register_operand"))
5497    (use (label_ref (match_operand 1 "")))]
5498   ""
5500   if (TARGET_MIPS16)
5501     operands[0] = expand_binop (Pmode, add_optab,
5502                                 convert_to_mode (Pmode, operands[0], false),
5503                                 gen_rtx_LABEL_REF (Pmode, operands[1]),
5504                                 0, 0, OPTAB_WIDEN);
5505   else if (TARGET_GPWORD)
5506     operands[0] = expand_binop (Pmode, add_optab, operands[0],
5507                                 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
5509   if (Pmode == SImode)
5510     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
5511   else
5512     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
5513   DONE;
5516 (define_insn "tablejump<mode>"
5517   [(set (pc)
5518         (match_operand:P 0 "register_operand" "d"))
5519    (use (label_ref (match_operand 1 "" "")))]
5520   ""
5521   "%*j\t%0%/"
5522   [(set_attr "type" "jump")
5523    (set_attr "mode" "none")])
5525 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
5526 ;; While it is possible to either pull it off the stack (in the
5527 ;; o32 case) or recalculate it given t9 and our target label,
5528 ;; it takes 3 or 4 insns to do so.
5530 (define_expand "builtin_setjmp_setup"
5531   [(use (match_operand 0 "register_operand"))]
5532   "TARGET_ABICALLS"
5534   rtx addr;
5536   addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
5537   emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
5538   DONE;
5541 ;; Restore the gp that we saved above.  Despite the earlier comment, it seems
5542 ;; that older code did recalculate the gp from $25.  Continue to jump through
5543 ;; $25 for compatibility (we lose nothing by doing so).
5545 (define_expand "builtin_longjmp"
5546   [(use (match_operand 0 "register_operand"))]
5547   "TARGET_ABICALLS"
5549   /* The elements of the buffer are, in order:  */
5550   int W = GET_MODE_SIZE (Pmode);
5551   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5552   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
5553   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
5554   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
5555   rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
5556   /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
5557      The target is bound to be using $28 as the global pointer
5558      but the current function might not be.  */
5559   rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
5561   /* This bit is similar to expand_builtin_longjmp except that it
5562      restores $gp as well.  */
5563   emit_move_insn (hard_frame_pointer_rtx, fp);
5564   emit_move_insn (pv, lab);
5565   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5566   emit_move_insn (gp, gpv);
5567   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5568   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5569   emit_insn (gen_rtx_USE (VOIDmode, gp));
5570   emit_indirect_jump (pv);
5571   DONE;
5575 ;;  ....................
5577 ;;      Function prologue/epilogue
5579 ;;  ....................
5582 (define_expand "prologue"
5583   [(const_int 1)]
5584   ""
5586   mips_expand_prologue ();
5587   DONE;
5590 ;; Block any insns from being moved before this point, since the
5591 ;; profiling call to mcount can use various registers that aren't
5592 ;; saved or used to pass arguments.
5594 (define_insn "blockage"
5595   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
5596   ""
5597   ""
5598   [(set_attr "type"     "unknown")
5599    (set_attr "mode"     "none")
5600    (set_attr "length"   "0")])
5602 (define_expand "epilogue"
5603   [(const_int 2)]
5604   ""
5606   mips_expand_epilogue (false);
5607   DONE;
5610 (define_expand "sibcall_epilogue"
5611   [(const_int 2)]
5612   ""
5614   mips_expand_epilogue (true);
5615   DONE;
5618 ;; Trivial return.  Make it look like a normal return insn as that
5619 ;; allows jump optimizations to work better.
5621 (define_insn "return"
5622   [(return)]
5623   "mips_can_use_return_insn ()"
5624   "%*j\t$31%/"
5625   [(set_attr "type"     "jump")
5626    (set_attr "mode"     "none")])
5628 ;; Normal return.
5630 (define_insn "return_internal"
5631   [(return)
5632    (use (match_operand 0 "pmode_register_operand" ""))]
5633   ""
5634   "%*j\t%0%/"
5635   [(set_attr "type"     "jump")
5636    (set_attr "mode"     "none")])
5638 ;; This is used in compiling the unwind routines.
5639 (define_expand "eh_return"
5640   [(use (match_operand 0 "general_operand"))]
5641   ""
5643   enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
5645   if (GET_MODE (operands[0]) != gpr_mode)
5646     operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
5647   if (TARGET_64BIT)
5648     emit_insn (gen_eh_set_lr_di (operands[0]));
5649   else
5650     emit_insn (gen_eh_set_lr_si (operands[0]));
5652   DONE;
5655 ;; Clobber the return address on the stack.  We can't expand this
5656 ;; until we know where it will be put in the stack frame.
5658 (define_insn "eh_set_lr_si"
5659   [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5660    (clobber (match_scratch:SI 1 "=&d"))]
5661   "! TARGET_64BIT"
5662   "#")
5664 (define_insn "eh_set_lr_di"
5665   [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5666    (clobber (match_scratch:DI 1 "=&d"))]
5667   "TARGET_64BIT"
5668   "#")
5670 (define_split
5671   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
5672    (clobber (match_scratch 1))]
5673   "reload_completed && !TARGET_DEBUG_D_MODE"
5674   [(const_int 0)]
5676   mips_set_return_address (operands[0], operands[1]);
5677   DONE;
5680 (define_insn_and_split "exception_receiver"
5681   [(set (reg:SI 28)
5682         (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
5683   "TARGET_ABICALLS && TARGET_OLDABI"
5684   "#"
5685   "&& reload_completed"
5686   [(const_int 0)]
5688   mips_restore_gp ();
5689   DONE;
5691   [(set_attr "type"   "load")
5692    (set_attr "length" "12")])
5695 ;;  ....................
5697 ;;      FUNCTION CALLS
5699 ;;  ....................
5701 ;; Instructions to load a call address from the GOT.  The address might
5702 ;; point to a function or to a lazy binding stub.  In the latter case,
5703 ;; the stub will use the dynamic linker to resolve the function, which
5704 ;; in turn will change the GOT entry to point to the function's real
5705 ;; address.
5707 ;; This means that every call, even pure and constant ones, can
5708 ;; potentially modify the GOT entry.  And once a stub has been called,
5709 ;; we must not call it again.
5711 ;; We represent this restriction using an imaginary fixed register that
5712 ;; acts like a GOT version number.  By making the register call-clobbered,
5713 ;; we tell the target-independent code that the address could be changed
5714 ;; by any call insn.
5715 (define_insn "load_call<mode>"
5716   [(set (match_operand:P 0 "register_operand" "=c")
5717         (unspec:P [(match_operand:P 1 "register_operand" "r")
5718                    (match_operand:P 2 "immediate_operand" "")
5719                    (reg:P FAKE_CALL_REGNO)]
5720                   UNSPEC_LOAD_CALL))]
5721   "TARGET_ABICALLS"
5722   "<load>\t%0,%R2(%1)"
5723   [(set_attr "type" "load")
5724    (set_attr "mode" "<MODE>")
5725    (set_attr "length" "4")])
5727 ;; Sibling calls.  All these patterns use jump instructions.
5729 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
5730 ;; addresses if a direct jump is acceptable.  Since the 'S' constraint
5731 ;; is defined in terms of call_insn_operand, the same is true of the
5732 ;; constraints.
5734 ;; When we use an indirect jump, we need a register that will be
5735 ;; preserved by the epilogue.  Since TARGET_ABICALLS forces us to
5736 ;; use $25 for this purpose -- and $25 is never clobbered by the
5737 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
5739 (define_expand "sibcall"
5740   [(parallel [(call (match_operand 0 "")
5741                     (match_operand 1 ""))
5742               (use (match_operand 2 ""))        ;; next_arg_reg
5743               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
5744   "TARGET_SIBCALLS"
5746   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
5747   DONE;
5750 (define_insn "sibcall_internal"
5751   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
5752          (match_operand 1 "" ""))]
5753   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5754   "@
5755     %*jr\t%0%/
5756     %*j\t%0%/"
5757   [(set_attr "type" "call")])
5759 (define_expand "sibcall_value"
5760   [(parallel [(set (match_operand 0 "")
5761                    (call (match_operand 1 "")
5762                          (match_operand 2 "")))
5763               (use (match_operand 3 ""))])]             ;; next_arg_reg
5764   "TARGET_SIBCALLS"
5766   mips_expand_call (operands[0], XEXP (operands[1], 0),
5767                     operands[2], operands[3], true);
5768   DONE;
5771 (define_insn "sibcall_value_internal"
5772   [(set (match_operand 0 "register_operand" "=df,df")
5773         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5774               (match_operand 2 "" "")))]
5775   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5776   "@
5777     %*jr\t%1%/
5778     %*j\t%1%/"
5779   [(set_attr "type" "call")])
5781 (define_insn "sibcall_value_multiple_internal"
5782   [(set (match_operand 0 "register_operand" "=df,df")
5783         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5784               (match_operand 2 "" "")))
5785    (set (match_operand 3 "register_operand" "=df,df")
5786         (call (mem:SI (match_dup 1))
5787               (match_dup 2)))]
5788   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5789   "@
5790     %*jr\t%1%/
5791     %*j\t%1%/"
5792   [(set_attr "type" "call")])
5794 (define_expand "call"
5795   [(parallel [(call (match_operand 0 "")
5796                     (match_operand 1 ""))
5797               (use (match_operand 2 ""))        ;; next_arg_reg
5798               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
5799   ""
5801   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
5802   DONE;
5805 ;; This instruction directly corresponds to an assembly-language "jal".
5806 ;; There are four cases:
5808 ;;    - -mno-abicalls:
5809 ;;        Both symbolic and register destinations are OK.  The pattern
5810 ;;        always expands to a single mips instruction.
5812 ;;    - -mabicalls/-mno-explicit-relocs:
5813 ;;        Again, both symbolic and register destinations are OK.
5814 ;;        The call is treated as a multi-instruction black box.
5816 ;;    - -mabicalls/-mexplicit-relocs with n32 or n64:
5817 ;;        Only "jal $25" is allowed.  This expands to a single "jalr $25"
5818 ;;        instruction.
5820 ;;    - -mabicalls/-mexplicit-relocs with o32 or o64:
5821 ;;        Only "jal $25" is allowed.  The call is actually two instructions:
5822 ;;        "jalr $25" followed by an insn to reload $gp.
5824 ;; In the last case, we can generate the individual instructions with
5825 ;; a define_split.  There are several things to be wary of:
5827 ;;   - We can't expose the load of $gp before reload.  If we did,
5828 ;;     it might get removed as dead, but reload can introduce new
5829 ;;     uses of $gp by rematerializing constants.
5831 ;;   - We shouldn't restore $gp after calls that never return.
5832 ;;     It isn't valid to insert instructions between a noreturn
5833 ;;     call and the following barrier.
5835 ;;   - The splitter deliberately changes the liveness of $gp.  The unsplit
5836 ;;     instruction preserves $gp and so have no effect on its liveness.
5837 ;;     But once we generate the separate insns, it becomes obvious that
5838 ;;     $gp is not live on entry to the call.
5840 ;; ??? The operands[2] = insn check is a hack to make the original insn
5841 ;; available to the splitter.
5842 (define_insn_and_split "call_internal"
5843   [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
5844          (match_operand 1 "" ""))
5845    (clobber (reg:SI 31))]
5846   ""
5847   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
5848   "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
5849   [(const_int 0)]
5851   emit_call_insn (gen_call_split (operands[0], operands[1]));
5852   if (!find_reg_note (operands[2], REG_NORETURN, 0))
5853     mips_restore_gp ();
5854   DONE;
5856   [(set_attr "jal" "indirect,direct")
5857    (set_attr "extended_mips16" "no,yes")])
5859 (define_insn "call_split"
5860   [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
5861          (match_operand 1 "" ""))
5862    (clobber (reg:SI 31))
5863    (clobber (reg:SI 28))]
5864   "TARGET_SPLIT_CALLS"
5865   "%*jalr\t%0%/"
5866   [(set_attr "type" "call")])
5868 (define_expand "call_value"
5869   [(parallel [(set (match_operand 0 "")
5870                    (call (match_operand 1 "")
5871                          (match_operand 2 "")))
5872               (use (match_operand 3 ""))])]             ;; next_arg_reg
5873   ""
5875   mips_expand_call (operands[0], XEXP (operands[1], 0),
5876                     operands[2], operands[3], false);
5877   DONE;
5880 ;; See comment for call_internal.
5881 (define_insn_and_split "call_value_internal"
5882   [(set (match_operand 0 "register_operand" "=df,df")
5883         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5884               (match_operand 2 "" "")))
5885    (clobber (reg:SI 31))]
5886   ""
5887   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
5888   "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
5889   [(const_int 0)]
5891   emit_call_insn (gen_call_value_split (operands[0], operands[1],
5892                                         operands[2]));
5893   if (!find_reg_note (operands[3], REG_NORETURN, 0))
5894     mips_restore_gp ();
5895   DONE;
5897   [(set_attr "jal" "indirect,direct")
5898    (set_attr "extended_mips16" "no,yes")])
5900 (define_insn "call_value_split"
5901   [(set (match_operand 0 "register_operand" "=df")
5902         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
5903               (match_operand 2 "" "")))
5904    (clobber (reg:SI 31))
5905    (clobber (reg:SI 28))]
5906   "TARGET_SPLIT_CALLS"
5907   "%*jalr\t%1%/"
5908   [(set_attr "type" "call")])
5910 ;; See comment for call_internal.
5911 (define_insn_and_split "call_value_multiple_internal"
5912   [(set (match_operand 0 "register_operand" "=df,df")
5913         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5914               (match_operand 2 "" "")))
5915    (set (match_operand 3 "register_operand" "=df,df")
5916         (call (mem:SI (match_dup 1))
5917               (match_dup 2)))
5918    (clobber (reg:SI 31))]
5919   ""
5920   { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
5921   "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
5922   [(const_int 0)]
5924   emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
5925                                                  operands[2], operands[3]));
5926   if (!find_reg_note (operands[4], REG_NORETURN, 0))
5927     mips_restore_gp ();
5928   DONE;
5930   [(set_attr "jal" "indirect,direct")
5931    (set_attr "extended_mips16" "no,yes")])
5933 (define_insn "call_value_multiple_split"
5934   [(set (match_operand 0 "register_operand" "=df")
5935         (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
5936               (match_operand 2 "" "")))
5937    (set (match_operand 3 "register_operand" "=df")
5938         (call (mem:SI (match_dup 1))
5939               (match_dup 2)))
5940    (clobber (reg:SI 31))
5941    (clobber (reg:SI 28))]
5942   "TARGET_SPLIT_CALLS"
5943   "%*jalr\t%1%/"
5944   [(set_attr "type" "call")])
5946 ;; Call subroutine returning any type.
5948 (define_expand "untyped_call"
5949   [(parallel [(call (match_operand 0 "")
5950                     (const_int 0))
5951               (match_operand 1 "")
5952               (match_operand 2 "")])]
5953   ""
5955   int i;
5957   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
5959   for (i = 0; i < XVECLEN (operands[2], 0); i++)
5960     {
5961       rtx set = XVECEXP (operands[2], 0, i);
5962       emit_move_insn (SET_DEST (set), SET_SRC (set));
5963     }
5965   emit_insn (gen_blockage ());
5966   DONE;
5970 ;;  ....................
5972 ;;      MISC.
5974 ;;  ....................
5978 (define_expand "prefetch"
5979   [(prefetch (match_operand 0 "address_operand")
5980              (match_operand 1 "const_int_operand")
5981              (match_operand 2 "const_int_operand"))]
5982   "ISA_HAS_PREFETCH"
5984   if (symbolic_operand (operands[0], GET_MODE (operands[0])))
5985     operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
5988 (define_insn "prefetch_si_address"
5989   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
5990                       (match_operand:SI 3 "const_int_operand" "I"))
5991              (match_operand:SI 1 "const_int_operand" "n")
5992              (match_operand:SI 2 "const_int_operand" "n"))]
5993   "ISA_HAS_PREFETCH && Pmode == SImode"
5994   { return mips_emit_prefetch (operands); }
5995   [(set_attr "type" "prefetch")])
5997 (define_insn "prefetch_indexed_si"
5998   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
5999                       (match_operand:SI 3 "register_operand" "r"))
6000              (match_operand:SI 1 "const_int_operand" "n")
6001              (match_operand:SI 2 "const_int_operand" "n"))]
6002   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
6003   { return mips_emit_prefetch (operands); }
6004   [(set_attr "type" "prefetchx")])
6006 (define_insn "prefetch_si"
6007   [(prefetch (match_operand:SI 0 "register_operand" "r")
6008              (match_operand:SI 1 "const_int_operand" "n")
6009              (match_operand:SI 2 "const_int_operand" "n"))]
6010   "ISA_HAS_PREFETCH && Pmode == SImode"
6012   operands[3] = const0_rtx;
6013   return mips_emit_prefetch (operands);
6015   [(set_attr "type" "prefetch")])
6017 (define_insn "prefetch_di_address"
6018   [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
6019                       (match_operand:DI 3 "const_int_operand" "I"))
6020              (match_operand:DI 1 "const_int_operand" "n")
6021              (match_operand:DI 2 "const_int_operand" "n"))]
6022   "ISA_HAS_PREFETCH && Pmode == DImode"
6023   { return mips_emit_prefetch (operands); }
6024   [(set_attr "type" "prefetch")])
6026 (define_insn "prefetch_indexed_di"
6027   [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
6028                       (match_operand:DI 3 "register_operand" "r"))
6029              (match_operand:DI 1 "const_int_operand" "n")
6030              (match_operand:DI 2 "const_int_operand" "n"))]
6031   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
6032   { return mips_emit_prefetch (operands); }
6033   [(set_attr "type" "prefetchx")])
6035 (define_insn "prefetch_di"
6036   [(prefetch (match_operand:DI 0 "register_operand" "r")
6037              (match_operand:DI 1 "const_int_operand" "n")
6038              (match_operand:DI 2 "const_int_operand" "n"))]
6039   "ISA_HAS_PREFETCH && Pmode == DImode"
6041   operands[3] = const0_rtx;
6042   return mips_emit_prefetch (operands);
6044   [(set_attr "type" "prefetch")])
6046 (define_insn "nop"
6047   [(const_int 0)]
6048   ""
6049   "%(nop%)"
6050   [(set_attr "type"     "nop")
6051    (set_attr "mode"     "none")])
6053 ;; Like nop, but commented out when outside a .set noreorder block.
6054 (define_insn "hazard_nop"
6055   [(const_int 1)]
6056   ""
6057   {
6058     if (set_noreorder)
6059       return "nop";
6060     else
6061       return "#nop";
6062   }
6063   [(set_attr "type"     "nop")])
6065 ;; MIPS4 Conditional move instructions.
6067 (define_insn ""
6068   [(set (match_operand:SI 0 "register_operand" "=d,d")
6069         (if_then_else:SI
6070          (match_operator:SI 4 "equality_operator"
6071                             [(match_operand:SI 1 "register_operand" "d,d")
6072                              (const_int 0)])
6073          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
6074          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
6075   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
6076   "@
6077     mov%B4\t%0,%z2,%1
6078     mov%b4\t%0,%z3,%1"
6079   [(set_attr "type" "condmove")
6080    (set_attr "mode" "SI")])
6082 (define_insn ""
6083   [(set (match_operand:SI 0 "register_operand" "=d,d")
6084         (if_then_else:SI
6085          (match_operator:DI 4 "equality_operator"
6086                             [(match_operand:DI 1 "register_operand" "d,d")
6087                              (const_int 0)])
6088          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
6089          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
6090   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
6091   "@
6092     mov%B4\t%0,%z2,%1
6093     mov%b4\t%0,%z3,%1"
6094   [(set_attr "type" "condmove")
6095    (set_attr "mode" "SI")])
6097 (define_insn ""
6098   [(set (match_operand:SI 0 "register_operand" "=d,d")
6099         (if_then_else:SI
6100          (match_operator:CC 3 "equality_operator"
6101                             [(match_operand:CC 4 "register_operand" "z,z")
6102                              (const_int 0)])
6103          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
6104          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
6105   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6106   "@
6107     mov%T3\t%0,%z1,%4
6108     mov%t3\t%0,%z2,%4"
6109   [(set_attr "type" "condmove")
6110    (set_attr "mode" "SI")])
6112 (define_insn ""
6113   [(set (match_operand:DI 0 "register_operand" "=d,d")
6114         (if_then_else:DI
6115          (match_operator:SI 4 "equality_operator"
6116                             [(match_operand:SI 1 "register_operand" "d,d")
6117                              (const_int 0)])
6118          (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
6119          (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
6120   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
6121   "@
6122     mov%B4\t%0,%z2,%1
6123     mov%b4\t%0,%z3,%1"
6124   [(set_attr "type" "condmove")
6125    (set_attr "mode" "DI")])
6127 (define_insn ""
6128   [(set (match_operand:DI 0 "register_operand" "=d,d")
6129         (if_then_else:DI
6130          (match_operator:DI 4 "equality_operator"
6131                             [(match_operand:DI 1 "register_operand" "d,d")
6132                              (const_int 0)])
6133          (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
6134          (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
6135   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
6136   "@
6137     mov%B4\t%0,%z2,%1
6138     mov%b4\t%0,%z3,%1"
6139   [(set_attr "type" "condmove")
6140    (set_attr "mode" "DI")])
6142 (define_insn ""
6143   [(set (match_operand:DI 0 "register_operand" "=d,d")
6144         (if_then_else:DI
6145          (match_operator:CC 3 "equality_operator"
6146                             [(match_operand:CC 4 "register_operand" "z,z")
6147                              (const_int 0)])
6148          (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
6149          (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
6150   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
6151   "@
6152     mov%T3\t%0,%z1,%4
6153     mov%t3\t%0,%z2,%4"
6154   [(set_attr "type" "condmove")
6155    (set_attr "mode" "DI")])
6157 (define_insn ""
6158   [(set (match_operand:SF 0 "register_operand" "=f,f")
6159         (if_then_else:SF
6160          (match_operator:SI 4 "equality_operator"
6161                             [(match_operand:SI 1 "register_operand" "d,d")
6162                              (const_int 0)])
6163          (match_operand:SF 2 "register_operand" "f,0")
6164          (match_operand:SF 3 "register_operand" "0,f")))]
6165   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6166   "@
6167     mov%B4.s\t%0,%2,%1
6168     mov%b4.s\t%0,%3,%1"
6169   [(set_attr "type" "condmove")
6170    (set_attr "mode" "SF")])
6172 (define_insn ""
6173   [(set (match_operand:SF 0 "register_operand" "=f,f")
6174         (if_then_else:SF
6175          (match_operator:DI 4 "equality_operator"
6176                             [(match_operand:DI 1 "register_operand" "d,d")
6177                              (const_int 0)])
6178          (match_operand:SF 2 "register_operand" "f,0")
6179          (match_operand:SF 3 "register_operand" "0,f")))]
6180   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6181   "@
6182     mov%B4.s\t%0,%2,%1
6183     mov%b4.s\t%0,%3,%1"
6184   [(set_attr "type" "condmove")
6185    (set_attr "mode" "SF")])
6187 (define_insn ""
6188   [(set (match_operand:SF 0 "register_operand" "=f,f")
6189         (if_then_else:SF
6190          (match_operator:CC 3 "equality_operator"
6191                             [(match_operand:CC 4 "register_operand" "z,z")
6192                              (const_int 0)])
6193          (match_operand:SF 1 "register_operand" "f,0")
6194          (match_operand:SF 2 "register_operand" "0,f")))]
6195   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6196   "@
6197     mov%T3.s\t%0,%1,%4
6198     mov%t3.s\t%0,%2,%4"
6199   [(set_attr "type" "condmove")
6200    (set_attr "mode" "SF")])
6202 (define_insn ""
6203   [(set (match_operand:DF 0 "register_operand" "=f,f")
6204         (if_then_else:DF
6205          (match_operator:SI 4 "equality_operator"
6206                             [(match_operand:SI 1 "register_operand" "d,d")
6207                              (const_int 0)])
6208          (match_operand:DF 2 "register_operand" "f,0")
6209          (match_operand:DF 3 "register_operand" "0,f")))]
6210   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6211   "@
6212     mov%B4.d\t%0,%2,%1
6213     mov%b4.d\t%0,%3,%1"
6214   [(set_attr "type" "condmove")
6215    (set_attr "mode" "DF")])
6217 (define_insn ""
6218   [(set (match_operand:DF 0 "register_operand" "=f,f")
6219         (if_then_else:DF
6220          (match_operator:DI 4 "equality_operator"
6221                             [(match_operand:DI 1 "register_operand" "d,d")
6222                              (const_int 0)])
6223          (match_operand:DF 2 "register_operand" "f,0")
6224          (match_operand:DF 3 "register_operand" "0,f")))]
6225   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6226   "@
6227     mov%B4.d\t%0,%2,%1
6228     mov%b4.d\t%0,%3,%1"
6229   [(set_attr "type" "condmove")
6230    (set_attr "mode" "DF")])
6232 (define_insn ""
6233   [(set (match_operand:DF 0 "register_operand" "=f,f")
6234         (if_then_else:DF
6235          (match_operator:CC 3 "equality_operator"
6236                             [(match_operand:CC 4 "register_operand" "z,z")
6237                              (const_int 0)])
6238          (match_operand:DF 1 "register_operand" "f,0")
6239          (match_operand:DF 2 "register_operand" "0,f")))]
6240   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6241   "@
6242     mov%T3.d\t%0,%1,%4
6243     mov%t3.d\t%0,%2,%4"
6244   [(set_attr "type" "condmove")
6245    (set_attr "mode" "DF")])
6247 ;; These are the main define_expand's used to make conditional moves.
6249 (define_expand "movsicc"
6250   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6251    (set (match_operand:SI 0 "register_operand")
6252         (if_then_else:SI (match_dup 5)
6253                          (match_operand:SI 2 "reg_or_0_operand")
6254                          (match_operand:SI 3 "reg_or_0_operand")))]
6255   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
6257   gen_conditional_move (operands);
6258   DONE;
6261 (define_expand "movdicc"
6262   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6263    (set (match_operand:DI 0 "register_operand")
6264         (if_then_else:DI (match_dup 5)
6265                          (match_operand:DI 2 "reg_or_0_operand")
6266                          (match_operand:DI 3 "reg_or_0_operand")))]
6267   "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
6269   gen_conditional_move (operands);
6270   DONE;
6273 (define_expand "movsfcc"
6274   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6275    (set (match_operand:SF 0 "register_operand")
6276         (if_then_else:SF (match_dup 5)
6277                          (match_operand:SF 2 "register_operand")
6278                          (match_operand:SF 3 "register_operand")))]
6279   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6281   gen_conditional_move (operands);
6282   DONE;
6285 (define_expand "movdfcc"
6286   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6287    (set (match_operand:DF 0 "register_operand")
6288         (if_then_else:DF (match_dup 5)
6289                          (match_operand:DF 2 "register_operand")
6290                          (match_operand:DF 3 "register_operand")))]
6291   "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6293   gen_conditional_move (operands);
6294   DONE;
6298 ;;  ....................
6300 ;;      mips16 inline constant tables
6302 ;;  ....................
6305 (define_insn "consttable_int"
6306   [(unspec_volatile [(match_operand 0 "consttable_operand" "")
6307                      (match_operand 1 "const_int_operand" "")]
6308                     UNSPEC_CONSTTABLE_INT)]
6309   "TARGET_MIPS16"
6311   assemble_integer (operands[0], INTVAL (operands[1]),
6312                     BITS_PER_UNIT * INTVAL (operands[1]), 1);
6313   return "";
6315   [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
6317 (define_insn "consttable_float"
6318   [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
6319                     UNSPEC_CONSTTABLE_FLOAT)]
6320   "TARGET_MIPS16"
6322   REAL_VALUE_TYPE d;
6324   if (GET_CODE (operands[0]) != CONST_DOUBLE)
6325     abort ();
6326   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
6327   assemble_real (d, GET_MODE (operands[0]),
6328                  GET_MODE_BITSIZE (GET_MODE (operands[0])));
6329   return "";
6331   [(set (attr "length")
6332         (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
6334 (define_insn "align"
6335   [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
6336   ""
6337   ".align\t%0"
6338   [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
6340 (define_split
6341   [(match_operand 0 "small_data_pattern")]
6342   "reload_completed"
6343   [(match_dup 0)]
6344   { operands[0] = mips_rewrite_small_data (operands[0]); })