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 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 GNU CC.
11 ;; GNU CC 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 ;; GNU CC 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 GNU CC; 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.
40 (UNSPEC_EH_RECEIVER 10)
42 (UNSPEC_CONSTTABLE_QI 12)
43 (UNSPEC_CONSTTABLE_HI 13)
44 (UNSPEC_CONSTTABLE_SI 14)
45 (UNSPEC_CONSTTABLE_DI 15)
46 (UNSPEC_CONSTTABLE_SF 16)
47 (UNSPEC_CONSTTABLE_DF 17)
53 ;; ....................
57 ;; ....................
59 ;; Classification of each insn.
60 ;; branch conditional branch
61 ;; jump unconditional jump
62 ;; call unconditional call
63 ;; load load instruction(s)
64 ;; store store instruction(s)
65 ;; move data movement within same register set
66 ;; xfer transfer to/from coprocessor
67 ;; hilo transfer of hi/lo registers
68 ;; arith integer arithmetic instruction
69 ;; darith double precision integer arithmetic instructions
70 ;; imul integer multiply
71 ;; idiv integer divide
72 ;; icmp integer compare
73 ;; fadd floating point add/subtract
74 ;; fmul floating point multiply
75 ;; fmadd floating point multiply-add
76 ;; fdiv floating point divide
77 ;; fabs floating point absolute value
78 ;; fneg floating point negation
79 ;; fcmp floating point compare
80 ;; fcvt floating point convert
81 ;; fsqrt floating point square root
82 ;; multi multiword sequence (or user asm statements)
86 "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,multi,nop"
87 (const_string "unknown"))
89 ;; Main data type used by the insn
90 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
92 ;; Length (in # of bytes). A conditional branch is allowed only to a
93 ;; location within a signed 18-bit offset of the delay slot. If that
94 ;; provides too smal a range, we use the `j' instruction. This
95 ;; instruction takes a 28-bit value, but that value is not an offset.
96 ;; Instead, it's bitwise-ored with the high-order four bits of the
97 ;; instruction in the delay slot, which means it cannot be used to
98 ;; cross a 256MB boundary. We could fall back back on the jr,
99 ;; instruction which allows full access to the entire address space,
100 ;; but we do not do so at present.
102 (define_attr "length" ""
103 (cond [(eq_attr "type" "branch")
104 (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
110 ;; Attribute describing the processor. This attribute must match exactly
111 ;; with the processor_type enumeration in mips.h.
113 ;; Attribute describing the processor
114 ;; (define_attr "cpu" "default,r3000,r6000,r4000"
116 ;; (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000")) (const_string "r3000")
117 ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000")) (const_string "r4000")
118 ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000")) (const_string "r6000")]
119 ;; (const_string "default"))))
121 ;; ??? Fix everything that tests this attribute.
123 "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r8000,r4kc,r5kc,r20kc"
124 (const (symbol_ref "mips_cpu_attr")))
126 ;; Does the instruction have a mandatory delay slot?
127 ;; The 3900, is (mostly) mips1, but does not have a mandatory load delay
129 (define_attr "dslot" "no,yes"
130 (if_then_else (ior (eq_attr "type" "branch,jump,call,xfer,hilo,fcmp")
131 (and (eq_attr "type" "load")
132 (and (eq (symbol_ref "mips_isa") (const_int 1))
133 (and (eq (symbol_ref "mips16") (const_int 0))
134 (eq_attr "cpu" "!r3900")))))
136 (const_string "no")))
138 ;; Can the instruction be put into a delay slot?
139 (define_attr "can_delay" "no,yes"
140 (if_then_else (and (eq_attr "dslot" "no")
141 ; ADJUST_INSN_LENGTH divides length by 2 on mips16,
142 ; so cope with it here.
143 (ior (and (eq (symbol_ref "mips16") (const_int 0))
144 (eq_attr "length" "4"))
145 (and (ne (symbol_ref "mips16") (const_int 0))
146 (eq_attr "length" "2"))))
148 (const_string "no")))
150 ;; Attribute defining whether or not we can use the branch-likely instructions
152 (define_attr "branch_likely" "no,yes"
154 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
156 (const_string "no"))))
159 ;; Describe a user's asm statement.
160 (define_asm_attributes
161 [(set_attr "type" "multi")])
163 ;; whether or not generating calls to position independent functions
164 (define_attr "abicalls" "no,yes"
165 (const (symbol_ref "mips_abicalls_attr")))
169 ;; .........................
171 ;; Delay slots, can't describe load/fcmp/xfer delay slots here
173 ;; .........................
175 (define_delay (and (eq_attr "type" "branch")
176 (eq (symbol_ref "mips16") (const_int 0)))
177 [(eq_attr "can_delay" "yes")
179 (and (eq_attr "branch_likely" "yes")
180 (and (eq_attr "dslot" "no")
181 (eq_attr "length" "4")))])
183 (define_delay (eq_attr "type" "jump")
184 [(eq_attr "can_delay" "yes")
188 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
189 [(eq_attr "can_delay" "yes")
195 ;; .........................
199 ;; .........................
201 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
202 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
204 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
206 (define_function_unit "memory" 1 0
207 (and (eq_attr "type" "load")
208 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
211 (define_function_unit "memory" 1 0
212 (and (eq_attr "type" "load")
213 (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
216 (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
218 (define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)
220 (define_function_unit "imuldiv" 1 0
221 (eq_attr "type" "hilo")
224 (define_function_unit "imuldiv" 1 0
225 (and (eq_attr "type" "imul")
226 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
229 ;; On them mips16, we want to stronly discourage a mult from appearing
230 ;; after an mflo, since that requires explicit nop instructions. We
231 ;; do this by pretending that mflo ties up the function unit for long
232 ;; enough that the scheduler will ignore load stalls and the like when
233 ;; selecting instructions to between the two instructions.
235 (define_function_unit "imuldiv" 1 0
236 (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0)))
239 (define_function_unit "imuldiv" 1 0
240 (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000,r3900"))
243 (define_function_unit "imuldiv" 1 0
244 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
247 (define_function_unit "imuldiv" 1 0
248 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4650"))
251 (define_function_unit "imuldiv" 1 0
252 (and (eq_attr "type" "imul")
253 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
256 (define_function_unit "imuldiv" 1 0
257 (and (eq_attr "type" "imul")
258 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
261 (define_function_unit "imuldiv" 1 0
262 (and (eq_attr "type" "imul")
263 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
266 (define_function_unit "imuldiv" 1 0
267 (and (eq_attr "type" "imul")
268 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
271 (define_function_unit "imuldiv" 1 0
272 (and (eq_attr "type" "imul")
273 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
276 (define_function_unit "imuldiv" 1 0
277 (and (eq_attr "type" "idiv")
278 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
281 (define_function_unit "imuldiv" 1 0
282 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
285 (define_function_unit "imuldiv" 1 0
286 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
289 (define_function_unit "imuldiv" 1 0
290 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
293 (define_function_unit "imuldiv" 1 0
294 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
297 (define_function_unit "imuldiv" 1 0
298 (and (eq_attr "type" "idiv")
299 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
302 (define_function_unit "imuldiv" 1 0
303 (and (eq_attr "type" "idiv")
304 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
307 (define_function_unit "imuldiv" 1 0
308 (and (eq_attr "type" "idiv")
309 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
312 (define_function_unit "imuldiv" 1 0
313 (and (eq_attr "type" "idiv")
314 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
317 (define_function_unit "imuldiv" 1 0
318 (and (eq_attr "type" "idiv")
319 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
322 (define_function_unit "imuldiv" 1 0
323 (and (eq_attr "type" "idiv")
324 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
327 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
328 ;; the FP hardware is part of the normal ALU circuitry. This means FP
329 ;; instructions affect the pipe-line, and no functional unit
330 ;; parallelism can occur on R4300 processors. To force GCC into coding
331 ;; for only a single functional unit, we force the R4300 FP
332 ;; instructions to be processed in the "imuldiv" unit.
334 (define_function_unit "adder" 1 1
335 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
338 (define_function_unit "adder" 1 1
339 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
342 (define_function_unit "adder" 1 1
343 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
346 (define_function_unit "adder" 1 1
347 (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
350 (define_function_unit "adder" 1 1
351 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
354 (define_function_unit "adder" 1 1
355 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
358 (define_function_unit "adder" 1 1
359 (and (eq_attr "type" "fabs,fneg")
360 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
363 (define_function_unit "adder" 1 1
364 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
367 (define_function_unit "mult" 1 1
368 (and (eq_attr "type" "fmul")
369 (and (eq_attr "mode" "SF")
370 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
373 (define_function_unit "mult" 1 1
374 (and (eq_attr "type" "fmul")
375 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
378 (define_function_unit "mult" 1 1
379 (and (eq_attr "type" "fmul")
380 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
383 (define_function_unit "mult" 1 1
384 (and (eq_attr "type" "fmul")
385 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
388 (define_function_unit "mult" 1 1
389 (and (eq_attr "type" "fmul")
390 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
393 (define_function_unit "mult" 1 1
394 (and (eq_attr "type" "fmul")
395 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
398 (define_function_unit "mult" 1 1
399 (and (eq_attr "type" "fmul")
400 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
403 (define_function_unit "divide" 1 1
404 (and (eq_attr "type" "fdiv")
405 (and (eq_attr "mode" "SF")
406 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
409 (define_function_unit "divide" 1 1
410 (and (eq_attr "type" "fdiv")
411 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
414 (define_function_unit "divide" 1 1
415 (and (eq_attr "type" "fdiv")
416 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
419 (define_function_unit "divide" 1 1
420 (and (eq_attr "type" "fdiv")
421 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
424 (define_function_unit "divide" 1 1
425 (and (eq_attr "type" "fdiv")
426 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
429 (define_function_unit "divide" 1 1
430 (and (eq_attr "type" "fdiv")
431 (and (eq_attr "mode" "DF")
432 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
435 (define_function_unit "divide" 1 1
436 (and (eq_attr "type" "fdiv")
437 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
440 (define_function_unit "divide" 1 1
441 (and (eq_attr "type" "fdiv")
442 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
445 (define_function_unit "divide" 1 1
446 (and (eq_attr "type" "fdiv")
447 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
450 ;;; ??? Is this number right?
451 (define_function_unit "divide" 1 1
452 (and (eq_attr "type" "fsqrt")
453 (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
456 (define_function_unit "divide" 1 1
457 (and (eq_attr "type" "fsqrt")
458 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
461 (define_function_unit "divide" 1 1
462 (and (eq_attr "type" "fsqrt")
463 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
466 ;;; ??? Is this number right?
467 (define_function_unit "divide" 1 1
468 (and (eq_attr "type" "fsqrt")
469 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
472 (define_function_unit "divide" 1 1
473 (and (eq_attr "type" "fsqrt")
474 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
477 (define_function_unit "divide" 1 1
478 (and (eq_attr "type" "fsqrt")
479 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
482 ;; R4300 FP instruction classes treated as part of the "imuldiv"
485 (define_function_unit "imuldiv" 1 0
486 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
489 (define_function_unit "imuldiv" 1 0
490 (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
493 (define_function_unit "imuldiv" 1 0
494 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
496 (define_function_unit "imuldiv" 1 0
497 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
500 (define_function_unit "imuldiv" 1 0
501 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
502 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
504 (define_function_unit "imuldiv" 1 0
505 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
506 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
509 ;; The following functional units do not use the cpu type, and use
510 ;; much less memory in genattrtab.c.
512 ;; (define_function_unit "memory" 1 0 (eq_attr "type" "load") 3 0)
513 ;; (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
515 ;; (define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0)
517 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0)
518 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0)
520 ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "imul") 17 0)
521 ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "idiv") 38 0)
523 ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fadd") 4 0)
524 ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fabs,fneg") 2 0)
526 ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF")) 7 0)
527 ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF")) 8 0)
529 ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF")) 23 0)
530 ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF")) 36 0)
532 ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0)
533 ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
536 ;; ....................
540 ;; ....................
544 [(trap_if (const_int 1) (const_int 0))]
548 if (ISA_HAS_COND_TRAP)
549 return \"teq\\t$0,$0\";
550 else if (TARGET_MIPS16)
556 (define_expand "conditional_trap"
557 [(trap_if (match_operator 0 "cmp_op"
558 [(match_dup 2) (match_dup 3)])
559 (match_operand 1 "const_int_operand" ""))]
563 mips_gen_conditional_trap (operands);
567 ;; Match a TRAP_IF with 2nd arg of 0. The div_trap_* insns match a
568 ;; 2nd arg of any CONST_INT, so this insn must appear first.
569 ;; gen_div_trap always generates TRAP_IF with 2nd arg of 6 or 7.
572 [(trap_if (match_operator 0 "trap_cmp_op"
573 [(match_operand:SI 1 "reg_or_0_operand" "d")
574 (match_operand:SI 2 "nonmemory_operand" "dI")])
580 ;; ....................
584 ;; ....................
587 (define_insn "adddf3"
588 [(set (match_operand:DF 0 "register_operand" "=f")
589 (plus:DF (match_operand:DF 1 "register_operand" "f")
590 (match_operand:DF 2 "register_operand" "f")))]
591 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
593 [(set_attr "type" "fadd")
594 (set_attr "mode" "DF")])
596 (define_insn "addsf3"
597 [(set (match_operand:SF 0 "register_operand" "=f")
598 (plus:SF (match_operand:SF 1 "register_operand" "f")
599 (match_operand:SF 2 "register_operand" "f")))]
602 [(set_attr "type" "fadd")
603 (set_attr "mode" "SF")])
605 (define_expand "addsi3"
606 [(set (match_operand:SI 0 "register_operand" "=d")
607 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
608 (match_operand:SI 2 "arith_operand" "dI")))]
612 /* The mips16 assembler handles -32768 correctly, and so does gas,
613 but some other MIPS assemblers think that -32768 needs to be
614 loaded into a register before it can be added in. */
617 && GET_CODE (operands[2]) == CONST_INT
618 && INTVAL (operands[2]) == -32768)
619 operands[2] = force_reg (SImode, operands[2]);
621 /* If a large stack adjustment was forced into a register, we may be
622 asked to generate rtx such as:
624 (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo)))
626 but no such instruction is available in mips16. Handle it by
627 using a temporary. */
629 && REGNO (operands[0]) == STACK_POINTER_REGNUM
630 && ((GET_CODE (operands[1]) == REG
631 && REGNO (operands[1]) != STACK_POINTER_REGNUM)
632 || GET_CODE (operands[2]) != CONST_INT))
634 rtx tmp = gen_reg_rtx (SImode);
636 emit_move_insn (tmp, operands[1]);
637 emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
638 emit_move_insn (operands[0], tmp);
643 (define_insn "addsi3_internal"
644 [(set (match_operand:SI 0 "register_operand" "=d")
645 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
646 (match_operand:SI 2 "arith_operand" "dI")))]
649 || GET_CODE (operands[2]) != CONST_INT
650 || INTVAL (operands[2]) != -32768)"
652 [(set_attr "type" "arith")
653 (set_attr "mode" "SI")])
655 ;; For the mips16, we need to recognize stack pointer additions
656 ;; explicitly, since we don't have a constraint for $sp. These insns
657 ;; will be generated by the save_restore_insns functions.
662 (match_operand:SI 0 "small_int" "I")))]
665 [(set_attr "type" "arith")
666 (set_attr "mode" "SI")
667 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
672 [(set (match_operand:SI 0 "register_operand" "=d")
674 (match_operand:SI 1 "small_int" "I")))]
677 [(set_attr "type" "arith")
678 (set_attr "mode" "SI")
679 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
684 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
685 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
686 (match_operand:SI 2 "arith_operand" "IQ,O,d")))]
688 && (GET_CODE (operands[1]) != REG
689 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
690 || M16_REG_P (REGNO (operands[1]))
691 || REGNO (operands[1]) == ARG_POINTER_REGNUM
692 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
693 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
694 && (GET_CODE (operands[2]) != REG
695 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
696 || M16_REG_P (REGNO (operands[2]))
697 || REGNO (operands[2]) == ARG_POINTER_REGNUM
698 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
699 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
702 if (REGNO (operands[0]) == REGNO (operands[1]))
703 return \"addu\\t%0,%2\";
704 return \"addu\\t%0,%1,%2\";
706 [(set_attr "type" "arith")
707 (set_attr "mode" "SI")
708 (set_attr_alternative "length"
709 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
712 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
718 ;; On the mips16, we can sometimes split an add of a constant which is
719 ;; a 4 byte instruction into two adds which are both 2 byte
720 ;; instructions. There are two cases: one where we are adding a
721 ;; constant plus a register to another register, and one where we are
722 ;; simply adding a constant to a register.
725 [(set (match_operand:SI 0 "register_operand" "")
726 (plus:SI (match_dup 0)
727 (match_operand:SI 1 "const_int_operand" "")))]
728 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
729 && GET_CODE (operands[0]) == REG
730 && M16_REG_P (REGNO (operands[0]))
731 && GET_CODE (operands[1]) == CONST_INT
732 && ((INTVAL (operands[1]) > 0x7f
733 && INTVAL (operands[1]) <= 0x7f + 0x7f)
734 || (INTVAL (operands[1]) < - 0x80
735 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
736 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
737 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
740 HOST_WIDE_INT val = INTVAL (operands[1]);
744 operands[1] = GEN_INT (0x7f);
745 operands[2] = GEN_INT (val - 0x7f);
749 operands[1] = GEN_INT (- 0x80);
750 operands[2] = GEN_INT (val + 0x80);
755 [(set (match_operand:SI 0 "register_operand" "")
756 (plus:SI (match_operand:SI 1 "register_operand" "")
757 (match_operand:SI 2 "const_int_operand" "")))]
758 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
759 && GET_CODE (operands[0]) == REG
760 && M16_REG_P (REGNO (operands[0]))
761 && GET_CODE (operands[1]) == REG
762 && M16_REG_P (REGNO (operands[1]))
763 && REGNO (operands[0]) != REGNO (operands[1])
764 && GET_CODE (operands[2]) == CONST_INT
765 && ((INTVAL (operands[2]) > 0x7
766 && INTVAL (operands[2]) <= 0x7 + 0x7f)
767 || (INTVAL (operands[2]) < - 0x8
768 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
769 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
770 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
773 HOST_WIDE_INT val = INTVAL (operands[2]);
777 operands[2] = GEN_INT (0x7);
778 operands[3] = GEN_INT (val - 0x7);
782 operands[2] = GEN_INT (- 0x8);
783 operands[3] = GEN_INT (val + 0x8);
787 (define_expand "adddi3"
788 [(parallel [(set (match_operand:DI 0 "register_operand" "")
789 (plus:DI (match_operand:DI 1 "se_register_operand" "")
790 (match_operand:DI 2 "se_arith_operand" "")))
791 (clobber (match_dup 3))])]
792 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
795 /* The mips16 assembler handles -32768 correctly, and so does gas,
796 but some other MIPS assemblers think that -32768 needs to be
797 loaded into a register before it can be added in. */
800 && GET_CODE (operands[2]) == CONST_INT
801 && INTVAL (operands[2]) == -32768)
802 operands[2] = force_reg (DImode, operands[2]);
804 /* If a large stack adjustment was forced into a register, we may be
805 asked to generate rtx such as:
807 (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo)))
809 but no such instruction is available in mips16. Handle it by
810 using a temporary. */
812 && REGNO (operands[0]) == STACK_POINTER_REGNUM
813 && ((GET_CODE (operands[1]) == REG
814 && REGNO (operands[1]) != STACK_POINTER_REGNUM)
815 || GET_CODE (operands[2]) != CONST_INT))
817 rtx tmp = gen_reg_rtx (DImode);
819 emit_move_insn (tmp, operands[1]);
820 emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
821 emit_move_insn (operands[0], tmp);
827 emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
832 operands[3] = gen_reg_rtx (SImode);
835 (define_insn "adddi3_internal_1"
836 [(set (match_operand:DI 0 "register_operand" "=d,&d")
837 (plus:DI (match_operand:DI 1 "register_operand" "0,d")
838 (match_operand:DI 2 "register_operand" "d,d")))
839 (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
840 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
843 return (REGNO (operands[0]) == REGNO (operands[1])
844 && REGNO (operands[0]) == REGNO (operands[2]))
845 ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
846 : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
848 [(set_attr "type" "darith")
849 (set_attr "mode" "DI")
850 (set_attr "length" "16")])
853 [(set (match_operand:DI 0 "register_operand" "")
854 (plus:DI (match_operand:DI 1 "register_operand" "")
855 (match_operand:DI 2 "register_operand" "")))
856 (clobber (match_operand:SI 3 "register_operand" ""))]
857 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
858 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
859 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
860 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
861 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
862 && (REGNO (operands[0]) != REGNO (operands[1])
863 || REGNO (operands[0]) != REGNO (operands[2]))"
865 [(set (subreg:SI (match_dup 0) 0)
866 (plus:SI (subreg:SI (match_dup 1) 0)
867 (subreg:SI (match_dup 2) 0)))
870 (ltu:SI (subreg:SI (match_dup 0) 0)
871 (subreg:SI (match_dup 2) 0)))
873 (set (subreg:SI (match_dup 0) 4)
874 (plus:SI (subreg:SI (match_dup 1) 4)
875 (subreg:SI (match_dup 2) 4)))
877 (set (subreg:SI (match_dup 0) 4)
878 (plus:SI (subreg:SI (match_dup 0) 4)
883 [(set (match_operand:DI 0 "register_operand" "")
884 (plus:DI (match_operand:DI 1 "register_operand" "")
885 (match_operand:DI 2 "register_operand" "")))
886 (clobber (match_operand:SI 3 "register_operand" ""))]
887 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
888 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
889 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
890 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
891 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
892 && (REGNO (operands[0]) != REGNO (operands[1])
893 || REGNO (operands[0]) != REGNO (operands[2]))"
895 [(set (subreg:SI (match_dup 0) 4)
896 (plus:SI (subreg:SI (match_dup 1) 4)
897 (subreg:SI (match_dup 2) 4)))
900 (ltu:SI (subreg:SI (match_dup 0) 4)
901 (subreg:SI (match_dup 2) 4)))
903 (set (subreg:SI (match_dup 0) 0)
904 (plus:SI (subreg:SI (match_dup 1) 0)
905 (subreg:SI (match_dup 2) 0)))
907 (set (subreg:SI (match_dup 0) 0)
908 (plus:SI (subreg:SI (match_dup 0) 0)
912 (define_insn "adddi3_internal_2"
913 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
914 (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
915 (match_operand:DI 2 "small_int" "P,J,N")))
916 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
917 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
919 || GET_CODE (operands[2]) != CONST_INT
920 || INTVAL (operands[2]) != -32768)"
922 addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
923 move\\t%L0,%L1\;move\\t%M0,%M1
924 subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
925 [(set_attr "type" "darith")
926 (set_attr "mode" "DI")
927 (set_attr "length" "12,8,16")])
930 [(set (match_operand:DI 0 "register_operand" "")
931 (plus:DI (match_operand:DI 1 "register_operand" "")
932 (match_operand:DI 2 "small_int" "")))
933 (clobber (match_operand:SI 3 "register_operand" ""))]
934 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
935 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
936 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
937 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
938 && INTVAL (operands[2]) > 0"
940 [(set (subreg:SI (match_dup 0) 0)
941 (plus:SI (subreg:SI (match_dup 1) 0)
945 (ltu:SI (subreg:SI (match_dup 0) 0)
948 (set (subreg:SI (match_dup 0) 4)
949 (plus:SI (subreg:SI (match_dup 1) 4)
954 [(set (match_operand:DI 0 "register_operand" "")
955 (plus:DI (match_operand:DI 1 "register_operand" "")
956 (match_operand:DI 2 "small_int" "")))
957 (clobber (match_operand:SI 3 "register_operand" ""))]
958 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
959 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
960 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
961 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
962 && INTVAL (operands[2]) > 0"
964 [(set (subreg:SI (match_dup 0) 4)
965 (plus:SI (subreg:SI (match_dup 1) 4)
969 (ltu:SI (subreg:SI (match_dup 0) 4)
972 (set (subreg:SI (match_dup 0) 0)
973 (plus:SI (subreg:SI (match_dup 1) 0)
977 (define_insn "adddi3_internal_3"
978 [(set (match_operand:DI 0 "register_operand" "=d")
979 (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
980 (match_operand:DI 2 "se_arith_operand" "dI")))]
984 || GET_CODE (operands[2]) != CONST_INT
985 || INTVAL (operands[2]) != -32768)"
988 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
989 ? \"dsubu\\t%0,%z1,%n2\"
990 : \"daddu\\t%0,%z1,%2\";
992 [(set_attr "type" "darith")
993 (set_attr "mode" "DI")])
995 ;; For the mips16, we need to recognize stack pointer additions
996 ;; explicitly, since we don't have a constraint for $sp. These insns
997 ;; will be generated by the save_restore_insns functions.
1001 (plus:DI (reg:DI 29)
1002 (match_operand:DI 0 "small_int" "I")))]
1003 "TARGET_MIPS16 && TARGET_64BIT"
1005 [(set_attr "type" "arith")
1006 (set_attr "mode" "DI")
1007 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
1012 [(set (match_operand:DI 0 "register_operand" "=d")
1013 (plus:DI (reg:DI 29)
1014 (match_operand:DI 1 "small_int" "I")))]
1015 "TARGET_MIPS16 && TARGET_64BIT"
1017 [(set_attr "type" "arith")
1018 (set_attr "mode" "DI")
1019 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
1024 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1025 (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1026 (match_operand:DI 2 "arith_operand" "IQ,O,d")))]
1027 "TARGET_MIPS16 && TARGET_64BIT
1028 && (GET_CODE (operands[1]) != REG
1029 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
1030 || M16_REG_P (REGNO (operands[1]))
1031 || REGNO (operands[1]) == ARG_POINTER_REGNUM
1032 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
1033 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
1034 && (GET_CODE (operands[2]) != REG
1035 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
1036 || M16_REG_P (REGNO (operands[2]))
1037 || REGNO (operands[2]) == ARG_POINTER_REGNUM
1038 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
1039 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
1042 if (REGNO (operands[0]) == REGNO (operands[1]))
1043 return \"daddu\\t%0,%2\";
1044 return \"daddu\\t%0,%1,%2\";
1046 [(set_attr "type" "arith")
1047 (set_attr "mode" "DI")
1048 (set_attr_alternative "length"
1049 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
1052 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1058 ;; On the mips16, we can sometimes split an add of a constant which is
1059 ;; a 4 byte instruction into two adds which are both 2 byte
1060 ;; instructions. There are two cases: one where we are adding a
1061 ;; constant plus a register to another register, and one where we are
1062 ;; simply adding a constant to a register.
1065 [(set (match_operand:DI 0 "register_operand" "")
1066 (plus:DI (match_dup 0)
1067 (match_operand:DI 1 "const_int_operand" "")))]
1068 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1069 && GET_CODE (operands[0]) == REG
1070 && M16_REG_P (REGNO (operands[0]))
1071 && GET_CODE (operands[1]) == CONST_INT
1072 && ((INTVAL (operands[1]) > 0xf
1073 && INTVAL (operands[1]) <= 0xf + 0xf)
1074 || (INTVAL (operands[1]) < - 0x10
1075 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1076 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1077 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1080 HOST_WIDE_INT val = INTVAL (operands[1]);
1084 operands[1] = GEN_INT (0xf);
1085 operands[2] = GEN_INT (val - 0xf);
1089 operands[1] = GEN_INT (- 0x10);
1090 operands[2] = GEN_INT (val + 0x10);
1095 [(set (match_operand:DI 0 "register_operand" "")
1096 (plus:DI (match_operand:DI 1 "register_operand" "")
1097 (match_operand:DI 2 "const_int_operand" "")))]
1098 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1099 && GET_CODE (operands[0]) == REG
1100 && M16_REG_P (REGNO (operands[0]))
1101 && GET_CODE (operands[1]) == REG
1102 && M16_REG_P (REGNO (operands[1]))
1103 && REGNO (operands[0]) != REGNO (operands[1])
1104 && GET_CODE (operands[2]) == CONST_INT
1105 && ((INTVAL (operands[2]) > 0x7
1106 && INTVAL (operands[2]) <= 0x7 + 0xf)
1107 || (INTVAL (operands[2]) < - 0x8
1108 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1109 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1110 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1113 HOST_WIDE_INT val = INTVAL (operands[2]);
1117 operands[2] = GEN_INT (0x7);
1118 operands[3] = GEN_INT (val - 0x7);
1122 operands[2] = GEN_INT (- 0x8);
1123 operands[3] = GEN_INT (val + 0x8);
1127 (define_insn "addsi3_internal_2"
1128 [(set (match_operand:DI 0 "register_operand" "=d")
1129 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1130 (match_operand:SI 2 "arith_operand" "dI"))))]
1134 || GET_CODE (operands[2]) != CONST_INT
1135 || INTVAL (operands[2]) != -32768)"
1138 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1139 ? \"subu\\t%0,%z1,%n2\"
1140 : \"addu\\t%0,%z1,%2\";
1142 [(set_attr "type" "arith")
1143 (set_attr "mode" "SI")])
1146 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1147 (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1148 (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1149 "TARGET_MIPS16 && TARGET_64BIT"
1152 if (REGNO (operands[0]) == REGNO (operands[1]))
1153 return \"addu\\t%0,%2\";
1154 return \"addu\\t%0,%1,%2\";
1156 [(set_attr "type" "arith")
1157 (set_attr "mode" "SI")
1158 (set_attr_alternative "length"
1159 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
1162 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1169 ;; ....................
1173 ;; ....................
1176 (define_insn "subdf3"
1177 [(set (match_operand:DF 0 "register_operand" "=f")
1178 (minus:DF (match_operand:DF 1 "register_operand" "f")
1179 (match_operand:DF 2 "register_operand" "f")))]
1180 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1182 [(set_attr "type" "fadd")
1183 (set_attr "mode" "DF")])
1185 (define_insn "subsf3"
1186 [(set (match_operand:SF 0 "register_operand" "=f")
1187 (minus:SF (match_operand:SF 1 "register_operand" "f")
1188 (match_operand:SF 2 "register_operand" "f")))]
1191 [(set_attr "type" "fadd")
1192 (set_attr "mode" "SF")])
1194 (define_expand "subsi3"
1195 [(set (match_operand:SI 0 "register_operand" "=d")
1196 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1197 (match_operand:SI 2 "arith_operand" "dI")))]
1201 if (GET_CODE (operands[2]) == CONST_INT
1202 && (INTVAL (operands[2]) == -32768
1204 && INTVAL (operands[2]) == -0x4000)))
1205 operands[2] = force_reg (SImode, operands[2]);
1208 (define_insn "subsi3_internal"
1209 [(set (match_operand:SI 0 "register_operand" "=d")
1210 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1211 (match_operand:SI 2 "arith_operand" "dI")))]
1213 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1215 [(set_attr "type" "arith")
1216 (set_attr "mode" "SI")])
1218 ;; For the mips16, we need to recognize stack pointer subtractions
1219 ;; explicitly, since we don't have a constraint for $sp. These insns
1220 ;; will be generated by the save_restore_insns functions.
1224 (minus:SI (reg:SI 29)
1225 (match_operand:SI 0 "small_int" "I")))]
1227 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1229 [(set_attr "type" "arith")
1230 (set_attr "mode" "SI")
1231 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1236 [(set (match_operand:SI 0 "register_operand" "=d")
1237 (minus:SI (reg:SI 29)
1238 (match_operand:SI 1 "small_int" "I")))]
1240 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1242 [(set_attr "type" "arith")
1243 (set_attr "mode" "SI")
1244 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "")
1250 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1251 (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1252 (match_operand:SI 2 "arith_operand" "I,O,d")))]
1254 && (GET_CODE (operands[2]) != CONST_INT
1255 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1258 if (REGNO (operands[0]) == REGNO (operands[1]))
1259 return \"subu\\t%0,%2\";
1260 return \"subu\\t%0,%1,%2\";
1262 [(set_attr "type" "arith")
1263 (set_attr "mode" "SI")
1264 (set_attr_alternative "length"
1265 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1268 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1273 ;; On the mips16, we can sometimes split an subtract of a constant
1274 ;; which is a 4 byte instruction into two adds which are both 2 byte
1275 ;; instructions. There are two cases: one where we are setting a
1276 ;; register to a register minus a constant, and one where we are
1277 ;; simply subtracting a constant from a register.
1280 [(set (match_operand:SI 0 "register_operand" "")
1281 (minus:SI (match_dup 0)
1282 (match_operand:SI 1 "const_int_operand" "")))]
1283 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1284 && GET_CODE (operands[0]) == REG
1285 && M16_REG_P (REGNO (operands[0]))
1286 && GET_CODE (operands[1]) == CONST_INT
1287 && ((INTVAL (operands[1]) > 0x80
1288 && INTVAL (operands[1]) <= 0x80 + 0x80)
1289 || (INTVAL (operands[1]) < - 0x7f
1290 && INTVAL (operands[1]) >= - 0x7f - 0x7f))"
1291 [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1)))
1292 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1295 HOST_WIDE_INT val = INTVAL (operands[1]);
1299 operands[1] = GEN_INT (0x80);
1300 operands[2] = GEN_INT (val - 0x80);
1304 operands[1] = GEN_INT (- 0x7f);
1305 operands[2] = GEN_INT (val + 0x7f);
1310 [(set (match_operand:SI 0 "register_operand" "")
1311 (minus:SI (match_operand:SI 1 "register_operand" "")
1312 (match_operand:SI 2 "const_int_operand" "")))]
1313 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1314 && GET_CODE (operands[0]) == REG
1315 && M16_REG_P (REGNO (operands[0]))
1316 && GET_CODE (operands[1]) == REG
1317 && M16_REG_P (REGNO (operands[1]))
1318 && REGNO (operands[0]) != REGNO (operands[1])
1319 && GET_CODE (operands[2]) == CONST_INT
1320 && ((INTVAL (operands[2]) > 0x8
1321 && INTVAL (operands[2]) <= 0x8 + 0x80)
1322 || (INTVAL (operands[2]) < - 0x7
1323 && INTVAL (operands[2]) >= - 0x7 - 0x7f))"
1324 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1325 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))]
1328 HOST_WIDE_INT val = INTVAL (operands[2]);
1332 operands[2] = GEN_INT (0x8);
1333 operands[3] = GEN_INT (val - 0x8);
1337 operands[2] = GEN_INT (- 0x7);
1338 operands[3] = GEN_INT (val + 0x7);
1342 (define_expand "subdi3"
1343 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1344 (minus:DI (match_operand:DI 1 "se_register_operand" "d")
1345 (match_operand:DI 2 "se_register_operand" "d")))
1346 (clobber (match_dup 3))])]
1347 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
1352 emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1357 operands[3] = gen_reg_rtx (SImode);
1360 (define_insn "subdi3_internal"
1361 [(set (match_operand:DI 0 "register_operand" "=d")
1362 (minus:DI (match_operand:DI 1 "register_operand" "d")
1363 (match_operand:DI 2 "register_operand" "d")))
1364 (clobber (match_operand:SI 3 "register_operand" "=d"))]
1365 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
1366 "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
1367 [(set_attr "type" "darith")
1368 (set_attr "mode" "DI")
1369 (set_attr "length" "16")])
1372 [(set (match_operand:DI 0 "register_operand" "")
1373 (minus:DI (match_operand:DI 1 "register_operand" "")
1374 (match_operand:DI 2 "register_operand" "")))
1375 (clobber (match_operand:SI 3 "register_operand" ""))]
1376 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1377 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1378 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1379 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1380 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1383 (ltu:SI (subreg:SI (match_dup 1) 0)
1384 (subreg:SI (match_dup 2) 0)))
1386 (set (subreg:SI (match_dup 0) 0)
1387 (minus:SI (subreg:SI (match_dup 1) 0)
1388 (subreg:SI (match_dup 2) 0)))
1390 (set (subreg:SI (match_dup 0) 4)
1391 (minus:SI (subreg:SI (match_dup 1) 4)
1392 (subreg:SI (match_dup 2) 4)))
1394 (set (subreg:SI (match_dup 0) 4)
1395 (minus:SI (subreg:SI (match_dup 0) 4)
1400 [(set (match_operand:DI 0 "register_operand" "")
1401 (minus:DI (match_operand:DI 1 "register_operand" "")
1402 (match_operand:DI 2 "register_operand" "")))
1403 (clobber (match_operand:SI 3 "register_operand" ""))]
1404 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1405 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1406 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1407 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1408 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1411 (ltu:SI (subreg:SI (match_dup 1) 4)
1412 (subreg:SI (match_dup 2) 4)))
1414 (set (subreg:SI (match_dup 0) 4)
1415 (minus:SI (subreg:SI (match_dup 1) 4)
1416 (subreg:SI (match_dup 2) 4)))
1418 (set (subreg:SI (match_dup 0) 0)
1419 (minus:SI (subreg:SI (match_dup 1) 0)
1420 (subreg:SI (match_dup 2) 0)))
1422 (set (subreg:SI (match_dup 0) 0)
1423 (minus:SI (subreg:SI (match_dup 0) 0)
1427 (define_insn "subdi3_internal_2"
1428 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1429 (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
1430 (match_operand:DI 2 "small_int" "P,J,N")))
1431 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
1432 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1433 && INTVAL (operands[2]) != -32768"
1435 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
1436 move\\t%L0,%L1\;move\\t%M0,%M1
1437 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
1438 [(set_attr "type" "darith")
1439 (set_attr "mode" "DI")
1440 (set_attr "length" "12,8,16")])
1443 [(set (match_operand:DI 0 "register_operand" "")
1444 (minus:DI (match_operand:DI 1 "register_operand" "")
1445 (match_operand:DI 2 "small_int" "")))
1446 (clobber (match_operand:SI 3 "register_operand" ""))]
1447 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1448 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1449 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1450 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1451 && INTVAL (operands[2]) > 0"
1454 (ltu:SI (subreg:SI (match_dup 1) 0)
1457 (set (subreg:SI (match_dup 0) 0)
1458 (minus:SI (subreg:SI (match_dup 1) 0)
1461 (set (subreg:SI (match_dup 0) 4)
1462 (minus:SI (subreg:SI (match_dup 1) 4)
1467 [(set (match_operand:DI 0 "register_operand" "")
1468 (minus:DI (match_operand:DI 1 "register_operand" "")
1469 (match_operand:DI 2 "small_int" "")))
1470 (clobber (match_operand:SI 3 "register_operand" ""))]
1471 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1472 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1473 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1474 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1475 && INTVAL (operands[2]) > 0"
1478 (ltu:SI (subreg:SI (match_dup 1) 4)
1481 (set (subreg:SI (match_dup 0) 4)
1482 (minus:SI (subreg:SI (match_dup 1) 4)
1485 (set (subreg:SI (match_dup 0) 0)
1486 (minus:SI (subreg:SI (match_dup 1) 0)
1490 (define_insn "subdi3_internal_3"
1491 [(set (match_operand:DI 0 "register_operand" "=d")
1492 (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
1493 (match_operand:DI 2 "se_arith_operand" "dI")))]
1494 "TARGET_64BIT && !TARGET_MIPS16
1495 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1498 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1499 ? \"daddu\\t%0,%z1,%n2\"
1500 : \"dsubu\\t%0,%z1,%2\";
1502 [(set_attr "type" "darith")
1503 (set_attr "mode" "DI")])
1505 ;; For the mips16, we need to recognize stack pointer subtractions
1506 ;; explicitly, since we don't have a constraint for $sp. These insns
1507 ;; will be generated by the save_restore_insns functions.
1511 (minus:DI (reg:DI 29)
1512 (match_operand:DI 0 "small_int" "I")))]
1514 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1516 [(set_attr "type" "arith")
1517 (set_attr "mode" "DI")
1518 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1523 [(set (match_operand:DI 0 "register_operand" "=d")
1524 (minus:DI (reg:DI 29)
1525 (match_operand:DI 1 "small_int" "I")))]
1527 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1529 [(set_attr "type" "arith")
1530 (set_attr "mode" "DI")
1531 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "")
1536 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1537 (minus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1538 (match_operand:DI 2 "arith_operand" "I,O,d")))]
1540 && (GET_CODE (operands[2]) != CONST_INT
1541 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1544 if (REGNO (operands[0]) == REGNO (operands[1]))
1545 return \"dsubu\\t%0,%2\";
1546 return \"dsubu\\t%0,%1,%2\";
1548 [(set_attr "type" "arith")
1549 (set_attr "mode" "DI")
1550 (set_attr_alternative "length"
1551 [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "")
1554 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1559 ;; On the mips16, we can sometimes split an add of a constant which is
1560 ;; a 4 byte instruction into two adds which are both 2 byte
1561 ;; instructions. There are two cases: one where we are adding a
1562 ;; constant plus a register to another register, and one where we are
1563 ;; simply adding a constant to a register.
1566 [(set (match_operand:DI 0 "register_operand" "")
1567 (minus:DI (match_dup 0)
1568 (match_operand:DI 1 "const_int_operand" "")))]
1569 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1570 && GET_CODE (operands[0]) == REG
1571 && M16_REG_P (REGNO (operands[0]))
1572 && GET_CODE (operands[1]) == CONST_INT
1573 && ((INTVAL (operands[1]) > 0x10
1574 && INTVAL (operands[1]) <= 0x10 + 0x10)
1575 || (INTVAL (operands[1]) < - 0xf
1576 && INTVAL (operands[1]) >= - 0xf - 0xf))"
1577 [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1)))
1578 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
1581 HOST_WIDE_INT val = INTVAL (operands[1]);
1585 operands[1] = GEN_INT (0xf);
1586 operands[2] = GEN_INT (val - 0xf);
1590 operands[1] = GEN_INT (- 0x10);
1591 operands[2] = GEN_INT (val + 0x10);
1596 [(set (match_operand:DI 0 "register_operand" "")
1597 (minus:DI (match_operand:DI 1 "register_operand" "")
1598 (match_operand:DI 2 "const_int_operand" "")))]
1599 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1600 && GET_CODE (operands[0]) == REG
1601 && M16_REG_P (REGNO (operands[0]))
1602 && GET_CODE (operands[1]) == REG
1603 && M16_REG_P (REGNO (operands[1]))
1604 && REGNO (operands[0]) != REGNO (operands[1])
1605 && GET_CODE (operands[2]) == CONST_INT
1606 && ((INTVAL (operands[2]) > 0x8
1607 && INTVAL (operands[2]) <= 0x8 + 0x10)
1608 || (INTVAL (operands[2]) < - 0x7
1609 && INTVAL (operands[2]) >= - 0x7 - 0xf))"
1610 [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
1611 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))]
1614 HOST_WIDE_INT val = INTVAL (operands[2]);
1618 operands[2] = GEN_INT (0x8);
1619 operands[3] = GEN_INT (val - 0x8);
1623 operands[2] = GEN_INT (- 0x7);
1624 operands[3] = GEN_INT (val + 0x7);
1628 (define_insn "subsi3_internal_2"
1629 [(set (match_operand:DI 0 "register_operand" "=d")
1630 (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1631 (match_operand:SI 2 "arith_operand" "dI"))))]
1632 "TARGET_64BIT && !TARGET_MIPS16
1633 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1636 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1637 ? \"addu\\t%0,%z1,%n2\"
1638 : \"subu\\t%0,%z1,%2\";
1640 [(set_attr "type" "arith")
1641 (set_attr "mode" "DI")])
1644 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1645 (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1646 (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1647 "TARGET_64BIT && TARGET_MIPS16
1648 && (GET_CODE (operands[2]) != CONST_INT
1649 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1652 if (REGNO (operands[0]) == REGNO (operands[1]))
1653 return \"subu\\t%0,%2\";
1654 return \"subu\\t%0,%1,%2\";
1656 [(set_attr "type" "arith")
1657 (set_attr "mode" "SI")
1658 (set_attr_alternative "length"
1659 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1662 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1670 ;; ....................
1674 ;; ....................
1677 ;; Early Vr4300 silicon has a CPU bug where multiplies with certain
1678 ;; operands may corrupt immediately following multiplies. This is a
1679 ;; simple fix to insert NOPs.
1681 (define_expand "muldf3"
1682 [(set (match_operand:DF 0 "register_operand" "=f")
1683 (mult:DF (match_operand:DF 1 "register_operand" "f")
1684 (match_operand:DF 2 "register_operand" "f")))]
1685 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1688 if (!TARGET_MIPS4300)
1689 emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
1691 emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
1695 (define_insn "muldf3_internal"
1696 [(set (match_operand:DF 0 "register_operand" "=f")
1697 (mult:DF (match_operand:DF 1 "register_operand" "f")
1698 (match_operand:DF 2 "register_operand" "f")))]
1699 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_MIPS4300"
1701 [(set_attr "type" "fmul")
1702 (set_attr "mode" "DF")])
1704 (define_insn "muldf3_r4300"
1705 [(set (match_operand:DF 0 "register_operand" "=f")
1706 (mult:DF (match_operand:DF 1 "register_operand" "f")
1707 (match_operand:DF 2 "register_operand" "f")))]
1708 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_MIPS4300"
1711 output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
1712 if (TARGET_4300_MUL_FIX)
1713 output_asm_insn (\"nop\", operands);
1716 [(set_attr "type" "fmul")
1717 (set_attr "mode" "DF")
1718 (set_attr "length" "8")]) ;; mul.d + nop
1720 (define_expand "mulsf3"
1721 [(set (match_operand:SF 0 "register_operand" "=f")
1722 (mult:SF (match_operand:SF 1 "register_operand" "f")
1723 (match_operand:SF 2 "register_operand" "f")))]
1727 if (!TARGET_MIPS4300)
1728 emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
1730 emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
1734 (define_insn "mulsf3_internal"
1735 [(set (match_operand:SF 0 "register_operand" "=f")
1736 (mult:SF (match_operand:SF 1 "register_operand" "f")
1737 (match_operand:SF 2 "register_operand" "f")))]
1738 "TARGET_HARD_FLOAT && !TARGET_MIPS4300"
1740 [(set_attr "type" "fmul")
1741 (set_attr "mode" "SF")])
1743 (define_insn "mulsf3_r4300"
1744 [(set (match_operand:SF 0 "register_operand" "=f")
1745 (mult:SF (match_operand:SF 1 "register_operand" "f")
1746 (match_operand:SF 2 "register_operand" "f")))]
1747 "TARGET_HARD_FLOAT && TARGET_MIPS4300"
1750 output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1751 if (TARGET_4300_MUL_FIX)
1752 output_asm_insn (\"nop\", operands);
1755 [(set_attr "type" "fmul")
1756 (set_attr "mode" "SF")
1757 (set_attr "length" "8")]) ;; mul.s + nop
1760 ;; ??? The R4000 (only) has a cpu bug. If a double-word shift executes while
1761 ;; a multiply is in progress, it may give an incorrect result. Avoid
1762 ;; this by keeping the mflo with the mult on the R4000.
1764 (define_expand "mulsi3"
1765 [(set (match_operand:SI 0 "register_operand" "=l")
1766 (mult:SI (match_operand:SI 1 "register_operand" "d")
1767 (match_operand:SI 2 "register_operand" "d")))
1768 (clobber (match_scratch:SI 3 "=h"))
1769 (clobber (match_scratch:SI 4 "=a"))]
1773 if (GENERATE_MULT3_SI || TARGET_MAD)
1774 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1775 else if (!TARGET_MIPS4000 || TARGET_MIPS16)
1776 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1778 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1782 (define_insn "mulsi3_mult3"
1783 [(set (match_operand:SI 0 "register_operand" "=d,l")
1784 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1785 (match_operand:SI 2 "register_operand" "d,d")))
1786 (clobber (match_scratch:SI 3 "=h,h"))
1787 (clobber (match_scratch:SI 4 "=l,X"))
1788 (clobber (match_scratch:SI 5 "=a,a"))]
1793 if (which_alternative == 1)
1794 return \"mult\\t%1,%2\";
1798 return \"mul\\t%0,%1,%2\";
1799 return \"mult\\t%0,%1,%2\";
1801 [(set_attr "type" "imul")
1802 (set_attr "mode" "SI")])
1804 (define_insn "mulsi3_internal"
1805 [(set (match_operand:SI 0 "register_operand" "=l")
1806 (mult:SI (match_operand:SI 1 "register_operand" "d")
1807 (match_operand:SI 2 "register_operand" "d")))
1808 (clobber (match_scratch:SI 3 "=h"))
1809 (clobber (match_scratch:SI 4 "=a"))]
1810 "!TARGET_MIPS4000 || TARGET_MIPS16"
1812 [(set_attr "type" "imul")
1813 (set_attr "mode" "SI")])
1815 (define_insn "mulsi3_r4000"
1816 [(set (match_operand:SI 0 "register_operand" "=d")
1817 (mult:SI (match_operand:SI 1 "register_operand" "d")
1818 (match_operand:SI 2 "register_operand" "d")))
1819 (clobber (match_scratch:SI 3 "=h"))
1820 (clobber (match_scratch:SI 4 "=l"))
1821 (clobber (match_scratch:SI 5 "=a"))]
1822 "TARGET_MIPS4000 && !TARGET_MIPS16"
1827 xoperands[0] = operands[0];
1828 xoperands[1] = gen_rtx_REG (SImode, LO_REGNUM);
1830 output_asm_insn (\"mult\\t%1,%2\", operands);
1831 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1834 [(set_attr "type" "imul")
1835 (set_attr "mode" "SI")
1836 (set_attr "length" "12")]) ;; mult + mflo + delay
1838 ;; Multiply-accumulate patterns
1840 ;; For processors that can copy the output to a general register:
1842 ;; The all-d alternative is needed because the combiner will find this
1843 ;; pattern and then register alloc/reload will move registers around to
1844 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1846 ;; The last alternative should be made slightly less desirable, but adding
1847 ;; "?" to the constraint is too strong, and causes values to be loaded into
1848 ;; LO even when that's more costly. For now, using "*d" mostly does the
1850 (define_insn "*mul_acc_si"
1851 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1852 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1853 (match_operand:SI 2 "register_operand" "d,d,d"))
1854 (match_operand:SI 3 "register_operand" "0,l,*d")))
1855 (clobber (match_scratch:SI 4 "=h,h,h"))
1856 (clobber (match_scratch:SI 5 "=X,3,l"))
1857 (clobber (match_scratch:SI 6 "=a,a,a"))
1858 (clobber (match_scratch:SI 7 "=X,X,d"))]
1860 || ISA_HAS_MADD_MSUB)
1864 static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" };
1865 if (which_alternative == 2)
1867 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1869 return madd[which_alternative];
1871 [(set_attr "type" "imul,imul,multi")
1872 (set_attr "mode" "SI")
1873 (set_attr "length" "4,4,8")])
1875 ;; Split the above insn if we failed to get LO allocated.
1877 [(set (match_operand:SI 0 "register_operand" "")
1878 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1879 (match_operand:SI 2 "register_operand" ""))
1880 (match_operand:SI 3 "register_operand" "")))
1881 (clobber (match_scratch:SI 4 ""))
1882 (clobber (match_scratch:SI 5 ""))
1883 (clobber (match_scratch:SI 6 ""))
1884 (clobber (match_scratch:SI 7 ""))]
1885 "reload_completed && !TARGET_DEBUG_D_MODE
1886 && GP_REG_P (true_regnum (operands[0]))
1887 && GP_REG_P (true_regnum (operands[3]))"
1888 [(parallel [(set (match_dup 7)
1889 (mult:SI (match_dup 1) (match_dup 2)))
1890 (clobber (match_dup 4))
1891 (clobber (match_dup 5))
1892 (clobber (match_dup 6))])
1893 (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 3)))]
1896 ;; Splitter to copy result of MADD to a general register
1898 [(set (match_operand:SI 0 "register_operand" "")
1899 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1900 (match_operand:SI 2 "register_operand" ""))
1901 (match_operand:SI 3 "register_operand" "")))
1902 (clobber (match_scratch:SI 4 ""))
1903 (clobber (match_scratch:SI 5 ""))
1904 (clobber (match_scratch:SI 6 ""))
1905 (clobber (match_scratch:SI 7 ""))]
1906 "reload_completed && !TARGET_DEBUG_D_MODE
1907 && GP_REG_P (true_regnum (operands[0]))
1908 && true_regnum (operands[3]) == LO_REGNUM"
1909 [(parallel [(set (match_dup 3)
1910 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1912 (clobber (match_dup 4))
1913 (clobber (match_dup 5))
1914 (clobber (match_dup 6))
1915 (clobber (match_dup 7))])
1916 (set (match_dup 0) (match_dup 3))]
1919 (define_insn "*mul_sub_si"
1920 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1921 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1922 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1923 (match_operand:SI 3 "register_operand" "d,d,d"))))
1924 (clobber (match_scratch:SI 4 "=h,h,h"))
1925 (clobber (match_scratch:SI 5 "=X,3,l"))
1926 (clobber (match_scratch:SI 6 "=a,a,a"))
1927 (clobber (match_scratch:SI 7 "=X,X,d"))]
1931 if (which_alternative != 0)
1933 return \"msub\\t%2,%3\";
1935 [(set_attr "type" "imul,imul,multi")
1936 (set_attr "mode" "SI")
1937 (set_attr "length" "4,8,8")])
1939 ;; Split the above insn if we failed to get LO allocated.
1941 [(set (match_operand:SI 0 "register_operand" "")
1942 (minus:SI (match_operand:SI 1 "register_operand" "")
1943 (mult:SI (match_operand:SI 2 "register_operand" "")
1944 (match_operand:SI 3 "register_operand" ""))))
1945 (clobber (match_scratch:SI 4 ""))
1946 (clobber (match_scratch:SI 5 ""))
1947 (clobber (match_scratch:SI 6 ""))
1948 (clobber (match_scratch:SI 7 ""))]
1949 "reload_completed && !TARGET_DEBUG_D_MODE
1950 && GP_REG_P (true_regnum (operands[0]))
1951 && GP_REG_P (true_regnum (operands[1]))"
1952 [(parallel [(set (match_dup 7)
1953 (mult:SI (match_dup 2) (match_dup 3)))
1954 (clobber (match_dup 4))
1955 (clobber (match_dup 5))
1956 (clobber (match_dup 6))])
1957 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
1960 ;; Splitter to copy result of MSUB to a general register
1962 [(set (match_operand:SI 0 "register_operand" "")
1963 (minus:SI (match_operand:SI 1 "register_operand" "")
1964 (mult:SI (match_operand:SI 2 "register_operand" "")
1965 (match_operand:SI 3 "register_operand" ""))))
1966 (clobber (match_scratch:SI 4 ""))
1967 (clobber (match_scratch:SI 5 ""))
1968 (clobber (match_scratch:SI 6 ""))
1969 (clobber (match_scratch:SI 7 ""))]
1970 "reload_completed && !TARGET_DEBUG_D_MODE
1971 && GP_REG_P (true_regnum (operands[0]))
1972 && true_regnum (operands[1]) == LO_REGNUM"
1973 [(parallel [(set (match_dup 1)
1974 (minus:SI (match_dup 1)
1975 (mult:SI (match_dup 2) (match_dup 3))))
1976 (clobber (match_dup 4))
1977 (clobber (match_dup 5))
1978 (clobber (match_dup 6))
1979 (clobber (match_dup 7))])
1980 (set (match_dup 0) (match_dup 1))]
1985 [(set (match_operand:SI 0 "register_operand" "")
1986 (minus:SI (match_operand:SI 1 "register_operand" "")
1987 (mult:SI (match_operand:SI 2 "register_operand" "")
1988 (match_operand:SI 3 "register_operand" ""))))
1989 (clobber (match_scratch:SI 4 ""))
1990 (clobber (match_scratch:SI 5 ""))
1991 (clobber (match_scratch:SI 6 ""))
1992 (clobber (match_scratch:SI 7 ""))]
1993 "reload_completed && !TARGET_DEBUG_D_MODE
1994 && GP_REG_P (true_regnum (operands[0]))
1995 && GP_REG_P (true_regnum (operands[1]))"
1996 [(parallel [(set (match_dup 7)
1997 (mult:SI (match_dup 2) (match_dup 3)))
1998 (clobber (match_dup 4))
1999 (clobber (match_dup 5))
2000 (clobber (match_dup 6))])
2001 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
2004 (define_expand "muldi3"
2005 [(set (match_operand:DI 0 "register_operand" "=l")
2006 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
2007 (match_operand:DI 2 "register_operand" "d")))
2008 (clobber (match_scratch:DI 3 "=h"))
2009 (clobber (match_scratch:DI 4 "=a"))]
2014 if (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)
2015 emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
2017 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
2021 ;; Don't accept both operands using se_register_operand, because if
2022 ;; both operands are sign extended we would prefer to use mult in the
2023 ;; mulsidi3 pattern. Commutativity should permit either operand to be
2026 (define_insn "muldi3_internal"
2027 [(set (match_operand:DI 0 "register_operand" "=l")
2028 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
2029 (match_operand:DI 2 "register_operand" "d")))
2030 (clobber (match_scratch:DI 3 "=h"))
2031 (clobber (match_scratch:DI 4 "=a"))]
2032 "TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16"
2034 [(set_attr "type" "imul")
2035 (set_attr "mode" "DI")])
2037 (define_insn "muldi3_internal2"
2038 [(set (match_operand:DI 0 "register_operand" "=d")
2039 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
2040 (match_operand:DI 2 "register_operand" "d")))
2041 (clobber (match_scratch:DI 3 "=h"))
2042 (clobber (match_scratch:DI 4 "=l"))
2043 (clobber (match_scratch:DI 5 "=a"))]
2044 "TARGET_64BIT && (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)"
2047 if (GENERATE_MULT3_DI)
2048 output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
2053 xoperands[0] = operands[0];
2054 xoperands[1] = gen_rtx_REG (DImode, LO_REGNUM);
2056 output_asm_insn (\"dmult\\t%1,%2\", operands);
2057 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2061 [(set_attr "type" "imul")
2062 (set_attr "mode" "DI")
2063 (set (attr "length")
2064 (if_then_else (ne (symbol_ref "GENERATE_MULT3_DI") (const_int 0))
2066 (const_int 12)))]) ;; mult + mflo + delay
2068 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
2070 (define_expand "mulsidi3"
2071 [(set (match_operand:DI 0 "register_operand" "=x")
2072 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2073 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
2077 rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
2079 emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
2082 emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
2087 (define_expand "umulsidi3"
2088 [(set (match_operand:DI 0 "register_operand" "=x")
2089 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2090 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
2094 rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
2096 emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
2099 emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
2104 (define_insn "mulsidi3_internal"
2105 [(set (match_operand:DI 0 "register_operand" "=x")
2106 (mult:DI (match_operator:DI 3 "extend_operator"
2107 [(match_operand:SI 1 "register_operand" "d")])
2108 (match_operator:DI 4 "extend_operator"
2109 [(match_operand:SI 2 "register_operand" "d")])))
2110 (clobber (match_scratch:SI 5 "=a"))]
2111 "!TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2114 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2115 return \"mult\\t%1,%2\";
2116 return \"multu\\t%1,%2\";
2118 [(set_attr "type" "imul")
2119 (set_attr "mode" "SI")])
2121 (define_insn "mulsidi3_64bit"
2122 [(set (match_operand:DI 0 "register_operand" "=a")
2123 (mult:DI (match_operator:DI 3 "extend_operator"
2124 [(match_operand:SI 1 "register_operand" "d")])
2125 (match_operator:DI 4 "extend_operator"
2126 [(match_operand:SI 2 "register_operand" "d")])))
2127 (clobber (match_scratch:DI 5 "=l"))
2128 (clobber (match_scratch:DI 6 "=h"))]
2129 "TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2132 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2133 return \"mult\\t%1,%2\";
2134 return \"multu\\t%1,%2\";
2136 [(set_attr "type" "imul")
2137 (set_attr "mode" "SI")])
2139 ;; _highpart patterns
2140 (define_expand "smulsi3_highpart"
2141 [(set (match_operand:SI 0 "register_operand" "=h")
2143 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2144 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2149 rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
2150 rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
2151 #ifndef NO_MD_PROTOTYPES
2152 rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
2156 genfn = gen_xmulsi3_highpart_internal;
2157 emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
2162 (define_expand "umulsi3_highpart"
2163 [(set (match_operand:SI 0 "register_operand" "=h")
2165 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2166 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2171 rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
2172 rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
2173 #ifndef NO_MD_PROTOTYPES
2174 rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
2178 genfn = gen_xmulsi3_highpart_internal;
2179 emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
2184 (define_insn "xmulsi3_highpart_internal"
2185 [(set (match_operand:SI 0 "register_operand" "=h")
2187 (match_operator:DI 5 "highpart_shift_operator"
2188 [(mult:DI (match_operator:DI 3 "extend_operator"
2189 [(match_operand:SI 1 "register_operand" "d")])
2190 (match_operator:DI 4 "extend_operator"
2191 [(match_operand:SI 2 "register_operand" "d")]))
2193 (clobber (match_scratch:SI 6 "=l"))
2194 (clobber (match_scratch:SI 7 "=a"))]
2195 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
2198 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2199 return \"mult\\t%1,%2\";
2201 return \"multu\\t%1,%2\";
2203 [(set_attr "type" "imul")
2204 (set_attr "mode" "SI")])
2206 (define_insn "smuldi3_highpart"
2207 [(set (match_operand:DI 0 "register_operand" "=h")
2209 (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2210 (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
2212 (clobber (match_scratch:DI 3 "=l"))
2213 (clobber (match_scratch:DI 4 "=a"))]
2216 [(set_attr "type" "imul")
2217 (set_attr "mode" "DI")])
2219 (define_insn "umuldi3_highpart"
2220 [(set (match_operand:DI 0 "register_operand" "=h")
2222 (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2223 (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
2225 (clobber (match_scratch:DI 3 "=l"))
2226 (clobber (match_scratch:DI 4 "=a"))]
2229 [(set_attr "type" "imul")
2230 (set_attr "mode" "DI")])
2232 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2233 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
2235 (define_insn "madsi"
2236 [(set (match_operand:SI 0 "register_operand" "+l")
2237 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2238 (match_operand:SI 2 "register_operand" "d"))
2240 (clobber (match_scratch:SI 3 "=h"))
2241 (clobber (match_scratch:SI 4 "=a"))]
2244 [(set_attr "type" "imul")
2245 (set_attr "mode" "SI")])
2247 (define_insn "*mul_acc_di"
2248 [(set (match_operand:DI 0 "register_operand" "+x")
2249 (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2250 [(match_operand:SI 1 "register_operand" "d")])
2251 (match_operator:DI 4 "extend_operator"
2252 [(match_operand:SI 2 "register_operand" "d")]))
2254 (clobber (match_scratch:SI 5 "=a"))]
2257 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2260 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2261 return \"mad\\t%1,%2\";
2263 return \"madu\\t%1,%2\";
2265 [(set_attr "type" "imul")
2266 (set_attr "mode" "SI")])
2268 (define_insn "*mul_acc_64bit_di"
2269 [(set (match_operand:DI 0 "register_operand" "+a")
2270 (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2271 [(match_operand:SI 1 "register_operand" "d")])
2272 (match_operator:DI 4 "extend_operator"
2273 [(match_operand:SI 2 "register_operand" "d")]))
2275 (clobber (match_scratch:SI 5 "=h"))
2276 (clobber (match_scratch:SI 6 "=l"))]
2279 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2282 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2283 return \"mad\\t%1,%2\";
2285 return \"madu\\t%1,%2\";
2287 [(set_attr "type" "imul")
2288 (set_attr "mode" "SI")])
2290 ;; Floating point multiply accumulate instructions.
2293 [(set (match_operand:DF 0 "register_operand" "=f")
2294 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2295 (match_operand:DF 2 "register_operand" "f"))
2296 (match_operand:DF 3 "register_operand" "f")))]
2297 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2298 "madd.d\\t%0,%3,%1,%2"
2299 [(set_attr "type" "fmadd")
2300 (set_attr "mode" "DF")])
2303 [(set (match_operand:SF 0 "register_operand" "=f")
2304 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2305 (match_operand:SF 2 "register_operand" "f"))
2306 (match_operand:SF 3 "register_operand" "f")))]
2307 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2308 "madd.s\\t%0,%3,%1,%2"
2309 [(set_attr "type" "fmadd")
2310 (set_attr "mode" "SF")])
2313 [(set (match_operand:DF 0 "register_operand" "=f")
2314 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2315 (match_operand:DF 2 "register_operand" "f"))
2316 (match_operand:DF 3 "register_operand" "f")))]
2317 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2318 "msub.d\\t%0,%3,%1,%2"
2319 [(set_attr "type" "fmadd")
2320 (set_attr "mode" "DF")])
2323 [(set (match_operand:SF 0 "register_operand" "=f")
2324 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2325 (match_operand:SF 2 "register_operand" "f"))
2326 (match_operand:SF 3 "register_operand" "f")))]
2328 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2329 "msub.s\\t%0,%3,%1,%2"
2330 [(set_attr "type" "fmadd")
2331 (set_attr "mode" "SF")])
2334 [(set (match_operand:DF 0 "register_operand" "=f")
2335 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2336 (match_operand:DF 2 "register_operand" "f"))
2337 (match_operand:DF 3 "register_operand" "f"))))]
2338 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2339 "nmadd.d\\t%0,%3,%1,%2"
2340 [(set_attr "type" "fmadd")
2341 (set_attr "mode" "DF")])
2344 [(set (match_operand:SF 0 "register_operand" "=f")
2345 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2346 (match_operand:SF 2 "register_operand" "f"))
2347 (match_operand:SF 3 "register_operand" "f"))))]
2348 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2349 "nmadd.s\\t%0,%3,%1,%2"
2350 [(set_attr "type" "fmadd")
2351 (set_attr "mode" "SF")])
2354 [(set (match_operand:DF 0 "register_operand" "=f")
2355 (minus:DF (match_operand:DF 1 "register_operand" "f")
2356 (mult:DF (match_operand:DF 2 "register_operand" "f")
2357 (match_operand:DF 3 "register_operand" "f"))))]
2358 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2359 "nmsub.d\\t%0,%1,%2,%3"
2360 [(set_attr "type" "fmadd")
2361 (set_attr "mode" "DF")])
2364 [(set (match_operand:SF 0 "register_operand" "=f")
2365 (minus:SF (match_operand:SF 1 "register_operand" "f")
2366 (mult:SF (match_operand:SF 2 "register_operand" "f")
2367 (match_operand:SF 3 "register_operand" "f"))))]
2368 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2369 "nmsub.s\\t%0,%1,%2,%3"
2370 [(set_attr "type" "fmadd")
2371 (set_attr "mode" "SF")])
2374 ;; ....................
2376 ;; DIVISION and REMAINDER
2378 ;; ....................
2381 (define_insn "divdf3"
2382 [(set (match_operand:DF 0 "register_operand" "=f")
2383 (div:DF (match_operand:DF 1 "register_operand" "f")
2384 (match_operand:DF 2 "register_operand" "f")))]
2385 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2387 [(set_attr "type" "fdiv")
2388 (set_attr "mode" "DF")])
2390 (define_insn "divsf3"
2391 [(set (match_operand:SF 0 "register_operand" "=f")
2392 (div:SF (match_operand:SF 1 "register_operand" "f")
2393 (match_operand:SF 2 "register_operand" "f")))]
2396 [(set_attr "type" "fdiv")
2397 (set_attr "mode" "SF")])
2400 [(set (match_operand:DF 0 "register_operand" "=f")
2401 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2402 (match_operand:DF 2 "register_operand" "f")))]
2403 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2405 [(set_attr "type" "fdiv")
2406 (set_attr "mode" "DF")])
2409 [(set (match_operand:SF 0 "register_operand" "=f")
2410 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2411 (match_operand:SF 2 "register_operand" "f")))]
2412 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2414 [(set_attr "type" "fdiv")
2415 (set_attr "mode" "SF")])
2417 ;; If optimizing, prefer the divmod functions over separate div and
2418 ;; mod functions, since this will allow using one instruction for both
2419 ;; the quotient and remainder. At present, the divmod is not moved out
2420 ;; of loops if it is constant within the loop, so allow -mdebugc to
2421 ;; use the old method of doing things.
2423 ;; 64 is the multiply/divide hi register
2424 ;; 65 is the multiply/divide lo register
2426 ;; ??? We can't accept constants here, because the MIPS assembler will replace
2427 ;; a divide by power of 2 with a shift, and then the remainder is no longer
2430 (define_expand "divmodsi4"
2431 [(set (match_operand:SI 0 "register_operand" "=d")
2432 (div:SI (match_operand:SI 1 "register_operand" "d")
2433 (match_operand:SI 2 "register_operand" "d")))
2434 (set (match_operand:SI 3 "register_operand" "=d")
2435 (mod:SI (match_dup 1)
2437 (clobber (match_scratch:SI 4 "=l"))
2438 (clobber (match_scratch:SI 5 "=h"))
2439 (clobber (match_scratch:SI 6 "=a"))]
2443 emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2],
2445 if (!TARGET_NO_CHECK_ZERO_DIV)
2447 emit_insn (gen_div_trap (operands[2],
2451 if (TARGET_CHECK_RANGE_DIV)
2453 emit_insn (gen_div_trap (operands[2],
2454 copy_to_mode_reg (SImode, GEN_INT (-1)),
2456 emit_insn (gen_div_trap (operands[2],
2457 copy_to_mode_reg (SImode,
2460 (BITMASK_HIGH, SImode))),
2467 (define_insn "divmodsi4_internal"
2468 [(set (match_operand:SI 0 "register_operand" "=l")
2469 (div: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 (mod:SI (match_dup 1)
2474 (clobber (match_scratch:SI 4 "=a"))]
2477 [(set_attr "type" "idiv")
2478 (set_attr "mode" "SI")])
2480 (define_expand "divmoddi4"
2481 [(set (match_operand:DI 0 "register_operand" "=d")
2482 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2483 (match_operand:DI 2 "se_register_operand" "d")))
2484 (set (match_operand:DI 3 "register_operand" "=d")
2485 (mod:DI (match_dup 1)
2487 (clobber (match_scratch:DI 4 "=l"))
2488 (clobber (match_scratch:DI 5 "=h"))
2489 (clobber (match_scratch:DI 6 "=a"))]
2490 "TARGET_64BIT && optimize"
2493 emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2],
2495 if (!TARGET_NO_CHECK_ZERO_DIV)
2497 emit_insn (gen_div_trap (operands[2],
2501 if (TARGET_CHECK_RANGE_DIV)
2503 emit_insn (gen_div_trap (operands[2],
2504 copy_to_mode_reg (DImode, GEN_INT (-1)),
2506 emit_insn (gen_div_trap (operands[2],
2507 copy_to_mode_reg (DImode,
2508 GEN_INT (BITMASK_HIGH)),
2515 (define_insn "divmoddi4_internal"
2516 [(set (match_operand:DI 0 "register_operand" "=l")
2517 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2518 (match_operand:DI 2 "se_register_operand" "d")))
2519 (set (match_operand:DI 3 "register_operand" "=h")
2520 (mod:DI (match_dup 1)
2522 (clobber (match_scratch:DI 4 "=a"))]
2523 "TARGET_64BIT && optimize"
2525 [(set_attr "type" "idiv")
2526 (set_attr "mode" "SI")])
2528 (define_expand "udivmodsi4"
2529 [(set (match_operand:SI 0 "register_operand" "=d")
2530 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2531 (match_operand:SI 2 "register_operand" "d")))
2532 (set (match_operand:SI 3 "register_operand" "=d")
2533 (umod:SI (match_dup 1)
2535 (clobber (match_scratch:SI 4 "=l"))
2536 (clobber (match_scratch:SI 5 "=h"))
2537 (clobber (match_scratch:SI 6 "=a"))]
2541 emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2],
2543 if (!TARGET_NO_CHECK_ZERO_DIV)
2545 emit_insn (gen_div_trap (operands[2],
2553 (define_insn "udivmodsi4_internal"
2554 [(set (match_operand:SI 0 "register_operand" "=l")
2555 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2556 (match_operand:SI 2 "register_operand" "d")))
2557 (set (match_operand:SI 3 "register_operand" "=h")
2558 (umod:SI (match_dup 1)
2560 (clobber (match_scratch:SI 4 "=a"))]
2563 [(set_attr "type" "idiv")
2564 (set_attr "mode" "SI")])
2566 (define_expand "udivmoddi4"
2567 [(set (match_operand:DI 0 "register_operand" "=d")
2568 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2569 (match_operand:DI 2 "se_register_operand" "d")))
2570 (set (match_operand:DI 3 "register_operand" "=d")
2571 (umod:DI (match_dup 1)
2573 (clobber (match_scratch:DI 4 "=l"))
2574 (clobber (match_scratch:DI 5 "=h"))
2575 (clobber (match_scratch:DI 6 "=a"))]
2576 "TARGET_64BIT && optimize"
2579 emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2],
2581 if (!TARGET_NO_CHECK_ZERO_DIV)
2583 emit_insn (gen_div_trap (operands[2],
2591 (define_insn "udivmoddi4_internal"
2592 [(set (match_operand:DI 0 "register_operand" "=l")
2593 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2594 (match_operand:DI 2 "se_register_operand" "d")))
2595 (set (match_operand:DI 3 "register_operand" "=h")
2596 (umod:DI (match_dup 1)
2598 (clobber (match_scratch:DI 4 "=a"))]
2599 "TARGET_64BIT && optimize"
2601 [(set_attr "type" "idiv")
2602 (set_attr "mode" "SI")])
2606 (define_expand "div_trap"
2607 [(trap_if (eq (match_operand 0 "register_operand" "d")
2608 (match_operand 1 "true_reg_or_0_operand" "dJ"))
2609 (match_operand 2 "immediate_operand" ""))]
2614 emit_insn (gen_div_trap_mips16 (operands[0],operands[1],operands[2]));
2616 emit_insn (gen_div_trap_normal (operands[0],operands[1],operands[2]));
2620 (define_insn "div_trap_normal"
2621 [(trap_if (eq (match_operand 0 "register_operand" "d,d")
2622 (match_operand 1 "true_reg_or_0_operand" "d,J"))
2623 (match_operand 2 "immediate_operand" ""))]
2628 int have_dep_anti = 0;
2630 /* For divmod if one division is not needed then we don't need an extra
2631 divide by zero trap, which is anti dependent on previous trap */
2632 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2634 if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2635 && GET_CODE (XEXP (link, 0)) == INSN
2636 && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2637 && which_alternative == 1)
2639 if (! have_dep_anti)
2641 if (GENERATE_BRANCHLIKELY)
2643 if (which_alternative == 1)
2644 return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2646 return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2650 if (which_alternative == 1)
2651 return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2653 return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2658 [(set_attr "type" "unknown")
2659 (set_attr "length" "12")])
2662 ;; The mips16 bne insns is a macro which uses reg 24 as an intermediate.
2664 (define_insn "div_trap_mips16"
2665 [(trap_if (eq (match_operand 0 "register_operand" "d,d")
2666 (match_operand 1 "true_reg_or_0_operand" "d,J"))
2667 (match_operand 2 "immediate_operand" ""))
2668 (clobber (reg:SI 24))]
2673 int have_dep_anti = 0;
2675 /* For divmod if one division is not needed then we don't need an extra
2676 divide by zero trap, which is anti dependent on previous trap */
2677 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2679 if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2680 && GET_CODE (XEXP (link, 0)) == INSN
2681 && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2682 && which_alternative == 1)
2684 if (! have_dep_anti)
2686 /* No branch delay slots on mips16. */
2687 if (which_alternative == 1)
2688 return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2690 return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2694 [(set_attr "type" "unknown")
2695 (set_attr "length" "12")])
2697 (define_expand "divsi3"
2698 [(set (match_operand:SI 0 "register_operand" "=l")
2699 (div:SI (match_operand:SI 1 "register_operand" "d")
2700 (match_operand:SI 2 "register_operand" "d")))
2701 (clobber (match_scratch:SI 3 "=h"))
2702 (clobber (match_scratch:SI 4 "=a"))]
2706 emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2]));
2707 if (!TARGET_NO_CHECK_ZERO_DIV)
2709 emit_insn (gen_div_trap (operands[2],
2713 if (TARGET_CHECK_RANGE_DIV)
2715 emit_insn (gen_div_trap (operands[2],
2716 copy_to_mode_reg (SImode, GEN_INT (-1)),
2718 emit_insn (gen_div_trap (operands[2],
2719 copy_to_mode_reg (SImode,
2722 (BITMASK_HIGH, SImode))),
2729 (define_insn "divsi3_internal"
2730 [(set (match_operand:SI 0 "register_operand" "=l")
2731 (div:SI (match_operand:SI 1 "register_operand" "d")
2732 (match_operand:SI 2 "nonmemory_operand" "di")))
2733 (clobber (match_scratch:SI 3 "=h"))
2734 (clobber (match_scratch:SI 4 "=a"))]
2737 [(set_attr "type" "idiv")
2738 (set_attr "mode" "SI")])
2740 (define_expand "divdi3"
2741 [(set (match_operand:DI 0 "register_operand" "=l")
2742 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2743 (match_operand:DI 2 "se_register_operand" "d")))
2744 (clobber (match_scratch:DI 3 "=h"))
2745 (clobber (match_scratch:DI 4 "=a"))]
2746 "TARGET_64BIT && !optimize"
2749 emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2]));
2750 if (!TARGET_NO_CHECK_ZERO_DIV)
2752 emit_insn (gen_div_trap (operands[2],
2756 if (TARGET_CHECK_RANGE_DIV)
2758 emit_insn (gen_div_trap (operands[2],
2759 copy_to_mode_reg (DImode, GEN_INT (-1)),
2761 emit_insn (gen_div_trap (operands[2],
2762 copy_to_mode_reg (DImode,
2763 GEN_INT (BITMASK_HIGH)),
2770 (define_insn "divdi3_internal"
2771 [(set (match_operand:DI 0 "register_operand" "=l")
2772 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2773 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2774 (clobber (match_scratch:SI 3 "=h"))
2775 (clobber (match_scratch:SI 4 "=a"))]
2776 "TARGET_64BIT && !optimize"
2778 [(set_attr "type" "idiv")
2779 (set_attr "mode" "DI")])
2781 (define_expand "modsi3"
2782 [(set (match_operand:SI 0 "register_operand" "=h")
2783 (mod:SI (match_operand:SI 1 "register_operand" "d")
2784 (match_operand:SI 2 "register_operand" "d")))
2785 (clobber (match_scratch:SI 3 "=l"))
2786 (clobber (match_scratch:SI 4 "=a"))]
2790 emit_insn (gen_modsi3_internal (operands[0], operands[1], operands[2]));
2791 if (!TARGET_NO_CHECK_ZERO_DIV)
2793 emit_insn (gen_div_trap (operands[2],
2797 if (TARGET_CHECK_RANGE_DIV)
2799 emit_insn (gen_div_trap (operands[2],
2800 copy_to_mode_reg (SImode, GEN_INT (-1)),
2802 emit_insn (gen_div_trap (operands[2],
2803 copy_to_mode_reg (SImode,
2806 (BITMASK_HIGH, SImode))),
2813 (define_insn "modsi3_internal"
2814 [(set (match_operand:SI 0 "register_operand" "=h")
2815 (mod:SI (match_operand:SI 1 "register_operand" "d")
2816 (match_operand:SI 2 "nonmemory_operand" "di")))
2817 (clobber (match_scratch:SI 3 "=l"))
2818 (clobber (match_scratch:SI 4 "=a"))]
2821 [(set_attr "type" "idiv")
2822 (set_attr "mode" "SI")])
2824 (define_expand "moddi3"
2825 [(set (match_operand:DI 0 "register_operand" "=h")
2826 (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2827 (match_operand:DI 2 "se_register_operand" "d")))
2828 (clobber (match_scratch:DI 3 "=l"))
2829 (clobber (match_scratch:DI 4 "=a"))]
2830 "TARGET_64BIT && !optimize"
2833 emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2]));
2834 if (!TARGET_NO_CHECK_ZERO_DIV)
2836 emit_insn (gen_div_trap (operands[2],
2840 if (TARGET_CHECK_RANGE_DIV)
2842 emit_insn (gen_div_trap (operands[2],
2843 copy_to_mode_reg (DImode, GEN_INT (-1)),
2845 emit_insn (gen_div_trap (operands[2],
2846 copy_to_mode_reg (DImode,
2847 GEN_INT (BITMASK_HIGH)),
2854 (define_insn "moddi3_internal"
2855 [(set (match_operand:DI 0 "register_operand" "=h")
2856 (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2857 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2858 (clobber (match_scratch:SI 3 "=l"))
2859 (clobber (match_scratch:SI 4 "=a"))]
2860 "TARGET_64BIT && !optimize"
2862 [(set_attr "type" "idiv")
2863 (set_attr "mode" "DI")])
2865 (define_expand "udivsi3"
2866 [(set (match_operand:SI 0 "register_operand" "=l")
2867 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2868 (match_operand:SI 2 "register_operand" "d")))
2869 (clobber (match_scratch:SI 3 "=h"))
2870 (clobber (match_scratch:SI 4 "=a"))]
2874 emit_insn (gen_udivsi3_internal (operands[0], operands[1], operands[2]));
2875 if (!TARGET_NO_CHECK_ZERO_DIV)
2877 emit_insn (gen_div_trap (operands[2],
2885 (define_insn "udivsi3_internal"
2886 [(set (match_operand:SI 0 "register_operand" "=l")
2887 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2888 (match_operand:SI 2 "nonmemory_operand" "di")))
2889 (clobber (match_scratch:SI 3 "=h"))
2890 (clobber (match_scratch:SI 4 "=a"))]
2893 [(set_attr "type" "idiv")
2894 (set_attr "mode" "SI")])
2896 (define_expand "udivdi3"
2897 [(set (match_operand:DI 0 "register_operand" "=l")
2898 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2899 (match_operand:DI 2 "se_register_operand" "di")))
2900 (clobber (match_scratch:DI 3 "=h"))
2901 (clobber (match_scratch:DI 4 "=a"))]
2902 "TARGET_64BIT && !optimize"
2905 emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2]));
2906 if (!TARGET_NO_CHECK_ZERO_DIV)
2908 emit_insn (gen_div_trap (operands[2],
2916 (define_insn "udivdi3_internal"
2917 [(set (match_operand:DI 0 "register_operand" "=l")
2918 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2919 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2920 (clobber (match_scratch:SI 3 "=h"))
2921 (clobber (match_scratch:SI 4 "=a"))]
2922 "TARGET_64BIT && !optimize"
2924 [(set_attr "type" "idiv")
2925 (set_attr "mode" "DI")])
2927 (define_expand "umodsi3"
2928 [(set (match_operand:SI 0 "register_operand" "=h")
2929 (umod:SI (match_operand:SI 1 "register_operand" "d")
2930 (match_operand:SI 2 "register_operand" "d")))
2931 (clobber (match_scratch:SI 3 "=l"))
2932 (clobber (match_scratch:SI 4 "=a"))]
2936 emit_insn (gen_umodsi3_internal (operands[0], operands[1], operands[2]));
2937 if (!TARGET_NO_CHECK_ZERO_DIV)
2939 emit_insn (gen_div_trap (operands[2],
2947 (define_insn "umodsi3_internal"
2948 [(set (match_operand:SI 0 "register_operand" "=h")
2949 (umod:SI (match_operand:SI 1 "register_operand" "d")
2950 (match_operand:SI 2 "nonmemory_operand" "di")))
2951 (clobber (match_scratch:SI 3 "=l"))
2952 (clobber (match_scratch:SI 4 "=a"))]
2955 [(set_attr "type" "idiv")
2956 (set_attr "mode" "SI")])
2958 (define_expand "umoddi3"
2959 [(set (match_operand:DI 0 "register_operand" "=h")
2960 (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2961 (match_operand:DI 2 "se_register_operand" "di")))
2962 (clobber (match_scratch:DI 3 "=l"))
2963 (clobber (match_scratch:DI 4 "=a"))]
2964 "TARGET_64BIT && !optimize"
2967 emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2]));
2968 if (!TARGET_NO_CHECK_ZERO_DIV)
2970 emit_insn (gen_div_trap (operands[2],
2978 (define_insn "umoddi3_internal"
2979 [(set (match_operand:DI 0 "register_operand" "=h")
2980 (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2981 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2982 (clobber (match_scratch:SI 3 "=l"))
2983 (clobber (match_scratch:SI 4 "=a"))]
2984 "TARGET_64BIT && !optimize"
2986 [(set_attr "type" "idiv")
2987 (set_attr "mode" "DI")])
2990 ;; ....................
2994 ;; ....................
2996 (define_insn "sqrtdf2"
2997 [(set (match_operand:DF 0 "register_operand" "=f")
2998 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2999 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
3001 [(set_attr "type" "fsqrt")
3002 (set_attr "mode" "DF")])
3004 (define_insn "sqrtsf2"
3005 [(set (match_operand:SF 0 "register_operand" "=f")
3006 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
3007 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
3009 [(set_attr "type" "fsqrt")
3010 (set_attr "mode" "SF")])
3013 [(set (match_operand:DF 0 "register_operand" "=f")
3014 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
3015 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
3016 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
3018 [(set_attr "type" "fsqrt")
3019 (set_attr "mode" "DF")])
3022 [(set (match_operand:SF 0 "register_operand" "=f")
3023 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
3024 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
3025 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
3027 [(set_attr "type" "fsqrt")
3028 (set_attr "mode" "SF")])
3032 ;; ....................
3036 ;; ....................
3038 ;; Do not use the integer abs macro instruction, since that signals an
3039 ;; exception on -2147483648 (sigh).
3041 (define_insn "abssi2"
3042 [(set (match_operand:SI 0 "register_operand" "=d")
3043 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
3047 dslots_jump_total++;
3048 dslots_jump_filled++;
3049 operands[2] = const0_rtx;
3051 if (REGNO (operands[0]) == REGNO (operands[1]))
3053 if (GENERATE_BRANCHLIKELY)
3054 return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
3056 return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n%~1:\";
3059 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
3061 [(set_attr "type" "multi")
3062 (set_attr "mode" "SI")
3063 (set_attr "length" "12")])
3065 (define_insn "absdi2"
3066 [(set (match_operand:DI 0 "register_operand" "=d")
3067 (abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
3068 "TARGET_64BIT && !TARGET_MIPS16"
3071 unsigned int regno1;
3072 dslots_jump_total++;
3073 dslots_jump_filled++;
3074 operands[2] = const0_rtx;
3076 if (GET_CODE (operands[1]) == REG)
3077 regno1 = REGNO (operands[1]);
3079 regno1 = REGNO (XEXP (operands[1], 0));
3081 if (REGNO (operands[0]) == regno1)
3082 return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
3084 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
3086 [(set_attr "type" "multi")
3087 (set_attr "mode" "DI")
3088 (set_attr "length" "12")])
3090 (define_insn "absdf2"
3091 [(set (match_operand:DF 0 "register_operand" "=f")
3092 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
3093 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3095 [(set_attr "type" "fabs")
3096 (set_attr "mode" "DF")])
3098 (define_insn "abssf2"
3099 [(set (match_operand:SF 0 "register_operand" "=f")
3100 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
3103 [(set_attr "type" "fabs")
3104 (set_attr "mode" "SF")])
3108 ;; ....................
3110 ;; FIND FIRST BIT INSTRUCTION
3112 ;; ....................
3115 (define_insn "ffssi2"
3116 [(set (match_operand:SI 0 "register_operand" "=&d")
3117 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
3118 (clobber (match_scratch:SI 2 "=&d"))
3119 (clobber (match_scratch:SI 3 "=&d"))]
3123 dslots_jump_total += 2;
3124 dslots_jump_filled += 2;
3125 operands[4] = const0_rtx;
3127 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3130 \\tbeq\\t%1,%z4,2f\\n\\
3131 %~1:\\tand\\t%2,%1,0x0001\\n\\
3132 \\taddu\\t%0,%0,1\\n\\
3133 \\tbeq\\t%2,%z4,1b\\n\\
3134 \\tsrl\\t%1,%1,1\\n\\
3139 \\tmove\\t%3,%1\\n\\
3140 \\tbeq\\t%3,%z4,2f\\n\\
3141 %~1:\\tand\\t%2,%3,0x0001\\n\\
3142 \\taddu\\t%0,%0,1\\n\\
3143 \\tbeq\\t%2,%z4,1b\\n\\
3144 \\tsrl\\t%3,%3,1\\n\\
3147 [(set_attr "type" "multi")
3148 (set_attr "mode" "SI")
3149 (set_attr "length" "12")])
3151 (define_insn "ffsdi2"
3152 [(set (match_operand:DI 0 "register_operand" "=&d")
3153 (ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
3154 (clobber (match_scratch:DI 2 "=&d"))
3155 (clobber (match_scratch:DI 3 "=&d"))]
3156 "TARGET_64BIT && !TARGET_MIPS16"
3159 dslots_jump_total += 2;
3160 dslots_jump_filled += 2;
3161 operands[4] = const0_rtx;
3163 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3166 \\tbeq\\t%1,%z4,2f\\n\\
3167 %~1:\\tand\\t%2,%1,0x0001\\n\\
3168 \\tdaddu\\t%0,%0,1\\n\\
3169 \\tbeq\\t%2,%z4,1b\\n\\
3170 \\tdsrl\\t%1,%1,1\\n\\
3175 \\tmove\\t%3,%1\\n\\
3176 \\tbeq\\t%3,%z4,2f\\n\\
3177 %~1:\\tand\\t%2,%3,0x0001\\n\\
3178 \\tdaddu\\t%0,%0,1\\n\\
3179 \\tbeq\\t%2,%z4,1b\\n\\
3180 \\tdsrl\\t%3,%3,1\\n\\
3183 [(set_attr "type" "multi")
3184 (set_attr "mode" "DI")
3185 (set_attr "length" "24")])
3189 ;; ....................
3191 ;; NEGATION and ONE'S COMPLEMENT
3193 ;; ....................
3195 (define_insn "negsi2"
3196 [(set (match_operand:SI 0 "register_operand" "=d")
3197 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
3202 return \"neg\\t%0,%1\";
3203 operands[2] = const0_rtx;
3204 return \"subu\\t%0,%z2,%1\";
3206 [(set_attr "type" "arith")
3207 (set_attr "mode" "SI")])
3209 (define_expand "negdi2"
3210 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
3211 (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
3212 (clobber (match_dup 2))])]
3213 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3218 emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
3222 operands[2] = gen_reg_rtx (SImode);
3225 (define_insn "negdi2_internal"
3226 [(set (match_operand:DI 0 "register_operand" "=d")
3227 (neg:DI (match_operand:DI 1 "register_operand" "d")))
3228 (clobber (match_operand:SI 2 "register_operand" "=d"))]
3229 "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
3232 operands[3] = const0_rtx;
3233 return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
3235 [(set_attr "type" "darith")
3236 (set_attr "mode" "DI")
3237 (set_attr "length" "16")])
3239 (define_insn "negdi2_internal_2"
3240 [(set (match_operand:DI 0 "register_operand" "=d")
3241 (neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
3242 "TARGET_64BIT && !TARGET_MIPS16"
3245 operands[2] = const0_rtx;
3246 return \"dsubu\\t%0,%z2,%1\";
3248 [(set_attr "type" "arith")
3249 (set_attr "mode" "DI")])
3251 (define_insn "negdf2"
3252 [(set (match_operand:DF 0 "register_operand" "=f")
3253 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
3254 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3256 [(set_attr "type" "fneg")
3257 (set_attr "mode" "DF")])
3259 (define_insn "negsf2"
3260 [(set (match_operand:SF 0 "register_operand" "=f")
3261 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3264 [(set_attr "type" "fneg")
3265 (set_attr "mode" "SF")])
3267 (define_insn "one_cmplsi2"
3268 [(set (match_operand:SI 0 "register_operand" "=d")
3269 (not:SI (match_operand:SI 1 "register_operand" "d")))]
3274 return \"not\\t%0,%1\";
3275 operands[2] = const0_rtx;
3276 return \"nor\\t%0,%z2,%1\";
3278 [(set_attr "type" "arith")
3279 (set_attr "mode" "SI")])
3281 (define_insn "one_cmpldi2"
3282 [(set (match_operand:DI 0 "register_operand" "=d")
3283 (not:DI (match_operand:DI 1 "se_register_operand" "d")))]
3290 return \"not\\t%0,%1\";
3291 return \"not\\t%M0,%M1\;not\\t%L0,%L1\";
3293 operands[2] = const0_rtx;
3295 return \"nor\\t%0,%z2,%1\";
3296 return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
3298 [(set_attr "type" "darith")
3299 (set_attr "mode" "DI")
3300 (set (attr "length")
3301 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3306 [(set (match_operand:DI 0 "register_operand" "")
3307 (not:DI (match_operand:DI 1 "register_operand" "")))]
3308 "reload_completed && !TARGET_64BIT
3309 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3310 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3311 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3313 [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
3314 (set (subreg:SI (match_dup 0) 4) (not:SI (subreg:SI (match_dup 1) 4)))]
3319 ;; ....................
3323 ;; ....................
3326 ;; Many of these instructions uses trivial define_expands, because we
3327 ;; want to use a different set of constraints when TARGET_MIPS16.
3329 (define_expand "andsi3"
3330 [(set (match_operand:SI 0 "register_operand" "=d,d")
3331 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3332 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3338 operands[1] = force_reg (SImode, operands[1]);
3339 operands[2] = force_reg (SImode, operands[2]);
3344 [(set (match_operand:SI 0 "register_operand" "=d,d")
3345 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3346 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3351 [(set_attr "type" "arith")
3352 (set_attr "mode" "SI")])
3355 [(set (match_operand:SI 0 "register_operand" "=d")
3356 (and:SI (match_operand:SI 1 "register_operand" "%0")
3357 (match_operand:SI 2 "register_operand" "d")))]
3360 [(set_attr "type" "arith")
3361 (set_attr "mode" "SI")])
3363 (define_expand "anddi3"
3364 [(set (match_operand:DI 0 "register_operand" "=d")
3365 (and:DI (match_operand:DI 1 "se_register_operand" "d")
3366 (match_operand:DI 2 "se_register_operand" "d")))]
3367 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3372 operands[1] = force_reg (DImode, operands[1]);
3373 operands[2] = force_reg (DImode, operands[2]);
3378 [(set (match_operand:DI 0 "register_operand" "=d")
3379 (and:DI (match_operand:DI 1 "se_register_operand" "d")
3380 (match_operand:DI 2 "se_register_operand" "d")))]
3381 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3385 return \"and\\t%0,%1,%2\";
3386 return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
3388 [(set_attr "type" "darith")
3389 (set_attr "mode" "DI")
3390 (set (attr "length")
3391 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3396 [(set (match_operand:DI 0 "register_operand" "=d")
3397 (and:DI (match_operand:DI 1 "se_register_operand" "0")
3398 (match_operand:DI 2 "se_register_operand" "d")))]
3399 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3403 return \"and\\t%0,%2\";
3404 return \"and\\t%M0,%M2\;and\\t%L0,%L2\";
3406 [(set_attr "type" "darith")
3407 (set_attr "mode" "DI")
3408 (set (attr "length")
3409 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3414 [(set (match_operand:DI 0 "register_operand" "")
3415 (and:DI (match_operand:DI 1 "register_operand" "")
3416 (match_operand:DI 2 "register_operand" "")))]
3417 "reload_completed && !TARGET_64BIT
3418 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3419 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3420 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3421 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3423 [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3424 (set (subreg:SI (match_dup 0) 4) (and:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3427 (define_insn "anddi3_internal1"
3428 [(set (match_operand:DI 0 "register_operand" "=d,d")
3429 (and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
3430 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
3431 "TARGET_64BIT && !TARGET_MIPS16"
3435 [(set_attr "type" "arith")
3436 (set_attr "mode" "DI")])
3438 (define_expand "iorsi3"
3439 [(set (match_operand:SI 0 "register_operand" "=d,d")
3440 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3441 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3447 operands[1] = force_reg (SImode, operands[1]);
3448 operands[2] = force_reg (SImode, operands[2]);
3453 [(set (match_operand:SI 0 "register_operand" "=d,d")
3454 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3455 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3460 [(set_attr "type" "arith")
3461 (set_attr "mode" "SI")])
3464 [(set (match_operand:SI 0 "register_operand" "=d")
3465 (ior:SI (match_operand:SI 1 "register_operand" "%0")
3466 (match_operand:SI 2 "register_operand" "d")))]
3469 [(set_attr "type" "arith")
3470 (set_attr "mode" "SI")])
3472 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
3475 (define_expand "iordi3"
3476 [(set (match_operand:DI 0 "register_operand" "=d")
3477 (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3478 (match_operand:DI 2 "se_register_operand" "d")))]
3479 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3483 [(set (match_operand:DI 0 "register_operand" "=d")
3484 (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3485 (match_operand:DI 2 "se_register_operand" "d")))]
3486 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3490 return \"or\\t%0,%1,%2\";
3491 return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
3493 [(set_attr "type" "darith")
3494 (set_attr "mode" "DI")
3495 (set (attr "length")
3496 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3501 [(set (match_operand:DI 0 "register_operand" "=d")
3502 (ior:DI (match_operand:DI 1 "se_register_operand" "0")
3503 (match_operand:DI 2 "se_register_operand" "d")))]
3504 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3508 return \"or\\t%0,%2\";
3509 return \"or\\t%M0,%M2\;or\\t%L0,%L2\";
3511 [(set_attr "type" "darith")
3512 (set_attr "mode" "DI")
3513 (set (attr "length")
3514 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3519 [(set (match_operand:DI 0 "register_operand" "")
3520 (ior:DI (match_operand:DI 1 "register_operand" "")
3521 (match_operand:DI 2 "register_operand" "")))]
3522 "reload_completed && !TARGET_64BIT
3523 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3524 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3525 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3526 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3528 [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3529 (set (subreg:SI (match_dup 0) 4) (ior:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3532 (define_expand "xorsi3"
3533 [(set (match_operand:SI 0 "register_operand" "=d,d")
3534 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3535 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3540 [(set (match_operand:SI 0 "register_operand" "=d,d")
3541 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3542 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3547 [(set_attr "type" "arith")
3548 (set_attr "mode" "SI")])
3551 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3552 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3553 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3559 [(set_attr "type" "arith")
3560 (set_attr "mode" "SI")
3561 (set_attr_alternative "length"
3563 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3568 ;; ??? If delete the 32-bit long long patterns, then could merge this with
3569 ;; the following xordi3_internal pattern.
3570 (define_expand "xordi3"
3571 [(set (match_operand:DI 0 "register_operand" "=d")
3572 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3573 (match_operand:DI 2 "se_register_operand" "d")))]
3574 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3578 [(set (match_operand:DI 0 "register_operand" "=d")
3579 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3580 (match_operand:DI 2 "se_register_operand" "d")))]
3581 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3585 return \"xor\\t%0,%1,%2\";
3586 return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
3588 [(set_attr "type" "darith")
3589 (set_attr "mode" "DI")
3590 (set (attr "length")
3591 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3596 [(set (match_operand:DI 0 "register_operand" "=d")
3597 (xor:DI (match_operand:DI 1 "se_register_operand" "0")
3598 (match_operand:DI 2 "se_register_operand" "d")))]
3599 "!TARGET_64BIT && TARGET_MIPS16"
3600 "xor\\t%M0,%M2\;xor\\t%L0,%L2"
3601 [(set_attr "type" "darith")
3602 (set_attr "mode" "DI")
3603 (set_attr "length" "8")])
3606 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3607 (xor:DI (match_operand:DI 1 "se_register_operand" "%0,d,d")
3608 (match_operand:DI 2 "se_uns_arith_operand" "d,K,d")))]
3609 "TARGET_64BIT && TARGET_MIPS16"
3614 [(set_attr "type" "arith")
3615 (set_attr "mode" "DI")
3616 (set_attr_alternative "length"
3618 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3624 [(set (match_operand:DI 0 "register_operand" "")
3625 (xor:DI (match_operand:DI 1 "register_operand" "")
3626 (match_operand:DI 2 "register_operand" "")))]
3627 "reload_completed && !TARGET_64BIT
3628 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3629 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3630 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3631 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3633 [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3634 (set (subreg:SI (match_dup 0) 4) (xor:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3637 (define_insn "xordi3_immed"
3638 [(set (match_operand:DI 0 "register_operand" "=d")
3639 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3640 (match_operand:DI 2 "se_uns_arith_operand" "K")))]
3641 "TARGET_64BIT && !TARGET_MIPS16"
3643 [(set_attr "type" "arith")
3644 (set_attr "mode" "DI")])
3646 (define_insn "*norsi3"
3647 [(set (match_operand:SI 0 "register_operand" "=d")
3648 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3649 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3652 [(set_attr "type" "arith")
3653 (set_attr "mode" "SI")])
3655 (define_insn "*nordi3"
3656 [(set (match_operand:DI 0 "register_operand" "=d")
3657 (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
3658 (not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
3663 return \"nor\\t%0,%z1,%z2\";
3664 return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
3666 [(set_attr "type" "darith")
3667 (set_attr "mode" "DI")
3668 (set (attr "length")
3669 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3674 [(set (match_operand:DI 0 "register_operand" "")
3675 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
3676 (not:DI (match_operand:DI 2 "register_operand" ""))))]
3677 "reload_completed && !TARGET_MIPS16 && !TARGET_64BIT
3678 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3679 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3680 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3681 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3683 [(set (subreg:SI (match_dup 0) 0) (and:SI (not:SI (subreg:SI (match_dup 1) 0)) (not:SI (subreg:SI (match_dup 2) 0))))
3684 (set (subreg:SI (match_dup 0) 4) (and:SI (not:SI (subreg:SI (match_dup 1) 4)) (not:SI (subreg:SI (match_dup 2) 4))))]
3688 ;; ....................
3692 ;; ....................
3694 (define_insn "truncdfsf2"
3695 [(set (match_operand:SF 0 "register_operand" "=f")
3696 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3697 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3699 [(set_attr "type" "fcvt")
3700 (set_attr "mode" "SF")])
3702 (define_insn "truncdisi2"
3703 [(set (match_operand:SI 0 "register_operand" "=d")
3704 (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
3709 return \"dsll\\t%0,%1,32\;dsra\\t%0,32\";
3710 return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\";
3712 [(set_attr "type" "darith")
3713 (set_attr "mode" "SI")
3714 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3718 (define_insn "truncdihi2"
3719 [(set (match_operand:HI 0 "register_operand" "=d")
3720 (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
3725 return \"dsll\\t%0,%1,48\;dsra\\t%0,48\";
3726 return \"andi\\t%0,%1,0xffff\";
3728 [(set_attr "type" "darith")
3729 (set_attr "mode" "HI")
3730 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3733 (define_insn "truncdiqi2"
3734 [(set (match_operand:QI 0 "register_operand" "=d")
3735 (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
3740 return \"dsll\\t%0,%1,56\;dsra\\t%0,56\";
3741 return \"andi\\t%0,%1,0x00ff\";
3743 [(set_attr "type" "darith")
3744 (set_attr "mode" "QI")
3745 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3749 ;; Combiner patterns to optimize shift/truncate combinations.
3751 [(set (match_operand:SI 0 "register_operand" "=d")
3752 (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3753 (match_operand:DI 2 "small_int" "I"))))]
3754 "TARGET_64BIT && !TARGET_MIPS16"
3757 int shift_amt = INTVAL (operands[2]) & 0x3f;
3761 operands[2] = GEN_INT (32 - shift_amt);
3762 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3766 operands[2] = GEN_INT (shift_amt);
3767 return \"dsra\\t%0,%1,%2\";
3770 [(set_attr "type" "darith")
3771 (set_attr "mode" "SI")
3772 (set_attr "length" "8")])
3775 [(set (match_operand:SI 0 "register_operand" "=d")
3776 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3777 (match_operand:DI 2 "small_int" "I"))))]
3778 "TARGET_64BIT && !TARGET_MIPS16"
3781 int shift_amt = INTVAL (operands[2]) & 0x3f;
3785 operands[2] = GEN_INT (32 - shift_amt);
3786 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3788 else if (shift_amt == 32)
3789 return \"dsra\\t%0,%1,32\";
3792 operands[2] = GEN_INT (shift_amt);
3793 return \"dsrl\\t%0,%1,%2\";
3796 [(set_attr "type" "darith")
3797 (set_attr "mode" "SI")
3798 (set_attr "length" "8")])
3801 [(set (match_operand:SI 0 "register_operand" "=d")
3802 (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
3803 (match_operand:DI 2 "small_int" "I"))))]
3807 int shift_amt = INTVAL (operands[2]) & 0x3f;
3811 operands[2] = GEN_INT (32 + shift_amt);
3813 return \"dsll\\t%0,%1,%2\;dsra\\t%0,32\";
3814 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3817 return \"move\\t%0,%.\";
3819 [(set_attr "type" "darith")
3820 (set_attr "mode" "SI")
3821 (set_attr "length" "8")])
3823 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3826 [(set (match_operand:SI 0 "register_operand" "=d")
3827 (zero_extend:SI (truncate:HI
3828 (match_operand:DI 1 "se_register_operand" "d"))))]
3829 "TARGET_64BIT && !TARGET_MIPS16"
3830 "andi\\t%0,%1,0xffff"
3831 [(set_attr "type" "darith")
3832 (set_attr "mode" "SI")])
3835 [(set (match_operand:SI 0 "register_operand" "=d")
3836 (zero_extend:SI (truncate:QI
3837 (match_operand:DI 1 "se_register_operand" "d"))))]
3838 "TARGET_64BIT && !TARGET_MIPS16"
3840 [(set_attr "type" "darith")
3841 (set_attr "mode" "SI")])
3844 [(set (match_operand:HI 0 "register_operand" "=d")
3845 (zero_extend:HI (truncate:QI
3846 (match_operand:DI 1 "se_register_operand" "d"))))]
3847 "TARGET_64BIT && !TARGET_MIPS16"
3849 [(set_attr "type" "darith")
3850 (set_attr "mode" "HI")])
3853 ;; ....................
3857 ;; ....................
3860 ;; Those for integer source operand are ordered widest source type first.
3862 (define_expand "zero_extendsidi2"
3863 [(set (match_operand:DI 0 "register_operand" "")
3864 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3868 if ((optimize || TARGET_MIPS16) && GET_CODE (operands[1]) == MEM)
3869 operands[1] = force_not_mem (operands[1]);
3871 if (GET_CODE (operands[1]) != MEM)
3873 rtx op1 = gen_lowpart (DImode, operands[1]);
3874 rtx temp = gen_reg_rtx (DImode);
3875 rtx shift = GEN_INT (32);
3877 emit_insn (gen_ashldi3 (temp, op1, shift));
3878 emit_insn (gen_lshrdi3 (operands[0], temp, shift));
3883 (define_insn "zero_extendsidi2_internal"
3884 [(set (match_operand:DI 0 "register_operand" "=d,d")
3885 (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
3886 "TARGET_64BIT && !TARGET_MIPS16"
3887 "* return mips_move_1word (operands, insn, TRUE);"
3888 [(set_attr "type" "load")
3889 (set_attr "mode" "DI")
3890 (set_attr "length" "4,8")])
3892 (define_expand "zero_extendhisi2"
3893 [(set (match_operand:SI 0 "register_operand" "")
3894 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3898 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3900 rtx op = gen_lowpart (SImode, operands[1]);
3901 rtx temp = force_reg (SImode, GEN_INT (0xffff));
3903 emit_insn (gen_andsi3 (operands[0], op, temp));
3909 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3910 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3914 if (which_alternative == 0)
3915 return \"andi\\t%0,%1,0xffff\";
3917 return mips_move_1word (operands, insn, TRUE);
3919 [(set_attr "type" "arith,load,load")
3920 (set_attr "mode" "SI")
3921 (set_attr "length" "4,4,8")])
3924 [(set (match_operand:SI 0 "register_operand" "=d,d")
3925 (zero_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3927 "* return mips_move_1word (operands, insn, TRUE);"
3928 [(set_attr "type" "load,load")
3929 (set_attr "mode" "SI")
3930 (set_attr "length" "4,8")])
3932 (define_expand "zero_extendhidi2"
3933 [(set (match_operand:DI 0 "register_operand" "")
3934 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3938 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3940 rtx op = gen_lowpart (DImode, operands[1]);
3941 rtx temp = force_reg (DImode, GEN_INT (0xffff));
3943 emit_insn (gen_anddi3 (operands[0], op, temp));
3949 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3950 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3951 "TARGET_64BIT && !TARGET_MIPS16"
3954 if (which_alternative == 0)
3955 return \"andi\\t%0,%1,0xffff\";
3957 return mips_move_1word (operands, insn, TRUE);
3959 [(set_attr "type" "arith,load,load")
3960 (set_attr "mode" "DI")
3961 (set_attr "length" "4,4,8")])
3964 [(set (match_operand:DI 0 "register_operand" "=d,d")
3965 (zero_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3966 "TARGET_64BIT && TARGET_MIPS16"
3967 "* return mips_move_1word (operands, insn, TRUE);"
3968 [(set_attr "type" "load,load")
3969 (set_attr "mode" "DI")
3970 (set_attr "length" "4,8")])
3972 (define_expand "zero_extendqihi2"
3973 [(set (match_operand:HI 0 "register_operand" "")
3974 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3978 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3980 rtx op0 = gen_lowpart (SImode, operands[0]);
3981 rtx op1 = gen_lowpart (SImode, operands[1]);
3982 rtx temp = force_reg (SImode, GEN_INT (0xff));
3984 emit_insn (gen_andsi3 (op0, op1, temp));
3990 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
3991 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3995 if (which_alternative == 0)
3996 return \"andi\\t%0,%1,0x00ff\";
3998 return mips_move_1word (operands, insn, TRUE);
4000 [(set_attr "type" "arith,load,load")
4001 (set_attr "mode" "HI")
4002 (set_attr "length" "4,4,8")])
4005 [(set (match_operand:HI 0 "register_operand" "=d,d")
4006 (zero_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
4008 "* return mips_move_1word (operands, insn, TRUE);"
4009 [(set_attr "type" "load,load")
4010 (set_attr "mode" "HI")
4011 (set_attr "length" "4,8")])
4013 (define_expand "zero_extendqisi2"
4014 [(set (match_operand:SI 0 "register_operand" "")
4015 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4019 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4021 rtx op = gen_lowpart (SImode, operands[1]);
4022 rtx temp = force_reg (SImode, GEN_INT (0xff));
4024 emit_insn (gen_andsi3 (operands[0], op, temp));
4030 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
4031 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
4035 if (which_alternative == 0)
4036 return \"andi\\t%0,%1,0x00ff\";
4038 return mips_move_1word (operands, insn, TRUE);
4040 [(set_attr "type" "arith,load,load")
4041 (set_attr "mode" "SI")
4042 (set_attr "length" "4,4,8")])
4045 [(set (match_operand:SI 0 "register_operand" "=d,d")
4046 (zero_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
4048 "* return mips_move_1word (operands, insn, TRUE);"
4049 [(set_attr "type" "load,load")
4050 (set_attr "mode" "SI")
4051 (set_attr "length" "4,8")])
4053 (define_expand "zero_extendqidi2"
4054 [(set (match_operand:DI 0 "register_operand" "")
4055 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4059 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4061 rtx op = gen_lowpart (DImode, operands[1]);
4062 rtx temp = force_reg (DImode, GEN_INT (0xff));
4064 emit_insn (gen_anddi3 (operands[0], op, temp));
4070 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4071 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
4072 "TARGET_64BIT && !TARGET_MIPS16"
4075 if (which_alternative == 0)
4076 return \"andi\\t%0,%1,0x00ff\";
4078 return mips_move_1word (operands, insn, TRUE);
4080 [(set_attr "type" "arith,load,load")
4081 (set_attr "mode" "DI")
4082 (set_attr "length" "4,4,8")])
4084 ;; These can be created when a paradoxical subreg operand with an implicit
4085 ;; sign_extend operator is reloaded. Because of the subreg, this is really
4087 ;; ??? It might be possible to eliminate the need for these patterns by adding
4088 ;; more support to reload for implicit sign_extend operators.
4089 (define_insn "*paradoxical_extendhidi2"
4090 [(set (match_operand:DI 0 "register_operand" "=d,d")
4092 (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
4096 return mips_move_1word (operands, insn, TRUE);
4098 [(set_attr "type" "load,load")
4099 (set_attr "mode" "DI")
4100 (set_attr "length" "4,8")])
4103 [(set (match_operand:DI 0 "register_operand" "=d,d")
4104 (zero_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4105 "TARGET_64BIT && TARGET_MIPS16"
4106 "* return mips_move_1word (operands, insn, TRUE);"
4107 [(set_attr "type" "load,load")
4108 (set_attr "mode" "DI")
4109 (set_attr "length" "4,8")])
4112 ;; ....................
4116 ;; ....................
4119 ;; Those for integer source operand are ordered widest source type first.
4121 ;; In 64 bit mode, 32 bit values in general registers are always
4122 ;; correctly sign extended. That means that if the target is a
4123 ;; general register, we can sign extend from SImode to DImode just by
4126 (define_insn "extendsidi2"
4127 [(set (match_operand:DI 0 "register_operand" "=d,y,d,*d,d,d")
4128 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,d,y,*x,R,m")))]
4130 "* return mips_move_1word (operands, insn, FALSE);"
4131 [(set_attr "type" "move,move,move,hilo,load,load")
4132 (set_attr "mode" "DI")
4133 (set_attr "length" "4,4,4,4,4,8")])
4135 ;; These patterns originally accepted general_operands, however, slightly
4136 ;; better code is generated by only accepting register_operands, and then
4137 ;; letting combine generate the lh and lb insns.
4139 (define_expand "extendhidi2"
4140 [(set (match_operand:DI 0 "register_operand" "")
4141 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
4145 if (optimize && GET_CODE (operands[1]) == MEM)
4146 operands[1] = force_not_mem (operands[1]);
4148 if (GET_CODE (operands[1]) != MEM)
4150 rtx op1 = gen_lowpart (DImode, operands[1]);
4151 rtx temp = gen_reg_rtx (DImode);
4152 rtx shift = GEN_INT (48);
4154 emit_insn (gen_ashldi3 (temp, op1, shift));
4155 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4160 (define_insn "extendhidi2_internal"
4161 [(set (match_operand:DI 0 "register_operand" "=d,d")
4162 (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
4164 "* return mips_move_1word (operands, insn, FALSE);"
4165 [(set_attr "type" "load")
4166 (set_attr "mode" "DI")
4167 (set_attr "length" "4,8")])
4169 (define_expand "extendhisi2"
4170 [(set (match_operand:SI 0 "register_operand" "")
4171 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4175 if (optimize && GET_CODE (operands[1]) == MEM)
4176 operands[1] = force_not_mem (operands[1]);
4178 if (GET_CODE (operands[1]) != MEM)
4180 rtx op1 = gen_lowpart (SImode, operands[1]);
4181 rtx temp = gen_reg_rtx (SImode);
4182 rtx shift = GEN_INT (16);
4184 emit_insn (gen_ashlsi3 (temp, op1, shift));
4185 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4190 (define_insn "extendhisi2_internal"
4191 [(set (match_operand:SI 0 "register_operand" "=d,d")
4192 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
4194 "* return mips_move_1word (operands, insn, FALSE);"
4195 [(set_attr "type" "load")
4196 (set_attr "mode" "SI")
4197 (set_attr "length" "4,8")])
4199 (define_expand "extendqihi2"
4200 [(set (match_operand:HI 0 "register_operand" "")
4201 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
4205 if (optimize && GET_CODE (operands[1]) == MEM)
4206 operands[1] = force_not_mem (operands[1]);
4208 if (GET_CODE (operands[1]) != MEM)
4210 rtx op0 = gen_lowpart (SImode, operands[0]);
4211 rtx op1 = gen_lowpart (SImode, operands[1]);
4212 rtx temp = gen_reg_rtx (SImode);
4213 rtx shift = GEN_INT (24);
4215 emit_insn (gen_ashlsi3 (temp, op1, shift));
4216 emit_insn (gen_ashrsi3 (op0, temp, shift));
4221 (define_insn "extendqihi2_internal"
4222 [(set (match_operand:HI 0 "register_operand" "=d,d")
4223 (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
4225 "* return mips_move_1word (operands, insn, FALSE);"
4226 [(set_attr "type" "load")
4227 (set_attr "mode" "SI")
4228 (set_attr "length" "4,8")])
4231 (define_expand "extendqisi2"
4232 [(set (match_operand:SI 0 "register_operand" "")
4233 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4237 if (optimize && GET_CODE (operands[1]) == MEM)
4238 operands[1] = force_not_mem (operands[1]);
4240 if (GET_CODE (operands[1]) != MEM)
4242 rtx op1 = gen_lowpart (SImode, operands[1]);
4243 rtx temp = gen_reg_rtx (SImode);
4244 rtx shift = GEN_INT (24);
4246 emit_insn (gen_ashlsi3 (temp, op1, shift));
4247 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4252 (define_insn "extendqisi2_insn"
4253 [(set (match_operand:SI 0 "register_operand" "=d,d")
4254 (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
4256 "* return mips_move_1word (operands, insn, FALSE);"
4257 [(set_attr "type" "load")
4258 (set_attr "mode" "SI")
4259 (set_attr "length" "4,8")])
4261 (define_expand "extendqidi2"
4262 [(set (match_operand:DI 0 "register_operand" "")
4263 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4267 if (optimize && GET_CODE (operands[1]) == MEM)
4268 operands[1] = force_not_mem (operands[1]);
4270 if (GET_CODE (operands[1]) != MEM)
4272 rtx op1 = gen_lowpart (DImode, operands[1]);
4273 rtx temp = gen_reg_rtx (DImode);
4274 rtx shift = GEN_INT (56);
4276 emit_insn (gen_ashldi3 (temp, op1, shift));
4277 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4282 (define_insn "extendqidi2_insn"
4283 [(set (match_operand:DI 0 "register_operand" "=d,d")
4284 (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4286 "* return mips_move_1word (operands, insn, FALSE);"
4287 [(set_attr "type" "load")
4288 (set_attr "mode" "DI")
4289 (set_attr "length" "4,8")])
4292 (define_insn "extendsfdf2"
4293 [(set (match_operand:DF 0 "register_operand" "=f")
4294 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
4295 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4297 [(set_attr "type" "fcvt")
4298 (set_attr "mode" "DF")])
4303 ;; ....................
4307 ;; ....................
4309 ;; The SImode scratch register can not be shared with address regs used for
4310 ;; operand zero, because then the address in the move instruction will be
4311 ;; clobbered. We mark the scratch register as early clobbered to prevent this.
4313 ;; We need the ?X in alternative 1 so that it will be chosen only if the
4314 ;; destination is a floating point register. Otherwise, alternative 1 can
4315 ;; have lower cost than alternative 0 (because there is one less loser), and
4316 ;; can be chosen when it won't work (because integral reloads into FP
4317 ;; registers are not supported).
4319 (define_insn "fix_truncdfsi2"
4320 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,*f,R,To")
4321 (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
4322 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
4323 (clobber (match_scratch:DF 3 "=f,?*X,f,f"))]
4324 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4329 if (which_alternative == 1)
4330 return \"trunc.w.d %0,%1,%2\";
4332 output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
4334 xoperands[0] = operands[0];
4335 xoperands[1] = operands[3];
4336 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4339 [(set_attr "type" "fcvt")
4340 (set_attr "mode" "DF")
4341 (set_attr "length" "44,36,40,44")])
4344 (define_insn "fix_truncsfsi2"
4345 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,*f,R,To")
4346 (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
4347 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
4348 (clobber (match_scratch:SF 3 "=f,?*X,f,f"))]
4354 if (which_alternative == 1)
4355 return \"trunc.w.s %0,%1,%2\";
4357 output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
4359 xoperands[0] = operands[0];
4360 xoperands[1] = operands[3];
4361 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4364 [(set_attr "type" "fcvt")
4365 (set_attr "mode" "SF")
4366 (set_attr "length" "44,36,40,44")])
4369 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
4370 ;;; but not in the chapter that describes the FPU. It is not mentioned at all
4371 ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
4373 ;;; Deleting this means that we now need two libgcc2.a libraries. One for
4374 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
4376 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
4378 (define_insn "fix_truncdfdi2"
4379 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,*f,R,To")
4380 (fix:DI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
4381 (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
4382 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4387 if (which_alternative == 1)
4388 return \"trunc.l.d %0,%1\";
4390 output_asm_insn (\"trunc.l.d %2,%1\", operands);
4392 xoperands[0] = operands[0];
4393 xoperands[1] = operands[2];
4394 output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
4397 [(set_attr "type" "fcvt")
4398 (set_attr "mode" "DF")
4399 (set_attr "length" "8,4,8,12")])
4402 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
4403 ;;; but not in the chapter that describes the FPU. It is not mentioned at all
4404 ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
4405 (define_insn "fix_truncsfdi2"
4406 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,*f,R,To")
4407 (fix:DI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
4408 (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
4409 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4414 if (which_alternative == 1)
4415 return \"trunc.l.s %0,%1\";
4417 output_asm_insn (\"trunc.l.s %2,%1\", operands);
4419 xoperands[0] = operands[0];
4420 xoperands[1] = operands[2];
4421 output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
4424 [(set_attr "type" "fcvt")
4425 (set_attr "mode" "SF")
4426 (set_attr "length" "8,4,8,12")])
4429 (define_insn "floatsidf2"
4430 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
4431 (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
4432 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4435 dslots_load_total++;
4436 if (GET_CODE (operands[1]) == MEM)
4437 return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
4439 return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
4441 [(set_attr "type" "fcvt")
4442 (set_attr "mode" "DF")
4443 (set_attr "length" "12,16,12")])
4446 (define_insn "floatdidf2"
4447 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
4448 (float:DF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
4449 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4452 dslots_load_total++;
4453 if (GET_CODE (operands[1]) == MEM)
4454 return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
4456 return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
4458 [(set_attr "type" "fcvt")
4459 (set_attr "mode" "DF")
4460 (set_attr "length" "12,16,12")])
4463 (define_insn "floatsisf2"
4464 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
4465 (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
4469 dslots_load_total++;
4470 if (GET_CODE (operands[1]) == MEM)
4471 return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
4473 return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
4475 [(set_attr "type" "fcvt")
4476 (set_attr "mode" "SF")
4477 (set_attr "length" "12,16,12")])
4480 (define_insn "floatdisf2"
4481 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
4482 (float:SF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
4483 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4486 dslots_load_total++;
4487 if (GET_CODE (operands[1]) == MEM)
4488 return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
4490 return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
4492 [(set_attr "type" "fcvt")
4493 (set_attr "mode" "SF")
4494 (set_attr "length" "12,16,12")])
4497 (define_expand "fixuns_truncdfsi2"
4498 [(set (match_operand:SI 0 "register_operand" "")
4499 (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
4500 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4503 rtx reg1 = gen_reg_rtx (DFmode);
4504 rtx reg2 = gen_reg_rtx (DFmode);
4505 rtx reg3 = gen_reg_rtx (SImode);
4506 rtx label1 = gen_label_rtx ();
4507 rtx label2 = gen_label_rtx ();
4508 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, 31);
4510 if (reg1) /* turn off complaints about unreached code */
4512 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4513 do_pending_stack_adjust ();
4515 emit_insn (gen_cmpdf (operands[1], reg1));
4516 emit_jump_insn (gen_bge (label1));
4518 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
4519 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4520 gen_rtx_LABEL_REF (VOIDmode, label2)));
4523 emit_label (label1);
4524 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
4525 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4526 (BITMASK_HIGH, SImode)));
4528 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
4529 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4531 emit_label (label2);
4533 /* allow REG_NOTES to be set on last insn (labels don't have enough
4534 fields, and can't be used for REG_NOTES anyway). */
4535 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4541 (define_expand "fixuns_truncdfdi2"
4542 [(set (match_operand:DI 0 "register_operand" "")
4543 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
4544 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4547 rtx reg1 = gen_reg_rtx (DFmode);
4548 rtx reg2 = gen_reg_rtx (DFmode);
4549 rtx reg3 = gen_reg_rtx (DImode);
4550 rtx label1 = gen_label_rtx ();
4551 rtx label2 = gen_label_rtx ();
4552 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, 63);
4554 if (reg1) /* turn off complaints about unreached code */
4556 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4557 do_pending_stack_adjust ();
4559 emit_insn (gen_cmpdf (operands[1], reg1));
4560 emit_jump_insn (gen_bge (label1));
4562 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
4563 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4564 gen_rtx_LABEL_REF (VOIDmode, label2)));
4567 emit_label (label1);
4568 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
4569 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4570 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4572 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
4573 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4575 emit_label (label2);
4577 /* allow REG_NOTES to be set on last insn (labels don't have enough
4578 fields, and can't be used for REG_NOTES anyway). */
4579 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4585 (define_expand "fixuns_truncsfsi2"
4586 [(set (match_operand:SI 0 "register_operand" "")
4587 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
4591 rtx reg1 = gen_reg_rtx (SFmode);
4592 rtx reg2 = gen_reg_rtx (SFmode);
4593 rtx reg3 = gen_reg_rtx (SImode);
4594 rtx label1 = gen_label_rtx ();
4595 rtx label2 = gen_label_rtx ();
4596 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, 31);
4598 if (reg1) /* turn off complaints about unreached code */
4600 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4601 do_pending_stack_adjust ();
4603 emit_insn (gen_cmpsf (operands[1], reg1));
4604 emit_jump_insn (gen_bge (label1));
4606 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
4607 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4608 gen_rtx_LABEL_REF (VOIDmode, label2)));
4611 emit_label (label1);
4612 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4613 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4614 (BITMASK_HIGH, SImode)));
4616 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4617 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4619 emit_label (label2);
4621 /* allow REG_NOTES to be set on last insn (labels don't have enough
4622 fields, and can't be used for REG_NOTES anyway). */
4623 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4629 (define_expand "fixuns_truncsfdi2"
4630 [(set (match_operand:DI 0 "register_operand" "")
4631 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
4632 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4635 rtx reg1 = gen_reg_rtx (SFmode);
4636 rtx reg2 = gen_reg_rtx (SFmode);
4637 rtx reg3 = gen_reg_rtx (DImode);
4638 rtx label1 = gen_label_rtx ();
4639 rtx label2 = gen_label_rtx ();
4640 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, 63);
4642 if (reg1) /* turn off complaints about unreached code */
4644 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4645 do_pending_stack_adjust ();
4647 emit_insn (gen_cmpsf (operands[1], reg1));
4648 emit_jump_insn (gen_bge (label1));
4650 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
4651 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4652 gen_rtx_LABEL_REF (VOIDmode, label2)));
4655 emit_label (label1);
4656 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4657 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4658 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4660 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4661 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4663 emit_label (label2);
4665 /* allow REG_NOTES to be set on last insn (labels don't have enough
4666 fields, and can't be used for REG_NOTES anyway). */
4667 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4674 ;; ....................
4678 ;; ....................
4680 ;; Bit field extract patterns which use lwl/lwr.
4682 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
4683 ;; It isn't clear whether this will give better code.
4685 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4686 (define_expand "extv"
4687 [(set (match_operand 0 "register_operand" "")
4688 (sign_extract (match_operand:QI 1 "memory_operand" "")
4689 (match_operand 2 "immediate_operand" "")
4690 (match_operand 3 "immediate_operand" "")))]
4694 /* If the field does not start on a byte boundary, then fail. */
4695 if (INTVAL (operands[3]) % 8 != 0)
4698 /* MIPS I and MIPS II can only handle a 32bit field. */
4699 if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4702 /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
4704 && INTVAL (operands[2]) != 64
4705 && INTVAL (operands[2]) != 32)
4708 /* This can happen for a 64 bit target, when extracting a value from
4709 a 64 bit union member. extract_bit_field doesn't verify that our
4710 source matches the predicate, so we force it to be a MEM here. */
4711 if (GET_CODE (operands[1]) != MEM)
4714 /* Change the mode to BLKmode for aliasing purposes. */
4715 operands[1] = adjust_address (operands[1], BLKmode, 0);
4717 /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value. */
4718 if (INTVAL (operands[2]) == 64)
4719 emit_insn (gen_movdi_uld (operands[0], operands[1]));
4724 operands[0] = gen_lowpart (SImode, operands[0]);
4725 if (operands[0] == NULL_RTX)
4728 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4733 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4734 (define_expand "extzv"
4735 [(set (match_operand 0 "register_operand" "")
4736 (zero_extract (match_operand:QI 1 "memory_operand" "")
4737 (match_operand 2 "immediate_operand" "")
4738 (match_operand 3 "immediate_operand" "")))]
4742 /* If the field does not start on a byte boundary, then fail. */
4743 if (INTVAL (operands[3]) % 8 != 0)
4746 /* MIPS I and MIPS II can only handle a 32bit field. */
4747 if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4750 /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
4752 && INTVAL (operands[2]) != 64
4753 && INTVAL (operands[2]) != 32)
4756 /* This can happen for a 64 bit target, when extracting a value from
4757 a 64 bit union member. extract_bit_field doesn't verify that our
4758 source matches the predicate, so we force it to be a MEM here. */
4759 if (GET_CODE (operands[1]) != MEM)
4762 /* Change the mode to BLKmode for aliasing purposes. */
4763 operands[1] = adjust_address (operands[1], BLKmode, 0);
4765 /* Otherwise, emit a lwl/lwr pair to load the value. */
4766 if (INTVAL (operands[2]) == 64)
4767 emit_insn (gen_movdi_uld (operands[0], operands[1]));
4772 operands[0] = gen_lowpart (SImode, operands[0]);
4773 if (operands[0] == NULL_RTX)
4776 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4781 ;; Only specify the mode operands 0, the rest are assumed to be word_mode.
4782 (define_expand "insv"
4783 [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
4784 (match_operand 1 "immediate_operand" "")
4785 (match_operand 2 "immediate_operand" ""))
4786 (match_operand 3 "register_operand" ""))]
4790 /* If the field does not start on a byte boundary, then fail. */
4791 if (INTVAL (operands[2]) % 8 != 0)
4794 /* MIPS I and MIPS II can only handle a 32bit field. */
4795 if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
4798 /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
4800 && INTVAL (operands[1]) != 64
4801 && INTVAL (operands[1]) != 32)
4804 /* This can happen for a 64 bit target, when storing into a 32 bit union
4805 member. store_bit_field doesn't verify that our target matches the
4806 predicate, so we force it to be a MEM here. */
4807 if (GET_CODE (operands[0]) != MEM)
4810 /* Change the mode to BLKmode for aliasing purposes. */
4811 operands[0] = adjust_address (operands[0], BLKmode, 0);
4813 /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value. */
4814 if (INTVAL (operands[1]) == 64)
4815 emit_insn (gen_movdi_usd (operands[0], operands[3]));
4820 operands[3] = gen_lowpart (SImode, operands[3]);
4821 if (operands[3] == NULL_RTX)
4824 emit_insn (gen_movsi_usw (operands[0], operands[3]));
4829 ;; unaligned word moves generated by the bit field patterns
4831 (define_insn "movsi_ulw"
4832 [(set (match_operand:SI 0 "register_operand" "=&d,&d")
4833 (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")]
4838 rtx offset = const0_rtx;
4839 rtx addr = XEXP (operands[1], 0);
4840 rtx mem_addr = eliminate_constant_term (addr, &offset);
4844 mips_count_memory_refs (operands[1], 2);
4846 /* The stack/frame pointers are always aligned, so we can convert
4847 to the faster lw if we are referencing an aligned stack location. */
4849 if ((INTVAL (offset) & 3) == 0
4850 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4851 ret = \"lw\\t%0,%1\";
4853 ret = \"ulw\\t%0,%1\";
4855 return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4857 [(set_attr "type" "load,load")
4858 (set_attr "mode" "SI")
4859 (set_attr "length" "8,16")])
4861 (define_insn "movsi_usw"
4862 [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4863 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")]
4868 rtx offset = const0_rtx;
4869 rtx addr = XEXP (operands[0], 0);
4870 rtx mem_addr = eliminate_constant_term (addr, &offset);
4873 mips_count_memory_refs (operands[0], 2);
4875 /* The stack/frame pointers are always aligned, so we can convert
4876 to the faster sw if we are referencing an aligned stack location. */
4878 if ((INTVAL (offset) & 3) == 0
4879 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4880 return \"sw\\t%z1,%0\";
4882 return \"usw\\t%z1,%0\";
4884 [(set_attr "type" "store")
4885 (set_attr "mode" "SI")
4886 (set_attr "length" "8,16")])
4888 ;; Bit field extract patterns which use ldl/ldr.
4890 ;; unaligned double word moves generated by the bit field patterns
4892 (define_insn "movdi_uld"
4893 [(set (match_operand:DI 0 "register_operand" "=&d,&d")
4894 (unspec:DI [(match_operand:BLK 1 "general_operand" "R,o")]
4899 rtx offset = const0_rtx;
4900 rtx addr = XEXP (operands[1], 0);
4901 rtx mem_addr = eliminate_constant_term (addr, &offset);
4905 mips_count_memory_refs (operands[1], 2);
4907 /* The stack/frame pointers are always aligned, so we can convert
4908 to the faster lw if we are referencing an aligned stack location. */
4910 if ((INTVAL (offset) & 7) == 0
4911 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4912 ret = \"ld\\t%0,%1\";
4914 ret = \"uld\\t%0,%1\";
4916 return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4918 [(set_attr "type" "load,load")
4919 (set_attr "mode" "SI")
4920 (set_attr "length" "8,16")])
4922 (define_insn "movdi_usd"
4923 [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4924 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")]
4929 rtx offset = const0_rtx;
4930 rtx addr = XEXP (operands[0], 0);
4931 rtx mem_addr = eliminate_constant_term (addr, &offset);
4934 mips_count_memory_refs (operands[0], 2);
4936 /* The stack/frame pointers are always aligned, so we can convert
4937 to the faster sw if we are referencing an aligned stack location. */
4939 if ((INTVAL (offset) & 7) == 0
4940 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4941 return \"sd\\t%1,%0\";
4943 return \"usd\\t%z1,%0\";
4945 [(set_attr "type" "store")
4946 (set_attr "mode" "SI")
4947 (set_attr "length" "8,16")])
4949 ;; These two patterns support loading addresses with two instructions instead
4950 ;; of using the macro instruction la.
4952 ;; ??? mips_move_1word has support for HIGH, so this pattern may be
4956 [(set (match_operand:SI 0 "register_operand" "=r")
4957 (high:SI (match_operand:SI 1 "immediate_operand" "")))]
4958 "mips_split_addresses && !TARGET_MIPS16"
4959 "lui\\t%0,%%hi(%1) # high"
4960 [(set_attr "type" "move")])
4963 [(set (match_operand:SI 0 "register_operand" "=r")
4964 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
4965 (match_operand:SI 2 "immediate_operand" "")))]
4966 "mips_split_addresses && !TARGET_MIPS16"
4967 "addiu\\t%0,%1,%%lo(%2) # low"
4968 [(set_attr "type" "arith")
4969 (set_attr "mode" "SI")])
4971 ;; 64-bit integer moves
4973 ;; Unlike most other insns, the move insns can't be split with
4974 ;; different predicates, because register spilling and other parts of
4975 ;; the compiler, have memoized the insn number already.
4977 (define_expand "movdi"
4978 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4979 (match_operand:DI 1 "general_operand" ""))]
4983 if (mips_split_addresses && mips_check_split (operands[1], DImode))
4985 enum machine_mode mode = GET_MODE (operands[0]);
4986 rtx tem = ((reload_in_progress | reload_completed)
4987 ? operands[0] : gen_reg_rtx (mode));
4989 emit_insn (gen_rtx_SET (VOIDmode, tem,
4990 gen_rtx_HIGH (mode, operands[1])));
4992 operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
4995 /* If we are generating embedded PIC code, and we are referring to a
4996 symbol in the .text section, we must use an offset from the start
4998 if (TARGET_EMBEDDED_PIC
4999 && (GET_CODE (operands[1]) == LABEL_REF
5000 || (GET_CODE (operands[1]) == SYMBOL_REF
5001 && ! SYMBOL_REF_FLAG (operands[1]))))
5005 temp = embedded_pic_offset (operands[1]);
5006 temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
5007 force_reg (DImode, temp));
5008 emit_move_insn (operands[0], force_reg (DImode, temp));
5012 /* If operands[1] is a constant address illegal for pic, then we need to
5013 handle it just like LEGITIMIZE_ADDRESS does. */
5014 if (flag_pic && pic_address_needs_scratch (operands[1]))
5016 rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
5017 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
5019 if (! SMALL_INT (temp2))
5020 temp2 = force_reg (DImode, temp2);
5022 emit_move_insn (operands[0], gen_rtx_PLUS (DImode, temp, temp2));
5026 /* On the mips16, we can handle a GP relative reference by adding in
5027 $gp. We need to check the name to see whether this is a string
5030 && register_operand (operands[0], DImode)
5031 && GET_CODE (operands[1]) == SYMBOL_REF
5032 && SYMBOL_REF_FLAG (operands[1]))
5034 const char *name = XSTR (operands[1], 0);
5037 || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5038 sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5042 if (reload_in_progress || reload_completed)
5044 /* In movsi we use the constant table here. However, in
5045 this case, we're better off copying $28 into a
5046 register and adding, because the constant table entry
5047 would be 8 bytes. */
5048 base_reg = operands[0];
5049 emit_move_insn (base_reg,
5050 gen_rtx (CONST, DImode,
5051 gen_rtx (REG, DImode,
5052 GP_REG_FIRST + 28)));
5056 base_reg = gen_reg_rtx (Pmode);
5057 emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
5060 emit_move_insn (operands[0],
5061 gen_rtx (PLUS, Pmode, base_reg,
5062 mips16_gp_offset (operands[1])));
5067 if ((reload_in_progress | reload_completed) == 0
5068 && !register_operand (operands[0], DImode)
5069 && !register_operand (operands[1], DImode)
5071 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
5072 && operands[1] != CONST0_RTX (DImode))))
5074 rtx temp = force_reg (DImode, operands[1]);
5075 emit_move_insn (operands[0], temp);
5080 ;; For mips16, we need a special case to handle storing $31 into
5081 ;; memory, since we don't have a constraint to match $31. This
5082 ;; instruction can be generated by save_restore_insns.
5085 [(set (match_operand:DI 0 "memory_operand" "=R,m")
5087 "TARGET_MIPS16 && TARGET_64BIT"
5090 operands[1] = gen_rtx (REG, DImode, 31);
5091 return mips_move_2words (operands, insn);
5093 [(set_attr "type" "store")
5094 (set_attr "mode" "DI")
5095 (set_attr "length" "4,8")])
5097 (define_insn "movdi_internal"
5098 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
5099 (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
5100 "!TARGET_64BIT && !TARGET_MIPS16
5101 && (register_operand (operands[0], DImode)
5102 || register_operand (operands[1], DImode)
5103 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5104 || operands[1] == CONST0_RTX (DImode))"
5105 "* return mips_move_2words (operands, insn); "
5106 [(set_attr "type" "move,arith,load,load,store,store,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5107 (set_attr "mode" "DI")
5108 (set_attr "length" "8,16,8,16,8,16,8,8,8,8,8,8,8,8,8")])
5111 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,To,*d")
5112 (match_operand:DI 1 "general_operand" "d,d,y,K,N,R,To,d,d,*x"))]
5113 "!TARGET_64BIT && TARGET_MIPS16
5114 && (register_operand (operands[0], DImode)
5115 || register_operand (operands[1], DImode))"
5116 "* return mips_move_2words (operands, insn);"
5117 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
5118 (set_attr "mode" "DI")
5119 (set_attr "length" "8,8,8,8,12,8,16,8,16,8")])
5122 [(set (match_operand:DI 0 "register_operand" "")
5123 (match_operand:DI 1 "register_operand" ""))]
5124 "reload_completed && !TARGET_64BIT
5125 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
5126 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
5127 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
5129 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
5130 (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
5133 (define_insn "movdi_internal2"
5134 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
5135 (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
5136 "TARGET_64BIT && !TARGET_MIPS16
5137 && (register_operand (operands[0], DImode)
5138 || se_register_operand (operands[1], DImode)
5139 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5140 || operands[1] == CONST0_RTX (DImode))"
5141 "* return mips_move_2words (operands, insn); "
5142 [(set_attr "type" "move,load,arith,arith,load,load,store,store,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5143 (set_attr "mode" "DI")
5144 (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,8,8,8,8,8,8,8")])
5147 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
5148 (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
5149 "TARGET_64BIT && TARGET_MIPS16
5150 && (register_operand (operands[0], DImode)
5151 || se_register_operand (operands[1], DImode))"
5152 "* return mips_move_2words (operands, insn);"
5153 [(set_attr "type" "move,move,move,arith,arith,arith,load,load,store,store,hilo")
5154 (set_attr "mode" "DI")
5155 (set_attr_alternative "length"
5159 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5162 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5165 (if_then_else (match_operand:VOID 1 "m16_usym5_4" "")
5174 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
5175 ;; when the original load is a 4 byte instruction but the add and the
5176 ;; load are 2 2 byte instructions.
5179 [(set (match_operand:DI 0 "register_operand" "")
5180 (mem:DI (plus:DI (match_dup 0)
5181 (match_operand:DI 1 "const_int_operand" ""))))]
5182 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
5183 && !TARGET_DEBUG_D_MODE
5184 && GET_CODE (operands[0]) == REG
5185 && M16_REG_P (REGNO (operands[0]))
5186 && GET_CODE (operands[1]) == CONST_INT
5187 && ((INTVAL (operands[1]) < 0
5188 && INTVAL (operands[1]) >= -0x10)
5189 || (INTVAL (operands[1]) >= 32 * 8
5190 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
5191 || (INTVAL (operands[1]) >= 0
5192 && INTVAL (operands[1]) < 32 * 8
5193 && (INTVAL (operands[1]) & 7) != 0))"
5194 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
5195 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
5198 HOST_WIDE_INT val = INTVAL (operands[1]);
5201 operands[2] = GEN_INT (0);
5202 else if (val >= 32 * 8)
5206 operands[1] = GEN_INT (0x8 + off);
5207 operands[2] = GEN_INT (val - off - 0x8);
5213 operands[1] = GEN_INT (off);
5214 operands[2] = GEN_INT (val - off);
5218 ;; Handle input reloads in DImode.
5219 ;; This is mainly to handle reloading HILO_REGNUM. Note that we may
5220 ;; see it as the source or the destination, depending upon which way
5221 ;; reload handles the instruction.
5222 ;; Making the second operand TImode is a trick. The compiler may
5223 ;; reuse the same register for operand 0 and operand 2. Using TImode
5224 ;; gives us two registers, so we can always use the one which is not
5227 (define_expand "reload_indi"
5228 [(set (match_operand:DI 0 "register_operand" "=b")
5229 (match_operand:DI 1 "" "b"))
5230 (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5234 rtx scratch = gen_rtx_REG (DImode,
5235 (REGNO (operands[0]) == REGNO (operands[2])
5236 ? REGNO (operands[2]) + 1
5237 : REGNO (operands[2])));
5239 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5241 if (GET_CODE (operands[1]) == MEM)
5243 rtx memword, offword, hi_word, lo_word;
5244 rtx addr = find_replacement (&XEXP (operands[1], 0));
5245 rtx op1 = replace_equiv_address (operands[1], addr);
5247 scratch = gen_rtx_REG (SImode, REGNO (scratch));
5248 memword = adjust_address (op1, SImode, 0);
5249 offword = adjust_address (op1, SImode, 4);
5251 if (BYTES_BIG_ENDIAN)
5261 emit_move_insn (scratch, hi_word);
5262 emit_move_insn (gen_rtx_REG (SImode, 64), scratch);
5263 emit_move_insn (scratch, lo_word);
5264 emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
5265 emit_insn (gen_hilo_delay (operands[0]));
5269 emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5270 emit_insn (gen_movdi (gen_rtx_REG (DImode, 64), scratch));
5271 emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5272 emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5273 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5274 emit_insn (gen_hilo_delay (operands[0]));
5278 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5280 emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 65)));
5281 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5282 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5283 emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 64)));
5284 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5285 emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5286 emit_insn (gen_hilo_delay (operands[1]));
5289 /* This handles moves between a float register and HI/LO. */
5290 emit_move_insn (scratch, operands[1]);
5291 emit_move_insn (operands[0], scratch);
5295 ;; Handle output reloads in DImode.
5297 ;; Reloading HILO_REG in MIPS16 mode requires two scratch registers, so we
5298 ;; use a TImode scratch reg.
5300 (define_expand "reload_outdi"
5301 [(set (match_operand:DI 0 "general_operand" "=b")
5302 (match_operand:DI 1 "se_register_operand" "b"))
5303 (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5307 rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5309 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5311 emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5312 emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
5313 emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5314 emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5315 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5316 emit_insn (gen_hilo_delay (operands[0]));
5319 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5321 if (GET_CODE (operands[0]) == MEM)
5323 rtx scratch, memword, offword, hi_word, lo_word;
5324 rtx addr = find_replacement (&XEXP (operands[0], 0));
5325 rtx op0 = replace_equiv_address (operands[0], addr);
5327 scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
5328 memword = adjust_address (op0, SImode, 0);
5329 offword = adjust_address (op0, SImode, 4);
5331 if (BYTES_BIG_ENDIAN)
5341 emit_move_insn (scratch, gen_rtx_REG (SImode, 64));
5342 emit_move_insn (hi_word, scratch);
5343 emit_move_insn (scratch, gen_rtx_REG (SImode, 65));
5344 emit_move_insn (lo_word, scratch);
5345 emit_insn (gen_hilo_delay (operands[1]));
5347 else if (TARGET_MIPS16 && ! M16_REG_P (REGNO (operands[0])))
5349 /* Handle the case where operand[0] is not a 'd' register,
5350 and hence we can not directly move from the HILO register
5352 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5353 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5354 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5355 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5356 emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64)));
5357 emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
5358 emit_insn (gen_iordi3 (scratch, scratch, scratch2));
5359 emit_insn (gen_movdi (operands[0], scratch));
5360 emit_insn (gen_hilo_delay (operands[1]));
5364 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5365 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5366 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5367 emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
5368 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5369 emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5370 emit_insn (gen_hilo_delay (operands[1]));
5374 /* This handles moves between a float register and HI/LO. */
5375 emit_move_insn (scratch, operands[1]);
5376 emit_move_insn (operands[0], scratch);
5380 ;; 32-bit Integer moves
5383 [(set (match_operand:SI 0 "register_operand" "")
5384 (match_operand:SI 1 "large_int" ""))]
5385 "!TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
5389 (ior:SI (match_dup 0)
5393 operands[2] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
5396 operands[3] = GEN_INT (INTVAL (operands[1]) & BITMASK_LOWER16);
5399 ;; Unlike most other insns, the move insns can't be split with
5400 ;; different predicates, because register spilling and other parts of
5401 ;; the compiler, have memoized the insn number already.
5403 (define_expand "movsi"
5404 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5405 (match_operand:SI 1 "general_operand" ""))]
5409 if (mips_split_addresses && mips_check_split (operands[1], SImode))
5411 enum machine_mode mode = GET_MODE (operands[0]);
5412 rtx tem = ((reload_in_progress | reload_completed)
5413 ? operands[0] : gen_reg_rtx (mode));
5415 emit_insn (gen_rtx_SET (VOIDmode, tem,
5416 gen_rtx_HIGH (mode, operands[1])));
5418 operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
5421 /* If we are generating embedded PIC code, and we are referring to a
5422 symbol in the .text section, we must use an offset from the start
5424 if (TARGET_EMBEDDED_PIC
5425 && (GET_CODE (operands[1]) == LABEL_REF
5426 || (GET_CODE (operands[1]) == SYMBOL_REF
5427 && ! SYMBOL_REF_FLAG (operands[1]))))
5431 temp = embedded_pic_offset (operands[1]);
5432 temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
5433 force_reg (SImode, temp));
5434 emit_move_insn (operands[0], force_reg (SImode, temp));
5438 /* If operands[1] is a constant address invalid for pic, then we need to
5439 handle it just like LEGITIMIZE_ADDRESS does. */
5440 if (flag_pic && pic_address_needs_scratch (operands[1]))
5442 rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
5443 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
5445 if (! SMALL_INT (temp2))
5446 temp2 = force_reg (SImode, temp2);
5448 emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, temp2));
5452 /* On the mips16, we can handle a GP relative reference by adding in
5453 $gp. We need to check the name to see whether this is a string
5456 && register_operand (operands[0], SImode)
5457 && GET_CODE (operands[1]) == SYMBOL_REF
5458 && SYMBOL_REF_FLAG (operands[1]))
5460 const char *name = XSTR (operands[1], 0);
5463 || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5464 sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5468 if (reload_in_progress || reload_completed)
5470 /* We need to reload this address. In this case we
5471 aren't going to have a chance to combine loading the
5472 address with the load or store. That means that we
5473 can either generate a 2 byte move followed by a 4
5474 byte addition, or a 2 byte load with a 4 byte entry
5475 in the constant table. Since the entry in the
5476 constant table might be shared, we're better off, on
5477 average, loading the address from the constant table. */
5478 emit_move_insn (operands[0],
5479 force_const_mem (SImode, operands[1]));
5483 base_reg = gen_reg_rtx (Pmode);
5484 emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
5486 emit_move_insn (operands[0],
5487 gen_rtx (PLUS, Pmode, base_reg,
5488 mips16_gp_offset (operands[1])));
5493 if ((reload_in_progress | reload_completed) == 0
5494 && !register_operand (operands[0], SImode)
5495 && !register_operand (operands[1], SImode)
5497 || GET_CODE (operands[1]) != CONST_INT
5498 || INTVAL (operands[1]) != 0))
5500 rtx temp = force_reg (SImode, operands[1]);
5501 emit_move_insn (operands[0], temp);
5506 ;; We can only store $ra directly into a small sp offset. Should the
5507 ;; offset be too wide, non-constant or not sp-based, leave it up to
5508 ;; reload to choose a scratch register.
5511 [(set (mem:SI (plus:SI (reg:SI 29)
5512 (match_operand:SI 0 "small_int" "n")))
5516 [(set_attr "type" "store")
5517 (set_attr "mode" "SI")
5518 (set_attr_alternative
5521 (lt (symbol_ref "(unsigned HOST_WIDE_INT) INTVAL (operands[0])")
5526 ;; The difference between these two is whether or not ints are allowed
5527 ;; in FP registers (off by default, use -mdebugh to enable).
5529 (define_insn "movsi_internal1"
5530 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*f*z,*f,*f,*f,*R,*m,*x,*x,*d,*d,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
5531 (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*f*z,*d,*f,*R,*m,*f,*f,J,*d,*x,*a,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
5532 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5533 && (register_operand (operands[0], SImode)
5534 || register_operand (operands[1], SImode)
5535 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5536 "* return mips_move_1word (operands, insn, FALSE);"
5537 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5538 (set_attr "mode" "SI")
5539 (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,4,8,4,8,4,4,4,4,4,4,8,4,4,8")])
5541 (define_insn "movsi_internal2"
5542 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
5543 (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
5544 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5545 && (register_operand (operands[0], SImode)
5546 || register_operand (operands[1], SImode)
5547 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5548 "* return mips_move_1word (operands, insn, FALSE);"
5549 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
5550 (set_attr "mode" "SI")
5551 (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,4,4,4,4,4,8,4,4,8")])
5553 ;; This is the mips16 movsi instruction. We accept a small integer as
5554 ;; the source if the destination is a GP memory reference. This is
5555 ;; because we want the combine pass to turn adding a GP reference to a
5556 ;; register into a direct GP reference, but the combine pass will pass
5557 ;; in the source as a constant if it finds an equivalent one. If the
5558 ;; instruction is recognized, reload will force the constant back out
5562 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,d,R,m,*d,*d")
5563 (match_operand:SI 1 "move_operand" "d,d,y,S,K,N,s,R,m,d,d,*x,*a"))]
5565 && (register_operand (operands[0], SImode)
5566 || register_operand (operands[1], SImode)
5567 || (GET_CODE (operands[0]) == MEM
5568 && GET_CODE (XEXP (operands[0], 0)) == PLUS
5569 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST
5570 && mips16_gp_offset_p (XEXP (XEXP (operands[0], 0), 1))
5571 && GET_CODE (operands[1]) == CONST_INT
5572 && (SMALL_INT (operands[1])
5573 || SMALL_INT_UNSIGNED (operands[1]))))"
5574 "* return mips_move_1word (operands, insn, FALSE);"
5575 [(set_attr "type" "move,move,move,load,arith,arith,arith,load,load,store,store,hilo,hilo")
5576 (set_attr "mode" "SI")
5577 (set_attr_alternative "length"
5582 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5585 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5588 (if_then_else (match_operand:VOID 1 "m16_usym8_4" "")
5598 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
5599 ;; when the original load is a 4 byte instruction but the add and the
5600 ;; load are 2 2 byte instructions.
5603 [(set (match_operand:SI 0 "register_operand" "")
5604 (mem:SI (plus:SI (match_dup 0)
5605 (match_operand:SI 1 "const_int_operand" ""))))]
5606 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5607 && GET_CODE (operands[0]) == REG
5608 && M16_REG_P (REGNO (operands[0]))
5609 && GET_CODE (operands[1]) == CONST_INT
5610 && ((INTVAL (operands[1]) < 0
5611 && INTVAL (operands[1]) >= -0x80)
5612 || (INTVAL (operands[1]) >= 32 * 4
5613 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
5614 || (INTVAL (operands[1]) >= 0
5615 && INTVAL (operands[1]) < 32 * 4
5616 && (INTVAL (operands[1]) & 3) != 0))"
5617 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5618 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
5621 HOST_WIDE_INT val = INTVAL (operands[1]);
5624 operands[2] = GEN_INT (0);
5625 else if (val >= 32 * 4)
5629 operands[1] = GEN_INT (0x7c + off);
5630 operands[2] = GEN_INT (val - off - 0x7c);
5636 operands[1] = GEN_INT (off);
5637 operands[2] = GEN_INT (val - off);
5641 ;; On the mips16, we can split a load of certain constants into a load
5642 ;; and an add. This turns a 4 byte instruction into 2 2 byte
5646 [(set (match_operand:SI 0 "register_operand" "")
5647 (match_operand:SI 1 "const_int_operand" ""))]
5648 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5649 && GET_CODE (operands[0]) == REG
5650 && M16_REG_P (REGNO (operands[0]))
5651 && GET_CODE (operands[1]) == CONST_INT
5652 && INTVAL (operands[1]) >= 0x100
5653 && INTVAL (operands[1]) <= 0xff + 0x7f"
5654 [(set (match_dup 0) (match_dup 1))
5655 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
5658 int val = INTVAL (operands[1]);
5660 operands[1] = GEN_INT (0xff);
5661 operands[2] = GEN_INT (val - 0xff);
5664 ;; On the mips16, we can split a load of a negative constant into a
5665 ;; load and a neg. That's what mips_move_1word will generate anyhow.
5668 [(set (match_operand:SI 0 "register_operand" "")
5669 (match_operand:SI 1 "const_int_operand" ""))]
5670 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5671 && GET_CODE (operands[0]) == REG
5672 && M16_REG_P (REGNO (operands[0]))
5673 && GET_CODE (operands[1]) == CONST_INT
5674 && INTVAL (operands[1]) < 0
5675 && INTVAL (operands[1]) > - 0x8000"
5676 [(set (match_dup 0) (match_dup 1))
5677 (set (match_dup 0) (neg:SI (match_dup 0)))]
5680 operands[1] = GEN_INT (- INTVAL (operands[1]));
5683 ;; Reload HILO_REGNUM in SI mode. This needs a scratch register in
5684 ;; order to set the sign bit correctly in the HI register.
5686 (define_expand "reload_outsi"
5687 [(set (match_operand:SI 0 "general_operand" "=b")
5688 (match_operand:SI 1 "register_operand" "b"))
5689 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5690 "TARGET_64BIT || TARGET_MIPS16"
5694 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5696 emit_insn (gen_movsi (gen_rtx_REG (SImode, 65), operands[1]));
5697 emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
5698 emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
5699 emit_insn (gen_hilo_delay (operands[0]));
5702 /* Use a mult to reload LO on mips16. ??? This is hideous. */
5704 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5706 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5707 /* This is gen_mulsi3_internal, but we need to fill in the
5708 scratch registers. */
5709 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5711 gen_rtx (SET, VOIDmode,
5713 gen_rtx (MULT, SImode,
5716 gen_rtx (CLOBBER, VOIDmode,
5717 gen_rtx (REG, SImode, 64)),
5718 gen_rtx (CLOBBER, VOIDmode,
5719 gen_rtx (REG, SImode, 66)))));
5722 /* FIXME: I don't know how to get a value into the HI register. */
5723 if (GET_CODE (operands[0]) == REG
5724 && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0]))
5725 : GP_REG_P (REGNO (operands[0]))))
5727 emit_move_insn (operands[0], operands[1]);
5730 /* This handles moves between a float register and HI/LO. */
5731 emit_move_insn (operands[2], operands[1]);
5732 emit_move_insn (operands[0], operands[2]);
5736 ;; Reload a value into HI or LO. There is no mthi or mtlo on mips16,
5737 ;; so we use a mult. ??? This is hideous, and we ought to figure out
5738 ;; something better.
5740 ;; We use no predicate for operand1, because it may be a PLUS, and there
5741 ;; is no convenient predicate for that.
5743 (define_expand "reload_insi"
5744 [(set (match_operand:SI 0 "register_operand" "=b")
5745 (match_operand:SI 1 "" "b"))
5746 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5751 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5753 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5754 /* This is gen_mulsi3_internal, but we need to fill in the
5755 scratch registers. */
5756 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5758 gen_rtx (SET, VOIDmode,
5760 gen_rtx (MULT, SImode,
5763 gen_rtx (CLOBBER, VOIDmode,
5764 gen_rtx (REG, SImode, 64)),
5765 gen_rtx (CLOBBER, VOIDmode,
5766 gen_rtx (REG, SImode, 66)))));
5770 /* If this is a plus, then this must be an add of the stack pointer against
5771 either a hard register or a pseudo. */
5772 if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
5776 if (XEXP (operands[1], 0) == stack_pointer_rtx)
5777 plus_op = XEXP (operands[1], 1);
5778 else if (XEXP (operands[1], 1) == stack_pointer_rtx)
5779 plus_op = XEXP (operands[1], 0);
5783 /* We should have a register now. */
5784 if (GET_CODE (plus_op) != REG)
5787 if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
5789 /* We have to have at least one temporary register which is not
5790 overlapping plus_op. */
5791 if (! rtx_equal_p (plus_op, operands[0]))
5793 emit_move_insn (operands[0], stack_pointer_rtx);
5794 emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
5796 else if (! rtx_equal_p (plus_op, operands[2]))
5798 emit_move_insn (operands[2], stack_pointer_rtx);
5799 emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
5806 /* We need two registers in this case. */
5807 if (! rtx_equal_p (operands[0], operands[2]))
5809 emit_move_insn (operands[0], stack_pointer_rtx);
5810 emit_move_insn (operands[2], plus_op);
5811 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
5819 /* FIXME: I don't know how to get a value into the HI register. */
5820 emit_move_insn (operands[0], operands[1]);
5824 ;; This insn is for the unspec delay for HILO.
5826 (define_insn "hilo_delay"
5827 [(unspec [(match_operand 0 "register_operand" "=b")] UNSPEC_HILO_DELAY)]
5830 [(set_attr "type" "nop")
5831 (set_attr "mode" "none")
5832 (set_attr "can_delay" "no")])
5834 ;; This insn handles moving CCmode values. It's really just a
5835 ;; slightly simplified copy of movsi_internal2, with additional cases
5836 ;; to move a condition register to a general register and to move
5837 ;; between the general registers and the floating point registers.
5839 (define_insn "movcc"
5840 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
5841 (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
5842 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5843 "* return mips_move_1word (operands, insn, FALSE);"
5844 [(set_attr "type" "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
5845 (set_attr "mode" "SI")
5846 (set_attr "length" "8,4,4,8,4,8,4,4,4,4,8,4,8")])
5848 ;; Reload condition code registers. These need scratch registers.
5850 (define_expand "reload_incc"
5851 [(set (match_operand:CC 0 "register_operand" "=z")
5852 (match_operand:CC 1 "general_operand" "z"))
5853 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
5854 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5861 /* This is called when are copying some value into a condition code
5862 register. Operand 0 is the condition code register. Operand 1
5863 is the source. Operand 2 is a scratch register; we use TFmode
5864 because we actually need two floating point registers. */
5865 if (! ST_REG_P (true_regnum (operands[0]))
5866 || ! FP_REG_P (true_regnum (operands[2])))
5869 /* We need to get the source in SFmode so that the insn is
5871 if (GET_CODE (operands[1]) == MEM)
5872 source = adjust_address (operands[1], SFmode, 0);
5873 else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
5874 source = gen_rtx_REG (SFmode, true_regnum (operands[1]));
5876 source = operands[1];
5878 /* FP1 and FP2 are the two halves of the TFmode scratch operand. They
5879 will be single registers in 64-bit mode and register pairs in 32-bit
5880 mode. SOURCE is loaded into FP1 and zero is loaded into FP2. */
5881 regno = REGNO (operands[2]);
5882 fp1 = gen_rtx_REG (SFmode, regno);
5883 fp2 = gen_rtx_REG (SFmode, regno + HARD_REGNO_NREGS (regno, DFmode));
5885 emit_insn (gen_move_insn (fp1, source));
5886 emit_insn (gen_move_insn (fp2, gen_rtx_REG (SFmode, 0)));
5887 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5888 gen_rtx_LT (CCmode, fp2, fp1)));
5893 (define_expand "reload_outcc"
5894 [(set (match_operand:CC 0 "general_operand" "=z")
5895 (match_operand:CC 1 "register_operand" "z"))
5896 (clobber (match_operand:CC 2 "register_operand" "=&d"))]
5897 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5900 /* This is called when we are copying a condition code register out
5901 to save it somewhere. Operand 0 should be the location we are
5902 going to save it to. Operand 1 should be the condition code
5903 register. Operand 2 should be a scratch general purpose register
5904 created for us by reload. The mips_secondary_reload_class
5905 function should have told reload that we don't need a scratch
5906 register if the destination is a general purpose register anyhow. */
5907 if (ST_REG_P (true_regnum (operands[0]))
5908 || GP_REG_P (true_regnum (operands[0]))
5909 || ! ST_REG_P (true_regnum (operands[1]))
5910 || ! GP_REG_P (true_regnum (operands[2])))
5913 /* All we have to do is copy the value from the condition code to
5914 the data register, which movcc can handle, and then store the
5915 value into the real final destination. */
5916 emit_insn (gen_move_insn (operands[2], operands[1]));
5917 emit_insn (gen_move_insn (operands[0], operands[2]));
5922 ;; MIPS4 supports loading and storing a floating point register from
5923 ;; the sum of two general registers. We use two versions for each of
5924 ;; these four instructions: one where the two general registers are
5925 ;; SImode, and one where they are DImode. This is because general
5926 ;; registers will be in SImode when they hold 32 bit values, but,
5927 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
5928 ;; instructions will still work correctly.
5930 ;; ??? Perhaps it would be better to support these instructions by
5931 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
5932 ;; these instructions can only be used to load and store floating
5933 ;; point registers, that would probably cause trouble in reload.
5936 [(set (match_operand:SF 0 "register_operand" "=f")
5937 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5938 (match_operand:SI 2 "register_operand" "d"))))]
5939 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5941 [(set_attr "type" "load")
5942 (set_attr "mode" "SF")])
5945 [(set (match_operand:SF 0 "register_operand" "=f")
5946 (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5947 (match_operand:DI 2 "se_register_operand" "d"))))]
5948 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5950 [(set_attr "type" "load")
5951 (set_attr "mode" "SF")])
5954 [(set (match_operand:DF 0 "register_operand" "=f")
5955 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5956 (match_operand:SI 2 "register_operand" "d"))))]
5957 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5959 [(set_attr "type" "load")
5960 (set_attr "mode" "DF")])
5963 [(set (match_operand:DF 0 "register_operand" "=f")
5964 (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5965 (match_operand:DI 2 "se_register_operand" "d"))))]
5966 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5968 [(set_attr "type" "load")
5969 (set_attr "mode" "DF")])
5972 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5973 (match_operand:SI 2 "register_operand" "d")))
5974 (match_operand:SF 0 "register_operand" "f"))]
5975 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5977 [(set_attr "type" "store")
5978 (set_attr "mode" "SF")])
5981 [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5982 (match_operand:DI 2 "se_register_operand" "d")))
5983 (match_operand:SF 0 "register_operand" "f"))]
5984 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5986 [(set_attr "type" "store")
5987 (set_attr "mode" "SF")])
5990 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5991 (match_operand:SI 2 "register_operand" "d")))
5992 (match_operand:DF 0 "register_operand" "f"))]
5993 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5995 [(set_attr "type" "store")
5996 (set_attr "mode" "DF")])
5999 [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
6000 (match_operand:DI 2 "se_register_operand" "d")))
6001 (match_operand:DF 0 "register_operand" "f"))]
6002 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6004 [(set_attr "type" "store")
6005 (set_attr "mode" "DF")])
6007 ;; 16-bit Integer moves
6009 ;; Unlike most other insns, the move insns can't be split with
6010 ;; different predicates, because register spilling and other parts of
6011 ;; the compiler, have memoized the insn number already.
6012 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
6014 (define_expand "movhi"
6015 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6016 (match_operand:HI 1 "general_operand" ""))]
6020 if ((reload_in_progress | reload_completed) == 0
6021 && !register_operand (operands[0], HImode)
6022 && !register_operand (operands[1], HImode)
6024 || (GET_CODE (operands[1]) != CONST_INT
6025 || INTVAL (operands[1]) != 0)))
6027 rtx temp = force_reg (HImode, operands[1]);
6028 emit_move_insn (operands[0], temp);
6033 ;; The difference between these two is whether or not ints are allowed
6034 ;; in FP registers (off by default, use -mdebugh to enable).
6036 (define_insn "movhi_internal1"
6037 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
6038 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
6039 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6040 && (register_operand (operands[0], HImode)
6041 || register_operand (operands[1], HImode)
6042 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6043 "* return mips_move_1word (operands, insn, TRUE);"
6044 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
6045 (set_attr "mode" "HI")
6046 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
6048 (define_insn "movhi_internal2"
6049 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
6050 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
6051 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6052 && (register_operand (operands[0], HImode)
6053 || register_operand (operands[1], HImode)
6054 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6055 "* return mips_move_1word (operands, insn, TRUE);"
6056 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
6057 (set_attr "mode" "HI")
6058 (set_attr "length" "4,4,4,8,4,8,4,4,4,4")])
6061 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
6062 (match_operand:HI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
6064 && (register_operand (operands[0], HImode)
6065 || register_operand (operands[1], HImode))"
6066 "* return mips_move_1word (operands, insn, TRUE);"
6067 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
6068 (set_attr "mode" "HI")
6069 (set_attr_alternative "length"
6073 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
6076 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6086 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
6087 ;; when the original load is a 4 byte instruction but the add and the
6088 ;; load are 2 2 byte instructions.
6091 [(set (match_operand:HI 0 "register_operand" "")
6092 (mem:HI (plus:SI (match_dup 0)
6093 (match_operand:SI 1 "const_int_operand" ""))))]
6094 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6095 && GET_CODE (operands[0]) == REG
6096 && M16_REG_P (REGNO (operands[0]))
6097 && GET_CODE (operands[1]) == CONST_INT
6098 && ((INTVAL (operands[1]) < 0
6099 && INTVAL (operands[1]) >= -0x80)
6100 || (INTVAL (operands[1]) >= 32 * 2
6101 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
6102 || (INTVAL (operands[1]) >= 0
6103 && INTVAL (operands[1]) < 32 * 2
6104 && (INTVAL (operands[1]) & 1) != 0))"
6105 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6106 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
6109 HOST_WIDE_INT val = INTVAL (operands[1]);
6112 operands[2] = GEN_INT (0);
6113 else if (val >= 32 * 2)
6117 operands[1] = GEN_INT (0x7e + off);
6118 operands[2] = GEN_INT (val - off - 0x7e);
6124 operands[1] = GEN_INT (off);
6125 operands[2] = GEN_INT (val - off);
6129 ;; 8-bit Integer moves
6131 ;; Unlike most other insns, the move insns can't be split with
6132 ;; different predicates, because register spilling and other parts of
6133 ;; the compiler, have memoized the insn number already.
6134 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
6136 (define_expand "movqi"
6137 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6138 (match_operand:QI 1 "general_operand" ""))]
6142 if ((reload_in_progress | reload_completed) == 0
6143 && !register_operand (operands[0], QImode)
6144 && !register_operand (operands[1], QImode)
6146 || (GET_CODE (operands[1]) != CONST_INT
6147 || INTVAL (operands[1]) != 0)))
6149 rtx temp = force_reg (QImode, operands[1]);
6150 emit_move_insn (operands[0], temp);
6155 ;; The difference between these two is whether or not ints are allowed
6156 ;; in FP registers (off by default, use -mdebugh to enable).
6158 (define_insn "movqi_internal1"
6159 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
6160 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
6161 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6162 && (register_operand (operands[0], QImode)
6163 || register_operand (operands[1], QImode)
6164 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6165 "* return mips_move_1word (operands, insn, TRUE);"
6166 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
6167 (set_attr "mode" "QI")
6168 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
6170 (define_insn "movqi_internal2"
6171 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
6172 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
6173 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6174 && (register_operand (operands[0], QImode)
6175 || register_operand (operands[1], QImode)
6176 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6177 "* return mips_move_1word (operands, insn, TRUE);"
6178 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
6179 (set_attr "mode" "QI")
6180 (set_attr "length" "4,4,4,8,4,8,4,4,4,4")])
6183 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
6184 (match_operand:QI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
6186 && (register_operand (operands[0], QImode)
6187 || register_operand (operands[1], QImode))"
6188 "* return mips_move_1word (operands, insn, TRUE);"
6189 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
6190 (set_attr "mode" "QI")
6191 (set_attr_alternative "length"
6195 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
6198 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6208 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
6209 ;; when the original load is a 4 byte instruction but the add and the
6210 ;; load are 2 2 byte instructions.
6213 [(set (match_operand:QI 0 "register_operand" "")
6214 (mem:QI (plus:SI (match_dup 0)
6215 (match_operand:SI 1 "const_int_operand" ""))))]
6216 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6217 && GET_CODE (operands[0]) == REG
6218 && M16_REG_P (REGNO (operands[0]))
6219 && GET_CODE (operands[1]) == CONST_INT
6220 && ((INTVAL (operands[1]) < 0
6221 && INTVAL (operands[1]) >= -0x80)
6222 || (INTVAL (operands[1]) >= 32
6223 && INTVAL (operands[1]) <= 31 + 0x7f))"
6224 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6225 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
6228 HOST_WIDE_INT val = INTVAL (operands[1]);
6231 operands[2] = GEN_INT (0);
6234 operands[1] = GEN_INT (0x7f);
6235 operands[2] = GEN_INT (val - 0x7f);
6239 ;; 32-bit floating point moves
6241 (define_expand "movsf"
6242 [(set (match_operand:SF 0 "nonimmediate_operand" "")
6243 (match_operand:SF 1 "general_operand" ""))]
6247 if ((reload_in_progress | reload_completed) == 0
6248 && !register_operand (operands[0], SFmode)
6249 && !register_operand (operands[1], SFmode)
6251 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6252 && operands[1] != CONST0_RTX (SFmode))))
6254 rtx temp = force_reg (SFmode, operands[1]);
6255 emit_move_insn (operands[0], temp);
6260 (define_insn "movsf_internal1"
6261 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
6262 (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
6264 && (register_operand (operands[0], SFmode)
6265 || register_operand (operands[1], SFmode)
6266 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6267 || operands[1] == CONST0_RTX (SFmode))"
6268 "* return mips_move_1word (operands, insn, FALSE);"
6269 [(set_attr "type" "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
6270 (set_attr "mode" "SF")
6271 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,8,4,8")])
6274 (define_insn "movsf_internal2"
6275 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
6276 (match_operand:SF 1 "general_operand" " Gd,R,Fm,d,d"))]
6277 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
6278 && (register_operand (operands[0], SFmode)
6279 || register_operand (operands[1], SFmode)
6280 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6281 || operands[1] == CONST0_RTX (SFmode))"
6282 "* return mips_move_1word (operands, insn, FALSE);"
6283 [(set_attr "type" "move,load,load,store,store")
6284 (set_attr "mode" "SF")
6285 (set_attr "length" "4,4,8,4,8")])
6288 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m")
6289 (match_operand:SF 1 "general_operand" "d,d,y,R,Fm,d,d"))]
6291 && (register_operand (operands[0], SFmode)
6292 || register_operand (operands[1], SFmode))"
6293 "* return mips_move_1word (operands, insn, FALSE);"
6294 [(set_attr "type" "move,move,move,load,load,store,store")
6295 (set_attr "mode" "SF")
6296 (set_attr "length" "4,4,4,4,8,4,8")])
6299 ;; 64-bit floating point moves
6301 (define_expand "movdf"
6302 [(set (match_operand:DF 0 "nonimmediate_operand" "")
6303 (match_operand:DF 1 "general_operand" ""))]
6307 if ((reload_in_progress | reload_completed) == 0
6308 && !register_operand (operands[0], DFmode)
6309 && !register_operand (operands[1], DFmode)
6311 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6312 && operands[1] != CONST0_RTX (DFmode))))
6314 rtx temp = force_reg (DFmode, operands[1]);
6315 emit_move_insn (operands[0], temp);
6320 (define_insn "movdf_internal1"
6321 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,To,f,*f,*d,*d,*d,*d,*R,*T")
6322 (match_operand:DF 1 "general_operand" "f,R,To,fG,fG,F,*d,*f,*d*G,*R,*T*F,*d,*d"))]
6323 "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
6324 && TARGET_DOUBLE_FLOAT
6325 && (register_operand (operands[0], DFmode)
6326 || register_operand (operands[1], DFmode)
6327 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6328 || operands[1] == CONST0_RTX (DFmode))"
6329 "* return mips_move_2words (operands, insn); "
6330 [(set_attr "type" "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
6331 (set_attr "mode" "DF")
6332 (set_attr "length" "4,8,16,8,16,16,8,8,8,8,16,8,16")])
6334 (define_insn "movdf_internal1a"
6335 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,*d,*d,*d,*To,*R,*d")
6336 (match_operand:DF 1 "general_operand" " f,To,f,G,f,G,*F,*To,*R,*d,*d,*d"))]
6337 "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
6338 && TARGET_DOUBLE_FLOAT
6339 && (register_operand (operands[0], DFmode)
6340 || register_operand (operands[1], DFmode)
6341 || (GET_CODE (operands [0]) == MEM
6342 && ((GET_CODE (operands[1]) == CONST_INT
6343 && INTVAL (operands[1]) == 0)
6344 || operands[1] == CONST0_RTX (DFmode))))"
6345 "* return mips_move_2words (operands, insn); "
6346 [(set_attr "type" "move,load,store,store,store,store,load,load,load,store,store,move")
6347 (set_attr "mode" "DF")
6348 (set_attr "length" "4,8,4,4,8,8,8,8,4,8,4,4")])
6350 (define_insn "movdf_internal2"
6351 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To,d,f,f")
6352 (match_operand:DF 1 "general_operand" "dG,R,ToF,d,d,f,d,f"))]
6353 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
6354 && (register_operand (operands[0], DFmode)
6355 || register_operand (operands[1], DFmode)
6356 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6357 || operands[1] == CONST0_RTX (DFmode))"
6358 "* return mips_move_2words (operands, insn); "
6359 [(set_attr "type" "move,load,load,store,store,xfer,load,move")
6360 (set_attr "mode" "DF")
6361 (set_attr "length" "8,8,16,8,16,8,8,4")])
6364 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To")
6365 (match_operand:DF 1 "general_operand" "d,d,y,R,ToF,d,d"))]
6367 && (register_operand (operands[0], DFmode)
6368 || register_operand (operands[1], DFmode))"
6369 "* return mips_move_2words (operands, insn);"
6370 [(set_attr "type" "move,move,move,load,load,store,store")
6371 (set_attr "mode" "DF")
6372 (set_attr "length" "8,8,8,8,16,8,16")])
6375 [(set (match_operand:DF 0 "register_operand" "")
6376 (match_operand:DF 1 "register_operand" ""))]
6377 "reload_completed && !TARGET_64BIT
6378 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6379 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
6380 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
6381 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
6382 (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
6385 ;; Instructions to load the global pointer register.
6386 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
6387 ;; uses in front of it. All symbol_refs implicitly use the gp reg.
6389 (define_insn "loadgp"
6391 (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
6392 (match_operand:DI 1 "register_operand" "")]
6394 (clobber (reg:DI 1))]
6396 "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]"
6397 [(set_attr "type" "move")
6398 (set_attr "mode" "DI")
6399 (set_attr "length" "12")])
6401 ;; Block moves, see mips.c for more details.
6402 ;; Argument 0 is the destination
6403 ;; Argument 1 is the source
6404 ;; Argument 2 is the length
6405 ;; Argument 3 is the alignment
6407 (define_expand "movstrsi"
6408 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
6409 (match_operand:BLK 1 "general_operand" ""))
6410 (use (match_operand:SI 2 "arith32_operand" ""))
6411 (use (match_operand:SI 3 "immediate_operand" ""))])]
6415 if (operands[0]) /* avoid unused code messages */
6417 expand_block_move (operands);
6422 ;; Insn generated by block moves
6424 (define_insn "movstrsi_internal"
6425 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6426 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6427 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6428 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6429 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6430 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6431 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6432 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6433 (use (const_int 0))] ;; normal block move
6435 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6436 [(set_attr "type" "store")
6437 (set_attr "mode" "none")
6438 (set_attr "length" "80")])
6440 ;; We need mips16 versions, because an offset from the stack pointer
6441 ;; is not offsettable, since the stack pointer can only handle 4 and 8
6445 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6446 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6447 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6448 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6449 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6450 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6451 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6452 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6453 (use (const_int 0))] ;; normal block move
6455 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6456 [(set_attr "type" "multi")
6457 (set_attr "mode" "none")
6458 (set_attr "length" "80")])
6460 ;; Split a block move into 2 parts, the first part is everything
6461 ;; except for the last move, and the second part is just the last
6462 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
6463 ;; fill a delay slot. This also prevents a bug in delayed branches
6464 ;; from showing up, which reuses one of the registers in our clobbers.
6467 [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
6468 (mem:BLK (match_operand:SI 1 "register_operand" "")))
6469 (clobber (match_operand:SI 4 "register_operand" ""))
6470 (clobber (match_operand:SI 5 "register_operand" ""))
6471 (clobber (match_operand:SI 6 "register_operand" ""))
6472 (clobber (match_operand:SI 7 "register_operand" ""))
6473 (use (match_operand:SI 2 "small_int" ""))
6474 (use (match_operand:SI 3 "small_int" ""))
6475 (use (const_int 0))]
6477 "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
6479 ;; All but the last move
6480 [(parallel [(set (mem:BLK (match_dup 0))
6481 (mem:BLK (match_dup 1)))
6482 (clobber (match_dup 4))
6483 (clobber (match_dup 5))
6484 (clobber (match_dup 6))
6485 (clobber (match_dup 7))
6488 (use (const_int 1))])
6490 ;; The last store, so it can fill a delay slot
6491 (parallel [(set (mem:BLK (match_dup 0))
6492 (mem:BLK (match_dup 1)))
6493 (clobber (match_dup 4))
6494 (clobber (match_dup 5))
6495 (clobber (match_dup 6))
6496 (clobber (match_dup 7))
6499 (use (const_int 2))])]
6503 (define_insn "movstrsi_internal2"
6504 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6505 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6506 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6507 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6508 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6509 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6510 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6511 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6512 (use (const_int 1))] ;; all but last store
6514 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6515 [(set_attr "type" "store")
6516 (set_attr "mode" "none")
6517 (set_attr "length" "80")])
6520 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6521 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6522 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6523 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6524 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6525 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6526 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6527 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6528 (use (const_int 1))] ;; all but last store
6530 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6531 [(set_attr "type" "multi")
6532 (set_attr "mode" "none")
6533 (set_attr "length" "80")])
6535 (define_insn "movstrsi_internal3"
6536 [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
6537 (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
6538 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6539 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6540 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6541 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6542 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6543 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6544 (use (const_int 2))] ;; just last store of block move
6546 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6547 [(set_attr "type" "store")
6548 (set_attr "mode" "none")])
6551 ;; ....................
6555 ;; ....................
6557 ;; Many of these instructions uses trivial define_expands, because we
6558 ;; want to use a different set of constraints when TARGET_MIPS16.
6560 (define_expand "ashlsi3"
6561 [(set (match_operand:SI 0 "register_operand" "=d")
6562 (ashift:SI (match_operand:SI 1 "register_operand" "d")
6563 (match_operand:SI 2 "arith_operand" "dI")))]
6567 /* On the mips16, a shift of more than 8 is a four byte instruction,
6568 so, for a shift between 8 and 16, it is just as fast to do two
6569 shifts of 8 or less. If there is a lot of shifting going on, we
6570 may win in CSE. Otherwise combine will put the shifts back
6571 together again. This can be called by function_arg, so we must
6572 be careful not to allocate a new register if we've reached the
6576 && GET_CODE (operands[2]) == CONST_INT
6577 && INTVAL (operands[2]) > 8
6578 && INTVAL (operands[2]) <= 16
6579 && ! reload_in_progress
6580 && ! reload_completed)
6582 rtx temp = gen_reg_rtx (SImode);
6584 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
6585 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
6586 GEN_INT (INTVAL (operands[2]) - 8)));
6591 (define_insn "ashlsi3_internal1"
6592 [(set (match_operand:SI 0 "register_operand" "=d")
6593 (ashift:SI (match_operand:SI 1 "register_operand" "d")
6594 (match_operand:SI 2 "arith_operand" "dI")))]
6598 if (GET_CODE (operands[2]) == CONST_INT)
6599 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6601 return \"sll\\t%0,%1,%2\";
6603 [(set_attr "type" "arith")
6604 (set_attr "mode" "SI")])
6606 (define_insn "ashlsi3_internal2"
6607 [(set (match_operand:SI 0 "register_operand" "=d,d")
6608 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
6609 (match_operand:SI 2 "arith_operand" "d,I")))]
6613 if (which_alternative == 0)
6614 return \"sll\\t%0,%2\";
6616 if (GET_CODE (operands[2]) == CONST_INT)
6617 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6619 return \"sll\\t%0,%1,%2\";
6621 [(set_attr "type" "arith")
6622 (set_attr "mode" "SI")
6623 (set_attr_alternative "length"
6625 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6629 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6632 [(set (match_operand:SI 0 "register_operand" "")
6633 (ashift:SI (match_operand:SI 1 "register_operand" "")
6634 (match_operand:SI 2 "const_int_operand" "")))]
6635 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6636 && GET_CODE (operands[2]) == CONST_INT
6637 && INTVAL (operands[2]) > 8
6638 && INTVAL (operands[2]) <= 16"
6639 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
6640 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
6643 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6646 (define_expand "ashldi3"
6647 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6648 (ashift:DI (match_operand:DI 1 "se_register_operand" "")
6649 (match_operand:SI 2 "arith_operand" "")))
6650 (clobber (match_dup 3))])]
6651 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6656 /* On the mips16, a shift of more than 8 is a four byte
6657 instruction, so, for a shift between 8 and 16, it is just as
6658 fast to do two shifts of 8 or less. If there is a lot of
6659 shifting going on, we may win in CSE. Otherwise combine will
6660 put the shifts back together again. This can be called by
6661 function_arg, so we must be careful not to allocate a new
6662 register if we've reached the reload pass. */
6665 && GET_CODE (operands[2]) == CONST_INT
6666 && INTVAL (operands[2]) > 8
6667 && INTVAL (operands[2]) <= 16
6668 && ! reload_in_progress
6669 && ! reload_completed)
6671 rtx temp = gen_reg_rtx (DImode);
6673 emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
6674 emit_insn (gen_ashldi3_internal4 (operands[0], temp,
6675 GEN_INT (INTVAL (operands[2]) - 8)));
6679 emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
6684 operands[3] = gen_reg_rtx (SImode);
6688 (define_insn "ashldi3_internal"
6689 [(set (match_operand:DI 0 "register_operand" "=&d")
6690 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6691 (match_operand:SI 2 "register_operand" "d")))
6692 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6693 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6696 operands[4] = const0_rtx;
6697 dslots_jump_total += 3;
6698 dslots_jump_filled += 2;
6700 return \"sll\\t%3,%2,26\\n\\
6701 \\tbgez\\t%3,1f\\n\\
6702 \\tsll\\t%M0,%L1,%2\\n\\
6704 \\tmove\\t%L0,%z4%)\\n\\
6707 \\t%(beq\\t%3,%z4,2f\\n\\
6708 \\tsll\\t%M0,%M1,%2%)\\n\\
6710 \\tsubu\\t%3,%z4,%2\\n\\
6711 \\tsrl\\t%3,%L1,%3\\n\\
6712 \\tor\\t%M0,%M0,%3\\n\\
6714 \\tsll\\t%L0,%L1,%2\\n\\
6717 [(set_attr "type" "darith")
6718 (set_attr "mode" "SI")
6719 (set_attr "length" "48")])
6722 (define_insn "ashldi3_internal2"
6723 [(set (match_operand:DI 0 "register_operand" "=d")
6724 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6725 (match_operand:SI 2 "small_int" "IJK")))
6726 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6727 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6728 && (INTVAL (operands[2]) & 32) != 0"
6731 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6732 operands[4] = const0_rtx;
6733 return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
6735 [(set_attr "type" "darith")
6736 (set_attr "mode" "DI")
6737 (set_attr "length" "8")])
6741 [(set (match_operand:DI 0 "register_operand" "")
6742 (ashift:DI (match_operand:DI 1 "register_operand" "")
6743 (match_operand:SI 2 "small_int" "")))
6744 (clobber (match_operand:SI 3 "register_operand" ""))]
6745 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6746 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6747 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6748 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6749 && (INTVAL (operands[2]) & 32) != 0"
6751 [(set (subreg:SI (match_dup 0) 4) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6752 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6754 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6758 [(set (match_operand:DI 0 "register_operand" "")
6759 (ashift:DI (match_operand:DI 1 "register_operand" "")
6760 (match_operand:SI 2 "small_int" "")))
6761 (clobber (match_operand:SI 3 "register_operand" ""))]
6762 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6763 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6764 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6765 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6766 && (INTVAL (operands[2]) & 32) != 0"
6768 [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
6769 (set (subreg:SI (match_dup 0) 4) (const_int 0))]
6771 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6774 (define_insn "ashldi3_internal3"
6775 [(set (match_operand:DI 0 "register_operand" "=d")
6776 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6777 (match_operand:SI 2 "small_int" "IJK")))
6778 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6779 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6780 && (INTVAL (operands[2]) & 63) < 32
6781 && (INTVAL (operands[2]) & 63) != 0"
6784 int amount = INTVAL (operands[2]);
6786 operands[2] = GEN_INT (amount & 31);
6787 operands[4] = const0_rtx;
6788 operands[5] = GEN_INT ((-amount) & 31);
6790 return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
6792 [(set_attr "type" "darith")
6793 (set_attr "mode" "DI")
6794 (set_attr "length" "16")])
6798 [(set (match_operand:DI 0 "register_operand" "")
6799 (ashift:DI (match_operand:DI 1 "register_operand" "")
6800 (match_operand:SI 2 "small_int" "")))
6801 (clobber (match_operand:SI 3 "register_operand" ""))]
6802 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6803 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6804 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6805 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6806 && (INTVAL (operands[2]) & 63) < 32
6807 && (INTVAL (operands[2]) & 63) != 0"
6809 [(set (subreg:SI (match_dup 0) 4)
6810 (ashift:SI (subreg:SI (match_dup 1) 4)
6814 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6817 (set (subreg:SI (match_dup 0) 4)
6818 (ior:SI (subreg:SI (match_dup 0) 4)
6821 (set (subreg:SI (match_dup 0) 0)
6822 (ashift:SI (subreg:SI (match_dup 1) 0)
6826 int amount = INTVAL (operands[2]);
6827 operands[2] = GEN_INT (amount & 31);
6828 operands[4] = GEN_INT ((-amount) & 31);
6833 [(set (match_operand:DI 0 "register_operand" "")
6834 (ashift:DI (match_operand:DI 1 "register_operand" "")
6835 (match_operand:SI 2 "small_int" "")))
6836 (clobber (match_operand:SI 3 "register_operand" ""))]
6837 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6838 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6839 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6840 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6841 && (INTVAL (operands[2]) & 63) < 32
6842 && (INTVAL (operands[2]) & 63) != 0"
6844 [(set (subreg:SI (match_dup 0) 0)
6845 (ashift:SI (subreg:SI (match_dup 1) 0)
6849 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
6852 (set (subreg:SI (match_dup 0) 0)
6853 (ior:SI (subreg:SI (match_dup 0) 0)
6856 (set (subreg:SI (match_dup 0) 4)
6857 (ashift:SI (subreg:SI (match_dup 1) 4)
6861 int amount = INTVAL (operands[2]);
6862 operands[2] = GEN_INT (amount & 31);
6863 operands[4] = GEN_INT ((-amount) & 31);
6867 (define_insn "ashldi3_internal4"
6868 [(set (match_operand:DI 0 "register_operand" "=d")
6869 (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
6870 (match_operand:SI 2 "arith_operand" "dI")))]
6871 "TARGET_64BIT && !TARGET_MIPS16"
6874 if (GET_CODE (operands[2]) == CONST_INT)
6875 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6877 return \"dsll\\t%0,%1,%2\";
6879 [(set_attr "type" "arith")
6880 (set_attr "mode" "DI")])
6883 [(set (match_operand:DI 0 "register_operand" "=d,d")
6884 (ashift:DI (match_operand:DI 1 "se_register_operand" "0,d")
6885 (match_operand:SI 2 "arith_operand" "d,I")))]
6886 "TARGET_64BIT && TARGET_MIPS16"
6889 if (which_alternative == 0)
6890 return \"dsll\\t%0,%2\";
6892 if (GET_CODE (operands[2]) == CONST_INT)
6893 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6895 return \"dsll\\t%0,%1,%2\";
6897 [(set_attr "type" "arith")
6898 (set_attr "mode" "DI")
6899 (set_attr_alternative "length"
6901 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6906 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6909 [(set (match_operand:DI 0 "register_operand" "")
6910 (ashift:DI (match_operand:DI 1 "register_operand" "")
6911 (match_operand:SI 2 "const_int_operand" "")))]
6912 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
6914 && GET_CODE (operands[2]) == CONST_INT
6915 && INTVAL (operands[2]) > 8
6916 && INTVAL (operands[2]) <= 16"
6917 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
6918 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
6921 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6924 (define_expand "ashrsi3"
6925 [(set (match_operand:SI 0 "register_operand" "=d")
6926 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6927 (match_operand:SI 2 "arith_operand" "dI")))]
6931 /* On the mips16, a shift of more than 8 is a four byte instruction,
6932 so, for a shift between 8 and 16, it is just as fast to do two
6933 shifts of 8 or less. If there is a lot of shifting going on, we
6934 may win in CSE. Otherwise combine will put the shifts back
6938 && GET_CODE (operands[2]) == CONST_INT
6939 && INTVAL (operands[2]) > 8
6940 && INTVAL (operands[2]) <= 16)
6942 rtx temp = gen_reg_rtx (SImode);
6944 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6945 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
6946 GEN_INT (INTVAL (operands[2]) - 8)));
6951 (define_insn "ashrsi3_internal1"
6952 [(set (match_operand:SI 0 "register_operand" "=d")
6953 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6954 (match_operand:SI 2 "arith_operand" "dI")))]
6958 if (GET_CODE (operands[2]) == CONST_INT)
6959 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6961 return \"sra\\t%0,%1,%2\";
6963 [(set_attr "type" "arith")
6964 (set_attr "mode" "SI")])
6966 (define_insn "ashrsi3_internal2"
6967 [(set (match_operand:SI 0 "register_operand" "=d,d")
6968 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6969 (match_operand:SI 2 "arith_operand" "d,I")))]
6973 if (which_alternative == 0)
6974 return \"sra\\t%0,%2\";
6976 if (GET_CODE (operands[2]) == CONST_INT)
6977 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6979 return \"sra\\t%0,%1,%2\";
6981 [(set_attr "type" "arith")
6982 (set_attr "mode" "SI")
6983 (set_attr_alternative "length"
6985 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6990 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6993 [(set (match_operand:SI 0 "register_operand" "")
6994 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6995 (match_operand:SI 2 "const_int_operand" "")))]
6996 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6997 && GET_CODE (operands[2]) == CONST_INT
6998 && INTVAL (operands[2]) > 8
6999 && INTVAL (operands[2]) <= 16"
7000 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
7001 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
7004 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7007 (define_expand "ashrdi3"
7008 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7009 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7010 (match_operand:SI 2 "arith_operand" "")))
7011 (clobber (match_dup 3))])]
7012 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7017 /* On the mips16, a shift of more than 8 is a four byte
7018 instruction, so, for a shift between 8 and 16, it is just as
7019 fast to do two shifts of 8 or less. If there is a lot of
7020 shifting going on, we may win in CSE. Otherwise combine will
7021 put the shifts back together again. */
7024 && GET_CODE (operands[2]) == CONST_INT
7025 && INTVAL (operands[2]) > 8
7026 && INTVAL (operands[2]) <= 16)
7028 rtx temp = gen_reg_rtx (DImode);
7030 emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7031 emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
7032 GEN_INT (INTVAL (operands[2]) - 8)));
7036 emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
7041 operands[3] = gen_reg_rtx (SImode);
7045 (define_insn "ashrdi3_internal"
7046 [(set (match_operand:DI 0 "register_operand" "=&d")
7047 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7048 (match_operand:SI 2 "register_operand" "d")))
7049 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7050 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7053 operands[4] = const0_rtx;
7054 dslots_jump_total += 3;
7055 dslots_jump_filled += 2;
7057 return \"sll\\t%3,%2,26\\n\\
7058 \\tbgez\\t%3,1f\\n\\
7059 \\tsra\\t%L0,%M1,%2\\n\\
7061 \\tsra\\t%M0,%M1,31%)\\n\\
7064 \\t%(beq\\t%3,%z4,2f\\n\\
7065 \\tsrl\\t%L0,%L1,%2%)\\n\\
7067 \\tsubu\\t%3,%z4,%2\\n\\
7068 \\tsll\\t%3,%M1,%3\\n\\
7069 \\tor\\t%L0,%L0,%3\\n\\
7071 \\tsra\\t%M0,%M1,%2\\n\\
7074 [(set_attr "type" "darith")
7075 (set_attr "mode" "DI")
7076 (set_attr "length" "48")])
7079 (define_insn "ashrdi3_internal2"
7080 [(set (match_operand:DI 0 "register_operand" "=d")
7081 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7082 (match_operand:SI 2 "small_int" "IJK")))
7083 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7084 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
7087 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7088 return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
7090 [(set_attr "type" "darith")
7091 (set_attr "mode" "DI")
7092 (set_attr "length" "8")])
7096 [(set (match_operand:DI 0 "register_operand" "")
7097 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7098 (match_operand:SI 2 "small_int" "")))
7099 (clobber (match_operand:SI 3 "register_operand" ""))]
7100 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7101 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7102 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7103 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7104 && (INTVAL (operands[2]) & 32) != 0"
7106 [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7107 (set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (const_int 31)))]
7109 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7113 [(set (match_operand:DI 0 "register_operand" "")
7114 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7115 (match_operand:SI 2 "small_int" "")))
7116 (clobber (match_operand:SI 3 "register_operand" ""))]
7117 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7118 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7119 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7120 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7121 && (INTVAL (operands[2]) & 32) != 0"
7123 [(set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7124 (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
7126 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7129 (define_insn "ashrdi3_internal3"
7130 [(set (match_operand:DI 0 "register_operand" "=d")
7131 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7132 (match_operand:SI 2 "small_int" "IJK")))
7133 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7134 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7135 && (INTVAL (operands[2]) & 63) < 32
7136 && (INTVAL (operands[2]) & 63) != 0"
7139 int amount = INTVAL (operands[2]);
7141 operands[2] = GEN_INT (amount & 31);
7142 operands[4] = GEN_INT ((-amount) & 31);
7144 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
7146 [(set_attr "type" "darith")
7147 (set_attr "mode" "DI")
7148 (set_attr "length" "16")])
7152 [(set (match_operand:DI 0 "register_operand" "")
7153 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7154 (match_operand:SI 2 "small_int" "")))
7155 (clobber (match_operand:SI 3 "register_operand" ""))]
7156 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7157 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7158 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7159 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7160 && (INTVAL (operands[2]) & 63) < 32
7161 && (INTVAL (operands[2]) & 63) != 0"
7163 [(set (subreg:SI (match_dup 0) 0)
7164 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7168 (ashift:SI (subreg:SI (match_dup 1) 4)
7171 (set (subreg:SI (match_dup 0) 0)
7172 (ior:SI (subreg:SI (match_dup 0) 0)
7175 (set (subreg:SI (match_dup 0) 4)
7176 (ashiftrt:SI (subreg:SI (match_dup 1) 4)
7180 int amount = INTVAL (operands[2]);
7181 operands[2] = GEN_INT (amount & 31);
7182 operands[4] = GEN_INT ((-amount) & 31);
7187 [(set (match_operand:DI 0 "register_operand" "")
7188 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7189 (match_operand:SI 2 "small_int" "")))
7190 (clobber (match_operand:SI 3 "register_operand" ""))]
7191 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7192 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7193 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7194 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7195 && (INTVAL (operands[2]) & 63) < 32
7196 && (INTVAL (operands[2]) & 63) != 0"
7198 [(set (subreg:SI (match_dup 0) 4)
7199 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7203 (ashift:SI (subreg:SI (match_dup 1) 0)
7206 (set (subreg:SI (match_dup 0) 4)
7207 (ior:SI (subreg:SI (match_dup 0) 4)
7210 (set (subreg:SI (match_dup 0) 0)
7211 (ashiftrt:SI (subreg:SI (match_dup 1) 0)
7215 int amount = INTVAL (operands[2]);
7216 operands[2] = GEN_INT (amount & 31);
7217 operands[4] = GEN_INT ((-amount) & 31);
7221 (define_insn "ashrdi3_internal4"
7222 [(set (match_operand:DI 0 "register_operand" "=d")
7223 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7224 (match_operand:SI 2 "arith_operand" "dI")))]
7225 "TARGET_64BIT && !TARGET_MIPS16"
7228 if (GET_CODE (operands[2]) == CONST_INT)
7229 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7231 return \"dsra\\t%0,%1,%2\";
7233 [(set_attr "type" "arith")
7234 (set_attr "mode" "DI")])
7237 [(set (match_operand:DI 0 "register_operand" "=d,d")
7238 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7239 (match_operand:SI 2 "arith_operand" "d,I")))]
7240 "TARGET_64BIT && TARGET_MIPS16"
7243 if (GET_CODE (operands[2]) == CONST_INT)
7244 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7246 return \"dsra\\t%0,%2\";
7248 [(set_attr "type" "arith")
7249 (set_attr "mode" "DI")
7250 (set_attr_alternative "length"
7252 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7256 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7259 [(set (match_operand:DI 0 "register_operand" "")
7260 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7261 (match_operand:SI 2 "const_int_operand" "")))]
7262 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
7264 && GET_CODE (operands[2]) == CONST_INT
7265 && INTVAL (operands[2]) > 8
7266 && INTVAL (operands[2]) <= 16"
7267 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
7268 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
7271 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7274 (define_expand "lshrsi3"
7275 [(set (match_operand:SI 0 "register_operand" "=d")
7276 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7277 (match_operand:SI 2 "arith_operand" "dI")))]
7281 /* On the mips16, a shift of more than 8 is a four byte instruction,
7282 so, for a shift between 8 and 16, it is just as fast to do two
7283 shifts of 8 or less. If there is a lot of shifting going on, we
7284 may win in CSE. Otherwise combine will put the shifts back
7288 && GET_CODE (operands[2]) == CONST_INT
7289 && INTVAL (operands[2]) > 8
7290 && INTVAL (operands[2]) <= 16)
7292 rtx temp = gen_reg_rtx (SImode);
7294 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
7295 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
7296 GEN_INT (INTVAL (operands[2]) - 8)));
7301 (define_insn "lshrsi3_internal1"
7302 [(set (match_operand:SI 0 "register_operand" "=d")
7303 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7304 (match_operand:SI 2 "arith_operand" "dI")))]
7308 if (GET_CODE (operands[2]) == CONST_INT)
7309 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7311 return \"srl\\t%0,%1,%2\";
7313 [(set_attr "type" "arith")
7314 (set_attr "mode" "SI")])
7316 (define_insn "lshrsi3_internal2"
7317 [(set (match_operand:SI 0 "register_operand" "=d,d")
7318 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
7319 (match_operand:SI 2 "arith_operand" "d,I")))]
7323 if (which_alternative == 0)
7324 return \"srl\\t%0,%2\";
7326 if (GET_CODE (operands[2]) == CONST_INT)
7327 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7329 return \"srl\\t%0,%1,%2\";
7331 [(set_attr "type" "arith")
7332 (set_attr "mode" "SI")
7333 (set_attr_alternative "length"
7335 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7340 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7343 [(set (match_operand:SI 0 "register_operand" "")
7344 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
7345 (match_operand:SI 2 "const_int_operand" "")))]
7346 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7347 && GET_CODE (operands[2]) == CONST_INT
7348 && INTVAL (operands[2]) > 8
7349 && INTVAL (operands[2]) <= 16"
7350 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
7351 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7354 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7357 ;; If we load a byte on the mips16 as a bitfield, the resulting
7358 ;; sequence of instructions is too complicated for combine, because it
7359 ;; involves four instructions: a load, a shift, a constant load into a
7360 ;; register, and an and (the key problem here is that the mips16 does
7361 ;; not have and immediate). We recognize a shift of a load in order
7362 ;; to make it simple enough for combine to understand.
7365 [(set (match_operand:SI 0 "register_operand" "=d,d")
7366 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "R,m")
7367 (match_operand:SI 2 "immediate_operand" "I,I")))]
7369 "lw\\t%0,%1\;srl\\t%0,%2"
7370 [(set_attr "type" "load")
7371 (set_attr "mode" "SI")
7372 (set_attr_alternative "length"
7373 [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7376 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7381 [(set (match_operand:SI 0 "register_operand" "")
7382 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "")
7383 (match_operand:SI 2 "immediate_operand" "")))]
7384 "TARGET_MIPS16 && !TARGET_DEBUG_D_MODE"
7385 [(set (match_dup 0) (match_dup 1))
7386 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7389 (define_expand "lshrdi3"
7390 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7391 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7392 (match_operand:SI 2 "arith_operand" "")))
7393 (clobber (match_dup 3))])]
7394 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7399 /* On the mips16, a shift of more than 8 is a four byte
7400 instruction, so, for a shift between 8 and 16, it is just as
7401 fast to do two shifts of 8 or less. If there is a lot of
7402 shifting going on, we may win in CSE. Otherwise combine will
7403 put the shifts back together again. */
7406 && GET_CODE (operands[2]) == CONST_INT
7407 && INTVAL (operands[2]) > 8
7408 && INTVAL (operands[2]) <= 16)
7410 rtx temp = gen_reg_rtx (DImode);
7412 emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7413 emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
7414 GEN_INT (INTVAL (operands[2]) - 8)));
7418 emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
7423 operands[3] = gen_reg_rtx (SImode);
7427 (define_insn "lshrdi3_internal"
7428 [(set (match_operand:DI 0 "register_operand" "=&d")
7429 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7430 (match_operand:SI 2 "register_operand" "d")))
7431 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7432 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7435 operands[4] = const0_rtx;
7436 dslots_jump_total += 3;
7437 dslots_jump_filled += 2;
7439 return \"sll\\t%3,%2,26\\n\\
7440 \\tbgez\\t%3,1f\\n\\
7441 \\tsrl\\t%L0,%M1,%2\\n\\
7443 \\tmove\\t%M0,%z4%)\\n\\
7446 \\t%(beq\\t%3,%z4,2f\\n\\
7447 \\tsrl\\t%L0,%L1,%2%)\\n\\
7449 \\tsubu\\t%3,%z4,%2\\n\\
7450 \\tsll\\t%3,%M1,%3\\n\\
7451 \\tor\\t%L0,%L0,%3\\n\\
7453 \\tsrl\\t%M0,%M1,%2\\n\\
7456 [(set_attr "type" "darith")
7457 (set_attr "mode" "DI")
7458 (set_attr "length" "48")])
7461 (define_insn "lshrdi3_internal2"
7462 [(set (match_operand:DI 0 "register_operand" "=d")
7463 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7464 (match_operand:SI 2 "small_int" "IJK")))
7465 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7466 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7467 && (INTVAL (operands[2]) & 32) != 0"
7470 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7471 operands[4] = const0_rtx;
7472 return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
7474 [(set_attr "type" "darith")
7475 (set_attr "mode" "DI")
7476 (set_attr "length" "8")])
7480 [(set (match_operand:DI 0 "register_operand" "")
7481 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7482 (match_operand:SI 2 "small_int" "")))
7483 (clobber (match_operand:SI 3 "register_operand" ""))]
7484 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7485 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7486 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7487 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7488 && (INTVAL (operands[2]) & 32) != 0"
7490 [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7491 (set (subreg:SI (match_dup 0) 4) (const_int 0))]
7493 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7497 [(set (match_operand:DI 0 "register_operand" "")
7498 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7499 (match_operand:SI 2 "small_int" "")))
7500 (clobber (match_operand:SI 3 "register_operand" ""))]
7501 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7502 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7503 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7504 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7505 && (INTVAL (operands[2]) & 32) != 0"
7507 [(set (subreg:SI (match_dup 0) 4) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7508 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
7510 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7513 (define_insn "lshrdi3_internal3"
7514 [(set (match_operand:DI 0 "register_operand" "=d")
7515 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7516 (match_operand:SI 2 "small_int" "IJK")))
7517 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7518 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7519 && (INTVAL (operands[2]) & 63) < 32
7520 && (INTVAL (operands[2]) & 63) != 0"
7523 int amount = INTVAL (operands[2]);
7525 operands[2] = GEN_INT (amount & 31);
7526 operands[4] = GEN_INT ((-amount) & 31);
7528 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
7530 [(set_attr "type" "darith")
7531 (set_attr "mode" "DI")
7532 (set_attr "length" "16")])
7536 [(set (match_operand:DI 0 "register_operand" "")
7537 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7538 (match_operand:SI 2 "small_int" "")))
7539 (clobber (match_operand:SI 3 "register_operand" ""))]
7540 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7541 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7542 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7543 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7544 && (INTVAL (operands[2]) & 63) < 32
7545 && (INTVAL (operands[2]) & 63) != 0"
7547 [(set (subreg:SI (match_dup 0) 0)
7548 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7552 (ashift:SI (subreg:SI (match_dup 1) 4)
7555 (set (subreg:SI (match_dup 0) 0)
7556 (ior:SI (subreg:SI (match_dup 0) 0)
7559 (set (subreg:SI (match_dup 0) 4)
7560 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7564 int amount = INTVAL (operands[2]);
7565 operands[2] = GEN_INT (amount & 31);
7566 operands[4] = GEN_INT ((-amount) & 31);
7571 [(set (match_operand:DI 0 "register_operand" "")
7572 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7573 (match_operand:SI 2 "small_int" "")))
7574 (clobber (match_operand:SI 3 "register_operand" ""))]
7575 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7576 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7577 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7578 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7579 && (INTVAL (operands[2]) & 63) < 32
7580 && (INTVAL (operands[2]) & 63) != 0"
7582 [(set (subreg:SI (match_dup 0) 4)
7583 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7587 (ashift:SI (subreg:SI (match_dup 1) 0)
7590 (set (subreg:SI (match_dup 0) 4)
7591 (ior:SI (subreg:SI (match_dup 0) 4)
7594 (set (subreg:SI (match_dup 0) 0)
7595 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7599 int amount = INTVAL (operands[2]);
7600 operands[2] = GEN_INT (amount & 31);
7601 operands[4] = GEN_INT ((-amount) & 31);
7605 (define_insn "lshrdi3_internal4"
7606 [(set (match_operand:DI 0 "register_operand" "=d")
7607 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7608 (match_operand:SI 2 "arith_operand" "dI")))]
7609 "TARGET_64BIT && !TARGET_MIPS16"
7612 if (GET_CODE (operands[2]) == CONST_INT)
7613 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7615 return \"dsrl\\t%0,%1,%2\";
7617 [(set_attr "type" "arith")
7618 (set_attr "mode" "DI")])
7621 [(set (match_operand:DI 0 "register_operand" "=d,d")
7622 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7623 (match_operand:SI 2 "arith_operand" "d,I")))]
7624 "TARGET_64BIT && TARGET_MIPS16"
7627 if (GET_CODE (operands[2]) == CONST_INT)
7628 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7630 return \"dsrl\\t%0,%2\";
7632 [(set_attr "type" "arith")
7633 (set_attr "mode" "DI")
7634 (set_attr_alternative "length"
7636 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7640 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7643 [(set (match_operand:DI 0 "register_operand" "")
7644 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7645 (match_operand:SI 2 "const_int_operand" "")))]
7646 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7647 && GET_CODE (operands[2]) == CONST_INT
7648 && INTVAL (operands[2]) > 8
7649 && INTVAL (operands[2]) <= 16"
7650 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
7651 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
7654 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7659 ;; ....................
7663 ;; ....................
7665 ;; Flow here is rather complex:
7667 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
7668 ;; arguments into the branch_cmp array, and the type into
7669 ;; branch_type. No RTL is generated.
7671 ;; 2) The appropriate branch define_expand is called, which then
7672 ;; creates the appropriate RTL for the comparison and branch.
7673 ;; Different CC modes are used, based on what type of branch is
7674 ;; done, so that we can constrain things appropriately. There
7675 ;; are assumptions in the rest of GCC that break if we fold the
7676 ;; operands into the branchs for integer operations, and use cc0
7677 ;; for floating point, so we use the fp status register instead.
7678 ;; If needed, an appropriate temporary is created to hold the
7679 ;; of the integer compare.
7681 (define_expand "cmpsi"
7683 (compare:CC (match_operand:SI 0 "register_operand" "")
7684 (match_operand:SI 1 "arith_operand" "")))]
7688 if (operands[0]) /* avoid unused code message */
7690 branch_cmp[0] = operands[0];
7691 branch_cmp[1] = operands[1];
7692 branch_type = CMP_SI;
7697 (define_expand "tstsi"
7699 (match_operand:SI 0 "register_operand" ""))]
7703 if (operands[0]) /* avoid unused code message */
7705 branch_cmp[0] = operands[0];
7706 branch_cmp[1] = const0_rtx;
7707 branch_type = CMP_SI;
7712 (define_expand "cmpdi"
7714 (compare:CC (match_operand:DI 0 "se_register_operand" "")
7715 (match_operand:DI 1 "se_arith_operand" "")))]
7719 if (operands[0]) /* avoid unused code message */
7721 branch_cmp[0] = operands[0];
7722 branch_cmp[1] = operands[1];
7723 branch_type = CMP_DI;
7728 (define_expand "tstdi"
7730 (match_operand:DI 0 "se_register_operand" ""))]
7734 if (operands[0]) /* avoid unused code message */
7736 branch_cmp[0] = operands[0];
7737 branch_cmp[1] = const0_rtx;
7738 branch_type = CMP_DI;
7743 (define_expand "cmpdf"
7745 (compare:CC (match_operand:DF 0 "register_operand" "")
7746 (match_operand:DF 1 "register_operand" "")))]
7747 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7750 if (operands[0]) /* avoid unused code message */
7752 branch_cmp[0] = operands[0];
7753 branch_cmp[1] = operands[1];
7754 branch_type = CMP_DF;
7759 (define_expand "cmpsf"
7761 (compare:CC (match_operand:SF 0 "register_operand" "")
7762 (match_operand:SF 1 "register_operand" "")))]
7766 if (operands[0]) /* avoid unused code message */
7768 branch_cmp[0] = operands[0];
7769 branch_cmp[1] = operands[1];
7770 branch_type = CMP_SF;
7777 ;; ....................
7779 ;; CONDITIONAL BRANCHES
7781 ;; ....................
7783 ;; Conditional branches on floating-point equality tests.
7785 (define_insn "branch_fp"
7788 (match_operator:CC 0 "cmp_op"
7789 [(match_operand:CC 2 "register_operand" "z")
7791 (label_ref (match_operand 1 "" ""))
7796 return mips_output_conditional_branch (insn,
7798 /*two_operands_p=*/0,
7801 get_attr_length (insn));
7803 [(set_attr "type" "branch")
7804 (set_attr "mode" "none")])
7806 (define_insn "branch_fp_inverted"
7809 (match_operator:CC 0 "cmp_op"
7810 [(match_operand:CC 2 "register_operand" "z")
7813 (label_ref (match_operand 1 "" ""))))]
7817 return mips_output_conditional_branch (insn,
7819 /*two_operands_p=*/0,
7822 get_attr_length (insn));
7824 [(set_attr "type" "branch")
7825 (set_attr "mode" "none")])
7827 ;; Conditional branches on comparisons with zero.
7829 (define_insn "branch_zero"
7832 (match_operator:SI 0 "cmp_op"
7833 [(match_operand:SI 2 "register_operand" "d")
7835 (label_ref (match_operand 1 "" ""))
7840 return mips_output_conditional_branch (insn,
7842 /*two_operands_p=*/0,
7845 get_attr_length (insn));
7847 [(set_attr "type" "branch")
7848 (set_attr "mode" "none")])
7850 (define_insn "branch_zero_inverted"
7853 (match_operator:SI 0 "cmp_op"
7854 [(match_operand:SI 2 "register_operand" "d")
7857 (label_ref (match_operand 1 "" ""))))]
7861 return mips_output_conditional_branch (insn,
7863 /*two_operands_p=*/0,
7866 get_attr_length (insn));
7868 [(set_attr "type" "branch")
7869 (set_attr "mode" "none")])
7871 (define_insn "branch_zero_di"
7874 (match_operator:DI 0 "cmp_op"
7875 [(match_operand:DI 2 "se_register_operand" "d")
7877 (label_ref (match_operand 1 "" ""))
7882 return mips_output_conditional_branch (insn,
7884 /*two_operands_p=*/0,
7887 get_attr_length (insn));
7889 [(set_attr "type" "branch")
7890 (set_attr "mode" "none")])
7892 (define_insn "branch_zero_di_inverted"
7895 (match_operator:DI 0 "cmp_op"
7896 [(match_operand:DI 2 "se_register_operand" "d")
7899 (label_ref (match_operand 1 "" ""))))]
7903 return mips_output_conditional_branch (insn,
7905 /*two_operands_p=*/0,
7908 get_attr_length (insn));
7910 [(set_attr "type" "branch")
7911 (set_attr "mode" "none")])
7913 ;; Conditional branch on equality comparision.
7915 (define_insn "branch_equality"
7918 (match_operator:SI 0 "equality_op"
7919 [(match_operand:SI 2 "register_operand" "d")
7920 (match_operand:SI 3 "register_operand" "d")])
7921 (label_ref (match_operand 1 "" ""))
7926 return mips_output_conditional_branch (insn,
7928 /*two_operands_p=*/1,
7931 get_attr_length (insn));
7933 [(set_attr "type" "branch")
7934 (set_attr "mode" "none")])
7936 (define_insn "branch_equality_di"
7939 (match_operator:DI 0 "equality_op"
7940 [(match_operand:DI 2 "se_register_operand" "d")
7941 (match_operand:DI 3 "se_register_operand" "d")])
7942 (label_ref (match_operand 1 "" ""))
7947 return mips_output_conditional_branch (insn,
7949 /*two_operands_p=*/1,
7952 get_attr_length (insn));
7954 [(set_attr "type" "branch")
7955 (set_attr "mode" "none")])
7957 (define_insn "branch_equality_inverted"
7960 (match_operator:SI 0 "equality_op"
7961 [(match_operand:SI 2 "register_operand" "d")
7962 (match_operand:SI 3 "register_operand" "d")])
7964 (label_ref (match_operand 1 "" ""))))]
7968 return mips_output_conditional_branch (insn,
7970 /*two_operands_p=*/1,
7973 get_attr_length (insn));
7975 [(set_attr "type" "branch")
7976 (set_attr "mode" "none")])
7978 (define_insn "branch_equality_di_inverted"
7981 (match_operator:DI 0 "equality_op"
7982 [(match_operand:DI 2 "se_register_operand" "d")
7983 (match_operand:DI 3 "se_register_operand" "d")])
7985 (label_ref (match_operand 1 "" ""))))]
7989 return mips_output_conditional_branch (insn,
7991 /*two_operands_p=*/1,
7994 get_attr_length (insn));
7996 [(set_attr "type" "branch")
7997 (set_attr "mode" "none")])
8003 (if_then_else (match_operator:SI 0 "equality_op"
8004 [(match_operand:SI 1 "register_operand" "d,t")
8006 (match_operand 2 "pc_or_label_operand" "")
8007 (match_operand 3 "pc_or_label_operand" "")))]
8011 if (operands[2] != pc_rtx)
8013 if (which_alternative == 0)
8014 return \"%*b%C0z\\t%1,%2\";
8016 return \"%*bt%C0z\\t%2\";
8020 if (which_alternative == 0)
8021 return \"%*b%N0z\\t%1,%3\";
8023 return \"%*bt%N0z\\t%3\";
8026 [(set_attr "type" "branch")
8027 (set_attr "mode" "none")
8028 (set_attr "length" "8")])
8032 (if_then_else (match_operator:DI 0 "equality_op"
8033 [(match_operand:DI 1 "se_register_operand" "d,t")
8035 (match_operand 2 "pc_or_label_operand" "")
8036 (match_operand 3 "pc_or_label_operand" "")))]
8040 if (operands[2] != pc_rtx)
8042 if (which_alternative == 0)
8043 return \"%*b%C0z\\t%1,%2\";
8045 return \"%*bt%C0z\\t%2\";
8049 if (which_alternative == 0)
8050 return \"%*b%N0z\\t%1,%3\";
8052 return \"%*bt%N0z\\t%3\";
8055 [(set_attr "type" "branch")
8056 (set_attr "mode" "none")
8057 (set_attr "length" "8")])
8059 (define_expand "beq"
8061 (if_then_else (eq:CC (cc0)
8063 (label_ref (match_operand 0 "" ""))
8068 if (operands[0]) /* avoid unused code warning */
8070 gen_conditional_branch (operands, EQ);
8075 (define_expand "bne"
8077 (if_then_else (ne:CC (cc0)
8079 (label_ref (match_operand 0 "" ""))
8084 if (operands[0]) /* avoid unused code warning */
8086 gen_conditional_branch (operands, NE);
8091 (define_expand "bgt"
8093 (if_then_else (gt:CC (cc0)
8095 (label_ref (match_operand 0 "" ""))
8100 if (operands[0]) /* avoid unused code warning */
8102 gen_conditional_branch (operands, GT);
8107 (define_expand "bge"
8109 (if_then_else (ge:CC (cc0)
8111 (label_ref (match_operand 0 "" ""))
8116 if (operands[0]) /* avoid unused code warning */
8118 gen_conditional_branch (operands, GE);
8123 (define_expand "blt"
8125 (if_then_else (lt:CC (cc0)
8127 (label_ref (match_operand 0 "" ""))
8132 if (operands[0]) /* avoid unused code warning */
8134 gen_conditional_branch (operands, LT);
8139 (define_expand "ble"
8141 (if_then_else (le:CC (cc0)
8143 (label_ref (match_operand 0 "" ""))
8148 if (operands[0]) /* avoid unused code warning */
8150 gen_conditional_branch (operands, LE);
8155 (define_expand "bgtu"
8157 (if_then_else (gtu:CC (cc0)
8159 (label_ref (match_operand 0 "" ""))
8164 if (operands[0]) /* avoid unused code warning */
8166 gen_conditional_branch (operands, GTU);
8171 (define_expand "bgeu"
8173 (if_then_else (geu:CC (cc0)
8175 (label_ref (match_operand 0 "" ""))
8180 if (operands[0]) /* avoid unused code warning */
8182 gen_conditional_branch (operands, GEU);
8188 (define_expand "bltu"
8190 (if_then_else (ltu:CC (cc0)
8192 (label_ref (match_operand 0 "" ""))
8197 if (operands[0]) /* avoid unused code warning */
8199 gen_conditional_branch (operands, LTU);
8204 (define_expand "bleu"
8206 (if_then_else (leu:CC (cc0)
8208 (label_ref (match_operand 0 "" ""))
8213 if (operands[0]) /* avoid unused code warning */
8215 gen_conditional_branch (operands, LEU);
8222 ;; ....................
8224 ;; SETTING A REGISTER FROM A COMPARISON
8226 ;; ....................
8228 (define_expand "seq"
8229 [(set (match_operand:SI 0 "register_operand" "=d")
8230 (eq:SI (match_dup 1)
8235 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8238 /* set up operands from compare. */
8239 operands[1] = branch_cmp[0];
8240 operands[2] = branch_cmp[1];
8242 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8244 gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
8248 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8249 operands[2] = force_reg (SImode, operands[2]);
8251 /* fall through and generate default code */
8255 (define_insn "seq_si_zero"
8256 [(set (match_operand:SI 0 "register_operand" "=d")
8257 (eq:SI (match_operand:SI 1 "register_operand" "d")
8261 [(set_attr "type" "arith")
8262 (set_attr "mode" "SI")])
8265 [(set (match_operand:SI 0 "register_operand" "=t")
8266 (eq:SI (match_operand:SI 1 "register_operand" "d")
8270 [(set_attr "type" "arith")
8271 (set_attr "mode" "SI")])
8273 (define_insn "seq_di_zero"
8274 [(set (match_operand:DI 0 "register_operand" "=d")
8275 (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8277 "TARGET_64BIT && !TARGET_MIPS16"
8279 [(set_attr "type" "arith")
8280 (set_attr "mode" "DI")])
8283 [(set (match_operand:DI 0 "register_operand" "=t")
8284 (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8286 "TARGET_64BIT && TARGET_MIPS16"
8288 [(set_attr "type" "arith")
8289 (set_attr "mode" "DI")])
8291 (define_insn "seq_si"
8292 [(set (match_operand:SI 0 "register_operand" "=d,d")
8293 (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
8294 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8295 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8297 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8298 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8299 [(set_attr "type" "arith")
8300 (set_attr "mode" "SI")
8301 (set_attr "length" "8")])
8304 [(set (match_operand:SI 0 "register_operand" "")
8305 (eq:SI (match_operand:SI 1 "register_operand" "")
8306 (match_operand:SI 2 "uns_arith_operand" "")))]
8307 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8308 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8310 (xor:SI (match_dup 1)
8313 (ltu:SI (match_dup 0)
8317 (define_insn "seq_di"
8318 [(set (match_operand:DI 0 "register_operand" "=d,d")
8319 (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8320 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8321 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8323 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8324 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8325 [(set_attr "type" "arith")
8326 (set_attr "mode" "DI")
8327 (set_attr "length" "8")])
8330 [(set (match_operand:DI 0 "register_operand" "")
8331 (eq:DI (match_operand:DI 1 "se_register_operand" "")
8332 (match_operand:DI 2 "se_uns_arith_operand" "")))]
8333 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8335 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8337 (xor:DI (match_dup 1)
8340 (ltu:DI (match_dup 0)
8344 ;; On the mips16 the default code is better than using sltu.
8346 (define_expand "sne"
8347 [(set (match_operand:SI 0 "register_operand" "=d")
8348 (ne:SI (match_dup 1)
8353 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8356 /* set up operands from compare. */
8357 operands[1] = branch_cmp[0];
8358 operands[2] = branch_cmp[1];
8360 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
8362 gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
8366 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8367 operands[2] = force_reg (SImode, operands[2]);
8369 /* fall through and generate default code */
8372 (define_insn "sne_si_zero"
8373 [(set (match_operand:SI 0 "register_operand" "=d")
8374 (ne:SI (match_operand:SI 1 "register_operand" "d")
8378 [(set_attr "type" "arith")
8379 (set_attr "mode" "SI")])
8381 (define_insn "sne_di_zero"
8382 [(set (match_operand:DI 0 "register_operand" "=d")
8383 (ne:DI (match_operand:DI 1 "se_register_operand" "d")
8385 "TARGET_64BIT && !TARGET_MIPS16"
8387 [(set_attr "type" "arith")
8388 (set_attr "mode" "DI")])
8390 (define_insn "sne_si"
8391 [(set (match_operand:SI 0 "register_operand" "=d,d")
8392 (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
8393 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8394 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8396 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8397 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8398 [(set_attr "type" "arith")
8399 (set_attr "mode" "SI")
8400 (set_attr "length" "8")])
8403 [(set (match_operand:SI 0 "register_operand" "")
8404 (ne:SI (match_operand:SI 1 "register_operand" "")
8405 (match_operand:SI 2 "uns_arith_operand" "")))]
8406 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8407 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8409 (xor:SI (match_dup 1)
8412 (gtu:SI (match_dup 0)
8416 (define_insn "sne_di"
8417 [(set (match_operand:DI 0 "register_operand" "=d,d")
8418 (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8419 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8420 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8422 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8423 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8424 [(set_attr "type" "arith")
8425 (set_attr "mode" "DI")
8426 (set_attr "length" "8")])
8429 [(set (match_operand:DI 0 "register_operand" "")
8430 (ne:DI (match_operand:DI 1 "se_register_operand" "")
8431 (match_operand:DI 2 "se_uns_arith_operand" "")))]
8432 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8434 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8436 (xor:DI (match_dup 1)
8439 (gtu:DI (match_dup 0)
8443 (define_expand "sgt"
8444 [(set (match_operand:SI 0 "register_operand" "=d")
8445 (gt:SI (match_dup 1)
8450 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8453 /* set up operands from compare. */
8454 operands[1] = branch_cmp[0];
8455 operands[2] = branch_cmp[1];
8457 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8459 gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
8463 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8464 operands[2] = force_reg (SImode, operands[2]);
8466 /* fall through and generate default code */
8469 (define_insn "sgt_si"
8470 [(set (match_operand:SI 0 "register_operand" "=d")
8471 (gt:SI (match_operand:SI 1 "register_operand" "d")
8472 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8475 [(set_attr "type" "arith")
8476 (set_attr "mode" "SI")])
8479 [(set (match_operand:SI 0 "register_operand" "=t")
8480 (gt:SI (match_operand:SI 1 "register_operand" "d")
8481 (match_operand:SI 2 "register_operand" "d")))]
8484 [(set_attr "type" "arith")
8485 (set_attr "mode" "SI")])
8487 (define_insn "sgt_di"
8488 [(set (match_operand:DI 0 "register_operand" "=d")
8489 (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8490 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8491 "TARGET_64BIT && !TARGET_MIPS16"
8493 [(set_attr "type" "arith")
8494 (set_attr "mode" "DI")])
8497 [(set (match_operand:DI 0 "register_operand" "=d")
8498 (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8499 (match_operand:DI 2 "se_register_operand" "d")))]
8500 "TARGET_64BIT && TARGET_MIPS16"
8502 [(set_attr "type" "arith")
8503 (set_attr "mode" "DI")])
8505 (define_expand "sge"
8506 [(set (match_operand:SI 0 "register_operand" "=d")
8507 (ge:SI (match_dup 1)
8512 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8515 /* set up operands from compare. */
8516 operands[1] = branch_cmp[0];
8517 operands[2] = branch_cmp[1];
8519 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8521 gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
8525 /* fall through and generate default code */
8528 (define_insn "sge_si"
8529 [(set (match_operand:SI 0 "register_operand" "=d")
8530 (ge:SI (match_operand:SI 1 "register_operand" "d")
8531 (match_operand:SI 2 "arith_operand" "dI")))]
8532 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8533 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8534 [(set_attr "type" "arith")
8535 (set_attr "mode" "SI")
8536 (set_attr "length" "8")])
8539 [(set (match_operand:SI 0 "register_operand" "")
8540 (ge:SI (match_operand:SI 1 "register_operand" "")
8541 (match_operand:SI 2 "arith_operand" "")))]
8542 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8544 (lt:SI (match_dup 1)
8547 (xor:SI (match_dup 0)
8551 (define_insn "sge_di"
8552 [(set (match_operand:DI 0 "register_operand" "=d")
8553 (ge:DI (match_operand:DI 1 "se_register_operand" "d")
8554 (match_operand:DI 2 "se_arith_operand" "dI")))]
8555 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8556 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8557 [(set_attr "type" "arith")
8558 (set_attr "mode" "DI")
8559 (set_attr "length" "8")])
8562 [(set (match_operand:DI 0 "register_operand" "")
8563 (ge:DI (match_operand:DI 1 "se_register_operand" "")
8564 (match_operand:DI 2 "se_arith_operand" "")))]
8565 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8568 (lt:DI (match_dup 1)
8571 (xor:DI (match_dup 0)
8575 (define_expand "slt"
8576 [(set (match_operand:SI 0 "register_operand" "=d")
8577 (lt:SI (match_dup 1)
8582 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8585 /* set up operands from compare. */
8586 operands[1] = branch_cmp[0];
8587 operands[2] = branch_cmp[1];
8589 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8591 gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
8595 /* fall through and generate default code */
8598 (define_insn "slt_si"
8599 [(set (match_operand:SI 0 "register_operand" "=d")
8600 (lt:SI (match_operand:SI 1 "register_operand" "d")
8601 (match_operand:SI 2 "arith_operand" "dI")))]
8604 [(set_attr "type" "arith")
8605 (set_attr "mode" "SI")])
8608 [(set (match_operand:SI 0 "register_operand" "=t,t")
8609 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
8610 (match_operand:SI 2 "arith_operand" "d,I")))]
8613 [(set_attr "type" "arith")
8614 (set_attr "mode" "SI")
8615 (set_attr_alternative "length"
8617 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8621 (define_insn "slt_di"
8622 [(set (match_operand:DI 0 "register_operand" "=d")
8623 (lt:DI (match_operand:DI 1 "se_register_operand" "d")
8624 (match_operand:DI 2 "se_arith_operand" "dI")))]
8625 "TARGET_64BIT && !TARGET_MIPS16"
8627 [(set_attr "type" "arith")
8628 (set_attr "mode" "DI")])
8631 [(set (match_operand:DI 0 "register_operand" "=t,t")
8632 (lt:DI (match_operand:DI 1 "se_register_operand" "d,d")
8633 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8634 "TARGET_64BIT && TARGET_MIPS16"
8636 [(set_attr "type" "arith")
8637 (set_attr "mode" "DI")
8638 (set_attr_alternative "length"
8640 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8644 (define_expand "sle"
8645 [(set (match_operand:SI 0 "register_operand" "=d")
8646 (le:SI (match_dup 1)
8651 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8654 /* set up operands from compare. */
8655 operands[1] = branch_cmp[0];
8656 operands[2] = branch_cmp[1];
8658 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8660 gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
8664 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8665 operands[2] = force_reg (SImode, operands[2]);
8667 /* fall through and generate default code */
8670 (define_insn "sle_si_const"
8671 [(set (match_operand:SI 0 "register_operand" "=d")
8672 (le:SI (match_operand:SI 1 "register_operand" "d")
8673 (match_operand:SI 2 "small_int" "I")))]
8674 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8677 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8678 return \"slt\\t%0,%1,%2\";
8680 [(set_attr "type" "arith")
8681 (set_attr "mode" "SI")])
8684 [(set (match_operand:SI 0 "register_operand" "=t")
8685 (le:SI (match_operand:SI 1 "register_operand" "d")
8686 (match_operand:SI 2 "small_int" "I")))]
8687 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8690 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8691 return \"slt\\t%1,%2\";
8693 [(set_attr "type" "arith")
8694 (set_attr "mode" "SI")
8695 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8699 (define_insn "sle_di_const"
8700 [(set (match_operand:DI 0 "register_operand" "=d")
8701 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8702 (match_operand:DI 2 "small_int" "I")))]
8703 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8706 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8707 return \"slt\\t%0,%1,%2\";
8709 [(set_attr "type" "arith")
8710 (set_attr "mode" "DI")])
8713 [(set (match_operand:DI 0 "register_operand" "=t")
8714 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8715 (match_operand:DI 2 "small_int" "I")))]
8716 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8719 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8720 return \"slt\\t%1,%2\";
8722 [(set_attr "type" "arith")
8723 (set_attr "mode" "DI")
8724 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8728 (define_insn "sle_si_reg"
8729 [(set (match_operand:SI 0 "register_operand" "=d")
8730 (le:SI (match_operand:SI 1 "register_operand" "d")
8731 (match_operand:SI 2 "register_operand" "d")))]
8732 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8733 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8734 [(set_attr "type" "arith")
8735 (set_attr "mode" "SI")
8736 (set_attr "length" "8")])
8739 [(set (match_operand:SI 0 "register_operand" "")
8740 (le:SI (match_operand:SI 1 "register_operand" "")
8741 (match_operand:SI 2 "register_operand" "")))]
8742 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8744 (lt:SI (match_dup 2)
8747 (xor:SI (match_dup 0)
8751 (define_insn "sle_di_reg"
8752 [(set (match_operand:DI 0 "register_operand" "=d")
8753 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8754 (match_operand:DI 2 "se_register_operand" "d")))]
8755 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8756 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8757 [(set_attr "type" "arith")
8758 (set_attr "mode" "DI")
8759 (set_attr "length" "8")])
8762 [(set (match_operand:DI 0 "register_operand" "")
8763 (le:DI (match_operand:DI 1 "se_register_operand" "")
8764 (match_operand:DI 2 "se_register_operand" "")))]
8765 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8768 (lt:DI (match_dup 2)
8771 (xor:DI (match_dup 0)
8775 (define_expand "sgtu"
8776 [(set (match_operand:SI 0 "register_operand" "=d")
8777 (gtu:SI (match_dup 1)
8782 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8785 /* set up operands from compare. */
8786 operands[1] = branch_cmp[0];
8787 operands[2] = branch_cmp[1];
8789 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8791 gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
8795 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8796 operands[2] = force_reg (SImode, operands[2]);
8798 /* fall through and generate default code */
8801 (define_insn "sgtu_si"
8802 [(set (match_operand:SI 0 "register_operand" "=d")
8803 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8804 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8807 [(set_attr "type" "arith")
8808 (set_attr "mode" "SI")])
8811 [(set (match_operand:SI 0 "register_operand" "=t")
8812 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8813 (match_operand:SI 2 "register_operand" "d")))]
8816 [(set_attr "type" "arith")
8817 (set_attr "mode" "SI")])
8819 (define_insn "sgtu_di"
8820 [(set (match_operand:DI 0 "register_operand" "=d")
8821 (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8822 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8825 [(set_attr "type" "arith")
8826 (set_attr "mode" "DI")])
8829 [(set (match_operand:DI 0 "register_operand" "=t")
8830 (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8831 (match_operand:DI 2 "se_register_operand" "d")))]
8834 [(set_attr "type" "arith")
8835 (set_attr "mode" "DI")])
8837 (define_expand "sgeu"
8838 [(set (match_operand:SI 0 "register_operand" "=d")
8839 (geu:SI (match_dup 1)
8844 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8847 /* set up operands from compare. */
8848 operands[1] = branch_cmp[0];
8849 operands[2] = branch_cmp[1];
8851 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8853 gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
8857 /* fall through and generate default code */
8860 (define_insn "sgeu_si"
8861 [(set (match_operand:SI 0 "register_operand" "=d")
8862 (geu:SI (match_operand:SI 1 "register_operand" "d")
8863 (match_operand:SI 2 "arith_operand" "dI")))]
8864 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8865 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8866 [(set_attr "type" "arith")
8867 (set_attr "mode" "SI")
8868 (set_attr "length" "8")])
8871 [(set (match_operand:SI 0 "register_operand" "")
8872 (geu:SI (match_operand:SI 1 "register_operand" "")
8873 (match_operand:SI 2 "arith_operand" "")))]
8874 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8876 (ltu:SI (match_dup 1)
8879 (xor:SI (match_dup 0)
8883 (define_insn "sgeu_di"
8884 [(set (match_operand:DI 0 "register_operand" "=d")
8885 (geu:DI (match_operand:DI 1 "se_register_operand" "d")
8886 (match_operand:DI 2 "se_arith_operand" "dI")))]
8887 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8888 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8889 [(set_attr "type" "arith")
8890 (set_attr "mode" "DI")
8891 (set_attr "length" "8")])
8894 [(set (match_operand:DI 0 "register_operand" "")
8895 (geu:DI (match_operand:DI 1 "se_register_operand" "")
8896 (match_operand:DI 2 "se_arith_operand" "")))]
8897 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8900 (ltu:DI (match_dup 1)
8903 (xor:DI (match_dup 0)
8907 (define_expand "sltu"
8908 [(set (match_operand:SI 0 "register_operand" "=d")
8909 (ltu:SI (match_dup 1)
8914 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8917 /* set up operands from compare. */
8918 operands[1] = branch_cmp[0];
8919 operands[2] = branch_cmp[1];
8921 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8923 gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
8927 /* fall through and generate default code */
8930 (define_insn "sltu_si"
8931 [(set (match_operand:SI 0 "register_operand" "=d")
8932 (ltu:SI (match_operand:SI 1 "register_operand" "d")
8933 (match_operand:SI 2 "arith_operand" "dI")))]
8936 [(set_attr "type" "arith")
8937 (set_attr "mode" "SI")])
8940 [(set (match_operand:SI 0 "register_operand" "=t,t")
8941 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
8942 (match_operand:SI 2 "arith_operand" "d,I")))]
8945 [(set_attr "type" "arith")
8946 (set_attr "mode" "SI")
8947 (set_attr_alternative "length"
8949 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8953 (define_insn "sltu_di"
8954 [(set (match_operand:DI 0 "register_operand" "=d")
8955 (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
8956 (match_operand:DI 2 "se_arith_operand" "dI")))]
8957 "TARGET_64BIT && !TARGET_MIPS16"
8959 [(set_attr "type" "arith")
8960 (set_attr "mode" "DI")])
8963 [(set (match_operand:DI 0 "register_operand" "=t,t")
8964 (ltu:DI (match_operand:DI 1 "se_register_operand" "d,d")
8965 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8966 "TARGET_64BIT && TARGET_MIPS16"
8968 [(set_attr "type" "arith")
8969 (set_attr "mode" "DI")
8970 (set_attr_alternative "length"
8972 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8976 (define_expand "sleu"
8977 [(set (match_operand:SI 0 "register_operand" "=d")
8978 (leu:SI (match_dup 1)
8983 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8986 /* set up operands from compare. */
8987 operands[1] = branch_cmp[0];
8988 operands[2] = branch_cmp[1];
8990 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8992 gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
8996 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8997 operands[2] = force_reg (SImode, operands[2]);
8999 /* fall through and generate default code */
9002 (define_insn "sleu_si_const"
9003 [(set (match_operand:SI 0 "register_operand" "=d")
9004 (leu:SI (match_operand:SI 1 "register_operand" "d")
9005 (match_operand:SI 2 "small_int" "I")))]
9006 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9009 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
9010 return \"sltu\\t%0,%1,%2\";
9012 [(set_attr "type" "arith")
9013 (set_attr "mode" "SI")])
9016 [(set (match_operand:SI 0 "register_operand" "=t")
9017 (leu:SI (match_operand:SI 1 "register_operand" "d")
9018 (match_operand:SI 2 "small_int" "I")))]
9019 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9022 operands[2] = GEN_INT (INTVAL (operands[2])+1);
9023 return \"sltu\\t%1,%2\";
9025 [(set_attr "type" "arith")
9026 (set_attr "mode" "SI")
9027 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
9031 (define_insn "sleu_di_const"
9032 [(set (match_operand:DI 0 "register_operand" "=d")
9033 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9034 (match_operand:DI 2 "small_int" "I")))]
9035 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9038 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
9039 return \"sltu\\t%0,%1,%2\";
9041 [(set_attr "type" "arith")
9042 (set_attr "mode" "DI")])
9045 [(set (match_operand:DI 0 "register_operand" "=t")
9046 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9047 (match_operand:DI 2 "small_int" "I")))]
9048 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9051 operands[2] = GEN_INT (INTVAL (operands[2])+1);
9052 return \"sltu\\t%1,%2\";
9054 [(set_attr "type" "arith")
9055 (set_attr "mode" "DI")
9056 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
9060 (define_insn "sleu_si_reg"
9061 [(set (match_operand:SI 0 "register_operand" "=d")
9062 (leu:SI (match_operand:SI 1 "register_operand" "d")
9063 (match_operand:SI 2 "register_operand" "d")))]
9064 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9065 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9066 [(set_attr "type" "arith")
9067 (set_attr "mode" "SI")
9068 (set_attr "length" "8")])
9071 [(set (match_operand:SI 0 "register_operand" "")
9072 (leu:SI (match_operand:SI 1 "register_operand" "")
9073 (match_operand:SI 2 "register_operand" "")))]
9074 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
9076 (ltu:SI (match_dup 2)
9079 (xor:SI (match_dup 0)
9083 (define_insn "sleu_di_reg"
9084 [(set (match_operand:DI 0 "register_operand" "=d")
9085 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9086 (match_operand:DI 2 "se_register_operand" "d")))]
9087 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9088 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9089 [(set_attr "type" "arith")
9090 (set_attr "mode" "DI")
9091 (set_attr "length" "8")])
9094 [(set (match_operand:DI 0 "register_operand" "")
9095 (leu:DI (match_operand:DI 1 "se_register_operand" "")
9096 (match_operand:DI 2 "se_register_operand" "")))]
9097 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
9100 (ltu:DI (match_dup 2)
9103 (xor:DI (match_dup 0)
9109 ;; ....................
9111 ;; FLOATING POINT COMPARISONS
9113 ;; ....................
9115 (define_insn "seq_df"
9116 [(set (match_operand:CC 0 "register_operand" "=z")
9117 (eq:CC (match_operand:DF 1 "register_operand" "f")
9118 (match_operand:DF 2 "register_operand" "f")))]
9119 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9122 return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9124 [(set_attr "type" "fcmp")
9125 (set_attr "mode" "FPSW")])
9127 (define_insn "slt_df"
9128 [(set (match_operand:CC 0 "register_operand" "=z")
9129 (lt:CC (match_operand:DF 1 "register_operand" "f")
9130 (match_operand:DF 2 "register_operand" "f")))]
9131 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9134 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9136 [(set_attr "type" "fcmp")
9137 (set_attr "mode" "FPSW")])
9139 (define_insn "sle_df"
9140 [(set (match_operand:CC 0 "register_operand" "=z")
9141 (le:CC (match_operand:DF 1 "register_operand" "f")
9142 (match_operand:DF 2 "register_operand" "f")))]
9143 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9146 return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9148 [(set_attr "type" "fcmp")
9149 (set_attr "mode" "FPSW")])
9151 (define_insn "sgt_df"
9152 [(set (match_operand:CC 0 "register_operand" "=z")
9153 (gt:CC (match_operand:DF 1 "register_operand" "f")
9154 (match_operand:DF 2 "register_operand" "f")))]
9155 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9158 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9160 [(set_attr "type" "fcmp")
9161 (set_attr "mode" "FPSW")])
9163 (define_insn "sge_df"
9164 [(set (match_operand:CC 0 "register_operand" "=z")
9165 (ge:CC (match_operand:DF 1 "register_operand" "f")
9166 (match_operand:DF 2 "register_operand" "f")))]
9167 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9170 return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9172 [(set_attr "type" "fcmp")
9173 (set_attr "mode" "FPSW")])
9175 (define_insn "seq_sf"
9176 [(set (match_operand:CC 0 "register_operand" "=z")
9177 (eq:CC (match_operand:SF 1 "register_operand" "f")
9178 (match_operand:SF 2 "register_operand" "f")))]
9182 return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9184 [(set_attr "type" "fcmp")
9185 (set_attr "mode" "FPSW")])
9187 (define_insn "slt_sf"
9188 [(set (match_operand:CC 0 "register_operand" "=z")
9189 (lt:CC (match_operand:SF 1 "register_operand" "f")
9190 (match_operand:SF 2 "register_operand" "f")))]
9194 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9196 [(set_attr "type" "fcmp")
9197 (set_attr "mode" "FPSW")])
9199 (define_insn "sle_sf"
9200 [(set (match_operand:CC 0 "register_operand" "=z")
9201 (le:CC (match_operand:SF 1 "register_operand" "f")
9202 (match_operand:SF 2 "register_operand" "f")))]
9206 return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9208 [(set_attr "type" "fcmp")
9209 (set_attr "mode" "FPSW")])
9211 (define_insn "sgt_sf"
9212 [(set (match_operand:CC 0 "register_operand" "=z")
9213 (gt:CC (match_operand:SF 1 "register_operand" "f")
9214 (match_operand:SF 2 "register_operand" "f")))]
9218 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9220 [(set_attr "type" "fcmp")
9221 (set_attr "mode" "FPSW")])
9223 (define_insn "sge_sf"
9224 [(set (match_operand:CC 0 "register_operand" "=z")
9225 (ge:CC (match_operand:SF 1 "register_operand" "f")
9226 (match_operand:SF 2 "register_operand" "f")))]
9230 return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9232 [(set_attr "type" "fcmp")
9233 (set_attr "mode" "FPSW")])
9237 ;; ....................
9239 ;; UNCONDITIONAL BRANCHES
9241 ;; ....................
9243 ;; Unconditional branches.
9247 (label_ref (match_operand 0 "" "")))]
9251 if (GET_CODE (operands[0]) == REG)
9252 return \"%*j\\t%0\";
9253 /* ??? I don't know why this is necessary. This works around an
9254 assembler problem that appears when a label is defined, then referenced
9255 in a switch table, then used in a `j' instruction. */
9256 else if (mips_abi != ABI_32 && mips_abi != ABI_O64)
9257 return \"%*b\\t%l0\";
9259 return \"%*j\\t%l0\";
9261 [(set_attr "type" "jump")
9262 (set_attr "mode" "none")])
9264 ;; We need a different insn for the mips16, because a mips16 branch
9265 ;; does not have a delay slot.
9269 (label_ref (match_operand 0 "" "")))]
9270 "TARGET_MIPS16 && GET_CODE (operands[0]) != REG"
9272 [(set_attr "type" "branch")
9273 (set_attr "mode" "none")
9274 (set_attr "length" "8")])
9276 (define_expand "indirect_jump"
9277 [(set (pc) (match_operand 0 "register_operand" "d"))]
9283 if (operands[0]) /* eliminate unused code warnings */
9286 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
9287 operands[0] = copy_to_mode_reg (Pmode, dest);
9289 if (!(Pmode == DImode))
9290 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
9292 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
9298 (define_insn "indirect_jump_internal1"
9299 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
9300 "!(Pmode == DImode)"
9302 [(set_attr "type" "jump")
9303 (set_attr "mode" "none")])
9305 (define_insn "indirect_jump_internal2"
9306 [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
9309 [(set_attr "type" "jump")
9310 (set_attr "mode" "none")])
9312 (define_expand "tablejump"
9314 (match_operand 0 "register_operand" "d"))
9315 (use (label_ref (match_operand 1 "" "")))]
9319 if (operands[0]) /* eliminate unused code warnings */
9323 if (GET_MODE (operands[0]) != HImode)
9325 if (!(Pmode == DImode))
9326 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
9328 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
9332 if (GET_MODE (operands[0]) != Pmode)
9337 if (!(Pmode == DImode))
9338 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
9340 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
9344 if (!(Pmode == DImode))
9345 emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
9347 emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
9354 (define_insn "tablejump_internal1"
9356 (match_operand:SI 0 "register_operand" "d"))
9357 (use (label_ref (match_operand 1 "" "")))]
9358 "!(Pmode == DImode)"
9360 [(set_attr "type" "jump")
9361 (set_attr "mode" "none")])
9363 (define_insn "tablejump_internal2"
9365 (match_operand:DI 0 "se_register_operand" "d"))
9366 (use (label_ref (match_operand 1 "" "")))]
9369 [(set_attr "type" "jump")
9370 (set_attr "mode" "none")])
9372 (define_expand "tablejump_internal3"
9373 [(parallel [(set (pc)
9374 (plus:SI (match_operand:SI 0 "register_operand" "d")
9375 (label_ref:SI (match_operand 1 "" ""))))
9376 (use (label_ref:SI (match_dup 1)))])]
9380 (define_expand "tablejump_mips161"
9381 [(set (pc) (plus:SI (sign_extend:SI
9382 (match_operand:HI 0 "register_operand" "d"))
9383 (label_ref:SI (match_operand 1 "" ""))))]
9384 "TARGET_MIPS16 && !(Pmode == DImode)"
9387 if (operands[0]) /* eliminate unused code warnings. */
9391 t1 = gen_reg_rtx (SImode);
9392 t2 = gen_reg_rtx (SImode);
9393 t3 = gen_reg_rtx (SImode);
9394 emit_insn (gen_extendhisi2 (t1, operands[0]));
9395 emit_move_insn (t2, gen_rtx (LABEL_REF, SImode, operands[1]));
9396 emit_insn (gen_addsi3 (t3, t1, t2));
9397 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
9402 (define_expand "tablejump_mips162"
9403 [(set (pc) (plus:DI (sign_extend:DI
9404 (match_operand:HI 0 "register_operand" "d"))
9405 (label_ref:DI (match_operand 1 "" ""))))]
9406 "TARGET_MIPS16 && Pmode == DImode"
9409 if (operands[0]) /* eliminate unused code warnings. */
9413 t1 = gen_reg_rtx (DImode);
9414 t2 = gen_reg_rtx (DImode);
9415 t3 = gen_reg_rtx (DImode);
9416 emit_insn (gen_extendhidi2 (t1, operands[0]));
9417 emit_move_insn (t2, gen_rtx (LABEL_REF, DImode, operands[1]));
9418 emit_insn (gen_adddi3 (t3, t1, t2));
9419 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
9424 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
9425 ;;; it is not valid. ??? With the USE, the condition tests may not be required
9428 ;;; ??? The length depends on the ABI. It is two for o32, and one for n32.
9429 ;;; We just use the conservative number here.
9433 (plus:SI (match_operand:SI 0 "register_operand" "d")
9434 (label_ref:SI (match_operand 1 "" ""))))
9435 (use (label_ref:SI (match_dup 1)))]
9436 "!(Pmode == DImode) && next_active_insn (insn) != 0
9437 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9438 && PREV_INSN (next_active_insn (insn)) == operands[1]"
9441 /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */
9442 if (mips_abi == ABI_32 || mips_abi == ABI_O64)
9443 output_asm_insn (\".cpadd\\t%0\", operands);
9444 return \"%*j\\t%0\";
9446 [(set_attr "type" "jump")
9447 (set_attr "mode" "none")
9448 (set_attr "length" "8")])
9450 (define_expand "tablejump_internal4"
9451 [(parallel [(set (pc)
9452 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9453 (label_ref:DI (match_operand 1 "" ""))))
9454 (use (label_ref:DI (match_dup 1)))])]
9458 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
9459 ;;; it is not valid. ??? With the USE, the condition tests may not be required
9464 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9465 (label_ref:DI (match_operand 1 "" ""))))
9466 (use (label_ref:DI (match_dup 1)))]
9467 "Pmode == DImode && next_active_insn (insn) != 0
9468 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9469 && PREV_INSN (next_active_insn (insn)) == operands[1]"
9471 [(set_attr "type" "jump")
9472 (set_attr "mode" "none")])
9474 ;; Implement a switch statement when generating embedded PIC code.
9475 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
9477 (define_expand "casesi"
9479 (minus:SI (match_operand:SI 0 "register_operand" "d")
9480 (match_operand:SI 1 "arith_operand" "dI")))
9482 (compare:CC (match_dup 5)
9483 (match_operand:SI 2 "arith_operand" "")))
9485 (if_then_else (gtu (cc0)
9487 (label_ref (match_operand 4 "" ""))
9491 (mem:SI (plus:SI (mult:SI (match_dup 5)
9493 (label_ref (match_operand 3 "" "")))))
9494 (clobber (match_scratch:SI 6 ""))
9495 (clobber (reg:SI 31))])]
9496 "TARGET_EMBEDDED_PIC"
9501 rtx reg = gen_reg_rtx (SImode);
9503 /* If the index is too large, go to the default label. */
9504 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
9505 emit_insn (gen_cmpsi (reg, operands[2]));
9506 emit_insn (gen_bgtu (operands[4]));
9508 /* Do the PIC jump. */
9509 if (Pmode != DImode)
9510 emit_jump_insn (gen_casesi_internal (reg, operands[3],
9511 gen_reg_rtx (SImode)));
9513 emit_jump_insn (gen_casesi_internal_di (reg, operands[3],
9514 gen_reg_rtx (DImode)));
9520 ;; An embedded PIC switch statement looks like this:
9522 ;; sll $reg,$index,2
9524 ;; addu $reg,$reg,$31
9525 ;; lw $reg,$L1-$LS1($reg)
9526 ;; addu $reg,$reg,$31
9533 (define_insn "casesi_internal"
9535 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
9537 (label_ref (match_operand 1 "" "")))))
9538 (clobber (match_operand:SI 2 "register_operand" "=d"))
9539 (clobber (reg:SI 31))]
9540 "TARGET_EMBEDDED_PIC"
9541 "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
9542 lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\\n\\t%*j\\t%2"
9543 [(set_attr "type" "jump")
9544 (set_attr "mode" "none")
9545 (set_attr "length" "24")])
9547 ;; This code assumes that the table index will never be >= 29 bits wide,
9548 ;; which allows the 'sign extend' from SI to DI be a no-op.
9549 (define_insn "casesi_internal_di"
9551 (mem:DI (plus:DI (sign_extend:DI
9552 (mult:SI (match_operand:SI 0 "register_operand" "d")
9554 (label_ref (match_operand 1 "" "")))))
9555 (clobber (match_operand:DI 2 "register_operand" "=d"))
9556 (clobber (reg:DI 31))]
9557 "TARGET_EMBEDDED_PIC"
9558 "%(bal\\t%S1\;sll\\t%2,%0,3\\n%~%S1:\;daddu\\t%2,%2,$31%)\;\\
9559 ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
9560 [(set_attr "type" "jump")
9561 (set_attr "mode" "none")
9562 (set_attr "length" "24")])
9564 ;; For o32/n32/n64, we save the gp in the jmp_buf as well. While it is
9565 ;; possible to either pull it off the stack (in the o32 case) or recalculate
9566 ;; it given t9 and our target label, it takes 3 or 4 insns to do so, and
9569 (define_expand "builtin_setjmp_setup"
9570 [(unspec [(match_operand 0 "register_operand" "r")] UNSPEC_SETJMP)]
9574 if (Pmode == DImode)
9575 emit_insn (gen_builtin_setjmp_setup_64 (operands[0]));
9577 emit_insn (gen_builtin_setjmp_setup_32 (operands[0]));
9581 (define_expand "builtin_setjmp_setup_32"
9582 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
9585 "TARGET_ABICALLS && ! (Pmode == DImode)"
9588 (define_expand "builtin_setjmp_setup_64"
9589 [(set (mem:DI (plus:DI (match_operand:DI 0 "register_operand" "r")
9592 "TARGET_ABICALLS && Pmode == DImode"
9595 ;; For o32/n32/n64, we need to arrange for longjmp to put the
9596 ;; target address in t9 so that we can use it for loading $gp.
9598 (define_expand "builtin_longjmp"
9599 [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPEC_LONGJMP)]
9603 /* The elements of the buffer are, in order: */
9604 int W = (Pmode == DImode ? 8 : 4);
9605 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9606 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
9607 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
9608 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
9609 rtx pv = gen_rtx_REG (Pmode, 25);
9610 rtx gp = gen_rtx_REG (Pmode, 28);
9612 /* This bit is the same as expand_builtin_longjmp. */
9613 emit_move_insn (hard_frame_pointer_rtx, fp);
9614 emit_move_insn (pv, lab);
9615 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
9616 emit_move_insn (gp, gpv);
9617 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
9618 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9619 emit_insn (gen_rtx_USE (VOIDmode, gp));
9620 emit_indirect_jump (pv);
9625 ;; ....................
9627 ;; Function prologue/epilogue
9629 ;; ....................
9632 (define_expand "prologue"
9637 if (mips_isa >= 0) /* avoid unused code warnings */
9639 mips_expand_prologue ();
9644 ;; Block any insns from being moved before this point, since the
9645 ;; profiling call to mcount can use various registers that aren't
9646 ;; saved or used to pass arguments.
9648 (define_insn "blockage"
9649 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
9652 [(set_attr "type" "unknown")
9653 (set_attr "mode" "none")
9654 (set_attr "length" "0")])
9656 (define_expand "epilogue"
9661 if (mips_isa >= 0) /* avoid unused code warnings */
9663 mips_expand_epilogue ();
9668 ;; Trivial return. Make it look like a normal return insn as that
9669 ;; allows jump optimizations to work better .
9670 (define_insn "return"
9672 "mips_can_use_return_insn ()"
9674 [(set_attr "type" "jump")
9675 (set_attr "mode" "none")])
9679 (define_insn "return_internal"
9680 [(use (match_operand 0 "pmode_register_operand" ""))
9685 return \"%*j\\t%0\";
9687 [(set_attr "type" "jump")
9688 (set_attr "mode" "none")])
9690 ;; When generating embedded PIC code we need to get the address of the
9691 ;; current function. This specialized instruction does just that.
9693 (define_insn "get_fnaddr"
9694 [(set (match_operand 0 "register_operand" "=d")
9695 (unspec [(match_operand 1 "" "")] UNSPEC_GET_FNADDR))
9696 (clobber (reg:SI 31))]
9697 "TARGET_EMBEDDED_PIC
9698 && GET_CODE (operands[1]) == SYMBOL_REF"
9699 "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
9700 [(set_attr "type" "call")
9701 (set_attr "mode" "none")
9702 (set_attr "length" "16")])
9704 ;; This is used in compiling the unwind routines.
9705 (define_expand "eh_return"
9706 [(use (match_operand 0 "general_operand" ""))
9707 (use (match_operand 1 "general_operand" ""))]
9711 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
9713 if (GET_MODE (operands[1]) != gpr_mode)
9714 operands[1] = convert_to_mode (gpr_mode, operands[1], 0);
9716 emit_insn (gen_eh_set_lr_di (operands[1]));
9718 emit_insn (gen_eh_set_lr_si (operands[1]));
9720 emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]);
9724 ;; Clobber the return address on the stack. We can't expand this
9725 ;; until we know where it will be put in the stack frame.
9727 (define_insn "eh_set_lr_si"
9728 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9729 (clobber (match_scratch:SI 1 "=&r"))]
9733 (define_insn "eh_set_lr_di"
9734 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9735 (clobber (match_scratch:DI 1 "=&r"))]
9740 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
9741 (clobber (match_scratch 1 ""))]
9742 "reload_completed && !TARGET_DEBUG_D_MODE"
9746 HOST_WIDE_INT gp_offset;
9749 compute_frame_size (get_frame_size ());
9750 if (((current_frame_info.mask >> 31) & 1) == 0)
9752 gp_offset = current_frame_info.gp_sp_offset;
9754 if (gp_offset < 32768)
9755 base = stack_pointer_rtx;
9759 emit_move_insn (base, GEN_INT (gp_offset));
9760 if (Pmode == DImode)
9761 emit_insn (gen_adddi3 (base, base, stack_pointer_rtx));
9763 emit_insn (gen_addsi3 (base, base, stack_pointer_rtx));
9766 emit_move_insn (gen_rtx_MEM (GET_MODE (operands[0]),
9767 plus_constant (base, gp_offset)),
9772 (define_insn "exception_receiver"
9773 [(unspec_volatile [(const_int 0)] UNSPEC_EH_RECEIVER)]
9774 "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)"
9779 operands[0] = pic_offset_table_rtx;
9780 if (frame_pointer_needed)
9781 loc = hard_frame_pointer_rtx;
9783 loc = stack_pointer_rtx;
9784 loc = plus_constant (loc, current_frame_info.args_size);
9785 operands[1] = gen_rtx_MEM (Pmode, loc);
9787 return mips_move_1word (operands, insn, 0);
9789 [(set_attr "type" "load")
9790 (set_attr "length" "8")])
9793 ;; ....................
9797 ;; ....................
9799 ;; calls.c now passes a third argument, make saber happy
9801 (define_expand "call"
9802 [(parallel [(call (match_operand 0 "memory_operand" "m")
9803 (match_operand 1 "" "i"))
9804 (clobber (reg:SI 31))
9805 (use (match_operand 2 "" "")) ;; next_arg_reg
9806 (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
9812 if (operands[0]) /* eliminate unused code warnings */
9814 addr = XEXP (operands[0], 0);
9815 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9816 || ! call_insn_operand (addr, VOIDmode))
9817 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
9819 /* In order to pass small structures by value in registers
9820 compatibly with the MIPS compiler, we need to shift the value
9821 into the high part of the register. Function_arg has encoded
9822 a PARALLEL rtx, holding a vector of adjustments to be made
9823 as the next_arg_reg variable, so we split up the insns,
9824 and emit them separately. */
9826 if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
9828 rtvec adjust = XVEC (operands[2], 0);
9829 int num = GET_NUM_ELEM (adjust);
9832 for (i = 0; i < num; i++)
9833 emit_insn (RTVEC_ELT (adjust, i));
9837 && mips16_hard_float
9839 && (int) GET_MODE (operands[2]) != 0)
9841 if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1],
9842 (int) GET_MODE (operands[2])))
9846 emit_call_insn (gen_call_internal0 (operands[0], operands[1],
9847 gen_rtx_REG (SImode,
9848 GP_REG_FIRST + 31)));
9853 (define_expand "call_internal0"
9854 [(parallel [(call (match_operand 0 "" "")
9855 (match_operand 1 "" ""))
9856 (clobber (match_operand:SI 2 "" ""))])]
9860 ;; We need to recognize reg:SI 31 specially for the mips16, because we
9861 ;; don't have a constraint letter for it.
9864 [(call (mem (match_operand 0 "call_insn_operand" "ei"))
9865 (match_operand 1 "" "i"))
9866 (clobber (match_operand:SI 2 "register_operand" "=y"))]
9867 "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9868 && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9870 [(set_attr "type" "call")
9871 (set_attr "mode" "none")
9872 (set_attr "length" "8")])
9874 (define_insn "call_internal1"
9875 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9876 (match_operand 1 "" "i"))
9877 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9878 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9881 register rtx target = operands[0];
9883 if (GET_CODE (target) == CONST_INT)
9884 return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
9885 else if (CONSTANT_ADDRESS_P (target))
9886 return \"%*jal\\t%0\";
9888 return \"%*jal\\t%2,%0\";
9890 [(set_attr "type" "call")
9891 (set_attr "mode" "none")])
9893 (define_insn "call_internal2"
9894 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9895 (match_operand 1 "" "i"))
9896 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9897 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9900 register rtx target = operands[0];
9902 if (GET_CODE (target) == CONST_INT)
9903 return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
9904 else if (CONSTANT_ADDRESS_P (target))
9906 if (GET_MODE (target) == SImode)
9907 return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
9909 return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
9911 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9912 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9914 return \"jal\\t%2,%0\";
9916 [(set_attr "type" "call")
9917 (set_attr "mode" "none")
9918 (set_attr "length" "8")])
9920 (define_insn "call_internal3a"
9921 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9922 (match_operand 1 "" "i"))
9923 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9925 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9927 [(set_attr "type" "call")
9928 (set_attr "mode" "none")])
9930 (define_insn "call_internal3b"
9931 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9932 (match_operand 1 "" "i"))
9933 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9935 && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9937 [(set_attr "type" "call")
9938 (set_attr "mode" "none")
9939 (set_attr "length" "1")])
9941 (define_insn "call_internal3c"
9942 [(call (mem:SI (match_operand:SI 0 "register_operand" "e"))
9943 (match_operand 1 "" "i"))
9944 (clobber (match_operand:SI 2 "register_operand" "=y"))]
9945 "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
9946 && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9948 [(set_attr "type" "call")
9949 (set_attr "mode" "none")])
9951 (define_insn "call_internal4a"
9952 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9953 (match_operand 1 "" "i"))
9954 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9955 "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
9958 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9959 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9961 return \"jal\\t%2,%0\";
9963 [(set_attr "type" "call")
9964 (set_attr "mode" "none")
9965 (set_attr "length" "8")])
9967 (define_insn "call_internal4b"
9968 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9969 (match_operand 1 "" "i"))
9970 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9971 "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
9974 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9975 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9977 return \"jal\\t%2,%0\";
9979 [(set_attr "type" "call")
9980 (set_attr "mode" "none")
9981 (set_attr "length" "8")])
9983 ;; calls.c now passes a fourth argument, make saber happy
9985 (define_expand "call_value"
9986 [(parallel [(set (match_operand 0 "register_operand" "=df")
9987 (call (match_operand 1 "memory_operand" "m")
9988 (match_operand 2 "" "i")))
9989 (clobber (reg:SI 31))
9990 (use (match_operand 3 "" ""))])] ;; next_arg_reg
9996 if (operands[0]) /* eliminate unused code warning */
9998 addr = XEXP (operands[1], 0);
9999 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
10000 || ! call_insn_operand (addr, VOIDmode))
10001 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
10003 /* In order to pass small structures by value in registers
10004 compatibly with the MIPS compiler, we need to shift the value
10005 into the high part of the register. Function_arg has encoded
10006 a PARALLEL rtx, holding a vector of adjustments to be made
10007 as the next_arg_reg variable, so we split up the insns,
10008 and emit them separately. */
10010 if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
10012 rtvec adjust = XVEC (operands[3], 0);
10013 int num = GET_NUM_ELEM (adjust);
10016 for (i = 0; i < num; i++)
10017 emit_insn (RTVEC_ELT (adjust, i));
10021 && mips16_hard_float
10022 && ((operands[3] != 0
10023 && (int) GET_MODE (operands[3]) != 0)
10024 || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT))
10026 if (build_mips16_call_stub (operands[0], operands[1], operands[2],
10027 (operands[3] == 0 ? 0
10028 : (int) GET_MODE (operands[3]))))
10032 /* Handle Irix6 function calls that have multiple non-contiguous
10034 if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
10036 emit_call_insn (gen_call_value_multiple_internal0
10037 (XEXP (XVECEXP (operands[0], 0, 0), 0),
10038 operands[1], operands[2],
10039 XEXP (XVECEXP (operands[0], 0, 1), 0),
10040 gen_rtx_REG (SImode, GP_REG_FIRST + 31)));
10044 /* We have a call returning a DImode structure in an FP reg.
10045 Strip off the now unnecessary PARALLEL. */
10046 if (GET_CODE (operands[0]) == PARALLEL)
10047 operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
10049 emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
10050 gen_rtx_REG (SImode,
10051 GP_REG_FIRST + 31)));
10057 (define_expand "call_value_internal0"
10058 [(parallel [(set (match_operand 0 "" "")
10059 (call (match_operand 1 "" "")
10060 (match_operand 2 "" "")))
10061 (clobber (match_operand:SI 3 "" ""))])]
10065 ;; Recognize $31 specially on the mips16, because we don't have a
10066 ;; constraint letter for it.
10069 [(set (match_operand 0 "register_operand" "=d")
10070 (call (mem (match_operand 1 "call_insn_operand" "ei"))
10071 (match_operand 2 "" "i")))
10072 (clobber (match_operand:SI 3 "register_operand" "=y"))]
10073 "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
10074 && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
10076 [(set_attr "type" "call")
10077 (set_attr "mode" "none")
10078 (set_attr "length" "8")])
10080 (define_insn "call_value_internal1"
10081 [(set (match_operand 0 "register_operand" "=df")
10082 (call (mem (match_operand 1 "call_insn_operand" "ri"))
10083 (match_operand 2 "" "i")))
10084 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10085 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10088 register rtx target = operands[1];
10090 if (GET_CODE (target) == CONST_INT)
10091 return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
10092 else if (CONSTANT_ADDRESS_P (target))
10093 return \"%*jal\\t%1\";
10095 return \"%*jal\\t%3,%1\";
10097 [(set_attr "type" "call")
10098 (set_attr "mode" "none")])
10100 (define_insn "call_value_internal2"
10101 [(set (match_operand 0 "register_operand" "=df")
10102 (call (mem (match_operand 1 "call_insn_operand" "ri"))
10103 (match_operand 2 "" "i")))
10104 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10105 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10108 register rtx target = operands[1];
10110 if (GET_CODE (target) == CONST_INT)
10111 return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
10112 else if (CONSTANT_ADDRESS_P (target))
10114 if (GET_MODE (target) == SImode)
10115 return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
10117 return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
10119 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10120 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10122 return \"jal\\t%3,%1\";
10124 [(set_attr "type" "call")
10125 (set_attr "mode" "none")
10126 (set_attr "length" "8")])
10128 (define_insn "call_value_internal3a"
10129 [(set (match_operand 0 "register_operand" "=df")
10130 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10131 (match_operand 2 "" "i")))
10132 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10134 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10136 [(set_attr "type" "call")
10137 (set_attr "mode" "none")])
10139 (define_insn "call_value_internal3b"
10140 [(set (match_operand 0 "register_operand" "=df")
10141 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10142 (match_operand 2 "" "i")))
10143 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10145 && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10147 [(set_attr "type" "call")
10148 (set_attr "mode" "none")])
10150 (define_insn "call_value_internal3c"
10151 [(set (match_operand 0 "register_operand" "=df")
10152 (call (mem:SI (match_operand:SI 1 "register_operand" "e"))
10153 (match_operand 2 "" "i")))
10154 (clobber (match_operand:SI 3 "register_operand" "=y"))]
10155 "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
10156 && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
10158 [(set_attr "type" "call")
10159 (set_attr "mode" "none")])
10161 (define_insn "call_value_internal4a"
10162 [(set (match_operand 0 "register_operand" "=df")
10163 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10164 (match_operand 2 "" "i")))
10165 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10166 "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
10169 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10170 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10172 return \"jal\\t%3,%1\";
10174 [(set_attr "type" "call")
10175 (set_attr "mode" "none")
10176 (set_attr "length" "8")])
10178 (define_insn "call_value_internal4b"
10179 [(set (match_operand 0 "register_operand" "=df")
10180 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10181 (match_operand 2 "" "i")))
10182 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10183 "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
10186 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10187 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10189 return \"jal\\t%3,%1\";
10191 [(set_attr "type" "call")
10192 (set_attr "mode" "none")
10193 (set_attr "length" "8")])
10195 (define_expand "call_value_multiple_internal0"
10196 [(parallel [(set (match_operand 0 "" "")
10197 (call (match_operand 1 "" "")
10198 (match_operand 2 "" "")))
10199 (set (match_operand 3 "" "")
10200 (call (match_dup 1)
10202 (clobber (match_operand:SI 4 "" ""))])]
10206 ;; ??? May eventually need all 6 versions of the call patterns with multiple
10209 (define_insn "call_value_multiple_internal1"
10210 [(set (match_operand 0 "register_operand" "=df")
10211 (call (mem (match_operand 1 "call_insn_operand" "ri"))
10212 (match_operand 2 "" "i")))
10213 (set (match_operand 3 "register_operand" "=df")
10214 (call (mem (match_dup 1))
10216 (clobber (match_operand:SI 4 "register_operand" "=d"))]
10217 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10220 register rtx target = operands[1];
10222 if (GET_CODE (target) == CONST_INT)
10223 return \"%[li\\t%@,%1\\n\\t%*jal\\t%4,%@%]\";
10224 else if (CONSTANT_ADDRESS_P (target))
10225 return \"%*jal\\t%1\";
10227 return \"%*jal\\t%4,%1\";
10229 [(set_attr "type" "call")
10230 (set_attr "mode" "none")])
10232 (define_insn "call_value_multiple_internal2"
10233 [(set (match_operand 0 "register_operand" "=df")
10234 (call (mem (match_operand 1 "call_insn_operand" "ri"))
10235 (match_operand 2 "" "i")))
10236 (set (match_operand 3 "register_operand" "=df")
10237 (call (mem (match_dup 1))
10239 (clobber (match_operand:SI 4 "register_operand" "=d"))]
10240 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10243 register rtx target = operands[1];
10245 if (GET_CODE (target) == CONST_INT)
10246 return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
10247 else if (CONSTANT_ADDRESS_P (target))
10249 if (GET_MODE (target) == SImode)
10250 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
10252 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
10254 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10255 return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
10257 return \"jal\\t%4,%1\";
10259 [(set_attr "type" "call")
10260 (set_attr "mode" "none")
10261 (set_attr "length" "8")])
10264 ;; Call subroutine returning any type.
10266 (define_expand "untyped_call"
10267 [(parallel [(call (match_operand 0 "" "")
10269 (match_operand 1 "" "")
10270 (match_operand 2 "" "")])]
10274 if (operands[0]) /* silence statement not reached warnings */
10278 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
10280 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10282 rtx set = XVECEXP (operands[2], 0, i);
10283 emit_move_insn (SET_DEST (set), SET_SRC (set));
10286 emit_insn (gen_blockage ());
10292 ;; ....................
10296 ;; ....................
10303 [(set_attr "type" "nop")
10304 (set_attr "mode" "none")])
10306 ;; The MIPS chip does not seem to require stack probes.
10308 ;; (define_expand "probe"
10309 ;; [(set (match_dup 0)
10314 ;; operands[0] = gen_reg_rtx (SImode);
10315 ;; operands[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
10316 ;; MEM_VOLATILE_P (operands[1]) = TRUE;
10318 ;; /* fall through and generate default code */
10323 ;; MIPS4 Conditional move instructions.
10326 [(set (match_operand:SI 0 "register_operand" "=d,d")
10328 (match_operator 4 "equality_op"
10329 [(match_operand:SI 1 "register_operand" "d,d")
10331 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10332 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10333 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10336 mov%b4\\t%0,%z3,%1"
10337 [(set_attr "type" "move")
10338 (set_attr "mode" "SI")])
10341 [(set (match_operand:SI 0 "register_operand" "=d,d")
10343 (match_operator 4 "equality_op"
10344 [(match_operand:DI 1 "se_register_operand" "d,d")
10346 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10347 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10348 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10351 mov%b4\\t%0,%z3,%1"
10352 [(set_attr "type" "move")
10353 (set_attr "mode" "SI")])
10356 [(set (match_operand:SI 0 "register_operand" "=d,d")
10358 (match_operator 3 "equality_op" [(match_operand:CC 4
10362 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
10363 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
10364 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10367 mov%t3\\t%0,%z2,%4"
10368 [(set_attr "type" "move")
10369 (set_attr "mode" "SI")])
10372 [(set (match_operand:DI 0 "register_operand" "=d,d")
10374 (match_operator 4 "equality_op"
10375 [(match_operand:SI 1 "register_operand" "d,d")
10377 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10378 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10379 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10382 mov%b4\\t%0,%z3,%1"
10383 [(set_attr "type" "move")
10384 (set_attr "mode" "DI")])
10387 [(set (match_operand:DI 0 "register_operand" "=d,d")
10389 (match_operator 4 "equality_op"
10390 [(match_operand:DI 1 "se_register_operand" "d,d")
10392 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10393 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10394 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10397 mov%b4\\t%0,%z3,%1"
10398 [(set_attr "type" "move")
10399 (set_attr "mode" "DI")])
10402 [(set (match_operand:DI 0 "register_operand" "=d,d")
10404 (match_operator 3 "equality_op" [(match_operand:CC 4
10408 (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
10409 (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
10410 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
10413 mov%t3\\t%0,%z2,%4"
10414 [(set_attr "type" "move")
10415 (set_attr "mode" "DI")])
10418 [(set (match_operand:SF 0 "register_operand" "=f,f")
10420 (match_operator 4 "equality_op"
10421 [(match_operand:SI 1 "register_operand" "d,d")
10423 (match_operand:SF 2 "register_operand" "f,0")
10424 (match_operand:SF 3 "register_operand" "0,f")))]
10425 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10427 mov%B4.s\\t%0,%2,%1
10428 mov%b4.s\\t%0,%3,%1"
10429 [(set_attr "type" "move")
10430 (set_attr "mode" "SF")])
10433 [(set (match_operand:SF 0 "register_operand" "=f,f")
10435 (match_operator 4 "equality_op"
10436 [(match_operand:DI 1 "se_register_operand" "d,d")
10438 (match_operand:SF 2 "register_operand" "f,0")
10439 (match_operand:SF 3 "register_operand" "0,f")))]
10440 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10442 mov%B4.s\\t%0,%2,%1
10443 mov%b4.s\\t%0,%3,%1"
10444 [(set_attr "type" "move")
10445 (set_attr "mode" "SF")])
10448 [(set (match_operand:SF 0 "register_operand" "=f,f")
10450 (match_operator 3 "equality_op" [(match_operand:CC 4
10454 (match_operand:SF 1 "register_operand" "f,0")
10455 (match_operand:SF 2 "register_operand" "0,f")))]
10456 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10458 mov%T3.s\\t%0,%1,%4
10459 mov%t3.s\\t%0,%2,%4"
10460 [(set_attr "type" "move")
10461 (set_attr "mode" "SF")])
10464 [(set (match_operand:DF 0 "register_operand" "=f,f")
10466 (match_operator 4 "equality_op"
10467 [(match_operand:SI 1 "register_operand" "d,d")
10469 (match_operand:DF 2 "register_operand" "f,0")
10470 (match_operand:DF 3 "register_operand" "0,f")))]
10471 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10473 mov%B4.d\\t%0,%2,%1
10474 mov%b4.d\\t%0,%3,%1"
10475 [(set_attr "type" "move")
10476 (set_attr "mode" "DF")])
10479 [(set (match_operand:DF 0 "register_operand" "=f,f")
10481 (match_operator 4 "equality_op"
10482 [(match_operand:DI 1 "se_register_operand" "d,d")
10484 (match_operand:DF 2 "register_operand" "f,0")
10485 (match_operand:DF 3 "register_operand" "0,f")))]
10486 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10488 mov%B4.d\\t%0,%2,%1
10489 mov%b4.d\\t%0,%3,%1"
10490 [(set_attr "type" "move")
10491 (set_attr "mode" "DF")])
10494 [(set (match_operand:DF 0 "register_operand" "=f,f")
10496 (match_operator 3 "equality_op" [(match_operand:CC 4
10500 (match_operand:DF 1 "register_operand" "f,0")
10501 (match_operand:DF 2 "register_operand" "0,f")))]
10502 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10504 mov%T3.d\\t%0,%1,%4
10505 mov%t3.d\\t%0,%2,%4"
10506 [(set_attr "type" "move")
10507 (set_attr "mode" "DF")])
10509 ;; These are the main define_expand's used to make conditional moves.
10511 (define_expand "movsicc"
10512 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10513 (set (match_operand:SI 0 "register_operand" "")
10514 (if_then_else:SI (match_dup 5)
10515 (match_operand:SI 2 "reg_or_0_operand" "")
10516 (match_operand:SI 3 "reg_or_0_operand" "")))]
10517 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10520 gen_conditional_move (operands);
10524 (define_expand "movdicc"
10525 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10526 (set (match_operand:DI 0 "register_operand" "")
10527 (if_then_else:DI (match_dup 5)
10528 (match_operand:DI 2 "se_reg_or_0_operand" "")
10529 (match_operand:DI 3 "se_reg_or_0_operand" "")))]
10530 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10533 if (mips_isa == 32)
10535 gen_conditional_move (operands);
10539 (define_expand "movsfcc"
10540 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10541 (set (match_operand:SF 0 "register_operand" "")
10542 (if_then_else:SF (match_dup 5)
10543 (match_operand:SF 2 "register_operand" "")
10544 (match_operand:SF 3 "register_operand" "")))]
10545 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10548 gen_conditional_move (operands);
10552 (define_expand "movdfcc"
10553 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10554 (set (match_operand:DF 0 "register_operand" "")
10555 (if_then_else:DF (match_dup 5)
10556 (match_operand:DF 2 "register_operand" "")
10557 (match_operand:DF 3 "register_operand" "")))]
10558 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10561 gen_conditional_move (operands);
10566 ;; ....................
10568 ;; mips16 inline constant tables
10570 ;; ....................
10573 (define_insn "consttable_qi"
10574 [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")]
10575 UNSPEC_CONSTTABLE_QI)]
10579 assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
10582 [(set_attr "type" "unknown")
10583 (set_attr "mode" "QI")
10584 (set_attr "length" "8")])
10586 (define_insn "consttable_hi"
10587 [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")]
10588 UNSPEC_CONSTTABLE_HI)]
10592 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10595 [(set_attr "type" "unknown")
10596 (set_attr "mode" "HI")
10597 (set_attr "length" "8")])
10599 (define_insn "consttable_si"
10600 [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")]
10601 UNSPEC_CONSTTABLE_SI)]
10605 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10608 [(set_attr "type" "unknown")
10609 (set_attr "mode" "SI")
10610 (set_attr "length" "8")])
10612 (define_insn "consttable_di"
10613 [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")]
10614 UNSPEC_CONSTTABLE_DI)]
10618 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10621 [(set_attr "type" "unknown")
10622 (set_attr "mode" "DI")
10623 (set_attr "length" "16")])
10625 (define_insn "consttable_sf"
10626 [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")]
10627 UNSPEC_CONSTTABLE_SF)]
10633 if (GET_CODE (operands[0]) != CONST_DOUBLE)
10635 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10636 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10639 [(set_attr "type" "unknown")
10640 (set_attr "mode" "SF")
10641 (set_attr "length" "8")])
10643 (define_insn "consttable_df"
10644 [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")]
10645 UNSPEC_CONSTTABLE_DF)]
10651 if (GET_CODE (operands[0]) != CONST_DOUBLE)
10653 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10654 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10657 [(set_attr "type" "unknown")
10658 (set_attr "mode" "DF")
10659 (set_attr "length" "16")])
10661 (define_insn "align_2"
10662 [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_2)]
10665 [(set_attr "type" "unknown")
10666 (set_attr "mode" "HI")
10667 (set_attr "length" "8")])
10669 (define_insn "align_4"
10670 [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_4)]
10673 [(set_attr "type" "unknown")
10674 (set_attr "mode" "SI")
10675 (set_attr "length" "8")])
10677 (define_insn "align_8"
10678 [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_8)]
10681 [(set_attr "type" "unknown")
10682 (set_attr "mode" "DI")
10683 (set_attr "length" "12")])
10686 ;; ....................
10688 ;; mips16 peepholes
10690 ;; ....................
10693 ;; On the mips16, reload will sometimes decide that a pseudo register
10694 ;; should go into $24, and then later on have to reload that register.
10695 ;; When that happens, we get a load of a general register followed by
10696 ;; a move from the general register to $24 followed by a branch.
10697 ;; These peepholes catch the common case, and fix it to just use the
10698 ;; general register for the branch.
10701 [(set (match_operand:SI 0 "register_operand" "=t")
10702 (match_operand:SI 1 "register_operand" "d"))
10704 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10706 (match_operand 3 "pc_or_label_operand" "")
10707 (match_operand 4 "pc_or_label_operand" "")))]
10709 && GET_CODE (operands[0]) == REG
10710 && REGNO (operands[0]) == 24
10711 && dead_or_set_p (insn, operands[0])
10712 && GET_CODE (operands[1]) == REG
10713 && M16_REG_P (REGNO (operands[1]))"
10716 if (operands[3] != pc_rtx)
10717 return \"%*b%C2z\\t%1,%3\";
10719 return \"%*b%N2z\\t%1,%4\";
10721 [(set_attr "type" "branch")
10722 (set_attr "mode" "none")
10723 (set_attr "length" "8")])
10726 [(set (match_operand:DI 0 "register_operand" "=t")
10727 (match_operand:DI 1 "register_operand" "d"))
10729 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10731 (match_operand 3 "pc_or_label_operand" "")
10732 (match_operand 4 "pc_or_label_operand" "")))]
10733 "TARGET_MIPS16 && TARGET_64BIT
10734 && GET_CODE (operands[0]) == REG
10735 && REGNO (operands[0]) == 24
10736 && dead_or_set_p (insn, operands[0])
10737 && GET_CODE (operands[1]) == REG
10738 && M16_REG_P (REGNO (operands[1]))"
10741 if (operands[3] != pc_rtx)
10742 return \"%*b%C2z\\t%1,%3\";
10744 return \"%*b%N2z\\t%1,%4\";
10746 [(set_attr "type" "branch")
10747 (set_attr "mode" "none")
10748 (set_attr "length" "8")])
10750 ;; We can also have the reverse reload: reload will spill $24 into
10751 ;; another register, and then do a branch on that register when it
10752 ;; could have just stuck with $24.
10755 [(set (match_operand:SI 0 "register_operand" "=d")
10756 (match_operand:SI 1 "register_operand" "t"))
10758 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10760 (match_operand 3 "pc_or_label_operand" "")
10761 (match_operand 4 "pc_or_label_operand" "")))]
10763 && GET_CODE (operands[1]) == REG
10764 && REGNO (operands[1]) == 24
10765 && GET_CODE (operands[0]) == REG
10766 && M16_REG_P (REGNO (operands[0]))
10767 && dead_or_set_p (insn, operands[0])"
10770 if (operands[3] != pc_rtx)
10771 return \"%*bt%C2z\\t%3\";
10773 return \"%*bt%N2z\\t%4\";
10775 [(set_attr "type" "branch")
10776 (set_attr "mode" "none")
10777 (set_attr "length" "8")])
10780 [(set (match_operand:DI 0 "register_operand" "=d")
10781 (match_operand:DI 1 "register_operand" "t"))
10783 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10785 (match_operand 3 "pc_or_label_operand" "")
10786 (match_operand 4 "pc_or_label_operand" "")))]
10787 "TARGET_MIPS16 && TARGET_64BIT
10788 && GET_CODE (operands[1]) == REG
10789 && REGNO (operands[1]) == 24
10790 && GET_CODE (operands[0]) == REG
10791 && M16_REG_P (REGNO (operands[0]))
10792 && dead_or_set_p (insn, operands[0])"
10795 if (operands[3] != pc_rtx)
10796 return \"%*bt%C2z\\t%3\";
10798 return \"%*bt%N2z\\t%4\";
10800 [(set_attr "type" "branch")
10801 (set_attr "mode" "none")
10802 (set_attr "length" "8")])
10804 ;; For the rare case where we need to load an address into a register
10805 ;; that can not be recognized by the normal movsi/addsi instructions.
10806 ;; I have no idea how many insns this can actually generate. It should
10807 ;; be rare, so over-estimating as 10 instructions should not have any
10808 ;; real performance impact.
10809 (define_insn "leasi"
10810 [(set (match_operand:SI 0 "register_operand" "=d")
10811 (match_operand:SI 1 "address_operand" "p"))]
10814 [(set_attr "type" "arith")
10815 (set_attr "mode" "SI")
10816 (set_attr "length" "40")])
10818 ;; Similarly for targets where we have 64bit pointers.
10819 (define_insn "leadi"
10820 [(set (match_operand:DI 0 "register_operand" "=d")
10821 (match_operand:DI 1 "address_operand" "p"))]
10824 [(set_attr "type" "arith")
10825 (set_attr "mode" "DI")
10826 (set_attr "length" "40")])