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 ;; ....................
61 ;; ....................
63 (define_attr "got" "unset,xgot_high,load"
64 (const_string "unset"))
66 ;; For jal instructions, this attribute is DIRECT when the target address
67 ;; is symbolic and INDIRECT when it is a register.
68 (define_attr "jal" "unset,direct,indirect"
69 (const_string "unset"))
71 ;; This attribute is YES if the instruction is a jal macro (not a
72 ;; real jal instruction).
74 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
75 ;; restore $gp. Direct jals are also macros in NewABI PIC since they
76 ;; load the target address into $25.
77 (define_attr "jal_macro" "no,yes"
78 (cond [(eq_attr "jal" "direct")
79 (symbol_ref "TARGET_ABICALLS != 0")
80 (eq_attr "jal" "indirect")
81 (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
84 ;; Classification of each insn.
85 ;; branch conditional branch
86 ;; jump unconditional jump
87 ;; call unconditional call
88 ;; load load instruction(s)
89 ;; fpload floating point load
90 ;; fpidxload floating point indexed load
91 ;; store store instruction(s)
92 ;; fpstore floating point store
93 ;; fpidxstore floating point indexed store
94 ;; prefetch memory prefetch (register + offset)
95 ;; prefetchx memory indexed prefetch (register + register)
96 ;; condmove conditional moves
97 ;; xfer transfer to/from coprocessor
98 ;; mthilo transfer to hi/lo registers
99 ;; mfhilo transfer from hi/lo registers
100 ;; const load constant
101 ;; arith integer arithmetic and logical instructions
102 ;; shift integer shift instructions
103 ;; slt set less than instructions
104 ;; clz the clz and clo instructions
105 ;; trap trap if instructions
106 ;; imul integer multiply
107 ;; imadd integer multiply-add
108 ;; idiv integer divide
109 ;; fmove floating point register move
110 ;; fadd floating point add/subtract
111 ;; fmul floating point multiply
112 ;; fmadd floating point multiply-add
113 ;; fdiv floating point divide
114 ;; fabs floating point absolute value
115 ;; fneg floating point negation
116 ;; fcmp floating point compare
117 ;; fcvt floating point convert
118 ;; fsqrt floating point square root
119 ;; frsqrt floating point reciprocal square root
120 ;; multi multiword sequence (or user asm statements)
123 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
124 (cond [(eq_attr "jal" "!unset") (const_string "call")
125 (eq_attr "got" "load") (const_string "load")]
126 (const_string "unknown")))
128 ;; Main data type used by the insn
129 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
130 (const_string "unknown"))
132 ;; Is this an extended instruction in mips16 mode?
133 (define_attr "extended_mips16" "no,yes"
136 ;; Length of instruction in bytes.
137 (define_attr "length" ""
138 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
139 ;; If a branch is outside this range, we have a choice of two
140 ;; sequences. For PIC, an out-of-range branch like:
145 ;; becomes the equivalent of:
154 ;; where the load address can be up to three instructions long
157 ;; The non-PIC case is similar except that we use a direct
158 ;; jump instead of an la/jr pair. Since the target of this
159 ;; jump is an absolute 28-bit bit address (the other bits
160 ;; coming from the address of the delay slot) this form cannot
161 ;; cross a 256MB boundary. We could provide the option of
162 ;; using la/jr in this case too, but we do not do so at
165 ;; Note that this value does not account for the delay slot
166 ;; instruction, whose length is added separately. If the RTL
167 ;; pattern has no explicit delay slot, mips_adjust_insn_length
168 ;; will add the length of the implicit nop. The values for
169 ;; forward and backward branches will be different as well.
170 (eq_attr "type" "branch")
171 (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
172 (le (minus (pc) (match_dup 1)) (const_int 131068)))
174 (ne (symbol_ref "flag_pic") (const_int 0))
178 (eq_attr "got" "load")
180 (eq_attr "got" "xgot_high")
183 (eq_attr "type" "const")
184 (symbol_ref "mips_const_insns (operands[1]) * 4")
185 (eq_attr "type" "load,fpload,fpidxload")
186 (symbol_ref "mips_fetch_insns (operands[1]) * 4")
187 (eq_attr "type" "store,fpstore,fpidxstore")
188 (symbol_ref "mips_fetch_insns (operands[0]) * 4")
190 ;; In the worst case, a call macro will take 8 instructions:
192 ;; lui $25,%call_hi(FOO)
194 ;; lw $25,%call_lo(FOO)($25)
200 (eq_attr "jal_macro" "yes")
203 (and (eq_attr "extended_mips16" "yes")
204 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
207 ;; Various VR4120 errata require a nop to be inserted after a macc
208 ;; instruction. The assembler does this for us, so account for
209 ;; the worst-case length here.
210 (and (eq_attr "type" "imadd")
211 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
214 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
215 ;; the result of the second one is missed. The assembler should work
216 ;; around this by inserting a nop after the first dmult.
217 (and (eq_attr "type" "imul")
218 (and (eq_attr "mode" "DI")
219 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
222 (eq_attr "type" "idiv")
223 (symbol_ref "mips_idiv_insns () * 4")
226 ;; Attribute describing the processor. This attribute must match exactly
227 ;; with the processor_type enumeration in mips.h.
229 "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
230 (const (symbol_ref "mips_tune")))
232 ;; The type of hardware hazard associated with this instruction.
233 ;; DELAY means that the next instruction cannot read the result
234 ;; of this one. HILO means that the next two instructions cannot
235 ;; write to HI or LO.
236 (define_attr "hazard" "none,delay,hilo"
237 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
238 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
239 (const_string "delay")
241 (and (eq_attr "type" "xfer")
242 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
243 (const_string "delay")
245 (and (eq_attr "type" "fcmp")
246 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
247 (const_string "delay")
249 ;; The r4000 multiplication patterns include an mflo instruction.
250 (and (eq_attr "type" "imul")
251 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
252 (const_string "hilo")
254 (and (eq_attr "type" "mfhilo")
255 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
256 (const_string "hilo")]
257 (const_string "none")))
259 ;; Is it a single instruction?
260 (define_attr "single_insn" "no,yes"
261 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
263 ;; Can the instruction be put into a delay slot?
264 (define_attr "can_delay" "no,yes"
265 (if_then_else (and (eq_attr "type" "!branch,call,jump")
266 (and (eq_attr "hazard" "none")
267 (eq_attr "single_insn" "yes")))
269 (const_string "no")))
271 ;; Attribute defining whether or not we can use the branch-likely instructions
272 (define_attr "branch_likely" "no,yes"
274 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
276 (const_string "no"))))
278 ;; True if an instruction might assign to hi or lo when reloaded.
279 ;; This is used by the TUNE_MACC_CHAINS code.
280 (define_attr "may_clobber_hilo" "no,yes"
281 (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
283 (const_string "no")))
285 ;; Describe a user's asm statement.
286 (define_asm_attributes
287 [(set_attr "type" "multi")])
289 ;; .........................
291 ;; Branch, call and jump delay slots
293 ;; .........................
295 (define_delay (and (eq_attr "type" "branch")
296 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
297 [(eq_attr "can_delay" "yes")
299 (and (eq_attr "branch_likely" "yes")
300 (eq_attr "can_delay" "yes"))])
302 (define_delay (eq_attr "type" "jump")
303 [(eq_attr "can_delay" "yes")
307 (define_delay (and (eq_attr "type" "call")
308 (eq_attr "jal_macro" "no"))
309 [(eq_attr "can_delay" "yes")
313 ;; Pipeline descriptions.
315 ;; generic.md provides a fallback for processors without a specific
316 ;; pipeline description. It is derived from the old define_function_unit
317 ;; version and uses the "alu" and "imuldiv" units declared below.
319 ;; Some of the processor-specific files are also derived from old
320 ;; define_function_unit descriptions and simply override the parts of
321 ;; generic.md that don't apply. The other processor-specific files
322 ;; are self-contained.
323 (define_automaton "alu,imuldiv")
325 (define_cpu_unit "alu" "alu")
326 (define_cpu_unit "imuldiv" "imuldiv")
342 (include "generic.md")
345 ;; ....................
349 ;; ....................
353 [(trap_if (const_int 1) (const_int 0))]
356 if (ISA_HAS_COND_TRAP)
358 /* The IRIX 6 O32 assembler requires the first break operand. */
359 else if (TARGET_MIPS16 || !TARGET_GAS)
364 [(set_attr "type" "trap")])
366 (define_expand "conditional_trap"
367 [(trap_if (match_operator 0 "cmp_op"
368 [(match_dup 2) (match_dup 3)])
369 (match_operand 1 "const_int_operand"))]
372 if (operands[1] == const0_rtx)
374 mips_gen_conditional_trap (operands);
382 [(trap_if (match_operator 0 "trap_cmp_op"
383 [(match_operand:SI 1 "reg_or_0_operand" "dJ")
384 (match_operand:SI 2 "arith_operand" "dI")])
388 [(set_attr "type" "trap")])
391 [(trap_if (match_operator 0 "trap_cmp_op"
392 [(match_operand:DI 1 "reg_or_0_operand" "dJ")
393 (match_operand:DI 2 "arith_operand" "dI")])
395 "TARGET_64BIT && ISA_HAS_COND_TRAP"
397 [(set_attr "type" "trap")])
400 ;; ....................
404 ;; ....................
407 (define_insn "adddf3"
408 [(set (match_operand:DF 0 "register_operand" "=f")
409 (plus:DF (match_operand:DF 1 "register_operand" "f")
410 (match_operand:DF 2 "register_operand" "f")))]
411 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
413 [(set_attr "type" "fadd")
414 (set_attr "mode" "DF")])
416 (define_insn "addsf3"
417 [(set (match_operand:SF 0 "register_operand" "=f")
418 (plus:SF (match_operand:SF 1 "register_operand" "f")
419 (match_operand:SF 2 "register_operand" "f")))]
422 [(set_attr "type" "fadd")
423 (set_attr "mode" "SF")])
425 (define_expand "addsi3"
426 [(set (match_operand:SI 0 "register_operand")
427 (plus:SI (match_operand:SI 1 "reg_or_0_operand")
428 (match_operand:SI 2 "arith_operand")))]
431 (define_insn "addsi3_internal"
432 [(set (match_operand:SI 0 "register_operand" "=d,d")
433 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
434 (match_operand:SI 2 "arith_operand" "d,Q")))]
439 [(set_attr "type" "arith")
440 (set_attr "mode" "SI")])
442 ;; For the mips16, we need to recognize stack pointer additions
443 ;; explicitly, since we don't have a constraint for $sp. These insns
444 ;; will be generated by the save_restore_insns functions.
449 (match_operand:SI 0 "small_int" "I")))]
452 [(set_attr "type" "arith")
453 (set_attr "mode" "SI")
454 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
459 [(set (match_operand:SI 0 "register_operand" "=d")
461 (match_operand:SI 1 "small_int" "I")))]
464 [(set_attr "type" "arith")
465 (set_attr "mode" "SI")
466 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4")
471 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
472 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
473 (match_operand:SI 2 "arith_operand" "Q,O,d")))]
476 if (REGNO (operands[0]) == REGNO (operands[1]))
477 return "addu\t%0,%2";
479 return "addu\t%0,%1,%2";
481 [(set_attr "type" "arith")
482 (set_attr "mode" "SI")
483 (set_attr_alternative "length"
484 [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
487 (if_then_else (match_operand:VOID 2 "m16_simm4_1")
493 ;; On the mips16, we can sometimes split an add of a constant which is
494 ;; a 4 byte instruction into two adds which are both 2 byte
495 ;; instructions. There are two cases: one where we are adding a
496 ;; constant plus a register to another register, and one where we are
497 ;; simply adding a constant to a register.
500 [(set (match_operand:SI 0 "register_operand")
501 (plus:SI (match_dup 0)
502 (match_operand:SI 1 "const_int_operand")))]
503 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
504 && GET_CODE (operands[0]) == REG
505 && M16_REG_P (REGNO (operands[0]))
506 && GET_CODE (operands[1]) == CONST_INT
507 && ((INTVAL (operands[1]) > 0x7f
508 && INTVAL (operands[1]) <= 0x7f + 0x7f)
509 || (INTVAL (operands[1]) < - 0x80
510 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
511 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
512 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
514 HOST_WIDE_INT val = INTVAL (operands[1]);
518 operands[1] = GEN_INT (0x7f);
519 operands[2] = GEN_INT (val - 0x7f);
523 operands[1] = GEN_INT (- 0x80);
524 operands[2] = GEN_INT (val + 0x80);
529 [(set (match_operand:SI 0 "register_operand")
530 (plus:SI (match_operand:SI 1 "register_operand")
531 (match_operand:SI 2 "const_int_operand")))]
532 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
533 && GET_CODE (operands[0]) == REG
534 && M16_REG_P (REGNO (operands[0]))
535 && GET_CODE (operands[1]) == REG
536 && M16_REG_P (REGNO (operands[1]))
537 && REGNO (operands[0]) != REGNO (operands[1])
538 && GET_CODE (operands[2]) == CONST_INT
539 && ((INTVAL (operands[2]) > 0x7
540 && INTVAL (operands[2]) <= 0x7 + 0x7f)
541 || (INTVAL (operands[2]) < - 0x8
542 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
543 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
544 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
546 HOST_WIDE_INT val = INTVAL (operands[2]);
550 operands[2] = GEN_INT (0x7);
551 operands[3] = GEN_INT (val - 0x7);
555 operands[2] = GEN_INT (- 0x8);
556 operands[3] = GEN_INT (val + 0x8);
560 (define_expand "adddi3"
561 [(set (match_operand:DI 0 "register_operand")
562 (plus:DI (match_operand:DI 1 "register_operand")
563 (match_operand:DI 2 "arith_operand")))]
566 (define_insn "adddi3_internal"
567 [(set (match_operand:DI 0 "register_operand" "=d,d")
568 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")
569 (match_operand:DI 2 "arith_operand" "d,Q")))]
570 "TARGET_64BIT && !TARGET_MIPS16"
574 [(set_attr "type" "arith")
575 (set_attr "mode" "DI")])
577 ;; For the mips16, we need to recognize stack pointer additions
578 ;; explicitly, since we don't have a constraint for $sp. These insns
579 ;; will be generated by the save_restore_insns functions.
584 (match_operand:DI 0 "small_int" "I")))]
585 "TARGET_MIPS16 && TARGET_64BIT"
587 [(set_attr "type" "arith")
588 (set_attr "mode" "DI")
589 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
594 [(set (match_operand:DI 0 "register_operand" "=d")
596 (match_operand:DI 1 "small_int" "I")))]
597 "TARGET_MIPS16 && TARGET_64BIT"
599 [(set_attr "type" "arith")
600 (set_attr "mode" "DI")
601 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4")
606 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
607 (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
608 (match_operand:DI 2 "arith_operand" "Q,O,d")))]
609 "TARGET_MIPS16 && TARGET_64BIT"
611 if (REGNO (operands[0]) == REGNO (operands[1]))
612 return "daddu\t%0,%2";
614 return "daddu\t%0,%1,%2";
616 [(set_attr "type" "arith")
617 (set_attr "mode" "DI")
618 (set_attr_alternative "length"
619 [(if_then_else (match_operand:VOID 2 "m16_simm5_1")
622 (if_then_else (match_operand:VOID 2 "m16_simm4_1")
628 ;; On the mips16, we can sometimes split an add of a constant which is
629 ;; a 4 byte instruction into two adds which are both 2 byte
630 ;; instructions. There are two cases: one where we are adding a
631 ;; constant plus a register to another register, and one where we are
632 ;; simply adding a constant to a register.
635 [(set (match_operand:DI 0 "register_operand")
636 (plus:DI (match_dup 0)
637 (match_operand:DI 1 "const_int_operand")))]
638 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
639 && GET_CODE (operands[0]) == REG
640 && M16_REG_P (REGNO (operands[0]))
641 && GET_CODE (operands[1]) == CONST_INT
642 && ((INTVAL (operands[1]) > 0xf
643 && INTVAL (operands[1]) <= 0xf + 0xf)
644 || (INTVAL (operands[1]) < - 0x10
645 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
646 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
647 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
649 HOST_WIDE_INT val = INTVAL (operands[1]);
653 operands[1] = GEN_INT (0xf);
654 operands[2] = GEN_INT (val - 0xf);
658 operands[1] = GEN_INT (- 0x10);
659 operands[2] = GEN_INT (val + 0x10);
664 [(set (match_operand:DI 0 "register_operand")
665 (plus:DI (match_operand:DI 1 "register_operand")
666 (match_operand:DI 2 "const_int_operand")))]
667 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
668 && GET_CODE (operands[0]) == REG
669 && M16_REG_P (REGNO (operands[0]))
670 && GET_CODE (operands[1]) == REG
671 && M16_REG_P (REGNO (operands[1]))
672 && REGNO (operands[0]) != REGNO (operands[1])
673 && GET_CODE (operands[2]) == CONST_INT
674 && ((INTVAL (operands[2]) > 0x7
675 && INTVAL (operands[2]) <= 0x7 + 0xf)
676 || (INTVAL (operands[2]) < - 0x8
677 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
678 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
679 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
681 HOST_WIDE_INT val = INTVAL (operands[2]);
685 operands[2] = GEN_INT (0x7);
686 operands[3] = GEN_INT (val - 0x7);
690 operands[2] = GEN_INT (- 0x8);
691 operands[3] = GEN_INT (val + 0x8);
695 (define_insn "addsi3_internal_2"
696 [(set (match_operand:DI 0 "register_operand" "=d,d")
697 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
698 (match_operand:SI 2 "arith_operand" "d,Q"))))]
699 "TARGET_64BIT && !TARGET_MIPS16"
703 [(set_attr "type" "arith")
704 (set_attr "mode" "SI")])
707 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
708 (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
709 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
710 "TARGET_MIPS16 && TARGET_64BIT"
712 if (REGNO (operands[0]) == REGNO (operands[1]))
713 return "addu\t%0,%2";
715 return "addu\t%0,%1,%2";
717 [(set_attr "type" "arith")
718 (set_attr "mode" "SI")
719 (set_attr_alternative "length"
720 [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
723 (if_then_else (match_operand:VOID 2 "m16_simm4_1")
729 ;; ....................
733 ;; ....................
736 (define_insn "subdf3"
737 [(set (match_operand:DF 0 "register_operand" "=f")
738 (minus:DF (match_operand:DF 1 "register_operand" "f")
739 (match_operand:DF 2 "register_operand" "f")))]
740 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
742 [(set_attr "type" "fadd")
743 (set_attr "mode" "DF")])
745 (define_insn "subsf3"
746 [(set (match_operand:SF 0 "register_operand" "=f")
747 (minus:SF (match_operand:SF 1 "register_operand" "f")
748 (match_operand:SF 2 "register_operand" "f")))]
751 [(set_attr "type" "fadd")
752 (set_attr "mode" "SF")])
754 (define_expand "subsi3"
755 [(set (match_operand:SI 0 "register_operand")
756 (minus:SI (match_operand:SI 1 "register_operand")
757 (match_operand:SI 2 "register_operand")))]
761 (define_insn "subsi3_internal"
762 [(set (match_operand:SI 0 "register_operand" "=d")
763 (minus:SI (match_operand:SI 1 "register_operand" "d")
764 (match_operand:SI 2 "register_operand" "d")))]
767 [(set_attr "type" "arith")
768 (set_attr "mode" "SI")])
770 (define_insn "subdi3"
771 [(set (match_operand:DI 0 "register_operand" "=d")
772 (minus:DI (match_operand:DI 1 "register_operand" "d")
773 (match_operand:DI 2 "register_operand" "d")))]
776 [(set_attr "type" "arith")
777 (set_attr "mode" "DI")])
779 (define_insn "subsi3_internal_2"
780 [(set (match_operand:DI 0 "register_operand" "=d")
782 (minus:SI (match_operand:SI 1 "register_operand" "d")
783 (match_operand:SI 2 "register_operand" "d"))))]
786 [(set_attr "type" "arith")
787 (set_attr "mode" "DI")])
790 ;; ....................
794 ;; ....................
797 (define_expand "muldf3"
798 [(set (match_operand:DF 0 "register_operand")
799 (mult:DF (match_operand:DF 1 "register_operand")
800 (match_operand:DF 2 "register_operand")))]
801 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
804 (define_insn "muldf3_internal"
805 [(set (match_operand:DF 0 "register_operand" "=f")
806 (mult:DF (match_operand:DF 1 "register_operand" "f")
807 (match_operand:DF 2 "register_operand" "f")))]
808 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
810 [(set_attr "type" "fmul")
811 (set_attr "mode" "DF")])
813 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
814 ;; operands may corrupt immediately following multiplies. This is a
815 ;; simple fix to insert NOPs.
817 (define_insn "muldf3_r4300"
818 [(set (match_operand:DF 0 "register_operand" "=f")
819 (mult:DF (match_operand:DF 1 "register_operand" "f")
820 (match_operand:DF 2 "register_operand" "f")))]
821 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
822 "mul.d\t%0,%1,%2\;nop"
823 [(set_attr "type" "fmul")
824 (set_attr "mode" "DF")
825 (set_attr "length" "8")])
827 (define_expand "mulsf3"
828 [(set (match_operand:SF 0 "register_operand")
829 (mult:SF (match_operand:SF 1 "register_operand")
830 (match_operand:SF 2 "register_operand")))]
834 (define_insn "mulsf3_internal"
835 [(set (match_operand:SF 0 "register_operand" "=f")
836 (mult:SF (match_operand:SF 1 "register_operand" "f")
837 (match_operand:SF 2 "register_operand" "f")))]
838 "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
840 [(set_attr "type" "fmul")
841 (set_attr "mode" "SF")])
845 (define_insn "mulsf3_r4300"
846 [(set (match_operand:SF 0 "register_operand" "=f")
847 (mult:SF (match_operand:SF 1 "register_operand" "f")
848 (match_operand:SF 2 "register_operand" "f")))]
849 "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
850 "mul.s\t%0,%1,%2\;nop"
851 [(set_attr "type" "fmul")
852 (set_attr "mode" "SF")
853 (set_attr "length" "8")])
856 ;; The original R4000 has a cpu bug. If a double-word or a variable
857 ;; shift executes while an integer multiplication is in progress, the
858 ;; shift may give an incorrect result. Avoid this by keeping the mflo
859 ;; with the mult on the R4000.
861 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
862 ;; (also valid for MIPS R4000MC processors):
864 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
865 ;; this errata description.
866 ;; The following code sequence causes the R4000 to incorrectly
867 ;; execute the Double Shift Right Arithmetic 32 (dsra32)
868 ;; instruction. If the dsra32 instruction is executed during an
869 ;; integer multiply, the dsra32 will only shift by the amount in
870 ;; specified in the instruction rather than the amount plus 32
872 ;; instruction 1: mult rs,rt integer multiply
873 ;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
874 ;; right arithmetic + 32
875 ;; Workaround: A dsra32 instruction placed after an integer
876 ;; multiply should not be one of the 11 instructions after the
877 ;; multiply instruction."
881 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
882 ;; the following description.
883 ;; All extended shifts (shift by n+32) and variable shifts (32 and
884 ;; 64-bit versions) may produce incorrect results under the
885 ;; following conditions:
886 ;; 1) An integer multiply is currently executing
887 ;; 2) These types of shift instructions are executed immediately
888 ;; following an integer divide instruction.
890 ;; 1) Make sure no integer multiply is running wihen these
891 ;; instruction are executed. If this cannot be predicted at
892 ;; compile time, then insert a "mfhi" to R0 instruction
893 ;; immediately after the integer multiply instruction. This
894 ;; will cause the integer multiply to complete before the shift
896 ;; 2) Separate integer divide and these two classes of shift
897 ;; instructions by another instruction or a noop."
899 ;; These processors have PRId values of 0x00004220 and 0x00004300,
902 (define_expand "mulsi3"
903 [(set (match_operand:SI 0 "register_operand")
904 (mult:SI (match_operand:SI 1 "register_operand")
905 (match_operand:SI 2 "register_operand")))]
908 if (GENERATE_MULT3_SI || TARGET_MAD)
909 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
910 else if (!TARGET_FIX_R4000)
911 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
913 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
917 (define_insn "mulsi3_mult3"
918 [(set (match_operand:SI 0 "register_operand" "=d,l")
919 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
920 (match_operand:SI 2 "register_operand" "d,d")))
921 (clobber (match_scratch:SI 3 "=h,h"))
922 (clobber (match_scratch:SI 4 "=l,X"))]
926 if (which_alternative == 1)
927 return "mult\t%1,%2";
936 return "mul\t%0,%1,%2";
937 return "mult\t%0,%1,%2";
939 [(set_attr "type" "imul")
940 (set_attr "mode" "SI")])
942 ;; If a register gets allocated to LO, and we spill to memory, the reload
943 ;; will include a move from LO to a GPR. Merge it into the multiplication
944 ;; if it can set the GPR directly.
947 ;; Operand 1: GPR (1st multiplication operand)
948 ;; Operand 2: GPR (2nd multiplication operand)
950 ;; Operand 4: GPR (destination)
953 [(set (match_operand:SI 0 "register_operand")
954 (mult:SI (match_operand:SI 1 "register_operand")
955 (match_operand:SI 2 "register_operand")))
956 (clobber (match_operand:SI 3 "register_operand"))
957 (clobber (scratch:SI))])
958 (set (match_operand:SI 4 "register_operand")
959 (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
960 "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
963 (mult:SI (match_dup 1)
965 (clobber (match_dup 3))
966 (clobber (match_dup 0))])])
968 (define_insn "mulsi3_internal"
969 [(set (match_operand:SI 0 "register_operand" "=l")
970 (mult:SI (match_operand:SI 1 "register_operand" "d")
971 (match_operand:SI 2 "register_operand" "d")))
972 (clobber (match_scratch:SI 3 "=h"))]
975 [(set_attr "type" "imul")
976 (set_attr "mode" "SI")])
978 (define_insn "mulsi3_r4000"
979 [(set (match_operand:SI 0 "register_operand" "=d")
980 (mult:SI (match_operand:SI 1 "register_operand" "d")
981 (match_operand:SI 2 "register_operand" "d")))
982 (clobber (match_scratch:SI 3 "=h"))
983 (clobber (match_scratch:SI 4 "=l"))]
985 "mult\t%1,%2\;mflo\t%0"
986 [(set_attr "type" "imul")
987 (set_attr "mode" "SI")
988 (set_attr "length" "8")])
990 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
991 ;; of "mult; mflo". They have the same latency, but the first form gives
992 ;; us an extra cycle to compute the operands.
995 ;; Operand 1: GPR (1st multiplication operand)
996 ;; Operand 2: GPR (2nd multiplication operand)
998 ;; Operand 4: GPR (destination)
1001 [(set (match_operand:SI 0 "register_operand")
1002 (mult:SI (match_operand:SI 1 "register_operand")
1003 (match_operand:SI 2 "register_operand")))
1004 (clobber (match_operand:SI 3 "register_operand"))])
1005 (set (match_operand:SI 4 "register_operand")
1006 (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1007 "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1012 (plus:SI (mult:SI (match_dup 1)
1016 (plus:SI (mult:SI (match_dup 1)
1019 (clobber (match_dup 3))])])
1021 ;; Multiply-accumulate patterns
1023 ;; For processors that can copy the output to a general register:
1025 ;; The all-d alternative is needed because the combiner will find this
1026 ;; pattern and then register alloc/reload will move registers around to
1027 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1029 ;; The last alternative should be made slightly less desirable, but adding
1030 ;; "?" to the constraint is too strong, and causes values to be loaded into
1031 ;; LO even when that's more costly. For now, using "*d" mostly does the
1033 (define_insn "*mul_acc_si"
1034 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1035 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1036 (match_operand:SI 2 "register_operand" "d,d,d"))
1037 (match_operand:SI 3 "register_operand" "0,l,*d")))
1038 (clobber (match_scratch:SI 4 "=h,h,h"))
1039 (clobber (match_scratch:SI 5 "=X,3,l"))
1040 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1042 || ISA_HAS_MADD_MSUB)
1045 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1046 if (which_alternative == 2)
1048 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1050 return madd[which_alternative];
1052 [(set_attr "type" "imadd,imadd,multi")
1053 (set_attr "mode" "SI")
1054 (set_attr "length" "4,4,8")])
1056 ;; Split the above insn if we failed to get LO allocated.
1058 [(set (match_operand:SI 0 "register_operand")
1059 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1060 (match_operand:SI 2 "register_operand"))
1061 (match_operand:SI 3 "register_operand")))
1062 (clobber (match_scratch:SI 4))
1063 (clobber (match_scratch:SI 5))
1064 (clobber (match_scratch:SI 6))]
1065 "reload_completed && !TARGET_DEBUG_D_MODE
1066 && GP_REG_P (true_regnum (operands[0]))
1067 && GP_REG_P (true_regnum (operands[3]))"
1068 [(parallel [(set (match_dup 6)
1069 (mult:SI (match_dup 1) (match_dup 2)))
1070 (clobber (match_dup 4))
1071 (clobber (match_dup 5))])
1072 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1075 ;; Splitter to copy result of MADD to a general register
1077 [(set (match_operand:SI 0 "register_operand")
1078 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1079 (match_operand:SI 2 "register_operand"))
1080 (match_operand:SI 3 "register_operand")))
1081 (clobber (match_scratch:SI 4))
1082 (clobber (match_scratch:SI 5))
1083 (clobber (match_scratch:SI 6))]
1084 "reload_completed && !TARGET_DEBUG_D_MODE
1085 && GP_REG_P (true_regnum (operands[0]))
1086 && true_regnum (operands[3]) == LO_REGNUM"
1087 [(parallel [(set (match_dup 3)
1088 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1090 (clobber (match_dup 4))
1091 (clobber (match_dup 5))
1092 (clobber (match_dup 6))])
1093 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1096 (define_insn "*macc"
1097 [(set (match_operand:SI 0 "register_operand" "=l,d")
1098 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1099 (match_operand:SI 2 "register_operand" "d,d"))
1100 (match_operand:SI 3 "register_operand" "0,l")))
1101 (clobber (match_scratch:SI 4 "=h,h"))
1102 (clobber (match_scratch:SI 5 "=X,3"))]
1105 if (which_alternative == 1)
1106 return "macc\t%0,%1,%2";
1107 else if (TARGET_MIPS5500)
1108 return "madd\t%1,%2";
1110 /* The VR4130 assumes that there is a two-cycle latency between a macc
1111 that "writes" to $0 and an instruction that reads from it. We avoid
1112 this by assigning to $1 instead. */
1113 return "%[macc\t%@,%1,%2%]";
1115 [(set_attr "type" "imadd")
1116 (set_attr "mode" "SI")])
1118 (define_insn "*msac"
1119 [(set (match_operand:SI 0 "register_operand" "=l,d")
1120 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1121 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1122 (match_operand:SI 3 "register_operand" "d,d"))))
1123 (clobber (match_scratch:SI 4 "=h,h"))
1124 (clobber (match_scratch:SI 5 "=X,1"))]
1127 if (which_alternative == 1)
1128 return "msac\t%0,%2,%3";
1129 else if (TARGET_MIPS5500)
1130 return "msub\t%2,%3";
1132 return "msac\t$0,%2,%3";
1134 [(set_attr "type" "imadd")
1135 (set_attr "mode" "SI")])
1137 ;; An msac-like instruction implemented using negation and a macc.
1138 (define_insn_and_split "*msac_using_macc"
1139 [(set (match_operand:SI 0 "register_operand" "=l,d")
1140 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1141 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1142 (match_operand:SI 3 "register_operand" "d,d"))))
1143 (clobber (match_scratch:SI 4 "=h,h"))
1144 (clobber (match_scratch:SI 5 "=X,1"))
1145 (clobber (match_scratch:SI 6 "=d,d"))]
1146 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1148 "&& reload_completed"
1150 (neg:SI (match_dup 3)))
1153 (plus:SI (mult:SI (match_dup 2)
1156 (clobber (match_dup 4))
1157 (clobber (match_dup 5))])]
1159 [(set_attr "type" "imadd")
1160 (set_attr "length" "8")])
1162 ;; Patterns generated by the define_peephole2 below.
1164 (define_insn "*macc2"
1165 [(set (match_operand:SI 0 "register_operand" "=l")
1166 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1167 (match_operand:SI 2 "register_operand" "d"))
1169 (set (match_operand:SI 3 "register_operand" "=d")
1170 (plus:SI (mult:SI (match_dup 1)
1173 (clobber (match_scratch:SI 4 "=h"))]
1174 "ISA_HAS_MACC && reload_completed"
1176 [(set_attr "type" "imadd")
1177 (set_attr "mode" "SI")])
1179 (define_insn "*msac2"
1180 [(set (match_operand:SI 0 "register_operand" "=l")
1181 (minus:SI (match_dup 0)
1182 (mult:SI (match_operand:SI 1 "register_operand" "d")
1183 (match_operand:SI 2 "register_operand" "d"))))
1184 (set (match_operand:SI 3 "register_operand" "=d")
1185 (minus:SI (match_dup 0)
1186 (mult:SI (match_dup 1)
1188 (clobber (match_scratch:SI 4 "=h"))]
1189 "ISA_HAS_MSAC && reload_completed"
1191 [(set_attr "type" "imadd")
1192 (set_attr "mode" "SI")])
1194 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1198 ;; Operand 1: macc/msac
1200 ;; Operand 3: GPR (destination)
1203 [(set (match_operand:SI 0 "register_operand")
1204 (match_operand:SI 1 "macc_msac_operand"))
1205 (clobber (match_operand:SI 2 "register_operand"))
1206 (clobber (scratch:SI))])
1207 (set (match_operand:SI 3 "register_operand")
1208 (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1210 [(parallel [(set (match_dup 0)
1214 (clobber (match_dup 2))])]
1217 ;; When we have a three-address multiplication instruction, it should
1218 ;; be faster to do a separate multiply and add, rather than moving
1219 ;; something into LO in order to use a macc instruction.
1221 ;; This peephole needs a scratch register to cater for the case when one
1222 ;; of the multiplication operands is the same as the destination.
1224 ;; Operand 0: GPR (scratch)
1226 ;; Operand 2: GPR (addend)
1227 ;; Operand 3: GPR (destination)
1228 ;; Operand 4: macc/msac
1230 ;; Operand 6: new multiplication
1231 ;; Operand 7: new addition/subtraction
1233 [(match_scratch:SI 0 "d")
1234 (set (match_operand:SI 1 "register_operand")
1235 (match_operand:SI 2 "register_operand"))
1238 [(set (match_operand:SI 3 "register_operand")
1239 (match_operand:SI 4 "macc_msac_operand"))
1240 (clobber (match_operand:SI 5 "register_operand"))
1241 (clobber (match_dup 1))])]
1243 && true_regnum (operands[1]) == LO_REGNUM
1244 && peep2_reg_dead_p (2, operands[1])
1245 && GP_REG_P (true_regnum (operands[3]))"
1246 [(parallel [(set (match_dup 0)
1248 (clobber (match_dup 5))
1249 (clobber (match_dup 1))])
1253 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1254 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1255 operands[2], operands[0]);
1258 ;; Same as above, except LO is the initial target of the macc.
1260 ;; Operand 0: GPR (scratch)
1262 ;; Operand 2: GPR (addend)
1263 ;; Operand 3: macc/msac
1265 ;; Operand 5: GPR (destination)
1266 ;; Operand 6: new multiplication
1267 ;; Operand 7: new addition/subtraction
1269 [(match_scratch:SI 0 "d")
1270 (set (match_operand:SI 1 "register_operand")
1271 (match_operand:SI 2 "register_operand"))
1275 (match_operand:SI 3 "macc_msac_operand"))
1276 (clobber (match_operand:SI 4 "register_operand"))
1277 (clobber (scratch:SI))])
1279 (set (match_operand:SI 5 "register_operand")
1280 (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1281 "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1282 [(parallel [(set (match_dup 0)
1284 (clobber (match_dup 4))
1285 (clobber (match_dup 1))])
1289 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1290 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1291 operands[2], operands[0]);
1294 (define_insn "*mul_sub_si"
1295 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1296 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1297 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1298 (match_operand:SI 3 "register_operand" "d,d,d"))))
1299 (clobber (match_scratch:SI 4 "=h,h,h"))
1300 (clobber (match_scratch:SI 5 "=X,1,l"))
1301 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1307 [(set_attr "type" "imadd,multi,multi")
1308 (set_attr "mode" "SI")
1309 (set_attr "length" "4,8,8")])
1311 ;; Split the above insn if we failed to get LO allocated.
1313 [(set (match_operand:SI 0 "register_operand")
1314 (minus:SI (match_operand:SI 1 "register_operand")
1315 (mult:SI (match_operand:SI 2 "register_operand")
1316 (match_operand:SI 3 "register_operand"))))
1317 (clobber (match_scratch:SI 4))
1318 (clobber (match_scratch:SI 5))
1319 (clobber (match_scratch:SI 6))]
1320 "reload_completed && !TARGET_DEBUG_D_MODE
1321 && GP_REG_P (true_regnum (operands[0]))
1322 && GP_REG_P (true_regnum (operands[1]))"
1323 [(parallel [(set (match_dup 6)
1324 (mult:SI (match_dup 2) (match_dup 3)))
1325 (clobber (match_dup 4))
1326 (clobber (match_dup 5))])
1327 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1330 ;; Splitter to copy result of MSUB to a general register
1332 [(set (match_operand:SI 0 "register_operand")
1333 (minus:SI (match_operand:SI 1 "register_operand")
1334 (mult:SI (match_operand:SI 2 "register_operand")
1335 (match_operand:SI 3 "register_operand"))))
1336 (clobber (match_scratch:SI 4))
1337 (clobber (match_scratch:SI 5))
1338 (clobber (match_scratch:SI 6))]
1339 "reload_completed && !TARGET_DEBUG_D_MODE
1340 && GP_REG_P (true_regnum (operands[0]))
1341 && true_regnum (operands[1]) == LO_REGNUM"
1342 [(parallel [(set (match_dup 1)
1343 (minus:SI (match_dup 1)
1344 (mult:SI (match_dup 2) (match_dup 3))))
1345 (clobber (match_dup 4))
1346 (clobber (match_dup 5))
1347 (clobber (match_dup 6))])
1348 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1351 (define_insn "*muls"
1352 [(set (match_operand:SI 0 "register_operand" "=l,d")
1353 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1354 (match_operand:SI 2 "register_operand" "d,d"))))
1355 (clobber (match_scratch:SI 3 "=h,h"))
1356 (clobber (match_scratch:SI 4 "=X,l"))]
1361 [(set_attr "type" "imul")
1362 (set_attr "mode" "SI")])
1364 (define_expand "muldi3"
1365 [(set (match_operand:DI 0 "register_operand")
1366 (mult:DI (match_operand:DI 1 "register_operand")
1367 (match_operand:DI 2 "register_operand")))]
1370 if (GENERATE_MULT3_DI)
1371 emit_insn (gen_muldi3_mult3 (operands[0], operands[1], operands[2]));
1372 else if (!TARGET_FIX_R4000)
1373 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1375 emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
1379 (define_insn "muldi3_mult3"
1380 [(set (match_operand:DI 0 "register_operand" "=d")
1381 (mult:DI (match_operand:DI 1 "register_operand" "d")
1382 (match_operand:DI 2 "register_operand" "d")))
1383 (clobber (match_scratch:DI 3 "=h"))
1384 (clobber (match_scratch:DI 4 "=l"))]
1385 "TARGET_64BIT && GENERATE_MULT3_DI"
1387 [(set_attr "type" "imul")
1388 (set_attr "mode" "DI")])
1390 (define_insn "muldi3_internal"
1391 [(set (match_operand:DI 0 "register_operand" "=l")
1392 (mult:DI (match_operand:DI 1 "register_operand" "d")
1393 (match_operand:DI 2 "register_operand" "d")))
1394 (clobber (match_scratch:DI 3 "=h"))]
1395 "TARGET_64BIT && !TARGET_FIX_R4000"
1397 [(set_attr "type" "imul")
1398 (set_attr "mode" "DI")])
1400 (define_insn "muldi3_r4000"
1401 [(set (match_operand:DI 0 "register_operand" "=d")
1402 (mult:DI (match_operand:DI 1 "register_operand" "d")
1403 (match_operand:DI 2 "register_operand" "d")))
1404 (clobber (match_scratch:DI 3 "=h"))
1405 (clobber (match_scratch:DI 4 "=l"))]
1406 "TARGET_64BIT && TARGET_FIX_R4000"
1407 "dmult\t%1,%2\;mflo\t%0"
1408 [(set_attr "type" "imul")
1409 (set_attr "mode" "DI")
1410 (set_attr "length" "8")])
1412 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1414 (define_expand "mulsidi3"
1416 [(set (match_operand:DI 0 "register_operand")
1418 (sign_extend:DI (match_operand:SI 1 "register_operand"))
1419 (sign_extend:DI (match_operand:SI 2 "register_operand"))))
1420 (clobber (scratch:DI))
1421 (clobber (scratch:DI))
1422 (clobber (scratch:DI))])]
1423 "!TARGET_64BIT || !TARGET_FIX_R4000"
1427 if (!TARGET_FIX_R4000)
1428 emit_insn (gen_mulsidi3_32bit_internal (operands[0], operands[1],
1431 emit_insn (gen_mulsidi3_32bit_r4000 (operands[0], operands[1],
1437 (define_insn "mulsidi3_32bit_internal"
1438 [(set (match_operand:DI 0 "register_operand" "=x")
1440 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1441 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1442 "!TARGET_64BIT && !TARGET_FIX_R4000"
1444 [(set_attr "type" "imul")
1445 (set_attr "mode" "SI")])
1447 (define_insn "mulsidi3_32bit_r4000"
1448 [(set (match_operand:DI 0 "register_operand" "=d")
1450 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1451 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1452 (clobber (match_scratch:DI 3 "=x"))]
1453 "!TARGET_64BIT && TARGET_FIX_R4000"
1454 "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1455 [(set_attr "type" "imul")
1456 (set_attr "mode" "SI")
1457 (set_attr "length" "12")])
1459 (define_insn_and_split "*mulsidi3_64bit"
1460 [(set (match_operand:DI 0 "register_operand" "=d")
1461 (mult:DI (match_operator:DI 1 "extend_operator"
1462 [(match_operand:SI 3 "register_operand" "d")])
1463 (match_operator:DI 2 "extend_operator"
1464 [(match_operand:SI 4 "register_operand" "d")])))
1465 (clobber (match_scratch:DI 5 "=l"))
1466 (clobber (match_scratch:DI 6 "=h"))
1467 (clobber (match_scratch:DI 7 "=d"))]
1468 "TARGET_64BIT && !TARGET_FIX_R4000
1469 && GET_CODE (operands[1]) == GET_CODE (operands[2])"
1471 "&& reload_completed"
1475 (mult:SI (match_dup 3)
1479 (mult:DI (match_dup 1)
1483 ;; OP7 <- LO, OP0 <- HI
1484 (set (match_dup 7) (unspec:DI [(match_dup 5) (match_dup 6)] UNSPEC_MFHILO))
1485 (set (match_dup 0) (unspec:DI [(match_dup 6) (match_dup 5)] UNSPEC_MFHILO))
1489 (ashift:DI (match_dup 7)
1492 (lshiftrt:DI (match_dup 7)
1495 ;; Shift OP0 into place.
1497 (ashift:DI (match_dup 0)
1500 ;; OR the two halves together
1502 (ior:DI (match_dup 0)
1505 [(set_attr "type" "imul")
1506 (set_attr "mode" "SI")
1507 (set_attr "length" "24")])
1509 (define_insn "*mulsidi3_64bit_parts"
1510 [(set (match_operand:DI 0 "register_operand" "=l")
1512 (mult:SI (match_operand:SI 2 "register_operand" "d")
1513 (match_operand:SI 3 "register_operand" "d"))))
1514 (set (match_operand:DI 1 "register_operand" "=h")
1517 (match_operator:DI 4 "extend_operator" [(match_dup 2)])
1518 (match_operator:DI 5 "extend_operator" [(match_dup 3)]))
1520 "TARGET_64BIT && !TARGET_FIX_R4000
1521 && GET_CODE (operands[4]) == GET_CODE (operands[5])"
1523 if (GET_CODE (operands[4]) == SIGN_EXTEND)
1524 return "mult\t%2,%3";
1526 return "multu\t%2,%3";
1528 [(set_attr "type" "imul")
1529 (set_attr "mode" "SI")])
1531 (define_expand "umulsidi3"
1533 [(set (match_operand:DI 0 "register_operand")
1535 (zero_extend:DI (match_operand:SI 1 "register_operand"))
1536 (zero_extend:DI (match_operand:SI 2 "register_operand"))))
1537 (clobber (scratch:DI))
1538 (clobber (scratch:DI))
1539 (clobber (scratch:DI))])]
1540 "!TARGET_64BIT || !TARGET_FIX_R4000"
1544 if (!TARGET_FIX_R4000)
1545 emit_insn (gen_umulsidi3_32bit_internal (operands[0], operands[1],
1548 emit_insn (gen_umulsidi3_32bit_r4000 (operands[0], operands[1],
1554 (define_insn "umulsidi3_32bit_internal"
1555 [(set (match_operand:DI 0 "register_operand" "=x")
1557 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1558 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1559 "!TARGET_64BIT && !TARGET_FIX_R4000"
1561 [(set_attr "type" "imul")
1562 (set_attr "mode" "SI")])
1564 (define_insn "umulsidi3_32bit_r4000"
1565 [(set (match_operand:DI 0 "register_operand" "=d")
1567 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1568 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1569 (clobber (match_scratch:DI 3 "=x"))]
1570 "!TARGET_64BIT && TARGET_FIX_R4000"
1571 "multu\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1572 [(set_attr "type" "imul")
1573 (set_attr "mode" "SI")
1574 (set_attr "length" "12")])
1576 ;; Widening multiply with negation.
1577 (define_insn "*muls_di"
1578 [(set (match_operand:DI 0 "register_operand" "=x")
1581 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1582 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1583 "!TARGET_64BIT && ISA_HAS_MULS"
1585 [(set_attr "type" "imul")
1586 (set_attr "length" "4")
1587 (set_attr "mode" "SI")])
1589 (define_insn "*umuls_di"
1590 [(set (match_operand:DI 0 "register_operand" "=x")
1593 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1594 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1595 "!TARGET_64BIT && ISA_HAS_MULS"
1597 [(set_attr "type" "imul")
1598 (set_attr "length" "4")
1599 (set_attr "mode" "SI")])
1601 (define_insn "*smsac_di"
1602 [(set (match_operand:DI 0 "register_operand" "=x")
1604 (match_operand:DI 3 "register_operand" "0")
1606 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1607 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1608 "!TARGET_64BIT && ISA_HAS_MSAC"
1610 if (TARGET_MIPS5500)
1611 return "msub\t%1,%2";
1613 return "msac\t$0,%1,%2";
1615 [(set_attr "type" "imadd")
1616 (set_attr "length" "4")
1617 (set_attr "mode" "SI")])
1619 (define_insn "*umsac_di"
1620 [(set (match_operand:DI 0 "register_operand" "=x")
1622 (match_operand:DI 3 "register_operand" "0")
1624 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1625 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1626 "!TARGET_64BIT && ISA_HAS_MSAC"
1628 if (TARGET_MIPS5500)
1629 return "msubu\t%1,%2";
1631 return "msacu\t$0,%1,%2";
1633 [(set_attr "type" "imadd")
1634 (set_attr "length" "4")
1635 (set_attr "mode" "SI")])
1637 ;; _highpart patterns
1638 (define_expand "umulsi3_highpart"
1639 [(set (match_operand:SI 0 "register_operand")
1642 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"))
1643 (zero_extend:DI (match_operand:SI 2 "register_operand")))
1645 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1648 emit_insn (gen_umulsi3_highpart_mulhi_internal (operands[0], operands[1],
1651 emit_insn (gen_umulsi3_highpart_internal (operands[0], operands[1],
1656 (define_insn "umulsi3_highpart_internal"
1657 [(set (match_operand:SI 0 "register_operand" "=h")
1660 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1661 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1663 (clobber (match_scratch:SI 3 "=l"))]
1664 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1666 [(set_attr "type" "imul")
1667 (set_attr "mode" "SI")
1668 (set_attr "length" "4")])
1670 (define_insn "umulsi3_highpart_mulhi_internal"
1671 [(set (match_operand:SI 0 "register_operand" "=h,d")
1674 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1675 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1677 (clobber (match_scratch:SI 3 "=l,l"))
1678 (clobber (match_scratch:SI 4 "=X,h"))]
1683 [(set_attr "type" "imul")
1684 (set_attr "mode" "SI")
1685 (set_attr "length" "4")])
1687 (define_insn "umulsi3_highpart_neg_mulhi_internal"
1688 [(set (match_operand:SI 0 "register_operand" "=h,d")
1692 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1693 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1695 (clobber (match_scratch:SI 3 "=l,l"))
1696 (clobber (match_scratch:SI 4 "=X,h"))]
1701 [(set_attr "type" "imul")
1702 (set_attr "mode" "SI")
1703 (set_attr "length" "4")])
1705 (define_expand "smulsi3_highpart"
1706 [(set (match_operand:SI 0 "register_operand")
1709 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"))
1710 (sign_extend:DI (match_operand:SI 2 "register_operand")))
1712 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1715 emit_insn (gen_smulsi3_highpart_mulhi_internal (operands[0], operands[1],
1718 emit_insn (gen_smulsi3_highpart_internal (operands[0], operands[1],
1723 (define_insn "smulsi3_highpart_internal"
1724 [(set (match_operand:SI 0 "register_operand" "=h")
1727 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1728 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1730 (clobber (match_scratch:SI 3 "=l"))]
1731 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1733 [(set_attr "type" "imul")
1734 (set_attr "mode" "SI")
1735 (set_attr "length" "4")])
1737 (define_insn "smulsi3_highpart_mulhi_internal"
1738 [(set (match_operand:SI 0 "register_operand" "=h,d")
1741 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1742 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1744 (clobber (match_scratch:SI 3 "=l,l"))
1745 (clobber (match_scratch:SI 4 "=X,h"))]
1750 [(set_attr "type" "imul")
1751 (set_attr "mode" "SI")
1752 (set_attr "length" "4")])
1754 (define_insn "smulsi3_highpart_neg_mulhi_internal"
1755 [(set (match_operand:SI 0 "register_operand" "=h,d")
1759 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1760 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1762 (clobber (match_scratch:SI 3 "=l,l"))
1763 (clobber (match_scratch:SI 4 "=X,h"))]
1768 [(set_attr "type" "imul")
1769 (set_attr "mode" "SI")])
1771 (define_insn "smuldi3_highpart"
1772 [(set (match_operand:DI 0 "register_operand" "=h")
1776 (sign_extend:TI (match_operand:DI 1 "register_operand" "d"))
1777 (sign_extend:TI (match_operand:DI 2 "register_operand" "d")))
1779 (clobber (match_scratch:DI 3 "=l"))]
1780 "TARGET_64BIT && !TARGET_FIX_R4000"
1782 [(set_attr "type" "imul")
1783 (set_attr "mode" "DI")])
1785 ;; Disable this pattern for -mfix-vr4120. This is for VR4120 errata MD(0),
1786 ;; which says that dmultu does not always produce the correct result.
1787 (define_insn "umuldi3_highpart"
1788 [(set (match_operand:DI 0 "register_operand" "=h")
1792 (zero_extend:TI (match_operand:DI 1 "register_operand" "d"))
1793 (zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
1795 (clobber (match_scratch:DI 3 "=l"))]
1796 "TARGET_64BIT && !TARGET_FIX_R4000 && !TARGET_FIX_VR4120"
1798 [(set_attr "type" "imul")
1799 (set_attr "mode" "DI")])
1802 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1803 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
1805 (define_insn "madsi"
1806 [(set (match_operand:SI 0 "register_operand" "+l")
1807 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1808 (match_operand:SI 2 "register_operand" "d"))
1810 (clobber (match_scratch:SI 3 "=h"))]
1813 [(set_attr "type" "imadd")
1814 (set_attr "mode" "SI")])
1816 (define_insn "*umul_acc_di"
1817 [(set (match_operand:DI 0 "register_operand" "=x")
1819 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1820 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1821 (match_operand:DI 3 "register_operand" "0")))]
1822 "(TARGET_MAD || ISA_HAS_MACC)
1826 return "madu\t%1,%2";
1827 else if (TARGET_MIPS5500)
1828 return "maddu\t%1,%2";
1830 /* See comment in *macc. */
1831 return "%[maccu\t%@,%1,%2%]";
1833 [(set_attr "type" "imadd")
1834 (set_attr "mode" "SI")])
1837 (define_insn "*smul_acc_di"
1838 [(set (match_operand:DI 0 "register_operand" "=x")
1840 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1841 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1842 (match_operand:DI 3 "register_operand" "0")))]
1843 "(TARGET_MAD || ISA_HAS_MACC)
1847 return "mad\t%1,%2";
1848 else if (TARGET_MIPS5500)
1849 return "madd\t%1,%2";
1851 /* See comment in *macc. */
1852 return "%[macc\t%@,%1,%2%]";
1854 [(set_attr "type" "imadd")
1855 (set_attr "mode" "SI")])
1857 ;; Floating point multiply accumulate instructions.
1860 [(set (match_operand:DF 0 "register_operand" "=f")
1861 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1862 (match_operand:DF 2 "register_operand" "f"))
1863 (match_operand:DF 3 "register_operand" "f")))]
1864 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1865 "madd.d\t%0,%3,%1,%2"
1866 [(set_attr "type" "fmadd")
1867 (set_attr "mode" "DF")])
1870 [(set (match_operand:SF 0 "register_operand" "=f")
1871 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1872 (match_operand:SF 2 "register_operand" "f"))
1873 (match_operand:SF 3 "register_operand" "f")))]
1874 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1875 "madd.s\t%0,%3,%1,%2"
1876 [(set_attr "type" "fmadd")
1877 (set_attr "mode" "SF")])
1880 [(set (match_operand:DF 0 "register_operand" "=f")
1881 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1882 (match_operand:DF 2 "register_operand" "f"))
1883 (match_operand:DF 3 "register_operand" "f")))]
1884 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1885 "msub.d\t%0,%3,%1,%2"
1886 [(set_attr "type" "fmadd")
1887 (set_attr "mode" "DF")])
1890 [(set (match_operand:SF 0 "register_operand" "=f")
1891 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1892 (match_operand:SF 2 "register_operand" "f"))
1893 (match_operand:SF 3 "register_operand" "f")))]
1895 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1896 "msub.s\t%0,%3,%1,%2"
1897 [(set_attr "type" "fmadd")
1898 (set_attr "mode" "SF")])
1901 [(set (match_operand:DF 0 "register_operand" "=f")
1902 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1903 (match_operand:DF 2 "register_operand" "f"))
1904 (match_operand:DF 3 "register_operand" "f"))))]
1905 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1906 "nmadd.d\t%0,%3,%1,%2"
1907 [(set_attr "type" "fmadd")
1908 (set_attr "mode" "DF")])
1911 [(set (match_operand:SF 0 "register_operand" "=f")
1912 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1913 (match_operand:SF 2 "register_operand" "f"))
1914 (match_operand:SF 3 "register_operand" "f"))))]
1915 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1916 "nmadd.s\t%0,%3,%1,%2"
1917 [(set_attr "type" "fmadd")
1918 (set_attr "mode" "SF")])
1921 [(set (match_operand:DF 0 "register_operand" "=f")
1922 (minus:DF (match_operand:DF 1 "register_operand" "f")
1923 (mult:DF (match_operand:DF 2 "register_operand" "f")
1924 (match_operand:DF 3 "register_operand" "f"))))]
1925 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1926 "nmsub.d\t%0,%1,%2,%3"
1927 [(set_attr "type" "fmadd")
1928 (set_attr "mode" "DF")])
1931 [(set (match_operand:SF 0 "register_operand" "=f")
1932 (minus:SF (match_operand:SF 1 "register_operand" "f")
1933 (mult:SF (match_operand:SF 2 "register_operand" "f")
1934 (match_operand:SF 3 "register_operand" "f"))))]
1935 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1936 "nmsub.s\t%0,%1,%2,%3"
1937 [(set_attr "type" "fmadd")
1938 (set_attr "mode" "SF")])
1941 ;; ....................
1943 ;; DIVISION and REMAINDER
1945 ;; ....................
1948 (define_expand "divdf3"
1949 [(set (match_operand:DF 0 "register_operand")
1950 (div:DF (match_operand:DF 1 "reg_or_const_float_1_operand")
1951 (match_operand:DF 2 "register_operand")))]
1952 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1954 if (const_float_1_operand (operands[1], DFmode))
1955 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1956 operands[1] = force_reg (DFmode, operands[1]);
1959 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
1961 ;; If an mfc1 or dmfc1 happens to access the floating point register
1962 ;; file at the same time a long latency operation (div, sqrt, recip,
1963 ;; sqrt) iterates an intermediate result back through the floating
1964 ;; point register file bypass, then instead returning the correct
1965 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1966 ;; result of the long latency operation.
1968 ;; The workaround is to insert an unconditional 'mov' from/to the
1969 ;; long latency op destination register.
1971 (define_insn "*divdf3"
1972 [(set (match_operand:DF 0 "register_operand" "=f")
1973 (div:DF (match_operand:DF 1 "register_operand" "f")
1974 (match_operand:DF 2 "register_operand" "f")))]
1975 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1978 return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
1980 return "div.d\t%0,%1,%2";
1982 [(set_attr "type" "fdiv")
1983 (set_attr "mode" "DF")
1984 (set (attr "length")
1985 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1990 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
1992 ;; In certain cases, div.s and div.ps may have a rounding error
1993 ;; and/or wrong inexact flag.
1995 ;; Therefore, we only allow div.s if not working around SB-1 rev2
1996 ;; errata, or if working around those errata and a slight loss of
1997 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
1998 (define_expand "divsf3"
1999 [(set (match_operand:SF 0 "register_operand")
2000 (div:SF (match_operand:SF 1 "reg_or_const_float_1_operand")
2001 (match_operand:SF 2 "register_operand")))]
2002 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2004 if (const_float_1_operand (operands[1], SFmode))
2005 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2006 operands[1] = force_reg (SFmode, operands[1]);
2009 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2010 ;; "divdf3" comment for details).
2012 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
2013 ;; "divsf3" comment for details).
2014 (define_insn "*divsf3"
2015 [(set (match_operand:SF 0 "register_operand" "=f")
2016 (div:SF (match_operand:SF 1 "register_operand" "f")
2017 (match_operand:SF 2 "register_operand" "f")))]
2018 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2021 return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
2023 return "div.s\t%0,%1,%2";
2025 [(set_attr "type" "fdiv")
2026 (set_attr "mode" "SF")
2027 (set (attr "length")
2028 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2032 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2033 ;; "divdf3" comment for details).
2035 [(set (match_operand:DF 0 "register_operand" "=f")
2036 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2037 (match_operand:DF 2 "register_operand" "f")))]
2038 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2041 return "recip.d\t%0,%2\;mov.d\t%0,%0";
2043 return "recip.d\t%0,%2";
2045 [(set_attr "type" "fdiv")
2046 (set_attr "mode" "DF")
2047 (set (attr "length")
2048 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2052 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2053 ;; "divdf3" comment for details).
2055 [(set (match_operand:SF 0 "register_operand" "=f")
2056 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2057 (match_operand:SF 2 "register_operand" "f")))]
2058 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2061 return "recip.s\t%0,%2\;mov.s\t%0,%0";
2063 return "recip.s\t%0,%2";
2065 [(set_attr "type" "fdiv")
2066 (set_attr "mode" "SF")
2067 (set (attr "length")
2068 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2072 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2073 ;; with negative operands. We use special libgcc functions instead.
2074 (define_insn "divmodsi4"
2075 [(set (match_operand:SI 0 "register_operand" "=l")
2076 (div:SI (match_operand:SI 1 "register_operand" "d")
2077 (match_operand:SI 2 "register_operand" "d")))
2078 (set (match_operand:SI 3 "register_operand" "=h")
2079 (mod:SI (match_dup 1)
2081 "!TARGET_FIX_VR4120"
2082 { return mips_output_division ("div\t$0,%1,%2", operands); }
2083 [(set_attr "type" "idiv")
2084 (set_attr "mode" "SI")])
2086 (define_insn "divmoddi4"
2087 [(set (match_operand:DI 0 "register_operand" "=l")
2088 (div:DI (match_operand:DI 1 "register_operand" "d")
2089 (match_operand:DI 2 "register_operand" "d")))
2090 (set (match_operand:DI 3 "register_operand" "=h")
2091 (mod:DI (match_dup 1)
2093 "TARGET_64BIT && !TARGET_FIX_VR4120"
2094 { return mips_output_division ("ddiv\t$0,%1,%2", operands); }
2095 [(set_attr "type" "idiv")
2096 (set_attr "mode" "DI")])
2098 (define_insn "udivmodsi4"
2099 [(set (match_operand:SI 0 "register_operand" "=l")
2100 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2101 (match_operand:SI 2 "register_operand" "d")))
2102 (set (match_operand:SI 3 "register_operand" "=h")
2103 (umod:SI (match_dup 1)
2106 { return mips_output_division ("divu\t$0,%1,%2", operands); }
2107 [(set_attr "type" "idiv")
2108 (set_attr "mode" "SI")])
2110 (define_insn "udivmoddi4"
2111 [(set (match_operand:DI 0 "register_operand" "=l")
2112 (udiv:DI (match_operand:DI 1 "register_operand" "d")
2113 (match_operand:DI 2 "register_operand" "d")))
2114 (set (match_operand:DI 3 "register_operand" "=h")
2115 (umod:DI (match_dup 1)
2118 { return mips_output_division ("ddivu\t$0,%1,%2", operands); }
2119 [(set_attr "type" "idiv")
2120 (set_attr "mode" "DI")])
2123 ;; ....................
2127 ;; ....................
2129 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2130 ;; "divdf3" comment for details).
2131 (define_insn "sqrtdf2"
2132 [(set (match_operand:DF 0 "register_operand" "=f")
2133 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2134 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2137 return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
2139 return "sqrt.d\t%0,%1";
2141 [(set_attr "type" "fsqrt")
2142 (set_attr "mode" "DF")
2143 (set (attr "length")
2144 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2148 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2149 ;; "divdf3" comment for details).
2150 (define_insn "sqrtsf2"
2151 [(set (match_operand:SF 0 "register_operand" "=f")
2152 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2153 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2156 return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
2158 return "sqrt.s\t%0,%1";
2160 [(set_attr "type" "fsqrt")
2161 (set_attr "mode" "SF")
2162 (set (attr "length")
2163 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2167 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2168 ;; "divdf3" comment for details).
2170 [(set (match_operand:DF 0 "register_operand" "=f")
2171 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2172 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2173 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2176 return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2178 return "rsqrt.d\t%0,%2";
2180 [(set_attr "type" "frsqrt")
2181 (set_attr "mode" "DF")
2182 (set (attr "length")
2183 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2187 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2188 ;; "divdf3" comment for details).
2190 [(set (match_operand:SF 0 "register_operand" "=f")
2191 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2192 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2193 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2196 return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2198 return "rsqrt.s\t%0,%2";
2200 [(set_attr "type" "frsqrt")
2201 (set_attr "mode" "SF")
2202 (set (attr "length")
2203 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2208 ;; ....................
2212 ;; ....................
2214 ;; Do not use the integer abs macro instruction, since that signals an
2215 ;; exception on -2147483648 (sigh).
2217 (define_insn "abssi2"
2218 [(set (match_operand:SI 0 "register_operand" "=d")
2219 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2222 operands[2] = const0_rtx;
2224 if (REGNO (operands[0]) == REGNO (operands[1]))
2226 if (GENERATE_BRANCHLIKELY)
2227 return "%(bltzl\t%1,1f\;subu\t%0,%z2,%0\n%~1:%)";
2229 return "bgez\t%1,1f%#\;subu\t%0,%z2,%0\n%~1:";
2232 return "%(bgez\t%1,1f\;move\t%0,%1\;subu\t%0,%z2,%0\n%~1:%)";
2234 [(set_attr "type" "multi")
2235 (set_attr "mode" "SI")
2236 (set_attr "length" "12")])
2238 (define_insn "absdi2"
2239 [(set (match_operand:DI 0 "register_operand" "=d")
2240 (abs:DI (match_operand:DI 1 "register_operand" "d")))]
2241 "TARGET_64BIT && !TARGET_MIPS16"
2243 unsigned int regno1;
2244 operands[2] = const0_rtx;
2246 if (GET_CODE (operands[1]) == REG)
2247 regno1 = REGNO (operands[1]);
2249 regno1 = REGNO (XEXP (operands[1], 0));
2251 if (REGNO (operands[0]) == regno1)
2252 return "%(bltzl\t%1,1f\;dsubu\t%0,%z2,%0\n%~1:%)";
2254 return "%(bgez\t%1,1f\;move\t%0,%1\;dsubu\t%0,%z2,%0\n%~1:%)";
2256 [(set_attr "type" "multi")
2257 (set_attr "mode" "DI")
2258 (set_attr "length" "12")])
2260 (define_insn "absdf2"
2261 [(set (match_operand:DF 0 "register_operand" "=f")
2262 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2263 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2265 [(set_attr "type" "fabs")
2266 (set_attr "mode" "DF")])
2268 (define_insn "abssf2"
2269 [(set (match_operand:SF 0 "register_operand" "=f")
2270 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2273 [(set_attr "type" "fabs")
2274 (set_attr "mode" "SF")])
2277 ;; ....................
2279 ;; FIND FIRST BIT INSTRUCTION
2281 ;; ....................
2284 (define_insn "ffssi2"
2285 [(set (match_operand:SI 0 "register_operand" "=&d")
2286 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2287 (clobber (match_scratch:SI 2 "=&d"))
2288 (clobber (match_scratch:SI 3 "=&d"))]
2291 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2295 %~1:\tand\t%2,%1,0x0001\;\
2305 %~1:\tand\t%2,%3,0x0001\;\
2311 [(set_attr "type" "multi")
2312 (set_attr "mode" "SI")
2313 (set_attr "length" "28")])
2315 (define_insn "ffsdi2"
2316 [(set (match_operand:DI 0 "register_operand" "=&d")
2317 (ffs:DI (match_operand:DI 1 "register_operand" "d")))
2318 (clobber (match_scratch:DI 2 "=&d"))
2319 (clobber (match_scratch:DI 3 "=&d"))]
2320 "TARGET_64BIT && !TARGET_MIPS16"
2322 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2326 %~1:\tand\t%2,%1,0x0001\;\
2336 %~1:\tand\t%2,%3,0x0001\;\
2342 [(set_attr "type" "multi")
2343 (set_attr "mode" "DI")
2344 (set_attr "length" "28")])
2347 ;; ...................
2349 ;; Count leading zeroes.
2351 ;; ...................
2354 (define_insn "clzsi2"
2355 [(set (match_operand:SI 0 "register_operand" "=d")
2356 (clz:SI (match_operand:SI 1 "register_operand" "d")))]
2359 [(set_attr "type" "clz")
2360 (set_attr "mode" "SI")])
2362 (define_insn "clzdi2"
2363 [(set (match_operand:DI 0 "register_operand" "=d")
2364 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
2367 [(set_attr "type" "clz")
2368 (set_attr "mode" "DI")])
2371 ;; ....................
2373 ;; NEGATION and ONE'S COMPLEMENT
2375 ;; ....................
2377 (define_insn "negsi2"
2378 [(set (match_operand:SI 0 "register_operand" "=d")
2379 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2383 return "neg\t%0,%1";
2385 return "subu\t%0,%.,%1";
2387 [(set_attr "type" "arith")
2388 (set_attr "mode" "SI")])
2390 (define_insn "negdi2"
2391 [(set (match_operand:DI 0 "register_operand" "=d")
2392 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2393 "TARGET_64BIT && !TARGET_MIPS16"
2395 [(set_attr "type" "arith")
2396 (set_attr "mode" "DI")])
2398 (define_insn "negdf2"
2399 [(set (match_operand:DF 0 "register_operand" "=f")
2400 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2401 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2403 [(set_attr "type" "fneg")
2404 (set_attr "mode" "DF")])
2406 (define_insn "negsf2"
2407 [(set (match_operand:SF 0 "register_operand" "=f")
2408 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2411 [(set_attr "type" "fneg")
2412 (set_attr "mode" "SF")])
2414 (define_insn "one_cmplsi2"
2415 [(set (match_operand:SI 0 "register_operand" "=d")
2416 (not:SI (match_operand:SI 1 "register_operand" "d")))]
2420 return "not\t%0,%1";
2422 return "nor\t%0,%.,%1";
2424 [(set_attr "type" "arith")
2425 (set_attr "mode" "SI")])
2427 (define_insn "one_cmpldi2"
2428 [(set (match_operand:DI 0 "register_operand" "=d")
2429 (not:DI (match_operand:DI 1 "register_operand" "d")))]
2433 return "not\t%0,%1";
2435 return "nor\t%0,%.,%1";
2437 [(set_attr "type" "arith")
2438 (set_attr "mode" "DI")])
2441 ;; ....................
2445 ;; ....................
2448 ;; Many of these instructions use trivial define_expands, because we
2449 ;; want to use a different set of constraints when TARGET_MIPS16.
2451 (define_expand "andsi3"
2452 [(set (match_operand:SI 0 "register_operand")
2453 (and:SI (match_operand:SI 1 "uns_arith_operand")
2454 (match_operand:SI 2 "uns_arith_operand")))]
2459 operands[1] = force_reg (SImode, operands[1]);
2460 operands[2] = force_reg (SImode, operands[2]);
2465 [(set (match_operand:SI 0 "register_operand" "=d,d")
2466 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2467 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2472 [(set_attr "type" "arith")
2473 (set_attr "mode" "SI")])
2476 [(set (match_operand:SI 0 "register_operand" "=d")
2477 (and:SI (match_operand:SI 1 "register_operand" "%0")
2478 (match_operand:SI 2 "register_operand" "d")))]
2481 [(set_attr "type" "arith")
2482 (set_attr "mode" "SI")])
2484 (define_expand "anddi3"
2485 [(set (match_operand:DI 0 "register_operand")
2486 (and:DI (match_operand:DI 1 "register_operand")
2487 (match_operand:DI 2 "uns_arith_operand")))]
2492 operands[1] = force_reg (DImode, operands[1]);
2493 operands[2] = force_reg (DImode, operands[2]);
2498 [(set (match_operand:DI 0 "register_operand" "=d,d")
2499 (and:DI (match_operand:DI 1 "register_operand" "d,d")
2500 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2501 "TARGET_64BIT && !TARGET_MIPS16"
2505 [(set_attr "type" "arith")
2506 (set_attr "mode" "DI")])
2509 [(set (match_operand:DI 0 "register_operand" "=d")
2510 (and:DI (match_operand:DI 1 "register_operand" "0")
2511 (match_operand:DI 2 "register_operand" "d")))]
2512 "TARGET_64BIT && TARGET_MIPS16"
2514 [(set_attr "type" "arith")
2515 (set_attr "mode" "DI")])
2517 (define_expand "iorsi3"
2518 [(set (match_operand:SI 0 "register_operand")
2519 (ior:SI (match_operand:SI 1 "uns_arith_operand")
2520 (match_operand:SI 2 "uns_arith_operand")))]
2525 operands[1] = force_reg (SImode, operands[1]);
2526 operands[2] = force_reg (SImode, operands[2]);
2531 [(set (match_operand:SI 0 "register_operand" "=d,d")
2532 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2533 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2538 [(set_attr "type" "arith")
2539 (set_attr "mode" "SI")])
2542 [(set (match_operand:SI 0 "register_operand" "=d")
2543 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2544 (match_operand:SI 2 "register_operand" "d")))]
2547 [(set_attr "type" "arith")
2548 (set_attr "mode" "SI")])
2550 (define_expand "iordi3"
2551 [(set (match_operand:DI 0 "register_operand")
2552 (ior:DI (match_operand:DI 1 "register_operand")
2553 (match_operand:DI 2 "uns_arith_operand")))]
2558 operands[1] = force_reg (DImode, operands[1]);
2559 operands[2] = force_reg (DImode, operands[2]);
2564 [(set (match_operand:DI 0 "register_operand" "=d,d")
2565 (ior:DI (match_operand:DI 1 "register_operand" "d,d")
2566 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2567 "TARGET_64BIT && !TARGET_MIPS16"
2571 [(set_attr "type" "arith")
2572 (set_attr "mode" "DI")])
2575 [(set (match_operand:DI 0 "register_operand" "=d")
2576 (ior:DI (match_operand:DI 1 "register_operand" "0")
2577 (match_operand:DI 2 "register_operand" "d")))]
2578 "TARGET_64BIT && TARGET_MIPS16"
2580 [(set_attr "type" "arith")
2581 (set_attr "mode" "DI")])
2583 (define_expand "xorsi3"
2584 [(set (match_operand:SI 0 "register_operand")
2585 (xor:SI (match_operand:SI 1 "uns_arith_operand")
2586 (match_operand:SI 2 "uns_arith_operand")))]
2591 [(set (match_operand:SI 0 "register_operand" "=d,d")
2592 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2593 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2598 [(set_attr "type" "arith")
2599 (set_attr "mode" "SI")])
2602 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
2603 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
2604 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
2610 [(set_attr "type" "arith")
2611 (set_attr "mode" "SI")
2612 (set_attr_alternative "length"
2614 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2619 (define_expand "xordi3"
2620 [(set (match_operand:DI 0 "register_operand")
2621 (xor:DI (match_operand:DI 1 "register_operand")
2622 (match_operand:DI 2 "uns_arith_operand")))]
2627 operands[1] = force_reg (DImode, operands[1]);
2628 operands[2] = force_reg (DImode, operands[2]);
2633 [(set (match_operand:DI 0 "register_operand" "=d,d")
2634 (xor:DI (match_operand:DI 1 "register_operand" "d,d")
2635 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2636 "TARGET_64BIT && !TARGET_MIPS16"
2640 [(set_attr "type" "arith")
2641 (set_attr "mode" "DI")])
2644 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
2645 (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
2646 (match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
2647 "TARGET_64BIT && TARGET_MIPS16"
2652 [(set_attr "type" "arith")
2653 (set_attr "mode" "DI")
2654 (set_attr_alternative "length"
2656 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2661 (define_insn "*norsi3"
2662 [(set (match_operand:SI 0 "register_operand" "=d")
2663 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
2664 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
2667 [(set_attr "type" "arith")
2668 (set_attr "mode" "SI")])
2670 (define_insn "*nordi3"
2671 [(set (match_operand:DI 0 "register_operand" "=d")
2672 (and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
2673 (not:DI (match_operand:DI 2 "register_operand" "d"))))]
2674 "TARGET_64BIT && !TARGET_MIPS16"
2676 [(set_attr "type" "arith")
2677 (set_attr "mode" "DI")])
2680 ;; ....................
2684 ;; ....................
2688 (define_insn "truncdfsf2"
2689 [(set (match_operand:SF 0 "register_operand" "=f")
2690 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2691 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2693 [(set_attr "type" "fcvt")
2694 (set_attr "mode" "SF")])
2696 ;; Integer truncation patterns. Truncating SImode values to smaller
2697 ;; modes is a no-op, as it is for most other GCC ports. Truncating
2698 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2699 ;; need to make sure that the lower 32 bits are properly sign-extended
2700 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
2701 ;; smaller than SImode is equivalent to two separate truncations:
2704 ;; DI ---> HI == DI ---> SI ---> HI
2705 ;; DI ---> QI == DI ---> SI ---> QI
2707 ;; Step A needs a real instruction but step B does not.
2709 (define_insn "truncdisi2"
2710 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2711 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2716 [(set_attr "type" "shift,store")
2717 (set_attr "mode" "SI")
2718 (set_attr "extended_mips16" "yes,*")])
2720 (define_insn "truncdihi2"
2721 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2722 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2727 [(set_attr "type" "shift,store")
2728 (set_attr "mode" "SI")
2729 (set_attr "extended_mips16" "yes,*")])
2731 (define_insn "truncdiqi2"
2732 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2733 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2738 [(set_attr "type" "shift,store")
2739 (set_attr "mode" "SI")
2740 (set_attr "extended_mips16" "yes,*")])
2742 ;; Combiner patterns to optimize shift/truncate combinations.
2745 [(set (match_operand:SI 0 "register_operand" "=d")
2746 (truncate:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2747 (match_operand:DI 2 "small_int" "I"))))]
2748 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2750 [(set_attr "type" "shift")
2751 (set_attr "mode" "SI")])
2754 [(set (match_operand:SI 0 "register_operand" "=d")
2755 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2757 "TARGET_64BIT && !TARGET_MIPS16"
2759 [(set_attr "type" "shift")
2760 (set_attr "mode" "SI")])
2763 ;; Combiner patterns for truncate/sign_extend combinations. They use
2764 ;; the shift/truncate patterns above.
2766 (define_insn_and_split ""
2767 [(set (match_operand:SI 0 "register_operand" "=d")
2769 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2770 "TARGET_64BIT && !TARGET_MIPS16"
2772 "&& reload_completed"
2774 (ashift:DI (match_dup 1)
2777 (truncate:SI (ashiftrt:DI (match_dup 2)
2779 { operands[2] = gen_lowpart (DImode, operands[0]); })
2781 (define_insn_and_split ""
2782 [(set (match_operand:SI 0 "register_operand" "=d")
2784 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2785 "TARGET_64BIT && !TARGET_MIPS16"
2787 "&& reload_completed"
2789 (ashift:DI (match_dup 1)
2792 (truncate:SI (ashiftrt:DI (match_dup 2)
2794 { operands[2] = gen_lowpart (DImode, operands[0]); })
2797 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2800 [(set (match_operand:SI 0 "register_operand" "=d")
2801 (zero_extend:SI (truncate:HI
2802 (match_operand:DI 1 "register_operand" "d"))))]
2803 "TARGET_64BIT && !TARGET_MIPS16"
2804 "andi\t%0,%1,0xffff"
2805 [(set_attr "type" "arith")
2806 (set_attr "mode" "SI")])
2809 [(set (match_operand:SI 0 "register_operand" "=d")
2810 (zero_extend:SI (truncate:QI
2811 (match_operand:DI 1 "register_operand" "d"))))]
2812 "TARGET_64BIT && !TARGET_MIPS16"
2814 [(set_attr "type" "arith")
2815 (set_attr "mode" "SI")])
2818 [(set (match_operand:HI 0 "register_operand" "=d")
2819 (zero_extend:HI (truncate:QI
2820 (match_operand:DI 1 "register_operand" "d"))))]
2821 "TARGET_64BIT && !TARGET_MIPS16"
2823 [(set_attr "type" "arith")
2824 (set_attr "mode" "HI")])
2827 ;; ....................
2831 ;; ....................
2834 ;; Those for integer source operand are ordered widest source type first.
2836 (define_insn_and_split "zero_extendsidi2"
2837 [(set (match_operand:DI 0 "register_operand" "=d")
2838 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2841 "&& reload_completed"
2843 (ashift:DI (match_dup 1) (const_int 32)))
2845 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2846 "operands[1] = gen_lowpart (DImode, operands[1]);"
2847 [(set_attr "type" "multi")
2848 (set_attr "mode" "DI")
2849 (set_attr "length" "8")])
2851 (define_insn "*zero_extendsidi2_mem"
2852 [(set (match_operand:DI 0 "register_operand" "=d")
2853 (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2856 [(set_attr "type" "load")
2857 (set_attr "mode" "DI")])
2859 (define_expand "zero_extendhisi2"
2860 [(set (match_operand:SI 0 "register_operand")
2861 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2864 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2866 rtx op = gen_lowpart (SImode, operands[1]);
2867 rtx temp = force_reg (SImode, GEN_INT (0xffff));
2869 emit_insn (gen_andsi3 (operands[0], op, temp));
2875 [(set (match_operand:SI 0 "register_operand" "=d,d")
2876 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2881 [(set_attr "type" "arith,load")
2882 (set_attr "mode" "SI")
2883 (set_attr "length" "4,*")])
2886 [(set (match_operand:SI 0 "register_operand" "=d")
2887 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2890 [(set_attr "type" "load")
2891 (set_attr "mode" "SI")])
2893 (define_expand "zero_extendhidi2"
2894 [(set (match_operand:DI 0 "register_operand")
2895 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2898 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2900 rtx op = gen_lowpart (DImode, operands[1]);
2901 rtx temp = force_reg (DImode, GEN_INT (0xffff));
2903 emit_insn (gen_anddi3 (operands[0], op, temp));
2909 [(set (match_operand:DI 0 "register_operand" "=d,d")
2910 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2911 "TARGET_64BIT && !TARGET_MIPS16"
2915 [(set_attr "type" "arith,load")
2916 (set_attr "mode" "DI")
2917 (set_attr "length" "4,*")])
2920 [(set (match_operand:DI 0 "register_operand" "=d")
2921 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2922 "TARGET_64BIT && TARGET_MIPS16"
2924 [(set_attr "type" "load")
2925 (set_attr "mode" "DI")])
2927 (define_expand "zero_extendqihi2"
2928 [(set (match_operand:HI 0 "register_operand")
2929 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2932 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2934 rtx op0 = gen_lowpart (SImode, operands[0]);
2935 rtx op1 = gen_lowpart (SImode, operands[1]);
2936 rtx temp = force_reg (SImode, GEN_INT (0xff));
2938 emit_insn (gen_andsi3 (op0, op1, temp));
2944 [(set (match_operand:HI 0 "register_operand" "=d,d")
2945 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2950 [(set_attr "type" "arith,load")
2951 (set_attr "mode" "HI")
2952 (set_attr "length" "4,*")])
2955 [(set (match_operand:HI 0 "register_operand" "=d")
2956 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2959 [(set_attr "type" "load")
2960 (set_attr "mode" "HI")])
2962 (define_expand "zero_extendqisi2"
2963 [(set (match_operand:SI 0 "register_operand")
2964 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2967 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2969 rtx op = gen_lowpart (SImode, operands[1]);
2970 rtx temp = force_reg (SImode, GEN_INT (0xff));
2972 emit_insn (gen_andsi3 (operands[0], op, temp));
2978 [(set (match_operand:SI 0 "register_operand" "=d,d")
2979 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2984 [(set_attr "type" "arith,load")
2985 (set_attr "mode" "SI")
2986 (set_attr "length" "4,*")])
2989 [(set (match_operand:SI 0 "register_operand" "=d")
2990 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2993 [(set_attr "type" "load")
2994 (set_attr "mode" "SI")])
2996 (define_expand "zero_extendqidi2"
2997 [(set (match_operand:DI 0 "register_operand")
2998 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3001 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3003 rtx op = gen_lowpart (DImode, operands[1]);
3004 rtx temp = force_reg (DImode, GEN_INT (0xff));
3006 emit_insn (gen_anddi3 (operands[0], op, temp));
3012 [(set (match_operand:DI 0 "register_operand" "=d,d")
3013 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3014 "TARGET_64BIT && !TARGET_MIPS16"
3018 [(set_attr "type" "arith,load")
3019 (set_attr "mode" "DI")
3020 (set_attr "length" "4,*")])
3023 [(set (match_operand:DI 0 "register_operand" "=d")
3024 (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3025 "TARGET_64BIT && TARGET_MIPS16"
3027 [(set_attr "type" "load")
3028 (set_attr "mode" "DI")])
3031 ;; ....................
3035 ;; ....................
3038 ;; Those for integer source operand are ordered widest source type first.
3040 ;; When TARGET_64BIT, all SImode integer registers should already be in
3041 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
3042 ;; therefore get rid of register->register instructions if we constrain
3043 ;; the source to be in the same register as the destination.
3045 ;; The register alternative has type "arith" so that the pre-reload
3046 ;; scheduler will treat it as a move. This reflects what happens if
3047 ;; the register alternative needs a reload.
3048 (define_insn_and_split "extendsidi2"
3049 [(set (match_operand:DI 0 "register_operand" "=d,d")
3050 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
3055 "&& reload_completed && register_operand (operands[1], VOIDmode)"
3058 emit_note (NOTE_INSN_DELETED);
3061 [(set_attr "type" "arith,load")
3062 (set_attr "mode" "DI")])
3064 ;; These patterns originally accepted general_operands, however, slightly
3065 ;; better code is generated by only accepting register_operands, and then
3066 ;; letting combine generate the lh and lb insns.
3068 ;; These expanders originally put values in registers first. We split
3069 ;; all non-mem patterns after reload.
3071 (define_expand "extendhidi2"
3072 [(set (match_operand:DI 0 "register_operand")
3073 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
3077 (define_insn "*extendhidi2"
3078 [(set (match_operand:DI 0 "register_operand" "=d")
3079 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
3084 [(set (match_operand:DI 0 "register_operand")
3085 (sign_extend:DI (match_operand:HI 1 "register_operand")))]
3086 "TARGET_64BIT && reload_completed"
3088 (ashift:DI (match_dup 1) (const_int 48)))
3090 (ashiftrt:DI (match_dup 0) (const_int 48)))]
3091 "operands[1] = gen_lowpart (DImode, operands[1]);")
3093 (define_insn "*extendhidi2_mem"
3094 [(set (match_operand:DI 0 "register_operand" "=d")
3095 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3098 [(set_attr "type" "load")
3099 (set_attr "mode" "DI")])
3101 (define_expand "extendhisi2"
3102 [(set (match_operand:SI 0 "register_operand")
3103 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
3106 if (ISA_HAS_SEB_SEH)
3108 emit_insn (gen_extendhisi2_hw (operands[0],
3109 force_reg (HImode, operands[1])));
3114 (define_insn "*extendhisi2"
3115 [(set (match_operand:SI 0 "register_operand" "=d")
3116 (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
3121 [(set (match_operand:SI 0 "register_operand")
3122 (sign_extend:SI (match_operand:HI 1 "register_operand")))]
3125 (ashift:SI (match_dup 1) (const_int 16)))
3127 (ashiftrt:SI (match_dup 0) (const_int 16)))]
3128 "operands[1] = gen_lowpart (SImode, operands[1]);")
3130 (define_insn "extendhisi2_mem"
3131 [(set (match_operand:SI 0 "register_operand" "=d")
3132 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3135 [(set_attr "type" "load")
3136 (set_attr "mode" "SI")])
3138 (define_insn "extendhisi2_hw"
3139 [(set (match_operand:SI 0 "register_operand" "=r")
3140 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
3143 [(set_attr "type" "arith")
3144 (set_attr "mode" "SI")])
3146 (define_expand "extendqihi2"
3147 [(set (match_operand:HI 0 "register_operand")
3148 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3152 (define_insn "*extendqihi2"
3153 [(set (match_operand:HI 0 "register_operand" "=d")
3154 (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
3159 [(set (match_operand:HI 0 "register_operand")
3160 (sign_extend:HI (match_operand:QI 1 "register_operand")))]
3163 (ashift:SI (match_dup 1) (const_int 24)))
3165 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3166 "operands[0] = gen_lowpart (SImode, operands[0]);
3167 operands[1] = gen_lowpart (SImode, operands[1]);")
3169 (define_insn "*extendqihi2_internal_mem"
3170 [(set (match_operand:HI 0 "register_operand" "=d")
3171 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3174 [(set_attr "type" "load")
3175 (set_attr "mode" "SI")])
3178 (define_expand "extendqisi2"
3179 [(set (match_operand:SI 0 "register_operand")
3180 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3183 if (ISA_HAS_SEB_SEH)
3185 emit_insn (gen_extendqisi2_hw (operands[0],
3186 force_reg (QImode, operands[1])));
3191 (define_insn "*extendqisi2"
3192 [(set (match_operand:SI 0 "register_operand" "=d")
3193 (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
3198 [(set (match_operand:SI 0 "register_operand")
3199 (sign_extend:SI (match_operand:QI 1 "register_operand")))]
3202 (ashift:SI (match_dup 1) (const_int 24)))
3204 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3205 "operands[1] = gen_lowpart (SImode, operands[1]);")
3207 (define_insn "*extendqisi2_mem"
3208 [(set (match_operand:SI 0 "register_operand" "=d")
3209 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3212 [(set_attr "type" "load")
3213 (set_attr "mode" "SI")])
3215 (define_insn "extendqisi2_hw"
3216 [(set (match_operand:SI 0 "register_operand" "=r")
3217 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
3220 [(set_attr "type" "arith")
3221 (set_attr "mode" "SI")])
3223 (define_expand "extendqidi2"
3224 [(set (match_operand:DI 0 "register_operand")
3225 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3229 (define_insn "*extendqidi2"
3230 [(set (match_operand:DI 0 "register_operand" "=d")
3231 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
3236 [(set (match_operand:DI 0 "register_operand")
3237 (sign_extend:DI (match_operand:QI 1 "register_operand")))]
3238 "TARGET_64BIT && reload_completed"
3240 (ashift:DI (match_dup 1) (const_int 56)))
3242 (ashiftrt:DI (match_dup 0) (const_int 56)))]
3243 "operands[1] = gen_lowpart (DImode, operands[1]);")
3245 (define_insn "*extendqidi2_mem"
3246 [(set (match_operand:DI 0 "register_operand" "=d")
3247 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3250 [(set_attr "type" "load")
3251 (set_attr "mode" "DI")])
3253 (define_insn "extendsfdf2"
3254 [(set (match_operand:DF 0 "register_operand" "=f")
3255 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3256 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3258 [(set_attr "type" "fcvt")
3259 (set_attr "mode" "DF")])
3262 ;; ....................
3266 ;; ....................
3268 (define_expand "fix_truncdfsi2"
3269 [(set (match_operand:SI 0 "register_operand")
3270 (fix:SI (match_operand:DF 1 "register_operand")))]
3271 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3273 if (!ISA_HAS_TRUNC_W)
3275 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3280 (define_insn "fix_truncdfsi2_insn"
3281 [(set (match_operand:SI 0 "register_operand" "=f")
3282 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3283 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3285 [(set_attr "type" "fcvt")
3286 (set_attr "mode" "DF")
3287 (set_attr "length" "4")])
3289 (define_insn "fix_truncdfsi2_macro"
3290 [(set (match_operand:SI 0 "register_operand" "=f")
3291 (fix:SI (match_operand:DF 1 "register_operand" "f")))
3292 (clobber (match_scratch:DF 2 "=d"))]
3293 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3296 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3298 return "trunc.w.d %0,%1,%2";
3300 [(set_attr "type" "fcvt")
3301 (set_attr "mode" "DF")
3302 (set_attr "length" "36")])
3304 (define_expand "fix_truncsfsi2"
3305 [(set (match_operand:SI 0 "register_operand")
3306 (fix:SI (match_operand:SF 1 "register_operand")))]
3309 if (!ISA_HAS_TRUNC_W)
3311 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3316 (define_insn "fix_truncsfsi2_insn"
3317 [(set (match_operand:SI 0 "register_operand" "=f")
3318 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3319 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3321 [(set_attr "type" "fcvt")
3322 (set_attr "mode" "DF")
3323 (set_attr "length" "4")])
3325 (define_insn "fix_truncsfsi2_macro"
3326 [(set (match_operand:SI 0 "register_operand" "=f")
3327 (fix:SI (match_operand:SF 1 "register_operand" "f")))
3328 (clobber (match_scratch:SF 2 "=d"))]
3329 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3332 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3334 return "trunc.w.s %0,%1,%2";
3336 [(set_attr "type" "fcvt")
3337 (set_attr "mode" "DF")
3338 (set_attr "length" "36")])
3341 (define_insn "fix_truncdfdi2"
3342 [(set (match_operand:DI 0 "register_operand" "=f")
3343 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3344 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3346 [(set_attr "type" "fcvt")
3347 (set_attr "mode" "DF")
3348 (set_attr "length" "4")])
3351 (define_insn "fix_truncsfdi2"
3352 [(set (match_operand:DI 0 "register_operand" "=f")
3353 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3354 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3356 [(set_attr "type" "fcvt")
3357 (set_attr "mode" "SF")
3358 (set_attr "length" "4")])
3361 (define_insn "floatsidf2"
3362 [(set (match_operand:DF 0 "register_operand" "=f")
3363 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3364 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3366 [(set_attr "type" "fcvt")
3367 (set_attr "mode" "DF")
3368 (set_attr "length" "4")])
3371 (define_insn "floatdidf2"
3372 [(set (match_operand:DF 0 "register_operand" "=f")
3373 (float:DF (match_operand:DI 1 "register_operand" "f")))]
3374 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3376 [(set_attr "type" "fcvt")
3377 (set_attr "mode" "DF")
3378 (set_attr "length" "4")])
3381 (define_insn "floatsisf2"
3382 [(set (match_operand:SF 0 "register_operand" "=f")
3383 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3386 [(set_attr "type" "fcvt")
3387 (set_attr "mode" "SF")
3388 (set_attr "length" "4")])
3391 (define_insn "floatdisf2"
3392 [(set (match_operand:SF 0 "register_operand" "=f")
3393 (float:SF (match_operand:DI 1 "register_operand" "f")))]
3394 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3396 [(set_attr "type" "fcvt")
3397 (set_attr "mode" "SF")
3398 (set_attr "length" "4")])
3401 (define_expand "fixuns_truncdfsi2"
3402 [(set (match_operand:SI 0 "register_operand")
3403 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
3404 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3406 rtx reg1 = gen_reg_rtx (DFmode);
3407 rtx reg2 = gen_reg_rtx (DFmode);
3408 rtx reg3 = gen_reg_rtx (SImode);
3409 rtx label1 = gen_label_rtx ();
3410 rtx label2 = gen_label_rtx ();
3411 REAL_VALUE_TYPE offset;
3413 real_2expN (&offset, 31);
3415 if (reg1) /* Turn off complaints about unreached code. */
3417 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3418 do_pending_stack_adjust ();
3420 emit_insn (gen_cmpdf (operands[1], reg1));
3421 emit_jump_insn (gen_bge (label1));
3423 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3424 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3425 gen_rtx_LABEL_REF (VOIDmode, label2)));
3428 emit_label (label1);
3429 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3430 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3431 (BITMASK_HIGH, SImode)));
3433 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3434 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3436 emit_label (label2);
3438 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3439 fields, and can't be used for REG_NOTES anyway). */
3440 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3446 (define_expand "fixuns_truncdfdi2"
3447 [(set (match_operand:DI 0 "register_operand")
3448 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3449 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3451 rtx reg1 = gen_reg_rtx (DFmode);
3452 rtx reg2 = gen_reg_rtx (DFmode);
3453 rtx reg3 = gen_reg_rtx (DImode);
3454 rtx label1 = gen_label_rtx ();
3455 rtx label2 = gen_label_rtx ();
3456 REAL_VALUE_TYPE offset;
3458 real_2expN (&offset, 63);
3460 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3461 do_pending_stack_adjust ();
3463 emit_insn (gen_cmpdf (operands[1], reg1));
3464 emit_jump_insn (gen_bge (label1));
3466 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3467 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3468 gen_rtx_LABEL_REF (VOIDmode, label2)));
3471 emit_label (label1);
3472 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3473 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3474 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3476 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3477 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3479 emit_label (label2);
3481 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3482 fields, and can't be used for REG_NOTES anyway). */
3483 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3488 (define_expand "fixuns_truncsfsi2"
3489 [(set (match_operand:SI 0 "register_operand")
3490 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3493 rtx reg1 = gen_reg_rtx (SFmode);
3494 rtx reg2 = gen_reg_rtx (SFmode);
3495 rtx reg3 = gen_reg_rtx (SImode);
3496 rtx label1 = gen_label_rtx ();
3497 rtx label2 = gen_label_rtx ();
3498 REAL_VALUE_TYPE offset;
3500 real_2expN (&offset, 31);
3502 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3503 do_pending_stack_adjust ();
3505 emit_insn (gen_cmpsf (operands[1], reg1));
3506 emit_jump_insn (gen_bge (label1));
3508 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3509 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3510 gen_rtx_LABEL_REF (VOIDmode, label2)));
3513 emit_label (label1);
3514 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3515 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3516 (BITMASK_HIGH, SImode)));
3518 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3519 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3521 emit_label (label2);
3523 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3524 fields, and can't be used for REG_NOTES anyway). */
3525 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3530 (define_expand "fixuns_truncsfdi2"
3531 [(set (match_operand:DI 0 "register_operand")
3532 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3533 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3535 rtx reg1 = gen_reg_rtx (SFmode);
3536 rtx reg2 = gen_reg_rtx (SFmode);
3537 rtx reg3 = gen_reg_rtx (DImode);
3538 rtx label1 = gen_label_rtx ();
3539 rtx label2 = gen_label_rtx ();
3540 REAL_VALUE_TYPE offset;
3542 real_2expN (&offset, 63);
3544 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3545 do_pending_stack_adjust ();
3547 emit_insn (gen_cmpsf (operands[1], reg1));
3548 emit_jump_insn (gen_bge (label1));
3550 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3551 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3552 gen_rtx_LABEL_REF (VOIDmode, label2)));
3555 emit_label (label1);
3556 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3557 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3558 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3560 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3561 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3563 emit_label (label2);
3565 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3566 fields, and can't be used for REG_NOTES anyway). */
3567 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3572 ;; ....................
3576 ;; ....................
3578 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3580 (define_expand "extv"
3581 [(set (match_operand 0 "register_operand")
3582 (sign_extract (match_operand:QI 1 "memory_operand")
3583 (match_operand 2 "immediate_operand")
3584 (match_operand 3 "immediate_operand")))]
3587 if (mips_expand_unaligned_load (operands[0], operands[1],
3588 INTVAL (operands[2]),
3589 INTVAL (operands[3])))
3595 (define_expand "extzv"
3596 [(set (match_operand 0 "register_operand")
3597 (zero_extract (match_operand:QI 1 "memory_operand")
3598 (match_operand 2 "immediate_operand")
3599 (match_operand 3 "immediate_operand")))]
3602 if (mips_expand_unaligned_load (operands[0], operands[1],
3603 INTVAL (operands[2]),
3604 INTVAL (operands[3])))
3610 (define_expand "insv"
3611 [(set (zero_extract (match_operand:QI 0 "memory_operand")
3612 (match_operand 1 "immediate_operand")
3613 (match_operand 2 "immediate_operand"))
3614 (match_operand 3 "reg_or_0_operand"))]
3617 if (mips_expand_unaligned_store (operands[0], operands[3],
3618 INTVAL (operands[1]),
3619 INTVAL (operands[2])))
3625 ;; Unaligned word moves generated by the bit field patterns.
3627 ;; As far as the rtl is concerned, both the left-part and right-part
3628 ;; instructions can access the whole field. However, the real operand
3629 ;; refers to just the first or the last byte (depending on endianness).
3630 ;; We therefore use two memory operands to each instruction, one to
3631 ;; describe the rtl effect and one to use in the assembly output.
3633 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3634 ;; This allows us to use the standard length calculations for the "load"
3635 ;; and "store" type attributes.
3637 (define_insn "mov_lwl"
3638 [(set (match_operand:SI 0 "register_operand" "=d")
3639 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3640 (match_operand:QI 2 "memory_operand" "m")]
3644 [(set_attr "type" "load")
3645 (set_attr "mode" "SI")
3646 (set_attr "hazard" "none")])
3648 (define_insn "mov_lwr"
3649 [(set (match_operand:SI 0 "register_operand" "=d")
3650 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3651 (match_operand:QI 2 "memory_operand" "m")
3652 (match_operand:SI 3 "register_operand" "0")]
3656 [(set_attr "type" "load")
3657 (set_attr "mode" "SI")])
3660 (define_insn "mov_swl"
3661 [(set (match_operand:BLK 0 "memory_operand" "=m")
3662 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3663 (match_operand:QI 2 "memory_operand" "m")]
3667 [(set_attr "type" "store")
3668 (set_attr "mode" "SI")])
3670 (define_insn "mov_swr"
3671 [(set (match_operand:BLK 0 "memory_operand" "+m")
3672 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3673 (match_operand:QI 2 "memory_operand" "m")
3678 [(set_attr "type" "store")
3679 (set_attr "mode" "SI")])
3682 (define_insn "mov_ldl"
3683 [(set (match_operand:DI 0 "register_operand" "=d")
3684 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3685 (match_operand:QI 2 "memory_operand" "m")]
3687 "TARGET_64BIT && !TARGET_MIPS16"
3689 [(set_attr "type" "load")
3690 (set_attr "mode" "DI")])
3692 (define_insn "mov_ldr"
3693 [(set (match_operand:DI 0 "register_operand" "=d")
3694 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3695 (match_operand:QI 2 "memory_operand" "m")
3696 (match_operand:DI 3 "register_operand" "0")]
3698 "TARGET_64BIT && !TARGET_MIPS16"
3700 [(set_attr "type" "load")
3701 (set_attr "mode" "DI")])
3704 (define_insn "mov_sdl"
3705 [(set (match_operand:BLK 0 "memory_operand" "=m")
3706 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3707 (match_operand:QI 2 "memory_operand" "m")]
3709 "TARGET_64BIT && !TARGET_MIPS16"
3711 [(set_attr "type" "store")
3712 (set_attr "mode" "DI")])
3714 (define_insn "mov_sdr"
3715 [(set (match_operand:BLK 0 "memory_operand" "+m")
3716 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3717 (match_operand:QI 2 "memory_operand" "m")
3720 "TARGET_64BIT && !TARGET_MIPS16"
3722 [(set_attr "type" "store")
3723 (set_attr "mode" "DI")])
3725 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3726 ;; The required value is:
3728 ;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3730 ;; which translates to:
3732 ;; lui op0,%highest(op1)
3733 ;; daddiu op0,op0,%higher(op1)
3735 ;; daddiu op0,op0,%hi(op1)
3737 (define_insn_and_split "*lea_high64"
3738 [(set (match_operand:DI 0 "register_operand" "=d")
3739 (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3740 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3742 "&& reload_completed"
3743 [(set (match_dup 0) (high:DI (match_dup 2)))
3744 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3745 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3746 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3747 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3749 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3750 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3752 [(set_attr "length" "20")])
3754 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3755 ;; SYMBOL_GENERAL X will take 6 cycles. This next pattern allows combine
3756 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3757 ;; used once. We can then use the sequence:
3759 ;; lui op0,%highest(op1)
3761 ;; daddiu op0,op0,%higher(op1)
3762 ;; daddiu op2,op2,%lo(op1)
3764 ;; daddu op0,op0,op2
3766 ;; which takes 4 cycles on most superscalar targets.
3767 (define_insn_and_split "*lea64"
3768 [(set (match_operand:DI 0 "register_operand" "=d")
3769 (match_operand:DI 1 "general_symbolic_operand" ""))
3770 (clobber (match_scratch:DI 2 "=&d"))]
3771 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3773 "&& reload_completed"
3774 [(set (match_dup 0) (high:DI (match_dup 3)))
3775 (set (match_dup 2) (high:DI (match_dup 4)))
3776 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3777 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3778 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3779 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3781 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3782 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3784 [(set_attr "length" "24")])
3786 ;; Insns to fetch a global symbol from a big GOT.
3788 (define_insn_and_split "*xgot_hisi"
3789 [(set (match_operand:SI 0 "register_operand" "=d")
3790 (high:SI (match_operand:SI 1 "global_got_operand" "")))]
3791 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3793 "&& reload_completed"
3794 [(set (match_dup 0) (high:SI (match_dup 2)))
3795 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
3797 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3798 operands[3] = pic_offset_table_rtx;
3800 [(set_attr "got" "xgot_high")])
3802 (define_insn_and_split "*xgot_losi"
3803 [(set (match_operand:SI 0 "register_operand" "=d")
3804 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
3805 (match_operand:SI 2 "global_got_operand" "")))]
3806 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3808 "&& reload_completed"
3810 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3811 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3812 [(set_attr "got" "load")])
3814 (define_insn_and_split "*xgot_hidi"
3815 [(set (match_operand:DI 0 "register_operand" "=d")
3816 (high:DI (match_operand:DI 1 "global_got_operand" "")))]
3817 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3819 "&& reload_completed"
3820 [(set (match_dup 0) (high:DI (match_dup 2)))
3821 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
3823 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3824 operands[3] = pic_offset_table_rtx;
3826 [(set_attr "got" "xgot_high")])
3828 (define_insn_and_split "*xgot_lodi"
3829 [(set (match_operand:DI 0 "register_operand" "=d")
3830 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
3831 (match_operand:DI 2 "global_got_operand" "")))]
3832 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3834 "&& reload_completed"
3836 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3837 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3838 [(set_attr "got" "load")])
3840 ;; Insns to fetch a global symbol from a normal GOT.
3842 (define_insn_and_split "*got_dispsi"
3843 [(set (match_operand:SI 0 "register_operand" "=d")
3844 (match_operand:SI 1 "global_got_operand" ""))]
3845 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3847 "&& reload_completed"
3849 (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3851 operands[2] = pic_offset_table_rtx;
3852 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3854 [(set_attr "got" "load")])
3856 (define_insn_and_split "*got_dispdi"
3857 [(set (match_operand:DI 0 "register_operand" "=d")
3858 (match_operand:DI 1 "global_got_operand" ""))]
3859 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3861 "&& reload_completed"
3863 (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3865 operands[2] = pic_offset_table_rtx;
3866 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3868 [(set_attr "got" "load")])
3870 ;; Insns for loading the high part of a local symbol.
3872 (define_insn_and_split "*got_pagesi"
3873 [(set (match_operand:SI 0 "register_operand" "=d")
3874 (high:SI (match_operand:SI 1 "local_got_operand" "")))]
3875 "TARGET_EXPLICIT_RELOCS"
3877 "&& reload_completed"
3879 (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3881 operands[2] = pic_offset_table_rtx;
3882 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3884 [(set_attr "got" "load")])
3886 (define_insn_and_split "*got_pagedi"
3887 [(set (match_operand:DI 0 "register_operand" "=d")
3888 (high:DI (match_operand:DI 1 "local_got_operand" "")))]
3889 "TARGET_EXPLICIT_RELOCS"
3891 "&& reload_completed"
3893 (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3895 operands[2] = pic_offset_table_rtx;
3896 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3898 [(set_attr "got" "load")])
3900 ;; Lower-level instructions for loading an address from the GOT.
3901 ;; We could use MEMs, but an unspec gives more optimization
3904 (define_insn "*load_gotsi"
3905 [(set (match_operand:SI 0 "register_operand" "=d")
3906 (unspec:SI [(match_operand:SI 1 "register_operand" "d")
3907 (match_operand:SI 2 "immediate_operand" "")]
3911 [(set_attr "type" "load")
3912 (set_attr "length" "4")])
3914 (define_insn "*load_gotdi"
3915 [(set (match_operand:DI 0 "register_operand" "=d")
3916 (unspec:DI [(match_operand:DI 1 "register_operand" "d")
3917 (match_operand:DI 2 "immediate_operand" "")]
3921 [(set_attr "type" "load")
3922 (set_attr "length" "4")])
3924 ;; Instructions for adding the low 16 bits of an address to a register.
3925 ;; Operand 2 is the address: print_operand works out which relocation
3926 ;; should be applied.
3928 (define_insn "*lowsi"
3929 [(set (match_operand:SI 0 "register_operand" "=d")
3930 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
3931 (match_operand:SI 2 "immediate_operand" "")))]
3934 [(set_attr "type" "arith")
3935 (set_attr "mode" "SI")])
3937 (define_insn "*lowdi"
3938 [(set (match_operand:DI 0 "register_operand" "=d")
3939 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
3940 (match_operand:DI 2 "immediate_operand" "")))]
3941 "!TARGET_MIPS16 && TARGET_64BIT"
3943 [(set_attr "type" "arith")
3944 (set_attr "mode" "DI")])
3946 (define_insn "*lowsi_mips16"
3947 [(set (match_operand:SI 0 "register_operand" "=d")
3948 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
3949 (match_operand:SI 2 "immediate_operand" "")))]
3952 [(set_attr "type" "arith")
3953 (set_attr "mode" "SI")
3954 (set_attr "length" "8")])
3956 (define_insn "*lowdi_mips16"
3957 [(set (match_operand:DI 0 "register_operand" "=d")
3958 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
3959 (match_operand:DI 2 "immediate_operand" "")))]
3960 "TARGET_MIPS16 && TARGET_64BIT"
3962 [(set_attr "type" "arith")
3963 (set_attr "mode" "DI")
3964 (set_attr "length" "8")])
3966 ;; 64-bit integer moves
3968 ;; Unlike most other insns, the move insns can't be split with
3969 ;; different predicates, because register spilling and other parts of
3970 ;; the compiler, have memoized the insn number already.
3972 (define_expand "movdi"
3973 [(set (match_operand:DI 0 "")
3974 (match_operand:DI 1 ""))]
3977 if (mips_legitimize_move (DImode, operands[0], operands[1]))
3981 ;; For mips16, we need a special case to handle storing $31 into
3982 ;; memory, since we don't have a constraint to match $31. This
3983 ;; instruction can be generated by save_restore_insns.
3986 [(set (match_operand:DI 0 "stack_operand" "=m")
3988 "TARGET_MIPS16 && TARGET_64BIT"
3990 [(set_attr "type" "store")
3991 (set_attr "mode" "DI")])
3993 (define_insn "*movdi_32bit"
3994 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
3995 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
3996 "!TARGET_64BIT && !TARGET_MIPS16
3997 && (register_operand (operands[0], DImode)
3998 || reg_or_0_operand (operands[1], DImode))"
3999 { return mips_output_move (operands[0], operands[1]); }
4000 [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
4001 (set_attr "mode" "DI")
4002 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
4004 (define_insn "*movdi_32bit_mips16"
4005 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4006 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4007 "!TARGET_64BIT && TARGET_MIPS16
4008 && (register_operand (operands[0], DImode)
4009 || register_operand (operands[1], DImode))"
4010 { return mips_output_move (operands[0], operands[1]); }
4011 [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo")
4012 (set_attr "mode" "DI")
4013 (set_attr "length" "8,8,8,8,12,*,*,8")])
4015 (define_insn "*movdi_64bit"
4016 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*B*C*D,*B*C*D,*d,*m")
4017 (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J*d,*d,*m,*B*C*D,*B*C*D"))]
4018 "TARGET_64BIT && !TARGET_MIPS16
4019 && (register_operand (operands[0], DImode)
4020 || reg_or_0_operand (operands[1], DImode))"
4021 { return mips_output_move (operands[0], operands[1]); }
4022 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
4023 (set_attr "mode" "DI")
4024 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
4026 (define_insn "*movdi_64bit_mips16"
4027 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4028 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4029 "TARGET_64BIT && TARGET_MIPS16
4030 && (register_operand (operands[0], DImode)
4031 || register_operand (operands[1], DImode))"
4032 { return mips_output_move (operands[0], operands[1]); }
4033 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
4034 (set_attr "mode" "DI")
4035 (set_attr_alternative "length"
4039 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4042 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4047 (const_string "*")])])
4050 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4051 ;; when the original load is a 4 byte instruction but the add and the
4052 ;; load are 2 2 byte instructions.
4055 [(set (match_operand:DI 0 "register_operand")
4056 (mem:DI (plus:DI (match_dup 0)
4057 (match_operand:DI 1 "const_int_operand"))))]
4058 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4059 && !TARGET_DEBUG_D_MODE
4060 && GET_CODE (operands[0]) == REG
4061 && M16_REG_P (REGNO (operands[0]))
4062 && GET_CODE (operands[1]) == CONST_INT
4063 && ((INTVAL (operands[1]) < 0
4064 && INTVAL (operands[1]) >= -0x10)
4065 || (INTVAL (operands[1]) >= 32 * 8
4066 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4067 || (INTVAL (operands[1]) >= 0
4068 && INTVAL (operands[1]) < 32 * 8
4069 && (INTVAL (operands[1]) & 7) != 0))"
4070 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4071 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4073 HOST_WIDE_INT val = INTVAL (operands[1]);
4076 operands[2] = const0_rtx;
4077 else if (val >= 32 * 8)
4081 operands[1] = GEN_INT (0x8 + off);
4082 operands[2] = GEN_INT (val - off - 0x8);
4088 operands[1] = GEN_INT (off);
4089 operands[2] = GEN_INT (val - off);
4093 ;; 32-bit Integer moves
4095 ;; Unlike most other insns, the move insns can't be split with
4096 ;; different predicates, because register spilling and other parts of
4097 ;; the compiler, have memoized the insn number already.
4099 (define_expand "movsi"
4100 [(set (match_operand:SI 0 "")
4101 (match_operand:SI 1 ""))]
4104 if (mips_legitimize_move (SImode, operands[0], operands[1]))
4108 ;; We can only store $ra directly into a small sp offset.
4111 [(set (match_operand:SI 0 "stack_operand" "=m")
4115 [(set_attr "type" "store")
4116 (set_attr "mode" "SI")])
4118 ;; The difference between these two is whether or not ints are allowed
4119 ;; in FP registers (off by default, use -mdebugh to enable).
4121 (define_insn "*movsi_internal"
4122 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*B*C*D,*B*C*D,*d,*m")
4123 (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*d,*m,*B*C*D,*B*C*D"))]
4125 && (register_operand (operands[0], SImode)
4126 || reg_or_0_operand (operands[1], SImode))"
4127 { return mips_output_move (operands[0], operands[1]); }
4128 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
4129 (set_attr "mode" "SI")
4130 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
4132 (define_insn "*movsi_mips16"
4133 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4134 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4136 && (register_operand (operands[0], SImode)
4137 || register_operand (operands[1], SImode))"
4138 { return mips_output_move (operands[0], operands[1]); }
4139 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
4140 (set_attr "mode" "SI")
4141 (set_attr_alternative "length"
4145 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4148 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4153 (const_string "*")])])
4155 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4156 ;; when the original load is a 4 byte instruction but the add and the
4157 ;; load are 2 2 byte instructions.
4160 [(set (match_operand:SI 0 "register_operand")
4161 (mem:SI (plus:SI (match_dup 0)
4162 (match_operand:SI 1 "const_int_operand"))))]
4163 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4164 && GET_CODE (operands[0]) == REG
4165 && M16_REG_P (REGNO (operands[0]))
4166 && GET_CODE (operands[1]) == CONST_INT
4167 && ((INTVAL (operands[1]) < 0
4168 && INTVAL (operands[1]) >= -0x80)
4169 || (INTVAL (operands[1]) >= 32 * 4
4170 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4171 || (INTVAL (operands[1]) >= 0
4172 && INTVAL (operands[1]) < 32 * 4
4173 && (INTVAL (operands[1]) & 3) != 0))"
4174 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4175 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4177 HOST_WIDE_INT val = INTVAL (operands[1]);
4180 operands[2] = const0_rtx;
4181 else if (val >= 32 * 4)
4185 operands[1] = GEN_INT (0x7c + off);
4186 operands[2] = GEN_INT (val - off - 0x7c);
4192 operands[1] = GEN_INT (off);
4193 operands[2] = GEN_INT (val - off);
4197 ;; On the mips16, we can split a load of certain constants into a load
4198 ;; and an add. This turns a 4 byte instruction into 2 2 byte
4202 [(set (match_operand:SI 0 "register_operand")
4203 (match_operand:SI 1 "const_int_operand"))]
4204 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4205 && GET_CODE (operands[0]) == REG
4206 && M16_REG_P (REGNO (operands[0]))
4207 && GET_CODE (operands[1]) == CONST_INT
4208 && INTVAL (operands[1]) >= 0x100
4209 && INTVAL (operands[1]) <= 0xff + 0x7f"
4210 [(set (match_dup 0) (match_dup 1))
4211 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4213 int val = INTVAL (operands[1]);
4215 operands[1] = GEN_INT (0xff);
4216 operands[2] = GEN_INT (val - 0xff);
4219 ;; This insn handles moving CCmode values. It's really just a
4220 ;; slightly simplified copy of movsi_internal2, with additional cases
4221 ;; to move a condition register to a general register and to move
4222 ;; between the general registers and the floating point registers.
4224 (define_insn "movcc"
4225 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
4226 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
4227 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4228 { return mips_output_move (operands[0], operands[1]); }
4229 [(set_attr "type" "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
4230 (set_attr "mode" "SI")
4231 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
4233 ;; Reload condition code registers. reload_incc and reload_outcc
4234 ;; both handle moves from arbitrary operands into condition code
4235 ;; registers. reload_incc handles the more common case in which
4236 ;; a source operand is constrained to be in a condition-code
4237 ;; register, but has not been allocated to one.
4239 ;; Sometimes, such as in movcc, we have a CCmode destination whose
4240 ;; constraints do not include 'z'. reload_outcc handles the case
4241 ;; when such an operand is allocated to a condition-code register.
4243 ;; Note that reloads from a condition code register to some
4244 ;; other location can be done using ordinary moves. Moving
4245 ;; into a GPR takes a single movcc, moving elsewhere takes
4246 ;; two. We can leave these cases to the generic reload code.
4247 (define_expand "reload_incc"
4248 [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4249 (match_operand:CC 1 "general_operand" ""))
4250 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4251 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4253 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4257 (define_expand "reload_outcc"
4258 [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4259 (match_operand:CC 1 "register_operand" ""))
4260 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4261 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4263 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4267 ;; MIPS4 supports loading and storing a floating point register from
4268 ;; the sum of two general registers. We use two versions for each of
4269 ;; these four instructions: one where the two general registers are
4270 ;; SImode, and one where they are DImode. This is because general
4271 ;; registers will be in SImode when they hold 32 bit values, but,
4272 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
4273 ;; instructions will still work correctly.
4275 ;; ??? Perhaps it would be better to support these instructions by
4276 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
4277 ;; these instructions can only be used to load and store floating
4278 ;; point registers, that would probably cause trouble in reload.
4281 [(set (match_operand:SF 0 "register_operand" "=f")
4282 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4283 (match_operand:SI 2 "register_operand" "d"))))]
4284 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4286 [(set_attr "type" "fpidxload")
4287 (set_attr "mode" "SF")
4288 (set_attr "length" "4")])
4291 [(set (match_operand:SF 0 "register_operand" "=f")
4292 (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4293 (match_operand:DI 2 "register_operand" "d"))))]
4294 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4296 [(set_attr "type" "fpidxload")
4297 (set_attr "mode" "SF")
4298 (set_attr "length" "4")])
4301 [(set (match_operand:DF 0 "register_operand" "=f")
4302 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4303 (match_operand:SI 2 "register_operand" "d"))))]
4304 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4306 [(set_attr "type" "fpidxload")
4307 (set_attr "mode" "DF")
4308 (set_attr "length" "4")])
4311 [(set (match_operand:DF 0 "register_operand" "=f")
4312 (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4313 (match_operand:DI 2 "register_operand" "d"))))]
4314 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4316 [(set_attr "type" "fpidxload")
4317 (set_attr "mode" "DF")
4318 (set_attr "length" "4")])
4321 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4322 (match_operand:SI 2 "register_operand" "d")))
4323 (match_operand:SF 0 "register_operand" "f"))]
4324 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4326 [(set_attr "type" "fpidxstore")
4327 (set_attr "mode" "SF")
4328 (set_attr "length" "4")])
4331 [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4332 (match_operand:DI 2 "register_operand" "d")))
4333 (match_operand:SF 0 "register_operand" "f"))]
4334 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4336 [(set_attr "type" "fpidxstore")
4337 (set_attr "mode" "SF")
4338 (set_attr "length" "4")])
4341 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4342 (match_operand:SI 2 "register_operand" "d")))
4343 (match_operand:DF 0 "register_operand" "f"))]
4344 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4346 [(set_attr "type" "fpidxstore")
4347 (set_attr "mode" "DF")
4348 (set_attr "length" "4")])
4351 [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4352 (match_operand:DI 2 "register_operand" "d")))
4353 (match_operand:DF 0 "register_operand" "f"))]
4354 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4356 [(set_attr "type" "fpidxstore")
4357 (set_attr "mode" "DF")
4358 (set_attr "length" "4")])
4360 ;; 16-bit Integer moves
4362 ;; Unlike most other insns, the move insns can't be split with
4363 ;; different predicates, because register spilling and other parts of
4364 ;; the compiler, have memoized the insn number already.
4365 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4367 (define_expand "movhi"
4368 [(set (match_operand:HI 0 "")
4369 (match_operand:HI 1 ""))]
4372 if (mips_legitimize_move (HImode, operands[0], operands[1]))
4376 (define_insn "*movhi_internal"
4377 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4378 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4380 && (register_operand (operands[0], HImode)
4381 || reg_or_0_operand (operands[1], HImode))"
4391 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4392 (set_attr "mode" "HI")
4393 (set_attr "length" "4,4,*,*,4,4,4,4")])
4395 (define_insn "*movhi_mips16"
4396 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4397 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))]
4399 && (register_operand (operands[0], HImode)
4400 || register_operand (operands[1], HImode))"
4409 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4410 (set_attr "mode" "HI")
4411 (set_attr_alternative "length"
4415 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4418 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4422 (const_string "*")])])
4425 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4426 ;; when the original load is a 4 byte instruction but the add and the
4427 ;; load are 2 2 byte instructions.
4430 [(set (match_operand:HI 0 "register_operand")
4431 (mem:HI (plus:SI (match_dup 0)
4432 (match_operand:SI 1 "const_int_operand"))))]
4433 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4434 && GET_CODE (operands[0]) == REG
4435 && M16_REG_P (REGNO (operands[0]))
4436 && GET_CODE (operands[1]) == CONST_INT
4437 && ((INTVAL (operands[1]) < 0
4438 && INTVAL (operands[1]) >= -0x80)
4439 || (INTVAL (operands[1]) >= 32 * 2
4440 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4441 || (INTVAL (operands[1]) >= 0
4442 && INTVAL (operands[1]) < 32 * 2
4443 && (INTVAL (operands[1]) & 1) != 0))"
4444 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4445 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4447 HOST_WIDE_INT val = INTVAL (operands[1]);
4450 operands[2] = const0_rtx;
4451 else if (val >= 32 * 2)
4455 operands[1] = GEN_INT (0x7e + off);
4456 operands[2] = GEN_INT (val - off - 0x7e);
4462 operands[1] = GEN_INT (off);
4463 operands[2] = GEN_INT (val - off);
4467 ;; 8-bit Integer moves
4469 ;; Unlike most other insns, the move insns can't be split with
4470 ;; different predicates, because register spilling and other parts of
4471 ;; the compiler, have memoized the insn number already.
4472 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4474 (define_expand "movqi"
4475 [(set (match_operand:QI 0 "")
4476 (match_operand:QI 1 ""))]
4479 if (mips_legitimize_move (QImode, operands[0], operands[1]))
4483 (define_insn "*movqi_internal"
4484 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4485 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4487 && (register_operand (operands[0], QImode)
4488 || reg_or_0_operand (operands[1], QImode))"
4498 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4499 (set_attr "mode" "QI")
4500 (set_attr "length" "4,4,*,*,4,4,4,4")])
4502 (define_insn "*movqi_mips16"
4503 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4504 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))]
4506 && (register_operand (operands[0], QImode)
4507 || register_operand (operands[1], QImode))"
4516 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4517 (set_attr "mode" "QI")
4518 (set_attr "length" "4,4,4,4,8,*,*")])
4520 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
4521 ;; when the original load is a 4 byte instruction but the add and the
4522 ;; load are 2 2 byte instructions.
4525 [(set (match_operand:QI 0 "register_operand")
4526 (mem:QI (plus:SI (match_dup 0)
4527 (match_operand:SI 1 "const_int_operand"))))]
4528 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4529 && GET_CODE (operands[0]) == REG
4530 && M16_REG_P (REGNO (operands[0]))
4531 && GET_CODE (operands[1]) == CONST_INT
4532 && ((INTVAL (operands[1]) < 0
4533 && INTVAL (operands[1]) >= -0x80)
4534 || (INTVAL (operands[1]) >= 32
4535 && INTVAL (operands[1]) <= 31 + 0x7f))"
4536 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4537 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4539 HOST_WIDE_INT val = INTVAL (operands[1]);
4542 operands[2] = const0_rtx;
4545 operands[1] = GEN_INT (0x7f);
4546 operands[2] = GEN_INT (val - 0x7f);
4550 ;; 32-bit floating point moves
4552 (define_expand "movsf"
4553 [(set (match_operand:SF 0 "")
4554 (match_operand:SF 1 ""))]
4557 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4561 (define_insn "*movsf_hardfloat"
4562 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4563 (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
4565 && (register_operand (operands[0], SFmode)
4566 || reg_or_0_operand (operands[1], SFmode))"
4567 { return mips_output_move (operands[0], operands[1]); }
4568 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4569 (set_attr "mode" "SF")
4570 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4572 (define_insn "*movsf_softfloat"
4573 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4574 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
4575 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4576 && (register_operand (operands[0], SFmode)
4577 || reg_or_0_operand (operands[1], SFmode))"
4578 { return mips_output_move (operands[0], operands[1]); }
4579 [(set_attr "type" "arith,load,store")
4580 (set_attr "mode" "SF")
4581 (set_attr "length" "4,*,*")])
4583 (define_insn "*movsf_mips16"
4584 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4585 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
4587 && (register_operand (operands[0], SFmode)
4588 || register_operand (operands[1], SFmode))"
4589 { return mips_output_move (operands[0], operands[1]); }
4590 [(set_attr "type" "arith,arith,arith,load,store")
4591 (set_attr "mode" "SF")
4592 (set_attr "length" "4,4,4,*,*")])
4595 ;; 64-bit floating point moves
4597 (define_expand "movdf"
4598 [(set (match_operand:DF 0 "")
4599 (match_operand:DF 1 ""))]
4602 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4606 (define_insn "*movdf_hardfloat_64bit"
4607 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4608 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4609 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
4610 && (register_operand (operands[0], DFmode)
4611 || reg_or_0_operand (operands[1], DFmode))"
4612 { return mips_output_move (operands[0], operands[1]); }
4613 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4614 (set_attr "mode" "DF")
4615 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4617 (define_insn "*movdf_hardfloat_32bit"
4618 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4619 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4620 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
4621 && (register_operand (operands[0], DFmode)
4622 || reg_or_0_operand (operands[1], DFmode))"
4623 { return mips_output_move (operands[0], operands[1]); }
4624 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4625 (set_attr "mode" "DF")
4626 (set_attr "length" "4,8,*,*,8,8,8,*,*")])
4628 (define_insn "*movdf_softfloat"
4629 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
4630 (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
4631 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4632 && (register_operand (operands[0], DFmode)
4633 || reg_or_0_operand (operands[1], DFmode))"
4634 { return mips_output_move (operands[0], operands[1]); }
4635 [(set_attr "type" "arith,load,store,xfer,xfer,fmove")
4636 (set_attr "mode" "DF")
4637 (set_attr "length" "8,*,*,4,4,4")])
4639 (define_insn "*movdf_mips16"
4640 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4641 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4643 && (register_operand (operands[0], DFmode)
4644 || register_operand (operands[1], DFmode))"
4645 { return mips_output_move (operands[0], operands[1]); }
4646 [(set_attr "type" "arith,arith,arith,load,store")
4647 (set_attr "mode" "DF")
4648 (set_attr "length" "8,8,8,*,*")])
4651 [(set (match_operand:DI 0 "nonimmediate_operand")
4652 (match_operand:DI 1 "move_operand"))]
4653 "reload_completed && !TARGET_64BIT
4654 && mips_split_64bit_move_p (operands[0], operands[1])"
4657 mips_split_64bit_move (operands[0], operands[1]);
4662 [(set (match_operand:DF 0 "nonimmediate_operand")
4663 (match_operand:DF 1 "move_operand"))]
4664 "reload_completed && !TARGET_64BIT
4665 && mips_split_64bit_move_p (operands[0], operands[1])"
4668 mips_split_64bit_move (operands[0], operands[1]);
4672 ;; When generating mips16 code, split moves of negative constants into
4673 ;; a positive "li" followed by a negation.
4675 [(set (match_operand 0 "register_operand")
4676 (match_operand 1 "const_int_operand"))]
4677 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4681 (neg:SI (match_dup 2)))]
4683 operands[2] = gen_lowpart (SImode, operands[0]);
4684 operands[3] = GEN_INT (-INTVAL (operands[1]));
4687 ;; The HI and LO registers are not truly independent. If we move an mthi
4688 ;; instruction before an mflo instruction, it will make the result of the
4689 ;; mflo unpredictable. The same goes for mtlo and mfhi.
4691 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4692 ;; Operand 1 is the register we want, operand 2 is the other one.
4694 (define_insn "mfhilo_di"
4695 [(set (match_operand:DI 0 "register_operand" "=d,d")
4696 (unspec:DI [(match_operand:DI 1 "register_operand" "h,l")
4697 (match_operand:DI 2 "register_operand" "l,h")]
4701 [(set_attr "type" "mfhilo")])
4703 (define_insn "mfhilo_si"
4704 [(set (match_operand:SI 0 "register_operand" "=d,d")
4705 (unspec:SI [(match_operand:SI 1 "register_operand" "h,l")
4706 (match_operand:SI 2 "register_operand" "l,h")]
4710 [(set_attr "type" "mfhilo")])
4712 ;; Patterns for loading or storing part of a paired floating point
4713 ;; register. We need them because odd-numbered floating-point registers
4714 ;; are not fully independent: see mips_split_64bit_move.
4716 ;; Load the low word of operand 0 with operand 1.
4717 (define_insn "load_df_low"
4718 [(set (match_operand:DF 0 "register_operand" "=f,f")
4719 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
4720 UNSPEC_LOAD_DF_LOW))]
4721 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4723 operands[0] = mips_subword (operands[0], 0);
4724 return mips_output_move (operands[0], operands[1]);
4726 [(set_attr "type" "xfer,fpload")
4727 (set_attr "mode" "SF")])
4729 ;; Load the high word of operand 0 from operand 1, preserving the value
4731 (define_insn "load_df_high"
4732 [(set (match_operand:DF 0 "register_operand" "=f,f")
4733 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
4734 (match_operand:DF 2 "register_operand" "0,0")]
4735 UNSPEC_LOAD_DF_HIGH))]
4736 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4738 operands[0] = mips_subword (operands[0], 1);
4739 return mips_output_move (operands[0], operands[1]);
4741 [(set_attr "type" "xfer,fpload")
4742 (set_attr "mode" "SF")])
4744 ;; Store the high word of operand 1 in operand 0. The corresponding
4745 ;; low-word move is done in the normal way.
4746 (define_insn "store_df_high"
4747 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4748 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4749 UNSPEC_STORE_DF_HIGH))]
4750 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4752 operands[1] = mips_subword (operands[1], 1);
4753 return mips_output_move (operands[0], operands[1]);
4755 [(set_attr "type" "xfer,fpstore")
4756 (set_attr "mode" "SF")])
4758 ;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
4759 ;; of _gp from the start of this function. Operand 1 is the incoming
4760 ;; function address.
4761 (define_insn_and_split "loadgp"
4762 [(unspec_volatile [(match_operand 0 "" "")
4763 (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4764 "TARGET_ABICALLS && TARGET_NEWABI"
4767 [(set (match_dup 2) (match_dup 3))
4768 (set (match_dup 2) (match_dup 4))
4769 (set (match_dup 2) (match_dup 5))]
4771 operands[2] = pic_offset_table_rtx;
4772 operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4773 operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4774 operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4776 [(set_attr "length" "12")])
4778 ;; The use of gp is hidden when not using explicit relocations.
4779 ;; This blockage instruction prevents the gp load from being
4780 ;; scheduled after an implicit use of gp. It also prevents
4781 ;; the load from being deleted as dead.
4782 (define_insn "loadgp_blockage"
4783 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4786 [(set_attr "type" "unknown")
4787 (set_attr "mode" "none")
4788 (set_attr "length" "0")])
4790 ;; Emit a .cprestore directive, which normally expands to a single store
4791 ;; instruction. Note that we continue to use .cprestore for explicit reloc
4792 ;; code so that jals inside inline asms will work correctly.
4793 (define_insn "cprestore"
4794 [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
4798 if (set_nomacro && which_alternative == 1)
4799 return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4801 return ".cprestore\t%0";
4803 [(set_attr "type" "store")
4804 (set_attr "length" "4,12")])
4806 ;; Block moves, see mips.c for more details.
4807 ;; Argument 0 is the destination
4808 ;; Argument 1 is the source
4809 ;; Argument 2 is the length
4810 ;; Argument 3 is the alignment
4812 (define_expand "movmemsi"
4813 [(parallel [(set (match_operand:BLK 0 "general_operand")
4814 (match_operand:BLK 1 "general_operand"))
4815 (use (match_operand:SI 2 ""))
4816 (use (match_operand:SI 3 "const_int_operand"))])]
4817 "!TARGET_MIPS16 && !TARGET_MEMCPY"
4819 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4826 ;; ....................
4830 ;; ....................
4832 ;; Many of these instructions use trivial define_expands, because we
4833 ;; want to use a different set of constraints when TARGET_MIPS16.
4835 (define_expand "ashlsi3"
4836 [(set (match_operand:SI 0 "register_operand")
4837 (ashift:SI (match_operand:SI 1 "register_operand")
4838 (match_operand:SI 2 "arith_operand")))]
4841 /* On the mips16, a shift of more than 8 is a four byte instruction,
4842 so, for a shift between 8 and 16, it is just as fast to do two
4843 shifts of 8 or less. If there is a lot of shifting going on, we
4844 may win in CSE. Otherwise combine will put the shifts back
4845 together again. This can be called by function_arg, so we must
4846 be careful not to allocate a new register if we've reached the
4850 && GET_CODE (operands[2]) == CONST_INT
4851 && INTVAL (operands[2]) > 8
4852 && INTVAL (operands[2]) <= 16
4853 && ! reload_in_progress
4854 && ! reload_completed)
4856 rtx temp = gen_reg_rtx (SImode);
4858 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
4859 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
4860 GEN_INT (INTVAL (operands[2]) - 8)));
4865 (define_insn "ashlsi3_internal1"
4866 [(set (match_operand:SI 0 "register_operand" "=d")
4867 (ashift:SI (match_operand:SI 1 "register_operand" "d")
4868 (match_operand:SI 2 "arith_operand" "dI")))]
4871 if (GET_CODE (operands[2]) == CONST_INT)
4872 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4874 return "sll\t%0,%1,%2";
4876 [(set_attr "type" "shift")
4877 (set_attr "mode" "SI")])
4879 (define_insn "ashlsi3_internal1_extend"
4880 [(set (match_operand:DI 0 "register_operand" "=d")
4881 (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
4882 (match_operand:SI 2 "arith_operand" "dI"))))]
4883 "TARGET_64BIT && !TARGET_MIPS16"
4885 if (GET_CODE (operands[2]) == CONST_INT)
4886 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4888 return "sll\t%0,%1,%2";
4890 [(set_attr "type" "shift")
4891 (set_attr "mode" "DI")])
4894 (define_insn "ashlsi3_internal2"
4895 [(set (match_operand:SI 0 "register_operand" "=d,d")
4896 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
4897 (match_operand:SI 2 "arith_operand" "d,I")))]
4900 if (which_alternative == 0)
4901 return "sll\t%0,%2";
4903 if (GET_CODE (operands[2]) == CONST_INT)
4904 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4906 return "sll\t%0,%1,%2";
4908 [(set_attr "type" "shift")
4909 (set_attr "mode" "SI")
4910 (set_attr_alternative "length"
4912 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4916 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4919 [(set (match_operand:SI 0 "register_operand")
4920 (ashift:SI (match_operand:SI 1 "register_operand")
4921 (match_operand:SI 2 "const_int_operand")))]
4922 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4923 && GET_CODE (operands[2]) == CONST_INT
4924 && INTVAL (operands[2]) > 8
4925 && INTVAL (operands[2]) <= 16"
4926 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
4927 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4928 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4930 (define_expand "ashldi3"
4931 [(set (match_operand:DI 0 "register_operand")
4932 (ashift:DI (match_operand:DI 1 "register_operand")
4933 (match_operand:SI 2 "arith_operand")))]
4936 /* On the mips16, a shift of more than 8 is a four byte
4937 instruction, so, for a shift between 8 and 16, it is just as
4938 fast to do two shifts of 8 or less. If there is a lot of
4939 shifting going on, we may win in CSE. Otherwise combine will
4940 put the shifts back together again. This can be called by
4941 function_arg, so we must be careful not to allocate a new
4942 register if we've reached the reload pass. */
4945 && GET_CODE (operands[2]) == CONST_INT
4946 && INTVAL (operands[2]) > 8
4947 && INTVAL (operands[2]) <= 16
4948 && ! reload_in_progress
4949 && ! reload_completed)
4951 rtx temp = gen_reg_rtx (DImode);
4953 emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
4954 emit_insn (gen_ashldi3_internal (operands[0], temp,
4955 GEN_INT (INTVAL (operands[2]) - 8)));
4961 (define_insn "ashldi3_internal"
4962 [(set (match_operand:DI 0 "register_operand" "=d")
4963 (ashift:DI (match_operand:DI 1 "register_operand" "d")
4964 (match_operand:SI 2 "arith_operand" "dI")))]
4965 "TARGET_64BIT && !TARGET_MIPS16"
4967 if (GET_CODE (operands[2]) == CONST_INT)
4968 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4970 return "dsll\t%0,%1,%2";
4972 [(set_attr "type" "shift")
4973 (set_attr "mode" "DI")])
4976 [(set (match_operand:DI 0 "register_operand" "=d,d")
4977 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4978 (match_operand:SI 2 "arith_operand" "d,I")))]
4979 "TARGET_64BIT && TARGET_MIPS16"
4981 if (which_alternative == 0)
4982 return "dsll\t%0,%2";
4984 if (GET_CODE (operands[2]) == CONST_INT)
4985 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4987 return "dsll\t%0,%1,%2";
4989 [(set_attr "type" "shift")
4990 (set_attr "mode" "DI")
4991 (set_attr_alternative "length"
4993 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4998 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5001 [(set (match_operand:DI 0 "register_operand")
5002 (ashift:DI (match_operand:DI 1 "register_operand")
5003 (match_operand:SI 2 "const_int_operand")))]
5004 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5006 && GET_CODE (operands[2]) == CONST_INT
5007 && INTVAL (operands[2]) > 8
5008 && INTVAL (operands[2]) <= 16"
5009 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
5010 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
5011 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5013 (define_expand "ashrsi3"
5014 [(set (match_operand:SI 0 "register_operand")
5015 (ashiftrt:SI (match_operand:SI 1 "register_operand")
5016 (match_operand:SI 2 "arith_operand")))]
5019 /* On the mips16, a shift of more than 8 is a four byte instruction,
5020 so, for a shift between 8 and 16, it is just as fast to do two
5021 shifts of 8 or less. If there is a lot of shifting going on, we
5022 may win in CSE. Otherwise combine will put the shifts back
5026 && GET_CODE (operands[2]) == CONST_INT
5027 && INTVAL (operands[2]) > 8
5028 && INTVAL (operands[2]) <= 16)
5030 rtx temp = gen_reg_rtx (SImode);
5032 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5033 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
5034 GEN_INT (INTVAL (operands[2]) - 8)));
5039 (define_insn "ashrsi3_internal1"
5040 [(set (match_operand:SI 0 "register_operand" "=d")
5041 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
5042 (match_operand:SI 2 "arith_operand" "dI")))]
5045 if (GET_CODE (operands[2]) == CONST_INT)
5046 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5048 return "sra\t%0,%1,%2";
5050 [(set_attr "type" "shift")
5051 (set_attr "mode" "SI")])
5053 (define_insn "ashrsi3_internal2"
5054 [(set (match_operand:SI 0 "register_operand" "=d,d")
5055 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5056 (match_operand:SI 2 "arith_operand" "d,I")))]
5059 if (which_alternative == 0)
5060 return "sra\t%0,%2";
5062 if (GET_CODE (operands[2]) == CONST_INT)
5063 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5065 return "sra\t%0,%1,%2";
5067 [(set_attr "type" "shift")
5068 (set_attr "mode" "SI")
5069 (set_attr_alternative "length"
5071 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5076 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5079 [(set (match_operand:SI 0 "register_operand")
5080 (ashiftrt:SI (match_operand:SI 1 "register_operand")
5081 (match_operand:SI 2 "const_int_operand")))]
5082 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5083 && GET_CODE (operands[2]) == CONST_INT
5084 && INTVAL (operands[2]) > 8
5085 && INTVAL (operands[2]) <= 16"
5086 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
5087 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
5088 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5090 (define_expand "ashrdi3"
5091 [(set (match_operand:DI 0 "register_operand")
5092 (ashiftrt:DI (match_operand:DI 1 "register_operand")
5093 (match_operand:SI 2 "arith_operand")))]
5096 /* On the mips16, a shift of more than 8 is a four byte
5097 instruction, so, for a shift between 8 and 16, it is just as
5098 fast to do two shifts of 8 or less. If there is a lot of
5099 shifting going on, we may win in CSE. Otherwise combine will
5100 put the shifts back together again. */
5103 && GET_CODE (operands[2]) == CONST_INT
5104 && INTVAL (operands[2]) > 8
5105 && INTVAL (operands[2]) <= 16)
5107 rtx temp = gen_reg_rtx (DImode);
5109 emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
5110 emit_insn (gen_ashrdi3_internal (operands[0], temp,
5111 GEN_INT (INTVAL (operands[2]) - 8)));
5117 (define_insn "ashrdi3_internal"
5118 [(set (match_operand:DI 0 "register_operand" "=d")
5119 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5120 (match_operand:SI 2 "arith_operand" "dI")))]
5121 "TARGET_64BIT && !TARGET_MIPS16"
5123 if (GET_CODE (operands[2]) == CONST_INT)
5124 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5126 return "dsra\t%0,%1,%2";
5128 [(set_attr "type" "shift")
5129 (set_attr "mode" "DI")])
5132 [(set (match_operand:DI 0 "register_operand" "=d,d")
5133 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5134 (match_operand:SI 2 "arith_operand" "d,I")))]
5135 "TARGET_64BIT && TARGET_MIPS16"
5137 if (GET_CODE (operands[2]) == CONST_INT)
5138 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5140 return "dsra\t%0,%2";
5142 [(set_attr "type" "shift")
5143 (set_attr "mode" "DI")
5144 (set_attr_alternative "length"
5146 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5150 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5153 [(set (match_operand:DI 0 "register_operand")
5154 (ashiftrt:DI (match_operand:DI 1 "register_operand")
5155 (match_operand:SI 2 "const_int_operand")))]
5156 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5158 && GET_CODE (operands[2]) == CONST_INT
5159 && INTVAL (operands[2]) > 8
5160 && INTVAL (operands[2]) <= 16"
5161 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
5162 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
5163 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5165 (define_expand "lshrsi3"
5166 [(set (match_operand:SI 0 "register_operand")
5167 (lshiftrt:SI (match_operand:SI 1 "register_operand")
5168 (match_operand:SI 2 "arith_operand")))]
5171 /* On the mips16, a shift of more than 8 is a four byte instruction,
5172 so, for a shift between 8 and 16, it is just as fast to do two
5173 shifts of 8 or less. If there is a lot of shifting going on, we
5174 may win in CSE. Otherwise combine will put the shifts back
5178 && GET_CODE (operands[2]) == CONST_INT
5179 && INTVAL (operands[2]) > 8
5180 && INTVAL (operands[2]) <= 16)
5182 rtx temp = gen_reg_rtx (SImode);
5184 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5185 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
5186 GEN_INT (INTVAL (operands[2]) - 8)));
5191 (define_insn "lshrsi3_internal1"
5192 [(set (match_operand:SI 0 "register_operand" "=d")
5193 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
5194 (match_operand:SI 2 "arith_operand" "dI")))]
5197 if (GET_CODE (operands[2]) == CONST_INT)
5198 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5200 return "srl\t%0,%1,%2";
5202 [(set_attr "type" "shift")
5203 (set_attr "mode" "SI")])
5205 (define_insn "lshrsi3_internal2"
5206 [(set (match_operand:SI 0 "register_operand" "=d,d")
5207 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5208 (match_operand:SI 2 "arith_operand" "d,I")))]
5211 if (which_alternative == 0)
5212 return "srl\t%0,%2";
5214 if (GET_CODE (operands[2]) == CONST_INT)
5215 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5217 return "srl\t%0,%1,%2";
5219 [(set_attr "type" "shift")
5220 (set_attr "mode" "SI")
5221 (set_attr_alternative "length"
5223 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5228 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5231 [(set (match_operand:SI 0 "register_operand")
5232 (lshiftrt:SI (match_operand:SI 1 "register_operand")
5233 (match_operand:SI 2 "const_int_operand")))]
5234 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5235 && GET_CODE (operands[2]) == CONST_INT
5236 && INTVAL (operands[2]) > 8
5237 && INTVAL (operands[2]) <= 16"
5238 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
5239 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5240 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5242 ;; If we load a byte on the mips16 as a bitfield, the resulting
5243 ;; sequence of instructions is too complicated for combine, because it
5244 ;; involves four instructions: a load, a shift, a constant load into a
5245 ;; register, and an and (the key problem here is that the mips16 does
5246 ;; not have and immediate). We recognize a shift of a load in order
5247 ;; to make it simple enough for combine to understand.
5249 ;; The length here is the worst case: the length of the split version
5250 ;; will be more accurate.
5251 (define_insn_and_split ""
5252 [(set (match_operand:SI 0 "register_operand" "=d")
5253 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5254 (match_operand:SI 2 "immediate_operand" "I")))]
5258 [(set (match_dup 0) (match_dup 1))
5259 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5261 [(set_attr "type" "load")
5262 (set_attr "mode" "SI")
5263 (set_attr "length" "16")])
5265 (define_expand "lshrdi3"
5266 [(set (match_operand:DI 0 "register_operand")
5267 (lshiftrt:DI (match_operand:DI 1 "register_operand")
5268 (match_operand:SI 2 "arith_operand")))]
5271 /* On the mips16, a shift of more than 8 is a four byte
5272 instruction, so, for a shift between 8 and 16, it is just as
5273 fast to do two shifts of 8 or less. If there is a lot of
5274 shifting going on, we may win in CSE. Otherwise combine will
5275 put the shifts back together again. */
5278 && GET_CODE (operands[2]) == CONST_INT
5279 && INTVAL (operands[2]) > 8
5280 && INTVAL (operands[2]) <= 16)
5282 rtx temp = gen_reg_rtx (DImode);
5284 emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
5285 emit_insn (gen_lshrdi3_internal (operands[0], temp,
5286 GEN_INT (INTVAL (operands[2]) - 8)));
5292 (define_insn "lshrdi3_internal"
5293 [(set (match_operand:DI 0 "register_operand" "=d")
5294 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
5295 (match_operand:SI 2 "arith_operand" "dI")))]
5296 "TARGET_64BIT && !TARGET_MIPS16"
5298 if (GET_CODE (operands[2]) == CONST_INT)
5299 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5301 return "dsrl\t%0,%1,%2";
5303 [(set_attr "type" "shift")
5304 (set_attr "mode" "DI")])
5307 [(set (match_operand:DI 0 "register_operand" "=d,d")
5308 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5309 (match_operand:SI 2 "arith_operand" "d,I")))]
5310 "TARGET_64BIT && TARGET_MIPS16"
5312 if (GET_CODE (operands[2]) == CONST_INT)
5313 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5315 return "dsrl\t%0,%2";
5317 [(set_attr "type" "shift")
5318 (set_attr "mode" "DI")
5319 (set_attr_alternative "length"
5321 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5325 (define_insn "rotrsi3"
5326 [(set (match_operand:SI 0 "register_operand" "=d")
5327 (rotatert:SI (match_operand:SI 1 "register_operand" "d")
5328 (match_operand:SI 2 "arith_operand" "dn")))]
5331 if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
5332 return "rorv\t%0,%1,%2";
5334 if ((GET_CODE (operands[2]) == CONST_INT)
5335 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
5338 return "ror\t%0,%1,%2";
5340 [(set_attr "type" "shift")
5341 (set_attr "mode" "SI")])
5343 (define_insn "rotrdi3"
5344 [(set (match_operand:DI 0 "register_operand" "=d")
5345 (rotatert:DI (match_operand:DI 1 "register_operand" "d")
5346 (match_operand:DI 2 "arith_operand" "dn")))]
5351 if (GET_CODE (operands[2]) != CONST_INT)
5352 return "drorv\t%0,%1,%2";
5354 if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
5355 return "dror32\t%0,%1,%2";
5358 if ((GET_CODE (operands[2]) == CONST_INT)
5359 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
5362 return "dror\t%0,%1,%2";
5364 [(set_attr "type" "shift")
5365 (set_attr "mode" "DI")])
5368 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5371 [(set (match_operand:DI 0 "register_operand")
5372 (lshiftrt:DI (match_operand:DI 1 "register_operand")
5373 (match_operand:SI 2 "const_int_operand")))]
5374 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5375 && GET_CODE (operands[2]) == CONST_INT
5376 && INTVAL (operands[2]) > 8
5377 && INTVAL (operands[2]) <= 16"
5378 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
5379 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
5380 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5383 ;; ....................
5387 ;; ....................
5389 ;; Flow here is rather complex:
5391 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the arguments
5392 ;; into cmp_operands[] but generates no RTL.
5394 ;; 2) The appropriate branch define_expand is called, which then
5395 ;; creates the appropriate RTL for the comparison and branch.
5396 ;; Different CC modes are used, based on what type of branch is
5397 ;; done, so that we can constrain things appropriately. There
5398 ;; are assumptions in the rest of GCC that break if we fold the
5399 ;; operands into the branches for integer operations, and use cc0
5400 ;; for floating point, so we use the fp status register instead.
5401 ;; If needed, an appropriate temporary is created to hold the
5402 ;; of the integer compare.
5404 (define_expand "cmpsi"
5406 (compare:CC (match_operand:SI 0 "register_operand")
5407 (match_operand:SI 1 "nonmemory_operand")))]
5410 cmp_operands[0] = operands[0];
5411 cmp_operands[1] = operands[1];
5415 (define_expand "cmpdi"
5417 (compare:CC (match_operand:DI 0 "register_operand")
5418 (match_operand:DI 1 "nonmemory_operand")))]
5421 cmp_operands[0] = operands[0];
5422 cmp_operands[1] = operands[1];
5426 (define_expand "cmpdf"
5428 (compare:CC (match_operand:DF 0 "register_operand")
5429 (match_operand:DF 1 "register_operand")))]
5430 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5432 cmp_operands[0] = operands[0];
5433 cmp_operands[1] = operands[1];
5437 (define_expand "cmpsf"
5439 (compare:CC (match_operand:SF 0 "register_operand")
5440 (match_operand:SF 1 "register_operand")))]
5443 cmp_operands[0] = operands[0];
5444 cmp_operands[1] = operands[1];
5449 ;; ....................
5451 ;; CONDITIONAL BRANCHES
5453 ;; ....................
5455 ;; Conditional branches on floating-point equality tests.
5457 (define_insn "branch_fp"
5460 (match_operator:CC 0 "cmp_op"
5461 [(match_operand:CC 2 "register_operand" "z")
5463 (label_ref (match_operand 1 "" ""))
5467 return mips_output_conditional_branch (insn,
5469 /*two_operands_p=*/0,
5472 get_attr_length (insn));
5474 [(set_attr "type" "branch")
5475 (set_attr "mode" "none")])
5477 (define_insn "branch_fp_inverted"
5480 (match_operator:CC 0 "cmp_op"
5481 [(match_operand:CC 2 "register_operand" "z")
5484 (label_ref (match_operand 1 "" ""))))]
5487 return mips_output_conditional_branch (insn,
5489 /*two_operands_p=*/0,
5492 get_attr_length (insn));
5494 [(set_attr "type" "branch")
5495 (set_attr "mode" "none")])
5497 ;; Conditional branches on comparisons with zero.
5499 (define_insn "branch_zero"
5502 (match_operator:SI 0 "cmp_op"
5503 [(match_operand:SI 2 "register_operand" "d")
5505 (label_ref (match_operand 1 "" ""))
5509 return mips_output_conditional_branch (insn,
5511 /*two_operands_p=*/0,
5514 get_attr_length (insn));
5516 [(set_attr "type" "branch")
5517 (set_attr "mode" "none")])
5519 (define_insn "branch_zero_inverted"
5522 (match_operator:SI 0 "cmp_op"
5523 [(match_operand:SI 2 "register_operand" "d")
5526 (label_ref (match_operand 1 "" ""))))]
5529 return mips_output_conditional_branch (insn,
5531 /*two_operands_p=*/0,
5534 get_attr_length (insn));
5536 [(set_attr "type" "branch")
5537 (set_attr "mode" "none")])
5539 (define_insn "branch_zero_di"
5542 (match_operator:DI 0 "cmp_op"
5543 [(match_operand:DI 2 "register_operand" "d")
5545 (label_ref (match_operand 1 "" ""))
5549 return mips_output_conditional_branch (insn,
5551 /*two_operands_p=*/0,
5554 get_attr_length (insn));
5556 [(set_attr "type" "branch")
5557 (set_attr "mode" "none")])
5559 (define_insn "branch_zero_di_inverted"
5562 (match_operator:DI 0 "cmp_op"
5563 [(match_operand:DI 2 "register_operand" "d")
5566 (label_ref (match_operand 1 "" ""))))]
5569 return mips_output_conditional_branch (insn,
5571 /*two_operands_p=*/0,
5574 get_attr_length (insn));
5576 [(set_attr "type" "branch")
5577 (set_attr "mode" "none")])
5579 ;; Conditional branch on equality comparison.
5581 (define_insn "branch_equality"
5584 (match_operator:SI 0 "equality_op"
5585 [(match_operand:SI 2 "register_operand" "d")
5586 (match_operand:SI 3 "register_operand" "d")])
5587 (label_ref (match_operand 1 "" ""))
5591 return mips_output_conditional_branch (insn,
5593 /*two_operands_p=*/1,
5596 get_attr_length (insn));
5598 [(set_attr "type" "branch")
5599 (set_attr "mode" "none")])
5601 (define_insn "branch_equality_di"
5604 (match_operator:DI 0 "equality_op"
5605 [(match_operand:DI 2 "register_operand" "d")
5606 (match_operand:DI 3 "register_operand" "d")])
5607 (label_ref (match_operand 1 "" ""))
5611 return mips_output_conditional_branch (insn,
5613 /*two_operands_p=*/1,
5616 get_attr_length (insn));
5618 [(set_attr "type" "branch")
5619 (set_attr "mode" "none")])
5621 (define_insn "branch_equality_inverted"
5624 (match_operator:SI 0 "equality_op"
5625 [(match_operand:SI 2 "register_operand" "d")
5626 (match_operand:SI 3 "register_operand" "d")])
5628 (label_ref (match_operand 1 "" ""))))]
5631 return mips_output_conditional_branch (insn,
5633 /*two_operands_p=*/1,
5636 get_attr_length (insn));
5638 [(set_attr "type" "branch")
5639 (set_attr "mode" "none")])
5641 (define_insn "branch_equality_di_inverted"
5644 (match_operator:DI 0 "equality_op"
5645 [(match_operand:DI 2 "register_operand" "d")
5646 (match_operand:DI 3 "register_operand" "d")])
5648 (label_ref (match_operand 1 "" ""))))]
5651 return mips_output_conditional_branch (insn,
5653 /*two_operands_p=*/1,
5656 get_attr_length (insn));
5658 [(set_attr "type" "branch")
5659 (set_attr "mode" "none")])
5665 (if_then_else (match_operator:SI 0 "equality_op"
5666 [(match_operand:SI 1 "register_operand" "d,t")
5668 (match_operand 2 "pc_or_label_operand" "")
5669 (match_operand 3 "pc_or_label_operand" "")))]
5672 if (operands[2] != pc_rtx)
5674 if (which_alternative == 0)
5675 return "b%C0z\t%1,%2";
5677 return "bt%C0z\t%2";
5681 if (which_alternative == 0)
5682 return "b%N0z\t%1,%3";
5684 return "bt%N0z\t%3";
5687 [(set_attr "type" "branch")
5688 (set_attr "mode" "none")
5689 (set_attr "length" "8")])
5693 (if_then_else (match_operator:DI 0 "equality_op"
5694 [(match_operand:DI 1 "register_operand" "d,t")
5696 (match_operand 2 "pc_or_label_operand" "")
5697 (match_operand 3 "pc_or_label_operand" "")))]
5700 if (operands[2] != pc_rtx)
5702 if (which_alternative == 0)
5703 return "b%C0z\t%1,%2";
5705 return "bt%C0z\t%2";
5709 if (which_alternative == 0)
5710 return "b%N0z\t%1,%3";
5712 return "bt%N0z\t%3";
5715 [(set_attr "type" "branch")
5716 (set_attr "mode" "none")
5717 (set_attr "length" "8")])
5719 (define_expand "bunordered"
5721 (if_then_else (unordered:CC (cc0)
5723 (label_ref (match_operand 0 ""))
5727 gen_conditional_branch (operands, UNORDERED);
5731 (define_expand "bordered"
5733 (if_then_else (ordered:CC (cc0)
5735 (label_ref (match_operand 0 ""))
5739 gen_conditional_branch (operands, ORDERED);
5743 (define_expand "bunlt"
5745 (if_then_else (unlt:CC (cc0)
5747 (label_ref (match_operand 0 ""))
5751 gen_conditional_branch (operands, UNLT);
5755 (define_expand "bunge"
5757 (if_then_else (unge:CC (cc0)
5759 (label_ref (match_operand 0 ""))
5763 gen_conditional_branch (operands, UNGE);
5767 (define_expand "buneq"
5769 (if_then_else (uneq:CC (cc0)
5771 (label_ref (match_operand 0 ""))
5775 gen_conditional_branch (operands, UNEQ);
5779 (define_expand "bltgt"
5781 (if_then_else (ltgt:CC (cc0)
5783 (label_ref (match_operand 0 ""))
5787 gen_conditional_branch (operands, LTGT);
5791 (define_expand "bunle"
5793 (if_then_else (unle:CC (cc0)
5795 (label_ref (match_operand 0 ""))
5799 gen_conditional_branch (operands, UNLE);
5803 (define_expand "bungt"
5805 (if_then_else (ungt:CC (cc0)
5807 (label_ref (match_operand 0 ""))
5811 gen_conditional_branch (operands, UNGT);
5815 (define_expand "beq"
5817 (if_then_else (eq:CC (cc0)
5819 (label_ref (match_operand 0 ""))
5823 gen_conditional_branch (operands, EQ);
5827 (define_expand "bne"
5829 (if_then_else (ne:CC (cc0)
5831 (label_ref (match_operand 0 ""))
5835 gen_conditional_branch (operands, NE);
5839 (define_expand "bgt"
5841 (if_then_else (gt:CC (cc0)
5843 (label_ref (match_operand 0 ""))
5847 gen_conditional_branch (operands, GT);
5851 (define_expand "bge"
5853 (if_then_else (ge:CC (cc0)
5855 (label_ref (match_operand 0 ""))
5859 gen_conditional_branch (operands, GE);
5863 (define_expand "blt"
5865 (if_then_else (lt:CC (cc0)
5867 (label_ref (match_operand 0 ""))
5871 gen_conditional_branch (operands, LT);
5875 (define_expand "ble"
5877 (if_then_else (le:CC (cc0)
5879 (label_ref (match_operand 0 ""))
5883 gen_conditional_branch (operands, LE);
5887 (define_expand "bgtu"
5889 (if_then_else (gtu:CC (cc0)
5891 (label_ref (match_operand 0 ""))
5895 gen_conditional_branch (operands, GTU);
5899 (define_expand "bgeu"
5901 (if_then_else (geu:CC (cc0)
5903 (label_ref (match_operand 0 ""))
5907 gen_conditional_branch (operands, GEU);
5911 (define_expand "bltu"
5913 (if_then_else (ltu:CC (cc0)
5915 (label_ref (match_operand 0 ""))
5919 gen_conditional_branch (operands, LTU);
5923 (define_expand "bleu"
5925 (if_then_else (leu:CC (cc0)
5927 (label_ref (match_operand 0 ""))
5931 gen_conditional_branch (operands, LEU);
5936 ;; ....................
5938 ;; SETTING A REGISTER FROM A COMPARISON
5940 ;; ....................
5942 (define_expand "seq"
5943 [(set (match_operand:SI 0 "register_operand")
5944 (eq:SI (match_dup 1)
5947 { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
5949 (define_insn "*seq_si"
5950 [(set (match_operand:SI 0 "register_operand" "=d")
5951 (eq:SI (match_operand:SI 1 "register_operand" "d")
5955 [(set_attr "type" "slt")
5956 (set_attr "mode" "SI")])
5958 (define_insn "*seq_si_mips16"
5959 [(set (match_operand:SI 0 "register_operand" "=t")
5960 (eq:SI (match_operand:SI 1 "register_operand" "d")
5964 [(set_attr "type" "slt")
5965 (set_attr "mode" "SI")])
5967 (define_insn "*seq_di"
5968 [(set (match_operand:DI 0 "register_operand" "=d")
5969 (eq:DI (match_operand:DI 1 "register_operand" "d")
5971 "TARGET_64BIT && !TARGET_MIPS16"
5973 [(set_attr "type" "slt")
5974 (set_attr "mode" "DI")])
5976 (define_insn "*seq_di_mips16"
5977 [(set (match_operand:DI 0 "register_operand" "=t")
5978 (eq:DI (match_operand:DI 1 "register_operand" "d")
5980 "TARGET_64BIT && TARGET_MIPS16"
5982 [(set_attr "type" "slt")
5983 (set_attr "mode" "DI")])
5985 ;; "sne" uses sltu instructions in which the first operand is $0.
5986 ;; This isn't possible in mips16 code.
5988 (define_expand "sne"
5989 [(set (match_operand:SI 0 "register_operand")
5990 (ne:SI (match_dup 1)
5993 { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
5995 (define_insn "*sne_si"
5996 [(set (match_operand:SI 0 "register_operand" "=d")
5997 (ne:SI (match_operand:SI 1 "register_operand" "d")
6001 [(set_attr "type" "slt")
6002 (set_attr "mode" "SI")])
6004 (define_insn "*sne_di"
6005 [(set (match_operand:DI 0 "register_operand" "=d")
6006 (ne:DI (match_operand:DI 1 "register_operand" "d")
6008 "TARGET_64BIT && !TARGET_MIPS16"
6010 [(set_attr "type" "slt")
6011 (set_attr "mode" "DI")])
6013 (define_expand "sgt"
6014 [(set (match_operand:SI 0 "register_operand")
6015 (gt:SI (match_dup 1)
6018 { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
6020 (define_insn "*sgt_si"
6021 [(set (match_operand:SI 0 "register_operand" "=d")
6022 (gt:SI (match_operand:SI 1 "register_operand" "d")
6023 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6026 [(set_attr "type" "slt")
6027 (set_attr "mode" "SI")])
6029 (define_insn "*sgt_si_mips16"
6030 [(set (match_operand:SI 0 "register_operand" "=t")
6031 (gt:SI (match_operand:SI 1 "register_operand" "d")
6032 (match_operand:SI 2 "register_operand" "d")))]
6035 [(set_attr "type" "slt")
6036 (set_attr "mode" "SI")])
6038 (define_insn "*sgt_di"
6039 [(set (match_operand:DI 0 "register_operand" "=d")
6040 (gt:DI (match_operand:DI 1 "register_operand" "d")
6041 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6042 "TARGET_64BIT && !TARGET_MIPS16"
6044 [(set_attr "type" "slt")
6045 (set_attr "mode" "DI")])
6047 (define_insn "*sgt_di_mips16"
6048 [(set (match_operand:DI 0 "register_operand" "=t")
6049 (gt:DI (match_operand:DI 1 "register_operand" "d")
6050 (match_operand:DI 2 "register_operand" "d")))]
6051 "TARGET_64BIT && TARGET_MIPS16"
6053 [(set_attr "type" "slt")
6054 (set_attr "mode" "DI")])
6056 (define_expand "sge"
6057 [(set (match_operand:SI 0 "register_operand")
6058 (ge:SI (match_dup 1)
6061 { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
6063 (define_insn "*sge_si"
6064 [(set (match_operand:SI 0 "register_operand" "=d")
6065 (ge:SI (match_operand:SI 1 "register_operand" "d")
6069 [(set_attr "type" "slt")
6070 (set_attr "mode" "SI")])
6072 (define_insn "*sge_di"
6073 [(set (match_operand:DI 0 "register_operand" "=d")
6074 (ge:DI (match_operand:DI 1 "register_operand" "d")
6076 "TARGET_64BIT && !TARGET_MIPS16"
6078 [(set_attr "type" "slt")
6079 (set_attr "mode" "DI")])
6081 (define_expand "slt"
6082 [(set (match_operand:SI 0 "register_operand")
6083 (lt:SI (match_dup 1)
6086 { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
6088 (define_insn "*slt_si"
6089 [(set (match_operand:SI 0 "register_operand" "=d")
6090 (lt:SI (match_operand:SI 1 "register_operand" "d")
6091 (match_operand:SI 2 "arith_operand" "dI")))]
6094 [(set_attr "type" "slt")
6095 (set_attr "mode" "SI")])
6097 (define_insn "*slt_si_mips16"
6098 [(set (match_operand:SI 0 "register_operand" "=t,t")
6099 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
6100 (match_operand:SI 2 "arith_operand" "d,I")))]
6103 [(set_attr "type" "slt")
6104 (set_attr "mode" "SI")
6105 (set_attr_alternative "length"
6107 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6111 (define_insn "*slt_di"
6112 [(set (match_operand:DI 0 "register_operand" "=d")
6113 (lt:DI (match_operand:DI 1 "register_operand" "d")
6114 (match_operand:DI 2 "arith_operand" "dI")))]
6115 "TARGET_64BIT && !TARGET_MIPS16"
6117 [(set_attr "type" "slt")
6118 (set_attr "mode" "DI")])
6120 (define_insn "*slt_di_mips16"
6121 [(set (match_operand:DI 0 "register_operand" "=t,t")
6122 (lt:DI (match_operand:DI 1 "register_operand" "d,d")
6123 (match_operand:DI 2 "arith_operand" "d,I")))]
6124 "TARGET_64BIT && TARGET_MIPS16"
6126 [(set_attr "type" "slt")
6127 (set_attr "mode" "DI")
6128 (set_attr_alternative "length"
6130 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6134 (define_expand "sle"
6135 [(set (match_operand:SI 0 "register_operand")
6136 (le:SI (match_dup 1)
6139 { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
6141 (define_insn "*sle_si"
6142 [(set (match_operand:SI 0 "register_operand" "=d")
6143 (le:SI (match_operand:SI 1 "register_operand" "d")
6144 (match_operand:SI 2 "sle_operand" "")))]
6147 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6148 return "slt\t%0,%1,%2";
6150 [(set_attr "type" "slt")
6151 (set_attr "mode" "SI")])
6153 (define_insn "*sle_si_mips16"
6154 [(set (match_operand:SI 0 "register_operand" "=t")
6155 (le:SI (match_operand:SI 1 "register_operand" "d")
6156 (match_operand:SI 2 "sle_operand" "")))]
6159 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6160 return "slt\t%1,%2";
6162 [(set_attr "type" "slt")
6163 (set_attr "mode" "SI")
6164 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6168 (define_insn "*sle_di"
6169 [(set (match_operand:DI 0 "register_operand" "=d")
6170 (le:DI (match_operand:DI 1 "register_operand" "d")
6171 (match_operand:DI 2 "sle_operand" "")))]
6172 "TARGET_64BIT && !TARGET_MIPS16"
6174 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6175 return "slt\t%0,%1,%2";
6177 [(set_attr "type" "slt")
6178 (set_attr "mode" "DI")])
6180 (define_insn "*sle_di_mips16"
6181 [(set (match_operand:DI 0 "register_operand" "=t")
6182 (le:DI (match_operand:DI 1 "register_operand" "d")
6183 (match_operand:DI 2 "sle_operand" "")))]
6184 "TARGET_64BIT && TARGET_MIPS16"
6186 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6187 return "slt\t%1,%2";
6189 [(set_attr "type" "slt")
6190 (set_attr "mode" "DI")
6191 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6195 (define_expand "sgtu"
6196 [(set (match_operand:SI 0 "register_operand")
6197 (gtu:SI (match_dup 1)
6200 { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
6202 (define_insn "*sgtu_si"
6203 [(set (match_operand:SI 0 "register_operand" "=d")
6204 (gtu:SI (match_operand:SI 1 "register_operand" "d")
6205 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6208 [(set_attr "type" "slt")
6209 (set_attr "mode" "SI")])
6211 (define_insn "*sgtu_si_mips16"
6212 [(set (match_operand:SI 0 "register_operand" "=t")
6213 (gtu:SI (match_operand:SI 1 "register_operand" "d")
6214 (match_operand:SI 2 "register_operand" "d")))]
6217 [(set_attr "type" "slt")
6218 (set_attr "mode" "SI")])
6220 (define_insn "*sgtu_di"
6221 [(set (match_operand:DI 0 "register_operand" "=d")
6222 (gtu:DI (match_operand:DI 1 "register_operand" "d")
6223 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6224 "TARGET_64BIT && !TARGET_MIPS16"
6226 [(set_attr "type" "slt")
6227 (set_attr "mode" "DI")])
6229 (define_insn "*sgtu_di_mips16"
6230 [(set (match_operand:DI 0 "register_operand" "=t")
6231 (gtu:DI (match_operand:DI 1 "register_operand" "d")
6232 (match_operand:DI 2 "register_operand" "d")))]
6233 "TARGET_64BIT && TARGET_MIPS16"
6235 [(set_attr "type" "slt")
6236 (set_attr "mode" "DI")])
6238 (define_expand "sgeu"
6239 [(set (match_operand:SI 0 "register_operand")
6240 (geu:SI (match_dup 1)
6243 { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
6245 (define_insn "*sge_si"
6246 [(set (match_operand:SI 0 "register_operand" "=d")
6247 (geu:SI (match_operand:SI 1 "register_operand" "d")
6251 [(set_attr "type" "slt")
6252 (set_attr "mode" "SI")])
6254 (define_insn "*sge_di"
6255 [(set (match_operand:DI 0 "register_operand" "=d")
6256 (geu:DI (match_operand:DI 1 "register_operand" "d")
6258 "TARGET_64BIT && !TARGET_MIPS16"
6260 [(set_attr "type" "slt")
6261 (set_attr "mode" "DI")])
6263 (define_expand "sltu"
6264 [(set (match_operand:SI 0 "register_operand")
6265 (ltu:SI (match_dup 1)
6268 { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
6270 (define_insn "*sltu_si"
6271 [(set (match_operand:SI 0 "register_operand" "=d")
6272 (ltu:SI (match_operand:SI 1 "register_operand" "d")
6273 (match_operand:SI 2 "arith_operand" "dI")))]
6276 [(set_attr "type" "slt")
6277 (set_attr "mode" "SI")])
6279 (define_insn "*sltu_si_mips16"
6280 [(set (match_operand:SI 0 "register_operand" "=t,t")
6281 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
6282 (match_operand:SI 2 "arith_operand" "d,I")))]
6285 [(set_attr "type" "slt")
6286 (set_attr "mode" "SI")
6287 (set_attr_alternative "length"
6289 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6293 (define_insn "*sltu_di"
6294 [(set (match_operand:DI 0 "register_operand" "=d")
6295 (ltu:DI (match_operand:DI 1 "register_operand" "d")
6296 (match_operand:DI 2 "arith_operand" "dI")))]
6297 "TARGET_64BIT && !TARGET_MIPS16"
6299 [(set_attr "type" "slt")
6300 (set_attr "mode" "DI")])
6302 (define_insn "*sltu_di_mips16"
6303 [(set (match_operand:DI 0 "register_operand" "=t,t")
6304 (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
6305 (match_operand:DI 2 "arith_operand" "d,I")))]
6306 "TARGET_64BIT && TARGET_MIPS16"
6308 [(set_attr "type" "slt")
6309 (set_attr "mode" "DI")
6310 (set_attr_alternative "length"
6312 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6316 (define_expand "sleu"
6317 [(set (match_operand:SI 0 "register_operand")
6318 (leu:SI (match_dup 1)
6321 { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
6323 (define_insn "*sleu_si"
6324 [(set (match_operand:SI 0 "register_operand" "=d")
6325 (leu:SI (match_operand:SI 1 "register_operand" "d")
6326 (match_operand:SI 2 "sleu_operand" "")))]
6329 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6330 return "sltu\t%0,%1,%2";
6332 [(set_attr "type" "slt")
6333 (set_attr "mode" "SI")])
6335 (define_insn "*sleu_si_mips16"
6336 [(set (match_operand:SI 0 "register_operand" "=t")
6337 (leu:SI (match_operand:SI 1 "register_operand" "d")
6338 (match_operand:SI 2 "sleu_operand" "")))]
6341 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6342 return "sltu\t%1,%2";
6344 [(set_attr "type" "slt")
6345 (set_attr "mode" "SI")
6346 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6350 (define_insn "*sleu_di"
6351 [(set (match_operand:DI 0 "register_operand" "=d")
6352 (leu:DI (match_operand:DI 1 "register_operand" "d")
6353 (match_operand:DI 2 "sleu_operand" "")))]
6354 "TARGET_64BIT && !TARGET_MIPS16"
6356 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6357 return "sltu\t%0,%1,%2";
6359 [(set_attr "type" "slt")
6360 (set_attr "mode" "DI")])
6362 (define_insn "*sleu_di_mips16"
6363 [(set (match_operand:DI 0 "register_operand" "=t")
6364 (leu:DI (match_operand:DI 1 "register_operand" "d")
6365 (match_operand:DI 2 "sleu_operand" "")))]
6366 "TARGET_64BIT && TARGET_MIPS16"
6368 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6369 return "sltu\t%1,%2";
6371 [(set_attr "type" "slt")
6372 (set_attr "mode" "DI")
6373 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6378 ;; ....................
6380 ;; FLOATING POINT COMPARISONS
6382 ;; ....................
6384 (define_insn "sunordered_df"
6385 [(set (match_operand:CC 0 "register_operand" "=z")
6386 (unordered:CC (match_operand:DF 1 "register_operand" "f")
6387 (match_operand:DF 2 "register_operand" "f")))]
6388 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6390 [(set_attr "type" "fcmp")
6391 (set_attr "mode" "FPSW")])
6393 (define_insn "sunlt_df"
6394 [(set (match_operand:CC 0 "register_operand" "=z")
6395 (unlt:CC (match_operand:DF 1 "register_operand" "f")
6396 (match_operand:DF 2 "register_operand" "f")))]
6397 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6399 [(set_attr "type" "fcmp")
6400 (set_attr "mode" "FPSW")])
6402 (define_insn "suneq_df"
6403 [(set (match_operand:CC 0 "register_operand" "=z")
6404 (uneq:CC (match_operand:DF 1 "register_operand" "f")
6405 (match_operand:DF 2 "register_operand" "f")))]
6406 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6408 [(set_attr "type" "fcmp")
6409 (set_attr "mode" "FPSW")])
6411 (define_insn "sunle_df"
6412 [(set (match_operand:CC 0 "register_operand" "=z")
6413 (unle:CC (match_operand:DF 1 "register_operand" "f")
6414 (match_operand:DF 2 "register_operand" "f")))]
6415 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6417 [(set_attr "type" "fcmp")
6418 (set_attr "mode" "FPSW")])
6420 (define_insn "seq_df"
6421 [(set (match_operand:CC 0 "register_operand" "=z")
6422 (eq:CC (match_operand:DF 1 "register_operand" "f")
6423 (match_operand:DF 2 "register_operand" "f")))]
6424 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6426 [(set_attr "type" "fcmp")
6427 (set_attr "mode" "FPSW")])
6429 (define_insn "slt_df"
6430 [(set (match_operand:CC 0 "register_operand" "=z")
6431 (lt:CC (match_operand:DF 1 "register_operand" "f")
6432 (match_operand:DF 2 "register_operand" "f")))]
6433 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6435 [(set_attr "type" "fcmp")
6436 (set_attr "mode" "FPSW")])
6438 (define_insn "sle_df"
6439 [(set (match_operand:CC 0 "register_operand" "=z")
6440 (le:CC (match_operand:DF 1 "register_operand" "f")
6441 (match_operand:DF 2 "register_operand" "f")))]
6442 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6444 [(set_attr "type" "fcmp")
6445 (set_attr "mode" "FPSW")])
6447 (define_insn "sgt_df"
6448 [(set (match_operand:CC 0 "register_operand" "=z")
6449 (gt:CC (match_operand:DF 1 "register_operand" "f")
6450 (match_operand:DF 2 "register_operand" "f")))]
6451 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6453 [(set_attr "type" "fcmp")
6454 (set_attr "mode" "FPSW")])
6456 (define_insn "sge_df"
6457 [(set (match_operand:CC 0 "register_operand" "=z")
6458 (ge:CC (match_operand:DF 1 "register_operand" "f")
6459 (match_operand:DF 2 "register_operand" "f")))]
6460 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6462 [(set_attr "type" "fcmp")
6463 (set_attr "mode" "FPSW")])
6465 (define_insn "sunordered_sf"
6466 [(set (match_operand:CC 0 "register_operand" "=z")
6467 (unordered:CC (match_operand:SF 1 "register_operand" "f")
6468 (match_operand:SF 2 "register_operand" "f")))]
6471 [(set_attr "type" "fcmp")
6472 (set_attr "mode" "FPSW")])
6474 (define_insn "sunlt_sf"
6475 [(set (match_operand:CC 0 "register_operand" "=z")
6476 (unlt:CC (match_operand:SF 1 "register_operand" "f")
6477 (match_operand:SF 2 "register_operand" "f")))]
6480 [(set_attr "type" "fcmp")
6481 (set_attr "mode" "FPSW")])
6483 (define_insn "suneq_sf"
6484 [(set (match_operand:CC 0 "register_operand" "=z")
6485 (uneq:CC (match_operand:SF 1 "register_operand" "f")
6486 (match_operand:SF 2 "register_operand" "f")))]
6489 [(set_attr "type" "fcmp")
6490 (set_attr "mode" "FPSW")])
6492 (define_insn "sunle_sf"
6493 [(set (match_operand:CC 0 "register_operand" "=z")
6494 (unle:CC (match_operand:SF 1 "register_operand" "f")
6495 (match_operand:SF 2 "register_operand" "f")))]
6498 [(set_attr "type" "fcmp")
6499 (set_attr "mode" "FPSW")])
6501 (define_insn "seq_sf"
6502 [(set (match_operand:CC 0 "register_operand" "=z")
6503 (eq:CC (match_operand:SF 1 "register_operand" "f")
6504 (match_operand:SF 2 "register_operand" "f")))]
6507 [(set_attr "type" "fcmp")
6508 (set_attr "mode" "FPSW")])
6510 (define_insn "slt_sf"
6511 [(set (match_operand:CC 0 "register_operand" "=z")
6512 (lt:CC (match_operand:SF 1 "register_operand" "f")
6513 (match_operand:SF 2 "register_operand" "f")))]
6516 [(set_attr "type" "fcmp")
6517 (set_attr "mode" "FPSW")])
6519 (define_insn "sle_sf"
6520 [(set (match_operand:CC 0 "register_operand" "=z")
6521 (le:CC (match_operand:SF 1 "register_operand" "f")
6522 (match_operand:SF 2 "register_operand" "f")))]
6525 [(set_attr "type" "fcmp")
6526 (set_attr "mode" "FPSW")])
6528 (define_insn "sgt_sf"
6529 [(set (match_operand:CC 0 "register_operand" "=z")
6530 (gt:CC (match_operand:SF 1 "register_operand" "f")
6531 (match_operand:SF 2 "register_operand" "f")))]
6534 [(set_attr "type" "fcmp")
6535 (set_attr "mode" "FPSW")])
6537 (define_insn "sge_sf"
6538 [(set (match_operand:CC 0 "register_operand" "=z")
6539 (ge:CC (match_operand:SF 1 "register_operand" "f")
6540 (match_operand:SF 2 "register_operand" "f")))]
6543 [(set_attr "type" "fcmp")
6544 (set_attr "mode" "FPSW")])
6547 ;; ....................
6549 ;; UNCONDITIONAL BRANCHES
6551 ;; ....................
6553 ;; Unconditional branches.
6557 (label_ref (match_operand 0 "" "")))]
6562 if (get_attr_length (insn) <= 8)
6563 return "%*b\t%l0%/";
6566 output_asm_insn (mips_output_load_label (), operands);
6567 return "%*jr\t%@%/%]";
6571 return "%*j\t%l0%/";
6573 [(set_attr "type" "jump")
6574 (set_attr "mode" "none")
6575 (set (attr "length")
6576 ;; We can't use `j' when emitting PIC. Emit a branch if it's
6577 ;; in range, otherwise load the address of the branch target into
6578 ;; $at and then jump to it.
6580 (ior (eq (symbol_ref "flag_pic") (const_int 0))
6581 (lt (abs (minus (match_dup 0)
6582 (plus (pc) (const_int 4))))
6583 (const_int 131072)))
6584 (const_int 4) (const_int 16)))])
6586 ;; We need a different insn for the mips16, because a mips16 branch
6587 ;; does not have a delay slot.
6591 (label_ref (match_operand 0 "" "")))]
6594 [(set_attr "type" "branch")
6595 (set_attr "mode" "none")
6596 (set_attr "length" "8")])
6598 (define_expand "indirect_jump"
6599 [(set (pc) (match_operand 0 "register_operand"))]
6605 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
6606 operands[0] = copy_to_mode_reg (Pmode, dest);
6608 if (!(Pmode == DImode))
6609 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
6611 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
6616 (define_insn "indirect_jump_internal1"
6617 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
6618 "!(Pmode == DImode)"
6620 [(set_attr "type" "jump")
6621 (set_attr "mode" "none")])
6623 (define_insn "indirect_jump_internal2"
6624 [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
6627 [(set_attr "type" "jump")
6628 (set_attr "mode" "none")])
6630 (define_expand "tablejump"
6632 (match_operand 0 "register_operand"))
6633 (use (label_ref (match_operand 1 "")))]
6638 if (GET_MODE (operands[0]) != HImode)
6640 if (!(Pmode == DImode))
6641 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
6643 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
6647 if (GET_MODE (operands[0]) != ptr_mode)
6651 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
6652 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
6654 if (Pmode == SImode)
6655 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
6657 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
6661 (define_insn "tablejump_internal1"
6663 (match_operand:SI 0 "register_operand" "d"))
6664 (use (label_ref (match_operand 1 "" "")))]
6667 [(set_attr "type" "jump")
6668 (set_attr "mode" "none")])
6670 (define_insn "tablejump_internal2"
6672 (match_operand:DI 0 "register_operand" "d"))
6673 (use (label_ref (match_operand 1 "" "")))]
6676 [(set_attr "type" "jump")
6677 (set_attr "mode" "none")])
6679 (define_expand "tablejump_mips161"
6680 [(set (pc) (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand"))
6681 (label_ref:SI (match_operand 1 ""))))]
6682 "TARGET_MIPS16 && !(Pmode == DImode)"
6686 t1 = gen_reg_rtx (SImode);
6687 t2 = gen_reg_rtx (SImode);
6688 t3 = gen_reg_rtx (SImode);
6689 emit_insn (gen_extendhisi2 (t1, operands[0]));
6690 emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
6691 emit_insn (gen_addsi3 (t3, t1, t2));
6692 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
6696 (define_expand "tablejump_mips162"
6697 [(set (pc) (plus:DI (sign_extend:DI (match_operand:HI 0 "register_operand"))
6698 (label_ref:DI (match_operand 1 ""))))]
6699 "TARGET_MIPS16 && Pmode == DImode"
6703 t1 = gen_reg_rtx (DImode);
6704 t2 = gen_reg_rtx (DImode);
6705 t3 = gen_reg_rtx (DImode);
6706 emit_insn (gen_extendhidi2 (t1, operands[0]));
6707 emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
6708 emit_insn (gen_adddi3 (t3, t1, t2));
6709 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
6713 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
6714 ;; While it is possible to either pull it off the stack (in the
6715 ;; o32 case) or recalculate it given t9 and our target label,
6716 ;; it takes 3 or 4 insns to do so.
6718 (define_expand "builtin_setjmp_setup"
6719 [(use (match_operand 0 "register_operand"))]
6724 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
6725 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
6729 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
6730 ;; that older code did recalculate the gp from $25. Continue to jump through
6731 ;; $25 for compatibility (we lose nothing by doing so).
6733 (define_expand "builtin_longjmp"
6734 [(use (match_operand 0 "register_operand"))]
6737 /* The elements of the buffer are, in order: */
6738 int W = GET_MODE_SIZE (Pmode);
6739 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6740 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
6741 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
6742 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
6743 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6744 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
6745 The target is bound to be using $28 as the global pointer
6746 but the current function might not be. */
6747 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
6749 /* This bit is similar to expand_builtin_longjmp except that it
6750 restores $gp as well. */
6751 emit_move_insn (hard_frame_pointer_rtx, fp);
6752 emit_move_insn (pv, lab);
6753 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6754 emit_move_insn (gp, gpv);
6755 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6756 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6757 emit_insn (gen_rtx_USE (VOIDmode, gp));
6758 emit_indirect_jump (pv);
6763 ;; ....................
6765 ;; Function prologue/epilogue
6767 ;; ....................
6770 (define_expand "prologue"
6774 mips_expand_prologue ();
6778 ;; Block any insns from being moved before this point, since the
6779 ;; profiling call to mcount can use various registers that aren't
6780 ;; saved or used to pass arguments.
6782 (define_insn "blockage"
6783 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
6786 [(set_attr "type" "unknown")
6787 (set_attr "mode" "none")
6788 (set_attr "length" "0")])
6790 (define_expand "epilogue"
6794 mips_expand_epilogue (false);
6798 (define_expand "sibcall_epilogue"
6802 mips_expand_epilogue (true);
6806 ;; Trivial return. Make it look like a normal return insn as that
6807 ;; allows jump optimizations to work better.
6809 (define_insn "return"
6811 "mips_can_use_return_insn ()"
6813 [(set_attr "type" "jump")
6814 (set_attr "mode" "none")])
6818 (define_insn "return_internal"
6820 (use (match_operand 0 "pmode_register_operand" ""))]
6823 [(set_attr "type" "jump")
6824 (set_attr "mode" "none")])
6826 ;; This is used in compiling the unwind routines.
6827 (define_expand "eh_return"
6828 [(use (match_operand 0 "general_operand"))]
6831 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
6833 if (GET_MODE (operands[0]) != gpr_mode)
6834 operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
6836 emit_insn (gen_eh_set_lr_di (operands[0]));
6838 emit_insn (gen_eh_set_lr_si (operands[0]));
6843 ;; Clobber the return address on the stack. We can't expand this
6844 ;; until we know where it will be put in the stack frame.
6846 (define_insn "eh_set_lr_si"
6847 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6848 (clobber (match_scratch:SI 1 "=&d"))]
6852 (define_insn "eh_set_lr_di"
6853 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6854 (clobber (match_scratch:DI 1 "=&d"))]
6859 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6860 (clobber (match_scratch 1))]
6861 "reload_completed && !TARGET_DEBUG_D_MODE"
6864 mips_set_return_address (operands[0], operands[1]);
6868 (define_insn_and_split "exception_receiver"
6870 (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
6871 "TARGET_ABICALLS && TARGET_OLDABI"
6873 "&& reload_completed"
6879 [(set_attr "type" "load")
6880 (set_attr "length" "12")])
6883 ;; ....................
6887 ;; ....................
6889 ;; Instructions to load a call address from the GOT. The address might
6890 ;; point to a function or to a lazy binding stub. In the latter case,
6891 ;; the stub will use the dynamic linker to resolve the function, which
6892 ;; in turn will change the GOT entry to point to the function's real
6895 ;; This means that every call, even pure and constant ones, can
6896 ;; potentially modify the GOT entry. And once a stub has been called,
6897 ;; we must not call it again.
6899 ;; We represent this restriction using an imaginary fixed register that
6900 ;; acts like a GOT version number. By making the register call-clobbered,
6901 ;; we tell the target-independent code that the address could be changed
6902 ;; by any call insn.
6903 (define_insn "load_callsi"
6904 [(set (match_operand:SI 0 "register_operand" "=c")
6905 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6906 (match_operand:SI 2 "immediate_operand" "")
6907 (reg:SI FAKE_CALL_REGNO)]
6911 [(set_attr "type" "load")
6912 (set_attr "length" "4")])
6914 (define_insn "load_calldi"
6915 [(set (match_operand:DI 0 "register_operand" "=c")
6916 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
6917 (match_operand:DI 2 "immediate_operand" "")
6918 (reg:DI FAKE_CALL_REGNO)]
6922 [(set_attr "type" "load")
6923 (set_attr "length" "4")])
6925 ;; Sibling calls. All these patterns use jump instructions.
6927 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
6928 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
6929 ;; is defined in terms of call_insn_operand, the same is true of the
6932 ;; When we use an indirect jump, we need a register that will be
6933 ;; preserved by the epilogue. Since TARGET_ABICALLS forces us to
6934 ;; use $25 for this purpose -- and $25 is never clobbered by the
6935 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
6937 (define_expand "sibcall"
6938 [(parallel [(call (match_operand 0 "")
6939 (match_operand 1 ""))
6940 (use (match_operand 2 "")) ;; next_arg_reg
6941 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
6944 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
6948 (define_insn "sibcall_internal"
6949 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
6950 (match_operand 1 "" ""))]
6951 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6955 [(set_attr "type" "call")])
6957 (define_expand "sibcall_value"
6958 [(parallel [(set (match_operand 0 "")
6959 (call (match_operand 1 "")
6960 (match_operand 2 "")))
6961 (use (match_operand 3 ""))])] ;; next_arg_reg
6964 mips_expand_call (operands[0], XEXP (operands[1], 0),
6965 operands[2], operands[3], true);
6969 (define_insn "sibcall_value_internal"
6970 [(set (match_operand 0 "register_operand" "=df,df")
6971 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6972 (match_operand 2 "" "")))]
6973 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6977 [(set_attr "type" "call")])
6979 (define_insn "sibcall_value_multiple_internal"
6980 [(set (match_operand 0 "register_operand" "=df,df")
6981 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6982 (match_operand 2 "" "")))
6983 (set (match_operand 3 "register_operand" "=df,df")
6984 (call (mem:SI (match_dup 1))
6986 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6990 [(set_attr "type" "call")])
6992 (define_expand "call"
6993 [(parallel [(call (match_operand 0 "")
6994 (match_operand 1 ""))
6995 (use (match_operand 2 "")) ;; next_arg_reg
6996 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
6999 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
7003 ;; This instruction directly corresponds to an assembly-language "jal".
7004 ;; There are four cases:
7007 ;; Both symbolic and register destinations are OK. The pattern
7008 ;; always expands to a single mips instruction.
7010 ;; - -mabicalls/-mno-explicit-relocs:
7011 ;; Again, both symbolic and register destinations are OK.
7012 ;; The call is treated as a multi-instruction black box.
7014 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
7015 ;; Only "jal $25" is allowed. This expands to a single "jalr $25"
7018 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
7019 ;; Only "jal $25" is allowed. The call is actually two instructions:
7020 ;; "jalr $25" followed by an insn to reload $gp.
7022 ;; In the last case, we can generate the individual instructions with
7023 ;; a define_split. There are several things to be wary of:
7025 ;; - We can't expose the load of $gp before reload. If we did,
7026 ;; it might get removed as dead, but reload can introduce new
7027 ;; uses of $gp by rematerializing constants.
7029 ;; - We shouldn't restore $gp after calls that never return.
7030 ;; It isn't valid to insert instructions between a noreturn
7031 ;; call and the following barrier.
7033 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
7034 ;; instruction preserves $gp and so have no effect on its liveness.
7035 ;; But once we generate the separate insns, it becomes obvious that
7036 ;; $gp is not live on entry to the call.
7038 ;; ??? The operands[2] = insn check is a hack to make the original insn
7039 ;; available to the splitter.
7040 (define_insn_and_split "call_internal"
7041 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
7042 (match_operand 1 "" ""))
7043 (clobber (reg:SI 31))]
7045 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
7046 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
7049 emit_call_insn (gen_call_split (operands[0], operands[1]));
7050 if (!find_reg_note (operands[2], REG_NORETURN, 0))
7054 [(set_attr "jal" "indirect,direct")
7055 (set_attr "extended_mips16" "no,yes")])
7057 (define_insn "call_split"
7058 [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
7059 (match_operand 1 "" ""))
7060 (clobber (reg:SI 31))
7061 (clobber (reg:SI 28))]
7062 "TARGET_SPLIT_CALLS"
7064 [(set_attr "type" "call")])
7066 (define_expand "call_value"
7067 [(parallel [(set (match_operand 0 "")
7068 (call (match_operand 1 "")
7069 (match_operand 2 "")))
7070 (use (match_operand 3 ""))])] ;; next_arg_reg
7073 mips_expand_call (operands[0], XEXP (operands[1], 0),
7074 operands[2], operands[3], false);
7078 ;; See comment for call_internal.
7079 (define_insn_and_split "call_value_internal"
7080 [(set (match_operand 0 "register_operand" "=df,df")
7081 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7082 (match_operand 2 "" "")))
7083 (clobber (reg:SI 31))]
7085 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7086 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
7089 emit_call_insn (gen_call_value_split (operands[0], operands[1],
7091 if (!find_reg_note (operands[3], REG_NORETURN, 0))
7095 [(set_attr "jal" "indirect,direct")
7096 (set_attr "extended_mips16" "no,yes")])
7098 (define_insn "call_value_split"
7099 [(set (match_operand 0 "register_operand" "=df")
7100 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7101 (match_operand 2 "" "")))
7102 (clobber (reg:SI 31))
7103 (clobber (reg:SI 28))]
7104 "TARGET_SPLIT_CALLS"
7106 [(set_attr "type" "call")])
7108 ;; See comment for call_internal.
7109 (define_insn_and_split "call_value_multiple_internal"
7110 [(set (match_operand 0 "register_operand" "=df,df")
7111 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7112 (match_operand 2 "" "")))
7113 (set (match_operand 3 "register_operand" "=df,df")
7114 (call (mem:SI (match_dup 1))
7116 (clobber (reg:SI 31))]
7118 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7119 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
7122 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
7123 operands[2], operands[3]));
7124 if (!find_reg_note (operands[4], REG_NORETURN, 0))
7128 [(set_attr "jal" "indirect,direct")
7129 (set_attr "extended_mips16" "no,yes")])
7131 (define_insn "call_value_multiple_split"
7132 [(set (match_operand 0 "register_operand" "=df")
7133 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7134 (match_operand 2 "" "")))
7135 (set (match_operand 3 "register_operand" "=df")
7136 (call (mem:SI (match_dup 1))
7138 (clobber (reg:SI 31))
7139 (clobber (reg:SI 28))]
7140 "TARGET_SPLIT_CALLS"
7142 [(set_attr "type" "call")])
7144 ;; Call subroutine returning any type.
7146 (define_expand "untyped_call"
7147 [(parallel [(call (match_operand 0 "")
7149 (match_operand 1 "")
7150 (match_operand 2 "")])]
7155 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
7157 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7159 rtx set = XVECEXP (operands[2], 0, i);
7160 emit_move_insn (SET_DEST (set), SET_SRC (set));
7163 emit_insn (gen_blockage ());
7168 ;; ....................
7172 ;; ....................
7176 (define_expand "prefetch"
7177 [(prefetch (match_operand 0 "address_operand")
7178 (match_operand 1 "const_int_operand")
7179 (match_operand 2 "const_int_operand"))]
7182 if (symbolic_operand (operands[0], GET_MODE (operands[0])))
7183 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
7186 (define_insn "prefetch_si_address"
7187 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7188 (match_operand:SI 3 "const_int_operand" "I"))
7189 (match_operand:SI 1 "const_int_operand" "n")
7190 (match_operand:SI 2 "const_int_operand" "n"))]
7191 "ISA_HAS_PREFETCH && Pmode == SImode"
7192 { return mips_emit_prefetch (operands); }
7193 [(set_attr "type" "prefetch")])
7195 (define_insn "prefetch_indexed_si"
7196 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7197 (match_operand:SI 3 "register_operand" "r"))
7198 (match_operand:SI 1 "const_int_operand" "n")
7199 (match_operand:SI 2 "const_int_operand" "n"))]
7200 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
7201 { return mips_emit_prefetch (operands); }
7202 [(set_attr "type" "prefetchx")])
7204 (define_insn "prefetch_si"
7205 [(prefetch (match_operand:SI 0 "register_operand" "r")
7206 (match_operand:SI 1 "const_int_operand" "n")
7207 (match_operand:SI 2 "const_int_operand" "n"))]
7208 "ISA_HAS_PREFETCH && Pmode == SImode"
7210 operands[3] = const0_rtx;
7211 return mips_emit_prefetch (operands);
7213 [(set_attr "type" "prefetch")])
7215 (define_insn "prefetch_di_address"
7216 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7217 (match_operand:DI 3 "const_int_operand" "I"))
7218 (match_operand:DI 1 "const_int_operand" "n")
7219 (match_operand:DI 2 "const_int_operand" "n"))]
7220 "ISA_HAS_PREFETCH && Pmode == DImode"
7221 { return mips_emit_prefetch (operands); }
7222 [(set_attr "type" "prefetch")])
7224 (define_insn "prefetch_indexed_di"
7225 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7226 (match_operand:DI 3 "register_operand" "r"))
7227 (match_operand:DI 1 "const_int_operand" "n")
7228 (match_operand:DI 2 "const_int_operand" "n"))]
7229 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
7230 { return mips_emit_prefetch (operands); }
7231 [(set_attr "type" "prefetchx")])
7233 (define_insn "prefetch_di"
7234 [(prefetch (match_operand:DI 0 "register_operand" "r")
7235 (match_operand:DI 1 "const_int_operand" "n")
7236 (match_operand:DI 2 "const_int_operand" "n"))]
7237 "ISA_HAS_PREFETCH && Pmode == DImode"
7239 operands[3] = const0_rtx;
7240 return mips_emit_prefetch (operands);
7242 [(set_attr "type" "prefetch")])
7248 [(set_attr "type" "nop")
7249 (set_attr "mode" "none")])
7251 ;; Like nop, but commented out when outside a .set noreorder block.
7252 (define_insn "hazard_nop"
7261 [(set_attr "type" "nop")])
7263 ;; MIPS4 Conditional move instructions.
7266 [(set (match_operand:SI 0 "register_operand" "=d,d")
7268 (match_operator 4 "equality_op"
7269 [(match_operand:SI 1 "register_operand" "d,d")
7271 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7272 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7273 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7277 [(set_attr "type" "condmove")
7278 (set_attr "mode" "SI")])
7281 [(set (match_operand:SI 0 "register_operand" "=d,d")
7283 (match_operator 4 "equality_op"
7284 [(match_operand:DI 1 "register_operand" "d,d")
7286 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7287 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7288 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7292 [(set_attr "type" "condmove")
7293 (set_attr "mode" "SI")])
7296 [(set (match_operand:SI 0 "register_operand" "=d,d")
7298 (match_operator 3 "equality_op" [(match_operand:CC 4
7302 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
7303 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
7304 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7308 [(set_attr "type" "condmove")
7309 (set_attr "mode" "SI")])
7312 [(set (match_operand:DI 0 "register_operand" "=d,d")
7314 (match_operator 4 "equality_op"
7315 [(match_operand:SI 1 "register_operand" "d,d")
7317 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7318 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7319 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7323 [(set_attr "type" "condmove")
7324 (set_attr "mode" "DI")])
7327 [(set (match_operand:DI 0 "register_operand" "=d,d")
7329 (match_operator 4 "equality_op"
7330 [(match_operand:DI 1 "register_operand" "d,d")
7332 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7333 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7334 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7338 [(set_attr "type" "condmove")
7339 (set_attr "mode" "DI")])
7342 [(set (match_operand:DI 0 "register_operand" "=d,d")
7344 (match_operator 3 "equality_op" [(match_operand:CC 4
7348 (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
7349 (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
7350 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
7354 [(set_attr "type" "condmove")
7355 (set_attr "mode" "DI")])
7358 [(set (match_operand:SF 0 "register_operand" "=f,f")
7360 (match_operator 4 "equality_op"
7361 [(match_operand:SI 1 "register_operand" "d,d")
7363 (match_operand:SF 2 "register_operand" "f,0")
7364 (match_operand:SF 3 "register_operand" "0,f")))]
7365 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7369 [(set_attr "type" "condmove")
7370 (set_attr "mode" "SF")])
7373 [(set (match_operand:SF 0 "register_operand" "=f,f")
7375 (match_operator 4 "equality_op"
7376 [(match_operand:DI 1 "register_operand" "d,d")
7378 (match_operand:SF 2 "register_operand" "f,0")
7379 (match_operand:SF 3 "register_operand" "0,f")))]
7380 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7384 [(set_attr "type" "condmove")
7385 (set_attr "mode" "SF")])
7388 [(set (match_operand:SF 0 "register_operand" "=f,f")
7390 (match_operator 3 "equality_op" [(match_operand:CC 4
7394 (match_operand:SF 1 "register_operand" "f,0")
7395 (match_operand:SF 2 "register_operand" "0,f")))]
7396 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7400 [(set_attr "type" "condmove")
7401 (set_attr "mode" "SF")])
7404 [(set (match_operand:DF 0 "register_operand" "=f,f")
7406 (match_operator 4 "equality_op"
7407 [(match_operand:SI 1 "register_operand" "d,d")
7409 (match_operand:DF 2 "register_operand" "f,0")
7410 (match_operand:DF 3 "register_operand" "0,f")))]
7411 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7415 [(set_attr "type" "condmove")
7416 (set_attr "mode" "DF")])
7419 [(set (match_operand:DF 0 "register_operand" "=f,f")
7421 (match_operator 4 "equality_op"
7422 [(match_operand:DI 1 "register_operand" "d,d")
7424 (match_operand:DF 2 "register_operand" "f,0")
7425 (match_operand:DF 3 "register_operand" "0,f")))]
7426 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7430 [(set_attr "type" "condmove")
7431 (set_attr "mode" "DF")])
7434 [(set (match_operand:DF 0 "register_operand" "=f,f")
7436 (match_operator 3 "equality_op" [(match_operand:CC 4
7440 (match_operand:DF 1 "register_operand" "f,0")
7441 (match_operand:DF 2 "register_operand" "0,f")))]
7442 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7446 [(set_attr "type" "condmove")
7447 (set_attr "mode" "DF")])
7449 ;; These are the main define_expand's used to make conditional moves.
7451 (define_expand "movsicc"
7452 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7453 (set (match_operand:SI 0 "register_operand")
7454 (if_then_else:SI (match_dup 5)
7455 (match_operand:SI 2 "reg_or_0_operand")
7456 (match_operand:SI 3 "reg_or_0_operand")))]
7457 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7459 gen_conditional_move (operands);
7463 (define_expand "movdicc"
7464 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7465 (set (match_operand:DI 0 "register_operand")
7466 (if_then_else:DI (match_dup 5)
7467 (match_operand:DI 2 "reg_or_0_operand")
7468 (match_operand:DI 3 "reg_or_0_operand")))]
7469 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7471 gen_conditional_move (operands);
7475 (define_expand "movsfcc"
7476 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7477 (set (match_operand:SF 0 "register_operand")
7478 (if_then_else:SF (match_dup 5)
7479 (match_operand:SF 2 "register_operand")
7480 (match_operand:SF 3 "register_operand")))]
7481 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7483 gen_conditional_move (operands);
7487 (define_expand "movdfcc"
7488 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7489 (set (match_operand:DF 0 "register_operand")
7490 (if_then_else:DF (match_dup 5)
7491 (match_operand:DF 2 "register_operand")
7492 (match_operand:DF 3 "register_operand")))]
7493 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7495 gen_conditional_move (operands);
7500 ;; ....................
7502 ;; mips16 inline constant tables
7504 ;; ....................
7507 (define_insn "consttable_int"
7508 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
7509 (match_operand 1 "const_int_operand" "")]
7510 UNSPEC_CONSTTABLE_INT)]
7513 assemble_integer (operands[0], INTVAL (operands[1]),
7514 BITS_PER_UNIT * INTVAL (operands[1]), 1);
7517 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
7519 (define_insn "consttable_float"
7520 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
7521 UNSPEC_CONSTTABLE_FLOAT)]
7526 if (GET_CODE (operands[0]) != CONST_DOUBLE)
7528 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7529 assemble_real (d, GET_MODE (operands[0]),
7530 GET_MODE_BITSIZE (GET_MODE (operands[0])));
7533 [(set (attr "length")
7534 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
7536 (define_insn "align"
7537 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
7540 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
7543 [(match_operand 0 "small_data_pattern")]
7546 { operands[0] = mips_rewrite_small_data (operands[0]); })