1 ;; Mips.md Machine Description for MIPS based processors
2 ;; Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 ;; Contributed by A. Lichnewsky, lich@inria.inria.fr
5 ;; Changes by Michael Meissner, meissner@osf.org
6 ;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
7 ;; Brendan Eich, brendan@microunity.com.
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING. If not, write to
23 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
26 ;; ??? Currently does not have define_function_unit support for the R8000.
27 ;; Must include new entries for fmadd in addition to existing entries.
30 [(UNSPEC_LOAD_DF_LOW 0)
31 (UNSPEC_LOAD_DF_HIGH 1)
32 (UNSPEC_STORE_DF_HIGH 2)
36 (UNSPEC_EH_RECEIVER 6)
38 (UNSPEC_CONSTTABLE_INT 8)
39 (UNSPEC_CONSTTABLE_FLOAT 9)
56 (UNSPEC_ADDRESS_FIRST 100)
58 (FAKE_CALL_REGNO 79)])
60 ;; ....................
64 ;; ....................
66 (define_attr "got" "unset,xgot_high,load"
67 (const_string "unset"))
69 ;; For jal instructions, this attribute is DIRECT when the target address
70 ;; is symbolic and INDIRECT when it is a register.
71 (define_attr "jal" "unset,direct,indirect"
72 (const_string "unset"))
74 ;; This attribute is YES if the instruction is a jal macro (not a
75 ;; real jal instruction).
77 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
78 ;; restore $gp. Direct jals are also macros in NewABI PIC since they
79 ;; load the target address into $25.
80 (define_attr "jal_macro" "no,yes"
81 (cond [(eq_attr "jal" "direct")
82 (symbol_ref "TARGET_ABICALLS != 0")
83 (eq_attr "jal" "indirect")
84 (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
87 ;; Classification of each insn.
88 ;; branch conditional branch
89 ;; jump unconditional jump
90 ;; call unconditional call
91 ;; load load instruction(s)
92 ;; fpload floating point load
93 ;; fpidxload floating point indexed load
94 ;; store store instruction(s)
95 ;; fpstore floating point store
96 ;; fpidxstore floating point indexed store
97 ;; prefetch memory prefetch (register + offset)
98 ;; prefetchx memory indexed prefetch (register + register)
99 ;; condmove conditional moves
100 ;; xfer transfer to/from coprocessor
101 ;; mthilo transfer to hi/lo registers
102 ;; mfhilo transfer from hi/lo registers
103 ;; const load constant
104 ;; arith integer arithmetic and logical instructions
105 ;; shift integer shift instructions
106 ;; slt set less than instructions
107 ;; clz the clz and clo instructions
108 ;; trap trap if instructions
109 ;; imul integer multiply
110 ;; imadd integer multiply-add
111 ;; idiv integer divide
112 ;; fmove floating point register move
113 ;; fadd floating point add/subtract
114 ;; fmul floating point multiply
115 ;; fmadd floating point multiply-add
116 ;; fdiv floating point divide
117 ;; fabs floating point absolute value
118 ;; fneg floating point negation
119 ;; fcmp floating point compare
120 ;; fcvt floating point convert
121 ;; fsqrt floating point square root
122 ;; frsqrt floating point reciprocal square root
123 ;; multi multiword sequence (or user asm statements)
126 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
127 (cond [(eq_attr "jal" "!unset") (const_string "call")
128 (eq_attr "got" "load") (const_string "load")]
129 (const_string "unknown")))
131 ;; Main data type used by the insn
132 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
133 (const_string "unknown"))
135 ;; Is this an extended instruction in mips16 mode?
136 (define_attr "extended_mips16" "no,yes"
139 ;; Length of instruction in bytes.
140 (define_attr "length" ""
141 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
142 ;; If a branch is outside this range, we have a choice of two
143 ;; sequences. For PIC, an out-of-range branch like:
148 ;; becomes the equivalent of:
157 ;; where the load address can be up to three instructions long
160 ;; The non-PIC case is similar except that we use a direct
161 ;; jump instead of an la/jr pair. Since the target of this
162 ;; jump is an absolute 28-bit bit address (the other bits
163 ;; coming from the address of the delay slot) this form cannot
164 ;; cross a 256MB boundary. We could provide the option of
165 ;; using la/jr in this case too, but we do not do so at
168 ;; Note that this value does not account for the delay slot
169 ;; instruction, whose length is added separately. If the RTL
170 ;; pattern has no explicit delay slot, mips_adjust_insn_length
171 ;; will add the length of the implicit nop. The values for
172 ;; forward and backward branches will be different as well.
173 (eq_attr "type" "branch")
174 (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
175 (le (minus (pc) (match_dup 1)) (const_int 131068)))
177 (ne (symbol_ref "flag_pic") (const_int 0))
181 (eq_attr "got" "load")
183 (eq_attr "got" "xgot_high")
186 (eq_attr "type" "const")
187 (symbol_ref "mips_const_insns (operands[1]) * 4")
188 (eq_attr "type" "load,fpload,fpidxload")
189 (symbol_ref "mips_fetch_insns (operands[1]) * 4")
190 (eq_attr "type" "store,fpstore,fpidxstore")
191 (symbol_ref "mips_fetch_insns (operands[0]) * 4")
193 ;; In the worst case, a call macro will take 8 instructions:
195 ;; lui $25,%call_hi(FOO)
197 ;; lw $25,%call_lo(FOO)($25)
203 (eq_attr "jal_macro" "yes")
206 (and (eq_attr "extended_mips16" "yes")
207 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
210 ;; Various VR4120 errata require a nop to be inserted after a macc
211 ;; instruction. The assembler does this for us, so account for
212 ;; the worst-case length here.
213 (and (eq_attr "type" "imadd")
214 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
217 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
218 ;; the result of the second one is missed. The assembler should work
219 ;; around this by inserting a nop after the first dmult.
220 (and (eq_attr "type" "imul")
221 (and (eq_attr "mode" "DI")
222 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
225 (eq_attr "type" "idiv")
226 (symbol_ref "mips_idiv_insns () * 4")
229 ;; Attribute describing the processor. This attribute must match exactly
230 ;; with the processor_type enumeration in mips.h.
232 "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
233 (const (symbol_ref "mips_tune")))
235 ;; The type of hardware hazard associated with this instruction.
236 ;; DELAY means that the next instruction cannot read the result
237 ;; of this one. HILO means that the next two instructions cannot
238 ;; write to HI or LO.
239 (define_attr "hazard" "none,delay,hilo"
240 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
241 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
242 (const_string "delay")
244 (and (eq_attr "type" "xfer")
245 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
246 (const_string "delay")
248 (and (eq_attr "type" "fcmp")
249 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
250 (const_string "delay")
252 ;; The r4000 multiplication patterns include an mflo instruction.
253 (and (eq_attr "type" "imul")
254 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
255 (const_string "hilo")
257 (and (eq_attr "type" "mfhilo")
258 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
259 (const_string "hilo")]
260 (const_string "none")))
262 ;; Is it a single instruction?
263 (define_attr "single_insn" "no,yes"
264 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
266 ;; Can the instruction be put into a delay slot?
267 (define_attr "can_delay" "no,yes"
268 (if_then_else (and (eq_attr "type" "!branch,call,jump")
269 (and (eq_attr "hazard" "none")
270 (eq_attr "single_insn" "yes")))
272 (const_string "no")))
274 ;; Attribute defining whether or not we can use the branch-likely instructions
275 (define_attr "branch_likely" "no,yes"
277 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
279 (const_string "no"))))
281 ;; True if an instruction might assign to hi or lo when reloaded.
282 ;; This is used by the TUNE_MACC_CHAINS code.
283 (define_attr "may_clobber_hilo" "no,yes"
284 (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
286 (const_string "no")))
288 ;; Describe a user's asm statement.
289 (define_asm_attributes
290 [(set_attr "type" "multi")])
292 ;; .........................
294 ;; Branch, call and jump delay slots
296 ;; .........................
298 (define_delay (and (eq_attr "type" "branch")
299 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
300 [(eq_attr "can_delay" "yes")
302 (and (eq_attr "branch_likely" "yes")
303 (eq_attr "can_delay" "yes"))])
305 (define_delay (eq_attr "type" "jump")
306 [(eq_attr "can_delay" "yes")
310 (define_delay (and (eq_attr "type" "call")
311 (eq_attr "jal_macro" "no"))
312 [(eq_attr "can_delay" "yes")
316 ;; .........................
320 ;; .........................
322 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
323 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
325 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
327 (define_function_unit "memory" 1 0
328 (and (eq_attr "type" "load,fpload,fpidxload")
329 (eq_attr "cpu" "r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
332 (define_function_unit "memory" 1 0
333 (and (eq_attr "type" "load,fpload,fpidxload")
334 (eq_attr "cpu" "r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
337 (define_function_unit "memory" 1 0
338 (eq_attr "type" "store,fpstore,fpidxstore")
341 (define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)
343 (define_function_unit "imuldiv" 1 0
344 (eq_attr "type" "mthilo,mfhilo")
347 (define_function_unit "imuldiv" 1 0
348 (and (eq_attr "type" "imul,imadd")
349 (eq_attr "cpu" "r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
352 ;; On them mips16, we want to stronly discourage a mult from appearing
353 ;; after an mflo, since that requires explicit nop instructions. We
354 ;; do this by pretending that mflo ties up the function unit for long
355 ;; enough that the scheduler will ignore load stalls and the like when
356 ;; selecting instructions to between the two instructions.
358 (define_function_unit "imuldiv" 1 0
359 (and (eq_attr "type" "mfhilo") (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
362 (define_function_unit "imuldiv" 1 0
363 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r3900"))
366 (define_function_unit "imuldiv" 1 0
367 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4000,r4600"))
370 (define_function_unit "imuldiv" 1 0
371 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4650"))
374 (define_function_unit "imuldiv" 1 0
375 (and (eq_attr "type" "imul,imadd")
376 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
379 (define_function_unit "imuldiv" 1 0
380 (and (eq_attr "type" "imul,imadd")
381 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
384 (define_function_unit "imuldiv" 1 0
385 (and (eq_attr "type" "imul,imadd")
386 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
389 (define_function_unit "imuldiv" 1 0
390 (and (eq_attr "type" "imul,imadd")
391 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
394 (define_function_unit "imuldiv" 1 0
395 (and (eq_attr "type" "imul,imadd")
396 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
399 (define_function_unit "imuldiv" 1 0
400 (and (eq_attr "type" "idiv")
401 (eq_attr "cpu" "r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
404 (define_function_unit "imuldiv" 1 0
405 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3900"))
408 (define_function_unit "imuldiv" 1 0
409 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
412 (define_function_unit "imuldiv" 1 0
413 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
416 (define_function_unit "imuldiv" 1 0
417 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
420 (define_function_unit "imuldiv" 1 0
421 (and (eq_attr "type" "idiv")
422 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
425 (define_function_unit "imuldiv" 1 0
426 (and (eq_attr "type" "idiv")
427 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
430 (define_function_unit "imuldiv" 1 0
431 (and (eq_attr "type" "idiv")
432 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
435 (define_function_unit "imuldiv" 1 0
436 (and (eq_attr "type" "idiv")
437 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
440 (define_function_unit "imuldiv" 1 0
441 (and (eq_attr "type" "idiv")
442 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
445 (define_function_unit "imuldiv" 1 0
446 (and (eq_attr "type" "idiv")
447 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
450 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
451 ;; the FP hardware is part of the normal ALU circuitry. This means FP
452 ;; instructions affect the pipe-line, and no functional unit
453 ;; parallelism can occur on R4300 processors. To force GCC into coding
454 ;; for only a single functional unit, we force the R4300 FP
455 ;; instructions to be processed in the "imuldiv" unit.
457 (define_function_unit "adder" 1 1
458 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3900,r6000,r4300,r5000"))
461 (define_function_unit "adder" 1 1
462 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3900,r6000"))
465 (define_function_unit "adder" 1 1
466 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
469 (define_function_unit "adder" 1 1
470 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3900,r6000,r4300"))
473 (define_function_unit "adder" 1 1
474 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3900"))
477 (define_function_unit "adder" 1 1
478 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
481 (define_function_unit "adder" 1 1
482 (and (eq_attr "type" "fabs,fneg,fmove")
483 (eq_attr "cpu" "r3900,r4600,r4650,r4300,r5000"))
486 (define_function_unit "adder" 1 1
487 (and (eq_attr "type" "fabs,fneg,fmove") (eq_attr "cpu" "r3900,r4600,r4650,r5000"))
490 (define_function_unit "mult" 1 1
491 (and (eq_attr "type" "fmul")
492 (and (eq_attr "mode" "SF")
493 (eq_attr "cpu" "r3900,r6000,r4600,r4650,r4300,r5000")))
496 (define_function_unit "mult" 1 1
497 (and (eq_attr "type" "fmul")
498 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3900,r5000")))
501 (define_function_unit "mult" 1 1
502 (and (eq_attr "type" "fmul")
503 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
506 (define_function_unit "mult" 1 1
507 (and (eq_attr "type" "fmul")
508 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
511 (define_function_unit "mult" 1 1
512 (and (eq_attr "type" "fmul")
513 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3900,r6000,r4300,r5000")))
516 (define_function_unit "mult" 1 1
517 (and (eq_attr "type" "fmul")
518 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3900,r5000")))
521 (define_function_unit "mult" 1 1
522 (and (eq_attr "type" "fmul")
523 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
526 (define_function_unit "divide" 1 1
527 (and (eq_attr "type" "fdiv")
528 (and (eq_attr "mode" "SF")
529 (eq_attr "cpu" "r3900,r6000,r4600,r4650,r4300,r5000")))
532 (define_function_unit "divide" 1 1
533 (and (eq_attr "type" "fdiv")
534 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3900")))
537 (define_function_unit "divide" 1 1
538 (and (eq_attr "type" "fdiv")
539 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
542 (define_function_unit "divide" 1 1
543 (and (eq_attr "type" "fdiv")
544 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
547 (define_function_unit "divide" 1 1
548 (and (eq_attr "type" "fdiv")
549 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
552 (define_function_unit "divide" 1 1
553 (and (eq_attr "type" "fdiv")
554 (and (eq_attr "mode" "DF")
555 (eq_attr "cpu" "r3900,r6000,r4600,r4650,r4300")))
558 (define_function_unit "divide" 1 1
559 (and (eq_attr "type" "fdiv")
560 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3900")))
563 (define_function_unit "divide" 1 1
564 (and (eq_attr "type" "fdiv")
565 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
568 (define_function_unit "divide" 1 1
569 (and (eq_attr "type" "fdiv")
570 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
573 ;;; ??? Is this number right?
574 (define_function_unit "divide" 1 1
575 (and (eq_attr "type" "fsqrt,frsqrt")
576 (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
579 (define_function_unit "divide" 1 1
580 (and (eq_attr "type" "fsqrt,frsqrt")
581 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
584 (define_function_unit "divide" 1 1
585 (and (eq_attr "type" "fsqrt,frsqrt")
586 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
589 ;;; ??? Is this number right?
590 (define_function_unit "divide" 1 1
591 (and (eq_attr "type" "fsqrt,frsqrt")
592 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
595 (define_function_unit "divide" 1 1
596 (and (eq_attr "type" "fsqrt,frsqrt")
597 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
600 (define_function_unit "divide" 1 1
601 (and (eq_attr "type" "fsqrt,frsqrt")
602 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
605 ;; R4300 FP instruction classes treated as part of the "imuldiv"
608 (define_function_unit "imuldiv" 1 0
609 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
612 (define_function_unit "imuldiv" 1 0
613 (and (eq_attr "type" "fcmp,fabs,fneg,fmove") (eq_attr "cpu" "r4300"))
616 (define_function_unit "imuldiv" 1 0
617 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
619 (define_function_unit "imuldiv" 1 0
620 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
623 (define_function_unit "imuldiv" 1 0
624 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
625 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
627 (define_function_unit "imuldiv" 1 0
628 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
629 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
632 ;; Include scheduling descriptions.
644 ;; ....................
648 ;; ....................
652 [(trap_if (const_int 1) (const_int 0))]
655 if (ISA_HAS_COND_TRAP)
657 /* The IRIX 6 O32 assembler requires the first break operand. */
658 else if (TARGET_MIPS16 || !TARGET_GAS)
663 [(set_attr "type" "trap")])
665 (define_expand "conditional_trap"
666 [(trap_if (match_operator 0 "cmp_op"
667 [(match_dup 2) (match_dup 3)])
668 (match_operand 1 "const_int_operand"))]
671 if (operands[1] == const0_rtx)
673 mips_gen_conditional_trap (operands);
681 [(trap_if (match_operator 0 "trap_cmp_op"
682 [(match_operand:SI 1 "reg_or_0_operand" "dJ")
683 (match_operand:SI 2 "arith_operand" "dI")])
687 [(set_attr "type" "trap")])
690 [(trap_if (match_operator 0 "trap_cmp_op"
691 [(match_operand:DI 1 "reg_or_0_operand" "dJ")
692 (match_operand:DI 2 "arith_operand" "dI")])
694 "TARGET_64BIT && ISA_HAS_COND_TRAP"
696 [(set_attr "type" "trap")])
699 ;; ....................
703 ;; ....................
706 (define_insn "adddf3"
707 [(set (match_operand:DF 0 "register_operand" "=f")
708 (plus:DF (match_operand:DF 1 "register_operand" "f")
709 (match_operand:DF 2 "register_operand" "f")))]
710 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
712 [(set_attr "type" "fadd")
713 (set_attr "mode" "DF")])
715 (define_insn "addsf3"
716 [(set (match_operand:SF 0 "register_operand" "=f")
717 (plus:SF (match_operand:SF 1 "register_operand" "f")
718 (match_operand:SF 2 "register_operand" "f")))]
721 [(set_attr "type" "fadd")
722 (set_attr "mode" "SF")])
724 (define_expand "addsi3"
725 [(set (match_operand:SI 0 "register_operand")
726 (plus:SI (match_operand:SI 1 "reg_or_0_operand")
727 (match_operand:SI 2 "arith_operand")))]
730 /* If a large stack adjustment was forced into a register, we may be
731 asked to generate rtx such as:
733 (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo)))
735 but no such instruction is available in mips16. Handle it by
736 using a temporary. */
738 && REGNO (operands[0]) == STACK_POINTER_REGNUM
739 && ((GET_CODE (operands[1]) == REG
740 && REGNO (operands[1]) != STACK_POINTER_REGNUM)
741 || GET_CODE (operands[2]) != CONST_INT))
743 rtx tmp = gen_reg_rtx (SImode);
745 emit_move_insn (tmp, operands[1]);
746 emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
747 emit_move_insn (operands[0], tmp);
752 (define_insn "addsi3_internal"
753 [(set (match_operand:SI 0 "register_operand" "=d,d")
754 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
755 (match_operand:SI 2 "arith_operand" "d,Q")))]
760 [(set_attr "type" "arith")
761 (set_attr "mode" "SI")])
763 ;; For the mips16, we need to recognize stack pointer additions
764 ;; explicitly, since we don't have a constraint for $sp. These insns
765 ;; will be generated by the save_restore_insns functions.
770 (match_operand:SI 0 "small_int" "I")))]
773 [(set_attr "type" "arith")
774 (set_attr "mode" "SI")
775 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
780 [(set (match_operand:SI 0 "register_operand" "=d")
782 (match_operand:SI 1 "small_int" "I")))]
785 [(set_attr "type" "arith")
786 (set_attr "mode" "SI")
787 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4")
792 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
793 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
794 (match_operand:SI 2 "arith_operand" "Q,O,d")))]
796 && (GET_CODE (operands[1]) != REG
797 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
798 || M16_REG_P (REGNO (operands[1]))
799 || REGNO (operands[1]) == ARG_POINTER_REGNUM
800 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
801 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
802 && (GET_CODE (operands[2]) != REG
803 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
804 || M16_REG_P (REGNO (operands[2]))
805 || REGNO (operands[2]) == ARG_POINTER_REGNUM
806 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
807 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
809 if (REGNO (operands[0]) == REGNO (operands[1]))
810 return "addu\t%0,%2";
812 return "addu\t%0,%1,%2";
814 [(set_attr "type" "arith")
815 (set_attr "mode" "SI")
816 (set_attr_alternative "length"
817 [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
820 (if_then_else (match_operand:VOID 2 "m16_simm4_1")
826 ;; On the mips16, we can sometimes split an add of a constant which is
827 ;; a 4 byte instruction into two adds which are both 2 byte
828 ;; instructions. There are two cases: one where we are adding a
829 ;; constant plus a register to another register, and one where we are
830 ;; simply adding a constant to a register.
833 [(set (match_operand:SI 0 "register_operand")
834 (plus:SI (match_dup 0)
835 (match_operand:SI 1 "const_int_operand")))]
836 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
837 && GET_CODE (operands[0]) == REG
838 && M16_REG_P (REGNO (operands[0]))
839 && GET_CODE (operands[1]) == CONST_INT
840 && ((INTVAL (operands[1]) > 0x7f
841 && INTVAL (operands[1]) <= 0x7f + 0x7f)
842 || (INTVAL (operands[1]) < - 0x80
843 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
844 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
845 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
847 HOST_WIDE_INT val = INTVAL (operands[1]);
851 operands[1] = GEN_INT (0x7f);
852 operands[2] = GEN_INT (val - 0x7f);
856 operands[1] = GEN_INT (- 0x80);
857 operands[2] = GEN_INT (val + 0x80);
862 [(set (match_operand:SI 0 "register_operand")
863 (plus:SI (match_operand:SI 1 "register_operand")
864 (match_operand:SI 2 "const_int_operand")))]
865 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
866 && GET_CODE (operands[0]) == REG
867 && M16_REG_P (REGNO (operands[0]))
868 && GET_CODE (operands[1]) == REG
869 && M16_REG_P (REGNO (operands[1]))
870 && REGNO (operands[0]) != REGNO (operands[1])
871 && GET_CODE (operands[2]) == CONST_INT
872 && ((INTVAL (operands[2]) > 0x7
873 && INTVAL (operands[2]) <= 0x7 + 0x7f)
874 || (INTVAL (operands[2]) < - 0x8
875 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
876 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
877 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
879 HOST_WIDE_INT val = INTVAL (operands[2]);
883 operands[2] = GEN_INT (0x7);
884 operands[3] = GEN_INT (val - 0x7);
888 operands[2] = GEN_INT (- 0x8);
889 operands[3] = GEN_INT (val + 0x8);
893 (define_expand "adddi3"
894 [(set (match_operand:DI 0 "register_operand")
895 (plus:DI (match_operand:DI 1 "register_operand")
896 (match_operand:DI 2 "arith_operand")))]
899 /* If a large stack adjustment was forced into a register, we may be
900 asked to generate rtx such as:
902 (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo)))
904 but no such instruction is available in mips16. Handle it by
905 using a temporary. */
907 && REGNO (operands[0]) == STACK_POINTER_REGNUM
908 && ((GET_CODE (operands[1]) == REG
909 && REGNO (operands[1]) != STACK_POINTER_REGNUM)
910 || GET_CODE (operands[2]) != CONST_INT))
912 rtx tmp = gen_reg_rtx (DImode);
914 emit_move_insn (tmp, operands[1]);
915 emit_insn (gen_adddi3 (tmp, tmp, operands[2]));
916 emit_move_insn (operands[0], tmp);
921 (define_insn "adddi3_internal"
922 [(set (match_operand:DI 0 "register_operand" "=d,d")
923 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")
924 (match_operand:DI 2 "arith_operand" "d,Q")))]
925 "TARGET_64BIT && !TARGET_MIPS16"
929 [(set_attr "type" "arith")
930 (set_attr "mode" "DI")])
932 ;; For the mips16, we need to recognize stack pointer additions
933 ;; explicitly, since we don't have a constraint for $sp. These insns
934 ;; will be generated by the save_restore_insns functions.
939 (match_operand:DI 0 "small_int" "I")))]
940 "TARGET_MIPS16 && TARGET_64BIT"
942 [(set_attr "type" "arith")
943 (set_attr "mode" "DI")
944 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
949 [(set (match_operand:DI 0 "register_operand" "=d")
951 (match_operand:DI 1 "small_int" "I")))]
952 "TARGET_MIPS16 && TARGET_64BIT"
954 [(set_attr "type" "arith")
955 (set_attr "mode" "DI")
956 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4")
961 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
962 (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
963 (match_operand:DI 2 "arith_operand" "Q,O,d")))]
964 "TARGET_MIPS16 && TARGET_64BIT
965 && (GET_CODE (operands[1]) != REG
966 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
967 || M16_REG_P (REGNO (operands[1]))
968 || REGNO (operands[1]) == ARG_POINTER_REGNUM
969 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
970 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
971 && (GET_CODE (operands[2]) != REG
972 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
973 || M16_REG_P (REGNO (operands[2]))
974 || REGNO (operands[2]) == ARG_POINTER_REGNUM
975 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
976 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
978 if (REGNO (operands[0]) == REGNO (operands[1]))
979 return "daddu\t%0,%2";
981 return "daddu\t%0,%1,%2";
983 [(set_attr "type" "arith")
984 (set_attr "mode" "DI")
985 (set_attr_alternative "length"
986 [(if_then_else (match_operand:VOID 2 "m16_simm5_1")
989 (if_then_else (match_operand:VOID 2 "m16_simm4_1")
995 ;; On the mips16, we can sometimes split an add of a constant which is
996 ;; a 4 byte instruction into two adds which are both 2 byte
997 ;; instructions. There are two cases: one where we are adding a
998 ;; constant plus a register to another register, and one where we are
999 ;; simply adding a constant to a register.
1002 [(set (match_operand:DI 0 "register_operand")
1003 (plus:DI (match_dup 0)
1004 (match_operand:DI 1 "const_int_operand")))]
1005 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1006 && GET_CODE (operands[0]) == REG
1007 && M16_REG_P (REGNO (operands[0]))
1008 && GET_CODE (operands[1]) == CONST_INT
1009 && ((INTVAL (operands[1]) > 0xf
1010 && INTVAL (operands[1]) <= 0xf + 0xf)
1011 || (INTVAL (operands[1]) < - 0x10
1012 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1013 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1014 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1016 HOST_WIDE_INT val = INTVAL (operands[1]);
1020 operands[1] = GEN_INT (0xf);
1021 operands[2] = GEN_INT (val - 0xf);
1025 operands[1] = GEN_INT (- 0x10);
1026 operands[2] = GEN_INT (val + 0x10);
1031 [(set (match_operand:DI 0 "register_operand")
1032 (plus:DI (match_operand:DI 1 "register_operand")
1033 (match_operand:DI 2 "const_int_operand")))]
1034 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1035 && GET_CODE (operands[0]) == REG
1036 && M16_REG_P (REGNO (operands[0]))
1037 && GET_CODE (operands[1]) == REG
1038 && M16_REG_P (REGNO (operands[1]))
1039 && REGNO (operands[0]) != REGNO (operands[1])
1040 && GET_CODE (operands[2]) == CONST_INT
1041 && ((INTVAL (operands[2]) > 0x7
1042 && INTVAL (operands[2]) <= 0x7 + 0xf)
1043 || (INTVAL (operands[2]) < - 0x8
1044 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1045 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1046 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1048 HOST_WIDE_INT val = INTVAL (operands[2]);
1052 operands[2] = GEN_INT (0x7);
1053 operands[3] = GEN_INT (val - 0x7);
1057 operands[2] = GEN_INT (- 0x8);
1058 operands[3] = GEN_INT (val + 0x8);
1062 (define_insn "addsi3_internal_2"
1063 [(set (match_operand:DI 0 "register_operand" "=d,d")
1064 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
1065 (match_operand:SI 2 "arith_operand" "d,Q"))))]
1066 "TARGET_64BIT && !TARGET_MIPS16"
1070 [(set_attr "type" "arith")
1071 (set_attr "mode" "SI")])
1074 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1075 (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1076 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
1077 "TARGET_MIPS16 && TARGET_64BIT"
1079 if (REGNO (operands[0]) == REGNO (operands[1]))
1080 return "addu\t%0,%2";
1082 return "addu\t%0,%1,%2";
1084 [(set_attr "type" "arith")
1085 (set_attr "mode" "SI")
1086 (set_attr_alternative "length"
1087 [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
1090 (if_then_else (match_operand:VOID 2 "m16_simm4_1")
1096 ;; ....................
1100 ;; ....................
1103 (define_insn "subdf3"
1104 [(set (match_operand:DF 0 "register_operand" "=f")
1105 (minus:DF (match_operand:DF 1 "register_operand" "f")
1106 (match_operand:DF 2 "register_operand" "f")))]
1107 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1109 [(set_attr "type" "fadd")
1110 (set_attr "mode" "DF")])
1112 (define_insn "subsf3"
1113 [(set (match_operand:SF 0 "register_operand" "=f")
1114 (minus:SF (match_operand:SF 1 "register_operand" "f")
1115 (match_operand:SF 2 "register_operand" "f")))]
1118 [(set_attr "type" "fadd")
1119 (set_attr "mode" "SF")])
1121 (define_expand "subsi3"
1122 [(set (match_operand:SI 0 "register_operand")
1123 (minus:SI (match_operand:SI 1 "register_operand")
1124 (match_operand:SI 2 "register_operand")))]
1128 (define_insn "subsi3_internal"
1129 [(set (match_operand:SI 0 "register_operand" "=d")
1130 (minus:SI (match_operand:SI 1 "register_operand" "d")
1131 (match_operand:SI 2 "register_operand" "d")))]
1134 [(set_attr "type" "arith")
1135 (set_attr "mode" "SI")])
1137 (define_insn "subdi3"
1138 [(set (match_operand:DI 0 "register_operand" "=d")
1139 (minus:DI (match_operand:DI 1 "register_operand" "d")
1140 (match_operand:DI 2 "register_operand" "d")))]
1143 [(set_attr "type" "arith")
1144 (set_attr "mode" "DI")])
1146 (define_insn "subsi3_internal_2"
1147 [(set (match_operand:DI 0 "register_operand" "=d")
1149 (minus:SI (match_operand:SI 1 "register_operand" "d")
1150 (match_operand:SI 2 "register_operand" "d"))))]
1153 [(set_attr "type" "arith")
1154 (set_attr "mode" "DI")])
1157 ;; ....................
1161 ;; ....................
1164 (define_expand "muldf3"
1165 [(set (match_operand:DF 0 "register_operand")
1166 (mult:DF (match_operand:DF 1 "register_operand")
1167 (match_operand:DF 2 "register_operand")))]
1168 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1171 (define_insn "muldf3_internal"
1172 [(set (match_operand:DF 0 "register_operand" "=f")
1173 (mult:DF (match_operand:DF 1 "register_operand" "f")
1174 (match_operand:DF 2 "register_operand" "f")))]
1175 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
1177 [(set_attr "type" "fmul")
1178 (set_attr "mode" "DF")])
1180 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
1181 ;; operands may corrupt immediately following multiplies. This is a
1182 ;; simple fix to insert NOPs.
1184 (define_insn "muldf3_r4300"
1185 [(set (match_operand:DF 0 "register_operand" "=f")
1186 (mult:DF (match_operand:DF 1 "register_operand" "f")
1187 (match_operand:DF 2 "register_operand" "f")))]
1188 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
1189 "mul.d\t%0,%1,%2\;nop"
1190 [(set_attr "type" "fmul")
1191 (set_attr "mode" "DF")
1192 (set_attr "length" "8")])
1194 (define_expand "mulsf3"
1195 [(set (match_operand:SF 0 "register_operand")
1196 (mult:SF (match_operand:SF 1 "register_operand")
1197 (match_operand:SF 2 "register_operand")))]
1201 (define_insn "mulsf3_internal"
1202 [(set (match_operand:SF 0 "register_operand" "=f")
1203 (mult:SF (match_operand:SF 1 "register_operand" "f")
1204 (match_operand:SF 2 "register_operand" "f")))]
1205 "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
1207 [(set_attr "type" "fmul")
1208 (set_attr "mode" "SF")])
1210 ;; See muldf3_r4300.
1212 (define_insn "mulsf3_r4300"
1213 [(set (match_operand:SF 0 "register_operand" "=f")
1214 (mult:SF (match_operand:SF 1 "register_operand" "f")
1215 (match_operand:SF 2 "register_operand" "f")))]
1216 "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
1217 "mul.s\t%0,%1,%2\;nop"
1218 [(set_attr "type" "fmul")
1219 (set_attr "mode" "SF")
1220 (set_attr "length" "8")])
1223 ;; The original R4000 has a cpu bug. If a double-word or a variable
1224 ;; shift executes while an integer multiplication is in progress, the
1225 ;; shift may give an incorrect result. Avoid this by keeping the mflo
1226 ;; with the mult on the R4000.
1228 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
1229 ;; (also valid for MIPS R4000MC processors):
1231 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
1232 ;; this errata description.
1233 ;; The following code sequence causes the R4000 to incorrectly
1234 ;; execute the Double Shift Right Arithmetic 32 (dsra32)
1235 ;; instruction. If the dsra32 instruction is executed during an
1236 ;; integer multiply, the dsra32 will only shift by the amount in
1237 ;; specified in the instruction rather than the amount plus 32
1239 ;; instruction 1: mult rs,rt integer multiply
1240 ;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
1241 ;; right arithmetic + 32
1242 ;; Workaround: A dsra32 instruction placed after an integer
1243 ;; multiply should not be one of the 11 instructions after the
1244 ;; multiply instruction."
1248 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
1249 ;; the following description.
1250 ;; All extended shifts (shift by n+32) and variable shifts (32 and
1251 ;; 64-bit versions) may produce incorrect results under the
1252 ;; following conditions:
1253 ;; 1) An integer multiply is currently executing
1254 ;; 2) These types of shift instructions are executed immediately
1255 ;; following an integer divide instruction.
1257 ;; 1) Make sure no integer multiply is running wihen these
1258 ;; instruction are executed. If this cannot be predicted at
1259 ;; compile time, then insert a "mfhi" to R0 instruction
1260 ;; immediately after the integer multiply instruction. This
1261 ;; will cause the integer multiply to complete before the shift
1263 ;; 2) Separate integer divide and these two classes of shift
1264 ;; instructions by another instruction or a noop."
1266 ;; These processors have PRId values of 0x00004220 and 0x00004300,
1269 (define_expand "mulsi3"
1270 [(set (match_operand:SI 0 "register_operand")
1271 (mult:SI (match_operand:SI 1 "register_operand")
1272 (match_operand:SI 2 "register_operand")))]
1275 if (GENERATE_MULT3_SI || TARGET_MAD)
1276 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1277 else if (!TARGET_FIX_R4000)
1278 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1280 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1284 (define_insn "mulsi3_mult3"
1285 [(set (match_operand:SI 0 "register_operand" "=d,l")
1286 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1287 (match_operand:SI 2 "register_operand" "d,d")))
1288 (clobber (match_scratch:SI 3 "=h,h"))
1289 (clobber (match_scratch:SI 4 "=l,X"))]
1293 if (which_alternative == 1)
1294 return "mult\t%1,%2";
1303 return "mul\t%0,%1,%2";
1304 return "mult\t%0,%1,%2";
1306 [(set_attr "type" "imul")
1307 (set_attr "mode" "SI")])
1309 ;; If a register gets allocated to LO, and we spill to memory, the reload
1310 ;; will include a move from LO to a GPR. Merge it into the multiplication
1311 ;; if it can set the GPR directly.
1314 ;; Operand 1: GPR (1st multiplication operand)
1315 ;; Operand 2: GPR (2nd multiplication operand)
1317 ;; Operand 4: GPR (destination)
1320 [(set (match_operand:SI 0 "register_operand")
1321 (mult:SI (match_operand:SI 1 "register_operand")
1322 (match_operand:SI 2 "register_operand")))
1323 (clobber (match_operand:SI 3 "register_operand"))
1324 (clobber (scratch:SI))])
1325 (set (match_operand:SI 4 "register_operand")
1326 (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1327 "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
1330 (mult:SI (match_dup 1)
1332 (clobber (match_dup 3))
1333 (clobber (match_dup 0))])])
1335 (define_insn "mulsi3_internal"
1336 [(set (match_operand:SI 0 "register_operand" "=l")
1337 (mult:SI (match_operand:SI 1 "register_operand" "d")
1338 (match_operand:SI 2 "register_operand" "d")))
1339 (clobber (match_scratch:SI 3 "=h"))]
1342 [(set_attr "type" "imul")
1343 (set_attr "mode" "SI")])
1345 (define_insn "mulsi3_r4000"
1346 [(set (match_operand:SI 0 "register_operand" "=d")
1347 (mult:SI (match_operand:SI 1 "register_operand" "d")
1348 (match_operand:SI 2 "register_operand" "d")))
1349 (clobber (match_scratch:SI 3 "=h"))
1350 (clobber (match_scratch:SI 4 "=l"))]
1352 "mult\t%1,%2\;mflo\t%0"
1353 [(set_attr "type" "imul")
1354 (set_attr "mode" "SI")
1355 (set_attr "length" "8")])
1357 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1358 ;; of "mult; mflo". They have the same latency, but the first form gives
1359 ;; us an extra cycle to compute the operands.
1362 ;; Operand 1: GPR (1st multiplication operand)
1363 ;; Operand 2: GPR (2nd multiplication operand)
1365 ;; Operand 4: GPR (destination)
1368 [(set (match_operand:SI 0 "register_operand")
1369 (mult:SI (match_operand:SI 1 "register_operand")
1370 (match_operand:SI 2 "register_operand")))
1371 (clobber (match_operand:SI 3 "register_operand"))])
1372 (set (match_operand:SI 4 "register_operand")
1373 (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1374 "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1379 (plus:SI (mult:SI (match_dup 1)
1383 (plus:SI (mult:SI (match_dup 1)
1386 (clobber (match_dup 3))])])
1388 ;; Multiply-accumulate patterns
1390 ;; For processors that can copy the output to a general register:
1392 ;; The all-d alternative is needed because the combiner will find this
1393 ;; pattern and then register alloc/reload will move registers around to
1394 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1396 ;; The last alternative should be made slightly less desirable, but adding
1397 ;; "?" to the constraint is too strong, and causes values to be loaded into
1398 ;; LO even when that's more costly. For now, using "*d" mostly does the
1400 (define_insn "*mul_acc_si"
1401 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1402 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1403 (match_operand:SI 2 "register_operand" "d,d,d"))
1404 (match_operand:SI 3 "register_operand" "0,l,*d")))
1405 (clobber (match_scratch:SI 4 "=h,h,h"))
1406 (clobber (match_scratch:SI 5 "=X,3,l"))
1407 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1409 || ISA_HAS_MADD_MSUB)
1412 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1413 if (which_alternative == 2)
1415 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1417 return madd[which_alternative];
1419 [(set_attr "type" "imadd,imadd,multi")
1420 (set_attr "mode" "SI")
1421 (set_attr "length" "4,4,8")])
1423 ;; Split the above insn if we failed to get LO allocated.
1425 [(set (match_operand:SI 0 "register_operand")
1426 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1427 (match_operand:SI 2 "register_operand"))
1428 (match_operand:SI 3 "register_operand")))
1429 (clobber (match_scratch:SI 4))
1430 (clobber (match_scratch:SI 5))
1431 (clobber (match_scratch:SI 6))]
1432 "reload_completed && !TARGET_DEBUG_D_MODE
1433 && GP_REG_P (true_regnum (operands[0]))
1434 && GP_REG_P (true_regnum (operands[3]))"
1435 [(parallel [(set (match_dup 6)
1436 (mult:SI (match_dup 1) (match_dup 2)))
1437 (clobber (match_dup 4))
1438 (clobber (match_dup 5))])
1439 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1442 ;; Splitter to copy result of MADD to a general register
1444 [(set (match_operand:SI 0 "register_operand")
1445 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1446 (match_operand:SI 2 "register_operand"))
1447 (match_operand:SI 3 "register_operand")))
1448 (clobber (match_scratch:SI 4))
1449 (clobber (match_scratch:SI 5))
1450 (clobber (match_scratch:SI 6))]
1451 "reload_completed && !TARGET_DEBUG_D_MODE
1452 && GP_REG_P (true_regnum (operands[0]))
1453 && true_regnum (operands[3]) == LO_REGNUM"
1454 [(parallel [(set (match_dup 3)
1455 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1457 (clobber (match_dup 4))
1458 (clobber (match_dup 5))
1459 (clobber (match_dup 6))])
1460 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1463 (define_insn "*macc"
1464 [(set (match_operand:SI 0 "register_operand" "=l,d")
1465 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1466 (match_operand:SI 2 "register_operand" "d,d"))
1467 (match_operand:SI 3 "register_operand" "0,l")))
1468 (clobber (match_scratch:SI 4 "=h,h"))
1469 (clobber (match_scratch:SI 5 "=X,3"))]
1472 if (which_alternative == 1)
1473 return "macc\t%0,%1,%2";
1474 else if (TARGET_MIPS5500)
1475 return "madd\t%1,%2";
1477 /* The VR4130 assumes that there is a two-cycle latency between a macc
1478 that "writes" to $0 and an instruction that reads from it. We avoid
1479 this by assigning to $1 instead. */
1480 return "%[macc\t%@,%1,%2%]";
1482 [(set_attr "type" "imadd")
1483 (set_attr "mode" "SI")])
1485 (define_insn "*msac"
1486 [(set (match_operand:SI 0 "register_operand" "=l,d")
1487 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1488 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1489 (match_operand:SI 3 "register_operand" "d,d"))))
1490 (clobber (match_scratch:SI 4 "=h,h"))
1491 (clobber (match_scratch:SI 5 "=X,1"))]
1494 if (which_alternative == 1)
1495 return "msac\t%0,%2,%3";
1496 else if (TARGET_MIPS5500)
1497 return "msub\t%2,%3";
1499 return "msac\t$0,%2,%3";
1501 [(set_attr "type" "imadd")
1502 (set_attr "mode" "SI")])
1504 ;; An msac-like instruction implemented using negation and a macc.
1505 (define_insn_and_split "*msac_using_macc"
1506 [(set (match_operand:SI 0 "register_operand" "=l,d")
1507 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1508 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1509 (match_operand:SI 3 "register_operand" "d,d"))))
1510 (clobber (match_scratch:SI 4 "=h,h"))
1511 (clobber (match_scratch:SI 5 "=X,1"))
1512 (clobber (match_scratch:SI 6 "=d,d"))]
1513 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1515 "&& reload_completed"
1517 (neg:SI (match_dup 3)))
1520 (plus:SI (mult:SI (match_dup 2)
1523 (clobber (match_dup 4))
1524 (clobber (match_dup 5))])]
1526 [(set_attr "type" "imadd")
1527 (set_attr "length" "8")])
1529 ;; Patterns generated by the define_peephole2 below.
1531 (define_insn "*macc2"
1532 [(set (match_operand:SI 0 "register_operand" "=l")
1533 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1534 (match_operand:SI 2 "register_operand" "d"))
1536 (set (match_operand:SI 3 "register_operand" "=d")
1537 (plus:SI (mult:SI (match_dup 1)
1540 (clobber (match_scratch:SI 4 "=h"))]
1541 "ISA_HAS_MACC && reload_completed"
1543 [(set_attr "type" "imadd")
1544 (set_attr "mode" "SI")])
1546 (define_insn "*msac2"
1547 [(set (match_operand:SI 0 "register_operand" "=l")
1548 (minus:SI (match_dup 0)
1549 (mult:SI (match_operand:SI 1 "register_operand" "d")
1550 (match_operand:SI 2 "register_operand" "d"))))
1551 (set (match_operand:SI 3 "register_operand" "=d")
1552 (minus:SI (match_dup 0)
1553 (mult:SI (match_dup 1)
1555 (clobber (match_scratch:SI 4 "=h"))]
1556 "ISA_HAS_MSAC && reload_completed"
1558 [(set_attr "type" "imadd")
1559 (set_attr "mode" "SI")])
1561 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1565 ;; Operand 1: macc/msac
1567 ;; Operand 3: GPR (destination)
1570 [(set (match_operand:SI 0 "register_operand")
1571 (match_operand:SI 1 "macc_msac_operand"))
1572 (clobber (match_operand:SI 2 "register_operand"))
1573 (clobber (scratch:SI))])
1574 (set (match_operand:SI 3 "register_operand")
1575 (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1577 [(parallel [(set (match_dup 0)
1581 (clobber (match_dup 2))])]
1584 ;; When we have a three-address multiplication instruction, it should
1585 ;; be faster to do a separate multiply and add, rather than moving
1586 ;; something into LO in order to use a macc instruction.
1588 ;; This peephole needs a scratch register to cater for the case when one
1589 ;; of the multiplication operands is the same as the destination.
1591 ;; Operand 0: GPR (scratch)
1593 ;; Operand 2: GPR (addend)
1594 ;; Operand 3: GPR (destination)
1595 ;; Operand 4: macc/msac
1597 ;; Operand 6: new multiplication
1598 ;; Operand 7: new addition/subtraction
1600 [(match_scratch:SI 0 "d")
1601 (set (match_operand:SI 1 "register_operand")
1602 (match_operand:SI 2 "register_operand"))
1605 [(set (match_operand:SI 3 "register_operand")
1606 (match_operand:SI 4 "macc_msac_operand"))
1607 (clobber (match_operand:SI 5 "register_operand"))
1608 (clobber (match_dup 1))])]
1610 && true_regnum (operands[1]) == LO_REGNUM
1611 && peep2_reg_dead_p (2, operands[1])
1612 && GP_REG_P (true_regnum (operands[3]))"
1613 [(parallel [(set (match_dup 0)
1615 (clobber (match_dup 5))
1616 (clobber (match_dup 1))])
1620 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1621 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1622 operands[2], operands[0]);
1625 ;; Same as above, except LO is the initial target of the macc.
1627 ;; Operand 0: GPR (scratch)
1629 ;; Operand 2: GPR (addend)
1630 ;; Operand 3: macc/msac
1632 ;; Operand 5: GPR (destination)
1633 ;; Operand 6: new multiplication
1634 ;; Operand 7: new addition/subtraction
1636 [(match_scratch:SI 0 "d")
1637 (set (match_operand:SI 1 "register_operand")
1638 (match_operand:SI 2 "register_operand"))
1642 (match_operand:SI 3 "macc_msac_operand"))
1643 (clobber (match_operand:SI 4 "register_operand"))
1644 (clobber (scratch:SI))])
1646 (set (match_operand:SI 5 "register_operand")
1647 (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1648 "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1649 [(parallel [(set (match_dup 0)
1651 (clobber (match_dup 4))
1652 (clobber (match_dup 1))])
1656 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1657 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1658 operands[2], operands[0]);
1661 (define_insn "*mul_sub_si"
1662 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1663 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1664 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1665 (match_operand:SI 3 "register_operand" "d,d,d"))))
1666 (clobber (match_scratch:SI 4 "=h,h,h"))
1667 (clobber (match_scratch:SI 5 "=X,1,l"))
1668 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1674 [(set_attr "type" "imadd,multi,multi")
1675 (set_attr "mode" "SI")
1676 (set_attr "length" "4,8,8")])
1678 ;; Split the above insn if we failed to get LO allocated.
1680 [(set (match_operand:SI 0 "register_operand")
1681 (minus:SI (match_operand:SI 1 "register_operand")
1682 (mult:SI (match_operand:SI 2 "register_operand")
1683 (match_operand:SI 3 "register_operand"))))
1684 (clobber (match_scratch:SI 4))
1685 (clobber (match_scratch:SI 5))
1686 (clobber (match_scratch:SI 6))]
1687 "reload_completed && !TARGET_DEBUG_D_MODE
1688 && GP_REG_P (true_regnum (operands[0]))
1689 && GP_REG_P (true_regnum (operands[1]))"
1690 [(parallel [(set (match_dup 6)
1691 (mult:SI (match_dup 2) (match_dup 3)))
1692 (clobber (match_dup 4))
1693 (clobber (match_dup 5))])
1694 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1697 ;; Splitter to copy result of MSUB to a general register
1699 [(set (match_operand:SI 0 "register_operand")
1700 (minus:SI (match_operand:SI 1 "register_operand")
1701 (mult:SI (match_operand:SI 2 "register_operand")
1702 (match_operand:SI 3 "register_operand"))))
1703 (clobber (match_scratch:SI 4))
1704 (clobber (match_scratch:SI 5))
1705 (clobber (match_scratch:SI 6))]
1706 "reload_completed && !TARGET_DEBUG_D_MODE
1707 && GP_REG_P (true_regnum (operands[0]))
1708 && true_regnum (operands[1]) == LO_REGNUM"
1709 [(parallel [(set (match_dup 1)
1710 (minus:SI (match_dup 1)
1711 (mult:SI (match_dup 2) (match_dup 3))))
1712 (clobber (match_dup 4))
1713 (clobber (match_dup 5))
1714 (clobber (match_dup 6))])
1715 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1718 (define_insn "*muls"
1719 [(set (match_operand:SI 0 "register_operand" "=l,d")
1720 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1721 (match_operand:SI 2 "register_operand" "d,d"))))
1722 (clobber (match_scratch:SI 3 "=h,h"))
1723 (clobber (match_scratch:SI 4 "=X,l"))]
1728 [(set_attr "type" "imul")
1729 (set_attr "mode" "SI")])
1731 (define_expand "muldi3"
1732 [(set (match_operand:DI 0 "register_operand")
1733 (mult:DI (match_operand:DI 1 "register_operand")
1734 (match_operand:DI 2 "register_operand")))]
1737 if (GENERATE_MULT3_DI)
1738 emit_insn (gen_muldi3_mult3 (operands[0], operands[1], operands[2]));
1739 else if (!TARGET_FIX_R4000)
1740 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1742 emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
1746 (define_insn "muldi3_mult3"
1747 [(set (match_operand:DI 0 "register_operand" "=d")
1748 (mult:DI (match_operand:DI 1 "register_operand" "d")
1749 (match_operand:DI 2 "register_operand" "d")))
1750 (clobber (match_scratch:DI 3 "=h"))
1751 (clobber (match_scratch:DI 4 "=l"))]
1752 "TARGET_64BIT && GENERATE_MULT3_DI"
1754 [(set_attr "type" "imul")
1755 (set_attr "mode" "DI")])
1757 (define_insn "muldi3_internal"
1758 [(set (match_operand:DI 0 "register_operand" "=l")
1759 (mult:DI (match_operand:DI 1 "register_operand" "d")
1760 (match_operand:DI 2 "register_operand" "d")))
1761 (clobber (match_scratch:DI 3 "=h"))]
1762 "TARGET_64BIT && !TARGET_FIX_R4000"
1764 [(set_attr "type" "imul")
1765 (set_attr "mode" "DI")])
1767 (define_insn "muldi3_r4000"
1768 [(set (match_operand:DI 0 "register_operand" "=d")
1769 (mult:DI (match_operand:DI 1 "register_operand" "d")
1770 (match_operand:DI 2 "register_operand" "d")))
1771 (clobber (match_scratch:DI 3 "=h"))
1772 (clobber (match_scratch:DI 4 "=l"))]
1773 "TARGET_64BIT && TARGET_FIX_R4000"
1774 "dmult\t%1,%2\;mflo\t%0"
1775 [(set_attr "type" "imul")
1776 (set_attr "mode" "DI")
1777 (set_attr "length" "8")])
1779 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1781 (define_expand "mulsidi3"
1783 [(set (match_operand:DI 0 "register_operand")
1785 (sign_extend:DI (match_operand:SI 1 "register_operand"))
1786 (sign_extend:DI (match_operand:SI 2 "register_operand"))))
1787 (clobber (scratch:DI))
1788 (clobber (scratch:DI))
1789 (clobber (scratch:DI))])]
1790 "!TARGET_64BIT || !TARGET_FIX_R4000"
1794 if (!TARGET_FIX_R4000)
1795 emit_insn (gen_mulsidi3_32bit_internal (operands[0], operands[1],
1798 emit_insn (gen_mulsidi3_32bit_r4000 (operands[0], operands[1],
1804 (define_insn "mulsidi3_32bit_internal"
1805 [(set (match_operand:DI 0 "register_operand" "=x")
1807 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1808 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1809 "!TARGET_64BIT && !TARGET_FIX_R4000"
1811 [(set_attr "type" "imul")
1812 (set_attr "mode" "SI")])
1814 (define_insn "mulsidi3_32bit_r4000"
1815 [(set (match_operand:DI 0 "register_operand" "=d")
1817 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1818 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1819 (clobber (match_scratch:DI 3 "=l"))
1820 (clobber (match_scratch:DI 4 "=h"))]
1821 "!TARGET_64BIT && TARGET_FIX_R4000"
1822 "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1823 [(set_attr "type" "imul")
1824 (set_attr "mode" "SI")
1825 (set_attr "length" "12")])
1827 (define_insn_and_split "*mulsidi3_64bit"
1828 [(set (match_operand:DI 0 "register_operand" "=d")
1829 (mult:DI (match_operator:DI 1 "extend_operator"
1830 [(match_operand:SI 3 "register_operand" "d")])
1831 (match_operator:DI 2 "extend_operator"
1832 [(match_operand:SI 4 "register_operand" "d")])))
1833 (clobber (match_scratch:DI 5 "=l"))
1834 (clobber (match_scratch:DI 6 "=h"))
1835 (clobber (match_scratch:DI 7 "=d"))]
1836 "TARGET_64BIT && !TARGET_FIX_R4000
1837 && GET_CODE (operands[1]) == GET_CODE (operands[2])"
1839 "&& reload_completed"
1843 (mult:SI (match_dup 3)
1847 (mult:DI (match_dup 1)
1851 ;; OP7 <- LO, OP0 <- HI
1852 (set (match_dup 7) (unspec:DI [(match_dup 5) (match_dup 6)] UNSPEC_MFHILO))
1853 (set (match_dup 0) (unspec:DI [(match_dup 6) (match_dup 5)] UNSPEC_MFHILO))
1857 (ashift:DI (match_dup 7)
1860 (lshiftrt:DI (match_dup 7)
1863 ;; Shift OP0 into place.
1865 (ashift:DI (match_dup 0)
1868 ;; OR the two halves together
1870 (ior:DI (match_dup 0)
1873 [(set_attr "type" "imul")
1874 (set_attr "mode" "SI")
1875 (set_attr "length" "24")])
1877 (define_insn "*mulsidi3_64bit_parts"
1878 [(set (match_operand:DI 0 "register_operand" "=l")
1880 (mult:SI (match_operand:SI 2 "register_operand" "d")
1881 (match_operand:SI 3 "register_operand" "d"))))
1882 (set (match_operand:DI 1 "register_operand" "=h")
1885 (match_operator:DI 4 "extend_operator" [(match_dup 2)])
1886 (match_operator:DI 5 "extend_operator" [(match_dup 3)]))
1888 "TARGET_64BIT && !TARGET_FIX_R4000
1889 && GET_CODE (operands[4]) == GET_CODE (operands[5])"
1891 if (GET_CODE (operands[4]) == SIGN_EXTEND)
1892 return "mult\t%2,%3";
1894 return "multu\t%2,%3";
1896 [(set_attr "type" "imul")
1897 (set_attr "mode" "SI")])
1899 (define_expand "umulsidi3"
1901 [(set (match_operand:DI 0 "register_operand")
1903 (zero_extend:DI (match_operand:SI 1 "register_operand"))
1904 (zero_extend:DI (match_operand:SI 2 "register_operand"))))
1905 (clobber (scratch:DI))
1906 (clobber (scratch:DI))
1907 (clobber (scratch:DI))])]
1908 "!TARGET_64BIT || !TARGET_FIX_R4000"
1912 if (!TARGET_FIX_R4000)
1913 emit_insn (gen_umulsidi3_32bit_internal (operands[0], operands[1],
1916 emit_insn (gen_umulsidi3_32bit_r4000 (operands[0], operands[1],
1922 (define_insn "umulsidi3_32bit_internal"
1923 [(set (match_operand:DI 0 "register_operand" "=x")
1925 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1926 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1927 "!TARGET_64BIT && !TARGET_FIX_R4000"
1929 [(set_attr "type" "imul")
1930 (set_attr "mode" "SI")])
1932 (define_insn "umulsidi3_32bit_r4000"
1933 [(set (match_operand:DI 0 "register_operand" "=d")
1935 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1936 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1937 (clobber (match_scratch:DI 3 "=l"))
1938 (clobber (match_scratch:DI 4 "=h"))]
1939 "!TARGET_64BIT && TARGET_FIX_R4000"
1940 "multu\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1941 [(set_attr "type" "imul")
1942 (set_attr "mode" "SI")
1943 (set_attr "length" "12")])
1945 ;; Widening multiply with negation.
1946 (define_insn "*muls_di"
1947 [(set (match_operand:DI 0 "register_operand" "=x")
1950 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1951 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1952 "!TARGET_64BIT && ISA_HAS_MULS"
1954 [(set_attr "type" "imul")
1955 (set_attr "length" "4")
1956 (set_attr "mode" "SI")])
1958 (define_insn "*umuls_di"
1959 [(set (match_operand:DI 0 "register_operand" "=x")
1962 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1963 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1964 "!TARGET_64BIT && ISA_HAS_MULS"
1966 [(set_attr "type" "imul")
1967 (set_attr "length" "4")
1968 (set_attr "mode" "SI")])
1970 (define_insn "*smsac_di"
1971 [(set (match_operand:DI 0 "register_operand" "=x")
1973 (match_operand:DI 3 "register_operand" "0")
1975 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1976 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1977 "!TARGET_64BIT && ISA_HAS_MSAC"
1979 if (TARGET_MIPS5500)
1980 return "msub\t%1,%2";
1982 return "msac\t$0,%1,%2";
1984 [(set_attr "type" "imadd")
1985 (set_attr "length" "4")
1986 (set_attr "mode" "SI")])
1988 (define_insn "*umsac_di"
1989 [(set (match_operand:DI 0 "register_operand" "=x")
1991 (match_operand:DI 3 "register_operand" "0")
1993 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1994 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1995 "!TARGET_64BIT && ISA_HAS_MSAC"
1997 if (TARGET_MIPS5500)
1998 return "msubu\t%1,%2";
2000 return "msacu\t$0,%1,%2";
2002 [(set_attr "type" "imadd")
2003 (set_attr "length" "4")
2004 (set_attr "mode" "SI")])
2006 ;; _highpart patterns
2007 (define_expand "umulsi3_highpart"
2008 [(set (match_operand:SI 0 "register_operand")
2011 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"))
2012 (zero_extend:DI (match_operand:SI 2 "register_operand")))
2014 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
2017 emit_insn (gen_umulsi3_highpart_mulhi_internal (operands[0], operands[1],
2020 emit_insn (gen_umulsi3_highpart_internal (operands[0], operands[1],
2025 (define_insn "umulsi3_highpart_internal"
2026 [(set (match_operand:SI 0 "register_operand" "=h")
2029 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2030 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2032 (clobber (match_scratch:SI 3 "=l"))]
2033 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
2035 [(set_attr "type" "imul")
2036 (set_attr "mode" "SI")
2037 (set_attr "length" "4")])
2039 (define_insn "umulsi3_highpart_mulhi_internal"
2040 [(set (match_operand:SI 0 "register_operand" "=h,d")
2043 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2044 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
2046 (clobber (match_scratch:SI 3 "=l,l"))
2047 (clobber (match_scratch:SI 4 "=X,h"))]
2052 [(set_attr "type" "imul")
2053 (set_attr "mode" "SI")
2054 (set_attr "length" "4")])
2056 (define_insn "umulsi3_highpart_neg_mulhi_internal"
2057 [(set (match_operand:SI 0 "register_operand" "=h,d")
2061 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2062 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
2064 (clobber (match_scratch:SI 3 "=l,l"))
2065 (clobber (match_scratch:SI 4 "=X,h"))]
2070 [(set_attr "type" "imul")
2071 (set_attr "mode" "SI")
2072 (set_attr "length" "4")])
2074 (define_expand "smulsi3_highpart"
2075 [(set (match_operand:SI 0 "register_operand")
2078 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"))
2079 (sign_extend:DI (match_operand:SI 2 "register_operand")))
2081 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
2084 emit_insn (gen_smulsi3_highpart_mulhi_internal (operands[0], operands[1],
2087 emit_insn (gen_smulsi3_highpart_internal (operands[0], operands[1],
2092 (define_insn "smulsi3_highpart_internal"
2093 [(set (match_operand:SI 0 "register_operand" "=h")
2096 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2097 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2099 (clobber (match_scratch:SI 3 "=l"))]
2100 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
2102 [(set_attr "type" "imul")
2103 (set_attr "mode" "SI")
2104 (set_attr "length" "4")])
2106 (define_insn "smulsi3_highpart_mulhi_internal"
2107 [(set (match_operand:SI 0 "register_operand" "=h,d")
2110 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2111 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
2113 (clobber (match_scratch:SI 3 "=l,l"))
2114 (clobber (match_scratch:SI 4 "=X,h"))]
2119 [(set_attr "type" "imul")
2120 (set_attr "mode" "SI")
2121 (set_attr "length" "4")])
2123 (define_insn "smulsi3_highpart_neg_mulhi_internal"
2124 [(set (match_operand:SI 0 "register_operand" "=h,d")
2128 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2129 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
2131 (clobber (match_scratch:SI 3 "=l,l"))
2132 (clobber (match_scratch:SI 4 "=X,h"))]
2137 [(set_attr "type" "imul")
2138 (set_attr "mode" "SI")])
2140 (define_insn "smuldi3_highpart"
2141 [(set (match_operand:DI 0 "register_operand" "=h")
2145 (sign_extend:TI (match_operand:DI 1 "register_operand" "d"))
2146 (sign_extend:TI (match_operand:DI 2 "register_operand" "d")))
2148 (clobber (match_scratch:DI 3 "=l"))]
2149 "TARGET_64BIT && !TARGET_FIX_R4000"
2151 [(set_attr "type" "imul")
2152 (set_attr "mode" "DI")])
2154 ;; Disable this pattern for -mfix-vr4120. This is for VR4120 errata MD(0),
2155 ;; which says that dmultu does not always produce the correct result.
2156 (define_insn "umuldi3_highpart"
2157 [(set (match_operand:DI 0 "register_operand" "=h")
2161 (zero_extend:TI (match_operand:DI 1 "register_operand" "d"))
2162 (zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
2164 (clobber (match_scratch:DI 3 "=l"))]
2165 "TARGET_64BIT && !TARGET_FIX_R4000 && !TARGET_FIX_VR4120"
2167 [(set_attr "type" "imul")
2168 (set_attr "mode" "DI")])
2171 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2172 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
2174 (define_insn "madsi"
2175 [(set (match_operand:SI 0 "register_operand" "+l")
2176 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2177 (match_operand:SI 2 "register_operand" "d"))
2179 (clobber (match_scratch:SI 3 "=h"))]
2182 [(set_attr "type" "imadd")
2183 (set_attr "mode" "SI")])
2185 (define_insn "*umul_acc_di"
2186 [(set (match_operand:DI 0 "register_operand" "=x")
2188 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2189 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2190 (match_operand:DI 3 "register_operand" "0")))]
2191 "(TARGET_MAD || ISA_HAS_MACC)
2195 return "madu\t%1,%2";
2196 else if (TARGET_MIPS5500)
2197 return "maddu\t%1,%2";
2199 /* See comment in *macc. */
2200 return "%[maccu\t%@,%1,%2%]";
2202 [(set_attr "type" "imadd")
2203 (set_attr "mode" "SI")])
2206 (define_insn "*smul_acc_di"
2207 [(set (match_operand:DI 0 "register_operand" "=x")
2209 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2210 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2211 (match_operand:DI 3 "register_operand" "0")))]
2212 "(TARGET_MAD || ISA_HAS_MACC)
2216 return "mad\t%1,%2";
2217 else if (TARGET_MIPS5500)
2218 return "madd\t%1,%2";
2220 /* See comment in *macc. */
2221 return "%[macc\t%@,%1,%2%]";
2223 [(set_attr "type" "imadd")
2224 (set_attr "mode" "SI")])
2226 ;; Floating point multiply accumulate instructions.
2229 [(set (match_operand:DF 0 "register_operand" "=f")
2230 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2231 (match_operand:DF 2 "register_operand" "f"))
2232 (match_operand:DF 3 "register_operand" "f")))]
2233 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2234 "madd.d\t%0,%3,%1,%2"
2235 [(set_attr "type" "fmadd")
2236 (set_attr "mode" "DF")])
2239 [(set (match_operand:SF 0 "register_operand" "=f")
2240 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2241 (match_operand:SF 2 "register_operand" "f"))
2242 (match_operand:SF 3 "register_operand" "f")))]
2243 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2244 "madd.s\t%0,%3,%1,%2"
2245 [(set_attr "type" "fmadd")
2246 (set_attr "mode" "SF")])
2249 [(set (match_operand:DF 0 "register_operand" "=f")
2250 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2251 (match_operand:DF 2 "register_operand" "f"))
2252 (match_operand:DF 3 "register_operand" "f")))]
2253 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2254 "msub.d\t%0,%3,%1,%2"
2255 [(set_attr "type" "fmadd")
2256 (set_attr "mode" "DF")])
2259 [(set (match_operand:SF 0 "register_operand" "=f")
2260 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2261 (match_operand:SF 2 "register_operand" "f"))
2262 (match_operand:SF 3 "register_operand" "f")))]
2264 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2265 "msub.s\t%0,%3,%1,%2"
2266 [(set_attr "type" "fmadd")
2267 (set_attr "mode" "SF")])
2270 [(set (match_operand:DF 0 "register_operand" "=f")
2271 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2272 (match_operand:DF 2 "register_operand" "f"))
2273 (match_operand:DF 3 "register_operand" "f"))))]
2274 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2275 "nmadd.d\t%0,%3,%1,%2"
2276 [(set_attr "type" "fmadd")
2277 (set_attr "mode" "DF")])
2280 [(set (match_operand:SF 0 "register_operand" "=f")
2281 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2282 (match_operand:SF 2 "register_operand" "f"))
2283 (match_operand:SF 3 "register_operand" "f"))))]
2284 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2285 "nmadd.s\t%0,%3,%1,%2"
2286 [(set_attr "type" "fmadd")
2287 (set_attr "mode" "SF")])
2290 [(set (match_operand:DF 0 "register_operand" "=f")
2291 (minus:DF (match_operand:DF 1 "register_operand" "f")
2292 (mult:DF (match_operand:DF 2 "register_operand" "f")
2293 (match_operand:DF 3 "register_operand" "f"))))]
2294 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2295 "nmsub.d\t%0,%1,%2,%3"
2296 [(set_attr "type" "fmadd")
2297 (set_attr "mode" "DF")])
2300 [(set (match_operand:SF 0 "register_operand" "=f")
2301 (minus:SF (match_operand:SF 1 "register_operand" "f")
2302 (mult:SF (match_operand:SF 2 "register_operand" "f")
2303 (match_operand:SF 3 "register_operand" "f"))))]
2304 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2305 "nmsub.s\t%0,%1,%2,%3"
2306 [(set_attr "type" "fmadd")
2307 (set_attr "mode" "SF")])
2310 ;; ....................
2312 ;; DIVISION and REMAINDER
2314 ;; ....................
2317 (define_expand "divdf3"
2318 [(set (match_operand:DF 0 "register_operand")
2319 (div:DF (match_operand:DF 1 "reg_or_const_float_1_operand")
2320 (match_operand:DF 2 "register_operand")))]
2321 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2323 if (const_float_1_operand (operands[1], DFmode))
2324 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2328 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
2330 ;; If an mfc1 or dmfc1 happens to access the floating point register
2331 ;; file at the same time a long latency operation (div, sqrt, recip,
2332 ;; sqrt) iterates an intermediate result back through the floating
2333 ;; point register file bypass, then instead returning the correct
2334 ;; register value the mfc1 or dmfc1 operation returns the intermediate
2335 ;; result of the long latency operation.
2337 ;; The workaround is to insert an unconditional 'mov' from/to the
2338 ;; long latency op destination register.
2340 (define_insn "*divdf3"
2341 [(set (match_operand:DF 0 "register_operand" "=f")
2342 (div:DF (match_operand:DF 1 "register_operand" "f")
2343 (match_operand:DF 2 "register_operand" "f")))]
2344 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2347 return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
2349 return "div.d\t%0,%1,%2";
2351 [(set_attr "type" "fdiv")
2352 (set_attr "mode" "DF")
2353 (set (attr "length")
2354 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2359 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
2361 ;; In certain cases, div.s and div.ps may have a rounding error
2362 ;; and/or wrong inexact flag.
2364 ;; Therefore, we only allow div.s if not working around SB-1 rev2
2365 ;; errata, or if working around those errata and a slight loss of
2366 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
2367 (define_expand "divsf3"
2368 [(set (match_operand:SF 0 "register_operand")
2369 (div:SF (match_operand:SF 1 "reg_or_const_float_1_operand")
2370 (match_operand:SF 2 "register_operand")))]
2371 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2373 if (const_float_1_operand (operands[1], SFmode))
2374 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2378 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2379 ;; "divdf3" comment for details).
2381 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
2382 ;; "divsf3" comment for details).
2383 (define_insn "*divsf3"
2384 [(set (match_operand:SF 0 "register_operand" "=f")
2385 (div:SF (match_operand:SF 1 "register_operand" "f")
2386 (match_operand:SF 2 "register_operand" "f")))]
2387 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2390 return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
2392 return "div.s\t%0,%1,%2";
2394 [(set_attr "type" "fdiv")
2395 (set_attr "mode" "SF")
2396 (set (attr "length")
2397 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2401 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2402 ;; "divdf3" comment for details).
2404 [(set (match_operand:DF 0 "register_operand" "=f")
2405 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2406 (match_operand:DF 2 "register_operand" "f")))]
2407 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2410 return "recip.d\t%0,%2\;mov.d\t%0,%0";
2412 return "recip.d\t%0,%2";
2414 [(set_attr "type" "fdiv")
2415 (set_attr "mode" "DF")
2416 (set (attr "length")
2417 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2421 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2422 ;; "divdf3" comment for details).
2424 [(set (match_operand:SF 0 "register_operand" "=f")
2425 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2426 (match_operand:SF 2 "register_operand" "f")))]
2427 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2430 return "recip.s\t%0,%2\;mov.s\t%0,%0";
2432 return "recip.s\t%0,%2";
2434 [(set_attr "type" "fdiv")
2435 (set_attr "mode" "SF")
2436 (set (attr "length")
2437 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2441 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2442 ;; with negative operands. We use special libgcc functions instead.
2443 (define_insn "divmodsi4"
2444 [(set (match_operand:SI 0 "register_operand" "=l")
2445 (div:SI (match_operand:SI 1 "register_operand" "d")
2446 (match_operand:SI 2 "register_operand" "d")))
2447 (set (match_operand:SI 3 "register_operand" "=h")
2448 (mod:SI (match_dup 1)
2450 "!TARGET_FIX_VR4120"
2451 { return mips_output_division ("div\t$0,%1,%2", operands); }
2452 [(set_attr "type" "idiv")
2453 (set_attr "mode" "SI")])
2455 (define_insn "divmoddi4"
2456 [(set (match_operand:DI 0 "register_operand" "=l")
2457 (div:DI (match_operand:DI 1 "register_operand" "d")
2458 (match_operand:DI 2 "register_operand" "d")))
2459 (set (match_operand:DI 3 "register_operand" "=h")
2460 (mod:DI (match_dup 1)
2462 "TARGET_64BIT && !TARGET_FIX_VR4120"
2463 { return mips_output_division ("ddiv\t$0,%1,%2", operands); }
2464 [(set_attr "type" "idiv")
2465 (set_attr "mode" "DI")])
2467 (define_insn "udivmodsi4"
2468 [(set (match_operand:SI 0 "register_operand" "=l")
2469 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2470 (match_operand:SI 2 "register_operand" "d")))
2471 (set (match_operand:SI 3 "register_operand" "=h")
2472 (umod:SI (match_dup 1)
2475 { return mips_output_division ("divu\t$0,%1,%2", operands); }
2476 [(set_attr "type" "idiv")
2477 (set_attr "mode" "SI")])
2479 (define_insn "udivmoddi4"
2480 [(set (match_operand:DI 0 "register_operand" "=l")
2481 (udiv:DI (match_operand:DI 1 "register_operand" "d")
2482 (match_operand:DI 2 "register_operand" "d")))
2483 (set (match_operand:DI 3 "register_operand" "=h")
2484 (umod:DI (match_dup 1)
2487 { return mips_output_division ("ddivu\t$0,%1,%2", operands); }
2488 [(set_attr "type" "idiv")
2489 (set_attr "mode" "DI")])
2492 ;; ....................
2496 ;; ....................
2498 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2499 ;; "divdf3" comment for details).
2500 (define_insn "sqrtdf2"
2501 [(set (match_operand:DF 0 "register_operand" "=f")
2502 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2503 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2506 return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
2508 return "sqrt.d\t%0,%1";
2510 [(set_attr "type" "fsqrt")
2511 (set_attr "mode" "DF")
2512 (set (attr "length")
2513 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2517 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2518 ;; "divdf3" comment for details).
2519 (define_insn "sqrtsf2"
2520 [(set (match_operand:SF 0 "register_operand" "=f")
2521 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2522 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2525 return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
2527 return "sqrt.s\t%0,%1";
2529 [(set_attr "type" "fsqrt")
2530 (set_attr "mode" "SF")
2531 (set (attr "length")
2532 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2536 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2537 ;; "divdf3" comment for details).
2539 [(set (match_operand:DF 0 "register_operand" "=f")
2540 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2541 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2542 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2545 return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2547 return "rsqrt.d\t%0,%2";
2549 [(set_attr "type" "frsqrt")
2550 (set_attr "mode" "DF")
2551 (set (attr "length")
2552 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2556 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2557 ;; "divdf3" comment for details).
2559 [(set (match_operand:SF 0 "register_operand" "=f")
2560 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2561 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2562 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2565 return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2567 return "rsqrt.s\t%0,%2";
2569 [(set_attr "type" "frsqrt")
2570 (set_attr "mode" "SF")
2571 (set (attr "length")
2572 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2577 ;; ....................
2581 ;; ....................
2583 ;; Do not use the integer abs macro instruction, since that signals an
2584 ;; exception on -2147483648 (sigh).
2586 (define_insn "abssi2"
2587 [(set (match_operand:SI 0 "register_operand" "=d")
2588 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2591 operands[2] = const0_rtx;
2593 if (REGNO (operands[0]) == REGNO (operands[1]))
2595 if (GENERATE_BRANCHLIKELY)
2596 return "%(bltzl\t%1,1f\;subu\t%0,%z2,%0\n%~1:%)";
2598 return "bgez\t%1,1f%#\;subu\t%0,%z2,%0\n%~1:";
2601 return "%(bgez\t%1,1f\;move\t%0,%1\;subu\t%0,%z2,%0\n%~1:%)";
2603 [(set_attr "type" "multi")
2604 (set_attr "mode" "SI")
2605 (set_attr "length" "12")])
2607 (define_insn "absdi2"
2608 [(set (match_operand:DI 0 "register_operand" "=d")
2609 (abs:DI (match_operand:DI 1 "register_operand" "d")))]
2610 "TARGET_64BIT && !TARGET_MIPS16"
2612 unsigned int regno1;
2613 operands[2] = const0_rtx;
2615 if (GET_CODE (operands[1]) == REG)
2616 regno1 = REGNO (operands[1]);
2618 regno1 = REGNO (XEXP (operands[1], 0));
2620 if (REGNO (operands[0]) == regno1)
2621 return "%(bltzl\t%1,1f\;dsubu\t%0,%z2,%0\n%~1:%)";
2623 return "%(bgez\t%1,1f\;move\t%0,%1\;dsubu\t%0,%z2,%0\n%~1:%)";
2625 [(set_attr "type" "multi")
2626 (set_attr "mode" "DI")
2627 (set_attr "length" "12")])
2629 (define_insn "absdf2"
2630 [(set (match_operand:DF 0 "register_operand" "=f")
2631 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2632 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2634 [(set_attr "type" "fabs")
2635 (set_attr "mode" "DF")])
2637 (define_insn "abssf2"
2638 [(set (match_operand:SF 0 "register_operand" "=f")
2639 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2642 [(set_attr "type" "fabs")
2643 (set_attr "mode" "SF")])
2646 ;; ....................
2648 ;; FIND FIRST BIT INSTRUCTION
2650 ;; ....................
2653 (define_insn "ffssi2"
2654 [(set (match_operand:SI 0 "register_operand" "=&d")
2655 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2656 (clobber (match_scratch:SI 2 "=&d"))
2657 (clobber (match_scratch:SI 3 "=&d"))]
2660 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2664 %~1:\tand\t%2,%1,0x0001\;\
2674 %~1:\tand\t%2,%3,0x0001\;\
2680 [(set_attr "type" "multi")
2681 (set_attr "mode" "SI")
2682 (set_attr "length" "28")])
2684 (define_insn "ffsdi2"
2685 [(set (match_operand:DI 0 "register_operand" "=&d")
2686 (ffs:DI (match_operand:DI 1 "register_operand" "d")))
2687 (clobber (match_scratch:DI 2 "=&d"))
2688 (clobber (match_scratch:DI 3 "=&d"))]
2689 "TARGET_64BIT && !TARGET_MIPS16"
2691 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2695 %~1:\tand\t%2,%1,0x0001\;\
2705 %~1:\tand\t%2,%3,0x0001\;\
2711 [(set_attr "type" "multi")
2712 (set_attr "mode" "DI")
2713 (set_attr "length" "28")])
2716 ;; ...................
2718 ;; Count leading zeroes.
2720 ;; ...................
2723 (define_insn "clzsi2"
2724 [(set (match_operand:SI 0 "register_operand" "=d")
2725 (clz:SI (match_operand:SI 1 "register_operand" "d")))]
2728 [(set_attr "type" "clz")
2729 (set_attr "mode" "SI")])
2731 (define_insn "clzdi2"
2732 [(set (match_operand:DI 0 "register_operand" "=d")
2733 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
2736 [(set_attr "type" "clz")
2737 (set_attr "mode" "DI")])
2740 ;; ....................
2742 ;; NEGATION and ONE'S COMPLEMENT
2744 ;; ....................
2746 (define_insn "negsi2"
2747 [(set (match_operand:SI 0 "register_operand" "=d")
2748 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2752 return "neg\t%0,%1";
2754 return "subu\t%0,%.,%1";
2756 [(set_attr "type" "arith")
2757 (set_attr "mode" "SI")])
2759 (define_insn "negdi2"
2760 [(set (match_operand:DI 0 "register_operand" "=d")
2761 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2762 "TARGET_64BIT && !TARGET_MIPS16"
2764 [(set_attr "type" "arith")
2765 (set_attr "mode" "DI")])
2767 (define_insn "negdf2"
2768 [(set (match_operand:DF 0 "register_operand" "=f")
2769 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2770 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2772 [(set_attr "type" "fneg")
2773 (set_attr "mode" "DF")])
2775 (define_insn "negsf2"
2776 [(set (match_operand:SF 0 "register_operand" "=f")
2777 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2780 [(set_attr "type" "fneg")
2781 (set_attr "mode" "SF")])
2783 (define_insn "one_cmplsi2"
2784 [(set (match_operand:SI 0 "register_operand" "=d")
2785 (not:SI (match_operand:SI 1 "register_operand" "d")))]
2789 return "not\t%0,%1";
2791 return "nor\t%0,%.,%1";
2793 [(set_attr "type" "arith")
2794 (set_attr "mode" "SI")])
2796 (define_insn "one_cmpldi2"
2797 [(set (match_operand:DI 0 "register_operand" "=d")
2798 (not:DI (match_operand:DI 1 "register_operand" "d")))]
2802 return "not\t%0,%1";
2804 return "nor\t%0,%.,%1";
2806 [(set_attr "type" "arith")
2807 (set_attr "mode" "DI")])
2810 ;; ....................
2814 ;; ....................
2817 ;; Many of these instructions use trivial define_expands, because we
2818 ;; want to use a different set of constraints when TARGET_MIPS16.
2820 (define_expand "andsi3"
2821 [(set (match_operand:SI 0 "register_operand")
2822 (and:SI (match_operand:SI 1 "uns_arith_operand")
2823 (match_operand:SI 2 "uns_arith_operand")))]
2828 operands[1] = force_reg (SImode, operands[1]);
2829 operands[2] = force_reg (SImode, operands[2]);
2834 [(set (match_operand:SI 0 "register_operand" "=d,d")
2835 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2836 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2841 [(set_attr "type" "arith")
2842 (set_attr "mode" "SI")])
2845 [(set (match_operand:SI 0 "register_operand" "=d")
2846 (and:SI (match_operand:SI 1 "register_operand" "%0")
2847 (match_operand:SI 2 "register_operand" "d")))]
2850 [(set_attr "type" "arith")
2851 (set_attr "mode" "SI")])
2853 (define_expand "anddi3"
2854 [(set (match_operand:DI 0 "register_operand")
2855 (and:DI (match_operand:DI 1 "register_operand")
2856 (match_operand:DI 2 "uns_arith_operand")))]
2861 operands[1] = force_reg (DImode, operands[1]);
2862 operands[2] = force_reg (DImode, operands[2]);
2867 [(set (match_operand:DI 0 "register_operand" "=d,d")
2868 (and:DI (match_operand:DI 1 "register_operand" "d,d")
2869 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2870 "TARGET_64BIT && !TARGET_MIPS16"
2874 [(set_attr "type" "arith")
2875 (set_attr "mode" "DI")])
2878 [(set (match_operand:DI 0 "register_operand" "=d")
2879 (and:DI (match_operand:DI 1 "register_operand" "0")
2880 (match_operand:DI 2 "register_operand" "d")))]
2881 "TARGET_64BIT && TARGET_MIPS16"
2883 [(set_attr "type" "arith")
2884 (set_attr "mode" "DI")])
2886 (define_expand "iorsi3"
2887 [(set (match_operand:SI 0 "register_operand")
2888 (ior:SI (match_operand:SI 1 "uns_arith_operand")
2889 (match_operand:SI 2 "uns_arith_operand")))]
2894 operands[1] = force_reg (SImode, operands[1]);
2895 operands[2] = force_reg (SImode, operands[2]);
2900 [(set (match_operand:SI 0 "register_operand" "=d,d")
2901 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2902 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2907 [(set_attr "type" "arith")
2908 (set_attr "mode" "SI")])
2911 [(set (match_operand:SI 0 "register_operand" "=d")
2912 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2913 (match_operand:SI 2 "register_operand" "d")))]
2916 [(set_attr "type" "arith")
2917 (set_attr "mode" "SI")])
2919 (define_expand "iordi3"
2920 [(set (match_operand:DI 0 "register_operand")
2921 (ior:DI (match_operand:DI 1 "register_operand")
2922 (match_operand:DI 2 "uns_arith_operand")))]
2927 operands[1] = force_reg (DImode, operands[1]);
2928 operands[2] = force_reg (DImode, operands[2]);
2933 [(set (match_operand:DI 0 "register_operand" "=d,d")
2934 (ior:DI (match_operand:DI 1 "register_operand" "d,d")
2935 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2936 "TARGET_64BIT && !TARGET_MIPS16"
2940 [(set_attr "type" "arith")
2941 (set_attr "mode" "DI")])
2944 [(set (match_operand:DI 0 "register_operand" "=d")
2945 (ior:DI (match_operand:DI 1 "register_operand" "0")
2946 (match_operand:DI 2 "register_operand" "d")))]
2947 "TARGET_64BIT && TARGET_MIPS16"
2949 [(set_attr "type" "arith")
2950 (set_attr "mode" "DI")])
2952 (define_expand "xorsi3"
2953 [(set (match_operand:SI 0 "register_operand")
2954 (xor:SI (match_operand:SI 1 "uns_arith_operand")
2955 (match_operand:SI 2 "uns_arith_operand")))]
2960 [(set (match_operand:SI 0 "register_operand" "=d,d")
2961 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2962 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2967 [(set_attr "type" "arith")
2968 (set_attr "mode" "SI")])
2971 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
2972 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
2973 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
2979 [(set_attr "type" "arith")
2980 (set_attr "mode" "SI")
2981 (set_attr_alternative "length"
2983 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2988 (define_expand "xordi3"
2989 [(set (match_operand:DI 0 "register_operand")
2990 (xor:DI (match_operand:DI 1 "register_operand")
2991 (match_operand:DI 2 "uns_arith_operand")))]
2996 operands[1] = force_reg (DImode, operands[1]);
2997 operands[2] = force_reg (DImode, operands[2]);
3002 [(set (match_operand:DI 0 "register_operand" "=d,d")
3003 (xor:DI (match_operand:DI 1 "register_operand" "d,d")
3004 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
3005 "TARGET_64BIT && !TARGET_MIPS16"
3009 [(set_attr "type" "arith")
3010 (set_attr "mode" "DI")])
3013 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3014 (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
3015 (match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
3016 "TARGET_64BIT && TARGET_MIPS16"
3021 [(set_attr "type" "arith")
3022 (set_attr "mode" "DI")
3023 (set_attr_alternative "length"
3025 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
3030 (define_insn "*norsi3"
3031 [(set (match_operand:SI 0 "register_operand" "=d")
3032 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3033 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3036 [(set_attr "type" "arith")
3037 (set_attr "mode" "SI")])
3039 (define_insn "*nordi3"
3040 [(set (match_operand:DI 0 "register_operand" "=d")
3041 (and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
3042 (not:DI (match_operand:DI 2 "register_operand" "d"))))]
3043 "TARGET_64BIT && !TARGET_MIPS16"
3045 [(set_attr "type" "arith")
3046 (set_attr "mode" "DI")])
3049 ;; ....................
3053 ;; ....................
3057 (define_insn "truncdfsf2"
3058 [(set (match_operand:SF 0 "register_operand" "=f")
3059 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3060 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3062 [(set_attr "type" "fcvt")
3063 (set_attr "mode" "SF")])
3065 ;; Integer truncation patterns. Truncating SImode values to smaller
3066 ;; modes is a no-op, as it is for most other GCC ports. Truncating
3067 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
3068 ;; need to make sure that the lower 32 bits are properly sign-extended
3069 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
3070 ;; smaller than SImode is equivalent to two separate truncations:
3073 ;; DI ---> HI == DI ---> SI ---> HI
3074 ;; DI ---> QI == DI ---> SI ---> QI
3076 ;; Step A needs a real instruction but step B does not.
3078 (define_insn "truncdisi2"
3079 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
3080 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
3085 [(set_attr "type" "shift,store")
3086 (set_attr "mode" "SI")
3087 (set_attr "extended_mips16" "yes,*")])
3089 (define_insn "truncdihi2"
3090 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
3091 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
3096 [(set_attr "type" "shift,store")
3097 (set_attr "mode" "SI")
3098 (set_attr "extended_mips16" "yes,*")])
3100 (define_insn "truncdiqi2"
3101 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
3102 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
3107 [(set_attr "type" "shift,store")
3108 (set_attr "mode" "SI")
3109 (set_attr "extended_mips16" "yes,*")])
3111 ;; Combiner patterns to optimize shift/truncate combinations.
3114 [(set (match_operand:SI 0 "register_operand" "=d")
3115 (truncate:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
3116 (match_operand:DI 2 "small_int" "I"))))]
3117 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
3119 [(set_attr "type" "shift")
3120 (set_attr "mode" "SI")])
3123 [(set (match_operand:SI 0 "register_operand" "=d")
3124 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
3126 "TARGET_64BIT && !TARGET_MIPS16"
3128 [(set_attr "type" "shift")
3129 (set_attr "mode" "SI")])
3132 ;; Combiner patterns for truncate/sign_extend combinations. They use
3133 ;; the shift/truncate patterns above.
3135 (define_insn_and_split ""
3136 [(set (match_operand:SI 0 "register_operand" "=d")
3138 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
3139 "TARGET_64BIT && !TARGET_MIPS16"
3141 "&& reload_completed"
3143 (ashift:DI (match_dup 1)
3146 (truncate:SI (ashiftrt:DI (match_dup 2)
3148 { operands[2] = gen_lowpart (DImode, operands[0]); })
3150 (define_insn_and_split ""
3151 [(set (match_operand:SI 0 "register_operand" "=d")
3153 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3154 "TARGET_64BIT && !TARGET_MIPS16"
3156 "&& reload_completed"
3158 (ashift:DI (match_dup 1)
3161 (truncate:SI (ashiftrt:DI (match_dup 2)
3163 { operands[2] = gen_lowpart (DImode, operands[0]); })
3166 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3169 [(set (match_operand:SI 0 "register_operand" "=d")
3170 (zero_extend:SI (truncate:HI
3171 (match_operand:DI 1 "register_operand" "d"))))]
3172 "TARGET_64BIT && !TARGET_MIPS16"
3173 "andi\t%0,%1,0xffff"
3174 [(set_attr "type" "arith")
3175 (set_attr "mode" "SI")])
3178 [(set (match_operand:SI 0 "register_operand" "=d")
3179 (zero_extend:SI (truncate:QI
3180 (match_operand:DI 1 "register_operand" "d"))))]
3181 "TARGET_64BIT && !TARGET_MIPS16"
3183 [(set_attr "type" "arith")
3184 (set_attr "mode" "SI")])
3187 [(set (match_operand:HI 0 "register_operand" "=d")
3188 (zero_extend:HI (truncate:QI
3189 (match_operand:DI 1 "register_operand" "d"))))]
3190 "TARGET_64BIT && !TARGET_MIPS16"
3192 [(set_attr "type" "arith")
3193 (set_attr "mode" "HI")])
3196 ;; ....................
3200 ;; ....................
3203 ;; Those for integer source operand are ordered widest source type first.
3205 (define_insn_and_split "zero_extendsidi2"
3206 [(set (match_operand:DI 0 "register_operand" "=d")
3207 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
3210 "&& reload_completed"
3212 (ashift:DI (match_dup 1) (const_int 32)))
3214 (lshiftrt:DI (match_dup 0) (const_int 32)))]
3215 "operands[1] = gen_lowpart (DImode, operands[1]);"
3216 [(set_attr "type" "multi")
3217 (set_attr "mode" "DI")
3218 (set_attr "length" "8")])
3220 (define_insn "*zero_extendsidi2_mem"
3221 [(set (match_operand:DI 0 "register_operand" "=d")
3222 (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
3225 [(set_attr "type" "load")
3226 (set_attr "mode" "DI")])
3228 (define_expand "zero_extendhisi2"
3229 [(set (match_operand:SI 0 "register_operand")
3230 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
3233 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3235 rtx op = gen_lowpart (SImode, operands[1]);
3236 rtx temp = force_reg (SImode, GEN_INT (0xffff));
3238 emit_insn (gen_andsi3 (operands[0], op, temp));
3244 [(set (match_operand:SI 0 "register_operand" "=d,d")
3245 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
3250 [(set_attr "type" "arith,load")
3251 (set_attr "mode" "SI")
3252 (set_attr "length" "4,*")])
3255 [(set (match_operand:SI 0 "register_operand" "=d")
3256 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3259 [(set_attr "type" "load")
3260 (set_attr "mode" "SI")])
3262 (define_expand "zero_extendhidi2"
3263 [(set (match_operand:DI 0 "register_operand")
3264 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
3267 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3269 rtx op = gen_lowpart (DImode, operands[1]);
3270 rtx temp = force_reg (DImode, GEN_INT (0xffff));
3272 emit_insn (gen_anddi3 (operands[0], op, temp));
3278 [(set (match_operand:DI 0 "register_operand" "=d,d")
3279 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
3280 "TARGET_64BIT && !TARGET_MIPS16"
3284 [(set_attr "type" "arith,load")
3285 (set_attr "mode" "DI")
3286 (set_attr "length" "4,*")])
3289 [(set (match_operand:DI 0 "register_operand" "=d")
3290 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3291 "TARGET_64BIT && TARGET_MIPS16"
3293 [(set_attr "type" "load")
3294 (set_attr "mode" "DI")])
3296 (define_expand "zero_extendqihi2"
3297 [(set (match_operand:HI 0 "register_operand")
3298 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3301 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3303 rtx op0 = gen_lowpart (SImode, operands[0]);
3304 rtx op1 = gen_lowpart (SImode, operands[1]);
3305 rtx temp = force_reg (SImode, GEN_INT (0xff));
3307 emit_insn (gen_andsi3 (op0, op1, temp));
3313 [(set (match_operand:HI 0 "register_operand" "=d,d")
3314 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3319 [(set_attr "type" "arith,load")
3320 (set_attr "mode" "HI")
3321 (set_attr "length" "4,*")])
3324 [(set (match_operand:HI 0 "register_operand" "=d")
3325 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3328 [(set_attr "type" "load")
3329 (set_attr "mode" "HI")])
3331 (define_expand "zero_extendqisi2"
3332 [(set (match_operand:SI 0 "register_operand")
3333 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3336 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3338 rtx op = gen_lowpart (SImode, operands[1]);
3339 rtx temp = force_reg (SImode, GEN_INT (0xff));
3341 emit_insn (gen_andsi3 (operands[0], op, temp));
3347 [(set (match_operand:SI 0 "register_operand" "=d,d")
3348 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3353 [(set_attr "type" "arith,load")
3354 (set_attr "mode" "SI")
3355 (set_attr "length" "4,*")])
3358 [(set (match_operand:SI 0 "register_operand" "=d")
3359 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3362 [(set_attr "type" "load")
3363 (set_attr "mode" "SI")])
3365 (define_expand "zero_extendqidi2"
3366 [(set (match_operand:DI 0 "register_operand")
3367 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3370 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3372 rtx op = gen_lowpart (DImode, operands[1]);
3373 rtx temp = force_reg (DImode, GEN_INT (0xff));
3375 emit_insn (gen_anddi3 (operands[0], op, temp));
3381 [(set (match_operand:DI 0 "register_operand" "=d,d")
3382 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3383 "TARGET_64BIT && !TARGET_MIPS16"
3387 [(set_attr "type" "arith,load")
3388 (set_attr "mode" "DI")
3389 (set_attr "length" "4,*")])
3392 [(set (match_operand:DI 0 "register_operand" "=d")
3393 (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3394 "TARGET_64BIT && TARGET_MIPS16"
3396 [(set_attr "type" "load")
3397 (set_attr "mode" "DI")])
3400 ;; ....................
3404 ;; ....................
3407 ;; Those for integer source operand are ordered widest source type first.
3409 ;; When TARGET_64BIT, all SImode integer registers should already be in
3410 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
3411 ;; therefore get rid of register->register instructions if we constrain
3412 ;; the source to be in the same register as the destination.
3414 ;; The register alternative has type "arith" so that the pre-reload
3415 ;; scheduler will treat it as a move. This reflects what happens if
3416 ;; the register alternative needs a reload.
3417 (define_insn_and_split "extendsidi2"
3418 [(set (match_operand:DI 0 "register_operand" "=d,d")
3419 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
3424 "&& reload_completed && register_operand (operands[1], VOIDmode)"
3427 emit_note (NOTE_INSN_DELETED);
3430 [(set_attr "type" "arith,load")
3431 (set_attr "mode" "DI")])
3433 ;; These patterns originally accepted general_operands, however, slightly
3434 ;; better code is generated by only accepting register_operands, and then
3435 ;; letting combine generate the lh and lb insns.
3437 ;; These expanders originally put values in registers first. We split
3438 ;; all non-mem patterns after reload.
3440 (define_expand "extendhidi2"
3441 [(set (match_operand:DI 0 "register_operand")
3442 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
3446 (define_insn "*extendhidi2"
3447 [(set (match_operand:DI 0 "register_operand" "=d")
3448 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
3453 [(set (match_operand:DI 0 "register_operand")
3454 (sign_extend:DI (match_operand:HI 1 "register_operand")))]
3455 "TARGET_64BIT && reload_completed"
3457 (ashift:DI (match_dup 1) (const_int 48)))
3459 (ashiftrt:DI (match_dup 0) (const_int 48)))]
3460 "operands[1] = gen_lowpart (DImode, operands[1]);")
3462 (define_insn "*extendhidi2_mem"
3463 [(set (match_operand:DI 0 "register_operand" "=d")
3464 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3467 [(set_attr "type" "load")
3468 (set_attr "mode" "DI")])
3470 (define_expand "extendhisi2"
3471 [(set (match_operand:SI 0 "register_operand")
3472 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
3475 if (ISA_HAS_SEB_SEH)
3477 emit_insn (gen_extendhisi2_hw (operands[0],
3478 force_reg (HImode, operands[1])));
3483 (define_insn "*extendhisi2"
3484 [(set (match_operand:SI 0 "register_operand" "=d")
3485 (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
3490 [(set (match_operand:SI 0 "register_operand")
3491 (sign_extend:SI (match_operand:HI 1 "register_operand")))]
3494 (ashift:SI (match_dup 1) (const_int 16)))
3496 (ashiftrt:SI (match_dup 0) (const_int 16)))]
3497 "operands[1] = gen_lowpart (SImode, operands[1]);")
3499 (define_insn "extendhisi2_mem"
3500 [(set (match_operand:SI 0 "register_operand" "=d")
3501 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3504 [(set_attr "type" "load")
3505 (set_attr "mode" "SI")])
3507 (define_insn "extendhisi2_hw"
3508 [(set (match_operand:SI 0 "register_operand" "=r")
3509 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
3512 [(set_attr "type" "arith")
3513 (set_attr "mode" "SI")])
3515 (define_expand "extendqihi2"
3516 [(set (match_operand:HI 0 "register_operand")
3517 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3521 (define_insn "*extendqihi2"
3522 [(set (match_operand:HI 0 "register_operand" "=d")
3523 (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
3528 [(set (match_operand:HI 0 "register_operand")
3529 (sign_extend:HI (match_operand:QI 1 "register_operand")))]
3532 (ashift:SI (match_dup 1) (const_int 24)))
3534 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3535 "operands[0] = gen_lowpart (SImode, operands[0]);
3536 operands[1] = gen_lowpart (SImode, operands[1]);")
3538 (define_insn "*extendqihi2_internal_mem"
3539 [(set (match_operand:HI 0 "register_operand" "=d")
3540 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3543 [(set_attr "type" "load")
3544 (set_attr "mode" "SI")])
3547 (define_expand "extendqisi2"
3548 [(set (match_operand:SI 0 "register_operand")
3549 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3552 if (ISA_HAS_SEB_SEH)
3554 emit_insn (gen_extendqisi2_hw (operands[0],
3555 force_reg (QImode, operands[1])));
3560 (define_insn "*extendqisi2"
3561 [(set (match_operand:SI 0 "register_operand" "=d")
3562 (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
3567 [(set (match_operand:SI 0 "register_operand")
3568 (sign_extend:SI (match_operand:QI 1 "register_operand")))]
3571 (ashift:SI (match_dup 1) (const_int 24)))
3573 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3574 "operands[1] = gen_lowpart (SImode, operands[1]);")
3576 (define_insn "*extendqisi2_mem"
3577 [(set (match_operand:SI 0 "register_operand" "=d")
3578 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3581 [(set_attr "type" "load")
3582 (set_attr "mode" "SI")])
3584 (define_insn "extendqisi2_hw"
3585 [(set (match_operand:SI 0 "register_operand" "=r")
3586 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
3589 [(set_attr "type" "arith")
3590 (set_attr "mode" "SI")])
3592 (define_expand "extendqidi2"
3593 [(set (match_operand:DI 0 "register_operand")
3594 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3598 (define_insn "*extendqidi2"
3599 [(set (match_operand:DI 0 "register_operand" "=d")
3600 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
3605 [(set (match_operand:DI 0 "register_operand")
3606 (sign_extend:DI (match_operand:QI 1 "register_operand")))]
3607 "TARGET_64BIT && reload_completed"
3609 (ashift:DI (match_dup 1) (const_int 56)))
3611 (ashiftrt:DI (match_dup 0) (const_int 56)))]
3612 "operands[1] = gen_lowpart (DImode, operands[1]);")
3614 (define_insn "*extendqidi2_mem"
3615 [(set (match_operand:DI 0 "register_operand" "=d")
3616 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3619 [(set_attr "type" "load")
3620 (set_attr "mode" "DI")])
3622 (define_insn "extendsfdf2"
3623 [(set (match_operand:DF 0 "register_operand" "=f")
3624 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3625 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3627 [(set_attr "type" "fcvt")
3628 (set_attr "mode" "DF")])
3631 ;; ....................
3635 ;; ....................
3637 (define_expand "fix_truncdfsi2"
3638 [(set (match_operand:SI 0 "register_operand")
3639 (fix:SI (match_operand:DF 1 "register_operand")))]
3640 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3642 if (!ISA_HAS_TRUNC_W)
3644 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3649 (define_insn "fix_truncdfsi2_insn"
3650 [(set (match_operand:SI 0 "register_operand" "=f")
3651 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3652 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3654 [(set_attr "type" "fcvt")
3655 (set_attr "mode" "DF")
3656 (set_attr "length" "4")])
3658 (define_insn "fix_truncdfsi2_macro"
3659 [(set (match_operand:SI 0 "register_operand" "=f")
3660 (fix:SI (match_operand:DF 1 "register_operand" "f")))
3661 (clobber (match_scratch:DF 2 "=d"))]
3662 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3665 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3667 return "trunc.w.d %0,%1,%2";
3669 [(set_attr "type" "fcvt")
3670 (set_attr "mode" "DF")
3671 (set_attr "length" "36")])
3673 (define_expand "fix_truncsfsi2"
3674 [(set (match_operand:SI 0 "register_operand")
3675 (fix:SI (match_operand:SF 1 "register_operand")))]
3678 if (!ISA_HAS_TRUNC_W)
3680 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3685 (define_insn "fix_truncsfsi2_insn"
3686 [(set (match_operand:SI 0 "register_operand" "=f")
3687 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3688 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3690 [(set_attr "type" "fcvt")
3691 (set_attr "mode" "DF")
3692 (set_attr "length" "4")])
3694 (define_insn "fix_truncsfsi2_macro"
3695 [(set (match_operand:SI 0 "register_operand" "=f")
3696 (fix:SI (match_operand:SF 1 "register_operand" "f")))
3697 (clobber (match_scratch:SF 2 "=d"))]
3698 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3701 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3703 return "trunc.w.s %0,%1,%2";
3705 [(set_attr "type" "fcvt")
3706 (set_attr "mode" "DF")
3707 (set_attr "length" "36")])
3710 (define_insn "fix_truncdfdi2"
3711 [(set (match_operand:DI 0 "register_operand" "=f")
3712 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3713 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3715 [(set_attr "type" "fcvt")
3716 (set_attr "mode" "DF")
3717 (set_attr "length" "4")])
3720 (define_insn "fix_truncsfdi2"
3721 [(set (match_operand:DI 0 "register_operand" "=f")
3722 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3723 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3725 [(set_attr "type" "fcvt")
3726 (set_attr "mode" "SF")
3727 (set_attr "length" "4")])
3730 (define_insn "floatsidf2"
3731 [(set (match_operand:DF 0 "register_operand" "=f")
3732 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3733 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3735 [(set_attr "type" "fcvt")
3736 (set_attr "mode" "DF")
3737 (set_attr "length" "4")])
3740 (define_insn "floatdidf2"
3741 [(set (match_operand:DF 0 "register_operand" "=f")
3742 (float:DF (match_operand:DI 1 "register_operand" "f")))]
3743 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3745 [(set_attr "type" "fcvt")
3746 (set_attr "mode" "DF")
3747 (set_attr "length" "4")])
3750 (define_insn "floatsisf2"
3751 [(set (match_operand:SF 0 "register_operand" "=f")
3752 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3755 [(set_attr "type" "fcvt")
3756 (set_attr "mode" "SF")
3757 (set_attr "length" "4")])
3760 (define_insn "floatdisf2"
3761 [(set (match_operand:SF 0 "register_operand" "=f")
3762 (float:SF (match_operand:DI 1 "register_operand" "f")))]
3763 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3765 [(set_attr "type" "fcvt")
3766 (set_attr "mode" "SF")
3767 (set_attr "length" "4")])
3770 (define_expand "fixuns_truncdfsi2"
3771 [(set (match_operand:SI 0 "register_operand")
3772 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
3773 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3775 rtx reg1 = gen_reg_rtx (DFmode);
3776 rtx reg2 = gen_reg_rtx (DFmode);
3777 rtx reg3 = gen_reg_rtx (SImode);
3778 rtx label1 = gen_label_rtx ();
3779 rtx label2 = gen_label_rtx ();
3780 REAL_VALUE_TYPE offset;
3782 real_2expN (&offset, 31);
3784 if (reg1) /* Turn off complaints about unreached code. */
3786 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3787 do_pending_stack_adjust ();
3789 emit_insn (gen_cmpdf (operands[1], reg1));
3790 emit_jump_insn (gen_bge (label1));
3792 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3793 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3794 gen_rtx_LABEL_REF (VOIDmode, label2)));
3797 emit_label (label1);
3798 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3799 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3800 (BITMASK_HIGH, SImode)));
3802 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3803 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3805 emit_label (label2);
3807 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3808 fields, and can't be used for REG_NOTES anyway). */
3809 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3815 (define_expand "fixuns_truncdfdi2"
3816 [(set (match_operand:DI 0 "register_operand")
3817 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3818 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3820 rtx reg1 = gen_reg_rtx (DFmode);
3821 rtx reg2 = gen_reg_rtx (DFmode);
3822 rtx reg3 = gen_reg_rtx (DImode);
3823 rtx label1 = gen_label_rtx ();
3824 rtx label2 = gen_label_rtx ();
3825 REAL_VALUE_TYPE offset;
3827 real_2expN (&offset, 63);
3829 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3830 do_pending_stack_adjust ();
3832 emit_insn (gen_cmpdf (operands[1], reg1));
3833 emit_jump_insn (gen_bge (label1));
3835 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3836 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3837 gen_rtx_LABEL_REF (VOIDmode, label2)));
3840 emit_label (label1);
3841 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3842 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3843 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3845 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3846 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3848 emit_label (label2);
3850 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3851 fields, and can't be used for REG_NOTES anyway). */
3852 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3857 (define_expand "fixuns_truncsfsi2"
3858 [(set (match_operand:SI 0 "register_operand")
3859 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3862 rtx reg1 = gen_reg_rtx (SFmode);
3863 rtx reg2 = gen_reg_rtx (SFmode);
3864 rtx reg3 = gen_reg_rtx (SImode);
3865 rtx label1 = gen_label_rtx ();
3866 rtx label2 = gen_label_rtx ();
3867 REAL_VALUE_TYPE offset;
3869 real_2expN (&offset, 31);
3871 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3872 do_pending_stack_adjust ();
3874 emit_insn (gen_cmpsf (operands[1], reg1));
3875 emit_jump_insn (gen_bge (label1));
3877 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3878 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3879 gen_rtx_LABEL_REF (VOIDmode, label2)));
3882 emit_label (label1);
3883 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3884 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3885 (BITMASK_HIGH, SImode)));
3887 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3888 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3890 emit_label (label2);
3892 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3893 fields, and can't be used for REG_NOTES anyway). */
3894 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3899 (define_expand "fixuns_truncsfdi2"
3900 [(set (match_operand:DI 0 "register_operand")
3901 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3902 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3904 rtx reg1 = gen_reg_rtx (SFmode);
3905 rtx reg2 = gen_reg_rtx (SFmode);
3906 rtx reg3 = gen_reg_rtx (DImode);
3907 rtx label1 = gen_label_rtx ();
3908 rtx label2 = gen_label_rtx ();
3909 REAL_VALUE_TYPE offset;
3911 real_2expN (&offset, 63);
3913 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3914 do_pending_stack_adjust ();
3916 emit_insn (gen_cmpsf (operands[1], reg1));
3917 emit_jump_insn (gen_bge (label1));
3919 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3920 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3921 gen_rtx_LABEL_REF (VOIDmode, label2)));
3924 emit_label (label1);
3925 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3926 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3927 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3929 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3930 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3932 emit_label (label2);
3934 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3935 fields, and can't be used for REG_NOTES anyway). */
3936 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3941 ;; ....................
3945 ;; ....................
3947 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3949 (define_expand "extv"
3950 [(set (match_operand 0 "register_operand")
3951 (sign_extract (match_operand:QI 1 "memory_operand")
3952 (match_operand 2 "immediate_operand")
3953 (match_operand 3 "immediate_operand")))]
3956 if (mips_expand_unaligned_load (operands[0], operands[1],
3957 INTVAL (operands[2]),
3958 INTVAL (operands[3])))
3964 (define_expand "extzv"
3965 [(set (match_operand 0 "register_operand")
3966 (zero_extract (match_operand:QI 1 "memory_operand")
3967 (match_operand 2 "immediate_operand")
3968 (match_operand 3 "immediate_operand")))]
3971 if (mips_expand_unaligned_load (operands[0], operands[1],
3972 INTVAL (operands[2]),
3973 INTVAL (operands[3])))
3979 (define_expand "insv"
3980 [(set (zero_extract (match_operand:QI 0 "memory_operand")
3981 (match_operand 1 "immediate_operand")
3982 (match_operand 2 "immediate_operand"))
3983 (match_operand 3 "reg_or_0_operand"))]
3986 if (mips_expand_unaligned_store (operands[0], operands[3],
3987 INTVAL (operands[1]),
3988 INTVAL (operands[2])))
3994 ;; Unaligned word moves generated by the bit field patterns.
3996 ;; As far as the rtl is concerned, both the left-part and right-part
3997 ;; instructions can access the whole field. However, the real operand
3998 ;; refers to just the first or the last byte (depending on endianness).
3999 ;; We therefore use two memory operands to each instruction, one to
4000 ;; describe the rtl effect and one to use in the assembly output.
4002 ;; Operands 0 and 1 are the rtl-level target and source respectively.
4003 ;; This allows us to use the standard length calculations for the "load"
4004 ;; and "store" type attributes.
4006 (define_insn "mov_lwl"
4007 [(set (match_operand:SI 0 "register_operand" "=d")
4008 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
4009 (match_operand:QI 2 "memory_operand" "m")]
4013 [(set_attr "type" "load")
4014 (set_attr "mode" "SI")
4015 (set_attr "hazard" "none")])
4017 (define_insn "mov_lwr"
4018 [(set (match_operand:SI 0 "register_operand" "=d")
4019 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
4020 (match_operand:QI 2 "memory_operand" "m")
4021 (match_operand:SI 3 "register_operand" "0")]
4025 [(set_attr "type" "load")
4026 (set_attr "mode" "SI")])
4029 (define_insn "mov_swl"
4030 [(set (match_operand:BLK 0 "memory_operand" "=m")
4031 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
4032 (match_operand:QI 2 "memory_operand" "m")]
4036 [(set_attr "type" "store")
4037 (set_attr "mode" "SI")])
4039 (define_insn "mov_swr"
4040 [(set (match_operand:BLK 0 "memory_operand" "+m")
4041 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
4042 (match_operand:QI 2 "memory_operand" "m")
4047 [(set_attr "type" "store")
4048 (set_attr "mode" "SI")])
4051 (define_insn "mov_ldl"
4052 [(set (match_operand:DI 0 "register_operand" "=d")
4053 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
4054 (match_operand:QI 2 "memory_operand" "m")]
4056 "TARGET_64BIT && !TARGET_MIPS16"
4058 [(set_attr "type" "load")
4059 (set_attr "mode" "DI")])
4061 (define_insn "mov_ldr"
4062 [(set (match_operand:DI 0 "register_operand" "=d")
4063 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
4064 (match_operand:QI 2 "memory_operand" "m")
4065 (match_operand:DI 3 "register_operand" "0")]
4067 "TARGET_64BIT && !TARGET_MIPS16"
4069 [(set_attr "type" "load")
4070 (set_attr "mode" "DI")])
4073 (define_insn "mov_sdl"
4074 [(set (match_operand:BLK 0 "memory_operand" "=m")
4075 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
4076 (match_operand:QI 2 "memory_operand" "m")]
4078 "TARGET_64BIT && !TARGET_MIPS16"
4080 [(set_attr "type" "store")
4081 (set_attr "mode" "DI")])
4083 (define_insn "mov_sdr"
4084 [(set (match_operand:BLK 0 "memory_operand" "+m")
4085 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
4086 (match_operand:QI 2 "memory_operand" "m")
4089 "TARGET_64BIT && !TARGET_MIPS16"
4091 [(set_attr "type" "store")
4092 (set_attr "mode" "DI")])
4094 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
4095 ;; The required value is:
4097 ;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
4099 ;; which translates to:
4101 ;; lui op0,%highest(op1)
4102 ;; daddiu op0,op0,%higher(op1)
4104 ;; daddiu op0,op0,%hi(op1)
4106 (define_insn_and_split "*lea_high64"
4107 [(set (match_operand:DI 0 "register_operand" "=d")
4108 (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
4109 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
4111 "&& reload_completed"
4112 [(set (match_dup 0) (high:DI (match_dup 2)))
4113 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
4114 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
4115 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4116 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
4118 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4119 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
4121 [(set_attr "length" "20")])
4123 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
4124 ;; SYMBOL_GENERAL X will take 6 cycles. This next pattern allows combine
4125 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
4126 ;; used once. We can then use the sequence:
4128 ;; lui op0,%highest(op1)
4130 ;; daddiu op0,op0,%higher(op1)
4131 ;; daddiu op2,op2,%lo(op1)
4133 ;; daddu op0,op0,op2
4135 ;; which takes 4 cycles on most superscalar targets.
4136 (define_insn_and_split "*lea64"
4137 [(set (match_operand:DI 0 "register_operand" "=d")
4138 (match_operand:DI 1 "general_symbolic_operand" ""))
4139 (clobber (match_scratch:DI 2 "=&d"))]
4140 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
4142 "&& reload_completed"
4143 [(set (match_dup 0) (high:DI (match_dup 3)))
4144 (set (match_dup 2) (high:DI (match_dup 4)))
4145 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4146 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
4147 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
4148 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
4150 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4151 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
4153 [(set_attr "length" "24")])
4155 ;; Insns to fetch a global symbol from a big GOT.
4157 (define_insn_and_split "*xgot_hisi"
4158 [(set (match_operand:SI 0 "register_operand" "=d")
4159 (high:SI (match_operand:SI 1 "global_got_operand" "")))]
4160 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4162 "&& reload_completed"
4163 [(set (match_dup 0) (high:SI (match_dup 2)))
4164 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
4166 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
4167 operands[3] = pic_offset_table_rtx;
4169 [(set_attr "got" "xgot_high")])
4171 (define_insn_and_split "*xgot_losi"
4172 [(set (match_operand:SI 0 "register_operand" "=d")
4173 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
4174 (match_operand:SI 2 "global_got_operand" "")))]
4175 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4177 "&& reload_completed"
4179 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
4180 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
4181 [(set_attr "got" "load")])
4183 (define_insn_and_split "*xgot_hidi"
4184 [(set (match_operand:DI 0 "register_operand" "=d")
4185 (high:DI (match_operand:DI 1 "global_got_operand" "")))]
4186 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4188 "&& reload_completed"
4189 [(set (match_dup 0) (high:DI (match_dup 2)))
4190 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
4192 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
4193 operands[3] = pic_offset_table_rtx;
4195 [(set_attr "got" "xgot_high")])
4197 (define_insn_and_split "*xgot_lodi"
4198 [(set (match_operand:DI 0 "register_operand" "=d")
4199 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
4200 (match_operand:DI 2 "global_got_operand" "")))]
4201 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4203 "&& reload_completed"
4205 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
4206 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
4207 [(set_attr "got" "load")])
4209 ;; Insns to fetch a global symbol from a normal GOT.
4211 (define_insn_and_split "*got_dispsi"
4212 [(set (match_operand:SI 0 "register_operand" "=d")
4213 (match_operand:SI 1 "global_got_operand" ""))]
4214 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
4216 "&& reload_completed"
4218 (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
4220 operands[2] = pic_offset_table_rtx;
4221 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
4223 [(set_attr "got" "load")])
4225 (define_insn_and_split "*got_dispdi"
4226 [(set (match_operand:DI 0 "register_operand" "=d")
4227 (match_operand:DI 1 "global_got_operand" ""))]
4228 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
4230 "&& reload_completed"
4232 (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
4234 operands[2] = pic_offset_table_rtx;
4235 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
4237 [(set_attr "got" "load")])
4239 ;; Insns for loading the high part of a local symbol.
4241 (define_insn_and_split "*got_pagesi"
4242 [(set (match_operand:SI 0 "register_operand" "=d")
4243 (high:SI (match_operand:SI 1 "local_got_operand" "")))]
4244 "TARGET_EXPLICIT_RELOCS"
4246 "&& reload_completed"
4248 (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
4250 operands[2] = pic_offset_table_rtx;
4251 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
4253 [(set_attr "got" "load")])
4255 (define_insn_and_split "*got_pagedi"
4256 [(set (match_operand:DI 0 "register_operand" "=d")
4257 (high:DI (match_operand:DI 1 "local_got_operand" "")))]
4258 "TARGET_EXPLICIT_RELOCS"
4260 "&& reload_completed"
4262 (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
4264 operands[2] = pic_offset_table_rtx;
4265 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
4267 [(set_attr "got" "load")])
4269 ;; Lower-level instructions for loading an address from the GOT.
4270 ;; We could use MEMs, but an unspec gives more optimization
4273 (define_insn "*load_gotsi"
4274 [(set (match_operand:SI 0 "register_operand" "=d")
4275 (unspec:SI [(match_operand:SI 1 "register_operand" "d")
4276 (match_operand:SI 2 "immediate_operand" "")]
4280 [(set_attr "type" "load")
4281 (set_attr "length" "4")])
4283 (define_insn "*load_gotdi"
4284 [(set (match_operand:DI 0 "register_operand" "=d")
4285 (unspec:DI [(match_operand:DI 1 "register_operand" "d")
4286 (match_operand:DI 2 "immediate_operand" "")]
4290 [(set_attr "type" "load")
4291 (set_attr "length" "4")])
4293 ;; Instructions for adding the low 16 bits of an address to a register.
4294 ;; Operand 2 is the address: print_operand works out which relocation
4295 ;; should be applied.
4297 (define_insn "*lowsi"
4298 [(set (match_operand:SI 0 "register_operand" "=d")
4299 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
4300 (match_operand:SI 2 "immediate_operand" "")))]
4303 [(set_attr "type" "arith")
4304 (set_attr "mode" "SI")])
4306 (define_insn "*lowdi"
4307 [(set (match_operand:DI 0 "register_operand" "=d")
4308 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
4309 (match_operand:DI 2 "immediate_operand" "")))]
4310 "!TARGET_MIPS16 && TARGET_64BIT"
4312 [(set_attr "type" "arith")
4313 (set_attr "mode" "DI")])
4315 (define_insn "*lowsi_mips16"
4316 [(set (match_operand:SI 0 "register_operand" "=d")
4317 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
4318 (match_operand:SI 2 "immediate_operand" "")))]
4321 [(set_attr "type" "arith")
4322 (set_attr "mode" "SI")
4323 (set_attr "length" "8")])
4325 (define_insn "*lowdi_mips16"
4326 [(set (match_operand:DI 0 "register_operand" "=d")
4327 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
4328 (match_operand:DI 2 "immediate_operand" "")))]
4329 "TARGET_MIPS16 && TARGET_64BIT"
4331 [(set_attr "type" "arith")
4332 (set_attr "mode" "DI")
4333 (set_attr "length" "8")])
4335 ;; 64-bit integer moves
4337 ;; Unlike most other insns, the move insns can't be split with
4338 ;; different predicates, because register spilling and other parts of
4339 ;; the compiler, have memoized the insn number already.
4341 (define_expand "movdi"
4342 [(set (match_operand:DI 0 "")
4343 (match_operand:DI 1 ""))]
4346 if (mips_legitimize_move (DImode, operands[0], operands[1]))
4350 ;; For mips16, we need a special case to handle storing $31 into
4351 ;; memory, since we don't have a constraint to match $31. This
4352 ;; instruction can be generated by save_restore_insns.
4355 [(set (match_operand:DI 0 "stack_operand" "=m")
4357 "TARGET_MIPS16 && TARGET_64BIT"
4359 [(set_attr "type" "store")
4360 (set_attr "mode" "DI")])
4362 (define_insn "*movdi_32bit"
4363 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
4364 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
4365 "!TARGET_64BIT && !TARGET_MIPS16
4366 && (register_operand (operands[0], DImode)
4367 || reg_or_0_operand (operands[1], DImode))"
4368 { return mips_output_move (operands[0], operands[1]); }
4369 [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
4370 (set_attr "mode" "DI")
4371 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
4373 (define_insn "*movdi_32bit_mips16"
4374 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4375 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4376 "!TARGET_64BIT && TARGET_MIPS16
4377 && (register_operand (operands[0], DImode)
4378 || register_operand (operands[1], DImode))"
4379 { return mips_output_move (operands[0], operands[1]); }
4380 [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo")
4381 (set_attr "mode" "DI")
4382 (set_attr "length" "8,8,8,8,12,*,*,8")])
4384 (define_insn "*movdi_64bit"
4385 [(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")
4386 (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"))]
4387 "TARGET_64BIT && !TARGET_MIPS16
4388 && (register_operand (operands[0], DImode)
4389 || reg_or_0_operand (operands[1], DImode))"
4390 { return mips_output_move (operands[0], operands[1]); }
4391 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
4392 (set_attr "mode" "DI")
4393 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
4395 (define_insn "*movdi_64bit_mips16"
4396 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4397 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4398 "TARGET_64BIT && TARGET_MIPS16
4399 && (register_operand (operands[0], DImode)
4400 || register_operand (operands[1], DImode))"
4401 { return mips_output_move (operands[0], operands[1]); }
4402 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
4403 (set_attr "mode" "DI")
4404 (set_attr_alternative "length"
4408 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4411 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4416 (const_string "*")])])
4419 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4420 ;; when the original load is a 4 byte instruction but the add and the
4421 ;; load are 2 2 byte instructions.
4424 [(set (match_operand:DI 0 "register_operand")
4425 (mem:DI (plus:DI (match_dup 0)
4426 (match_operand:DI 1 "const_int_operand"))))]
4427 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4428 && !TARGET_DEBUG_D_MODE
4429 && GET_CODE (operands[0]) == REG
4430 && M16_REG_P (REGNO (operands[0]))
4431 && GET_CODE (operands[1]) == CONST_INT
4432 && ((INTVAL (operands[1]) < 0
4433 && INTVAL (operands[1]) >= -0x10)
4434 || (INTVAL (operands[1]) >= 32 * 8
4435 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4436 || (INTVAL (operands[1]) >= 0
4437 && INTVAL (operands[1]) < 32 * 8
4438 && (INTVAL (operands[1]) & 7) != 0))"
4439 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4440 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4442 HOST_WIDE_INT val = INTVAL (operands[1]);
4445 operands[2] = const0_rtx;
4446 else if (val >= 32 * 8)
4450 operands[1] = GEN_INT (0x8 + off);
4451 operands[2] = GEN_INT (val - off - 0x8);
4457 operands[1] = GEN_INT (off);
4458 operands[2] = GEN_INT (val - off);
4462 ;; 32-bit Integer moves
4464 ;; Unlike most other insns, the move insns can't be split with
4465 ;; different predicates, because register spilling and other parts of
4466 ;; the compiler, have memoized the insn number already.
4468 (define_expand "movsi"
4469 [(set (match_operand:SI 0 "")
4470 (match_operand:SI 1 ""))]
4473 if (mips_legitimize_move (SImode, operands[0], operands[1]))
4477 ;; We can only store $ra directly into a small sp offset.
4480 [(set (match_operand:SI 0 "stack_operand" "=m")
4484 [(set_attr "type" "store")
4485 (set_attr "mode" "SI")])
4487 ;; The difference between these two is whether or not ints are allowed
4488 ;; in FP registers (off by default, use -mdebugh to enable).
4490 (define_insn "*movsi_internal"
4491 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*B*C*D,*B*C*D,*d,*m")
4492 (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*d,*m,*B*C*D,*B*C*D"))]
4494 && (register_operand (operands[0], SImode)
4495 || reg_or_0_operand (operands[1], SImode))"
4496 { return mips_output_move (operands[0], operands[1]); }
4497 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
4498 (set_attr "mode" "SI")
4499 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
4501 (define_insn "*movsi_mips16"
4502 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4503 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4505 && (register_operand (operands[0], SImode)
4506 || register_operand (operands[1], SImode))"
4507 { return mips_output_move (operands[0], operands[1]); }
4508 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
4509 (set_attr "mode" "SI")
4510 (set_attr_alternative "length"
4514 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4517 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4522 (const_string "*")])])
4524 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4525 ;; when the original load is a 4 byte instruction but the add and the
4526 ;; load are 2 2 byte instructions.
4529 [(set (match_operand:SI 0 "register_operand")
4530 (mem:SI (plus:SI (match_dup 0)
4531 (match_operand:SI 1 "const_int_operand"))))]
4532 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4533 && GET_CODE (operands[0]) == REG
4534 && M16_REG_P (REGNO (operands[0]))
4535 && GET_CODE (operands[1]) == CONST_INT
4536 && ((INTVAL (operands[1]) < 0
4537 && INTVAL (operands[1]) >= -0x80)
4538 || (INTVAL (operands[1]) >= 32 * 4
4539 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4540 || (INTVAL (operands[1]) >= 0
4541 && INTVAL (operands[1]) < 32 * 4
4542 && (INTVAL (operands[1]) & 3) != 0))"
4543 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4544 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4546 HOST_WIDE_INT val = INTVAL (operands[1]);
4549 operands[2] = const0_rtx;
4550 else if (val >= 32 * 4)
4554 operands[1] = GEN_INT (0x7c + off);
4555 operands[2] = GEN_INT (val - off - 0x7c);
4561 operands[1] = GEN_INT (off);
4562 operands[2] = GEN_INT (val - off);
4566 ;; On the mips16, we can split a load of certain constants into a load
4567 ;; and an add. This turns a 4 byte instruction into 2 2 byte
4571 [(set (match_operand:SI 0 "register_operand")
4572 (match_operand:SI 1 "const_int_operand"))]
4573 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4574 && GET_CODE (operands[0]) == REG
4575 && M16_REG_P (REGNO (operands[0]))
4576 && GET_CODE (operands[1]) == CONST_INT
4577 && INTVAL (operands[1]) >= 0x100
4578 && INTVAL (operands[1]) <= 0xff + 0x7f"
4579 [(set (match_dup 0) (match_dup 1))
4580 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4582 int val = INTVAL (operands[1]);
4584 operands[1] = GEN_INT (0xff);
4585 operands[2] = GEN_INT (val - 0xff);
4588 ;; On the mips16, we can split a load of a negative constant into a
4589 ;; load and a neg. That's what mips_output_move will generate anyhow.
4592 [(set (match_operand:SI 0 "register_operand")
4593 (match_operand:SI 1 "const_int_operand"))]
4594 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4595 && GET_CODE (operands[0]) == REG
4596 && M16_REG_P (REGNO (operands[0]))
4597 && GET_CODE (operands[1]) == CONST_INT
4598 && INTVAL (operands[1]) < 0
4599 && INTVAL (operands[1]) > - 0x8000"
4600 [(set (match_dup 0) (match_dup 1))
4601 (set (match_dup 0) (neg:SI (match_dup 0)))]
4602 { operands[1] = GEN_INT (- INTVAL (operands[1])); })
4604 ;; This insn handles moving CCmode values. It's really just a
4605 ;; slightly simplified copy of movsi_internal2, with additional cases
4606 ;; to move a condition register to a general register and to move
4607 ;; between the general registers and the floating point registers.
4609 (define_insn "movcc"
4610 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
4611 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
4612 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4613 { return mips_output_move (operands[0], operands[1]); }
4614 [(set_attr "type" "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
4615 (set_attr "mode" "SI")
4616 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
4618 ;; Reload condition code registers. reload_incc and reload_outcc
4619 ;; both handle moves from arbitrary operands into condition code
4620 ;; registers. reload_incc handles the more common case in which
4621 ;; a source operand is constrained to be in a condition-code
4622 ;; register, but has not been allocated to one.
4624 ;; Sometimes, such as in movcc, we have a CCmode destination whose
4625 ;; constraints do not include 'z'. reload_outcc handles the case
4626 ;; when such an operand is allocated to a condition-code register.
4628 ;; Note that reloads from a condition code register to some
4629 ;; other location can be done using ordinary moves. Moving
4630 ;; into a GPR takes a single movcc, moving elsewhere takes
4631 ;; two. We can leave these cases to the generic reload code.
4632 (define_expand "reload_incc"
4633 [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4634 (match_operand:CC 1 "general_operand" ""))
4635 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4636 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4638 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4642 (define_expand "reload_outcc"
4643 [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4644 (match_operand:CC 1 "register_operand" ""))
4645 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4646 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4648 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4652 ;; MIPS4 supports loading and storing a floating point register from
4653 ;; the sum of two general registers. We use two versions for each of
4654 ;; these four instructions: one where the two general registers are
4655 ;; SImode, and one where they are DImode. This is because general
4656 ;; registers will be in SImode when they hold 32 bit values, but,
4657 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
4658 ;; instructions will still work correctly.
4660 ;; ??? Perhaps it would be better to support these instructions by
4661 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
4662 ;; these instructions can only be used to load and store floating
4663 ;; point registers, that would probably cause trouble in reload.
4666 [(set (match_operand:SF 0 "register_operand" "=f")
4667 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4668 (match_operand:SI 2 "register_operand" "d"))))]
4669 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4671 [(set_attr "type" "fpidxload")
4672 (set_attr "mode" "SF")
4673 (set_attr "length" "4")])
4676 [(set (match_operand:SF 0 "register_operand" "=f")
4677 (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4678 (match_operand:DI 2 "register_operand" "d"))))]
4679 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4681 [(set_attr "type" "fpidxload")
4682 (set_attr "mode" "SF")
4683 (set_attr "length" "4")])
4686 [(set (match_operand:DF 0 "register_operand" "=f")
4687 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4688 (match_operand:SI 2 "register_operand" "d"))))]
4689 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4691 [(set_attr "type" "fpidxload")
4692 (set_attr "mode" "DF")
4693 (set_attr "length" "4")])
4696 [(set (match_operand:DF 0 "register_operand" "=f")
4697 (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4698 (match_operand:DI 2 "register_operand" "d"))))]
4699 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4701 [(set_attr "type" "fpidxload")
4702 (set_attr "mode" "DF")
4703 (set_attr "length" "4")])
4706 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4707 (match_operand:SI 2 "register_operand" "d")))
4708 (match_operand:SF 0 "register_operand" "f"))]
4709 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4711 [(set_attr "type" "fpidxstore")
4712 (set_attr "mode" "SF")
4713 (set_attr "length" "4")])
4716 [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4717 (match_operand:DI 2 "register_operand" "d")))
4718 (match_operand:SF 0 "register_operand" "f"))]
4719 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4721 [(set_attr "type" "fpidxstore")
4722 (set_attr "mode" "SF")
4723 (set_attr "length" "4")])
4726 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4727 (match_operand:SI 2 "register_operand" "d")))
4728 (match_operand:DF 0 "register_operand" "f"))]
4729 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4731 [(set_attr "type" "fpidxstore")
4732 (set_attr "mode" "DF")
4733 (set_attr "length" "4")])
4736 [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4737 (match_operand:DI 2 "register_operand" "d")))
4738 (match_operand:DF 0 "register_operand" "f"))]
4739 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4741 [(set_attr "type" "fpidxstore")
4742 (set_attr "mode" "DF")
4743 (set_attr "length" "4")])
4745 ;; 16-bit Integer moves
4747 ;; Unlike most other insns, the move insns can't be split with
4748 ;; different predicates, because register spilling and other parts of
4749 ;; the compiler, have memoized the insn number already.
4750 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4752 (define_expand "movhi"
4753 [(set (match_operand:HI 0 "")
4754 (match_operand:HI 1 ""))]
4757 if (mips_legitimize_move (HImode, operands[0], operands[1]))
4761 (define_insn "*movhi_internal"
4762 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4763 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4765 && (register_operand (operands[0], HImode)
4766 || reg_or_0_operand (operands[1], HImode))"
4776 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4777 (set_attr "mode" "HI")
4778 (set_attr "length" "4,4,*,*,4,4,4,4")])
4780 (define_insn "*movhi_mips16"
4781 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4782 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))]
4784 && (register_operand (operands[0], HImode)
4785 || register_operand (operands[1], HImode))"
4794 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4795 (set_attr "mode" "HI")
4796 (set_attr_alternative "length"
4800 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4803 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4807 (const_string "*")])])
4810 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4811 ;; when the original load is a 4 byte instruction but the add and the
4812 ;; load are 2 2 byte instructions.
4815 [(set (match_operand:HI 0 "register_operand")
4816 (mem:HI (plus:SI (match_dup 0)
4817 (match_operand:SI 1 "const_int_operand"))))]
4818 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4819 && GET_CODE (operands[0]) == REG
4820 && M16_REG_P (REGNO (operands[0]))
4821 && GET_CODE (operands[1]) == CONST_INT
4822 && ((INTVAL (operands[1]) < 0
4823 && INTVAL (operands[1]) >= -0x80)
4824 || (INTVAL (operands[1]) >= 32 * 2
4825 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4826 || (INTVAL (operands[1]) >= 0
4827 && INTVAL (operands[1]) < 32 * 2
4828 && (INTVAL (operands[1]) & 1) != 0))"
4829 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4830 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4832 HOST_WIDE_INT val = INTVAL (operands[1]);
4835 operands[2] = const0_rtx;
4836 else if (val >= 32 * 2)
4840 operands[1] = GEN_INT (0x7e + off);
4841 operands[2] = GEN_INT (val - off - 0x7e);
4847 operands[1] = GEN_INT (off);
4848 operands[2] = GEN_INT (val - off);
4852 ;; 8-bit Integer moves
4854 ;; Unlike most other insns, the move insns can't be split with
4855 ;; different predicates, because register spilling and other parts of
4856 ;; the compiler, have memoized the insn number already.
4857 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4859 (define_expand "movqi"
4860 [(set (match_operand:QI 0 "")
4861 (match_operand:QI 1 ""))]
4864 if (mips_legitimize_move (QImode, operands[0], operands[1]))
4868 (define_insn "*movqi_internal"
4869 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4870 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4872 && (register_operand (operands[0], QImode)
4873 || reg_or_0_operand (operands[1], QImode))"
4883 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4884 (set_attr "mode" "QI")
4885 (set_attr "length" "4,4,*,*,4,4,4,4")])
4887 (define_insn "*movqi_mips16"
4888 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4889 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))]
4891 && (register_operand (operands[0], QImode)
4892 || register_operand (operands[1], QImode))"
4901 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4902 (set_attr "mode" "QI")
4903 (set_attr "length" "4,4,4,4,8,*,*")])
4905 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
4906 ;; when the original load is a 4 byte instruction but the add and the
4907 ;; load are 2 2 byte instructions.
4910 [(set (match_operand:QI 0 "register_operand")
4911 (mem:QI (plus:SI (match_dup 0)
4912 (match_operand:SI 1 "const_int_operand"))))]
4913 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4914 && GET_CODE (operands[0]) == REG
4915 && M16_REG_P (REGNO (operands[0]))
4916 && GET_CODE (operands[1]) == CONST_INT
4917 && ((INTVAL (operands[1]) < 0
4918 && INTVAL (operands[1]) >= -0x80)
4919 || (INTVAL (operands[1]) >= 32
4920 && INTVAL (operands[1]) <= 31 + 0x7f))"
4921 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4922 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4924 HOST_WIDE_INT val = INTVAL (operands[1]);
4927 operands[2] = const0_rtx;
4930 operands[1] = GEN_INT (0x7f);
4931 operands[2] = GEN_INT (val - 0x7f);
4935 ;; 32-bit floating point moves
4937 (define_expand "movsf"
4938 [(set (match_operand:SF 0 "")
4939 (match_operand:SF 1 ""))]
4942 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4946 (define_insn "*movsf_hardfloat"
4947 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4948 (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
4950 && (register_operand (operands[0], SFmode)
4951 || reg_or_0_operand (operands[1], SFmode))"
4952 { return mips_output_move (operands[0], operands[1]); }
4953 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4954 (set_attr "mode" "SF")
4955 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4957 (define_insn "*movsf_softfloat"
4958 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4959 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
4960 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4961 && (register_operand (operands[0], SFmode)
4962 || reg_or_0_operand (operands[1], SFmode))"
4963 { return mips_output_move (operands[0], operands[1]); }
4964 [(set_attr "type" "arith,load,store")
4965 (set_attr "mode" "SF")
4966 (set_attr "length" "4,*,*")])
4968 (define_insn "*movsf_mips16"
4969 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4970 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
4972 && (register_operand (operands[0], SFmode)
4973 || register_operand (operands[1], SFmode))"
4974 { return mips_output_move (operands[0], operands[1]); }
4975 [(set_attr "type" "arith,arith,arith,load,store")
4976 (set_attr "mode" "SF")
4977 (set_attr "length" "4,4,4,*,*")])
4980 ;; 64-bit floating point moves
4982 (define_expand "movdf"
4983 [(set (match_operand:DF 0 "")
4984 (match_operand:DF 1 ""))]
4987 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4991 (define_insn "*movdf_hardfloat_64bit"
4992 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4993 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4994 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
4995 && (register_operand (operands[0], DFmode)
4996 || reg_or_0_operand (operands[1], DFmode))"
4997 { return mips_output_move (operands[0], operands[1]); }
4998 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4999 (set_attr "mode" "DF")
5000 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
5002 (define_insn "*movdf_hardfloat_32bit"
5003 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
5004 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
5005 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
5006 && (register_operand (operands[0], DFmode)
5007 || reg_or_0_operand (operands[1], DFmode))"
5008 { return mips_output_move (operands[0], operands[1]); }
5009 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
5010 (set_attr "mode" "DF")
5011 (set_attr "length" "4,8,*,*,8,8,8,*,*")])
5013 (define_insn "*movdf_softfloat"
5014 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
5015 (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
5016 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
5017 && (register_operand (operands[0], DFmode)
5018 || reg_or_0_operand (operands[1], DFmode))"
5019 { return mips_output_move (operands[0], operands[1]); }
5020 [(set_attr "type" "arith,load,store,xfer,xfer,fmove")
5021 (set_attr "mode" "DF")
5022 (set_attr "length" "8,*,*,4,4,4")])
5024 (define_insn "*movdf_mips16"
5025 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
5026 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
5028 && (register_operand (operands[0], DFmode)
5029 || register_operand (operands[1], DFmode))"
5030 { return mips_output_move (operands[0], operands[1]); }
5031 [(set_attr "type" "arith,arith,arith,load,store")
5032 (set_attr "mode" "DF")
5033 (set_attr "length" "8,8,8,*,*")])
5036 [(set (match_operand:DI 0 "nonimmediate_operand")
5037 (match_operand:DI 1 "move_operand"))]
5038 "reload_completed && !TARGET_64BIT
5039 && mips_split_64bit_move_p (operands[0], operands[1])"
5042 mips_split_64bit_move (operands[0], operands[1]);
5047 [(set (match_operand:DF 0 "nonimmediate_operand")
5048 (match_operand:DF 1 "move_operand"))]
5049 "reload_completed && !TARGET_64BIT
5050 && mips_split_64bit_move_p (operands[0], operands[1])"
5053 mips_split_64bit_move (operands[0], operands[1]);
5057 ;; The HI and LO registers are not truly independent. If we move an mthi
5058 ;; instruction before an mflo instruction, it will make the result of the
5059 ;; mflo unpredictable. The same goes for mtlo and mfhi.
5061 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
5062 ;; Operand 1 is the register we want, operand 2 is the other one.
5064 (define_insn "mfhilo_di"
5065 [(set (match_operand:DI 0 "register_operand" "=d,d")
5066 (unspec:DI [(match_operand:DI 1 "register_operand" "h,l")
5067 (match_operand:DI 2 "register_operand" "l,h")]
5071 [(set_attr "type" "mfhilo")])
5073 (define_insn "mfhilo_si"
5074 [(set (match_operand:SI 0 "register_operand" "=d,d")
5075 (unspec:SI [(match_operand:SI 1 "register_operand" "h,l")
5076 (match_operand:SI 2 "register_operand" "l,h")]
5080 [(set_attr "type" "mfhilo")])
5082 ;; Patterns for loading or storing part of a paired floating point
5083 ;; register. We need them because odd-numbered floating-point registers
5084 ;; are not fully independent: see mips_split_64bit_move.
5086 ;; Load the low word of operand 0 with operand 1.
5087 (define_insn "load_df_low"
5088 [(set (match_operand:DF 0 "register_operand" "=f,f")
5089 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
5090 UNSPEC_LOAD_DF_LOW))]
5091 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
5093 operands[0] = mips_subword (operands[0], 0);
5094 return mips_output_move (operands[0], operands[1]);
5096 [(set_attr "type" "xfer,fpload")
5097 (set_attr "mode" "SF")])
5099 ;; Load the high word of operand 0 from operand 1, preserving the value
5101 (define_insn "load_df_high"
5102 [(set (match_operand:DF 0 "register_operand" "=f,f")
5103 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
5104 (match_operand:DF 2 "register_operand" "0,0")]
5105 UNSPEC_LOAD_DF_HIGH))]
5106 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
5108 operands[0] = mips_subword (operands[0], 1);
5109 return mips_output_move (operands[0], operands[1]);
5111 [(set_attr "type" "xfer,fpload")
5112 (set_attr "mode" "SF")])
5114 ;; Store the high word of operand 1 in operand 0. The corresponding
5115 ;; low-word move is done in the normal way.
5116 (define_insn "store_df_high"
5117 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
5118 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
5119 UNSPEC_STORE_DF_HIGH))]
5120 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
5122 operands[1] = mips_subword (operands[1], 1);
5123 return mips_output_move (operands[0], operands[1]);
5125 [(set_attr "type" "xfer,fpstore")
5126 (set_attr "mode" "SF")])
5128 ;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
5129 ;; of _gp from the start of this function. Operand 1 is the incoming
5130 ;; function address.
5131 (define_insn_and_split "loadgp"
5132 [(unspec_volatile [(match_operand 0 "" "")
5133 (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
5134 "TARGET_ABICALLS && TARGET_NEWABI"
5137 [(set (match_dup 2) (match_dup 3))
5138 (set (match_dup 2) (match_dup 4))
5139 (set (match_dup 2) (match_dup 5))]
5141 operands[2] = pic_offset_table_rtx;
5142 operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
5143 operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
5144 operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
5146 [(set_attr "length" "12")])
5148 ;; The use of gp is hidden when not using explicit relocations.
5149 ;; This blockage instruction prevents the gp load from being
5150 ;; scheduled after an implicit use of gp. It also prevents
5151 ;; the load from being deleted as dead.
5152 (define_insn "loadgp_blockage"
5153 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
5156 [(set_attr "type" "unknown")
5157 (set_attr "mode" "none")
5158 (set_attr "length" "0")])
5160 ;; Emit a .cprestore directive, which expands to a single store instruction.
5161 ;; Note that we continue to use .cprestore for explicit reloc code so that
5162 ;; jals inside inlines asms will work correctly.
5163 (define_insn "cprestore"
5164 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
5168 [(set_attr "type" "store")
5169 (set_attr "length" "4")])
5171 ;; Block moves, see mips.c for more details.
5172 ;; Argument 0 is the destination
5173 ;; Argument 1 is the source
5174 ;; Argument 2 is the length
5175 ;; Argument 3 is the alignment
5177 (define_expand "movstrsi"
5178 [(parallel [(set (match_operand:BLK 0 "general_operand")
5179 (match_operand:BLK 1 "general_operand"))
5180 (use (match_operand:SI 2 ""))
5181 (use (match_operand:SI 3 "const_int_operand"))])]
5182 "!TARGET_MIPS16 && !TARGET_MEMCPY"
5184 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
5191 ;; ....................
5195 ;; ....................
5197 ;; Many of these instructions use trivial define_expands, because we
5198 ;; want to use a different set of constraints when TARGET_MIPS16.
5200 (define_expand "ashlsi3"
5201 [(set (match_operand:SI 0 "register_operand")
5202 (ashift:SI (match_operand:SI 1 "register_operand")
5203 (match_operand:SI 2 "arith_operand")))]
5206 /* On the mips16, a shift of more than 8 is a four byte instruction,
5207 so, for a shift between 8 and 16, it is just as fast to do two
5208 shifts of 8 or less. If there is a lot of shifting going on, we
5209 may win in CSE. Otherwise combine will put the shifts back
5210 together again. This can be called by function_arg, so we must
5211 be careful not to allocate a new register if we've reached the
5215 && GET_CODE (operands[2]) == CONST_INT
5216 && INTVAL (operands[2]) > 8
5217 && INTVAL (operands[2]) <= 16
5218 && ! reload_in_progress
5219 && ! reload_completed)
5221 rtx temp = gen_reg_rtx (SImode);
5223 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
5224 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
5225 GEN_INT (INTVAL (operands[2]) - 8)));
5230 (define_insn "ashlsi3_internal1"
5231 [(set (match_operand:SI 0 "register_operand" "=d")
5232 (ashift:SI (match_operand:SI 1 "register_operand" "d")
5233 (match_operand:SI 2 "arith_operand" "dI")))]
5236 if (GET_CODE (operands[2]) == CONST_INT)
5237 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5239 return "sll\t%0,%1,%2";
5241 [(set_attr "type" "shift")
5242 (set_attr "mode" "SI")])
5244 (define_insn "ashlsi3_internal1_extend"
5245 [(set (match_operand:DI 0 "register_operand" "=d")
5246 (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
5247 (match_operand:SI 2 "arith_operand" "dI"))))]
5248 "TARGET_64BIT && !TARGET_MIPS16"
5250 if (GET_CODE (operands[2]) == CONST_INT)
5251 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5253 return "sll\t%0,%1,%2";
5255 [(set_attr "type" "shift")
5256 (set_attr "mode" "DI")])
5259 (define_insn "ashlsi3_internal2"
5260 [(set (match_operand:SI 0 "register_operand" "=d,d")
5261 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
5262 (match_operand:SI 2 "arith_operand" "d,I")))]
5265 if (which_alternative == 0)
5266 return "sll\t%0,%2";
5268 if (GET_CODE (operands[2]) == CONST_INT)
5269 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5271 return "sll\t%0,%1,%2";
5273 [(set_attr "type" "shift")
5274 (set_attr "mode" "SI")
5275 (set_attr_alternative "length"
5277 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5281 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5284 [(set (match_operand:SI 0 "register_operand")
5285 (ashift:SI (match_operand:SI 1 "register_operand")
5286 (match_operand:SI 2 "const_int_operand")))]
5287 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5288 && GET_CODE (operands[2]) == CONST_INT
5289 && INTVAL (operands[2]) > 8
5290 && INTVAL (operands[2]) <= 16"
5291 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
5292 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
5293 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5295 (define_expand "ashldi3"
5296 [(set (match_operand:DI 0 "register_operand")
5297 (ashift:DI (match_operand:DI 1 "register_operand")
5298 (match_operand:SI 2 "arith_operand")))]
5301 /* On the mips16, a shift of more than 8 is a four byte
5302 instruction, so, for a shift between 8 and 16, it is just as
5303 fast to do two shifts of 8 or less. If there is a lot of
5304 shifting going on, we may win in CSE. Otherwise combine will
5305 put the shifts back together again. This can be called by
5306 function_arg, so we must be careful not to allocate a new
5307 register if we've reached the reload pass. */
5310 && GET_CODE (operands[2]) == CONST_INT
5311 && INTVAL (operands[2]) > 8
5312 && INTVAL (operands[2]) <= 16
5313 && ! reload_in_progress
5314 && ! reload_completed)
5316 rtx temp = gen_reg_rtx (DImode);
5318 emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
5319 emit_insn (gen_ashldi3_internal (operands[0], temp,
5320 GEN_INT (INTVAL (operands[2]) - 8)));
5326 (define_insn "ashldi3_internal"
5327 [(set (match_operand:DI 0 "register_operand" "=d")
5328 (ashift:DI (match_operand:DI 1 "register_operand" "d")
5329 (match_operand:SI 2 "arith_operand" "dI")))]
5330 "TARGET_64BIT && !TARGET_MIPS16"
5332 if (GET_CODE (operands[2]) == CONST_INT)
5333 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5335 return "dsll\t%0,%1,%2";
5337 [(set_attr "type" "shift")
5338 (set_attr "mode" "DI")])
5341 [(set (match_operand:DI 0 "register_operand" "=d,d")
5342 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
5343 (match_operand:SI 2 "arith_operand" "d,I")))]
5344 "TARGET_64BIT && TARGET_MIPS16"
5346 if (which_alternative == 0)
5347 return "dsll\t%0,%2";
5349 if (GET_CODE (operands[2]) == CONST_INT)
5350 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5352 return "dsll\t%0,%1,%2";
5354 [(set_attr "type" "shift")
5355 (set_attr "mode" "DI")
5356 (set_attr_alternative "length"
5358 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5363 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5366 [(set (match_operand:DI 0 "register_operand")
5367 (ashift:DI (match_operand:DI 1 "register_operand")
5368 (match_operand:SI 2 "const_int_operand")))]
5369 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5371 && GET_CODE (operands[2]) == CONST_INT
5372 && INTVAL (operands[2]) > 8
5373 && INTVAL (operands[2]) <= 16"
5374 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
5375 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
5376 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5378 (define_expand "ashrsi3"
5379 [(set (match_operand:SI 0 "register_operand")
5380 (ashiftrt:SI (match_operand:SI 1 "register_operand")
5381 (match_operand:SI 2 "arith_operand")))]
5384 /* On the mips16, a shift of more than 8 is a four byte instruction,
5385 so, for a shift between 8 and 16, it is just as fast to do two
5386 shifts of 8 or less. If there is a lot of shifting going on, we
5387 may win in CSE. Otherwise combine will put the shifts back
5391 && GET_CODE (operands[2]) == CONST_INT
5392 && INTVAL (operands[2]) > 8
5393 && INTVAL (operands[2]) <= 16)
5395 rtx temp = gen_reg_rtx (SImode);
5397 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5398 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
5399 GEN_INT (INTVAL (operands[2]) - 8)));
5404 (define_insn "ashrsi3_internal1"
5405 [(set (match_operand:SI 0 "register_operand" "=d")
5406 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
5407 (match_operand:SI 2 "arith_operand" "dI")))]
5410 if (GET_CODE (operands[2]) == CONST_INT)
5411 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5413 return "sra\t%0,%1,%2";
5415 [(set_attr "type" "shift")
5416 (set_attr "mode" "SI")])
5418 (define_insn "ashrsi3_internal2"
5419 [(set (match_operand:SI 0 "register_operand" "=d,d")
5420 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5421 (match_operand:SI 2 "arith_operand" "d,I")))]
5424 if (which_alternative == 0)
5425 return "sra\t%0,%2";
5427 if (GET_CODE (operands[2]) == CONST_INT)
5428 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5430 return "sra\t%0,%1,%2";
5432 [(set_attr "type" "shift")
5433 (set_attr "mode" "SI")
5434 (set_attr_alternative "length"
5436 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5441 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5444 [(set (match_operand:SI 0 "register_operand")
5445 (ashiftrt:SI (match_operand:SI 1 "register_operand")
5446 (match_operand:SI 2 "const_int_operand")))]
5447 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5448 && GET_CODE (operands[2]) == CONST_INT
5449 && INTVAL (operands[2]) > 8
5450 && INTVAL (operands[2]) <= 16"
5451 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
5452 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
5453 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5455 (define_expand "ashrdi3"
5456 [(set (match_operand:DI 0 "register_operand")
5457 (ashiftrt:DI (match_operand:DI 1 "register_operand")
5458 (match_operand:SI 2 "arith_operand")))]
5461 /* On the mips16, a shift of more than 8 is a four byte
5462 instruction, so, for a shift between 8 and 16, it is just as
5463 fast to do two shifts of 8 or less. If there is a lot of
5464 shifting going on, we may win in CSE. Otherwise combine will
5465 put the shifts back together again. */
5468 && GET_CODE (operands[2]) == CONST_INT
5469 && INTVAL (operands[2]) > 8
5470 && INTVAL (operands[2]) <= 16)
5472 rtx temp = gen_reg_rtx (DImode);
5474 emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
5475 emit_insn (gen_ashrdi3_internal (operands[0], temp,
5476 GEN_INT (INTVAL (operands[2]) - 8)));
5482 (define_insn "ashrdi3_internal"
5483 [(set (match_operand:DI 0 "register_operand" "=d")
5484 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5485 (match_operand:SI 2 "arith_operand" "dI")))]
5486 "TARGET_64BIT && !TARGET_MIPS16"
5488 if (GET_CODE (operands[2]) == CONST_INT)
5489 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5491 return "dsra\t%0,%1,%2";
5493 [(set_attr "type" "shift")
5494 (set_attr "mode" "DI")])
5497 [(set (match_operand:DI 0 "register_operand" "=d,d")
5498 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5499 (match_operand:SI 2 "arith_operand" "d,I")))]
5500 "TARGET_64BIT && TARGET_MIPS16"
5502 if (GET_CODE (operands[2]) == CONST_INT)
5503 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5505 return "dsra\t%0,%2";
5507 [(set_attr "type" "shift")
5508 (set_attr "mode" "DI")
5509 (set_attr_alternative "length"
5511 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5515 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5518 [(set (match_operand:DI 0 "register_operand")
5519 (ashiftrt:DI (match_operand:DI 1 "register_operand")
5520 (match_operand:SI 2 "const_int_operand")))]
5521 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5523 && GET_CODE (operands[2]) == CONST_INT
5524 && INTVAL (operands[2]) > 8
5525 && INTVAL (operands[2]) <= 16"
5526 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
5527 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
5528 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5530 (define_expand "lshrsi3"
5531 [(set (match_operand:SI 0 "register_operand")
5532 (lshiftrt:SI (match_operand:SI 1 "register_operand")
5533 (match_operand:SI 2 "arith_operand")))]
5536 /* On the mips16, a shift of more than 8 is a four byte instruction,
5537 so, for a shift between 8 and 16, it is just as fast to do two
5538 shifts of 8 or less. If there is a lot of shifting going on, we
5539 may win in CSE. Otherwise combine will put the shifts back
5543 && GET_CODE (operands[2]) == CONST_INT
5544 && INTVAL (operands[2]) > 8
5545 && INTVAL (operands[2]) <= 16)
5547 rtx temp = gen_reg_rtx (SImode);
5549 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5550 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
5551 GEN_INT (INTVAL (operands[2]) - 8)));
5556 (define_insn "lshrsi3_internal1"
5557 [(set (match_operand:SI 0 "register_operand" "=d")
5558 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
5559 (match_operand:SI 2 "arith_operand" "dI")))]
5562 if (GET_CODE (operands[2]) == CONST_INT)
5563 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5565 return "srl\t%0,%1,%2";
5567 [(set_attr "type" "shift")
5568 (set_attr "mode" "SI")])
5570 (define_insn "lshrsi3_internal2"
5571 [(set (match_operand:SI 0 "register_operand" "=d,d")
5572 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5573 (match_operand:SI 2 "arith_operand" "d,I")))]
5576 if (which_alternative == 0)
5577 return "srl\t%0,%2";
5579 if (GET_CODE (operands[2]) == CONST_INT)
5580 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5582 return "srl\t%0,%1,%2";
5584 [(set_attr "type" "shift")
5585 (set_attr "mode" "SI")
5586 (set_attr_alternative "length"
5588 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5593 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5596 [(set (match_operand:SI 0 "register_operand")
5597 (lshiftrt:SI (match_operand:SI 1 "register_operand")
5598 (match_operand:SI 2 "const_int_operand")))]
5599 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5600 && GET_CODE (operands[2]) == CONST_INT
5601 && INTVAL (operands[2]) > 8
5602 && INTVAL (operands[2]) <= 16"
5603 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
5604 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5605 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5607 ;; If we load a byte on the mips16 as a bitfield, the resulting
5608 ;; sequence of instructions is too complicated for combine, because it
5609 ;; involves four instructions: a load, a shift, a constant load into a
5610 ;; register, and an and (the key problem here is that the mips16 does
5611 ;; not have and immediate). We recognize a shift of a load in order
5612 ;; to make it simple enough for combine to understand.
5614 ;; The length here is the worst case: the length of the split version
5615 ;; will be more accurate.
5616 (define_insn_and_split ""
5617 [(set (match_operand:SI 0 "register_operand" "=d")
5618 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5619 (match_operand:SI 2 "immediate_operand" "I")))]
5623 [(set (match_dup 0) (match_dup 1))
5624 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5626 [(set_attr "type" "load")
5627 (set_attr "mode" "SI")
5628 (set_attr "length" "16")])
5630 (define_expand "lshrdi3"
5631 [(set (match_operand:DI 0 "register_operand")
5632 (lshiftrt:DI (match_operand:DI 1 "register_operand")
5633 (match_operand:SI 2 "arith_operand")))]
5636 /* On the mips16, a shift of more than 8 is a four byte
5637 instruction, so, for a shift between 8 and 16, it is just as
5638 fast to do two shifts of 8 or less. If there is a lot of
5639 shifting going on, we may win in CSE. Otherwise combine will
5640 put the shifts back together again. */
5643 && GET_CODE (operands[2]) == CONST_INT
5644 && INTVAL (operands[2]) > 8
5645 && INTVAL (operands[2]) <= 16)
5647 rtx temp = gen_reg_rtx (DImode);
5649 emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
5650 emit_insn (gen_lshrdi3_internal (operands[0], temp,
5651 GEN_INT (INTVAL (operands[2]) - 8)));
5657 (define_insn "lshrdi3_internal"
5658 [(set (match_operand:DI 0 "register_operand" "=d")
5659 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
5660 (match_operand:SI 2 "arith_operand" "dI")))]
5661 "TARGET_64BIT && !TARGET_MIPS16"
5663 if (GET_CODE (operands[2]) == CONST_INT)
5664 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5666 return "dsrl\t%0,%1,%2";
5668 [(set_attr "type" "shift")
5669 (set_attr "mode" "DI")])
5672 [(set (match_operand:DI 0 "register_operand" "=d,d")
5673 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5674 (match_operand:SI 2 "arith_operand" "d,I")))]
5675 "TARGET_64BIT && TARGET_MIPS16"
5677 if (GET_CODE (operands[2]) == CONST_INT)
5678 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5680 return "dsrl\t%0,%2";
5682 [(set_attr "type" "shift")
5683 (set_attr "mode" "DI")
5684 (set_attr_alternative "length"
5686 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5690 (define_insn "rotrsi3"
5691 [(set (match_operand:SI 0 "register_operand" "=d")
5692 (rotatert:SI (match_operand:SI 1 "register_operand" "d")
5693 (match_operand:SI 2 "arith_operand" "dn")))]
5696 if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
5697 return "rorv\t%0,%1,%2";
5699 if ((GET_CODE (operands[2]) == CONST_INT)
5700 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
5703 return "ror\t%0,%1,%2";
5705 [(set_attr "type" "shift")
5706 (set_attr "mode" "SI")])
5708 (define_insn "rotrdi3"
5709 [(set (match_operand:DI 0 "register_operand" "=d")
5710 (rotatert:DI (match_operand:DI 1 "register_operand" "d")
5711 (match_operand:DI 2 "arith_operand" "dn")))]
5716 if (GET_CODE (operands[2]) != CONST_INT)
5717 return "drorv\t%0,%1,%2";
5719 if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
5720 return "dror32\t%0,%1,%2";
5723 if ((GET_CODE (operands[2]) == CONST_INT)
5724 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
5727 return "dror\t%0,%1,%2";
5729 [(set_attr "type" "shift")
5730 (set_attr "mode" "DI")])
5733 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5736 [(set (match_operand:DI 0 "register_operand")
5737 (lshiftrt:DI (match_operand:DI 1 "register_operand")
5738 (match_operand:SI 2 "const_int_operand")))]
5739 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5740 && GET_CODE (operands[2]) == CONST_INT
5741 && INTVAL (operands[2]) > 8
5742 && INTVAL (operands[2]) <= 16"
5743 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
5744 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
5745 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5748 ;; ....................
5752 ;; ....................
5754 ;; Flow here is rather complex:
5756 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
5757 ;; arguments into the branch_cmp array, and the type into
5758 ;; branch_type. No RTL is generated.
5760 ;; 2) The appropriate branch define_expand is called, which then
5761 ;; creates the appropriate RTL for the comparison and branch.
5762 ;; Different CC modes are used, based on what type of branch is
5763 ;; done, so that we can constrain things appropriately. There
5764 ;; are assumptions in the rest of GCC that break if we fold the
5765 ;; operands into the branches for integer operations, and use cc0
5766 ;; for floating point, so we use the fp status register instead.
5767 ;; If needed, an appropriate temporary is created to hold the
5768 ;; of the integer compare.
5770 (define_expand "cmpsi"
5772 (compare:CC (match_operand:SI 0 "register_operand")
5773 (match_operand:SI 1 "arith_operand")))]
5776 branch_cmp[0] = operands[0];
5777 branch_cmp[1] = operands[1];
5778 branch_type = CMP_SI;
5782 (define_expand "cmpdi"
5784 (compare:CC (match_operand:DI 0 "register_operand")
5785 (match_operand:DI 1 "arith_operand")))]
5788 branch_cmp[0] = operands[0];
5789 branch_cmp[1] = operands[1];
5790 branch_type = CMP_DI;
5794 (define_expand "cmpdf"
5796 (compare:CC (match_operand:DF 0 "register_operand")
5797 (match_operand:DF 1 "register_operand")))]
5798 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5800 branch_cmp[0] = operands[0];
5801 branch_cmp[1] = operands[1];
5802 branch_type = CMP_DF;
5806 (define_expand "cmpsf"
5808 (compare:CC (match_operand:SF 0 "register_operand")
5809 (match_operand:SF 1 "register_operand")))]
5812 branch_cmp[0] = operands[0];
5813 branch_cmp[1] = operands[1];
5814 branch_type = CMP_SF;
5819 ;; ....................
5821 ;; CONDITIONAL BRANCHES
5823 ;; ....................
5825 ;; Conditional branches on floating-point equality tests.
5827 (define_insn "branch_fp"
5830 (match_operator:CC 0 "cmp_op"
5831 [(match_operand:CC 2 "register_operand" "z")
5833 (label_ref (match_operand 1 "" ""))
5837 return mips_output_conditional_branch (insn,
5839 /*two_operands_p=*/0,
5842 get_attr_length (insn));
5844 [(set_attr "type" "branch")
5845 (set_attr "mode" "none")])
5847 (define_insn "branch_fp_inverted"
5850 (match_operator:CC 0 "cmp_op"
5851 [(match_operand:CC 2 "register_operand" "z")
5854 (label_ref (match_operand 1 "" ""))))]
5857 return mips_output_conditional_branch (insn,
5859 /*two_operands_p=*/0,
5862 get_attr_length (insn));
5864 [(set_attr "type" "branch")
5865 (set_attr "mode" "none")])
5867 ;; Conditional branches on comparisons with zero.
5869 (define_insn "branch_zero"
5872 (match_operator:SI 0 "cmp_op"
5873 [(match_operand:SI 2 "register_operand" "d")
5875 (label_ref (match_operand 1 "" ""))
5879 return mips_output_conditional_branch (insn,
5881 /*two_operands_p=*/0,
5884 get_attr_length (insn));
5886 [(set_attr "type" "branch")
5887 (set_attr "mode" "none")])
5889 (define_insn "branch_zero_inverted"
5892 (match_operator:SI 0 "cmp_op"
5893 [(match_operand:SI 2 "register_operand" "d")
5896 (label_ref (match_operand 1 "" ""))))]
5899 return mips_output_conditional_branch (insn,
5901 /*two_operands_p=*/0,
5904 get_attr_length (insn));
5906 [(set_attr "type" "branch")
5907 (set_attr "mode" "none")])
5909 (define_insn "branch_zero_di"
5912 (match_operator:DI 0 "cmp_op"
5913 [(match_operand:DI 2 "register_operand" "d")
5915 (label_ref (match_operand 1 "" ""))
5919 return mips_output_conditional_branch (insn,
5921 /*two_operands_p=*/0,
5924 get_attr_length (insn));
5926 [(set_attr "type" "branch")
5927 (set_attr "mode" "none")])
5929 (define_insn "branch_zero_di_inverted"
5932 (match_operator:DI 0 "cmp_op"
5933 [(match_operand:DI 2 "register_operand" "d")
5936 (label_ref (match_operand 1 "" ""))))]
5939 return mips_output_conditional_branch (insn,
5941 /*two_operands_p=*/0,
5944 get_attr_length (insn));
5946 [(set_attr "type" "branch")
5947 (set_attr "mode" "none")])
5949 ;; Conditional branch on equality comparison.
5951 (define_insn "branch_equality"
5954 (match_operator:SI 0 "equality_op"
5955 [(match_operand:SI 2 "register_operand" "d")
5956 (match_operand:SI 3 "register_operand" "d")])
5957 (label_ref (match_operand 1 "" ""))
5961 return mips_output_conditional_branch (insn,
5963 /*two_operands_p=*/1,
5966 get_attr_length (insn));
5968 [(set_attr "type" "branch")
5969 (set_attr "mode" "none")])
5971 (define_insn "branch_equality_di"
5974 (match_operator:DI 0 "equality_op"
5975 [(match_operand:DI 2 "register_operand" "d")
5976 (match_operand:DI 3 "register_operand" "d")])
5977 (label_ref (match_operand 1 "" ""))
5981 return mips_output_conditional_branch (insn,
5983 /*two_operands_p=*/1,
5986 get_attr_length (insn));
5988 [(set_attr "type" "branch")
5989 (set_attr "mode" "none")])
5991 (define_insn "branch_equality_inverted"
5994 (match_operator:SI 0 "equality_op"
5995 [(match_operand:SI 2 "register_operand" "d")
5996 (match_operand:SI 3 "register_operand" "d")])
5998 (label_ref (match_operand 1 "" ""))))]
6001 return mips_output_conditional_branch (insn,
6003 /*two_operands_p=*/1,
6006 get_attr_length (insn));
6008 [(set_attr "type" "branch")
6009 (set_attr "mode" "none")])
6011 (define_insn "branch_equality_di_inverted"
6014 (match_operator:DI 0 "equality_op"
6015 [(match_operand:DI 2 "register_operand" "d")
6016 (match_operand:DI 3 "register_operand" "d")])
6018 (label_ref (match_operand 1 "" ""))))]
6021 return mips_output_conditional_branch (insn,
6023 /*two_operands_p=*/1,
6026 get_attr_length (insn));
6028 [(set_attr "type" "branch")
6029 (set_attr "mode" "none")])
6035 (if_then_else (match_operator:SI 0 "equality_op"
6036 [(match_operand:SI 1 "register_operand" "d,t")
6038 (match_operand 2 "pc_or_label_operand" "")
6039 (match_operand 3 "pc_or_label_operand" "")))]
6042 if (operands[2] != pc_rtx)
6044 if (which_alternative == 0)
6045 return "b%C0z\t%1,%2";
6047 return "bt%C0z\t%2";
6051 if (which_alternative == 0)
6052 return "b%N0z\t%1,%3";
6054 return "bt%N0z\t%3";
6057 [(set_attr "type" "branch")
6058 (set_attr "mode" "none")
6059 (set_attr "length" "8")])
6063 (if_then_else (match_operator:DI 0 "equality_op"
6064 [(match_operand:DI 1 "register_operand" "d,t")
6066 (match_operand 2 "pc_or_label_operand" "")
6067 (match_operand 3 "pc_or_label_operand" "")))]
6070 if (operands[2] != pc_rtx)
6072 if (which_alternative == 0)
6073 return "b%C0z\t%1,%2";
6075 return "bt%C0z\t%2";
6079 if (which_alternative == 0)
6080 return "b%N0z\t%1,%3";
6082 return "bt%N0z\t%3";
6085 [(set_attr "type" "branch")
6086 (set_attr "mode" "none")
6087 (set_attr "length" "8")])
6089 (define_expand "bunordered"
6091 (if_then_else (unordered:CC (cc0)
6093 (label_ref (match_operand 0 ""))
6097 gen_conditional_branch (operands, UNORDERED);
6101 (define_expand "bordered"
6103 (if_then_else (ordered:CC (cc0)
6105 (label_ref (match_operand 0 ""))
6109 gen_conditional_branch (operands, ORDERED);
6113 (define_expand "bunlt"
6115 (if_then_else (unlt:CC (cc0)
6117 (label_ref (match_operand 0 ""))
6121 gen_conditional_branch (operands, UNLT);
6125 (define_expand "bunge"
6127 (if_then_else (unge:CC (cc0)
6129 (label_ref (match_operand 0 ""))
6133 gen_conditional_branch (operands, UNGE);
6137 (define_expand "buneq"
6139 (if_then_else (uneq:CC (cc0)
6141 (label_ref (match_operand 0 ""))
6145 gen_conditional_branch (operands, UNEQ);
6149 (define_expand "bltgt"
6151 (if_then_else (ltgt:CC (cc0)
6153 (label_ref (match_operand 0 ""))
6157 gen_conditional_branch (operands, LTGT);
6161 (define_expand "bunle"
6163 (if_then_else (unle:CC (cc0)
6165 (label_ref (match_operand 0 ""))
6169 gen_conditional_branch (operands, UNLE);
6173 (define_expand "bungt"
6175 (if_then_else (ungt:CC (cc0)
6177 (label_ref (match_operand 0 ""))
6181 gen_conditional_branch (operands, UNGT);
6185 (define_expand "beq"
6187 (if_then_else (eq:CC (cc0)
6189 (label_ref (match_operand 0 ""))
6193 gen_conditional_branch (operands, EQ);
6197 (define_expand "bne"
6199 (if_then_else (ne:CC (cc0)
6201 (label_ref (match_operand 0 ""))
6205 gen_conditional_branch (operands, NE);
6209 (define_expand "bgt"
6211 (if_then_else (gt:CC (cc0)
6213 (label_ref (match_operand 0 ""))
6217 gen_conditional_branch (operands, GT);
6221 (define_expand "bge"
6223 (if_then_else (ge:CC (cc0)
6225 (label_ref (match_operand 0 ""))
6229 gen_conditional_branch (operands, GE);
6233 (define_expand "blt"
6235 (if_then_else (lt:CC (cc0)
6237 (label_ref (match_operand 0 ""))
6241 gen_conditional_branch (operands, LT);
6245 (define_expand "ble"
6247 (if_then_else (le:CC (cc0)
6249 (label_ref (match_operand 0 ""))
6253 gen_conditional_branch (operands, LE);
6257 (define_expand "bgtu"
6259 (if_then_else (gtu:CC (cc0)
6261 (label_ref (match_operand 0 ""))
6265 gen_conditional_branch (operands, GTU);
6269 (define_expand "bgeu"
6271 (if_then_else (geu:CC (cc0)
6273 (label_ref (match_operand 0 ""))
6277 gen_conditional_branch (operands, GEU);
6281 (define_expand "bltu"
6283 (if_then_else (ltu:CC (cc0)
6285 (label_ref (match_operand 0 ""))
6289 gen_conditional_branch (operands, LTU);
6293 (define_expand "bleu"
6295 (if_then_else (leu:CC (cc0)
6297 (label_ref (match_operand 0 ""))
6301 gen_conditional_branch (operands, LEU);
6306 ;; ....................
6308 ;; SETTING A REGISTER FROM A COMPARISON
6310 ;; ....................
6312 (define_expand "seq"
6313 [(set (match_operand:SI 0 "register_operand")
6314 (eq:SI (match_dup 1)
6318 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6321 /* Set up operands from compare. */
6322 operands[1] = branch_cmp[0];
6323 operands[2] = branch_cmp[1];
6325 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6327 gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
6331 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
6332 operands[2] = force_reg (SImode, operands[2]);
6334 /* Fall through and generate default code. */
6338 (define_insn "seq_si_zero"
6339 [(set (match_operand:SI 0 "register_operand" "=d")
6340 (eq:SI (match_operand:SI 1 "register_operand" "d")
6344 [(set_attr "type" "slt")
6345 (set_attr "mode" "SI")])
6348 [(set (match_operand:SI 0 "register_operand" "=t")
6349 (eq:SI (match_operand:SI 1 "register_operand" "d")
6353 [(set_attr "type" "slt")
6354 (set_attr "mode" "SI")])
6356 (define_insn "seq_di_zero"
6357 [(set (match_operand:DI 0 "register_operand" "=d")
6358 (eq:DI (match_operand:DI 1 "register_operand" "d")
6360 "TARGET_64BIT && !TARGET_MIPS16"
6362 [(set_attr "type" "slt")
6363 (set_attr "mode" "DI")])
6366 [(set (match_operand:DI 0 "register_operand" "=t")
6367 (eq:DI (match_operand:DI 1 "register_operand" "d")
6369 "TARGET_64BIT && TARGET_MIPS16"
6371 [(set_attr "type" "slt")
6372 (set_attr "mode" "DI")])
6374 (define_insn "seq_si"
6375 [(set (match_operand:SI 0 "register_operand" "=d,d")
6376 (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
6377 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
6378 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6380 xor\t%0,%1,%2\;sltu\t%0,%0,1
6381 xori\t%0,%1,%2\;sltu\t%0,%0,1"
6382 [(set_attr "type" "multi")
6383 (set_attr "mode" "SI")
6384 (set_attr "length" "8")])
6387 [(set (match_operand:SI 0 "register_operand")
6388 (eq:SI (match_operand:SI 1 "register_operand")
6389 (match_operand:SI 2 "uns_arith_operand")))]
6390 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
6391 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
6393 (xor:SI (match_dup 1)
6396 (ltu:SI (match_dup 0)
6400 (define_insn "seq_di"
6401 [(set (match_operand:DI 0 "register_operand" "=d,d")
6402 (eq:DI (match_operand:DI 1 "register_operand" "%d,d")
6403 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
6404 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6406 xor\t%0,%1,%2\;sltu\t%0,%0,1
6407 xori\t%0,%1,%2\;sltu\t%0,%0,1"
6408 [(set_attr "type" "multi")
6409 (set_attr "mode" "DI")
6410 (set_attr "length" "8")])
6413 [(set (match_operand:DI 0 "register_operand")
6414 (eq:DI (match_operand:DI 1 "register_operand")
6415 (match_operand:DI 2 "uns_arith_operand")))]
6416 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
6418 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
6420 (xor:DI (match_dup 1)
6423 (ltu:DI (match_dup 0)
6427 ;; On the mips16 the default code is better than using sltu.
6429 (define_expand "sne"
6430 [(set (match_operand:SI 0 "register_operand")
6431 (ne:SI (match_dup 1)
6435 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6438 /* Set up operands from compare. */
6439 operands[1] = branch_cmp[0];
6440 operands[2] = branch_cmp[1];
6442 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
6444 gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
6448 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
6449 operands[2] = force_reg (SImode, operands[2]);
6451 /* Fall through and generate default code. */
6454 (define_insn "sne_si_zero"
6455 [(set (match_operand:SI 0 "register_operand" "=d")
6456 (ne:SI (match_operand:SI 1 "register_operand" "d")
6460 [(set_attr "type" "slt")
6461 (set_attr "mode" "SI")])
6463 (define_insn "sne_di_zero"
6464 [(set (match_operand:DI 0 "register_operand" "=d")
6465 (ne:DI (match_operand:DI 1 "register_operand" "d")
6467 "TARGET_64BIT && !TARGET_MIPS16"
6469 [(set_attr "type" "slt")
6470 (set_attr "mode" "DI")])
6472 (define_insn "sne_si"
6473 [(set (match_operand:SI 0 "register_operand" "=d,d")
6474 (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
6475 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
6476 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6478 xor\t%0,%1,%2\;sltu\t%0,%.,%0
6479 xori\t%0,%1,%x2\;sltu\t%0,%.,%0"
6480 [(set_attr "type" "multi")
6481 (set_attr "mode" "SI")
6482 (set_attr "length" "8")])
6485 [(set (match_operand:SI 0 "register_operand")
6486 (ne:SI (match_operand:SI 1 "register_operand")
6487 (match_operand:SI 2 "uns_arith_operand")))]
6488 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
6489 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
6491 (xor:SI (match_dup 1)
6494 (gtu:SI (match_dup 0)
6498 (define_insn "sne_di"
6499 [(set (match_operand:DI 0 "register_operand" "=d,d")
6500 (ne:DI (match_operand:DI 1 "register_operand" "%d,d")
6501 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
6502 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6504 xor\t%0,%1,%2\;sltu\t%0,%.,%0
6505 xori\t%0,%1,%x2\;sltu\t%0,%.,%0"
6506 [(set_attr "type" "multi")
6507 (set_attr "mode" "DI")
6508 (set_attr "length" "8")])
6511 [(set (match_operand:DI 0 "register_operand")
6512 (ne:DI (match_operand:DI 1 "register_operand")
6513 (match_operand:DI 2 "uns_arith_operand")))]
6514 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
6516 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
6518 (xor:DI (match_dup 1)
6521 (gtu:DI (match_dup 0)
6525 (define_expand "sgt"
6526 [(set (match_operand:SI 0 "register_operand")
6527 (gt:SI (match_dup 1)
6531 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6534 /* Set up operands from compare. */
6535 operands[1] = branch_cmp[0];
6536 operands[2] = branch_cmp[1];
6538 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6540 gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
6544 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
6545 operands[2] = force_reg (SImode, operands[2]);
6547 /* Fall through and generate default code. */
6550 (define_insn "sgt_si"
6551 [(set (match_operand:SI 0 "register_operand" "=d")
6552 (gt:SI (match_operand:SI 1 "register_operand" "d")
6553 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6556 [(set_attr "type" "slt")
6557 (set_attr "mode" "SI")])
6560 [(set (match_operand:SI 0 "register_operand" "=t")
6561 (gt:SI (match_operand:SI 1 "register_operand" "d")
6562 (match_operand:SI 2 "register_operand" "d")))]
6565 [(set_attr "type" "slt")
6566 (set_attr "mode" "SI")])
6568 (define_insn "sgt_di"
6569 [(set (match_operand:DI 0 "register_operand" "=d")
6570 (gt:DI (match_operand:DI 1 "register_operand" "d")
6571 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6572 "TARGET_64BIT && !TARGET_MIPS16"
6574 [(set_attr "type" "slt")
6575 (set_attr "mode" "DI")])
6578 [(set (match_operand:DI 0 "register_operand" "=d")
6579 (gt:DI (match_operand:DI 1 "register_operand" "d")
6580 (match_operand:DI 2 "register_operand" "d")))]
6581 "TARGET_64BIT && TARGET_MIPS16"
6583 [(set_attr "type" "slt")
6584 (set_attr "mode" "DI")])
6586 (define_expand "sge"
6587 [(set (match_operand:SI 0 "register_operand")
6588 (ge:SI (match_dup 1)
6592 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6595 /* Set up operands from compare. */
6596 operands[1] = branch_cmp[0];
6597 operands[2] = branch_cmp[1];
6599 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6601 gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
6605 /* Fall through and generate default code. */
6608 (define_insn "sge_si"
6609 [(set (match_operand:SI 0 "register_operand" "=d")
6610 (ge:SI (match_operand:SI 1 "register_operand" "d")
6611 (match_operand:SI 2 "arith_operand" "dI")))]
6612 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6613 "slt\t%0,%1,%2\;xori\t%0,%0,0x0001"
6614 [(set_attr "type" "multi")
6615 (set_attr "mode" "SI")
6616 (set_attr "length" "8")])
6619 [(set (match_operand:SI 0 "register_operand")
6620 (ge:SI (match_operand:SI 1 "register_operand")
6621 (match_operand:SI 2 "arith_operand")))]
6622 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
6624 (lt:SI (match_dup 1)
6627 (xor:SI (match_dup 0)
6631 (define_insn "sge_di"
6632 [(set (match_operand:DI 0 "register_operand" "=d")
6633 (ge:DI (match_operand:DI 1 "register_operand" "d")
6634 (match_operand:DI 2 "arith_operand" "dI")))]
6635 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6636 "slt\t%0,%1,%2\;xori\t%0,%0,0x0001"
6637 [(set_attr "type" "multi")
6638 (set_attr "mode" "DI")
6639 (set_attr "length" "8")])
6642 [(set (match_operand:DI 0 "register_operand")
6643 (ge:DI (match_operand:DI 1 "register_operand")
6644 (match_operand:DI 2 "arith_operand")))]
6645 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
6648 (lt:DI (match_dup 1)
6651 (xor:DI (match_dup 0)
6655 (define_expand "slt"
6656 [(set (match_operand:SI 0 "register_operand")
6657 (lt:SI (match_dup 1)
6661 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6664 /* Set up operands from compare. */
6665 operands[1] = branch_cmp[0];
6666 operands[2] = branch_cmp[1];
6668 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6670 gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
6674 /* Fall through and generate default code. */
6677 (define_insn "slt_si"
6678 [(set (match_operand:SI 0 "register_operand" "=d")
6679 (lt:SI (match_operand:SI 1 "register_operand" "d")
6680 (match_operand:SI 2 "arith_operand" "dI")))]
6683 [(set_attr "type" "slt")
6684 (set_attr "mode" "SI")])
6687 [(set (match_operand:SI 0 "register_operand" "=t,t")
6688 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
6689 (match_operand:SI 2 "arith_operand" "d,I")))]
6692 [(set_attr "type" "slt")
6693 (set_attr "mode" "SI")
6694 (set_attr_alternative "length"
6696 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6700 (define_insn "slt_di"
6701 [(set (match_operand:DI 0 "register_operand" "=d")
6702 (lt:DI (match_operand:DI 1 "register_operand" "d")
6703 (match_operand:DI 2 "arith_operand" "dI")))]
6704 "TARGET_64BIT && !TARGET_MIPS16"
6706 [(set_attr "type" "slt")
6707 (set_attr "mode" "DI")])
6710 [(set (match_operand:DI 0 "register_operand" "=t,t")
6711 (lt:DI (match_operand:DI 1 "register_operand" "d,d")
6712 (match_operand:DI 2 "arith_operand" "d,I")))]
6713 "TARGET_64BIT && TARGET_MIPS16"
6715 [(set_attr "type" "slt")
6716 (set_attr "mode" "DI")
6717 (set_attr_alternative "length"
6719 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6723 (define_expand "sle"
6724 [(set (match_operand:SI 0 "register_operand")
6725 (le:SI (match_dup 1)
6729 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6732 /* Set up operands from compare. */
6733 operands[1] = branch_cmp[0];
6734 operands[2] = branch_cmp[1];
6736 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6738 gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
6742 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
6743 operands[2] = force_reg (SImode, operands[2]);
6745 /* Fall through and generate default code. */
6748 (define_insn "sle_si_const"
6749 [(set (match_operand:SI 0 "register_operand" "=d")
6750 (le:SI (match_operand:SI 1 "register_operand" "d")
6751 (match_operand:SI 2 "small_int" "I")))]
6752 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6754 operands[2] = GEN_INT (INTVAL (operands[2])+1);
6755 return "slt\t%0,%1,%2";
6757 [(set_attr "type" "slt")
6758 (set_attr "mode" "SI")])
6761 [(set (match_operand:SI 0 "register_operand" "=t")
6762 (le:SI (match_operand:SI 1 "register_operand" "d")
6763 (match_operand:SI 2 "small_int" "I")))]
6764 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6766 operands[2] = GEN_INT (INTVAL (operands[2])+1);
6767 return "slt\t%1,%2";
6769 [(set_attr "type" "slt")
6770 (set_attr "mode" "SI")
6771 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6775 (define_insn "sle_di_const"
6776 [(set (match_operand:DI 0 "register_operand" "=d")
6777 (le:DI (match_operand:DI 1 "register_operand" "d")
6778 (match_operand:DI 2 "small_int" "I")))]
6779 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6781 operands[2] = GEN_INT (INTVAL (operands[2])+1);
6782 return "slt\t%0,%1,%2";
6784 [(set_attr "type" "slt")
6785 (set_attr "mode" "DI")])
6788 [(set (match_operand:DI 0 "register_operand" "=t")
6789 (le:DI (match_operand:DI 1 "register_operand" "d")
6790 (match_operand:DI 2 "small_int" "I")))]
6791 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6793 operands[2] = GEN_INT (INTVAL (operands[2])+1);
6794 return "slt\t%1,%2";
6796 [(set_attr "type" "slt")
6797 (set_attr "mode" "DI")
6798 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6802 (define_insn "sle_si_reg"
6803 [(set (match_operand:SI 0 "register_operand" "=d")
6804 (le:SI (match_operand:SI 1 "register_operand" "d")
6805 (match_operand:SI 2 "register_operand" "d")))]
6806 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6807 "slt\t%0,%z2,%1\;xori\t%0,%0,0x0001"
6808 [(set_attr "type" "multi")
6809 (set_attr "mode" "SI")
6810 (set_attr "length" "8")])
6813 [(set (match_operand:SI 0 "register_operand")
6814 (le:SI (match_operand:SI 1 "register_operand")
6815 (match_operand:SI 2 "register_operand")))]
6816 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
6818 (lt:SI (match_dup 2)
6821 (xor:SI (match_dup 0)
6825 (define_insn "sle_di_reg"
6826 [(set (match_operand:DI 0 "register_operand" "=d")
6827 (le:DI (match_operand:DI 1 "register_operand" "d")
6828 (match_operand:DI 2 "register_operand" "d")))]
6829 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6830 "slt\t%0,%z2,%1\;xori\t%0,%0,0x0001"
6831 [(set_attr "type" "multi")
6832 (set_attr "mode" "DI")
6833 (set_attr "length" "8")])
6836 [(set (match_operand:DI 0 "register_operand")
6837 (le:DI (match_operand:DI 1 "register_operand")
6838 (match_operand:DI 2 "register_operand")))]
6839 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
6842 (lt:DI (match_dup 2)
6845 (xor:DI (match_dup 0)
6849 (define_expand "sgtu"
6850 [(set (match_operand:SI 0 "register_operand")
6851 (gtu:SI (match_dup 1)
6855 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6858 /* Set up operands from compare. */
6859 operands[1] = branch_cmp[0];
6860 operands[2] = branch_cmp[1];
6862 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6864 gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
6868 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
6869 operands[2] = force_reg (SImode, operands[2]);
6871 /* Fall through and generate default code. */
6874 (define_insn "sgtu_si"
6875 [(set (match_operand:SI 0 "register_operand" "=d")
6876 (gtu:SI (match_operand:SI 1 "register_operand" "d")
6877 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6880 [(set_attr "type" "slt")
6881 (set_attr "mode" "SI")])
6884 [(set (match_operand:SI 0 "register_operand" "=t")
6885 (gtu:SI (match_operand:SI 1 "register_operand" "d")
6886 (match_operand:SI 2 "register_operand" "d")))]
6889 [(set_attr "type" "slt")
6890 (set_attr "mode" "SI")])
6892 (define_insn "sgtu_di"
6893 [(set (match_operand:DI 0 "register_operand" "=d")
6894 (gtu:DI (match_operand:DI 1 "register_operand" "d")
6895 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6896 "TARGET_64BIT && !TARGET_MIPS16"
6898 [(set_attr "type" "slt")
6899 (set_attr "mode" "DI")])
6902 [(set (match_operand:DI 0 "register_operand" "=t")
6903 (gtu:DI (match_operand:DI 1 "register_operand" "d")
6904 (match_operand:DI 2 "register_operand" "d")))]
6905 "TARGET_64BIT && TARGET_MIPS16"
6907 [(set_attr "type" "slt")
6908 (set_attr "mode" "DI")])
6910 (define_expand "sgeu"
6911 [(set (match_operand:SI 0 "register_operand")
6912 (geu:SI (match_dup 1)
6916 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6919 /* Set up operands from compare. */
6920 operands[1] = branch_cmp[0];
6921 operands[2] = branch_cmp[1];
6923 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6925 gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
6929 /* Fall through and generate default code. */
6932 (define_insn "sgeu_si"
6933 [(set (match_operand:SI 0 "register_operand" "=d")
6934 (geu:SI (match_operand:SI 1 "register_operand" "d")
6935 (match_operand:SI 2 "arith_operand" "dI")))]
6936 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6937 "sltu\t%0,%1,%2\;xori\t%0,%0,0x0001"
6938 [(set_attr "type" "multi")
6939 (set_attr "mode" "SI")
6940 (set_attr "length" "8")])
6943 [(set (match_operand:SI 0 "register_operand")
6944 (geu:SI (match_operand:SI 1 "register_operand")
6945 (match_operand:SI 2 "arith_operand")))]
6946 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
6948 (ltu:SI (match_dup 1)
6951 (xor:SI (match_dup 0)
6955 (define_insn "sgeu_di"
6956 [(set (match_operand:DI 0 "register_operand" "=d")
6957 (geu:DI (match_operand:DI 1 "register_operand" "d")
6958 (match_operand:DI 2 "arith_operand" "dI")))]
6959 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6960 "sltu\t%0,%1,%2\;xori\t%0,%0,0x0001"
6961 [(set_attr "type" "multi")
6962 (set_attr "mode" "DI")
6963 (set_attr "length" "8")])
6966 [(set (match_operand:DI 0 "register_operand")
6967 (geu:DI (match_operand:DI 1 "register_operand")
6968 (match_operand:DI 2 "arith_operand")))]
6969 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
6972 (ltu:DI (match_dup 1)
6975 (xor:DI (match_dup 0)
6979 (define_expand "sltu"
6980 [(set (match_operand:SI 0 "register_operand")
6981 (ltu:SI (match_dup 1)
6985 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6988 /* Set up operands from compare. */
6989 operands[1] = branch_cmp[0];
6990 operands[2] = branch_cmp[1];
6992 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6994 gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
6998 /* Fall through and generate default code. */
7001 (define_insn "sltu_si"
7002 [(set (match_operand:SI 0 "register_operand" "=d")
7003 (ltu:SI (match_operand:SI 1 "register_operand" "d")
7004 (match_operand:SI 2 "arith_operand" "dI")))]
7007 [(set_attr "type" "slt")
7008 (set_attr "mode" "SI")])
7011 [(set (match_operand:SI 0 "register_operand" "=t,t")
7012 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
7013 (match_operand:SI 2 "arith_operand" "d,I")))]
7016 [(set_attr "type" "slt")
7017 (set_attr "mode" "SI")
7018 (set_attr_alternative "length"
7020 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
7024 (define_insn "sltu_di"
7025 [(set (match_operand:DI 0 "register_operand" "=d")
7026 (ltu:DI (match_operand:DI 1 "register_operand" "d")
7027 (match_operand:DI 2 "arith_operand" "dI")))]
7028 "TARGET_64BIT && !TARGET_MIPS16"
7030 [(set_attr "type" "slt")
7031 (set_attr "mode" "DI")])
7034 [(set (match_operand:DI 0 "register_operand" "=t,t")
7035 (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
7036 (match_operand:DI 2 "arith_operand" "d,I")))]
7037 "TARGET_64BIT && TARGET_MIPS16"
7039 [(set_attr "type" "slt")
7040 (set_attr "mode" "DI")
7041 (set_attr_alternative "length"
7043 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
7047 (define_expand "sleu"
7048 [(set (match_operand:SI 0 "register_operand")
7049 (leu:SI (match_dup 1)
7053 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7056 /* Set up operands from compare. */
7057 operands[1] = branch_cmp[0];
7058 operands[2] = branch_cmp[1];
7060 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7062 gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
7066 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
7067 operands[2] = force_reg (SImode, operands[2]);
7069 /* Fall through and generate default code. */
7072 (define_insn "sleu_si_const"
7073 [(set (match_operand:SI 0 "register_operand" "=d")
7074 (leu:SI (match_operand:SI 1 "register_operand" "d")
7075 (match_operand:SI 2 "small_int" "I")))]
7076 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7078 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
7079 return "sltu\t%0,%1,%2";
7081 [(set_attr "type" "slt")
7082 (set_attr "mode" "SI")])
7085 [(set (match_operand:SI 0 "register_operand" "=t")
7086 (leu:SI (match_operand:SI 1 "register_operand" "d")
7087 (match_operand:SI 2 "small_int" "I")))]
7088 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7090 operands[2] = GEN_INT (INTVAL (operands[2])+1);
7091 return "sltu\t%1,%2";
7093 [(set_attr "type" "slt")
7094 (set_attr "mode" "SI")
7095 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
7099 (define_insn "sleu_di_const"
7100 [(set (match_operand:DI 0 "register_operand" "=d")
7101 (leu:DI (match_operand:DI 1 "register_operand" "d")
7102 (match_operand:DI 2 "small_int" "I")))]
7103 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7105 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
7106 return "sltu\t%0,%1,%2";
7108 [(set_attr "type" "slt")
7109 (set_attr "mode" "DI")])
7112 [(set (match_operand:DI 0 "register_operand" "=t")
7113 (leu:DI (match_operand:DI 1 "register_operand" "d")
7114 (match_operand:DI 2 "small_int" "I")))]
7115 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7117 operands[2] = GEN_INT (INTVAL (operands[2])+1);
7118 return "sltu\t%1,%2";
7120 [(set_attr "type" "slt")
7121 (set_attr "mode" "DI")
7122 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
7126 (define_insn "sleu_si_reg"
7127 [(set (match_operand:SI 0 "register_operand" "=d")
7128 (leu:SI (match_operand:SI 1 "register_operand" "d")
7129 (match_operand:SI 2 "register_operand" "d")))]
7130 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7131 "sltu\t%0,%z2,%1\;xori\t%0,%0,0x0001"
7132 [(set_attr "type" "multi")
7133 (set_attr "mode" "SI")
7134 (set_attr "length" "8")])
7137 [(set (match_operand:SI 0 "register_operand")
7138 (leu:SI (match_operand:SI 1 "register_operand")
7139 (match_operand:SI 2 "register_operand")))]
7140 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7142 (ltu:SI (match_dup 2)
7145 (xor:SI (match_dup 0)
7149 (define_insn "sleu_di_reg"
7150 [(set (match_operand:DI 0 "register_operand" "=d")
7151 (leu:DI (match_operand:DI 1 "register_operand" "d")
7152 (match_operand:DI 2 "register_operand" "d")))]
7153 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7154 "sltu\t%0,%z2,%1\;xori\t%0,%0,0x0001"
7155 [(set_attr "type" "multi")
7156 (set_attr "mode" "DI")
7157 (set_attr "length" "8")])
7160 [(set (match_operand:DI 0 "register_operand")
7161 (leu:DI (match_operand:DI 1 "register_operand")
7162 (match_operand:DI 2 "register_operand")))]
7163 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7166 (ltu:DI (match_dup 2)
7169 (xor:DI (match_dup 0)
7174 ;; ....................
7176 ;; FLOATING POINT COMPARISONS
7178 ;; ....................
7180 (define_insn "sunordered_df"
7181 [(set (match_operand:CC 0 "register_operand" "=z")
7182 (unordered:CC (match_operand:DF 1 "register_operand" "f")
7183 (match_operand:DF 2 "register_operand" "f")))]
7184 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7186 [(set_attr "type" "fcmp")
7187 (set_attr "mode" "FPSW")])
7189 (define_insn "sunlt_df"
7190 [(set (match_operand:CC 0 "register_operand" "=z")
7191 (unlt:CC (match_operand:DF 1 "register_operand" "f")
7192 (match_operand:DF 2 "register_operand" "f")))]
7193 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7195 [(set_attr "type" "fcmp")
7196 (set_attr "mode" "FPSW")])
7198 (define_insn "suneq_df"
7199 [(set (match_operand:CC 0 "register_operand" "=z")
7200 (uneq:CC (match_operand:DF 1 "register_operand" "f")
7201 (match_operand:DF 2 "register_operand" "f")))]
7202 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7204 [(set_attr "type" "fcmp")
7205 (set_attr "mode" "FPSW")])
7207 (define_insn "sunle_df"
7208 [(set (match_operand:CC 0 "register_operand" "=z")
7209 (unle:CC (match_operand:DF 1 "register_operand" "f")
7210 (match_operand:DF 2 "register_operand" "f")))]
7211 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7213 [(set_attr "type" "fcmp")
7214 (set_attr "mode" "FPSW")])
7216 (define_insn "seq_df"
7217 [(set (match_operand:CC 0 "register_operand" "=z")
7218 (eq:CC (match_operand:DF 1 "register_operand" "f")
7219 (match_operand:DF 2 "register_operand" "f")))]
7220 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7222 [(set_attr "type" "fcmp")
7223 (set_attr "mode" "FPSW")])
7225 (define_insn "slt_df"
7226 [(set (match_operand:CC 0 "register_operand" "=z")
7227 (lt:CC (match_operand:DF 1 "register_operand" "f")
7228 (match_operand:DF 2 "register_operand" "f")))]
7229 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7231 [(set_attr "type" "fcmp")
7232 (set_attr "mode" "FPSW")])
7234 (define_insn "sle_df"
7235 [(set (match_operand:CC 0 "register_operand" "=z")
7236 (le:CC (match_operand:DF 1 "register_operand" "f")
7237 (match_operand:DF 2 "register_operand" "f")))]
7238 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7240 [(set_attr "type" "fcmp")
7241 (set_attr "mode" "FPSW")])
7243 (define_insn "sgt_df"
7244 [(set (match_operand:CC 0 "register_operand" "=z")
7245 (gt:CC (match_operand:DF 1 "register_operand" "f")
7246 (match_operand:DF 2 "register_operand" "f")))]
7247 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7249 [(set_attr "type" "fcmp")
7250 (set_attr "mode" "FPSW")])
7252 (define_insn "sge_df"
7253 [(set (match_operand:CC 0 "register_operand" "=z")
7254 (ge:CC (match_operand:DF 1 "register_operand" "f")
7255 (match_operand:DF 2 "register_operand" "f")))]
7256 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7258 [(set_attr "type" "fcmp")
7259 (set_attr "mode" "FPSW")])
7261 (define_insn "sunordered_sf"
7262 [(set (match_operand:CC 0 "register_operand" "=z")
7263 (unordered:CC (match_operand:SF 1 "register_operand" "f")
7264 (match_operand:SF 2 "register_operand" "f")))]
7267 [(set_attr "type" "fcmp")
7268 (set_attr "mode" "FPSW")])
7270 (define_insn "sunlt_sf"
7271 [(set (match_operand:CC 0 "register_operand" "=z")
7272 (unlt:CC (match_operand:SF 1 "register_operand" "f")
7273 (match_operand:SF 2 "register_operand" "f")))]
7276 [(set_attr "type" "fcmp")
7277 (set_attr "mode" "FPSW")])
7279 (define_insn "suneq_sf"
7280 [(set (match_operand:CC 0 "register_operand" "=z")
7281 (uneq:CC (match_operand:SF 1 "register_operand" "f")
7282 (match_operand:SF 2 "register_operand" "f")))]
7285 [(set_attr "type" "fcmp")
7286 (set_attr "mode" "FPSW")])
7288 (define_insn "sunle_sf"
7289 [(set (match_operand:CC 0 "register_operand" "=z")
7290 (unle:CC (match_operand:SF 1 "register_operand" "f")
7291 (match_operand:SF 2 "register_operand" "f")))]
7294 [(set_attr "type" "fcmp")
7295 (set_attr "mode" "FPSW")])
7297 (define_insn "seq_sf"
7298 [(set (match_operand:CC 0 "register_operand" "=z")
7299 (eq:CC (match_operand:SF 1 "register_operand" "f")
7300 (match_operand:SF 2 "register_operand" "f")))]
7303 [(set_attr "type" "fcmp")
7304 (set_attr "mode" "FPSW")])
7306 (define_insn "slt_sf"
7307 [(set (match_operand:CC 0 "register_operand" "=z")
7308 (lt:CC (match_operand:SF 1 "register_operand" "f")
7309 (match_operand:SF 2 "register_operand" "f")))]
7312 [(set_attr "type" "fcmp")
7313 (set_attr "mode" "FPSW")])
7315 (define_insn "sle_sf"
7316 [(set (match_operand:CC 0 "register_operand" "=z")
7317 (le:CC (match_operand:SF 1 "register_operand" "f")
7318 (match_operand:SF 2 "register_operand" "f")))]
7321 [(set_attr "type" "fcmp")
7322 (set_attr "mode" "FPSW")])
7324 (define_insn "sgt_sf"
7325 [(set (match_operand:CC 0 "register_operand" "=z")
7326 (gt:CC (match_operand:SF 1 "register_operand" "f")
7327 (match_operand:SF 2 "register_operand" "f")))]
7330 [(set_attr "type" "fcmp")
7331 (set_attr "mode" "FPSW")])
7333 (define_insn "sge_sf"
7334 [(set (match_operand:CC 0 "register_operand" "=z")
7335 (ge:CC (match_operand:SF 1 "register_operand" "f")
7336 (match_operand:SF 2 "register_operand" "f")))]
7339 [(set_attr "type" "fcmp")
7340 (set_attr "mode" "FPSW")])
7343 ;; ....................
7345 ;; UNCONDITIONAL BRANCHES
7347 ;; ....................
7349 ;; Unconditional branches.
7353 (label_ref (match_operand 0 "" "")))]
7358 if (get_attr_length (insn) <= 8)
7359 return "%*b\t%l0%/";
7362 output_asm_insn (mips_output_load_label (), operands);
7363 return "%*jr\t%@%/%]";
7367 return "%*j\t%l0%/";
7369 [(set_attr "type" "jump")
7370 (set_attr "mode" "none")
7371 (set (attr "length")
7372 ;; We can't use `j' when emitting PIC. Emit a branch if it's
7373 ;; in range, otherwise load the address of the branch target into
7374 ;; $at and then jump to it.
7376 (ior (eq (symbol_ref "flag_pic") (const_int 0))
7377 (lt (abs (minus (match_dup 0)
7378 (plus (pc) (const_int 4))))
7379 (const_int 131072)))
7380 (const_int 4) (const_int 16)))])
7382 ;; We need a different insn for the mips16, because a mips16 branch
7383 ;; does not have a delay slot.
7387 (label_ref (match_operand 0 "" "")))]
7390 [(set_attr "type" "branch")
7391 (set_attr "mode" "none")
7392 (set_attr "length" "8")])
7394 (define_expand "indirect_jump"
7395 [(set (pc) (match_operand 0 "register_operand"))]
7401 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
7402 operands[0] = copy_to_mode_reg (Pmode, dest);
7404 if (!(Pmode == DImode))
7405 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
7407 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
7412 (define_insn "indirect_jump_internal1"
7413 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
7414 "!(Pmode == DImode)"
7416 [(set_attr "type" "jump")
7417 (set_attr "mode" "none")])
7419 (define_insn "indirect_jump_internal2"
7420 [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
7423 [(set_attr "type" "jump")
7424 (set_attr "mode" "none")])
7426 (define_expand "tablejump"
7428 (match_operand 0 "register_operand"))
7429 (use (label_ref (match_operand 1 "")))]
7434 if (GET_MODE (operands[0]) != HImode)
7436 if (!(Pmode == DImode))
7437 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
7439 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
7443 if (GET_MODE (operands[0]) != ptr_mode)
7447 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
7448 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
7450 if (Pmode == SImode)
7451 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
7453 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
7457 (define_insn "tablejump_internal1"
7459 (match_operand:SI 0 "register_operand" "d"))
7460 (use (label_ref (match_operand 1 "" "")))]
7463 [(set_attr "type" "jump")
7464 (set_attr "mode" "none")])
7466 (define_insn "tablejump_internal2"
7468 (match_operand:DI 0 "register_operand" "d"))
7469 (use (label_ref (match_operand 1 "" "")))]
7472 [(set_attr "type" "jump")
7473 (set_attr "mode" "none")])
7475 (define_expand "tablejump_mips161"
7476 [(set (pc) (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand"))
7477 (label_ref:SI (match_operand 1 ""))))]
7478 "TARGET_MIPS16 && !(Pmode == DImode)"
7482 t1 = gen_reg_rtx (SImode);
7483 t2 = gen_reg_rtx (SImode);
7484 t3 = gen_reg_rtx (SImode);
7485 emit_insn (gen_extendhisi2 (t1, operands[0]));
7486 emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
7487 emit_insn (gen_addsi3 (t3, t1, t2));
7488 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
7492 (define_expand "tablejump_mips162"
7493 [(set (pc) (plus:DI (sign_extend:DI (match_operand:HI 0 "register_operand"))
7494 (label_ref:DI (match_operand 1 ""))))]
7495 "TARGET_MIPS16 && Pmode == DImode"
7499 t1 = gen_reg_rtx (DImode);
7500 t2 = gen_reg_rtx (DImode);
7501 t3 = gen_reg_rtx (DImode);
7502 emit_insn (gen_extendhidi2 (t1, operands[0]));
7503 emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
7504 emit_insn (gen_adddi3 (t3, t1, t2));
7505 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
7509 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
7510 ;; While it is possible to either pull it off the stack (in the
7511 ;; o32 case) or recalculate it given t9 and our target label,
7512 ;; it takes 3 or 4 insns to do so.
7514 (define_expand "builtin_setjmp_setup"
7515 [(use (match_operand 0 "register_operand"))]
7520 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
7521 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
7525 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
7526 ;; that older code did recalculate the gp from $25. Continue to jump through
7527 ;; $25 for compatibility (we lose nothing by doing so).
7529 (define_expand "builtin_longjmp"
7530 [(use (match_operand 0 "register_operand"))]
7533 /* The elements of the buffer are, in order: */
7534 int W = GET_MODE_SIZE (Pmode);
7535 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
7536 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
7537 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
7538 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
7539 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
7540 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
7541 The target is bound to be using $28 as the global pointer
7542 but the current function might not be. */
7543 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
7545 /* This bit is similar to expand_builtin_longjmp except that it
7546 restores $gp as well. */
7547 emit_move_insn (hard_frame_pointer_rtx, fp);
7548 emit_move_insn (pv, lab);
7549 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
7550 emit_move_insn (gp, gpv);
7551 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
7552 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7553 emit_insn (gen_rtx_USE (VOIDmode, gp));
7554 emit_indirect_jump (pv);
7559 ;; ....................
7561 ;; Function prologue/epilogue
7563 ;; ....................
7566 (define_expand "prologue"
7570 mips_expand_prologue ();
7574 ;; Block any insns from being moved before this point, since the
7575 ;; profiling call to mcount can use various registers that aren't
7576 ;; saved or used to pass arguments.
7578 (define_insn "blockage"
7579 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
7582 [(set_attr "type" "unknown")
7583 (set_attr "mode" "none")
7584 (set_attr "length" "0")])
7586 (define_expand "epilogue"
7590 mips_expand_epilogue (false);
7594 (define_expand "sibcall_epilogue"
7598 mips_expand_epilogue (true);
7602 ;; Trivial return. Make it look like a normal return insn as that
7603 ;; allows jump optimizations to work better.
7605 (define_insn "return"
7607 "mips_can_use_return_insn ()"
7609 [(set_attr "type" "jump")
7610 (set_attr "mode" "none")])
7614 (define_insn "return_internal"
7616 (use (match_operand 0 "pmode_register_operand" ""))]
7619 [(set_attr "type" "jump")
7620 (set_attr "mode" "none")])
7622 ;; This is used in compiling the unwind routines.
7623 (define_expand "eh_return"
7624 [(use (match_operand 0 "general_operand"))]
7627 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
7629 if (GET_MODE (operands[0]) != gpr_mode)
7630 operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
7632 emit_insn (gen_eh_set_lr_di (operands[0]));
7634 emit_insn (gen_eh_set_lr_si (operands[0]));
7639 ;; Clobber the return address on the stack. We can't expand this
7640 ;; until we know where it will be put in the stack frame.
7642 (define_insn "eh_set_lr_si"
7643 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
7644 (clobber (match_scratch:SI 1 "=&d"))]
7648 (define_insn "eh_set_lr_di"
7649 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
7650 (clobber (match_scratch:DI 1 "=&d"))]
7655 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
7656 (clobber (match_scratch 1))]
7657 "reload_completed && !TARGET_DEBUG_D_MODE"
7660 mips_set_return_address (operands[0], operands[1]);
7664 (define_insn "exception_receiver"
7666 (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
7667 "TARGET_ABICALLS && TARGET_OLDABI"
7669 operands[0] = pic_offset_table_rtx;
7670 operands[1] = mips_gp_save_slot ();
7671 return mips_output_move (operands[0], operands[1]);
7673 [(set_attr "type" "load")
7674 (set_attr "length" "8")])
7677 ;; ....................
7681 ;; ....................
7683 ;; Instructions to load a call address from the GOT. The address might
7684 ;; point to a function or to a lazy binding stub. In the latter case,
7685 ;; the stub will use the dynamic linker to resolve the function, which
7686 ;; in turn will change the GOT entry to point to the function's real
7689 ;; This means that every call, even pure and constant ones, can
7690 ;; potentially modify the GOT entry. And once a stub has been called,
7691 ;; we must not call it again.
7693 ;; We represent this restriction using an imaginary fixed register that
7694 ;; acts like a GOT version number. By making the register call-clobbered,
7695 ;; we tell the target-independent code that the address could be changed
7696 ;; by any call insn.
7697 (define_insn "load_callsi"
7698 [(set (match_operand:SI 0 "register_operand" "=c")
7699 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7700 (match_operand:SI 2 "immediate_operand" "")
7701 (reg:SI FAKE_CALL_REGNO)]
7705 [(set_attr "type" "load")
7706 (set_attr "length" "4")])
7708 (define_insn "load_calldi"
7709 [(set (match_operand:DI 0 "register_operand" "=c")
7710 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7711 (match_operand:DI 2 "immediate_operand" "")
7712 (reg:DI FAKE_CALL_REGNO)]
7716 [(set_attr "type" "load")
7717 (set_attr "length" "4")])
7719 ;; Sibling calls. All these patterns use jump instructions.
7721 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
7722 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
7723 ;; is defined in terms of call_insn_operand, the same is true of the
7726 ;; When we use an indirect jump, we need a register that will be
7727 ;; preserved by the epilogue. Since TARGET_ABICALLS forces us to
7728 ;; use $25 for this purpose -- and $25 is never clobbered by the
7729 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
7731 (define_expand "sibcall"
7732 [(parallel [(call (match_operand 0 "")
7733 (match_operand 1 ""))
7734 (use (match_operand 2 "")) ;; next_arg_reg
7735 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
7738 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
7742 (define_insn "sibcall_internal"
7743 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
7744 (match_operand 1 "" ""))]
7745 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7749 [(set_attr "type" "call")])
7751 (define_expand "sibcall_value"
7752 [(parallel [(set (match_operand 0 "")
7753 (call (match_operand 1 "")
7754 (match_operand 2 "")))
7755 (use (match_operand 3 ""))])] ;; next_arg_reg
7758 mips_expand_call (operands[0], XEXP (operands[1], 0),
7759 operands[2], operands[3], true);
7763 (define_insn "sibcall_value_internal"
7764 [(set (match_operand 0 "register_operand" "=df,df")
7765 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
7766 (match_operand 2 "" "")))]
7767 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7771 [(set_attr "type" "call")])
7773 (define_insn "sibcall_value_multiple_internal"
7774 [(set (match_operand 0 "register_operand" "=df,df")
7775 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
7776 (match_operand 2 "" "")))
7777 (set (match_operand 3 "register_operand" "=df,df")
7778 (call (mem:SI (match_dup 1))
7780 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7784 [(set_attr "type" "call")])
7786 (define_expand "call"
7787 [(parallel [(call (match_operand 0 "")
7788 (match_operand 1 ""))
7789 (use (match_operand 2 "")) ;; next_arg_reg
7790 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
7793 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
7797 ;; This instruction directly corresponds to an assembly-language "jal".
7798 ;; There are four cases:
7801 ;; Both symbolic and register destinations are OK. The pattern
7802 ;; always expands to a single mips instruction.
7804 ;; - -mabicalls/-mno-explicit-relocs:
7805 ;; Again, both symbolic and register destinations are OK.
7806 ;; The call is treated as a multi-instruction black box.
7808 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
7809 ;; Only "jal $25" is allowed. This expands to a single "jalr $25"
7812 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
7813 ;; Only "jal $25" is allowed. The call is actually two instructions:
7814 ;; "jalr $25" followed by an insn to reload $gp.
7816 ;; In the last case, we can generate the individual instructions with
7817 ;; a define_split. There are several things to be wary of:
7819 ;; - We can't expose the load of $gp before reload. If we did,
7820 ;; it might get removed as dead, but reload can introduce new
7821 ;; uses of $gp by rematerializing constants.
7823 ;; - We shouldn't restore $gp after calls that never return.
7824 ;; It isn't valid to insert instructions between a noreturn
7825 ;; call and the following barrier.
7827 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
7828 ;; instruction preserves $gp and so have no effect on its liveness.
7829 ;; But once we generate the separate insns, it becomes obvious that
7830 ;; $gp is not live on entry to the call.
7832 ;; ??? The operands[2] = insn check is a hack to make the original insn
7833 ;; available to the splitter.
7834 (define_insn_and_split "call_internal"
7835 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
7836 (match_operand 1 "" ""))
7837 (clobber (reg:SI 31))]
7839 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
7840 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
7843 emit_call_insn (gen_call_split (operands[0], operands[1]));
7844 if (!find_reg_note (operands[2], REG_NORETURN, 0))
7845 emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
7848 [(set_attr "jal" "indirect,direct")
7849 (set_attr "extended_mips16" "no,yes")])
7851 (define_insn "call_split"
7852 [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
7853 (match_operand 1 "" ""))
7854 (clobber (reg:SI 31))
7855 (clobber (reg:SI 28))]
7856 "TARGET_SPLIT_CALLS"
7858 [(set_attr "type" "call")])
7860 (define_expand "call_value"
7861 [(parallel [(set (match_operand 0 "")
7862 (call (match_operand 1 "")
7863 (match_operand 2 "")))
7864 (use (match_operand 3 ""))])] ;; next_arg_reg
7867 mips_expand_call (operands[0], XEXP (operands[1], 0),
7868 operands[2], operands[3], false);
7872 ;; See comment for call_internal.
7873 (define_insn_and_split "call_value_internal"
7874 [(set (match_operand 0 "register_operand" "=df,df")
7875 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7876 (match_operand 2 "" "")))
7877 (clobber (reg:SI 31))]
7879 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7880 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
7883 emit_call_insn (gen_call_value_split (operands[0], operands[1],
7885 if (!find_reg_note (operands[3], REG_NORETURN, 0))
7886 emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
7889 [(set_attr "jal" "indirect,direct")
7890 (set_attr "extended_mips16" "no,yes")])
7892 (define_insn "call_value_split"
7893 [(set (match_operand 0 "register_operand" "=df")
7894 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7895 (match_operand 2 "" "")))
7896 (clobber (reg:SI 31))
7897 (clobber (reg:SI 28))]
7898 "TARGET_SPLIT_CALLS"
7900 [(set_attr "type" "call")])
7902 ;; See comment for call_internal.
7903 (define_insn_and_split "call_value_multiple_internal"
7904 [(set (match_operand 0 "register_operand" "=df,df")
7905 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7906 (match_operand 2 "" "")))
7907 (set (match_operand 3 "register_operand" "=df,df")
7908 (call (mem:SI (match_dup 1))
7910 (clobber (reg:SI 31))]
7912 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7913 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
7916 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
7917 operands[2], operands[3]));
7918 if (!find_reg_note (operands[4], REG_NORETURN, 0))
7919 emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
7922 [(set_attr "jal" "indirect,direct")
7923 (set_attr "extended_mips16" "no,yes")])
7925 (define_insn "call_value_multiple_split"
7926 [(set (match_operand 0 "register_operand" "=df")
7927 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7928 (match_operand 2 "" "")))
7929 (set (match_operand 3 "register_operand" "=df")
7930 (call (mem:SI (match_dup 1))
7932 (clobber (reg:SI 31))
7933 (clobber (reg:SI 28))]
7934 "TARGET_SPLIT_CALLS"
7936 [(set_attr "type" "call")])
7938 ;; Call subroutine returning any type.
7940 (define_expand "untyped_call"
7941 [(parallel [(call (match_operand 0 "")
7943 (match_operand 1 "")
7944 (match_operand 2 "")])]
7949 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
7951 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7953 rtx set = XVECEXP (operands[2], 0, i);
7954 emit_move_insn (SET_DEST (set), SET_SRC (set));
7957 emit_insn (gen_blockage ());
7962 ;; ....................
7966 ;; ....................
7970 (define_expand "prefetch"
7971 [(prefetch (match_operand 0 "address_operand")
7972 (match_operand 1 "const_int_operand")
7973 (match_operand 2 "const_int_operand"))]
7976 if (symbolic_operand (operands[0], GET_MODE (operands[0])))
7977 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
7980 (define_insn "prefetch_si_address"
7981 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7982 (match_operand:SI 3 "const_int_operand" "I"))
7983 (match_operand:SI 1 "const_int_operand" "n")
7984 (match_operand:SI 2 "const_int_operand" "n"))]
7985 "ISA_HAS_PREFETCH && Pmode == SImode"
7986 { return mips_emit_prefetch (operands); }
7987 [(set_attr "type" "prefetch")])
7989 (define_insn "prefetch_indexed_si"
7990 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7991 (match_operand:SI 3 "register_operand" "r"))
7992 (match_operand:SI 1 "const_int_operand" "n")
7993 (match_operand:SI 2 "const_int_operand" "n"))]
7994 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
7995 { return mips_emit_prefetch (operands); }
7996 [(set_attr "type" "prefetchx")])
7998 (define_insn "prefetch_si"
7999 [(prefetch (match_operand:SI 0 "register_operand" "r")
8000 (match_operand:SI 1 "const_int_operand" "n")
8001 (match_operand:SI 2 "const_int_operand" "n"))]
8002 "ISA_HAS_PREFETCH && Pmode == SImode"
8004 operands[3] = const0_rtx;
8005 return mips_emit_prefetch (operands);
8007 [(set_attr "type" "prefetch")])
8009 (define_insn "prefetch_di_address"
8010 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
8011 (match_operand:DI 3 "const_int_operand" "I"))
8012 (match_operand:DI 1 "const_int_operand" "n")
8013 (match_operand:DI 2 "const_int_operand" "n"))]
8014 "ISA_HAS_PREFETCH && Pmode == DImode"
8015 { return mips_emit_prefetch (operands); }
8016 [(set_attr "type" "prefetch")])
8018 (define_insn "prefetch_indexed_di"
8019 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
8020 (match_operand:DI 3 "register_operand" "r"))
8021 (match_operand:DI 1 "const_int_operand" "n")
8022 (match_operand:DI 2 "const_int_operand" "n"))]
8023 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
8024 { return mips_emit_prefetch (operands); }
8025 [(set_attr "type" "prefetchx")])
8027 (define_insn "prefetch_di"
8028 [(prefetch (match_operand:DI 0 "register_operand" "r")
8029 (match_operand:DI 1 "const_int_operand" "n")
8030 (match_operand:DI 2 "const_int_operand" "n"))]
8031 "ISA_HAS_PREFETCH && Pmode == DImode"
8033 operands[3] = const0_rtx;
8034 return mips_emit_prefetch (operands);
8036 [(set_attr "type" "prefetch")])
8042 [(set_attr "type" "nop")
8043 (set_attr "mode" "none")])
8045 ;; Like nop, but commented out when outside a .set noreorder block.
8046 (define_insn "hazard_nop"
8055 [(set_attr "type" "nop")])
8057 ;; MIPS4 Conditional move instructions.
8060 [(set (match_operand:SI 0 "register_operand" "=d,d")
8062 (match_operator 4 "equality_op"
8063 [(match_operand:SI 1 "register_operand" "d,d")
8065 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
8066 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
8067 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
8071 [(set_attr "type" "condmove")
8072 (set_attr "mode" "SI")])
8075 [(set (match_operand:SI 0 "register_operand" "=d,d")
8077 (match_operator 4 "equality_op"
8078 [(match_operand:DI 1 "register_operand" "d,d")
8080 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
8081 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
8082 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
8086 [(set_attr "type" "condmove")
8087 (set_attr "mode" "SI")])
8090 [(set (match_operand:SI 0 "register_operand" "=d,d")
8092 (match_operator 3 "equality_op" [(match_operand:CC 4
8096 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
8097 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
8098 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8102 [(set_attr "type" "condmove")
8103 (set_attr "mode" "SI")])
8106 [(set (match_operand:DI 0 "register_operand" "=d,d")
8108 (match_operator 4 "equality_op"
8109 [(match_operand:SI 1 "register_operand" "d,d")
8111 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
8112 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
8113 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
8117 [(set_attr "type" "condmove")
8118 (set_attr "mode" "DI")])
8121 [(set (match_operand:DI 0 "register_operand" "=d,d")
8123 (match_operator 4 "equality_op"
8124 [(match_operand:DI 1 "register_operand" "d,d")
8126 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
8127 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
8128 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
8132 [(set_attr "type" "condmove")
8133 (set_attr "mode" "DI")])
8136 [(set (match_operand:DI 0 "register_operand" "=d,d")
8138 (match_operator 3 "equality_op" [(match_operand:CC 4
8142 (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
8143 (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
8144 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
8148 [(set_attr "type" "condmove")
8149 (set_attr "mode" "DI")])
8152 [(set (match_operand:SF 0 "register_operand" "=f,f")
8154 (match_operator 4 "equality_op"
8155 [(match_operand:SI 1 "register_operand" "d,d")
8157 (match_operand:SF 2 "register_operand" "f,0")
8158 (match_operand:SF 3 "register_operand" "0,f")))]
8159 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8163 [(set_attr "type" "condmove")
8164 (set_attr "mode" "SF")])
8167 [(set (match_operand:SF 0 "register_operand" "=f,f")
8169 (match_operator 4 "equality_op"
8170 [(match_operand:DI 1 "register_operand" "d,d")
8172 (match_operand:SF 2 "register_operand" "f,0")
8173 (match_operand:SF 3 "register_operand" "0,f")))]
8174 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8178 [(set_attr "type" "condmove")
8179 (set_attr "mode" "SF")])
8182 [(set (match_operand:SF 0 "register_operand" "=f,f")
8184 (match_operator 3 "equality_op" [(match_operand:CC 4
8188 (match_operand:SF 1 "register_operand" "f,0")
8189 (match_operand:SF 2 "register_operand" "0,f")))]
8190 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8194 [(set_attr "type" "condmove")
8195 (set_attr "mode" "SF")])
8198 [(set (match_operand:DF 0 "register_operand" "=f,f")
8200 (match_operator 4 "equality_op"
8201 [(match_operand:SI 1 "register_operand" "d,d")
8203 (match_operand:DF 2 "register_operand" "f,0")
8204 (match_operand:DF 3 "register_operand" "0,f")))]
8205 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8209 [(set_attr "type" "condmove")
8210 (set_attr "mode" "DF")])
8213 [(set (match_operand:DF 0 "register_operand" "=f,f")
8215 (match_operator 4 "equality_op"
8216 [(match_operand:DI 1 "register_operand" "d,d")
8218 (match_operand:DF 2 "register_operand" "f,0")
8219 (match_operand:DF 3 "register_operand" "0,f")))]
8220 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8224 [(set_attr "type" "condmove")
8225 (set_attr "mode" "DF")])
8228 [(set (match_operand:DF 0 "register_operand" "=f,f")
8230 (match_operator 3 "equality_op" [(match_operand:CC 4
8234 (match_operand:DF 1 "register_operand" "f,0")
8235 (match_operand:DF 2 "register_operand" "0,f")))]
8236 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8240 [(set_attr "type" "condmove")
8241 (set_attr "mode" "DF")])
8243 ;; These are the main define_expand's used to make conditional moves.
8245 (define_expand "movsicc"
8246 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
8247 (set (match_operand:SI 0 "register_operand")
8248 (if_then_else:SI (match_dup 5)
8249 (match_operand:SI 2 "reg_or_0_operand")
8250 (match_operand:SI 3 "reg_or_0_operand")))]
8251 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
8253 gen_conditional_move (operands);
8257 (define_expand "movdicc"
8258 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
8259 (set (match_operand:DI 0 "register_operand")
8260 (if_then_else:DI (match_dup 5)
8261 (match_operand:DI 2 "reg_or_0_operand")
8262 (match_operand:DI 3 "reg_or_0_operand")))]
8263 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
8265 gen_conditional_move (operands);
8269 (define_expand "movsfcc"
8270 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
8271 (set (match_operand:SF 0 "register_operand")
8272 (if_then_else:SF (match_dup 5)
8273 (match_operand:SF 2 "register_operand")
8274 (match_operand:SF 3 "register_operand")))]
8275 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8277 gen_conditional_move (operands);
8281 (define_expand "movdfcc"
8282 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
8283 (set (match_operand:DF 0 "register_operand")
8284 (if_then_else:DF (match_dup 5)
8285 (match_operand:DF 2 "register_operand")
8286 (match_operand:DF 3 "register_operand")))]
8287 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8289 gen_conditional_move (operands);
8294 ;; ....................
8296 ;; mips16 inline constant tables
8298 ;; ....................
8301 (define_insn "consttable_int"
8302 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
8303 (match_operand 1 "const_int_operand" "")]
8304 UNSPEC_CONSTTABLE_INT)]
8307 assemble_integer (operands[0], INTVAL (operands[1]),
8308 BITS_PER_UNIT * INTVAL (operands[1]), 1);
8311 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
8313 (define_insn "consttable_float"
8314 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
8315 UNSPEC_CONSTTABLE_FLOAT)]
8320 if (GET_CODE (operands[0]) != CONST_DOUBLE)
8322 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
8323 assemble_real (d, GET_MODE (operands[0]),
8324 GET_MODE_BITSIZE (GET_MODE (operands[0])));
8327 [(set (attr "length")
8328 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
8330 (define_insn "align"
8331 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
8334 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
8337 ;; ....................
8341 ;; ....................
8344 ;; On the mips16, reload will sometimes decide that a pseudo register
8345 ;; should go into $24, and then later on have to reload that register.
8346 ;; When that happens, we get a load of a general register followed by
8347 ;; a move from the general register to $24 followed by a branch.
8348 ;; These peepholes catch the common case, and fix it to just use the
8349 ;; general register for the branch.
8352 [(set (match_operand:SI 0 "register_operand" "=t")
8353 (match_operand:SI 1 "register_operand" "d"))
8355 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
8357 (match_operand 3 "pc_or_label_operand" "")
8358 (match_operand 4 "pc_or_label_operand" "")))]
8360 && GET_CODE (operands[0]) == REG
8361 && REGNO (operands[0]) == 24
8362 && dead_or_set_p (insn, operands[0])
8363 && GET_CODE (operands[1]) == REG
8364 && M16_REG_P (REGNO (operands[1]))"
8366 if (operands[3] != pc_rtx)
8367 return "b%C2z\t%1,%3";
8369 return "b%N2z\t%1,%4";
8371 [(set_attr "type" "branch")
8372 (set_attr "mode" "none")
8373 (set_attr "length" "8")])
8376 [(set (match_operand:DI 0 "register_operand" "=t")
8377 (match_operand:DI 1 "register_operand" "d"))
8379 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
8381 (match_operand 3 "pc_or_label_operand" "")
8382 (match_operand 4 "pc_or_label_operand" "")))]
8383 "TARGET_MIPS16 && TARGET_64BIT
8384 && GET_CODE (operands[0]) == REG
8385 && REGNO (operands[0]) == 24
8386 && dead_or_set_p (insn, operands[0])
8387 && GET_CODE (operands[1]) == REG
8388 && M16_REG_P (REGNO (operands[1]))"
8390 if (operands[3] != pc_rtx)
8391 return "b%C2z\t%1,%3";
8393 return "b%N2z\t%1,%4";
8395 [(set_attr "type" "branch")
8396 (set_attr "mode" "none")
8397 (set_attr "length" "8")])
8399 ;; We can also have the reverse reload: reload will spill $24 into
8400 ;; another register, and then do a branch on that register when it
8401 ;; could have just stuck with $24.
8404 [(set (match_operand:SI 0 "register_operand" "=d")
8405 (match_operand:SI 1 "register_operand" "t"))
8407 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
8409 (match_operand 3 "pc_or_label_operand" "")
8410 (match_operand 4 "pc_or_label_operand" "")))]
8412 && GET_CODE (operands[1]) == REG
8413 && REGNO (operands[1]) == 24
8414 && GET_CODE (operands[0]) == REG
8415 && M16_REG_P (REGNO (operands[0]))
8416 && dead_or_set_p (insn, operands[0])"
8418 if (operands[3] != pc_rtx)
8419 return "bt%C2z\t%3";
8421 return "bt%N2z\t%4";
8423 [(set_attr "type" "branch")
8424 (set_attr "mode" "none")
8425 (set_attr "length" "8")])
8428 [(set (match_operand:DI 0 "register_operand" "=d")
8429 (match_operand:DI 1 "register_operand" "t"))
8431 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
8433 (match_operand 3 "pc_or_label_operand" "")
8434 (match_operand 4 "pc_or_label_operand" "")))]
8435 "TARGET_MIPS16 && TARGET_64BIT
8436 && GET_CODE (operands[1]) == REG
8437 && REGNO (operands[1]) == 24
8438 && GET_CODE (operands[0]) == REG
8439 && M16_REG_P (REGNO (operands[0]))
8440 && dead_or_set_p (insn, operands[0])"
8442 if (operands[3] != pc_rtx)
8443 return "bt%C2z\t%3";
8445 return "bt%N2z\t%4";
8447 [(set_attr "type" "branch")
8448 (set_attr "mode" "none")
8449 (set_attr "length" "8")])
8452 [(match_operand 0 "small_data_pattern")]
8455 { operands[0] = mips_rewrite_small_data (operands[0]); })