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, CONST_DOUBLE_FROM_REAL_VALUE (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, CONST_DOUBLE_FROM_REAL_VALUE (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, CONST_DOUBLE_FROM_REAL_VALUE (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, CONST_DOUBLE_FROM_REAL_VALUE (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%z1,%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,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,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,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,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,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,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,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,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,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,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,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,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,R,m,*d,*d")
5563 (match_operand:SI 1 "move_operand" "d,d,y,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,arith,arith,arith,load,load,store,store,hilo,hilo")
5576 (set_attr "mode" "SI")
5577 (set_attr_alternative "length"
5581 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5584 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5587 (if_then_else (match_operand:VOID 1 "m16_usym8_4" "")
5597 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
5598 ;; when the original load is a 4 byte instruction but the add and the
5599 ;; load are 2 2 byte instructions.
5602 [(set (match_operand:SI 0 "register_operand" "")
5603 (mem:SI (plus:SI (match_dup 0)
5604 (match_operand:SI 1 "const_int_operand" ""))))]
5605 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5606 && GET_CODE (operands[0]) == REG
5607 && M16_REG_P (REGNO (operands[0]))
5608 && GET_CODE (operands[1]) == CONST_INT
5609 && ((INTVAL (operands[1]) < 0
5610 && INTVAL (operands[1]) >= -0x80)
5611 || (INTVAL (operands[1]) >= 32 * 4
5612 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
5613 || (INTVAL (operands[1]) >= 0
5614 && INTVAL (operands[1]) < 32 * 4
5615 && (INTVAL (operands[1]) & 3) != 0))"
5616 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5617 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
5620 HOST_WIDE_INT val = INTVAL (operands[1]);
5623 operands[2] = GEN_INT (0);
5624 else if (val >= 32 * 4)
5628 operands[1] = GEN_INT (0x7c + off);
5629 operands[2] = GEN_INT (val - off - 0x7c);
5635 operands[1] = GEN_INT (off);
5636 operands[2] = GEN_INT (val - off);
5640 ;; On the mips16, we can split a load of certain constants into a load
5641 ;; and an add. This turns a 4 byte instruction into 2 2 byte
5645 [(set (match_operand:SI 0 "register_operand" "")
5646 (match_operand:SI 1 "const_int_operand" ""))]
5647 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5648 && GET_CODE (operands[0]) == REG
5649 && M16_REG_P (REGNO (operands[0]))
5650 && GET_CODE (operands[1]) == CONST_INT
5651 && INTVAL (operands[1]) >= 0x100
5652 && INTVAL (operands[1]) <= 0xff + 0x7f"
5653 [(set (match_dup 0) (match_dup 1))
5654 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
5657 int val = INTVAL (operands[1]);
5659 operands[1] = GEN_INT (0xff);
5660 operands[2] = GEN_INT (val - 0xff);
5663 ;; On the mips16, we can split a load of a negative constant into a
5664 ;; load and a neg. That's what mips_move_1word will generate anyhow.
5667 [(set (match_operand:SI 0 "register_operand" "")
5668 (match_operand:SI 1 "const_int_operand" ""))]
5669 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5670 && GET_CODE (operands[0]) == REG
5671 && M16_REG_P (REGNO (operands[0]))
5672 && GET_CODE (operands[1]) == CONST_INT
5673 && INTVAL (operands[1]) < 0
5674 && INTVAL (operands[1]) > - 0x8000"
5675 [(set (match_dup 0) (match_dup 1))
5676 (set (match_dup 0) (neg:SI (match_dup 0)))]
5679 operands[1] = GEN_INT (- INTVAL (operands[1]));
5682 ;; Reload HILO_REGNUM in SI mode. This needs a scratch register in
5683 ;; order to set the sign bit correctly in the HI register.
5685 (define_expand "reload_outsi"
5686 [(set (match_operand:SI 0 "general_operand" "=b")
5687 (match_operand:SI 1 "register_operand" "b"))
5688 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5689 "TARGET_64BIT || TARGET_MIPS16"
5693 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5695 emit_insn (gen_movsi (gen_rtx_REG (SImode, 65), operands[1]));
5696 emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
5697 emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
5698 emit_insn (gen_hilo_delay (operands[0]));
5701 /* Use a mult to reload LO on mips16. ??? This is hideous. */
5703 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5705 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5706 /* This is gen_mulsi3_internal, but we need to fill in the
5707 scratch registers. */
5708 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5710 gen_rtx (SET, VOIDmode,
5712 gen_rtx (MULT, SImode,
5715 gen_rtx (CLOBBER, VOIDmode,
5716 gen_rtx (REG, SImode, 64)),
5717 gen_rtx (CLOBBER, VOIDmode,
5718 gen_rtx (REG, SImode, 66)))));
5721 /* FIXME: I don't know how to get a value into the HI register. */
5722 if (GET_CODE (operands[0]) == REG
5723 && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0]))
5724 : GP_REG_P (REGNO (operands[0]))))
5726 emit_move_insn (operands[0], operands[1]);
5729 /* This handles moves between a float register and HI/LO. */
5730 emit_move_insn (operands[2], operands[1]);
5731 emit_move_insn (operands[0], operands[2]);
5735 ;; Reload a value into HI or LO. There is no mthi or mtlo on mips16,
5736 ;; so we use a mult. ??? This is hideous, and we ought to figure out
5737 ;; something better.
5739 ;; We use no predicate for operand1, because it may be a PLUS, and there
5740 ;; is no convenient predicate for that.
5742 (define_expand "reload_insi"
5743 [(set (match_operand:SI 0 "register_operand" "=b")
5744 (match_operand:SI 1 "" "b"))
5745 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5750 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5752 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5753 /* This is gen_mulsi3_internal, but we need to fill in the
5754 scratch registers. */
5755 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5757 gen_rtx (SET, VOIDmode,
5759 gen_rtx (MULT, SImode,
5762 gen_rtx (CLOBBER, VOIDmode,
5763 gen_rtx (REG, SImode, 64)),
5764 gen_rtx (CLOBBER, VOIDmode,
5765 gen_rtx (REG, SImode, 66)))));
5769 /* If this is a plus, then this must be an add of the stack pointer against
5770 either a hard register or a pseudo. */
5771 if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
5775 if (XEXP (operands[1], 0) == stack_pointer_rtx)
5776 plus_op = XEXP (operands[1], 1);
5777 else if (XEXP (operands[1], 1) == stack_pointer_rtx)
5778 plus_op = XEXP (operands[1], 0);
5782 /* We should have a register now. */
5783 if (GET_CODE (plus_op) != REG)
5786 if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
5788 /* We have to have at least one temporary register which is not
5789 overlapping plus_op. */
5790 if (! rtx_equal_p (plus_op, operands[0]))
5792 emit_move_insn (operands[0], stack_pointer_rtx);
5793 emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
5795 else if (! rtx_equal_p (plus_op, operands[2]))
5797 emit_move_insn (operands[2], stack_pointer_rtx);
5798 emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
5805 /* We need two registers in this case. */
5806 if (! rtx_equal_p (operands[0], operands[2]))
5808 emit_move_insn (operands[0], stack_pointer_rtx);
5809 emit_move_insn (operands[2], plus_op);
5810 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
5818 /* FIXME: I don't know how to get a value into the HI register. */
5819 emit_move_insn (operands[0], operands[1]);
5823 ;; This insn is for the unspec delay for HILO.
5825 (define_insn "hilo_delay"
5826 [(unspec [(match_operand 0 "register_operand" "=b")] UNSPEC_HILO_DELAY)]
5829 [(set_attr "type" "nop")
5830 (set_attr "mode" "none")
5831 (set_attr "can_delay" "no")])
5833 ;; This insn handles moving CCmode values. It's really just a
5834 ;; slightly simplified copy of movsi_internal2, with additional cases
5835 ;; to move a condition register to a general register and to move
5836 ;; between the general registers and the floating point registers.
5838 (define_insn "movcc"
5839 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
5840 (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
5841 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5842 "* return mips_move_1word (operands, insn, FALSE);"
5843 [(set_attr "type" "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
5844 (set_attr "mode" "SI")
5845 (set_attr "length" "8,4,4,8,4,8,4,4,4,4,8,4,8")])
5847 ;; Reload condition code registers. These need scratch registers.
5849 (define_expand "reload_incc"
5850 [(set (match_operand:CC 0 "register_operand" "=z")
5851 (match_operand:CC 1 "general_operand" "z"))
5852 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
5853 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5860 /* This is called when are copying some value into a condition code
5861 register. Operand 0 is the condition code register. Operand 1
5862 is the source. Operand 2 is a scratch register; we use TFmode
5863 because we actually need two floating point registers. */
5864 if (! ST_REG_P (true_regnum (operands[0]))
5865 || ! FP_REG_P (true_regnum (operands[2])))
5868 /* We need to get the source in SFmode so that the insn is
5870 if (GET_CODE (operands[1]) == MEM)
5871 source = adjust_address (operands[1], SFmode, 0);
5872 else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
5873 source = gen_rtx_REG (SFmode, true_regnum (operands[1]));
5875 source = operands[1];
5877 /* FP1 and FP2 are the two halves of the TFmode scratch operand. They
5878 will be single registers in 64-bit mode and register pairs in 32-bit
5879 mode. SOURCE is loaded into FP1 and zero is loaded into FP2. */
5880 regno = REGNO (operands[2]);
5881 fp1 = gen_rtx_REG (SFmode, regno);
5882 fp2 = gen_rtx_REG (SFmode, regno + HARD_REGNO_NREGS (regno, DFmode));
5884 emit_insn (gen_move_insn (fp1, source));
5885 emit_insn (gen_move_insn (fp2, gen_rtx_REG (SFmode, 0)));
5886 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5887 gen_rtx_LT (CCmode, fp2, fp1)));
5892 (define_expand "reload_outcc"
5893 [(set (match_operand:CC 0 "general_operand" "=z")
5894 (match_operand:CC 1 "register_operand" "z"))
5895 (clobber (match_operand:CC 2 "register_operand" "=&d"))]
5896 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5899 /* This is called when we are copying a condition code register out
5900 to save it somewhere. Operand 0 should be the location we are
5901 going to save it to. Operand 1 should be the condition code
5902 register. Operand 2 should be a scratch general purpose register
5903 created for us by reload. The mips_secondary_reload_class
5904 function should have told reload that we don't need a scratch
5905 register if the destination is a general purpose register anyhow. */
5906 if (ST_REG_P (true_regnum (operands[0]))
5907 || GP_REG_P (true_regnum (operands[0]))
5908 || ! ST_REG_P (true_regnum (operands[1]))
5909 || ! GP_REG_P (true_regnum (operands[2])))
5912 /* All we have to do is copy the value from the condition code to
5913 the data register, which movcc can handle, and then store the
5914 value into the real final destination. */
5915 emit_insn (gen_move_insn (operands[2], operands[1]));
5916 emit_insn (gen_move_insn (operands[0], operands[2]));
5921 ;; MIPS4 supports loading and storing a floating point register from
5922 ;; the sum of two general registers. We use two versions for each of
5923 ;; these four instructions: one where the two general registers are
5924 ;; SImode, and one where they are DImode. This is because general
5925 ;; registers will be in SImode when they hold 32 bit values, but,
5926 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
5927 ;; instructions will still work correctly.
5929 ;; ??? Perhaps it would be better to support these instructions by
5930 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
5931 ;; these instructions can only be used to load and store floating
5932 ;; point registers, that would probably cause trouble in reload.
5935 [(set (match_operand:SF 0 "register_operand" "=f")
5936 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5937 (match_operand:SI 2 "register_operand" "d"))))]
5938 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5940 [(set_attr "type" "load")
5941 (set_attr "mode" "SF")])
5944 [(set (match_operand:SF 0 "register_operand" "=f")
5945 (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5946 (match_operand:DI 2 "se_register_operand" "d"))))]
5947 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5949 [(set_attr "type" "load")
5950 (set_attr "mode" "SF")])
5953 [(set (match_operand:DF 0 "register_operand" "=f")
5954 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5955 (match_operand:SI 2 "register_operand" "d"))))]
5956 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5958 [(set_attr "type" "load")
5959 (set_attr "mode" "DF")])
5962 [(set (match_operand:DF 0 "register_operand" "=f")
5963 (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5964 (match_operand:DI 2 "se_register_operand" "d"))))]
5965 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5967 [(set_attr "type" "load")
5968 (set_attr "mode" "DF")])
5971 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5972 (match_operand:SI 2 "register_operand" "d")))
5973 (match_operand:SF 0 "register_operand" "f"))]
5974 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5976 [(set_attr "type" "store")
5977 (set_attr "mode" "SF")])
5980 [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5981 (match_operand:DI 2 "se_register_operand" "d")))
5982 (match_operand:SF 0 "register_operand" "f"))]
5983 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5985 [(set_attr "type" "store")
5986 (set_attr "mode" "SF")])
5989 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5990 (match_operand:SI 2 "register_operand" "d")))
5991 (match_operand:DF 0 "register_operand" "f"))]
5992 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5994 [(set_attr "type" "store")
5995 (set_attr "mode" "DF")])
5998 [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5999 (match_operand:DI 2 "se_register_operand" "d")))
6000 (match_operand:DF 0 "register_operand" "f"))]
6001 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6003 [(set_attr "type" "store")
6004 (set_attr "mode" "DF")])
6006 ;; 16-bit Integer moves
6008 ;; Unlike most other insns, the move insns can't be split with
6009 ;; different predicates, because register spilling and other parts of
6010 ;; the compiler, have memoized the insn number already.
6011 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
6013 (define_expand "movhi"
6014 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6015 (match_operand:HI 1 "general_operand" ""))]
6019 if ((reload_in_progress | reload_completed) == 0
6020 && !register_operand (operands[0], HImode)
6021 && !register_operand (operands[1], HImode)
6023 || (GET_CODE (operands[1]) != CONST_INT
6024 || INTVAL (operands[1]) != 0)))
6026 rtx temp = force_reg (HImode, operands[1]);
6027 emit_move_insn (operands[0], temp);
6032 ;; The difference between these two is whether or not ints are allowed
6033 ;; in FP registers (off by default, use -mdebugh to enable).
6035 (define_insn "movhi_internal1"
6036 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
6037 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
6038 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6039 && (register_operand (operands[0], HImode)
6040 || register_operand (operands[1], HImode)
6041 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6042 "* return mips_move_1word (operands, insn, TRUE);"
6043 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
6044 (set_attr "mode" "HI")
6045 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
6047 (define_insn "movhi_internal2"
6048 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
6049 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
6050 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6051 && (register_operand (operands[0], HImode)
6052 || register_operand (operands[1], HImode)
6053 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6054 "* return mips_move_1word (operands, insn, TRUE);"
6055 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
6056 (set_attr "mode" "HI")
6057 (set_attr "length" "4,4,4,8,4,8,4,4,4,4")])
6060 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
6061 (match_operand:HI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
6063 && (register_operand (operands[0], HImode)
6064 || register_operand (operands[1], HImode))"
6065 "* return mips_move_1word (operands, insn, TRUE);"
6066 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
6067 (set_attr "mode" "HI")
6068 (set_attr_alternative "length"
6072 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
6075 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6085 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
6086 ;; when the original load is a 4 byte instruction but the add and the
6087 ;; load are 2 2 byte instructions.
6090 [(set (match_operand:HI 0 "register_operand" "")
6091 (mem:HI (plus:SI (match_dup 0)
6092 (match_operand:SI 1 "const_int_operand" ""))))]
6093 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6094 && GET_CODE (operands[0]) == REG
6095 && M16_REG_P (REGNO (operands[0]))
6096 && GET_CODE (operands[1]) == CONST_INT
6097 && ((INTVAL (operands[1]) < 0
6098 && INTVAL (operands[1]) >= -0x80)
6099 || (INTVAL (operands[1]) >= 32 * 2
6100 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
6101 || (INTVAL (operands[1]) >= 0
6102 && INTVAL (operands[1]) < 32 * 2
6103 && (INTVAL (operands[1]) & 1) != 0))"
6104 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6105 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
6108 HOST_WIDE_INT val = INTVAL (operands[1]);
6111 operands[2] = GEN_INT (0);
6112 else if (val >= 32 * 2)
6116 operands[1] = GEN_INT (0x7e + off);
6117 operands[2] = GEN_INT (val - off - 0x7e);
6123 operands[1] = GEN_INT (off);
6124 operands[2] = GEN_INT (val - off);
6128 ;; 8-bit Integer moves
6130 ;; Unlike most other insns, the move insns can't be split with
6131 ;; different predicates, because register spilling and other parts of
6132 ;; the compiler, have memoized the insn number already.
6133 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
6135 (define_expand "movqi"
6136 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6137 (match_operand:QI 1 "general_operand" ""))]
6141 if ((reload_in_progress | reload_completed) == 0
6142 && !register_operand (operands[0], QImode)
6143 && !register_operand (operands[1], QImode)
6145 || (GET_CODE (operands[1]) != CONST_INT
6146 || INTVAL (operands[1]) != 0)))
6148 rtx temp = force_reg (QImode, operands[1]);
6149 emit_move_insn (operands[0], temp);
6154 ;; The difference between these two is whether or not ints are allowed
6155 ;; in FP registers (off by default, use -mdebugh to enable).
6157 (define_insn "movqi_internal1"
6158 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
6159 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
6160 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6161 && (register_operand (operands[0], QImode)
6162 || register_operand (operands[1], QImode)
6163 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6164 "* return mips_move_1word (operands, insn, TRUE);"
6165 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
6166 (set_attr "mode" "QI")
6167 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
6169 (define_insn "movqi_internal2"
6170 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
6171 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
6172 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6173 && (register_operand (operands[0], QImode)
6174 || register_operand (operands[1], QImode)
6175 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6176 "* return mips_move_1word (operands, insn, TRUE);"
6177 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
6178 (set_attr "mode" "QI")
6179 (set_attr "length" "4,4,4,8,4,8,4,4,4,4")])
6182 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
6183 (match_operand:QI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
6185 && (register_operand (operands[0], QImode)
6186 || register_operand (operands[1], QImode))"
6187 "* return mips_move_1word (operands, insn, TRUE);"
6188 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
6189 (set_attr "mode" "QI")
6190 (set_attr_alternative "length"
6194 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
6197 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6207 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
6208 ;; when the original load is a 4 byte instruction but the add and the
6209 ;; load are 2 2 byte instructions.
6212 [(set (match_operand:QI 0 "register_operand" "")
6213 (mem:QI (plus:SI (match_dup 0)
6214 (match_operand:SI 1 "const_int_operand" ""))))]
6215 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6216 && GET_CODE (operands[0]) == REG
6217 && M16_REG_P (REGNO (operands[0]))
6218 && GET_CODE (operands[1]) == CONST_INT
6219 && ((INTVAL (operands[1]) < 0
6220 && INTVAL (operands[1]) >= -0x80)
6221 || (INTVAL (operands[1]) >= 32
6222 && INTVAL (operands[1]) <= 31 + 0x7f))"
6223 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6224 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
6227 HOST_WIDE_INT val = INTVAL (operands[1]);
6230 operands[2] = GEN_INT (0);
6233 operands[1] = GEN_INT (0x7f);
6234 operands[2] = GEN_INT (val - 0x7f);
6238 ;; 32-bit floating point moves
6240 (define_expand "movsf"
6241 [(set (match_operand:SF 0 "nonimmediate_operand" "")
6242 (match_operand:SF 1 "general_operand" ""))]
6246 if ((reload_in_progress | reload_completed) == 0
6247 && !register_operand (operands[0], SFmode)
6248 && !register_operand (operands[1], SFmode)
6250 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6251 && operands[1] != CONST0_RTX (SFmode))))
6253 rtx temp = force_reg (SFmode, operands[1]);
6254 emit_move_insn (operands[0], temp);
6259 (define_insn "movsf_internal1"
6260 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
6261 (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
6263 && (register_operand (operands[0], SFmode)
6264 || register_operand (operands[1], SFmode)
6265 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6266 || operands[1] == CONST0_RTX (SFmode))"
6267 "* return mips_move_1word (operands, insn, FALSE);"
6268 [(set_attr "type" "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
6269 (set_attr "mode" "SF")
6270 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,8,4,8")])
6273 (define_insn "movsf_internal2"
6274 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
6275 (match_operand:SF 1 "general_operand" " Gd,R,Fm,d,d"))]
6276 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
6277 && (register_operand (operands[0], SFmode)
6278 || register_operand (operands[1], SFmode)
6279 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6280 || operands[1] == CONST0_RTX (SFmode))"
6281 "* return mips_move_1word (operands, insn, FALSE);"
6282 [(set_attr "type" "move,load,load,store,store")
6283 (set_attr "mode" "SF")
6284 (set_attr "length" "4,4,8,4,8")])
6287 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m")
6288 (match_operand:SF 1 "general_operand" "d,d,y,R,Fm,d,d"))]
6290 && (register_operand (operands[0], SFmode)
6291 || register_operand (operands[1], SFmode))"
6292 "* return mips_move_1word (operands, insn, FALSE);"
6293 [(set_attr "type" "move,move,move,load,load,store,store")
6294 (set_attr "mode" "SF")
6295 (set_attr "length" "4,4,4,4,8,4,8")])
6298 ;; 64-bit floating point moves
6300 (define_expand "movdf"
6301 [(set (match_operand:DF 0 "nonimmediate_operand" "")
6302 (match_operand:DF 1 "general_operand" ""))]
6306 if ((reload_in_progress | reload_completed) == 0
6307 && !register_operand (operands[0], DFmode)
6308 && !register_operand (operands[1], DFmode)
6310 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6311 && operands[1] != CONST0_RTX (DFmode))))
6313 rtx temp = force_reg (DFmode, operands[1]);
6314 emit_move_insn (operands[0], temp);
6319 (define_insn "movdf_internal1"
6320 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,To,f,*f,*d,*d,*d,*d,*R,*T")
6321 (match_operand:DF 1 "general_operand" "f,R,To,fG,fG,F,*d,*f,*d*G,*R,*T*F,*d,*d"))]
6322 "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
6323 && TARGET_DOUBLE_FLOAT
6324 && (register_operand (operands[0], DFmode)
6325 || register_operand (operands[1], DFmode)
6326 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6327 || operands[1] == CONST0_RTX (DFmode))"
6328 "* return mips_move_2words (operands, insn); "
6329 [(set_attr "type" "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
6330 (set_attr "mode" "DF")
6331 (set_attr "length" "4,8,16,8,16,16,8,8,8,8,16,8,16")])
6333 (define_insn "movdf_internal1a"
6334 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,*d,*d,*d,*To,*R,*d")
6335 (match_operand:DF 1 "general_operand" " f,To,f,G,f,G,*F,*To,*R,*d,*d,*d"))]
6336 "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
6337 && TARGET_DOUBLE_FLOAT
6338 && (register_operand (operands[0], DFmode)
6339 || register_operand (operands[1], DFmode)
6340 || (GET_CODE (operands [0]) == MEM
6341 && ((GET_CODE (operands[1]) == CONST_INT
6342 && INTVAL (operands[1]) == 0)
6343 || operands[1] == CONST0_RTX (DFmode))))"
6344 "* return mips_move_2words (operands, insn); "
6345 [(set_attr "type" "move,load,store,store,store,store,load,load,load,store,store,move")
6346 (set_attr "mode" "DF")
6347 (set_attr "length" "4,8,4,4,8,8,8,8,4,8,4,4")])
6349 (define_insn "movdf_internal2"
6350 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To,d,f,f")
6351 (match_operand:DF 1 "general_operand" "dG,R,ToF,d,d,f,d,f"))]
6352 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
6353 && (register_operand (operands[0], DFmode)
6354 || register_operand (operands[1], DFmode)
6355 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6356 || operands[1] == CONST0_RTX (DFmode))"
6357 "* return mips_move_2words (operands, insn); "
6358 [(set_attr "type" "move,load,load,store,store,xfer,load,move")
6359 (set_attr "mode" "DF")
6360 (set_attr "length" "8,8,16,8,16,8,8,4")])
6363 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To")
6364 (match_operand:DF 1 "general_operand" "d,d,y,R,ToF,d,d"))]
6366 && (register_operand (operands[0], DFmode)
6367 || register_operand (operands[1], DFmode))"
6368 "* return mips_move_2words (operands, insn);"
6369 [(set_attr "type" "move,move,move,load,load,store,store")
6370 (set_attr "mode" "DF")
6371 (set_attr "length" "8,8,8,8,16,8,16")])
6374 [(set (match_operand:DF 0 "register_operand" "")
6375 (match_operand:DF 1 "register_operand" ""))]
6376 "reload_completed && !TARGET_64BIT
6377 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6378 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
6379 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
6380 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
6381 (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
6384 ;; Instructions to load the global pointer register.
6385 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
6386 ;; uses in front of it. All symbol_refs implicitly use the gp reg.
6388 (define_insn "loadgp"
6390 (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
6391 (match_operand:DI 1 "register_operand" "")]
6393 (clobber (reg:DI 1))]
6395 "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]"
6396 [(set_attr "type" "move")
6397 (set_attr "mode" "DI")
6398 (set_attr "length" "12")])
6400 ;; Block moves, see mips.c for more details.
6401 ;; Argument 0 is the destination
6402 ;; Argument 1 is the source
6403 ;; Argument 2 is the length
6404 ;; Argument 3 is the alignment
6406 (define_expand "movstrsi"
6407 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
6408 (match_operand:BLK 1 "general_operand" ""))
6409 (use (match_operand:SI 2 "arith32_operand" ""))
6410 (use (match_operand:SI 3 "immediate_operand" ""))])]
6414 if (operands[0]) /* avoid unused code messages */
6416 expand_block_move (operands);
6421 ;; Insn generated by block moves
6423 (define_insn "movstrsi_internal"
6424 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6425 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6426 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6427 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6428 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6429 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6430 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6431 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6432 (use (const_int 0))] ;; normal block move
6434 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6435 [(set_attr "type" "store")
6436 (set_attr "mode" "none")
6437 (set_attr "length" "80")])
6439 ;; We need mips16 versions, because an offset from the stack pointer
6440 ;; is not offsettable, since the stack pointer can only handle 4 and 8
6444 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6445 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6446 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6447 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6448 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6449 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6450 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6451 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6452 (use (const_int 0))] ;; normal block move
6454 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6455 [(set_attr "type" "multi")
6456 (set_attr "mode" "none")
6457 (set_attr "length" "80")])
6459 ;; Split a block move into 2 parts, the first part is everything
6460 ;; except for the last move, and the second part is just the last
6461 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
6462 ;; fill a delay slot. This also prevents a bug in delayed branches
6463 ;; from showing up, which reuses one of the registers in our clobbers.
6466 [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
6467 (mem:BLK (match_operand:SI 1 "register_operand" "")))
6468 (clobber (match_operand:SI 4 "register_operand" ""))
6469 (clobber (match_operand:SI 5 "register_operand" ""))
6470 (clobber (match_operand:SI 6 "register_operand" ""))
6471 (clobber (match_operand:SI 7 "register_operand" ""))
6472 (use (match_operand:SI 2 "small_int" ""))
6473 (use (match_operand:SI 3 "small_int" ""))
6474 (use (const_int 0))]
6476 "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
6478 ;; All but the last move
6479 [(parallel [(set (mem:BLK (match_dup 0))
6480 (mem:BLK (match_dup 1)))
6481 (clobber (match_dup 4))
6482 (clobber (match_dup 5))
6483 (clobber (match_dup 6))
6484 (clobber (match_dup 7))
6487 (use (const_int 1))])
6489 ;; The last store, so it can fill a delay slot
6490 (parallel [(set (mem:BLK (match_dup 0))
6491 (mem:BLK (match_dup 1)))
6492 (clobber (match_dup 4))
6493 (clobber (match_dup 5))
6494 (clobber (match_dup 6))
6495 (clobber (match_dup 7))
6498 (use (const_int 2))])]
6502 (define_insn "movstrsi_internal2"
6503 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6504 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6505 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6506 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6507 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6508 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6509 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6510 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6511 (use (const_int 1))] ;; all but last store
6513 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6514 [(set_attr "type" "store")
6515 (set_attr "mode" "none")
6516 (set_attr "length" "80")])
6519 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6520 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6521 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6522 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6523 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6524 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6525 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6526 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6527 (use (const_int 1))] ;; all but last store
6529 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6530 [(set_attr "type" "multi")
6531 (set_attr "mode" "none")
6532 (set_attr "length" "80")])
6534 (define_insn "movstrsi_internal3"
6535 [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
6536 (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
6537 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6538 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6539 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6540 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6541 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6542 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6543 (use (const_int 2))] ;; just last store of block move
6545 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6546 [(set_attr "type" "store")
6547 (set_attr "mode" "none")])
6550 ;; ....................
6554 ;; ....................
6556 ;; Many of these instructions uses trivial define_expands, because we
6557 ;; want to use a different set of constraints when TARGET_MIPS16.
6559 (define_expand "ashlsi3"
6560 [(set (match_operand:SI 0 "register_operand" "=d")
6561 (ashift:SI (match_operand:SI 1 "register_operand" "d")
6562 (match_operand:SI 2 "arith_operand" "dI")))]
6566 /* On the mips16, a shift of more than 8 is a four byte instruction,
6567 so, for a shift between 8 and 16, it is just as fast to do two
6568 shifts of 8 or less. If there is a lot of shifting going on, we
6569 may win in CSE. Otherwise combine will put the shifts back
6570 together again. This can be called by function_arg, so we must
6571 be careful not to allocate a new register if we've reached the
6575 && GET_CODE (operands[2]) == CONST_INT
6576 && INTVAL (operands[2]) > 8
6577 && INTVAL (operands[2]) <= 16
6578 && ! reload_in_progress
6579 && ! reload_completed)
6581 rtx temp = gen_reg_rtx (SImode);
6583 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
6584 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
6585 GEN_INT (INTVAL (operands[2]) - 8)));
6590 (define_insn "ashlsi3_internal1"
6591 [(set (match_operand:SI 0 "register_operand" "=d")
6592 (ashift:SI (match_operand:SI 1 "register_operand" "d")
6593 (match_operand:SI 2 "arith_operand" "dI")))]
6597 if (GET_CODE (operands[2]) == CONST_INT)
6598 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6600 return \"sll\\t%0,%1,%2\";
6602 [(set_attr "type" "arith")
6603 (set_attr "mode" "SI")])
6605 (define_insn "ashlsi3_internal2"
6606 [(set (match_operand:SI 0 "register_operand" "=d,d")
6607 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
6608 (match_operand:SI 2 "arith_operand" "d,I")))]
6612 if (which_alternative == 0)
6613 return \"sll\\t%0,%2\";
6615 if (GET_CODE (operands[2]) == CONST_INT)
6616 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6618 return \"sll\\t%0,%1,%2\";
6620 [(set_attr "type" "arith")
6621 (set_attr "mode" "SI")
6622 (set_attr_alternative "length"
6624 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6628 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6631 [(set (match_operand:SI 0 "register_operand" "")
6632 (ashift:SI (match_operand:SI 1 "register_operand" "")
6633 (match_operand:SI 2 "const_int_operand" "")))]
6634 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6635 && GET_CODE (operands[2]) == CONST_INT
6636 && INTVAL (operands[2]) > 8
6637 && INTVAL (operands[2]) <= 16"
6638 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
6639 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
6642 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6645 (define_expand "ashldi3"
6646 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6647 (ashift:DI (match_operand:DI 1 "se_register_operand" "")
6648 (match_operand:SI 2 "arith_operand" "")))
6649 (clobber (match_dup 3))])]
6650 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6655 /* On the mips16, a shift of more than 8 is a four byte
6656 instruction, so, for a shift between 8 and 16, it is just as
6657 fast to do two shifts of 8 or less. If there is a lot of
6658 shifting going on, we may win in CSE. Otherwise combine will
6659 put the shifts back together again. This can be called by
6660 function_arg, so we must be careful not to allocate a new
6661 register if we've reached the reload pass. */
6664 && GET_CODE (operands[2]) == CONST_INT
6665 && INTVAL (operands[2]) > 8
6666 && INTVAL (operands[2]) <= 16
6667 && ! reload_in_progress
6668 && ! reload_completed)
6670 rtx temp = gen_reg_rtx (DImode);
6672 emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
6673 emit_insn (gen_ashldi3_internal4 (operands[0], temp,
6674 GEN_INT (INTVAL (operands[2]) - 8)));
6678 emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
6683 operands[3] = gen_reg_rtx (SImode);
6687 (define_insn "ashldi3_internal"
6688 [(set (match_operand:DI 0 "register_operand" "=&d")
6689 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6690 (match_operand:SI 2 "register_operand" "d")))
6691 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6692 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6695 operands[4] = const0_rtx;
6696 dslots_jump_total += 3;
6697 dslots_jump_filled += 2;
6699 return \"sll\\t%3,%2,26\\n\\
6700 \\tbgez\\t%3,1f\\n\\
6701 \\tsll\\t%M0,%L1,%2\\n\\
6703 \\tmove\\t%L0,%z4%)\\n\\
6706 \\t%(beq\\t%3,%z4,2f\\n\\
6707 \\tsll\\t%M0,%M1,%2%)\\n\\
6709 \\tsubu\\t%3,%z4,%2\\n\\
6710 \\tsrl\\t%3,%L1,%3\\n\\
6711 \\tor\\t%M0,%M0,%3\\n\\
6713 \\tsll\\t%L0,%L1,%2\\n\\
6716 [(set_attr "type" "darith")
6717 (set_attr "mode" "SI")
6718 (set_attr "length" "48")])
6721 (define_insn "ashldi3_internal2"
6722 [(set (match_operand:DI 0 "register_operand" "=d")
6723 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6724 (match_operand:SI 2 "small_int" "IJK")))
6725 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6726 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6727 && (INTVAL (operands[2]) & 32) != 0"
6730 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6731 operands[4] = const0_rtx;
6732 return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
6734 [(set_attr "type" "darith")
6735 (set_attr "mode" "DI")
6736 (set_attr "length" "8")])
6740 [(set (match_operand:DI 0 "register_operand" "")
6741 (ashift:DI (match_operand:DI 1 "register_operand" "")
6742 (match_operand:SI 2 "small_int" "")))
6743 (clobber (match_operand:SI 3 "register_operand" ""))]
6744 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6745 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6746 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6747 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6748 && (INTVAL (operands[2]) & 32) != 0"
6750 [(set (subreg:SI (match_dup 0) 4) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6751 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6753 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6757 [(set (match_operand:DI 0 "register_operand" "")
6758 (ashift:DI (match_operand:DI 1 "register_operand" "")
6759 (match_operand:SI 2 "small_int" "")))
6760 (clobber (match_operand:SI 3 "register_operand" ""))]
6761 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6762 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6763 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6764 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6765 && (INTVAL (operands[2]) & 32) != 0"
6767 [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
6768 (set (subreg:SI (match_dup 0) 4) (const_int 0))]
6770 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6773 (define_insn "ashldi3_internal3"
6774 [(set (match_operand:DI 0 "register_operand" "=d")
6775 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6776 (match_operand:SI 2 "small_int" "IJK")))
6777 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6778 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6779 && (INTVAL (operands[2]) & 63) < 32
6780 && (INTVAL (operands[2]) & 63) != 0"
6783 int amount = INTVAL (operands[2]);
6785 operands[2] = GEN_INT (amount & 31);
6786 operands[4] = const0_rtx;
6787 operands[5] = GEN_INT ((-amount) & 31);
6789 return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
6791 [(set_attr "type" "darith")
6792 (set_attr "mode" "DI")
6793 (set_attr "length" "16")])
6797 [(set (match_operand:DI 0 "register_operand" "")
6798 (ashift:DI (match_operand:DI 1 "register_operand" "")
6799 (match_operand:SI 2 "small_int" "")))
6800 (clobber (match_operand:SI 3 "register_operand" ""))]
6801 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6802 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6803 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6804 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6805 && (INTVAL (operands[2]) & 63) < 32
6806 && (INTVAL (operands[2]) & 63) != 0"
6808 [(set (subreg:SI (match_dup 0) 4)
6809 (ashift:SI (subreg:SI (match_dup 1) 4)
6813 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6816 (set (subreg:SI (match_dup 0) 4)
6817 (ior:SI (subreg:SI (match_dup 0) 4)
6820 (set (subreg:SI (match_dup 0) 0)
6821 (ashift:SI (subreg:SI (match_dup 1) 0)
6825 int amount = INTVAL (operands[2]);
6826 operands[2] = GEN_INT (amount & 31);
6827 operands[4] = GEN_INT ((-amount) & 31);
6832 [(set (match_operand:DI 0 "register_operand" "")
6833 (ashift:DI (match_operand:DI 1 "register_operand" "")
6834 (match_operand:SI 2 "small_int" "")))
6835 (clobber (match_operand:SI 3 "register_operand" ""))]
6836 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6837 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6838 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6839 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6840 && (INTVAL (operands[2]) & 63) < 32
6841 && (INTVAL (operands[2]) & 63) != 0"
6843 [(set (subreg:SI (match_dup 0) 0)
6844 (ashift:SI (subreg:SI (match_dup 1) 0)
6848 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
6851 (set (subreg:SI (match_dup 0) 0)
6852 (ior:SI (subreg:SI (match_dup 0) 0)
6855 (set (subreg:SI (match_dup 0) 4)
6856 (ashift:SI (subreg:SI (match_dup 1) 4)
6860 int amount = INTVAL (operands[2]);
6861 operands[2] = GEN_INT (amount & 31);
6862 operands[4] = GEN_INT ((-amount) & 31);
6866 (define_insn "ashldi3_internal4"
6867 [(set (match_operand:DI 0 "register_operand" "=d")
6868 (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
6869 (match_operand:SI 2 "arith_operand" "dI")))]
6870 "TARGET_64BIT && !TARGET_MIPS16"
6873 if (GET_CODE (operands[2]) == CONST_INT)
6874 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6876 return \"dsll\\t%0,%1,%2\";
6878 [(set_attr "type" "arith")
6879 (set_attr "mode" "DI")])
6882 [(set (match_operand:DI 0 "register_operand" "=d,d")
6883 (ashift:DI (match_operand:DI 1 "se_register_operand" "0,d")
6884 (match_operand:SI 2 "arith_operand" "d,I")))]
6885 "TARGET_64BIT && TARGET_MIPS16"
6888 if (which_alternative == 0)
6889 return \"dsll\\t%0,%2\";
6891 if (GET_CODE (operands[2]) == CONST_INT)
6892 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6894 return \"dsll\\t%0,%1,%2\";
6896 [(set_attr "type" "arith")
6897 (set_attr "mode" "DI")
6898 (set_attr_alternative "length"
6900 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6905 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6908 [(set (match_operand:DI 0 "register_operand" "")
6909 (ashift:DI (match_operand:DI 1 "register_operand" "")
6910 (match_operand:SI 2 "const_int_operand" "")))]
6911 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
6913 && GET_CODE (operands[2]) == CONST_INT
6914 && INTVAL (operands[2]) > 8
6915 && INTVAL (operands[2]) <= 16"
6916 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
6917 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
6920 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6923 (define_expand "ashrsi3"
6924 [(set (match_operand:SI 0 "register_operand" "=d")
6925 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6926 (match_operand:SI 2 "arith_operand" "dI")))]
6930 /* On the mips16, a shift of more than 8 is a four byte instruction,
6931 so, for a shift between 8 and 16, it is just as fast to do two
6932 shifts of 8 or less. If there is a lot of shifting going on, we
6933 may win in CSE. Otherwise combine will put the shifts back
6937 && GET_CODE (operands[2]) == CONST_INT
6938 && INTVAL (operands[2]) > 8
6939 && INTVAL (operands[2]) <= 16)
6941 rtx temp = gen_reg_rtx (SImode);
6943 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6944 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
6945 GEN_INT (INTVAL (operands[2]) - 8)));
6950 (define_insn "ashrsi3_internal1"
6951 [(set (match_operand:SI 0 "register_operand" "=d")
6952 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6953 (match_operand:SI 2 "arith_operand" "dI")))]
6957 if (GET_CODE (operands[2]) == CONST_INT)
6958 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6960 return \"sra\\t%0,%1,%2\";
6962 [(set_attr "type" "arith")
6963 (set_attr "mode" "SI")])
6965 (define_insn "ashrsi3_internal2"
6966 [(set (match_operand:SI 0 "register_operand" "=d,d")
6967 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6968 (match_operand:SI 2 "arith_operand" "d,I")))]
6972 if (which_alternative == 0)
6973 return \"sra\\t%0,%2\";
6975 if (GET_CODE (operands[2]) == CONST_INT)
6976 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6978 return \"sra\\t%0,%1,%2\";
6980 [(set_attr "type" "arith")
6981 (set_attr "mode" "SI")
6982 (set_attr_alternative "length"
6984 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6989 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6992 [(set (match_operand:SI 0 "register_operand" "")
6993 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6994 (match_operand:SI 2 "const_int_operand" "")))]
6995 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6996 && GET_CODE (operands[2]) == CONST_INT
6997 && INTVAL (operands[2]) > 8
6998 && INTVAL (operands[2]) <= 16"
6999 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
7000 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
7003 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7006 (define_expand "ashrdi3"
7007 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7008 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7009 (match_operand:SI 2 "arith_operand" "")))
7010 (clobber (match_dup 3))])]
7011 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7016 /* On the mips16, a shift of more than 8 is a four byte
7017 instruction, so, for a shift between 8 and 16, it is just as
7018 fast to do two shifts of 8 or less. If there is a lot of
7019 shifting going on, we may win in CSE. Otherwise combine will
7020 put the shifts back together again. */
7023 && GET_CODE (operands[2]) == CONST_INT
7024 && INTVAL (operands[2]) > 8
7025 && INTVAL (operands[2]) <= 16)
7027 rtx temp = gen_reg_rtx (DImode);
7029 emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7030 emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
7031 GEN_INT (INTVAL (operands[2]) - 8)));
7035 emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
7040 operands[3] = gen_reg_rtx (SImode);
7044 (define_insn "ashrdi3_internal"
7045 [(set (match_operand:DI 0 "register_operand" "=&d")
7046 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7047 (match_operand:SI 2 "register_operand" "d")))
7048 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7049 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7052 operands[4] = const0_rtx;
7053 dslots_jump_total += 3;
7054 dslots_jump_filled += 2;
7056 return \"sll\\t%3,%2,26\\n\\
7057 \\tbgez\\t%3,1f\\n\\
7058 \\tsra\\t%L0,%M1,%2\\n\\
7060 \\tsra\\t%M0,%M1,31%)\\n\\
7063 \\t%(beq\\t%3,%z4,2f\\n\\
7064 \\tsrl\\t%L0,%L1,%2%)\\n\\
7066 \\tsubu\\t%3,%z4,%2\\n\\
7067 \\tsll\\t%3,%M1,%3\\n\\
7068 \\tor\\t%L0,%L0,%3\\n\\
7070 \\tsra\\t%M0,%M1,%2\\n\\
7073 [(set_attr "type" "darith")
7074 (set_attr "mode" "DI")
7075 (set_attr "length" "48")])
7078 (define_insn "ashrdi3_internal2"
7079 [(set (match_operand:DI 0 "register_operand" "=d")
7080 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7081 (match_operand:SI 2 "small_int" "IJK")))
7082 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7083 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
7086 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7087 return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
7089 [(set_attr "type" "darith")
7090 (set_attr "mode" "DI")
7091 (set_attr "length" "8")])
7095 [(set (match_operand:DI 0 "register_operand" "")
7096 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7097 (match_operand:SI 2 "small_int" "")))
7098 (clobber (match_operand:SI 3 "register_operand" ""))]
7099 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7100 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7101 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7102 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7103 && (INTVAL (operands[2]) & 32) != 0"
7105 [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7106 (set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (const_int 31)))]
7108 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7112 [(set (match_operand:DI 0 "register_operand" "")
7113 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7114 (match_operand:SI 2 "small_int" "")))
7115 (clobber (match_operand:SI 3 "register_operand" ""))]
7116 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7117 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7118 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7119 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7120 && (INTVAL (operands[2]) & 32) != 0"
7122 [(set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7123 (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
7125 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7128 (define_insn "ashrdi3_internal3"
7129 [(set (match_operand:DI 0 "register_operand" "=d")
7130 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7131 (match_operand:SI 2 "small_int" "IJK")))
7132 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7133 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7134 && (INTVAL (operands[2]) & 63) < 32
7135 && (INTVAL (operands[2]) & 63) != 0"
7138 int amount = INTVAL (operands[2]);
7140 operands[2] = GEN_INT (amount & 31);
7141 operands[4] = GEN_INT ((-amount) & 31);
7143 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
7145 [(set_attr "type" "darith")
7146 (set_attr "mode" "DI")
7147 (set_attr "length" "16")])
7151 [(set (match_operand:DI 0 "register_operand" "")
7152 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7153 (match_operand:SI 2 "small_int" "")))
7154 (clobber (match_operand:SI 3 "register_operand" ""))]
7155 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7156 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7157 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7158 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7159 && (INTVAL (operands[2]) & 63) < 32
7160 && (INTVAL (operands[2]) & 63) != 0"
7162 [(set (subreg:SI (match_dup 0) 0)
7163 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7167 (ashift:SI (subreg:SI (match_dup 1) 4)
7170 (set (subreg:SI (match_dup 0) 0)
7171 (ior:SI (subreg:SI (match_dup 0) 0)
7174 (set (subreg:SI (match_dup 0) 4)
7175 (ashiftrt:SI (subreg:SI (match_dup 1) 4)
7179 int amount = INTVAL (operands[2]);
7180 operands[2] = GEN_INT (amount & 31);
7181 operands[4] = GEN_INT ((-amount) & 31);
7186 [(set (match_operand:DI 0 "register_operand" "")
7187 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7188 (match_operand:SI 2 "small_int" "")))
7189 (clobber (match_operand:SI 3 "register_operand" ""))]
7190 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7191 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7192 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7193 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7194 && (INTVAL (operands[2]) & 63) < 32
7195 && (INTVAL (operands[2]) & 63) != 0"
7197 [(set (subreg:SI (match_dup 0) 4)
7198 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7202 (ashift:SI (subreg:SI (match_dup 1) 0)
7205 (set (subreg:SI (match_dup 0) 4)
7206 (ior:SI (subreg:SI (match_dup 0) 4)
7209 (set (subreg:SI (match_dup 0) 0)
7210 (ashiftrt:SI (subreg:SI (match_dup 1) 0)
7214 int amount = INTVAL (operands[2]);
7215 operands[2] = GEN_INT (amount & 31);
7216 operands[4] = GEN_INT ((-amount) & 31);
7220 (define_insn "ashrdi3_internal4"
7221 [(set (match_operand:DI 0 "register_operand" "=d")
7222 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7223 (match_operand:SI 2 "arith_operand" "dI")))]
7224 "TARGET_64BIT && !TARGET_MIPS16"
7227 if (GET_CODE (operands[2]) == CONST_INT)
7228 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7230 return \"dsra\\t%0,%1,%2\";
7232 [(set_attr "type" "arith")
7233 (set_attr "mode" "DI")])
7236 [(set (match_operand:DI 0 "register_operand" "=d,d")
7237 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7238 (match_operand:SI 2 "arith_operand" "d,I")))]
7239 "TARGET_64BIT && TARGET_MIPS16"
7242 if (GET_CODE (operands[2]) == CONST_INT)
7243 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7245 return \"dsra\\t%0,%2\";
7247 [(set_attr "type" "arith")
7248 (set_attr "mode" "DI")
7249 (set_attr_alternative "length"
7251 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7255 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7258 [(set (match_operand:DI 0 "register_operand" "")
7259 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7260 (match_operand:SI 2 "const_int_operand" "")))]
7261 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
7263 && GET_CODE (operands[2]) == CONST_INT
7264 && INTVAL (operands[2]) > 8
7265 && INTVAL (operands[2]) <= 16"
7266 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
7267 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
7270 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7273 (define_expand "lshrsi3"
7274 [(set (match_operand:SI 0 "register_operand" "=d")
7275 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7276 (match_operand:SI 2 "arith_operand" "dI")))]
7280 /* On the mips16, a shift of more than 8 is a four byte instruction,
7281 so, for a shift between 8 and 16, it is just as fast to do two
7282 shifts of 8 or less. If there is a lot of shifting going on, we
7283 may win in CSE. Otherwise combine will put the shifts back
7287 && GET_CODE (operands[2]) == CONST_INT
7288 && INTVAL (operands[2]) > 8
7289 && INTVAL (operands[2]) <= 16)
7291 rtx temp = gen_reg_rtx (SImode);
7293 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
7294 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
7295 GEN_INT (INTVAL (operands[2]) - 8)));
7300 (define_insn "lshrsi3_internal1"
7301 [(set (match_operand:SI 0 "register_operand" "=d")
7302 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7303 (match_operand:SI 2 "arith_operand" "dI")))]
7307 if (GET_CODE (operands[2]) == CONST_INT)
7308 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7310 return \"srl\\t%0,%1,%2\";
7312 [(set_attr "type" "arith")
7313 (set_attr "mode" "SI")])
7315 (define_insn "lshrsi3_internal2"
7316 [(set (match_operand:SI 0 "register_operand" "=d,d")
7317 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
7318 (match_operand:SI 2 "arith_operand" "d,I")))]
7322 if (which_alternative == 0)
7323 return \"srl\\t%0,%2\";
7325 if (GET_CODE (operands[2]) == CONST_INT)
7326 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7328 return \"srl\\t%0,%1,%2\";
7330 [(set_attr "type" "arith")
7331 (set_attr "mode" "SI")
7332 (set_attr_alternative "length"
7334 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7339 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7342 [(set (match_operand:SI 0 "register_operand" "")
7343 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
7344 (match_operand:SI 2 "const_int_operand" "")))]
7345 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7346 && GET_CODE (operands[2]) == CONST_INT
7347 && INTVAL (operands[2]) > 8
7348 && INTVAL (operands[2]) <= 16"
7349 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
7350 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7353 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7356 ;; If we load a byte on the mips16 as a bitfield, the resulting
7357 ;; sequence of instructions is too complicated for combine, because it
7358 ;; involves four instructions: a load, a shift, a constant load into a
7359 ;; register, and an and (the key problem here is that the mips16 does
7360 ;; not have and immediate). We recognize a shift of a load in order
7361 ;; to make it simple enough for combine to understand.
7364 [(set (match_operand:SI 0 "register_operand" "=d,d")
7365 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "R,m")
7366 (match_operand:SI 2 "immediate_operand" "I,I")))]
7368 "lw\\t%0,%1\;srl\\t%0,%2"
7369 [(set_attr "type" "load")
7370 (set_attr "mode" "SI")
7371 (set_attr_alternative "length"
7372 [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7375 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7380 [(set (match_operand:SI 0 "register_operand" "")
7381 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "")
7382 (match_operand:SI 2 "immediate_operand" "")))]
7383 "TARGET_MIPS16 && !TARGET_DEBUG_D_MODE"
7384 [(set (match_dup 0) (match_dup 1))
7385 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7388 (define_expand "lshrdi3"
7389 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7390 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7391 (match_operand:SI 2 "arith_operand" "")))
7392 (clobber (match_dup 3))])]
7393 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7398 /* On the mips16, a shift of more than 8 is a four byte
7399 instruction, so, for a shift between 8 and 16, it is just as
7400 fast to do two shifts of 8 or less. If there is a lot of
7401 shifting going on, we may win in CSE. Otherwise combine will
7402 put the shifts back together again. */
7405 && GET_CODE (operands[2]) == CONST_INT
7406 && INTVAL (operands[2]) > 8
7407 && INTVAL (operands[2]) <= 16)
7409 rtx temp = gen_reg_rtx (DImode);
7411 emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7412 emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
7413 GEN_INT (INTVAL (operands[2]) - 8)));
7417 emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
7422 operands[3] = gen_reg_rtx (SImode);
7426 (define_insn "lshrdi3_internal"
7427 [(set (match_operand:DI 0 "register_operand" "=&d")
7428 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7429 (match_operand:SI 2 "register_operand" "d")))
7430 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7431 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7434 operands[4] = const0_rtx;
7435 dslots_jump_total += 3;
7436 dslots_jump_filled += 2;
7438 return \"sll\\t%3,%2,26\\n\\
7439 \\tbgez\\t%3,1f\\n\\
7440 \\tsrl\\t%L0,%M1,%2\\n\\
7442 \\tmove\\t%M0,%z4%)\\n\\
7445 \\t%(beq\\t%3,%z4,2f\\n\\
7446 \\tsrl\\t%L0,%L1,%2%)\\n\\
7448 \\tsubu\\t%3,%z4,%2\\n\\
7449 \\tsll\\t%3,%M1,%3\\n\\
7450 \\tor\\t%L0,%L0,%3\\n\\
7452 \\tsrl\\t%M0,%M1,%2\\n\\
7455 [(set_attr "type" "darith")
7456 (set_attr "mode" "DI")
7457 (set_attr "length" "48")])
7460 (define_insn "lshrdi3_internal2"
7461 [(set (match_operand:DI 0 "register_operand" "=d")
7462 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7463 (match_operand:SI 2 "small_int" "IJK")))
7464 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7465 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7466 && (INTVAL (operands[2]) & 32) != 0"
7469 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7470 operands[4] = const0_rtx;
7471 return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
7473 [(set_attr "type" "darith")
7474 (set_attr "mode" "DI")
7475 (set_attr "length" "8")])
7479 [(set (match_operand:DI 0 "register_operand" "")
7480 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7481 (match_operand:SI 2 "small_int" "")))
7482 (clobber (match_operand:SI 3 "register_operand" ""))]
7483 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7484 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7485 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7486 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7487 && (INTVAL (operands[2]) & 32) != 0"
7489 [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7490 (set (subreg:SI (match_dup 0) 4) (const_int 0))]
7492 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7496 [(set (match_operand:DI 0 "register_operand" "")
7497 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7498 (match_operand:SI 2 "small_int" "")))
7499 (clobber (match_operand:SI 3 "register_operand" ""))]
7500 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7501 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7502 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7503 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7504 && (INTVAL (operands[2]) & 32) != 0"
7506 [(set (subreg:SI (match_dup 0) 4) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7507 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
7509 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7512 (define_insn "lshrdi3_internal3"
7513 [(set (match_operand:DI 0 "register_operand" "=d")
7514 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7515 (match_operand:SI 2 "small_int" "IJK")))
7516 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7517 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7518 && (INTVAL (operands[2]) & 63) < 32
7519 && (INTVAL (operands[2]) & 63) != 0"
7522 int amount = INTVAL (operands[2]);
7524 operands[2] = GEN_INT (amount & 31);
7525 operands[4] = GEN_INT ((-amount) & 31);
7527 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
7529 [(set_attr "type" "darith")
7530 (set_attr "mode" "DI")
7531 (set_attr "length" "16")])
7535 [(set (match_operand:DI 0 "register_operand" "")
7536 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7537 (match_operand:SI 2 "small_int" "")))
7538 (clobber (match_operand:SI 3 "register_operand" ""))]
7539 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7540 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7541 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7542 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7543 && (INTVAL (operands[2]) & 63) < 32
7544 && (INTVAL (operands[2]) & 63) != 0"
7546 [(set (subreg:SI (match_dup 0) 0)
7547 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7551 (ashift:SI (subreg:SI (match_dup 1) 4)
7554 (set (subreg:SI (match_dup 0) 0)
7555 (ior:SI (subreg:SI (match_dup 0) 0)
7558 (set (subreg:SI (match_dup 0) 4)
7559 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7563 int amount = INTVAL (operands[2]);
7564 operands[2] = GEN_INT (amount & 31);
7565 operands[4] = GEN_INT ((-amount) & 31);
7570 [(set (match_operand:DI 0 "register_operand" "")
7571 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7572 (match_operand:SI 2 "small_int" "")))
7573 (clobber (match_operand:SI 3 "register_operand" ""))]
7574 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7575 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7576 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7577 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7578 && (INTVAL (operands[2]) & 63) < 32
7579 && (INTVAL (operands[2]) & 63) != 0"
7581 [(set (subreg:SI (match_dup 0) 4)
7582 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7586 (ashift:SI (subreg:SI (match_dup 1) 0)
7589 (set (subreg:SI (match_dup 0) 4)
7590 (ior:SI (subreg:SI (match_dup 0) 4)
7593 (set (subreg:SI (match_dup 0) 0)
7594 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7598 int amount = INTVAL (operands[2]);
7599 operands[2] = GEN_INT (amount & 31);
7600 operands[4] = GEN_INT ((-amount) & 31);
7604 (define_insn "lshrdi3_internal4"
7605 [(set (match_operand:DI 0 "register_operand" "=d")
7606 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7607 (match_operand:SI 2 "arith_operand" "dI")))]
7608 "TARGET_64BIT && !TARGET_MIPS16"
7611 if (GET_CODE (operands[2]) == CONST_INT)
7612 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7614 return \"dsrl\\t%0,%1,%2\";
7616 [(set_attr "type" "arith")
7617 (set_attr "mode" "DI")])
7620 [(set (match_operand:DI 0 "register_operand" "=d,d")
7621 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7622 (match_operand:SI 2 "arith_operand" "d,I")))]
7623 "TARGET_64BIT && TARGET_MIPS16"
7626 if (GET_CODE (operands[2]) == CONST_INT)
7627 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7629 return \"dsrl\\t%0,%2\";
7631 [(set_attr "type" "arith")
7632 (set_attr "mode" "DI")
7633 (set_attr_alternative "length"
7635 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7639 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7642 [(set (match_operand:DI 0 "register_operand" "")
7643 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7644 (match_operand:SI 2 "const_int_operand" "")))]
7645 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7646 && GET_CODE (operands[2]) == CONST_INT
7647 && INTVAL (operands[2]) > 8
7648 && INTVAL (operands[2]) <= 16"
7649 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
7650 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
7653 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7658 ;; ....................
7662 ;; ....................
7664 ;; Flow here is rather complex:
7666 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
7667 ;; arguments into the branch_cmp array, and the type into
7668 ;; branch_type. No RTL is generated.
7670 ;; 2) The appropriate branch define_expand is called, which then
7671 ;; creates the appropriate RTL for the comparison and branch.
7672 ;; Different CC modes are used, based on what type of branch is
7673 ;; done, so that we can constrain things appropriately. There
7674 ;; are assumptions in the rest of GCC that break if we fold the
7675 ;; operands into the branchs for integer operations, and use cc0
7676 ;; for floating point, so we use the fp status register instead.
7677 ;; If needed, an appropriate temporary is created to hold the
7678 ;; of the integer compare.
7680 (define_expand "cmpsi"
7682 (compare:CC (match_operand:SI 0 "register_operand" "")
7683 (match_operand:SI 1 "arith_operand" "")))]
7687 if (operands[0]) /* avoid unused code message */
7689 branch_cmp[0] = operands[0];
7690 branch_cmp[1] = operands[1];
7691 branch_type = CMP_SI;
7696 (define_expand "tstsi"
7698 (match_operand:SI 0 "register_operand" ""))]
7702 if (operands[0]) /* avoid unused code message */
7704 branch_cmp[0] = operands[0];
7705 branch_cmp[1] = const0_rtx;
7706 branch_type = CMP_SI;
7711 (define_expand "cmpdi"
7713 (compare:CC (match_operand:DI 0 "se_register_operand" "")
7714 (match_operand:DI 1 "se_arith_operand" "")))]
7718 if (operands[0]) /* avoid unused code message */
7720 branch_cmp[0] = operands[0];
7721 branch_cmp[1] = operands[1];
7722 branch_type = CMP_DI;
7727 (define_expand "tstdi"
7729 (match_operand:DI 0 "se_register_operand" ""))]
7733 if (operands[0]) /* avoid unused code message */
7735 branch_cmp[0] = operands[0];
7736 branch_cmp[1] = const0_rtx;
7737 branch_type = CMP_DI;
7742 (define_expand "cmpdf"
7744 (compare:CC (match_operand:DF 0 "register_operand" "")
7745 (match_operand:DF 1 "register_operand" "")))]
7746 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7749 if (operands[0]) /* avoid unused code message */
7751 branch_cmp[0] = operands[0];
7752 branch_cmp[1] = operands[1];
7753 branch_type = CMP_DF;
7758 (define_expand "cmpsf"
7760 (compare:CC (match_operand:SF 0 "register_operand" "")
7761 (match_operand:SF 1 "register_operand" "")))]
7765 if (operands[0]) /* avoid unused code message */
7767 branch_cmp[0] = operands[0];
7768 branch_cmp[1] = operands[1];
7769 branch_type = CMP_SF;
7776 ;; ....................
7778 ;; CONDITIONAL BRANCHES
7780 ;; ....................
7782 ;; Conditional branches on floating-point equality tests.
7784 (define_insn "branch_fp"
7787 (match_operator:CC 0 "cmp_op"
7788 [(match_operand:CC 2 "register_operand" "z")
7790 (label_ref (match_operand 1 "" ""))
7795 return mips_output_conditional_branch (insn,
7797 /*two_operands_p=*/0,
7800 get_attr_length (insn));
7802 [(set_attr "type" "branch")
7803 (set_attr "mode" "none")])
7805 (define_insn "branch_fp_inverted"
7808 (match_operator:CC 0 "cmp_op"
7809 [(match_operand:CC 2 "register_operand" "z")
7812 (label_ref (match_operand 1 "" ""))))]
7816 return mips_output_conditional_branch (insn,
7818 /*two_operands_p=*/0,
7821 get_attr_length (insn));
7823 [(set_attr "type" "branch")
7824 (set_attr "mode" "none")])
7826 ;; Conditional branches on comparisons with zero.
7828 (define_insn "branch_zero"
7831 (match_operator:SI 0 "cmp_op"
7832 [(match_operand:SI 2 "register_operand" "d")
7834 (label_ref (match_operand 1 "" ""))
7839 return mips_output_conditional_branch (insn,
7841 /*two_operands_p=*/0,
7844 get_attr_length (insn));
7846 [(set_attr "type" "branch")
7847 (set_attr "mode" "none")])
7849 (define_insn "branch_zero_inverted"
7852 (match_operator:SI 0 "cmp_op"
7853 [(match_operand:SI 2 "register_operand" "d")
7856 (label_ref (match_operand 1 "" ""))))]
7860 return mips_output_conditional_branch (insn,
7862 /*two_operands_p=*/0,
7865 get_attr_length (insn));
7867 [(set_attr "type" "branch")
7868 (set_attr "mode" "none")])
7870 (define_insn "branch_zero_di"
7873 (match_operator:DI 0 "cmp_op"
7874 [(match_operand:DI 2 "se_register_operand" "d")
7876 (label_ref (match_operand 1 "" ""))
7881 return mips_output_conditional_branch (insn,
7883 /*two_operands_p=*/0,
7886 get_attr_length (insn));
7888 [(set_attr "type" "branch")
7889 (set_attr "mode" "none")])
7891 (define_insn "branch_zero_di_inverted"
7894 (match_operator:DI 0 "cmp_op"
7895 [(match_operand:DI 2 "se_register_operand" "d")
7898 (label_ref (match_operand 1 "" ""))))]
7902 return mips_output_conditional_branch (insn,
7904 /*two_operands_p=*/0,
7907 get_attr_length (insn));
7909 [(set_attr "type" "branch")
7910 (set_attr "mode" "none")])
7912 ;; Conditional branch on equality comparision.
7914 (define_insn "branch_equality"
7917 (match_operator:SI 0 "equality_op"
7918 [(match_operand:SI 2 "register_operand" "d")
7919 (match_operand:SI 3 "register_operand" "d")])
7920 (label_ref (match_operand 1 "" ""))
7925 return mips_output_conditional_branch (insn,
7927 /*two_operands_p=*/1,
7930 get_attr_length (insn));
7932 [(set_attr "type" "branch")
7933 (set_attr "mode" "none")])
7935 (define_insn "branch_equality_di"
7938 (match_operator:DI 0 "equality_op"
7939 [(match_operand:DI 2 "se_register_operand" "d")
7940 (match_operand:DI 3 "se_register_operand" "d")])
7941 (label_ref (match_operand 1 "" ""))
7946 return mips_output_conditional_branch (insn,
7948 /*two_operands_p=*/1,
7951 get_attr_length (insn));
7953 [(set_attr "type" "branch")
7954 (set_attr "mode" "none")])
7956 (define_insn "branch_equality_inverted"
7959 (match_operator:SI 0 "equality_op"
7960 [(match_operand:SI 2 "register_operand" "d")
7961 (match_operand:SI 3 "register_operand" "d")])
7963 (label_ref (match_operand 1 "" ""))))]
7967 return mips_output_conditional_branch (insn,
7969 /*two_operands_p=*/1,
7972 get_attr_length (insn));
7974 [(set_attr "type" "branch")
7975 (set_attr "mode" "none")])
7977 (define_insn "branch_equality_di_inverted"
7980 (match_operator:DI 0 "equality_op"
7981 [(match_operand:DI 2 "se_register_operand" "d")
7982 (match_operand:DI 3 "se_register_operand" "d")])
7984 (label_ref (match_operand 1 "" ""))))]
7988 return mips_output_conditional_branch (insn,
7990 /*two_operands_p=*/1,
7993 get_attr_length (insn));
7995 [(set_attr "type" "branch")
7996 (set_attr "mode" "none")])
8002 (if_then_else (match_operator:SI 0 "equality_op"
8003 [(match_operand:SI 1 "register_operand" "d,t")
8005 (match_operand 2 "pc_or_label_operand" "")
8006 (match_operand 3 "pc_or_label_operand" "")))]
8010 if (operands[2] != pc_rtx)
8012 if (which_alternative == 0)
8013 return \"%*b%C0z\\t%1,%2\";
8015 return \"%*bt%C0z\\t%2\";
8019 if (which_alternative == 0)
8020 return \"%*b%N0z\\t%1,%3\";
8022 return \"%*bt%N0z\\t%3\";
8025 [(set_attr "type" "branch")
8026 (set_attr "mode" "none")
8027 (set_attr "length" "8")])
8031 (if_then_else (match_operator:DI 0 "equality_op"
8032 [(match_operand:DI 1 "se_register_operand" "d,t")
8034 (match_operand 2 "pc_or_label_operand" "")
8035 (match_operand 3 "pc_or_label_operand" "")))]
8039 if (operands[2] != pc_rtx)
8041 if (which_alternative == 0)
8042 return \"%*b%C0z\\t%1,%2\";
8044 return \"%*bt%C0z\\t%2\";
8048 if (which_alternative == 0)
8049 return \"%*b%N0z\\t%1,%3\";
8051 return \"%*bt%N0z\\t%3\";
8054 [(set_attr "type" "branch")
8055 (set_attr "mode" "none")
8056 (set_attr "length" "8")])
8058 (define_expand "beq"
8060 (if_then_else (eq:CC (cc0)
8062 (label_ref (match_operand 0 "" ""))
8067 if (operands[0]) /* avoid unused code warning */
8069 gen_conditional_branch (operands, EQ);
8074 (define_expand "bne"
8076 (if_then_else (ne:CC (cc0)
8078 (label_ref (match_operand 0 "" ""))
8083 if (operands[0]) /* avoid unused code warning */
8085 gen_conditional_branch (operands, NE);
8090 (define_expand "bgt"
8092 (if_then_else (gt:CC (cc0)
8094 (label_ref (match_operand 0 "" ""))
8099 if (operands[0]) /* avoid unused code warning */
8101 gen_conditional_branch (operands, GT);
8106 (define_expand "bge"
8108 (if_then_else (ge:CC (cc0)
8110 (label_ref (match_operand 0 "" ""))
8115 if (operands[0]) /* avoid unused code warning */
8117 gen_conditional_branch (operands, GE);
8122 (define_expand "blt"
8124 (if_then_else (lt:CC (cc0)
8126 (label_ref (match_operand 0 "" ""))
8131 if (operands[0]) /* avoid unused code warning */
8133 gen_conditional_branch (operands, LT);
8138 (define_expand "ble"
8140 (if_then_else (le:CC (cc0)
8142 (label_ref (match_operand 0 "" ""))
8147 if (operands[0]) /* avoid unused code warning */
8149 gen_conditional_branch (operands, LE);
8154 (define_expand "bgtu"
8156 (if_then_else (gtu:CC (cc0)
8158 (label_ref (match_operand 0 "" ""))
8163 if (operands[0]) /* avoid unused code warning */
8165 gen_conditional_branch (operands, GTU);
8170 (define_expand "bgeu"
8172 (if_then_else (geu:CC (cc0)
8174 (label_ref (match_operand 0 "" ""))
8179 if (operands[0]) /* avoid unused code warning */
8181 gen_conditional_branch (operands, GEU);
8187 (define_expand "bltu"
8189 (if_then_else (ltu:CC (cc0)
8191 (label_ref (match_operand 0 "" ""))
8196 if (operands[0]) /* avoid unused code warning */
8198 gen_conditional_branch (operands, LTU);
8203 (define_expand "bleu"
8205 (if_then_else (leu:CC (cc0)
8207 (label_ref (match_operand 0 "" ""))
8212 if (operands[0]) /* avoid unused code warning */
8214 gen_conditional_branch (operands, LEU);
8221 ;; ....................
8223 ;; SETTING A REGISTER FROM A COMPARISON
8225 ;; ....................
8227 (define_expand "seq"
8228 [(set (match_operand:SI 0 "register_operand" "=d")
8229 (eq:SI (match_dup 1)
8234 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8237 /* set up operands from compare. */
8238 operands[1] = branch_cmp[0];
8239 operands[2] = branch_cmp[1];
8241 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8243 gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
8247 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8248 operands[2] = force_reg (SImode, operands[2]);
8250 /* fall through and generate default code */
8254 (define_insn "seq_si_zero"
8255 [(set (match_operand:SI 0 "register_operand" "=d")
8256 (eq:SI (match_operand:SI 1 "register_operand" "d")
8260 [(set_attr "type" "arith")
8261 (set_attr "mode" "SI")])
8264 [(set (match_operand:SI 0 "register_operand" "=t")
8265 (eq:SI (match_operand:SI 1 "register_operand" "d")
8269 [(set_attr "type" "arith")
8270 (set_attr "mode" "SI")])
8272 (define_insn "seq_di_zero"
8273 [(set (match_operand:DI 0 "register_operand" "=d")
8274 (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8276 "TARGET_64BIT && !TARGET_MIPS16"
8278 [(set_attr "type" "arith")
8279 (set_attr "mode" "DI")])
8282 [(set (match_operand:DI 0 "register_operand" "=t")
8283 (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8285 "TARGET_64BIT && TARGET_MIPS16"
8287 [(set_attr "type" "arith")
8288 (set_attr "mode" "DI")])
8290 (define_insn "seq_si"
8291 [(set (match_operand:SI 0 "register_operand" "=d,d")
8292 (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
8293 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8294 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8296 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8297 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8298 [(set_attr "type" "arith")
8299 (set_attr "mode" "SI")
8300 (set_attr "length" "8")])
8303 [(set (match_operand:SI 0 "register_operand" "")
8304 (eq:SI (match_operand:SI 1 "register_operand" "")
8305 (match_operand:SI 2 "uns_arith_operand" "")))]
8306 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8307 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8309 (xor:SI (match_dup 1)
8312 (ltu:SI (match_dup 0)
8316 (define_insn "seq_di"
8317 [(set (match_operand:DI 0 "register_operand" "=d,d")
8318 (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8319 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8320 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8322 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8323 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8324 [(set_attr "type" "arith")
8325 (set_attr "mode" "DI")
8326 (set_attr "length" "8")])
8329 [(set (match_operand:DI 0 "register_operand" "")
8330 (eq:DI (match_operand:DI 1 "se_register_operand" "")
8331 (match_operand:DI 2 "se_uns_arith_operand" "")))]
8332 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8334 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8336 (xor:DI (match_dup 1)
8339 (ltu:DI (match_dup 0)
8343 ;; On the mips16 the default code is better than using sltu.
8345 (define_expand "sne"
8346 [(set (match_operand:SI 0 "register_operand" "=d")
8347 (ne:SI (match_dup 1)
8352 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8355 /* set up operands from compare. */
8356 operands[1] = branch_cmp[0];
8357 operands[2] = branch_cmp[1];
8359 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
8361 gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
8365 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8366 operands[2] = force_reg (SImode, operands[2]);
8368 /* fall through and generate default code */
8371 (define_insn "sne_si_zero"
8372 [(set (match_operand:SI 0 "register_operand" "=d")
8373 (ne:SI (match_operand:SI 1 "register_operand" "d")
8377 [(set_attr "type" "arith")
8378 (set_attr "mode" "SI")])
8380 (define_insn "sne_di_zero"
8381 [(set (match_operand:DI 0 "register_operand" "=d")
8382 (ne:DI (match_operand:DI 1 "se_register_operand" "d")
8384 "TARGET_64BIT && !TARGET_MIPS16"
8386 [(set_attr "type" "arith")
8387 (set_attr "mode" "DI")])
8389 (define_insn "sne_si"
8390 [(set (match_operand:SI 0 "register_operand" "=d,d")
8391 (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
8392 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8393 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8395 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8396 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8397 [(set_attr "type" "arith")
8398 (set_attr "mode" "SI")
8399 (set_attr "length" "8")])
8402 [(set (match_operand:SI 0 "register_operand" "")
8403 (ne:SI (match_operand:SI 1 "register_operand" "")
8404 (match_operand:SI 2 "uns_arith_operand" "")))]
8405 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8406 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8408 (xor:SI (match_dup 1)
8411 (gtu:SI (match_dup 0)
8415 (define_insn "sne_di"
8416 [(set (match_operand:DI 0 "register_operand" "=d,d")
8417 (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8418 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8419 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8421 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8422 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8423 [(set_attr "type" "arith")
8424 (set_attr "mode" "DI")
8425 (set_attr "length" "8")])
8428 [(set (match_operand:DI 0 "register_operand" "")
8429 (ne:DI (match_operand:DI 1 "se_register_operand" "")
8430 (match_operand:DI 2 "se_uns_arith_operand" "")))]
8431 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8433 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8435 (xor:DI (match_dup 1)
8438 (gtu:DI (match_dup 0)
8442 (define_expand "sgt"
8443 [(set (match_operand:SI 0 "register_operand" "=d")
8444 (gt:SI (match_dup 1)
8449 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8452 /* set up operands from compare. */
8453 operands[1] = branch_cmp[0];
8454 operands[2] = branch_cmp[1];
8456 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8458 gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
8462 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8463 operands[2] = force_reg (SImode, operands[2]);
8465 /* fall through and generate default code */
8468 (define_insn "sgt_si"
8469 [(set (match_operand:SI 0 "register_operand" "=d")
8470 (gt:SI (match_operand:SI 1 "register_operand" "d")
8471 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8474 [(set_attr "type" "arith")
8475 (set_attr "mode" "SI")])
8478 [(set (match_operand:SI 0 "register_operand" "=t")
8479 (gt:SI (match_operand:SI 1 "register_operand" "d")
8480 (match_operand:SI 2 "register_operand" "d")))]
8483 [(set_attr "type" "arith")
8484 (set_attr "mode" "SI")])
8486 (define_insn "sgt_di"
8487 [(set (match_operand:DI 0 "register_operand" "=d")
8488 (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8489 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8490 "TARGET_64BIT && !TARGET_MIPS16"
8492 [(set_attr "type" "arith")
8493 (set_attr "mode" "DI")])
8496 [(set (match_operand:DI 0 "register_operand" "=d")
8497 (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8498 (match_operand:DI 2 "se_register_operand" "d")))]
8499 "TARGET_64BIT && TARGET_MIPS16"
8501 [(set_attr "type" "arith")
8502 (set_attr "mode" "DI")])
8504 (define_expand "sge"
8505 [(set (match_operand:SI 0 "register_operand" "=d")
8506 (ge:SI (match_dup 1)
8511 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8514 /* set up operands from compare. */
8515 operands[1] = branch_cmp[0];
8516 operands[2] = branch_cmp[1];
8518 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8520 gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
8524 /* fall through and generate default code */
8527 (define_insn "sge_si"
8528 [(set (match_operand:SI 0 "register_operand" "=d")
8529 (ge:SI (match_operand:SI 1 "register_operand" "d")
8530 (match_operand:SI 2 "arith_operand" "dI")))]
8531 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8532 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8533 [(set_attr "type" "arith")
8534 (set_attr "mode" "SI")
8535 (set_attr "length" "8")])
8538 [(set (match_operand:SI 0 "register_operand" "")
8539 (ge:SI (match_operand:SI 1 "register_operand" "")
8540 (match_operand:SI 2 "arith_operand" "")))]
8541 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8543 (lt:SI (match_dup 1)
8546 (xor:SI (match_dup 0)
8550 (define_insn "sge_di"
8551 [(set (match_operand:DI 0 "register_operand" "=d")
8552 (ge:DI (match_operand:DI 1 "se_register_operand" "d")
8553 (match_operand:DI 2 "se_arith_operand" "dI")))]
8554 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8555 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8556 [(set_attr "type" "arith")
8557 (set_attr "mode" "DI")
8558 (set_attr "length" "8")])
8561 [(set (match_operand:DI 0 "register_operand" "")
8562 (ge:DI (match_operand:DI 1 "se_register_operand" "")
8563 (match_operand:DI 2 "se_arith_operand" "")))]
8564 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8567 (lt:DI (match_dup 1)
8570 (xor:DI (match_dup 0)
8574 (define_expand "slt"
8575 [(set (match_operand:SI 0 "register_operand" "=d")
8576 (lt:SI (match_dup 1)
8581 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8584 /* set up operands from compare. */
8585 operands[1] = branch_cmp[0];
8586 operands[2] = branch_cmp[1];
8588 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8590 gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
8594 /* fall through and generate default code */
8597 (define_insn "slt_si"
8598 [(set (match_operand:SI 0 "register_operand" "=d")
8599 (lt:SI (match_operand:SI 1 "register_operand" "d")
8600 (match_operand:SI 2 "arith_operand" "dI")))]
8603 [(set_attr "type" "arith")
8604 (set_attr "mode" "SI")])
8607 [(set (match_operand:SI 0 "register_operand" "=t,t")
8608 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
8609 (match_operand:SI 2 "arith_operand" "d,I")))]
8612 [(set_attr "type" "arith")
8613 (set_attr "mode" "SI")
8614 (set_attr_alternative "length"
8616 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8620 (define_insn "slt_di"
8621 [(set (match_operand:DI 0 "register_operand" "=d")
8622 (lt:DI (match_operand:DI 1 "se_register_operand" "d")
8623 (match_operand:DI 2 "se_arith_operand" "dI")))]
8624 "TARGET_64BIT && !TARGET_MIPS16"
8626 [(set_attr "type" "arith")
8627 (set_attr "mode" "DI")])
8630 [(set (match_operand:DI 0 "register_operand" "=t,t")
8631 (lt:DI (match_operand:DI 1 "se_register_operand" "d,d")
8632 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8633 "TARGET_64BIT && TARGET_MIPS16"
8635 [(set_attr "type" "arith")
8636 (set_attr "mode" "DI")
8637 (set_attr_alternative "length"
8639 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8643 (define_expand "sle"
8644 [(set (match_operand:SI 0 "register_operand" "=d")
8645 (le:SI (match_dup 1)
8650 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8653 /* set up operands from compare. */
8654 operands[1] = branch_cmp[0];
8655 operands[2] = branch_cmp[1];
8657 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8659 gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
8663 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8664 operands[2] = force_reg (SImode, operands[2]);
8666 /* fall through and generate default code */
8669 (define_insn "sle_si_const"
8670 [(set (match_operand:SI 0 "register_operand" "=d")
8671 (le:SI (match_operand:SI 1 "register_operand" "d")
8672 (match_operand:SI 2 "small_int" "I")))]
8673 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8676 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8677 return \"slt\\t%0,%1,%2\";
8679 [(set_attr "type" "arith")
8680 (set_attr "mode" "SI")])
8683 [(set (match_operand:SI 0 "register_operand" "=t")
8684 (le:SI (match_operand:SI 1 "register_operand" "d")
8685 (match_operand:SI 2 "small_int" "I")))]
8686 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8689 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8690 return \"slt\\t%1,%2\";
8692 [(set_attr "type" "arith")
8693 (set_attr "mode" "SI")
8694 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8698 (define_insn "sle_di_const"
8699 [(set (match_operand:DI 0 "register_operand" "=d")
8700 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8701 (match_operand:DI 2 "small_int" "I")))]
8702 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8705 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8706 return \"slt\\t%0,%1,%2\";
8708 [(set_attr "type" "arith")
8709 (set_attr "mode" "DI")])
8712 [(set (match_operand:DI 0 "register_operand" "=t")
8713 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8714 (match_operand:DI 2 "small_int" "I")))]
8715 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8718 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8719 return \"slt\\t%1,%2\";
8721 [(set_attr "type" "arith")
8722 (set_attr "mode" "DI")
8723 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8727 (define_insn "sle_si_reg"
8728 [(set (match_operand:SI 0 "register_operand" "=d")
8729 (le:SI (match_operand:SI 1 "register_operand" "d")
8730 (match_operand:SI 2 "register_operand" "d")))]
8731 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8732 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8733 [(set_attr "type" "arith")
8734 (set_attr "mode" "SI")
8735 (set_attr "length" "8")])
8738 [(set (match_operand:SI 0 "register_operand" "")
8739 (le:SI (match_operand:SI 1 "register_operand" "")
8740 (match_operand:SI 2 "register_operand" "")))]
8741 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8743 (lt:SI (match_dup 2)
8746 (xor:SI (match_dup 0)
8750 (define_insn "sle_di_reg"
8751 [(set (match_operand:DI 0 "register_operand" "=d")
8752 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8753 (match_operand:DI 2 "se_register_operand" "d")))]
8754 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8755 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8756 [(set_attr "type" "arith")
8757 (set_attr "mode" "DI")
8758 (set_attr "length" "8")])
8761 [(set (match_operand:DI 0 "register_operand" "")
8762 (le:DI (match_operand:DI 1 "se_register_operand" "")
8763 (match_operand:DI 2 "se_register_operand" "")))]
8764 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8767 (lt:DI (match_dup 2)
8770 (xor:DI (match_dup 0)
8774 (define_expand "sgtu"
8775 [(set (match_operand:SI 0 "register_operand" "=d")
8776 (gtu:SI (match_dup 1)
8781 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8784 /* set up operands from compare. */
8785 operands[1] = branch_cmp[0];
8786 operands[2] = branch_cmp[1];
8788 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8790 gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
8794 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8795 operands[2] = force_reg (SImode, operands[2]);
8797 /* fall through and generate default code */
8800 (define_insn "sgtu_si"
8801 [(set (match_operand:SI 0 "register_operand" "=d")
8802 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8803 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8806 [(set_attr "type" "arith")
8807 (set_attr "mode" "SI")])
8810 [(set (match_operand:SI 0 "register_operand" "=t")
8811 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8812 (match_operand:SI 2 "register_operand" "d")))]
8815 [(set_attr "type" "arith")
8816 (set_attr "mode" "SI")])
8818 (define_insn "sgtu_di"
8819 [(set (match_operand:DI 0 "register_operand" "=d")
8820 (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8821 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8824 [(set_attr "type" "arith")
8825 (set_attr "mode" "DI")])
8828 [(set (match_operand:DI 0 "register_operand" "=t")
8829 (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8830 (match_operand:DI 2 "se_register_operand" "d")))]
8833 [(set_attr "type" "arith")
8834 (set_attr "mode" "DI")])
8836 (define_expand "sgeu"
8837 [(set (match_operand:SI 0 "register_operand" "=d")
8838 (geu:SI (match_dup 1)
8843 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8846 /* set up operands from compare. */
8847 operands[1] = branch_cmp[0];
8848 operands[2] = branch_cmp[1];
8850 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8852 gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
8856 /* fall through and generate default code */
8859 (define_insn "sgeu_si"
8860 [(set (match_operand:SI 0 "register_operand" "=d")
8861 (geu:SI (match_operand:SI 1 "register_operand" "d")
8862 (match_operand:SI 2 "arith_operand" "dI")))]
8863 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8864 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8865 [(set_attr "type" "arith")
8866 (set_attr "mode" "SI")
8867 (set_attr "length" "8")])
8870 [(set (match_operand:SI 0 "register_operand" "")
8871 (geu:SI (match_operand:SI 1 "register_operand" "")
8872 (match_operand:SI 2 "arith_operand" "")))]
8873 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8875 (ltu:SI (match_dup 1)
8878 (xor:SI (match_dup 0)
8882 (define_insn "sgeu_di"
8883 [(set (match_operand:DI 0 "register_operand" "=d")
8884 (geu:DI (match_operand:DI 1 "se_register_operand" "d")
8885 (match_operand:DI 2 "se_arith_operand" "dI")))]
8886 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8887 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8888 [(set_attr "type" "arith")
8889 (set_attr "mode" "DI")
8890 (set_attr "length" "8")])
8893 [(set (match_operand:DI 0 "register_operand" "")
8894 (geu:DI (match_operand:DI 1 "se_register_operand" "")
8895 (match_operand:DI 2 "se_arith_operand" "")))]
8896 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8899 (ltu:DI (match_dup 1)
8902 (xor:DI (match_dup 0)
8906 (define_expand "sltu"
8907 [(set (match_operand:SI 0 "register_operand" "=d")
8908 (ltu:SI (match_dup 1)
8913 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8916 /* set up operands from compare. */
8917 operands[1] = branch_cmp[0];
8918 operands[2] = branch_cmp[1];
8920 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8922 gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
8926 /* fall through and generate default code */
8929 (define_insn "sltu_si"
8930 [(set (match_operand:SI 0 "register_operand" "=d")
8931 (ltu:SI (match_operand:SI 1 "register_operand" "d")
8932 (match_operand:SI 2 "arith_operand" "dI")))]
8935 [(set_attr "type" "arith")
8936 (set_attr "mode" "SI")])
8939 [(set (match_operand:SI 0 "register_operand" "=t,t")
8940 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
8941 (match_operand:SI 2 "arith_operand" "d,I")))]
8944 [(set_attr "type" "arith")
8945 (set_attr "mode" "SI")
8946 (set_attr_alternative "length"
8948 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8952 (define_insn "sltu_di"
8953 [(set (match_operand:DI 0 "register_operand" "=d")
8954 (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
8955 (match_operand:DI 2 "se_arith_operand" "dI")))]
8956 "TARGET_64BIT && !TARGET_MIPS16"
8958 [(set_attr "type" "arith")
8959 (set_attr "mode" "DI")])
8962 [(set (match_operand:DI 0 "register_operand" "=t,t")
8963 (ltu:DI (match_operand:DI 1 "se_register_operand" "d,d")
8964 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8965 "TARGET_64BIT && TARGET_MIPS16"
8967 [(set_attr "type" "arith")
8968 (set_attr "mode" "DI")
8969 (set_attr_alternative "length"
8971 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8975 (define_expand "sleu"
8976 [(set (match_operand:SI 0 "register_operand" "=d")
8977 (leu:SI (match_dup 1)
8982 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8985 /* set up operands from compare. */
8986 operands[1] = branch_cmp[0];
8987 operands[2] = branch_cmp[1];
8989 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8991 gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
8995 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8996 operands[2] = force_reg (SImode, operands[2]);
8998 /* fall through and generate default code */
9001 (define_insn "sleu_si_const"
9002 [(set (match_operand:SI 0 "register_operand" "=d")
9003 (leu:SI (match_operand:SI 1 "register_operand" "d")
9004 (match_operand:SI 2 "small_int" "I")))]
9005 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9008 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
9009 return \"sltu\\t%0,%1,%2\";
9011 [(set_attr "type" "arith")
9012 (set_attr "mode" "SI")])
9015 [(set (match_operand:SI 0 "register_operand" "=t")
9016 (leu:SI (match_operand:SI 1 "register_operand" "d")
9017 (match_operand:SI 2 "small_int" "I")))]
9018 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9021 operands[2] = GEN_INT (INTVAL (operands[2])+1);
9022 return \"sltu\\t%1,%2\";
9024 [(set_attr "type" "arith")
9025 (set_attr "mode" "SI")
9026 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
9030 (define_insn "sleu_di_const"
9031 [(set (match_operand:DI 0 "register_operand" "=d")
9032 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9033 (match_operand:DI 2 "small_int" "I")))]
9034 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9037 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
9038 return \"sltu\\t%0,%1,%2\";
9040 [(set_attr "type" "arith")
9041 (set_attr "mode" "DI")])
9044 [(set (match_operand:DI 0 "register_operand" "=t")
9045 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9046 (match_operand:DI 2 "small_int" "I")))]
9047 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9050 operands[2] = GEN_INT (INTVAL (operands[2])+1);
9051 return \"sltu\\t%1,%2\";
9053 [(set_attr "type" "arith")
9054 (set_attr "mode" "DI")
9055 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
9059 (define_insn "sleu_si_reg"
9060 [(set (match_operand:SI 0 "register_operand" "=d")
9061 (leu:SI (match_operand:SI 1 "register_operand" "d")
9062 (match_operand:SI 2 "register_operand" "d")))]
9063 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9064 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9065 [(set_attr "type" "arith")
9066 (set_attr "mode" "SI")
9067 (set_attr "length" "8")])
9070 [(set (match_operand:SI 0 "register_operand" "")
9071 (leu:SI (match_operand:SI 1 "register_operand" "")
9072 (match_operand:SI 2 "register_operand" "")))]
9073 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
9075 (ltu:SI (match_dup 2)
9078 (xor:SI (match_dup 0)
9082 (define_insn "sleu_di_reg"
9083 [(set (match_operand:DI 0 "register_operand" "=d")
9084 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9085 (match_operand:DI 2 "se_register_operand" "d")))]
9086 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9087 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9088 [(set_attr "type" "arith")
9089 (set_attr "mode" "DI")
9090 (set_attr "length" "8")])
9093 [(set (match_operand:DI 0 "register_operand" "")
9094 (leu:DI (match_operand:DI 1 "se_register_operand" "")
9095 (match_operand:DI 2 "se_register_operand" "")))]
9096 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
9099 (ltu:DI (match_dup 2)
9102 (xor:DI (match_dup 0)
9108 ;; ....................
9110 ;; FLOATING POINT COMPARISONS
9112 ;; ....................
9114 (define_insn "seq_df"
9115 [(set (match_operand:CC 0 "register_operand" "=z")
9116 (eq:CC (match_operand:DF 1 "register_operand" "f")
9117 (match_operand:DF 2 "register_operand" "f")))]
9118 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9121 return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9123 [(set_attr "type" "fcmp")
9124 (set_attr "mode" "FPSW")])
9126 (define_insn "slt_df"
9127 [(set (match_operand:CC 0 "register_operand" "=z")
9128 (lt:CC (match_operand:DF 1 "register_operand" "f")
9129 (match_operand:DF 2 "register_operand" "f")))]
9130 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9133 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9135 [(set_attr "type" "fcmp")
9136 (set_attr "mode" "FPSW")])
9138 (define_insn "sle_df"
9139 [(set (match_operand:CC 0 "register_operand" "=z")
9140 (le:CC (match_operand:DF 1 "register_operand" "f")
9141 (match_operand:DF 2 "register_operand" "f")))]
9142 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9145 return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9147 [(set_attr "type" "fcmp")
9148 (set_attr "mode" "FPSW")])
9150 (define_insn "sgt_df"
9151 [(set (match_operand:CC 0 "register_operand" "=z")
9152 (gt:CC (match_operand:DF 1 "register_operand" "f")
9153 (match_operand:DF 2 "register_operand" "f")))]
9154 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9157 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9159 [(set_attr "type" "fcmp")
9160 (set_attr "mode" "FPSW")])
9162 (define_insn "sge_df"
9163 [(set (match_operand:CC 0 "register_operand" "=z")
9164 (ge:CC (match_operand:DF 1 "register_operand" "f")
9165 (match_operand:DF 2 "register_operand" "f")))]
9166 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9169 return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9171 [(set_attr "type" "fcmp")
9172 (set_attr "mode" "FPSW")])
9174 (define_insn "seq_sf"
9175 [(set (match_operand:CC 0 "register_operand" "=z")
9176 (eq:CC (match_operand:SF 1 "register_operand" "f")
9177 (match_operand:SF 2 "register_operand" "f")))]
9181 return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9183 [(set_attr "type" "fcmp")
9184 (set_attr "mode" "FPSW")])
9186 (define_insn "slt_sf"
9187 [(set (match_operand:CC 0 "register_operand" "=z")
9188 (lt:CC (match_operand:SF 1 "register_operand" "f")
9189 (match_operand:SF 2 "register_operand" "f")))]
9193 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9195 [(set_attr "type" "fcmp")
9196 (set_attr "mode" "FPSW")])
9198 (define_insn "sle_sf"
9199 [(set (match_operand:CC 0 "register_operand" "=z")
9200 (le:CC (match_operand:SF 1 "register_operand" "f")
9201 (match_operand:SF 2 "register_operand" "f")))]
9205 return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9207 [(set_attr "type" "fcmp")
9208 (set_attr "mode" "FPSW")])
9210 (define_insn "sgt_sf"
9211 [(set (match_operand:CC 0 "register_operand" "=z")
9212 (gt:CC (match_operand:SF 1 "register_operand" "f")
9213 (match_operand:SF 2 "register_operand" "f")))]
9217 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9219 [(set_attr "type" "fcmp")
9220 (set_attr "mode" "FPSW")])
9222 (define_insn "sge_sf"
9223 [(set (match_operand:CC 0 "register_operand" "=z")
9224 (ge:CC (match_operand:SF 1 "register_operand" "f")
9225 (match_operand:SF 2 "register_operand" "f")))]
9229 return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9231 [(set_attr "type" "fcmp")
9232 (set_attr "mode" "FPSW")])
9236 ;; ....................
9238 ;; UNCONDITIONAL BRANCHES
9240 ;; ....................
9242 ;; Unconditional branches.
9246 (label_ref (match_operand 0 "" "")))]
9250 if (GET_CODE (operands[0]) == REG)
9251 return \"%*j\\t%0\";
9252 /* ??? I don't know why this is necessary. This works around an
9253 assembler problem that appears when a label is defined, then referenced
9254 in a switch table, then used in a `j' instruction. */
9255 else if (mips_abi != ABI_32 && mips_abi != ABI_O64)
9256 return \"%*b\\t%l0\";
9258 return \"%*j\\t%l0\";
9260 [(set_attr "type" "jump")
9261 (set_attr "mode" "none")])
9263 ;; We need a different insn for the mips16, because a mips16 branch
9264 ;; does not have a delay slot.
9268 (label_ref (match_operand 0 "" "")))]
9269 "TARGET_MIPS16 && GET_CODE (operands[0]) != REG"
9271 [(set_attr "type" "branch")
9272 (set_attr "mode" "none")
9273 (set_attr "length" "8")])
9275 (define_expand "indirect_jump"
9276 [(set (pc) (match_operand 0 "register_operand" "d"))]
9282 if (operands[0]) /* eliminate unused code warnings */
9285 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
9286 operands[0] = copy_to_mode_reg (Pmode, dest);
9288 if (!(Pmode == DImode))
9289 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
9291 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
9297 (define_insn "indirect_jump_internal1"
9298 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
9299 "!(Pmode == DImode)"
9301 [(set_attr "type" "jump")
9302 (set_attr "mode" "none")])
9304 (define_insn "indirect_jump_internal2"
9305 [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
9308 [(set_attr "type" "jump")
9309 (set_attr "mode" "none")])
9311 (define_expand "tablejump"
9313 (match_operand 0 "register_operand" "d"))
9314 (use (label_ref (match_operand 1 "" "")))]
9318 if (operands[0]) /* eliminate unused code warnings */
9322 if (GET_MODE (operands[0]) != HImode)
9324 if (!(Pmode == DImode))
9325 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
9327 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
9331 if (GET_MODE (operands[0]) != Pmode)
9336 if (!(Pmode == DImode))
9337 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
9339 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
9343 if (!(Pmode == DImode))
9344 emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
9346 emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
9353 (define_insn "tablejump_internal1"
9355 (match_operand:SI 0 "register_operand" "d"))
9356 (use (label_ref (match_operand 1 "" "")))]
9357 "!(Pmode == DImode)"
9359 [(set_attr "type" "jump")
9360 (set_attr "mode" "none")])
9362 (define_insn "tablejump_internal2"
9364 (match_operand:DI 0 "se_register_operand" "d"))
9365 (use (label_ref (match_operand 1 "" "")))]
9368 [(set_attr "type" "jump")
9369 (set_attr "mode" "none")])
9371 (define_expand "tablejump_internal3"
9372 [(parallel [(set (pc)
9373 (plus:SI (match_operand:SI 0 "register_operand" "d")
9374 (label_ref:SI (match_operand 1 "" ""))))
9375 (use (label_ref:SI (match_dup 1)))])]
9379 (define_expand "tablejump_mips161"
9380 [(set (pc) (plus:SI (sign_extend:SI
9381 (match_operand:HI 0 "register_operand" "d"))
9382 (label_ref:SI (match_operand 1 "" ""))))]
9383 "TARGET_MIPS16 && !(Pmode == DImode)"
9386 if (operands[0]) /* eliminate unused code warnings. */
9390 t1 = gen_reg_rtx (SImode);
9391 t2 = gen_reg_rtx (SImode);
9392 t3 = gen_reg_rtx (SImode);
9393 emit_insn (gen_extendhisi2 (t1, operands[0]));
9394 emit_move_insn (t2, gen_rtx (LABEL_REF, SImode, operands[1]));
9395 emit_insn (gen_addsi3 (t3, t1, t2));
9396 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
9401 (define_expand "tablejump_mips162"
9402 [(set (pc) (plus:DI (sign_extend:DI
9403 (match_operand:HI 0 "register_operand" "d"))
9404 (label_ref:DI (match_operand 1 "" ""))))]
9405 "TARGET_MIPS16 && Pmode == DImode"
9408 if (operands[0]) /* eliminate unused code warnings. */
9412 t1 = gen_reg_rtx (DImode);
9413 t2 = gen_reg_rtx (DImode);
9414 t3 = gen_reg_rtx (DImode);
9415 emit_insn (gen_extendhidi2 (t1, operands[0]));
9416 emit_move_insn (t2, gen_rtx (LABEL_REF, DImode, operands[1]));
9417 emit_insn (gen_adddi3 (t3, t1, t2));
9418 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
9423 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
9424 ;;; it is not valid. ??? With the USE, the condition tests may not be required
9427 ;;; ??? The length depends on the ABI. It is two for o32, and one for n32.
9428 ;;; We just use the conservative number here.
9432 (plus:SI (match_operand:SI 0 "register_operand" "d")
9433 (label_ref:SI (match_operand 1 "" ""))))
9434 (use (label_ref:SI (match_dup 1)))]
9435 "!(Pmode == DImode) && next_active_insn (insn) != 0
9436 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9437 && PREV_INSN (next_active_insn (insn)) == operands[1]"
9440 /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */
9441 if (mips_abi == ABI_32 || mips_abi == ABI_O64)
9442 output_asm_insn (\".cpadd\\t%0\", operands);
9443 return \"%*j\\t%0\";
9445 [(set_attr "type" "jump")
9446 (set_attr "mode" "none")
9447 (set_attr "length" "8")])
9449 (define_expand "tablejump_internal4"
9450 [(parallel [(set (pc)
9451 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9452 (label_ref:DI (match_operand 1 "" ""))))
9453 (use (label_ref:DI (match_dup 1)))])]
9457 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
9458 ;;; it is not valid. ??? With the USE, the condition tests may not be required
9463 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9464 (label_ref:DI (match_operand 1 "" ""))))
9465 (use (label_ref:DI (match_dup 1)))]
9466 "Pmode == DImode && next_active_insn (insn) != 0
9467 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9468 && PREV_INSN (next_active_insn (insn)) == operands[1]"
9470 [(set_attr "type" "jump")
9471 (set_attr "mode" "none")])
9473 ;; Implement a switch statement when generating embedded PIC code.
9474 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
9476 (define_expand "casesi"
9478 (minus:SI (match_operand:SI 0 "register_operand" "d")
9479 (match_operand:SI 1 "arith_operand" "dI")))
9481 (compare:CC (match_dup 5)
9482 (match_operand:SI 2 "arith_operand" "")))
9484 (if_then_else (gtu (cc0)
9486 (label_ref (match_operand 4 "" ""))
9490 (mem:SI (plus:SI (mult:SI (match_dup 5)
9492 (label_ref (match_operand 3 "" "")))))
9493 (clobber (match_scratch:SI 6 ""))
9494 (clobber (reg:SI 31))])]
9495 "TARGET_EMBEDDED_PIC"
9500 rtx reg = gen_reg_rtx (SImode);
9502 /* If the index is too large, go to the default label. */
9503 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
9504 emit_insn (gen_cmpsi (reg, operands[2]));
9505 emit_insn (gen_bgtu (operands[4]));
9507 /* Do the PIC jump. */
9508 if (Pmode != DImode)
9509 emit_jump_insn (gen_casesi_internal (reg, operands[3],
9510 gen_reg_rtx (SImode)));
9512 emit_jump_insn (gen_casesi_internal_di (reg, operands[3],
9513 gen_reg_rtx (DImode)));
9519 ;; An embedded PIC switch statement looks like this:
9521 ;; sll $reg,$index,2
9523 ;; addu $reg,$reg,$31
9524 ;; lw $reg,$L1-$LS1($reg)
9525 ;; addu $reg,$reg,$31
9532 (define_insn "casesi_internal"
9534 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
9536 (label_ref (match_operand 1 "" "")))))
9537 (clobber (match_operand:SI 2 "register_operand" "=d"))
9538 (clobber (reg:SI 31))]
9539 "TARGET_EMBEDDED_PIC"
9540 "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
9541 lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\\n\\t%*j\\t%2"
9542 [(set_attr "type" "jump")
9543 (set_attr "mode" "none")
9544 (set_attr "length" "24")])
9546 ;; This code assumes that the table index will never be >= 29 bits wide,
9547 ;; which allows the 'sign extend' from SI to DI be a no-op.
9548 (define_insn "casesi_internal_di"
9550 (mem:DI (plus:DI (sign_extend:DI
9551 (mult:SI (match_operand:SI 0 "register_operand" "d")
9553 (label_ref (match_operand 1 "" "")))))
9554 (clobber (match_operand:DI 2 "register_operand" "=d"))
9555 (clobber (reg:DI 31))]
9556 "TARGET_EMBEDDED_PIC"
9557 "%(bal\\t%S1\;sll\\t%2,%0,3\\n%~%S1:\;daddu\\t%2,%2,$31%)\;\\
9558 ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
9559 [(set_attr "type" "jump")
9560 (set_attr "mode" "none")
9561 (set_attr "length" "24")])
9563 ;; For o32/n32/n64, we save the gp in the jmp_buf as well. While it is
9564 ;; possible to either pull it off the stack (in the o32 case) or recalculate
9565 ;; it given t9 and our target label, it takes 3 or 4 insns to do so, and
9568 (define_expand "builtin_setjmp_setup"
9569 [(unspec [(match_operand 0 "register_operand" "r")] UNSPEC_SETJMP)]
9573 if (Pmode == DImode)
9574 emit_insn (gen_builtin_setjmp_setup_64 (operands[0]));
9576 emit_insn (gen_builtin_setjmp_setup_32 (operands[0]));
9580 (define_expand "builtin_setjmp_setup_32"
9581 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
9584 "TARGET_ABICALLS && ! (Pmode == DImode)"
9587 (define_expand "builtin_setjmp_setup_64"
9588 [(set (mem:DI (plus:DI (match_operand:DI 0 "register_operand" "r")
9591 "TARGET_ABICALLS && Pmode == DImode"
9594 ;; For o32/n32/n64, we need to arrange for longjmp to put the
9595 ;; target address in t9 so that we can use it for loading $gp.
9597 (define_expand "builtin_longjmp"
9598 [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPEC_LONGJMP)]
9602 /* The elements of the buffer are, in order: */
9603 int W = (Pmode == DImode ? 8 : 4);
9604 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9605 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
9606 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
9607 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
9608 rtx pv = gen_rtx_REG (Pmode, 25);
9609 rtx gp = gen_rtx_REG (Pmode, 28);
9611 /* This bit is the same as expand_builtin_longjmp. */
9612 emit_move_insn (hard_frame_pointer_rtx, fp);
9613 emit_move_insn (pv, lab);
9614 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
9615 emit_move_insn (gp, gpv);
9616 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
9617 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9618 emit_insn (gen_rtx_USE (VOIDmode, gp));
9619 emit_indirect_jump (pv);
9624 ;; ....................
9626 ;; Function prologue/epilogue
9628 ;; ....................
9631 (define_expand "prologue"
9636 if (mips_isa >= 0) /* avoid unused code warnings */
9638 mips_expand_prologue ();
9643 ;; Block any insns from being moved before this point, since the
9644 ;; profiling call to mcount can use various registers that aren't
9645 ;; saved or used to pass arguments.
9647 (define_insn "blockage"
9648 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
9651 [(set_attr "type" "unknown")
9652 (set_attr "mode" "none")
9653 (set_attr "length" "0")])
9655 (define_expand "epilogue"
9660 if (mips_isa >= 0) /* avoid unused code warnings */
9662 mips_expand_epilogue ();
9667 ;; Trivial return. Make it look like a normal return insn as that
9668 ;; allows jump optimizations to work better .
9669 (define_insn "return"
9671 "mips_can_use_return_insn ()"
9673 [(set_attr "type" "jump")
9674 (set_attr "mode" "none")])
9678 (define_insn "return_internal"
9679 [(use (match_operand 0 "pmode_register_operand" ""))
9684 return \"%*j\\t%0\";
9686 [(set_attr "type" "jump")
9687 (set_attr "mode" "none")])
9689 ;; When generating embedded PIC code we need to get the address of the
9690 ;; current function. This specialized instruction does just that.
9692 (define_insn "get_fnaddr"
9693 [(set (match_operand 0 "register_operand" "=d")
9694 (unspec [(match_operand 1 "" "")] UNSPEC_GET_FNADDR))
9695 (clobber (reg:SI 31))]
9696 "TARGET_EMBEDDED_PIC
9697 && GET_CODE (operands[1]) == SYMBOL_REF"
9698 "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
9699 [(set_attr "type" "call")
9700 (set_attr "mode" "none")
9701 (set_attr "length" "16")])
9703 ;; This is used in compiling the unwind routines.
9704 (define_expand "eh_return"
9705 [(use (match_operand 0 "general_operand" ""))
9706 (use (match_operand 1 "general_operand" ""))]
9710 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
9712 if (GET_MODE (operands[1]) != gpr_mode)
9713 operands[1] = convert_to_mode (gpr_mode, operands[1], 0);
9715 emit_insn (gen_eh_set_lr_di (operands[1]));
9717 emit_insn (gen_eh_set_lr_si (operands[1]));
9719 emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]);
9723 ;; Clobber the return address on the stack. We can't expand this
9724 ;; until we know where it will be put in the stack frame.
9726 (define_insn "eh_set_lr_si"
9727 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9728 (clobber (match_scratch:SI 1 "=&r"))]
9732 (define_insn "eh_set_lr_di"
9733 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9734 (clobber (match_scratch:DI 1 "=&r"))]
9739 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
9740 (clobber (match_scratch 1 ""))]
9741 "reload_completed && !TARGET_DEBUG_D_MODE"
9745 HOST_WIDE_INT gp_offset;
9748 compute_frame_size (get_frame_size ());
9749 if (((current_frame_info.mask >> 31) & 1) == 0)
9751 gp_offset = current_frame_info.gp_sp_offset;
9753 if (gp_offset < 32768)
9754 base = stack_pointer_rtx;
9758 emit_move_insn (base, GEN_INT (gp_offset));
9759 if (Pmode == DImode)
9760 emit_insn (gen_adddi3 (base, base, stack_pointer_rtx));
9762 emit_insn (gen_addsi3 (base, base, stack_pointer_rtx));
9765 emit_move_insn (gen_rtx_MEM (GET_MODE (operands[0]),
9766 plus_constant (base, gp_offset)),
9771 (define_insn "exception_receiver"
9772 [(unspec_volatile [(const_int 0)] UNSPEC_EH_RECEIVER)]
9773 "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)"
9778 operands[0] = pic_offset_table_rtx;
9779 if (frame_pointer_needed)
9780 loc = hard_frame_pointer_rtx;
9782 loc = stack_pointer_rtx;
9783 loc = plus_constant (loc, current_frame_info.args_size);
9784 operands[1] = gen_rtx_MEM (Pmode, loc);
9786 return mips_move_1word (operands, insn, 0);
9788 [(set_attr "type" "load")
9789 (set_attr "length" "8")])
9792 ;; ....................
9796 ;; ....................
9798 ;; calls.c now passes a third argument, make saber happy
9800 (define_expand "call"
9801 [(parallel [(call (match_operand 0 "memory_operand" "m")
9802 (match_operand 1 "" "i"))
9803 (clobber (reg:SI 31))
9804 (use (match_operand 2 "" "")) ;; next_arg_reg
9805 (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
9811 if (operands[0]) /* eliminate unused code warnings */
9813 addr = XEXP (operands[0], 0);
9814 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9815 || ! call_insn_operand (addr, VOIDmode))
9816 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
9818 /* In order to pass small structures by value in registers
9819 compatibly with the MIPS compiler, we need to shift the value
9820 into the high part of the register. Function_arg has encoded
9821 a PARALLEL rtx, holding a vector of adjustments to be made
9822 as the next_arg_reg variable, so we split up the insns,
9823 and emit them separately. */
9825 if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
9827 rtvec adjust = XVEC (operands[2], 0);
9828 int num = GET_NUM_ELEM (adjust);
9831 for (i = 0; i < num; i++)
9832 emit_insn (RTVEC_ELT (adjust, i));
9836 && mips16_hard_float
9838 && (int) GET_MODE (operands[2]) != 0)
9840 if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1],
9841 (int) GET_MODE (operands[2])))
9845 emit_call_insn (gen_call_internal0 (operands[0], operands[1],
9846 gen_rtx_REG (SImode,
9847 GP_REG_FIRST + 31)));
9852 (define_expand "call_internal0"
9853 [(parallel [(call (match_operand 0 "" "")
9854 (match_operand 1 "" ""))
9855 (clobber (match_operand:SI 2 "" ""))])]
9859 ;; We need to recognize reg:SI 31 specially for the mips16, because we
9860 ;; don't have a constraint letter for it.
9863 [(call (mem (match_operand 0 "call_insn_operand" "ei"))
9864 (match_operand 1 "" "i"))
9865 (clobber (match_operand:SI 2 "register_operand" "=y"))]
9866 "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9867 && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9869 [(set_attr "type" "call")
9870 (set_attr "mode" "none")
9871 (set_attr "length" "8")])
9873 (define_insn "call_internal1"
9874 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9875 (match_operand 1 "" "i"))
9876 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9877 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9880 register rtx target = operands[0];
9882 if (GET_CODE (target) == CONST_INT)
9883 return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
9884 else if (CONSTANT_ADDRESS_P (target))
9885 return \"%*jal\\t%0\";
9887 return \"%*jal\\t%2,%0\";
9889 [(set_attr "type" "call")
9890 (set_attr "mode" "none")])
9892 (define_insn "call_internal2"
9893 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9894 (match_operand 1 "" "i"))
9895 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9896 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9899 register rtx target = operands[0];
9901 if (GET_CODE (target) == CONST_INT)
9902 return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
9903 else if (CONSTANT_ADDRESS_P (target))
9905 if (GET_MODE (target) == SImode)
9906 return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
9908 return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
9910 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9911 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9913 return \"jal\\t%2,%0\";
9915 [(set_attr "type" "call")
9916 (set_attr "mode" "none")
9917 (set_attr "length" "8")])
9919 (define_insn "call_internal3a"
9920 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9921 (match_operand 1 "" "i"))
9922 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9924 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9926 [(set_attr "type" "call")
9927 (set_attr "mode" "none")])
9929 (define_insn "call_internal3b"
9930 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9931 (match_operand 1 "" "i"))
9932 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9934 && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9936 [(set_attr "type" "call")
9937 (set_attr "mode" "none")
9938 (set_attr "length" "1")])
9940 (define_insn "call_internal3c"
9941 [(call (mem:SI (match_operand:SI 0 "register_operand" "e"))
9942 (match_operand 1 "" "i"))
9943 (clobber (match_operand:SI 2 "register_operand" "=y"))]
9944 "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
9945 && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9947 [(set_attr "type" "call")
9948 (set_attr "mode" "none")])
9950 (define_insn "call_internal4a"
9951 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9952 (match_operand 1 "" "i"))
9953 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9954 "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
9957 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9958 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9960 return \"jal\\t%2,%0\";
9962 [(set_attr "type" "call")
9963 (set_attr "mode" "none")
9964 (set_attr "length" "8")])
9966 (define_insn "call_internal4b"
9967 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9968 (match_operand 1 "" "i"))
9969 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9970 "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
9973 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9974 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9976 return \"jal\\t%2,%0\";
9978 [(set_attr "type" "call")
9979 (set_attr "mode" "none")
9980 (set_attr "length" "8")])
9982 ;; calls.c now passes a fourth argument, make saber happy
9984 (define_expand "call_value"
9985 [(parallel [(set (match_operand 0 "register_operand" "=df")
9986 (call (match_operand 1 "memory_operand" "m")
9987 (match_operand 2 "" "i")))
9988 (clobber (reg:SI 31))
9989 (use (match_operand 3 "" ""))])] ;; next_arg_reg
9995 if (operands[0]) /* eliminate unused code warning */
9997 addr = XEXP (operands[1], 0);
9998 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9999 || ! call_insn_operand (addr, VOIDmode))
10000 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
10002 /* In order to pass small structures by value in registers
10003 compatibly with the MIPS compiler, we need to shift the value
10004 into the high part of the register. Function_arg has encoded
10005 a PARALLEL rtx, holding a vector of adjustments to be made
10006 as the next_arg_reg variable, so we split up the insns,
10007 and emit them separately. */
10009 if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
10011 rtvec adjust = XVEC (operands[3], 0);
10012 int num = GET_NUM_ELEM (adjust);
10015 for (i = 0; i < num; i++)
10016 emit_insn (RTVEC_ELT (adjust, i));
10020 && mips16_hard_float
10021 && ((operands[3] != 0
10022 && (int) GET_MODE (operands[3]) != 0)
10023 || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT))
10025 if (build_mips16_call_stub (operands[0], operands[1], operands[2],
10026 (operands[3] == 0 ? 0
10027 : (int) GET_MODE (operands[3]))))
10031 /* Handle Irix6 function calls that have multiple non-contiguous
10033 if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
10035 emit_call_insn (gen_call_value_multiple_internal0
10036 (XEXP (XVECEXP (operands[0], 0, 0), 0),
10037 operands[1], operands[2],
10038 XEXP (XVECEXP (operands[0], 0, 1), 0),
10039 gen_rtx_REG (SImode, GP_REG_FIRST + 31)));
10043 /* We have a call returning a DImode structure in an FP reg.
10044 Strip off the now unnecessary PARALLEL. */
10045 if (GET_CODE (operands[0]) == PARALLEL)
10046 operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
10048 emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
10049 gen_rtx_REG (SImode,
10050 GP_REG_FIRST + 31)));
10056 (define_expand "call_value_internal0"
10057 [(parallel [(set (match_operand 0 "" "")
10058 (call (match_operand 1 "" "")
10059 (match_operand 2 "" "")))
10060 (clobber (match_operand:SI 3 "" ""))])]
10064 ;; Recognize $31 specially on the mips16, because we don't have a
10065 ;; constraint letter for it.
10068 [(set (match_operand 0 "register_operand" "=d")
10069 (call (mem (match_operand 1 "call_insn_operand" "ei"))
10070 (match_operand 2 "" "i")))
10071 (clobber (match_operand:SI 3 "register_operand" "=y"))]
10072 "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
10073 && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
10075 [(set_attr "type" "call")
10076 (set_attr "mode" "none")
10077 (set_attr "length" "8")])
10079 (define_insn "call_value_internal1"
10080 [(set (match_operand 0 "register_operand" "=df")
10081 (call (mem (match_operand 1 "call_insn_operand" "ri"))
10082 (match_operand 2 "" "i")))
10083 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10084 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10087 register rtx target = operands[1];
10089 if (GET_CODE (target) == CONST_INT)
10090 return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
10091 else if (CONSTANT_ADDRESS_P (target))
10092 return \"%*jal\\t%1\";
10094 return \"%*jal\\t%3,%1\";
10096 [(set_attr "type" "call")
10097 (set_attr "mode" "none")])
10099 (define_insn "call_value_internal2"
10100 [(set (match_operand 0 "register_operand" "=df")
10101 (call (mem (match_operand 1 "call_insn_operand" "ri"))
10102 (match_operand 2 "" "i")))
10103 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10104 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10107 register rtx target = operands[1];
10109 if (GET_CODE (target) == CONST_INT)
10110 return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
10111 else if (CONSTANT_ADDRESS_P (target))
10113 if (GET_MODE (target) == SImode)
10114 return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
10116 return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
10118 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10119 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10121 return \"jal\\t%3,%1\";
10123 [(set_attr "type" "call")
10124 (set_attr "mode" "none")
10125 (set_attr "length" "8")])
10127 (define_insn "call_value_internal3a"
10128 [(set (match_operand 0 "register_operand" "=df")
10129 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10130 (match_operand 2 "" "i")))
10131 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10133 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10135 [(set_attr "type" "call")
10136 (set_attr "mode" "none")])
10138 (define_insn "call_value_internal3b"
10139 [(set (match_operand 0 "register_operand" "=df")
10140 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10141 (match_operand 2 "" "i")))
10142 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10144 && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10146 [(set_attr "type" "call")
10147 (set_attr "mode" "none")])
10149 (define_insn "call_value_internal3c"
10150 [(set (match_operand 0 "register_operand" "=df")
10151 (call (mem:SI (match_operand:SI 1 "register_operand" "e"))
10152 (match_operand 2 "" "i")))
10153 (clobber (match_operand:SI 3 "register_operand" "=y"))]
10154 "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
10155 && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
10157 [(set_attr "type" "call")
10158 (set_attr "mode" "none")])
10160 (define_insn "call_value_internal4a"
10161 [(set (match_operand 0 "register_operand" "=df")
10162 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10163 (match_operand 2 "" "i")))
10164 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10165 "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
10168 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10169 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10171 return \"jal\\t%3,%1\";
10173 [(set_attr "type" "call")
10174 (set_attr "mode" "none")
10175 (set_attr "length" "8")])
10177 (define_insn "call_value_internal4b"
10178 [(set (match_operand 0 "register_operand" "=df")
10179 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10180 (match_operand 2 "" "i")))
10181 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10182 "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
10185 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10186 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10188 return \"jal\\t%3,%1\";
10190 [(set_attr "type" "call")
10191 (set_attr "mode" "none")
10192 (set_attr "length" "8")])
10194 (define_expand "call_value_multiple_internal0"
10195 [(parallel [(set (match_operand 0 "" "")
10196 (call (match_operand 1 "" "")
10197 (match_operand 2 "" "")))
10198 (set (match_operand 3 "" "")
10199 (call (match_dup 1)
10201 (clobber (match_operand:SI 4 "" ""))])]
10205 ;; ??? May eventually need all 6 versions of the call patterns with multiple
10208 (define_insn "call_value_multiple_internal1"
10209 [(set (match_operand 0 "register_operand" "=df")
10210 (call (mem (match_operand 1 "call_insn_operand" "ri"))
10211 (match_operand 2 "" "i")))
10212 (set (match_operand 3 "register_operand" "=df")
10213 (call (mem (match_dup 1))
10215 (clobber (match_operand:SI 4 "register_operand" "=d"))]
10216 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10219 register rtx target = operands[1];
10221 if (GET_CODE (target) == CONST_INT)
10222 return \"%[li\\t%@,%1\\n\\t%*jal\\t%4,%@%]\";
10223 else if (CONSTANT_ADDRESS_P (target))
10224 return \"%*jal\\t%1\";
10226 return \"%*jal\\t%4,%1\";
10228 [(set_attr "type" "call")
10229 (set_attr "mode" "none")])
10231 (define_insn "call_value_multiple_internal2"
10232 [(set (match_operand 0 "register_operand" "=df")
10233 (call (mem (match_operand 1 "call_insn_operand" "ri"))
10234 (match_operand 2 "" "i")))
10235 (set (match_operand 3 "register_operand" "=df")
10236 (call (mem (match_dup 1))
10238 (clobber (match_operand:SI 4 "register_operand" "=d"))]
10239 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10242 register rtx target = operands[1];
10244 if (GET_CODE (target) == CONST_INT)
10245 return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
10246 else if (CONSTANT_ADDRESS_P (target))
10248 if (GET_MODE (target) == SImode)
10249 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
10251 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
10253 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10254 return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
10256 return \"jal\\t%4,%1\";
10258 [(set_attr "type" "call")
10259 (set_attr "mode" "none")
10260 (set_attr "length" "8")])
10263 ;; Call subroutine returning any type.
10265 (define_expand "untyped_call"
10266 [(parallel [(call (match_operand 0 "" "")
10268 (match_operand 1 "" "")
10269 (match_operand 2 "" "")])]
10273 if (operands[0]) /* silence statement not reached warnings */
10277 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
10279 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10281 rtx set = XVECEXP (operands[2], 0, i);
10282 emit_move_insn (SET_DEST (set), SET_SRC (set));
10285 emit_insn (gen_blockage ());
10291 ;; ....................
10295 ;; ....................
10302 [(set_attr "type" "nop")
10303 (set_attr "mode" "none")])
10305 ;; The MIPS chip does not seem to require stack probes.
10307 ;; (define_expand "probe"
10308 ;; [(set (match_dup 0)
10313 ;; operands[0] = gen_reg_rtx (SImode);
10314 ;; operands[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
10315 ;; MEM_VOLATILE_P (operands[1]) = TRUE;
10317 ;; /* fall through and generate default code */
10322 ;; MIPS4 Conditional move instructions.
10325 [(set (match_operand:SI 0 "register_operand" "=d,d")
10327 (match_operator 4 "equality_op"
10328 [(match_operand:SI 1 "register_operand" "d,d")
10330 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10331 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10332 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10335 mov%b4\\t%0,%z3,%1"
10336 [(set_attr "type" "move")
10337 (set_attr "mode" "SI")])
10340 [(set (match_operand:SI 0 "register_operand" "=d,d")
10342 (match_operator 4 "equality_op"
10343 [(match_operand:DI 1 "se_register_operand" "d,d")
10345 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10346 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10347 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10350 mov%b4\\t%0,%z3,%1"
10351 [(set_attr "type" "move")
10352 (set_attr "mode" "SI")])
10355 [(set (match_operand:SI 0 "register_operand" "=d,d")
10357 (match_operator 3 "equality_op" [(match_operand:CC 4
10361 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
10362 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
10363 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10366 mov%t3\\t%0,%z2,%4"
10367 [(set_attr "type" "move")
10368 (set_attr "mode" "SI")])
10371 [(set (match_operand:DI 0 "register_operand" "=d,d")
10373 (match_operator 4 "equality_op"
10374 [(match_operand:SI 1 "register_operand" "d,d")
10376 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10377 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10378 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10381 mov%b4\\t%0,%z3,%1"
10382 [(set_attr "type" "move")
10383 (set_attr "mode" "DI")])
10386 [(set (match_operand:DI 0 "register_operand" "=d,d")
10388 (match_operator 4 "equality_op"
10389 [(match_operand:DI 1 "se_register_operand" "d,d")
10391 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10392 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10393 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10396 mov%b4\\t%0,%z3,%1"
10397 [(set_attr "type" "move")
10398 (set_attr "mode" "DI")])
10401 [(set (match_operand:DI 0 "register_operand" "=d,d")
10403 (match_operator 3 "equality_op" [(match_operand:CC 4
10407 (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
10408 (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
10409 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
10412 mov%t3\\t%0,%z2,%4"
10413 [(set_attr "type" "move")
10414 (set_attr "mode" "DI")])
10417 [(set (match_operand:SF 0 "register_operand" "=f,f")
10419 (match_operator 4 "equality_op"
10420 [(match_operand:SI 1 "register_operand" "d,d")
10422 (match_operand:SF 2 "register_operand" "f,0")
10423 (match_operand:SF 3 "register_operand" "0,f")))]
10424 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10426 mov%B4.s\\t%0,%2,%1
10427 mov%b4.s\\t%0,%3,%1"
10428 [(set_attr "type" "move")
10429 (set_attr "mode" "SF")])
10432 [(set (match_operand:SF 0 "register_operand" "=f,f")
10434 (match_operator 4 "equality_op"
10435 [(match_operand:DI 1 "se_register_operand" "d,d")
10437 (match_operand:SF 2 "register_operand" "f,0")
10438 (match_operand:SF 3 "register_operand" "0,f")))]
10439 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10441 mov%B4.s\\t%0,%2,%1
10442 mov%b4.s\\t%0,%3,%1"
10443 [(set_attr "type" "move")
10444 (set_attr "mode" "SF")])
10447 [(set (match_operand:SF 0 "register_operand" "=f,f")
10449 (match_operator 3 "equality_op" [(match_operand:CC 4
10453 (match_operand:SF 1 "register_operand" "f,0")
10454 (match_operand:SF 2 "register_operand" "0,f")))]
10455 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10457 mov%T3.s\\t%0,%1,%4
10458 mov%t3.s\\t%0,%2,%4"
10459 [(set_attr "type" "move")
10460 (set_attr "mode" "SF")])
10463 [(set (match_operand:DF 0 "register_operand" "=f,f")
10465 (match_operator 4 "equality_op"
10466 [(match_operand:SI 1 "register_operand" "d,d")
10468 (match_operand:DF 2 "register_operand" "f,0")
10469 (match_operand:DF 3 "register_operand" "0,f")))]
10470 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10472 mov%B4.d\\t%0,%2,%1
10473 mov%b4.d\\t%0,%3,%1"
10474 [(set_attr "type" "move")
10475 (set_attr "mode" "DF")])
10478 [(set (match_operand:DF 0 "register_operand" "=f,f")
10480 (match_operator 4 "equality_op"
10481 [(match_operand:DI 1 "se_register_operand" "d,d")
10483 (match_operand:DF 2 "register_operand" "f,0")
10484 (match_operand:DF 3 "register_operand" "0,f")))]
10485 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10487 mov%B4.d\\t%0,%2,%1
10488 mov%b4.d\\t%0,%3,%1"
10489 [(set_attr "type" "move")
10490 (set_attr "mode" "DF")])
10493 [(set (match_operand:DF 0 "register_operand" "=f,f")
10495 (match_operator 3 "equality_op" [(match_operand:CC 4
10499 (match_operand:DF 1 "register_operand" "f,0")
10500 (match_operand:DF 2 "register_operand" "0,f")))]
10501 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10503 mov%T3.d\\t%0,%1,%4
10504 mov%t3.d\\t%0,%2,%4"
10505 [(set_attr "type" "move")
10506 (set_attr "mode" "DF")])
10508 ;; These are the main define_expand's used to make conditional moves.
10510 (define_expand "movsicc"
10511 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10512 (set (match_operand:SI 0 "register_operand" "")
10513 (if_then_else:SI (match_dup 5)
10514 (match_operand:SI 2 "reg_or_0_operand" "")
10515 (match_operand:SI 3 "reg_or_0_operand" "")))]
10516 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10519 gen_conditional_move (operands);
10523 (define_expand "movdicc"
10524 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10525 (set (match_operand:DI 0 "register_operand" "")
10526 (if_then_else:DI (match_dup 5)
10527 (match_operand:DI 2 "se_reg_or_0_operand" "")
10528 (match_operand:DI 3 "se_reg_or_0_operand" "")))]
10529 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10532 if (mips_isa == 32)
10534 gen_conditional_move (operands);
10538 (define_expand "movsfcc"
10539 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10540 (set (match_operand:SF 0 "register_operand" "")
10541 (if_then_else:SF (match_dup 5)
10542 (match_operand:SF 2 "register_operand" "")
10543 (match_operand:SF 3 "register_operand" "")))]
10544 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10547 gen_conditional_move (operands);
10551 (define_expand "movdfcc"
10552 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10553 (set (match_operand:DF 0 "register_operand" "")
10554 (if_then_else:DF (match_dup 5)
10555 (match_operand:DF 2 "register_operand" "")
10556 (match_operand:DF 3 "register_operand" "")))]
10557 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10560 gen_conditional_move (operands);
10565 ;; ....................
10567 ;; mips16 inline constant tables
10569 ;; ....................
10572 (define_insn "consttable_qi"
10573 [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")]
10574 UNSPEC_CONSTTABLE_QI)]
10578 assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
10581 [(set_attr "type" "unknown")
10582 (set_attr "mode" "QI")
10583 (set_attr "length" "8")])
10585 (define_insn "consttable_hi"
10586 [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")]
10587 UNSPEC_CONSTTABLE_HI)]
10591 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10594 [(set_attr "type" "unknown")
10595 (set_attr "mode" "HI")
10596 (set_attr "length" "8")])
10598 (define_insn "consttable_si"
10599 [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")]
10600 UNSPEC_CONSTTABLE_SI)]
10604 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10607 [(set_attr "type" "unknown")
10608 (set_attr "mode" "SI")
10609 (set_attr "length" "8")])
10611 (define_insn "consttable_di"
10612 [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")]
10613 UNSPEC_CONSTTABLE_DI)]
10617 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10620 [(set_attr "type" "unknown")
10621 (set_attr "mode" "DI")
10622 (set_attr "length" "16")])
10624 (define_insn "consttable_sf"
10625 [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")]
10626 UNSPEC_CONSTTABLE_SF)]
10632 if (GET_CODE (operands[0]) != CONST_DOUBLE)
10634 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10635 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10638 [(set_attr "type" "unknown")
10639 (set_attr "mode" "SF")
10640 (set_attr "length" "8")])
10642 (define_insn "consttable_df"
10643 [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")]
10644 UNSPEC_CONSTTABLE_DF)]
10650 if (GET_CODE (operands[0]) != CONST_DOUBLE)
10652 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10653 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10656 [(set_attr "type" "unknown")
10657 (set_attr "mode" "DF")
10658 (set_attr "length" "16")])
10660 (define_insn "align_2"
10661 [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_2)]
10664 [(set_attr "type" "unknown")
10665 (set_attr "mode" "HI")
10666 (set_attr "length" "8")])
10668 (define_insn "align_4"
10669 [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_4)]
10672 [(set_attr "type" "unknown")
10673 (set_attr "mode" "SI")
10674 (set_attr "length" "8")])
10676 (define_insn "align_8"
10677 [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_8)]
10680 [(set_attr "type" "unknown")
10681 (set_attr "mode" "DI")
10682 (set_attr "length" "12")])
10685 ;; ....................
10687 ;; mips16 peepholes
10689 ;; ....................
10692 ;; On the mips16, reload will sometimes decide that a pseudo register
10693 ;; should go into $24, and then later on have to reload that register.
10694 ;; When that happens, we get a load of a general register followed by
10695 ;; a move from the general register to $24 followed by a branch.
10696 ;; These peepholes catch the common case, and fix it to just use the
10697 ;; general register for the branch.
10700 [(set (match_operand:SI 0 "register_operand" "=t")
10701 (match_operand:SI 1 "register_operand" "d"))
10703 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10705 (match_operand 3 "pc_or_label_operand" "")
10706 (match_operand 4 "pc_or_label_operand" "")))]
10708 && GET_CODE (operands[0]) == REG
10709 && REGNO (operands[0]) == 24
10710 && dead_or_set_p (insn, operands[0])
10711 && GET_CODE (operands[1]) == REG
10712 && M16_REG_P (REGNO (operands[1]))"
10715 if (operands[3] != pc_rtx)
10716 return \"%*b%C2z\\t%1,%3\";
10718 return \"%*b%N2z\\t%1,%4\";
10720 [(set_attr "type" "branch")
10721 (set_attr "mode" "none")
10722 (set_attr "length" "8")])
10725 [(set (match_operand:DI 0 "register_operand" "=t")
10726 (match_operand:DI 1 "register_operand" "d"))
10728 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10730 (match_operand 3 "pc_or_label_operand" "")
10731 (match_operand 4 "pc_or_label_operand" "")))]
10732 "TARGET_MIPS16 && TARGET_64BIT
10733 && GET_CODE (operands[0]) == REG
10734 && REGNO (operands[0]) == 24
10735 && dead_or_set_p (insn, operands[0])
10736 && GET_CODE (operands[1]) == REG
10737 && M16_REG_P (REGNO (operands[1]))"
10740 if (operands[3] != pc_rtx)
10741 return \"%*b%C2z\\t%1,%3\";
10743 return \"%*b%N2z\\t%1,%4\";
10745 [(set_attr "type" "branch")
10746 (set_attr "mode" "none")
10747 (set_attr "length" "8")])
10749 ;; We can also have the reverse reload: reload will spill $24 into
10750 ;; another register, and then do a branch on that register when it
10751 ;; could have just stuck with $24.
10754 [(set (match_operand:SI 0 "register_operand" "=d")
10755 (match_operand:SI 1 "register_operand" "t"))
10757 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10759 (match_operand 3 "pc_or_label_operand" "")
10760 (match_operand 4 "pc_or_label_operand" "")))]
10762 && GET_CODE (operands[1]) == REG
10763 && REGNO (operands[1]) == 24
10764 && GET_CODE (operands[0]) == REG
10765 && M16_REG_P (REGNO (operands[0]))
10766 && dead_or_set_p (insn, operands[0])"
10769 if (operands[3] != pc_rtx)
10770 return \"%*bt%C2z\\t%3\";
10772 return \"%*bt%N2z\\t%4\";
10774 [(set_attr "type" "branch")
10775 (set_attr "mode" "none")
10776 (set_attr "length" "8")])
10779 [(set (match_operand:DI 0 "register_operand" "=d")
10780 (match_operand:DI 1 "register_operand" "t"))
10782 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10784 (match_operand 3 "pc_or_label_operand" "")
10785 (match_operand 4 "pc_or_label_operand" "")))]
10786 "TARGET_MIPS16 && TARGET_64BIT
10787 && GET_CODE (operands[1]) == REG
10788 && REGNO (operands[1]) == 24
10789 && GET_CODE (operands[0]) == REG
10790 && M16_REG_P (REGNO (operands[0]))
10791 && dead_or_set_p (insn, operands[0])"
10794 if (operands[3] != pc_rtx)
10795 return \"%*bt%C2z\\t%3\";
10797 return \"%*bt%N2z\\t%4\";
10799 [(set_attr "type" "branch")
10800 (set_attr "mode" "none")
10801 (set_attr "length" "8")])
10803 ;; For the rare case where we need to load an address into a register
10804 ;; that can not be recognized by the normal movsi/addsi instructions.
10805 ;; I have no idea how many insns this can actually generate. It should
10806 ;; be rare, so over-estimating as 10 instructions should not have any
10807 ;; real performance impact.
10808 (define_insn "leasi"
10809 [(set (match_operand:SI 0 "register_operand" "=d")
10810 (match_operand:SI 1 "address_operand" "p"))]
10813 [(set_attr "type" "arith")
10814 (set_attr "mode" "SI")
10815 (set_attr "length" "40")])
10817 ;; Similarly for targets where we have 64bit pointers.
10818 (define_insn "leadi"
10819 [(set (match_operand:DI 0 "register_operand" "=d")
10820 (match_operand:DI 1 "address_operand" "p"))]
10823 [(set_attr "type" "arith")
10824 (set_attr "mode" "DI")
10825 (set_attr "length" "40")])