1 ;; Mips.md Machine Description for MIPS based processors
2 ;; Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 ;; Contributed by A. Lichnewsky, lich@inria.inria.fr
5 ;; Changes by Michael Meissner, meissner@osf.org
6 ;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
7 ;; Brendan Eich, brendan@microunity.com.
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING. If not, write to
23 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
27 [(UNSPEC_LOAD_DF_LOW 0)
28 (UNSPEC_LOAD_DF_HIGH 1)
29 (UNSPEC_STORE_DF_HIGH 2)
33 (UNSPEC_EH_RECEIVER 6)
35 (UNSPEC_CONSTTABLE_INT 8)
36 (UNSPEC_CONSTTABLE_FLOAT 9)
53 (UNSPEC_ADDRESS_FIRST 100)
55 (FAKE_CALL_REGNO 79)])
57 (include "predicates.md")
59 ;; ....................
63 ;; ....................
65 (define_attr "got" "unset,xgot_high,load"
66 (const_string "unset"))
68 ;; For jal instructions, this attribute is DIRECT when the target address
69 ;; is symbolic and INDIRECT when it is a register.
70 (define_attr "jal" "unset,direct,indirect"
71 (const_string "unset"))
73 ;; This attribute is YES if the instruction is a jal macro (not a
74 ;; real jal instruction).
76 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
77 ;; restore $gp. Direct jals are also macros in NewABI PIC since they
78 ;; load the target address into $25.
79 (define_attr "jal_macro" "no,yes"
80 (cond [(eq_attr "jal" "direct")
81 (symbol_ref "TARGET_ABICALLS != 0")
82 (eq_attr "jal" "indirect")
83 (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
86 ;; Classification of each insn.
87 ;; branch conditional branch
88 ;; jump unconditional jump
89 ;; call unconditional call
90 ;; load load instruction(s)
91 ;; fpload floating point load
92 ;; fpidxload floating point indexed load
93 ;; store store instruction(s)
94 ;; fpstore floating point store
95 ;; fpidxstore floating point indexed store
96 ;; prefetch memory prefetch (register + offset)
97 ;; prefetchx memory indexed prefetch (register + register)
98 ;; condmove conditional moves
99 ;; xfer transfer to/from coprocessor
100 ;; mthilo transfer to hi/lo registers
101 ;; mfhilo transfer from hi/lo registers
102 ;; const load constant
103 ;; arith integer arithmetic and logical instructions
104 ;; shift integer shift instructions
105 ;; slt set less than instructions
106 ;; clz the clz and clo instructions
107 ;; trap trap if instructions
108 ;; imul integer multiply
109 ;; imadd integer multiply-add
110 ;; idiv integer divide
111 ;; fmove floating point register move
112 ;; fadd floating point add/subtract
113 ;; fmul floating point multiply
114 ;; fmadd floating point multiply-add
115 ;; fdiv floating point divide
116 ;; fabs floating point absolute value
117 ;; fneg floating point negation
118 ;; fcmp floating point compare
119 ;; fcvt floating point convert
120 ;; fsqrt floating point square root
121 ;; frsqrt floating point reciprocal square root
122 ;; multi multiword sequence (or user asm statements)
125 "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"
126 (cond [(eq_attr "jal" "!unset") (const_string "call")
127 (eq_attr "got" "load") (const_string "load")]
128 (const_string "unknown")))
130 ;; Main data type used by the insn
131 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
132 (const_string "unknown"))
134 ;; Is this an extended instruction in mips16 mode?
135 (define_attr "extended_mips16" "no,yes"
138 ;; Length of instruction in bytes.
139 (define_attr "length" ""
140 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
141 ;; If a branch is outside this range, we have a choice of two
142 ;; sequences. For PIC, an out-of-range branch like:
147 ;; becomes the equivalent of:
156 ;; where the load address can be up to three instructions long
159 ;; The non-PIC case is similar except that we use a direct
160 ;; jump instead of an la/jr pair. Since the target of this
161 ;; jump is an absolute 28-bit bit address (the other bits
162 ;; coming from the address of the delay slot) this form cannot
163 ;; cross a 256MB boundary. We could provide the option of
164 ;; using la/jr in this case too, but we do not do so at
167 ;; Note that this value does not account for the delay slot
168 ;; instruction, whose length is added separately. If the RTL
169 ;; pattern has no explicit delay slot, mips_adjust_insn_length
170 ;; will add the length of the implicit nop. The values for
171 ;; forward and backward branches will be different as well.
172 (eq_attr "type" "branch")
173 (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
174 (le (minus (pc) (match_dup 1)) (const_int 131068)))
176 (ne (symbol_ref "flag_pic") (const_int 0))
180 (eq_attr "got" "load")
182 (eq_attr "got" "xgot_high")
185 (eq_attr "type" "const")
186 (symbol_ref "mips_const_insns (operands[1]) * 4")
187 (eq_attr "type" "load,fpload,fpidxload")
188 (symbol_ref "mips_fetch_insns (operands[1]) * 4")
189 (eq_attr "type" "store,fpstore,fpidxstore")
190 (symbol_ref "mips_fetch_insns (operands[0]) * 4")
192 ;; In the worst case, a call macro will take 8 instructions:
194 ;; lui $25,%call_hi(FOO)
196 ;; lw $25,%call_lo(FOO)($25)
202 (eq_attr "jal_macro" "yes")
205 (and (eq_attr "extended_mips16" "yes")
206 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
209 ;; Various VR4120 errata require a nop to be inserted after a macc
210 ;; instruction. The assembler does this for us, so account for
211 ;; the worst-case length here.
212 (and (eq_attr "type" "imadd")
213 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
216 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
217 ;; the result of the second one is missed. The assembler should work
218 ;; around this by inserting a nop after the first dmult.
219 (and (eq_attr "type" "imul")
220 (and (eq_attr "mode" "DI")
221 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
224 (eq_attr "type" "idiv")
225 (symbol_ref "mips_idiv_insns () * 4")
228 ;; Attribute describing the processor. This attribute must match exactly
229 ;; with the processor_type enumeration in mips.h.
231 "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
232 (const (symbol_ref "mips_tune")))
234 ;; The type of hardware hazard associated with this instruction.
235 ;; DELAY means that the next instruction cannot read the result
236 ;; of this one. HILO means that the next two instructions cannot
237 ;; write to HI or LO.
238 (define_attr "hazard" "none,delay,hilo"
239 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
240 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
241 (const_string "delay")
243 (and (eq_attr "type" "xfer")
244 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
245 (const_string "delay")
247 (and (eq_attr "type" "fcmp")
248 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
249 (const_string "delay")
251 ;; The r4000 multiplication patterns include an mflo instruction.
252 (and (eq_attr "type" "imul")
253 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
254 (const_string "hilo")
256 (and (eq_attr "type" "mfhilo")
257 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
258 (const_string "hilo")]
259 (const_string "none")))
261 ;; Is it a single instruction?
262 (define_attr "single_insn" "no,yes"
263 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
265 ;; Can the instruction be put into a delay slot?
266 (define_attr "can_delay" "no,yes"
267 (if_then_else (and (eq_attr "type" "!branch,call,jump")
268 (and (eq_attr "hazard" "none")
269 (eq_attr "single_insn" "yes")))
271 (const_string "no")))
273 ;; Attribute defining whether or not we can use the branch-likely instructions
274 (define_attr "branch_likely" "no,yes"
276 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
278 (const_string "no"))))
280 ;; True if an instruction might assign to hi or lo when reloaded.
281 ;; This is used by the TUNE_MACC_CHAINS code.
282 (define_attr "may_clobber_hilo" "no,yes"
283 (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
285 (const_string "no")))
287 ;; Describe a user's asm statement.
288 (define_asm_attributes
289 [(set_attr "type" "multi")])
291 ;; .........................
293 ;; Branch, call and jump delay slots
295 ;; .........................
297 (define_delay (and (eq_attr "type" "branch")
298 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
299 [(eq_attr "can_delay" "yes")
301 (and (eq_attr "branch_likely" "yes")
302 (eq_attr "can_delay" "yes"))])
304 (define_delay (eq_attr "type" "jump")
305 [(eq_attr "can_delay" "yes")
309 (define_delay (and (eq_attr "type" "call")
310 (eq_attr "jal_macro" "no"))
311 [(eq_attr "can_delay" "yes")
315 ;; Pipeline descriptions.
317 ;; generic.md provides a fallback for processors without a specific
318 ;; pipeline description. It is derived from the old define_function_unit
319 ;; version and uses the "alu" and "imuldiv" units declared below.
321 ;; Some of the processor-specific files are also derived from old
322 ;; define_function_unit descriptions and simply override the parts of
323 ;; generic.md that don't apply. The other processor-specific files
324 ;; are self-contained.
325 (define_automaton "alu,imuldiv")
327 (define_cpu_unit "alu" "alu")
328 (define_cpu_unit "imuldiv" "imuldiv")
344 (include "generic.md")
347 ;; ....................
351 ;; ....................
355 [(trap_if (const_int 1) (const_int 0))]
358 if (ISA_HAS_COND_TRAP)
360 /* The IRIX 6 O32 assembler requires the first break operand. */
361 else if (TARGET_MIPS16 || !TARGET_GAS)
366 [(set_attr "type" "trap")])
368 (define_expand "conditional_trap"
369 [(trap_if (match_operator 0 "comparison_operator"
370 [(match_dup 2) (match_dup 3)])
371 (match_operand 1 "const_int_operand"))]
374 if (operands[1] == const0_rtx)
376 mips_gen_conditional_trap (operands);
384 [(trap_if (match_operator 0 "trap_comparison_operator"
385 [(match_operand:SI 1 "reg_or_0_operand" "dJ")
386 (match_operand:SI 2 "arith_operand" "dI")])
390 [(set_attr "type" "trap")])
393 [(trap_if (match_operator 0 "trap_comparison_operator"
394 [(match_operand:DI 1 "reg_or_0_operand" "dJ")
395 (match_operand:DI 2 "arith_operand" "dI")])
397 "TARGET_64BIT && ISA_HAS_COND_TRAP"
399 [(set_attr "type" "trap")])
402 ;; ....................
406 ;; ....................
409 (define_insn "adddf3"
410 [(set (match_operand:DF 0 "register_operand" "=f")
411 (plus:DF (match_operand:DF 1 "register_operand" "f")
412 (match_operand:DF 2 "register_operand" "f")))]
413 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
415 [(set_attr "type" "fadd")
416 (set_attr "mode" "DF")])
418 (define_insn "addsf3"
419 [(set (match_operand:SF 0 "register_operand" "=f")
420 (plus:SF (match_operand:SF 1 "register_operand" "f")
421 (match_operand:SF 2 "register_operand" "f")))]
424 [(set_attr "type" "fadd")
425 (set_attr "mode" "SF")])
427 (define_expand "addsi3"
428 [(set (match_operand:SI 0 "register_operand")
429 (plus:SI (match_operand:SI 1 "reg_or_0_operand")
430 (match_operand:SI 2 "arith_operand")))]
433 (define_insn "addsi3_internal"
434 [(set (match_operand:SI 0 "register_operand" "=d,d")
435 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
436 (match_operand:SI 2 "arith_operand" "d,Q")))]
441 [(set_attr "type" "arith")
442 (set_attr "mode" "SI")])
444 ;; For the mips16, we need to recognize stack pointer additions
445 ;; explicitly, since we don't have a constraint for $sp. These insns
446 ;; will be generated by the save_restore_insns functions.
451 (match_operand:SI 0 "const_arith_operand" "")))]
454 [(set_attr "type" "arith")
455 (set_attr "mode" "SI")
456 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
461 [(set (match_operand:SI 0 "register_operand" "=d")
463 (match_operand:SI 1 "const_arith_operand" "")))]
466 [(set_attr "type" "arith")
467 (set_attr "mode" "SI")
468 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4")
473 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
474 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
475 (match_operand:SI 2 "arith_operand" "Q,O,d")))]
478 if (REGNO (operands[0]) == REGNO (operands[1]))
479 return "addu\t%0,%2";
481 return "addu\t%0,%1,%2";
483 [(set_attr "type" "arith")
484 (set_attr "mode" "SI")
485 (set_attr_alternative "length"
486 [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
489 (if_then_else (match_operand:VOID 2 "m16_simm4_1")
495 ;; On the mips16, we can sometimes split an add of a constant which is
496 ;; a 4 byte instruction into two adds which are both 2 byte
497 ;; instructions. There are two cases: one where we are adding a
498 ;; constant plus a register to another register, and one where we are
499 ;; simply adding a constant to a register.
502 [(set (match_operand:SI 0 "register_operand")
503 (plus:SI (match_dup 0)
504 (match_operand:SI 1 "const_int_operand")))]
505 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
506 && GET_CODE (operands[0]) == REG
507 && M16_REG_P (REGNO (operands[0]))
508 && GET_CODE (operands[1]) == CONST_INT
509 && ((INTVAL (operands[1]) > 0x7f
510 && INTVAL (operands[1]) <= 0x7f + 0x7f)
511 || (INTVAL (operands[1]) < - 0x80
512 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
513 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
514 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
516 HOST_WIDE_INT val = INTVAL (operands[1]);
520 operands[1] = GEN_INT (0x7f);
521 operands[2] = GEN_INT (val - 0x7f);
525 operands[1] = GEN_INT (- 0x80);
526 operands[2] = GEN_INT (val + 0x80);
531 [(set (match_operand:SI 0 "register_operand")
532 (plus:SI (match_operand:SI 1 "register_operand")
533 (match_operand:SI 2 "const_int_operand")))]
534 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
535 && GET_CODE (operands[0]) == REG
536 && M16_REG_P (REGNO (operands[0]))
537 && GET_CODE (operands[1]) == REG
538 && M16_REG_P (REGNO (operands[1]))
539 && REGNO (operands[0]) != REGNO (operands[1])
540 && GET_CODE (operands[2]) == CONST_INT
541 && ((INTVAL (operands[2]) > 0x7
542 && INTVAL (operands[2]) <= 0x7 + 0x7f)
543 || (INTVAL (operands[2]) < - 0x8
544 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
545 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
546 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
548 HOST_WIDE_INT val = INTVAL (operands[2]);
552 operands[2] = GEN_INT (0x7);
553 operands[3] = GEN_INT (val - 0x7);
557 operands[2] = GEN_INT (- 0x8);
558 operands[3] = GEN_INT (val + 0x8);
562 (define_expand "adddi3"
563 [(set (match_operand:DI 0 "register_operand")
564 (plus:DI (match_operand:DI 1 "register_operand")
565 (match_operand:DI 2 "arith_operand")))]
568 (define_insn "adddi3_internal"
569 [(set (match_operand:DI 0 "register_operand" "=d,d")
570 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")
571 (match_operand:DI 2 "arith_operand" "d,Q")))]
572 "TARGET_64BIT && !TARGET_MIPS16"
576 [(set_attr "type" "arith")
577 (set_attr "mode" "DI")])
579 ;; For the mips16, we need to recognize stack pointer additions
580 ;; explicitly, since we don't have a constraint for $sp. These insns
581 ;; will be generated by the save_restore_insns functions.
586 (match_operand:DI 0 "const_arith_operand" "")))]
587 "TARGET_MIPS16 && TARGET_64BIT"
589 [(set_attr "type" "arith")
590 (set_attr "mode" "DI")
591 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
596 [(set (match_operand:DI 0 "register_operand" "=d")
598 (match_operand:DI 1 "const_arith_operand" "")))]
599 "TARGET_MIPS16 && TARGET_64BIT"
601 [(set_attr "type" "arith")
602 (set_attr "mode" "DI")
603 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4")
608 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
609 (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
610 (match_operand:DI 2 "arith_operand" "Q,O,d")))]
611 "TARGET_MIPS16 && TARGET_64BIT"
613 if (REGNO (operands[0]) == REGNO (operands[1]))
614 return "daddu\t%0,%2";
616 return "daddu\t%0,%1,%2";
618 [(set_attr "type" "arith")
619 (set_attr "mode" "DI")
620 (set_attr_alternative "length"
621 [(if_then_else (match_operand:VOID 2 "m16_simm5_1")
624 (if_then_else (match_operand:VOID 2 "m16_simm4_1")
630 ;; On the mips16, we can sometimes split an add of a constant which is
631 ;; a 4 byte instruction into two adds which are both 2 byte
632 ;; instructions. There are two cases: one where we are adding a
633 ;; constant plus a register to another register, and one where we are
634 ;; simply adding a constant to a register.
637 [(set (match_operand:DI 0 "register_operand")
638 (plus:DI (match_dup 0)
639 (match_operand:DI 1 "const_int_operand")))]
640 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
641 && GET_CODE (operands[0]) == REG
642 && M16_REG_P (REGNO (operands[0]))
643 && GET_CODE (operands[1]) == CONST_INT
644 && ((INTVAL (operands[1]) > 0xf
645 && INTVAL (operands[1]) <= 0xf + 0xf)
646 || (INTVAL (operands[1]) < - 0x10
647 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
648 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
649 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
651 HOST_WIDE_INT val = INTVAL (operands[1]);
655 operands[1] = GEN_INT (0xf);
656 operands[2] = GEN_INT (val - 0xf);
660 operands[1] = GEN_INT (- 0x10);
661 operands[2] = GEN_INT (val + 0x10);
666 [(set (match_operand:DI 0 "register_operand")
667 (plus:DI (match_operand:DI 1 "register_operand")
668 (match_operand:DI 2 "const_int_operand")))]
669 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
670 && GET_CODE (operands[0]) == REG
671 && M16_REG_P (REGNO (operands[0]))
672 && GET_CODE (operands[1]) == REG
673 && M16_REG_P (REGNO (operands[1]))
674 && REGNO (operands[0]) != REGNO (operands[1])
675 && GET_CODE (operands[2]) == CONST_INT
676 && ((INTVAL (operands[2]) > 0x7
677 && INTVAL (operands[2]) <= 0x7 + 0xf)
678 || (INTVAL (operands[2]) < - 0x8
679 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
680 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
681 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
683 HOST_WIDE_INT val = INTVAL (operands[2]);
687 operands[2] = GEN_INT (0x7);
688 operands[3] = GEN_INT (val - 0x7);
692 operands[2] = GEN_INT (- 0x8);
693 operands[3] = GEN_INT (val + 0x8);
697 (define_insn "addsi3_internal_2"
698 [(set (match_operand:DI 0 "register_operand" "=d,d")
699 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
700 (match_operand:SI 2 "arith_operand" "d,Q"))))]
701 "TARGET_64BIT && !TARGET_MIPS16"
705 [(set_attr "type" "arith")
706 (set_attr "mode" "SI")])
709 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
710 (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
711 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
712 "TARGET_MIPS16 && TARGET_64BIT"
714 if (REGNO (operands[0]) == REGNO (operands[1]))
715 return "addu\t%0,%2";
717 return "addu\t%0,%1,%2";
719 [(set_attr "type" "arith")
720 (set_attr "mode" "SI")
721 (set_attr_alternative "length"
722 [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
725 (if_then_else (match_operand:VOID 2 "m16_simm4_1")
731 ;; ....................
735 ;; ....................
738 (define_insn "subdf3"
739 [(set (match_operand:DF 0 "register_operand" "=f")
740 (minus:DF (match_operand:DF 1 "register_operand" "f")
741 (match_operand:DF 2 "register_operand" "f")))]
742 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
744 [(set_attr "type" "fadd")
745 (set_attr "mode" "DF")])
747 (define_insn "subsf3"
748 [(set (match_operand:SF 0 "register_operand" "=f")
749 (minus:SF (match_operand:SF 1 "register_operand" "f")
750 (match_operand:SF 2 "register_operand" "f")))]
753 [(set_attr "type" "fadd")
754 (set_attr "mode" "SF")])
756 (define_expand "subsi3"
757 [(set (match_operand:SI 0 "register_operand")
758 (minus:SI (match_operand:SI 1 "register_operand")
759 (match_operand:SI 2 "register_operand")))]
763 (define_insn "subsi3_internal"
764 [(set (match_operand:SI 0 "register_operand" "=d")
765 (minus:SI (match_operand:SI 1 "register_operand" "d")
766 (match_operand:SI 2 "register_operand" "d")))]
769 [(set_attr "type" "arith")
770 (set_attr "mode" "SI")])
772 (define_insn "subdi3"
773 [(set (match_operand:DI 0 "register_operand" "=d")
774 (minus:DI (match_operand:DI 1 "register_operand" "d")
775 (match_operand:DI 2 "register_operand" "d")))]
778 [(set_attr "type" "arith")
779 (set_attr "mode" "DI")])
781 (define_insn "subsi3_internal_2"
782 [(set (match_operand:DI 0 "register_operand" "=d")
784 (minus:SI (match_operand:SI 1 "register_operand" "d")
785 (match_operand:SI 2 "register_operand" "d"))))]
788 [(set_attr "type" "arith")
789 (set_attr "mode" "DI")])
792 ;; ....................
796 ;; ....................
799 (define_expand "muldf3"
800 [(set (match_operand:DF 0 "register_operand")
801 (mult:DF (match_operand:DF 1 "register_operand")
802 (match_operand:DF 2 "register_operand")))]
803 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
806 (define_insn "muldf3_internal"
807 [(set (match_operand:DF 0 "register_operand" "=f")
808 (mult:DF (match_operand:DF 1 "register_operand" "f")
809 (match_operand:DF 2 "register_operand" "f")))]
810 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
812 [(set_attr "type" "fmul")
813 (set_attr "mode" "DF")])
815 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
816 ;; operands may corrupt immediately following multiplies. This is a
817 ;; simple fix to insert NOPs.
819 (define_insn "muldf3_r4300"
820 [(set (match_operand:DF 0 "register_operand" "=f")
821 (mult:DF (match_operand:DF 1 "register_operand" "f")
822 (match_operand:DF 2 "register_operand" "f")))]
823 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
824 "mul.d\t%0,%1,%2\;nop"
825 [(set_attr "type" "fmul")
826 (set_attr "mode" "DF")
827 (set_attr "length" "8")])
829 (define_expand "mulsf3"
830 [(set (match_operand:SF 0 "register_operand")
831 (mult:SF (match_operand:SF 1 "register_operand")
832 (match_operand:SF 2 "register_operand")))]
836 (define_insn "mulsf3_internal"
837 [(set (match_operand:SF 0 "register_operand" "=f")
838 (mult:SF (match_operand:SF 1 "register_operand" "f")
839 (match_operand:SF 2 "register_operand" "f")))]
840 "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
842 [(set_attr "type" "fmul")
843 (set_attr "mode" "SF")])
847 (define_insn "mulsf3_r4300"
848 [(set (match_operand:SF 0 "register_operand" "=f")
849 (mult:SF (match_operand:SF 1 "register_operand" "f")
850 (match_operand:SF 2 "register_operand" "f")))]
851 "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
852 "mul.s\t%0,%1,%2\;nop"
853 [(set_attr "type" "fmul")
854 (set_attr "mode" "SF")
855 (set_attr "length" "8")])
858 ;; The original R4000 has a cpu bug. If a double-word or a variable
859 ;; shift executes while an integer multiplication is in progress, the
860 ;; shift may give an incorrect result. Avoid this by keeping the mflo
861 ;; with the mult on the R4000.
863 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
864 ;; (also valid for MIPS R4000MC processors):
866 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
867 ;; this errata description.
868 ;; The following code sequence causes the R4000 to incorrectly
869 ;; execute the Double Shift Right Arithmetic 32 (dsra32)
870 ;; instruction. If the dsra32 instruction is executed during an
871 ;; integer multiply, the dsra32 will only shift by the amount in
872 ;; specified in the instruction rather than the amount plus 32
874 ;; instruction 1: mult rs,rt integer multiply
875 ;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
876 ;; right arithmetic + 32
877 ;; Workaround: A dsra32 instruction placed after an integer
878 ;; multiply should not be one of the 11 instructions after the
879 ;; multiply instruction."
883 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
884 ;; the following description.
885 ;; All extended shifts (shift by n+32) and variable shifts (32 and
886 ;; 64-bit versions) may produce incorrect results under the
887 ;; following conditions:
888 ;; 1) An integer multiply is currently executing
889 ;; 2) These types of shift instructions are executed immediately
890 ;; following an integer divide instruction.
892 ;; 1) Make sure no integer multiply is running wihen these
893 ;; instruction are executed. If this cannot be predicted at
894 ;; compile time, then insert a "mfhi" to R0 instruction
895 ;; immediately after the integer multiply instruction. This
896 ;; will cause the integer multiply to complete before the shift
898 ;; 2) Separate integer divide and these two classes of shift
899 ;; instructions by another instruction or a noop."
901 ;; These processors have PRId values of 0x00004220 and 0x00004300,
904 (define_expand "mulsi3"
905 [(set (match_operand:SI 0 "register_operand")
906 (mult:SI (match_operand:SI 1 "register_operand")
907 (match_operand:SI 2 "register_operand")))]
910 if (GENERATE_MULT3_SI || TARGET_MAD)
911 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
912 else if (!TARGET_FIX_R4000)
913 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
915 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
919 (define_insn "mulsi3_mult3"
920 [(set (match_operand:SI 0 "register_operand" "=d,l")
921 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
922 (match_operand:SI 2 "register_operand" "d,d")))
923 (clobber (match_scratch:SI 3 "=h,h"))
924 (clobber (match_scratch:SI 4 "=l,X"))]
928 if (which_alternative == 1)
929 return "mult\t%1,%2";
938 return "mul\t%0,%1,%2";
939 return "mult\t%0,%1,%2";
941 [(set_attr "type" "imul")
942 (set_attr "mode" "SI")])
944 ;; If a register gets allocated to LO, and we spill to memory, the reload
945 ;; will include a move from LO to a GPR. Merge it into the multiplication
946 ;; if it can set the GPR directly.
949 ;; Operand 1: GPR (1st multiplication operand)
950 ;; Operand 2: GPR (2nd multiplication operand)
952 ;; Operand 4: GPR (destination)
955 [(set (match_operand:SI 0 "register_operand")
956 (mult:SI (match_operand:SI 1 "register_operand")
957 (match_operand:SI 2 "register_operand")))
958 (clobber (match_operand:SI 3 "register_operand"))
959 (clobber (scratch:SI))])
960 (set (match_operand:SI 4 "register_operand")
961 (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
962 "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
965 (mult:SI (match_dup 1)
967 (clobber (match_dup 3))
968 (clobber (match_dup 0))])])
970 (define_insn "mulsi3_internal"
971 [(set (match_operand:SI 0 "register_operand" "=l")
972 (mult:SI (match_operand:SI 1 "register_operand" "d")
973 (match_operand:SI 2 "register_operand" "d")))
974 (clobber (match_scratch:SI 3 "=h"))]
977 [(set_attr "type" "imul")
978 (set_attr "mode" "SI")])
980 (define_insn "mulsi3_r4000"
981 [(set (match_operand:SI 0 "register_operand" "=d")
982 (mult:SI (match_operand:SI 1 "register_operand" "d")
983 (match_operand:SI 2 "register_operand" "d")))
984 (clobber (match_scratch:SI 3 "=h"))
985 (clobber (match_scratch:SI 4 "=l"))]
987 "mult\t%1,%2\;mflo\t%0"
988 [(set_attr "type" "imul")
989 (set_attr "mode" "SI")
990 (set_attr "length" "8")])
992 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
993 ;; of "mult; mflo". They have the same latency, but the first form gives
994 ;; us an extra cycle to compute the operands.
997 ;; Operand 1: GPR (1st multiplication operand)
998 ;; Operand 2: GPR (2nd multiplication operand)
1000 ;; Operand 4: GPR (destination)
1003 [(set (match_operand:SI 0 "register_operand")
1004 (mult:SI (match_operand:SI 1 "register_operand")
1005 (match_operand:SI 2 "register_operand")))
1006 (clobber (match_operand:SI 3 "register_operand"))])
1007 (set (match_operand:SI 4 "register_operand")
1008 (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1009 "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1014 (plus:SI (mult:SI (match_dup 1)
1018 (plus:SI (mult:SI (match_dup 1)
1021 (clobber (match_dup 3))])])
1023 ;; Multiply-accumulate patterns
1025 ;; For processors that can copy the output to a general register:
1027 ;; The all-d alternative is needed because the combiner will find this
1028 ;; pattern and then register alloc/reload will move registers around to
1029 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1031 ;; The last alternative should be made slightly less desirable, but adding
1032 ;; "?" to the constraint is too strong, and causes values to be loaded into
1033 ;; LO even when that's more costly. For now, using "*d" mostly does the
1035 (define_insn "*mul_acc_si"
1036 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1037 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1038 (match_operand:SI 2 "register_operand" "d,d,d"))
1039 (match_operand:SI 3 "register_operand" "0,l,*d")))
1040 (clobber (match_scratch:SI 4 "=h,h,h"))
1041 (clobber (match_scratch:SI 5 "=X,3,l"))
1042 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1044 || ISA_HAS_MADD_MSUB)
1047 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1048 if (which_alternative == 2)
1050 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1052 return madd[which_alternative];
1054 [(set_attr "type" "imadd,imadd,multi")
1055 (set_attr "mode" "SI")
1056 (set_attr "length" "4,4,8")])
1058 ;; Split the above insn if we failed to get LO allocated.
1060 [(set (match_operand:SI 0 "register_operand")
1061 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1062 (match_operand:SI 2 "register_operand"))
1063 (match_operand:SI 3 "register_operand")))
1064 (clobber (match_scratch:SI 4))
1065 (clobber (match_scratch:SI 5))
1066 (clobber (match_scratch:SI 6))]
1067 "reload_completed && !TARGET_DEBUG_D_MODE
1068 && GP_REG_P (true_regnum (operands[0]))
1069 && GP_REG_P (true_regnum (operands[3]))"
1070 [(parallel [(set (match_dup 6)
1071 (mult:SI (match_dup 1) (match_dup 2)))
1072 (clobber (match_dup 4))
1073 (clobber (match_dup 5))])
1074 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1077 ;; Splitter to copy result of MADD to a general register
1079 [(set (match_operand:SI 0 "register_operand")
1080 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1081 (match_operand:SI 2 "register_operand"))
1082 (match_operand:SI 3 "register_operand")))
1083 (clobber (match_scratch:SI 4))
1084 (clobber (match_scratch:SI 5))
1085 (clobber (match_scratch:SI 6))]
1086 "reload_completed && !TARGET_DEBUG_D_MODE
1087 && GP_REG_P (true_regnum (operands[0]))
1088 && true_regnum (operands[3]) == LO_REGNUM"
1089 [(parallel [(set (match_dup 3)
1090 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1092 (clobber (match_dup 4))
1093 (clobber (match_dup 5))
1094 (clobber (match_dup 6))])
1095 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1098 (define_insn "*macc"
1099 [(set (match_operand:SI 0 "register_operand" "=l,d")
1100 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1101 (match_operand:SI 2 "register_operand" "d,d"))
1102 (match_operand:SI 3 "register_operand" "0,l")))
1103 (clobber (match_scratch:SI 4 "=h,h"))
1104 (clobber (match_scratch:SI 5 "=X,3"))]
1107 if (which_alternative == 1)
1108 return "macc\t%0,%1,%2";
1109 else if (TARGET_MIPS5500)
1110 return "madd\t%1,%2";
1112 /* The VR4130 assumes that there is a two-cycle latency between a macc
1113 that "writes" to $0 and an instruction that reads from it. We avoid
1114 this by assigning to $1 instead. */
1115 return "%[macc\t%@,%1,%2%]";
1117 [(set_attr "type" "imadd")
1118 (set_attr "mode" "SI")])
1120 (define_insn "*msac"
1121 [(set (match_operand:SI 0 "register_operand" "=l,d")
1122 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1123 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1124 (match_operand:SI 3 "register_operand" "d,d"))))
1125 (clobber (match_scratch:SI 4 "=h,h"))
1126 (clobber (match_scratch:SI 5 "=X,1"))]
1129 if (which_alternative == 1)
1130 return "msac\t%0,%2,%3";
1131 else if (TARGET_MIPS5500)
1132 return "msub\t%2,%3";
1134 return "msac\t$0,%2,%3";
1136 [(set_attr "type" "imadd")
1137 (set_attr "mode" "SI")])
1139 ;; An msac-like instruction implemented using negation and a macc.
1140 (define_insn_and_split "*msac_using_macc"
1141 [(set (match_operand:SI 0 "register_operand" "=l,d")
1142 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1143 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1144 (match_operand:SI 3 "register_operand" "d,d"))))
1145 (clobber (match_scratch:SI 4 "=h,h"))
1146 (clobber (match_scratch:SI 5 "=X,1"))
1147 (clobber (match_scratch:SI 6 "=d,d"))]
1148 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1150 "&& reload_completed"
1152 (neg:SI (match_dup 3)))
1155 (plus:SI (mult:SI (match_dup 2)
1158 (clobber (match_dup 4))
1159 (clobber (match_dup 5))])]
1161 [(set_attr "type" "imadd")
1162 (set_attr "length" "8")])
1164 ;; Patterns generated by the define_peephole2 below.
1166 (define_insn "*macc2"
1167 [(set (match_operand:SI 0 "register_operand" "=l")
1168 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1169 (match_operand:SI 2 "register_operand" "d"))
1171 (set (match_operand:SI 3 "register_operand" "=d")
1172 (plus:SI (mult:SI (match_dup 1)
1175 (clobber (match_scratch:SI 4 "=h"))]
1176 "ISA_HAS_MACC && reload_completed"
1178 [(set_attr "type" "imadd")
1179 (set_attr "mode" "SI")])
1181 (define_insn "*msac2"
1182 [(set (match_operand:SI 0 "register_operand" "=l")
1183 (minus:SI (match_dup 0)
1184 (mult:SI (match_operand:SI 1 "register_operand" "d")
1185 (match_operand:SI 2 "register_operand" "d"))))
1186 (set (match_operand:SI 3 "register_operand" "=d")
1187 (minus:SI (match_dup 0)
1188 (mult:SI (match_dup 1)
1190 (clobber (match_scratch:SI 4 "=h"))]
1191 "ISA_HAS_MSAC && reload_completed"
1193 [(set_attr "type" "imadd")
1194 (set_attr "mode" "SI")])
1196 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1200 ;; Operand 1: macc/msac
1202 ;; Operand 3: GPR (destination)
1205 [(set (match_operand:SI 0 "register_operand")
1206 (match_operand:SI 1 "macc_msac_operand"))
1207 (clobber (match_operand:SI 2 "register_operand"))
1208 (clobber (scratch:SI))])
1209 (set (match_operand:SI 3 "register_operand")
1210 (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1212 [(parallel [(set (match_dup 0)
1216 (clobber (match_dup 2))])]
1219 ;; When we have a three-address multiplication instruction, it should
1220 ;; be faster to do a separate multiply and add, rather than moving
1221 ;; something into LO in order to use a macc instruction.
1223 ;; This peephole needs a scratch register to cater for the case when one
1224 ;; of the multiplication operands is the same as the destination.
1226 ;; Operand 0: GPR (scratch)
1228 ;; Operand 2: GPR (addend)
1229 ;; Operand 3: GPR (destination)
1230 ;; Operand 4: macc/msac
1232 ;; Operand 6: new multiplication
1233 ;; Operand 7: new addition/subtraction
1235 [(match_scratch:SI 0 "d")
1236 (set (match_operand:SI 1 "register_operand")
1237 (match_operand:SI 2 "register_operand"))
1240 [(set (match_operand:SI 3 "register_operand")
1241 (match_operand:SI 4 "macc_msac_operand"))
1242 (clobber (match_operand:SI 5 "register_operand"))
1243 (clobber (match_dup 1))])]
1245 && true_regnum (operands[1]) == LO_REGNUM
1246 && peep2_reg_dead_p (2, operands[1])
1247 && GP_REG_P (true_regnum (operands[3]))"
1248 [(parallel [(set (match_dup 0)
1250 (clobber (match_dup 5))
1251 (clobber (match_dup 1))])
1255 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1256 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1257 operands[2], operands[0]);
1260 ;; Same as above, except LO is the initial target of the macc.
1262 ;; Operand 0: GPR (scratch)
1264 ;; Operand 2: GPR (addend)
1265 ;; Operand 3: macc/msac
1267 ;; Operand 5: GPR (destination)
1268 ;; Operand 6: new multiplication
1269 ;; Operand 7: new addition/subtraction
1271 [(match_scratch:SI 0 "d")
1272 (set (match_operand:SI 1 "register_operand")
1273 (match_operand:SI 2 "register_operand"))
1277 (match_operand:SI 3 "macc_msac_operand"))
1278 (clobber (match_operand:SI 4 "register_operand"))
1279 (clobber (scratch:SI))])
1281 (set (match_operand:SI 5 "register_operand")
1282 (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1283 "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1284 [(parallel [(set (match_dup 0)
1286 (clobber (match_dup 4))
1287 (clobber (match_dup 1))])
1291 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1292 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1293 operands[2], operands[0]);
1296 (define_insn "*mul_sub_si"
1297 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1298 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1299 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1300 (match_operand:SI 3 "register_operand" "d,d,d"))))
1301 (clobber (match_scratch:SI 4 "=h,h,h"))
1302 (clobber (match_scratch:SI 5 "=X,1,l"))
1303 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1309 [(set_attr "type" "imadd,multi,multi")
1310 (set_attr "mode" "SI")
1311 (set_attr "length" "4,8,8")])
1313 ;; Split the above insn if we failed to get LO allocated.
1315 [(set (match_operand:SI 0 "register_operand")
1316 (minus:SI (match_operand:SI 1 "register_operand")
1317 (mult:SI (match_operand:SI 2 "register_operand")
1318 (match_operand:SI 3 "register_operand"))))
1319 (clobber (match_scratch:SI 4))
1320 (clobber (match_scratch:SI 5))
1321 (clobber (match_scratch:SI 6))]
1322 "reload_completed && !TARGET_DEBUG_D_MODE
1323 && GP_REG_P (true_regnum (operands[0]))
1324 && GP_REG_P (true_regnum (operands[1]))"
1325 [(parallel [(set (match_dup 6)
1326 (mult:SI (match_dup 2) (match_dup 3)))
1327 (clobber (match_dup 4))
1328 (clobber (match_dup 5))])
1329 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1332 ;; Splitter to copy result of MSUB to a general register
1334 [(set (match_operand:SI 0 "register_operand")
1335 (minus:SI (match_operand:SI 1 "register_operand")
1336 (mult:SI (match_operand:SI 2 "register_operand")
1337 (match_operand:SI 3 "register_operand"))))
1338 (clobber (match_scratch:SI 4))
1339 (clobber (match_scratch:SI 5))
1340 (clobber (match_scratch:SI 6))]
1341 "reload_completed && !TARGET_DEBUG_D_MODE
1342 && GP_REG_P (true_regnum (operands[0]))
1343 && true_regnum (operands[1]) == LO_REGNUM"
1344 [(parallel [(set (match_dup 1)
1345 (minus:SI (match_dup 1)
1346 (mult:SI (match_dup 2) (match_dup 3))))
1347 (clobber (match_dup 4))
1348 (clobber (match_dup 5))
1349 (clobber (match_dup 6))])
1350 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1353 (define_insn "*muls"
1354 [(set (match_operand:SI 0 "register_operand" "=l,d")
1355 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1356 (match_operand:SI 2 "register_operand" "d,d"))))
1357 (clobber (match_scratch:SI 3 "=h,h"))
1358 (clobber (match_scratch:SI 4 "=X,l"))]
1363 [(set_attr "type" "imul")
1364 (set_attr "mode" "SI")])
1366 (define_expand "muldi3"
1367 [(set (match_operand:DI 0 "register_operand")
1368 (mult:DI (match_operand:DI 1 "register_operand")
1369 (match_operand:DI 2 "register_operand")))]
1372 if (GENERATE_MULT3_DI)
1373 emit_insn (gen_muldi3_mult3 (operands[0], operands[1], operands[2]));
1374 else if (!TARGET_FIX_R4000)
1375 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1377 emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
1381 (define_insn "muldi3_mult3"
1382 [(set (match_operand:DI 0 "register_operand" "=d")
1383 (mult:DI (match_operand:DI 1 "register_operand" "d")
1384 (match_operand:DI 2 "register_operand" "d")))
1385 (clobber (match_scratch:DI 3 "=h"))
1386 (clobber (match_scratch:DI 4 "=l"))]
1387 "TARGET_64BIT && GENERATE_MULT3_DI"
1389 [(set_attr "type" "imul")
1390 (set_attr "mode" "DI")])
1392 (define_insn "muldi3_internal"
1393 [(set (match_operand:DI 0 "register_operand" "=l")
1394 (mult:DI (match_operand:DI 1 "register_operand" "d")
1395 (match_operand:DI 2 "register_operand" "d")))
1396 (clobber (match_scratch:DI 3 "=h"))]
1397 "TARGET_64BIT && !TARGET_FIX_R4000"
1399 [(set_attr "type" "imul")
1400 (set_attr "mode" "DI")])
1402 (define_insn "muldi3_r4000"
1403 [(set (match_operand:DI 0 "register_operand" "=d")
1404 (mult:DI (match_operand:DI 1 "register_operand" "d")
1405 (match_operand:DI 2 "register_operand" "d")))
1406 (clobber (match_scratch:DI 3 "=h"))
1407 (clobber (match_scratch:DI 4 "=l"))]
1408 "TARGET_64BIT && TARGET_FIX_R4000"
1409 "dmult\t%1,%2\;mflo\t%0"
1410 [(set_attr "type" "imul")
1411 (set_attr "mode" "DI")
1412 (set_attr "length" "8")])
1414 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1416 (define_expand "mulsidi3"
1418 [(set (match_operand:DI 0 "register_operand")
1420 (sign_extend:DI (match_operand:SI 1 "register_operand"))
1421 (sign_extend:DI (match_operand:SI 2 "register_operand"))))
1422 (clobber (scratch:DI))
1423 (clobber (scratch:DI))
1424 (clobber (scratch:DI))])]
1425 "!TARGET_64BIT || !TARGET_FIX_R4000"
1429 if (!TARGET_FIX_R4000)
1430 emit_insn (gen_mulsidi3_32bit_internal (operands[0], operands[1],
1433 emit_insn (gen_mulsidi3_32bit_r4000 (operands[0], operands[1],
1439 (define_insn "mulsidi3_32bit_internal"
1440 [(set (match_operand:DI 0 "register_operand" "=x")
1442 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1443 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1444 "!TARGET_64BIT && !TARGET_FIX_R4000"
1446 [(set_attr "type" "imul")
1447 (set_attr "mode" "SI")])
1449 (define_insn "mulsidi3_32bit_r4000"
1450 [(set (match_operand:DI 0 "register_operand" "=d")
1452 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1453 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1454 (clobber (match_scratch:DI 3 "=x"))]
1455 "!TARGET_64BIT && TARGET_FIX_R4000"
1456 "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1457 [(set_attr "type" "imul")
1458 (set_attr "mode" "SI")
1459 (set_attr "length" "12")])
1461 (define_insn_and_split "*mulsidi3_64bit"
1462 [(set (match_operand:DI 0 "register_operand" "=d")
1463 (mult:DI (match_operator:DI 1 "extend_operator"
1464 [(match_operand:SI 3 "register_operand" "d")])
1465 (match_operator:DI 2 "extend_operator"
1466 [(match_operand:SI 4 "register_operand" "d")])))
1467 (clobber (match_scratch:DI 5 "=l"))
1468 (clobber (match_scratch:DI 6 "=h"))
1469 (clobber (match_scratch:DI 7 "=d"))]
1470 "TARGET_64BIT && !TARGET_FIX_R4000
1471 && GET_CODE (operands[1]) == GET_CODE (operands[2])"
1473 "&& reload_completed"
1477 (mult:SI (match_dup 3)
1481 (mult:DI (match_dup 1)
1485 ;; OP7 <- LO, OP0 <- HI
1486 (set (match_dup 7) (unspec:DI [(match_dup 5) (match_dup 6)] UNSPEC_MFHILO))
1487 (set (match_dup 0) (unspec:DI [(match_dup 6) (match_dup 5)] UNSPEC_MFHILO))
1491 (ashift:DI (match_dup 7)
1494 (lshiftrt:DI (match_dup 7)
1497 ;; Shift OP0 into place.
1499 (ashift:DI (match_dup 0)
1502 ;; OR the two halves together
1504 (ior:DI (match_dup 0)
1507 [(set_attr "type" "imul")
1508 (set_attr "mode" "SI")
1509 (set_attr "length" "24")])
1511 (define_insn "*mulsidi3_64bit_parts"
1512 [(set (match_operand:DI 0 "register_operand" "=l")
1514 (mult:SI (match_operand:SI 2 "register_operand" "d")
1515 (match_operand:SI 3 "register_operand" "d"))))
1516 (set (match_operand:DI 1 "register_operand" "=h")
1519 (match_operator:DI 4 "extend_operator" [(match_dup 2)])
1520 (match_operator:DI 5 "extend_operator" [(match_dup 3)]))
1522 "TARGET_64BIT && !TARGET_FIX_R4000
1523 && GET_CODE (operands[4]) == GET_CODE (operands[5])"
1525 if (GET_CODE (operands[4]) == SIGN_EXTEND)
1526 return "mult\t%2,%3";
1528 return "multu\t%2,%3";
1530 [(set_attr "type" "imul")
1531 (set_attr "mode" "SI")])
1533 (define_expand "umulsidi3"
1535 [(set (match_operand:DI 0 "register_operand")
1537 (zero_extend:DI (match_operand:SI 1 "register_operand"))
1538 (zero_extend:DI (match_operand:SI 2 "register_operand"))))
1539 (clobber (scratch:DI))
1540 (clobber (scratch:DI))
1541 (clobber (scratch:DI))])]
1542 "!TARGET_64BIT || !TARGET_FIX_R4000"
1546 if (!TARGET_FIX_R4000)
1547 emit_insn (gen_umulsidi3_32bit_internal (operands[0], operands[1],
1550 emit_insn (gen_umulsidi3_32bit_r4000 (operands[0], operands[1],
1556 (define_insn "umulsidi3_32bit_internal"
1557 [(set (match_operand:DI 0 "register_operand" "=x")
1559 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1560 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1561 "!TARGET_64BIT && !TARGET_FIX_R4000"
1563 [(set_attr "type" "imul")
1564 (set_attr "mode" "SI")])
1566 (define_insn "umulsidi3_32bit_r4000"
1567 [(set (match_operand:DI 0 "register_operand" "=d")
1569 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1570 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1571 (clobber (match_scratch:DI 3 "=x"))]
1572 "!TARGET_64BIT && TARGET_FIX_R4000"
1573 "multu\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1574 [(set_attr "type" "imul")
1575 (set_attr "mode" "SI")
1576 (set_attr "length" "12")])
1578 ;; Widening multiply with negation.
1579 (define_insn "*muls_di"
1580 [(set (match_operand:DI 0 "register_operand" "=x")
1583 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1584 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1585 "!TARGET_64BIT && ISA_HAS_MULS"
1587 [(set_attr "type" "imul")
1588 (set_attr "length" "4")
1589 (set_attr "mode" "SI")])
1591 (define_insn "*umuls_di"
1592 [(set (match_operand:DI 0 "register_operand" "=x")
1595 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1596 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1597 "!TARGET_64BIT && ISA_HAS_MULS"
1599 [(set_attr "type" "imul")
1600 (set_attr "length" "4")
1601 (set_attr "mode" "SI")])
1603 (define_insn "*smsac_di"
1604 [(set (match_operand:DI 0 "register_operand" "=x")
1606 (match_operand:DI 3 "register_operand" "0")
1608 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1609 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1610 "!TARGET_64BIT && ISA_HAS_MSAC"
1612 if (TARGET_MIPS5500)
1613 return "msub\t%1,%2";
1615 return "msac\t$0,%1,%2";
1617 [(set_attr "type" "imadd")
1618 (set_attr "length" "4")
1619 (set_attr "mode" "SI")])
1621 (define_insn "*umsac_di"
1622 [(set (match_operand:DI 0 "register_operand" "=x")
1624 (match_operand:DI 3 "register_operand" "0")
1626 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1627 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1628 "!TARGET_64BIT && ISA_HAS_MSAC"
1630 if (TARGET_MIPS5500)
1631 return "msubu\t%1,%2";
1633 return "msacu\t$0,%1,%2";
1635 [(set_attr "type" "imadd")
1636 (set_attr "length" "4")
1637 (set_attr "mode" "SI")])
1639 ;; _highpart patterns
1640 (define_expand "umulsi3_highpart"
1641 [(set (match_operand:SI 0 "register_operand")
1644 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"))
1645 (zero_extend:DI (match_operand:SI 2 "register_operand")))
1647 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1650 emit_insn (gen_umulsi3_highpart_mulhi_internal (operands[0], operands[1],
1653 emit_insn (gen_umulsi3_highpart_internal (operands[0], operands[1],
1658 (define_insn "umulsi3_highpart_internal"
1659 [(set (match_operand:SI 0 "register_operand" "=h")
1662 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1663 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1665 (clobber (match_scratch:SI 3 "=l"))]
1666 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1668 [(set_attr "type" "imul")
1669 (set_attr "mode" "SI")
1670 (set_attr "length" "4")])
1672 (define_insn "umulsi3_highpart_mulhi_internal"
1673 [(set (match_operand:SI 0 "register_operand" "=h,d")
1676 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1677 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1679 (clobber (match_scratch:SI 3 "=l,l"))
1680 (clobber (match_scratch:SI 4 "=X,h"))]
1685 [(set_attr "type" "imul")
1686 (set_attr "mode" "SI")
1687 (set_attr "length" "4")])
1689 (define_insn "umulsi3_highpart_neg_mulhi_internal"
1690 [(set (match_operand:SI 0 "register_operand" "=h,d")
1694 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1695 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1697 (clobber (match_scratch:SI 3 "=l,l"))
1698 (clobber (match_scratch:SI 4 "=X,h"))]
1703 [(set_attr "type" "imul")
1704 (set_attr "mode" "SI")
1705 (set_attr "length" "4")])
1707 (define_expand "smulsi3_highpart"
1708 [(set (match_operand:SI 0 "register_operand")
1711 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"))
1712 (sign_extend:DI (match_operand:SI 2 "register_operand")))
1714 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1717 emit_insn (gen_smulsi3_highpart_mulhi_internal (operands[0], operands[1],
1720 emit_insn (gen_smulsi3_highpart_internal (operands[0], operands[1],
1725 (define_insn "smulsi3_highpart_internal"
1726 [(set (match_operand:SI 0 "register_operand" "=h")
1729 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1730 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1732 (clobber (match_scratch:SI 3 "=l"))]
1733 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1735 [(set_attr "type" "imul")
1736 (set_attr "mode" "SI")
1737 (set_attr "length" "4")])
1739 (define_insn "smulsi3_highpart_mulhi_internal"
1740 [(set (match_operand:SI 0 "register_operand" "=h,d")
1743 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1744 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1746 (clobber (match_scratch:SI 3 "=l,l"))
1747 (clobber (match_scratch:SI 4 "=X,h"))]
1752 [(set_attr "type" "imul")
1753 (set_attr "mode" "SI")
1754 (set_attr "length" "4")])
1756 (define_insn "smulsi3_highpart_neg_mulhi_internal"
1757 [(set (match_operand:SI 0 "register_operand" "=h,d")
1761 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1762 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1764 (clobber (match_scratch:SI 3 "=l,l"))
1765 (clobber (match_scratch:SI 4 "=X,h"))]
1770 [(set_attr "type" "imul")
1771 (set_attr "mode" "SI")])
1773 (define_insn "smuldi3_highpart"
1774 [(set (match_operand:DI 0 "register_operand" "=h")
1778 (sign_extend:TI (match_operand:DI 1 "register_operand" "d"))
1779 (sign_extend:TI (match_operand:DI 2 "register_operand" "d")))
1781 (clobber (match_scratch:DI 3 "=l"))]
1782 "TARGET_64BIT && !TARGET_FIX_R4000"
1784 [(set_attr "type" "imul")
1785 (set_attr "mode" "DI")])
1787 ;; Disable this pattern for -mfix-vr4120. This is for VR4120 errata MD(0),
1788 ;; which says that dmultu does not always produce the correct result.
1789 (define_insn "umuldi3_highpart"
1790 [(set (match_operand:DI 0 "register_operand" "=h")
1794 (zero_extend:TI (match_operand:DI 1 "register_operand" "d"))
1795 (zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
1797 (clobber (match_scratch:DI 3 "=l"))]
1798 "TARGET_64BIT && !TARGET_FIX_R4000 && !TARGET_FIX_VR4120"
1800 [(set_attr "type" "imul")
1801 (set_attr "mode" "DI")])
1804 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1805 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
1807 (define_insn "madsi"
1808 [(set (match_operand:SI 0 "register_operand" "+l")
1809 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1810 (match_operand:SI 2 "register_operand" "d"))
1812 (clobber (match_scratch:SI 3 "=h"))]
1815 [(set_attr "type" "imadd")
1816 (set_attr "mode" "SI")])
1818 (define_insn "*umul_acc_di"
1819 [(set (match_operand:DI 0 "register_operand" "=x")
1821 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1822 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1823 (match_operand:DI 3 "register_operand" "0")))]
1824 "(TARGET_MAD || ISA_HAS_MACC)
1828 return "madu\t%1,%2";
1829 else if (TARGET_MIPS5500)
1830 return "maddu\t%1,%2";
1832 /* See comment in *macc. */
1833 return "%[maccu\t%@,%1,%2%]";
1835 [(set_attr "type" "imadd")
1836 (set_attr "mode" "SI")])
1839 (define_insn "*smul_acc_di"
1840 [(set (match_operand:DI 0 "register_operand" "=x")
1842 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1843 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1844 (match_operand:DI 3 "register_operand" "0")))]
1845 "(TARGET_MAD || ISA_HAS_MACC)
1849 return "mad\t%1,%2";
1850 else if (TARGET_MIPS5500)
1851 return "madd\t%1,%2";
1853 /* See comment in *macc. */
1854 return "%[macc\t%@,%1,%2%]";
1856 [(set_attr "type" "imadd")
1857 (set_attr "mode" "SI")])
1859 ;; Floating point multiply accumulate instructions.
1862 [(set (match_operand:DF 0 "register_operand" "=f")
1863 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1864 (match_operand:DF 2 "register_operand" "f"))
1865 (match_operand:DF 3 "register_operand" "f")))]
1866 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1867 "madd.d\t%0,%3,%1,%2"
1868 [(set_attr "type" "fmadd")
1869 (set_attr "mode" "DF")])
1872 [(set (match_operand:SF 0 "register_operand" "=f")
1873 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1874 (match_operand:SF 2 "register_operand" "f"))
1875 (match_operand:SF 3 "register_operand" "f")))]
1876 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1877 "madd.s\t%0,%3,%1,%2"
1878 [(set_attr "type" "fmadd")
1879 (set_attr "mode" "SF")])
1882 [(set (match_operand:DF 0 "register_operand" "=f")
1883 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1884 (match_operand:DF 2 "register_operand" "f"))
1885 (match_operand:DF 3 "register_operand" "f")))]
1886 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1887 "msub.d\t%0,%3,%1,%2"
1888 [(set_attr "type" "fmadd")
1889 (set_attr "mode" "DF")])
1892 [(set (match_operand:SF 0 "register_operand" "=f")
1893 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1894 (match_operand:SF 2 "register_operand" "f"))
1895 (match_operand:SF 3 "register_operand" "f")))]
1897 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1898 "msub.s\t%0,%3,%1,%2"
1899 [(set_attr "type" "fmadd")
1900 (set_attr "mode" "SF")])
1903 [(set (match_operand:DF 0 "register_operand" "=f")
1904 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1905 (match_operand:DF 2 "register_operand" "f"))
1906 (match_operand:DF 3 "register_operand" "f"))))]
1907 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1908 "nmadd.d\t%0,%3,%1,%2"
1909 [(set_attr "type" "fmadd")
1910 (set_attr "mode" "DF")])
1913 [(set (match_operand:SF 0 "register_operand" "=f")
1914 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1915 (match_operand:SF 2 "register_operand" "f"))
1916 (match_operand:SF 3 "register_operand" "f"))))]
1917 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1918 "nmadd.s\t%0,%3,%1,%2"
1919 [(set_attr "type" "fmadd")
1920 (set_attr "mode" "SF")])
1923 [(set (match_operand:DF 0 "register_operand" "=f")
1924 (minus:DF (match_operand:DF 1 "register_operand" "f")
1925 (mult:DF (match_operand:DF 2 "register_operand" "f")
1926 (match_operand:DF 3 "register_operand" "f"))))]
1927 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1928 "nmsub.d\t%0,%1,%2,%3"
1929 [(set_attr "type" "fmadd")
1930 (set_attr "mode" "DF")])
1933 [(set (match_operand:SF 0 "register_operand" "=f")
1934 (minus:SF (match_operand:SF 1 "register_operand" "f")
1935 (mult:SF (match_operand:SF 2 "register_operand" "f")
1936 (match_operand:SF 3 "register_operand" "f"))))]
1937 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1938 "nmsub.s\t%0,%1,%2,%3"
1939 [(set_attr "type" "fmadd")
1940 (set_attr "mode" "SF")])
1943 ;; ....................
1945 ;; DIVISION and REMAINDER
1947 ;; ....................
1950 (define_expand "divdf3"
1951 [(set (match_operand:DF 0 "register_operand")
1952 (div:DF (match_operand:DF 1 "reg_or_1_operand")
1953 (match_operand:DF 2 "register_operand")))]
1954 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1956 if (const_1_operand (operands[1], DFmode))
1957 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1958 operands[1] = force_reg (DFmode, operands[1]);
1961 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
1963 ;; If an mfc1 or dmfc1 happens to access the floating point register
1964 ;; file at the same time a long latency operation (div, sqrt, recip,
1965 ;; sqrt) iterates an intermediate result back through the floating
1966 ;; point register file bypass, then instead returning the correct
1967 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1968 ;; result of the long latency operation.
1970 ;; The workaround is to insert an unconditional 'mov' from/to the
1971 ;; long latency op destination register.
1973 (define_insn "*divdf3"
1974 [(set (match_operand:DF 0 "register_operand" "=f")
1975 (div:DF (match_operand:DF 1 "register_operand" "f")
1976 (match_operand:DF 2 "register_operand" "f")))]
1977 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1980 return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
1982 return "div.d\t%0,%1,%2";
1984 [(set_attr "type" "fdiv")
1985 (set_attr "mode" "DF")
1986 (set (attr "length")
1987 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1992 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
1994 ;; In certain cases, div.s and div.ps may have a rounding error
1995 ;; and/or wrong inexact flag.
1997 ;; Therefore, we only allow div.s if not working around SB-1 rev2
1998 ;; errata, or if working around those errata and a slight loss of
1999 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
2000 (define_expand "divsf3"
2001 [(set (match_operand:SF 0 "register_operand")
2002 (div:SF (match_operand:SF 1 "reg_or_1_operand")
2003 (match_operand:SF 2 "register_operand")))]
2004 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2006 if (const_1_operand (operands[1], SFmode))
2007 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2008 operands[1] = force_reg (SFmode, operands[1]);
2011 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2012 ;; "divdf3" comment for details).
2014 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
2015 ;; "divsf3" comment for details).
2016 (define_insn "*divsf3"
2017 [(set (match_operand:SF 0 "register_operand" "=f")
2018 (div:SF (match_operand:SF 1 "register_operand" "f")
2019 (match_operand:SF 2 "register_operand" "f")))]
2020 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2023 return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
2025 return "div.s\t%0,%1,%2";
2027 [(set_attr "type" "fdiv")
2028 (set_attr "mode" "SF")
2029 (set (attr "length")
2030 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2034 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2035 ;; "divdf3" comment for details).
2037 [(set (match_operand:DF 0 "register_operand" "=f")
2038 (div:DF (match_operand:DF 1 "const_1_operand" "")
2039 (match_operand:DF 2 "register_operand" "f")))]
2040 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2043 return "recip.d\t%0,%2\;mov.d\t%0,%0";
2045 return "recip.d\t%0,%2";
2047 [(set_attr "type" "fdiv")
2048 (set_attr "mode" "DF")
2049 (set (attr "length")
2050 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2054 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2055 ;; "divdf3" comment for details).
2057 [(set (match_operand:SF 0 "register_operand" "=f")
2058 (div:SF (match_operand:SF 1 "const_1_operand" "")
2059 (match_operand:SF 2 "register_operand" "f")))]
2060 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2063 return "recip.s\t%0,%2\;mov.s\t%0,%0";
2065 return "recip.s\t%0,%2";
2067 [(set_attr "type" "fdiv")
2068 (set_attr "mode" "SF")
2069 (set (attr "length")
2070 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2074 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2075 ;; with negative operands. We use special libgcc functions instead.
2076 (define_insn "divmodsi4"
2077 [(set (match_operand:SI 0 "register_operand" "=l")
2078 (div:SI (match_operand:SI 1 "register_operand" "d")
2079 (match_operand:SI 2 "register_operand" "d")))
2080 (set (match_operand:SI 3 "register_operand" "=h")
2081 (mod:SI (match_dup 1)
2083 "!TARGET_FIX_VR4120"
2084 { return mips_output_division ("div\t$0,%1,%2", operands); }
2085 [(set_attr "type" "idiv")
2086 (set_attr "mode" "SI")])
2088 (define_insn "divmoddi4"
2089 [(set (match_operand:DI 0 "register_operand" "=l")
2090 (div:DI (match_operand:DI 1 "register_operand" "d")
2091 (match_operand:DI 2 "register_operand" "d")))
2092 (set (match_operand:DI 3 "register_operand" "=h")
2093 (mod:DI (match_dup 1)
2095 "TARGET_64BIT && !TARGET_FIX_VR4120"
2096 { return mips_output_division ("ddiv\t$0,%1,%2", operands); }
2097 [(set_attr "type" "idiv")
2098 (set_attr "mode" "DI")])
2100 (define_insn "udivmodsi4"
2101 [(set (match_operand:SI 0 "register_operand" "=l")
2102 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2103 (match_operand:SI 2 "register_operand" "d")))
2104 (set (match_operand:SI 3 "register_operand" "=h")
2105 (umod:SI (match_dup 1)
2108 { return mips_output_division ("divu\t$0,%1,%2", operands); }
2109 [(set_attr "type" "idiv")
2110 (set_attr "mode" "SI")])
2112 (define_insn "udivmoddi4"
2113 [(set (match_operand:DI 0 "register_operand" "=l")
2114 (udiv:DI (match_operand:DI 1 "register_operand" "d")
2115 (match_operand:DI 2 "register_operand" "d")))
2116 (set (match_operand:DI 3 "register_operand" "=h")
2117 (umod:DI (match_dup 1)
2120 { return mips_output_division ("ddivu\t$0,%1,%2", operands); }
2121 [(set_attr "type" "idiv")
2122 (set_attr "mode" "DI")])
2125 ;; ....................
2129 ;; ....................
2131 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2132 ;; "divdf3" comment for details).
2133 (define_insn "sqrtdf2"
2134 [(set (match_operand:DF 0 "register_operand" "=f")
2135 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2136 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2139 return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
2141 return "sqrt.d\t%0,%1";
2143 [(set_attr "type" "fsqrt")
2144 (set_attr "mode" "DF")
2145 (set (attr "length")
2146 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2150 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2151 ;; "divdf3" comment for details).
2152 (define_insn "sqrtsf2"
2153 [(set (match_operand:SF 0 "register_operand" "=f")
2154 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2155 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2158 return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
2160 return "sqrt.s\t%0,%1";
2162 [(set_attr "type" "fsqrt")
2163 (set_attr "mode" "SF")
2164 (set (attr "length")
2165 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2169 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2170 ;; "divdf3" comment for details).
2172 [(set (match_operand:DF 0 "register_operand" "=f")
2173 (div:DF (match_operand:DF 1 "const_1_operand" "")
2174 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2175 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2178 return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2180 return "rsqrt.d\t%0,%2";
2182 [(set_attr "type" "frsqrt")
2183 (set_attr "mode" "DF")
2184 (set (attr "length")
2185 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2189 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2190 ;; "divdf3" comment for details).
2192 [(set (match_operand:SF 0 "register_operand" "=f")
2193 (div:SF (match_operand:SF 1 "const_1_operand" "")
2194 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2195 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2198 return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2200 return "rsqrt.s\t%0,%2";
2202 [(set_attr "type" "frsqrt")
2203 (set_attr "mode" "SF")
2204 (set (attr "length")
2205 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2209 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2210 ;; "divdf3" comment for details).
2212 [(set (match_operand:DF 0 "register_operand" "=f")
2213 (sqrt:DF (div:DF (match_operand:DF 1 "const_1_operand" "")
2214 (match_operand:DF 2 "register_operand" "f"))))]
2215 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2218 return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2220 return "rsqrt.d\t%0,%2";
2222 [(set_attr "type" "frsqrt")
2223 (set_attr "mode" "DF")
2224 (set (attr "length")
2225 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2229 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2230 ;; "divdf3" comment for details).
2232 [(set (match_operand:SF 0 "register_operand" "=f")
2233 (sqrt:SF (div:SF (match_operand:SF 1 "const_1_operand" "")
2234 (match_operand:SF 2 "register_operand" "f"))))]
2235 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2238 return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2240 return "rsqrt.s\t%0,%2";
2242 [(set_attr "type" "frsqrt")
2243 (set_attr "mode" "SF")
2244 (set (attr "length")
2245 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2250 ;; ....................
2254 ;; ....................
2256 ;; Do not use the integer abs macro instruction, since that signals an
2257 ;; exception on -2147483648 (sigh).
2259 (define_insn "abssi2"
2260 [(set (match_operand:SI 0 "register_operand" "=d")
2261 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2264 operands[2] = const0_rtx;
2266 if (REGNO (operands[0]) == REGNO (operands[1]))
2268 if (GENERATE_BRANCHLIKELY)
2269 return "%(bltzl\t%1,1f\;subu\t%0,%z2,%0\n%~1:%)";
2271 return "bgez\t%1,1f%#\;subu\t%0,%z2,%0\n%~1:";
2274 return "%(bgez\t%1,1f\;move\t%0,%1\;subu\t%0,%z2,%0\n%~1:%)";
2276 [(set_attr "type" "multi")
2277 (set_attr "mode" "SI")
2278 (set_attr "length" "12")])
2280 (define_insn "absdi2"
2281 [(set (match_operand:DI 0 "register_operand" "=d")
2282 (abs:DI (match_operand:DI 1 "register_operand" "d")))]
2283 "TARGET_64BIT && !TARGET_MIPS16"
2285 unsigned int regno1;
2286 operands[2] = const0_rtx;
2288 if (GET_CODE (operands[1]) == REG)
2289 regno1 = REGNO (operands[1]);
2291 regno1 = REGNO (XEXP (operands[1], 0));
2293 if (REGNO (operands[0]) == regno1)
2294 return "%(bltzl\t%1,1f\;dsubu\t%0,%z2,%0\n%~1:%)";
2296 return "%(bgez\t%1,1f\;move\t%0,%1\;dsubu\t%0,%z2,%0\n%~1:%)";
2298 [(set_attr "type" "multi")
2299 (set_attr "mode" "DI")
2300 (set_attr "length" "12")])
2302 (define_insn "absdf2"
2303 [(set (match_operand:DF 0 "register_operand" "=f")
2304 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2305 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2307 [(set_attr "type" "fabs")
2308 (set_attr "mode" "DF")])
2310 (define_insn "abssf2"
2311 [(set (match_operand:SF 0 "register_operand" "=f")
2312 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2315 [(set_attr "type" "fabs")
2316 (set_attr "mode" "SF")])
2319 ;; ....................
2321 ;; FIND FIRST BIT INSTRUCTION
2323 ;; ....................
2326 (define_insn "ffssi2"
2327 [(set (match_operand:SI 0 "register_operand" "=&d")
2328 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2329 (clobber (match_scratch:SI 2 "=&d"))
2330 (clobber (match_scratch:SI 3 "=&d"))]
2333 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2337 %~1:\tand\t%2,%1,0x0001\;\
2347 %~1:\tand\t%2,%3,0x0001\;\
2353 [(set_attr "type" "multi")
2354 (set_attr "mode" "SI")
2355 (set_attr "length" "28")])
2357 (define_insn "ffsdi2"
2358 [(set (match_operand:DI 0 "register_operand" "=&d")
2359 (ffs:DI (match_operand:DI 1 "register_operand" "d")))
2360 (clobber (match_scratch:DI 2 "=&d"))
2361 (clobber (match_scratch:DI 3 "=&d"))]
2362 "TARGET_64BIT && !TARGET_MIPS16"
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" "DI")
2386 (set_attr "length" "28")])
2389 ;; ...................
2391 ;; Count leading zeroes.
2393 ;; ...................
2396 (define_insn "clzsi2"
2397 [(set (match_operand:SI 0 "register_operand" "=d")
2398 (clz:SI (match_operand:SI 1 "register_operand" "d")))]
2401 [(set_attr "type" "clz")
2402 (set_attr "mode" "SI")])
2404 (define_insn "clzdi2"
2405 [(set (match_operand:DI 0 "register_operand" "=d")
2406 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
2409 [(set_attr "type" "clz")
2410 (set_attr "mode" "DI")])
2413 ;; ....................
2415 ;; NEGATION and ONE'S COMPLEMENT
2417 ;; ....................
2419 (define_insn "negsi2"
2420 [(set (match_operand:SI 0 "register_operand" "=d")
2421 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2425 return "neg\t%0,%1";
2427 return "subu\t%0,%.,%1";
2429 [(set_attr "type" "arith")
2430 (set_attr "mode" "SI")])
2432 (define_insn "negdi2"
2433 [(set (match_operand:DI 0 "register_operand" "=d")
2434 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2435 "TARGET_64BIT && !TARGET_MIPS16"
2437 [(set_attr "type" "arith")
2438 (set_attr "mode" "DI")])
2440 (define_insn "negdf2"
2441 [(set (match_operand:DF 0 "register_operand" "=f")
2442 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2443 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2445 [(set_attr "type" "fneg")
2446 (set_attr "mode" "DF")])
2448 (define_insn "negsf2"
2449 [(set (match_operand:SF 0 "register_operand" "=f")
2450 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2453 [(set_attr "type" "fneg")
2454 (set_attr "mode" "SF")])
2456 (define_insn "one_cmplsi2"
2457 [(set (match_operand:SI 0 "register_operand" "=d")
2458 (not:SI (match_operand:SI 1 "register_operand" "d")))]
2462 return "not\t%0,%1";
2464 return "nor\t%0,%.,%1";
2466 [(set_attr "type" "arith")
2467 (set_attr "mode" "SI")])
2469 (define_insn "one_cmpldi2"
2470 [(set (match_operand:DI 0 "register_operand" "=d")
2471 (not:DI (match_operand:DI 1 "register_operand" "d")))]
2475 return "not\t%0,%1";
2477 return "nor\t%0,%.,%1";
2479 [(set_attr "type" "arith")
2480 (set_attr "mode" "DI")])
2483 ;; ....................
2487 ;; ....................
2490 ;; Many of these instructions use trivial define_expands, because we
2491 ;; want to use a different set of constraints when TARGET_MIPS16.
2493 (define_expand "andsi3"
2494 [(set (match_operand:SI 0 "register_operand")
2495 (and:SI (match_operand:SI 1 "uns_arith_operand")
2496 (match_operand:SI 2 "uns_arith_operand")))]
2501 operands[1] = force_reg (SImode, operands[1]);
2502 operands[2] = force_reg (SImode, operands[2]);
2507 [(set (match_operand:SI 0 "register_operand" "=d,d")
2508 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2509 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2514 [(set_attr "type" "arith")
2515 (set_attr "mode" "SI")])
2518 [(set (match_operand:SI 0 "register_operand" "=d")
2519 (and:SI (match_operand:SI 1 "register_operand" "%0")
2520 (match_operand:SI 2 "register_operand" "d")))]
2523 [(set_attr "type" "arith")
2524 (set_attr "mode" "SI")])
2526 (define_expand "anddi3"
2527 [(set (match_operand:DI 0 "register_operand")
2528 (and:DI (match_operand:DI 1 "register_operand")
2529 (match_operand:DI 2 "uns_arith_operand")))]
2534 operands[1] = force_reg (DImode, operands[1]);
2535 operands[2] = force_reg (DImode, operands[2]);
2540 [(set (match_operand:DI 0 "register_operand" "=d,d")
2541 (and:DI (match_operand:DI 1 "register_operand" "d,d")
2542 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2543 "TARGET_64BIT && !TARGET_MIPS16"
2547 [(set_attr "type" "arith")
2548 (set_attr "mode" "DI")])
2551 [(set (match_operand:DI 0 "register_operand" "=d")
2552 (and:DI (match_operand:DI 1 "register_operand" "0")
2553 (match_operand:DI 2 "register_operand" "d")))]
2554 "TARGET_64BIT && TARGET_MIPS16"
2556 [(set_attr "type" "arith")
2557 (set_attr "mode" "DI")])
2559 (define_expand "iorsi3"
2560 [(set (match_operand:SI 0 "register_operand")
2561 (ior:SI (match_operand:SI 1 "uns_arith_operand")
2562 (match_operand:SI 2 "uns_arith_operand")))]
2567 operands[1] = force_reg (SImode, operands[1]);
2568 operands[2] = force_reg (SImode, operands[2]);
2573 [(set (match_operand:SI 0 "register_operand" "=d,d")
2574 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2575 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2580 [(set_attr "type" "arith")
2581 (set_attr "mode" "SI")])
2584 [(set (match_operand:SI 0 "register_operand" "=d")
2585 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2586 (match_operand:SI 2 "register_operand" "d")))]
2589 [(set_attr "type" "arith")
2590 (set_attr "mode" "SI")])
2592 (define_expand "iordi3"
2593 [(set (match_operand:DI 0 "register_operand")
2594 (ior:DI (match_operand:DI 1 "register_operand")
2595 (match_operand:DI 2 "uns_arith_operand")))]
2600 operands[1] = force_reg (DImode, operands[1]);
2601 operands[2] = force_reg (DImode, operands[2]);
2606 [(set (match_operand:DI 0 "register_operand" "=d,d")
2607 (ior:DI (match_operand:DI 1 "register_operand" "d,d")
2608 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2609 "TARGET_64BIT && !TARGET_MIPS16"
2613 [(set_attr "type" "arith")
2614 (set_attr "mode" "DI")])
2617 [(set (match_operand:DI 0 "register_operand" "=d")
2618 (ior:DI (match_operand:DI 1 "register_operand" "0")
2619 (match_operand:DI 2 "register_operand" "d")))]
2620 "TARGET_64BIT && TARGET_MIPS16"
2622 [(set_attr "type" "arith")
2623 (set_attr "mode" "DI")])
2625 (define_expand "xorsi3"
2626 [(set (match_operand:SI 0 "register_operand")
2627 (xor:SI (match_operand:SI 1 "uns_arith_operand")
2628 (match_operand:SI 2 "uns_arith_operand")))]
2633 [(set (match_operand:SI 0 "register_operand" "=d,d")
2634 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2635 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2640 [(set_attr "type" "arith")
2641 (set_attr "mode" "SI")])
2644 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
2645 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
2646 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
2652 [(set_attr "type" "arith")
2653 (set_attr "mode" "SI")
2654 (set_attr_alternative "length"
2656 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2661 (define_expand "xordi3"
2662 [(set (match_operand:DI 0 "register_operand")
2663 (xor:DI (match_operand:DI 1 "register_operand")
2664 (match_operand:DI 2 "uns_arith_operand")))]
2669 operands[1] = force_reg (DImode, operands[1]);
2670 operands[2] = force_reg (DImode, operands[2]);
2675 [(set (match_operand:DI 0 "register_operand" "=d,d")
2676 (xor:DI (match_operand:DI 1 "register_operand" "d,d")
2677 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2678 "TARGET_64BIT && !TARGET_MIPS16"
2682 [(set_attr "type" "arith")
2683 (set_attr "mode" "DI")])
2686 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
2687 (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
2688 (match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
2689 "TARGET_64BIT && TARGET_MIPS16"
2694 [(set_attr "type" "arith")
2695 (set_attr "mode" "DI")
2696 (set_attr_alternative "length"
2698 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2703 (define_insn "*norsi3"
2704 [(set (match_operand:SI 0 "register_operand" "=d")
2705 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
2706 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
2709 [(set_attr "type" "arith")
2710 (set_attr "mode" "SI")])
2712 (define_insn "*nordi3"
2713 [(set (match_operand:DI 0 "register_operand" "=d")
2714 (and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
2715 (not:DI (match_operand:DI 2 "register_operand" "d"))))]
2716 "TARGET_64BIT && !TARGET_MIPS16"
2718 [(set_attr "type" "arith")
2719 (set_attr "mode" "DI")])
2722 ;; ....................
2726 ;; ....................
2730 (define_insn "truncdfsf2"
2731 [(set (match_operand:SF 0 "register_operand" "=f")
2732 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2733 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2735 [(set_attr "type" "fcvt")
2736 (set_attr "mode" "SF")])
2738 ;; Integer truncation patterns. Truncating SImode values to smaller
2739 ;; modes is a no-op, as it is for most other GCC ports. Truncating
2740 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2741 ;; need to make sure that the lower 32 bits are properly sign-extended
2742 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
2743 ;; smaller than SImode is equivalent to two separate truncations:
2746 ;; DI ---> HI == DI ---> SI ---> HI
2747 ;; DI ---> QI == DI ---> SI ---> QI
2749 ;; Step A needs a real instruction but step B does not.
2751 (define_insn "truncdisi2"
2752 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2753 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2758 [(set_attr "type" "shift,store")
2759 (set_attr "mode" "SI")
2760 (set_attr "extended_mips16" "yes,*")])
2762 (define_insn "truncdihi2"
2763 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2764 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2769 [(set_attr "type" "shift,store")
2770 (set_attr "mode" "SI")
2771 (set_attr "extended_mips16" "yes,*")])
2773 (define_insn "truncdiqi2"
2774 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2775 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2780 [(set_attr "type" "shift,store")
2781 (set_attr "mode" "SI")
2782 (set_attr "extended_mips16" "yes,*")])
2784 ;; Combiner patterns to optimize shift/truncate combinations.
2787 [(set (match_operand:SI 0 "register_operand" "=d")
2789 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2790 (match_operand:DI 2 "const_arith_operand" ""))))]
2791 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2793 [(set_attr "type" "shift")
2794 (set_attr "mode" "SI")])
2797 [(set (match_operand:SI 0 "register_operand" "=d")
2798 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2800 "TARGET_64BIT && !TARGET_MIPS16"
2802 [(set_attr "type" "shift")
2803 (set_attr "mode" "SI")])
2806 ;; Combiner patterns for truncate/sign_extend combinations. They use
2807 ;; the shift/truncate patterns above.
2809 (define_insn_and_split ""
2810 [(set (match_operand:SI 0 "register_operand" "=d")
2812 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2813 "TARGET_64BIT && !TARGET_MIPS16"
2815 "&& reload_completed"
2817 (ashift:DI (match_dup 1)
2820 (truncate:SI (ashiftrt:DI (match_dup 2)
2822 { operands[2] = gen_lowpart (DImode, operands[0]); })
2824 (define_insn_and_split ""
2825 [(set (match_operand:SI 0 "register_operand" "=d")
2827 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2828 "TARGET_64BIT && !TARGET_MIPS16"
2830 "&& reload_completed"
2832 (ashift:DI (match_dup 1)
2835 (truncate:SI (ashiftrt:DI (match_dup 2)
2837 { operands[2] = gen_lowpart (DImode, operands[0]); })
2840 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2843 [(set (match_operand:SI 0 "register_operand" "=d")
2844 (zero_extend:SI (truncate:HI
2845 (match_operand:DI 1 "register_operand" "d"))))]
2846 "TARGET_64BIT && !TARGET_MIPS16"
2847 "andi\t%0,%1,0xffff"
2848 [(set_attr "type" "arith")
2849 (set_attr "mode" "SI")])
2852 [(set (match_operand:SI 0 "register_operand" "=d")
2853 (zero_extend:SI (truncate:QI
2854 (match_operand:DI 1 "register_operand" "d"))))]
2855 "TARGET_64BIT && !TARGET_MIPS16"
2857 [(set_attr "type" "arith")
2858 (set_attr "mode" "SI")])
2861 [(set (match_operand:HI 0 "register_operand" "=d")
2862 (zero_extend:HI (truncate:QI
2863 (match_operand:DI 1 "register_operand" "d"))))]
2864 "TARGET_64BIT && !TARGET_MIPS16"
2866 [(set_attr "type" "arith")
2867 (set_attr "mode" "HI")])
2870 ;; ....................
2874 ;; ....................
2877 ;; Those for integer source operand are ordered widest source type first.
2879 (define_insn_and_split "zero_extendsidi2"
2880 [(set (match_operand:DI 0 "register_operand" "=d")
2881 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2884 "&& reload_completed"
2886 (ashift:DI (match_dup 1) (const_int 32)))
2888 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2889 "operands[1] = gen_lowpart (DImode, operands[1]);"
2890 [(set_attr "type" "multi")
2891 (set_attr "mode" "DI")
2892 (set_attr "length" "8")])
2894 (define_insn "*zero_extendsidi2_mem"
2895 [(set (match_operand:DI 0 "register_operand" "=d")
2896 (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2899 [(set_attr "type" "load")
2900 (set_attr "mode" "DI")])
2902 (define_expand "zero_extendhisi2"
2903 [(set (match_operand:SI 0 "register_operand")
2904 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2907 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2909 rtx op = gen_lowpart (SImode, operands[1]);
2910 rtx temp = force_reg (SImode, GEN_INT (0xffff));
2912 emit_insn (gen_andsi3 (operands[0], op, temp));
2918 [(set (match_operand:SI 0 "register_operand" "=d,d")
2919 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2924 [(set_attr "type" "arith,load")
2925 (set_attr "mode" "SI")
2926 (set_attr "length" "4,*")])
2929 [(set (match_operand:SI 0 "register_operand" "=d")
2930 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2933 [(set_attr "type" "load")
2934 (set_attr "mode" "SI")])
2936 (define_expand "zero_extendhidi2"
2937 [(set (match_operand:DI 0 "register_operand")
2938 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2941 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2943 rtx op = gen_lowpart (DImode, operands[1]);
2944 rtx temp = force_reg (DImode, GEN_INT (0xffff));
2946 emit_insn (gen_anddi3 (operands[0], op, temp));
2952 [(set (match_operand:DI 0 "register_operand" "=d,d")
2953 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2954 "TARGET_64BIT && !TARGET_MIPS16"
2958 [(set_attr "type" "arith,load")
2959 (set_attr "mode" "DI")
2960 (set_attr "length" "4,*")])
2963 [(set (match_operand:DI 0 "register_operand" "=d")
2964 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2965 "TARGET_64BIT && TARGET_MIPS16"
2967 [(set_attr "type" "load")
2968 (set_attr "mode" "DI")])
2970 (define_expand "zero_extendqihi2"
2971 [(set (match_operand:HI 0 "register_operand")
2972 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2975 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2977 rtx op0 = gen_lowpart (SImode, operands[0]);
2978 rtx op1 = gen_lowpart (SImode, operands[1]);
2979 rtx temp = force_reg (SImode, GEN_INT (0xff));
2981 emit_insn (gen_andsi3 (op0, op1, temp));
2987 [(set (match_operand:HI 0 "register_operand" "=d,d")
2988 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2993 [(set_attr "type" "arith,load")
2994 (set_attr "mode" "HI")
2995 (set_attr "length" "4,*")])
2998 [(set (match_operand:HI 0 "register_operand" "=d")
2999 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3002 [(set_attr "type" "load")
3003 (set_attr "mode" "HI")])
3005 (define_expand "zero_extendqisi2"
3006 [(set (match_operand:SI 0 "register_operand")
3007 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3010 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3012 rtx op = gen_lowpart (SImode, operands[1]);
3013 rtx temp = force_reg (SImode, GEN_INT (0xff));
3015 emit_insn (gen_andsi3 (operands[0], op, temp));
3021 [(set (match_operand:SI 0 "register_operand" "=d,d")
3022 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3027 [(set_attr "type" "arith,load")
3028 (set_attr "mode" "SI")
3029 (set_attr "length" "4,*")])
3032 [(set (match_operand:SI 0 "register_operand" "=d")
3033 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3036 [(set_attr "type" "load")
3037 (set_attr "mode" "SI")])
3039 (define_expand "zero_extendqidi2"
3040 [(set (match_operand:DI 0 "register_operand")
3041 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3044 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3046 rtx op = gen_lowpart (DImode, operands[1]);
3047 rtx temp = force_reg (DImode, GEN_INT (0xff));
3049 emit_insn (gen_anddi3 (operands[0], op, temp));
3055 [(set (match_operand:DI 0 "register_operand" "=d,d")
3056 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3057 "TARGET_64BIT && !TARGET_MIPS16"
3061 [(set_attr "type" "arith,load")
3062 (set_attr "mode" "DI")
3063 (set_attr "length" "4,*")])
3066 [(set (match_operand:DI 0 "register_operand" "=d")
3067 (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3068 "TARGET_64BIT && TARGET_MIPS16"
3070 [(set_attr "type" "load")
3071 (set_attr "mode" "DI")])
3074 ;; ....................
3078 ;; ....................
3081 ;; Those for integer source operand are ordered widest source type first.
3083 ;; When TARGET_64BIT, all SImode integer registers should already be in
3084 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
3085 ;; therefore get rid of register->register instructions if we constrain
3086 ;; the source to be in the same register as the destination.
3088 ;; The register alternative has type "arith" so that the pre-reload
3089 ;; scheduler will treat it as a move. This reflects what happens if
3090 ;; the register alternative needs a reload.
3091 (define_insn_and_split "extendsidi2"
3092 [(set (match_operand:DI 0 "register_operand" "=d,d")
3093 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
3098 "&& reload_completed && register_operand (operands[1], VOIDmode)"
3101 emit_note (NOTE_INSN_DELETED);
3104 [(set_attr "type" "arith,load")
3105 (set_attr "mode" "DI")])
3107 ;; These patterns originally accepted general_operands, however, slightly
3108 ;; better code is generated by only accepting register_operands, and then
3109 ;; letting combine generate the lh and lb insns.
3111 ;; These expanders originally put values in registers first. We split
3112 ;; all non-mem patterns after reload.
3114 (define_expand "extendhidi2"
3115 [(set (match_operand:DI 0 "register_operand")
3116 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
3120 (define_insn "*extendhidi2"
3121 [(set (match_operand:DI 0 "register_operand" "=d")
3122 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
3127 [(set (match_operand:DI 0 "register_operand")
3128 (sign_extend:DI (match_operand:HI 1 "register_operand")))]
3129 "TARGET_64BIT && reload_completed"
3131 (ashift:DI (match_dup 1) (const_int 48)))
3133 (ashiftrt:DI (match_dup 0) (const_int 48)))]
3134 "operands[1] = gen_lowpart (DImode, operands[1]);")
3136 (define_insn "*extendhidi2_mem"
3137 [(set (match_operand:DI 0 "register_operand" "=d")
3138 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3141 [(set_attr "type" "load")
3142 (set_attr "mode" "DI")])
3144 (define_expand "extendhisi2"
3145 [(set (match_operand:SI 0 "register_operand")
3146 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
3149 if (ISA_HAS_SEB_SEH)
3151 emit_insn (gen_extendhisi2_hw (operands[0],
3152 force_reg (HImode, operands[1])));
3157 (define_insn "*extendhisi2"
3158 [(set (match_operand:SI 0 "register_operand" "=d")
3159 (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
3164 [(set (match_operand:SI 0 "register_operand")
3165 (sign_extend:SI (match_operand:HI 1 "register_operand")))]
3168 (ashift:SI (match_dup 1) (const_int 16)))
3170 (ashiftrt:SI (match_dup 0) (const_int 16)))]
3171 "operands[1] = gen_lowpart (SImode, operands[1]);")
3173 (define_insn "extendhisi2_mem"
3174 [(set (match_operand:SI 0 "register_operand" "=d")
3175 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3178 [(set_attr "type" "load")
3179 (set_attr "mode" "SI")])
3181 (define_insn "extendhisi2_hw"
3182 [(set (match_operand:SI 0 "register_operand" "=r")
3183 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
3186 [(set_attr "type" "arith")
3187 (set_attr "mode" "SI")])
3189 (define_expand "extendqihi2"
3190 [(set (match_operand:HI 0 "register_operand")
3191 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3195 (define_insn "*extendqihi2"
3196 [(set (match_operand:HI 0 "register_operand" "=d")
3197 (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
3202 [(set (match_operand:HI 0 "register_operand")
3203 (sign_extend:HI (match_operand:QI 1 "register_operand")))]
3206 (ashift:SI (match_dup 1) (const_int 24)))
3208 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3209 "operands[0] = gen_lowpart (SImode, operands[0]);
3210 operands[1] = gen_lowpart (SImode, operands[1]);")
3212 (define_insn "*extendqihi2_internal_mem"
3213 [(set (match_operand:HI 0 "register_operand" "=d")
3214 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3217 [(set_attr "type" "load")
3218 (set_attr "mode" "SI")])
3221 (define_expand "extendqisi2"
3222 [(set (match_operand:SI 0 "register_operand")
3223 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3226 if (ISA_HAS_SEB_SEH)
3228 emit_insn (gen_extendqisi2_hw (operands[0],
3229 force_reg (QImode, operands[1])));
3234 (define_insn "*extendqisi2"
3235 [(set (match_operand:SI 0 "register_operand" "=d")
3236 (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
3241 [(set (match_operand:SI 0 "register_operand")
3242 (sign_extend:SI (match_operand:QI 1 "register_operand")))]
3245 (ashift:SI (match_dup 1) (const_int 24)))
3247 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3248 "operands[1] = gen_lowpart (SImode, operands[1]);")
3250 (define_insn "*extendqisi2_mem"
3251 [(set (match_operand:SI 0 "register_operand" "=d")
3252 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3255 [(set_attr "type" "load")
3256 (set_attr "mode" "SI")])
3258 (define_insn "extendqisi2_hw"
3259 [(set (match_operand:SI 0 "register_operand" "=r")
3260 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
3263 [(set_attr "type" "arith")
3264 (set_attr "mode" "SI")])
3266 (define_expand "extendqidi2"
3267 [(set (match_operand:DI 0 "register_operand")
3268 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3272 (define_insn "*extendqidi2"
3273 [(set (match_operand:DI 0 "register_operand" "=d")
3274 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
3279 [(set (match_operand:DI 0 "register_operand")
3280 (sign_extend:DI (match_operand:QI 1 "register_operand")))]
3281 "TARGET_64BIT && reload_completed"
3283 (ashift:DI (match_dup 1) (const_int 56)))
3285 (ashiftrt:DI (match_dup 0) (const_int 56)))]
3286 "operands[1] = gen_lowpart (DImode, operands[1]);")
3288 (define_insn "*extendqidi2_mem"
3289 [(set (match_operand:DI 0 "register_operand" "=d")
3290 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3293 [(set_attr "type" "load")
3294 (set_attr "mode" "DI")])
3296 (define_insn "extendsfdf2"
3297 [(set (match_operand:DF 0 "register_operand" "=f")
3298 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3299 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3301 [(set_attr "type" "fcvt")
3302 (set_attr "mode" "DF")])
3305 ;; ....................
3309 ;; ....................
3311 (define_expand "fix_truncdfsi2"
3312 [(set (match_operand:SI 0 "register_operand")
3313 (fix:SI (match_operand:DF 1 "register_operand")))]
3314 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3316 if (!ISA_HAS_TRUNC_W)
3318 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3323 (define_insn "fix_truncdfsi2_insn"
3324 [(set (match_operand:SI 0 "register_operand" "=f")
3325 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3326 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3328 [(set_attr "type" "fcvt")
3329 (set_attr "mode" "DF")
3330 (set_attr "length" "4")])
3332 (define_insn "fix_truncdfsi2_macro"
3333 [(set (match_operand:SI 0 "register_operand" "=f")
3334 (fix:SI (match_operand:DF 1 "register_operand" "f")))
3335 (clobber (match_scratch:DF 2 "=d"))]
3336 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3339 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3341 return "trunc.w.d %0,%1,%2";
3343 [(set_attr "type" "fcvt")
3344 (set_attr "mode" "DF")
3345 (set_attr "length" "36")])
3347 (define_expand "fix_truncsfsi2"
3348 [(set (match_operand:SI 0 "register_operand")
3349 (fix:SI (match_operand:SF 1 "register_operand")))]
3352 if (!ISA_HAS_TRUNC_W)
3354 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3359 (define_insn "fix_truncsfsi2_insn"
3360 [(set (match_operand:SI 0 "register_operand" "=f")
3361 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3362 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3364 [(set_attr "type" "fcvt")
3365 (set_attr "mode" "DF")
3366 (set_attr "length" "4")])
3368 (define_insn "fix_truncsfsi2_macro"
3369 [(set (match_operand:SI 0 "register_operand" "=f")
3370 (fix:SI (match_operand:SF 1 "register_operand" "f")))
3371 (clobber (match_scratch:SF 2 "=d"))]
3372 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3375 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3377 return "trunc.w.s %0,%1,%2";
3379 [(set_attr "type" "fcvt")
3380 (set_attr "mode" "DF")
3381 (set_attr "length" "36")])
3384 (define_insn "fix_truncdfdi2"
3385 [(set (match_operand:DI 0 "register_operand" "=f")
3386 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3387 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3389 [(set_attr "type" "fcvt")
3390 (set_attr "mode" "DF")
3391 (set_attr "length" "4")])
3394 (define_insn "fix_truncsfdi2"
3395 [(set (match_operand:DI 0 "register_operand" "=f")
3396 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3397 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3399 [(set_attr "type" "fcvt")
3400 (set_attr "mode" "SF")
3401 (set_attr "length" "4")])
3404 (define_insn "floatsidf2"
3405 [(set (match_operand:DF 0 "register_operand" "=f")
3406 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3407 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3409 [(set_attr "type" "fcvt")
3410 (set_attr "mode" "DF")
3411 (set_attr "length" "4")])
3414 (define_insn "floatdidf2"
3415 [(set (match_operand:DF 0 "register_operand" "=f")
3416 (float:DF (match_operand:DI 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 "floatsisf2"
3425 [(set (match_operand:SF 0 "register_operand" "=f")
3426 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3429 [(set_attr "type" "fcvt")
3430 (set_attr "mode" "SF")
3431 (set_attr "length" "4")])
3434 (define_insn "floatdisf2"
3435 [(set (match_operand:SF 0 "register_operand" "=f")
3436 (float:SF (match_operand:DI 1 "register_operand" "f")))]
3437 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3439 [(set_attr "type" "fcvt")
3440 (set_attr "mode" "SF")
3441 (set_attr "length" "4")])
3444 (define_expand "fixuns_truncdfsi2"
3445 [(set (match_operand:SI 0 "register_operand")
3446 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
3447 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3449 rtx reg1 = gen_reg_rtx (DFmode);
3450 rtx reg2 = gen_reg_rtx (DFmode);
3451 rtx reg3 = gen_reg_rtx (SImode);
3452 rtx label1 = gen_label_rtx ();
3453 rtx label2 = gen_label_rtx ();
3454 REAL_VALUE_TYPE offset;
3456 real_2expN (&offset, 31);
3458 if (reg1) /* Turn off complaints about unreached code. */
3460 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3461 do_pending_stack_adjust ();
3463 emit_insn (gen_cmpdf (operands[1], reg1));
3464 emit_jump_insn (gen_bge (label1));
3466 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3467 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3468 gen_rtx_LABEL_REF (VOIDmode, label2)));
3471 emit_label (label1);
3472 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3473 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3474 (BITMASK_HIGH, SImode)));
3476 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3477 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3479 emit_label (label2);
3481 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3482 fields, and can't be used for REG_NOTES anyway). */
3483 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3489 (define_expand "fixuns_truncdfdi2"
3490 [(set (match_operand:DI 0 "register_operand")
3491 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3492 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3494 rtx reg1 = gen_reg_rtx (DFmode);
3495 rtx reg2 = gen_reg_rtx (DFmode);
3496 rtx reg3 = gen_reg_rtx (DImode);
3497 rtx label1 = gen_label_rtx ();
3498 rtx label2 = gen_label_rtx ();
3499 REAL_VALUE_TYPE offset;
3501 real_2expN (&offset, 63);
3503 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3504 do_pending_stack_adjust ();
3506 emit_insn (gen_cmpdf (operands[1], reg1));
3507 emit_jump_insn (gen_bge (label1));
3509 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3510 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3511 gen_rtx_LABEL_REF (VOIDmode, label2)));
3514 emit_label (label1);
3515 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3516 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3517 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3519 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3520 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3522 emit_label (label2);
3524 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3525 fields, and can't be used for REG_NOTES anyway). */
3526 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3531 (define_expand "fixuns_truncsfsi2"
3532 [(set (match_operand:SI 0 "register_operand")
3533 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3536 rtx reg1 = gen_reg_rtx (SFmode);
3537 rtx reg2 = gen_reg_rtx (SFmode);
3538 rtx reg3 = gen_reg_rtx (SImode);
3539 rtx label1 = gen_label_rtx ();
3540 rtx label2 = gen_label_rtx ();
3541 REAL_VALUE_TYPE offset;
3543 real_2expN (&offset, 31);
3545 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3546 do_pending_stack_adjust ();
3548 emit_insn (gen_cmpsf (operands[1], reg1));
3549 emit_jump_insn (gen_bge (label1));
3551 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3552 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3553 gen_rtx_LABEL_REF (VOIDmode, label2)));
3556 emit_label (label1);
3557 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3558 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3559 (BITMASK_HIGH, SImode)));
3561 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3562 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3564 emit_label (label2);
3566 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3567 fields, and can't be used for REG_NOTES anyway). */
3568 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3573 (define_expand "fixuns_truncsfdi2"
3574 [(set (match_operand:DI 0 "register_operand")
3575 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3576 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3578 rtx reg1 = gen_reg_rtx (SFmode);
3579 rtx reg2 = gen_reg_rtx (SFmode);
3580 rtx reg3 = gen_reg_rtx (DImode);
3581 rtx label1 = gen_label_rtx ();
3582 rtx label2 = gen_label_rtx ();
3583 REAL_VALUE_TYPE offset;
3585 real_2expN (&offset, 63);
3587 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3588 do_pending_stack_adjust ();
3590 emit_insn (gen_cmpsf (operands[1], reg1));
3591 emit_jump_insn (gen_bge (label1));
3593 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3594 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3595 gen_rtx_LABEL_REF (VOIDmode, label2)));
3598 emit_label (label1);
3599 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3600 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3601 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3603 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3604 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3606 emit_label (label2);
3608 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3609 fields, and can't be used for REG_NOTES anyway). */
3610 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3615 ;; ....................
3619 ;; ....................
3621 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3623 (define_expand "extv"
3624 [(set (match_operand 0 "register_operand")
3625 (sign_extract (match_operand:QI 1 "memory_operand")
3626 (match_operand 2 "immediate_operand")
3627 (match_operand 3 "immediate_operand")))]
3630 if (mips_expand_unaligned_load (operands[0], operands[1],
3631 INTVAL (operands[2]),
3632 INTVAL (operands[3])))
3638 (define_expand "extzv"
3639 [(set (match_operand 0 "register_operand")
3640 (zero_extract (match_operand:QI 1 "memory_operand")
3641 (match_operand 2 "immediate_operand")
3642 (match_operand 3 "immediate_operand")))]
3645 if (mips_expand_unaligned_load (operands[0], operands[1],
3646 INTVAL (operands[2]),
3647 INTVAL (operands[3])))
3653 (define_expand "insv"
3654 [(set (zero_extract (match_operand:QI 0 "memory_operand")
3655 (match_operand 1 "immediate_operand")
3656 (match_operand 2 "immediate_operand"))
3657 (match_operand 3 "reg_or_0_operand"))]
3660 if (mips_expand_unaligned_store (operands[0], operands[3],
3661 INTVAL (operands[1]),
3662 INTVAL (operands[2])))
3668 ;; Unaligned word moves generated by the bit field patterns.
3670 ;; As far as the rtl is concerned, both the left-part and right-part
3671 ;; instructions can access the whole field. However, the real operand
3672 ;; refers to just the first or the last byte (depending on endianness).
3673 ;; We therefore use two memory operands to each instruction, one to
3674 ;; describe the rtl effect and one to use in the assembly output.
3676 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3677 ;; This allows us to use the standard length calculations for the "load"
3678 ;; and "store" type attributes.
3680 (define_insn "mov_lwl"
3681 [(set (match_operand:SI 0 "register_operand" "=d")
3682 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3683 (match_operand:QI 2 "memory_operand" "m")]
3687 [(set_attr "type" "load")
3688 (set_attr "mode" "SI")
3689 (set_attr "hazard" "none")])
3691 (define_insn "mov_lwr"
3692 [(set (match_operand:SI 0 "register_operand" "=d")
3693 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3694 (match_operand:QI 2 "memory_operand" "m")
3695 (match_operand:SI 3 "register_operand" "0")]
3699 [(set_attr "type" "load")
3700 (set_attr "mode" "SI")])
3703 (define_insn "mov_swl"
3704 [(set (match_operand:BLK 0 "memory_operand" "=m")
3705 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3706 (match_operand:QI 2 "memory_operand" "m")]
3710 [(set_attr "type" "store")
3711 (set_attr "mode" "SI")])
3713 (define_insn "mov_swr"
3714 [(set (match_operand:BLK 0 "memory_operand" "+m")
3715 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3716 (match_operand:QI 2 "memory_operand" "m")
3721 [(set_attr "type" "store")
3722 (set_attr "mode" "SI")])
3725 (define_insn "mov_ldl"
3726 [(set (match_operand:DI 0 "register_operand" "=d")
3727 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3728 (match_operand:QI 2 "memory_operand" "m")]
3730 "TARGET_64BIT && !TARGET_MIPS16"
3732 [(set_attr "type" "load")
3733 (set_attr "mode" "DI")])
3735 (define_insn "mov_ldr"
3736 [(set (match_operand:DI 0 "register_operand" "=d")
3737 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3738 (match_operand:QI 2 "memory_operand" "m")
3739 (match_operand:DI 3 "register_operand" "0")]
3741 "TARGET_64BIT && !TARGET_MIPS16"
3743 [(set_attr "type" "load")
3744 (set_attr "mode" "DI")])
3747 (define_insn "mov_sdl"
3748 [(set (match_operand:BLK 0 "memory_operand" "=m")
3749 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3750 (match_operand:QI 2 "memory_operand" "m")]
3752 "TARGET_64BIT && !TARGET_MIPS16"
3754 [(set_attr "type" "store")
3755 (set_attr "mode" "DI")])
3757 (define_insn "mov_sdr"
3758 [(set (match_operand:BLK 0 "memory_operand" "+m")
3759 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3760 (match_operand:QI 2 "memory_operand" "m")
3763 "TARGET_64BIT && !TARGET_MIPS16"
3765 [(set_attr "type" "store")
3766 (set_attr "mode" "DI")])
3768 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3769 ;; The required value is:
3771 ;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3773 ;; which translates to:
3775 ;; lui op0,%highest(op1)
3776 ;; daddiu op0,op0,%higher(op1)
3778 ;; daddiu op0,op0,%hi(op1)
3780 (define_insn_and_split "*lea_high64"
3781 [(set (match_operand:DI 0 "register_operand" "=d")
3782 (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3783 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3785 "&& reload_completed"
3786 [(set (match_dup 0) (high:DI (match_dup 2)))
3787 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3788 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3789 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3790 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3792 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3793 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3795 [(set_attr "length" "20")])
3797 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3798 ;; SYMBOL_GENERAL X will take 6 cycles. This next pattern allows combine
3799 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3800 ;; used once. We can then use the sequence:
3802 ;; lui op0,%highest(op1)
3804 ;; daddiu op0,op0,%higher(op1)
3805 ;; daddiu op2,op2,%lo(op1)
3807 ;; daddu op0,op0,op2
3809 ;; which takes 4 cycles on most superscalar targets.
3810 (define_insn_and_split "*lea64"
3811 [(set (match_operand:DI 0 "register_operand" "=d")
3812 (match_operand:DI 1 "general_symbolic_operand" ""))
3813 (clobber (match_scratch:DI 2 "=&d"))]
3814 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3816 "&& reload_completed"
3817 [(set (match_dup 0) (high:DI (match_dup 3)))
3818 (set (match_dup 2) (high:DI (match_dup 4)))
3819 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3820 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3821 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3822 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3824 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3825 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3827 [(set_attr "length" "24")])
3829 ;; Insns to fetch a global symbol from a big GOT.
3831 (define_insn_and_split "*xgot_hisi"
3832 [(set (match_operand:SI 0 "register_operand" "=d")
3833 (high:SI (match_operand:SI 1 "global_got_operand" "")))]
3834 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3836 "&& reload_completed"
3837 [(set (match_dup 0) (high:SI (match_dup 2)))
3838 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
3840 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3841 operands[3] = pic_offset_table_rtx;
3843 [(set_attr "got" "xgot_high")])
3845 (define_insn_and_split "*xgot_losi"
3846 [(set (match_operand:SI 0 "register_operand" "=d")
3847 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
3848 (match_operand:SI 2 "global_got_operand" "")))]
3849 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3851 "&& reload_completed"
3853 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3854 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3855 [(set_attr "got" "load")])
3857 (define_insn_and_split "*xgot_hidi"
3858 [(set (match_operand:DI 0 "register_operand" "=d")
3859 (high:DI (match_operand:DI 1 "global_got_operand" "")))]
3860 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3862 "&& reload_completed"
3863 [(set (match_dup 0) (high:DI (match_dup 2)))
3864 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
3866 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3867 operands[3] = pic_offset_table_rtx;
3869 [(set_attr "got" "xgot_high")])
3871 (define_insn_and_split "*xgot_lodi"
3872 [(set (match_operand:DI 0 "register_operand" "=d")
3873 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
3874 (match_operand:DI 2 "global_got_operand" "")))]
3875 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3877 "&& reload_completed"
3879 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3880 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3881 [(set_attr "got" "load")])
3883 ;; Insns to fetch a global symbol from a normal GOT.
3885 (define_insn_and_split "*got_dispsi"
3886 [(set (match_operand:SI 0 "register_operand" "=d")
3887 (match_operand:SI 1 "global_got_operand" ""))]
3888 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3890 "&& reload_completed"
3892 (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3894 operands[2] = pic_offset_table_rtx;
3895 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3897 [(set_attr "got" "load")])
3899 (define_insn_and_split "*got_dispdi"
3900 [(set (match_operand:DI 0 "register_operand" "=d")
3901 (match_operand:DI 1 "global_got_operand" ""))]
3902 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3904 "&& reload_completed"
3906 (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3908 operands[2] = pic_offset_table_rtx;
3909 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3911 [(set_attr "got" "load")])
3913 ;; Insns for loading the high part of a local symbol.
3915 (define_insn_and_split "*got_pagesi"
3916 [(set (match_operand:SI 0 "register_operand" "=d")
3917 (high:SI (match_operand:SI 1 "local_got_operand" "")))]
3918 "TARGET_EXPLICIT_RELOCS"
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_PAGE);
3927 [(set_attr "got" "load")])
3929 (define_insn_and_split "*got_pagedi"
3930 [(set (match_operand:DI 0 "register_operand" "=d")
3931 (high:DI (match_operand:DI 1 "local_got_operand" "")))]
3932 "TARGET_EXPLICIT_RELOCS"
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_PAGE);
3941 [(set_attr "got" "load")])
3943 ;; Lower-level instructions for loading an address from the GOT.
3944 ;; We could use MEMs, but an unspec gives more optimization
3947 (define_insn "*load_gotsi"
3948 [(set (match_operand:SI 0 "register_operand" "=d")
3949 (unspec:SI [(match_operand:SI 1 "register_operand" "d")
3950 (match_operand:SI 2 "immediate_operand" "")]
3954 [(set_attr "type" "load")
3955 (set_attr "length" "4")])
3957 (define_insn "*load_gotdi"
3958 [(set (match_operand:DI 0 "register_operand" "=d")
3959 (unspec:DI [(match_operand:DI 1 "register_operand" "d")
3960 (match_operand:DI 2 "immediate_operand" "")]
3964 [(set_attr "type" "load")
3965 (set_attr "length" "4")])
3967 ;; Instructions for adding the low 16 bits of an address to a register.
3968 ;; Operand 2 is the address: print_operand works out which relocation
3969 ;; should be applied.
3971 (define_insn "*lowsi"
3972 [(set (match_operand:SI 0 "register_operand" "=d")
3973 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
3974 (match_operand:SI 2 "immediate_operand" "")))]
3977 [(set_attr "type" "arith")
3978 (set_attr "mode" "SI")])
3980 (define_insn "*lowdi"
3981 [(set (match_operand:DI 0 "register_operand" "=d")
3982 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
3983 (match_operand:DI 2 "immediate_operand" "")))]
3984 "!TARGET_MIPS16 && TARGET_64BIT"
3986 [(set_attr "type" "arith")
3987 (set_attr "mode" "DI")])
3989 (define_insn "*lowsi_mips16"
3990 [(set (match_operand:SI 0 "register_operand" "=d")
3991 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
3992 (match_operand:SI 2 "immediate_operand" "")))]
3995 [(set_attr "type" "arith")
3996 (set_attr "mode" "SI")
3997 (set_attr "length" "8")])
3999 (define_insn "*lowdi_mips16"
4000 [(set (match_operand:DI 0 "register_operand" "=d")
4001 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
4002 (match_operand:DI 2 "immediate_operand" "")))]
4003 "TARGET_MIPS16 && TARGET_64BIT"
4005 [(set_attr "type" "arith")
4006 (set_attr "mode" "DI")
4007 (set_attr "length" "8")])
4009 ;; 64-bit integer moves
4011 ;; Unlike most other insns, the move insns can't be split with
4012 ;; different predicates, because register spilling and other parts of
4013 ;; the compiler, have memoized the insn number already.
4015 (define_expand "movdi"
4016 [(set (match_operand:DI 0 "")
4017 (match_operand:DI 1 ""))]
4020 if (mips_legitimize_move (DImode, operands[0], operands[1]))
4024 ;; For mips16, we need a special case to handle storing $31 into
4025 ;; memory, since we don't have a constraint to match $31. This
4026 ;; instruction can be generated by save_restore_insns.
4029 [(set (match_operand:DI 0 "stack_operand" "=m")
4031 "TARGET_MIPS16 && TARGET_64BIT"
4033 [(set_attr "type" "store")
4034 (set_attr "mode" "DI")])
4036 (define_insn "*movdi_32bit"
4037 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
4038 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
4039 "!TARGET_64BIT && !TARGET_MIPS16
4040 && (register_operand (operands[0], DImode)
4041 || reg_or_0_operand (operands[1], DImode))"
4042 { return mips_output_move (operands[0], operands[1]); }
4043 [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
4044 (set_attr "mode" "DI")
4045 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
4047 (define_insn "*movdi_32bit_mips16"
4048 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4049 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4050 "!TARGET_64BIT && TARGET_MIPS16
4051 && (register_operand (operands[0], DImode)
4052 || register_operand (operands[1], DImode))"
4053 { return mips_output_move (operands[0], operands[1]); }
4054 [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo")
4055 (set_attr "mode" "DI")
4056 (set_attr "length" "8,8,8,8,12,*,*,8")])
4058 (define_insn "*movdi_64bit"
4059 [(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")
4060 (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"))]
4061 "TARGET_64BIT && !TARGET_MIPS16
4062 && (register_operand (operands[0], DImode)
4063 || reg_or_0_operand (operands[1], DImode))"
4064 { return mips_output_move (operands[0], operands[1]); }
4065 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
4066 (set_attr "mode" "DI")
4067 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
4069 (define_insn "*movdi_64bit_mips16"
4070 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4071 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4072 "TARGET_64BIT && TARGET_MIPS16
4073 && (register_operand (operands[0], DImode)
4074 || register_operand (operands[1], DImode))"
4075 { return mips_output_move (operands[0], operands[1]); }
4076 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
4077 (set_attr "mode" "DI")
4078 (set_attr_alternative "length"
4082 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4085 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4090 (const_string "*")])])
4093 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4094 ;; when the original load is a 4 byte instruction but the add and the
4095 ;; load are 2 2 byte instructions.
4098 [(set (match_operand:DI 0 "register_operand")
4099 (mem:DI (plus:DI (match_dup 0)
4100 (match_operand:DI 1 "const_int_operand"))))]
4101 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4102 && !TARGET_DEBUG_D_MODE
4103 && GET_CODE (operands[0]) == REG
4104 && M16_REG_P (REGNO (operands[0]))
4105 && GET_CODE (operands[1]) == CONST_INT
4106 && ((INTVAL (operands[1]) < 0
4107 && INTVAL (operands[1]) >= -0x10)
4108 || (INTVAL (operands[1]) >= 32 * 8
4109 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4110 || (INTVAL (operands[1]) >= 0
4111 && INTVAL (operands[1]) < 32 * 8
4112 && (INTVAL (operands[1]) & 7) != 0))"
4113 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4114 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4116 HOST_WIDE_INT val = INTVAL (operands[1]);
4119 operands[2] = const0_rtx;
4120 else if (val >= 32 * 8)
4124 operands[1] = GEN_INT (0x8 + off);
4125 operands[2] = GEN_INT (val - off - 0x8);
4131 operands[1] = GEN_INT (off);
4132 operands[2] = GEN_INT (val - off);
4136 ;; 32-bit Integer moves
4138 ;; Unlike most other insns, the move insns can't be split with
4139 ;; different predicates, because register spilling and other parts of
4140 ;; the compiler, have memoized the insn number already.
4142 (define_expand "movsi"
4143 [(set (match_operand:SI 0 "")
4144 (match_operand:SI 1 ""))]
4147 if (mips_legitimize_move (SImode, operands[0], operands[1]))
4151 ;; We can only store $ra directly into a small sp offset.
4154 [(set (match_operand:SI 0 "stack_operand" "=m")
4158 [(set_attr "type" "store")
4159 (set_attr "mode" "SI")])
4161 ;; The difference between these two is whether or not ints are allowed
4162 ;; in FP registers (off by default, use -mdebugh to enable).
4164 (define_insn "*movsi_internal"
4165 [(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")
4166 (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"))]
4168 && (register_operand (operands[0], SImode)
4169 || reg_or_0_operand (operands[1], SImode))"
4170 { return mips_output_move (operands[0], operands[1]); }
4171 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
4172 (set_attr "mode" "SI")
4173 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
4175 (define_insn "*movsi_mips16"
4176 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4177 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4179 && (register_operand (operands[0], SImode)
4180 || register_operand (operands[1], SImode))"
4181 { return mips_output_move (operands[0], operands[1]); }
4182 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
4183 (set_attr "mode" "SI")
4184 (set_attr_alternative "length"
4188 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4191 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4196 (const_string "*")])])
4198 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4199 ;; when the original load is a 4 byte instruction but the add and the
4200 ;; load are 2 2 byte instructions.
4203 [(set (match_operand:SI 0 "register_operand")
4204 (mem:SI (plus:SI (match_dup 0)
4205 (match_operand:SI 1 "const_int_operand"))))]
4206 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4207 && GET_CODE (operands[0]) == REG
4208 && M16_REG_P (REGNO (operands[0]))
4209 && GET_CODE (operands[1]) == CONST_INT
4210 && ((INTVAL (operands[1]) < 0
4211 && INTVAL (operands[1]) >= -0x80)
4212 || (INTVAL (operands[1]) >= 32 * 4
4213 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4214 || (INTVAL (operands[1]) >= 0
4215 && INTVAL (operands[1]) < 32 * 4
4216 && (INTVAL (operands[1]) & 3) != 0))"
4217 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4218 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4220 HOST_WIDE_INT val = INTVAL (operands[1]);
4223 operands[2] = const0_rtx;
4224 else if (val >= 32 * 4)
4228 operands[1] = GEN_INT (0x7c + off);
4229 operands[2] = GEN_INT (val - off - 0x7c);
4235 operands[1] = GEN_INT (off);
4236 operands[2] = GEN_INT (val - off);
4240 ;; On the mips16, we can split a load of certain constants into a load
4241 ;; and an add. This turns a 4 byte instruction into 2 2 byte
4245 [(set (match_operand:SI 0 "register_operand")
4246 (match_operand:SI 1 "const_int_operand"))]
4247 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4248 && GET_CODE (operands[0]) == REG
4249 && M16_REG_P (REGNO (operands[0]))
4250 && GET_CODE (operands[1]) == CONST_INT
4251 && INTVAL (operands[1]) >= 0x100
4252 && INTVAL (operands[1]) <= 0xff + 0x7f"
4253 [(set (match_dup 0) (match_dup 1))
4254 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4256 int val = INTVAL (operands[1]);
4258 operands[1] = GEN_INT (0xff);
4259 operands[2] = GEN_INT (val - 0xff);
4262 ;; This insn handles moving CCmode values. It's really just a
4263 ;; slightly simplified copy of movsi_internal2, with additional cases
4264 ;; to move a condition register to a general register and to move
4265 ;; between the general registers and the floating point registers.
4267 (define_insn "movcc"
4268 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
4269 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
4270 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4271 { return mips_output_move (operands[0], operands[1]); }
4272 [(set_attr "type" "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
4273 (set_attr "mode" "SI")
4274 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
4276 ;; Reload condition code registers. reload_incc and reload_outcc
4277 ;; both handle moves from arbitrary operands into condition code
4278 ;; registers. reload_incc handles the more common case in which
4279 ;; a source operand is constrained to be in a condition-code
4280 ;; register, but has not been allocated to one.
4282 ;; Sometimes, such as in movcc, we have a CCmode destination whose
4283 ;; constraints do not include 'z'. reload_outcc handles the case
4284 ;; when such an operand is allocated to a condition-code register.
4286 ;; Note that reloads from a condition code register to some
4287 ;; other location can be done using ordinary moves. Moving
4288 ;; into a GPR takes a single movcc, moving elsewhere takes
4289 ;; two. We can leave these cases to the generic reload code.
4290 (define_expand "reload_incc"
4291 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
4292 (match_operand:CC 1 "general_operand" ""))
4293 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4294 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4296 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4300 (define_expand "reload_outcc"
4301 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
4302 (match_operand:CC 1 "register_operand" ""))
4303 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4304 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4306 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4310 ;; MIPS4 supports loading and storing a floating point register from
4311 ;; the sum of two general registers. We use two versions for each of
4312 ;; these four instructions: one where the two general registers are
4313 ;; SImode, and one where they are DImode. This is because general
4314 ;; registers will be in SImode when they hold 32 bit values, but,
4315 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
4316 ;; instructions will still work correctly.
4318 ;; ??? Perhaps it would be better to support these instructions by
4319 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
4320 ;; these instructions can only be used to load and store floating
4321 ;; point registers, that would probably cause trouble in reload.
4324 [(set (match_operand:SF 0 "register_operand" "=f")
4325 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4326 (match_operand:SI 2 "register_operand" "d"))))]
4327 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4329 [(set_attr "type" "fpidxload")
4330 (set_attr "mode" "SF")
4331 (set_attr "length" "4")])
4334 [(set (match_operand:SF 0 "register_operand" "=f")
4335 (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4336 (match_operand:DI 2 "register_operand" "d"))))]
4337 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4339 [(set_attr "type" "fpidxload")
4340 (set_attr "mode" "SF")
4341 (set_attr "length" "4")])
4344 [(set (match_operand:DF 0 "register_operand" "=f")
4345 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4346 (match_operand:SI 2 "register_operand" "d"))))]
4347 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4349 [(set_attr "type" "fpidxload")
4350 (set_attr "mode" "DF")
4351 (set_attr "length" "4")])
4354 [(set (match_operand:DF 0 "register_operand" "=f")
4355 (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4356 (match_operand:DI 2 "register_operand" "d"))))]
4357 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4359 [(set_attr "type" "fpidxload")
4360 (set_attr "mode" "DF")
4361 (set_attr "length" "4")])
4364 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4365 (match_operand:SI 2 "register_operand" "d")))
4366 (match_operand:SF 0 "register_operand" "f"))]
4367 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4369 [(set_attr "type" "fpidxstore")
4370 (set_attr "mode" "SF")
4371 (set_attr "length" "4")])
4374 [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4375 (match_operand:DI 2 "register_operand" "d")))
4376 (match_operand:SF 0 "register_operand" "f"))]
4377 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4379 [(set_attr "type" "fpidxstore")
4380 (set_attr "mode" "SF")
4381 (set_attr "length" "4")])
4384 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4385 (match_operand:SI 2 "register_operand" "d")))
4386 (match_operand:DF 0 "register_operand" "f"))]
4387 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4389 [(set_attr "type" "fpidxstore")
4390 (set_attr "mode" "DF")
4391 (set_attr "length" "4")])
4394 [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4395 (match_operand:DI 2 "register_operand" "d")))
4396 (match_operand:DF 0 "register_operand" "f"))]
4397 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4399 [(set_attr "type" "fpidxstore")
4400 (set_attr "mode" "DF")
4401 (set_attr "length" "4")])
4403 ;; 16-bit Integer moves
4405 ;; Unlike most other insns, the move insns can't be split with
4406 ;; different predicates, because register spilling and other parts of
4407 ;; the compiler, have memoized the insn number already.
4408 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4410 (define_expand "movhi"
4411 [(set (match_operand:HI 0 "")
4412 (match_operand:HI 1 ""))]
4415 if (mips_legitimize_move (HImode, operands[0], operands[1]))
4419 (define_insn "*movhi_internal"
4420 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4421 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4423 && (register_operand (operands[0], HImode)
4424 || reg_or_0_operand (operands[1], HImode))"
4434 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4435 (set_attr "mode" "HI")
4436 (set_attr "length" "4,4,*,*,4,4,4,4")])
4438 (define_insn "*movhi_mips16"
4439 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4440 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))]
4442 && (register_operand (operands[0], HImode)
4443 || register_operand (operands[1], HImode))"
4452 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4453 (set_attr "mode" "HI")
4454 (set_attr_alternative "length"
4458 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4461 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4465 (const_string "*")])])
4468 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4469 ;; when the original load is a 4 byte instruction but the add and the
4470 ;; load are 2 2 byte instructions.
4473 [(set (match_operand:HI 0 "register_operand")
4474 (mem:HI (plus:SI (match_dup 0)
4475 (match_operand:SI 1 "const_int_operand"))))]
4476 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4477 && GET_CODE (operands[0]) == REG
4478 && M16_REG_P (REGNO (operands[0]))
4479 && GET_CODE (operands[1]) == CONST_INT
4480 && ((INTVAL (operands[1]) < 0
4481 && INTVAL (operands[1]) >= -0x80)
4482 || (INTVAL (operands[1]) >= 32 * 2
4483 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4484 || (INTVAL (operands[1]) >= 0
4485 && INTVAL (operands[1]) < 32 * 2
4486 && (INTVAL (operands[1]) & 1) != 0))"
4487 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4488 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4490 HOST_WIDE_INT val = INTVAL (operands[1]);
4493 operands[2] = const0_rtx;
4494 else if (val >= 32 * 2)
4498 operands[1] = GEN_INT (0x7e + off);
4499 operands[2] = GEN_INT (val - off - 0x7e);
4505 operands[1] = GEN_INT (off);
4506 operands[2] = GEN_INT (val - off);
4510 ;; 8-bit Integer moves
4512 ;; Unlike most other insns, the move insns can't be split with
4513 ;; different predicates, because register spilling and other parts of
4514 ;; the compiler, have memoized the insn number already.
4515 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4517 (define_expand "movqi"
4518 [(set (match_operand:QI 0 "")
4519 (match_operand:QI 1 ""))]
4522 if (mips_legitimize_move (QImode, operands[0], operands[1]))
4526 (define_insn "*movqi_internal"
4527 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4528 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4530 && (register_operand (operands[0], QImode)
4531 || reg_or_0_operand (operands[1], QImode))"
4541 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4542 (set_attr "mode" "QI")
4543 (set_attr "length" "4,4,*,*,4,4,4,4")])
4545 (define_insn "*movqi_mips16"
4546 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4547 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))]
4549 && (register_operand (operands[0], QImode)
4550 || register_operand (operands[1], QImode))"
4559 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4560 (set_attr "mode" "QI")
4561 (set_attr "length" "4,4,4,4,8,*,*")])
4563 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
4564 ;; when the original load is a 4 byte instruction but the add and the
4565 ;; load are 2 2 byte instructions.
4568 [(set (match_operand:QI 0 "register_operand")
4569 (mem:QI (plus:SI (match_dup 0)
4570 (match_operand:SI 1 "const_int_operand"))))]
4571 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4572 && GET_CODE (operands[0]) == REG
4573 && M16_REG_P (REGNO (operands[0]))
4574 && GET_CODE (operands[1]) == CONST_INT
4575 && ((INTVAL (operands[1]) < 0
4576 && INTVAL (operands[1]) >= -0x80)
4577 || (INTVAL (operands[1]) >= 32
4578 && INTVAL (operands[1]) <= 31 + 0x7f))"
4579 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4580 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4582 HOST_WIDE_INT val = INTVAL (operands[1]);
4585 operands[2] = const0_rtx;
4588 operands[1] = GEN_INT (0x7f);
4589 operands[2] = GEN_INT (val - 0x7f);
4593 ;; 32-bit floating point moves
4595 (define_expand "movsf"
4596 [(set (match_operand:SF 0 "")
4597 (match_operand:SF 1 ""))]
4600 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4604 (define_insn "*movsf_hardfloat"
4605 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4606 (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
4608 && (register_operand (operands[0], SFmode)
4609 || reg_or_0_operand (operands[1], SFmode))"
4610 { return mips_output_move (operands[0], operands[1]); }
4611 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4612 (set_attr "mode" "SF")
4613 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4615 (define_insn "*movsf_softfloat"
4616 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4617 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
4618 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4619 && (register_operand (operands[0], SFmode)
4620 || reg_or_0_operand (operands[1], SFmode))"
4621 { return mips_output_move (operands[0], operands[1]); }
4622 [(set_attr "type" "arith,load,store")
4623 (set_attr "mode" "SF")
4624 (set_attr "length" "4,*,*")])
4626 (define_insn "*movsf_mips16"
4627 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4628 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
4630 && (register_operand (operands[0], SFmode)
4631 || register_operand (operands[1], SFmode))"
4632 { return mips_output_move (operands[0], operands[1]); }
4633 [(set_attr "type" "arith,arith,arith,load,store")
4634 (set_attr "mode" "SF")
4635 (set_attr "length" "4,4,4,*,*")])
4638 ;; 64-bit floating point moves
4640 (define_expand "movdf"
4641 [(set (match_operand:DF 0 "")
4642 (match_operand:DF 1 ""))]
4645 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4649 (define_insn "*movdf_hardfloat_64bit"
4650 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4651 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4652 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
4653 && (register_operand (operands[0], DFmode)
4654 || reg_or_0_operand (operands[1], DFmode))"
4655 { return mips_output_move (operands[0], operands[1]); }
4656 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4657 (set_attr "mode" "DF")
4658 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4660 (define_insn "*movdf_hardfloat_32bit"
4661 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4662 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4663 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
4664 && (register_operand (operands[0], DFmode)
4665 || reg_or_0_operand (operands[1], DFmode))"
4666 { return mips_output_move (operands[0], operands[1]); }
4667 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4668 (set_attr "mode" "DF")
4669 (set_attr "length" "4,8,*,*,8,8,8,*,*")])
4671 (define_insn "*movdf_softfloat"
4672 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
4673 (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
4674 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4675 && (register_operand (operands[0], DFmode)
4676 || reg_or_0_operand (operands[1], DFmode))"
4677 { return mips_output_move (operands[0], operands[1]); }
4678 [(set_attr "type" "arith,load,store,xfer,xfer,fmove")
4679 (set_attr "mode" "DF")
4680 (set_attr "length" "8,*,*,4,4,4")])
4682 (define_insn "*movdf_mips16"
4683 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4684 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4686 && (register_operand (operands[0], DFmode)
4687 || register_operand (operands[1], DFmode))"
4688 { return mips_output_move (operands[0], operands[1]); }
4689 [(set_attr "type" "arith,arith,arith,load,store")
4690 (set_attr "mode" "DF")
4691 (set_attr "length" "8,8,8,*,*")])
4694 [(set (match_operand:DI 0 "nonimmediate_operand")
4695 (match_operand:DI 1 "move_operand"))]
4696 "reload_completed && !TARGET_64BIT
4697 && mips_split_64bit_move_p (operands[0], operands[1])"
4700 mips_split_64bit_move (operands[0], operands[1]);
4705 [(set (match_operand:DF 0 "nonimmediate_operand")
4706 (match_operand:DF 1 "move_operand"))]
4707 "reload_completed && !TARGET_64BIT
4708 && mips_split_64bit_move_p (operands[0], operands[1])"
4711 mips_split_64bit_move (operands[0], operands[1]);
4715 ;; When generating mips16 code, split moves of negative constants into
4716 ;; a positive "li" followed by a negation.
4718 [(set (match_operand 0 "register_operand")
4719 (match_operand 1 "const_int_operand"))]
4720 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4724 (neg:SI (match_dup 2)))]
4726 operands[2] = gen_lowpart (SImode, operands[0]);
4727 operands[3] = GEN_INT (-INTVAL (operands[1]));
4730 ;; The HI and LO registers are not truly independent. If we move an mthi
4731 ;; instruction before an mflo instruction, it will make the result of the
4732 ;; mflo unpredictable. The same goes for mtlo and mfhi.
4734 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4735 ;; Operand 1 is the register we want, operand 2 is the other one.
4737 (define_insn "mfhilo_di"
4738 [(set (match_operand:DI 0 "register_operand" "=d,d")
4739 (unspec:DI [(match_operand:DI 1 "register_operand" "h,l")
4740 (match_operand:DI 2 "register_operand" "l,h")]
4744 [(set_attr "type" "mfhilo")])
4746 (define_insn "mfhilo_si"
4747 [(set (match_operand:SI 0 "register_operand" "=d,d")
4748 (unspec:SI [(match_operand:SI 1 "register_operand" "h,l")
4749 (match_operand:SI 2 "register_operand" "l,h")]
4753 [(set_attr "type" "mfhilo")])
4755 ;; Patterns for loading or storing part of a paired floating point
4756 ;; register. We need them because odd-numbered floating-point registers
4757 ;; are not fully independent: see mips_split_64bit_move.
4759 ;; Load the low word of operand 0 with operand 1.
4760 (define_insn "load_df_low"
4761 [(set (match_operand:DF 0 "register_operand" "=f,f")
4762 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
4763 UNSPEC_LOAD_DF_LOW))]
4764 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4766 operands[0] = mips_subword (operands[0], 0);
4767 return mips_output_move (operands[0], operands[1]);
4769 [(set_attr "type" "xfer,fpload")
4770 (set_attr "mode" "SF")])
4772 ;; Load the high word of operand 0 from operand 1, preserving the value
4774 (define_insn "load_df_high"
4775 [(set (match_operand:DF 0 "register_operand" "=f,f")
4776 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
4777 (match_operand:DF 2 "register_operand" "0,0")]
4778 UNSPEC_LOAD_DF_HIGH))]
4779 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4781 operands[0] = mips_subword (operands[0], 1);
4782 return mips_output_move (operands[0], operands[1]);
4784 [(set_attr "type" "xfer,fpload")
4785 (set_attr "mode" "SF")])
4787 ;; Store the high word of operand 1 in operand 0. The corresponding
4788 ;; low-word move is done in the normal way.
4789 (define_insn "store_df_high"
4790 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4791 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4792 UNSPEC_STORE_DF_HIGH))]
4793 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4795 operands[1] = mips_subword (operands[1], 1);
4796 return mips_output_move (operands[0], operands[1]);
4798 [(set_attr "type" "xfer,fpstore")
4799 (set_attr "mode" "SF")])
4801 ;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
4802 ;; of _gp from the start of this function. Operand 1 is the incoming
4803 ;; function address.
4804 (define_insn_and_split "loadgp"
4805 [(unspec_volatile [(match_operand 0 "" "")
4806 (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4807 "TARGET_ABICALLS && TARGET_NEWABI"
4810 [(set (match_dup 2) (match_dup 3))
4811 (set (match_dup 2) (match_dup 4))
4812 (set (match_dup 2) (match_dup 5))]
4814 operands[2] = pic_offset_table_rtx;
4815 operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4816 operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4817 operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4819 [(set_attr "length" "12")])
4821 ;; The use of gp is hidden when not using explicit relocations.
4822 ;; This blockage instruction prevents the gp load from being
4823 ;; scheduled after an implicit use of gp. It also prevents
4824 ;; the load from being deleted as dead.
4825 (define_insn "loadgp_blockage"
4826 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4829 [(set_attr "type" "unknown")
4830 (set_attr "mode" "none")
4831 (set_attr "length" "0")])
4833 ;; Emit a .cprestore directive, which normally expands to a single store
4834 ;; instruction. Note that we continue to use .cprestore for explicit reloc
4835 ;; code so that jals inside inline asms will work correctly.
4836 (define_insn "cprestore"
4837 [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
4841 if (set_nomacro && which_alternative == 1)
4842 return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4844 return ".cprestore\t%0";
4846 [(set_attr "type" "store")
4847 (set_attr "length" "4,12")])
4849 ;; Block moves, see mips.c for more details.
4850 ;; Argument 0 is the destination
4851 ;; Argument 1 is the source
4852 ;; Argument 2 is the length
4853 ;; Argument 3 is the alignment
4855 (define_expand "movmemsi"
4856 [(parallel [(set (match_operand:BLK 0 "general_operand")
4857 (match_operand:BLK 1 "general_operand"))
4858 (use (match_operand:SI 2 ""))
4859 (use (match_operand:SI 3 "const_int_operand"))])]
4860 "!TARGET_MIPS16 && !TARGET_MEMCPY"
4862 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4869 ;; ....................
4873 ;; ....................
4875 ;; Many of these instructions use trivial define_expands, because we
4876 ;; want to use a different set of constraints when TARGET_MIPS16.
4878 (define_expand "ashlsi3"
4879 [(set (match_operand:SI 0 "register_operand")
4880 (ashift:SI (match_operand:SI 1 "register_operand")
4881 (match_operand:SI 2 "arith_operand")))]
4884 /* On the mips16, a shift of more than 8 is a four byte instruction,
4885 so, for a shift between 8 and 16, it is just as fast to do two
4886 shifts of 8 or less. If there is a lot of shifting going on, we
4887 may win in CSE. Otherwise combine will put the shifts back
4888 together again. This can be called by function_arg, so we must
4889 be careful not to allocate a new register if we've reached the
4893 && GET_CODE (operands[2]) == CONST_INT
4894 && INTVAL (operands[2]) > 8
4895 && INTVAL (operands[2]) <= 16
4896 && ! reload_in_progress
4897 && ! reload_completed)
4899 rtx temp = gen_reg_rtx (SImode);
4901 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
4902 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
4903 GEN_INT (INTVAL (operands[2]) - 8)));
4908 (define_insn "ashlsi3_internal1"
4909 [(set (match_operand:SI 0 "register_operand" "=d")
4910 (ashift:SI (match_operand:SI 1 "register_operand" "d")
4911 (match_operand:SI 2 "arith_operand" "dI")))]
4914 if (GET_CODE (operands[2]) == CONST_INT)
4915 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4917 return "sll\t%0,%1,%2";
4919 [(set_attr "type" "shift")
4920 (set_attr "mode" "SI")])
4922 (define_insn "ashlsi3_internal1_extend"
4923 [(set (match_operand:DI 0 "register_operand" "=d")
4924 (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
4925 (match_operand:SI 2 "arith_operand" "dI"))))]
4926 "TARGET_64BIT && !TARGET_MIPS16"
4928 if (GET_CODE (operands[2]) == CONST_INT)
4929 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4931 return "sll\t%0,%1,%2";
4933 [(set_attr "type" "shift")
4934 (set_attr "mode" "DI")])
4937 (define_insn "ashlsi3_internal2"
4938 [(set (match_operand:SI 0 "register_operand" "=d,d")
4939 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
4940 (match_operand:SI 2 "arith_operand" "d,I")))]
4943 if (which_alternative == 0)
4944 return "sll\t%0,%2";
4946 if (GET_CODE (operands[2]) == CONST_INT)
4947 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4949 return "sll\t%0,%1,%2";
4951 [(set_attr "type" "shift")
4952 (set_attr "mode" "SI")
4953 (set_attr_alternative "length"
4955 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4959 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4962 [(set (match_operand:SI 0 "register_operand")
4963 (ashift:SI (match_operand:SI 1 "register_operand")
4964 (match_operand:SI 2 "const_int_operand")))]
4965 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4966 && GET_CODE (operands[2]) == CONST_INT
4967 && INTVAL (operands[2]) > 8
4968 && INTVAL (operands[2]) <= 16"
4969 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
4970 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4971 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4973 (define_expand "ashldi3"
4974 [(set (match_operand:DI 0 "register_operand")
4975 (ashift:DI (match_operand:DI 1 "register_operand")
4976 (match_operand:SI 2 "arith_operand")))]
4979 /* On the mips16, a shift of more than 8 is a four byte
4980 instruction, so, for a shift between 8 and 16, it is just as
4981 fast to do two shifts of 8 or less. If there is a lot of
4982 shifting going on, we may win in CSE. Otherwise combine will
4983 put the shifts back together again. This can be called by
4984 function_arg, so we must be careful not to allocate a new
4985 register if we've reached the reload pass. */
4988 && GET_CODE (operands[2]) == CONST_INT
4989 && INTVAL (operands[2]) > 8
4990 && INTVAL (operands[2]) <= 16
4991 && ! reload_in_progress
4992 && ! reload_completed)
4994 rtx temp = gen_reg_rtx (DImode);
4996 emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
4997 emit_insn (gen_ashldi3_internal (operands[0], temp,
4998 GEN_INT (INTVAL (operands[2]) - 8)));
5004 (define_insn "ashldi3_internal"
5005 [(set (match_operand:DI 0 "register_operand" "=d")
5006 (ashift:DI (match_operand:DI 1 "register_operand" "d")
5007 (match_operand:SI 2 "arith_operand" "dI")))]
5008 "TARGET_64BIT && !TARGET_MIPS16"
5010 if (GET_CODE (operands[2]) == CONST_INT)
5011 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5013 return "dsll\t%0,%1,%2";
5015 [(set_attr "type" "shift")
5016 (set_attr "mode" "DI")])
5019 [(set (match_operand:DI 0 "register_operand" "=d,d")
5020 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
5021 (match_operand:SI 2 "arith_operand" "d,I")))]
5022 "TARGET_64BIT && TARGET_MIPS16"
5024 if (which_alternative == 0)
5025 return "dsll\t%0,%2";
5027 if (GET_CODE (operands[2]) == CONST_INT)
5028 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5030 return "dsll\t%0,%1,%2";
5032 [(set_attr "type" "shift")
5033 (set_attr "mode" "DI")
5034 (set_attr_alternative "length"
5036 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5041 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5044 [(set (match_operand:DI 0 "register_operand")
5045 (ashift:DI (match_operand:DI 1 "register_operand")
5046 (match_operand:SI 2 "const_int_operand")))]
5047 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5049 && GET_CODE (operands[2]) == CONST_INT
5050 && INTVAL (operands[2]) > 8
5051 && INTVAL (operands[2]) <= 16"
5052 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
5053 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
5054 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5056 (define_expand "ashrsi3"
5057 [(set (match_operand:SI 0 "register_operand")
5058 (ashiftrt:SI (match_operand:SI 1 "register_operand")
5059 (match_operand:SI 2 "arith_operand")))]
5062 /* On the mips16, a shift of more than 8 is a four byte instruction,
5063 so, for a shift between 8 and 16, it is just as fast to do two
5064 shifts of 8 or less. If there is a lot of shifting going on, we
5065 may win in CSE. Otherwise combine will put the shifts back
5069 && GET_CODE (operands[2]) == CONST_INT
5070 && INTVAL (operands[2]) > 8
5071 && INTVAL (operands[2]) <= 16)
5073 rtx temp = gen_reg_rtx (SImode);
5075 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5076 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
5077 GEN_INT (INTVAL (operands[2]) - 8)));
5082 (define_insn "ashrsi3_internal1"
5083 [(set (match_operand:SI 0 "register_operand" "=d")
5084 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
5085 (match_operand:SI 2 "arith_operand" "dI")))]
5088 if (GET_CODE (operands[2]) == CONST_INT)
5089 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5091 return "sra\t%0,%1,%2";
5093 [(set_attr "type" "shift")
5094 (set_attr "mode" "SI")])
5096 (define_insn "ashrsi3_internal2"
5097 [(set (match_operand:SI 0 "register_operand" "=d,d")
5098 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5099 (match_operand:SI 2 "arith_operand" "d,I")))]
5102 if (which_alternative == 0)
5103 return "sra\t%0,%2";
5105 if (GET_CODE (operands[2]) == CONST_INT)
5106 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5108 return "sra\t%0,%1,%2";
5110 [(set_attr "type" "shift")
5111 (set_attr "mode" "SI")
5112 (set_attr_alternative "length"
5114 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5119 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5122 [(set (match_operand:SI 0 "register_operand")
5123 (ashiftrt:SI (match_operand:SI 1 "register_operand")
5124 (match_operand:SI 2 "const_int_operand")))]
5125 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5126 && GET_CODE (operands[2]) == CONST_INT
5127 && INTVAL (operands[2]) > 8
5128 && INTVAL (operands[2]) <= 16"
5129 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
5130 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
5131 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5133 (define_expand "ashrdi3"
5134 [(set (match_operand:DI 0 "register_operand")
5135 (ashiftrt:DI (match_operand:DI 1 "register_operand")
5136 (match_operand:SI 2 "arith_operand")))]
5139 /* On the mips16, a shift of more than 8 is a four byte
5140 instruction, so, for a shift between 8 and 16, it is just as
5141 fast to do two shifts of 8 or less. If there is a lot of
5142 shifting going on, we may win in CSE. Otherwise combine will
5143 put the shifts back together again. */
5146 && GET_CODE (operands[2]) == CONST_INT
5147 && INTVAL (operands[2]) > 8
5148 && INTVAL (operands[2]) <= 16)
5150 rtx temp = gen_reg_rtx (DImode);
5152 emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
5153 emit_insn (gen_ashrdi3_internal (operands[0], temp,
5154 GEN_INT (INTVAL (operands[2]) - 8)));
5160 (define_insn "ashrdi3_internal"
5161 [(set (match_operand:DI 0 "register_operand" "=d")
5162 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5163 (match_operand:SI 2 "arith_operand" "dI")))]
5164 "TARGET_64BIT && !TARGET_MIPS16"
5166 if (GET_CODE (operands[2]) == CONST_INT)
5167 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5169 return "dsra\t%0,%1,%2";
5171 [(set_attr "type" "shift")
5172 (set_attr "mode" "DI")])
5175 [(set (match_operand:DI 0 "register_operand" "=d,d")
5176 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5177 (match_operand:SI 2 "arith_operand" "d,I")))]
5178 "TARGET_64BIT && TARGET_MIPS16"
5180 if (GET_CODE (operands[2]) == CONST_INT)
5181 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5183 return "dsra\t%0,%2";
5185 [(set_attr "type" "shift")
5186 (set_attr "mode" "DI")
5187 (set_attr_alternative "length"
5189 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5193 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5196 [(set (match_operand:DI 0 "register_operand")
5197 (ashiftrt:DI (match_operand:DI 1 "register_operand")
5198 (match_operand:SI 2 "const_int_operand")))]
5199 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5201 && GET_CODE (operands[2]) == CONST_INT
5202 && INTVAL (operands[2]) > 8
5203 && INTVAL (operands[2]) <= 16"
5204 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
5205 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
5206 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5208 (define_expand "lshrsi3"
5209 [(set (match_operand:SI 0 "register_operand")
5210 (lshiftrt:SI (match_operand:SI 1 "register_operand")
5211 (match_operand:SI 2 "arith_operand")))]
5214 /* On the mips16, a shift of more than 8 is a four byte instruction,
5215 so, for a shift between 8 and 16, it is just as fast to do two
5216 shifts of 8 or less. If there is a lot of shifting going on, we
5217 may win in CSE. Otherwise combine will put the shifts back
5221 && GET_CODE (operands[2]) == CONST_INT
5222 && INTVAL (operands[2]) > 8
5223 && INTVAL (operands[2]) <= 16)
5225 rtx temp = gen_reg_rtx (SImode);
5227 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5228 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
5229 GEN_INT (INTVAL (operands[2]) - 8)));
5234 (define_insn "lshrsi3_internal1"
5235 [(set (match_operand:SI 0 "register_operand" "=d")
5236 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
5237 (match_operand:SI 2 "arith_operand" "dI")))]
5240 if (GET_CODE (operands[2]) == CONST_INT)
5241 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5243 return "srl\t%0,%1,%2";
5245 [(set_attr "type" "shift")
5246 (set_attr "mode" "SI")])
5248 (define_insn "lshrsi3_internal2"
5249 [(set (match_operand:SI 0 "register_operand" "=d,d")
5250 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5251 (match_operand:SI 2 "arith_operand" "d,I")))]
5254 if (which_alternative == 0)
5255 return "srl\t%0,%2";
5257 if (GET_CODE (operands[2]) == CONST_INT)
5258 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5260 return "srl\t%0,%1,%2";
5262 [(set_attr "type" "shift")
5263 (set_attr "mode" "SI")
5264 (set_attr_alternative "length"
5266 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5271 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5274 [(set (match_operand:SI 0 "register_operand")
5275 (lshiftrt:SI (match_operand:SI 1 "register_operand")
5276 (match_operand:SI 2 "const_int_operand")))]
5277 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5278 && GET_CODE (operands[2]) == CONST_INT
5279 && INTVAL (operands[2]) > 8
5280 && INTVAL (operands[2]) <= 16"
5281 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
5282 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5283 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5285 ;; If we load a byte on the mips16 as a bitfield, the resulting
5286 ;; sequence of instructions is too complicated for combine, because it
5287 ;; involves four instructions: a load, a shift, a constant load into a
5288 ;; register, and an and (the key problem here is that the mips16 does
5289 ;; not have and immediate). We recognize a shift of a load in order
5290 ;; to make it simple enough for combine to understand.
5292 ;; The length here is the worst case: the length of the split version
5293 ;; will be more accurate.
5294 (define_insn_and_split ""
5295 [(set (match_operand:SI 0 "register_operand" "=d")
5296 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5297 (match_operand:SI 2 "immediate_operand" "I")))]
5301 [(set (match_dup 0) (match_dup 1))
5302 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5304 [(set_attr "type" "load")
5305 (set_attr "mode" "SI")
5306 (set_attr "length" "16")])
5308 (define_expand "lshrdi3"
5309 [(set (match_operand:DI 0 "register_operand")
5310 (lshiftrt:DI (match_operand:DI 1 "register_operand")
5311 (match_operand:SI 2 "arith_operand")))]
5314 /* On the mips16, a shift of more than 8 is a four byte
5315 instruction, so, for a shift between 8 and 16, it is just as
5316 fast to do two shifts of 8 or less. If there is a lot of
5317 shifting going on, we may win in CSE. Otherwise combine will
5318 put the shifts back together again. */
5321 && GET_CODE (operands[2]) == CONST_INT
5322 && INTVAL (operands[2]) > 8
5323 && INTVAL (operands[2]) <= 16)
5325 rtx temp = gen_reg_rtx (DImode);
5327 emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
5328 emit_insn (gen_lshrdi3_internal (operands[0], temp,
5329 GEN_INT (INTVAL (operands[2]) - 8)));
5335 (define_insn "lshrdi3_internal"
5336 [(set (match_operand:DI 0 "register_operand" "=d")
5337 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
5338 (match_operand:SI 2 "arith_operand" "dI")))]
5339 "TARGET_64BIT && !TARGET_MIPS16"
5341 if (GET_CODE (operands[2]) == CONST_INT)
5342 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5344 return "dsrl\t%0,%1,%2";
5346 [(set_attr "type" "shift")
5347 (set_attr "mode" "DI")])
5350 [(set (match_operand:DI 0 "register_operand" "=d,d")
5351 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5352 (match_operand:SI 2 "arith_operand" "d,I")))]
5353 "TARGET_64BIT && TARGET_MIPS16"
5355 if (GET_CODE (operands[2]) == CONST_INT)
5356 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5358 return "dsrl\t%0,%2";
5360 [(set_attr "type" "shift")
5361 (set_attr "mode" "DI")
5362 (set_attr_alternative "length"
5364 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5368 (define_insn "rotrsi3"
5369 [(set (match_operand:SI 0 "register_operand" "=d")
5370 (rotatert:SI (match_operand:SI 1 "register_operand" "d")
5371 (match_operand:SI 2 "arith_operand" "dn")))]
5374 if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
5375 return "rorv\t%0,%1,%2";
5377 if ((GET_CODE (operands[2]) == CONST_INT)
5378 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
5381 return "ror\t%0,%1,%2";
5383 [(set_attr "type" "shift")
5384 (set_attr "mode" "SI")])
5386 (define_insn "rotrdi3"
5387 [(set (match_operand:DI 0 "register_operand" "=d")
5388 (rotatert:DI (match_operand:DI 1 "register_operand" "d")
5389 (match_operand:DI 2 "arith_operand" "dn")))]
5394 if (GET_CODE (operands[2]) != CONST_INT)
5395 return "drorv\t%0,%1,%2";
5397 if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
5398 return "dror32\t%0,%1,%2";
5401 if ((GET_CODE (operands[2]) == CONST_INT)
5402 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
5405 return "dror\t%0,%1,%2";
5407 [(set_attr "type" "shift")
5408 (set_attr "mode" "DI")])
5411 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5414 [(set (match_operand:DI 0 "register_operand")
5415 (lshiftrt:DI (match_operand:DI 1 "register_operand")
5416 (match_operand:SI 2 "const_int_operand")))]
5417 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5418 && GET_CODE (operands[2]) == CONST_INT
5419 && INTVAL (operands[2]) > 8
5420 && INTVAL (operands[2]) <= 16"
5421 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
5422 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
5423 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5426 ;; ....................
5430 ;; ....................
5432 ;; Flow here is rather complex:
5434 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the arguments
5435 ;; into cmp_operands[] but generates no RTL.
5437 ;; 2) The appropriate branch define_expand is called, which then
5438 ;; creates the appropriate RTL for the comparison and branch.
5439 ;; Different CC modes are used, based on what type of branch is
5440 ;; done, so that we can constrain things appropriately. There
5441 ;; are assumptions in the rest of GCC that break if we fold the
5442 ;; operands into the branches for integer operations, and use cc0
5443 ;; for floating point, so we use the fp status register instead.
5444 ;; If needed, an appropriate temporary is created to hold the
5445 ;; of the integer compare.
5447 (define_expand "cmpsi"
5449 (compare:CC (match_operand:SI 0 "register_operand")
5450 (match_operand:SI 1 "nonmemory_operand")))]
5453 cmp_operands[0] = operands[0];
5454 cmp_operands[1] = operands[1];
5458 (define_expand "cmpdi"
5460 (compare:CC (match_operand:DI 0 "register_operand")
5461 (match_operand:DI 1 "nonmemory_operand")))]
5464 cmp_operands[0] = operands[0];
5465 cmp_operands[1] = operands[1];
5469 (define_expand "cmpdf"
5471 (compare:CC (match_operand:DF 0 "register_operand")
5472 (match_operand:DF 1 "register_operand")))]
5473 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5475 cmp_operands[0] = operands[0];
5476 cmp_operands[1] = operands[1];
5480 (define_expand "cmpsf"
5482 (compare:CC (match_operand:SF 0 "register_operand")
5483 (match_operand:SF 1 "register_operand")))]
5486 cmp_operands[0] = operands[0];
5487 cmp_operands[1] = operands[1];
5492 ;; ....................
5494 ;; CONDITIONAL BRANCHES
5496 ;; ....................
5498 ;; Conditional branches on floating-point equality tests.
5500 (define_insn "branch_fp"
5503 (match_operator:CC 0 "comparison_operator"
5504 [(match_operand:CC 2 "register_operand" "z")
5506 (label_ref (match_operand 1 "" ""))
5510 return mips_output_conditional_branch (insn,
5512 /*two_operands_p=*/0,
5515 get_attr_length (insn));
5517 [(set_attr "type" "branch")
5518 (set_attr "mode" "none")])
5520 (define_insn "branch_fp_inverted"
5523 (match_operator:CC 0 "comparison_operator"
5524 [(match_operand:CC 2 "register_operand" "z")
5527 (label_ref (match_operand 1 "" ""))))]
5530 return mips_output_conditional_branch (insn,
5532 /*two_operands_p=*/0,
5535 get_attr_length (insn));
5537 [(set_attr "type" "branch")
5538 (set_attr "mode" "none")])
5540 ;; Conditional branches on comparisons with zero.
5542 (define_insn "branch_zero"
5545 (match_operator:SI 0 "comparison_operator"
5546 [(match_operand:SI 2 "register_operand" "d")
5548 (label_ref (match_operand 1 "" ""))
5552 return mips_output_conditional_branch (insn,
5554 /*two_operands_p=*/0,
5557 get_attr_length (insn));
5559 [(set_attr "type" "branch")
5560 (set_attr "mode" "none")])
5562 (define_insn "branch_zero_inverted"
5565 (match_operator:SI 0 "comparison_operator"
5566 [(match_operand:SI 2 "register_operand" "d")
5569 (label_ref (match_operand 1 "" ""))))]
5572 return mips_output_conditional_branch (insn,
5574 /*two_operands_p=*/0,
5577 get_attr_length (insn));
5579 [(set_attr "type" "branch")
5580 (set_attr "mode" "none")])
5582 (define_insn "branch_zero_di"
5585 (match_operator:DI 0 "comparison_operator"
5586 [(match_operand:DI 2 "register_operand" "d")
5588 (label_ref (match_operand 1 "" ""))
5592 return mips_output_conditional_branch (insn,
5594 /*two_operands_p=*/0,
5597 get_attr_length (insn));
5599 [(set_attr "type" "branch")
5600 (set_attr "mode" "none")])
5602 (define_insn "branch_zero_di_inverted"
5605 (match_operator:DI 0 "comparison_operator"
5606 [(match_operand:DI 2 "register_operand" "d")
5609 (label_ref (match_operand 1 "" ""))))]
5612 return mips_output_conditional_branch (insn,
5614 /*two_operands_p=*/0,
5617 get_attr_length (insn));
5619 [(set_attr "type" "branch")
5620 (set_attr "mode" "none")])
5622 ;; Conditional branch on equality comparison.
5624 (define_insn "branch_equality"
5627 (match_operator:SI 0 "equality_operator"
5628 [(match_operand:SI 2 "register_operand" "d")
5629 (match_operand:SI 3 "register_operand" "d")])
5630 (label_ref (match_operand 1 "" ""))
5634 return mips_output_conditional_branch (insn,
5636 /*two_operands_p=*/1,
5639 get_attr_length (insn));
5641 [(set_attr "type" "branch")
5642 (set_attr "mode" "none")])
5644 (define_insn "branch_equality_di"
5647 (match_operator:DI 0 "equality_operator"
5648 [(match_operand:DI 2 "register_operand" "d")
5649 (match_operand:DI 3 "register_operand" "d")])
5650 (label_ref (match_operand 1 "" ""))
5654 return mips_output_conditional_branch (insn,
5656 /*two_operands_p=*/1,
5659 get_attr_length (insn));
5661 [(set_attr "type" "branch")
5662 (set_attr "mode" "none")])
5664 (define_insn "branch_equality_inverted"
5667 (match_operator:SI 0 "equality_operator"
5668 [(match_operand:SI 2 "register_operand" "d")
5669 (match_operand:SI 3 "register_operand" "d")])
5671 (label_ref (match_operand 1 "" ""))))]
5674 return mips_output_conditional_branch (insn,
5676 /*two_operands_p=*/1,
5679 get_attr_length (insn));
5681 [(set_attr "type" "branch")
5682 (set_attr "mode" "none")])
5684 (define_insn "branch_equality_di_inverted"
5687 (match_operator:DI 0 "equality_operator"
5688 [(match_operand:DI 2 "register_operand" "d")
5689 (match_operand:DI 3 "register_operand" "d")])
5691 (label_ref (match_operand 1 "" ""))))]
5694 return mips_output_conditional_branch (insn,
5696 /*two_operands_p=*/1,
5699 get_attr_length (insn));
5701 [(set_attr "type" "branch")
5702 (set_attr "mode" "none")])
5709 (match_operator:SI 0 "equality_operator"
5710 [(match_operand:SI 1 "register_operand" "d,t")
5712 (match_operand 2 "pc_or_label_operand" "")
5713 (match_operand 3 "pc_or_label_operand" "")))]
5716 if (operands[2] != pc_rtx)
5718 if (which_alternative == 0)
5719 return "b%C0z\t%1,%2";
5721 return "bt%C0z\t%2";
5725 if (which_alternative == 0)
5726 return "b%N0z\t%1,%3";
5728 return "bt%N0z\t%3";
5731 [(set_attr "type" "branch")
5732 (set_attr "mode" "none")
5733 (set_attr "length" "8")])
5738 (match_operator:DI 0 "equality_operator"
5739 [(match_operand:DI 1 "register_operand" "d,t")
5741 (match_operand 2 "pc_or_label_operand" "")
5742 (match_operand 3 "pc_or_label_operand" "")))]
5745 if (operands[2] != pc_rtx)
5747 if (which_alternative == 0)
5748 return "b%C0z\t%1,%2";
5750 return "bt%C0z\t%2";
5754 if (which_alternative == 0)
5755 return "b%N0z\t%1,%3";
5757 return "bt%N0z\t%3";
5760 [(set_attr "type" "branch")
5761 (set_attr "mode" "none")
5762 (set_attr "length" "8")])
5764 (define_expand "bunordered"
5766 (if_then_else (unordered:CC (cc0)
5768 (label_ref (match_operand 0 ""))
5772 gen_conditional_branch (operands, UNORDERED);
5776 (define_expand "bordered"
5778 (if_then_else (ordered:CC (cc0)
5780 (label_ref (match_operand 0 ""))
5784 gen_conditional_branch (operands, ORDERED);
5788 (define_expand "bunlt"
5790 (if_then_else (unlt:CC (cc0)
5792 (label_ref (match_operand 0 ""))
5796 gen_conditional_branch (operands, UNLT);
5800 (define_expand "bunge"
5802 (if_then_else (unge:CC (cc0)
5804 (label_ref (match_operand 0 ""))
5808 gen_conditional_branch (operands, UNGE);
5812 (define_expand "buneq"
5814 (if_then_else (uneq:CC (cc0)
5816 (label_ref (match_operand 0 ""))
5820 gen_conditional_branch (operands, UNEQ);
5824 (define_expand "bltgt"
5826 (if_then_else (ltgt:CC (cc0)
5828 (label_ref (match_operand 0 ""))
5832 gen_conditional_branch (operands, LTGT);
5836 (define_expand "bunle"
5838 (if_then_else (unle:CC (cc0)
5840 (label_ref (match_operand 0 ""))
5844 gen_conditional_branch (operands, UNLE);
5848 (define_expand "bungt"
5850 (if_then_else (ungt:CC (cc0)
5852 (label_ref (match_operand 0 ""))
5856 gen_conditional_branch (operands, UNGT);
5860 (define_expand "beq"
5862 (if_then_else (eq:CC (cc0)
5864 (label_ref (match_operand 0 ""))
5868 gen_conditional_branch (operands, EQ);
5872 (define_expand "bne"
5874 (if_then_else (ne:CC (cc0)
5876 (label_ref (match_operand 0 ""))
5880 gen_conditional_branch (operands, NE);
5884 (define_expand "bgt"
5886 (if_then_else (gt:CC (cc0)
5888 (label_ref (match_operand 0 ""))
5892 gen_conditional_branch (operands, GT);
5896 (define_expand "bge"
5898 (if_then_else (ge:CC (cc0)
5900 (label_ref (match_operand 0 ""))
5904 gen_conditional_branch (operands, GE);
5908 (define_expand "blt"
5910 (if_then_else (lt:CC (cc0)
5912 (label_ref (match_operand 0 ""))
5916 gen_conditional_branch (operands, LT);
5920 (define_expand "ble"
5922 (if_then_else (le:CC (cc0)
5924 (label_ref (match_operand 0 ""))
5928 gen_conditional_branch (operands, LE);
5932 (define_expand "bgtu"
5934 (if_then_else (gtu:CC (cc0)
5936 (label_ref (match_operand 0 ""))
5940 gen_conditional_branch (operands, GTU);
5944 (define_expand "bgeu"
5946 (if_then_else (geu:CC (cc0)
5948 (label_ref (match_operand 0 ""))
5952 gen_conditional_branch (operands, GEU);
5956 (define_expand "bltu"
5958 (if_then_else (ltu:CC (cc0)
5960 (label_ref (match_operand 0 ""))
5964 gen_conditional_branch (operands, LTU);
5968 (define_expand "bleu"
5970 (if_then_else (leu:CC (cc0)
5972 (label_ref (match_operand 0 ""))
5976 gen_conditional_branch (operands, LEU);
5981 ;; ....................
5983 ;; SETTING A REGISTER FROM A COMPARISON
5985 ;; ....................
5987 (define_expand "seq"
5988 [(set (match_operand:SI 0 "register_operand")
5989 (eq:SI (match_dup 1)
5992 { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
5994 (define_insn "*seq_si"
5995 [(set (match_operand:SI 0 "register_operand" "=d")
5996 (eq:SI (match_operand:SI 1 "register_operand" "d")
6000 [(set_attr "type" "slt")
6001 (set_attr "mode" "SI")])
6003 (define_insn "*seq_si_mips16"
6004 [(set (match_operand:SI 0 "register_operand" "=t")
6005 (eq:SI (match_operand:SI 1 "register_operand" "d")
6009 [(set_attr "type" "slt")
6010 (set_attr "mode" "SI")])
6012 (define_insn "*seq_di"
6013 [(set (match_operand:DI 0 "register_operand" "=d")
6014 (eq:DI (match_operand:DI 1 "register_operand" "d")
6016 "TARGET_64BIT && !TARGET_MIPS16"
6018 [(set_attr "type" "slt")
6019 (set_attr "mode" "DI")])
6021 (define_insn "*seq_di_mips16"
6022 [(set (match_operand:DI 0 "register_operand" "=t")
6023 (eq:DI (match_operand:DI 1 "register_operand" "d")
6025 "TARGET_64BIT && TARGET_MIPS16"
6027 [(set_attr "type" "slt")
6028 (set_attr "mode" "DI")])
6030 ;; "sne" uses sltu instructions in which the first operand is $0.
6031 ;; This isn't possible in mips16 code.
6033 (define_expand "sne"
6034 [(set (match_operand:SI 0 "register_operand")
6035 (ne:SI (match_dup 1)
6038 { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
6040 (define_insn "*sne_si"
6041 [(set (match_operand:SI 0 "register_operand" "=d")
6042 (ne:SI (match_operand:SI 1 "register_operand" "d")
6046 [(set_attr "type" "slt")
6047 (set_attr "mode" "SI")])
6049 (define_insn "*sne_di"
6050 [(set (match_operand:DI 0 "register_operand" "=d")
6051 (ne:DI (match_operand:DI 1 "register_operand" "d")
6053 "TARGET_64BIT && !TARGET_MIPS16"
6055 [(set_attr "type" "slt")
6056 (set_attr "mode" "DI")])
6058 (define_expand "sgt"
6059 [(set (match_operand:SI 0 "register_operand")
6060 (gt:SI (match_dup 1)
6063 { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
6065 (define_insn "*sgt_si"
6066 [(set (match_operand:SI 0 "register_operand" "=d")
6067 (gt:SI (match_operand:SI 1 "register_operand" "d")
6068 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6071 [(set_attr "type" "slt")
6072 (set_attr "mode" "SI")])
6074 (define_insn "*sgt_si_mips16"
6075 [(set (match_operand:SI 0 "register_operand" "=t")
6076 (gt:SI (match_operand:SI 1 "register_operand" "d")
6077 (match_operand:SI 2 "register_operand" "d")))]
6080 [(set_attr "type" "slt")
6081 (set_attr "mode" "SI")])
6083 (define_insn "*sgt_di"
6084 [(set (match_operand:DI 0 "register_operand" "=d")
6085 (gt:DI (match_operand:DI 1 "register_operand" "d")
6086 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6087 "TARGET_64BIT && !TARGET_MIPS16"
6089 [(set_attr "type" "slt")
6090 (set_attr "mode" "DI")])
6092 (define_insn "*sgt_di_mips16"
6093 [(set (match_operand:DI 0 "register_operand" "=t")
6094 (gt:DI (match_operand:DI 1 "register_operand" "d")
6095 (match_operand:DI 2 "register_operand" "d")))]
6096 "TARGET_64BIT && TARGET_MIPS16"
6098 [(set_attr "type" "slt")
6099 (set_attr "mode" "DI")])
6101 (define_expand "sge"
6102 [(set (match_operand:SI 0 "register_operand")
6103 (ge:SI (match_dup 1)
6106 { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
6108 (define_insn "*sge_si"
6109 [(set (match_operand:SI 0 "register_operand" "=d")
6110 (ge:SI (match_operand:SI 1 "register_operand" "d")
6114 [(set_attr "type" "slt")
6115 (set_attr "mode" "SI")])
6117 (define_insn "*sge_di"
6118 [(set (match_operand:DI 0 "register_operand" "=d")
6119 (ge:DI (match_operand:DI 1 "register_operand" "d")
6121 "TARGET_64BIT && !TARGET_MIPS16"
6123 [(set_attr "type" "slt")
6124 (set_attr "mode" "DI")])
6126 (define_expand "slt"
6127 [(set (match_operand:SI 0 "register_operand")
6128 (lt:SI (match_dup 1)
6131 { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
6133 (define_insn "*slt_si"
6134 [(set (match_operand:SI 0 "register_operand" "=d")
6135 (lt:SI (match_operand:SI 1 "register_operand" "d")
6136 (match_operand:SI 2 "arith_operand" "dI")))]
6139 [(set_attr "type" "slt")
6140 (set_attr "mode" "SI")])
6142 (define_insn "*slt_si_mips16"
6143 [(set (match_operand:SI 0 "register_operand" "=t,t")
6144 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
6145 (match_operand:SI 2 "arith_operand" "d,I")))]
6148 [(set_attr "type" "slt")
6149 (set_attr "mode" "SI")
6150 (set_attr_alternative "length"
6152 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6156 (define_insn "*slt_di"
6157 [(set (match_operand:DI 0 "register_operand" "=d")
6158 (lt:DI (match_operand:DI 1 "register_operand" "d")
6159 (match_operand:DI 2 "arith_operand" "dI")))]
6160 "TARGET_64BIT && !TARGET_MIPS16"
6162 [(set_attr "type" "slt")
6163 (set_attr "mode" "DI")])
6165 (define_insn "*slt_di_mips16"
6166 [(set (match_operand:DI 0 "register_operand" "=t,t")
6167 (lt:DI (match_operand:DI 1 "register_operand" "d,d")
6168 (match_operand:DI 2 "arith_operand" "d,I")))]
6169 "TARGET_64BIT && TARGET_MIPS16"
6171 [(set_attr "type" "slt")
6172 (set_attr "mode" "DI")
6173 (set_attr_alternative "length"
6175 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6179 (define_expand "sle"
6180 [(set (match_operand:SI 0 "register_operand")
6181 (le:SI (match_dup 1)
6184 { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
6186 (define_insn "*sle_si"
6187 [(set (match_operand:SI 0 "register_operand" "=d")
6188 (le:SI (match_operand:SI 1 "register_operand" "d")
6189 (match_operand:SI 2 "sle_operand" "")))]
6192 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6193 return "slt\t%0,%1,%2";
6195 [(set_attr "type" "slt")
6196 (set_attr "mode" "SI")])
6198 (define_insn "*sle_si_mips16"
6199 [(set (match_operand:SI 0 "register_operand" "=t")
6200 (le:SI (match_operand:SI 1 "register_operand" "d")
6201 (match_operand:SI 2 "sle_operand" "")))]
6204 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6205 return "slt\t%1,%2";
6207 [(set_attr "type" "slt")
6208 (set_attr "mode" "SI")
6209 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6213 (define_insn "*sle_di"
6214 [(set (match_operand:DI 0 "register_operand" "=d")
6215 (le:DI (match_operand:DI 1 "register_operand" "d")
6216 (match_operand:DI 2 "sle_operand" "")))]
6217 "TARGET_64BIT && !TARGET_MIPS16"
6219 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6220 return "slt\t%0,%1,%2";
6222 [(set_attr "type" "slt")
6223 (set_attr "mode" "DI")])
6225 (define_insn "*sle_di_mips16"
6226 [(set (match_operand:DI 0 "register_operand" "=t")
6227 (le:DI (match_operand:DI 1 "register_operand" "d")
6228 (match_operand:DI 2 "sle_operand" "")))]
6229 "TARGET_64BIT && TARGET_MIPS16"
6231 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6232 return "slt\t%1,%2";
6234 [(set_attr "type" "slt")
6235 (set_attr "mode" "DI")
6236 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6240 (define_expand "sgtu"
6241 [(set (match_operand:SI 0 "register_operand")
6242 (gtu:SI (match_dup 1)
6245 { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
6247 (define_insn "*sgtu_si"
6248 [(set (match_operand:SI 0 "register_operand" "=d")
6249 (gtu:SI (match_operand:SI 1 "register_operand" "d")
6250 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6253 [(set_attr "type" "slt")
6254 (set_attr "mode" "SI")])
6256 (define_insn "*sgtu_si_mips16"
6257 [(set (match_operand:SI 0 "register_operand" "=t")
6258 (gtu:SI (match_operand:SI 1 "register_operand" "d")
6259 (match_operand:SI 2 "register_operand" "d")))]
6262 [(set_attr "type" "slt")
6263 (set_attr "mode" "SI")])
6265 (define_insn "*sgtu_di"
6266 [(set (match_operand:DI 0 "register_operand" "=d")
6267 (gtu:DI (match_operand:DI 1 "register_operand" "d")
6268 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6269 "TARGET_64BIT && !TARGET_MIPS16"
6271 [(set_attr "type" "slt")
6272 (set_attr "mode" "DI")])
6274 (define_insn "*sgtu_di_mips16"
6275 [(set (match_operand:DI 0 "register_operand" "=t")
6276 (gtu:DI (match_operand:DI 1 "register_operand" "d")
6277 (match_operand:DI 2 "register_operand" "d")))]
6278 "TARGET_64BIT && TARGET_MIPS16"
6280 [(set_attr "type" "slt")
6281 (set_attr "mode" "DI")])
6283 (define_expand "sgeu"
6284 [(set (match_operand:SI 0 "register_operand")
6285 (geu:SI (match_dup 1)
6288 { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
6290 (define_insn "*sge_si"
6291 [(set (match_operand:SI 0 "register_operand" "=d")
6292 (geu:SI (match_operand:SI 1 "register_operand" "d")
6296 [(set_attr "type" "slt")
6297 (set_attr "mode" "SI")])
6299 (define_insn "*sge_di"
6300 [(set (match_operand:DI 0 "register_operand" "=d")
6301 (geu:DI (match_operand:DI 1 "register_operand" "d")
6303 "TARGET_64BIT && !TARGET_MIPS16"
6305 [(set_attr "type" "slt")
6306 (set_attr "mode" "DI")])
6308 (define_expand "sltu"
6309 [(set (match_operand:SI 0 "register_operand")
6310 (ltu:SI (match_dup 1)
6313 { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
6315 (define_insn "*sltu_si"
6316 [(set (match_operand:SI 0 "register_operand" "=d")
6317 (ltu:SI (match_operand:SI 1 "register_operand" "d")
6318 (match_operand:SI 2 "arith_operand" "dI")))]
6321 [(set_attr "type" "slt")
6322 (set_attr "mode" "SI")])
6324 (define_insn "*sltu_si_mips16"
6325 [(set (match_operand:SI 0 "register_operand" "=t,t")
6326 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
6327 (match_operand:SI 2 "arith_operand" "d,I")))]
6330 [(set_attr "type" "slt")
6331 (set_attr "mode" "SI")
6332 (set_attr_alternative "length"
6334 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6338 (define_insn "*sltu_di"
6339 [(set (match_operand:DI 0 "register_operand" "=d")
6340 (ltu:DI (match_operand:DI 1 "register_operand" "d")
6341 (match_operand:DI 2 "arith_operand" "dI")))]
6342 "TARGET_64BIT && !TARGET_MIPS16"
6344 [(set_attr "type" "slt")
6345 (set_attr "mode" "DI")])
6347 (define_insn "*sltu_di_mips16"
6348 [(set (match_operand:DI 0 "register_operand" "=t,t")
6349 (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
6350 (match_operand:DI 2 "arith_operand" "d,I")))]
6351 "TARGET_64BIT && TARGET_MIPS16"
6353 [(set_attr "type" "slt")
6354 (set_attr "mode" "DI")
6355 (set_attr_alternative "length"
6357 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6361 (define_expand "sleu"
6362 [(set (match_operand:SI 0 "register_operand")
6363 (leu:SI (match_dup 1)
6366 { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
6368 (define_insn "*sleu_si"
6369 [(set (match_operand:SI 0 "register_operand" "=d")
6370 (leu:SI (match_operand:SI 1 "register_operand" "d")
6371 (match_operand:SI 2 "sleu_operand" "")))]
6374 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6375 return "sltu\t%0,%1,%2";
6377 [(set_attr "type" "slt")
6378 (set_attr "mode" "SI")])
6380 (define_insn "*sleu_si_mips16"
6381 [(set (match_operand:SI 0 "register_operand" "=t")
6382 (leu:SI (match_operand:SI 1 "register_operand" "d")
6383 (match_operand:SI 2 "sleu_operand" "")))]
6386 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6387 return "sltu\t%1,%2";
6389 [(set_attr "type" "slt")
6390 (set_attr "mode" "SI")
6391 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6395 (define_insn "*sleu_di"
6396 [(set (match_operand:DI 0 "register_operand" "=d")
6397 (leu:DI (match_operand:DI 1 "register_operand" "d")
6398 (match_operand:DI 2 "sleu_operand" "")))]
6399 "TARGET_64BIT && !TARGET_MIPS16"
6401 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6402 return "sltu\t%0,%1,%2";
6404 [(set_attr "type" "slt")
6405 (set_attr "mode" "DI")])
6407 (define_insn "*sleu_di_mips16"
6408 [(set (match_operand:DI 0 "register_operand" "=t")
6409 (leu:DI (match_operand:DI 1 "register_operand" "d")
6410 (match_operand:DI 2 "sleu_operand" "")))]
6411 "TARGET_64BIT && TARGET_MIPS16"
6413 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6414 return "sltu\t%1,%2";
6416 [(set_attr "type" "slt")
6417 (set_attr "mode" "DI")
6418 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6423 ;; ....................
6425 ;; FLOATING POINT COMPARISONS
6427 ;; ....................
6429 (define_insn "sunordered_df"
6430 [(set (match_operand:CC 0 "register_operand" "=z")
6431 (unordered:CC (match_operand:DF 1 "register_operand" "f")
6432 (match_operand:DF 2 "register_operand" "f")))]
6433 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6435 [(set_attr "type" "fcmp")
6436 (set_attr "mode" "FPSW")])
6438 (define_insn "sunlt_df"
6439 [(set (match_operand:CC 0 "register_operand" "=z")
6440 (unlt:CC (match_operand:DF 1 "register_operand" "f")
6441 (match_operand:DF 2 "register_operand" "f")))]
6442 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6444 [(set_attr "type" "fcmp")
6445 (set_attr "mode" "FPSW")])
6447 (define_insn "suneq_df"
6448 [(set (match_operand:CC 0 "register_operand" "=z")
6449 (uneq:CC (match_operand:DF 1 "register_operand" "f")
6450 (match_operand:DF 2 "register_operand" "f")))]
6451 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6453 [(set_attr "type" "fcmp")
6454 (set_attr "mode" "FPSW")])
6456 (define_insn "sunle_df"
6457 [(set (match_operand:CC 0 "register_operand" "=z")
6458 (unle:CC (match_operand:DF 1 "register_operand" "f")
6459 (match_operand:DF 2 "register_operand" "f")))]
6460 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6462 [(set_attr "type" "fcmp")
6463 (set_attr "mode" "FPSW")])
6465 (define_insn "seq_df"
6466 [(set (match_operand:CC 0 "register_operand" "=z")
6467 (eq:CC (match_operand:DF 1 "register_operand" "f")
6468 (match_operand:DF 2 "register_operand" "f")))]
6469 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6471 [(set_attr "type" "fcmp")
6472 (set_attr "mode" "FPSW")])
6474 (define_insn "slt_df"
6475 [(set (match_operand:CC 0 "register_operand" "=z")
6476 (lt:CC (match_operand:DF 1 "register_operand" "f")
6477 (match_operand:DF 2 "register_operand" "f")))]
6478 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6480 [(set_attr "type" "fcmp")
6481 (set_attr "mode" "FPSW")])
6483 (define_insn "sle_df"
6484 [(set (match_operand:CC 0 "register_operand" "=z")
6485 (le:CC (match_operand:DF 1 "register_operand" "f")
6486 (match_operand:DF 2 "register_operand" "f")))]
6487 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6489 [(set_attr "type" "fcmp")
6490 (set_attr "mode" "FPSW")])
6492 (define_insn "sgt_df"
6493 [(set (match_operand:CC 0 "register_operand" "=z")
6494 (gt:CC (match_operand:DF 1 "register_operand" "f")
6495 (match_operand:DF 2 "register_operand" "f")))]
6496 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6498 [(set_attr "type" "fcmp")
6499 (set_attr "mode" "FPSW")])
6501 (define_insn "sge_df"
6502 [(set (match_operand:CC 0 "register_operand" "=z")
6503 (ge:CC (match_operand:DF 1 "register_operand" "f")
6504 (match_operand:DF 2 "register_operand" "f")))]
6505 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6507 [(set_attr "type" "fcmp")
6508 (set_attr "mode" "FPSW")])
6510 (define_insn "sunordered_sf"
6511 [(set (match_operand:CC 0 "register_operand" "=z")
6512 (unordered:CC (match_operand:SF 1 "register_operand" "f")
6513 (match_operand:SF 2 "register_operand" "f")))]
6516 [(set_attr "type" "fcmp")
6517 (set_attr "mode" "FPSW")])
6519 (define_insn "sunlt_sf"
6520 [(set (match_operand:CC 0 "register_operand" "=z")
6521 (unlt:CC (match_operand:SF 1 "register_operand" "f")
6522 (match_operand:SF 2 "register_operand" "f")))]
6525 [(set_attr "type" "fcmp")
6526 (set_attr "mode" "FPSW")])
6528 (define_insn "suneq_sf"
6529 [(set (match_operand:CC 0 "register_operand" "=z")
6530 (uneq:CC (match_operand:SF 1 "register_operand" "f")
6531 (match_operand:SF 2 "register_operand" "f")))]
6534 [(set_attr "type" "fcmp")
6535 (set_attr "mode" "FPSW")])
6537 (define_insn "sunle_sf"
6538 [(set (match_operand:CC 0 "register_operand" "=z")
6539 (unle:CC (match_operand:SF 1 "register_operand" "f")
6540 (match_operand:SF 2 "register_operand" "f")))]
6543 [(set_attr "type" "fcmp")
6544 (set_attr "mode" "FPSW")])
6546 (define_insn "seq_sf"
6547 [(set (match_operand:CC 0 "register_operand" "=z")
6548 (eq:CC (match_operand:SF 1 "register_operand" "f")
6549 (match_operand:SF 2 "register_operand" "f")))]
6552 [(set_attr "type" "fcmp")
6553 (set_attr "mode" "FPSW")])
6555 (define_insn "slt_sf"
6556 [(set (match_operand:CC 0 "register_operand" "=z")
6557 (lt:CC (match_operand:SF 1 "register_operand" "f")
6558 (match_operand:SF 2 "register_operand" "f")))]
6561 [(set_attr "type" "fcmp")
6562 (set_attr "mode" "FPSW")])
6564 (define_insn "sle_sf"
6565 [(set (match_operand:CC 0 "register_operand" "=z")
6566 (le:CC (match_operand:SF 1 "register_operand" "f")
6567 (match_operand:SF 2 "register_operand" "f")))]
6570 [(set_attr "type" "fcmp")
6571 (set_attr "mode" "FPSW")])
6573 (define_insn "sgt_sf"
6574 [(set (match_operand:CC 0 "register_operand" "=z")
6575 (gt:CC (match_operand:SF 1 "register_operand" "f")
6576 (match_operand:SF 2 "register_operand" "f")))]
6579 [(set_attr "type" "fcmp")
6580 (set_attr "mode" "FPSW")])
6582 (define_insn "sge_sf"
6583 [(set (match_operand:CC 0 "register_operand" "=z")
6584 (ge:CC (match_operand:SF 1 "register_operand" "f")
6585 (match_operand:SF 2 "register_operand" "f")))]
6588 [(set_attr "type" "fcmp")
6589 (set_attr "mode" "FPSW")])
6592 ;; ....................
6594 ;; UNCONDITIONAL BRANCHES
6596 ;; ....................
6598 ;; Unconditional branches.
6602 (label_ref (match_operand 0 "" "")))]
6607 if (get_attr_length (insn) <= 8)
6608 return "%*b\t%l0%/";
6611 output_asm_insn (mips_output_load_label (), operands);
6612 return "%*jr\t%@%/%]";
6616 return "%*j\t%l0%/";
6618 [(set_attr "type" "jump")
6619 (set_attr "mode" "none")
6620 (set (attr "length")
6621 ;; We can't use `j' when emitting PIC. Emit a branch if it's
6622 ;; in range, otherwise load the address of the branch target into
6623 ;; $at and then jump to it.
6625 (ior (eq (symbol_ref "flag_pic") (const_int 0))
6626 (lt (abs (minus (match_dup 0)
6627 (plus (pc) (const_int 4))))
6628 (const_int 131072)))
6629 (const_int 4) (const_int 16)))])
6631 ;; We need a different insn for the mips16, because a mips16 branch
6632 ;; does not have a delay slot.
6636 (label_ref (match_operand 0 "" "")))]
6639 [(set_attr "type" "branch")
6640 (set_attr "mode" "none")
6641 (set_attr "length" "8")])
6643 (define_expand "indirect_jump"
6644 [(set (pc) (match_operand 0 "register_operand"))]
6650 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
6651 operands[0] = copy_to_mode_reg (Pmode, dest);
6653 if (!(Pmode == DImode))
6654 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
6656 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
6661 (define_insn "indirect_jump_internal1"
6662 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
6663 "!(Pmode == DImode)"
6665 [(set_attr "type" "jump")
6666 (set_attr "mode" "none")])
6668 (define_insn "indirect_jump_internal2"
6669 [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
6672 [(set_attr "type" "jump")
6673 (set_attr "mode" "none")])
6675 (define_expand "tablejump"
6677 (match_operand 0 "register_operand"))
6678 (use (label_ref (match_operand 1 "")))]
6683 if (GET_MODE (operands[0]) != HImode)
6685 if (!(Pmode == DImode))
6686 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
6688 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
6692 if (GET_MODE (operands[0]) != ptr_mode)
6696 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
6697 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
6699 if (Pmode == SImode)
6700 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
6702 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
6706 (define_insn "tablejump_internal1"
6708 (match_operand:SI 0 "register_operand" "d"))
6709 (use (label_ref (match_operand 1 "" "")))]
6712 [(set_attr "type" "jump")
6713 (set_attr "mode" "none")])
6715 (define_insn "tablejump_internal2"
6717 (match_operand:DI 0 "register_operand" "d"))
6718 (use (label_ref (match_operand 1 "" "")))]
6721 [(set_attr "type" "jump")
6722 (set_attr "mode" "none")])
6724 (define_expand "tablejump_mips161"
6725 [(set (pc) (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand"))
6726 (label_ref:SI (match_operand 1 ""))))]
6727 "TARGET_MIPS16 && !(Pmode == DImode)"
6731 t1 = gen_reg_rtx (SImode);
6732 t2 = gen_reg_rtx (SImode);
6733 t3 = gen_reg_rtx (SImode);
6734 emit_insn (gen_extendhisi2 (t1, operands[0]));
6735 emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
6736 emit_insn (gen_addsi3 (t3, t1, t2));
6737 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
6741 (define_expand "tablejump_mips162"
6742 [(set (pc) (plus:DI (sign_extend:DI (match_operand:HI 0 "register_operand"))
6743 (label_ref:DI (match_operand 1 ""))))]
6744 "TARGET_MIPS16 && Pmode == DImode"
6748 t1 = gen_reg_rtx (DImode);
6749 t2 = gen_reg_rtx (DImode);
6750 t3 = gen_reg_rtx (DImode);
6751 emit_insn (gen_extendhidi2 (t1, operands[0]));
6752 emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
6753 emit_insn (gen_adddi3 (t3, t1, t2));
6754 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
6758 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
6759 ;; While it is possible to either pull it off the stack (in the
6760 ;; o32 case) or recalculate it given t9 and our target label,
6761 ;; it takes 3 or 4 insns to do so.
6763 (define_expand "builtin_setjmp_setup"
6764 [(use (match_operand 0 "register_operand"))]
6769 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
6770 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
6774 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
6775 ;; that older code did recalculate the gp from $25. Continue to jump through
6776 ;; $25 for compatibility (we lose nothing by doing so).
6778 (define_expand "builtin_longjmp"
6779 [(use (match_operand 0 "register_operand"))]
6782 /* The elements of the buffer are, in order: */
6783 int W = GET_MODE_SIZE (Pmode);
6784 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6785 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
6786 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
6787 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
6788 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6789 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
6790 The target is bound to be using $28 as the global pointer
6791 but the current function might not be. */
6792 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
6794 /* This bit is similar to expand_builtin_longjmp except that it
6795 restores $gp as well. */
6796 emit_move_insn (hard_frame_pointer_rtx, fp);
6797 emit_move_insn (pv, lab);
6798 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6799 emit_move_insn (gp, gpv);
6800 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6801 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6802 emit_insn (gen_rtx_USE (VOIDmode, gp));
6803 emit_indirect_jump (pv);
6808 ;; ....................
6810 ;; Function prologue/epilogue
6812 ;; ....................
6815 (define_expand "prologue"
6819 mips_expand_prologue ();
6823 ;; Block any insns from being moved before this point, since the
6824 ;; profiling call to mcount can use various registers that aren't
6825 ;; saved or used to pass arguments.
6827 (define_insn "blockage"
6828 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
6831 [(set_attr "type" "unknown")
6832 (set_attr "mode" "none")
6833 (set_attr "length" "0")])
6835 (define_expand "epilogue"
6839 mips_expand_epilogue (false);
6843 (define_expand "sibcall_epilogue"
6847 mips_expand_epilogue (true);
6851 ;; Trivial return. Make it look like a normal return insn as that
6852 ;; allows jump optimizations to work better.
6854 (define_insn "return"
6856 "mips_can_use_return_insn ()"
6858 [(set_attr "type" "jump")
6859 (set_attr "mode" "none")])
6863 (define_insn "return_internal"
6865 (use (match_operand 0 "pmode_register_operand" ""))]
6868 [(set_attr "type" "jump")
6869 (set_attr "mode" "none")])
6871 ;; This is used in compiling the unwind routines.
6872 (define_expand "eh_return"
6873 [(use (match_operand 0 "general_operand"))]
6876 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
6878 if (GET_MODE (operands[0]) != gpr_mode)
6879 operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
6881 emit_insn (gen_eh_set_lr_di (operands[0]));
6883 emit_insn (gen_eh_set_lr_si (operands[0]));
6888 ;; Clobber the return address on the stack. We can't expand this
6889 ;; until we know where it will be put in the stack frame.
6891 (define_insn "eh_set_lr_si"
6892 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6893 (clobber (match_scratch:SI 1 "=&d"))]
6897 (define_insn "eh_set_lr_di"
6898 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6899 (clobber (match_scratch:DI 1 "=&d"))]
6904 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6905 (clobber (match_scratch 1))]
6906 "reload_completed && !TARGET_DEBUG_D_MODE"
6909 mips_set_return_address (operands[0], operands[1]);
6913 (define_insn_and_split "exception_receiver"
6915 (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
6916 "TARGET_ABICALLS && TARGET_OLDABI"
6918 "&& reload_completed"
6924 [(set_attr "type" "load")
6925 (set_attr "length" "12")])
6928 ;; ....................
6932 ;; ....................
6934 ;; Instructions to load a call address from the GOT. The address might
6935 ;; point to a function or to a lazy binding stub. In the latter case,
6936 ;; the stub will use the dynamic linker to resolve the function, which
6937 ;; in turn will change the GOT entry to point to the function's real
6940 ;; This means that every call, even pure and constant ones, can
6941 ;; potentially modify the GOT entry. And once a stub has been called,
6942 ;; we must not call it again.
6944 ;; We represent this restriction using an imaginary fixed register that
6945 ;; acts like a GOT version number. By making the register call-clobbered,
6946 ;; we tell the target-independent code that the address could be changed
6947 ;; by any call insn.
6948 (define_insn "load_callsi"
6949 [(set (match_operand:SI 0 "register_operand" "=c")
6950 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6951 (match_operand:SI 2 "immediate_operand" "")
6952 (reg:SI FAKE_CALL_REGNO)]
6956 [(set_attr "type" "load")
6957 (set_attr "length" "4")])
6959 (define_insn "load_calldi"
6960 [(set (match_operand:DI 0 "register_operand" "=c")
6961 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
6962 (match_operand:DI 2 "immediate_operand" "")
6963 (reg:DI FAKE_CALL_REGNO)]
6967 [(set_attr "type" "load")
6968 (set_attr "length" "4")])
6970 ;; Sibling calls. All these patterns use jump instructions.
6972 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
6973 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
6974 ;; is defined in terms of call_insn_operand, the same is true of the
6977 ;; When we use an indirect jump, we need a register that will be
6978 ;; preserved by the epilogue. Since TARGET_ABICALLS forces us to
6979 ;; use $25 for this purpose -- and $25 is never clobbered by the
6980 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
6982 (define_expand "sibcall"
6983 [(parallel [(call (match_operand 0 "")
6984 (match_operand 1 ""))
6985 (use (match_operand 2 "")) ;; next_arg_reg
6986 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
6989 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
6993 (define_insn "sibcall_internal"
6994 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
6995 (match_operand 1 "" ""))]
6996 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7000 [(set_attr "type" "call")])
7002 (define_expand "sibcall_value"
7003 [(parallel [(set (match_operand 0 "")
7004 (call (match_operand 1 "")
7005 (match_operand 2 "")))
7006 (use (match_operand 3 ""))])] ;; next_arg_reg
7009 mips_expand_call (operands[0], XEXP (operands[1], 0),
7010 operands[2], operands[3], true);
7014 (define_insn "sibcall_value_internal"
7015 [(set (match_operand 0 "register_operand" "=df,df")
7016 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
7017 (match_operand 2 "" "")))]
7018 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7022 [(set_attr "type" "call")])
7024 (define_insn "sibcall_value_multiple_internal"
7025 [(set (match_operand 0 "register_operand" "=df,df")
7026 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
7027 (match_operand 2 "" "")))
7028 (set (match_operand 3 "register_operand" "=df,df")
7029 (call (mem:SI (match_dup 1))
7031 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7035 [(set_attr "type" "call")])
7037 (define_expand "call"
7038 [(parallel [(call (match_operand 0 "")
7039 (match_operand 1 ""))
7040 (use (match_operand 2 "")) ;; next_arg_reg
7041 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
7044 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
7048 ;; This instruction directly corresponds to an assembly-language "jal".
7049 ;; There are four cases:
7052 ;; Both symbolic and register destinations are OK. The pattern
7053 ;; always expands to a single mips instruction.
7055 ;; - -mabicalls/-mno-explicit-relocs:
7056 ;; Again, both symbolic and register destinations are OK.
7057 ;; The call is treated as a multi-instruction black box.
7059 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
7060 ;; Only "jal $25" is allowed. This expands to a single "jalr $25"
7063 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
7064 ;; Only "jal $25" is allowed. The call is actually two instructions:
7065 ;; "jalr $25" followed by an insn to reload $gp.
7067 ;; In the last case, we can generate the individual instructions with
7068 ;; a define_split. There are several things to be wary of:
7070 ;; - We can't expose the load of $gp before reload. If we did,
7071 ;; it might get removed as dead, but reload can introduce new
7072 ;; uses of $gp by rematerializing constants.
7074 ;; - We shouldn't restore $gp after calls that never return.
7075 ;; It isn't valid to insert instructions between a noreturn
7076 ;; call and the following barrier.
7078 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
7079 ;; instruction preserves $gp and so have no effect on its liveness.
7080 ;; But once we generate the separate insns, it becomes obvious that
7081 ;; $gp is not live on entry to the call.
7083 ;; ??? The operands[2] = insn check is a hack to make the original insn
7084 ;; available to the splitter.
7085 (define_insn_and_split "call_internal"
7086 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
7087 (match_operand 1 "" ""))
7088 (clobber (reg:SI 31))]
7090 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
7091 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
7094 emit_call_insn (gen_call_split (operands[0], operands[1]));
7095 if (!find_reg_note (operands[2], REG_NORETURN, 0))
7099 [(set_attr "jal" "indirect,direct")
7100 (set_attr "extended_mips16" "no,yes")])
7102 (define_insn "call_split"
7103 [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
7104 (match_operand 1 "" ""))
7105 (clobber (reg:SI 31))
7106 (clobber (reg:SI 28))]
7107 "TARGET_SPLIT_CALLS"
7109 [(set_attr "type" "call")])
7111 (define_expand "call_value"
7112 [(parallel [(set (match_operand 0 "")
7113 (call (match_operand 1 "")
7114 (match_operand 2 "")))
7115 (use (match_operand 3 ""))])] ;; next_arg_reg
7118 mips_expand_call (operands[0], XEXP (operands[1], 0),
7119 operands[2], operands[3], false);
7123 ;; See comment for call_internal.
7124 (define_insn_and_split "call_value_internal"
7125 [(set (match_operand 0 "register_operand" "=df,df")
7126 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7127 (match_operand 2 "" "")))
7128 (clobber (reg:SI 31))]
7130 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7131 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
7134 emit_call_insn (gen_call_value_split (operands[0], operands[1],
7136 if (!find_reg_note (operands[3], REG_NORETURN, 0))
7140 [(set_attr "jal" "indirect,direct")
7141 (set_attr "extended_mips16" "no,yes")])
7143 (define_insn "call_value_split"
7144 [(set (match_operand 0 "register_operand" "=df")
7145 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7146 (match_operand 2 "" "")))
7147 (clobber (reg:SI 31))
7148 (clobber (reg:SI 28))]
7149 "TARGET_SPLIT_CALLS"
7151 [(set_attr "type" "call")])
7153 ;; See comment for call_internal.
7154 (define_insn_and_split "call_value_multiple_internal"
7155 [(set (match_operand 0 "register_operand" "=df,df")
7156 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7157 (match_operand 2 "" "")))
7158 (set (match_operand 3 "register_operand" "=df,df")
7159 (call (mem:SI (match_dup 1))
7161 (clobber (reg:SI 31))]
7163 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7164 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
7167 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
7168 operands[2], operands[3]));
7169 if (!find_reg_note (operands[4], REG_NORETURN, 0))
7173 [(set_attr "jal" "indirect,direct")
7174 (set_attr "extended_mips16" "no,yes")])
7176 (define_insn "call_value_multiple_split"
7177 [(set (match_operand 0 "register_operand" "=df")
7178 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7179 (match_operand 2 "" "")))
7180 (set (match_operand 3 "register_operand" "=df")
7181 (call (mem:SI (match_dup 1))
7183 (clobber (reg:SI 31))
7184 (clobber (reg:SI 28))]
7185 "TARGET_SPLIT_CALLS"
7187 [(set_attr "type" "call")])
7189 ;; Call subroutine returning any type.
7191 (define_expand "untyped_call"
7192 [(parallel [(call (match_operand 0 "")
7194 (match_operand 1 "")
7195 (match_operand 2 "")])]
7200 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
7202 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7204 rtx set = XVECEXP (operands[2], 0, i);
7205 emit_move_insn (SET_DEST (set), SET_SRC (set));
7208 emit_insn (gen_blockage ());
7213 ;; ....................
7217 ;; ....................
7221 (define_expand "prefetch"
7222 [(prefetch (match_operand 0 "address_operand")
7223 (match_operand 1 "const_int_operand")
7224 (match_operand 2 "const_int_operand"))]
7227 if (symbolic_operand (operands[0], GET_MODE (operands[0])))
7228 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
7231 (define_insn "prefetch_si_address"
7232 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7233 (match_operand:SI 3 "const_int_operand" "I"))
7234 (match_operand:SI 1 "const_int_operand" "n")
7235 (match_operand:SI 2 "const_int_operand" "n"))]
7236 "ISA_HAS_PREFETCH && Pmode == SImode"
7237 { return mips_emit_prefetch (operands); }
7238 [(set_attr "type" "prefetch")])
7240 (define_insn "prefetch_indexed_si"
7241 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7242 (match_operand:SI 3 "register_operand" "r"))
7243 (match_operand:SI 1 "const_int_operand" "n")
7244 (match_operand:SI 2 "const_int_operand" "n"))]
7245 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
7246 { return mips_emit_prefetch (operands); }
7247 [(set_attr "type" "prefetchx")])
7249 (define_insn "prefetch_si"
7250 [(prefetch (match_operand:SI 0 "register_operand" "r")
7251 (match_operand:SI 1 "const_int_operand" "n")
7252 (match_operand:SI 2 "const_int_operand" "n"))]
7253 "ISA_HAS_PREFETCH && Pmode == SImode"
7255 operands[3] = const0_rtx;
7256 return mips_emit_prefetch (operands);
7258 [(set_attr "type" "prefetch")])
7260 (define_insn "prefetch_di_address"
7261 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7262 (match_operand:DI 3 "const_int_operand" "I"))
7263 (match_operand:DI 1 "const_int_operand" "n")
7264 (match_operand:DI 2 "const_int_operand" "n"))]
7265 "ISA_HAS_PREFETCH && Pmode == DImode"
7266 { return mips_emit_prefetch (operands); }
7267 [(set_attr "type" "prefetch")])
7269 (define_insn "prefetch_indexed_di"
7270 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7271 (match_operand:DI 3 "register_operand" "r"))
7272 (match_operand:DI 1 "const_int_operand" "n")
7273 (match_operand:DI 2 "const_int_operand" "n"))]
7274 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
7275 { return mips_emit_prefetch (operands); }
7276 [(set_attr "type" "prefetchx")])
7278 (define_insn "prefetch_di"
7279 [(prefetch (match_operand:DI 0 "register_operand" "r")
7280 (match_operand:DI 1 "const_int_operand" "n")
7281 (match_operand:DI 2 "const_int_operand" "n"))]
7282 "ISA_HAS_PREFETCH && Pmode == DImode"
7284 operands[3] = const0_rtx;
7285 return mips_emit_prefetch (operands);
7287 [(set_attr "type" "prefetch")])
7293 [(set_attr "type" "nop")
7294 (set_attr "mode" "none")])
7296 ;; Like nop, but commented out when outside a .set noreorder block.
7297 (define_insn "hazard_nop"
7306 [(set_attr "type" "nop")])
7308 ;; MIPS4 Conditional move instructions.
7311 [(set (match_operand:SI 0 "register_operand" "=d,d")
7313 (match_operator:SI 4 "equality_operator"
7314 [(match_operand:SI 1 "register_operand" "d,d")
7316 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7317 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7318 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7322 [(set_attr "type" "condmove")
7323 (set_attr "mode" "SI")])
7326 [(set (match_operand:SI 0 "register_operand" "=d,d")
7328 (match_operator:DI 4 "equality_operator"
7329 [(match_operand:DI 1 "register_operand" "d,d")
7331 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7332 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7333 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7337 [(set_attr "type" "condmove")
7338 (set_attr "mode" "SI")])
7341 [(set (match_operand:SI 0 "register_operand" "=d,d")
7343 (match_operator:CC 3 "equality_operator"
7344 [(match_operand:CC 4 "register_operand" "z,z")
7346 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
7347 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
7348 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7352 [(set_attr "type" "condmove")
7353 (set_attr "mode" "SI")])
7356 [(set (match_operand:DI 0 "register_operand" "=d,d")
7358 (match_operator:SI 4 "equality_operator"
7359 [(match_operand:SI 1 "register_operand" "d,d")
7361 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7362 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7363 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7367 [(set_attr "type" "condmove")
7368 (set_attr "mode" "DI")])
7371 [(set (match_operand:DI 0 "register_operand" "=d,d")
7373 (match_operator:DI 4 "equality_operator"
7374 [(match_operand:DI 1 "register_operand" "d,d")
7376 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7377 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7378 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7382 [(set_attr "type" "condmove")
7383 (set_attr "mode" "DI")])
7386 [(set (match_operand:DI 0 "register_operand" "=d,d")
7388 (match_operator:CC 3 "equality_operator"
7389 [(match_operand:CC 4 "register_operand" "z,z")
7391 (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
7392 (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
7393 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
7397 [(set_attr "type" "condmove")
7398 (set_attr "mode" "DI")])
7401 [(set (match_operand:SF 0 "register_operand" "=f,f")
7403 (match_operator:SI 4 "equality_operator"
7404 [(match_operand:SI 1 "register_operand" "d,d")
7406 (match_operand:SF 2 "register_operand" "f,0")
7407 (match_operand:SF 3 "register_operand" "0,f")))]
7408 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7412 [(set_attr "type" "condmove")
7413 (set_attr "mode" "SF")])
7416 [(set (match_operand:SF 0 "register_operand" "=f,f")
7418 (match_operator:DI 4 "equality_operator"
7419 [(match_operand:DI 1 "register_operand" "d,d")
7421 (match_operand:SF 2 "register_operand" "f,0")
7422 (match_operand:SF 3 "register_operand" "0,f")))]
7423 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7427 [(set_attr "type" "condmove")
7428 (set_attr "mode" "SF")])
7431 [(set (match_operand:SF 0 "register_operand" "=f,f")
7433 (match_operator:CC 3 "equality_operator"
7434 [(match_operand:CC 4 "register_operand" "z,z")
7436 (match_operand:SF 1 "register_operand" "f,0")
7437 (match_operand:SF 2 "register_operand" "0,f")))]
7438 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7442 [(set_attr "type" "condmove")
7443 (set_attr "mode" "SF")])
7446 [(set (match_operand:DF 0 "register_operand" "=f,f")
7448 (match_operator:SI 4 "equality_operator"
7449 [(match_operand:SI 1 "register_operand" "d,d")
7451 (match_operand:DF 2 "register_operand" "f,0")
7452 (match_operand:DF 3 "register_operand" "0,f")))]
7453 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7457 [(set_attr "type" "condmove")
7458 (set_attr "mode" "DF")])
7461 [(set (match_operand:DF 0 "register_operand" "=f,f")
7463 (match_operator:DI 4 "equality_operator"
7464 [(match_operand:DI 1 "register_operand" "d,d")
7466 (match_operand:DF 2 "register_operand" "f,0")
7467 (match_operand:DF 3 "register_operand" "0,f")))]
7468 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7472 [(set_attr "type" "condmove")
7473 (set_attr "mode" "DF")])
7476 [(set (match_operand:DF 0 "register_operand" "=f,f")
7478 (match_operator:CC 3 "equality_operator"
7479 [(match_operand:CC 4 "register_operand" "z,z")
7481 (match_operand:DF 1 "register_operand" "f,0")
7482 (match_operand:DF 2 "register_operand" "0,f")))]
7483 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7487 [(set_attr "type" "condmove")
7488 (set_attr "mode" "DF")])
7490 ;; These are the main define_expand's used to make conditional moves.
7492 (define_expand "movsicc"
7493 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7494 (set (match_operand:SI 0 "register_operand")
7495 (if_then_else:SI (match_dup 5)
7496 (match_operand:SI 2 "reg_or_0_operand")
7497 (match_operand:SI 3 "reg_or_0_operand")))]
7498 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7500 gen_conditional_move (operands);
7504 (define_expand "movdicc"
7505 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7506 (set (match_operand:DI 0 "register_operand")
7507 (if_then_else:DI (match_dup 5)
7508 (match_operand:DI 2 "reg_or_0_operand")
7509 (match_operand:DI 3 "reg_or_0_operand")))]
7510 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7512 gen_conditional_move (operands);
7516 (define_expand "movsfcc"
7517 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7518 (set (match_operand:SF 0 "register_operand")
7519 (if_then_else:SF (match_dup 5)
7520 (match_operand:SF 2 "register_operand")
7521 (match_operand:SF 3 "register_operand")))]
7522 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7524 gen_conditional_move (operands);
7528 (define_expand "movdfcc"
7529 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7530 (set (match_operand:DF 0 "register_operand")
7531 (if_then_else:DF (match_dup 5)
7532 (match_operand:DF 2 "register_operand")
7533 (match_operand:DF 3 "register_operand")))]
7534 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7536 gen_conditional_move (operands);
7541 ;; ....................
7543 ;; mips16 inline constant tables
7545 ;; ....................
7548 (define_insn "consttable_int"
7549 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
7550 (match_operand 1 "const_int_operand" "")]
7551 UNSPEC_CONSTTABLE_INT)]
7554 assemble_integer (operands[0], INTVAL (operands[1]),
7555 BITS_PER_UNIT * INTVAL (operands[1]), 1);
7558 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
7560 (define_insn "consttable_float"
7561 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
7562 UNSPEC_CONSTTABLE_FLOAT)]
7567 if (GET_CODE (operands[0]) != CONST_DOUBLE)
7569 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7570 assemble_real (d, GET_MODE (operands[0]),
7571 GET_MODE_BITSIZE (GET_MODE (operands[0])));
7574 [(set (attr "length")
7575 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
7577 (define_insn "align"
7578 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
7581 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
7584 [(match_operand 0 "small_data_pattern")]
7587 { operands[0] = mips_rewrite_small_data (operands[0]); })