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, 2005 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, 51 Franklin Street, Fifth Floor,
24 ;; Boston, MA 02110-1301, 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_TLS_GET_TP 28)
51 (UNSPEC_ADDRESS_FIRST 100)
55 ;; For MIPS Paired-Singled Floating Point Instructions.
57 (UNSPEC_MOVE_TF_PS 200)
60 ;; MIPS64/MIPS32R2 alnv.ps
63 ;; MIPS-3D instructions
67 (UNSPEC_CVT_PW_PS 205)
68 (UNSPEC_CVT_PS_PW 206)
76 ;; MIPS DSP ASE Revision 0.98 3/24/2005
84 (UNSPEC_RADDU_W_QB 307)
86 (UNSPEC_PRECRQ_QB_PH 309)
87 (UNSPEC_PRECRQ_PH_W 310)
88 (UNSPEC_PRECRQ_RS_PH_W 311)
89 (UNSPEC_PRECRQU_S_QB_PH 312)
90 (UNSPEC_PRECEQ_W_PHL 313)
91 (UNSPEC_PRECEQ_W_PHR 314)
92 (UNSPEC_PRECEQU_PH_QBL 315)
93 (UNSPEC_PRECEQU_PH_QBR 316)
94 (UNSPEC_PRECEQU_PH_QBLA 317)
95 (UNSPEC_PRECEQU_PH_QBRA 318)
96 (UNSPEC_PRECEU_PH_QBL 319)
97 (UNSPEC_PRECEU_PH_QBR 320)
98 (UNSPEC_PRECEU_PH_QBLA 321)
99 (UNSPEC_PRECEU_PH_QBRA 322)
105 (UNSPEC_MULEU_S_PH_QBL 328)
106 (UNSPEC_MULEU_S_PH_QBR 329)
107 (UNSPEC_MULQ_RS_PH 330)
108 (UNSPEC_MULEQ_S_W_PHL 331)
109 (UNSPEC_MULEQ_S_W_PHR 332)
110 (UNSPEC_DPAU_H_QBL 333)
111 (UNSPEC_DPAU_H_QBR 334)
112 (UNSPEC_DPSU_H_QBL 335)
113 (UNSPEC_DPSU_H_QBR 336)
114 (UNSPEC_DPAQ_S_W_PH 337)
115 (UNSPEC_DPSQ_S_W_PH 338)
116 (UNSPEC_MULSAQ_S_W_PH 339)
117 (UNSPEC_DPAQ_SA_L_W 340)
118 (UNSPEC_DPSQ_SA_L_W 341)
119 (UNSPEC_MAQ_S_W_PHL 342)
120 (UNSPEC_MAQ_S_W_PHR 343)
121 (UNSPEC_MAQ_SA_W_PHL 344)
122 (UNSPEC_MAQ_SA_W_PHR 345)
130 (UNSPEC_CMPGU_EQ_QB 353)
131 (UNSPEC_CMPGU_LT_QB 354)
132 (UNSPEC_CMPGU_LE_QB 355)
134 (UNSPEC_PACKRL_PH 357)
136 (UNSPEC_EXTR_R_W 359)
137 (UNSPEC_EXTR_RS_W 360)
138 (UNSPEC_EXTR_S_H 361)
148 (include "predicates.md")
149 (include "constraints.md")
151 ;; ....................
155 ;; ....................
157 (define_attr "got" "unset,xgot_high,load"
158 (const_string "unset"))
160 ;; For jal instructions, this attribute is DIRECT when the target address
161 ;; is symbolic and INDIRECT when it is a register.
162 (define_attr "jal" "unset,direct,indirect"
163 (const_string "unset"))
165 ;; This attribute is YES if the instruction is a jal macro (not a
166 ;; real jal instruction).
168 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
169 ;; restore $gp. Direct jals are also macros in NewABI PIC since they
170 ;; load the target address into $25.
171 (define_attr "jal_macro" "no,yes"
172 (cond [(eq_attr "jal" "direct")
173 (symbol_ref "TARGET_ABICALLS != 0")
174 (eq_attr "jal" "indirect")
175 (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
176 (const_string "no")))
178 ;; Classification of each insn.
179 ;; branch conditional branch
180 ;; jump unconditional jump
181 ;; call unconditional call
182 ;; load load instruction(s)
183 ;; fpload floating point load
184 ;; fpidxload floating point indexed load
185 ;; store store instruction(s)
186 ;; fpstore floating point store
187 ;; fpidxstore floating point indexed store
188 ;; prefetch memory prefetch (register + offset)
189 ;; prefetchx memory indexed prefetch (register + register)
190 ;; condmove conditional moves
191 ;; xfer transfer to/from coprocessor
192 ;; mthilo transfer to hi/lo registers
193 ;; mfhilo transfer from hi/lo registers
194 ;; const load constant
195 ;; arith integer arithmetic and logical instructions
196 ;; shift integer shift instructions
197 ;; slt set less than instructions
198 ;; clz the clz and clo instructions
199 ;; trap trap if instructions
200 ;; imul integer multiply 2 operands
201 ;; imul3 integer multiply 3 operands
202 ;; imadd integer multiply-add
203 ;; idiv integer divide
204 ;; fmove floating point register move
205 ;; fadd floating point add/subtract
206 ;; fmul floating point multiply
207 ;; fmadd floating point multiply-add
208 ;; fdiv floating point divide
209 ;; frdiv floating point reciprocal divide
210 ;; frdiv1 floating point reciprocal divide step 1
211 ;; frdiv2 floating point reciprocal divide step 2
212 ;; fabs floating point absolute value
213 ;; fneg floating point negation
214 ;; fcmp floating point compare
215 ;; fcvt floating point convert
216 ;; fsqrt floating point square root
217 ;; frsqrt floating point reciprocal square root
218 ;; frsqrt1 floating point reciprocal square root step1
219 ;; frsqrt2 floating point reciprocal square root step2
220 ;; multi multiword sequence (or user asm statements)
223 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imul3,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,multi,nop"
224 (cond [(eq_attr "jal" "!unset") (const_string "call")
225 (eq_attr "got" "load") (const_string "load")]
226 (const_string "unknown")))
228 ;; Main data type used by the insn
229 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
230 (const_string "unknown"))
232 ;; Mode for conversion types (fcvt)
233 ;; I2S integer to float single (SI/DI to SF)
234 ;; I2D integer to float double (SI/DI to DF)
235 ;; S2I float to integer (SF to SI/DI)
236 ;; D2I float to integer (DF to SI/DI)
237 ;; D2S double to float single
238 ;; S2D float single to double
240 (define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D"
241 (const_string "unknown"))
243 ;; Is this an extended instruction in mips16 mode?
244 (define_attr "extended_mips16" "no,yes"
247 ;; Length of instruction in bytes.
248 (define_attr "length" ""
249 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
250 ;; If a branch is outside this range, we have a choice of two
251 ;; sequences. For PIC, an out-of-range branch like:
256 ;; becomes the equivalent of:
265 ;; where the load address can be up to three instructions long
268 ;; The non-PIC case is similar except that we use a direct
269 ;; jump instead of an la/jr pair. Since the target of this
270 ;; jump is an absolute 28-bit bit address (the other bits
271 ;; coming from the address of the delay slot) this form cannot
272 ;; cross a 256MB boundary. We could provide the option of
273 ;; using la/jr in this case too, but we do not do so at
276 ;; Note that this value does not account for the delay slot
277 ;; instruction, whose length is added separately. If the RTL
278 ;; pattern has no explicit delay slot, mips_adjust_insn_length
279 ;; will add the length of the implicit nop. The values for
280 ;; forward and backward branches will be different as well.
281 (eq_attr "type" "branch")
282 (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
283 (le (minus (pc) (match_dup 1)) (const_int 131068)))
285 (ne (symbol_ref "flag_pic") (const_int 0))
289 (eq_attr "got" "load")
291 (eq_attr "got" "xgot_high")
294 (eq_attr "type" "const")
295 (symbol_ref "mips_const_insns (operands[1]) * 4")
296 (eq_attr "type" "load,fpload")
297 (symbol_ref "mips_fetch_insns (operands[1]) * 4")
298 (eq_attr "type" "store,fpstore")
299 (symbol_ref "mips_fetch_insns (operands[0]) * 4")
301 ;; In the worst case, a call macro will take 8 instructions:
303 ;; lui $25,%call_hi(FOO)
305 ;; lw $25,%call_lo(FOO)($25)
311 (eq_attr "jal_macro" "yes")
314 (and (eq_attr "extended_mips16" "yes")
315 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
318 ;; Various VR4120 errata require a nop to be inserted after a macc
319 ;; instruction. The assembler does this for us, so account for
320 ;; the worst-case length here.
321 (and (eq_attr "type" "imadd")
322 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
325 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
326 ;; the result of the second one is missed. The assembler should work
327 ;; around this by inserting a nop after the first dmult.
328 (and (eq_attr "type" "imul,imul3")
329 (and (eq_attr "mode" "DI")
330 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
333 (eq_attr "type" "idiv")
334 (symbol_ref "mips_idiv_insns () * 4")
337 ;; Attribute describing the processor. This attribute must match exactly
338 ;; with the processor_type enumeration in mips.h.
340 "r3000,4kc,4kp,5kc,5kf,20kc,24k,24kx,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
341 (const (symbol_ref "mips_tune")))
343 ;; The type of hardware hazard associated with this instruction.
344 ;; DELAY means that the next instruction cannot read the result
345 ;; of this one. HILO means that the next two instructions cannot
346 ;; write to HI or LO.
347 (define_attr "hazard" "none,delay,hilo"
348 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
349 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
350 (const_string "delay")
352 (and (eq_attr "type" "xfer")
353 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
354 (const_string "delay")
356 (and (eq_attr "type" "fcmp")
357 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
358 (const_string "delay")
360 ;; The r4000 multiplication patterns include an mflo instruction.
361 (and (eq_attr "type" "imul")
362 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
363 (const_string "hilo")
365 (and (eq_attr "type" "mfhilo")
366 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
367 (const_string "hilo")]
368 (const_string "none")))
370 ;; Is it a single instruction?
371 (define_attr "single_insn" "no,yes"
372 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
374 ;; Can the instruction be put into a delay slot?
375 (define_attr "can_delay" "no,yes"
376 (if_then_else (and (eq_attr "type" "!branch,call,jump")
377 (and (eq_attr "hazard" "none")
378 (eq_attr "single_insn" "yes")))
380 (const_string "no")))
382 ;; Attribute defining whether or not we can use the branch-likely instructions
383 (define_attr "branch_likely" "no,yes"
385 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
387 (const_string "no"))))
389 ;; True if an instruction might assign to hi or lo when reloaded.
390 ;; This is used by the TUNE_MACC_CHAINS code.
391 (define_attr "may_clobber_hilo" "no,yes"
392 (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthilo")
394 (const_string "no")))
396 ;; Describe a user's asm statement.
397 (define_asm_attributes
398 [(set_attr "type" "multi")
399 (set_attr "can_delay" "no")])
401 ;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
402 ;; from the same template.
403 (define_mode_macro GPR [SI (DI "TARGET_64BIT")])
405 ;; This mode macro allows :P to be used for patterns that operate on
406 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
407 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
409 ;; This mode macro allows :MOVECC to be used anywhere that a
410 ;; conditional-move-type condition is needed.
411 (define_mode_macro MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
413 ;; This mode macro allows the QI and HI extension patterns to be defined from
414 ;; the same template.
415 (define_mode_macro SHORT [QI HI])
417 ;; This mode macro allows :ANYF to be used wherever a scalar or vector
418 ;; floating-point mode is allowed.
419 (define_mode_macro ANYF [(SF "TARGET_HARD_FLOAT")
420 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
421 (V2SF "TARGET_PAIRED_SINGLE_FLOAT")])
423 ;; Like ANYF, but only applies to scalar modes.
424 (define_mode_macro SCALARF [(SF "TARGET_HARD_FLOAT")
425 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
427 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
428 ;; 32-bit version and "dsubu" in the 64-bit version.
429 (define_mode_attr d [(SI "") (DI "d")])
431 ;; This attribute gives the length suffix for a sign- or zero-extension
433 (define_mode_attr size [(QI "b") (HI "h")])
435 ;; This attributes gives the mode mask of a SHORT.
436 (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
438 ;; Mode attributes for GPR loads and stores.
439 (define_mode_attr load [(SI "lw") (DI "ld")])
440 (define_mode_attr store [(SI "sw") (DI "sd")])
442 ;; Similarly for MIPS IV indexed FPR loads and stores.
443 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
444 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
446 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
447 ;; are different. Some forms of unextended addiu have an 8-bit immediate
448 ;; field but the equivalent daddiu has only a 5-bit field.
449 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
451 ;; This attribute gives the best constraint to use for registers of
453 (define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
455 ;; This attribute gives the format suffix for floating-point operations.
456 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
458 ;; This attribute gives the upper-case mode name for one unit of a
459 ;; floating-point mode.
460 (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
462 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
464 ;; In certain cases, div.s and div.ps may have a rounding error
465 ;; and/or wrong inexact flag.
467 ;; Therefore, we only allow div.s if not working around SB-1 rev2
468 ;; errata or if a slight loss of precision is OK.
469 (define_mode_attr divide_condition
470 [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")
471 (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")])
473 ; This attribute gives the condition for which sqrt instructions exist.
474 (define_mode_attr sqrt_condition
475 [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")])
477 ; This attribute gives the condition for which recip and rsqrt instructions
479 (define_mode_attr recip_condition
480 [(SF "ISA_HAS_FP4") (DF "ISA_HAS_FP4") (V2SF "TARGET_SB1")])
482 ;; This code macro allows all branch instructions to be generated from
483 ;; a single define_expand template.
484 (define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
485 eq ne gt ge lt le gtu geu ltu leu])
487 ;; This code macro allows signed and unsigned widening multiplications
488 ;; to use the same template.
489 (define_code_macro any_extend [sign_extend zero_extend])
491 ;; This code macro allows the three shift instructions to be generated
492 ;; from the same template.
493 (define_code_macro any_shift [ashift ashiftrt lshiftrt])
495 ;; This code macro allows all native floating-point comparisons to be
496 ;; generated from the same template.
497 (define_code_macro fcond [unordered uneq unlt unle eq lt le])
499 ;; This code macro is used for comparisons that can be implemented
500 ;; by swapping the operands.
501 (define_code_macro swapped_fcond [ge gt unge ungt])
503 ;; <u> expands to an empty string when doing a signed operation and
504 ;; "u" when doing an unsigned operation.
505 (define_code_attr u [(sign_extend "") (zero_extend "u")])
507 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
508 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
510 ;; <optab> expands to the name of the optab for a particular code.
511 (define_code_attr optab [(ashift "ashl")
515 ;; <insn> expands to the name of the insn that implements a particular code.
516 (define_code_attr insn [(ashift "sll")
520 ;; <fcond> is the c.cond.fmt condition associated with a particular code.
521 (define_code_attr fcond [(unordered "un")
529 ;; Similar, but for swapped conditions.
530 (define_code_attr swapped_fcond [(ge "le")
535 ;; .........................
537 ;; Branch, call and jump delay slots
539 ;; .........................
541 (define_delay (and (eq_attr "type" "branch")
542 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
543 [(eq_attr "can_delay" "yes")
545 (and (eq_attr "branch_likely" "yes")
546 (eq_attr "can_delay" "yes"))])
548 (define_delay (eq_attr "type" "jump")
549 [(eq_attr "can_delay" "yes")
553 (define_delay (and (eq_attr "type" "call")
554 (eq_attr "jal_macro" "no"))
555 [(eq_attr "can_delay" "yes")
559 ;; Pipeline descriptions.
561 ;; generic.md provides a fallback for processors without a specific
562 ;; pipeline description. It is derived from the old define_function_unit
563 ;; version and uses the "alu" and "imuldiv" units declared below.
565 ;; Some of the processor-specific files are also derived from old
566 ;; define_function_unit descriptions and simply override the parts of
567 ;; generic.md that don't apply. The other processor-specific files
568 ;; are self-contained.
569 (define_automaton "alu,imuldiv")
571 (define_cpu_unit "alu" "alu")
572 (define_cpu_unit "imuldiv" "imuldiv")
591 (include "generic.md")
594 ;; ....................
598 ;; ....................
602 [(trap_if (const_int 1) (const_int 0))]
605 if (ISA_HAS_COND_TRAP)
607 else if (TARGET_MIPS16)
612 [(set_attr "type" "trap")])
614 (define_expand "conditional_trap"
615 [(trap_if (match_operator 0 "comparison_operator"
616 [(match_dup 2) (match_dup 3)])
617 (match_operand 1 "const_int_operand"))]
620 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
621 && operands[1] == const0_rtx)
623 mips_gen_conditional_trap (operands);
630 (define_insn "*conditional_trap<mode>"
631 [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
632 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
633 (match_operand:GPR 2 "arith_operand" "dI")])
637 [(set_attr "type" "trap")])
640 ;; ....................
644 ;; ....................
647 (define_insn "add<mode>3"
648 [(set (match_operand:ANYF 0 "register_operand" "=f")
649 (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
650 (match_operand:ANYF 2 "register_operand" "f")))]
652 "add.<fmt>\t%0,%1,%2"
653 [(set_attr "type" "fadd")
654 (set_attr "mode" "<UNITMODE>")])
656 (define_expand "add<mode>3"
657 [(set (match_operand:GPR 0 "register_operand")
658 (plus:GPR (match_operand:GPR 1 "register_operand")
659 (match_operand:GPR 2 "arith_operand")))]
662 (define_insn "*add<mode>3"
663 [(set (match_operand:GPR 0 "register_operand" "=d,d")
664 (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
665 (match_operand:GPR 2 "arith_operand" "d,Q")))]
670 [(set_attr "type" "arith")
671 (set_attr "mode" "<MODE>")])
673 ;; We need to recognize MIPS16 stack pointer additions explicitly, since
674 ;; we don't have a constraint for $sp. These insns will be generated by
675 ;; the save_restore_insns functions.
677 (define_insn "*add<mode>3_sp1"
679 (plus:GPR (reg:GPR 29)
680 (match_operand:GPR 0 "const_arith_operand" "")))]
683 [(set_attr "type" "arith")
684 (set_attr "mode" "<MODE>")
685 (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
689 (define_insn "*add<mode>3_sp2"
690 [(set (match_operand:GPR 0 "register_operand" "=d")
691 (plus:GPR (reg:GPR 29)
692 (match_operand:GPR 1 "const_arith_operand" "")))]
695 [(set_attr "type" "arith")
696 (set_attr "mode" "<MODE>")
697 (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
701 (define_insn "*add<mode>3_mips16"
702 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
703 (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
704 (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
710 [(set_attr "type" "arith")
711 (set_attr "mode" "<MODE>")
712 (set_attr_alternative "length"
713 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
716 (if_then_else (match_operand 2 "m16_simm4_1")
722 ;; On the mips16, we can sometimes split an add of a constant which is
723 ;; a 4 byte instruction into two adds which are both 2 byte
724 ;; instructions. There are two cases: one where we are adding a
725 ;; constant plus a register to another register, and one where we are
726 ;; simply adding a constant to a register.
729 [(set (match_operand:SI 0 "register_operand")
730 (plus:SI (match_dup 0)
731 (match_operand:SI 1 "const_int_operand")))]
732 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
733 && REG_P (operands[0])
734 && M16_REG_P (REGNO (operands[0]))
735 && GET_CODE (operands[1]) == CONST_INT
736 && ((INTVAL (operands[1]) > 0x7f
737 && INTVAL (operands[1]) <= 0x7f + 0x7f)
738 || (INTVAL (operands[1]) < - 0x80
739 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
740 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
741 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
743 HOST_WIDE_INT val = INTVAL (operands[1]);
747 operands[1] = GEN_INT (0x7f);
748 operands[2] = GEN_INT (val - 0x7f);
752 operands[1] = GEN_INT (- 0x80);
753 operands[2] = GEN_INT (val + 0x80);
758 [(set (match_operand:SI 0 "register_operand")
759 (plus:SI (match_operand:SI 1 "register_operand")
760 (match_operand:SI 2 "const_int_operand")))]
761 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
762 && REG_P (operands[0])
763 && M16_REG_P (REGNO (operands[0]))
764 && REG_P (operands[1])
765 && M16_REG_P (REGNO (operands[1]))
766 && REGNO (operands[0]) != REGNO (operands[1])
767 && GET_CODE (operands[2]) == CONST_INT
768 && ((INTVAL (operands[2]) > 0x7
769 && INTVAL (operands[2]) <= 0x7 + 0x7f)
770 || (INTVAL (operands[2]) < - 0x8
771 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
772 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
773 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
775 HOST_WIDE_INT val = INTVAL (operands[2]);
779 operands[2] = GEN_INT (0x7);
780 operands[3] = GEN_INT (val - 0x7);
784 operands[2] = GEN_INT (- 0x8);
785 operands[3] = GEN_INT (val + 0x8);
790 [(set (match_operand:DI 0 "register_operand")
791 (plus:DI (match_dup 0)
792 (match_operand:DI 1 "const_int_operand")))]
793 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
794 && REG_P (operands[0])
795 && M16_REG_P (REGNO (operands[0]))
796 && GET_CODE (operands[1]) == CONST_INT
797 && ((INTVAL (operands[1]) > 0xf
798 && INTVAL (operands[1]) <= 0xf + 0xf)
799 || (INTVAL (operands[1]) < - 0x10
800 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
801 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
802 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
804 HOST_WIDE_INT val = INTVAL (operands[1]);
808 operands[1] = GEN_INT (0xf);
809 operands[2] = GEN_INT (val - 0xf);
813 operands[1] = GEN_INT (- 0x10);
814 operands[2] = GEN_INT (val + 0x10);
819 [(set (match_operand:DI 0 "register_operand")
820 (plus:DI (match_operand:DI 1 "register_operand")
821 (match_operand:DI 2 "const_int_operand")))]
822 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
823 && REG_P (operands[0])
824 && M16_REG_P (REGNO (operands[0]))
825 && REG_P (operands[1])
826 && M16_REG_P (REGNO (operands[1]))
827 && REGNO (operands[0]) != REGNO (operands[1])
828 && GET_CODE (operands[2]) == CONST_INT
829 && ((INTVAL (operands[2]) > 0x7
830 && INTVAL (operands[2]) <= 0x7 + 0xf)
831 || (INTVAL (operands[2]) < - 0x8
832 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
833 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
834 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
836 HOST_WIDE_INT val = INTVAL (operands[2]);
840 operands[2] = GEN_INT (0x7);
841 operands[3] = GEN_INT (val - 0x7);
845 operands[2] = GEN_INT (- 0x8);
846 operands[3] = GEN_INT (val + 0x8);
850 (define_insn "*addsi3_extended"
851 [(set (match_operand:DI 0 "register_operand" "=d,d")
853 (plus:SI (match_operand:SI 1 "register_operand" "d,d")
854 (match_operand:SI 2 "arith_operand" "d,Q"))))]
855 "TARGET_64BIT && !TARGET_MIPS16"
859 [(set_attr "type" "arith")
860 (set_attr "mode" "SI")])
862 ;; Split this insn so that the addiu splitters can have a crack at it.
863 ;; Use a conservative length estimate until the split.
864 (define_insn_and_split "*addsi3_extended_mips16"
865 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
867 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
868 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
869 "TARGET_64BIT && TARGET_MIPS16"
871 "&& reload_completed"
872 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
873 { operands[3] = gen_lowpart (SImode, operands[0]); }
874 [(set_attr "type" "arith")
875 (set_attr "mode" "SI")
876 (set_attr "extended_mips16" "yes")])
879 ;; ....................
883 ;; ....................
886 (define_insn "sub<mode>3"
887 [(set (match_operand:ANYF 0 "register_operand" "=f")
888 (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
889 (match_operand:ANYF 2 "register_operand" "f")))]
891 "sub.<fmt>\t%0,%1,%2"
892 [(set_attr "type" "fadd")
893 (set_attr "mode" "<UNITMODE>")])
895 (define_insn "sub<mode>3"
896 [(set (match_operand:GPR 0 "register_operand" "=d")
897 (minus:GPR (match_operand:GPR 1 "register_operand" "d")
898 (match_operand:GPR 2 "register_operand" "d")))]
901 [(set_attr "type" "arith")
902 (set_attr "mode" "<MODE>")])
904 (define_insn "*subsi3_extended"
905 [(set (match_operand:DI 0 "register_operand" "=d")
907 (minus:SI (match_operand:SI 1 "register_operand" "d")
908 (match_operand:SI 2 "register_operand" "d"))))]
911 [(set_attr "type" "arith")
912 (set_attr "mode" "DI")])
915 ;; ....................
919 ;; ....................
922 (define_expand "mul<mode>3"
923 [(set (match_operand:SCALARF 0 "register_operand")
924 (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
925 (match_operand:SCALARF 2 "register_operand")))]
929 (define_insn "*mul<mode>3"
930 [(set (match_operand:SCALARF 0 "register_operand" "=f")
931 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
932 (match_operand:SCALARF 2 "register_operand" "f")))]
933 "!TARGET_4300_MUL_FIX"
934 "mul.<fmt>\t%0,%1,%2"
935 [(set_attr "type" "fmul")
936 (set_attr "mode" "<MODE>")])
938 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
939 ;; operands may corrupt immediately following multiplies. This is a
940 ;; simple fix to insert NOPs.
942 (define_insn "*mul<mode>3_r4300"
943 [(set (match_operand:SCALARF 0 "register_operand" "=f")
944 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
945 (match_operand:SCALARF 2 "register_operand" "f")))]
946 "TARGET_4300_MUL_FIX"
947 "mul.<fmt>\t%0,%1,%2\;nop"
948 [(set_attr "type" "fmul")
949 (set_attr "mode" "<MODE>")
950 (set_attr "length" "8")])
952 (define_insn "mulv2sf3"
953 [(set (match_operand:V2SF 0 "register_operand" "=f")
954 (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
955 (match_operand:V2SF 2 "register_operand" "f")))]
956 "TARGET_PAIRED_SINGLE_FLOAT"
958 [(set_attr "type" "fmul")
959 (set_attr "mode" "SF")])
961 ;; The original R4000 has a cpu bug. If a double-word or a variable
962 ;; shift executes while an integer multiplication is in progress, the
963 ;; shift may give an incorrect result. Avoid this by keeping the mflo
964 ;; with the mult on the R4000.
966 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
967 ;; (also valid for MIPS R4000MC processors):
969 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
970 ;; this errata description.
971 ;; The following code sequence causes the R4000 to incorrectly
972 ;; execute the Double Shift Right Arithmetic 32 (dsra32)
973 ;; instruction. If the dsra32 instruction is executed during an
974 ;; integer multiply, the dsra32 will only shift by the amount in
975 ;; specified in the instruction rather than the amount plus 32
977 ;; instruction 1: mult rs,rt integer multiply
978 ;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
979 ;; right arithmetic + 32
980 ;; Workaround: A dsra32 instruction placed after an integer
981 ;; multiply should not be one of the 11 instructions after the
982 ;; multiply instruction."
986 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
987 ;; the following description.
988 ;; All extended shifts (shift by n+32) and variable shifts (32 and
989 ;; 64-bit versions) may produce incorrect results under the
990 ;; following conditions:
991 ;; 1) An integer multiply is currently executing
992 ;; 2) These types of shift instructions are executed immediately
993 ;; following an integer divide instruction.
995 ;; 1) Make sure no integer multiply is running wihen these
996 ;; instruction are executed. If this cannot be predicted at
997 ;; compile time, then insert a "mfhi" to R0 instruction
998 ;; immediately after the integer multiply instruction. This
999 ;; will cause the integer multiply to complete before the shift
1001 ;; 2) Separate integer divide and these two classes of shift
1002 ;; instructions by another instruction or a noop."
1004 ;; These processors have PRId values of 0x00004220 and 0x00004300,
1007 (define_expand "mul<mode>3"
1008 [(set (match_operand:GPR 0 "register_operand")
1009 (mult:GPR (match_operand:GPR 1 "register_operand")
1010 (match_operand:GPR 2 "register_operand")))]
1013 if (GENERATE_MULT3_<MODE>)
1014 emit_insn (gen_mul<mode>3_mult3 (operands[0], operands[1], operands[2]));
1015 else if (!TARGET_FIX_R4000)
1016 emit_insn (gen_mul<mode>3_internal (operands[0], operands[1],
1019 emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
1023 (define_insn "mulsi3_mult3"
1024 [(set (match_operand:SI 0 "register_operand" "=d,l")
1025 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1026 (match_operand:SI 2 "register_operand" "d,d")))
1027 (clobber (match_scratch:SI 3 "=h,h"))
1028 (clobber (match_scratch:SI 4 "=l,X"))]
1031 if (which_alternative == 1)
1032 return "mult\t%1,%2";
1041 return "mul\t%0,%1,%2";
1042 return "mult\t%0,%1,%2";
1044 [(set_attr "type" "imul3,imul")
1045 (set_attr "mode" "SI")])
1047 (define_insn "muldi3_mult3"
1048 [(set (match_operand:DI 0 "register_operand" "=d")
1049 (mult:DI (match_operand:DI 1 "register_operand" "d")
1050 (match_operand:DI 2 "register_operand" "d")))
1051 (clobber (match_scratch:DI 3 "=h"))
1052 (clobber (match_scratch:DI 4 "=l"))]
1053 "TARGET_64BIT && GENERATE_MULT3_DI"
1055 [(set_attr "type" "imul3")
1056 (set_attr "mode" "DI")])
1058 ;; If a register gets allocated to LO, and we spill to memory, the reload
1059 ;; will include a move from LO to a GPR. Merge it into the multiplication
1060 ;; if it can set the GPR directly.
1063 ;; Operand 1: GPR (1st multiplication operand)
1064 ;; Operand 2: GPR (2nd multiplication operand)
1066 ;; Operand 4: GPR (destination)
1069 [(set (match_operand:SI 0 "register_operand")
1070 (mult:SI (match_operand:SI 1 "register_operand")
1071 (match_operand:SI 2 "register_operand")))
1072 (clobber (match_operand:SI 3 "register_operand"))
1073 (clobber (scratch:SI))])
1074 (set (match_operand:SI 4 "register_operand")
1075 (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1076 "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
1079 (mult:SI (match_dup 1)
1081 (clobber (match_dup 3))
1082 (clobber (match_dup 0))])])
1084 (define_insn "mul<mode>3_internal"
1085 [(set (match_operand:GPR 0 "register_operand" "=l")
1086 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1087 (match_operand:GPR 2 "register_operand" "d")))
1088 (clobber (match_scratch:GPR 3 "=h"))]
1091 [(set_attr "type" "imul")
1092 (set_attr "mode" "<MODE>")])
1094 (define_insn "mul<mode>3_r4000"
1095 [(set (match_operand:GPR 0 "register_operand" "=d")
1096 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1097 (match_operand:GPR 2 "register_operand" "d")))
1098 (clobber (match_scratch:GPR 3 "=h"))
1099 (clobber (match_scratch:GPR 4 "=l"))]
1101 "<d>mult\t%1,%2\;mflo\t%0"
1102 [(set_attr "type" "imul")
1103 (set_attr "mode" "<MODE>")
1104 (set_attr "length" "8")])
1106 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1107 ;; of "mult; mflo". They have the same latency, but the first form gives
1108 ;; us an extra cycle to compute the operands.
1111 ;; Operand 1: GPR (1st multiplication operand)
1112 ;; Operand 2: GPR (2nd multiplication operand)
1114 ;; Operand 4: GPR (destination)
1117 [(set (match_operand:SI 0 "register_operand")
1118 (mult:SI (match_operand:SI 1 "register_operand")
1119 (match_operand:SI 2 "register_operand")))
1120 (clobber (match_operand:SI 3 "register_operand"))])
1121 (set (match_operand:SI 4 "register_operand")
1122 (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1123 "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1128 (plus:SI (mult:SI (match_dup 1)
1132 (plus:SI (mult:SI (match_dup 1)
1135 (clobber (match_dup 3))])])
1137 ;; Multiply-accumulate patterns
1139 ;; For processors that can copy the output to a general register:
1141 ;; The all-d alternative is needed because the combiner will find this
1142 ;; pattern and then register alloc/reload will move registers around to
1143 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1145 ;; The last alternative should be made slightly less desirable, but adding
1146 ;; "?" to the constraint is too strong, and causes values to be loaded into
1147 ;; LO even when that's more costly. For now, using "*d" mostly does the
1149 (define_insn "*mul_acc_si"
1150 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1151 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1152 (match_operand:SI 2 "register_operand" "d,d,d"))
1153 (match_operand:SI 3 "register_operand" "0,l,*d")))
1154 (clobber (match_scratch:SI 4 "=h,h,h"))
1155 (clobber (match_scratch:SI 5 "=X,3,l"))
1156 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1158 || ISA_HAS_MADD_MSUB)
1161 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1162 if (which_alternative == 2)
1164 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1166 return madd[which_alternative];
1168 [(set_attr "type" "imadd,imadd,multi")
1169 (set_attr "mode" "SI")
1170 (set_attr "length" "4,4,8")])
1172 ;; Split the above insn if we failed to get LO allocated.
1174 [(set (match_operand:SI 0 "register_operand")
1175 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1176 (match_operand:SI 2 "register_operand"))
1177 (match_operand:SI 3 "register_operand")))
1178 (clobber (match_scratch:SI 4))
1179 (clobber (match_scratch:SI 5))
1180 (clobber (match_scratch:SI 6))]
1181 "reload_completed && !TARGET_DEBUG_D_MODE
1182 && GP_REG_P (true_regnum (operands[0]))
1183 && GP_REG_P (true_regnum (operands[3]))"
1184 [(parallel [(set (match_dup 6)
1185 (mult:SI (match_dup 1) (match_dup 2)))
1186 (clobber (match_dup 4))
1187 (clobber (match_dup 5))])
1188 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1191 ;; Splitter to copy result of MADD to a general register
1193 [(set (match_operand:SI 0 "register_operand")
1194 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1195 (match_operand:SI 2 "register_operand"))
1196 (match_operand:SI 3 "register_operand")))
1197 (clobber (match_scratch:SI 4))
1198 (clobber (match_scratch:SI 5))
1199 (clobber (match_scratch:SI 6))]
1200 "reload_completed && !TARGET_DEBUG_D_MODE
1201 && GP_REG_P (true_regnum (operands[0]))
1202 && true_regnum (operands[3]) == LO_REGNUM"
1203 [(parallel [(set (match_dup 3)
1204 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1206 (clobber (match_dup 4))
1207 (clobber (match_dup 5))
1208 (clobber (match_dup 6))])
1209 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1212 (define_insn "*macc"
1213 [(set (match_operand:SI 0 "register_operand" "=l,d")
1214 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1215 (match_operand:SI 2 "register_operand" "d,d"))
1216 (match_operand:SI 3 "register_operand" "0,l")))
1217 (clobber (match_scratch:SI 4 "=h,h"))
1218 (clobber (match_scratch:SI 5 "=X,3"))]
1221 if (which_alternative == 1)
1222 return "macc\t%0,%1,%2";
1223 else if (TARGET_MIPS5500)
1224 return "madd\t%1,%2";
1226 /* The VR4130 assumes that there is a two-cycle latency between a macc
1227 that "writes" to $0 and an instruction that reads from it. We avoid
1228 this by assigning to $1 instead. */
1229 return "%[macc\t%@,%1,%2%]";
1231 [(set_attr "type" "imadd")
1232 (set_attr "mode" "SI")])
1234 (define_insn "*msac"
1235 [(set (match_operand:SI 0 "register_operand" "=l,d")
1236 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1237 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1238 (match_operand:SI 3 "register_operand" "d,d"))))
1239 (clobber (match_scratch:SI 4 "=h,h"))
1240 (clobber (match_scratch:SI 5 "=X,1"))]
1243 if (which_alternative == 1)
1244 return "msac\t%0,%2,%3";
1245 else if (TARGET_MIPS5500)
1246 return "msub\t%2,%3";
1248 return "msac\t$0,%2,%3";
1250 [(set_attr "type" "imadd")
1251 (set_attr "mode" "SI")])
1253 ;; An msac-like instruction implemented using negation and a macc.
1254 (define_insn_and_split "*msac_using_macc"
1255 [(set (match_operand:SI 0 "register_operand" "=l,d")
1256 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1257 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1258 (match_operand:SI 3 "register_operand" "d,d"))))
1259 (clobber (match_scratch:SI 4 "=h,h"))
1260 (clobber (match_scratch:SI 5 "=X,1"))
1261 (clobber (match_scratch:SI 6 "=d,d"))]
1262 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1264 "&& reload_completed"
1266 (neg:SI (match_dup 3)))
1269 (plus:SI (mult:SI (match_dup 2)
1272 (clobber (match_dup 4))
1273 (clobber (match_dup 5))])]
1275 [(set_attr "type" "imadd")
1276 (set_attr "length" "8")])
1278 ;; Patterns generated by the define_peephole2 below.
1280 (define_insn "*macc2"
1281 [(set (match_operand:SI 0 "register_operand" "=l")
1282 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1283 (match_operand:SI 2 "register_operand" "d"))
1285 (set (match_operand:SI 3 "register_operand" "=d")
1286 (plus:SI (mult:SI (match_dup 1)
1289 (clobber (match_scratch:SI 4 "=h"))]
1290 "ISA_HAS_MACC && reload_completed"
1292 [(set_attr "type" "imadd")
1293 (set_attr "mode" "SI")])
1295 (define_insn "*msac2"
1296 [(set (match_operand:SI 0 "register_operand" "=l")
1297 (minus:SI (match_dup 0)
1298 (mult:SI (match_operand:SI 1 "register_operand" "d")
1299 (match_operand:SI 2 "register_operand" "d"))))
1300 (set (match_operand:SI 3 "register_operand" "=d")
1301 (minus:SI (match_dup 0)
1302 (mult:SI (match_dup 1)
1304 (clobber (match_scratch:SI 4 "=h"))]
1305 "ISA_HAS_MSAC && reload_completed"
1307 [(set_attr "type" "imadd")
1308 (set_attr "mode" "SI")])
1310 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1314 ;; Operand 1: macc/msac
1316 ;; Operand 3: GPR (destination)
1319 [(set (match_operand:SI 0 "register_operand")
1320 (match_operand:SI 1 "macc_msac_operand"))
1321 (clobber (match_operand:SI 2 "register_operand"))
1322 (clobber (scratch:SI))])
1323 (set (match_operand:SI 3 "register_operand")
1324 (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1326 [(parallel [(set (match_dup 0)
1330 (clobber (match_dup 2))])]
1333 ;; When we have a three-address multiplication instruction, it should
1334 ;; be faster to do a separate multiply and add, rather than moving
1335 ;; something into LO in order to use a macc instruction.
1337 ;; This peephole needs a scratch register to cater for the case when one
1338 ;; of the multiplication operands is the same as the destination.
1340 ;; Operand 0: GPR (scratch)
1342 ;; Operand 2: GPR (addend)
1343 ;; Operand 3: GPR (destination)
1344 ;; Operand 4: macc/msac
1346 ;; Operand 6: new multiplication
1347 ;; Operand 7: new addition/subtraction
1349 [(match_scratch:SI 0 "d")
1350 (set (match_operand:SI 1 "register_operand")
1351 (match_operand:SI 2 "register_operand"))
1354 [(set (match_operand:SI 3 "register_operand")
1355 (match_operand:SI 4 "macc_msac_operand"))
1356 (clobber (match_operand:SI 5 "register_operand"))
1357 (clobber (match_dup 1))])]
1359 && true_regnum (operands[1]) == LO_REGNUM
1360 && peep2_reg_dead_p (2, operands[1])
1361 && GP_REG_P (true_regnum (operands[3]))"
1362 [(parallel [(set (match_dup 0)
1364 (clobber (match_dup 5))
1365 (clobber (match_dup 1))])
1369 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1370 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1371 operands[2], operands[0]);
1374 ;; Same as above, except LO is the initial target of the macc.
1376 ;; Operand 0: GPR (scratch)
1378 ;; Operand 2: GPR (addend)
1379 ;; Operand 3: macc/msac
1381 ;; Operand 5: GPR (destination)
1382 ;; Operand 6: new multiplication
1383 ;; Operand 7: new addition/subtraction
1385 [(match_scratch:SI 0 "d")
1386 (set (match_operand:SI 1 "register_operand")
1387 (match_operand:SI 2 "register_operand"))
1391 (match_operand:SI 3 "macc_msac_operand"))
1392 (clobber (match_operand:SI 4 "register_operand"))
1393 (clobber (scratch:SI))])
1395 (set (match_operand:SI 5 "register_operand")
1396 (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1397 "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1398 [(parallel [(set (match_dup 0)
1400 (clobber (match_dup 4))
1401 (clobber (match_dup 1))])
1405 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1406 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1407 operands[2], operands[0]);
1410 (define_insn "*mul_sub_si"
1411 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1412 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1413 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1414 (match_operand:SI 3 "register_operand" "d,d,d"))))
1415 (clobber (match_scratch:SI 4 "=h,h,h"))
1416 (clobber (match_scratch:SI 5 "=X,1,l"))
1417 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1423 [(set_attr "type" "imadd,multi,multi")
1424 (set_attr "mode" "SI")
1425 (set_attr "length" "4,8,8")])
1427 ;; Split the above insn if we failed to get LO allocated.
1429 [(set (match_operand:SI 0 "register_operand")
1430 (minus:SI (match_operand:SI 1 "register_operand")
1431 (mult:SI (match_operand:SI 2 "register_operand")
1432 (match_operand:SI 3 "register_operand"))))
1433 (clobber (match_scratch:SI 4))
1434 (clobber (match_scratch:SI 5))
1435 (clobber (match_scratch:SI 6))]
1436 "reload_completed && !TARGET_DEBUG_D_MODE
1437 && GP_REG_P (true_regnum (operands[0]))
1438 && GP_REG_P (true_regnum (operands[1]))"
1439 [(parallel [(set (match_dup 6)
1440 (mult:SI (match_dup 2) (match_dup 3)))
1441 (clobber (match_dup 4))
1442 (clobber (match_dup 5))])
1443 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1446 ;; Splitter to copy result of MSUB to a general register
1448 [(set (match_operand:SI 0 "register_operand")
1449 (minus:SI (match_operand:SI 1 "register_operand")
1450 (mult:SI (match_operand:SI 2 "register_operand")
1451 (match_operand:SI 3 "register_operand"))))
1452 (clobber (match_scratch:SI 4))
1453 (clobber (match_scratch:SI 5))
1454 (clobber (match_scratch:SI 6))]
1455 "reload_completed && !TARGET_DEBUG_D_MODE
1456 && GP_REG_P (true_regnum (operands[0]))
1457 && true_regnum (operands[1]) == LO_REGNUM"
1458 [(parallel [(set (match_dup 1)
1459 (minus:SI (match_dup 1)
1460 (mult:SI (match_dup 2) (match_dup 3))))
1461 (clobber (match_dup 4))
1462 (clobber (match_dup 5))
1463 (clobber (match_dup 6))])
1464 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1467 (define_insn "*muls"
1468 [(set (match_operand:SI 0 "register_operand" "=l,d")
1469 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1470 (match_operand:SI 2 "register_operand" "d,d"))))
1471 (clobber (match_scratch:SI 3 "=h,h"))
1472 (clobber (match_scratch:SI 4 "=X,l"))]
1477 [(set_attr "type" "imul,imul3")
1478 (set_attr "mode" "SI")])
1480 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1482 (define_expand "<u>mulsidi3"
1484 [(set (match_operand:DI 0 "register_operand")
1485 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1486 (any_extend:DI (match_operand:SI 2 "register_operand"))))
1487 (clobber (scratch:DI))
1488 (clobber (scratch:DI))
1489 (clobber (scratch:DI))])]
1490 "!TARGET_64BIT || !TARGET_FIX_R4000"
1494 if (!TARGET_FIX_R4000)
1495 emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1498 emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1504 (define_insn "<u>mulsidi3_32bit_internal"
1505 [(set (match_operand:DI 0 "register_operand" "=x")
1506 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1507 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1508 "!TARGET_64BIT && !TARGET_FIX_R4000"
1510 [(set_attr "type" "imul")
1511 (set_attr "mode" "SI")])
1513 (define_insn "<u>mulsidi3_32bit_r4000"
1514 [(set (match_operand:DI 0 "register_operand" "=d")
1515 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1516 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1517 (clobber (match_scratch:DI 3 "=x"))]
1518 "!TARGET_64BIT && TARGET_FIX_R4000"
1519 "mult<u>\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1520 [(set_attr "type" "imul")
1521 (set_attr "mode" "SI")
1522 (set_attr "length" "12")])
1524 (define_insn_and_split "*<u>mulsidi3_64bit"
1525 [(set (match_operand:DI 0 "register_operand" "=d")
1526 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1527 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1528 (clobber (match_scratch:DI 3 "=l"))
1529 (clobber (match_scratch:DI 4 "=h"))
1530 (clobber (match_scratch:DI 5 "=d"))]
1531 "TARGET_64BIT && !TARGET_FIX_R4000"
1533 "&& reload_completed"
1537 (mult:SI (match_dup 1)
1541 (mult:DI (any_extend:DI (match_dup 1))
1542 (any_extend:DI (match_dup 2)))
1545 ;; OP5 <- LO, OP0 <- HI
1546 (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1547 (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1551 (ashift:DI (match_dup 5)
1554 (lshiftrt:DI (match_dup 5)
1557 ;; Shift OP0 into place.
1559 (ashift:DI (match_dup 0)
1562 ;; OR the two halves together
1564 (ior:DI (match_dup 0)
1567 [(set_attr "type" "imul")
1568 (set_attr "mode" "SI")
1569 (set_attr "length" "24")])
1571 (define_insn "*<u>mulsidi3_64bit_parts"
1572 [(set (match_operand:DI 0 "register_operand" "=l")
1574 (mult:SI (match_operand:SI 2 "register_operand" "d")
1575 (match_operand:SI 3 "register_operand" "d"))))
1576 (set (match_operand:DI 1 "register_operand" "=h")
1578 (mult:DI (any_extend:DI (match_dup 2))
1579 (any_extend:DI (match_dup 3)))
1581 "TARGET_64BIT && !TARGET_FIX_R4000"
1583 [(set_attr "type" "imul")
1584 (set_attr "mode" "SI")])
1586 ;; Widening multiply with negation.
1587 (define_insn "*muls<u>_di"
1588 [(set (match_operand:DI 0 "register_operand" "=x")
1591 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1592 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1593 "!TARGET_64BIT && ISA_HAS_MULS"
1595 [(set_attr "type" "imul")
1596 (set_attr "mode" "SI")])
1598 (define_insn "*msac<u>_di"
1599 [(set (match_operand:DI 0 "register_operand" "=x")
1601 (match_operand:DI 3 "register_operand" "0")
1603 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1604 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1605 "!TARGET_64BIT && ISA_HAS_MSAC"
1607 if (TARGET_MIPS5500)
1608 return "msub<u>\t%1,%2";
1610 return "msac<u>\t$0,%1,%2";
1612 [(set_attr "type" "imadd")
1613 (set_attr "mode" "SI")])
1615 ;; _highpart patterns
1617 (define_expand "<su>mulsi3_highpart"
1618 [(set (match_operand:SI 0 "register_operand")
1621 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1622 (any_extend:DI (match_operand:SI 2 "register_operand")))
1624 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1627 emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1631 emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1636 (define_insn "<su>mulsi3_highpart_internal"
1637 [(set (match_operand:SI 0 "register_operand" "=h")
1640 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1641 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1643 (clobber (match_scratch:SI 3 "=l"))]
1644 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1646 [(set_attr "type" "imul")
1647 (set_attr "mode" "SI")])
1649 (define_insn "<su>mulsi3_highpart_mulhi_internal"
1650 [(set (match_operand:SI 0 "register_operand" "=h,d")
1654 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1655 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1657 (clobber (match_scratch:SI 3 "=l,l"))
1658 (clobber (match_scratch:SI 4 "=X,h"))]
1663 [(set_attr "type" "imul,imul3")
1664 (set_attr "mode" "SI")])
1666 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1667 [(set (match_operand:SI 0 "register_operand" "=h,d")
1672 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1673 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1675 (clobber (match_scratch:SI 3 "=l,l"))
1676 (clobber (match_scratch:SI 4 "=X,h"))]
1680 mulshi<u>\t%0,%1,%2"
1681 [(set_attr "type" "imul,imul3")
1682 (set_attr "mode" "SI")])
1684 ;; Disable unsigned multiplication for -mfix-vr4120. This is for VR4120
1685 ;; errata MD(0), which says that dmultu does not always produce the
1687 (define_insn "<su>muldi3_highpart"
1688 [(set (match_operand:DI 0 "register_operand" "=h")
1692 (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1693 (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1695 (clobber (match_scratch:DI 3 "=l"))]
1696 "TARGET_64BIT && !TARGET_FIX_R4000
1697 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1699 [(set_attr "type" "imul")
1700 (set_attr "mode" "DI")])
1702 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1703 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
1705 (define_insn "madsi"
1706 [(set (match_operand:SI 0 "register_operand" "+l")
1707 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1708 (match_operand:SI 2 "register_operand" "d"))
1710 (clobber (match_scratch:SI 3 "=h"))]
1713 [(set_attr "type" "imadd")
1714 (set_attr "mode" "SI")])
1716 (define_insn "*<su>mul_acc_di"
1717 [(set (match_operand:DI 0 "register_operand" "=x")
1719 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1720 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1721 (match_operand:DI 3 "register_operand" "0")))]
1722 "(TARGET_MAD || ISA_HAS_MACC)
1726 return "mad<u>\t%1,%2";
1727 else if (TARGET_MIPS5500)
1728 return "madd<u>\t%1,%2";
1730 /* See comment in *macc. */
1731 return "%[macc<u>\t%@,%1,%2%]";
1733 [(set_attr "type" "imadd")
1734 (set_attr "mode" "SI")])
1736 ;; Floating point multiply accumulate instructions.
1738 (define_insn "*madd<mode>"
1739 [(set (match_operand:ANYF 0 "register_operand" "=f")
1740 (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1741 (match_operand:ANYF 2 "register_operand" "f"))
1742 (match_operand:ANYF 3 "register_operand" "f")))]
1743 "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1744 "madd.<fmt>\t%0,%3,%1,%2"
1745 [(set_attr "type" "fmadd")
1746 (set_attr "mode" "<UNITMODE>")])
1748 (define_insn "*msub<mode>"
1749 [(set (match_operand:ANYF 0 "register_operand" "=f")
1750 (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1751 (match_operand:ANYF 2 "register_operand" "f"))
1752 (match_operand:ANYF 3 "register_operand" "f")))]
1753 "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1754 "msub.<fmt>\t%0,%3,%1,%2"
1755 [(set_attr "type" "fmadd")
1756 (set_attr "mode" "<UNITMODE>")])
1758 (define_insn "*nmadd<mode>"
1759 [(set (match_operand:ANYF 0 "register_operand" "=f")
1760 (neg:ANYF (plus:ANYF
1761 (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1762 (match_operand:ANYF 2 "register_operand" "f"))
1763 (match_operand:ANYF 3 "register_operand" "f"))))]
1764 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1765 && HONOR_SIGNED_ZEROS (<MODE>mode)"
1766 "nmadd.<fmt>\t%0,%3,%1,%2"
1767 [(set_attr "type" "fmadd")
1768 (set_attr "mode" "<UNITMODE>")])
1770 (define_insn "*nmadd<mode>_fastmath"
1771 [(set (match_operand:ANYF 0 "register_operand" "=f")
1773 (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
1774 (match_operand:ANYF 2 "register_operand" "f"))
1775 (match_operand:ANYF 3 "register_operand" "f")))]
1776 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1777 && !HONOR_SIGNED_ZEROS (<MODE>mode)"
1778 "nmadd.<fmt>\t%0,%3,%1,%2"
1779 [(set_attr "type" "fmadd")
1780 (set_attr "mode" "<UNITMODE>")])
1782 (define_insn "*nmsub<mode>"
1783 [(set (match_operand:ANYF 0 "register_operand" "=f")
1784 (neg:ANYF (minus:ANYF
1785 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1786 (match_operand:ANYF 3 "register_operand" "f"))
1787 (match_operand:ANYF 1 "register_operand" "f"))))]
1788 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1789 && HONOR_SIGNED_ZEROS (<MODE>mode)"
1790 "nmsub.<fmt>\t%0,%1,%2,%3"
1791 [(set_attr "type" "fmadd")
1792 (set_attr "mode" "<UNITMODE>")])
1794 (define_insn "*nmsub<mode>_fastmath"
1795 [(set (match_operand:ANYF 0 "register_operand" "=f")
1797 (match_operand:ANYF 1 "register_operand" "f")
1798 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1799 (match_operand:ANYF 3 "register_operand" "f"))))]
1800 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1801 && !HONOR_SIGNED_ZEROS (<MODE>mode)"
1802 "nmsub.<fmt>\t%0,%1,%2,%3"
1803 [(set_attr "type" "fmadd")
1804 (set_attr "mode" "<UNITMODE>")])
1807 ;; ....................
1809 ;; DIVISION and REMAINDER
1811 ;; ....................
1814 (define_expand "div<mode>3"
1815 [(set (match_operand:ANYF 0 "register_operand")
1816 (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
1817 (match_operand:ANYF 2 "register_operand")))]
1818 "<divide_condition>"
1820 if (const_1_operand (operands[1], <MODE>mode))
1821 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1822 operands[1] = force_reg (<MODE>mode, operands[1]);
1825 ;; These patterns work around the early SB-1 rev2 core "F1" erratum:
1827 ;; If an mfc1 or dmfc1 happens to access the floating point register
1828 ;; file at the same time a long latency operation (div, sqrt, recip,
1829 ;; sqrt) iterates an intermediate result back through the floating
1830 ;; point register file bypass, then instead returning the correct
1831 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1832 ;; result of the long latency operation.
1834 ;; The workaround is to insert an unconditional 'mov' from/to the
1835 ;; long latency op destination register.
1837 (define_insn "*div<mode>3"
1838 [(set (match_operand:ANYF 0 "register_operand" "=f")
1839 (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
1840 (match_operand:ANYF 2 "register_operand" "f")))]
1841 "<divide_condition>"
1844 return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
1846 return "div.<fmt>\t%0,%1,%2";
1848 [(set_attr "type" "fdiv")
1849 (set_attr "mode" "<UNITMODE>")
1850 (set (attr "length")
1851 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1855 (define_insn "*recip<mode>3"
1856 [(set (match_operand:ANYF 0 "register_operand" "=f")
1857 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1858 (match_operand:ANYF 2 "register_operand" "f")))]
1859 "<recip_condition> && flag_unsafe_math_optimizations"
1862 return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1864 return "recip.<fmt>\t%0,%2";
1866 [(set_attr "type" "frdiv")
1867 (set_attr "mode" "<UNITMODE>")
1868 (set (attr "length")
1869 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1873 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
1874 ;; with negative operands. We use special libgcc functions instead.
1875 (define_insn "divmod<mode>4"
1876 [(set (match_operand:GPR 0 "register_operand" "=l")
1877 (div:GPR (match_operand:GPR 1 "register_operand" "d")
1878 (match_operand:GPR 2 "register_operand" "d")))
1879 (set (match_operand:GPR 3 "register_operand" "=h")
1880 (mod:GPR (match_dup 1)
1882 "!TARGET_FIX_VR4120"
1883 { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1884 [(set_attr "type" "idiv")
1885 (set_attr "mode" "<MODE>")])
1887 (define_insn "udivmod<mode>4"
1888 [(set (match_operand:GPR 0 "register_operand" "=l")
1889 (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1890 (match_operand:GPR 2 "register_operand" "d")))
1891 (set (match_operand:GPR 3 "register_operand" "=h")
1892 (umod:GPR (match_dup 1)
1895 { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1896 [(set_attr "type" "idiv")
1897 (set_attr "mode" "<MODE>")])
1900 ;; ....................
1904 ;; ....................
1906 ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
1907 ;; "*div[sd]f3" comment for details).
1909 (define_insn "sqrt<mode>2"
1910 [(set (match_operand:ANYF 0 "register_operand" "=f")
1911 (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1915 return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
1917 return "sqrt.<fmt>\t%0,%1";
1919 [(set_attr "type" "fsqrt")
1920 (set_attr "mode" "<UNITMODE>")
1921 (set (attr "length")
1922 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1926 (define_insn "*rsqrt<mode>a"
1927 [(set (match_operand:ANYF 0 "register_operand" "=f")
1928 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1929 (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
1930 "<recip_condition> && flag_unsafe_math_optimizations"
1933 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1935 return "rsqrt.<fmt>\t%0,%2";
1937 [(set_attr "type" "frsqrt")
1938 (set_attr "mode" "<UNITMODE>")
1939 (set (attr "length")
1940 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1944 (define_insn "*rsqrt<mode>b"
1945 [(set (match_operand:ANYF 0 "register_operand" "=f")
1946 (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1947 (match_operand:ANYF 2 "register_operand" "f"))))]
1948 "<recip_condition> && flag_unsafe_math_optimizations"
1951 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1953 return "rsqrt.<fmt>\t%0,%2";
1955 [(set_attr "type" "frsqrt")
1956 (set_attr "mode" "<UNITMODE>")
1957 (set (attr "length")
1958 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1963 ;; ....................
1967 ;; ....................
1969 ;; Do not use the integer abs macro instruction, since that signals an
1970 ;; exception on -2147483648 (sigh).
1972 (define_insn "abs<mode>2"
1973 [(set (match_operand:ANYF 0 "register_operand" "=f")
1974 (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1977 [(set_attr "type" "fabs")
1978 (set_attr "mode" "<UNITMODE>")])
1981 ;; ...................
1983 ;; Count leading zeroes.
1985 ;; ...................
1988 (define_insn "clz<mode>2"
1989 [(set (match_operand:GPR 0 "register_operand" "=d")
1990 (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
1993 [(set_attr "type" "clz")
1994 (set_attr "mode" "<MODE>")])
1997 ;; ....................
1999 ;; NEGATION and ONE'S COMPLEMENT
2001 ;; ....................
2003 (define_insn "negsi2"
2004 [(set (match_operand:SI 0 "register_operand" "=d")
2005 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2009 return "neg\t%0,%1";
2011 return "subu\t%0,%.,%1";
2013 [(set_attr "type" "arith")
2014 (set_attr "mode" "SI")])
2016 (define_insn "negdi2"
2017 [(set (match_operand:DI 0 "register_operand" "=d")
2018 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2019 "TARGET_64BIT && !TARGET_MIPS16"
2021 [(set_attr "type" "arith")
2022 (set_attr "mode" "DI")])
2024 (define_insn "neg<mode>2"
2025 [(set (match_operand:ANYF 0 "register_operand" "=f")
2026 (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2029 [(set_attr "type" "fneg")
2030 (set_attr "mode" "<UNITMODE>")])
2032 (define_insn "one_cmpl<mode>2"
2033 [(set (match_operand:GPR 0 "register_operand" "=d")
2034 (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2038 return "not\t%0,%1";
2040 return "nor\t%0,%.,%1";
2042 [(set_attr "type" "arith")
2043 (set_attr "mode" "<MODE>")])
2046 ;; ....................
2050 ;; ....................
2053 ;; Many of these instructions use trivial define_expands, because we
2054 ;; want to use a different set of constraints when TARGET_MIPS16.
2056 (define_expand "and<mode>3"
2057 [(set (match_operand:GPR 0 "register_operand")
2058 (and:GPR (match_operand:GPR 1 "register_operand")
2059 (match_operand:GPR 2 "uns_arith_operand")))]
2063 operands[2] = force_reg (<MODE>mode, operands[2]);
2066 (define_insn "*and<mode>3"
2067 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2068 (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2069 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2074 [(set_attr "type" "arith")
2075 (set_attr "mode" "<MODE>")])
2077 (define_insn "*and<mode>3_mips16"
2078 [(set (match_operand:GPR 0 "register_operand" "=d")
2079 (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2080 (match_operand:GPR 2 "register_operand" "d")))]
2083 [(set_attr "type" "arith")
2084 (set_attr "mode" "<MODE>")])
2086 (define_expand "ior<mode>3"
2087 [(set (match_operand:GPR 0 "register_operand")
2088 (ior:GPR (match_operand:GPR 1 "register_operand")
2089 (match_operand:GPR 2 "uns_arith_operand")))]
2093 operands[2] = force_reg (<MODE>mode, operands[2]);
2096 (define_insn "*ior<mode>3"
2097 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2098 (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2099 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2104 [(set_attr "type" "arith")
2105 (set_attr "mode" "<MODE>")])
2107 (define_insn "*ior<mode>3_mips16"
2108 [(set (match_operand:GPR 0 "register_operand" "=d")
2109 (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2110 (match_operand:GPR 2 "register_operand" "d")))]
2113 [(set_attr "type" "arith")
2114 (set_attr "mode" "<MODE>")])
2116 (define_expand "xor<mode>3"
2117 [(set (match_operand:GPR 0 "register_operand")
2118 (xor:GPR (match_operand:GPR 1 "register_operand")
2119 (match_operand:GPR 2 "uns_arith_operand")))]
2124 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2125 (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2126 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2131 [(set_attr "type" "arith")
2132 (set_attr "mode" "<MODE>")])
2135 [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2136 (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2137 (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2143 [(set_attr "type" "arith")
2144 (set_attr "mode" "<MODE>")
2145 (set_attr_alternative "length"
2147 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2152 (define_insn "*nor<mode>3"
2153 [(set (match_operand:GPR 0 "register_operand" "=d")
2154 (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2155 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2158 [(set_attr "type" "arith")
2159 (set_attr "mode" "<MODE>")])
2162 ;; ....................
2166 ;; ....................
2170 (define_insn "truncdfsf2"
2171 [(set (match_operand:SF 0 "register_operand" "=f")
2172 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2173 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2175 [(set_attr "type" "fcvt")
2176 (set_attr "cnv_mode" "D2S")
2177 (set_attr "mode" "SF")])
2179 ;; Integer truncation patterns. Truncating SImode values to smaller
2180 ;; modes is a no-op, as it is for most other GCC ports. Truncating
2181 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2182 ;; need to make sure that the lower 32 bits are properly sign-extended
2183 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
2184 ;; smaller than SImode is equivalent to two separate truncations:
2187 ;; DI ---> HI == DI ---> SI ---> HI
2188 ;; DI ---> QI == DI ---> SI ---> QI
2190 ;; Step A needs a real instruction but step B does not.
2192 (define_insn "truncdisi2"
2193 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2194 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2199 [(set_attr "type" "shift,store")
2200 (set_attr "mode" "SI")
2201 (set_attr "extended_mips16" "yes,*")])
2203 (define_insn "truncdihi2"
2204 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2205 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2210 [(set_attr "type" "shift,store")
2211 (set_attr "mode" "SI")
2212 (set_attr "extended_mips16" "yes,*")])
2214 (define_insn "truncdiqi2"
2215 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2216 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2221 [(set_attr "type" "shift,store")
2222 (set_attr "mode" "SI")
2223 (set_attr "extended_mips16" "yes,*")])
2225 ;; Combiner patterns to optimize shift/truncate combinations.
2228 [(set (match_operand:SI 0 "register_operand" "=d")
2230 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2231 (match_operand:DI 2 "const_arith_operand" ""))))]
2232 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2234 [(set_attr "type" "shift")
2235 (set_attr "mode" "SI")])
2238 [(set (match_operand:SI 0 "register_operand" "=d")
2239 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2241 "TARGET_64BIT && !TARGET_MIPS16"
2243 [(set_attr "type" "shift")
2244 (set_attr "mode" "SI")])
2247 ;; Combiner patterns for truncate/sign_extend combinations. They use
2248 ;; the shift/truncate patterns above.
2250 (define_insn_and_split ""
2251 [(set (match_operand:SI 0 "register_operand" "=d")
2253 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2254 "TARGET_64BIT && !TARGET_MIPS16"
2256 "&& reload_completed"
2258 (ashift:DI (match_dup 1)
2261 (truncate:SI (ashiftrt:DI (match_dup 2)
2263 { operands[2] = gen_lowpart (DImode, operands[0]); })
2265 (define_insn_and_split ""
2266 [(set (match_operand:SI 0 "register_operand" "=d")
2268 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2269 "TARGET_64BIT && !TARGET_MIPS16"
2271 "&& reload_completed"
2273 (ashift:DI (match_dup 1)
2276 (truncate:SI (ashiftrt:DI (match_dup 2)
2278 { operands[2] = gen_lowpart (DImode, operands[0]); })
2281 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2284 [(set (match_operand:SI 0 "register_operand" "=d")
2285 (zero_extend:SI (truncate:HI
2286 (match_operand:DI 1 "register_operand" "d"))))]
2287 "TARGET_64BIT && !TARGET_MIPS16"
2288 "andi\t%0,%1,0xffff"
2289 [(set_attr "type" "arith")
2290 (set_attr "mode" "SI")])
2293 [(set (match_operand:SI 0 "register_operand" "=d")
2294 (zero_extend:SI (truncate:QI
2295 (match_operand:DI 1 "register_operand" "d"))))]
2296 "TARGET_64BIT && !TARGET_MIPS16"
2298 [(set_attr "type" "arith")
2299 (set_attr "mode" "SI")])
2302 [(set (match_operand:HI 0 "register_operand" "=d")
2303 (zero_extend:HI (truncate:QI
2304 (match_operand:DI 1 "register_operand" "d"))))]
2305 "TARGET_64BIT && !TARGET_MIPS16"
2307 [(set_attr "type" "arith")
2308 (set_attr "mode" "HI")])
2311 ;; ....................
2315 ;; ....................
2319 (define_insn_and_split "zero_extendsidi2"
2320 [(set (match_operand:DI 0 "register_operand" "=d,d")
2321 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
2326 "&& reload_completed && REG_P (operands[1])"
2328 (ashift:DI (match_dup 1) (const_int 32)))
2330 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2331 { operands[1] = gen_lowpart (DImode, operands[1]); }
2332 [(set_attr "type" "multi,load")
2333 (set_attr "mode" "DI")
2334 (set_attr "length" "8,*")])
2336 ;; Combine is not allowed to convert this insn into a zero_extendsidi2
2337 ;; because of TRULY_NOOP_TRUNCATION.
2339 (define_insn_and_split "*clear_upper32"
2340 [(set (match_operand:DI 0 "register_operand" "=d,d")
2341 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
2342 (const_int 4294967295)))]
2345 if (which_alternative == 0)
2348 operands[1] = gen_lowpart (SImode, operands[1]);
2349 return "lwu\t%0,%1";
2351 "&& reload_completed && REG_P (operands[1])"
2353 (ashift:DI (match_dup 1) (const_int 32)))
2355 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2357 [(set_attr "type" "multi,load")
2358 (set_attr "mode" "DI")
2359 (set_attr "length" "8,*")])
2361 (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
2362 [(set (match_operand:GPR 0 "register_operand")
2363 (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2366 if (TARGET_MIPS16 && !GENERATE_MIPS16E
2367 && !memory_operand (operands[1], <SHORT:MODE>mode))
2369 emit_insn (gen_and<GPR:mode>3 (operands[0],
2370 gen_lowpart (<GPR:MODE>mode, operands[1]),
2371 force_reg (<GPR:MODE>mode,
2372 GEN_INT (<SHORT:mask>))));
2377 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
2378 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2380 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2383 andi\t%0,%1,<SHORT:mask>
2384 l<SHORT:size>u\t%0,%1"
2385 [(set_attr "type" "arith,load")
2386 (set_attr "mode" "<GPR:MODE>")])
2388 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e"
2389 [(set (match_operand:GPR 0 "register_operand" "=d")
2390 (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
2392 "ze<SHORT:size>\t%0"
2393 [(set_attr "type" "arith")
2394 (set_attr "mode" "<GPR:MODE>")])
2396 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16"
2397 [(set (match_operand:GPR 0 "register_operand" "=d")
2398 (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
2400 "l<SHORT:size>u\t%0,%1"
2401 [(set_attr "type" "load")
2402 (set_attr "mode" "<GPR:MODE>")])
2404 (define_expand "zero_extendqihi2"
2405 [(set (match_operand:HI 0 "register_operand")
2406 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2409 if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
2411 emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
2417 (define_insn "*zero_extendqihi2"
2418 [(set (match_operand:HI 0 "register_operand" "=d,d")
2419 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2424 [(set_attr "type" "arith,load")
2425 (set_attr "mode" "HI")])
2427 (define_insn "*zero_extendqihi2_mips16"
2428 [(set (match_operand:HI 0 "register_operand" "=d")
2429 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2432 [(set_attr "type" "load")
2433 (set_attr "mode" "HI")])
2436 ;; ....................
2440 ;; ....................
2443 ;; Those for integer source operand are ordered widest source type first.
2445 ;; When TARGET_64BIT, all SImode integer registers should already be in
2446 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
2447 ;; therefore get rid of register->register instructions if we constrain
2448 ;; the source to be in the same register as the destination.
2450 ;; The register alternative has type "arith" so that the pre-reload
2451 ;; scheduler will treat it as a move. This reflects what happens if
2452 ;; the register alternative needs a reload.
2453 (define_insn_and_split "extendsidi2"
2454 [(set (match_operand:DI 0 "register_operand" "=d,d")
2455 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2460 "&& reload_completed && register_operand (operands[1], VOIDmode)"
2463 emit_note (NOTE_INSN_DELETED);
2466 [(set_attr "type" "arith,load")
2467 (set_attr "mode" "DI")])
2469 (define_expand "extend<SHORT:mode><GPR:mode>2"
2470 [(set (match_operand:GPR 0 "register_operand")
2471 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2474 (define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e"
2475 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2476 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
2480 l<SHORT:size>\t%0,%1"
2481 [(set_attr "type" "arith,load")
2482 (set_attr "mode" "<GPR:MODE>")])
2484 (define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
2485 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2487 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2488 "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2491 l<SHORT:size>\t%0,%1"
2492 "&& reload_completed && REG_P (operands[1])"
2493 [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
2494 (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
2496 operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
2497 operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
2498 - GET_MODE_BITSIZE (<SHORT:MODE>mode));
2500 [(set_attr "type" "arith,load")
2501 (set_attr "mode" "<GPR:MODE>")
2502 (set_attr "length" "8,*")])
2504 (define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
2505 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2507 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2510 se<SHORT:size>\t%0,%1
2511 l<SHORT:size>\t%0,%1"
2512 [(set_attr "type" "arith,load")
2513 (set_attr "mode" "<GPR:MODE>")])
2515 ;; This pattern generates the same code as extendqisi2; split it into
2516 ;; that form after reload.
2517 (define_insn_and_split "extendqihi2"
2518 [(set (match_operand:HI 0 "register_operand" "=d,d")
2519 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2523 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
2524 { operands[0] = gen_lowpart (SImode, operands[0]); }
2525 [(set_attr "type" "arith,load")
2526 (set_attr "mode" "SI")
2527 (set_attr "length" "8,*")])
2529 (define_insn "extendsfdf2"
2530 [(set (match_operand:DF 0 "register_operand" "=f")
2531 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2532 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2534 [(set_attr "type" "fcvt")
2535 (set_attr "cnv_mode" "S2D")
2536 (set_attr "mode" "DF")])
2539 ;; ....................
2543 ;; ....................
2545 (define_expand "fix_truncdfsi2"
2546 [(set (match_operand:SI 0 "register_operand")
2547 (fix:SI (match_operand:DF 1 "register_operand")))]
2548 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2550 if (!ISA_HAS_TRUNC_W)
2552 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2557 (define_insn "fix_truncdfsi2_insn"
2558 [(set (match_operand:SI 0 "register_operand" "=f")
2559 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2560 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2562 [(set_attr "type" "fcvt")
2563 (set_attr "mode" "DF")
2564 (set_attr "cnv_mode" "D2I")
2565 (set_attr "length" "4")])
2567 (define_insn "fix_truncdfsi2_macro"
2568 [(set (match_operand:SI 0 "register_operand" "=f")
2569 (fix:SI (match_operand:DF 1 "register_operand" "f")))
2570 (clobber (match_scratch:DF 2 "=d"))]
2571 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2574 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2576 return "trunc.w.d %0,%1,%2";
2578 [(set_attr "type" "fcvt")
2579 (set_attr "mode" "DF")
2580 (set_attr "cnv_mode" "D2I")
2581 (set_attr "length" "36")])
2583 (define_expand "fix_truncsfsi2"
2584 [(set (match_operand:SI 0 "register_operand")
2585 (fix:SI (match_operand:SF 1 "register_operand")))]
2588 if (!ISA_HAS_TRUNC_W)
2590 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2595 (define_insn "fix_truncsfsi2_insn"
2596 [(set (match_operand:SI 0 "register_operand" "=f")
2597 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2598 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2600 [(set_attr "type" "fcvt")
2601 (set_attr "mode" "SF")
2602 (set_attr "cnv_mode" "S2I")
2603 (set_attr "length" "4")])
2605 (define_insn "fix_truncsfsi2_macro"
2606 [(set (match_operand:SI 0 "register_operand" "=f")
2607 (fix:SI (match_operand:SF 1 "register_operand" "f")))
2608 (clobber (match_scratch:SF 2 "=d"))]
2609 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2612 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2614 return "trunc.w.s %0,%1,%2";
2616 [(set_attr "type" "fcvt")
2617 (set_attr "mode" "SF")
2618 (set_attr "cnv_mode" "S2I")
2619 (set_attr "length" "36")])
2622 (define_insn "fix_truncdfdi2"
2623 [(set (match_operand:DI 0 "register_operand" "=f")
2624 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2625 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2627 [(set_attr "type" "fcvt")
2628 (set_attr "mode" "DF")
2629 (set_attr "cnv_mode" "D2I")
2630 (set_attr "length" "4")])
2633 (define_insn "fix_truncsfdi2"
2634 [(set (match_operand:DI 0 "register_operand" "=f")
2635 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2636 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2638 [(set_attr "type" "fcvt")
2639 (set_attr "mode" "SF")
2640 (set_attr "cnv_mode" "S2I")
2641 (set_attr "length" "4")])
2644 (define_insn "floatsidf2"
2645 [(set (match_operand:DF 0 "register_operand" "=f")
2646 (float:DF (match_operand:SI 1 "register_operand" "f")))]
2647 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2649 [(set_attr "type" "fcvt")
2650 (set_attr "mode" "DF")
2651 (set_attr "cnv_mode" "I2D")
2652 (set_attr "length" "4")])
2655 (define_insn "floatdidf2"
2656 [(set (match_operand:DF 0 "register_operand" "=f")
2657 (float:DF (match_operand:DI 1 "register_operand" "f")))]
2658 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2660 [(set_attr "type" "fcvt")
2661 (set_attr "mode" "DF")
2662 (set_attr "cnv_mode" "I2D")
2663 (set_attr "length" "4")])
2666 (define_insn "floatsisf2"
2667 [(set (match_operand:SF 0 "register_operand" "=f")
2668 (float:SF (match_operand:SI 1 "register_operand" "f")))]
2671 [(set_attr "type" "fcvt")
2672 (set_attr "mode" "SF")
2673 (set_attr "cnv_mode" "I2S")
2674 (set_attr "length" "4")])
2677 (define_insn "floatdisf2"
2678 [(set (match_operand:SF 0 "register_operand" "=f")
2679 (float:SF (match_operand:DI 1 "register_operand" "f")))]
2680 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2682 [(set_attr "type" "fcvt")
2683 (set_attr "mode" "SF")
2684 (set_attr "cnv_mode" "I2S")
2685 (set_attr "length" "4")])
2688 (define_expand "fixuns_truncdfsi2"
2689 [(set (match_operand:SI 0 "register_operand")
2690 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2691 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2693 rtx reg1 = gen_reg_rtx (DFmode);
2694 rtx reg2 = gen_reg_rtx (DFmode);
2695 rtx reg3 = gen_reg_rtx (SImode);
2696 rtx label1 = gen_label_rtx ();
2697 rtx label2 = gen_label_rtx ();
2698 REAL_VALUE_TYPE offset;
2700 real_2expN (&offset, 31);
2702 if (reg1) /* Turn off complaints about unreached code. */
2704 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2705 do_pending_stack_adjust ();
2707 emit_insn (gen_cmpdf (operands[1], reg1));
2708 emit_jump_insn (gen_bge (label1));
2710 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2711 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2712 gen_rtx_LABEL_REF (VOIDmode, label2)));
2715 emit_label (label1);
2716 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2717 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2718 (BITMASK_HIGH, SImode)));
2720 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2721 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2723 emit_label (label2);
2725 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2726 fields, and can't be used for REG_NOTES anyway). */
2727 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2733 (define_expand "fixuns_truncdfdi2"
2734 [(set (match_operand:DI 0 "register_operand")
2735 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
2736 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2738 rtx reg1 = gen_reg_rtx (DFmode);
2739 rtx reg2 = gen_reg_rtx (DFmode);
2740 rtx reg3 = gen_reg_rtx (DImode);
2741 rtx label1 = gen_label_rtx ();
2742 rtx label2 = gen_label_rtx ();
2743 REAL_VALUE_TYPE offset;
2745 real_2expN (&offset, 63);
2747 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2748 do_pending_stack_adjust ();
2750 emit_insn (gen_cmpdf (operands[1], reg1));
2751 emit_jump_insn (gen_bge (label1));
2753 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2754 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2755 gen_rtx_LABEL_REF (VOIDmode, label2)));
2758 emit_label (label1);
2759 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2760 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2761 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2763 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2764 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2766 emit_label (label2);
2768 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2769 fields, and can't be used for REG_NOTES anyway). */
2770 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2775 (define_expand "fixuns_truncsfsi2"
2776 [(set (match_operand:SI 0 "register_operand")
2777 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
2780 rtx reg1 = gen_reg_rtx (SFmode);
2781 rtx reg2 = gen_reg_rtx (SFmode);
2782 rtx reg3 = gen_reg_rtx (SImode);
2783 rtx label1 = gen_label_rtx ();
2784 rtx label2 = gen_label_rtx ();
2785 REAL_VALUE_TYPE offset;
2787 real_2expN (&offset, 31);
2789 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2790 do_pending_stack_adjust ();
2792 emit_insn (gen_cmpsf (operands[1], reg1));
2793 emit_jump_insn (gen_bge (label1));
2795 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2796 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2797 gen_rtx_LABEL_REF (VOIDmode, label2)));
2800 emit_label (label1);
2801 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2802 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2803 (BITMASK_HIGH, SImode)));
2805 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2806 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2808 emit_label (label2);
2810 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2811 fields, and can't be used for REG_NOTES anyway). */
2812 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2817 (define_expand "fixuns_truncsfdi2"
2818 [(set (match_operand:DI 0 "register_operand")
2819 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
2820 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2822 rtx reg1 = gen_reg_rtx (SFmode);
2823 rtx reg2 = gen_reg_rtx (SFmode);
2824 rtx reg3 = gen_reg_rtx (DImode);
2825 rtx label1 = gen_label_rtx ();
2826 rtx label2 = gen_label_rtx ();
2827 REAL_VALUE_TYPE offset;
2829 real_2expN (&offset, 63);
2831 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2832 do_pending_stack_adjust ();
2834 emit_insn (gen_cmpsf (operands[1], reg1));
2835 emit_jump_insn (gen_bge (label1));
2837 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
2838 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2839 gen_rtx_LABEL_REF (VOIDmode, label2)));
2842 emit_label (label1);
2843 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2844 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2845 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2847 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
2848 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2850 emit_label (label2);
2852 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2853 fields, and can't be used for REG_NOTES anyway). */
2854 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2859 ;; ....................
2863 ;; ....................
2865 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
2867 (define_expand "extv"
2868 [(set (match_operand 0 "register_operand")
2869 (sign_extract (match_operand:QI 1 "memory_operand")
2870 (match_operand 2 "immediate_operand")
2871 (match_operand 3 "immediate_operand")))]
2874 if (mips_expand_unaligned_load (operands[0], operands[1],
2875 INTVAL (operands[2]),
2876 INTVAL (operands[3])))
2882 (define_expand "extzv"
2883 [(set (match_operand 0 "register_operand")
2884 (zero_extract (match_operand 1 "nonimmediate_operand")
2885 (match_operand 2 "immediate_operand")
2886 (match_operand 3 "immediate_operand")))]
2889 if (mips_expand_unaligned_load (operands[0], operands[1],
2890 INTVAL (operands[2]),
2891 INTVAL (operands[3])))
2893 else if (mips_use_ins_ext_p (operands[1], operands[2], operands[3]))
2895 if (GET_MODE (operands[0]) == DImode)
2896 emit_insn (gen_extzvdi (operands[0], operands[1], operands[2],
2899 emit_insn (gen_extzvsi (operands[0], operands[1], operands[2],
2907 (define_insn "extzv<mode>"
2908 [(set (match_operand:GPR 0 "register_operand" "=d")
2909 (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
2910 (match_operand:SI 2 "immediate_operand" "I")
2911 (match_operand:SI 3 "immediate_operand" "I")))]
2912 "mips_use_ins_ext_p (operands[1], operands[2], operands[3])"
2913 "<d>ext\t%0,%1,%3,%2"
2914 [(set_attr "type" "arith")
2915 (set_attr "mode" "<MODE>")])
2918 (define_expand "insv"
2919 [(set (zero_extract (match_operand 0 "nonimmediate_operand")
2920 (match_operand 1 "immediate_operand")
2921 (match_operand 2 "immediate_operand"))
2922 (match_operand 3 "reg_or_0_operand"))]
2925 if (mips_expand_unaligned_store (operands[0], operands[3],
2926 INTVAL (operands[1]),
2927 INTVAL (operands[2])))
2929 else if (mips_use_ins_ext_p (operands[0], operands[1], operands[2]))
2931 if (GET_MODE (operands[0]) == DImode)
2932 emit_insn (gen_insvdi (operands[0], operands[1], operands[2],
2935 emit_insn (gen_insvsi (operands[0], operands[1], operands[2],
2943 (define_insn "insv<mode>"
2944 [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
2945 (match_operand:SI 1 "immediate_operand" "I")
2946 (match_operand:SI 2 "immediate_operand" "I"))
2947 (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
2948 "mips_use_ins_ext_p (operands[0], operands[1], operands[2])"
2949 "<d>ins\t%0,%z3,%2,%1"
2950 [(set_attr "type" "arith")
2951 (set_attr "mode" "<MODE>")])
2953 ;; Unaligned word moves generated by the bit field patterns.
2955 ;; As far as the rtl is concerned, both the left-part and right-part
2956 ;; instructions can access the whole field. However, the real operand
2957 ;; refers to just the first or the last byte (depending on endianness).
2958 ;; We therefore use two memory operands to each instruction, one to
2959 ;; describe the rtl effect and one to use in the assembly output.
2961 ;; Operands 0 and 1 are the rtl-level target and source respectively.
2962 ;; This allows us to use the standard length calculations for the "load"
2963 ;; and "store" type attributes.
2965 (define_insn "mov_<load>l"
2966 [(set (match_operand:GPR 0 "register_operand" "=d")
2967 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
2968 (match_operand:QI 2 "memory_operand" "m")]
2972 [(set_attr "type" "load")
2973 (set_attr "mode" "<MODE>")])
2975 (define_insn "mov_<load>r"
2976 [(set (match_operand:GPR 0 "register_operand" "=d")
2977 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
2978 (match_operand:QI 2 "memory_operand" "m")
2979 (match_operand:GPR 3 "register_operand" "0")]
2980 UNSPEC_LOAD_RIGHT))]
2983 [(set_attr "type" "load")
2984 (set_attr "mode" "<MODE>")])
2986 (define_insn "mov_<store>l"
2987 [(set (match_operand:BLK 0 "memory_operand" "=m")
2988 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
2989 (match_operand:QI 2 "memory_operand" "m")]
2990 UNSPEC_STORE_LEFT))]
2993 [(set_attr "type" "store")
2994 (set_attr "mode" "<MODE>")])
2996 (define_insn "mov_<store>r"
2997 [(set (match_operand:BLK 0 "memory_operand" "+m")
2998 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
2999 (match_operand:QI 2 "memory_operand" "m")
3001 UNSPEC_STORE_RIGHT))]
3004 [(set_attr "type" "store")
3005 (set_attr "mode" "<MODE>")])
3007 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3008 ;; The required value is:
3010 ;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3012 ;; which translates to:
3014 ;; lui op0,%highest(op1)
3015 ;; daddiu op0,op0,%higher(op1)
3017 ;; daddiu op0,op0,%hi(op1)
3020 ;; The split is deferred until after flow2 to allow the peephole2 below
3022 (define_insn_and_split "*lea_high64"
3023 [(set (match_operand:DI 0 "register_operand" "=d")
3024 (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3025 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3027 "&& flow2_completed"
3028 [(set (match_dup 0) (high:DI (match_dup 2)))
3029 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3030 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3031 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3032 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3034 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3035 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3037 [(set_attr "length" "20")])
3039 ;; Use a scratch register to reduce the latency of the above pattern
3040 ;; on superscalar machines. The optimized sequence is:
3042 ;; lui op1,%highest(op2)
3044 ;; daddiu op1,op1,%higher(op2)
3046 ;; daddu op1,op1,op0
3048 [(set (match_operand:DI 1 "register_operand")
3049 (high:DI (match_operand:DI 2 "general_symbolic_operand")))
3050 (match_scratch:DI 0 "d")]
3051 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3052 [(set (match_dup 1) (high:DI (match_dup 3)))
3053 (set (match_dup 0) (high:DI (match_dup 4)))
3054 (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
3055 (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
3056 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
3058 operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
3059 operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
3062 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3063 ;; SYMBOL_GENERAL X will take 6 cycles. This next pattern allows combine
3064 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3065 ;; used once. We can then use the sequence:
3067 ;; lui op0,%highest(op1)
3069 ;; daddiu op0,op0,%higher(op1)
3070 ;; daddiu op2,op2,%lo(op1)
3072 ;; daddu op0,op0,op2
3074 ;; which takes 4 cycles on most superscalar targets.
3075 (define_insn_and_split "*lea64"
3076 [(set (match_operand:DI 0 "register_operand" "=d")
3077 (match_operand:DI 1 "general_symbolic_operand" ""))
3078 (clobber (match_scratch:DI 2 "=&d"))]
3079 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3081 "&& reload_completed"
3082 [(set (match_dup 0) (high:DI (match_dup 3)))
3083 (set (match_dup 2) (high:DI (match_dup 4)))
3084 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3085 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3086 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3087 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3089 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3090 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3092 [(set_attr "length" "24")])
3094 ;; Insns to fetch a global symbol from a big GOT.
3096 (define_insn_and_split "*xgot_hi<mode>"
3097 [(set (match_operand:P 0 "register_operand" "=d")
3098 (high:P (match_operand:P 1 "global_got_operand" "")))]
3099 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3101 "&& reload_completed"
3102 [(set (match_dup 0) (high:P (match_dup 2)))
3103 (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3105 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3106 operands[3] = pic_offset_table_rtx;
3108 [(set_attr "got" "xgot_high")
3109 (set_attr "mode" "<MODE>")])
3111 (define_insn_and_split "*xgot_lo<mode>"
3112 [(set (match_operand:P 0 "register_operand" "=d")
3113 (lo_sum:P (match_operand:P 1 "register_operand" "d")
3114 (match_operand:P 2 "global_got_operand" "")))]
3115 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3117 "&& reload_completed"
3119 (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3120 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3121 [(set_attr "got" "load")
3122 (set_attr "mode" "<MODE>")])
3124 ;; Insns to fetch a global symbol from a normal GOT.
3126 (define_insn_and_split "*got_disp<mode>"
3127 [(set (match_operand:P 0 "register_operand" "=d")
3128 (match_operand:P 1 "global_got_operand" ""))]
3129 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3131 "&& reload_completed"
3133 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3135 operands[2] = pic_offset_table_rtx;
3136 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3138 [(set_attr "got" "load")
3139 (set_attr "mode" "<MODE>")])
3141 ;; Insns for loading the high part of a local symbol.
3143 (define_insn_and_split "*got_page<mode>"
3144 [(set (match_operand:P 0 "register_operand" "=d")
3145 (high:P (match_operand:P 1 "local_got_operand" "")))]
3146 "TARGET_EXPLICIT_RELOCS"
3148 "&& reload_completed"
3150 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3152 operands[2] = pic_offset_table_rtx;
3153 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3155 [(set_attr "got" "load")
3156 (set_attr "mode" "<MODE>")])
3158 ;; Lower-level instructions for loading an address from the GOT.
3159 ;; We could use MEMs, but an unspec gives more optimization
3162 (define_insn "load_got<mode>"
3163 [(set (match_operand:P 0 "register_operand" "=d")
3164 (unspec:P [(match_operand:P 1 "register_operand" "d")
3165 (match_operand:P 2 "immediate_operand" "")]
3168 "<load>\t%0,%R2(%1)"
3169 [(set_attr "type" "load")
3170 (set_attr "mode" "<MODE>")
3171 (set_attr "length" "4")])
3173 ;; Instructions for adding the low 16 bits of an address to a register.
3174 ;; Operand 2 is the address: print_operand works out which relocation
3175 ;; should be applied.
3177 (define_insn "*low<mode>"
3178 [(set (match_operand:P 0 "register_operand" "=d")
3179 (lo_sum:P (match_operand:P 1 "register_operand" "d")
3180 (match_operand:P 2 "immediate_operand" "")))]
3182 "<d>addiu\t%0,%1,%R2"
3183 [(set_attr "type" "arith")
3184 (set_attr "mode" "<MODE>")])
3186 (define_insn "*low<mode>_mips16"
3187 [(set (match_operand:P 0 "register_operand" "=d")
3188 (lo_sum:P (match_operand:P 1 "register_operand" "0")
3189 (match_operand:P 2 "immediate_operand" "")))]
3192 [(set_attr "type" "arith")
3193 (set_attr "mode" "<MODE>")
3194 (set_attr "length" "8")])
3196 ;; 64-bit integer moves
3198 ;; Unlike most other insns, the move insns can't be split with
3199 ;; different predicates, because register spilling and other parts of
3200 ;; the compiler, have memoized the insn number already.
3202 (define_expand "movdi"
3203 [(set (match_operand:DI 0 "")
3204 (match_operand:DI 1 ""))]
3207 if (mips_legitimize_move (DImode, operands[0], operands[1]))
3211 ;; For mips16, we need a special case to handle storing $31 into
3212 ;; memory, since we don't have a constraint to match $31. This
3213 ;; instruction can be generated by save_restore_insns.
3215 (define_insn "*mov<mode>_ra"
3216 [(set (match_operand:GPR 0 "stack_operand" "=m")
3220 [(set_attr "type" "store")
3221 (set_attr "mode" "<MODE>")])
3223 (define_insn "*movdi_32bit"
3224 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*B*C*D,*B*C*D,*d,*m")
3225 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
3226 "!TARGET_64BIT && !TARGET_MIPS16
3227 && (register_operand (operands[0], DImode)
3228 || reg_or_0_operand (operands[1], DImode))"
3229 { return mips_output_move (operands[0], operands[1]); }
3230 [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
3231 (set_attr "mode" "DI")
3232 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
3234 (define_insn "*movdi_32bit_mips16"
3235 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3236 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3237 "!TARGET_64BIT && TARGET_MIPS16
3238 && (register_operand (operands[0], DImode)
3239 || register_operand (operands[1], DImode))"
3240 { return mips_output_move (operands[0], operands[1]); }
3241 [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo")
3242 (set_attr "mode" "DI")
3243 (set_attr "length" "8,8,8,8,12,*,*,8")])
3245 (define_insn "*movdi_64bit"
3246 [(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")
3247 (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"))]
3248 "TARGET_64BIT && !TARGET_MIPS16
3249 && (register_operand (operands[0], DImode)
3250 || reg_or_0_operand (operands[1], DImode))"
3251 { return mips_output_move (operands[0], operands[1]); }
3252 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
3253 (set_attr "mode" "DI")
3254 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3256 (define_insn "*movdi_64bit_mips16"
3257 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3258 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3259 "TARGET_64BIT && TARGET_MIPS16
3260 && (register_operand (operands[0], DImode)
3261 || register_operand (operands[1], DImode))"
3262 { return mips_output_move (operands[0], operands[1]); }
3263 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
3264 (set_attr "mode" "DI")
3265 (set_attr_alternative "length"
3269 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3272 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3277 (const_string "*")])])
3280 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
3281 ;; when the original load is a 4 byte instruction but the add and the
3282 ;; load are 2 2 byte instructions.
3285 [(set (match_operand:DI 0 "register_operand")
3286 (mem:DI (plus:DI (match_dup 0)
3287 (match_operand:DI 1 "const_int_operand"))))]
3288 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3289 && !TARGET_DEBUG_D_MODE
3290 && REG_P (operands[0])
3291 && M16_REG_P (REGNO (operands[0]))
3292 && GET_CODE (operands[1]) == CONST_INT
3293 && ((INTVAL (operands[1]) < 0
3294 && INTVAL (operands[1]) >= -0x10)
3295 || (INTVAL (operands[1]) >= 32 * 8
3296 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3297 || (INTVAL (operands[1]) >= 0
3298 && INTVAL (operands[1]) < 32 * 8
3299 && (INTVAL (operands[1]) & 7) != 0))"
3300 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3301 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3303 HOST_WIDE_INT val = INTVAL (operands[1]);
3306 operands[2] = const0_rtx;
3307 else if (val >= 32 * 8)
3311 operands[1] = GEN_INT (0x8 + off);
3312 operands[2] = GEN_INT (val - off - 0x8);
3318 operands[1] = GEN_INT (off);
3319 operands[2] = GEN_INT (val - off);
3323 ;; 32-bit Integer moves
3325 ;; Unlike most other insns, the move insns can't be split with
3326 ;; different predicates, because register spilling and other parts of
3327 ;; the compiler, have memoized the insn number already.
3329 (define_expand "movsi"
3330 [(set (match_operand:SI 0 "")
3331 (match_operand:SI 1 ""))]
3334 if (mips_legitimize_move (SImode, operands[0], operands[1]))
3338 ;; The difference between these two is whether or not ints are allowed
3339 ;; in FP registers (off by default, use -mdebugh to enable).
3341 (define_insn "*movsi_internal"
3342 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*a,*d,*B*C*D,*B*C*D,*d,*m")
3343 (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*A,*d,*m,*B*C*D,*B*C*D"))]
3345 && (register_operand (operands[0], SImode)
3346 || reg_or_0_operand (operands[1], SImode))"
3347 { return mips_output_move (operands[0], operands[1]); }
3348 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,mfhilo,xfer,load,xfer,store")
3349 (set_attr "mode" "SI")
3350 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")])
3352 (define_insn "*movsi_mips16"
3353 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3354 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3356 && (register_operand (operands[0], SImode)
3357 || register_operand (operands[1], SImode))"
3358 { return mips_output_move (operands[0], operands[1]); }
3359 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
3360 (set_attr "mode" "SI")
3361 (set_attr_alternative "length"
3365 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3368 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3373 (const_string "*")])])
3375 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
3376 ;; when the original load is a 4 byte instruction but the add and the
3377 ;; load are 2 2 byte instructions.
3380 [(set (match_operand:SI 0 "register_operand")
3381 (mem:SI (plus:SI (match_dup 0)
3382 (match_operand:SI 1 "const_int_operand"))))]
3383 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3384 && REG_P (operands[0])
3385 && M16_REG_P (REGNO (operands[0]))
3386 && GET_CODE (operands[1]) == CONST_INT
3387 && ((INTVAL (operands[1]) < 0
3388 && INTVAL (operands[1]) >= -0x80)
3389 || (INTVAL (operands[1]) >= 32 * 4
3390 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3391 || (INTVAL (operands[1]) >= 0
3392 && INTVAL (operands[1]) < 32 * 4
3393 && (INTVAL (operands[1]) & 3) != 0))"
3394 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3395 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3397 HOST_WIDE_INT val = INTVAL (operands[1]);