1 ;; Mips.md Machine Description for MIPS based processors
2 ;; Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 ;; Contributed by A. Lichnewsky, lich@inria.inria.fr
5 ;; Changes by Michael Meissner, meissner@osf.org
6 ;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
7 ;; Brendan Eich, brendan@microunity.com.
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING. If not, write to
23 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
27 [(UNSPEC_LOAD_DF_LOW 0)
28 (UNSPEC_LOAD_DF_HIGH 1)
29 (UNSPEC_STORE_DF_HIGH 2)
33 (UNSPEC_EH_RECEIVER 6)
35 (UNSPEC_CONSTTABLE_INT 8)
36 (UNSPEC_CONSTTABLE_FLOAT 9)
40 (UNSPEC_LOAD_RIGHT 19)
41 (UNSPEC_STORE_LEFT 20)
42 (UNSPEC_STORE_RIGHT 21)
49 (UNSPEC_ADDRESS_FIRST 100)
53 ;; For MIPS Paired-Singled Floating Point Instructions.
55 (UNSPEC_MOVE_TF_PS 200)
58 ;; MIPS64/MIPS32R2 alnv.ps
61 ;; MIPS-3D instructions
65 (UNSPEC_CVT_PW_PS 205)
66 (UNSPEC_CVT_PS_PW 206)
76 (include "predicates.md")
78 ;; ....................
82 ;; ....................
84 (define_attr "got" "unset,xgot_high,load"
85 (const_string "unset"))
87 ;; For jal instructions, this attribute is DIRECT when the target address
88 ;; is symbolic and INDIRECT when it is a register.
89 (define_attr "jal" "unset,direct,indirect"
90 (const_string "unset"))
92 ;; This attribute is YES if the instruction is a jal macro (not a
93 ;; real jal instruction).
95 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
96 ;; restore $gp. Direct jals are also macros in NewABI PIC since they
97 ;; load the target address into $25.
98 (define_attr "jal_macro" "no,yes"
99 (cond [(eq_attr "jal" "direct")
100 (symbol_ref "TARGET_ABICALLS != 0")
101 (eq_attr "jal" "indirect")
102 (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
103 (const_string "no")))
105 ;; Classification of each insn.
106 ;; branch conditional branch
107 ;; jump unconditional jump
108 ;; call unconditional call
109 ;; load load instruction(s)
110 ;; fpload floating point load
111 ;; fpidxload floating point indexed load
112 ;; store store instruction(s)
113 ;; fpstore floating point store
114 ;; fpidxstore floating point indexed store
115 ;; prefetch memory prefetch (register + offset)
116 ;; prefetchx memory indexed prefetch (register + register)
117 ;; condmove conditional moves
118 ;; xfer transfer to/from coprocessor
119 ;; mthilo transfer to hi/lo registers
120 ;; mfhilo transfer from hi/lo registers
121 ;; const load constant
122 ;; arith integer arithmetic and logical instructions
123 ;; shift integer shift instructions
124 ;; slt set less than instructions
125 ;; clz the clz and clo instructions
126 ;; trap trap if instructions
127 ;; imul integer multiply
128 ;; imadd integer multiply-add
129 ;; idiv integer divide
130 ;; fmove floating point register move
131 ;; fadd floating point add/subtract
132 ;; fmul floating point multiply
133 ;; fmadd floating point multiply-add
134 ;; fdiv floating point divide
135 ;; frdiv floating point reciprocal divide
136 ;; frdiv1 floating point reciprocal divide step 1
137 ;; frdiv2 floating point reciprocal divide step 2
138 ;; fabs floating point absolute value
139 ;; fneg floating point negation
140 ;; fcmp floating point compare
141 ;; fcvt floating point convert
142 ;; fsqrt floating point square root
143 ;; frsqrt floating point reciprocal square root
144 ;; frsqrt1 floating point reciprocal square root step1
145 ;; frsqrt2 floating point reciprocal square root step2
146 ;; multi multiword sequence (or user asm statements)
149 "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,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,multi,nop"
150 (cond [(eq_attr "jal" "!unset") (const_string "call")
151 (eq_attr "got" "load") (const_string "load")]
152 (const_string "unknown")))
154 ;; Main data type used by the insn
155 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
156 (const_string "unknown"))
158 ;; Is this an extended instruction in mips16 mode?
159 (define_attr "extended_mips16" "no,yes"
162 ;; Length of instruction in bytes.
163 (define_attr "length" ""
164 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
165 ;; If a branch is outside this range, we have a choice of two
166 ;; sequences. For PIC, an out-of-range branch like:
171 ;; becomes the equivalent of:
180 ;; where the load address can be up to three instructions long
183 ;; The non-PIC case is similar except that we use a direct
184 ;; jump instead of an la/jr pair. Since the target of this
185 ;; jump is an absolute 28-bit bit address (the other bits
186 ;; coming from the address of the delay slot) this form cannot
187 ;; cross a 256MB boundary. We could provide the option of
188 ;; using la/jr in this case too, but we do not do so at
191 ;; Note that this value does not account for the delay slot
192 ;; instruction, whose length is added separately. If the RTL
193 ;; pattern has no explicit delay slot, mips_adjust_insn_length
194 ;; will add the length of the implicit nop. The values for
195 ;; forward and backward branches will be different as well.
196 (eq_attr "type" "branch")
197 (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
198 (le (minus (pc) (match_dup 1)) (const_int 131068)))
200 (ne (symbol_ref "flag_pic") (const_int 0))
204 (eq_attr "got" "load")
206 (eq_attr "got" "xgot_high")
209 (eq_attr "type" "const")
210 (symbol_ref "mips_const_insns (operands[1]) * 4")
211 (eq_attr "type" "load,fpload")
212 (symbol_ref "mips_fetch_insns (operands[1]) * 4")
213 (eq_attr "type" "store,fpstore")
214 (symbol_ref "mips_fetch_insns (operands[0]) * 4")
216 ;; In the worst case, a call macro will take 8 instructions:
218 ;; lui $25,%call_hi(FOO)
220 ;; lw $25,%call_lo(FOO)($25)
226 (eq_attr "jal_macro" "yes")
229 (and (eq_attr "extended_mips16" "yes")
230 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
233 ;; Various VR4120 errata require a nop to be inserted after a macc
234 ;; instruction. The assembler does this for us, so account for
235 ;; the worst-case length here.
236 (and (eq_attr "type" "imadd")
237 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
240 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
241 ;; the result of the second one is missed. The assembler should work
242 ;; around this by inserting a nop after the first dmult.
243 (and (eq_attr "type" "imul")
244 (and (eq_attr "mode" "DI")
245 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
248 (eq_attr "type" "idiv")
249 (symbol_ref "mips_idiv_insns () * 4")
252 ;; Attribute describing the processor. This attribute must match exactly
253 ;; with the processor_type enumeration in mips.h.
255 "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
256 (const (symbol_ref "mips_tune")))
258 ;; The type of hardware hazard associated with this instruction.
259 ;; DELAY means that the next instruction cannot read the result
260 ;; of this one. HILO means that the next two instructions cannot
261 ;; write to HI or LO.
262 (define_attr "hazard" "none,delay,hilo"
263 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
264 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
265 (const_string "delay")
267 (and (eq_attr "type" "xfer")
268 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
269 (const_string "delay")
271 (and (eq_attr "type" "fcmp")
272 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
273 (const_string "delay")
275 ;; The r4000 multiplication patterns include an mflo instruction.
276 (and (eq_attr "type" "imul")
277 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
278 (const_string "hilo")
280 (and (eq_attr "type" "mfhilo")
281 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
282 (const_string "hilo")]
283 (const_string "none")))
285 ;; Is it a single instruction?
286 (define_attr "single_insn" "no,yes"
287 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
289 ;; Can the instruction be put into a delay slot?
290 (define_attr "can_delay" "no,yes"
291 (if_then_else (and (eq_attr "type" "!branch,call,jump")
292 (and (eq_attr "hazard" "none")
293 (eq_attr "single_insn" "yes")))
295 (const_string "no")))
297 ;; Attribute defining whether or not we can use the branch-likely instructions
298 (define_attr "branch_likely" "no,yes"
300 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
302 (const_string "no"))))
304 ;; True if an instruction might assign to hi or lo when reloaded.
305 ;; This is used by the TUNE_MACC_CHAINS code.
306 (define_attr "may_clobber_hilo" "no,yes"
307 (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
309 (const_string "no")))
311 ;; Describe a user's asm statement.
312 (define_asm_attributes
313 [(set_attr "type" "multi")])
315 ;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
316 ;; from the same template.
317 (define_mode_macro GPR [SI (DI "TARGET_64BIT")])
319 ;; This mode macro allows :P to be used for patterns that operate on
320 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
321 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
323 ;; This mode macro allows :MOVECC to be used anywhere that a
324 ;; conditional-move-type condition is needed.
325 (define_mode_macro MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
327 ;; This mode macro allows the QI and HI extension patterns to be defined from
328 ;; the same template.
329 (define_mode_macro SHORT [QI HI])
331 ;; This mode macro allows :ANYF to be used wherever a scalar or vector
332 ;; floating-point mode is allowed.
333 (define_mode_macro ANYF [(SF "TARGET_HARD_FLOAT")
334 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
335 (V2SF "TARGET_PAIRED_SINGLE_FLOAT")])
337 ;; Like ANYF, but only applies to scalar modes.
338 (define_mode_macro SCALARF [(SF "TARGET_HARD_FLOAT")
339 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
341 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
342 ;; 32-bit version and "dsubu" in the 64-bit version.
343 (define_mode_attr d [(SI "") (DI "d")])
345 ;; This attribute gives the length suffix for a sign- or zero-extension
347 (define_mode_attr size [(QI "b") (HI "h")])
349 ;; This attributes gives the mode mask of a SHORT.
350 (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
352 ;; Mode attributes for GPR loads and stores.
353 (define_mode_attr load [(SI "lw") (DI "ld")])
354 (define_mode_attr store [(SI "sw") (DI "sd")])
356 ;; Similarly for MIPS IV indexed FPR loads and stores.
357 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1")])
358 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1")])
360 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
361 ;; are different. Some forms of unextended addiu have an 8-bit immediate
362 ;; field but the equivalent daddiu has only a 5-bit field.
363 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
365 ;; This attribute gives the best constraint to use for registers of
367 (define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
369 ;; This attribute gives the format suffix for floating-point operations.
370 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
372 ;; This attribute gives the upper-case mode name for one unit of a
373 ;; floating-point mode.
374 (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
376 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
378 ;; In certain cases, div.s and div.ps may have a rounding error
379 ;; and/or wrong inexact flag.
381 ;; Therefore, we only allow div.s if not working around SB-1 rev2
382 ;; errata or if a slight loss of precision is OK.
383 (define_mode_attr divide_condition
384 [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")])
386 ;; This code macro allows all branch instructions to be generated from
387 ;; a single define_expand template.
388 (define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
389 eq ne gt ge lt le gtu geu ltu leu])
391 ;; This code macro allows signed and unsigned widening multiplications
392 ;; to use the same template.
393 (define_code_macro any_extend [sign_extend zero_extend])
395 ;; This code macro allows the three shift instructions to be generated
396 ;; from the same template.
397 (define_code_macro any_shift [ashift ashiftrt lshiftrt])
399 ;; This code macro allows all native floating-point comparisons to be
400 ;; generated from the same template.
401 (define_code_macro fcond [unordered uneq unlt unle eq lt le])
403 ;; <u> expands to an empty string when doing a signed operation and
404 ;; "u" when doing an unsigned operation.
405 (define_code_attr u [(sign_extend "") (zero_extend "u")])
407 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
408 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
410 ;; <optab> expands to the name of the optab for a particular code.
411 (define_code_attr optab [(ashift "ashl")
415 ;; <insn> expands to the name of the insn that implements a particular code.
416 (define_code_attr insn [(ashift "sll")
420 ;; <fcond> is the c.cond.fmt condition associated with a particular code.
421 (define_code_attr fcond [(unordered "un")
429 ;; .........................
431 ;; Branch, call and jump delay slots
433 ;; .........................
435 (define_delay (and (eq_attr "type" "branch")
436 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
437 [(eq_attr "can_delay" "yes")
439 (and (eq_attr "branch_likely" "yes")
440 (eq_attr "can_delay" "yes"))])
442 (define_delay (eq_attr "type" "jump")
443 [(eq_attr "can_delay" "yes")
447 (define_delay (and (eq_attr "type" "call")
448 (eq_attr "jal_macro" "no"))
449 [(eq_attr "can_delay" "yes")
453 ;; Pipeline descriptions.
455 ;; generic.md provides a fallback for processors without a specific
456 ;; pipeline description. It is derived from the old define_function_unit
457 ;; version and uses the "alu" and "imuldiv" units declared below.
459 ;; Some of the processor-specific files are also derived from old
460 ;; define_function_unit descriptions and simply override the parts of
461 ;; generic.md that don't apply. The other processor-specific files
462 ;; are self-contained.
463 (define_automaton "alu,imuldiv")
465 (define_cpu_unit "alu" "alu")
466 (define_cpu_unit "imuldiv" "imuldiv")
482 (include "generic.md")
485 ;; ....................
489 ;; ....................
493 [(trap_if (const_int 1) (const_int 0))]
496 if (ISA_HAS_COND_TRAP)
498 else if (TARGET_MIPS16)
503 [(set_attr "type" "trap")])
505 (define_expand "conditional_trap"
506 [(trap_if (match_operator 0 "comparison_operator"
507 [(match_dup 2) (match_dup 3)])
508 (match_operand 1 "const_int_operand"))]
511 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
512 && operands[1] == const0_rtx)
514 mips_gen_conditional_trap (operands);
521 (define_insn "*conditional_trap<mode>"
522 [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
523 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
524 (match_operand:GPR 2 "arith_operand" "dI")])
528 [(set_attr "type" "trap")])
531 ;; ....................
535 ;; ....................
538 (define_insn "add<mode>3"
539 [(set (match_operand:ANYF 0 "register_operand" "=f")
540 (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
541 (match_operand:ANYF 2 "register_operand" "f")))]
543 "add.<fmt>\t%0,%1,%2"
544 [(set_attr "type" "fadd")
545 (set_attr "mode" "<UNITMODE>")])
547 (define_expand "add<mode>3"
548 [(set (match_operand:GPR 0 "register_operand")
549 (plus:GPR (match_operand:GPR 1 "register_operand")
550 (match_operand:GPR 2 "arith_operand")))]
553 (define_insn "*add<mode>3"
554 [(set (match_operand:GPR 0 "register_operand" "=d,d")
555 (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
556 (match_operand:GPR 2 "arith_operand" "d,Q")))]
561 [(set_attr "type" "arith")
562 (set_attr "mode" "<MODE>")])
564 ;; We need to recognize MIPS16 stack pointer additions explicitly, since
565 ;; we don't have a constraint for $sp. These insns will be generated by
566 ;; the save_restore_insns functions.
568 (define_insn "*add<mode>3_sp1"
570 (plus:GPR (reg:GPR 29)
571 (match_operand:GPR 0 "const_arith_operand" "")))]
574 [(set_attr "type" "arith")
575 (set_attr "mode" "<MODE>")
576 (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
580 (define_insn "*add<mode>3_sp2"
581 [(set (match_operand:GPR 0 "register_operand" "=d")
582 (plus:GPR (reg:GPR 29)
583 (match_operand:GPR 1 "const_arith_operand" "")))]
586 [(set_attr "type" "arith")
587 (set_attr "mode" "<MODE>")
588 (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
592 (define_insn "*add<mode>3_mips16"
593 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
594 (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
595 (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
601 [(set_attr "type" "arith")
602 (set_attr "mode" "<MODE>")
603 (set_attr_alternative "length"
604 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
607 (if_then_else (match_operand 2 "m16_simm4_1")
613 ;; On the mips16, we can sometimes split an add of a constant which is
614 ;; a 4 byte instruction into two adds which are both 2 byte
615 ;; instructions. There are two cases: one where we are adding a
616 ;; constant plus a register to another register, and one where we are
617 ;; simply adding a constant to a register.
620 [(set (match_operand:SI 0 "register_operand")
621 (plus:SI (match_dup 0)
622 (match_operand:SI 1 "const_int_operand")))]
623 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
624 && GET_CODE (operands[0]) == REG
625 && M16_REG_P (REGNO (operands[0]))
626 && GET_CODE (operands[1]) == CONST_INT
627 && ((INTVAL (operands[1]) > 0x7f
628 && INTVAL (operands[1]) <= 0x7f + 0x7f)
629 || (INTVAL (operands[1]) < - 0x80
630 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
631 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
632 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
634 HOST_WIDE_INT val = INTVAL (operands[1]);
638 operands[1] = GEN_INT (0x7f);
639 operands[2] = GEN_INT (val - 0x7f);
643 operands[1] = GEN_INT (- 0x80);
644 operands[2] = GEN_INT (val + 0x80);
649 [(set (match_operand:SI 0 "register_operand")
650 (plus:SI (match_operand:SI 1 "register_operand")
651 (match_operand:SI 2 "const_int_operand")))]
652 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
653 && GET_CODE (operands[0]) == REG
654 && M16_REG_P (REGNO (operands[0]))
655 && GET_CODE (operands[1]) == REG
656 && M16_REG_P (REGNO (operands[1]))
657 && REGNO (operands[0]) != REGNO (operands[1])
658 && GET_CODE (operands[2]) == CONST_INT
659 && ((INTVAL (operands[2]) > 0x7
660 && INTVAL (operands[2]) <= 0x7 + 0x7f)
661 || (INTVAL (operands[2]) < - 0x8
662 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
663 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
664 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
666 HOST_WIDE_INT val = INTVAL (operands[2]);
670 operands[2] = GEN_INT (0x7);
671 operands[3] = GEN_INT (val - 0x7);
675 operands[2] = GEN_INT (- 0x8);
676 operands[3] = GEN_INT (val + 0x8);
681 [(set (match_operand:DI 0 "register_operand")
682 (plus:DI (match_dup 0)
683 (match_operand:DI 1 "const_int_operand")))]
684 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
685 && GET_CODE (operands[0]) == REG
686 && M16_REG_P (REGNO (operands[0]))
687 && GET_CODE (operands[1]) == CONST_INT
688 && ((INTVAL (operands[1]) > 0xf
689 && INTVAL (operands[1]) <= 0xf + 0xf)
690 || (INTVAL (operands[1]) < - 0x10
691 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
692 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
693 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
695 HOST_WIDE_INT val = INTVAL (operands[1]);
699 operands[1] = GEN_INT (0xf);
700 operands[2] = GEN_INT (val - 0xf);
704 operands[1] = GEN_INT (- 0x10);
705 operands[2] = GEN_INT (val + 0x10);
710 [(set (match_operand:DI 0 "register_operand")
711 (plus:DI (match_operand:DI 1 "register_operand")
712 (match_operand:DI 2 "const_int_operand")))]
713 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
714 && GET_CODE (operands[0]) == REG
715 && M16_REG_P (REGNO (operands[0]))
716 && GET_CODE (operands[1]) == REG
717 && M16_REG_P (REGNO (operands[1]))
718 && REGNO (operands[0]) != REGNO (operands[1])
719 && GET_CODE (operands[2]) == CONST_INT
720 && ((INTVAL (operands[2]) > 0x7
721 && INTVAL (operands[2]) <= 0x7 + 0xf)
722 || (INTVAL (operands[2]) < - 0x8
723 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
724 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
725 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
727 HOST_WIDE_INT val = INTVAL (operands[2]);
731 operands[2] = GEN_INT (0x7);
732 operands[3] = GEN_INT (val - 0x7);
736 operands[2] = GEN_INT (- 0x8);
737 operands[3] = GEN_INT (val + 0x8);
741 (define_insn "*addsi3_extended"
742 [(set (match_operand:DI 0 "register_operand" "=d,d")
744 (plus:SI (match_operand:SI 1 "register_operand" "d,d")
745 (match_operand:SI 2 "arith_operand" "d,Q"))))]
746 "TARGET_64BIT && !TARGET_MIPS16"
750 [(set_attr "type" "arith")
751 (set_attr "mode" "SI")])
753 ;; Split this insn so that the addiu splitters can have a crack at it.
754 ;; Use a conservative length estimate until the split.
755 (define_insn_and_split "*addsi3_extended_mips16"
756 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
758 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
759 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
760 "TARGET_64BIT && TARGET_MIPS16"
762 "&& reload_completed"
763 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
764 { operands[3] = gen_lowpart (SImode, operands[0]); }
765 [(set_attr "type" "arith")
766 (set_attr "mode" "SI")
767 (set_attr "extended_mips16" "yes")])
770 ;; ....................
774 ;; ....................
777 (define_insn "sub<mode>3"
778 [(set (match_operand:ANYF 0 "register_operand" "=f")
779 (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
780 (match_operand:ANYF 2 "register_operand" "f")))]
782 "sub.<fmt>\t%0,%1,%2"
783 [(set_attr "type" "fadd")
784 (set_attr "mode" "<UNITMODE>")])
786 (define_insn "sub<mode>3"
787 [(set (match_operand:GPR 0 "register_operand" "=d")
788 (minus:GPR (match_operand:GPR 1 "register_operand" "d")
789 (match_operand:GPR 2 "register_operand" "d")))]
792 [(set_attr "type" "arith")
793 (set_attr "mode" "<MODE>")])
795 (define_insn "*subsi3_extended"
796 [(set (match_operand:DI 0 "register_operand" "=d")
798 (minus:SI (match_operand:SI 1 "register_operand" "d")
799 (match_operand:SI 2 "register_operand" "d"))))]
802 [(set_attr "type" "arith")
803 (set_attr "mode" "DI")])
806 ;; ....................
810 ;; ....................
813 (define_expand "mul<mode>3"
814 [(set (match_operand:SCALARF 0 "register_operand")
815 (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
816 (match_operand:SCALARF 2 "register_operand")))]
820 (define_insn "*mul<mode>3"
821 [(set (match_operand:SCALARF 0 "register_operand" "=f")
822 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
823 (match_operand:SCALARF 2 "register_operand" "f")))]
824 "!TARGET_4300_MUL_FIX"
825 "mul.<fmt>\t%0,%1,%2"
826 [(set_attr "type" "fmul")
827 (set_attr "mode" "<MODE>")])
829 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
830 ;; operands may corrupt immediately following multiplies. This is a
831 ;; simple fix to insert NOPs.
833 (define_insn "*mul<mode>3_r4300"
834 [(set (match_operand:SCALARF 0 "register_operand" "=f")
835 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
836 (match_operand:SCALARF 2 "register_operand" "f")))]
837 "TARGET_4300_MUL_FIX"
838 "mul.<fmt>\t%0,%1,%2\;nop"
839 [(set_attr "type" "fmul")
840 (set_attr "mode" "<MODE>")
841 (set_attr "length" "8")])
843 (define_insn "mulv2sf3"
844 [(set (match_operand:V2SF 0 "register_operand" "=f")
845 (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
846 (match_operand:V2SF 2 "register_operand" "f")))]
847 "TARGET_PAIRED_SINGLE_FLOAT"
849 [(set_attr "type" "fmul")
850 (set_attr "mode" "SF")])
852 ;; The original R4000 has a cpu bug. If a double-word or a variable
853 ;; shift executes while an integer multiplication is in progress, the
854 ;; shift may give an incorrect result. Avoid this by keeping the mflo
855 ;; with the mult on the R4000.
857 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
858 ;; (also valid for MIPS R4000MC processors):
860 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
861 ;; this errata description.
862 ;; The following code sequence causes the R4000 to incorrectly
863 ;; execute the Double Shift Right Arithmetic 32 (dsra32)
864 ;; instruction. If the dsra32 instruction is executed during an
865 ;; integer multiply, the dsra32 will only shift by the amount in
866 ;; specified in the instruction rather than the amount plus 32
868 ;; instruction 1: mult rs,rt integer multiply
869 ;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
870 ;; right arithmetic + 32
871 ;; Workaround: A dsra32 instruction placed after an integer
872 ;; multiply should not be one of the 11 instructions after the
873 ;; multiply instruction."
877 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
878 ;; the following description.
879 ;; All extended shifts (shift by n+32) and variable shifts (32 and
880 ;; 64-bit versions) may produce incorrect results under the
881 ;; following conditions:
882 ;; 1) An integer multiply is currently executing
883 ;; 2) These types of shift instructions are executed immediately
884 ;; following an integer divide instruction.
886 ;; 1) Make sure no integer multiply is running wihen these
887 ;; instruction are executed. If this cannot be predicted at
888 ;; compile time, then insert a "mfhi" to R0 instruction
889 ;; immediately after the integer multiply instruction. This
890 ;; will cause the integer multiply to complete before the shift
892 ;; 2) Separate integer divide and these two classes of shift
893 ;; instructions by another instruction or a noop."
895 ;; These processors have PRId values of 0x00004220 and 0x00004300,
898 (define_expand "mul<mode>3"
899 [(set (match_operand:GPR 0 "register_operand")
900 (mult:GPR (match_operand:GPR 1 "register_operand")
901 (match_operand:GPR 2 "register_operand")))]
904 if (GENERATE_MULT3_<MODE>)
905 emit_insn (gen_mul<mode>3_mult3 (operands[0], operands[1], operands[2]));
906 else if (!TARGET_FIX_R4000)
907 emit_insn (gen_mul<mode>3_internal (operands[0], operands[1],
910 emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
914 (define_insn "mulsi3_mult3"
915 [(set (match_operand:SI 0 "register_operand" "=d,l")
916 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
917 (match_operand:SI 2 "register_operand" "d,d")))
918 (clobber (match_scratch:SI 3 "=h,h"))
919 (clobber (match_scratch:SI 4 "=l,X"))]
922 if (which_alternative == 1)
923 return "mult\t%1,%2";
932 return "mul\t%0,%1,%2";
933 return "mult\t%0,%1,%2";
935 [(set_attr "type" "imul")
936 (set_attr "mode" "SI")])
938 (define_insn "muldi3_mult3"
939 [(set (match_operand:DI 0 "register_operand" "=d")
940 (mult:DI (match_operand:DI 1 "register_operand" "d")
941 (match_operand:DI 2 "register_operand" "d")))
942 (clobber (match_scratch:DI 3 "=h"))
943 (clobber (match_scratch:DI 4 "=l"))]
944 "TARGET_64BIT && GENERATE_MULT3_DI"
946 [(set_attr "type" "imul")
947 (set_attr "mode" "DI")])
949 ;; If a register gets allocated to LO, and we spill to memory, the reload
950 ;; will include a move from LO to a GPR. Merge it into the multiplication
951 ;; if it can set the GPR directly.
954 ;; Operand 1: GPR (1st multiplication operand)
955 ;; Operand 2: GPR (2nd multiplication operand)
957 ;; Operand 4: GPR (destination)
960 [(set (match_operand:SI 0 "register_operand")
961 (mult:SI (match_operand:SI 1 "register_operand")
962 (match_operand:SI 2 "register_operand")))
963 (clobber (match_operand:SI 3 "register_operand"))
964 (clobber (scratch:SI))])
965 (set (match_operand:SI 4 "register_operand")
966 (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
967 "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
970 (mult:SI (match_dup 1)
972 (clobber (match_dup 3))
973 (clobber (match_dup 0))])])
975 (define_insn "mul<mode>3_internal"
976 [(set (match_operand:GPR 0 "register_operand" "=l")
977 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
978 (match_operand:GPR 2 "register_operand" "d")))
979 (clobber (match_scratch:GPR 3 "=h"))]
982 [(set_attr "type" "imul")
983 (set_attr "mode" "<MODE>")])
985 (define_insn "mul<mode>3_r4000"
986 [(set (match_operand:GPR 0 "register_operand" "=d")
987 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
988 (match_operand:GPR 2 "register_operand" "d")))
989 (clobber (match_scratch:GPR 3 "=h"))
990 (clobber (match_scratch:GPR 4 "=l"))]
992 "<d>mult\t%1,%2\;mflo\t%0"
993 [(set_attr "type" "imul")
994 (set_attr "mode" "<MODE>")
995 (set_attr "length" "8")])
997 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
998 ;; of "mult; mflo". They have the same latency, but the first form gives
999 ;; us an extra cycle to compute the operands.
1002 ;; Operand 1: GPR (1st multiplication operand)
1003 ;; Operand 2: GPR (2nd multiplication operand)
1005 ;; Operand 4: GPR (destination)
1008 [(set (match_operand:SI 0 "register_operand")
1009 (mult:SI (match_operand:SI 1 "register_operand")
1010 (match_operand:SI 2 "register_operand")))
1011 (clobber (match_operand:SI 3 "register_operand"))])
1012 (set (match_operand:SI 4 "register_operand")
1013 (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1014 "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1019 (plus:SI (mult:SI (match_dup 1)
1023 (plus:SI (mult:SI (match_dup 1)
1026 (clobber (match_dup 3))])])
1028 ;; Multiply-accumulate patterns
1030 ;; For processors that can copy the output to a general register:
1032 ;; The all-d alternative is needed because the combiner will find this
1033 ;; pattern and then register alloc/reload will move registers around to
1034 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1036 ;; The last alternative should be made slightly less desirable, but adding
1037 ;; "?" to the constraint is too strong, and causes values to be loaded into
1038 ;; LO even when that's more costly. For now, using "*d" mostly does the
1040 (define_insn "*mul_acc_si"
1041 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1042 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1043 (match_operand:SI 2 "register_operand" "d,d,d"))
1044 (match_operand:SI 3 "register_operand" "0,l,*d")))
1045 (clobber (match_scratch:SI 4 "=h,h,h"))
1046 (clobber (match_scratch:SI 5 "=X,3,l"))
1047 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1049 || ISA_HAS_MADD_MSUB)
1052 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1053 if (which_alternative == 2)
1055 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1057 return madd[which_alternative];
1059 [(set_attr "type" "imadd,imadd,multi")
1060 (set_attr "mode" "SI")
1061 (set_attr "length" "4,4,8")])
1063 ;; Split the above insn if we failed to get LO allocated.
1065 [(set (match_operand:SI 0 "register_operand")
1066 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1067 (match_operand:SI 2 "register_operand"))
1068 (match_operand:SI 3 "register_operand")))
1069 (clobber (match_scratch:SI 4))
1070 (clobber (match_scratch:SI 5))
1071 (clobber (match_scratch:SI 6))]
1072 "reload_completed && !TARGET_DEBUG_D_MODE
1073 && GP_REG_P (true_regnum (operands[0]))
1074 && GP_REG_P (true_regnum (operands[3]))"
1075 [(parallel [(set (match_dup 6)
1076 (mult:SI (match_dup 1) (match_dup 2)))
1077 (clobber (match_dup 4))
1078 (clobber (match_dup 5))])
1079 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1082 ;; Splitter to copy result of MADD to a general register
1084 [(set (match_operand:SI 0 "register_operand")
1085 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1086 (match_operand:SI 2 "register_operand"))
1087 (match_operand:SI 3 "register_operand")))
1088 (clobber (match_scratch:SI 4))
1089 (clobber (match_scratch:SI 5))
1090 (clobber (match_scratch:SI 6))]
1091 "reload_completed && !TARGET_DEBUG_D_MODE
1092 && GP_REG_P (true_regnum (operands[0]))
1093 && true_regnum (operands[3]) == LO_REGNUM"
1094 [(parallel [(set (match_dup 3)
1095 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1097 (clobber (match_dup 4))
1098 (clobber (match_dup 5))
1099 (clobber (match_dup 6))])
1100 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1103 (define_insn "*macc"
1104 [(set (match_operand:SI 0 "register_operand" "=l,d")
1105 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1106 (match_operand:SI 2 "register_operand" "d,d"))
1107 (match_operand:SI 3 "register_operand" "0,l")))
1108 (clobber (match_scratch:SI 4 "=h,h"))
1109 (clobber (match_scratch:SI 5 "=X,3"))]
1112 if (which_alternative == 1)
1113 return "macc\t%0,%1,%2";
1114 else if (TARGET_MIPS5500)
1115 return "madd\t%1,%2";
1117 /* The VR4130 assumes that there is a two-cycle latency between a macc
1118 that "writes" to $0 and an instruction that reads from it. We avoid
1119 this by assigning to $1 instead. */
1120 return "%[macc\t%@,%1,%2%]";
1122 [(set_attr "type" "imadd")
1123 (set_attr "mode" "SI")])
1125 (define_insn "*msac"
1126 [(set (match_operand:SI 0 "register_operand" "=l,d")
1127 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1128 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1129 (match_operand:SI 3 "register_operand" "d,d"))))
1130 (clobber (match_scratch:SI 4 "=h,h"))
1131 (clobber (match_scratch:SI 5 "=X,1"))]
1134 if (which_alternative == 1)
1135 return "msac\t%0,%2,%3";
1136 else if (TARGET_MIPS5500)
1137 return "msub\t%2,%3";
1139 return "msac\t$0,%2,%3";
1141 [(set_attr "type" "imadd")
1142 (set_attr "mode" "SI")])
1144 ;; An msac-like instruction implemented using negation and a macc.
1145 (define_insn_and_split "*msac_using_macc"
1146 [(set (match_operand:SI 0 "register_operand" "=l,d")
1147 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1148 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1149 (match_operand:SI 3 "register_operand" "d,d"))))
1150 (clobber (match_scratch:SI 4 "=h,h"))
1151 (clobber (match_scratch:SI 5 "=X,1"))
1152 (clobber (match_scratch:SI 6 "=d,d"))]
1153 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1155 "&& reload_completed"
1157 (neg:SI (match_dup 3)))
1160 (plus:SI (mult:SI (match_dup 2)
1163 (clobber (match_dup 4))
1164 (clobber (match_dup 5))])]
1166 [(set_attr "type" "imadd")
1167 (set_attr "length" "8")])
1169 ;; Patterns generated by the define_peephole2 below.
1171 (define_insn "*macc2"
1172 [(set (match_operand:SI 0 "register_operand" "=l")
1173 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1174 (match_operand:SI 2 "register_operand" "d"))
1176 (set (match_operand:SI 3 "register_operand" "=d")
1177 (plus:SI (mult:SI (match_dup 1)
1180 (clobber (match_scratch:SI 4 "=h"))]
1181 "ISA_HAS_MACC && reload_completed"
1183 [(set_attr "type" "imadd")
1184 (set_attr "mode" "SI")])
1186 (define_insn "*msac2"
1187 [(set (match_operand:SI 0 "register_operand" "=l")
1188 (minus:SI (match_dup 0)
1189 (mult:SI (match_operand:SI 1 "register_operand" "d")
1190 (match_operand:SI 2 "register_operand" "d"))))
1191 (set (match_operand:SI 3 "register_operand" "=d")
1192 (minus:SI (match_dup 0)
1193 (mult:SI (match_dup 1)
1195 (clobber (match_scratch:SI 4 "=h"))]
1196 "ISA_HAS_MSAC && reload_completed"
1198 [(set_attr "type" "imadd")
1199 (set_attr "mode" "SI")])
1201 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1205 ;; Operand 1: macc/msac
1207 ;; Operand 3: GPR (destination)
1210 [(set (match_operand:SI 0 "register_operand")
1211 (match_operand:SI 1 "macc_msac_operand"))
1212 (clobber (match_operand:SI 2 "register_operand"))
1213 (clobber (scratch:SI))])
1214 (set (match_operand:SI 3 "register_operand")
1215 (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1217 [(parallel [(set (match_dup 0)
1221 (clobber (match_dup 2))])]
1224 ;; When we have a three-address multiplication instruction, it should
1225 ;; be faster to do a separate multiply and add, rather than moving
1226 ;; something into LO in order to use a macc instruction.
1228 ;; This peephole needs a scratch register to cater for the case when one
1229 ;; of the multiplication operands is the same as the destination.
1231 ;; Operand 0: GPR (scratch)
1233 ;; Operand 2: GPR (addend)
1234 ;; Operand 3: GPR (destination)
1235 ;; Operand 4: macc/msac
1237 ;; Operand 6: new multiplication
1238 ;; Operand 7: new addition/subtraction
1240 [(match_scratch:SI 0 "d")
1241 (set (match_operand:SI 1 "register_operand")
1242 (match_operand:SI 2 "register_operand"))
1245 [(set (match_operand:SI 3 "register_operand")
1246 (match_operand:SI 4 "macc_msac_operand"))
1247 (clobber (match_operand:SI 5 "register_operand"))
1248 (clobber (match_dup 1))])]
1250 && true_regnum (operands[1]) == LO_REGNUM
1251 && peep2_reg_dead_p (2, operands[1])
1252 && GP_REG_P (true_regnum (operands[3]))"
1253 [(parallel [(set (match_dup 0)
1255 (clobber (match_dup 5))
1256 (clobber (match_dup 1))])
1260 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1261 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1262 operands[2], operands[0]);
1265 ;; Same as above, except LO is the initial target of the macc.
1267 ;; Operand 0: GPR (scratch)
1269 ;; Operand 2: GPR (addend)
1270 ;; Operand 3: macc/msac
1272 ;; Operand 5: GPR (destination)
1273 ;; Operand 6: new multiplication
1274 ;; Operand 7: new addition/subtraction
1276 [(match_scratch:SI 0 "d")
1277 (set (match_operand:SI 1 "register_operand")
1278 (match_operand:SI 2 "register_operand"))
1282 (match_operand:SI 3 "macc_msac_operand"))
1283 (clobber (match_operand:SI 4 "register_operand"))
1284 (clobber (scratch:SI))])
1286 (set (match_operand:SI 5 "register_operand")
1287 (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1288 "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1289 [(parallel [(set (match_dup 0)
1291 (clobber (match_dup 4))
1292 (clobber (match_dup 1))])
1296 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1297 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1298 operands[2], operands[0]);
1301 (define_insn "*mul_sub_si"
1302 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1303 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1304 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1305 (match_operand:SI 3 "register_operand" "d,d,d"))))
1306 (clobber (match_scratch:SI 4 "=h,h,h"))
1307 (clobber (match_scratch:SI 5 "=X,1,l"))
1308 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1314 [(set_attr "type" "imadd,multi,multi")
1315 (set_attr "mode" "SI")
1316 (set_attr "length" "4,8,8")])
1318 ;; Split the above insn if we failed to get LO allocated.
1320 [(set (match_operand:SI 0 "register_operand")
1321 (minus:SI (match_operand:SI 1 "register_operand")
1322 (mult:SI (match_operand:SI 2 "register_operand")
1323 (match_operand:SI 3 "register_operand"))))
1324 (clobber (match_scratch:SI 4))
1325 (clobber (match_scratch:SI 5))
1326 (clobber (match_scratch:SI 6))]
1327 "reload_completed && !TARGET_DEBUG_D_MODE
1328 && GP_REG_P (true_regnum (operands[0]))
1329 && GP_REG_P (true_regnum (operands[1]))"
1330 [(parallel [(set (match_dup 6)
1331 (mult:SI (match_dup 2) (match_dup 3)))
1332 (clobber (match_dup 4))
1333 (clobber (match_dup 5))])
1334 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1337 ;; Splitter to copy result of MSUB to a general register
1339 [(set (match_operand:SI 0 "register_operand")
1340 (minus:SI (match_operand:SI 1 "register_operand")
1341 (mult:SI (match_operand:SI 2 "register_operand")
1342 (match_operand:SI 3 "register_operand"))))
1343 (clobber (match_scratch:SI 4))
1344 (clobber (match_scratch:SI 5))
1345 (clobber (match_scratch:SI 6))]
1346 "reload_completed && !TARGET_DEBUG_D_MODE
1347 && GP_REG_P (true_regnum (operands[0]))
1348 && true_regnum (operands[1]) == LO_REGNUM"
1349 [(parallel [(set (match_dup 1)
1350 (minus:SI (match_dup 1)
1351 (mult:SI (match_dup 2) (match_dup 3))))
1352 (clobber (match_dup 4))
1353 (clobber (match_dup 5))
1354 (clobber (match_dup 6))])
1355 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1358 (define_insn "*muls"
1359 [(set (match_operand:SI 0 "register_operand" "=l,d")
1360 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1361 (match_operand:SI 2 "register_operand" "d,d"))))
1362 (clobber (match_scratch:SI 3 "=h,h"))
1363 (clobber (match_scratch:SI 4 "=X,l"))]
1368 [(set_attr "type" "imul")
1369 (set_attr "mode" "SI")])
1371 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1373 (define_expand "<u>mulsidi3"
1375 [(set (match_operand:DI 0 "register_operand")
1376 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1377 (any_extend:DI (match_operand:SI 2 "register_operand"))))
1378 (clobber (scratch:DI))
1379 (clobber (scratch:DI))
1380 (clobber (scratch:DI))])]
1381 "!TARGET_64BIT || !TARGET_FIX_R4000"
1385 if (!TARGET_FIX_R4000)
1386 emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1389 emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1395 (define_insn "<u>mulsidi3_32bit_internal"
1396 [(set (match_operand:DI 0 "register_operand" "=x")
1397 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1398 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1399 "!TARGET_64BIT && !TARGET_FIX_R4000"
1401 [(set_attr "type" "imul")
1402 (set_attr "mode" "SI")])
1404 (define_insn "<u>mulsidi3_32bit_r4000"
1405 [(set (match_operand:DI 0 "register_operand" "=d")
1406 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1407 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1408 (clobber (match_scratch:DI 3 "=x"))]
1409 "!TARGET_64BIT && TARGET_FIX_R4000"
1410 "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1411 [(set_attr "type" "imul")
1412 (set_attr "mode" "SI")
1413 (set_attr "length" "12")])
1415 (define_insn_and_split "*<u>mulsidi3_64bit"
1416 [(set (match_operand:DI 0 "register_operand" "=d")
1417 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1418 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1419 (clobber (match_scratch:DI 3 "=l"))
1420 (clobber (match_scratch:DI 4 "=h"))
1421 (clobber (match_scratch:DI 5 "=d"))]
1422 "TARGET_64BIT && !TARGET_FIX_R4000"
1424 "&& reload_completed"
1428 (mult:SI (match_dup 1)
1432 (mult:DI (any_extend:DI (match_dup 1))
1433 (any_extend:DI (match_dup 2)))
1436 ;; OP5 <- LO, OP0 <- HI
1437 (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1438 (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1442 (ashift:DI (match_dup 5)
1445 (lshiftrt:DI (match_dup 5)
1448 ;; Shift OP0 into place.
1450 (ashift:DI (match_dup 0)
1453 ;; OR the two halves together
1455 (ior:DI (match_dup 0)
1458 [(set_attr "type" "imul")
1459 (set_attr "mode" "SI")
1460 (set_attr "length" "24")])
1462 (define_insn "*<u>mulsidi3_64bit_parts"
1463 [(set (match_operand:DI 0 "register_operand" "=l")
1465 (mult:SI (match_operand:SI 2 "register_operand" "d")
1466 (match_operand:SI 3 "register_operand" "d"))))
1467 (set (match_operand:DI 1 "register_operand" "=h")
1469 (mult:DI (any_extend:DI (match_dup 2))
1470 (any_extend:DI (match_dup 3)))
1472 "TARGET_64BIT && !TARGET_FIX_R4000"
1474 [(set_attr "type" "imul")
1475 (set_attr "mode" "SI")])
1477 ;; Widening multiply with negation.
1478 (define_insn "*muls<u>_di"
1479 [(set (match_operand:DI 0 "register_operand" "=x")
1482 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1483 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1484 "!TARGET_64BIT && ISA_HAS_MULS"
1486 [(set_attr "type" "imul")
1487 (set_attr "mode" "SI")])
1489 (define_insn "*msac<u>_di"
1490 [(set (match_operand:DI 0 "register_operand" "=x")
1492 (match_operand:DI 3 "register_operand" "0")
1494 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1495 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1496 "!TARGET_64BIT && ISA_HAS_MSAC"
1498 if (TARGET_MIPS5500)
1499 return "msub<u>\t%1,%2";
1501 return "msac<u>\t$0,%1,%2";
1503 [(set_attr "type" "imadd")
1504 (set_attr "mode" "SI")])
1506 ;; _highpart patterns
1508 (define_expand "<su>mulsi3_highpart"
1509 [(set (match_operand:SI 0 "register_operand")
1512 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1513 (any_extend:DI (match_operand:SI 2 "register_operand")))
1515 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1518 emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1522 emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1527 (define_insn "<su>mulsi3_highpart_internal"
1528 [(set (match_operand:SI 0 "register_operand" "=h")
1531 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1532 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1534 (clobber (match_scratch:SI 3 "=l"))]
1535 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1537 [(set_attr "type" "imul")
1538 (set_attr "mode" "SI")])
1540 (define_insn "<su>mulsi3_highpart_mulhi_internal"
1541 [(set (match_operand:SI 0 "register_operand" "=h,d")
1545 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1546 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1548 (clobber (match_scratch:SI 3 "=l,l"))
1549 (clobber (match_scratch:SI 4 "=X,h"))]
1554 [(set_attr "type" "imul")
1555 (set_attr "mode" "SI")])
1557 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1558 [(set (match_operand:SI 0 "register_operand" "=h,d")
1563 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1564 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1566 (clobber (match_scratch:SI 3 "=l,l"))
1567 (clobber (match_scratch:SI 4 "=X,h"))]
1571 mulshi<u>\t%0,%1,%2"
1572 [(set_attr "type" "imul")
1573 (set_attr "mode" "SI")])
1575 ;; Disable unsigned multiplication for -mfix-vr4120. This is for VR4120
1576 ;; errata MD(0), which says that dmultu does not always produce the
1578 (define_insn "<su>muldi3_highpart"
1579 [(set (match_operand:DI 0 "register_operand" "=h")
1583 (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1584 (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1586 (clobber (match_scratch:DI 3 "=l"))]
1587 "TARGET_64BIT && !TARGET_FIX_R4000
1588 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1590 [(set_attr "type" "imul")
1591 (set_attr "mode" "DI")])
1593 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1594 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
1596 (define_insn "madsi"
1597 [(set (match_operand:SI 0 "register_operand" "+l")
1598 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1599 (match_operand:SI 2 "register_operand" "d"))
1601 (clobber (match_scratch:SI 3 "=h"))]
1604 [(set_attr "type" "imadd")
1605 (set_attr "mode" "SI")])
1607 (define_insn "*<su>mul_acc_di"
1608 [(set (match_operand:DI 0 "register_operand" "=x")
1610 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1611 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1612 (match_operand:DI 3 "register_operand" "0")))]
1613 "(TARGET_MAD || ISA_HAS_MACC)
1617 return "mad<u>\t%1,%2";
1618 else if (TARGET_MIPS5500)
1619 return "madd<u>\t%1,%2";
1621 /* See comment in *macc. */
1622 return "%[macc<u>\t%@,%1,%2%]";
1624 [(set_attr "type" "imadd")
1625 (set_attr "mode" "SI")])
1627 ;; Floating point multiply accumulate instructions.
1629 (define_insn "*madd<mode>"
1630 [(set (match_operand:ANYF 0 "register_operand" "=f")
1631 (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1632 (match_operand:ANYF 2 "register_operand" "f"))
1633 (match_operand:ANYF 3 "register_operand" "f")))]
1634 "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1635 "madd.<fmt>\t%0,%3,%1,%2"
1636 [(set_attr "type" "fmadd")
1637 (set_attr "mode" "<UNITMODE>")])
1639 (define_insn "*msub<mode>"
1640 [(set (match_operand:ANYF 0 "register_operand" "=f")
1641 (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1642 (match_operand:ANYF 2 "register_operand" "f"))
1643 (match_operand:ANYF 3 "register_operand" "f")))]
1644 "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1645 "msub.<fmt>\t%0,%3,%1,%2"
1646 [(set_attr "type" "fmadd")
1647 (set_attr "mode" "<UNITMODE>")])
1649 (define_insn "*nmadd<mode>"
1650 [(set (match_operand:ANYF 0 "register_operand" "=f")
1651 (neg:ANYF (plus:ANYF
1652 (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1653 (match_operand:ANYF 2 "register_operand" "f"))
1654 (match_operand:ANYF 3 "register_operand" "f"))))]
1655 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1656 && HONOR_SIGNED_ZEROS (<MODE>mode)"
1657 "nmadd.<fmt>\t%0,%3,%1,%2"
1658 [(set_attr "type" "fmadd")
1659 (set_attr "mode" "<UNITMODE>")])
1661 (define_insn "*nmadd<mode>_fastmath"
1662 [(set (match_operand:ANYF 0 "register_operand" "=f")
1664 (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
1665 (match_operand:ANYF 2 "register_operand" "f"))
1666 (match_operand:ANYF 3 "register_operand" "f")))]
1667 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1668 && !HONOR_SIGNED_ZEROS (<MODE>mode)"
1669 "nmadd.<fmt>\t%0,%3,%1,%2"
1670 [(set_attr "type" "fmadd")
1671 (set_attr "mode" "<UNITMODE>")])
1673 (define_insn "*nmsub<mode>"
1674 [(set (match_operand:ANYF 0 "register_operand" "=f")
1675 (neg:ANYF (minus:ANYF
1676 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1677 (match_operand:ANYF 3 "register_operand" "f"))
1678 (match_operand:ANYF 1 "register_operand" "f"))))]
1679 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1680 && HONOR_SIGNED_ZEROS (<MODE>mode)"
1681 "nmsub.<fmt>\t%0,%1,%2,%3"
1682 [(set_attr "type" "fmadd")
1683 (set_attr "mode" "<UNITMODE>")])
1685 (define_insn "*nmsub<mode>_fastmath"
1686 [(set (match_operand:ANYF 0 "register_operand" "=f")
1688 (match_operand:ANYF 1 "register_operand" "f")
1689 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1690 (match_operand:ANYF 3 "register_operand" "f"))))]
1691 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1692 && !HONOR_SIGNED_ZEROS (<MODE>mode)"
1693 "nmsub.<fmt>\t%0,%1,%2,%3"
1694 [(set_attr "type" "fmadd")
1695 (set_attr "mode" "<UNITMODE>")])
1698 ;; ....................
1700 ;; DIVISION and REMAINDER
1702 ;; ....................
1705 (define_expand "div<mode>3"
1706 [(set (match_operand:SCALARF 0 "register_operand")
1707 (div:SCALARF (match_operand:SCALARF 1 "reg_or_1_operand")
1708 (match_operand:SCALARF 2 "register_operand")))]
1709 "<divide_condition>"
1711 if (const_1_operand (operands[1], <MODE>mode))
1712 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1713 operands[1] = force_reg (<MODE>mode, operands[1]);
1716 ;; These patterns work around the early SB-1 rev2 core "F1" erratum:
1718 ;; If an mfc1 or dmfc1 happens to access the floating point register
1719 ;; file at the same time a long latency operation (div, sqrt, recip,
1720 ;; sqrt) iterates an intermediate result back through the floating
1721 ;; point register file bypass, then instead returning the correct
1722 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1723 ;; result of the long latency operation.
1725 ;; The workaround is to insert an unconditional 'mov' from/to the
1726 ;; long latency op destination register.
1728 (define_insn "*div<mode>3"
1729 [(set (match_operand:SCALARF 0 "register_operand" "=f")
1730 (div:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1731 (match_operand:SCALARF 2 "register_operand" "f")))]
1732 "<divide_condition>"
1735 return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
1737 return "div.<fmt>\t%0,%1,%2";
1739 [(set_attr "type" "fdiv")
1740 (set_attr "mode" "<MODE>")
1741 (set (attr "length")
1742 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1746 (define_insn "*recip<mode>3"
1747 [(set (match_operand:SCALARF 0 "register_operand" "=f")
1748 (div:SCALARF (match_operand:SCALARF 1 "const_1_operand" "")
1749 (match_operand:SCALARF 2 "register_operand" "f")))]
1750 "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
1753 return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1755 return "recip.<fmt>\t%0,%2";
1757 [(set_attr "type" "frdiv")
1758 (set_attr "mode" "<MODE>")
1759 (set (attr "length")
1760 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1764 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
1765 ;; with negative operands. We use special libgcc functions instead.
1766 (define_insn "divmod<mode>4"
1767 [(set (match_operand:GPR 0 "register_operand" "=l")
1768 (div:GPR (match_operand:GPR 1 "register_operand" "d")
1769 (match_operand:GPR 2 "register_operand" "d")))
1770 (set (match_operand:GPR 3 "register_operand" "=h")
1771 (mod:GPR (match_dup 1)
1773 "!TARGET_FIX_VR4120"
1774 { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1775 [(set_attr "type" "idiv")
1776 (set_attr "mode" "<MODE>")])
1778 (define_insn "udivmod<mode>4"
1779 [(set (match_operand:GPR 0 "register_operand" "=l")
1780 (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1781 (match_operand:GPR 2 "register_operand" "d")))
1782 (set (match_operand:GPR 3 "register_operand" "=h")
1783 (umod:GPR (match_dup 1)
1786 { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1787 [(set_attr "type" "idiv")
1788 (set_attr "mode" "<MODE>")])
1791 ;; ....................
1795 ;; ....................
1797 ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
1798 ;; "*div[sd]f3" comment for details).
1800 (define_insn "sqrt<mode>2"
1801 [(set (match_operand:SCALARF 0 "register_operand" "=f")
1802 (sqrt:SCALARF (match_operand:SCALARF 1 "register_operand" "f")))]
1806 return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
1808 return "sqrt.<fmt>\t%0,%1";
1810 [(set_attr "type" "fsqrt")
1811 (set_attr "mode" "<MODE>")
1812 (set (attr "length")
1813 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1817 (define_insn "*rsqrt<mode>a"
1818 [(set (match_operand:SCALARF 0 "register_operand" "=f")
1820 (match_operand:SCALARF 1 "const_1_operand" "")
1821 (sqrt:SCALARF (match_operand:SCALARF 2 "register_operand" "f"))))]
1822 "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
1825 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1827 return "rsqrt.<fmt>\t%0,%2";
1829 [(set_attr "type" "frsqrt")
1830 (set_attr "mode" "<MODE>")
1831 (set (attr "length")
1832 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1836 (define_insn "*rsqrt<mode>b"
1837 [(set (match_operand:SCALARF 0 "register_operand" "=f")
1839 (div:SCALARF (match_operand:SCALARF 1 "const_1_operand" "")
1840 (match_operand:SCALARF 2 "register_operand" "f"))))]
1841 "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
1844 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1846 return "rsqrt.<fmt>\t%0,%2";
1848 [(set_attr "type" "frsqrt")
1849 (set_attr "mode" "<MODE>")
1850 (set (attr "length")
1851 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1856 ;; ....................
1860 ;; ....................
1862 ;; Do not use the integer abs macro instruction, since that signals an
1863 ;; exception on -2147483648 (sigh).
1865 (define_insn "abs<mode>2"
1866 [(set (match_operand:GPR 0 "register_operand" "=d")
1867 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))]
1870 if (REGNO (operands[0]) == REGNO (operands[1]) && GENERATE_BRANCHLIKELY)
1871 return "%(bltzl\t%1,1f\;<d>subu\t%0,%.,%0\n%~1:%)";
1873 return "%(bgez\t%1,1f\;move\t%0,%1\;<d>subu\t%0,%.,%0\n%~1:%)";
1875 [(set_attr "type" "multi")
1876 (set_attr "mode" "<MODE>")
1877 (set_attr "length" "12")])
1879 (define_insn "abs<mode>2"
1880 [(set (match_operand:ANYF 0 "register_operand" "=f")
1881 (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1884 [(set_attr "type" "fabs")
1885 (set_attr "mode" "<UNITMODE>")])
1888 ;; ....................
1890 ;; FIND FIRST BIT INSTRUCTION
1892 ;; ....................
1895 (define_insn "ffs<mode>2"
1896 [(set (match_operand:GPR 0 "register_operand" "=&d")
1897 (ffs:GPR (match_operand:GPR 1 "register_operand" "d")))
1898 (clobber (match_scratch:GPR 2 "=&d"))
1899 (clobber (match_scratch:GPR 3 "=&d"))]
1902 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
1906 %~1:\tand\t%2,%1,0x0001\;\
1916 %~1:\tand\t%2,%3,0x0001\;\
1922 [(set_attr "type" "multi")
1923 (set_attr "mode" "<MODE>")
1924 (set_attr "length" "28")])
1927 ;; ...................
1929 ;; Count leading zeroes.
1931 ;; ...................
1934 (define_insn "clz<mode>2"
1935 [(set (match_operand:GPR 0 "register_operand" "=d")
1936 (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
1939 [(set_attr "type" "clz")
1940 (set_attr "mode" "<MODE>")])
1943 ;; ....................
1945 ;; NEGATION and ONE'S COMPLEMENT
1947 ;; ....................
1949 (define_insn "negsi2"
1950 [(set (match_operand:SI 0 "register_operand" "=d")
1951 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
1955 return "neg\t%0,%1";
1957 return "subu\t%0,%.,%1";
1959 [(set_attr "type" "arith")
1960 (set_attr "mode" "SI")])
1962 (define_insn "negdi2"
1963 [(set (match_operand:DI 0 "register_operand" "=d")
1964 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
1965 "TARGET_64BIT && !TARGET_MIPS16"
1967 [(set_attr "type" "arith")
1968 (set_attr "mode" "DI")])
1970 (define_insn "neg<mode>2"
1971 [(set (match_operand:ANYF 0 "register_operand" "=f")
1972 (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1975 [(set_attr "type" "fneg")
1976 (set_attr "mode" "<UNITMODE>")])
1978 (define_insn "one_cmpl<mode>2"
1979 [(set (match_operand:GPR 0 "register_operand" "=d")
1980 (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
1984 return "not\t%0,%1";
1986 return "nor\t%0,%.,%1";
1988 [(set_attr "type" "arith")
1989 (set_attr "mode" "<MODE>")])
1992 ;; ....................
1996 ;; ....................
1999 ;; Many of these instructions use trivial define_expands, because we
2000 ;; want to use a different set of constraints when TARGET_MIPS16.
2002 (define_expand "and<mode>3"
2003 [(set (match_operand:GPR 0 "register_operand")
2004 (and:GPR (match_operand:GPR 1 "register_operand")
2005 (match_operand:GPR 2 "uns_arith_operand")))]
2009 operands[2] = force_reg (<MODE>mode, operands[2]);
2012 (define_insn "*and<mode>3"
2013 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2014 (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2015 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2020 [(set_attr "type" "arith")
2021 (set_attr "mode" "<MODE>")])
2023 (define_insn "*and<mode>3_mips16"
2024 [(set (match_operand:GPR 0 "register_operand" "=d")
2025 (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2026 (match_operand:GPR 2 "register_operand" "d")))]
2029 [(set_attr "type" "arith")
2030 (set_attr "mode" "<MODE>")])
2032 (define_expand "ior<mode>3"
2033 [(set (match_operand:GPR 0 "register_operand")
2034 (ior:GPR (match_operand:GPR 1 "register_operand")
2035 (match_operand:GPR 2 "uns_arith_operand")))]
2039 operands[2] = force_reg (<MODE>mode, operands[2]);
2042 (define_insn "*ior<mode>3"
2043 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2044 (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2045 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2050 [(set_attr "type" "arith")
2051 (set_attr "mode" "<MODE>")])
2053 (define_insn "*ior<mode>3_mips16"
2054 [(set (match_operand:GPR 0 "register_operand" "=d")
2055 (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2056 (match_operand:GPR 2 "register_operand" "d")))]
2059 [(set_attr "type" "arith")
2060 (set_attr "mode" "<MODE>")])
2062 (define_expand "xor<mode>3"
2063 [(set (match_operand:GPR 0 "register_operand")
2064 (xor:GPR (match_operand:GPR 1 "register_operand")
2065 (match_operand:GPR 2 "uns_arith_operand")))]
2070 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2071 (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2072 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2077 [(set_attr "type" "arith")
2078 (set_attr "mode" "<MODE>")])
2081 [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2082 (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2083 (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2089 [(set_attr "type" "arith")
2090 (set_attr "mode" "<MODE>")
2091 (set_attr_alternative "length"
2093 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2098 (define_insn "*nor<mode>3"
2099 [(set (match_operand:GPR 0 "register_operand" "=d")
2100 (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2101 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2104 [(set_attr "type" "arith")
2105 (set_attr "mode" "<MODE>")])
2108 ;; ....................
2112 ;; ....................
2116 (define_insn "truncdfsf2"
2117 [(set (match_operand:SF 0 "register_operand" "=f")
2118 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2119 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2121 [(set_attr "type" "fcvt")
2122 (set_attr "mode" "SF")])
2124 ;; Integer truncation patterns. Truncating SImode values to smaller
2125 ;; modes is a no-op, as it is for most other GCC ports. Truncating
2126 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2127 ;; need to make sure that the lower 32 bits are properly sign-extended
2128 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
2129 ;; smaller than SImode is equivalent to two separate truncations:
2132 ;; DI ---> HI == DI ---> SI ---> HI
2133 ;; DI ---> QI == DI ---> SI ---> QI
2135 ;; Step A needs a real instruction but step B does not.
2137 (define_insn "truncdisi2"
2138 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2139 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2144 [(set_attr "type" "shift,store")
2145 (set_attr "mode" "SI")
2146 (set_attr "extended_mips16" "yes,*")])
2148 (define_insn "truncdihi2"
2149 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2150 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2155 [(set_attr "type" "shift,store")
2156 (set_attr "mode" "SI")
2157 (set_attr "extended_mips16" "yes,*")])
2159 (define_insn "truncdiqi2"
2160 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2161 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2166 [(set_attr "type" "shift,store")
2167 (set_attr "mode" "SI")
2168 (set_attr "extended_mips16" "yes,*")])
2170 ;; Combiner patterns to optimize shift/truncate combinations.
2173 [(set (match_operand:SI 0 "register_operand" "=d")
2175 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2176 (match_operand:DI 2 "const_arith_operand" ""))))]
2177 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2179 [(set_attr "type" "shift")
2180 (set_attr "mode" "SI")])
2183 [(set (match_operand:SI 0 "register_operand" "=d")
2184 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2186 "TARGET_64BIT && !TARGET_MIPS16"
2188 [(set_attr "type" "shift")
2189 (set_attr "mode" "SI")])
2192 ;; Combiner patterns for truncate/sign_extend combinations. They use
2193 ;; the shift/truncate patterns above.
2195 (define_insn_and_split ""
2196 [(set (match_operand:SI 0 "register_operand" "=d")
2198 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2199 "TARGET_64BIT && !TARGET_MIPS16"
2201 "&& reload_completed"
2203 (ashift:DI (match_dup 1)
2206 (truncate:SI (ashiftrt:DI (match_dup 2)
2208 { operands[2] = gen_lowpart (DImode, operands[0]); })
2210 (define_insn_and_split ""
2211 [(set (match_operand:SI 0 "register_operand" "=d")
2213 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2214 "TARGET_64BIT && !TARGET_MIPS16"
2216 "&& reload_completed"
2218 (ashift:DI (match_dup 1)
2221 (truncate:SI (ashiftrt:DI (match_dup 2)
2223 { operands[2] = gen_lowpart (DImode, operands[0]); })
2226 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2229 [(set (match_operand:SI 0 "register_operand" "=d")
2230 (zero_extend:SI (truncate:HI
2231 (match_operand:DI 1 "register_operand" "d"))))]
2232 "TARGET_64BIT && !TARGET_MIPS16"
2233 "andi\t%0,%1,0xffff"
2234 [(set_attr "type" "arith")
2235 (set_attr "mode" "SI")])
2238 [(set (match_operand:SI 0 "register_operand" "=d")
2239 (zero_extend:SI (truncate:QI
2240 (match_operand:DI 1 "register_operand" "d"))))]
2241 "TARGET_64BIT && !TARGET_MIPS16"
2243 [(set_attr "type" "arith")
2244 (set_attr "mode" "SI")])
2247 [(set (match_operand:HI 0 "register_operand" "=d")
2248 (zero_extend:HI (truncate:QI
2249 (match_operand:DI 1 "register_operand" "d"))))]
2250 "TARGET_64BIT && !TARGET_MIPS16"
2252 [(set_attr "type" "arith")
2253 (set_attr "mode" "HI")])
2256 ;; ....................
2260 ;; ....................
2264 (define_insn_and_split "zero_extendsidi2"
2265 [(set (match_operand:DI 0 "register_operand" "=d,d")
2266 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
2271 "&& reload_completed && REG_P (operands[1])"
2273 (ashift:DI (match_dup 1) (const_int 32)))
2275 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2276 { operands[1] = gen_lowpart (DImode, operands[1]); }
2277 [(set_attr "type" "multi,load")
2278 (set_attr "mode" "DI")
2279 (set_attr "length" "8,*")])
2281 (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
2282 [(set (match_operand:GPR 0 "register_operand")
2283 (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2286 if (TARGET_MIPS16 && !memory_operand (operands[1], <SHORT:MODE>mode))
2288 emit_insn (gen_and<GPR:mode>3 (operands[0],
2289 gen_lowpart (<GPR:MODE>mode, operands[1]),
2290 force_reg (<GPR:MODE>mode,
2291 GEN_INT (<SHORT:mask>))));
2296 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
2297 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2299 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2302 andi\t%0,%1,<SHORT:mask>
2303 l<SHORT:size>u\t%0,%1"
2304 [(set_attr "type" "arith,load")
2305 (set_attr "mode" "<GPR:MODE>")])
2307 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16"
2308 [(set (match_operand:GPR 0 "register_operand" "=d")
2309 (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
2311 "l<SHORT:size>u\t%0,%1"
2312 [(set_attr "type" "load")
2313 (set_attr "mode" "<GPR:MODE>")])
2315 (define_expand "zero_extendqihi2"
2316 [(set (match_operand:HI 0 "register_operand")
2317 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2320 if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
2322 emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
2328 (define_insn "*zero_extendqihi2"
2329 [(set (match_operand:HI 0 "register_operand" "=d,d")
2330 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2335 [(set_attr "type" "arith,load")
2336 (set_attr "mode" "HI")])
2338 (define_insn "*zero_extendqihi2_mips16"
2339 [(set (match_operand:HI 0 "register_operand" "=d")
2340 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2343 [(set_attr "type" "load")
2344 (set_attr "mode" "HI")])
2347 ;; ....................
2351 ;; ....................
2354 ;; Those for integer source operand are ordered widest source type first.
2356 ;; When TARGET_64BIT, all SImode integer registers should already be in
2357 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
2358 ;; therefore get rid of register->register instructions if we constrain
2359 ;; the source to be in the same register as the destination.
2361 ;; The register alternative has type "arith" so that the pre-reload
2362 ;; scheduler will treat it as a move. This reflects what happens if
2363 ;; the register alternative needs a reload.
2364 (define_insn_and_split "extendsidi2"
2365 [(set (match_operand:DI 0 "register_operand" "=d,d")
2366 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2371 "&& reload_completed && register_operand (operands[1], VOIDmode)"
2374 emit_note (NOTE_INSN_DELETED);
2377 [(set_attr "type" "arith,load")
2378 (set_attr "mode" "DI")])
2380 (define_expand "extend<SHORT:mode><GPR:mode>2"
2381 [(set (match_operand:GPR 0 "register_operand")
2382 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2385 (define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
2386 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2388 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2392 l<SHORT:size>\t%0,%1"
2393 "&& reload_completed && REG_P (operands[1])"
2394 [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
2395 (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
2397 operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
2398 operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
2399 - GET_MODE_BITSIZE (<SHORT:MODE>mode));
2401 [(set_attr "type" "arith,load")
2402 (set_attr "mode" "<GPR:MODE>")
2403 (set_attr "length" "8,*")])
2405 (define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
2406 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2408 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2411 se<SHORT:size>\t%0,%1
2412 l<SHORT:size>\t%0,%1"
2413 [(set_attr "type" "arith,load")
2414 (set_attr "mode" "<GPR:MODE>")])
2416 ;; This pattern generates the same code as extendqisi2; split it into
2417 ;; that form after reload.
2418 (define_insn_and_split "extendqihi2"
2419 [(set (match_operand:HI 0 "register_operand" "=d,d")
2420 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2424 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
2425 { operands[0] = gen_lowpart (SImode, operands[0]); }
2426 [(set_attr "type" "arith,load")
2427 (set_attr "mode" "SI")
2428 (set_attr "length" "8,*")])
2430 (define_insn "extendsfdf2"
2431 [(set (match_operand:DF 0 "register_operand" "=f")
2432 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2433 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2435 [(set_attr "type" "fcvt")
2436 (set_attr "mode" "DF")])
2439 ;; ....................
2443 ;; ....................
2445 (define_expand "fix_truncdfsi2"
2446 [(set (match_operand:SI 0 "register_operand")
2447 (fix:SI (match_operand:DF 1 "register_operand")))]
2448 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2450 if (!ISA_HAS_TRUNC_W)
2452 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2457 (define_insn "fix_truncdfsi2_insn"
2458 [(set (match_operand:SI 0 "register_operand" "=f")
2459 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2460 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2462 [(set_attr "type" "fcvt")
2463 (set_attr "mode" "DF")
2464 (set_attr "length" "4")])
2466 (define_insn "fix_truncdfsi2_macro"
2467 [(set (match_operand:SI 0 "register_operand" "=f")
2468 (fix:SI (match_operand:DF 1 "register_operand" "f")))
2469 (clobber (match_scratch:DF 2 "=d"))]
2470 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2473 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2475 return "trunc.w.d %0,%1,%2";
2477 [(set_attr "type" "fcvt")
2478 (set_attr "mode" "DF")
2479 (set_attr "length" "36")])
2481 (define_expand "fix_truncsfsi2"
2482 [(set (match_operand:SI 0 "register_operand")
2483 (fix:SI (match_operand:SF 1 "register_operand")))]
2486 if (!ISA_HAS_TRUNC_W)
2488 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2493 (define_insn "fix_truncsfsi2_insn"
2494 [(set (match_operand:SI 0 "register_operand" "=f")
2495 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2496 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2498 [(set_attr "type" "fcvt")
2499 (set_attr "mode" "DF")
2500 (set_attr "length" "4")])
2502 (define_insn "fix_truncsfsi2_macro"
2503 [(set (match_operand:SI 0 "register_operand" "=f")
2504 (fix:SI (match_operand:SF 1 "register_operand" "f")))
2505 (clobber (match_scratch:SF 2 "=d"))]
2506 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2509 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2511 return "trunc.w.s %0,%1,%2";
2513 [(set_attr "type" "fcvt")
2514 (set_attr "mode" "DF")
2515 (set_attr "length" "36")])
2518 (define_insn "fix_truncdfdi2"
2519 [(set (match_operand:DI 0 "register_operand" "=f")
2520 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2521 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2523 [(set_attr "type" "fcvt")
2524 (set_attr "mode" "DF")
2525 (set_attr "length" "4")])
2528 (define_insn "fix_truncsfdi2"
2529 [(set (match_operand:DI 0 "register_operand" "=f")
2530 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2531 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2533 [(set_attr "type" "fcvt")
2534 (set_attr "mode" "SF")
2535 (set_attr "length" "4")])
2538 (define_insn "floatsidf2"
2539 [(set (match_operand:DF 0 "register_operand" "=f")
2540 (float:DF (match_operand:SI 1 "register_operand" "f")))]
2541 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2543 [(set_attr "type" "fcvt")
2544 (set_attr "mode" "DF")
2545 (set_attr "length" "4")])
2548 (define_insn "floatdidf2"
2549 [(set (match_operand:DF 0 "register_operand" "=f")
2550 (float:DF (match_operand:DI 1 "register_operand" "f")))]
2551 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2553 [(set_attr "type" "fcvt")
2554 (set_attr "mode" "DF")
2555 (set_attr "length" "4")])
2558 (define_insn "floatsisf2"
2559 [(set (match_operand:SF 0 "register_operand" "=f")
2560 (float:SF (match_operand:SI 1 "register_operand" "f")))]
2563 [(set_attr "type" "fcvt")
2564 (set_attr "mode" "SF")
2565 (set_attr "length" "4")])
2568 (define_insn "floatdisf2"
2569 [(set (match_operand:SF 0 "register_operand" "=f")
2570 (float:SF (match_operand:DI 1 "register_operand" "f")))]
2571 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2573 [(set_attr "type" "fcvt")
2574 (set_attr "mode" "SF")
2575 (set_attr "length" "4")])
2578 (define_expand "fixuns_truncdfsi2"
2579 [(set (match_operand:SI 0 "register_operand")
2580 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2581 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2583 rtx reg1 = gen_reg_rtx (DFmode);
2584 rtx reg2 = gen_reg_rtx (DFmode);
2585 rtx reg3 = gen_reg_rtx (SImode);
2586 rtx label1 = gen_label_rtx ();
2587 rtx label2 = gen_label_rtx ();
2588 REAL_VALUE_TYPE offset;
2590 real_2expN (&offset, 31);
2592 if (reg1) /* Turn off complaints about unreached code. */
2594 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2595 do_pending_stack_adjust ();
2597 emit_insn (gen_cmpdf (operands[1], reg1));
2598 emit_jump_insn (gen_bge (label1));
2600 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2601 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2602 gen_rtx_LABEL_REF (VOIDmode, label2)));
2605 emit_label (label1);
2606 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2607 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2608 (BITMASK_HIGH, SImode)));
2610 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2611 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2613 emit_label (label2);
2615 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2616 fields, and can't be used for REG_NOTES anyway). */
2617 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2623 (define_expand "fixuns_truncdfdi2"
2624 [(set (match_operand:DI 0 "register_operand")
2625 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
2626 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2628 rtx reg1 = gen_reg_rtx (DFmode);
2629 rtx reg2 = gen_reg_rtx (DFmode);
2630 rtx reg3 = gen_reg_rtx (DImode);
2631 rtx label1 = gen_label_rtx ();
2632 rtx label2 = gen_label_rtx ();
2633 REAL_VALUE_TYPE offset;
2635 real_2expN (&offset, 63);
2637 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2638 do_pending_stack_adjust ();
2640 emit_insn (gen_cmpdf (operands[1], reg1));
2641 emit_jump_insn (gen_bge (label1));
2643 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2644 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2645 gen_rtx_LABEL_REF (VOIDmode, label2)));
2648 emit_label (label1);
2649 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2650 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2651 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2653 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2654 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2656 emit_label (label2);
2658 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2659 fields, and can't be used for REG_NOTES anyway). */
2660 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2665 (define_expand "fixuns_truncsfsi2"
2666 [(set (match_operand:SI 0 "register_operand")
2667 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
2670 rtx reg1 = gen_reg_rtx (SFmode);
2671 rtx reg2 = gen_reg_rtx (SFmode);
2672 rtx reg3 = gen_reg_rtx (SImode);
2673 rtx label1 = gen_label_rtx ();
2674 rtx label2 = gen_label_rtx ();
2675 REAL_VALUE_TYPE offset;
2677 real_2expN (&offset, 31);
2679 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2680 do_pending_stack_adjust ();
2682 emit_insn (gen_cmpsf (operands[1], reg1));
2683 emit_jump_insn (gen_bge (label1));
2685 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2686 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2687 gen_rtx_LABEL_REF (VOIDmode, label2)));
2690 emit_label (label1);
2691 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2692 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2693 (BITMASK_HIGH, SImode)));
2695 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2696 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2698 emit_label (label2);
2700 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2701 fields, and can't be used for REG_NOTES anyway). */
2702 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2707 (define_expand "fixuns_truncsfdi2"
2708 [(set (match_operand:DI 0 "register_operand")
2709 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
2710 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2712 rtx reg1 = gen_reg_rtx (SFmode);
2713 rtx reg2 = gen_reg_rtx (SFmode);
2714 rtx reg3 = gen_reg_rtx (DImode);
2715 rtx label1 = gen_label_rtx ();
2716 rtx label2 = gen_label_rtx ();
2717 REAL_VALUE_TYPE offset;
2719 real_2expN (&offset, 63);
2721 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2722 do_pending_stack_adjust ();
2724 emit_insn (gen_cmpsf (operands[1], reg1));
2725 emit_jump_insn (gen_bge (label1));
2727 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
2728 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2729 gen_rtx_LABEL_REF (VOIDmode, label2)));
2732 emit_label (label1);
2733 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2734 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2735 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2737 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
2738 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2740 emit_label (label2);
2742 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2743 fields, and can't be used for REG_NOTES anyway). */
2744 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2749 ;; ....................
2753 ;; ....................
2755 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
2757 (define_expand "extv"
2758 [(set (match_operand 0 "register_operand")
2759 (sign_extract (match_operand:QI 1 "memory_operand")
2760 (match_operand 2 "immediate_operand")
2761 (match_operand 3 "immediate_operand")))]
2764 if (mips_expand_unaligned_load (operands[0], operands[1],
2765 INTVAL (operands[2]),
2766 INTVAL (operands[3])))
2772 (define_expand "extzv"
2773 [(set (match_operand 0 "register_operand")
2774 (zero_extract (match_operand:QI 1 "memory_operand")
2775 (match_operand 2 "immediate_operand")
2776 (match_operand 3 "immediate_operand")))]
2779 if (mips_expand_unaligned_load (operands[0], operands[1],
2780 INTVAL (operands[2]),
2781 INTVAL (operands[3])))
2787 (define_expand "insv"
2788 [(set (zero_extract (match_operand:QI 0 "memory_operand")
2789 (match_operand 1 "immediate_operand")
2790 (match_operand 2 "immediate_operand"))
2791 (match_operand 3 "reg_or_0_operand"))]
2794 if (mips_expand_unaligned_store (operands[0], operands[3],
2795 INTVAL (operands[1]),
2796 INTVAL (operands[2])))
2802 ;; Unaligned word moves generated by the bit field patterns.
2804 ;; As far as the rtl is concerned, both the left-part and right-part
2805 ;; instructions can access the whole field. However, the real operand
2806 ;; refers to just the first or the last byte (depending on endianness).
2807 ;; We therefore use two memory operands to each instruction, one to
2808 ;; describe the rtl effect and one to use in the assembly output.
2810 ;; Operands 0 and 1 are the rtl-level target and source respectively.
2811 ;; This allows us to use the standard length calculations for the "load"
2812 ;; and "store" type attributes.
2814 (define_insn "mov_<load>l"
2815 [(set (match_operand:GPR 0 "register_operand" "=d")
2816 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
2817 (match_operand:QI 2 "memory_operand" "m")]
2821 [(set_attr "type" "load")
2822 (set_attr "mode" "<MODE>")
2823 (set_attr "hazard" "none")])
2825 (define_insn "mov_<load>r"
2826 [(set (match_operand:GPR 0 "register_operand" "=d")
2827 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
2828 (match_operand:QI 2 "memory_operand" "m")
2829 (match_operand:GPR 3 "register_operand" "0")]
2830 UNSPEC_LOAD_RIGHT))]
2833 [(set_attr "type" "load")
2834 (set_attr "mode" "<MODE>")])
2836 (define_insn "mov_<store>l"
2837 [(set (match_operand:BLK 0 "memory_operand" "=m")
2838 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
2839 (match_operand:QI 2 "memory_operand" "m")]
2840 UNSPEC_STORE_LEFT))]
2843 [(set_attr "type" "store")
2844 (set_attr "mode" "<MODE>")])
2846 (define_insn "mov_<store>r"
2847 [(set (match_operand:BLK 0 "memory_operand" "+m")
2848 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
2849 (match_operand:QI 2 "memory_operand" "m")
2851 UNSPEC_STORE_RIGHT))]
2854 [(set_attr "type" "store")
2855 (set_attr "mode" "<MODE>")])
2857 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
2858 ;; The required value is:
2860 ;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
2862 ;; which translates to:
2864 ;; lui op0,%highest(op1)
2865 ;; daddiu op0,op0,%higher(op1)
2867 ;; daddiu op0,op0,%hi(op1)
2870 ;; The split is deferred until after flow2 to allow the peephole2 below
2872 (define_insn_and_split "*lea_high64"
2873 [(set (match_operand:DI 0 "register_operand" "=d")
2874 (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
2875 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
2877 "&& flow2_completed"
2878 [(set (match_dup 0) (high:DI (match_dup 2)))
2879 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
2880 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
2881 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
2882 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
2884 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
2885 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
2887 [(set_attr "length" "20")])
2889 ;; Use a scratch register to reduce the latency of the above pattern
2890 ;; on superscalar machines. The optimized sequence is:
2892 ;; lui op1,%highest(op2)
2894 ;; daddiu op1,op1,%higher(op2)
2896 ;; daddu op1,op1,op0
2898 [(match_scratch:DI 0 "d")
2899 (set (match_operand:DI 1 "register_operand")
2900 (high:DI (match_operand:DI 2 "general_symbolic_operand")))]
2901 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
2902 [(set (match_dup 1) (high:DI (match_dup 3)))
2903 (set (match_dup 0) (high:DI (match_dup 4)))
2904 (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
2905 (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
2906 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
2908 operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
2909 operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
2912 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
2913 ;; SYMBOL_GENERAL X will take 6 cycles. This next pattern allows combine
2914 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
2915 ;; used once. We can then use the sequence:
2917 ;; lui op0,%highest(op1)
2919 ;; daddiu op0,op0,%higher(op1)
2920 ;; daddiu op2,op2,%lo(op1)
2922 ;; daddu op0,op0,op2
2924 ;; which takes 4 cycles on most superscalar targets.
2925 (define_insn_and_split "*lea64"
2926 [(set (match_operand:DI 0 "register_operand" "=d")
2927 (match_operand:DI 1 "general_symbolic_operand" ""))
2928 (clobber (match_scratch:DI 2 "=&d"))]
2929 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
2931 "&& reload_completed"
2932 [(set (match_dup 0) (high:DI (match_dup 3)))
2933 (set (match_dup 2) (high:DI (match_dup 4)))
2934 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
2935 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
2936 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
2937 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
2939 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
2940 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
2942 [(set_attr "length" "24")])
2944 ;; Insns to fetch a global symbol from a big GOT.
2946 (define_insn_and_split "*xgot_hi<mode>"
2947 [(set (match_operand:P 0 "register_operand" "=d")
2948 (high:P (match_operand:P 1 "global_got_operand" "")))]
2949 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
2951 "&& reload_completed"
2952 [(set (match_dup 0) (high:P (match_dup 2)))
2953 (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
2955 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
2956 operands[3] = pic_offset_table_rtx;
2958 [(set_attr "got" "xgot_high")
2959 (set_attr "mode" "<MODE>")])
2961 (define_insn_and_split "*xgot_lo<mode>"
2962 [(set (match_operand:P 0 "register_operand" "=d")
2963 (lo_sum:P (match_operand:P 1 "register_operand" "d")
2964 (match_operand:P 2 "global_got_operand" "")))]
2965 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
2967 "&& reload_completed"
2969 (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
2970 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
2971 [(set_attr "got" "load")
2972 (set_attr "mode" "<MODE>")])
2974 ;; Insns to fetch a global symbol from a normal GOT.
2976 (define_insn_and_split "*got_disp<mode>"
2977 [(set (match_operand:P 0 "register_operand" "=d")
2978 (match_operand:P 1 "global_got_operand" ""))]
2979 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
2981 "&& reload_completed"
2983 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
2985 operands[2] = pic_offset_table_rtx;
2986 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
2988 [(set_attr "got" "load")
2989 (set_attr "mode" "<MODE>")])
2991 ;; Insns for loading the high part of a local symbol.
2993 (define_insn_and_split "*got_page<mode>"
2994 [(set (match_operand:P 0 "register_operand" "=d")
2995 (high:P (match_operand:P 1 "local_got_operand" "")))]
2996 "TARGET_EXPLICIT_RELOCS"
2998 "&& reload_completed"
3000 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3002 operands[2] = pic_offset_table_rtx;
3003 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3005 [(set_attr "got" "load")
3006 (set_attr "mode" "<MODE>")])
3008 ;; Lower-level instructions for loading an address from the GOT.
3009 ;; We could use MEMs, but an unspec gives more optimization
3012 (define_insn "*load_got<mode>"
3013 [(set (match_operand:P 0 "register_operand" "=d")
3014 (unspec:P [(match_operand:P 1 "register_operand" "d")
3015 (match_operand:P 2 "immediate_operand" "")]
3018 "<load>\t%0,%R2(%1)"
3019 [(set_attr "type" "load")
3020 (set_attr "mode" "<MODE>")
3021 (set_attr "length" "4")])
3023 ;; Instructions for adding the low 16 bits of an address to a register.
3024 ;; Operand 2 is the address: print_operand works out which relocation
3025 ;; should be applied.
3027 (define_insn "*low<mode>"
3028 [(set (match_operand:P 0 "register_operand" "=d")
3029 (lo_sum:P (match_operand:P 1 "register_operand" "d")
3030 (match_operand:P 2 "immediate_operand" "")))]
3032 "<d>addiu\t%0,%1,%R2"
3033 [(set_attr "type" "arith")
3034 (set_attr "mode" "<MODE>")])
3036 (define_insn "*low<mode>_mips16"
3037 [(set (match_operand:P 0 "register_operand" "=d")
3038 (lo_sum:P (match_operand:P 1 "register_operand" "0")
3039 (match_operand:P 2 "immediate_operand" "")))]
3042 [(set_attr "type" "arith")
3043 (set_attr "mode" "<MODE>")
3044 (set_attr "length" "8")])
3046 ;; 64-bit integer moves
3048 ;; Unlike most other insns, the move insns can't be split with
3049 ;; different predicates, because register spilling and other parts of
3050 ;; the compiler, have memoized the insn number already.
3052 (define_expand "movdi"
3053 [(set (match_operand:DI 0 "")
3054 (match_operand:DI 1 ""))]
3057 if (mips_legitimize_move (DImode, operands[0], operands[1]))
3061 ;; For mips16, we need a special case to handle storing $31 into
3062 ;; memory, since we don't have a constraint to match $31. This
3063 ;; instruction can be generated by save_restore_insns.
3065 (define_insn "*mov<mode>_ra"
3066 [(set (match_operand:GPR 0 "stack_operand" "=m")
3070 [(set_attr "type" "store")
3071 (set_attr "mode" "<MODE>")])
3073 (define_insn "*movdi_32bit"
3074 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
3075 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
3076 "!TARGET_64BIT && !TARGET_MIPS16
3077 && (register_operand (operands[0], DImode)
3078 || reg_or_0_operand (operands[1], DImode))"
3079 { return mips_output_move (operands[0], operands[1]); }
3080 [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
3081 (set_attr "mode" "DI")
3082 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
3084 (define_insn "*movdi_32bit_mips16"
3085 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3086 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3087 "!TARGET_64BIT && TARGET_MIPS16
3088 && (register_operand (operands[0], DImode)
3089 || register_operand (operands[1], DImode))"
3090 { return mips_output_move (operands[0], operands[1]); }
3091 [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo")
3092 (set_attr "mode" "DI")
3093 (set_attr "length" "8,8,8,8,12,*,*,8")])
3095 (define_insn "*movdi_64bit"
3096 [(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")
3097 (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"))]
3098 "TARGET_64BIT && !TARGET_MIPS16
3099 && (register_operand (operands[0], DImode)
3100 || reg_or_0_operand (operands[1], DImode))"
3101 { return mips_output_move (operands[0], operands[1]); }
3102 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
3103 (set_attr "mode" "DI")
3104 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3106 (define_insn "*movdi_64bit_mips16"
3107 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3108 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3109 "TARGET_64BIT && TARGET_MIPS16
3110 && (register_operand (operands[0], DImode)
3111 || register_operand (operands[1], DImode))"
3112 { return mips_output_move (operands[0], operands[1]); }
3113 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
3114 (set_attr "mode" "DI")
3115 (set_attr_alternative "length"
3119 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3122 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3127 (const_string "*")])])
3130 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
3131 ;; when the original load is a 4 byte instruction but the add and the
3132 ;; load are 2 2 byte instructions.
3135 [(set (match_operand:DI 0 "register_operand")
3136 (mem:DI (plus:DI (match_dup 0)
3137 (match_operand:DI 1 "const_int_operand"))))]
3138 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3139 && !TARGET_DEBUG_D_MODE
3140 && GET_CODE (operands[0]) == REG
3141 && M16_REG_P (REGNO (operands[0]))
3142 && GET_CODE (operands[1]) == CONST_INT
3143 && ((INTVAL (operands[1]) < 0
3144 && INTVAL (operands[1]) >= -0x10)
3145 || (INTVAL (operands[1]) >= 32 * 8
3146 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3147 || (INTVAL (operands[1]) >= 0
3148 && INTVAL (operands[1]) < 32 * 8
3149 && (INTVAL (operands[1]) & 7) != 0))"
3150 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3151 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3153 HOST_WIDE_INT val = INTVAL (operands[1]);
3156 operands[2] = const0_rtx;
3157 else if (val >= 32 * 8)
3161 operands[1] = GEN_INT (0x8 + off);
3162 operands[2] = GEN_INT (val - off - 0x8);
3168 operands[1] = GEN_INT (off);
3169 operands[2] = GEN_INT (val - off);
3173 ;; 32-bit Integer moves
3175 ;; Unlike most other insns, the move insns can't be split with
3176 ;; different predicates, because register spilling and other parts of
3177 ;; the compiler, have memoized the insn number already.
3179 (define_expand "movsi"
3180 [(set (match_operand:SI 0 "")
3181 (match_operand:SI 1 ""))]
3184 if (mips_legitimize_move (SImode, operands[0], operands[1]))
3188 ;; The difference between these two is whether or not ints are allowed
3189 ;; in FP registers (off by default, use -mdebugh to enable).
3191 (define_insn "*movsi_internal"
3192 [(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")
3193 (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"))]
3195 && (register_operand (operands[0], SImode)
3196 || reg_or_0_operand (operands[1], SImode))"
3197 { return mips_output_move (operands[0], operands[1]); }
3198 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
3199 (set_attr "mode" "SI")
3200 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
3202 (define_insn "*movsi_mips16"
3203 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3204 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3206 && (register_operand (operands[0], SImode)
3207 || register_operand (operands[1], SImode))"
3208 { return mips_output_move (operands[0], operands[1]); }
3209 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
3210 (set_attr "mode" "SI")
3211 (set_attr_alternative "length"
3215 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3218 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3223 (const_string "*")])])
3225 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
3226 ;; when the original load is a 4 byte instruction but the add and the
3227 ;; load are 2 2 byte instructions.
3230 [(set (match_operand:SI 0 "register_operand")
3231 (mem:SI (plus:SI (match_dup 0)
3232 (match_operand:SI 1 "const_int_operand"))))]
3233 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3234 && GET_CODE (operands[0]) == REG
3235 && M16_REG_P (REGNO (operands[0]))
3236 && GET_CODE (operands[1]) == CONST_INT
3237 && ((INTVAL (operands[1]) < 0
3238 && INTVAL (operands[1]) >= -0x80)
3239 || (INTVAL (operands[1]) >= 32 * 4
3240 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3241 || (INTVAL (operands[1]) >= 0
3242 && INTVAL (operands[1]) < 32 * 4
3243 && (INTVAL (operands[1]) & 3) != 0))"
3244 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3245 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3247 HOST_WIDE_INT val = INTVAL (operands[1]);
3250 operands[2] = const0_rtx;
3251 else if (val >= 32 * 4)
3255 operands[1] = GEN_INT (0x7c + off);
3256 operands[2] = GEN_INT (val - off - 0x7c);
3262 operands[1] = GEN_INT (off);
3263 operands[2] = GEN_INT (val - off);
3267 ;; On the mips16, we can split a load of certain constants into a load
3268 ;; and an add. This turns a 4 byte instruction into 2 2 byte
3272 [(set (match_operand:SI 0 "register_operand")
3273 (match_operand:SI 1 "const_int_operand"))]
3274 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3275 && GET_CODE (operands[0]) == REG
3276 && M16_REG_P (REGNO (operands[0]))
3277 && GET_CODE (operands[1]) == CONST_INT
3278 && INTVAL (operands[1]) >= 0x100
3279 && INTVAL (operands[1]) <= 0xff + 0x7f"
3280 [(set (match_dup 0) (match_dup 1))
3281 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3283 int val = INTVAL (operands[1]);
3285 operands[1] = GEN_INT (0xff);
3286 operands[2] = GEN_INT (val - 0xff);
3289 ;; This insn handles moving CCmode values. It's really just a
3290 ;; slightly simplified copy of movsi_internal2, with additional cases
3291 ;; to move a condition register to a general register and to move
3292 ;; between the general registers and the floating point registers.
3294 (define_insn "movcc"
3295 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3296 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3297 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3298 { return mips_output_move (operands[0], operands[1]); }
3299 [(set_attr "type" "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
3300 (set_attr "mode" "SI")
3301 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
3303 ;; Reload condition code registers. reload_incc and reload_outcc
3304 ;; both handle moves from arbitrary operands into condition code
3305 ;; registers. reload_incc handles the more common case in which
3306 ;; a source operand is constrained to be in a condition-code
3307 ;; register, but has not been allocated to one.
3309 ;; Sometimes, such as in movcc, we have a CCmode destination whose
3310 ;; constraints do not include 'z'. reload_outcc handles the case
3311 ;; when such an operand is allocated to a condition-code register.
3313 ;; Note that reloads from a condition code register to some
3314 ;; other location can be done using ordinary moves. Moving
3315 ;; into a GPR takes a single movcc, moving elsewhere takes
3316 ;; two. We can leave these cases to the generic reload code.
3317 (define_expand "reload_incc"
3318 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3319 (match_operand:CC 1 "general_operand" ""))
3320 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3321 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3323 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3327 (define_expand "reload_outcc"
3328 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3329 (match_operand:CC 1 "register_operand" ""))
3330 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3331 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3333 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3337 ;; MIPS4 supports loading and storing a floating point register from
3338 ;; the sum of two general registers. We use two versions for each of
3339 ;; these four instructions: one where the two general registers are
3340 ;; SImode, and one where they are DImode. This is because general
3341 ;; registers will be in SImode when they hold 32 bit values, but,
3342 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
3343 ;; instructions will still work correctly.
3345 ;; ??? Perhaps it would be better to support these instructions by
3346 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
3347 ;; these instructions can only be used to load and store floating
3348 ;; point registers, that would probably cause trouble in reload.
3350 (define_insn "*<ANYF:loadx>_<P:mode>"
3351 [(set (match_operand:ANYF 0 "register_operand" "=f")
3352 (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3353 (match_operand:P 2 "register_operand" "d"))))]
3355 "<ANYF:loadx>\t%0,%1(%2)"
3356 [(set_attr "type" "fpidxload")
3357 (set_attr "mode" "<ANYF:UNITMODE>")])
3359 (define_insn "*<ANYF:storex>_<P:mode>"
3360 [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3361 (match_operand:P 2 "register_operand" "d")))
3362 (match_operand:ANYF 0 "register_operand" "f"))]
3364 "<ANYF:storex>\t%0,%1(%2)"
3365 [(set_attr "type" "fpidxstore")
3366 (set_attr "mode" "<ANYF:UNITMODE>")])
3368 ;; 16-bit Integer moves
3370 ;; Unlike most other insns, the move insns can't be split with
3371 ;; different predicates, because register spilling and other parts of
3372 ;; the compiler, have memoized the insn number already.
3373 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3375 (define_expand "movhi"
3376 [(set (match_operand:HI 0 "")
3377 (match_operand:HI 1 ""))]
3380 if (mips_legitimize_move (HImode, operands[0], operands[1]))
3384 (define_insn "*movhi_internal"
3385 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3386 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
3388 && (register_operand (operands[0], HImode)
3389 || reg_or_0_operand (operands[1], HImode))"
3399 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3400 (set_attr "mode" "HI")
3401 (set_attr "length" "4,4,*,*,4,4,4,4")])
3403 (define_insn "*movhi_mips16"
3404 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3405 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))]
3407 && (register_operand (operands[0], HImode)
3408 || register_operand (operands[1], HImode))"
3417 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
3418 (set_attr "mode" "HI")
3419 (set_attr_alternative "length"
3423 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3426 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3430 (const_string "*")])])
3433 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
3434 ;; when the original load is a 4 byte instruction but the add and the
3435 ;; load are 2 2 byte instructions.
3438 [(set (match_operand:HI 0 "register_operand")
3439 (mem:HI (plus:SI (match_dup 0)
3440 (match_operand:SI 1 "const_int_operand"))))]
3441 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3442 && GET_CODE (operands[0]) == REG
3443 && M16_REG_P (REGNO (operands[0]))
3444 && GET_CODE (operands[1]) == CONST_INT
3445 && ((INTVAL (operands[1]) < 0
3446 && INTVAL (operands[1]) >= -0x80)
3447 || (INTVAL (operands[1]) >= 32 * 2
3448 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
3449 || (INTVAL (operands[1]) >= 0
3450 && INTVAL (operands[1]) < 32 * 2
3451 && (INTVAL (operands[1]) & 1) != 0))"
3452 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3453 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
3455 HOST_WIDE_INT val = INTVAL (operands[1]);
3458 operands[2] = const0_rtx;
3459 else if (val >= 32 * 2)
3463 operands[1] = GEN_INT (0x7e + off);
3464 operands[2] = GEN_INT (val - off - 0x7e);
3470 operands[1] = GEN_INT (off);
3471 operands[2] = GEN_INT (val - off);
3475 ;; 8-bit Integer moves
3477 ;; Unlike most other insns, the move insns can't be split with
3478 ;; different predicates, because register spilling and other parts of
3479 ;; the compiler, have memoized the insn number already.
3480 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3482 (define_expand "movqi"
3483 [(set (match_operand:QI 0 "")
3484 (match_operand:QI 1 ""))]
3487 if (mips_legitimize_move (QImode, operands[0], operands[1]))
3491 (define_insn "*movqi_internal"
3492 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3493 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
3495 && (register_operand (operands[0], QImode)
3496 || reg_or_0_operand (operands[1], QImode))"
3506 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3507 (set_attr "mode" "QI")
3508 (set_attr "length" "4,4,*,*,4,4,4,4")])
3510 (define_insn "*movqi_mips16"
3511 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3512 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))]
3514 && (register_operand (operands[0], QImode)
3515 || register_operand (operands[1], QImode))"
3524 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
3525 (set_attr "mode" "QI")
3526 (set_attr "length" "4,4,4,4,8,*,*")])
3528 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
3529 ;; when the original load is a 4 byte instruction but the add and the
3530 ;; load are 2 2 byte instructions.
3533 [(set (match_operand:QI 0 "register_operand")
3534 (mem:QI (plus:SI (match_dup 0)
3535 (match_operand:SI 1 "const_int_operand"))))]
3536 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3537 && GET_CODE (operands[0]) == REG
3538 && M16_REG_P (REGNO (operands[0]))
3539 && GET_CODE (operands[1]) == CONST_INT
3540 && ((INTVAL (operands[1]) < 0
3541 && INTVAL (operands[1]) >= -0x80)
3542 || (INTVAL (operands[1]) >= 32
3543 && INTVAL (operands[1]) <= 31 + 0x7f))"
3544 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3545 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
3547 HOST_WIDE_INT val = INTVAL (operands[1]);
3550 operands[2] = const0_rtx;
3553 operands[1] = GEN_INT (0x7f);
3554 operands[2] = GEN_INT (val - 0x7f);
3558 ;; 32-bit floating point moves
3560 (define_expand "movsf"
3561 [(set (match_operand:SF 0 "")
3562 (match_operand:SF 1 ""))]
3565 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
3569 (define_insn "*movsf_hardfloat"
3570 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3571 (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))]
3573 && (register_operand (operands[0], SFmode)
3574 || reg_or_0_operand (operands[1], SFmode))"
3575 { return mips_output_move (operands[0], operands[1]); }
3576 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3577 (set_attr "mode" "SF")
3578 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
3580 (define_insn "*movsf_softfloat"
3581 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
3582 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
3583 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
3584 && (register_operand (operands[0], SFmode)
3585 || reg_or_0_operand (operands[1], SFmode))"
3586 { return mips_output_move (operands[0], operands[1]); }
3587 [(set_attr "type" "arith,load,store")
3588 (set_attr "mode" "SF")
3589 (set_attr "length" "4,*,*")])
3591 (define_insn "*movsf_mips16"
3592 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
3593 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
3595 && (register_operand (operands[0], SFmode)
3596 || register_operand (operands[1], SFmode))"
3597 { return mips_output_move (operands[0], operands[1]); }
3598 [(set_attr "type" "arith,arith,arith,load,store")
3599 (set_attr "mode" "SF")
3600 (set_attr "length" "4,4,4,*,*")])
3603 ;; 64-bit floating point moves
3605 (define_expand "movdf"
3606 [(set (match_operand:DF 0 "")
3607 (match_operand:DF 1 ""))]
3610 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
3614 (define_insn "*movdf_hardfloat_64bit"
3615 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3616 (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3617 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
3618 && (register_operand (operands[0], DFmode)
3619 || reg_or_0_operand (operands[1], DFmode))"
3620 { return mips_output_move (operands[0], operands[1]); }
3621 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3622 (set_attr "mode" "DF")
3623 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
3625 (define_insn "*movdf_hardfloat_32bit"
3626 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3627 (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3628 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
3629 && (register_operand (operands[0], DFmode)
3630 || reg_or_0_operand (operands[1], DFmode))"
3631 { return mips_output_move (operands[0], operands[1]); }
3632 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3633 (set_attr "mode" "DF")
3634 (set_attr "length" "4,8,*,*,*,8,8,8,*,*")])
3636 (define_insn "*movdf_softfloat"
3637 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
3638 (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
3639 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
3640 && (register_operand (operands[0], DFmode)
3641 || reg_or_0_operand (operands[1], DFmode))"
3642 { return mips_output_move (operands[0], operands[1]); }
3643 [(set_attr "type" "arith,load,store,xfer,xfer,fmove")
3644 (set_attr "mode" "DF")
3645 (set_attr "length" "8,*,*,4,4,4")])
3647 (define_insn "*movdf_mips16"
3648 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
3649 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
3651 && (register_operand (operands[0], DFmode)
3652 || register_operand (operands[1], DFmode))"
3653 { return mips_output_move (operands[0], operands[1]); }
3654 [(set_attr "type" "arith,arith,arith,load,store")
3655 (set_attr "mode" "DF")
3656 (set_attr "length" "8,8,8,*,*")])
3659 [(set (match_operand:DI 0 "nonimmediate_operand")
3660 (match_operand:DI 1 "move_operand"))]
3661 "reload_completed && !TARGET_64BIT
3662 && mips_split_64bit_move_p (operands[0], operands[1])"
3665 mips_split_64bit_move (operands[0], operands[1]);
3670 [(set (match_operand:DF 0 "nonimmediate_operand")
3671 (match_operand:DF 1 "move_operand"))]
3672 "reload_completed && !TARGET_64BIT
3673 && mips_split_64bit_move_p (operands[0], operands[1])"
3676 mips_split_64bit_move (operands[0], operands[1]);
3680 ;; When generating mips16 code, split moves of negative constants into
3681 ;; a positive "li" followed by a negation.
3683 [(set (match_operand 0 "register_operand")
3684 (match_operand 1 "const_int_operand"))]
3685 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
3689 (neg:SI (match_dup 2)))]
3691 operands[2] = gen_lowpart (SImode, operands[0]);
3692 operands[3] = GEN_INT (-INTVAL (operands[1]));
3695 ;; 64-bit paired-single floating point moves
3697 (define_expand "movv2sf"
3698 [(set (match_operand:V2SF 0)
3699 (match_operand:V2SF 1))]
3700 "TARGET_PAIRED_SINGLE_FLOAT"
3702 if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
3706 (define_insn "movv2sf_hardfloat_64bit"
3707 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3708 (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
3709 "TARGET_PAIRED_SINGLE_FLOAT
3711 && (register_operand (operands[0], V2SFmode)
3712 || reg_or_0_operand (operands[1], V2SFmode))"
3713 { return mips_output_move (operands[0], operands[1]); }
3714 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3715 (set_attr "mode" "SF")
3716 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
3718 ;; The HI and LO registers are not truly independent. If we move an mthi
3719 ;; instruction before an mflo instruction, it will make the result of the
3720 ;; mflo unpredictable. The same goes for mtlo and mfhi.
3722 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
3723 ;; Operand 1 is the register we want, operand 2 is the other one.
3725 (define_insn "mfhilo_<mode>"
3726 [(set (match_operand:GPR 0 "register_operand" "=d,d")
3727 (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
3728 (match_operand:GPR 2 "register_operand" "l,h")]
3732 [(set_attr "type" "mfhilo")
3733 (set_attr "mode" "<MODE>")])
3735 ;; Patterns for loading or storing part of a paired floating point
3736 ;; register. We need them because odd-numbered floating-point registers
3737 ;; are not fully independent: see mips_split_64bit_move.
3739 ;; Load the low word of operand 0 with operand 1.
3740 (define_insn "load_df_low"
3741 [(set (match_operand:DF 0 "register_operand" "=f,f")
3742 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
3743 UNSPEC_LOAD_DF_LOW))]
3744 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3746 operands[0] = mips_subword (operands[0], 0);
3747 return mips_output_move (operands[0], operands[1]);
3749 [(set_attr "type" "xfer,fpload")
3750 (set_attr "mode" "SF")])
3752 ;; Load the high word of operand 0 from operand 1, preserving the value
3754 (define_insn "load_df_high"
3755 [(set (match_operand:DF 0 "register_operand" "=f,f")
3756 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
3757 (match_operand:DF 2 "register_operand" "0,0")]
3758 UNSPEC_LOAD_DF_HIGH))]
3759 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3761 operands[0] = mips_subword (operands[0], 1);
3762 return mips_output_move (operands[0], operands[1]);
3764 [(set_attr "type" "xfer,fpload")
3765 (set_attr "mode" "SF")])
3767 ;; Store the high word of operand 1 in operand 0. The corresponding
3768 ;; low-word move is done in the normal way.
3769 (define_insn "store_df_high"
3770 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
3771 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
3772 UNSPEC_STORE_DF_HIGH))]
3773 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3775 operands[1] = mips_subword (operands[1], 1);
3776 return mips_output_move (operands[0], operands[1]);
3778 [(set_attr "type" "xfer,fpstore")
3779 (set_attr "mode" "SF")])
3781 ;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
3782 ;; of _gp from the start of this function. Operand 1 is the incoming
3783 ;; function address.
3784 (define_insn_and_split "loadgp"
3785 [(unspec_volatile [(match_operand 0 "" "")
3786 (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
3787 "TARGET_ABICALLS && TARGET_NEWABI"
3790 [(set (match_dup 2) (match_dup 3))
3791 (set (match_dup 2) (match_dup 4))
3792 (set (match_dup 2) (match_dup 5))]
3794 operands[2] = pic_offset_table_rtx;
3795 operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
3796 operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
3797 operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
3799 [(set_attr "length" "12")])
3801 ;; The use of gp is hidden when not using explicit relocations.
3802 ;; This blockage instruction prevents the gp load from being
3803 ;; scheduled after an implicit use of gp. It also prevents
3804 ;; the load from being deleted as dead.
3805 (define_insn "loadgp_blockage"
3806 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
3809 [(set_attr "type" "unknown")
3810 (set_attr "mode" "none")
3811 (set_attr "length" "0")])
3813 ;; Emit a .cprestore directive, which normally expands to a single store
3814 ;; instruction. Note that we continue to use .cprestore for explicit reloc
3815 ;; code so that jals inside inline asms will work correctly.
3816 (define_insn "cprestore"
3817 [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
3821 if (set_nomacro && which_alternative == 1)
3822 return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
3824 return ".cprestore\t%0";
3826 [(set_attr "type" "store")
3827 (set_attr "length" "4,12")])
3829 ;; Block moves, see mips.c for more details.
3830 ;; Argument 0 is the destination
3831 ;; Argument 1 is the source
3832 ;; Argument 2 is the length
3833 ;; Argument 3 is the alignment
3835 (define_expand "movmemsi"
3836 [(parallel [(set (match_operand:BLK 0 "general_operand")
3837 (match_operand:BLK 1 "general_operand"))
3838 (use (match_operand:SI 2 ""))
3839 (use (match_operand:SI 3 "const_int_operand"))])]
3840 "!TARGET_MIPS16 && !TARGET_MEMCPY"
3842 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
3849 ;; ....................
3853 ;; ....................
3855 (define_expand "<optab><mode>3"
3856 [(set (match_operand:GPR 0 "register_operand")
3857 (any_shift:GPR (match_operand:GPR 1 "register_operand")
3858 (match_operand:SI 2 "arith_operand")))]
3861 /* On the mips16, a shift of more than 8 is a four byte instruction,
3862 so, for a shift between 8 and 16, it is just as fast to do two
3863 shifts of 8 or less. If there is a lot of shifting going on, we
3864 may win in CSE. Otherwise combine will put the shifts back
3865 together again. This can be called by function_arg, so we must
3866 be careful not to allocate a new register if we've reached the
3870 && GET_CODE (operands[2]) == CONST_INT
3871 && INTVAL (operands[2]) > 8
3872 && INTVAL (operands[2]) <= 16
3873 && !reload_in_progress
3874 && !reload_completed)
3876 rtx temp = gen_reg_rtx (<MODE>mode);
3878 emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8)));
3879 emit_insn (gen_<optab><mode>3 (operands[0], temp,
3880 GEN_INT (INTVAL (operands[2]) - 8)));
3885 (define_insn "*<optab><mode>3"
3886 [(set (match_operand:GPR 0 "register_operand" "=d")
3887 (any_shift:GPR (match_operand:GPR 1 "register_operand" "d")
3888 (match_operand:SI 2 "arith_operand" "dI")))]
3891 if (GET_CODE (operands[2]) == CONST_INT)
3892 operands[2] = GEN_INT (INTVAL (operands[2])
3893 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3895 return "<d><insn>\t%0,%1,%2";
3897 [(set_attr "type" "shift")
3898 (set_attr "mode" "<MODE>")])
3900 (define_insn "*<optab>si3_extend"
3901 [(set (match_operand:DI 0 "register_operand" "=d")
3903 (any_shift:SI (match_operand:SI 1 "register_operand" "d")
3904 (match_operand:SI 2 "arith_operand" "dI"))))]
3905 "TARGET_64BIT && !TARGET_MIPS16"
3907 if (GET_CODE (operands[2]) == CONST_INT)
3908 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
3910 return "<insn>\t%0,%1,%2";
3912 [(set_attr "type" "shift")
3913 (set_attr "mode" "SI")])
3915 (define_insn "*<optab>si3_mips16"
3916 [(set (match_operand:SI 0 "register_operand" "=d,d")
3917 (any_shift:SI (match_operand:SI 1 "register_operand" "0,d")
3918 (match_operand:SI 2 "arith_operand" "d,I")))]
3921 if (which_alternative == 0)
3922 return "<insn>\t%0,%2";
3924 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
3925 return "<insn>\t%0,%1,%2";
3927 [(set_attr "type" "shift")
3928 (set_attr "mode" "SI")
3929 (set_attr_alternative "length"
3931 (if_then_else (match_operand 2 "m16_uimm3_b")
3935 ;; We need separate DImode MIPS16 patterns because of the irregularity
3937 (define_insn "*ashldi3_mips16"
3938 [(set (match_operand:DI 0 "register_operand" "=d,d")
3939 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
3940 (match_operand:SI 2 "arith_operand" "d,I")))]
3941 "TARGET_64BIT && TARGET_MIPS16"
3943 if (which_alternative == 0)
3944 return "dsll\t%0,%2";
3946 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
3947 return "dsll\t%0,%1,%2";
3949 [(set_attr "type" "shift")
3950 (set_attr "mode" "DI")
3951 (set_attr_alternative "length"
3953 (if_then_else (match_operand 2 "m16_uimm3_b")
3957 (define_insn "*ashrdi3_mips16"
3958 [(set (match_operand:DI 0 "register_operand" "=d,d")
3959 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
3960 (match_operand:SI 2 "arith_operand" "d,I")))]
3961 "TARGET_64BIT && TARGET_MIPS16"
3963 if (GET_CODE (operands[2]) == CONST_INT)
3964 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
3966 return "dsra\t%0,%2";
3968 [(set_attr "type" "shift")
3969 (set_attr "mode" "DI")
3970 (set_attr_alternative "length"
3972 (if_then_else (match_operand 2 "m16_uimm3_b")
3976 (define_insn "*lshrdi3_mips16"
3977 [(set (match_operand:DI 0 "register_operand" "=d,d")
3978 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
3979 (match_operand:SI 2 "arith_operand" "d,I")))]
3980 "TARGET_64BIT && TARGET_MIPS16"
3982 if (GET_CODE (operands[2]) == CONST_INT)
3983 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
3985 return "dsrl\t%0,%2";
3987 [(set_attr "type" "shift")
3988 (set_attr "mode" "DI")
3989 (set_attr_alternative "length"
3991 (if_then_else (match_operand 2 "m16_uimm3_b")
3995 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
3998 [(set (match_operand:GPR 0 "register_operand")
3999 (any_shift:GPR (match_operand:GPR 1 "register_operand")
4000 (match_operand:GPR 2 "const_int_operand")))]
4001 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4002 && GET_CODE (operands[2]) == CONST_INT
4003 && INTVAL (operands[2]) > 8
4004 && INTVAL (operands[2]) <= 16"
4005 [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
4006 (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
4007 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4009 ;; If we load a byte on the mips16 as a bitfield, the resulting
4010 ;; sequence of instructions is too complicated for combine, because it
4011 ;; involves four instructions: a load, a shift, a constant load into a
4012 ;; register, and an and (the key problem here is that the mips16 does
4013 ;; not have and immediate). We recognize a shift of a load in order
4014 ;; to make it simple enough for combine to understand.
4016 ;; The length here is the worst case: the length of the split version
4017 ;; will be more accurate.
4018 (define_insn_and_split ""
4019 [(set (match_operand:SI 0 "register_operand" "=d")
4020 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4021 (match_operand:SI 2 "immediate_operand" "I")))]
4025 [(set (match_dup 0) (match_dup 1))
4026 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4028 [(set_attr "type" "load")
4029 (set_attr "mode" "SI")
4030 (set_attr "length" "16")])
4032 (define_insn "rotr<mode>3"
4033 [(set (match_operand:GPR 0 "register_operand" "=d")
4034 (rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
4035 (match_operand:SI 2 "arith_operand" "dI")))]
4036 "ISA_HAS_ROTR_<MODE>"
4038 if (GET_CODE (operands[2]) == CONST_INT)
4039 gcc_assert (INTVAL (operands[2]) >= 0
4040 && INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode));
4042 return "<d>ror\t%0,%1,%2";
4044 [(set_attr "type" "shift")
4045 (set_attr "mode" "<MODE>")])
4048 ;; ....................
4052 ;; ....................
4054 ;; Flow here is rather complex:
4056 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the arguments
4057 ;; into cmp_operands[] but generates no RTL.
4059 ;; 2) The appropriate branch define_expand is called, which then
4060 ;; creates the appropriate RTL for the comparison and branch.
4061 ;; Different CC modes are used, based on what type of branch is
4062 ;; done, so that we can constrain things appropriately. There
4063 ;; are assumptions in the rest of GCC that break if we fold the
4064 ;; operands into the branches for integer operations, and use cc0
4065 ;; for floating point, so we use the fp status register instead.
4066 ;; If needed, an appropriate temporary is created to hold the
4067 ;; of the integer compare.
4069 (define_expand "cmp<mode>"
4071 (compare:CC (match_operand:GPR 0 "register_operand")
4072 (match_operand:GPR 1 "nonmemory_operand")))]
4075 cmp_operands[0] = operands[0];
4076 cmp_operands[1] = operands[1];
4080 (define_expand "cmp<mode>"
4082 (compare:CC (match_operand:SCALARF 0 "register_operand")
4083 (match_operand:SCALARF 1 "register_operand")))]
4086 cmp_operands[0] = operands[0];
4087 cmp_operands[1] = operands[1];
4092 ;; ....................
4094 ;; CONDITIONAL BRANCHES
4096 ;; ....................
4098 ;; Conditional branches on floating-point equality tests.
4100 (define_insn "branch_fp"
4103 (match_operator:CC 0 "comparison_operator"
4104 [(match_operand:CC 2 "register_operand" "z")
4106 (label_ref (match_operand 1 "" ""))
4110 return mips_output_conditional_branch (insn,
4112 /*two_operands_p=*/0,
4115 get_attr_length (insn));
4117 [(set_attr "type" "branch")
4118 (set_attr "mode" "none")])
4120 (define_insn "branch_fp_inverted"
4123 (match_operator:CC 0 "comparison_operator"
4124 [(match_operand:CC 2 "register_operand" "z")
4127 (label_ref (match_operand 1 "" ""))))]
4130 return mips_output_conditional_branch (insn,
4132 /*two_operands_p=*/0,
4135 get_attr_length (insn));
4137 [(set_attr "type" "branch")
4138 (set_attr "mode" "none")])
4140 ;; Conditional branches on comparisons with zero.
4142 (define_insn "*branch_zero<mode>"
4145 (match_operator:GPR 0 "comparison_operator"
4146 [(match_operand:GPR 2 "register_operand" "d")
4148 (label_ref (match_operand 1 "" ""))
4152 return mips_output_conditional_branch (insn,
4154 /*two_operands_p=*/0,
4157 get_attr_length (insn));
4159 [(set_attr "type" "branch")
4160 (set_attr "mode" "none")])
4162 (define_insn "*branch_zero<mode>_inverted"
4165 (match_operator:GPR 0 "comparison_operator"
4166 [(match_operand:GPR 2 "register_operand" "d")
4169 (label_ref (match_operand 1 "" ""))))]
4172 return mips_output_conditional_branch (insn,
4174 /*two_operands_p=*/0,
4177 get_attr_length (insn));
4179 [(set_attr "type" "branch")
4180 (set_attr "mode" "none")])
4182 ;; Conditional branch on equality comparison.
4184 (define_insn "*branch_equality<mode>"
4187 (match_operator:GPR 0 "equality_operator"
4188 [(match_operand:GPR 2 "register_operand" "d")
4189 (match_operand:GPR 3 "register_operand" "d")])
4190 (label_ref (match_operand 1 "" ""))
4194 return mips_output_conditional_branch (insn,
4196 /*two_operands_p=*/1,
4199 get_attr_length (insn));
4201 [(set_attr "type" "branch")
4202 (set_attr "mode" "none")])
4204 (define_insn "*branch_equality<mode>_inverted"
4207 (match_operator:GPR 0 "equality_operator"
4208 [(match_operand:GPR 2 "register_operand" "d")
4209 (match_operand:GPR 3 "register_operand" "d")])
4211 (label_ref (match_operand 1 "" ""))))]
4214 return mips_output_conditional_branch (insn,
4216 /*two_operands_p=*/1,
4219 get_attr_length (insn));
4221 [(set_attr "type" "branch")
4222 (set_attr "mode" "none")])
4226 (define_insn "*branch_equality<mode>_mips16"
4229 (match_operator:GPR 0 "equality_operator"
4230 [(match_operand:GPR 1 "register_operand" "d,t")
4232 (match_operand 2 "pc_or_label_operand" "")
4233 (match_operand 3 "pc_or_label_operand" "")))]
4236 if (operands[2] != pc_rtx)
4238 if (which_alternative == 0)
4239 return "b%C0z\t%1,%2";
4241 return "bt%C0z\t%2";
4245 if (which_alternative == 0)
4246 return "b%N0z\t%1,%3";
4248 return "bt%N0z\t%3";
4251 [(set_attr "type" "branch")
4252 (set_attr "mode" "none")
4253 (set_attr "length" "8")])
4255 (define_expand "b<code>"
4257 (if_then_else (any_cond:CC (cc0)
4259 (label_ref (match_operand 0 ""))
4263 gen_conditional_branch (operands, <CODE>);
4268 ;; ....................
4270 ;; SETTING A REGISTER FROM A COMPARISON
4272 ;; ....................
4274 (define_expand "seq"
4275 [(set (match_operand:SI 0 "register_operand")
4276 (eq:SI (match_dup 1)
4279 { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
4281 (define_insn "*seq_<mode>"
4282 [(set (match_operand:GPR 0 "register_operand" "=d")
4283 (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4287 [(set_attr "type" "slt")
4288 (set_attr "mode" "<MODE>")])
4290 (define_insn "*seq_<mode>_mips16"
4291 [(set (match_operand:GPR 0 "register_operand" "=t")
4292 (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4296 [(set_attr "type" "slt")
4297 (set_attr "mode" "<MODE>")])
4299 ;; "sne" uses sltu instructions in which the first operand is $0.
4300 ;; This isn't possible in mips16 code.
4302 (define_expand "sne"
4303 [(set (match_operand:SI 0 "register_operand")
4304 (ne:SI (match_dup 1)
4307 { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
4309 (define_insn "*sne_<mode>"
4310 [(set (match_operand:GPR 0 "register_operand" "=d")
4311 (ne:GPR (match_operand:GPR 1 "register_operand" "d")
4315 [(set_attr "type" "slt")
4316 (set_attr "mode" "<MODE>")])
4318 (define_expand "sgt"
4319 [(set (match_operand:SI 0 "register_operand")
4320 (gt:SI (match_dup 1)
4323 { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
4325 (define_insn "*sgt_<mode>"
4326 [(set (match_operand:GPR 0 "register_operand" "=d")
4327 (gt:GPR (match_operand:GPR 1 "register_operand" "d")
4328 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4331 [(set_attr "type" "slt")
4332 (set_attr "mode" "<MODE>")])
4334 (define_insn "*sgt_<mode>_mips16"
4335 [(set (match_operand:GPR 0 "register_operand" "=t")
4336 (gt:GPR (match_operand:GPR 1 "register_operand" "d")
4337 (match_operand:GPR 2 "register_operand" "d")))]
4340 [(set_attr "type" "slt")
4341 (set_attr "mode" "<MODE>")])
4343 (define_expand "sge"
4344 [(set (match_operand:SI 0 "register_operand")
4345 (ge:SI (match_dup 1)
4348 { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
4350 (define_insn "*sge_<mode>"
4351 [(set (match_operand:GPR 0 "register_operand" "=d")
4352 (ge:GPR (match_operand:GPR 1 "register_operand" "d")
4356 [(set_attr "type" "slt")
4357 (set_attr "mode" "<MODE>")])
4359 (define_expand "slt"
4360 [(set (match_operand:SI 0 "register_operand")
4361 (lt:SI (match_dup 1)
4364 { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
4366 (define_insn "*slt_<mode>"
4367 [(set (match_operand:GPR 0 "register_operand" "=d")
4368 (lt:GPR (match_operand:GPR 1 "register_operand" "d")
4369 (match_operand:GPR 2 "arith_operand" "dI")))]
4372 [(set_attr "type" "slt")
4373 (set_attr "mode" "<MODE>")])
4375 (define_insn "*slt_<mode>_mips16"
4376 [(set (match_operand:GPR 0 "register_operand" "=t,t")
4377 (lt:GPR (match_operand:GPR 1 "register_operand" "d,d")
4378 (match_operand:GPR 2 "arith_operand" "d,I")))]
4381 [(set_attr "type" "slt")
4382 (set_attr "mode" "<MODE>")
4383 (set_attr_alternative "length"
4385 (if_then_else (match_operand 2 "m16_uimm8_1")
4389 (define_expand "sle"
4390 [(set (match_operand:SI 0 "register_operand")
4391 (le:SI (match_dup 1)
4394 { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
4396 (define_insn "*sle_<mode>"
4397 [(set (match_operand:GPR 0 "register_operand" "=d")
4398 (le:GPR (match_operand:GPR 1 "register_operand" "d")
4399 (match_operand:GPR 2 "sle_operand" "")))]
4402 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4403 return "slt\t%0,%1,%2";
4405 [(set_attr "type" "slt")
4406 (set_attr "mode" "<MODE>")])
4408 (define_insn "*sle_<mode>_mips16"
4409 [(set (match_operand:GPR 0 "register_operand" "=t")
4410 (le:GPR (match_operand:GPR 1 "register_operand" "d")
4411 (match_operand:GPR 2 "sle_operand" "")))]
4414 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4415 return "slt\t%1,%2";
4417 [(set_attr "type" "slt")
4418 (set_attr "mode" "<MODE>")
4419 (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4423 (define_expand "sgtu"
4424 [(set (match_operand:SI 0 "register_operand")
4425 (gtu:SI (match_dup 1)
4428 { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
4430 (define_insn "*sgtu_<mode>"
4431 [(set (match_operand:GPR 0 "register_operand" "=d")
4432 (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4433 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4436 [(set_attr "type" "slt")
4437 (set_attr "mode" "<MODE>")])
4439 (define_insn "*sgtu_<mode>_mips16"
4440 [(set (match_operand:GPR 0 "register_operand" "=t")
4441 (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4442 (match_operand:GPR 2 "register_operand" "d")))]
4445 [(set_attr "type" "slt")
4446 (set_attr "mode" "<MODE>")])
4448 (define_expand "sgeu"
4449 [(set (match_operand:SI 0 "register_operand")
4450 (geu:SI (match_dup 1)
4453 { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
4455 (define_insn "*sge_<mode>"
4456 [(set (match_operand:GPR 0 "register_operand" "=d")
4457 (geu:GPR (match_operand:GPR 1 "register_operand" "d")
4461 [(set_attr "type" "slt")
4462 (set_attr "mode" "<MODE>")])
4464 (define_expand "sltu"
4465 [(set (match_operand:SI 0 "register_operand")
4466 (ltu:SI (match_dup 1)
4469 { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
4471 (define_insn "*sltu_<mode>"
4472 [(set (match_operand:GPR 0 "register_operand" "=d")
4473 (ltu:GPR (match_operand:GPR 1 "register_operand" "d")
4474 (match_operand:GPR 2 "arith_operand" "dI")))]
4477 [(set_attr "type" "slt")
4478 (set_attr "mode" "<MODE>")])
4480 (define_insn "*sltu_<mode>_mips16"
4481 [(set (match_operand:GPR 0 "register_operand" "=t,t")
4482 (ltu:GPR (match_operand:GPR 1 "register_operand" "d,d")
4483 (match_operand:GPR 2 "arith_operand" "d,I")))]
4486 [(set_attr "type" "slt")
4487 (set_attr "mode" "<MODE>")
4488 (set_attr_alternative "length"
4490 (if_then_else (match_operand 2 "m16_uimm8_1")
4494 (define_expand "sleu"
4495 [(set (match_operand:SI 0 "register_operand")
4496 (leu:SI (match_dup 1)
4499 { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
4501 (define_insn "*sleu_<mode>"
4502 [(set (match_operand:GPR 0 "register_operand" "=d")
4503 (leu:GPR (match_operand:GPR 1 "register_operand" "d")
4504 (match_operand:GPR 2 "sleu_operand" "")))]
4507 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4508 return "sltu\t%0,%1,%2";
4510 [(set_attr "type" "slt")
4511 (set_attr "mode" "<MODE>")])
4513 (define_insn "*sleu_<mode>_mips16"
4514 [(set (match_operand:GPR 0 "register_operand" "=t")
4515 (leu:GPR (match_operand:GPR 1 "register_operand" "d")
4516 (match_operand:GPR 2 "sleu_operand" "")))]
4519 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4520 return "sltu\t%1,%2";
4522 [(set_attr "type" "slt")
4523 (set_attr "mode" "<MODE>")
4524 (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4529 ;; ....................
4531 ;; FLOATING POINT COMPARISONS
4533 ;; ....................
4535 (define_insn "s<code>_<mode>"
4536 [(set (match_operand:CC 0 "register_operand" "=z")
4537 (fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
4538 (match_operand:SCALARF 2 "register_operand" "f")))]
4540 "c.<fcond>.<fmt>\t%Z0%1,%2"
4541 [(set_attr "type" "fcmp")
4542 (set_attr "mode" "FPSW")])
4544 (define_insn "sgt_<mode>"
4545 [(set (match_operand:CC 0 "register_operand" "=z")
4546 (gt:CC (match_operand:SCALARF 1 "register_operand" "f")
4547 (match_operand:SCALARF 2 "register_operand" "f")))]
4549 "c.lt.<fmt>\t%Z0%2,%1"
4550 [(set_attr "type" "fcmp")
4551 (set_attr "mode" "FPSW")])
4553 (define_insn "sge_<mode>"
4554 [(set (match_operand:CC 0 "register_operand" "=z")
4555 (ge:CC (match_operand:SCALARF 1 "register_operand" "f")
4556 (match_operand:SCALARF 2 "register_operand" "f")))]
4558 "c.le.<fmt>\t%Z0%2,%1"
4559 [(set_attr "type" "fcmp")
4560 (set_attr "mode" "FPSW")])
4563 ;; ....................
4565 ;; UNCONDITIONAL BRANCHES
4567 ;; ....................
4569 ;; Unconditional branches.
4573 (label_ref (match_operand 0 "" "")))]
4578 if (get_attr_length (insn) <= 8)
4579 return "%*b\t%l0%/";
4582 output_asm_insn (mips_output_load_label (), operands);
4583 return "%*jr\t%@%/%]";
4587 return "%*j\t%l0%/";
4589 [(set_attr "type" "jump")
4590 (set_attr "mode" "none")
4591 (set (attr "length")
4592 ;; We can't use `j' when emitting PIC. Emit a branch if it's
4593 ;; in range, otherwise load the address of the branch target into
4594 ;; $at and then jump to it.
4596 (ior (eq (symbol_ref "flag_pic") (const_int 0))
4597 (lt (abs (minus (match_dup 0)
4598 (plus (pc) (const_int 4))))
4599 (const_int 131072)))
4600 (const_int 4) (const_int 16)))])
4602 ;; We need a different insn for the mips16, because a mips16 branch
4603 ;; does not have a delay slot.
4607 (label_ref (match_operand 0 "" "")))]
4610 [(set_attr "type" "branch")
4611 (set_attr "mode" "none")
4612 (set_attr "length" "8")])
4614 (define_expand "indirect_jump"
4615 [(set (pc) (match_operand 0 "register_operand"))]
4618 operands[0] = force_reg (Pmode, operands[0]);
4619 if (Pmode == SImode)
4620 emit_jump_insn (gen_indirect_jumpsi (operands[0]));
4622 emit_jump_insn (gen_indirect_jumpdi (operands[0]));
4626 (define_insn "indirect_jump<mode>"
4627 [(set (pc) (match_operand:P 0 "register_operand" "d"))]
4630 [(set_attr "type" "jump")
4631 (set_attr "mode" "none")])
4633 (define_expand "tablejump"
4635 (match_operand 0 "register_operand"))
4636 (use (label_ref (match_operand 1 "")))]
4640 operands[0] = expand_binop (Pmode, add_optab,
4641 convert_to_mode (Pmode, operands[0], false),
4642 gen_rtx_LABEL_REF (Pmode, operands[1]),
4644 else if (TARGET_GPWORD)
4645 operands[0] = expand_binop (Pmode, add_optab, operands[0],
4646 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
4648 if (Pmode == SImode)
4649 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
4651 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
4655 (define_insn "tablejump<mode>"
4657 (match_operand:P 0 "register_operand" "d"))
4658 (use (label_ref (match_operand 1 "" "")))]
4661 [(set_attr "type" "jump")
4662 (set_attr "mode" "none")])
4664 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
4665 ;; While it is possible to either pull it off the stack (in the
4666 ;; o32 case) or recalculate it given t9 and our target label,
4667 ;; it takes 3 or 4 insns to do so.
4669 (define_expand "builtin_setjmp_setup"
4670 [(use (match_operand 0 "register_operand"))]
4675 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
4676 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
4680 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
4681 ;; that older code did recalculate the gp from $25. Continue to jump through
4682 ;; $25 for compatibility (we lose nothing by doing so).
4684 (define_expand "builtin_longjmp"
4685 [(use (match_operand 0 "register_operand"))]
4688 /* The elements of the buffer are, in order: */
4689 int W = GET_MODE_SIZE (Pmode);
4690 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
4691 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
4692 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
4693 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
4694 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
4695 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
4696 The target is bound to be using $28 as the global pointer
4697 but the current function might not be. */
4698 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
4700 /* This bit is similar to expand_builtin_longjmp except that it
4701 restores $gp as well. */
4702 emit_move_insn (hard_frame_pointer_rtx, fp);
4703 emit_move_insn (pv, lab);
4704 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
4705 emit_move_insn (gp, gpv);
4706 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
4707 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4708 emit_insn (gen_rtx_USE (VOIDmode, gp));
4709 emit_indirect_jump (pv);
4714 ;; ....................
4716 ;; Function prologue/epilogue
4718 ;; ....................
4721 (define_expand "prologue"
4725 mips_expand_prologue ();
4729 ;; Block any insns from being moved before this point, since the
4730 ;; profiling call to mcount can use various registers that aren't
4731 ;; saved or used to pass arguments.
4733 (define_insn "blockage"
4734 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
4737 [(set_attr "type" "unknown")
4738 (set_attr "mode" "none")
4739 (set_attr "length" "0")])
4741 (define_expand "epilogue"
4745 mips_expand_epilogue (false);
4749 (define_expand "sibcall_epilogue"
4753 mips_expand_epilogue (true);
4757 ;; Trivial return. Make it look like a normal return insn as that
4758 ;; allows jump optimizations to work better.
4760 (define_insn "return"
4762 "mips_can_use_return_insn ()"
4764 [(set_attr "type" "jump")
4765 (set_attr "mode" "none")])
4769 (define_insn "return_internal"
4771 (use (match_operand 0 "pmode_register_operand" ""))]
4774 [(set_attr "type" "jump")
4775 (set_attr "mode" "none")])
4777 ;; This is used in compiling the unwind routines.
4778 (define_expand "eh_return"
4779 [(use (match_operand 0 "general_operand"))]
4782 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
4784 if (GET_MODE (operands[0]) != gpr_mode)
4785 operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
4787 emit_insn (gen_eh_set_lr_di (operands[0]));
4789 emit_insn (gen_eh_set_lr_si (operands[0]));
4794 ;; Clobber the return address on the stack. We can't expand this
4795 ;; until we know where it will be put in the stack frame.
4797 (define_insn "eh_set_lr_si"
4798 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
4799 (clobber (match_scratch:SI 1 "=&d"))]
4803 (define_insn "eh_set_lr_di"
4804 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
4805 (clobber (match_scratch:DI 1 "=&d"))]
4810 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
4811 (clobber (match_scratch 1))]
4812 "reload_completed && !TARGET_DEBUG_D_MODE"
4815 mips_set_return_address (operands[0], operands[1]);
4819 (define_insn_and_split "exception_receiver"
4821 (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
4822 "TARGET_ABICALLS && TARGET_OLDABI"
4824 "&& reload_completed"
4830 [(set_attr "type" "load")
4831 (set_attr "length" "12")])
4834 ;; ....................
4838 ;; ....................
4840 ;; Instructions to load a call address from the GOT. The address might
4841 ;; point to a function or to a lazy binding stub. In the latter case,
4842 ;; the stub will use the dynamic linker to resolve the function, which
4843 ;; in turn will change the GOT entry to point to the function's real
4846 ;; This means that every call, even pure and constant ones, can
4847 ;; potentially modify the GOT entry. And once a stub has been called,
4848 ;; we must not call it again.
4850 ;; We represent this restriction using an imaginary fixed register that
4851 ;; acts like a GOT version number. By making the register call-clobbered,
4852 ;; we tell the target-independent code that the address could be changed
4853 ;; by any call insn.
4854 (define_insn "load_call<mode>"
4855 [(set (match_operand:P 0 "register_operand" "=c")
4856 (unspec:P [(match_operand:P 1 "register_operand" "r")
4857 (match_operand:P 2 "immediate_operand" "")
4858 (reg:P FAKE_CALL_REGNO)]
4861 "<load>\t%0,%R2(%1)"
4862 [(set_attr "type" "load")
4863 (set_attr "mode" "<MODE>")
4864 (set_attr "length" "4")])
4866 ;; Sibling calls. All these patterns use jump instructions.
4868 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
4869 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
4870 ;; is defined in terms of call_insn_operand, the same is true of the
4873 ;; When we use an indirect jump, we need a register that will be
4874 ;; preserved by the epilogue. Since TARGET_ABICALLS forces us to
4875 ;; use $25 for this purpose -- and $25 is never clobbered by the
4876 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
4878 (define_expand "sibcall"
4879 [(parallel [(call (match_operand 0 "")
4880 (match_operand 1 ""))
4881 (use (match_operand 2 "")) ;; next_arg_reg
4882 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
4885 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
4889 (define_insn "sibcall_internal"
4890 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
4891 (match_operand 1 "" ""))]
4892 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
4896 [(set_attr "type" "call")])
4898 (define_expand "sibcall_value"
4899 [(parallel [(set (match_operand 0 "")
4900 (call (match_operand 1 "")
4901 (match_operand 2 "")))
4902 (use (match_operand 3 ""))])] ;; next_arg_reg
4905 mips_expand_call (operands[0], XEXP (operands[1], 0),
4906 operands[2], operands[3], true);
4910 (define_insn "sibcall_value_internal"
4911 [(set (match_operand 0 "register_operand" "=df,df")
4912 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
4913 (match_operand 2 "" "")))]
4914 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
4918 [(set_attr "type" "call")])
4920 (define_insn "sibcall_value_multiple_internal"
4921 [(set (match_operand 0 "register_operand" "=df,df")
4922 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
4923 (match_operand 2 "" "")))
4924 (set (match_operand 3 "register_operand" "=df,df")
4925 (call (mem:SI (match_dup 1))
4927 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
4931 [(set_attr "type" "call")])
4933 (define_expand "call"
4934 [(parallel [(call (match_operand 0 "")
4935 (match_operand 1 ""))
4936 (use (match_operand 2 "")) ;; next_arg_reg
4937 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
4940 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
4944 ;; This instruction directly corresponds to an assembly-language "jal".
4945 ;; There are four cases:
4948 ;; Both symbolic and register destinations are OK. The pattern
4949 ;; always expands to a single mips instruction.
4951 ;; - -mabicalls/-mno-explicit-relocs:
4952 ;; Again, both symbolic and register destinations are OK.
4953 ;; The call is treated as a multi-instruction black box.
4955 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
4956 ;; Only "jal $25" is allowed. This expands to a single "jalr $25"
4959 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
4960 ;; Only "jal $25" is allowed. The call is actually two instructions:
4961 ;; "jalr $25" followed by an insn to reload $gp.
4963 ;; In the last case, we can generate the individual instructions with
4964 ;; a define_split. There are several things to be wary of:
4966 ;; - We can't expose the load of $gp before reload. If we did,
4967 ;; it might get removed as dead, but reload can introduce new
4968 ;; uses of $gp by rematerializing constants.
4970 ;; - We shouldn't restore $gp after calls that never return.
4971 ;; It isn't valid to insert instructions between a noreturn
4972 ;; call and the following barrier.
4974 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
4975 ;; instruction preserves $gp and so have no effect on its liveness.
4976 ;; But once we generate the separate insns, it becomes obvious that
4977 ;; $gp is not live on entry to the call.
4979 ;; ??? The operands[2] = insn check is a hack to make the original insn
4980 ;; available to the splitter.
4981 (define_insn_and_split "call_internal"
4982 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
4983 (match_operand 1 "" ""))
4984 (clobber (reg:SI 31))]
4986 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
4987 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
4990 emit_call_insn (gen_call_split (operands[0], operands[1]));
4991 if (!find_reg_note (operands[2], REG_NORETURN, 0))
4995 [(set_attr "jal" "indirect,direct")
4996 (set_attr "extended_mips16" "no,yes")])
4998 (define_insn "call_split"
4999 [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
5000 (match_operand 1 "" ""))
5001 (clobber (reg:SI 31))
5002 (clobber (reg:SI 28))]
5003 "TARGET_SPLIT_CALLS"
5005 [(set_attr "type" "call")])
5007 (define_expand "call_value"
5008 [(parallel [(set (match_operand 0 "")
5009 (call (match_operand 1 "")
5010 (match_operand 2 "")))
5011 (use (match_operand 3 ""))])] ;; next_arg_reg
5014 mips_expand_call (operands[0], XEXP (operands[1], 0),
5015 operands[2], operands[3], false);
5019 ;; See comment for call_internal.
5020 (define_insn_and_split "call_value_internal"
5021 [(set (match_operand 0 "register_operand" "=df,df")
5022 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5023 (match_operand 2 "" "")))
5024 (clobber (reg:SI 31))]
5026 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
5027 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
5030 emit_call_insn (gen_call_value_split (operands[0], operands[1],
5032 if (!find_reg_note (operands[3], REG_NORETURN, 0))
5036 [(set_attr "jal" "indirect,direct")
5037 (set_attr "extended_mips16" "no,yes")])
5039 (define_insn "call_value_split"
5040 [(set (match_operand 0 "register_operand" "=df")
5041 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
5042 (match_operand 2 "" "")))
5043 (clobber (reg:SI 31))
5044 (clobber (reg:SI 28))]
5045 "TARGET_SPLIT_CALLS"
5047 [(set_attr "type" "call")])
5049 ;; See comment for call_internal.
5050 (define_insn_and_split "call_value_multiple_internal"
5051 [(set (match_operand 0 "register_operand" "=df,df")
5052 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5053 (match_operand 2 "" "")))
5054 (set (match_operand 3 "register_operand" "=df,df")
5055 (call (mem:SI (match_dup 1))
5057 (clobber (reg:SI 31))]
5059 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
5060 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
5063 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
5064 operands[2], operands[3]));
5065 if (!find_reg_note (operands[4], REG_NORETURN, 0))
5069 [(set_attr "jal" "indirect,direct")
5070 (set_attr "extended_mips16" "no,yes")])
5072 (define_insn "call_value_multiple_split"
5073 [(set (match_operand 0 "register_operand" "=df")
5074 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
5075 (match_operand 2 "" "")))
5076 (set (match_operand 3 "register_operand" "=df")
5077 (call (mem:SI (match_dup 1))
5079 (clobber (reg:SI 31))
5080 (clobber (reg:SI 28))]
5081 "TARGET_SPLIT_CALLS"
5083 [(set_attr "type" "call")])
5085 ;; Call subroutine returning any type.
5087 (define_expand "untyped_call"
5088 [(parallel [(call (match_operand 0 "")
5090 (match_operand 1 "")
5091 (match_operand 2 "")])]
5096 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
5098 for (i = 0; i < XVECLEN (operands[2], 0); i++)
5100 rtx set = XVECEXP (operands[2], 0, i);
5101 emit_move_insn (SET_DEST (set), SET_SRC (set));
5104 emit_insn (gen_blockage ());
5109 ;; ....................
5113 ;; ....................
5117 (define_insn "prefetch"
5118 [(prefetch (match_operand:QI 0 "address_operand" "p")
5119 (match_operand 1 "const_int_operand" "n")
5120 (match_operand 2 "const_int_operand" "n"))]
5121 "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
5123 operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
5124 return "pref\t%1,%a0";
5126 [(set_attr "type" "prefetch")])
5128 (define_insn "*prefetch_indexed_<mode>"
5129 [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
5130 (match_operand:P 1 "register_operand" "d"))
5131 (match_operand 2 "const_int_operand" "n")
5132 (match_operand 3 "const_int_operand" "n"))]
5133 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5135 operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
5136 return "prefx\t%2,%1(%0)";
5138 [(set_attr "type" "prefetchx")])
5144 [(set_attr "type" "nop")
5145 (set_attr "mode" "none")])
5147 ;; Like nop, but commented out when outside a .set noreorder block.
5148 (define_insn "hazard_nop"
5157 [(set_attr "type" "nop")])
5159 ;; MIPS4 Conditional move instructions.
5161 (define_insn "*mov<GPR:mode>_on_<MOVECC:mode>"
5162 [(set (match_operand:GPR 0 "register_operand" "=d,d")
5164 (match_operator:MOVECC 4 "equality_operator"
5165 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5167 (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
5168 (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
5173 [(set_attr "type" "condmove")
5174 (set_attr "mode" "<GPR:MODE>")])
5176 (define_insn "*mov<SCALARF:mode>_on_<MOVECC:mode>"
5177 [(set (match_operand:SCALARF 0 "register_operand" "=f,f")
5178 (if_then_else:SCALARF
5179 (match_operator:MOVECC 4 "equality_operator"
5180 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5182 (match_operand:SCALARF 2 "register_operand" "f,0")
5183 (match_operand:SCALARF 3 "register_operand" "0,f")))]
5186 mov%T4.<fmt>\t%0,%2,%1
5187 mov%t4.<fmt>\t%0,%3,%1"
5188 [(set_attr "type" "condmove")
5189 (set_attr "mode" "<SCALARF:MODE>")])
5191 ;; These are the main define_expand's used to make conditional moves.
5193 (define_expand "mov<mode>cc"
5194 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5195 (set (match_operand:GPR 0 "register_operand")
5196 (if_then_else:GPR (match_dup 5)
5197 (match_operand:GPR 2 "reg_or_0_operand")
5198 (match_operand:GPR 3 "reg_or_0_operand")))]
5201 gen_conditional_move (operands);
5205 (define_expand "mov<mode>cc"
5206 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5207 (set (match_operand:SCALARF 0 "register_operand")
5208 (if_then_else:SCALARF (match_dup 5)
5209 (match_operand:SCALARF 2 "register_operand")
5210 (match_operand:SCALARF 3 "register_operand")))]
5213 gen_conditional_move (operands);
5218 ;; ....................
5220 ;; mips16 inline constant tables
5222 ;; ....................
5225 (define_insn "consttable_int"
5226 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
5227 (match_operand 1 "const_int_operand" "")]
5228 UNSPEC_CONSTTABLE_INT)]
5231 assemble_integer (operands[0], INTVAL (operands[1]),
5232 BITS_PER_UNIT * INTVAL (operands[1]), 1);
5235 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
5237 (define_insn "consttable_float"
5238 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
5239 UNSPEC_CONSTTABLE_FLOAT)]
5244 gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
5245 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
5246 assemble_real (d, GET_MODE (operands[0]),
5247 GET_MODE_BITSIZE (GET_MODE (operands[0])));
5250 [(set (attr "length")
5251 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
5253 (define_insn "align"
5254 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
5257 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
5260 [(match_operand 0 "small_data_pattern")]
5263 { operands[0] = mips_rewrite_small_data (operands[0]); })
5265 ; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
5267 (include "mips-ps-3d.md")