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.
29 ;; UNSPEC values used in mips.md
32 ;; 1 movsi_us, get_fnaddr
33 ;; 2 reload_in*, reload_out* : sets delay on HILO register
35 ;; 20 builtin_setjmp_setup
37 ;; UNSPEC_VOLATILE values
41 ;; 4 exception_receiver
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 ;; Attribute defining whether or not we can use the branch-likely instructions
140 (define_attr "branch_likely" "no,yes"
142 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
144 (const_string "no"))))
147 ;; Describe a user's asm statement.
148 (define_asm_attributes
149 [(set_attr "type" "multi")])
151 ;; whether or not generating calls to position independent functions
152 (define_attr "abicalls" "no,yes"
153 (const (symbol_ref "mips_abicalls_attr")))
157 ;; .........................
159 ;; Delay slots, can't describe load/fcmp/xfer delay slots here
161 ;; .........................
163 (define_delay (and (eq_attr "type" "branch")
164 (eq (symbol_ref "mips16") (const_int 0)))
165 [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
167 (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "4")))])
169 (define_delay (eq_attr "type" "jump")
170 [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
174 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
175 [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
181 ;; .........................
185 ;; .........................
187 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
188 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
190 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
192 (define_function_unit "memory" 1 0
193 (and (eq_attr "type" "load")
194 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
197 (define_function_unit "memory" 1 0
198 (and (eq_attr "type" "load")
199 (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
202 (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
204 (define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)
206 (define_function_unit "imuldiv" 1 0
207 (eq_attr "type" "hilo")
210 (define_function_unit "imuldiv" 1 0
211 (and (eq_attr "type" "imul")
212 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
215 ;; On them mips16, we want to stronly discourage a mult from appearing
216 ;; after an mflo, since that requires explicit nop instructions. We
217 ;; do this by pretending that mflo ties up the function unit for long
218 ;; enough that the scheduler will ignore load stalls and the like when
219 ;; selecting instructions to between the two instructions.
221 (define_function_unit "imuldiv" 1 0
222 (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0)))
225 (define_function_unit "imuldiv" 1 0
226 (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000,r3900"))
229 (define_function_unit "imuldiv" 1 0
230 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
233 (define_function_unit "imuldiv" 1 0
234 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4650"))
237 (define_function_unit "imuldiv" 1 0
238 (and (eq_attr "type" "imul")
239 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
242 (define_function_unit "imuldiv" 1 0
243 (and (eq_attr "type" "imul")
244 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
247 (define_function_unit "imuldiv" 1 0
248 (and (eq_attr "type" "imul")
249 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
252 (define_function_unit "imuldiv" 1 0
253 (and (eq_attr "type" "imul")
254 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
257 (define_function_unit "imuldiv" 1 0
258 (and (eq_attr "type" "imul")
259 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
262 (define_function_unit "imuldiv" 1 0
263 (and (eq_attr "type" "idiv")
264 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
267 (define_function_unit "imuldiv" 1 0
268 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
271 (define_function_unit "imuldiv" 1 0
272 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
275 (define_function_unit "imuldiv" 1 0
276 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
279 (define_function_unit "imuldiv" 1 0
280 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
283 (define_function_unit "imuldiv" 1 0
284 (and (eq_attr "type" "idiv")
285 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
288 (define_function_unit "imuldiv" 1 0
289 (and (eq_attr "type" "idiv")
290 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
293 (define_function_unit "imuldiv" 1 0
294 (and (eq_attr "type" "idiv")
295 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
298 (define_function_unit "imuldiv" 1 0
299 (and (eq_attr "type" "idiv")
300 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
303 (define_function_unit "imuldiv" 1 0
304 (and (eq_attr "type" "idiv")
305 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
308 (define_function_unit "imuldiv" 1 0
309 (and (eq_attr "type" "idiv")
310 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
313 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
314 ;; the FP hardware is part of the normal ALU circuitry. This means FP
315 ;; instructions affect the pipe-line, and no functional unit
316 ;; parallelism can occur on R4300 processors. To force GCC into coding
317 ;; for only a single functional unit, we force the R4300 FP
318 ;; instructions to be processed in the "imuldiv" unit.
320 (define_function_unit "adder" 1 1
321 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
324 (define_function_unit "adder" 1 1
325 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
328 (define_function_unit "adder" 1 1
329 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
332 (define_function_unit "adder" 1 1
333 (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
336 (define_function_unit "adder" 1 1
337 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
340 (define_function_unit "adder" 1 1
341 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
344 (define_function_unit "adder" 1 1
345 (and (eq_attr "type" "fabs,fneg")
346 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
349 (define_function_unit "adder" 1 1
350 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
353 (define_function_unit "mult" 1 1
354 (and (eq_attr "type" "fmul")
355 (and (eq_attr "mode" "SF")
356 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
359 (define_function_unit "mult" 1 1
360 (and (eq_attr "type" "fmul")
361 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
364 (define_function_unit "mult" 1 1
365 (and (eq_attr "type" "fmul")
366 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
369 (define_function_unit "mult" 1 1
370 (and (eq_attr "type" "fmul")
371 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
374 (define_function_unit "mult" 1 1
375 (and (eq_attr "type" "fmul")
376 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
379 (define_function_unit "mult" 1 1
380 (and (eq_attr "type" "fmul")
381 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
384 (define_function_unit "mult" 1 1
385 (and (eq_attr "type" "fmul")
386 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
389 (define_function_unit "divide" 1 1
390 (and (eq_attr "type" "fdiv")
391 (and (eq_attr "mode" "SF")
392 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
395 (define_function_unit "divide" 1 1
396 (and (eq_attr "type" "fdiv")
397 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
400 (define_function_unit "divide" 1 1
401 (and (eq_attr "type" "fdiv")
402 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
405 (define_function_unit "divide" 1 1
406 (and (eq_attr "type" "fdiv")
407 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
410 (define_function_unit "divide" 1 1
411 (and (eq_attr "type" "fdiv")
412 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
415 (define_function_unit "divide" 1 1
416 (and (eq_attr "type" "fdiv")
417 (and (eq_attr "mode" "DF")
418 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
421 (define_function_unit "divide" 1 1
422 (and (eq_attr "type" "fdiv")
423 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
426 (define_function_unit "divide" 1 1
427 (and (eq_attr "type" "fdiv")
428 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
431 (define_function_unit "divide" 1 1
432 (and (eq_attr "type" "fdiv")
433 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
436 ;;; ??? Is this number right?
437 (define_function_unit "divide" 1 1
438 (and (eq_attr "type" "fsqrt")
439 (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
442 (define_function_unit "divide" 1 1
443 (and (eq_attr "type" "fsqrt")
444 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
447 (define_function_unit "divide" 1 1
448 (and (eq_attr "type" "fsqrt")
449 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
452 ;;; ??? Is this number right?
453 (define_function_unit "divide" 1 1
454 (and (eq_attr "type" "fsqrt")
455 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
458 (define_function_unit "divide" 1 1
459 (and (eq_attr "type" "fsqrt")
460 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
463 (define_function_unit "divide" 1 1
464 (and (eq_attr "type" "fsqrt")
465 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
468 ;; R4300 FP instruction classes treated as part of the "imuldiv"
471 (define_function_unit "imuldiv" 1 0
472 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
475 (define_function_unit "imuldiv" 1 0
476 (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
479 (define_function_unit "imuldiv" 1 0
480 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
482 (define_function_unit "imuldiv" 1 0
483 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
486 (define_function_unit "imuldiv" 1 0
487 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
488 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
490 (define_function_unit "imuldiv" 1 0
491 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
492 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
495 ;; The following functional units do not use the cpu type, and use
496 ;; much less memory in genattrtab.c.
498 ;; (define_function_unit "memory" 1 0 (eq_attr "type" "load") 3 0)
499 ;; (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
501 ;; (define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0)
503 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0)
504 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0)
506 ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "imul") 17 0)
507 ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "idiv") 38 0)
509 ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fadd") 4 0)
510 ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fabs,fneg") 2 0)
512 ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF")) 7 0)
513 ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF")) 8 0)
515 ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF")) 23 0)
516 ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF")) 36 0)
518 ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0)
519 ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
522 ;; ....................
526 ;; ....................
530 [(trap_if (const_int 1) (const_int 0))]
534 if (ISA_HAS_COND_TRAP)
535 return \"teq\\t$0,$0\";
540 (define_expand "conditional_trap"
541 [(trap_if (match_operator 0 "cmp_op"
542 [(match_dup 2) (match_dup 3)])
543 (match_operand 1 "const_int_operand" ""))]
547 mips_gen_conditional_trap (operands);
551 ;; Match a TRAP_IF with 2nd arg of 0. The div_trap_* insns match a
552 ;; 2nd arg of any CONST_INT, so this insn must appear first.
553 ;; gen_div_trap always generates TRAP_IF with 2nd arg of 6 or 7.
556 [(trap_if (match_operator 0 "trap_cmp_op"
557 [(match_operand:SI 1 "reg_or_0_operand" "d")
558 (match_operand:SI 2 "nonmemory_operand" "dI")])
564 ;; ....................
568 ;; ....................
571 (define_insn "adddf3"
572 [(set (match_operand:DF 0 "register_operand" "=f")
573 (plus:DF (match_operand:DF 1 "register_operand" "f")
574 (match_operand:DF 2 "register_operand" "f")))]
575 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
577 [(set_attr "type" "fadd")
578 (set_attr "mode" "DF")])
580 (define_insn "addsf3"
581 [(set (match_operand:SF 0 "register_operand" "=f")
582 (plus:SF (match_operand:SF 1 "register_operand" "f")
583 (match_operand:SF 2 "register_operand" "f")))]
586 [(set_attr "type" "fadd")
587 (set_attr "mode" "SF")])
589 (define_expand "addsi3"
590 [(set (match_operand:SI 0 "register_operand" "=d")
591 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
592 (match_operand:SI 2 "arith_operand" "dI")))]
596 /* The mips16 assembler handles -32768 correctly, and so does gas,
597 but some other MIPS assemblers think that -32768 needs to be
598 loaded into a register before it can be added in. */
601 && GET_CODE (operands[2]) == CONST_INT
602 && INTVAL (operands[2]) == -32768)
603 operands[2] = force_reg (SImode, operands[2]);
606 (define_insn "addsi3_internal"
607 [(set (match_operand:SI 0 "register_operand" "=d")
608 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
609 (match_operand:SI 2 "arith_operand" "dI")))]
612 || GET_CODE (operands[2]) != CONST_INT
613 || INTVAL (operands[2]) != -32768)"
615 [(set_attr "type" "arith")
616 (set_attr "mode" "SI")])
618 ;; For the mips16, we need to recognize stack pointer additions
619 ;; explicitly, since we don't have a constraint for $sp. These insns
620 ;; will be generated by the save_restore_insns functions.
625 (match_operand:SI 0 "small_int" "I")))]
628 [(set_attr "type" "arith")
629 (set_attr "mode" "SI")
630 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
635 [(set (match_operand:SI 0 "register_operand" "=d")
637 (match_operand:SI 1 "small_int" "I")))]
640 [(set_attr "type" "arith")
641 (set_attr "mode" "SI")
642 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
647 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
648 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
649 (match_operand:SI 2 "arith_operand" "IQ,O,d")))]
651 && (GET_CODE (operands[1]) != REG
652 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
653 || M16_REG_P (REGNO (operands[1]))
654 || REGNO (operands[1]) == ARG_POINTER_REGNUM
655 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
656 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
657 && (GET_CODE (operands[2]) != REG
658 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
659 || M16_REG_P (REGNO (operands[2]))
660 || REGNO (operands[2]) == ARG_POINTER_REGNUM
661 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
662 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
665 if (REGNO (operands[0]) == REGNO (operands[1]))
666 return \"addu\\t%0,%2\";
667 return \"addu\\t%0,%1,%2\";
669 [(set_attr "type" "arith")
670 (set_attr "mode" "SI")
671 (set_attr_alternative "length"
672 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
675 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
681 ;; On the mips16, we can sometimes split an add of a constant which is
682 ;; a 4 byte instruction into two adds which are both 2 byte
683 ;; instructions. There are two cases: one where we are adding a
684 ;; constant plus a register to another register, and one where we are
685 ;; simply adding a constant to a register.
688 [(set (match_operand:SI 0 "register_operand" "")
689 (plus:SI (match_dup 0)
690 (match_operand:SI 1 "const_int_operand" "")))]
691 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
692 && GET_CODE (operands[0]) == REG
693 && M16_REG_P (REGNO (operands[0]))
694 && GET_CODE (operands[1]) == CONST_INT
695 && ((INTVAL (operands[1]) > 0x7f
696 && INTVAL (operands[1]) <= 0x7f + 0x7f)
697 || (INTVAL (operands[1]) < - 0x80
698 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
699 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
700 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
703 HOST_WIDE_INT val = INTVAL (operands[1]);
707 operands[1] = GEN_INT (0x7f);
708 operands[2] = GEN_INT (val - 0x7f);
712 operands[1] = GEN_INT (- 0x80);
713 operands[2] = GEN_INT (val + 0x80);
718 [(set (match_operand:SI 0 "register_operand" "")
719 (plus:SI (match_operand:SI 1 "register_operand" "")
720 (match_operand:SI 2 "const_int_operand" "")))]
721 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
722 && GET_CODE (operands[0]) == REG
723 && M16_REG_P (REGNO (operands[0]))
724 && GET_CODE (operands[1]) == REG
725 && M16_REG_P (REGNO (operands[1]))
726 && REGNO (operands[0]) != REGNO (operands[1])
727 && GET_CODE (operands[2]) == CONST_INT
728 && ((INTVAL (operands[2]) > 0x7
729 && INTVAL (operands[2]) <= 0x7 + 0x7f)
730 || (INTVAL (operands[2]) < - 0x8
731 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
732 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
733 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
736 HOST_WIDE_INT val = INTVAL (operands[2]);
740 operands[2] = GEN_INT (0x7);
741 operands[3] = GEN_INT (val - 0x7);
745 operands[2] = GEN_INT (- 0x8);
746 operands[3] = GEN_INT (val + 0x8);
750 (define_expand "adddi3"
751 [(parallel [(set (match_operand:DI 0 "register_operand" "")
752 (plus:DI (match_operand:DI 1 "se_register_operand" "")
753 (match_operand:DI 2 "se_arith_operand" "")))
754 (clobber (match_dup 3))])]
755 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
758 /* The mips16 assembler handles -32768 correctly, and so does gas,
759 but some other MIPS assemblers think that -32768 needs to be
760 loaded into a register before it can be added in. */
763 && GET_CODE (operands[2]) == CONST_INT
764 && INTVAL (operands[2]) == -32768)
765 operands[2] = force_reg (DImode, operands[2]);
769 emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
774 operands[3] = gen_reg_rtx (SImode);
777 (define_insn "adddi3_internal_1"
778 [(set (match_operand:DI 0 "register_operand" "=d,&d")
779 (plus:DI (match_operand:DI 1 "register_operand" "0,d")
780 (match_operand:DI 2 "register_operand" "d,d")))
781 (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
782 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
785 return (REGNO (operands[0]) == REGNO (operands[1])
786 && REGNO (operands[0]) == REGNO (operands[2]))
787 ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
788 : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
790 [(set_attr "type" "darith")
791 (set_attr "mode" "DI")
792 (set_attr "length" "16")])
795 [(set (match_operand:DI 0 "register_operand" "")
796 (plus:DI (match_operand:DI 1 "register_operand" "")
797 (match_operand:DI 2 "register_operand" "")))
798 (clobber (match_operand:SI 3 "register_operand" ""))]
799 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
800 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
801 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
802 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
803 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
804 && (REGNO (operands[0]) != REGNO (operands[1])
805 || REGNO (operands[0]) != REGNO (operands[2]))"
807 [(set (subreg:SI (match_dup 0) 0)
808 (plus:SI (subreg:SI (match_dup 1) 0)
809 (subreg:SI (match_dup 2) 0)))
812 (ltu:SI (subreg:SI (match_dup 0) 0)
813 (subreg:SI (match_dup 2) 0)))
815 (set (subreg:SI (match_dup 0) 4)
816 (plus:SI (subreg:SI (match_dup 1) 4)
817 (subreg:SI (match_dup 2) 4)))
819 (set (subreg:SI (match_dup 0) 4)
820 (plus:SI (subreg:SI (match_dup 0) 4)
825 [(set (match_operand:DI 0 "register_operand" "")
826 (plus:DI (match_operand:DI 1 "register_operand" "")
827 (match_operand:DI 2 "register_operand" "")))
828 (clobber (match_operand:SI 3 "register_operand" ""))]
829 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
830 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
831 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
832 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
833 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
834 && (REGNO (operands[0]) != REGNO (operands[1])
835 || REGNO (operands[0]) != REGNO (operands[2]))"
837 [(set (subreg:SI (match_dup 0) 4)
838 (plus:SI (subreg:SI (match_dup 1) 4)
839 (subreg:SI (match_dup 2) 4)))
842 (ltu:SI (subreg:SI (match_dup 0) 4)
843 (subreg:SI (match_dup 2) 4)))
845 (set (subreg:SI (match_dup 0) 0)
846 (plus:SI (subreg:SI (match_dup 1) 0)
847 (subreg:SI (match_dup 2) 0)))
849 (set (subreg:SI (match_dup 0) 0)
850 (plus:SI (subreg:SI (match_dup 0) 0)
854 (define_insn "adddi3_internal_2"
855 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
856 (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
857 (match_operand:DI 2 "small_int" "P,J,N")))
858 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
859 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
861 || GET_CODE (operands[2]) != CONST_INT
862 || INTVAL (operands[2]) != -32768)"
864 addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
865 move\\t%L0,%L1\;move\\t%M0,%M1
866 subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
867 [(set_attr "type" "darith")
868 (set_attr "mode" "DI")
869 (set_attr "length" "12,8,16")])
872 [(set (match_operand:DI 0 "register_operand" "")
873 (plus:DI (match_operand:DI 1 "register_operand" "")
874 (match_operand:DI 2 "small_int" "")))
875 (clobber (match_operand:SI 3 "register_operand" ""))]
876 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
877 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
878 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
879 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
880 && INTVAL (operands[2]) > 0"
882 [(set (subreg:SI (match_dup 0) 0)
883 (plus:SI (subreg:SI (match_dup 1) 0)
887 (ltu:SI (subreg:SI (match_dup 0) 0)
890 (set (subreg:SI (match_dup 0) 4)
891 (plus:SI (subreg:SI (match_dup 1) 4)
896 [(set (match_operand:DI 0 "register_operand" "")
897 (plus:DI (match_operand:DI 1 "register_operand" "")
898 (match_operand:DI 2 "small_int" "")))
899 (clobber (match_operand:SI 3 "register_operand" ""))]
900 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
901 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
902 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
903 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
904 && INTVAL (operands[2]) > 0"
906 [(set (subreg:SI (match_dup 0) 4)
907 (plus:SI (subreg:SI (match_dup 1) 4)
911 (ltu:SI (subreg:SI (match_dup 0) 4)
914 (set (subreg:SI (match_dup 0) 0)
915 (plus:SI (subreg:SI (match_dup 1) 0)
919 (define_insn "adddi3_internal_3"
920 [(set (match_operand:DI 0 "register_operand" "=d")
921 (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
922 (match_operand:DI 2 "se_arith_operand" "dI")))]
926 || GET_CODE (operands[2]) != CONST_INT
927 || INTVAL (operands[2]) != -32768)"
930 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
931 ? \"dsubu\\t%0,%z1,%n2\"
932 : \"daddu\\t%0,%z1,%2\";
934 [(set_attr "type" "darith")
935 (set_attr "mode" "DI")])
937 ;; For the mips16, we need to recognize stack pointer additions
938 ;; explicitly, since we don't have a constraint for $sp. These insns
939 ;; will be generated by the save_restore_insns functions.
944 (match_operand:DI 0 "small_int" "I")))]
945 "TARGET_MIPS16 && TARGET_64BIT"
947 [(set_attr "type" "arith")
948 (set_attr "mode" "DI")
949 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
954 [(set (match_operand:DI 0 "register_operand" "=d")
956 (match_operand:DI 1 "small_int" "I")))]
957 "TARGET_MIPS16 && TARGET_64BIT"
959 [(set_attr "type" "arith")
960 (set_attr "mode" "DI")
961 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
966 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
967 (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
968 (match_operand:DI 2 "arith_operand" "IQ,O,d")))]
969 "TARGET_MIPS16 && TARGET_64BIT
970 && (GET_CODE (operands[1]) != REG
971 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
972 || M16_REG_P (REGNO (operands[1]))
973 || REGNO (operands[1]) == ARG_POINTER_REGNUM
974 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
975 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
976 && (GET_CODE (operands[2]) != REG
977 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
978 || M16_REG_P (REGNO (operands[2]))
979 || REGNO (operands[2]) == ARG_POINTER_REGNUM
980 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
981 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
984 if (REGNO (operands[0]) == REGNO (operands[1]))
985 return \"daddu\\t%0,%2\";
986 return \"daddu\\t%0,%1,%2\";
988 [(set_attr "type" "arith")
989 (set_attr "mode" "DI")
990 (set_attr_alternative "length"
991 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
994 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1000 ;; On the mips16, we can sometimes split an add of a constant which is
1001 ;; a 4 byte instruction into two adds which are both 2 byte
1002 ;; instructions. There are two cases: one where we are adding a
1003 ;; constant plus a register to another register, and one where we are
1004 ;; simply adding a constant to a register.
1007 [(set (match_operand:DI 0 "register_operand" "")
1008 (plus:DI (match_dup 0)
1009 (match_operand:DI 1 "const_int_operand" "")))]
1010 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1011 && GET_CODE (operands[0]) == REG
1012 && M16_REG_P (REGNO (operands[0]))
1013 && GET_CODE (operands[1]) == CONST_INT
1014 && ((INTVAL (operands[1]) > 0xf
1015 && INTVAL (operands[1]) <= 0xf + 0xf)
1016 || (INTVAL (operands[1]) < - 0x10
1017 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1018 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1019 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1022 HOST_WIDE_INT val = INTVAL (operands[1]);
1026 operands[1] = GEN_INT (0xf);
1027 operands[2] = GEN_INT (val - 0xf);
1031 operands[1] = GEN_INT (- 0x10);
1032 operands[2] = GEN_INT (val + 0x10);
1037 [(set (match_operand:DI 0 "register_operand" "")
1038 (plus:DI (match_operand:DI 1 "register_operand" "")
1039 (match_operand:DI 2 "const_int_operand" "")))]
1040 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1041 && GET_CODE (operands[0]) == REG
1042 && M16_REG_P (REGNO (operands[0]))
1043 && GET_CODE (operands[1]) == REG
1044 && M16_REG_P (REGNO (operands[1]))
1045 && REGNO (operands[0]) != REGNO (operands[1])
1046 && GET_CODE (operands[2]) == CONST_INT
1047 && ((INTVAL (operands[2]) > 0x7
1048 && INTVAL (operands[2]) <= 0x7 + 0xf)
1049 || (INTVAL (operands[2]) < - 0x8
1050 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1051 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1052 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1055 HOST_WIDE_INT val = INTVAL (operands[2]);
1059 operands[2] = GEN_INT (0x7);
1060 operands[3] = GEN_INT (val - 0x7);
1064 operands[2] = GEN_INT (- 0x8);
1065 operands[3] = GEN_INT (val + 0x8);
1069 (define_insn "addsi3_internal_2"
1070 [(set (match_operand:DI 0 "register_operand" "=d")
1071 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1072 (match_operand:SI 2 "arith_operand" "dI"))))]
1076 || GET_CODE (operands[2]) != CONST_INT
1077 || INTVAL (operands[2]) != -32768)"
1080 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1081 ? \"subu\\t%0,%z1,%n2\"
1082 : \"addu\\t%0,%z1,%2\";
1084 [(set_attr "type" "arith")
1085 (set_attr "mode" "SI")])
1088 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1089 (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1090 (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1091 "TARGET_MIPS16 && TARGET_64BIT"
1094 if (REGNO (operands[0]) == REGNO (operands[1]))
1095 return \"addu\\t%0,%2\";
1096 return \"addu\\t%0,%1,%2\";
1098 [(set_attr "type" "arith")
1099 (set_attr "mode" "SI")
1100 (set_attr_alternative "length"
1101 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
1104 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1111 ;; ....................
1115 ;; ....................
1118 (define_insn "subdf3"
1119 [(set (match_operand:DF 0 "register_operand" "=f")
1120 (minus:DF (match_operand:DF 1 "register_operand" "f")
1121 (match_operand:DF 2 "register_operand" "f")))]
1122 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1124 [(set_attr "type" "fadd")
1125 (set_attr "mode" "DF")])
1127 (define_insn "subsf3"
1128 [(set (match_operand:SF 0 "register_operand" "=f")
1129 (minus:SF (match_operand:SF 1 "register_operand" "f")
1130 (match_operand:SF 2 "register_operand" "f")))]
1133 [(set_attr "type" "fadd")
1134 (set_attr "mode" "SF")])
1136 (define_expand "subsi3"
1137 [(set (match_operand:SI 0 "register_operand" "=d")
1138 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1139 (match_operand:SI 2 "arith_operand" "dI")))]
1143 if (GET_CODE (operands[2]) == CONST_INT
1144 && (INTVAL (operands[2]) == -32768
1146 && INTVAL (operands[2]) == -0x4000)))
1147 operands[2] = force_reg (SImode, operands[2]);
1150 (define_insn "subsi3_internal"
1151 [(set (match_operand:SI 0 "register_operand" "=d")
1152 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1153 (match_operand:SI 2 "arith_operand" "dI")))]
1155 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1157 [(set_attr "type" "arith")
1158 (set_attr "mode" "SI")])
1160 ;; For the mips16, we need to recognize stack pointer subtractions
1161 ;; explicitly, since we don't have a constraint for $sp. These insns
1162 ;; will be generated by the save_restore_insns functions.
1166 (minus:SI (reg:SI 29)
1167 (match_operand:SI 0 "small_int" "I")))]
1169 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1171 [(set_attr "type" "arith")
1172 (set_attr "mode" "SI")
1173 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1178 [(set (match_operand:SI 0 "register_operand" "=d")
1179 (minus:SI (reg:SI 29)
1180 (match_operand:SI 1 "small_int" "I")))]
1182 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1184 [(set_attr "type" "arith")
1185 (set_attr "mode" "SI")
1186 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "")
1192 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1193 (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1194 (match_operand:SI 2 "arith_operand" "I,O,d")))]
1196 && (GET_CODE (operands[2]) != CONST_INT
1197 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1200 if (REGNO (operands[0]) == REGNO (operands[1]))
1201 return \"subu\\t%0,%2\";
1202 return \"subu\\t%0,%1,%2\";
1204 [(set_attr "type" "arith")
1205 (set_attr "mode" "SI")
1206 (set_attr_alternative "length"
1207 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1210 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1215 ;; On the mips16, we can sometimes split an subtract of a constant
1216 ;; which is a 4 byte instruction into two adds which are both 2 byte
1217 ;; instructions. There are two cases: one where we are setting a
1218 ;; register to a register minus a constant, and one where we are
1219 ;; simply subtracting a constant from a register.
1222 [(set (match_operand:SI 0 "register_operand" "")
1223 (minus:SI (match_dup 0)
1224 (match_operand:SI 1 "const_int_operand" "")))]
1225 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1226 && GET_CODE (operands[0]) == REG
1227 && M16_REG_P (REGNO (operands[0]))
1228 && GET_CODE (operands[1]) == CONST_INT
1229 && ((INTVAL (operands[1]) > 0x80
1230 && INTVAL (operands[1]) <= 0x80 + 0x80)
1231 || (INTVAL (operands[1]) < - 0x7f
1232 && INTVAL (operands[1]) >= - 0x7f - 0x7f))"
1233 [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1)))
1234 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1237 HOST_WIDE_INT val = INTVAL (operands[1]);
1241 operands[1] = GEN_INT (0x80);
1242 operands[2] = GEN_INT (val - 0x80);
1246 operands[1] = GEN_INT (- 0x7f);
1247 operands[2] = GEN_INT (val + 0x7f);
1252 [(set (match_operand:SI 0 "register_operand" "")
1253 (minus:SI (match_operand:SI 1 "register_operand" "")
1254 (match_operand:SI 2 "const_int_operand" "")))]
1255 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1256 && GET_CODE (operands[0]) == REG
1257 && M16_REG_P (REGNO (operands[0]))
1258 && GET_CODE (operands[1]) == REG
1259 && M16_REG_P (REGNO (operands[1]))
1260 && REGNO (operands[0]) != REGNO (operands[1])
1261 && GET_CODE (operands[2]) == CONST_INT
1262 && ((INTVAL (operands[2]) > 0x8
1263 && INTVAL (operands[2]) <= 0x8 + 0x80)
1264 || (INTVAL (operands[2]) < - 0x7
1265 && INTVAL (operands[2]) >= - 0x7 - 0x7f))"
1266 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1267 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))]
1270 HOST_WIDE_INT val = INTVAL (operands[2]);
1274 operands[2] = GEN_INT (0x8);
1275 operands[3] = GEN_INT (val - 0x8);
1279 operands[2] = GEN_INT (- 0x7);
1280 operands[3] = GEN_INT (val + 0x7);
1284 (define_expand "subdi3"
1285 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1286 (minus:DI (match_operand:DI 1 "se_register_operand" "d")
1287 (match_operand:DI 2 "se_register_operand" "d")))
1288 (clobber (match_dup 3))])]
1289 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
1294 emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1299 operands[3] = gen_reg_rtx (SImode);
1302 (define_insn "subdi3_internal"
1303 [(set (match_operand:DI 0 "register_operand" "=d")
1304 (minus:DI (match_operand:DI 1 "register_operand" "d")
1305 (match_operand:DI 2 "register_operand" "d")))
1306 (clobber (match_operand:SI 3 "register_operand" "=d"))]
1307 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
1308 "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
1309 [(set_attr "type" "darith")
1310 (set_attr "mode" "DI")
1311 (set_attr "length" "16")])
1314 [(set (match_operand:DI 0 "register_operand" "")
1315 (minus:DI (match_operand:DI 1 "register_operand" "")
1316 (match_operand:DI 2 "register_operand" "")))
1317 (clobber (match_operand:SI 3 "register_operand" ""))]
1318 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1319 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1320 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1321 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1322 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1325 (ltu:SI (subreg:SI (match_dup 1) 0)
1326 (subreg:SI (match_dup 2) 0)))
1328 (set (subreg:SI (match_dup 0) 0)
1329 (minus:SI (subreg:SI (match_dup 1) 0)
1330 (subreg:SI (match_dup 2) 0)))
1332 (set (subreg:SI (match_dup 0) 4)
1333 (minus:SI (subreg:SI (match_dup 1) 4)
1334 (subreg:SI (match_dup 2) 4)))
1336 (set (subreg:SI (match_dup 0) 4)
1337 (minus:SI (subreg:SI (match_dup 0) 4)
1342 [(set (match_operand:DI 0 "register_operand" "")
1343 (minus:DI (match_operand:DI 1 "register_operand" "")
1344 (match_operand:DI 2 "register_operand" "")))
1345 (clobber (match_operand:SI 3 "register_operand" ""))]
1346 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1347 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1348 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1349 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1350 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1353 (ltu:SI (subreg:SI (match_dup 1) 4)
1354 (subreg:SI (match_dup 2) 4)))
1356 (set (subreg:SI (match_dup 0) 4)
1357 (minus:SI (subreg:SI (match_dup 1) 4)
1358 (subreg:SI (match_dup 2) 4)))
1360 (set (subreg:SI (match_dup 0) 0)
1361 (minus:SI (subreg:SI (match_dup 1) 0)
1362 (subreg:SI (match_dup 2) 0)))
1364 (set (subreg:SI (match_dup 0) 0)
1365 (minus:SI (subreg:SI (match_dup 0) 0)
1369 (define_insn "subdi3_internal_2"
1370 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1371 (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
1372 (match_operand:DI 2 "small_int" "P,J,N")))
1373 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
1374 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1375 && INTVAL (operands[2]) != -32768"
1377 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
1378 move\\t%L0,%L1\;move\\t%M0,%M1
1379 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
1380 [(set_attr "type" "darith")
1381 (set_attr "mode" "DI")
1382 (set_attr "length" "12,8,16")])
1385 [(set (match_operand:DI 0 "register_operand" "")
1386 (minus:DI (match_operand:DI 1 "register_operand" "")
1387 (match_operand:DI 2 "small_int" "")))
1388 (clobber (match_operand:SI 3 "register_operand" ""))]
1389 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1390 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1391 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1392 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1393 && INTVAL (operands[2]) > 0"
1396 (ltu:SI (subreg:SI (match_dup 1) 0)
1399 (set (subreg:SI (match_dup 0) 0)
1400 (minus:SI (subreg:SI (match_dup 1) 0)
1403 (set (subreg:SI (match_dup 0) 4)
1404 (minus:SI (subreg:SI (match_dup 1) 4)
1409 [(set (match_operand:DI 0 "register_operand" "")
1410 (minus:DI (match_operand:DI 1 "register_operand" "")
1411 (match_operand:DI 2 "small_int" "")))
1412 (clobber (match_operand:SI 3 "register_operand" ""))]
1413 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1414 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1415 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1416 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1417 && INTVAL (operands[2]) > 0"
1420 (ltu:SI (subreg:SI (match_dup 1) 4)
1423 (set (subreg:SI (match_dup 0) 4)
1424 (minus:SI (subreg:SI (match_dup 1) 4)
1427 (set (subreg:SI (match_dup 0) 0)
1428 (minus:SI (subreg:SI (match_dup 1) 0)
1432 (define_insn "subdi3_internal_3"
1433 [(set (match_operand:DI 0 "register_operand" "=d")
1434 (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
1435 (match_operand:DI 2 "se_arith_operand" "dI")))]
1436 "TARGET_64BIT && !TARGET_MIPS16
1437 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1440 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1441 ? \"daddu\\t%0,%z1,%n2\"
1442 : \"dsubu\\t%0,%z1,%2\";
1444 [(set_attr "type" "darith")
1445 (set_attr "mode" "DI")])
1447 ;; For the mips16, we need to recognize stack pointer subtractions
1448 ;; explicitly, since we don't have a constraint for $sp. These insns
1449 ;; will be generated by the save_restore_insns functions.
1453 (minus:DI (reg:DI 29)
1454 (match_operand:DI 0 "small_int" "I")))]
1456 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1458 [(set_attr "type" "arith")
1459 (set_attr "mode" "DI")
1460 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1465 [(set (match_operand:DI 0 "register_operand" "=d")
1466 (minus:DI (reg:DI 29)
1467 (match_operand:DI 1 "small_int" "I")))]
1469 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1471 [(set_attr "type" "arith")
1472 (set_attr "mode" "DI")
1473 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "")
1478 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1479 (minus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1480 (match_operand:DI 2 "arith_operand" "I,O,d")))]
1482 && (GET_CODE (operands[2]) != CONST_INT
1483 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1486 if (REGNO (operands[0]) == REGNO (operands[1]))
1487 return \"dsubu\\t%0,%2\";
1488 return \"dsubu\\t%0,%1,%2\";
1490 [(set_attr "type" "arith")
1491 (set_attr "mode" "DI")
1492 (set_attr_alternative "length"
1493 [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "")
1496 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1501 ;; On the mips16, we can sometimes split an add of a constant which is
1502 ;; a 4 byte instruction into two adds which are both 2 byte
1503 ;; instructions. There are two cases: one where we are adding a
1504 ;; constant plus a register to another register, and one where we are
1505 ;; simply adding a constant to a register.
1508 [(set (match_operand:DI 0 "register_operand" "")
1509 (minus:DI (match_dup 0)
1510 (match_operand:DI 1 "const_int_operand" "")))]
1511 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1512 && GET_CODE (operands[0]) == REG
1513 && M16_REG_P (REGNO (operands[0]))
1514 && GET_CODE (operands[1]) == CONST_INT
1515 && ((INTVAL (operands[1]) > 0x10
1516 && INTVAL (operands[1]) <= 0x10 + 0x10)
1517 || (INTVAL (operands[1]) < - 0xf
1518 && INTVAL (operands[1]) >= - 0xf - 0xf))"
1519 [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1)))
1520 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
1523 HOST_WIDE_INT val = INTVAL (operands[1]);
1527 operands[1] = GEN_INT (0xf);
1528 operands[2] = GEN_INT (val - 0xf);
1532 operands[1] = GEN_INT (- 0x10);
1533 operands[2] = GEN_INT (val + 0x10);
1538 [(set (match_operand:DI 0 "register_operand" "")
1539 (minus:DI (match_operand:DI 1 "register_operand" "")
1540 (match_operand:DI 2 "const_int_operand" "")))]
1541 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1542 && GET_CODE (operands[0]) == REG
1543 && M16_REG_P (REGNO (operands[0]))
1544 && GET_CODE (operands[1]) == REG
1545 && M16_REG_P (REGNO (operands[1]))
1546 && REGNO (operands[0]) != REGNO (operands[1])
1547 && GET_CODE (operands[2]) == CONST_INT
1548 && ((INTVAL (operands[2]) > 0x8
1549 && INTVAL (operands[2]) <= 0x8 + 0x10)
1550 || (INTVAL (operands[2]) < - 0x7
1551 && INTVAL (operands[2]) >= - 0x7 - 0xf))"
1552 [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
1553 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))]
1556 HOST_WIDE_INT val = INTVAL (operands[2]);
1560 operands[2] = GEN_INT (0x8);
1561 operands[3] = GEN_INT (val - 0x8);
1565 operands[2] = GEN_INT (- 0x7);
1566 operands[3] = GEN_INT (val + 0x7);
1570 (define_insn "subsi3_internal_2"
1571 [(set (match_operand:DI 0 "register_operand" "=d")
1572 (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1573 (match_operand:SI 2 "arith_operand" "dI"))))]
1574 "TARGET_64BIT && !TARGET_MIPS16
1575 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1578 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1579 ? \"addu\\t%0,%z1,%n2\"
1580 : \"subu\\t%0,%z1,%2\";
1582 [(set_attr "type" "arith")
1583 (set_attr "mode" "DI")])
1586 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1587 (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1588 (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1589 "TARGET_64BIT && TARGET_MIPS16
1590 && (GET_CODE (operands[2]) != CONST_INT
1591 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1594 if (REGNO (operands[0]) == REGNO (operands[1]))
1595 return \"subu\\t%0,%2\";
1596 return \"subu\\t%0,%1,%2\";
1598 [(set_attr "type" "arith")
1599 (set_attr "mode" "SI")
1600 (set_attr_alternative "length"
1601 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1604 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1612 ;; ....................
1616 ;; ....................
1619 ;; Early Vr4300 silicon has a CPU bug where multiplies with certain
1620 ;; operands may corrupt immediately following multiplies. This is a
1621 ;; simple fix to insert NOPs.
1623 (define_expand "muldf3"
1624 [(set (match_operand:DF 0 "register_operand" "=f")
1625 (mult:DF (match_operand:DF 1 "register_operand" "f")
1626 (match_operand:DF 2 "register_operand" "f")))]
1627 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1630 if (!TARGET_MIPS4300)
1631 emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
1633 emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
1637 (define_insn "muldf3_internal"
1638 [(set (match_operand:DF 0 "register_operand" "=f")
1639 (mult:DF (match_operand:DF 1 "register_operand" "f")
1640 (match_operand:DF 2 "register_operand" "f")))]
1641 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_MIPS4300"
1643 [(set_attr "type" "fmul")
1644 (set_attr "mode" "DF")])
1646 (define_insn "muldf3_r4300"
1647 [(set (match_operand:DF 0 "register_operand" "=f")
1648 (mult:DF (match_operand:DF 1 "register_operand" "f")
1649 (match_operand:DF 2 "register_operand" "f")))]
1650 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_MIPS4300"
1653 output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
1654 if (TARGET_4300_MUL_FIX)
1655 output_asm_insn (\"nop\", operands);
1658 [(set_attr "type" "fmul")
1659 (set_attr "mode" "DF")
1660 (set_attr "length" "8")]) ;; mul.d + nop
1662 (define_expand "mulsf3"
1663 [(set (match_operand:SF 0 "register_operand" "=f")
1664 (mult:SF (match_operand:SF 1 "register_operand" "f")
1665 (match_operand:SF 2 "register_operand" "f")))]
1669 if (!TARGET_MIPS4300)
1670 emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
1672 emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
1676 (define_insn "mulsf3_internal"
1677 [(set (match_operand:SF 0 "register_operand" "=f")
1678 (mult:SF (match_operand:SF 1 "register_operand" "f")
1679 (match_operand:SF 2 "register_operand" "f")))]
1680 "TARGET_HARD_FLOAT && !TARGET_MIPS4300"
1682 [(set_attr "type" "fmul")
1683 (set_attr "mode" "SF")])
1685 (define_insn "mulsf3_r4300"
1686 [(set (match_operand:SF 0 "register_operand" "=f")
1687 (mult:SF (match_operand:SF 1 "register_operand" "f")
1688 (match_operand:SF 2 "register_operand" "f")))]
1689 "TARGET_HARD_FLOAT && TARGET_MIPS4300"
1692 output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1693 if (TARGET_4300_MUL_FIX)
1694 output_asm_insn (\"nop\", operands);
1697 [(set_attr "type" "fmul")
1698 (set_attr "mode" "SF")
1699 (set_attr "length" "8")]) ;; mul.s + nop
1702 ;; ??? The R4000 (only) has a cpu bug. If a double-word shift executes while
1703 ;; a multiply is in progress, it may give an incorrect result. Avoid
1704 ;; this by keeping the mflo with the mult on the R4000.
1706 (define_expand "mulsi3"
1707 [(set (match_operand:SI 0 "register_operand" "=l")
1708 (mult:SI (match_operand:SI 1 "register_operand" "d")
1709 (match_operand:SI 2 "register_operand" "d")))
1710 (clobber (match_scratch:SI 3 "=h"))
1711 (clobber (match_scratch:SI 4 "=a"))]
1715 if (GENERATE_MULT3_SI || TARGET_MAD)
1716 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1717 else if (!TARGET_MIPS4000 || TARGET_MIPS16)
1718 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1720 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1724 (define_insn "mulsi3_mult3"
1725 [(set (match_operand:SI 0 "register_operand" "=d,l")
1726 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1727 (match_operand:SI 2 "register_operand" "d,d")))
1728 (clobber (match_scratch:SI 3 "=h,h"))
1729 (clobber (match_scratch:SI 4 "=l,X"))
1730 (clobber (match_scratch:SI 5 "=a,a"))]
1735 if (which_alternative == 1)
1736 return \"mult\\t%1,%2\";
1740 return \"mul\\t%0,%1,%2\";
1741 return \"mult\\t%0,%1,%2\";
1743 [(set_attr "type" "imul")
1744 (set_attr "mode" "SI")])
1746 (define_insn "mulsi3_internal"
1747 [(set (match_operand:SI 0 "register_operand" "=l")
1748 (mult:SI (match_operand:SI 1 "register_operand" "d")
1749 (match_operand:SI 2 "register_operand" "d")))
1750 (clobber (match_scratch:SI 3 "=h"))
1751 (clobber (match_scratch:SI 4 "=a"))]
1752 "!TARGET_MIPS4000 || TARGET_MIPS16"
1754 [(set_attr "type" "imul")
1755 (set_attr "mode" "SI")])
1757 (define_insn "mulsi3_r4000"
1758 [(set (match_operand:SI 0 "register_operand" "=d")
1759 (mult:SI (match_operand:SI 1 "register_operand" "d")
1760 (match_operand:SI 2 "register_operand" "d")))
1761 (clobber (match_scratch:SI 3 "=h"))
1762 (clobber (match_scratch:SI 4 "=l"))
1763 (clobber (match_scratch:SI 5 "=a"))]
1764 "TARGET_MIPS4000 && !TARGET_MIPS16"
1769 xoperands[0] = operands[0];
1770 xoperands[1] = gen_rtx_REG (SImode, LO_REGNUM);
1772 output_asm_insn (\"mult\\t%1,%2\", operands);
1773 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1776 [(set_attr "type" "imul")
1777 (set_attr "mode" "SI")
1778 (set_attr "length" "12")]) ;; mult + mflo + delay
1780 ;; Multiply-accumulate patterns
1782 ;; For processors that can copy the output to a general register:
1784 ;; The all-d alternative is needed because the combiner will find this
1785 ;; pattern and then register alloc/reload will move registers around to
1786 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1788 ;; The last alternative should be made slightly less desirable, but adding
1789 ;; "?" to the constraint is too strong, and causes values to be loaded into
1790 ;; LO even when that's more costly. For now, using "*d" mostly does the
1792 (define_insn "*mul_acc_si"
1793 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1794 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1795 (match_operand:SI 2 "register_operand" "d,d,d"))
1796 (match_operand:SI 3 "register_operand" "0,l,*d")))
1797 (clobber (match_scratch:SI 4 "=h,h,h"))
1798 (clobber (match_scratch:SI 5 "=X,3,l"))
1799 (clobber (match_scratch:SI 6 "=a,a,a"))
1800 (clobber (match_scratch:SI 7 "=X,X,d"))]
1802 || ISA_HAS_MADD_MSUB)
1806 static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" };
1807 if (which_alternative == 2)
1809 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1811 return madd[which_alternative];
1813 [(set_attr "type" "imul,imul,multi")
1814 (set_attr "mode" "SI")
1815 (set_attr "length" "4,4,8")])
1817 ;; Split the above insn if we failed to get LO allocated.
1819 [(set (match_operand:SI 0 "register_operand" "")
1820 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1821 (match_operand:SI 2 "register_operand" ""))
1822 (match_operand:SI 3 "register_operand" "")))
1823 (clobber (match_scratch:SI 4 ""))
1824 (clobber (match_scratch:SI 5 ""))
1825 (clobber (match_scratch:SI 6 ""))
1826 (clobber (match_scratch:SI 7 ""))]
1827 "reload_completed && !TARGET_DEBUG_D_MODE
1828 && GP_REG_P (true_regnum (operands[0]))
1829 && GP_REG_P (true_regnum (operands[3]))"
1830 [(parallel [(set (match_dup 7)
1831 (mult:SI (match_dup 1) (match_dup 2)))
1832 (clobber (match_dup 4))
1833 (clobber (match_dup 5))
1834 (clobber (match_dup 6))])
1835 (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 3)))]
1838 ;; Splitter to copy result of MADD to a general register
1840 [(set (match_operand:SI 0 "register_operand" "")
1841 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1842 (match_operand:SI 2 "register_operand" ""))
1843 (match_operand:SI 3 "register_operand" "")))
1844 (clobber (match_scratch:SI 4 ""))
1845 (clobber (match_scratch:SI 5 ""))
1846 (clobber (match_scratch:SI 6 ""))
1847 (clobber (match_scratch:SI 7 ""))]
1848 "reload_completed && !TARGET_DEBUG_D_MODE
1849 && GP_REG_P (true_regnum (operands[0]))
1850 && true_regnum (operands[3]) == LO_REGNUM"
1851 [(parallel [(set (match_dup 3)
1852 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1854 (clobber (match_dup 4))
1855 (clobber (match_dup 5))
1856 (clobber (match_dup 6))
1857 (clobber (match_dup 7))])
1858 (set (match_dup 0) (match_dup 3))]
1861 (define_insn "*mul_sub_si"
1862 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1863 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1864 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1865 (match_operand:SI 3 "register_operand" "d,d,d"))))
1866 (clobber (match_scratch:SI 4 "=h,h,h"))
1867 (clobber (match_scratch:SI 5 "=X,3,l"))
1868 (clobber (match_scratch:SI 6 "=a,a,a"))
1869 (clobber (match_scratch:SI 7 "=X,X,d"))]
1873 if (which_alternative != 0)
1875 return \"msub\\t%2,%3\";
1877 [(set_attr "type" "imul,imul,multi")
1878 (set_attr "mode" "SI")
1879 (set_attr "length" "4,8,8")])
1881 ;; Split the above insn if we failed to get LO allocated.
1883 [(set (match_operand:SI 0 "register_operand" "")
1884 (minus:SI (match_operand:SI 1 "register_operand" "")
1885 (mult:SI (match_operand:SI 2 "register_operand" "")
1886 (match_operand:SI 3 "register_operand" ""))))
1887 (clobber (match_scratch:SI 4 ""))
1888 (clobber (match_scratch:SI 5 ""))
1889 (clobber (match_scratch:SI 6 ""))
1890 (clobber (match_scratch:SI 7 ""))]
1891 "reload_completed && !TARGET_DEBUG_D_MODE
1892 && GP_REG_P (true_regnum (operands[0]))
1893 && GP_REG_P (true_regnum (operands[1]))"
1894 [(parallel [(set (match_dup 7)
1895 (mult:SI (match_dup 2) (match_dup 3)))
1896 (clobber (match_dup 4))
1897 (clobber (match_dup 5))
1898 (clobber (match_dup 6))])
1899 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
1902 ;; Splitter to copy result of MSUB to a general register
1904 [(set (match_operand:SI 0 "register_operand" "")
1905 (minus:SI (match_operand:SI 1 "register_operand" "")
1906 (mult:SI (match_operand:SI 2 "register_operand" "")
1907 (match_operand:SI 3 "register_operand" ""))))
1908 (clobber (match_scratch:SI 4 ""))
1909 (clobber (match_scratch:SI 5 ""))
1910 (clobber (match_scratch:SI 6 ""))
1911 (clobber (match_scratch:SI 7 ""))]
1912 "reload_completed && !TARGET_DEBUG_D_MODE
1913 && GP_REG_P (true_regnum (operands[0]))
1914 && true_regnum (operands[1]) == LO_REGNUM"
1915 [(parallel [(set (match_dup 1)
1916 (minus:SI (match_dup 1)
1917 (mult:SI (match_dup 2) (match_dup 3))))
1918 (clobber (match_dup 4))
1919 (clobber (match_dup 5))
1920 (clobber (match_dup 6))
1921 (clobber (match_dup 7))])
1922 (set (match_dup 0) (match_dup 1))]
1927 [(set (match_operand:SI 0 "register_operand" "")
1928 (minus:SI (match_operand:SI 1 "register_operand" "")
1929 (mult:SI (match_operand:SI 2 "register_operand" "")
1930 (match_operand:SI 3 "register_operand" ""))))
1931 (clobber (match_scratch:SI 4 ""))
1932 (clobber (match_scratch:SI 5 ""))
1933 (clobber (match_scratch:SI 6 ""))
1934 (clobber (match_scratch:SI 7 ""))]
1935 "reload_completed && !TARGET_DEBUG_D_MODE
1936 && GP_REG_P (true_regnum (operands[0]))
1937 && GP_REG_P (true_regnum (operands[1]))"
1938 [(parallel [(set (match_dup 7)
1939 (mult:SI (match_dup 2) (match_dup 3)))
1940 (clobber (match_dup 4))
1941 (clobber (match_dup 5))
1942 (clobber (match_dup 6))])
1943 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
1946 (define_expand "muldi3"
1947 [(set (match_operand:DI 0 "register_operand" "=l")
1948 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1949 (match_operand:DI 2 "register_operand" "d")))
1950 (clobber (match_scratch:DI 3 "=h"))
1951 (clobber (match_scratch:DI 4 "=a"))]
1956 if (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)
1957 emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
1959 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1963 ;; Don't accept both operands using se_register_operand, because if
1964 ;; both operands are sign extended we would prefer to use mult in the
1965 ;; mulsidi3 pattern. Commutativity should permit either operand to be
1968 (define_insn "muldi3_internal"
1969 [(set (match_operand:DI 0 "register_operand" "=l")
1970 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1971 (match_operand:DI 2 "register_operand" "d")))
1972 (clobber (match_scratch:DI 3 "=h"))
1973 (clobber (match_scratch:DI 4 "=a"))]
1974 "TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16"
1976 [(set_attr "type" "imul")
1977 (set_attr "mode" "DI")])
1979 (define_insn "muldi3_internal2"
1980 [(set (match_operand:DI 0 "register_operand" "=d")
1981 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1982 (match_operand:DI 2 "register_operand" "d")))
1983 (clobber (match_scratch:DI 3 "=h"))
1984 (clobber (match_scratch:DI 4 "=l"))
1985 (clobber (match_scratch:DI 5 "=a"))]
1986 "TARGET_64BIT && (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)"
1989 if (GENERATE_MULT3_DI)
1990 output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
1995 xoperands[0] = operands[0];
1996 xoperands[1] = gen_rtx_REG (DImode, LO_REGNUM);
1998 output_asm_insn (\"dmult\\t%1,%2\", operands);
1999 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2003 [(set_attr "type" "imul")
2004 (set_attr "mode" "DI")
2005 (set (attr "length")
2006 (if_then_else (ne (symbol_ref "GENERATE_MULT3_DI") (const_int 0))
2008 (const_int 12)))]) ;; mult + mflo + delay
2010 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
2012 (define_expand "mulsidi3"
2013 [(set (match_operand:DI 0 "register_operand" "=x")
2014 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2015 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
2019 rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
2021 emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
2024 emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
2029 (define_expand "umulsidi3"
2030 [(set (match_operand:DI 0 "register_operand" "=x")
2031 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2032 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
2036 rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
2038 emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
2041 emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
2046 (define_insn "mulsidi3_internal"
2047 [(set (match_operand:DI 0 "register_operand" "=x")
2048 (mult:DI (match_operator:DI 3 "extend_operator"
2049 [(match_operand:SI 1 "register_operand" "d")])
2050 (match_operator:DI 4 "extend_operator"
2051 [(match_operand:SI 2 "register_operand" "d")])))
2052 (clobber (match_scratch:SI 5 "=a"))]
2053 "!TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2056 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2057 return \"mult\\t%1,%2\";
2058 return \"multu\\t%1,%2\";
2060 [(set_attr "type" "imul")
2061 (set_attr "mode" "SI")])
2063 (define_insn "mulsidi3_64bit"
2064 [(set (match_operand:DI 0 "register_operand" "=a")
2065 (mult:DI (match_operator:DI 3 "extend_operator"
2066 [(match_operand:SI 1 "register_operand" "d")])
2067 (match_operator:DI 4 "extend_operator"
2068 [(match_operand:SI 2 "register_operand" "d")])))
2069 (clobber (match_scratch:DI 5 "=l"))
2070 (clobber (match_scratch:DI 6 "=h"))]
2071 "TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2074 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2075 return \"mult\\t%1,%2\";
2076 return \"multu\\t%1,%2\";
2078 [(set_attr "type" "imul")
2079 (set_attr "mode" "SI")])
2081 ;; _highpart patterns
2082 (define_expand "smulsi3_highpart"
2083 [(set (match_operand:SI 0 "register_operand" "=h")
2085 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2086 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2091 rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
2092 rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
2093 #ifndef NO_MD_PROTOTYPES
2094 rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
2098 genfn = gen_xmulsi3_highpart_internal;
2099 emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
2104 (define_expand "umulsi3_highpart"
2105 [(set (match_operand:SI 0 "register_operand" "=h")
2107 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2108 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2113 rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
2114 rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
2115 #ifndef NO_MD_PROTOTYPES
2116 rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
2120 genfn = gen_xmulsi3_highpart_internal;
2121 emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
2126 (define_insn "xmulsi3_highpart_internal"
2127 [(set (match_operand:SI 0 "register_operand" "=h")
2129 (match_operator:DI 5 "highpart_shift_operator"
2130 [(mult:DI (match_operator:DI 3 "extend_operator"
2131 [(match_operand:SI 1 "register_operand" "d")])
2132 (match_operator:DI 4 "extend_operator"
2133 [(match_operand:SI 2 "register_operand" "d")]))
2135 (clobber (match_scratch:SI 6 "=l"))
2136 (clobber (match_scratch:SI 7 "=a"))]
2137 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
2140 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2141 return \"mult\\t%1,%2\";
2143 return \"multu\\t%1,%2\";
2145 [(set_attr "type" "imul")
2146 (set_attr "mode" "SI")])
2148 (define_insn "smuldi3_highpart"
2149 [(set (match_operand:DI 0 "register_operand" "=h")
2151 (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2152 (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
2154 (clobber (match_scratch:DI 3 "=l"))
2155 (clobber (match_scratch:DI 4 "=a"))]
2158 [(set_attr "type" "imul")
2159 (set_attr "mode" "DI")])
2161 (define_insn "umuldi3_highpart"
2162 [(set (match_operand:DI 0 "register_operand" "=h")
2164 (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2165 (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
2167 (clobber (match_scratch:DI 3 "=l"))
2168 (clobber (match_scratch:DI 4 "=a"))]
2171 [(set_attr "type" "imul")
2172 (set_attr "mode" "DI")])
2174 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2175 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
2177 (define_insn "madsi"
2178 [(set (match_operand:SI 0 "register_operand" "+l")
2179 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2180 (match_operand:SI 2 "register_operand" "d"))
2182 (clobber (match_scratch:SI 3 "=h"))
2183 (clobber (match_scratch:SI 4 "=a"))]
2186 [(set_attr "type" "imul")
2187 (set_attr "mode" "SI")])
2189 (define_insn "*mul_acc_di"
2190 [(set (match_operand:DI 0 "register_operand" "+x")
2191 (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2192 [(match_operand:SI 1 "register_operand" "d")])
2193 (match_operator:DI 4 "extend_operator"
2194 [(match_operand:SI 2 "register_operand" "d")]))
2196 (clobber (match_scratch:SI 5 "=a"))]
2199 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2202 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2203 return \"mad\\t%1,%2\";
2205 return \"madu\\t%1,%2\";
2207 [(set_attr "type" "imul")
2208 (set_attr "mode" "SI")])
2210 (define_insn "*mul_acc_64bit_di"
2211 [(set (match_operand:DI 0 "register_operand" "+a")
2212 (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2213 [(match_operand:SI 1 "register_operand" "d")])
2214 (match_operator:DI 4 "extend_operator"
2215 [(match_operand:SI 2 "register_operand" "d")]))
2217 (clobber (match_scratch:SI 5 "=h"))
2218 (clobber (match_scratch:SI 6 "=l"))]
2221 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2224 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2225 return \"mad\\t%1,%2\";
2227 return \"madu\\t%1,%2\";
2229 [(set_attr "type" "imul")
2230 (set_attr "mode" "SI")])
2232 ;; Floating point multiply accumulate instructions.
2235 [(set (match_operand:DF 0 "register_operand" "=f")
2236 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2237 (match_operand:DF 2 "register_operand" "f"))
2238 (match_operand:DF 3 "register_operand" "f")))]
2239 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2240 "madd.d\\t%0,%3,%1,%2"
2241 [(set_attr "type" "fmadd")
2242 (set_attr "mode" "DF")])
2245 [(set (match_operand:SF 0 "register_operand" "=f")
2246 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2247 (match_operand:SF 2 "register_operand" "f"))
2248 (match_operand:SF 3 "register_operand" "f")))]
2249 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2250 "madd.s\\t%0,%3,%1,%2"
2251 [(set_attr "type" "fmadd")
2252 (set_attr "mode" "SF")])
2255 [(set (match_operand:DF 0 "register_operand" "=f")
2256 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2257 (match_operand:DF 2 "register_operand" "f"))
2258 (match_operand:DF 3 "register_operand" "f")))]
2259 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2260 "msub.d\\t%0,%3,%1,%2"
2261 [(set_attr "type" "fmadd")
2262 (set_attr "mode" "DF")])
2265 [(set (match_operand:SF 0 "register_operand" "=f")
2266 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2267 (match_operand:SF 2 "register_operand" "f"))
2268 (match_operand:SF 3 "register_operand" "f")))]
2270 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2271 "msub.s\\t%0,%3,%1,%2"
2272 [(set_attr "type" "fmadd")
2273 (set_attr "mode" "SF")])
2276 [(set (match_operand:DF 0 "register_operand" "=f")
2277 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2278 (match_operand:DF 2 "register_operand" "f"))
2279 (match_operand:DF 3 "register_operand" "f"))))]
2280 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2281 "nmadd.d\\t%0,%3,%1,%2"
2282 [(set_attr "type" "fmadd")
2283 (set_attr "mode" "DF")])
2286 [(set (match_operand:SF 0 "register_operand" "=f")
2287 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2288 (match_operand:SF 2 "register_operand" "f"))
2289 (match_operand:SF 3 "register_operand" "f"))))]
2290 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2291 "nmadd.s\\t%0,%3,%1,%2"
2292 [(set_attr "type" "fmadd")
2293 (set_attr "mode" "SF")])
2296 [(set (match_operand:DF 0 "register_operand" "=f")
2297 (minus:DF (match_operand:DF 1 "register_operand" "f")
2298 (mult:DF (match_operand:DF 2 "register_operand" "f")
2299 (match_operand:DF 3 "register_operand" "f"))))]
2300 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2301 "nmsub.d\\t%0,%1,%2,%3"
2302 [(set_attr "type" "fmadd")
2303 (set_attr "mode" "DF")])
2306 [(set (match_operand:SF 0 "register_operand" "=f")
2307 (minus:SF (match_operand:SF 1 "register_operand" "f")
2308 (mult:SF (match_operand:SF 2 "register_operand" "f")
2309 (match_operand:SF 3 "register_operand" "f"))))]
2310 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2311 "nmsub.s\\t%0,%1,%2,%3"
2312 [(set_attr "type" "fmadd")
2313 (set_attr "mode" "SF")])
2316 ;; ....................
2318 ;; DIVISION and REMAINDER
2320 ;; ....................
2323 (define_insn "divdf3"
2324 [(set (match_operand:DF 0 "register_operand" "=f")
2325 (div:DF (match_operand:DF 1 "register_operand" "f")
2326 (match_operand:DF 2 "register_operand" "f")))]
2327 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2329 [(set_attr "type" "fdiv")
2330 (set_attr "mode" "DF")])
2332 (define_insn "divsf3"
2333 [(set (match_operand:SF 0 "register_operand" "=f")
2334 (div:SF (match_operand:SF 1 "register_operand" "f")
2335 (match_operand:SF 2 "register_operand" "f")))]
2338 [(set_attr "type" "fdiv")
2339 (set_attr "mode" "SF")])
2342 [(set (match_operand:DF 0 "register_operand" "=f")
2343 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2344 (match_operand:DF 2 "register_operand" "f")))]
2345 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2347 [(set_attr "type" "fdiv")
2348 (set_attr "mode" "DF")])
2351 [(set (match_operand:SF 0 "register_operand" "=f")
2352 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2353 (match_operand:SF 2 "register_operand" "f")))]
2354 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2356 [(set_attr "type" "fdiv")
2357 (set_attr "mode" "SF")])
2359 ;; If optimizing, prefer the divmod functions over separate div and
2360 ;; mod functions, since this will allow using one instruction for both
2361 ;; the quotient and remainder. At present, the divmod is not moved out
2362 ;; of loops if it is constant within the loop, so allow -mdebugc to
2363 ;; use the old method of doing things.
2365 ;; 64 is the multiply/divide hi register
2366 ;; 65 is the multiply/divide lo register
2368 ;; ??? We can't accept constants here, because the MIPS assembler will replace
2369 ;; a divide by power of 2 with a shift, and then the remainder is no longer
2372 (define_expand "divmodsi4"
2373 [(set (match_operand:SI 0 "register_operand" "=d")
2374 (div:SI (match_operand:SI 1 "register_operand" "d")
2375 (match_operand:SI 2 "register_operand" "d")))
2376 (set (match_operand:SI 3 "register_operand" "=d")
2377 (mod:SI (match_dup 1)
2379 (clobber (match_scratch:SI 4 "=l"))
2380 (clobber (match_scratch:SI 5 "=h"))
2381 (clobber (match_scratch:SI 6 "=a"))]
2385 emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2],
2387 if (!TARGET_NO_CHECK_ZERO_DIV)
2389 emit_insn (gen_div_trap (operands[2],
2393 if (TARGET_CHECK_RANGE_DIV)
2395 emit_insn (gen_div_trap (operands[2],
2396 copy_to_mode_reg (SImode, GEN_INT (-1)),
2398 emit_insn (gen_div_trap (operands[2],
2399 copy_to_mode_reg (SImode,
2402 (BITMASK_HIGH, SImode))),
2409 (define_insn "divmodsi4_internal"
2410 [(set (match_operand:SI 0 "register_operand" "=l")
2411 (div:SI (match_operand:SI 1 "register_operand" "d")
2412 (match_operand:SI 2 "register_operand" "d")))
2413 (set (match_operand:SI 3 "register_operand" "=h")
2414 (mod:SI (match_dup 1)
2416 (clobber (match_scratch:SI 4 "=a"))]
2419 [(set_attr "type" "idiv")
2420 (set_attr "mode" "SI")])
2422 (define_expand "divmoddi4"
2423 [(set (match_operand:DI 0 "register_operand" "=d")
2424 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2425 (match_operand:DI 2 "se_register_operand" "d")))
2426 (set (match_operand:DI 3 "register_operand" "=d")
2427 (mod:DI (match_dup 1)
2429 (clobber (match_scratch:DI 4 "=l"))
2430 (clobber (match_scratch:DI 5 "=h"))
2431 (clobber (match_scratch:DI 6 "=a"))]
2432 "TARGET_64BIT && optimize"
2435 emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2],
2437 if (!TARGET_NO_CHECK_ZERO_DIV)
2439 emit_insn (gen_div_trap (operands[2],
2443 if (TARGET_CHECK_RANGE_DIV)
2445 emit_insn (gen_div_trap (operands[2],
2446 copy_to_mode_reg (DImode, GEN_INT (-1)),
2448 emit_insn (gen_div_trap (operands[2],
2449 copy_to_mode_reg (DImode,
2450 GEN_INT (BITMASK_HIGH)),
2457 (define_insn "divmoddi4_internal"
2458 [(set (match_operand:DI 0 "register_operand" "=l")
2459 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2460 (match_operand:DI 2 "se_register_operand" "d")))
2461 (set (match_operand:DI 3 "register_operand" "=h")
2462 (mod:DI (match_dup 1)
2464 (clobber (match_scratch:DI 4 "=a"))]
2465 "TARGET_64BIT && optimize"
2467 [(set_attr "type" "idiv")
2468 (set_attr "mode" "SI")])
2470 (define_expand "udivmodsi4"
2471 [(set (match_operand:SI 0 "register_operand" "=d")
2472 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2473 (match_operand:SI 2 "register_operand" "d")))
2474 (set (match_operand:SI 3 "register_operand" "=d")
2475 (umod:SI (match_dup 1)
2477 (clobber (match_scratch:SI 4 "=l"))
2478 (clobber (match_scratch:SI 5 "=h"))
2479 (clobber (match_scratch:SI 6 "=a"))]
2483 emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2],
2485 if (!TARGET_NO_CHECK_ZERO_DIV)
2487 emit_insn (gen_div_trap (operands[2],
2495 (define_insn "udivmodsi4_internal"
2496 [(set (match_operand:SI 0 "register_operand" "=l")
2497 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2498 (match_operand:SI 2 "register_operand" "d")))
2499 (set (match_operand:SI 3 "register_operand" "=h")
2500 (umod:SI (match_dup 1)
2502 (clobber (match_scratch:SI 4 "=a"))]
2505 [(set_attr "type" "idiv")
2506 (set_attr "mode" "SI")])
2508 (define_expand "udivmoddi4"
2509 [(set (match_operand:DI 0 "register_operand" "=d")
2510 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2511 (match_operand:DI 2 "se_register_operand" "d")))
2512 (set (match_operand:DI 3 "register_operand" "=d")
2513 (umod:DI (match_dup 1)
2515 (clobber (match_scratch:DI 4 "=l"))
2516 (clobber (match_scratch:DI 5 "=h"))
2517 (clobber (match_scratch:DI 6 "=a"))]
2518 "TARGET_64BIT && optimize"
2521 emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2],
2523 if (!TARGET_NO_CHECK_ZERO_DIV)
2525 emit_insn (gen_div_trap (operands[2],
2533 (define_insn "udivmoddi4_internal"
2534 [(set (match_operand:DI 0 "register_operand" "=l")
2535 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2536 (match_operand:DI 2 "se_register_operand" "d")))
2537 (set (match_operand:DI 3 "register_operand" "=h")
2538 (umod:DI (match_dup 1)
2540 (clobber (match_scratch:DI 4 "=a"))]
2541 "TARGET_64BIT && optimize"
2543 [(set_attr "type" "idiv")
2544 (set_attr "mode" "SI")])
2548 (define_expand "div_trap"
2549 [(trap_if (eq (match_operand 0 "register_operand" "d")
2550 (match_operand 1 "true_reg_or_0_operand" "dJ"))
2551 (match_operand 2 "immediate_operand" ""))]
2556 emit_insn (gen_div_trap_mips16 (operands[0],operands[1],operands[2]));
2558 emit_insn (gen_div_trap_normal (operands[0],operands[1],operands[2]));
2562 (define_insn "div_trap_normal"
2563 [(trap_if (eq (match_operand 0 "register_operand" "d,d")
2564 (match_operand 1 "true_reg_or_0_operand" "d,J"))
2565 (match_operand 2 "immediate_operand" ""))]
2570 int have_dep_anti = 0;
2572 /* For divmod if one division is not needed then we don't need an extra
2573 divide by zero trap, which is anti dependent on previous trap */
2574 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2576 if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2577 && GET_CODE (XEXP (link, 0)) == INSN
2578 && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2579 && which_alternative == 1)
2581 if (! have_dep_anti)
2583 if (GENERATE_BRANCHLIKELY)
2585 if (which_alternative == 1)
2586 return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2588 return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2592 if (which_alternative == 1)
2593 return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2595 return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2600 [(set_attr "type" "unknown")
2601 (set_attr "length" "12")])
2604 ;; The mips16 bne insns is a macro which uses reg 24 as an intermediate.
2606 (define_insn "div_trap_mips16"
2607 [(trap_if (eq (match_operand 0 "register_operand" "d,d")
2608 (match_operand 1 "true_reg_or_0_operand" "d,J"))
2609 (match_operand 2 "immediate_operand" ""))
2610 (clobber (reg:SI 24))]
2615 int have_dep_anti = 0;
2617 /* For divmod if one division is not needed then we don't need an extra
2618 divide by zero trap, which is anti dependent on previous trap */
2619 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2621 if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2622 && GET_CODE (XEXP (link, 0)) == INSN
2623 && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2624 && which_alternative == 1)
2626 if (! have_dep_anti)
2628 /* No branch delay slots on mips16. */
2629 if (which_alternative == 1)
2630 return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2632 return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2636 [(set_attr "type" "unknown")
2637 (set_attr "length" "12")])
2639 (define_expand "divsi3"
2640 [(set (match_operand:SI 0 "register_operand" "=l")
2641 (div:SI (match_operand:SI 1 "register_operand" "d")
2642 (match_operand:SI 2 "register_operand" "d")))
2643 (clobber (match_scratch:SI 3 "=h"))
2644 (clobber (match_scratch:SI 4 "=a"))]
2648 emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2]));
2649 if (!TARGET_NO_CHECK_ZERO_DIV)
2651 emit_insn (gen_div_trap (operands[2],
2655 if (TARGET_CHECK_RANGE_DIV)
2657 emit_insn (gen_div_trap (operands[2],
2658 copy_to_mode_reg (SImode, GEN_INT (-1)),
2660 emit_insn (gen_div_trap (operands[2],
2661 copy_to_mode_reg (SImode,
2664 (BITMASK_HIGH, SImode))),
2671 (define_insn "divsi3_internal"
2672 [(set (match_operand:SI 0 "register_operand" "=l")
2673 (div:SI (match_operand:SI 1 "register_operand" "d")
2674 (match_operand:SI 2 "nonmemory_operand" "di")))
2675 (clobber (match_scratch:SI 3 "=h"))
2676 (clobber (match_scratch:SI 4 "=a"))]
2679 [(set_attr "type" "idiv")
2680 (set_attr "mode" "SI")])
2682 (define_expand "divdi3"
2683 [(set (match_operand:DI 0 "register_operand" "=l")
2684 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2685 (match_operand:DI 2 "se_register_operand" "d")))
2686 (clobber (match_scratch:DI 3 "=h"))
2687 (clobber (match_scratch:DI 4 "=a"))]
2688 "TARGET_64BIT && !optimize"
2691 emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2]));
2692 if (!TARGET_NO_CHECK_ZERO_DIV)
2694 emit_insn (gen_div_trap (operands[2],
2698 if (TARGET_CHECK_RANGE_DIV)
2700 emit_insn (gen_div_trap (operands[2],
2701 copy_to_mode_reg (DImode, GEN_INT (-1)),
2703 emit_insn (gen_div_trap (operands[2],
2704 copy_to_mode_reg (DImode,
2705 GEN_INT (BITMASK_HIGH)),
2712 (define_insn "divdi3_internal"
2713 [(set (match_operand:DI 0 "register_operand" "=l")
2714 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2715 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2716 (clobber (match_scratch:SI 3 "=h"))
2717 (clobber (match_scratch:SI 4 "=a"))]
2718 "TARGET_64BIT && !optimize"
2720 [(set_attr "type" "idiv")
2721 (set_attr "mode" "DI")])
2723 (define_expand "modsi3"
2724 [(set (match_operand:SI 0 "register_operand" "=h")
2725 (mod:SI (match_operand:SI 1 "register_operand" "d")
2726 (match_operand:SI 2 "register_operand" "d")))
2727 (clobber (match_scratch:SI 3 "=l"))
2728 (clobber (match_scratch:SI 4 "=a"))]
2732 emit_insn (gen_modsi3_internal (operands[0], operands[1], operands[2]));
2733 if (!TARGET_NO_CHECK_ZERO_DIV)
2735 emit_insn (gen_div_trap (operands[2],
2739 if (TARGET_CHECK_RANGE_DIV)
2741 emit_insn (gen_div_trap (operands[2],
2742 copy_to_mode_reg (SImode, GEN_INT (-1)),
2744 emit_insn (gen_div_trap (operands[2],
2745 copy_to_mode_reg (SImode,
2748 (BITMASK_HIGH, SImode))),
2755 (define_insn "modsi3_internal"
2756 [(set (match_operand:SI 0 "register_operand" "=h")
2757 (mod:SI (match_operand:SI 1 "register_operand" "d")
2758 (match_operand:SI 2 "nonmemory_operand" "di")))
2759 (clobber (match_scratch:SI 3 "=l"))
2760 (clobber (match_scratch:SI 4 "=a"))]
2763 [(set_attr "type" "idiv")
2764 (set_attr "mode" "SI")])
2766 (define_expand "moddi3"
2767 [(set (match_operand:DI 0 "register_operand" "=h")
2768 (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2769 (match_operand:DI 2 "se_register_operand" "d")))
2770 (clobber (match_scratch:DI 3 "=l"))
2771 (clobber (match_scratch:DI 4 "=a"))]
2772 "TARGET_64BIT && !optimize"
2775 emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2]));
2776 if (!TARGET_NO_CHECK_ZERO_DIV)
2778 emit_insn (gen_div_trap (operands[2],
2782 if (TARGET_CHECK_RANGE_DIV)
2784 emit_insn (gen_div_trap (operands[2],
2785 copy_to_mode_reg (DImode, GEN_INT (-1)),
2787 emit_insn (gen_div_trap (operands[2],
2788 copy_to_mode_reg (DImode,
2789 GEN_INT (BITMASK_HIGH)),
2796 (define_insn "moddi3_internal"
2797 [(set (match_operand:DI 0 "register_operand" "=h")
2798 (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2799 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2800 (clobber (match_scratch:SI 3 "=l"))
2801 (clobber (match_scratch:SI 4 "=a"))]
2802 "TARGET_64BIT && !optimize"
2804 [(set_attr "type" "idiv")
2805 (set_attr "mode" "DI")])
2807 (define_expand "udivsi3"
2808 [(set (match_operand:SI 0 "register_operand" "=l")
2809 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2810 (match_operand:SI 2 "register_operand" "d")))
2811 (clobber (match_scratch:SI 3 "=h"))
2812 (clobber (match_scratch:SI 4 "=a"))]
2816 emit_insn (gen_udivsi3_internal (operands[0], operands[1], operands[2]));
2817 if (!TARGET_NO_CHECK_ZERO_DIV)
2819 emit_insn (gen_div_trap (operands[2],
2827 (define_insn "udivsi3_internal"
2828 [(set (match_operand:SI 0 "register_operand" "=l")
2829 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2830 (match_operand:SI 2 "nonmemory_operand" "di")))
2831 (clobber (match_scratch:SI 3 "=h"))
2832 (clobber (match_scratch:SI 4 "=a"))]
2835 [(set_attr "type" "idiv")
2836 (set_attr "mode" "SI")])
2838 (define_expand "udivdi3"
2839 [(set (match_operand:DI 0 "register_operand" "=l")
2840 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2841 (match_operand:DI 2 "se_register_operand" "di")))
2842 (clobber (match_scratch:DI 3 "=h"))
2843 (clobber (match_scratch:DI 4 "=a"))]
2844 "TARGET_64BIT && !optimize"
2847 emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2]));
2848 if (!TARGET_NO_CHECK_ZERO_DIV)
2850 emit_insn (gen_div_trap (operands[2],
2858 (define_insn "udivdi3_internal"
2859 [(set (match_operand:DI 0 "register_operand" "=l")
2860 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2861 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2862 (clobber (match_scratch:SI 3 "=h"))
2863 (clobber (match_scratch:SI 4 "=a"))]
2864 "TARGET_64BIT && !optimize"
2866 [(set_attr "type" "idiv")
2867 (set_attr "mode" "DI")])
2869 (define_expand "umodsi3"
2870 [(set (match_operand:SI 0 "register_operand" "=h")
2871 (umod:SI (match_operand:SI 1 "register_operand" "d")
2872 (match_operand:SI 2 "register_operand" "d")))
2873 (clobber (match_scratch:SI 3 "=l"))
2874 (clobber (match_scratch:SI 4 "=a"))]
2878 emit_insn (gen_umodsi3_internal (operands[0], operands[1], operands[2]));
2879 if (!TARGET_NO_CHECK_ZERO_DIV)
2881 emit_insn (gen_div_trap (operands[2],
2889 (define_insn "umodsi3_internal"
2890 [(set (match_operand:SI 0 "register_operand" "=h")
2891 (umod:SI (match_operand:SI 1 "register_operand" "d")
2892 (match_operand:SI 2 "nonmemory_operand" "di")))
2893 (clobber (match_scratch:SI 3 "=l"))
2894 (clobber (match_scratch:SI 4 "=a"))]
2897 [(set_attr "type" "idiv")
2898 (set_attr "mode" "SI")])
2900 (define_expand "umoddi3"
2901 [(set (match_operand:DI 0 "register_operand" "=h")
2902 (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2903 (match_operand:DI 2 "se_register_operand" "di")))
2904 (clobber (match_scratch:DI 3 "=l"))
2905 (clobber (match_scratch:DI 4 "=a"))]
2906 "TARGET_64BIT && !optimize"
2909 emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2]));
2910 if (!TARGET_NO_CHECK_ZERO_DIV)
2912 emit_insn (gen_div_trap (operands[2],
2920 (define_insn "umoddi3_internal"
2921 [(set (match_operand:DI 0 "register_operand" "=h")
2922 (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2923 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2924 (clobber (match_scratch:SI 3 "=l"))
2925 (clobber (match_scratch:SI 4 "=a"))]
2926 "TARGET_64BIT && !optimize"
2928 [(set_attr "type" "idiv")
2929 (set_attr "mode" "DI")])
2932 ;; ....................
2936 ;; ....................
2938 (define_insn "sqrtdf2"
2939 [(set (match_operand:DF 0 "register_operand" "=f")
2940 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2941 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2943 [(set_attr "type" "fsqrt")
2944 (set_attr "mode" "DF")])
2946 (define_insn "sqrtsf2"
2947 [(set (match_operand:SF 0 "register_operand" "=f")
2948 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2949 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2951 [(set_attr "type" "fsqrt")
2952 (set_attr "mode" "SF")])
2955 [(set (match_operand:DF 0 "register_operand" "=f")
2956 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2957 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2958 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2960 [(set_attr "type" "fsqrt")
2961 (set_attr "mode" "DF")])
2964 [(set (match_operand:SF 0 "register_operand" "=f")
2965 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2966 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2967 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2969 [(set_attr "type" "fsqrt")
2970 (set_attr "mode" "SF")])
2974 ;; ....................
2978 ;; ....................
2980 ;; Do not use the integer abs macro instruction, since that signals an
2981 ;; exception on -2147483648 (sigh).
2983 (define_insn "abssi2"
2984 [(set (match_operand:SI 0 "register_operand" "=d")
2985 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2989 dslots_jump_total++;
2990 dslots_jump_filled++;
2991 operands[2] = const0_rtx;
2993 if (REGNO (operands[0]) == REGNO (operands[1]))
2995 if (GENERATE_BRANCHLIKELY)
2996 return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
2998 return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n%~1:\";
3001 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
3003 [(set_attr "type" "multi")
3004 (set_attr "mode" "SI")
3005 (set_attr "length" "12")])
3007 (define_insn "absdi2"
3008 [(set (match_operand:DI 0 "register_operand" "=d")
3009 (abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
3010 "TARGET_64BIT && !TARGET_MIPS16"
3013 unsigned int regno1;
3014 dslots_jump_total++;
3015 dslots_jump_filled++;
3016 operands[2] = const0_rtx;
3018 if (GET_CODE (operands[1]) == REG)
3019 regno1 = REGNO (operands[1]);
3021 regno1 = REGNO (XEXP (operands[1], 0));
3023 if (REGNO (operands[0]) == regno1)
3024 return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
3026 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
3028 [(set_attr "type" "multi")
3029 (set_attr "mode" "DI")
3030 (set_attr "length" "12")])
3032 (define_insn "absdf2"
3033 [(set (match_operand:DF 0 "register_operand" "=f")
3034 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
3035 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3037 [(set_attr "type" "fabs")
3038 (set_attr "mode" "DF")])
3040 (define_insn "abssf2"
3041 [(set (match_operand:SF 0 "register_operand" "=f")
3042 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
3045 [(set_attr "type" "fabs")
3046 (set_attr "mode" "SF")])
3050 ;; ....................
3052 ;; FIND FIRST BIT INSTRUCTION
3054 ;; ....................
3057 (define_insn "ffssi2"
3058 [(set (match_operand:SI 0 "register_operand" "=&d")
3059 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
3060 (clobber (match_scratch:SI 2 "=&d"))
3061 (clobber (match_scratch:SI 3 "=&d"))]
3065 dslots_jump_total += 2;
3066 dslots_jump_filled += 2;
3067 operands[4] = const0_rtx;
3069 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3072 \\tbeq\\t%1,%z4,2f\\n\\
3073 %~1:\\tand\\t%2,%1,0x0001\\n\\
3074 \\taddu\\t%0,%0,1\\n\\
3075 \\tbeq\\t%2,%z4,1b\\n\\
3076 \\tsrl\\t%1,%1,1\\n\\
3081 \\tmove\\t%3,%1\\n\\
3082 \\tbeq\\t%3,%z4,2f\\n\\
3083 %~1:\\tand\\t%2,%3,0x0001\\n\\
3084 \\taddu\\t%0,%0,1\\n\\
3085 \\tbeq\\t%2,%z4,1b\\n\\
3086 \\tsrl\\t%3,%3,1\\n\\
3089 [(set_attr "type" "multi")
3090 (set_attr "mode" "SI")
3091 (set_attr "length" "12")])
3093 (define_insn "ffsdi2"
3094 [(set (match_operand:DI 0 "register_operand" "=&d")
3095 (ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
3096 (clobber (match_scratch:DI 2 "=&d"))
3097 (clobber (match_scratch:DI 3 "=&d"))]
3098 "TARGET_64BIT && !TARGET_MIPS16"
3101 dslots_jump_total += 2;
3102 dslots_jump_filled += 2;
3103 operands[4] = const0_rtx;
3105 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3108 \\tbeq\\t%1,%z4,2f\\n\\
3109 %~1:\\tand\\t%2,%1,0x0001\\n\\
3110 \\tdaddu\\t%0,%0,1\\n\\
3111 \\tbeq\\t%2,%z4,1b\\n\\
3112 \\tdsrl\\t%1,%1,1\\n\\
3117 \\tmove\\t%3,%1\\n\\
3118 \\tbeq\\t%3,%z4,2f\\n\\
3119 %~1:\\tand\\t%2,%3,0x0001\\n\\
3120 \\tdaddu\\t%0,%0,1\\n\\
3121 \\tbeq\\t%2,%z4,1b\\n\\
3122 \\tdsrl\\t%3,%3,1\\n\\
3125 [(set_attr "type" "multi")
3126 (set_attr "mode" "DI")
3127 (set_attr "length" "24")])
3131 ;; ....................
3133 ;; NEGATION and ONE'S COMPLEMENT
3135 ;; ....................
3137 (define_insn "negsi2"
3138 [(set (match_operand:SI 0 "register_operand" "=d")
3139 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
3144 return \"neg\\t%0,%1\";
3145 operands[2] = const0_rtx;
3146 return \"subu\\t%0,%z2,%1\";
3148 [(set_attr "type" "arith")
3149 (set_attr "mode" "SI")])
3151 (define_expand "negdi2"
3152 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
3153 (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
3154 (clobber (match_dup 2))])]
3155 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3160 emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
3164 operands[2] = gen_reg_rtx (SImode);
3167 (define_insn "negdi2_internal"
3168 [(set (match_operand:DI 0 "register_operand" "=d")
3169 (neg:DI (match_operand:DI 1 "register_operand" "d")))
3170 (clobber (match_operand:SI 2 "register_operand" "=d"))]
3171 "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
3174 operands[3] = const0_rtx;
3175 return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
3177 [(set_attr "type" "darith")
3178 (set_attr "mode" "DI")
3179 (set_attr "length" "16")])
3181 (define_insn "negdi2_internal_2"
3182 [(set (match_operand:DI 0 "register_operand" "=d")
3183 (neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
3184 "TARGET_64BIT && !TARGET_MIPS16"
3187 operands[2] = const0_rtx;
3188 return \"dsubu\\t%0,%z2,%1\";
3190 [(set_attr "type" "arith")
3191 (set_attr "mode" "DI")])
3193 (define_insn "negdf2"
3194 [(set (match_operand:DF 0 "register_operand" "=f")
3195 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
3196 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3198 [(set_attr "type" "fneg")
3199 (set_attr "mode" "DF")])
3201 (define_insn "negsf2"
3202 [(set (match_operand:SF 0 "register_operand" "=f")
3203 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3206 [(set_attr "type" "fneg")
3207 (set_attr "mode" "SF")])
3209 (define_insn "one_cmplsi2"
3210 [(set (match_operand:SI 0 "register_operand" "=d")
3211 (not:SI (match_operand:SI 1 "register_operand" "d")))]
3216 return \"not\\t%0,%1\";
3217 operands[2] = const0_rtx;
3218 return \"nor\\t%0,%z2,%1\";
3220 [(set_attr "type" "arith")
3221 (set_attr "mode" "SI")])
3223 (define_insn "one_cmpldi2"
3224 [(set (match_operand:DI 0 "register_operand" "=d")
3225 (not:DI (match_operand:DI 1 "se_register_operand" "d")))]
3232 return \"not\\t%0,%1\";
3233 return \"not\\t%M0,%M1\;not\\t%L0,%L1\";
3235 operands[2] = const0_rtx;
3237 return \"nor\\t%0,%z2,%1\";
3238 return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
3240 [(set_attr "type" "darith")
3241 (set_attr "mode" "DI")
3242 (set (attr "length")
3243 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3248 [(set (match_operand:DI 0 "register_operand" "")
3249 (not:DI (match_operand:DI 1 "register_operand" "")))]
3250 "reload_completed && !TARGET_64BIT
3251 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3252 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3253 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3255 [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
3256 (set (subreg:SI (match_dup 0) 4) (not:SI (subreg:SI (match_dup 1) 4)))]
3261 ;; ....................
3265 ;; ....................
3268 ;; Many of these instructions uses trivial define_expands, because we
3269 ;; want to use a different set of constraints when TARGET_MIPS16.
3271 (define_expand "andsi3"
3272 [(set (match_operand:SI 0 "register_operand" "=d,d")
3273 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3274 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3279 operands[2] = force_reg (SImode, operands[2]);
3283 [(set (match_operand:SI 0 "register_operand" "=d,d")
3284 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3285 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3290 [(set_attr "type" "arith")
3291 (set_attr "mode" "SI")])
3294 [(set (match_operand:SI 0 "register_operand" "=d")
3295 (and:SI (match_operand:SI 1 "register_operand" "%0")
3296 (match_operand:SI 2 "register_operand" "d")))]
3299 [(set_attr "type" "arith")
3300 (set_attr "mode" "SI")])
3302 (define_expand "anddi3"
3303 [(set (match_operand:DI 0 "register_operand" "=d")
3304 (and:DI (match_operand:DI 1 "se_register_operand" "d")
3305 (match_operand:DI 2 "se_register_operand" "d")))]
3306 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3310 operands[2] = force_reg (DImode, operands[2]);
3314 [(set (match_operand:DI 0 "register_operand" "=d")
3315 (and:DI (match_operand:DI 1 "se_register_operand" "d")
3316 (match_operand:DI 2 "se_register_operand" "d")))]
3317 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3321 return \"and\\t%0,%1,%2\";
3322 return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
3324 [(set_attr "type" "darith")
3325 (set_attr "mode" "DI")
3326 (set (attr "length")
3327 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3332 [(set (match_operand:DI 0 "register_operand" "=d")
3333 (and:DI (match_operand:DI 1 "se_register_operand" "0")
3334 (match_operand:DI 2 "se_register_operand" "d")))]
3335 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3339 return \"and\\t%0,%2\";
3340 return \"and\\t%M0,%M2\;and\\t%L0,%L2\";
3342 [(set_attr "type" "darith")
3343 (set_attr "mode" "DI")
3344 (set (attr "length")
3345 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3350 [(set (match_operand:DI 0 "register_operand" "")
3351 (and:DI (match_operand:DI 1 "register_operand" "")
3352 (match_operand:DI 2 "register_operand" "")))]
3353 "reload_completed && !TARGET_64BIT
3354 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3355 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3356 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3357 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3359 [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3360 (set (subreg:SI (match_dup 0) 4) (and:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3363 (define_insn "anddi3_internal1"
3364 [(set (match_operand:DI 0 "register_operand" "=d,d")
3365 (and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
3366 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
3367 "TARGET_64BIT && !TARGET_MIPS16"
3371 [(set_attr "type" "arith")
3372 (set_attr "mode" "DI")])
3374 (define_expand "iorsi3"
3375 [(set (match_operand:SI 0 "register_operand" "=d,d")
3376 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3377 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3382 operands[2] = force_reg (SImode, operands[2]);
3386 [(set (match_operand:SI 0 "register_operand" "=d,d")
3387 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3388 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3393 [(set_attr "type" "arith")
3394 (set_attr "mode" "SI")])
3397 [(set (match_operand:SI 0 "register_operand" "=d")
3398 (ior:SI (match_operand:SI 1 "register_operand" "%0")
3399 (match_operand:SI 2 "register_operand" "d")))]
3402 [(set_attr "type" "arith")
3403 (set_attr "mode" "SI")])
3405 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
3408 (define_expand "iordi3"
3409 [(set (match_operand:DI 0 "register_operand" "=d")
3410 (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3411 (match_operand:DI 2 "se_register_operand" "d")))]
3412 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3416 [(set (match_operand:DI 0 "register_operand" "=d")
3417 (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3418 (match_operand:DI 2 "se_register_operand" "d")))]
3419 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3423 return \"or\\t%0,%1,%2\";
3424 return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
3426 [(set_attr "type" "darith")
3427 (set_attr "mode" "DI")
3428 (set (attr "length")
3429 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3434 [(set (match_operand:DI 0 "register_operand" "=d")
3435 (ior:DI (match_operand:DI 1 "se_register_operand" "0")
3436 (match_operand:DI 2 "se_register_operand" "d")))]
3437 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3441 return \"or\\t%0,%2\";
3442 return \"or\\t%M0,%M2\;or\\t%L0,%L2\";
3444 [(set_attr "type" "darith")
3445 (set_attr "mode" "DI")
3446 (set (attr "length")
3447 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3452 [(set (match_operand:DI 0 "register_operand" "")
3453 (ior:DI (match_operand:DI 1 "register_operand" "")
3454 (match_operand:DI 2 "register_operand" "")))]
3455 "reload_completed && !TARGET_64BIT
3456 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3457 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3458 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3459 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3461 [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3462 (set (subreg:SI (match_dup 0) 4) (ior:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3465 (define_expand "xorsi3"
3466 [(set (match_operand:SI 0 "register_operand" "=d,d")
3467 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3468 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3473 [(set (match_operand:SI 0 "register_operand" "=d,d")
3474 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3475 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3480 [(set_attr "type" "arith")
3481 (set_attr "mode" "SI")])
3484 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3485 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3486 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3492 [(set_attr "type" "arith")
3493 (set_attr "mode" "SI")
3494 (set_attr_alternative "length"
3496 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3501 ;; ??? If delete the 32-bit long long patterns, then could merge this with
3502 ;; the following xordi3_internal pattern.
3503 (define_expand "xordi3"
3504 [(set (match_operand:DI 0 "register_operand" "=d")
3505 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3506 (match_operand:DI 2 "se_register_operand" "d")))]
3507 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3511 [(set (match_operand:DI 0 "register_operand" "=d")
3512 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3513 (match_operand:DI 2 "se_register_operand" "d")))]
3514 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3518 return \"xor\\t%0,%1,%2\";
3519 return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
3521 [(set_attr "type" "darith")
3522 (set_attr "mode" "DI")
3523 (set (attr "length")
3524 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3529 [(set (match_operand:DI 0 "register_operand" "=d")
3530 (xor:DI (match_operand:DI 1 "se_register_operand" "0")
3531 (match_operand:DI 2 "se_register_operand" "d")))]
3532 "!TARGET_64BIT && TARGET_MIPS16"
3533 "xor\\t%M0,%M2\;xor\\t%L0,%L2"
3534 [(set_attr "type" "darith")
3535 (set_attr "mode" "DI")
3536 (set_attr "length" "8")])
3539 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3540 (xor:DI (match_operand:DI 1 "se_register_operand" "%0,d,d")
3541 (match_operand:DI 2 "se_uns_arith_operand" "d,K,d")))]
3542 "TARGET_64BIT && TARGET_MIPS16"
3547 [(set_attr "type" "arith")
3548 (set_attr "mode" "DI")
3549 (set_attr_alternative "length"
3551 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3557 [(set (match_operand:DI 0 "register_operand" "")
3558 (xor:DI (match_operand:DI 1 "register_operand" "")
3559 (match_operand:DI 2 "register_operand" "")))]
3560 "reload_completed && !TARGET_64BIT
3561 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3562 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3563 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3564 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3566 [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3567 (set (subreg:SI (match_dup 0) 4) (xor:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
3570 (define_insn "xordi3_immed"
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_uns_arith_operand" "K")))]
3574 "TARGET_64BIT && !TARGET_MIPS16"
3576 [(set_attr "type" "arith")
3577 (set_attr "mode" "DI")])
3579 (define_insn "*norsi3"
3580 [(set (match_operand:SI 0 "register_operand" "=d")
3581 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3582 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3585 [(set_attr "type" "arith")
3586 (set_attr "mode" "SI")])
3588 (define_insn "*nordi3"
3589 [(set (match_operand:DI 0 "register_operand" "=d")
3590 (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
3591 (not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
3596 return \"nor\\t%0,%z1,%z2\";
3597 return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
3599 [(set_attr "type" "darith")
3600 (set_attr "mode" "DI")
3601 (set (attr "length")
3602 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3607 [(set (match_operand:DI 0 "register_operand" "")
3608 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
3609 (not:DI (match_operand:DI 2 "register_operand" ""))))]
3610 "reload_completed && !TARGET_MIPS16 && !TARGET_64BIT
3611 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3612 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3613 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3614 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3616 [(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))))
3617 (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))))]
3621 ;; ....................
3625 ;; ....................
3627 (define_insn "truncdfsf2"
3628 [(set (match_operand:SF 0 "register_operand" "=f")
3629 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3630 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3632 [(set_attr "type" "fcvt")
3633 (set_attr "mode" "SF")])
3635 (define_insn "truncdisi2"
3636 [(set (match_operand:SI 0 "register_operand" "=d")
3637 (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
3642 return \"dsll\\t%0,%1,32\;dsra\\t%0,32\";
3643 return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\";
3645 [(set_attr "type" "darith")
3646 (set_attr "mode" "SI")
3647 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3651 (define_insn "truncdihi2"
3652 [(set (match_operand:HI 0 "register_operand" "=d")
3653 (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
3658 return \"dsll\\t%0,%1,48\;dsra\\t%0,48\";
3659 return \"andi\\t%0,%1,0xffff\";
3661 [(set_attr "type" "darith")
3662 (set_attr "mode" "HI")
3663 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3666 (define_insn "truncdiqi2"
3667 [(set (match_operand:QI 0 "register_operand" "=d")
3668 (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
3673 return \"dsll\\t%0,%1,56\;dsra\\t%0,56\";
3674 return \"andi\\t%0,%1,0x00ff\";
3676 [(set_attr "type" "darith")
3677 (set_attr "mode" "QI")
3678 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3682 ;; Combiner patterns to optimize shift/truncate combinations.
3684 [(set (match_operand:SI 0 "register_operand" "=d")
3685 (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3686 (match_operand:DI 2 "small_int" "I"))))]
3687 "TARGET_64BIT && !TARGET_MIPS16"
3690 int shift_amt = INTVAL (operands[2]) & 0x3f;
3694 operands[2] = GEN_INT (32 - shift_amt);
3695 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3699 operands[2] = GEN_INT (shift_amt);
3700 return \"dsra\\t%0,%1,%2\";
3703 [(set_attr "type" "darith")
3704 (set_attr "mode" "SI")
3705 (set_attr "length" "8")])
3708 [(set (match_operand:SI 0 "register_operand" "=d")
3709 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3710 (match_operand:DI 2 "small_int" "I"))))]
3711 "TARGET_64BIT && !TARGET_MIPS16"
3714 int shift_amt = INTVAL (operands[2]) & 0x3f;
3718 operands[2] = GEN_INT (32 - shift_amt);
3719 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3721 else if (shift_amt == 32)
3722 return \"dsra\\t%0,%1,32\";
3725 operands[2] = GEN_INT (shift_amt);
3726 return \"dsrl\\t%0,%1,%2\";
3729 [(set_attr "type" "darith")
3730 (set_attr "mode" "SI")
3731 (set_attr "length" "8")])
3734 [(set (match_operand:SI 0 "register_operand" "=d")
3735 (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
3736 (match_operand:DI 2 "small_int" "I"))))]
3740 int shift_amt = INTVAL (operands[2]) & 0x3f;
3744 operands[2] = GEN_INT (32 + shift_amt);
3746 return \"dsll\\t%0,%1,%2\;dsra\\t%0,32\";
3747 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3750 return \"move\\t%0,%.\";
3752 [(set_attr "type" "darith")
3753 (set_attr "mode" "SI")
3754 (set_attr "length" "8")])
3756 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3759 [(set (match_operand:SI 0 "register_operand" "=d")
3760 (zero_extend:SI (truncate:HI
3761 (match_operand:DI 1 "se_register_operand" "d"))))]
3762 "TARGET_64BIT && !TARGET_MIPS16"
3763 "andi\\t%0,%1,0xffff"
3764 [(set_attr "type" "darith")
3765 (set_attr "mode" "SI")])
3768 [(set (match_operand:SI 0 "register_operand" "=d")
3769 (zero_extend:SI (truncate:QI
3770 (match_operand:DI 1 "se_register_operand" "d"))))]
3771 "TARGET_64BIT && !TARGET_MIPS16"
3773 [(set_attr "type" "darith")
3774 (set_attr "mode" "SI")])
3777 [(set (match_operand:HI 0 "register_operand" "=d")
3778 (zero_extend:HI (truncate:QI
3779 (match_operand:DI 1 "se_register_operand" "d"))))]
3780 "TARGET_64BIT && !TARGET_MIPS16"
3782 [(set_attr "type" "darith")
3783 (set_attr "mode" "HI")])
3786 ;; ....................
3790 ;; ....................
3793 ;; Those for integer source operand are ordered widest source type first.
3795 (define_expand "zero_extendsidi2"
3796 [(set (match_operand:DI 0 "register_operand" "")
3797 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3801 if ((optimize || TARGET_MIPS16) && GET_CODE (operands[1]) == MEM)
3802 operands[1] = force_not_mem (operands[1]);
3804 if (GET_CODE (operands[1]) != MEM)
3806 rtx op1 = gen_lowpart (DImode, operands[1]);
3807 rtx temp = gen_reg_rtx (DImode);
3808 rtx shift = GEN_INT (32);
3810 emit_insn (gen_ashldi3 (temp, op1, shift));
3811 emit_insn (gen_lshrdi3 (operands[0], temp, shift));
3816 (define_insn "zero_extendsidi2_internal"
3817 [(set (match_operand:DI 0 "register_operand" "=d,d")
3818 (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
3819 "TARGET_64BIT && !TARGET_MIPS16"
3820 "* return mips_move_1word (operands, insn, TRUE);"
3821 [(set_attr "type" "load")
3822 (set_attr "mode" "DI")
3823 (set_attr "length" "4,8")])
3825 (define_expand "zero_extendhisi2"
3826 [(set (match_operand:SI 0 "register_operand" "")
3827 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3831 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3833 rtx op = gen_lowpart (SImode, operands[1]);
3834 rtx temp = force_reg (SImode, GEN_INT (0xffff));
3836 emit_insn (gen_andsi3 (operands[0], op, temp));
3842 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3843 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3847 if (which_alternative == 0)
3848 return \"andi\\t%0,%1,0xffff\";
3850 return mips_move_1word (operands, insn, TRUE);
3852 [(set_attr "type" "arith,load,load")
3853 (set_attr "mode" "SI")
3854 (set_attr "length" "4,4,8")])
3857 [(set (match_operand:SI 0 "register_operand" "=d,d")
3858 (zero_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3860 "* return mips_move_1word (operands, insn, TRUE);"
3861 [(set_attr "type" "load,load")
3862 (set_attr "mode" "SI")
3863 (set_attr "length" "4,8")])
3865 (define_expand "zero_extendhidi2"
3866 [(set (match_operand:DI 0 "register_operand" "")
3867 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3871 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3873 rtx op = gen_lowpart (DImode, operands[1]);
3874 rtx temp = force_reg (DImode, GEN_INT (0xffff));
3876 emit_insn (gen_anddi3 (operands[0], op, temp));
3882 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3883 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3884 "TARGET_64BIT && !TARGET_MIPS16"
3887 if (which_alternative == 0)
3888 return \"andi\\t%0,%1,0xffff\";
3890 return mips_move_1word (operands, insn, TRUE);
3892 [(set_attr "type" "arith,load,load")
3893 (set_attr "mode" "DI")
3894 (set_attr "length" "4,4,8")])
3897 [(set (match_operand:DI 0 "register_operand" "=d,d")
3898 (zero_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3899 "TARGET_64BIT && TARGET_MIPS16"
3900 "* return mips_move_1word (operands, insn, TRUE);"
3901 [(set_attr "type" "load,load")
3902 (set_attr "mode" "DI")
3903 (set_attr "length" "4,8")])
3905 (define_expand "zero_extendqihi2"
3906 [(set (match_operand:HI 0 "register_operand" "")
3907 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3911 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3913 rtx op0 = gen_lowpart (SImode, operands[0]);
3914 rtx op1 = gen_lowpart (SImode, operands[1]);
3915 rtx temp = force_reg (SImode, GEN_INT (0xff));
3917 emit_insn (gen_andsi3 (op0, op1, temp));
3923 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
3924 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3928 if (which_alternative == 0)
3929 return \"andi\\t%0,%1,0x00ff\";
3931 return mips_move_1word (operands, insn, TRUE);
3933 [(set_attr "type" "arith,load,load")
3934 (set_attr "mode" "HI")
3935 (set_attr "length" "4,4,8")])
3938 [(set (match_operand:HI 0 "register_operand" "=d,d")
3939 (zero_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
3941 "* return mips_move_1word (operands, insn, TRUE);"
3942 [(set_attr "type" "load,load")
3943 (set_attr "mode" "HI")
3944 (set_attr "length" "4,8")])
3946 (define_expand "zero_extendqisi2"
3947 [(set (match_operand:SI 0 "register_operand" "")
3948 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3952 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3954 rtx op = gen_lowpart (SImode, operands[1]);
3955 rtx temp = force_reg (SImode, GEN_INT (0xff));
3957 emit_insn (gen_andsi3 (operands[0], op, temp));
3963 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3964 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3968 if (which_alternative == 0)
3969 return \"andi\\t%0,%1,0x00ff\";
3971 return mips_move_1word (operands, insn, TRUE);
3973 [(set_attr "type" "arith,load,load")
3974 (set_attr "mode" "SI")
3975 (set_attr "length" "4,4,8")])
3978 [(set (match_operand:SI 0 "register_operand" "=d,d")
3979 (zero_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
3981 "* return mips_move_1word (operands, insn, TRUE);"
3982 [(set_attr "type" "load,load")
3983 (set_attr "mode" "SI")
3984 (set_attr "length" "4,8")])
3986 (define_expand "zero_extendqidi2"
3987 [(set (match_operand:DI 0 "register_operand" "")
3988 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
3992 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3994 rtx op = gen_lowpart (DImode, operands[1]);
3995 rtx temp = force_reg (DImode, GEN_INT (0xff));
3997 emit_insn (gen_anddi3 (operands[0], op, temp));
4003 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4004 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
4005 "TARGET_64BIT && !TARGET_MIPS16"
4008 if (which_alternative == 0)
4009 return \"andi\\t%0,%1,0x00ff\";
4011 return mips_move_1word (operands, insn, TRUE);
4013 [(set_attr "type" "arith,load,load")
4014 (set_attr "mode" "DI")
4015 (set_attr "length" "4,4,8")])
4017 ;; These can be created when a paradoxical subreg operand with an implicit
4018 ;; sign_extend operator is reloaded. Because of the subreg, this is really
4020 ;; ??? It might be possible to eliminate the need for these patterns by adding
4021 ;; more support to reload for implicit sign_extend operators.
4022 (define_insn "*paradoxical_extendhidi2"
4023 [(set (match_operand:DI 0 "register_operand" "=d,d")
4025 (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
4029 return mips_move_1word (operands, insn, TRUE);
4031 [(set_attr "type" "load,load")
4032 (set_attr "mode" "DI")
4033 (set_attr "length" "4,8")])
4036 [(set (match_operand:DI 0 "register_operand" "=d,d")
4037 (zero_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4038 "TARGET_64BIT && TARGET_MIPS16"
4039 "* return mips_move_1word (operands, insn, TRUE);"
4040 [(set_attr "type" "load,load")
4041 (set_attr "mode" "DI")
4042 (set_attr "length" "4,8")])
4045 ;; ....................
4049 ;; ....................
4052 ;; Those for integer source operand are ordered widest source type first.
4054 ;; In 64 bit mode, 32 bit values in general registers are always
4055 ;; correctly sign extended. That means that if the target is a
4056 ;; general register, we can sign extend from SImode to DImode just by
4059 (define_insn "extendsidi2"
4060 [(set (match_operand:DI 0 "register_operand" "=d,y,d,*d,d,d")
4061 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,d,y,*x,R,m")))]
4063 "* return mips_move_1word (operands, insn, FALSE);"
4064 [(set_attr "type" "move,move,move,hilo,load,load")
4065 (set_attr "mode" "DI")
4066 (set_attr "length" "4,4,4,4,4,8")])
4068 ;; These patterns originally accepted general_operands, however, slightly
4069 ;; better code is generated by only accepting register_operands, and then
4070 ;; letting combine generate the lh and lb insns.
4072 (define_expand "extendhidi2"
4073 [(set (match_operand:DI 0 "register_operand" "")
4074 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
4078 if (optimize && GET_CODE (operands[1]) == MEM)
4079 operands[1] = force_not_mem (operands[1]);
4081 if (GET_CODE (operands[1]) != MEM)
4083 rtx op1 = gen_lowpart (DImode, operands[1]);
4084 rtx temp = gen_reg_rtx (DImode);
4085 rtx shift = GEN_INT (48);
4087 emit_insn (gen_ashldi3 (temp, op1, shift));
4088 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4093 (define_insn "extendhidi2_internal"
4094 [(set (match_operand:DI 0 "register_operand" "=d,d")
4095 (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
4097 "* return mips_move_1word (operands, insn, FALSE);"
4098 [(set_attr "type" "load")
4099 (set_attr "mode" "DI")
4100 (set_attr "length" "4,8")])
4102 (define_expand "extendhisi2"
4103 [(set (match_operand:SI 0 "register_operand" "")
4104 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4108 if (optimize && GET_CODE (operands[1]) == MEM)
4109 operands[1] = force_not_mem (operands[1]);
4111 if (GET_CODE (operands[1]) != MEM)
4113 rtx op1 = gen_lowpart (SImode, operands[1]);
4114 rtx temp = gen_reg_rtx (SImode);
4115 rtx shift = GEN_INT (16);
4117 emit_insn (gen_ashlsi3 (temp, op1, shift));
4118 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4123 (define_insn "extendhisi2_internal"
4124 [(set (match_operand:SI 0 "register_operand" "=d,d")
4125 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
4127 "* return mips_move_1word (operands, insn, FALSE);"
4128 [(set_attr "type" "load")
4129 (set_attr "mode" "SI")
4130 (set_attr "length" "4,8")])
4132 (define_expand "extendqihi2"
4133 [(set (match_operand:HI 0 "register_operand" "")
4134 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
4138 if (optimize && GET_CODE (operands[1]) == MEM)
4139 operands[1] = force_not_mem (operands[1]);
4141 if (GET_CODE (operands[1]) != MEM)
4143 rtx op0 = gen_lowpart (SImode, operands[0]);
4144 rtx op1 = gen_lowpart (SImode, operands[1]);
4145 rtx temp = gen_reg_rtx (SImode);
4146 rtx shift = GEN_INT (24);
4148 emit_insn (gen_ashlsi3 (temp, op1, shift));
4149 emit_insn (gen_ashrsi3 (op0, temp, shift));
4154 (define_insn "extendqihi2_internal"
4155 [(set (match_operand:HI 0 "register_operand" "=d,d")
4156 (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
4158 "* return mips_move_1word (operands, insn, FALSE);"
4159 [(set_attr "type" "load")
4160 (set_attr "mode" "SI")
4161 (set_attr "length" "4,8")])
4164 (define_expand "extendqisi2"
4165 [(set (match_operand:SI 0 "register_operand" "")
4166 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4170 if (optimize && GET_CODE (operands[1]) == MEM)
4171 operands[1] = force_not_mem (operands[1]);
4173 if (GET_CODE (operands[1]) != MEM)
4175 rtx op1 = gen_lowpart (SImode, operands[1]);
4176 rtx temp = gen_reg_rtx (SImode);
4177 rtx shift = GEN_INT (24);
4179 emit_insn (gen_ashlsi3 (temp, op1, shift));
4180 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4185 (define_insn "extendqisi2_insn"
4186 [(set (match_operand:SI 0 "register_operand" "=d,d")
4187 (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
4189 "* return mips_move_1word (operands, insn, FALSE);"
4190 [(set_attr "type" "load")
4191 (set_attr "mode" "SI")
4192 (set_attr "length" "4,8")])
4194 (define_expand "extendqidi2"
4195 [(set (match_operand:DI 0 "register_operand" "")
4196 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4200 if (optimize && GET_CODE (operands[1]) == MEM)
4201 operands[1] = force_not_mem (operands[1]);
4203 if (GET_CODE (operands[1]) != MEM)
4205 rtx op1 = gen_lowpart (DImode, operands[1]);
4206 rtx temp = gen_reg_rtx (DImode);
4207 rtx shift = GEN_INT (56);
4209 emit_insn (gen_ashldi3 (temp, op1, shift));
4210 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4215 (define_insn "extendqidi2_insn"
4216 [(set (match_operand:DI 0 "register_operand" "=d,d")
4217 (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4219 "* return mips_move_1word (operands, insn, FALSE);"
4220 [(set_attr "type" "load")
4221 (set_attr "mode" "DI")
4222 (set_attr "length" "4,8")])
4225 (define_insn "extendsfdf2"
4226 [(set (match_operand:DF 0 "register_operand" "=f")
4227 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
4228 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4230 [(set_attr "type" "fcvt")
4231 (set_attr "mode" "DF")])
4236 ;; ....................
4240 ;; ....................
4242 ;; The SImode scratch register can not be shared with address regs used for
4243 ;; operand zero, because then the address in the move instruction will be
4244 ;; clobbered. We mark the scratch register as early clobbered to prevent this.
4246 ;; We need the ?X in alternative 1 so that it will be chosen only if the
4247 ;; destination is a floating point register. Otherwise, alternative 1 can
4248 ;; have lower cost than alternative 0 (because there is one less loser), and
4249 ;; can be chosen when it won't work (because integral reloads into FP
4250 ;; registers are not supported).
4252 (define_insn "fix_truncdfsi2"
4253 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,*f,R,To")
4254 (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
4255 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
4256 (clobber (match_scratch:DF 3 "=f,?*X,f,f"))]
4257 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4262 if (which_alternative == 1)
4263 return \"trunc.w.d %0,%1,%2\";
4265 output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
4267 xoperands[0] = operands[0];
4268 xoperands[1] = operands[3];
4269 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4272 [(set_attr "type" "fcvt")
4273 (set_attr "mode" "DF")
4274 (set_attr "length" "44,36,40,44")])
4277 (define_insn "fix_truncsfsi2"
4278 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,*f,R,To")
4279 (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
4280 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
4281 (clobber (match_scratch:SF 3 "=f,?*X,f,f"))]
4287 if (which_alternative == 1)
4288 return \"trunc.w.s %0,%1,%2\";
4290 output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
4292 xoperands[0] = operands[0];
4293 xoperands[1] = operands[3];
4294 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4297 [(set_attr "type" "fcvt")
4298 (set_attr "mode" "SF")
4299 (set_attr "length" "44,36,40,44")])
4302 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
4303 ;;; but not in the chapter that describes the FPU. It is not mentioned at all
4304 ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
4306 ;;; Deleting this means that we now need two libgcc2.a libraries. One for
4307 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
4309 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
4311 (define_insn "fix_truncdfdi2"
4312 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,*f,R,To")
4313 (fix:DI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
4314 (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
4315 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4320 if (which_alternative == 1)
4321 return \"trunc.l.d %0,%1\";
4323 output_asm_insn (\"trunc.l.d %2,%1\", operands);
4325 xoperands[0] = operands[0];
4326 xoperands[1] = operands[2];
4327 output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
4330 [(set_attr "type" "fcvt")
4331 (set_attr "mode" "DF")
4332 (set_attr "length" "8,4,8,12")])
4335 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
4336 ;;; but not in the chapter that describes the FPU. It is not mentioned at all
4337 ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
4338 (define_insn "fix_truncsfdi2"
4339 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,*f,R,To")
4340 (fix:DI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
4341 (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
4342 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4347 if (which_alternative == 1)
4348 return \"trunc.l.s %0,%1\";
4350 output_asm_insn (\"trunc.l.s %2,%1\", operands);
4352 xoperands[0] = operands[0];
4353 xoperands[1] = operands[2];
4354 output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
4357 [(set_attr "type" "fcvt")
4358 (set_attr "mode" "SF")
4359 (set_attr "length" "8,4,8,12")])
4362 (define_insn "floatsidf2"
4363 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
4364 (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
4365 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4368 dslots_load_total++;
4369 if (GET_CODE (operands[1]) == MEM)
4370 return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
4372 return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
4374 [(set_attr "type" "fcvt")
4375 (set_attr "mode" "DF")
4376 (set_attr "length" "12,16,12")])
4379 (define_insn "floatdidf2"
4380 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
4381 (float:DF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
4382 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4385 dslots_load_total++;
4386 if (GET_CODE (operands[1]) == MEM)
4387 return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
4389 return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
4391 [(set_attr "type" "fcvt")
4392 (set_attr "mode" "DF")
4393 (set_attr "length" "12,16,12")])
4396 (define_insn "floatsisf2"
4397 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
4398 (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
4402 dslots_load_total++;
4403 if (GET_CODE (operands[1]) == MEM)
4404 return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
4406 return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
4408 [(set_attr "type" "fcvt")
4409 (set_attr "mode" "SF")
4410 (set_attr "length" "12,16,12")])
4413 (define_insn "floatdisf2"
4414 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
4415 (float:SF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
4416 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4419 dslots_load_total++;
4420 if (GET_CODE (operands[1]) == MEM)
4421 return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
4423 return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
4425 [(set_attr "type" "fcvt")
4426 (set_attr "mode" "SF")
4427 (set_attr "length" "12,16,12")])
4430 (define_expand "fixuns_truncdfsi2"
4431 [(set (match_operand:SI 0 "register_operand" "")
4432 (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
4433 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4436 rtx reg1 = gen_reg_rtx (DFmode);
4437 rtx reg2 = gen_reg_rtx (DFmode);
4438 rtx reg3 = gen_reg_rtx (SImode);
4439 rtx label1 = gen_label_rtx ();
4440 rtx label2 = gen_label_rtx ();
4441 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
4443 if (reg1) /* turn off complaints about unreached code */
4445 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4446 do_pending_stack_adjust ();
4448 emit_insn (gen_cmpdf (operands[1], reg1));
4449 emit_jump_insn (gen_bge (label1));
4451 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
4452 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4453 gen_rtx_LABEL_REF (VOIDmode, label2)));
4456 emit_label (label1);
4457 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
4458 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4459 (BITMASK_HIGH, SImode)));
4461 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
4462 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4464 emit_label (label2);
4466 /* allow REG_NOTES to be set on last insn (labels don't have enough
4467 fields, and can't be used for REG_NOTES anyway). */
4468 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4474 (define_expand "fixuns_truncdfdi2"
4475 [(set (match_operand:DI 0 "register_operand" "")
4476 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
4477 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4480 rtx reg1 = gen_reg_rtx (DFmode);
4481 rtx reg2 = gen_reg_rtx (DFmode);
4482 rtx reg3 = gen_reg_rtx (DImode);
4483 rtx label1 = gen_label_rtx ();
4484 rtx label2 = gen_label_rtx ();
4485 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
4487 if (reg1) /* turn off complaints about unreached code */
4489 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4490 do_pending_stack_adjust ();
4492 emit_insn (gen_cmpdf (operands[1], reg1));
4493 emit_jump_insn (gen_bge (label1));
4495 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
4496 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4497 gen_rtx_LABEL_REF (VOIDmode, label2)));
4500 emit_label (label1);
4501 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
4502 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4503 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4505 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
4506 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4508 emit_label (label2);
4510 /* allow REG_NOTES to be set on last insn (labels don't have enough
4511 fields, and can't be used for REG_NOTES anyway). */
4512 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4518 (define_expand "fixuns_truncsfsi2"
4519 [(set (match_operand:SI 0 "register_operand" "")
4520 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
4524 rtx reg1 = gen_reg_rtx (SFmode);
4525 rtx reg2 = gen_reg_rtx (SFmode);
4526 rtx reg3 = gen_reg_rtx (SImode);
4527 rtx label1 = gen_label_rtx ();
4528 rtx label2 = gen_label_rtx ();
4529 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
4531 if (reg1) /* turn off complaints about unreached code */
4533 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4534 do_pending_stack_adjust ();
4536 emit_insn (gen_cmpsf (operands[1], reg1));
4537 emit_jump_insn (gen_bge (label1));
4539 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
4540 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4541 gen_rtx_LABEL_REF (VOIDmode, label2)));
4544 emit_label (label1);
4545 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4546 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4547 (BITMASK_HIGH, SImode)));
4549 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4550 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4552 emit_label (label2);
4554 /* allow REG_NOTES to be set on last insn (labels don't have enough
4555 fields, and can't be used for REG_NOTES anyway). */
4556 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4562 (define_expand "fixuns_truncsfdi2"
4563 [(set (match_operand:DI 0 "register_operand" "")
4564 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
4565 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4568 rtx reg1 = gen_reg_rtx (SFmode);
4569 rtx reg2 = gen_reg_rtx (SFmode);
4570 rtx reg3 = gen_reg_rtx (DImode);
4571 rtx label1 = gen_label_rtx ();
4572 rtx label2 = gen_label_rtx ();
4573 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
4575 if (reg1) /* turn off complaints about unreached code */
4577 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4578 do_pending_stack_adjust ();
4580 emit_insn (gen_cmpsf (operands[1], reg1));
4581 emit_jump_insn (gen_bge (label1));
4583 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
4584 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4585 gen_rtx_LABEL_REF (VOIDmode, label2)));
4588 emit_label (label1);
4589 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
4590 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4591 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4593 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4594 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4596 emit_label (label2);
4598 /* allow REG_NOTES to be set on last insn (labels don't have enough
4599 fields, and can't be used for REG_NOTES anyway). */
4600 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4607 ;; ....................
4611 ;; ....................
4613 ;; Bit field extract patterns which use lwl/lwr.
4615 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
4616 ;; It isn't clear whether this will give better code.
4618 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4619 (define_expand "extv"
4620 [(set (match_operand 0 "register_operand" "")
4621 (sign_extract (match_operand:QI 1 "memory_operand" "")
4622 (match_operand 2 "immediate_operand" "")
4623 (match_operand 3 "immediate_operand" "")))]
4627 /* If the field does not start on a byte boundary, then fail. */
4628 if (INTVAL (operands[3]) % 8 != 0)
4631 /* MIPS I and MIPS II can only handle a 32bit field. */
4632 if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4635 /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
4637 && INTVAL (operands[2]) != 64
4638 && INTVAL (operands[2]) != 32)
4641 /* This can happen for a 64 bit target, when extracting a value from
4642 a 64 bit union member. extract_bit_field doesn't verify that our
4643 source matches the predicate, so we force it to be a MEM here. */
4644 if (GET_CODE (operands[1]) != MEM)
4647 /* Change the mode to BLKmode for aliasing purposes. */
4648 operands[1] = adjust_address (operands[1], BLKmode, 0);
4650 /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value. */
4651 if (INTVAL (operands[2]) == 64)
4652 emit_insn (gen_movdi_uld (operands[0], operands[1]));
4657 operands[0] = gen_lowpart (SImode, operands[0]);
4658 if (operands[0] == NULL_RTX)
4661 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4666 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4667 (define_expand "extzv"
4668 [(set (match_operand 0 "register_operand" "")
4669 (zero_extract (match_operand:QI 1 "memory_operand" "")
4670 (match_operand 2 "immediate_operand" "")
4671 (match_operand 3 "immediate_operand" "")))]
4675 /* If the field does not start on a byte boundary, then fail. */
4676 if (INTVAL (operands[3]) % 8 != 0)
4679 /* MIPS I and MIPS II can only handle a 32bit field. */
4680 if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4683 /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
4685 && INTVAL (operands[2]) != 64
4686 && INTVAL (operands[2]) != 32)
4689 /* This can happen for a 64 bit target, when extracting a value from
4690 a 64 bit union member. extract_bit_field doesn't verify that our
4691 source matches the predicate, so we force it to be a MEM here. */
4692 if (GET_CODE (operands[1]) != MEM)
4695 /* Change the mode to BLKmode for aliasing purposes. */
4696 operands[1] = adjust_address (operands[1], BLKmode, 0);
4698 /* Otherwise, emit a lwl/lwr pair to load the value. */
4699 if (INTVAL (operands[2]) == 64)
4700 emit_insn (gen_movdi_uld (operands[0], operands[1]));
4705 operands[0] = gen_lowpart (SImode, operands[0]);
4706 if (operands[0] == NULL_RTX)
4709 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4714 ;; Only specify the mode operands 0, the rest are assumed to be word_mode.
4715 (define_expand "insv"
4716 [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
4717 (match_operand 1 "immediate_operand" "")
4718 (match_operand 2 "immediate_operand" ""))
4719 (match_operand 3 "register_operand" ""))]
4723 /* If the field does not start on a byte boundary, then fail. */
4724 if (INTVAL (operands[2]) % 8 != 0)
4727 /* MIPS I and MIPS II can only handle a 32bit field. */
4728 if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
4731 /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
4733 && INTVAL (operands[1]) != 64
4734 && INTVAL (operands[1]) != 32)
4737 /* This can happen for a 64 bit target, when storing into a 32 bit union
4738 member. store_bit_field doesn't verify that our target matches the
4739 predicate, so we force it to be a MEM here. */
4740 if (GET_CODE (operands[0]) != MEM)
4743 /* Change the mode to BLKmode for aliasing purposes. */
4744 operands[0] = adjust_address (operands[0], BLKmode, 0);
4746 /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value. */
4747 if (INTVAL (operands[1]) == 64)
4748 emit_insn (gen_movdi_usd (operands[0], operands[3]));
4753 operands[3] = gen_lowpart (SImode, operands[3]);
4754 if (operands[3] == NULL_RTX)
4757 emit_insn (gen_movsi_usw (operands[0], operands[3]));
4762 ;; unaligned word moves generated by the bit field patterns
4764 (define_insn "movsi_ulw"
4765 [(set (match_operand:SI 0 "register_operand" "=&d,&d")
4766 (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
4770 rtx offset = const0_rtx;
4771 rtx addr = XEXP (operands[1], 0);
4772 rtx mem_addr = eliminate_constant_term (addr, &offset);
4776 mips_count_memory_refs (operands[1], 2);
4778 /* The stack/frame pointers are always aligned, so we can convert
4779 to the faster lw if we are referencing an aligned stack location. */
4781 if ((INTVAL (offset) & 3) == 0
4782 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4783 ret = \"lw\\t%0,%1\";
4785 ret = \"ulw\\t%0,%1\";
4787 return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4789 [(set_attr "type" "load,load")
4790 (set_attr "mode" "SI")
4791 (set_attr "length" "8,16")])
4793 (define_insn "movsi_usw"
4794 [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4795 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
4799 rtx offset = const0_rtx;
4800 rtx addr = XEXP (operands[0], 0);
4801 rtx mem_addr = eliminate_constant_term (addr, &offset);
4804 mips_count_memory_refs (operands[0], 2);
4806 /* The stack/frame pointers are always aligned, so we can convert
4807 to the faster sw if we are referencing an aligned stack location. */
4809 if ((INTVAL (offset) & 3) == 0
4810 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4811 return \"sw\\t%z1,%0\";
4813 return \"usw\\t%z1,%0\";
4815 [(set_attr "type" "store")
4816 (set_attr "mode" "SI")
4817 (set_attr "length" "8,16")])
4819 ;; Bit field extract patterns which use ldl/ldr.
4821 ;; unaligned double word moves generated by the bit field patterns
4823 (define_insn "movdi_uld"
4824 [(set (match_operand:DI 0 "register_operand" "=&d,&d")
4825 (unspec:DI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
4829 rtx offset = const0_rtx;
4830 rtx addr = XEXP (operands[1], 0);
4831 rtx mem_addr = eliminate_constant_term (addr, &offset);
4835 mips_count_memory_refs (operands[1], 2);
4837 /* The stack/frame pointers are always aligned, so we can convert
4838 to the faster lw if we are referencing an aligned stack location. */
4840 if ((INTVAL (offset) & 7) == 0
4841 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4842 ret = \"ld\\t%0,%1\";
4844 ret = \"uld\\t%0,%1\";
4846 return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4848 [(set_attr "type" "load,load")
4849 (set_attr "mode" "SI")
4850 (set_attr "length" "8,16")])
4852 (define_insn "movdi_usd"
4853 [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4854 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
4858 rtx offset = const0_rtx;
4859 rtx addr = XEXP (operands[0], 0);
4860 rtx mem_addr = eliminate_constant_term (addr, &offset);
4863 mips_count_memory_refs (operands[0], 2);
4865 /* The stack/frame pointers are always aligned, so we can convert
4866 to the faster sw if we are referencing an aligned stack location. */
4868 if ((INTVAL (offset) & 7) == 0
4869 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4870 return \"sd\\t%1,%0\";
4872 return \"usd\\t%z1,%0\";
4874 [(set_attr "type" "store")
4875 (set_attr "mode" "SI")
4876 (set_attr "length" "8,16")])
4878 ;; These two patterns support loading addresses with two instructions instead
4879 ;; of using the macro instruction la.
4881 ;; ??? mips_move_1word has support for HIGH, so this pattern may be
4885 [(set (match_operand:SI 0 "register_operand" "=r")
4886 (high:SI (match_operand:SI 1 "immediate_operand" "")))]
4887 "mips_split_addresses && !TARGET_MIPS16"
4888 "lui\\t%0,%%hi(%1) # high"
4889 [(set_attr "type" "move")])
4892 [(set (match_operand:SI 0 "register_operand" "=r")
4893 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
4894 (match_operand:SI 2 "immediate_operand" "")))]
4895 "mips_split_addresses && !TARGET_MIPS16"
4896 "addiu\\t%0,%1,%%lo(%2) # low"
4897 [(set_attr "type" "arith")
4898 (set_attr "mode" "SI")])
4900 ;; 64-bit integer moves
4902 ;; Unlike most other insns, the move insns can't be split with
4903 ;; different predicates, because register spilling and other parts of
4904 ;; the compiler, have memoized the insn number already.
4906 (define_expand "movdi"
4907 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4908 (match_operand:DI 1 "general_operand" ""))]
4912 if (mips_split_addresses && mips_check_split (operands[1], DImode))
4914 enum machine_mode mode = GET_MODE (operands[0]);
4915 rtx tem = ((reload_in_progress | reload_completed)
4916 ? operands[0] : gen_reg_rtx (mode));
4918 emit_insn (gen_rtx_SET (VOIDmode, tem,
4919 gen_rtx_HIGH (mode, operands[1])));
4921 operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
4924 /* If we are generating embedded PIC code, and we are referring to a
4925 symbol in the .text section, we must use an offset from the start
4927 if (TARGET_EMBEDDED_PIC
4928 && (GET_CODE (operands[1]) == LABEL_REF
4929 || (GET_CODE (operands[1]) == SYMBOL_REF
4930 && ! SYMBOL_REF_FLAG (operands[1]))))
4934 temp = embedded_pic_offset (operands[1]);
4935 temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_rtx,
4936 force_reg (DImode, temp));
4937 emit_move_insn (operands[0], force_reg (DImode, temp));
4941 /* If operands[1] is a constant address illegal for pic, then we need to
4942 handle it just like LEGITIMIZE_ADDRESS does. */
4943 if (flag_pic && pic_address_needs_scratch (operands[1]))
4945 rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
4946 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
4948 if (! SMALL_INT (temp2))
4949 temp2 = force_reg (DImode, temp2);
4951 emit_move_insn (operands[0], gen_rtx_PLUS (DImode, temp, temp2));
4955 /* On the mips16, we can handle a GP relative reference by adding in
4956 $gp. We need to check the name to see whether this is a string
4959 && register_operand (operands[0], DImode)
4960 && GET_CODE (operands[1]) == SYMBOL_REF
4961 && SYMBOL_REF_FLAG (operands[1]))
4963 const char *name = XSTR (operands[1], 0);
4966 || strncmp (name + 1, LOCAL_LABEL_PREFIX,
4967 sizeof LOCAL_LABEL_PREFIX - 1) != 0)
4971 if (reload_in_progress || reload_completed)
4973 /* In movsi we use the constant table here. However, in
4974 this case, we're better off copying $28 into a
4975 register and adding, because the constant table entry
4976 would be 8 bytes. */
4977 base_reg = operands[0];
4978 emit_move_insn (base_reg,
4979 gen_rtx (CONST, DImode,
4980 gen_rtx (REG, DImode,
4981 GP_REG_FIRST + 28)));
4985 base_reg = gen_reg_rtx (Pmode);
4986 emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
4989 emit_move_insn (operands[0],
4990 gen_rtx (PLUS, Pmode, base_reg,
4991 mips16_gp_offset (operands[1])));
4996 if ((reload_in_progress | reload_completed) == 0
4997 && !register_operand (operands[0], DImode)
4998 && !register_operand (operands[1], DImode)
5000 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
5001 && operands[1] != CONST0_RTX (DImode))))
5003 rtx temp = force_reg (DImode, operands[1]);
5004 emit_move_insn (operands[0], temp);
5009 ;; For mips16, we need a special case to handle storing $31 into
5010 ;; memory, since we don't have a constraint to match $31. This
5011 ;; instruction can be generated by save_restore_insns.
5014 [(set (match_operand:DI 0 "memory_operand" "=R,m")
5016 "TARGET_MIPS16 && TARGET_64BIT"
5019 operands[1] = gen_rtx (REG, DImode, 31);
5020 return mips_move_2words (operands, insn);
5022 [(set_attr "type" "store")
5023 (set_attr "mode" "DI")
5024 (set_attr "length" "4,8")])
5026 (define_insn "movdi_internal"
5027 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x")
5028 (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d"))]
5029 "!TARGET_64BIT && !TARGET_MIPS16
5030 && (register_operand (operands[0], DImode)
5031 || register_operand (operands[1], DImode)
5032 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5033 || operands[1] == CONST0_RTX (DImode))"
5034 "* return mips_move_2words (operands, insn); "
5035 [(set_attr "type" "move,arith,load,load,store,store,hilo,hilo,hilo")
5036 (set_attr "mode" "DI")
5037 (set_attr "length" "8,16,8,16,8,16,8,8,8")])
5040 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,To,*d")
5041 (match_operand:DI 1 "general_operand" "d,d,y,K,N,R,To,d,d,*x"))]
5042 "!TARGET_64BIT && TARGET_MIPS16
5043 && (register_operand (operands[0], DImode)
5044 || register_operand (operands[1], DImode))"
5045 "* return mips_move_2words (operands, insn);"
5046 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
5047 (set_attr "mode" "DI")
5048 (set_attr "length" "8,8,8,8,12,8,16,8,16,8")])
5051 [(set (match_operand:DI 0 "register_operand" "")
5052 (match_operand:DI 1 "register_operand" ""))]
5053 "reload_completed && !TARGET_64BIT
5054 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
5055 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
5056 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
5058 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
5059 (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
5062 (define_insn "movdi_internal2"
5063 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a")
5064 (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J"))]
5065 "TARGET_64BIT && !TARGET_MIPS16
5066 && (register_operand (operands[0], DImode)
5067 || se_register_operand (operands[1], DImode)
5068 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5069 || operands[1] == CONST0_RTX (DImode))"
5070 "* return mips_move_2words (operands, insn); "
5071 [(set_attr "type" "move,load,arith,arith,load,load,store,store,hilo,hilo,hilo,hilo")
5072 (set_attr "mode" "DI")
5073 (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,8")])
5076 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
5077 (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
5078 "TARGET_64BIT && TARGET_MIPS16
5079 && (register_operand (operands[0], DImode)
5080 || se_register_operand (operands[1], DImode))"
5081 "* return mips_move_2words (operands, insn);"
5082 [(set_attr "type" "move,move,move,arith,arith,arith,load,load,store,store,hilo")
5083 (set_attr "mode" "DI")
5084 (set_attr_alternative "length"
5088 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5091 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5094 (if_then_else (match_operand:VOID 1 "m16_usym5_4" "")
5103 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
5104 ;; when the original load is a 4 byte instruction but the add and the
5105 ;; load are 2 2 byte instructions.
5108 [(set (match_operand:DI 0 "register_operand" "")
5109 (mem:DI (plus:DI (match_dup 0)
5110 (match_operand:DI 1 "const_int_operand" ""))))]
5111 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
5112 && !TARGET_DEBUG_D_MODE
5113 && GET_CODE (operands[0]) == REG
5114 && M16_REG_P (REGNO (operands[0]))
5115 && GET_CODE (operands[1]) == CONST_INT
5116 && ((INTVAL (operands[1]) < 0
5117 && INTVAL (operands[1]) >= -0x10)
5118 || (INTVAL (operands[1]) >= 32 * 8
5119 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
5120 || (INTVAL (operands[1]) >= 0
5121 && INTVAL (operands[1]) < 32 * 8
5122 && (INTVAL (operands[1]) & 7) != 0))"
5123 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
5124 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
5127 HOST_WIDE_INT val = INTVAL (operands[1]);
5130 operands[2] = GEN_INT (0);
5131 else if (val >= 32 * 8)
5135 operands[1] = GEN_INT (0x8 + off);
5136 operands[2] = GEN_INT (val - off - 0x8);
5142 operands[1] = GEN_INT (off);
5143 operands[2] = GEN_INT (val - off);
5147 ;; Handle input reloads in DImode.
5148 ;; This is mainly to handle reloading HILO_REGNUM. Note that we may
5149 ;; see it as the source or the destination, depending upon which way
5150 ;; reload handles the instruction.
5151 ;; Making the second operand TImode is a trick. The compiler may
5152 ;; reuse the same register for operand 0 and operand 2. Using TImode
5153 ;; gives us two registers, so we can always use the one which is not
5156 (define_expand "reload_indi"
5157 [(set (match_operand:DI 0 "register_operand" "=b")
5158 (match_operand:DI 1 "" "b"))
5159 (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5163 rtx scratch = gen_rtx_REG (DImode,
5164 (REGNO (operands[0]) == REGNO (operands[2])
5165 ? REGNO (operands[2]) + 1
5166 : REGNO (operands[2])));
5168 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5170 if (GET_CODE (operands[1]) == MEM)
5172 rtx memword, offword, hi_word, lo_word;
5173 rtx addr = find_replacement (&XEXP (operands[1], 0));
5174 rtx op1 = replace_equiv_address (operands[1], addr);
5176 scratch = gen_rtx_REG (SImode, REGNO (scratch));
5177 memword = adjust_address (op1, SImode, 0);
5178 offword = adjust_address (op1, SImode, 4);
5180 if (BYTES_BIG_ENDIAN)
5190 emit_move_insn (scratch, hi_word);
5191 emit_move_insn (gen_rtx_REG (SImode, 64), scratch);
5192 emit_move_insn (scratch, lo_word);
5193 emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
5194 emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[0]), 2));
5198 emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5199 emit_insn (gen_movdi (gen_rtx_REG (DImode, 64), scratch));
5200 emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5201 emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5202 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5203 emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[0]), 2));
5207 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5209 emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 65)));
5210 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5211 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5212 emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 64)));
5213 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5214 emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5215 emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[1]), 2));
5218 /* This handles moves between a float register and HI/LO. */
5219 emit_move_insn (scratch, operands[1]);
5220 emit_move_insn (operands[0], scratch);
5224 ;; Handle output reloads in DImode.
5226 ;; Reloading HILO_REG in MIPS16 mode requires two scratch registers, so we
5227 ;; use a TImode scratch reg.
5229 (define_expand "reload_outdi"
5230 [(set (match_operand:DI 0 "general_operand" "=b")
5231 (match_operand:DI 1 "se_register_operand" "b"))
5232 (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5236 rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5238 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5240 emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5241 emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
5242 emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5243 emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5244 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5245 emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[0]), 2));
5248 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5250 if (GET_CODE (operands[0]) == MEM)
5252 rtx scratch, memword, offword, hi_word, lo_word;
5253 rtx addr = find_replacement (&XEXP (operands[0], 0));
5254 rtx op0 = replace_equiv_address (operands[0], addr);
5256 scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
5257 memword = adjust_address (op0, SImode, 0);
5258 offword = adjust_address (op0, SImode, 4);
5260 if (BYTES_BIG_ENDIAN)
5270 emit_move_insn (scratch, gen_rtx_REG (SImode, 64));
5271 emit_move_insn (hi_word, scratch);
5272 emit_move_insn (scratch, gen_rtx_REG (SImode, 65));
5273 emit_move_insn (lo_word, scratch);
5274 emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[1]), 2));
5276 else if (TARGET_MIPS16 && ! M16_REG_P (REGNO (operands[0])))
5278 /* Handle the case where operand[0] is not a 'd' register,
5279 and hence we can not directly move from the HILO register
5281 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5282 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5283 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5284 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5285 emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64)));
5286 emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
5287 emit_insn (gen_iordi3 (scratch, scratch, scratch2));
5288 emit_insn (gen_movdi (operands[0], scratch));
5289 emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[1]), 2));
5293 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5294 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5295 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5296 emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
5297 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5298 emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5299 emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[1]), 2));
5303 /* This handles moves between a float register and HI/LO. */
5304 emit_move_insn (scratch, operands[1]);
5305 emit_move_insn (operands[0], scratch);
5309 ;; 32-bit Integer moves
5312 [(set (match_operand:SI 0 "register_operand" "")
5313 (match_operand:SI 1 "large_int" ""))]
5314 "!TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
5318 (ior:SI (match_dup 0)
5322 operands[2] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
5325 operands[3] = GEN_INT (INTVAL (operands[1]) & BITMASK_LOWER16);
5328 ;; Unlike most other insns, the move insns can't be split with
5329 ;; different predicates, because register spilling and other parts of
5330 ;; the compiler, have memoized the insn number already.
5332 (define_expand "movsi"
5333 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5334 (match_operand:SI 1 "general_operand" ""))]
5338 if (mips_split_addresses && mips_check_split (operands[1], SImode))
5340 enum machine_mode mode = GET_MODE (operands[0]);
5341 rtx tem = ((reload_in_progress | reload_completed)
5342 ? operands[0] : gen_reg_rtx (mode));
5344 emit_insn (gen_rtx_SET (VOIDmode, tem,
5345 gen_rtx_HIGH (mode, operands[1])));
5347 operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
5350 /* If we are generating embedded PIC code, and we are referring to a
5351 symbol in the .text section, we must use an offset from the start
5353 if (TARGET_EMBEDDED_PIC
5354 && (GET_CODE (operands[1]) == LABEL_REF
5355 || (GET_CODE (operands[1]) == SYMBOL_REF
5356 && ! SYMBOL_REF_FLAG (operands[1]))))
5360 temp = embedded_pic_offset (operands[1]);
5361 temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_rtx,
5362 force_reg (SImode, temp));
5363 emit_move_insn (operands[0], force_reg (SImode, temp));
5367 /* If operands[1] is a constant address invalid for pic, then we need to
5368 handle it just like LEGITIMIZE_ADDRESS does. */
5369 if (flag_pic && pic_address_needs_scratch (operands[1]))
5371 rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
5372 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
5374 if (! SMALL_INT (temp2))
5375 temp2 = force_reg (SImode, temp2);
5377 emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, temp2));
5381 /* On the mips16, we can handle a GP relative reference by adding in
5382 $gp. We need to check the name to see whether this is a string
5385 && register_operand (operands[0], SImode)
5386 && GET_CODE (operands[1]) == SYMBOL_REF
5387 && SYMBOL_REF_FLAG (operands[1]))
5389 const char *name = XSTR (operands[1], 0);
5392 || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5393 sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5397 if (reload_in_progress || reload_completed)
5399 /* We need to reload this address. In this case we
5400 aren't going to have a chance to combine loading the
5401 address with the load or store. That means that we
5402 can either generate a 2 byte move followed by a 4
5403 byte addition, or a 2 byte load with a 4 byte entry
5404 in the constant table. Since the entry in the
5405 constant table might be shared, we're better off, on
5406 average, loading the address from the constant table. */
5407 emit_move_insn (operands[0],
5408 force_const_mem (SImode, operands[1]));
5412 base_reg = gen_reg_rtx (Pmode);
5413 emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
5415 emit_move_insn (operands[0],
5416 gen_rtx (PLUS, Pmode, base_reg,
5417 mips16_gp_offset (operands[1])));
5422 if ((reload_in_progress | reload_completed) == 0
5423 && !register_operand (operands[0], SImode)
5424 && !register_operand (operands[1], SImode)
5426 || GET_CODE (operands[1]) != CONST_INT
5427 || INTVAL (operands[1]) != 0))
5429 rtx temp = force_reg (SImode, operands[1]);
5430 emit_move_insn (operands[0], temp);
5435 ;; For mips16, we need a special case to handle storing $31 into
5436 ;; memory, since we don't have a constraint to match $31. This
5437 ;; instruction can be generated by save_restore_insns.
5440 [(set (match_operand:SI 0 "memory_operand" "=R,m")
5445 operands[1] = gen_rtx (REG, SImode, 31);
5446 return mips_move_1word (operands, insn, FALSE);
5448 [(set_attr "type" "store")
5449 (set_attr "mode" "SI")
5450 (set_attr "length" "4,8")])
5452 ;; The difference between these two is whether or not ints are allowed
5453 ;; in FP registers (off by default, use -mdebugh to enable).
5455 (define_insn "movsi_internal1"
5456 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*f*z,*f,*f,*f,*R,*m,*x,*x,*d,*d")
5457 (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*f*z,*d,*f,*R,*m,*f,*f,J,*d,*x,*a"))]
5458 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5459 && (register_operand (operands[0], SImode)
5460 || register_operand (operands[1], SImode)
5461 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5462 "* return mips_move_1word (operands, insn, FALSE);"
5463 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo,hilo,hilo")
5464 (set_attr "mode" "SI")
5465 (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,4,8,4,8,4,4,4,4")])
5467 (define_insn "movsi_internal2"
5468 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d")
5469 (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a"))]
5470 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5471 && (register_operand (operands[0], SImode)
5472 || register_operand (operands[1], SImode)
5473 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5474 "* return mips_move_1word (operands, insn, FALSE);"
5475 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo")
5476 (set_attr "mode" "SI")
5477 (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,4,4,4")])
5479 ;; This is the mips16 movsi instruction. We accept a small integer as
5480 ;; the source if the destination is a GP memory reference. This is
5481 ;; because we want the combine pass to turn adding a GP reference to a
5482 ;; register into a direct GP reference, but the combine pass will pass
5483 ;; in the source as a constant if it finds an equivalent one. If the
5484 ;; instruction is recognized, reload will force the constant back out
5488 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,d,R,m,*d,*d")
5489 (match_operand:SI 1 "move_operand" "d,d,y,S,K,N,s,R,m,d,d,*x,*a"))]
5491 && (register_operand (operands[0], SImode)
5492 || register_operand (operands[1], SImode)
5493 || (GET_CODE (operands[0]) == MEM
5494 && GET_CODE (XEXP (operands[0], 0)) == PLUS
5495 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST
5496 && mips16_gp_offset_p (XEXP (XEXP (operands[0], 0), 1))
5497 && GET_CODE (operands[1]) == CONST_INT
5498 && (SMALL_INT (operands[1])
5499 || SMALL_INT_UNSIGNED (operands[1]))))"
5500 "* return mips_move_1word (operands, insn, FALSE);"
5501 [(set_attr "type" "move,move,move,load,arith,arith,arith,load,load,store,store,hilo,hilo")
5502 (set_attr "mode" "SI")
5503 (set_attr_alternative "length"
5508 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5511 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5514 (if_then_else (match_operand:VOID 1 "m16_usym8_4" "")
5524 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
5525 ;; when the original load is a 4 byte instruction but the add and the
5526 ;; load are 2 2 byte instructions.
5529 [(set (match_operand:SI 0 "register_operand" "")
5530 (mem:SI (plus:SI (match_dup 0)
5531 (match_operand:SI 1 "const_int_operand" ""))))]
5532 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5533 && GET_CODE (operands[0]) == REG
5534 && M16_REG_P (REGNO (operands[0]))
5535 && GET_CODE (operands[1]) == CONST_INT
5536 && ((INTVAL (operands[1]) < 0
5537 && INTVAL (operands[1]) >= -0x80)
5538 || (INTVAL (operands[1]) >= 32 * 4
5539 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
5540 || (INTVAL (operands[1]) >= 0
5541 && INTVAL (operands[1]) < 32 * 4
5542 && (INTVAL (operands[1]) & 3) != 0))"
5543 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5544 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
5547 HOST_WIDE_INT val = INTVAL (operands[1]);
5550 operands[2] = GEN_INT (0);
5551 else if (val >= 32 * 4)
5555 operands[1] = GEN_INT (0x7c + off);
5556 operands[2] = GEN_INT (val - off - 0x7c);
5562 operands[1] = GEN_INT (off);
5563 operands[2] = GEN_INT (val - off);
5567 ;; On the mips16, we can split a load of certain constants into a load
5568 ;; and an add. This turns a 4 byte instruction into 2 2 byte
5572 [(set (match_operand:SI 0 "register_operand" "")
5573 (match_operand:SI 1 "const_int_operand" ""))]
5574 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5575 && GET_CODE (operands[0]) == REG
5576 && M16_REG_P (REGNO (operands[0]))
5577 && GET_CODE (operands[1]) == CONST_INT
5578 && INTVAL (operands[1]) >= 0x100
5579 && INTVAL (operands[1]) <= 0xff + 0x7f"
5580 [(set (match_dup 0) (match_dup 1))
5581 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
5584 int val = INTVAL (operands[1]);
5586 operands[1] = GEN_INT (0xff);
5587 operands[2] = GEN_INT (val - 0xff);
5590 ;; On the mips16, we can split a load of a negative constant into a
5591 ;; load and a neg. That's what mips_move_1word will generate anyhow.
5594 [(set (match_operand:SI 0 "register_operand" "")
5595 (match_operand:SI 1 "const_int_operand" ""))]
5596 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5597 && GET_CODE (operands[0]) == REG
5598 && M16_REG_P (REGNO (operands[0]))
5599 && GET_CODE (operands[1]) == CONST_INT
5600 && INTVAL (operands[1]) < 0
5601 && INTVAL (operands[1]) > - 0x8000"
5602 [(set (match_dup 0) (match_dup 1))
5603 (set (match_dup 0) (neg:SI (match_dup 0)))]
5606 operands[1] = GEN_INT (- INTVAL (operands[1]));
5609 ;; Reload HILO_REGNUM in SI mode. This needs a scratch register in
5610 ;; order to set the sign bit correctly in the HI register.
5612 (define_expand "reload_outsi"
5613 [(set (match_operand:SI 0 "general_operand" "=b")
5614 (match_operand:SI 1 "register_operand" "b"))
5615 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5616 "TARGET_64BIT || TARGET_MIPS16"
5620 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5622 emit_insn (gen_movsi (gen_rtx_REG (SImode, 65), operands[1]));
5623 emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
5624 emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
5625 emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[0]), 2));
5628 /* Use a mult to reload LO on mips16. ??? This is hideous. */
5630 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5632 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5633 /* This is gen_mulsi3_internal, but we need to fill in the
5634 scratch registers. */
5635 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5637 gen_rtx (SET, VOIDmode,
5639 gen_rtx (MULT, SImode,
5642 gen_rtx (CLOBBER, VOIDmode,
5643 gen_rtx (REG, SImode, 64)),
5644 gen_rtx (CLOBBER, VOIDmode,
5645 gen_rtx (REG, SImode, 66)))));
5648 /* FIXME: I don't know how to get a value into the HI register. */
5649 if (GET_CODE (operands[0]) == REG
5650 && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0]))
5651 : GP_REG_P (REGNO (operands[0]))))
5653 emit_move_insn (operands[0], operands[1]);
5656 /* This handles moves between a float register and HI/LO. */
5657 emit_move_insn (operands[2], operands[1]);
5658 emit_move_insn (operands[0], operands[2]);
5662 ;; Reload a value into HI or LO. There is no mthi or mtlo on mips16,
5663 ;; so we use a mult. ??? This is hideous, and we ought to figure out
5664 ;; something better.
5666 ;; We use no predicate for operand1, because it may be a PLUS, and there
5667 ;; is no convenient predicate for that.
5669 (define_expand "reload_insi"
5670 [(set (match_operand:SI 0 "register_operand" "=b")
5671 (match_operand:SI 1 "" "b"))
5672 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5677 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5679 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5680 /* This is gen_mulsi3_internal, but we need to fill in the
5681 scratch registers. */
5682 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5684 gen_rtx (SET, VOIDmode,
5686 gen_rtx (MULT, SImode,
5689 gen_rtx (CLOBBER, VOIDmode,
5690 gen_rtx (REG, SImode, 64)),
5691 gen_rtx (CLOBBER, VOIDmode,
5692 gen_rtx (REG, SImode, 66)))));
5696 /* If this is a plus, then this must be an add of the stack pointer against
5697 either a hard register or a pseudo. */
5698 if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
5702 if (XEXP (operands[1], 0) == stack_pointer_rtx)
5703 plus_op = XEXP (operands[1], 1);
5704 else if (XEXP (operands[1], 1) == stack_pointer_rtx)
5705 plus_op = XEXP (operands[1], 0);
5709 /* We should have a register now. */
5710 if (GET_CODE (plus_op) != REG)
5713 if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
5715 /* We have to have at least one temporary register which is not
5716 overlapping plus_op. */
5717 if (! rtx_equal_p (plus_op, operands[0]))
5719 emit_move_insn (operands[0], stack_pointer_rtx);
5720 emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
5722 else if (! rtx_equal_p (plus_op, operands[2]))
5724 emit_move_insn (operands[2], stack_pointer_rtx);
5725 emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
5732 /* We need two registers in this case. */
5733 if (! rtx_equal_p (operands[0], operands[2]))
5735 emit_move_insn (operands[0], stack_pointer_rtx);
5736 emit_move_insn (operands[2], plus_op);
5737 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
5745 /* FIXME: I don't know how to get a value into the HI register. */
5746 emit_move_insn (operands[0], operands[1]);
5750 ;; This insn is for the unspec delay for HILO.
5752 (define_insn "*HILO_delay"
5753 [(unspec [(match_operand 0 "register_operand" "=b")] 2 )]
5756 [(set_attr "type" "nop")
5757 (set_attr "mode" "none")])
5759 ;; This insn handles moving CCmode values. It's really just a
5760 ;; slightly simplified copy of movsi_internal2, with additional cases
5761 ;; to move a condition register to a general register and to move
5762 ;; between the general registers and the floating point registers.
5764 (define_insn "movcc"
5765 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
5766 (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
5767 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5768 "* return mips_move_1word (operands, insn, FALSE);"
5769 [(set_attr "type" "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
5770 (set_attr "mode" "SI")
5771 (set_attr "length" "8,4,4,8,4,8,4,4,4,4,8,4,8")])
5773 ;; Reload condition code registers. These need scratch registers.
5775 (define_expand "reload_incc"
5776 [(set (match_operand:CC 0 "register_operand" "=z")
5777 (match_operand:CC 1 "general_operand" "z"))
5778 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
5779 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5786 /* This is called when are copying some value into a condition code
5787 register. Operand 0 is the condition code register. Operand 1
5788 is the source. Operand 2 is a scratch register; we use TFmode
5789 because we actually need two floating point registers. */
5790 if (! ST_REG_P (true_regnum (operands[0]))
5791 || ! FP_REG_P (true_regnum (operands[2])))
5794 /* We need to get the source in SFmode so that the insn is
5796 if (GET_CODE (operands[1]) == MEM)
5797 source = adjust_address (operands[1], SFmode, 0);
5798 else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
5799 source = gen_rtx_REG (SFmode, true_regnum (operands[1]));
5801 source = operands[1];
5803 /* FP1 and FP2 are the two halves of the TFmode scratch operand. They
5804 will be single registers in 64-bit mode and register pairs in 32-bit
5805 mode. SOURCE is loaded into FP1 and zero is loaded into FP2. */
5806 regno = REGNO (operands[2]);
5807 fp1 = gen_rtx_REG (SFmode, regno);
5808 fp2 = gen_rtx_REG (SFmode, regno + HARD_REGNO_NREGS (regno, DFmode));
5810 emit_insn (gen_move_insn (fp1, source));
5811 emit_insn (gen_move_insn (fp2, gen_rtx_REG (SFmode, 0)));
5812 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5813 gen_rtx_LT (CCmode, fp2, fp1)));
5818 (define_expand "reload_outcc"
5819 [(set (match_operand:CC 0 "general_operand" "=z")
5820 (match_operand:CC 1 "register_operand" "z"))
5821 (clobber (match_operand:CC 2 "register_operand" "=&d"))]
5822 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
5825 /* This is called when we are copying a condition code register out
5826 to save it somewhere. Operand 0 should be the location we are
5827 going to save it to. Operand 1 should be the condition code
5828 register. Operand 2 should be a scratch general purpose register
5829 created for us by reload. The mips_secondary_reload_class
5830 function should have told reload that we don't need a scratch
5831 register if the destination is a general purpose register anyhow. */
5832 if (ST_REG_P (true_regnum (operands[0]))
5833 || GP_REG_P (true_regnum (operands[0]))
5834 || ! ST_REG_P (true_regnum (operands[1]))
5835 || ! GP_REG_P (true_regnum (operands[2])))
5838 /* All we have to do is copy the value from the condition code to
5839 the data register, which movcc can handle, and then store the
5840 value into the real final destination. */
5841 emit_insn (gen_move_insn (operands[2], operands[1]));
5842 emit_insn (gen_move_insn (operands[0], operands[2]));
5847 ;; MIPS4 supports loading and storing a floating point register from
5848 ;; the sum of two general registers. We use two versions for each of
5849 ;; these four instructions: one where the two general registers are
5850 ;; SImode, and one where they are DImode. This is because general
5851 ;; registers will be in SImode when they hold 32 bit values, but,
5852 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
5853 ;; instructions will still work correctly.
5855 ;; ??? Perhaps it would be better to support these instructions by
5856 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
5857 ;; these instructions can only be used to load and store floating
5858 ;; point registers, that would probably cause trouble in reload.
5861 [(set (match_operand:SF 0 "register_operand" "=f")
5862 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5863 (match_operand:SI 2 "register_operand" "d"))))]
5864 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5866 [(set_attr "type" "load")
5867 (set_attr "mode" "SF")])
5870 [(set (match_operand:SF 0 "register_operand" "=f")
5871 (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5872 (match_operand:DI 2 "se_register_operand" "d"))))]
5873 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5875 [(set_attr "type" "load")
5876 (set_attr "mode" "SF")])
5879 [(set (match_operand:DF 0 "register_operand" "=f")
5880 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5881 (match_operand:SI 2 "register_operand" "d"))))]
5882 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5884 [(set_attr "type" "load")
5885 (set_attr "mode" "DF")])
5888 [(set (match_operand:DF 0 "register_operand" "=f")
5889 (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5890 (match_operand:DI 2 "se_register_operand" "d"))))]
5891 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5893 [(set_attr "type" "load")
5894 (set_attr "mode" "DF")])
5897 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5898 (match_operand:SI 2 "register_operand" "d")))
5899 (match_operand:SF 0 "register_operand" "f"))]
5900 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5902 [(set_attr "type" "store")
5903 (set_attr "mode" "SF")])
5906 [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5907 (match_operand:DI 2 "se_register_operand" "d")))
5908 (match_operand:SF 0 "register_operand" "f"))]
5909 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
5911 [(set_attr "type" "store")
5912 (set_attr "mode" "SF")])
5915 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5916 (match_operand:SI 2 "register_operand" "d")))
5917 (match_operand:DF 0 "register_operand" "f"))]
5918 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5920 [(set_attr "type" "store")
5921 (set_attr "mode" "DF")])
5924 [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5925 (match_operand:DI 2 "se_register_operand" "d")))
5926 (match_operand:DF 0 "register_operand" "f"))]
5927 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5929 [(set_attr "type" "store")
5930 (set_attr "mode" "DF")])
5932 ;; 16-bit Integer moves
5934 ;; Unlike most other insns, the move insns can't be split with
5935 ;; different predicates, because register spilling and other parts of
5936 ;; the compiler, have memoized the insn number already.
5937 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5939 (define_expand "movhi"
5940 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5941 (match_operand:HI 1 "general_operand" ""))]
5945 if ((reload_in_progress | reload_completed) == 0
5946 && !register_operand (operands[0], HImode)
5947 && !register_operand (operands[1], HImode)
5949 || (GET_CODE (operands[1]) != CONST_INT
5950 || INTVAL (operands[1]) != 0)))
5952 rtx temp = force_reg (HImode, operands[1]);
5953 emit_move_insn (operands[0], temp);
5958 ;; The difference between these two is whether or not ints are allowed
5959 ;; in FP registers (off by default, use -mdebugh to enable).
5961 (define_insn "movhi_internal1"
5962 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
5963 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
5964 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5965 && (register_operand (operands[0], HImode)
5966 || register_operand (operands[1], HImode)
5967 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5968 "* return mips_move_1word (operands, insn, TRUE);"
5969 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
5970 (set_attr "mode" "HI")
5971 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
5973 (define_insn "movhi_internal2"
5974 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
5975 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
5976 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5977 && (register_operand (operands[0], HImode)
5978 || register_operand (operands[1], HImode)
5979 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5980 "* return mips_move_1word (operands, insn, TRUE);"
5981 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
5982 (set_attr "mode" "HI")
5983 (set_attr "length" "4,4,4,8,4,8,4,4,4,4")])
5986 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
5987 (match_operand:HI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
5989 && (register_operand (operands[0], HImode)
5990 || register_operand (operands[1], HImode))"
5991 "* return mips_move_1word (operands, insn, TRUE);"
5992 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
5993 (set_attr "mode" "HI")
5994 (set_attr_alternative "length"
5998 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
6001 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6011 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
6012 ;; when the original load is a 4 byte instruction but the add and the
6013 ;; load are 2 2 byte instructions.
6016 [(set (match_operand:HI 0 "register_operand" "")
6017 (mem:HI (plus:SI (match_dup 0)
6018 (match_operand:SI 1 "const_int_operand" ""))))]
6019 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6020 && GET_CODE (operands[0]) == REG
6021 && M16_REG_P (REGNO (operands[0]))
6022 && GET_CODE (operands[1]) == CONST_INT
6023 && ((INTVAL (operands[1]) < 0
6024 && INTVAL (operands[1]) >= -0x80)
6025 || (INTVAL (operands[1]) >= 32 * 2
6026 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
6027 || (INTVAL (operands[1]) >= 0
6028 && INTVAL (operands[1]) < 32 * 2
6029 && (INTVAL (operands[1]) & 1) != 0))"
6030 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6031 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
6034 HOST_WIDE_INT val = INTVAL (operands[1]);
6037 operands[2] = GEN_INT (0);
6038 else if (val >= 32 * 2)
6042 operands[1] = GEN_INT (0x7e + off);
6043 operands[2] = GEN_INT (val - off - 0x7e);
6049 operands[1] = GEN_INT (off);
6050 operands[2] = GEN_INT (val - off);
6054 ;; 8-bit Integer moves
6056 ;; Unlike most other insns, the move insns can't be split with
6057 ;; different predicates, because register spilling and other parts of
6058 ;; the compiler, have memoized the insn number already.
6059 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
6061 (define_expand "movqi"
6062 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6063 (match_operand:QI 1 "general_operand" ""))]
6067 if ((reload_in_progress | reload_completed) == 0
6068 && !register_operand (operands[0], QImode)
6069 && !register_operand (operands[1], QImode)
6071 || (GET_CODE (operands[1]) != CONST_INT
6072 || INTVAL (operands[1]) != 0)))
6074 rtx temp = force_reg (QImode, operands[1]);
6075 emit_move_insn (operands[0], temp);
6080 ;; The difference between these two is whether or not ints are allowed
6081 ;; in FP registers (off by default, use -mdebugh to enable).
6083 (define_insn "movqi_internal1"
6084 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
6085 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
6086 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6087 && (register_operand (operands[0], QImode)
6088 || register_operand (operands[1], QImode)
6089 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6090 "* return mips_move_1word (operands, insn, TRUE);"
6091 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
6092 (set_attr "mode" "QI")
6093 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
6095 (define_insn "movqi_internal2"
6096 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
6097 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
6098 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
6099 && (register_operand (operands[0], QImode)
6100 || register_operand (operands[1], QImode)
6101 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
6102 "* return mips_move_1word (operands, insn, TRUE);"
6103 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
6104 (set_attr "mode" "QI")
6105 (set_attr "length" "4,4,4,8,4,8,4,4,4,4")])
6108 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
6109 (match_operand:QI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
6111 && (register_operand (operands[0], QImode)
6112 || register_operand (operands[1], QImode))"
6113 "* return mips_move_1word (operands, insn, TRUE);"
6114 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
6115 (set_attr "mode" "QI")
6116 (set_attr_alternative "length"
6120 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
6123 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
6133 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
6134 ;; when the original load is a 4 byte instruction but the add and the
6135 ;; load are 2 2 byte instructions.
6138 [(set (match_operand:QI 0 "register_operand" "")
6139 (mem:QI (plus:SI (match_dup 0)
6140 (match_operand:SI 1 "const_int_operand" ""))))]
6141 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6142 && GET_CODE (operands[0]) == REG
6143 && M16_REG_P (REGNO (operands[0]))
6144 && GET_CODE (operands[1]) == CONST_INT
6145 && ((INTVAL (operands[1]) < 0
6146 && INTVAL (operands[1]) >= -0x80)
6147 || (INTVAL (operands[1]) >= 32
6148 && INTVAL (operands[1]) <= 31 + 0x7f))"
6149 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6150 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
6153 HOST_WIDE_INT val = INTVAL (operands[1]);
6156 operands[2] = GEN_INT (0);
6159 operands[1] = GEN_INT (0x7f);
6160 operands[2] = GEN_INT (val - 0x7f);
6164 ;; 32-bit floating point moves
6166 (define_expand "movsf"
6167 [(set (match_operand:SF 0 "nonimmediate_operand" "")
6168 (match_operand:SF 1 "general_operand" ""))]
6172 if ((reload_in_progress | reload_completed) == 0
6173 && !register_operand (operands[0], SFmode)
6174 && !register_operand (operands[1], SFmode)
6176 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6177 && operands[1] != CONST0_RTX (SFmode))))
6179 rtx temp = force_reg (SFmode, operands[1]);
6180 emit_move_insn (operands[0], temp);
6185 (define_insn "movsf_internal1"
6186 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
6187 (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
6189 && (register_operand (operands[0], SFmode)
6190 || register_operand (operands[1], SFmode)
6191 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6192 || operands[1] == CONST0_RTX (SFmode))"
6193 "* return mips_move_1word (operands, insn, FALSE);"
6194 [(set_attr "type" "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
6195 (set_attr "mode" "SF")
6196 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,8,4,8")])
6199 (define_insn "movsf_internal2"
6200 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
6201 (match_operand:SF 1 "general_operand" " Gd,R,Fm,d,d"))]
6202 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
6203 && (register_operand (operands[0], SFmode)
6204 || register_operand (operands[1], SFmode)
6205 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6206 || operands[1] == CONST0_RTX (SFmode))"
6207 "* return mips_move_1word (operands, insn, FALSE);"
6208 [(set_attr "type" "move,load,load,store,store")
6209 (set_attr "mode" "SF")
6210 (set_attr "length" "4,4,8,4,8")])
6213 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m")
6214 (match_operand:SF 1 "general_operand" "d,d,y,R,Fm,d,d"))]
6216 && (register_operand (operands[0], SFmode)
6217 || register_operand (operands[1], SFmode))"
6218 "* return mips_move_1word (operands, insn, FALSE);"
6219 [(set_attr "type" "move,move,move,load,load,store,store")
6220 (set_attr "mode" "SF")
6221 (set_attr "length" "4,4,4,4,8,4,8")])
6224 ;; 64-bit floating point moves
6226 (define_expand "movdf"
6227 [(set (match_operand:DF 0 "nonimmediate_operand" "")
6228 (match_operand:DF 1 "general_operand" ""))]
6232 if ((reload_in_progress | reload_completed) == 0
6233 && !register_operand (operands[0], DFmode)
6234 && !register_operand (operands[1], DFmode)
6236 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6237 && operands[1] != CONST0_RTX (DFmode))))
6239 rtx temp = force_reg (DFmode, operands[1]);
6240 emit_move_insn (operands[0], temp);
6245 (define_insn "movdf_internal1"
6246 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,To,f,*f,*d,*d,*d,*d,*R,*T")
6247 (match_operand:DF 1 "general_operand" "f,R,To,fG,fG,F,*d,*f,*d*G,*R,*T*F,*d,*d"))]
6248 "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
6249 && TARGET_DOUBLE_FLOAT
6250 && (register_operand (operands[0], DFmode)
6251 || register_operand (operands[1], DFmode)
6252 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6253 || operands[1] == CONST0_RTX (DFmode))"
6254 "* return mips_move_2words (operands, insn); "
6255 [(set_attr "type" "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
6256 (set_attr "mode" "DF")
6257 (set_attr "length" "4,8,16,8,16,16,8,8,8,8,16,8,16")])
6259 (define_insn "movdf_internal1a"
6260 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,*d,*d,*d,*To,*R,*d")
6261 (match_operand:DF 1 "general_operand" " f,To,f,G,f,G,*F,*To,*R,*d,*d,*d"))]
6262 "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
6263 && TARGET_DOUBLE_FLOAT
6264 && (register_operand (operands[0], DFmode)
6265 || register_operand (operands[1], DFmode)
6266 || (GET_CODE (operands [0]) == MEM
6267 && ((GET_CODE (operands[1]) == CONST_INT
6268 && INTVAL (operands[1]) == 0)
6269 || operands[1] == CONST0_RTX (DFmode))))"
6270 "* return mips_move_2words (operands, insn); "
6271 [(set_attr "type" "move,load,store,store,store,store,load,load,load,store,store,move")
6272 (set_attr "mode" "DF")
6273 (set_attr "length" "4,8,4,4,8,8,8,8,4,8,4,4")])
6275 (define_insn "movdf_internal2"
6276 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To,*d")
6277 (match_operand:DF 1 "general_operand" "dG,R,ToF,d,d,*f"))]
6278 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
6279 && (register_operand (operands[0], DFmode)
6280 || register_operand (operands[1], DFmode)
6281 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6282 || operands[1] == CONST0_RTX (DFmode))"
6283 "* return mips_move_2words (operands, insn); "
6284 [(set_attr "type" "move,load,load,store,store,xfer")
6285 (set_attr "mode" "DF")
6286 (set_attr "length" "8,8,16,8,16,8")])
6289 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To")
6290 (match_operand:DF 1 "general_operand" "d,d,y,R,ToF,d,d"))]
6292 && (register_operand (operands[0], DFmode)
6293 || register_operand (operands[1], DFmode))"
6294 "* return mips_move_2words (operands, insn);"
6295 [(set_attr "type" "move,move,move,load,load,store,store")
6296 (set_attr "mode" "DF")
6297 (set_attr "length" "8,8,8,8,16,8,16")])
6300 [(set (match_operand:DF 0 "register_operand" "")
6301 (match_operand:DF 1 "register_operand" ""))]
6302 "reload_completed && !TARGET_64BIT
6303 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6304 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
6305 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
6306 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
6307 (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
6310 ;; Instructions to load the global pointer register.
6311 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
6312 ;; uses in front of it. All symbol_refs implicitly use the gp reg.
6314 (define_insn "loadgp"
6316 (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
6317 (match_operand:DI 1 "register_operand" "")] 2))
6318 (clobber (reg:DI 1))]
6320 "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]"
6321 [(set_attr "type" "move")
6322 (set_attr "mode" "DI")
6323 (set_attr "length" "12")])
6325 ;; Block moves, see mips.c for more details.
6326 ;; Argument 0 is the destination
6327 ;; Argument 1 is the source
6328 ;; Argument 2 is the length
6329 ;; Argument 3 is the alignment
6331 (define_expand "movstrsi"
6332 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
6333 (match_operand:BLK 1 "general_operand" ""))
6334 (use (match_operand:SI 2 "arith32_operand" ""))
6335 (use (match_operand:SI 3 "immediate_operand" ""))])]
6339 if (operands[0]) /* avoid unused code messages */
6341 expand_block_move (operands);
6346 ;; Insn generated by block moves
6348 (define_insn "movstrsi_internal"
6349 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6350 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6351 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6352 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6353 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6354 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6355 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6356 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6357 (use (const_int 0))] ;; normal block move
6359 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6360 [(set_attr "type" "store")
6361 (set_attr "mode" "none")
6362 (set_attr "length" "80")])
6364 ;; We need mips16 versions, because an offset from the stack pointer
6365 ;; is not offsettable, since the stack pointer can only handle 4 and 8
6369 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6370 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6371 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6372 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6373 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6374 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6375 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6376 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6377 (use (const_int 0))] ;; normal block move
6379 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6380 [(set_attr "type" "multi")
6381 (set_attr "mode" "none")
6382 (set_attr "length" "80")])
6384 ;; Split a block move into 2 parts, the first part is everything
6385 ;; except for the last move, and the second part is just the last
6386 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
6387 ;; fill a delay slot. This also prevents a bug in delayed branches
6388 ;; from showing up, which reuses one of the registers in our clobbers.
6391 [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
6392 (mem:BLK (match_operand:SI 1 "register_operand" "")))
6393 (clobber (match_operand:SI 4 "register_operand" ""))
6394 (clobber (match_operand:SI 5 "register_operand" ""))
6395 (clobber (match_operand:SI 6 "register_operand" ""))
6396 (clobber (match_operand:SI 7 "register_operand" ""))
6397 (use (match_operand:SI 2 "small_int" ""))
6398 (use (match_operand:SI 3 "small_int" ""))
6399 (use (const_int 0))]
6401 "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
6403 ;; All but the last move
6404 [(parallel [(set (mem:BLK (match_dup 0))
6405 (mem:BLK (match_dup 1)))
6406 (clobber (match_dup 4))
6407 (clobber (match_dup 5))
6408 (clobber (match_dup 6))
6409 (clobber (match_dup 7))
6412 (use (const_int 1))])
6414 ;; The last store, so it can fill a delay slot
6415 (parallel [(set (mem:BLK (match_dup 0))
6416 (mem:BLK (match_dup 1)))
6417 (clobber (match_dup 4))
6418 (clobber (match_dup 5))
6419 (clobber (match_dup 6))
6420 (clobber (match_dup 7))
6423 (use (const_int 2))])]
6427 (define_insn "movstrsi_internal2"
6428 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6429 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6430 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6431 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6432 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6433 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6434 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6435 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6436 (use (const_int 1))] ;; all but last store
6438 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6439 [(set_attr "type" "store")
6440 (set_attr "mode" "none")
6441 (set_attr "length" "80")])
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 1))] ;; all but last store
6454 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6455 [(set_attr "type" "multi")
6456 (set_attr "mode" "none")
6457 (set_attr "length" "80")])
6459 (define_insn "movstrsi_internal3"
6460 [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
6461 (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
6462 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6463 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6464 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6465 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6466 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6467 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6468 (use (const_int 2))] ;; just last store of block move
6470 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6471 [(set_attr "type" "store")
6472 (set_attr "mode" "none")])
6475 ;; ....................
6479 ;; ....................
6481 ;; Many of these instructions uses trivial define_expands, because we
6482 ;; want to use a different set of constraints when TARGET_MIPS16.
6484 (define_expand "ashlsi3"
6485 [(set (match_operand:SI 0 "register_operand" "=d")
6486 (ashift:SI (match_operand:SI 1 "register_operand" "d")
6487 (match_operand:SI 2 "arith_operand" "dI")))]
6491 /* On the mips16, a shift of more than 8 is a four byte instruction,
6492 so, for a shift between 8 and 16, it is just as fast to do two
6493 shifts of 8 or less. If there is a lot of shifting going on, we
6494 may win in CSE. Otherwise combine will put the shifts back
6495 together again. This can be called by function_arg, so we must
6496 be careful not to allocate a new register if we've reached the
6500 && GET_CODE (operands[2]) == CONST_INT
6501 && INTVAL (operands[2]) > 8
6502 && INTVAL (operands[2]) <= 16
6503 && ! reload_in_progress
6504 && ! reload_completed)
6506 rtx temp = gen_reg_rtx (SImode);
6508 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
6509 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
6510 GEN_INT (INTVAL (operands[2]) - 8)));
6515 (define_insn "ashlsi3_internal1"
6516 [(set (match_operand:SI 0 "register_operand" "=d")
6517 (ashift:SI (match_operand:SI 1 "register_operand" "d")
6518 (match_operand:SI 2 "arith_operand" "dI")))]
6522 if (GET_CODE (operands[2]) == CONST_INT)
6523 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6525 return \"sll\\t%0,%1,%2\";
6527 [(set_attr "type" "arith")
6528 (set_attr "mode" "SI")])
6530 (define_insn "ashlsi3_internal2"
6531 [(set (match_operand:SI 0 "register_operand" "=d,d")
6532 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
6533 (match_operand:SI 2 "arith_operand" "d,I")))]
6537 if (which_alternative == 0)
6538 return \"sll\\t%0,%2\";
6540 if (GET_CODE (operands[2]) == CONST_INT)
6541 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6543 return \"sll\\t%0,%1,%2\";
6545 [(set_attr "type" "arith")
6546 (set_attr "mode" "SI")
6547 (set_attr_alternative "length"
6549 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6553 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6556 [(set (match_operand:SI 0 "register_operand" "")
6557 (ashift:SI (match_operand:SI 1 "register_operand" "")
6558 (match_operand:SI 2 "const_int_operand" "")))]
6559 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6560 && GET_CODE (operands[2]) == CONST_INT
6561 && INTVAL (operands[2]) > 8
6562 && INTVAL (operands[2]) <= 16"
6563 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
6564 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
6567 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6570 (define_expand "ashldi3"
6571 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6572 (ashift:DI (match_operand:DI 1 "se_register_operand" "")
6573 (match_operand:SI 2 "arith_operand" "")))
6574 (clobber (match_dup 3))])]
6575 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6580 /* On the mips16, a shift of more than 8 is a four byte
6581 instruction, so, for a shift between 8 and 16, it is just as
6582 fast to do two shifts of 8 or less. If there is a lot of
6583 shifting going on, we may win in CSE. Otherwise combine will
6584 put the shifts back together again. This can be called by
6585 function_arg, so we must be careful not to allocate a new
6586 register if we've reached the reload pass. */
6589 && GET_CODE (operands[2]) == CONST_INT
6590 && INTVAL (operands[2]) > 8
6591 && INTVAL (operands[2]) <= 16
6592 && ! reload_in_progress
6593 && ! reload_completed)
6595 rtx temp = gen_reg_rtx (DImode);
6597 emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
6598 emit_insn (gen_ashldi3_internal4 (operands[0], temp,
6599 GEN_INT (INTVAL (operands[2]) - 8)));
6603 emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
6608 operands[3] = gen_reg_rtx (SImode);
6612 (define_insn "ashldi3_internal"
6613 [(set (match_operand:DI 0 "register_operand" "=&d")
6614 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6615 (match_operand:SI 2 "register_operand" "d")))
6616 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6617 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6620 operands[4] = const0_rtx;
6621 dslots_jump_total += 3;
6622 dslots_jump_filled += 2;
6624 return \"sll\\t%3,%2,26\\n\\
6625 \\tbgez\\t%3,1f\\n\\
6626 \\tsll\\t%M0,%L1,%2\\n\\
6628 \\tmove\\t%L0,%z4%)\\n\\
6631 \\t%(beq\\t%3,%z4,2f\\n\\
6632 \\tsll\\t%M0,%M1,%2%)\\n\\
6634 \\tsubu\\t%3,%z4,%2\\n\\
6635 \\tsrl\\t%3,%L1,%3\\n\\
6636 \\tor\\t%M0,%M0,%3\\n\\
6638 \\tsll\\t%L0,%L1,%2\\n\\
6641 [(set_attr "type" "darith")
6642 (set_attr "mode" "SI")
6643 (set_attr "length" "48")])
6646 (define_insn "ashldi3_internal2"
6647 [(set (match_operand:DI 0 "register_operand" "=d")
6648 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6649 (match_operand:SI 2 "small_int" "IJK")))
6650 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6651 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6652 && (INTVAL (operands[2]) & 32) != 0"
6655 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6656 operands[4] = const0_rtx;
6657 return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
6659 [(set_attr "type" "darith")
6660 (set_attr "mode" "DI")
6661 (set_attr "length" "8")])
6665 [(set (match_operand:DI 0 "register_operand" "")
6666 (ashift:DI (match_operand:DI 1 "register_operand" "")
6667 (match_operand:SI 2 "small_int" "")))
6668 (clobber (match_operand:SI 3 "register_operand" ""))]
6669 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6670 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6671 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6672 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6673 && (INTVAL (operands[2]) & 32) != 0"
6675 [(set (subreg:SI (match_dup 0) 4) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6676 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6678 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6682 [(set (match_operand:DI 0 "register_operand" "")
6683 (ashift:DI (match_operand:DI 1 "register_operand" "")
6684 (match_operand:SI 2 "small_int" "")))
6685 (clobber (match_operand:SI 3 "register_operand" ""))]
6686 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6687 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6688 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6689 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6690 && (INTVAL (operands[2]) & 32) != 0"
6692 [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
6693 (set (subreg:SI (match_dup 0) 4) (const_int 0))]
6695 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6698 (define_insn "ashldi3_internal3"
6699 [(set (match_operand:DI 0 "register_operand" "=d")
6700 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6701 (match_operand:SI 2 "small_int" "IJK")))
6702 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6703 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6704 && (INTVAL (operands[2]) & 63) < 32
6705 && (INTVAL (operands[2]) & 63) != 0"
6708 int amount = INTVAL (operands[2]);
6710 operands[2] = GEN_INT (amount & 31);
6711 operands[4] = const0_rtx;
6712 operands[5] = GEN_INT ((-amount) & 31);
6714 return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
6716 [(set_attr "type" "darith")
6717 (set_attr "mode" "DI")
6718 (set_attr "length" "16")])
6722 [(set (match_operand:DI 0 "register_operand" "")
6723 (ashift:DI (match_operand:DI 1 "register_operand" "")
6724 (match_operand:SI 2 "small_int" "")))
6725 (clobber (match_operand:SI 3 "register_operand" ""))]
6726 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6727 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6728 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6729 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6730 && (INTVAL (operands[2]) & 63) < 32
6731 && (INTVAL (operands[2]) & 63) != 0"
6733 [(set (subreg:SI (match_dup 0) 4)
6734 (ashift:SI (subreg:SI (match_dup 1) 4)
6738 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6741 (set (subreg:SI (match_dup 0) 4)
6742 (ior:SI (subreg:SI (match_dup 0) 4)
6745 (set (subreg:SI (match_dup 0) 0)
6746 (ashift:SI (subreg:SI (match_dup 1) 0)
6750 int amount = INTVAL (operands[2]);
6751 operands[2] = GEN_INT (amount & 31);
6752 operands[4] = GEN_INT ((-amount) & 31);
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]) & 63) < 32
6766 && (INTVAL (operands[2]) & 63) != 0"
6768 [(set (subreg:SI (match_dup 0) 0)
6769 (ashift:SI (subreg:SI (match_dup 1) 0)
6773 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
6776 (set (subreg:SI (match_dup 0) 0)
6777 (ior:SI (subreg:SI (match_dup 0) 0)
6780 (set (subreg:SI (match_dup 0) 4)
6781 (ashift:SI (subreg:SI (match_dup 1) 4)
6785 int amount = INTVAL (operands[2]);
6786 operands[2] = GEN_INT (amount & 31);
6787 operands[4] = GEN_INT ((-amount) & 31);
6791 (define_insn "ashldi3_internal4"
6792 [(set (match_operand:DI 0 "register_operand" "=d")
6793 (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
6794 (match_operand:SI 2 "arith_operand" "dI")))]
6795 "TARGET_64BIT && !TARGET_MIPS16"
6798 if (GET_CODE (operands[2]) == CONST_INT)
6799 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6801 return \"dsll\\t%0,%1,%2\";
6803 [(set_attr "type" "arith")
6804 (set_attr "mode" "DI")])
6807 [(set (match_operand:DI 0 "register_operand" "=d,d")
6808 (ashift:DI (match_operand:DI 1 "se_register_operand" "0,d")
6809 (match_operand:SI 2 "arith_operand" "d,I")))]
6810 "TARGET_64BIT && TARGET_MIPS16"
6813 if (which_alternative == 0)
6814 return \"dsll\\t%0,%2\";
6816 if (GET_CODE (operands[2]) == CONST_INT)
6817 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6819 return \"dsll\\t%0,%1,%2\";
6821 [(set_attr "type" "arith")
6822 (set_attr "mode" "DI")
6823 (set_attr_alternative "length"
6825 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6830 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6833 [(set (match_operand:DI 0 "register_operand" "")
6834 (ashift:DI (match_operand:DI 1 "register_operand" "")
6835 (match_operand:SI 2 "const_int_operand" "")))]
6836 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
6838 && GET_CODE (operands[2]) == CONST_INT
6839 && INTVAL (operands[2]) > 8
6840 && INTVAL (operands[2]) <= 16"
6841 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
6842 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
6845 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6848 (define_expand "ashrsi3"
6849 [(set (match_operand:SI 0 "register_operand" "=d")
6850 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6851 (match_operand:SI 2 "arith_operand" "dI")))]
6855 /* On the mips16, a shift of more than 8 is a four byte instruction,
6856 so, for a shift between 8 and 16, it is just as fast to do two
6857 shifts of 8 or less. If there is a lot of shifting going on, we
6858 may win in CSE. Otherwise combine will put the shifts back
6862 && GET_CODE (operands[2]) == CONST_INT
6863 && INTVAL (operands[2]) > 8
6864 && INTVAL (operands[2]) <= 16)
6866 rtx temp = gen_reg_rtx (SImode);
6868 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6869 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
6870 GEN_INT (INTVAL (operands[2]) - 8)));
6875 (define_insn "ashrsi3_internal1"
6876 [(set (match_operand:SI 0 "register_operand" "=d")
6877 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6878 (match_operand:SI 2 "arith_operand" "dI")))]
6882 if (GET_CODE (operands[2]) == CONST_INT)
6883 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6885 return \"sra\\t%0,%1,%2\";
6887 [(set_attr "type" "arith")
6888 (set_attr "mode" "SI")])
6890 (define_insn "ashrsi3_internal2"
6891 [(set (match_operand:SI 0 "register_operand" "=d,d")
6892 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6893 (match_operand:SI 2 "arith_operand" "d,I")))]
6897 if (which_alternative == 0)
6898 return \"sra\\t%0,%2\";
6900 if (GET_CODE (operands[2]) == CONST_INT)
6901 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6903 return \"sra\\t%0,%1,%2\";
6905 [(set_attr "type" "arith")
6906 (set_attr "mode" "SI")
6907 (set_attr_alternative "length"
6909 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6914 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6917 [(set (match_operand:SI 0 "register_operand" "")
6918 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6919 (match_operand:SI 2 "const_int_operand" "")))]
6920 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6921 && GET_CODE (operands[2]) == CONST_INT
6922 && INTVAL (operands[2]) > 8
6923 && INTVAL (operands[2]) <= 16"
6924 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
6925 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
6928 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6931 (define_expand "ashrdi3"
6932 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6933 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
6934 (match_operand:SI 2 "arith_operand" "")))
6935 (clobber (match_dup 3))])]
6936 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6941 /* On the mips16, a shift of more than 8 is a four byte
6942 instruction, so, for a shift between 8 and 16, it is just as
6943 fast to do two shifts of 8 or less. If there is a lot of
6944 shifting going on, we may win in CSE. Otherwise combine will
6945 put the shifts back together again. */
6948 && GET_CODE (operands[2]) == CONST_INT
6949 && INTVAL (operands[2]) > 8
6950 && INTVAL (operands[2]) <= 16)
6952 rtx temp = gen_reg_rtx (DImode);
6954 emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
6955 emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
6956 GEN_INT (INTVAL (operands[2]) - 8)));
6960 emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
6965 operands[3] = gen_reg_rtx (SImode);
6969 (define_insn "ashrdi3_internal"
6970 [(set (match_operand:DI 0 "register_operand" "=&d")
6971 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6972 (match_operand:SI 2 "register_operand" "d")))
6973 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6974 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6977 operands[4] = const0_rtx;
6978 dslots_jump_total += 3;
6979 dslots_jump_filled += 2;
6981 return \"sll\\t%3,%2,26\\n\\
6982 \\tbgez\\t%3,1f\\n\\
6983 \\tsra\\t%L0,%M1,%2\\n\\
6985 \\tsra\\t%M0,%M1,31%)\\n\\
6988 \\t%(beq\\t%3,%z4,2f\\n\\
6989 \\tsrl\\t%L0,%L1,%2%)\\n\\
6991 \\tsubu\\t%3,%z4,%2\\n\\
6992 \\tsll\\t%3,%M1,%3\\n\\
6993 \\tor\\t%L0,%L0,%3\\n\\
6995 \\tsra\\t%M0,%M1,%2\\n\\
6998 [(set_attr "type" "darith")
6999 (set_attr "mode" "DI")
7000 (set_attr "length" "48")])
7003 (define_insn "ashrdi3_internal2"
7004 [(set (match_operand:DI 0 "register_operand" "=d")
7005 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7006 (match_operand:SI 2 "small_int" "IJK")))
7007 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7008 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
7011 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7012 return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
7014 [(set_attr "type" "darith")
7015 (set_attr "mode" "DI")
7016 (set_attr "length" "8")])
7020 [(set (match_operand:DI 0 "register_operand" "")
7021 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7022 (match_operand:SI 2 "small_int" "")))
7023 (clobber (match_operand:SI 3 "register_operand" ""))]
7024 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7025 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7026 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7027 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7028 && (INTVAL (operands[2]) & 32) != 0"
7030 [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7031 (set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (const_int 31)))]
7033 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7037 [(set (match_operand:DI 0 "register_operand" "")
7038 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7039 (match_operand:SI 2 "small_int" "")))
7040 (clobber (match_operand:SI 3 "register_operand" ""))]
7041 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7042 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
7043 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7044 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7045 && (INTVAL (operands[2]) & 32) != 0"
7047 [(set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7048 (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
7050 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7053 (define_insn "ashrdi3_internal3"
7054 [(set (match_operand:DI 0 "register_operand" "=d")
7055 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
7056 (match_operand:SI 2 "small_int" "IJK")))
7057 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7058 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7059 && (INTVAL (operands[2]) & 63) < 32
7060 && (INTVAL (operands[2]) & 63) != 0"
7063 int amount = INTVAL (operands[2]);
7065 operands[2] = GEN_INT (amount & 31);
7066 operands[4] = GEN_INT ((-amount) & 31);
7068 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
7070 [(set_attr "type" "darith")
7071 (set_attr "mode" "DI")
7072 (set_attr "length" "16")])
7076 [(set (match_operand:DI 0 "register_operand" "")
7077 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7078 (match_operand:SI 2 "small_int" "")))
7079 (clobber (match_operand:SI 3 "register_operand" ""))]
7080 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7081 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7082 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7083 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7084 && (INTVAL (operands[2]) & 63) < 32
7085 && (INTVAL (operands[2]) & 63) != 0"
7087 [(set (subreg:SI (match_dup 0) 0)
7088 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7092 (ashift:SI (subreg:SI (match_dup 1) 4)
7095 (set (subreg:SI (match_dup 0) 0)
7096 (ior:SI (subreg:SI (match_dup 0) 0)
7099 (set (subreg:SI (match_dup 0) 4)
7100 (ashiftrt:SI (subreg:SI (match_dup 1) 4)
7104 int amount = INTVAL (operands[2]);
7105 operands[2] = GEN_INT (amount & 31);
7106 operands[4] = GEN_INT ((-amount) & 31);
7111 [(set (match_operand:DI 0 "register_operand" "")
7112 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7113 (match_operand:SI 2 "small_int" "")))
7114 (clobber (match_operand:SI 3 "register_operand" ""))]
7115 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7116 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7117 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7118 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7119 && (INTVAL (operands[2]) & 63) < 32
7120 && (INTVAL (operands[2]) & 63) != 0"
7122 [(set (subreg:SI (match_dup 0) 4)
7123 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7127 (ashift:SI (subreg:SI (match_dup 1) 0)
7130 (set (subreg:SI (match_dup 0) 4)
7131 (ior:SI (subreg:SI (match_dup 0) 4)
7134 (set (subreg:SI (match_dup 0) 0)
7135 (ashiftrt:SI (subreg:SI (match_dup 1) 0)
7139 int amount = INTVAL (operands[2]);
7140 operands[2] = GEN_INT (amount & 31);
7141 operands[4] = GEN_INT ((-amount) & 31);
7145 (define_insn "ashrdi3_internal4"
7146 [(set (match_operand:DI 0 "register_operand" "=d")
7147 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7148 (match_operand:SI 2 "arith_operand" "dI")))]
7149 "TARGET_64BIT && !TARGET_MIPS16"
7152 if (GET_CODE (operands[2]) == CONST_INT)
7153 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7155 return \"dsra\\t%0,%1,%2\";
7157 [(set_attr "type" "arith")
7158 (set_attr "mode" "DI")])
7161 [(set (match_operand:DI 0 "register_operand" "=d,d")
7162 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7163 (match_operand:SI 2 "arith_operand" "d,I")))]
7164 "TARGET_64BIT && TARGET_MIPS16"
7167 if (GET_CODE (operands[2]) == CONST_INT)
7168 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7170 return \"dsra\\t%0,%2\";
7172 [(set_attr "type" "arith")
7173 (set_attr "mode" "DI")
7174 (set_attr_alternative "length"
7176 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7180 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7183 [(set (match_operand:DI 0 "register_operand" "")
7184 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7185 (match_operand:SI 2 "const_int_operand" "")))]
7186 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
7188 && GET_CODE (operands[2]) == CONST_INT
7189 && INTVAL (operands[2]) > 8
7190 && INTVAL (operands[2]) <= 16"
7191 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
7192 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
7195 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7198 (define_expand "lshrsi3"
7199 [(set (match_operand:SI 0 "register_operand" "=d")
7200 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7201 (match_operand:SI 2 "arith_operand" "dI")))]
7205 /* On the mips16, a shift of more than 8 is a four byte instruction,
7206 so, for a shift between 8 and 16, it is just as fast to do two
7207 shifts of 8 or less. If there is a lot of shifting going on, we
7208 may win in CSE. Otherwise combine will put the shifts back
7212 && GET_CODE (operands[2]) == CONST_INT
7213 && INTVAL (operands[2]) > 8
7214 && INTVAL (operands[2]) <= 16)
7216 rtx temp = gen_reg_rtx (SImode);
7218 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
7219 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
7220 GEN_INT (INTVAL (operands[2]) - 8)));
7225 (define_insn "lshrsi3_internal1"
7226 [(set (match_operand:SI 0 "register_operand" "=d")
7227 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7228 (match_operand:SI 2 "arith_operand" "dI")))]
7232 if (GET_CODE (operands[2]) == CONST_INT)
7233 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7235 return \"srl\\t%0,%1,%2\";
7237 [(set_attr "type" "arith")
7238 (set_attr "mode" "SI")])
7240 (define_insn "lshrsi3_internal2"
7241 [(set (match_operand:SI 0 "register_operand" "=d,d")
7242 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
7243 (match_operand:SI 2 "arith_operand" "d,I")))]
7247 if (which_alternative == 0)
7248 return \"srl\\t%0,%2\";
7250 if (GET_CODE (operands[2]) == CONST_INT)
7251 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7253 return \"srl\\t%0,%1,%2\";
7255 [(set_attr "type" "arith")
7256 (set_attr "mode" "SI")
7257 (set_attr_alternative "length"
7259 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7264 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7267 [(set (match_operand:SI 0 "register_operand" "")
7268 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
7269 (match_operand:SI 2 "const_int_operand" "")))]
7270 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7271 && GET_CODE (operands[2]) == CONST_INT
7272 && INTVAL (operands[2]) > 8
7273 && INTVAL (operands[2]) <= 16"
7274 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
7275 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7278 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7281 ;; If we load a byte on the mips16 as a bitfield, the resulting
7282 ;; sequence of instructions is too complicated for combine, because it
7283 ;; involves four instructions: a load, a shift, a constant load into a
7284 ;; register, and an and (the key problem here is that the mips16 does
7285 ;; not have and immediate). We recognize a shift of a load in order
7286 ;; to make it simple enough for combine to understand.
7289 [(set (match_operand:SI 0 "register_operand" "=d,d")
7290 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "R,m")
7291 (match_operand:SI 2 "immediate_operand" "I,I")))]
7293 "lw\\t%0,%1\;srl\\t%0,%2"
7294 [(set_attr "type" "load")
7295 (set_attr "mode" "SI")
7296 (set_attr_alternative "length"
7297 [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7300 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7305 [(set (match_operand:SI 0 "register_operand" "")
7306 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "")
7307 (match_operand:SI 2 "immediate_operand" "")))]
7308 "TARGET_MIPS16 && !TARGET_DEBUG_D_MODE"
7309 [(set (match_dup 0) (match_dup 1))
7310 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7313 (define_expand "lshrdi3"
7314 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7315 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7316 (match_operand:SI 2 "arith_operand" "")))
7317 (clobber (match_dup 3))])]
7318 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7323 /* On the mips16, a shift of more than 8 is a four byte
7324 instruction, so, for a shift between 8 and 16, it is just as
7325 fast to do two shifts of 8 or less. If there is a lot of
7326 shifting going on, we may win in CSE. Otherwise combine will
7327 put the shifts back together again. */
7330 && GET_CODE (operands[2]) == CONST_INT
7331 && INTVAL (operands[2]) > 8
7332 && INTVAL (operands[2]) <= 16)
7334 rtx temp = gen_reg_rtx (DImode);
7336 emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7337 emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
7338 GEN_INT (INTVAL (operands[2]) - 8)));
7342 emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
7347 operands[3] = gen_reg_rtx (SImode);
7351 (define_insn "lshrdi3_internal"
7352 [(set (match_operand:DI 0 "register_operand" "=&d")
7353 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7354 (match_operand:SI 2 "register_operand" "d")))
7355 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7356 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7359 operands[4] = const0_rtx;
7360 dslots_jump_total += 3;
7361 dslots_jump_filled += 2;
7363 return \"sll\\t%3,%2,26\\n\\
7364 \\tbgez\\t%3,1f\\n\\
7365 \\tsrl\\t%L0,%M1,%2\\n\\
7367 \\tmove\\t%M0,%z4%)\\n\\
7370 \\t%(beq\\t%3,%z4,2f\\n\\
7371 \\tsrl\\t%L0,%L1,%2%)\\n\\
7373 \\tsubu\\t%3,%z4,%2\\n\\
7374 \\tsll\\t%3,%M1,%3\\n\\
7375 \\tor\\t%L0,%L0,%3\\n\\
7377 \\tsrl\\t%M0,%M1,%2\\n\\
7380 [(set_attr "type" "darith")
7381 (set_attr "mode" "DI")
7382 (set_attr "length" "48")])
7385 (define_insn "lshrdi3_internal2"
7386 [(set (match_operand:DI 0 "register_operand" "=d")
7387 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7388 (match_operand:SI 2 "small_int" "IJK")))
7389 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7390 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7391 && (INTVAL (operands[2]) & 32) != 0"
7394 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7395 operands[4] = const0_rtx;
7396 return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
7398 [(set_attr "type" "darith")
7399 (set_attr "mode" "DI")
7400 (set_attr "length" "8")])
7404 [(set (match_operand:DI 0 "register_operand" "")
7405 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7406 (match_operand:SI 2 "small_int" "")))
7407 (clobber (match_operand:SI 3 "register_operand" ""))]
7408 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7409 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7410 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7411 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7412 && (INTVAL (operands[2]) & 32) != 0"
7414 [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7415 (set (subreg:SI (match_dup 0) 4) (const_int 0))]
7417 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7421 [(set (match_operand:DI 0 "register_operand" "")
7422 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7423 (match_operand:SI 2 "small_int" "")))
7424 (clobber (match_operand:SI 3 "register_operand" ""))]
7425 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7426 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7427 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7428 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7429 && (INTVAL (operands[2]) & 32) != 0"
7431 [(set (subreg:SI (match_dup 0) 4) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7432 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
7434 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7437 (define_insn "lshrdi3_internal3"
7438 [(set (match_operand:DI 0 "register_operand" "=d")
7439 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7440 (match_operand:SI 2 "small_int" "IJK")))
7441 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7442 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7443 && (INTVAL (operands[2]) & 63) < 32
7444 && (INTVAL (operands[2]) & 63) != 0"
7447 int amount = INTVAL (operands[2]);
7449 operands[2] = GEN_INT (amount & 31);
7450 operands[4] = GEN_INT ((-amount) & 31);
7452 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
7454 [(set_attr "type" "darith")
7455 (set_attr "mode" "DI")
7456 (set_attr "length" "16")])
7460 [(set (match_operand:DI 0 "register_operand" "")
7461 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7462 (match_operand:SI 2 "small_int" "")))
7463 (clobber (match_operand:SI 3 "register_operand" ""))]
7464 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7465 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7466 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7467 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7468 && (INTVAL (operands[2]) & 63) < 32
7469 && (INTVAL (operands[2]) & 63) != 0"
7471 [(set (subreg:SI (match_dup 0) 0)
7472 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7476 (ashift:SI (subreg:SI (match_dup 1) 4)
7479 (set (subreg:SI (match_dup 0) 0)
7480 (ior:SI (subreg:SI (match_dup 0) 0)
7483 (set (subreg:SI (match_dup 0) 4)
7484 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7488 int amount = INTVAL (operands[2]);
7489 operands[2] = GEN_INT (amount & 31);
7490 operands[4] = GEN_INT ((-amount) & 31);
7495 [(set (match_operand:DI 0 "register_operand" "")
7496 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7497 (match_operand:SI 2 "small_int" "")))
7498 (clobber (match_operand:SI 3 "register_operand" ""))]
7499 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7500 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7501 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7502 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7503 && (INTVAL (operands[2]) & 63) < 32
7504 && (INTVAL (operands[2]) & 63) != 0"
7506 [(set (subreg:SI (match_dup 0) 4)
7507 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
7511 (ashift:SI (subreg:SI (match_dup 1) 0)
7514 (set (subreg:SI (match_dup 0) 4)
7515 (ior:SI (subreg:SI (match_dup 0) 4)
7518 (set (subreg:SI (match_dup 0) 0)
7519 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7523 int amount = INTVAL (operands[2]);
7524 operands[2] = GEN_INT (amount & 31);
7525 operands[4] = GEN_INT ((-amount) & 31);
7529 (define_insn "lshrdi3_internal4"
7530 [(set (match_operand:DI 0 "register_operand" "=d")
7531 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7532 (match_operand:SI 2 "arith_operand" "dI")))]
7533 "TARGET_64BIT && !TARGET_MIPS16"
7536 if (GET_CODE (operands[2]) == CONST_INT)
7537 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7539 return \"dsrl\\t%0,%1,%2\";
7541 [(set_attr "type" "arith")
7542 (set_attr "mode" "DI")])
7545 [(set (match_operand:DI 0 "register_operand" "=d,d")
7546 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7547 (match_operand:SI 2 "arith_operand" "d,I")))]
7548 "TARGET_64BIT && TARGET_MIPS16"
7551 if (GET_CODE (operands[2]) == CONST_INT)
7552 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7554 return \"dsrl\\t%0,%2\";
7556 [(set_attr "type" "arith")
7557 (set_attr "mode" "DI")
7558 (set_attr_alternative "length"
7560 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7564 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7567 [(set (match_operand:DI 0 "register_operand" "")
7568 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7569 (match_operand:SI 2 "const_int_operand" "")))]
7570 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
7571 && GET_CODE (operands[2]) == CONST_INT
7572 && INTVAL (operands[2]) > 8
7573 && INTVAL (operands[2]) <= 16"
7574 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
7575 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
7578 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7583 ;; ....................
7587 ;; ....................
7589 ;; Flow here is rather complex:
7591 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
7592 ;; arguments into the branch_cmp array, and the type into
7593 ;; branch_type. No RTL is generated.
7595 ;; 2) The appropriate branch define_expand is called, which then
7596 ;; creates the appropriate RTL for the comparison and branch.
7597 ;; Different CC modes are used, based on what type of branch is
7598 ;; done, so that we can constrain things appropriately. There
7599 ;; are assumptions in the rest of GCC that break if we fold the
7600 ;; operands into the branchs for integer operations, and use cc0
7601 ;; for floating point, so we use the fp status register instead.
7602 ;; If needed, an appropriate temporary is created to hold the
7603 ;; of the integer compare.
7605 (define_expand "cmpsi"
7607 (compare:CC (match_operand:SI 0 "register_operand" "")
7608 (match_operand:SI 1 "arith_operand" "")))]
7612 if (operands[0]) /* avoid unused code message */
7614 branch_cmp[0] = operands[0];
7615 branch_cmp[1] = operands[1];
7616 branch_type = CMP_SI;
7621 (define_expand "tstsi"
7623 (match_operand:SI 0 "register_operand" ""))]
7627 if (operands[0]) /* avoid unused code message */
7629 branch_cmp[0] = operands[0];
7630 branch_cmp[1] = const0_rtx;
7631 branch_type = CMP_SI;
7636 (define_expand "cmpdi"
7638 (compare:CC (match_operand:DI 0 "se_register_operand" "")
7639 (match_operand:DI 1 "se_arith_operand" "")))]
7643 if (operands[0]) /* avoid unused code message */
7645 branch_cmp[0] = operands[0];
7646 branch_cmp[1] = operands[1];
7647 branch_type = CMP_DI;
7652 (define_expand "tstdi"
7654 (match_operand:DI 0 "se_register_operand" ""))]
7658 if (operands[0]) /* avoid unused code message */
7660 branch_cmp[0] = operands[0];
7661 branch_cmp[1] = const0_rtx;
7662 branch_type = CMP_DI;
7667 (define_expand "cmpdf"
7669 (compare:CC (match_operand:DF 0 "register_operand" "")
7670 (match_operand:DF 1 "register_operand" "")))]
7671 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7674 if (operands[0]) /* avoid unused code message */
7676 branch_cmp[0] = operands[0];
7677 branch_cmp[1] = operands[1];
7678 branch_type = CMP_DF;
7683 (define_expand "cmpsf"
7685 (compare:CC (match_operand:SF 0 "register_operand" "")
7686 (match_operand:SF 1 "register_operand" "")))]
7690 if (operands[0]) /* avoid unused code message */
7692 branch_cmp[0] = operands[0];
7693 branch_cmp[1] = operands[1];
7694 branch_type = CMP_SF;
7701 ;; ....................
7703 ;; CONDITIONAL BRANCHES
7705 ;; ....................
7707 ;; Conditional branches on floating-point equality tests.
7709 (define_insn "branch_fp"
7712 (match_operator:CC 0 "cmp_op"
7713 [(match_operand:CC 2 "register_operand" "z")
7715 (label_ref (match_operand 1 "" ""))
7720 return mips_output_conditional_branch (insn,
7722 /*two_operands_p=*/0,
7725 get_attr_length (insn));
7727 [(set_attr "type" "branch")
7728 (set_attr "mode" "none")])
7730 (define_insn "branch_fp_inverted"
7733 (match_operator:CC 0 "cmp_op"
7734 [(match_operand:CC 2 "register_operand" "z")
7737 (label_ref (match_operand 1 "" ""))))]
7741 return mips_output_conditional_branch (insn,
7743 /*two_operands_p=*/0,
7746 get_attr_length (insn));
7748 [(set_attr "type" "branch")
7749 (set_attr "mode" "none")])
7751 ;; Conditional branches on comparisons with zero.
7753 (define_insn "branch_zero"
7756 (match_operator:SI 0 "cmp_op"
7757 [(match_operand:SI 2 "register_operand" "d")
7759 (label_ref (match_operand 1 "" ""))
7764 return mips_output_conditional_branch (insn,
7766 /*two_operands_p=*/0,
7769 get_attr_length (insn));
7771 [(set_attr "type" "branch")
7772 (set_attr "mode" "none")])
7774 (define_insn "branch_zero_inverted"
7777 (match_operator:SI 0 "cmp_op"
7778 [(match_operand:SI 2 "register_operand" "d")
7781 (label_ref (match_operand 1 "" ""))))]
7785 return mips_output_conditional_branch (insn,
7787 /*two_operands_p=*/0,
7790 get_attr_length (insn));
7792 [(set_attr "type" "branch")
7793 (set_attr "mode" "none")])
7795 (define_insn "branch_zero_di"
7798 (match_operator:DI 0 "cmp_op"
7799 [(match_operand:DI 2 "se_register_operand" "d")
7801 (label_ref (match_operand 1 "" ""))
7806 return mips_output_conditional_branch (insn,
7808 /*two_operands_p=*/0,
7811 get_attr_length (insn));
7813 [(set_attr "type" "branch")
7814 (set_attr "mode" "none")])
7816 (define_insn "branch_zero_di_inverted"
7819 (match_operator:DI 0 "cmp_op"
7820 [(match_operand:DI 2 "se_register_operand" "d")
7823 (label_ref (match_operand 1 "" ""))))]
7827 return mips_output_conditional_branch (insn,
7829 /*two_operands_p=*/0,
7832 get_attr_length (insn));
7834 [(set_attr "type" "branch")
7835 (set_attr "mode" "none")])
7837 ;; Conditional branch on equality comparision.
7839 (define_insn "branch_equality"
7842 (match_operator:SI 0 "equality_op"
7843 [(match_operand:SI 2 "register_operand" "d")
7844 (match_operand:SI 3 "register_operand" "d")])
7845 (label_ref (match_operand 1 "" ""))
7850 return mips_output_conditional_branch (insn,
7852 /*two_operands_p=*/1,
7855 get_attr_length (insn));
7857 [(set_attr "type" "branch")
7858 (set_attr "mode" "none")])
7860 (define_insn "branch_equality_di"
7863 (match_operator:DI 0 "equality_op"
7864 [(match_operand:DI 2 "se_register_operand" "d")
7865 (match_operand:DI 3 "se_register_operand" "d")])
7866 (label_ref (match_operand 1 "" ""))
7871 return mips_output_conditional_branch (insn,
7873 /*two_operands_p=*/1,
7876 get_attr_length (insn));
7878 [(set_attr "type" "branch")
7879 (set_attr "mode" "none")])
7881 (define_insn "branch_equality_inverted"
7884 (match_operator:SI 0 "equality_op"
7885 [(match_operand:SI 2 "register_operand" "d")
7886 (match_operand:SI 3 "register_operand" "d")])
7888 (label_ref (match_operand 1 "" ""))))]
7892 return mips_output_conditional_branch (insn,
7894 /*two_operands_p=*/1,
7897 get_attr_length (insn));
7899 [(set_attr "type" "branch")
7900 (set_attr "mode" "none")])
7902 (define_insn "branch_equality_di_inverted"
7905 (match_operator:DI 0 "equality_op"
7906 [(match_operand:DI 2 "se_register_operand" "d")
7907 (match_operand:DI 3 "se_register_operand" "d")])
7909 (label_ref (match_operand 1 "" ""))))]
7913 return mips_output_conditional_branch (insn,
7915 /*two_operands_p=*/1,
7918 get_attr_length (insn));
7920 [(set_attr "type" "branch")
7921 (set_attr "mode" "none")])
7927 (if_then_else (match_operator:SI 0 "equality_op"
7928 [(match_operand:SI 1 "register_operand" "d,t")
7930 (match_operand 2 "pc_or_label_operand" "")
7931 (match_operand 3 "pc_or_label_operand" "")))]
7935 if (operands[2] != pc_rtx)
7937 if (which_alternative == 0)
7938 return \"%*b%C0z\\t%1,%2\";
7940 return \"%*bt%C0z\\t%2\";
7944 if (which_alternative == 0)
7945 return \"%*b%N0z\\t%1,%3\";
7947 return \"%*bt%N0z\\t%3\";
7950 [(set_attr "type" "branch")
7951 (set_attr "mode" "none")
7952 (set_attr "length" "8")])
7956 (if_then_else (match_operator:DI 0 "equality_op"
7957 [(match_operand:DI 1 "se_register_operand" "d,t")
7959 (match_operand 2 "pc_or_label_operand" "")
7960 (match_operand 3 "pc_or_label_operand" "")))]
7964 if (operands[2] != pc_rtx)
7966 if (which_alternative == 0)
7967 return \"%*b%C0z\\t%1,%2\";
7969 return \"%*bt%C0z\\t%2\";
7973 if (which_alternative == 0)
7974 return \"%*b%N0z\\t%1,%3\";
7976 return \"%*bt%N0z\\t%3\";
7979 [(set_attr "type" "branch")
7980 (set_attr "mode" "none")
7981 (set_attr "length" "8")])
7983 (define_expand "beq"
7985 (if_then_else (eq:CC (cc0)
7987 (label_ref (match_operand 0 "" ""))
7992 if (operands[0]) /* avoid unused code warning */
7994 gen_conditional_branch (operands, EQ);
7999 (define_expand "bne"
8001 (if_then_else (ne:CC (cc0)
8003 (label_ref (match_operand 0 "" ""))
8008 if (operands[0]) /* avoid unused code warning */
8010 gen_conditional_branch (operands, NE);
8015 (define_expand "bgt"
8017 (if_then_else (gt:CC (cc0)
8019 (label_ref (match_operand 0 "" ""))
8024 if (operands[0]) /* avoid unused code warning */
8026 gen_conditional_branch (operands, GT);
8031 (define_expand "bge"
8033 (if_then_else (ge:CC (cc0)
8035 (label_ref (match_operand 0 "" ""))
8040 if (operands[0]) /* avoid unused code warning */
8042 gen_conditional_branch (operands, GE);
8047 (define_expand "blt"
8049 (if_then_else (lt:CC (cc0)
8051 (label_ref (match_operand 0 "" ""))
8056 if (operands[0]) /* avoid unused code warning */
8058 gen_conditional_branch (operands, LT);
8063 (define_expand "ble"
8065 (if_then_else (le:CC (cc0)
8067 (label_ref (match_operand 0 "" ""))
8072 if (operands[0]) /* avoid unused code warning */
8074 gen_conditional_branch (operands, LE);
8079 (define_expand "bgtu"
8081 (if_then_else (gtu:CC (cc0)
8083 (label_ref (match_operand 0 "" ""))
8088 if (operands[0]) /* avoid unused code warning */
8090 gen_conditional_branch (operands, GTU);
8095 (define_expand "bgeu"
8097 (if_then_else (geu:CC (cc0)
8099 (label_ref (match_operand 0 "" ""))
8104 if (operands[0]) /* avoid unused code warning */
8106 gen_conditional_branch (operands, GEU);
8112 (define_expand "bltu"
8114 (if_then_else (ltu:CC (cc0)
8116 (label_ref (match_operand 0 "" ""))
8121 if (operands[0]) /* avoid unused code warning */
8123 gen_conditional_branch (operands, LTU);
8128 (define_expand "bleu"
8130 (if_then_else (leu:CC (cc0)
8132 (label_ref (match_operand 0 "" ""))
8137 if (operands[0]) /* avoid unused code warning */
8139 gen_conditional_branch (operands, LEU);
8146 ;; ....................
8148 ;; SETTING A REGISTER FROM A COMPARISON
8150 ;; ....................
8152 (define_expand "seq"
8153 [(set (match_operand:SI 0 "register_operand" "=d")
8154 (eq:SI (match_dup 1)
8159 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8162 /* set up operands from compare. */
8163 operands[1] = branch_cmp[0];
8164 operands[2] = branch_cmp[1];
8166 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8168 gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
8172 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8173 operands[2] = force_reg (SImode, operands[2]);
8175 /* fall through and generate default code */
8179 (define_insn "seq_si_zero"
8180 [(set (match_operand:SI 0 "register_operand" "=d")
8181 (eq:SI (match_operand:SI 1 "register_operand" "d")
8185 [(set_attr "type" "arith")
8186 (set_attr "mode" "SI")])
8189 [(set (match_operand:SI 0 "register_operand" "=t")
8190 (eq:SI (match_operand:SI 1 "register_operand" "d")
8194 [(set_attr "type" "arith")
8195 (set_attr "mode" "SI")])
8197 (define_insn "seq_di_zero"
8198 [(set (match_operand:DI 0 "register_operand" "=d")
8199 (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8201 "TARGET_64BIT && !TARGET_MIPS16"
8203 [(set_attr "type" "arith")
8204 (set_attr "mode" "DI")])
8207 [(set (match_operand:DI 0 "register_operand" "=t")
8208 (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8210 "TARGET_64BIT && TARGET_MIPS16"
8212 [(set_attr "type" "arith")
8213 (set_attr "mode" "DI")])
8215 (define_insn "seq_si"
8216 [(set (match_operand:SI 0 "register_operand" "=d,d")
8217 (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
8218 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8219 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8221 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8222 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8223 [(set_attr "type" "arith")
8224 (set_attr "mode" "SI")
8225 (set_attr "length" "8")])
8228 [(set (match_operand:SI 0 "register_operand" "")
8229 (eq:SI (match_operand:SI 1 "register_operand" "")
8230 (match_operand:SI 2 "uns_arith_operand" "")))]
8231 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8232 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8234 (xor:SI (match_dup 1)
8237 (ltu:SI (match_dup 0)
8241 (define_insn "seq_di"
8242 [(set (match_operand:DI 0 "register_operand" "=d,d")
8243 (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8244 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8245 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8247 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8248 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8249 [(set_attr "type" "arith")
8250 (set_attr "mode" "DI")
8251 (set_attr "length" "8")])
8254 [(set (match_operand:DI 0 "register_operand" "")
8255 (eq:DI (match_operand:DI 1 "se_register_operand" "")
8256 (match_operand:DI 2 "se_uns_arith_operand" "")))]
8257 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8259 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8261 (xor:DI (match_dup 1)
8264 (ltu:DI (match_dup 0)
8268 ;; On the mips16 the default code is better than using sltu.
8270 (define_expand "sne"
8271 [(set (match_operand:SI 0 "register_operand" "=d")
8272 (ne:SI (match_dup 1)
8277 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8280 /* set up operands from compare. */
8281 operands[1] = branch_cmp[0];
8282 operands[2] = branch_cmp[1];
8284 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
8286 gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
8290 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8291 operands[2] = force_reg (SImode, operands[2]);
8293 /* fall through and generate default code */
8296 (define_insn "sne_si_zero"
8297 [(set (match_operand:SI 0 "register_operand" "=d")
8298 (ne:SI (match_operand:SI 1 "register_operand" "d")
8302 [(set_attr "type" "arith")
8303 (set_attr "mode" "SI")])
8305 (define_insn "sne_di_zero"
8306 [(set (match_operand:DI 0 "register_operand" "=d")
8307 (ne:DI (match_operand:DI 1 "se_register_operand" "d")
8309 "TARGET_64BIT && !TARGET_MIPS16"
8311 [(set_attr "type" "arith")
8312 (set_attr "mode" "DI")])
8314 (define_insn "sne_si"
8315 [(set (match_operand:SI 0 "register_operand" "=d,d")
8316 (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
8317 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8318 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8320 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8321 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8322 [(set_attr "type" "arith")
8323 (set_attr "mode" "SI")
8324 (set_attr "length" "8")])
8327 [(set (match_operand:SI 0 "register_operand" "")
8328 (ne:SI (match_operand:SI 1 "register_operand" "")
8329 (match_operand:SI 2 "uns_arith_operand" "")))]
8330 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8331 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8333 (xor:SI (match_dup 1)
8336 (gtu:SI (match_dup 0)
8340 (define_insn "sne_di"
8341 [(set (match_operand:DI 0 "register_operand" "=d,d")
8342 (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8343 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8344 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8346 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8347 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8348 [(set_attr "type" "arith")
8349 (set_attr "mode" "DI")
8350 (set_attr "length" "8")])
8353 [(set (match_operand:DI 0 "register_operand" "")
8354 (ne:DI (match_operand:DI 1 "se_register_operand" "")
8355 (match_operand:DI 2 "se_uns_arith_operand" "")))]
8356 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8358 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8360 (xor:DI (match_dup 1)
8363 (gtu:DI (match_dup 0)
8367 (define_expand "sgt"
8368 [(set (match_operand:SI 0 "register_operand" "=d")
8369 (gt:SI (match_dup 1)
8374 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8377 /* set up operands from compare. */
8378 operands[1] = branch_cmp[0];
8379 operands[2] = branch_cmp[1];
8381 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8383 gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
8387 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8388 operands[2] = force_reg (SImode, operands[2]);
8390 /* fall through and generate default code */
8393 (define_insn "sgt_si"
8394 [(set (match_operand:SI 0 "register_operand" "=d")
8395 (gt:SI (match_operand:SI 1 "register_operand" "d")
8396 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8399 [(set_attr "type" "arith")
8400 (set_attr "mode" "SI")])
8403 [(set (match_operand:SI 0 "register_operand" "=t")
8404 (gt:SI (match_operand:SI 1 "register_operand" "d")
8405 (match_operand:SI 2 "register_operand" "d")))]
8408 [(set_attr "type" "arith")
8409 (set_attr "mode" "SI")])
8411 (define_insn "sgt_di"
8412 [(set (match_operand:DI 0 "register_operand" "=d")
8413 (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8414 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8415 "TARGET_64BIT && !TARGET_MIPS16"
8417 [(set_attr "type" "arith")
8418 (set_attr "mode" "DI")])
8421 [(set (match_operand:DI 0 "register_operand" "=d")
8422 (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8423 (match_operand:DI 2 "se_register_operand" "d")))]
8424 "TARGET_64BIT && TARGET_MIPS16"
8426 [(set_attr "type" "arith")
8427 (set_attr "mode" "DI")])
8429 (define_expand "sge"
8430 [(set (match_operand:SI 0 "register_operand" "=d")
8431 (ge:SI (match_dup 1)
8436 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8439 /* set up operands from compare. */
8440 operands[1] = branch_cmp[0];
8441 operands[2] = branch_cmp[1];
8443 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8445 gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
8449 /* fall through and generate default code */
8452 (define_insn "sge_si"
8453 [(set (match_operand:SI 0 "register_operand" "=d")
8454 (ge:SI (match_operand:SI 1 "register_operand" "d")
8455 (match_operand:SI 2 "arith_operand" "dI")))]
8456 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8457 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8458 [(set_attr "type" "arith")
8459 (set_attr "mode" "SI")
8460 (set_attr "length" "8")])
8463 [(set (match_operand:SI 0 "register_operand" "")
8464 (ge:SI (match_operand:SI 1 "register_operand" "")
8465 (match_operand:SI 2 "arith_operand" "")))]
8466 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8468 (lt:SI (match_dup 1)
8471 (xor:SI (match_dup 0)
8475 (define_insn "sge_di"
8476 [(set (match_operand:DI 0 "register_operand" "=d")
8477 (ge:DI (match_operand:DI 1 "se_register_operand" "d")
8478 (match_operand:DI 2 "se_arith_operand" "dI")))]
8479 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8480 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8481 [(set_attr "type" "arith")
8482 (set_attr "mode" "DI")
8483 (set_attr "length" "8")])
8486 [(set (match_operand:DI 0 "register_operand" "")
8487 (ge:DI (match_operand:DI 1 "se_register_operand" "")
8488 (match_operand:DI 2 "se_arith_operand" "")))]
8489 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8492 (lt:DI (match_dup 1)
8495 (xor:DI (match_dup 0)
8499 (define_expand "slt"
8500 [(set (match_operand:SI 0 "register_operand" "=d")
8501 (lt:SI (match_dup 1)
8506 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8509 /* set up operands from compare. */
8510 operands[1] = branch_cmp[0];
8511 operands[2] = branch_cmp[1];
8513 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8515 gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
8519 /* fall through and generate default code */
8522 (define_insn "slt_si"
8523 [(set (match_operand:SI 0 "register_operand" "=d")
8524 (lt:SI (match_operand:SI 1 "register_operand" "d")
8525 (match_operand:SI 2 "arith_operand" "dI")))]
8528 [(set_attr "type" "arith")
8529 (set_attr "mode" "SI")])
8532 [(set (match_operand:SI 0 "register_operand" "=t,t")
8533 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
8534 (match_operand:SI 2 "arith_operand" "d,I")))]
8537 [(set_attr "type" "arith")
8538 (set_attr "mode" "SI")
8539 (set_attr_alternative "length"
8541 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8545 (define_insn "slt_di"
8546 [(set (match_operand:DI 0 "register_operand" "=d")
8547 (lt:DI (match_operand:DI 1 "se_register_operand" "d")
8548 (match_operand:DI 2 "se_arith_operand" "dI")))]
8549 "TARGET_64BIT && !TARGET_MIPS16"
8551 [(set_attr "type" "arith")
8552 (set_attr "mode" "DI")])
8555 [(set (match_operand:DI 0 "register_operand" "=t,t")
8556 (lt:DI (match_operand:DI 1 "se_register_operand" "d,d")
8557 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8558 "TARGET_64BIT && TARGET_MIPS16"
8560 [(set_attr "type" "arith")
8561 (set_attr "mode" "DI")
8562 (set_attr_alternative "length"
8564 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8568 (define_expand "sle"
8569 [(set (match_operand:SI 0 "register_operand" "=d")
8570 (le:SI (match_dup 1)
8575 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8578 /* set up operands from compare. */
8579 operands[1] = branch_cmp[0];
8580 operands[2] = branch_cmp[1];
8582 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8584 gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
8588 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8589 operands[2] = force_reg (SImode, operands[2]);
8591 /* fall through and generate default code */
8594 (define_insn "sle_si_const"
8595 [(set (match_operand:SI 0 "register_operand" "=d")
8596 (le:SI (match_operand:SI 1 "register_operand" "d")
8597 (match_operand:SI 2 "small_int" "I")))]
8598 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8601 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8602 return \"slt\\t%0,%1,%2\";
8604 [(set_attr "type" "arith")
8605 (set_attr "mode" "SI")])
8608 [(set (match_operand:SI 0 "register_operand" "=t")
8609 (le:SI (match_operand:SI 1 "register_operand" "d")
8610 (match_operand:SI 2 "small_int" "I")))]
8611 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8614 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8615 return \"slt\\t%1,%2\";
8617 [(set_attr "type" "arith")
8618 (set_attr "mode" "SI")
8619 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8623 (define_insn "sle_di_const"
8624 [(set (match_operand:DI 0 "register_operand" "=d")
8625 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8626 (match_operand:DI 2 "small_int" "I")))]
8627 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8630 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8631 return \"slt\\t%0,%1,%2\";
8633 [(set_attr "type" "arith")
8634 (set_attr "mode" "DI")])
8637 [(set (match_operand:DI 0 "register_operand" "=t")
8638 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8639 (match_operand:DI 2 "small_int" "I")))]
8640 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8643 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8644 return \"slt\\t%1,%2\";
8646 [(set_attr "type" "arith")
8647 (set_attr "mode" "DI")
8648 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8652 (define_insn "sle_si_reg"
8653 [(set (match_operand:SI 0 "register_operand" "=d")
8654 (le:SI (match_operand:SI 1 "register_operand" "d")
8655 (match_operand:SI 2 "register_operand" "d")))]
8656 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8657 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8658 [(set_attr "type" "arith")
8659 (set_attr "mode" "SI")
8660 (set_attr "length" "8")])
8663 [(set (match_operand:SI 0 "register_operand" "")
8664 (le:SI (match_operand:SI 1 "register_operand" "")
8665 (match_operand:SI 2 "register_operand" "")))]
8666 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8668 (lt:SI (match_dup 2)
8671 (xor:SI (match_dup 0)
8675 (define_insn "sle_di_reg"
8676 [(set (match_operand:DI 0 "register_operand" "=d")
8677 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8678 (match_operand:DI 2 "se_register_operand" "d")))]
8679 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8680 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8681 [(set_attr "type" "arith")
8682 (set_attr "mode" "DI")
8683 (set_attr "length" "8")])
8686 [(set (match_operand:DI 0 "register_operand" "")
8687 (le:DI (match_operand:DI 1 "se_register_operand" "")
8688 (match_operand:DI 2 "se_register_operand" "")))]
8689 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8692 (lt:DI (match_dup 2)
8695 (xor:DI (match_dup 0)
8699 (define_expand "sgtu"
8700 [(set (match_operand:SI 0 "register_operand" "=d")
8701 (gtu:SI (match_dup 1)
8706 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8709 /* set up operands from compare. */
8710 operands[1] = branch_cmp[0];
8711 operands[2] = branch_cmp[1];
8713 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8715 gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
8719 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8720 operands[2] = force_reg (SImode, operands[2]);
8722 /* fall through and generate default code */
8725 (define_insn "sgtu_si"
8726 [(set (match_operand:SI 0 "register_operand" "=d")
8727 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8728 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8731 [(set_attr "type" "arith")
8732 (set_attr "mode" "SI")])
8735 [(set (match_operand:SI 0 "register_operand" "=t")
8736 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8737 (match_operand:SI 2 "register_operand" "d")))]
8740 [(set_attr "type" "arith")
8741 (set_attr "mode" "SI")])
8743 (define_insn "sgtu_di"
8744 [(set (match_operand:DI 0 "register_operand" "=d")
8745 (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8746 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8749 [(set_attr "type" "arith")
8750 (set_attr "mode" "DI")])
8753 [(set (match_operand:DI 0 "register_operand" "=t")
8754 (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8755 (match_operand:DI 2 "se_register_operand" "d")))]
8758 [(set_attr "type" "arith")
8759 (set_attr "mode" "DI")])
8761 (define_expand "sgeu"
8762 [(set (match_operand:SI 0 "register_operand" "=d")
8763 (geu:SI (match_dup 1)
8768 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8771 /* set up operands from compare. */
8772 operands[1] = branch_cmp[0];
8773 operands[2] = branch_cmp[1];
8775 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8777 gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
8781 /* fall through and generate default code */
8784 (define_insn "sgeu_si"
8785 [(set (match_operand:SI 0 "register_operand" "=d")
8786 (geu:SI (match_operand:SI 1 "register_operand" "d")
8787 (match_operand:SI 2 "arith_operand" "dI")))]
8788 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8789 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8790 [(set_attr "type" "arith")
8791 (set_attr "mode" "SI")
8792 (set_attr "length" "8")])
8795 [(set (match_operand:SI 0 "register_operand" "")
8796 (geu:SI (match_operand:SI 1 "register_operand" "")
8797 (match_operand:SI 2 "arith_operand" "")))]
8798 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8800 (ltu:SI (match_dup 1)
8803 (xor:SI (match_dup 0)
8807 (define_insn "sgeu_di"
8808 [(set (match_operand:DI 0 "register_operand" "=d")
8809 (geu:DI (match_operand:DI 1 "se_register_operand" "d")
8810 (match_operand:DI 2 "se_arith_operand" "dI")))]
8811 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8812 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8813 [(set_attr "type" "arith")
8814 (set_attr "mode" "DI")
8815 (set_attr "length" "8")])
8818 [(set (match_operand:DI 0 "register_operand" "")
8819 (geu:DI (match_operand:DI 1 "se_register_operand" "")
8820 (match_operand:DI 2 "se_arith_operand" "")))]
8821 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8824 (ltu:DI (match_dup 1)
8827 (xor:DI (match_dup 0)
8831 (define_expand "sltu"
8832 [(set (match_operand:SI 0 "register_operand" "=d")
8833 (ltu:SI (match_dup 1)
8838 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8841 /* set up operands from compare. */
8842 operands[1] = branch_cmp[0];
8843 operands[2] = branch_cmp[1];
8845 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8847 gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
8851 /* fall through and generate default code */
8854 (define_insn "sltu_si"
8855 [(set (match_operand:SI 0 "register_operand" "=d")
8856 (ltu:SI (match_operand:SI 1 "register_operand" "d")
8857 (match_operand:SI 2 "arith_operand" "dI")))]
8860 [(set_attr "type" "arith")
8861 (set_attr "mode" "SI")])
8864 [(set (match_operand:SI 0 "register_operand" "=t,t")
8865 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
8866 (match_operand:SI 2 "arith_operand" "d,I")))]
8869 [(set_attr "type" "arith")
8870 (set_attr "mode" "SI")
8871 (set_attr_alternative "length"
8873 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8877 (define_insn "sltu_di"
8878 [(set (match_operand:DI 0 "register_operand" "=d")
8879 (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
8880 (match_operand:DI 2 "se_arith_operand" "dI")))]
8881 "TARGET_64BIT && !TARGET_MIPS16"
8883 [(set_attr "type" "arith")
8884 (set_attr "mode" "DI")])
8887 [(set (match_operand:DI 0 "register_operand" "=t,t")
8888 (ltu:DI (match_operand:DI 1 "se_register_operand" "d,d")
8889 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8890 "TARGET_64BIT && TARGET_MIPS16"
8892 [(set_attr "type" "arith")
8893 (set_attr "mode" "DI")
8894 (set_attr_alternative "length"
8896 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8900 (define_expand "sleu"
8901 [(set (match_operand:SI 0 "register_operand" "=d")
8902 (leu:SI (match_dup 1)
8907 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8910 /* set up operands from compare. */
8911 operands[1] = branch_cmp[0];
8912 operands[2] = branch_cmp[1];
8914 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8916 gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
8920 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8921 operands[2] = force_reg (SImode, operands[2]);
8923 /* fall through and generate default code */
8926 (define_insn "sleu_si_const"
8927 [(set (match_operand:SI 0 "register_operand" "=d")
8928 (leu:SI (match_operand:SI 1 "register_operand" "d")
8929 (match_operand:SI 2 "small_int" "I")))]
8930 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8933 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
8934 return \"sltu\\t%0,%1,%2\";
8936 [(set_attr "type" "arith")
8937 (set_attr "mode" "SI")])
8940 [(set (match_operand:SI 0 "register_operand" "=t")
8941 (leu:SI (match_operand:SI 1 "register_operand" "d")
8942 (match_operand:SI 2 "small_int" "I")))]
8943 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8946 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8947 return \"sltu\\t%1,%2\";
8949 [(set_attr "type" "arith")
8950 (set_attr "mode" "SI")
8951 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8955 (define_insn "sleu_di_const"
8956 [(set (match_operand:DI 0 "register_operand" "=d")
8957 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8958 (match_operand:DI 2 "small_int" "I")))]
8959 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8962 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
8963 return \"sltu\\t%0,%1,%2\";
8965 [(set_attr "type" "arith")
8966 (set_attr "mode" "DI")])
8969 [(set (match_operand:DI 0 "register_operand" "=t")
8970 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8971 (match_operand:DI 2 "small_int" "I")))]
8972 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8975 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8976 return \"sltu\\t%1,%2\";
8978 [(set_attr "type" "arith")
8979 (set_attr "mode" "DI")
8980 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8984 (define_insn "sleu_si_reg"
8985 [(set (match_operand:SI 0 "register_operand" "=d")
8986 (leu:SI (match_operand:SI 1 "register_operand" "d")
8987 (match_operand:SI 2 "register_operand" "d")))]
8988 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8989 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8990 [(set_attr "type" "arith")
8991 (set_attr "mode" "SI")
8992 (set_attr "length" "8")])
8995 [(set (match_operand:SI 0 "register_operand" "")
8996 (leu:SI (match_operand:SI 1 "register_operand" "")
8997 (match_operand:SI 2 "register_operand" "")))]
8998 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
9000 (ltu:SI (match_dup 2)
9003 (xor:SI (match_dup 0)
9007 (define_insn "sleu_di_reg"
9008 [(set (match_operand:DI 0 "register_operand" "=d")
9009 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
9010 (match_operand:DI 2 "se_register_operand" "d")))]
9011 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
9012 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9013 [(set_attr "type" "arith")
9014 (set_attr "mode" "DI")
9015 (set_attr "length" "8")])
9018 [(set (match_operand:DI 0 "register_operand" "")
9019 (leu:DI (match_operand:DI 1 "se_register_operand" "")
9020 (match_operand:DI 2 "se_register_operand" "")))]
9021 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
9024 (ltu:DI (match_dup 2)
9027 (xor:DI (match_dup 0)
9033 ;; ....................
9035 ;; FLOATING POINT COMPARISONS
9037 ;; ....................
9039 (define_insn "seq_df"
9040 [(set (match_operand:CC 0 "register_operand" "=z")
9041 (eq:CC (match_operand:DF 1 "register_operand" "f")
9042 (match_operand:DF 2 "register_operand" "f")))]
9043 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9046 return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9048 [(set_attr "type" "fcmp")
9049 (set_attr "mode" "FPSW")])
9051 (define_insn "slt_df"
9052 [(set (match_operand:CC 0 "register_operand" "=z")
9053 (lt:CC (match_operand:DF 1 "register_operand" "f")
9054 (match_operand:DF 2 "register_operand" "f")))]
9055 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9058 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9060 [(set_attr "type" "fcmp")
9061 (set_attr "mode" "FPSW")])
9063 (define_insn "sle_df"
9064 [(set (match_operand:CC 0 "register_operand" "=z")
9065 (le:CC (match_operand:DF 1 "register_operand" "f")
9066 (match_operand:DF 2 "register_operand" "f")))]
9067 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9070 return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9072 [(set_attr "type" "fcmp")
9073 (set_attr "mode" "FPSW")])
9075 (define_insn "sgt_df"
9076 [(set (match_operand:CC 0 "register_operand" "=z")
9077 (gt:CC (match_operand:DF 1 "register_operand" "f")
9078 (match_operand:DF 2 "register_operand" "f")))]
9079 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9082 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9084 [(set_attr "type" "fcmp")
9085 (set_attr "mode" "FPSW")])
9087 (define_insn "sge_df"
9088 [(set (match_operand:CC 0 "register_operand" "=z")
9089 (ge:CC (match_operand:DF 1 "register_operand" "f")
9090 (match_operand:DF 2 "register_operand" "f")))]
9091 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9094 return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9096 [(set_attr "type" "fcmp")
9097 (set_attr "mode" "FPSW")])
9099 (define_insn "seq_sf"
9100 [(set (match_operand:CC 0 "register_operand" "=z")
9101 (eq:CC (match_operand:SF 1 "register_operand" "f")
9102 (match_operand:SF 2 "register_operand" "f")))]
9106 return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9108 [(set_attr "type" "fcmp")
9109 (set_attr "mode" "FPSW")])
9111 (define_insn "slt_sf"
9112 [(set (match_operand:CC 0 "register_operand" "=z")
9113 (lt:CC (match_operand:SF 1 "register_operand" "f")
9114 (match_operand:SF 2 "register_operand" "f")))]
9118 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9120 [(set_attr "type" "fcmp")
9121 (set_attr "mode" "FPSW")])
9123 (define_insn "sle_sf"
9124 [(set (match_operand:CC 0 "register_operand" "=z")
9125 (le:CC (match_operand:SF 1 "register_operand" "f")
9126 (match_operand:SF 2 "register_operand" "f")))]
9130 return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9132 [(set_attr "type" "fcmp")
9133 (set_attr "mode" "FPSW")])
9135 (define_insn "sgt_sf"
9136 [(set (match_operand:CC 0 "register_operand" "=z")
9137 (gt:CC (match_operand:SF 1 "register_operand" "f")
9138 (match_operand:SF 2 "register_operand" "f")))]
9142 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9144 [(set_attr "type" "fcmp")
9145 (set_attr "mode" "FPSW")])
9147 (define_insn "sge_sf"
9148 [(set (match_operand:CC 0 "register_operand" "=z")
9149 (ge:CC (match_operand:SF 1 "register_operand" "f")
9150 (match_operand:SF 2 "register_operand" "f")))]
9154 return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9156 [(set_attr "type" "fcmp")
9157 (set_attr "mode" "FPSW")])
9161 ;; ....................
9163 ;; UNCONDITIONAL BRANCHES
9165 ;; ....................
9167 ;; Unconditional branches.
9171 (label_ref (match_operand 0 "" "")))]
9175 if (GET_CODE (operands[0]) == REG)
9176 return \"%*j\\t%0\";
9177 /* ??? I don't know why this is necessary. This works around an
9178 assembler problem that appears when a label is defined, then referenced
9179 in a switch table, then used in a `j' instruction. */
9180 else if (mips_abi != ABI_32 && mips_abi != ABI_O64)
9181 return \"%*b\\t%l0\";
9183 return \"%*j\\t%l0\";
9185 [(set_attr "type" "jump")
9186 (set_attr "mode" "none")])
9188 ;; We need a different insn for the mips16, because a mips16 branch
9189 ;; does not have a delay slot.
9193 (label_ref (match_operand 0 "" "")))]
9194 "TARGET_MIPS16 && GET_CODE (operands[0]) != REG"
9196 [(set_attr "type" "branch")
9197 (set_attr "mode" "none")
9198 (set_attr "length" "8")])
9200 (define_expand "indirect_jump"
9201 [(set (pc) (match_operand 0 "register_operand" "d"))]
9207 if (operands[0]) /* eliminate unused code warnings */
9210 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
9211 operands[0] = copy_to_mode_reg (Pmode, dest);
9213 if (!(Pmode == DImode))
9214 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
9216 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
9222 (define_insn "indirect_jump_internal1"
9223 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
9224 "!(Pmode == DImode)"
9226 [(set_attr "type" "jump")
9227 (set_attr "mode" "none")])
9229 (define_insn "indirect_jump_internal2"
9230 [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
9233 [(set_attr "type" "jump")
9234 (set_attr "mode" "none")])
9236 (define_expand "tablejump"
9238 (match_operand 0 "register_operand" "d"))
9239 (use (label_ref (match_operand 1 "" "")))]
9243 if (operands[0]) /* eliminate unused code warnings */
9247 if (GET_MODE (operands[0]) != HImode)
9249 if (!(Pmode == DImode))
9250 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
9252 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
9256 if (GET_MODE (operands[0]) != Pmode)
9261 if (!(Pmode == DImode))
9262 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
9264 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
9268 if (!(Pmode == DImode))
9269 emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
9271 emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
9278 (define_insn "tablejump_internal1"
9280 (match_operand:SI 0 "register_operand" "d"))
9281 (use (label_ref (match_operand 1 "" "")))]
9282 "!(Pmode == DImode)"
9284 [(set_attr "type" "jump")
9285 (set_attr "mode" "none")])
9287 (define_insn "tablejump_internal2"
9289 (match_operand:DI 0 "se_register_operand" "d"))
9290 (use (label_ref (match_operand 1 "" "")))]
9293 [(set_attr "type" "jump")
9294 (set_attr "mode" "none")])
9296 (define_expand "tablejump_internal3"
9297 [(parallel [(set (pc)
9298 (plus:SI (match_operand:SI 0 "register_operand" "d")
9299 (label_ref:SI (match_operand 1 "" ""))))
9300 (use (label_ref:SI (match_dup 1)))])]
9304 (define_expand "tablejump_mips161"
9305 [(set (pc) (plus:SI (sign_extend:SI
9306 (match_operand:HI 0 "register_operand" "d"))
9307 (label_ref:SI (match_operand 1 "" ""))))]
9308 "TARGET_MIPS16 && !(Pmode == DImode)"
9311 if (operands[0]) /* eliminate unused code warnings. */
9315 t1 = gen_reg_rtx (SImode);
9316 t2 = gen_reg_rtx (SImode);
9317 t3 = gen_reg_rtx (SImode);
9318 emit_insn (gen_extendhisi2 (t1, operands[0]));
9319 emit_move_insn (t2, gen_rtx (LABEL_REF, SImode, operands[1]));
9320 emit_insn (gen_addsi3 (t3, t1, t2));
9321 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
9326 (define_expand "tablejump_mips162"
9327 [(set (pc) (plus:DI (sign_extend:DI
9328 (match_operand:HI 0 "register_operand" "d"))
9329 (label_ref:DI (match_operand 1 "" ""))))]
9330 "TARGET_MIPS16 && Pmode == DImode"
9333 if (operands[0]) /* eliminate unused code warnings. */
9337 t1 = gen_reg_rtx (DImode);
9338 t2 = gen_reg_rtx (DImode);
9339 t3 = gen_reg_rtx (DImode);
9340 emit_insn (gen_extendhidi2 (t1, operands[0]));
9341 emit_move_insn (t2, gen_rtx (LABEL_REF, DImode, operands[1]));
9342 emit_insn (gen_adddi3 (t3, t1, t2));
9343 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
9348 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
9349 ;;; it is not valid. ??? With the USE, the condition tests may not be required
9352 ;;; ??? The length depends on the ABI. It is two for o32, and one for n32.
9353 ;;; We just use the conservative number here.
9357 (plus:SI (match_operand:SI 0 "register_operand" "d")
9358 (label_ref:SI (match_operand 1 "" ""))))
9359 (use (label_ref:SI (match_dup 1)))]
9360 "!(Pmode == DImode) && next_active_insn (insn) != 0
9361 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9362 && PREV_INSN (next_active_insn (insn)) == operands[1]"
9365 /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */
9366 if (mips_abi == ABI_32 || mips_abi == ABI_O64)
9367 output_asm_insn (\".cpadd\\t%0\", operands);
9368 return \"%*j\\t%0\";
9370 [(set_attr "type" "jump")
9371 (set_attr "mode" "none")
9372 (set_attr "length" "8")])
9374 (define_expand "tablejump_internal4"
9375 [(parallel [(set (pc)
9376 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9377 (label_ref:DI (match_operand 1 "" ""))))
9378 (use (label_ref:DI (match_dup 1)))])]
9382 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
9383 ;;; it is not valid. ??? With the USE, the condition tests may not be required
9388 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9389 (label_ref:DI (match_operand 1 "" ""))))
9390 (use (label_ref:DI (match_dup 1)))]
9391 "Pmode == DImode && next_active_insn (insn) != 0
9392 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9393 && PREV_INSN (next_active_insn (insn)) == operands[1]"
9395 [(set_attr "type" "jump")
9396 (set_attr "mode" "none")])
9398 ;; Implement a switch statement when generating embedded PIC code.
9399 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
9401 (define_expand "casesi"
9403 (minus:SI (match_operand:SI 0 "register_operand" "d")
9404 (match_operand:SI 1 "arith_operand" "dI")))
9406 (compare:CC (match_dup 5)
9407 (match_operand:SI 2 "arith_operand" "")))
9409 (if_then_else (gtu (cc0)
9411 (label_ref (match_operand 4 "" ""))
9415 (mem:SI (plus:SI (mult:SI (match_dup 5)
9417 (label_ref (match_operand 3 "" "")))))
9418 (clobber (match_scratch:SI 6 ""))
9419 (clobber (reg:SI 31))])]
9420 "TARGET_EMBEDDED_PIC"
9425 rtx reg = gen_reg_rtx (SImode);
9427 /* If the index is too large, go to the default label. */
9428 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
9429 emit_insn (gen_cmpsi (reg, operands[2]));
9430 emit_insn (gen_bgtu (operands[4]));
9432 /* Do the PIC jump. */
9433 if (Pmode != DImode)
9434 emit_jump_insn (gen_casesi_internal (reg, operands[3],
9435 gen_reg_rtx (SImode)));
9437 emit_jump_insn (gen_casesi_internal_di (reg, operands[3],
9438 gen_reg_rtx (DImode)));
9444 ;; An embedded PIC switch statement looks like this:
9446 ;; sll $reg,$index,2
9448 ;; addu $reg,$reg,$31
9449 ;; lw $reg,$L1-$LS1($reg)
9450 ;; addu $reg,$reg,$31
9457 (define_insn "casesi_internal"
9459 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
9461 (label_ref (match_operand 1 "" "")))))
9462 (clobber (match_operand:SI 2 "register_operand" "=d"))
9463 (clobber (reg:SI 31))]
9464 "TARGET_EMBEDDED_PIC"
9465 "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
9466 lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\;j\\t%2"
9467 [(set_attr "type" "jump")
9468 (set_attr "mode" "none")
9469 (set_attr "length" "24")])
9471 (define_insn "casesi_internal_di"
9473 (mem:DI (plus:DI (sign_extend:DI
9474 (mult:SI (match_operand:SI 0 "register_operand" "d")
9476 (label_ref (match_operand 1 "" "")))))
9477 (clobber (match_operand:DI 2 "register_operand" "=d"))
9478 (clobber (reg:DI 31))]
9479 "TARGET_EMBEDDED_PIC"
9480 "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
9481 ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\;j\\t%2"
9482 [(set_attr "type" "jump")
9483 (set_attr "mode" "none")
9484 (set_attr "length" "24")])
9486 ;; For o32/n32/n64, we save the gp in the jmp_buf as well. While it is
9487 ;; possible to either pull it off the stack (in the o32 case) or recalculate
9488 ;; it given t9 and our target label, it takes 3 or 4 insns to do so, and
9491 (define_expand "builtin_setjmp_setup"
9492 [(unspec [(match_operand 0 "register_operand" "r")] 20)]
9496 if (Pmode == DImode)
9497 emit_insn (gen_builtin_setjmp_setup_64 (operands[0]));
9499 emit_insn (gen_builtin_setjmp_setup_32 (operands[0]));
9503 (define_expand "builtin_setjmp_setup_32"
9504 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
9507 "TARGET_ABICALLS && ! (Pmode == DImode)"
9510 (define_expand "builtin_setjmp_setup_64"
9511 [(set (mem:DI (plus:DI (match_operand:DI 0 "register_operand" "r")
9514 "TARGET_ABICALLS && Pmode == DImode"
9517 ;; For o32/n32/n64, we need to arrange for longjmp to put the
9518 ;; target address in t9 so that we can use it for loading $gp.
9520 (define_expand "builtin_longjmp"
9521 [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
9525 /* The elements of the buffer are, in order: */
9526 int W = (Pmode == DImode ? 8 : 4);
9527 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9528 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
9529 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
9530 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
9531 rtx pv = gen_rtx_REG (Pmode, 25);
9532 rtx gp = gen_rtx_REG (Pmode, 28);
9534 /* This bit is the same as expand_builtin_longjmp. */
9535 emit_move_insn (hard_frame_pointer_rtx, fp);
9536 emit_move_insn (pv, lab);
9537 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
9538 emit_move_insn (gp, gpv);
9539 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
9540 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9541 emit_insn (gen_rtx_USE (VOIDmode, gp));
9542 emit_indirect_jump (pv);
9547 ;; ....................
9549 ;; Function prologue/epilogue
9551 ;; ....................
9554 (define_expand "prologue"
9559 if (mips_isa >= 0) /* avoid unused code warnings */
9561 mips_expand_prologue ();
9566 ;; Block any insns from being moved before this point, since the
9567 ;; profiling call to mcount can use various registers that aren't
9568 ;; saved or used to pass arguments.
9570 (define_insn "blockage"
9571 [(unspec_volatile [(const_int 0)] 0)]
9574 [(set_attr "type" "unknown")
9575 (set_attr "mode" "none")
9576 (set_attr "length" "0")])
9578 (define_expand "epilogue"
9583 if (mips_isa >= 0) /* avoid unused code warnings */
9585 mips_expand_epilogue ();
9590 ;; Trivial return. Make it look like a normal return insn as that
9591 ;; allows jump optimizations to work better .
9592 (define_insn "return"
9594 "mips_can_use_return_insn ()"
9596 [(set_attr "type" "jump")
9597 (set_attr "mode" "none")])
9601 (define_insn "return_internal"
9602 [(use (match_operand 0 "pmode_register_operand" ""))
9607 return \"%*j\\t%0\";
9609 [(set_attr "type" "jump")
9610 (set_attr "mode" "none")])
9612 ;; When generating embedded PIC code we need to get the address of the
9613 ;; current function. This specialized instruction does just that.
9615 (define_insn "get_fnaddr"
9616 [(set (match_operand 0 "register_operand" "=d")
9617 (unspec [(match_operand 1 "" "")] 1))
9618 (clobber (reg:SI 31))]
9619 "TARGET_EMBEDDED_PIC
9620 && GET_CODE (operands[1]) == SYMBOL_REF"
9621 "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
9622 [(set_attr "type" "call")
9623 (set_attr "mode" "none")
9624 (set_attr "length" "16")])
9626 ;; This is used in compiling the unwind routines.
9627 (define_expand "eh_return"
9628 [(use (match_operand 0 "general_operand" ""))
9629 (use (match_operand 1 "general_operand" ""))]
9633 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
9635 if (GET_MODE (operands[1]) != gpr_mode)
9636 operands[1] = convert_to_mode (gpr_mode, operands[1], 0);
9638 emit_insn (gen_eh_set_lr_di (operands[1]));
9640 emit_insn (gen_eh_set_lr_si (operands[1]));
9642 emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]);
9646 ;; Clobber the return address on the stack. We can't expand this
9647 ;; until we know where it will be put in the stack frame.
9649 (define_insn "eh_set_lr_si"
9650 [(unspec [(match_operand:SI 0 "register_operand" "r")] 3)
9651 (clobber (match_scratch:SI 1 "=&r"))]
9655 (define_insn "eh_set_lr_di"
9656 [(unspec [(match_operand:DI 0 "register_operand" "r")] 3)
9657 (clobber (match_scratch:DI 1 "=&r"))]
9662 [(unspec [(match_operand 0 "register_operand" "")] 3)
9663 (clobber (match_scratch 1 ""))]
9664 "reload_completed && !TARGET_DEBUG_D_MODE"
9668 HOST_WIDE_INT gp_offset;
9671 compute_frame_size (get_frame_size ());
9672 if (((current_frame_info.mask >> 31) & 1) == 0)
9674 gp_offset = current_frame_info.gp_sp_offset;
9676 if (gp_offset < 32768)
9677 base = stack_pointer_rtx;
9681 emit_move_insn (base, GEN_INT (gp_offset));
9682 if (Pmode == DImode)
9683 emit_insn (gen_adddi3 (base, base, stack_pointer_rtx));
9685 emit_insn (gen_addsi3 (base, base, stack_pointer_rtx));
9688 emit_move_insn (gen_rtx_MEM (GET_MODE (operands[0]),
9689 plus_constant (base, gp_offset)),
9694 (define_insn "exception_receiver"
9695 [(unspec_volatile [(const_int 0)] 4)]
9696 "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)"
9701 operands[0] = pic_offset_table_rtx;
9702 if (frame_pointer_needed)
9703 loc = hard_frame_pointer_rtx;
9705 loc = stack_pointer_rtx;
9706 loc = plus_constant (loc, current_frame_info.args_size);
9707 operands[1] = gen_rtx_MEM (Pmode, loc);
9709 return mips_move_1word (operands, insn, 0);
9711 [(set_attr "type" "load")
9712 (set_attr "length" "8")])
9715 ;; ....................
9719 ;; ....................
9721 ;; calls.c now passes a third argument, make saber happy
9723 (define_expand "call"
9724 [(parallel [(call (match_operand 0 "memory_operand" "m")
9725 (match_operand 1 "" "i"))
9726 (clobber (reg:SI 31))
9727 (use (match_operand 2 "" "")) ;; next_arg_reg
9728 (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
9734 if (operands[0]) /* eliminate unused code warnings */
9736 addr = XEXP (operands[0], 0);
9737 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9738 || ! call_insn_operand (addr, VOIDmode))
9739 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
9741 /* In order to pass small structures by value in registers
9742 compatibly with the MIPS compiler, we need to shift the value
9743 into the high part of the register. Function_arg has encoded
9744 a PARALLEL rtx, holding a vector of adjustments to be made
9745 as the next_arg_reg variable, so we split up the insns,
9746 and emit them separately. */
9748 if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
9750 rtvec adjust = XVEC (operands[2], 0);
9751 int num = GET_NUM_ELEM (adjust);
9754 for (i = 0; i < num; i++)
9755 emit_insn (RTVEC_ELT (adjust, i));
9759 && mips16_hard_float
9761 && (int) GET_MODE (operands[2]) != 0)
9763 if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1],
9764 (int) GET_MODE (operands[2])))
9768 emit_call_insn (gen_call_internal0 (operands[0], operands[1],
9769 gen_rtx_REG (SImode,
9770 GP_REG_FIRST + 31)));
9775 (define_expand "call_internal0"
9776 [(parallel [(call (match_operand 0 "" "")
9777 (match_operand 1 "" ""))
9778 (clobber (match_operand:SI 2 "" ""))])]
9782 ;; We need to recognize reg:SI 31 specially for the mips16, because we
9783 ;; don't have a constraint letter for it.
9786 [(call (mem (match_operand 0 "call_insn_operand" "ei"))
9787 (match_operand 1 "" "i"))
9788 (clobber (match_operand:SI 2 "register_operand" "=y"))]
9789 "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9790 && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9792 [(set_attr "type" "call")
9793 (set_attr "mode" "none")
9794 (set_attr "length" "8")])
9796 (define_insn "call_internal1"
9797 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9798 (match_operand 1 "" "i"))
9799 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9800 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9803 register rtx target = operands[0];
9805 if (GET_CODE (target) == CONST_INT)
9806 return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
9807 else if (CONSTANT_ADDRESS_P (target))
9808 return \"%*jal\\t%0\";
9810 return \"%*jal\\t%2,%0\";
9812 [(set_attr "type" "call")
9813 (set_attr "mode" "none")])
9815 (define_insn "call_internal2"
9816 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9817 (match_operand 1 "" "i"))
9818 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9819 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9822 register rtx target = operands[0];
9824 if (GET_CODE (target) == CONST_INT)
9825 return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
9826 else if (CONSTANT_ADDRESS_P (target))
9828 if (GET_MODE (target) == SImode)
9829 return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
9831 return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
9833 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9834 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9836 return \"jal\\t%2,%0\";
9838 [(set_attr "type" "call")
9839 (set_attr "mode" "none")
9840 (set_attr "length" "8")])
9842 (define_insn "call_internal3a"
9843 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9844 (match_operand 1 "" "i"))
9845 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9847 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9849 [(set_attr "type" "call")
9850 (set_attr "mode" "none")])
9852 (define_insn "call_internal3b"
9853 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9854 (match_operand 1 "" "i"))
9855 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9857 && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9859 [(set_attr "type" "call")
9860 (set_attr "mode" "none")
9861 (set_attr "length" "1")])
9863 (define_insn "call_internal3c"
9864 [(call (mem:SI (match_operand:SI 0 "register_operand" "e"))
9865 (match_operand 1 "" "i"))
9866 (clobber (match_operand:SI 2 "register_operand" "=y"))]
9867 "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
9868 && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9870 [(set_attr "type" "call")
9871 (set_attr "mode" "none")])
9873 (define_insn "call_internal4a"
9874 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9875 (match_operand 1 "" "i"))
9876 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9877 "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
9880 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9881 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9883 return \"jal\\t%2,%0\";
9885 [(set_attr "type" "call")
9886 (set_attr "mode" "none")
9887 (set_attr "length" "8")])
9889 (define_insn "call_internal4b"
9890 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9891 (match_operand 1 "" "i"))
9892 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9893 "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
9896 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9897 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9899 return \"jal\\t%2,%0\";
9901 [(set_attr "type" "call")
9902 (set_attr "mode" "none")
9903 (set_attr "length" "8")])
9905 ;; calls.c now passes a fourth argument, make saber happy
9907 (define_expand "call_value"
9908 [(parallel [(set (match_operand 0 "register_operand" "=df")
9909 (call (match_operand 1 "memory_operand" "m")
9910 (match_operand 2 "" "i")))
9911 (clobber (reg:SI 31))
9912 (use (match_operand 3 "" ""))])] ;; next_arg_reg
9918 if (operands[0]) /* eliminate unused code warning */
9920 addr = XEXP (operands[1], 0);
9921 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9922 || ! call_insn_operand (addr, VOIDmode))
9923 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
9925 /* In order to pass small structures by value in registers
9926 compatibly with the MIPS compiler, we need to shift the value
9927 into the high part of the register. Function_arg has encoded
9928 a PARALLEL rtx, holding a vector of adjustments to be made
9929 as the next_arg_reg variable, so we split up the insns,
9930 and emit them separately. */
9932 if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
9934 rtvec adjust = XVEC (operands[3], 0);
9935 int num = GET_NUM_ELEM (adjust);
9938 for (i = 0; i < num; i++)
9939 emit_insn (RTVEC_ELT (adjust, i));
9943 && mips16_hard_float
9944 && ((operands[3] != 0
9945 && (int) GET_MODE (operands[3]) != 0)
9946 || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT))
9948 if (build_mips16_call_stub (operands[0], operands[1], operands[2],
9949 (operands[3] == 0 ? 0
9950 : (int) GET_MODE (operands[3]))))
9954 /* Handle Irix6 function calls that have multiple non-contiguous
9956 if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
9958 emit_call_insn (gen_call_value_multiple_internal0
9959 (XEXP (XVECEXP (operands[0], 0, 0), 0),
9960 operands[1], operands[2],
9961 XEXP (XVECEXP (operands[0], 0, 1), 0),
9962 gen_rtx_REG (SImode, GP_REG_FIRST + 31)));
9966 /* We have a call returning a DImode structure in an FP reg.
9967 Strip off the now unnecessary PARALLEL. */
9968 if (GET_CODE (operands[0]) == PARALLEL)
9969 operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
9971 emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
9972 gen_rtx_REG (SImode,
9973 GP_REG_FIRST + 31)));
9979 (define_expand "call_value_internal0"
9980 [(parallel [(set (match_operand 0 "" "")
9981 (call (match_operand 1 "" "")
9982 (match_operand 2 "" "")))
9983 (clobber (match_operand:SI 3 "" ""))])]
9987 ;; Recognize $31 specially on the mips16, because we don't have a
9988 ;; constraint letter for it.
9991 [(set (match_operand 0 "register_operand" "=d")
9992 (call (mem (match_operand 1 "call_insn_operand" "ei"))
9993 (match_operand 2 "" "i")))
9994 (clobber (match_operand:SI 3 "register_operand" "=y"))]
9995 "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9996 && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
9998 [(set_attr "type" "call")
9999 (set_attr "mode" "none")
10000 (set_attr "length" "8")])
10002 (define_insn "call_value_internal1"
10003 [(set (match_operand 0 "register_operand" "=df")
10004 (call (mem (match_operand 1 "call_insn_operand" "ri"))
10005 (match_operand 2 "" "i")))
10006 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10007 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10010 register rtx target = operands[1];
10012 if (GET_CODE (target) == CONST_INT)
10013 return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
10014 else if (CONSTANT_ADDRESS_P (target))
10015 return \"%*jal\\t%1\";
10017 return \"%*jal\\t%3,%1\";
10019 [(set_attr "type" "call")
10020 (set_attr "mode" "none")])
10022 (define_insn "call_value_internal2"
10023 [(set (match_operand 0 "register_operand" "=df")
10024 (call (mem (match_operand 1 "call_insn_operand" "ri"))
10025 (match_operand 2 "" "i")))
10026 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10027 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10030 register rtx target = operands[1];
10032 if (GET_CODE (target) == CONST_INT)
10033 return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
10034 else if (CONSTANT_ADDRESS_P (target))
10036 if (GET_MODE (target) == SImode)
10037 return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
10039 return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
10041 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10042 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10044 return \"jal\\t%3,%1\";
10046 [(set_attr "type" "call")
10047 (set_attr "mode" "none")
10048 (set_attr "length" "8")])
10050 (define_insn "call_value_internal3a"
10051 [(set (match_operand 0 "register_operand" "=df")
10052 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10053 (match_operand 2 "" "i")))
10054 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10056 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10058 [(set_attr "type" "call")
10059 (set_attr "mode" "none")])
10061 (define_insn "call_value_internal3b"
10062 [(set (match_operand 0 "register_operand" "=df")
10063 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10064 (match_operand 2 "" "i")))
10065 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10067 && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
10069 [(set_attr "type" "call")
10070 (set_attr "mode" "none")])
10072 (define_insn "call_value_internal3c"
10073 [(set (match_operand 0 "register_operand" "=df")
10074 (call (mem:SI (match_operand:SI 1 "register_operand" "e"))
10075 (match_operand 2 "" "i")))
10076 (clobber (match_operand:SI 3 "register_operand" "=y"))]
10077 "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
10078 && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
10080 [(set_attr "type" "call")
10081 (set_attr "mode" "none")])
10083 (define_insn "call_value_internal4a"
10084 [(set (match_operand 0 "register_operand" "=df")
10085 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
10086 (match_operand 2 "" "i")))
10087 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10088 "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
10091 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10092 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10094 return \"jal\\t%3,%1\";
10096 [(set_attr "type" "call")
10097 (set_attr "mode" "none")
10098 (set_attr "length" "8")])
10100 (define_insn "call_value_internal4b"
10101 [(set (match_operand 0 "register_operand" "=df")
10102 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
10103 (match_operand 2 "" "i")))
10104 (clobber (match_operand:SI 3 "register_operand" "=d"))]
10105 "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
10108 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
10109 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
10111 return \"jal\\t%3,%1\";
10113 [(set_attr "type" "call")
10114 (set_attr "mode" "none")
10115 (set_attr "length" "8")])
10117 (define_expand "call_value_multiple_internal0"
10118 [(parallel [(set (match_operand 0 "" "")
10119 (call (match_operand 1 "" "")
10120 (match_operand 2 "" "")))
10121 (set (match_operand 3 "" "")
10122 (call (match_dup 1)
10124 (clobber (match_operand:SI 4 "" ""))])]
10128 ;; ??? May eventually need all 6 versions of the call patterns with multiple
10131 (define_insn "call_value_multiple_internal1"
10132 [(set (match_operand 0 "register_operand" "=df")
10133 (call (mem (match_operand 1 "call_insn_operand" "ri"))
10134 (match_operand 2 "" "i")))
10135 (set (match_operand 3 "register_operand" "=df")
10136 (call (mem (match_dup 1))
10138 (clobber (match_operand:SI 4 "register_operand" "=d"))]
10139 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
10142 register rtx target = operands[1];
10144 if (GET_CODE (target) == CONST_INT)
10145 return \"%[li\\t%@,%1\\n\\t%*jal\\t%4,%@%]\";
10146 else if (CONSTANT_ADDRESS_P (target))
10147 return \"%*jal\\t%1\";
10149 return \"%*jal\\t%4,%1\";
10151 [(set_attr "type" "call")
10152 (set_attr "mode" "none")])
10154 (define_insn "call_value_multiple_internal2"
10155 [(set (match_operand 0 "register_operand" "=df")
10156 (call (mem (match_operand 1 "call_insn_operand" "ri"))
10157 (match_operand 2 "" "i")))
10158 (set (match_operand 3 "register_operand" "=df")
10159 (call (mem (match_dup 1))
10161 (clobber (match_operand:SI 4 "register_operand" "=d"))]
10162 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
10165 register rtx target = operands[1];
10167 if (GET_CODE (target) == CONST_INT)
10168 return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
10169 else if (CONSTANT_ADDRESS_P (target))
10171 if (GET_MODE (target) == SImode)
10172 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
10174 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
10176 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
10177 return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
10179 return \"jal\\t%4,%1\";
10181 [(set_attr "type" "call")
10182 (set_attr "mode" "none")
10183 (set_attr "length" "8")])
10186 ;; Call subroutine returning any type.
10188 (define_expand "untyped_call"
10189 [(parallel [(call (match_operand 0 "" "")
10191 (match_operand 1 "" "")
10192 (match_operand 2 "" "")])]
10196 if (operands[0]) /* silence statement not reached warnings */
10200 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
10202 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10204 rtx set = XVECEXP (operands[2], 0, i);
10205 emit_move_insn (SET_DEST (set), SET_SRC (set));
10208 emit_insn (gen_blockage ());
10214 ;; ....................
10218 ;; ....................
10225 [(set_attr "type" "nop")
10226 (set_attr "mode" "none")])
10228 ;; The MIPS chip does not seem to require stack probes.
10230 ;; (define_expand "probe"
10231 ;; [(set (match_dup 0)
10236 ;; operands[0] = gen_reg_rtx (SImode);
10237 ;; operands[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
10238 ;; MEM_VOLATILE_P (operands[1]) = TRUE;
10240 ;; /* fall through and generate default code */
10245 ;; MIPS4 Conditional move instructions.
10248 [(set (match_operand:SI 0 "register_operand" "=d,d")
10250 (match_operator 4 "equality_op"
10251 [(match_operand:SI 1 "register_operand" "d,d")
10253 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10254 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10255 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10258 mov%b4\\t%0,%z3,%1"
10259 [(set_attr "type" "move")
10260 (set_attr "mode" "SI")])
10263 [(set (match_operand:SI 0 "register_operand" "=d,d")
10265 (match_operator 4 "equality_op"
10266 [(match_operand:DI 1 "se_register_operand" "d,d")
10268 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10269 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
10270 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10273 mov%b4\\t%0,%z3,%1"
10274 [(set_attr "type" "move")
10275 (set_attr "mode" "SI")])
10278 [(set (match_operand:SI 0 "register_operand" "=d,d")
10280 (match_operator 3 "equality_op" [(match_operand:CC 4
10284 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
10285 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
10286 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10289 mov%t3\\t%0,%z2,%4"
10290 [(set_attr "type" "move")
10291 (set_attr "mode" "SI")])
10294 [(set (match_operand:DI 0 "register_operand" "=d,d")
10296 (match_operator 4 "equality_op"
10297 [(match_operand:SI 1 "register_operand" "d,d")
10299 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10300 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10301 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10304 mov%b4\\t%0,%z3,%1"
10305 [(set_attr "type" "move")
10306 (set_attr "mode" "DI")])
10309 [(set (match_operand:DI 0 "register_operand" "=d,d")
10311 (match_operator 4 "equality_op"
10312 [(match_operand:DI 1 "se_register_operand" "d,d")
10314 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10315 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10316 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10319 mov%b4\\t%0,%z3,%1"
10320 [(set_attr "type" "move")
10321 (set_attr "mode" "DI")])
10324 [(set (match_operand:DI 0 "register_operand" "=d,d")
10326 (match_operator 3 "equality_op" [(match_operand:CC 4
10330 (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
10331 (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
10332 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
10335 mov%t3\\t%0,%z2,%4"
10336 [(set_attr "type" "move")
10337 (set_attr "mode" "DI")])
10340 [(set (match_operand:SF 0 "register_operand" "=f,f")
10342 (match_operator 4 "equality_op"
10343 [(match_operand:SI 1 "register_operand" "d,d")
10345 (match_operand:SF 2 "register_operand" "f,0")
10346 (match_operand:SF 3 "register_operand" "0,f")))]
10347 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10349 mov%B4.s\\t%0,%2,%1
10350 mov%b4.s\\t%0,%3,%1"
10351 [(set_attr "type" "move")
10352 (set_attr "mode" "SF")])
10355 [(set (match_operand:SF 0 "register_operand" "=f,f")
10357 (match_operator 4 "equality_op"
10358 [(match_operand:DI 1 "se_register_operand" "d,d")
10360 (match_operand:SF 2 "register_operand" "f,0")
10361 (match_operand:SF 3 "register_operand" "0,f")))]
10362 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10364 mov%B4.s\\t%0,%2,%1
10365 mov%b4.s\\t%0,%3,%1"
10366 [(set_attr "type" "move")
10367 (set_attr "mode" "SF")])
10370 [(set (match_operand:SF 0 "register_operand" "=f,f")
10372 (match_operator 3 "equality_op" [(match_operand:CC 4
10376 (match_operand:SF 1 "register_operand" "f,0")
10377 (match_operand:SF 2 "register_operand" "0,f")))]
10378 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10380 mov%T3.s\\t%0,%1,%4
10381 mov%t3.s\\t%0,%2,%4"
10382 [(set_attr "type" "move")
10383 (set_attr "mode" "SF")])
10386 [(set (match_operand:DF 0 "register_operand" "=f,f")
10388 (match_operator 4 "equality_op"
10389 [(match_operand:SI 1 "register_operand" "d,d")
10391 (match_operand:DF 2 "register_operand" "f,0")
10392 (match_operand:DF 3 "register_operand" "0,f")))]
10393 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10395 mov%B4.d\\t%0,%2,%1
10396 mov%b4.d\\t%0,%3,%1"
10397 [(set_attr "type" "move")
10398 (set_attr "mode" "DF")])
10401 [(set (match_operand:DF 0 "register_operand" "=f,f")
10403 (match_operator 4 "equality_op"
10404 [(match_operand:DI 1 "se_register_operand" "d,d")
10406 (match_operand:DF 2 "register_operand" "f,0")
10407 (match_operand:DF 3 "register_operand" "0,f")))]
10408 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10410 mov%B4.d\\t%0,%2,%1
10411 mov%b4.d\\t%0,%3,%1"
10412 [(set_attr "type" "move")
10413 (set_attr "mode" "DF")])
10416 [(set (match_operand:DF 0 "register_operand" "=f,f")
10418 (match_operator 3 "equality_op" [(match_operand:CC 4
10422 (match_operand:DF 1 "register_operand" "f,0")
10423 (match_operand:DF 2 "register_operand" "0,f")))]
10424 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10426 mov%T3.d\\t%0,%1,%4
10427 mov%t3.d\\t%0,%2,%4"
10428 [(set_attr "type" "move")
10429 (set_attr "mode" "DF")])
10431 ;; These are the main define_expand's used to make conditional moves.
10433 (define_expand "movsicc"
10434 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10435 (set (match_operand:SI 0 "register_operand" "")
10436 (if_then_else:SI (match_dup 5)
10437 (match_operand:SI 2 "reg_or_0_operand" "")
10438 (match_operand:SI 3 "reg_or_0_operand" "")))]
10439 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
10442 gen_conditional_move (operands);
10446 (define_expand "movdicc"
10447 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10448 (set (match_operand:DI 0 "register_operand" "")
10449 (if_then_else:DI (match_dup 5)
10450 (match_operand:DI 2 "se_reg_or_0_operand" "")
10451 (match_operand:DI 3 "se_reg_or_0_operand" "")))]
10452 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
10455 if (mips_isa == 32)
10457 gen_conditional_move (operands);
10461 (define_expand "movsfcc"
10462 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10463 (set (match_operand:SF 0 "register_operand" "")
10464 (if_then_else:SF (match_dup 5)
10465 (match_operand:SF 2 "register_operand" "")
10466 (match_operand:SF 3 "register_operand" "")))]
10467 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
10470 gen_conditional_move (operands);
10474 (define_expand "movdfcc"
10475 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10476 (set (match_operand:DF 0 "register_operand" "")
10477 (if_then_else:DF (match_dup 5)
10478 (match_operand:DF 2 "register_operand" "")
10479 (match_operand:DF 3 "register_operand" "")))]
10480 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10483 gen_conditional_move (operands);
10488 ;; ....................
10490 ;; mips16 inline constant tables
10492 ;; ....................
10495 (define_insn "consttable_qi"
10496 [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")] 10)]
10500 assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
10503 [(set_attr "type" "unknown")
10504 (set_attr "mode" "QI")
10505 (set_attr "length" "8")])
10507 (define_insn "consttable_hi"
10508 [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")] 11)]
10512 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10515 [(set_attr "type" "unknown")
10516 (set_attr "mode" "HI")
10517 (set_attr "length" "8")])
10519 (define_insn "consttable_si"
10520 [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")] 12)]
10524 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10527 [(set_attr "type" "unknown")
10528 (set_attr "mode" "SI")
10529 (set_attr "length" "8")])
10531 (define_insn "consttable_di"
10532 [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")] 13)]
10536 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10539 [(set_attr "type" "unknown")
10540 (set_attr "mode" "DI")
10541 (set_attr "length" "16")])
10543 (define_insn "consttable_sf"
10544 [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")] 14)]
10548 union real_extract u;
10550 if (GET_CODE (operands[0]) != CONST_DOUBLE)
10552 memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
10553 assemble_real (u.d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10556 [(set_attr "type" "unknown")
10557 (set_attr "mode" "SF")
10558 (set_attr "length" "8")])
10560 (define_insn "consttable_df"
10561 [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")] 15)]
10565 union real_extract u;
10567 if (GET_CODE (operands[0]) != CONST_DOUBLE)
10569 memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
10570 assemble_real (u.d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10573 [(set_attr "type" "unknown")
10574 (set_attr "mode" "DF")
10575 (set_attr "length" "16")])
10577 (define_insn "align_2"
10578 [(unspec_volatile [(const_int 0)] 16)]
10581 [(set_attr "type" "unknown")
10582 (set_attr "mode" "HI")
10583 (set_attr "length" "8")])
10585 (define_insn "align_4"
10586 [(unspec_volatile [(const_int 0)] 17)]
10589 [(set_attr "type" "unknown")
10590 (set_attr "mode" "SI")
10591 (set_attr "length" "8")])
10593 (define_insn "align_8"
10594 [(unspec_volatile [(const_int 0)] 18)]
10597 [(set_attr "type" "unknown")
10598 (set_attr "mode" "DI")
10599 (set_attr "length" "12")])
10602 ;; ....................
10604 ;; mips16 peepholes
10606 ;; ....................
10609 ;; On the mips16, reload will sometimes decide that a pseudo register
10610 ;; should go into $24, and then later on have to reload that register.
10611 ;; When that happens, we get a load of a general register followed by
10612 ;; a move from the general register to $24 followed by a branch.
10613 ;; These peepholes catch the common case, and fix it to just use the
10614 ;; general register for the branch.
10617 [(set (match_operand:SI 0 "register_operand" "=t")
10618 (match_operand:SI 1 "register_operand" "d"))
10620 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10622 (match_operand 3 "pc_or_label_operand" "")
10623 (match_operand 4 "pc_or_label_operand" "")))]
10625 && GET_CODE (operands[0]) == REG
10626 && REGNO (operands[0]) == 24
10627 && dead_or_set_p (insn, operands[0])
10628 && GET_CODE (operands[1]) == REG
10629 && M16_REG_P (REGNO (operands[1]))"
10632 if (operands[3] != pc_rtx)
10633 return \"%*b%C2z\\t%1,%3\";
10635 return \"%*b%N2z\\t%1,%4\";
10637 [(set_attr "type" "branch")
10638 (set_attr "mode" "none")
10639 (set_attr "length" "8")])
10642 [(set (match_operand:DI 0 "register_operand" "=t")
10643 (match_operand:DI 1 "register_operand" "d"))
10645 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10647 (match_operand 3 "pc_or_label_operand" "")
10648 (match_operand 4 "pc_or_label_operand" "")))]
10649 "TARGET_MIPS16 && TARGET_64BIT
10650 && GET_CODE (operands[0]) == REG
10651 && REGNO (operands[0]) == 24
10652 && dead_or_set_p (insn, operands[0])
10653 && GET_CODE (operands[1]) == REG
10654 && M16_REG_P (REGNO (operands[1]))"
10657 if (operands[3] != pc_rtx)
10658 return \"%*b%C2z\\t%1,%3\";
10660 return \"%*b%N2z\\t%1,%4\";
10662 [(set_attr "type" "branch")
10663 (set_attr "mode" "none")
10664 (set_attr "length" "8")])
10666 ;; We can also have the reverse reload: reload will spill $24 into
10667 ;; another register, and then do a branch on that register when it
10668 ;; could have just stuck with $24.
10671 [(set (match_operand:SI 0 "register_operand" "=d")
10672 (match_operand:SI 1 "register_operand" "t"))
10674 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10676 (match_operand 3 "pc_or_label_operand" "")
10677 (match_operand 4 "pc_or_label_operand" "")))]
10679 && GET_CODE (operands[1]) == REG
10680 && REGNO (operands[1]) == 24
10681 && GET_CODE (operands[0]) == REG
10682 && M16_REG_P (REGNO (operands[0]))
10683 && dead_or_set_p (insn, operands[0])"
10686 if (operands[3] != pc_rtx)
10687 return \"%*bt%C2z\\t%3\";
10689 return \"%*bt%N2z\\t%4\";
10691 [(set_attr "type" "branch")
10692 (set_attr "mode" "none")
10693 (set_attr "length" "8")])
10696 [(set (match_operand:DI 0 "register_operand" "=d")
10697 (match_operand:DI 1 "register_operand" "t"))
10699 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10701 (match_operand 3 "pc_or_label_operand" "")
10702 (match_operand 4 "pc_or_label_operand" "")))]
10703 "TARGET_MIPS16 && TARGET_64BIT
10704 && GET_CODE (operands[1]) == REG
10705 && REGNO (operands[1]) == 24
10706 && GET_CODE (operands[0]) == REG
10707 && M16_REG_P (REGNO (operands[0]))
10708 && dead_or_set_p (insn, operands[0])"
10711 if (operands[3] != pc_rtx)
10712 return \"%*bt%C2z\\t%3\";
10714 return \"%*bt%N2z\\t%4\";
10716 [(set_attr "type" "branch")
10717 (set_attr "mode" "none")
10718 (set_attr "length" "8")])
10720 ;; For the rare case where we need to load an address into a register
10721 ;; that can not be recognized by the normal movsi/addsi instructions.
10722 ;; I have no idea how many insns this can actually generate. It should
10723 ;; be rare, so over-estimating as 10 instructions should not have any
10724 ;; real performance impact.
10725 (define_insn "leasi"
10726 [(set (match_operand:SI 0 "register_operand" "=d")
10727 (match_operand:SI 1 "address_operand" "p"))]
10730 [(set_attr "type" "arith")
10731 (set_attr "mode" "SI")
10732 (set_attr "length" "40")])
10734 ;; Similarly for targets where we have 64bit pointers.
10735 (define_insn "leadi"
10736 [(set (match_operand:DI 0 "register_operand" "=d")
10737 (match_operand:DI 1 "address_operand" "p"))]
10740 [(set_attr "type" "arith")
10741 (set_attr "mode" "DI")
10742 (set_attr "length" "40")])