1 ;; Mips.md Machine Description for MIPS based processors
2 ;; Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 ;; Contributed by A. Lichnewsky, lich@inria.inria.fr
5 ;; Changes by Michael Meissner, meissner@osf.org
6 ;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
7 ;; Brendan Eich, brendan@microunity.com.
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING. If not, write to
23 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
27 [(UNSPEC_LOAD_DF_LOW 0)
28 (UNSPEC_LOAD_DF_HIGH 1)
29 (UNSPEC_STORE_DF_HIGH 2)
33 (UNSPEC_EH_RECEIVER 6)
35 (UNSPEC_CONSTTABLE_INT 8)
36 (UNSPEC_CONSTTABLE_FLOAT 9)
53 (UNSPEC_ADDRESS_FIRST 100)
55 (FAKE_CALL_REGNO 79)])
57 (include "predicates.md")
59 ;; ....................
63 ;; ....................
65 (define_attr "got" "unset,xgot_high,load"
66 (const_string "unset"))
68 ;; For jal instructions, this attribute is DIRECT when the target address
69 ;; is symbolic and INDIRECT when it is a register.
70 (define_attr "jal" "unset,direct,indirect"
71 (const_string "unset"))
73 ;; This attribute is YES if the instruction is a jal macro (not a
74 ;; real jal instruction).
76 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
77 ;; restore $gp. Direct jals are also macros in NewABI PIC since they
78 ;; load the target address into $25.
79 (define_attr "jal_macro" "no,yes"
80 (cond [(eq_attr "jal" "direct")
81 (symbol_ref "TARGET_ABICALLS != 0")
82 (eq_attr "jal" "indirect")
83 (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
86 ;; Classification of each insn.
87 ;; branch conditional branch
88 ;; jump unconditional jump
89 ;; call unconditional call
90 ;; load load instruction(s)
91 ;; fpload floating point load
92 ;; fpidxload floating point indexed load
93 ;; store store instruction(s)
94 ;; fpstore floating point store
95 ;; fpidxstore floating point indexed store
96 ;; prefetch memory prefetch (register + offset)
97 ;; prefetchx memory indexed prefetch (register + register)
98 ;; condmove conditional moves
99 ;; xfer transfer to/from coprocessor
100 ;; mthilo transfer to hi/lo registers
101 ;; mfhilo transfer from hi/lo registers
102 ;; const load constant
103 ;; arith integer arithmetic and logical instructions
104 ;; shift integer shift instructions
105 ;; slt set less than instructions
106 ;; clz the clz and clo instructions
107 ;; trap trap if instructions
108 ;; imul integer multiply
109 ;; imadd integer multiply-add
110 ;; idiv integer divide
111 ;; fmove floating point register move
112 ;; fadd floating point add/subtract
113 ;; fmul floating point multiply
114 ;; fmadd floating point multiply-add
115 ;; fdiv floating point divide
116 ;; frdiv floating point reciprocal divide
117 ;; fabs floating point absolute value
118 ;; fneg floating point negation
119 ;; fcmp floating point compare
120 ;; fcvt floating point convert
121 ;; fsqrt floating point square root
122 ;; frsqrt floating point reciprocal square root
123 ;; multi multiword sequence (or user asm statements)
126 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,frdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
127 (cond [(eq_attr "jal" "!unset") (const_string "call")
128 (eq_attr "got" "load") (const_string "load")]
129 (const_string "unknown")))
131 ;; Main data type used by the insn
132 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
133 (const_string "unknown"))
135 ;; Is this an extended instruction in mips16 mode?
136 (define_attr "extended_mips16" "no,yes"
139 ;; Length of instruction in bytes.
140 (define_attr "length" ""
141 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
142 ;; If a branch is outside this range, we have a choice of two
143 ;; sequences. For PIC, an out-of-range branch like:
148 ;; becomes the equivalent of:
157 ;; where the load address can be up to three instructions long
160 ;; The non-PIC case is similar except that we use a direct
161 ;; jump instead of an la/jr pair. Since the target of this
162 ;; jump is an absolute 28-bit bit address (the other bits
163 ;; coming from the address of the delay slot) this form cannot
164 ;; cross a 256MB boundary. We could provide the option of
165 ;; using la/jr in this case too, but we do not do so at
168 ;; Note that this value does not account for the delay slot
169 ;; instruction, whose length is added separately. If the RTL
170 ;; pattern has no explicit delay slot, mips_adjust_insn_length
171 ;; will add the length of the implicit nop. The values for
172 ;; forward and backward branches will be different as well.
173 (eq_attr "type" "branch")
174 (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
175 (le (minus (pc) (match_dup 1)) (const_int 131068)))
177 (ne (symbol_ref "flag_pic") (const_int 0))
181 (eq_attr "got" "load")
183 (eq_attr "got" "xgot_high")
186 (eq_attr "type" "const")
187 (symbol_ref "mips_const_insns (operands[1]) * 4")
188 (eq_attr "type" "load,fpload,fpidxload")
189 (symbol_ref "mips_fetch_insns (operands[1]) * 4")
190 (eq_attr "type" "store,fpstore,fpidxstore")
191 (symbol_ref "mips_fetch_insns (operands[0]) * 4")
193 ;; In the worst case, a call macro will take 8 instructions:
195 ;; lui $25,%call_hi(FOO)
197 ;; lw $25,%call_lo(FOO)($25)
203 (eq_attr "jal_macro" "yes")
206 (and (eq_attr "extended_mips16" "yes")
207 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
210 ;; Various VR4120 errata require a nop to be inserted after a macc
211 ;; instruction. The assembler does this for us, so account for
212 ;; the worst-case length here.
213 (and (eq_attr "type" "imadd")
214 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
217 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
218 ;; the result of the second one is missed. The assembler should work
219 ;; around this by inserting a nop after the first dmult.
220 (and (eq_attr "type" "imul")
221 (and (eq_attr "mode" "DI")
222 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
225 (eq_attr "type" "idiv")
226 (symbol_ref "mips_idiv_insns () * 4")
229 ;; Attribute describing the processor. This attribute must match exactly
230 ;; with the processor_type enumeration in mips.h.
232 "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
233 (const (symbol_ref "mips_tune")))
235 ;; The type of hardware hazard associated with this instruction.
236 ;; DELAY means that the next instruction cannot read the result
237 ;; of this one. HILO means that the next two instructions cannot
238 ;; write to HI or LO.
239 (define_attr "hazard" "none,delay,hilo"
240 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
241 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
242 (const_string "delay")
244 (and (eq_attr "type" "xfer")
245 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
246 (const_string "delay")
248 (and (eq_attr "type" "fcmp")
249 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
250 (const_string "delay")
252 ;; The r4000 multiplication patterns include an mflo instruction.
253 (and (eq_attr "type" "imul")
254 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
255 (const_string "hilo")
257 (and (eq_attr "type" "mfhilo")
258 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
259 (const_string "hilo")]
260 (const_string "none")))
262 ;; Is it a single instruction?
263 (define_attr "single_insn" "no,yes"
264 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
266 ;; Can the instruction be put into a delay slot?
267 (define_attr "can_delay" "no,yes"
268 (if_then_else (and (eq_attr "type" "!branch,call,jump")
269 (and (eq_attr "hazard" "none")
270 (eq_attr "single_insn" "yes")))
272 (const_string "no")))
274 ;; Attribute defining whether or not we can use the branch-likely instructions
275 (define_attr "branch_likely" "no,yes"
277 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
279 (const_string "no"))))
281 ;; True if an instruction might assign to hi or lo when reloaded.
282 ;; This is used by the TUNE_MACC_CHAINS code.
283 (define_attr "may_clobber_hilo" "no,yes"
284 (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
286 (const_string "no")))
288 ;; Describe a user's asm statement.
289 (define_asm_attributes
290 [(set_attr "type" "multi")])
292 ;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
293 ;; from the same template.
294 (define_mode_macro GPR [SI (DI "TARGET_64BIT")])
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 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
301 ;; are different. Some forms of unextended addiu have an 8-bit immediate
302 ;; field but the equivalent daddiu has only a 5-bit field.
303 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
305 ;; This code macro allows all branch instructions to be generated from
306 ;; a single define_expand template.
307 (define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
308 eq ne gt ge lt le gtu geu ltu leu])
310 ;; This code macro allows signed and unsigned widening multiplications
311 ;; to use the same template.
312 (define_code_macro any_extend [sign_extend zero_extend])
314 ;; <u> expands to an empty string when doing a signed operation and
315 ;; "u" when doing an unsigned operation.
316 (define_code_attr u [(sign_extend "") (zero_extend "u")])
318 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
319 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
321 ;; .........................
323 ;; Branch, call and jump delay slots
325 ;; .........................
327 (define_delay (and (eq_attr "type" "branch")
328 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
329 [(eq_attr "can_delay" "yes")
331 (and (eq_attr "branch_likely" "yes")
332 (eq_attr "can_delay" "yes"))])
334 (define_delay (eq_attr "type" "jump")
335 [(eq_attr "can_delay" "yes")
339 (define_delay (and (eq_attr "type" "call")
340 (eq_attr "jal_macro" "no"))
341 [(eq_attr "can_delay" "yes")
345 ;; Pipeline descriptions.
347 ;; generic.md provides a fallback for processors without a specific
348 ;; pipeline description. It is derived from the old define_function_unit
349 ;; version and uses the "alu" and "imuldiv" units declared below.
351 ;; Some of the processor-specific files are also derived from old
352 ;; define_function_unit descriptions and simply override the parts of
353 ;; generic.md that don't apply. The other processor-specific files
354 ;; are self-contained.
355 (define_automaton "alu,imuldiv")
357 (define_cpu_unit "alu" "alu")
358 (define_cpu_unit "imuldiv" "imuldiv")
374 (include "generic.md")
377 ;; ....................
381 ;; ....................
385 [(trap_if (const_int 1) (const_int 0))]
388 if (ISA_HAS_COND_TRAP)
390 else if (TARGET_MIPS16)
395 [(set_attr "type" "trap")])
397 (define_expand "conditional_trap"
398 [(trap_if (match_operator 0 "comparison_operator"
399 [(match_dup 2) (match_dup 3)])
400 (match_operand 1 "const_int_operand"))]
403 if (operands[1] == const0_rtx)
405 mips_gen_conditional_trap (operands);
413 [(trap_if (match_operator 0 "trap_comparison_operator"
414 [(match_operand:SI 1 "reg_or_0_operand" "dJ")
415 (match_operand:SI 2 "arith_operand" "dI")])
419 [(set_attr "type" "trap")])
422 [(trap_if (match_operator 0 "trap_comparison_operator"
423 [(match_operand:DI 1 "reg_or_0_operand" "dJ")
424 (match_operand:DI 2 "arith_operand" "dI")])
426 "TARGET_64BIT && ISA_HAS_COND_TRAP"
428 [(set_attr "type" "trap")])
431 ;; ....................
435 ;; ....................
438 (define_insn "adddf3"
439 [(set (match_operand:DF 0 "register_operand" "=f")
440 (plus:DF (match_operand:DF 1 "register_operand" "f")
441 (match_operand:DF 2 "register_operand" "f")))]
442 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
444 [(set_attr "type" "fadd")
445 (set_attr "mode" "DF")])
447 (define_insn "addsf3"
448 [(set (match_operand:SF 0 "register_operand" "=f")
449 (plus:SF (match_operand:SF 1 "register_operand" "f")
450 (match_operand:SF 2 "register_operand" "f")))]
453 [(set_attr "type" "fadd")
454 (set_attr "mode" "SF")])
456 (define_expand "add<mode>3"
457 [(set (match_operand:GPR 0 "register_operand")
458 (plus:GPR (match_operand:GPR 1 "register_operand")
459 (match_operand:GPR 2 "arith_operand")))]
462 (define_insn "*add<mode>3"
463 [(set (match_operand:GPR 0 "register_operand" "=d,d")
464 (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
465 (match_operand:GPR 2 "arith_operand" "d,Q")))]
470 [(set_attr "type" "arith")
471 (set_attr "mode" "<MODE>")])
473 ;; We need to recognize MIPS16 stack pointer additions explicitly, since
474 ;; we don't have a constraint for $sp. These insns will be generated by
475 ;; the save_restore_insns functions.
477 (define_insn "*add<mode>3_sp1"
479 (plus:GPR (reg:GPR 29)
480 (match_operand:GPR 0 "const_arith_operand" "")))]
483 [(set_attr "type" "arith")
484 (set_attr "mode" "<MODE>")
485 (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
489 (define_insn "*add<mode>3_sp2"
490 [(set (match_operand:GPR 0 "register_operand" "=d")
491 (plus:GPR (reg:GPR 29)
492 (match_operand:GPR 1 "const_arith_operand" "")))]
495 [(set_attr "type" "arith")
496 (set_attr "mode" "<MODE>")
497 (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
501 (define_insn "*add<mode>3_mips16"
502 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
503 (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
504 (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
510 [(set_attr "type" "arith")
511 (set_attr "mode" "<MODE>")
512 (set_attr_alternative "length"
513 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
516 (if_then_else (match_operand 2 "m16_simm4_1")
522 ;; On the mips16, we can sometimes split an add of a constant which is
523 ;; a 4 byte instruction into two adds which are both 2 byte
524 ;; instructions. There are two cases: one where we are adding a
525 ;; constant plus a register to another register, and one where we are
526 ;; simply adding a constant to a register.
529 [(set (match_operand:SI 0 "register_operand")
530 (plus:SI (match_dup 0)
531 (match_operand:SI 1 "const_int_operand")))]
532 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
533 && GET_CODE (operands[0]) == REG
534 && M16_REG_P (REGNO (operands[0]))
535 && GET_CODE (operands[1]) == CONST_INT
536 && ((INTVAL (operands[1]) > 0x7f
537 && INTVAL (operands[1]) <= 0x7f + 0x7f)
538 || (INTVAL (operands[1]) < - 0x80
539 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
540 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
541 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
543 HOST_WIDE_INT val = INTVAL (operands[1]);
547 operands[1] = GEN_INT (0x7f);
548 operands[2] = GEN_INT (val - 0x7f);
552 operands[1] = GEN_INT (- 0x80);
553 operands[2] = GEN_INT (val + 0x80);
558 [(set (match_operand:SI 0 "register_operand")
559 (plus:SI (match_operand:SI 1 "register_operand")
560 (match_operand:SI 2 "const_int_operand")))]
561 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
562 && GET_CODE (operands[0]) == REG
563 && M16_REG_P (REGNO (operands[0]))
564 && GET_CODE (operands[1]) == REG
565 && M16_REG_P (REGNO (operands[1]))
566 && REGNO (operands[0]) != REGNO (operands[1])
567 && GET_CODE (operands[2]) == CONST_INT
568 && ((INTVAL (operands[2]) > 0x7
569 && INTVAL (operands[2]) <= 0x7 + 0x7f)
570 || (INTVAL (operands[2]) < - 0x8
571 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
572 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
573 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
575 HOST_WIDE_INT val = INTVAL (operands[2]);
579 operands[2] = GEN_INT (0x7);
580 operands[3] = GEN_INT (val - 0x7);
584 operands[2] = GEN_INT (- 0x8);
585 operands[3] = GEN_INT (val + 0x8);
590 [(set (match_operand:DI 0 "register_operand")
591 (plus:DI (match_dup 0)
592 (match_operand:DI 1 "const_int_operand")))]
593 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
594 && GET_CODE (operands[0]) == REG
595 && M16_REG_P (REGNO (operands[0]))
596 && GET_CODE (operands[1]) == CONST_INT
597 && ((INTVAL (operands[1]) > 0xf
598 && INTVAL (operands[1]) <= 0xf + 0xf)
599 || (INTVAL (operands[1]) < - 0x10
600 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
601 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
602 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
604 HOST_WIDE_INT val = INTVAL (operands[1]);
608 operands[1] = GEN_INT (0xf);
609 operands[2] = GEN_INT (val - 0xf);
613 operands[1] = GEN_INT (- 0x10);
614 operands[2] = GEN_INT (val + 0x10);
619 [(set (match_operand:DI 0 "register_operand")
620 (plus:DI (match_operand:DI 1 "register_operand")
621 (match_operand:DI 2 "const_int_operand")))]
622 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
623 && GET_CODE (operands[0]) == REG
624 && M16_REG_P (REGNO (operands[0]))
625 && GET_CODE (operands[1]) == REG
626 && M16_REG_P (REGNO (operands[1]))
627 && REGNO (operands[0]) != REGNO (operands[1])
628 && GET_CODE (operands[2]) == CONST_INT
629 && ((INTVAL (operands[2]) > 0x7
630 && INTVAL (operands[2]) <= 0x7 + 0xf)
631 || (INTVAL (operands[2]) < - 0x8
632 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
633 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
634 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
636 HOST_WIDE_INT val = INTVAL (operands[2]);
640 operands[2] = GEN_INT (0x7);
641 operands[3] = GEN_INT (val - 0x7);
645 operands[2] = GEN_INT (- 0x8);
646 operands[3] = GEN_INT (val + 0x8);
650 (define_insn "*addsi3_extended"
651 [(set (match_operand:DI 0 "register_operand" "=d,d")
653 (plus:SI (match_operand:SI 1 "register_operand" "d,d")
654 (match_operand:SI 2 "arith_operand" "d,Q"))))]
655 "TARGET_64BIT && !TARGET_MIPS16"
659 [(set_attr "type" "arith")
660 (set_attr "mode" "SI")])
662 ;; Split this insn so that the addiu splitters can have a crack at it.
663 ;; Use a conservative length estimate until the split.
664 (define_insn_and_split "*addsi3_extended_mips16"
665 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
667 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
668 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
669 "TARGET_64BIT && TARGET_MIPS16"
671 "&& reload_completed"
672 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
673 { operands[3] = gen_lowpart (SImode, operands[0]); }
674 [(set_attr "type" "arith")
675 (set_attr "mode" "SI")
676 (set_attr "extended_mips16" "yes")])
679 ;; ....................
683 ;; ....................
686 (define_insn "subdf3"
687 [(set (match_operand:DF 0 "register_operand" "=f")
688 (minus:DF (match_operand:DF 1 "register_operand" "f")
689 (match_operand:DF 2 "register_operand" "f")))]
690 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
692 [(set_attr "type" "fadd")
693 (set_attr "mode" "DF")])
695 (define_insn "subsf3"
696 [(set (match_operand:SF 0 "register_operand" "=f")
697 (minus:SF (match_operand:SF 1 "register_operand" "f")
698 (match_operand:SF 2 "register_operand" "f")))]
701 [(set_attr "type" "fadd")
702 (set_attr "mode" "SF")])
704 (define_insn "sub<mode>3"
705 [(set (match_operand:GPR 0 "register_operand" "=d")
706 (minus:GPR (match_operand:GPR 1 "register_operand" "d")
707 (match_operand:GPR 2 "register_operand" "d")))]
710 [(set_attr "type" "arith")
711 (set_attr "mode" "<MODE>")])
713 (define_insn "*subsi3_extended"
714 [(set (match_operand:DI 0 "register_operand" "=d")
716 (minus:SI (match_operand:SI 1 "register_operand" "d")
717 (match_operand:SI 2 "register_operand" "d"))))]
720 [(set_attr "type" "arith")
721 (set_attr "mode" "DI")])
724 ;; ....................
728 ;; ....................
731 (define_expand "muldf3"
732 [(set (match_operand:DF 0 "register_operand")
733 (mult:DF (match_operand:DF 1 "register_operand")
734 (match_operand:DF 2 "register_operand")))]
735 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
738 (define_insn "muldf3_internal"
739 [(set (match_operand:DF 0 "register_operand" "=f")
740 (mult:DF (match_operand:DF 1 "register_operand" "f")
741 (match_operand:DF 2 "register_operand" "f")))]
742 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
744 [(set_attr "type" "fmul")
745 (set_attr "mode" "DF")])
747 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
748 ;; operands may corrupt immediately following multiplies. This is a
749 ;; simple fix to insert NOPs.
751 (define_insn "muldf3_r4300"
752 [(set (match_operand:DF 0 "register_operand" "=f")
753 (mult:DF (match_operand:DF 1 "register_operand" "f")
754 (match_operand:DF 2 "register_operand" "f")))]
755 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
756 "mul.d\t%0,%1,%2\;nop"
757 [(set_attr "type" "fmul")
758 (set_attr "mode" "DF")
759 (set_attr "length" "8")])
761 (define_expand "mulsf3"
762 [(set (match_operand:SF 0 "register_operand")
763 (mult:SF (match_operand:SF 1 "register_operand")
764 (match_operand:SF 2 "register_operand")))]
768 (define_insn "mulsf3_internal"
769 [(set (match_operand:SF 0 "register_operand" "=f")
770 (mult:SF (match_operand:SF 1 "register_operand" "f")
771 (match_operand:SF 2 "register_operand" "f")))]
772 "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
774 [(set_attr "type" "fmul")
775 (set_attr "mode" "SF")])
779 (define_insn "mulsf3_r4300"
780 [(set (match_operand:SF 0 "register_operand" "=f")
781 (mult:SF (match_operand:SF 1 "register_operand" "f")
782 (match_operand:SF 2 "register_operand" "f")))]
783 "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
784 "mul.s\t%0,%1,%2\;nop"
785 [(set_attr "type" "fmul")
786 (set_attr "mode" "SF")
787 (set_attr "length" "8")])
790 ;; The original R4000 has a cpu bug. If a double-word or a variable
791 ;; shift executes while an integer multiplication is in progress, the
792 ;; shift may give an incorrect result. Avoid this by keeping the mflo
793 ;; with the mult on the R4000.
795 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
796 ;; (also valid for MIPS R4000MC processors):
798 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
799 ;; this errata description.
800 ;; The following code sequence causes the R4000 to incorrectly
801 ;; execute the Double Shift Right Arithmetic 32 (dsra32)
802 ;; instruction. If the dsra32 instruction is executed during an
803 ;; integer multiply, the dsra32 will only shift by the amount in
804 ;; specified in the instruction rather than the amount plus 32
806 ;; instruction 1: mult rs,rt integer multiply
807 ;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
808 ;; right arithmetic + 32
809 ;; Workaround: A dsra32 instruction placed after an integer
810 ;; multiply should not be one of the 11 instructions after the
811 ;; multiply instruction."
815 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
816 ;; the following description.
817 ;; All extended shifts (shift by n+32) and variable shifts (32 and
818 ;; 64-bit versions) may produce incorrect results under the
819 ;; following conditions:
820 ;; 1) An integer multiply is currently executing
821 ;; 2) These types of shift instructions are executed immediately
822 ;; following an integer divide instruction.
824 ;; 1) Make sure no integer multiply is running wihen these
825 ;; instruction are executed. If this cannot be predicted at
826 ;; compile time, then insert a "mfhi" to R0 instruction
827 ;; immediately after the integer multiply instruction. This
828 ;; will cause the integer multiply to complete before the shift
830 ;; 2) Separate integer divide and these two classes of shift
831 ;; instructions by another instruction or a noop."
833 ;; These processors have PRId values of 0x00004220 and 0x00004300,
836 (define_expand "mul<mode>3"
837 [(set (match_operand:GPR 0 "register_operand")
838 (mult:GPR (match_operand:GPR 1 "register_operand")
839 (match_operand:GPR 2 "register_operand")))]
842 if (GENERATE_MULT3_<MODE>)
843 emit_insn (gen_mul<mode>3_mult3 (operands[0], operands[1], operands[2]));
844 else if (!TARGET_FIX_R4000)
845 emit_insn (gen_mul<mode>3_internal (operands[0], operands[1],
848 emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
852 (define_insn "mulsi3_mult3"
853 [(set (match_operand:SI 0 "register_operand" "=d,l")
854 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
855 (match_operand:SI 2 "register_operand" "d,d")))
856 (clobber (match_scratch:SI 3 "=h,h"))
857 (clobber (match_scratch:SI 4 "=l,X"))]
860 if (which_alternative == 1)
861 return "mult\t%1,%2";
870 return "mul\t%0,%1,%2";
871 return "mult\t%0,%1,%2";
873 [(set_attr "type" "imul")
874 (set_attr "mode" "SI")])
876 (define_insn "muldi3_mult3"
877 [(set (match_operand:DI 0 "register_operand" "=d")
878 (mult:DI (match_operand:DI 1 "register_operand" "d")
879 (match_operand:DI 2 "register_operand" "d")))
880 (clobber (match_scratch:DI 3 "=h"))
881 (clobber (match_scratch:DI 4 "=l"))]
882 "TARGET_64BIT && GENERATE_MULT3_DI"
884 [(set_attr "type" "imul")
885 (set_attr "mode" "DI")])
887 ;; If a register gets allocated to LO, and we spill to memory, the reload
888 ;; will include a move from LO to a GPR. Merge it into the multiplication
889 ;; if it can set the GPR directly.
892 ;; Operand 1: GPR (1st multiplication operand)
893 ;; Operand 2: GPR (2nd multiplication operand)
895 ;; Operand 4: GPR (destination)
898 [(set (match_operand:SI 0 "register_operand")
899 (mult:SI (match_operand:SI 1 "register_operand")
900 (match_operand:SI 2 "register_operand")))
901 (clobber (match_operand:SI 3 "register_operand"))
902 (clobber (scratch:SI))])
903 (set (match_operand:SI 4 "register_operand")
904 (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
905 "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
908 (mult:SI (match_dup 1)
910 (clobber (match_dup 3))
911 (clobber (match_dup 0))])])
913 (define_insn "mul<mode>3_internal"
914 [(set (match_operand:GPR 0 "register_operand" "=l")
915 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
916 (match_operand:GPR 2 "register_operand" "d")))
917 (clobber (match_scratch:GPR 3 "=h"))]
920 [(set_attr "type" "imul")
921 (set_attr "mode" "<MODE>")])
923 (define_insn "mul<mode>3_r4000"
924 [(set (match_operand:GPR 0 "register_operand" "=d")
925 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
926 (match_operand:GPR 2 "register_operand" "d")))
927 (clobber (match_scratch:GPR 3 "=h"))
928 (clobber (match_scratch:GPR 4 "=l"))]
930 "<d>mult\t%1,%2\;mflo\t%0"
931 [(set_attr "type" "imul")
932 (set_attr "mode" "<MODE>")
933 (set_attr "length" "8")])
935 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
936 ;; of "mult; mflo". They have the same latency, but the first form gives
937 ;; us an extra cycle to compute the operands.
940 ;; Operand 1: GPR (1st multiplication operand)
941 ;; Operand 2: GPR (2nd multiplication operand)
943 ;; Operand 4: GPR (destination)
946 [(set (match_operand:SI 0 "register_operand")
947 (mult:SI (match_operand:SI 1 "register_operand")
948 (match_operand:SI 2 "register_operand")))
949 (clobber (match_operand:SI 3 "register_operand"))])
950 (set (match_operand:SI 4 "register_operand")
951 (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
952 "ISA_HAS_MACC && !GENERATE_MULT3_SI"
957 (plus:SI (mult:SI (match_dup 1)
961 (plus:SI (mult:SI (match_dup 1)
964 (clobber (match_dup 3))])])
966 ;; Multiply-accumulate patterns
968 ;; For processors that can copy the output to a general register:
970 ;; The all-d alternative is needed because the combiner will find this
971 ;; pattern and then register alloc/reload will move registers around to
972 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
974 ;; The last alternative should be made slightly less desirable, but adding
975 ;; "?" to the constraint is too strong, and causes values to be loaded into
976 ;; LO even when that's more costly. For now, using "*d" mostly does the
978 (define_insn "*mul_acc_si"
979 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
980 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
981 (match_operand:SI 2 "register_operand" "d,d,d"))
982 (match_operand:SI 3 "register_operand" "0,l,*d")))
983 (clobber (match_scratch:SI 4 "=h,h,h"))
984 (clobber (match_scratch:SI 5 "=X,3,l"))
985 (clobber (match_scratch:SI 6 "=X,X,&d"))]
987 || ISA_HAS_MADD_MSUB)
990 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
991 if (which_alternative == 2)
993 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
995 return madd[which_alternative];
997 [(set_attr "type" "imadd,imadd,multi")
998 (set_attr "mode" "SI")
999 (set_attr "length" "4,4,8")])
1001 ;; Split the above insn if we failed to get LO allocated.
1003 [(set (match_operand:SI 0 "register_operand")
1004 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1005 (match_operand:SI 2 "register_operand"))
1006 (match_operand:SI 3 "register_operand")))
1007 (clobber (match_scratch:SI 4))
1008 (clobber (match_scratch:SI 5))
1009 (clobber (match_scratch:SI 6))]
1010 "reload_completed && !TARGET_DEBUG_D_MODE
1011 && GP_REG_P (true_regnum (operands[0]))
1012 && GP_REG_P (true_regnum (operands[3]))"
1013 [(parallel [(set (match_dup 6)
1014 (mult:SI (match_dup 1) (match_dup 2)))
1015 (clobber (match_dup 4))
1016 (clobber (match_dup 5))])
1017 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1020 ;; Splitter to copy result of MADD to a general register
1022 [(set (match_operand:SI 0 "register_operand")
1023 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1024 (match_operand:SI 2 "register_operand"))
1025 (match_operand:SI 3 "register_operand")))
1026 (clobber (match_scratch:SI 4))
1027 (clobber (match_scratch:SI 5))
1028 (clobber (match_scratch:SI 6))]
1029 "reload_completed && !TARGET_DEBUG_D_MODE
1030 && GP_REG_P (true_regnum (operands[0]))
1031 && true_regnum (operands[3]) == LO_REGNUM"
1032 [(parallel [(set (match_dup 3)
1033 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1035 (clobber (match_dup 4))
1036 (clobber (match_dup 5))
1037 (clobber (match_dup 6))])
1038 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1041 (define_insn "*macc"
1042 [(set (match_operand:SI 0 "register_operand" "=l,d")
1043 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1044 (match_operand:SI 2 "register_operand" "d,d"))
1045 (match_operand:SI 3 "register_operand" "0,l")))
1046 (clobber (match_scratch:SI 4 "=h,h"))
1047 (clobber (match_scratch:SI 5 "=X,3"))]
1050 if (which_alternative == 1)
1051 return "macc\t%0,%1,%2";
1052 else if (TARGET_MIPS5500)
1053 return "madd\t%1,%2";
1055 /* The VR4130 assumes that there is a two-cycle latency between a macc
1056 that "writes" to $0 and an instruction that reads from it. We avoid
1057 this by assigning to $1 instead. */
1058 return "%[macc\t%@,%1,%2%]";
1060 [(set_attr "type" "imadd")
1061 (set_attr "mode" "SI")])
1063 (define_insn "*msac"
1064 [(set (match_operand:SI 0 "register_operand" "=l,d")
1065 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1066 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1067 (match_operand:SI 3 "register_operand" "d,d"))))
1068 (clobber (match_scratch:SI 4 "=h,h"))
1069 (clobber (match_scratch:SI 5 "=X,1"))]
1072 if (which_alternative == 1)
1073 return "msac\t%0,%2,%3";
1074 else if (TARGET_MIPS5500)
1075 return "msub\t%2,%3";
1077 return "msac\t$0,%2,%3";
1079 [(set_attr "type" "imadd")
1080 (set_attr "mode" "SI")])
1082 ;; An msac-like instruction implemented using negation and a macc.
1083 (define_insn_and_split "*msac_using_macc"
1084 [(set (match_operand:SI 0 "register_operand" "=l,d")
1085 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1086 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1087 (match_operand:SI 3 "register_operand" "d,d"))))
1088 (clobber (match_scratch:SI 4 "=h,h"))
1089 (clobber (match_scratch:SI 5 "=X,1"))
1090 (clobber (match_scratch:SI 6 "=d,d"))]
1091 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1093 "&& reload_completed"
1095 (neg:SI (match_dup 3)))
1098 (plus:SI (mult:SI (match_dup 2)
1101 (clobber (match_dup 4))
1102 (clobber (match_dup 5))])]
1104 [(set_attr "type" "imadd")
1105 (set_attr "length" "8")])
1107 ;; Patterns generated by the define_peephole2 below.
1109 (define_insn "*macc2"
1110 [(set (match_operand:SI 0 "register_operand" "=l")
1111 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1112 (match_operand:SI 2 "register_operand" "d"))
1114 (set (match_operand:SI 3 "register_operand" "=d")
1115 (plus:SI (mult:SI (match_dup 1)
1118 (clobber (match_scratch:SI 4 "=h"))]
1119 "ISA_HAS_MACC && reload_completed"
1121 [(set_attr "type" "imadd")
1122 (set_attr "mode" "SI")])
1124 (define_insn "*msac2"
1125 [(set (match_operand:SI 0 "register_operand" "=l")
1126 (minus:SI (match_dup 0)
1127 (mult:SI (match_operand:SI 1 "register_operand" "d")
1128 (match_operand:SI 2 "register_operand" "d"))))
1129 (set (match_operand:SI 3 "register_operand" "=d")
1130 (minus:SI (match_dup 0)
1131 (mult:SI (match_dup 1)
1133 (clobber (match_scratch:SI 4 "=h"))]
1134 "ISA_HAS_MSAC && reload_completed"
1136 [(set_attr "type" "imadd")
1137 (set_attr "mode" "SI")])
1139 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1143 ;; Operand 1: macc/msac
1145 ;; Operand 3: GPR (destination)
1148 [(set (match_operand:SI 0 "register_operand")
1149 (match_operand:SI 1 "macc_msac_operand"))
1150 (clobber (match_operand:SI 2 "register_operand"))
1151 (clobber (scratch:SI))])
1152 (set (match_operand:SI 3 "register_operand")
1153 (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1155 [(parallel [(set (match_dup 0)
1159 (clobber (match_dup 2))])]
1162 ;; When we have a three-address multiplication instruction, it should
1163 ;; be faster to do a separate multiply and add, rather than moving
1164 ;; something into LO in order to use a macc instruction.
1166 ;; This peephole needs a scratch register to cater for the case when one
1167 ;; of the multiplication operands is the same as the destination.
1169 ;; Operand 0: GPR (scratch)
1171 ;; Operand 2: GPR (addend)
1172 ;; Operand 3: GPR (destination)
1173 ;; Operand 4: macc/msac
1175 ;; Operand 6: new multiplication
1176 ;; Operand 7: new addition/subtraction
1178 [(match_scratch:SI 0 "d")
1179 (set (match_operand:SI 1 "register_operand")
1180 (match_operand:SI 2 "register_operand"))
1183 [(set (match_operand:SI 3 "register_operand")
1184 (match_operand:SI 4 "macc_msac_operand"))
1185 (clobber (match_operand:SI 5 "register_operand"))
1186 (clobber (match_dup 1))])]
1188 && true_regnum (operands[1]) == LO_REGNUM
1189 && peep2_reg_dead_p (2, operands[1])
1190 && GP_REG_P (true_regnum (operands[3]))"
1191 [(parallel [(set (match_dup 0)
1193 (clobber (match_dup 5))
1194 (clobber (match_dup 1))])
1198 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1199 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1200 operands[2], operands[0]);
1203 ;; Same as above, except LO is the initial target of the macc.
1205 ;; Operand 0: GPR (scratch)
1207 ;; Operand 2: GPR (addend)
1208 ;; Operand 3: macc/msac
1210 ;; Operand 5: GPR (destination)
1211 ;; Operand 6: new multiplication
1212 ;; Operand 7: new addition/subtraction
1214 [(match_scratch:SI 0 "d")
1215 (set (match_operand:SI 1 "register_operand")
1216 (match_operand:SI 2 "register_operand"))
1220 (match_operand:SI 3 "macc_msac_operand"))
1221 (clobber (match_operand:SI 4 "register_operand"))
1222 (clobber (scratch:SI))])
1224 (set (match_operand:SI 5 "register_operand")
1225 (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1226 "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1227 [(parallel [(set (match_dup 0)
1229 (clobber (match_dup 4))
1230 (clobber (match_dup 1))])
1234 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1235 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1236 operands[2], operands[0]);
1239 (define_insn "*mul_sub_si"
1240 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1241 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1242 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1243 (match_operand:SI 3 "register_operand" "d,d,d"))))
1244 (clobber (match_scratch:SI 4 "=h,h,h"))
1245 (clobber (match_scratch:SI 5 "=X,1,l"))
1246 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1252 [(set_attr "type" "imadd,multi,multi")
1253 (set_attr "mode" "SI")
1254 (set_attr "length" "4,8,8")])
1256 ;; Split the above insn if we failed to get LO allocated.
1258 [(set (match_operand:SI 0 "register_operand")
1259 (minus:SI (match_operand:SI 1 "register_operand")
1260 (mult:SI (match_operand:SI 2 "register_operand")
1261 (match_operand:SI 3 "register_operand"))))
1262 (clobber (match_scratch:SI 4))
1263 (clobber (match_scratch:SI 5))
1264 (clobber (match_scratch:SI 6))]
1265 "reload_completed && !TARGET_DEBUG_D_MODE
1266 && GP_REG_P (true_regnum (operands[0]))
1267 && GP_REG_P (true_regnum (operands[1]))"
1268 [(parallel [(set (match_dup 6)
1269 (mult:SI (match_dup 2) (match_dup 3)))
1270 (clobber (match_dup 4))
1271 (clobber (match_dup 5))])
1272 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1275 ;; Splitter to copy result of MSUB to a general register
1277 [(set (match_operand:SI 0 "register_operand")
1278 (minus:SI (match_operand:SI 1 "register_operand")
1279 (mult:SI (match_operand:SI 2 "register_operand")
1280 (match_operand:SI 3 "register_operand"))))
1281 (clobber (match_scratch:SI 4))
1282 (clobber (match_scratch:SI 5))
1283 (clobber (match_scratch:SI 6))]
1284 "reload_completed && !TARGET_DEBUG_D_MODE
1285 && GP_REG_P (true_regnum (operands[0]))
1286 && true_regnum (operands[1]) == LO_REGNUM"
1287 [(parallel [(set (match_dup 1)
1288 (minus:SI (match_dup 1)
1289 (mult:SI (match_dup 2) (match_dup 3))))
1290 (clobber (match_dup 4))
1291 (clobber (match_dup 5))
1292 (clobber (match_dup 6))])
1293 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1296 (define_insn "*muls"
1297 [(set (match_operand:SI 0 "register_operand" "=l,d")
1298 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1299 (match_operand:SI 2 "register_operand" "d,d"))))
1300 (clobber (match_scratch:SI 3 "=h,h"))
1301 (clobber (match_scratch:SI 4 "=X,l"))]
1306 [(set_attr "type" "imul")
1307 (set_attr "mode" "SI")])
1309 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1311 (define_expand "<u>mulsidi3"
1313 [(set (match_operand:DI 0 "register_operand")
1314 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1315 (any_extend:DI (match_operand:SI 2 "register_operand"))))
1316 (clobber (scratch:DI))
1317 (clobber (scratch:DI))
1318 (clobber (scratch:DI))])]
1319 "!TARGET_64BIT || !TARGET_FIX_R4000"
1323 if (!TARGET_FIX_R4000)
1324 emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1327 emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1333 (define_insn "<u>mulsidi3_32bit_internal"
1334 [(set (match_operand:DI 0 "register_operand" "=x")
1335 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1336 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1337 "!TARGET_64BIT && !TARGET_FIX_R4000"
1339 [(set_attr "type" "imul")
1340 (set_attr "mode" "SI")])
1342 (define_insn "<u>mulsidi3_32bit_r4000"
1343 [(set (match_operand:DI 0 "register_operand" "=d")
1344 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1345 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1346 (clobber (match_scratch:DI 3 "=x"))]
1347 "!TARGET_64BIT && TARGET_FIX_R4000"
1348 "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1349 [(set_attr "type" "imul")
1350 (set_attr "mode" "SI")
1351 (set_attr "length" "12")])
1353 (define_insn_and_split "*<u>mulsidi3_64bit"
1354 [(set (match_operand:DI 0 "register_operand" "=d")
1355 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1356 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1357 (clobber (match_scratch:DI 3 "=l"))
1358 (clobber (match_scratch:DI 4 "=h"))
1359 (clobber (match_scratch:DI 5 "=d"))]
1360 "TARGET_64BIT && !TARGET_FIX_R4000"
1362 "&& reload_completed"
1366 (mult:SI (match_dup 1)
1370 (mult:DI (any_extend:DI (match_dup 1))
1371 (any_extend:DI (match_dup 2)))
1374 ;; OP5 <- LO, OP0 <- HI
1375 (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1376 (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1380 (ashift:DI (match_dup 5)
1383 (lshiftrt:DI (match_dup 5)
1386 ;; Shift OP0 into place.
1388 (ashift:DI (match_dup 0)
1391 ;; OR the two halves together
1393 (ior:DI (match_dup 0)
1396 [(set_attr "type" "imul")
1397 (set_attr "mode" "SI")
1398 (set_attr "length" "24")])
1400 (define_insn "*<u>mulsidi3_64bit_parts"
1401 [(set (match_operand:DI 0 "register_operand" "=l")
1403 (mult:SI (match_operand:SI 2 "register_operand" "d")
1404 (match_operand:SI 3 "register_operand" "d"))))
1405 (set (match_operand:DI 1 "register_operand" "=h")
1407 (mult:DI (any_extend:DI (match_dup 2))
1408 (any_extend:DI (match_dup 3)))
1410 "TARGET_64BIT && !TARGET_FIX_R4000"
1412 [(set_attr "type" "imul")
1413 (set_attr "mode" "SI")])
1415 ;; Widening multiply with negation.
1416 (define_insn "*muls<u>_di"
1417 [(set (match_operand:DI 0 "register_operand" "=x")
1420 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1421 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1422 "!TARGET_64BIT && ISA_HAS_MULS"
1424 [(set_attr "type" "imul")
1425 (set_attr "mode" "SI")])
1427 (define_insn "*msac<u>_di"
1428 [(set (match_operand:DI 0 "register_operand" "=x")
1430 (match_operand:DI 3 "register_operand" "0")
1432 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1433 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1434 "!TARGET_64BIT && ISA_HAS_MSAC"
1436 if (TARGET_MIPS5500)
1437 return "msub<u>\t%1,%2";
1439 return "msac<u>\t$0,%1,%2";
1441 [(set_attr "type" "imadd")
1442 (set_attr "mode" "SI")])
1444 ;; _highpart patterns
1446 (define_expand "<su>mulsi3_highpart"
1447 [(set (match_operand:SI 0 "register_operand")
1450 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1451 (any_extend:DI (match_operand:SI 2 "register_operand")))
1453 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1456 emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1460 emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1465 (define_insn "<su>mulsi3_highpart_internal"
1466 [(set (match_operand:SI 0 "register_operand" "=h")
1469 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1470 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1472 (clobber (match_scratch:SI 3 "=l"))]
1473 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1475 [(set_attr "type" "imul")
1476 (set_attr "mode" "SI")])
1478 (define_insn "<su>mulsi3_highpart_mulhi_internal"
1479 [(set (match_operand:SI 0 "register_operand" "=h,d")
1483 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1484 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1486 (clobber (match_scratch:SI 3 "=l,l"))
1487 (clobber (match_scratch:SI 4 "=X,h"))]
1492 [(set_attr "type" "imul")
1493 (set_attr "mode" "SI")])
1495 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1496 [(set (match_operand:SI 0 "register_operand" "=h,d")
1501 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1502 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1504 (clobber (match_scratch:SI 3 "=l,l"))
1505 (clobber (match_scratch:SI 4 "=X,h"))]
1509 mulshi<u>\t%0,%1,%2"
1510 [(set_attr "type" "imul")
1511 (set_attr "mode" "SI")])
1513 ;; Disable unsigned multiplication for -mfix-vr4120. This is for VR4120
1514 ;; errata MD(0), which says that dmultu does not always produce the
1516 (define_insn "<su>muldi3_highpart"
1517 [(set (match_operand:DI 0 "register_operand" "=h")
1521 (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1522 (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1524 (clobber (match_scratch:DI 3 "=l"))]
1525 "TARGET_64BIT && !TARGET_FIX_R4000
1526 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1528 [(set_attr "type" "imul")
1529 (set_attr "mode" "DI")])
1531 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1532 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
1534 (define_insn "madsi"
1535 [(set (match_operand:SI 0 "register_operand" "+l")
1536 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1537 (match_operand:SI 2 "register_operand" "d"))
1539 (clobber (match_scratch:SI 3 "=h"))]
1542 [(set_attr "type" "imadd")
1543 (set_attr "mode" "SI")])
1545 (define_insn "*<su>mul_acc_di"
1546 [(set (match_operand:DI 0 "register_operand" "=x")
1548 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1549 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1550 (match_operand:DI 3 "register_operand" "0")))]
1551 "(TARGET_MAD || ISA_HAS_MACC)
1555 return "mad<u>\t%1,%2";
1556 else if (TARGET_MIPS5500)
1557 return "madd<u>\t%1,%2";
1559 /* See comment in *macc. */
1560 return "%[macc<u>\t%@,%1,%2%]";
1562 [(set_attr "type" "imadd")
1563 (set_attr "mode" "SI")])
1565 ;; Floating point multiply accumulate instructions.
1568 [(set (match_operand:DF 0 "register_operand" "=f")
1569 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1570 (match_operand:DF 2 "register_operand" "f"))
1571 (match_operand:DF 3 "register_operand" "f")))]
1572 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1573 "madd.d\t%0,%3,%1,%2"
1574 [(set_attr "type" "fmadd")
1575 (set_attr "mode" "DF")])
1578 [(set (match_operand:SF 0 "register_operand" "=f")
1579 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1580 (match_operand:SF 2 "register_operand" "f"))
1581 (match_operand:SF 3 "register_operand" "f")))]
1582 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1583 "madd.s\t%0,%3,%1,%2"
1584 [(set_attr "type" "fmadd")
1585 (set_attr "mode" "SF")])
1588 [(set (match_operand:DF 0 "register_operand" "=f")
1589 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1590 (match_operand:DF 2 "register_operand" "f"))
1591 (match_operand:DF 3 "register_operand" "f")))]
1592 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1593 "msub.d\t%0,%3,%1,%2"
1594 [(set_attr "type" "fmadd")
1595 (set_attr "mode" "DF")])
1598 [(set (match_operand:SF 0 "register_operand" "=f")
1599 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1600 (match_operand:SF 2 "register_operand" "f"))
1601 (match_operand:SF 3 "register_operand" "f")))]
1603 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1604 "msub.s\t%0,%3,%1,%2"
1605 [(set_attr "type" "fmadd")
1606 (set_attr "mode" "SF")])
1609 [(set (match_operand:DF 0 "register_operand" "=f")
1610 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1611 (match_operand:DF 2 "register_operand" "f"))
1612 (match_operand:DF 3 "register_operand" "f"))))]
1613 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1614 && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1615 "nmadd.d\t%0,%3,%1,%2"
1616 [(set_attr "type" "fmadd")
1617 (set_attr "mode" "DF")])
1620 [(set (match_operand:DF 0 "register_operand" "=f")
1621 (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
1622 (match_operand:DF 2 "register_operand" "f"))
1623 (match_operand:DF 3 "register_operand" "f")))]
1624 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1625 && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1626 "nmadd.d\t%0,%3,%1,%2"
1627 [(set_attr "type" "fmadd")
1628 (set_attr "mode" "DF")])
1631 [(set (match_operand:SF 0 "register_operand" "=f")
1632 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1633 (match_operand:SF 2 "register_operand" "f"))
1634 (match_operand:SF 3 "register_operand" "f"))))]
1635 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1636 && HONOR_SIGNED_ZEROS (SFmode)"
1637 "nmadd.s\t%0,%3,%1,%2"
1638 [(set_attr "type" "fmadd")
1639 (set_attr "mode" "SF")])
1642 [(set (match_operand:SF 0 "register_operand" "=f")
1643 (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
1644 (match_operand:SF 2 "register_operand" "f"))
1645 (match_operand:SF 3 "register_operand" "f")))]
1646 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1647 && !HONOR_SIGNED_ZEROS (SFmode)"
1648 "nmadd.s\t%0,%3,%1,%2"
1649 [(set_attr "type" "fmadd")
1650 (set_attr "mode" "SF")])
1653 [(set (match_operand:DF 0 "register_operand" "=f")
1654 (neg:DF (minus:DF (mult:DF (match_operand:DF 2 "register_operand" "f")
1655 (match_operand:DF 3 "register_operand" "f"))
1656 (match_operand:DF 1 "register_operand" "f"))))]
1657 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1658 && TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)"
1659 "nmsub.d\t%0,%1,%2,%3"
1660 [(set_attr "type" "fmadd")
1661 (set_attr "mode" "DF")])
1664 [(set (match_operand:DF 0 "register_operand" "=f")
1665 (minus:DF (match_operand:DF 1 "register_operand" "f")
1666 (mult:DF (match_operand:DF 2 "register_operand" "f")
1667 (match_operand:DF 3 "register_operand" "f"))))]
1668 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
1669 && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)"
1670 "nmsub.d\t%0,%1,%2,%3"
1671 [(set_attr "type" "fmadd")
1672 (set_attr "mode" "DF")])
1675 [(set (match_operand:SF 0 "register_operand" "=f")
1676 (neg:SF (minus:SF (mult:SF (match_operand:SF 2 "register_operand" "f")
1677 (match_operand:SF 3 "register_operand" "f"))
1678 (match_operand:SF 1 "register_operand" "f"))))]
1679 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1680 && HONOR_SIGNED_ZEROS (SFmode)"
1681 "nmsub.s\t%0,%1,%2,%3"
1682 [(set_attr "type" "fmadd")
1683 (set_attr "mode" "SF")])
1686 [(set (match_operand:SF 0 "register_operand" "=f")
1687 (minus:SF (match_operand:SF 1 "register_operand" "f")
1688 (mult:SF (match_operand:SF 2 "register_operand" "f")
1689 (match_operand:SF 3 "register_operand" "f"))))]
1690 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD
1691 && !HONOR_SIGNED_ZEROS (SFmode)"
1692 "nmsub.s\t%0,%1,%2,%3"
1693 [(set_attr "type" "fmadd")
1694 (set_attr "mode" "SF")])
1697 ;; ....................
1699 ;; DIVISION and REMAINDER
1701 ;; ....................
1704 (define_expand "divdf3"
1705 [(set (match_operand:DF 0 "register_operand")
1706 (div:DF (match_operand:DF 1 "reg_or_1_operand")
1707 (match_operand:DF 2 "register_operand")))]
1708 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1710 if (const_1_operand (operands[1], DFmode))
1711 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1712 operands[1] = force_reg (DFmode, operands[1]);
1715 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
1717 ;; If an mfc1 or dmfc1 happens to access the floating point register
1718 ;; file at the same time a long latency operation (div, sqrt, recip,
1719 ;; sqrt) iterates an intermediate result back through the floating
1720 ;; point register file bypass, then instead returning the correct
1721 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1722 ;; result of the long latency operation.
1724 ;; The workaround is to insert an unconditional 'mov' from/to the
1725 ;; long latency op destination register.
1727 (define_insn "*divdf3"
1728 [(set (match_operand:DF 0 "register_operand" "=f")
1729 (div:DF (match_operand:DF 1 "register_operand" "f")
1730 (match_operand:DF 2 "register_operand" "f")))]
1731 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1734 return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
1736 return "div.d\t%0,%1,%2";
1738 [(set_attr "type" "fdiv")
1739 (set_attr "mode" "DF")
1740 (set (attr "length")
1741 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1746 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
1748 ;; In certain cases, div.s and div.ps may have a rounding error
1749 ;; and/or wrong inexact flag.
1751 ;; Therefore, we only allow div.s if not working around SB-1 rev2
1752 ;; errata, or if working around those errata and a slight loss of
1753 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
1754 (define_expand "divsf3"
1755 [(set (match_operand:SF 0 "register_operand")
1756 (div:SF (match_operand:SF 1 "reg_or_1_operand")
1757 (match_operand:SF 2 "register_operand")))]
1758 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
1760 if (const_1_operand (operands[1], SFmode))
1761 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1762 operands[1] = force_reg (SFmode, operands[1]);
1765 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1766 ;; "divdf3" comment for details).
1768 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
1769 ;; "divsf3" comment for details).
1770 (define_insn "*divsf3"
1771 [(set (match_operand:SF 0 "register_operand" "=f")
1772 (div:SF (match_operand:SF 1 "register_operand" "f")
1773 (match_operand:SF 2 "register_operand" "f")))]
1774 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
1777 return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
1779 return "div.s\t%0,%1,%2";
1781 [(set_attr "type" "fdiv")
1782 (set_attr "mode" "SF")
1783 (set (attr "length")
1784 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1788 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1789 ;; "divdf3" comment for details).
1791 [(set (match_operand:DF 0 "register_operand" "=f")
1792 (div:DF (match_operand:DF 1 "const_1_operand" "")
1793 (match_operand:DF 2 "register_operand" "f")))]
1794 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
1797 return "recip.d\t%0,%2\;mov.d\t%0,%0";
1799 return "recip.d\t%0,%2";
1801 [(set_attr "type" "frdiv")
1802 (set_attr "mode" "DF")
1803 (set (attr "length")
1804 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1808 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1809 ;; "divdf3" comment for details).
1811 [(set (match_operand:SF 0 "register_operand" "=f")
1812 (div:SF (match_operand:SF 1 "const_1_operand" "")
1813 (match_operand:SF 2 "register_operand" "f")))]
1814 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
1817 return "recip.s\t%0,%2\;mov.s\t%0,%0";
1819 return "recip.s\t%0,%2";
1821 [(set_attr "type" "frdiv")
1822 (set_attr "mode" "SF")
1823 (set (attr "length")
1824 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1828 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
1829 ;; with negative operands. We use special libgcc functions instead.
1830 (define_insn "divmod<mode>4"
1831 [(set (match_operand:GPR 0 "register_operand" "=l")
1832 (div:GPR (match_operand:GPR 1 "register_operand" "d")
1833 (match_operand:GPR 2 "register_operand" "d")))
1834 (set (match_operand:GPR 3 "register_operand" "=h")
1835 (mod:GPR (match_dup 1)
1837 "!TARGET_FIX_VR4120"
1838 { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1839 [(set_attr "type" "idiv")
1840 (set_attr "mode" "<MODE>")])
1842 (define_insn "udivmod<mode>4"
1843 [(set (match_operand:GPR 0 "register_operand" "=l")
1844 (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1845 (match_operand:GPR 2 "register_operand" "d")))
1846 (set (match_operand:GPR 3 "register_operand" "=h")
1847 (umod:GPR (match_dup 1)
1850 { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1851 [(set_attr "type" "idiv")
1852 (set_attr "mode" "<MODE>")])
1855 ;; ....................
1859 ;; ....................
1861 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1862 ;; "divdf3" comment for details).
1863 (define_insn "sqrtdf2"
1864 [(set (match_operand:DF 0 "register_operand" "=f")
1865 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
1866 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
1869 return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
1871 return "sqrt.d\t%0,%1";
1873 [(set_attr "type" "fsqrt")
1874 (set_attr "mode" "DF")
1875 (set (attr "length")
1876 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1880 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1881 ;; "divdf3" comment for details).
1882 (define_insn "sqrtsf2"
1883 [(set (match_operand:SF 0 "register_operand" "=f")
1884 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
1885 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
1888 return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
1890 return "sqrt.s\t%0,%1";
1892 [(set_attr "type" "fsqrt")
1893 (set_attr "mode" "SF")
1894 (set (attr "length")
1895 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1899 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1900 ;; "divdf3" comment for details).
1902 [(set (match_operand:DF 0 "register_operand" "=f")
1903 (div:DF (match_operand:DF 1 "const_1_operand" "")
1904 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
1905 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
1908 return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
1910 return "rsqrt.d\t%0,%2";
1912 [(set_attr "type" "frsqrt")
1913 (set_attr "mode" "DF")
1914 (set (attr "length")
1915 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1919 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1920 ;; "divdf3" comment for details).
1922 [(set (match_operand:SF 0 "register_operand" "=f")
1923 (div:SF (match_operand:SF 1 "const_1_operand" "")
1924 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
1925 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
1928 return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
1930 return "rsqrt.s\t%0,%2";
1932 [(set_attr "type" "frsqrt")
1933 (set_attr "mode" "SF")
1934 (set (attr "length")
1935 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1939 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1940 ;; "divdf3" comment for details).
1942 [(set (match_operand:DF 0 "register_operand" "=f")
1943 (sqrt:DF (div:DF (match_operand:DF 1 "const_1_operand" "")
1944 (match_operand:DF 2 "register_operand" "f"))))]
1945 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
1948 return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
1950 return "rsqrt.d\t%0,%2";
1952 [(set_attr "type" "frsqrt")
1953 (set_attr "mode" "DF")
1954 (set (attr "length")
1955 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1959 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
1960 ;; "divdf3" comment for details).
1962 [(set (match_operand:SF 0 "register_operand" "=f")
1963 (sqrt:SF (div:SF (match_operand:SF 1 "const_1_operand" "")
1964 (match_operand:SF 2 "register_operand" "f"))))]
1965 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
1968 return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
1970 return "rsqrt.s\t%0,%2";
1972 [(set_attr "type" "frsqrt")
1973 (set_attr "mode" "SF")
1974 (set (attr "length")
1975 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1980 ;; ....................
1984 ;; ....................
1986 ;; Do not use the integer abs macro instruction, since that signals an
1987 ;; exception on -2147483648 (sigh).
1989 (define_insn "abs<mode>2"
1990 [(set (match_operand:GPR 0 "register_operand" "=d")
1991 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))]
1994 if (REGNO (operands[0]) == REGNO (operands[1]) && GENERATE_BRANCHLIKELY)
1995 return "%(bltzl\t%1,1f\;<d>subu\t%0,%.,%0\n%~1:%)";
1997 return "%(bgez\t%1,1f\;move\t%0,%1\;<d>subu\t%0,%.,%0\n%~1:%)";
1999 [(set_attr "type" "multi")
2000 (set_attr "mode" "<MODE>")
2001 (set_attr "length" "12")])
2003 (define_insn "absdf2"
2004 [(set (match_operand:DF 0 "register_operand" "=f")
2005 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2006 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2008 [(set_attr "type" "fabs")
2009 (set_attr "mode" "DF")])
2011 (define_insn "abssf2"
2012 [(set (match_operand:SF 0 "register_operand" "=f")
2013 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2016 [(set_attr "type" "fabs")
2017 (set_attr "mode" "SF")])
2020 ;; ....................
2022 ;; FIND FIRST BIT INSTRUCTION
2024 ;; ....................
2027 (define_insn "ffs<mode>2"
2028 [(set (match_operand:GPR 0 "register_operand" "=&d")
2029 (ffs:GPR (match_operand:GPR 1 "register_operand" "d")))
2030 (clobber (match_scratch:GPR 2 "=&d"))
2031 (clobber (match_scratch:GPR 3 "=&d"))]
2034 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2038 %~1:\tand\t%2,%1,0x0001\;\
2048 %~1:\tand\t%2,%3,0x0001\;\
2054 [(set_attr "type" "multi")
2055 (set_attr "mode" "<MODE>")
2056 (set_attr "length" "28")])
2059 ;; ...................
2061 ;; Count leading zeroes.
2063 ;; ...................
2066 (define_insn "clz<mode>2"
2067 [(set (match_operand:GPR 0 "register_operand" "=d")
2068 (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2071 [(set_attr "type" "clz")
2072 (set_attr "mode" "<MODE>")])
2075 ;; ....................
2077 ;; NEGATION and ONE'S COMPLEMENT
2079 ;; ....................
2081 (define_insn "negsi2"
2082 [(set (match_operand:SI 0 "register_operand" "=d")
2083 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2087 return "neg\t%0,%1";
2089 return "subu\t%0,%.,%1";
2091 [(set_attr "type" "arith")
2092 (set_attr "mode" "SI")])
2094 (define_insn "negdi2"
2095 [(set (match_operand:DI 0 "register_operand" "=d")
2096 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2097 "TARGET_64BIT && !TARGET_MIPS16"
2099 [(set_attr "type" "arith")
2100 (set_attr "mode" "DI")])
2102 (define_insn "negdf2"
2103 [(set (match_operand:DF 0 "register_operand" "=f")
2104 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2105 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2107 [(set_attr "type" "fneg")
2108 (set_attr "mode" "DF")])
2110 (define_insn "negsf2"
2111 [(set (match_operand:SF 0 "register_operand" "=f")
2112 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2115 [(set_attr "type" "fneg")
2116 (set_attr "mode" "SF")])
2118 (define_insn "one_cmplsi2"
2119 [(set (match_operand:SI 0 "register_operand" "=d")
2120 (not:SI (match_operand:SI 1 "register_operand" "d")))]
2124 return "not\t%0,%1";
2126 return "nor\t%0,%.,%1";
2128 [(set_attr "type" "arith")
2129 (set_attr "mode" "SI")])
2131 (define_insn "one_cmpldi2"
2132 [(set (match_operand:DI 0 "register_operand" "=d")
2133 (not:DI (match_operand:DI 1 "register_operand" "d")))]
2137 return "not\t%0,%1";
2139 return "nor\t%0,%.,%1";
2141 [(set_attr "type" "arith")
2142 (set_attr "mode" "DI")])
2145 ;; ....................
2149 ;; ....................
2152 ;; Many of these instructions use trivial define_expands, because we
2153 ;; want to use a different set of constraints when TARGET_MIPS16.
2155 (define_expand "andsi3"
2156 [(set (match_operand:SI 0 "register_operand")
2157 (and:SI (match_operand:SI 1 "uns_arith_operand")
2158 (match_operand:SI 2 "uns_arith_operand")))]
2163 operands[1] = force_reg (SImode, operands[1]);
2164 operands[2] = force_reg (SImode, operands[2]);
2169 [(set (match_operand:SI 0 "register_operand" "=d,d")
2170 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2171 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2176 [(set_attr "type" "arith")
2177 (set_attr "mode" "SI")])
2180 [(set (match_operand:SI 0 "register_operand" "=d")
2181 (and:SI (match_operand:SI 1 "register_operand" "%0")
2182 (match_operand:SI 2 "register_operand" "d")))]
2185 [(set_attr "type" "arith")
2186 (set_attr "mode" "SI")])
2188 (define_expand "anddi3"
2189 [(set (match_operand:DI 0 "register_operand")
2190 (and:DI (match_operand:DI 1 "register_operand")
2191 (match_operand:DI 2 "uns_arith_operand")))]
2196 operands[1] = force_reg (DImode, operands[1]);
2197 operands[2] = force_reg (DImode, operands[2]);
2202 [(set (match_operand:DI 0 "register_operand" "=d,d")
2203 (and:DI (match_operand:DI 1 "register_operand" "d,d")
2204 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2205 "TARGET_64BIT && !TARGET_MIPS16"
2209 [(set_attr "type" "arith")
2210 (set_attr "mode" "DI")])
2213 [(set (match_operand:DI 0 "register_operand" "=d")
2214 (and:DI (match_operand:DI 1 "register_operand" "0")
2215 (match_operand:DI 2 "register_operand" "d")))]
2216 "TARGET_64BIT && TARGET_MIPS16"
2218 [(set_attr "type" "arith")
2219 (set_attr "mode" "DI")])
2221 (define_expand "iorsi3"
2222 [(set (match_operand:SI 0 "register_operand")
2223 (ior:SI (match_operand:SI 1 "uns_arith_operand")
2224 (match_operand:SI 2 "uns_arith_operand")))]
2229 operands[1] = force_reg (SImode, operands[1]);
2230 operands[2] = force_reg (SImode, operands[2]);
2235 [(set (match_operand:SI 0 "register_operand" "=d,d")
2236 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2237 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2242 [(set_attr "type" "arith")
2243 (set_attr "mode" "SI")])
2246 [(set (match_operand:SI 0 "register_operand" "=d")
2247 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2248 (match_operand:SI 2 "register_operand" "d")))]
2251 [(set_attr "type" "arith")
2252 (set_attr "mode" "SI")])
2254 (define_expand "iordi3"
2255 [(set (match_operand:DI 0 "register_operand")
2256 (ior:DI (match_operand:DI 1 "register_operand")
2257 (match_operand:DI 2 "uns_arith_operand")))]
2262 operands[1] = force_reg (DImode, operands[1]);
2263 operands[2] = force_reg (DImode, operands[2]);
2268 [(set (match_operand:DI 0 "register_operand" "=d,d")
2269 (ior:DI (match_operand:DI 1 "register_operand" "d,d")
2270 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2271 "TARGET_64BIT && !TARGET_MIPS16"
2275 [(set_attr "type" "arith")
2276 (set_attr "mode" "DI")])
2279 [(set (match_operand:DI 0 "register_operand" "=d")
2280 (ior:DI (match_operand:DI 1 "register_operand" "0")
2281 (match_operand:DI 2 "register_operand" "d")))]
2282 "TARGET_64BIT && TARGET_MIPS16"
2284 [(set_attr "type" "arith")
2285 (set_attr "mode" "DI")])
2287 (define_expand "xorsi3"
2288 [(set (match_operand:SI 0 "register_operand")
2289 (xor:SI (match_operand:SI 1 "uns_arith_operand")
2290 (match_operand:SI 2 "uns_arith_operand")))]
2295 [(set (match_operand:SI 0 "register_operand" "=d,d")
2296 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2297 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2302 [(set_attr "type" "arith")
2303 (set_attr "mode" "SI")])
2306 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
2307 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
2308 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
2314 [(set_attr "type" "arith")
2315 (set_attr "mode" "SI")
2316 (set_attr_alternative "length"
2318 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2323 (define_expand "xordi3"
2324 [(set (match_operand:DI 0 "register_operand")
2325 (xor:DI (match_operand:DI 1 "register_operand")
2326 (match_operand:DI 2 "uns_arith_operand")))]
2331 operands[1] = force_reg (DImode, operands[1]);
2332 operands[2] = force_reg (DImode, operands[2]);
2337 [(set (match_operand:DI 0 "register_operand" "=d,d")
2338 (xor:DI (match_operand:DI 1 "register_operand" "d,d")
2339 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2340 "TARGET_64BIT && !TARGET_MIPS16"
2344 [(set_attr "type" "arith")
2345 (set_attr "mode" "DI")])
2348 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
2349 (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
2350 (match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
2351 "TARGET_64BIT && TARGET_MIPS16"
2356 [(set_attr "type" "arith")
2357 (set_attr "mode" "DI")
2358 (set_attr_alternative "length"
2360 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2365 (define_insn "*norsi3"
2366 [(set (match_operand:SI 0 "register_operand" "=d")
2367 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
2368 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
2371 [(set_attr "type" "arith")
2372 (set_attr "mode" "SI")])
2374 (define_insn "*nordi3"
2375 [(set (match_operand:DI 0 "register_operand" "=d")
2376 (and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
2377 (not:DI (match_operand:DI 2 "register_operand" "d"))))]
2378 "TARGET_64BIT && !TARGET_MIPS16"
2380 [(set_attr "type" "arith")
2381 (set_attr "mode" "DI")])
2384 ;; ....................
2388 ;; ....................
2392 (define_insn "truncdfsf2"
2393 [(set (match_operand:SF 0 "register_operand" "=f")
2394 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2395 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2397 [(set_attr "type" "fcvt")
2398 (set_attr "mode" "SF")])
2400 ;; Integer truncation patterns. Truncating SImode values to smaller
2401 ;; modes is a no-op, as it is for most other GCC ports. Truncating
2402 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2403 ;; need to make sure that the lower 32 bits are properly sign-extended
2404 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
2405 ;; smaller than SImode is equivalent to two separate truncations:
2408 ;; DI ---> HI == DI ---> SI ---> HI
2409 ;; DI ---> QI == DI ---> SI ---> QI
2411 ;; Step A needs a real instruction but step B does not.
2413 (define_insn "truncdisi2"
2414 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2415 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2420 [(set_attr "type" "shift,store")
2421 (set_attr "mode" "SI")
2422 (set_attr "extended_mips16" "yes,*")])
2424 (define_insn "truncdihi2"
2425 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2426 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2431 [(set_attr "type" "shift,store")
2432 (set_attr "mode" "SI")
2433 (set_attr "extended_mips16" "yes,*")])
2435 (define_insn "truncdiqi2"
2436 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2437 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2442 [(set_attr "type" "shift,store")
2443 (set_attr "mode" "SI")
2444 (set_attr "extended_mips16" "yes,*")])
2446 ;; Combiner patterns to optimize shift/truncate combinations.
2449 [(set (match_operand:SI 0 "register_operand" "=d")
2451 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2452 (match_operand:DI 2 "const_arith_operand" ""))))]
2453 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2455 [(set_attr "type" "shift")
2456 (set_attr "mode" "SI")])
2459 [(set (match_operand:SI 0 "register_operand" "=d")
2460 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2462 "TARGET_64BIT && !TARGET_MIPS16"
2464 [(set_attr "type" "shift")
2465 (set_attr "mode" "SI")])
2468 ;; Combiner patterns for truncate/sign_extend combinations. They use
2469 ;; the shift/truncate patterns above.
2471 (define_insn_and_split ""
2472 [(set (match_operand:SI 0 "register_operand" "=d")
2474 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2475 "TARGET_64BIT && !TARGET_MIPS16"
2477 "&& reload_completed"
2479 (ashift:DI (match_dup 1)
2482 (truncate:SI (ashiftrt:DI (match_dup 2)
2484 { operands[2] = gen_lowpart (DImode, operands[0]); })
2486 (define_insn_and_split ""
2487 [(set (match_operand:SI 0 "register_operand" "=d")
2489 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2490 "TARGET_64BIT && !TARGET_MIPS16"
2492 "&& reload_completed"
2494 (ashift:DI (match_dup 1)
2497 (truncate:SI (ashiftrt:DI (match_dup 2)
2499 { operands[2] = gen_lowpart (DImode, operands[0]); })
2502 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2505 [(set (match_operand:SI 0 "register_operand" "=d")
2506 (zero_extend:SI (truncate:HI
2507 (match_operand:DI 1 "register_operand" "d"))))]
2508 "TARGET_64BIT && !TARGET_MIPS16"
2509 "andi\t%0,%1,0xffff"
2510 [(set_attr "type" "arith")
2511 (set_attr "mode" "SI")])
2514 [(set (match_operand:SI 0 "register_operand" "=d")
2515 (zero_extend:SI (truncate:QI
2516 (match_operand:DI 1 "register_operand" "d"))))]
2517 "TARGET_64BIT && !TARGET_MIPS16"
2519 [(set_attr "type" "arith")
2520 (set_attr "mode" "SI")])
2523 [(set (match_operand:HI 0 "register_operand" "=d")
2524 (zero_extend:HI (truncate:QI
2525 (match_operand:DI 1 "register_operand" "d"))))]
2526 "TARGET_64BIT && !TARGET_MIPS16"
2528 [(set_attr "type" "arith")
2529 (set_attr "mode" "HI")])
2532 ;; ....................
2536 ;; ....................
2539 ;; Those for integer source operand are ordered widest source type first.
2541 (define_insn_and_split "zero_extendsidi2"
2542 [(set (match_operand:DI 0 "register_operand" "=d")
2543 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2546 "&& reload_completed"
2548 (ashift:DI (match_dup 1) (const_int 32)))
2550 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2551 "operands[1] = gen_lowpart (DImode, operands[1]);"
2552 [(set_attr "type" "multi")
2553 (set_attr "mode" "DI")
2554 (set_attr "length" "8")])
2556 (define_insn "*zero_extendsidi2_mem"
2557 [(set (match_operand:DI 0 "register_operand" "=d")
2558 (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2561 [(set_attr "type" "load")
2562 (set_attr "mode" "DI")])
2564 (define_expand "zero_extendhisi2"
2565 [(set (match_operand:SI 0 "register_operand")
2566 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2569 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2571 rtx op = gen_lowpart (SImode, operands[1]);
2572 rtx temp = force_reg (SImode, GEN_INT (0xffff));
2574 emit_insn (gen_andsi3 (operands[0], op, temp));
2580 [(set (match_operand:SI 0 "register_operand" "=d,d")
2581 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2586 [(set_attr "type" "arith,load")
2587 (set_attr "mode" "SI")
2588 (set_attr "length" "4,*")])
2591 [(set (match_operand:SI 0 "register_operand" "=d")
2592 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2595 [(set_attr "type" "load")
2596 (set_attr "mode" "SI")])
2598 (define_expand "zero_extendhidi2"
2599 [(set (match_operand:DI 0 "register_operand")
2600 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2603 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2605 rtx op = gen_lowpart (DImode, operands[1]);
2606 rtx temp = force_reg (DImode, GEN_INT (0xffff));
2608 emit_insn (gen_anddi3 (operands[0], op, temp));
2614 [(set (match_operand:DI 0 "register_operand" "=d,d")
2615 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2616 "TARGET_64BIT && !TARGET_MIPS16"
2620 [(set_attr "type" "arith,load")
2621 (set_attr "mode" "DI")
2622 (set_attr "length" "4,*")])
2625 [(set (match_operand:DI 0 "register_operand" "=d")
2626 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2627 "TARGET_64BIT && TARGET_MIPS16"
2629 [(set_attr "type" "load")
2630 (set_attr "mode" "DI")])
2632 (define_expand "zero_extendqihi2"
2633 [(set (match_operand:HI 0 "register_operand")
2634 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2637 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2639 rtx op0 = gen_lowpart (SImode, operands[0]);
2640 rtx op1 = gen_lowpart (SImode, operands[1]);
2641 rtx temp = force_reg (SImode, GEN_INT (0xff));
2643 emit_insn (gen_andsi3 (op0, op1, temp));
2649 [(set (match_operand:HI 0 "register_operand" "=d,d")
2650 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2655 [(set_attr "type" "arith,load")
2656 (set_attr "mode" "HI")
2657 (set_attr "length" "4,*")])
2660 [(set (match_operand:HI 0 "register_operand" "=d")
2661 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2664 [(set_attr "type" "load")
2665 (set_attr "mode" "HI")])
2667 (define_expand "zero_extendqisi2"
2668 [(set (match_operand:SI 0 "register_operand")
2669 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2672 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2674 rtx op = gen_lowpart (SImode, operands[1]);
2675 rtx temp = force_reg (SImode, GEN_INT (0xff));
2677 emit_insn (gen_andsi3 (operands[0], op, temp));
2683 [(set (match_operand:SI 0 "register_operand" "=d,d")
2684 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2689 [(set_attr "type" "arith,load")
2690 (set_attr "mode" "SI")
2691 (set_attr "length" "4,*")])
2694 [(set (match_operand:SI 0 "register_operand" "=d")
2695 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2698 [(set_attr "type" "load")
2699 (set_attr "mode" "SI")])
2701 (define_expand "zero_extendqidi2"
2702 [(set (match_operand:DI 0 "register_operand")
2703 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2706 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2708 rtx op = gen_lowpart (DImode, operands[1]);
2709 rtx temp = force_reg (DImode, GEN_INT (0xff));
2711 emit_insn (gen_anddi3 (operands[0], op, temp));
2717 [(set (match_operand:DI 0 "register_operand" "=d,d")
2718 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2719 "TARGET_64BIT && !TARGET_MIPS16"
2723 [(set_attr "type" "arith,load")
2724 (set_attr "mode" "DI")
2725 (set_attr "length" "4,*")])
2728 [(set (match_operand:DI 0 "register_operand" "=d")
2729 (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2730 "TARGET_64BIT && TARGET_MIPS16"
2732 [(set_attr "type" "load")
2733 (set_attr "mode" "DI")])
2736 ;; ....................
2740 ;; ....................
2743 ;; Those for integer source operand are ordered widest source type first.
2745 ;; When TARGET_64BIT, all SImode integer registers should already be in
2746 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
2747 ;; therefore get rid of register->register instructions if we constrain
2748 ;; the source to be in the same register as the destination.
2750 ;; The register alternative has type "arith" so that the pre-reload
2751 ;; scheduler will treat it as a move. This reflects what happens if
2752 ;; the register alternative needs a reload.
2753 (define_insn_and_split "extendsidi2"
2754 [(set (match_operand:DI 0 "register_operand" "=d,d")
2755 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2760 "&& reload_completed && register_operand (operands[1], VOIDmode)"
2763 emit_note (NOTE_INSN_DELETED);
2766 [(set_attr "type" "arith,load")
2767 (set_attr "mode" "DI")])
2769 ;; These patterns originally accepted general_operands, however, slightly
2770 ;; better code is generated by only accepting register_operands, and then
2771 ;; letting combine generate the lh and lb insns.
2773 ;; These expanders originally put values in registers first. We split
2774 ;; all non-mem patterns after reload.
2776 (define_expand "extendhidi2"
2777 [(set (match_operand:DI 0 "register_operand")
2778 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2782 (define_insn "*extendhidi2"
2783 [(set (match_operand:DI 0 "register_operand" "=d")
2784 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
2789 [(set (match_operand:DI 0 "register_operand")
2790 (sign_extend:DI (match_operand:HI 1 "register_operand")))]
2791 "TARGET_64BIT && reload_completed"
2793 (ashift:DI (match_dup 1) (const_int 48)))
2795 (ashiftrt:DI (match_dup 0) (const_int 48)))]
2796 "operands[1] = gen_lowpart (DImode, operands[1]);")
2798 (define_insn "*extendhidi2_mem"
2799 [(set (match_operand:DI 0 "register_operand" "=d")
2800 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2803 [(set_attr "type" "load")
2804 (set_attr "mode" "DI")])
2806 (define_expand "extendhisi2"
2807 [(set (match_operand:SI 0 "register_operand")
2808 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2811 if (ISA_HAS_SEB_SEH)
2813 emit_insn (gen_extendhisi2_hw (operands[0],
2814 force_reg (HImode, operands[1])));
2819 (define_insn "*extendhisi2"
2820 [(set (match_operand:SI 0 "register_operand" "=d")
2821 (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
2826 [(set (match_operand:SI 0 "register_operand")
2827 (sign_extend:SI (match_operand:HI 1 "register_operand")))]
2830 (ashift:SI (match_dup 1) (const_int 16)))
2832 (ashiftrt:SI (match_dup 0) (const_int 16)))]
2833 "operands[1] = gen_lowpart (SImode, operands[1]);")
2835 (define_insn "extendhisi2_mem"
2836 [(set (match_operand:SI 0 "register_operand" "=d")
2837 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2840 [(set_attr "type" "load")
2841 (set_attr "mode" "SI")])
2843 (define_insn "extendhisi2_hw"
2844 [(set (match_operand:SI 0 "register_operand" "=r")
2845 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
2848 [(set_attr "type" "arith")
2849 (set_attr "mode" "SI")])
2851 (define_expand "extendqihi2"
2852 [(set (match_operand:HI 0 "register_operand")
2853 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2857 (define_insn "*extendqihi2"
2858 [(set (match_operand:HI 0 "register_operand" "=d")
2859 (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
2864 [(set (match_operand:HI 0 "register_operand")
2865 (sign_extend:HI (match_operand:QI 1 "register_operand")))]
2868 (ashift:SI (match_dup 1) (const_int 24)))
2870 (ashiftrt:SI (match_dup 0) (const_int 24)))]
2871 "operands[0] = gen_lowpart (SImode, operands[0]);
2872 operands[1] = gen_lowpart (SImode, operands[1]);")
2874 (define_insn "*extendqihi2_internal_mem"
2875 [(set (match_operand:HI 0 "register_operand" "=d")
2876 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2879 [(set_attr "type" "load")
2880 (set_attr "mode" "SI")])
2883 (define_expand "extendqisi2"
2884 [(set (match_operand:SI 0 "register_operand")
2885 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2888 if (ISA_HAS_SEB_SEH)
2890 emit_insn (gen_extendqisi2_hw (operands[0],
2891 force_reg (QImode, operands[1])));
2896 (define_insn "*extendqisi2"
2897 [(set (match_operand:SI 0 "register_operand" "=d")
2898 (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
2903 [(set (match_operand:SI 0 "register_operand")
2904 (sign_extend:SI (match_operand:QI 1 "register_operand")))]
2907 (ashift:SI (match_dup 1) (const_int 24)))
2909 (ashiftrt:SI (match_dup 0) (const_int 24)))]
2910 "operands[1] = gen_lowpart (SImode, operands[1]);")
2912 (define_insn "*extendqisi2_mem"
2913 [(set (match_operand:SI 0 "register_operand" "=d")
2914 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2917 [(set_attr "type" "load")
2918 (set_attr "mode" "SI")])
2920 (define_insn "extendqisi2_hw"
2921 [(set (match_operand:SI 0 "register_operand" "=r")
2922 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
2925 [(set_attr "type" "arith")
2926 (set_attr "mode" "SI")])
2928 (define_expand "extendqidi2"
2929 [(set (match_operand:DI 0 "register_operand")
2930 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2934 (define_insn "*extendqidi2"
2935 [(set (match_operand:DI 0 "register_operand" "=d")
2936 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
2941 [(set (match_operand:DI 0 "register_operand")
2942 (sign_extend:DI (match_operand:QI 1 "register_operand")))]
2943 "TARGET_64BIT && reload_completed"
2945 (ashift:DI (match_dup 1) (const_int 56)))
2947 (ashiftrt:DI (match_dup 0) (const_int 56)))]
2948 "operands[1] = gen_lowpart (DImode, operands[1]);")
2950 (define_insn "*extendqidi2_mem"
2951 [(set (match_operand:DI 0 "register_operand" "=d")
2952 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2955 [(set_attr "type" "load")
2956 (set_attr "mode" "DI")])
2958 (define_insn "extendsfdf2"
2959 [(set (match_operand:DF 0 "register_operand" "=f")
2960 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2961 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2963 [(set_attr "type" "fcvt")
2964 (set_attr "mode" "DF")])
2967 ;; ....................
2971 ;; ....................
2973 (define_expand "fix_truncdfsi2"
2974 [(set (match_operand:SI 0 "register_operand")
2975 (fix:SI (match_operand:DF 1 "register_operand")))]
2976 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2978 if (!ISA_HAS_TRUNC_W)
2980 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2985 (define_insn "fix_truncdfsi2_insn"
2986 [(set (match_operand:SI 0 "register_operand" "=f")
2987 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2988 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2990 [(set_attr "type" "fcvt")
2991 (set_attr "mode" "DF")
2992 (set_attr "length" "4")])
2994 (define_insn "fix_truncdfsi2_macro"
2995 [(set (match_operand:SI 0 "register_operand" "=f")
2996 (fix:SI (match_operand:DF 1 "register_operand" "f")))
2997 (clobber (match_scratch:DF 2 "=d"))]
2998 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3001 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3003 return "trunc.w.d %0,%1,%2";
3005 [(set_attr "type" "fcvt")
3006 (set_attr "mode" "DF")
3007 (set_attr "length" "36")])
3009 (define_expand "fix_truncsfsi2"
3010 [(set (match_operand:SI 0 "register_operand")
3011 (fix:SI (match_operand:SF 1 "register_operand")))]
3014 if (!ISA_HAS_TRUNC_W)
3016 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3021 (define_insn "fix_truncsfsi2_insn"
3022 [(set (match_operand:SI 0 "register_operand" "=f")
3023 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3024 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3026 [(set_attr "type" "fcvt")
3027 (set_attr "mode" "DF")
3028 (set_attr "length" "4")])
3030 (define_insn "fix_truncsfsi2_macro"
3031 [(set (match_operand:SI 0 "register_operand" "=f")
3032 (fix:SI (match_operand:SF 1 "register_operand" "f")))
3033 (clobber (match_scratch:SF 2 "=d"))]
3034 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3037 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3039 return "trunc.w.s %0,%1,%2";
3041 [(set_attr "type" "fcvt")
3042 (set_attr "mode" "DF")
3043 (set_attr "length" "36")])
3046 (define_insn "fix_truncdfdi2"
3047 [(set (match_operand:DI 0 "register_operand" "=f")
3048 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3049 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3051 [(set_attr "type" "fcvt")
3052 (set_attr "mode" "DF")
3053 (set_attr "length" "4")])
3056 (define_insn "fix_truncsfdi2"
3057 [(set (match_operand:DI 0 "register_operand" "=f")
3058 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3059 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3061 [(set_attr "type" "fcvt")
3062 (set_attr "mode" "SF")
3063 (set_attr "length" "4")])
3066 (define_insn "floatsidf2"
3067 [(set (match_operand:DF 0 "register_operand" "=f")
3068 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3069 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3071 [(set_attr "type" "fcvt")
3072 (set_attr "mode" "DF")
3073 (set_attr "length" "4")])
3076 (define_insn "floatdidf2"
3077 [(set (match_operand:DF 0 "register_operand" "=f")
3078 (float:DF (match_operand:DI 1 "register_operand" "f")))]
3079 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3081 [(set_attr "type" "fcvt")
3082 (set_attr "mode" "DF")
3083 (set_attr "length" "4")])
3086 (define_insn "floatsisf2"
3087 [(set (match_operand:SF 0 "register_operand" "=f")
3088 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3091 [(set_attr "type" "fcvt")
3092 (set_attr "mode" "SF")
3093 (set_attr "length" "4")])
3096 (define_insn "floatdisf2"
3097 [(set (match_operand:SF 0 "register_operand" "=f")
3098 (float:SF (match_operand:DI 1 "register_operand" "f")))]
3099 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3101 [(set_attr "type" "fcvt")
3102 (set_attr "mode" "SF")
3103 (set_attr "length" "4")])
3106 (define_expand "fixuns_truncdfsi2"
3107 [(set (match_operand:SI 0 "register_operand")
3108 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
3109 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3111 rtx reg1 = gen_reg_rtx (DFmode);
3112 rtx reg2 = gen_reg_rtx (DFmode);
3113 rtx reg3 = gen_reg_rtx (SImode);
3114 rtx label1 = gen_label_rtx ();
3115 rtx label2 = gen_label_rtx ();
3116 REAL_VALUE_TYPE offset;
3118 real_2expN (&offset, 31);
3120 if (reg1) /* Turn off complaints about unreached code. */
3122 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3123 do_pending_stack_adjust ();
3125 emit_insn (gen_cmpdf (operands[1], reg1));
3126 emit_jump_insn (gen_bge (label1));
3128 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3129 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3130 gen_rtx_LABEL_REF (VOIDmode, label2)));
3133 emit_label (label1);
3134 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3135 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3136 (BITMASK_HIGH, SImode)));
3138 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3139 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3141 emit_label (label2);
3143 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3144 fields, and can't be used for REG_NOTES anyway). */
3145 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3151 (define_expand "fixuns_truncdfdi2"
3152 [(set (match_operand:DI 0 "register_operand")
3153 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3154 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3156 rtx reg1 = gen_reg_rtx (DFmode);
3157 rtx reg2 = gen_reg_rtx (DFmode);
3158 rtx reg3 = gen_reg_rtx (DImode);
3159 rtx label1 = gen_label_rtx ();
3160 rtx label2 = gen_label_rtx ();
3161 REAL_VALUE_TYPE offset;
3163 real_2expN (&offset, 63);
3165 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3166 do_pending_stack_adjust ();
3168 emit_insn (gen_cmpdf (operands[1], reg1));
3169 emit_jump_insn (gen_bge (label1));
3171 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3172 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3173 gen_rtx_LABEL_REF (VOIDmode, label2)));
3176 emit_label (label1);
3177 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3178 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3179 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3181 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3182 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3184 emit_label (label2);
3186 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3187 fields, and can't be used for REG_NOTES anyway). */
3188 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3193 (define_expand "fixuns_truncsfsi2"
3194 [(set (match_operand:SI 0 "register_operand")
3195 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3198 rtx reg1 = gen_reg_rtx (SFmode);
3199 rtx reg2 = gen_reg_rtx (SFmode);
3200 rtx reg3 = gen_reg_rtx (SImode);
3201 rtx label1 = gen_label_rtx ();
3202 rtx label2 = gen_label_rtx ();
3203 REAL_VALUE_TYPE offset;
3205 real_2expN (&offset, 31);
3207 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3208 do_pending_stack_adjust ();
3210 emit_insn (gen_cmpsf (operands[1], reg1));
3211 emit_jump_insn (gen_bge (label1));
3213 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3214 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3215 gen_rtx_LABEL_REF (VOIDmode, label2)));
3218 emit_label (label1);
3219 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3220 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3221 (BITMASK_HIGH, SImode)));
3223 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3224 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3226 emit_label (label2);
3228 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3229 fields, and can't be used for REG_NOTES anyway). */
3230 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3235 (define_expand "fixuns_truncsfdi2"
3236 [(set (match_operand:DI 0 "register_operand")
3237 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3238 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3240 rtx reg1 = gen_reg_rtx (SFmode);
3241 rtx reg2 = gen_reg_rtx (SFmode);
3242 rtx reg3 = gen_reg_rtx (DImode);
3243 rtx label1 = gen_label_rtx ();
3244 rtx label2 = gen_label_rtx ();
3245 REAL_VALUE_TYPE offset;
3247 real_2expN (&offset, 63);
3249 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3250 do_pending_stack_adjust ();
3252 emit_insn (gen_cmpsf (operands[1], reg1));
3253 emit_jump_insn (gen_bge (label1));
3255 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3256 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3257 gen_rtx_LABEL_REF (VOIDmode, label2)));
3260 emit_label (label1);
3261 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3262 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3263 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3265 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3266 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3268 emit_label (label2);
3270 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3271 fields, and can't be used for REG_NOTES anyway). */
3272 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3277 ;; ....................
3281 ;; ....................
3283 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3285 (define_expand "extv"
3286 [(set (match_operand 0 "register_operand")
3287 (sign_extract (match_operand:QI 1 "memory_operand")
3288 (match_operand 2 "immediate_operand")
3289 (match_operand 3 "immediate_operand")))]
3292 if (mips_expand_unaligned_load (operands[0], operands[1],
3293 INTVAL (operands[2]),
3294 INTVAL (operands[3])))
3300 (define_expand "extzv"
3301 [(set (match_operand 0 "register_operand")
3302 (zero_extract (match_operand:QI 1 "memory_operand")
3303 (match_operand 2 "immediate_operand")
3304 (match_operand 3 "immediate_operand")))]
3307 if (mips_expand_unaligned_load (operands[0], operands[1],
3308 INTVAL (operands[2]),
3309 INTVAL (operands[3])))
3315 (define_expand "insv"
3316 [(set (zero_extract (match_operand:QI 0 "memory_operand")
3317 (match_operand 1 "immediate_operand")
3318 (match_operand 2 "immediate_operand"))
3319 (match_operand 3 "reg_or_0_operand"))]
3322 if (mips_expand_unaligned_store (operands[0], operands[3],
3323 INTVAL (operands[1]),
3324 INTVAL (operands[2])))
3330 ;; Unaligned word moves generated by the bit field patterns.
3332 ;; As far as the rtl is concerned, both the left-part and right-part
3333 ;; instructions can access the whole field. However, the real operand
3334 ;; refers to just the first or the last byte (depending on endianness).
3335 ;; We therefore use two memory operands to each instruction, one to
3336 ;; describe the rtl effect and one to use in the assembly output.
3338 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3339 ;; This allows us to use the standard length calculations for the "load"
3340 ;; and "store" type attributes.
3342 (define_insn "mov_lwl"
3343 [(set (match_operand:SI 0 "register_operand" "=d")
3344 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3345 (match_operand:QI 2 "memory_operand" "m")]
3349 [(set_attr "type" "load")
3350 (set_attr "mode" "SI")
3351 (set_attr "hazard" "none")])
3353 (define_insn "mov_lwr"
3354 [(set (match_operand:SI 0 "register_operand" "=d")
3355 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3356 (match_operand:QI 2 "memory_operand" "m")
3357 (match_operand:SI 3 "register_operand" "0")]
3361 [(set_attr "type" "load")
3362 (set_attr "mode" "SI")])
3365 (define_insn "mov_swl"
3366 [(set (match_operand:BLK 0 "memory_operand" "=m")
3367 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3368 (match_operand:QI 2 "memory_operand" "m")]
3372 [(set_attr "type" "store")
3373 (set_attr "mode" "SI")])
3375 (define_insn "mov_swr"
3376 [(set (match_operand:BLK 0 "memory_operand" "+m")
3377 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3378 (match_operand:QI 2 "memory_operand" "m")
3383 [(set_attr "type" "store")
3384 (set_attr "mode" "SI")])
3387 (define_insn "mov_ldl"
3388 [(set (match_operand:DI 0 "register_operand" "=d")
3389 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3390 (match_operand:QI 2 "memory_operand" "m")]
3392 "TARGET_64BIT && !TARGET_MIPS16"
3394 [(set_attr "type" "load")
3395 (set_attr "mode" "DI")])
3397 (define_insn "mov_ldr"
3398 [(set (match_operand:DI 0 "register_operand" "=d")
3399 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3400 (match_operand:QI 2 "memory_operand" "m")
3401 (match_operand:DI 3 "register_operand" "0")]
3403 "TARGET_64BIT && !TARGET_MIPS16"
3405 [(set_attr "type" "load")
3406 (set_attr "mode" "DI")])
3409 (define_insn "mov_sdl"
3410 [(set (match_operand:BLK 0 "memory_operand" "=m")
3411 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3412 (match_operand:QI 2 "memory_operand" "m")]
3414 "TARGET_64BIT && !TARGET_MIPS16"
3416 [(set_attr "type" "store")
3417 (set_attr "mode" "DI")])
3419 (define_insn "mov_sdr"
3420 [(set (match_operand:BLK 0 "memory_operand" "+m")
3421 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3422 (match_operand:QI 2 "memory_operand" "m")
3425 "TARGET_64BIT && !TARGET_MIPS16"
3427 [(set_attr "type" "store")
3428 (set_attr "mode" "DI")])
3430 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3431 ;; The required value is:
3433 ;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3435 ;; which translates to:
3437 ;; lui op0,%highest(op1)
3438 ;; daddiu op0,op0,%higher(op1)
3440 ;; daddiu op0,op0,%hi(op1)
3442 (define_insn_and_split "*lea_high64"
3443 [(set (match_operand:DI 0 "register_operand" "=d")
3444 (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3445 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3447 "&& reload_completed"
3448 [(set (match_dup 0) (high:DI (match_dup 2)))
3449 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3450 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3451 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3452 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3454 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3455 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3457 [(set_attr "length" "20")])
3459 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3460 ;; SYMBOL_GENERAL X will take 6 cycles. This next pattern allows combine
3461 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3462 ;; used once. We can then use the sequence:
3464 ;; lui op0,%highest(op1)
3466 ;; daddiu op0,op0,%higher(op1)
3467 ;; daddiu op2,op2,%lo(op1)
3469 ;; daddu op0,op0,op2
3471 ;; which takes 4 cycles on most superscalar targets.
3472 (define_insn_and_split "*lea64"
3473 [(set (match_operand:DI 0 "register_operand" "=d")
3474 (match_operand:DI 1 "general_symbolic_operand" ""))
3475 (clobber (match_scratch:DI 2 "=&d"))]
3476 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3478 "&& reload_completed"
3479 [(set (match_dup 0) (high:DI (match_dup 3)))
3480 (set (match_dup 2) (high:DI (match_dup 4)))
3481 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3482 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3483 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3484 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3486 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3487 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3489 [(set_attr "length" "24")])
3491 ;; Insns to fetch a global symbol from a big GOT.
3493 (define_insn_and_split "*xgot_hisi"
3494 [(set (match_operand:SI 0 "register_operand" "=d")
3495 (high:SI (match_operand:SI 1 "global_got_operand" "")))]
3496 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3498 "&& reload_completed"
3499 [(set (match_dup 0) (high:SI (match_dup 2)))
3500 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
3502 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3503 operands[3] = pic_offset_table_rtx;
3505 [(set_attr "got" "xgot_high")])
3507 (define_insn_and_split "*xgot_losi"
3508 [(set (match_operand:SI 0 "register_operand" "=d")
3509 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
3510 (match_operand:SI 2 "global_got_operand" "")))]
3511 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3513 "&& reload_completed"
3515 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3516 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3517 [(set_attr "got" "load")])
3519 (define_insn_and_split "*xgot_hidi"
3520 [(set (match_operand:DI 0 "register_operand" "=d")
3521 (high:DI (match_operand:DI 1 "global_got_operand" "")))]
3522 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3524 "&& reload_completed"
3525 [(set (match_dup 0) (high:DI (match_dup 2)))
3526 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
3528 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3529 operands[3] = pic_offset_table_rtx;
3531 [(set_attr "got" "xgot_high")])
3533 (define_insn_and_split "*xgot_lodi"
3534 [(set (match_operand:DI 0 "register_operand" "=d")
3535 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
3536 (match_operand:DI 2 "global_got_operand" "")))]
3537 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3539 "&& reload_completed"
3541 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3542 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3543 [(set_attr "got" "load")])
3545 ;; Insns to fetch a global symbol from a normal GOT.
3547 (define_insn_and_split "*got_dispsi"
3548 [(set (match_operand:SI 0 "register_operand" "=d")
3549 (match_operand:SI 1 "global_got_operand" ""))]
3550 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3552 "&& reload_completed"
3554 (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3556 operands[2] = pic_offset_table_rtx;
3557 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3559 [(set_attr "got" "load")])
3561 (define_insn_and_split "*got_dispdi"
3562 [(set (match_operand:DI 0 "register_operand" "=d")
3563 (match_operand:DI 1 "global_got_operand" ""))]
3564 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3566 "&& reload_completed"
3568 (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3570 operands[2] = pic_offset_table_rtx;
3571 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3573 [(set_attr "got" "load")])
3575 ;; Insns for loading the high part of a local symbol.
3577 (define_insn_and_split "*got_pagesi"
3578 [(set (match_operand:SI 0 "register_operand" "=d")
3579 (high:SI (match_operand:SI 1 "local_got_operand" "")))]
3580 "TARGET_EXPLICIT_RELOCS"
3582 "&& reload_completed"
3584 (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3586 operands[2] = pic_offset_table_rtx;
3587 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3589 [(set_attr "got" "load")])
3591 (define_insn_and_split "*got_pagedi"
3592 [(set (match_operand:DI 0 "register_operand" "=d")
3593 (high:DI (match_operand:DI 1 "local_got_operand" "")))]
3594 "TARGET_EXPLICIT_RELOCS"
3596 "&& reload_completed"
3598 (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3600 operands[2] = pic_offset_table_rtx;
3601 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3603 [(set_attr "got" "load")])
3605 ;; Lower-level instructions for loading an address from the GOT.
3606 ;; We could use MEMs, but an unspec gives more optimization
3609 (define_insn "*load_gotsi"
3610 [(set (match_operand:SI 0 "register_operand" "=d")
3611 (unspec:SI [(match_operand:SI 1 "register_operand" "d")
3612 (match_operand:SI 2 "immediate_operand" "")]
3616 [(set_attr "type" "load")
3617 (set_attr "length" "4")])
3619 (define_insn "*load_gotdi"
3620 [(set (match_operand:DI 0 "register_operand" "=d")
3621 (unspec:DI [(match_operand:DI 1 "register_operand" "d")
3622 (match_operand:DI 2 "immediate_operand" "")]
3626 [(set_attr "type" "load")
3627 (set_attr "length" "4")])
3629 ;; Instructions for adding the low 16 bits of an address to a register.
3630 ;; Operand 2 is the address: print_operand works out which relocation
3631 ;; should be applied.
3633 (define_insn "*lowsi"
3634 [(set (match_operand:SI 0 "register_operand" "=d")
3635 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
3636 (match_operand:SI 2 "immediate_operand" "")))]
3639 [(set_attr "type" "arith")
3640 (set_attr "mode" "SI")])
3642 (define_insn "*lowdi"
3643 [(set (match_operand:DI 0 "register_operand" "=d")
3644 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
3645 (match_operand:DI 2 "immediate_operand" "")))]
3646 "!TARGET_MIPS16 && TARGET_64BIT"
3648 [(set_attr "type" "arith")
3649 (set_attr "mode" "DI")])
3651 (define_insn "*lowsi_mips16"
3652 [(set (match_operand:SI 0 "register_operand" "=d")
3653 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
3654 (match_operand:SI 2 "immediate_operand" "")))]
3657 [(set_attr "type" "arith")
3658 (set_attr "mode" "SI")
3659 (set_attr "length" "8")])
3661 (define_insn "*lowdi_mips16"
3662 [(set (match_operand:DI 0 "register_operand" "=d")
3663 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
3664 (match_operand:DI 2 "immediate_operand" "")))]
3665 "TARGET_MIPS16 && TARGET_64BIT"
3667 [(set_attr "type" "arith")
3668 (set_attr "mode" "DI")
3669 (set_attr "length" "8")])
3671 ;; 64-bit integer moves
3673 ;; Unlike most other insns, the move insns can't be split with
3674 ;; different predicates, because register spilling and other parts of
3675 ;; the compiler, have memoized the insn number already.
3677 (define_expand "movdi"
3678 [(set (match_operand:DI 0 "")
3679 (match_operand:DI 1 ""))]
3682 if (mips_legitimize_move (DImode, operands[0], operands[1]))
3686 ;; For mips16, we need a special case to handle storing $31 into
3687 ;; memory, since we don't have a constraint to match $31. This
3688 ;; instruction can be generated by save_restore_insns.
3691 [(set (match_operand:DI 0 "stack_operand" "=m")
3693 "TARGET_MIPS16 && TARGET_64BIT"
3695 [(set_attr "type" "store")
3696 (set_attr "mode" "DI")])
3698 (define_insn "*movdi_32bit"
3699 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
3700 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
3701 "!TARGET_64BIT && !TARGET_MIPS16
3702 && (register_operand (operands[0], DImode)
3703 || reg_or_0_operand (operands[1], DImode))"
3704 { return mips_output_move (operands[0], operands[1]); }
3705 [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
3706 (set_attr "mode" "DI")
3707 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
3709 (define_insn "*movdi_32bit_mips16"
3710 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3711 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3712 "!TARGET_64BIT && TARGET_MIPS16
3713 && (register_operand (operands[0], DImode)
3714 || register_operand (operands[1], DImode))"
3715 { return mips_output_move (operands[0], operands[1]); }
3716 [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo")
3717 (set_attr "mode" "DI")
3718 (set_attr "length" "8,8,8,8,12,*,*,8")])
3720 (define_insn "*movdi_64bit"
3721 [(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")
3722 (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"))]
3723 "TARGET_64BIT && !TARGET_MIPS16
3724 && (register_operand (operands[0], DImode)
3725 || reg_or_0_operand (operands[1], DImode))"
3726 { return mips_output_move (operands[0], operands[1]); }
3727 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
3728 (set_attr "mode" "DI")
3729 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3731 (define_insn "*movdi_64bit_mips16"
3732 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3733 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3734 "TARGET_64BIT && TARGET_MIPS16
3735 && (register_operand (operands[0], DImode)
3736 || register_operand (operands[1], DImode))"
3737 { return mips_output_move (operands[0], operands[1]); }
3738 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
3739 (set_attr "mode" "DI")
3740 (set_attr_alternative "length"
3744 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3747 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3752 (const_string "*")])])
3755 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
3756 ;; when the original load is a 4 byte instruction but the add and the
3757 ;; load are 2 2 byte instructions.
3760 [(set (match_operand:DI 0 "register_operand")
3761 (mem:DI (plus:DI (match_dup 0)
3762 (match_operand:DI 1 "const_int_operand"))))]
3763 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3764 && !TARGET_DEBUG_D_MODE
3765 && GET_CODE (operands[0]) == REG
3766 && M16_REG_P (REGNO (operands[0]))
3767 && GET_CODE (operands[1]) == CONST_INT
3768 && ((INTVAL (operands[1]) < 0
3769 && INTVAL (operands[1]) >= -0x10)
3770 || (INTVAL (operands[1]) >= 32 * 8
3771 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3772 || (INTVAL (operands[1]) >= 0
3773 && INTVAL (operands[1]) < 32 * 8
3774 && (INTVAL (operands[1]) & 7) != 0))"
3775 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3776 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3778 HOST_WIDE_INT val = INTVAL (operands[1]);
3781 operands[2] = const0_rtx;
3782 else if (val >= 32 * 8)
3786 operands[1] = GEN_INT (0x8 + off);
3787 operands[2] = GEN_INT (val - off - 0x8);
3793 operands[1] = GEN_INT (off);
3794 operands[2] = GEN_INT (val - off);
3798 ;; 32-bit Integer moves
3800 ;; Unlike most other insns, the move insns can't be split with
3801 ;; different predicates, because register spilling and other parts of
3802 ;; the compiler, have memoized the insn number already.
3804 (define_expand "movsi"
3805 [(set (match_operand:SI 0 "")
3806 (match_operand:SI 1 ""))]
3809 if (mips_legitimize_move (SImode, operands[0], operands[1]))
3813 ;; We can only store $ra directly into a small sp offset.
3816 [(set (match_operand:SI 0 "stack_operand" "=m")
3820 [(set_attr "type" "store")
3821 (set_attr "mode" "SI")])
3823 ;; The difference between these two is whether or not ints are allowed
3824 ;; in FP registers (off by default, use -mdebugh to enable).
3826 (define_insn "*movsi_internal"
3827 [(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")
3828 (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"))]
3830 && (register_operand (operands[0], SImode)
3831 || reg_or_0_operand (operands[1], SImode))"
3832 { return mips_output_move (operands[0], operands[1]); }
3833 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
3834 (set_attr "mode" "SI")
3835 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
3837 (define_insn "*movsi_mips16"
3838 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3839 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3841 && (register_operand (operands[0], SImode)
3842 || register_operand (operands[1], SImode))"
3843 { return mips_output_move (operands[0], operands[1]); }
3844 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
3845 (set_attr "mode" "SI")
3846 (set_attr_alternative "length"
3850 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3853 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3858 (const_string "*")])])
3860 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
3861 ;; when the original load is a 4 byte instruction but the add and the
3862 ;; load are 2 2 byte instructions.
3865 [(set (match_operand:SI 0 "register_operand")
3866 (mem:SI (plus:SI (match_dup 0)
3867 (match_operand:SI 1 "const_int_operand"))))]
3868 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3869 && GET_CODE (operands[0]) == REG
3870 && M16_REG_P (REGNO (operands[0]))
3871 && GET_CODE (operands[1]) == CONST_INT
3872 && ((INTVAL (operands[1]) < 0
3873 && INTVAL (operands[1]) >= -0x80)
3874 || (INTVAL (operands[1]) >= 32 * 4
3875 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3876 || (INTVAL (operands[1]) >= 0
3877 && INTVAL (operands[1]) < 32 * 4
3878 && (INTVAL (operands[1]) & 3) != 0))"
3879 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3880 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3882 HOST_WIDE_INT val = INTVAL (operands[1]);
3885 operands[2] = const0_rtx;
3886 else if (val >= 32 * 4)
3890 operands[1] = GEN_INT (0x7c + off);
3891 operands[2] = GEN_INT (val - off - 0x7c);
3897 operands[1] = GEN_INT (off);
3898 operands[2] = GEN_INT (val - off);
3902 ;; On the mips16, we can split a load of certain constants into a load
3903 ;; and an add. This turns a 4 byte instruction into 2 2 byte
3907 [(set (match_operand:SI 0 "register_operand")
3908 (match_operand:SI 1 "const_int_operand"))]
3909 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3910 && GET_CODE (operands[0]) == REG
3911 && M16_REG_P (REGNO (operands[0]))
3912 && GET_CODE (operands[1]) == CONST_INT
3913 && INTVAL (operands[1]) >= 0x100
3914 && INTVAL (operands[1]) <= 0xff + 0x7f"
3915 [(set (match_dup 0) (match_dup 1))
3916 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3918 int val = INTVAL (operands[1]);
3920 operands[1] = GEN_INT (0xff);
3921 operands[2] = GEN_INT (val - 0xff);
3924 ;; This insn handles moving CCmode values. It's really just a
3925 ;; slightly simplified copy of movsi_internal2, with additional cases
3926 ;; to move a condition register to a general register and to move
3927 ;; between the general registers and the floating point registers.
3929 (define_insn "movcc"
3930 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3931 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3932 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3933 { return mips_output_move (operands[0], operands[1]); }
3934 [(set_attr "type" "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
3935 (set_attr "mode" "SI")
3936 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
3938 ;; Reload condition code registers. reload_incc and reload_outcc
3939 ;; both handle moves from arbitrary operands into condition code
3940 ;; registers. reload_incc handles the more common case in which
3941 ;; a source operand is constrained to be in a condition-code
3942 ;; register, but has not been allocated to one.
3944 ;; Sometimes, such as in movcc, we have a CCmode destination whose
3945 ;; constraints do not include 'z'. reload_outcc handles the case
3946 ;; when such an operand is allocated to a condition-code register.
3948 ;; Note that reloads from a condition code register to some
3949 ;; other location can be done using ordinary moves. Moving
3950 ;; into a GPR takes a single movcc, moving elsewhere takes
3951 ;; two. We can leave these cases to the generic reload code.
3952 (define_expand "reload_incc"
3953 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3954 (match_operand:CC 1 "general_operand" ""))
3955 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3956 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3958 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3962 (define_expand "reload_outcc"
3963 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3964 (match_operand:CC 1 "register_operand" ""))
3965 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3966 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3968 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3972 ;; MIPS4 supports loading and storing a floating point register from
3973 ;; the sum of two general registers. We use two versions for each of
3974 ;; these four instructions: one where the two general registers are
3975 ;; SImode, and one where they are DImode. This is because general
3976 ;; registers will be in SImode when they hold 32 bit values, but,
3977 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
3978 ;; instructions will still work correctly.
3980 ;; ??? Perhaps it would be better to support these instructions by
3981 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
3982 ;; these instructions can only be used to load and store floating
3983 ;; point registers, that would probably cause trouble in reload.
3986 [(set (match_operand:SF 0 "register_operand" "=f")
3987 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
3988 (match_operand:SI 2 "register_operand" "d"))))]
3989 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
3991 [(set_attr "type" "fpidxload")
3992 (set_attr "mode" "SF")
3993 (set_attr "length" "4")])
3996 [(set (match_operand:SF 0 "register_operand" "=f")
3997 (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
3998 (match_operand:DI 2 "register_operand" "d"))))]
3999 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4001 [(set_attr "type" "fpidxload")
4002 (set_attr "mode" "SF")
4003 (set_attr "length" "4")])
4006 [(set (match_operand:DF 0 "register_operand" "=f")
4007 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4008 (match_operand:SI 2 "register_operand" "d"))))]
4009 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4011 [(set_attr "type" "fpidxload")
4012 (set_attr "mode" "DF")
4013 (set_attr "length" "4")])
4016 [(set (match_operand:DF 0 "register_operand" "=f")
4017 (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4018 (match_operand:DI 2 "register_operand" "d"))))]
4019 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4021 [(set_attr "type" "fpidxload")
4022 (set_attr "mode" "DF")
4023 (set_attr "length" "4")])
4026 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4027 (match_operand:SI 2 "register_operand" "d")))
4028 (match_operand:SF 0 "register_operand" "f"))]
4029 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4031 [(set_attr "type" "fpidxstore")
4032 (set_attr "mode" "SF")
4033 (set_attr "length" "4")])
4036 [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4037 (match_operand:DI 2 "register_operand" "d")))
4038 (match_operand:SF 0 "register_operand" "f"))]
4039 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4041 [(set_attr "type" "fpidxstore")
4042 (set_attr "mode" "SF")
4043 (set_attr "length" "4")])
4046 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4047 (match_operand:SI 2 "register_operand" "d")))
4048 (match_operand:DF 0 "register_operand" "f"))]
4049 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4051 [(set_attr "type" "fpidxstore")
4052 (set_attr "mode" "DF")
4053 (set_attr "length" "4")])
4056 [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4057 (match_operand:DI 2 "register_operand" "d")))
4058 (match_operand:DF 0 "register_operand" "f"))]
4059 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4061 [(set_attr "type" "fpidxstore")
4062 (set_attr "mode" "DF")
4063 (set_attr "length" "4")])
4065 ;; 16-bit Integer moves
4067 ;; Unlike most other insns, the move insns can't be split with
4068 ;; different predicates, because register spilling and other parts of
4069 ;; the compiler, have memoized the insn number already.
4070 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4072 (define_expand "movhi"
4073 [(set (match_operand:HI 0 "")
4074 (match_operand:HI 1 ""))]
4077 if (mips_legitimize_move (HImode, operands[0], operands[1]))
4081 (define_insn "*movhi_internal"
4082 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4083 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4085 && (register_operand (operands[0], HImode)
4086 || reg_or_0_operand (operands[1], HImode))"
4096 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4097 (set_attr "mode" "HI")
4098 (set_attr "length" "4,4,*,*,4,4,4,4")])
4100 (define_insn "*movhi_mips16"
4101 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4102 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))]
4104 && (register_operand (operands[0], HImode)
4105 || register_operand (operands[1], HImode))"
4114 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4115 (set_attr "mode" "HI")
4116 (set_attr_alternative "length"
4120 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4123 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4127 (const_string "*")])])
4130 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4131 ;; when the original load is a 4 byte instruction but the add and the
4132 ;; load are 2 2 byte instructions.
4135 [(set (match_operand:HI 0 "register_operand")
4136 (mem:HI (plus:SI (match_dup 0)
4137 (match_operand:SI 1 "const_int_operand"))))]
4138 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4139 && GET_CODE (operands[0]) == REG
4140 && M16_REG_P (REGNO (operands[0]))
4141 && GET_CODE (operands[1]) == CONST_INT
4142 && ((INTVAL (operands[1]) < 0
4143 && INTVAL (operands[1]) >= -0x80)
4144 || (INTVAL (operands[1]) >= 32 * 2
4145 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4146 || (INTVAL (operands[1]) >= 0
4147 && INTVAL (operands[1]) < 32 * 2
4148 && (INTVAL (operands[1]) & 1) != 0))"
4149 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4150 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4152 HOST_WIDE_INT val = INTVAL (operands[1]);
4155 operands[2] = const0_rtx;
4156 else if (val >= 32 * 2)
4160 operands[1] = GEN_INT (0x7e + off);
4161 operands[2] = GEN_INT (val - off - 0x7e);
4167 operands[1] = GEN_INT (off);
4168 operands[2] = GEN_INT (val - off);
4172 ;; 8-bit Integer moves
4174 ;; Unlike most other insns, the move insns can't be split with
4175 ;; different predicates, because register spilling and other parts of
4176 ;; the compiler, have memoized the insn number already.
4177 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4179 (define_expand "movqi"
4180 [(set (match_operand:QI 0 "")
4181 (match_operand:QI 1 ""))]
4184 if (mips_legitimize_move (QImode, operands[0], operands[1]))
4188 (define_insn "*movqi_internal"
4189 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4190 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4192 && (register_operand (operands[0], QImode)
4193 || reg_or_0_operand (operands[1], QImode))"
4203 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4204 (set_attr "mode" "QI")
4205 (set_attr "length" "4,4,*,*,4,4,4,4")])
4207 (define_insn "*movqi_mips16"
4208 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4209 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))]
4211 && (register_operand (operands[0], QImode)
4212 || register_operand (operands[1], QImode))"
4221 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4222 (set_attr "mode" "QI")
4223 (set_attr "length" "4,4,4,4,8,*,*")])
4225 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
4226 ;; when the original load is a 4 byte instruction but the add and the
4227 ;; load are 2 2 byte instructions.
4230 [(set (match_operand:QI 0 "register_operand")
4231 (mem:QI (plus:SI (match_dup 0)
4232 (match_operand:SI 1 "const_int_operand"))))]
4233 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4234 && GET_CODE (operands[0]) == REG
4235 && M16_REG_P (REGNO (operands[0]))
4236 && GET_CODE (operands[1]) == CONST_INT
4237 && ((INTVAL (operands[1]) < 0
4238 && INTVAL (operands[1]) >= -0x80)
4239 || (INTVAL (operands[1]) >= 32
4240 && INTVAL (operands[1]) <= 31 + 0x7f))"
4241 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4242 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4244 HOST_WIDE_INT val = INTVAL (operands[1]);
4247 operands[2] = const0_rtx;
4250 operands[1] = GEN_INT (0x7f);
4251 operands[2] = GEN_INT (val - 0x7f);
4255 ;; 32-bit floating point moves
4257 (define_expand "movsf"
4258 [(set (match_operand:SF 0 "")
4259 (match_operand:SF 1 ""))]
4262 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4266 (define_insn "*movsf_hardfloat"
4267 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4268 (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
4270 && (register_operand (operands[0], SFmode)
4271 || reg_or_0_operand (operands[1], SFmode))"
4272 { return mips_output_move (operands[0], operands[1]); }
4273 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4274 (set_attr "mode" "SF")
4275 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4277 (define_insn "*movsf_softfloat"
4278 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4279 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
4280 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4281 && (register_operand (operands[0], SFmode)
4282 || reg_or_0_operand (operands[1], SFmode))"
4283 { return mips_output_move (operands[0], operands[1]); }
4284 [(set_attr "type" "arith,load,store")
4285 (set_attr "mode" "SF")
4286 (set_attr "length" "4,*,*")])
4288 (define_insn "*movsf_mips16"
4289 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4290 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
4292 && (register_operand (operands[0], SFmode)
4293 || register_operand (operands[1], SFmode))"
4294 { return mips_output_move (operands[0], operands[1]); }
4295 [(set_attr "type" "arith,arith,arith,load,store")
4296 (set_attr "mode" "SF")
4297 (set_attr "length" "4,4,4,*,*")])
4300 ;; 64-bit floating point moves
4302 (define_expand "movdf"
4303 [(set (match_operand:DF 0 "")
4304 (match_operand:DF 1 ""))]
4307 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4311 (define_insn "*movdf_hardfloat_64bit"
4312 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4313 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4314 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
4315 && (register_operand (operands[0], DFmode)
4316 || reg_or_0_operand (operands[1], DFmode))"
4317 { return mips_output_move (operands[0], operands[1]); }
4318 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4319 (set_attr "mode" "DF")
4320 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4322 (define_insn "*movdf_hardfloat_32bit"
4323 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4324 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4325 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
4326 && (register_operand (operands[0], DFmode)
4327 || reg_or_0_operand (operands[1], DFmode))"
4328 { return mips_output_move (operands[0], operands[1]); }
4329 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4330 (set_attr "mode" "DF")
4331 (set_attr "length" "4,8,*,*,8,8,8,*,*")])
4333 (define_insn "*movdf_softfloat"
4334 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
4335 (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
4336 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4337 && (register_operand (operands[0], DFmode)
4338 || reg_or_0_operand (operands[1], DFmode))"
4339 { return mips_output_move (operands[0], operands[1]); }
4340 [(set_attr "type" "arith,load,store,xfer,xfer,fmove")
4341 (set_attr "mode" "DF")
4342 (set_attr "length" "8,*,*,4,4,4")])
4344 (define_insn "*movdf_mips16"
4345 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4346 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4348 && (register_operand (operands[0], DFmode)
4349 || register_operand (operands[1], DFmode))"
4350 { return mips_output_move (operands[0], operands[1]); }
4351 [(set_attr "type" "arith,arith,arith,load,store")
4352 (set_attr "mode" "DF")
4353 (set_attr "length" "8,8,8,*,*")])
4356 [(set (match_operand:DI 0 "nonimmediate_operand")
4357 (match_operand:DI 1 "move_operand"))]
4358 "reload_completed && !TARGET_64BIT
4359 && mips_split_64bit_move_p (operands[0], operands[1])"
4362 mips_split_64bit_move (operands[0], operands[1]);
4367 [(set (match_operand:DF 0 "nonimmediate_operand")
4368 (match_operand:DF 1 "move_operand"))]
4369 "reload_completed && !TARGET_64BIT
4370 && mips_split_64bit_move_p (operands[0], operands[1])"
4373 mips_split_64bit_move (operands[0], operands[1]);
4377 ;; When generating mips16 code, split moves of negative constants into
4378 ;; a positive "li" followed by a negation.
4380 [(set (match_operand 0 "register_operand")
4381 (match_operand 1 "const_int_operand"))]
4382 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4386 (neg:SI (match_dup 2)))]
4388 operands[2] = gen_lowpart (SImode, operands[0]);
4389 operands[3] = GEN_INT (-INTVAL (operands[1]));
4392 ;; The HI and LO registers are not truly independent. If we move an mthi
4393 ;; instruction before an mflo instruction, it will make the result of the
4394 ;; mflo unpredictable. The same goes for mtlo and mfhi.
4396 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4397 ;; Operand 1 is the register we want, operand 2 is the other one.
4399 (define_insn "mfhilo_di"
4400 [(set (match_operand:DI 0 "register_operand" "=d,d")
4401 (unspec:DI [(match_operand:DI 1 "register_operand" "h,l")
4402 (match_operand:DI 2 "register_operand" "l,h")]
4406 [(set_attr "type" "mfhilo")])
4408 (define_insn "mfhilo_si"
4409 [(set (match_operand:SI 0 "register_operand" "=d,d")
4410 (unspec:SI [(match_operand:SI 1 "register_operand" "h,l")
4411 (match_operand:SI 2 "register_operand" "l,h")]
4415 [(set_attr "type" "mfhilo")])
4417 ;; Patterns for loading or storing part of a paired floating point
4418 ;; register. We need them because odd-numbered floating-point registers
4419 ;; are not fully independent: see mips_split_64bit_move.
4421 ;; Load the low word of operand 0 with operand 1.
4422 (define_insn "load_df_low"
4423 [(set (match_operand:DF 0 "register_operand" "=f,f")
4424 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
4425 UNSPEC_LOAD_DF_LOW))]
4426 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4428 operands[0] = mips_subword (operands[0], 0);
4429 return mips_output_move (operands[0], operands[1]);
4431 [(set_attr "type" "xfer,fpload")
4432 (set_attr "mode" "SF")])
4434 ;; Load the high word of operand 0 from operand 1, preserving the value
4436 (define_insn "load_df_high"
4437 [(set (match_operand:DF 0 "register_operand" "=f,f")
4438 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
4439 (match_operand:DF 2 "register_operand" "0,0")]
4440 UNSPEC_LOAD_DF_HIGH))]
4441 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4443 operands[0] = mips_subword (operands[0], 1);
4444 return mips_output_move (operands[0], operands[1]);
4446 [(set_attr "type" "xfer,fpload")
4447 (set_attr "mode" "SF")])
4449 ;; Store the high word of operand 1 in operand 0. The corresponding
4450 ;; low-word move is done in the normal way.
4451 (define_insn "store_df_high"
4452 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4453 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4454 UNSPEC_STORE_DF_HIGH))]
4455 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4457 operands[1] = mips_subword (operands[1], 1);
4458 return mips_output_move (operands[0], operands[1]);
4460 [(set_attr "type" "xfer,fpstore")
4461 (set_attr "mode" "SF")])
4463 ;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
4464 ;; of _gp from the start of this function. Operand 1 is the incoming
4465 ;; function address.
4466 (define_insn_and_split "loadgp"
4467 [(unspec_volatile [(match_operand 0 "" "")
4468 (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4469 "TARGET_ABICALLS && TARGET_NEWABI"
4472 [(set (match_dup 2) (match_dup 3))
4473 (set (match_dup 2) (match_dup 4))
4474 (set (match_dup 2) (match_dup 5))]
4476 operands[2] = pic_offset_table_rtx;
4477 operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4478 operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4479 operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4481 [(set_attr "length" "12")])
4483 ;; The use of gp is hidden when not using explicit relocations.
4484 ;; This blockage instruction prevents the gp load from being
4485 ;; scheduled after an implicit use of gp. It also prevents
4486 ;; the load from being deleted as dead.
4487 (define_insn "loadgp_blockage"
4488 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4491 [(set_attr "type" "unknown")
4492 (set_attr "mode" "none")
4493 (set_attr "length" "0")])
4495 ;; Emit a .cprestore directive, which normally expands to a single store
4496 ;; instruction. Note that we continue to use .cprestore for explicit reloc
4497 ;; code so that jals inside inline asms will work correctly.
4498 (define_insn "cprestore"
4499 [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
4503 if (set_nomacro && which_alternative == 1)
4504 return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4506 return ".cprestore\t%0";
4508 [(set_attr "type" "store")
4509 (set_attr "length" "4,12")])
4511 ;; Block moves, see mips.c for more details.
4512 ;; Argument 0 is the destination
4513 ;; Argument 1 is the source
4514 ;; Argument 2 is the length
4515 ;; Argument 3 is the alignment
4517 (define_expand "movmemsi"
4518 [(parallel [(set (match_operand:BLK 0 "general_operand")
4519 (match_operand:BLK 1 "general_operand"))
4520 (use (match_operand:SI 2 ""))
4521 (use (match_operand:SI 3 "const_int_operand"))])]
4522 "!TARGET_MIPS16 && !TARGET_MEMCPY"
4524 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4531 ;; ....................
4535 ;; ....................
4537 ;; Many of these instructions use trivial define_expands, because we
4538 ;; want to use a different set of constraints when TARGET_MIPS16.
4540 (define_expand "ashlsi3"
4541 [(set (match_operand:SI 0 "register_operand")
4542 (ashift:SI (match_operand:SI 1 "register_operand")
4543 (match_operand:SI 2 "arith_operand")))]
4546 /* On the mips16, a shift of more than 8 is a four byte instruction,
4547 so, for a shift between 8 and 16, it is just as fast to do two
4548 shifts of 8 or less. If there is a lot of shifting going on, we
4549 may win in CSE. Otherwise combine will put the shifts back
4550 together again. This can be called by function_arg, so we must
4551 be careful not to allocate a new register if we've reached the
4555 && GET_CODE (operands[2]) == CONST_INT
4556 && INTVAL (operands[2]) > 8
4557 && INTVAL (operands[2]) <= 16
4558 && ! reload_in_progress
4559 && ! reload_completed)
4561 rtx temp = gen_reg_rtx (SImode);
4563 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
4564 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
4565 GEN_INT (INTVAL (operands[2]) - 8)));
4570 (define_insn "ashlsi3_internal1"
4571 [(set (match_operand:SI 0 "register_operand" "=d")
4572 (ashift:SI (match_operand:SI 1 "register_operand" "d")
4573 (match_operand:SI 2 "arith_operand" "dI")))]
4576 if (GET_CODE (operands[2]) == CONST_INT)
4577 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4579 return "sll\t%0,%1,%2";
4581 [(set_attr "type" "shift")
4582 (set_attr "mode" "SI")])
4584 (define_insn "ashlsi3_internal1_extend"
4585 [(set (match_operand:DI 0 "register_operand" "=d")
4586 (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
4587 (match_operand:SI 2 "arith_operand" "dI"))))]
4588 "TARGET_64BIT && !TARGET_MIPS16"
4590 if (GET_CODE (operands[2]) == CONST_INT)
4591 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4593 return "sll\t%0,%1,%2";
4595 [(set_attr "type" "shift")
4596 (set_attr "mode" "DI")])
4599 (define_insn "ashlsi3_internal2"
4600 [(set (match_operand:SI 0 "register_operand" "=d,d")
4601 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
4602 (match_operand:SI 2 "arith_operand" "d,I")))]
4605 if (which_alternative == 0)
4606 return "sll\t%0,%2";
4608 if (GET_CODE (operands[2]) == CONST_INT)
4609 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4611 return "sll\t%0,%1,%2";
4613 [(set_attr "type" "shift")
4614 (set_attr "mode" "SI")
4615 (set_attr_alternative "length"
4617 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4621 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4624 [(set (match_operand:SI 0 "register_operand")
4625 (ashift:SI (match_operand:SI 1 "register_operand")
4626 (match_operand:SI 2 "const_int_operand")))]
4627 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4628 && GET_CODE (operands[2]) == CONST_INT
4629 && INTVAL (operands[2]) > 8
4630 && INTVAL (operands[2]) <= 16"
4631 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
4632 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4633 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4635 (define_expand "ashldi3"
4636 [(set (match_operand:DI 0 "register_operand")
4637 (ashift:DI (match_operand:DI 1 "register_operand")
4638 (match_operand:SI 2 "arith_operand")))]
4641 /* On the mips16, a shift of more than 8 is a four byte
4642 instruction, so, for a shift between 8 and 16, it is just as
4643 fast to do two shifts of 8 or less. If there is a lot of
4644 shifting going on, we may win in CSE. Otherwise combine will
4645 put the shifts back together again. This can be called by
4646 function_arg, so we must be careful not to allocate a new
4647 register if we've reached the reload pass. */
4650 && GET_CODE (operands[2]) == CONST_INT
4651 && INTVAL (operands[2]) > 8
4652 && INTVAL (operands[2]) <= 16
4653 && ! reload_in_progress
4654 && ! reload_completed)
4656 rtx temp = gen_reg_rtx (DImode);
4658 emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
4659 emit_insn (gen_ashldi3_internal (operands[0], temp,
4660 GEN_INT (INTVAL (operands[2]) - 8)));
4666 (define_insn "ashldi3_internal"
4667 [(set (match_operand:DI 0 "register_operand" "=d")
4668 (ashift:DI (match_operand:DI 1 "register_operand" "d")
4669 (match_operand:SI 2 "arith_operand" "dI")))]
4670 "TARGET_64BIT && !TARGET_MIPS16"
4672 if (GET_CODE (operands[2]) == CONST_INT)
4673 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4675 return "dsll\t%0,%1,%2";
4677 [(set_attr "type" "shift")
4678 (set_attr "mode" "DI")])
4681 [(set (match_operand:DI 0 "register_operand" "=d,d")
4682 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4683 (match_operand:SI 2 "arith_operand" "d,I")))]
4684 "TARGET_64BIT && TARGET_MIPS16"
4686 if (which_alternative == 0)
4687 return "dsll\t%0,%2";
4689 if (GET_CODE (operands[2]) == CONST_INT)
4690 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4692 return "dsll\t%0,%1,%2";
4694 [(set_attr "type" "shift")
4695 (set_attr "mode" "DI")
4696 (set_attr_alternative "length"
4698 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4703 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4706 [(set (match_operand:DI 0 "register_operand")
4707 (ashift:DI (match_operand:DI 1 "register_operand")
4708 (match_operand:SI 2 "const_int_operand")))]
4709 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
4711 && GET_CODE (operands[2]) == CONST_INT
4712 && INTVAL (operands[2]) > 8
4713 && INTVAL (operands[2]) <= 16"
4714 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
4715 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
4716 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4718 (define_expand "ashrsi3"
4719 [(set (match_operand:SI 0 "register_operand")
4720 (ashiftrt:SI (match_operand:SI 1 "register_operand")
4721 (match_operand:SI 2 "arith_operand")))]
4724 /* On the mips16, a shift of more than 8 is a four byte instruction,
4725 so, for a shift between 8 and 16, it is just as fast to do two
4726 shifts of 8 or less. If there is a lot of shifting going on, we
4727 may win in CSE. Otherwise combine will put the shifts back
4731 && GET_CODE (operands[2]) == CONST_INT
4732 && INTVAL (operands[2]) > 8
4733 && INTVAL (operands[2]) <= 16)
4735 rtx temp = gen_reg_rtx (SImode);
4737 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
4738 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
4739 GEN_INT (INTVAL (operands[2]) - 8)));
4744 (define_insn "ashrsi3_internal1"
4745 [(set (match_operand:SI 0 "register_operand" "=d")
4746 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
4747 (match_operand:SI 2 "arith_operand" "dI")))]
4750 if (GET_CODE (operands[2]) == CONST_INT)
4751 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4753 return "sra\t%0,%1,%2";
4755 [(set_attr "type" "shift")
4756 (set_attr "mode" "SI")])
4758 (define_insn "ashrsi3_internal2"
4759 [(set (match_operand:SI 0 "register_operand" "=d,d")
4760 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
4761 (match_operand:SI 2 "arith_operand" "d,I")))]
4764 if (which_alternative == 0)
4765 return "sra\t%0,%2";
4767 if (GET_CODE (operands[2]) == CONST_INT)
4768 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4770 return "sra\t%0,%1,%2";
4772 [(set_attr "type" "shift")
4773 (set_attr "mode" "SI")
4774 (set_attr_alternative "length"
4776 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4781 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4784 [(set (match_operand:SI 0 "register_operand")
4785 (ashiftrt:SI (match_operand:SI 1 "register_operand")
4786 (match_operand:SI 2 "const_int_operand")))]
4787 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4788 && GET_CODE (operands[2]) == CONST_INT
4789 && INTVAL (operands[2]) > 8
4790 && INTVAL (operands[2]) <= 16"
4791 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
4792 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
4793 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4795 (define_expand "ashrdi3"
4796 [(set (match_operand:DI 0 "register_operand")
4797 (ashiftrt:DI (match_operand:DI 1 "register_operand")
4798 (match_operand:SI 2 "arith_operand")))]
4801 /* On the mips16, a shift of more than 8 is a four byte
4802 instruction, so, for a shift between 8 and 16, it is just as
4803 fast to do two shifts of 8 or less. If there is a lot of
4804 shifting going on, we may win in CSE. Otherwise combine will
4805 put the shifts back together again. */
4808 && GET_CODE (operands[2]) == CONST_INT
4809 && INTVAL (operands[2]) > 8
4810 && INTVAL (operands[2]) <= 16)
4812 rtx temp = gen_reg_rtx (DImode);
4814 emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
4815 emit_insn (gen_ashrdi3_internal (operands[0], temp,
4816 GEN_INT (INTVAL (operands[2]) - 8)));
4822 (define_insn "ashrdi3_internal"
4823 [(set (match_operand:DI 0 "register_operand" "=d")
4824 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4825 (match_operand:SI 2 "arith_operand" "dI")))]
4826 "TARGET_64BIT && !TARGET_MIPS16"
4828 if (GET_CODE (operands[2]) == CONST_INT)
4829 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4831 return "dsra\t%0,%1,%2";
4833 [(set_attr "type" "shift")
4834 (set_attr "mode" "DI")])
4837 [(set (match_operand:DI 0 "register_operand" "=d,d")
4838 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4839 (match_operand:SI 2 "arith_operand" "d,I")))]
4840 "TARGET_64BIT && TARGET_MIPS16"
4842 if (GET_CODE (operands[2]) == CONST_INT)
4843 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4845 return "dsra\t%0,%2";
4847 [(set_attr "type" "shift")
4848 (set_attr "mode" "DI")
4849 (set_attr_alternative "length"
4851 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4855 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4858 [(set (match_operand:DI 0 "register_operand")
4859 (ashiftrt:DI (match_operand:DI 1 "register_operand")
4860 (match_operand:SI 2 "const_int_operand")))]
4861 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
4863 && GET_CODE (operands[2]) == CONST_INT
4864 && INTVAL (operands[2]) > 8
4865 && INTVAL (operands[2]) <= 16"
4866 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
4867 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
4868 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4870 (define_expand "lshrsi3"
4871 [(set (match_operand:SI 0 "register_operand")
4872 (lshiftrt:SI (match_operand:SI 1 "register_operand")
4873 (match_operand:SI 2 "arith_operand")))]
4876 /* On the mips16, a shift of more than 8 is a four byte instruction,
4877 so, for a shift between 8 and 16, it is just as fast to do two
4878 shifts of 8 or less. If there is a lot of shifting going on, we
4879 may win in CSE. Otherwise combine will put the shifts back
4883 && GET_CODE (operands[2]) == CONST_INT
4884 && INTVAL (operands[2]) > 8
4885 && INTVAL (operands[2]) <= 16)
4887 rtx temp = gen_reg_rtx (SImode);
4889 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
4890 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
4891 GEN_INT (INTVAL (operands[2]) - 8)));
4896 (define_insn "lshrsi3_internal1"
4897 [(set (match_operand:SI 0 "register_operand" "=d")
4898 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
4899 (match_operand:SI 2 "arith_operand" "dI")))]
4902 if (GET_CODE (operands[2]) == CONST_INT)
4903 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4905 return "srl\t%0,%1,%2";
4907 [(set_attr "type" "shift")
4908 (set_attr "mode" "SI")])
4910 (define_insn "lshrsi3_internal2"
4911 [(set (match_operand:SI 0 "register_operand" "=d,d")
4912 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
4913 (match_operand:SI 2 "arith_operand" "d,I")))]
4916 if (which_alternative == 0)
4917 return "srl\t%0,%2";
4919 if (GET_CODE (operands[2]) == CONST_INT)
4920 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4922 return "srl\t%0,%1,%2";
4924 [(set_attr "type" "shift")
4925 (set_attr "mode" "SI")
4926 (set_attr_alternative "length"
4928 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4933 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4936 [(set (match_operand:SI 0 "register_operand")
4937 (lshiftrt:SI (match_operand:SI 1 "register_operand")
4938 (match_operand:SI 2 "const_int_operand")))]
4939 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4940 && GET_CODE (operands[2]) == CONST_INT
4941 && INTVAL (operands[2]) > 8
4942 && INTVAL (operands[2]) <= 16"
4943 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
4944 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4945 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4947 ;; If we load a byte on the mips16 as a bitfield, the resulting
4948 ;; sequence of instructions is too complicated for combine, because it
4949 ;; involves four instructions: a load, a shift, a constant load into a
4950 ;; register, and an and (the key problem here is that the mips16 does
4951 ;; not have and immediate). We recognize a shift of a load in order
4952 ;; to make it simple enough for combine to understand.
4954 ;; The length here is the worst case: the length of the split version
4955 ;; will be more accurate.
4956 (define_insn_and_split ""
4957 [(set (match_operand:SI 0 "register_operand" "=d")
4958 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4959 (match_operand:SI 2 "immediate_operand" "I")))]
4963 [(set (match_dup 0) (match_dup 1))
4964 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4966 [(set_attr "type" "load")
4967 (set_attr "mode" "SI")
4968 (set_attr "length" "16")])
4970 (define_expand "lshrdi3"
4971 [(set (match_operand:DI 0 "register_operand")
4972 (lshiftrt:DI (match_operand:DI 1 "register_operand")
4973 (match_operand:SI 2 "arith_operand")))]
4976 /* On the mips16, a shift of more than 8 is a four byte
4977 instruction, so, for a shift between 8 and 16, it is just as
4978 fast to do two shifts of 8 or less. If there is a lot of
4979 shifting going on, we may win in CSE. Otherwise combine will
4980 put the shifts back together again. */
4983 && GET_CODE (operands[2]) == CONST_INT
4984 && INTVAL (operands[2]) > 8
4985 && INTVAL (operands[2]) <= 16)
4987 rtx temp = gen_reg_rtx (DImode);
4989 emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
4990 emit_insn (gen_lshrdi3_internal (operands[0], temp,
4991 GEN_INT (INTVAL (operands[2]) - 8)));
4997 (define_insn "lshrdi3_internal"
4998 [(set (match_operand:DI 0 "register_operand" "=d")
4999 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
5000 (match_operand:SI 2 "arith_operand" "dI")))]
5001 "TARGET_64BIT && !TARGET_MIPS16"
5003 if (GET_CODE (operands[2]) == CONST_INT)
5004 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5006 return "dsrl\t%0,%1,%2";
5008 [(set_attr "type" "shift")
5009 (set_attr "mode" "DI")])
5012 [(set (match_operand:DI 0 "register_operand" "=d,d")
5013 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5014 (match_operand:SI 2 "arith_operand" "d,I")))]
5015 "TARGET_64BIT && TARGET_MIPS16"
5017 if (GET_CODE (operands[2]) == CONST_INT)
5018 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5020 return "dsrl\t%0,%2";
5022 [(set_attr "type" "shift")
5023 (set_attr "mode" "DI")
5024 (set_attr_alternative "length"
5026 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5030 (define_insn "rotrsi3"
5031 [(set (match_operand:SI 0 "register_operand" "=d")
5032 (rotatert:SI (match_operand:SI 1 "register_operand" "d")
5033 (match_operand:SI 2 "arith_operand" "dn")))]
5036 if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
5037 return "rorv\t%0,%1,%2";
5039 if ((GET_CODE (operands[2]) == CONST_INT)
5040 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
5043 return "ror\t%0,%1,%2";
5045 [(set_attr "type" "shift")
5046 (set_attr "mode" "SI")])
5048 (define_insn "rotrdi3"
5049 [(set (match_operand:DI 0 "register_operand" "=d")
5050 (rotatert:DI (match_operand:DI 1 "register_operand" "d")
5051 (match_operand:DI 2 "arith_operand" "dn")))]
5056 if (GET_CODE (operands[2]) != CONST_INT)
5057 return "drorv\t%0,%1,%2";
5059 if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
5060 return "dror32\t%0,%1,%2";
5063 if ((GET_CODE (operands[2]) == CONST_INT)
5064 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
5067 return "dror\t%0,%1,%2";
5069 [(set_attr "type" "shift")
5070 (set_attr "mode" "DI")])
5073 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5076 [(set (match_operand:DI 0 "register_operand")
5077 (lshiftrt:DI (match_operand:DI 1 "register_operand")
5078 (match_operand:SI 2 "const_int_operand")))]
5079 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5080 && GET_CODE (operands[2]) == CONST_INT
5081 && INTVAL (operands[2]) > 8
5082 && INTVAL (operands[2]) <= 16"
5083 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
5084 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
5085 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5088 ;; ....................
5092 ;; ....................
5094 ;; Flow here is rather complex:
5096 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the arguments
5097 ;; into cmp_operands[] but generates no RTL.
5099 ;; 2) The appropriate branch define_expand is called, which then
5100 ;; creates the appropriate RTL for the comparison and branch.
5101 ;; Different CC modes are used, based on what type of branch is
5102 ;; done, so that we can constrain things appropriately. There
5103 ;; are assumptions in the rest of GCC that break if we fold the
5104 ;; operands into the branches for integer operations, and use cc0
5105 ;; for floating point, so we use the fp status register instead.
5106 ;; If needed, an appropriate temporary is created to hold the
5107 ;; of the integer compare.
5109 (define_expand "cmpsi"
5111 (compare:CC (match_operand:SI 0 "register_operand")
5112 (match_operand:SI 1 "nonmemory_operand")))]
5115 cmp_operands[0] = operands[0];
5116 cmp_operands[1] = operands[1];
5120 (define_expand "cmpdi"
5122 (compare:CC (match_operand:DI 0 "register_operand")
5123 (match_operand:DI 1 "nonmemory_operand")))]
5126 cmp_operands[0] = operands[0];
5127 cmp_operands[1] = operands[1];
5131 (define_expand "cmpdf"
5133 (compare:CC (match_operand:DF 0 "register_operand")
5134 (match_operand:DF 1 "register_operand")))]
5135 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5137 cmp_operands[0] = operands[0];
5138 cmp_operands[1] = operands[1];
5142 (define_expand "cmpsf"
5144 (compare:CC (match_operand:SF 0 "register_operand")
5145 (match_operand:SF 1 "register_operand")))]
5148 cmp_operands[0] = operands[0];
5149 cmp_operands[1] = operands[1];
5154 ;; ....................
5156 ;; CONDITIONAL BRANCHES
5158 ;; ....................
5160 ;; Conditional branches on floating-point equality tests.
5162 (define_insn "branch_fp"
5165 (match_operator:CC 0 "comparison_operator"
5166 [(match_operand:CC 2 "register_operand" "z")
5168 (label_ref (match_operand 1 "" ""))
5172 return mips_output_conditional_branch (insn,
5174 /*two_operands_p=*/0,
5177 get_attr_length (insn));
5179 [(set_attr "type" "branch")
5180 (set_attr "mode" "none")])
5182 (define_insn "branch_fp_inverted"
5185 (match_operator:CC 0 "comparison_operator"
5186 [(match_operand:CC 2 "register_operand" "z")
5189 (label_ref (match_operand 1 "" ""))))]
5192 return mips_output_conditional_branch (insn,
5194 /*two_operands_p=*/0,
5197 get_attr_length (insn));
5199 [(set_attr "type" "branch")
5200 (set_attr "mode" "none")])
5202 ;; Conditional branches on comparisons with zero.
5204 (define_insn "branch_zero"
5207 (match_operator:SI 0 "comparison_operator"
5208 [(match_operand:SI 2 "register_operand" "d")
5210 (label_ref (match_operand 1 "" ""))
5214 return mips_output_conditional_branch (insn,
5216 /*two_operands_p=*/0,
5219 get_attr_length (insn));
5221 [(set_attr "type" "branch")
5222 (set_attr "mode" "none")])
5224 (define_insn "branch_zero_inverted"
5227 (match_operator:SI 0 "comparison_operator"
5228 [(match_operand:SI 2 "register_operand" "d")
5231 (label_ref (match_operand 1 "" ""))))]
5234 return mips_output_conditional_branch (insn,
5236 /*two_operands_p=*/0,
5239 get_attr_length (insn));
5241 [(set_attr "type" "branch")
5242 (set_attr "mode" "none")])
5244 (define_insn "branch_zero_di"
5247 (match_operator:DI 0 "comparison_operator"
5248 [(match_operand:DI 2 "register_operand" "d")
5250 (label_ref (match_operand 1 "" ""))
5254 return mips_output_conditional_branch (insn,
5256 /*two_operands_p=*/0,
5259 get_attr_length (insn));
5261 [(set_attr "type" "branch")
5262 (set_attr "mode" "none")])
5264 (define_insn "branch_zero_di_inverted"
5267 (match_operator:DI 0 "comparison_operator"
5268 [(match_operand:DI 2 "register_operand" "d")
5271 (label_ref (match_operand 1 "" ""))))]
5274 return mips_output_conditional_branch (insn,
5276 /*two_operands_p=*/0,
5279 get_attr_length (insn));
5281 [(set_attr "type" "branch")
5282 (set_attr "mode" "none")])
5284 ;; Conditional branch on equality comparison.
5286 (define_insn "branch_equality"
5289 (match_operator:SI 0 "equality_operator"
5290 [(match_operand:SI 2 "register_operand" "d")
5291 (match_operand:SI 3 "register_operand" "d")])
5292 (label_ref (match_operand 1 "" ""))
5296 return mips_output_conditional_branch (insn,
5298 /*two_operands_p=*/1,
5301 get_attr_length (insn));
5303 [(set_attr "type" "branch")
5304 (set_attr "mode" "none")])
5306 (define_insn "branch_equality_di"
5309 (match_operator:DI 0 "equality_operator"
5310 [(match_operand:DI 2 "register_operand" "d")
5311 (match_operand:DI 3 "register_operand" "d")])
5312 (label_ref (match_operand 1 "" ""))
5316 return mips_output_conditional_branch (insn,
5318 /*two_operands_p=*/1,
5321 get_attr_length (insn));
5323 [(set_attr "type" "branch")
5324 (set_attr "mode" "none")])
5326 (define_insn "branch_equality_inverted"
5329 (match_operator:SI 0 "equality_operator"
5330 [(match_operand:SI 2 "register_operand" "d")
5331 (match_operand:SI 3 "register_operand" "d")])
5333 (label_ref (match_operand 1 "" ""))))]
5336 return mips_output_conditional_branch (insn,
5338 /*two_operands_p=*/1,
5341 get_attr_length (insn));
5343 [(set_attr "type" "branch")
5344 (set_attr "mode" "none")])
5346 (define_insn "branch_equality_di_inverted"
5349 (match_operator:DI 0 "equality_operator"
5350 [(match_operand:DI 2 "register_operand" "d")
5351 (match_operand:DI 3 "register_operand" "d")])
5353 (label_ref (match_operand 1 "" ""))))]
5356 return mips_output_conditional_branch (insn,
5358 /*two_operands_p=*/1,
5361 get_attr_length (insn));
5363 [(set_attr "type" "branch")
5364 (set_attr "mode" "none")])
5371 (match_operator:SI 0 "equality_operator"
5372 [(match_operand:SI 1 "register_operand" "d,t")
5374 (match_operand 2 "pc_or_label_operand" "")
5375 (match_operand 3 "pc_or_label_operand" "")))]
5378 if (operands[2] != pc_rtx)
5380 if (which_alternative == 0)
5381 return "b%C0z\t%1,%2";
5383 return "bt%C0z\t%2";
5387 if (which_alternative == 0)
5388 return "b%N0z\t%1,%3";
5390 return "bt%N0z\t%3";
5393 [(set_attr "type" "branch")
5394 (set_attr "mode" "none")
5395 (set_attr "length" "8")])
5400 (match_operator:DI 0 "equality_operator"
5401 [(match_operand:DI 1 "register_operand" "d,t")
5403 (match_operand 2 "pc_or_label_operand" "")
5404 (match_operand 3 "pc_or_label_operand" "")))]
5407 if (operands[2] != pc_rtx)
5409 if (which_alternative == 0)
5410 return "b%C0z\t%1,%2";
5412 return "bt%C0z\t%2";
5416 if (which_alternative == 0)
5417 return "b%N0z\t%1,%3";
5419 return "bt%N0z\t%3";
5422 [(set_attr "type" "branch")
5423 (set_attr "mode" "none")
5424 (set_attr "length" "8")])
5426 (define_expand "b<code>"
5428 (if_then_else (any_cond:CC (cc0)
5430 (label_ref (match_operand 0 ""))
5434 gen_conditional_branch (operands, <CODE>);
5439 ;; ....................
5441 ;; SETTING A REGISTER FROM A COMPARISON
5443 ;; ....................
5445 (define_expand "seq"
5446 [(set (match_operand:SI 0 "register_operand")
5447 (eq:SI (match_dup 1)
5450 { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
5452 (define_insn "*seq_si"
5453 [(set (match_operand:SI 0 "register_operand" "=d")
5454 (eq:SI (match_operand:SI 1 "register_operand" "d")
5458 [(set_attr "type" "slt")
5459 (set_attr "mode" "SI")])
5461 (define_insn "*seq_si_mips16"
5462 [(set (match_operand:SI 0 "register_operand" "=t")
5463 (eq:SI (match_operand:SI 1 "register_operand" "d")
5467 [(set_attr "type" "slt")
5468 (set_attr "mode" "SI")])
5470 (define_insn "*seq_di"
5471 [(set (match_operand:DI 0 "register_operand" "=d")
5472 (eq:DI (match_operand:DI 1 "register_operand" "d")
5474 "TARGET_64BIT && !TARGET_MIPS16"
5476 [(set_attr "type" "slt")
5477 (set_attr "mode" "DI")])
5479 (define_insn "*seq_di_mips16"
5480 [(set (match_operand:DI 0 "register_operand" "=t")
5481 (eq:DI (match_operand:DI 1 "register_operand" "d")
5483 "TARGET_64BIT && TARGET_MIPS16"
5485 [(set_attr "type" "slt")
5486 (set_attr "mode" "DI")])
5488 ;; "sne" uses sltu instructions in which the first operand is $0.
5489 ;; This isn't possible in mips16 code.
5491 (define_expand "sne"
5492 [(set (match_operand:SI 0 "register_operand")
5493 (ne:SI (match_dup 1)
5496 { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
5498 (define_insn "*sne_si"
5499 [(set (match_operand:SI 0 "register_operand" "=d")
5500 (ne:SI (match_operand:SI 1 "register_operand" "d")
5504 [(set_attr "type" "slt")
5505 (set_attr "mode" "SI")])
5507 (define_insn "*sne_di"
5508 [(set (match_operand:DI 0 "register_operand" "=d")
5509 (ne:DI (match_operand:DI 1 "register_operand" "d")
5511 "TARGET_64BIT && !TARGET_MIPS16"
5513 [(set_attr "type" "slt")
5514 (set_attr "mode" "DI")])
5516 (define_expand "sgt"
5517 [(set (match_operand:SI 0 "register_operand")
5518 (gt:SI (match_dup 1)
5521 { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
5523 (define_insn "*sgt_si"
5524 [(set (match_operand:SI 0 "register_operand" "=d")
5525 (gt:SI (match_operand:SI 1 "register_operand" "d")
5526 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
5529 [(set_attr "type" "slt")
5530 (set_attr "mode" "SI")])
5532 (define_insn "*sgt_si_mips16"
5533 [(set (match_operand:SI 0 "register_operand" "=t")
5534 (gt:SI (match_operand:SI 1 "register_operand" "d")
5535 (match_operand:SI 2 "register_operand" "d")))]
5538 [(set_attr "type" "slt")
5539 (set_attr "mode" "SI")])
5541 (define_insn "*sgt_di"
5542 [(set (match_operand:DI 0 "register_operand" "=d")
5543 (gt:DI (match_operand:DI 1 "register_operand" "d")
5544 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
5545 "TARGET_64BIT && !TARGET_MIPS16"
5547 [(set_attr "type" "slt")
5548 (set_attr "mode" "DI")])
5550 (define_insn "*sgt_di_mips16"
5551 [(set (match_operand:DI 0 "register_operand" "=t")
5552 (gt:DI (match_operand:DI 1 "register_operand" "d")
5553 (match_operand:DI 2 "register_operand" "d")))]
5554 "TARGET_64BIT && TARGET_MIPS16"
5556 [(set_attr "type" "slt")
5557 (set_attr "mode" "DI")])
5559 (define_expand "sge"
5560 [(set (match_operand:SI 0 "register_operand")
5561 (ge:SI (match_dup 1)
5564 { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
5566 (define_insn "*sge_si"
5567 [(set (match_operand:SI 0 "register_operand" "=d")
5568 (ge:SI (match_operand:SI 1 "register_operand" "d")
5572 [(set_attr "type" "slt")
5573 (set_attr "mode" "SI")])
5575 (define_insn "*sge_di"
5576 [(set (match_operand:DI 0 "register_operand" "=d")
5577 (ge:DI (match_operand:DI 1 "register_operand" "d")
5579 "TARGET_64BIT && !TARGET_MIPS16"
5581 [(set_attr "type" "slt")
5582 (set_attr "mode" "DI")])
5584 (define_expand "slt"
5585 [(set (match_operand:SI 0 "register_operand")
5586 (lt:SI (match_dup 1)
5589 { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
5591 (define_insn "*slt_si"
5592 [(set (match_operand:SI 0 "register_operand" "=d")
5593 (lt:SI (match_operand:SI 1 "register_operand" "d")
5594 (match_operand:SI 2 "arith_operand" "dI")))]
5597 [(set_attr "type" "slt")
5598 (set_attr "mode" "SI")])
5600 (define_insn "*slt_si_mips16"
5601 [(set (match_operand:SI 0 "register_operand" "=t,t")
5602 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
5603 (match_operand:SI 2 "arith_operand" "d,I")))]
5606 [(set_attr "type" "slt")
5607 (set_attr "mode" "SI")
5608 (set_attr_alternative "length"
5610 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
5614 (define_insn "*slt_di"
5615 [(set (match_operand:DI 0 "register_operand" "=d")
5616 (lt:DI (match_operand:DI 1 "register_operand" "d")
5617 (match_operand:DI 2 "arith_operand" "dI")))]
5618 "TARGET_64BIT && !TARGET_MIPS16"
5620 [(set_attr "type" "slt")
5621 (set_attr "mode" "DI")])
5623 (define_insn "*slt_di_mips16"
5624 [(set (match_operand:DI 0 "register_operand" "=t,t")
5625 (lt:DI (match_operand:DI 1 "register_operand" "d,d")
5626 (match_operand:DI 2 "arith_operand" "d,I")))]
5627 "TARGET_64BIT && TARGET_MIPS16"
5629 [(set_attr "type" "slt")
5630 (set_attr "mode" "DI")
5631 (set_attr_alternative "length"
5633 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
5637 (define_expand "sle"
5638 [(set (match_operand:SI 0 "register_operand")
5639 (le:SI (match_dup 1)
5642 { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
5644 (define_insn "*sle_si"
5645 [(set (match_operand:SI 0 "register_operand" "=d")
5646 (le:SI (match_operand:SI 1 "register_operand" "d")
5647 (match_operand:SI 2 "sle_operand" "")))]
5650 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5651 return "slt\t%0,%1,%2";
5653 [(set_attr "type" "slt")
5654 (set_attr "mode" "SI")])
5656 (define_insn "*sle_si_mips16"
5657 [(set (match_operand:SI 0 "register_operand" "=t")
5658 (le:SI (match_operand:SI 1 "register_operand" "d")
5659 (match_operand:SI 2 "sle_operand" "")))]
5662 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5663 return "slt\t%1,%2";
5665 [(set_attr "type" "slt")
5666 (set_attr "mode" "SI")
5667 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
5671 (define_insn "*sle_di"
5672 [(set (match_operand:DI 0 "register_operand" "=d")
5673 (le:DI (match_operand:DI 1 "register_operand" "d")
5674 (match_operand:DI 2 "sle_operand" "")))]
5675 "TARGET_64BIT && !TARGET_MIPS16"
5677 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5678 return "slt\t%0,%1,%2";
5680 [(set_attr "type" "slt")
5681 (set_attr "mode" "DI")])
5683 (define_insn "*sle_di_mips16"
5684 [(set (match_operand:DI 0 "register_operand" "=t")
5685 (le:DI (match_operand:DI 1 "register_operand" "d")
5686 (match_operand:DI 2 "sle_operand" "")))]
5687 "TARGET_64BIT && TARGET_MIPS16"
5689 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5690 return "slt\t%1,%2";
5692 [(set_attr "type" "slt")
5693 (set_attr "mode" "DI")
5694 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
5698 (define_expand "sgtu"
5699 [(set (match_operand:SI 0 "register_operand")
5700 (gtu:SI (match_dup 1)
5703 { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
5705 (define_insn "*sgtu_si"
5706 [(set (match_operand:SI 0 "register_operand" "=d")
5707 (gtu:SI (match_operand:SI 1 "register_operand" "d")
5708 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
5711 [(set_attr "type" "slt")
5712 (set_attr "mode" "SI")])
5714 (define_insn "*sgtu_si_mips16"
5715 [(set (match_operand:SI 0 "register_operand" "=t")
5716 (gtu:SI (match_operand:SI 1 "register_operand" "d")
5717 (match_operand:SI 2 "register_operand" "d")))]
5720 [(set_attr "type" "slt")
5721 (set_attr "mode" "SI")])
5723 (define_insn "*sgtu_di"
5724 [(set (match_operand:DI 0 "register_operand" "=d")
5725 (gtu:DI (match_operand:DI 1 "register_operand" "d")
5726 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
5727 "TARGET_64BIT && !TARGET_MIPS16"
5729 [(set_attr "type" "slt")
5730 (set_attr "mode" "DI")])
5732 (define_insn "*sgtu_di_mips16"
5733 [(set (match_operand:DI 0 "register_operand" "=t")
5734 (gtu:DI (match_operand:DI 1 "register_operand" "d")
5735 (match_operand:DI 2 "register_operand" "d")))]
5736 "TARGET_64BIT && TARGET_MIPS16"
5738 [(set_attr "type" "slt")
5739 (set_attr "mode" "DI")])
5741 (define_expand "sgeu"
5742 [(set (match_operand:SI 0 "register_operand")
5743 (geu:SI (match_dup 1)
5746 { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
5748 (define_insn "*sge_si"
5749 [(set (match_operand:SI 0 "register_operand" "=d")
5750 (geu:SI (match_operand:SI 1 "register_operand" "d")
5754 [(set_attr "type" "slt")
5755 (set_attr "mode" "SI")])
5757 (define_insn "*sge_di"
5758 [(set (match_operand:DI 0 "register_operand" "=d")
5759 (geu:DI (match_operand:DI 1 "register_operand" "d")
5761 "TARGET_64BIT && !TARGET_MIPS16"
5763 [(set_attr "type" "slt")
5764 (set_attr "mode" "DI")])
5766 (define_expand "sltu"
5767 [(set (match_operand:SI 0 "register_operand")
5768 (ltu:SI (match_dup 1)
5771 { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
5773 (define_insn "*sltu_si"
5774 [(set (match_operand:SI 0 "register_operand" "=d")
5775 (ltu:SI (match_operand:SI 1 "register_operand" "d")
5776 (match_operand:SI 2 "arith_operand" "dI")))]
5779 [(set_attr "type" "slt")
5780 (set_attr "mode" "SI")])
5782 (define_insn "*sltu_si_mips16"
5783 [(set (match_operand:SI 0 "register_operand" "=t,t")
5784 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
5785 (match_operand:SI 2 "arith_operand" "d,I")))]
5788 [(set_attr "type" "slt")
5789 (set_attr "mode" "SI")
5790 (set_attr_alternative "length"
5792 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
5796 (define_insn "*sltu_di"
5797 [(set (match_operand:DI 0 "register_operand" "=d")
5798 (ltu:DI (match_operand:DI 1 "register_operand" "d")
5799 (match_operand:DI 2 "arith_operand" "dI")))]
5800 "TARGET_64BIT && !TARGET_MIPS16"
5802 [(set_attr "type" "slt")
5803 (set_attr "mode" "DI")])
5805 (define_insn "*sltu_di_mips16"
5806 [(set (match_operand:DI 0 "register_operand" "=t,t")
5807 (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
5808 (match_operand:DI 2 "arith_operand" "d,I")))]
5809 "TARGET_64BIT && TARGET_MIPS16"
5811 [(set_attr "type" "slt")
5812 (set_attr "mode" "DI")
5813 (set_attr_alternative "length"
5815 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
5819 (define_expand "sleu"
5820 [(set (match_operand:SI 0 "register_operand")
5821 (leu:SI (match_dup 1)
5824 { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
5826 (define_insn "*sleu_si"
5827 [(set (match_operand:SI 0 "register_operand" "=d")
5828 (leu:SI (match_operand:SI 1 "register_operand" "d")
5829 (match_operand:SI 2 "sleu_operand" "")))]
5832 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5833 return "sltu\t%0,%1,%2";
5835 [(set_attr "type" "slt")
5836 (set_attr "mode" "SI")])
5838 (define_insn "*sleu_si_mips16"
5839 [(set (match_operand:SI 0 "register_operand" "=t")
5840 (leu:SI (match_operand:SI 1 "register_operand" "d")
5841 (match_operand:SI 2 "sleu_operand" "")))]
5844 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5845 return "sltu\t%1,%2";
5847 [(set_attr "type" "slt")
5848 (set_attr "mode" "SI")
5849 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
5853 (define_insn "*sleu_di"
5854 [(set (match_operand:DI 0 "register_operand" "=d")
5855 (leu:DI (match_operand:DI 1 "register_operand" "d")
5856 (match_operand:DI 2 "sleu_operand" "")))]
5857 "TARGET_64BIT && !TARGET_MIPS16"
5859 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5860 return "sltu\t%0,%1,%2";
5862 [(set_attr "type" "slt")
5863 (set_attr "mode" "DI")])
5865 (define_insn "*sleu_di_mips16"
5866 [(set (match_operand:DI 0 "register_operand" "=t")
5867 (leu:DI (match_operand:DI 1 "register_operand" "d")
5868 (match_operand:DI 2 "sleu_operand" "")))]
5869 "TARGET_64BIT && TARGET_MIPS16"
5871 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5872 return "sltu\t%1,%2";
5874 [(set_attr "type" "slt")
5875 (set_attr "mode" "DI")
5876 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
5881 ;; ....................
5883 ;; FLOATING POINT COMPARISONS
5885 ;; ....................
5887 (define_insn "sunordered_df"
5888 [(set (match_operand:CC 0 "register_operand" "=z")
5889 (unordered:CC (match_operand:DF 1 "register_operand" "f")
5890 (match_operand:DF 2 "register_operand" "f")))]
5891 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5893 [(set_attr "type" "fcmp")
5894 (set_attr "mode" "FPSW")])
5896 (define_insn "sunlt_df"
5897 [(set (match_operand:CC 0 "register_operand" "=z")
5898 (unlt:CC (match_operand:DF 1 "register_operand" "f")
5899 (match_operand:DF 2 "register_operand" "f")))]
5900 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5902 [(set_attr "type" "fcmp")
5903 (set_attr "mode" "FPSW")])
5905 (define_insn "suneq_df"
5906 [(set (match_operand:CC 0 "register_operand" "=z")
5907 (uneq:CC (match_operand:DF 1 "register_operand" "f")
5908 (match_operand:DF 2 "register_operand" "f")))]
5909 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5911 [(set_attr "type" "fcmp")
5912 (set_attr "mode" "FPSW")])
5914 (define_insn "sunle_df"
5915 [(set (match_operand:CC 0 "register_operand" "=z")
5916 (unle:CC (match_operand:DF 1 "register_operand" "f")
5917 (match_operand:DF 2 "register_operand" "f")))]
5918 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5920 [(set_attr "type" "fcmp")
5921 (set_attr "mode" "FPSW")])
5923 (define_insn "seq_df"
5924 [(set (match_operand:CC 0 "register_operand" "=z")
5925 (eq:CC (match_operand:DF 1 "register_operand" "f")
5926 (match_operand:DF 2 "register_operand" "f")))]
5927 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5929 [(set_attr "type" "fcmp")
5930 (set_attr "mode" "FPSW")])
5932 (define_insn "slt_df"
5933 [(set (match_operand:CC 0 "register_operand" "=z")
5934 (lt:CC (match_operand:DF 1 "register_operand" "f")
5935 (match_operand:DF 2 "register_operand" "f")))]
5936 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5938 [(set_attr "type" "fcmp")
5939 (set_attr "mode" "FPSW")])
5941 (define_insn "sle_df"
5942 [(set (match_operand:CC 0 "register_operand" "=z")
5943 (le:CC (match_operand:DF 1 "register_operand" "f")
5944 (match_operand:DF 2 "register_operand" "f")))]
5945 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5947 [(set_attr "type" "fcmp")
5948 (set_attr "mode" "FPSW")])
5950 (define_insn "sgt_df"
5951 [(set (match_operand:CC 0 "register_operand" "=z")
5952 (gt:CC (match_operand:DF 1 "register_operand" "f")
5953 (match_operand:DF 2 "register_operand" "f")))]
5954 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5956 [(set_attr "type" "fcmp")
5957 (set_attr "mode" "FPSW")])
5959 (define_insn "sge_df"
5960 [(set (match_operand:CC 0 "register_operand" "=z")
5961 (ge:CC (match_operand:DF 1 "register_operand" "f")
5962 (match_operand:DF 2 "register_operand" "f")))]
5963 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5965 [(set_attr "type" "fcmp")
5966 (set_attr "mode" "FPSW")])
5968 (define_insn "sunordered_sf"
5969 [(set (match_operand:CC 0 "register_operand" "=z")
5970 (unordered:CC (match_operand:SF 1 "register_operand" "f")
5971 (match_operand:SF 2 "register_operand" "f")))]
5974 [(set_attr "type" "fcmp")
5975 (set_attr "mode" "FPSW")])
5977 (define_insn "sunlt_sf"
5978 [(set (match_operand:CC 0 "register_operand" "=z")
5979 (unlt:CC (match_operand:SF 1 "register_operand" "f")
5980 (match_operand:SF 2 "register_operand" "f")))]
5983 [(set_attr "type" "fcmp")
5984 (set_attr "mode" "FPSW")])
5986 (define_insn "suneq_sf"
5987 [(set (match_operand:CC 0 "register_operand" "=z")
5988 (uneq:CC (match_operand:SF 1 "register_operand" "f")
5989 (match_operand:SF 2 "register_operand" "f")))]
5992 [(set_attr "type" "fcmp")
5993 (set_attr "mode" "FPSW")])
5995 (define_insn "sunle_sf"
5996 [(set (match_operand:CC 0 "register_operand" "=z")
5997 (unle:CC (match_operand:SF 1 "register_operand" "f")
5998 (match_operand:SF 2 "register_operand" "f")))]
6001 [(set_attr "type" "fcmp")
6002 (set_attr "mode" "FPSW")])
6004 (define_insn "seq_sf"
6005 [(set (match_operand:CC 0 "register_operand" "=z")
6006 (eq:CC (match_operand:SF 1 "register_operand" "f")
6007 (match_operand:SF 2 "register_operand" "f")))]
6010 [(set_attr "type" "fcmp")
6011 (set_attr "mode" "FPSW")])
6013 (define_insn "slt_sf"
6014 [(set (match_operand:CC 0 "register_operand" "=z")
6015 (lt:CC (match_operand:SF 1 "register_operand" "f")
6016 (match_operand:SF 2 "register_operand" "f")))]
6019 [(set_attr "type" "fcmp")
6020 (set_attr "mode" "FPSW")])
6022 (define_insn "sle_sf"
6023 [(set (match_operand:CC 0 "register_operand" "=z")
6024 (le:CC (match_operand:SF 1 "register_operand" "f")
6025 (match_operand:SF 2 "register_operand" "f")))]
6028 [(set_attr "type" "fcmp")
6029 (set_attr "mode" "FPSW")])
6031 (define_insn "sgt_sf"
6032 [(set (match_operand:CC 0 "register_operand" "=z")
6033 (gt:CC (match_operand:SF 1 "register_operand" "f")
6034 (match_operand:SF 2 "register_operand" "f")))]
6037 [(set_attr "type" "fcmp")
6038 (set_attr "mode" "FPSW")])
6040 (define_insn "sge_sf"
6041 [(set (match_operand:CC 0 "register_operand" "=z")
6042 (ge:CC (match_operand:SF 1 "register_operand" "f")
6043 (match_operand:SF 2 "register_operand" "f")))]
6046 [(set_attr "type" "fcmp")
6047 (set_attr "mode" "FPSW")])
6050 ;; ....................
6052 ;; UNCONDITIONAL BRANCHES
6054 ;; ....................
6056 ;; Unconditional branches.
6060 (label_ref (match_operand 0 "" "")))]
6065 if (get_attr_length (insn) <= 8)
6066 return "%*b\t%l0%/";
6069 output_asm_insn (mips_output_load_label (), operands);
6070 return "%*jr\t%@%/%]";
6074 return "%*j\t%l0%/";
6076 [(set_attr "type" "jump")
6077 (set_attr "mode" "none")
6078 (set (attr "length")
6079 ;; We can't use `j' when emitting PIC. Emit a branch if it's
6080 ;; in range, otherwise load the address of the branch target into
6081 ;; $at and then jump to it.
6083 (ior (eq (symbol_ref "flag_pic") (const_int 0))
6084 (lt (abs (minus (match_dup 0)
6085 (plus (pc) (const_int 4))))
6086 (const_int 131072)))
6087 (const_int 4) (const_int 16)))])
6089 ;; We need a different insn for the mips16, because a mips16 branch
6090 ;; does not have a delay slot.
6094 (label_ref (match_operand 0 "" "")))]
6097 [(set_attr "type" "branch")
6098 (set_attr "mode" "none")
6099 (set_attr "length" "8")])
6101 (define_expand "indirect_jump"
6102 [(set (pc) (match_operand 0 "register_operand"))]
6108 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
6109 operands[0] = copy_to_mode_reg (Pmode, dest);
6111 if (!(Pmode == DImode))
6112 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
6114 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
6119 (define_insn "indirect_jump_internal1"
6120 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
6121 "!(Pmode == DImode)"
6123 [(set_attr "type" "jump")
6124 (set_attr "mode" "none")])
6126 (define_insn "indirect_jump_internal2"
6127 [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
6130 [(set_attr "type" "jump")
6131 (set_attr "mode" "none")])
6133 (define_expand "tablejump"
6135 (match_operand 0 "register_operand"))
6136 (use (label_ref (match_operand 1 "")))]
6141 if (GET_MODE (operands[0]) != HImode)
6143 if (!(Pmode == DImode))
6144 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
6146 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
6150 if (GET_MODE (operands[0]) != ptr_mode)
6154 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
6155 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
6157 if (Pmode == SImode)
6158 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
6160 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
6164 (define_insn "tablejump_internal1"
6166 (match_operand:SI 0 "register_operand" "d"))
6167 (use (label_ref (match_operand 1 "" "")))]
6170 [(set_attr "type" "jump")
6171 (set_attr "mode" "none")])
6173 (define_insn "tablejump_internal2"
6175 (match_operand:DI 0 "register_operand" "d"))
6176 (use (label_ref (match_operand 1 "" "")))]
6179 [(set_attr "type" "jump")
6180 (set_attr "mode" "none")])
6182 (define_expand "tablejump_mips161"
6183 [(set (pc) (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand"))
6184 (label_ref:SI (match_operand 1 ""))))]
6185 "TARGET_MIPS16 && !(Pmode == DImode)"
6189 t1 = gen_reg_rtx (SImode);
6190 t2 = gen_reg_rtx (SImode);
6191 t3 = gen_reg_rtx (SImode);
6192 emit_insn (gen_extendhisi2 (t1, operands[0]));
6193 emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
6194 emit_insn (gen_addsi3 (t3, t1, t2));
6195 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
6199 (define_expand "tablejump_mips162"
6200 [(set (pc) (plus:DI (sign_extend:DI (match_operand:HI 0 "register_operand"))
6201 (label_ref:DI (match_operand 1 ""))))]
6202 "TARGET_MIPS16 && Pmode == DImode"
6206 t1 = gen_reg_rtx (DImode);
6207 t2 = gen_reg_rtx (DImode);
6208 t3 = gen_reg_rtx (DImode);
6209 emit_insn (gen_extendhidi2 (t1, operands[0]));
6210 emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
6211 emit_insn (gen_adddi3 (t3, t1, t2));
6212 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
6216 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
6217 ;; While it is possible to either pull it off the stack (in the
6218 ;; o32 case) or recalculate it given t9 and our target label,
6219 ;; it takes 3 or 4 insns to do so.
6221 (define_expand "builtin_setjmp_setup"
6222 [(use (match_operand 0 "register_operand"))]
6227 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
6228 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
6232 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
6233 ;; that older code did recalculate the gp from $25. Continue to jump through
6234 ;; $25 for compatibility (we lose nothing by doing so).
6236 (define_expand "builtin_longjmp"
6237 [(use (match_operand 0 "register_operand"))]
6240 /* The elements of the buffer are, in order: */
6241 int W = GET_MODE_SIZE (Pmode);
6242 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6243 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
6244 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
6245 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
6246 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6247 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
6248 The target is bound to be using $28 as the global pointer
6249 but the current function might not be. */
6250 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
6252 /* This bit is similar to expand_builtin_longjmp except that it
6253 restores $gp as well. */
6254 emit_move_insn (hard_frame_pointer_rtx, fp);
6255 emit_move_insn (pv, lab);
6256 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6257 emit_move_insn (gp, gpv);
6258 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6259 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6260 emit_insn (gen_rtx_USE (VOIDmode, gp));
6261 emit_indirect_jump (pv);
6266 ;; ....................
6268 ;; Function prologue/epilogue
6270 ;; ....................
6273 (define_expand "prologue"
6277 mips_expand_prologue ();
6281 ;; Block any insns from being moved before this point, since the
6282 ;; profiling call to mcount can use various registers that aren't
6283 ;; saved or used to pass arguments.
6285 (define_insn "blockage"
6286 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
6289 [(set_attr "type" "unknown")
6290 (set_attr "mode" "none")
6291 (set_attr "length" "0")])
6293 (define_expand "epilogue"
6297 mips_expand_epilogue (false);
6301 (define_expand "sibcall_epilogue"
6305 mips_expand_epilogue (true);
6309 ;; Trivial return. Make it look like a normal return insn as that
6310 ;; allows jump optimizations to work better.
6312 (define_insn "return"
6314 "mips_can_use_return_insn ()"
6316 [(set_attr "type" "jump")
6317 (set_attr "mode" "none")])
6321 (define_insn "return_internal"
6323 (use (match_operand 0 "pmode_register_operand" ""))]
6326 [(set_attr "type" "jump")
6327 (set_attr "mode" "none")])
6329 ;; This is used in compiling the unwind routines.
6330 (define_expand "eh_return"
6331 [(use (match_operand 0 "general_operand"))]
6334 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
6336 if (GET_MODE (operands[0]) != gpr_mode)
6337 operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
6339 emit_insn (gen_eh_set_lr_di (operands[0]));
6341 emit_insn (gen_eh_set_lr_si (operands[0]));
6346 ;; Clobber the return address on the stack. We can't expand this
6347 ;; until we know where it will be put in the stack frame.
6349 (define_insn "eh_set_lr_si"
6350 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6351 (clobber (match_scratch:SI 1 "=&d"))]
6355 (define_insn "eh_set_lr_di"
6356 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6357 (clobber (match_scratch:DI 1 "=&d"))]
6362 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6363 (clobber (match_scratch 1))]
6364 "reload_completed && !TARGET_DEBUG_D_MODE"
6367 mips_set_return_address (operands[0], operands[1]);
6371 (define_insn_and_split "exception_receiver"
6373 (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
6374 "TARGET_ABICALLS && TARGET_OLDABI"
6376 "&& reload_completed"
6382 [(set_attr "type" "load")
6383 (set_attr "length" "12")])
6386 ;; ....................
6390 ;; ....................
6392 ;; Instructions to load a call address from the GOT. The address might
6393 ;; point to a function or to a lazy binding stub. In the latter case,
6394 ;; the stub will use the dynamic linker to resolve the function, which
6395 ;; in turn will change the GOT entry to point to the function's real
6398 ;; This means that every call, even pure and constant ones, can
6399 ;; potentially modify the GOT entry. And once a stub has been called,
6400 ;; we must not call it again.
6402 ;; We represent this restriction using an imaginary fixed register that
6403 ;; acts like a GOT version number. By making the register call-clobbered,
6404 ;; we tell the target-independent code that the address could be changed
6405 ;; by any call insn.
6406 (define_insn "load_callsi"
6407 [(set (match_operand:SI 0 "register_operand" "=c")
6408 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6409 (match_operand:SI 2 "immediate_operand" "")
6410 (reg:SI FAKE_CALL_REGNO)]
6414 [(set_attr "type" "load")
6415 (set_attr "length" "4")])
6417 (define_insn "load_calldi"
6418 [(set (match_operand:DI 0 "register_operand" "=c")
6419 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
6420 (match_operand:DI 2 "immediate_operand" "")
6421 (reg:DI FAKE_CALL_REGNO)]
6425 [(set_attr "type" "load")
6426 (set_attr "length" "4")])
6428 ;; Sibling calls. All these patterns use jump instructions.
6430 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
6431 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
6432 ;; is defined in terms of call_insn_operand, the same is true of the
6435 ;; When we use an indirect jump, we need a register that will be
6436 ;; preserved by the epilogue. Since TARGET_ABICALLS forces us to
6437 ;; use $25 for this purpose -- and $25 is never clobbered by the
6438 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
6440 (define_expand "sibcall"
6441 [(parallel [(call (match_operand 0 "")
6442 (match_operand 1 ""))
6443 (use (match_operand 2 "")) ;; next_arg_reg
6444 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
6447 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
6451 (define_insn "sibcall_internal"
6452 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
6453 (match_operand 1 "" ""))]
6454 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6458 [(set_attr "type" "call")])
6460 (define_expand "sibcall_value"
6461 [(parallel [(set (match_operand 0 "")
6462 (call (match_operand 1 "")
6463 (match_operand 2 "")))
6464 (use (match_operand 3 ""))])] ;; next_arg_reg
6467 mips_expand_call (operands[0], XEXP (operands[1], 0),
6468 operands[2], operands[3], true);
6472 (define_insn "sibcall_value_internal"
6473 [(set (match_operand 0 "register_operand" "=df,df")
6474 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6475 (match_operand 2 "" "")))]
6476 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6480 [(set_attr "type" "call")])
6482 (define_insn "sibcall_value_multiple_internal"
6483 [(set (match_operand 0 "register_operand" "=df,df")
6484 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6485 (match_operand 2 "" "")))
6486 (set (match_operand 3 "register_operand" "=df,df")
6487 (call (mem:SI (match_dup 1))
6489 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6493 [(set_attr "type" "call")])
6495 (define_expand "call"
6496 [(parallel [(call (match_operand 0 "")
6497 (match_operand 1 ""))
6498 (use (match_operand 2 "")) ;; next_arg_reg
6499 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
6502 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
6506 ;; This instruction directly corresponds to an assembly-language "jal".
6507 ;; There are four cases:
6510 ;; Both symbolic and register destinations are OK. The pattern
6511 ;; always expands to a single mips instruction.
6513 ;; - -mabicalls/-mno-explicit-relocs:
6514 ;; Again, both symbolic and register destinations are OK.
6515 ;; The call is treated as a multi-instruction black box.
6517 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
6518 ;; Only "jal $25" is allowed. This expands to a single "jalr $25"
6521 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
6522 ;; Only "jal $25" is allowed. The call is actually two instructions:
6523 ;; "jalr $25" followed by an insn to reload $gp.
6525 ;; In the last case, we can generate the individual instructions with
6526 ;; a define_split. There are several things to be wary of:
6528 ;; - We can't expose the load of $gp before reload. If we did,
6529 ;; it might get removed as dead, but reload can introduce new
6530 ;; uses of $gp by rematerializing constants.
6532 ;; - We shouldn't restore $gp after calls that never return.
6533 ;; It isn't valid to insert instructions between a noreturn
6534 ;; call and the following barrier.
6536 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
6537 ;; instruction preserves $gp and so have no effect on its liveness.
6538 ;; But once we generate the separate insns, it becomes obvious that
6539 ;; $gp is not live on entry to the call.
6541 ;; ??? The operands[2] = insn check is a hack to make the original insn
6542 ;; available to the splitter.
6543 (define_insn_and_split "call_internal"
6544 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
6545 (match_operand 1 "" ""))
6546 (clobber (reg:SI 31))]
6548 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
6549 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
6552 emit_call_insn (gen_call_split (operands[0], operands[1]));
6553 if (!find_reg_note (operands[2], REG_NORETURN, 0))
6557 [(set_attr "jal" "indirect,direct")
6558 (set_attr "extended_mips16" "no,yes")])
6560 (define_insn "call_split"
6561 [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
6562 (match_operand 1 "" ""))
6563 (clobber (reg:SI 31))
6564 (clobber (reg:SI 28))]
6565 "TARGET_SPLIT_CALLS"
6567 [(set_attr "type" "call")])
6569 (define_expand "call_value"
6570 [(parallel [(set (match_operand 0 "")
6571 (call (match_operand 1 "")
6572 (match_operand 2 "")))
6573 (use (match_operand 3 ""))])] ;; next_arg_reg
6576 mips_expand_call (operands[0], XEXP (operands[1], 0),
6577 operands[2], operands[3], false);
6581 ;; See comment for call_internal.
6582 (define_insn_and_split "call_value_internal"
6583 [(set (match_operand 0 "register_operand" "=df,df")
6584 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6585 (match_operand 2 "" "")))
6586 (clobber (reg:SI 31))]
6588 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
6589 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
6592 emit_call_insn (gen_call_value_split (operands[0], operands[1],
6594 if (!find_reg_note (operands[3], REG_NORETURN, 0))
6598 [(set_attr "jal" "indirect,direct")
6599 (set_attr "extended_mips16" "no,yes")])
6601 (define_insn "call_value_split"
6602 [(set (match_operand 0 "register_operand" "=df")
6603 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
6604 (match_operand 2 "" "")))
6605 (clobber (reg:SI 31))
6606 (clobber (reg:SI 28))]
6607 "TARGET_SPLIT_CALLS"
6609 [(set_attr "type" "call")])
6611 ;; See comment for call_internal.
6612 (define_insn_and_split "call_value_multiple_internal"
6613 [(set (match_operand 0 "register_operand" "=df,df")
6614 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6615 (match_operand 2 "" "")))
6616 (set (match_operand 3 "register_operand" "=df,df")
6617 (call (mem:SI (match_dup 1))
6619 (clobber (reg:SI 31))]
6621 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
6622 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
6625 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
6626 operands[2], operands[3]));
6627 if (!find_reg_note (operands[4], REG_NORETURN, 0))
6631 [(set_attr "jal" "indirect,direct")
6632 (set_attr "extended_mips16" "no,yes")])
6634 (define_insn "call_value_multiple_split"
6635 [(set (match_operand 0 "register_operand" "=df")
6636 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
6637 (match_operand 2 "" "")))
6638 (set (match_operand 3 "register_operand" "=df")
6639 (call (mem:SI (match_dup 1))
6641 (clobber (reg:SI 31))
6642 (clobber (reg:SI 28))]
6643 "TARGET_SPLIT_CALLS"
6645 [(set_attr "type" "call")])
6647 ;; Call subroutine returning any type.
6649 (define_expand "untyped_call"
6650 [(parallel [(call (match_operand 0 "")
6652 (match_operand 1 "")
6653 (match_operand 2 "")])]
6658 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6660 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6662 rtx set = XVECEXP (operands[2], 0, i);
6663 emit_move_insn (SET_DEST (set), SET_SRC (set));
6666 emit_insn (gen_blockage ());
6671 ;; ....................
6675 ;; ....................
6679 (define_expand "prefetch"
6680 [(prefetch (match_operand 0 "address_operand")
6681 (match_operand 1 "const_int_operand")
6682 (match_operand 2 "const_int_operand"))]
6685 if (symbolic_operand (operands[0], GET_MODE (operands[0])))
6686 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
6689 (define_insn "prefetch_si_address"
6690 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
6691 (match_operand:SI 3 "const_int_operand" "I"))
6692 (match_operand:SI 1 "const_int_operand" "n")
6693 (match_operand:SI 2 "const_int_operand" "n"))]
6694 "ISA_HAS_PREFETCH && Pmode == SImode"
6695 { return mips_emit_prefetch (operands); }
6696 [(set_attr "type" "prefetch")])
6698 (define_insn "prefetch_indexed_si"
6699 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
6700 (match_operand:SI 3 "register_operand" "r"))
6701 (match_operand:SI 1 "const_int_operand" "n")
6702 (match_operand:SI 2 "const_int_operand" "n"))]
6703 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
6704 { return mips_emit_prefetch (operands); }
6705 [(set_attr "type" "prefetchx")])
6707 (define_insn "prefetch_si"
6708 [(prefetch (match_operand:SI 0 "register_operand" "r")
6709 (match_operand:SI 1 "const_int_operand" "n")
6710 (match_operand:SI 2 "const_int_operand" "n"))]
6711 "ISA_HAS_PREFETCH && Pmode == SImode"
6713 operands[3] = const0_rtx;
6714 return mips_emit_prefetch (operands);
6716 [(set_attr "type" "prefetch")])
6718 (define_insn "prefetch_di_address"
6719 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
6720 (match_operand:DI 3 "const_int_operand" "I"))
6721 (match_operand:DI 1 "const_int_operand" "n")
6722 (match_operand:DI 2 "const_int_operand" "n"))]
6723 "ISA_HAS_PREFETCH && Pmode == DImode"
6724 { return mips_emit_prefetch (operands); }
6725 [(set_attr "type" "prefetch")])
6727 (define_insn "prefetch_indexed_di"
6728 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
6729 (match_operand:DI 3 "register_operand" "r"))
6730 (match_operand:DI 1 "const_int_operand" "n")
6731 (match_operand:DI 2 "const_int_operand" "n"))]
6732 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
6733 { return mips_emit_prefetch (operands); }
6734 [(set_attr "type" "prefetchx")])
6736 (define_insn "prefetch_di"
6737 [(prefetch (match_operand:DI 0 "register_operand" "r")
6738 (match_operand:DI 1 "const_int_operand" "n")
6739 (match_operand:DI 2 "const_int_operand" "n"))]
6740 "ISA_HAS_PREFETCH && Pmode == DImode"
6742 operands[3] = const0_rtx;
6743 return mips_emit_prefetch (operands);
6745 [(set_attr "type" "prefetch")])
6751 [(set_attr "type" "nop")
6752 (set_attr "mode" "none")])
6754 ;; Like nop, but commented out when outside a .set noreorder block.
6755 (define_insn "hazard_nop"
6764 [(set_attr "type" "nop")])
6766 ;; MIPS4 Conditional move instructions.
6769 [(set (match_operand:SI 0 "register_operand" "=d,d")
6771 (match_operator:SI 4 "equality_operator"
6772 [(match_operand:SI 1 "register_operand" "d,d")
6774 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
6775 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
6776 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
6780 [(set_attr "type" "condmove")
6781 (set_attr "mode" "SI")])
6784 [(set (match_operand:SI 0 "register_operand" "=d,d")
6786 (match_operator:DI 4 "equality_operator"
6787 [(match_operand:DI 1 "register_operand" "d,d")
6789 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
6790 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
6791 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
6795 [(set_attr "type" "condmove")
6796 (set_attr "mode" "SI")])
6799 [(set (match_operand:SI 0 "register_operand" "=d,d")
6801 (match_operator:CC 3 "equality_operator"
6802 [(match_operand:CC 4 "register_operand" "z,z")
6804 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
6805 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
6806 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6810 [(set_attr "type" "condmove")
6811 (set_attr "mode" "SI")])
6814 [(set (match_operand:DI 0 "register_operand" "=d,d")
6816 (match_operator:SI 4 "equality_operator"
6817 [(match_operand:SI 1 "register_operand" "d,d")
6819 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
6820 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
6821 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
6825 [(set_attr "type" "condmove")
6826 (set_attr "mode" "DI")])
6829 [(set (match_operand:DI 0 "register_operand" "=d,d")
6831 (match_operator:DI 4 "equality_operator"
6832 [(match_operand:DI 1 "register_operand" "d,d")
6834 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
6835 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
6836 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
6840 [(set_attr "type" "condmove")
6841 (set_attr "mode" "DI")])
6844 [(set (match_operand:DI 0 "register_operand" "=d,d")
6846 (match_operator:CC 3 "equality_operator"
6847 [(match_operand:CC 4 "register_operand" "z,z")
6849 (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
6850 (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
6851 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
6855 [(set_attr "type" "condmove")
6856 (set_attr "mode" "DI")])
6859 [(set (match_operand:SF 0 "register_operand" "=f,f")
6861 (match_operator:SI 4 "equality_operator"
6862 [(match_operand:SI 1 "register_operand" "d,d")
6864 (match_operand:SF 2 "register_operand" "f,0")
6865 (match_operand:SF 3 "register_operand" "0,f")))]
6866 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6870 [(set_attr "type" "condmove")
6871 (set_attr "mode" "SF")])
6874 [(set (match_operand:SF 0 "register_operand" "=f,f")
6876 (match_operator:DI 4 "equality_operator"
6877 [(match_operand:DI 1 "register_operand" "d,d")
6879 (match_operand:SF 2 "register_operand" "f,0")
6880 (match_operand:SF 3 "register_operand" "0,f")))]
6881 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6885 [(set_attr "type" "condmove")
6886 (set_attr "mode" "SF")])
6889 [(set (match_operand:SF 0 "register_operand" "=f,f")
6891 (match_operator:CC 3 "equality_operator"
6892 [(match_operand:CC 4 "register_operand" "z,z")
6894 (match_operand:SF 1 "register_operand" "f,0")
6895 (match_operand:SF 2 "register_operand" "0,f")))]
6896 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6900 [(set_attr "type" "condmove")
6901 (set_attr "mode" "SF")])
6904 [(set (match_operand:DF 0 "register_operand" "=f,f")
6906 (match_operator:SI 4 "equality_operator"
6907 [(match_operand:SI 1 "register_operand" "d,d")
6909 (match_operand:DF 2 "register_operand" "f,0")
6910 (match_operand:DF 3 "register_operand" "0,f")))]
6911 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6915 [(set_attr "type" "condmove")
6916 (set_attr "mode" "DF")])
6919 [(set (match_operand:DF 0 "register_operand" "=f,f")
6921 (match_operator:DI 4 "equality_operator"
6922 [(match_operand:DI 1 "register_operand" "d,d")
6924 (match_operand:DF 2 "register_operand" "f,0")
6925 (match_operand:DF 3 "register_operand" "0,f")))]
6926 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6930 [(set_attr "type" "condmove")
6931 (set_attr "mode" "DF")])
6934 [(set (match_operand:DF 0 "register_operand" "=f,f")
6936 (match_operator:CC 3 "equality_operator"
6937 [(match_operand:CC 4 "register_operand" "z,z")
6939 (match_operand:DF 1 "register_operand" "f,0")
6940 (match_operand:DF 2 "register_operand" "0,f")))]
6941 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6945 [(set_attr "type" "condmove")
6946 (set_attr "mode" "DF")])
6948 ;; These are the main define_expand's used to make conditional moves.
6950 (define_expand "movsicc"
6951 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6952 (set (match_operand:SI 0 "register_operand")
6953 (if_then_else:SI (match_dup 5)
6954 (match_operand:SI 2 "reg_or_0_operand")
6955 (match_operand:SI 3 "reg_or_0_operand")))]
6956 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
6958 gen_conditional_move (operands);
6962 (define_expand "movdicc"
6963 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6964 (set (match_operand:DI 0 "register_operand")
6965 (if_then_else:DI (match_dup 5)
6966 (match_operand:DI 2 "reg_or_0_operand")
6967 (match_operand:DI 3 "reg_or_0_operand")))]
6968 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
6970 gen_conditional_move (operands);
6974 (define_expand "movsfcc"
6975 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6976 (set (match_operand:SF 0 "register_operand")
6977 (if_then_else:SF (match_dup 5)
6978 (match_operand:SF 2 "register_operand")
6979 (match_operand:SF 3 "register_operand")))]
6980 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
6982 gen_conditional_move (operands);
6986 (define_expand "movdfcc"
6987 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6988 (set (match_operand:DF 0 "register_operand")
6989 (if_then_else:DF (match_dup 5)
6990 (match_operand:DF 2 "register_operand")
6991 (match_operand:DF 3 "register_operand")))]
6992 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6994 gen_conditional_move (operands);
6999 ;; ....................
7001 ;; mips16 inline constant tables
7003 ;; ....................
7006 (define_insn "consttable_int"
7007 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
7008 (match_operand 1 "const_int_operand" "")]
7009 UNSPEC_CONSTTABLE_INT)]
7012 assemble_integer (operands[0], INTVAL (operands[1]),
7013 BITS_PER_UNIT * INTVAL (operands[1]), 1);
7016 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
7018 (define_insn "consttable_float"
7019 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
7020 UNSPEC_CONSTTABLE_FLOAT)]
7025 if (GET_CODE (operands[0]) != CONST_DOUBLE)
7027 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7028 assemble_real (d, GET_MODE (operands[0]),
7029 GET_MODE_BITSIZE (GET_MODE (operands[0])));
7032 [(set (attr "length")
7033 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
7035 (define_insn "align"
7036 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
7039 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
7042 [(match_operand 0 "small_data_pattern")]
7045 { operands[0] = mips_rewrite_small_data (operands[0]); })