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, 2006, 2007
4 ;; Free Software Foundation, Inc.
5 ;; Contributed by A. Lichnewsky, lich@inria.inria.fr
6 ;; Changes by Michael Meissner, meissner@osf.org
7 ;; 64-bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
8 ;; Brendan Eich, brendan@microunity.com.
10 ;; This file is part of GCC.
12 ;; GCC is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 3, or (at your option)
17 ;; GCC is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GCC; see the file COPYING3. If not see
24 ;; <http://www.gnu.org/licenses/>.
27 [(UNSPEC_LOAD_DF_LOW 0)
28 (UNSPEC_LOAD_DF_HIGH 1)
29 (UNSPEC_STORE_DF_HIGH 2)
33 (UNSPEC_NONLOCAL_GOTO_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)
52 (UNSPEC_CLEAR_HAZARD 33)
56 (UNSPEC_COMPARE_AND_SWAP 37)
57 (UNSPEC_SYNC_OLD_OP 38)
58 (UNSPEC_SYNC_NEW_OP 39)
59 (UNSPEC_SYNC_EXCHANGE 40)
60 (UNSPEC_MEMORY_BARRIER 41)
62 (UNSPEC_ADDRESS_FIRST 100)
66 ;; For MIPS Paired-Singled Floating Point Instructions.
68 (UNSPEC_MOVE_TF_PS 200)
71 ;; MIPS64/MIPS32R2 alnv.ps
74 ;; MIPS-3D instructions
78 (UNSPEC_CVT_PW_PS 205)
79 (UNSPEC_CVT_PS_PW 206)
87 (UNSPEC_SINGLE_CC 213)
90 ;; MIPS DSP ASE Revision 0.98 3/24/2005
98 (UNSPEC_RADDU_W_QB 307)
100 (UNSPEC_PRECRQ_QB_PH 309)
101 (UNSPEC_PRECRQ_PH_W 310)
102 (UNSPEC_PRECRQ_RS_PH_W 311)
103 (UNSPEC_PRECRQU_S_QB_PH 312)
104 (UNSPEC_PRECEQ_W_PHL 313)
105 (UNSPEC_PRECEQ_W_PHR 314)
106 (UNSPEC_PRECEQU_PH_QBL 315)
107 (UNSPEC_PRECEQU_PH_QBR 316)
108 (UNSPEC_PRECEQU_PH_QBLA 317)
109 (UNSPEC_PRECEQU_PH_QBRA 318)
110 (UNSPEC_PRECEU_PH_QBL 319)
111 (UNSPEC_PRECEU_PH_QBR 320)
112 (UNSPEC_PRECEU_PH_QBLA 321)
113 (UNSPEC_PRECEU_PH_QBRA 322)
119 (UNSPEC_MULEU_S_PH_QBL 328)
120 (UNSPEC_MULEU_S_PH_QBR 329)
121 (UNSPEC_MULQ_RS_PH 330)
122 (UNSPEC_MULEQ_S_W_PHL 331)
123 (UNSPEC_MULEQ_S_W_PHR 332)
124 (UNSPEC_DPAU_H_QBL 333)
125 (UNSPEC_DPAU_H_QBR 334)
126 (UNSPEC_DPSU_H_QBL 335)
127 (UNSPEC_DPSU_H_QBR 336)
128 (UNSPEC_DPAQ_S_W_PH 337)
129 (UNSPEC_DPSQ_S_W_PH 338)
130 (UNSPEC_MULSAQ_S_W_PH 339)
131 (UNSPEC_DPAQ_SA_L_W 340)
132 (UNSPEC_DPSQ_SA_L_W 341)
133 (UNSPEC_MAQ_S_W_PHL 342)
134 (UNSPEC_MAQ_S_W_PHR 343)
135 (UNSPEC_MAQ_SA_W_PHL 344)
136 (UNSPEC_MAQ_SA_W_PHR 345)
144 (UNSPEC_CMPGU_EQ_QB 353)
145 (UNSPEC_CMPGU_LT_QB 354)
146 (UNSPEC_CMPGU_LE_QB 355)
148 (UNSPEC_PACKRL_PH 357)
150 (UNSPEC_EXTR_R_W 359)
151 (UNSPEC_EXTR_RS_W 360)
152 (UNSPEC_EXTR_S_H 361)
160 ;; MIPS DSP ASE REV 2 Revision 0.02 11/24/2006
161 (UNSPEC_ABSQ_S_QB 400)
163 (UNSPEC_ADDU_S_PH 402)
164 (UNSPEC_ADDUH_QB 403)
165 (UNSPEC_ADDUH_R_QB 404)
168 (UNSPEC_CMPGDU_EQ_QB 407)
169 (UNSPEC_CMPGDU_LT_QB 408)
170 (UNSPEC_CMPGDU_LE_QB 409)
171 (UNSPEC_DPA_W_PH 410)
172 (UNSPEC_DPS_W_PH 411)
178 (UNSPEC_MUL_S_PH 417)
179 (UNSPEC_MULQ_RS_W 418)
180 (UNSPEC_MULQ_S_PH 419)
181 (UNSPEC_MULQ_S_W 420)
182 (UNSPEC_MULSA_W_PH 421)
185 (UNSPEC_PRECR_QB_PH 424)
186 (UNSPEC_PRECR_SRA_PH_W 425)
187 (UNSPEC_PRECR_SRA_R_PH_W 426)
190 (UNSPEC_SHRA_R_QB 429)
193 (UNSPEC_SUBU_S_PH 432)
194 (UNSPEC_SUBUH_QB 433)
195 (UNSPEC_SUBUH_R_QB 434)
196 (UNSPEC_ADDQH_PH 435)
197 (UNSPEC_ADDQH_R_PH 436)
199 (UNSPEC_ADDQH_R_W 438)
200 (UNSPEC_SUBQH_PH 439)
201 (UNSPEC_SUBQH_R_PH 440)
203 (UNSPEC_SUBQH_R_W 442)
204 (UNSPEC_DPAX_W_PH 443)
205 (UNSPEC_DPSX_W_PH 444)
206 (UNSPEC_DPAQX_S_W_PH 445)
207 (UNSPEC_DPAQX_SA_W_PH 446)
208 (UNSPEC_DPSQX_S_W_PH 447)
209 (UNSPEC_DPSQX_SA_W_PH 448)
213 (include "predicates.md")
214 (include "constraints.md")
216 ;; ....................
220 ;; ....................
222 (define_attr "got" "unset,xgot_high,load"
223 (const_string "unset"))
225 ;; For jal instructions, this attribute is DIRECT when the target address
226 ;; is symbolic and INDIRECT when it is a register.
227 (define_attr "jal" "unset,direct,indirect"
228 (const_string "unset"))
230 ;; This attribute is YES if the instruction is a jal macro (not a
231 ;; real jal instruction).
233 ;; jal is always a macro for TARGET_CALL_CLOBBERED_GP because it includes
234 ;; an instruction to restore $gp. Direct jals are also macros for
235 ;; flag_pic && !TARGET_ABSOLUTE_ABICALLS because they first load
236 ;; the target address into a register.
237 (define_attr "jal_macro" "no,yes"
238 (cond [(eq_attr "jal" "direct")
239 (symbol_ref "TARGET_CALL_CLOBBERED_GP
240 || (flag_pic && !TARGET_ABSOLUTE_ABICALLS)")
241 (eq_attr "jal" "indirect")
242 (symbol_ref "TARGET_CALL_CLOBBERED_GP")]
243 (const_string "no")))
245 ;; Classification of each insn.
246 ;; branch conditional branch
247 ;; jump unconditional jump
248 ;; call unconditional call
249 ;; load load instruction(s)
250 ;; fpload floating point load
251 ;; fpidxload floating point indexed load
252 ;; store store instruction(s)
253 ;; fpstore floating point store
254 ;; fpidxstore floating point indexed store
255 ;; prefetch memory prefetch (register + offset)
256 ;; prefetchx memory indexed prefetch (register + register)
257 ;; condmove conditional moves
258 ;; mfc transfer from coprocessor
259 ;; mtc transfer to coprocessor
260 ;; mthilo transfer to hi/lo registers
261 ;; mfhilo transfer from hi/lo registers
262 ;; const load constant
263 ;; arith integer arithmetic instructions
264 ;; logical integer logical instructions
265 ;; shift integer shift instructions
266 ;; slt set less than instructions
267 ;; signext sign extend instructions
268 ;; clz the clz and clo instructions
269 ;; trap trap if instructions
270 ;; imul integer multiply 2 operands
271 ;; imul3 integer multiply 3 operands
272 ;; imadd integer multiply-add
273 ;; idiv integer divide
274 ;; move integer register move ({,D}ADD{,U} with rt = 0)
275 ;; fmove floating point register move
276 ;; fadd floating point add/subtract
277 ;; fmul floating point multiply
278 ;; fmadd floating point multiply-add
279 ;; fdiv floating point divide
280 ;; frdiv floating point reciprocal divide
281 ;; frdiv1 floating point reciprocal divide step 1
282 ;; frdiv2 floating point reciprocal divide step 2
283 ;; fabs floating point absolute value
284 ;; fneg floating point negation
285 ;; fcmp floating point compare
286 ;; fcvt floating point convert
287 ;; fsqrt floating point square root
288 ;; frsqrt floating point reciprocal square root
289 ;; frsqrt1 floating point reciprocal square root step1
290 ;; frsqrt2 floating point reciprocal square root step2
291 ;; multi multiword sequence (or user asm statements)
294 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,mfc,mtc,mthilo,mfhilo,const,arith,logical,shift,slt,signext,clz,trap,imul,imul3,imadd,idiv,move,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,multi,nop"
295 (cond [(eq_attr "jal" "!unset") (const_string "call")
296 (eq_attr "got" "load") (const_string "load")]
297 (const_string "unknown")))
299 ;; Main data type used by the insn
300 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
301 (const_string "unknown"))
303 ;; Mode for conversion types (fcvt)
304 ;; I2S integer to float single (SI/DI to SF)
305 ;; I2D integer to float double (SI/DI to DF)
306 ;; S2I float to integer (SF to SI/DI)
307 ;; D2I float to integer (DF to SI/DI)
308 ;; D2S double to float single
309 ;; S2D float single to double
311 (define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D"
312 (const_string "unknown"))
314 ;; Is this an extended instruction in mips16 mode?
315 (define_attr "extended_mips16" "no,yes"
318 ;; Length of instruction in bytes.
319 (define_attr "length" ""
320 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
321 ;; If a branch is outside this range, we have a choice of two
322 ;; sequences. For PIC, an out-of-range branch like:
327 ;; becomes the equivalent of:
336 ;; where the load address can be up to three instructions long
339 ;; The non-PIC case is similar except that we use a direct
340 ;; jump instead of an la/jr pair. Since the target of this
341 ;; jump is an absolute 28-bit bit address (the other bits
342 ;; coming from the address of the delay slot) this form cannot
343 ;; cross a 256MB boundary. We could provide the option of
344 ;; using la/jr in this case too, but we do not do so at
347 ;; Note that this value does not account for the delay slot
348 ;; instruction, whose length is added separately. If the RTL
349 ;; pattern has no explicit delay slot, mips_adjust_insn_length
350 ;; will add the length of the implicit nop. The values for
351 ;; forward and backward branches will be different as well.
352 (eq_attr "type" "branch")
353 (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
354 (le (minus (pc) (match_dup 1)) (const_int 131068)))
356 (ne (symbol_ref "flag_pic") (const_int 0))
360 (eq_attr "got" "load")
362 (eq_attr "got" "xgot_high")
365 (eq_attr "type" "const")
366 (symbol_ref "mips_const_insns (operands[1]) * 4")
367 (eq_attr "type" "load,fpload")
368 (symbol_ref "mips_load_store_insns (operands[1], insn) * 4")
369 (eq_attr "type" "store,fpstore")
370 (symbol_ref "mips_load_store_insns (operands[0], insn) * 4")
372 ;; In the worst case, a call macro will take 8 instructions:
374 ;; lui $25,%call_hi(FOO)
376 ;; lw $25,%call_lo(FOO)($25)
382 (eq_attr "jal_macro" "yes")
385 (and (eq_attr "extended_mips16" "yes")
386 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
389 ;; Various VR4120 errata require a nop to be inserted after a macc
390 ;; instruction. The assembler does this for us, so account for
391 ;; the worst-case length here.
392 (and (eq_attr "type" "imadd")
393 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
396 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
397 ;; the result of the second one is missed. The assembler should work
398 ;; around this by inserting a nop after the first dmult.
399 (and (eq_attr "type" "imul,imul3")
400 (and (eq_attr "mode" "DI")
401 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
404 (eq_attr "type" "idiv")
405 (symbol_ref "mips_idiv_insns () * 4")
408 ;; Attribute describing the processor. This attribute must match exactly
409 ;; with the processor_type enumeration in mips.h.
411 "r3000,4kc,4kp,5kc,5kf,20kc,24kc,24kf2_1,24kf1_1,74kc,74kf2_1,74kf1_1,74kf3_2,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000"
412 (const (symbol_ref "mips_tune")))
414 ;; The type of hardware hazard associated with this instruction.
415 ;; DELAY means that the next instruction cannot read the result
416 ;; of this one. HILO means that the next two instructions cannot
417 ;; write to HI or LO.
418 (define_attr "hazard" "none,delay,hilo"
419 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
420 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
421 (const_string "delay")
423 (and (eq_attr "type" "mfc,mtc")
424 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
425 (const_string "delay")
427 (and (eq_attr "type" "fcmp")
428 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
429 (const_string "delay")
431 ;; The r4000 multiplication patterns include an mflo instruction.
432 (and (eq_attr "type" "imul")
433 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
434 (const_string "hilo")
436 (and (eq_attr "type" "mfhilo")
437 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
438 (const_string "hilo")]
439 (const_string "none")))
441 ;; Is it a single instruction?
442 (define_attr "single_insn" "no,yes"
443 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
445 ;; Can the instruction be put into a delay slot?
446 (define_attr "can_delay" "no,yes"
447 (if_then_else (and (eq_attr "type" "!branch,call,jump")
448 (and (eq_attr "hazard" "none")
449 (eq_attr "single_insn" "yes")))
451 (const_string "no")))
453 ;; Attribute defining whether or not we can use the branch-likely instructions
454 (define_attr "branch_likely" "no,yes"
456 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
458 (const_string "no"))))
460 ;; True if an instruction might assign to hi or lo when reloaded.
461 ;; This is used by the TUNE_MACC_CHAINS code.
462 (define_attr "may_clobber_hilo" "no,yes"
463 (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthilo")
465 (const_string "no")))
467 ;; Describe a user's asm statement.
468 (define_asm_attributes
469 [(set_attr "type" "multi")
470 (set_attr "can_delay" "no")])
472 ;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
473 ;; from the same template.
474 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
476 ;; This mode iterator allows :P to be used for patterns that operate on
477 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
478 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
480 ;; This mode iterator allows :MOVECC to be used anywhere that a
481 ;; conditional-move-type condition is needed.
482 (define_mode_iterator MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
484 ;; This mode iterator allows the QI and HI extension patterns to be defined from
485 ;; the same template.
486 (define_mode_iterator SHORT [QI HI])
488 ;; This mode iterator allows :ANYF to be used wherever a scalar or vector
489 ;; floating-point mode is allowed.
490 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
491 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
492 (V2SF "TARGET_PAIRED_SINGLE_FLOAT")])
494 ;; Like ANYF, but only applies to scalar modes.
495 (define_mode_iterator SCALARF [(SF "TARGET_HARD_FLOAT")
496 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
498 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
499 ;; 32-bit version and "dsubu" in the 64-bit version.
500 (define_mode_attr d [(SI "") (DI "d")])
502 ;; This attribute gives the length suffix for a sign- or zero-extension
504 (define_mode_attr size [(QI "b") (HI "h")])
506 ;; This attributes gives the mode mask of a SHORT.
507 (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
509 ;; Mode attributes for GPR loads and stores.
510 (define_mode_attr load [(SI "lw") (DI "ld")])
511 (define_mode_attr store [(SI "sw") (DI "sd")])
513 ;; Similarly for MIPS IV indexed FPR loads and stores.
514 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
515 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
517 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
518 ;; are different. Some forms of unextended addiu have an 8-bit immediate
519 ;; field but the equivalent daddiu has only a 5-bit field.
520 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
522 ;; This attribute gives the best constraint to use for registers of
524 (define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
526 ;; This attribute gives the format suffix for floating-point operations.
527 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
529 ;; This attribute gives the upper-case mode name for one unit of a
530 ;; floating-point mode.
531 (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
533 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
535 ;; In certain cases, div.s and div.ps may have a rounding error
536 ;; and/or wrong inexact flag.
538 ;; Therefore, we only allow div.s if not working around SB-1 rev2
539 ;; errata or if a slight loss of precision is OK.
540 (define_mode_attr divide_condition
541 [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")
542 (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")])
544 ; This attribute gives the condition for which sqrt instructions exist.
545 (define_mode_attr sqrt_condition
546 [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")])
548 ; This attribute gives the condition for which recip and rsqrt instructions
550 (define_mode_attr recip_condition
551 [(SF "ISA_HAS_FP4") (DF "ISA_HAS_FP4") (V2SF "TARGET_SB1")])
553 ;; This code iterator allows all branch instructions to be generated from
554 ;; a single define_expand template.
555 (define_code_iterator any_cond [unordered ordered unlt unge uneq ltgt unle ungt
556 eq ne gt ge lt le gtu geu ltu leu])
558 ;; This code iterator allows signed and unsigned widening multiplications
559 ;; to use the same template.
560 (define_code_iterator any_extend [sign_extend zero_extend])
562 ;; This code iterator allows the three shift instructions to be generated
563 ;; from the same template.
564 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
566 ;; This code iterator allows all native floating-point comparisons to be
567 ;; generated from the same template.
568 (define_code_iterator fcond [unordered uneq unlt unle eq lt le])
570 ;; This code iterator is used for comparisons that can be implemented
571 ;; by swapping the operands.
572 (define_code_iterator swapped_fcond [ge gt unge ungt])
574 ;; <u> expands to an empty string when doing a signed operation and
575 ;; "u" when doing an unsigned operation.
576 (define_code_attr u [(sign_extend "") (zero_extend "u")])
578 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
579 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
581 ;; <optab> expands to the name of the optab for a particular code.
582 (define_code_attr optab [(ashift "ashl")
589 ;; <insn> expands to the name of the insn that implements a particular code.
590 (define_code_attr insn [(ashift "sll")
597 ;; <fcond> is the c.cond.fmt condition associated with a particular code.
598 (define_code_attr fcond [(unordered "un")
606 ;; Similar, but for swapped conditions.
607 (define_code_attr swapped_fcond [(ge "le")
612 ;; Atomic fetch bitwise operations.
613 (define_code_iterator fetchop_bit [ior xor and])
615 ;; <immediate_insn> expands to the name of the insn that implements
616 ;; a particular code to operate in immediate values.
617 (define_code_attr immediate_insn [(ior "ori") (xor "xori") (and "andi")])
620 ;; .........................
622 ;; Branch, call and jump delay slots
624 ;; .........................
626 (define_delay (and (eq_attr "type" "branch")
627 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
628 [(eq_attr "can_delay" "yes")
630 (and (eq_attr "branch_likely" "yes")
631 (eq_attr "can_delay" "yes"))])
633 (define_delay (eq_attr "type" "jump")
634 [(eq_attr "can_delay" "yes")
638 (define_delay (and (eq_attr "type" "call")
639 (eq_attr "jal_macro" "no"))
640 [(eq_attr "can_delay" "yes")
644 ;; Pipeline descriptions.
646 ;; generic.md provides a fallback for processors without a specific
647 ;; pipeline description. It is derived from the old define_function_unit
648 ;; version and uses the "alu" and "imuldiv" units declared below.
650 ;; Some of the processor-specific files are also derived from old
651 ;; define_function_unit descriptions and simply override the parts of
652 ;; generic.md that don't apply. The other processor-specific files
653 ;; are self-contained.
654 (define_automaton "alu,imuldiv")
656 (define_cpu_unit "alu" "alu")
657 (define_cpu_unit "imuldiv" "imuldiv")
678 (include "generic.md")
681 ;; ....................
685 ;; ....................
689 [(trap_if (const_int 1) (const_int 0))]
692 if (ISA_HAS_COND_TRAP)
694 else if (TARGET_MIPS16)
699 [(set_attr "type" "trap")])
701 (define_expand "conditional_trap"
702 [(trap_if (match_operator 0 "comparison_operator"
703 [(match_dup 2) (match_dup 3)])
704 (match_operand 1 "const_int_operand"))]
707 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
708 && operands[1] == const0_rtx)
710 mips_gen_conditional_trap (operands);
717 (define_insn "*conditional_trap<mode>"
718 [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
719 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
720 (match_operand:GPR 2 "arith_operand" "dI")])
724 [(set_attr "type" "trap")])
727 ;; ....................
731 ;; ....................
734 (define_insn "add<mode>3"
735 [(set (match_operand:ANYF 0 "register_operand" "=f")
736 (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
737 (match_operand:ANYF 2 "register_operand" "f")))]
739 "add.<fmt>\t%0,%1,%2"
740 [(set_attr "type" "fadd")
741 (set_attr "mode" "<UNITMODE>")])
743 (define_expand "add<mode>3"
744 [(set (match_operand:GPR 0 "register_operand")
745 (plus:GPR (match_operand:GPR 1 "register_operand")
746 (match_operand:GPR 2 "arith_operand")))]
749 (define_insn "*add<mode>3"
750 [(set (match_operand:GPR 0 "register_operand" "=d,d")
751 (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
752 (match_operand:GPR 2 "arith_operand" "d,Q")))]
757 [(set_attr "type" "arith")
758 (set_attr "mode" "<MODE>")])
760 (define_insn "*add<mode>3_mips16"
761 [(set (match_operand:GPR 0 "register_operand" "=ks,d,d,d,d")
762 (plus:GPR (match_operand:GPR 1 "register_operand" "ks,ks,0,d,d")
763 (match_operand:GPR 2 "arith_operand" "Q,Q,Q,O,d")))]
771 [(set_attr "type" "arith")
772 (set_attr "mode" "<MODE>")
773 (set_attr_alternative "length"
774 [(if_then_else (match_operand 2 "m16_simm8_8")
777 (if_then_else (match_operand 2 "m16_uimm<si8_di5>_4")
780 (if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
783 (if_then_else (match_operand 2 "m16_simm4_1")
788 ;; On the mips16, we can sometimes split an add of a constant which is
789 ;; a 4 byte instruction into two adds which are both 2 byte
790 ;; instructions. There are two cases: one where we are adding a
791 ;; constant plus a register to another register, and one where we are
792 ;; simply adding a constant to a register.
795 [(set (match_operand:SI 0 "register_operand")
796 (plus:SI (match_dup 0)
797 (match_operand:SI 1 "const_int_operand")))]
798 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
799 && REG_P (operands[0])
800 && M16_REG_P (REGNO (operands[0]))
801 && GET_CODE (operands[1]) == CONST_INT
802 && ((INTVAL (operands[1]) > 0x7f
803 && INTVAL (operands[1]) <= 0x7f + 0x7f)
804 || (INTVAL (operands[1]) < - 0x80
805 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
806 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
807 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
809 HOST_WIDE_INT val = INTVAL (operands[1]);
813 operands[1] = GEN_INT (0x7f);
814 operands[2] = GEN_INT (val - 0x7f);
818 operands[1] = GEN_INT (- 0x80);
819 operands[2] = GEN_INT (val + 0x80);
824 [(set (match_operand:SI 0 "register_operand")
825 (plus:SI (match_operand:SI 1 "register_operand")
826 (match_operand:SI 2 "const_int_operand")))]
827 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
828 && REG_P (operands[0])
829 && M16_REG_P (REGNO (operands[0]))
830 && REG_P (operands[1])
831 && M16_REG_P (REGNO (operands[1]))
832 && REGNO (operands[0]) != REGNO (operands[1])
833 && GET_CODE (operands[2]) == CONST_INT
834 && ((INTVAL (operands[2]) > 0x7
835 && INTVAL (operands[2]) <= 0x7 + 0x7f)
836 || (INTVAL (operands[2]) < - 0x8
837 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
838 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
839 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
841 HOST_WIDE_INT val = INTVAL (operands[2]);
845 operands[2] = GEN_INT (0x7);
846 operands[3] = GEN_INT (val - 0x7);
850 operands[2] = GEN_INT (- 0x8);
851 operands[3] = GEN_INT (val + 0x8);
856 [(set (match_operand:DI 0 "register_operand")
857 (plus:DI (match_dup 0)
858 (match_operand:DI 1 "const_int_operand")))]
859 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
860 && REG_P (operands[0])
861 && M16_REG_P (REGNO (operands[0]))
862 && GET_CODE (operands[1]) == CONST_INT
863 && ((INTVAL (operands[1]) > 0xf
864 && INTVAL (operands[1]) <= 0xf + 0xf)
865 || (INTVAL (operands[1]) < - 0x10
866 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
867 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
868 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
870 HOST_WIDE_INT val = INTVAL (operands[1]);
874 operands[1] = GEN_INT (0xf);
875 operands[2] = GEN_INT (val - 0xf);
879 operands[1] = GEN_INT (- 0x10);
880 operands[2] = GEN_INT (val + 0x10);
885 [(set (match_operand:DI 0 "register_operand")
886 (plus:DI (match_operand:DI 1 "register_operand")
887 (match_operand:DI 2 "const_int_operand")))]
888 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
889 && REG_P (operands[0])
890 && M16_REG_P (REGNO (operands[0]))
891 && REG_P (operands[1])
892 && M16_REG_P (REGNO (operands[1]))
893 && REGNO (operands[0]) != REGNO (operands[1])
894 && GET_CODE (operands[2]) == CONST_INT
895 && ((INTVAL (operands[2]) > 0x7
896 && INTVAL (operands[2]) <= 0x7 + 0xf)
897 || (INTVAL (operands[2]) < - 0x8
898 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
899 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
900 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
902 HOST_WIDE_INT val = INTVAL (operands[2]);
906 operands[2] = GEN_INT (0x7);
907 operands[3] = GEN_INT (val - 0x7);
911 operands[2] = GEN_INT (- 0x8);
912 operands[3] = GEN_INT (val + 0x8);
916 (define_insn "*addsi3_extended"
917 [(set (match_operand:DI 0 "register_operand" "=d,d")
919 (plus:SI (match_operand:SI 1 "register_operand" "d,d")
920 (match_operand:SI 2 "arith_operand" "d,Q"))))]
921 "TARGET_64BIT && !TARGET_MIPS16"
925 [(set_attr "type" "arith")
926 (set_attr "mode" "SI")])
928 ;; Split this insn so that the addiu splitters can have a crack at it.
929 ;; Use a conservative length estimate until the split.
930 (define_insn_and_split "*addsi3_extended_mips16"
931 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
933 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
934 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
935 "TARGET_64BIT && TARGET_MIPS16"
937 "&& reload_completed"
938 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
939 { operands[3] = gen_lowpart (SImode, operands[0]); }
940 [(set_attr "type" "arith")
941 (set_attr "mode" "SI")
942 (set_attr "extended_mips16" "yes")])
945 ;; ....................
949 ;; ....................
952 (define_insn "sub<mode>3"
953 [(set (match_operand:ANYF 0 "register_operand" "=f")
954 (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
955 (match_operand:ANYF 2 "register_operand" "f")))]
957 "sub.<fmt>\t%0,%1,%2"
958 [(set_attr "type" "fadd")
959 (set_attr "mode" "<UNITMODE>")])
961 (define_insn "sub<mode>3"
962 [(set (match_operand:GPR 0 "register_operand" "=d")
963 (minus:GPR (match_operand:GPR 1 "register_operand" "d")
964 (match_operand:GPR 2 "register_operand" "d")))]
967 [(set_attr "type" "arith")
968 (set_attr "mode" "<MODE>")])
970 (define_insn "*subsi3_extended"
971 [(set (match_operand:DI 0 "register_operand" "=d")
973 (minus:SI (match_operand:SI 1 "register_operand" "d")
974 (match_operand:SI 2 "register_operand" "d"))))]
977 [(set_attr "type" "arith")
978 (set_attr "mode" "DI")])
981 ;; ....................
985 ;; ....................
988 (define_expand "mul<mode>3"
989 [(set (match_operand:SCALARF 0 "register_operand")
990 (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
991 (match_operand:SCALARF 2 "register_operand")))]
995 (define_insn "*mul<mode>3"
996 [(set (match_operand:SCALARF 0 "register_operand" "=f")
997 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
998 (match_operand:SCALARF 2 "register_operand" "f")))]
999 "!TARGET_4300_MUL_FIX"
1000 "mul.<fmt>\t%0,%1,%2"
1001 [(set_attr "type" "fmul")
1002 (set_attr "mode" "<MODE>")])
1004 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
1005 ;; operands may corrupt immediately following multiplies. This is a
1006 ;; simple fix to insert NOPs.
1008 (define_insn "*mul<mode>3_r4300"
1009 [(set (match_operand:SCALARF 0 "register_operand" "=f")
1010 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1011 (match_operand:SCALARF 2 "register_operand" "f")))]
1012 "TARGET_4300_MUL_FIX"
1013 "mul.<fmt>\t%0,%1,%2\;nop"
1014 [(set_attr "type" "fmul")
1015 (set_attr "mode" "<MODE>")
1016 (set_attr "length" "8")])
1018 (define_insn "mulv2sf3"
1019 [(set (match_operand:V2SF 0 "register_operand" "=f")
1020 (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
1021 (match_operand:V2SF 2 "register_operand" "f")))]
1022 "TARGET_PAIRED_SINGLE_FLOAT"
1024 [(set_attr "type" "fmul")
1025 (set_attr "mode" "SF")])
1027 ;; The original R4000 has a cpu bug. If a double-word or a variable
1028 ;; shift executes while an integer multiplication is in progress, the
1029 ;; shift may give an incorrect result. Avoid this by keeping the mflo
1030 ;; with the mult on the R4000.
1032 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
1033 ;; (also valid for MIPS R4000MC processors):
1035 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
1036 ;; this errata description.
1037 ;; The following code sequence causes the R4000 to incorrectly
1038 ;; execute the Double Shift Right Arithmetic 32 (dsra32)
1039 ;; instruction. If the dsra32 instruction is executed during an
1040 ;; integer multiply, the dsra32 will only shift by the amount in
1041 ;; specified in the instruction rather than the amount plus 32
1043 ;; instruction 1: mult rs,rt integer multiply
1044 ;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
1045 ;; right arithmetic + 32
1046 ;; Workaround: A dsra32 instruction placed after an integer
1047 ;; multiply should not be one of the 11 instructions after the
1048 ;; multiply instruction."
1052 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
1053 ;; the following description.
1054 ;; All extended shifts (shift by n+32) and variable shifts (32 and
1055 ;; 64-bit versions) may produce incorrect results under the
1056 ;; following conditions:
1057 ;; 1) An integer multiply is currently executing
1058 ;; 2) These types of shift instructions are executed immediately
1059 ;; following an integer divide instruction.
1061 ;; 1) Make sure no integer multiply is running wihen these
1062 ;; instruction are executed. If this cannot be predicted at
1063 ;; compile time, then insert a "mfhi" to R0 instruction
1064 ;; immediately after the integer multiply instruction. This
1065 ;; will cause the integer multiply to complete before the shift
1067 ;; 2) Separate integer divide and these two classes of shift
1068 ;; instructions by another instruction or a noop."
1070 ;; These processors have PRId values of 0x00004220 and 0x00004300,
1073 (define_expand "mulsi3"
1074 [(set (match_operand:SI 0 "register_operand")
1075 (mult:SI (match_operand:SI 1 "register_operand")
1076 (match_operand:SI 2 "register_operand")))]
1080 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1081 else if (TARGET_FIX_R4000)
1082 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1084 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1088 (define_expand "muldi3"
1089 [(set (match_operand:DI 0 "register_operand")
1090 (mult:DI (match_operand:DI 1 "register_operand")
1091 (match_operand:DI 2 "register_operand")))]
1094 if (TARGET_FIX_R4000)
1095 emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
1097 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1101 (define_insn "mulsi3_mult3"
1102 [(set (match_operand:SI 0 "register_operand" "=d,l")
1103 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1104 (match_operand:SI 2 "register_operand" "d,d")))
1105 (clobber (match_scratch:SI 3 "=h,h"))
1106 (clobber (match_scratch:SI 4 "=l,X"))]
1109 if (which_alternative == 1)
1110 return "mult\t%1,%2";
1111 if (TARGET_MIPS3900)
1112 return "mult\t%0,%1,%2";
1113 return "mul\t%0,%1,%2";
1115 [(set_attr "type" "imul3,imul")
1116 (set_attr "mode" "SI")])
1118 ;; If a register gets allocated to LO, and we spill to memory, the reload
1119 ;; will include a move from LO to a GPR. Merge it into the multiplication
1120 ;; if it can set the GPR directly.
1123 ;; Operand 1: GPR (1st multiplication operand)
1124 ;; Operand 2: GPR (2nd multiplication operand)
1126 ;; Operand 4: GPR (destination)
1129 [(set (match_operand:SI 0 "register_operand")
1130 (mult:SI (match_operand:SI 1 "register_operand")
1131 (match_operand:SI 2 "register_operand")))
1132 (clobber (match_operand:SI 3 "register_operand"))
1133 (clobber (scratch:SI))])
1134 (set (match_operand:SI 4 "register_operand")
1135 (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1136 "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[0])"
1139 (mult:SI (match_dup 1)
1141 (clobber (match_dup 3))
1142 (clobber (match_dup 0))])])
1144 (define_insn "mul<mode>3_internal"
1145 [(set (match_operand:GPR 0 "register_operand" "=l")
1146 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1147 (match_operand:GPR 2 "register_operand" "d")))
1148 (clobber (match_scratch:GPR 3 "=h"))]
1151 [(set_attr "type" "imul")
1152 (set_attr "mode" "<MODE>")])
1154 (define_insn "mul<mode>3_r4000"
1155 [(set (match_operand:GPR 0 "register_operand" "=d")
1156 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1157 (match_operand:GPR 2 "register_operand" "d")))
1158 (clobber (match_scratch:GPR 3 "=h"))
1159 (clobber (match_scratch:GPR 4 "=l"))]
1161 "<d>mult\t%1,%2\;mflo\t%0"
1162 [(set_attr "type" "imul")
1163 (set_attr "mode" "<MODE>")
1164 (set_attr "length" "8")])
1166 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1167 ;; of "mult; mflo". They have the same latency, but the first form gives
1168 ;; us an extra cycle to compute the operands.
1171 ;; Operand 1: GPR (1st multiplication operand)
1172 ;; Operand 2: GPR (2nd multiplication operand)
1174 ;; Operand 4: GPR (destination)
1177 [(set (match_operand:SI 0 "register_operand")
1178 (mult:SI (match_operand:SI 1 "register_operand")
1179 (match_operand:SI 2 "register_operand")))
1180 (clobber (match_operand:SI 3 "register_operand"))])
1181 (set (match_operand:SI 4 "register_operand")
1182 (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1183 "ISA_HAS_MACC && !ISA_HAS_MUL3"
1188 (plus:SI (mult:SI (match_dup 1)
1192 (plus:SI (mult:SI (match_dup 1)
1195 (clobber (match_dup 3))])])
1197 ;; Multiply-accumulate patterns
1199 ;; For processors that can copy the output to a general register:
1201 ;; The all-d alternative is needed because the combiner will find this
1202 ;; pattern and then register alloc/reload will move registers around to
1203 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1205 ;; The last alternative should be made slightly less desirable, but adding
1206 ;; "?" to the constraint is too strong, and causes values to be loaded into
1207 ;; LO even when that's more costly. For now, using "*d" mostly does the
1209 (define_insn "*mul_acc_si"
1210 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1211 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1212 (match_operand:SI 2 "register_operand" "d,d,d"))
1213 (match_operand:SI 3 "register_operand" "0,l,*d")))
1214 (clobber (match_scratch:SI 4 "=h,h,h"))
1215 (clobber (match_scratch:SI 5 "=X,3,l"))
1216 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1218 || GENERATE_MADD_MSUB)
1221 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1222 if (which_alternative == 2)
1224 if (GENERATE_MADD_MSUB && which_alternative != 0)
1226 return madd[which_alternative];
1228 [(set_attr "type" "imadd")
1229 (set_attr "mode" "SI")
1230 (set_attr "length" "4,4,8")])
1232 ;; Split the above insn if we failed to get LO allocated.
1234 [(set (match_operand:SI 0 "register_operand")
1235 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1236 (match_operand:SI 2 "register_operand"))
1237 (match_operand:SI 3 "register_operand")))
1238 (clobber (match_scratch:SI 4))
1239 (clobber (match_scratch:SI 5))
1240 (clobber (match_scratch:SI 6))]
1241 "reload_completed && !TARGET_DEBUG_D_MODE
1242 && GP_REG_P (true_regnum (operands[0]))
1243 && GP_REG_P (true_regnum (operands[3]))"
1244 [(parallel [(set (match_dup 6)
1245 (mult:SI (match_dup 1) (match_dup 2)))
1246 (clobber (match_dup 4))
1247 (clobber (match_dup 5))])
1248 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1251 ;; Splitter to copy result of MADD to a general register
1253 [(set (match_operand:SI 0 "register_operand")
1254 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1255 (match_operand:SI 2 "register_operand"))
1256 (match_operand:SI 3 "register_operand")))
1257 (clobber (match_scratch:SI 4))
1258 (clobber (match_scratch:SI 5))
1259 (clobber (match_scratch:SI 6))]
1260 "reload_completed && !TARGET_DEBUG_D_MODE
1261 && GP_REG_P (true_regnum (operands[0]))
1262 && true_regnum (operands[3]) == LO_REGNUM"
1263 [(parallel [(set (match_dup 3)
1264 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1266 (clobber (match_dup 4))
1267 (clobber (match_dup 5))
1268 (clobber (match_dup 6))])
1269 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1272 (define_insn "*macc"
1273 [(set (match_operand:SI 0 "register_operand" "=l,d")
1274 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1275 (match_operand:SI 2 "register_operand" "d,d"))
1276 (match_operand:SI 3 "register_operand" "0,l")))
1277 (clobber (match_scratch:SI 4 "=h,h"))
1278 (clobber (match_scratch:SI 5 "=X,3"))]
1281 if (which_alternative == 1)
1282 return "macc\t%0,%1,%2";
1283 else if (TARGET_MIPS5500)
1284 return "madd\t%1,%2";
1286 /* The VR4130 assumes that there is a two-cycle latency between a macc
1287 that "writes" to $0 and an instruction that reads from it. We avoid
1288 this by assigning to $1 instead. */
1289 return "%[macc\t%@,%1,%2%]";
1291 [(set_attr "type" "imadd")
1292 (set_attr "mode" "SI")])
1294 (define_insn "*msac"
1295 [(set (match_operand:SI 0 "register_operand" "=l,d")
1296 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1297 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1298 (match_operand:SI 3 "register_operand" "d,d"))))
1299 (clobber (match_scratch:SI 4 "=h,h"))
1300 (clobber (match_scratch:SI 5 "=X,1"))]
1303 if (which_alternative == 1)
1304 return "msac\t%0,%2,%3";
1305 else if (TARGET_MIPS5500)
1306 return "msub\t%2,%3";
1308 return "msac\t$0,%2,%3";
1310 [(set_attr "type" "imadd")
1311 (set_attr "mode" "SI")])
1313 ;; An msac-like instruction implemented using negation and a macc.
1314 (define_insn_and_split "*msac_using_macc"
1315 [(set (match_operand:SI 0 "register_operand" "=l,d")
1316 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1317 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1318 (match_operand:SI 3 "register_operand" "d,d"))))
1319 (clobber (match_scratch:SI 4 "=h,h"))
1320 (clobber (match_scratch:SI 5 "=X,1"))
1321 (clobber (match_scratch:SI 6 "=d,d"))]
1322 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1324 "&& reload_completed"
1326 (neg:SI (match_dup 3)))
1329 (plus:SI (mult:SI (match_dup 2)
1332 (clobber (match_dup 4))
1333 (clobber (match_dup 5))])]
1335 [(set_attr "type" "imadd")
1336 (set_attr "length" "8")])
1338 ;; Patterns generated by the define_peephole2 below.
1340 (define_insn "*macc2"
1341 [(set (match_operand:SI 0 "register_operand" "=l")
1342 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1343 (match_operand:SI 2 "register_operand" "d"))
1345 (set (match_operand:SI 3 "register_operand" "=d")
1346 (plus:SI (mult:SI (match_dup 1)
1349 (clobber (match_scratch:SI 4 "=h"))]
1350 "ISA_HAS_MACC && reload_completed"
1352 [(set_attr "type" "imadd")
1353 (set_attr "mode" "SI")])
1355 (define_insn "*msac2"
1356 [(set (match_operand:SI 0 "register_operand" "=l")
1357 (minus:SI (match_dup 0)
1358 (mult:SI (match_operand:SI 1 "register_operand" "d")
1359 (match_operand:SI 2 "register_operand" "d"))))
1360 (set (match_operand:SI 3 "register_operand" "=d")
1361 (minus:SI (match_dup 0)
1362 (mult:SI (match_dup 1)
1364 (clobber (match_scratch:SI 4 "=h"))]
1365 "ISA_HAS_MSAC && reload_completed"
1367 [(set_attr "type" "imadd")
1368 (set_attr "mode" "SI")])
1370 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1374 ;; Operand 1: macc/msac
1376 ;; Operand 3: GPR (destination)
1379 [(set (match_operand:SI 0 "register_operand")
1380 (match_operand:SI 1 "macc_msac_operand"))
1381 (clobber (match_operand:SI 2 "register_operand"))
1382 (clobber (scratch:SI))])
1383 (set (match_operand:SI 3 "register_operand")
1384 (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1386 [(parallel [(set (match_dup 0)
1390 (clobber (match_dup 2))])]
1393 ;; When we have a three-address multiplication instruction, it should
1394 ;; be faster to do a separate multiply and add, rather than moving
1395 ;; something into LO in order to use a macc instruction.
1397 ;; This peephole needs a scratch register to cater for the case when one
1398 ;; of the multiplication operands is the same as the destination.
1400 ;; Operand 0: GPR (scratch)
1402 ;; Operand 2: GPR (addend)
1403 ;; Operand 3: GPR (destination)
1404 ;; Operand 4: macc/msac
1406 ;; Operand 6: new multiplication
1407 ;; Operand 7: new addition/subtraction
1409 [(match_scratch:SI 0 "d")
1410 (set (match_operand:SI 1 "register_operand")
1411 (match_operand:SI 2 "register_operand"))
1414 [(set (match_operand:SI 3 "register_operand")
1415 (match_operand:SI 4 "macc_msac_operand"))
1416 (clobber (match_operand:SI 5 "register_operand"))
1417 (clobber (match_dup 1))])]
1419 && true_regnum (operands[1]) == LO_REGNUM
1420 && peep2_reg_dead_p (2, operands[1])
1421 && GP_REG_P (true_regnum (operands[3]))"
1422 [(parallel [(set (match_dup 0)
1424 (clobber (match_dup 5))
1425 (clobber (match_dup 1))])
1429 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1430 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1431 operands[2], operands[0]);
1434 ;; Same as above, except LO is the initial target of the macc.
1436 ;; Operand 0: GPR (scratch)
1438 ;; Operand 2: GPR (addend)
1439 ;; Operand 3: macc/msac
1441 ;; Operand 5: GPR (destination)
1442 ;; Operand 6: new multiplication
1443 ;; Operand 7: new addition/subtraction
1445 [(match_scratch:SI 0 "d")
1446 (set (match_operand:SI 1 "register_operand")
1447 (match_operand:SI 2 "register_operand"))
1451 (match_operand:SI 3 "macc_msac_operand"))
1452 (clobber (match_operand:SI 4 "register_operand"))
1453 (clobber (scratch:SI))])
1455 (set (match_operand:SI 5 "register_operand")
1456 (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1457 "ISA_HAS_MUL3 && peep2_reg_dead_p (3, operands[1])"
1458 [(parallel [(set (match_dup 0)
1460 (clobber (match_dup 4))
1461 (clobber (match_dup 1))])
1465 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1466 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1467 operands[2], operands[0]);
1470 (define_insn "*mul_sub_si"
1471 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1472 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1473 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1474 (match_operand:SI 3 "register_operand" "d,d,d"))))
1475 (clobber (match_scratch:SI 4 "=h,h,h"))
1476 (clobber (match_scratch:SI 5 "=X,1,l"))
1477 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1478 "GENERATE_MADD_MSUB"
1483 [(set_attr "type" "imadd")
1484 (set_attr "mode" "SI")
1485 (set_attr "length" "4,8,8")])
1487 ;; Split the above insn if we failed to get LO allocated.
1489 [(set (match_operand:SI 0 "register_operand")
1490 (minus:SI (match_operand:SI 1 "register_operand")
1491 (mult:SI (match_operand:SI 2 "register_operand")
1492 (match_operand:SI 3 "register_operand"))))
1493 (clobber (match_scratch:SI 4))
1494 (clobber (match_scratch:SI 5))
1495 (clobber (match_scratch:SI 6))]
1496 "reload_completed && !TARGET_DEBUG_D_MODE
1497 && GP_REG_P (true_regnum (operands[0]))
1498 && GP_REG_P (true_regnum (operands[1]))"
1499 [(parallel [(set (match_dup 6)
1500 (mult:SI (match_dup 2) (match_dup 3)))
1501 (clobber (match_dup 4))
1502 (clobber (match_dup 5))])
1503 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1506 ;; Splitter to copy result of MSUB to a general register
1508 [(set (match_operand:SI 0 "register_operand")
1509 (minus:SI (match_operand:SI 1 "register_operand")
1510 (mult:SI (match_operand:SI 2 "register_operand")
1511 (match_operand:SI 3 "register_operand"))))
1512 (clobber (match_scratch:SI 4))
1513 (clobber (match_scratch:SI 5))
1514 (clobber (match_scratch:SI 6))]
1515 "reload_completed && !TARGET_DEBUG_D_MODE
1516 && GP_REG_P (true_regnum (operands[0]))
1517 && true_regnum (operands[1]) == LO_REGNUM"
1518 [(parallel [(set (match_dup 1)
1519 (minus:SI (match_dup 1)
1520 (mult:SI (match_dup 2) (match_dup 3))))
1521 (clobber (match_dup 4))
1522 (clobber (match_dup 5))
1523 (clobber (match_dup 6))])
1524 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1527 (define_insn "*muls"
1528 [(set (match_operand:SI 0 "register_operand" "=l,d")
1529 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1530 (match_operand:SI 2 "register_operand" "d,d"))))
1531 (clobber (match_scratch:SI 3 "=h,h"))
1532 (clobber (match_scratch:SI 4 "=X,l"))]
1537 [(set_attr "type" "imul,imul3")
1538 (set_attr "mode" "SI")])
1540 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1542 (define_expand "<u>mulsidi3"
1544 [(set (match_operand:DI 0 "register_operand")
1545 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1546 (any_extend:DI (match_operand:SI 2 "register_operand"))))
1547 (clobber (scratch:DI))
1548 (clobber (scratch:DI))
1549 (clobber (scratch:DI))])]
1550 "!TARGET_64BIT || !TARGET_FIX_R4000"
1554 if (!TARGET_FIX_R4000)
1555 emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1558 emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1564 (define_insn "<u>mulsidi3_32bit_internal"
1565 [(set (match_operand:DI 0 "register_operand" "=x")
1566 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1567 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1568 "!TARGET_64BIT && !TARGET_FIX_R4000 && !TARGET_DSPR2"
1570 [(set_attr "type" "imul")
1571 (set_attr "mode" "SI")])
1573 (define_insn "<u>mulsidi3_32bit_r4000"
1574 [(set (match_operand:DI 0 "register_operand" "=d")
1575 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1576 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1577 (clobber (match_scratch:DI 3 "=x"))]
1578 "!TARGET_64BIT && TARGET_FIX_R4000"
1579 "mult<u>\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1580 [(set_attr "type" "imul")
1581 (set_attr "mode" "SI")
1582 (set_attr "length" "12")])
1584 (define_insn_and_split "*<u>mulsidi3_64bit"
1585 [(set (match_operand:DI 0 "register_operand" "=d")
1586 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1587 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1588 (clobber (match_scratch:DI 3 "=l"))
1589 (clobber (match_scratch:DI 4 "=h"))
1590 (clobber (match_scratch:DI 5 "=d"))]
1591 "TARGET_64BIT && !TARGET_FIX_R4000"
1593 "&& reload_completed"
1597 (mult:SI (match_dup 1)
1601 (mult:DI (any_extend:DI (match_dup 1))
1602 (any_extend:DI (match_dup 2)))
1605 ;; OP5 <- LO, OP0 <- HI
1606 (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1607 (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1611 (ashift:DI (match_dup 5)
1614 (lshiftrt:DI (match_dup 5)
1617 ;; Shift OP0 into place.
1619 (ashift:DI (match_dup 0)
1622 ;; OR the two halves together
1624 (ior:DI (match_dup 0)
1627 [(set_attr "type" "imul")
1628 (set_attr "mode" "SI")
1629 (set_attr "length" "24")])
1631 (define_insn "*<u>mulsidi3_64bit_parts"
1632 [(set (match_operand:DI 0 "register_operand" "=l")
1634 (mult:SI (match_operand:SI 2 "register_operand" "d")
1635 (match_operand:SI 3 "register_operand" "d"))))
1636 (set (match_operand:DI 1 "register_operand" "=h")
1638 (mult:DI (any_extend:DI (match_dup 2))
1639 (any_extend:DI (match_dup 3)))
1641 "TARGET_64BIT && !TARGET_FIX_R4000"
1643 [(set_attr "type" "imul")
1644 (set_attr "mode" "SI")])
1646 ;; Widening multiply with negation.
1647 (define_insn "*muls<u>_di"
1648 [(set (match_operand:DI 0 "register_operand" "=x")
1651 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1652 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1653 "!TARGET_64BIT && ISA_HAS_MULS"
1655 [(set_attr "type" "imul")
1656 (set_attr "mode" "SI")])
1658 (define_insn "<u>msubsidi4"
1659 [(set (match_operand:DI 0 "register_operand" "=ka")
1661 (match_operand:DI 3 "register_operand" "0")
1663 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1664 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1665 "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || TARGET_DSPR2)"
1668 return "msub<u>\t%q0,%1,%2";
1669 else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB)
1670 return "msub<u>\t%1,%2";
1672 return "msac<u>\t$0,%1,%2";
1674 [(set_attr "type" "imadd")
1675 (set_attr "mode" "SI")])
1677 ;; _highpart patterns
1679 (define_expand "<su>mulsi3_highpart"
1680 [(set (match_operand:SI 0 "register_operand")
1683 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1684 (any_extend:DI (match_operand:SI 2 "register_operand")))
1686 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1689 emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1693 emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1698 (define_insn "<su>mulsi3_highpart_internal"
1699 [(set (match_operand:SI 0 "register_operand" "=h")
1702 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1703 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1705 (clobber (match_scratch:SI 3 "=l"))]
1706 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1708 [(set_attr "type" "imul")
1709 (set_attr "mode" "SI")])
1711 (define_insn "<su>mulsi3_highpart_mulhi_internal"
1712 [(set (match_operand:SI 0 "register_operand" "=h,d")
1716 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1717 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1719 (clobber (match_scratch:SI 3 "=l,l"))
1720 (clobber (match_scratch:SI 4 "=X,h"))]
1725 [(set_attr "type" "imul,imul3")
1726 (set_attr "mode" "SI")])
1728 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1729 [(set (match_operand:SI 0 "register_operand" "=h,d")
1734 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1735 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1737 (clobber (match_scratch:SI 3 "=l,l"))
1738 (clobber (match_scratch:SI 4 "=X,h"))]
1742 mulshi<u>\t%0,%1,%2"
1743 [(set_attr "type" "imul,imul3")
1744 (set_attr "mode" "SI")])
1746 ;; Disable unsigned multiplication for -mfix-vr4120. This is for VR4120
1747 ;; errata MD(0), which says that dmultu does not always produce the
1749 (define_insn "<su>muldi3_highpart"
1750 [(set (match_operand:DI 0 "register_operand" "=h")
1754 (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1755 (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1757 (clobber (match_scratch:DI 3 "=l"))]
1758 "TARGET_64BIT && !TARGET_FIX_R4000
1759 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1761 [(set_attr "type" "imul")
1762 (set_attr "mode" "DI")])
1764 ;; The R4650 supports a 32-bit multiply/ 64-bit accumulate
1765 ;; instruction. The HI/LO registers are used as a 64-bit accumulator.
1767 (define_insn "madsi"
1768 [(set (match_operand:SI 0 "register_operand" "+l")
1769 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1770 (match_operand:SI 2 "register_operand" "d"))
1772 (clobber (match_scratch:SI 3 "=h"))]
1775 [(set_attr "type" "imadd")
1776 (set_attr "mode" "SI")])
1778 (define_insn "<u>maddsidi4"
1779 [(set (match_operand:DI 0 "register_operand" "=ka")
1781 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1782 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1783 (match_operand:DI 3 "register_operand" "0")))]
1784 "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || TARGET_DSPR2)
1788 return "mad<u>\t%1,%2";
1789 else if (TARGET_DSPR2)
1790 return "madd<u>\t%q0,%1,%2";
1791 else if (GENERATE_MADD_MSUB || TARGET_MIPS5500)
1792 return "madd<u>\t%1,%2";
1794 /* See comment in *macc. */
1795 return "%[macc<u>\t%@,%1,%2%]";
1797 [(set_attr "type" "imadd")
1798 (set_attr "mode" "SI")])
1800 ;; Floating point multiply accumulate instructions.
1802 (define_insn "*madd<mode>"
1803 [(set (match_operand:ANYF 0 "register_operand" "=f")
1804 (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1805 (match_operand:ANYF 2 "register_operand" "f"))
1806 (match_operand:ANYF 3 "register_operand" "f")))]
1807 "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1808 "madd.<fmt>\t%0,%3,%1,%2"
1809 [(set_attr "type" "fmadd")
1810 (set_attr "mode" "<UNITMODE>")])
1812 (define_insn "*msub<mode>"
1813 [(set (match_operand:ANYF 0 "register_operand" "=f")
1814 (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1815 (match_operand:ANYF 2 "register_operand" "f"))
1816 (match_operand:ANYF 3 "register_operand" "f")))]
1817 "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1818 "msub.<fmt>\t%0,%3,%1,%2"
1819 [(set_attr "type" "fmadd")
1820 (set_attr "mode" "<UNITMODE>")])
1822 (define_insn "*nmadd<mode>"
1823 [(set (match_operand:ANYF 0 "register_operand" "=f")
1824 (neg:ANYF (plus:ANYF
1825 (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1826 (match_operand:ANYF 2 "register_operand" "f"))
1827 (match_operand:ANYF 3 "register_operand" "f"))))]
1828 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1829 && HONOR_SIGNED_ZEROS (<MODE>mode)
1830 && !HONOR_NANS (<MODE>mode)"
1831 "nmadd.<fmt>\t%0,%3,%1,%2"
1832 [(set_attr "type" "fmadd")
1833 (set_attr "mode" "<UNITMODE>")])
1835 (define_insn "*nmadd<mode>_fastmath"
1836 [(set (match_operand:ANYF 0 "register_operand" "=f")
1838 (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
1839 (match_operand:ANYF 2 "register_operand" "f"))
1840 (match_operand:ANYF 3 "register_operand" "f")))]
1841 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1842 && !HONOR_SIGNED_ZEROS (<MODE>mode)
1843 && !HONOR_NANS (<MODE>mode)"
1844 "nmadd.<fmt>\t%0,%3,%1,%2"
1845 [(set_attr "type" "fmadd")
1846 (set_attr "mode" "<UNITMODE>")])
1848 (define_insn "*nmsub<mode>"
1849 [(set (match_operand:ANYF 0 "register_operand" "=f")
1850 (neg:ANYF (minus:ANYF
1851 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1852 (match_operand:ANYF 3 "register_operand" "f"))
1853 (match_operand:ANYF 1 "register_operand" "f"))))]
1854 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1855 && HONOR_SIGNED_ZEROS (<MODE>mode)
1856 && !HONOR_NANS (<MODE>mode)"
1857 "nmsub.<fmt>\t%0,%1,%2,%3"
1858 [(set_attr "type" "fmadd")
1859 (set_attr "mode" "<UNITMODE>")])
1861 (define_insn "*nmsub<mode>_fastmath"
1862 [(set (match_operand:ANYF 0 "register_operand" "=f")
1864 (match_operand:ANYF 1 "register_operand" "f")
1865 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1866 (match_operand:ANYF 3 "register_operand" "f"))))]
1867 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1868 && !HONOR_SIGNED_ZEROS (<MODE>mode)
1869 && !HONOR_NANS (<MODE>mode)"
1870 "nmsub.<fmt>\t%0,%1,%2,%3"
1871 [(set_attr "type" "fmadd")
1872 (set_attr "mode" "<UNITMODE>")])
1875 ;; ....................
1877 ;; DIVISION and REMAINDER
1879 ;; ....................
1882 (define_expand "div<mode>3"
1883 [(set (match_operand:ANYF 0 "register_operand")
1884 (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
1885 (match_operand:ANYF 2 "register_operand")))]
1886 "<divide_condition>"
1888 if (const_1_operand (operands[1], <MODE>mode))
1889 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1890 operands[1] = force_reg (<MODE>mode, operands[1]);
1893 ;; These patterns work around the early SB-1 rev2 core "F1" erratum:
1895 ;; If an mfc1 or dmfc1 happens to access the floating point register
1896 ;; file at the same time a long latency operation (div, sqrt, recip,
1897 ;; sqrt) iterates an intermediate result back through the floating
1898 ;; point register file bypass, then instead returning the correct
1899 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1900 ;; result of the long latency operation.
1902 ;; The workaround is to insert an unconditional 'mov' from/to the
1903 ;; long latency op destination register.
1905 (define_insn "*div<mode>3"
1906 [(set (match_operand:ANYF 0 "register_operand" "=f")
1907 (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
1908 (match_operand:ANYF 2 "register_operand" "f")))]
1909 "<divide_condition>"
1912 return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
1914 return "div.<fmt>\t%0,%1,%2";
1916 [(set_attr "type" "fdiv")
1917 (set_attr "mode" "<UNITMODE>")
1918 (set (attr "length")
1919 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1923 (define_insn "*recip<mode>3"
1924 [(set (match_operand:ANYF 0 "register_operand" "=f")
1925 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1926 (match_operand:ANYF 2 "register_operand" "f")))]
1927 "<recip_condition> && flag_unsafe_math_optimizations"
1930 return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1932 return "recip.<fmt>\t%0,%2";
1934 [(set_attr "type" "frdiv")
1935 (set_attr "mode" "<UNITMODE>")
1936 (set (attr "length")
1937 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1941 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
1942 ;; with negative operands. We use special libgcc functions instead.
1943 (define_insn "divmod<mode>4"
1944 [(set (match_operand:GPR 0 "register_operand" "=l")
1945 (div:GPR (match_operand:GPR 1 "register_operand" "d")
1946 (match_operand:GPR 2 "register_operand" "d")))
1947 (set (match_operand:GPR 3 "register_operand" "=h")
1948 (mod:GPR (match_dup 1)
1950 "!TARGET_FIX_VR4120"
1951 { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1952 [(set_attr "type" "idiv")
1953 (set_attr "mode" "<MODE>")])
1955 (define_insn "udivmod<mode>4"
1956 [(set (match_operand:GPR 0 "register_operand" "=l")
1957 (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1958 (match_operand:GPR 2 "register_operand" "d")))
1959 (set (match_operand:GPR 3 "register_operand" "=h")
1960 (umod:GPR (match_dup 1)
1963 { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1964 [(set_attr "type" "idiv")
1965 (set_attr "mode" "<MODE>")])
1968 ;; ....................
1972 ;; ....................
1974 ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
1975 ;; "*div[sd]f3" comment for details).
1977 (define_insn "sqrt<mode>2"
1978 [(set (match_operand:ANYF 0 "register_operand" "=f")
1979 (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1983 return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
1985 return "sqrt.<fmt>\t%0,%1";
1987 [(set_attr "type" "fsqrt")
1988 (set_attr "mode" "<UNITMODE>")
1989 (set (attr "length")
1990 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1994 (define_insn "*rsqrt<mode>a"
1995 [(set (match_operand:ANYF 0 "register_operand" "=f")
1996 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1997 (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
1998 "<recip_condition> && flag_unsafe_math_optimizations"
2001 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2003 return "rsqrt.<fmt>\t%0,%2";
2005 [(set_attr "type" "frsqrt")
2006 (set_attr "mode" "<UNITMODE>")
2007 (set (attr "length")
2008 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2012 (define_insn "*rsqrt<mode>b"
2013 [(set (match_operand:ANYF 0 "register_operand" "=f")
2014 (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2015 (match_operand:ANYF 2 "register_operand" "f"))))]
2016 "<recip_condition> && flag_unsafe_math_optimizations"
2019 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2021 return "rsqrt.<fmt>\t%0,%2";
2023 [(set_attr "type" "frsqrt")
2024 (set_attr "mode" "<UNITMODE>")
2025 (set (attr "length")
2026 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2031 ;; ....................
2035 ;; ....................
2037 ;; Do not use the integer abs macro instruction, since that signals an
2038 ;; exception on -2147483648 (sigh).
2040 ;; abs.fmt is an arithmetic instruction and treats all NaN inputs as
2041 ;; invalid; it does not clear their sign bits. We therefore can't use
2042 ;; abs.fmt if the signs of NaNs matter.
2044 (define_insn "abs<mode>2"
2045 [(set (match_operand:ANYF 0 "register_operand" "=f")
2046 (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2047 "!HONOR_NANS (<MODE>mode)"
2049 [(set_attr "type" "fabs")
2050 (set_attr "mode" "<UNITMODE>")])
2053 ;; ...................
2055 ;; Count leading zeroes.
2057 ;; ...................
2060 (define_insn "clz<mode>2"
2061 [(set (match_operand:GPR 0 "register_operand" "=d")
2062 (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2065 [(set_attr "type" "clz")
2066 (set_attr "mode" "<MODE>")])
2069 ;; ....................
2071 ;; NEGATION and ONE'S COMPLEMENT
2073 ;; ....................
2075 (define_insn "negsi2"
2076 [(set (match_operand:SI 0 "register_operand" "=d")
2077 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2081 return "neg\t%0,%1";
2083 return "subu\t%0,%.,%1";
2085 [(set_attr "type" "arith")
2086 (set_attr "mode" "SI")])
2088 (define_insn "negdi2"
2089 [(set (match_operand:DI 0 "register_operand" "=d")
2090 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2091 "TARGET_64BIT && !TARGET_MIPS16"
2093 [(set_attr "type" "arith")
2094 (set_attr "mode" "DI")])
2096 ;; neg.fmt is an arithmetic instruction and treats all NaN inputs as
2097 ;; invalid; it does not flip their sign bit. We therefore can't use
2098 ;; neg.fmt if the signs of NaNs matter.
2100 (define_insn "neg<mode>2"
2101 [(set (match_operand:ANYF 0 "register_operand" "=f")
2102 (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2103 "!HONOR_NANS (<MODE>mode)"
2105 [(set_attr "type" "fneg")
2106 (set_attr "mode" "<UNITMODE>")])
2108 (define_insn "one_cmpl<mode>2"
2109 [(set (match_operand:GPR 0 "register_operand" "=d")
2110 (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2114 return "not\t%0,%1";
2116 return "nor\t%0,%.,%1";
2118 [(set_attr "type" "logical")
2119 (set_attr "mode" "<MODE>")])
2122 ;; ....................
2126 ;; ....................
2129 ;; Many of these instructions use trivial define_expands, because we
2130 ;; want to use a different set of constraints when TARGET_MIPS16.
2132 (define_expand "and<mode>3"
2133 [(set (match_operand:GPR 0 "register_operand")
2134 (and:GPR (match_operand:GPR 1 "register_operand")
2135 (match_operand:GPR 2 "uns_arith_operand")))]
2139 operands[2] = force_reg (<MODE>mode, operands[2]);
2142 (define_insn "*and<mode>3"
2143 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2144 (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2145 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2150 [(set_attr "type" "logical")
2151 (set_attr "mode" "<MODE>")])
2153 (define_insn "*and<mode>3_mips16"
2154 [(set (match_operand:GPR 0 "register_operand" "=d")
2155 (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2156 (match_operand:GPR 2 "register_operand" "d")))]
2159 [(set_attr "type" "logical")
2160 (set_attr "mode" "<MODE>")])
2162 (define_expand "ior<mode>3"
2163 [(set (match_operand:GPR 0 "register_operand")
2164 (ior:GPR (match_operand:GPR 1 "register_operand")
2165 (match_operand:GPR 2 "uns_arith_operand")))]
2169 operands[2] = force_reg (<MODE>mode, operands[2]);
2172 (define_insn "*ior<mode>3"
2173 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2174 (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2175 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2180 [(set_attr "type" "logical")
2181 (set_attr "mode" "<MODE>")])
2183 (define_insn "*ior<mode>3_mips16"
2184 [(set (match_operand:GPR 0 "register_operand" "=d")
2185 (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2186 (match_operand:GPR 2 "register_operand" "d")))]
2189 [(set_attr "type" "logical")
2190 (set_attr "mode" "<MODE>")])
2192 (define_expand "xor<mode>3"
2193 [(set (match_operand:GPR 0 "register_operand")
2194 (xor:GPR (match_operand:GPR 1 "register_operand")
2195 (match_operand:GPR 2 "uns_arith_operand")))]
2200 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2201 (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2202 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2207 [(set_attr "type" "logical")
2208 (set_attr "mode" "<MODE>")])
2211 [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2212 (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2213 (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2219 [(set_attr "type" "logical,arith,arith")
2220 (set_attr "mode" "<MODE>")
2221 (set_attr_alternative "length"
2223 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2228 (define_insn "*nor<mode>3"
2229 [(set (match_operand:GPR 0 "register_operand" "=d")
2230 (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2231 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2234 [(set_attr "type" "logical")
2235 (set_attr "mode" "<MODE>")])
2238 ;; ....................
2242 ;; ....................
2246 (define_insn "truncdfsf2"
2247 [(set (match_operand:SF 0 "register_operand" "=f")
2248 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2249 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2251 [(set_attr "type" "fcvt")
2252 (set_attr "cnv_mode" "D2S")
2253 (set_attr "mode" "SF")])
2255 ;; Integer truncation patterns. Truncating SImode values to smaller
2256 ;; modes is a no-op, as it is for most other GCC ports. Truncating
2257 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2258 ;; need to make sure that the lower 32 bits are properly sign-extended
2259 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
2260 ;; smaller than SImode is equivalent to two separate truncations:
2263 ;; DI ---> HI == DI ---> SI ---> HI
2264 ;; DI ---> QI == DI ---> SI ---> QI
2266 ;; Step A needs a real instruction but step B does not.
2268 (define_insn "truncdisi2"
2269 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2270 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2275 [(set_attr "type" "shift,store")
2276 (set_attr "mode" "SI")
2277 (set_attr "extended_mips16" "yes,*")])
2279 (define_insn "truncdihi2"
2280 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2281 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2286 [(set_attr "type" "shift,store")
2287 (set_attr "mode" "SI")
2288 (set_attr "extended_mips16" "yes,*")])
2290 (define_insn "truncdiqi2"
2291 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2292 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2297 [(set_attr "type" "shift,store")
2298 (set_attr "mode" "SI")
2299 (set_attr "extended_mips16" "yes,*")])
2301 ;; Combiner patterns to optimize shift/truncate combinations.
2304 [(set (match_operand:SI 0 "register_operand" "=d")
2306 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2307 (match_operand:DI 2 "const_arith_operand" ""))))]
2308 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2310 [(set_attr "type" "shift")
2311 (set_attr "mode" "SI")])
2314 [(set (match_operand:SI 0 "register_operand" "=d")
2315 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2317 "TARGET_64BIT && !TARGET_MIPS16"
2319 [(set_attr "type" "shift")
2320 (set_attr "mode" "SI")])
2323 ;; Combiner patterns for truncate/sign_extend combinations. They use
2324 ;; the shift/truncate patterns above.
2326 (define_insn_and_split ""
2327 [(set (match_operand:SI 0 "register_operand" "=d")
2329 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2330 "TARGET_64BIT && !TARGET_MIPS16"
2332 "&& reload_completed"
2334 (ashift:DI (match_dup 1)
2337 (truncate:SI (ashiftrt:DI (match_dup 2)
2339 { operands[2] = gen_lowpart (DImode, operands[0]); })
2341 (define_insn_and_split ""
2342 [(set (match_operand:SI 0 "register_operand" "=d")
2344 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2345 "TARGET_64BIT && !TARGET_MIPS16"
2347 "&& reload_completed"
2349 (ashift:DI (match_dup 1)
2352 (truncate:SI (ashiftrt:DI (match_dup 2)
2354 { operands[2] = gen_lowpart (DImode, operands[0]); })
2357 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2360 [(set (match_operand:SI 0 "register_operand" "=d")
2361 (zero_extend:SI (truncate:HI
2362 (match_operand:DI 1 "register_operand" "d"))))]
2363 "TARGET_64BIT && !TARGET_MIPS16"
2364 "andi\t%0,%1,0xffff"
2365 [(set_attr "type" "logical")
2366 (set_attr "mode" "SI")])
2369 [(set (match_operand:SI 0 "register_operand" "=d")
2370 (zero_extend:SI (truncate:QI
2371 (match_operand:DI 1 "register_operand" "d"))))]
2372 "TARGET_64BIT && !TARGET_MIPS16"
2374 [(set_attr "type" "logical")
2375 (set_attr "mode" "SI")])
2378 [(set (match_operand:HI 0 "register_operand" "=d")
2379 (zero_extend:HI (truncate:QI
2380 (match_operand:DI 1 "register_operand" "d"))))]
2381 "TARGET_64BIT && !TARGET_MIPS16"
2383 [(set_attr "type" "logical")
2384 (set_attr "mode" "HI")])
2387 ;; ....................
2391 ;; ....................
2395 (define_insn_and_split "zero_extendsidi2"
2396 [(set (match_operand:DI 0 "register_operand" "=d,d")
2397 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
2402 "&& reload_completed && REG_P (operands[1])"
2404 (ashift:DI (match_dup 1) (const_int 32)))
2406 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2407 { operands[1] = gen_lowpart (DImode, operands[1]); }
2408 [(set_attr "type" "multi,load")
2409 (set_attr "mode" "DI")
2410 (set_attr "length" "8,*")])
2412 ;; Combine is not allowed to convert this insn into a zero_extendsidi2
2413 ;; because of TRULY_NOOP_TRUNCATION.
2415 (define_insn_and_split "*clear_upper32"
2416 [(set (match_operand:DI 0 "register_operand" "=d,d")
2417 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
2418 (const_int 4294967295)))]
2421 if (which_alternative == 0)
2424 operands[1] = gen_lowpart (SImode, operands[1]);
2425 return "lwu\t%0,%1";
2427 "&& reload_completed && REG_P (operands[1])"
2429 (ashift:DI (match_dup 1) (const_int 32)))
2431 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2433 [(set_attr "type" "multi,load")
2434 (set_attr "mode" "DI")
2435 (set_attr "length" "8,*")])
2437 (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
2438 [(set (match_operand:GPR 0 "register_operand")
2439 (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2442 if (TARGET_MIPS16 && !GENERATE_MIPS16E
2443 && !memory_operand (operands[1], <SHORT:MODE>mode))
2445 emit_insn (gen_and<GPR:mode>3 (operands[0],
2446 gen_lowpart (<GPR:MODE>mode, operands[1]),
2447 force_reg (<GPR:MODE>mode,
2448 GEN_INT (<SHORT:mask>))));
2453 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
2454 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2456 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2459 andi\t%0,%1,<SHORT:mask>
2460 l<SHORT:size>u\t%0,%1"
2461 [(set_attr "type" "logical,load")
2462 (set_attr "mode" "<GPR:MODE>")])
2464 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e"
2465 [(set (match_operand:GPR 0 "register_operand" "=d")
2466 (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
2468 "ze<SHORT:size>\t%0"
2469 [(set_attr "type" "arith")
2470 (set_attr "mode" "<GPR:MODE>")])
2472 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16"
2473 [(set (match_operand:GPR 0 "register_operand" "=d")
2474 (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
2476 "l<SHORT:size>u\t%0,%1"
2477 [(set_attr "type" "load")
2478 (set_attr "mode" "<GPR:MODE>")])
2480 (define_expand "zero_extendqihi2"
2481 [(set (match_operand:HI 0 "register_operand")
2482 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2485 if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
2487 emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
2493 (define_insn "*zero_extendqihi2"
2494 [(set (match_operand:HI 0 "register_operand" "=d,d")
2495 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2500 [(set_attr "type" "logical,load")
2501 (set_attr "mode" "HI")])
2503 (define_insn "*zero_extendqihi2_mips16"
2504 [(set (match_operand:HI 0 "register_operand" "=d")
2505 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2508 [(set_attr "type" "load")
2509 (set_attr "mode" "HI")])
2512 ;; ....................
2516 ;; ....................
2519 ;; Those for integer source operand are ordered widest source type first.
2521 ;; When TARGET_64BIT, all SImode integer registers should already be in
2522 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
2523 ;; therefore get rid of register->register instructions if we constrain
2524 ;; the source to be in the same register as the destination.
2526 ;; The register alternative has type "arith" so that the pre-reload
2527 ;; scheduler will treat it as a move. This reflects what happens if
2528 ;; the register alternative needs a reload.
2529 (define_insn_and_split "extendsidi2"
2530 [(set (match_operand:DI 0 "register_operand" "=d,d")
2531 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2536 "&& reload_completed && register_operand (operands[1], VOIDmode)"
2539 emit_note (NOTE_INSN_DELETED);
2542 [(set_attr "type" "arith,load")
2543 (set_attr "mode" "DI")])
2545 (define_expand "extend<SHORT:mode><GPR:mode>2"
2546 [(set (match_operand:GPR 0 "register_operand")
2547 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2550 (define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e"
2551 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2552 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
2556 l<SHORT:size>\t%0,%1"
2557 [(set_attr "type" "signext,load")
2558 (set_attr "mode" "<GPR:MODE>")])
2560 (define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
2561 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2563 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2564 "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2567 l<SHORT:size>\t%0,%1"
2568 "&& reload_completed && REG_P (operands[1])"
2569 [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
2570 (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
2572 operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
2573 operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
2574 - GET_MODE_BITSIZE (<SHORT:MODE>mode));
2576 [(set_attr "type" "arith,load")
2577 (set_attr "mode" "<GPR:MODE>")
2578 (set_attr "length" "8,*")])
2580 (define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
2581 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2583 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2586 se<SHORT:size>\t%0,%1
2587 l<SHORT:size>\t%0,%1"
2588 [(set_attr "type" "signext,load")
2589 (set_attr "mode" "<GPR:MODE>")])
2591 (define_expand "extendqihi2"
2592 [(set (match_operand:HI 0 "register_operand")
2593 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2596 (define_insn "*extendqihi2_mips16e"
2597 [(set (match_operand:HI 0 "register_operand" "=d,d")
2598 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,m")))]
2603 [(set_attr "type" "signext,load")
2604 (set_attr "mode" "SI")])
2606 (define_insn_and_split "*extendqihi2"
2607 [(set (match_operand:HI 0 "register_operand" "=d,d")
2609 (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2610 "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2614 "&& reload_completed && REG_P (operands[1])"
2615 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2616 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
2618 operands[0] = gen_lowpart (SImode, operands[0]);
2619 operands[1] = gen_lowpart (SImode, operands[1]);
2620 operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
2621 - GET_MODE_BITSIZE (QImode));
2623 [(set_attr "type" "multi,load")
2624 (set_attr "mode" "SI")
2625 (set_attr "length" "8,*")])
2627 (define_insn "*extendqihi2_seb"
2628 [(set (match_operand:HI 0 "register_operand" "=d,d")
2630 (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2635 [(set_attr "type" "signext,load")
2636 (set_attr "mode" "SI")])
2638 (define_insn "extendsfdf2"
2639 [(set (match_operand:DF 0 "register_operand" "=f")
2640 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2641 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2643 [(set_attr "type" "fcvt")
2644 (set_attr "cnv_mode" "S2D")
2645 (set_attr "mode" "DF")])
2648 ;; ....................
2652 ;; ....................
2654 (define_expand "fix_truncdfsi2"
2655 [(set (match_operand:SI 0 "register_operand")
2656 (fix:SI (match_operand:DF 1 "register_operand")))]
2657 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2659 if (!ISA_HAS_TRUNC_W)
2661 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2666 (define_insn "fix_truncdfsi2_insn"
2667 [(set (match_operand:SI 0 "register_operand" "=f")
2668 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2669 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2671 [(set_attr "type" "fcvt")
2672 (set_attr "mode" "DF")
2673 (set_attr "cnv_mode" "D2I")
2674 (set_attr "length" "4")])
2676 (define_insn "fix_truncdfsi2_macro"
2677 [(set (match_operand:SI 0 "register_operand" "=f")
2678 (fix:SI (match_operand:DF 1 "register_operand" "f")))
2679 (clobber (match_scratch:DF 2 "=d"))]
2680 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2683 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2685 return "trunc.w.d %0,%1,%2";
2687 [(set_attr "type" "fcvt")
2688 (set_attr "mode" "DF")
2689 (set_attr "cnv_mode" "D2I")
2690 (set_attr "length" "36")])
2692 (define_expand "fix_truncsfsi2"
2693 [(set (match_operand:SI 0 "register_operand")
2694 (fix:SI (match_operand:SF 1 "register_operand")))]
2697 if (!ISA_HAS_TRUNC_W)
2699 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2704 (define_insn "fix_truncsfsi2_insn"
2705 [(set (match_operand:SI 0 "register_operand" "=f")
2706 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2707 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2709 [(set_attr "type" "fcvt")
2710 (set_attr "mode" "SF")
2711 (set_attr "cnv_mode" "S2I")
2712 (set_attr "length" "4")])
2714 (define_insn "fix_truncsfsi2_macro"
2715 [(set (match_operand:SI 0 "register_operand" "=f")
2716 (fix:SI (match_operand:SF 1 "register_operand" "f")))
2717 (clobber (match_scratch:SF 2 "=d"))]
2718 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2721 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2723 return "trunc.w.s %0,%1,%2";
2725 [(set_attr "type" "fcvt")
2726 (set_attr "mode" "SF")
2727 (set_attr "cnv_mode" "S2I")
2728 (set_attr "length" "36")])
2731 (define_insn "fix_truncdfdi2"
2732 [(set (match_operand:DI 0 "register_operand" "=f")
2733 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2734 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2736 [(set_attr "type" "fcvt")
2737 (set_attr "mode" "DF")
2738 (set_attr "cnv_mode" "D2I")
2739 (set_attr "length" "4")])
2742 (define_insn "fix_truncsfdi2"
2743 [(set (match_operand:DI 0 "register_operand" "=f")
2744 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2745 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2747 [(set_attr "type" "fcvt")
2748 (set_attr "mode" "SF")
2749 (set_attr "cnv_mode" "S2I")
2750 (set_attr "length" "4")])
2753 (define_insn "floatsidf2"
2754 [(set (match_operand:DF 0 "register_operand" "=f")
2755 (float:DF (match_operand:SI 1 "register_operand" "f")))]
2756 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2758 [(set_attr "type" "fcvt")
2759 (set_attr "mode" "DF")
2760 (set_attr "cnv_mode" "I2D")
2761 (set_attr "length" "4")])
2764 (define_insn "floatdidf2"
2765 [(set (match_operand:DF 0 "register_operand" "=f")
2766 (float:DF (match_operand:DI 1 "register_operand" "f")))]
2767 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2769 [(set_attr "type" "fcvt")
2770 (set_attr "mode" "DF")
2771 (set_attr "cnv_mode" "I2D")
2772 (set_attr "length" "4")])
2775 (define_insn "floatsisf2"
2776 [(set (match_operand:SF 0 "register_operand" "=f")
2777 (float:SF (match_operand:SI 1 "register_operand" "f")))]
2780 [(set_attr "type" "fcvt")
2781 (set_attr "mode" "SF")
2782 (set_attr "cnv_mode" "I2S")
2783 (set_attr "length" "4")])
2786 (define_insn "floatdisf2"
2787 [(set (match_operand:SF 0 "register_operand" "=f")
2788 (float:SF (match_operand:DI 1 "register_operand" "f")))]
2789 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2791 [(set_attr "type" "fcvt")
2792 (set_attr "mode" "SF")
2793 (set_attr "cnv_mode" "I2S")
2794 (set_attr "length" "4")])
2797 (define_expand "fixuns_truncdfsi2"
2798 [(set (match_operand:SI 0 "register_operand")
2799 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2800 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2802 rtx reg1 = gen_reg_rtx (DFmode);
2803 rtx reg2 = gen_reg_rtx (DFmode);
2804 rtx reg3 = gen_reg_rtx (SImode);
2805 rtx label1 = gen_label_rtx ();
2806 rtx label2 = gen_label_rtx ();
2807 REAL_VALUE_TYPE offset;
2809 real_2expN (&offset, 31, DFmode);
2811 if (reg1) /* Turn off complaints about unreached code. */
2813 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2814 do_pending_stack_adjust ();
2816 emit_insn (gen_cmpdf (operands[1], reg1));
2817 emit_jump_insn (gen_bge (label1));
2819 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2820 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2821 gen_rtx_LABEL_REF (VOIDmode, label2)));
2824 emit_label (label1);
2825 mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2826 mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
2827 (BITMASK_HIGH, SImode)));
2829 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2830 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2832 emit_label (label2);
2834 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2835 fields, and can't be used for REG_NOTES anyway). */
2836 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2842 (define_expand "fixuns_truncdfdi2"
2843 [(set (match_operand:DI 0 "register_operand")
2844 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
2845 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2847 rtx reg1 = gen_reg_rtx (DFmode);
2848 rtx reg2 = gen_reg_rtx (DFmode);
2849 rtx reg3 = gen_reg_rtx (DImode);
2850 rtx label1 = gen_label_rtx ();
2851 rtx label2 = gen_label_rtx ();
2852 REAL_VALUE_TYPE offset;
2854 real_2expN (&offset, 63, DFmode);
2856 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2857 do_pending_stack_adjust ();
2859 emit_insn (gen_cmpdf (operands[1], reg1));
2860 emit_jump_insn (gen_bge (label1));
2862 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2863 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2864 gen_rtx_LABEL_REF (VOIDmode, label2)));
2867 emit_label (label1);
2868 mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2869 mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
2870 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2872 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2873 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2875 emit_label (label2);
2877 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2878 fields, and can't be used for REG_NOTES anyway). */
2879 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2884 (define_expand "fixuns_truncsfsi2"
2885 [(set (match_operand:SI 0 "register_operand")
2886 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
2889 rtx reg1 = gen_reg_rtx (SFmode);
2890 rtx reg2 = gen_reg_rtx (SFmode);
2891 rtx reg3 = gen_reg_rtx (SImode);
2892 rtx label1 = gen_label_rtx ();
2893 rtx label2 = gen_label_rtx ();
2894 REAL_VALUE_TYPE offset;
2896 real_2expN (&offset, 31, SFmode);
2898 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2899 do_pending_stack_adjust ();
2901 emit_insn (gen_cmpsf (operands[1], reg1));
2902 emit_jump_insn (gen_bge (label1));
2904 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2905 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2906 gen_rtx_LABEL_REF (VOIDmode, label2)));
2909 emit_label (label1);
2910 mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2911 mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
2912 (BITMASK_HIGH, SImode)));
2914 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2915 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2917 emit_label (label2);
2919 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2920 fields, and can't be used for REG_NOTES anyway). */
2921 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2926 (define_expand "fixuns_truncsfdi2"
2927 [(set (match_operand:DI 0 "register_operand")
2928 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
2929 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2931 rtx reg1 = gen_reg_rtx (SFmode);
2932 rtx reg2 = gen_reg_rtx (SFmode);
2933 rtx reg3 = gen_reg_rtx (DImode);
2934 rtx label1 = gen_label_rtx ();
2935 rtx label2 = gen_label_rtx ();
2936 REAL_VALUE_TYPE offset;
2938 real_2expN (&offset, 63, SFmode);
2940 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2941 do_pending_stack_adjust ();
2943 emit_insn (gen_cmpsf (operands[1], reg1));
2944 emit_jump_insn (gen_bge (label1));
2946 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
2947 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2948 gen_rtx_LABEL_REF (VOIDmode, label2)));
2951 emit_label (label1);
2952 mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2953 mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
2954 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2956 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
2957 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2959 emit_label (label2);
2961 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2962 fields, and can't be used for REG_NOTES anyway). */
2963 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2968 ;; ....................
2972 ;; ....................
2974 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
2976 (define_expand "extv"
2977 [(set (match_operand 0 "register_operand")
2978 (sign_extract (match_operand:QI 1 "memory_operand")
2979 (match_operand 2 "immediate_operand")
2980 (match_operand 3 "immediate_operand")))]
2983 if (mips_expand_unaligned_load (operands[0], operands[1],
2984 INTVAL (operands[2]),
2985 INTVAL (operands[3])))
2991 (define_expand "extzv"
2992 [(set (match_operand 0 "register_operand")
2993 (zero_extract (match_operand 1 "nonimmediate_operand")
2994 (match_operand 2 "immediate_operand")
2995 (match_operand 3 "immediate_operand")))]
2998 if (mips_expand_unaligned_load (operands[0], operands[1],
2999 INTVAL (operands[2]),
3000 INTVAL (operands[3])))
3002 else if (mips_use_ins_ext_p (operands[1], operands[2], operands[3]))
3004 if (GET_MODE (operands[0]) == DImode)
3005 emit_insn (gen_extzvdi (operands[0], operands[1], operands[2],
3008 emit_insn (gen_extzvsi (operands[0], operands[1], operands[2],
3016 (define_insn "extzv<mode>"
3017 [(set (match_operand:GPR 0 "register_operand" "=d")
3018 (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
3019 (match_operand:SI 2 "immediate_operand" "I")
3020 (match_operand:SI 3 "immediate_operand" "I")))]
3021 "mips_use_ins_ext_p (operands[1], operands[2], operands[3])"
3022 "<d>ext\t%0,%1,%3,%2"
3023 [(set_attr "type" "arith")
3024 (set_attr "mode" "<MODE>")])
3027 (define_expand "insv"
3028 [(set (zero_extract (match_operand 0 "nonimmediate_operand")
3029 (match_operand 1 "immediate_operand")
3030 (match_operand 2 "immediate_operand"))
3031 (match_operand 3 "reg_or_0_operand"))]
3034 if (mips_expand_unaligned_store (operands[0], operands[3],
3035 INTVAL (operands[1]),
3036 INTVAL (operands[2])))
3038 else if (mips_use_ins_ext_p (operands[0], operands[1], operands[2]))
3040 if (GET_MODE (operands[0]) == DImode)
3041 emit_insn (gen_insvdi (operands[0], operands[1], operands[2],
3044 emit_insn (gen_insvsi (operands[0], operands[1], operands[2],
3052 (define_insn "insv<mode>"
3053 [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
3054 (match_operand:SI 1 "immediate_operand" "I")
3055 (match_operand:SI 2 "immediate_operand" "I"))
3056 (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
3057 "mips_use_ins_ext_p (operands[0], operands[1], operands[2])"
3058 "<d>ins\t%0,%z3,%2,%1"
3059 [(set_attr "type" "arith")
3060 (set_attr "mode" "<MODE>")])
3062 ;; Unaligned word moves generated by the bit field patterns.
3064 ;; As far as the rtl is concerned, both the left-part and right-part
3065 ;; instructions can access the whole field. However, the real operand
3066 ;; refers to just the first or the last byte (depending on endianness).
3067 ;; We therefore use two memory operands to each instruction, one to
3068 ;; describe the rtl effect and one to use in the assembly output.
3070 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3071 ;; This allows us to use the standard length calculations for the "load"
3072 ;; and "store" type attributes.
3074 (define_insn "mov_<load>l"
3075 [(set (match_operand:GPR 0 "register_operand" "=d")
3076 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3077 (match_operand:QI 2 "memory_operand" "m")]
3079 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
3081 [(set_attr "type" "load")
3082 (set_attr "mode" "<MODE>")])
3084 (define_insn "mov_<load>r"
3085 [(set (match_operand:GPR 0 "register_operand" "=d")
3086 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3087 (match_operand:QI 2 "memory_operand" "m")
3088 (match_operand:GPR 3 "register_operand" "0")]
3089 UNSPEC_LOAD_RIGHT))]
3090 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
3092 [(set_attr "type" "load")
3093 (set_attr "mode" "<MODE>")])
3095 (define_insn "mov_<store>l"
3096 [(set (match_operand:BLK 0 "memory_operand" "=m")
3097 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3098 (match_operand:QI 2 "memory_operand" "m")]
3099 UNSPEC_STORE_LEFT))]
3100 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3102 [(set_attr "type" "store")
3103 (set_attr "mode" "<MODE>")])
3105 (define_insn "mov_<store>r"
3106 [(set (match_operand:BLK 0 "memory_operand" "+m")
3107 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3108 (match_operand:QI 2 "memory_operand" "m")
3110 UNSPEC_STORE_RIGHT))]
3111 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3113 [(set_attr "type" "store")
3114 (set_attr "mode" "<MODE>")])
3116 ;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE.
3117 ;; The required value is:
3119 ;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3121 ;; which translates to:
3123 ;; lui op0,%highest(op1)
3124 ;; daddiu op0,op0,%higher(op1)
3126 ;; daddiu op0,op0,%hi(op1)
3129 ;; The split is deferred until after flow2 to allow the peephole2 below
3131 (define_insn_and_split "*lea_high64"
3132 [(set (match_operand:DI 0 "register_operand" "=d")
3133 (high:DI (match_operand:DI 1 "absolute_symbolic_operand" "")))]
3134 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3136 "&& epilogue_completed"
3137 [(set (match_dup 0) (high:DI (match_dup 2)))
3138 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3139 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3140 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3141 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3143 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3144 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3146 [(set_attr "length" "20")])
3148 ;; Use a scratch register to reduce the latency of the above pattern
3149 ;; on superscalar machines. The optimized sequence is:
3151 ;; lui op1,%highest(op2)
3153 ;; daddiu op1,op1,%higher(op2)
3155 ;; daddu op1,op1,op0
3157 [(set (match_operand:DI 1 "register_operand")
3158 (high:DI (match_operand:DI 2 "absolute_symbolic_operand")))
3159 (match_scratch:DI 0 "d")]
3160 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3161 [(set (match_dup 1) (high:DI (match_dup 3)))
3162 (set (match_dup 0) (high:DI (match_dup 4)))
3163 (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
3164 (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
3165 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
3167 operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
3168 operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
3171 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3172 ;; SYMBOL_ABSOLUTE X will take 6 cycles. This next pattern allows combine
3173 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3174 ;; used once. We can then use the sequence:
3176 ;; lui op0,%highest(op1)
3178 ;; daddiu op0,op0,%higher(op1)
3179 ;; daddiu op2,op2,%lo(op1)
3181 ;; daddu op0,op0,op2
3183 ;; which takes 4 cycles on most superscalar targets.
3184 (define_insn_and_split "*lea64"
3185 [(set (match_operand:DI 0 "register_operand" "=d")
3186 (match_operand:DI 1 "absolute_symbolic_operand" ""))
3187 (clobber (match_scratch:DI 2 "=&d"))]
3188 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3190 "&& reload_completed"
3191 [(set (match_dup 0) (high:DI (match_dup 3)))
3192 (set (match_dup 2) (high:DI (match_dup 4)))
3193 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3194 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3195 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3196 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3198 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3199 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3201 [(set_attr "length" "24")])
3203 ;; Split HIGHs into:
3208 ;; on MIPS16 targets.
3210 [(set (match_operand:SI 0 "register_operand" "=d")
3211 (high:SI (match_operand:SI 1 "absolute_symbolic_operand" "")))]
3212 "TARGET_MIPS16 && reload_completed"
3213 [(set (match_dup 0) (match_dup 2))
3214 (set (match_dup 0) (ashift:SI (match_dup 0) (const_int 16)))]
3216 operands[2] = mips_unspec_address (operands[1], SYMBOL_32_HIGH);
3219 ;; Insns to fetch a symbol from a big GOT.
3221 (define_insn_and_split "*xgot_hi<mode>"
3222 [(set (match_operand:P 0 "register_operand" "=d")
3223 (high:P (match_operand:P 1 "got_disp_operand" "")))]
3224 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3226 "&& reload_completed"
3227 [(set (match_dup 0) (high:P (match_dup 2)))
3228 (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3230 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
3231 operands[3] = pic_offset_table_rtx;
3233 [(set_attr "got" "xgot_high")
3234 (set_attr "mode" "<MODE>")])
3236 (define_insn_and_split "*xgot_lo<mode>"
3237 [(set (match_operand:P 0 "register_operand" "=d")
3238 (lo_sum:P (match_operand:P 1 "register_operand" "d")
3239 (match_operand:P 2 "got_disp_operand" "")))]
3240 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3242 "&& reload_completed"
3244 (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3245 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_DISP); }
3246 [(set_attr "got" "load")
3247 (set_attr "mode" "<MODE>")])
3249 ;; Insns to fetch a symbol from a normal GOT.
3251 (define_insn_and_split "*got_disp<mode>"
3252 [(set (match_operand:P 0 "register_operand" "=d")
3253 (match_operand:P 1 "got_disp_operand" ""))]
3254 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3256 "&& reload_completed"
3258 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3260 operands[2] = pic_offset_table_rtx;
3261 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
3263 [(set_attr "got" "load")
3264 (set_attr "mode" "<MODE>")])
3266 ;; Insns for loading the "page" part of a page/ofst address from the GOT.
3268 (define_insn_and_split "*got_page<mode>"
3269 [(set (match_operand:P 0 "register_operand" "=d")
3270 (high:P (match_operand:P 1 "got_page_ofst_operand" "")))]
3271 "TARGET_EXPLICIT_RELOCS"
3273 "&& reload_completed"
3275 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3277 operands[2] = pic_offset_table_rtx;
3278 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3280 [(set_attr "got" "load")
3281 (set_attr "mode" "<MODE>")])
3283 ;; Lower-level instructions for loading an address from the GOT.
3284 ;; We could use MEMs, but an unspec gives more optimization
3287 (define_insn "load_got<mode>"
3288 [(set (match_operand:P 0 "register_operand" "=d")
3289 (unspec:P [(match_operand:P 1 "register_operand" "d")
3290 (match_operand:P 2 "immediate_operand" "")]
3293 "<load>\t%0,%R2(%1)"
3294 [(set_attr "type" "load")
3295 (set_attr "mode" "<MODE>")
3296 (set_attr "length" "4")])
3298 ;; Instructions for adding the low 16 bits of an address to a register.
3299 ;; Operand 2 is the address: print_operand works out which relocation
3300 ;; should be applied.
3302 (define_insn "*low<mode>"
3303 [(set (match_operand:P 0 "register_operand" "=d")
3304 (lo_sum:P (match_operand:P 1 "register_operand" "d")
3305 (match_operand:P 2 "immediate_operand" "")))]
3307 "<d>addiu\t%0,%1,%R2"
3308 [(set_attr "type" "arith")
3309 (set_attr "mode" "<MODE>")])
3311 (define_insn "*low<mode>_mips16"
3312 [(set (match_operand:P 0 "register_operand" "=d")
3313 (lo_sum:P (match_operand:P 1 "register_operand" "0")
3314 (match_operand:P 2 "immediate_operand" "")))]
3317 [(set_attr "type" "arith")
3318 (set_attr "mode" "<MODE>")
3319 (set_attr "length" "8")])
3321 ;; Allow combine to split complex const_int load sequences, using operand 2
3322 ;; to store the intermediate results. See move_operand for details.
3324 [(set (match_operand:GPR 0 "register_operand")
3325 (match_operand:GPR 1 "splittable_const_int_operand"))
3326 (clobber (match_operand:GPR 2 "register_operand"))]
3330 mips_move_integer (operands[0], operands[2], INTVAL (operands[1]));
3334 ;; Likewise, for symbolic operands.
3336 [(set (match_operand:P 0 "register_operand")
3337 (match_operand:P 1))
3338 (clobber (match_operand:P 2 "register_operand"))]
3339 "mips_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
3340 [(set (match_dup 0) (match_dup 3))]
3342 mips_split_symbol (operands[2], operands[1],
3343 MAX_MACHINE_MODE, &operands[3]);
3346 ;; 64-bit integer moves
3348 ;; Unlike most other insns, the move insns can't be split with
3349 ;; different predicates, because register spilling and other parts of
3350 ;; the compiler, have memoized the insn number already.
3352 (define_expand "movdi"
3353 [(set (match_operand:DI 0 "")
3354 (match_operand:DI 1 ""))]
3357 if (mips_legitimize_move (DImode, operands[0], operands[1]))
3361 ;; For mips16, we need a special case to handle storing $31 into
3362 ;; memory, since we don't have a constraint to match $31. This
3363 ;; instruction can be generated by save_restore_insns.
3365 (define_insn "*mov<mode>_ra"
3366 [(set (match_operand:GPR 0 "stack_operand" "=m")
3370 [(set_attr "type" "store")
3371 (set_attr "mode" "<MODE>")])
3373 (define_insn "*movdi_32bit"
3374 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*B*C*D,*B*C*D,*d,*m")
3375 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
3376 "!TARGET_64BIT && !TARGET_FLOAT64 && !TARGET_MIPS16
3377 && (register_operand (operands[0], DImode)
3378 || reg_or_0_operand (operands[1], DImode))"
3379 { return mips_output_move (operands[0], operands[1]); }
3380 [(set_attr "type" "multi,multi,load,store,mthilo,mfhilo,mtc,load,mfc,store")
3381 (set_attr "mode" "DI")
3382 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
3384 (define_insn "*movdi_gp32_fp64"
3385 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*f,*f,*f,*d,*m")
3386 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*f,*J*d,*m,*f,*f"))]
3387 "!TARGET_64BIT && TARGET_FLOAT64 && !TARGET_MIPS16
3388 && (register_operand (operands[0], DImode)
3389 || reg_or_0_operand (operands[1], DImode))"
3390 { return mips_output_move (operands[0], operands[1]); }
3391 [(set_attr "type" "multi,multi,load,store,mthilo,mfhilo,fmove,mtc,fpload,mfc,fpstore")
3392 (set_attr "mode" "DI")
3393 (set_attr "length" "8,16,*,*,8,8,4,8,*,8,*")])
3395 (define_insn "*movdi_32bit_mips16"
3396 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3397 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3398 "!TARGET_64BIT && TARGET_MIPS16
3399 && (register_operand (operands[0], DImode)
3400 || register_operand (operands[1], DImode))"
3401 { return mips_output_move (operands[0], operands[1]); }
3402 [(set_attr "type" "multi,multi,multi,multi,multi,load,store,mfhilo")
3403 (set_attr "mode" "DI")
3404 (set_attr "length" "8,8,8,8,12,*,*,8")])
3406 (define_insn "*movdi_64bit"
3407 [(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")
3408 (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"))]
3409 "TARGET_64BIT && !TARGET_MIPS16
3410 && (register_operand (operands[0], DImode)
3411 || reg_or_0_operand (operands[1], DImode))"
3412 { return mips_output_move (operands[0], operands[1]); }
3413 [(set_attr "type" "move,const,const,load,store,fmove,mtc,fpload,mfc,fpstore,mthilo,mtc,load,mfc,store")
3414 (set_attr "mode" "DI")
3415 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3417 (define_insn "*movdi_64bit_mips16"
3418 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3419 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3420 "TARGET_64BIT && TARGET_MIPS16
3421 && (register_operand (operands[0], DImode)
3422 || register_operand (operands[1], DImode))"
3423 { return mips_output_move (operands[0], operands[1]); }
3424 [(set_attr "type" "move,move,move,arith,arith,const,load,store")
3425 (set_attr "mode" "DI")
3426 (set_attr_alternative "length"
3430 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3433 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3438 (const_string "*")])])
3441 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
3442 ;; when the original load is a 4 byte instruction but the add and the
3443 ;; load are 2 2 byte instructions.
3446 [(set (match_operand:DI 0 "register_operand")
3447 (mem:DI (plus:DI (match_dup 0)
3448 (match_operand:DI 1 "const_int_operand"))))]
3449 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3450 && !TARGET_DEBUG_D_MODE
3451 && REG_P (operands[0])
3452 && M16_REG_P (REGNO (operands[0]))
3453 && GET_CODE (operands[1]) == CONST_INT
3454 && ((INTVAL (operands[1]) < 0
3455 && INTVAL (operands[1]) >= -0x10)
3456 || (INTVAL (operands[1]) >= 32 * 8
3457 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3458 || (INTVAL (operands[1]) >= 0
3459 && INTVAL (operands[1]) < 32 * 8
3460 && (INTVAL (operands[1]) & 7) != 0))"
3461 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3462 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3464 HOST_WIDE_INT val = INTVAL (operands[1]);
3467 operands[2] = const0_rtx;
3468 else if (val >= 32 * 8)
3472 operands[1] = GEN_INT (0x8 + off);
3473 operands[2] = GEN_INT (val - off - 0x8);
3479 operands[1] = GEN_INT (off);
3480 operands[2] = GEN_INT (val - off);
3484 ;; 32-bit Integer moves
3486 ;; Unlike most other insns, the move insns can't be split with
3487 ;; different predicates, because register spilling and other parts of
3488 ;; the compiler, have memoized the insn number already.
3490 (define_expand "movsi"
3491 [(set (match_operand:SI 0 "")
3492 (match_operand:SI 1 ""))]
3495 if (mips_legitimize_move (SImode, operands[0], operands[1]))
3499 ;; The difference between these two is whether or not ints are allowed
3500 ;; in FP registers (off by default, use -mdebugh to enable).
3502 (define_insn "*movsi_internal"
3503 [(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")
3504 (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"))]
3506 && (register_operand (operands[0], SImode)
3507 || reg_or_0_operand (operands[1], SImode))"
3508 { return mips_output_move (operands[0], operands[1]); }
3509 [(set_attr "type" "move,const,const,load,store,fmove,mtc,fpload,mfc,fpstore,mfc,mtc,mthilo,mfhilo,mtc,load,mfc,store")
3510 (set_attr "mode" "SI")
3511 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")])
3513 (define_insn "*movsi_mips16"
3514 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3515 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3517 && (register_operand (operands[0], SImode)
3518 || register_operand (operands[1], SImode))"
3519 { return mips_output_move (operands[0], operands[1]); }
3520 [(set_attr "type" "move,move,move,arith,arith,const,load,store")
3521 (set_attr "mode" "SI")
3522 (set_attr_alternative "length"
3526 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3529 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3534 (const_string "*")])])
3536 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
3537 ;; when the original load is a 4 byte instruction but the add and the
3538 ;; load are 2 2 byte instructions.
3541 [(set (match_operand:SI 0 "register_operand")
3542 (mem:SI (plus:SI (match_dup 0)
3543 (match_operand:SI 1 "const_int_operand"))))]
3544 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3545 && REG_P (operands[0])
3546 && M16_REG_P (REGNO (operands[0]))
3547 && GET_CODE (operands[1]) == CONST_INT
3548 && ((INTVAL (operands[1]) < 0
3549 && INTVAL (operands[1]) >= -0x80)
3550 || (INTVAL (operands[1]) >= 32 * 4
3551 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3552 || (INTVAL (operands[1]) >= 0
3553 && INTVAL (operands[1]) < 32 * 4
3554 && (INTVAL (operands[1]) & 3) != 0))"
3555 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3556 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3558 HOST_WIDE_INT val = INTVAL (operands[1]);
3561 operands[2] = const0_rtx;
3562 else if (val >= 32 * 4)
3566 operands[1] = GEN_INT (0x7c + off);
3567 operands[2] = GEN_INT (val - off - 0x7c);
3573 operands[1] = GEN_INT (off);
3574 operands[2] = GEN_INT (val - off);
3578 ;; On the mips16, we can split a load of certain constants into a load
3579 ;; and an add. This turns a 4 byte instruction into 2 2 byte
3583 [(set (match_operand:SI 0 "register_operand")
3584 (match_operand:SI 1 "const_int_operand"))]
3585 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3586 && REG_P (operands[0])
3587 && M16_REG_P (REGNO (operands[0]))
3588 && GET_CODE (operands[1]) == CONST_INT
3589 && INTVAL (operands[1]) >= 0x100
3590 && INTVAL (operands[1]) <= 0xff + 0x7f"
3591 [(set (match_dup 0) (match_dup 1))
3592 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3594 int val = INTVAL (operands[1]);
3596 operands[1] = GEN_INT (0xff);
3597 operands[2] = GEN_INT (val - 0xff);
3600 ;; This insn handles moving CCmode values. It's really just a
3601 ;; slightly simplified copy of movsi_internal2, with additional cases
3602 ;; to move a condition register to a general register and to move
3603 ;; between the general registers and the floating point registers.
3605 (define_insn "movcc"
3606 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3607 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3608 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3609 { return mips_output_move (operands[0], operands[1]); }
3610 [(set_attr "type" "multi,move,load,store,mfc,mtc,fmove,fpload,fpstore")
3611 (set_attr "mode" "SI")
3612 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
3614 ;; Reload condition code registers. reload_incc and reload_outcc
3615 ;; both handle moves from arbitrary operands into condition code
3616 ;; registers. reload_incc handles the more common case in which
3617 ;; a source operand is constrained to be in a condition-code
3618 ;; register, but has not been allocated to one.
3620 ;; Sometimes, such as in movcc, we have a CCmode destination whose
3621 ;; constraints do not include 'z'. reload_outcc handles the case
3622 ;; when such an operand is allocated to a condition-code register.
3624 ;; Note that reloads from a condition code register to some
3625 ;; other location can be done using ordinary moves. Moving
3626 ;; into a GPR takes a single movcc, moving elsewhere takes
3627 ;; two. We can leave these cases to the generic reload code.
3628 (define_expand "reload_incc"
3629 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3630 (match_operand:CC 1 "general_operand" ""))
3631 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3632 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3634 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3638 (define_expand "reload_outcc"
3639 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3640 (match_operand:CC 1 "register_operand" ""))
3641 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3642 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3644 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3648 ;; MIPS4 supports loading and storing a floating point register from
3649 ;; the sum of two general registers. We use two versions for each of
3650 ;; these four instructions: one where the two general registers are
3651 ;; SImode, and one where they are DImode. This is because general
3652 ;; registers will be in SImode when they hold 32-bit values, but,
3653 ;; since the 32-bit values are always sign extended, the [ls][wd]xc1
3654 ;; instructions will still work correctly.
3656 ;; ??? Perhaps it would be better to support these instructions by
3657 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
3658 ;; these instructions can only be used to load and store floating
3659 ;; point registers, that would probably cause trouble in reload.
3661 (define_insn "*<ANYF:loadx>_<P:mode>"
3662 [(set (match_operand:ANYF 0 "register_operand" "=f")
3663 (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3664 (match_operand:P 2 "register_operand" "d"))))]
3666 "<ANYF:loadx>\t%0,%1(%2)"
3667 [(set_attr "type" "fpidxload")
3668 (set_attr "mode" "<ANYF:UNITMODE>")])
3670 (define_insn "*<ANYF:storex>_<P:mode>"
3671 [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3672 (match_operand:P 2 "register_operand" "d")))
3673 (match_operand:ANYF 0 "register_operand" "f"))]
3675 "<ANYF:storex>\t%0,%1(%2)"
3676 [(set_attr "type" "fpidxstore")
3677 (set_attr "mode" "<ANYF:UNITMODE>")])
3679 ;; Scaled indexed address load.
3680 ;; Per md.texi, we only need to look for a pattern with multiply in the
3681 ;; address expression, not shift.
3683 (define_insn "*lwxs"
3684 [(set (match_operand:SI 0 "register_operand" "=d")
3685 (mem:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
3687 (match_operand:SI 2 "register_operand" "d"))))]
3690 [(set_attr "type" "load")
3691 (set_attr "mode" "SI")
3692 (set_attr "length" "4")])
3694 ;; 16-bit Integer moves
3696 ;; Unlike most other insns, the move insns can't be split with
3697 ;; different predicates, because register spilling and other parts of
3698 ;; the compiler, have memoized the insn number already.
3699 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3701 (define_expand "movhi"
3702 [(set (match_operand:HI 0 "")
3703 (match_operand:HI 1 ""))]
3706 if (mips_legitimize_move (HImode, operands[0], operands[1]))
3710 (define_insn "*movhi_internal"
3711 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3712 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
3714 && (register_operand (operands[0], HImode)
3715 || reg_or_0_operand (operands[1], HImode))"
3725 [(set_attr "type" "move,arith,load,store,mfc,mtc,fmove,mthilo")
3726 (set_attr "mode" "HI")
3727 (set_attr "length" "4,4,*,*,4,4,4,4")])
3729 (define_insn "*movhi_mips16"
3730 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3731 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))]
3733 && (register_operand (operands[0], HImode)
3734 || register_operand (operands[1], HImode))"
3743 [(set_attr "type" "move,move,move,arith,arith,load,store")
3744 (set_attr "mode" "HI")
3745 (set_attr_alternative "length"
3749 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3752 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3756 (const_string "*")])])
3759 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
3760 ;; when the original load is a 4 byte instruction but the add and the
3761 ;; load are 2 2 byte instructions.
3764 [(set (match_operand:HI 0 "register_operand")
3765 (mem:HI (plus:SI (match_dup 0)
3766 (match_operand:SI 1 "const_int_operand"))))]
3767 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3768 && REG_P (operands[0])
3769 && M16_REG_P (REGNO (operands[0]))
3770 && GET_CODE (operands[1]) == CONST_INT
3771 && ((INTVAL (operands[1]) < 0
3772 && INTVAL (operands[1]) >= -0x80)
3773 || (INTVAL (operands[1]) >= 32 * 2
3774 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
3775 || (INTVAL (operands[1]) >= 0
3776 && INTVAL (operands[1]) < 32 * 2
3777 && (INTVAL (operands[1]) & 1) != 0))"
3778 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3779 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
3781 HOST_WIDE_INT val = INTVAL (operands[1]);
3784 operands[2] = const0_rtx;
3785 else if (val >= 32 * 2)
3789 operands[1] = GEN_INT (0x7e + off);
3790 operands[2] = GEN_INT (val - off - 0x7e);
3796 operands[1] = GEN_INT (off);
3797 operands[2] = GEN_INT (val - off);
3801 ;; 8-bit Integer moves
3803 ;; Unlike most other insns, the move insns can't be split with
3804 ;; different predicates, because register spilling and other parts of
3805 ;; the compiler, have memoized the insn number already.
3806 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3808 (define_expand "movqi"
3809 [(set (match_operand:QI 0 "")
3810 (match_operand:QI 1 ""))]
3813 if (mips_legitimize_move (QImode, operands[0], operands[1]))
3817 (define_insn "*movqi_internal"
3818 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3819 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
3821 && (register_operand (operands[0], QImode)
3822 || reg_or_0_operand (operands[1], QImode))"
3832 [(set_attr "type" "move,arith,load,store,mfc,mtc,fmove,mthilo")
3833 (set_attr "mode" "QI")
3834 (set_attr "length" "4,4,*,*,4,4,4,4")])
3836 (define_insn "*movqi_mips16"
3837 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3838 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))]
3840 && (register_operand (operands[0], QImode)
3841 || register_operand (operands[1], QImode))"
3850 [(set_attr "type" "move,move,move,arith,arith,load,store")
3851 (set_attr "mode" "QI")
3852 (set_attr "length" "4,4,4,4,8,*,*")])
3854 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
3855 ;; when the original load is a 4 byte instruction but the add and the
3856 ;; load are 2 2 byte instructions.
3859 [(set (match_operand:QI 0 "register_operand")
3860 (mem:QI (plus:SI (match_dup 0)
3861 (match_operand:SI 1 "const_int_operand"))))]
3862 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3863 && REG_P (operands[0])
3864 && M16_REG_P (REGNO (operands[0]))
3865 && GET_CODE (operands[1]) == CONST_INT
3866 && ((INTVAL (operands[1]) < 0
3867 && INTVAL (operands[1]) >= -0x80)
3868 || (INTVAL (operands[1]) >= 32
3869 && INTVAL (operands[1]) <= 31 + 0x7f))"
3870 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3871 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
3873 HOST_WIDE_INT val = INTVAL (operands[1]);
3876 operands[2] = const0_rtx;
3879 operands[1] = GEN_INT (0x7f);
3880 operands[2] = GEN_INT (val - 0x7f);
3884 ;; 32-bit floating point moves
3886 (define_expand "movsf"
3887 [(set (match_operand:SF 0 "")
3888 (match_operand:SF 1 ""))]
3891 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
3895 (define_insn "*movsf_hardfloat"
3896 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3897 (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))]
3899 && (register_operand (operands[0], SFmode)
3900 || reg_or_0_operand (operands[1], SFmode))"
3901 { return mips_output_move (operands[0], operands[1]); }
3902 [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
3903 (set_attr "mode" "SF")
3904 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
3906 (define_insn "*movsf_softfloat"
3907 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
3908 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
3909 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
3910 && (register_operand (operands[0], SFmode)
3911 || reg_or_0_operand (operands[1], SFmode))"
3912 { return mips_output_move (operands[0], operands[1]); }
3913 [(set_attr "type" "move,load,store")
3914 (set_attr "mode" "SF")
3915 (set_attr "length" "4,*,*")])
3917 (define_insn "*movsf_mips16"
3918 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
3919 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
3921 && (register_operand (operands[0], SFmode)
3922 || register_operand (operands[1], SFmode))"
3923 { return mips_output_move (operands[0], operands[1]); }
3924 [(set_attr "type" "move,move,move,load,store")
3925 (set_attr "mode" "SF")
3926 (set_attr "length" "4,4,4,*,*")])
3929 ;; 64-bit floating point moves
3931 (define_expand "movdf"
3932 [(set (match_operand:DF 0 "")
3933 (match_operand:DF 1 ""))]
3936 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
3940 (define_insn "*movdf_hardfloat_64bit"
3941 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3942 (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3943 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
3944 && (register_operand (operands[0], DFmode)
3945 || reg_or_0_operand (operands[1], DFmode))"
3946 { return mips_output_move (operands[0], operands[1]); }
3947 [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
3948 (set_attr "mode" "DF")
3949 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
3951 ;; This pattern applies to both !TARGET_FLOAT64 and TARGET_FLOAT64.
3952 (define_insn "*movdf_hardfloat_32bit"
3953 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3954 (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3955 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
3956 && (register_operand (operands[0], DFmode)
3957 || reg_or_0_operand (operands[1], DFmode))"
3958 { return mips_output_move (operands[0], operands[1]); }
3959 [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
3960 (set_attr "mode" "DF")
3961 (set_attr "length" "4,8,*,*,*,8,8,8,*,*")])
3963 (define_insn "*movdf_softfloat"
3964 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
3965 (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
3966 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
3967 && (register_operand (operands[0], DFmode)
3968 || reg_or_0_operand (operands[1], DFmode))"
3969 { return mips_output_move (operands[0], operands[1]); }
3970 [(set_attr "type" "multi,load,store,mfc,mtc,fmove")
3971 (set_attr "mode" "DF")
3972 (set_attr "length" "8,*,*,4,4,4")])
3974 (define_insn "*movdf_mips16"
3975 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
3976 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
3978 && (register_operand (operands[0], DFmode)
3979 || register_operand (operands[1], DFmode))"
3980 { return mips_output_move (operands[0], operands[1]); }
3981 [(set_attr "type" "multi,multi,multi,load,store")
3982 (set_attr "mode" "DF")
3983 (set_attr "length" "8,8,8,*,*")])
3986 [(set (match_operand:DI 0 "nonimmediate_operand")
3987 (match_operand:DI 1 "move_operand"))]
3988 "reload_completed && !TARGET_64BIT
3989 && mips_split_64bit_move_p (operands[0], operands[1])"
3992 mips_split_64bit_move (operands[0], operands[1]);
3997 [(set (match_operand:DF 0 "nonimmediate_operand")
3998 (match_operand:DF 1 "move_operand"))]
3999 "reload_completed && !TARGET_64BIT
4000 && mips_split_64bit_move_p (operands[0], operands[1])"
4003 mips_split_64bit_move (operands[0], operands[1]);
4007 ;; When generating mips16 code, split moves of negative constants into
4008 ;; a positive "li" followed by a negation.
4010 [(set (match_operand 0 "register_operand")
4011 (match_operand 1 "const_int_operand"))]
4012 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4016 (neg:SI (match_dup 2)))]
4018 operands[2] = gen_lowpart (SImode, operands[0]);
4019 operands[3] = GEN_INT (-INTVAL (operands[1]));
4022 ;; 64-bit paired-single floating point moves
4024 (define_expand "movv2sf"
4025 [(set (match_operand:V2SF 0)
4026 (match_operand:V2SF 1))]
4027 "TARGET_PAIRED_SINGLE_FLOAT"
4029 if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
4033 (define_insn "movv2sf_hardfloat_64bit"
4034 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4035 (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
4036 "TARGET_PAIRED_SINGLE_FLOAT
4038 && (register_operand (operands[0], V2SFmode)
4039 || reg_or_0_operand (operands[1], V2SFmode))"
4040 { return mips_output_move (operands[0], operands[1]); }
4041 [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4042 (set_attr "mode" "SF")
4043 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
4045 ;; The HI and LO registers are not truly independent. If we move an mthi
4046 ;; instruction before an mflo instruction, it will make the result of the
4047 ;; mflo unpredictable. The same goes for mtlo and mfhi.
4049 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4050 ;; Operand 1 is the register we want, operand 2 is the other one.
4052 ;; When generating VR4120 or VR4130 code, we use macc{,hi} and
4053 ;; dmacc{,hi} instead of mfhi and mflo. This avoids both the normal
4054 ;; MIPS III hi/lo hazards and the errata related to -mfix-vr4130.
4056 (define_expand "mfhilo_<mode>"
4057 [(set (match_operand:GPR 0 "register_operand")
4058 (unspec:GPR [(match_operand:GPR 1 "register_operand")
4059 (match_operand:GPR 2 "register_operand")]
4062 (define_insn "*mfhilo_<mode>"
4063 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4064 (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
4065 (match_operand:GPR 2 "register_operand" "l,h")]
4069 [(set_attr "type" "mfhilo")
4070 (set_attr "mode" "<MODE>")])
4072 (define_insn "*mfhilo_<mode>_macc"
4073 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4074 (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
4075 (match_operand:GPR 2 "register_operand" "l,h")]
4081 [(set_attr "type" "mfhilo")
4082 (set_attr "mode" "<MODE>")])
4084 ;; Patterns for loading or storing part of a paired floating point
4085 ;; register. We need them because odd-numbered floating-point registers
4086 ;; are not fully independent: see mips_split_64bit_move.
4088 ;; Load the low word of operand 0 with operand 1.
4089 (define_insn "load_df_low"
4090 [(set (match_operand:DF 0 "register_operand" "=f,f")
4091 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
4092 UNSPEC_LOAD_DF_LOW))]
4093 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4095 operands[0] = mips_subword (operands[0], 0);
4096 return mips_output_move (operands[0], operands[1]);
4098 [(set_attr "type" "mtc,fpload")
4099 (set_attr "mode" "SF")])
4101 ;; Load the high word of operand 0 from operand 1, preserving the value
4103 (define_insn "load_df_high"
4104 [(set (match_operand:DF 0 "register_operand" "=f,f")
4105 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
4106 (match_operand:DF 2 "register_operand" "0,0")]
4107 UNSPEC_LOAD_DF_HIGH))]
4108 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4110 operands[0] = mips_subword (operands[0], 1);
4111 return mips_output_move (operands[0], operands[1]);
4113 [(set_attr "type" "mtc,fpload")
4114 (set_attr "mode" "SF")])
4116 ;; Store the high word of operand 1 in operand 0. The corresponding
4117 ;; low-word move is done in the normal way.
4118 (define_insn "store_df_high"
4119 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4120 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4121 UNSPEC_STORE_DF_HIGH))]
4122 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4124 operands[1] = mips_subword (operands[1], 1);
4125 return mips_output_move (operands[0], operands[1]);
4127 [(set_attr "type" "mfc,fpstore")
4128 (set_attr "mode" "SF")])
4130 ;; Move operand 1 to the high word of operand 0 using mthc1, preserving the
4131 ;; value in the low word.
4132 (define_insn "mthc1"
4133 [(set (match_operand:DF 0 "register_operand" "=f")
4134 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ")
4135 (match_operand:DF 2 "register_operand" "0")]
4137 "TARGET_HARD_FLOAT && !TARGET_64BIT && ISA_HAS_MXHC1"
4139 [(set_attr "type" "mtc")
4140 (set_attr "mode" "SF")])
4142 ;; Move high word of operand 1 to operand 0 using mfhc1. The corresponding
4143 ;; low-word move is done in the normal way.
4144 (define_insn "mfhc1"
4145 [(set (match_operand:SI 0 "register_operand" "=d")
4146 (unspec:SI [(match_operand:DF 1 "register_operand" "f")]
4148 "TARGET_HARD_FLOAT && !TARGET_64BIT && ISA_HAS_MXHC1"
4150 [(set_attr "type" "mfc")
4151 (set_attr "mode" "SF")])
4153 ;; Move a constant that satisfies CONST_GP_P into operand 0.
4154 (define_expand "load_const_gp"
4155 [(set (match_operand 0 "register_operand" "=d")
4156 (const (unspec [(const_int 0)] UNSPEC_GP)))])
4158 ;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
4159 ;; of _gp from the start of this function. Operand 1 is the incoming
4160 ;; function address.
4161 (define_insn_and_split "loadgp_newabi"
4162 [(unspec_volatile [(match_operand 0 "" "")
4163 (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4164 "mips_current_loadgp_style () == LOADGP_NEWABI"
4167 [(set (match_dup 2) (match_dup 3))
4168 (set (match_dup 2) (match_dup 4))
4169 (set (match_dup 2) (match_dup 5))]
4171 operands[2] = pic_offset_table_rtx;
4172 operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4173 operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4174 operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4176 [(set_attr "length" "12")])
4178 ;; Likewise, for -mno-shared code. Operand 0 is the __gnu_local_gp symbol.
4179 (define_insn_and_split "loadgp_absolute"
4180 [(unspec_volatile [(match_operand 0 "" "")] UNSPEC_LOADGP)]
4181 "mips_current_loadgp_style () == LOADGP_ABSOLUTE"
4186 mips_emit_move (pic_offset_table_rtx, operands[0]);
4189 [(set_attr "length" "8")])
4191 ;; The use of gp is hidden when not using explicit relocations.
4192 ;; This blockage instruction prevents the gp load from being
4193 ;; scheduled after an implicit use of gp. It also prevents
4194 ;; the load from being deleted as dead.
4195 (define_insn "loadgp_blockage"
4196 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4199 [(set_attr "type" "unknown")
4200 (set_attr "mode" "none")
4201 (set_attr "length" "0")])
4203 ;; Initialize $gp for RTP PIC. Operand 0 is the __GOTT_BASE__ symbol
4204 ;; and operand 1 is the __GOTT_INDEX__ symbol.
4205 (define_insn "loadgp_rtp"
4206 [(unspec_volatile [(match_operand 0 "symbol_ref_operand")
4207 (match_operand 1 "symbol_ref_operand")] UNSPEC_LOADGP)]
4208 "mips_current_loadgp_style () == LOADGP_RTP"
4210 [(set_attr "length" "12")])
4213 [(unspec_volatile [(match_operand:P 0 "symbol_ref_operand")
4214 (match_operand:P 1 "symbol_ref_operand")] UNSPEC_LOADGP)]
4215 "mips_current_loadgp_style () == LOADGP_RTP"
4216 [(set (match_dup 2) (high:P (match_dup 3)))
4217 (set (match_dup 2) (unspec:P [(match_dup 2)
4218 (match_dup 3)] UNSPEC_LOAD_GOT))
4219 (set (match_dup 2) (unspec:P [(match_dup 2)
4220 (match_dup 4)] UNSPEC_LOAD_GOT))]
4222 operands[2] = pic_offset_table_rtx;
4223 operands[3] = mips_unspec_address (operands[0], SYMBOL_ABSOLUTE);
4224 operands[4] = mips_unspec_address (operands[1], SYMBOL_HALF);
4227 ;; Emit a .cprestore directive, which normally expands to a single store
4228 ;; instruction. Note that we continue to use .cprestore for explicit reloc
4229 ;; code so that jals inside inline asms will work correctly.
4230 (define_insn "cprestore"
4231 [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")
4236 if (set_nomacro && which_alternative == 1)
4237 return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4239 return ".cprestore\t%0";
4241 [(set_attr "type" "store")
4242 (set_attr "length" "4,12")])
4244 ;; Expand in-line code to clear the instruction cache between operand[0] and
4246 (define_expand "clear_cache"
4247 [(match_operand 0 "pmode_register_operand")
4248 (match_operand 1 "pmode_register_operand")]
4254 mips_expand_synci_loop (operands[0], operands[1]);
4255 emit_insn (gen_sync ());
4256 emit_insn (gen_clear_hazard ());
4258 else if (mips_cache_flush_func && mips_cache_flush_func[0])
4260 rtx len = gen_reg_rtx (Pmode);
4261 emit_insn (gen_sub3_insn (len, operands[1], operands[0]));
4262 /* Flush both caches. We need to flush the data cache in case
4263 the system has a write-back cache. */
4264 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mips_cache_flush_func),
4265 0, VOIDmode, 3, operands[0], Pmode, len, Pmode,
4266 GEN_INT (3), TYPE_MODE (integer_type_node));
4272 [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
4276 (define_insn "synci"
4277 [(unspec_volatile [(match_operand 0 "pmode_register_operand" "d")]
4282 (define_insn "rdhwr"
4283 [(set (match_operand:SI 0 "register_operand" "=d")
4284 (unspec_volatile [(match_operand:SI 1 "const_int_operand" "n")]
4289 (define_insn "clear_hazard"
4290 [(unspec_volatile [(const_int 0)] UNSPEC_CLEAR_HAZARD)
4291 (clobber (reg:SI 31))]
4294 return ".set\tpush\n"
4295 "\t.set\tnoreorder\n"
4299 "1:\taddiu\t$31,$31,12\n"
4304 [(set_attr "length" "20")])
4306 ;; Atomic memory operations.
4308 (define_insn "memory_barrier"
4309 [(set (mem:BLK (scratch))
4310 (unspec:BLK [(const_int 0)] UNSPEC_MEMORY_BARRIER))]
4314 (define_insn "sync_compare_and_swap<mode>"
4315 [(set (match_operand:GPR 0 "register_operand" "=&d,d")
4316 (match_operand:GPR 1 "memory_operand" "+R,R"))
4318 (unspec_volatile:GPR [(match_operand:GPR 2 "register_operand" "d,d")
4319 (match_operand:GPR 3 "arith_operand" "I,d")]
4320 UNSPEC_COMPARE_AND_SWAP))]
4323 if (which_alternative == 0)
4324 return MIPS_COMPARE_AND_SWAP ("<d>", "li");
4326 return MIPS_COMPARE_AND_SWAP ("<d>", "move");
4328 [(set_attr "length" "28")])
4330 (define_insn "sync_add<mode>"
4331 [(set (match_operand:GPR 0 "memory_operand" "+R,R")
4332 (unspec_volatile:GPR
4333 [(plus:GPR (match_dup 0)
4334 (match_operand:GPR 1 "arith_operand" "I,d"))]
4335 UNSPEC_SYNC_OLD_OP))]
4338 if (which_alternative == 0)
4339 return MIPS_SYNC_OP ("<d>", "<d>addiu");
4341 return MIPS_SYNC_OP ("<d>", "<d>addu");
4343 [(set_attr "length" "24")])
4345 (define_insn "sync_sub<mode>"
4346 [(set (match_operand:GPR 0 "memory_operand" "+R")
4347 (unspec_volatile:GPR
4348 [(minus:GPR (match_dup 0)
4349 (match_operand:GPR 1 "register_operand" "d"))]
4350 UNSPEC_SYNC_OLD_OP))]
4353 return MIPS_SYNC_OP ("<d>", "<d>subu");
4355 [(set_attr "length" "24")])
4357 (define_insn "sync_old_add<mode>"
4358 [(set (match_operand:GPR 0 "register_operand" "=&d,d")
4359 (match_operand:GPR 1 "memory_operand" "+R,R"))
4361 (unspec_volatile:GPR
4362 [(plus:GPR (match_dup 1)
4363 (match_operand:GPR 2 "arith_operand" "I,d"))]
4364 UNSPEC_SYNC_OLD_OP))]
4367 if (which_alternative == 0)
4368 return MIPS_SYNC_OLD_OP ("<d>", "<d>addiu");
4370 return MIPS_SYNC_OLD_OP ("<d>", "<d>addu");
4372 [(set_attr "length" "24")])
4374 (define_insn "sync_old_sub<mode>"
4375 [(set (match_operand:GPR 0 "register_operand" "=&d")
4376 (match_operand:GPR 1 "memory_operand" "+R"))
4378 (unspec_volatile:GPR
4379 [(minus:GPR (match_dup 1)
4380 (match_operand:GPR 2 "register_operand" "d"))]
4381 UNSPEC_SYNC_OLD_OP))]
4384 return MIPS_SYNC_OLD_OP ("<d>", "<d>subu");
4386 [(set_attr "length" "24")])
4388 (define_insn "sync_new_add<mode>"
4389 [(set (match_operand:GPR 0 "register_operand" "=&d,d")
4390 (plus:GPR (match_operand:GPR 1 "memory_operand" "+R,R")
4391 (match_operand:GPR 2 "arith_operand" "I,d")))
4393 (unspec_volatile:GPR
4394 [(plus:GPR (match_dup 1) (match_dup 2))]
4395 UNSPEC_SYNC_NEW_OP))]
4398 if (which_alternative == 0)
4399 return MIPS_SYNC_NEW_OP ("<d>", "<d>addiu");
4401 return MIPS_SYNC_NEW_OP ("<d>", "<d>addu");
4403 [(set_attr "length" "24")])
4405 (define_insn "sync_new_sub<mode>"
4406 [(set (match_operand:GPR 0 "register_operand" "=&d")
4407 (minus:GPR (match_operand:GPR 1 "memory_operand" "+R")
4408 (match_operand:GPR 2 "register_operand" "d")))
4410 (unspec_volatile:GPR
4411 [(minus:GPR (match_dup 1) (match_dup 2))]
4412 UNSPEC_SYNC_NEW_OP))]
4415 return MIPS_SYNC_NEW_OP ("<d>", "<d>subu");
4417 [(set_attr "length" "24")])
4419 (define_insn "sync_<optab><mode>"
4420 [(set (match_operand:GPR 0 "memory_operand" "+R,R")
4421 (unspec_volatile:GPR
4422 [(fetchop_bit:GPR (match_operand:GPR 1 "uns_arith_operand" "K,d")
4424 UNSPEC_SYNC_OLD_OP))]
4427 if (which_alternative == 0)
4428 return MIPS_SYNC_OP ("<d>", "<immediate_insn>");
4430 return MIPS_SYNC_OP ("<d>", "<insn>");
4432 [(set_attr "length" "24")])
4434 (define_insn "sync_old_<optab><mode>"
4435 [(set (match_operand:GPR 0 "register_operand" "=&d,d")
4436 (match_operand:GPR 1 "memory_operand" "+R,R"))
4438 (unspec_volatile:GPR
4439 [(fetchop_bit:GPR (match_operand:GPR 2 "uns_arith_operand" "K,d")
4441 UNSPEC_SYNC_OLD_OP))]
4444 if (which_alternative == 0)
4445 return MIPS_SYNC_OLD_OP ("<d>", "<immediate_insn>");
4447 return MIPS_SYNC_OLD_OP ("<d>", "<insn>");
4449 [(set_attr "length" "24")])
4451 (define_insn "sync_new_<optab><mode>"
4452 [(set (match_operand:GPR 0 "register_operand" "=&d,d")
4453 (match_operand:GPR 1 "memory_operand" "+R,R"))
4455 (unspec_volatile:GPR
4456 [(fetchop_bit:GPR (match_operand:GPR 2 "uns_arith_operand" "K,d")
4458 UNSPEC_SYNC_NEW_OP))]
4461 if (which_alternative == 0)
4462 return MIPS_SYNC_NEW_OP ("<d>", "<immediate_insn>");
4464 return MIPS_SYNC_NEW_OP ("<d>", "<insn>");
4466 [(set_attr "length" "24")])
4468 (define_insn "sync_nand<mode>"
4469 [(set (match_operand:GPR 0 "memory_operand" "+R,R")
4470 (unspec_volatile:GPR [(match_operand:GPR 1 "uns_arith_operand" "K,d")]
4471 UNSPEC_SYNC_OLD_OP))]
4474 if (which_alternative == 0)
4475 return MIPS_SYNC_NAND ("<d>", "andi");
4477 return MIPS_SYNC_NAND ("<d>", "and");
4479 [(set_attr "length" "28")])
4481 (define_insn "sync_old_nand<mode>"
4482 [(set (match_operand:GPR 0 "register_operand" "=&d,d")
4483 (match_operand:GPR 1 "memory_operand" "+R,R"))
4485 (unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")]
4486 UNSPEC_SYNC_OLD_OP))]
4489 if (which_alternative == 0)
4490 return MIPS_SYNC_OLD_NAND ("<d>", "andi");
4492 return MIPS_SYNC_OLD_NAND ("<d>", "and");
4494 [(set_attr "length" "28")])
4496 (define_insn "sync_new_nand<mode>"
4497 [(set (match_operand:GPR 0 "register_operand" "=&d,d")
4498 (match_operand:GPR 1 "memory_operand" "+R,R"))
4500 (unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")]
4501 UNSPEC_SYNC_NEW_OP))]
4504 if (which_alternative == 0)
4505 return MIPS_SYNC_NEW_NAND ("<d>", "andi");
4507 return MIPS_SYNC_NEW_NAND ("<d>", "and");
4509 [(set_attr "length" "28")])
4511 (define_insn "sync_lock_test_and_set<mode>"
4512 [(set (match_operand:GPR 0 "register_operand" "=&d,d")
4513 (match_operand:GPR 1 "memory_operand" "+R,R"))
4515 (unspec_volatile:GPR [(match_operand:GPR 2 "arith_operand" "I,d")]
4516 UNSPEC_SYNC_EXCHANGE))]
4519 if (which_alternative == 0)
4520 return MIPS_SYNC_EXCHANGE ("<d>", "li");
4522 return MIPS_SYNC_EXCHANGE ("<d>", "move");
4524 [(set_attr "length" "24")])
4526 ;; Block moves, see mips.c for more details.
4527 ;; Argument 0 is the destination
4528 ;; Argument 1 is the source
4529 ;; Argument 2 is the length
4530 ;; Argument 3 is the alignment
4532 (define_expand "movmemsi"
4533 [(parallel [(set (match_operand:BLK 0 "general_operand")
4534 (match_operand:BLK 1 "general_operand"))
4535 (use (match_operand:SI 2 ""))
4536 (use (match_operand:SI 3 "const_int_operand"))])]
4537 "!TARGET_MIPS16 && !TARGET_MEMCPY"
4539 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4546 ;; ....................
4550 ;; ....................
4552 (define_expand "<optab><mode>3"
4553 [(set (match_operand:GPR 0 "register_operand")
4554 (any_shift:GPR (match_operand:GPR 1 "register_operand")
4555 (match_operand:SI 2 "arith_operand")))]
4558 /* On the mips16, a shift of more than 8 is a four byte instruction,
4559 so, for a shift between 8 and 16, it is just as fast to do two
4560 shifts of 8 or less. If there is a lot of shifting going on, we
4561 may win in CSE. Otherwise combine will put the shifts back
4562 together again. This can be called by function_arg, so we must
4563 be careful not to allocate a new register if we've reached the
4567 && GET_CODE (operands[2]) == CONST_INT
4568 && INTVAL (operands[2]) > 8
4569 && INTVAL (operands[2]) <= 16
4570 && !reload_in_progress
4571 && !reload_completed)
4573 rtx temp = gen_reg_rtx (<MODE>mode);
4575 emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8)));
4576 emit_insn (gen_<optab><mode>3 (operands[0], temp,
4577 GEN_INT (INTVAL (operands[2]) - 8)));
4582 (define_insn "*<optab><mode>3"
4583 [(set (match_operand:GPR 0 "register_operand" "=d")
4584 (any_shift:GPR (match_operand:GPR 1 "register_operand" "d")
4585 (match_operand:SI 2 "arith_operand" "dI")))]
4588 if (GET_CODE (operands[2]) == CONST_INT)
4589 operands[2] = GEN_INT (INTVAL (operands[2])
4590 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
4592 return "<d><insn>\t%0,%1,%2";
4594 [(set_attr "type" "shift")
4595 (set_attr "mode" "<MODE>")])
4597 (define_insn "*<optab>si3_extend"
4598 [(set (match_operand:DI 0 "register_operand" "=d")
4600 (any_shift:SI (match_operand:SI 1 "register_operand" "d")
4601 (match_operand:SI 2 "arith_operand" "dI"))))]
4602 "TARGET_64BIT && !TARGET_MIPS16"
4604 if (GET_CODE (operands[2]) == CONST_INT)
4605 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4607 return "<insn>\t%0,%1,%2";
4609 [(set_attr "type" "shift")
4610 (set_attr "mode" "SI")])
4612 (define_insn "*<optab>si3_mips16"
4613 [(set (match_operand:SI 0 "register_operand" "=d,d")
4614 (any_shift:SI (match_operand:SI 1 "register_operand" "0,d")
4615 (match_operand:SI 2 "arith_operand" "d,I")))]
4618 if (which_alternative == 0)
4619 return "<insn>\t%0,%2";
4621 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4622 return "<insn>\t%0,%1,%2";
4624 [(set_attr "type" "shift")
4625 (set_attr "mode" "SI")
4626 (set_attr_alternative "length"
4628 (if_then_else (match_operand 2 "m16_uimm3_b")
4632 ;; We need separate DImode MIPS16 patterns because of the irregularity
4634 (define_insn "*ashldi3_mips16"
4635 [(set (match_operand:DI 0 "register_operand" "=d,d")
4636 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4637 (match_operand:SI 2 "arith_operand" "d,I")))]
4638 "TARGET_64BIT && TARGET_MIPS16"
4640 if (which_alternative == 0)
4641 return "dsll\t%0,%2";
4643 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4644 return "dsll\t%0,%1,%2";
4646 [(set_attr "type" "shift")
4647 (set_attr "mode" "DI")
4648 (set_attr_alternative "length"
4650 (if_then_else (match_operand 2 "m16_uimm3_b")
4654 (define_insn "*ashrdi3_mips16"
4655 [(set (match_operand:DI 0 "register_operand" "=d,d")
4656 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4657 (match_operand:SI 2 "arith_operand" "d,I")))]
4658 "TARGET_64BIT && TARGET_MIPS16"
4660 if (GET_CODE (operands[2]) == CONST_INT)
4661 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4663 return "dsra\t%0,%2";
4665 [(set_attr "type" "shift")
4666 (set_attr "mode" "DI")
4667 (set_attr_alternative "length"
4669 (if_then_else (match_operand 2 "m16_uimm3_b")
4673 (define_insn "*lshrdi3_mips16"
4674 [(set (match_operand:DI 0 "register_operand" "=d,d")
4675 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4676 (match_operand:SI 2 "arith_operand" "d,I")))]
4677 "TARGET_64BIT && TARGET_MIPS16"
4679 if (GET_CODE (operands[2]) == CONST_INT)
4680 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4682 return "dsrl\t%0,%2";
4684 [(set_attr "type" "shift")
4685 (set_attr "mode" "DI")
4686 (set_attr_alternative "length"
4688 (if_then_else (match_operand 2 "m16_uimm3_b")
4692 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4695 [(set (match_operand:GPR 0 "register_operand")
4696 (any_shift:GPR (match_operand:GPR 1 "register_operand")
4697 (match_operand:GPR 2 "const_int_operand")))]
4698 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4699 && GET_CODE (operands[2]) == CONST_INT
4700 && INTVAL (operands[2]) > 8
4701 && INTVAL (operands[2]) <= 16"
4702 [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
4703 (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
4704 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4706 ;; If we load a byte on the mips16 as a bitfield, the resulting
4707 ;; sequence of instructions is too complicated for combine, because it
4708 ;; involves four instructions: a load, a shift, a constant load into a
4709 ;; register, and an and (the key problem here is that the mips16 does
4710 ;; not have and immediate). We recognize a shift of a load in order
4711 ;; to make it simple enough for combine to understand.
4713 ;; The length here is the worst case: the length of the split version
4714 ;; will be more accurate.
4715 (define_insn_and_split ""
4716 [(set (match_operand:SI 0 "register_operand" "=d")
4717 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4718 (match_operand:SI 2 "immediate_operand" "I")))]
4722 [(set (match_dup 0) (match_dup 1))
4723 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4725 [(set_attr "type" "load")
4726 (set_attr "mode" "SI")
4727 (set_attr "length" "16")])
4729 (define_insn "rotr<mode>3"
4730 [(set (match_operand:GPR 0 "register_operand" "=d")
4731 (rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
4732 (match_operand:SI 2 "arith_operand" "dI")))]
4735 if (GET_CODE (operands[2]) == CONST_INT)
4736 gcc_assert (INTVAL (operands[2]) >= 0
4737 && INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode));
4739 return "<d>ror\t%0,%1,%2";
4741 [(set_attr "type" "shift")
4742 (set_attr "mode" "<MODE>")])
4745 ;; ....................
4749 ;; ....................
4751 ;; Flow here is rather complex:
4753 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the arguments
4754 ;; into cmp_operands[] but generates no RTL.
4756 ;; 2) The appropriate branch define_expand is called, which then
4757 ;; creates the appropriate RTL for the comparison and branch.
4758 ;; Different CC modes are used, based on what type of branch is
4759 ;; done, so that we can constrain things appropriately. There
4760 ;; are assumptions in the rest of GCC that break if we fold the
4761 ;; operands into the branches for integer operations, and use cc0
4762 ;; for floating point, so we use the fp status register instead.
4763 ;; If needed, an appropriate temporary is created to hold the
4764 ;; of the integer compare.
4766 (define_expand "cmp<mode>"
4768 (compare:CC (match_operand:GPR 0 "register_operand")
4769 (match_operand:GPR 1 "nonmemory_operand")))]
4772 cmp_operands[0] = operands[0];
4773 cmp_operands[1] = operands[1];
4777 (define_expand "cmp<mode>"
4779 (compare:CC (match_operand:SCALARF 0 "register_operand")
4780 (match_operand:SCALARF 1 "register_operand")))]
4783 cmp_operands[0] = operands[0];
4784 cmp_operands[1] = operands[1];
4789 ;; ....................
4791 ;; CONDITIONAL BRANCHES
4793 ;; ....................
4795 ;; Conditional branches on floating-point equality tests.
4797 (define_insn "*branch_fp"
4800 (match_operator 0 "equality_operator"
4801 [(match_operand:CC 2 "register_operand" "z")
4803 (label_ref (match_operand 1 "" ""))
4807 return mips_output_conditional_branch (insn, operands,
4808 MIPS_BRANCH ("b%F0", "%Z2%1"),
4809 MIPS_BRANCH ("b%W0", "%Z2%1"));
4811 [(set_attr "type" "branch")
4812 (set_attr "mode" "none")])
4814 (define_insn "*branch_fp_inverted"
4817 (match_operator 0 "equality_operator"
4818 [(match_operand:CC 2 "register_operand" "z")
4821 (label_ref (match_operand 1 "" ""))))]
4824 return mips_output_conditional_branch (insn, operands,
4825 MIPS_BRANCH ("b%W0", "%Z2%1"),
4826 MIPS_BRANCH ("b%F0", "%Z2%1"));
4828 [(set_attr "type" "branch")
4829 (set_attr "mode" "none")])
4831 ;; Conditional branches on ordered comparisons with zero.
4833 (define_insn "*branch_order<mode>"
4836 (match_operator 0 "order_operator"
4837 [(match_operand:GPR 2 "register_operand" "d")
4839 (label_ref (match_operand 1 "" ""))
4842 { return mips_output_order_conditional_branch (insn, operands, false); }
4843 [(set_attr "type" "branch")
4844 (set_attr "mode" "none")])
4846 (define_insn "*branch_order<mode>_inverted"
4849 (match_operator 0 "order_operator"
4850 [(match_operand:GPR 2 "register_operand" "d")
4853 (label_ref (match_operand 1 "" ""))))]
4855 { return mips_output_order_conditional_branch (insn, operands, true); }
4856 [(set_attr "type" "branch")
4857 (set_attr "mode" "none")])
4859 ;; Conditional branch on equality comparison.
4861 (define_insn "*branch_equality<mode>"
4864 (match_operator 0 "equality_operator"
4865 [(match_operand:GPR 2 "register_operand" "d")
4866 (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
4867 (label_ref (match_operand 1 "" ""))
4871 return mips_output_conditional_branch (insn, operands,
4872 MIPS_BRANCH ("b%C0", "%2,%z3,%1"),
4873 MIPS_BRANCH ("b%N0", "%2,%z3,%1"));
4875 [(set_attr "type" "branch")
4876 (set_attr "mode" "none")])
4878 (define_insn "*branch_equality<mode>_inverted"
4881 (match_operator 0 "equality_operator"
4882 [(match_operand:GPR 2 "register_operand" "d")
4883 (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
4885 (label_ref (match_operand 1 "" ""))))]
4888 return mips_output_conditional_branch (insn, operands,
4889 MIPS_BRANCH ("b%N0", "%2,%z3,%1"),
4890 MIPS_BRANCH ("b%C0", "%2,%z3,%1"));
4892 [(set_attr "type" "branch")
4893 (set_attr "mode" "none")])
4897 (define_insn "*branch_equality<mode>_mips16"
4900 (match_operator 0 "equality_operator"
4901 [(match_operand:GPR 1 "register_operand" "d,t")
4903 (match_operand 2 "pc_or_label_operand" "")
4904 (match_operand 3 "pc_or_label_operand" "")))]
4907 if (operands[2] != pc_rtx)
4909 if (which_alternative == 0)
4910 return "b%C0z\t%1,%2";
4912 return "bt%C0z\t%2";
4916 if (which_alternative == 0)
4917 return "b%N0z\t%1,%3";
4919 return "bt%N0z\t%3";
4922 [(set_attr "type" "branch")
4923 (set_attr "mode" "none")
4924 (set_attr "length" "8")])
4926 (define_expand "b<code>"
4928 (if_then_else (any_cond:CC (cc0)
4930 (label_ref (match_operand 0 ""))
4934 gen_conditional_branch (operands, <CODE>);
4938 ;; Used to implement built-in functions.
4939 (define_expand "condjump"
4941 (if_then_else (match_operand 0)
4942 (label_ref (match_operand 1))
4946 ;; ....................
4948 ;; SETTING A REGISTER FROM A COMPARISON
4950 ;; ....................
4952 (define_expand "seq"
4953 [(set (match_operand:SI 0 "register_operand")
4954 (eq:SI (match_dup 1)
4957 { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
4959 (define_insn "*seq_<mode>"
4960 [(set (match_operand:GPR 0 "register_operand" "=d")
4961 (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4965 [(set_attr "type" "slt")
4966 (set_attr "mode" "<MODE>")])
4968 (define_insn "*seq_<mode>_mips16"
4969 [(set (match_operand:GPR 0 "register_operand" "=t")
4970 (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4974 [(set_attr "type" "slt")
4975 (set_attr "mode" "<MODE>")])
4977 ;; "sne" uses sltu instructions in which the first operand is $0.
4978 ;; This isn't possible in mips16 code.
4980 (define_expand "sne"
4981 [(set (match_operand:SI 0 "register_operand")
4982 (ne:SI (match_dup 1)
4985 { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
4987 (define_insn "*sne_<mode>"
4988 [(set (match_operand:GPR 0 "register_operand" "=d")
4989 (ne:GPR (match_operand:GPR 1 "register_operand" "d")
4993 [(set_attr "type" "slt")
4994 (set_attr "mode" "<MODE>")])
4996 (define_expand "sgt"
4997 [(set (match_operand:SI 0 "register_operand")
4998 (gt:SI (match_dup 1)
5001 { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
5003 (define_insn "*sgt_<mode>"
5004 [(set (match_operand:GPR 0 "register_operand" "=d")
5005 (gt:GPR (match_operand:GPR 1 "register_operand" "d")
5006 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
5009 [(set_attr "type" "slt")
5010 (set_attr "mode" "<MODE>")])
5012 (define_insn "*sgt_<mode>_mips16"
5013 [(set (match_operand:GPR 0 "register_operand" "=t")
5014 (gt:GPR (match_operand:GPR 1 "register_operand" "d")
5015 (match_operand:GPR 2 "register_operand" "d")))]
5018 [(set_attr "type" "slt")
5019 (set_attr "mode" "<MODE>")])
5021 (define_expand "sge"
5022 [(set (match_operand:SI 0 "register_operand")
5023 (ge:SI (match_dup 1)
5026 { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
5028 (define_insn "*sge_<mode>"
5029 [(set (match_operand:GPR 0 "register_operand" "=d")
5030 (ge:GPR (match_operand:GPR 1 "register_operand" "d")
5034 [(set_attr "type" "slt")
5035 (set_attr "mode" "<MODE>")])
5037 (define_expand "slt"
5038 [(set (match_operand:SI 0 "register_operand")
5039 (lt:SI (match_dup 1)
5042 { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
5044 (define_insn "*slt_<mode>"
5045 [(set (match_operand:GPR 0 "register_operand" "=d")
5046 (lt:GPR (match_operand:GPR 1 "register_operand" "d")
5047 (match_operand:GPR 2 "arith_operand" "dI")))]
5050 [(set_attr "type" "slt")
5051 (set_attr "mode" "<MODE>")])
5053 (define_insn "*slt_<mode>_mips16"
5054 [(set (match_operand:GPR 0 "register_operand" "=t,t")
5055 (lt:GPR (match_operand:GPR 1 "register_operand" "d,d")
5056 (match_operand:GPR 2 "arith_operand" "d,I")))]
5059 [(set_attr "type" "slt")
5060 (set_attr "mode" "<MODE>")
5061 (set_attr_alternative "length"
5063 (if_then_else (match_operand 2 "m16_uimm8_1")
5067 (define_expand "sle"
5068 [(set (match_operand:SI 0 "register_operand")
5069 (le:SI (match_dup 1)
5072 { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
5074 (define_insn "*sle_<mode>"
5075 [(set (match_operand:GPR 0 "register_operand" "=d")
5076 (le:GPR (match_operand:GPR 1 "register_operand" "d")
5077 (match_operand:GPR 2 "sle_operand" "")))]
5080 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5081 return "slt\t%0,%1,%2";
5083 [(set_attr "type" "slt")
5084 (set_attr "mode" "<MODE>")])
5086 (define_insn "*sle_<mode>_mips16"
5087 [(set (match_operand:GPR 0 "register_operand" "=t")
5088 (le:GPR (match_operand:GPR 1 "register_operand" "d")
5089 (match_operand:GPR 2 "sle_operand" "")))]
5092 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5093 return "slt\t%1,%2";
5095 [(set_attr "type" "slt")
5096 (set_attr "mode" "<MODE>")
5097 (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
5101 (define_expand "sgtu"
5102 [(set (match_operand:SI 0 "register_operand")
5103 (gtu:SI (match_dup 1)
5106 { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
5108 (define_insn "*sgtu_<mode>"
5109 [(set (match_operand:GPR 0 "register_operand" "=d")
5110 (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
5111 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
5114 [(set_attr "type" "slt")
5115 (set_attr "mode" "<MODE>")])
5117 (define_insn "*sgtu_<mode>_mips16"
5118 [(set (match_operand:GPR 0 "register_operand" "=t")
5119 (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
5120 (match_operand:GPR 2 "register_operand" "d")))]
5123 [(set_attr "type" "slt")
5124 (set_attr "mode" "<MODE>")])
5126 (define_expand "sgeu"
5127 [(set (match_operand:SI 0 "register_operand")
5128 (geu:SI (match_dup 1)
5131 { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
5133 (define_insn "*sge_<mode>"
5134 [(set (match_operand:GPR 0 "register_operand" "=d")
5135 (geu:GPR (match_operand:GPR 1 "register_operand" "d")
5139 [(set_attr "type" "slt")
5140 (set_attr "mode" "<MODE>")])
5142 (define_expand "sltu"
5143 [(set (match_operand:SI 0 "register_operand")
5144 (ltu:SI (match_dup 1)
5147 { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
5149 (define_insn "*sltu_<mode>"
5150 [(set (match_operand:GPR 0 "register_operand" "=d")
5151 (ltu:GPR (match_operand:GPR 1 "register_operand" "d")
5152 (match_operand:GPR 2 "arith_operand" "dI")))]
5155 [(set_attr "type" "slt")
5156 (set_attr "mode" "<MODE>")])
5158 (define_insn "*sltu_<mode>_mips16"
5159 [(set (match_operand:GPR 0 "register_operand" "=t,t")
5160 (ltu:GPR (match_operand:GPR 1 "register_operand" "d,d")
5161 (match_operand:GPR 2 "arith_operand" "d,I")))]
5164 [(set_attr "type" "slt")
5165 (set_attr "mode" "<MODE>")
5166 (set_attr_alternative "length"
5168 (if_then_else (match_operand 2 "m16_uimm8_1")
5172 (define_expand "sleu"
5173 [(set (match_operand:SI 0 "register_operand")
5174 (leu:SI (match_dup 1)
5177 { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
5179 (define_insn "*sleu_<mode>"
5180 [(set (match_operand:GPR 0 "register_operand" "=d")
5181 (leu:GPR (match_operand:GPR 1 "register_operand" "d")
5182 (match_operand:GPR 2 "sleu_operand" "")))]
5185 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5186 return "sltu\t%0,%1,%2";
5188 [(set_attr "type" "slt")
5189 (set_attr "mode" "<MODE>")])
5191 (define_insn "*sleu_<mode>_mips16"
5192 [(set (match_operand:GPR 0 "register_operand" "=t")
5193 (leu:GPR (match_operand:GPR 1 "register_operand" "d")
5194 (match_operand:GPR 2 "sleu_operand" "")))]
5197 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5198 return "sltu\t%1,%2";
5200 [(set_attr "type" "slt")
5201 (set_attr "mode" "<MODE>")
5202 (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
5207 ;; ....................
5209 ;; FLOATING POINT COMPARISONS
5211 ;; ....................
5213 (define_insn "s<code>_<mode>"
5214 [(set (match_operand:CC 0 "register_operand" "=z")
5215 (fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
5216 (match_operand:SCALARF 2 "register_operand" "f")))]
5218 "c.<fcond>.<fmt>\t%Z0%1,%2"
5219 [(set_attr "type" "fcmp")
5220 (set_attr "mode" "FPSW")])
5222 (define_insn "s<code>_<mode>"
5223 [(set (match_operand:CC 0 "register_operand" "=z")
5224 (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
5225 (match_operand:SCALARF 2 "register_operand" "f")))]
5227 "c.<swapped_fcond>.<fmt>\t%Z0%2,%1"
5228 [(set_attr "type" "fcmp")
5229 (set_attr "mode" "FPSW")])
5232 ;; ....................
5234 ;; UNCONDITIONAL BRANCHES
5236 ;; ....................
5238 ;; Unconditional branches.
5242 (label_ref (match_operand 0 "" "")))]
5247 if (get_attr_length (insn) <= 8)
5248 return "%*b\t%l0%/";
5251 output_asm_insn (mips_output_load_label (), operands);
5252 return "%*jr\t%@%/%]";
5256 return "%*j\t%l0%/";
5258 [(set_attr "type" "jump")
5259 (set_attr "mode" "none")
5260 (set (attr "length")
5261 ;; We can't use `j' when emitting PIC. Emit a branch if it's
5262 ;; in range, otherwise load the address of the branch target into
5263 ;; $at and then jump to it.
5265 (ior (eq (symbol_ref "flag_pic") (const_int 0))
5266 (lt (abs (minus (match_dup 0)
5267 (plus (pc) (const_int 4))))
5268 (const_int 131072)))
5269 (const_int 4) (const_int 16)))])
5271 ;; We need a different insn for the mips16, because a mips16 branch
5272 ;; does not have a delay slot.
5276 (label_ref (match_operand 0 "" "")))]
5279 [(set_attr "type" "branch")
5280 (set_attr "mode" "none")
5281 (set_attr "length" "8")])
5283 (define_expand "indirect_jump"
5284 [(set (pc) (match_operand 0 "register_operand"))]
5287 operands[0] = force_reg (Pmode, operands[0]);
5288 if (Pmode == SImode)
5289 emit_jump_insn (gen_indirect_jumpsi (operands[0]));
5291 emit_jump_insn (gen_indirect_jumpdi (operands[0]));
5295 (define_insn "indirect_jump<mode>"
5296 [(set (pc) (match_operand:P 0 "register_operand" "d"))]
5299 [(set_attr "type" "jump")
5300 (set_attr "mode" "none")])
5302 (define_expand "tablejump"
5304 (match_operand 0 "register_operand"))
5305 (use (label_ref (match_operand 1 "")))]
5308 if (TARGET_MIPS16_SHORT_JUMP_TABLES)
5309 operands[0] = expand_binop (Pmode, add_optab,
5310 convert_to_mode (Pmode, operands[0], false),
5311 gen_rtx_LABEL_REF (Pmode, operands[1]),
5313 else if (TARGET_GPWORD)
5314 operands[0] = expand_binop (Pmode, add_optab, operands[0],
5315 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
5316 else if (TARGET_RTP_PIC)
5318 /* When generating RTP PIC, we use case table entries that are relative
5319 to the start of the function. Add the function's address to the
5321 rtx start = get_hard_reg_initial_val (Pmode, PIC_FUNCTION_ADDR_REGNUM);
5322 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
5323 start, 0, 0, OPTAB_WIDEN);
5326 if (Pmode == SImode)
5327 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
5329 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
5333 (define_insn "tablejump<mode>"
5335 (match_operand:P 0 "register_operand" "d"))
5336 (use (label_ref (match_operand 1 "" "")))]
5339 [(set_attr "type" "jump")
5340 (set_attr "mode" "none")])
5342 ;; For TARGET_USE_GOT, we save the gp in the jmp_buf as well.
5343 ;; While it is possible to either pull it off the stack (in the
5344 ;; o32 case) or recalculate it given t9 and our target label,
5345 ;; it takes 3 or 4 insns to do so.
5347 (define_expand "builtin_setjmp_setup"
5348 [(use (match_operand 0 "register_operand"))]
5353 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
5354 mips_emit_move (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
5358 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
5359 ;; that older code did recalculate the gp from $25. Continue to jump through
5360 ;; $25 for compatibility (we lose nothing by doing so).
5362 (define_expand "builtin_longjmp"
5363 [(use (match_operand 0 "register_operand"))]
5366 /* The elements of the buffer are, in order: */
5367 int W = GET_MODE_SIZE (Pmode);
5368 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5369 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
5370 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
5371 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
5372 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
5373 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
5374 The target is bound to be using $28 as the global pointer
5375 but the current function might not be. */
5376 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
5378 /* This bit is similar to expand_builtin_longjmp except that it
5379 restores $gp as well. */
5380 mips_emit_move (hard_frame_pointer_rtx, fp);
5381 mips_emit_move (pv, lab);
5382 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5383 mips_emit_move (gp, gpv);
5384 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5385 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5386 emit_insn (gen_rtx_USE (VOIDmode, gp));
5387 emit_indirect_jump (pv);
5392 ;; ....................
5394 ;; Function prologue/epilogue
5396 ;; ....................
5399 (define_expand "prologue"
5403 mips_expand_prologue ();
5407 ;; Block any insns from being moved before this point, since the
5408 ;; profiling call to mcount can use various registers that aren't
5409 ;; saved or used to pass arguments.
5411 (define_insn "blockage"
5412 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
5415 [(set_attr "type" "unknown")
5416 (set_attr "mode" "none")
5417 (set_attr "length" "0")])
5419 (define_expand "epilogue"
5423 mips_expand_epilogue (false);
5427 (define_expand "sibcall_epilogue"
5431 mips_expand_epilogue (true);
5435 ;; Trivial return. Make it look like a normal return insn as that
5436 ;; allows jump optimizations to work better.
5438 (define_insn "return"
5440 "mips_can_use_return_insn ()"
5442 [(set_attr "type" "jump")
5443 (set_attr "mode" "none")])
5447 (define_insn "return_internal"
5449 (use (match_operand 0 "pmode_register_operand" ""))]
5452 [(set_attr "type" "jump")
5453 (set_attr "mode" "none")])
5455 ;; This is used in compiling the unwind routines.
5456 (define_expand "eh_return"
5457 [(use (match_operand 0 "general_operand"))]
5460 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
5462 if (GET_MODE (operands[0]) != gpr_mode)
5463 operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
5465 emit_insn (gen_eh_set_lr_di (operands[0]));
5467 emit_insn (gen_eh_set_lr_si (operands[0]));
5472 ;; Clobber the return address on the stack. We can't expand this
5473 ;; until we know where it will be put in the stack frame.
5475 (define_insn "eh_set_lr_si"
5476 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5477 (clobber (match_scratch:SI 1 "=&d"))]
5481 (define_insn "eh_set_lr_di"
5482 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5483 (clobber (match_scratch:DI 1 "=&d"))]
5488 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
5489 (clobber (match_scratch 1))]
5490 "reload_completed && !TARGET_DEBUG_D_MODE"
5493 mips_set_return_address (operands[0], operands[1]);
5497 (define_insn_and_split "nonlocal_goto_receiver"
5499 (unspec_volatile:SI [(const_int 0)] UNSPEC_NONLOCAL_GOTO_RECEIVER))]
5500 "TARGET_CALL_CLOBBERED_GP"
5502 "&& reload_completed"
5508 [(set_attr "type" "load")
5509 (set_attr "length" "12")])
5512 ;; ....................
5516 ;; ....................
5518 ;; Instructions to load a call address from the GOT. The address might
5519 ;; point to a function or to a lazy binding stub. In the latter case,
5520 ;; the stub will use the dynamic linker to resolve the function, which
5521 ;; in turn will change the GOT entry to point to the function's real
5524 ;; This means that every call, even pure and constant ones, can
5525 ;; potentially modify the GOT entry. And once a stub has been called,
5526 ;; we must not call it again.
5528 ;; We represent this restriction using an imaginary fixed register that
5529 ;; acts like a GOT version number. By making the register call-clobbered,
5530 ;; we tell the target-independent code that the address could be changed
5531 ;; by any call insn.
5532 (define_insn "load_call<mode>"
5533 [(set (match_operand:P 0 "register_operand" "=d")
5534 (unspec:P [(match_operand:P 1 "register_operand" "r")
5535 (match_operand:P 2 "immediate_operand" "")
5536 (reg:P FAKE_CALL_REGNO)]
5539 "<load>\t%0,%R2(%1)"
5540 [(set_attr "type" "load")
5541 (set_attr "mode" "<MODE>")
5542 (set_attr "length" "4")])
5544 ;; Sibling calls. All these patterns use jump instructions.
5546 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
5547 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
5548 ;; is defined in terms of call_insn_operand, the same is true of the
5551 ;; When we use an indirect jump, we need a register that will be
5552 ;; preserved by the epilogue. Since TARGET_USE_PIC_FN_ADDR_REG forces
5553 ;; us to use $25 for this purpose -- and $25 is never clobbered by the
5554 ;; epilogue -- we might as well use it for !TARGET_USE_PIC_FN_ADDR_REG
5557 (define_expand "sibcall"
5558 [(parallel [(call (match_operand 0 "")
5559 (match_operand 1 ""))
5560 (use (match_operand 2 "")) ;; next_arg_reg
5561 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
5564 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
5568 (define_insn "sibcall_internal"
5569 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
5570 (match_operand 1 "" ""))]
5571 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5572 { return MIPS_CALL ("j", operands, 0); }
5573 [(set_attr "type" "call")])
5575 (define_expand "sibcall_value"
5576 [(parallel [(set (match_operand 0 "")
5577 (call (match_operand 1 "")
5578 (match_operand 2 "")))
5579 (use (match_operand 3 ""))])] ;; next_arg_reg
5582 mips_expand_call (operands[0], XEXP (operands[1], 0),
5583 operands[2], operands[3], true);
5587 (define_insn "sibcall_value_internal"
5588 [(set (match_operand 0 "register_operand" "")
5589 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5590 (match_operand 2 "" "")))]
5591 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5592 { return MIPS_CALL ("j", operands, 1); }
5593 [(set_attr "type" "call")])
5595 (define_insn "sibcall_value_multiple_internal"
5596 [(set (match_operand 0 "register_operand" "")
5597 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5598 (match_operand 2 "" "")))
5599 (set (match_operand 3 "register_operand" "")
5600 (call (mem:SI (match_dup 1))
5602 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5603 { return MIPS_CALL ("j", operands, 1); }
5604 [(set_attr "type" "call")])
5606 (define_expand "call"
5607 [(parallel [(call (match_operand 0 "")
5608 (match_operand 1 ""))
5609 (use (match_operand 2 "")) ;; next_arg_reg
5610 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
5613 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
5617 ;; This instruction directly corresponds to an assembly-language "jal".
5618 ;; There are four cases:
5621 ;; Both symbolic and register destinations are OK. The pattern
5622 ;; always expands to a single mips instruction.
5624 ;; - -mabicalls/-mno-explicit-relocs:
5625 ;; Again, both symbolic and register destinations are OK.
5626 ;; The call is treated as a multi-instruction black box.
5628 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
5629 ;; Only "jal $25" is allowed. This expands to a single "jalr $25"
5632 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
5633 ;; Only "jal $25" is allowed. The call is actually two instructions:
5634 ;; "jalr $25" followed by an insn to reload $gp.
5636 ;; In the last case, we can generate the individual instructions with
5637 ;; a define_split. There are several things to be wary of:
5639 ;; - We can't expose the load of $gp before reload. If we did,
5640 ;; it might get removed as dead, but reload can introduce new
5641 ;; uses of $gp by rematerializing constants.
5643 ;; - We shouldn't restore $gp after calls that never return.
5644 ;; It isn't valid to insert instructions between a noreturn
5645 ;; call and the following barrier.
5647 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
5648 ;; instruction preserves $gp and so have no effect on its liveness.
5649 ;; But once we generate the separate insns, it becomes obvious that
5650 ;; $gp is not live on entry to the call.
5652 ;; ??? The operands[2] = insn check is a hack to make the original insn
5653 ;; available to the splitter.
5654 (define_insn_and_split "call_internal"
5655 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
5656 (match_operand 1 "" ""))
5657 (clobber (reg:SI 31))]
5659 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0); }
5660 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
5663 emit_call_insn (gen_call_split (operands[0], operands[1]));
5664 if (!find_reg_note (operands[2], REG_NORETURN, 0))
5668 [(set_attr "jal" "indirect,direct")
5669 (set_attr "extended_mips16" "no,yes")])
5671 ;; A pattern for calls that must be made directly. It is used for
5672 ;; MIPS16 calls that the linker may need to redirect to a hard-float
5673 ;; stub; the linker relies on the call relocation type to detect when
5674 ;; such redirection is needed.
5675 (define_insn "call_internal_direct"
5676 [(call (mem:SI (match_operand 0 "const_call_insn_operand"))
5679 (clobber (reg:SI 31))]
5681 { return MIPS_CALL ("jal", operands, 0); })
5683 (define_insn "call_split"
5684 [(call (mem:SI (match_operand 0 "call_insn_operand" "cS"))
5685 (match_operand 1 "" ""))
5686 (clobber (reg:SI 31))
5687 (clobber (reg:SI 28))]
5688 "TARGET_SPLIT_CALLS"
5689 { return MIPS_CALL ("jal", operands, 0); }
5690 [(set_attr "type" "call")])
5692 (define_expand "call_value"
5693 [(parallel [(set (match_operand 0 "")
5694 (call (match_operand 1 "")
5695 (match_operand 2 "")))
5696 (use (match_operand 3 ""))])] ;; next_arg_reg
5699 mips_expand_call (operands[0], XEXP (operands[1], 0),
5700 operands[2], operands[3], false);
5704 ;; See comment for call_internal.
5705 (define_insn_and_split "call_value_internal"
5706 [(set (match_operand 0 "register_operand" "")
5707 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5708 (match_operand 2 "" "")))
5709 (clobber (reg:SI 31))]
5711 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
5712 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
5715 emit_call_insn (gen_call_value_split (operands[0], operands[1],
5717 if (!find_reg_note (operands[3], REG_NORETURN, 0))
5721 [(set_attr "jal" "indirect,direct")
5722 (set_attr "extended_mips16" "no,yes")])
5724 (define_insn "call_value_split"
5725 [(set (match_operand 0 "register_operand" "")
5726 (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
5727 (match_operand 2 "" "")))
5728 (clobber (reg:SI 31))
5729 (clobber (reg:SI 28))]
5730 "TARGET_SPLIT_CALLS"
5731 { return MIPS_CALL ("jal", operands, 1); }
5732 [(set_attr "type" "call")])
5734 ;; See call_internal_direct.
5735 (define_insn "call_value_internal_direct"
5736 [(set (match_operand 0 "register_operand")
5737 (call (mem:SI (match_operand 1 "const_call_insn_operand"))
5740 (clobber (reg:SI 31))]
5742 { return MIPS_CALL ("jal", operands, 1); })
5744 ;; See comment for call_internal.
5745 (define_insn_and_split "call_value_multiple_internal"
5746 [(set (match_operand 0 "register_operand" "")
5747 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5748 (match_operand 2 "" "")))
5749 (set (match_operand 3 "register_operand" "")
5750 (call (mem:SI (match_dup 1))
5752 (clobber (reg:SI 31))]
5754 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
5755 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
5758 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
5759 operands[2], operands[3]));
5760 if (!find_reg_note (operands[4], REG_NORETURN, 0))
5764 [(set_attr "jal" "indirect,direct")
5765 (set_attr "extended_mips16" "no,yes")])
5767 (define_insn "call_value_multiple_split"
5768 [(set (match_operand 0 "register_operand" "")
5769 (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
5770 (match_operand 2 "" "")))
5771 (set (match_operand 3 "register_operand" "")
5772 (call (mem:SI (match_dup 1))
5774 (clobber (reg:SI 31))
5775 (clobber (reg:SI 28))]
5776 "TARGET_SPLIT_CALLS"
5777 { return MIPS_CALL ("jal", operands, 1); }
5778 [(set_attr "type" "call")])
5780 ;; Call subroutine returning any type.
5782 (define_expand "untyped_call"
5783 [(parallel [(call (match_operand 0 "")
5785 (match_operand 1 "")
5786 (match_operand 2 "")])]
5791 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
5793 for (i = 0; i < XVECLEN (operands[2], 0); i++)
5795 rtx set = XVECEXP (operands[2], 0, i);
5796 mips_emit_move (SET_DEST (set), SET_SRC (set));
5799 emit_insn (gen_blockage ());
5804 ;; ....................
5808 ;; ....................
5812 (define_insn "prefetch"
5813 [(prefetch (match_operand:QI 0 "address_operand" "p")
5814 (match_operand 1 "const_int_operand" "n")
5815 (match_operand 2 "const_int_operand" "n"))]
5816 "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
5818 operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
5819 return "pref\t%1,%a0";
5821 [(set_attr "type" "prefetch")])
5823 (define_insn "*prefetch_indexed_<mode>"
5824 [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
5825 (match_operand:P 1 "register_operand" "d"))
5826 (match_operand 2 "const_int_operand" "n")
5827 (match_operand 3 "const_int_operand" "n"))]
5828 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5830 operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
5831 return "prefx\t%2,%1(%0)";
5833 [(set_attr "type" "prefetchx")])
5839 [(set_attr "type" "nop")
5840 (set_attr "mode" "none")])
5842 ;; Like nop, but commented out when outside a .set noreorder block.
5843 (define_insn "hazard_nop"
5852 [(set_attr "type" "nop")])
5854 ;; MIPS4 Conditional move instructions.
5856 (define_insn "*mov<GPR:mode>_on_<MOVECC:mode>"
5857 [(set (match_operand:GPR 0 "register_operand" "=d,d")
5859 (match_operator:MOVECC 4 "equality_operator"
5860 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5862 (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
5863 (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
5868 [(set_attr "type" "condmove")
5869 (set_attr "mode" "<GPR:MODE>")])
5871 (define_insn "*mov<SCALARF:mode>_on_<MOVECC:mode>"
5872 [(set (match_operand:SCALARF 0 "register_operand" "=f,f")
5873 (if_then_else:SCALARF
5874 (match_operator:MOVECC 4 "equality_operator"
5875 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5877 (match_operand:SCALARF 2 "register_operand" "f,0")
5878 (match_operand:SCALARF 3 "register_operand" "0,f")))]
5881 mov%T4.<fmt>\t%0,%2,%1
5882 mov%t4.<fmt>\t%0,%3,%1"
5883 [(set_attr "type" "condmove")
5884 (set_attr "mode" "<SCALARF:MODE>")])
5886 ;; These are the main define_expand's used to make conditional moves.
5888 (define_expand "mov<mode>cc"
5889 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5890 (set (match_operand:GPR 0 "register_operand")
5891 (if_then_else:GPR (match_dup 5)
5892 (match_operand:GPR 2 "reg_or_0_operand")
5893 (match_operand:GPR 3 "reg_or_0_operand")))]
5896 gen_conditional_move (operands);
5900 (define_expand "mov<mode>cc"
5901 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5902 (set (match_operand:SCALARF 0 "register_operand")
5903 (if_then_else:SCALARF (match_dup 5)
5904 (match_operand:SCALARF 2 "register_operand")
5905 (match_operand:SCALARF 3 "register_operand")))]
5908 gen_conditional_move (operands);
5913 ;; ....................
5915 ;; mips16 inline constant tables
5917 ;; ....................
5920 (define_insn "consttable_int"
5921 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
5922 (match_operand 1 "const_int_operand" "")]
5923 UNSPEC_CONSTTABLE_INT)]
5926 assemble_integer (operands[0], INTVAL (operands[1]),
5927 BITS_PER_UNIT * INTVAL (operands[1]), 1);
5930 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
5932 (define_insn "consttable_float"
5933 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
5934 UNSPEC_CONSTTABLE_FLOAT)]
5939 gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
5940 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
5941 assemble_real (d, GET_MODE (operands[0]),
5942 GET_MODE_BITSIZE (GET_MODE (operands[0])));
5945 [(set (attr "length")
5946 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
5948 (define_insn "align"
5949 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
5952 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
5955 [(match_operand 0 "small_data_pattern")]
5958 { operands[0] = mips_rewrite_small_data (operands[0]); })
5961 ;; ....................
5963 ;; MIPS16e Save/Restore
5965 ;; ....................
5968 (define_insn "*mips16e_save_restore"
5969 [(match_parallel 0 ""
5970 [(set (match_operand:SI 1 "register_operand")
5971 (plus:SI (match_dup 1)
5972 (match_operand:SI 2 "const_int_operand")))])]
5973 "operands[1] == stack_pointer_rtx
5974 && mips16e_save_restore_pattern_p (operands[0], INTVAL (operands[2]), NULL)"
5975 { return mips16e_output_save_restore (operands[0], INTVAL (operands[2])); }
5976 [(set_attr "type" "arith")
5977 (set_attr "extended_mips16" "yes")])
5979 ; Thread-Local Storage
5981 ; The TLS base pointer is accessed via "rdhwr $v1, $29". No current
5982 ; MIPS architecture defines this register, and no current
5983 ; implementation provides it; instead, any OS which supports TLS is
5984 ; expected to trap and emulate this instruction. rdhwr is part of the
5985 ; MIPS 32r2 specification, but we use it on any architecture because
5986 ; we expect it to be emulated. Use .set to force the assembler to
5989 (define_insn "tls_get_tp_<mode>"
5990 [(set (match_operand:P 0 "register_operand" "=v")
5991 (unspec:P [(const_int 0)]
5992 UNSPEC_TLS_GET_TP))]
5993 "HAVE_AS_TLS && !TARGET_MIPS16"
5994 ".set\tpush\;.set\tmips32r2\t\;rdhwr\t%0,$29\;.set\tpop"
5995 [(set_attr "type" "unknown")
5996 ; Since rdhwr always generates a trap for now, putting it in a delay
5997 ; slot would make the kernel's emulation of it much slower.
5998 (set_attr "can_delay" "no")
5999 (set_attr "mode" "<MODE>")])
6001 ; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
6003 (include "mips-ps-3d.md")
6005 ; The MIPS DSP Instructions.
6007 (include "mips-dsp.md")
6009 ; The MIPS DSP REV 2 Instructions.
6011 (include "mips-dspr2.md")