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
1908 && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1909 "nmadd.d\t%0,%3,%1,%2"
1910 [(set_attr "type" "fmadd")
1911 (set_attr "mode" "DF")])
1914 [(set (match_operand:DF 0 "register_operand" "=f")
1915 (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
1916 (match_operand:DF 2 "register_operand" "f"))
1917 (match_operand:DF 3 "register_operand" "f")))]
1918 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1919 && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1920 "nmadd.d\t%0,%3,%1,%2"
1921 [(set_attr "type" "fmadd")
1922 (set_attr "mode" "DF")])
1925 [(set (match_operand:SF 0 "register_operand" "=f")
1926 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1927 (match_operand:SF 2 "register_operand" "f"))
1928 (match_operand:SF 3 "register_operand" "f"))))]
1929 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1930 && HONOR_SIGNED_ZEROS (SFmode)"
1931 "nmadd.s\t%0,%3,%1,%2"
1932 [(set_attr "type" "fmadd")
1933 (set_attr "mode" "SF")])
1936 [(set (match_operand:SF 0 "register_operand" "=f")
1937 (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
1938 (match_operand:SF 2 "register_operand" "f"))
1939 (match_operand:SF 3 "register_operand" "f")))]
1940 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1941 && !HONOR_SIGNED_ZEROS (SFmode)"
1942 "nmadd.s\t%0,%3,%1,%2"
1943 [(set_attr "type" "fmadd")
1944 (set_attr "mode" "SF")])
1947 [(set (match_operand:DF 0 "register_operand" "=f")
1948 (neg:DF (minus:DF (mult:DF (match_operand:DF 2 "register_operand" "f")
1949 (match_operand:DF 3 "register_operand" "f"))
1950 (match_operand:DF 1 "register_operand" "f"))))]
1951 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1952 && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1953 "nmsub.d\t%0,%1,%2,%3"
1954 [(set_attr "type" "fmadd")
1955 (set_attr "mode" "DF")])
1958 [(set (match_operand:DF 0 "register_operand" "=f")
1959 (minus:DF (match_operand:DF 1 "register_operand" "f")
1960 (mult:DF (match_operand:DF 2 "register_operand" "f")
1961 (match_operand:DF 3 "register_operand" "f"))))]
1962 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1963 && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1964 "nmsub.d\t%0,%1,%2,%3"
1965 [(set_attr "type" "fmadd")
1966 (set_attr "mode" "DF")])
1969 [(set (match_operand:SF 0 "register_operand" "=f")
1970 (neg:SF (minus:SF (mult:SF (match_operand:SF 2 "register_operand" "f")
1971 (match_operand:SF 3 "register_operand" "f"))
1972 (match_operand:SF 1 "register_operand" "f"))))]
1973 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1974 && HONOR_SIGNED_ZEROS (SFmode)"
1975 "nmsub.s\t%0,%1,%2,%3"
1976 [(set_attr "type" "fmadd")
1977 (set_attr "mode" "SF")])
1980 [(set (match_operand:SF 0 "register_operand" "=f")
1981 (minus:SF (match_operand:SF 1 "register_operand" "f")
1982 (mult:SF (match_operand:SF 2 "register_operand" "f")
1983 (match_operand:SF 3 "register_operand" "f"))))]
1984 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1985 && !HONOR_SIGNED_ZEROS (SFmode)"
1986 "nmsub.s\t%0,%1,%2,%3"
1987 [(set_attr "type" "fmadd")
1988 (set_attr "mode" "SF")])
1991 ;; ....................
1993 ;; DIVISION and REMAINDER
1995 ;; ....................
1998 (define_expand "divdf3"
1999 [(set (match_operand:DF 0 "register_operand")
2000 (div:DF (match_operand:DF 1 "reg_or_1_operand")
2001 (match_operand:DF 2 "register_operand")))]
2002 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2004 if (const_1_operand (operands[1], DFmode))
2005 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2006 operands[1] = force_reg (DFmode, operands[1]);
2009 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
2011 ;; If an mfc1 or dmfc1 happens to access the floating point register
2012 ;; file at the same time a long latency operation (div, sqrt, recip,
2013 ;; sqrt) iterates an intermediate result back through the floating
2014 ;; point register file bypass, then instead returning the correct
2015 ;; register value the mfc1 or dmfc1 operation returns the intermediate
2016 ;; result of the long latency operation.
2018 ;; The workaround is to insert an unconditional 'mov' from/to the
2019 ;; long latency op destination register.
2021 (define_insn "*divdf3"
2022 [(set (match_operand:DF 0 "register_operand" "=f")
2023 (div:DF (match_operand:DF 1 "register_operand" "f")
2024 (match_operand:DF 2 "register_operand" "f")))]
2025 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2028 return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
2030 return "div.d\t%0,%1,%2";
2032 [(set_attr "type" "fdiv")
2033 (set_attr "mode" "DF")
2034 (set (attr "length")
2035 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2040 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
2042 ;; In certain cases, div.s and div.ps may have a rounding error
2043 ;; and/or wrong inexact flag.
2045 ;; Therefore, we only allow div.s if not working around SB-1 rev2
2046 ;; errata, or if working around those errata and a slight loss of
2047 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
2048 (define_expand "divsf3"
2049 [(set (match_operand:SF 0 "register_operand")
2050 (div:SF (match_operand:SF 1 "reg_or_1_operand")
2051 (match_operand:SF 2 "register_operand")))]
2052 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2054 if (const_1_operand (operands[1], SFmode))
2055 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2056 operands[1] = force_reg (SFmode, operands[1]);
2059 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2060 ;; "divdf3" comment for details).
2062 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
2063 ;; "divsf3" comment for details).
2064 (define_insn "*divsf3"
2065 [(set (match_operand:SF 0 "register_operand" "=f")
2066 (div:SF (match_operand:SF 1 "register_operand" "f")
2067 (match_operand:SF 2 "register_operand" "f")))]
2068 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2071 return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
2073 return "div.s\t%0,%1,%2";
2075 [(set_attr "type" "fdiv")
2076 (set_attr "mode" "SF")
2077 (set (attr "length")
2078 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2082 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2083 ;; "divdf3" comment for details).
2085 [(set (match_operand:DF 0 "register_operand" "=f")
2086 (div:DF (match_operand:DF 1 "const_1_operand" "")
2087 (match_operand:DF 2 "register_operand" "f")))]
2088 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2091 return "recip.d\t%0,%2\;mov.d\t%0,%0";
2093 return "recip.d\t%0,%2";
2095 [(set_attr "type" "fdiv")
2096 (set_attr "mode" "DF")
2097 (set (attr "length")
2098 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2102 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2103 ;; "divdf3" comment for details).
2105 [(set (match_operand:SF 0 "register_operand" "=f")
2106 (div:SF (match_operand:SF 1 "const_1_operand" "")
2107 (match_operand:SF 2 "register_operand" "f")))]
2108 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2111 return "recip.s\t%0,%2\;mov.s\t%0,%0";
2113 return "recip.s\t%0,%2";
2115 [(set_attr "type" "fdiv")
2116 (set_attr "mode" "SF")
2117 (set (attr "length")
2118 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2122 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2123 ;; with negative operands. We use special libgcc functions instead.
2124 (define_insn "divmodsi4"
2125 [(set (match_operand:SI 0 "register_operand" "=l")
2126 (div:SI (match_operand:SI 1 "register_operand" "d")
2127 (match_operand:SI 2 "register_operand" "d")))
2128 (set (match_operand:SI 3 "register_operand" "=h")
2129 (mod:SI (match_dup 1)
2131 "!TARGET_FIX_VR4120"
2132 { return mips_output_division ("div\t$0,%1,%2", operands); }
2133 [(set_attr "type" "idiv")
2134 (set_attr "mode" "SI")])
2136 (define_insn "divmoddi4"
2137 [(set (match_operand:DI 0 "register_operand" "=l")
2138 (div:DI (match_operand:DI 1 "register_operand" "d")
2139 (match_operand:DI 2 "register_operand" "d")))
2140 (set (match_operand:DI 3 "register_operand" "=h")
2141 (mod:DI (match_dup 1)
2143 "TARGET_64BIT && !TARGET_FIX_VR4120"
2144 { return mips_output_division ("ddiv\t$0,%1,%2", operands); }
2145 [(set_attr "type" "idiv")
2146 (set_attr "mode" "DI")])
2148 (define_insn "udivmodsi4"
2149 [(set (match_operand:SI 0 "register_operand" "=l")
2150 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2151 (match_operand:SI 2 "register_operand" "d")))
2152 (set (match_operand:SI 3 "register_operand" "=h")
2153 (umod:SI (match_dup 1)
2156 { return mips_output_division ("divu\t$0,%1,%2", operands); }
2157 [(set_attr "type" "idiv")
2158 (set_attr "mode" "SI")])
2160 (define_insn "udivmoddi4"
2161 [(set (match_operand:DI 0 "register_operand" "=l")
2162 (udiv:DI (match_operand:DI 1 "register_operand" "d")
2163 (match_operand:DI 2 "register_operand" "d")))
2164 (set (match_operand:DI 3 "register_operand" "=h")
2165 (umod:DI (match_dup 1)
2168 { return mips_output_division ("ddivu\t$0,%1,%2", operands); }
2169 [(set_attr "type" "idiv")
2170 (set_attr "mode" "DI")])
2173 ;; ....................
2177 ;; ....................
2179 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2180 ;; "divdf3" comment for details).
2181 (define_insn "sqrtdf2"
2182 [(set (match_operand:DF 0 "register_operand" "=f")
2183 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2184 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2187 return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
2189 return "sqrt.d\t%0,%1";
2191 [(set_attr "type" "fsqrt")
2192 (set_attr "mode" "DF")
2193 (set (attr "length")
2194 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2198 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2199 ;; "divdf3" comment for details).
2200 (define_insn "sqrtsf2"
2201 [(set (match_operand:SF 0 "register_operand" "=f")
2202 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2203 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2206 return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
2208 return "sqrt.s\t%0,%1";
2210 [(set_attr "type" "fsqrt")
2211 (set_attr "mode" "SF")
2212 (set (attr "length")
2213 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2217 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2218 ;; "divdf3" comment for details).
2220 [(set (match_operand:DF 0 "register_operand" "=f")
2221 (div:DF (match_operand:DF 1 "const_1_operand" "")
2222 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2223 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2226 return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2228 return "rsqrt.d\t%0,%2";
2230 [(set_attr "type" "frsqrt")
2231 (set_attr "mode" "DF")
2232 (set (attr "length")
2233 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2237 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2238 ;; "divdf3" comment for details).
2240 [(set (match_operand:SF 0 "register_operand" "=f")
2241 (div:SF (match_operand:SF 1 "const_1_operand" "")
2242 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2243 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2246 return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2248 return "rsqrt.s\t%0,%2";
2250 [(set_attr "type" "frsqrt")
2251 (set_attr "mode" "SF")
2252 (set (attr "length")
2253 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2257 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2258 ;; "divdf3" comment for details).
2260 [(set (match_operand:DF 0 "register_operand" "=f")
2261 (sqrt:DF (div:DF (match_operand:DF 1 "const_1_operand" "")
2262 (match_operand:DF 2 "register_operand" "f"))))]
2263 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2266 return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2268 return "rsqrt.d\t%0,%2";
2270 [(set_attr "type" "frsqrt")
2271 (set_attr "mode" "DF")
2272 (set (attr "length")
2273 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2277 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2278 ;; "divdf3" comment for details).
2280 [(set (match_operand:SF 0 "register_operand" "=f")
2281 (sqrt:SF (div:SF (match_operand:SF 1 "const_1_operand" "")
2282 (match_operand:SF 2 "register_operand" "f"))))]
2283 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2286 return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2288 return "rsqrt.s\t%0,%2";
2290 [(set_attr "type" "frsqrt")
2291 (set_attr "mode" "SF")
2292 (set (attr "length")
2293 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2298 ;; ....................
2302 ;; ....................
2304 ;; Do not use the integer abs macro instruction, since that signals an
2305 ;; exception on -2147483648 (sigh).
2307 (define_insn "abssi2"
2308 [(set (match_operand:SI 0 "register_operand" "=d")
2309 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2312 operands[2] = const0_rtx;
2314 if (REGNO (operands[0]) == REGNO (operands[1]))
2316 if (GENERATE_BRANCHLIKELY)
2317 return "%(bltzl\t%1,1f\;subu\t%0,%z2,%0\n%~1:%)";
2319 return "bgez\t%1,1f%#\;subu\t%0,%z2,%0\n%~1:";
2322 return "%(bgez\t%1,1f\;move\t%0,%1\;subu\t%0,%z2,%0\n%~1:%)";
2324 [(set_attr "type" "multi")
2325 (set_attr "mode" "SI")
2326 (set_attr "length" "12")])
2328 (define_insn "absdi2"
2329 [(set (match_operand:DI 0 "register_operand" "=d")
2330 (abs:DI (match_operand:DI 1 "register_operand" "d")))]
2331 "TARGET_64BIT && !TARGET_MIPS16"
2333 unsigned int regno1;
2334 operands[2] = const0_rtx;
2336 if (GET_CODE (operands[1]) == REG)
2337 regno1 = REGNO (operands[1]);
2339 regno1 = REGNO (XEXP (operands[1], 0));
2341 if (REGNO (operands[0]) == regno1)
2342 return "%(bltzl\t%1,1f\;dsubu\t%0,%z2,%0\n%~1:%)";
2344 return "%(bgez\t%1,1f\;move\t%0,%1\;dsubu\t%0,%z2,%0\n%~1:%)";
2346 [(set_attr "type" "multi")
2347 (set_attr "mode" "DI")
2348 (set_attr "length" "12")])
2350 (define_insn "absdf2"
2351 [(set (match_operand:DF 0 "register_operand" "=f")
2352 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2353 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2355 [(set_attr "type" "fabs")
2356 (set_attr "mode" "DF")])
2358 (define_insn "abssf2"
2359 [(set (match_operand:SF 0 "register_operand" "=f")
2360 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2363 [(set_attr "type" "fabs")
2364 (set_attr "mode" "SF")])
2367 ;; ....................
2369 ;; FIND FIRST BIT INSTRUCTION
2371 ;; ....................
2374 (define_insn "ffssi2"
2375 [(set (match_operand:SI 0 "register_operand" "=&d")
2376 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2377 (clobber (match_scratch:SI 2 "=&d"))
2378 (clobber (match_scratch:SI 3 "=&d"))]
2381 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2385 %~1:\tand\t%2,%1,0x0001\;\
2395 %~1:\tand\t%2,%3,0x0001\;\
2401 [(set_attr "type" "multi")
2402 (set_attr "mode" "SI")
2403 (set_attr "length" "28")])
2405 (define_insn "ffsdi2"
2406 [(set (match_operand:DI 0 "register_operand" "=&d")
2407 (ffs:DI (match_operand:DI 1 "register_operand" "d")))
2408 (clobber (match_scratch:DI 2 "=&d"))
2409 (clobber (match_scratch:DI 3 "=&d"))]
2410 "TARGET_64BIT && !TARGET_MIPS16"
2412 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2416 %~1:\tand\t%2,%1,0x0001\;\
2426 %~1:\tand\t%2,%3,0x0001\;\
2432 [(set_attr "type" "multi")
2433 (set_attr "mode" "DI")
2434 (set_attr "length" "28")])
2437 ;; ...................
2439 ;; Count leading zeroes.
2441 ;; ...................
2444 (define_insn "clzsi2"
2445 [(set (match_operand:SI 0 "register_operand" "=d")
2446 (clz:SI (match_operand:SI 1 "register_operand" "d")))]
2449 [(set_attr "type" "clz")
2450 (set_attr "mode" "SI")])
2452 (define_insn "clzdi2"
2453 [(set (match_operand:DI 0 "register_operand" "=d")
2454 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
2457 [(set_attr "type" "clz")
2458 (set_attr "mode" "DI")])
2461 ;; ....................
2463 ;; NEGATION and ONE'S COMPLEMENT
2465 ;; ....................
2467 (define_insn "negsi2"
2468 [(set (match_operand:SI 0 "register_operand" "=d")
2469 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2473 return "neg\t%0,%1";
2475 return "subu\t%0,%.,%1";
2477 [(set_attr "type" "arith")
2478 (set_attr "mode" "SI")])
2480 (define_insn "negdi2"
2481 [(set (match_operand:DI 0 "register_operand" "=d")
2482 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2483 "TARGET_64BIT && !TARGET_MIPS16"
2485 [(set_attr "type" "arith")
2486 (set_attr "mode" "DI")])
2488 (define_insn "negdf2"
2489 [(set (match_operand:DF 0 "register_operand" "=f")
2490 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2491 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2493 [(set_attr "type" "fneg")
2494 (set_attr "mode" "DF")])
2496 (define_insn "negsf2"
2497 [(set (match_operand:SF 0 "register_operand" "=f")
2498 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2501 [(set_attr "type" "fneg")
2502 (set_attr "mode" "SF")])
2504 (define_insn "one_cmplsi2"
2505 [(set (match_operand:SI 0 "register_operand" "=d")
2506 (not:SI (match_operand:SI 1 "register_operand" "d")))]
2510 return "not\t%0,%1";
2512 return "nor\t%0,%.,%1";
2514 [(set_attr "type" "arith")
2515 (set_attr "mode" "SI")])
2517 (define_insn "one_cmpldi2"
2518 [(set (match_operand:DI 0 "register_operand" "=d")
2519 (not:DI (match_operand:DI 1 "register_operand" "d")))]
2523 return "not\t%0,%1";
2525 return "nor\t%0,%.,%1";
2527 [(set_attr "type" "arith")
2528 (set_attr "mode" "DI")])
2531 ;; ....................
2535 ;; ....................
2538 ;; Many of these instructions use trivial define_expands, because we
2539 ;; want to use a different set of constraints when TARGET_MIPS16.
2541 (define_expand "andsi3"
2542 [(set (match_operand:SI 0 "register_operand")
2543 (and:SI (match_operand:SI 1 "uns_arith_operand")
2544 (match_operand:SI 2 "uns_arith_operand")))]
2549 operands[1] = force_reg (SImode, operands[1]);
2550 operands[2] = force_reg (SImode, operands[2]);
2555 [(set (match_operand:SI 0 "register_operand" "=d,d")
2556 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2557 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2562 [(set_attr "type" "arith")
2563 (set_attr "mode" "SI")])
2566 [(set (match_operand:SI 0 "register_operand" "=d")
2567 (and:SI (match_operand:SI 1 "register_operand" "%0")
2568 (match_operand:SI 2 "register_operand" "d")))]
2571 [(set_attr "type" "arith")
2572 (set_attr "mode" "SI")])
2574 (define_expand "anddi3"
2575 [(set (match_operand:DI 0 "register_operand")
2576 (and:DI (match_operand:DI 1 "register_operand")
2577 (match_operand:DI 2 "uns_arith_operand")))]
2582 operands[1] = force_reg (DImode, operands[1]);
2583 operands[2] = force_reg (DImode, operands[2]);
2588 [(set (match_operand:DI 0 "register_operand" "=d,d")
2589 (and:DI (match_operand:DI 1 "register_operand" "d,d")
2590 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2591 "TARGET_64BIT && !TARGET_MIPS16"
2595 [(set_attr "type" "arith")
2596 (set_attr "mode" "DI")])
2599 [(set (match_operand:DI 0 "register_operand" "=d")
2600 (and:DI (match_operand:DI 1 "register_operand" "0")
2601 (match_operand:DI 2 "register_operand" "d")))]
2602 "TARGET_64BIT && TARGET_MIPS16"
2604 [(set_attr "type" "arith")
2605 (set_attr "mode" "DI")])
2607 (define_expand "iorsi3"
2608 [(set (match_operand:SI 0 "register_operand")
2609 (ior:SI (match_operand:SI 1 "uns_arith_operand")
2610 (match_operand:SI 2 "uns_arith_operand")))]
2615 operands[1] = force_reg (SImode, operands[1]);
2616 operands[2] = force_reg (SImode, operands[2]);
2621 [(set (match_operand:SI 0 "register_operand" "=d,d")
2622 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2623 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2628 [(set_attr "type" "arith")
2629 (set_attr "mode" "SI")])
2632 [(set (match_operand:SI 0 "register_operand" "=d")
2633 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2634 (match_operand:SI 2 "register_operand" "d")))]
2637 [(set_attr "type" "arith")
2638 (set_attr "mode" "SI")])
2640 (define_expand "iordi3"
2641 [(set (match_operand:DI 0 "register_operand")
2642 (ior:DI (match_operand:DI 1 "register_operand")
2643 (match_operand:DI 2 "uns_arith_operand")))]
2648 operands[1] = force_reg (DImode, operands[1]);
2649 operands[2] = force_reg (DImode, operands[2]);
2654 [(set (match_operand:DI 0 "register_operand" "=d,d")
2655 (ior:DI (match_operand:DI 1 "register_operand" "d,d")
2656 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2657 "TARGET_64BIT && !TARGET_MIPS16"
2661 [(set_attr "type" "arith")
2662 (set_attr "mode" "DI")])
2665 [(set (match_operand:DI 0 "register_operand" "=d")
2666 (ior:DI (match_operand:DI 1 "register_operand" "0")
2667 (match_operand:DI 2 "register_operand" "d")))]
2668 "TARGET_64BIT && TARGET_MIPS16"
2670 [(set_attr "type" "arith")
2671 (set_attr "mode" "DI")])
2673 (define_expand "xorsi3"
2674 [(set (match_operand:SI 0 "register_operand")
2675 (xor:SI (match_operand:SI 1 "uns_arith_operand")
2676 (match_operand:SI 2 "uns_arith_operand")))]
2681 [(set (match_operand:SI 0 "register_operand" "=d,d")
2682 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2683 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2688 [(set_attr "type" "arith")
2689 (set_attr "mode" "SI")])
2692 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
2693 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
2694 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
2700 [(set_attr "type" "arith")
2701 (set_attr "mode" "SI")
2702 (set_attr_alternative "length"
2704 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2709 (define_expand "xordi3"
2710 [(set (match_operand:DI 0 "register_operand")
2711 (xor:DI (match_operand:DI 1 "register_operand")
2712 (match_operand:DI 2 "uns_arith_operand")))]
2717 operands[1] = force_reg (DImode, operands[1]);
2718 operands[2] = force_reg (DImode, operands[2]);
2723 [(set (match_operand:DI 0 "register_operand" "=d,d")
2724 (xor:DI (match_operand:DI 1 "register_operand" "d,d")
2725 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2726 "TARGET_64BIT && !TARGET_MIPS16"
2730 [(set_attr "type" "arith")
2731 (set_attr "mode" "DI")])
2734 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
2735 (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
2736 (match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
2737 "TARGET_64BIT && TARGET_MIPS16"
2742 [(set_attr "type" "arith")
2743 (set_attr "mode" "DI")
2744 (set_attr_alternative "length"
2746 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2751 (define_insn "*norsi3"
2752 [(set (match_operand:SI 0 "register_operand" "=d")
2753 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
2754 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
2757 [(set_attr "type" "arith")
2758 (set_attr "mode" "SI")])
2760 (define_insn "*nordi3"
2761 [(set (match_operand:DI 0 "register_operand" "=d")
2762 (and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
2763 (not:DI (match_operand:DI 2 "register_operand" "d"))))]
2764 "TARGET_64BIT && !TARGET_MIPS16"
2766 [(set_attr "type" "arith")
2767 (set_attr "mode" "DI")])
2770 ;; ....................
2774 ;; ....................
2778 (define_insn "truncdfsf2"
2779 [(set (match_operand:SF 0 "register_operand" "=f")
2780 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2781 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2783 [(set_attr "type" "fcvt")
2784 (set_attr "mode" "SF")])
2786 ;; Integer truncation patterns. Truncating SImode values to smaller
2787 ;; modes is a no-op, as it is for most other GCC ports. Truncating
2788 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2789 ;; need to make sure that the lower 32 bits are properly sign-extended
2790 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
2791 ;; smaller than SImode is equivalent to two separate truncations:
2794 ;; DI ---> HI == DI ---> SI ---> HI
2795 ;; DI ---> QI == DI ---> SI ---> QI
2797 ;; Step A needs a real instruction but step B does not.
2799 (define_insn "truncdisi2"
2800 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2801 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2806 [(set_attr "type" "shift,store")
2807 (set_attr "mode" "SI")
2808 (set_attr "extended_mips16" "yes,*")])
2810 (define_insn "truncdihi2"
2811 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2812 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2817 [(set_attr "type" "shift,store")
2818 (set_attr "mode" "SI")
2819 (set_attr "extended_mips16" "yes,*")])
2821 (define_insn "truncdiqi2"
2822 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2823 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2828 [(set_attr "type" "shift,store")
2829 (set_attr "mode" "SI")
2830 (set_attr "extended_mips16" "yes,*")])
2832 ;; Combiner patterns to optimize shift/truncate combinations.
2835 [(set (match_operand:SI 0 "register_operand" "=d")
2837 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2838 (match_operand:DI 2 "const_arith_operand" ""))))]
2839 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2841 [(set_attr "type" "shift")
2842 (set_attr "mode" "SI")])
2845 [(set (match_operand:SI 0 "register_operand" "=d")
2846 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2848 "TARGET_64BIT && !TARGET_MIPS16"
2850 [(set_attr "type" "shift")
2851 (set_attr "mode" "SI")])
2854 ;; Combiner patterns for truncate/sign_extend combinations. They use
2855 ;; the shift/truncate patterns above.
2857 (define_insn_and_split ""
2858 [(set (match_operand:SI 0 "register_operand" "=d")
2860 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2861 "TARGET_64BIT && !TARGET_MIPS16"
2863 "&& reload_completed"
2865 (ashift:DI (match_dup 1)
2868 (truncate:SI (ashiftrt:DI (match_dup 2)
2870 { operands[2] = gen_lowpart (DImode, operands[0]); })
2872 (define_insn_and_split ""
2873 [(set (match_operand:SI 0 "register_operand" "=d")
2875 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2876 "TARGET_64BIT && !TARGET_MIPS16"
2878 "&& reload_completed"
2880 (ashift:DI (match_dup 1)
2883 (truncate:SI (ashiftrt:DI (match_dup 2)
2885 { operands[2] = gen_lowpart (DImode, operands[0]); })
2888 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2891 [(set (match_operand:SI 0 "register_operand" "=d")
2892 (zero_extend:SI (truncate:HI
2893 (match_operand:DI 1 "register_operand" "d"))))]
2894 "TARGET_64BIT && !TARGET_MIPS16"
2895 "andi\t%0,%1,0xffff"
2896 [(set_attr "type" "arith")
2897 (set_attr "mode" "SI")])
2900 [(set (match_operand:SI 0 "register_operand" "=d")
2901 (zero_extend:SI (truncate:QI
2902 (match_operand:DI 1 "register_operand" "d"))))]
2903 "TARGET_64BIT && !TARGET_MIPS16"
2905 [(set_attr "type" "arith")
2906 (set_attr "mode" "SI")])
2909 [(set (match_operand:HI 0 "register_operand" "=d")
2910 (zero_extend:HI (truncate:QI
2911 (match_operand:DI 1 "register_operand" "d"))))]
2912 "TARGET_64BIT && !TARGET_MIPS16"
2914 [(set_attr "type" "arith")
2915 (set_attr "mode" "HI")])
2918 ;; ....................
2922 ;; ....................
2925 ;; Those for integer source operand are ordered widest source type first.
2927 (define_insn_and_split "zero_extendsidi2"
2928 [(set (match_operand:DI 0 "register_operand" "=d")
2929 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2932 "&& reload_completed"
2934 (ashift:DI (match_dup 1) (const_int 32)))
2936 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2937 "operands[1] = gen_lowpart (DImode, operands[1]);"
2938 [(set_attr "type" "multi")
2939 (set_attr "mode" "DI")
2940 (set_attr "length" "8")])
2942 (define_insn "*zero_extendsidi2_mem"
2943 [(set (match_operand:DI 0 "register_operand" "=d")
2944 (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2947 [(set_attr "type" "load")
2948 (set_attr "mode" "DI")])
2950 (define_expand "zero_extendhisi2"
2951 [(set (match_operand:SI 0 "register_operand")
2952 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2955 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2957 rtx op = gen_lowpart (SImode, operands[1]);
2958 rtx temp = force_reg (SImode, GEN_INT (0xffff));
2960 emit_insn (gen_andsi3 (operands[0], op, temp));
2966 [(set (match_operand:SI 0 "register_operand" "=d,d")
2967 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2972 [(set_attr "type" "arith,load")
2973 (set_attr "mode" "SI")
2974 (set_attr "length" "4,*")])
2977 [(set (match_operand:SI 0 "register_operand" "=d")
2978 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2981 [(set_attr "type" "load")
2982 (set_attr "mode" "SI")])
2984 (define_expand "zero_extendhidi2"
2985 [(set (match_operand:DI 0 "register_operand")
2986 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2989 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2991 rtx op = gen_lowpart (DImode, operands[1]);
2992 rtx temp = force_reg (DImode, GEN_INT (0xffff));
2994 emit_insn (gen_anddi3 (operands[0], op, temp));
3000 [(set (match_operand:DI 0 "register_operand" "=d,d")
3001 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
3002 "TARGET_64BIT && !TARGET_MIPS16"
3006 [(set_attr "type" "arith,load")
3007 (set_attr "mode" "DI")
3008 (set_attr "length" "4,*")])
3011 [(set (match_operand:DI 0 "register_operand" "=d")
3012 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3013 "TARGET_64BIT && TARGET_MIPS16"
3015 [(set_attr "type" "load")
3016 (set_attr "mode" "DI")])
3018 (define_expand "zero_extendqihi2"
3019 [(set (match_operand:HI 0 "register_operand")
3020 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3023 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3025 rtx op0 = gen_lowpart (SImode, operands[0]);
3026 rtx op1 = gen_lowpart (SImode, operands[1]);
3027 rtx temp = force_reg (SImode, GEN_INT (0xff));
3029 emit_insn (gen_andsi3 (op0, op1, temp));
3035 [(set (match_operand:HI 0 "register_operand" "=d,d")
3036 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3041 [(set_attr "type" "arith,load")
3042 (set_attr "mode" "HI")
3043 (set_attr "length" "4,*")])
3046 [(set (match_operand:HI 0 "register_operand" "=d")
3047 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3050 [(set_attr "type" "load")
3051 (set_attr "mode" "HI")])
3053 (define_expand "zero_extendqisi2"
3054 [(set (match_operand:SI 0 "register_operand")
3055 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3058 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3060 rtx op = gen_lowpart (SImode, operands[1]);
3061 rtx temp = force_reg (SImode, GEN_INT (0xff));
3063 emit_insn (gen_andsi3 (operands[0], op, temp));
3069 [(set (match_operand:SI 0 "register_operand" "=d,d")
3070 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3075 [(set_attr "type" "arith,load")
3076 (set_attr "mode" "SI")
3077 (set_attr "length" "4,*")])
3080 [(set (match_operand:SI 0 "register_operand" "=d")
3081 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3084 [(set_attr "type" "load")
3085 (set_attr "mode" "SI")])
3087 (define_expand "zero_extendqidi2"
3088 [(set (match_operand:DI 0 "register_operand")
3089 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3092 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3094 rtx op = gen_lowpart (DImode, operands[1]);
3095 rtx temp = force_reg (DImode, GEN_INT (0xff));
3097 emit_insn (gen_anddi3 (operands[0], op, temp));
3103 [(set (match_operand:DI 0 "register_operand" "=d,d")
3104 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3105 "TARGET_64BIT && !TARGET_MIPS16"
3109 [(set_attr "type" "arith,load")
3110 (set_attr "mode" "DI")
3111 (set_attr "length" "4,*")])
3114 [(set (match_operand:DI 0 "register_operand" "=d")
3115 (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3116 "TARGET_64BIT && TARGET_MIPS16"
3118 [(set_attr "type" "load")
3119 (set_attr "mode" "DI")])
3122 ;; ....................
3126 ;; ....................
3129 ;; Those for integer source operand are ordered widest source type first.
3131 ;; When TARGET_64BIT, all SImode integer registers should already be in
3132 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
3133 ;; therefore get rid of register->register instructions if we constrain
3134 ;; the source to be in the same register as the destination.
3136 ;; The register alternative has type "arith" so that the pre-reload
3137 ;; scheduler will treat it as a move. This reflects what happens if
3138 ;; the register alternative needs a reload.
3139 (define_insn_and_split "extendsidi2"
3140 [(set (match_operand:DI 0 "register_operand" "=d,d")
3141 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
3146 "&& reload_completed && register_operand (operands[1], VOIDmode)"
3149 emit_note (NOTE_INSN_DELETED);
3152 [(set_attr "type" "arith,load")
3153 (set_attr "mode" "DI")])
3155 ;; These patterns originally accepted general_operands, however, slightly
3156 ;; better code is generated by only accepting register_operands, and then
3157 ;; letting combine generate the lh and lb insns.
3159 ;; These expanders originally put values in registers first. We split
3160 ;; all non-mem patterns after reload.
3162 (define_expand "extendhidi2"
3163 [(set (match_operand:DI 0 "register_operand")
3164 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
3168 (define_insn "*extendhidi2"
3169 [(set (match_operand:DI 0 "register_operand" "=d")
3170 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
3175 [(set (match_operand:DI 0 "register_operand")
3176 (sign_extend:DI (match_operand:HI 1 "register_operand")))]
3177 "TARGET_64BIT && reload_completed"
3179 (ashift:DI (match_dup 1) (const_int 48)))
3181 (ashiftrt:DI (match_dup 0) (const_int 48)))]
3182 "operands[1] = gen_lowpart (DImode, operands[1]);")
3184 (define_insn "*extendhidi2_mem"
3185 [(set (match_operand:DI 0 "register_operand" "=d")
3186 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3189 [(set_attr "type" "load")
3190 (set_attr "mode" "DI")])
3192 (define_expand "extendhisi2"
3193 [(set (match_operand:SI 0 "register_operand")
3194 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
3197 if (ISA_HAS_SEB_SEH)
3199 emit_insn (gen_extendhisi2_hw (operands[0],
3200 force_reg (HImode, operands[1])));
3205 (define_insn "*extendhisi2"
3206 [(set (match_operand:SI 0 "register_operand" "=d")
3207 (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
3212 [(set (match_operand:SI 0 "register_operand")
3213 (sign_extend:SI (match_operand:HI 1 "register_operand")))]
3216 (ashift:SI (match_dup 1) (const_int 16)))
3218 (ashiftrt:SI (match_dup 0) (const_int 16)))]
3219 "operands[1] = gen_lowpart (SImode, operands[1]);")
3221 (define_insn "extendhisi2_mem"
3222 [(set (match_operand:SI 0 "register_operand" "=d")
3223 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3226 [(set_attr "type" "load")
3227 (set_attr "mode" "SI")])
3229 (define_insn "extendhisi2_hw"
3230 [(set (match_operand:SI 0 "register_operand" "=r")
3231 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
3234 [(set_attr "type" "arith")
3235 (set_attr "mode" "SI")])
3237 (define_expand "extendqihi2"
3238 [(set (match_operand:HI 0 "register_operand")
3239 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3243 (define_insn "*extendqihi2"
3244 [(set (match_operand:HI 0 "register_operand" "=d")
3245 (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
3250 [(set (match_operand:HI 0 "register_operand")
3251 (sign_extend:HI (match_operand:QI 1 "register_operand")))]
3254 (ashift:SI (match_dup 1) (const_int 24)))
3256 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3257 "operands[0] = gen_lowpart (SImode, operands[0]);
3258 operands[1] = gen_lowpart (SImode, operands[1]);")
3260 (define_insn "*extendqihi2_internal_mem"
3261 [(set (match_operand:HI 0 "register_operand" "=d")
3262 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3265 [(set_attr "type" "load")
3266 (set_attr "mode" "SI")])
3269 (define_expand "extendqisi2"
3270 [(set (match_operand:SI 0 "register_operand")
3271 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3274 if (ISA_HAS_SEB_SEH)
3276 emit_insn (gen_extendqisi2_hw (operands[0],
3277 force_reg (QImode, operands[1])));
3282 (define_insn "*extendqisi2"
3283 [(set (match_operand:SI 0 "register_operand" "=d")
3284 (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
3289 [(set (match_operand:SI 0 "register_operand")
3290 (sign_extend:SI (match_operand:QI 1 "register_operand")))]
3293 (ashift:SI (match_dup 1) (const_int 24)))
3295 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3296 "operands[1] = gen_lowpart (SImode, operands[1]);")
3298 (define_insn "*extendqisi2_mem"
3299 [(set (match_operand:SI 0 "register_operand" "=d")
3300 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3303 [(set_attr "type" "load")
3304 (set_attr "mode" "SI")])
3306 (define_insn "extendqisi2_hw"
3307 [(set (match_operand:SI 0 "register_operand" "=r")
3308 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
3311 [(set_attr "type" "arith")
3312 (set_attr "mode" "SI")])
3314 (define_expand "extendqidi2"
3315 [(set (match_operand:DI 0 "register_operand")
3316 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3320 (define_insn "*extendqidi2"
3321 [(set (match_operand:DI 0 "register_operand" "=d")
3322 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
3327 [(set (match_operand:DI 0 "register_operand")
3328 (sign_extend:DI (match_operand:QI 1 "register_operand")))]
3329 "TARGET_64BIT && reload_completed"
3331 (ashift:DI (match_dup 1) (const_int 56)))
3333 (ashiftrt:DI (match_dup 0) (const_int 56)))]
3334 "operands[1] = gen_lowpart (DImode, operands[1]);")
3336 (define_insn "*extendqidi2_mem"
3337 [(set (match_operand:DI 0 "register_operand" "=d")
3338 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3341 [(set_attr "type" "load")
3342 (set_attr "mode" "DI")])
3344 (define_insn "extendsfdf2"
3345 [(set (match_operand:DF 0 "register_operand" "=f")
3346 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3347 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3349 [(set_attr "type" "fcvt")
3350 (set_attr "mode" "DF")])
3353 ;; ....................
3357 ;; ....................
3359 (define_expand "fix_truncdfsi2"
3360 [(set (match_operand:SI 0 "register_operand")
3361 (fix:SI (match_operand:DF 1 "register_operand")))]
3362 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3364 if (!ISA_HAS_TRUNC_W)
3366 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3371 (define_insn "fix_truncdfsi2_insn"
3372 [(set (match_operand:SI 0 "register_operand" "=f")
3373 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3374 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3376 [(set_attr "type" "fcvt")
3377 (set_attr "mode" "DF")
3378 (set_attr "length" "4")])
3380 (define_insn "fix_truncdfsi2_macro"
3381 [(set (match_operand:SI 0 "register_operand" "=f")
3382 (fix:SI (match_operand:DF 1 "register_operand" "f")))
3383 (clobber (match_scratch:DF 2 "=d"))]
3384 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3387 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3389 return "trunc.w.d %0,%1,%2";
3391 [(set_attr "type" "fcvt")
3392 (set_attr "mode" "DF")
3393 (set_attr "length" "36")])
3395 (define_expand "fix_truncsfsi2"
3396 [(set (match_operand:SI 0 "register_operand")
3397 (fix:SI (match_operand:SF 1 "register_operand")))]
3400 if (!ISA_HAS_TRUNC_W)
3402 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3407 (define_insn "fix_truncsfsi2_insn"
3408 [(set (match_operand:SI 0 "register_operand" "=f")
3409 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3410 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3412 [(set_attr "type" "fcvt")
3413 (set_attr "mode" "DF")
3414 (set_attr "length" "4")])
3416 (define_insn "fix_truncsfsi2_macro"
3417 [(set (match_operand:SI 0 "register_operand" "=f")
3418 (fix:SI (match_operand:SF 1 "register_operand" "f")))
3419 (clobber (match_scratch:SF 2 "=d"))]
3420 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3423 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3425 return "trunc.w.s %0,%1,%2";
3427 [(set_attr "type" "fcvt")
3428 (set_attr "mode" "DF")
3429 (set_attr "length" "36")])
3432 (define_insn "fix_truncdfdi2"
3433 [(set (match_operand:DI 0 "register_operand" "=f")
3434 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3435 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3437 [(set_attr "type" "fcvt")
3438 (set_attr "mode" "DF")
3439 (set_attr "length" "4")])
3442 (define_insn "fix_truncsfdi2"
3443 [(set (match_operand:DI 0 "register_operand" "=f")
3444 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3445 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3447 [(set_attr "type" "fcvt")
3448 (set_attr "mode" "SF")
3449 (set_attr "length" "4")])
3452 (define_insn "floatsidf2"
3453 [(set (match_operand:DF 0 "register_operand" "=f")
3454 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3455 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3457 [(set_attr "type" "fcvt")
3458 (set_attr "mode" "DF")
3459 (set_attr "length" "4")])
3462 (define_insn "floatdidf2"
3463 [(set (match_operand:DF 0 "register_operand" "=f")
3464 (float:DF (match_operand:DI 1 "register_operand" "f")))]
3465 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3467 [(set_attr "type" "fcvt")
3468 (set_attr "mode" "DF")
3469 (set_attr "length" "4")])
3472 (define_insn "floatsisf2"
3473 [(set (match_operand:SF 0 "register_operand" "=f")
3474 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3477 [(set_attr "type" "fcvt")
3478 (set_attr "mode" "SF")
3479 (set_attr "length" "4")])
3482 (define_insn "floatdisf2"
3483 [(set (match_operand:SF 0 "register_operand" "=f")
3484 (float:SF (match_operand:DI 1 "register_operand" "f")))]
3485 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3487 [(set_attr "type" "fcvt")
3488 (set_attr "mode" "SF")
3489 (set_attr "length" "4")])
3492 (define_expand "fixuns_truncdfsi2"
3493 [(set (match_operand:SI 0 "register_operand")
3494 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
3495 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3497 rtx reg1 = gen_reg_rtx (DFmode);
3498 rtx reg2 = gen_reg_rtx (DFmode);
3499 rtx reg3 = gen_reg_rtx (SImode);
3500 rtx label1 = gen_label_rtx ();
3501 rtx label2 = gen_label_rtx ();
3502 REAL_VALUE_TYPE offset;
3504 real_2expN (&offset, 31);
3506 if (reg1) /* Turn off complaints about unreached code. */
3508 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3509 do_pending_stack_adjust ();
3511 emit_insn (gen_cmpdf (operands[1], reg1));
3512 emit_jump_insn (gen_bge (label1));
3514 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3515 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3516 gen_rtx_LABEL_REF (VOIDmode, label2)));
3519 emit_label (label1);
3520 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3521 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3522 (BITMASK_HIGH, SImode)));
3524 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3525 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3527 emit_label (label2);
3529 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3530 fields, and can't be used for REG_NOTES anyway). */
3531 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3537 (define_expand "fixuns_truncdfdi2"
3538 [(set (match_operand:DI 0 "register_operand")
3539 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3540 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3542 rtx reg1 = gen_reg_rtx (DFmode);
3543 rtx reg2 = gen_reg_rtx (DFmode);
3544 rtx reg3 = gen_reg_rtx (DImode);
3545 rtx label1 = gen_label_rtx ();
3546 rtx label2 = gen_label_rtx ();
3547 REAL_VALUE_TYPE offset;
3549 real_2expN (&offset, 63);
3551 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3552 do_pending_stack_adjust ();
3554 emit_insn (gen_cmpdf (operands[1], reg1));
3555 emit_jump_insn (gen_bge (label1));
3557 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3558 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3559 gen_rtx_LABEL_REF (VOIDmode, label2)));
3562 emit_label (label1);
3563 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3564 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3565 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3567 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3568 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3570 emit_label (label2);
3572 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3573 fields, and can't be used for REG_NOTES anyway). */
3574 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3579 (define_expand "fixuns_truncsfsi2"
3580 [(set (match_operand:SI 0 "register_operand")
3581 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3584 rtx reg1 = gen_reg_rtx (SFmode);
3585 rtx reg2 = gen_reg_rtx (SFmode);
3586 rtx reg3 = gen_reg_rtx (SImode);
3587 rtx label1 = gen_label_rtx ();
3588 rtx label2 = gen_label_rtx ();
3589 REAL_VALUE_TYPE offset;
3591 real_2expN (&offset, 31);
3593 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3594 do_pending_stack_adjust ();
3596 emit_insn (gen_cmpsf (operands[1], reg1));
3597 emit_jump_insn (gen_bge (label1));
3599 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3600 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3601 gen_rtx_LABEL_REF (VOIDmode, label2)));
3604 emit_label (label1);
3605 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3606 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3607 (BITMASK_HIGH, SImode)));
3609 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3610 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3612 emit_label (label2);
3614 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3615 fields, and can't be used for REG_NOTES anyway). */
3616 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3621 (define_expand "fixuns_truncsfdi2"
3622 [(set (match_operand:DI 0 "register_operand")
3623 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3624 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3626 rtx reg1 = gen_reg_rtx (SFmode);
3627 rtx reg2 = gen_reg_rtx (SFmode);
3628 rtx reg3 = gen_reg_rtx (DImode);
3629 rtx label1 = gen_label_rtx ();
3630 rtx label2 = gen_label_rtx ();
3631 REAL_VALUE_TYPE offset;
3633 real_2expN (&offset, 63);
3635 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3636 do_pending_stack_adjust ();
3638 emit_insn (gen_cmpsf (operands[1], reg1));
3639 emit_jump_insn (gen_bge (label1));
3641 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3642 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3643 gen_rtx_LABEL_REF (VOIDmode, label2)));
3646 emit_label (label1);
3647 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3648 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3649 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3651 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3652 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3654 emit_label (label2);
3656 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3657 fields, and can't be used for REG_NOTES anyway). */
3658 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3663 ;; ....................
3667 ;; ....................
3669 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3671 (define_expand "extv"
3672 [(set (match_operand 0 "register_operand")
3673 (sign_extract (match_operand:QI 1 "memory_operand")
3674 (match_operand 2 "immediate_operand")
3675 (match_operand 3 "immediate_operand")))]
3678 if (mips_expand_unaligned_load (operands[0], operands[1],
3679 INTVAL (operands[2]),
3680 INTVAL (operands[3])))
3686 (define_expand "extzv"
3687 [(set (match_operand 0 "register_operand")
3688 (zero_extract (match_operand:QI 1 "memory_operand")
3689 (match_operand 2 "immediate_operand")
3690 (match_operand 3 "immediate_operand")))]
3693 if (mips_expand_unaligned_load (operands[0], operands[1],
3694 INTVAL (operands[2]),
3695 INTVAL (operands[3])))
3701 (define_expand "insv"
3702 [(set (zero_extract (match_operand:QI 0 "memory_operand")
3703 (match_operand 1 "immediate_operand")
3704 (match_operand 2 "immediate_operand"))
3705 (match_operand 3 "reg_or_0_operand"))]
3708 if (mips_expand_unaligned_store (operands[0], operands[3],
3709 INTVAL (operands[1]),
3710 INTVAL (operands[2])))
3716 ;; Unaligned word moves generated by the bit field patterns.
3718 ;; As far as the rtl is concerned, both the left-part and right-part
3719 ;; instructions can access the whole field. However, the real operand
3720 ;; refers to just the first or the last byte (depending on endianness).
3721 ;; We therefore use two memory operands to each instruction, one to
3722 ;; describe the rtl effect and one to use in the assembly output.
3724 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3725 ;; This allows us to use the standard length calculations for the "load"
3726 ;; and "store" type attributes.
3728 (define_insn "mov_lwl"
3729 [(set (match_operand:SI 0 "register_operand" "=d")
3730 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3731 (match_operand:QI 2 "memory_operand" "m")]
3735 [(set_attr "type" "load")
3736 (set_attr "mode" "SI")
3737 (set_attr "hazard" "none")])
3739 (define_insn "mov_lwr"
3740 [(set (match_operand:SI 0 "register_operand" "=d")
3741 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3742 (match_operand:QI 2 "memory_operand" "m")
3743 (match_operand:SI 3 "register_operand" "0")]
3747 [(set_attr "type" "load")
3748 (set_attr "mode" "SI")])
3751 (define_insn "mov_swl"
3752 [(set (match_operand:BLK 0 "memory_operand" "=m")
3753 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3754 (match_operand:QI 2 "memory_operand" "m")]
3758 [(set_attr "type" "store")
3759 (set_attr "mode" "SI")])
3761 (define_insn "mov_swr"
3762 [(set (match_operand:BLK 0 "memory_operand" "+m")
3763 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3764 (match_operand:QI 2 "memory_operand" "m")
3769 [(set_attr "type" "store")
3770 (set_attr "mode" "SI")])
3773 (define_insn "mov_ldl"
3774 [(set (match_operand:DI 0 "register_operand" "=d")
3775 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3776 (match_operand:QI 2 "memory_operand" "m")]
3778 "TARGET_64BIT && !TARGET_MIPS16"
3780 [(set_attr "type" "load")
3781 (set_attr "mode" "DI")])
3783 (define_insn "mov_ldr"
3784 [(set (match_operand:DI 0 "register_operand" "=d")
3785 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3786 (match_operand:QI 2 "memory_operand" "m")
3787 (match_operand:DI 3 "register_operand" "0")]
3789 "TARGET_64BIT && !TARGET_MIPS16"
3791 [(set_attr "type" "load")
3792 (set_attr "mode" "DI")])
3795 (define_insn "mov_sdl"
3796 [(set (match_operand:BLK 0 "memory_operand" "=m")
3797 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3798 (match_operand:QI 2 "memory_operand" "m")]
3800 "TARGET_64BIT && !TARGET_MIPS16"
3802 [(set_attr "type" "store")
3803 (set_attr "mode" "DI")])
3805 (define_insn "mov_sdr"
3806 [(set (match_operand:BLK 0 "memory_operand" "+m")
3807 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3808 (match_operand:QI 2 "memory_operand" "m")
3811 "TARGET_64BIT && !TARGET_MIPS16"
3813 [(set_attr "type" "store")
3814 (set_attr "mode" "DI")])
3816 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3817 ;; The required value is:
3819 ;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3821 ;; which translates to:
3823 ;; lui op0,%highest(op1)
3824 ;; daddiu op0,op0,%higher(op1)
3826 ;; daddiu op0,op0,%hi(op1)
3828 (define_insn_and_split "*lea_high64"
3829 [(set (match_operand:DI 0 "register_operand" "=d")
3830 (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3831 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3833 "&& reload_completed"
3834 [(set (match_dup 0) (high:DI (match_dup 2)))
3835 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3836 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3837 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3838 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3840 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3841 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3843 [(set_attr "length" "20")])
3845 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3846 ;; SYMBOL_GENERAL X will take 6 cycles. This next pattern allows combine
3847 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3848 ;; used once. We can then use the sequence:
3850 ;; lui op0,%highest(op1)
3852 ;; daddiu op0,op0,%higher(op1)
3853 ;; daddiu op2,op2,%lo(op1)
3855 ;; daddu op0,op0,op2
3857 ;; which takes 4 cycles on most superscalar targets.
3858 (define_insn_and_split "*lea64"
3859 [(set (match_operand:DI 0 "register_operand" "=d")
3860 (match_operand:DI 1 "general_symbolic_operand" ""))
3861 (clobber (match_scratch:DI 2 "=&d"))]
3862 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3864 "&& reload_completed"
3865 [(set (match_dup 0) (high:DI (match_dup 3)))
3866 (set (match_dup 2) (high:DI (match_dup 4)))
3867 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3868 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3869 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3870 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3872 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3873 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3875 [(set_attr "length" "24")])
3877 ;; Insns to fetch a global symbol from a big GOT.
3879 (define_insn_and_split "*xgot_hisi"
3880 [(set (match_operand:SI 0 "register_operand" "=d")
3881 (high:SI (match_operand:SI 1 "global_got_operand" "")))]
3882 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3884 "&& reload_completed"
3885 [(set (match_dup 0) (high:SI (match_dup 2)))
3886 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
3888 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3889 operands[3] = pic_offset_table_rtx;
3891 [(set_attr "got" "xgot_high")])
3893 (define_insn_and_split "*xgot_losi"
3894 [(set (match_operand:SI 0 "register_operand" "=d")
3895 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
3896 (match_operand:SI 2 "global_got_operand" "")))]
3897 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3899 "&& reload_completed"
3901 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3902 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3903 [(set_attr "got" "load")])
3905 (define_insn_and_split "*xgot_hidi"
3906 [(set (match_operand:DI 0 "register_operand" "=d")
3907 (high:DI (match_operand:DI 1 "global_got_operand" "")))]
3908 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3910 "&& reload_completed"
3911 [(set (match_dup 0) (high:DI (match_dup 2)))
3912 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
3914 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3915 operands[3] = pic_offset_table_rtx;
3917 [(set_attr "got" "xgot_high")])
3919 (define_insn_and_split "*xgot_lodi"
3920 [(set (match_operand:DI 0 "register_operand" "=d")
3921 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
3922 (match_operand:DI 2 "global_got_operand" "")))]
3923 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3925 "&& reload_completed"
3927 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3928 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3929 [(set_attr "got" "load")])
3931 ;; Insns to fetch a global symbol from a normal GOT.
3933 (define_insn_and_split "*got_dispsi"
3934 [(set (match_operand:SI 0 "register_operand" "=d")
3935 (match_operand:SI 1 "global_got_operand" ""))]
3936 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3938 "&& reload_completed"
3940 (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3942 operands[2] = pic_offset_table_rtx;
3943 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3945 [(set_attr "got" "load")])
3947 (define_insn_and_split "*got_dispdi"
3948 [(set (match_operand:DI 0 "register_operand" "=d")
3949 (match_operand:DI 1 "global_got_operand" ""))]
3950 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3952 "&& reload_completed"
3954 (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3956 operands[2] = pic_offset_table_rtx;
3957 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3959 [(set_attr "got" "load")])
3961 ;; Insns for loading the high part of a local symbol.
3963 (define_insn_and_split "*got_pagesi"
3964 [(set (match_operand:SI 0 "register_operand" "=d")
3965 (high:SI (match_operand:SI 1 "local_got_operand" "")))]
3966 "TARGET_EXPLICIT_RELOCS"
3968 "&& reload_completed"
3970 (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3972 operands[2] = pic_offset_table_rtx;
3973 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3975 [(set_attr "got" "load")])
3977 (define_insn_and_split "*got_pagedi"
3978 [(set (match_operand:DI 0 "register_operand" "=d")
3979 (high:DI (match_operand:DI 1 "local_got_operand" "")))]
3980 "TARGET_EXPLICIT_RELOCS"
3982 "&& reload_completed"
3984 (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3986 operands[2] = pic_offset_table_rtx;
3987 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3989 [(set_attr "got" "load")])
3991 ;; Lower-level instructions for loading an address from the GOT.
3992 ;; We could use MEMs, but an unspec gives more optimization
3995 (define_insn "*load_gotsi"
3996 [(set (match_operand:SI 0 "register_operand" "=d")
3997 (unspec:SI [(match_operand:SI 1 "register_operand" "d")
3998 (match_operand:SI 2 "immediate_operand" "")]
4002 [(set_attr "type" "load")
4003 (set_attr "length" "4")])
4005 (define_insn "*load_gotdi"
4006 [(set (match_operand:DI 0 "register_operand" "=d")
4007 (unspec:DI [(match_operand:DI 1 "register_operand" "d")
4008 (match_operand:DI 2 "immediate_operand" "")]
4012 [(set_attr "type" "load")
4013 (set_attr "length" "4")])
4015 ;; Instructions for adding the low 16 bits of an address to a register.
4016 ;; Operand 2 is the address: print_operand works out which relocation
4017 ;; should be applied.
4019 (define_insn "*lowsi"
4020 [(set (match_operand:SI 0 "register_operand" "=d")
4021 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
4022 (match_operand:SI 2 "immediate_operand" "")))]
4025 [(set_attr "type" "arith")
4026 (set_attr "mode" "SI")])
4028 (define_insn "*lowdi"
4029 [(set (match_operand:DI 0 "register_operand" "=d")
4030 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
4031 (match_operand:DI 2 "immediate_operand" "")))]
4032 "!TARGET_MIPS16 && TARGET_64BIT"
4034 [(set_attr "type" "arith")
4035 (set_attr "mode" "DI")])
4037 (define_insn "*lowsi_mips16"
4038 [(set (match_operand:SI 0 "register_operand" "=d")
4039 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
4040 (match_operand:SI 2 "immediate_operand" "")))]
4043 [(set_attr "type" "arith")
4044 (set_attr "mode" "SI")
4045 (set_attr "length" "8")])
4047 (define_insn "*lowdi_mips16"
4048 [(set (match_operand:DI 0 "register_operand" "=d")
4049 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
4050 (match_operand:DI 2 "immediate_operand" "")))]
4051 "TARGET_MIPS16 && TARGET_64BIT"
4053 [(set_attr "type" "arith")
4054 (set_attr "mode" "DI")
4055 (set_attr "length" "8")])
4057 ;; 64-bit integer moves
4059 ;; Unlike most other insns, the move insns can't be split with
4060 ;; different predicates, because register spilling and other parts of
4061 ;; the compiler, have memoized the insn number already.
4063 (define_expand "movdi"
4064 [(set (match_operand:DI 0 "")
4065 (match_operand:DI 1 ""))]
4068 if (mips_legitimize_move (DImode, operands[0], operands[1]))
4072 ;; For mips16, we need a special case to handle storing $31 into
4073 ;; memory, since we don't have a constraint to match $31. This
4074 ;; instruction can be generated by save_restore_insns.
4077 [(set (match_operand:DI 0 "stack_operand" "=m")
4079 "TARGET_MIPS16 && TARGET_64BIT"
4081 [(set_attr "type" "store")
4082 (set_attr "mode" "DI")])
4084 (define_insn "*movdi_32bit"
4085 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
4086 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
4087 "!TARGET_64BIT && !TARGET_MIPS16
4088 && (register_operand (operands[0], DImode)
4089 || reg_or_0_operand (operands[1], DImode))"
4090 { return mips_output_move (operands[0], operands[1]); }
4091 [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
4092 (set_attr "mode" "DI")
4093 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
4095 (define_insn "*movdi_32bit_mips16"
4096 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4097 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4098 "!TARGET_64BIT && TARGET_MIPS16
4099 && (register_operand (operands[0], DImode)
4100 || register_operand (operands[1], DImode))"
4101 { return mips_output_move (operands[0], operands[1]); }
4102 [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo")
4103 (set_attr "mode" "DI")
4104 (set_attr "length" "8,8,8,8,12,*,*,8")])
4106 (define_insn "*movdi_64bit"
4107 [(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")
4108 (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"))]
4109 "TARGET_64BIT && !TARGET_MIPS16
4110 && (register_operand (operands[0], DImode)
4111 || reg_or_0_operand (operands[1], DImode))"
4112 { return mips_output_move (operands[0], operands[1]); }
4113 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
4114 (set_attr "mode" "DI")
4115 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
4117 (define_insn "*movdi_64bit_mips16"
4118 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4119 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4120 "TARGET_64BIT && TARGET_MIPS16
4121 && (register_operand (operands[0], DImode)
4122 || register_operand (operands[1], DImode))"
4123 { return mips_output_move (operands[0], operands[1]); }
4124 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
4125 (set_attr "mode" "DI")
4126 (set_attr_alternative "length"
4130 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4133 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4138 (const_string "*")])])
4141 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4142 ;; when the original load is a 4 byte instruction but the add and the
4143 ;; load are 2 2 byte instructions.
4146 [(set (match_operand:DI 0 "register_operand")
4147 (mem:DI (plus:DI (match_dup 0)
4148 (match_operand:DI 1 "const_int_operand"))))]
4149 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4150 && !TARGET_DEBUG_D_MODE
4151 && GET_CODE (operands[0]) == REG
4152 && M16_REG_P (REGNO (operands[0]))
4153 && GET_CODE (operands[1]) == CONST_INT
4154 && ((INTVAL (operands[1]) < 0
4155 && INTVAL (operands[1]) >= -0x10)
4156 || (INTVAL (operands[1]) >= 32 * 8
4157 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4158 || (INTVAL (operands[1]) >= 0
4159 && INTVAL (operands[1]) < 32 * 8
4160 && (INTVAL (operands[1]) & 7) != 0))"
4161 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4162 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4164 HOST_WIDE_INT val = INTVAL (operands[1]);
4167 operands[2] = const0_rtx;
4168 else if (val >= 32 * 8)
4172 operands[1] = GEN_INT (0x8 + off);
4173 operands[2] = GEN_INT (val - off - 0x8);
4179 operands[1] = GEN_INT (off);
4180 operands[2] = GEN_INT (val - off);
4184 ;; 32-bit Integer moves
4186 ;; Unlike most other insns, the move insns can't be split with
4187 ;; different predicates, because register spilling and other parts of
4188 ;; the compiler, have memoized the insn number already.
4190 (define_expand "movsi"
4191 [(set (match_operand:SI 0 "")
4192 (match_operand:SI 1 ""))]
4195 if (mips_legitimize_move (SImode, operands[0], operands[1]))
4199 ;; We can only store $ra directly into a small sp offset.
4202 [(set (match_operand:SI 0 "stack_operand" "=m")
4206 [(set_attr "type" "store")
4207 (set_attr "mode" "SI")])
4209 ;; The difference between these two is whether or not ints are allowed
4210 ;; in FP registers (off by default, use -mdebugh to enable).
4212 (define_insn "*movsi_internal"
4213 [(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")
4214 (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"))]
4216 && (register_operand (operands[0], SImode)
4217 || reg_or_0_operand (operands[1], SImode))"
4218 { return mips_output_move (operands[0], operands[1]); }
4219 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
4220 (set_attr "mode" "SI")
4221 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
4223 (define_insn "*movsi_mips16"
4224 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4225 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4227 && (register_operand (operands[0], SImode)
4228 || register_operand (operands[1], SImode))"
4229 { return mips_output_move (operands[0], operands[1]); }
4230 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
4231 (set_attr "mode" "SI")
4232 (set_attr_alternative "length"
4236 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4239 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4244 (const_string "*")])])
4246 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4247 ;; when the original load is a 4 byte instruction but the add and the
4248 ;; load are 2 2 byte instructions.
4251 [(set (match_operand:SI 0 "register_operand")
4252 (mem:SI (plus:SI (match_dup 0)
4253 (match_operand:SI 1 "const_int_operand"))))]
4254 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4255 && GET_CODE (operands[0]) == REG
4256 && M16_REG_P (REGNO (operands[0]))
4257 && GET_CODE (operands[1]) == CONST_INT
4258 && ((INTVAL (operands[1]) < 0
4259 && INTVAL (operands[1]) >= -0x80)
4260 || (INTVAL (operands[1]) >= 32 * 4
4261 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4262 || (INTVAL (operands[1]) >= 0
4263 && INTVAL (operands[1]) < 32 * 4
4264 && (INTVAL (operands[1]) & 3) != 0))"
4265 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4266 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4268 HOST_WIDE_INT val = INTVAL (operands[1]);
4271 operands[2] = const0_rtx;
4272 else if (val >= 32 * 4)
4276 operands[1] = GEN_INT (0x7c + off);
4277 operands[2] = GEN_INT (val - off - 0x7c);
4283 operands[1] = GEN_INT (off);
4284 operands[2] = GEN_INT (val - off);
4288 ;; On the mips16, we can split a load of certain constants into a load
4289 ;; and an add. This turns a 4 byte instruction into 2 2 byte
4293 [(set (match_operand:SI 0 "register_operand")
4294 (match_operand:SI 1 "const_int_operand"))]
4295 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4296 && GET_CODE (operands[0]) == REG
4297 && M16_REG_P (REGNO (operands[0]))
4298 && GET_CODE (operands[1]) == CONST_INT
4299 && INTVAL (operands[1]) >= 0x100
4300 && INTVAL (operands[1]) <= 0xff + 0x7f"
4301 [(set (match_dup 0) (match_dup 1))
4302 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4304 int val = INTVAL (operands[1]);
4306 operands[1] = GEN_INT (0xff);
4307 operands[2] = GEN_INT (val - 0xff);
4310 ;; This insn handles moving CCmode values. It's really just a
4311 ;; slightly simplified copy of movsi_internal2, with additional cases
4312 ;; to move a condition register to a general register and to move
4313 ;; between the general registers and the floating point registers.
4315 (define_insn "movcc"
4316 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
4317 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
4318 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4319 { return mips_output_move (operands[0], operands[1]); }
4320 [(set_attr "type" "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
4321 (set_attr "mode" "SI")
4322 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
4324 ;; Reload condition code registers. reload_incc and reload_outcc
4325 ;; both handle moves from arbitrary operands into condition code
4326 ;; registers. reload_incc handles the more common case in which
4327 ;; a source operand is constrained to be in a condition-code
4328 ;; register, but has not been allocated to one.
4330 ;; Sometimes, such as in movcc, we have a CCmode destination whose
4331 ;; constraints do not include 'z'. reload_outcc handles the case
4332 ;; when such an operand is allocated to a condition-code register.
4334 ;; Note that reloads from a condition code register to some
4335 ;; other location can be done using ordinary moves. Moving
4336 ;; into a GPR takes a single movcc, moving elsewhere takes
4337 ;; two. We can leave these cases to the generic reload code.
4338 (define_expand "reload_incc"
4339 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
4340 (match_operand:CC 1 "general_operand" ""))
4341 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4342 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4344 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4348 (define_expand "reload_outcc"
4349 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
4350 (match_operand:CC 1 "register_operand" ""))
4351 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4352 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4354 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4358 ;; MIPS4 supports loading and storing a floating point register from
4359 ;; the sum of two general registers. We use two versions for each of
4360 ;; these four instructions: one where the two general registers are
4361 ;; SImode, and one where they are DImode. This is because general
4362 ;; registers will be in SImode when they hold 32 bit values, but,
4363 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
4364 ;; instructions will still work correctly.
4366 ;; ??? Perhaps it would be better to support these instructions by
4367 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
4368 ;; these instructions can only be used to load and store floating
4369 ;; point registers, that would probably cause trouble in reload.
4372 [(set (match_operand:SF 0 "register_operand" "=f")
4373 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4374 (match_operand:SI 2 "register_operand" "d"))))]
4375 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4377 [(set_attr "type" "fpidxload")
4378 (set_attr "mode" "SF")
4379 (set_attr "length" "4")])
4382 [(set (match_operand:SF 0 "register_operand" "=f")
4383 (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4384 (match_operand:DI 2 "register_operand" "d"))))]
4385 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4387 [(set_attr "type" "fpidxload")
4388 (set_attr "mode" "SF")
4389 (set_attr "length" "4")])
4392 [(set (match_operand:DF 0 "register_operand" "=f")
4393 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4394 (match_operand:SI 2 "register_operand" "d"))))]
4395 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4397 [(set_attr "type" "fpidxload")
4398 (set_attr "mode" "DF")
4399 (set_attr "length" "4")])
4402 [(set (match_operand:DF 0 "register_operand" "=f")
4403 (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4404 (match_operand:DI 2 "register_operand" "d"))))]
4405 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4407 [(set_attr "type" "fpidxload")
4408 (set_attr "mode" "DF")
4409 (set_attr "length" "4")])
4412 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4413 (match_operand:SI 2 "register_operand" "d")))
4414 (match_operand:SF 0 "register_operand" "f"))]
4415 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4417 [(set_attr "type" "fpidxstore")
4418 (set_attr "mode" "SF")
4419 (set_attr "length" "4")])
4422 [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4423 (match_operand:DI 2 "register_operand" "d")))
4424 (match_operand:SF 0 "register_operand" "f"))]
4425 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4427 [(set_attr "type" "fpidxstore")
4428 (set_attr "mode" "SF")
4429 (set_attr "length" "4")])
4432 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4433 (match_operand:SI 2 "register_operand" "d")))
4434 (match_operand:DF 0 "register_operand" "f"))]
4435 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4437 [(set_attr "type" "fpidxstore")
4438 (set_attr "mode" "DF")
4439 (set_attr "length" "4")])
4442 [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4443 (match_operand:DI 2 "register_operand" "d")))
4444 (match_operand:DF 0 "register_operand" "f"))]
4445 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4447 [(set_attr "type" "fpidxstore")
4448 (set_attr "mode" "DF")
4449 (set_attr "length" "4")])
4451 ;; 16-bit Integer moves
4453 ;; Unlike most other insns, the move insns can't be split with
4454 ;; different predicates, because register spilling and other parts of
4455 ;; the compiler, have memoized the insn number already.
4456 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4458 (define_expand "movhi"
4459 [(set (match_operand:HI 0 "")
4460 (match_operand:HI 1 ""))]
4463 if (mips_legitimize_move (HImode, operands[0], operands[1]))
4467 (define_insn "*movhi_internal"
4468 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4469 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4471 && (register_operand (operands[0], HImode)
4472 || reg_or_0_operand (operands[1], HImode))"
4482 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4483 (set_attr "mode" "HI")
4484 (set_attr "length" "4,4,*,*,4,4,4,4")])
4486 (define_insn "*movhi_mips16"
4487 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4488 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))]
4490 && (register_operand (operands[0], HImode)
4491 || register_operand (operands[1], HImode))"
4500 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4501 (set_attr "mode" "HI")
4502 (set_attr_alternative "length"
4506 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4509 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4513 (const_string "*")])])
4516 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4517 ;; when the original load is a 4 byte instruction but the add and the
4518 ;; load are 2 2 byte instructions.
4521 [(set (match_operand:HI 0 "register_operand")
4522 (mem:HI (plus:SI (match_dup 0)
4523 (match_operand:SI 1 "const_int_operand"))))]
4524 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4525 && GET_CODE (operands[0]) == REG
4526 && M16_REG_P (REGNO (operands[0]))
4527 && GET_CODE (operands[1]) == CONST_INT
4528 && ((INTVAL (operands[1]) < 0
4529 && INTVAL (operands[1]) >= -0x80)
4530 || (INTVAL (operands[1]) >= 32 * 2
4531 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4532 || (INTVAL (operands[1]) >= 0
4533 && INTVAL (operands[1]) < 32 * 2
4534 && (INTVAL (operands[1]) & 1) != 0))"
4535 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4536 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4538 HOST_WIDE_INT val = INTVAL (operands[1]);
4541 operands[2] = const0_rtx;
4542 else if (val >= 32 * 2)
4546 operands[1] = GEN_INT (0x7e + off);
4547 operands[2] = GEN_INT (val - off - 0x7e);
4553 operands[1] = GEN_INT (off);
4554 operands[2] = GEN_INT (val - off);
4558 ;; 8-bit Integer moves
4560 ;; Unlike most other insns, the move insns can't be split with
4561 ;; different predicates, because register spilling and other parts of
4562 ;; the compiler, have memoized the insn number already.
4563 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4565 (define_expand "movqi"
4566 [(set (match_operand:QI 0 "")
4567 (match_operand:QI 1 ""))]
4570 if (mips_legitimize_move (QImode, operands[0], operands[1]))
4574 (define_insn "*movqi_internal"
4575 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4576 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4578 && (register_operand (operands[0], QImode)
4579 || reg_or_0_operand (operands[1], QImode))"
4589 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4590 (set_attr "mode" "QI")
4591 (set_attr "length" "4,4,*,*,4,4,4,4")])
4593 (define_insn "*movqi_mips16"
4594 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4595 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))]
4597 && (register_operand (operands[0], QImode)
4598 || register_operand (operands[1], QImode))"
4607 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4608 (set_attr "mode" "QI")
4609 (set_attr "length" "4,4,4,4,8,*,*")])
4611 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
4612 ;; when the original load is a 4 byte instruction but the add and the
4613 ;; load are 2 2 byte instructions.
4616 [(set (match_operand:QI 0 "register_operand")
4617 (mem:QI (plus:SI (match_dup 0)
4618 (match_operand:SI 1 "const_int_operand"))))]
4619 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4620 && GET_CODE (operands[0]) == REG
4621 && M16_REG_P (REGNO (operands[0]))
4622 && GET_CODE (operands[1]) == CONST_INT
4623 && ((INTVAL (operands[1]) < 0
4624 && INTVAL (operands[1]) >= -0x80)
4625 || (INTVAL (operands[1]) >= 32
4626 && INTVAL (operands[1]) <= 31 + 0x7f))"
4627 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4628 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4630 HOST_WIDE_INT val = INTVAL (operands[1]);
4633 operands[2] = const0_rtx;
4636 operands[1] = GEN_INT (0x7f);
4637 operands[2] = GEN_INT (val - 0x7f);
4641 ;; 32-bit floating point moves
4643 (define_expand "movsf"
4644 [(set (match_operand:SF 0 "")
4645 (match_operand:SF 1 ""))]
4648 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4652 (define_insn "*movsf_hardfloat"
4653 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4654 (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
4656 && (register_operand (operands[0], SFmode)
4657 || reg_or_0_operand (operands[1], SFmode))"
4658 { return mips_output_move (operands[0], operands[1]); }
4659 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4660 (set_attr "mode" "SF")
4661 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4663 (define_insn "*movsf_softfloat"
4664 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4665 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
4666 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4667 && (register_operand (operands[0], SFmode)
4668 || reg_or_0_operand (operands[1], SFmode))"
4669 { return mips_output_move (operands[0], operands[1]); }
4670 [(set_attr "type" "arith,load,store")
4671 (set_attr "mode" "SF")
4672 (set_attr "length" "4,*,*")])
4674 (define_insn "*movsf_mips16"
4675 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4676 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
4678 && (register_operand (operands[0], SFmode)
4679 || register_operand (operands[1], SFmode))"
4680 { return mips_output_move (operands[0], operands[1]); }
4681 [(set_attr "type" "arith,arith,arith,load,store")
4682 (set_attr "mode" "SF")
4683 (set_attr "length" "4,4,4,*,*")])
4686 ;; 64-bit floating point moves
4688 (define_expand "movdf"
4689 [(set (match_operand:DF 0 "")
4690 (match_operand:DF 1 ""))]
4693 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4697 (define_insn "*movdf_hardfloat_64bit"
4698 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4699 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4700 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
4701 && (register_operand (operands[0], DFmode)
4702 || reg_or_0_operand (operands[1], DFmode))"
4703 { return mips_output_move (operands[0], operands[1]); }
4704 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4705 (set_attr "mode" "DF")
4706 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4708 (define_insn "*movdf_hardfloat_32bit"
4709 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4710 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4711 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
4712 && (register_operand (operands[0], DFmode)
4713 || reg_or_0_operand (operands[1], DFmode))"
4714 { return mips_output_move (operands[0], operands[1]); }
4715 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4716 (set_attr "mode" "DF")
4717 (set_attr "length" "4,8,*,*,8,8,8,*,*")])
4719 (define_insn "*movdf_softfloat"
4720 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
4721 (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
4722 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4723 && (register_operand (operands[0], DFmode)
4724 || reg_or_0_operand (operands[1], DFmode))"
4725 { return mips_output_move (operands[0], operands[1]); }
4726 [(set_attr "type" "arith,load,store,xfer,xfer,fmove")
4727 (set_attr "mode" "DF")
4728 (set_attr "length" "8,*,*,4,4,4")])
4730 (define_insn "*movdf_mips16"
4731 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4732 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4734 && (register_operand (operands[0], DFmode)
4735 || register_operand (operands[1], DFmode))"
4736 { return mips_output_move (operands[0], operands[1]); }
4737 [(set_attr "type" "arith,arith,arith,load,store")
4738 (set_attr "mode" "DF")
4739 (set_attr "length" "8,8,8,*,*")])
4742 [(set (match_operand:DI 0 "nonimmediate_operand")
4743 (match_operand:DI 1 "move_operand"))]
4744 "reload_completed && !TARGET_64BIT
4745 && mips_split_64bit_move_p (operands[0], operands[1])"
4748 mips_split_64bit_move (operands[0], operands[1]);
4753 [(set (match_operand:DF 0 "nonimmediate_operand")
4754 (match_operand:DF 1 "move_operand"))]
4755 "reload_completed && !TARGET_64BIT
4756 && mips_split_64bit_move_p (operands[0], operands[1])"
4759 mips_split_64bit_move (operands[0], operands[1]);
4763 ;; When generating mips16 code, split moves of negative constants into
4764 ;; a positive "li" followed by a negation.
4766 [(set (match_operand 0 "register_operand")
4767 (match_operand 1 "const_int_operand"))]
4768 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4772 (neg:SI (match_dup 2)))]
4774 operands[2] = gen_lowpart (SImode, operands[0]);
4775 operands[3] = GEN_INT (-INTVAL (operands[1]));
4778 ;; The HI and LO registers are not truly independent. If we move an mthi
4779 ;; instruction before an mflo instruction, it will make the result of the
4780 ;; mflo unpredictable. The same goes for mtlo and mfhi.
4782 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4783 ;; Operand 1 is the register we want, operand 2 is the other one.
4785 (define_insn "mfhilo_di"
4786 [(set (match_operand:DI 0 "register_operand" "=d,d")
4787 (unspec:DI [(match_operand:DI 1 "register_operand" "h,l")
4788 (match_operand:DI 2 "register_operand" "l,h")]
4792 [(set_attr "type" "mfhilo")])
4794 (define_insn "mfhilo_si"
4795 [(set (match_operand:SI 0 "register_operand" "=d,d")
4796 (unspec:SI [(match_operand:SI 1 "register_operand" "h,l")
4797 (match_operand:SI 2 "register_operand" "l,h")]
4801 [(set_attr "type" "mfhilo")])
4803 ;; Patterns for loading or storing part of a paired floating point
4804 ;; register. We need them because odd-numbered floating-point registers
4805 ;; are not fully independent: see mips_split_64bit_move.
4807 ;; Load the low word of operand 0 with operand 1.
4808 (define_insn "load_df_low"
4809 [(set (match_operand:DF 0 "register_operand" "=f,f")
4810 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
4811 UNSPEC_LOAD_DF_LOW))]
4812 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4814 operands[0] = mips_subword (operands[0], 0);
4815 return mips_output_move (operands[0], operands[1]);
4817 [(set_attr "type" "xfer,fpload")
4818 (set_attr "mode" "SF")])
4820 ;; Load the high word of operand 0 from operand 1, preserving the value
4822 (define_insn "load_df_high"
4823 [(set (match_operand:DF 0 "register_operand" "=f,f")
4824 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
4825 (match_operand:DF 2 "register_operand" "0,0")]
4826 UNSPEC_LOAD_DF_HIGH))]
4827 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4829 operands[0] = mips_subword (operands[0], 1);
4830 return mips_output_move (operands[0], operands[1]);
4832 [(set_attr "type" "xfer,fpload")
4833 (set_attr "mode" "SF")])
4835 ;; Store the high word of operand 1 in operand 0. The corresponding
4836 ;; low-word move is done in the normal way.
4837 (define_insn "store_df_high"
4838 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4839 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4840 UNSPEC_STORE_DF_HIGH))]
4841 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4843 operands[1] = mips_subword (operands[1], 1);
4844 return mips_output_move (operands[0], operands[1]);
4846 [(set_attr "type" "xfer,fpstore")
4847 (set_attr "mode" "SF")])
4849 ;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
4850 ;; of _gp from the start of this function. Operand 1 is the incoming
4851 ;; function address.
4852 (define_insn_and_split "loadgp"
4853 [(unspec_volatile [(match_operand 0 "" "")
4854 (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4855 "TARGET_ABICALLS && TARGET_NEWABI"
4858 [(set (match_dup 2) (match_dup 3))
4859 (set (match_dup 2) (match_dup 4))
4860 (set (match_dup 2) (match_dup 5))]
4862 operands[2] = pic_offset_table_rtx;
4863 operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4864 operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4865 operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4867 [(set_attr "length" "12")])
4869 ;; The use of gp is hidden when not using explicit relocations.
4870 ;; This blockage instruction prevents the gp load from being
4871 ;; scheduled after an implicit use of gp. It also prevents
4872 ;; the load from being deleted as dead.
4873 (define_insn "loadgp_blockage"
4874 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4877 [(set_attr "type" "unknown")
4878 (set_attr "mode" "none")
4879 (set_attr "length" "0")])
4881 ;; Emit a .cprestore directive, which normally expands to a single store
4882 ;; instruction. Note that we continue to use .cprestore for explicit reloc
4883 ;; code so that jals inside inline asms will work correctly.
4884 (define_insn "cprestore"
4885 [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
4889 if (set_nomacro && which_alternative == 1)
4890 return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4892 return ".cprestore\t%0";
4894 [(set_attr "type" "store")
4895 (set_attr "length" "4,12")])
4897 ;; Block moves, see mips.c for more details.
4898 ;; Argument 0 is the destination
4899 ;; Argument 1 is the source
4900 ;; Argument 2 is the length
4901 ;; Argument 3 is the alignment
4903 (define_expand "movmemsi"
4904 [(parallel [(set (match_operand:BLK 0 "general_operand")
4905 (match_operand:BLK 1 "general_operand"))
4906 (use (match_operand:SI 2 ""))
4907 (use (match_operand:SI 3 "const_int_operand"))])]
4908 "!TARGET_MIPS16 && !TARGET_MEMCPY"
4910 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4917 ;; ....................
4921 ;; ....................
4923 ;; Many of these instructions use trivial define_expands, because we
4924 ;; want to use a different set of constraints when TARGET_MIPS16.
4926 (define_expand "ashlsi3"
4927 [(set (match_operand:SI 0 "register_operand")
4928 (ashift:SI (match_operand:SI 1 "register_operand")
4929 (match_operand:SI 2 "arith_operand")))]
4932 /* On the mips16, a shift of more than 8 is a four byte instruction,
4933 so, for a shift between 8 and 16, it is just as fast to do two
4934 shifts of 8 or less. If there is a lot of shifting going on, we
4935 may win in CSE. Otherwise combine will put the shifts back
4936 together again. This can be called by function_arg, so we must
4937 be careful not to allocate a new register if we've reached the
4941 && GET_CODE (operands[2]) == CONST_INT
4942 && INTVAL (operands[2]) > 8
4943 && INTVAL (operands[2]) <= 16
4944 && ! reload_in_progress
4945 && ! reload_completed)
4947 rtx temp = gen_reg_rtx (SImode);
4949 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
4950 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
4951 GEN_INT (INTVAL (operands[2]) - 8)));
4956 (define_insn "ashlsi3_internal1"
4957 [(set (match_operand:SI 0 "register_operand" "=d")
4958 (ashift:SI (match_operand:SI 1 "register_operand" "d")
4959 (match_operand:SI 2 "arith_operand" "dI")))]
4962 if (GET_CODE (operands[2]) == CONST_INT)
4963 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4965 return "sll\t%0,%1,%2";
4967 [(set_attr "type" "shift")
4968 (set_attr "mode" "SI")])
4970 (define_insn "ashlsi3_internal1_extend"
4971 [(set (match_operand:DI 0 "register_operand" "=d")
4972 (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
4973 (match_operand:SI 2 "arith_operand" "dI"))))]
4974 "TARGET_64BIT && !TARGET_MIPS16"
4976 if (GET_CODE (operands[2]) == CONST_INT)
4977 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4979 return "sll\t%0,%1,%2";
4981 [(set_attr "type" "shift")
4982 (set_attr "mode" "DI")])
4985 (define_insn "ashlsi3_internal2"
4986 [(set (match_operand:SI 0 "register_operand" "=d,d")
4987 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
4988 (match_operand:SI 2 "arith_operand" "d,I")))]
4991 if (which_alternative == 0)
4992 return "sll\t%0,%2";
4994 if (GET_CODE (operands[2]) == CONST_INT)
4995 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4997 return "sll\t%0,%1,%2";
4999 [(set_attr "type" "shift")
5000 (set_attr "mode" "SI")
5001 (set_attr_alternative "length"
5003 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5007 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5010 [(set (match_operand:SI 0 "register_operand")
5011 (ashift:SI (match_operand:SI 1 "register_operand")
5012 (match_operand:SI 2 "const_int_operand")))]
5013 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5014 && GET_CODE (operands[2]) == CONST_INT
5015 && INTVAL (operands[2]) > 8
5016 && INTVAL (operands[2]) <= 16"
5017 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
5018 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
5019 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5021 (define_expand "ashldi3"
5022 [(set (match_operand:DI 0 "register_operand")
5023 (ashift:DI (match_operand:DI 1 "register_operand")
5024 (match_operand:SI 2 "arith_operand")))]
5027 /* On the mips16, a shift of more than 8 is a four byte
5028 instruction, so, for a shift between 8 and 16, it is just as
5029 fast to do two shifts of 8 or less. If there is a lot of
5030 shifting going on, we may win in CSE. Otherwise combine will
5031 put the shifts back together again. This can be called by
5032 function_arg, so we must be careful not to allocate a new
5033 register if we've reached the reload pass. */
5036 && GET_CODE (operands[2]) == CONST_INT
5037 && INTVAL (operands[2]) > 8
5038 && INTVAL (operands[2]) <= 16
5039 && ! reload_in_progress
5040 && ! reload_completed)
5042 rtx temp = gen_reg_rtx (DImode);
5044 emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
5045 emit_insn (gen_ashldi3_internal (operands[0], temp,
5046 GEN_INT (INTVAL (operands[2]) - 8)));
5052 (define_insn "ashldi3_internal"
5053 [(set (match_operand:DI 0 "register_operand" "=d")
5054 (ashift:DI (match_operand:DI 1 "register_operand" "d")
5055 (match_operand:SI 2 "arith_operand" "dI")))]
5056 "TARGET_64BIT && !TARGET_MIPS16"
5058 if (GET_CODE (operands[2]) == CONST_INT)
5059 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5061 return "dsll\t%0,%1,%2";
5063 [(set_attr "type" "shift")
5064 (set_attr "mode" "DI")])
5067 [(set (match_operand:DI 0 "register_operand" "=d,d")
5068 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
5069 (match_operand:SI 2 "arith_operand" "d,I")))]
5070 "TARGET_64BIT && TARGET_MIPS16"
5072 if (which_alternative == 0)
5073 return "dsll\t%0,%2";
5075 if (GET_CODE (operands[2]) == CONST_INT)
5076 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5078 return "dsll\t%0,%1,%2";
5080 [(set_attr "type" "shift")
5081 (set_attr "mode" "DI")
5082 (set_attr_alternative "length"
5084 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5089 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5092 [(set (match_operand:DI 0 "register_operand")
5093 (ashift:DI (match_operand:DI 1 "register_operand")
5094 (match_operand:SI 2 "const_int_operand")))]
5095 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5097 && GET_CODE (operands[2]) == CONST_INT
5098 && INTVAL (operands[2]) > 8
5099 && INTVAL (operands[2]) <= 16"
5100 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
5101 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
5102 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5104 (define_expand "ashrsi3"
5105 [(set (match_operand:SI 0 "register_operand")
5106 (ashiftrt:SI (match_operand:SI 1 "register_operand")
5107 (match_operand:SI 2 "arith_operand")))]
5110 /* On the mips16, a shift of more than 8 is a four byte instruction,
5111 so, for a shift between 8 and 16, it is just as fast to do two
5112 shifts of 8 or less. If there is a lot of shifting going on, we
5113 may win in CSE. Otherwise combine will put the shifts back
5117 && GET_CODE (operands[2]) == CONST_INT
5118 && INTVAL (operands[2]) > 8
5119 && INTVAL (operands[2]) <= 16)
5121 rtx temp = gen_reg_rtx (SImode);
5123 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5124 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
5125 GEN_INT (INTVAL (operands[2]) - 8)));
5130 (define_insn "ashrsi3_internal1"
5131 [(set (match_operand:SI 0 "register_operand" "=d")
5132 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
5133 (match_operand:SI 2 "arith_operand" "dI")))]
5136 if (GET_CODE (operands[2]) == CONST_INT)
5137 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5139 return "sra\t%0,%1,%2";
5141 [(set_attr "type" "shift")
5142 (set_attr "mode" "SI")])
5144 (define_insn "ashrsi3_internal2"
5145 [(set (match_operand:SI 0 "register_operand" "=d,d")
5146 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5147 (match_operand:SI 2 "arith_operand" "d,I")))]
5150 if (which_alternative == 0)
5151 return "sra\t%0,%2";
5153 if (GET_CODE (operands[2]) == CONST_INT)
5154 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5156 return "sra\t%0,%1,%2";
5158 [(set_attr "type" "shift")
5159 (set_attr "mode" "SI")
5160 (set_attr_alternative "length"
5162 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5167 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5170 [(set (match_operand:SI 0 "register_operand")
5171 (ashiftrt:SI (match_operand:SI 1 "register_operand")
5172 (match_operand:SI 2 "const_int_operand")))]
5173 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5174 && GET_CODE (operands[2]) == CONST_INT
5175 && INTVAL (operands[2]) > 8
5176 && INTVAL (operands[2]) <= 16"
5177 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
5178 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
5179 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5181 (define_expand "ashrdi3"
5182 [(set (match_operand:DI 0 "register_operand")
5183 (ashiftrt:DI (match_operand:DI 1 "register_operand")
5184 (match_operand:SI 2 "arith_operand")))]
5187 /* On the mips16, a shift of more than 8 is a four byte
5188 instruction, so, for a shift between 8 and 16, it is just as
5189 fast to do two shifts of 8 or less. If there is a lot of
5190 shifting going on, we may win in CSE. Otherwise combine will
5191 put the shifts back together again. */
5194 && GET_CODE (operands[2]) == CONST_INT
5195 && INTVAL (operands[2]) > 8
5196 && INTVAL (operands[2]) <= 16)
5198 rtx temp = gen_reg_rtx (DImode);
5200 emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
5201 emit_insn (gen_ashrdi3_internal (operands[0], temp,
5202 GEN_INT (INTVAL (operands[2]) - 8)));
5208 (define_insn "ashrdi3_internal"
5209 [(set (match_operand:DI 0 "register_operand" "=d")
5210 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5211 (match_operand:SI 2 "arith_operand" "dI")))]
5212 "TARGET_64BIT && !TARGET_MIPS16"
5214 if (GET_CODE (operands[2]) == CONST_INT)
5215 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5217 return "dsra\t%0,%1,%2";
5219 [(set_attr "type" "shift")
5220 (set_attr "mode" "DI")])
5223 [(set (match_operand:DI 0 "register_operand" "=d,d")
5224 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5225 (match_operand:SI 2 "arith_operand" "d,I")))]
5226 "TARGET_64BIT && TARGET_MIPS16"
5228 if (GET_CODE (operands[2]) == CONST_INT)
5229 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5231 return "dsra\t%0,%2";
5233 [(set_attr "type" "shift")
5234 (set_attr "mode" "DI")
5235 (set_attr_alternative "length"
5237 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5241 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5244 [(set (match_operand:DI 0 "register_operand")
5245 (ashiftrt:DI (match_operand:DI 1 "register_operand")
5246 (match_operand:SI 2 "const_int_operand")))]
5247 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5249 && GET_CODE (operands[2]) == CONST_INT
5250 && INTVAL (operands[2]) > 8
5251 && INTVAL (operands[2]) <= 16"
5252 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
5253 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
5254 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5256 (define_expand "lshrsi3"
5257 [(set (match_operand:SI 0 "register_operand")
5258 (lshiftrt:SI (match_operand:SI 1 "register_operand")
5259 (match_operand:SI 2 "arith_operand")))]
5262 /* On the mips16, a shift of more than 8 is a four byte instruction,
5263 so, for a shift between 8 and 16, it is just as fast to do two
5264 shifts of 8 or less. If there is a lot of shifting going on, we
5265 may win in CSE. Otherwise combine will put the shifts back
5269 && GET_CODE (operands[2]) == CONST_INT
5270 && INTVAL (operands[2]) > 8
5271 && INTVAL (operands[2]) <= 16)
5273 rtx temp = gen_reg_rtx (SImode);
5275 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5276 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
5277 GEN_INT (INTVAL (operands[2]) - 8)));
5282 (define_insn "lshrsi3_internal1"
5283 [(set (match_operand:SI 0 "register_operand" "=d")
5284 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
5285 (match_operand:SI 2 "arith_operand" "dI")))]
5288 if (GET_CODE (operands[2]) == CONST_INT)
5289 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5291 return "srl\t%0,%1,%2";
5293 [(set_attr "type" "shift")
5294 (set_attr "mode" "SI")])
5296 (define_insn "lshrsi3_internal2"
5297 [(set (match_operand:SI 0 "register_operand" "=d,d")
5298 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5299 (match_operand:SI 2 "arith_operand" "d,I")))]
5302 if (which_alternative == 0)
5303 return "srl\t%0,%2";
5305 if (GET_CODE (operands[2]) == CONST_INT)
5306 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5308 return "srl\t%0,%1,%2";
5310 [(set_attr "type" "shift")
5311 (set_attr "mode" "SI")
5312 (set_attr_alternative "length"
5314 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5319 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5322 [(set (match_operand:SI 0 "register_operand")
5323 (lshiftrt:SI (match_operand:SI 1 "register_operand")
5324 (match_operand:SI 2 "const_int_operand")))]
5325 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5326 && GET_CODE (operands[2]) == CONST_INT
5327 && INTVAL (operands[2]) > 8
5328 && INTVAL (operands[2]) <= 16"
5329 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
5330 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5331 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5333 ;; If we load a byte on the mips16 as a bitfield, the resulting
5334 ;; sequence of instructions is too complicated for combine, because it
5335 ;; involves four instructions: a load, a shift, a constant load into a
5336 ;; register, and an and (the key problem here is that the mips16 does
5337 ;; not have and immediate). We recognize a shift of a load in order
5338 ;; to make it simple enough for combine to understand.
5340 ;; The length here is the worst case: the length of the split version
5341 ;; will be more accurate.
5342 (define_insn_and_split ""
5343 [(set (match_operand:SI 0 "register_operand" "=d")
5344 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5345 (match_operand:SI 2 "immediate_operand" "I")))]
5349 [(set (match_dup 0) (match_dup 1))
5350 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5352 [(set_attr "type" "load")
5353 (set_attr "mode" "SI")
5354 (set_attr "length" "16")])
5356 (define_expand "lshrdi3"
5357 [(set (match_operand:DI 0 "register_operand")
5358 (lshiftrt:DI (match_operand:DI 1 "register_operand")
5359 (match_operand:SI 2 "arith_operand")))]
5362 /* On the mips16, a shift of more than 8 is a four byte
5363 instruction, so, for a shift between 8 and 16, it is just as
5364 fast to do two shifts of 8 or less. If there is a lot of
5365 shifting going on, we may win in CSE. Otherwise combine will
5366 put the shifts back together again. */
5369 && GET_CODE (operands[2]) == CONST_INT
5370 && INTVAL (operands[2]) > 8
5371 && INTVAL (operands[2]) <= 16)
5373 rtx temp = gen_reg_rtx (DImode);
5375 emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
5376 emit_insn (gen_lshrdi3_internal (operands[0], temp,
5377 GEN_INT (INTVAL (operands[2]) - 8)));
5383 (define_insn "lshrdi3_internal"
5384 [(set (match_operand:DI 0 "register_operand" "=d")
5385 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
5386 (match_operand:SI 2 "arith_operand" "dI")))]
5387 "TARGET_64BIT && !TARGET_MIPS16"
5389 if (GET_CODE (operands[2]) == CONST_INT)
5390 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5392 return "dsrl\t%0,%1,%2";
5394 [(set_attr "type" "shift")
5395 (set_attr "mode" "DI")])
5398 [(set (match_operand:DI 0 "register_operand" "=d,d")
5399 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5400 (match_operand:SI 2 "arith_operand" "d,I")))]
5401 "TARGET_64BIT && TARGET_MIPS16"
5403 if (GET_CODE (operands[2]) == CONST_INT)
5404 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5406 return "dsrl\t%0,%2";
5408 [(set_attr "type" "shift")
5409 (set_attr "mode" "DI")
5410 (set_attr_alternative "length"
5412 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5416 (define_insn "rotrsi3"
5417 [(set (match_operand:SI 0 "register_operand" "=d")
5418 (rotatert:SI (match_operand:SI 1 "register_operand" "d")
5419 (match_operand:SI 2 "arith_operand" "dn")))]
5422 if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
5423 return "rorv\t%0,%1,%2";
5425 if ((GET_CODE (operands[2]) == CONST_INT)
5426 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
5429 return "ror\t%0,%1,%2";
5431 [(set_attr "type" "shift")
5432 (set_attr "mode" "SI")])
5434 (define_insn "rotrdi3"
5435 [(set (match_operand:DI 0 "register_operand" "=d")
5436 (rotatert:DI (match_operand:DI 1 "register_operand" "d")
5437 (match_operand:DI 2 "arith_operand" "dn")))]
5442 if (GET_CODE (operands[2]) != CONST_INT)
5443 return "drorv\t%0,%1,%2";
5445 if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
5446 return "dror32\t%0,%1,%2";
5449 if ((GET_CODE (operands[2]) == CONST_INT)
5450 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
5453 return "dror\t%0,%1,%2";
5455 [(set_attr "type" "shift")
5456 (set_attr "mode" "DI")])
5459 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5462 [(set (match_operand:DI 0 "register_operand")
5463 (lshiftrt:DI (match_operand:DI 1 "register_operand")
5464 (match_operand:SI 2 "const_int_operand")))]
5465 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5466 && GET_CODE (operands[2]) == CONST_INT
5467 && INTVAL (operands[2]) > 8
5468 && INTVAL (operands[2]) <= 16"
5469 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
5470 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
5471 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5474 ;; ....................
5478 ;; ....................
5480 ;; Flow here is rather complex:
5482 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the arguments
5483 ;; into cmp_operands[] but generates no RTL.
5485 ;; 2) The appropriate branch define_expand is called, which then
5486 ;; creates the appropriate RTL for the comparison and branch.
5487 ;; Different CC modes are used, based on what type of branch is
5488 ;; done, so that we can constrain things appropriately. There
5489 ;; are assumptions in the rest of GCC that break if we fold the
5490 ;; operands into the branches for integer operations, and use cc0
5491 ;; for floating point, so we use the fp status register instead.
5492 ;; If needed, an appropriate temporary is created to hold the
5493 ;; of the integer compare.
5495 (define_expand "cmpsi"
5497 (compare:CC (match_operand:SI 0 "register_operand")
5498 (match_operand:SI 1 "nonmemory_operand")))]
5501 cmp_operands[0] = operands[0];
5502 cmp_operands[1] = operands[1];
5506 (define_expand "cmpdi"
5508 (compare:CC (match_operand:DI 0 "register_operand")
5509 (match_operand:DI 1 "nonmemory_operand")))]
5512 cmp_operands[0] = operands[0];
5513 cmp_operands[1] = operands[1];
5517 (define_expand "cmpdf"
5519 (compare:CC (match_operand:DF 0 "register_operand")
5520 (match_operand:DF 1 "register_operand")))]
5521 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5523 cmp_operands[0] = operands[0];
5524 cmp_operands[1] = operands[1];
5528 (define_expand "cmpsf"
5530 (compare:CC (match_operand:SF 0 "register_operand")
5531 (match_operand:SF 1 "register_operand")))]
5534 cmp_operands[0] = operands[0];
5535 cmp_operands[1] = operands[1];
5540 ;; ....................
5542 ;; CONDITIONAL BRANCHES
5544 ;; ....................
5546 ;; Conditional branches on floating-point equality tests.
5548 (define_insn "branch_fp"
5551 (match_operator:CC 0 "comparison_operator"
5552 [(match_operand:CC 2 "register_operand" "z")
5554 (label_ref (match_operand 1 "" ""))
5558 return mips_output_conditional_branch (insn,
5560 /*two_operands_p=*/0,
5563 get_attr_length (insn));
5565 [(set_attr "type" "branch")
5566 (set_attr "mode" "none")])
5568 (define_insn "branch_fp_inverted"
5571 (match_operator:CC 0 "comparison_operator"
5572 [(match_operand:CC 2 "register_operand" "z")
5575 (label_ref (match_operand 1 "" ""))))]
5578 return mips_output_conditional_branch (insn,
5580 /*two_operands_p=*/0,
5583 get_attr_length (insn));
5585 [(set_attr "type" "branch")
5586 (set_attr "mode" "none")])
5588 ;; Conditional branches on comparisons with zero.
5590 (define_insn "branch_zero"
5593 (match_operator:SI 0 "comparison_operator"
5594 [(match_operand:SI 2 "register_operand" "d")
5596 (label_ref (match_operand 1 "" ""))
5600 return mips_output_conditional_branch (insn,
5602 /*two_operands_p=*/0,
5605 get_attr_length (insn));
5607 [(set_attr "type" "branch")
5608 (set_attr "mode" "none")])
5610 (define_insn "branch_zero_inverted"
5613 (match_operator:SI 0 "comparison_operator"
5614 [(match_operand:SI 2 "register_operand" "d")
5617 (label_ref (match_operand 1 "" ""))))]
5620 return mips_output_conditional_branch (insn,
5622 /*two_operands_p=*/0,
5625 get_attr_length (insn));
5627 [(set_attr "type" "branch")
5628 (set_attr "mode" "none")])
5630 (define_insn "branch_zero_di"
5633 (match_operator:DI 0 "comparison_operator"
5634 [(match_operand:DI 2 "register_operand" "d")
5636 (label_ref (match_operand 1 "" ""))
5640 return mips_output_conditional_branch (insn,
5642 /*two_operands_p=*/0,
5645 get_attr_length (insn));
5647 [(set_attr "type" "branch")
5648 (set_attr "mode" "none")])
5650 (define_insn "branch_zero_di_inverted"
5653 (match_operator:DI 0 "comparison_operator"
5654 [(match_operand:DI 2 "register_operand" "d")
5657 (label_ref (match_operand 1 "" ""))))]
5660 return mips_output_conditional_branch (insn,
5662 /*two_operands_p=*/0,
5665 get_attr_length (insn));
5667 [(set_attr "type" "branch")
5668 (set_attr "mode" "none")])
5670 ;; Conditional branch on equality comparison.
5672 (define_insn "branch_equality"
5675 (match_operator:SI 0 "equality_operator"
5676 [(match_operand:SI 2 "register_operand" "d")
5677 (match_operand:SI 3 "register_operand" "d")])
5678 (label_ref (match_operand 1 "" ""))
5682 return mips_output_conditional_branch (insn,
5684 /*two_operands_p=*/1,
5687 get_attr_length (insn));
5689 [(set_attr "type" "branch")
5690 (set_attr "mode" "none")])
5692 (define_insn "branch_equality_di"
5695 (match_operator:DI 0 "equality_operator"
5696 [(match_operand:DI 2 "register_operand" "d")
5697 (match_operand:DI 3 "register_operand" "d")])
5698 (label_ref (match_operand 1 "" ""))
5702 return mips_output_conditional_branch (insn,
5704 /*two_operands_p=*/1,
5707 get_attr_length (insn));
5709 [(set_attr "type" "branch")
5710 (set_attr "mode" "none")])
5712 (define_insn "branch_equality_inverted"
5715 (match_operator:SI 0 "equality_operator"
5716 [(match_operand:SI 2 "register_operand" "d")
5717 (match_operand:SI 3 "register_operand" "d")])
5719 (label_ref (match_operand 1 "" ""))))]
5722 return mips_output_conditional_branch (insn,
5724 /*two_operands_p=*/1,
5727 get_attr_length (insn));
5729 [(set_attr "type" "branch")
5730 (set_attr "mode" "none")])
5732 (define_insn "branch_equality_di_inverted"
5735 (match_operator:DI 0 "equality_operator"
5736 [(match_operand:DI 2 "register_operand" "d")
5737 (match_operand:DI 3 "register_operand" "d")])
5739 (label_ref (match_operand 1 "" ""))))]
5742 return mips_output_conditional_branch (insn,
5744 /*two_operands_p=*/1,
5747 get_attr_length (insn));
5749 [(set_attr "type" "branch")
5750 (set_attr "mode" "none")])
5757 (match_operator:SI 0 "equality_operator"
5758 [(match_operand:SI 1 "register_operand" "d,t")
5760 (match_operand 2 "pc_or_label_operand" "")
5761 (match_operand 3 "pc_or_label_operand" "")))]
5764 if (operands[2] != pc_rtx)
5766 if (which_alternative == 0)
5767 return "b%C0z\t%1,%2";
5769 return "bt%C0z\t%2";
5773 if (which_alternative == 0)
5774 return "b%N0z\t%1,%3";
5776 return "bt%N0z\t%3";
5779 [(set_attr "type" "branch")
5780 (set_attr "mode" "none")
5781 (set_attr "length" "8")])
5786 (match_operator:DI 0 "equality_operator"
5787 [(match_operand:DI 1 "register_operand" "d,t")
5789 (match_operand 2 "pc_or_label_operand" "")
5790 (match_operand 3 "pc_or_label_operand" "")))]
5793 if (operands[2] != pc_rtx)
5795 if (which_alternative == 0)
5796 return "b%C0z\t%1,%2";
5798 return "bt%C0z\t%2";
5802 if (which_alternative == 0)
5803 return "b%N0z\t%1,%3";
5805 return "bt%N0z\t%3";
5808 [(set_attr "type" "branch")
5809 (set_attr "mode" "none")
5810 (set_attr "length" "8")])
5812 (define_expand "bunordered"
5814 (if_then_else (unordered:CC (cc0)
5816 (label_ref (match_operand 0 ""))
5820 gen_conditional_branch (operands, UNORDERED);
5824 (define_expand "bordered"
5826 (if_then_else (ordered:CC (cc0)
5828 (label_ref (match_operand 0 ""))
5832 gen_conditional_branch (operands, ORDERED);
5836 (define_expand "bunlt"
5838 (if_then_else (unlt:CC (cc0)
5840 (label_ref (match_operand 0 ""))
5844 gen_conditional_branch (operands, UNLT);
5848 (define_expand "bunge"
5850 (if_then_else (unge:CC (cc0)
5852 (label_ref (match_operand 0 ""))
5856 gen_conditional_branch (operands, UNGE);
5860 (define_expand "buneq"
5862 (if_then_else (uneq:CC (cc0)
5864 (label_ref (match_operand 0 ""))
5868 gen_conditional_branch (operands, UNEQ);
5872 (define_expand "bltgt"
5874 (if_then_else (ltgt:CC (cc0)
5876 (label_ref (match_operand 0 ""))
5880 gen_conditional_branch (operands, LTGT);
5884 (define_expand "bunle"
5886 (if_then_else (unle:CC (cc0)
5888 (label_ref (match_operand 0 ""))
5892 gen_conditional_branch (operands, UNLE);
5896 (define_expand "bungt"
5898 (if_then_else (ungt:CC (cc0)
5900 (label_ref (match_operand 0 ""))
5904 gen_conditional_branch (operands, UNGT);
5908 (define_expand "beq"
5910 (if_then_else (eq:CC (cc0)
5912 (label_ref (match_operand 0 ""))
5916 gen_conditional_branch (operands, EQ);
5920 (define_expand "bne"
5922 (if_then_else (ne:CC (cc0)
5924 (label_ref (match_operand 0 ""))
5928 gen_conditional_branch (operands, NE);
5932 (define_expand "bgt"
5934 (if_then_else (gt:CC (cc0)
5936 (label_ref (match_operand 0 ""))
5940 gen_conditional_branch (operands, GT);
5944 (define_expand "bge"
5946 (if_then_else (ge:CC (cc0)
5948 (label_ref (match_operand 0 ""))
5952 gen_conditional_branch (operands, GE);
5956 (define_expand "blt"
5958 (if_then_else (lt:CC (cc0)
5960 (label_ref (match_operand 0 ""))
5964 gen_conditional_branch (operands, LT);
5968 (define_expand "ble"
5970 (if_then_else (le:CC (cc0)
5972 (label_ref (match_operand 0 ""))
5976 gen_conditional_branch (operands, LE);
5980 (define_expand "bgtu"
5982 (if_then_else (gtu:CC (cc0)
5984 (label_ref (match_operand 0 ""))
5988 gen_conditional_branch (operands, GTU);
5992 (define_expand "bgeu"
5994 (if_then_else (geu:CC (cc0)
5996 (label_ref (match_operand 0 ""))
6000 gen_conditional_branch (operands, GEU);
6004 (define_expand "bltu"
6006 (if_then_else (ltu:CC (cc0)
6008 (label_ref (match_operand 0 ""))
6012 gen_conditional_branch (operands, LTU);
6016 (define_expand "bleu"
6018 (if_then_else (leu:CC (cc0)
6020 (label_ref (match_operand 0 ""))
6024 gen_conditional_branch (operands, LEU);
6029 ;; ....................
6031 ;; SETTING A REGISTER FROM A COMPARISON
6033 ;; ....................
6035 (define_expand "seq"
6036 [(set (match_operand:SI 0 "register_operand")
6037 (eq:SI (match_dup 1)
6040 { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
6042 (define_insn "*seq_si"
6043 [(set (match_operand:SI 0 "register_operand" "=d")
6044 (eq:SI (match_operand:SI 1 "register_operand" "d")
6048 [(set_attr "type" "slt")
6049 (set_attr "mode" "SI")])
6051 (define_insn "*seq_si_mips16"
6052 [(set (match_operand:SI 0 "register_operand" "=t")
6053 (eq:SI (match_operand:SI 1 "register_operand" "d")
6057 [(set_attr "type" "slt")
6058 (set_attr "mode" "SI")])
6060 (define_insn "*seq_di"
6061 [(set (match_operand:DI 0 "register_operand" "=d")
6062 (eq:DI (match_operand:DI 1 "register_operand" "d")
6064 "TARGET_64BIT && !TARGET_MIPS16"
6066 [(set_attr "type" "slt")
6067 (set_attr "mode" "DI")])
6069 (define_insn "*seq_di_mips16"
6070 [(set (match_operand:DI 0 "register_operand" "=t")
6071 (eq:DI (match_operand:DI 1 "register_operand" "d")
6073 "TARGET_64BIT && TARGET_MIPS16"
6075 [(set_attr "type" "slt")
6076 (set_attr "mode" "DI")])
6078 ;; "sne" uses sltu instructions in which the first operand is $0.
6079 ;; This isn't possible in mips16 code.
6081 (define_expand "sne"
6082 [(set (match_operand:SI 0 "register_operand")
6083 (ne:SI (match_dup 1)
6086 { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
6088 (define_insn "*sne_si"
6089 [(set (match_operand:SI 0 "register_operand" "=d")
6090 (ne:SI (match_operand:SI 1 "register_operand" "d")
6094 [(set_attr "type" "slt")
6095 (set_attr "mode" "SI")])
6097 (define_insn "*sne_di"
6098 [(set (match_operand:DI 0 "register_operand" "=d")
6099 (ne:DI (match_operand:DI 1 "register_operand" "d")
6101 "TARGET_64BIT && !TARGET_MIPS16"
6103 [(set_attr "type" "slt")
6104 (set_attr "mode" "DI")])
6106 (define_expand "sgt"
6107 [(set (match_operand:SI 0 "register_operand")
6108 (gt:SI (match_dup 1)
6111 { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
6113 (define_insn "*sgt_si"
6114 [(set (match_operand:SI 0 "register_operand" "=d")
6115 (gt:SI (match_operand:SI 1 "register_operand" "d")
6116 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6119 [(set_attr "type" "slt")
6120 (set_attr "mode" "SI")])
6122 (define_insn "*sgt_si_mips16"
6123 [(set (match_operand:SI 0 "register_operand" "=t")
6124 (gt:SI (match_operand:SI 1 "register_operand" "d")
6125 (match_operand:SI 2 "register_operand" "d")))]
6128 [(set_attr "type" "slt")
6129 (set_attr "mode" "SI")])
6131 (define_insn "*sgt_di"
6132 [(set (match_operand:DI 0 "register_operand" "=d")
6133 (gt:DI (match_operand:DI 1 "register_operand" "d")
6134 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6135 "TARGET_64BIT && !TARGET_MIPS16"
6137 [(set_attr "type" "slt")
6138 (set_attr "mode" "DI")])
6140 (define_insn "*sgt_di_mips16"
6141 [(set (match_operand:DI 0 "register_operand" "=t")
6142 (gt:DI (match_operand:DI 1 "register_operand" "d")
6143 (match_operand:DI 2 "register_operand" "d")))]
6144 "TARGET_64BIT && TARGET_MIPS16"
6146 [(set_attr "type" "slt")
6147 (set_attr "mode" "DI")])
6149 (define_expand "sge"
6150 [(set (match_operand:SI 0 "register_operand")
6151 (ge:SI (match_dup 1)
6154 { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
6156 (define_insn "*sge_si"
6157 [(set (match_operand:SI 0 "register_operand" "=d")
6158 (ge:SI (match_operand:SI 1 "register_operand" "d")
6162 [(set_attr "type" "slt")
6163 (set_attr "mode" "SI")])
6165 (define_insn "*sge_di"
6166 [(set (match_operand:DI 0 "register_operand" "=d")
6167 (ge:DI (match_operand:DI 1 "register_operand" "d")
6169 "TARGET_64BIT && !TARGET_MIPS16"
6171 [(set_attr "type" "slt")
6172 (set_attr "mode" "DI")])
6174 (define_expand "slt"
6175 [(set (match_operand:SI 0 "register_operand")
6176 (lt:SI (match_dup 1)
6179 { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
6181 (define_insn "*slt_si"
6182 [(set (match_operand:SI 0 "register_operand" "=d")
6183 (lt:SI (match_operand:SI 1 "register_operand" "d")
6184 (match_operand:SI 2 "arith_operand" "dI")))]
6187 [(set_attr "type" "slt")
6188 (set_attr "mode" "SI")])
6190 (define_insn "*slt_si_mips16"
6191 [(set (match_operand:SI 0 "register_operand" "=t,t")
6192 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
6193 (match_operand:SI 2 "arith_operand" "d,I")))]
6196 [(set_attr "type" "slt")
6197 (set_attr "mode" "SI")
6198 (set_attr_alternative "length"
6200 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6204 (define_insn "*slt_di"
6205 [(set (match_operand:DI 0 "register_operand" "=d")
6206 (lt:DI (match_operand:DI 1 "register_operand" "d")
6207 (match_operand:DI 2 "arith_operand" "dI")))]
6208 "TARGET_64BIT && !TARGET_MIPS16"
6210 [(set_attr "type" "slt")
6211 (set_attr "mode" "DI")])
6213 (define_insn "*slt_di_mips16"
6214 [(set (match_operand:DI 0 "register_operand" "=t,t")
6215 (lt:DI (match_operand:DI 1 "register_operand" "d,d")
6216 (match_operand:DI 2 "arith_operand" "d,I")))]
6217 "TARGET_64BIT && TARGET_MIPS16"
6219 [(set_attr "type" "slt")
6220 (set_attr "mode" "DI")
6221 (set_attr_alternative "length"
6223 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6227 (define_expand "sle"
6228 [(set (match_operand:SI 0 "register_operand")
6229 (le:SI (match_dup 1)
6232 { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
6234 (define_insn "*sle_si"
6235 [(set (match_operand:SI 0 "register_operand" "=d")
6236 (le:SI (match_operand:SI 1 "register_operand" "d")
6237 (match_operand:SI 2 "sle_operand" "")))]
6240 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6241 return "slt\t%0,%1,%2";
6243 [(set_attr "type" "slt")
6244 (set_attr "mode" "SI")])
6246 (define_insn "*sle_si_mips16"
6247 [(set (match_operand:SI 0 "register_operand" "=t")
6248 (le:SI (match_operand:SI 1 "register_operand" "d")
6249 (match_operand:SI 2 "sle_operand" "")))]
6252 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6253 return "slt\t%1,%2";
6255 [(set_attr "type" "slt")
6256 (set_attr "mode" "SI")
6257 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6261 (define_insn "*sle_di"
6262 [(set (match_operand:DI 0 "register_operand" "=d")
6263 (le:DI (match_operand:DI 1 "register_operand" "d")
6264 (match_operand:DI 2 "sle_operand" "")))]
6265 "TARGET_64BIT && !TARGET_MIPS16"
6267 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6268 return "slt\t%0,%1,%2";
6270 [(set_attr "type" "slt")
6271 (set_attr "mode" "DI")])
6273 (define_insn "*sle_di_mips16"
6274 [(set (match_operand:DI 0 "register_operand" "=t")
6275 (le:DI (match_operand:DI 1 "register_operand" "d")
6276 (match_operand:DI 2 "sle_operand" "")))]
6277 "TARGET_64BIT && TARGET_MIPS16"
6279 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6280 return "slt\t%1,%2";
6282 [(set_attr "type" "slt")
6283 (set_attr "mode" "DI")
6284 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6288 (define_expand "sgtu"
6289 [(set (match_operand:SI 0 "register_operand")
6290 (gtu:SI (match_dup 1)
6293 { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
6295 (define_insn "*sgtu_si"
6296 [(set (match_operand:SI 0 "register_operand" "=d")
6297 (gtu:SI (match_operand:SI 1 "register_operand" "d")
6298 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6301 [(set_attr "type" "slt")
6302 (set_attr "mode" "SI")])
6304 (define_insn "*sgtu_si_mips16"
6305 [(set (match_operand:SI 0 "register_operand" "=t")
6306 (gtu:SI (match_operand:SI 1 "register_operand" "d")
6307 (match_operand:SI 2 "register_operand" "d")))]
6310 [(set_attr "type" "slt")
6311 (set_attr "mode" "SI")])
6313 (define_insn "*sgtu_di"
6314 [(set (match_operand:DI 0 "register_operand" "=d")
6315 (gtu:DI (match_operand:DI 1 "register_operand" "d")
6316 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6317 "TARGET_64BIT && !TARGET_MIPS16"
6319 [(set_attr "type" "slt")
6320 (set_attr "mode" "DI")])
6322 (define_insn "*sgtu_di_mips16"
6323 [(set (match_operand:DI 0 "register_operand" "=t")
6324 (gtu:DI (match_operand:DI 1 "register_operand" "d")
6325 (match_operand:DI 2 "register_operand" "d")))]
6326 "TARGET_64BIT && TARGET_MIPS16"
6328 [(set_attr "type" "slt")
6329 (set_attr "mode" "DI")])
6331 (define_expand "sgeu"
6332 [(set (match_operand:SI 0 "register_operand")
6333 (geu:SI (match_dup 1)
6336 { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
6338 (define_insn "*sge_si"
6339 [(set (match_operand:SI 0 "register_operand" "=d")
6340 (geu:SI (match_operand:SI 1 "register_operand" "d")
6344 [(set_attr "type" "slt")
6345 (set_attr "mode" "SI")])
6347 (define_insn "*sge_di"
6348 [(set (match_operand:DI 0 "register_operand" "=d")
6349 (geu:DI (match_operand:DI 1 "register_operand" "d")
6351 "TARGET_64BIT && !TARGET_MIPS16"
6353 [(set_attr "type" "slt")
6354 (set_attr "mode" "DI")])
6356 (define_expand "sltu"
6357 [(set (match_operand:SI 0 "register_operand")
6358 (ltu:SI (match_dup 1)
6361 { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
6363 (define_insn "*sltu_si"
6364 [(set (match_operand:SI 0 "register_operand" "=d")
6365 (ltu:SI (match_operand:SI 1 "register_operand" "d")
6366 (match_operand:SI 2 "arith_operand" "dI")))]
6369 [(set_attr "type" "slt")
6370 (set_attr "mode" "SI")])
6372 (define_insn "*sltu_si_mips16"
6373 [(set (match_operand:SI 0 "register_operand" "=t,t")
6374 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
6375 (match_operand:SI 2 "arith_operand" "d,I")))]
6378 [(set_attr "type" "slt")
6379 (set_attr "mode" "SI")
6380 (set_attr_alternative "length"
6382 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6386 (define_insn "*sltu_di"
6387 [(set (match_operand:DI 0 "register_operand" "=d")
6388 (ltu:DI (match_operand:DI 1 "register_operand" "d")
6389 (match_operand:DI 2 "arith_operand" "dI")))]
6390 "TARGET_64BIT && !TARGET_MIPS16"
6392 [(set_attr "type" "slt")
6393 (set_attr "mode" "DI")])
6395 (define_insn "*sltu_di_mips16"
6396 [(set (match_operand:DI 0 "register_operand" "=t,t")
6397 (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
6398 (match_operand:DI 2 "arith_operand" "d,I")))]
6399 "TARGET_64BIT && TARGET_MIPS16"
6401 [(set_attr "type" "slt")
6402 (set_attr "mode" "DI")
6403 (set_attr_alternative "length"
6405 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6409 (define_expand "sleu"
6410 [(set (match_operand:SI 0 "register_operand")
6411 (leu:SI (match_dup 1)
6414 { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
6416 (define_insn "*sleu_si"
6417 [(set (match_operand:SI 0 "register_operand" "=d")
6418 (leu:SI (match_operand:SI 1 "register_operand" "d")
6419 (match_operand:SI 2 "sleu_operand" "")))]
6422 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6423 return "sltu\t%0,%1,%2";
6425 [(set_attr "type" "slt")
6426 (set_attr "mode" "SI")])
6428 (define_insn "*sleu_si_mips16"
6429 [(set (match_operand:SI 0 "register_operand" "=t")
6430 (leu:SI (match_operand:SI 1 "register_operand" "d")
6431 (match_operand:SI 2 "sleu_operand" "")))]
6434 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6435 return "sltu\t%1,%2";
6437 [(set_attr "type" "slt")
6438 (set_attr "mode" "SI")
6439 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6443 (define_insn "*sleu_di"
6444 [(set (match_operand:DI 0 "register_operand" "=d")
6445 (leu:DI (match_operand:DI 1 "register_operand" "d")
6446 (match_operand:DI 2 "sleu_operand" "")))]
6447 "TARGET_64BIT && !TARGET_MIPS16"
6449 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6450 return "sltu\t%0,%1,%2";
6452 [(set_attr "type" "slt")
6453 (set_attr "mode" "DI")])
6455 (define_insn "*sleu_di_mips16"
6456 [(set (match_operand:DI 0 "register_operand" "=t")
6457 (leu:DI (match_operand:DI 1 "register_operand" "d")
6458 (match_operand:DI 2 "sleu_operand" "")))]
6459 "TARGET_64BIT && TARGET_MIPS16"
6461 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6462 return "sltu\t%1,%2";
6464 [(set_attr "type" "slt")
6465 (set_attr "mode" "DI")
6466 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6471 ;; ....................
6473 ;; FLOATING POINT COMPARISONS
6475 ;; ....................
6477 (define_insn "sunordered_df"
6478 [(set (match_operand:CC 0 "register_operand" "=z")
6479 (unordered:CC (match_operand:DF 1 "register_operand" "f")
6480 (match_operand:DF 2 "register_operand" "f")))]
6481 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6483 [(set_attr "type" "fcmp")
6484 (set_attr "mode" "FPSW")])
6486 (define_insn "sunlt_df"
6487 [(set (match_operand:CC 0 "register_operand" "=z")
6488 (unlt:CC (match_operand:DF 1 "register_operand" "f")
6489 (match_operand:DF 2 "register_operand" "f")))]
6490 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6492 [(set_attr "type" "fcmp")
6493 (set_attr "mode" "FPSW")])
6495 (define_insn "suneq_df"
6496 [(set (match_operand:CC 0 "register_operand" "=z")
6497 (uneq:CC (match_operand:DF 1 "register_operand" "f")
6498 (match_operand:DF 2 "register_operand" "f")))]
6499 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6501 [(set_attr "type" "fcmp")
6502 (set_attr "mode" "FPSW")])
6504 (define_insn "sunle_df"
6505 [(set (match_operand:CC 0 "register_operand" "=z")
6506 (unle:CC (match_operand:DF 1 "register_operand" "f")
6507 (match_operand:DF 2 "register_operand" "f")))]
6508 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6510 [(set_attr "type" "fcmp")
6511 (set_attr "mode" "FPSW")])
6513 (define_insn "seq_df"
6514 [(set (match_operand:CC 0 "register_operand" "=z")
6515 (eq:CC (match_operand:DF 1 "register_operand" "f")
6516 (match_operand:DF 2 "register_operand" "f")))]
6517 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6519 [(set_attr "type" "fcmp")
6520 (set_attr "mode" "FPSW")])
6522 (define_insn "slt_df"
6523 [(set (match_operand:CC 0 "register_operand" "=z")
6524 (lt:CC (match_operand:DF 1 "register_operand" "f")
6525 (match_operand:DF 2 "register_operand" "f")))]
6526 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6528 [(set_attr "type" "fcmp")
6529 (set_attr "mode" "FPSW")])
6531 (define_insn "sle_df"
6532 [(set (match_operand:CC 0 "register_operand" "=z")
6533 (le:CC (match_operand:DF 1 "register_operand" "f")
6534 (match_operand:DF 2 "register_operand" "f")))]
6535 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6537 [(set_attr "type" "fcmp")
6538 (set_attr "mode" "FPSW")])
6540 (define_insn "sgt_df"
6541 [(set (match_operand:CC 0 "register_operand" "=z")
6542 (gt:CC (match_operand:DF 1 "register_operand" "f")
6543 (match_operand:DF 2 "register_operand" "f")))]
6544 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6546 [(set_attr "type" "fcmp")
6547 (set_attr "mode" "FPSW")])
6549 (define_insn "sge_df"
6550 [(set (match_operand:CC 0 "register_operand" "=z")
6551 (ge:CC (match_operand:DF 1 "register_operand" "f")
6552 (match_operand:DF 2 "register_operand" "f")))]
6553 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6555 [(set_attr "type" "fcmp")
6556 (set_attr "mode" "FPSW")])
6558 (define_insn "sunordered_sf"
6559 [(set (match_operand:CC 0 "register_operand" "=z")
6560 (unordered:CC (match_operand:SF 1 "register_operand" "f")
6561 (match_operand:SF 2 "register_operand" "f")))]
6564 [(set_attr "type" "fcmp")
6565 (set_attr "mode" "FPSW")])
6567 (define_insn "sunlt_sf"
6568 [(set (match_operand:CC 0 "register_operand" "=z")
6569 (unlt:CC (match_operand:SF 1 "register_operand" "f")
6570 (match_operand:SF 2 "register_operand" "f")))]
6573 [(set_attr "type" "fcmp")
6574 (set_attr "mode" "FPSW")])
6576 (define_insn "suneq_sf"
6577 [(set (match_operand:CC 0 "register_operand" "=z")
6578 (uneq:CC (match_operand:SF 1 "register_operand" "f")
6579 (match_operand:SF 2 "register_operand" "f")))]
6582 [(set_attr "type" "fcmp")
6583 (set_attr "mode" "FPSW")])
6585 (define_insn "sunle_sf"
6586 [(set (match_operand:CC 0 "register_operand" "=z")
6587 (unle:CC (match_operand:SF 1 "register_operand" "f")
6588 (match_operand:SF 2 "register_operand" "f")))]
6591 [(set_attr "type" "fcmp")
6592 (set_attr "mode" "FPSW")])
6594 (define_insn "seq_sf"
6595 [(set (match_operand:CC 0 "register_operand" "=z")
6596 (eq:CC (match_operand:SF 1 "register_operand" "f")
6597 (match_operand:SF 2 "register_operand" "f")))]
6600 [(set_attr "type" "fcmp")
6601 (set_attr "mode" "FPSW")])
6603 (define_insn "slt_sf"
6604 [(set (match_operand:CC 0 "register_operand" "=z")
6605 (lt:CC (match_operand:SF 1 "register_operand" "f")
6606 (match_operand:SF 2 "register_operand" "f")))]
6609 [(set_attr "type" "fcmp")
6610 (set_attr "mode" "FPSW")])
6612 (define_insn "sle_sf"
6613 [(set (match_operand:CC 0 "register_operand" "=z")
6614 (le:CC (match_operand:SF 1 "register_operand" "f")
6615 (match_operand:SF 2 "register_operand" "f")))]
6618 [(set_attr "type" "fcmp")
6619 (set_attr "mode" "FPSW")])
6621 (define_insn "sgt_sf"
6622 [(set (match_operand:CC 0 "register_operand" "=z")
6623 (gt:CC (match_operand:SF 1 "register_operand" "f")
6624 (match_operand:SF 2 "register_operand" "f")))]
6627 [(set_attr "type" "fcmp")
6628 (set_attr "mode" "FPSW")])
6630 (define_insn "sge_sf"
6631 [(set (match_operand:CC 0 "register_operand" "=z")
6632 (ge:CC (match_operand:SF 1 "register_operand" "f")
6633 (match_operand:SF 2 "register_operand" "f")))]
6636 [(set_attr "type" "fcmp")
6637 (set_attr "mode" "FPSW")])
6640 ;; ....................
6642 ;; UNCONDITIONAL BRANCHES
6644 ;; ....................
6646 ;; Unconditional branches.
6650 (label_ref (match_operand 0 "" "")))]
6655 if (get_attr_length (insn) <= 8)
6656 return "%*b\t%l0%/";
6659 output_asm_insn (mips_output_load_label (), operands);
6660 return "%*jr\t%@%/%]";
6664 return "%*j\t%l0%/";
6666 [(set_attr "type" "jump")
6667 (set_attr "mode" "none")
6668 (set (attr "length")
6669 ;; We can't use `j' when emitting PIC. Emit a branch if it's
6670 ;; in range, otherwise load the address of the branch target into
6671 ;; $at and then jump to it.
6673 (ior (eq (symbol_ref "flag_pic") (const_int 0))
6674 (lt (abs (minus (match_dup 0)
6675 (plus (pc) (const_int 4))))
6676 (const_int 131072)))
6677 (const_int 4) (const_int 16)))])
6679 ;; We need a different insn for the mips16, because a mips16 branch
6680 ;; does not have a delay slot.
6684 (label_ref (match_operand 0 "" "")))]
6687 [(set_attr "type" "branch")
6688 (set_attr "mode" "none")
6689 (set_attr "length" "8")])
6691 (define_expand "indirect_jump"
6692 [(set (pc) (match_operand 0 "register_operand"))]
6698 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
6699 operands[0] = copy_to_mode_reg (Pmode, dest);
6701 if (!(Pmode == DImode))
6702 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
6704 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
6709 (define_insn "indirect_jump_internal1"
6710 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
6711 "!(Pmode == DImode)"
6713 [(set_attr "type" "jump")
6714 (set_attr "mode" "none")])
6716 (define_insn "indirect_jump_internal2"
6717 [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
6720 [(set_attr "type" "jump")
6721 (set_attr "mode" "none")])
6723 (define_expand "tablejump"
6725 (match_operand 0 "register_operand"))
6726 (use (label_ref (match_operand 1 "")))]
6731 if (GET_MODE (operands[0]) != HImode)
6733 if (!(Pmode == DImode))
6734 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
6736 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
6740 if (GET_MODE (operands[0]) != ptr_mode)
6744 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
6745 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
6747 if (Pmode == SImode)
6748 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
6750 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
6754 (define_insn "tablejump_internal1"
6756 (match_operand:SI 0 "register_operand" "d"))
6757 (use (label_ref (match_operand 1 "" "")))]
6760 [(set_attr "type" "jump")
6761 (set_attr "mode" "none")])
6763 (define_insn "tablejump_internal2"
6765 (match_operand:DI 0 "register_operand" "d"))
6766 (use (label_ref (match_operand 1 "" "")))]
6769 [(set_attr "type" "jump")
6770 (set_attr "mode" "none")])
6772 (define_expand "tablejump_mips161"
6773 [(set (pc) (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand"))
6774 (label_ref:SI (match_operand 1 ""))))]
6775 "TARGET_MIPS16 && !(Pmode == DImode)"
6779 t1 = gen_reg_rtx (SImode);
6780 t2 = gen_reg_rtx (SImode);
6781 t3 = gen_reg_rtx (SImode);
6782 emit_insn (gen_extendhisi2 (t1, operands[0]));
6783 emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
6784 emit_insn (gen_addsi3 (t3, t1, t2));
6785 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
6789 (define_expand "tablejump_mips162"
6790 [(set (pc) (plus:DI (sign_extend:DI (match_operand:HI 0 "register_operand"))
6791 (label_ref:DI (match_operand 1 ""))))]
6792 "TARGET_MIPS16 && Pmode == DImode"
6796 t1 = gen_reg_rtx (DImode);
6797 t2 = gen_reg_rtx (DImode);
6798 t3 = gen_reg_rtx (DImode);
6799 emit_insn (gen_extendhidi2 (t1, operands[0]));
6800 emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
6801 emit_insn (gen_adddi3 (t3, t1, t2));
6802 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
6806 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
6807 ;; While it is possible to either pull it off the stack (in the
6808 ;; o32 case) or recalculate it given t9 and our target label,
6809 ;; it takes 3 or 4 insns to do so.
6811 (define_expand "builtin_setjmp_setup"
6812 [(use (match_operand 0 "register_operand"))]
6817 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
6818 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
6822 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
6823 ;; that older code did recalculate the gp from $25. Continue to jump through
6824 ;; $25 for compatibility (we lose nothing by doing so).
6826 (define_expand "builtin_longjmp"
6827 [(use (match_operand 0 "register_operand"))]
6830 /* The elements of the buffer are, in order: */
6831 int W = GET_MODE_SIZE (Pmode);
6832 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6833 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
6834 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
6835 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
6836 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6837 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
6838 The target is bound to be using $28 as the global pointer
6839 but the current function might not be. */
6840 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
6842 /* This bit is similar to expand_builtin_longjmp except that it
6843 restores $gp as well. */
6844 emit_move_insn (hard_frame_pointer_rtx, fp);
6845 emit_move_insn (pv, lab);
6846 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6847 emit_move_insn (gp, gpv);
6848 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6849 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6850 emit_insn (gen_rtx_USE (VOIDmode, gp));
6851 emit_indirect_jump (pv);
6856 ;; ....................
6858 ;; Function prologue/epilogue
6860 ;; ....................
6863 (define_expand "prologue"
6867 mips_expand_prologue ();
6871 ;; Block any insns from being moved before this point, since the
6872 ;; profiling call to mcount can use various registers that aren't
6873 ;; saved or used to pass arguments.
6875 (define_insn "blockage"
6876 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
6879 [(set_attr "type" "unknown")
6880 (set_attr "mode" "none")
6881 (set_attr "length" "0")])
6883 (define_expand "epilogue"
6887 mips_expand_epilogue (false);
6891 (define_expand "sibcall_epilogue"
6895 mips_expand_epilogue (true);
6899 ;; Trivial return. Make it look like a normal return insn as that
6900 ;; allows jump optimizations to work better.
6902 (define_insn "return"
6904 "mips_can_use_return_insn ()"
6906 [(set_attr "type" "jump")
6907 (set_attr "mode" "none")])
6911 (define_insn "return_internal"
6913 (use (match_operand 0 "pmode_register_operand" ""))]
6916 [(set_attr "type" "jump")
6917 (set_attr "mode" "none")])
6919 ;; This is used in compiling the unwind routines.
6920 (define_expand "eh_return"
6921 [(use (match_operand 0 "general_operand"))]
6924 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
6926 if (GET_MODE (operands[0]) != gpr_mode)
6927 operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
6929 emit_insn (gen_eh_set_lr_di (operands[0]));
6931 emit_insn (gen_eh_set_lr_si (operands[0]));
6936 ;; Clobber the return address on the stack. We can't expand this
6937 ;; until we know where it will be put in the stack frame.
6939 (define_insn "eh_set_lr_si"
6940 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6941 (clobber (match_scratch:SI 1 "=&d"))]
6945 (define_insn "eh_set_lr_di"
6946 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6947 (clobber (match_scratch:DI 1 "=&d"))]
6952 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6953 (clobber (match_scratch 1))]
6954 "reload_completed && !TARGET_DEBUG_D_MODE"
6957 mips_set_return_address (operands[0], operands[1]);
6961 (define_insn_and_split "exception_receiver"
6963 (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
6964 "TARGET_ABICALLS && TARGET_OLDABI"
6966 "&& reload_completed"
6972 [(set_attr "type" "load")
6973 (set_attr "length" "12")])
6976 ;; ....................
6980 ;; ....................
6982 ;; Instructions to load a call address from the GOT. The address might
6983 ;; point to a function or to a lazy binding stub. In the latter case,
6984 ;; the stub will use the dynamic linker to resolve the function, which
6985 ;; in turn will change the GOT entry to point to the function's real
6988 ;; This means that every call, even pure and constant ones, can
6989 ;; potentially modify the GOT entry. And once a stub has been called,
6990 ;; we must not call it again.
6992 ;; We represent this restriction using an imaginary fixed register that
6993 ;; acts like a GOT version number. By making the register call-clobbered,
6994 ;; we tell the target-independent code that the address could be changed
6995 ;; by any call insn.
6996 (define_insn "load_callsi"
6997 [(set (match_operand:SI 0 "register_operand" "=c")
6998 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6999 (match_operand:SI 2 "immediate_operand" "")
7000 (reg:SI FAKE_CALL_REGNO)]
7004 [(set_attr "type" "load")
7005 (set_attr "length" "4")])
7007 (define_insn "load_calldi"
7008 [(set (match_operand:DI 0 "register_operand" "=c")
7009 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7010 (match_operand:DI 2 "immediate_operand" "")
7011 (reg:DI FAKE_CALL_REGNO)]
7015 [(set_attr "type" "load")
7016 (set_attr "length" "4")])
7018 ;; Sibling calls. All these patterns use jump instructions.
7020 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
7021 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
7022 ;; is defined in terms of call_insn_operand, the same is true of the
7025 ;; When we use an indirect jump, we need a register that will be
7026 ;; preserved by the epilogue. Since TARGET_ABICALLS forces us to
7027 ;; use $25 for this purpose -- and $25 is never clobbered by the
7028 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
7030 (define_expand "sibcall"
7031 [(parallel [(call (match_operand 0 "")
7032 (match_operand 1 ""))
7033 (use (match_operand 2 "")) ;; next_arg_reg
7034 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
7037 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
7041 (define_insn "sibcall_internal"
7042 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
7043 (match_operand 1 "" ""))]
7044 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7048 [(set_attr "type" "call")])
7050 (define_expand "sibcall_value"
7051 [(parallel [(set (match_operand 0 "")
7052 (call (match_operand 1 "")
7053 (match_operand 2 "")))
7054 (use (match_operand 3 ""))])] ;; next_arg_reg
7057 mips_expand_call (operands[0], XEXP (operands[1], 0),
7058 operands[2], operands[3], true);
7062 (define_insn "sibcall_value_internal"
7063 [(set (match_operand 0 "register_operand" "=df,df")
7064 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
7065 (match_operand 2 "" "")))]
7066 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7070 [(set_attr "type" "call")])
7072 (define_insn "sibcall_value_multiple_internal"
7073 [(set (match_operand 0 "register_operand" "=df,df")
7074 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
7075 (match_operand 2 "" "")))
7076 (set (match_operand 3 "register_operand" "=df,df")
7077 (call (mem:SI (match_dup 1))
7079 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7083 [(set_attr "type" "call")])
7085 (define_expand "call"
7086 [(parallel [(call (match_operand 0 "")
7087 (match_operand 1 ""))
7088 (use (match_operand 2 "")) ;; next_arg_reg
7089 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
7092 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
7096 ;; This instruction directly corresponds to an assembly-language "jal".
7097 ;; There are four cases:
7100 ;; Both symbolic and register destinations are OK. The pattern
7101 ;; always expands to a single mips instruction.
7103 ;; - -mabicalls/-mno-explicit-relocs:
7104 ;; Again, both symbolic and register destinations are OK.
7105 ;; The call is treated as a multi-instruction black box.
7107 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
7108 ;; Only "jal $25" is allowed. This expands to a single "jalr $25"
7111 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
7112 ;; Only "jal $25" is allowed. The call is actually two instructions:
7113 ;; "jalr $25" followed by an insn to reload $gp.
7115 ;; In the last case, we can generate the individual instructions with
7116 ;; a define_split. There are several things to be wary of:
7118 ;; - We can't expose the load of $gp before reload. If we did,
7119 ;; it might get removed as dead, but reload can introduce new
7120 ;; uses of $gp by rematerializing constants.
7122 ;; - We shouldn't restore $gp after calls that never return.
7123 ;; It isn't valid to insert instructions between a noreturn
7124 ;; call and the following barrier.
7126 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
7127 ;; instruction preserves $gp and so have no effect on its liveness.
7128 ;; But once we generate the separate insns, it becomes obvious that
7129 ;; $gp is not live on entry to the call.
7131 ;; ??? The operands[2] = insn check is a hack to make the original insn
7132 ;; available to the splitter.
7133 (define_insn_and_split "call_internal"
7134 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
7135 (match_operand 1 "" ""))
7136 (clobber (reg:SI 31))]
7138 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
7139 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
7142 emit_call_insn (gen_call_split (operands[0], operands[1]));
7143 if (!find_reg_note (operands[2], REG_NORETURN, 0))
7147 [(set_attr "jal" "indirect,direct")
7148 (set_attr "extended_mips16" "no,yes")])
7150 (define_insn "call_split"
7151 [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
7152 (match_operand 1 "" ""))
7153 (clobber (reg:SI 31))
7154 (clobber (reg:SI 28))]
7155 "TARGET_SPLIT_CALLS"
7157 [(set_attr "type" "call")])
7159 (define_expand "call_value"
7160 [(parallel [(set (match_operand 0 "")
7161 (call (match_operand 1 "")
7162 (match_operand 2 "")))
7163 (use (match_operand 3 ""))])] ;; next_arg_reg
7166 mips_expand_call (operands[0], XEXP (operands[1], 0),
7167 operands[2], operands[3], false);
7171 ;; See comment for call_internal.
7172 (define_insn_and_split "call_value_internal"
7173 [(set (match_operand 0 "register_operand" "=df,df")
7174 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7175 (match_operand 2 "" "")))
7176 (clobber (reg:SI 31))]
7178 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7179 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
7182 emit_call_insn (gen_call_value_split (operands[0], operands[1],
7184 if (!find_reg_note (operands[3], REG_NORETURN, 0))
7188 [(set_attr "jal" "indirect,direct")
7189 (set_attr "extended_mips16" "no,yes")])
7191 (define_insn "call_value_split"
7192 [(set (match_operand 0 "register_operand" "=df")
7193 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7194 (match_operand 2 "" "")))
7195 (clobber (reg:SI 31))
7196 (clobber (reg:SI 28))]
7197 "TARGET_SPLIT_CALLS"
7199 [(set_attr "type" "call")])
7201 ;; See comment for call_internal.
7202 (define_insn_and_split "call_value_multiple_internal"
7203 [(set (match_operand 0 "register_operand" "=df,df")
7204 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7205 (match_operand 2 "" "")))
7206 (set (match_operand 3 "register_operand" "=df,df")
7207 (call (mem:SI (match_dup 1))
7209 (clobber (reg:SI 31))]
7211 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7212 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
7215 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
7216 operands[2], operands[3]));
7217 if (!find_reg_note (operands[4], REG_NORETURN, 0))
7221 [(set_attr "jal" "indirect,direct")
7222 (set_attr "extended_mips16" "no,yes")])
7224 (define_insn "call_value_multiple_split"
7225 [(set (match_operand 0 "register_operand" "=df")
7226 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7227 (match_operand 2 "" "")))
7228 (set (match_operand 3 "register_operand" "=df")
7229 (call (mem:SI (match_dup 1))
7231 (clobber (reg:SI 31))
7232 (clobber (reg:SI 28))]
7233 "TARGET_SPLIT_CALLS"
7235 [(set_attr "type" "call")])
7237 ;; Call subroutine returning any type.
7239 (define_expand "untyped_call"
7240 [(parallel [(call (match_operand 0 "")
7242 (match_operand 1 "")
7243 (match_operand 2 "")])]
7248 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
7250 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7252 rtx set = XVECEXP (operands[2], 0, i);
7253 emit_move_insn (SET_DEST (set), SET_SRC (set));
7256 emit_insn (gen_blockage ());
7261 ;; ....................
7265 ;; ....................
7269 (define_expand "prefetch"
7270 [(prefetch (match_operand 0 "address_operand")
7271 (match_operand 1 "const_int_operand")
7272 (match_operand 2 "const_int_operand"))]
7275 if (symbolic_operand (operands[0], GET_MODE (operands[0])))
7276 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
7279 (define_insn "prefetch_si_address"
7280 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7281 (match_operand:SI 3 "const_int_operand" "I"))
7282 (match_operand:SI 1 "const_int_operand" "n")
7283 (match_operand:SI 2 "const_int_operand" "n"))]
7284 "ISA_HAS_PREFETCH && Pmode == SImode"
7285 { return mips_emit_prefetch (operands); }
7286 [(set_attr "type" "prefetch")])
7288 (define_insn "prefetch_indexed_si"
7289 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7290 (match_operand:SI 3 "register_operand" "r"))
7291 (match_operand:SI 1 "const_int_operand" "n")
7292 (match_operand:SI 2 "const_int_operand" "n"))]
7293 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
7294 { return mips_emit_prefetch (operands); }
7295 [(set_attr "type" "prefetchx")])
7297 (define_insn "prefetch_si"
7298 [(prefetch (match_operand:SI 0 "register_operand" "r")
7299 (match_operand:SI 1 "const_int_operand" "n")
7300 (match_operand:SI 2 "const_int_operand" "n"))]
7301 "ISA_HAS_PREFETCH && Pmode == SImode"
7303 operands[3] = const0_rtx;
7304 return mips_emit_prefetch (operands);
7306 [(set_attr "type" "prefetch")])
7308 (define_insn "prefetch_di_address"
7309 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7310 (match_operand:DI 3 "const_int_operand" "I"))
7311 (match_operand:DI 1 "const_int_operand" "n")
7312 (match_operand:DI 2 "const_int_operand" "n"))]
7313 "ISA_HAS_PREFETCH && Pmode == DImode"
7314 { return mips_emit_prefetch (operands); }
7315 [(set_attr "type" "prefetch")])
7317 (define_insn "prefetch_indexed_di"
7318 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7319 (match_operand:DI 3 "register_operand" "r"))
7320 (match_operand:DI 1 "const_int_operand" "n")
7321 (match_operand:DI 2 "const_int_operand" "n"))]
7322 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
7323 { return mips_emit_prefetch (operands); }
7324 [(set_attr "type" "prefetchx")])
7326 (define_insn "prefetch_di"
7327 [(prefetch (match_operand:DI 0 "register_operand" "r")
7328 (match_operand:DI 1 "const_int_operand" "n")
7329 (match_operand:DI 2 "const_int_operand" "n"))]
7330 "ISA_HAS_PREFETCH && Pmode == DImode"
7332 operands[3] = const0_rtx;
7333 return mips_emit_prefetch (operands);
7335 [(set_attr "type" "prefetch")])
7341 [(set_attr "type" "nop")
7342 (set_attr "mode" "none")])
7344 ;; Like nop, but commented out when outside a .set noreorder block.
7345 (define_insn "hazard_nop"
7354 [(set_attr "type" "nop")])
7356 ;; MIPS4 Conditional move instructions.
7359 [(set (match_operand:SI 0 "register_operand" "=d,d")
7361 (match_operator:SI 4 "equality_operator"
7362 [(match_operand:SI 1 "register_operand" "d,d")
7364 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7365 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7366 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7370 [(set_attr "type" "condmove")
7371 (set_attr "mode" "SI")])
7374 [(set (match_operand:SI 0 "register_operand" "=d,d")
7376 (match_operator:DI 4 "equality_operator"
7377 [(match_operand:DI 1 "register_operand" "d,d")
7379 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7380 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7381 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7385 [(set_attr "type" "condmove")
7386 (set_attr "mode" "SI")])
7389 [(set (match_operand:SI 0 "register_operand" "=d,d")
7391 (match_operator:CC 3 "equality_operator"
7392 [(match_operand:CC 4 "register_operand" "z,z")
7394 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
7395 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
7396 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7400 [(set_attr "type" "condmove")
7401 (set_attr "mode" "SI")])
7404 [(set (match_operand:DI 0 "register_operand" "=d,d")
7406 (match_operator:SI 4 "equality_operator"
7407 [(match_operand:SI 1 "register_operand" "d,d")
7409 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7410 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7411 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7415 [(set_attr "type" "condmove")
7416 (set_attr "mode" "DI")])
7419 [(set (match_operand:DI 0 "register_operand" "=d,d")
7421 (match_operator:DI 4 "equality_operator"
7422 [(match_operand:DI 1 "register_operand" "d,d")
7424 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7425 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7426 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7430 [(set_attr "type" "condmove")
7431 (set_attr "mode" "DI")])
7434 [(set (match_operand:DI 0 "register_operand" "=d,d")
7436 (match_operator:CC 3 "equality_operator"
7437 [(match_operand:CC 4 "register_operand" "z,z")
7439 (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
7440 (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
7441 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
7445 [(set_attr "type" "condmove")
7446 (set_attr "mode" "DI")])
7449 [(set (match_operand:SF 0 "register_operand" "=f,f")
7451 (match_operator:SI 4 "equality_operator"
7452 [(match_operand:SI 1 "register_operand" "d,d")
7454 (match_operand:SF 2 "register_operand" "f,0")
7455 (match_operand:SF 3 "register_operand" "0,f")))]
7456 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7460 [(set_attr "type" "condmove")
7461 (set_attr "mode" "SF")])
7464 [(set (match_operand:SF 0 "register_operand" "=f,f")
7466 (match_operator:DI 4 "equality_operator"
7467 [(match_operand:DI 1 "register_operand" "d,d")
7469 (match_operand:SF 2 "register_operand" "f,0")
7470 (match_operand:SF 3 "register_operand" "0,f")))]
7471 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7475 [(set_attr "type" "condmove")
7476 (set_attr "mode" "SF")])
7479 [(set (match_operand:SF 0 "register_operand" "=f,f")
7481 (match_operator:CC 3 "equality_operator"
7482 [(match_operand:CC 4 "register_operand" "z,z")
7484 (match_operand:SF 1 "register_operand" "f,0")
7485 (match_operand:SF 2 "register_operand" "0,f")))]
7486 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7490 [(set_attr "type" "condmove")
7491 (set_attr "mode" "SF")])
7494 [(set (match_operand:DF 0 "register_operand" "=f,f")
7496 (match_operator:SI 4 "equality_operator"
7497 [(match_operand:SI 1 "register_operand" "d,d")
7499 (match_operand:DF 2 "register_operand" "f,0")
7500 (match_operand:DF 3 "register_operand" "0,f")))]
7501 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7505 [(set_attr "type" "condmove")
7506 (set_attr "mode" "DF")])
7509 [(set (match_operand:DF 0 "register_operand" "=f,f")
7511 (match_operator:DI 4 "equality_operator"
7512 [(match_operand:DI 1 "register_operand" "d,d")
7514 (match_operand:DF 2 "register_operand" "f,0")
7515 (match_operand:DF 3 "register_operand" "0,f")))]
7516 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7520 [(set_attr "type" "condmove")
7521 (set_attr "mode" "DF")])
7524 [(set (match_operand:DF 0 "register_operand" "=f,f")
7526 (match_operator:CC 3 "equality_operator"
7527 [(match_operand:CC 4 "register_operand" "z,z")
7529 (match_operand:DF 1 "register_operand" "f,0")
7530 (match_operand:DF 2 "register_operand" "0,f")))]
7531 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7535 [(set_attr "type" "condmove")
7536 (set_attr "mode" "DF")])
7538 ;; These are the main define_expand's used to make conditional moves.
7540 (define_expand "movsicc"
7541 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7542 (set (match_operand:SI 0 "register_operand")
7543 (if_then_else:SI (match_dup 5)
7544 (match_operand:SI 2 "reg_or_0_operand")
7545 (match_operand:SI 3 "reg_or_0_operand")))]
7546 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7548 gen_conditional_move (operands);
7552 (define_expand "movdicc"
7553 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7554 (set (match_operand:DI 0 "register_operand")
7555 (if_then_else:DI (match_dup 5)
7556 (match_operand:DI 2 "reg_or_0_operand")
7557 (match_operand:DI 3 "reg_or_0_operand")))]
7558 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7560 gen_conditional_move (operands);
7564 (define_expand "movsfcc"
7565 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7566 (set (match_operand:SF 0 "register_operand")
7567 (if_then_else:SF (match_dup 5)
7568 (match_operand:SF 2 "register_operand")
7569 (match_operand:SF 3 "register_operand")))]
7570 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7572 gen_conditional_move (operands);
7576 (define_expand "movdfcc"
7577 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7578 (set (match_operand:DF 0 "register_operand")
7579 (if_then_else:DF (match_dup 5)
7580 (match_operand:DF 2 "register_operand")
7581 (match_operand:DF 3 "register_operand")))]
7582 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7584 gen_conditional_move (operands);
7589 ;; ....................
7591 ;; mips16 inline constant tables
7593 ;; ....................
7596 (define_insn "consttable_int"
7597 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
7598 (match_operand 1 "const_int_operand" "")]
7599 UNSPEC_CONSTTABLE_INT)]
7602 assemble_integer (operands[0], INTVAL (operands[1]),
7603 BITS_PER_UNIT * INTVAL (operands[1]), 1);
7606 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
7608 (define_insn "consttable_float"
7609 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
7610 UNSPEC_CONSTTABLE_FLOAT)]
7615 if (GET_CODE (operands[0]) != CONST_DOUBLE)
7617 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7618 assemble_real (d, GET_MODE (operands[0]),
7619 GET_MODE_BITSIZE (GET_MODE (operands[0])));
7622 [(set (attr "length")
7623 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
7625 (define_insn "align"
7626 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
7629 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
7632 [(match_operand 0 "small_data_pattern")]
7635 { operands[0] = mips_rewrite_small_data (operands[0]); })