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)
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.
27 [(UNSPEC_LOAD_DF_LOW 0)
28 (UNSPEC_LOAD_DF_HIGH 1)
29 (UNSPEC_STORE_DF_HIGH 2)
33 (UNSPEC_EH_RECEIVER 6)
35 (UNSPEC_CONSTTABLE_INT 8)
36 (UNSPEC_CONSTTABLE_FLOAT 9)
53 (UNSPEC_ADDRESS_FIRST 100)
55 (FAKE_CALL_REGNO 79)])
57 (include "predicates.md")
59 ;; ....................
63 ;; ....................
65 (define_attr "got" "unset,xgot_high,load"
66 (const_string "unset"))
68 ;; For jal instructions, this attribute is DIRECT when the target address
69 ;; is symbolic and INDIRECT when it is a register.
70 (define_attr "jal" "unset,direct,indirect"
71 (const_string "unset"))
73 ;; This attribute is YES if the instruction is a jal macro (not a
74 ;; real jal instruction).
76 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
77 ;; restore $gp. Direct jals are also macros in NewABI PIC since they
78 ;; load the target address into $25.
79 (define_attr "jal_macro" "no,yes"
80 (cond [(eq_attr "jal" "direct")
81 (symbol_ref "TARGET_ABICALLS != 0")
82 (eq_attr "jal" "indirect")
83 (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
86 ;; Classification of each insn.
87 ;; branch conditional branch
88 ;; jump unconditional jump
89 ;; call unconditional call
90 ;; load load instruction(s)
91 ;; fpload floating point load
92 ;; fpidxload floating point indexed load
93 ;; store store instruction(s)
94 ;; fpstore floating point store
95 ;; fpidxstore floating point indexed store
96 ;; prefetch memory prefetch (register + offset)
97 ;; prefetchx memory indexed prefetch (register + register)
98 ;; condmove conditional moves
99 ;; xfer transfer to/from coprocessor
100 ;; mthilo transfer to hi/lo registers
101 ;; mfhilo transfer from hi/lo registers
102 ;; const load constant
103 ;; arith integer arithmetic and logical instructions
104 ;; shift integer shift instructions
105 ;; slt set less than instructions
106 ;; clz the clz and clo instructions
107 ;; trap trap if instructions
108 ;; imul integer multiply
109 ;; imadd integer multiply-add
110 ;; idiv integer divide
111 ;; fmove floating point register move
112 ;; fadd floating point add/subtract
113 ;; fmul floating point multiply
114 ;; fmadd floating point multiply-add
115 ;; fdiv floating point divide
116 ;; frdiv floating point reciprocal divide
117 ;; fabs floating point absolute value
118 ;; fneg floating point negation
119 ;; fcmp floating point compare
120 ;; fcvt floating point convert
121 ;; fsqrt floating point square root
122 ;; frsqrt floating point reciprocal square root
123 ;; multi multiword sequence (or user asm statements)
126 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,frdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
127 (cond [(eq_attr "jal" "!unset") (const_string "call")
128 (eq_attr "got" "load") (const_string "load")]
129 (const_string "unknown")))
131 ;; Main data type used by the insn
132 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
133 (const_string "unknown"))
135 ;; Is this an extended instruction in mips16 mode?
136 (define_attr "extended_mips16" "no,yes"
139 ;; Length of instruction in bytes.
140 (define_attr "length" ""
141 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
142 ;; If a branch is outside this range, we have a choice of two
143 ;; sequences. For PIC, an out-of-range branch like:
148 ;; becomes the equivalent of:
157 ;; where the load address can be up to three instructions long
160 ;; The non-PIC case is similar except that we use a direct
161 ;; jump instead of an la/jr pair. Since the target of this
162 ;; jump is an absolute 28-bit bit address (the other bits
163 ;; coming from the address of the delay slot) this form cannot
164 ;; cross a 256MB boundary. We could provide the option of
165 ;; using la/jr in this case too, but we do not do so at
168 ;; Note that this value does not account for the delay slot
169 ;; instruction, whose length is added separately. If the RTL
170 ;; pattern has no explicit delay slot, mips_adjust_insn_length
171 ;; will add the length of the implicit nop. The values for
172 ;; forward and backward branches will be different as well.
173 (eq_attr "type" "branch")
174 (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
175 (le (minus (pc) (match_dup 1)) (const_int 131068)))
177 (ne (symbol_ref "flag_pic") (const_int 0))
181 (eq_attr "got" "load")
183 (eq_attr "got" "xgot_high")
186 (eq_attr "type" "const")
187 (symbol_ref "mips_const_insns (operands[1]) * 4")
188 (eq_attr "type" "load,fpload,fpidxload")
189 (symbol_ref "mips_fetch_insns (operands[1]) * 4")
190 (eq_attr "type" "store,fpstore,fpidxstore")
191 (symbol_ref "mips_fetch_insns (operands[0]) * 4")
193 ;; In the worst case, a call macro will take 8 instructions:
195 ;; lui $25,%call_hi(FOO)
197 ;; lw $25,%call_lo(FOO)($25)
203 (eq_attr "jal_macro" "yes")
206 (and (eq_attr "extended_mips16" "yes")
207 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
210 ;; Various VR4120 errata require a nop to be inserted after a macc
211 ;; instruction. The assembler does this for us, so account for
212 ;; the worst-case length here.
213 (and (eq_attr "type" "imadd")
214 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
217 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
218 ;; the result of the second one is missed. The assembler should work
219 ;; around this by inserting a nop after the first dmult.
220 (and (eq_attr "type" "imul")
221 (and (eq_attr "mode" "DI")
222 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
225 (eq_attr "type" "idiv")
226 (symbol_ref "mips_idiv_insns () * 4")
229 ;; Attribute describing the processor. This attribute must match exactly
230 ;; with the processor_type enumeration in mips.h.
232 "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
233 (const (symbol_ref "mips_tune")))
235 ;; The type of hardware hazard associated with this instruction.
236 ;; DELAY means that the next instruction cannot read the result
237 ;; of this one. HILO means that the next two instructions cannot
238 ;; write to HI or LO.
239 (define_attr "hazard" "none,delay,hilo"
240 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
241 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
242 (const_string "delay")
244 (and (eq_attr "type" "xfer")
245 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
246 (const_string "delay")
248 (and (eq_attr "type" "fcmp")
249 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
250 (const_string "delay")
252 ;; The r4000 multiplication patterns include an mflo instruction.
253 (and (eq_attr "type" "imul")
254 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
255 (const_string "hilo")
257 (and (eq_attr "type" "mfhilo")
258 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
259 (const_string "hilo")]
260 (const_string "none")))
262 ;; Is it a single instruction?
263 (define_attr "single_insn" "no,yes"
264 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
266 ;; Can the instruction be put into a delay slot?
267 (define_attr "can_delay" "no,yes"
268 (if_then_else (and (eq_attr "type" "!branch,call,jump")
269 (and (eq_attr "hazard" "none")
270 (eq_attr "single_insn" "yes")))
272 (const_string "no")))
274 ;; Attribute defining whether or not we can use the branch-likely instructions
275 (define_attr "branch_likely" "no,yes"
277 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
279 (const_string "no"))))
281 ;; True if an instruction might assign to hi or lo when reloaded.
282 ;; This is used by the TUNE_MACC_CHAINS code.
283 (define_attr "may_clobber_hilo" "no,yes"
284 (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
286 (const_string "no")))
288 ;; Describe a user's asm statement.
289 (define_asm_attributes
290 [(set_attr "type" "multi")])
292 ;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
293 ;; from the same template.
294 (define_mode_macro GPR [SI (DI "TARGET_64BIT")])
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 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
301 ;; are different. Some forms of unextended addiu have an 8-bit immediate
302 ;; field but the equivalent daddiu has only a 5-bit field.
303 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
305 ;; This code macro allows all branch instructions to be generated from
306 ;; a single define_expand template.
307 (define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
308 eq ne gt ge lt le gtu geu ltu leu])
310 ;; .........................
312 ;; Branch, call and jump delay slots
314 ;; .........................
316 (define_delay (and (eq_attr "type" "branch")
317 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
318 [(eq_attr "can_delay" "yes")
320 (and (eq_attr "branch_likely" "yes")
321 (eq_attr "can_delay" "yes"))])
323 (define_delay (eq_attr "type" "jump")
324 [(eq_attr "can_delay" "yes")
328 (define_delay (and (eq_attr "type" "call")
329 (eq_attr "jal_macro" "no"))
330 [(eq_attr "can_delay" "yes")
334 ;; Pipeline descriptions.
336 ;; generic.md provides a fallback for processors without a specific
337 ;; pipeline description. It is derived from the old define_function_unit
338 ;; version and uses the "alu" and "imuldiv" units declared below.
340 ;; Some of the processor-specific files are also derived from old
341 ;; define_function_unit descriptions and simply override the parts of
342 ;; generic.md that don't apply. The other processor-specific files
343 ;; are self-contained.
344 (define_automaton "alu,imuldiv")
346 (define_cpu_unit "alu" "alu")
347 (define_cpu_unit "imuldiv" "imuldiv")
363 (include "generic.md")
366 ;; ....................
370 ;; ....................
374 [(trap_if (const_int 1) (const_int 0))]
377 if (ISA_HAS_COND_TRAP)
379 /* The IRIX 6 O32 assembler requires the first break operand. */
380 else if (TARGET_MIPS16 || !TARGET_GAS)
385 [(set_attr "type" "trap")])
387 (define_expand "conditional_trap"
388 [(trap_if (match_operator 0 "comparison_operator"
389 [(match_dup 2) (match_dup 3)])
390 (match_operand 1 "const_int_operand"))]
393 if (operands[1] == const0_rtx)
395 mips_gen_conditional_trap (operands);
403 [(trap_if (match_operator 0 "trap_comparison_operator"
404 [(match_operand:SI 1 "reg_or_0_operand" "dJ")
405 (match_operand:SI 2 "arith_operand" "dI")])
409 [(set_attr "type" "trap")])
412 [(trap_if (match_operator 0 "trap_comparison_operator"
413 [(match_operand:DI 1 "reg_or_0_operand" "dJ")
414 (match_operand:DI 2 "arith_operand" "dI")])
416 "TARGET_64BIT && ISA_HAS_COND_TRAP"
418 [(set_attr "type" "trap")])
421 ;; ....................
425 ;; ....................
428 (define_insn "adddf3"
429 [(set (match_operand:DF 0 "register_operand" "=f")
430 (plus:DF (match_operand:DF 1 "register_operand" "f")
431 (match_operand:DF 2 "register_operand" "f")))]
432 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
434 [(set_attr "type" "fadd")
435 (set_attr "mode" "DF")])
437 (define_insn "addsf3"
438 [(set (match_operand:SF 0 "register_operand" "=f")
439 (plus:SF (match_operand:SF 1 "register_operand" "f")
440 (match_operand:SF 2 "register_operand" "f")))]
443 [(set_attr "type" "fadd")
444 (set_attr "mode" "SF")])
446 (define_expand "add<mode>3"
447 [(set (match_operand:GPR 0 "register_operand")
448 (plus:GPR (match_operand:GPR 1 "register_operand")
449 (match_operand:GPR 2 "arith_operand")))]
452 (define_insn "*add<mode>3"
453 [(set (match_operand:GPR 0 "register_operand" "=d,d")
454 (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
455 (match_operand:GPR 2 "arith_operand" "d,Q")))]
460 [(set_attr "type" "arith")
461 (set_attr "mode" "<MODE>")])
463 ;; We need to recognize MIPS16 stack pointer additions explicitly, since
464 ;; we don't have a constraint for $sp. These insns will be generated by
465 ;; the save_restore_insns functions.
467 (define_insn "*add<mode>3_sp1"
469 (plus:GPR (reg:GPR 29)
470 (match_operand:GPR 0 "const_arith_operand" "")))]
473 [(set_attr "type" "arith")
474 (set_attr "mode" "<MODE>")
475 (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
479 (define_insn "*add<mode>3_sp2"
480 [(set (match_operand:GPR 0 "register_operand" "=d")
481 (plus:GPR (reg:GPR 29)
482 (match_operand:GPR 1 "const_arith_operand" "")))]
485 [(set_attr "type" "arith")
486 (set_attr "mode" "<MODE>")
487 (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
491 (define_insn "*add<mode>3_mips16"
492 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
493 (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
494 (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
500 [(set_attr "type" "arith")
501 (set_attr "mode" "<MODE>")
502 (set_attr_alternative "length"
503 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
506 (if_then_else (match_operand 2 "m16_simm4_1")
512 ;; On the mips16, we can sometimes split an add of a constant which is
513 ;; a 4 byte instruction into two adds which are both 2 byte
514 ;; instructions. There are two cases: one where we are adding a
515 ;; constant plus a register to another register, and one where we are
516 ;; simply adding a constant to a register.
519 [(set (match_operand:SI 0 "register_operand")
520 (plus:SI (match_dup 0)
521 (match_operand:SI 1 "const_int_operand")))]
522 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
523 && GET_CODE (operands[0]) == REG
524 && M16_REG_P (REGNO (operands[0]))
525 && GET_CODE (operands[1]) == CONST_INT
526 && ((INTVAL (operands[1]) > 0x7f
527 && INTVAL (operands[1]) <= 0x7f + 0x7f)
528 || (INTVAL (operands[1]) < - 0x80
529 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
530 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
531 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
533 HOST_WIDE_INT val = INTVAL (operands[1]);
537 operands[1] = GEN_INT (0x7f);
538 operands[2] = GEN_INT (val - 0x7f);
542 operands[1] = GEN_INT (- 0x80);
543 operands[2] = GEN_INT (val + 0x80);
548 [(set (match_operand:SI 0 "register_operand")
549 (plus:SI (match_operand:SI 1 "register_operand")
550 (match_operand:SI 2 "const_int_operand")))]
551 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
552 && GET_CODE (operands[0]) == REG
553 && M16_REG_P (REGNO (operands[0]))
554 && GET_CODE (operands[1]) == REG
555 && M16_REG_P (REGNO (operands[1]))
556 && REGNO (operands[0]) != REGNO (operands[1])
557 && GET_CODE (operands[2]) == CONST_INT
558 && ((INTVAL (operands[2]) > 0x7
559 && INTVAL (operands[2]) <= 0x7 + 0x7f)
560 || (INTVAL (operands[2]) < - 0x8
561 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
562 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
563 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
565 HOST_WIDE_INT val = INTVAL (operands[2]);
569 operands[2] = GEN_INT (0x7);
570 operands[3] = GEN_INT (val - 0x7);
574 operands[2] = GEN_INT (- 0x8);
575 operands[3] = GEN_INT (val + 0x8);
580 [(set (match_operand:DI 0 "register_operand")
581 (plus:DI (match_dup 0)
582 (match_operand:DI 1 "const_int_operand")))]
583 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
584 && GET_CODE (operands[0]) == REG
585 && M16_REG_P (REGNO (operands[0]))
586 && GET_CODE (operands[1]) == CONST_INT
587 && ((INTVAL (operands[1]) > 0xf
588 && INTVAL (operands[1]) <= 0xf + 0xf)
589 || (INTVAL (operands[1]) < - 0x10
590 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
591 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
592 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
594 HOST_WIDE_INT val = INTVAL (operands[1]);
598 operands[1] = GEN_INT (0xf);
599 operands[2] = GEN_INT (val - 0xf);
603 operands[1] = GEN_INT (- 0x10);
604 operands[2] = GEN_INT (val + 0x10);
609 [(set (match_operand:DI 0 "register_operand")
610 (plus:DI (match_operand:DI 1 "register_operand")
611 (match_operand:DI 2 "const_int_operand")))]
612 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
613 && GET_CODE (operands[0]) == REG
614 && M16_REG_P (REGNO (operands[0]))
615 && GET_CODE (operands[1]) == REG
616 && M16_REG_P (REGNO (operands[1]))
617 && REGNO (operands[0]) != REGNO (operands[1])
618 && GET_CODE (operands[2]) == CONST_INT
619 && ((INTVAL (operands[2]) > 0x7
620 && INTVAL (operands[2]) <= 0x7 + 0xf)
621 || (INTVAL (operands[2]) < - 0x8
622 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
623 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
624 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
626 HOST_WIDE_INT val = INTVAL (operands[2]);
630 operands[2] = GEN_INT (0x7);
631 operands[3] = GEN_INT (val - 0x7);
635 operands[2] = GEN_INT (- 0x8);
636 operands[3] = GEN_INT (val + 0x8);
640 (define_insn "*addsi3_extended"
641 [(set (match_operand:DI 0 "register_operand" "=d,d")
643 (plus:SI (match_operand:SI 1 "register_operand" "d,d")
644 (match_operand:SI 2 "arith_operand" "d,Q"))))]
645 "TARGET_64BIT && !TARGET_MIPS16"
649 [(set_attr "type" "arith")
650 (set_attr "mode" "SI")])
652 ;; Split this insn so that the addiu splitters can have a crack at it.
653 ;; Use a conservative length estimate until the split.
654 (define_insn_and_split "*addsi3_extended_mips16"
655 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
657 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
658 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
659 "TARGET_64BIT && TARGET_MIPS16"
661 "&& reload_completed"
662 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
663 { operands[3] = gen_lowpart (SImode, operands[0]); }
664 [(set_attr "type" "arith")
665 (set_attr "mode" "SI")
666 (set_attr "extended_mips16" "yes")])
669 ;; ....................
673 ;; ....................
676 (define_insn "subdf3"
677 [(set (match_operand:DF 0 "register_operand" "=f")
678 (minus:DF (match_operand:DF 1 "register_operand" "f")
679 (match_operand:DF 2 "register_operand" "f")))]
680 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
682 [(set_attr "type" "fadd")
683 (set_attr "mode" "DF")])
685 (define_insn "subsf3"
686 [(set (match_operand:SF 0 "register_operand" "=f")
687 (minus:SF (match_operand:SF 1 "register_operand" "f")
688 (match_operand:SF 2 "register_operand" "f")))]
691 [(set_attr "type" "fadd")
692 (set_attr "mode" "SF")])
694 (define_insn "sub<mode>3"
695 [(set (match_operand:GPR 0 "register_operand" "=d")
696 (minus:GPR (match_operand:GPR 1 "register_operand" "d")
697 (match_operand:GPR 2 "register_operand" "d")))]
700 [(set_attr "type" "arith")
701 (set_attr "mode" "<MODE>")])
703 (define_insn "*subsi3_extended"
704 [(set (match_operand:DI 0 "register_operand" "=d")
706 (minus:SI (match_operand:SI 1 "register_operand" "d")
707 (match_operand:SI 2 "register_operand" "d"))))]
710 [(set_attr "type" "arith")
711 (set_attr "mode" "DI")])
714 ;; ....................
718 ;; ....................
721 (define_expand "muldf3"
722 [(set (match_operand:DF 0 "register_operand")
723 (mult:DF (match_operand:DF 1 "register_operand")
724 (match_operand:DF 2 "register_operand")))]
725 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
728 (define_insn "muldf3_internal"
729 [(set (match_operand:DF 0 "register_operand" "=f")
730 (mult:DF (match_operand:DF 1 "register_operand" "f")
731 (match_operand:DF 2 "register_operand" "f")))]
732 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
734 [(set_attr "type" "fmul")
735 (set_attr "mode" "DF")])
737 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
738 ;; operands may corrupt immediately following multiplies. This is a
739 ;; simple fix to insert NOPs.
741 (define_insn "muldf3_r4300"
742 [(set (match_operand:DF 0 "register_operand" "=f")
743 (mult:DF (match_operand:DF 1 "register_operand" "f")
744 (match_operand:DF 2 "register_operand" "f")))]
745 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
746 "mul.d\t%0,%1,%2\;nop"
747 [(set_attr "type" "fmul")
748 (set_attr "mode" "DF")
749 (set_attr "length" "8")])
751 (define_expand "mulsf3"
752 [(set (match_operand:SF 0 "register_operand")
753 (mult:SF (match_operand:SF 1 "register_operand")
754 (match_operand:SF 2 "register_operand")))]
758 (define_insn "mulsf3_internal"
759 [(set (match_operand:SF 0 "register_operand" "=f")
760 (mult:SF (match_operand:SF 1 "register_operand" "f")
761 (match_operand:SF 2 "register_operand" "f")))]
762 "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
764 [(set_attr "type" "fmul")
765 (set_attr "mode" "SF")])
769 (define_insn "mulsf3_r4300"
770 [(set (match_operand:SF 0 "register_operand" "=f")
771 (mult:SF (match_operand:SF 1 "register_operand" "f")
772 (match_operand:SF 2 "register_operand" "f")))]
773 "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
774 "mul.s\t%0,%1,%2\;nop"
775 [(set_attr "type" "fmul")
776 (set_attr "mode" "SF")
777 (set_attr "length" "8")])
780 ;; The original R4000 has a cpu bug. If a double-word or a variable
781 ;; shift executes while an integer multiplication is in progress, the
782 ;; shift may give an incorrect result. Avoid this by keeping the mflo
783 ;; with the mult on the R4000.
785 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
786 ;; (also valid for MIPS R4000MC processors):
788 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
789 ;; this errata description.
790 ;; The following code sequence causes the R4000 to incorrectly
791 ;; execute the Double Shift Right Arithmetic 32 (dsra32)
792 ;; instruction. If the dsra32 instruction is executed during an
793 ;; integer multiply, the dsra32 will only shift by the amount in
794 ;; specified in the instruction rather than the amount plus 32
796 ;; instruction 1: mult rs,rt integer multiply
797 ;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
798 ;; right arithmetic + 32
799 ;; Workaround: A dsra32 instruction placed after an integer
800 ;; multiply should not be one of the 11 instructions after the
801 ;; multiply instruction."
805 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
806 ;; the following description.
807 ;; All extended shifts (shift by n+32) and variable shifts (32 and
808 ;; 64-bit versions) may produce incorrect results under the
809 ;; following conditions:
810 ;; 1) An integer multiply is currently executing
811 ;; 2) These types of shift instructions are executed immediately
812 ;; following an integer divide instruction.
814 ;; 1) Make sure no integer multiply is running wihen these
815 ;; instruction are executed. If this cannot be predicted at
816 ;; compile time, then insert a "mfhi" to R0 instruction
817 ;; immediately after the integer multiply instruction. This
818 ;; will cause the integer multiply to complete before the shift
820 ;; 2) Separate integer divide and these two classes of shift
821 ;; instructions by another instruction or a noop."
823 ;; These processors have PRId values of 0x00004220 and 0x00004300,
826 (define_expand "mulsi3"
827 [(set (match_operand:SI 0 "register_operand")
828 (mult:SI (match_operand:SI 1 "register_operand")
829 (match_operand:SI 2 "register_operand")))]
832 if (GENERATE_MULT3_SI || TARGET_MAD)
833 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
834 else if (!TARGET_FIX_R4000)
835 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
837 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
841 (define_insn "mulsi3_mult3"
842 [(set (match_operand:SI 0 "register_operand" "=d,l")
843 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
844 (match_operand:SI 2 "register_operand" "d,d")))
845 (clobber (match_scratch:SI 3 "=h,h"))
846 (clobber (match_scratch:SI 4 "=l,X"))]
850 if (which_alternative == 1)
851 return "mult\t%1,%2";
860 return "mul\t%0,%1,%2";
861 return "mult\t%0,%1,%2";
863 [(set_attr "type" "imul")
864 (set_attr "mode" "SI")])
866 ;; If a register gets allocated to LO, and we spill to memory, the reload
867 ;; will include a move from LO to a GPR. Merge it into the multiplication
868 ;; if it can set the GPR directly.
871 ;; Operand 1: GPR (1st multiplication operand)
872 ;; Operand 2: GPR (2nd multiplication operand)
874 ;; Operand 4: GPR (destination)
877 [(set (match_operand:SI 0 "register_operand")
878 (mult:SI (match_operand:SI 1 "register_operand")
879 (match_operand:SI 2 "register_operand")))
880 (clobber (match_operand:SI 3 "register_operand"))
881 (clobber (scratch:SI))])
882 (set (match_operand:SI 4 "register_operand")
883 (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
884 "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
887 (mult:SI (match_dup 1)
889 (clobber (match_dup 3))
890 (clobber (match_dup 0))])])
892 (define_insn "mulsi3_internal"
893 [(set (match_operand:SI 0 "register_operand" "=l")
894 (mult:SI (match_operand:SI 1 "register_operand" "d")
895 (match_operand:SI 2 "register_operand" "d")))
896 (clobber (match_scratch:SI 3 "=h"))]
899 [(set_attr "type" "imul")
900 (set_attr "mode" "SI")])
902 (define_insn "mulsi3_r4000"
903 [(set (match_operand:SI 0 "register_operand" "=d")
904 (mult:SI (match_operand:SI 1 "register_operand" "d")
905 (match_operand:SI 2 "register_operand" "d")))
906 (clobber (match_scratch:SI 3 "=h"))
907 (clobber (match_scratch:SI 4 "=l"))]
909 "mult\t%1,%2\;mflo\t%0"
910 [(set_attr "type" "imul")
911 (set_attr "mode" "SI")
912 (set_attr "length" "8")])
914 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
915 ;; of "mult; mflo". They have the same latency, but the first form gives
916 ;; us an extra cycle to compute the operands.
919 ;; Operand 1: GPR (1st multiplication operand)
920 ;; Operand 2: GPR (2nd multiplication operand)
922 ;; Operand 4: GPR (destination)
925 [(set (match_operand:SI 0 "register_operand")
926 (mult:SI (match_operand:SI 1 "register_operand")
927 (match_operand:SI 2 "register_operand")))
928 (clobber (match_operand:SI 3 "register_operand"))])
929 (set (match_operand:SI 4 "register_operand")
930 (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
931 "ISA_HAS_MACC && !GENERATE_MULT3_SI"
936 (plus:SI (mult:SI (match_dup 1)
940 (plus:SI (mult:SI (match_dup 1)
943 (clobber (match_dup 3))])])
945 ;; Multiply-accumulate patterns
947 ;; For processors that can copy the output to a general register:
949 ;; The all-d alternative is needed because the combiner will find this
950 ;; pattern and then register alloc/reload will move registers around to
951 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
953 ;; The last alternative should be made slightly less desirable, but adding
954 ;; "?" to the constraint is too strong, and causes values to be loaded into
955 ;; LO even when that's more costly. For now, using "*d" mostly does the
957 (define_insn "*mul_acc_si"
958 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
959 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
960 (match_operand:SI 2 "register_operand" "d,d,d"))
961 (match_operand:SI 3 "register_operand" "0,l,*d")))
962 (clobber (match_scratch:SI 4 "=h,h,h"))
963 (clobber (match_scratch:SI 5 "=X,3,l"))
964 (clobber (match_scratch:SI 6 "=X,X,&d"))]
966 || ISA_HAS_MADD_MSUB)
969 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
970 if (which_alternative == 2)
972 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
974 return madd[which_alternative];
976 [(set_attr "type" "imadd,imadd,multi")
977 (set_attr "mode" "SI")
978 (set_attr "length" "4,4,8")])
980 ;; Split the above insn if we failed to get LO allocated.
982 [(set (match_operand:SI 0 "register_operand")
983 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
984 (match_operand:SI 2 "register_operand"))
985 (match_operand:SI 3 "register_operand")))
986 (clobber (match_scratch:SI 4))
987 (clobber (match_scratch:SI 5))
988 (clobber (match_scratch:SI 6))]
989 "reload_completed && !TARGET_DEBUG_D_MODE
990 && GP_REG_P (true_regnum (operands[0]))
991 && GP_REG_P (true_regnum (operands[3]))"
992 [(parallel [(set (match_dup 6)
993 (mult:SI (match_dup 1) (match_dup 2)))
994 (clobber (match_dup 4))
995 (clobber (match_dup 5))])
996 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
999 ;; Splitter to copy result of MADD to a general register
1001 [(set (match_operand:SI 0 "register_operand")
1002 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1003 (match_operand:SI 2 "register_operand"))
1004 (match_operand:SI 3 "register_operand")))
1005 (clobber (match_scratch:SI 4))
1006 (clobber (match_scratch:SI 5))
1007 (clobber (match_scratch:SI 6))]
1008 "reload_completed && !TARGET_DEBUG_D_MODE
1009 && GP_REG_P (true_regnum (operands[0]))
1010 && true_regnum (operands[3]) == LO_REGNUM"
1011 [(parallel [(set (match_dup 3)
1012 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1014 (clobber (match_dup 4))
1015 (clobber (match_dup 5))
1016 (clobber (match_dup 6))])
1017 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1020 (define_insn "*macc"
1021 [(set (match_operand:SI 0 "register_operand" "=l,d")
1022 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1023 (match_operand:SI 2 "register_operand" "d,d"))
1024 (match_operand:SI 3 "register_operand" "0,l")))
1025 (clobber (match_scratch:SI 4 "=h,h"))
1026 (clobber (match_scratch:SI 5 "=X,3"))]
1029 if (which_alternative == 1)
1030 return "macc\t%0,%1,%2";
1031 else if (TARGET_MIPS5500)
1032 return "madd\t%1,%2";
1034 /* The VR4130 assumes that there is a two-cycle latency between a macc
1035 that "writes" to $0 and an instruction that reads from it. We avoid
1036 this by assigning to $1 instead. */
1037 return "%[macc\t%@,%1,%2%]";
1039 [(set_attr "type" "imadd")
1040 (set_attr "mode" "SI")])
1042 (define_insn "*msac"
1043 [(set (match_operand:SI 0 "register_operand" "=l,d")
1044 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1045 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1046 (match_operand:SI 3 "register_operand" "d,d"))))
1047 (clobber (match_scratch:SI 4 "=h,h"))
1048 (clobber (match_scratch:SI 5 "=X,1"))]
1051 if (which_alternative == 1)
1052 return "msac\t%0,%2,%3";
1053 else if (TARGET_MIPS5500)
1054 return "msub\t%2,%3";
1056 return "msac\t$0,%2,%3";
1058 [(set_attr "type" "imadd")
1059 (set_attr "mode" "SI")])
1061 ;; An msac-like instruction implemented using negation and a macc.
1062 (define_insn_and_split "*msac_using_macc"
1063 [(set (match_operand:SI 0 "register_operand" "=l,d")
1064 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1065 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1066 (match_operand:SI 3 "register_operand" "d,d"))))
1067 (clobber (match_scratch:SI 4 "=h,h"))
1068 (clobber (match_scratch:SI 5 "=X,1"))
1069 (clobber (match_scratch:SI 6 "=d,d"))]
1070 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1072 "&& reload_completed"
1074 (neg:SI (match_dup 3)))
1077 (plus:SI (mult:SI (match_dup 2)
1080 (clobber (match_dup 4))
1081 (clobber (match_dup 5))])]
1083 [(set_attr "type" "imadd")
1084 (set_attr "length" "8")])
1086 ;; Patterns generated by the define_peephole2 below.
1088 (define_insn "*macc2"
1089 [(set (match_operand:SI 0 "register_operand" "=l")
1090 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1091 (match_operand:SI 2 "register_operand" "d"))
1093 (set (match_operand:SI 3 "register_operand" "=d")
1094 (plus:SI (mult:SI (match_dup 1)
1097 (clobber (match_scratch:SI 4 "=h"))]
1098 "ISA_HAS_MACC && reload_completed"
1100 [(set_attr "type" "imadd")
1101 (set_attr "mode" "SI")])
1103 (define_insn "*msac2"
1104 [(set (match_operand:SI 0 "register_operand" "=l")
1105 (minus:SI (match_dup 0)
1106 (mult:SI (match_operand:SI 1 "register_operand" "d")
1107 (match_operand:SI 2 "register_operand" "d"))))
1108 (set (match_operand:SI 3 "register_operand" "=d")
1109 (minus:SI (match_dup 0)
1110 (mult:SI (match_dup 1)
1112 (clobber (match_scratch:SI 4 "=h"))]
1113 "ISA_HAS_MSAC && reload_completed"
1115 [(set_attr "type" "imadd")
1116 (set_attr "mode" "SI")])
1118 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1122 ;; Operand 1: macc/msac
1124 ;; Operand 3: GPR (destination)
1127 [(set (match_operand:SI 0 "register_operand")
1128 (match_operand:SI 1 "macc_msac_operand"))
1129 (clobber (match_operand:SI 2 "register_operand"))
1130 (clobber (scratch:SI))])
1131 (set (match_operand:SI 3 "register_operand")
1132 (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1134 [(parallel [(set (match_dup 0)
1138 (clobber (match_dup 2))])]
1141 ;; When we have a three-address multiplication instruction, it should
1142 ;; be faster to do a separate multiply and add, rather than moving
1143 ;; something into LO in order to use a macc instruction.
1145 ;; This peephole needs a scratch register to cater for the case when one
1146 ;; of the multiplication operands is the same as the destination.
1148 ;; Operand 0: GPR (scratch)
1150 ;; Operand 2: GPR (addend)
1151 ;; Operand 3: GPR (destination)
1152 ;; Operand 4: macc/msac
1154 ;; Operand 6: new multiplication
1155 ;; Operand 7: new addition/subtraction
1157 [(match_scratch:SI 0 "d")
1158 (set (match_operand:SI 1 "register_operand")
1159 (match_operand:SI 2 "register_operand"))
1162 [(set (match_operand:SI 3 "register_operand")
1163 (match_operand:SI 4 "macc_msac_operand"))
1164 (clobber (match_operand:SI 5 "register_operand"))
1165 (clobber (match_dup 1))])]
1167 && true_regnum (operands[1]) == LO_REGNUM
1168 && peep2_reg_dead_p (2, operands[1])
1169 && GP_REG_P (true_regnum (operands[3]))"
1170 [(parallel [(set (match_dup 0)
1172 (clobber (match_dup 5))
1173 (clobber (match_dup 1))])
1177 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1178 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1179 operands[2], operands[0]);
1182 ;; Same as above, except LO is the initial target of the macc.
1184 ;; Operand 0: GPR (scratch)
1186 ;; Operand 2: GPR (addend)
1187 ;; Operand 3: macc/msac
1189 ;; Operand 5: GPR (destination)
1190 ;; Operand 6: new multiplication
1191 ;; Operand 7: new addition/subtraction
1193 [(match_scratch:SI 0 "d")
1194 (set (match_operand:SI 1 "register_operand")
1195 (match_operand:SI 2 "register_operand"))
1199 (match_operand:SI 3 "macc_msac_operand"))
1200 (clobber (match_operand:SI 4 "register_operand"))
1201 (clobber (scratch:SI))])
1203 (set (match_operand:SI 5 "register_operand")
1204 (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1205 "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1206 [(parallel [(set (match_dup 0)
1208 (clobber (match_dup 4))
1209 (clobber (match_dup 1))])
1213 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1214 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1215 operands[2], operands[0]);
1218 (define_insn "*mul_sub_si"
1219 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1220 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1221 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1222 (match_operand:SI 3 "register_operand" "d,d,d"))))
1223 (clobber (match_scratch:SI 4 "=h,h,h"))
1224 (clobber (match_scratch:SI 5 "=X,1,l"))
1225 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1231 [(set_attr "type" "imadd,multi,multi")
1232 (set_attr "mode" "SI")
1233 (set_attr "length" "4,8,8")])
1235 ;; Split the above insn if we failed to get LO allocated.
1237 [(set (match_operand:SI 0 "register_operand")
1238 (minus:SI (match_operand:SI 1 "register_operand")
1239 (mult:SI (match_operand:SI 2 "register_operand")
1240 (match_operand:SI 3 "register_operand"))))
1241 (clobber (match_scratch:SI 4))
1242 (clobber (match_scratch:SI 5))
1243 (clobber (match_scratch:SI 6))]
1244 "reload_completed && !TARGET_DEBUG_D_MODE
1245 && GP_REG_P (true_regnum (operands[0]))
1246 && GP_REG_P (true_regnum (operands[1]))"
1247 [(parallel [(set (match_dup 6)
1248 (mult:SI (match_dup 2) (match_dup 3)))
1249 (clobber (match_dup 4))
1250 (clobber (match_dup 5))])
1251 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1254 ;; Splitter to copy result of MSUB to a general register
1256 [(set (match_operand:SI 0 "register_operand")
1257 (minus:SI (match_operand:SI 1 "register_operand")
1258 (mult:SI (match_operand:SI 2 "register_operand")
1259 (match_operand:SI 3 "register_operand"))))
1260 (clobber (match_scratch:SI 4))
1261 (clobber (match_scratch:SI 5))
1262 (clobber (match_scratch:SI 6))]
1263 "reload_completed && !TARGET_DEBUG_D_MODE
1264 && GP_REG_P (true_regnum (operands[0]))
1265 && true_regnum (operands[1]) == LO_REGNUM"
1266 [(parallel [(set (match_dup 1)
1267 (minus:SI (match_dup 1)
1268 (mult:SI (match_dup 2) (match_dup 3))))
1269 (clobber (match_dup 4))
1270 (clobber (match_dup 5))
1271 (clobber (match_dup 6))])
1272 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1275 (define_insn "*muls"
1276 [(set (match_operand:SI 0 "register_operand" "=l,d")
1277 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1278 (match_operand:SI 2 "register_operand" "d,d"))))
1279 (clobber (match_scratch:SI 3 "=h,h"))
1280 (clobber (match_scratch:SI 4 "=X,l"))]
1285 [(set_attr "type" "imul")
1286 (set_attr "mode" "SI")])
1288 (define_expand "muldi3"
1289 [(set (match_operand:DI 0 "register_operand")
1290 (mult:DI (match_operand:DI 1 "register_operand")
1291 (match_operand:DI 2 "register_operand")))]
1294 if (GENERATE_MULT3_DI)
1295 emit_insn (gen_muldi3_mult3 (operands[0], operands[1], operands[2]));
1296 else if (!TARGET_FIX_R4000)
1297 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1299 emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
1303 (define_insn "muldi3_mult3"
1304 [(set (match_operand:DI 0 "register_operand" "=d")
1305 (mult:DI (match_operand:DI 1 "register_operand" "d")
1306 (match_operand:DI 2 "register_operand" "d")))
1307 (clobber (match_scratch:DI 3 "=h"))
1308 (clobber (match_scratch:DI 4 "=l"))]
1309 "TARGET_64BIT && GENERATE_MULT3_DI"
1311 [(set_attr "type" "imul")
1312 (set_attr "mode" "DI")])
1314 (define_insn "muldi3_internal"
1315 [(set (match_operand:DI 0 "register_operand" "=l")
1316 (mult:DI (match_operand:DI 1 "register_operand" "d")
1317 (match_operand:DI 2 "register_operand" "d")))
1318 (clobber (match_scratch:DI 3 "=h"))]
1319 "TARGET_64BIT && !TARGET_FIX_R4000"
1321 [(set_attr "type" "imul")
1322 (set_attr "mode" "DI")])
1324 (define_insn "muldi3_r4000"
1325 [(set (match_operand:DI 0 "register_operand" "=d")
1326 (mult:DI (match_operand:DI 1 "register_operand" "d")
1327 (match_operand:DI 2 "register_operand" "d")))
1328 (clobber (match_scratch:DI 3 "=h"))
1329 (clobber (match_scratch:DI 4 "=l"))]
1330 "TARGET_64BIT && TARGET_FIX_R4000"
1331 "dmult\t%1,%2\;mflo\t%0"
1332 [(set_attr "type" "imul")
1333 (set_attr "mode" "DI")
1334 (set_attr "length" "8")])
1336 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1338 (define_expand "mulsidi3"
1340 [(set (match_operand:DI 0 "register_operand")
1342 (sign_extend:DI (match_operand:SI 1 "register_operand"))
1343 (sign_extend:DI (match_operand:SI 2 "register_operand"))))
1344 (clobber (scratch:DI))
1345 (clobber (scratch:DI))
1346 (clobber (scratch:DI))])]
1347 "!TARGET_64BIT || !TARGET_FIX_R4000"
1351 if (!TARGET_FIX_R4000)
1352 emit_insn (gen_mulsidi3_32bit_internal (operands[0], operands[1],
1355 emit_insn (gen_mulsidi3_32bit_r4000 (operands[0], operands[1],
1361 (define_insn "mulsidi3_32bit_internal"
1362 [(set (match_operand:DI 0 "register_operand" "=x")
1364 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1365 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1366 "!TARGET_64BIT && !TARGET_FIX_R4000"
1368 [(set_attr "type" "imul")
1369 (set_attr "mode" "SI")])
1371 (define_insn "mulsidi3_32bit_r4000"
1372 [(set (match_operand:DI 0 "register_operand" "=d")
1374 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1375 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1376 (clobber (match_scratch:DI 3 "=x"))]
1377 "!TARGET_64BIT && TARGET_FIX_R4000"
1378 "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1379 [(set_attr "type" "imul")
1380 (set_attr "mode" "SI")
1381 (set_attr "length" "12")])
1383 (define_insn_and_split "*mulsidi3_64bit"
1384 [(set (match_operand:DI 0 "register_operand" "=d")
1385 (mult:DI (match_operator:DI 1 "extend_operator"
1386 [(match_operand:SI 3 "register_operand" "d")])
1387 (match_operator:DI 2 "extend_operator"
1388 [(match_operand:SI 4 "register_operand" "d")])))
1389 (clobber (match_scratch:DI 5 "=l"))
1390 (clobber (match_scratch:DI 6 "=h"))
1391 (clobber (match_scratch:DI 7 "=d"))]
1392 "TARGET_64BIT && !TARGET_FIX_R4000
1393 && GET_CODE (operands[1]) == GET_CODE (operands[2])"
1395 "&& reload_completed"
1399 (mult:SI (match_dup 3)
1403 (mult:DI (match_dup 1)
1407 ;; OP7 <- LO, OP0 <- HI
1408 (set (match_dup 7) (unspec:DI [(match_dup 5) (match_dup 6)] UNSPEC_MFHILO))
1409 (set (match_dup 0) (unspec:DI [(match_dup 6) (match_dup 5)] UNSPEC_MFHILO))
1413 (ashift:DI (match_dup 7)
1416 (lshiftrt:DI (match_dup 7)
1419 ;; Shift OP0 into place.
1421 (ashift:DI (match_dup 0)
1424 ;; OR the two halves together
1426 (ior:DI (match_dup 0)
1429 [(set_attr "type" "imul")
1430 (set_attr "mode" "SI")
1431 (set_attr "length" "24")])
1433 (define_insn "*mulsidi3_64bit_parts"
1434 [(set (match_operand:DI 0 "register_operand" "=l")
1436 (mult:SI (match_operand:SI 2 "register_operand" "d")
1437 (match_operand:SI 3 "register_operand" "d"))))
1438 (set (match_operand:DI 1 "register_operand" "=h")
1441 (match_operator:DI 4 "extend_operator" [(match_dup 2)])
1442 (match_operator:DI 5 "extend_operator" [(match_dup 3)]))
1444 "TARGET_64BIT && !TARGET_FIX_R4000
1445 && GET_CODE (operands[4]) == GET_CODE (operands[5])"
1447 if (GET_CODE (operands[4]) == SIGN_EXTEND)
1448 return "mult\t%2,%3";
1450 return "multu\t%2,%3";
1452 [(set_attr "type" "imul")
1453 (set_attr "mode" "SI")])
1455 (define_expand "umulsidi3"
1457 [(set (match_operand:DI 0 "register_operand")
1459 (zero_extend:DI (match_operand:SI 1 "register_operand"))
1460 (zero_extend:DI (match_operand:SI 2 "register_operand"))))
1461 (clobber (scratch:DI))
1462 (clobber (scratch:DI))
1463 (clobber (scratch:DI))])]
1464 "!TARGET_64BIT || !TARGET_FIX_R4000"
1468 if (!TARGET_FIX_R4000)
1469 emit_insn (gen_umulsidi3_32bit_internal (operands[0], operands[1],
1472 emit_insn (gen_umulsidi3_32bit_r4000 (operands[0], operands[1],
1478 (define_insn "umulsidi3_32bit_internal"
1479 [(set (match_operand:DI 0 "register_operand" "=x")
1481 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1482 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1483 "!TARGET_64BIT && !TARGET_FIX_R4000"
1485 [(set_attr "type" "imul")
1486 (set_attr "mode" "SI")])
1488 (define_insn "umulsidi3_32bit_r4000"
1489 [(set (match_operand:DI 0 "register_operand" "=d")
1491 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1492 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1493 (clobber (match_scratch:DI 3 "=x"))]
1494 "!TARGET_64BIT && TARGET_FIX_R4000"
1495 "multu\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1496 [(set_attr "type" "imul")
1497 (set_attr "mode" "SI")
1498 (set_attr "length" "12")])
1500 ;; Widening multiply with negation.
1501 (define_insn "*muls_di"
1502 [(set (match_operand:DI 0 "register_operand" "=x")
1505 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1506 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1507 "!TARGET_64BIT && ISA_HAS_MULS"
1509 [(set_attr "type" "imul")
1510 (set_attr "length" "4")
1511 (set_attr "mode" "SI")])
1513 (define_insn "*umuls_di"
1514 [(set (match_operand:DI 0 "register_operand" "=x")
1517 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1518 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1519 "!TARGET_64BIT && ISA_HAS_MULS"
1521 [(set_attr "type" "imul")
1522 (set_attr "length" "4")
1523 (set_attr "mode" "SI")])
1525 (define_insn "*smsac_di"
1526 [(set (match_operand:DI 0 "register_operand" "=x")
1528 (match_operand:DI 3 "register_operand" "0")
1530 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1531 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1532 "!TARGET_64BIT && ISA_HAS_MSAC"
1534 if (TARGET_MIPS5500)
1535 return "msub\t%1,%2";
1537 return "msac\t$0,%1,%2";
1539 [(set_attr "type" "imadd")
1540 (set_attr "length" "4")
1541 (set_attr "mode" "SI")])
1543 (define_insn "*umsac_di"
1544 [(set (match_operand:DI 0 "register_operand" "=x")
1546 (match_operand:DI 3 "register_operand" "0")
1548 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1549 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1550 "!TARGET_64BIT && ISA_HAS_MSAC"
1552 if (TARGET_MIPS5500)
1553 return "msubu\t%1,%2";
1555 return "msacu\t$0,%1,%2";
1557 [(set_attr "type" "imadd")
1558 (set_attr "length" "4")
1559 (set_attr "mode" "SI")])
1561 ;; _highpart patterns
1562 (define_expand "umulsi3_highpart"
1563 [(set (match_operand:SI 0 "register_operand")
1566 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"))
1567 (zero_extend:DI (match_operand:SI 2 "register_operand")))
1569 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1572 emit_insn (gen_umulsi3_highpart_mulhi_internal (operands[0], operands[1],
1575 emit_insn (gen_umulsi3_highpart_internal (operands[0], operands[1],
1580 (define_insn "umulsi3_highpart_internal"
1581 [(set (match_operand:SI 0 "register_operand" "=h")
1584 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1585 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1587 (clobber (match_scratch:SI 3 "=l"))]
1588 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1590 [(set_attr "type" "imul")
1591 (set_attr "mode" "SI")
1592 (set_attr "length" "4")])
1594 (define_insn "umulsi3_highpart_mulhi_internal"
1595 [(set (match_operand:SI 0 "register_operand" "=h,d")
1598 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1599 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1601 (clobber (match_scratch:SI 3 "=l,l"))
1602 (clobber (match_scratch:SI 4 "=X,h"))]
1607 [(set_attr "type" "imul")
1608 (set_attr "mode" "SI")
1609 (set_attr "length" "4")])
1611 (define_insn "umulsi3_highpart_neg_mulhi_internal"
1612 [(set (match_operand:SI 0 "register_operand" "=h,d")
1616 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1617 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1619 (clobber (match_scratch:SI 3 "=l,l"))
1620 (clobber (match_scratch:SI 4 "=X,h"))]
1625 [(set_attr "type" "imul")
1626 (set_attr "mode" "SI")
1627 (set_attr "length" "4")])
1629 (define_expand "smulsi3_highpart"
1630 [(set (match_operand:SI 0 "register_operand")
1633 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"))
1634 (sign_extend:DI (match_operand:SI 2 "register_operand")))
1636 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1639 emit_insn (gen_smulsi3_highpart_mulhi_internal (operands[0], operands[1],
1642 emit_insn (gen_smulsi3_highpart_internal (operands[0], operands[1],
1647 (define_insn "smulsi3_highpart_internal"
1648 [(set (match_operand:SI 0 "register_operand" "=h")
1651 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1652 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1654 (clobber (match_scratch:SI 3 "=l"))]
1655 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1657 [(set_attr "type" "imul")
1658 (set_attr "mode" "SI")
1659 (set_attr "length" "4")])
1661 (define_insn "smulsi3_highpart_mulhi_internal"
1662 [(set (match_operand:SI 0 "register_operand" "=h,d")
1665 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1666 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1668 (clobber (match_scratch:SI 3 "=l,l"))
1669 (clobber (match_scratch:SI 4 "=X,h"))]
1674 [(set_attr "type" "imul")
1675 (set_attr "mode" "SI")
1676 (set_attr "length" "4")])
1678 (define_insn "smulsi3_highpart_neg_mulhi_internal"
1679 [(set (match_operand:SI 0 "register_operand" "=h,d")
1683 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1684 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1686 (clobber (match_scratch:SI 3 "=l,l"))
1687 (clobber (match_scratch:SI 4 "=X,h"))]
1692 [(set_attr "type" "imul")
1693 (set_attr "mode" "SI")])
1695 (define_insn "smuldi3_highpart"
1696 [(set (match_operand:DI 0 "register_operand" "=h")
1700 (sign_extend:TI (match_operand:DI 1 "register_operand" "d"))
1701 (sign_extend:TI (match_operand:DI 2 "register_operand" "d")))
1703 (clobber (match_scratch:DI 3 "=l"))]
1704 "TARGET_64BIT && !TARGET_FIX_R4000"
1706 [(set_attr "type" "imul")
1707 (set_attr "mode" "DI")])
1709 ;; Disable this pattern for -mfix-vr4120. This is for VR4120 errata MD(0),
1710 ;; which says that dmultu does not always produce the correct result.
1711 (define_insn "umuldi3_highpart"
1712 [(set (match_operand:DI 0 "register_operand" "=h")
1716 (zero_extend:TI (match_operand:DI 1 "register_operand" "d"))
1717 (zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
1719 (clobber (match_scratch:DI 3 "=l"))]
1720 "TARGET_64BIT && !TARGET_FIX_R4000 && !TARGET_FIX_VR4120"
1722 [(set_attr "type" "imul")
1723 (set_attr "mode" "DI")])
1726 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1727 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
1729 (define_insn "madsi"
1730 [(set (match_operand:SI 0 "register_operand" "+l")
1731 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1732 (match_operand:SI 2 "register_operand" "d"))
1734 (clobber (match_scratch:SI 3 "=h"))]
1737 [(set_attr "type" "imadd")
1738 (set_attr "mode" "SI")])
1740 (define_insn "*umul_acc_di"
1741 [(set (match_operand:DI 0 "register_operand" "=x")
1743 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1744 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1745 (match_operand:DI 3 "register_operand" "0")))]
1746 "(TARGET_MAD || ISA_HAS_MACC)
1750 return "madu\t%1,%2";
1751 else if (TARGET_MIPS5500)
1752 return "maddu\t%1,%2";
1754 /* See comment in *macc. */
1755 return "%[maccu\t%@,%1,%2%]";
1757 [(set_attr "type" "imadd")
1758 (set_attr "mode" "SI")])
1761 (define_insn "*smul_acc_di"
1762 [(set (match_operand:DI 0 "register_operand" "=x")
1764 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1765 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1766 (match_operand:DI 3 "register_operand" "0")))]
1767 "(TARGET_MAD || ISA_HAS_MACC)
1771 return "mad\t%1,%2";
1772 else if (TARGET_MIPS5500)
1773 return "madd\t%1,%2";
1775 /* See comment in *macc. */
1776 return "%[macc\t%@,%1,%2%]";
1778 [(set_attr "type" "imadd")
1779 (set_attr "mode" "SI")])
1781 ;; Floating point multiply accumulate instructions.
1784 [(set (match_operand:DF 0 "register_operand" "=f")
1785 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1786 (match_operand:DF 2 "register_operand" "f"))
1787 (match_operand:DF 3 "register_operand" "f")))]
1788 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1789 "madd.d\t%0,%3,%1,%2"
1790 [(set_attr "type" "fmadd")
1791 (set_attr "mode" "DF")])
1794 [(set (match_operand:SF 0 "register_operand" "=f")
1795 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1796 (match_operand:SF 2 "register_operand" "f"))
1797 (match_operand:SF 3 "register_operand" "f")))]
1798 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1799 "madd.s\t%0,%3,%1,%2"
1800 [(set_attr "type" "fmadd")
1801 (set_attr "mode" "SF")])
1804 [(set (match_operand:DF 0 "register_operand" "=f")
1805 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1806 (match_operand:DF 2 "register_operand" "f"))
1807 (match_operand:DF 3 "register_operand" "f")))]
1808 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1809 "msub.d\t%0,%3,%1,%2"
1810 [(set_attr "type" "fmadd")
1811 (set_attr "mode" "DF")])
1814 [(set (match_operand:SF 0 "register_operand" "=f")
1815 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1816 (match_operand:SF 2 "register_operand" "f"))
1817 (match_operand:SF 3 "register_operand" "f")))]
1819 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1820 "msub.s\t%0,%3,%1,%2"
1821 [(set_attr "type" "fmadd")
1822 (set_attr "mode" "SF")])
1825 [(set (match_operand:DF 0 "register_operand" "=f")
1826 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1827 (match_operand:DF 2 "register_operand" "f"))
1828 (match_operand:DF 3 "register_operand" "f"))))]
1829 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1830 && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1831 "nmadd.d\t%0,%3,%1,%2"
1832 [(set_attr "type" "fmadd")
1833 (set_attr "mode" "DF")])
1836 [(set (match_operand:DF 0 "register_operand" "=f")
1837 (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
1838 (match_operand:DF 2 "register_operand" "f"))
1839 (match_operand:DF 3 "register_operand" "f")))]
1840 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1841 && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1842 "nmadd.d\t%0,%3,%1,%2"
1843 [(set_attr "type" "fmadd")
1844 (set_attr "mode" "DF")])
1847 [(set (match_operand:SF 0 "register_operand" "=f")
1848 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1849 (match_operand:SF 2 "register_operand" "f"))
1850 (match_operand:SF 3 "register_operand" "f"))))]
1851 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1852 && HONOR_SIGNED_ZEROS (SFmode)"
1853 "nmadd.s\t%0,%3,%1,%2"
1854 [(set_attr "type" "fmadd")
1855 (set_attr "mode" "SF")])
1858 [(set (match_operand:SF 0 "register_operand" "=f")
1859 (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
1860 (match_operand:SF 2 "register_operand" "f"))
1861 (match_operand:SF 3 "register_operand" "f")))]
1862 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1863 && !HONOR_SIGNED_ZEROS (SFmode)"
1864 "nmadd.s\t%0,%3,%1,%2"
1865 [(set_attr "type" "fmadd")
1866 (set_attr "mode" "SF")])
1869 [(set (match_operand:DF 0 "register_operand" "=f")
1870 (neg:DF (minus:DF (mult:DF (match_operand:DF 2 "register_operand" "f")
1871 (match_operand:DF 3 "register_operand" "f"))
1872 (match_operand:DF 1 "register_operand" "f"))))]
1873 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1874 && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1875 "nmsub.d\t%0,%1,%2,%3"
1876 [(set_attr "type" "fmadd")
1877 (set_attr "mode" "DF")])
1880 [(set (match_operand:DF 0 "register_operand" "=f")
1881 (minus:DF (match_operand:DF 1 "register_operand" "f")
1882 (mult:DF (match_operand:DF 2 "register_operand" "f")
1883 (match_operand:DF 3 "register_operand" "f"))))]
1884 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1885 && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1886 "nmsub.d\t%0,%1,%2,%3"
1887 [(set_attr "type" "fmadd")
1888 (set_attr "mode" "DF")])
1891 [(set (match_operand:SF 0 "register_operand" "=f")
1892 (neg:SF (minus:SF (mult:SF (match_operand:SF 2 "register_operand" "f")
1893 (match_operand:SF 3 "register_operand" "f"))
1894 (match_operand:SF 1 "register_operand" "f"))))]
1895 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1896 && HONOR_SIGNED_ZEROS (SFmode)"
1897 "nmsub.s\t%0,%1,%2,%3"
1898 [(set_attr "type" "fmadd")
1899 (set_attr "mode" "SF")])
1902 [(set (match_operand:SF 0 "register_operand" "=f")
1903 (minus:SF (match_operand:SF 1 "register_operand" "f")
1904 (mult:SF (match_operand:SF 2 "register_operand" "f")
1905 (match_operand:SF 3 "register_operand" "f"))))]
1906 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1907 && !HONOR_SIGNED_ZEROS (SFmode)"
1908 "nmsub.s\t%0,%1,%2,%3"
1909 [(set_attr "type" "fmadd")
1910 (set_attr "mode" "SF")])
1913 ;; ....................
1915 ;; DIVISION and REMAINDER
1917 ;; ....................
1920 (define_expand "divdf3"
1921 [(set (match_operand:DF 0 "register_operand")
1922 (div:DF (match_operand:DF 1 "reg_or_1_operand")
1923 (match_operand:DF 2 "register_operand")))]
1924 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1926 if (const_1_operand (operands[1], DFmode))
1927 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1928 operands[1] = force_reg (DFmode, operands[1]);
1931 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
1933 ;; If an mfc1 or dmfc1 happens to access the floating point register
1934 ;; file at the same time a long latency operation (div, sqrt, recip,
1935 ;; sqrt) iterates an intermediate result back through the floating
1936 ;; point register file bypass, then instead returning the correct
1937 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1938 ;; result of the long latency operation.
1940 ;; The workaround is to insert an unconditional 'mov' from/to the
1941 ;; long latency op destination register.
1943 (define_insn "*divdf3"
1944 [(set (match_operand:DF 0 "register_operand" "=f")
1945 (div:DF (match_operand:DF 1 "register_operand" "f")
1946 (match_operand:DF 2 "register_operand" "f")))]
1947 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1950 return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
1952 return "div.d\t%0,%1,%2";
1954 [(set_attr "type" "fdiv")
1955 (set_attr "mode" "DF")
1956 (set (attr "length")
1957 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1962 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
1964 ;; In certain cases, div.s and div.ps may have a rounding error
1965 ;; and/or wrong inexact flag.
1967 ;; Therefore, we only allow div.s if not working around SB-1 rev2
1968 ;; errata, or if working around those errata and a slight loss of
1969 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
1970 (define_expand "divsf3"
1971 [(set (match_operand:SF 0 "register_operand")
1972 (div:SF (match_operand:SF 1 "reg_or_1_operand")
1973 (match_operand:SF 2 "register_operand")))]
1974 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
1976 if (const_1_operand (operands[1], SFmode))
1977 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1978 operands[1] = force_reg (SFmode, operands[1]);
1981 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1982 ;; "divdf3" comment for details).
1984 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
1985 ;; "divsf3" comment for details).
1986 (define_insn "*divsf3"
1987 [(set (match_operand:SF 0 "register_operand" "=f")
1988 (div:SF (match_operand:SF 1 "register_operand" "f")
1989 (match_operand:SF 2 "register_operand" "f")))]
1990 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
1993 return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
1995 return "div.s\t%0,%1,%2";
1997 [(set_attr "type" "fdiv")
1998 (set_attr "mode" "SF")
1999 (set (attr "length")
2000 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2004 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2005 ;; "divdf3" comment for details).
2007 [(set (match_operand:DF 0 "register_operand" "=f")
2008 (div:DF (match_operand:DF 1 "const_1_operand" "")
2009 (match_operand:DF 2 "register_operand" "f")))]
2010 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2013 return "recip.d\t%0,%2\;mov.d\t%0,%0";
2015 return "recip.d\t%0,%2";
2017 [(set_attr "type" "frdiv")
2018 (set_attr "mode" "DF")
2019 (set (attr "length")
2020 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2024 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2025 ;; "divdf3" comment for details).
2027 [(set (match_operand:SF 0 "register_operand" "=f")
2028 (div:SF (match_operand:SF 1 "const_1_operand" "")
2029 (match_operand:SF 2 "register_operand" "f")))]
2030 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2033 return "recip.s\t%0,%2\;mov.s\t%0,%0";
2035 return "recip.s\t%0,%2";
2037 [(set_attr "type" "frdiv")
2038 (set_attr "mode" "SF")
2039 (set (attr "length")
2040 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2044 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2045 ;; with negative operands. We use special libgcc functions instead.
2046 (define_insn "divmodsi4"
2047 [(set (match_operand:SI 0 "register_operand" "=l")
2048 (div:SI (match_operand:SI 1 "register_operand" "d")
2049 (match_operand:SI 2 "register_operand" "d")))
2050 (set (match_operand:SI 3 "register_operand" "=h")
2051 (mod:SI (match_dup 1)
2053 "!TARGET_FIX_VR4120"
2054 { return mips_output_division ("div\t$0,%1,%2", operands); }
2055 [(set_attr "type" "idiv")
2056 (set_attr "mode" "SI")])
2058 (define_insn "divmoddi4"
2059 [(set (match_operand:DI 0 "register_operand" "=l")
2060 (div:DI (match_operand:DI 1 "register_operand" "d")
2061 (match_operand:DI 2 "register_operand" "d")))
2062 (set (match_operand:DI 3 "register_operand" "=h")
2063 (mod:DI (match_dup 1)
2065 "TARGET_64BIT && !TARGET_FIX_VR4120"
2066 { return mips_output_division ("ddiv\t$0,%1,%2", operands); }
2067 [(set_attr "type" "idiv")
2068 (set_attr "mode" "DI")])
2070 (define_insn "udivmodsi4"
2071 [(set (match_operand:SI 0 "register_operand" "=l")
2072 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2073 (match_operand:SI 2 "register_operand" "d")))
2074 (set (match_operand:SI 3 "register_operand" "=h")
2075 (umod:SI (match_dup 1)
2078 { return mips_output_division ("divu\t$0,%1,%2", operands); }
2079 [(set_attr "type" "idiv")
2080 (set_attr "mode" "SI")])
2082 (define_insn "udivmoddi4"
2083 [(set (match_operand:DI 0 "register_operand" "=l")
2084 (udiv:DI (match_operand:DI 1 "register_operand" "d")
2085 (match_operand:DI 2 "register_operand" "d")))
2086 (set (match_operand:DI 3 "register_operand" "=h")
2087 (umod:DI (match_dup 1)
2090 { return mips_output_division ("ddivu\t$0,%1,%2", operands); }
2091 [(set_attr "type" "idiv")
2092 (set_attr "mode" "DI")])
2095 ;; ....................
2099 ;; ....................
2101 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2102 ;; "divdf3" comment for details).
2103 (define_insn "sqrtdf2"
2104 [(set (match_operand:DF 0 "register_operand" "=f")
2105 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2106 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2109 return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
2111 return "sqrt.d\t%0,%1";
2113 [(set_attr "type" "fsqrt")
2114 (set_attr "mode" "DF")
2115 (set (attr "length")
2116 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2120 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2121 ;; "divdf3" comment for details).
2122 (define_insn "sqrtsf2"
2123 [(set (match_operand:SF 0 "register_operand" "=f")
2124 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2125 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2128 return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
2130 return "sqrt.s\t%0,%1";
2132 [(set_attr "type" "fsqrt")
2133 (set_attr "mode" "SF")
2134 (set (attr "length")
2135 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2139 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2140 ;; "divdf3" comment for details).
2142 [(set (match_operand:DF 0 "register_operand" "=f")
2143 (div:DF (match_operand:DF 1 "const_1_operand" "")
2144 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2145 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2148 return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2150 return "rsqrt.d\t%0,%2";
2152 [(set_attr "type" "frsqrt")
2153 (set_attr "mode" "DF")
2154 (set (attr "length")
2155 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2159 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2160 ;; "divdf3" comment for details).
2162 [(set (match_operand:SF 0 "register_operand" "=f")
2163 (div:SF (match_operand:SF 1 "const_1_operand" "")
2164 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2165 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2168 return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2170 return "rsqrt.s\t%0,%2";
2172 [(set_attr "type" "frsqrt")
2173 (set_attr "mode" "SF")
2174 (set (attr "length")
2175 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2179 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2180 ;; "divdf3" comment for details).
2182 [(set (match_operand:DF 0 "register_operand" "=f")
2183 (sqrt:DF (div:DF (match_operand:DF 1 "const_1_operand" "")
2184 (match_operand:DF 2 "register_operand" "f"))))]
2185 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2188 return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2190 return "rsqrt.d\t%0,%2";
2192 [(set_attr "type" "frsqrt")
2193 (set_attr "mode" "DF")
2194 (set (attr "length")
2195 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2199 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2200 ;; "divdf3" comment for details).
2202 [(set (match_operand:SF 0 "register_operand" "=f")
2203 (sqrt:SF (div:SF (match_operand:SF 1 "const_1_operand" "")
2204 (match_operand:SF 2 "register_operand" "f"))))]
2205 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2208 return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2210 return "rsqrt.s\t%0,%2";
2212 [(set_attr "type" "frsqrt")
2213 (set_attr "mode" "SF")
2214 (set (attr "length")
2215 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2220 ;; ....................
2224 ;; ....................
2226 ;; Do not use the integer abs macro instruction, since that signals an
2227 ;; exception on -2147483648 (sigh).
2229 (define_insn "abssi2"
2230 [(set (match_operand:SI 0 "register_operand" "=d")
2231 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2234 operands[2] = const0_rtx;
2236 if (REGNO (operands[0]) == REGNO (operands[1]))
2238 if (GENERATE_BRANCHLIKELY)
2239 return "%(bltzl\t%1,1f\;subu\t%0,%z2,%0\n%~1:%)";
2241 return "bgez\t%1,1f%#\;subu\t%0,%z2,%0\n%~1:";
2244 return "%(bgez\t%1,1f\;move\t%0,%1\;subu\t%0,%z2,%0\n%~1:%)";
2246 [(set_attr "type" "multi")
2247 (set_attr "mode" "SI")
2248 (set_attr "length" "12")])
2250 (define_insn "absdi2"
2251 [(set (match_operand:DI 0 "register_operand" "=d")
2252 (abs:DI (match_operand:DI 1 "register_operand" "d")))]
2253 "TARGET_64BIT && !TARGET_MIPS16"
2255 unsigned int regno1;
2256 operands[2] = const0_rtx;
2258 if (GET_CODE (operands[1]) == REG)
2259 regno1 = REGNO (operands[1]);
2261 regno1 = REGNO (XEXP (operands[1], 0));
2263 if (REGNO (operands[0]) == regno1)
2264 return "%(bltzl\t%1,1f\;dsubu\t%0,%z2,%0\n%~1:%)";
2266 return "%(bgez\t%1,1f\;move\t%0,%1\;dsubu\t%0,%z2,%0\n%~1:%)";
2268 [(set_attr "type" "multi")
2269 (set_attr "mode" "DI")
2270 (set_attr "length" "12")])
2272 (define_insn "absdf2"
2273 [(set (match_operand:DF 0 "register_operand" "=f")
2274 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2275 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2277 [(set_attr "type" "fabs")
2278 (set_attr "mode" "DF")])
2280 (define_insn "abssf2"
2281 [(set (match_operand:SF 0 "register_operand" "=f")
2282 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2285 [(set_attr "type" "fabs")
2286 (set_attr "mode" "SF")])
2289 ;; ....................
2291 ;; FIND FIRST BIT INSTRUCTION
2293 ;; ....................
2296 (define_insn "ffssi2"
2297 [(set (match_operand:SI 0 "register_operand" "=&d")
2298 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2299 (clobber (match_scratch:SI 2 "=&d"))
2300 (clobber (match_scratch:SI 3 "=&d"))]
2303 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2307 %~1:\tand\t%2,%1,0x0001\;\
2317 %~1:\tand\t%2,%3,0x0001\;\
2323 [(set_attr "type" "multi")
2324 (set_attr "mode" "SI")
2325 (set_attr "length" "28")])
2327 (define_insn "ffsdi2"
2328 [(set (match_operand:DI 0 "register_operand" "=&d")
2329 (ffs:DI (match_operand:DI 1 "register_operand" "d")))
2330 (clobber (match_scratch:DI 2 "=&d"))
2331 (clobber (match_scratch:DI 3 "=&d"))]
2332 "TARGET_64BIT && !TARGET_MIPS16"
2334 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2338 %~1:\tand\t%2,%1,0x0001\;\
2348 %~1:\tand\t%2,%3,0x0001\;\
2354 [(set_attr "type" "multi")
2355 (set_attr "mode" "DI")
2356 (set_attr "length" "28")])
2359 ;; ...................
2361 ;; Count leading zeroes.
2363 ;; ...................
2366 (define_insn "clzsi2"
2367 [(set (match_operand:SI 0 "register_operand" "=d")
2368 (clz:SI (match_operand:SI 1 "register_operand" "d")))]
2371 [(set_attr "type" "clz")
2372 (set_attr "mode" "SI")])
2374 (define_insn "clzdi2"
2375 [(set (match_operand:DI 0 "register_operand" "=d")
2376 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
2379 [(set_attr "type" "clz")
2380 (set_attr "mode" "DI")])
2383 ;; ....................
2385 ;; NEGATION and ONE'S COMPLEMENT
2387 ;; ....................
2389 (define_insn "negsi2"
2390 [(set (match_operand:SI 0 "register_operand" "=d")
2391 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2395 return "neg\t%0,%1";
2397 return "subu\t%0,%.,%1";
2399 [(set_attr "type" "arith")
2400 (set_attr "mode" "SI")])
2402 (define_insn "negdi2"
2403 [(set (match_operand:DI 0 "register_operand" "=d")
2404 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2405 "TARGET_64BIT && !TARGET_MIPS16"
2407 [(set_attr "type" "arith")
2408 (set_attr "mode" "DI")])
2410 (define_insn "negdf2"
2411 [(set (match_operand:DF 0 "register_operand" "=f")
2412 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2413 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2415 [(set_attr "type" "fneg")
2416 (set_attr "mode" "DF")])
2418 (define_insn "negsf2"
2419 [(set (match_operand:SF 0 "register_operand" "=f")
2420 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2423 [(set_attr "type" "fneg")
2424 (set_attr "mode" "SF")])
2426 (define_insn "one_cmplsi2"
2427 [(set (match_operand:SI 0 "register_operand" "=d")
2428 (not:SI (match_operand:SI 1 "register_operand" "d")))]
2432 return "not\t%0,%1";
2434 return "nor\t%0,%.,%1";
2436 [(set_attr "type" "arith")
2437 (set_attr "mode" "SI")])
2439 (define_insn "one_cmpldi2"
2440 [(set (match_operand:DI 0 "register_operand" "=d")
2441 (not:DI (match_operand:DI 1 "register_operand" "d")))]
2445 return "not\t%0,%1";
2447 return "nor\t%0,%.,%1";
2449 [(set_attr "type" "arith")
2450 (set_attr "mode" "DI")])
2453 ;; ....................
2457 ;; ....................
2460 ;; Many of these instructions use trivial define_expands, because we
2461 ;; want to use a different set of constraints when TARGET_MIPS16.
2463 (define_expand "andsi3"
2464 [(set (match_operand:SI 0 "register_operand")
2465 (and:SI (match_operand:SI 1 "uns_arith_operand")
2466 (match_operand:SI 2 "uns_arith_operand")))]
2471 operands[1] = force_reg (SImode, operands[1]);
2472 operands[2] = force_reg (SImode, operands[2]);
2477 [(set (match_operand:SI 0 "register_operand" "=d,d")
2478 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2479 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2484 [(set_attr "type" "arith")
2485 (set_attr "mode" "SI")])
2488 [(set (match_operand:SI 0 "register_operand" "=d")
2489 (and:SI (match_operand:SI 1 "register_operand" "%0")
2490 (match_operand:SI 2 "register_operand" "d")))]
2493 [(set_attr "type" "arith")
2494 (set_attr "mode" "SI")])
2496 (define_expand "anddi3"
2497 [(set (match_operand:DI 0 "register_operand")
2498 (and:DI (match_operand:DI 1 "register_operand")
2499 (match_operand:DI 2 "uns_arith_operand")))]
2504 operands[1] = force_reg (DImode, operands[1]);
2505 operands[2] = force_reg (DImode, operands[2]);
2510 [(set (match_operand:DI 0 "register_operand" "=d,d")
2511 (and:DI (match_operand:DI 1 "register_operand" "d,d")
2512 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2513 "TARGET_64BIT && !TARGET_MIPS16"
2517 [(set_attr "type" "arith")
2518 (set_attr "mode" "DI")])
2521 [(set (match_operand:DI 0 "register_operand" "=d")
2522 (and:DI (match_operand:DI 1 "register_operand" "0")
2523 (match_operand:DI 2 "register_operand" "d")))]
2524 "TARGET_64BIT && TARGET_MIPS16"
2526 [(set_attr "type" "arith")
2527 (set_attr "mode" "DI")])
2529 (define_expand "iorsi3"
2530 [(set (match_operand:SI 0 "register_operand")
2531 (ior:SI (match_operand:SI 1 "uns_arith_operand")
2532 (match_operand:SI 2 "uns_arith_operand")))]
2537 operands[1] = force_reg (SImode, operands[1]);
2538 operands[2] = force_reg (SImode, operands[2]);
2543 [(set (match_operand:SI 0 "register_operand" "=d,d")
2544 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2545 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2550 [(set_attr "type" "arith")
2551 (set_attr "mode" "SI")])
2554 [(set (match_operand:SI 0 "register_operand" "=d")
2555 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2556 (match_operand:SI 2 "register_operand" "d")))]
2559 [(set_attr "type" "arith")
2560 (set_attr "mode" "SI")])
2562 (define_expand "iordi3"
2563 [(set (match_operand:DI 0 "register_operand")
2564 (ior:DI (match_operand:DI 1 "register_operand")
2565 (match_operand:DI 2 "uns_arith_operand")))]
2570 operands[1] = force_reg (DImode, operands[1]);
2571 operands[2] = force_reg (DImode, operands[2]);
2576 [(set (match_operand:DI 0 "register_operand" "=d,d")
2577 (ior:DI (match_operand:DI 1 "register_operand" "d,d")
2578 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2579 "TARGET_64BIT && !TARGET_MIPS16"
2583 [(set_attr "type" "arith")
2584 (set_attr "mode" "DI")])
2587 [(set (match_operand:DI 0 "register_operand" "=d")
2588 (ior:DI (match_operand:DI 1 "register_operand" "0")
2589 (match_operand:DI 2 "register_operand" "d")))]
2590 "TARGET_64BIT && TARGET_MIPS16"
2592 [(set_attr "type" "arith")
2593 (set_attr "mode" "DI")])
2595 (define_expand "xorsi3"
2596 [(set (match_operand:SI 0 "register_operand")
2597 (xor:SI (match_operand:SI 1 "uns_arith_operand")
2598 (match_operand:SI 2 "uns_arith_operand")))]
2603 [(set (match_operand:SI 0 "register_operand" "=d,d")
2604 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2605 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2610 [(set_attr "type" "arith")
2611 (set_attr "mode" "SI")])
2614 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
2615 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
2616 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
2622 [(set_attr "type" "arith")
2623 (set_attr "mode" "SI")
2624 (set_attr_alternative "length"
2626 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2631 (define_expand "xordi3"
2632 [(set (match_operand:DI 0 "register_operand")
2633 (xor:DI (match_operand:DI 1 "register_operand")
2634 (match_operand:DI 2 "uns_arith_operand")))]
2639 operands[1] = force_reg (DImode, operands[1]);
2640 operands[2] = force_reg (DImode, operands[2]);
2645 [(set (match_operand:DI 0 "register_operand" "=d,d")
2646 (xor:DI (match_operand:DI 1 "register_operand" "d,d")
2647 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2648 "TARGET_64BIT && !TARGET_MIPS16"
2652 [(set_attr "type" "arith")
2653 (set_attr "mode" "DI")])
2656 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
2657 (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
2658 (match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
2659 "TARGET_64BIT && TARGET_MIPS16"
2664 [(set_attr "type" "arith")
2665 (set_attr "mode" "DI")
2666 (set_attr_alternative "length"
2668 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2673 (define_insn "*norsi3"
2674 [(set (match_operand:SI 0 "register_operand" "=d")
2675 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
2676 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
2679 [(set_attr "type" "arith")
2680 (set_attr "mode" "SI")])
2682 (define_insn "*nordi3"
2683 [(set (match_operand:DI 0 "register_operand" "=d")
2684 (and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
2685 (not:DI (match_operand:DI 2 "register_operand" "d"))))]
2686 "TARGET_64BIT && !TARGET_MIPS16"
2688 [(set_attr "type" "arith")
2689 (set_attr "mode" "DI")])
2692 ;; ....................
2696 ;; ....................
2700 (define_insn "truncdfsf2"
2701 [(set (match_operand:SF 0 "register_operand" "=f")
2702 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2703 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2705 [(set_attr "type" "fcvt")
2706 (set_attr "mode" "SF")])
2708 ;; Integer truncation patterns. Truncating SImode values to smaller
2709 ;; modes is a no-op, as it is for most other GCC ports. Truncating
2710 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2711 ;; need to make sure that the lower 32 bits are properly sign-extended
2712 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
2713 ;; smaller than SImode is equivalent to two separate truncations:
2716 ;; DI ---> HI == DI ---> SI ---> HI
2717 ;; DI ---> QI == DI ---> SI ---> QI
2719 ;; Step A needs a real instruction but step B does not.
2721 (define_insn "truncdisi2"
2722 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2723 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2728 [(set_attr "type" "shift,store")
2729 (set_attr "mode" "SI")
2730 (set_attr "extended_mips16" "yes,*")])
2732 (define_insn "truncdihi2"
2733 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2734 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2739 [(set_attr "type" "shift,store")
2740 (set_attr "mode" "SI")
2741 (set_attr "extended_mips16" "yes,*")])
2743 (define_insn "truncdiqi2"
2744 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2745 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2750 [(set_attr "type" "shift,store")
2751 (set_attr "mode" "SI")
2752 (set_attr "extended_mips16" "yes,*")])
2754 ;; Combiner patterns to optimize shift/truncate combinations.
2757 [(set (match_operand:SI 0 "register_operand" "=d")
2759 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2760 (match_operand:DI 2 "const_arith_operand" ""))))]
2761 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2763 [(set_attr "type" "shift")
2764 (set_attr "mode" "SI")])
2767 [(set (match_operand:SI 0 "register_operand" "=d")
2768 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2770 "TARGET_64BIT && !TARGET_MIPS16"
2772 [(set_attr "type" "shift")
2773 (set_attr "mode" "SI")])
2776 ;; Combiner patterns for truncate/sign_extend combinations. They use
2777 ;; the shift/truncate patterns above.
2779 (define_insn_and_split ""
2780 [(set (match_operand:SI 0 "register_operand" "=d")
2782 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2783 "TARGET_64BIT && !TARGET_MIPS16"
2785 "&& reload_completed"
2787 (ashift:DI (match_dup 1)
2790 (truncate:SI (ashiftrt:DI (match_dup 2)
2792 { operands[2] = gen_lowpart (DImode, operands[0]); })
2794 (define_insn_and_split ""
2795 [(set (match_operand:SI 0 "register_operand" "=d")
2797 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2798 "TARGET_64BIT && !TARGET_MIPS16"
2800 "&& reload_completed"
2802 (ashift:DI (match_dup 1)
2805 (truncate:SI (ashiftrt:DI (match_dup 2)
2807 { operands[2] = gen_lowpart (DImode, operands[0]); })
2810 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2813 [(set (match_operand:SI 0 "register_operand" "=d")
2814 (zero_extend:SI (truncate:HI
2815 (match_operand:DI 1 "register_operand" "d"))))]
2816 "TARGET_64BIT && !TARGET_MIPS16"
2817 "andi\t%0,%1,0xffff"
2818 [(set_attr "type" "arith")
2819 (set_attr "mode" "SI")])
2822 [(set (match_operand:SI 0 "register_operand" "=d")
2823 (zero_extend:SI (truncate:QI
2824 (match_operand:DI 1 "register_operand" "d"))))]
2825 "TARGET_64BIT && !TARGET_MIPS16"
2827 [(set_attr "type" "arith")
2828 (set_attr "mode" "SI")])
2831 [(set (match_operand:HI 0 "register_operand" "=d")
2832 (zero_extend:HI (truncate:QI
2833 (match_operand:DI 1 "register_operand" "d"))))]
2834 "TARGET_64BIT && !TARGET_MIPS16"
2836 [(set_attr "type" "arith")
2837 (set_attr "mode" "HI")])
2840 ;; ....................
2844 ;; ....................
2847 ;; Those for integer source operand are ordered widest source type first.
2849 (define_insn_and_split "zero_extendsidi2"
2850 [(set (match_operand:DI 0 "register_operand" "=d")
2851 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2854 "&& reload_completed"
2856 (ashift:DI (match_dup 1) (const_int 32)))
2858 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2859 "operands[1] = gen_lowpart (DImode, operands[1]);"
2860 [(set_attr "type" "multi")
2861 (set_attr "mode" "DI")
2862 (set_attr "length" "8")])
2864 (define_insn "*zero_extendsidi2_mem"
2865 [(set (match_operand:DI 0 "register_operand" "=d")
2866 (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2869 [(set_attr "type" "load")
2870 (set_attr "mode" "DI")])
2872 (define_expand "zero_extendhisi2"
2873 [(set (match_operand:SI 0 "register_operand")
2874 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2877 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2879 rtx op = gen_lowpart (SImode, operands[1]);
2880 rtx temp = force_reg (SImode, GEN_INT (0xffff));
2882 emit_insn (gen_andsi3 (operands[0], op, temp));
2888 [(set (match_operand:SI 0 "register_operand" "=d,d")
2889 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2894 [(set_attr "type" "arith,load")
2895 (set_attr "mode" "SI")
2896 (set_attr "length" "4,*")])
2899 [(set (match_operand:SI 0 "register_operand" "=d")
2900 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2903 [(set_attr "type" "load")
2904 (set_attr "mode" "SI")])
2906 (define_expand "zero_extendhidi2"
2907 [(set (match_operand:DI 0 "register_operand")
2908 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2911 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2913 rtx op = gen_lowpart (DImode, operands[1]);
2914 rtx temp = force_reg (DImode, GEN_INT (0xffff));
2916 emit_insn (gen_anddi3 (operands[0], op, temp));
2922 [(set (match_operand:DI 0 "register_operand" "=d,d")
2923 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2924 "TARGET_64BIT && !TARGET_MIPS16"
2928 [(set_attr "type" "arith,load")
2929 (set_attr "mode" "DI")
2930 (set_attr "length" "4,*")])
2933 [(set (match_operand:DI 0 "register_operand" "=d")
2934 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2935 "TARGET_64BIT && TARGET_MIPS16"
2937 [(set_attr "type" "load")
2938 (set_attr "mode" "DI")])
2940 (define_expand "zero_extendqihi2"
2941 [(set (match_operand:HI 0 "register_operand")
2942 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2945 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2947 rtx op0 = gen_lowpart (SImode, operands[0]);
2948 rtx op1 = gen_lowpart (SImode, operands[1]);
2949 rtx temp = force_reg (SImode, GEN_INT (0xff));
2951 emit_insn (gen_andsi3 (op0, op1, temp));
2957 [(set (match_operand:HI 0 "register_operand" "=d,d")
2958 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2963 [(set_attr "type" "arith,load")
2964 (set_attr "mode" "HI")
2965 (set_attr "length" "4,*")])
2968 [(set (match_operand:HI 0 "register_operand" "=d")
2969 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2972 [(set_attr "type" "load")
2973 (set_attr "mode" "HI")])
2975 (define_expand "zero_extendqisi2"
2976 [(set (match_operand:SI 0 "register_operand")
2977 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2980 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2982 rtx op = gen_lowpart (SImode, operands[1]);
2983 rtx temp = force_reg (SImode, GEN_INT (0xff));
2985 emit_insn (gen_andsi3 (operands[0], op, temp));
2991 [(set (match_operand:SI 0 "register_operand" "=d,d")
2992 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2997 [(set_attr "type" "arith,load")
2998 (set_attr "mode" "SI")
2999 (set_attr "length" "4,*")])
3002 [(set (match_operand:SI 0 "register_operand" "=d")
3003 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3006 [(set_attr "type" "load")
3007 (set_attr "mode" "SI")])
3009 (define_expand "zero_extendqidi2"
3010 [(set (match_operand:DI 0 "register_operand")
3011 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3014 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3016 rtx op = gen_lowpart (DImode, operands[1]);
3017 rtx temp = force_reg (DImode, GEN_INT (0xff));
3019 emit_insn (gen_anddi3 (operands[0], op, temp));
3025 [(set (match_operand:DI 0 "register_operand" "=d,d")
3026 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3027 "TARGET_64BIT && !TARGET_MIPS16"
3031 [(set_attr "type" "arith,load")
3032 (set_attr "mode" "DI")
3033 (set_attr "length" "4,*")])
3036 [(set (match_operand:DI 0 "register_operand" "=d")
3037 (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3038 "TARGET_64BIT && TARGET_MIPS16"
3040 [(set_attr "type" "load")
3041 (set_attr "mode" "DI")])
3044 ;; ....................
3048 ;; ....................
3051 ;; Those for integer source operand are ordered widest source type first.
3053 ;; When TARGET_64BIT, all SImode integer registers should already be in
3054 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
3055 ;; therefore get rid of register->register instructions if we constrain
3056 ;; the source to be in the same register as the destination.
3058 ;; The register alternative has type "arith" so that the pre-reload
3059 ;; scheduler will treat it as a move. This reflects what happens if
3060 ;; the register alternative needs a reload.
3061 (define_insn_and_split "extendsidi2"
3062 [(set (match_operand:DI 0 "register_operand" "=d,d")
3063 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
3068 "&& reload_completed && register_operand (operands[1], VOIDmode)"
3071 emit_note (NOTE_INSN_DELETED);
3074 [(set_attr "type" "arith,load")
3075 (set_attr "mode" "DI")])
3077 ;; These patterns originally accepted general_operands, however, slightly
3078 ;; better code is generated by only accepting register_operands, and then
3079 ;; letting combine generate the lh and lb insns.
3081 ;; These expanders originally put values in registers first. We split
3082 ;; all non-mem patterns after reload.
3084 (define_expand "extendhidi2"
3085 [(set (match_operand:DI 0 "register_operand")
3086 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
3090 (define_insn "*extendhidi2"
3091 [(set (match_operand:DI 0 "register_operand" "=d")
3092 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
3097 [(set (match_operand:DI 0 "register_operand")
3098 (sign_extend:DI (match_operand:HI 1 "register_operand")))]
3099 "TARGET_64BIT && reload_completed"
3101 (ashift:DI (match_dup 1) (const_int 48)))
3103 (ashiftrt:DI (match_dup 0) (const_int 48)))]
3104 "operands[1] = gen_lowpart (DImode, operands[1]);")
3106 (define_insn "*extendhidi2_mem"
3107 [(set (match_operand:DI 0 "register_operand" "=d")
3108 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3111 [(set_attr "type" "load")
3112 (set_attr "mode" "DI")])
3114 (define_expand "extendhisi2"
3115 [(set (match_operand:SI 0 "register_operand")
3116 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
3119 if (ISA_HAS_SEB_SEH)
3121 emit_insn (gen_extendhisi2_hw (operands[0],
3122 force_reg (HImode, operands[1])));
3127 (define_insn "*extendhisi2"
3128 [(set (match_operand:SI 0 "register_operand" "=d")
3129 (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
3134 [(set (match_operand:SI 0 "register_operand")
3135 (sign_extend:SI (match_operand:HI 1 "register_operand")))]
3138 (ashift:SI (match_dup 1) (const_int 16)))
3140 (ashiftrt:SI (match_dup 0) (const_int 16)))]
3141 "operands[1] = gen_lowpart (SImode, operands[1]);")
3143 (define_insn "extendhisi2_mem"
3144 [(set (match_operand:SI 0 "register_operand" "=d")
3145 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3148 [(set_attr "type" "load")
3149 (set_attr "mode" "SI")])
3151 (define_insn "extendhisi2_hw"
3152 [(set (match_operand:SI 0 "register_operand" "=r")
3153 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
3156 [(set_attr "type" "arith")
3157 (set_attr "mode" "SI")])
3159 (define_expand "extendqihi2"
3160 [(set (match_operand:HI 0 "register_operand")
3161 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3165 (define_insn "*extendqihi2"
3166 [(set (match_operand:HI 0 "register_operand" "=d")
3167 (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
3172 [(set (match_operand:HI 0 "register_operand")
3173 (sign_extend:HI (match_operand:QI 1 "register_operand")))]
3176 (ashift:SI (match_dup 1) (const_int 24)))
3178 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3179 "operands[0] = gen_lowpart (SImode, operands[0]);
3180 operands[1] = gen_lowpart (SImode, operands[1]);")
3182 (define_insn "*extendqihi2_internal_mem"
3183 [(set (match_operand:HI 0 "register_operand" "=d")
3184 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3187 [(set_attr "type" "load")
3188 (set_attr "mode" "SI")])
3191 (define_expand "extendqisi2"
3192 [(set (match_operand:SI 0 "register_operand")
3193 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3196 if (ISA_HAS_SEB_SEH)
3198 emit_insn (gen_extendqisi2_hw (operands[0],
3199 force_reg (QImode, operands[1])));
3204 (define_insn "*extendqisi2"
3205 [(set (match_operand:SI 0 "register_operand" "=d")
3206 (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
3211 [(set (match_operand:SI 0 "register_operand")
3212 (sign_extend:SI (match_operand:QI 1 "register_operand")))]
3215 (ashift:SI (match_dup 1) (const_int 24)))
3217 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3218 "operands[1] = gen_lowpart (SImode, operands[1]);")
3220 (define_insn "*extendqisi2_mem"
3221 [(set (match_operand:SI 0 "register_operand" "=d")
3222 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3225 [(set_attr "type" "load")
3226 (set_attr "mode" "SI")])
3228 (define_insn "extendqisi2_hw"
3229 [(set (match_operand:SI 0 "register_operand" "=r")
3230 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
3233 [(set_attr "type" "arith")
3234 (set_attr "mode" "SI")])
3236 (define_expand "extendqidi2"
3237 [(set (match_operand:DI 0 "register_operand")
3238 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3242 (define_insn "*extendqidi2"
3243 [(set (match_operand:DI 0 "register_operand" "=d")
3244 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
3249 [(set (match_operand:DI 0 "register_operand")
3250 (sign_extend:DI (match_operand:QI 1 "register_operand")))]
3251 "TARGET_64BIT && reload_completed"
3253 (ashift:DI (match_dup 1) (const_int 56)))
3255 (ashiftrt:DI (match_dup 0) (const_int 56)))]
3256 "operands[1] = gen_lowpart (DImode, operands[1]);")
3258 (define_insn "*extendqidi2_mem"
3259 [(set (match_operand:DI 0 "register_operand" "=d")
3260 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3263 [(set_attr "type" "load")
3264 (set_attr "mode" "DI")])
3266 (define_insn "extendsfdf2"
3267 [(set (match_operand:DF 0 "register_operand" "=f")
3268 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3269 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3271 [(set_attr "type" "fcvt")
3272 (set_attr "mode" "DF")])
3275 ;; ....................
3279 ;; ....................
3281 (define_expand "fix_truncdfsi2"
3282 [(set (match_operand:SI 0 "register_operand")
3283 (fix:SI (match_operand:DF 1 "register_operand")))]
3284 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3286 if (!ISA_HAS_TRUNC_W)
3288 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3293 (define_insn "fix_truncdfsi2_insn"
3294 [(set (match_operand:SI 0 "register_operand" "=f")
3295 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3296 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3298 [(set_attr "type" "fcvt")
3299 (set_attr "mode" "DF")
3300 (set_attr "length" "4")])
3302 (define_insn "fix_truncdfsi2_macro"
3303 [(set (match_operand:SI 0 "register_operand" "=f")
3304 (fix:SI (match_operand:DF 1 "register_operand" "f")))
3305 (clobber (match_scratch:DF 2 "=d"))]
3306 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3309 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3311 return "trunc.w.d %0,%1,%2";
3313 [(set_attr "type" "fcvt")
3314 (set_attr "mode" "DF")
3315 (set_attr "length" "36")])
3317 (define_expand "fix_truncsfsi2"
3318 [(set (match_operand:SI 0 "register_operand")
3319 (fix:SI (match_operand:SF 1 "register_operand")))]
3322 if (!ISA_HAS_TRUNC_W)
3324 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3329 (define_insn "fix_truncsfsi2_insn"
3330 [(set (match_operand:SI 0 "register_operand" "=f")
3331 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3332 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3334 [(set_attr "type" "fcvt")
3335 (set_attr "mode" "DF")
3336 (set_attr "length" "4")])
3338 (define_insn "fix_truncsfsi2_macro"
3339 [(set (match_operand:SI 0 "register_operand" "=f")
3340 (fix:SI (match_operand:SF 1 "register_operand" "f")))
3341 (clobber (match_scratch:SF 2 "=d"))]
3342 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3345 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3347 return "trunc.w.s %0,%1,%2";
3349 [(set_attr "type" "fcvt")
3350 (set_attr "mode" "DF")
3351 (set_attr "length" "36")])
3354 (define_insn "fix_truncdfdi2"
3355 [(set (match_operand:DI 0 "register_operand" "=f")
3356 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3357 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3359 [(set_attr "type" "fcvt")
3360 (set_attr "mode" "DF")
3361 (set_attr "length" "4")])
3364 (define_insn "fix_truncsfdi2"
3365 [(set (match_operand:DI 0 "register_operand" "=f")
3366 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3367 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3369 [(set_attr "type" "fcvt")
3370 (set_attr "mode" "SF")
3371 (set_attr "length" "4")])
3374 (define_insn "floatsidf2"
3375 [(set (match_operand:DF 0 "register_operand" "=f")
3376 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3377 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3379 [(set_attr "type" "fcvt")
3380 (set_attr "mode" "DF")
3381 (set_attr "length" "4")])
3384 (define_insn "floatdidf2"
3385 [(set (match_operand:DF 0 "register_operand" "=f")
3386 (float:DF (match_operand:DI 1 "register_operand" "f")))]
3387 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3389 [(set_attr "type" "fcvt")
3390 (set_attr "mode" "DF")
3391 (set_attr "length" "4")])
3394 (define_insn "floatsisf2"
3395 [(set (match_operand:SF 0 "register_operand" "=f")
3396 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3399 [(set_attr "type" "fcvt")
3400 (set_attr "mode" "SF")
3401 (set_attr "length" "4")])
3404 (define_insn "floatdisf2"
3405 [(set (match_operand:SF 0 "register_operand" "=f")
3406 (float:SF (match_operand:DI 1 "register_operand" "f")))]
3407 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3409 [(set_attr "type" "fcvt")
3410 (set_attr "mode" "SF")
3411 (set_attr "length" "4")])
3414 (define_expand "fixuns_truncdfsi2"
3415 [(set (match_operand:SI 0 "register_operand")
3416 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
3417 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3419 rtx reg1 = gen_reg_rtx (DFmode);
3420 rtx reg2 = gen_reg_rtx (DFmode);
3421 rtx reg3 = gen_reg_rtx (SImode);
3422 rtx label1 = gen_label_rtx ();
3423 rtx label2 = gen_label_rtx ();
3424 REAL_VALUE_TYPE offset;
3426 real_2expN (&offset, 31);
3428 if (reg1) /* Turn off complaints about unreached code. */
3430 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3431 do_pending_stack_adjust ();
3433 emit_insn (gen_cmpdf (operands[1], reg1));
3434 emit_jump_insn (gen_bge (label1));
3436 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3437 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3438 gen_rtx_LABEL_REF (VOIDmode, label2)));
3441 emit_label (label1);
3442 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3443 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3444 (BITMASK_HIGH, SImode)));
3446 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3447 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3449 emit_label (label2);
3451 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3452 fields, and can't be used for REG_NOTES anyway). */
3453 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3459 (define_expand "fixuns_truncdfdi2"
3460 [(set (match_operand:DI 0 "register_operand")
3461 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3462 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3464 rtx reg1 = gen_reg_rtx (DFmode);
3465 rtx reg2 = gen_reg_rtx (DFmode);
3466 rtx reg3 = gen_reg_rtx (DImode);
3467 rtx label1 = gen_label_rtx ();
3468 rtx label2 = gen_label_rtx ();
3469 REAL_VALUE_TYPE offset;
3471 real_2expN (&offset, 63);
3473 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3474 do_pending_stack_adjust ();
3476 emit_insn (gen_cmpdf (operands[1], reg1));
3477 emit_jump_insn (gen_bge (label1));
3479 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3480 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3481 gen_rtx_LABEL_REF (VOIDmode, label2)));
3484 emit_label (label1);
3485 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3486 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3487 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3489 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3490 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3492 emit_label (label2);
3494 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3495 fields, and can't be used for REG_NOTES anyway). */
3496 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3501 (define_expand "fixuns_truncsfsi2"
3502 [(set (match_operand:SI 0 "register_operand")
3503 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3506 rtx reg1 = gen_reg_rtx (SFmode);
3507 rtx reg2 = gen_reg_rtx (SFmode);
3508 rtx reg3 = gen_reg_rtx (SImode);
3509 rtx label1 = gen_label_rtx ();
3510 rtx label2 = gen_label_rtx ();
3511 REAL_VALUE_TYPE offset;
3513 real_2expN (&offset, 31);
3515 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3516 do_pending_stack_adjust ();
3518 emit_insn (gen_cmpsf (operands[1], reg1));
3519 emit_jump_insn (gen_bge (label1));
3521 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3522 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3523 gen_rtx_LABEL_REF (VOIDmode, label2)));
3526 emit_label (label1);
3527 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3528 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3529 (BITMASK_HIGH, SImode)));
3531 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3532 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3534 emit_label (label2);
3536 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3537 fields, and can't be used for REG_NOTES anyway). */
3538 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3543 (define_expand "fixuns_truncsfdi2"
3544 [(set (match_operand:DI 0 "register_operand")
3545 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3546 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3548 rtx reg1 = gen_reg_rtx (SFmode);
3549 rtx reg2 = gen_reg_rtx (SFmode);
3550 rtx reg3 = gen_reg_rtx (DImode);
3551 rtx label1 = gen_label_rtx ();
3552 rtx label2 = gen_label_rtx ();
3553 REAL_VALUE_TYPE offset;
3555 real_2expN (&offset, 63);
3557 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3558 do_pending_stack_adjust ();
3560 emit_insn (gen_cmpsf (operands[1], reg1));
3561 emit_jump_insn (gen_bge (label1));
3563 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3564 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3565 gen_rtx_LABEL_REF (VOIDmode, label2)));
3568 emit_label (label1);
3569 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3570 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3571 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3573 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3574 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3576 emit_label (label2);
3578 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3579 fields, and can't be used for REG_NOTES anyway). */
3580 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3585 ;; ....................
3589 ;; ....................
3591 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3593 (define_expand "extv"
3594 [(set (match_operand 0 "register_operand")
3595 (sign_extract (match_operand:QI 1 "memory_operand")
3596 (match_operand 2 "immediate_operand")
3597 (match_operand 3 "immediate_operand")))]
3600 if (mips_expand_unaligned_load (operands[0], operands[1],
3601 INTVAL (operands[2]),
3602 INTVAL (operands[3])))
3608 (define_expand "extzv"
3609 [(set (match_operand 0 "register_operand")
3610 (zero_extract (match_operand:QI 1 "memory_operand")
3611 (match_operand 2 "immediate_operand")
3612 (match_operand 3 "immediate_operand")))]
3615 if (mips_expand_unaligned_load (operands[0], operands[1],
3616 INTVAL (operands[2]),
3617 INTVAL (operands[3])))
3623 (define_expand "insv"
3624 [(set (zero_extract (match_operand:QI 0 "memory_operand")
3625 (match_operand 1 "immediate_operand")
3626 (match_operand 2 "immediate_operand"))
3627 (match_operand 3 "reg_or_0_operand"))]
3630 if (mips_expand_unaligned_store (operands[0], operands[3],
3631 INTVAL (operands[1]),
3632 INTVAL (operands[2])))
3638 ;; Unaligned word moves generated by the bit field patterns.
3640 ;; As far as the rtl is concerned, both the left-part and right-part
3641 ;; instructions can access the whole field. However, the real operand
3642 ;; refers to just the first or the last byte (depending on endianness).
3643 ;; We therefore use two memory operands to each instruction, one to
3644 ;; describe the rtl effect and one to use in the assembly output.
3646 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3647 ;; This allows us to use the standard length calculations for the "load"
3648 ;; and "store" type attributes.
3650 (define_insn "mov_lwl"
3651 [(set (match_operand:SI 0 "register_operand" "=d")
3652 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3653 (match_operand:QI 2 "memory_operand" "m")]
3657 [(set_attr "type" "load")
3658 (set_attr "mode" "SI")
3659 (set_attr "hazard" "none")])
3661 (define_insn "mov_lwr"
3662 [(set (match_operand:SI 0 "register_operand" "=d")
3663 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3664 (match_operand:QI 2 "memory_operand" "m")
3665 (match_operand:SI 3 "register_operand" "0")]
3669 [(set_attr "type" "load")
3670 (set_attr "mode" "SI")])
3673 (define_insn "mov_swl"
3674 [(set (match_operand:BLK 0 "memory_operand" "=m")
3675 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3676 (match_operand:QI 2 "memory_operand" "m")]
3680 [(set_attr "type" "store")
3681 (set_attr "mode" "SI")])
3683 (define_insn "mov_swr"
3684 [(set (match_operand:BLK 0 "memory_operand" "+m")
3685 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3686 (match_operand:QI 2 "memory_operand" "m")
3691 [(set_attr "type" "store")
3692 (set_attr "mode" "SI")])
3695 (define_insn "mov_ldl"
3696 [(set (match_operand:DI 0 "register_operand" "=d")
3697 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3698 (match_operand:QI 2 "memory_operand" "m")]
3700 "TARGET_64BIT && !TARGET_MIPS16"
3702 [(set_attr "type" "load")
3703 (set_attr "mode" "DI")])
3705 (define_insn "mov_ldr"
3706 [(set (match_operand:DI 0 "register_operand" "=d")
3707 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3708 (match_operand:QI 2 "memory_operand" "m")
3709 (match_operand:DI 3 "register_operand" "0")]
3711 "TARGET_64BIT && !TARGET_MIPS16"
3713 [(set_attr "type" "load")
3714 (set_attr "mode" "DI")])
3717 (define_insn "mov_sdl"
3718 [(set (match_operand:BLK 0 "memory_operand" "=m")
3719 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3720 (match_operand:QI 2 "memory_operand" "m")]
3722 "TARGET_64BIT && !TARGET_MIPS16"
3724 [(set_attr "type" "store")
3725 (set_attr "mode" "DI")])
3727 (define_insn "mov_sdr"
3728 [(set (match_operand:BLK 0 "memory_operand" "+m")
3729 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3730 (match_operand:QI 2 "memory_operand" "m")
3733 "TARGET_64BIT && !TARGET_MIPS16"
3735 [(set_attr "type" "store")
3736 (set_attr "mode" "DI")])
3738 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3739 ;; The required value is:
3741 ;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3743 ;; which translates to:
3745 ;; lui op0,%highest(op1)
3746 ;; daddiu op0,op0,%higher(op1)
3748 ;; daddiu op0,op0,%hi(op1)
3750 (define_insn_and_split "*lea_high64"
3751 [(set (match_operand:DI 0 "register_operand" "=d")
3752 (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3753 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3755 "&& reload_completed"
3756 [(set (match_dup 0) (high:DI (match_dup 2)))
3757 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3758 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3759 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3760 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3762 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3763 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3765 [(set_attr "length" "20")])
3767 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3768 ;; SYMBOL_GENERAL X will take 6 cycles. This next pattern allows combine
3769 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3770 ;; used once. We can then use the sequence:
3772 ;; lui op0,%highest(op1)
3774 ;; daddiu op0,op0,%higher(op1)
3775 ;; daddiu op2,op2,%lo(op1)
3777 ;; daddu op0,op0,op2
3779 ;; which takes 4 cycles on most superscalar targets.
3780 (define_insn_and_split "*lea64"
3781 [(set (match_operand:DI 0 "register_operand" "=d")
3782 (match_operand:DI 1 "general_symbolic_operand" ""))
3783 (clobber (match_scratch:DI 2 "=&d"))]
3784 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3786 "&& reload_completed"
3787 [(set (match_dup 0) (high:DI (match_dup 3)))
3788 (set (match_dup 2) (high:DI (match_dup 4)))
3789 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3790 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3791 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3792 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3794 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3795 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3797 [(set_attr "length" "24")])
3799 ;; Insns to fetch a global symbol from a big GOT.
3801 (define_insn_and_split "*xgot_hisi"
3802 [(set (match_operand:SI 0 "register_operand" "=d")
3803 (high:SI (match_operand:SI 1 "global_got_operand" "")))]
3804 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3806 "&& reload_completed"
3807 [(set (match_dup 0) (high:SI (match_dup 2)))
3808 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
3810 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3811 operands[3] = pic_offset_table_rtx;
3813 [(set_attr "got" "xgot_high")])
3815 (define_insn_and_split "*xgot_losi"
3816 [(set (match_operand:SI 0 "register_operand" "=d")
3817 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
3818 (match_operand:SI 2 "global_got_operand" "")))]
3819 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3821 "&& reload_completed"
3823 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3824 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3825 [(set_attr "got" "load")])
3827 (define_insn_and_split "*xgot_hidi"
3828 [(set (match_operand:DI 0 "register_operand" "=d")
3829 (high:DI (match_operand:DI 1 "global_got_operand" "")))]
3830 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3832 "&& reload_completed"
3833 [(set (match_dup 0) (high:DI (match_dup 2)))
3834 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
3836 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3837 operands[3] = pic_offset_table_rtx;
3839 [(set_attr "got" "xgot_high")])
3841 (define_insn_and_split "*xgot_lodi"
3842 [(set (match_operand:DI 0 "register_operand" "=d")
3843 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
3844 (match_operand:DI 2 "global_got_operand" "")))]
3845 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3847 "&& reload_completed"
3849 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3850 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3851 [(set_attr "got" "load")])
3853 ;; Insns to fetch a global symbol from a normal GOT.
3855 (define_insn_and_split "*got_dispsi"
3856 [(set (match_operand:SI 0 "register_operand" "=d")
3857 (match_operand:SI 1 "global_got_operand" ""))]
3858 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3860 "&& reload_completed"
3862 (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3864 operands[2] = pic_offset_table_rtx;
3865 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3867 [(set_attr "got" "load")])
3869 (define_insn_and_split "*got_dispdi"
3870 [(set (match_operand:DI 0 "register_operand" "=d")
3871 (match_operand:DI 1 "global_got_operand" ""))]
3872 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3874 "&& reload_completed"
3876 (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3878 operands[2] = pic_offset_table_rtx;
3879 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3881 [(set_attr "got" "load")])
3883 ;; Insns for loading the high part of a local symbol.
3885 (define_insn_and_split "*got_pagesi"
3886 [(set (match_operand:SI 0 "register_operand" "=d")
3887 (high:SI (match_operand:SI 1 "local_got_operand" "")))]
3888 "TARGET_EXPLICIT_RELOCS"
3890 "&& reload_completed"
3892 (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3894 operands[2] = pic_offset_table_rtx;
3895 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3897 [(set_attr "got" "load")])
3899 (define_insn_and_split "*got_pagedi"
3900 [(set (match_operand:DI 0 "register_operand" "=d")
3901 (high:DI (match_operand:DI 1 "local_got_operand" "")))]
3902 "TARGET_EXPLICIT_RELOCS"
3904 "&& reload_completed"
3906 (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3908 operands[2] = pic_offset_table_rtx;
3909 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3911 [(set_attr "got" "load")])
3913 ;; Lower-level instructions for loading an address from the GOT.
3914 ;; We could use MEMs, but an unspec gives more optimization
3917 (define_insn "*load_gotsi"
3918 [(set (match_operand:SI 0 "register_operand" "=d")
3919 (unspec:SI [(match_operand:SI 1 "register_operand" "d")
3920 (match_operand:SI 2 "immediate_operand" "")]
3924 [(set_attr "type" "load")
3925 (set_attr "length" "4")])
3927 (define_insn "*load_gotdi"
3928 [(set (match_operand:DI 0 "register_operand" "=d")
3929 (unspec:DI [(match_operand:DI 1 "register_operand" "d")
3930 (match_operand:DI 2 "immediate_operand" "")]
3934 [(set_attr "type" "load")
3935 (set_attr "length" "4")])
3937 ;; Instructions for adding the low 16 bits of an address to a register.
3938 ;; Operand 2 is the address: print_operand works out which relocation
3939 ;; should be applied.
3941 (define_insn "*lowsi"
3942 [(set (match_operand:SI 0 "register_operand" "=d")
3943 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
3944 (match_operand:SI 2 "immediate_operand" "")))]
3947 [(set_attr "type" "arith")
3948 (set_attr "mode" "SI")])
3950 (define_insn "*lowdi"
3951 [(set (match_operand:DI 0 "register_operand" "=d")
3952 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
3953 (match_operand:DI 2 "immediate_operand" "")))]
3954 "!TARGET_MIPS16 && TARGET_64BIT"
3956 [(set_attr "type" "arith")
3957 (set_attr "mode" "DI")])
3959 (define_insn "*lowsi_mips16"
3960 [(set (match_operand:SI 0 "register_operand" "=d")
3961 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
3962 (match_operand:SI 2 "immediate_operand" "")))]
3965 [(set_attr "type" "arith")
3966 (set_attr "mode" "SI")
3967 (set_attr "length" "8")])
3969 (define_insn "*lowdi_mips16"
3970 [(set (match_operand:DI 0 "register_operand" "=d")
3971 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
3972 (match_operand:DI 2 "immediate_operand" "")))]
3973 "TARGET_MIPS16 && TARGET_64BIT"
3975 [(set_attr "type" "arith")
3976 (set_attr "mode" "DI")
3977 (set_attr "length" "8")])
3979 ;; 64-bit integer moves
3981 ;; Unlike most other insns, the move insns can't be split with
3982 ;; different predicates, because register spilling and other parts of
3983 ;; the compiler, have memoized the insn number already.
3985 (define_expand "movdi"
3986 [(set (match_operand:DI 0 "")
3987 (match_operand:DI 1 ""))]
3990 if (mips_legitimize_move (DImode, operands[0], operands[1]))
3994 ;; For mips16, we need a special case to handle storing $31 into
3995 ;; memory, since we don't have a constraint to match $31. This
3996 ;; instruction can be generated by save_restore_insns.
3999 [(set (match_operand:DI 0 "stack_operand" "=m")
4001 "TARGET_MIPS16 && TARGET_64BIT"
4003 [(set_attr "type" "store")
4004 (set_attr "mode" "DI")])
4006 (define_insn "*movdi_32bit"
4007 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
4008 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
4009 "!TARGET_64BIT && !TARGET_MIPS16
4010 && (register_operand (operands[0], DImode)
4011 || reg_or_0_operand (operands[1], DImode))"
4012 { return mips_output_move (operands[0], operands[1]); }
4013 [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
4014 (set_attr "mode" "DI")
4015 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
4017 (define_insn "*movdi_32bit_mips16"
4018 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4019 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4020 "!TARGET_64BIT && TARGET_MIPS16
4021 && (register_operand (operands[0], DImode)
4022 || register_operand (operands[1], DImode))"
4023 { return mips_output_move (operands[0], operands[1]); }
4024 [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo")
4025 (set_attr "mode" "DI")
4026 (set_attr "length" "8,8,8,8,12,*,*,8")])
4028 (define_insn "*movdi_64bit"
4029 [(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")
4030 (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"))]
4031 "TARGET_64BIT && !TARGET_MIPS16
4032 && (register_operand (operands[0], DImode)
4033 || reg_or_0_operand (operands[1], DImode))"
4034 { return mips_output_move (operands[0], operands[1]); }
4035 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
4036 (set_attr "mode" "DI")
4037 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
4039 (define_insn "*movdi_64bit_mips16"
4040 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4041 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4042 "TARGET_64BIT && TARGET_MIPS16
4043 && (register_operand (operands[0], DImode)
4044 || register_operand (operands[1], DImode))"
4045 { return mips_output_move (operands[0], operands[1]); }
4046 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
4047 (set_attr "mode" "DI")
4048 (set_attr_alternative "length"
4052 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4055 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4060 (const_string "*")])])
4063 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4064 ;; when the original load is a 4 byte instruction but the add and the
4065 ;; load are 2 2 byte instructions.
4068 [(set (match_operand:DI 0 "register_operand")
4069 (mem:DI (plus:DI (match_dup 0)
4070 (match_operand:DI 1 "const_int_operand"))))]
4071 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4072 && !TARGET_DEBUG_D_MODE
4073 && GET_CODE (operands[0]) == REG
4074 && M16_REG_P (REGNO (operands[0]))
4075 && GET_CODE (operands[1]) == CONST_INT
4076 && ((INTVAL (operands[1]) < 0
4077 && INTVAL (operands[1]) >= -0x10)
4078 || (INTVAL (operands[1]) >= 32 * 8
4079 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4080 || (INTVAL (operands[1]) >= 0
4081 && INTVAL (operands[1]) < 32 * 8
4082 && (INTVAL (operands[1]) & 7) != 0))"
4083 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4084 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4086 HOST_WIDE_INT val = INTVAL (operands[1]);
4089 operands[2] = const0_rtx;
4090 else if (val >= 32 * 8)
4094 operands[1] = GEN_INT (0x8 + off);
4095 operands[2] = GEN_INT (val - off - 0x8);
4101 operands[1] = GEN_INT (off);
4102 operands[2] = GEN_INT (val - off);
4106 ;; 32-bit Integer moves
4108 ;; Unlike most other insns, the move insns can't be split with
4109 ;; different predicates, because register spilling and other parts of
4110 ;; the compiler, have memoized the insn number already.
4112 (define_expand "movsi"
4113 [(set (match_operand:SI 0 "")
4114 (match_operand:SI 1 ""))]
4117 if (mips_legitimize_move (SImode, operands[0], operands[1]))
4121 ;; We can only store $ra directly into a small sp offset.
4124 [(set (match_operand:SI 0 "stack_operand" "=m")
4128 [(set_attr "type" "store")
4129 (set_attr "mode" "SI")])
4131 ;; The difference between these two is whether or not ints are allowed
4132 ;; in FP registers (off by default, use -mdebugh to enable).
4134 (define_insn "*movsi_internal"
4135 [(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")
4136 (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"))]
4138 && (register_operand (operands[0], SImode)
4139 || reg_or_0_operand (operands[1], SImode))"
4140 { return mips_output_move (operands[0], operands[1]); }
4141 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
4142 (set_attr "mode" "SI")
4143 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
4145 (define_insn "*movsi_mips16"
4146 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4147 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4149 && (register_operand (operands[0], SImode)
4150 || register_operand (operands[1], SImode))"
4151 { return mips_output_move (operands[0], operands[1]); }
4152 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
4153 (set_attr "mode" "SI")
4154 (set_attr_alternative "length"
4158 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4161 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4166 (const_string "*")])])
4168 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4169 ;; when the original load is a 4 byte instruction but the add and the
4170 ;; load are 2 2 byte instructions.
4173 [(set (match_operand:SI 0 "register_operand")
4174 (mem:SI (plus:SI (match_dup 0)
4175 (match_operand:SI 1 "const_int_operand"))))]
4176 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4177 && GET_CODE (operands[0]) == REG
4178 && M16_REG_P (REGNO (operands[0]))
4179 && GET_CODE (operands[1]) == CONST_INT
4180 && ((INTVAL (operands[1]) < 0
4181 && INTVAL (operands[1]) >= -0x80)
4182 || (INTVAL (operands[1]) >= 32 * 4
4183 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4184 || (INTVAL (operands[1]) >= 0
4185 && INTVAL (operands[1]) < 32 * 4
4186 && (INTVAL (operands[1]) & 3) != 0))"
4187 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4188 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4190 HOST_WIDE_INT val = INTVAL (operands[1]);
4193 operands[2] = const0_rtx;
4194 else if (val >= 32 * 4)
4198 operands[1] = GEN_INT (0x7c + off);
4199 operands[2] = GEN_INT (val - off - 0x7c);
4205 operands[1] = GEN_INT (off);
4206 operands[2] = GEN_INT (val - off);
4210 ;; On the mips16, we can split a load of certain constants into a load
4211 ;; and an add. This turns a 4 byte instruction into 2 2 byte
4215 [(set (match_operand:SI 0 "register_operand")
4216 (match_operand:SI 1 "const_int_operand"))]
4217 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4218 && GET_CODE (operands[0]) == REG
4219 && M16_REG_P (REGNO (operands[0]))
4220 && GET_CODE (operands[1]) == CONST_INT
4221 && INTVAL (operands[1]) >= 0x100
4222 && INTVAL (operands[1]) <= 0xff + 0x7f"
4223 [(set (match_dup 0) (match_dup 1))
4224 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4226 int val = INTVAL (operands[1]);
4228 operands[1] = GEN_INT (0xff);
4229 operands[2] = GEN_INT (val - 0xff);
4232 ;; This insn handles moving CCmode values. It's really just a
4233 ;; slightly simplified copy of movsi_internal2, with additional cases
4234 ;; to move a condition register to a general register and to move
4235 ;; between the general registers and the floating point registers.
4237 (define_insn "movcc"
4238 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
4239 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
4240 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4241 { return mips_output_move (operands[0], operands[1]); }
4242 [(set_attr "type" "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
4243 (set_attr "mode" "SI")
4244 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
4246 ;; Reload condition code registers. reload_incc and reload_outcc
4247 ;; both handle moves from arbitrary operands into condition code
4248 ;; registers. reload_incc handles the more common case in which
4249 ;; a source operand is constrained to be in a condition-code
4250 ;; register, but has not been allocated to one.
4252 ;; Sometimes, such as in movcc, we have a CCmode destination whose
4253 ;; constraints do not include 'z'. reload_outcc handles the case
4254 ;; when such an operand is allocated to a condition-code register.
4256 ;; Note that reloads from a condition code register to some
4257 ;; other location can be done using ordinary moves. Moving
4258 ;; into a GPR takes a single movcc, moving elsewhere takes
4259 ;; two. We can leave these cases to the generic reload code.
4260 (define_expand "reload_incc"
4261 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
4262 (match_operand:CC 1 "general_operand" ""))
4263 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4264 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4266 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4270 (define_expand "reload_outcc"
4271 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
4272 (match_operand:CC 1 "register_operand" ""))
4273 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4274 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4276 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4280 ;; MIPS4 supports loading and storing a floating point register from
4281 ;; the sum of two general registers. We use two versions for each of
4282 ;; these four instructions: one where the two general registers are
4283 ;; SImode, and one where they are DImode. This is because general
4284 ;; registers will be in SImode when they hold 32 bit values, but,
4285 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
4286 ;; instructions will still work correctly.
4288 ;; ??? Perhaps it would be better to support these instructions by
4289 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
4290 ;; these instructions can only be used to load and store floating
4291 ;; point registers, that would probably cause trouble in reload.
4294 [(set (match_operand:SF 0 "register_operand" "=f")
4295 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4296 (match_operand:SI 2 "register_operand" "d"))))]
4297 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4299 [(set_attr "type" "fpidxload")
4300 (set_attr "mode" "SF")
4301 (set_attr "length" "4")])
4304 [(set (match_operand:SF 0 "register_operand" "=f")
4305 (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4306 (match_operand:DI 2 "register_operand" "d"))))]
4307 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4309 [(set_attr "type" "fpidxload")
4310 (set_attr "mode" "SF")
4311 (set_attr "length" "4")])
4314 [(set (match_operand:DF 0 "register_operand" "=f")
4315 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4316 (match_operand:SI 2 "register_operand" "d"))))]
4317 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4319 [(set_attr "type" "fpidxload")
4320 (set_attr "mode" "DF")
4321 (set_attr "length" "4")])
4324 [(set (match_operand:DF 0 "register_operand" "=f")
4325 (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4326 (match_operand:DI 2 "register_operand" "d"))))]
4327 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4329 [(set_attr "type" "fpidxload")
4330 (set_attr "mode" "DF")
4331 (set_attr "length" "4")])
4334 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4335 (match_operand:SI 2 "register_operand" "d")))
4336 (match_operand:SF 0 "register_operand" "f"))]
4337 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4339 [(set_attr "type" "fpidxstore")
4340 (set_attr "mode" "SF")
4341 (set_attr "length" "4")])
4344 [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4345 (match_operand:DI 2 "register_operand" "d")))
4346 (match_operand:SF 0 "register_operand" "f"))]
4347 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4349 [(set_attr "type" "fpidxstore")
4350 (set_attr "mode" "SF")
4351 (set_attr "length" "4")])
4354 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4355 (match_operand:SI 2 "register_operand" "d")))
4356 (match_operand:DF 0 "register_operand" "f"))]
4357 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4359 [(set_attr "type" "fpidxstore")
4360 (set_attr "mode" "DF")
4361 (set_attr "length" "4")])
4364 [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4365 (match_operand:DI 2 "register_operand" "d")))
4366 (match_operand:DF 0 "register_operand" "f"))]
4367 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4369 [(set_attr "type" "fpidxstore")
4370 (set_attr "mode" "DF")
4371 (set_attr "length" "4")])
4373 ;; 16-bit Integer moves
4375 ;; Unlike most other insns, the move insns can't be split with
4376 ;; different predicates, because register spilling and other parts of
4377 ;; the compiler, have memoized the insn number already.
4378 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4380 (define_expand "movhi"
4381 [(set (match_operand:HI 0 "")
4382 (match_operand:HI 1 ""))]
4385 if (mips_legitimize_move (HImode, operands[0], operands[1]))
4389 (define_insn "*movhi_internal"
4390 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4391 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4393 && (register_operand (operands[0], HImode)
4394 || reg_or_0_operand (operands[1], HImode))"
4404 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4405 (set_attr "mode" "HI")
4406 (set_attr "length" "4,4,*,*,4,4,4,4")])
4408 (define_insn "*movhi_mips16"
4409 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4410 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))]
4412 && (register_operand (operands[0], HImode)
4413 || register_operand (operands[1], HImode))"
4422 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4423 (set_attr "mode" "HI")
4424 (set_attr_alternative "length"
4428 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4431 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4435 (const_string "*")])])
4438 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4439 ;; when the original load is a 4 byte instruction but the add and the
4440 ;; load are 2 2 byte instructions.
4443 [(set (match_operand:HI 0 "register_operand")
4444 (mem:HI (plus:SI (match_dup 0)
4445 (match_operand:SI 1 "const_int_operand"))))]
4446 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4447 && GET_CODE (operands[0]) == REG
4448 && M16_REG_P (REGNO (operands[0]))
4449 && GET_CODE (operands[1]) == CONST_INT
4450 && ((INTVAL (operands[1]) < 0
4451 && INTVAL (operands[1]) >= -0x80)
4452 || (INTVAL (operands[1]) >= 32 * 2
4453 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4454 || (INTVAL (operands[1]) >= 0
4455 && INTVAL (operands[1]) < 32 * 2
4456 && (INTVAL (operands[1]) & 1) != 0))"
4457 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4458 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4460 HOST_WIDE_INT val = INTVAL (operands[1]);
4463 operands[2] = const0_rtx;
4464 else if (val >= 32 * 2)
4468 operands[1] = GEN_INT (0x7e + off);
4469 operands[2] = GEN_INT (val - off - 0x7e);
4475 operands[1] = GEN_INT (off);
4476 operands[2] = GEN_INT (val - off);
4480 ;; 8-bit Integer moves
4482 ;; Unlike most other insns, the move insns can't be split with
4483 ;; different predicates, because register spilling and other parts of
4484 ;; the compiler, have memoized the insn number already.
4485 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4487 (define_expand "movqi"
4488 [(set (match_operand:QI 0 "")
4489 (match_operand:QI 1 ""))]
4492 if (mips_legitimize_move (QImode, operands[0], operands[1]))
4496 (define_insn "*movqi_internal"
4497 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4498 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4500 && (register_operand (operands[0], QImode)
4501 || reg_or_0_operand (operands[1], QImode))"
4511 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4512 (set_attr "mode" "QI")
4513 (set_attr "length" "4,4,*,*,4,4,4,4")])
4515 (define_insn "*movqi_mips16"
4516 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4517 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))]
4519 && (register_operand (operands[0], QImode)
4520 || register_operand (operands[1], QImode))"
4529 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4530 (set_attr "mode" "QI")
4531 (set_attr "length" "4,4,4,4,8,*,*")])
4533 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
4534 ;; when the original load is a 4 byte instruction but the add and the
4535 ;; load are 2 2 byte instructions.
4538 [(set (match_operand:QI 0 "register_operand")
4539 (mem:QI (plus:SI (match_dup 0)
4540 (match_operand:SI 1 "const_int_operand"))))]
4541 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4542 && GET_CODE (operands[0]) == REG
4543 && M16_REG_P (REGNO (operands[0]))
4544 && GET_CODE (operands[1]) == CONST_INT
4545 && ((INTVAL (operands[1]) < 0
4546 && INTVAL (operands[1]) >= -0x80)
4547 || (INTVAL (operands[1]) >= 32
4548 && INTVAL (operands[1]) <= 31 + 0x7f))"
4549 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4550 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4552 HOST_WIDE_INT val = INTVAL (operands[1]);
4555 operands[2] = const0_rtx;
4558 operands[1] = GEN_INT (0x7f);
4559 operands[2] = GEN_INT (val - 0x7f);
4563 ;; 32-bit floating point moves
4565 (define_expand "movsf"
4566 [(set (match_operand:SF 0 "")
4567 (match_operand:SF 1 ""))]
4570 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4574 (define_insn "*movsf_hardfloat"
4575 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4576 (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
4578 && (register_operand (operands[0], SFmode)
4579 || reg_or_0_operand (operands[1], SFmode))"
4580 { return mips_output_move (operands[0], operands[1]); }
4581 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4582 (set_attr "mode" "SF")
4583 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4585 (define_insn "*movsf_softfloat"
4586 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4587 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
4588 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4589 && (register_operand (operands[0], SFmode)
4590 || reg_or_0_operand (operands[1], SFmode))"
4591 { return mips_output_move (operands[0], operands[1]); }
4592 [(set_attr "type" "arith,load,store")
4593 (set_attr "mode" "SF")
4594 (set_attr "length" "4,*,*")])
4596 (define_insn "*movsf_mips16"
4597 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4598 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
4600 && (register_operand (operands[0], SFmode)
4601 || register_operand (operands[1], SFmode))"
4602 { return mips_output_move (operands[0], operands[1]); }
4603 [(set_attr "type" "arith,arith,arith,load,store")
4604 (set_attr "mode" "SF")
4605 (set_attr "length" "4,4,4,*,*")])
4608 ;; 64-bit floating point moves
4610 (define_expand "movdf"
4611 [(set (match_operand:DF 0 "")
4612 (match_operand:DF 1 ""))]
4615 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4619 (define_insn "*movdf_hardfloat_64bit"
4620 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4621 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4622 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
4623 && (register_operand (operands[0], DFmode)
4624 || reg_or_0_operand (operands[1], DFmode))"
4625 { return mips_output_move (operands[0], operands[1]); }
4626 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4627 (set_attr "mode" "DF")
4628 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4630 (define_insn "*movdf_hardfloat_32bit"
4631 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4632 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4633 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
4634 && (register_operand (operands[0], DFmode)
4635 || reg_or_0_operand (operands[1], DFmode))"
4636 { return mips_output_move (operands[0], operands[1]); }
4637 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4638 (set_attr "mode" "DF")
4639 (set_attr "length" "4,8,*,*,8,8,8,*,*")])
4641 (define_insn "*movdf_softfloat"
4642 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
4643 (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
4644 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4645 && (register_operand (operands[0], DFmode)
4646 || reg_or_0_operand (operands[1], DFmode))"
4647 { return mips_output_move (operands[0], operands[1]); }
4648 [(set_attr "type" "arith,load,store,xfer,xfer,fmove")
4649 (set_attr "mode" "DF")
4650 (set_attr "length" "8,*,*,4,4,4")])
4652 (define_insn "*movdf_mips16"
4653 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4654 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4656 && (register_operand (operands[0], DFmode)
4657 || register_operand (operands[1], DFmode))"
4658 { return mips_output_move (operands[0], operands[1]); }
4659 [(set_attr "type" "arith,arith,arith,load,store")
4660 (set_attr "mode" "DF")
4661 (set_attr "length" "8,8,8,*,*")])
4664 [(set (match_operand:DI 0 "nonimmediate_operand")
4665 (match_operand:DI 1 "move_operand"))]
4666 "reload_completed && !TARGET_64BIT
4667 && mips_split_64bit_move_p (operands[0], operands[1])"
4670 mips_split_64bit_move (operands[0], operands[1]);
4675 [(set (match_operand:DF 0 "nonimmediate_operand")
4676 (match_operand:DF 1 "move_operand"))]
4677 "reload_completed && !TARGET_64BIT
4678 && mips_split_64bit_move_p (operands[0], operands[1])"
4681 mips_split_64bit_move (operands[0], operands[1]);
4685 ;; When generating mips16 code, split moves of negative constants into
4686 ;; a positive "li" followed by a negation.
4688 [(set (match_operand 0 "register_operand")
4689 (match_operand 1 "const_int_operand"))]
4690 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4694 (neg:SI (match_dup 2)))]
4696 operands[2] = gen_lowpart (SImode, operands[0]);
4697 operands[3] = GEN_INT (-INTVAL (operands[1]));
4700 ;; The HI and LO registers are not truly independent. If we move an mthi
4701 ;; instruction before an mflo instruction, it will make the result of the
4702 ;; mflo unpredictable. The same goes for mtlo and mfhi.
4704 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4705 ;; Operand 1 is the register we want, operand 2 is the other one.
4707 (define_insn "mfhilo_di"
4708 [(set (match_operand:DI 0 "register_operand" "=d,d")
4709 (unspec:DI [(match_operand:DI 1 "register_operand" "h,l")
4710 (match_operand:DI 2 "register_operand" "l,h")]
4714 [(set_attr "type" "mfhilo")])
4716 (define_insn "mfhilo_si"
4717 [(set (match_operand:SI 0 "register_operand" "=d,d")
4718 (unspec:SI [(match_operand:SI 1 "register_operand" "h,l")
4719 (match_operand:SI 2 "register_operand" "l,h")]
4723 [(set_attr "type" "mfhilo")])
4725 ;; Patterns for loading or storing part of a paired floating point
4726 ;; register. We need them because odd-numbered floating-point registers
4727 ;; are not fully independent: see mips_split_64bit_move.
4729 ;; Load the low word of operand 0 with operand 1.
4730 (define_insn "load_df_low"
4731 [(set (match_operand:DF 0 "register_operand" "=f,f")
4732 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
4733 UNSPEC_LOAD_DF_LOW))]
4734 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4736 operands[0] = mips_subword (operands[0], 0);
4737 return mips_output_move (operands[0], operands[1]);
4739 [(set_attr "type" "xfer,fpload")
4740 (set_attr "mode" "SF")])
4742 ;; Load the high word of operand 0 from operand 1, preserving the value
4744 (define_insn "load_df_high"
4745 [(set (match_operand:DF 0 "register_operand" "=f,f")
4746 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
4747 (match_operand:DF 2 "register_operand" "0,0")]
4748 UNSPEC_LOAD_DF_HIGH))]
4749 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4751 operands[0] = mips_subword (operands[0], 1);
4752 return mips_output_move (operands[0], operands[1]);
4754 [(set_attr "type" "xfer,fpload")
4755 (set_attr "mode" "SF")])
4757 ;; Store the high word of operand 1 in operand 0. The corresponding
4758 ;; low-word move is done in the normal way.
4759 (define_insn "store_df_high"
4760 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4761 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4762 UNSPEC_STORE_DF_HIGH))]
4763 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4765 operands[1] = mips_subword (operands[1], 1);
4766 return mips_output_move (operands[0], operands[1]);
4768 [(set_attr "type" "xfer,fpstore")
4769 (set_attr "mode" "SF")])
4771 ;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
4772 ;; of _gp from the start of this function. Operand 1 is the incoming
4773 ;; function address.
4774 (define_insn_and_split "loadgp"
4775 [(unspec_volatile [(match_operand 0 "" "")
4776 (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4777 "TARGET_ABICALLS && TARGET_NEWABI"
4780 [(set (match_dup 2) (match_dup 3))
4781 (set (match_dup 2) (match_dup 4))
4782 (set (match_dup 2) (match_dup 5))]
4784 operands[2] = pic_offset_table_rtx;
4785 operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4786 operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4787 operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4789 [(set_attr "length" "12")])
4791 ;; The use of gp is hidden when not using explicit relocations.
4792 ;; This blockage instruction prevents the gp load from being
4793 ;; scheduled after an implicit use of gp. It also prevents
4794 ;; the load from being deleted as dead.
4795 (define_insn "loadgp_blockage"
4796 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4799 [(set_attr "type" "unknown")
4800 (set_attr "mode" "none")
4801 (set_attr "length" "0")])
4803 ;; Emit a .cprestore directive, which normally expands to a single store
4804 ;; instruction. Note that we continue to use .cprestore for explicit reloc
4805 ;; code so that jals inside inline asms will work correctly.
4806 (define_insn "cprestore"
4807 [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
4811 if (set_nomacro && which_alternative == 1)
4812 return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4814 return ".cprestore\t%0";
4816 [(set_attr "type" "store")
4817 (set_attr "length" "4,12")])
4819 ;; Block moves, see mips.c for more details.
4820 ;; Argument 0 is the destination
4821 ;; Argument 1 is the source
4822 ;; Argument 2 is the length
4823 ;; Argument 3 is the alignment
4825 (define_expand "movmemsi"
4826 [(parallel [(set (match_operand:BLK 0 "general_operand")
4827 (match_operand:BLK 1 "general_operand"))
4828 (use (match_operand:SI 2 ""))
4829 (use (match_operand:SI 3 "const_int_operand"))])]
4830 "!TARGET_MIPS16 && !TARGET_MEMCPY"
4832 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4839 ;; ....................
4843 ;; ....................
4845 ;; Many of these instructions use trivial define_expands, because we
4846 ;; want to use a different set of constraints when TARGET_MIPS16.
4848 (define_expand "ashlsi3"
4849 [(set (match_operand:SI 0 "register_operand")
4850 (ashift:SI (match_operand:SI 1 "register_operand")
4851 (match_operand:SI 2 "arith_operand")))]
4854 /* On the mips16, a shift of more than 8 is a four byte instruction,
4855 so, for a shift between 8 and 16, it is just as fast to do two
4856 shifts of 8 or less. If there is a lot of shifting going on, we
4857 may win in CSE. Otherwise combine will put the shifts back
4858 together again. This can be called by function_arg, so we must
4859 be careful not to allocate a new register if we've reached the
4863 && GET_CODE (operands[2]) == CONST_INT
4864 && INTVAL (operands[2]) > 8
4865 && INTVAL (operands[2]) <= 16
4866 && ! reload_in_progress
4867 && ! reload_completed)
4869 rtx temp = gen_reg_rtx (SImode);
4871 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
4872 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
4873 GEN_INT (INTVAL (operands[2]) - 8)));
4878 (define_insn "ashlsi3_internal1"
4879 [(set (match_operand:SI 0 "register_operand" "=d")
4880 (ashift:SI (match_operand:SI 1 "register_operand" "d")
4881 (match_operand:SI 2 "arith_operand" "dI")))]
4884 if (GET_CODE (operands[2]) == CONST_INT)
4885 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4887 return "sll\t%0,%1,%2";
4889 [(set_attr "type" "shift")
4890 (set_attr "mode" "SI")])
4892 (define_insn "ashlsi3_internal1_extend"
4893 [(set (match_operand:DI 0 "register_operand" "=d")
4894 (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
4895 (match_operand:SI 2 "arith_operand" "dI"))))]
4896 "TARGET_64BIT && !TARGET_MIPS16"
4898 if (GET_CODE (operands[2]) == CONST_INT)
4899 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4901 return "sll\t%0,%1,%2";
4903 [(set_attr "type" "shift")
4904 (set_attr "mode" "DI")])
4907 (define_insn "ashlsi3_internal2"
4908 [(set (match_operand:SI 0 "register_operand" "=d,d")
4909 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
4910 (match_operand:SI 2 "arith_operand" "d,I")))]
4913 if (which_alternative == 0)
4914 return "sll\t%0,%2";
4916 if (GET_CODE (operands[2]) == CONST_INT)
4917 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4919 return "sll\t%0,%1,%2";
4921 [(set_attr "type" "shift")
4922 (set_attr "mode" "SI")
4923 (set_attr_alternative "length"
4925 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4929 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4932 [(set (match_operand:SI 0 "register_operand")
4933 (ashift:SI (match_operand:SI 1 "register_operand")
4934 (match_operand:SI 2 "const_int_operand")))]
4935 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4936 && GET_CODE (operands[2]) == CONST_INT
4937 && INTVAL (operands[2]) > 8
4938 && INTVAL (operands[2]) <= 16"
4939 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
4940 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4941 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4943 (define_expand "ashldi3"
4944 [(set (match_operand:DI 0 "register_operand")
4945 (ashift:DI (match_operand:DI 1 "register_operand")
4946 (match_operand:SI 2 "arith_operand")))]
4949 /* On the mips16, a shift of more than 8 is a four byte
4950 instruction, so, for a shift between 8 and 16, it is just as
4951 fast to do two shifts of 8 or less. If there is a lot of
4952 shifting going on, we may win in CSE. Otherwise combine will
4953 put the shifts back together again. This can be called by
4954 function_arg, so we must be careful not to allocate a new
4955 register if we've reached the reload pass. */
4958 && GET_CODE (operands[2]) == CONST_INT
4959 && INTVAL (operands[2]) > 8
4960 && INTVAL (operands[2]) <= 16
4961 && ! reload_in_progress
4962 && ! reload_completed)
4964 rtx temp = gen_reg_rtx (DImode);
4966 emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
4967 emit_insn (gen_ashldi3_internal (operands[0], temp,
4968 GEN_INT (INTVAL (operands[2]) - 8)));
4974 (define_insn "ashldi3_internal"
4975 [(set (match_operand:DI 0 "register_operand" "=d")
4976 (ashift:DI (match_operand:DI 1 "register_operand" "d")
4977 (match_operand:SI 2 "arith_operand" "dI")))]
4978 "TARGET_64BIT && !TARGET_MIPS16"
4980 if (GET_CODE (operands[2]) == CONST_INT)
4981 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4983 return "dsll\t%0,%1,%2";
4985 [(set_attr "type" "shift")
4986 (set_attr "mode" "DI")])
4989 [(set (match_operand:DI 0 "register_operand" "=d,d")
4990 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4991 (match_operand:SI 2 "arith_operand" "d,I")))]
4992 "TARGET_64BIT && TARGET_MIPS16"
4994 if (which_alternative == 0)
4995 return "dsll\t%0,%2";
4997 if (GET_CODE (operands[2]) == CONST_INT)
4998 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5000 return "dsll\t%0,%1,%2";
5002 [(set_attr "type" "shift")
5003 (set_attr "mode" "DI")
5004 (set_attr_alternative "length"
5006 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5011 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5014 [(set (match_operand:DI 0 "register_operand")
5015 (ashift:DI (match_operand:DI 1 "register_operand")
5016 (match_operand:SI 2 "const_int_operand")))]
5017 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5019 && GET_CODE (operands[2]) == CONST_INT
5020 && INTVAL (operands[2]) > 8
5021 && INTVAL (operands[2]) <= 16"
5022 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
5023 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
5024 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5026 (define_expand "ashrsi3"
5027 [(set (match_operand:SI 0 "register_operand")
5028 (ashiftrt:SI (match_operand:SI 1 "register_operand")
5029 (match_operand:SI 2 "arith_operand")))]
5032 /* On the mips16, a shift of more than 8 is a four byte instruction,
5033 so, for a shift between 8 and 16, it is just as fast to do two
5034 shifts of 8 or less. If there is a lot of shifting going on, we
5035 may win in CSE. Otherwise combine will put the shifts back
5039 && GET_CODE (operands[2]) == CONST_INT
5040 && INTVAL (operands[2]) > 8
5041 && INTVAL (operands[2]) <= 16)
5043 rtx temp = gen_reg_rtx (SImode);
5045 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5046 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
5047 GEN_INT (INTVAL (operands[2]) - 8)));
5052 (define_insn "ashrsi3_internal1"
5053 [(set (match_operand:SI 0 "register_operand" "=d")
5054 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
5055 (match_operand:SI 2 "arith_operand" "dI")))]
5058 if (GET_CODE (operands[2]) == CONST_INT)
5059 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5061 return "sra\t%0,%1,%2";
5063 [(set_attr "type" "shift")
5064 (set_attr "mode" "SI")])
5066 (define_insn "ashrsi3_internal2"
5067 [(set (match_operand:SI 0 "register_operand" "=d,d")
5068 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5069 (match_operand:SI 2 "arith_operand" "d,I")))]
5072 if (which_alternative == 0)
5073 return "sra\t%0,%2";
5075 if (GET_CODE (operands[2]) == CONST_INT)
5076 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5078 return "sra\t%0,%1,%2";
5080 [(set_attr "type" "shift")
5081 (set_attr "mode" "SI")
5082 (set_attr_alternative "length"
5084 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5089 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5092 [(set (match_operand:SI 0 "register_operand")
5093 (ashiftrt:SI (match_operand:SI 1 "register_operand")
5094 (match_operand:SI 2 "const_int_operand")))]
5095 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5096 && GET_CODE (operands[2]) == CONST_INT
5097 && INTVAL (operands[2]) > 8
5098 && INTVAL (operands[2]) <= 16"
5099 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
5100 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
5101 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5103 (define_expand "ashrdi3"
5104 [(set (match_operand:DI 0 "register_operand")
5105 (ashiftrt:DI (match_operand:DI 1 "register_operand")
5106 (match_operand:SI 2 "arith_operand")))]
5109 /* On the mips16, a shift of more than 8 is a four byte
5110 instruction, so, for a shift between 8 and 16, it is just as
5111 fast to do two shifts of 8 or less. If there is a lot of
5112 shifting going on, we may win in CSE. Otherwise combine will
5113 put the shifts back together again. */
5116 && GET_CODE (operands[2]) == CONST_INT
5117 && INTVAL (operands[2]) > 8
5118 && INTVAL (operands[2]) <= 16)
5120 rtx temp = gen_reg_rtx (DImode);
5122 emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
5123 emit_insn (gen_ashrdi3_internal (operands[0], temp,
5124 GEN_INT (INTVAL (operands[2]) - 8)));
5130 (define_insn "ashrdi3_internal"
5131 [(set (match_operand:DI 0 "register_operand" "=d")
5132 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5133 (match_operand:SI 2 "arith_operand" "dI")))]
5134 "TARGET_64BIT && !TARGET_MIPS16"
5136 if (GET_CODE (operands[2]) == CONST_INT)
5137 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5139 return "dsra\t%0,%1,%2";
5141 [(set_attr "type" "shift")
5142 (set_attr "mode" "DI")])
5145 [(set (match_operand:DI 0 "register_operand" "=d,d")
5146 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5147 (match_operand:SI 2 "arith_operand" "d,I")))]
5148 "TARGET_64BIT && TARGET_MIPS16"
5150 if (GET_CODE (operands[2]) == CONST_INT)
5151 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5153 return "dsra\t%0,%2";
5155 [(set_attr "type" "shift")
5156 (set_attr "mode" "DI")
5157 (set_attr_alternative "length"
5159 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5163 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5166 [(set (match_operand:DI 0 "register_operand")
5167 (ashiftrt:DI (match_operand:DI 1 "register_operand")
5168 (match_operand:SI 2 "const_int_operand")))]
5169 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5171 && GET_CODE (operands[2]) == CONST_INT
5172 && INTVAL (operands[2]) > 8
5173 && INTVAL (operands[2]) <= 16"
5174 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
5175 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
5176 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5178 (define_expand "lshrsi3"
5179 [(set (match_operand:SI 0 "register_operand")
5180 (lshiftrt:SI (match_operand:SI 1 "register_operand")
5181 (match_operand:SI 2 "arith_operand")))]
5184 /* On the mips16, a shift of more than 8 is a four byte instruction,
5185 so, for a shift between 8 and 16, it is just as fast to do two
5186 shifts of 8 or less. If there is a lot of shifting going on, we
5187 may win in CSE. Otherwise combine will put the shifts back
5191 && GET_CODE (operands[2]) == CONST_INT
5192 && INTVAL (operands[2]) > 8
5193 && INTVAL (operands[2]) <= 16)
5195 rtx temp = gen_reg_rtx (SImode);
5197 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5198 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
5199 GEN_INT (INTVAL (operands[2]) - 8)));
5204 (define_insn "lshrsi3_internal1"
5205 [(set (match_operand:SI 0 "register_operand" "=d")
5206 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
5207 (match_operand:SI 2 "arith_operand" "dI")))]
5210 if (GET_CODE (operands[2]) == CONST_INT)
5211 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5213 return "srl\t%0,%1,%2";
5215 [(set_attr "type" "shift")
5216 (set_attr "mode" "SI")])
5218 (define_insn "lshrsi3_internal2"
5219 [(set (match_operand:SI 0 "register_operand" "=d,d")
5220 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5221 (match_operand:SI 2 "arith_operand" "d,I")))]
5224 if (which_alternative == 0)
5225 return "srl\t%0,%2";
5227 if (GET_CODE (operands[2]) == CONST_INT)
5228 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5230 return "srl\t%0,%1,%2";
5232 [(set_attr "type" "shift")
5233 (set_attr "mode" "SI")
5234 (set_attr_alternative "length"
5236 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5241 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5244 [(set (match_operand:SI 0 "register_operand")
5245 (lshiftrt:SI (match_operand:SI 1 "register_operand")
5246 (match_operand:SI 2 "const_int_operand")))]
5247 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5248 && GET_CODE (operands[2]) == CONST_INT
5249 && INTVAL (operands[2]) > 8
5250 && INTVAL (operands[2]) <= 16"
5251 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
5252 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5253 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5255 ;; If we load a byte on the mips16 as a bitfield, the resulting
5256 ;; sequence of instructions is too complicated for combine, because it
5257 ;; involves four instructions: a load, a shift, a constant load into a
5258 ;; register, and an and (the key problem here is that the mips16 does
5259 ;; not have and immediate). We recognize a shift of a load in order
5260 ;; to make it simple enough for combine to understand.
5262 ;; The length here is the worst case: the length of the split version
5263 ;; will be more accurate.
5264 (define_insn_and_split ""
5265 [(set (match_operand:SI 0 "register_operand" "=d")
5266 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5267 (match_operand:SI 2 "immediate_operand" "I")))]
5271 [(set (match_dup 0) (match_dup 1))
5272 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5274 [(set_attr "type" "load")
5275 (set_attr "mode" "SI")
5276 (set_attr "length" "16")])
5278 (define_expand "lshrdi3"
5279 [(set (match_operand:DI 0 "register_operand")
5280 (lshiftrt:DI (match_operand:DI 1 "register_operand")
5281 (match_operand:SI 2 "arith_operand")))]
5284 /* On the mips16, a shift of more than 8 is a four byte
5285 instruction, so, for a shift between 8 and 16, it is just as
5286 fast to do two shifts of 8 or less. If there is a lot of
5287 shifting going on, we may win in CSE. Otherwise combine will
5288 put the shifts back together again. */
5291 && GET_CODE (operands[2]) == CONST_INT
5292 && INTVAL (operands[2]) > 8
5293 && INTVAL (operands[2]) <= 16)
5295 rtx temp = gen_reg_rtx (DImode);
5297 emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
5298 emit_insn (gen_lshrdi3_internal (operands[0], temp,
5299 GEN_INT (INTVAL (operands[2]) - 8)));
5305 (define_insn "lshrdi3_internal"
5306 [(set (match_operand:DI 0 "register_operand" "=d")
5307 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
5308 (match_operand:SI 2 "arith_operand" "dI")))]
5309 "TARGET_64BIT && !TARGET_MIPS16"
5311 if (GET_CODE (operands[2]) == CONST_INT)
5312 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5314 return "dsrl\t%0,%1,%2";
5316 [(set_attr "type" "shift")
5317 (set_attr "mode" "DI")])
5320 [(set (match_operand:DI 0 "register_operand" "=d,d")
5321 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5322 (match_operand:SI 2 "arith_operand" "d,I")))]
5323 "TARGET_64BIT && TARGET_MIPS16"
5325 if (GET_CODE (operands[2]) == CONST_INT)
5326 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5328 return "dsrl\t%0,%2";
5330 [(set_attr "type" "shift")
5331 (set_attr "mode" "DI")
5332 (set_attr_alternative "length"
5334 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5338 (define_insn "rotrsi3"
5339 [(set (match_operand:SI 0 "register_operand" "=d")
5340 (rotatert:SI (match_operand:SI 1 "register_operand" "d")
5341 (match_operand:SI 2 "arith_operand" "dn")))]
5344 if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
5345 return "rorv\t%0,%1,%2";
5347 if ((GET_CODE (operands[2]) == CONST_INT)
5348 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
5351 return "ror\t%0,%1,%2";
5353 [(set_attr "type" "shift")
5354 (set_attr "mode" "SI")])
5356 (define_insn "rotrdi3"
5357 [(set (match_operand:DI 0 "register_operand" "=d")
5358 (rotatert:DI (match_operand:DI 1 "register_operand" "d")
5359 (match_operand:DI 2 "arith_operand" "dn")))]
5364 if (GET_CODE (operands[2]) != CONST_INT)
5365 return "drorv\t%0,%1,%2";
5367 if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
5368 return "dror32\t%0,%1,%2";
5371 if ((GET_CODE (operands[2]) == CONST_INT)
5372 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
5375 return "dror\t%0,%1,%2";
5377 [(set_attr "type" "shift")
5378 (set_attr "mode" "DI")])
5381 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5384 [(set (match_operand:DI 0 "register_operand")
5385 (lshiftrt:DI (match_operand:DI 1 "register_operand")
5386 (match_operand:SI 2 "const_int_operand")))]
5387 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5388 && GET_CODE (operands[2]) == CONST_INT
5389 && INTVAL (operands[2]) > 8
5390 && INTVAL (operands[2]) <= 16"
5391 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
5392 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
5393 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5396 ;; ....................
5400 ;; ....................
5402 ;; Flow here is rather complex:
5404 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the arguments
5405 ;; into cmp_operands[] but generates no RTL.
5407 ;; 2) The appropriate branch define_expand is called, which then
5408 ;; creates the appropriate RTL for the comparison and branch.
5409 ;; Different CC modes are used, based on what type of branch is
5410 ;; done, so that we can constrain things appropriately. There
5411 ;; are assumptions in the rest of GCC that break if we fold the
5412 ;; operands into the branches for integer operations, and use cc0
5413 ;; for floating point, so we use the fp status register instead.
5414 ;; If needed, an appropriate temporary is created to hold the
5415 ;; of the integer compare.
5417 (define_expand "cmpsi"
5419 (compare:CC (match_operand:SI 0 "register_operand")
5420 (match_operand:SI 1 "nonmemory_operand")))]
5423 cmp_operands[0] = operands[0];
5424 cmp_operands[1] = operands[1];
5428 (define_expand "cmpdi"
5430 (compare:CC (match_operand:DI 0 "register_operand")
5431 (match_operand:DI 1 "nonmemory_operand")))]
5434 cmp_operands[0] = operands[0];
5435 cmp_operands[1] = operands[1];
5439 (define_expand "cmpdf"
5441 (compare:CC (match_operand:DF 0 "register_operand")
5442 (match_operand:DF 1 "register_operand")))]
5443 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5445 cmp_operands[0] = operands[0];
5446 cmp_operands[1] = operands[1];
5450 (define_expand "cmpsf"
5452 (compare:CC (match_operand:SF 0 "register_operand")
5453 (match_operand:SF 1 "register_operand")))]
5456 cmp_operands[0] = operands[0];
5457 cmp_operands[1] = operands[1];
5462 ;; ....................
5464 ;; CONDITIONAL BRANCHES
5466 ;; ....................
5468 ;; Conditional branches on floating-point equality tests.
5470 (define_insn "branch_fp"
5473 (match_operator:CC 0 "comparison_operator"
5474 [(match_operand:CC 2 "register_operand" "z")
5476 (label_ref (match_operand 1 "" ""))
5480 return mips_output_conditional_branch (insn,
5482 /*two_operands_p=*/0,
5485 get_attr_length (insn));
5487 [(set_attr "type" "branch")
5488 (set_attr "mode" "none")])
5490 (define_insn "branch_fp_inverted"
5493 (match_operator:CC 0 "comparison_operator"
5494 [(match_operand:CC 2 "register_operand" "z")
5497 (label_ref (match_operand 1 "" ""))))]
5500 return mips_output_conditional_branch (insn,
5502 /*two_operands_p=*/0,
5505 get_attr_length (insn));
5507 [(set_attr "type" "branch")
5508 (set_attr "mode" "none")])
5510 ;; Conditional branches on comparisons with zero.
5512 (define_insn "branch_zero"
5515 (match_operator:SI 0 "comparison_operator"
5516 [(match_operand:SI 2 "register_operand" "d")
5518 (label_ref (match_operand 1 "" ""))
5522 return mips_output_conditional_branch (insn,
5524 /*two_operands_p=*/0,
5527 get_attr_length (insn));
5529 [(set_attr "type" "branch")
5530 (set_attr "mode" "none")])
5532 (define_insn "branch_zero_inverted"
5535 (match_operator:SI 0 "comparison_operator"
5536 [(match_operand:SI 2 "register_operand" "d")
5539 (label_ref (match_operand 1 "" ""))))]
5542 return mips_output_conditional_branch (insn,
5544 /*two_operands_p=*/0,
5547 get_attr_length (insn));
5549 [(set_attr "type" "branch")
5550 (set_attr "mode" "none")])
5552 (define_insn "branch_zero_di"
5555 (match_operator:DI 0 "comparison_operator"
5556 [(match_operand:DI 2 "register_operand" "d")
5558 (label_ref (match_operand 1 "" ""))
5562 return mips_output_conditional_branch (insn,
5564 /*two_operands_p=*/0,
5567 get_attr_length (insn));
5569 [(set_attr "type" "branch")
5570 (set_attr "mode" "none")])
5572 (define_insn "branch_zero_di_inverted"
5575 (match_operator:DI 0 "comparison_operator"
5576 [(match_operand:DI 2 "register_operand" "d")
5579 (label_ref (match_operand 1 "" ""))))]
5582 return mips_output_conditional_branch (insn,
5584 /*two_operands_p=*/0,
5587 get_attr_length (insn));
5589 [(set_attr "type" "branch")
5590 (set_attr "mode" "none")])
5592 ;; Conditional branch on equality comparison.
5594 (define_insn "branch_equality"
5597 (match_operator:SI 0 "equality_operator"
5598 [(match_operand:SI 2 "register_operand" "d")
5599 (match_operand:SI 3 "register_operand" "d")])
5600 (label_ref (match_operand 1 "" ""))
5604 return mips_output_conditional_branch (insn,
5606 /*two_operands_p=*/1,
5609 get_attr_length (insn));
5611 [(set_attr "type" "branch")
5612 (set_attr "mode" "none")])
5614 (define_insn "branch_equality_di"
5617 (match_operator:DI 0 "equality_operator"
5618 [(match_operand:DI 2 "register_operand" "d")
5619 (match_operand:DI 3 "register_operand" "d")])
5620 (label_ref (match_operand 1 "" ""))
5624 return mips_output_conditional_branch (insn,
5626 /*two_operands_p=*/1,
5629 get_attr_length (insn));
5631 [(set_attr "type" "branch")
5632 (set_attr "mode" "none")])
5634 (define_insn "branch_equality_inverted"
5637 (match_operator:SI 0 "equality_operator"
5638 [(match_operand:SI 2 "register_operand" "d")
5639 (match_operand:SI 3 "register_operand" "d")])
5641 (label_ref (match_operand 1 "" ""))))]
5644 return mips_output_conditional_branch (insn,
5646 /*two_operands_p=*/1,
5649 get_attr_length (insn));
5651 [(set_attr "type" "branch")
5652 (set_attr "mode" "none")])
5654 (define_insn "branch_equality_di_inverted"
5657 (match_operator:DI 0 "equality_operator"
5658 [(match_operand:DI 2 "register_operand" "d")
5659 (match_operand:DI 3 "register_operand" "d")])
5661 (label_ref (match_operand 1 "" ""))))]
5664 return mips_output_conditional_branch (insn,
5666 /*two_operands_p=*/1,
5669 get_attr_length (insn));
5671 [(set_attr "type" "branch")
5672 (set_attr "mode" "none")])
5679 (match_operator:SI 0 "equality_operator"
5680 [(match_operand:SI 1 "register_operand" "d,t")
5682 (match_operand 2 "pc_or_label_operand" "")
5683 (match_operand 3 "pc_or_label_operand" "")))]
5686 if (operands[2] != pc_rtx)
5688 if (which_alternative == 0)
5689 return "b%C0z\t%1,%2";
5691 return "bt%C0z\t%2";
5695 if (which_alternative == 0)
5696 return "b%N0z\t%1,%3";
5698 return "bt%N0z\t%3";
5701 [(set_attr "type" "branch")
5702 (set_attr "mode" "none")
5703 (set_attr "length" "8")])
5708 (match_operator:DI 0 "equality_operator"
5709 [(match_operand:DI 1 "register_operand" "d,t")
5711 (match_operand 2 "pc_or_label_operand" "")
5712 (match_operand 3 "pc_or_label_operand" "")))]
5715 if (operands[2] != pc_rtx)
5717 if (which_alternative == 0)
5718 return "b%C0z\t%1,%2";
5720 return "bt%C0z\t%2";
5724 if (which_alternative == 0)
5725 return "b%N0z\t%1,%3";
5727 return "bt%N0z\t%3";
5730 [(set_attr "type" "branch")
5731 (set_attr "mode" "none")
5732 (set_attr "length" "8")])
5734 (define_expand "b<code>"
5736 (if_then_else (any_cond:CC (cc0)
5738 (label_ref (match_operand 0 ""))
5742 gen_conditional_branch (operands, <CODE>);
5747 ;; ....................
5749 ;; SETTING A REGISTER FROM A COMPARISON
5751 ;; ....................
5753 (define_expand "seq"
5754 [(set (match_operand:SI 0 "register_operand")
5755 (eq:SI (match_dup 1)
5758 { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
5760 (define_insn "*seq_si"
5761 [(set (match_operand:SI 0 "register_operand" "=d")
5762 (eq:SI (match_operand:SI 1 "register_operand" "d")
5766 [(set_attr "type" "slt")
5767 (set_attr "mode" "SI")])
5769 (define_insn "*seq_si_mips16"
5770 [(set (match_operand:SI 0 "register_operand" "=t")
5771 (eq:SI (match_operand:SI 1 "register_operand" "d")
5775 [(set_attr "type" "slt")
5776 (set_attr "mode" "SI")])
5778 (define_insn "*seq_di"
5779 [(set (match_operand:DI 0 "register_operand" "=d")
5780 (eq:DI (match_operand:DI 1 "register_operand" "d")
5782 "TARGET_64BIT && !TARGET_MIPS16"
5784 [(set_attr "type" "slt")
5785 (set_attr "mode" "DI")])
5787 (define_insn "*seq_di_mips16"
5788 [(set (match_operand:DI 0 "register_operand" "=t")
5789 (eq:DI (match_operand:DI 1 "register_operand" "d")
5791 "TARGET_64BIT && TARGET_MIPS16"
5793 [(set_attr "type" "slt")
5794 (set_attr "mode" "DI")])
5796 ;; "sne" uses sltu instructions in which the first operand is $0.
5797 ;; This isn't possible in mips16 code.
5799 (define_expand "sne"
5800 [(set (match_operand:SI 0 "register_operand")
5801 (ne:SI (match_dup 1)
5804 { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
5806 (define_insn "*sne_si"
5807 [(set (match_operand:SI 0 "register_operand" "=d")
5808 (ne:SI (match_operand:SI 1 "register_operand" "d")
5812 [(set_attr "type" "slt")
5813 (set_attr "mode" "SI")])
5815 (define_insn "*sne_di"
5816 [(set (match_operand:DI 0 "register_operand" "=d")
5817 (ne:DI (match_operand:DI 1 "register_operand" "d")
5819 "TARGET_64BIT && !TARGET_MIPS16"
5821 [(set_attr "type" "slt")
5822 (set_attr "mode" "DI")])
5824 (define_expand "sgt"
5825 [(set (match_operand:SI 0 "register_operand")
5826 (gt:SI (match_dup 1)
5829 { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
5831 (define_insn "*sgt_si"
5832 [(set (match_operand:SI 0 "register_operand" "=d")
5833 (gt:SI (match_operand:SI 1 "register_operand" "d")
5834 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
5837 [(set_attr "type" "slt")
5838 (set_attr "mode" "SI")])
5840 (define_insn "*sgt_si_mips16"
5841 [(set (match_operand:SI 0 "register_operand" "=t")
5842 (gt:SI (match_operand:SI 1 "register_operand" "d")
5843 (match_operand:SI 2 "register_operand" "d")))]
5846 [(set_attr "type" "slt")
5847 (set_attr "mode" "SI")])
5849 (define_insn "*sgt_di"
5850 [(set (match_operand:DI 0 "register_operand" "=d")
5851 (gt:DI (match_operand:DI 1 "register_operand" "d")
5852 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
5853 "TARGET_64BIT && !TARGET_MIPS16"
5855 [(set_attr "type" "slt")
5856 (set_attr "mode" "DI")])
5858 (define_insn "*sgt_di_mips16"
5859 [(set (match_operand:DI 0 "register_operand" "=t")
5860 (gt:DI (match_operand:DI 1 "register_operand" "d")
5861 (match_operand:DI 2 "register_operand" "d")))]
5862 "TARGET_64BIT && TARGET_MIPS16"
5864 [(set_attr "type" "slt")
5865 (set_attr "mode" "DI")])
5867 (define_expand "sge"
5868 [(set (match_operand:SI 0 "register_operand")
5869 (ge:SI (match_dup 1)
5872 { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
5874 (define_insn "*sge_si"
5875 [(set (match_operand:SI 0 "register_operand" "=d")
5876 (ge:SI (match_operand:SI 1 "register_operand" "d")
5880 [(set_attr "type" "slt")
5881 (set_attr "mode" "SI")])
5883 (define_insn "*sge_di"
5884 [(set (match_operand:DI 0 "register_operand" "=d")
5885 (ge:DI (match_operand:DI 1 "register_operand" "d")
5887 "TARGET_64BIT && !TARGET_MIPS16"
5889 [(set_attr "type" "slt")
5890 (set_attr "mode" "DI")])
5892 (define_expand "slt"
5893 [(set (match_operand:SI 0 "register_operand")
5894 (lt:SI (match_dup 1)
5897 { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
5899 (define_insn "*slt_si"
5900 [(set (match_operand:SI 0 "register_operand" "=d")
5901 (lt:SI (match_operand:SI 1 "register_operand" "d")
5902 (match_operand:SI 2 "arith_operand" "dI")))]
5905 [(set_attr "type" "slt")
5906 (set_attr "mode" "SI")])
5908 (define_insn "*slt_si_mips16"
5909 [(set (match_operand:SI 0 "register_operand" "=t,t")
5910 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
5911 (match_operand:SI 2 "arith_operand" "d,I")))]
5914 [(set_attr "type" "slt")
5915 (set_attr "mode" "SI")
5916 (set_attr_alternative "length"
5918 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
5922 (define_insn "*slt_di"
5923 [(set (match_operand:DI 0 "register_operand" "=d")
5924 (lt:DI (match_operand:DI 1 "register_operand" "d")
5925 (match_operand:DI 2 "arith_operand" "dI")))]
5926 "TARGET_64BIT && !TARGET_MIPS16"
5928 [(set_attr "type" "slt")
5929 (set_attr "mode" "DI")])
5931 (define_insn "*slt_di_mips16"
5932 [(set (match_operand:DI 0 "register_operand" "=t,t")
5933 (lt:DI (match_operand:DI 1 "register_operand" "d,d")
5934 (match_operand:DI 2 "arith_operand" "d,I")))]
5935 "TARGET_64BIT && TARGET_MIPS16"
5937 [(set_attr "type" "slt")
5938 (set_attr "mode" "DI")
5939 (set_attr_alternative "length"
5941 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
5945 (define_expand "sle"
5946 [(set (match_operand:SI 0 "register_operand")
5947 (le:SI (match_dup 1)
5950 { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
5952 (define_insn "*sle_si"
5953 [(set (match_operand:SI 0 "register_operand" "=d")
5954 (le:SI (match_operand:SI 1 "register_operand" "d")
5955 (match_operand:SI 2 "sle_operand" "")))]
5958 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5959 return "slt\t%0,%1,%2";
5961 [(set_attr "type" "slt")
5962 (set_attr "mode" "SI")])
5964 (define_insn "*sle_si_mips16"
5965 [(set (match_operand:SI 0 "register_operand" "=t")
5966 (le:SI (match_operand:SI 1 "register_operand" "d")
5967 (match_operand:SI 2 "sle_operand" "")))]
5970 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5971 return "slt\t%1,%2";
5973 [(set_attr "type" "slt")
5974 (set_attr "mode" "SI")
5975 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
5979 (define_insn "*sle_di"
5980 [(set (match_operand:DI 0 "register_operand" "=d")
5981 (le:DI (match_operand:DI 1 "register_operand" "d")
5982 (match_operand:DI 2 "sle_operand" "")))]
5983 "TARGET_64BIT && !TARGET_MIPS16"
5985 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5986 return "slt\t%0,%1,%2";
5988 [(set_attr "type" "slt")
5989 (set_attr "mode" "DI")])
5991 (define_insn "*sle_di_mips16"
5992 [(set (match_operand:DI 0 "register_operand" "=t")
5993 (le:DI (match_operand:DI 1 "register_operand" "d")
5994 (match_operand:DI 2 "sle_operand" "")))]
5995 "TARGET_64BIT && TARGET_MIPS16"
5997 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5998 return "slt\t%1,%2";
6000 [(set_attr "type" "slt")
6001 (set_attr "mode" "DI")
6002 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6006 (define_expand "sgtu"
6007 [(set (match_operand:SI 0 "register_operand")
6008 (gtu:SI (match_dup 1)
6011 { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
6013 (define_insn "*sgtu_si"
6014 [(set (match_operand:SI 0 "register_operand" "=d")
6015 (gtu:SI (match_operand:SI 1 "register_operand" "d")
6016 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6019 [(set_attr "type" "slt")
6020 (set_attr "mode" "SI")])
6022 (define_insn "*sgtu_si_mips16"
6023 [(set (match_operand:SI 0 "register_operand" "=t")
6024 (gtu:SI (match_operand:SI 1 "register_operand" "d")
6025 (match_operand:SI 2 "register_operand" "d")))]
6028 [(set_attr "type" "slt")
6029 (set_attr "mode" "SI")])
6031 (define_insn "*sgtu_di"
6032 [(set (match_operand:DI 0 "register_operand" "=d")
6033 (gtu:DI (match_operand:DI 1 "register_operand" "d")
6034 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6035 "TARGET_64BIT && !TARGET_MIPS16"
6037 [(set_attr "type" "slt")
6038 (set_attr "mode" "DI")])
6040 (define_insn "*sgtu_di_mips16"
6041 [(set (match_operand:DI 0 "register_operand" "=t")
6042 (gtu:DI (match_operand:DI 1 "register_operand" "d")
6043 (match_operand:DI 2 "register_operand" "d")))]
6044 "TARGET_64BIT && TARGET_MIPS16"
6046 [(set_attr "type" "slt")
6047 (set_attr "mode" "DI")])
6049 (define_expand "sgeu"
6050 [(set (match_operand:SI 0 "register_operand")
6051 (geu:SI (match_dup 1)
6054 { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
6056 (define_insn "*sge_si"
6057 [(set (match_operand:SI 0 "register_operand" "=d")
6058 (geu:SI (match_operand:SI 1 "register_operand" "d")
6062 [(set_attr "type" "slt")
6063 (set_attr "mode" "SI")])
6065 (define_insn "*sge_di"
6066 [(set (match_operand:DI 0 "register_operand" "=d")
6067 (geu:DI (match_operand:DI 1 "register_operand" "d")
6069 "TARGET_64BIT && !TARGET_MIPS16"
6071 [(set_attr "type" "slt")
6072 (set_attr "mode" "DI")])
6074 (define_expand "sltu"
6075 [(set (match_operand:SI 0 "register_operand")
6076 (ltu:SI (match_dup 1)
6079 { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
6081 (define_insn "*sltu_si"
6082 [(set (match_operand:SI 0 "register_operand" "=d")
6083 (ltu:SI (match_operand:SI 1 "register_operand" "d")
6084 (match_operand:SI 2 "arith_operand" "dI")))]
6087 [(set_attr "type" "slt")
6088 (set_attr "mode" "SI")])
6090 (define_insn "*sltu_si_mips16"
6091 [(set (match_operand:SI 0 "register_operand" "=t,t")
6092 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
6093 (match_operand:SI 2 "arith_operand" "d,I")))]
6096 [(set_attr "type" "slt")
6097 (set_attr "mode" "SI")
6098 (set_attr_alternative "length"
6100 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6104 (define_insn "*sltu_di"
6105 [(set (match_operand:DI 0 "register_operand" "=d")
6106 (ltu:DI (match_operand:DI 1 "register_operand" "d")
6107 (match_operand:DI 2 "arith_operand" "dI")))]
6108 "TARGET_64BIT && !TARGET_MIPS16"
6110 [(set_attr "type" "slt")
6111 (set_attr "mode" "DI")])
6113 (define_insn "*sltu_di_mips16"
6114 [(set (match_operand:DI 0 "register_operand" "=t,t")
6115 (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
6116 (match_operand:DI 2 "arith_operand" "d,I")))]
6117 "TARGET_64BIT && TARGET_MIPS16"
6119 [(set_attr "type" "slt")
6120 (set_attr "mode" "DI")
6121 (set_attr_alternative "length"
6123 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6127 (define_expand "sleu"
6128 [(set (match_operand:SI 0 "register_operand")
6129 (leu:SI (match_dup 1)
6132 { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
6134 (define_insn "*sleu_si"
6135 [(set (match_operand:SI 0 "register_operand" "=d")
6136 (leu:SI (match_operand:SI 1 "register_operand" "d")
6137 (match_operand:SI 2 "sleu_operand" "")))]
6140 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6141 return "sltu\t%0,%1,%2";
6143 [(set_attr "type" "slt")
6144 (set_attr "mode" "SI")])
6146 (define_insn "*sleu_si_mips16"
6147 [(set (match_operand:SI 0 "register_operand" "=t")
6148 (leu:SI (match_operand:SI 1 "register_operand" "d")
6149 (match_operand:SI 2 "sleu_operand" "")))]
6152 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6153 return "sltu\t%1,%2";
6155 [(set_attr "type" "slt")
6156 (set_attr "mode" "SI")
6157 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6161 (define_insn "*sleu_di"
6162 [(set (match_operand:DI 0 "register_operand" "=d")
6163 (leu:DI (match_operand:DI 1 "register_operand" "d")
6164 (match_operand:DI 2 "sleu_operand" "")))]
6165 "TARGET_64BIT && !TARGET_MIPS16"
6167 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6168 return "sltu\t%0,%1,%2";
6170 [(set_attr "type" "slt")
6171 (set_attr "mode" "DI")])
6173 (define_insn "*sleu_di_mips16"
6174 [(set (match_operand:DI 0 "register_operand" "=t")
6175 (leu:DI (match_operand:DI 1 "register_operand" "d")
6176 (match_operand:DI 2 "sleu_operand" "")))]
6177 "TARGET_64BIT && TARGET_MIPS16"
6179 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6180 return "sltu\t%1,%2";
6182 [(set_attr "type" "slt")
6183 (set_attr "mode" "DI")
6184 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6189 ;; ....................
6191 ;; FLOATING POINT COMPARISONS
6193 ;; ....................
6195 (define_insn "sunordered_df"
6196 [(set (match_operand:CC 0 "register_operand" "=z")
6197 (unordered:CC (match_operand:DF 1 "register_operand" "f")
6198 (match_operand:DF 2 "register_operand" "f")))]
6199 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6201 [(set_attr "type" "fcmp")
6202 (set_attr "mode" "FPSW")])
6204 (define_insn "sunlt_df"
6205 [(set (match_operand:CC 0 "register_operand" "=z")
6206 (unlt:CC (match_operand:DF 1 "register_operand" "f")
6207 (match_operand:DF 2 "register_operand" "f")))]
6208 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6210 [(set_attr "type" "fcmp")
6211 (set_attr "mode" "FPSW")])
6213 (define_insn "suneq_df"
6214 [(set (match_operand:CC 0 "register_operand" "=z")
6215 (uneq:CC (match_operand:DF 1 "register_operand" "f")
6216 (match_operand:DF 2 "register_operand" "f")))]
6217 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6219 [(set_attr "type" "fcmp")
6220 (set_attr "mode" "FPSW")])
6222 (define_insn "sunle_df"
6223 [(set (match_operand:CC 0 "register_operand" "=z")
6224 (unle:CC (match_operand:DF 1 "register_operand" "f")
6225 (match_operand:DF 2 "register_operand" "f")))]
6226 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6228 [(set_attr "type" "fcmp")
6229 (set_attr "mode" "FPSW")])
6231 (define_insn "seq_df"
6232 [(set (match_operand:CC 0 "register_operand" "=z")
6233 (eq:CC (match_operand:DF 1 "register_operand" "f")
6234 (match_operand:DF 2 "register_operand" "f")))]
6235 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6237 [(set_attr "type" "fcmp")
6238 (set_attr "mode" "FPSW")])
6240 (define_insn "slt_df"
6241 [(set (match_operand:CC 0 "register_operand" "=z")
6242 (lt:CC (match_operand:DF 1 "register_operand" "f")
6243 (match_operand:DF 2 "register_operand" "f")))]
6244 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6246 [(set_attr "type" "fcmp")
6247 (set_attr "mode" "FPSW")])
6249 (define_insn "sle_df"
6250 [(set (match_operand:CC 0 "register_operand" "=z")
6251 (le:CC (match_operand:DF 1 "register_operand" "f")
6252 (match_operand:DF 2 "register_operand" "f")))]
6253 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6255 [(set_attr "type" "fcmp")
6256 (set_attr "mode" "FPSW")])
6258 (define_insn "sgt_df"
6259 [(set (match_operand:CC 0 "register_operand" "=z")
6260 (gt:CC (match_operand:DF 1 "register_operand" "f")
6261 (match_operand:DF 2 "register_operand" "f")))]
6262 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6264 [(set_attr "type" "fcmp")
6265 (set_attr "mode" "FPSW")])
6267 (define_insn "sge_df"
6268 [(set (match_operand:CC 0 "register_operand" "=z")
6269 (ge:CC (match_operand:DF 1 "register_operand" "f")
6270 (match_operand:DF 2 "register_operand" "f")))]
6271 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6273 [(set_attr "type" "fcmp")
6274 (set_attr "mode" "FPSW")])
6276 (define_insn "sunordered_sf"
6277 [(set (match_operand:CC 0 "register_operand" "=z")
6278 (unordered:CC (match_operand:SF 1 "register_operand" "f")
6279 (match_operand:SF 2 "register_operand" "f")))]
6282 [(set_attr "type" "fcmp")
6283 (set_attr "mode" "FPSW")])
6285 (define_insn "sunlt_sf"
6286 [(set (match_operand:CC 0 "register_operand" "=z")
6287 (unlt:CC (match_operand:SF 1 "register_operand" "f")
6288 (match_operand:SF 2 "register_operand" "f")))]
6291 [(set_attr "type" "fcmp")
6292 (set_attr "mode" "FPSW")])
6294 (define_insn "suneq_sf"
6295 [(set (match_operand:CC 0 "register_operand" "=z")
6296 (uneq:CC (match_operand:SF 1 "register_operand" "f")
6297 (match_operand:SF 2 "register_operand" "f")))]
6300 [(set_attr "type" "fcmp")
6301 (set_attr "mode" "FPSW")])
6303 (define_insn "sunle_sf"
6304 [(set (match_operand:CC 0 "register_operand" "=z")
6305 (unle:CC (match_operand:SF 1 "register_operand" "f")
6306 (match_operand:SF 2 "register_operand" "f")))]
6309 [(set_attr "type" "fcmp")
6310 (set_attr "mode" "FPSW")])
6312 (define_insn "seq_sf"
6313 [(set (match_operand:CC 0 "register_operand" "=z")
6314 (eq:CC (match_operand:SF 1 "register_operand" "f")
6315 (match_operand:SF 2 "register_operand" "f")))]
6318 [(set_attr "type" "fcmp")
6319 (set_attr "mode" "FPSW")])
6321 (define_insn "slt_sf"
6322 [(set (match_operand:CC 0 "register_operand" "=z")
6323 (lt:CC (match_operand:SF 1 "register_operand" "f")
6324 (match_operand:SF 2 "register_operand" "f")))]
6327 [(set_attr "type" "fcmp")
6328 (set_attr "mode" "FPSW")])
6330 (define_insn "sle_sf"
6331 [(set (match_operand:CC 0 "register_operand" "=z")
6332 (le:CC (match_operand:SF 1 "register_operand" "f")
6333 (match_operand:SF 2 "register_operand" "f")))]
6336 [(set_attr "type" "fcmp")
6337 (set_attr "mode" "FPSW")])
6339 (define_insn "sgt_sf"
6340 [(set (match_operand:CC 0 "register_operand" "=z")
6341 (gt:CC (match_operand:SF 1 "register_operand" "f")
6342 (match_operand:SF 2 "register_operand" "f")))]
6345 [(set_attr "type" "fcmp")
6346 (set_attr "mode" "FPSW")])
6348 (define_insn "sge_sf"
6349 [(set (match_operand:CC 0 "register_operand" "=z")
6350 (ge:CC (match_operand:SF 1 "register_operand" "f")
6351 (match_operand:SF 2 "register_operand" "f")))]
6354 [(set_attr "type" "fcmp")
6355 (set_attr "mode" "FPSW")])
6358 ;; ....................
6360 ;; UNCONDITIONAL BRANCHES
6362 ;; ....................
6364 ;; Unconditional branches.
6368 (label_ref (match_operand 0 "" "")))]
6373 if (get_attr_length (insn) <= 8)
6374 return "%*b\t%l0%/";
6377 output_asm_insn (mips_output_load_label (), operands);
6378 return "%*jr\t%@%/%]";
6382 return "%*j\t%l0%/";
6384 [(set_attr "type" "jump")
6385 (set_attr "mode" "none")
6386 (set (attr "length")
6387 ;; We can't use `j' when emitting PIC. Emit a branch if it's
6388 ;; in range, otherwise load the address of the branch target into
6389 ;; $at and then jump to it.
6391 (ior (eq (symbol_ref "flag_pic") (const_int 0))
6392 (lt (abs (minus (match_dup 0)
6393 (plus (pc) (const_int 4))))
6394 (const_int 131072)))
6395 (const_int 4) (const_int 16)))])
6397 ;; We need a different insn for the mips16, because a mips16 branch
6398 ;; does not have a delay slot.
6402 (label_ref (match_operand 0 "" "")))]
6405 [(set_attr "type" "branch")
6406 (set_attr "mode" "none")
6407 (set_attr "length" "8")])
6409 (define_expand "indirect_jump"
6410 [(set (pc) (match_operand 0 "register_operand"))]
6416 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
6417 operands[0] = copy_to_mode_reg (Pmode, dest);
6419 if (!(Pmode == DImode))
6420 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
6422 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
6427 (define_insn "indirect_jump_internal1"
6428 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
6429 "!(Pmode == DImode)"
6431 [(set_attr "type" "jump")
6432 (set_attr "mode" "none")])
6434 (define_insn "indirect_jump_internal2"
6435 [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
6438 [(set_attr "type" "jump")
6439 (set_attr "mode" "none")])
6441 (define_expand "tablejump"
6443 (match_operand 0 "register_operand"))
6444 (use (label_ref (match_operand 1 "")))]
6449 if (GET_MODE (operands[0]) != HImode)
6451 if (!(Pmode == DImode))
6452 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
6454 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
6458 if (GET_MODE (operands[0]) != ptr_mode)
6462 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
6463 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
6465 if (Pmode == SImode)
6466 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
6468 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
6472 (define_insn "tablejump_internal1"
6474 (match_operand:SI 0 "register_operand" "d"))
6475 (use (label_ref (match_operand 1 "" "")))]
6478 [(set_attr "type" "jump")
6479 (set_attr "mode" "none")])
6481 (define_insn "tablejump_internal2"
6483 (match_operand:DI 0 "register_operand" "d"))
6484 (use (label_ref (match_operand 1 "" "")))]
6487 [(set_attr "type" "jump")
6488 (set_attr "mode" "none")])
6490 (define_expand "tablejump_mips161"
6491 [(set (pc) (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand"))
6492 (label_ref:SI (match_operand 1 ""))))]
6493 "TARGET_MIPS16 && !(Pmode == DImode)"
6497 t1 = gen_reg_rtx (SImode);
6498 t2 = gen_reg_rtx (SImode);
6499 t3 = gen_reg_rtx (SImode);
6500 emit_insn (gen_extendhisi2 (t1, operands[0]));
6501 emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
6502 emit_insn (gen_addsi3 (t3, t1, t2));
6503 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
6507 (define_expand "tablejump_mips162"
6508 [(set (pc) (plus:DI (sign_extend:DI (match_operand:HI 0 "register_operand"))
6509 (label_ref:DI (match_operand 1 ""))))]
6510 "TARGET_MIPS16 && Pmode == DImode"
6514 t1 = gen_reg_rtx (DImode);
6515 t2 = gen_reg_rtx (DImode);
6516 t3 = gen_reg_rtx (DImode);
6517 emit_insn (gen_extendhidi2 (t1, operands[0]));
6518 emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
6519 emit_insn (gen_adddi3 (t3, t1, t2));
6520 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
6524 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
6525 ;; While it is possible to either pull it off the stack (in the
6526 ;; o32 case) or recalculate it given t9 and our target label,
6527 ;; it takes 3 or 4 insns to do so.
6529 (define_expand "builtin_setjmp_setup"
6530 [(use (match_operand 0 "register_operand"))]
6535 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
6536 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
6540 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
6541 ;; that older code did recalculate the gp from $25. Continue to jump through
6542 ;; $25 for compatibility (we lose nothing by doing so).
6544 (define_expand "builtin_longjmp"
6545 [(use (match_operand 0 "register_operand"))]
6548 /* The elements of the buffer are, in order: */
6549 int W = GET_MODE_SIZE (Pmode);
6550 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6551 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
6552 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
6553 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
6554 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6555 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
6556 The target is bound to be using $28 as the global pointer
6557 but the current function might not be. */
6558 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
6560 /* This bit is similar to expand_builtin_longjmp except that it
6561 restores $gp as well. */
6562 emit_move_insn (hard_frame_pointer_rtx, fp);
6563 emit_move_insn (pv, lab);
6564 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6565 emit_move_insn (gp, gpv);
6566 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6567 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6568 emit_insn (gen_rtx_USE (VOIDmode, gp));
6569 emit_indirect_jump (pv);
6574 ;; ....................
6576 ;; Function prologue/epilogue
6578 ;; ....................
6581 (define_expand "prologue"
6585 mips_expand_prologue ();
6589 ;; Block any insns from being moved before this point, since the
6590 ;; profiling call to mcount can use various registers that aren't
6591 ;; saved or used to pass arguments.
6593 (define_insn "blockage"
6594 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
6597 [(set_attr "type" "unknown")
6598 (set_attr "mode" "none")
6599 (set_attr "length" "0")])
6601 (define_expand "epilogue"
6605 mips_expand_epilogue (false);
6609 (define_expand "sibcall_epilogue"
6613 mips_expand_epilogue (true);
6617 ;; Trivial return. Make it look like a normal return insn as that
6618 ;; allows jump optimizations to work better.
6620 (define_insn "return"
6622 "mips_can_use_return_insn ()"
6624 [(set_attr "type" "jump")
6625 (set_attr "mode" "none")])
6629 (define_insn "return_internal"
6631 (use (match_operand 0 "pmode_register_operand" ""))]
6634 [(set_attr "type" "jump")
6635 (set_attr "mode" "none")])
6637 ;; This is used in compiling the unwind routines.
6638 (define_expand "eh_return"
6639 [(use (match_operand 0 "general_operand"))]
6642 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
6644 if (GET_MODE (operands[0]) != gpr_mode)
6645 operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
6647 emit_insn (gen_eh_set_lr_di (operands[0]));
6649 emit_insn (gen_eh_set_lr_si (operands[0]));
6654 ;; Clobber the return address on the stack. We can't expand this
6655 ;; until we know where it will be put in the stack frame.
6657 (define_insn "eh_set_lr_si"
6658 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6659 (clobber (match_scratch:SI 1 "=&d"))]
6663 (define_insn "eh_set_lr_di"
6664 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6665 (clobber (match_scratch:DI 1 "=&d"))]
6670 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6671 (clobber (match_scratch 1))]
6672 "reload_completed && !TARGET_DEBUG_D_MODE"
6675 mips_set_return_address (operands[0], operands[1]);
6679 (define_insn_and_split "exception_receiver"
6681 (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
6682 "TARGET_ABICALLS && TARGET_OLDABI"
6684 "&& reload_completed"
6690 [(set_attr "type" "load")
6691 (set_attr "length" "12")])
6694 ;; ....................
6698 ;; ....................
6700 ;; Instructions to load a call address from the GOT. The address might
6701 ;; point to a function or to a lazy binding stub. In the latter case,
6702 ;; the stub will use the dynamic linker to resolve the function, which
6703 ;; in turn will change the GOT entry to point to the function's real
6706 ;; This means that every call, even pure and constant ones, can
6707 ;; potentially modify the GOT entry. And once a stub has been called,
6708 ;; we must not call it again.
6710 ;; We represent this restriction using an imaginary fixed register that
6711 ;; acts like a GOT version number. By making the register call-clobbered,
6712 ;; we tell the target-independent code that the address could be changed
6713 ;; by any call insn.
6714 (define_insn "load_callsi"
6715 [(set (match_operand:SI 0 "register_operand" "=c")
6716 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6717 (match_operand:SI 2 "immediate_operand" "")
6718 (reg:SI FAKE_CALL_REGNO)]
6722 [(set_attr "type" "load")
6723 (set_attr "length" "4")])
6725 (define_insn "load_calldi"
6726 [(set (match_operand:DI 0 "register_operand" "=c")
6727 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
6728 (match_operand:DI 2 "immediate_operand" "")
6729 (reg:DI FAKE_CALL_REGNO)]
6733 [(set_attr "type" "load")
6734 (set_attr "length" "4")])
6736 ;; Sibling calls. All these patterns use jump instructions.
6738 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
6739 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
6740 ;; is defined in terms of call_insn_operand, the same is true of the
6743 ;; When we use an indirect jump, we need a register that will be
6744 ;; preserved by the epilogue. Since TARGET_ABICALLS forces us to
6745 ;; use $25 for this purpose -- and $25 is never clobbered by the
6746 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
6748 (define_expand "sibcall"
6749 [(parallel [(call (match_operand 0 "")
6750 (match_operand 1 ""))
6751 (use (match_operand 2 "")) ;; next_arg_reg
6752 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
6755 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
6759 (define_insn "sibcall_internal"
6760 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
6761 (match_operand 1 "" ""))]
6762 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6766 [(set_attr "type" "call")])
6768 (define_expand "sibcall_value"
6769 [(parallel [(set (match_operand 0 "")
6770 (call (match_operand 1 "")
6771 (match_operand 2 "")))
6772 (use (match_operand 3 ""))])] ;; next_arg_reg
6775 mips_expand_call (operands[0], XEXP (operands[1], 0),
6776 operands[2], operands[3], true);
6780 (define_insn "sibcall_value_internal"
6781 [(set (match_operand 0 "register_operand" "=df,df")
6782 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6783 (match_operand 2 "" "")))]
6784 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6788 [(set_attr "type" "call")])
6790 (define_insn "sibcall_value_multiple_internal"
6791 [(set (match_operand 0 "register_operand" "=df,df")
6792 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6793 (match_operand 2 "" "")))
6794 (set (match_operand 3 "register_operand" "=df,df")
6795 (call (mem:SI (match_dup 1))
6797 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6801 [(set_attr "type" "call")])
6803 (define_expand "call"
6804 [(parallel [(call (match_operand 0 "")
6805 (match_operand 1 ""))
6806 (use (match_operand 2 "")) ;; next_arg_reg
6807 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
6810 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
6814 ;; This instruction directly corresponds to an assembly-language "jal".
6815 ;; There are four cases:
6818 ;; Both symbolic and register destinations are OK. The pattern
6819 ;; always expands to a single mips instruction.
6821 ;; - -mabicalls/-mno-explicit-relocs:
6822 ;; Again, both symbolic and register destinations are OK.
6823 ;; The call is treated as a multi-instruction black box.
6825 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
6826 ;; Only "jal $25" is allowed. This expands to a single "jalr $25"
6829 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
6830 ;; Only "jal $25" is allowed. The call is actually two instructions:
6831 ;; "jalr $25" followed by an insn to reload $gp.
6833 ;; In the last case, we can generate the individual instructions with
6834 ;; a define_split. There are several things to be wary of:
6836 ;; - We can't expose the load of $gp before reload. If we did,
6837 ;; it might get removed as dead, but reload can introduce new
6838 ;; uses of $gp by rematerializing constants.
6840 ;; - We shouldn't restore $gp after calls that never return.
6841 ;; It isn't valid to insert instructions between a noreturn
6842 ;; call and the following barrier.
6844 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
6845 ;; instruction preserves $gp and so have no effect on its liveness.
6846 ;; But once we generate the separate insns, it becomes obvious that
6847 ;; $gp is not live on entry to the call.
6849 ;; ??? The operands[2] = insn check is a hack to make the original insn
6850 ;; available to the splitter.
6851 (define_insn_and_split "call_internal"
6852 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
6853 (match_operand 1 "" ""))
6854 (clobber (reg:SI 31))]
6856 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
6857 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
6860 emit_call_insn (gen_call_split (operands[0], operands[1]));
6861 if (!find_reg_note (operands[2], REG_NORETURN, 0))
6865 [(set_attr "jal" "indirect,direct")
6866 (set_attr "extended_mips16" "no,yes")])
6868 (define_insn "call_split"
6869 [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
6870 (match_operand 1 "" ""))
6871 (clobber (reg:SI 31))
6872 (clobber (reg:SI 28))]
6873 "TARGET_SPLIT_CALLS"
6875 [(set_attr "type" "call")])
6877 (define_expand "call_value"
6878 [(parallel [(set (match_operand 0 "")
6879 (call (match_operand 1 "")
6880 (match_operand 2 "")))
6881 (use (match_operand 3 ""))])] ;; next_arg_reg
6884 mips_expand_call (operands[0], XEXP (operands[1], 0),
6885 operands[2], operands[3], false);
6889 ;; See comment for call_internal.
6890 (define_insn_and_split "call_value_internal"
6891 [(set (match_operand 0 "register_operand" "=df,df")
6892 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6893 (match_operand 2 "" "")))
6894 (clobber (reg:SI 31))]
6896 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
6897 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
6900 emit_call_insn (gen_call_value_split (operands[0], operands[1],
6902 if (!find_reg_note (operands[3], REG_NORETURN, 0))
6906 [(set_attr "jal" "indirect,direct")
6907 (set_attr "extended_mips16" "no,yes")])
6909 (define_insn "call_value_split"
6910 [(set (match_operand 0 "register_operand" "=df")
6911 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
6912 (match_operand 2 "" "")))
6913 (clobber (reg:SI 31))
6914 (clobber (reg:SI 28))]
6915 "TARGET_SPLIT_CALLS"
6917 [(set_attr "type" "call")])
6919 ;; See comment for call_internal.
6920 (define_insn_and_split "call_value_multiple_internal"
6921 [(set (match_operand 0 "register_operand" "=df,df")
6922 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6923 (match_operand 2 "" "")))
6924 (set (match_operand 3 "register_operand" "=df,df")
6925 (call (mem:SI (match_dup 1))
6927 (clobber (reg:SI 31))]
6929 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
6930 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
6933 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
6934 operands[2], operands[3]));
6935 if (!find_reg_note (operands[4], REG_NORETURN, 0))
6939 [(set_attr "jal" "indirect,direct")
6940 (set_attr "extended_mips16" "no,yes")])
6942 (define_insn "call_value_multiple_split"
6943 [(set (match_operand 0 "register_operand" "=df")
6944 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
6945 (match_operand 2 "" "")))
6946 (set (match_operand 3 "register_operand" "=df")
6947 (call (mem:SI (match_dup 1))
6949 (clobber (reg:SI 31))
6950 (clobber (reg:SI 28))]
6951 "TARGET_SPLIT_CALLS"
6953 [(set_attr "type" "call")])
6955 ;; Call subroutine returning any type.
6957 (define_expand "untyped_call"
6958 [(parallel [(call (match_operand 0 "")
6960 (match_operand 1 "")
6961 (match_operand 2 "")])]
6966 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6968 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6970 rtx set = XVECEXP (operands[2], 0, i);
6971 emit_move_insn (SET_DEST (set), SET_SRC (set));
6974 emit_insn (gen_blockage ());
6979 ;; ....................
6983 ;; ....................
6987 (define_expand "prefetch"
6988 [(prefetch (match_operand 0 "address_operand")
6989 (match_operand 1 "const_int_operand")
6990 (match_operand 2 "const_int_operand"))]
6993 if (symbolic_operand (operands[0], GET_MODE (operands[0])))
6994 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
6997 (define_insn "prefetch_si_address"
6998 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
6999 (match_operand:SI 3 "const_int_operand" "I"))
7000 (match_operand:SI 1 "const_int_operand" "n")
7001 (match_operand:SI 2 "const_int_operand" "n"))]
7002 "ISA_HAS_PREFETCH && Pmode == SImode"
7003 { return mips_emit_prefetch (operands); }
7004 [(set_attr "type" "prefetch")])
7006 (define_insn "prefetch_indexed_si"
7007 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7008 (match_operand:SI 3 "register_operand" "r"))
7009 (match_operand:SI 1 "const_int_operand" "n")
7010 (match_operand:SI 2 "const_int_operand" "n"))]
7011 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
7012 { return mips_emit_prefetch (operands); }
7013 [(set_attr "type" "prefetchx")])
7015 (define_insn "prefetch_si"
7016 [(prefetch (match_operand:SI 0 "register_operand" "r")
7017 (match_operand:SI 1 "const_int_operand" "n")
7018 (match_operand:SI 2 "const_int_operand" "n"))]
7019 "ISA_HAS_PREFETCH && Pmode == SImode"
7021 operands[3] = const0_rtx;
7022 return mips_emit_prefetch (operands);
7024 [(set_attr "type" "prefetch")])
7026 (define_insn "prefetch_di_address"
7027 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7028 (match_operand:DI 3 "const_int_operand" "I"))
7029 (match_operand:DI 1 "const_int_operand" "n")
7030 (match_operand:DI 2 "const_int_operand" "n"))]
7031 "ISA_HAS_PREFETCH && Pmode == DImode"
7032 { return mips_emit_prefetch (operands); }
7033 [(set_attr "type" "prefetch")])
7035 (define_insn "prefetch_indexed_di"
7036 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7037 (match_operand:DI 3 "register_operand" "r"))
7038 (match_operand:DI 1 "const_int_operand" "n")
7039 (match_operand:DI 2 "const_int_operand" "n"))]
7040 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
7041 { return mips_emit_prefetch (operands); }
7042 [(set_attr "type" "prefetchx")])
7044 (define_insn "prefetch_di"
7045 [(prefetch (match_operand:DI 0 "register_operand" "r")
7046 (match_operand:DI 1 "const_int_operand" "n")
7047 (match_operand:DI 2 "const_int_operand" "n"))]
7048 "ISA_HAS_PREFETCH && Pmode == DImode"
7050 operands[3] = const0_rtx;
7051 return mips_emit_prefetch (operands);
7053 [(set_attr "type" "prefetch")])
7059 [(set_attr "type" "nop")
7060 (set_attr "mode" "none")])
7062 ;; Like nop, but commented out when outside a .set noreorder block.
7063 (define_insn "hazard_nop"
7072 [(set_attr "type" "nop")])
7074 ;; MIPS4 Conditional move instructions.
7077 [(set (match_operand:SI 0 "register_operand" "=d,d")
7079 (match_operator:SI 4 "equality_operator"
7080 [(match_operand:SI 1 "register_operand" "d,d")
7082 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7083 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7084 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7088 [(set_attr "type" "condmove")
7089 (set_attr "mode" "SI")])
7092 [(set (match_operand:SI 0 "register_operand" "=d,d")
7094 (match_operator:DI 4 "equality_operator"
7095 [(match_operand:DI 1 "register_operand" "d,d")
7097 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7098 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7099 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7103 [(set_attr "type" "condmove")
7104 (set_attr "mode" "SI")])
7107 [(set (match_operand:SI 0 "register_operand" "=d,d")
7109 (match_operator:CC 3 "equality_operator"
7110 [(match_operand:CC 4 "register_operand" "z,z")
7112 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
7113 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
7114 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7118 [(set_attr "type" "condmove")
7119 (set_attr "mode" "SI")])
7122 [(set (match_operand:DI 0 "register_operand" "=d,d")
7124 (match_operator:SI 4 "equality_operator"
7125 [(match_operand:SI 1 "register_operand" "d,d")
7127 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7128 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7129 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7133 [(set_attr "type" "condmove")
7134 (set_attr "mode" "DI")])
7137 [(set (match_operand:DI 0 "register_operand" "=d,d")
7139 (match_operator:DI 4 "equality_operator"
7140 [(match_operand:DI 1 "register_operand" "d,d")
7142 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7143 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7144 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7148 [(set_attr "type" "condmove")
7149 (set_attr "mode" "DI")])
7152 [(set (match_operand:DI 0 "register_operand" "=d,d")
7154 (match_operator:CC 3 "equality_operator"
7155 [(match_operand:CC 4 "register_operand" "z,z")
7157 (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
7158 (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
7159 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
7163 [(set_attr "type" "condmove")
7164 (set_attr "mode" "DI")])
7167 [(set (match_operand:SF 0 "register_operand" "=f,f")
7169 (match_operator:SI 4 "equality_operator"
7170 [(match_operand:SI 1 "register_operand" "d,d")
7172 (match_operand:SF 2 "register_operand" "f,0")
7173 (match_operand:SF 3 "register_operand" "0,f")))]
7174 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7178 [(set_attr "type" "condmove")
7179 (set_attr "mode" "SF")])
7182 [(set (match_operand:SF 0 "register_operand" "=f,f")
7184 (match_operator:DI 4 "equality_operator"
7185 [(match_operand:DI 1 "register_operand" "d,d")
7187 (match_operand:SF 2 "register_operand" "f,0")
7188 (match_operand:SF 3 "register_operand" "0,f")))]
7189 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7193 [(set_attr "type" "condmove")
7194 (set_attr "mode" "SF")])
7197 [(set (match_operand:SF 0 "register_operand" "=f,f")
7199 (match_operator:CC 3 "equality_operator"
7200 [(match_operand:CC 4 "register_operand" "z,z")
7202 (match_operand:SF 1 "register_operand" "f,0")
7203 (match_operand:SF 2 "register_operand" "0,f")))]
7204 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7208 [(set_attr "type" "condmove")
7209 (set_attr "mode" "SF")])
7212 [(set (match_operand:DF 0 "register_operand" "=f,f")
7214 (match_operator:SI 4 "equality_operator"
7215 [(match_operand:SI 1 "register_operand" "d,d")
7217 (match_operand:DF 2 "register_operand" "f,0")
7218 (match_operand:DF 3 "register_operand" "0,f")))]
7219 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7223 [(set_attr "type" "condmove")
7224 (set_attr "mode" "DF")])
7227 [(set (match_operand:DF 0 "register_operand" "=f,f")
7229 (match_operator:DI 4 "equality_operator"
7230 [(match_operand:DI 1 "register_operand" "d,d")
7232 (match_operand:DF 2 "register_operand" "f,0")
7233 (match_operand:DF 3 "register_operand" "0,f")))]
7234 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7238 [(set_attr "type" "condmove")
7239 (set_attr "mode" "DF")])
7242 [(set (match_operand:DF 0 "register_operand" "=f,f")
7244 (match_operator:CC 3 "equality_operator"
7245 [(match_operand:CC 4 "register_operand" "z,z")
7247 (match_operand:DF 1 "register_operand" "f,0")
7248 (match_operand:DF 2 "register_operand" "0,f")))]
7249 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7253 [(set_attr "type" "condmove")
7254 (set_attr "mode" "DF")])
7256 ;; These are the main define_expand's used to make conditional moves.
7258 (define_expand "movsicc"
7259 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7260 (set (match_operand:SI 0 "register_operand")
7261 (if_then_else:SI (match_dup 5)
7262 (match_operand:SI 2 "reg_or_0_operand")
7263 (match_operand:SI 3 "reg_or_0_operand")))]
7264 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7266 gen_conditional_move (operands);
7270 (define_expand "movdicc"
7271 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7272 (set (match_operand:DI 0 "register_operand")
7273 (if_then_else:DI (match_dup 5)
7274 (match_operand:DI 2 "reg_or_0_operand")
7275 (match_operand:DI 3 "reg_or_0_operand")))]
7276 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7278 gen_conditional_move (operands);
7282 (define_expand "movsfcc"
7283 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7284 (set (match_operand:SF 0 "register_operand")
7285 (if_then_else:SF (match_dup 5)
7286 (match_operand:SF 2 "register_operand")
7287 (match_operand:SF 3 "register_operand")))]
7288 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7290 gen_conditional_move (operands);
7294 (define_expand "movdfcc"
7295 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7296 (set (match_operand:DF 0 "register_operand")
7297 (if_then_else:DF (match_dup 5)
7298 (match_operand:DF 2 "register_operand")
7299 (match_operand:DF 3 "register_operand")))]
7300 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7302 gen_conditional_move (operands);
7307 ;; ....................
7309 ;; mips16 inline constant tables
7311 ;; ....................
7314 (define_insn "consttable_int"
7315 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
7316 (match_operand 1 "const_int_operand" "")]
7317 UNSPEC_CONSTTABLE_INT)]
7320 assemble_integer (operands[0], INTVAL (operands[1]),
7321 BITS_PER_UNIT * INTVAL (operands[1]), 1);
7324 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
7326 (define_insn "consttable_float"
7327 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
7328 UNSPEC_CONSTTABLE_FLOAT)]
7333 if (GET_CODE (operands[0]) != CONST_DOUBLE)
7335 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7336 assemble_real (d, GET_MODE (operands[0]),
7337 GET_MODE_BITSIZE (GET_MODE (operands[0])));
7340 [(set (attr "length")
7341 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
7343 (define_insn "align"
7344 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
7347 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
7350 [(match_operand 0 "small_data_pattern")]
7353 { operands[0] = mips_rewrite_small_data (operands[0]); })