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.
26 ;; ??? Currently does not have define_function_unit support for the R8000.
27 ;; Must include new entries for fmadd in addition to existing entries.
30 [(UNSPEC_LOAD_DF_LOW 0)
31 (UNSPEC_LOAD_DF_HIGH 1)
32 (UNSPEC_STORE_DF_HIGH 2)
36 (UNSPEC_EH_RECEIVER 6)
38 (UNSPEC_CONSTTABLE_INT 8)
39 (UNSPEC_CONSTTABLE_FLOAT 9)
56 (UNSPEC_ADDRESS_FIRST 100)
58 (FAKE_CALL_REGNO 79)])
60 ;; ....................
64 ;; ....................
66 (define_attr "got" "unset,xgot_high,load"
67 (const_string "unset"))
69 ;; For jal instructions, this attribute is DIRECT when the target address
70 ;; is symbolic and INDIRECT when it is a register.
71 (define_attr "jal" "unset,direct,indirect"
72 (const_string "unset"))
74 ;; This attribute is YES if the instruction is a jal macro (not a
75 ;; real jal instruction).
77 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
78 ;; restore $gp. Direct jals are also macros in NewABI PIC since they
79 ;; load the target address into $25.
80 (define_attr "jal_macro" "no,yes"
81 (cond [(eq_attr "jal" "direct")
82 (symbol_ref "TARGET_ABICALLS != 0")
83 (eq_attr "jal" "indirect")
84 (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
87 ;; Classification of each insn.
88 ;; branch conditional branch
89 ;; jump unconditional jump
90 ;; call unconditional call
91 ;; load load instruction(s)
92 ;; fpload floating point load
93 ;; fpidxload floating point indexed load
94 ;; store store instruction(s)
95 ;; fpstore floating point store
96 ;; fpidxstore floating point indexed store
97 ;; prefetch memory prefetch (register + offset)
98 ;; prefetchx memory indexed prefetch (register + register)
99 ;; condmove conditional moves
100 ;; xfer transfer to/from coprocessor
101 ;; mthilo transfer to hi/lo registers
102 ;; mfhilo transfer from hi/lo registers
103 ;; const load constant
104 ;; arith integer arithmetic and logical instructions
105 ;; shift integer shift instructions
106 ;; slt set less than instructions
107 ;; clz the clz and clo instructions
108 ;; trap trap if instructions
109 ;; imul integer multiply
110 ;; imadd integer multiply-add
111 ;; idiv integer divide
112 ;; fmove floating point register move
113 ;; fadd floating point add/subtract
114 ;; fmul floating point multiply
115 ;; fmadd floating point multiply-add
116 ;; fdiv floating point divide
117 ;; fabs floating point absolute value
118 ;; fneg floating point negation
119 ;; fcmp floating point compare
120 ;; fcvt floating point convert
121 ;; fsqrt floating point square root
122 ;; frsqrt floating point reciprocal square root
123 ;; multi multiword sequence (or user asm statements)
126 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
127 (cond [(eq_attr "jal" "!unset") (const_string "call")
128 (eq_attr "got" "load") (const_string "load")]
129 (const_string "unknown")))
131 ;; Main data type used by the insn
132 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
133 (const_string "unknown"))
135 ;; Is this an extended instruction in mips16 mode?
136 (define_attr "extended_mips16" "no,yes"
139 ;; Length of instruction in bytes.
140 (define_attr "length" ""
141 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
142 ;; If a branch is outside this range, we have a choice of two
143 ;; sequences. For PIC, an out-of-range branch like:
148 ;; becomes the equivalent of:
157 ;; where the load address can be up to three instructions long
160 ;; The non-PIC case is similar except that we use a direct
161 ;; jump instead of an la/jr pair. Since the target of this
162 ;; jump is an absolute 28-bit bit address (the other bits
163 ;; coming from the address of the delay slot) this form cannot
164 ;; cross a 256MB boundary. We could provide the option of
165 ;; using la/jr in this case too, but we do not do so at
168 ;; Note that this value does not account for the delay slot
169 ;; instruction, whose length is added separately. If the RTL
170 ;; pattern has no explicit delay slot, mips_adjust_insn_length
171 ;; will add the length of the implicit nop. The values for
172 ;; forward and backward branches will be different as well.
173 (eq_attr "type" "branch")
174 (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
175 (le (minus (pc) (match_dup 1)) (const_int 131068)))
177 (ne (symbol_ref "flag_pic") (const_int 0))
181 (eq_attr "got" "load")
183 (eq_attr "got" "xgot_high")
186 (eq_attr "type" "const")
187 (symbol_ref "mips_const_insns (operands[1]) * 4")
188 (eq_attr "type" "load,fpload,fpidxload")
189 (symbol_ref "mips_fetch_insns (operands[1]) * 4")
190 (eq_attr "type" "store,fpstore,fpidxstore")
191 (symbol_ref "mips_fetch_insns (operands[0]) * 4")
193 ;; In the worst case, a call macro will take 8 instructions:
195 ;; lui $25,%call_hi(FOO)
197 ;; lw $25,%call_lo(FOO)($25)
203 (eq_attr "jal_macro" "yes")
206 (and (eq_attr "extended_mips16" "yes")
207 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
210 ;; Various VR4120 errata require a nop to be inserted after a macc
211 ;; instruction. The assembler does this for us, so account for
212 ;; the worst-case length here.
213 (and (eq_attr "type" "imadd")
214 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
217 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
218 ;; the result of the second one is missed. The assembler should work
219 ;; around this by inserting a nop after the first dmult.
220 (and (eq_attr "type" "imul")
221 (and (eq_attr "mode" "DI")
222 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
225 (eq_attr "type" "idiv")
226 (symbol_ref "mips_idiv_insns () * 4")
229 ;; Attribute describing the processor. This attribute must match exactly
230 ;; with the processor_type enumeration in mips.h.
232 "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
233 (const (symbol_ref "mips_tune")))
235 ;; The type of hardware hazard associated with this instruction.
236 ;; DELAY means that the next instruction cannot read the result
237 ;; of this one. HILO means that the next two instructions cannot
238 ;; write to HI or LO.
239 (define_attr "hazard" "none,delay,hilo"
240 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
241 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
242 (const_string "delay")
244 (and (eq_attr "type" "xfer")
245 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
246 (const_string "delay")
248 (and (eq_attr "type" "fcmp")
249 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
250 (const_string "delay")
252 ;; The r4000 multiplication patterns include an mflo instruction.
253 (and (eq_attr "type" "imul")
254 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
255 (const_string "hilo")
257 (and (eq_attr "type" "mfhilo")
258 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
259 (const_string "hilo")]
260 (const_string "none")))
262 ;; Is it a single instruction?
263 (define_attr "single_insn" "no,yes"
264 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
266 ;; Can the instruction be put into a delay slot?
267 (define_attr "can_delay" "no,yes"
268 (if_then_else (and (eq_attr "type" "!branch,call,jump")
269 (and (eq_attr "hazard" "none")
270 (eq_attr "single_insn" "yes")))
272 (const_string "no")))
274 ;; Attribute defining whether or not we can use the branch-likely instructions
275 (define_attr "branch_likely" "no,yes"
277 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
279 (const_string "no"))))
281 ;; True if an instruction might assign to hi or lo when reloaded.
282 ;; This is used by the TUNE_MACC_CHAINS code.
283 (define_attr "may_clobber_hilo" "no,yes"
284 (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
286 (const_string "no")))
288 ;; Describe a user's asm statement.
289 (define_asm_attributes
290 [(set_attr "type" "multi")])
292 ;; .........................
294 ;; Branch, call and jump delay slots
296 ;; .........................
298 (define_delay (and (eq_attr "type" "branch")
299 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
300 [(eq_attr "can_delay" "yes")
302 (and (eq_attr "branch_likely" "yes")
303 (eq_attr "can_delay" "yes"))])
305 (define_delay (eq_attr "type" "jump")
306 [(eq_attr "can_delay" "yes")
310 (define_delay (and (eq_attr "type" "call")
311 (eq_attr "jal_macro" "no"))
312 [(eq_attr "can_delay" "yes")
316 ;; Pipeline descriptions.
318 ;; generic.md provides a fallback for processors without a specific
319 ;; pipeline description. It is derived from the old define_function_unit
320 ;; version and uses the "alu" and "imuldiv" units declared below.
322 ;; Some of the processor-specific files are also derived from old
323 ;; define_function_unit descriptions and simply override the parts of
324 ;; generic.md that don't apply. The other processor-specific files
325 ;; are self-contained.
326 (define_automaton "alu,imuldiv")
328 (define_cpu_unit "alu" "alu")
329 (define_cpu_unit "imuldiv" "imuldiv")
345 (include "generic.md")
348 ;; ....................
352 ;; ....................
356 [(trap_if (const_int 1) (const_int 0))]
359 if (ISA_HAS_COND_TRAP)
361 /* The IRIX 6 O32 assembler requires the first break operand. */
362 else if (TARGET_MIPS16 || !TARGET_GAS)
367 [(set_attr "type" "trap")])
369 (define_expand "conditional_trap"
370 [(trap_if (match_operator 0 "cmp_op"
371 [(match_dup 2) (match_dup 3)])
372 (match_operand 1 "const_int_operand"))]
375 if (operands[1] == const0_rtx)
377 mips_gen_conditional_trap (operands);
385 [(trap_if (match_operator 0 "trap_cmp_op"
386 [(match_operand:SI 1 "reg_or_0_operand" "dJ")
387 (match_operand:SI 2 "arith_operand" "dI")])
391 [(set_attr "type" "trap")])
394 [(trap_if (match_operator 0 "trap_cmp_op"
395 [(match_operand:DI 1 "reg_or_0_operand" "dJ")
396 (match_operand:DI 2 "arith_operand" "dI")])
398 "TARGET_64BIT && ISA_HAS_COND_TRAP"
400 [(set_attr "type" "trap")])
403 ;; ....................
407 ;; ....................
410 (define_insn "adddf3"
411 [(set (match_operand:DF 0 "register_operand" "=f")
412 (plus:DF (match_operand:DF 1 "register_operand" "f")
413 (match_operand:DF 2 "register_operand" "f")))]
414 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
416 [(set_attr "type" "fadd")
417 (set_attr "mode" "DF")])
419 (define_insn "addsf3"
420 [(set (match_operand:SF 0 "register_operand" "=f")
421 (plus:SF (match_operand:SF 1 "register_operand" "f")
422 (match_operand:SF 2 "register_operand" "f")))]
425 [(set_attr "type" "fadd")
426 (set_attr "mode" "SF")])
428 (define_expand "addsi3"
429 [(set (match_operand:SI 0 "register_operand")
430 (plus:SI (match_operand:SI 1 "reg_or_0_operand")
431 (match_operand:SI 2 "arith_operand")))]
434 /* If a large stack adjustment was forced into a register, we may be
435 asked to generate rtx such as:
437 (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo)))
439 but no such instruction is available in mips16. Handle it by
440 using a temporary. */
442 && REGNO (operands[0]) == STACK_POINTER_REGNUM
443 && ((GET_CODE (operands[1]) == REG
444 && REGNO (operands[1]) != STACK_POINTER_REGNUM)
445 || GET_CODE (operands[2]) != CONST_INT))
447 rtx tmp = gen_reg_rtx (SImode);
449 emit_move_insn (tmp, operands[1]);
450 emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
451 emit_move_insn (operands[0], tmp);
456 (define_insn "addsi3_internal"
457 [(set (match_operand:SI 0 "register_operand" "=d,d")
458 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
459 (match_operand:SI 2 "arith_operand" "d,Q")))]
464 [(set_attr "type" "arith")
465 (set_attr "mode" "SI")])
467 ;; For the mips16, we need to recognize stack pointer additions
468 ;; explicitly, since we don't have a constraint for $sp. These insns
469 ;; will be generated by the save_restore_insns functions.
474 (match_operand:SI 0 "small_int" "I")))]
477 [(set_attr "type" "arith")
478 (set_attr "mode" "SI")
479 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
484 [(set (match_operand:SI 0 "register_operand" "=d")
486 (match_operand:SI 1 "small_int" "I")))]
489 [(set_attr "type" "arith")
490 (set_attr "mode" "SI")
491 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4")
496 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
497 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
498 (match_operand:SI 2 "arith_operand" "Q,O,d")))]
500 && (GET_CODE (operands[1]) != REG
501 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
502 || M16_REG_P (REGNO (operands[1]))
503 || REGNO (operands[1]) == ARG_POINTER_REGNUM
504 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
505 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
506 && (GET_CODE (operands[2]) != REG
507 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
508 || M16_REG_P (REGNO (operands[2]))
509 || REGNO (operands[2]) == ARG_POINTER_REGNUM
510 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
511 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
513 if (REGNO (operands[0]) == REGNO (operands[1]))
514 return "addu\t%0,%2";
516 return "addu\t%0,%1,%2";
518 [(set_attr "type" "arith")
519 (set_attr "mode" "SI")
520 (set_attr_alternative "length"
521 [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
524 (if_then_else (match_operand:VOID 2 "m16_simm4_1")
530 ;; On the mips16, we can sometimes split an add of a constant which is
531 ;; a 4 byte instruction into two adds which are both 2 byte
532 ;; instructions. There are two cases: one where we are adding a
533 ;; constant plus a register to another register, and one where we are
534 ;; simply adding a constant to a register.
537 [(set (match_operand:SI 0 "register_operand")
538 (plus:SI (match_dup 0)
539 (match_operand:SI 1 "const_int_operand")))]
540 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
541 && GET_CODE (operands[0]) == REG
542 && M16_REG_P (REGNO (operands[0]))
543 && GET_CODE (operands[1]) == CONST_INT
544 && ((INTVAL (operands[1]) > 0x7f
545 && INTVAL (operands[1]) <= 0x7f + 0x7f)
546 || (INTVAL (operands[1]) < - 0x80
547 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
548 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
549 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
551 HOST_WIDE_INT val = INTVAL (operands[1]);
555 operands[1] = GEN_INT (0x7f);
556 operands[2] = GEN_INT (val - 0x7f);
560 operands[1] = GEN_INT (- 0x80);
561 operands[2] = GEN_INT (val + 0x80);
566 [(set (match_operand:SI 0 "register_operand")
567 (plus:SI (match_operand:SI 1 "register_operand")
568 (match_operand:SI 2 "const_int_operand")))]
569 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
570 && GET_CODE (operands[0]) == REG
571 && M16_REG_P (REGNO (operands[0]))
572 && GET_CODE (operands[1]) == REG
573 && M16_REG_P (REGNO (operands[1]))
574 && REGNO (operands[0]) != REGNO (operands[1])
575 && GET_CODE (operands[2]) == CONST_INT
576 && ((INTVAL (operands[2]) > 0x7
577 && INTVAL (operands[2]) <= 0x7 + 0x7f)
578 || (INTVAL (operands[2]) < - 0x8
579 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
580 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
581 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
583 HOST_WIDE_INT val = INTVAL (operands[2]);
587 operands[2] = GEN_INT (0x7);
588 operands[3] = GEN_INT (val - 0x7);
592 operands[2] = GEN_INT (- 0x8);
593 operands[3] = GEN_INT (val + 0x8);
597 (define_expand "adddi3"
598 [(set (match_operand:DI 0 "register_operand")
599 (plus:DI (match_operand:DI 1 "register_operand")
600 (match_operand:DI 2 "arith_operand")))]
603 /* If a large stack adjustment was forced into a register, we may be
604 asked to generate rtx such as:
606 (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo)))
608 but no such instruction is available in mips16. Handle it by
609 using a temporary. */
611 && REGNO (operands[0]) == STACK_POINTER_REGNUM
612 && ((GET_CODE (operands[1]) == REG
613 && REGNO (operands[1]) != STACK_POINTER_REGNUM)
614 || GET_CODE (operands[2]) != CONST_INT))
616 rtx tmp = gen_reg_rtx (DImode);
618 emit_move_insn (tmp, operands[1]);
619 emit_insn (gen_adddi3 (tmp, tmp, operands[2]));
620 emit_move_insn (operands[0], tmp);
625 (define_insn "adddi3_internal"
626 [(set (match_operand:DI 0 "register_operand" "=d,d")
627 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")
628 (match_operand:DI 2 "arith_operand" "d,Q")))]
629 "TARGET_64BIT && !TARGET_MIPS16"
633 [(set_attr "type" "arith")
634 (set_attr "mode" "DI")])
636 ;; For the mips16, we need to recognize stack pointer additions
637 ;; explicitly, since we don't have a constraint for $sp. These insns
638 ;; will be generated by the save_restore_insns functions.
643 (match_operand:DI 0 "small_int" "I")))]
644 "TARGET_MIPS16 && TARGET_64BIT"
646 [(set_attr "type" "arith")
647 (set_attr "mode" "DI")
648 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
653 [(set (match_operand:DI 0 "register_operand" "=d")
655 (match_operand:DI 1 "small_int" "I")))]
656 "TARGET_MIPS16 && TARGET_64BIT"
658 [(set_attr "type" "arith")
659 (set_attr "mode" "DI")
660 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4")
665 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
666 (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
667 (match_operand:DI 2 "arith_operand" "Q,O,d")))]
668 "TARGET_MIPS16 && TARGET_64BIT
669 && (GET_CODE (operands[1]) != REG
670 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
671 || M16_REG_P (REGNO (operands[1]))
672 || REGNO (operands[1]) == ARG_POINTER_REGNUM
673 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
674 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
675 && (GET_CODE (operands[2]) != REG
676 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
677 || M16_REG_P (REGNO (operands[2]))
678 || REGNO (operands[2]) == ARG_POINTER_REGNUM
679 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
680 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
682 if (REGNO (operands[0]) == REGNO (operands[1]))
683 return "daddu\t%0,%2";
685 return "daddu\t%0,%1,%2";
687 [(set_attr "type" "arith")
688 (set_attr "mode" "DI")
689 (set_attr_alternative "length"
690 [(if_then_else (match_operand:VOID 2 "m16_simm5_1")
693 (if_then_else (match_operand:VOID 2 "m16_simm4_1")
699 ;; On the mips16, we can sometimes split an add of a constant which is
700 ;; a 4 byte instruction into two adds which are both 2 byte
701 ;; instructions. There are two cases: one where we are adding a
702 ;; constant plus a register to another register, and one where we are
703 ;; simply adding a constant to a register.
706 [(set (match_operand:DI 0 "register_operand")
707 (plus:DI (match_dup 0)
708 (match_operand:DI 1 "const_int_operand")))]
709 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
710 && GET_CODE (operands[0]) == REG
711 && M16_REG_P (REGNO (operands[0]))
712 && GET_CODE (operands[1]) == CONST_INT
713 && ((INTVAL (operands[1]) > 0xf
714 && INTVAL (operands[1]) <= 0xf + 0xf)
715 || (INTVAL (operands[1]) < - 0x10
716 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
717 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
718 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
720 HOST_WIDE_INT val = INTVAL (operands[1]);
724 operands[1] = GEN_INT (0xf);
725 operands[2] = GEN_INT (val - 0xf);
729 operands[1] = GEN_INT (- 0x10);
730 operands[2] = GEN_INT (val + 0x10);
735 [(set (match_operand:DI 0 "register_operand")
736 (plus:DI (match_operand:DI 1 "register_operand")
737 (match_operand:DI 2 "const_int_operand")))]
738 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
739 && GET_CODE (operands[0]) == REG
740 && M16_REG_P (REGNO (operands[0]))
741 && GET_CODE (operands[1]) == REG
742 && M16_REG_P (REGNO (operands[1]))
743 && REGNO (operands[0]) != REGNO (operands[1])
744 && GET_CODE (operands[2]) == CONST_INT
745 && ((INTVAL (operands[2]) > 0x7
746 && INTVAL (operands[2]) <= 0x7 + 0xf)
747 || (INTVAL (operands[2]) < - 0x8
748 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
749 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
750 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
752 HOST_WIDE_INT val = INTVAL (operands[2]);
756 operands[2] = GEN_INT (0x7);
757 operands[3] = GEN_INT (val - 0x7);
761 operands[2] = GEN_INT (- 0x8);
762 operands[3] = GEN_INT (val + 0x8);
766 (define_insn "addsi3_internal_2"
767 [(set (match_operand:DI 0 "register_operand" "=d,d")
768 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
769 (match_operand:SI 2 "arith_operand" "d,Q"))))]
770 "TARGET_64BIT && !TARGET_MIPS16"
774 [(set_attr "type" "arith")
775 (set_attr "mode" "SI")])
778 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
779 (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
780 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
781 "TARGET_MIPS16 && TARGET_64BIT"
783 if (REGNO (operands[0]) == REGNO (operands[1]))
784 return "addu\t%0,%2";
786 return "addu\t%0,%1,%2";
788 [(set_attr "type" "arith")
789 (set_attr "mode" "SI")
790 (set_attr_alternative "length"
791 [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
794 (if_then_else (match_operand:VOID 2 "m16_simm4_1")
800 ;; ....................
804 ;; ....................
807 (define_insn "subdf3"
808 [(set (match_operand:DF 0 "register_operand" "=f")
809 (minus:DF (match_operand:DF 1 "register_operand" "f")
810 (match_operand:DF 2 "register_operand" "f")))]
811 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
813 [(set_attr "type" "fadd")
814 (set_attr "mode" "DF")])
816 (define_insn "subsf3"
817 [(set (match_operand:SF 0 "register_operand" "=f")
818 (minus:SF (match_operand:SF 1 "register_operand" "f")
819 (match_operand:SF 2 "register_operand" "f")))]
822 [(set_attr "type" "fadd")
823 (set_attr "mode" "SF")])
825 (define_expand "subsi3"
826 [(set (match_operand:SI 0 "register_operand")
827 (minus:SI (match_operand:SI 1 "register_operand")
828 (match_operand:SI 2 "register_operand")))]
832 (define_insn "subsi3_internal"
833 [(set (match_operand:SI 0 "register_operand" "=d")
834 (minus:SI (match_operand:SI 1 "register_operand" "d")
835 (match_operand:SI 2 "register_operand" "d")))]
838 [(set_attr "type" "arith")
839 (set_attr "mode" "SI")])
841 (define_insn "subdi3"
842 [(set (match_operand:DI 0 "register_operand" "=d")
843 (minus:DI (match_operand:DI 1 "register_operand" "d")
844 (match_operand:DI 2 "register_operand" "d")))]
847 [(set_attr "type" "arith")
848 (set_attr "mode" "DI")])
850 (define_insn "subsi3_internal_2"
851 [(set (match_operand:DI 0 "register_operand" "=d")
853 (minus:SI (match_operand:SI 1 "register_operand" "d")
854 (match_operand:SI 2 "register_operand" "d"))))]
857 [(set_attr "type" "arith")
858 (set_attr "mode" "DI")])
861 ;; ....................
865 ;; ....................
868 (define_expand "muldf3"
869 [(set (match_operand:DF 0 "register_operand")
870 (mult:DF (match_operand:DF 1 "register_operand")
871 (match_operand:DF 2 "register_operand")))]
872 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
875 (define_insn "muldf3_internal"
876 [(set (match_operand:DF 0 "register_operand" "=f")
877 (mult:DF (match_operand:DF 1 "register_operand" "f")
878 (match_operand:DF 2 "register_operand" "f")))]
879 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
881 [(set_attr "type" "fmul")
882 (set_attr "mode" "DF")])
884 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
885 ;; operands may corrupt immediately following multiplies. This is a
886 ;; simple fix to insert NOPs.
888 (define_insn "muldf3_r4300"
889 [(set (match_operand:DF 0 "register_operand" "=f")
890 (mult:DF (match_operand:DF 1 "register_operand" "f")
891 (match_operand:DF 2 "register_operand" "f")))]
892 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
893 "mul.d\t%0,%1,%2\;nop"
894 [(set_attr "type" "fmul")
895 (set_attr "mode" "DF")
896 (set_attr "length" "8")])
898 (define_expand "mulsf3"
899 [(set (match_operand:SF 0 "register_operand")
900 (mult:SF (match_operand:SF 1 "register_operand")
901 (match_operand:SF 2 "register_operand")))]
905 (define_insn "mulsf3_internal"
906 [(set (match_operand:SF 0 "register_operand" "=f")
907 (mult:SF (match_operand:SF 1 "register_operand" "f")
908 (match_operand:SF 2 "register_operand" "f")))]
909 "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
911 [(set_attr "type" "fmul")
912 (set_attr "mode" "SF")])
916 (define_insn "mulsf3_r4300"
917 [(set (match_operand:SF 0 "register_operand" "=f")
918 (mult:SF (match_operand:SF 1 "register_operand" "f")
919 (match_operand:SF 2 "register_operand" "f")))]
920 "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
921 "mul.s\t%0,%1,%2\;nop"
922 [(set_attr "type" "fmul")
923 (set_attr "mode" "SF")
924 (set_attr "length" "8")])
927 ;; The original R4000 has a cpu bug. If a double-word or a variable
928 ;; shift executes while an integer multiplication is in progress, the
929 ;; shift may give an incorrect result. Avoid this by keeping the mflo
930 ;; with the mult on the R4000.
932 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
933 ;; (also valid for MIPS R4000MC processors):
935 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
936 ;; this errata description.
937 ;; The following code sequence causes the R4000 to incorrectly
938 ;; execute the Double Shift Right Arithmetic 32 (dsra32)
939 ;; instruction. If the dsra32 instruction is executed during an
940 ;; integer multiply, the dsra32 will only shift by the amount in
941 ;; specified in the instruction rather than the amount plus 32
943 ;; instruction 1: mult rs,rt integer multiply
944 ;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
945 ;; right arithmetic + 32
946 ;; Workaround: A dsra32 instruction placed after an integer
947 ;; multiply should not be one of the 11 instructions after the
948 ;; multiply instruction."
952 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
953 ;; the following description.
954 ;; All extended shifts (shift by n+32) and variable shifts (32 and
955 ;; 64-bit versions) may produce incorrect results under the
956 ;; following conditions:
957 ;; 1) An integer multiply is currently executing
958 ;; 2) These types of shift instructions are executed immediately
959 ;; following an integer divide instruction.
961 ;; 1) Make sure no integer multiply is running wihen these
962 ;; instruction are executed. If this cannot be predicted at
963 ;; compile time, then insert a "mfhi" to R0 instruction
964 ;; immediately after the integer multiply instruction. This
965 ;; will cause the integer multiply to complete before the shift
967 ;; 2) Separate integer divide and these two classes of shift
968 ;; instructions by another instruction or a noop."
970 ;; These processors have PRId values of 0x00004220 and 0x00004300,
973 (define_expand "mulsi3"
974 [(set (match_operand:SI 0 "register_operand")
975 (mult:SI (match_operand:SI 1 "register_operand")
976 (match_operand:SI 2 "register_operand")))]
979 if (GENERATE_MULT3_SI || TARGET_MAD)
980 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
981 else if (!TARGET_FIX_R4000)
982 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
984 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
988 (define_insn "mulsi3_mult3"
989 [(set (match_operand:SI 0 "register_operand" "=d,l")
990 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
991 (match_operand:SI 2 "register_operand" "d,d")))
992 (clobber (match_scratch:SI 3 "=h,h"))
993 (clobber (match_scratch:SI 4 "=l,X"))]
997 if (which_alternative == 1)
998 return "mult\t%1,%2";
1007 return "mul\t%0,%1,%2";
1008 return "mult\t%0,%1,%2";
1010 [(set_attr "type" "imul")
1011 (set_attr "mode" "SI")])
1013 ;; If a register gets allocated to LO, and we spill to memory, the reload
1014 ;; will include a move from LO to a GPR. Merge it into the multiplication
1015 ;; if it can set the GPR directly.
1018 ;; Operand 1: GPR (1st multiplication operand)
1019 ;; Operand 2: GPR (2nd multiplication operand)
1021 ;; Operand 4: GPR (destination)
1024 [(set (match_operand:SI 0 "register_operand")
1025 (mult:SI (match_operand:SI 1 "register_operand")
1026 (match_operand:SI 2 "register_operand")))
1027 (clobber (match_operand:SI 3 "register_operand"))
1028 (clobber (scratch:SI))])
1029 (set (match_operand:SI 4 "register_operand")
1030 (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1031 "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
1034 (mult:SI (match_dup 1)
1036 (clobber (match_dup 3))
1037 (clobber (match_dup 0))])])
1039 (define_insn "mulsi3_internal"
1040 [(set (match_operand:SI 0 "register_operand" "=l")
1041 (mult:SI (match_operand:SI 1 "register_operand" "d")
1042 (match_operand:SI 2 "register_operand" "d")))
1043 (clobber (match_scratch:SI 3 "=h"))]
1046 [(set_attr "type" "imul")
1047 (set_attr "mode" "SI")])
1049 (define_insn "mulsi3_r4000"
1050 [(set (match_operand:SI 0 "register_operand" "=d")
1051 (mult:SI (match_operand:SI 1 "register_operand" "d")
1052 (match_operand:SI 2 "register_operand" "d")))
1053 (clobber (match_scratch:SI 3 "=h"))
1054 (clobber (match_scratch:SI 4 "=l"))]
1056 "mult\t%1,%2\;mflo\t%0"
1057 [(set_attr "type" "imul")
1058 (set_attr "mode" "SI")
1059 (set_attr "length" "8")])
1061 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1062 ;; of "mult; mflo". They have the same latency, but the first form gives
1063 ;; us an extra cycle to compute the operands.
1066 ;; Operand 1: GPR (1st multiplication operand)
1067 ;; Operand 2: GPR (2nd multiplication operand)
1069 ;; Operand 4: GPR (destination)
1072 [(set (match_operand:SI 0 "register_operand")
1073 (mult:SI (match_operand:SI 1 "register_operand")
1074 (match_operand:SI 2 "register_operand")))
1075 (clobber (match_operand:SI 3 "register_operand"))])
1076 (set (match_operand:SI 4 "register_operand")
1077 (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1078 "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1083 (plus:SI (mult:SI (match_dup 1)
1087 (plus:SI (mult:SI (match_dup 1)
1090 (clobber (match_dup 3))])])
1092 ;; Multiply-accumulate patterns
1094 ;; For processors that can copy the output to a general register:
1096 ;; The all-d alternative is needed because the combiner will find this
1097 ;; pattern and then register alloc/reload will move registers around to
1098 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1100 ;; The last alternative should be made slightly less desirable, but adding
1101 ;; "?" to the constraint is too strong, and causes values to be loaded into
1102 ;; LO even when that's more costly. For now, using "*d" mostly does the
1104 (define_insn "*mul_acc_si"
1105 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1106 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1107 (match_operand:SI 2 "register_operand" "d,d,d"))
1108 (match_operand:SI 3 "register_operand" "0,l,*d")))
1109 (clobber (match_scratch:SI 4 "=h,h,h"))
1110 (clobber (match_scratch:SI 5 "=X,3,l"))
1111 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1113 || ISA_HAS_MADD_MSUB)
1116 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1117 if (which_alternative == 2)
1119 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1121 return madd[which_alternative];
1123 [(set_attr "type" "imadd,imadd,multi")
1124 (set_attr "mode" "SI")
1125 (set_attr "length" "4,4,8")])
1127 ;; Split the above insn if we failed to get LO allocated.
1129 [(set (match_operand:SI 0 "register_operand")
1130 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1131 (match_operand:SI 2 "register_operand"))
1132 (match_operand:SI 3 "register_operand")))
1133 (clobber (match_scratch:SI 4))
1134 (clobber (match_scratch:SI 5))
1135 (clobber (match_scratch:SI 6))]
1136 "reload_completed && !TARGET_DEBUG_D_MODE
1137 && GP_REG_P (true_regnum (operands[0]))
1138 && GP_REG_P (true_regnum (operands[3]))"
1139 [(parallel [(set (match_dup 6)
1140 (mult:SI (match_dup 1) (match_dup 2)))
1141 (clobber (match_dup 4))
1142 (clobber (match_dup 5))])
1143 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1146 ;; Splitter to copy result of MADD to a general register
1148 [(set (match_operand:SI 0 "register_operand")
1149 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1150 (match_operand:SI 2 "register_operand"))
1151 (match_operand:SI 3 "register_operand")))
1152 (clobber (match_scratch:SI 4))
1153 (clobber (match_scratch:SI 5))
1154 (clobber (match_scratch:SI 6))]
1155 "reload_completed && !TARGET_DEBUG_D_MODE
1156 && GP_REG_P (true_regnum (operands[0]))
1157 && true_regnum (operands[3]) == LO_REGNUM"
1158 [(parallel [(set (match_dup 3)
1159 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1161 (clobber (match_dup 4))
1162 (clobber (match_dup 5))
1163 (clobber (match_dup 6))])
1164 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1167 (define_insn "*macc"
1168 [(set (match_operand:SI 0 "register_operand" "=l,d")
1169 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1170 (match_operand:SI 2 "register_operand" "d,d"))
1171 (match_operand:SI 3 "register_operand" "0,l")))
1172 (clobber (match_scratch:SI 4 "=h,h"))
1173 (clobber (match_scratch:SI 5 "=X,3"))]
1176 if (which_alternative == 1)
1177 return "macc\t%0,%1,%2";
1178 else if (TARGET_MIPS5500)
1179 return "madd\t%1,%2";
1181 /* The VR4130 assumes that there is a two-cycle latency between a macc
1182 that "writes" to $0 and an instruction that reads from it. We avoid
1183 this by assigning to $1 instead. */
1184 return "%[macc\t%@,%1,%2%]";
1186 [(set_attr "type" "imadd")
1187 (set_attr "mode" "SI")])
1189 (define_insn "*msac"
1190 [(set (match_operand:SI 0 "register_operand" "=l,d")
1191 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1192 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1193 (match_operand:SI 3 "register_operand" "d,d"))))
1194 (clobber (match_scratch:SI 4 "=h,h"))
1195 (clobber (match_scratch:SI 5 "=X,1"))]
1198 if (which_alternative == 1)
1199 return "msac\t%0,%2,%3";
1200 else if (TARGET_MIPS5500)
1201 return "msub\t%2,%3";
1203 return "msac\t$0,%2,%3";
1205 [(set_attr "type" "imadd")
1206 (set_attr "mode" "SI")])
1208 ;; An msac-like instruction implemented using negation and a macc.
1209 (define_insn_and_split "*msac_using_macc"
1210 [(set (match_operand:SI 0 "register_operand" "=l,d")
1211 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1212 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1213 (match_operand:SI 3 "register_operand" "d,d"))))
1214 (clobber (match_scratch:SI 4 "=h,h"))
1215 (clobber (match_scratch:SI 5 "=X,1"))
1216 (clobber (match_scratch:SI 6 "=d,d"))]
1217 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1219 "&& reload_completed"
1221 (neg:SI (match_dup 3)))
1224 (plus:SI (mult:SI (match_dup 2)
1227 (clobber (match_dup 4))
1228 (clobber (match_dup 5))])]
1230 [(set_attr "type" "imadd")
1231 (set_attr "length" "8")])
1233 ;; Patterns generated by the define_peephole2 below.
1235 (define_insn "*macc2"
1236 [(set (match_operand:SI 0 "register_operand" "=l")
1237 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1238 (match_operand:SI 2 "register_operand" "d"))
1240 (set (match_operand:SI 3 "register_operand" "=d")
1241 (plus:SI (mult:SI (match_dup 1)
1244 (clobber (match_scratch:SI 4 "=h"))]
1245 "ISA_HAS_MACC && reload_completed"
1247 [(set_attr "type" "imadd")
1248 (set_attr "mode" "SI")])
1250 (define_insn "*msac2"
1251 [(set (match_operand:SI 0 "register_operand" "=l")
1252 (minus:SI (match_dup 0)
1253 (mult:SI (match_operand:SI 1 "register_operand" "d")
1254 (match_operand:SI 2 "register_operand" "d"))))
1255 (set (match_operand:SI 3 "register_operand" "=d")
1256 (minus:SI (match_dup 0)
1257 (mult:SI (match_dup 1)
1259 (clobber (match_scratch:SI 4 "=h"))]
1260 "ISA_HAS_MSAC && reload_completed"
1262 [(set_attr "type" "imadd")
1263 (set_attr "mode" "SI")])
1265 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1269 ;; Operand 1: macc/msac
1271 ;; Operand 3: GPR (destination)
1274 [(set (match_operand:SI 0 "register_operand")
1275 (match_operand:SI 1 "macc_msac_operand"))
1276 (clobber (match_operand:SI 2 "register_operand"))
1277 (clobber (scratch:SI))])
1278 (set (match_operand:SI 3 "register_operand")
1279 (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1281 [(parallel [(set (match_dup 0)
1285 (clobber (match_dup 2))])]
1288 ;; When we have a three-address multiplication instruction, it should
1289 ;; be faster to do a separate multiply and add, rather than moving
1290 ;; something into LO in order to use a macc instruction.
1292 ;; This peephole needs a scratch register to cater for the case when one
1293 ;; of the multiplication operands is the same as the destination.
1295 ;; Operand 0: GPR (scratch)
1297 ;; Operand 2: GPR (addend)
1298 ;; Operand 3: GPR (destination)
1299 ;; Operand 4: macc/msac
1301 ;; Operand 6: new multiplication
1302 ;; Operand 7: new addition/subtraction
1304 [(match_scratch:SI 0 "d")
1305 (set (match_operand:SI 1 "register_operand")
1306 (match_operand:SI 2 "register_operand"))
1309 [(set (match_operand:SI 3 "register_operand")
1310 (match_operand:SI 4 "macc_msac_operand"))
1311 (clobber (match_operand:SI 5 "register_operand"))
1312 (clobber (match_dup 1))])]
1314 && true_regnum (operands[1]) == LO_REGNUM
1315 && peep2_reg_dead_p (2, operands[1])
1316 && GP_REG_P (true_regnum (operands[3]))"
1317 [(parallel [(set (match_dup 0)
1319 (clobber (match_dup 5))
1320 (clobber (match_dup 1))])
1324 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1325 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1326 operands[2], operands[0]);
1329 ;; Same as above, except LO is the initial target of the macc.
1331 ;; Operand 0: GPR (scratch)
1333 ;; Operand 2: GPR (addend)
1334 ;; Operand 3: macc/msac
1336 ;; Operand 5: GPR (destination)
1337 ;; Operand 6: new multiplication
1338 ;; Operand 7: new addition/subtraction
1340 [(match_scratch:SI 0 "d")
1341 (set (match_operand:SI 1 "register_operand")
1342 (match_operand:SI 2 "register_operand"))
1346 (match_operand:SI 3 "macc_msac_operand"))
1347 (clobber (match_operand:SI 4 "register_operand"))
1348 (clobber (scratch:SI))])
1350 (set (match_operand:SI 5 "register_operand")
1351 (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1352 "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1353 [(parallel [(set (match_dup 0)
1355 (clobber (match_dup 4))
1356 (clobber (match_dup 1))])
1360 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1361 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1362 operands[2], operands[0]);
1365 (define_insn "*mul_sub_si"
1366 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1367 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1368 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1369 (match_operand:SI 3 "register_operand" "d,d,d"))))
1370 (clobber (match_scratch:SI 4 "=h,h,h"))
1371 (clobber (match_scratch:SI 5 "=X,1,l"))
1372 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1378 [(set_attr "type" "imadd,multi,multi")
1379 (set_attr "mode" "SI")
1380 (set_attr "length" "4,8,8")])
1382 ;; Split the above insn if we failed to get LO allocated.
1384 [(set (match_operand:SI 0 "register_operand")
1385 (minus:SI (match_operand:SI 1 "register_operand")
1386 (mult:SI (match_operand:SI 2 "register_operand")
1387 (match_operand:SI 3 "register_operand"))))
1388 (clobber (match_scratch:SI 4))
1389 (clobber (match_scratch:SI 5))
1390 (clobber (match_scratch:SI 6))]
1391 "reload_completed && !TARGET_DEBUG_D_MODE
1392 && GP_REG_P (true_regnum (operands[0]))
1393 && GP_REG_P (true_regnum (operands[1]))"
1394 [(parallel [(set (match_dup 6)
1395 (mult:SI (match_dup 2) (match_dup 3)))
1396 (clobber (match_dup 4))
1397 (clobber (match_dup 5))])
1398 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1401 ;; Splitter to copy result of MSUB to a general register
1403 [(set (match_operand:SI 0 "register_operand")
1404 (minus:SI (match_operand:SI 1 "register_operand")
1405 (mult:SI (match_operand:SI 2 "register_operand")
1406 (match_operand:SI 3 "register_operand"))))
1407 (clobber (match_scratch:SI 4))
1408 (clobber (match_scratch:SI 5))
1409 (clobber (match_scratch:SI 6))]
1410 "reload_completed && !TARGET_DEBUG_D_MODE
1411 && GP_REG_P (true_regnum (operands[0]))
1412 && true_regnum (operands[1]) == LO_REGNUM"
1413 [(parallel [(set (match_dup 1)
1414 (minus:SI (match_dup 1)
1415 (mult:SI (match_dup 2) (match_dup 3))))
1416 (clobber (match_dup 4))
1417 (clobber (match_dup 5))
1418 (clobber (match_dup 6))])
1419 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1422 (define_insn "*muls"
1423 [(set (match_operand:SI 0 "register_operand" "=l,d")
1424 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1425 (match_operand:SI 2 "register_operand" "d,d"))))
1426 (clobber (match_scratch:SI 3 "=h,h"))
1427 (clobber (match_scratch:SI 4 "=X,l"))]
1432 [(set_attr "type" "imul")
1433 (set_attr "mode" "SI")])
1435 (define_expand "muldi3"
1436 [(set (match_operand:DI 0 "register_operand")
1437 (mult:DI (match_operand:DI 1 "register_operand")
1438 (match_operand:DI 2 "register_operand")))]
1441 if (GENERATE_MULT3_DI)
1442 emit_insn (gen_muldi3_mult3 (operands[0], operands[1], operands[2]));
1443 else if (!TARGET_FIX_R4000)
1444 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1446 emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
1450 (define_insn "muldi3_mult3"
1451 [(set (match_operand:DI 0 "register_operand" "=d")
1452 (mult:DI (match_operand:DI 1 "register_operand" "d")
1453 (match_operand:DI 2 "register_operand" "d")))
1454 (clobber (match_scratch:DI 3 "=h"))
1455 (clobber (match_scratch:DI 4 "=l"))]
1456 "TARGET_64BIT && GENERATE_MULT3_DI"
1458 [(set_attr "type" "imul")
1459 (set_attr "mode" "DI")])
1461 (define_insn "muldi3_internal"
1462 [(set (match_operand:DI 0 "register_operand" "=l")
1463 (mult:DI (match_operand:DI 1 "register_operand" "d")
1464 (match_operand:DI 2 "register_operand" "d")))
1465 (clobber (match_scratch:DI 3 "=h"))]
1466 "TARGET_64BIT && !TARGET_FIX_R4000"
1468 [(set_attr "type" "imul")
1469 (set_attr "mode" "DI")])
1471 (define_insn "muldi3_r4000"
1472 [(set (match_operand:DI 0 "register_operand" "=d")
1473 (mult:DI (match_operand:DI 1 "register_operand" "d")
1474 (match_operand:DI 2 "register_operand" "d")))
1475 (clobber (match_scratch:DI 3 "=h"))
1476 (clobber (match_scratch:DI 4 "=l"))]
1477 "TARGET_64BIT && TARGET_FIX_R4000"
1478 "dmult\t%1,%2\;mflo\t%0"
1479 [(set_attr "type" "imul")
1480 (set_attr "mode" "DI")
1481 (set_attr "length" "8")])
1483 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1485 (define_expand "mulsidi3"
1487 [(set (match_operand:DI 0 "register_operand")
1489 (sign_extend:DI (match_operand:SI 1 "register_operand"))
1490 (sign_extend:DI (match_operand:SI 2 "register_operand"))))
1491 (clobber (scratch:DI))
1492 (clobber (scratch:DI))
1493 (clobber (scratch:DI))])]
1494 "!TARGET_64BIT || !TARGET_FIX_R4000"
1498 if (!TARGET_FIX_R4000)
1499 emit_insn (gen_mulsidi3_32bit_internal (operands[0], operands[1],
1502 emit_insn (gen_mulsidi3_32bit_r4000 (operands[0], operands[1],
1508 (define_insn "mulsidi3_32bit_internal"
1509 [(set (match_operand:DI 0 "register_operand" "=x")
1511 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1512 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1513 "!TARGET_64BIT && !TARGET_FIX_R4000"
1515 [(set_attr "type" "imul")
1516 (set_attr "mode" "SI")])
1518 (define_insn "mulsidi3_32bit_r4000"
1519 [(set (match_operand:DI 0 "register_operand" "=d")
1521 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1522 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1523 (clobber (match_scratch:DI 3 "=l"))
1524 (clobber (match_scratch:DI 4 "=h"))]
1525 "!TARGET_64BIT && TARGET_FIX_R4000"
1526 "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1527 [(set_attr "type" "imul")
1528 (set_attr "mode" "SI")
1529 (set_attr "length" "12")])
1531 (define_insn_and_split "*mulsidi3_64bit"
1532 [(set (match_operand:DI 0 "register_operand" "=d")
1533 (mult:DI (match_operator:DI 1 "extend_operator"
1534 [(match_operand:SI 3 "register_operand" "d")])
1535 (match_operator:DI 2 "extend_operator"
1536 [(match_operand:SI 4 "register_operand" "d")])))
1537 (clobber (match_scratch:DI 5 "=l"))
1538 (clobber (match_scratch:DI 6 "=h"))
1539 (clobber (match_scratch:DI 7 "=d"))]
1540 "TARGET_64BIT && !TARGET_FIX_R4000
1541 && GET_CODE (operands[1]) == GET_CODE (operands[2])"
1543 "&& reload_completed"
1547 (mult:SI (match_dup 3)
1551 (mult:DI (match_dup 1)
1555 ;; OP7 <- LO, OP0 <- HI
1556 (set (match_dup 7) (unspec:DI [(match_dup 5) (match_dup 6)] UNSPEC_MFHILO))
1557 (set (match_dup 0) (unspec:DI [(match_dup 6) (match_dup 5)] UNSPEC_MFHILO))
1561 (ashift:DI (match_dup 7)
1564 (lshiftrt:DI (match_dup 7)
1567 ;; Shift OP0 into place.
1569 (ashift:DI (match_dup 0)
1572 ;; OR the two halves together
1574 (ior:DI (match_dup 0)
1577 [(set_attr "type" "imul")
1578 (set_attr "mode" "SI")
1579 (set_attr "length" "24")])
1581 (define_insn "*mulsidi3_64bit_parts"
1582 [(set (match_operand:DI 0 "register_operand" "=l")
1584 (mult:SI (match_operand:SI 2 "register_operand" "d")
1585 (match_operand:SI 3 "register_operand" "d"))))
1586 (set (match_operand:DI 1 "register_operand" "=h")
1589 (match_operator:DI 4 "extend_operator" [(match_dup 2)])
1590 (match_operator:DI 5 "extend_operator" [(match_dup 3)]))
1592 "TARGET_64BIT && !TARGET_FIX_R4000
1593 && GET_CODE (operands[4]) == GET_CODE (operands[5])"
1595 if (GET_CODE (operands[4]) == SIGN_EXTEND)
1596 return "mult\t%2,%3";
1598 return "multu\t%2,%3";
1600 [(set_attr "type" "imul")
1601 (set_attr "mode" "SI")])
1603 (define_expand "umulsidi3"
1605 [(set (match_operand:DI 0 "register_operand")
1607 (zero_extend:DI (match_operand:SI 1 "register_operand"))
1608 (zero_extend:DI (match_operand:SI 2 "register_operand"))))
1609 (clobber (scratch:DI))
1610 (clobber (scratch:DI))
1611 (clobber (scratch:DI))])]
1612 "!TARGET_64BIT || !TARGET_FIX_R4000"
1616 if (!TARGET_FIX_R4000)
1617 emit_insn (gen_umulsidi3_32bit_internal (operands[0], operands[1],
1620 emit_insn (gen_umulsidi3_32bit_r4000 (operands[0], operands[1],
1626 (define_insn "umulsidi3_32bit_internal"
1627 [(set (match_operand:DI 0 "register_operand" "=x")
1629 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1630 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1631 "!TARGET_64BIT && !TARGET_FIX_R4000"
1633 [(set_attr "type" "imul")
1634 (set_attr "mode" "SI")])
1636 (define_insn "umulsidi3_32bit_r4000"
1637 [(set (match_operand:DI 0 "register_operand" "=d")
1639 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1640 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1641 (clobber (match_scratch:DI 3 "=l"))
1642 (clobber (match_scratch:DI 4 "=h"))]
1643 "!TARGET_64BIT && TARGET_FIX_R4000"
1644 "multu\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1645 [(set_attr "type" "imul")
1646 (set_attr "mode" "SI")
1647 (set_attr "length" "12")])
1649 ;; Widening multiply with negation.
1650 (define_insn "*muls_di"
1651 [(set (match_operand:DI 0 "register_operand" "=x")
1654 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1655 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1656 "!TARGET_64BIT && ISA_HAS_MULS"
1658 [(set_attr "type" "imul")
1659 (set_attr "length" "4")
1660 (set_attr "mode" "SI")])
1662 (define_insn "*umuls_di"
1663 [(set (match_operand:DI 0 "register_operand" "=x")
1666 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1667 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1668 "!TARGET_64BIT && ISA_HAS_MULS"
1670 [(set_attr "type" "imul")
1671 (set_attr "length" "4")
1672 (set_attr "mode" "SI")])
1674 (define_insn "*smsac_di"
1675 [(set (match_operand:DI 0 "register_operand" "=x")
1677 (match_operand:DI 3 "register_operand" "0")
1679 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1680 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1681 "!TARGET_64BIT && ISA_HAS_MSAC"
1683 if (TARGET_MIPS5500)
1684 return "msub\t%1,%2";
1686 return "msac\t$0,%1,%2";
1688 [(set_attr "type" "imadd")
1689 (set_attr "length" "4")
1690 (set_attr "mode" "SI")])
1692 (define_insn "*umsac_di"
1693 [(set (match_operand:DI 0 "register_operand" "=x")
1695 (match_operand:DI 3 "register_operand" "0")
1697 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1698 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1699 "!TARGET_64BIT && ISA_HAS_MSAC"
1701 if (TARGET_MIPS5500)
1702 return "msubu\t%1,%2";
1704 return "msacu\t$0,%1,%2";
1706 [(set_attr "type" "imadd")
1707 (set_attr "length" "4")
1708 (set_attr "mode" "SI")])
1710 ;; _highpart patterns
1711 (define_expand "umulsi3_highpart"
1712 [(set (match_operand:SI 0 "register_operand")
1715 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"))
1716 (zero_extend:DI (match_operand:SI 2 "register_operand")))
1718 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1721 emit_insn (gen_umulsi3_highpart_mulhi_internal (operands[0], operands[1],
1724 emit_insn (gen_umulsi3_highpart_internal (operands[0], operands[1],
1729 (define_insn "umulsi3_highpart_internal"
1730 [(set (match_operand:SI 0 "register_operand" "=h")
1733 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1734 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1736 (clobber (match_scratch:SI 3 "=l"))]
1737 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1739 [(set_attr "type" "imul")
1740 (set_attr "mode" "SI")
1741 (set_attr "length" "4")])
1743 (define_insn "umulsi3_highpart_mulhi_internal"
1744 [(set (match_operand:SI 0 "register_operand" "=h,d")
1747 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1748 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1750 (clobber (match_scratch:SI 3 "=l,l"))
1751 (clobber (match_scratch:SI 4 "=X,h"))]
1756 [(set_attr "type" "imul")
1757 (set_attr "mode" "SI")
1758 (set_attr "length" "4")])
1760 (define_insn "umulsi3_highpart_neg_mulhi_internal"
1761 [(set (match_operand:SI 0 "register_operand" "=h,d")
1765 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1766 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1768 (clobber (match_scratch:SI 3 "=l,l"))
1769 (clobber (match_scratch:SI 4 "=X,h"))]
1774 [(set_attr "type" "imul")
1775 (set_attr "mode" "SI")
1776 (set_attr "length" "4")])
1778 (define_expand "smulsi3_highpart"
1779 [(set (match_operand:SI 0 "register_operand")
1782 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"))
1783 (sign_extend:DI (match_operand:SI 2 "register_operand")))
1785 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1788 emit_insn (gen_smulsi3_highpart_mulhi_internal (operands[0], operands[1],
1791 emit_insn (gen_smulsi3_highpart_internal (operands[0], operands[1],
1796 (define_insn "smulsi3_highpart_internal"
1797 [(set (match_operand:SI 0 "register_operand" "=h")
1800 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1801 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1803 (clobber (match_scratch:SI 3 "=l"))]
1804 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1806 [(set_attr "type" "imul")
1807 (set_attr "mode" "SI")
1808 (set_attr "length" "4")])
1810 (define_insn "smulsi3_highpart_mulhi_internal"
1811 [(set (match_operand:SI 0 "register_operand" "=h,d")
1814 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1815 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1817 (clobber (match_scratch:SI 3 "=l,l"))
1818 (clobber (match_scratch:SI 4 "=X,h"))]
1823 [(set_attr "type" "imul")
1824 (set_attr "mode" "SI")
1825 (set_attr "length" "4")])
1827 (define_insn "smulsi3_highpart_neg_mulhi_internal"
1828 [(set (match_operand:SI 0 "register_operand" "=h,d")
1832 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1833 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1835 (clobber (match_scratch:SI 3 "=l,l"))
1836 (clobber (match_scratch:SI 4 "=X,h"))]
1841 [(set_attr "type" "imul")
1842 (set_attr "mode" "SI")])
1844 (define_insn "smuldi3_highpart"
1845 [(set (match_operand:DI 0 "register_operand" "=h")
1849 (sign_extend:TI (match_operand:DI 1 "register_operand" "d"))
1850 (sign_extend:TI (match_operand:DI 2 "register_operand" "d")))
1852 (clobber (match_scratch:DI 3 "=l"))]
1853 "TARGET_64BIT && !TARGET_FIX_R4000"
1855 [(set_attr "type" "imul")
1856 (set_attr "mode" "DI")])
1858 ;; Disable this pattern for -mfix-vr4120. This is for VR4120 errata MD(0),
1859 ;; which says that dmultu does not always produce the correct result.
1860 (define_insn "umuldi3_highpart"
1861 [(set (match_operand:DI 0 "register_operand" "=h")
1865 (zero_extend:TI (match_operand:DI 1 "register_operand" "d"))
1866 (zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
1868 (clobber (match_scratch:DI 3 "=l"))]
1869 "TARGET_64BIT && !TARGET_FIX_R4000 && !TARGET_FIX_VR4120"
1871 [(set_attr "type" "imul")
1872 (set_attr "mode" "DI")])
1875 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1876 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
1878 (define_insn "madsi"
1879 [(set (match_operand:SI 0 "register_operand" "+l")
1880 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1881 (match_operand:SI 2 "register_operand" "d"))
1883 (clobber (match_scratch:SI 3 "=h"))]
1886 [(set_attr "type" "imadd")
1887 (set_attr "mode" "SI")])
1889 (define_insn "*umul_acc_di"
1890 [(set (match_operand:DI 0 "register_operand" "=x")
1892 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1893 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1894 (match_operand:DI 3 "register_operand" "0")))]
1895 "(TARGET_MAD || ISA_HAS_MACC)
1899 return "madu\t%1,%2";
1900 else if (TARGET_MIPS5500)
1901 return "maddu\t%1,%2";
1903 /* See comment in *macc. */
1904 return "%[maccu\t%@,%1,%2%]";
1906 [(set_attr "type" "imadd")
1907 (set_attr "mode" "SI")])
1910 (define_insn "*smul_acc_di"
1911 [(set (match_operand:DI 0 "register_operand" "=x")
1913 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1914 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1915 (match_operand:DI 3 "register_operand" "0")))]
1916 "(TARGET_MAD || ISA_HAS_MACC)
1920 return "mad\t%1,%2";
1921 else if (TARGET_MIPS5500)
1922 return "madd\t%1,%2";
1924 /* See comment in *macc. */
1925 return "%[macc\t%@,%1,%2%]";
1927 [(set_attr "type" "imadd")
1928 (set_attr "mode" "SI")])
1930 ;; Floating point multiply accumulate instructions.
1933 [(set (match_operand:DF 0 "register_operand" "=f")
1934 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1935 (match_operand:DF 2 "register_operand" "f"))
1936 (match_operand:DF 3 "register_operand" "f")))]
1937 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1938 "madd.d\t%0,%3,%1,%2"
1939 [(set_attr "type" "fmadd")
1940 (set_attr "mode" "DF")])
1943 [(set (match_operand:SF 0 "register_operand" "=f")
1944 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1945 (match_operand:SF 2 "register_operand" "f"))
1946 (match_operand:SF 3 "register_operand" "f")))]
1947 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1948 "madd.s\t%0,%3,%1,%2"
1949 [(set_attr "type" "fmadd")
1950 (set_attr "mode" "SF")])
1953 [(set (match_operand:DF 0 "register_operand" "=f")
1954 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1955 (match_operand:DF 2 "register_operand" "f"))
1956 (match_operand:DF 3 "register_operand" "f")))]
1957 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1958 "msub.d\t%0,%3,%1,%2"
1959 [(set_attr "type" "fmadd")
1960 (set_attr "mode" "DF")])
1963 [(set (match_operand:SF 0 "register_operand" "=f")
1964 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1965 (match_operand:SF 2 "register_operand" "f"))
1966 (match_operand:SF 3 "register_operand" "f")))]
1968 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1969 "msub.s\t%0,%3,%1,%2"
1970 [(set_attr "type" "fmadd")
1971 (set_attr "mode" "SF")])
1974 [(set (match_operand:DF 0 "register_operand" "=f")
1975 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1976 (match_operand:DF 2 "register_operand" "f"))
1977 (match_operand:DF 3 "register_operand" "f"))))]
1978 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1979 "nmadd.d\t%0,%3,%1,%2"
1980 [(set_attr "type" "fmadd")
1981 (set_attr "mode" "DF")])
1984 [(set (match_operand:SF 0 "register_operand" "=f")
1985 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1986 (match_operand:SF 2 "register_operand" "f"))
1987 (match_operand:SF 3 "register_operand" "f"))))]
1988 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1989 "nmadd.s\t%0,%3,%1,%2"
1990 [(set_attr "type" "fmadd")
1991 (set_attr "mode" "SF")])
1994 [(set (match_operand:DF 0 "register_operand" "=f")
1995 (minus:DF (match_operand:DF 1 "register_operand" "f")
1996 (mult:DF (match_operand:DF 2 "register_operand" "f")
1997 (match_operand:DF 3 "register_operand" "f"))))]
1998 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1999 "nmsub.d\t%0,%1,%2,%3"
2000 [(set_attr "type" "fmadd")
2001 (set_attr "mode" "DF")])
2004 [(set (match_operand:SF 0 "register_operand" "=f")
2005 (minus:SF (match_operand:SF 1 "register_operand" "f")
2006 (mult:SF (match_operand:SF 2 "register_operand" "f")
2007 (match_operand:SF 3 "register_operand" "f"))))]
2008 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2009 "nmsub.s\t%0,%1,%2,%3"
2010 [(set_attr "type" "fmadd")
2011 (set_attr "mode" "SF")])
2014 ;; ....................
2016 ;; DIVISION and REMAINDER
2018 ;; ....................
2021 (define_expand "divdf3"
2022 [(set (match_operand:DF 0 "register_operand")
2023 (div:DF (match_operand:DF 1 "reg_or_const_float_1_operand")
2024 (match_operand:DF 2 "register_operand")))]
2025 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2027 if (const_float_1_operand (operands[1], DFmode))
2028 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2029 operands[1] = force_reg (DFmode, operands[1]);
2032 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
2034 ;; If an mfc1 or dmfc1 happens to access the floating point register
2035 ;; file at the same time a long latency operation (div, sqrt, recip,
2036 ;; sqrt) iterates an intermediate result back through the floating
2037 ;; point register file bypass, then instead returning the correct
2038 ;; register value the mfc1 or dmfc1 operation returns the intermediate
2039 ;; result of the long latency operation.
2041 ;; The workaround is to insert an unconditional 'mov' from/to the
2042 ;; long latency op destination register.
2044 (define_insn "*divdf3"
2045 [(set (match_operand:DF 0 "register_operand" "=f")
2046 (div:DF (match_operand:DF 1 "register_operand" "f")
2047 (match_operand:DF 2 "register_operand" "f")))]
2048 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2051 return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
2053 return "div.d\t%0,%1,%2";
2055 [(set_attr "type" "fdiv")
2056 (set_attr "mode" "DF")
2057 (set (attr "length")
2058 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2063 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
2065 ;; In certain cases, div.s and div.ps may have a rounding error
2066 ;; and/or wrong inexact flag.
2068 ;; Therefore, we only allow div.s if not working around SB-1 rev2
2069 ;; errata, or if working around those errata and a slight loss of
2070 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
2071 (define_expand "divsf3"
2072 [(set (match_operand:SF 0 "register_operand")
2073 (div:SF (match_operand:SF 1 "reg_or_const_float_1_operand")
2074 (match_operand:SF 2 "register_operand")))]
2075 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2077 if (const_float_1_operand (operands[1], SFmode))
2078 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2079 operands[1] = force_reg (SFmode, operands[1]);
2082 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2083 ;; "divdf3" comment for details).
2085 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
2086 ;; "divsf3" comment for details).
2087 (define_insn "*divsf3"
2088 [(set (match_operand:SF 0 "register_operand" "=f")
2089 (div:SF (match_operand:SF 1 "register_operand" "f")
2090 (match_operand:SF 2 "register_operand" "f")))]
2091 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2094 return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
2096 return "div.s\t%0,%1,%2";
2098 [(set_attr "type" "fdiv")
2099 (set_attr "mode" "SF")
2100 (set (attr "length")
2101 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2105 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2106 ;; "divdf3" comment for details).
2108 [(set (match_operand:DF 0 "register_operand" "=f")
2109 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2110 (match_operand:DF 2 "register_operand" "f")))]
2111 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2114 return "recip.d\t%0,%2\;mov.d\t%0,%0";
2116 return "recip.d\t%0,%2";
2118 [(set_attr "type" "fdiv")
2119 (set_attr "mode" "DF")
2120 (set (attr "length")
2121 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2125 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2126 ;; "divdf3" comment for details).
2128 [(set (match_operand:SF 0 "register_operand" "=f")
2129 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2130 (match_operand:SF 2 "register_operand" "f")))]
2131 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2134 return "recip.s\t%0,%2\;mov.s\t%0,%0";
2136 return "recip.s\t%0,%2";
2138 [(set_attr "type" "fdiv")
2139 (set_attr "mode" "SF")
2140 (set (attr "length")
2141 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2145 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2146 ;; with negative operands. We use special libgcc functions instead.
2147 (define_insn "divmodsi4"
2148 [(set (match_operand:SI 0 "register_operand" "=l")
2149 (div:SI (match_operand:SI 1 "register_operand" "d")
2150 (match_operand:SI 2 "register_operand" "d")))
2151 (set (match_operand:SI 3 "register_operand" "=h")
2152 (mod:SI (match_dup 1)
2154 "!TARGET_FIX_VR4120"
2155 { return mips_output_division ("div\t$0,%1,%2", operands); }
2156 [(set_attr "type" "idiv")
2157 (set_attr "mode" "SI")])
2159 (define_insn "divmoddi4"
2160 [(set (match_operand:DI 0 "register_operand" "=l")
2161 (div:DI (match_operand:DI 1 "register_operand" "d")
2162 (match_operand:DI 2 "register_operand" "d")))
2163 (set (match_operand:DI 3 "register_operand" "=h")
2164 (mod:DI (match_dup 1)
2166 "TARGET_64BIT && !TARGET_FIX_VR4120"
2167 { return mips_output_division ("ddiv\t$0,%1,%2", operands); }
2168 [(set_attr "type" "idiv")
2169 (set_attr "mode" "DI")])
2171 (define_insn "udivmodsi4"
2172 [(set (match_operand:SI 0 "register_operand" "=l")
2173 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2174 (match_operand:SI 2 "register_operand" "d")))
2175 (set (match_operand:SI 3 "register_operand" "=h")
2176 (umod:SI (match_dup 1)
2179 { return mips_output_division ("divu\t$0,%1,%2", operands); }
2180 [(set_attr "type" "idiv")
2181 (set_attr "mode" "SI")])
2183 (define_insn "udivmoddi4"
2184 [(set (match_operand:DI 0 "register_operand" "=l")
2185 (udiv:DI (match_operand:DI 1 "register_operand" "d")
2186 (match_operand:DI 2 "register_operand" "d")))
2187 (set (match_operand:DI 3 "register_operand" "=h")
2188 (umod:DI (match_dup 1)
2191 { return mips_output_division ("ddivu\t$0,%1,%2", operands); }
2192 [(set_attr "type" "idiv")
2193 (set_attr "mode" "DI")])
2196 ;; ....................
2200 ;; ....................
2202 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2203 ;; "divdf3" comment for details).
2204 (define_insn "sqrtdf2"
2205 [(set (match_operand:DF 0 "register_operand" "=f")
2206 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2207 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2210 return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
2212 return "sqrt.d\t%0,%1";
2214 [(set_attr "type" "fsqrt")
2215 (set_attr "mode" "DF")
2216 (set (attr "length")
2217 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2221 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2222 ;; "divdf3" comment for details).
2223 (define_insn "sqrtsf2"
2224 [(set (match_operand:SF 0 "register_operand" "=f")
2225 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2226 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2229 return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
2231 return "sqrt.s\t%0,%1";
2233 [(set_attr "type" "fsqrt")
2234 (set_attr "mode" "SF")
2235 (set (attr "length")
2236 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2240 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2241 ;; "divdf3" comment for details).
2243 [(set (match_operand:DF 0 "register_operand" "=f")
2244 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2245 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2246 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2249 return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2251 return "rsqrt.d\t%0,%2";
2253 [(set_attr "type" "frsqrt")
2254 (set_attr "mode" "DF")
2255 (set (attr "length")
2256 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2260 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2261 ;; "divdf3" comment for details).
2263 [(set (match_operand:SF 0 "register_operand" "=f")
2264 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2265 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2266 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2269 return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2271 return "rsqrt.s\t%0,%2";
2273 [(set_attr "type" "frsqrt")
2274 (set_attr "mode" "SF")
2275 (set (attr "length")
2276 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2281 ;; ....................
2285 ;; ....................
2287 ;; Do not use the integer abs macro instruction, since that signals an
2288 ;; exception on -2147483648 (sigh).
2290 (define_insn "abssi2"
2291 [(set (match_operand:SI 0 "register_operand" "=d")
2292 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2295 operands[2] = const0_rtx;
2297 if (REGNO (operands[0]) == REGNO (operands[1]))
2299 if (GENERATE_BRANCHLIKELY)
2300 return "%(bltzl\t%1,1f\;subu\t%0,%z2,%0\n%~1:%)";
2302 return "bgez\t%1,1f%#\;subu\t%0,%z2,%0\n%~1:";
2305 return "%(bgez\t%1,1f\;move\t%0,%1\;subu\t%0,%z2,%0\n%~1:%)";
2307 [(set_attr "type" "multi")
2308 (set_attr "mode" "SI")
2309 (set_attr "length" "12")])
2311 (define_insn "absdi2"
2312 [(set (match_operand:DI 0 "register_operand" "=d")
2313 (abs:DI (match_operand:DI 1 "register_operand" "d")))]
2314 "TARGET_64BIT && !TARGET_MIPS16"
2316 unsigned int regno1;
2317 operands[2] = const0_rtx;
2319 if (GET_CODE (operands[1]) == REG)
2320 regno1 = REGNO (operands[1]);
2322 regno1 = REGNO (XEXP (operands[1], 0));
2324 if (REGNO (operands[0]) == regno1)
2325 return "%(bltzl\t%1,1f\;dsubu\t%0,%z2,%0\n%~1:%)";
2327 return "%(bgez\t%1,1f\;move\t%0,%1\;dsubu\t%0,%z2,%0\n%~1:%)";
2329 [(set_attr "type" "multi")
2330 (set_attr "mode" "DI")
2331 (set_attr "length" "12")])
2333 (define_insn "absdf2"
2334 [(set (match_operand:DF 0 "register_operand" "=f")
2335 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2336 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2338 [(set_attr "type" "fabs")
2339 (set_attr "mode" "DF")])
2341 (define_insn "abssf2"
2342 [(set (match_operand:SF 0 "register_operand" "=f")
2343 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2346 [(set_attr "type" "fabs")
2347 (set_attr "mode" "SF")])
2350 ;; ....................
2352 ;; FIND FIRST BIT INSTRUCTION
2354 ;; ....................
2357 (define_insn "ffssi2"
2358 [(set (match_operand:SI 0 "register_operand" "=&d")
2359 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2360 (clobber (match_scratch:SI 2 "=&d"))
2361 (clobber (match_scratch:SI 3 "=&d"))]
2364 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2368 %~1:\tand\t%2,%1,0x0001\;\
2378 %~1:\tand\t%2,%3,0x0001\;\
2384 [(set_attr "type" "multi")
2385 (set_attr "mode" "SI")
2386 (set_attr "length" "28")])
2388 (define_insn "ffsdi2"
2389 [(set (match_operand:DI 0 "register_operand" "=&d")
2390 (ffs:DI (match_operand:DI 1 "register_operand" "d")))
2391 (clobber (match_scratch:DI 2 "=&d"))
2392 (clobber (match_scratch:DI 3 "=&d"))]
2393 "TARGET_64BIT && !TARGET_MIPS16"
2395 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2399 %~1:\tand\t%2,%1,0x0001\;\
2409 %~1:\tand\t%2,%3,0x0001\;\
2415 [(set_attr "type" "multi")
2416 (set_attr "mode" "DI")
2417 (set_attr "length" "28")])
2420 ;; ...................
2422 ;; Count leading zeroes.
2424 ;; ...................
2427 (define_insn "clzsi2"
2428 [(set (match_operand:SI 0 "register_operand" "=d")
2429 (clz:SI (match_operand:SI 1 "register_operand" "d")))]
2432 [(set_attr "type" "clz")
2433 (set_attr "mode" "SI")])
2435 (define_insn "clzdi2"
2436 [(set (match_operand:DI 0 "register_operand" "=d")
2437 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
2440 [(set_attr "type" "clz")
2441 (set_attr "mode" "DI")])
2444 ;; ....................
2446 ;; NEGATION and ONE'S COMPLEMENT
2448 ;; ....................
2450 (define_insn "negsi2"
2451 [(set (match_operand:SI 0 "register_operand" "=d")
2452 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2456 return "neg\t%0,%1";
2458 return "subu\t%0,%.,%1";
2460 [(set_attr "type" "arith")
2461 (set_attr "mode" "SI")])
2463 (define_insn "negdi2"
2464 [(set (match_operand:DI 0 "register_operand" "=d")
2465 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2466 "TARGET_64BIT && !TARGET_MIPS16"
2468 [(set_attr "type" "arith")
2469 (set_attr "mode" "DI")])
2471 (define_insn "negdf2"
2472 [(set (match_operand:DF 0 "register_operand" "=f")
2473 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2474 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2476 [(set_attr "type" "fneg")
2477 (set_attr "mode" "DF")])
2479 (define_insn "negsf2"
2480 [(set (match_operand:SF 0 "register_operand" "=f")
2481 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2484 [(set_attr "type" "fneg")
2485 (set_attr "mode" "SF")])
2487 (define_insn "one_cmplsi2"
2488 [(set (match_operand:SI 0 "register_operand" "=d")
2489 (not:SI (match_operand:SI 1 "register_operand" "d")))]
2493 return "not\t%0,%1";
2495 return "nor\t%0,%.,%1";
2497 [(set_attr "type" "arith")
2498 (set_attr "mode" "SI")])
2500 (define_insn "one_cmpldi2"
2501 [(set (match_operand:DI 0 "register_operand" "=d")
2502 (not:DI (match_operand:DI 1 "register_operand" "d")))]
2506 return "not\t%0,%1";
2508 return "nor\t%0,%.,%1";
2510 [(set_attr "type" "arith")
2511 (set_attr "mode" "DI")])
2514 ;; ....................
2518 ;; ....................
2521 ;; Many of these instructions use trivial define_expands, because we
2522 ;; want to use a different set of constraints when TARGET_MIPS16.
2524 (define_expand "andsi3"
2525 [(set (match_operand:SI 0 "register_operand")
2526 (and:SI (match_operand:SI 1 "uns_arith_operand")
2527 (match_operand:SI 2 "uns_arith_operand")))]
2532 operands[1] = force_reg (SImode, operands[1]);
2533 operands[2] = force_reg (SImode, operands[2]);
2538 [(set (match_operand:SI 0 "register_operand" "=d,d")
2539 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2540 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2545 [(set_attr "type" "arith")
2546 (set_attr "mode" "SI")])
2549 [(set (match_operand:SI 0 "register_operand" "=d")
2550 (and:SI (match_operand:SI 1 "register_operand" "%0")
2551 (match_operand:SI 2 "register_operand" "d")))]
2554 [(set_attr "type" "arith")
2555 (set_attr "mode" "SI")])
2557 (define_expand "anddi3"
2558 [(set (match_operand:DI 0 "register_operand")
2559 (and:DI (match_operand:DI 1 "register_operand")
2560 (match_operand:DI 2 "uns_arith_operand")))]
2565 operands[1] = force_reg (DImode, operands[1]);
2566 operands[2] = force_reg (DImode, operands[2]);
2571 [(set (match_operand:DI 0 "register_operand" "=d,d")
2572 (and:DI (match_operand:DI 1 "register_operand" "d,d")
2573 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2574 "TARGET_64BIT && !TARGET_MIPS16"
2578 [(set_attr "type" "arith")
2579 (set_attr "mode" "DI")])
2582 [(set (match_operand:DI 0 "register_operand" "=d")
2583 (and:DI (match_operand:DI 1 "register_operand" "0")
2584 (match_operand:DI 2 "register_operand" "d")))]
2585 "TARGET_64BIT && TARGET_MIPS16"
2587 [(set_attr "type" "arith")
2588 (set_attr "mode" "DI")])
2590 (define_expand "iorsi3"
2591 [(set (match_operand:SI 0 "register_operand")
2592 (ior:SI (match_operand:SI 1 "uns_arith_operand")
2593 (match_operand:SI 2 "uns_arith_operand")))]
2598 operands[1] = force_reg (SImode, operands[1]);
2599 operands[2] = force_reg (SImode, operands[2]);
2604 [(set (match_operand:SI 0 "register_operand" "=d,d")
2605 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2606 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2611 [(set_attr "type" "arith")
2612 (set_attr "mode" "SI")])
2615 [(set (match_operand:SI 0 "register_operand" "=d")
2616 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2617 (match_operand:SI 2 "register_operand" "d")))]
2620 [(set_attr "type" "arith")
2621 (set_attr "mode" "SI")])
2623 (define_expand "iordi3"
2624 [(set (match_operand:DI 0 "register_operand")
2625 (ior:DI (match_operand:DI 1 "register_operand")
2626 (match_operand:DI 2 "uns_arith_operand")))]
2631 operands[1] = force_reg (DImode, operands[1]);
2632 operands[2] = force_reg (DImode, operands[2]);
2637 [(set (match_operand:DI 0 "register_operand" "=d,d")
2638 (ior:DI (match_operand:DI 1 "register_operand" "d,d")
2639 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2640 "TARGET_64BIT && !TARGET_MIPS16"
2644 [(set_attr "type" "arith")
2645 (set_attr "mode" "DI")])
2648 [(set (match_operand:DI 0 "register_operand" "=d")
2649 (ior:DI (match_operand:DI 1 "register_operand" "0")
2650 (match_operand:DI 2 "register_operand" "d")))]
2651 "TARGET_64BIT && TARGET_MIPS16"
2653 [(set_attr "type" "arith")
2654 (set_attr "mode" "DI")])
2656 (define_expand "xorsi3"
2657 [(set (match_operand:SI 0 "register_operand")
2658 (xor:SI (match_operand:SI 1 "uns_arith_operand")
2659 (match_operand:SI 2 "uns_arith_operand")))]
2664 [(set (match_operand:SI 0 "register_operand" "=d,d")
2665 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2666 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2671 [(set_attr "type" "arith")
2672 (set_attr "mode" "SI")])
2675 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
2676 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
2677 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
2683 [(set_attr "type" "arith")
2684 (set_attr "mode" "SI")
2685 (set_attr_alternative "length"
2687 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2692 (define_expand "xordi3"
2693 [(set (match_operand:DI 0 "register_operand")
2694 (xor:DI (match_operand:DI 1 "register_operand")
2695 (match_operand:DI 2 "uns_arith_operand")))]
2700 operands[1] = force_reg (DImode, operands[1]);
2701 operands[2] = force_reg (DImode, operands[2]);
2706 [(set (match_operand:DI 0 "register_operand" "=d,d")
2707 (xor:DI (match_operand:DI 1 "register_operand" "d,d")
2708 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2709 "TARGET_64BIT && !TARGET_MIPS16"
2713 [(set_attr "type" "arith")
2714 (set_attr "mode" "DI")])
2717 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
2718 (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
2719 (match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
2720 "TARGET_64BIT && TARGET_MIPS16"
2725 [(set_attr "type" "arith")
2726 (set_attr "mode" "DI")
2727 (set_attr_alternative "length"
2729 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2734 (define_insn "*norsi3"
2735 [(set (match_operand:SI 0 "register_operand" "=d")
2736 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
2737 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
2740 [(set_attr "type" "arith")
2741 (set_attr "mode" "SI")])
2743 (define_insn "*nordi3"
2744 [(set (match_operand:DI 0 "register_operand" "=d")
2745 (and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
2746 (not:DI (match_operand:DI 2 "register_operand" "d"))))]
2747 "TARGET_64BIT && !TARGET_MIPS16"
2749 [(set_attr "type" "arith")
2750 (set_attr "mode" "DI")])
2753 ;; ....................
2757 ;; ....................
2761 (define_insn "truncdfsf2"
2762 [(set (match_operand:SF 0 "register_operand" "=f")
2763 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2764 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2766 [(set_attr "type" "fcvt")
2767 (set_attr "mode" "SF")])
2769 ;; Integer truncation patterns. Truncating SImode values to smaller
2770 ;; modes is a no-op, as it is for most other GCC ports. Truncating
2771 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2772 ;; need to make sure that the lower 32 bits are properly sign-extended
2773 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
2774 ;; smaller than SImode is equivalent to two separate truncations:
2777 ;; DI ---> HI == DI ---> SI ---> HI
2778 ;; DI ---> QI == DI ---> SI ---> QI
2780 ;; Step A needs a real instruction but step B does not.
2782 (define_insn "truncdisi2"
2783 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2784 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2789 [(set_attr "type" "shift,store")
2790 (set_attr "mode" "SI")
2791 (set_attr "extended_mips16" "yes,*")])
2793 (define_insn "truncdihi2"
2794 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2795 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2800 [(set_attr "type" "shift,store")
2801 (set_attr "mode" "SI")
2802 (set_attr "extended_mips16" "yes,*")])
2804 (define_insn "truncdiqi2"
2805 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2806 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2811 [(set_attr "type" "shift,store")
2812 (set_attr "mode" "SI")
2813 (set_attr "extended_mips16" "yes,*")])
2815 ;; Combiner patterns to optimize shift/truncate combinations.
2818 [(set (match_operand:SI 0 "register_operand" "=d")
2819 (truncate:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2820 (match_operand:DI 2 "small_int" "I"))))]
2821 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2823 [(set_attr "type" "shift")
2824 (set_attr "mode" "SI")])
2827 [(set (match_operand:SI 0 "register_operand" "=d")
2828 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2830 "TARGET_64BIT && !TARGET_MIPS16"
2832 [(set_attr "type" "shift")
2833 (set_attr "mode" "SI")])
2836 ;; Combiner patterns for truncate/sign_extend combinations. They use
2837 ;; the shift/truncate patterns above.
2839 (define_insn_and_split ""
2840 [(set (match_operand:SI 0 "register_operand" "=d")
2842 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2843 "TARGET_64BIT && !TARGET_MIPS16"
2845 "&& reload_completed"
2847 (ashift:DI (match_dup 1)
2850 (truncate:SI (ashiftrt:DI (match_dup 2)
2852 { operands[2] = gen_lowpart (DImode, operands[0]); })
2854 (define_insn_and_split ""
2855 [(set (match_operand:SI 0 "register_operand" "=d")
2857 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2858 "TARGET_64BIT && !TARGET_MIPS16"
2860 "&& reload_completed"
2862 (ashift:DI (match_dup 1)
2865 (truncate:SI (ashiftrt:DI (match_dup 2)
2867 { operands[2] = gen_lowpart (DImode, operands[0]); })
2870 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2873 [(set (match_operand:SI 0 "register_operand" "=d")
2874 (zero_extend:SI (truncate:HI
2875 (match_operand:DI 1 "register_operand" "d"))))]
2876 "TARGET_64BIT && !TARGET_MIPS16"
2877 "andi\t%0,%1,0xffff"
2878 [(set_attr "type" "arith")
2879 (set_attr "mode" "SI")])
2882 [(set (match_operand:SI 0 "register_operand" "=d")
2883 (zero_extend:SI (truncate:QI
2884 (match_operand:DI 1 "register_operand" "d"))))]
2885 "TARGET_64BIT && !TARGET_MIPS16"
2887 [(set_attr "type" "arith")
2888 (set_attr "mode" "SI")])
2891 [(set (match_operand:HI 0 "register_operand" "=d")
2892 (zero_extend:HI (truncate:QI
2893 (match_operand:DI 1 "register_operand" "d"))))]
2894 "TARGET_64BIT && !TARGET_MIPS16"
2896 [(set_attr "type" "arith")
2897 (set_attr "mode" "HI")])
2900 ;; ....................
2904 ;; ....................
2907 ;; Those for integer source operand are ordered widest source type first.
2909 (define_insn_and_split "zero_extendsidi2"
2910 [(set (match_operand:DI 0 "register_operand" "=d")
2911 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2914 "&& reload_completed"
2916 (ashift:DI (match_dup 1) (const_int 32)))
2918 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2919 "operands[1] = gen_lowpart (DImode, operands[1]);"
2920 [(set_attr "type" "multi")
2921 (set_attr "mode" "DI")
2922 (set_attr "length" "8")])
2924 (define_insn "*zero_extendsidi2_mem"
2925 [(set (match_operand:DI 0 "register_operand" "=d")
2926 (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2929 [(set_attr "type" "load")
2930 (set_attr "mode" "DI")])
2932 (define_expand "zero_extendhisi2"
2933 [(set (match_operand:SI 0 "register_operand")
2934 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2937 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2939 rtx op = gen_lowpart (SImode, operands[1]);
2940 rtx temp = force_reg (SImode, GEN_INT (0xffff));
2942 emit_insn (gen_andsi3 (operands[0], op, temp));
2948 [(set (match_operand:SI 0 "register_operand" "=d,d")
2949 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2954 [(set_attr "type" "arith,load")
2955 (set_attr "mode" "SI")
2956 (set_attr "length" "4,*")])
2959 [(set (match_operand:SI 0 "register_operand" "=d")
2960 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2963 [(set_attr "type" "load")
2964 (set_attr "mode" "SI")])
2966 (define_expand "zero_extendhidi2"
2967 [(set (match_operand:DI 0 "register_operand")
2968 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2971 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2973 rtx op = gen_lowpart (DImode, operands[1]);
2974 rtx temp = force_reg (DImode, GEN_INT (0xffff));
2976 emit_insn (gen_anddi3 (operands[0], op, temp));
2982 [(set (match_operand:DI 0 "register_operand" "=d,d")
2983 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2984 "TARGET_64BIT && !TARGET_MIPS16"
2988 [(set_attr "type" "arith,load")
2989 (set_attr "mode" "DI")
2990 (set_attr "length" "4,*")])
2993 [(set (match_operand:DI 0 "register_operand" "=d")
2994 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2995 "TARGET_64BIT && TARGET_MIPS16"
2997 [(set_attr "type" "load")
2998 (set_attr "mode" "DI")])
3000 (define_expand "zero_extendqihi2"
3001 [(set (match_operand:HI 0 "register_operand")
3002 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3005 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3007 rtx op0 = gen_lowpart (SImode, operands[0]);
3008 rtx op1 = gen_lowpart (SImode, operands[1]);
3009 rtx temp = force_reg (SImode, GEN_INT (0xff));
3011 emit_insn (gen_andsi3 (op0, op1, temp));
3017 [(set (match_operand:HI 0 "register_operand" "=d,d")
3018 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3023 [(set_attr "type" "arith,load")
3024 (set_attr "mode" "HI")
3025 (set_attr "length" "4,*")])
3028 [(set (match_operand:HI 0 "register_operand" "=d")
3029 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3032 [(set_attr "type" "load")
3033 (set_attr "mode" "HI")])
3035 (define_expand "zero_extendqisi2"
3036 [(set (match_operand:SI 0 "register_operand")
3037 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3040 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3042 rtx op = gen_lowpart (SImode, operands[1]);
3043 rtx temp = force_reg (SImode, GEN_INT (0xff));
3045 emit_insn (gen_andsi3 (operands[0], op, temp));
3051 [(set (match_operand:SI 0 "register_operand" "=d,d")
3052 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3057 [(set_attr "type" "arith,load")
3058 (set_attr "mode" "SI")
3059 (set_attr "length" "4,*")])
3062 [(set (match_operand:SI 0 "register_operand" "=d")
3063 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3066 [(set_attr "type" "load")
3067 (set_attr "mode" "SI")])
3069 (define_expand "zero_extendqidi2"
3070 [(set (match_operand:DI 0 "register_operand")
3071 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3074 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3076 rtx op = gen_lowpart (DImode, operands[1]);
3077 rtx temp = force_reg (DImode, GEN_INT (0xff));
3079 emit_insn (gen_anddi3 (operands[0], op, temp));
3085 [(set (match_operand:DI 0 "register_operand" "=d,d")
3086 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3087 "TARGET_64BIT && !TARGET_MIPS16"
3091 [(set_attr "type" "arith,load")
3092 (set_attr "mode" "DI")
3093 (set_attr "length" "4,*")])
3096 [(set (match_operand:DI 0 "register_operand" "=d")
3097 (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3098 "TARGET_64BIT && TARGET_MIPS16"
3100 [(set_attr "type" "load")
3101 (set_attr "mode" "DI")])
3104 ;; ....................
3108 ;; ....................
3111 ;; Those for integer source operand are ordered widest source type first.
3113 ;; When TARGET_64BIT, all SImode integer registers should already be in
3114 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
3115 ;; therefore get rid of register->register instructions if we constrain
3116 ;; the source to be in the same register as the destination.
3118 ;; The register alternative has type "arith" so that the pre-reload
3119 ;; scheduler will treat it as a move. This reflects what happens if
3120 ;; the register alternative needs a reload.
3121 (define_insn_and_split "extendsidi2"
3122 [(set (match_operand:DI 0 "register_operand" "=d,d")
3123 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
3128 "&& reload_completed && register_operand (operands[1], VOIDmode)"
3131 emit_note (NOTE_INSN_DELETED);
3134 [(set_attr "type" "arith,load")
3135 (set_attr "mode" "DI")])
3137 ;; These patterns originally accepted general_operands, however, slightly
3138 ;; better code is generated by only accepting register_operands, and then
3139 ;; letting combine generate the lh and lb insns.
3141 ;; These expanders originally put values in registers first. We split
3142 ;; all non-mem patterns after reload.
3144 (define_expand "extendhidi2"
3145 [(set (match_operand:DI 0 "register_operand")
3146 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
3150 (define_insn "*extendhidi2"
3151 [(set (match_operand:DI 0 "register_operand" "=d")
3152 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
3157 [(set (match_operand:DI 0 "register_operand")
3158 (sign_extend:DI (match_operand:HI 1 "register_operand")))]
3159 "TARGET_64BIT && reload_completed"
3161 (ashift:DI (match_dup 1) (const_int 48)))
3163 (ashiftrt:DI (match_dup 0) (const_int 48)))]
3164 "operands[1] = gen_lowpart (DImode, operands[1]);")
3166 (define_insn "*extendhidi2_mem"
3167 [(set (match_operand:DI 0 "register_operand" "=d")
3168 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3171 [(set_attr "type" "load")
3172 (set_attr "mode" "DI")])
3174 (define_expand "extendhisi2"
3175 [(set (match_operand:SI 0 "register_operand")
3176 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
3179 if (ISA_HAS_SEB_SEH)
3181 emit_insn (gen_extendhisi2_hw (operands[0],
3182 force_reg (HImode, operands[1])));
3187 (define_insn "*extendhisi2"
3188 [(set (match_operand:SI 0 "register_operand" "=d")
3189 (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
3194 [(set (match_operand:SI 0 "register_operand")
3195 (sign_extend:SI (match_operand:HI 1 "register_operand")))]
3198 (ashift:SI (match_dup 1) (const_int 16)))
3200 (ashiftrt:SI (match_dup 0) (const_int 16)))]
3201 "operands[1] = gen_lowpart (SImode, operands[1]);")
3203 (define_insn "extendhisi2_mem"
3204 [(set (match_operand:SI 0 "register_operand" "=d")
3205 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3208 [(set_attr "type" "load")
3209 (set_attr "mode" "SI")])
3211 (define_insn "extendhisi2_hw"
3212 [(set (match_operand:SI 0 "register_operand" "=r")
3213 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
3216 [(set_attr "type" "arith")
3217 (set_attr "mode" "SI")])
3219 (define_expand "extendqihi2"
3220 [(set (match_operand:HI 0 "register_operand")
3221 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3225 (define_insn "*extendqihi2"
3226 [(set (match_operand:HI 0 "register_operand" "=d")
3227 (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
3232 [(set (match_operand:HI 0 "register_operand")
3233 (sign_extend:HI (match_operand:QI 1 "register_operand")))]
3236 (ashift:SI (match_dup 1) (const_int 24)))
3238 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3239 "operands[0] = gen_lowpart (SImode, operands[0]);
3240 operands[1] = gen_lowpart (SImode, operands[1]);")
3242 (define_insn "*extendqihi2_internal_mem"
3243 [(set (match_operand:HI 0 "register_operand" "=d")
3244 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3247 [(set_attr "type" "load")
3248 (set_attr "mode" "SI")])
3251 (define_expand "extendqisi2"
3252 [(set (match_operand:SI 0 "register_operand")
3253 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3256 if (ISA_HAS_SEB_SEH)
3258 emit_insn (gen_extendqisi2_hw (operands[0],
3259 force_reg (QImode, operands[1])));
3264 (define_insn "*extendqisi2"
3265 [(set (match_operand:SI 0 "register_operand" "=d")
3266 (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
3271 [(set (match_operand:SI 0 "register_operand")
3272 (sign_extend:SI (match_operand:QI 1 "register_operand")))]
3275 (ashift:SI (match_dup 1) (const_int 24)))
3277 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3278 "operands[1] = gen_lowpart (SImode, operands[1]);")
3280 (define_insn "*extendqisi2_mem"
3281 [(set (match_operand:SI 0 "register_operand" "=d")
3282 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3285 [(set_attr "type" "load")
3286 (set_attr "mode" "SI")])
3288 (define_insn "extendqisi2_hw"
3289 [(set (match_operand:SI 0 "register_operand" "=r")
3290 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
3293 [(set_attr "type" "arith")
3294 (set_attr "mode" "SI")])
3296 (define_expand "extendqidi2"
3297 [(set (match_operand:DI 0 "register_operand")
3298 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3302 (define_insn "*extendqidi2"
3303 [(set (match_operand:DI 0 "register_operand" "=d")
3304 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
3309 [(set (match_operand:DI 0 "register_operand")
3310 (sign_extend:DI (match_operand:QI 1 "register_operand")))]
3311 "TARGET_64BIT && reload_completed"
3313 (ashift:DI (match_dup 1) (const_int 56)))
3315 (ashiftrt:DI (match_dup 0) (const_int 56)))]
3316 "operands[1] = gen_lowpart (DImode, operands[1]);")
3318 (define_insn "*extendqidi2_mem"
3319 [(set (match_operand:DI 0 "register_operand" "=d")
3320 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3323 [(set_attr "type" "load")
3324 (set_attr "mode" "DI")])
3326 (define_insn "extendsfdf2"
3327 [(set (match_operand:DF 0 "register_operand" "=f")
3328 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3329 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3331 [(set_attr "type" "fcvt")
3332 (set_attr "mode" "DF")])
3335 ;; ....................
3339 ;; ....................
3341 (define_expand "fix_truncdfsi2"
3342 [(set (match_operand:SI 0 "register_operand")
3343 (fix:SI (match_operand:DF 1 "register_operand")))]
3344 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3346 if (!ISA_HAS_TRUNC_W)
3348 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3353 (define_insn "fix_truncdfsi2_insn"
3354 [(set (match_operand:SI 0 "register_operand" "=f")
3355 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3356 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3358 [(set_attr "type" "fcvt")
3359 (set_attr "mode" "DF")
3360 (set_attr "length" "4")])
3362 (define_insn "fix_truncdfsi2_macro"
3363 [(set (match_operand:SI 0 "register_operand" "=f")
3364 (fix:SI (match_operand:DF 1 "register_operand" "f")))
3365 (clobber (match_scratch:DF 2 "=d"))]
3366 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3369 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3371 return "trunc.w.d %0,%1,%2";
3373 [(set_attr "type" "fcvt")
3374 (set_attr "mode" "DF")
3375 (set_attr "length" "36")])
3377 (define_expand "fix_truncsfsi2"
3378 [(set (match_operand:SI 0 "register_operand")
3379 (fix:SI (match_operand:SF 1 "register_operand")))]
3382 if (!ISA_HAS_TRUNC_W)
3384 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3389 (define_insn "fix_truncsfsi2_insn"
3390 [(set (match_operand:SI 0 "register_operand" "=f")
3391 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3392 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3394 [(set_attr "type" "fcvt")
3395 (set_attr "mode" "DF")
3396 (set_attr "length" "4")])
3398 (define_insn "fix_truncsfsi2_macro"
3399 [(set (match_operand:SI 0 "register_operand" "=f")
3400 (fix:SI (match_operand:SF 1 "register_operand" "f")))
3401 (clobber (match_scratch:SF 2 "=d"))]
3402 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3405 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3407 return "trunc.w.s %0,%1,%2";
3409 [(set_attr "type" "fcvt")
3410 (set_attr "mode" "DF")
3411 (set_attr "length" "36")])
3414 (define_insn "fix_truncdfdi2"
3415 [(set (match_operand:DI 0 "register_operand" "=f")
3416 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3417 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3419 [(set_attr "type" "fcvt")
3420 (set_attr "mode" "DF")
3421 (set_attr "length" "4")])
3424 (define_insn "fix_truncsfdi2"
3425 [(set (match_operand:DI 0 "register_operand" "=f")
3426 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3427 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3429 [(set_attr "type" "fcvt")
3430 (set_attr "mode" "SF")
3431 (set_attr "length" "4")])
3434 (define_insn "floatsidf2"
3435 [(set (match_operand:DF 0 "register_operand" "=f")
3436 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3437 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3439 [(set_attr "type" "fcvt")
3440 (set_attr "mode" "DF")
3441 (set_attr "length" "4")])
3444 (define_insn "floatdidf2"
3445 [(set (match_operand:DF 0 "register_operand" "=f")
3446 (float:DF (match_operand:DI 1 "register_operand" "f")))]
3447 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3449 [(set_attr "type" "fcvt")
3450 (set_attr "mode" "DF")
3451 (set_attr "length" "4")])
3454 (define_insn "floatsisf2"
3455 [(set (match_operand:SF 0 "register_operand" "=f")
3456 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3459 [(set_attr "type" "fcvt")
3460 (set_attr "mode" "SF")
3461 (set_attr "length" "4")])
3464 (define_insn "floatdisf2"
3465 [(set (match_operand:SF 0 "register_operand" "=f")
3466 (float:SF (match_operand:DI 1 "register_operand" "f")))]
3467 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3469 [(set_attr "type" "fcvt")
3470 (set_attr "mode" "SF")
3471 (set_attr "length" "4")])
3474 (define_expand "fixuns_truncdfsi2"
3475 [(set (match_operand:SI 0 "register_operand")
3476 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
3477 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3479 rtx reg1 = gen_reg_rtx (DFmode);
3480 rtx reg2 = gen_reg_rtx (DFmode);
3481 rtx reg3 = gen_reg_rtx (SImode);
3482 rtx label1 = gen_label_rtx ();
3483 rtx label2 = gen_label_rtx ();
3484 REAL_VALUE_TYPE offset;
3486 real_2expN (&offset, 31);
3488 if (reg1) /* Turn off complaints about unreached code. */
3490 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3491 do_pending_stack_adjust ();
3493 emit_insn (gen_cmpdf (operands[1], reg1));
3494 emit_jump_insn (gen_bge (label1));
3496 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3497 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3498 gen_rtx_LABEL_REF (VOIDmode, label2)));
3501 emit_label (label1);
3502 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3503 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3504 (BITMASK_HIGH, SImode)));
3506 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3507 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3509 emit_label (label2);
3511 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3512 fields, and can't be used for REG_NOTES anyway). */
3513 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3519 (define_expand "fixuns_truncdfdi2"
3520 [(set (match_operand:DI 0 "register_operand")
3521 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3522 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3524 rtx reg1 = gen_reg_rtx (DFmode);
3525 rtx reg2 = gen_reg_rtx (DFmode);
3526 rtx reg3 = gen_reg_rtx (DImode);
3527 rtx label1 = gen_label_rtx ();
3528 rtx label2 = gen_label_rtx ();
3529 REAL_VALUE_TYPE offset;
3531 real_2expN (&offset, 63);
3533 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3534 do_pending_stack_adjust ();
3536 emit_insn (gen_cmpdf (operands[1], reg1));
3537 emit_jump_insn (gen_bge (label1));
3539 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3540 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3541 gen_rtx_LABEL_REF (VOIDmode, label2)));
3544 emit_label (label1);
3545 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3546 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3547 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3549 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3550 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3552 emit_label (label2);
3554 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3555 fields, and can't be used for REG_NOTES anyway). */
3556 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3561 (define_expand "fixuns_truncsfsi2"
3562 [(set (match_operand:SI 0 "register_operand")
3563 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3566 rtx reg1 = gen_reg_rtx (SFmode);
3567 rtx reg2 = gen_reg_rtx (SFmode);
3568 rtx reg3 = gen_reg_rtx (SImode);
3569 rtx label1 = gen_label_rtx ();
3570 rtx label2 = gen_label_rtx ();
3571 REAL_VALUE_TYPE offset;
3573 real_2expN (&offset, 31);
3575 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3576 do_pending_stack_adjust ();
3578 emit_insn (gen_cmpsf (operands[1], reg1));
3579 emit_jump_insn (gen_bge (label1));
3581 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3582 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3583 gen_rtx_LABEL_REF (VOIDmode, label2)));
3586 emit_label (label1);
3587 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3588 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3589 (BITMASK_HIGH, SImode)));
3591 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3592 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3594 emit_label (label2);
3596 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3597 fields, and can't be used for REG_NOTES anyway). */
3598 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3603 (define_expand "fixuns_truncsfdi2"
3604 [(set (match_operand:DI 0 "register_operand")
3605 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3606 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3608 rtx reg1 = gen_reg_rtx (SFmode);
3609 rtx reg2 = gen_reg_rtx (SFmode);
3610 rtx reg3 = gen_reg_rtx (DImode);
3611 rtx label1 = gen_label_rtx ();
3612 rtx label2 = gen_label_rtx ();
3613 REAL_VALUE_TYPE offset;
3615 real_2expN (&offset, 63);
3617 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3618 do_pending_stack_adjust ();
3620 emit_insn (gen_cmpsf (operands[1], reg1));
3621 emit_jump_insn (gen_bge (label1));
3623 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3624 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3625 gen_rtx_LABEL_REF (VOIDmode, label2)));
3628 emit_label (label1);
3629 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3630 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3631 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3633 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3634 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3636 emit_label (label2);
3638 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3639 fields, and can't be used for REG_NOTES anyway). */
3640 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3645 ;; ....................
3649 ;; ....................
3651 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3653 (define_expand "extv"
3654 [(set (match_operand 0 "register_operand")
3655 (sign_extract (match_operand:QI 1 "memory_operand")
3656 (match_operand 2 "immediate_operand")
3657 (match_operand 3 "immediate_operand")))]
3660 if (mips_expand_unaligned_load (operands[0], operands[1],
3661 INTVAL (operands[2]),
3662 INTVAL (operands[3])))
3668 (define_expand "extzv"
3669 [(set (match_operand 0 "register_operand")
3670 (zero_extract (match_operand:QI 1 "memory_operand")
3671 (match_operand 2 "immediate_operand")
3672 (match_operand 3 "immediate_operand")))]
3675 if (mips_expand_unaligned_load (operands[0], operands[1],
3676 INTVAL (operands[2]),
3677 INTVAL (operands[3])))
3683 (define_expand "insv"
3684 [(set (zero_extract (match_operand:QI 0 "memory_operand")
3685 (match_operand 1 "immediate_operand")
3686 (match_operand 2 "immediate_operand"))
3687 (match_operand 3 "reg_or_0_operand"))]
3690 if (mips_expand_unaligned_store (operands[0], operands[3],
3691 INTVAL (operands[1]),
3692 INTVAL (operands[2])))
3698 ;; Unaligned word moves generated by the bit field patterns.
3700 ;; As far as the rtl is concerned, both the left-part and right-part
3701 ;; instructions can access the whole field. However, the real operand
3702 ;; refers to just the first or the last byte (depending on endianness).
3703 ;; We therefore use two memory operands to each instruction, one to
3704 ;; describe the rtl effect and one to use in the assembly output.
3706 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3707 ;; This allows us to use the standard length calculations for the "load"
3708 ;; and "store" type attributes.
3710 (define_insn "mov_lwl"
3711 [(set (match_operand:SI 0 "register_operand" "=d")
3712 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3713 (match_operand:QI 2 "memory_operand" "m")]
3717 [(set_attr "type" "load")
3718 (set_attr "mode" "SI")
3719 (set_attr "hazard" "none")])
3721 (define_insn "mov_lwr"
3722 [(set (match_operand:SI 0 "register_operand" "=d")
3723 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3724 (match_operand:QI 2 "memory_operand" "m")
3725 (match_operand:SI 3 "register_operand" "0")]
3729 [(set_attr "type" "load")
3730 (set_attr "mode" "SI")])
3733 (define_insn "mov_swl"
3734 [(set (match_operand:BLK 0 "memory_operand" "=m")
3735 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3736 (match_operand:QI 2 "memory_operand" "m")]
3740 [(set_attr "type" "store")
3741 (set_attr "mode" "SI")])
3743 (define_insn "mov_swr"
3744 [(set (match_operand:BLK 0 "memory_operand" "+m")
3745 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3746 (match_operand:QI 2 "memory_operand" "m")
3751 [(set_attr "type" "store")
3752 (set_attr "mode" "SI")])
3755 (define_insn "mov_ldl"
3756 [(set (match_operand:DI 0 "register_operand" "=d")
3757 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3758 (match_operand:QI 2 "memory_operand" "m")]
3760 "TARGET_64BIT && !TARGET_MIPS16"
3762 [(set_attr "type" "load")
3763 (set_attr "mode" "DI")])
3765 (define_insn "mov_ldr"
3766 [(set (match_operand:DI 0 "register_operand" "=d")
3767 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3768 (match_operand:QI 2 "memory_operand" "m")
3769 (match_operand:DI 3 "register_operand" "0")]
3771 "TARGET_64BIT && !TARGET_MIPS16"
3773 [(set_attr "type" "load")
3774 (set_attr "mode" "DI")])
3777 (define_insn "mov_sdl"
3778 [(set (match_operand:BLK 0 "memory_operand" "=m")
3779 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3780 (match_operand:QI 2 "memory_operand" "m")]
3782 "TARGET_64BIT && !TARGET_MIPS16"
3784 [(set_attr "type" "store")
3785 (set_attr "mode" "DI")])
3787 (define_insn "mov_sdr"
3788 [(set (match_operand:BLK 0 "memory_operand" "+m")
3789 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3790 (match_operand:QI 2 "memory_operand" "m")
3793 "TARGET_64BIT && !TARGET_MIPS16"
3795 [(set_attr "type" "store")
3796 (set_attr "mode" "DI")])
3798 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3799 ;; The required value is:
3801 ;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3803 ;; which translates to:
3805 ;; lui op0,%highest(op1)
3806 ;; daddiu op0,op0,%higher(op1)
3808 ;; daddiu op0,op0,%hi(op1)
3810 (define_insn_and_split "*lea_high64"
3811 [(set (match_operand:DI 0 "register_operand" "=d")
3812 (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3813 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3815 "&& reload_completed"
3816 [(set (match_dup 0) (high:DI (match_dup 2)))
3817 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3818 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3819 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3820 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3822 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3823 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3825 [(set_attr "length" "20")])
3827 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3828 ;; SYMBOL_GENERAL X will take 6 cycles. This next pattern allows combine
3829 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3830 ;; used once. We can then use the sequence:
3832 ;; lui op0,%highest(op1)
3834 ;; daddiu op0,op0,%higher(op1)
3835 ;; daddiu op2,op2,%lo(op1)
3837 ;; daddu op0,op0,op2
3839 ;; which takes 4 cycles on most superscalar targets.
3840 (define_insn_and_split "*lea64"
3841 [(set (match_operand:DI 0 "register_operand" "=d")
3842 (match_operand:DI 1 "general_symbolic_operand" ""))
3843 (clobber (match_scratch:DI 2 "=&d"))]
3844 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3846 "&& reload_completed"
3847 [(set (match_dup 0) (high:DI (match_dup 3)))
3848 (set (match_dup 2) (high:DI (match_dup 4)))
3849 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3850 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3851 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3852 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3854 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3855 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3857 [(set_attr "length" "24")])
3859 ;; Insns to fetch a global symbol from a big GOT.
3861 (define_insn_and_split "*xgot_hisi"
3862 [(set (match_operand:SI 0 "register_operand" "=d")
3863 (high:SI (match_operand:SI 1 "global_got_operand" "")))]
3864 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3866 "&& reload_completed"
3867 [(set (match_dup 0) (high:SI (match_dup 2)))
3868 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
3870 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3871 operands[3] = pic_offset_table_rtx;
3873 [(set_attr "got" "xgot_high")])
3875 (define_insn_and_split "*xgot_losi"
3876 [(set (match_operand:SI 0 "register_operand" "=d")
3877 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
3878 (match_operand:SI 2 "global_got_operand" "")))]
3879 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3881 "&& reload_completed"
3883 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3884 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3885 [(set_attr "got" "load")])
3887 (define_insn_and_split "*xgot_hidi"
3888 [(set (match_operand:DI 0 "register_operand" "=d")
3889 (high:DI (match_operand:DI 1 "global_got_operand" "")))]
3890 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3892 "&& reload_completed"
3893 [(set (match_dup 0) (high:DI (match_dup 2)))
3894 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
3896 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3897 operands[3] = pic_offset_table_rtx;
3899 [(set_attr "got" "xgot_high")])
3901 (define_insn_and_split "*xgot_lodi"
3902 [(set (match_operand:DI 0 "register_operand" "=d")
3903 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
3904 (match_operand:DI 2 "global_got_operand" "")))]
3905 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3907 "&& reload_completed"
3909 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3910 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3911 [(set_attr "got" "load")])
3913 ;; Insns to fetch a global symbol from a normal GOT.
3915 (define_insn_and_split "*got_dispsi"
3916 [(set (match_operand:SI 0 "register_operand" "=d")
3917 (match_operand:SI 1 "global_got_operand" ""))]
3918 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3920 "&& reload_completed"
3922 (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3924 operands[2] = pic_offset_table_rtx;
3925 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3927 [(set_attr "got" "load")])
3929 (define_insn_and_split "*got_dispdi"
3930 [(set (match_operand:DI 0 "register_operand" "=d")
3931 (match_operand:DI 1 "global_got_operand" ""))]
3932 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3934 "&& reload_completed"
3936 (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3938 operands[2] = pic_offset_table_rtx;
3939 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3941 [(set_attr "got" "load")])
3943 ;; Insns for loading the high part of a local symbol.
3945 (define_insn_and_split "*got_pagesi"
3946 [(set (match_operand:SI 0 "register_operand" "=d")
3947 (high:SI (match_operand:SI 1 "local_got_operand" "")))]
3948 "TARGET_EXPLICIT_RELOCS"
3950 "&& reload_completed"
3952 (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3954 operands[2] = pic_offset_table_rtx;
3955 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3957 [(set_attr "got" "load")])
3959 (define_insn_and_split "*got_pagedi"
3960 [(set (match_operand:DI 0 "register_operand" "=d")
3961 (high:DI (match_operand:DI 1 "local_got_operand" "")))]
3962 "TARGET_EXPLICIT_RELOCS"
3964 "&& reload_completed"
3966 (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3968 operands[2] = pic_offset_table_rtx;
3969 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3971 [(set_attr "got" "load")])
3973 ;; Lower-level instructions for loading an address from the GOT.
3974 ;; We could use MEMs, but an unspec gives more optimization
3977 (define_insn "*load_gotsi"
3978 [(set (match_operand:SI 0 "register_operand" "=d")
3979 (unspec:SI [(match_operand:SI 1 "register_operand" "d")
3980 (match_operand:SI 2 "immediate_operand" "")]
3984 [(set_attr "type" "load")
3985 (set_attr "length" "4")])
3987 (define_insn "*load_gotdi"
3988 [(set (match_operand:DI 0 "register_operand" "=d")
3989 (unspec:DI [(match_operand:DI 1 "register_operand" "d")
3990 (match_operand:DI 2 "immediate_operand" "")]
3994 [(set_attr "type" "load")
3995 (set_attr "length" "4")])
3997 ;; Instructions for adding the low 16 bits of an address to a register.
3998 ;; Operand 2 is the address: print_operand works out which relocation
3999 ;; should be applied.
4001 (define_insn "*lowsi"
4002 [(set (match_operand:SI 0 "register_operand" "=d")
4003 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
4004 (match_operand:SI 2 "immediate_operand" "")))]
4007 [(set_attr "type" "arith")
4008 (set_attr "mode" "SI")])
4010 (define_insn "*lowdi"
4011 [(set (match_operand:DI 0 "register_operand" "=d")
4012 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
4013 (match_operand:DI 2 "immediate_operand" "")))]
4014 "!TARGET_MIPS16 && TARGET_64BIT"
4016 [(set_attr "type" "arith")
4017 (set_attr "mode" "DI")])
4019 (define_insn "*lowsi_mips16"
4020 [(set (match_operand:SI 0 "register_operand" "=d")
4021 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
4022 (match_operand:SI 2 "immediate_operand" "")))]
4025 [(set_attr "type" "arith")
4026 (set_attr "mode" "SI")
4027 (set_attr "length" "8")])
4029 (define_insn "*lowdi_mips16"
4030 [(set (match_operand:DI 0 "register_operand" "=d")
4031 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
4032 (match_operand:DI 2 "immediate_operand" "")))]
4033 "TARGET_MIPS16 && TARGET_64BIT"
4035 [(set_attr "type" "arith")
4036 (set_attr "mode" "DI")
4037 (set_attr "length" "8")])
4039 ;; 64-bit integer moves
4041 ;; Unlike most other insns, the move insns can't be split with
4042 ;; different predicates, because register spilling and other parts of
4043 ;; the compiler, have memoized the insn number already.
4045 (define_expand "movdi"
4046 [(set (match_operand:DI 0 "")
4047 (match_operand:DI 1 ""))]
4050 if (mips_legitimize_move (DImode, operands[0], operands[1]))
4054 ;; For mips16, we need a special case to handle storing $31 into
4055 ;; memory, since we don't have a constraint to match $31. This
4056 ;; instruction can be generated by save_restore_insns.
4059 [(set (match_operand:DI 0 "stack_operand" "=m")
4061 "TARGET_MIPS16 && TARGET_64BIT"
4063 [(set_attr "type" "store")
4064 (set_attr "mode" "DI")])
4066 (define_insn "*movdi_32bit"
4067 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
4068 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
4069 "!TARGET_64BIT && !TARGET_MIPS16
4070 && (register_operand (operands[0], DImode)
4071 || reg_or_0_operand (operands[1], DImode))"
4072 { return mips_output_move (operands[0], operands[1]); }
4073 [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
4074 (set_attr "mode" "DI")
4075 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
4077 (define_insn "*movdi_32bit_mips16"
4078 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4079 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4080 "!TARGET_64BIT && TARGET_MIPS16
4081 && (register_operand (operands[0], DImode)
4082 || register_operand (operands[1], DImode))"
4083 { return mips_output_move (operands[0], operands[1]); }
4084 [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo")
4085 (set_attr "mode" "DI")
4086 (set_attr "length" "8,8,8,8,12,*,*,8")])
4088 (define_insn "*movdi_64bit"
4089 [(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")
4090 (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"))]
4091 "TARGET_64BIT && !TARGET_MIPS16
4092 && (register_operand (operands[0], DImode)
4093 || reg_or_0_operand (operands[1], DImode))"
4094 { return mips_output_move (operands[0], operands[1]); }
4095 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
4096 (set_attr "mode" "DI")
4097 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
4099 (define_insn "*movdi_64bit_mips16"
4100 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4101 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4102 "TARGET_64BIT && TARGET_MIPS16
4103 && (register_operand (operands[0], DImode)
4104 || register_operand (operands[1], DImode))"
4105 { return mips_output_move (operands[0], operands[1]); }
4106 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
4107 (set_attr "mode" "DI")
4108 (set_attr_alternative "length"
4112 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4115 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4120 (const_string "*")])])
4123 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4124 ;; when the original load is a 4 byte instruction but the add and the
4125 ;; load are 2 2 byte instructions.
4128 [(set (match_operand:DI 0 "register_operand")
4129 (mem:DI (plus:DI (match_dup 0)
4130 (match_operand:DI 1 "const_int_operand"))))]
4131 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4132 && !TARGET_DEBUG_D_MODE
4133 && GET_CODE (operands[0]) == REG
4134 && M16_REG_P (REGNO (operands[0]))
4135 && GET_CODE (operands[1]) == CONST_INT
4136 && ((INTVAL (operands[1]) < 0
4137 && INTVAL (operands[1]) >= -0x10)
4138 || (INTVAL (operands[1]) >= 32 * 8
4139 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4140 || (INTVAL (operands[1]) >= 0
4141 && INTVAL (operands[1]) < 32 * 8
4142 && (INTVAL (operands[1]) & 7) != 0))"
4143 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4144 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4146 HOST_WIDE_INT val = INTVAL (operands[1]);
4149 operands[2] = const0_rtx;
4150 else if (val >= 32 * 8)
4154 operands[1] = GEN_INT (0x8 + off);
4155 operands[2] = GEN_INT (val - off - 0x8);
4161 operands[1] = GEN_INT (off);
4162 operands[2] = GEN_INT (val - off);
4166 ;; 32-bit Integer moves
4168 ;; Unlike most other insns, the move insns can't be split with
4169 ;; different predicates, because register spilling and other parts of
4170 ;; the compiler, have memoized the insn number already.
4172 (define_expand "movsi"
4173 [(set (match_operand:SI 0 "")
4174 (match_operand:SI 1 ""))]
4177 if (mips_legitimize_move (SImode, operands[0], operands[1]))
4181 ;; We can only store $ra directly into a small sp offset.
4184 [(set (match_operand:SI 0 "stack_operand" "=m")
4188 [(set_attr "type" "store")
4189 (set_attr "mode" "SI")])
4191 ;; The difference between these two is whether or not ints are allowed
4192 ;; in FP registers (off by default, use -mdebugh to enable).
4194 (define_insn "*movsi_internal"
4195 [(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")
4196 (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"))]
4198 && (register_operand (operands[0], SImode)
4199 || reg_or_0_operand (operands[1], SImode))"
4200 { return mips_output_move (operands[0], operands[1]); }
4201 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
4202 (set_attr "mode" "SI")
4203 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
4205 (define_insn "*movsi_mips16"
4206 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4207 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4209 && (register_operand (operands[0], SImode)
4210 || register_operand (operands[1], SImode))"
4211 { return mips_output_move (operands[0], operands[1]); }
4212 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
4213 (set_attr "mode" "SI")
4214 (set_attr_alternative "length"
4218 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4221 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4226 (const_string "*")])])
4228 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4229 ;; when the original load is a 4 byte instruction but the add and the
4230 ;; load are 2 2 byte instructions.
4233 [(set (match_operand:SI 0 "register_operand")
4234 (mem:SI (plus:SI (match_dup 0)
4235 (match_operand:SI 1 "const_int_operand"))))]
4236 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4237 && GET_CODE (operands[0]) == REG
4238 && M16_REG_P (REGNO (operands[0]))
4239 && GET_CODE (operands[1]) == CONST_INT
4240 && ((INTVAL (operands[1]) < 0
4241 && INTVAL (operands[1]) >= -0x80)
4242 || (INTVAL (operands[1]) >= 32 * 4
4243 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4244 || (INTVAL (operands[1]) >= 0
4245 && INTVAL (operands[1]) < 32 * 4
4246 && (INTVAL (operands[1]) & 3) != 0))"
4247 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4248 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4250 HOST_WIDE_INT val = INTVAL (operands[1]);
4253 operands[2] = const0_rtx;
4254 else if (val >= 32 * 4)
4258 operands[1] = GEN_INT (0x7c + off);
4259 operands[2] = GEN_INT (val - off - 0x7c);
4265 operands[1] = GEN_INT (off);
4266 operands[2] = GEN_INT (val - off);
4270 ;; On the mips16, we can split a load of certain constants into a load
4271 ;; and an add. This turns a 4 byte instruction into 2 2 byte
4275 [(set (match_operand:SI 0 "register_operand")
4276 (match_operand:SI 1 "const_int_operand"))]
4277 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4278 && GET_CODE (operands[0]) == REG
4279 && M16_REG_P (REGNO (operands[0]))
4280 && GET_CODE (operands[1]) == CONST_INT
4281 && INTVAL (operands[1]) >= 0x100
4282 && INTVAL (operands[1]) <= 0xff + 0x7f"
4283 [(set (match_dup 0) (match_dup 1))
4284 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4286 int val = INTVAL (operands[1]);
4288 operands[1] = GEN_INT (0xff);
4289 operands[2] = GEN_INT (val - 0xff);
4292 ;; This insn handles moving CCmode values. It's really just a
4293 ;; slightly simplified copy of movsi_internal2, with additional cases
4294 ;; to move a condition register to a general register and to move
4295 ;; between the general registers and the floating point registers.
4297 (define_insn "movcc"
4298 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
4299 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
4300 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4301 { return mips_output_move (operands[0], operands[1]); }
4302 [(set_attr "type" "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
4303 (set_attr "mode" "SI")
4304 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
4306 ;; Reload condition code registers. reload_incc and reload_outcc
4307 ;; both handle moves from arbitrary operands into condition code
4308 ;; registers. reload_incc handles the more common case in which
4309 ;; a source operand is constrained to be in a condition-code
4310 ;; register, but has not been allocated to one.
4312 ;; Sometimes, such as in movcc, we have a CCmode destination whose
4313 ;; constraints do not include 'z'. reload_outcc handles the case
4314 ;; when such an operand is allocated to a condition-code register.
4316 ;; Note that reloads from a condition code register to some
4317 ;; other location can be done using ordinary moves. Moving
4318 ;; into a GPR takes a single movcc, moving elsewhere takes
4319 ;; two. We can leave these cases to the generic reload code.
4320 (define_expand "reload_incc"
4321 [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4322 (match_operand:CC 1 "general_operand" ""))
4323 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4324 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4326 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4330 (define_expand "reload_outcc"
4331 [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4332 (match_operand:CC 1 "register_operand" ""))
4333 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4334 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4336 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4340 ;; MIPS4 supports loading and storing a floating point register from
4341 ;; the sum of two general registers. We use two versions for each of
4342 ;; these four instructions: one where the two general registers are
4343 ;; SImode, and one where they are DImode. This is because general
4344 ;; registers will be in SImode when they hold 32 bit values, but,
4345 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
4346 ;; instructions will still work correctly.
4348 ;; ??? Perhaps it would be better to support these instructions by
4349 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
4350 ;; these instructions can only be used to load and store floating
4351 ;; point registers, that would probably cause trouble in reload.
4354 [(set (match_operand:SF 0 "register_operand" "=f")
4355 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4356 (match_operand:SI 2 "register_operand" "d"))))]
4357 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4359 [(set_attr "type" "fpidxload")
4360 (set_attr "mode" "SF")
4361 (set_attr "length" "4")])
4364 [(set (match_operand:SF 0 "register_operand" "=f")
4365 (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4366 (match_operand:DI 2 "register_operand" "d"))))]
4367 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4369 [(set_attr "type" "fpidxload")
4370 (set_attr "mode" "SF")
4371 (set_attr "length" "4")])
4374 [(set (match_operand:DF 0 "register_operand" "=f")
4375 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4376 (match_operand:SI 2 "register_operand" "d"))))]
4377 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4379 [(set_attr "type" "fpidxload")
4380 (set_attr "mode" "DF")
4381 (set_attr "length" "4")])
4384 [(set (match_operand:DF 0 "register_operand" "=f")
4385 (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4386 (match_operand:DI 2 "register_operand" "d"))))]
4387 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4389 [(set_attr "type" "fpidxload")
4390 (set_attr "mode" "DF")
4391 (set_attr "length" "4")])
4394 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4395 (match_operand:SI 2 "register_operand" "d")))
4396 (match_operand:SF 0 "register_operand" "f"))]
4397 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4399 [(set_attr "type" "fpidxstore")
4400 (set_attr "mode" "SF")
4401 (set_attr "length" "4")])
4404 [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4405 (match_operand:DI 2 "register_operand" "d")))
4406 (match_operand:SF 0 "register_operand" "f"))]
4407 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4409 [(set_attr "type" "fpidxstore")
4410 (set_attr "mode" "SF")
4411 (set_attr "length" "4")])
4414 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4415 (match_operand:SI 2 "register_operand" "d")))
4416 (match_operand:DF 0 "register_operand" "f"))]
4417 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4419 [(set_attr "type" "fpidxstore")
4420 (set_attr "mode" "DF")
4421 (set_attr "length" "4")])
4424 [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4425 (match_operand:DI 2 "register_operand" "d")))
4426 (match_operand:DF 0 "register_operand" "f"))]
4427 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4429 [(set_attr "type" "fpidxstore")
4430 (set_attr "mode" "DF")
4431 (set_attr "length" "4")])
4433 ;; 16-bit Integer moves
4435 ;; Unlike most other insns, the move insns can't be split with
4436 ;; different predicates, because register spilling and other parts of
4437 ;; the compiler, have memoized the insn number already.
4438 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4440 (define_expand "movhi"
4441 [(set (match_operand:HI 0 "")
4442 (match_operand:HI 1 ""))]
4445 if (mips_legitimize_move (HImode, operands[0], operands[1]))
4449 (define_insn "*movhi_internal"
4450 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4451 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4453 && (register_operand (operands[0], HImode)
4454 || reg_or_0_operand (operands[1], HImode))"
4464 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4465 (set_attr "mode" "HI")
4466 (set_attr "length" "4,4,*,*,4,4,4,4")])
4468 (define_insn "*movhi_mips16"
4469 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4470 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))]
4472 && (register_operand (operands[0], HImode)
4473 || register_operand (operands[1], HImode))"
4482 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4483 (set_attr "mode" "HI")
4484 (set_attr_alternative "length"
4488 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4491 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4495 (const_string "*")])])
4498 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4499 ;; when the original load is a 4 byte instruction but the add and the
4500 ;; load are 2 2 byte instructions.
4503 [(set (match_operand:HI 0 "register_operand")
4504 (mem:HI (plus:SI (match_dup 0)
4505 (match_operand:SI 1 "const_int_operand"))))]
4506 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4507 && GET_CODE (operands[0]) == REG
4508 && M16_REG_P (REGNO (operands[0]))
4509 && GET_CODE (operands[1]) == CONST_INT
4510 && ((INTVAL (operands[1]) < 0
4511 && INTVAL (operands[1]) >= -0x80)
4512 || (INTVAL (operands[1]) >= 32 * 2
4513 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4514 || (INTVAL (operands[1]) >= 0
4515 && INTVAL (operands[1]) < 32 * 2
4516 && (INTVAL (operands[1]) & 1) != 0))"
4517 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4518 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4520 HOST_WIDE_INT val = INTVAL (operands[1]);
4523 operands[2] = const0_rtx;
4524 else if (val >= 32 * 2)
4528 operands[1] = GEN_INT (0x7e + off);
4529 operands[2] = GEN_INT (val - off - 0x7e);
4535 operands[1] = GEN_INT (off);
4536 operands[2] = GEN_INT (val - off);
4540 ;; 8-bit Integer moves
4542 ;; Unlike most other insns, the move insns can't be split with
4543 ;; different predicates, because register spilling and other parts of
4544 ;; the compiler, have memoized the insn number already.
4545 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4547 (define_expand "movqi"
4548 [(set (match_operand:QI 0 "")
4549 (match_operand:QI 1 ""))]
4552 if (mips_legitimize_move (QImode, operands[0], operands[1]))
4556 (define_insn "*movqi_internal"
4557 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4558 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4560 && (register_operand (operands[0], QImode)
4561 || reg_or_0_operand (operands[1], QImode))"
4571 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4572 (set_attr "mode" "QI")
4573 (set_attr "length" "4,4,*,*,4,4,4,4")])
4575 (define_insn "*movqi_mips16"
4576 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4577 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))]
4579 && (register_operand (operands[0], QImode)
4580 || register_operand (operands[1], QImode))"
4589 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4590 (set_attr "mode" "QI")
4591 (set_attr "length" "4,4,4,4,8,*,*")])
4593 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
4594 ;; when the original load is a 4 byte instruction but the add and the
4595 ;; load are 2 2 byte instructions.
4598 [(set (match_operand:QI 0 "register_operand")
4599 (mem:QI (plus:SI (match_dup 0)
4600 (match_operand:SI 1 "const_int_operand"))))]
4601 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4602 && GET_CODE (operands[0]) == REG
4603 && M16_REG_P (REGNO (operands[0]))
4604 && GET_CODE (operands[1]) == CONST_INT
4605 && ((INTVAL (operands[1]) < 0
4606 && INTVAL (operands[1]) >= -0x80)
4607 || (INTVAL (operands[1]) >= 32
4608 && INTVAL (operands[1]) <= 31 + 0x7f))"
4609 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4610 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4612 HOST_WIDE_INT val = INTVAL (operands[1]);
4615 operands[2] = const0_rtx;
4618 operands[1] = GEN_INT (0x7f);
4619 operands[2] = GEN_INT (val - 0x7f);
4623 ;; 32-bit floating point moves
4625 (define_expand "movsf"
4626 [(set (match_operand:SF 0 "")
4627 (match_operand:SF 1 ""))]
4630 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4634 (define_insn "*movsf_hardfloat"
4635 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4636 (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
4638 && (register_operand (operands[0], SFmode)
4639 || reg_or_0_operand (operands[1], SFmode))"
4640 { return mips_output_move (operands[0], operands[1]); }
4641 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4642 (set_attr "mode" "SF")
4643 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4645 (define_insn "*movsf_softfloat"
4646 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4647 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
4648 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4649 && (register_operand (operands[0], SFmode)
4650 || reg_or_0_operand (operands[1], SFmode))"
4651 { return mips_output_move (operands[0], operands[1]); }
4652 [(set_attr "type" "arith,load,store")
4653 (set_attr "mode" "SF")
4654 (set_attr "length" "4,*,*")])
4656 (define_insn "*movsf_mips16"
4657 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4658 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
4660 && (register_operand (operands[0], SFmode)
4661 || register_operand (operands[1], SFmode))"
4662 { return mips_output_move (operands[0], operands[1]); }
4663 [(set_attr "type" "arith,arith,arith,load,store")
4664 (set_attr "mode" "SF")
4665 (set_attr "length" "4,4,4,*,*")])
4668 ;; 64-bit floating point moves
4670 (define_expand "movdf"
4671 [(set (match_operand:DF 0 "")
4672 (match_operand:DF 1 ""))]
4675 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4679 (define_insn "*movdf_hardfloat_64bit"
4680 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4681 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4682 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
4683 && (register_operand (operands[0], DFmode)
4684 || reg_or_0_operand (operands[1], DFmode))"
4685 { return mips_output_move (operands[0], operands[1]); }
4686 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4687 (set_attr "mode" "DF")
4688 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4690 (define_insn "*movdf_hardfloat_32bit"
4691 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4692 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4693 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
4694 && (register_operand (operands[0], DFmode)
4695 || reg_or_0_operand (operands[1], DFmode))"
4696 { return mips_output_move (operands[0], operands[1]); }
4697 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4698 (set_attr "mode" "DF")
4699 (set_attr "length" "4,8,*,*,8,8,8,*,*")])
4701 (define_insn "*movdf_softfloat"
4702 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
4703 (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
4704 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4705 && (register_operand (operands[0], DFmode)
4706 || reg_or_0_operand (operands[1], DFmode))"
4707 { return mips_output_move (operands[0], operands[1]); }
4708 [(set_attr "type" "arith,load,store,xfer,xfer,fmove")
4709 (set_attr "mode" "DF")
4710 (set_attr "length" "8,*,*,4,4,4")])
4712 (define_insn "*movdf_mips16"
4713 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4714 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4716 && (register_operand (operands[0], DFmode)
4717 || register_operand (operands[1], DFmode))"
4718 { return mips_output_move (operands[0], operands[1]); }
4719 [(set_attr "type" "arith,arith,arith,load,store")
4720 (set_attr "mode" "DF")
4721 (set_attr "length" "8,8,8,*,*")])
4724 [(set (match_operand:DI 0 "nonimmediate_operand")
4725 (match_operand:DI 1 "move_operand"))]
4726 "reload_completed && !TARGET_64BIT
4727 && mips_split_64bit_move_p (operands[0], operands[1])"
4730 mips_split_64bit_move (operands[0], operands[1]);
4735 [(set (match_operand:DF 0 "nonimmediate_operand")
4736 (match_operand:DF 1 "move_operand"))]
4737 "reload_completed && !TARGET_64BIT
4738 && mips_split_64bit_move_p (operands[0], operands[1])"
4741 mips_split_64bit_move (operands[0], operands[1]);
4745 ;; When generating mips16 code, split moves of negative constants into
4746 ;; a positive "li" followed by a negation.
4748 [(set (match_operand 0 "register_operand")
4749 (match_operand 1 "const_int_operand"))]
4750 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4754 (neg:SI (match_dup 2)))]
4756 operands[2] = gen_lowpart (SImode, operands[0]);
4757 operands[3] = GEN_INT (-INTVAL (operands[1]));
4760 ;; The HI and LO registers are not truly independent. If we move an mthi
4761 ;; instruction before an mflo instruction, it will make the result of the
4762 ;; mflo unpredictable. The same goes for mtlo and mfhi.
4764 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4765 ;; Operand 1 is the register we want, operand 2 is the other one.
4767 (define_insn "mfhilo_di"
4768 [(set (match_operand:DI 0 "register_operand" "=d,d")
4769 (unspec:DI [(match_operand:DI 1 "register_operand" "h,l")
4770 (match_operand:DI 2 "register_operand" "l,h")]
4774 [(set_attr "type" "mfhilo")])
4776 (define_insn "mfhilo_si"
4777 [(set (match_operand:SI 0 "register_operand" "=d,d")
4778 (unspec:SI [(match_operand:SI 1 "register_operand" "h,l")
4779 (match_operand:SI 2 "register_operand" "l,h")]
4783 [(set_attr "type" "mfhilo")])
4785 ;; Patterns for loading or storing part of a paired floating point
4786 ;; register. We need them because odd-numbered floating-point registers
4787 ;; are not fully independent: see mips_split_64bit_move.
4789 ;; Load the low word of operand 0 with operand 1.
4790 (define_insn "load_df_low"
4791 [(set (match_operand:DF 0 "register_operand" "=f,f")
4792 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
4793 UNSPEC_LOAD_DF_LOW))]
4794 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4796 operands[0] = mips_subword (operands[0], 0);
4797 return mips_output_move (operands[0], operands[1]);
4799 [(set_attr "type" "xfer,fpload")
4800 (set_attr "mode" "SF")])
4802 ;; Load the high word of operand 0 from operand 1, preserving the value
4804 (define_insn "load_df_high"
4805 [(set (match_operand:DF 0 "register_operand" "=f,f")
4806 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
4807 (match_operand:DF 2 "register_operand" "0,0")]
4808 UNSPEC_LOAD_DF_HIGH))]
4809 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4811 operands[0] = mips_subword (operands[0], 1);
4812 return mips_output_move (operands[0], operands[1]);
4814 [(set_attr "type" "xfer,fpload")
4815 (set_attr "mode" "SF")])
4817 ;; Store the high word of operand 1 in operand 0. The corresponding
4818 ;; low-word move is done in the normal way.
4819 (define_insn "store_df_high"
4820 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4821 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4822 UNSPEC_STORE_DF_HIGH))]
4823 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4825 operands[1] = mips_subword (operands[1], 1);
4826 return mips_output_move (operands[0], operands[1]);
4828 [(set_attr "type" "xfer,fpstore")
4829 (set_attr "mode" "SF")])
4831 ;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
4832 ;; of _gp from the start of this function. Operand 1 is the incoming
4833 ;; function address.
4834 (define_insn_and_split "loadgp"
4835 [(unspec_volatile [(match_operand 0 "" "")
4836 (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4837 "TARGET_ABICALLS && TARGET_NEWABI"
4840 [(set (match_dup 2) (match_dup 3))
4841 (set (match_dup 2) (match_dup 4))
4842 (set (match_dup 2) (match_dup 5))]
4844 operands[2] = pic_offset_table_rtx;
4845 operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4846 operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4847 operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4849 [(set_attr "length" "12")])
4851 ;; The use of gp is hidden when not using explicit relocations.
4852 ;; This blockage instruction prevents the gp load from being
4853 ;; scheduled after an implicit use of gp. It also prevents
4854 ;; the load from being deleted as dead.
4855 (define_insn "loadgp_blockage"
4856 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4859 [(set_attr "type" "unknown")
4860 (set_attr "mode" "none")
4861 (set_attr "length" "0")])
4863 ;; Emit a .cprestore directive, which expands to a single store instruction.
4864 ;; Note that we continue to use .cprestore for explicit reloc code so that
4865 ;; jals inside inlines asms will work correctly.
4866 (define_insn "cprestore"
4867 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
4871 [(set_attr "type" "store")
4872 (set_attr "length" "4")])
4874 ;; Block moves, see mips.c for more details.
4875 ;; Argument 0 is the destination
4876 ;; Argument 1 is the source
4877 ;; Argument 2 is the length
4878 ;; Argument 3 is the alignment
4880 (define_expand "movmemsi"
4881 [(parallel [(set (match_operand:BLK 0 "general_operand")
4882 (match_operand:BLK 1 "general_operand"))
4883 (use (match_operand:SI 2 ""))
4884 (use (match_operand:SI 3 "const_int_operand"))])]
4885 "!TARGET_MIPS16 && !TARGET_MEMCPY"
4887 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4894 ;; ....................
4898 ;; ....................
4900 ;; Many of these instructions use trivial define_expands, because we
4901 ;; want to use a different set of constraints when TARGET_MIPS16.
4903 (define_expand "ashlsi3"
4904 [(set (match_operand:SI 0 "register_operand")
4905 (ashift:SI (match_operand:SI 1 "register_operand")
4906 (match_operand:SI 2 "arith_operand")))]
4909 /* On the mips16, a shift of more than 8 is a four byte instruction,
4910 so, for a shift between 8 and 16, it is just as fast to do two
4911 shifts of 8 or less. If there is a lot of shifting going on, we
4912 may win in CSE. Otherwise combine will put the shifts back
4913 together again. This can be called by function_arg, so we must
4914 be careful not to allocate a new register if we've reached the
4918 && GET_CODE (operands[2]) == CONST_INT
4919 && INTVAL (operands[2]) > 8
4920 && INTVAL (operands[2]) <= 16
4921 && ! reload_in_progress
4922 && ! reload_completed)
4924 rtx temp = gen_reg_rtx (SImode);
4926 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
4927 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
4928 GEN_INT (INTVAL (operands[2]) - 8)));
4933 (define_insn "ashlsi3_internal1"
4934 [(set (match_operand:SI 0 "register_operand" "=d")
4935 (ashift:SI (match_operand:SI 1 "register_operand" "d")
4936 (match_operand:SI 2 "arith_operand" "dI")))]
4939 if (GET_CODE (operands[2]) == CONST_INT)
4940 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4942 return "sll\t%0,%1,%2";
4944 [(set_attr "type" "shift")
4945 (set_attr "mode" "SI")])
4947 (define_insn "ashlsi3_internal1_extend"
4948 [(set (match_operand:DI 0 "register_operand" "=d")
4949 (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
4950 (match_operand:SI 2 "arith_operand" "dI"))))]
4951 "TARGET_64BIT && !TARGET_MIPS16"
4953 if (GET_CODE (operands[2]) == CONST_INT)
4954 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4956 return "sll\t%0,%1,%2";
4958 [(set_attr "type" "shift")
4959 (set_attr "mode" "DI")])
4962 (define_insn "ashlsi3_internal2"
4963 [(set (match_operand:SI 0 "register_operand" "=d,d")
4964 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
4965 (match_operand:SI 2 "arith_operand" "d,I")))]
4968 if (which_alternative == 0)
4969 return "sll\t%0,%2";
4971 if (GET_CODE (operands[2]) == CONST_INT)
4972 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4974 return "sll\t%0,%1,%2";
4976 [(set_attr "type" "shift")
4977 (set_attr "mode" "SI")
4978 (set_attr_alternative "length"
4980 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4984 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4987 [(set (match_operand:SI 0 "register_operand")
4988 (ashift:SI (match_operand:SI 1 "register_operand")
4989 (match_operand:SI 2 "const_int_operand")))]
4990 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4991 && GET_CODE (operands[2]) == CONST_INT
4992 && INTVAL (operands[2]) > 8
4993 && INTVAL (operands[2]) <= 16"
4994 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
4995 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4996 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4998 (define_expand "ashldi3"
4999 [(set (match_operand:DI 0 "register_operand")
5000 (ashift:DI (match_operand:DI 1 "register_operand")
5001 (match_operand:SI 2 "arith_operand")))]
5004 /* On the mips16, a shift of more than 8 is a four byte
5005 instruction, so, for a shift between 8 and 16, it is just as
5006 fast to do two shifts of 8 or less. If there is a lot of
5007 shifting going on, we may win in CSE. Otherwise combine will
5008 put the shifts back together again. This can be called by
5009 function_arg, so we must be careful not to allocate a new
5010 register if we've reached the reload pass. */
5013 && GET_CODE (operands[2]) == CONST_INT
5014 && INTVAL (operands[2]) > 8
5015 && INTVAL (operands[2]) <= 16
5016 && ! reload_in_progress
5017 && ! reload_completed)
5019 rtx temp = gen_reg_rtx (DImode);
5021 emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
5022 emit_insn (gen_ashldi3_internal (operands[0], temp,
5023 GEN_INT (INTVAL (operands[2]) - 8)));
5029 (define_insn "ashldi3_internal"
5030 [(set (match_operand:DI 0 "register_operand" "=d")
5031 (ashift:DI (match_operand:DI 1 "register_operand" "d")
5032 (match_operand:SI 2 "arith_operand" "dI")))]
5033 "TARGET_64BIT && !TARGET_MIPS16"
5035 if (GET_CODE (operands[2]) == CONST_INT)
5036 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5038 return "dsll\t%0,%1,%2";
5040 [(set_attr "type" "shift")
5041 (set_attr "mode" "DI")])
5044 [(set (match_operand:DI 0 "register_operand" "=d,d")
5045 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
5046 (match_operand:SI 2 "arith_operand" "d,I")))]
5047 "TARGET_64BIT && TARGET_MIPS16"
5049 if (which_alternative == 0)
5050 return "dsll\t%0,%2";
5052 if (GET_CODE (operands[2]) == CONST_INT)
5053 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5055 return "dsll\t%0,%1,%2";
5057 [(set_attr "type" "shift")
5058 (set_attr "mode" "DI")
5059 (set_attr_alternative "length"
5061 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5066 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5069 [(set (match_operand:DI 0 "register_operand")
5070 (ashift:DI (match_operand:DI 1 "register_operand")
5071 (match_operand:SI 2 "const_int_operand")))]
5072 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5074 && GET_CODE (operands[2]) == CONST_INT
5075 && INTVAL (operands[2]) > 8
5076 && INTVAL (operands[2]) <= 16"
5077 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
5078 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
5079 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5081 (define_expand "ashrsi3"
5082 [(set (match_operand:SI 0 "register_operand")
5083 (ashiftrt:SI (match_operand:SI 1 "register_operand")
5084 (match_operand:SI 2 "arith_operand")))]
5087 /* On the mips16, a shift of more than 8 is a four byte instruction,
5088 so, for a shift between 8 and 16, it is just as fast to do two
5089 shifts of 8 or less. If there is a lot of shifting going on, we
5090 may win in CSE. Otherwise combine will put the shifts back
5094 && GET_CODE (operands[2]) == CONST_INT
5095 && INTVAL (operands[2]) > 8
5096 && INTVAL (operands[2]) <= 16)
5098 rtx temp = gen_reg_rtx (SImode);
5100 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5101 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
5102 GEN_INT (INTVAL (operands[2]) - 8)));
5107 (define_insn "ashrsi3_internal1"
5108 [(set (match_operand:SI 0 "register_operand" "=d")
5109 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
5110 (match_operand:SI 2 "arith_operand" "dI")))]
5113 if (GET_CODE (operands[2]) == CONST_INT)
5114 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5116 return "sra\t%0,%1,%2";
5118 [(set_attr "type" "shift")
5119 (set_attr "mode" "SI")])
5121 (define_insn "ashrsi3_internal2"
5122 [(set (match_operand:SI 0 "register_operand" "=d,d")
5123 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5124 (match_operand:SI 2 "arith_operand" "d,I")))]
5127 if (which_alternative == 0)
5128 return "sra\t%0,%2";
5130 if (GET_CODE (operands[2]) == CONST_INT)
5131 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5133 return "sra\t%0,%1,%2";
5135 [(set_attr "type" "shift")
5136 (set_attr "mode" "SI")
5137 (set_attr_alternative "length"
5139 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5144 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5147 [(set (match_operand:SI 0 "register_operand")
5148 (ashiftrt:SI (match_operand:SI 1 "register_operand")
5149 (match_operand:SI 2 "const_int_operand")))]
5150 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5151 && GET_CODE (operands[2]) == CONST_INT
5152 && INTVAL (operands[2]) > 8
5153 && INTVAL (operands[2]) <= 16"
5154 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
5155 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
5156 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5158 (define_expand "ashrdi3"
5159 [(set (match_operand:DI 0 "register_operand")
5160 (ashiftrt:DI (match_operand:DI 1 "register_operand")
5161 (match_operand:SI 2 "arith_operand")))]
5164 /* On the mips16, a shift of more than 8 is a four byte
5165 instruction, so, for a shift between 8 and 16, it is just as
5166 fast to do two shifts of 8 or less. If there is a lot of
5167 shifting going on, we may win in CSE. Otherwise combine will
5168 put the shifts back together again. */
5171 && GET_CODE (operands[2]) == CONST_INT
5172 && INTVAL (operands[2]) > 8
5173 && INTVAL (operands[2]) <= 16)
5175 rtx temp = gen_reg_rtx (DImode);
5177 emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
5178 emit_insn (gen_ashrdi3_internal (operands[0], temp,
5179 GEN_INT (INTVAL (operands[2]) - 8)));
5185 (define_insn "ashrdi3_internal"
5186 [(set (match_operand:DI 0 "register_operand" "=d")
5187 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5188 (match_operand:SI 2 "arith_operand" "dI")))]
5189 "TARGET_64BIT && !TARGET_MIPS16"
5191 if (GET_CODE (operands[2]) == CONST_INT)
5192 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5194 return "dsra\t%0,%1,%2";
5196 [(set_attr "type" "shift")
5197 (set_attr "mode" "DI")])
5200 [(set (match_operand:DI 0 "register_operand" "=d,d")
5201 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5202 (match_operand:SI 2 "arith_operand" "d,I")))]
5203 "TARGET_64BIT && TARGET_MIPS16"
5205 if (GET_CODE (operands[2]) == CONST_INT)
5206 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5208 return "dsra\t%0,%2";
5210 [(set_attr "type" "shift")
5211 (set_attr "mode" "DI")
5212 (set_attr_alternative "length"
5214 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5218 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5221 [(set (match_operand:DI 0 "register_operand")
5222 (ashiftrt:DI (match_operand:DI 1 "register_operand")
5223 (match_operand:SI 2 "const_int_operand")))]
5224 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5226 && GET_CODE (operands[2]) == CONST_INT
5227 && INTVAL (operands[2]) > 8
5228 && INTVAL (operands[2]) <= 16"
5229 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
5230 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
5231 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5233 (define_expand "lshrsi3"
5234 [(set (match_operand:SI 0 "register_operand")
5235 (lshiftrt:SI (match_operand:SI 1 "register_operand")
5236 (match_operand:SI 2 "arith_operand")))]
5239 /* On the mips16, a shift of more than 8 is a four byte instruction,
5240 so, for a shift between 8 and 16, it is just as fast to do two
5241 shifts of 8 or less. If there is a lot of shifting going on, we
5242 may win in CSE. Otherwise combine will put the shifts back
5246 && GET_CODE (operands[2]) == CONST_INT
5247 && INTVAL (operands[2]) > 8
5248 && INTVAL (operands[2]) <= 16)
5250 rtx temp = gen_reg_rtx (SImode);
5252 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5253 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
5254 GEN_INT (INTVAL (operands[2]) - 8)));
5259 (define_insn "lshrsi3_internal1"
5260 [(set (match_operand:SI 0 "register_operand" "=d")
5261 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
5262 (match_operand:SI 2 "arith_operand" "dI")))]
5265 if (GET_CODE (operands[2]) == CONST_INT)
5266 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5268 return "srl\t%0,%1,%2";
5270 [(set_attr "type" "shift")
5271 (set_attr "mode" "SI")])
5273 (define_insn "lshrsi3_internal2"
5274 [(set (match_operand:SI 0 "register_operand" "=d,d")
5275 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5276 (match_operand:SI 2 "arith_operand" "d,I")))]
5279 if (which_alternative == 0)
5280 return "srl\t%0,%2";
5282 if (GET_CODE (operands[2]) == CONST_INT)
5283 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5285 return "srl\t%0,%1,%2";
5287 [(set_attr "type" "shift")
5288 (set_attr "mode" "SI")
5289 (set_attr_alternative "length"
5291 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5296 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5299 [(set (match_operand:SI 0 "register_operand")
5300 (lshiftrt:SI (match_operand:SI 1 "register_operand")
5301 (match_operand:SI 2 "const_int_operand")))]
5302 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5303 && GET_CODE (operands[2]) == CONST_INT
5304 && INTVAL (operands[2]) > 8
5305 && INTVAL (operands[2]) <= 16"
5306 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
5307 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5308 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5310 ;; If we load a byte on the mips16 as a bitfield, the resulting
5311 ;; sequence of instructions is too complicated for combine, because it
5312 ;; involves four instructions: a load, a shift, a constant load into a
5313 ;; register, and an and (the key problem here is that the mips16 does
5314 ;; not have and immediate). We recognize a shift of a load in order
5315 ;; to make it simple enough for combine to understand.
5317 ;; The length here is the worst case: the length of the split version
5318 ;; will be more accurate.
5319 (define_insn_and_split ""
5320 [(set (match_operand:SI 0 "register_operand" "=d")
5321 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5322 (match_operand:SI 2 "immediate_operand" "I")))]
5326 [(set (match_dup 0) (match_dup 1))
5327 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5329 [(set_attr "type" "load")
5330 (set_attr "mode" "SI")
5331 (set_attr "length" "16")])
5333 (define_expand "lshrdi3"
5334 [(set (match_operand:DI 0 "register_operand")
5335 (lshiftrt:DI (match_operand:DI 1 "register_operand")
5336 (match_operand:SI 2 "arith_operand")))]
5339 /* On the mips16, a shift of more than 8 is a four byte
5340 instruction, so, for a shift between 8 and 16, it is just as
5341 fast to do two shifts of 8 or less. If there is a lot of
5342 shifting going on, we may win in CSE. Otherwise combine will
5343 put the shifts back together again. */
5346 && GET_CODE (operands[2]) == CONST_INT
5347 && INTVAL (operands[2]) > 8
5348 && INTVAL (operands[2]) <= 16)
5350 rtx temp = gen_reg_rtx (DImode);
5352 emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
5353 emit_insn (gen_lshrdi3_internal (operands[0], temp,
5354 GEN_INT (INTVAL (operands[2]) - 8)));
5360 (define_insn "lshrdi3_internal"
5361 [(set (match_operand:DI 0 "register_operand" "=d")
5362 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
5363 (match_operand:SI 2 "arith_operand" "dI")))]
5364 "TARGET_64BIT && !TARGET_MIPS16"
5366 if (GET_CODE (operands[2]) == CONST_INT)
5367 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5369 return "dsrl\t%0,%1,%2";
5371 [(set_attr "type" "shift")
5372 (set_attr "mode" "DI")])
5375 [(set (match_operand:DI 0 "register_operand" "=d,d")
5376 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5377 (match_operand:SI 2 "arith_operand" "d,I")))]
5378 "TARGET_64BIT && TARGET_MIPS16"
5380 if (GET_CODE (operands[2]) == CONST_INT)
5381 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5383 return "dsrl\t%0,%2";
5385 [(set_attr "type" "shift")
5386 (set_attr "mode" "DI")
5387 (set_attr_alternative "length"
5389 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5393 (define_insn "rotrsi3"
5394 [(set (match_operand:SI 0 "register_operand" "=d")
5395 (rotatert:SI (match_operand:SI 1 "register_operand" "d")
5396 (match_operand:SI 2 "arith_operand" "dn")))]
5399 if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
5400 return "rorv\t%0,%1,%2";
5402 if ((GET_CODE (operands[2]) == CONST_INT)
5403 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
5406 return "ror\t%0,%1,%2";
5408 [(set_attr "type" "shift")
5409 (set_attr "mode" "SI")])
5411 (define_insn "rotrdi3"
5412 [(set (match_operand:DI 0 "register_operand" "=d")
5413 (rotatert:DI (match_operand:DI 1 "register_operand" "d")
5414 (match_operand:DI 2 "arith_operand" "dn")))]
5419 if (GET_CODE (operands[2]) != CONST_INT)
5420 return "drorv\t%0,%1,%2";
5422 if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
5423 return "dror32\t%0,%1,%2";
5426 if ((GET_CODE (operands[2]) == CONST_INT)
5427 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
5430 return "dror\t%0,%1,%2";
5432 [(set_attr "type" "shift")
5433 (set_attr "mode" "DI")])
5436 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5439 [(set (match_operand:DI 0 "register_operand")
5440 (lshiftrt:DI (match_operand:DI 1 "register_operand")
5441 (match_operand:SI 2 "const_int_operand")))]
5442 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5443 && GET_CODE (operands[2]) == CONST_INT
5444 && INTVAL (operands[2]) > 8
5445 && INTVAL (operands[2]) <= 16"
5446 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
5447 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
5448 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5451 ;; ....................
5455 ;; ....................
5457 ;; Flow here is rather complex:
5459 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the arguments
5460 ;; into cmp_operands[] but generates no RTL.
5462 ;; 2) The appropriate branch define_expand is called, which then
5463 ;; creates the appropriate RTL for the comparison and branch.
5464 ;; Different CC modes are used, based on what type of branch is
5465 ;; done, so that we can constrain things appropriately. There
5466 ;; are assumptions in the rest of GCC that break if we fold the
5467 ;; operands into the branches for integer operations, and use cc0
5468 ;; for floating point, so we use the fp status register instead.
5469 ;; If needed, an appropriate temporary is created to hold the
5470 ;; of the integer compare.
5472 (define_expand "cmpsi"
5474 (compare:CC (match_operand:SI 0 "register_operand")
5475 (match_operand:SI 1 "arith_operand")))]
5478 cmp_operands[0] = operands[0];
5479 cmp_operands[1] = operands[1];
5483 (define_expand "cmpdi"
5485 (compare:CC (match_operand:DI 0 "register_operand")
5486 (match_operand:DI 1 "arith_operand")))]
5489 cmp_operands[0] = operands[0];
5490 cmp_operands[1] = operands[1];
5494 (define_expand "cmpdf"
5496 (compare:CC (match_operand:DF 0 "register_operand")
5497 (match_operand:DF 1 "register_operand")))]
5498 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5500 cmp_operands[0] = operands[0];
5501 cmp_operands[1] = operands[1];
5505 (define_expand "cmpsf"
5507 (compare:CC (match_operand:SF 0 "register_operand")
5508 (match_operand:SF 1 "register_operand")))]
5511 cmp_operands[0] = operands[0];
5512 cmp_operands[1] = operands[1];
5517 ;; ....................
5519 ;; CONDITIONAL BRANCHES
5521 ;; ....................
5523 ;; Conditional branches on floating-point equality tests.
5525 (define_insn "branch_fp"
5528 (match_operator:CC 0 "cmp_op"
5529 [(match_operand:CC 2 "register_operand" "z")
5531 (label_ref (match_operand 1 "" ""))
5535 return mips_output_conditional_branch (insn,
5537 /*two_operands_p=*/0,
5540 get_attr_length (insn));
5542 [(set_attr "type" "branch")
5543 (set_attr "mode" "none")])
5545 (define_insn "branch_fp_inverted"
5548 (match_operator:CC 0 "cmp_op"
5549 [(match_operand:CC 2 "register_operand" "z")
5552 (label_ref (match_operand 1 "" ""))))]
5555 return mips_output_conditional_branch (insn,
5557 /*two_operands_p=*/0,
5560 get_attr_length (insn));
5562 [(set_attr "type" "branch")
5563 (set_attr "mode" "none")])
5565 ;; Conditional branches on comparisons with zero.
5567 (define_insn "branch_zero"
5570 (match_operator:SI 0 "cmp_op"
5571 [(match_operand:SI 2 "register_operand" "d")
5573 (label_ref (match_operand 1 "" ""))
5577 return mips_output_conditional_branch (insn,
5579 /*two_operands_p=*/0,
5582 get_attr_length (insn));
5584 [(set_attr "type" "branch")
5585 (set_attr "mode" "none")])
5587 (define_insn "branch_zero_inverted"
5590 (match_operator:SI 0 "cmp_op"
5591 [(match_operand:SI 2 "register_operand" "d")
5594 (label_ref (match_operand 1 "" ""))))]
5597 return mips_output_conditional_branch (insn,
5599 /*two_operands_p=*/0,
5602 get_attr_length (insn));
5604 [(set_attr "type" "branch")
5605 (set_attr "mode" "none")])
5607 (define_insn "branch_zero_di"
5610 (match_operator:DI 0 "cmp_op"
5611 [(match_operand:DI 2 "register_operand" "d")
5613 (label_ref (match_operand 1 "" ""))
5617 return mips_output_conditional_branch (insn,
5619 /*two_operands_p=*/0,
5622 get_attr_length (insn));
5624 [(set_attr "type" "branch")
5625 (set_attr "mode" "none")])
5627 (define_insn "branch_zero_di_inverted"
5630 (match_operator:DI 0 "cmp_op"
5631 [(match_operand:DI 2 "register_operand" "d")
5634 (label_ref (match_operand 1 "" ""))))]
5637 return mips_output_conditional_branch (insn,
5639 /*two_operands_p=*/0,
5642 get_attr_length (insn));
5644 [(set_attr "type" "branch")
5645 (set_attr "mode" "none")])
5647 ;; Conditional branch on equality comparison.
5649 (define_insn "branch_equality"
5652 (match_operator:SI 0 "equality_op"
5653 [(match_operand:SI 2 "register_operand" "d")
5654 (match_operand:SI 3 "register_operand" "d")])
5655 (label_ref (match_operand 1 "" ""))
5659 return mips_output_conditional_branch (insn,
5661 /*two_operands_p=*/1,
5664 get_attr_length (insn));
5666 [(set_attr "type" "branch")
5667 (set_attr "mode" "none")])
5669 (define_insn "branch_equality_di"
5672 (match_operator:DI 0 "equality_op"
5673 [(match_operand:DI 2 "register_operand" "d")
5674 (match_operand:DI 3 "register_operand" "d")])
5675 (label_ref (match_operand 1 "" ""))
5679 return mips_output_conditional_branch (insn,
5681 /*two_operands_p=*/1,
5684 get_attr_length (insn));
5686 [(set_attr "type" "branch")
5687 (set_attr "mode" "none")])
5689 (define_insn "branch_equality_inverted"
5692 (match_operator:SI 0 "equality_op"
5693 [(match_operand:SI 2 "register_operand" "d")
5694 (match_operand:SI 3 "register_operand" "d")])
5696 (label_ref (match_operand 1 "" ""))))]
5699 return mips_output_conditional_branch (insn,
5701 /*two_operands_p=*/1,
5704 get_attr_length (insn));
5706 [(set_attr "type" "branch")
5707 (set_attr "mode" "none")])
5709 (define_insn "branch_equality_di_inverted"
5712 (match_operator:DI 0 "equality_op"
5713 [(match_operand:DI 2 "register_operand" "d")
5714 (match_operand:DI 3 "register_operand" "d")])
5716 (label_ref (match_operand 1 "" ""))))]
5719 return mips_output_conditional_branch (insn,
5721 /*two_operands_p=*/1,
5724 get_attr_length (insn));
5726 [(set_attr "type" "branch")
5727 (set_attr "mode" "none")])
5733 (if_then_else (match_operator:SI 0 "equality_op"
5734 [(match_operand:SI 1 "register_operand" "d,t")
5736 (match_operand 2 "pc_or_label_operand" "")
5737 (match_operand 3 "pc_or_label_operand" "")))]
5740 if (operands[2] != pc_rtx)
5742 if (which_alternative == 0)
5743 return "b%C0z\t%1,%2";
5745 return "bt%C0z\t%2";
5749 if (which_alternative == 0)
5750 return "b%N0z\t%1,%3";
5752 return "bt%N0z\t%3";
5755 [(set_attr "type" "branch")
5756 (set_attr "mode" "none")
5757 (set_attr "length" "8")])
5761 (if_then_else (match_operator:DI 0 "equality_op"
5762 [(match_operand:DI 1 "register_operand" "d,t")
5764 (match_operand 2 "pc_or_label_operand" "")
5765 (match_operand 3 "pc_or_label_operand" "")))]
5768 if (operands[2] != pc_rtx)
5770 if (which_alternative == 0)
5771 return "b%C0z\t%1,%2";
5773 return "bt%C0z\t%2";
5777 if (which_alternative == 0)
5778 return "b%N0z\t%1,%3";
5780 return "bt%N0z\t%3";
5783 [(set_attr "type" "branch")
5784 (set_attr "mode" "none")
5785 (set_attr "length" "8")])
5787 (define_expand "bunordered"
5789 (if_then_else (unordered:CC (cc0)
5791 (label_ref (match_operand 0 ""))
5795 gen_conditional_branch (operands, UNORDERED);
5799 (define_expand "bordered"
5801 (if_then_else (ordered:CC (cc0)
5803 (label_ref (match_operand 0 ""))
5807 gen_conditional_branch (operands, ORDERED);
5811 (define_expand "bunlt"
5813 (if_then_else (unlt:CC (cc0)
5815 (label_ref (match_operand 0 ""))
5819 gen_conditional_branch (operands, UNLT);
5823 (define_expand "bunge"
5825 (if_then_else (unge:CC (cc0)
5827 (label_ref (match_operand 0 ""))
5831 gen_conditional_branch (operands, UNGE);
5835 (define_expand "buneq"
5837 (if_then_else (uneq:CC (cc0)
5839 (label_ref (match_operand 0 ""))
5843 gen_conditional_branch (operands, UNEQ);
5847 (define_expand "bltgt"
5849 (if_then_else (ltgt:CC (cc0)
5851 (label_ref (match_operand 0 ""))
5855 gen_conditional_branch (operands, LTGT);
5859 (define_expand "bunle"
5861 (if_then_else (unle:CC (cc0)
5863 (label_ref (match_operand 0 ""))
5867 gen_conditional_branch (operands, UNLE);
5871 (define_expand "bungt"
5873 (if_then_else (ungt:CC (cc0)
5875 (label_ref (match_operand 0 ""))
5879 gen_conditional_branch (operands, UNGT);
5883 (define_expand "beq"
5885 (if_then_else (eq:CC (cc0)
5887 (label_ref (match_operand 0 ""))
5891 gen_conditional_branch (operands, EQ);
5895 (define_expand "bne"
5897 (if_then_else (ne:CC (cc0)
5899 (label_ref (match_operand 0 ""))
5903 gen_conditional_branch (operands, NE);
5907 (define_expand "bgt"
5909 (if_then_else (gt:CC (cc0)
5911 (label_ref (match_operand 0 ""))
5915 gen_conditional_branch (operands, GT);
5919 (define_expand "bge"
5921 (if_then_else (ge:CC (cc0)
5923 (label_ref (match_operand 0 ""))
5927 gen_conditional_branch (operands, GE);
5931 (define_expand "blt"
5933 (if_then_else (lt:CC (cc0)
5935 (label_ref (match_operand 0 ""))
5939 gen_conditional_branch (operands, LT);
5943 (define_expand "ble"
5945 (if_then_else (le:CC (cc0)
5947 (label_ref (match_operand 0 ""))
5951 gen_conditional_branch (operands, LE);
5955 (define_expand "bgtu"
5957 (if_then_else (gtu:CC (cc0)
5959 (label_ref (match_operand 0 ""))
5963 gen_conditional_branch (operands, GTU);
5967 (define_expand "bgeu"
5969 (if_then_else (geu:CC (cc0)
5971 (label_ref (match_operand 0 ""))
5975 gen_conditional_branch (operands, GEU);
5979 (define_expand "bltu"
5981 (if_then_else (ltu:CC (cc0)
5983 (label_ref (match_operand 0 ""))
5987 gen_conditional_branch (operands, LTU);
5991 (define_expand "bleu"
5993 (if_then_else (leu:CC (cc0)
5995 (label_ref (match_operand 0 ""))
5999 gen_conditional_branch (operands, LEU);
6004 ;; ....................
6006 ;; SETTING A REGISTER FROM A COMPARISON
6008 ;; ....................
6010 (define_expand "seq"
6011 [(set (match_operand:SI 0 "register_operand")
6012 (eq:SI (match_dup 1)
6016 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6019 gen_int_relational (EQ, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6024 (define_insn "*seq_si"
6025 [(set (match_operand:SI 0 "register_operand" "=d")
6026 (eq:SI (match_operand:SI 1 "register_operand" "d")
6030 [(set_attr "type" "slt")
6031 (set_attr "mode" "SI")])
6033 (define_insn "*seq_si_mips16"
6034 [(set (match_operand:SI 0 "register_operand" "=t")
6035 (eq:SI (match_operand:SI 1 "register_operand" "d")
6039 [(set_attr "type" "slt")
6040 (set_attr "mode" "SI")])
6042 (define_insn "*seq_di"
6043 [(set (match_operand:DI 0 "register_operand" "=d")
6044 (eq:DI (match_operand:DI 1 "register_operand" "d")
6046 "TARGET_64BIT && !TARGET_MIPS16"
6048 [(set_attr "type" "slt")
6049 (set_attr "mode" "DI")])
6051 (define_insn "*seq_di_mips16"
6052 [(set (match_operand:DI 0 "register_operand" "=t")
6053 (eq:DI (match_operand:DI 1 "register_operand" "d")
6055 "TARGET_64BIT && TARGET_MIPS16"
6057 [(set_attr "type" "slt")
6058 (set_attr "mode" "DI")])
6060 ;; On the mips16 the default code is better than using sltu.
6062 (define_expand "sne"
6063 [(set (match_operand:SI 0 "register_operand")
6064 (ne:SI (match_dup 1)
6068 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6071 gen_int_relational (NE, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6075 (define_insn "*sne_si"
6076 [(set (match_operand:SI 0 "register_operand" "=d")
6077 (ne:SI (match_operand:SI 1 "register_operand" "d")
6081 [(set_attr "type" "slt")
6082 (set_attr "mode" "SI")])
6084 (define_insn "*sne_di"
6085 [(set (match_operand:DI 0 "register_operand" "=d")
6086 (ne:DI (match_operand:DI 1 "register_operand" "d")
6088 "TARGET_64BIT && !TARGET_MIPS16"
6090 [(set_attr "type" "slt")
6091 (set_attr "mode" "DI")])
6093 (define_expand "sgt"
6094 [(set (match_operand:SI 0 "register_operand")
6095 (gt:SI (match_dup 1)
6099 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6102 gen_int_relational (GT, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6106 (define_insn "*sgt_si"
6107 [(set (match_operand:SI 0 "register_operand" "=d")
6108 (gt:SI (match_operand:SI 1 "register_operand" "d")
6109 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6112 [(set_attr "type" "slt")
6113 (set_attr "mode" "SI")])
6115 (define_insn "*sgt_si_mips16"
6116 [(set (match_operand:SI 0 "register_operand" "=t")
6117 (gt:SI (match_operand:SI 1 "register_operand" "d")
6118 (match_operand:SI 2 "register_operand" "d")))]
6121 [(set_attr "type" "slt")
6122 (set_attr "mode" "SI")])
6124 (define_insn "*sgt_di"
6125 [(set (match_operand:DI 0 "register_operand" "=d")
6126 (gt:DI (match_operand:DI 1 "register_operand" "d")
6127 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6128 "TARGET_64BIT && !TARGET_MIPS16"
6130 [(set_attr "type" "slt")
6131 (set_attr "mode" "DI")])
6133 (define_insn "*sgt_di_mips16"
6134 [(set (match_operand:DI 0 "register_operand" "=t")
6135 (gt:DI (match_operand:DI 1 "register_operand" "d")
6136 (match_operand:DI 2 "register_operand" "d")))]
6137 "TARGET_64BIT && TARGET_MIPS16"
6139 [(set_attr "type" "slt")
6140 (set_attr "mode" "DI")])
6142 (define_expand "sge"
6143 [(set (match_operand:SI 0 "register_operand")
6144 (ge:SI (match_dup 1)
6148 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6151 gen_int_relational (GE, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6155 (define_expand "slt"
6156 [(set (match_operand:SI 0 "register_operand")
6157 (lt:SI (match_dup 1)
6161 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6164 gen_int_relational (LT, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6168 (define_insn "*slt_si"
6169 [(set (match_operand:SI 0 "register_operand" "=d")
6170 (lt:SI (match_operand:SI 1 "register_operand" "d")
6171 (match_operand:SI 2 "arith_operand" "dI")))]
6174 [(set_attr "type" "slt")
6175 (set_attr "mode" "SI")])
6177 (define_insn "*slt_si_mips16"
6178 [(set (match_operand:SI 0 "register_operand" "=t,t")
6179 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
6180 (match_operand:SI 2 "arith_operand" "d,I")))]
6183 [(set_attr "type" "slt")
6184 (set_attr "mode" "SI")
6185 (set_attr_alternative "length"
6187 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6191 (define_insn "*slt_di"
6192 [(set (match_operand:DI 0 "register_operand" "=d")
6193 (lt:DI (match_operand:DI 1 "register_operand" "d")
6194 (match_operand:DI 2 "arith_operand" "dI")))]
6195 "TARGET_64BIT && !TARGET_MIPS16"
6197 [(set_attr "type" "slt")
6198 (set_attr "mode" "DI")])
6200 (define_insn "*slt_di_mips16"
6201 [(set (match_operand:DI 0 "register_operand" "=t,t")
6202 (lt:DI (match_operand:DI 1 "register_operand" "d,d")
6203 (match_operand:DI 2 "arith_operand" "d,I")))]
6204 "TARGET_64BIT && TARGET_MIPS16"
6206 [(set_attr "type" "slt")
6207 (set_attr "mode" "DI")
6208 (set_attr_alternative "length"
6210 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6214 (define_expand "sle"
6215 [(set (match_operand:SI 0 "register_operand")
6216 (le:SI (match_dup 1)
6220 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6223 gen_int_relational (LE, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6227 (define_insn "*sle_si"
6228 [(set (match_operand:SI 0 "register_operand" "=d")
6229 (le:SI (match_operand:SI 1 "register_operand" "d")
6230 (match_operand:SI 2 "small_int" "I")))]
6231 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6233 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6234 return "slt\t%0,%1,%2";
6236 [(set_attr "type" "slt")
6237 (set_attr "mode" "SI")])
6239 (define_insn "*sle_si_mips16"
6240 [(set (match_operand:SI 0 "register_operand" "=t")
6241 (le:SI (match_operand:SI 1 "register_operand" "d")
6242 (match_operand:SI 2 "small_int" "I")))]
6243 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6245 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6246 return "slt\t%1,%2";
6248 [(set_attr "type" "slt")
6249 (set_attr "mode" "SI")
6250 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6254 (define_insn "*sle_di"
6255 [(set (match_operand:DI 0 "register_operand" "=d")
6256 (le:DI (match_operand:DI 1 "register_operand" "d")
6257 (match_operand:DI 2 "small_int" "I")))]
6258 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6260 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6261 return "slt\t%0,%1,%2";
6263 [(set_attr "type" "slt")
6264 (set_attr "mode" "DI")])
6266 (define_insn "*sle_di_mips16"
6267 [(set (match_operand:DI 0 "register_operand" "=t")
6268 (le:DI (match_operand:DI 1 "register_operand" "d")
6269 (match_operand:DI 2 "small_int" "I")))]
6270 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6272 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6273 return "slt\t%1,%2";
6275 [(set_attr "type" "slt")
6276 (set_attr "mode" "DI")
6277 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6281 (define_expand "sgtu"
6282 [(set (match_operand:SI 0 "register_operand")
6283 (gtu:SI (match_dup 1)
6287 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6290 gen_int_relational (GTU, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6294 (define_insn "*sgtu_si"
6295 [(set (match_operand:SI 0 "register_operand" "=d")
6296 (gtu:SI (match_operand:SI 1 "register_operand" "d")
6297 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6300 [(set_attr "type" "slt")
6301 (set_attr "mode" "SI")])
6303 (define_insn "*sgtu_si_mips16"
6304 [(set (match_operand:SI 0 "register_operand" "=t")
6305 (gtu:SI (match_operand:SI 1 "register_operand" "d")
6306 (match_operand:SI 2 "register_operand" "d")))]
6309 [(set_attr "type" "slt")
6310 (set_attr "mode" "SI")])
6312 (define_insn "*sgtu_di"
6313 [(set (match_operand:DI 0 "register_operand" "=d")
6314 (gtu:DI (match_operand:DI 1 "register_operand" "d")
6315 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6316 "TARGET_64BIT && !TARGET_MIPS16"
6318 [(set_attr "type" "slt")
6319 (set_attr "mode" "DI")])
6321 (define_insn "*sgtu_di_mips16"
6322 [(set (match_operand:DI 0 "register_operand" "=t")
6323 (gtu:DI (match_operand:DI 1 "register_operand" "d")
6324 (match_operand:DI 2 "register_operand" "d")))]
6325 "TARGET_64BIT && TARGET_MIPS16"
6327 [(set_attr "type" "slt")
6328 (set_attr "mode" "DI")])
6330 (define_expand "sgeu"
6331 [(set (match_operand:SI 0 "register_operand")
6332 (geu:SI (match_dup 1)
6336 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6339 gen_int_relational (GEU, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6343 (define_expand "sltu"
6344 [(set (match_operand:SI 0 "register_operand")
6345 (ltu:SI (match_dup 1)
6349 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6352 gen_int_relational (LTU, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6356 (define_insn "*sltu_si"
6357 [(set (match_operand:SI 0 "register_operand" "=d")
6358 (ltu:SI (match_operand:SI 1 "register_operand" "d")
6359 (match_operand:SI 2 "arith_operand" "dI")))]
6362 [(set_attr "type" "slt")
6363 (set_attr "mode" "SI")])
6365 (define_insn "*sltu_si_mips16"
6366 [(set (match_operand:SI 0 "register_operand" "=t,t")
6367 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
6368 (match_operand:SI 2 "arith_operand" "d,I")))]
6371 [(set_attr "type" "slt")
6372 (set_attr "mode" "SI")
6373 (set_attr_alternative "length"
6375 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6379 (define_insn "*sltu_di"
6380 [(set (match_operand:DI 0 "register_operand" "=d")
6381 (ltu:DI (match_operand:DI 1 "register_operand" "d")
6382 (match_operand:DI 2 "arith_operand" "dI")))]
6383 "TARGET_64BIT && !TARGET_MIPS16"
6385 [(set_attr "type" "slt")
6386 (set_attr "mode" "DI")])
6388 (define_insn "*sltu_di_mips16"
6389 [(set (match_operand:DI 0 "register_operand" "=t,t")
6390 (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
6391 (match_operand:DI 2 "arith_operand" "d,I")))]
6392 "TARGET_64BIT && TARGET_MIPS16"
6394 [(set_attr "type" "slt")
6395 (set_attr "mode" "DI")
6396 (set_attr_alternative "length"
6398 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6402 (define_expand "sleu"
6403 [(set (match_operand:SI 0 "register_operand")
6404 (leu:SI (match_dup 1)
6408 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6411 gen_int_relational (LEU, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6415 (define_insn "*sleu_si"
6416 [(set (match_operand:SI 0 "register_operand" "=d")
6417 (leu:SI (match_operand:SI 1 "register_operand" "d")
6418 (match_operand:SI 2 "small_int" "I")))]
6419 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6421 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6422 return "sltu\t%0,%1,%2";
6424 [(set_attr "type" "slt")
6425 (set_attr "mode" "SI")])
6427 (define_insn "*sleu_si_mips16"
6428 [(set (match_operand:SI 0 "register_operand" "=t")
6429 (leu:SI (match_operand:SI 1 "register_operand" "d")
6430 (match_operand:SI 2 "small_int" "I")))]
6431 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6433 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6434 return "sltu\t%1,%2";
6436 [(set_attr "type" "slt")
6437 (set_attr "mode" "SI")
6438 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6442 (define_insn "*sleu_di"
6443 [(set (match_operand:DI 0 "register_operand" "=d")
6444 (leu:DI (match_operand:DI 1 "register_operand" "d")
6445 (match_operand:DI 2 "small_int" "I")))]
6446 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6448 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6449 return "sltu\t%0,%1,%2";
6451 [(set_attr "type" "slt")
6452 (set_attr "mode" "DI")])
6454 (define_insn "*sleu_di_mips16"
6455 [(set (match_operand:DI 0 "register_operand" "=t")
6456 (leu:DI (match_operand:DI 1 "register_operand" "d")
6457 (match_operand:DI 2 "small_int" "I")))]
6458 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6460 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6461 return "sltu\t%1,%2";
6463 [(set_attr "type" "slt")
6464 (set_attr "mode" "DI")
6465 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6470 ;; ....................
6472 ;; FLOATING POINT COMPARISONS
6474 ;; ....................
6476 (define_insn "sunordered_df"
6477 [(set (match_operand:CC 0 "register_operand" "=z")
6478 (unordered:CC (match_operand:DF 1 "register_operand" "f")
6479 (match_operand:DF 2 "register_operand" "f")))]
6480 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6482 [(set_attr "type" "fcmp")
6483 (set_attr "mode" "FPSW")])
6485 (define_insn "sunlt_df"
6486 [(set (match_operand:CC 0 "register_operand" "=z")
6487 (unlt:CC (match_operand:DF 1 "register_operand" "f")
6488 (match_operand:DF 2 "register_operand" "f")))]
6489 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6491 [(set_attr "type" "fcmp")
6492 (set_attr "mode" "FPSW")])
6494 (define_insn "suneq_df"
6495 [(set (match_operand:CC 0 "register_operand" "=z")
6496 (uneq:CC (match_operand:DF 1 "register_operand" "f")
6497 (match_operand:DF 2 "register_operand" "f")))]
6498 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6500 [(set_attr "type" "fcmp")
6501 (set_attr "mode" "FPSW")])
6503 (define_insn "sunle_df"
6504 [(set (match_operand:CC 0 "register_operand" "=z")
6505 (unle:CC (match_operand:DF 1 "register_operand" "f")
6506 (match_operand:DF 2 "register_operand" "f")))]
6507 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6509 [(set_attr "type" "fcmp")
6510 (set_attr "mode" "FPSW")])
6512 (define_insn "seq_df"
6513 [(set (match_operand:CC 0 "register_operand" "=z")
6514 (eq:CC (match_operand:DF 1 "register_operand" "f")
6515 (match_operand:DF 2 "register_operand" "f")))]
6516 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6518 [(set_attr "type" "fcmp")
6519 (set_attr "mode" "FPSW")])
6521 (define_insn "slt_df"
6522 [(set (match_operand:CC 0 "register_operand" "=z")
6523 (lt:CC (match_operand:DF 1 "register_operand" "f")
6524 (match_operand:DF 2 "register_operand" "f")))]
6525 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6527 [(set_attr "type" "fcmp")
6528 (set_attr "mode" "FPSW")])
6530 (define_insn "sle_df"
6531 [(set (match_operand:CC 0 "register_operand" "=z")
6532 (le:CC (match_operand:DF 1 "register_operand" "f")
6533 (match_operand:DF 2 "register_operand" "f")))]
6534 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6536 [(set_attr "type" "fcmp")
6537 (set_attr "mode" "FPSW")])
6539 (define_insn "sgt_df"
6540 [(set (match_operand:CC 0 "register_operand" "=z")
6541 (gt:CC (match_operand:DF 1 "register_operand" "f")
6542 (match_operand:DF 2 "register_operand" "f")))]
6543 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6545 [(set_attr "type" "fcmp")
6546 (set_attr "mode" "FPSW")])
6548 (define_insn "sge_df"
6549 [(set (match_operand:CC 0 "register_operand" "=z")
6550 (ge:CC (match_operand:DF 1 "register_operand" "f")
6551 (match_operand:DF 2 "register_operand" "f")))]
6552 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6554 [(set_attr "type" "fcmp")
6555 (set_attr "mode" "FPSW")])
6557 (define_insn "sunordered_sf"
6558 [(set (match_operand:CC 0 "register_operand" "=z")
6559 (unordered:CC (match_operand:SF 1 "register_operand" "f")
6560 (match_operand:SF 2 "register_operand" "f")))]
6563 [(set_attr "type" "fcmp")
6564 (set_attr "mode" "FPSW")])
6566 (define_insn "sunlt_sf"
6567 [(set (match_operand:CC 0 "register_operand" "=z")
6568 (unlt:CC (match_operand:SF 1 "register_operand" "f")
6569 (match_operand:SF 2 "register_operand" "f")))]
6572 [(set_attr "type" "fcmp")
6573 (set_attr "mode" "FPSW")])
6575 (define_insn "suneq_sf"
6576 [(set (match_operand:CC 0 "register_operand" "=z")
6577 (uneq:CC (match_operand:SF 1 "register_operand" "f")
6578 (match_operand:SF 2 "register_operand" "f")))]
6581 [(set_attr "type" "fcmp")
6582 (set_attr "mode" "FPSW")])
6584 (define_insn "sunle_sf"
6585 [(set (match_operand:CC 0 "register_operand" "=z")
6586 (unle:CC (match_operand:SF 1 "register_operand" "f")
6587 (match_operand:SF 2 "register_operand" "f")))]
6590 [(set_attr "type" "fcmp")
6591 (set_attr "mode" "FPSW")])
6593 (define_insn "seq_sf"
6594 [(set (match_operand:CC 0 "register_operand" "=z")
6595 (eq:CC (match_operand:SF 1 "register_operand" "f")
6596 (match_operand:SF 2 "register_operand" "f")))]
6599 [(set_attr "type" "fcmp")
6600 (set_attr "mode" "FPSW")])
6602 (define_insn "slt_sf"
6603 [(set (match_operand:CC 0 "register_operand" "=z")
6604 (lt:CC (match_operand:SF 1 "register_operand" "f")
6605 (match_operand:SF 2 "register_operand" "f")))]
6608 [(set_attr "type" "fcmp")
6609 (set_attr "mode" "FPSW")])
6611 (define_insn "sle_sf"
6612 [(set (match_operand:CC 0 "register_operand" "=z")
6613 (le:CC (match_operand:SF 1 "register_operand" "f")
6614 (match_operand:SF 2 "register_operand" "f")))]
6617 [(set_attr "type" "fcmp")
6618 (set_attr "mode" "FPSW")])
6620 (define_insn "sgt_sf"
6621 [(set (match_operand:CC 0 "register_operand" "=z")
6622 (gt:CC (match_operand:SF 1 "register_operand" "f")
6623 (match_operand:SF 2 "register_operand" "f")))]
6626 [(set_attr "type" "fcmp")
6627 (set_attr "mode" "FPSW")])
6629 (define_insn "sge_sf"
6630 [(set (match_operand:CC 0 "register_operand" "=z")
6631 (ge:CC (match_operand:SF 1 "register_operand" "f")
6632 (match_operand:SF 2 "register_operand" "f")))]
6635 [(set_attr "type" "fcmp")
6636 (set_attr "mode" "FPSW")])
6639 ;; ....................
6641 ;; UNCONDITIONAL BRANCHES
6643 ;; ....................
6645 ;; Unconditional branches.
6649 (label_ref (match_operand 0 "" "")))]
6654 if (get_attr_length (insn) <= 8)
6655 return "%*b\t%l0%/";
6658 output_asm_insn (mips_output_load_label (), operands);
6659 return "%*jr\t%@%/%]";
6663 return "%*j\t%l0%/";
6665 [(set_attr "type" "jump")
6666 (set_attr "mode" "none")
6667 (set (attr "length")
6668 ;; We can't use `j' when emitting PIC. Emit a branch if it's
6669 ;; in range, otherwise load the address of the branch target into
6670 ;; $at and then jump to it.
6672 (ior (eq (symbol_ref "flag_pic") (const_int 0))
6673 (lt (abs (minus (match_dup 0)
6674 (plus (pc) (const_int 4))))
6675 (const_int 131072)))
6676 (const_int 4) (const_int 16)))])
6678 ;; We need a different insn for the mips16, because a mips16 branch
6679 ;; does not have a delay slot.
6683 (label_ref (match_operand 0 "" "")))]
6686 [(set_attr "type" "branch")
6687 (set_attr "mode" "none")
6688 (set_attr "length" "8")])
6690 (define_expand "indirect_jump"
6691 [(set (pc) (match_operand 0 "register_operand"))]
6697 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
6698 operands[0] = copy_to_mode_reg (Pmode, dest);
6700 if (!(Pmode == DImode))
6701 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
6703 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
6708 (define_insn "indirect_jump_internal1"
6709 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
6710 "!(Pmode == DImode)"
6712 [(set_attr "type" "jump")
6713 (set_attr "mode" "none")])
6715 (define_insn "indirect_jump_internal2"
6716 [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
6719 [(set_attr "type" "jump")
6720 (set_attr "mode" "none")])
6722 (define_expand "tablejump"
6724 (match_operand 0 "register_operand"))
6725 (use (label_ref (match_operand 1 "")))]
6730 if (GET_MODE (operands[0]) != HImode)
6732 if (!(Pmode == DImode))
6733 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
6735 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
6739 if (GET_MODE (operands[0]) != ptr_mode)
6743 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
6744 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
6746 if (Pmode == SImode)
6747 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
6749 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
6753 (define_insn "tablejump_internal1"
6755 (match_operand:SI 0 "register_operand" "d"))
6756 (use (label_ref (match_operand 1 "" "")))]
6759 [(set_attr "type" "jump")
6760 (set_attr "mode" "none")])
6762 (define_insn "tablejump_internal2"
6764 (match_operand:DI 0 "register_operand" "d"))
6765 (use (label_ref (match_operand 1 "" "")))]
6768 [(set_attr "type" "jump")
6769 (set_attr "mode" "none")])
6771 (define_expand "tablejump_mips161"
6772 [(set (pc) (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand"))
6773 (label_ref:SI (match_operand 1 ""))))]
6774 "TARGET_MIPS16 && !(Pmode == DImode)"
6778 t1 = gen_reg_rtx (SImode);
6779 t2 = gen_reg_rtx (SImode);
6780 t3 = gen_reg_rtx (SImode);
6781 emit_insn (gen_extendhisi2 (t1, operands[0]));
6782 emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
6783 emit_insn (gen_addsi3 (t3, t1, t2));
6784 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
6788 (define_expand "tablejump_mips162"
6789 [(set (pc) (plus:DI (sign_extend:DI (match_operand:HI 0 "register_operand"))
6790 (label_ref:DI (match_operand 1 ""))))]
6791 "TARGET_MIPS16 && Pmode == DImode"
6795 t1 = gen_reg_rtx (DImode);
6796 t2 = gen_reg_rtx (DImode);
6797 t3 = gen_reg_rtx (DImode);
6798 emit_insn (gen_extendhidi2 (t1, operands[0]));
6799 emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
6800 emit_insn (gen_adddi3 (t3, t1, t2));
6801 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
6805 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
6806 ;; While it is possible to either pull it off the stack (in the
6807 ;; o32 case) or recalculate it given t9 and our target label,
6808 ;; it takes 3 or 4 insns to do so.
6810 (define_expand "builtin_setjmp_setup"
6811 [(use (match_operand 0 "register_operand"))]
6816 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
6817 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
6821 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
6822 ;; that older code did recalculate the gp from $25. Continue to jump through
6823 ;; $25 for compatibility (we lose nothing by doing so).
6825 (define_expand "builtin_longjmp"
6826 [(use (match_operand 0 "register_operand"))]
6829 /* The elements of the buffer are, in order: */
6830 int W = GET_MODE_SIZE (Pmode);
6831 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6832 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
6833 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
6834 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
6835 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6836 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
6837 The target is bound to be using $28 as the global pointer
6838 but the current function might not be. */
6839 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
6841 /* This bit is similar to expand_builtin_longjmp except that it
6842 restores $gp as well. */
6843 emit_move_insn (hard_frame_pointer_rtx, fp);
6844 emit_move_insn (pv, lab);
6845 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6846 emit_move_insn (gp, gpv);
6847 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6848 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6849 emit_insn (gen_rtx_USE (VOIDmode, gp));
6850 emit_indirect_jump (pv);
6855 ;; ....................
6857 ;; Function prologue/epilogue
6859 ;; ....................
6862 (define_expand "prologue"
6866 mips_expand_prologue ();
6870 ;; Block any insns from being moved before this point, since the
6871 ;; profiling call to mcount can use various registers that aren't
6872 ;; saved or used to pass arguments.
6874 (define_insn "blockage"
6875 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
6878 [(set_attr "type" "unknown")
6879 (set_attr "mode" "none")
6880 (set_attr "length" "0")])
6882 (define_expand "epilogue"
6886 mips_expand_epilogue (false);
6890 (define_expand "sibcall_epilogue"
6894 mips_expand_epilogue (true);
6898 ;; Trivial return. Make it look like a normal return insn as that
6899 ;; allows jump optimizations to work better.
6901 (define_insn "return"
6903 "mips_can_use_return_insn ()"
6905 [(set_attr "type" "jump")
6906 (set_attr "mode" "none")])
6910 (define_insn "return_internal"
6912 (use (match_operand 0 "pmode_register_operand" ""))]
6915 [(set_attr "type" "jump")
6916 (set_attr "mode" "none")])
6918 ;; This is used in compiling the unwind routines.
6919 (define_expand "eh_return"
6920 [(use (match_operand 0 "general_operand"))]
6923 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
6925 if (GET_MODE (operands[0]) != gpr_mode)
6926 operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
6928 emit_insn (gen_eh_set_lr_di (operands[0]));
6930 emit_insn (gen_eh_set_lr_si (operands[0]));
6935 ;; Clobber the return address on the stack. We can't expand this
6936 ;; until we know where it will be put in the stack frame.
6938 (define_insn "eh_set_lr_si"
6939 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6940 (clobber (match_scratch:SI 1 "=&d"))]
6944 (define_insn "eh_set_lr_di"
6945 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6946 (clobber (match_scratch:DI 1 "=&d"))]
6951 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6952 (clobber (match_scratch 1))]
6953 "reload_completed && !TARGET_DEBUG_D_MODE"
6956 mips_set_return_address (operands[0], operands[1]);
6960 (define_insn "exception_receiver"
6962 (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
6963 "TARGET_ABICALLS && TARGET_OLDABI"
6965 operands[0] = pic_offset_table_rtx;
6966 operands[1] = mips_gp_save_slot ();
6967 return mips_output_move (operands[0], operands[1]);
6969 [(set_attr "type" "load")
6970 (set_attr "length" "8")])
6973 ;; ....................
6977 ;; ....................
6979 ;; Instructions to load a call address from the GOT. The address might
6980 ;; point to a function or to a lazy binding stub. In the latter case,
6981 ;; the stub will use the dynamic linker to resolve the function, which
6982 ;; in turn will change the GOT entry to point to the function's real
6985 ;; This means that every call, even pure and constant ones, can
6986 ;; potentially modify the GOT entry. And once a stub has been called,
6987 ;; we must not call it again.
6989 ;; We represent this restriction using an imaginary fixed register that
6990 ;; acts like a GOT version number. By making the register call-clobbered,
6991 ;; we tell the target-independent code that the address could be changed
6992 ;; by any call insn.
6993 (define_insn "load_callsi"
6994 [(set (match_operand:SI 0 "register_operand" "=c")
6995 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6996 (match_operand:SI 2 "immediate_operand" "")
6997 (reg:SI FAKE_CALL_REGNO)]
7001 [(set_attr "type" "load")
7002 (set_attr "length" "4")])
7004 (define_insn "load_calldi"
7005 [(set (match_operand:DI 0 "register_operand" "=c")
7006 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7007 (match_operand:DI 2 "immediate_operand" "")
7008 (reg:DI FAKE_CALL_REGNO)]
7012 [(set_attr "type" "load")
7013 (set_attr "length" "4")])
7015 ;; Sibling calls. All these patterns use jump instructions.
7017 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
7018 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
7019 ;; is defined in terms of call_insn_operand, the same is true of the
7022 ;; When we use an indirect jump, we need a register that will be
7023 ;; preserved by the epilogue. Since TARGET_ABICALLS forces us to
7024 ;; use $25 for this purpose -- and $25 is never clobbered by the
7025 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
7027 (define_expand "sibcall"
7028 [(parallel [(call (match_operand 0 "")
7029 (match_operand 1 ""))
7030 (use (match_operand 2 "")) ;; next_arg_reg
7031 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
7034 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
7038 (define_insn "sibcall_internal"
7039 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
7040 (match_operand 1 "" ""))]
7041 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7045 [(set_attr "type" "call")])
7047 (define_expand "sibcall_value"
7048 [(parallel [(set (match_operand 0 "")
7049 (call (match_operand 1 "")
7050 (match_operand 2 "")))
7051 (use (match_operand 3 ""))])] ;; next_arg_reg
7054 mips_expand_call (operands[0], XEXP (operands[1], 0),
7055 operands[2], operands[3], true);
7059 (define_insn "sibcall_value_internal"
7060 [(set (match_operand 0 "register_operand" "=df,df")
7061 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
7062 (match_operand 2 "" "")))]
7063 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7067 [(set_attr "type" "call")])
7069 (define_insn "sibcall_value_multiple_internal"
7070 [(set (match_operand 0 "register_operand" "=df,df")
7071 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
7072 (match_operand 2 "" "")))
7073 (set (match_operand 3 "register_operand" "=df,df")
7074 (call (mem:SI (match_dup 1))
7076 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7080 [(set_attr "type" "call")])
7082 (define_expand "call"
7083 [(parallel [(call (match_operand 0 "")
7084 (match_operand 1 ""))
7085 (use (match_operand 2 "")) ;; next_arg_reg
7086 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
7089 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
7093 ;; This instruction directly corresponds to an assembly-language "jal".
7094 ;; There are four cases:
7097 ;; Both symbolic and register destinations are OK. The pattern
7098 ;; always expands to a single mips instruction.
7100 ;; - -mabicalls/-mno-explicit-relocs:
7101 ;; Again, both symbolic and register destinations are OK.
7102 ;; The call is treated as a multi-instruction black box.
7104 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
7105 ;; Only "jal $25" is allowed. This expands to a single "jalr $25"
7108 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
7109 ;; Only "jal $25" is allowed. The call is actually two instructions:
7110 ;; "jalr $25" followed by an insn to reload $gp.
7112 ;; In the last case, we can generate the individual instructions with
7113 ;; a define_split. There are several things to be wary of:
7115 ;; - We can't expose the load of $gp before reload. If we did,
7116 ;; it might get removed as dead, but reload can introduce new
7117 ;; uses of $gp by rematerializing constants.
7119 ;; - We shouldn't restore $gp after calls that never return.
7120 ;; It isn't valid to insert instructions between a noreturn
7121 ;; call and the following barrier.
7123 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
7124 ;; instruction preserves $gp and so have no effect on its liveness.
7125 ;; But once we generate the separate insns, it becomes obvious that
7126 ;; $gp is not live on entry to the call.
7128 ;; ??? The operands[2] = insn check is a hack to make the original insn
7129 ;; available to the splitter.
7130 (define_insn_and_split "call_internal"
7131 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
7132 (match_operand 1 "" ""))
7133 (clobber (reg:SI 31))]
7135 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
7136 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
7139 emit_call_insn (gen_call_split (operands[0], operands[1]));
7140 if (!find_reg_note (operands[2], REG_NORETURN, 0))
7141 emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
7144 [(set_attr "jal" "indirect,direct")
7145 (set_attr "extended_mips16" "no,yes")])
7147 (define_insn "call_split"
7148 [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
7149 (match_operand 1 "" ""))
7150 (clobber (reg:SI 31))
7151 (clobber (reg:SI 28))]
7152 "TARGET_SPLIT_CALLS"
7154 [(set_attr "type" "call")])
7156 (define_expand "call_value"
7157 [(parallel [(set (match_operand 0 "")
7158 (call (match_operand 1 "")
7159 (match_operand 2 "")))
7160 (use (match_operand 3 ""))])] ;; next_arg_reg
7163 mips_expand_call (operands[0], XEXP (operands[1], 0),
7164 operands[2], operands[3], false);
7168 ;; See comment for call_internal.
7169 (define_insn_and_split "call_value_internal"
7170 [(set (match_operand 0 "register_operand" "=df,df")
7171 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7172 (match_operand 2 "" "")))
7173 (clobber (reg:SI 31))]
7175 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7176 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
7179 emit_call_insn (gen_call_value_split (operands[0], operands[1],
7181 if (!find_reg_note (operands[3], REG_NORETURN, 0))
7182 emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
7185 [(set_attr "jal" "indirect,direct")
7186 (set_attr "extended_mips16" "no,yes")])
7188 (define_insn "call_value_split"
7189 [(set (match_operand 0 "register_operand" "=df")
7190 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7191 (match_operand 2 "" "")))
7192 (clobber (reg:SI 31))
7193 (clobber (reg:SI 28))]
7194 "TARGET_SPLIT_CALLS"
7196 [(set_attr "type" "call")])
7198 ;; See comment for call_internal.
7199 (define_insn_and_split "call_value_multiple_internal"
7200 [(set (match_operand 0 "register_operand" "=df,df")
7201 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7202 (match_operand 2 "" "")))
7203 (set (match_operand 3 "register_operand" "=df,df")
7204 (call (mem:SI (match_dup 1))
7206 (clobber (reg:SI 31))]
7208 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7209 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
7212 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
7213 operands[2], operands[3]));
7214 if (!find_reg_note (operands[4], REG_NORETURN, 0))
7215 emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
7218 [(set_attr "jal" "indirect,direct")
7219 (set_attr "extended_mips16" "no,yes")])
7221 (define_insn "call_value_multiple_split"
7222 [(set (match_operand 0 "register_operand" "=df")
7223 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7224 (match_operand 2 "" "")))
7225 (set (match_operand 3 "register_operand" "=df")
7226 (call (mem:SI (match_dup 1))
7228 (clobber (reg:SI 31))
7229 (clobber (reg:SI 28))]
7230 "TARGET_SPLIT_CALLS"
7232 [(set_attr "type" "call")])
7234 ;; Call subroutine returning any type.
7236 (define_expand "untyped_call"
7237 [(parallel [(call (match_operand 0 "")
7239 (match_operand 1 "")
7240 (match_operand 2 "")])]
7245 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
7247 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7249 rtx set = XVECEXP (operands[2], 0, i);
7250 emit_move_insn (SET_DEST (set), SET_SRC (set));
7253 emit_insn (gen_blockage ());
7258 ;; ....................
7262 ;; ....................
7266 (define_expand "prefetch"
7267 [(prefetch (match_operand 0 "address_operand")
7268 (match_operand 1 "const_int_operand")
7269 (match_operand 2 "const_int_operand"))]
7272 if (symbolic_operand (operands[0], GET_MODE (operands[0])))
7273 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
7276 (define_insn "prefetch_si_address"
7277 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7278 (match_operand:SI 3 "const_int_operand" "I"))
7279 (match_operand:SI 1 "const_int_operand" "n")
7280 (match_operand:SI 2 "const_int_operand" "n"))]
7281 "ISA_HAS_PREFETCH && Pmode == SImode"
7282 { return mips_emit_prefetch (operands); }
7283 [(set_attr "type" "prefetch")])
7285 (define_insn "prefetch_indexed_si"
7286 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7287 (match_operand:SI 3 "register_operand" "r"))
7288 (match_operand:SI 1 "const_int_operand" "n")
7289 (match_operand:SI 2 "const_int_operand" "n"))]
7290 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
7291 { return mips_emit_prefetch (operands); }
7292 [(set_attr "type" "prefetchx")])
7294 (define_insn "prefetch_si"
7295 [(prefetch (match_operand:SI 0 "register_operand" "r")
7296 (match_operand:SI 1 "const_int_operand" "n")
7297 (match_operand:SI 2 "const_int_operand" "n"))]
7298 "ISA_HAS_PREFETCH && Pmode == SImode"
7300 operands[3] = const0_rtx;
7301 return mips_emit_prefetch (operands);
7303 [(set_attr "type" "prefetch")])
7305 (define_insn "prefetch_di_address"
7306 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7307 (match_operand:DI 3 "const_int_operand" "I"))
7308 (match_operand:DI 1 "const_int_operand" "n")
7309 (match_operand:DI 2 "const_int_operand" "n"))]
7310 "ISA_HAS_PREFETCH && Pmode == DImode"
7311 { return mips_emit_prefetch (operands); }
7312 [(set_attr "type" "prefetch")])
7314 (define_insn "prefetch_indexed_di"
7315 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7316 (match_operand:DI 3 "register_operand" "r"))
7317 (match_operand:DI 1 "const_int_operand" "n")
7318 (match_operand:DI 2 "const_int_operand" "n"))]
7319 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
7320 { return mips_emit_prefetch (operands); }
7321 [(set_attr "type" "prefetchx")])
7323 (define_insn "prefetch_di"
7324 [(prefetch (match_operand:DI 0 "register_operand" "r")
7325 (match_operand:DI 1 "const_int_operand" "n")
7326 (match_operand:DI 2 "const_int_operand" "n"))]
7327 "ISA_HAS_PREFETCH && Pmode == DImode"
7329 operands[3] = const0_rtx;
7330 return mips_emit_prefetch (operands);
7332 [(set_attr "type" "prefetch")])
7338 [(set_attr "type" "nop")
7339 (set_attr "mode" "none")])
7341 ;; Like nop, but commented out when outside a .set noreorder block.
7342 (define_insn "hazard_nop"
7351 [(set_attr "type" "nop")])
7353 ;; MIPS4 Conditional move instructions.
7356 [(set (match_operand:SI 0 "register_operand" "=d,d")
7358 (match_operator 4 "equality_op"
7359 [(match_operand:SI 1 "register_operand" "d,d")
7361 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7362 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7363 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7367 [(set_attr "type" "condmove")
7368 (set_attr "mode" "SI")])
7371 [(set (match_operand:SI 0 "register_operand" "=d,d")
7373 (match_operator 4 "equality_op"
7374 [(match_operand:DI 1 "register_operand" "d,d")
7376 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7377 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7378 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7382 [(set_attr "type" "condmove")
7383 (set_attr "mode" "SI")])
7386 [(set (match_operand:SI 0 "register_operand" "=d,d")
7388 (match_operator 3 "equality_op" [(match_operand:CC 4
7392 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
7393 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
7394 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7398 [(set_attr "type" "condmove")
7399 (set_attr "mode" "SI")])
7402 [(set (match_operand:DI 0 "register_operand" "=d,d")
7404 (match_operator 4 "equality_op"
7405 [(match_operand:SI 1 "register_operand" "d,d")
7407 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7408 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7409 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7413 [(set_attr "type" "condmove")
7414 (set_attr "mode" "DI")])
7417 [(set (match_operand:DI 0 "register_operand" "=d,d")
7419 (match_operator 4 "equality_op"
7420 [(match_operand:DI 1 "register_operand" "d,d")
7422 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7423 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7424 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7428 [(set_attr "type" "condmove")
7429 (set_attr "mode" "DI")])
7432 [(set (match_operand:DI 0 "register_operand" "=d,d")
7434 (match_operator 3 "equality_op" [(match_operand:CC 4
7438 (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
7439 (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
7440 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
7444 [(set_attr "type" "condmove")
7445 (set_attr "mode" "DI")])
7448 [(set (match_operand:SF 0 "register_operand" "=f,f")
7450 (match_operator 4 "equality_op"
7451 [(match_operand:SI 1 "register_operand" "d,d")
7453 (match_operand:SF 2 "register_operand" "f,0")
7454 (match_operand:SF 3 "register_operand" "0,f")))]
7455 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7459 [(set_attr "type" "condmove")
7460 (set_attr "mode" "SF")])
7463 [(set (match_operand:SF 0 "register_operand" "=f,f")
7465 (match_operator 4 "equality_op"
7466 [(match_operand:DI 1 "register_operand" "d,d")
7468 (match_operand:SF 2 "register_operand" "f,0")
7469 (match_operand:SF 3 "register_operand" "0,f")))]
7470 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7474 [(set_attr "type" "condmove")
7475 (set_attr "mode" "SF")])
7478 [(set (match_operand:SF 0 "register_operand" "=f,f")
7480 (match_operator 3 "equality_op" [(match_operand:CC 4
7484 (match_operand:SF 1 "register_operand" "f,0")
7485 (match_operand:SF 2 "register_operand" "0,f")))]
7486 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7490 [(set_attr "type" "condmove")
7491 (set_attr "mode" "SF")])
7494 [(set (match_operand:DF 0 "register_operand" "=f,f")
7496 (match_operator 4 "equality_op"
7497 [(match_operand:SI 1 "register_operand" "d,d")
7499 (match_operand:DF 2 "register_operand" "f,0")
7500 (match_operand:DF 3 "register_operand" "0,f")))]
7501 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7505 [(set_attr "type" "condmove")
7506 (set_attr "mode" "DF")])
7509 [(set (match_operand:DF 0 "register_operand" "=f,f")
7511 (match_operator 4 "equality_op"
7512 [(match_operand:DI 1 "register_operand" "d,d")
7514 (match_operand:DF 2 "register_operand" "f,0")
7515 (match_operand:DF 3 "register_operand" "0,f")))]
7516 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7520 [(set_attr "type" "condmove")
7521 (set_attr "mode" "DF")])
7524 [(set (match_operand:DF 0 "register_operand" "=f,f")
7526 (match_operator 3 "equality_op" [(match_operand:CC 4
7530 (match_operand:DF 1 "register_operand" "f,0")
7531 (match_operand:DF 2 "register_operand" "0,f")))]
7532 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7536 [(set_attr "type" "condmove")
7537 (set_attr "mode" "DF")])
7539 ;; These are the main define_expand's used to make conditional moves.
7541 (define_expand "movsicc"
7542 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7543 (set (match_operand:SI 0 "register_operand")
7544 (if_then_else:SI (match_dup 5)
7545 (match_operand:SI 2 "reg_or_0_operand")
7546 (match_operand:SI 3 "reg_or_0_operand")))]
7547 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7549 gen_conditional_move (operands);
7553 (define_expand "movdicc"
7554 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7555 (set (match_operand:DI 0 "register_operand")
7556 (if_then_else:DI (match_dup 5)
7557 (match_operand:DI 2 "reg_or_0_operand")
7558 (match_operand:DI 3 "reg_or_0_operand")))]
7559 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7561 gen_conditional_move (operands);
7565 (define_expand "movsfcc"
7566 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7567 (set (match_operand:SF 0 "register_operand")
7568 (if_then_else:SF (match_dup 5)
7569 (match_operand:SF 2 "register_operand")
7570 (match_operand:SF 3 "register_operand")))]
7571 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7573 gen_conditional_move (operands);
7577 (define_expand "movdfcc"
7578 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7579 (set (match_operand:DF 0 "register_operand")
7580 (if_then_else:DF (match_dup 5)
7581 (match_operand:DF 2 "register_operand")
7582 (match_operand:DF 3 "register_operand")))]
7583 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7585 gen_conditional_move (operands);
7590 ;; ....................
7592 ;; mips16 inline constant tables
7594 ;; ....................
7597 (define_insn "consttable_int"
7598 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
7599 (match_operand 1 "const_int_operand" "")]
7600 UNSPEC_CONSTTABLE_INT)]
7603 assemble_integer (operands[0], INTVAL (operands[1]),
7604 BITS_PER_UNIT * INTVAL (operands[1]), 1);
7607 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
7609 (define_insn "consttable_float"
7610 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
7611 UNSPEC_CONSTTABLE_FLOAT)]
7616 if (GET_CODE (operands[0]) != CONST_DOUBLE)
7618 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7619 assemble_real (d, GET_MODE (operands[0]),
7620 GET_MODE_BITSIZE (GET_MODE (operands[0])));
7623 [(set (attr "length")
7624 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
7626 (define_insn "align"
7627 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
7630 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
7633 [(match_operand 0 "small_data_pattern")]
7636 { operands[0] = mips_rewrite_small_data (operands[0]); })