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)
40 (UNSPEC_LOAD_RIGHT 19)
41 (UNSPEC_STORE_LEFT 20)
42 (UNSPEC_STORE_RIGHT 21)
49 (UNSPEC_ADDRESS_FIRST 100)
51 (FAKE_CALL_REGNO 79)])
53 (include "predicates.md")
55 ;; ....................
59 ;; ....................
61 (define_attr "got" "unset,xgot_high,load"
62 (const_string "unset"))
64 ;; For jal instructions, this attribute is DIRECT when the target address
65 ;; is symbolic and INDIRECT when it is a register.
66 (define_attr "jal" "unset,direct,indirect"
67 (const_string "unset"))
69 ;; This attribute is YES if the instruction is a jal macro (not a
70 ;; real jal instruction).
72 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
73 ;; restore $gp. Direct jals are also macros in NewABI PIC since they
74 ;; load the target address into $25.
75 (define_attr "jal_macro" "no,yes"
76 (cond [(eq_attr "jal" "direct")
77 (symbol_ref "TARGET_ABICALLS != 0")
78 (eq_attr "jal" "indirect")
79 (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
82 ;; Classification of each insn.
83 ;; branch conditional branch
84 ;; jump unconditional jump
85 ;; call unconditional call
86 ;; load load instruction(s)
87 ;; fpload floating point load
88 ;; fpidxload floating point indexed load
89 ;; store store instruction(s)
90 ;; fpstore floating point store
91 ;; fpidxstore floating point indexed store
92 ;; prefetch memory prefetch (register + offset)
93 ;; prefetchx memory indexed prefetch (register + register)
94 ;; condmove conditional moves
95 ;; xfer transfer to/from coprocessor
96 ;; mthilo transfer to hi/lo registers
97 ;; mfhilo transfer from hi/lo registers
98 ;; const load constant
99 ;; arith integer arithmetic and logical instructions
100 ;; shift integer shift instructions
101 ;; slt set less than instructions
102 ;; clz the clz and clo instructions
103 ;; trap trap if instructions
104 ;; imul integer multiply
105 ;; imadd integer multiply-add
106 ;; idiv integer divide
107 ;; fmove floating point register move
108 ;; fadd floating point add/subtract
109 ;; fmul floating point multiply
110 ;; fmadd floating point multiply-add
111 ;; fdiv floating point divide
112 ;; frdiv floating point reciprocal divide
113 ;; fabs floating point absolute value
114 ;; fneg floating point negation
115 ;; fcmp floating point compare
116 ;; fcvt floating point convert
117 ;; fsqrt floating point square root
118 ;; frsqrt floating point reciprocal square root
119 ;; multi multiword sequence (or user asm statements)
122 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,frdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
123 (cond [(eq_attr "jal" "!unset") (const_string "call")
124 (eq_attr "got" "load") (const_string "load")]
125 (const_string "unknown")))
127 ;; Main data type used by the insn
128 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
129 (const_string "unknown"))
131 ;; Is this an extended instruction in mips16 mode?
132 (define_attr "extended_mips16" "no,yes"
135 ;; Length of instruction in bytes.
136 (define_attr "length" ""
137 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
138 ;; If a branch is outside this range, we have a choice of two
139 ;; sequences. For PIC, an out-of-range branch like:
144 ;; becomes the equivalent of:
153 ;; where the load address can be up to three instructions long
156 ;; The non-PIC case is similar except that we use a direct
157 ;; jump instead of an la/jr pair. Since the target of this
158 ;; jump is an absolute 28-bit bit address (the other bits
159 ;; coming from the address of the delay slot) this form cannot
160 ;; cross a 256MB boundary. We could provide the option of
161 ;; using la/jr in this case too, but we do not do so at
164 ;; Note that this value does not account for the delay slot
165 ;; instruction, whose length is added separately. If the RTL
166 ;; pattern has no explicit delay slot, mips_adjust_insn_length
167 ;; will add the length of the implicit nop. The values for
168 ;; forward and backward branches will be different as well.
169 (eq_attr "type" "branch")
170 (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
171 (le (minus (pc) (match_dup 1)) (const_int 131068)))
173 (ne (symbol_ref "flag_pic") (const_int 0))
177 (eq_attr "got" "load")
179 (eq_attr "got" "xgot_high")
182 (eq_attr "type" "const")
183 (symbol_ref "mips_const_insns (operands[1]) * 4")
184 (eq_attr "type" "load,fpload")
185 (symbol_ref "mips_fetch_insns (operands[1]) * 4")
186 (eq_attr "type" "store,fpstore")
187 (symbol_ref "mips_fetch_insns (operands[0]) * 4")
189 ;; In the worst case, a call macro will take 8 instructions:
191 ;; lui $25,%call_hi(FOO)
193 ;; lw $25,%call_lo(FOO)($25)
199 (eq_attr "jal_macro" "yes")
202 (and (eq_attr "extended_mips16" "yes")
203 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
206 ;; Various VR4120 errata require a nop to be inserted after a macc
207 ;; instruction. The assembler does this for us, so account for
208 ;; the worst-case length here.
209 (and (eq_attr "type" "imadd")
210 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
213 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
214 ;; the result of the second one is missed. The assembler should work
215 ;; around this by inserting a nop after the first dmult.
216 (and (eq_attr "type" "imul")
217 (and (eq_attr "mode" "DI")
218 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
221 (eq_attr "type" "idiv")
222 (symbol_ref "mips_idiv_insns () * 4")
225 ;; Attribute describing the processor. This attribute must match exactly
226 ;; with the processor_type enumeration in mips.h.
228 "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
229 (const (symbol_ref "mips_tune")))
231 ;; The type of hardware hazard associated with this instruction.
232 ;; DELAY means that the next instruction cannot read the result
233 ;; of this one. HILO means that the next two instructions cannot
234 ;; write to HI or LO.
235 (define_attr "hazard" "none,delay,hilo"
236 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
237 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
238 (const_string "delay")
240 (and (eq_attr "type" "xfer")
241 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
242 (const_string "delay")
244 (and (eq_attr "type" "fcmp")
245 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
246 (const_string "delay")
248 ;; The r4000 multiplication patterns include an mflo instruction.
249 (and (eq_attr "type" "imul")
250 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
251 (const_string "hilo")
253 (and (eq_attr "type" "mfhilo")
254 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
255 (const_string "hilo")]
256 (const_string "none")))
258 ;; Is it a single instruction?
259 (define_attr "single_insn" "no,yes"
260 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
262 ;; Can the instruction be put into a delay slot?
263 (define_attr "can_delay" "no,yes"
264 (if_then_else (and (eq_attr "type" "!branch,call,jump")
265 (and (eq_attr "hazard" "none")
266 (eq_attr "single_insn" "yes")))
268 (const_string "no")))
270 ;; Attribute defining whether or not we can use the branch-likely instructions
271 (define_attr "branch_likely" "no,yes"
273 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
275 (const_string "no"))))
277 ;; True if an instruction might assign to hi or lo when reloaded.
278 ;; This is used by the TUNE_MACC_CHAINS code.
279 (define_attr "may_clobber_hilo" "no,yes"
280 (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
282 (const_string "no")))
284 ;; Describe a user's asm statement.
285 (define_asm_attributes
286 [(set_attr "type" "multi")])
288 ;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
289 ;; from the same template.
290 (define_mode_macro GPR [SI (DI "TARGET_64BIT")])
292 ;; This mode macro allows :P to be used for patterns that operate on
293 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
294 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
296 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
297 ;; 32-bit version and "dsubu" in the 64-bit version.
298 (define_mode_attr d [(SI "") (DI "d")])
300 ;; Mode attributes for GPR loads and stores.
301 (define_mode_attr load [(SI "lw") (DI "ld")])
302 (define_mode_attr store [(SI "sw") (DI "sd")])
304 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
305 ;; are different. Some forms of unextended addiu have an 8-bit immediate
306 ;; field but the equivalent daddiu has only a 5-bit field.
307 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
309 ;; This code macro allows all branch instructions to be generated from
310 ;; a single define_expand template.
311 (define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
312 eq ne gt ge lt le gtu geu ltu leu])
314 ;; This code macro allows signed and unsigned widening multiplications
315 ;; to use the same template.
316 (define_code_macro any_extend [sign_extend zero_extend])
318 ;; <u> expands to an empty string when doing a signed operation and
319 ;; "u" when doing an unsigned operation.
320 (define_code_attr u [(sign_extend "") (zero_extend "u")])
322 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
323 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
325 ;; .........................
327 ;; Branch, call and jump delay slots
329 ;; .........................
331 (define_delay (and (eq_attr "type" "branch")
332 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
333 [(eq_attr "can_delay" "yes")
335 (and (eq_attr "branch_likely" "yes")
336 (eq_attr "can_delay" "yes"))])
338 (define_delay (eq_attr "type" "jump")
339 [(eq_attr "can_delay" "yes")
343 (define_delay (and (eq_attr "type" "call")
344 (eq_attr "jal_macro" "no"))
345 [(eq_attr "can_delay" "yes")
349 ;; Pipeline descriptions.
351 ;; generic.md provides a fallback for processors without a specific
352 ;; pipeline description. It is derived from the old define_function_unit
353 ;; version and uses the "alu" and "imuldiv" units declared below.
355 ;; Some of the processor-specific files are also derived from old
356 ;; define_function_unit descriptions and simply override the parts of
357 ;; generic.md that don't apply. The other processor-specific files
358 ;; are self-contained.
359 (define_automaton "alu,imuldiv")
361 (define_cpu_unit "alu" "alu")
362 (define_cpu_unit "imuldiv" "imuldiv")
378 (include "generic.md")
381 ;; ....................
385 ;; ....................
389 [(trap_if (const_int 1) (const_int 0))]
392 if (ISA_HAS_COND_TRAP)
394 else if (TARGET_MIPS16)
399 [(set_attr "type" "trap")])
401 (define_expand "conditional_trap"
402 [(trap_if (match_operator 0 "comparison_operator"
403 [(match_dup 2) (match_dup 3)])
404 (match_operand 1 "const_int_operand"))]
407 if (operands[1] == const0_rtx)
409 mips_gen_conditional_trap (operands);
417 [(trap_if (match_operator 0 "trap_comparison_operator"
418 [(match_operand:SI 1 "reg_or_0_operand" "dJ")
419 (match_operand:SI 2 "arith_operand" "dI")])
423 [(set_attr "type" "trap")])
426 [(trap_if (match_operator 0 "trap_comparison_operator"
427 [(match_operand:DI 1 "reg_or_0_operand" "dJ")
428 (match_operand:DI 2 "arith_operand" "dI")])
430 "TARGET_64BIT && ISA_HAS_COND_TRAP"
432 [(set_attr "type" "trap")])
435 ;; ....................
439 ;; ....................
442 (define_insn "adddf3"
443 [(set (match_operand:DF 0 "register_operand" "=f")
444 (plus:DF (match_operand:DF 1 "register_operand" "f")
445 (match_operand:DF 2 "register_operand" "f")))]
446 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
448 [(set_attr "type" "fadd")
449 (set_attr "mode" "DF")])
451 (define_insn "addsf3"
452 [(set (match_operand:SF 0 "register_operand" "=f")
453 (plus:SF (match_operand:SF 1 "register_operand" "f")
454 (match_operand:SF 2 "register_operand" "f")))]
457 [(set_attr "type" "fadd")
458 (set_attr "mode" "SF")])
460 (define_expand "add<mode>3"
461 [(set (match_operand:GPR 0 "register_operand")
462 (plus:GPR (match_operand:GPR 1 "register_operand")
463 (match_operand:GPR 2 "arith_operand")))]
466 (define_insn "*add<mode>3"
467 [(set (match_operand:GPR 0 "register_operand" "=d,d")
468 (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
469 (match_operand:GPR 2 "arith_operand" "d,Q")))]
474 [(set_attr "type" "arith")
475 (set_attr "mode" "<MODE>")])
477 ;; We need to recognize MIPS16 stack pointer additions explicitly, since
478 ;; we don't have a constraint for $sp. These insns will be generated by
479 ;; the save_restore_insns functions.
481 (define_insn "*add<mode>3_sp1"
483 (plus:GPR (reg:GPR 29)
484 (match_operand:GPR 0 "const_arith_operand" "")))]
487 [(set_attr "type" "arith")
488 (set_attr "mode" "<MODE>")
489 (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
493 (define_insn "*add<mode>3_sp2"
494 [(set (match_operand:GPR 0 "register_operand" "=d")
495 (plus:GPR (reg:GPR 29)
496 (match_operand:GPR 1 "const_arith_operand" "")))]
499 [(set_attr "type" "arith")
500 (set_attr "mode" "<MODE>")
501 (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
505 (define_insn "*add<mode>3_mips16"
506 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
507 (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
508 (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
514 [(set_attr "type" "arith")
515 (set_attr "mode" "<MODE>")
516 (set_attr_alternative "length"
517 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
520 (if_then_else (match_operand 2 "m16_simm4_1")
526 ;; On the mips16, we can sometimes split an add of a constant which is
527 ;; a 4 byte instruction into two adds which are both 2 byte
528 ;; instructions. There are two cases: one where we are adding a
529 ;; constant plus a register to another register, and one where we are
530 ;; simply adding a constant to a register.
533 [(set (match_operand:SI 0 "register_operand")
534 (plus:SI (match_dup 0)
535 (match_operand:SI 1 "const_int_operand")))]
536 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
537 && GET_CODE (operands[0]) == REG
538 && M16_REG_P (REGNO (operands[0]))
539 && GET_CODE (operands[1]) == CONST_INT
540 && ((INTVAL (operands[1]) > 0x7f
541 && INTVAL (operands[1]) <= 0x7f + 0x7f)
542 || (INTVAL (operands[1]) < - 0x80
543 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
544 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
545 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
547 HOST_WIDE_INT val = INTVAL (operands[1]);
551 operands[1] = GEN_INT (0x7f);
552 operands[2] = GEN_INT (val - 0x7f);
556 operands[1] = GEN_INT (- 0x80);
557 operands[2] = GEN_INT (val + 0x80);
562 [(set (match_operand:SI 0 "register_operand")
563 (plus:SI (match_operand:SI 1 "register_operand")
564 (match_operand:SI 2 "const_int_operand")))]
565 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
566 && GET_CODE (operands[0]) == REG
567 && M16_REG_P (REGNO (operands[0]))
568 && GET_CODE (operands[1]) == REG
569 && M16_REG_P (REGNO (operands[1]))
570 && REGNO (operands[0]) != REGNO (operands[1])
571 && GET_CODE (operands[2]) == CONST_INT
572 && ((INTVAL (operands[2]) > 0x7
573 && INTVAL (operands[2]) <= 0x7 + 0x7f)
574 || (INTVAL (operands[2]) < - 0x8
575 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
576 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
577 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
579 HOST_WIDE_INT val = INTVAL (operands[2]);
583 operands[2] = GEN_INT (0x7);
584 operands[3] = GEN_INT (val - 0x7);
588 operands[2] = GEN_INT (- 0x8);
589 operands[3] = GEN_INT (val + 0x8);
594 [(set (match_operand:DI 0 "register_operand")
595 (plus:DI (match_dup 0)
596 (match_operand:DI 1 "const_int_operand")))]
597 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
598 && GET_CODE (operands[0]) == REG
599 && M16_REG_P (REGNO (operands[0]))
600 && GET_CODE (operands[1]) == CONST_INT
601 && ((INTVAL (operands[1]) > 0xf
602 && INTVAL (operands[1]) <= 0xf + 0xf)
603 || (INTVAL (operands[1]) < - 0x10
604 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
605 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
606 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
608 HOST_WIDE_INT val = INTVAL (operands[1]);
612 operands[1] = GEN_INT (0xf);
613 operands[2] = GEN_INT (val - 0xf);
617 operands[1] = GEN_INT (- 0x10);
618 operands[2] = GEN_INT (val + 0x10);
623 [(set (match_operand:DI 0 "register_operand")
624 (plus:DI (match_operand:DI 1 "register_operand")
625 (match_operand:DI 2 "const_int_operand")))]
626 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
627 && GET_CODE (operands[0]) == REG
628 && M16_REG_P (REGNO (operands[0]))
629 && GET_CODE (operands[1]) == REG
630 && M16_REG_P (REGNO (operands[1]))
631 && REGNO (operands[0]) != REGNO (operands[1])
632 && GET_CODE (operands[2]) == CONST_INT
633 && ((INTVAL (operands[2]) > 0x7
634 && INTVAL (operands[2]) <= 0x7 + 0xf)
635 || (INTVAL (operands[2]) < - 0x8
636 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
637 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
638 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
640 HOST_WIDE_INT val = INTVAL (operands[2]);
644 operands[2] = GEN_INT (0x7);
645 operands[3] = GEN_INT (val - 0x7);
649 operands[2] = GEN_INT (- 0x8);
650 operands[3] = GEN_INT (val + 0x8);
654 (define_insn "*addsi3_extended"
655 [(set (match_operand:DI 0 "register_operand" "=d,d")
657 (plus:SI (match_operand:SI 1 "register_operand" "d,d")
658 (match_operand:SI 2 "arith_operand" "d,Q"))))]
659 "TARGET_64BIT && !TARGET_MIPS16"
663 [(set_attr "type" "arith")
664 (set_attr "mode" "SI")])
666 ;; Split this insn so that the addiu splitters can have a crack at it.
667 ;; Use a conservative length estimate until the split.
668 (define_insn_and_split "*addsi3_extended_mips16"
669 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
671 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
672 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
673 "TARGET_64BIT && TARGET_MIPS16"
675 "&& reload_completed"
676 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
677 { operands[3] = gen_lowpart (SImode, operands[0]); }
678 [(set_attr "type" "arith")
679 (set_attr "mode" "SI")
680 (set_attr "extended_mips16" "yes")])
683 ;; ....................
687 ;; ....................
690 (define_insn "subdf3"
691 [(set (match_operand:DF 0 "register_operand" "=f")
692 (minus:DF (match_operand:DF 1 "register_operand" "f")
693 (match_operand:DF 2 "register_operand" "f")))]
694 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
696 [(set_attr "type" "fadd")
697 (set_attr "mode" "DF")])
699 (define_insn "subsf3"
700 [(set (match_operand:SF 0 "register_operand" "=f")
701 (minus:SF (match_operand:SF 1 "register_operand" "f")
702 (match_operand:SF 2 "register_operand" "f")))]
705 [(set_attr "type" "fadd")
706 (set_attr "mode" "SF")])
708 (define_insn "sub<mode>3"
709 [(set (match_operand:GPR 0 "register_operand" "=d")
710 (minus:GPR (match_operand:GPR 1 "register_operand" "d")
711 (match_operand:GPR 2 "register_operand" "d")))]
714 [(set_attr "type" "arith")
715 (set_attr "mode" "<MODE>")])
717 (define_insn "*subsi3_extended"
718 [(set (match_operand:DI 0 "register_operand" "=d")
720 (minus:SI (match_operand:SI 1 "register_operand" "d")
721 (match_operand:SI 2 "register_operand" "d"))))]
724 [(set_attr "type" "arith")
725 (set_attr "mode" "DI")])
728 ;; ....................
732 ;; ....................
735 (define_expand "muldf3"
736 [(set (match_operand:DF 0 "register_operand")
737 (mult:DF (match_operand:DF 1 "register_operand")
738 (match_operand:DF 2 "register_operand")))]
739 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
742 (define_insn "muldf3_internal"
743 [(set (match_operand:DF 0 "register_operand" "=f")
744 (mult:DF (match_operand:DF 1 "register_operand" "f")
745 (match_operand:DF 2 "register_operand" "f")))]
746 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
748 [(set_attr "type" "fmul")
749 (set_attr "mode" "DF")])
751 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
752 ;; operands may corrupt immediately following multiplies. This is a
753 ;; simple fix to insert NOPs.
755 (define_insn "muldf3_r4300"
756 [(set (match_operand:DF 0 "register_operand" "=f")
757 (mult:DF (match_operand:DF 1 "register_operand" "f")
758 (match_operand:DF 2 "register_operand" "f")))]
759 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
760 "mul.d\t%0,%1,%2\;nop"
761 [(set_attr "type" "fmul")
762 (set_attr "mode" "DF")
763 (set_attr "length" "8")])
765 (define_expand "mulsf3"
766 [(set (match_operand:SF 0 "register_operand")
767 (mult:SF (match_operand:SF 1 "register_operand")
768 (match_operand:SF 2 "register_operand")))]
772 (define_insn "mulsf3_internal"
773 [(set (match_operand:SF 0 "register_operand" "=f")
774 (mult:SF (match_operand:SF 1 "register_operand" "f")
775 (match_operand:SF 2 "register_operand" "f")))]
776 "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
778 [(set_attr "type" "fmul")
779 (set_attr "mode" "SF")])
783 (define_insn "mulsf3_r4300"
784 [(set (match_operand:SF 0 "register_operand" "=f")
785 (mult:SF (match_operand:SF 1 "register_operand" "f")
786 (match_operand:SF 2 "register_operand" "f")))]
787 "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
788 "mul.s\t%0,%1,%2\;nop"
789 [(set_attr "type" "fmul")
790 (set_attr "mode" "SF")
791 (set_attr "length" "8")])
794 ;; The original R4000 has a cpu bug. If a double-word or a variable
795 ;; shift executes while an integer multiplication is in progress, the
796 ;; shift may give an incorrect result. Avoid this by keeping the mflo
797 ;; with the mult on the R4000.
799 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
800 ;; (also valid for MIPS R4000MC processors):
802 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
803 ;; this errata description.
804 ;; The following code sequence causes the R4000 to incorrectly
805 ;; execute the Double Shift Right Arithmetic 32 (dsra32)
806 ;; instruction. If the dsra32 instruction is executed during an
807 ;; integer multiply, the dsra32 will only shift by the amount in
808 ;; specified in the instruction rather than the amount plus 32
810 ;; instruction 1: mult rs,rt integer multiply
811 ;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
812 ;; right arithmetic + 32
813 ;; Workaround: A dsra32 instruction placed after an integer
814 ;; multiply should not be one of the 11 instructions after the
815 ;; multiply instruction."
819 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
820 ;; the following description.
821 ;; All extended shifts (shift by n+32) and variable shifts (32 and
822 ;; 64-bit versions) may produce incorrect results under the
823 ;; following conditions:
824 ;; 1) An integer multiply is currently executing
825 ;; 2) These types of shift instructions are executed immediately
826 ;; following an integer divide instruction.
828 ;; 1) Make sure no integer multiply is running wihen these
829 ;; instruction are executed. If this cannot be predicted at
830 ;; compile time, then insert a "mfhi" to R0 instruction
831 ;; immediately after the integer multiply instruction. This
832 ;; will cause the integer multiply to complete before the shift
834 ;; 2) Separate integer divide and these two classes of shift
835 ;; instructions by another instruction or a noop."
837 ;; These processors have PRId values of 0x00004220 and 0x00004300,
840 (define_expand "mul<mode>3"
841 [(set (match_operand:GPR 0 "register_operand")
842 (mult:GPR (match_operand:GPR 1 "register_operand")
843 (match_operand:GPR 2 "register_operand")))]
846 if (GENERATE_MULT3_<MODE>)
847 emit_insn (gen_mul<mode>3_mult3 (operands[0], operands[1], operands[2]));
848 else if (!TARGET_FIX_R4000)
849 emit_insn (gen_mul<mode>3_internal (operands[0], operands[1],
852 emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
856 (define_insn "mulsi3_mult3"
857 [(set (match_operand:SI 0 "register_operand" "=d,l")
858 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
859 (match_operand:SI 2 "register_operand" "d,d")))
860 (clobber (match_scratch:SI 3 "=h,h"))
861 (clobber (match_scratch:SI 4 "=l,X"))]
864 if (which_alternative == 1)
865 return "mult\t%1,%2";
874 return "mul\t%0,%1,%2";
875 return "mult\t%0,%1,%2";
877 [(set_attr "type" "imul")
878 (set_attr "mode" "SI")])
880 (define_insn "muldi3_mult3"
881 [(set (match_operand:DI 0 "register_operand" "=d")
882 (mult:DI (match_operand:DI 1 "register_operand" "d")
883 (match_operand:DI 2 "register_operand" "d")))
884 (clobber (match_scratch:DI 3 "=h"))
885 (clobber (match_scratch:DI 4 "=l"))]
886 "TARGET_64BIT && GENERATE_MULT3_DI"
888 [(set_attr "type" "imul")
889 (set_attr "mode" "DI")])
891 ;; If a register gets allocated to LO, and we spill to memory, the reload
892 ;; will include a move from LO to a GPR. Merge it into the multiplication
893 ;; if it can set the GPR directly.
896 ;; Operand 1: GPR (1st multiplication operand)
897 ;; Operand 2: GPR (2nd multiplication operand)
899 ;; Operand 4: GPR (destination)
902 [(set (match_operand:SI 0 "register_operand")
903 (mult:SI (match_operand:SI 1 "register_operand")
904 (match_operand:SI 2 "register_operand")))
905 (clobber (match_operand:SI 3 "register_operand"))
906 (clobber (scratch:SI))])
907 (set (match_operand:SI 4 "register_operand")
908 (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
909 "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
912 (mult:SI (match_dup 1)
914 (clobber (match_dup 3))
915 (clobber (match_dup 0))])])
917 (define_insn "mul<mode>3_internal"
918 [(set (match_operand:GPR 0 "register_operand" "=l")
919 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
920 (match_operand:GPR 2 "register_operand" "d")))
921 (clobber (match_scratch:GPR 3 "=h"))]
924 [(set_attr "type" "imul")
925 (set_attr "mode" "<MODE>")])
927 (define_insn "mul<mode>3_r4000"
928 [(set (match_operand:GPR 0 "register_operand" "=d")
929 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
930 (match_operand:GPR 2 "register_operand" "d")))
931 (clobber (match_scratch:GPR 3 "=h"))
932 (clobber (match_scratch:GPR 4 "=l"))]
934 "<d>mult\t%1,%2\;mflo\t%0"
935 [(set_attr "type" "imul")
936 (set_attr "mode" "<MODE>")
937 (set_attr "length" "8")])
939 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
940 ;; of "mult; mflo". They have the same latency, but the first form gives
941 ;; us an extra cycle to compute the operands.
944 ;; Operand 1: GPR (1st multiplication operand)
945 ;; Operand 2: GPR (2nd multiplication operand)
947 ;; Operand 4: GPR (destination)
950 [(set (match_operand:SI 0 "register_operand")
951 (mult:SI (match_operand:SI 1 "register_operand")
952 (match_operand:SI 2 "register_operand")))
953 (clobber (match_operand:SI 3 "register_operand"))])
954 (set (match_operand:SI 4 "register_operand")
955 (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
956 "ISA_HAS_MACC && !GENERATE_MULT3_SI"
961 (plus:SI (mult:SI (match_dup 1)
965 (plus:SI (mult:SI (match_dup 1)
968 (clobber (match_dup 3))])])
970 ;; Multiply-accumulate patterns
972 ;; For processors that can copy the output to a general register:
974 ;; The all-d alternative is needed because the combiner will find this
975 ;; pattern and then register alloc/reload will move registers around to
976 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
978 ;; The last alternative should be made slightly less desirable, but adding
979 ;; "?" to the constraint is too strong, and causes values to be loaded into
980 ;; LO even when that's more costly. For now, using "*d" mostly does the
982 (define_insn "*mul_acc_si"
983 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
984 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
985 (match_operand:SI 2 "register_operand" "d,d,d"))
986 (match_operand:SI 3 "register_operand" "0,l,*d")))
987 (clobber (match_scratch:SI 4 "=h,h,h"))
988 (clobber (match_scratch:SI 5 "=X,3,l"))
989 (clobber (match_scratch:SI 6 "=X,X,&d"))]
991 || ISA_HAS_MADD_MSUB)
994 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
995 if (which_alternative == 2)
997 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
999 return madd[which_alternative];
1001 [(set_attr "type" "imadd,imadd,multi")
1002 (set_attr "mode" "SI")
1003 (set_attr "length" "4,4,8")])
1005 ;; Split the above insn if we failed to get LO allocated.
1007 [(set (match_operand:SI 0 "register_operand")
1008 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1009 (match_operand:SI 2 "register_operand"))
1010 (match_operand:SI 3 "register_operand")))
1011 (clobber (match_scratch:SI 4))
1012 (clobber (match_scratch:SI 5))
1013 (clobber (match_scratch:SI 6))]
1014 "reload_completed && !TARGET_DEBUG_D_MODE
1015 && GP_REG_P (true_regnum (operands[0]))
1016 && GP_REG_P (true_regnum (operands[3]))"
1017 [(parallel [(set (match_dup 6)
1018 (mult:SI (match_dup 1) (match_dup 2)))
1019 (clobber (match_dup 4))
1020 (clobber (match_dup 5))])
1021 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1024 ;; Splitter to copy result of MADD to a general register
1026 [(set (match_operand:SI 0 "register_operand")
1027 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1028 (match_operand:SI 2 "register_operand"))
1029 (match_operand:SI 3 "register_operand")))
1030 (clobber (match_scratch:SI 4))
1031 (clobber (match_scratch:SI 5))
1032 (clobber (match_scratch:SI 6))]
1033 "reload_completed && !TARGET_DEBUG_D_MODE
1034 && GP_REG_P (true_regnum (operands[0]))
1035 && true_regnum (operands[3]) == LO_REGNUM"
1036 [(parallel [(set (match_dup 3)
1037 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1039 (clobber (match_dup 4))
1040 (clobber (match_dup 5))
1041 (clobber (match_dup 6))])
1042 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1045 (define_insn "*macc"
1046 [(set (match_operand:SI 0 "register_operand" "=l,d")
1047 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1048 (match_operand:SI 2 "register_operand" "d,d"))
1049 (match_operand:SI 3 "register_operand" "0,l")))
1050 (clobber (match_scratch:SI 4 "=h,h"))
1051 (clobber (match_scratch:SI 5 "=X,3"))]
1054 if (which_alternative == 1)
1055 return "macc\t%0,%1,%2";
1056 else if (TARGET_MIPS5500)
1057 return "madd\t%1,%2";
1059 /* The VR4130 assumes that there is a two-cycle latency between a macc
1060 that "writes" to $0 and an instruction that reads from it. We avoid
1061 this by assigning to $1 instead. */
1062 return "%[macc\t%@,%1,%2%]";
1064 [(set_attr "type" "imadd")
1065 (set_attr "mode" "SI")])
1067 (define_insn "*msac"
1068 [(set (match_operand:SI 0 "register_operand" "=l,d")
1069 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1070 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1071 (match_operand:SI 3 "register_operand" "d,d"))))
1072 (clobber (match_scratch:SI 4 "=h,h"))
1073 (clobber (match_scratch:SI 5 "=X,1"))]
1076 if (which_alternative == 1)
1077 return "msac\t%0,%2,%3";
1078 else if (TARGET_MIPS5500)
1079 return "msub\t%2,%3";
1081 return "msac\t$0,%2,%3";
1083 [(set_attr "type" "imadd")
1084 (set_attr "mode" "SI")])
1086 ;; An msac-like instruction implemented using negation and a macc.
1087 (define_insn_and_split "*msac_using_macc"
1088 [(set (match_operand:SI 0 "register_operand" "=l,d")
1089 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1090 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1091 (match_operand:SI 3 "register_operand" "d,d"))))
1092 (clobber (match_scratch:SI 4 "=h,h"))
1093 (clobber (match_scratch:SI 5 "=X,1"))
1094 (clobber (match_scratch:SI 6 "=d,d"))]
1095 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1097 "&& reload_completed"
1099 (neg:SI (match_dup 3)))
1102 (plus:SI (mult:SI (match_dup 2)
1105 (clobber (match_dup 4))
1106 (clobber (match_dup 5))])]
1108 [(set_attr "type" "imadd")
1109 (set_attr "length" "8")])
1111 ;; Patterns generated by the define_peephole2 below.
1113 (define_insn "*macc2"
1114 [(set (match_operand:SI 0 "register_operand" "=l")
1115 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1116 (match_operand:SI 2 "register_operand" "d"))
1118 (set (match_operand:SI 3 "register_operand" "=d")
1119 (plus:SI (mult:SI (match_dup 1)
1122 (clobber (match_scratch:SI 4 "=h"))]
1123 "ISA_HAS_MACC && reload_completed"
1125 [(set_attr "type" "imadd")
1126 (set_attr "mode" "SI")])
1128 (define_insn "*msac2"
1129 [(set (match_operand:SI 0 "register_operand" "=l")
1130 (minus:SI (match_dup 0)
1131 (mult:SI (match_operand:SI 1 "register_operand" "d")
1132 (match_operand:SI 2 "register_operand" "d"))))
1133 (set (match_operand:SI 3 "register_operand" "=d")
1134 (minus:SI (match_dup 0)
1135 (mult:SI (match_dup 1)
1137 (clobber (match_scratch:SI 4 "=h"))]
1138 "ISA_HAS_MSAC && reload_completed"
1140 [(set_attr "type" "imadd")
1141 (set_attr "mode" "SI")])
1143 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1147 ;; Operand 1: macc/msac
1149 ;; Operand 3: GPR (destination)
1152 [(set (match_operand:SI 0 "register_operand")
1153 (match_operand:SI 1 "macc_msac_operand"))
1154 (clobber (match_operand:SI 2 "register_operand"))
1155 (clobber (scratch:SI))])
1156 (set (match_operand:SI 3 "register_operand")
1157 (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1159 [(parallel [(set (match_dup 0)
1163 (clobber (match_dup 2))])]
1166 ;; When we have a three-address multiplication instruction, it should
1167 ;; be faster to do a separate multiply and add, rather than moving
1168 ;; something into LO in order to use a macc instruction.
1170 ;; This peephole needs a scratch register to cater for the case when one
1171 ;; of the multiplication operands is the same as the destination.
1173 ;; Operand 0: GPR (scratch)
1175 ;; Operand 2: GPR (addend)
1176 ;; Operand 3: GPR (destination)
1177 ;; Operand 4: macc/msac
1179 ;; Operand 6: new multiplication
1180 ;; Operand 7: new addition/subtraction
1182 [(match_scratch:SI 0 "d")
1183 (set (match_operand:SI 1 "register_operand")
1184 (match_operand:SI 2 "register_operand"))
1187 [(set (match_operand:SI 3 "register_operand")
1188 (match_operand:SI 4 "macc_msac_operand"))
1189 (clobber (match_operand:SI 5 "register_operand"))
1190 (clobber (match_dup 1))])]
1192 && true_regnum (operands[1]) == LO_REGNUM
1193 && peep2_reg_dead_p (2, operands[1])
1194 && GP_REG_P (true_regnum (operands[3]))"
1195 [(parallel [(set (match_dup 0)
1197 (clobber (match_dup 5))
1198 (clobber (match_dup 1))])
1202 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1203 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1204 operands[2], operands[0]);
1207 ;; Same as above, except LO is the initial target of the macc.
1209 ;; Operand 0: GPR (scratch)
1211 ;; Operand 2: GPR (addend)
1212 ;; Operand 3: macc/msac
1214 ;; Operand 5: GPR (destination)
1215 ;; Operand 6: new multiplication
1216 ;; Operand 7: new addition/subtraction
1218 [(match_scratch:SI 0 "d")
1219 (set (match_operand:SI 1 "register_operand")
1220 (match_operand:SI 2 "register_operand"))
1224 (match_operand:SI 3 "macc_msac_operand"))
1225 (clobber (match_operand:SI 4 "register_operand"))
1226 (clobber (scratch:SI))])
1228 (set (match_operand:SI 5 "register_operand")
1229 (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1230 "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1231 [(parallel [(set (match_dup 0)
1233 (clobber (match_dup 4))
1234 (clobber (match_dup 1))])
1238 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1239 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1240 operands[2], operands[0]);
1243 (define_insn "*mul_sub_si"
1244 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1245 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1246 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1247 (match_operand:SI 3 "register_operand" "d,d,d"))))
1248 (clobber (match_scratch:SI 4 "=h,h,h"))
1249 (clobber (match_scratch:SI 5 "=X,1,l"))
1250 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1256 [(set_attr "type" "imadd,multi,multi")
1257 (set_attr "mode" "SI")
1258 (set_attr "length" "4,8,8")])
1260 ;; Split the above insn if we failed to get LO allocated.
1262 [(set (match_operand:SI 0 "register_operand")
1263 (minus:SI (match_operand:SI 1 "register_operand")
1264 (mult:SI (match_operand:SI 2 "register_operand")
1265 (match_operand:SI 3 "register_operand"))))
1266 (clobber (match_scratch:SI 4))
1267 (clobber (match_scratch:SI 5))
1268 (clobber (match_scratch:SI 6))]
1269 "reload_completed && !TARGET_DEBUG_D_MODE
1270 && GP_REG_P (true_regnum (operands[0]))
1271 && GP_REG_P (true_regnum (operands[1]))"
1272 [(parallel [(set (match_dup 6)
1273 (mult:SI (match_dup 2) (match_dup 3)))
1274 (clobber (match_dup 4))
1275 (clobber (match_dup 5))])
1276 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1279 ;; Splitter to copy result of MSUB to a general register
1281 [(set (match_operand:SI 0 "register_operand")
1282 (minus:SI (match_operand:SI 1 "register_operand")
1283 (mult:SI (match_operand:SI 2 "register_operand")
1284 (match_operand:SI 3 "register_operand"))))
1285 (clobber (match_scratch:SI 4))
1286 (clobber (match_scratch:SI 5))
1287 (clobber (match_scratch:SI 6))]
1288 "reload_completed && !TARGET_DEBUG_D_MODE
1289 && GP_REG_P (true_regnum (operands[0]))
1290 && true_regnum (operands[1]) == LO_REGNUM"
1291 [(parallel [(set (match_dup 1)
1292 (minus:SI (match_dup 1)
1293 (mult:SI (match_dup 2) (match_dup 3))))
1294 (clobber (match_dup 4))
1295 (clobber (match_dup 5))
1296 (clobber (match_dup 6))])
1297 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1300 (define_insn "*muls"
1301 [(set (match_operand:SI 0 "register_operand" "=l,d")
1302 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1303 (match_operand:SI 2 "register_operand" "d,d"))))
1304 (clobber (match_scratch:SI 3 "=h,h"))
1305 (clobber (match_scratch:SI 4 "=X,l"))]
1310 [(set_attr "type" "imul")
1311 (set_attr "mode" "SI")])
1313 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1315 (define_expand "<u>mulsidi3"
1317 [(set (match_operand:DI 0 "register_operand")
1318 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1319 (any_extend:DI (match_operand:SI 2 "register_operand"))))
1320 (clobber (scratch:DI))
1321 (clobber (scratch:DI))
1322 (clobber (scratch:DI))])]
1323 "!TARGET_64BIT || !TARGET_FIX_R4000"
1327 if (!TARGET_FIX_R4000)
1328 emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1331 emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1337 (define_insn "<u>mulsidi3_32bit_internal"
1338 [(set (match_operand:DI 0 "register_operand" "=x")
1339 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1340 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1341 "!TARGET_64BIT && !TARGET_FIX_R4000"
1343 [(set_attr "type" "imul")
1344 (set_attr "mode" "SI")])
1346 (define_insn "<u>mulsidi3_32bit_r4000"
1347 [(set (match_operand:DI 0 "register_operand" "=d")
1348 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1349 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1350 (clobber (match_scratch:DI 3 "=x"))]
1351 "!TARGET_64BIT && TARGET_FIX_R4000"
1352 "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1353 [(set_attr "type" "imul")
1354 (set_attr "mode" "SI")
1355 (set_attr "length" "12")])
1357 (define_insn_and_split "*<u>mulsidi3_64bit"
1358 [(set (match_operand:DI 0 "register_operand" "=d")
1359 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1360 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1361 (clobber (match_scratch:DI 3 "=l"))
1362 (clobber (match_scratch:DI 4 "=h"))
1363 (clobber (match_scratch:DI 5 "=d"))]
1364 "TARGET_64BIT && !TARGET_FIX_R4000"
1366 "&& reload_completed"
1370 (mult:SI (match_dup 1)
1374 (mult:DI (any_extend:DI (match_dup 1))
1375 (any_extend:DI (match_dup 2)))
1378 ;; OP5 <- LO, OP0 <- HI
1379 (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1380 (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1384 (ashift:DI (match_dup 5)
1387 (lshiftrt:DI (match_dup 5)
1390 ;; Shift OP0 into place.
1392 (ashift:DI (match_dup 0)
1395 ;; OR the two halves together
1397 (ior:DI (match_dup 0)
1400 [(set_attr "type" "imul")
1401 (set_attr "mode" "SI")
1402 (set_attr "length" "24")])
1404 (define_insn "*<u>mulsidi3_64bit_parts"
1405 [(set (match_operand:DI 0 "register_operand" "=l")
1407 (mult:SI (match_operand:SI 2 "register_operand" "d")
1408 (match_operand:SI 3 "register_operand" "d"))))
1409 (set (match_operand:DI 1 "register_operand" "=h")
1411 (mult:DI (any_extend:DI (match_dup 2))
1412 (any_extend:DI (match_dup 3)))
1414 "TARGET_64BIT && !TARGET_FIX_R4000"
1416 [(set_attr "type" "imul")
1417 (set_attr "mode" "SI")])
1419 ;; Widening multiply with negation.
1420 (define_insn "*muls<u>_di"
1421 [(set (match_operand:DI 0 "register_operand" "=x")
1424 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1425 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1426 "!TARGET_64BIT && ISA_HAS_MULS"
1428 [(set_attr "type" "imul")
1429 (set_attr "mode" "SI")])
1431 (define_insn "*msac<u>_di"
1432 [(set (match_operand:DI 0 "register_operand" "=x")
1434 (match_operand:DI 3 "register_operand" "0")
1436 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1437 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1438 "!TARGET_64BIT && ISA_HAS_MSAC"
1440 if (TARGET_MIPS5500)
1441 return "msub<u>\t%1,%2";
1443 return "msac<u>\t$0,%1,%2";
1445 [(set_attr "type" "imadd")
1446 (set_attr "mode" "SI")])
1448 ;; _highpart patterns
1450 (define_expand "<su>mulsi3_highpart"
1451 [(set (match_operand:SI 0 "register_operand")
1454 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1455 (any_extend:DI (match_operand:SI 2 "register_operand")))
1457 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1460 emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1464 emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1469 (define_insn "<su>mulsi3_highpart_internal"
1470 [(set (match_operand:SI 0 "register_operand" "=h")
1473 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1474 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1476 (clobber (match_scratch:SI 3 "=l"))]
1477 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1479 [(set_attr "type" "imul")
1480 (set_attr "mode" "SI")])
1482 (define_insn "<su>mulsi3_highpart_mulhi_internal"
1483 [(set (match_operand:SI 0 "register_operand" "=h,d")
1487 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1488 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1490 (clobber (match_scratch:SI 3 "=l,l"))
1491 (clobber (match_scratch:SI 4 "=X,h"))]
1496 [(set_attr "type" "imul")
1497 (set_attr "mode" "SI")])
1499 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1500 [(set (match_operand:SI 0 "register_operand" "=h,d")
1505 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1506 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1508 (clobber (match_scratch:SI 3 "=l,l"))
1509 (clobber (match_scratch:SI 4 "=X,h"))]
1513 mulshi<u>\t%0,%1,%2"
1514 [(set_attr "type" "imul")
1515 (set_attr "mode" "SI")])
1517 ;; Disable unsigned multiplication for -mfix-vr4120. This is for VR4120
1518 ;; errata MD(0), which says that dmultu does not always produce the
1520 (define_insn "<su>muldi3_highpart"
1521 [(set (match_operand:DI 0 "register_operand" "=h")
1525 (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1526 (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1528 (clobber (match_scratch:DI 3 "=l"))]
1529 "TARGET_64BIT && !TARGET_FIX_R4000
1530 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1532 [(set_attr "type" "imul")
1533 (set_attr "mode" "DI")])
1535 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1536 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
1538 (define_insn "madsi"
1539 [(set (match_operand:SI 0 "register_operand" "+l")
1540 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1541 (match_operand:SI 2 "register_operand" "d"))
1543 (clobber (match_scratch:SI 3 "=h"))]
1546 [(set_attr "type" "imadd")
1547 (set_attr "mode" "SI")])
1549 (define_insn "*<su>mul_acc_di"
1550 [(set (match_operand:DI 0 "register_operand" "=x")
1552 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1553 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1554 (match_operand:DI 3 "register_operand" "0")))]
1555 "(TARGET_MAD || ISA_HAS_MACC)
1559 return "mad<u>\t%1,%2";
1560 else if (TARGET_MIPS5500)
1561 return "madd<u>\t%1,%2";
1563 /* See comment in *macc. */
1564 return "%[macc<u>\t%@,%1,%2%]";
1566 [(set_attr "type" "imadd")
1567 (set_attr "mode" "SI")])
1569 ;; Floating point multiply accumulate instructions.
1572 [(set (match_operand:DF 0 "register_operand" "=f")
1573 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1574 (match_operand:DF 2 "register_operand" "f"))
1575 (match_operand:DF 3 "register_operand" "f")))]
1576 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1577 "madd.d\t%0,%3,%1,%2"
1578 [(set_attr "type" "fmadd")
1579 (set_attr "mode" "DF")])
1582 [(set (match_operand:SF 0 "register_operand" "=f")
1583 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1584 (match_operand:SF 2 "register_operand" "f"))
1585 (match_operand:SF 3 "register_operand" "f")))]
1586 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1587 "madd.s\t%0,%3,%1,%2"
1588 [(set_attr "type" "fmadd")
1589 (set_attr "mode" "SF")])
1592 [(set (match_operand:DF 0 "register_operand" "=f")
1593 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1594 (match_operand:DF 2 "register_operand" "f"))
1595 (match_operand:DF 3 "register_operand" "f")))]
1596 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1597 "msub.d\t%0,%3,%1,%2"
1598 [(set_attr "type" "fmadd")
1599 (set_attr "mode" "DF")])
1602 [(set (match_operand:SF 0 "register_operand" "=f")
1603 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1604 (match_operand:SF 2 "register_operand" "f"))
1605 (match_operand:SF 3 "register_operand" "f")))]
1607 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1608 "msub.s\t%0,%3,%1,%2"
1609 [(set_attr "type" "fmadd")
1610 (set_attr "mode" "SF")])
1613 [(set (match_operand:DF 0 "register_operand" "=f")
1614 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1615 (match_operand:DF 2 "register_operand" "f"))
1616 (match_operand:DF 3 "register_operand" "f"))))]
1617 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1618 && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1619 "nmadd.d\t%0,%3,%1,%2"
1620 [(set_attr "type" "fmadd")
1621 (set_attr "mode" "DF")])
1624 [(set (match_operand:DF 0 "register_operand" "=f")
1625 (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
1626 (match_operand:DF 2 "register_operand" "f"))
1627 (match_operand:DF 3 "register_operand" "f")))]
1628 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1629 && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1630 "nmadd.d\t%0,%3,%1,%2"
1631 [(set_attr "type" "fmadd")
1632 (set_attr "mode" "DF")])
1635 [(set (match_operand:SF 0 "register_operand" "=f")
1636 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1637 (match_operand:SF 2 "register_operand" "f"))
1638 (match_operand:SF 3 "register_operand" "f"))))]
1639 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1640 && HONOR_SIGNED_ZEROS (SFmode)"
1641 "nmadd.s\t%0,%3,%1,%2"
1642 [(set_attr "type" "fmadd")
1643 (set_attr "mode" "SF")])
1646 [(set (match_operand:SF 0 "register_operand" "=f")
1647 (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
1648 (match_operand:SF 2 "register_operand" "f"))
1649 (match_operand:SF 3 "register_operand" "f")))]
1650 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1651 && !HONOR_SIGNED_ZEROS (SFmode)"
1652 "nmadd.s\t%0,%3,%1,%2"
1653 [(set_attr "type" "fmadd")
1654 (set_attr "mode" "SF")])
1657 [(set (match_operand:DF 0 "register_operand" "=f")
1658 (neg:DF (minus:DF (mult:DF (match_operand:DF 2 "register_operand" "f")
1659 (match_operand:DF 3 "register_operand" "f"))
1660 (match_operand:DF 1 "register_operand" "f"))))]
1661 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1662 && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1663 "nmsub.d\t%0,%1,%2,%3"
1664 [(set_attr "type" "fmadd")
1665 (set_attr "mode" "DF")])
1668 [(set (match_operand:DF 0 "register_operand" "=f")
1669 (minus:DF (match_operand:DF 1 "register_operand" "f")
1670 (mult:DF (match_operand:DF 2 "register_operand" "f")
1671 (match_operand:DF 3 "register_operand" "f"))))]
1672 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1673 && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1674 "nmsub.d\t%0,%1,%2,%3"
1675 [(set_attr "type" "fmadd")
1676 (set_attr "mode" "DF")])
1679 [(set (match_operand:SF 0 "register_operand" "=f")
1680 (neg:SF (minus:SF (mult:SF (match_operand:SF 2 "register_operand" "f")
1681 (match_operand:SF 3 "register_operand" "f"))
1682 (match_operand:SF 1 "register_operand" "f"))))]
1683 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1684 && HONOR_SIGNED_ZEROS (SFmode)"
1685 "nmsub.s\t%0,%1,%2,%3"
1686 [(set_attr "type" "fmadd")
1687 (set_attr "mode" "SF")])
1690 [(set (match_operand:SF 0 "register_operand" "=f")
1691 (minus:SF (match_operand:SF 1 "register_operand" "f")
1692 (mult:SF (match_operand:SF 2 "register_operand" "f")
1693 (match_operand:SF 3 "register_operand" "f"))))]
1694 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1695 && !HONOR_SIGNED_ZEROS (SFmode)"
1696 "nmsub.s\t%0,%1,%2,%3"
1697 [(set_attr "type" "fmadd")
1698 (set_attr "mode" "SF")])
1701 ;; ....................
1703 ;; DIVISION and REMAINDER
1705 ;; ....................
1708 (define_expand "divdf3"
1709 [(set (match_operand:DF 0 "register_operand")
1710 (div:DF (match_operand:DF 1 "reg_or_1_operand")
1711 (match_operand:DF 2 "register_operand")))]
1712 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1714 if (const_1_operand (operands[1], DFmode))
1715 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1716 operands[1] = force_reg (DFmode, operands[1]);
1719 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
1721 ;; If an mfc1 or dmfc1 happens to access the floating point register
1722 ;; file at the same time a long latency operation (div, sqrt, recip,
1723 ;; sqrt) iterates an intermediate result back through the floating
1724 ;; point register file bypass, then instead returning the correct
1725 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1726 ;; result of the long latency operation.
1728 ;; The workaround is to insert an unconditional 'mov' from/to the
1729 ;; long latency op destination register.
1731 (define_insn "*divdf3"
1732 [(set (match_operand:DF 0 "register_operand" "=f")
1733 (div:DF (match_operand:DF 1 "register_operand" "f")
1734 (match_operand:DF 2 "register_operand" "f")))]
1735 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1738 return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
1740 return "div.d\t%0,%1,%2";
1742 [(set_attr "type" "fdiv")
1743 (set_attr "mode" "DF")
1744 (set (attr "length")
1745 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1750 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
1752 ;; In certain cases, div.s and div.ps may have a rounding error
1753 ;; and/or wrong inexact flag.
1755 ;; Therefore, we only allow div.s if not working around SB-1 rev2
1756 ;; errata, or if working around those errata and a slight loss of
1757 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
1758 (define_expand "divsf3"
1759 [(set (match_operand:SF 0 "register_operand")
1760 (div:SF (match_operand:SF 1 "reg_or_1_operand")
1761 (match_operand:SF 2 "register_operand")))]
1762 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
1764 if (const_1_operand (operands[1], SFmode))
1765 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1766 operands[1] = force_reg (SFmode, operands[1]);
1769 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1770 ;; "divdf3" comment for details).
1772 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
1773 ;; "divsf3" comment for details).
1774 (define_insn "*divsf3"
1775 [(set (match_operand:SF 0 "register_operand" "=f")
1776 (div:SF (match_operand:SF 1 "register_operand" "f")
1777 (match_operand:SF 2 "register_operand" "f")))]
1778 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
1781 return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
1783 return "div.s\t%0,%1,%2";
1785 [(set_attr "type" "fdiv")
1786 (set_attr "mode" "SF")
1787 (set (attr "length")
1788 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1792 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1793 ;; "divdf3" comment for details).
1795 [(set (match_operand:DF 0 "register_operand" "=f")
1796 (div:DF (match_operand:DF 1 "const_1_operand" "")
1797 (match_operand:DF 2 "register_operand" "f")))]
1798 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
1801 return "recip.d\t%0,%2\;mov.d\t%0,%0";
1803 return "recip.d\t%0,%2";
1805 [(set_attr "type" "frdiv")
1806 (set_attr "mode" "DF")
1807 (set (attr "length")
1808 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1812 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1813 ;; "divdf3" comment for details).
1815 [(set (match_operand:SF 0 "register_operand" "=f")
1816 (div:SF (match_operand:SF 1 "const_1_operand" "")
1817 (match_operand:SF 2 "register_operand" "f")))]
1818 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
1821 return "recip.s\t%0,%2\;mov.s\t%0,%0";
1823 return "recip.s\t%0,%2";
1825 [(set_attr "type" "frdiv")
1826 (set_attr "mode" "SF")
1827 (set (attr "length")
1828 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1832 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
1833 ;; with negative operands. We use special libgcc functions instead.
1834 (define_insn "divmod<mode>4"
1835 [(set (match_operand:GPR 0 "register_operand" "=l")
1836 (div:GPR (match_operand:GPR 1 "register_operand" "d")
1837 (match_operand:GPR 2 "register_operand" "d")))
1838 (set (match_operand:GPR 3 "register_operand" "=h")
1839 (mod:GPR (match_dup 1)
1841 "!TARGET_FIX_VR4120"
1842 { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1843 [(set_attr "type" "idiv")
1844 (set_attr "mode" "<MODE>")])
1846 (define_insn "udivmod<mode>4"
1847 [(set (match_operand:GPR 0 "register_operand" "=l")
1848 (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1849 (match_operand:GPR 2 "register_operand" "d")))
1850 (set (match_operand:GPR 3 "register_operand" "=h")
1851 (umod:GPR (match_dup 1)
1854 { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1855 [(set_attr "type" "idiv")
1856 (set_attr "mode" "<MODE>")])
1859 ;; ....................
1863 ;; ....................
1865 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1866 ;; "divdf3" comment for details).
1867 (define_insn "sqrtdf2"
1868 [(set (match_operand:DF 0 "register_operand" "=f")
1869 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
1870 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
1873 return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
1875 return "sqrt.d\t%0,%1";
1877 [(set_attr "type" "fsqrt")
1878 (set_attr "mode" "DF")
1879 (set (attr "length")
1880 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1884 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1885 ;; "divdf3" comment for details).
1886 (define_insn "sqrtsf2"
1887 [(set (match_operand:SF 0 "register_operand" "=f")
1888 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
1889 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
1892 return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
1894 return "sqrt.s\t%0,%1";
1896 [(set_attr "type" "fsqrt")
1897 (set_attr "mode" "SF")
1898 (set (attr "length")
1899 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1903 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1904 ;; "divdf3" comment for details).
1906 [(set (match_operand:DF 0 "register_operand" "=f")
1907 (div:DF (match_operand:DF 1 "const_1_operand" "")
1908 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
1909 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
1912 return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
1914 return "rsqrt.d\t%0,%2";
1916 [(set_attr "type" "frsqrt")
1917 (set_attr "mode" "DF")
1918 (set (attr "length")
1919 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1923 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1924 ;; "divdf3" comment for details).
1926 [(set (match_operand:SF 0 "register_operand" "=f")
1927 (div:SF (match_operand:SF 1 "const_1_operand" "")
1928 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
1929 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
1932 return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
1934 return "rsqrt.s\t%0,%2";
1936 [(set_attr "type" "frsqrt")
1937 (set_attr "mode" "SF")
1938 (set (attr "length")
1939 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1943 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1944 ;; "divdf3" comment for details).
1946 [(set (match_operand:DF 0 "register_operand" "=f")
1947 (sqrt:DF (div:DF (match_operand:DF 1 "const_1_operand" "")
1948 (match_operand:DF 2 "register_operand" "f"))))]
1949 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
1952 return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
1954 return "rsqrt.d\t%0,%2";
1956 [(set_attr "type" "frsqrt")
1957 (set_attr "mode" "DF")
1958 (set (attr "length")
1959 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1963 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1964 ;; "divdf3" comment for details).
1966 [(set (match_operand:SF 0 "register_operand" "=f")
1967 (sqrt:SF (div:SF (match_operand:SF 1 "const_1_operand" "")
1968 (match_operand:SF 2 "register_operand" "f"))))]
1969 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
1972 return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
1974 return "rsqrt.s\t%0,%2";
1976 [(set_attr "type" "frsqrt")
1977 (set_attr "mode" "SF")
1978 (set (attr "length")
1979 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1984 ;; ....................
1988 ;; ....................
1990 ;; Do not use the integer abs macro instruction, since that signals an
1991 ;; exception on -2147483648 (sigh).
1993 (define_insn "abs<mode>2"
1994 [(set (match_operand:GPR 0 "register_operand" "=d")
1995 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))]
1998 if (REGNO (operands[0]) == REGNO (operands[1]) && GENERATE_BRANCHLIKELY)
1999 return "%(bltzl\t%1,1f\;<d>subu\t%0,%.,%0\n%~1:%)";
2001 return "%(bgez\t%1,1f\;move\t%0,%1\;<d>subu\t%0,%.,%0\n%~1:%)";
2003 [(set_attr "type" "multi")
2004 (set_attr "mode" "<MODE>")
2005 (set_attr "length" "12")])
2007 (define_insn "absdf2"
2008 [(set (match_operand:DF 0 "register_operand" "=f")
2009 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2010 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2012 [(set_attr "type" "fabs")
2013 (set_attr "mode" "DF")])
2015 (define_insn "abssf2"
2016 [(set (match_operand:SF 0 "register_operand" "=f")
2017 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2020 [(set_attr "type" "fabs")
2021 (set_attr "mode" "SF")])
2024 ;; ....................
2026 ;; FIND FIRST BIT INSTRUCTION
2028 ;; ....................
2031 (define_insn "ffs<mode>2"
2032 [(set (match_operand:GPR 0 "register_operand" "=&d")
2033 (ffs:GPR (match_operand:GPR 1 "register_operand" "d")))
2034 (clobber (match_scratch:GPR 2 "=&d"))
2035 (clobber (match_scratch:GPR 3 "=&d"))]
2038 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2042 %~1:\tand\t%2,%1,0x0001\;\
2052 %~1:\tand\t%2,%3,0x0001\;\
2058 [(set_attr "type" "multi")
2059 (set_attr "mode" "<MODE>")
2060 (set_attr "length" "28")])
2063 ;; ...................
2065 ;; Count leading zeroes.
2067 ;; ...................
2070 (define_insn "clz<mode>2"
2071 [(set (match_operand:GPR 0 "register_operand" "=d")
2072 (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2075 [(set_attr "type" "clz")
2076 (set_attr "mode" "<MODE>")])
2079 ;; ....................
2081 ;; NEGATION and ONE'S COMPLEMENT
2083 ;; ....................
2085 (define_insn "negsi2"
2086 [(set (match_operand:SI 0 "register_operand" "=d")
2087 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2091 return "neg\t%0,%1";
2093 return "subu\t%0,%.,%1";
2095 [(set_attr "type" "arith")
2096 (set_attr "mode" "SI")])
2098 (define_insn "negdi2"
2099 [(set (match_operand:DI 0 "register_operand" "=d")
2100 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2101 "TARGET_64BIT && !TARGET_MIPS16"
2103 [(set_attr "type" "arith")
2104 (set_attr "mode" "DI")])
2106 (define_insn "negdf2"
2107 [(set (match_operand:DF 0 "register_operand" "=f")
2108 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2109 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2111 [(set_attr "type" "fneg")
2112 (set_attr "mode" "DF")])
2114 (define_insn "negsf2"
2115 [(set (match_operand:SF 0 "register_operand" "=f")
2116 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2119 [(set_attr "type" "fneg")
2120 (set_attr "mode" "SF")])
2122 (define_insn "one_cmpl<mode>2"
2123 [(set (match_operand:GPR 0 "register_operand" "=d")
2124 (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2128 return "not\t%0,%1";
2130 return "nor\t%0,%.,%1";
2132 [(set_attr "type" "arith")
2133 (set_attr "mode" "<MODE>")])
2136 ;; ....................
2140 ;; ....................
2143 ;; Many of these instructions use trivial define_expands, because we
2144 ;; want to use a different set of constraints when TARGET_MIPS16.
2146 (define_expand "and<mode>3"
2147 [(set (match_operand:GPR 0 "register_operand")
2148 (and:GPR (match_operand:GPR 1 "register_operand")
2149 (match_operand:GPR 2 "uns_arith_operand")))]
2153 operands[2] = force_reg (<MODE>mode, operands[2]);
2156 (define_insn "*and<mode>3"
2157 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2158 (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2159 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2164 [(set_attr "type" "arith")
2165 (set_attr "mode" "<MODE>")])
2167 (define_insn "*and<mode>3_mips16"
2168 [(set (match_operand:GPR 0 "register_operand" "=d")
2169 (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2170 (match_operand:GPR 2 "register_operand" "d")))]
2173 [(set_attr "type" "arith")
2174 (set_attr "mode" "<MODE>")])
2176 (define_expand "ior<mode>3"
2177 [(set (match_operand:GPR 0 "register_operand")
2178 (ior:GPR (match_operand:GPR 1 "register_operand")
2179 (match_operand:GPR 2 "uns_arith_operand")))]
2183 operands[2] = force_reg (<MODE>mode, operands[2]);
2186 (define_insn "*ior<mode>3"
2187 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2188 (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2189 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2194 [(set_attr "type" "arith")
2195 (set_attr "mode" "<MODE>")])
2197 (define_insn "*ior<mode>3_mips16"
2198 [(set (match_operand:GPR 0 "register_operand" "=d")
2199 (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2200 (match_operand:GPR 2 "register_operand" "d")))]
2203 [(set_attr "type" "arith")
2204 (set_attr "mode" "<MODE>")])
2206 (define_expand "xor<mode>3"
2207 [(set (match_operand:GPR 0 "register_operand")
2208 (xor:GPR (match_operand:GPR 1 "register_operand")
2209 (match_operand:GPR 2 "uns_arith_operand")))]
2214 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2215 (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2216 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2221 [(set_attr "type" "arith")
2222 (set_attr "mode" "<MODE>")])
2225 [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2226 (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2227 (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2233 [(set_attr "type" "arith")
2234 (set_attr "mode" "<MODE>")
2235 (set_attr_alternative "length"
2237 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2242 (define_insn "*nor<mode>3"
2243 [(set (match_operand:GPR 0 "register_operand" "=d")
2244 (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2245 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2248 [(set_attr "type" "arith")
2249 (set_attr "mode" "<MODE>")])
2252 ;; ....................
2256 ;; ....................
2260 (define_insn "truncdfsf2"
2261 [(set (match_operand:SF 0 "register_operand" "=f")
2262 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2263 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2265 [(set_attr "type" "fcvt")
2266 (set_attr "mode" "SF")])
2268 ;; Integer truncation patterns. Truncating SImode values to smaller
2269 ;; modes is a no-op, as it is for most other GCC ports. Truncating
2270 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2271 ;; need to make sure that the lower 32 bits are properly sign-extended
2272 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
2273 ;; smaller than SImode is equivalent to two separate truncations:
2276 ;; DI ---> HI == DI ---> SI ---> HI
2277 ;; DI ---> QI == DI ---> SI ---> QI
2279 ;; Step A needs a real instruction but step B does not.
2281 (define_insn "truncdisi2"
2282 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2283 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2288 [(set_attr "type" "shift,store")
2289 (set_attr "mode" "SI")
2290 (set_attr "extended_mips16" "yes,*")])
2292 (define_insn "truncdihi2"
2293 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2294 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2299 [(set_attr "type" "shift,store")
2300 (set_attr "mode" "SI")
2301 (set_attr "extended_mips16" "yes,*")])
2303 (define_insn "truncdiqi2"
2304 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2305 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2310 [(set_attr "type" "shift,store")
2311 (set_attr "mode" "SI")
2312 (set_attr "extended_mips16" "yes,*")])
2314 ;; Combiner patterns to optimize shift/truncate combinations.
2317 [(set (match_operand:SI 0 "register_operand" "=d")
2319 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2320 (match_operand:DI 2 "const_arith_operand" ""))))]
2321 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2323 [(set_attr "type" "shift")
2324 (set_attr "mode" "SI")])
2327 [(set (match_operand:SI 0 "register_operand" "=d")
2328 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2330 "TARGET_64BIT && !TARGET_MIPS16"
2332 [(set_attr "type" "shift")
2333 (set_attr "mode" "SI")])
2336 ;; Combiner patterns for truncate/sign_extend combinations. They use
2337 ;; the shift/truncate patterns above.
2339 (define_insn_and_split ""
2340 [(set (match_operand:SI 0 "register_operand" "=d")
2342 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2343 "TARGET_64BIT && !TARGET_MIPS16"
2345 "&& reload_completed"
2347 (ashift:DI (match_dup 1)
2350 (truncate:SI (ashiftrt:DI (match_dup 2)
2352 { operands[2] = gen_lowpart (DImode, operands[0]); })
2354 (define_insn_and_split ""
2355 [(set (match_operand:SI 0 "register_operand" "=d")
2357 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2358 "TARGET_64BIT && !TARGET_MIPS16"
2360 "&& reload_completed"
2362 (ashift:DI (match_dup 1)
2365 (truncate:SI (ashiftrt:DI (match_dup 2)
2367 { operands[2] = gen_lowpart (DImode, operands[0]); })
2370 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2373 [(set (match_operand:SI 0 "register_operand" "=d")
2374 (zero_extend:SI (truncate:HI
2375 (match_operand:DI 1 "register_operand" "d"))))]
2376 "TARGET_64BIT && !TARGET_MIPS16"
2377 "andi\t%0,%1,0xffff"
2378 [(set_attr "type" "arith")
2379 (set_attr "mode" "SI")])
2382 [(set (match_operand:SI 0 "register_operand" "=d")
2383 (zero_extend:SI (truncate:QI
2384 (match_operand:DI 1 "register_operand" "d"))))]
2385 "TARGET_64BIT && !TARGET_MIPS16"
2387 [(set_attr "type" "arith")
2388 (set_attr "mode" "SI")])
2391 [(set (match_operand:HI 0 "register_operand" "=d")
2392 (zero_extend:HI (truncate:QI
2393 (match_operand:DI 1 "register_operand" "d"))))]
2394 "TARGET_64BIT && !TARGET_MIPS16"
2396 [(set_attr "type" "arith")
2397 (set_attr "mode" "HI")])
2400 ;; ....................
2404 ;; ....................
2407 ;; Those for integer source operand are ordered widest source type first.
2409 (define_insn_and_split "zero_extendsidi2"
2410 [(set (match_operand:DI 0 "register_operand" "=d")
2411 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2414 "&& reload_completed"
2416 (ashift:DI (match_dup 1) (const_int 32)))
2418 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2419 "operands[1] = gen_lowpart (DImode, operands[1]);"
2420 [(set_attr "type" "multi")
2421 (set_attr "mode" "DI")
2422 (set_attr "length" "8")])
2424 (define_insn "*zero_extendsidi2_mem"
2425 [(set (match_operand:DI 0 "register_operand" "=d")
2426 (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2429 [(set_attr "type" "load")
2430 (set_attr "mode" "DI")])
2432 (define_expand "zero_extendhisi2"
2433 [(set (match_operand:SI 0 "register_operand")
2434 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2437 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2439 rtx op = gen_lowpart (SImode, operands[1]);
2440 rtx temp = force_reg (SImode, GEN_INT (0xffff));
2442 emit_insn (gen_andsi3 (operands[0], op, temp));
2448 [(set (match_operand:SI 0 "register_operand" "=d,d")
2449 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2454 [(set_attr "type" "arith,load")
2455 (set_attr "mode" "SI")
2456 (set_attr "length" "4,*")])
2459 [(set (match_operand:SI 0 "register_operand" "=d")
2460 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2463 [(set_attr "type" "load")
2464 (set_attr "mode" "SI")])
2466 (define_expand "zero_extendhidi2"
2467 [(set (match_operand:DI 0 "register_operand")
2468 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2471 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2473 rtx op = gen_lowpart (DImode, operands[1]);
2474 rtx temp = force_reg (DImode, GEN_INT (0xffff));
2476 emit_insn (gen_anddi3 (operands[0], op, temp));
2482 [(set (match_operand:DI 0 "register_operand" "=d,d")
2483 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2484 "TARGET_64BIT && !TARGET_MIPS16"
2488 [(set_attr "type" "arith,load")
2489 (set_attr "mode" "DI")
2490 (set_attr "length" "4,*")])
2493 [(set (match_operand:DI 0 "register_operand" "=d")
2494 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2495 "TARGET_64BIT && TARGET_MIPS16"
2497 [(set_attr "type" "load")
2498 (set_attr "mode" "DI")])
2500 (define_expand "zero_extendqihi2"
2501 [(set (match_operand:HI 0 "register_operand")
2502 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2505 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2507 rtx op0 = gen_lowpart (SImode, operands[0]);
2508 rtx op1 = gen_lowpart (SImode, operands[1]);
2509 rtx temp = force_reg (SImode, GEN_INT (0xff));
2511 emit_insn (gen_andsi3 (op0, op1, temp));
2517 [(set (match_operand:HI 0 "register_operand" "=d,d")
2518 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2523 [(set_attr "type" "arith,load")
2524 (set_attr "mode" "HI")
2525 (set_attr "length" "4,*")])
2528 [(set (match_operand:HI 0 "register_operand" "=d")
2529 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2532 [(set_attr "type" "load")
2533 (set_attr "mode" "HI")])
2535 (define_expand "zero_extendqisi2"
2536 [(set (match_operand:SI 0 "register_operand")
2537 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2540 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2542 rtx op = gen_lowpart (SImode, operands[1]);
2543 rtx temp = force_reg (SImode, GEN_INT (0xff));
2545 emit_insn (gen_andsi3 (operands[0], op, temp));
2551 [(set (match_operand:SI 0 "register_operand" "=d,d")
2552 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2557 [(set_attr "type" "arith,load")
2558 (set_attr "mode" "SI")
2559 (set_attr "length" "4,*")])
2562 [(set (match_operand:SI 0 "register_operand" "=d")
2563 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2566 [(set_attr "type" "load")
2567 (set_attr "mode" "SI")])
2569 (define_expand "zero_extendqidi2"
2570 [(set (match_operand:DI 0 "register_operand")
2571 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2574 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2576 rtx op = gen_lowpart (DImode, operands[1]);
2577 rtx temp = force_reg (DImode, GEN_INT (0xff));
2579 emit_insn (gen_anddi3 (operands[0], op, temp));
2585 [(set (match_operand:DI 0 "register_operand" "=d,d")
2586 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2587 "TARGET_64BIT && !TARGET_MIPS16"
2591 [(set_attr "type" "arith,load")
2592 (set_attr "mode" "DI")
2593 (set_attr "length" "4,*")])
2596 [(set (match_operand:DI 0 "register_operand" "=d")
2597 (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2598 "TARGET_64BIT && TARGET_MIPS16"
2600 [(set_attr "type" "load")
2601 (set_attr "mode" "DI")])
2604 ;; ....................
2608 ;; ....................
2611 ;; Those for integer source operand are ordered widest source type first.
2613 ;; When TARGET_64BIT, all SImode integer registers should already be in
2614 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
2615 ;; therefore get rid of register->register instructions if we constrain
2616 ;; the source to be in the same register as the destination.
2618 ;; The register alternative has type "arith" so that the pre-reload
2619 ;; scheduler will treat it as a move. This reflects what happens if
2620 ;; the register alternative needs a reload.
2621 (define_insn_and_split "extendsidi2"
2622 [(set (match_operand:DI 0 "register_operand" "=d,d")
2623 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2628 "&& reload_completed && register_operand (operands[1], VOIDmode)"
2631 emit_note (NOTE_INSN_DELETED);
2634 [(set_attr "type" "arith,load")
2635 (set_attr "mode" "DI")])
2637 ;; These patterns originally accepted general_operands, however, slightly
2638 ;; better code is generated by only accepting register_operands, and then
2639 ;; letting combine generate the lh and lb insns.
2641 ;; These expanders originally put values in registers first. We split
2642 ;; all non-mem patterns after reload.
2644 (define_expand "extendhidi2"
2645 [(set (match_operand:DI 0 "register_operand")
2646 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2650 (define_insn "*extendhidi2"
2651 [(set (match_operand:DI 0 "register_operand" "=d")
2652 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
2657 [(set (match_operand:DI 0 "register_operand")
2658 (sign_extend:DI (match_operand:HI 1 "register_operand")))]
2659 "TARGET_64BIT && reload_completed"
2661 (ashift:DI (match_dup 1) (const_int 48)))
2663 (ashiftrt:DI (match_dup 0) (const_int 48)))]
2664 "operands[1] = gen_lowpart (DImode, operands[1]);")
2666 (define_insn "*extendhidi2_mem"
2667 [(set (match_operand:DI 0 "register_operand" "=d")
2668 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2671 [(set_attr "type" "load")
2672 (set_attr "mode" "DI")])
2674 (define_expand "extendhisi2"
2675 [(set (match_operand:SI 0 "register_operand")
2676 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2679 if (ISA_HAS_SEB_SEH)
2681 emit_insn (gen_extendhisi2_hw (operands[0],
2682 force_reg (HImode, operands[1])));
2687 (define_insn "*extendhisi2"
2688 [(set (match_operand:SI 0 "register_operand" "=d")
2689 (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
2694 [(set (match_operand:SI 0 "register_operand")
2695 (sign_extend:SI (match_operand:HI 1 "register_operand")))]
2698 (ashift:SI (match_dup 1) (const_int 16)))
2700 (ashiftrt:SI (match_dup 0) (const_int 16)))]
2701 "operands[1] = gen_lowpart (SImode, operands[1]);")
2703 (define_insn "extendhisi2_mem"
2704 [(set (match_operand:SI 0 "register_operand" "=d")
2705 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2708 [(set_attr "type" "load")
2709 (set_attr "mode" "SI")])
2711 (define_insn "extendhisi2_hw"
2712 [(set (match_operand:SI 0 "register_operand" "=r")
2713 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
2716 [(set_attr "type" "arith")
2717 (set_attr "mode" "SI")])
2719 (define_expand "extendqihi2"
2720 [(set (match_operand:HI 0 "register_operand")
2721 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2725 (define_insn "*extendqihi2"
2726 [(set (match_operand:HI 0 "register_operand" "=d")
2727 (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
2732 [(set (match_operand:HI 0 "register_operand")
2733 (sign_extend:HI (match_operand:QI 1 "register_operand")))]
2736 (ashift:SI (match_dup 1) (const_int 24)))
2738 (ashiftrt:SI (match_dup 0) (const_int 24)))]
2739 "operands[0] = gen_lowpart (SImode, operands[0]);
2740 operands[1] = gen_lowpart (SImode, operands[1]);")
2742 (define_insn "*extendqihi2_internal_mem"
2743 [(set (match_operand:HI 0 "register_operand" "=d")
2744 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2747 [(set_attr "type" "load")
2748 (set_attr "mode" "SI")])
2751 (define_expand "extendqisi2"
2752 [(set (match_operand:SI 0 "register_operand")
2753 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2756 if (ISA_HAS_SEB_SEH)
2758 emit_insn (gen_extendqisi2_hw (operands[0],
2759 force_reg (QImode, operands[1])));
2764 (define_insn "*extendqisi2"
2765 [(set (match_operand:SI 0 "register_operand" "=d")
2766 (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
2771 [(set (match_operand:SI 0 "register_operand")
2772 (sign_extend:SI (match_operand:QI 1 "register_operand")))]
2775 (ashift:SI (match_dup 1) (const_int 24)))
2777 (ashiftrt:SI (match_dup 0) (const_int 24)))]
2778 "operands[1] = gen_lowpart (SImode, operands[1]);")
2780 (define_insn "*extendqisi2_mem"
2781 [(set (match_operand:SI 0 "register_operand" "=d")
2782 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2785 [(set_attr "type" "load")
2786 (set_attr "mode" "SI")])
2788 (define_insn "extendqisi2_hw"
2789 [(set (match_operand:SI 0 "register_operand" "=r")
2790 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
2793 [(set_attr "type" "arith")
2794 (set_attr "mode" "SI")])
2796 (define_expand "extendqidi2"
2797 [(set (match_operand:DI 0 "register_operand")
2798 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2802 (define_insn "*extendqidi2"
2803 [(set (match_operand:DI 0 "register_operand" "=d")
2804 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
2809 [(set (match_operand:DI 0 "register_operand")
2810 (sign_extend:DI (match_operand:QI 1 "register_operand")))]
2811 "TARGET_64BIT && reload_completed"
2813 (ashift:DI (match_dup 1) (const_int 56)))
2815 (ashiftrt:DI (match_dup 0) (const_int 56)))]
2816 "operands[1] = gen_lowpart (DImode, operands[1]);")
2818 (define_insn "*extendqidi2_mem"
2819 [(set (match_operand:DI 0 "register_operand" "=d")
2820 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2823 [(set_attr "type" "load")
2824 (set_attr "mode" "DI")])
2826 (define_insn "extendsfdf2"
2827 [(set (match_operand:DF 0 "register_operand" "=f")
2828 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2829 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2831 [(set_attr "type" "fcvt")
2832 (set_attr "mode" "DF")])
2835 ;; ....................
2839 ;; ....................
2841 (define_expand "fix_truncdfsi2"
2842 [(set (match_operand:SI 0 "register_operand")
2843 (fix:SI (match_operand:DF 1 "register_operand")))]
2844 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2846 if (!ISA_HAS_TRUNC_W)
2848 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2853 (define_insn "fix_truncdfsi2_insn"
2854 [(set (match_operand:SI 0 "register_operand" "=f")
2855 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2856 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2858 [(set_attr "type" "fcvt")
2859 (set_attr "mode" "DF")
2860 (set_attr "length" "4")])
2862 (define_insn "fix_truncdfsi2_macro"
2863 [(set (match_operand:SI 0 "register_operand" "=f")
2864 (fix:SI (match_operand:DF 1 "register_operand" "f")))
2865 (clobber (match_scratch:DF 2 "=d"))]
2866 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2869 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2871 return "trunc.w.d %0,%1,%2";
2873 [(set_attr "type" "fcvt")
2874 (set_attr "mode" "DF")
2875 (set_attr "length" "36")])
2877 (define_expand "fix_truncsfsi2"
2878 [(set (match_operand:SI 0 "register_operand")
2879 (fix:SI (match_operand:SF 1 "register_operand")))]
2882 if (!ISA_HAS_TRUNC_W)
2884 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2889 (define_insn "fix_truncsfsi2_insn"
2890 [(set (match_operand:SI 0 "register_operand" "=f")
2891 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2892 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2894 [(set_attr "type" "fcvt")
2895 (set_attr "mode" "DF")
2896 (set_attr "length" "4")])
2898 (define_insn "fix_truncsfsi2_macro"
2899 [(set (match_operand:SI 0 "register_operand" "=f")
2900 (fix:SI (match_operand:SF 1 "register_operand" "f")))
2901 (clobber (match_scratch:SF 2 "=d"))]
2902 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2905 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2907 return "trunc.w.s %0,%1,%2";
2909 [(set_attr "type" "fcvt")
2910 (set_attr "mode" "DF")
2911 (set_attr "length" "36")])
2914 (define_insn "fix_truncdfdi2"
2915 [(set (match_operand:DI 0 "register_operand" "=f")
2916 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2917 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2919 [(set_attr "type" "fcvt")
2920 (set_attr "mode" "DF")
2921 (set_attr "length" "4")])
2924 (define_insn "fix_truncsfdi2"
2925 [(set (match_operand:DI 0 "register_operand" "=f")
2926 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2927 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2929 [(set_attr "type" "fcvt")
2930 (set_attr "mode" "SF")
2931 (set_attr "length" "4")])
2934 (define_insn "floatsidf2"
2935 [(set (match_operand:DF 0 "register_operand" "=f")
2936 (float:DF (match_operand:SI 1 "register_operand" "f")))]
2937 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2939 [(set_attr "type" "fcvt")
2940 (set_attr "mode" "DF")
2941 (set_attr "length" "4")])
2944 (define_insn "floatdidf2"
2945 [(set (match_operand:DF 0 "register_operand" "=f")
2946 (float:DF (match_operand:DI 1 "register_operand" "f")))]
2947 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2949 [(set_attr "type" "fcvt")
2950 (set_attr "mode" "DF")
2951 (set_attr "length" "4")])
2954 (define_insn "floatsisf2"
2955 [(set (match_operand:SF 0 "register_operand" "=f")
2956 (float:SF (match_operand:SI 1 "register_operand" "f")))]
2959 [(set_attr "type" "fcvt")
2960 (set_attr "mode" "SF")
2961 (set_attr "length" "4")])
2964 (define_insn "floatdisf2"
2965 [(set (match_operand:SF 0 "register_operand" "=f")
2966 (float:SF (match_operand:DI 1 "register_operand" "f")))]
2967 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2969 [(set_attr "type" "fcvt")
2970 (set_attr "mode" "SF")
2971 (set_attr "length" "4")])
2974 (define_expand "fixuns_truncdfsi2"
2975 [(set (match_operand:SI 0 "register_operand")
2976 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2977 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2979 rtx reg1 = gen_reg_rtx (DFmode);
2980 rtx reg2 = gen_reg_rtx (DFmode);
2981 rtx reg3 = gen_reg_rtx (SImode);
2982 rtx label1 = gen_label_rtx ();
2983 rtx label2 = gen_label_rtx ();
2984 REAL_VALUE_TYPE offset;
2986 real_2expN (&offset, 31);
2988 if (reg1) /* Turn off complaints about unreached code. */
2990 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2991 do_pending_stack_adjust ();
2993 emit_insn (gen_cmpdf (operands[1], reg1));
2994 emit_jump_insn (gen_bge (label1));
2996 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2997 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2998 gen_rtx_LABEL_REF (VOIDmode, label2)));
3001 emit_label (label1);
3002 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3003 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3004 (BITMASK_HIGH, SImode)));
3006 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3007 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3009 emit_label (label2);
3011 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3012 fields, and can't be used for REG_NOTES anyway). */
3013 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3019 (define_expand "fixuns_truncdfdi2"
3020 [(set (match_operand:DI 0 "register_operand")
3021 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3022 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3024 rtx reg1 = gen_reg_rtx (DFmode);
3025 rtx reg2 = gen_reg_rtx (DFmode);
3026 rtx reg3 = gen_reg_rtx (DImode);
3027 rtx label1 = gen_label_rtx ();
3028 rtx label2 = gen_label_rtx ();
3029 REAL_VALUE_TYPE offset;
3031 real_2expN (&offset, 63);
3033 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3034 do_pending_stack_adjust ();
3036 emit_insn (gen_cmpdf (operands[1], reg1));
3037 emit_jump_insn (gen_bge (label1));
3039 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3040 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3041 gen_rtx_LABEL_REF (VOIDmode, label2)));
3044 emit_label (label1);
3045 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3046 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3047 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3049 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3050 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3052 emit_label (label2);
3054 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3055 fields, and can't be used for REG_NOTES anyway). */
3056 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3061 (define_expand "fixuns_truncsfsi2"
3062 [(set (match_operand:SI 0 "register_operand")
3063 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3066 rtx reg1 = gen_reg_rtx (SFmode);
3067 rtx reg2 = gen_reg_rtx (SFmode);
3068 rtx reg3 = gen_reg_rtx (SImode);
3069 rtx label1 = gen_label_rtx ();
3070 rtx label2 = gen_label_rtx ();
3071 REAL_VALUE_TYPE offset;
3073 real_2expN (&offset, 31);
3075 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3076 do_pending_stack_adjust ();
3078 emit_insn (gen_cmpsf (operands[1], reg1));
3079 emit_jump_insn (gen_bge (label1));
3081 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3082 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3083 gen_rtx_LABEL_REF (VOIDmode, label2)));
3086 emit_label (label1);
3087 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3088 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3089 (BITMASK_HIGH, SImode)));
3091 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3092 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3094 emit_label (label2);
3096 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3097 fields, and can't be used for REG_NOTES anyway). */
3098 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3103 (define_expand "fixuns_truncsfdi2"
3104 [(set (match_operand:DI 0 "register_operand")
3105 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3106 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3108 rtx reg1 = gen_reg_rtx (SFmode);
3109 rtx reg2 = gen_reg_rtx (SFmode);
3110 rtx reg3 = gen_reg_rtx (DImode);
3111 rtx label1 = gen_label_rtx ();
3112 rtx label2 = gen_label_rtx ();
3113 REAL_VALUE_TYPE offset;
3115 real_2expN (&offset, 63);
3117 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3118 do_pending_stack_adjust ();
3120 emit_insn (gen_cmpsf (operands[1], reg1));
3121 emit_jump_insn (gen_bge (label1));
3123 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3124 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3125 gen_rtx_LABEL_REF (VOIDmode, label2)));
3128 emit_label (label1);
3129 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3130 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3131 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3133 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3134 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3136 emit_label (label2);
3138 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3139 fields, and can't be used for REG_NOTES anyway). */
3140 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3145 ;; ....................
3149 ;; ....................
3151 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3153 (define_expand "extv"
3154 [(set (match_operand 0 "register_operand")
3155 (sign_extract (match_operand:QI 1 "memory_operand")
3156 (match_operand 2 "immediate_operand")
3157 (match_operand 3 "immediate_operand")))]
3160 if (mips_expand_unaligned_load (operands[0], operands[1],
3161 INTVAL (operands[2]),
3162 INTVAL (operands[3])))
3168 (define_expand "extzv"
3169 [(set (match_operand 0 "register_operand")
3170 (zero_extract (match_operand:QI 1 "memory_operand")
3171 (match_operand 2 "immediate_operand")
3172 (match_operand 3 "immediate_operand")))]
3175 if (mips_expand_unaligned_load (operands[0], operands[1],
3176 INTVAL (operands[2]),
3177 INTVAL (operands[3])))
3183 (define_expand "insv"
3184 [(set (zero_extract (match_operand:QI 0 "memory_operand")
3185 (match_operand 1 "immediate_operand")
3186 (match_operand 2 "immediate_operand"))
3187 (match_operand 3 "reg_or_0_operand"))]
3190 if (mips_expand_unaligned_store (operands[0], operands[3],
3191 INTVAL (operands[1]),
3192 INTVAL (operands[2])))
3198 ;; Unaligned word moves generated by the bit field patterns.
3200 ;; As far as the rtl is concerned, both the left-part and right-part
3201 ;; instructions can access the whole field. However, the real operand
3202 ;; refers to just the first or the last byte (depending on endianness).
3203 ;; We therefore use two memory operands to each instruction, one to
3204 ;; describe the rtl effect and one to use in the assembly output.
3206 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3207 ;; This allows us to use the standard length calculations for the "load"
3208 ;; and "store" type attributes.
3210 (define_insn "mov_<load>l"
3211 [(set (match_operand:GPR 0 "register_operand" "=d")
3212 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3213 (match_operand:QI 2 "memory_operand" "m")]
3217 [(set_attr "type" "load")
3218 (set_attr "mode" "<MODE>")
3219 (set_attr "hazard" "none")])
3221 (define_insn "mov_<load>r"
3222 [(set (match_operand:GPR 0 "register_operand" "=d")
3223 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3224 (match_operand:QI 2 "memory_operand" "m")
3225 (match_operand:GPR 3 "register_operand" "0")]
3226 UNSPEC_LOAD_RIGHT))]
3229 [(set_attr "type" "load")
3230 (set_attr "mode" "<MODE>")])
3232 (define_insn "mov_<store>l"
3233 [(set (match_operand:BLK 0 "memory_operand" "=m")
3234 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3235 (match_operand:QI 2 "memory_operand" "m")]
3236 UNSPEC_STORE_LEFT))]
3239 [(set_attr "type" "store")
3240 (set_attr "mode" "<MODE>")])
3242 (define_insn "mov_<store>r"
3243 [(set (match_operand:BLK 0 "memory_operand" "+m")
3244 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3245 (match_operand:QI 2 "memory_operand" "m")
3247 UNSPEC_STORE_RIGHT))]
3250 [(set_attr "type" "store")
3251 (set_attr "mode" "<MODE>")])
3253 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3254 ;; The required value is:
3256 ;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3258 ;; which translates to:
3260 ;; lui op0,%highest(op1)
3261 ;; daddiu op0,op0,%higher(op1)
3263 ;; daddiu op0,op0,%hi(op1)
3265 (define_insn_and_split "*lea_high64"
3266 [(set (match_operand:DI 0 "register_operand" "=d")
3267 (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3268 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3270 "&& reload_completed"
3271 [(set (match_dup 0) (high:DI (match_dup 2)))
3272 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3273 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3274 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3275 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3277 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3278 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3280 [(set_attr "length" "20")])
3282 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3283 ;; SYMBOL_GENERAL X will take 6 cycles. This next pattern allows combine
3284 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3285 ;; used once. We can then use the sequence:
3287 ;; lui op0,%highest(op1)
3289 ;; daddiu op0,op0,%higher(op1)
3290 ;; daddiu op2,op2,%lo(op1)
3292 ;; daddu op0,op0,op2
3294 ;; which takes 4 cycles on most superscalar targets.
3295 (define_insn_and_split "*lea64"
3296 [(set (match_operand:DI 0 "register_operand" "=d")
3297 (match_operand:DI 1 "general_symbolic_operand" ""))
3298 (clobber (match_scratch:DI 2 "=&d"))]
3299 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3301 "&& reload_completed"
3302 [(set (match_dup 0) (high:DI (match_dup 3)))
3303 (set (match_dup 2) (high:DI (match_dup 4)))
3304 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3305 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3306 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3307 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3309 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3310 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3312 [(set_attr "length" "24")])
3314 ;; Insns to fetch a global symbol from a big GOT.
3316 (define_insn_and_split "*xgot_hi<mode>"
3317 [(set (match_operand:P 0 "register_operand" "=d")
3318 (high:P (match_operand:P 1 "global_got_operand" "")))]
3319 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3321 "&& reload_completed"
3322 [(set (match_dup 0) (high:P (match_dup 2)))
3323 (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3325 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3326 operands[3] = pic_offset_table_rtx;
3328 [(set_attr "got" "xgot_high")
3329 (set_attr "mode" "<MODE>")])
3331 (define_insn_and_split "*xgot_lo<mode>"
3332 [(set (match_operand:P 0 "register_operand" "=d")
3333 (lo_sum:P (match_operand:P 1 "register_operand" "d")
3334 (match_operand:P 2 "global_got_operand" "")))]
3335 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3337 "&& reload_completed"
3339 (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3340 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3341 [(set_attr "got" "load")
3342 (set_attr "mode" "<MODE>")])
3344 ;; Insns to fetch a global symbol from a normal GOT.
3346 (define_insn_and_split "*got_disp<mode>"
3347 [(set (match_operand:P 0 "register_operand" "=d")
3348 (match_operand:P 1 "global_got_operand" ""))]
3349 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3351 "&& reload_completed"
3353 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3355 operands[2] = pic_offset_table_rtx;
3356 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3358 [(set_attr "got" "load")
3359 (set_attr "mode" "<MODE>")])
3361 ;; Insns for loading the high part of a local symbol.
3363 (define_insn_and_split "*got_page<mode>"
3364 [(set (match_operand:P 0 "register_operand" "=d")
3365 (high:P (match_operand:P 1 "local_got_operand" "")))]
3366 "TARGET_EXPLICIT_RELOCS"
3368 "&& reload_completed"
3370 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3372 operands[2] = pic_offset_table_rtx;
3373 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3375 [(set_attr "got" "load")
3376 (set_attr "mode" "<MODE>")])
3378 ;; Lower-level instructions for loading an address from the GOT.
3379 ;; We could use MEMs, but an unspec gives more optimization
3382 (define_insn "*load_got<mode>"
3383 [(set (match_operand:P 0 "register_operand" "=d")
3384 (unspec:P [(match_operand:P 1 "register_operand" "d")
3385 (match_operand:P 2 "immediate_operand" "")]
3388 "<load>\t%0,%R2(%1)"
3389 [(set_attr "type" "load")
3390 (set_attr "mode" "<MODE>")
3391 (set_attr "length" "4")])
3393 ;; Instructions for adding the low 16 bits of an address to a register.
3394 ;; Operand 2 is the address: print_operand works out which relocation
3395 ;; should be applied.
3397 (define_insn "*low<mode>"
3398 [(set (match_operand:P 0 "register_operand" "=d")
3399 (lo_sum:P (match_operand:P 1 "register_operand" "d")
3400 (match_operand:P 2 "immediate_operand" "")))]
3402 "<d>addiu\t%0,%1,%R2"
3403 [(set_attr "type" "arith")
3404 (set_attr "mode" "<MODE>")])
3406 (define_insn "*low<mode>_mips16"
3407 [(set (match_operand:P 0 "register_operand" "=d")
3408 (lo_sum:P (match_operand:P 1 "register_operand" "0")
3409 (match_operand:P 2 "immediate_operand" "")))]
3412 [(set_attr "type" "arith")
3413 (set_attr "mode" "<MODE>")
3414 (set_attr "length" "8")])
3416 ;; 64-bit integer moves
3418 ;; Unlike most other insns, the move insns can't be split with
3419 ;; different predicates, because register spilling and other parts of
3420 ;; the compiler, have memoized the insn number already.
3422 (define_expand "movdi"
3423 [(set (match_operand:DI 0 "")
3424 (match_operand:DI 1 ""))]
3427 if (mips_legitimize_move (DImode, operands[0], operands[1]))
3431 ;; For mips16, we need a special case to handle storing $31 into
3432 ;; memory, since we don't have a constraint to match $31. This
3433 ;; instruction can be generated by save_restore_insns.
3435 (define_insn "*mov<mode>_ra"
3436 [(set (match_operand:GPR 0 "stack_operand" "=m")
3440 [(set_attr "type" "store")
3441 (set_attr "mode" "<MODE>")])
3443 (define_insn "*movdi_32bit"
3444 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
3445 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
3446 "!TARGET_64BIT && !TARGET_MIPS16
3447 && (register_operand (operands[0], DImode)
3448 || reg_or_0_operand (operands[1], DImode))"
3449 { return mips_output_move (operands[0], operands[1]); }
3450 [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
3451 (set_attr "mode" "DI")
3452 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
3454 (define_insn "*movdi_32bit_mips16"
3455 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3456 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3457 "!TARGET_64BIT && TARGET_MIPS16
3458 && (register_operand (operands[0], DImode)
3459 || register_operand (operands[1], DImode))"
3460 { return mips_output_move (operands[0], operands[1]); }
3461 [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo")
3462 (set_attr "mode" "DI")
3463 (set_attr "length" "8,8,8,8,12,*,*,8")])
3465 (define_insn "*movdi_64bit"
3466 [(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")
3467 (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"))]
3468 "TARGET_64BIT && !TARGET_MIPS16
3469 && (register_operand (operands[0], DImode)
3470 || reg_or_0_operand (operands[1], DImode))"
3471 { return mips_output_move (operands[0], operands[1]); }
3472 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
3473 (set_attr "mode" "DI")
3474 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3476 (define_insn "*movdi_64bit_mips16"
3477 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3478 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3479 "TARGET_64BIT && TARGET_MIPS16
3480 && (register_operand (operands[0], DImode)
3481 || register_operand (operands[1], DImode))"
3482 { return mips_output_move (operands[0], operands[1]); }
3483 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
3484 (set_attr "mode" "DI")
3485 (set_attr_alternative "length"
3489 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3492 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3497 (const_string "*")])])
3500 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
3501 ;; when the original load is a 4 byte instruction but the add and the
3502 ;; load are 2 2 byte instructions.
3505 [(set (match_operand:DI 0 "register_operand")
3506 (mem:DI (plus:DI (match_dup 0)
3507 (match_operand:DI 1 "const_int_operand"))))]
3508 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3509 && !TARGET_DEBUG_D_MODE
3510 && GET_CODE (operands[0]) == REG
3511 && M16_REG_P (REGNO (operands[0]))
3512 && GET_CODE (operands[1]) == CONST_INT
3513 && ((INTVAL (operands[1]) < 0
3514 && INTVAL (operands[1]) >= -0x10)
3515 || (INTVAL (operands[1]) >= 32 * 8
3516 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3517 || (INTVAL (operands[1]) >= 0
3518 && INTVAL (operands[1]) < 32 * 8
3519 && (INTVAL (operands[1]) & 7) != 0))"
3520 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3521 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3523 HOST_WIDE_INT val = INTVAL (operands[1]);
3526 operands[2] = const0_rtx;
3527 else if (val >= 32 * 8)
3531 operands[1] = GEN_INT (0x8 + off);
3532 operands[2] = GEN_INT (val - off - 0x8);
3538 operands[1] = GEN_INT (off);
3539 operands[2] = GEN_INT (val - off);
3543 ;; 32-bit Integer moves
3545 ;; Unlike most other insns, the move insns can't be split with
3546 ;; different predicates, because register spilling and other parts of
3547 ;; the compiler, have memoized the insn number already.
3549 (define_expand "movsi"
3550 [(set (match_operand:SI 0 "")
3551 (match_operand:SI 1 ""))]
3554 if (mips_legitimize_move (SImode, operands[0], operands[1]))
3558 ;; The difference between these two is whether or not ints are allowed
3559 ;; in FP registers (off by default, use -mdebugh to enable).
3561 (define_insn "*movsi_internal"
3562 [(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")
3563 (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"))]
3565 && (register_operand (operands[0], SImode)
3566 || reg_or_0_operand (operands[1], SImode))"
3567 { return mips_output_move (operands[0], operands[1]); }
3568 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
3569 (set_attr "mode" "SI")
3570 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
3572 (define_insn "*movsi_mips16"
3573 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3574 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3576 && (register_operand (operands[0], SImode)
3577 || register_operand (operands[1], SImode))"
3578 { return mips_output_move (operands[0], operands[1]); }
3579 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
3580 (set_attr "mode" "SI")
3581 (set_attr_alternative "length"
3585 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3588 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3593 (const_string "*")])])
3595 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
3596 ;; when the original load is a 4 byte instruction but the add and the
3597 ;; load are 2 2 byte instructions.
3600 [(set (match_operand:SI 0 "register_operand")
3601 (mem:SI (plus:SI (match_dup 0)
3602 (match_operand:SI 1 "const_int_operand"))))]
3603 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3604 && GET_CODE (operands[0]) == REG
3605 && M16_REG_P (REGNO (operands[0]))
3606 && GET_CODE (operands[1]) == CONST_INT
3607 && ((INTVAL (operands[1]) < 0
3608 && INTVAL (operands[1]) >= -0x80)
3609 || (INTVAL (operands[1]) >= 32 * 4
3610 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3611 || (INTVAL (operands[1]) >= 0
3612 && INTVAL (operands[1]) < 32 * 4
3613 && (INTVAL (operands[1]) & 3) != 0))"
3614 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3615 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3617 HOST_WIDE_INT val = INTVAL (operands[1]);
3620 operands[2] = const0_rtx;
3621 else if (val >= 32 * 4)
3625 operands[1] = GEN_INT (0x7c + off);
3626 operands[2] = GEN_INT (val - off - 0x7c);
3632 operands[1] = GEN_INT (off);
3633 operands[2] = GEN_INT (val - off);
3637 ;; On the mips16, we can split a load of certain constants into a load
3638 ;; and an add. This turns a 4 byte instruction into 2 2 byte
3642 [(set (match_operand:SI 0 "register_operand")
3643 (match_operand:SI 1 "const_int_operand"))]
3644 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3645 && GET_CODE (operands[0]) == REG
3646 && M16_REG_P (REGNO (operands[0]))
3647 && GET_CODE (operands[1]) == CONST_INT
3648 && INTVAL (operands[1]) >= 0x100
3649 && INTVAL (operands[1]) <= 0xff + 0x7f"
3650 [(set (match_dup 0) (match_dup 1))
3651 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3653 int val = INTVAL (operands[1]);
3655 operands[1] = GEN_INT (0xff);
3656 operands[2] = GEN_INT (val - 0xff);
3659 ;; This insn handles moving CCmode values. It's really just a
3660 ;; slightly simplified copy of movsi_internal2, with additional cases
3661 ;; to move a condition register to a general register and to move
3662 ;; between the general registers and the floating point registers.
3664 (define_insn "movcc"
3665 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3666 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3667 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3668 { return mips_output_move (operands[0], operands[1]); }
3669 [(set_attr "type" "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
3670 (set_attr "mode" "SI")
3671 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
3673 ;; Reload condition code registers. reload_incc and reload_outcc
3674 ;; both handle moves from arbitrary operands into condition code
3675 ;; registers. reload_incc handles the more common case in which
3676 ;; a source operand is constrained to be in a condition-code
3677 ;; register, but has not been allocated to one.
3679 ;; Sometimes, such as in movcc, we have a CCmode destination whose
3680 ;; constraints do not include 'z'. reload_outcc handles the case
3681 ;; when such an operand is allocated to a condition-code register.
3683 ;; Note that reloads from a condition code register to some
3684 ;; other location can be done using ordinary moves. Moving
3685 ;; into a GPR takes a single movcc, moving elsewhere takes
3686 ;; two. We can leave these cases to the generic reload code.
3687 (define_expand "reload_incc"
3688 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3689 (match_operand:CC 1 "general_operand" ""))
3690 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3691 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3693 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3697 (define_expand "reload_outcc"
3698 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3699 (match_operand:CC 1 "register_operand" ""))
3700 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3701 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3703 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3707 ;; MIPS4 supports loading and storing a floating point register from
3708 ;; the sum of two general registers. We use two versions for each of
3709 ;; these four instructions: one where the two general registers are
3710 ;; SImode, and one where they are DImode. This is because general
3711 ;; registers will be in SImode when they hold 32 bit values, but,
3712 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
3713 ;; instructions will still work correctly.
3715 ;; ??? Perhaps it would be better to support these instructions by
3716 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
3717 ;; these instructions can only be used to load and store floating
3718 ;; point registers, that would probably cause trouble in reload.
3720 (define_insn "*lwxc1_<mode>"
3721 [(set (match_operand:SF 0 "register_operand" "=f")
3722 (mem:SF (plus:P (match_operand:P 1 "register_operand" "d")
3723 (match_operand:P 2 "register_operand" "d"))))]
3724 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
3726 [(set_attr "type" "fpidxload")
3727 (set_attr "mode" "SF")])
3729 (define_insn "*ldxc1_<mode>"
3730 [(set (match_operand:DF 0 "register_operand" "=f")
3731 (mem:DF (plus:P (match_operand:P 1 "register_operand" "d")
3732 (match_operand:P 2 "register_operand" "d"))))]
3733 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3735 [(set_attr "type" "fpidxload")
3736 (set_attr "mode" "DF")])
3738 (define_insn "*swxc1_<mode>"
3739 [(set (mem:SF (plus:P (match_operand:P 1 "register_operand" "d")
3740 (match_operand:P 2 "register_operand" "d")))
3741 (match_operand:SF 0 "register_operand" "f"))]
3742 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
3744 [(set_attr "type" "fpidxstore")
3745 (set_attr "mode" "SF")])
3747 (define_insn "*sdxc1_<mode>"
3748 [(set (mem:DF (plus:P (match_operand:P 1 "register_operand" "d")
3749 (match_operand:P 2 "register_operand" "d")))
3750 (match_operand:DF 0 "register_operand" "f"))]
3751 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3753 [(set_attr "type" "fpidxstore")
3754 (set_attr "mode" "DF")])
3756 ;; 16-bit Integer moves
3758 ;; Unlike most other insns, the move insns can't be split with
3759 ;; different predicates, because register spilling and other parts of
3760 ;; the compiler, have memoized the insn number already.
3761 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3763 (define_expand "movhi"
3764 [(set (match_operand:HI 0 "")
3765 (match_operand:HI 1 ""))]
3768 if (mips_legitimize_move (HImode, operands[0], operands[1]))
3772 (define_insn "*movhi_internal"
3773 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3774 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
3776 && (register_operand (operands[0], HImode)
3777 || reg_or_0_operand (operands[1], HImode))"
3787 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3788 (set_attr "mode" "HI")
3789 (set_attr "length" "4,4,*,*,4,4,4,4")])
3791 (define_insn "*movhi_mips16"
3792 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3793 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))]
3795 && (register_operand (operands[0], HImode)
3796 || register_operand (operands[1], HImode))"
3805 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
3806 (set_attr "mode" "HI")
3807 (set_attr_alternative "length"
3811 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3814 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3818 (const_string "*")])])
3821 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
3822 ;; when the original load is a 4 byte instruction but the add and the
3823 ;; load are 2 2 byte instructions.
3826 [(set (match_operand:HI 0 "register_operand")
3827 (mem:HI (plus:SI (match_dup 0)
3828 (match_operand:SI 1 "const_int_operand"))))]
3829 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3830 && GET_CODE (operands[0]) == REG
3831 && M16_REG_P (REGNO (operands[0]))
3832 && GET_CODE (operands[1]) == CONST_INT
3833 && ((INTVAL (operands[1]) < 0
3834 && INTVAL (operands[1]) >= -0x80)
3835 || (INTVAL (operands[1]) >= 32 * 2
3836 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
3837 || (INTVAL (operands[1]) >= 0
3838 && INTVAL (operands[1]) < 32 * 2
3839 && (INTVAL (operands[1]) & 1) != 0))"
3840 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3841 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
3843 HOST_WIDE_INT val = INTVAL (operands[1]);
3846 operands[2] = const0_rtx;
3847 else if (val >= 32 * 2)
3851 operands[1] = GEN_INT (0x7e + off);
3852 operands[2] = GEN_INT (val - off - 0x7e);
3858 operands[1] = GEN_INT (off);
3859 operands[2] = GEN_INT (val - off);
3863 ;; 8-bit Integer moves
3865 ;; Unlike most other insns, the move insns can't be split with
3866 ;; different predicates, because register spilling and other parts of
3867 ;; the compiler, have memoized the insn number already.
3868 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3870 (define_expand "movqi"
3871 [(set (match_operand:QI 0 "")
3872 (match_operand:QI 1 ""))]
3875 if (mips_legitimize_move (QImode, operands[0], operands[1]))
3879 (define_insn "*movqi_internal"
3880 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3881 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
3883 && (register_operand (operands[0], QImode)
3884 || reg_or_0_operand (operands[1], QImode))"
3894 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3895 (set_attr "mode" "QI")
3896 (set_attr "length" "4,4,*,*,4,4,4,4")])
3898 (define_insn "*movqi_mips16"
3899 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3900 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))]
3902 && (register_operand (operands[0], QImode)
3903 || register_operand (operands[1], QImode))"
3912 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
3913 (set_attr "mode" "QI")
3914 (set_attr "length" "4,4,4,4,8,*,*")])
3916 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
3917 ;; when the original load is a 4 byte instruction but the add and the
3918 ;; load are 2 2 byte instructions.
3921 [(set (match_operand:QI 0 "register_operand")
3922 (mem:QI (plus:SI (match_dup 0)
3923 (match_operand:SI 1 "const_int_operand"))))]
3924 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3925 && GET_CODE (operands[0]) == REG
3926 && M16_REG_P (REGNO (operands[0]))
3927 && GET_CODE (operands[1]) == CONST_INT
3928 && ((INTVAL (operands[1]) < 0
3929 && INTVAL (operands[1]) >= -0x80)
3930 || (INTVAL (operands[1]) >= 32
3931 && INTVAL (operands[1]) <= 31 + 0x7f))"
3932 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3933 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
3935 HOST_WIDE_INT val = INTVAL (operands[1]);
3938 operands[2] = const0_rtx;
3941 operands[1] = GEN_INT (0x7f);
3942 operands[2] = GEN_INT (val - 0x7f);
3946 ;; 32-bit floating point moves
3948 (define_expand "movsf"
3949 [(set (match_operand:SF 0 "")
3950 (match_operand:SF 1 ""))]
3953 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
3957 (define_insn "*movsf_hardfloat"
3958 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
3959 (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
3961 && (register_operand (operands[0], SFmode)
3962 || reg_or_0_operand (operands[1], SFmode))"
3963 { return mips_output_move (operands[0], operands[1]); }
3964 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
3965 (set_attr "mode" "SF")
3966 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
3968 (define_insn "*movsf_softfloat"
3969 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
3970 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
3971 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
3972 && (register_operand (operands[0], SFmode)
3973 || reg_or_0_operand (operands[1], SFmode))"
3974 { return mips_output_move (operands[0], operands[1]); }
3975 [(set_attr "type" "arith,load,store")
3976 (set_attr "mode" "SF")
3977 (set_attr "length" "4,*,*")])
3979 (define_insn "*movsf_mips16"
3980 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
3981 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
3983 && (register_operand (operands[0], SFmode)
3984 || register_operand (operands[1], SFmode))"
3985 { return mips_output_move (operands[0], operands[1]); }
3986 [(set_attr "type" "arith,arith,arith,load,store")
3987 (set_attr "mode" "SF")
3988 (set_attr "length" "4,4,4,*,*")])
3991 ;; 64-bit floating point moves
3993 (define_expand "movdf"
3994 [(set (match_operand:DF 0 "")
3995 (match_operand:DF 1 ""))]
3998 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4002 (define_insn "*movdf_hardfloat_64bit"
4003 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4004 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4005 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
4006 && (register_operand (operands[0], DFmode)
4007 || reg_or_0_operand (operands[1], DFmode))"
4008 { return mips_output_move (operands[0], operands[1]); }
4009 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4010 (set_attr "mode" "DF")
4011 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4013 (define_insn "*movdf_hardfloat_32bit"
4014 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4015 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4016 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
4017 && (register_operand (operands[0], DFmode)
4018 || reg_or_0_operand (operands[1], DFmode))"
4019 { return mips_output_move (operands[0], operands[1]); }
4020 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4021 (set_attr "mode" "DF")
4022 (set_attr "length" "4,8,*,*,8,8,8,*,*")])
4024 (define_insn "*movdf_softfloat"
4025 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
4026 (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
4027 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4028 && (register_operand (operands[0], DFmode)
4029 || reg_or_0_operand (operands[1], DFmode))"
4030 { return mips_output_move (operands[0], operands[1]); }
4031 [(set_attr "type" "arith,load,store,xfer,xfer,fmove")
4032 (set_attr "mode" "DF")
4033 (set_attr "length" "8,*,*,4,4,4")])
4035 (define_insn "*movdf_mips16"
4036 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4037 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4039 && (register_operand (operands[0], DFmode)
4040 || register_operand (operands[1], DFmode))"
4041 { return mips_output_move (operands[0], operands[1]); }
4042 [(set_attr "type" "arith,arith,arith,load,store")
4043 (set_attr "mode" "DF")
4044 (set_attr "length" "8,8,8,*,*")])
4047 [(set (match_operand:DI 0 "nonimmediate_operand")
4048 (match_operand:DI 1 "move_operand"))]
4049 "reload_completed && !TARGET_64BIT
4050 && mips_split_64bit_move_p (operands[0], operands[1])"
4053 mips_split_64bit_move (operands[0], operands[1]);
4058 [(set (match_operand:DF 0 "nonimmediate_operand")
4059 (match_operand:DF 1 "move_operand"))]
4060 "reload_completed && !TARGET_64BIT
4061 && mips_split_64bit_move_p (operands[0], operands[1])"
4064 mips_split_64bit_move (operands[0], operands[1]);
4068 ;; When generating mips16 code, split moves of negative constants into
4069 ;; a positive "li" followed by a negation.
4071 [(set (match_operand 0 "register_operand")
4072 (match_operand 1 "const_int_operand"))]
4073 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4077 (neg:SI (match_dup 2)))]
4079 operands[2] = gen_lowpart (SImode, operands[0]);
4080 operands[3] = GEN_INT (-INTVAL (operands[1]));
4083 ;; The HI and LO registers are not truly independent. If we move an mthi
4084 ;; instruction before an mflo instruction, it will make the result of the
4085 ;; mflo unpredictable. The same goes for mtlo and mfhi.
4087 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4088 ;; Operand 1 is the register we want, operand 2 is the other one.
4090 (define_insn "mfhilo_di"
4091 [(set (match_operand:DI 0 "register_operand" "=d,d")
4092 (unspec:DI [(match_operand:DI 1 "register_operand" "h,l")
4093 (match_operand:DI 2 "register_operand" "l,h")]
4097 [(set_attr "type" "mfhilo")])
4099 (define_insn "mfhilo_si"
4100 [(set (match_operand:SI 0 "register_operand" "=d,d")
4101 (unspec:SI [(match_operand:SI 1 "register_operand" "h,l")
4102 (match_operand:SI 2 "register_operand" "l,h")]
4106 [(set_attr "type" "mfhilo")])
4108 ;; Patterns for loading or storing part of a paired floating point
4109 ;; register. We need them because odd-numbered floating-point registers
4110 ;; are not fully independent: see mips_split_64bit_move.
4112 ;; Load the low word of operand 0 with operand 1.
4113 (define_insn "load_df_low"
4114 [(set (match_operand:DF 0 "register_operand" "=f,f")
4115 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
4116 UNSPEC_LOAD_DF_LOW))]
4117 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4119 operands[0] = mips_subword (operands[0], 0);
4120 return mips_output_move (operands[0], operands[1]);
4122 [(set_attr "type" "xfer,fpload")
4123 (set_attr "mode" "SF")])
4125 ;; Load the high word of operand 0 from operand 1, preserving the value
4127 (define_insn "load_df_high"
4128 [(set (match_operand:DF 0 "register_operand" "=f,f")
4129 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
4130 (match_operand:DF 2 "register_operand" "0,0")]
4131 UNSPEC_LOAD_DF_HIGH))]
4132 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4134 operands[0] = mips_subword (operands[0], 1);
4135 return mips_output_move (operands[0], operands[1]);
4137 [(set_attr "type" "xfer,fpload")
4138 (set_attr "mode" "SF")])
4140 ;; Store the high word of operand 1 in operand 0. The corresponding
4141 ;; low-word move is done in the normal way.
4142 (define_insn "store_df_high"
4143 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4144 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4145 UNSPEC_STORE_DF_HIGH))]
4146 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4148 operands[1] = mips_subword (operands[1], 1);
4149 return mips_output_move (operands[0], operands[1]);
4151 [(set_attr "type" "xfer,fpstore")
4152 (set_attr "mode" "SF")])
4154 ;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
4155 ;; of _gp from the start of this function. Operand 1 is the incoming
4156 ;; function address.
4157 (define_insn_and_split "loadgp"
4158 [(unspec_volatile [(match_operand 0 "" "")
4159 (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4160 "TARGET_ABICALLS && TARGET_NEWABI"
4163 [(set (match_dup 2) (match_dup 3))
4164 (set (match_dup 2) (match_dup 4))
4165 (set (match_dup 2) (match_dup 5))]
4167 operands[2] = pic_offset_table_rtx;
4168 operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4169 operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4170 operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4172 [(set_attr "length" "12")])
4174 ;; The use of gp is hidden when not using explicit relocations.
4175 ;; This blockage instruction prevents the gp load from being
4176 ;; scheduled after an implicit use of gp. It also prevents
4177 ;; the load from being deleted as dead.
4178 (define_insn "loadgp_blockage"
4179 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4182 [(set_attr "type" "unknown")
4183 (set_attr "mode" "none")
4184 (set_attr "length" "0")])
4186 ;; Emit a .cprestore directive, which normally expands to a single store
4187 ;; instruction. Note that we continue to use .cprestore for explicit reloc
4188 ;; code so that jals inside inline asms will work correctly.
4189 (define_insn "cprestore"
4190 [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
4194 if (set_nomacro && which_alternative == 1)
4195 return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4197 return ".cprestore\t%0";
4199 [(set_attr "type" "store")
4200 (set_attr "length" "4,12")])
4202 ;; Block moves, see mips.c for more details.
4203 ;; Argument 0 is the destination
4204 ;; Argument 1 is the source
4205 ;; Argument 2 is the length
4206 ;; Argument 3 is the alignment
4208 (define_expand "movmemsi"
4209 [(parallel [(set (match_operand:BLK 0 "general_operand")
4210 (match_operand:BLK 1 "general_operand"))
4211 (use (match_operand:SI 2 ""))
4212 (use (match_operand:SI 3 "const_int_operand"))])]
4213 "!TARGET_MIPS16 && !TARGET_MEMCPY"
4215 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4222 ;; ....................
4226 ;; ....................
4228 ;; Many of these instructions use trivial define_expands, because we
4229 ;; want to use a different set of constraints when TARGET_MIPS16.
4231 (define_expand "ashlsi3"
4232 [(set (match_operand:SI 0 "register_operand")
4233 (ashift:SI (match_operand:SI 1 "register_operand")
4234 (match_operand:SI 2 "arith_operand")))]
4237 /* On the mips16, a shift of more than 8 is a four byte instruction,
4238 so, for a shift between 8 and 16, it is just as fast to do two
4239 shifts of 8 or less. If there is a lot of shifting going on, we
4240 may win in CSE. Otherwise combine will put the shifts back
4241 together again. This can be called by function_arg, so we must
4242 be careful not to allocate a new register if we've reached the
4246 && GET_CODE (operands[2]) == CONST_INT
4247 && INTVAL (operands[2]) > 8
4248 && INTVAL (operands[2]) <= 16
4249 && ! reload_in_progress
4250 && ! reload_completed)
4252 rtx temp = gen_reg_rtx (SImode);
4254 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
4255 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
4256 GEN_INT (INTVAL (operands[2]) - 8)));
4261 (define_insn "ashlsi3_internal1"
4262 [(set (match_operand:SI 0 "register_operand" "=d")
4263 (ashift:SI (match_operand:SI 1 "register_operand" "d")
4264 (match_operand:SI 2 "arith_operand" "dI")))]
4267 if (GET_CODE (operands[2]) == CONST_INT)
4268 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4270 return "sll\t%0,%1,%2";
4272 [(set_attr "type" "shift")
4273 (set_attr "mode" "SI")])
4275 (define_insn "ashlsi3_internal1_extend"
4276 [(set (match_operand:DI 0 "register_operand" "=d")
4277 (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
4278 (match_operand:SI 2 "arith_operand" "dI"))))]
4279 "TARGET_64BIT && !TARGET_MIPS16"
4281 if (GET_CODE (operands[2]) == CONST_INT)
4282 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4284 return "sll\t%0,%1,%2";
4286 [(set_attr "type" "shift")
4287 (set_attr "mode" "DI")])
4290 (define_insn "ashlsi3_internal2"
4291 [(set (match_operand:SI 0 "register_operand" "=d,d")
4292 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
4293 (match_operand:SI 2 "arith_operand" "d,I")))]
4296 if (which_alternative == 0)
4297 return "sll\t%0,%2";
4299 if (GET_CODE (operands[2]) == CONST_INT)
4300 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4302 return "sll\t%0,%1,%2";
4304 [(set_attr "type" "shift")
4305 (set_attr "mode" "SI")
4306 (set_attr_alternative "length"
4308 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4312 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4315 [(set (match_operand:SI 0 "register_operand")
4316 (ashift:SI (match_operand:SI 1 "register_operand")
4317 (match_operand:SI 2 "const_int_operand")))]
4318 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4319 && GET_CODE (operands[2]) == CONST_INT
4320 && INTVAL (operands[2]) > 8
4321 && INTVAL (operands[2]) <= 16"
4322 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
4323 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4324 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4326 (define_expand "ashldi3"
4327 [(set (match_operand:DI 0 "register_operand")
4328 (ashift:DI (match_operand:DI 1 "register_operand")
4329 (match_operand:SI 2 "arith_operand")))]
4332 /* On the mips16, a shift of more than 8 is a four byte
4333 instruction, so, for a shift between 8 and 16, it is just as
4334 fast to do two shifts of 8 or less. If there is a lot of
4335 shifting going on, we may win in CSE. Otherwise combine will
4336 put the shifts back together again. This can be called by
4337 function_arg, so we must be careful not to allocate a new
4338 register if we've reached the reload pass. */
4341 && GET_CODE (operands[2]) == CONST_INT
4342 && INTVAL (operands[2]) > 8
4343 && INTVAL (operands[2]) <= 16
4344 && ! reload_in_progress
4345 && ! reload_completed)
4347 rtx temp = gen_reg_rtx (DImode);
4349 emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
4350 emit_insn (gen_ashldi3_internal (operands[0], temp,
4351 GEN_INT (INTVAL (operands[2]) - 8)));
4357 (define_insn "ashldi3_internal"
4358 [(set (match_operand:DI 0 "register_operand" "=d")
4359 (ashift:DI (match_operand:DI 1 "register_operand" "d")
4360 (match_operand:SI 2 "arith_operand" "dI")))]
4361 "TARGET_64BIT && !TARGET_MIPS16"
4363 if (GET_CODE (operands[2]) == CONST_INT)
4364 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4366 return "dsll\t%0,%1,%2";
4368 [(set_attr "type" "shift")
4369 (set_attr "mode" "DI")])
4372 [(set (match_operand:DI 0 "register_operand" "=d,d")
4373 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4374 (match_operand:SI 2 "arith_operand" "d,I")))]
4375 "TARGET_64BIT && TARGET_MIPS16"
4377 if (which_alternative == 0)
4378 return "dsll\t%0,%2";
4380 if (GET_CODE (operands[2]) == CONST_INT)
4381 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4383 return "dsll\t%0,%1,%2";
4385 [(set_attr "type" "shift")
4386 (set_attr "mode" "DI")
4387 (set_attr_alternative "length"
4389 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4394 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4397 [(set (match_operand:DI 0 "register_operand")
4398 (ashift:DI (match_operand:DI 1 "register_operand")
4399 (match_operand:SI 2 "const_int_operand")))]
4400 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
4402 && GET_CODE (operands[2]) == CONST_INT
4403 && INTVAL (operands[2]) > 8
4404 && INTVAL (operands[2]) <= 16"
4405 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
4406 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
4407 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4409 (define_expand "ashrsi3"
4410 [(set (match_operand:SI 0 "register_operand")
4411 (ashiftrt:SI (match_operand:SI 1 "register_operand")
4412 (match_operand:SI 2 "arith_operand")))]
4415 /* On the mips16, a shift of more than 8 is a four byte instruction,
4416 so, for a shift between 8 and 16, it is just as fast to do two
4417 shifts of 8 or less. If there is a lot of shifting going on, we
4418 may win in CSE. Otherwise combine will put the shifts back
4422 && GET_CODE (operands[2]) == CONST_INT
4423 && INTVAL (operands[2]) > 8
4424 && INTVAL (operands[2]) <= 16)
4426 rtx temp = gen_reg_rtx (SImode);
4428 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
4429 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
4430 GEN_INT (INTVAL (operands[2]) - 8)));
4435 (define_insn "ashrsi3_internal1"
4436 [(set (match_operand:SI 0 "register_operand" "=d")
4437 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
4438 (match_operand:SI 2 "arith_operand" "dI")))]
4441 if (GET_CODE (operands[2]) == CONST_INT)
4442 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4444 return "sra\t%0,%1,%2";
4446 [(set_attr "type" "shift")
4447 (set_attr "mode" "SI")])
4449 (define_insn "ashrsi3_internal2"
4450 [(set (match_operand:SI 0 "register_operand" "=d,d")
4451 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
4452 (match_operand:SI 2 "arith_operand" "d,I")))]
4455 if (which_alternative == 0)
4456 return "sra\t%0,%2";
4458 if (GET_CODE (operands[2]) == CONST_INT)
4459 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4461 return "sra\t%0,%1,%2";
4463 [(set_attr "type" "shift")
4464 (set_attr "mode" "SI")
4465 (set_attr_alternative "length"
4467 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4472 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4475 [(set (match_operand:SI 0 "register_operand")
4476 (ashiftrt:SI (match_operand:SI 1 "register_operand")
4477 (match_operand:SI 2 "const_int_operand")))]
4478 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4479 && GET_CODE (operands[2]) == CONST_INT
4480 && INTVAL (operands[2]) > 8
4481 && INTVAL (operands[2]) <= 16"
4482 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
4483 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
4484 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4486 (define_expand "ashrdi3"
4487 [(set (match_operand:DI 0 "register_operand")
4488 (ashiftrt:DI (match_operand:DI 1 "register_operand")
4489 (match_operand:SI 2 "arith_operand")))]
4492 /* On the mips16, a shift of more than 8 is a four byte
4493 instruction, so, for a shift between 8 and 16, it is just as
4494 fast to do two shifts of 8 or less. If there is a lot of
4495 shifting going on, we may win in CSE. Otherwise combine will
4496 put the shifts back together again. */
4499 && GET_CODE (operands[2]) == CONST_INT
4500 && INTVAL (operands[2]) > 8
4501 && INTVAL (operands[2]) <= 16)
4503 rtx temp = gen_reg_rtx (DImode);
4505 emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
4506 emit_insn (gen_ashrdi3_internal (operands[0], temp,
4507 GEN_INT (INTVAL (operands[2]) - 8)));
4513 (define_insn "ashrdi3_internal"
4514 [(set (match_operand:DI 0 "register_operand" "=d")
4515 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4516 (match_operand:SI 2 "arith_operand" "dI")))]
4517 "TARGET_64BIT && !TARGET_MIPS16"
4519 if (GET_CODE (operands[2]) == CONST_INT)
4520 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4522 return "dsra\t%0,%1,%2";
4524 [(set_attr "type" "shift")
4525 (set_attr "mode" "DI")])
4528 [(set (match_operand:DI 0 "register_operand" "=d,d")
4529 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4530 (match_operand:SI 2 "arith_operand" "d,I")))]
4531 "TARGET_64BIT && TARGET_MIPS16"
4533 if (GET_CODE (operands[2]) == CONST_INT)
4534 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4536 return "dsra\t%0,%2";
4538 [(set_attr "type" "shift")
4539 (set_attr "mode" "DI")
4540 (set_attr_alternative "length"
4542 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4546 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4549 [(set (match_operand:DI 0 "register_operand")
4550 (ashiftrt:DI (match_operand:DI 1 "register_operand")
4551 (match_operand:SI 2 "const_int_operand")))]
4552 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
4554 && GET_CODE (operands[2]) == CONST_INT
4555 && INTVAL (operands[2]) > 8
4556 && INTVAL (operands[2]) <= 16"
4557 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
4558 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
4559 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4561 (define_expand "lshrsi3"
4562 [(set (match_operand:SI 0 "register_operand")
4563 (lshiftrt:SI (match_operand:SI 1 "register_operand")
4564 (match_operand:SI 2 "arith_operand")))]
4567 /* On the mips16, a shift of more than 8 is a four byte instruction,
4568 so, for a shift between 8 and 16, it is just as fast to do two
4569 shifts of 8 or less. If there is a lot of shifting going on, we
4570 may win in CSE. Otherwise combine will put the shifts back
4574 && GET_CODE (operands[2]) == CONST_INT
4575 && INTVAL (operands[2]) > 8
4576 && INTVAL (operands[2]) <= 16)
4578 rtx temp = gen_reg_rtx (SImode);
4580 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
4581 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
4582 GEN_INT (INTVAL (operands[2]) - 8)));
4587 (define_insn "lshrsi3_internal1"
4588 [(set (match_operand:SI 0 "register_operand" "=d")
4589 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
4590 (match_operand:SI 2 "arith_operand" "dI")))]
4593 if (GET_CODE (operands[2]) == CONST_INT)
4594 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4596 return "srl\t%0,%1,%2";
4598 [(set_attr "type" "shift")
4599 (set_attr "mode" "SI")])
4601 (define_insn "lshrsi3_internal2"
4602 [(set (match_operand:SI 0 "register_operand" "=d,d")
4603 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
4604 (match_operand:SI 2 "arith_operand" "d,I")))]
4607 if (which_alternative == 0)
4608 return "srl\t%0,%2";
4610 if (GET_CODE (operands[2]) == CONST_INT)
4611 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4613 return "srl\t%0,%1,%2";
4615 [(set_attr "type" "shift")
4616 (set_attr "mode" "SI")
4617 (set_attr_alternative "length"
4619 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4624 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4627 [(set (match_operand:SI 0 "register_operand")
4628 (lshiftrt:SI (match_operand:SI 1 "register_operand")
4629 (match_operand:SI 2 "const_int_operand")))]
4630 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4631 && GET_CODE (operands[2]) == CONST_INT
4632 && INTVAL (operands[2]) > 8
4633 && INTVAL (operands[2]) <= 16"
4634 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
4635 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4636 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4638 ;; If we load a byte on the mips16 as a bitfield, the resulting
4639 ;; sequence of instructions is too complicated for combine, because it
4640 ;; involves four instructions: a load, a shift, a constant load into a
4641 ;; register, and an and (the key problem here is that the mips16 does
4642 ;; not have and immediate). We recognize a shift of a load in order
4643 ;; to make it simple enough for combine to understand.
4645 ;; The length here is the worst case: the length of the split version
4646 ;; will be more accurate.
4647 (define_insn_and_split ""
4648 [(set (match_operand:SI 0 "register_operand" "=d")
4649 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4650 (match_operand:SI 2 "immediate_operand" "I")))]
4654 [(set (match_dup 0) (match_dup 1))
4655 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4657 [(set_attr "type" "load")
4658 (set_attr "mode" "SI")
4659 (set_attr "length" "16")])
4661 (define_expand "lshrdi3"
4662 [(set (match_operand:DI 0 "register_operand")
4663 (lshiftrt:DI (match_operand:DI 1 "register_operand")
4664 (match_operand:SI 2 "arith_operand")))]
4667 /* On the mips16, a shift of more than 8 is a four byte
4668 instruction, so, for a shift between 8 and 16, it is just as
4669 fast to do two shifts of 8 or less. If there is a lot of
4670 shifting going on, we may win in CSE. Otherwise combine will
4671 put the shifts back together again. */
4674 && GET_CODE (operands[2]) == CONST_INT
4675 && INTVAL (operands[2]) > 8
4676 && INTVAL (operands[2]) <= 16)
4678 rtx temp = gen_reg_rtx (DImode);
4680 emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
4681 emit_insn (gen_lshrdi3_internal (operands[0], temp,
4682 GEN_INT (INTVAL (operands[2]) - 8)));
4688 (define_insn "lshrdi3_internal"
4689 [(set (match_operand:DI 0 "register_operand" "=d")
4690 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4691 (match_operand:SI 2 "arith_operand" "dI")))]
4692 "TARGET_64BIT && !TARGET_MIPS16"
4694 if (GET_CODE (operands[2]) == CONST_INT)
4695 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4697 return "dsrl\t%0,%1,%2";
4699 [(set_attr "type" "shift")
4700 (set_attr "mode" "DI")])
4703 [(set (match_operand:DI 0 "register_operand" "=d,d")
4704 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4705 (match_operand:SI 2 "arith_operand" "d,I")))]
4706 "TARGET_64BIT && TARGET_MIPS16"
4708 if (GET_CODE (operands[2]) == CONST_INT)
4709 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4711 return "dsrl\t%0,%2";
4713 [(set_attr "type" "shift")
4714 (set_attr "mode" "DI")
4715 (set_attr_alternative "length"
4717 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4721 (define_insn "rotrsi3"
4722 [(set (match_operand:SI 0 "register_operand" "=d")
4723 (rotatert:SI (match_operand:SI 1 "register_operand" "d")
4724 (match_operand:SI 2 "arith_operand" "dn")))]
4727 if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
4728 return "rorv\t%0,%1,%2";
4730 if ((GET_CODE (operands[2]) == CONST_INT)
4731 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
4734 return "ror\t%0,%1,%2";
4736 [(set_attr "type" "shift")
4737 (set_attr "mode" "SI")])
4739 (define_insn "rotrdi3"
4740 [(set (match_operand:DI 0 "register_operand" "=d")
4741 (rotatert:DI (match_operand:DI 1 "register_operand" "d")
4742 (match_operand:DI 2 "arith_operand" "dn")))]
4747 if (GET_CODE (operands[2]) != CONST_INT)
4748 return "drorv\t%0,%1,%2";
4750 if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
4751 return "dror32\t%0,%1,%2";
4754 if ((GET_CODE (operands[2]) == CONST_INT)
4755 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
4758 return "dror\t%0,%1,%2";
4760 [(set_attr "type" "shift")
4761 (set_attr "mode" "DI")])
4764 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4767 [(set (match_operand:DI 0 "register_operand")
4768 (lshiftrt:DI (match_operand:DI 1 "register_operand")
4769 (match_operand:SI 2 "const_int_operand")))]
4770 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4771 && GET_CODE (operands[2]) == CONST_INT
4772 && INTVAL (operands[2]) > 8
4773 && INTVAL (operands[2]) <= 16"
4774 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
4775 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
4776 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4779 ;; ....................
4783 ;; ....................
4785 ;; Flow here is rather complex:
4787 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the arguments
4788 ;; into cmp_operands[] but generates no RTL.
4790 ;; 2) The appropriate branch define_expand is called, which then
4791 ;; creates the appropriate RTL for the comparison and branch.
4792 ;; Different CC modes are used, based on what type of branch is
4793 ;; done, so that we can constrain things appropriately. There
4794 ;; are assumptions in the rest of GCC that break if we fold the
4795 ;; operands into the branches for integer operations, and use cc0
4796 ;; for floating point, so we use the fp status register instead.
4797 ;; If needed, an appropriate temporary is created to hold the
4798 ;; of the integer compare.
4800 (define_expand "cmpsi"
4802 (compare:CC (match_operand:SI 0 "register_operand")
4803 (match_operand:SI 1 "nonmemory_operand")))]
4806 cmp_operands[0] = operands[0];
4807 cmp_operands[1] = operands[1];
4811 (define_expand "cmpdi"
4813 (compare:CC (match_operand:DI 0 "register_operand")
4814 (match_operand:DI 1 "nonmemory_operand")))]
4817 cmp_operands[0] = operands[0];
4818 cmp_operands[1] = operands[1];
4822 (define_expand "cmpdf"
4824 (compare:CC (match_operand:DF 0 "register_operand")
4825 (match_operand:DF 1 "register_operand")))]
4826 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4828 cmp_operands[0] = operands[0];
4829 cmp_operands[1] = operands[1];
4833 (define_expand "cmpsf"
4835 (compare:CC (match_operand:SF 0 "register_operand")
4836 (match_operand:SF 1 "register_operand")))]
4839 cmp_operands[0] = operands[0];
4840 cmp_operands[1] = operands[1];
4845 ;; ....................
4847 ;; CONDITIONAL BRANCHES
4849 ;; ....................
4851 ;; Conditional branches on floating-point equality tests.
4853 (define_insn "branch_fp"
4856 (match_operator:CC 0 "comparison_operator"
4857 [(match_operand:CC 2 "register_operand" "z")
4859 (label_ref (match_operand 1 "" ""))
4863 return mips_output_conditional_branch (insn,
4865 /*two_operands_p=*/0,
4868 get_attr_length (insn));
4870 [(set_attr "type" "branch")
4871 (set_attr "mode" "none")])
4873 (define_insn "branch_fp_inverted"
4876 (match_operator:CC 0 "comparison_operator"
4877 [(match_operand:CC 2 "register_operand" "z")
4880 (label_ref (match_operand 1 "" ""))))]
4883 return mips_output_conditional_branch (insn,
4885 /*two_operands_p=*/0,
4888 get_attr_length (insn));
4890 [(set_attr "type" "branch")
4891 (set_attr "mode" "none")])
4893 ;; Conditional branches on comparisons with zero.
4895 (define_insn "branch_zero"
4898 (match_operator:SI 0 "comparison_operator"
4899 [(match_operand:SI 2 "register_operand" "d")
4901 (label_ref (match_operand 1 "" ""))
4905 return mips_output_conditional_branch (insn,
4907 /*two_operands_p=*/0,
4910 get_attr_length (insn));
4912 [(set_attr "type" "branch")
4913 (set_attr "mode" "none")])
4915 (define_insn "branch_zero_inverted"
4918 (match_operator:SI 0 "comparison_operator"
4919 [(match_operand:SI 2 "register_operand" "d")
4922 (label_ref (match_operand 1 "" ""))))]
4925 return mips_output_conditional_branch (insn,
4927 /*two_operands_p=*/0,
4930 get_attr_length (insn));
4932 [(set_attr "type" "branch")
4933 (set_attr "mode" "none")])
4935 (define_insn "branch_zero_di"
4938 (match_operator:DI 0 "comparison_operator"
4939 [(match_operand:DI 2 "register_operand" "d")
4941 (label_ref (match_operand 1 "" ""))
4945 return mips_output_conditional_branch (insn,
4947 /*two_operands_p=*/0,
4950 get_attr_length (insn));
4952 [(set_attr "type" "branch")
4953 (set_attr "mode" "none")])
4955 (define_insn "branch_zero_di_inverted"
4958 (match_operator:DI 0 "comparison_operator"
4959 [(match_operand:DI 2 "register_operand" "d")
4962 (label_ref (match_operand 1 "" ""))))]
4965 return mips_output_conditional_branch (insn,
4967 /*two_operands_p=*/0,
4970 get_attr_length (insn));
4972 [(set_attr "type" "branch")
4973 (set_attr "mode" "none")])
4975 ;; Conditional branch on equality comparison.
4977 (define_insn "branch_equality"
4980 (match_operator:SI 0 "equality_operator"
4981 [(match_operand:SI 2 "register_operand" "d")
4982 (match_operand:SI 3 "register_operand" "d")])
4983 (label_ref (match_operand 1 "" ""))
4987 return mips_output_conditional_branch (insn,
4989 /*two_operands_p=*/1,
4992 get_attr_length (insn));
4994 [(set_attr "type" "branch")
4995 (set_attr "mode" "none")])
4997 (define_insn "branch_equality_di"
5000 (match_operator:DI 0 "equality_operator"
5001 [(match_operand:DI 2 "register_operand" "d")
5002 (match_operand:DI 3 "register_operand" "d")])
5003 (label_ref (match_operand 1 "" ""))
5007 return mips_output_conditional_branch (insn,
5009 /*two_operands_p=*/1,
5012 get_attr_length (insn));
5014 [(set_attr "type" "branch")
5015 (set_attr "mode" "none")])
5017 (define_insn "branch_equality_inverted"
5020 (match_operator:SI 0 "equality_operator"
5021 [(match_operand:SI 2 "register_operand" "d")
5022 (match_operand:SI 3 "register_operand" "d")])
5024 (label_ref (match_operand 1 "" ""))))]
5027 return mips_output_conditional_branch (insn,
5029 /*two_operands_p=*/1,
5032 get_attr_length (insn));
5034 [(set_attr "type" "branch")
5035 (set_attr "mode" "none")])
5037 (define_insn "branch_equality_di_inverted"
5040 (match_operator:DI 0 "equality_operator"
5041 [(match_operand:DI 2 "register_operand" "d")
5042 (match_operand:DI 3 "register_operand" "d")])
5044 (label_ref (match_operand 1 "" ""))))]
5047 return mips_output_conditional_branch (insn,
5049 /*two_operands_p=*/1,
5052 get_attr_length (insn));
5054 [(set_attr "type" "branch")
5055 (set_attr "mode" "none")])
5062 (match_operator:SI 0 "equality_operator"
5063 [(match_operand:SI 1 "register_operand" "d,t")
5065 (match_operand 2 "pc_or_label_operand" "")
5066 (match_operand 3 "pc_or_label_operand" "")))]
5069 if (operands[2] != pc_rtx)
5071 if (which_alternative == 0)
5072 return "b%C0z\t%1,%2";
5074 return "bt%C0z\t%2";
5078 if (which_alternative == 0)
5079 return "b%N0z\t%1,%3";
5081 return "bt%N0z\t%3";
5084 [(set_attr "type" "branch")
5085 (set_attr "mode" "none")
5086 (set_attr "length" "8")])
5091 (match_operator:DI 0 "equality_operator"
5092 [(match_operand:DI 1 "register_operand" "d,t")
5094 (match_operand 2 "pc_or_label_operand" "")
5095 (match_operand 3 "pc_or_label_operand" "")))]
5098 if (operands[2] != pc_rtx)
5100 if (which_alternative == 0)
5101 return "b%C0z\t%1,%2";
5103 return "bt%C0z\t%2";
5107 if (which_alternative == 0)
5108 return "b%N0z\t%1,%3";
5110 return "bt%N0z\t%3";
5113 [(set_attr "type" "branch")
5114 (set_attr "mode" "none")
5115 (set_attr "length" "8")])
5117 (define_expand "b<code>"
5119 (if_then_else (any_cond:CC (cc0)
5121 (label_ref (match_operand 0 ""))
5125 gen_conditional_branch (operands, <CODE>);
5130 ;; ....................
5132 ;; SETTING A REGISTER FROM A COMPARISON
5134 ;; ....................
5136 (define_expand "seq"
5137 [(set (match_operand:SI 0 "register_operand")
5138 (eq:SI (match_dup 1)
5141 { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
5143 (define_insn "*seq_si"
5144 [(set (match_operand:SI 0 "register_operand" "=d")
5145 (eq:SI (match_operand:SI 1 "register_operand" "d")
5149 [(set_attr "type" "slt")
5150 (set_attr "mode" "SI")])
5152 (define_insn "*seq_si_mips16"
5153 [(set (match_operand:SI 0 "register_operand" "=t")
5154 (eq:SI (match_operand:SI 1 "register_operand" "d")
5158 [(set_attr "type" "slt")
5159 (set_attr "mode" "SI")])
5161 (define_insn "*seq_di"
5162 [(set (match_operand:DI 0 "register_operand" "=d")
5163 (eq:DI (match_operand:DI 1 "register_operand" "d")
5165 "TARGET_64BIT && !TARGET_MIPS16"
5167 [(set_attr "type" "slt")
5168 (set_attr "mode" "DI")])
5170 (define_insn "*seq_di_mips16"
5171 [(set (match_operand:DI 0 "register_operand" "=t")
5172 (eq:DI (match_operand:DI 1 "register_operand" "d")
5174 "TARGET_64BIT && TARGET_MIPS16"
5176 [(set_attr "type" "slt")
5177 (set_attr "mode" "DI")])
5179 ;; "sne" uses sltu instructions in which the first operand is $0.
5180 ;; This isn't possible in mips16 code.
5182 (define_expand "sne"
5183 [(set (match_operand:SI 0 "register_operand")
5184 (ne:SI (match_dup 1)
5187 { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
5189 (define_insn "*sne_si"
5190 [(set (match_operand:SI 0 "register_operand" "=d")
5191 (ne:SI (match_operand:SI 1 "register_operand" "d")
5195 [(set_attr "type" "slt")
5196 (set_attr "mode" "SI")])
5198 (define_insn "*sne_di"
5199 [(set (match_operand:DI 0 "register_operand" "=d")
5200 (ne:DI (match_operand:DI 1 "register_operand" "d")
5202 "TARGET_64BIT && !TARGET_MIPS16"
5204 [(set_attr "type" "slt")
5205 (set_attr "mode" "DI")])
5207 (define_expand "sgt"
5208 [(set (match_operand:SI 0 "register_operand")
5209 (gt:SI (match_dup 1)
5212 { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
5214 (define_insn "*sgt_si"
5215 [(set (match_operand:SI 0 "register_operand" "=d")
5216 (gt:SI (match_operand:SI 1 "register_operand" "d")
5217 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
5220 [(set_attr "type" "slt")
5221 (set_attr "mode" "SI")])
5223 (define_insn "*sgt_si_mips16"
5224 [(set (match_operand:SI 0 "register_operand" "=t")
5225 (gt:SI (match_operand:SI 1 "register_operand" "d")
5226 (match_operand:SI 2 "register_operand" "d")))]
5229 [(set_attr "type" "slt")
5230 (set_attr "mode" "SI")])
5232 (define_insn "*sgt_di"
5233 [(set (match_operand:DI 0 "register_operand" "=d")
5234 (gt:DI (match_operand:DI 1 "register_operand" "d")
5235 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
5236 "TARGET_64BIT && !TARGET_MIPS16"
5238 [(set_attr "type" "slt")
5239 (set_attr "mode" "DI")])
5241 (define_insn "*sgt_di_mips16"
5242 [(set (match_operand:DI 0 "register_operand" "=t")
5243 (gt:DI (match_operand:DI 1 "register_operand" "d")
5244 (match_operand:DI 2 "register_operand" "d")))]
5245 "TARGET_64BIT && TARGET_MIPS16"
5247 [(set_attr "type" "slt")
5248 (set_attr "mode" "DI")])
5250 (define_expand "sge"
5251 [(set (match_operand:SI 0 "register_operand")
5252 (ge:SI (match_dup 1)
5255 { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
5257 (define_insn "*sge_si"
5258 [(set (match_operand:SI 0 "register_operand" "=d")
5259 (ge:SI (match_operand:SI 1 "register_operand" "d")
5263 [(set_attr "type" "slt")
5264 (set_attr "mode" "SI")])
5266 (define_insn "*sge_di"
5267 [(set (match_operand:DI 0 "register_operand" "=d")
5268 (ge:DI (match_operand:DI 1 "register_operand" "d")
5270 "TARGET_64BIT && !TARGET_MIPS16"
5272 [(set_attr "type" "slt")
5273 (set_attr "mode" "DI")])
5275 (define_expand "slt"
5276 [(set (match_operand:SI 0 "register_operand")
5277 (lt:SI (match_dup 1)
5280 { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
5282 (define_insn "*slt_si"
5283 [(set (match_operand:SI 0 "register_operand" "=d")
5284 (lt:SI (match_operand:SI 1 "register_operand" "d")
5285 (match_operand:SI 2 "arith_operand" "dI")))]
5288 [(set_attr "type" "slt")
5289 (set_attr "mode" "SI")])
5291 (define_insn "*slt_si_mips16"
5292 [(set (match_operand:SI 0 "register_operand" "=t,t")
5293 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
5294 (match_operand:SI 2 "arith_operand" "d,I")))]
5297 [(set_attr "type" "slt")
5298 (set_attr "mode" "SI")
5299 (set_attr_alternative "length"
5301 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
5305 (define_insn "*slt_di"
5306 [(set (match_operand:DI 0 "register_operand" "=d")
5307 (lt:DI (match_operand:DI 1 "register_operand" "d")
5308 (match_operand:DI 2 "arith_operand" "dI")))]
5309 "TARGET_64BIT && !TARGET_MIPS16"
5311 [(set_attr "type" "slt")
5312 (set_attr "mode" "DI")])
5314 (define_insn "*slt_di_mips16"
5315 [(set (match_operand:DI 0 "register_operand" "=t,t")
5316 (lt:DI (match_operand:DI 1 "register_operand" "d,d")
5317 (match_operand:DI 2 "arith_operand" "d,I")))]
5318 "TARGET_64BIT && TARGET_MIPS16"
5320 [(set_attr "type" "slt")
5321 (set_attr "mode" "DI")
5322 (set_attr_alternative "length"
5324 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
5328 (define_expand "sle"
5329 [(set (match_operand:SI 0 "register_operand")
5330 (le:SI (match_dup 1)
5333 { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
5335 (define_insn "*sle_si"
5336 [(set (match_operand:SI 0 "register_operand" "=d")
5337 (le:SI (match_operand:SI 1 "register_operand" "d")
5338 (match_operand:SI 2 "sle_operand" "")))]
5341 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5342 return "slt\t%0,%1,%2";
5344 [(set_attr "type" "slt")
5345 (set_attr "mode" "SI")])
5347 (define_insn "*sle_si_mips16"
5348 [(set (match_operand:SI 0 "register_operand" "=t")
5349 (le:SI (match_operand:SI 1 "register_operand" "d")
5350 (match_operand:SI 2 "sle_operand" "")))]
5353 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5354 return "slt\t%1,%2";
5356 [(set_attr "type" "slt")
5357 (set_attr "mode" "SI")
5358 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
5362 (define_insn "*sle_di"
5363 [(set (match_operand:DI 0 "register_operand" "=d")
5364 (le:DI (match_operand:DI 1 "register_operand" "d")
5365 (match_operand:DI 2 "sle_operand" "")))]
5366 "TARGET_64BIT && !TARGET_MIPS16"
5368 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5369 return "slt\t%0,%1,%2";
5371 [(set_attr "type" "slt")
5372 (set_attr "mode" "DI")])
5374 (define_insn "*sle_di_mips16"
5375 [(set (match_operand:DI 0 "register_operand" "=t")
5376 (le:DI (match_operand:DI 1 "register_operand" "d")
5377 (match_operand:DI 2 "sle_operand" "")))]
5378 "TARGET_64BIT && TARGET_MIPS16"
5380 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5381 return "slt\t%1,%2";
5383 [(set_attr "type" "slt")
5384 (set_attr "mode" "DI")
5385 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
5389 (define_expand "sgtu"
5390 [(set (match_operand:SI 0 "register_operand")
5391 (gtu:SI (match_dup 1)
5394 { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
5396 (define_insn "*sgtu_si"
5397 [(set (match_operand:SI 0 "register_operand" "=d")
5398 (gtu:SI (match_operand:SI 1 "register_operand" "d")
5399 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
5402 [(set_attr "type" "slt")
5403 (set_attr "mode" "SI")])
5405 (define_insn "*sgtu_si_mips16"
5406 [(set (match_operand:SI 0 "register_operand" "=t")
5407 (gtu:SI (match_operand:SI 1 "register_operand" "d")
5408 (match_operand:SI 2 "register_operand" "d")))]
5411 [(set_attr "type" "slt")
5412 (set_attr "mode" "SI")])
5414 (define_insn "*sgtu_di"
5415 [(set (match_operand:DI 0 "register_operand" "=d")
5416 (gtu:DI (match_operand:DI 1 "register_operand" "d")
5417 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
5418 "TARGET_64BIT && !TARGET_MIPS16"
5420 [(set_attr "type" "slt")
5421 (set_attr "mode" "DI")])
5423 (define_insn "*sgtu_di_mips16"
5424 [(set (match_operand:DI 0 "register_operand" "=t")
5425 (gtu:DI (match_operand:DI 1 "register_operand" "d")
5426 (match_operand:DI 2 "register_operand" "d")))]
5427 "TARGET_64BIT && TARGET_MIPS16"
5429 [(set_attr "type" "slt")
5430 (set_attr "mode" "DI")])
5432 (define_expand "sgeu"
5433 [(set (match_operand:SI 0 "register_operand")
5434 (geu:SI (match_dup 1)
5437 { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
5439 (define_insn "*sge_si"
5440 [(set (match_operand:SI 0 "register_operand" "=d")
5441 (geu:SI (match_operand:SI 1 "register_operand" "d")
5445 [(set_attr "type" "slt")
5446 (set_attr "mode" "SI")])
5448 (define_insn "*sge_di"
5449 [(set (match_operand:DI 0 "register_operand" "=d")
5450 (geu:DI (match_operand:DI 1 "register_operand" "d")
5452 "TARGET_64BIT && !TARGET_MIPS16"
5454 [(set_attr "type" "slt")
5455 (set_attr "mode" "DI")])
5457 (define_expand "sltu"
5458 [(set (match_operand:SI 0 "register_operand")
5459 (ltu:SI (match_dup 1)
5462 { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
5464 (define_insn "*sltu_si"
5465 [(set (match_operand:SI 0 "register_operand" "=d")
5466 (ltu:SI (match_operand:SI 1 "register_operand" "d")
5467 (match_operand:SI 2 "arith_operand" "dI")))]
5470 [(set_attr "type" "slt")
5471 (set_attr "mode" "SI")])
5473 (define_insn "*sltu_si_mips16"
5474 [(set (match_operand:SI 0 "register_operand" "=t,t")
5475 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
5476 (match_operand:SI 2 "arith_operand" "d,I")))]
5479 [(set_attr "type" "slt")
5480 (set_attr "mode" "SI")
5481 (set_attr_alternative "length"
5483 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
5487 (define_insn "*sltu_di"
5488 [(set (match_operand:DI 0 "register_operand" "=d")
5489 (ltu:DI (match_operand:DI 1 "register_operand" "d")
5490 (match_operand:DI 2 "arith_operand" "dI")))]
5491 "TARGET_64BIT && !TARGET_MIPS16"
5493 [(set_attr "type" "slt")
5494 (set_attr "mode" "DI")])
5496 (define_insn "*sltu_di_mips16"
5497 [(set (match_operand:DI 0 "register_operand" "=t,t")
5498 (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
5499 (match_operand:DI 2 "arith_operand" "d,I")))]
5500 "TARGET_64BIT && TARGET_MIPS16"
5502 [(set_attr "type" "slt")
5503 (set_attr "mode" "DI")
5504 (set_attr_alternative "length"
5506 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
5510 (define_expand "sleu"
5511 [(set (match_operand:SI 0 "register_operand")
5512 (leu:SI (match_dup 1)
5515 { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
5517 (define_insn "*sleu_si"
5518 [(set (match_operand:SI 0 "register_operand" "=d")
5519 (leu:SI (match_operand:SI 1 "register_operand" "d")
5520 (match_operand:SI 2 "sleu_operand" "")))]
5523 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5524 return "sltu\t%0,%1,%2";
5526 [(set_attr "type" "slt")
5527 (set_attr "mode" "SI")])
5529 (define_insn "*sleu_si_mips16"
5530 [(set (match_operand:SI 0 "register_operand" "=t")
5531 (leu:SI (match_operand:SI 1 "register_operand" "d")
5532 (match_operand:SI 2 "sleu_operand" "")))]
5535 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5536 return "sltu\t%1,%2";
5538 [(set_attr "type" "slt")
5539 (set_attr "mode" "SI")
5540 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
5544 (define_insn "*sleu_di"
5545 [(set (match_operand:DI 0 "register_operand" "=d")
5546 (leu:DI (match_operand:DI 1 "register_operand" "d")
5547 (match_operand:DI 2 "sleu_operand" "")))]
5548 "TARGET_64BIT && !TARGET_MIPS16"
5550 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5551 return "sltu\t%0,%1,%2";
5553 [(set_attr "type" "slt")
5554 (set_attr "mode" "DI")])
5556 (define_insn "*sleu_di_mips16"
5557 [(set (match_operand:DI 0 "register_operand" "=t")
5558 (leu:DI (match_operand:DI 1 "register_operand" "d")
5559 (match_operand:DI 2 "sleu_operand" "")))]
5560 "TARGET_64BIT && TARGET_MIPS16"
5562 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5563 return "sltu\t%1,%2";
5565 [(set_attr "type" "slt")
5566 (set_attr "mode" "DI")
5567 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
5572 ;; ....................
5574 ;; FLOATING POINT COMPARISONS
5576 ;; ....................
5578 (define_insn "sunordered_df"
5579 [(set (match_operand:CC 0 "register_operand" "=z")
5580 (unordered:CC (match_operand:DF 1 "register_operand" "f")
5581 (match_operand:DF 2 "register_operand" "f")))]
5582 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5584 [(set_attr "type" "fcmp")
5585 (set_attr "mode" "FPSW")])
5587 (define_insn "sunlt_df"
5588 [(set (match_operand:CC 0 "register_operand" "=z")
5589 (unlt:CC (match_operand:DF 1 "register_operand" "f")
5590 (match_operand:DF 2 "register_operand" "f")))]
5591 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5593 [(set_attr "type" "fcmp")
5594 (set_attr "mode" "FPSW")])
5596 (define_insn "suneq_df"
5597 [(set (match_operand:CC 0 "register_operand" "=z")
5598 (uneq:CC (match_operand:DF 1 "register_operand" "f")
5599 (match_operand:DF 2 "register_operand" "f")))]
5600 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5602 [(set_attr "type" "fcmp")
5603 (set_attr "mode" "FPSW")])
5605 (define_insn "sunle_df"
5606 [(set (match_operand:CC 0 "register_operand" "=z")
5607 (unle:CC (match_operand:DF 1 "register_operand" "f")
5608 (match_operand:DF 2 "register_operand" "f")))]
5609 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5611 [(set_attr "type" "fcmp")
5612 (set_attr "mode" "FPSW")])
5614 (define_insn "seq_df"
5615 [(set (match_operand:CC 0 "register_operand" "=z")
5616 (eq:CC (match_operand:DF 1 "register_operand" "f")
5617 (match_operand:DF 2 "register_operand" "f")))]
5618 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5620 [(set_attr "type" "fcmp")
5621 (set_attr "mode" "FPSW")])
5623 (define_insn "slt_df"
5624 [(set (match_operand:CC 0 "register_operand" "=z")
5625 (lt:CC (match_operand:DF 1 "register_operand" "f")
5626 (match_operand:DF 2 "register_operand" "f")))]
5627 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5629 [(set_attr "type" "fcmp")
5630 (set_attr "mode" "FPSW")])
5632 (define_insn "sle_df"
5633 [(set (match_operand:CC 0 "register_operand" "=z")
5634 (le:CC (match_operand:DF 1 "register_operand" "f")
5635 (match_operand:DF 2 "register_operand" "f")))]
5636 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5638 [(set_attr "type" "fcmp")
5639 (set_attr "mode" "FPSW")])
5641 (define_insn "sgt_df"
5642 [(set (match_operand:CC 0 "register_operand" "=z")
5643 (gt:CC (match_operand:DF 1 "register_operand" "f")
5644 (match_operand:DF 2 "register_operand" "f")))]
5645 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5647 [(set_attr "type" "fcmp")
5648 (set_attr "mode" "FPSW")])
5650 (define_insn "sge_df"
5651 [(set (match_operand:CC 0 "register_operand" "=z")
5652 (ge:CC (match_operand:DF 1 "register_operand" "f")
5653 (match_operand:DF 2 "register_operand" "f")))]
5654 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5656 [(set_attr "type" "fcmp")
5657 (set_attr "mode" "FPSW")])
5659 (define_insn "sunordered_sf"
5660 [(set (match_operand:CC 0 "register_operand" "=z")
5661 (unordered:CC (match_operand:SF 1 "register_operand" "f")
5662 (match_operand:SF 2 "register_operand" "f")))]
5665 [(set_attr "type" "fcmp")
5666 (set_attr "mode" "FPSW")])
5668 (define_insn "sunlt_sf"
5669 [(set (match_operand:CC 0 "register_operand" "=z")
5670 (unlt:CC (match_operand:SF 1 "register_operand" "f")
5671 (match_operand:SF 2 "register_operand" "f")))]
5674 [(set_attr "type" "fcmp")
5675 (set_attr "mode" "FPSW")])
5677 (define_insn "suneq_sf"
5678 [(set (match_operand:CC 0 "register_operand" "=z")
5679 (uneq:CC (match_operand:SF 1 "register_operand" "f")
5680 (match_operand:SF 2 "register_operand" "f")))]
5683 [(set_attr "type" "fcmp")
5684 (set_attr "mode" "FPSW")])
5686 (define_insn "sunle_sf"
5687 [(set (match_operand:CC 0 "register_operand" "=z")
5688 (unle:CC (match_operand:SF 1 "register_operand" "f")
5689 (match_operand:SF 2 "register_operand" "f")))]
5692 [(set_attr "type" "fcmp")
5693 (set_attr "mode" "FPSW")])
5695 (define_insn "seq_sf"
5696 [(set (match_operand:CC 0 "register_operand" "=z")
5697 (eq:CC (match_operand:SF 1 "register_operand" "f")
5698 (match_operand:SF 2 "register_operand" "f")))]
5701 [(set_attr "type" "fcmp")
5702 (set_attr "mode" "FPSW")])
5704 (define_insn "slt_sf"
5705 [(set (match_operand:CC 0 "register_operand" "=z")
5706 (lt:CC (match_operand:SF 1 "register_operand" "f")
5707 (match_operand:SF 2 "register_operand" "f")))]
5710 [(set_attr "type" "fcmp")
5711 (set_attr "mode" "FPSW")])
5713 (define_insn "sle_sf"
5714 [(set (match_operand:CC 0 "register_operand" "=z")
5715 (le:CC (match_operand:SF 1 "register_operand" "f")
5716 (match_operand:SF 2 "register_operand" "f")))]
5719 [(set_attr "type" "fcmp")
5720 (set_attr "mode" "FPSW")])
5722 (define_insn "sgt_sf"
5723 [(set (match_operand:CC 0 "register_operand" "=z")
5724 (gt:CC (match_operand:SF 1 "register_operand" "f")
5725 (match_operand:SF 2 "register_operand" "f")))]
5728 [(set_attr "type" "fcmp")
5729 (set_attr "mode" "FPSW")])
5731 (define_insn "sge_sf"
5732 [(set (match_operand:CC 0 "register_operand" "=z")
5733 (ge:CC (match_operand:SF 1 "register_operand" "f")
5734 (match_operand:SF 2 "register_operand" "f")))]
5737 [(set_attr "type" "fcmp")
5738 (set_attr "mode" "FPSW")])
5741 ;; ....................
5743 ;; UNCONDITIONAL BRANCHES
5745 ;; ....................
5747 ;; Unconditional branches.
5751 (label_ref (match_operand 0 "" "")))]
5756 if (get_attr_length (insn) <= 8)
5757 return "%*b\t%l0%/";
5760 output_asm_insn (mips_output_load_label (), operands);
5761 return "%*jr\t%@%/%]";
5765 return "%*j\t%l0%/";
5767 [(set_attr "type" "jump")
5768 (set_attr "mode" "none")
5769 (set (attr "length")
5770 ;; We can't use `j' when emitting PIC. Emit a branch if it's
5771 ;; in range, otherwise load the address of the branch target into
5772 ;; $at and then jump to it.
5774 (ior (eq (symbol_ref "flag_pic") (const_int 0))
5775 (lt (abs (minus (match_dup 0)
5776 (plus (pc) (const_int 4))))
5777 (const_int 131072)))
5778 (const_int 4) (const_int 16)))])
5780 ;; We need a different insn for the mips16, because a mips16 branch
5781 ;; does not have a delay slot.
5785 (label_ref (match_operand 0 "" "")))]
5788 [(set_attr "type" "branch")
5789 (set_attr "mode" "none")
5790 (set_attr "length" "8")])
5792 (define_expand "indirect_jump"
5793 [(set (pc) (match_operand 0 "register_operand"))]
5799 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
5800 operands[0] = copy_to_mode_reg (Pmode, dest);
5802 if (!(Pmode == DImode))
5803 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
5805 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
5810 (define_insn "indirect_jump_internal1"
5811 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
5812 "!(Pmode == DImode)"
5814 [(set_attr "type" "jump")
5815 (set_attr "mode" "none")])
5817 (define_insn "indirect_jump_internal2"
5818 [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
5821 [(set_attr "type" "jump")
5822 (set_attr "mode" "none")])
5824 (define_expand "tablejump"
5826 (match_operand 0 "register_operand"))
5827 (use (label_ref (match_operand 1 "")))]
5832 if (GET_MODE (operands[0]) != HImode)
5834 if (!(Pmode == DImode))
5835 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
5837 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
5841 if (GET_MODE (operands[0]) != ptr_mode)
5845 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
5846 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
5848 if (Pmode == SImode)
5849 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
5851 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
5855 (define_insn "tablejump_internal1"
5857 (match_operand:SI 0 "register_operand" "d"))
5858 (use (label_ref (match_operand 1 "" "")))]
5861 [(set_attr "type" "jump")
5862 (set_attr "mode" "none")])
5864 (define_insn "tablejump_internal2"
5866 (match_operand:DI 0 "register_operand" "d"))
5867 (use (label_ref (match_operand 1 "" "")))]
5870 [(set_attr "type" "jump")
5871 (set_attr "mode" "none")])
5873 (define_expand "tablejump_mips161"
5874 [(set (pc) (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand"))
5875 (label_ref:SI (match_operand 1 ""))))]
5876 "TARGET_MIPS16 && !(Pmode == DImode)"
5880 t1 = gen_reg_rtx (SImode);
5881 t2 = gen_reg_rtx (SImode);
5882 t3 = gen_reg_rtx (SImode);
5883 emit_insn (gen_extendhisi2 (t1, operands[0]));
5884 emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
5885 emit_insn (gen_addsi3 (t3, t1, t2));
5886 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
5890 (define_expand "tablejump_mips162"
5891 [(set (pc) (plus:DI (sign_extend:DI (match_operand:HI 0 "register_operand"))
5892 (label_ref:DI (match_operand 1 ""))))]
5893 "TARGET_MIPS16 && Pmode == DImode"
5897 t1 = gen_reg_rtx (DImode);
5898 t2 = gen_reg_rtx (DImode);
5899 t3 = gen_reg_rtx (DImode);
5900 emit_insn (gen_extendhidi2 (t1, operands[0]));
5901 emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
5902 emit_insn (gen_adddi3 (t3, t1, t2));
5903 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
5907 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
5908 ;; While it is possible to either pull it off the stack (in the
5909 ;; o32 case) or recalculate it given t9 and our target label,
5910 ;; it takes 3 or 4 insns to do so.
5912 (define_expand "builtin_setjmp_setup"
5913 [(use (match_operand 0 "register_operand"))]
5918 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
5919 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
5923 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
5924 ;; that older code did recalculate the gp from $25. Continue to jump through
5925 ;; $25 for compatibility (we lose nothing by doing so).
5927 (define_expand "builtin_longjmp"
5928 [(use (match_operand 0 "register_operand"))]
5931 /* The elements of the buffer are, in order: */
5932 int W = GET_MODE_SIZE (Pmode);
5933 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5934 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
5935 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
5936 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
5937 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
5938 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
5939 The target is bound to be using $28 as the global pointer
5940 but the current function might not be. */
5941 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
5943 /* This bit is similar to expand_builtin_longjmp except that it
5944 restores $gp as well. */
5945 emit_move_insn (hard_frame_pointer_rtx, fp);
5946 emit_move_insn (pv, lab);
5947 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5948 emit_move_insn (gp, gpv);
5949 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5950 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5951 emit_insn (gen_rtx_USE (VOIDmode, gp));
5952 emit_indirect_jump (pv);
5957 ;; ....................
5959 ;; Function prologue/epilogue
5961 ;; ....................
5964 (define_expand "prologue"
5968 mips_expand_prologue ();
5972 ;; Block any insns from being moved before this point, since the
5973 ;; profiling call to mcount can use various registers that aren't
5974 ;; saved or used to pass arguments.
5976 (define_insn "blockage"
5977 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
5980 [(set_attr "type" "unknown")
5981 (set_attr "mode" "none")
5982 (set_attr "length" "0")])
5984 (define_expand "epilogue"
5988 mips_expand_epilogue (false);
5992 (define_expand "sibcall_epilogue"
5996 mips_expand_epilogue (true);
6000 ;; Trivial return. Make it look like a normal return insn as that
6001 ;; allows jump optimizations to work better.
6003 (define_insn "return"
6005 "mips_can_use_return_insn ()"
6007 [(set_attr "type" "jump")
6008 (set_attr "mode" "none")])
6012 (define_insn "return_internal"
6014 (use (match_operand 0 "pmode_register_operand" ""))]
6017 [(set_attr "type" "jump")
6018 (set_attr "mode" "none")])
6020 ;; This is used in compiling the unwind routines.
6021 (define_expand "eh_return"
6022 [(use (match_operand 0 "general_operand"))]
6025 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
6027 if (GET_MODE (operands[0]) != gpr_mode)
6028 operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
6030 emit_insn (gen_eh_set_lr_di (operands[0]));
6032 emit_insn (gen_eh_set_lr_si (operands[0]));
6037 ;; Clobber the return address on the stack. We can't expand this
6038 ;; until we know where it will be put in the stack frame.
6040 (define_insn "eh_set_lr_si"
6041 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6042 (clobber (match_scratch:SI 1 "=&d"))]
6046 (define_insn "eh_set_lr_di"
6047 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6048 (clobber (match_scratch:DI 1 "=&d"))]
6053 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6054 (clobber (match_scratch 1))]
6055 "reload_completed && !TARGET_DEBUG_D_MODE"
6058 mips_set_return_address (operands[0], operands[1]);
6062 (define_insn_and_split "exception_receiver"
6064 (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
6065 "TARGET_ABICALLS && TARGET_OLDABI"
6067 "&& reload_completed"
6073 [(set_attr "type" "load")
6074 (set_attr "length" "12")])
6077 ;; ....................
6081 ;; ....................
6083 ;; Instructions to load a call address from the GOT. The address might
6084 ;; point to a function or to a lazy binding stub. In the latter case,
6085 ;; the stub will use the dynamic linker to resolve the function, which
6086 ;; in turn will change the GOT entry to point to the function's real
6089 ;; This means that every call, even pure and constant ones, can
6090 ;; potentially modify the GOT entry. And once a stub has been called,
6091 ;; we must not call it again.
6093 ;; We represent this restriction using an imaginary fixed register that
6094 ;; acts like a GOT version number. By making the register call-clobbered,
6095 ;; we tell the target-independent code that the address could be changed
6096 ;; by any call insn.
6097 (define_insn "load_callsi"
6098 [(set (match_operand:SI 0 "register_operand" "=c")
6099 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6100 (match_operand:SI 2 "immediate_operand" "")
6101 (reg:SI FAKE_CALL_REGNO)]
6105 [(set_attr "type" "load")
6106 (set_attr "length" "4")])
6108 (define_insn "load_calldi"
6109 [(set (match_operand:DI 0 "register_operand" "=c")
6110 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
6111 (match_operand:DI 2 "immediate_operand" "")
6112 (reg:DI FAKE_CALL_REGNO)]
6116 [(set_attr "type" "load")
6117 (set_attr "length" "4")])
6119 ;; Sibling calls. All these patterns use jump instructions.
6121 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
6122 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
6123 ;; is defined in terms of call_insn_operand, the same is true of the
6126 ;; When we use an indirect jump, we need a register that will be
6127 ;; preserved by the epilogue. Since TARGET_ABICALLS forces us to
6128 ;; use $25 for this purpose -- and $25 is never clobbered by the
6129 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
6131 (define_expand "sibcall"
6132 [(parallel [(call (match_operand 0 "")
6133 (match_operand 1 ""))
6134 (use (match_operand 2 "")) ;; next_arg_reg
6135 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
6138 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
6142 (define_insn "sibcall_internal"
6143 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
6144 (match_operand 1 "" ""))]
6145 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6149 [(set_attr "type" "call")])
6151 (define_expand "sibcall_value"
6152 [(parallel [(set (match_operand 0 "")
6153 (call (match_operand 1 "")
6154 (match_operand 2 "")))
6155 (use (match_operand 3 ""))])] ;; next_arg_reg
6158 mips_expand_call (operands[0], XEXP (operands[1], 0),
6159 operands[2], operands[3], true);
6163 (define_insn "sibcall_value_internal"
6164 [(set (match_operand 0 "register_operand" "=df,df")
6165 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6166 (match_operand 2 "" "")))]
6167 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6171 [(set_attr "type" "call")])
6173 (define_insn "sibcall_value_multiple_internal"
6174 [(set (match_operand 0 "register_operand" "=df,df")
6175 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6176 (match_operand 2 "" "")))
6177 (set (match_operand 3 "register_operand" "=df,df")
6178 (call (mem:SI (match_dup 1))
6180 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6184 [(set_attr "type" "call")])
6186 (define_expand "call"
6187 [(parallel [(call (match_operand 0 "")
6188 (match_operand 1 ""))
6189 (use (match_operand 2 "")) ;; next_arg_reg
6190 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
6193 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
6197 ;; This instruction directly corresponds to an assembly-language "jal".
6198 ;; There are four cases:
6201 ;; Both symbolic and register destinations are OK. The pattern
6202 ;; always expands to a single mips instruction.
6204 ;; - -mabicalls/-mno-explicit-relocs:
6205 ;; Again, both symbolic and register destinations are OK.
6206 ;; The call is treated as a multi-instruction black box.
6208 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
6209 ;; Only "jal $25" is allowed. This expands to a single "jalr $25"
6212 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
6213 ;; Only "jal $25" is allowed. The call is actually two instructions:
6214 ;; "jalr $25" followed by an insn to reload $gp.
6216 ;; In the last case, we can generate the individual instructions with
6217 ;; a define_split. There are several things to be wary of:
6219 ;; - We can't expose the load of $gp before reload. If we did,
6220 ;; it might get removed as dead, but reload can introduce new
6221 ;; uses of $gp by rematerializing constants.
6223 ;; - We shouldn't restore $gp after calls that never return.
6224 ;; It isn't valid to insert instructions between a noreturn
6225 ;; call and the following barrier.
6227 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
6228 ;; instruction preserves $gp and so have no effect on its liveness.
6229 ;; But once we generate the separate insns, it becomes obvious that
6230 ;; $gp is not live on entry to the call.
6232 ;; ??? The operands[2] = insn check is a hack to make the original insn
6233 ;; available to the splitter.
6234 (define_insn_and_split "call_internal"
6235 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
6236 (match_operand 1 "" ""))
6237 (clobber (reg:SI 31))]
6239 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
6240 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
6243 emit_call_insn (gen_call_split (operands[0], operands[1]));
6244 if (!find_reg_note (operands[2], REG_NORETURN, 0))
6248 [(set_attr "jal" "indirect,direct")
6249 (set_attr "extended_mips16" "no,yes")])
6251 (define_insn "call_split"
6252 [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
6253 (match_operand 1 "" ""))
6254 (clobber (reg:SI 31))
6255 (clobber (reg:SI 28))]
6256 "TARGET_SPLIT_CALLS"
6258 [(set_attr "type" "call")])
6260 (define_expand "call_value"
6261 [(parallel [(set (match_operand 0 "")
6262 (call (match_operand 1 "")
6263 (match_operand 2 "")))
6264 (use (match_operand 3 ""))])] ;; next_arg_reg
6267 mips_expand_call (operands[0], XEXP (operands[1], 0),
6268 operands[2], operands[3], false);
6272 ;; See comment for call_internal.
6273 (define_insn_and_split "call_value_internal"
6274 [(set (match_operand 0 "register_operand" "=df,df")
6275 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6276 (match_operand 2 "" "")))
6277 (clobber (reg:SI 31))]
6279 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
6280 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
6283 emit_call_insn (gen_call_value_split (operands[0], operands[1],
6285 if (!find_reg_note (operands[3], REG_NORETURN, 0))
6289 [(set_attr "jal" "indirect,direct")
6290 (set_attr "extended_mips16" "no,yes")])
6292 (define_insn "call_value_split"
6293 [(set (match_operand 0 "register_operand" "=df")
6294 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
6295 (match_operand 2 "" "")))
6296 (clobber (reg:SI 31))
6297 (clobber (reg:SI 28))]
6298 "TARGET_SPLIT_CALLS"
6300 [(set_attr "type" "call")])
6302 ;; See comment for call_internal.
6303 (define_insn_and_split "call_value_multiple_internal"
6304 [(set (match_operand 0 "register_operand" "=df,df")
6305 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6306 (match_operand 2 "" "")))
6307 (set (match_operand 3 "register_operand" "=df,df")
6308 (call (mem:SI (match_dup 1))
6310 (clobber (reg:SI 31))]
6312 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
6313 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
6316 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
6317 operands[2], operands[3]));
6318 if (!find_reg_note (operands[4], REG_NORETURN, 0))
6322 [(set_attr "jal" "indirect,direct")
6323 (set_attr "extended_mips16" "no,yes")])
6325 (define_insn "call_value_multiple_split"
6326 [(set (match_operand 0 "register_operand" "=df")
6327 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
6328 (match_operand 2 "" "")))
6329 (set (match_operand 3 "register_operand" "=df")
6330 (call (mem:SI (match_dup 1))
6332 (clobber (reg:SI 31))
6333 (clobber (reg:SI 28))]
6334 "TARGET_SPLIT_CALLS"
6336 [(set_attr "type" "call")])
6338 ;; Call subroutine returning any type.
6340 (define_expand "untyped_call"
6341 [(parallel [(call (match_operand 0 "")
6343 (match_operand 1 "")
6344 (match_operand 2 "")])]
6349 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6351 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6353 rtx set = XVECEXP (operands[2], 0, i);
6354 emit_move_insn (SET_DEST (set), SET_SRC (set));
6357 emit_insn (gen_blockage ());
6362 ;; ....................
6366 ;; ....................
6370 (define_expand "prefetch"
6371 [(prefetch (match_operand 0 "address_operand")
6372 (match_operand 1 "const_int_operand")
6373 (match_operand 2 "const_int_operand"))]
6376 if (symbolic_operand (operands[0], GET_MODE (operands[0])))
6377 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
6380 (define_insn "prefetch_si_address"
6381 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
6382 (match_operand:SI 3 "const_int_operand" "I"))
6383 (match_operand:SI 1 "const_int_operand" "n")
6384 (match_operand:SI 2 "const_int_operand" "n"))]
6385 "ISA_HAS_PREFETCH && Pmode == SImode"
6386 { return mips_emit_prefetch (operands); }
6387 [(set_attr "type" "prefetch")])
6389 (define_insn "prefetch_indexed_si"
6390 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
6391 (match_operand:SI 3 "register_operand" "r"))
6392 (match_operand:SI 1 "const_int_operand" "n")
6393 (match_operand:SI 2 "const_int_operand" "n"))]
6394 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
6395 { return mips_emit_prefetch (operands); }
6396 [(set_attr "type" "prefetchx")])
6398 (define_insn "prefetch_si"
6399 [(prefetch (match_operand:SI 0 "register_operand" "r")
6400 (match_operand:SI 1 "const_int_operand" "n")
6401 (match_operand:SI 2 "const_int_operand" "n"))]
6402 "ISA_HAS_PREFETCH && Pmode == SImode"
6404 operands[3] = const0_rtx;
6405 return mips_emit_prefetch (operands);
6407 [(set_attr "type" "prefetch")])
6409 (define_insn "prefetch_di_address"
6410 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
6411 (match_operand:DI 3 "const_int_operand" "I"))
6412 (match_operand:DI 1 "const_int_operand" "n")
6413 (match_operand:DI 2 "const_int_operand" "n"))]
6414 "ISA_HAS_PREFETCH && Pmode == DImode"
6415 { return mips_emit_prefetch (operands); }
6416 [(set_attr "type" "prefetch")])
6418 (define_insn "prefetch_indexed_di"
6419 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
6420 (match_operand:DI 3 "register_operand" "r"))
6421 (match_operand:DI 1 "const_int_operand" "n")
6422 (match_operand:DI 2 "const_int_operand" "n"))]
6423 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
6424 { return mips_emit_prefetch (operands); }
6425 [(set_attr "type" "prefetchx")])
6427 (define_insn "prefetch_di"
6428 [(prefetch (match_operand:DI 0 "register_operand" "r")
6429 (match_operand:DI 1 "const_int_operand" "n")
6430 (match_operand:DI 2 "const_int_operand" "n"))]
6431 "ISA_HAS_PREFETCH && Pmode == DImode"
6433 operands[3] = const0_rtx;
6434 return mips_emit_prefetch (operands);
6436 [(set_attr "type" "prefetch")])
6442 [(set_attr "type" "nop")
6443 (set_attr "mode" "none")])
6445 ;; Like nop, but commented out when outside a .set noreorder block.
6446 (define_insn "hazard_nop"
6455 [(set_attr "type" "nop")])
6457 ;; MIPS4 Conditional move instructions.
6460 [(set (match_operand:SI 0 "register_operand" "=d,d")
6462 (match_operator:SI 4 "equality_operator"
6463 [(match_operand:SI 1 "register_operand" "d,d")
6465 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
6466 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
6467 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
6471 [(set_attr "type" "condmove")
6472 (set_attr "mode" "SI")])
6475 [(set (match_operand:SI 0 "register_operand" "=d,d")
6477 (match_operator:DI 4 "equality_operator"
6478 [(match_operand:DI 1 "register_operand" "d,d")
6480 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
6481 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
6482 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
6486 [(set_attr "type" "condmove")
6487 (set_attr "mode" "SI")])
6490 [(set (match_operand:SI 0 "register_operand" "=d,d")
6492 (match_operator:CC 3 "equality_operator"
6493 [(match_operand:CC 4 "register_operand" "z,z")
6495 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
6496 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
6497 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6501 [(set_attr "type" "condmove")
6502 (set_attr "mode" "SI")])
6505 [(set (match_operand:DI 0 "register_operand" "=d,d")
6507 (match_operator:SI 4 "equality_operator"
6508 [(match_operand:SI 1 "register_operand" "d,d")
6510 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
6511 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
6512 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
6516 [(set_attr "type" "condmove")
6517 (set_attr "mode" "DI")])
6520 [(set (match_operand:DI 0 "register_operand" "=d,d")
6522 (match_operator:DI 4 "equality_operator"
6523 [(match_operand:DI 1 "register_operand" "d,d")
6525 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
6526 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
6527 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
6531 [(set_attr "type" "condmove")
6532 (set_attr "mode" "DI")])
6535 [(set (match_operand:DI 0 "register_operand" "=d,d")
6537 (match_operator:CC 3 "equality_operator"
6538 [(match_operand:CC 4 "register_operand" "z,z")
6540 (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
6541 (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
6542 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
6546 [(set_attr "type" "condmove")
6547 (set_attr "mode" "DI")])
6550 [(set (match_operand:SF 0 "register_operand" "=f,f")
6552 (match_operator:SI 4 "equality_operator"
6553 [(match_operand:SI 1 "register_operand" "d,d")
6555 (match_operand:SF 2 "register_operand" "f,0")
6556 (match_operand:SF 3 "register_operand" "0,f")))]
6557 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6561 [(set_attr "type" "condmove")
6562 (set_attr "mode" "SF")])
6565 [(set (match_operand:SF 0 "register_operand" "=f,f")
6567 (match_operator:DI 4 "equality_operator"
6568 [(match_operand:DI 1 "register_operand" "d,d")
6570 (match_operand:SF 2 "register_operand" "f,0")
6571 (match_operand:SF 3 "register_operand" "0,f")))]
6572 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6576 [(set_attr "type" "condmove")
6577 (set_attr "mode" "SF")])
6580 [(set (match_operand:SF 0 "register_operand" "=f,f")
6582 (match_operator:CC 3 "equality_operator"
6583 [(match_operand:CC 4 "register_operand" "z,z")
6585 (match_operand:SF 1 "register_operand" "f,0")
6586 (match_operand:SF 2 "register_operand" "0,f")))]
6587 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6591 [(set_attr "type" "condmove")
6592 (set_attr "mode" "SF")])
6595 [(set (match_operand:DF 0 "register_operand" "=f,f")
6597 (match_operator:SI 4 "equality_operator"
6598 [(match_operand:SI 1 "register_operand" "d,d")
6600 (match_operand:DF 2 "register_operand" "f,0")
6601 (match_operand:DF 3 "register_operand" "0,f")))]
6602 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6606 [(set_attr "type" "condmove")
6607 (set_attr "mode" "DF")])
6610 [(set (match_operand:DF 0 "register_operand" "=f,f")
6612 (match_operator:DI 4 "equality_operator"
6613 [(match_operand:DI 1 "register_operand" "d,d")
6615 (match_operand:DF 2 "register_operand" "f,0")
6616 (match_operand:DF 3 "register_operand" "0,f")))]
6617 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6621 [(set_attr "type" "condmove")
6622 (set_attr "mode" "DF")])
6625 [(set (match_operand:DF 0 "register_operand" "=f,f")
6627 (match_operator:CC 3 "equality_operator"
6628 [(match_operand:CC 4 "register_operand" "z,z")
6630 (match_operand:DF 1 "register_operand" "f,0")
6631 (match_operand:DF 2 "register_operand" "0,f")))]
6632 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6636 [(set_attr "type" "condmove")
6637 (set_attr "mode" "DF")])
6639 ;; These are the main define_expand's used to make conditional moves.
6641 (define_expand "movsicc"
6642 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6643 (set (match_operand:SI 0 "register_operand")
6644 (if_then_else:SI (match_dup 5)
6645 (match_operand:SI 2 "reg_or_0_operand")
6646 (match_operand:SI 3 "reg_or_0_operand")))]
6647 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
6649 gen_conditional_move (operands);
6653 (define_expand "movdicc"
6654 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6655 (set (match_operand:DI 0 "register_operand")
6656 (if_then_else:DI (match_dup 5)
6657 (match_operand:DI 2 "reg_or_0_operand")
6658 (match_operand:DI 3 "reg_or_0_operand")))]
6659 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
6661 gen_conditional_move (operands);
6665 (define_expand "movsfcc"
6666 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6667 (set (match_operand:SF 0 "register_operand")
6668 (if_then_else:SF (match_dup 5)
6669 (match_operand:SF 2 "register_operand")
6670 (match_operand:SF 3 "register_operand")))]
6671 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6673 gen_conditional_move (operands);
6677 (define_expand "movdfcc"
6678 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6679 (set (match_operand:DF 0 "register_operand")
6680 (if_then_else:DF (match_dup 5)
6681 (match_operand:DF 2 "register_operand")
6682 (match_operand:DF 3 "register_operand")))]
6683 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6685 gen_conditional_move (operands);
6690 ;; ....................
6692 ;; mips16 inline constant tables
6694 ;; ....................
6697 (define_insn "consttable_int"
6698 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
6699 (match_operand 1 "const_int_operand" "")]
6700 UNSPEC_CONSTTABLE_INT)]
6703 assemble_integer (operands[0], INTVAL (operands[1]),
6704 BITS_PER_UNIT * INTVAL (operands[1]), 1);
6707 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
6709 (define_insn "consttable_float"
6710 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
6711 UNSPEC_CONSTTABLE_FLOAT)]
6716 if (GET_CODE (operands[0]) != CONST_DOUBLE)
6718 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
6719 assemble_real (d, GET_MODE (operands[0]),
6720 GET_MODE_BITSIZE (GET_MODE (operands[0])));
6723 [(set (attr "length")
6724 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
6726 (define_insn "align"
6727 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
6730 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
6733 [(match_operand 0 "small_data_pattern")]
6736 { operands[0] = mips_rewrite_small_data (operands[0]); })