1 ;; Mips.md Machine Description for MIPS based processors
2 ;; Contributed by A. Lichnewsky, lich@inria.inria.fr
3 ;; Changes by Michael Meissner, meissner@osf.org
4 ;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
5 ;; Brendan Eich, brendan@microunity.com.
6 ;; Copyright (C) 1989, 90-98, 1999 Free Software Foundation, Inc.
8 ;; This file is part of GNU CC.
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;; ??? Currently does not have define_function_unit support for the R8000.
26 ;; Must include new entries for fmadd in addition to existing entries.
30 ;; ....................
34 ;; ....................
36 ;; Classification of each insn.
37 ;; branch conditional branch
38 ;; jump unconditional jump
39 ;; call unconditional call
40 ;; load load instruction(s)
41 ;; store store instruction(s)
42 ;; move data movement within same register set
43 ;; xfer transfer to/from coprocessor
44 ;; hilo transfer of hi/lo registers
45 ;; arith integer arithmetic instruction
46 ;; darith double precision integer arithmetic instructions
47 ;; imul integer multiply
48 ;; idiv integer divide
49 ;; icmp integer compare
50 ;; fadd floating point add/subtract
51 ;; fmul floating point multiply
52 ;; fmadd floating point multiply-add
53 ;; fdiv floating point divide
54 ;; fabs floating point absolute value
55 ;; fneg floating point negation
56 ;; fcmp floating point compare
57 ;; fcvt floating point convert
58 ;; fsqrt floating point square root
59 ;; multi multiword sequence (or user asm statements)
63 "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"
64 (const_string "unknown"))
66 ;; Main data type used by the insn
67 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
69 ;; Length (in # of bytes). A conditional branch is allowed only to a
70 ;; location within a signed 18-bit offset of the delay slot. If that
71 ;; provides too smal a range, we use the `j' instruction. This
72 ;; instruction takes a 28-bit value, but that value is not an offset.
73 ;; Instead, it's bitwise-ored with the high-order four bits of the
74 ;; instruction in the delay slot, which means it cannot be used to
75 ;; cross a 256MB boundary. We could fall back back on the jr,
76 ;; instruction which allows full access to the entire address space,
77 ;; but we do not do so at present.
79 (define_attr "length" ""
80 (cond [(eq_attr "type" "branch")
81 (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
87 ;; Attribute describing the processor. This attribute must match exactly
88 ;; with the processor_type enumeration in mips.h.
90 ;; Attribute describing the processor
91 ;; (define_attr "cpu" "default,r3000,r6000,r4000"
93 ;; (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000")) (const_string "r3000")
94 ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000")) (const_string "r4000")
95 ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000")) (const_string "r6000")]
96 ;; (const_string "default"))))
98 ;; ??? Fix everything that tests this attribute.
100 "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r8000"
101 (const (symbol_ref "mips_cpu_attr")))
103 ;; Does the instruction have a mandatory delay slot?
104 ;; The 3900, is (mostly) mips1, but does not have a mandatory load delay
106 (define_attr "dslot" "no,yes"
107 (if_then_else (ior (eq_attr "type" "branch,jump,call,xfer,hilo,fcmp")
108 (and (eq_attr "type" "load")
109 (and (eq (symbol_ref "mips_isa") (const_int 1))
110 (and (eq (symbol_ref "mips16") (const_int 0))
111 (eq_attr "cpu" "!r3900")))))
113 (const_string "no")))
115 ;; Attribute defining whether or not we can use the branch-likely instructions
117 (define_attr "branch_likely" "no,yes"
119 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
121 (const_string "no"))))
124 ;; Describe a user's asm statement.
125 (define_asm_attributes
126 [(set_attr "type" "multi")])
128 ;; whether or not generating calls to position independent functions
129 (define_attr "abicalls" "no,yes"
130 (const (symbol_ref "mips_abicalls_attr")))
134 ;; .........................
136 ;; Delay slots, can't describe load/fcmp/xfer delay slots here
138 ;; .........................
140 (define_delay (and (eq_attr "type" "branch")
141 (eq (symbol_ref "mips16") (const_int 0)))
142 [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
144 (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "4")))])
146 (define_delay (eq_attr "type" "jump")
147 [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
151 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
152 [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
158 ;; .........................
162 ;; .........................
164 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
165 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
167 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
169 (define_function_unit "memory" 1 0
170 (and (eq_attr "type" "load")
171 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
174 (define_function_unit "memory" 1 0
175 (and (eq_attr "type" "load")
176 (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
179 (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
181 (define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)
183 (define_function_unit "imuldiv" 1 0
184 (eq_attr "type" "hilo")
187 (define_function_unit "imuldiv" 1 0
188 (and (eq_attr "type" "imul")
189 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
192 ;; On them mips16, we want to stronly discourage a mult from appearing
193 ;; after an mflo, since that requires explicit nop instructions. We
194 ;; do this by pretending that mflo ties up the function unit for long
195 ;; enough that the scheduler will ignore load stalls and the like when
196 ;; selecting instructions to between the two instructions.
198 (define_function_unit "imuldiv" 1 0
199 (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0)))
202 (define_function_unit "imuldiv" 1 0
203 (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000,r3900"))
206 (define_function_unit "imuldiv" 1 0
207 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
210 (define_function_unit "imuldiv" 1 0
211 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4650"))
214 (define_function_unit "imuldiv" 1 0
215 (and (eq_attr "type" "imul")
216 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
219 (define_function_unit "imuldiv" 1 0
220 (and (eq_attr "type" "imul")
221 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
224 (define_function_unit "imuldiv" 1 0
225 (and (eq_attr "type" "imul")
226 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
229 (define_function_unit "imuldiv" 1 0
230 (and (eq_attr "type" "imul")
231 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
234 (define_function_unit "imuldiv" 1 0
235 (and (eq_attr "type" "imul")
236 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
239 (define_function_unit "imuldiv" 1 0
240 (and (eq_attr "type" "idiv")
241 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
244 (define_function_unit "imuldiv" 1 0
245 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
248 (define_function_unit "imuldiv" 1 0
249 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
252 (define_function_unit "imuldiv" 1 0
253 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
256 (define_function_unit "imuldiv" 1 0
257 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
260 (define_function_unit "imuldiv" 1 0
261 (and (eq_attr "type" "idiv")
262 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
265 (define_function_unit "imuldiv" 1 0
266 (and (eq_attr "type" "idiv")
267 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
270 (define_function_unit "imuldiv" 1 0
271 (and (eq_attr "type" "idiv")
272 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
275 (define_function_unit "imuldiv" 1 0
276 (and (eq_attr "type" "idiv")
277 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
280 (define_function_unit "imuldiv" 1 0
281 (and (eq_attr "type" "idiv")
282 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
285 (define_function_unit "imuldiv" 1 0
286 (and (eq_attr "type" "idiv")
287 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
290 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
291 ;; the FP hardware is part of the normal ALU circuitry. This means FP
292 ;; instructions affect the pipe-line, and no functional unit
293 ;; parallelism can occur on R4300 processors. To force GCC into coding
294 ;; for only a single functional unit, we force the R4300 FP
295 ;; instructions to be processed in the "imuldiv" unit.
297 (define_function_unit "adder" 1 1
298 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
301 (define_function_unit "adder" 1 1
302 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
305 (define_function_unit "adder" 1 1
306 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
309 (define_function_unit "adder" 1 1
310 (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
313 (define_function_unit "adder" 1 1
314 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
317 (define_function_unit "adder" 1 1
318 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
321 (define_function_unit "adder" 1 1
322 (and (eq_attr "type" "fabs,fneg")
323 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
326 (define_function_unit "adder" 1 1
327 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
330 (define_function_unit "mult" 1 1
331 (and (eq_attr "type" "fmul")
332 (and (eq_attr "mode" "SF")
333 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
336 (define_function_unit "mult" 1 1
337 (and (eq_attr "type" "fmul")
338 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
341 (define_function_unit "mult" 1 1
342 (and (eq_attr "type" "fmul")
343 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
346 (define_function_unit "mult" 1 1
347 (and (eq_attr "type" "fmul")
348 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
351 (define_function_unit "mult" 1 1
352 (and (eq_attr "type" "fmul")
353 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
356 (define_function_unit "mult" 1 1
357 (and (eq_attr "type" "fmul")
358 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
361 (define_function_unit "mult" 1 1
362 (and (eq_attr "type" "fmul")
363 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
366 (define_function_unit "divide" 1 1
367 (and (eq_attr "type" "fdiv")
368 (and (eq_attr "mode" "SF")
369 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
372 (define_function_unit "divide" 1 1
373 (and (eq_attr "type" "fdiv")
374 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
377 (define_function_unit "divide" 1 1
378 (and (eq_attr "type" "fdiv")
379 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
382 (define_function_unit "divide" 1 1
383 (and (eq_attr "type" "fdiv")
384 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
387 (define_function_unit "divide" 1 1
388 (and (eq_attr "type" "fdiv")
389 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
392 (define_function_unit "divide" 1 1
393 (and (eq_attr "type" "fdiv")
394 (and (eq_attr "mode" "DF")
395 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
398 (define_function_unit "divide" 1 1
399 (and (eq_attr "type" "fdiv")
400 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
403 (define_function_unit "divide" 1 1
404 (and (eq_attr "type" "fdiv")
405 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
408 (define_function_unit "divide" 1 1
409 (and (eq_attr "type" "fdiv")
410 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
413 ;;; ??? Is this number right?
414 (define_function_unit "divide" 1 1
415 (and (eq_attr "type" "fsqrt")
416 (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
419 (define_function_unit "divide" 1 1
420 (and (eq_attr "type" "fsqrt")
421 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
424 (define_function_unit "divide" 1 1
425 (and (eq_attr "type" "fsqrt")
426 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
429 ;;; ??? Is this number right?
430 (define_function_unit "divide" 1 1
431 (and (eq_attr "type" "fsqrt")
432 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
435 (define_function_unit "divide" 1 1
436 (and (eq_attr "type" "fsqrt")
437 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
440 (define_function_unit "divide" 1 1
441 (and (eq_attr "type" "fsqrt")
442 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
445 ;; R4300 FP instruction classes treated as part of the "imuldiv"
448 (define_function_unit "imuldiv" 1 0
449 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
452 (define_function_unit "imuldiv" 1 0
453 (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
456 (define_function_unit "imuldiv" 1 0
457 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
459 (define_function_unit "imuldiv" 1 0
460 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
463 (define_function_unit "imuldiv" 1 0
464 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
465 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
467 (define_function_unit "imuldiv" 1 0
468 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
469 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
472 ;; The following functional units do not use the cpu type, and use
473 ;; much less memory in genattrtab.c.
475 ;; (define_function_unit "memory" 1 0 (eq_attr "type" "load") 3 0)
476 ;; (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
478 ;; (define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0)
480 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0)
481 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0)
483 ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "imul") 17 0)
484 ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "idiv") 38 0)
486 ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fadd") 4 0)
487 ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fabs,fneg") 2 0)
489 ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF")) 7 0)
490 ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF")) 8 0)
492 ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF")) 23 0)
493 ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF")) 36 0)
495 ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0)
496 ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
500 ;; ....................
504 ;; ....................
507 (define_insn "adddf3"
508 [(set (match_operand:DF 0 "register_operand" "=f")
509 (plus:DF (match_operand:DF 1 "register_operand" "f")
510 (match_operand:DF 2 "register_operand" "f")))]
511 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
513 [(set_attr "type" "fadd")
514 (set_attr "mode" "DF")])
516 (define_insn "addsf3"
517 [(set (match_operand:SF 0 "register_operand" "=f")
518 (plus:SF (match_operand:SF 1 "register_operand" "f")
519 (match_operand:SF 2 "register_operand" "f")))]
522 [(set_attr "type" "fadd")
523 (set_attr "mode" "SF")])
525 (define_expand "addsi3"
526 [(set (match_operand:SI 0 "register_operand" "=d")
527 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
528 (match_operand:SI 2 "arith_operand" "dI")))]
532 /* The mips16 assembler handles -32768 correctly, and so does gas,
533 but some other MIPS assemblers think that -32768 needs to be
534 loaded into a register before it can be added in. */
537 && GET_CODE (operands[2]) == CONST_INT
538 && INTVAL (operands[2]) == -32768)
539 operands[2] = force_reg (SImode, operands[2]);
542 (define_insn "addsi3_internal"
543 [(set (match_operand:SI 0 "register_operand" "=d")
544 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
545 (match_operand:SI 2 "arith_operand" "dI")))]
548 || GET_CODE (operands[2]) != CONST_INT
549 || INTVAL (operands[2]) != -32768)"
551 [(set_attr "type" "arith")
552 (set_attr "mode" "SI")])
554 ;; For the mips16, we need to recognize stack pointer additions
555 ;; explicitly, since we don't have a constraint for $sp. These insns
556 ;; will be generated by the save_restore_insns functions.
561 (match_operand:SI 0 "small_int" "I")))]
564 [(set_attr "type" "arith")
565 (set_attr "mode" "SI")
566 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
571 [(set (match_operand:SI 0 "register_operand" "=d")
573 (match_operand:SI 1 "small_int" "I")))]
576 [(set_attr "type" "arith")
577 (set_attr "mode" "SI")
578 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
583 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
584 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
585 (match_operand:SI 2 "arith_operand" "IQ,O,d")))]
587 && (GET_CODE (operands[1]) != REG
588 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
589 || M16_REG_P (REGNO (operands[1]))
590 || REGNO (operands[1]) == ARG_POINTER_REGNUM
591 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
592 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
593 && (GET_CODE (operands[2]) != REG
594 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
595 || M16_REG_P (REGNO (operands[2]))
596 || REGNO (operands[2]) == ARG_POINTER_REGNUM
597 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
598 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
601 if (REGNO (operands[0]) == REGNO (operands[1]))
602 return \"addu\\t%0,%2\";
603 return \"addu\\t%0,%1,%2\";
605 [(set_attr "type" "arith")
606 (set_attr "mode" "SI")
607 (set_attr_alternative "length"
608 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
611 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
617 ;; On the mips16, we can sometimes split an add of a constant which is
618 ;; a 4 byte instruction into two adds which are both 2 byte
619 ;; instructions. There are two cases: one where we are adding a
620 ;; constant plus a register to another register, and one where we are
621 ;; simply adding a constant to a register.
624 [(set (match_operand:SI 0 "register_operand" "")
625 (plus:SI (match_dup 0)
626 (match_operand:SI 1 "const_int_operand" "")))]
627 "TARGET_MIPS16 && reload_completed
628 && GET_CODE (operands[0]) == REG
629 && M16_REG_P (REGNO (operands[0]))
630 && GET_CODE (operands[1]) == CONST_INT
631 && ((INTVAL (operands[1]) > 0x7f
632 && INTVAL (operands[1]) <= 0x7f + 0x7f)
633 || (INTVAL (operands[1]) < - 0x80
634 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
635 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
636 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
639 HOST_WIDE_INT val = INTVAL (operands[1]);
643 operands[1] = GEN_INT (0x7f);
644 operands[2] = GEN_INT (val - 0x7f);
648 operands[1] = GEN_INT (- 0x80);
649 operands[2] = GEN_INT (val + 0x80);
654 [(set (match_operand:SI 0 "register_operand" "")
655 (plus:SI (match_operand:SI 1 "register_operand" "")
656 (match_operand:SI 2 "const_int_operand" "")))]
657 "TARGET_MIPS16 && reload_completed
658 && GET_CODE (operands[0]) == REG
659 && M16_REG_P (REGNO (operands[0]))
660 && GET_CODE (operands[1]) == REG
661 && M16_REG_P (REGNO (operands[1]))
662 && REGNO (operands[0]) != REGNO (operands[1])
663 && GET_CODE (operands[2]) == CONST_INT
664 && ((INTVAL (operands[2]) > 0x7
665 && INTVAL (operands[2]) <= 0x7 + 0x7f)
666 || (INTVAL (operands[2]) < - 0x8
667 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
668 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
669 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
672 HOST_WIDE_INT val = INTVAL (operands[2]);
676 operands[2] = GEN_INT (0x7);
677 operands[3] = GEN_INT (val - 0x7);
681 operands[2] = GEN_INT (- 0x8);
682 operands[3] = GEN_INT (val + 0x8);
686 (define_expand "adddi3"
687 [(parallel [(set (match_operand:DI 0 "register_operand" "")
688 (plus:DI (match_operand:DI 1 "se_register_operand" "")
689 (match_operand:DI 2 "se_arith_operand" "")))
690 (clobber (match_dup 3))])]
691 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
694 /* The mips16 assembler handles -32768 correctly, and so does gas,
695 but some other MIPS assemblers think that -32768 needs to be
696 loaded into a register before it can be added in. */
699 && GET_CODE (operands[2]) == CONST_INT
700 && INTVAL (operands[2]) == -32768)
701 operands[2] = force_reg (DImode, operands[2]);
705 emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
710 operands[3] = gen_reg_rtx (SImode);
713 (define_insn "adddi3_internal_1"
714 [(set (match_operand:DI 0 "register_operand" "=d,&d")
715 (plus:DI (match_operand:DI 1 "register_operand" "0,d")
716 (match_operand:DI 2 "register_operand" "d,d")))
717 (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
718 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
721 return (REGNO (operands[0]) == REGNO (operands[1])
722 && REGNO (operands[0]) == REGNO (operands[2]))
723 ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
724 : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
726 [(set_attr "type" "darith")
727 (set_attr "mode" "DI")
728 (set_attr "length" "16")])
731 [(set (match_operand:DI 0 "register_operand" "")
732 (plus:DI (match_operand:DI 1 "register_operand" "")
733 (match_operand:DI 2 "register_operand" "")))
734 (clobber (match_operand:SI 3 "register_operand" ""))]
735 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
736 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
737 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
738 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
739 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
740 && (REGNO (operands[0]) != REGNO (operands[1])
741 || REGNO (operands[0]) != REGNO (operands[2]))"
743 [(set (subreg:SI (match_dup 0) 0)
744 (plus:SI (subreg:SI (match_dup 1) 0)
745 (subreg:SI (match_dup 2) 0)))
748 (ltu:SI (subreg:SI (match_dup 0) 0)
749 (subreg:SI (match_dup 2) 0)))
751 (set (subreg:SI (match_dup 0) 1)
752 (plus:SI (subreg:SI (match_dup 1) 1)
753 (subreg:SI (match_dup 2) 1)))
755 (set (subreg:SI (match_dup 0) 1)
756 (plus:SI (subreg:SI (match_dup 0) 1)
761 [(set (match_operand:DI 0 "register_operand" "")
762 (plus:DI (match_operand:DI 1 "register_operand" "")
763 (match_operand:DI 2 "register_operand" "")))
764 (clobber (match_operand:SI 3 "register_operand" ""))]
765 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
766 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
767 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
768 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
769 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
770 && (REGNO (operands[0]) != REGNO (operands[1])
771 || REGNO (operands[0]) != REGNO (operands[2]))"
773 [(set (subreg:SI (match_dup 0) 1)
774 (plus:SI (subreg:SI (match_dup 1) 1)
775 (subreg:SI (match_dup 2) 1)))
778 (ltu:SI (subreg:SI (match_dup 0) 1)
779 (subreg:SI (match_dup 2) 1)))
781 (set (subreg:SI (match_dup 0) 0)
782 (plus:SI (subreg:SI (match_dup 1) 0)
783 (subreg:SI (match_dup 2) 0)))
785 (set (subreg:SI (match_dup 0) 0)
786 (plus:SI (subreg:SI (match_dup 0) 0)
790 (define_insn "adddi3_internal_2"
791 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
792 (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
793 (match_operand:DI 2 "small_int" "P,J,N")))
794 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
795 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
797 || GET_CODE (operands[2]) != CONST_INT
798 || INTVAL (operands[2]) != -32768)"
800 addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
801 move\\t%L0,%L1\;move\\t%M0,%M1
802 subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
803 [(set_attr "type" "darith")
804 (set_attr "mode" "DI")
805 (set_attr "length" "12,8,16")])
808 [(set (match_operand:DI 0 "register_operand" "")
809 (plus:DI (match_operand:DI 1 "register_operand" "")
810 (match_operand:DI 2 "small_int" "")))
811 (clobber (match_operand:SI 3 "register_operand" "=d"))]
812 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
813 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
814 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
815 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
816 && INTVAL (operands[2]) > 0"
818 [(set (subreg:SI (match_dup 0) 0)
819 (plus:SI (subreg:SI (match_dup 1) 0)
823 (ltu:SI (subreg:SI (match_dup 0) 0)
826 (set (subreg:SI (match_dup 0) 1)
827 (plus:SI (subreg:SI (match_dup 1) 1)
832 [(set (match_operand:DI 0 "register_operand" "")
833 (plus:DI (match_operand:DI 1 "register_operand" "")
834 (match_operand:DI 2 "small_int" "")))
835 (clobber (match_operand:SI 3 "register_operand" "=d"))]
836 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
837 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
838 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
839 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
840 && INTVAL (operands[2]) > 0"
842 [(set (subreg:SI (match_dup 0) 1)
843 (plus:SI (subreg:SI (match_dup 1) 1)
847 (ltu:SI (subreg:SI (match_dup 0) 1)
850 (set (subreg:SI (match_dup 0) 0)
851 (plus:SI (subreg:SI (match_dup 1) 0)
855 (define_insn "adddi3_internal_3"
856 [(set (match_operand:DI 0 "register_operand" "=d")
857 (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
858 (match_operand:DI 2 "se_arith_operand" "dI")))]
862 || GET_CODE (operands[2]) != CONST_INT
863 || INTVAL (operands[2]) != -32768)"
866 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
867 ? \"dsubu\\t%0,%z1,%n2\"
868 : \"daddu\\t%0,%z1,%2\";
870 [(set_attr "type" "darith")
871 (set_attr "mode" "DI")])
873 ;; For the mips16, we need to recognize stack pointer additions
874 ;; explicitly, since we don't have a constraint for $sp. These insns
875 ;; will be generated by the save_restore_insns functions.
880 (match_operand:DI 0 "small_int" "I")))]
881 "TARGET_MIPS16 && TARGET_64BIT"
883 [(set_attr "type" "arith")
884 (set_attr "mode" "DI")
885 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
890 [(set (match_operand:DI 0 "register_operand" "=d")
892 (match_operand:DI 1 "small_int" "I")))]
893 "TARGET_MIPS16 && TARGET_64BIT"
895 [(set_attr "type" "arith")
896 (set_attr "mode" "DI")
897 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
902 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
903 (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
904 (match_operand:DI 2 "arith_operand" "IQ,O,d")))]
905 "TARGET_MIPS16 && TARGET_64BIT
906 && (GET_CODE (operands[1]) != REG
907 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
908 || M16_REG_P (REGNO (operands[1]))
909 || REGNO (operands[1]) == ARG_POINTER_REGNUM
910 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
911 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
912 && (GET_CODE (operands[2]) != REG
913 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
914 || M16_REG_P (REGNO (operands[2]))
915 || REGNO (operands[2]) == ARG_POINTER_REGNUM
916 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
917 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
920 if (REGNO (operands[0]) == REGNO (operands[1]))
921 return \"daddu\\t%0,%2\";
922 return \"daddu\\t%0,%1,%2\";
924 [(set_attr "type" "arith")
925 (set_attr "mode" "DI")
926 (set_attr_alternative "length"
927 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
930 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
936 ;; On the mips16, we can sometimes split an add of a constant which is
937 ;; a 4 byte instruction into two adds which are both 2 byte
938 ;; instructions. There are two cases: one where we are adding a
939 ;; constant plus a register to another register, and one where we are
940 ;; simply adding a constant to a register.
943 [(set (match_operand:DI 0 "register_operand" "")
944 (plus:DI (match_dup 0)
945 (match_operand:DI 1 "const_int_operand" "")))]
946 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
947 && GET_CODE (operands[0]) == REG
948 && M16_REG_P (REGNO (operands[0]))
949 && GET_CODE (operands[1]) == CONST_INT
950 && ((INTVAL (operands[1]) > 0xf
951 && INTVAL (operands[1]) <= 0xf + 0xf)
952 || (INTVAL (operands[1]) < - 0x10
953 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
954 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
955 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
958 HOST_WIDE_INT val = INTVAL (operands[1]);
962 operands[1] = GEN_INT (0xf);
963 operands[2] = GEN_INT (val - 0xf);
967 operands[1] = GEN_INT (- 0x10);
968 operands[2] = GEN_INT (val + 0x10);
973 [(set (match_operand:DI 0 "register_operand" "")
974 (plus:DI (match_operand:DI 1 "register_operand" "")
975 (match_operand:DI 2 "const_int_operand" "")))]
976 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
977 && GET_CODE (operands[0]) == REG
978 && M16_REG_P (REGNO (operands[0]))
979 && GET_CODE (operands[1]) == REG
980 && M16_REG_P (REGNO (operands[1]))
981 && REGNO (operands[0]) != REGNO (operands[1])
982 && GET_CODE (operands[2]) == CONST_INT
983 && ((INTVAL (operands[2]) > 0x7
984 && INTVAL (operands[2]) <= 0x7 + 0xf)
985 || (INTVAL (operands[2]) < - 0x8
986 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
987 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
988 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
991 HOST_WIDE_INT val = INTVAL (operands[2]);
995 operands[2] = GEN_INT (0x7);
996 operands[3] = GEN_INT (val - 0x7);
1000 operands[2] = GEN_INT (- 0x8);
1001 operands[3] = GEN_INT (val + 0x8);
1005 (define_insn "addsi3_internal_2"
1006 [(set (match_operand:DI 0 "register_operand" "=d")
1007 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1008 (match_operand:SI 2 "arith_operand" "dI"))))]
1012 || GET_CODE (operands[2]) != CONST_INT
1013 || INTVAL (operands[2]) != -32768)"
1016 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1017 ? \"subu\\t%0,%z1,%n2\"
1018 : \"addu\\t%0,%z1,%2\";
1020 [(set_attr "type" "arith")
1021 (set_attr "mode" "SI")])
1024 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1025 (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1026 (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1027 "TARGET_MIPS16 && TARGET_64BIT"
1030 if (REGNO (operands[0]) == REGNO (operands[1]))
1031 return \"addu\\t%0,%2\";
1032 return \"addu\\t%0,%1,%2\";
1034 [(set_attr "type" "arith")
1035 (set_attr "mode" "SI")
1036 (set_attr_alternative "length"
1037 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
1040 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1047 ;; ....................
1051 ;; ....................
1054 (define_insn "subdf3"
1055 [(set (match_operand:DF 0 "register_operand" "=f")
1056 (minus:DF (match_operand:DF 1 "register_operand" "f")
1057 (match_operand:DF 2 "register_operand" "f")))]
1058 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1060 [(set_attr "type" "fadd")
1061 (set_attr "mode" "DF")])
1063 (define_insn "subsf3"
1064 [(set (match_operand:SF 0 "register_operand" "=f")
1065 (minus:SF (match_operand:SF 1 "register_operand" "f")
1066 (match_operand:SF 2 "register_operand" "f")))]
1069 [(set_attr "type" "fadd")
1070 (set_attr "mode" "SF")])
1072 (define_expand "subsi3"
1073 [(set (match_operand:SI 0 "register_operand" "=d")
1074 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1075 (match_operand:SI 2 "arith_operand" "dI")))]
1079 if (GET_CODE (operands[2]) == CONST_INT
1080 && (INTVAL (operands[2]) == -32768
1082 && INTVAL (operands[2]) == -0x4000)))
1083 operands[2] = force_reg (SImode, operands[2]);
1086 (define_insn "subsi3_internal"
1087 [(set (match_operand:SI 0 "register_operand" "=d")
1088 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1089 (match_operand:SI 2 "arith_operand" "dI")))]
1091 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1093 [(set_attr "type" "arith")
1094 (set_attr "mode" "SI")])
1096 ;; For the mips16, we need to recognize stack pointer subtractions
1097 ;; explicitly, since we don't have a constraint for $sp. These insns
1098 ;; will be generated by the save_restore_insns functions.
1102 (minus:SI (reg:SI 29)
1103 (match_operand:SI 0 "small_int" "I")))]
1105 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1107 [(set_attr "type" "arith")
1108 (set_attr "mode" "SI")
1109 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1114 [(set (match_operand:SI 0 "register_operand" "=d")
1115 (minus:SI (reg:SI 29)
1116 (match_operand:SI 1 "small_int" "I")))]
1118 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1120 [(set_attr "type" "arith")
1121 (set_attr "mode" "SI")
1122 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "")
1128 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1129 (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1130 (match_operand:SI 2 "arith_operand" "I,O,d")))]
1132 && (GET_CODE (operands[2]) != CONST_INT
1133 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1136 if (REGNO (operands[0]) == REGNO (operands[1]))
1137 return \"subu\\t%0,%2\";
1138 return \"subu\\t%0,%1,%2\";
1140 [(set_attr "type" "arith")
1141 (set_attr "mode" "SI")
1142 (set_attr_alternative "length"
1143 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1146 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1151 ;; On the mips16, we can sometimes split an subtract of a constant
1152 ;; which is a 4 byte instruction into two adds which are both 2 byte
1153 ;; instructions. There are two cases: one where we are setting a
1154 ;; register to a register minus a constant, and one where we are
1155 ;; simply subtracting a constant from a register.
1158 [(set (match_operand:SI 0 "register_operand" "")
1159 (minus:SI (match_dup 0)
1160 (match_operand:SI 1 "const_int_operand" "")))]
1161 "TARGET_MIPS16 && reload_completed
1162 && GET_CODE (operands[0]) == REG
1163 && M16_REG_P (REGNO (operands[0]))
1164 && GET_CODE (operands[1]) == CONST_INT
1165 && ((INTVAL (operands[1]) > 0x80
1166 && INTVAL (operands[1]) <= 0x80 + 0x80)
1167 || (INTVAL (operands[1]) < - 0x7f
1168 && INTVAL (operands[1]) >= - 0x7f - 0x7f))"
1169 [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1)))
1170 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1173 HOST_WIDE_INT val = INTVAL (operands[1]);
1177 operands[1] = GEN_INT (0x80);
1178 operands[2] = GEN_INT (val - 0x80);
1182 operands[1] = GEN_INT (- 0x7f);
1183 operands[2] = GEN_INT (val + 0x7f);
1188 [(set (match_operand:SI 0 "register_operand" "")
1189 (minus:SI (match_operand:SI 1 "register_operand" "")
1190 (match_operand:SI 2 "const_int_operand" "")))]
1191 "TARGET_MIPS16 && reload_completed
1192 && GET_CODE (operands[0]) == REG
1193 && M16_REG_P (REGNO (operands[0]))
1194 && GET_CODE (operands[1]) == REG
1195 && M16_REG_P (REGNO (operands[1]))
1196 && REGNO (operands[0]) != REGNO (operands[1])
1197 && GET_CODE (operands[2]) == CONST_INT
1198 && ((INTVAL (operands[2]) > 0x8
1199 && INTVAL (operands[2]) <= 0x8 + 0x80)
1200 || (INTVAL (operands[2]) < - 0x7
1201 && INTVAL (operands[2]) >= - 0x7 - 0x7f))"
1202 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1203 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))]
1206 HOST_WIDE_INT val = INTVAL (operands[2]);
1210 operands[2] = GEN_INT (0x8);
1211 operands[3] = GEN_INT (val - 0x8);
1215 operands[2] = GEN_INT (- 0x7);
1216 operands[3] = GEN_INT (val + 0x7);
1220 (define_expand "subdi3"
1221 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1222 (minus:DI (match_operand:DI 1 "se_register_operand" "d")
1223 (match_operand:DI 2 "se_register_operand" "d")))
1224 (clobber (match_dup 3))])]
1225 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
1230 emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1235 operands[3] = gen_reg_rtx (SImode);
1238 (define_insn "subdi3_internal"
1239 [(set (match_operand:DI 0 "register_operand" "=d")
1240 (minus:DI (match_operand:DI 1 "register_operand" "d")
1241 (match_operand:DI 2 "register_operand" "d")))
1242 (clobber (match_operand:SI 3 "register_operand" "=d"))]
1243 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
1244 "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
1245 [(set_attr "type" "darith")
1246 (set_attr "mode" "DI")
1247 (set_attr "length" "16")])
1250 [(set (match_operand:DI 0 "register_operand" "")
1251 (minus:DI (match_operand:DI 1 "register_operand" "")
1252 (match_operand:DI 2 "register_operand" "")))
1253 (clobber (match_operand:SI 3 "register_operand" ""))]
1254 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1255 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1256 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1257 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1258 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1261 (ltu:SI (subreg:SI (match_dup 1) 0)
1262 (subreg:SI (match_dup 2) 0)))
1264 (set (subreg:SI (match_dup 0) 0)
1265 (minus:SI (subreg:SI (match_dup 1) 0)
1266 (subreg:SI (match_dup 2) 0)))
1268 (set (subreg:SI (match_dup 0) 1)
1269 (minus:SI (subreg:SI (match_dup 1) 1)
1270 (subreg:SI (match_dup 2) 1)))
1272 (set (subreg:SI (match_dup 0) 1)
1273 (minus:SI (subreg:SI (match_dup 0) 1)
1278 [(set (match_operand:DI 0 "register_operand" "")
1279 (minus:DI (match_operand:DI 1 "register_operand" "")
1280 (match_operand:DI 2 "register_operand" "")))
1281 (clobber (match_operand:SI 3 "register_operand" ""))]
1282 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1283 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1284 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1285 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1286 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1289 (ltu:SI (subreg:SI (match_dup 1) 1)
1290 (subreg:SI (match_dup 2) 1)))
1292 (set (subreg:SI (match_dup 0) 1)
1293 (minus:SI (subreg:SI (match_dup 1) 1)
1294 (subreg:SI (match_dup 2) 1)))
1296 (set (subreg:SI (match_dup 0) 0)
1297 (minus:SI (subreg:SI (match_dup 1) 0)
1298 (subreg:SI (match_dup 2) 0)))
1300 (set (subreg:SI (match_dup 0) 0)
1301 (minus:SI (subreg:SI (match_dup 0) 0)
1305 (define_insn "subdi3_internal_2"
1306 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1307 (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
1308 (match_operand:DI 2 "small_int" "P,J,N")))
1309 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
1310 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1311 && INTVAL (operands[2]) != -32768"
1313 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
1314 move\\t%L0,%L1\;move\\t%M0,%M1
1315 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
1316 [(set_attr "type" "darith")
1317 (set_attr "mode" "DI")
1318 (set_attr "length" "12,8,16")])
1321 [(set (match_operand:DI 0 "register_operand" "")
1322 (minus:DI (match_operand:DI 1 "register_operand" "")
1323 (match_operand:DI 2 "small_int" "")))
1324 (clobber (match_operand:SI 3 "register_operand" ""))]
1325 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1326 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1327 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1328 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1329 && INTVAL (operands[2]) > 0"
1332 (ltu:SI (subreg:SI (match_dup 1) 0)
1335 (set (subreg:SI (match_dup 0) 0)
1336 (minus:SI (subreg:SI (match_dup 1) 0)
1339 (set (subreg:SI (match_dup 0) 1)
1340 (minus:SI (subreg:SI (match_dup 1) 1)
1345 [(set (match_operand:DI 0 "register_operand" "")
1346 (minus:DI (match_operand:DI 1 "register_operand" "")
1347 (match_operand:DI 2 "small_int" "")))
1348 (clobber (match_operand:SI 3 "register_operand" ""))]
1349 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1350 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1351 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1352 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1353 && INTVAL (operands[2]) > 0"
1356 (ltu:SI (subreg:SI (match_dup 1) 1)
1359 (set (subreg:SI (match_dup 0) 1)
1360 (minus:SI (subreg:SI (match_dup 1) 1)
1363 (set (subreg:SI (match_dup 0) 0)
1364 (minus:SI (subreg:SI (match_dup 1) 0)
1368 (define_insn "subdi3_internal_3"
1369 [(set (match_operand:DI 0 "register_operand" "=d")
1370 (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
1371 (match_operand:DI 2 "se_arith_operand" "dI")))]
1372 "TARGET_64BIT && !TARGET_MIPS16
1373 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1376 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1377 ? \"daddu\\t%0,%z1,%n2\"
1378 : \"dsubu\\t%0,%z1,%2\";
1380 [(set_attr "type" "darith")
1381 (set_attr "mode" "DI")])
1383 ;; For the mips16, we need to recognize stack pointer subtractions
1384 ;; explicitly, since we don't have a constraint for $sp. These insns
1385 ;; will be generated by the save_restore_insns functions.
1389 (minus:DI (reg:DI 29)
1390 (match_operand:DI 0 "small_int" "I")))]
1392 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1394 [(set_attr "type" "arith")
1395 (set_attr "mode" "DI")
1396 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1401 [(set (match_operand:DI 0 "register_operand" "=d")
1402 (minus:DI (reg:DI 29)
1403 (match_operand:DI 1 "small_int" "I")))]
1405 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1407 [(set_attr "type" "arith")
1408 (set_attr "mode" "DI")
1409 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "")
1414 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1415 (minus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1416 (match_operand:DI 2 "arith_operand" "I,O,d")))]
1418 && (GET_CODE (operands[2]) != CONST_INT
1419 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1422 if (REGNO (operands[0]) == REGNO (operands[1]))
1423 return \"dsubu\\t%0,%2\";
1424 return \"dsubu\\t%0,%1,%2\";
1426 [(set_attr "type" "arith")
1427 (set_attr "mode" "DI")
1428 (set_attr_alternative "length"
1429 [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "")
1432 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1437 ;; On the mips16, we can sometimes split an add of a constant which is
1438 ;; a 4 byte instruction into two adds which are both 2 byte
1439 ;; instructions. There are two cases: one where we are adding a
1440 ;; constant plus a register to another register, and one where we are
1441 ;; simply adding a constant to a register.
1444 [(set (match_operand:DI 0 "register_operand" "")
1445 (minus:DI (match_dup 0)
1446 (match_operand:DI 1 "const_int_operand" "")))]
1447 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
1448 && GET_CODE (operands[0]) == REG
1449 && M16_REG_P (REGNO (operands[0]))
1450 && GET_CODE (operands[1]) == CONST_INT
1451 && ((INTVAL (operands[1]) > 0x10
1452 && INTVAL (operands[1]) <= 0x10 + 0x10)
1453 || (INTVAL (operands[1]) < - 0xf
1454 && INTVAL (operands[1]) >= - 0xf - 0xf))"
1455 [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1)))
1456 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
1459 HOST_WIDE_INT val = INTVAL (operands[1]);
1463 operands[1] = GEN_INT (0xf);
1464 operands[2] = GEN_INT (val - 0xf);
1468 operands[1] = GEN_INT (- 0x10);
1469 operands[2] = GEN_INT (val + 0x10);
1474 [(set (match_operand:DI 0 "register_operand" "")
1475 (minus:DI (match_operand:DI 1 "register_operand" "")
1476 (match_operand:DI 2 "const_int_operand" "")))]
1477 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
1478 && GET_CODE (operands[0]) == REG
1479 && M16_REG_P (REGNO (operands[0]))
1480 && GET_CODE (operands[1]) == REG
1481 && M16_REG_P (REGNO (operands[1]))
1482 && REGNO (operands[0]) != REGNO (operands[1])
1483 && GET_CODE (operands[2]) == CONST_INT
1484 && ((INTVAL (operands[2]) > 0x8
1485 && INTVAL (operands[2]) <= 0x8 + 0x10)
1486 || (INTVAL (operands[2]) < - 0x7
1487 && INTVAL (operands[2]) >= - 0x7 - 0xf))"
1488 [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
1489 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))]
1492 HOST_WIDE_INT val = INTVAL (operands[2]);
1496 operands[2] = GEN_INT (0x8);
1497 operands[3] = GEN_INT (val - 0x8);
1501 operands[2] = GEN_INT (- 0x7);
1502 operands[3] = GEN_INT (val + 0x7);
1506 (define_insn "subsi3_internal_2"
1507 [(set (match_operand:DI 0 "register_operand" "=d")
1508 (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1509 (match_operand:SI 2 "arith_operand" "dI"))))]
1510 "TARGET_64BIT && !TARGET_MIPS16
1511 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1514 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1515 ? \"addu\\t%0,%z1,%n2\"
1516 : \"subu\\t%0,%z1,%2\";
1518 [(set_attr "type" "arith")
1519 (set_attr "mode" "DI")])
1522 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1523 (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1524 (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1525 "TARGET_64BIT && TARGET_MIPS16
1526 && (GET_CODE (operands[2]) != CONST_INT
1527 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1530 if (REGNO (operands[0]) == REGNO (operands[1]))
1531 return \"subu\\t%0,%2\";
1532 return \"subu\\t%0,%1,%2\";
1534 [(set_attr "type" "arith")
1535 (set_attr "mode" "SI")
1536 (set_attr_alternative "length"
1537 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1540 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1548 ;; ....................
1552 ;; ....................
1555 ;; Early Vr4300 silicon has a CPU bug where multiplies with certain
1556 ;; operands may corrupt immediately following multiplies. This is a
1557 ;; simple fix to insert NOPs.
1559 (define_expand "muldf3"
1560 [(set (match_operand:DF 0 "register_operand" "=f")
1561 (mult:DF (match_operand:DF 1 "register_operand" "f")
1562 (match_operand:DF 2 "register_operand" "f")))]
1563 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1566 if (mips_cpu != PROCESSOR_R4300)
1567 emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
1569 emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
1573 (define_insn "muldf3_internal"
1574 [(set (match_operand:DF 0 "register_operand" "=f")
1575 (mult:DF (match_operand:DF 1 "register_operand" "f")
1576 (match_operand:DF 2 "register_operand" "f")))]
1577 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu != PROCESSOR_R4300"
1579 [(set_attr "type" "fmul")
1580 (set_attr "mode" "DF")])
1582 (define_insn "muldf3_r4300"
1583 [(set (match_operand:DF 0 "register_operand" "=f")
1584 (mult:DF (match_operand:DF 1 "register_operand" "f")
1585 (match_operand:DF 2 "register_operand" "f")))]
1586 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu == PROCESSOR_R4300"
1589 output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
1590 if (TARGET_4300_MUL_FIX)
1591 output_asm_insn (\"nop\", operands);
1594 [(set_attr "type" "fmul")
1595 (set_attr "mode" "DF")
1596 (set_attr "length" "8")]) ;; mul.d + nop
1598 (define_expand "mulsf3"
1599 [(set (match_operand:SF 0 "register_operand" "=f")
1600 (mult:SF (match_operand:SF 1 "register_operand" "f")
1601 (match_operand:SF 2 "register_operand" "f")))]
1605 if (mips_cpu != PROCESSOR_R4300)
1606 emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
1608 emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
1612 (define_insn "mulsf3_internal"
1613 [(set (match_operand:SF 0 "register_operand" "=f")
1614 (mult:SF (match_operand:SF 1 "register_operand" "f")
1615 (match_operand:SF 2 "register_operand" "f")))]
1616 "TARGET_HARD_FLOAT && mips_cpu != PROCESSOR_R4300"
1618 [(set_attr "type" "fmul")
1619 (set_attr "mode" "SF")])
1621 (define_insn "mulsf3_r4300"
1622 [(set (match_operand:SF 0 "register_operand" "=f")
1623 (mult:SF (match_operand:SF 1 "register_operand" "f")
1624 (match_operand:SF 2 "register_operand" "f")))]
1625 "TARGET_HARD_FLOAT && mips_cpu == PROCESSOR_R4300"
1628 output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1629 if (TARGET_4300_MUL_FIX)
1630 output_asm_insn (\"nop\", operands);
1633 [(set_attr "type" "fmul")
1634 (set_attr "mode" "SF")
1635 (set_attr "length" "8")]) ;; mul.s + nop
1638 ;; ??? The R4000 (only) has a cpu bug. If a double-word shift executes while
1639 ;; a multiply is in progress, it may give an incorrect result. Avoid
1640 ;; this by keeping the mflo with the mult on the R4000.
1642 (define_expand "mulsi3"
1643 [(set (match_operand:SI 0 "register_operand" "=l")
1644 (mult:SI (match_operand:SI 1 "register_operand" "d")
1645 (match_operand:SI 2 "register_operand" "d")))
1646 (clobber (match_scratch:SI 3 "=h"))
1647 (clobber (match_scratch:SI 4 "=a"))]
1651 if (HAVE_mulsi3_mult3)
1652 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1653 else if (mips_cpu != PROCESSOR_R4000 || TARGET_MIPS16)
1654 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1656 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1660 (define_insn "mulsi3_mult3"
1661 [(set (match_operand:SI 0 "register_operand" "=d,l")
1662 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1663 (match_operand:SI 2 "register_operand" "d,d")))
1664 (clobber (match_scratch:SI 3 "=h,h"))
1665 (clobber (match_scratch:SI 4 "=l,X"))
1666 (clobber (match_scratch:SI 5 "=a,a"))]
1671 if (which_alternative == 1)
1672 return \"mult\\t%1,%2\";
1674 return \"mul\\t%0,%1,%2\";
1675 return \"mult\\t%0,%1,%2\";
1677 [(set_attr "type" "imul")
1678 (set_attr "mode" "SI")])
1680 (define_insn "mulsi3_internal"
1681 [(set (match_operand:SI 0 "register_operand" "=l")
1682 (mult:SI (match_operand:SI 1 "register_operand" "d")
1683 (match_operand:SI 2 "register_operand" "d")))
1684 (clobber (match_scratch:SI 3 "=h"))
1685 (clobber (match_scratch:SI 4 "=a"))]
1686 "mips_cpu != PROCESSOR_R4000 || TARGET_MIPS16"
1688 [(set_attr "type" "imul")
1689 (set_attr "mode" "SI")])
1691 (define_insn "mulsi3_r4000"
1692 [(set (match_operand:SI 0 "register_operand" "=d")
1693 (mult:SI (match_operand:SI 1 "register_operand" "d")
1694 (match_operand:SI 2 "register_operand" "d")))
1695 (clobber (match_scratch:SI 3 "=h"))
1696 (clobber (match_scratch:SI 4 "=l"))
1697 (clobber (match_scratch:SI 5 "=a"))]
1698 "mips_cpu == PROCESSOR_R4000 && !TARGET_MIPS16"
1703 xoperands[0] = operands[0];
1704 xoperands[1] = gen_rtx (REG, SImode, LO_REGNUM);
1706 output_asm_insn (\"mult\\t%1,%2\", operands);
1707 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1710 [(set_attr "type" "imul")
1711 (set_attr "mode" "SI")
1712 (set_attr "length" "12")]) ;; mult + mflo + delay
1714 ;; Multiply-accumulate patterns
1716 ;; For processors that can copy the output to a general register:
1718 ;; The all-d alternative is needed because the combiner will find this
1719 ;; pattern and then register alloc/reload will move registers around to
1720 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1722 ;; The last alternative should be made slightly less desirable, but adding
1723 ;; "?" to the constraint is too strong, and causes values to be loaded into
1724 ;; LO even when that's more costly. For now, using "*d" mostly does the
1726 (define_insn "*mul_acc_si"
1727 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1728 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1729 (match_operand:SI 2 "register_operand" "d,d,d"))
1730 (match_operand:SI 3 "register_operand" "0,l,*d")))
1731 (clobber (match_scratch:SI 4 "=h,h,h"))
1732 (clobber (match_scratch:SI 5 "=X,3,l"))
1733 (clobber (match_scratch:SI 6 "=a,a,a"))
1734 (clobber (match_scratch:SI 7 "=X,X,d"))]
1739 static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" };
1740 if (which_alternative == 2)
1742 return madd[which_alternative];
1744 [(set_attr "type" "imul,imul,multi")
1745 (set_attr "mode" "SI")
1746 (set_attr "length" "4,4,8")])
1748 ;; Split the above insn if we failed to get LO allocated.
1750 [(set (match_operand:SI 0 "register_operand" "")
1751 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1752 (match_operand:SI 2 "register_operand" ""))
1753 (match_operand:SI 3 "register_operand" "")))
1754 (clobber (match_scratch:SI 4 ""))
1755 (clobber (match_scratch:SI 5 ""))
1756 (clobber (match_scratch:SI 6 ""))
1757 (clobber (match_scratch:SI 7 ""))]
1758 "reload_completed && GP_REG_P (true_regnum (operands[0])) && GP_REG_P (true_regnum (operands[3]))"
1759 [(parallel [(set (match_dup 7)
1760 (mult:SI (match_dup 1) (match_dup 2)))
1761 (clobber (match_dup 4))
1762 (clobber (match_dup 5))
1763 (clobber (match_dup 6))])
1764 (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 3)))]
1768 [(set (match_operand:SI 0 "register_operand" "")
1769 (minus:SI (match_operand:SI 1 "register_operand" "")
1770 (mult:SI (match_operand:SI 2 "register_operand" "")
1771 (match_operand:SI 3 "register_operand" ""))))
1772 (clobber (match_scratch:SI 4 ""))
1773 (clobber (match_scratch:SI 5 ""))
1774 (clobber (match_scratch:SI 6 ""))
1775 (clobber (match_scratch:SI 7 ""))]
1776 "reload_completed && GP_REG_P (true_regnum (operands[0])) && GP_REG_P (true_regnum (operands[1]))"
1777 [(parallel [(set (match_dup 7)
1778 (mult:SI (match_dup 2) (match_dup 3)))
1779 (clobber (match_dup 4))
1780 (clobber (match_dup 5))
1781 (clobber (match_dup 6))])
1782 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
1785 (define_expand "muldi3"
1786 [(set (match_operand:DI 0 "register_operand" "=l")
1787 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1788 (match_operand:DI 2 "register_operand" "d")))
1789 (clobber (match_scratch:DI 3 "=h"))
1790 (clobber (match_scratch:DI 4 "=a"))]
1795 if (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000 || TARGET_MIPS16)
1796 emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
1798 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1802 ;; Don't accept both operands using se_register_operand, because if
1803 ;; both operands are sign extended we would prefer to use mult in the
1804 ;; mulsidi3 pattern. Commutativity should permit either operand to be
1807 (define_insn "muldi3_internal"
1808 [(set (match_operand:DI 0 "register_operand" "=l")
1809 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1810 (match_operand:DI 2 "register_operand" "d")))
1811 (clobber (match_scratch:DI 3 "=h"))
1812 (clobber (match_scratch:DI 4 "=a"))]
1813 "TARGET_64BIT && mips_cpu != PROCESSOR_R4000 && !TARGET_MIPS16"
1815 [(set_attr "type" "imul")
1816 (set_attr "mode" "DI")])
1818 (define_insn "muldi3_internal2"
1819 [(set (match_operand:DI 0 "register_operand" "=d")
1820 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1821 (match_operand:DI 2 "register_operand" "d")))
1822 (clobber (match_scratch:DI 3 "=h"))
1823 (clobber (match_scratch:DI 4 "=l"))
1824 (clobber (match_scratch:DI 5 "=a"))]
1825 "TARGET_64BIT && (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000 || TARGET_MIPS16)"
1829 output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
1834 xoperands[0] = operands[0];
1835 xoperands[1] = gen_rtx (REG, DImode, LO_REGNUM);
1837 output_asm_insn (\"dmult\\t%1,%2\", operands);
1838 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1842 [(set_attr "type" "imul")
1843 (set_attr "mode" "DI")
1844 (set (attr "length")
1845 (if_then_else (ne (symbol_ref "GENERATE_MULT3") (const_int 0))
1847 (const_int 12)))]) ;; mult + mflo + delay
1849 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1851 (define_expand "mulsidi3"
1852 [(set (match_operand:DI 0 "register_operand" "=x")
1853 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1854 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1858 rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
1860 emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
1863 emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
1868 (define_expand "umulsidi3"
1869 [(set (match_operand:DI 0 "register_operand" "=x")
1870 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1871 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1875 rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
1877 emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
1880 emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
1885 (define_insn "mulsidi3_internal"
1886 [(set (match_operand:DI 0 "register_operand" "=x")
1887 (mult:DI (match_operator:DI 3 "extend_operator"
1888 [(match_operand:SI 1 "register_operand" "d")])
1889 (match_operator:DI 4 "extend_operator"
1890 [(match_operand:SI 2 "register_operand" "d")])))
1891 (clobber (match_scratch:SI 5 "=a"))]
1892 "!TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
1895 if (GET_CODE (operands[3]) == SIGN_EXTEND)
1896 return \"mult\\t%1,%2\";
1897 return \"multu\\t%1,%2\";
1899 [(set_attr "type" "imul")
1900 (set_attr "mode" "SI")])
1902 (define_insn "mulsidi3_64bit"
1903 [(set (match_operand:DI 0 "register_operand" "=a")
1904 (mult:DI (match_operator:DI 3 "extend_operator"
1905 [(match_operand:SI 1 "register_operand" "d")])
1906 (match_operator:DI 4 "extend_operator"
1907 [(match_operand:SI 2 "register_operand" "d")])))
1908 (clobber (match_scratch:DI 5 "=l"))
1909 (clobber (match_scratch:DI 6 "=h"))]
1910 "TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
1913 if (GET_CODE (operands[3]) == SIGN_EXTEND)
1914 return \"mult\\t%1,%2\";
1915 return \"multu\\t%1,%2\";
1917 [(set_attr "type" "imul")
1918 (set_attr "mode" "SI")])
1920 ;; _highpart patterns
1921 (define_expand "smulsi3_highpart"
1922 [(set (match_operand:SI 0 "register_operand" "=h")
1924 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1925 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1930 rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
1931 rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
1932 #ifndef NO_MD_PROTOTYPES
1933 rtx (*genfn) PROTO((rtx, rtx, rtx, rtx, rtx, rtx));
1937 genfn = gen_xmulsi3_highpart_internal;
1938 emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
1943 (define_expand "umulsi3_highpart"
1944 [(set (match_operand:SI 0 "register_operand" "=h")
1946 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1947 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1952 rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
1953 rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
1954 #ifndef NO_MD_PROTOTYPES
1955 rtx (*genfn) PROTO((rtx, rtx, rtx, rtx, rtx, rtx));
1959 genfn = gen_xmulsi3_highpart_internal;
1960 emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
1965 (define_insn "xmulsi3_highpart_internal"
1966 [(set (match_operand:SI 0 "register_operand" "=h")
1968 (match_operator:DI 5 "highpart_shift_operator"
1969 [(mult:DI (match_operator:DI 3 "extend_operator"
1970 [(match_operand:SI 1 "register_operand" "d")])
1971 (match_operator:DI 4 "extend_operator"
1972 [(match_operand:SI 2 "register_operand" "d")]))
1974 (clobber (match_scratch:SI 6 "=l"))
1975 (clobber (match_scratch:SI 7 "=a"))]
1976 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
1979 if (GET_CODE (operands[3]) == SIGN_EXTEND)
1980 return \"mult\\t%1,%2\";
1982 return \"multu\\t%1,%2\";
1984 [(set_attr "type" "imul")
1985 (set_attr "mode" "SI")])
1987 (define_insn "smuldi3_highpart"
1988 [(set (match_operand:DI 0 "register_operand" "=h")
1990 (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
1991 (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
1993 (clobber (match_scratch:DI 3 "=l"))
1994 (clobber (match_scratch:DI 4 "=a"))]
1997 [(set_attr "type" "imul")
1998 (set_attr "mode" "DI")])
2000 (define_insn "umuldi3_highpart"
2001 [(set (match_operand:DI 0 "register_operand" "=h")
2003 (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2004 (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
2006 (clobber (match_scratch:DI 3 "=l"))
2007 (clobber (match_scratch:DI 4 "=a"))]
2010 [(set_attr "type" "imul")
2011 (set_attr "mode" "DI")])
2013 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2014 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
2016 (define_insn "madsi"
2017 [(set (match_operand:SI 0 "register_operand" "+l")
2018 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2019 (match_operand:SI 2 "register_operand" "d"))
2021 (clobber (match_scratch:SI 3 "=h"))
2022 (clobber (match_scratch:SI 4 "=a"))]
2025 [(set_attr "type" "imul")
2026 (set_attr "mode" "SI")])
2028 (define_insn "*mul_acc_di"
2029 [(set (match_operand:DI 0 "register_operand" "+x")
2030 (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2031 [(match_operand:SI 1 "register_operand" "d")])
2032 (match_operator:DI 4 "extend_operator"
2033 [(match_operand:SI 2 "register_operand" "d")]))
2035 (clobber (match_scratch:SI 5 "=a"))]
2038 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2041 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2042 return \"mad\\t%1,%2\";
2044 return \"madu\\t%1,%2\";
2046 [(set_attr "type" "imul")
2047 (set_attr "mode" "SI")])
2049 (define_insn "*mul_acc_64bit_di"
2050 [(set (match_operand:DI 0 "register_operand" "+a")
2051 (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2052 [(match_operand:SI 1 "register_operand" "d")])
2053 (match_operator:DI 4 "extend_operator"
2054 [(match_operand:SI 2 "register_operand" "d")]))
2056 (clobber (match_scratch:SI 5 "=h"))
2057 (clobber (match_scratch:SI 6 "=l"))]
2060 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2063 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2064 return \"mad\\t%1,%2\";
2066 return \"madu\\t%1,%2\";
2068 [(set_attr "type" "imul")
2069 (set_attr "mode" "SI")])
2071 ;; Floating point multiply accumulate instructions.
2074 [(set (match_operand:DF 0 "register_operand" "=f")
2075 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2076 (match_operand:DF 2 "register_operand" "f"))
2077 (match_operand:DF 3 "register_operand" "f")))]
2078 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2079 "madd.d\\t%0,%3,%1,%2"
2080 [(set_attr "type" "fmadd")
2081 (set_attr "mode" "DF")])
2084 [(set (match_operand:SF 0 "register_operand" "=f")
2085 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2086 (match_operand:SF 2 "register_operand" "f"))
2087 (match_operand:SF 3 "register_operand" "f")))]
2088 "mips_isa >= 4 && TARGET_HARD_FLOAT"
2089 "madd.s\\t%0,%3,%1,%2"
2090 [(set_attr "type" "fmadd")
2091 (set_attr "mode" "SF")])
2094 [(set (match_operand:DF 0 "register_operand" "=f")
2095 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2096 (match_operand:DF 2 "register_operand" "f"))
2097 (match_operand:DF 3 "register_operand" "f")))]
2098 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2099 "msub.d\\t%0,%3,%1,%2"
2100 [(set_attr "type" "fmadd")
2101 (set_attr "mode" "DF")])
2104 [(set (match_operand:SF 0 "register_operand" "=f")
2105 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2106 (match_operand:SF 2 "register_operand" "f"))
2107 (match_operand:SF 3 "register_operand" "f")))]
2109 "mips_isa >= 4 && TARGET_HARD_FLOAT"
2110 "msub.s\\t%0,%3,%1,%2"
2111 [(set_attr "type" "fmadd")
2112 (set_attr "mode" "SF")])
2115 [(set (match_operand:DF 0 "register_operand" "=f")
2116 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2117 (match_operand:DF 2 "register_operand" "f"))
2118 (match_operand:DF 3 "register_operand" "f"))))]
2119 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2120 "nmadd.d\\t%0,%3,%1,%2"
2121 [(set_attr "type" "fmadd")
2122 (set_attr "mode" "DF")])
2125 [(set (match_operand:SF 0 "register_operand" "=f")
2126 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2127 (match_operand:SF 2 "register_operand" "f"))
2128 (match_operand:SF 3 "register_operand" "f"))))]
2129 "mips_isa >= 4 && TARGET_HARD_FLOAT"
2130 "nmadd.s\\t%0,%3,%1,%2"
2131 [(set_attr "type" "fmadd")
2132 (set_attr "mode" "SF")])
2135 [(set (match_operand:DF 0 "register_operand" "=f")
2136 (minus:DF (match_operand:DF 1 "register_operand" "f")
2137 (mult:DF (match_operand:DF 2 "register_operand" "f")
2138 (match_operand:DF 3 "register_operand" "f"))))]
2139 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2140 "nmsub.d\\t%0,%1,%2,%3"
2141 [(set_attr "type" "fmadd")
2142 (set_attr "mode" "DF")])
2145 [(set (match_operand:SF 0 "register_operand" "=f")
2146 (minus:SF (match_operand:SF 1 "register_operand" "f")
2147 (mult:SF (match_operand:SF 2 "register_operand" "f")
2148 (match_operand:SF 3 "register_operand" "f"))))]
2149 "mips_isa >= 4 && TARGET_HARD_FLOAT"
2150 "nmsub.s\\t%0,%1,%2,%3"
2151 [(set_attr "type" "fmadd")
2152 (set_attr "mode" "SF")])
2155 ;; ....................
2157 ;; DIVISION and REMAINDER
2159 ;; ....................
2162 (define_insn "divdf3"
2163 [(set (match_operand:DF 0 "register_operand" "=f")
2164 (div:DF (match_operand:DF 1 "register_operand" "f")
2165 (match_operand:DF 2 "register_operand" "f")))]
2166 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2168 [(set_attr "type" "fdiv")
2169 (set_attr "mode" "DF")])
2171 (define_insn "divsf3"
2172 [(set (match_operand:SF 0 "register_operand" "=f")
2173 (div:SF (match_operand:SF 1 "register_operand" "f")
2174 (match_operand:SF 2 "register_operand" "f")))]
2177 [(set_attr "type" "fdiv")
2178 (set_attr "mode" "SF")])
2181 [(set (match_operand:DF 0 "register_operand" "=f")
2182 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2183 (match_operand:DF 2 "register_operand" "f")))]
2184 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
2186 [(set_attr "type" "fdiv")
2187 (set_attr "mode" "DF")])
2190 [(set (match_operand:SF 0 "register_operand" "=f")
2191 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2192 (match_operand:SF 2 "register_operand" "f")))]
2193 "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
2195 [(set_attr "type" "fdiv")
2196 (set_attr "mode" "SF")])
2198 ;; If optimizing, prefer the divmod functions over separate div and
2199 ;; mod functions, since this will allow using one instruction for both
2200 ;; the quotient and remainder. At present, the divmod is not moved out
2201 ;; of loops if it is constant within the loop, so allow -mdebugc to
2202 ;; use the old method of doing things.
2204 ;; 64 is the multiply/divide hi register
2205 ;; 65 is the multiply/divide lo register
2207 ;; ??? We can't accept constants here, because the MIPS assembler will replace
2208 ;; a divide by power of 2 with a shift, and then the remainder is no longer
2211 (define_expand "divmodsi4"
2212 [(set (match_operand:SI 0 "register_operand" "=d")
2213 (div:SI (match_operand:SI 1 "register_operand" "d")
2214 (match_operand:SI 2 "register_operand" "d")))
2215 (set (match_operand:SI 3 "register_operand" "=d")
2216 (mod:SI (match_dup 1)
2218 (clobber (match_scratch:SI 4 "=l"))
2219 (clobber (match_scratch:SI 5 "=h"))
2220 (clobber (match_scratch:SI 6 "=a"))]
2224 emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2],
2226 if (!TARGET_NO_CHECK_ZERO_DIV)
2228 emit_insn (gen_div_trap (operands[2],
2232 if (TARGET_CHECK_RANGE_DIV)
2234 emit_insn (gen_div_trap (operands[2],
2235 copy_to_mode_reg (SImode, GEN_INT (-1)),
2237 emit_insn (gen_div_trap (operands[2],
2238 copy_to_mode_reg (SImode, GEN_INT (0x80000000)),
2245 (define_insn "divmodsi4_internal"
2246 [(set (match_operand:SI 0 "register_operand" "=l")
2247 (div:SI (match_operand:SI 1 "register_operand" "d")
2248 (match_operand:SI 2 "register_operand" "d")))
2249 (set (match_operand:SI 3 "register_operand" "=h")
2250 (mod:SI (match_dup 1)
2252 (clobber (match_scratch:SI 6 "=a"))]
2255 [(set_attr "type" "idiv")
2256 (set_attr "mode" "SI")])
2258 (define_expand "divmoddi4"
2259 [(set (match_operand:DI 0 "register_operand" "=d")
2260 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2261 (match_operand:DI 2 "se_register_operand" "d")))
2262 (set (match_operand:DI 3 "register_operand" "=d")
2263 (mod:DI (match_dup 1)
2265 (clobber (match_scratch:DI 4 "=l"))
2266 (clobber (match_scratch:DI 5 "=h"))
2267 (clobber (match_scratch:DI 6 "=a"))]
2268 "TARGET_64BIT && optimize"
2271 emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2],
2273 if (!TARGET_NO_CHECK_ZERO_DIV)
2275 emit_insn (gen_div_trap (operands[2],
2279 if (TARGET_CHECK_RANGE_DIV)
2281 emit_insn (gen_div_trap (operands[2],
2282 copy_to_mode_reg (DImode, GEN_INT (-1)),
2284 emit_insn (gen_div_trap (operands[2],
2285 copy_to_mode_reg (DImode, GEN_INT (0x80000000)),
2292 (define_insn "divmoddi4_internal"
2293 [(set (match_operand:DI 0 "register_operand" "=l")
2294 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2295 (match_operand:DI 2 "se_register_operand" "d")))
2296 (set (match_operand:DI 3 "register_operand" "=h")
2297 (mod:DI (match_dup 1)
2299 (clobber (match_scratch:DI 6 "=a"))]
2300 "TARGET_64BIT && optimize"
2302 [(set_attr "type" "idiv")
2303 (set_attr "mode" "SI")])
2305 (define_expand "udivmodsi4"
2306 [(set (match_operand:SI 0 "register_operand" "=d")
2307 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2308 (match_operand:SI 2 "register_operand" "d")))
2309 (set (match_operand:SI 3 "register_operand" "=d")
2310 (umod:SI (match_dup 1)
2312 (clobber (match_scratch:SI 4 "=l"))
2313 (clobber (match_scratch:SI 5 "=h"))
2314 (clobber (match_scratch:SI 6 "=a"))]
2318 emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2],
2320 if (!TARGET_NO_CHECK_ZERO_DIV)
2322 emit_insn (gen_div_trap (operands[2],
2330 (define_insn "udivmodsi4_internal"
2331 [(set (match_operand:SI 0 "register_operand" "=l")
2332 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2333 (match_operand:SI 2 "register_operand" "d")))
2334 (set (match_operand:SI 3 "register_operand" "=h")
2335 (umod:SI (match_dup 1)
2337 (clobber (match_scratch:SI 6 "=a"))]
2340 [(set_attr "type" "idiv")
2341 (set_attr "mode" "SI")])
2343 (define_expand "udivmoddi4"
2344 [(set (match_operand:DI 0 "register_operand" "=d")
2345 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2346 (match_operand:DI 2 "se_register_operand" "d")))
2347 (set (match_operand:DI 3 "register_operand" "=d")
2348 (umod:DI (match_dup 1)
2350 (clobber (match_scratch:DI 4 "=l"))
2351 (clobber (match_scratch:DI 5 "=h"))
2352 (clobber (match_scratch:DI 6 "=a"))]
2353 "TARGET_64BIT && optimize"
2356 emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2],
2358 if (!TARGET_NO_CHECK_ZERO_DIV)
2360 emit_insn (gen_div_trap (operands[2],
2368 (define_insn "udivmoddi4_internal"
2369 [(set (match_operand:DI 0 "register_operand" "=l")
2370 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2371 (match_operand:DI 2 "se_register_operand" "d")))
2372 (set (match_operand:DI 3 "register_operand" "=h")
2373 (umod:DI (match_dup 1)
2375 (clobber (match_scratch:DI 6 "=a"))]
2376 "TARGET_64BIT && optimize"
2378 [(set_attr "type" "idiv")
2379 (set_attr "mode" "SI")])
2383 (define_expand "div_trap"
2384 [(trap_if (eq (match_operand 0 "register_operand" "d")
2385 (match_operand 1 "true_reg_or_0_operand" "dJ"))
2386 (match_operand 2 "immediate_operand" ""))]
2391 emit_insn (gen_div_trap_mips16 (operands[0],operands[1],operands[2]));
2393 emit_insn (gen_div_trap_normal (operands[0],operands[1],operands[2]));
2397 (define_insn "div_trap_normal"
2398 [(trap_if (eq (match_operand 0 "register_operand" "d")
2399 (match_operand 1 "true_reg_or_0_operand" "dJ"))
2400 (match_operand 2 "immediate_operand" ""))]
2405 int have_dep_anti = 0;
2407 /* For divmod if one division is not needed then we don't need an extra
2408 divide by zero trap, which is anti dependent on previous trap */
2409 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2411 if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2412 && GET_CODE (XEXP (link, 0)) == INSN
2413 && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2414 && REGNO (operands[1]) == 0)
2416 if (! have_dep_anti)
2418 if (GENERATE_BRANCHLIKELY)
2420 if (GET_CODE (operands[1]) == CONST_INT)
2421 return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2423 return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2427 if (GET_CODE (operands[1]) == CONST_INT)
2428 return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2430 return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2435 [(set_attr "type" "unknown")
2436 (set_attr "length" "12")])
2439 ;; The mips16 bne insns is a macro which uses reg 24 as an intermediate.
2441 (define_insn "div_trap_mips16"
2442 [(trap_if (eq (match_operand 0 "register_operand" "d")
2443 (match_operand 1 "true_reg_or_0_operand" "dJ"))
2444 (match_operand 2 "immediate_operand" ""))
2445 (clobber (reg:SI 24))]
2450 int have_dep_anti = 0;
2452 /* For divmod if one division is not needed then we don't need an extra
2453 divide by zero trap, which is anti dependent on previous trap */
2454 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2456 if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2457 && GET_CODE (XEXP (link, 0)) == INSN
2458 && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2459 && REGNO (operands[1]) == 0)
2461 if (! have_dep_anti)
2463 /* No branch delay slots on mips16. */
2464 if (GET_CODE (operands[1]) == CONST_INT)
2465 return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2467 return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2471 [(set_attr "type" "unknown")
2472 (set_attr "length" "12")])
2474 (define_expand "divsi3"
2475 [(set (match_operand:SI 0 "register_operand" "=l")
2476 (div:SI (match_operand:SI 1 "register_operand" "d")
2477 (match_operand:SI 2 "register_operand" "d")))
2478 (clobber (match_scratch:SI 3 "=h"))
2479 (clobber (match_scratch:SI 4 "=a"))]
2483 emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2]));
2484 if (!TARGET_NO_CHECK_ZERO_DIV)
2486 emit_insn (gen_div_trap (operands[2],
2490 if (TARGET_CHECK_RANGE_DIV)
2492 emit_insn (gen_div_trap (operands[2],
2493 copy_to_mode_reg (SImode, GEN_INT (-1)),
2495 emit_insn (gen_div_trap (operands[2],
2496 copy_to_mode_reg (SImode, GEN_INT (0x80000000)),
2503 (define_insn "divsi3_internal"
2504 [(set (match_operand:SI 0 "register_operand" "=l")
2505 (div:SI (match_operand:SI 1 "register_operand" "d")
2506 (match_operand:SI 2 "nonmemory_operand" "di")))
2507 (clobber (match_scratch:SI 3 "=h"))
2508 (clobber (match_scratch:SI 4 "=a"))]
2511 [(set_attr "type" "idiv")
2512 (set_attr "mode" "SI")])
2514 (define_expand "divdi3"
2515 [(set (match_operand:DI 0 "register_operand" "=l")
2516 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2517 (match_operand:DI 2 "se_register_operand" "d")))
2518 (clobber (match_scratch:DI 3 "=h"))
2519 (clobber (match_scratch:DI 4 "=a"))]
2520 "TARGET_64BIT && !optimize"
2523 emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2]));
2524 if (!TARGET_NO_CHECK_ZERO_DIV)
2526 emit_insn (gen_div_trap (operands[2],
2530 if (TARGET_CHECK_RANGE_DIV)
2532 emit_insn (gen_div_trap (operands[2],
2533 copy_to_mode_reg (DImode, GEN_INT (-1)),
2535 emit_insn (gen_div_trap (operands[2],
2536 copy_to_mode_reg (DImode, GEN_INT (0x80000000)),
2543 (define_insn "divdi3_internal"
2544 [(set (match_operand:DI 0 "register_operand" "=l")
2545 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2546 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2547 (clobber (match_scratch:SI 3 "=h"))
2548 (clobber (match_scratch:SI 4 "=a"))]
2549 "TARGET_64BIT && !optimize"
2551 [(set_attr "type" "idiv")
2552 (set_attr "mode" "DI")])
2554 (define_expand "modsi3"
2555 [(set (match_operand:SI 0 "register_operand" "=h")
2556 (mod:SI (match_operand:SI 1 "register_operand" "d")
2557 (match_operand:SI 2 "register_operand" "d")))
2558 (clobber (match_scratch:SI 3 "=l"))
2559 (clobber (match_scratch:SI 4 "=a"))]
2563 emit_insn (gen_modsi3_internal (operands[0], operands[1], operands[2]));
2564 if (!TARGET_NO_CHECK_ZERO_DIV)
2566 emit_insn (gen_div_trap (operands[2],
2570 if (TARGET_CHECK_RANGE_DIV)
2572 emit_insn (gen_div_trap (operands[2],
2573 copy_to_mode_reg (SImode, GEN_INT (-1)),
2575 emit_insn (gen_div_trap (operands[2],
2576 copy_to_mode_reg (SImode, GEN_INT (0x80000000)),
2583 (define_insn "modsi3_internal"
2584 [(set (match_operand:SI 0 "register_operand" "=h")
2585 (mod:SI (match_operand:SI 1 "register_operand" "d")
2586 (match_operand:SI 2 "nonmemory_operand" "di")))
2587 (clobber (match_scratch:SI 3 "=l"))
2588 (clobber (match_scratch:SI 4 "=a"))]
2591 [(set_attr "type" "idiv")
2592 (set_attr "mode" "SI")])
2594 (define_expand "moddi3"
2595 [(set (match_operand:DI 0 "register_operand" "=h")
2596 (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2597 (match_operand:DI 2 "se_register_operand" "d")))
2598 (clobber (match_scratch:DI 3 "=l"))
2599 (clobber (match_scratch:DI 4 "=a"))]
2600 "TARGET_64BIT && !optimize"
2603 emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2]));
2604 if (!TARGET_NO_CHECK_ZERO_DIV)
2606 emit_insn (gen_div_trap (operands[2],
2610 if (TARGET_CHECK_RANGE_DIV)
2612 emit_insn (gen_div_trap (operands[2],
2613 copy_to_mode_reg (DImode, GEN_INT (-1)),
2615 emit_insn (gen_div_trap (operands[2],
2616 copy_to_mode_reg (DImode, GEN_INT (0x80000000)),
2623 (define_insn "moddi3_internal"
2624 [(set (match_operand:DI 0 "register_operand" "=h")
2625 (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2626 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2627 (clobber (match_scratch:SI 3 "=l"))
2628 (clobber (match_scratch:SI 4 "=a"))]
2629 "TARGET_64BIT && !optimize"
2631 [(set_attr "type" "idiv")
2632 (set_attr "mode" "DI")])
2634 (define_expand "udivsi3"
2635 [(set (match_operand:SI 0 "register_operand" "=l")
2636 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2637 (match_operand:SI 2 "register_operand" "d")))
2638 (clobber (match_scratch:SI 3 "=h"))
2639 (clobber (match_scratch:SI 4 "=a"))]
2643 emit_insn (gen_udivsi3_internal (operands[0], operands[1], operands[2]));
2644 if (!TARGET_NO_CHECK_ZERO_DIV)
2646 emit_insn (gen_div_trap (operands[2],
2654 (define_insn "udivsi3_internal"
2655 [(set (match_operand:SI 0 "register_operand" "=l")
2656 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2657 (match_operand:SI 2 "nonmemory_operand" "di")))
2658 (clobber (match_scratch:SI 3 "=h"))
2659 (clobber (match_scratch:SI 4 "=a"))]
2662 [(set_attr "type" "idiv")
2663 (set_attr "mode" "SI")])
2665 (define_expand "udivdi3"
2666 [(set (match_operand:DI 0 "register_operand" "=l")
2667 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2668 (match_operand:DI 2 "se_register_operand" "di")))
2669 (clobber (match_scratch:DI 3 "=h"))
2670 (clobber (match_scratch:DI 4 "=a"))]
2671 "TARGET_64BIT && !optimize"
2674 emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2]));
2675 if (!TARGET_NO_CHECK_ZERO_DIV)
2677 emit_insn (gen_div_trap (operands[2],
2685 (define_insn "udivdi3_internal"
2686 [(set (match_operand:DI 0 "register_operand" "=l")
2687 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2688 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2689 (clobber (match_scratch:SI 3 "=h"))
2690 (clobber (match_scratch:SI 4 "=a"))]
2691 "TARGET_64BIT && !optimize"
2693 [(set_attr "type" "idiv")
2694 (set_attr "mode" "DI")])
2696 (define_expand "umodsi3"
2697 [(set (match_operand:SI 0 "register_operand" "=h")
2698 (umod:SI (match_operand:SI 1 "register_operand" "d")
2699 (match_operand:SI 2 "register_operand" "d")))
2700 (clobber (match_scratch:SI 3 "=l"))
2701 (clobber (match_scratch:SI 4 "=a"))]
2705 emit_insn (gen_umodsi3_internal (operands[0], operands[1], operands[2]));
2706 if (!TARGET_NO_CHECK_ZERO_DIV)
2708 emit_insn (gen_div_trap (operands[2],
2716 (define_insn "umodsi3_internal"
2717 [(set (match_operand:SI 0 "register_operand" "=h")
2718 (umod:SI (match_operand:SI 1 "register_operand" "d")
2719 (match_operand:SI 2 "nonmemory_operand" "di")))
2720 (clobber (match_scratch:SI 3 "=l"))
2721 (clobber (match_scratch:SI 4 "=a"))]
2724 [(set_attr "type" "idiv")
2725 (set_attr "mode" "SI")])
2727 (define_expand "umoddi3"
2728 [(set (match_operand:DI 0 "register_operand" "=h")
2729 (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2730 (match_operand:DI 2 "se_register_operand" "di")))
2731 (clobber (match_scratch:DI 3 "=l"))
2732 (clobber (match_scratch:DI 4 "=a"))]
2733 "TARGET_64BIT && !optimize"
2736 emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2]));
2737 if (!TARGET_NO_CHECK_ZERO_DIV)
2739 emit_insn (gen_div_trap (operands[2],
2747 (define_insn "umoddi3_internal"
2748 [(set (match_operand:DI 0 "register_operand" "=h")
2749 (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2750 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2751 (clobber (match_scratch:SI 3 "=l"))
2752 (clobber (match_scratch:SI 4 "=a"))]
2753 "TARGET_64BIT && !optimize"
2755 [(set_attr "type" "idiv")
2756 (set_attr "mode" "DI")])
2759 ;; ....................
2763 ;; ....................
2765 (define_insn "sqrtdf2"
2766 [(set (match_operand:DF 0 "register_operand" "=f")
2767 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2768 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2770 [(set_attr "type" "fsqrt")
2771 (set_attr "mode" "DF")])
2773 (define_insn "sqrtsf2"
2774 [(set (match_operand:SF 0 "register_operand" "=f")
2775 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2776 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2778 [(set_attr "type" "fsqrt")
2779 (set_attr "mode" "SF")])
2782 [(set (match_operand:DF 0 "register_operand" "=f")
2783 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2784 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2785 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
2787 [(set_attr "type" "fsqrt")
2788 (set_attr "mode" "DF")])
2791 [(set (match_operand:SF 0 "register_operand" "=f")
2792 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2793 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2794 "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
2796 [(set_attr "type" "fsqrt")
2797 (set_attr "mode" "SF")])
2801 ;; ....................
2805 ;; ....................
2807 ;; Do not use the integer abs macro instruction, since that signals an
2808 ;; exception on -2147483648 (sigh).
2810 (define_insn "abssi2"
2811 [(set (match_operand:SI 0 "register_operand" "=d")
2812 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2816 dslots_jump_total++;
2817 dslots_jump_filled++;
2818 operands[2] = const0_rtx;
2820 if (REGNO (operands[0]) == REGNO (operands[1]))
2822 if (GENERATE_BRANCHLIKELY)
2823 return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
2825 return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n%~1:\";
2828 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
2830 [(set_attr "type" "multi")
2831 (set_attr "mode" "SI")
2832 (set_attr "length" "12")])
2834 (define_insn "absdi2"
2835 [(set (match_operand:DI 0 "register_operand" "=d")
2836 (abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
2837 "TARGET_64BIT && !TARGET_MIPS16"
2840 dslots_jump_total++;
2841 dslots_jump_filled++;
2842 operands[2] = const0_rtx;
2844 if (REGNO (operands[0]) == REGNO (operands[1]))
2845 return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
2847 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
2849 [(set_attr "type" "multi")
2850 (set_attr "mode" "DI")
2851 (set_attr "length" "12")])
2853 (define_insn "absdf2"
2854 [(set (match_operand:DF 0 "register_operand" "=f")
2855 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2856 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2858 [(set_attr "type" "fabs")
2859 (set_attr "mode" "DF")])
2861 (define_insn "abssf2"
2862 [(set (match_operand:SF 0 "register_operand" "=f")
2863 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2866 [(set_attr "type" "fabs")
2867 (set_attr "mode" "SF")])
2871 ;; ....................
2873 ;; FIND FIRST BIT INSTRUCTION
2875 ;; ....................
2878 (define_insn "ffssi2"
2879 [(set (match_operand:SI 0 "register_operand" "=&d")
2880 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2881 (clobber (match_scratch:SI 2 "=&d"))
2882 (clobber (match_scratch:SI 3 "=&d"))]
2886 dslots_jump_total += 2;
2887 dslots_jump_filled += 2;
2888 operands[4] = const0_rtx;
2890 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2893 \\tbeq\\t%1,%z4,2f\\n\\
2894 %~1:\\tand\\t%2,%1,0x0001\\n\\
2895 \\taddu\\t%0,%0,1\\n\\
2896 \\tbeq\\t%2,%z4,1b\\n\\
2897 \\tsrl\\t%1,%1,1\\n\\
2902 \\tmove\\t%3,%1\\n\\
2903 \\tbeq\\t%3,%z4,2f\\n\\
2904 %~1:\\tand\\t%2,%3,0x0001\\n\\
2905 \\taddu\\t%0,%0,1\\n\\
2906 \\tbeq\\t%2,%z4,1b\\n\\
2907 \\tsrl\\t%3,%3,1\\n\\
2910 [(set_attr "type" "multi")
2911 (set_attr "mode" "SI")
2912 (set_attr "length" "12")])
2914 (define_insn "ffsdi2"
2915 [(set (match_operand:DI 0 "register_operand" "=&d")
2916 (ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
2917 (clobber (match_scratch:DI 2 "=&d"))
2918 (clobber (match_scratch:DI 3 "=&d"))]
2919 "TARGET_64BIT && !TARGET_MIPS16"
2922 dslots_jump_total += 2;
2923 dslots_jump_filled += 2;
2924 operands[4] = const0_rtx;
2926 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2929 \\tbeq\\t%1,%z4,2f\\n\\
2930 %~1:\\tand\\t%2,%1,0x0001\\n\\
2931 \\tdaddu\\t%0,%0,1\\n\\
2932 \\tbeq\\t%2,%z4,1b\\n\\
2933 \\tdsrl\\t%1,%1,1\\n\\
2938 \\tmove\\t%3,%1\\n\\
2939 \\tbeq\\t%3,%z4,2f\\n\\
2940 %~1:\\tand\\t%2,%3,0x0001\\n\\
2941 \\tdaddu\\t%0,%0,1\\n\\
2942 \\tbeq\\t%2,%z4,1b\\n\\
2943 \\tdsrl\\t%3,%3,1\\n\\
2946 [(set_attr "type" "multi")
2947 (set_attr "mode" "DI")
2948 (set_attr "length" "24")])
2952 ;; ....................
2954 ;; NEGATION and ONE'S COMPLEMENT
2956 ;; ....................
2958 (define_insn "negsi2"
2959 [(set (match_operand:SI 0 "register_operand" "=d")
2960 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2965 return \"neg\\t%0,%1\";
2966 operands[2] = const0_rtx;
2967 return \"subu\\t%0,%z2,%1\";
2969 [(set_attr "type" "arith")
2970 (set_attr "mode" "SI")])
2972 (define_expand "negdi2"
2973 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
2974 (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
2975 (clobber (match_dup 2))])]
2976 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
2981 emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
2985 operands[2] = gen_reg_rtx (SImode);
2988 (define_insn "negdi2_internal"
2989 [(set (match_operand:DI 0 "register_operand" "=d")
2990 (neg:DI (match_operand:DI 1 "register_operand" "d")))
2991 (clobber (match_operand:SI 2 "register_operand" "=d"))]
2992 "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
2995 operands[3] = const0_rtx;
2996 return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
2998 [(set_attr "type" "darith")
2999 (set_attr "mode" "DI")
3000 (set_attr "length" "16")])
3002 (define_insn "negdi2_internal_2"
3003 [(set (match_operand:DI 0 "register_operand" "=d")
3004 (neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
3005 "TARGET_64BIT && !TARGET_MIPS16"
3008 operands[2] = const0_rtx;
3009 return \"dsubu\\t%0,%z2,%1\";
3011 [(set_attr "type" "arith")
3012 (set_attr "mode" "DI")])
3014 (define_insn "negdf2"
3015 [(set (match_operand:DF 0 "register_operand" "=f")
3016 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
3017 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3019 [(set_attr "type" "fneg")
3020 (set_attr "mode" "DF")])
3022 (define_insn "negsf2"
3023 [(set (match_operand:SF 0 "register_operand" "=f")
3024 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3027 [(set_attr "type" "fneg")
3028 (set_attr "mode" "SF")])
3030 (define_insn "one_cmplsi2"
3031 [(set (match_operand:SI 0 "register_operand" "=d")
3032 (not:SI (match_operand:SI 1 "register_operand" "d")))]
3037 return \"not\\t%0,%1\";
3038 operands[2] = const0_rtx;
3039 return \"nor\\t%0,%z2,%1\";
3041 [(set_attr "type" "arith")
3042 (set_attr "mode" "SI")])
3044 (define_insn "one_cmpldi2"
3045 [(set (match_operand:DI 0 "register_operand" "=d")
3046 (not:DI (match_operand:DI 1 "se_register_operand" "d")))]
3053 return \"not\\t%0,%1\";
3054 return \"not\\t%M0,%M1\;not\\t%L0,%L1\";
3056 operands[2] = const0_rtx;
3058 return \"nor\\t%0,%z2,%1\";
3059 return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
3061 [(set_attr "type" "darith")
3062 (set_attr "mode" "DI")
3063 (set (attr "length")
3064 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3069 [(set (match_operand:DI 0 "register_operand" "")
3070 (not:DI (match_operand:DI 1 "register_operand" "")))]
3071 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3072 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3073 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3075 [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
3076 (set (subreg:SI (match_dup 0) 1) (not:SI (subreg:SI (match_dup 1) 1)))]
3081 ;; ....................
3085 ;; ....................
3088 ;; Many of these instructions uses trivial define_expands, because we
3089 ;; want to use a different set of constraints when TARGET_MIPS16.
3091 (define_expand "andsi3"
3092 [(set (match_operand:SI 0 "register_operand" "=d,d")
3093 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3094 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3099 operands[2] = force_reg (SImode, operands[2]);
3103 [(set (match_operand:SI 0 "register_operand" "=d,d")
3104 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3105 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3110 [(set_attr "type" "arith")
3111 (set_attr "mode" "SI")])
3114 [(set (match_operand:SI 0 "register_operand" "=d")
3115 (and:SI (match_operand:SI 1 "register_operand" "%0")
3116 (match_operand:SI 2 "register_operand" "d")))]
3119 [(set_attr "type" "arith")
3120 (set_attr "mode" "SI")])
3122 (define_expand "anddi3"
3123 [(set (match_operand:DI 0 "register_operand" "=d")
3124 (and:DI (match_operand:DI 1 "se_register_operand" "d")
3125 (match_operand:DI 2 "se_register_operand" "d")))]
3126 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3130 operands[2] = force_reg (DImode, operands[2]);
3134 [(set (match_operand:DI 0 "register_operand" "=d")
3135 (and:DI (match_operand:DI 1 "se_register_operand" "d")
3136 (match_operand:DI 2 "se_register_operand" "d")))]
3137 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3141 return \"and\\t%0,%1,%2\";
3142 return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
3144 [(set_attr "type" "darith")
3145 (set_attr "mode" "DI")
3146 (set (attr "length")
3147 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3152 [(set (match_operand:DI 0 "register_operand" "=d")
3153 (and:DI (match_operand:DI 1 "se_register_operand" "0")
3154 (match_operand:DI 2 "se_register_operand" "d")))]
3155 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3159 return \"and\\t%0,%2\";
3160 return \"and\\t%M0,%M2\;and\\t%L0,%L2\";
3162 [(set_attr "type" "darith")
3163 (set_attr "mode" "DI")
3164 (set (attr "length")
3165 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3170 [(set (match_operand:DI 0 "register_operand" "")
3171 (and:DI (match_operand:DI 1 "register_operand" "")
3172 (match_operand:DI 2 "register_operand" "")))]
3173 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3174 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3175 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3176 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3178 [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3179 (set (subreg:SI (match_dup 0) 1) (and:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
3182 (define_insn "anddi3_internal1"
3183 [(set (match_operand:DI 0 "register_operand" "=d,d")
3184 (and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
3185 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
3186 "TARGET_64BIT && !TARGET_MIPS16"
3190 [(set_attr "type" "arith")
3191 (set_attr "mode" "DI")])
3193 (define_expand "iorsi3"
3194 [(set (match_operand:SI 0 "register_operand" "=d,d")
3195 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3196 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3201 operands[2] = force_reg (SImode, operands[2]);
3205 [(set (match_operand:SI 0 "register_operand" "=d,d")
3206 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3207 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3212 [(set_attr "type" "arith")
3213 (set_attr "mode" "SI")])
3216 [(set (match_operand:SI 0 "register_operand" "=d")
3217 (ior:SI (match_operand:SI 1 "register_operand" "%0")
3218 (match_operand:SI 2 "register_operand" "d")))]
3221 [(set_attr "type" "arith")
3222 (set_attr "mode" "SI")])
3224 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
3227 (define_expand "iordi3"
3228 [(set (match_operand:DI 0 "register_operand" "=d")
3229 (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3230 (match_operand:DI 2 "se_register_operand" "d")))]
3231 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3235 [(set (match_operand:DI 0 "register_operand" "=d")
3236 (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3237 (match_operand:DI 2 "se_register_operand" "d")))]
3238 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3242 return \"or\\t%0,%1,%2\";
3243 return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
3245 [(set_attr "type" "darith")
3246 (set_attr "mode" "DI")
3247 (set (attr "length")
3248 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3253 [(set (match_operand:DI 0 "register_operand" "=d")
3254 (ior:DI (match_operand:DI 1 "se_register_operand" "0")
3255 (match_operand:DI 2 "se_register_operand" "d")))]
3256 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3260 return \"or\\t%0,%2\";
3261 return \"or\\t%M0,%M2\;or\\t%L0,%L2\";
3263 [(set_attr "type" "darith")
3264 (set_attr "mode" "DI")
3265 (set (attr "length")
3266 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3271 [(set (match_operand:DI 0 "register_operand" "")
3272 (ior:DI (match_operand:DI 1 "register_operand" "")
3273 (match_operand:DI 2 "register_operand" "")))]
3274 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3275 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3276 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3277 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3279 [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3280 (set (subreg:SI (match_dup 0) 1) (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
3283 (define_expand "xorsi3"
3284 [(set (match_operand:SI 0 "register_operand" "=d,d")
3285 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3286 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3291 [(set (match_operand:SI 0 "register_operand" "=d,d")
3292 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3293 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3298 [(set_attr "type" "arith")
3299 (set_attr "mode" "SI")])
3302 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3303 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3304 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3310 [(set_attr "type" "arith")
3311 (set_attr "mode" "SI")
3312 (set_attr_alternative "length"
3314 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3319 ;; ??? If delete the 32-bit long long patterns, then could merge this with
3320 ;; the following xordi3_internal pattern.
3321 (define_expand "xordi3"
3322 [(set (match_operand:DI 0 "register_operand" "=d")
3323 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3324 (match_operand:DI 2 "se_register_operand" "d")))]
3325 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3329 [(set (match_operand:DI 0 "register_operand" "=d")
3330 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3331 (match_operand:DI 2 "se_register_operand" "d")))]
3332 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3336 return \"xor\\t%0,%1,%2\";
3337 return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
3339 [(set_attr "type" "darith")
3340 (set_attr "mode" "DI")
3341 (set (attr "length")
3342 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3347 [(set (match_operand:DI 0 "register_operand" "=d")
3348 (xor:DI (match_operand:DI 1 "se_register_operand" "0")
3349 (match_operand:DI 2 "se_register_operand" "d")))]
3350 "!TARGET_64BIT && TARGET_MIPS16"
3351 "xor\\t%M0,%M2\;xor\\t%L0,%L2"
3352 [(set_attr "type" "darith")
3353 (set_attr "mode" "DI")
3354 (set_attr "length" "8")])
3357 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3358 (xor:DI (match_operand:DI 1 "se_register_operand" "%0,d,d")
3359 (match_operand:DI 2 "se_uns_arith_operand" "d,K,d")))]
3360 "TARGET_64BIT && TARGET_MIPS16"
3365 [(set_attr "type" "arith")
3366 (set_attr "mode" "DI")
3367 (set_attr_alternative "length"
3369 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3375 [(set (match_operand:DI 0 "register_operand" "")
3376 (xor:DI (match_operand:DI 1 "register_operand" "")
3377 (match_operand:DI 2 "register_operand" "")))]
3378 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3379 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3380 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3381 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3383 [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3384 (set (subreg:SI (match_dup 0) 1) (xor:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
3387 (define_insn "xordi3_immed"
3388 [(set (match_operand:DI 0 "register_operand" "=d")
3389 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3390 (match_operand:DI 2 "se_uns_arith_operand" "K")))]
3391 "TARGET_64BIT && !TARGET_MIPS16"
3393 [(set_attr "type" "arith")
3394 (set_attr "mode" "DI")])
3396 (define_insn "*norsi3"
3397 [(set (match_operand:SI 0 "register_operand" "=d")
3398 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3399 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3402 [(set_attr "type" "arith")
3403 (set_attr "mode" "SI")])
3405 (define_insn "*nordi3"
3406 [(set (match_operand:DI 0 "register_operand" "=d")
3407 (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
3408 (not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
3413 return \"nor\\t%0,%z1,%z2\";
3414 return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
3416 [(set_attr "type" "darith")
3417 (set_attr "mode" "DI")
3418 (set (attr "length")
3419 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3424 [(set (match_operand:DI 0 "register_operand" "")
3425 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
3426 (not:DI (match_operand:DI 2 "register_operand" ""))))]
3427 "reload_completed && !TARGET_MIPS16 && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3428 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3429 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3430 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3432 [(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))))
3433 (set (subreg:SI (match_dup 0) 1) (and:SI (not:SI (subreg:SI (match_dup 1) 1)) (not:SI (subreg:SI (match_dup 2) 1))))]
3437 ;; ....................
3441 ;; ....................
3443 (define_insn "truncdfsf2"
3444 [(set (match_operand:SF 0 "register_operand" "=f")
3445 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3446 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3448 [(set_attr "type" "fcvt")
3449 (set_attr "mode" "SF")])
3451 (define_insn "truncdisi2"
3452 [(set (match_operand:SI 0 "register_operand" "=d")
3453 (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
3458 return \"dsll\\t%0,%1,32\;dsra\\t%0,32\";
3459 return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\";
3461 [(set_attr "type" "darith")
3462 (set_attr "mode" "SI")
3463 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3467 (define_insn "truncdihi2"
3468 [(set (match_operand:HI 0 "register_operand" "=d")
3469 (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
3474 return \"dsll\\t%0,%1,48\;dsra\\t%0,48\";
3475 return \"andi\\t%0,%1,0xffff\";
3477 [(set_attr "type" "darith")
3478 (set_attr "mode" "HI")
3479 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3482 (define_insn "truncdiqi2"
3483 [(set (match_operand:QI 0 "register_operand" "=d")
3484 (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
3489 return \"dsll\\t%0,%1,56\;dsra\\t%0,56\";
3490 return \"andi\\t%0,%1,0x00ff\";
3492 [(set_attr "type" "darith")
3493 (set_attr "mode" "QI")
3494 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3498 ;; Combiner patterns to optimize shift/truncate combinations.
3500 [(set (match_operand:SI 0 "register_operand" "=d")
3501 (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3502 (match_operand:DI 2 "small_int" "I"))))]
3503 "TARGET_64BIT && !TARGET_MIPS16"
3506 int shift_amt = INTVAL (operands[2]) & 0x3f;
3510 operands[2] = GEN_INT (32 - shift_amt);
3511 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3515 operands[2] = GEN_INT (shift_amt);
3516 return \"dsra\\t%0,%1,%2\";
3519 [(set_attr "type" "darith")
3520 (set_attr "mode" "SI")
3521 (set_attr "length" "8")])
3524 [(set (match_operand:SI 0 "register_operand" "=d")
3525 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3526 (match_operand:DI 2 "small_int" "I"))))]
3527 "TARGET_64BIT && !TARGET_MIPS16"
3530 int shift_amt = INTVAL (operands[2]) & 0x3f;
3534 operands[2] = GEN_INT (32 - shift_amt);
3535 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3537 else if (shift_amt == 32)
3538 return \"dsra\\t%0,%1,32\";
3541 operands[2] = GEN_INT (shift_amt);
3542 return \"dsrl\\t%0,%1,%2\";
3545 [(set_attr "type" "darith")
3546 (set_attr "mode" "SI")
3547 (set_attr "length" "8")])
3550 [(set (match_operand:SI 0 "register_operand" "=d")
3551 (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
3552 (match_operand:DI 2 "small_int" "I"))))]
3556 int shift_amt = INTVAL (operands[2]) & 0x3f;
3560 operands[2] = GEN_INT (32 + shift_amt);
3562 return \"dsll\\t%0,%1,%2\;dsra\\t%0,32\";
3563 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3566 return \"move\\t%0,%.\";
3568 [(set_attr "type" "darith")
3569 (set_attr "mode" "SI")
3570 (set_attr "length" "8")])
3572 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3575 [(set (match_operand:SI 0 "register_operand" "=d")
3576 (zero_extend:SI (truncate:HI
3577 (match_operand:DI 1 "se_register_operand" "d"))))]
3578 "TARGET_64BIT && !TARGET_MIPS16"
3579 "andi\\t%0,%1,0xffff"
3580 [(set_attr "type" "darith")
3581 (set_attr "mode" "SI")])
3584 [(set (match_operand:SI 0 "register_operand" "=d")
3585 (zero_extend:SI (truncate:QI
3586 (match_operand:DI 1 "se_register_operand" "d"))))]
3587 "TARGET_64BIT && !TARGET_MIPS16"
3589 [(set_attr "type" "darith")
3590 (set_attr "mode" "SI")])
3593 [(set (match_operand:HI 0 "register_operand" "=d")
3594 (zero_extend:HI (truncate:QI
3595 (match_operand:DI 1 "se_register_operand" "d"))))]
3596 "TARGET_64BIT && !TARGET_MIPS16"
3598 [(set_attr "type" "darith")
3599 (set_attr "mode" "HI")])
3602 ;; ....................
3606 ;; ....................
3609 ;; Those for integer source operand are ordered widest source type first.
3611 (define_expand "zero_extendsidi2"
3612 [(set (match_operand:DI 0 "register_operand" "")
3613 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3617 if (optimize && GET_CODE (operands[1]) == MEM)
3618 operands[1] = force_not_mem (operands[1]);
3620 if (GET_CODE (operands[1]) != MEM)
3622 rtx op1 = gen_lowpart (DImode, operands[1]);
3623 rtx temp = gen_reg_rtx (DImode);
3624 rtx shift = GEN_INT (32);
3626 emit_insn (gen_ashldi3 (temp, op1, shift));
3627 emit_insn (gen_lshrdi3 (operands[0], temp, shift));
3632 (define_insn "zero_extendsidi2_internal"
3633 [(set (match_operand:DI 0 "register_operand" "=d,d")
3634 (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
3636 "* return mips_move_1word (operands, insn, TRUE);"
3637 [(set_attr "type" "load")
3638 (set_attr "mode" "DI")
3639 (set_attr "length" "4,8")])
3641 (define_expand "zero_extendhisi2"
3642 [(set (match_operand:SI 0 "register_operand" "")
3643 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3647 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3649 rtx op = gen_lowpart (SImode, operands[1]);
3650 rtx temp = force_reg (SImode, GEN_INT (0xffff));
3652 emit_insn (gen_andsi3 (operands[0], op, temp));
3658 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3659 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3663 if (which_alternative == 0)
3664 return \"andi\\t%0,%1,0xffff\";
3666 return mips_move_1word (operands, insn, TRUE);
3668 [(set_attr "type" "arith,load,load")
3669 (set_attr "mode" "SI")
3670 (set_attr "length" "4,4,8")])
3673 [(set (match_operand:SI 0 "register_operand" "=d,d")
3674 (zero_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3676 "* return mips_move_1word (operands, insn, TRUE);"
3677 [(set_attr "type" "load,load")
3678 (set_attr "mode" "SI")
3679 (set_attr "length" "4,8")])
3681 (define_expand "zero_extendhidi2"
3682 [(set (match_operand:DI 0 "register_operand" "")
3683 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3687 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3689 rtx op = gen_lowpart (DImode, operands[1]);
3690 rtx temp = force_reg (DImode, GEN_INT (0xffff));
3692 emit_insn (gen_anddi3 (operands[0], op, temp));
3698 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3699 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3700 "TARGET_64BIT && !TARGET_MIPS16"
3703 if (which_alternative == 0)
3704 return \"andi\\t%0,%1,0xffff\";
3706 return mips_move_1word (operands, insn, TRUE);
3708 [(set_attr "type" "arith,load,load")
3709 (set_attr "mode" "DI")
3710 (set_attr "length" "4,4,8")])
3713 [(set (match_operand:DI 0 "register_operand" "=d,d")
3714 (zero_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3715 "TARGET_64BIT && TARGET_MIPS16"
3716 "* return mips_move_1word (operands, insn, TRUE);"
3717 [(set_attr "type" "load,load")
3718 (set_attr "mode" "DI")
3719 (set_attr "length" "4,8")])
3721 (define_expand "zero_extendqihi2"
3722 [(set (match_operand:HI 0 "register_operand" "")
3723 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3727 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3729 rtx op0 = gen_lowpart (SImode, operands[0]);
3730 rtx op1 = gen_lowpart (SImode, operands[1]);
3731 rtx temp = force_reg (SImode, GEN_INT (0xff));
3733 emit_insn (gen_andsi3 (op0, op1, temp));
3739 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
3740 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3744 if (which_alternative == 0)
3745 return \"andi\\t%0,%1,0x00ff\";
3747 return mips_move_1word (operands, insn, TRUE);
3749 [(set_attr "type" "arith,load,load")
3750 (set_attr "mode" "HI")
3751 (set_attr "length" "4,4,8")])
3754 [(set (match_operand:HI 0 "register_operand" "=d,d")
3755 (zero_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
3757 "* return mips_move_1word (operands, insn, TRUE);"
3758 [(set_attr "type" "load,load")
3759 (set_attr "mode" "HI")
3760 (set_attr "length" "4,8")])
3762 (define_expand "zero_extendqisi2"
3763 [(set (match_operand:SI 0 "register_operand" "")
3764 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3768 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3770 rtx op = gen_lowpart (SImode, operands[1]);
3771 rtx temp = force_reg (SImode, GEN_INT (0xff));
3773 emit_insn (gen_andsi3 (operands[0], op, temp));
3779 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3780 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3784 if (which_alternative == 0)
3785 return \"andi\\t%0,%1,0x00ff\";
3787 return mips_move_1word (operands, insn, TRUE);
3789 [(set_attr "type" "arith,load,load")
3790 (set_attr "mode" "SI")
3791 (set_attr "length" "4,4,8")])
3794 [(set (match_operand:SI 0 "register_operand" "=d,d")
3795 (zero_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
3797 "* return mips_move_1word (operands, insn, TRUE);"
3798 [(set_attr "type" "load,load")
3799 (set_attr "mode" "SI")
3800 (set_attr "length" "4,8")])
3802 (define_expand "zero_extendqidi2"
3803 [(set (match_operand:DI 0 "register_operand" "")
3804 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
3808 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3810 rtx op = gen_lowpart (DImode, operands[1]);
3811 rtx temp = force_reg (DImode, GEN_INT (0xff));
3813 emit_insn (gen_anddi3 (operands[0], op, temp));
3819 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3820 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3821 "TARGET_64BIT && !TARGET_MIPS16"
3824 if (which_alternative == 0)
3825 return \"andi\\t%0,%1,0x00ff\";
3827 return mips_move_1word (operands, insn, TRUE);
3829 [(set_attr "type" "arith,load,load")
3830 (set_attr "mode" "DI")
3831 (set_attr "length" "4,4,8")])
3833 ;; These can be created when a paradoxical subreg operand with an implicit
3834 ;; sign_extend operator is reloaded. Because of the subreg, this is really
3836 ;; ??? It might be possible to eliminate the need for these patterns by adding
3837 ;; more support to reload for implicit sign_extend operators.
3838 (define_insn "*paradoxical_extendhidi2"
3839 [(set (match_operand:DI 0 "register_operand" "=d,d")
3841 (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
3845 return mips_move_1word (operands, insn, TRUE);
3847 [(set_attr "type" "load,load")
3848 (set_attr "mode" "DI")
3849 (set_attr "length" "4,8")])
3852 [(set (match_operand:DI 0 "register_operand" "=d,d")
3853 (zero_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
3854 "TARGET_64BIT && TARGET_MIPS16"
3855 "* return mips_move_1word (operands, insn, TRUE);"
3856 [(set_attr "type" "load,load")
3857 (set_attr "mode" "DI")
3858 (set_attr "length" "4,8")])
3861 ;; ....................
3865 ;; ....................
3868 ;; Those for integer source operand are ordered widest source type first.
3870 ;; In 64 bit mode, 32 bit values in general registers are always
3871 ;; correctly sign extended. That means that if the target is a
3872 ;; general register, we can sign extend from SImode to DImode just by
3875 (define_insn "extendsidi2"
3876 [(set (match_operand:DI 0 "register_operand" "=d,y,d,*d,d,d")
3877 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,d,y,*x,R,m")))]
3879 "* return mips_move_1word (operands, insn, FALSE);"
3880 [(set_attr "type" "move,move,move,hilo,load,load")
3881 (set_attr "mode" "DI")
3882 (set_attr "length" "4,4,4,4,4,8")])
3884 ;; These patterns originally accepted general_operands, however, slightly
3885 ;; better code is generated by only accepting register_operands, and then
3886 ;; letting combine generate the lh and lb insns.
3888 (define_expand "extendhidi2"
3889 [(set (match_operand:DI 0 "register_operand" "")
3890 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3894 if (optimize && GET_CODE (operands[1]) == MEM)
3895 operands[1] = force_not_mem (operands[1]);
3897 if (GET_CODE (operands[1]) != MEM)
3899 rtx op1 = gen_lowpart (DImode, operands[1]);
3900 rtx temp = gen_reg_rtx (DImode);
3901 rtx shift = GEN_INT (48);
3903 emit_insn (gen_ashldi3 (temp, op1, shift));
3904 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
3909 (define_insn "extendhidi2_internal"
3910 [(set (match_operand:DI 0 "register_operand" "=d,d")
3911 (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3913 "* return mips_move_1word (operands, insn, FALSE);"
3914 [(set_attr "type" "load")
3915 (set_attr "mode" "DI")
3916 (set_attr "length" "4,8")])
3918 (define_expand "extendhisi2"
3919 [(set (match_operand:SI 0 "register_operand" "")
3920 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3924 if (optimize && GET_CODE (operands[1]) == MEM)
3925 operands[1] = force_not_mem (operands[1]);
3927 if (GET_CODE (operands[1]) != MEM)
3929 rtx op1 = gen_lowpart (SImode, operands[1]);
3930 rtx temp = gen_reg_rtx (SImode);
3931 rtx shift = GEN_INT (16);
3933 emit_insn (gen_ashlsi3 (temp, op1, shift));
3934 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
3939 (define_insn "extendhisi2_internal"
3940 [(set (match_operand:SI 0 "register_operand" "=d,d")
3941 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3943 "* return mips_move_1word (operands, insn, FALSE);"
3944 [(set_attr "type" "load")
3945 (set_attr "mode" "SI")
3946 (set_attr "length" "4,8")])
3948 (define_expand "extendqihi2"
3949 [(set (match_operand:HI 0 "register_operand" "")
3950 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3954 if (optimize && GET_CODE (operands[1]) == MEM)
3955 operands[1] = force_not_mem (operands[1]);
3957 if (GET_CODE (operands[1]) != MEM)
3959 rtx op0 = gen_lowpart (SImode, operands[0]);
3960 rtx op1 = gen_lowpart (SImode, operands[1]);
3961 rtx temp = gen_reg_rtx (SImode);
3962 rtx shift = GEN_INT (24);
3964 emit_insn (gen_ashlsi3 (temp, op1, shift));
3965 emit_insn (gen_ashrsi3 (op0, temp, shift));
3970 (define_insn "extendqihi2_internal"
3971 [(set (match_operand:HI 0 "register_operand" "=d,d")
3972 (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
3974 "* return mips_move_1word (operands, insn, FALSE);"
3975 [(set_attr "type" "load")
3976 (set_attr "mode" "SI")
3977 (set_attr "length" "4,8")])
3980 (define_expand "extendqisi2"
3981 [(set (match_operand:SI 0 "register_operand" "")
3982 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3986 if (optimize && GET_CODE (operands[1]) == MEM)
3987 operands[1] = force_not_mem (operands[1]);
3989 if (GET_CODE (operands[1]) != MEM)
3991 rtx op1 = gen_lowpart (SImode, operands[1]);
3992 rtx temp = gen_reg_rtx (SImode);
3993 rtx shift = GEN_INT (24);
3995 emit_insn (gen_ashlsi3 (temp, op1, shift));
3996 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4001 (define_insn "extendqisi2_insn"
4002 [(set (match_operand:SI 0 "register_operand" "=d,d")
4003 (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
4005 "* return mips_move_1word (operands, insn, FALSE);"
4006 [(set_attr "type" "load")
4007 (set_attr "mode" "SI")
4008 (set_attr "length" "4,8")])
4010 (define_expand "extendqidi2"
4011 [(set (match_operand:DI 0 "register_operand" "")
4012 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4016 if (optimize && GET_CODE (operands[1]) == MEM)
4017 operands[1] = force_not_mem (operands[1]);
4019 if (GET_CODE (operands[1]) != MEM)
4021 rtx op1 = gen_lowpart (DImode, operands[1]);
4022 rtx temp = gen_reg_rtx (DImode);
4023 rtx shift = GEN_INT (56);
4025 emit_insn (gen_ashldi3 (temp, op1, shift));
4026 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4031 (define_insn "extendqidi2_insn"
4032 [(set (match_operand:DI 0 "register_operand" "=d,d")
4033 (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4035 "* return mips_move_1word (operands, insn, FALSE);"
4036 [(set_attr "type" "load")
4037 (set_attr "mode" "DI")
4038 (set_attr "length" "4,8")])
4041 (define_insn "extendsfdf2"
4042 [(set (match_operand:DF 0 "register_operand" "=f")
4043 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
4044 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4046 [(set_attr "type" "fcvt")
4047 (set_attr "mode" "DF")])
4052 ;; ....................
4056 ;; ....................
4058 ;; The SImode scratch register can not be shared with address regs used for
4059 ;; operand zero, because then the address in the move instruction will be
4060 ;; clobbered. We mark the scratch register as early clobbered to prevent this.
4062 ;; We need the ?X in alternative 1 so that it will be choosen only if the
4063 ;; destination is a floating point register. Otherwise, alternative 1 can
4064 ;; have lower cost than alternative 0 (because there is one less loser), and
4065 ;; can be choosen when it won't work (because integral reloads into FP
4066 ;; registers are not supported).
4068 (define_insn "fix_truncdfsi2"
4069 [(set (match_operand:SI 0 "general_operand" "=d,*f,R,To")
4070 (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
4071 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
4072 (clobber (match_scratch:DF 3 "=f,?*X,f,f"))]
4073 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4078 if (which_alternative == 1)
4079 return \"trunc.w.d %0,%1,%2\";
4081 output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
4083 xoperands[0] = operands[0];
4084 xoperands[1] = operands[3];
4085 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4088 [(set_attr "type" "fcvt")
4089 (set_attr "mode" "DF")
4090 (set_attr "length" "44,36,40,44")])
4093 (define_insn "fix_truncsfsi2"
4094 [(set (match_operand:SI 0 "general_operand" "=d,*f,R,To")
4095 (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
4096 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
4097 (clobber (match_scratch:SF 3 "=f,?*X,f,f"))]
4103 if (which_alternative == 1)
4104 return \"trunc.w.s %0,%1,%2\";
4106 output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
4108 xoperands[0] = operands[0];
4109 xoperands[1] = operands[3];
4110 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4113 [(set_attr "type" "fcvt")
4114 (set_attr "mode" "SF")
4115 (set_attr "length" "44,36,40,44")])
4118 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
4119 ;;; but not in the chapter that describes the FPU. It is not mentioned at all
4120 ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
4122 ;;; Deleting this means that we now need two libgcc2.a libraries. One for
4123 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
4125 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
4127 (define_insn "fix_truncdfdi2"
4128 [(set (match_operand:DI 0 "general_operand" "=d,*f,R,To")
4129 (fix:DI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
4130 (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
4131 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4136 if (which_alternative == 1)
4137 return \"trunc.l.d %0,%1\";
4139 output_asm_insn (\"trunc.l.d %2,%1\", operands);
4141 xoperands[0] = operands[0];
4142 xoperands[1] = operands[2];
4143 output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
4146 [(set_attr "type" "fcvt")
4147 (set_attr "mode" "DF")
4148 (set_attr "length" "8,4,8,12")])
4151 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
4152 ;;; but not in the chapter that describes the FPU. It is not mentioned at all
4153 ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
4154 (define_insn "fix_truncsfdi2"
4155 [(set (match_operand:DI 0 "general_operand" "=d,*f,R,To")
4156 (fix:DI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
4157 (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
4158 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4163 if (which_alternative == 1)
4164 return \"trunc.l.s %0,%1\";
4166 output_asm_insn (\"trunc.l.s %2,%1\", operands);
4168 xoperands[0] = operands[0];
4169 xoperands[1] = operands[2];
4170 output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
4173 [(set_attr "type" "fcvt")
4174 (set_attr "mode" "SF")
4175 (set_attr "length" "8,4,8,12")])
4178 (define_insn "floatsidf2"
4179 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
4180 (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
4181 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4184 dslots_load_total++;
4185 if (GET_CODE (operands[1]) == MEM)
4186 return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
4188 return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
4190 [(set_attr "type" "fcvt")
4191 (set_attr "mode" "DF")
4192 (set_attr "length" "12,16,12")])
4195 (define_insn "floatdidf2"
4196 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
4197 (float:DF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
4198 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4201 dslots_load_total++;
4202 if (GET_CODE (operands[1]) == MEM)
4203 return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
4205 return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
4207 [(set_attr "type" "fcvt")
4208 (set_attr "mode" "DF")
4209 (set_attr "length" "12,16,12")])
4212 (define_insn "floatsisf2"
4213 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
4214 (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
4218 dslots_load_total++;
4219 if (GET_CODE (operands[1]) == MEM)
4220 return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
4222 return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
4224 [(set_attr "type" "fcvt")
4225 (set_attr "mode" "SF")
4226 (set_attr "length" "12,16,12")])
4229 (define_insn "floatdisf2"
4230 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
4231 (float:SF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
4232 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4235 dslots_load_total++;
4236 if (GET_CODE (operands[1]) == MEM)
4237 return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
4239 return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
4241 [(set_attr "type" "fcvt")
4242 (set_attr "mode" "SF")
4243 (set_attr "length" "12,16,12")])
4246 (define_expand "fixuns_truncdfsi2"
4247 [(set (match_operand:SI 0 "register_operand" "")
4248 (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
4249 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4252 rtx reg1 = gen_reg_rtx (DFmode);
4253 rtx reg2 = gen_reg_rtx (DFmode);
4254 rtx reg3 = gen_reg_rtx (SImode);
4255 rtx label1 = gen_label_rtx ();
4256 rtx label2 = gen_label_rtx ();
4257 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
4259 if (reg1) /* turn off complaints about unreached code */
4261 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4262 do_pending_stack_adjust ();
4264 emit_insn (gen_cmpdf (operands[1], reg1));
4265 emit_jump_insn (gen_bge (label1));
4267 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
4268 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4269 gen_rtx (LABEL_REF, VOIDmode, label2)));
4272 emit_label (label1);
4273 emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
4274 emit_move_insn (reg3, GEN_INT (0x80000000));
4276 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
4277 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4279 emit_label (label2);
4281 /* allow REG_NOTES to be set on last insn (labels don't have enough
4282 fields, and can't be used for REG_NOTES anyway). */
4283 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4289 (define_expand "fixuns_truncdfdi2"
4290 [(set (match_operand:DI 0 "register_operand" "")
4291 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
4292 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4295 rtx reg1 = gen_reg_rtx (DFmode);
4296 rtx reg2 = gen_reg_rtx (DFmode);
4297 rtx reg3 = gen_reg_rtx (DImode);
4298 rtx label1 = gen_label_rtx ();
4299 rtx label2 = gen_label_rtx ();
4300 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
4302 if (reg1) /* turn off complaints about unreached code */
4304 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4305 do_pending_stack_adjust ();
4307 emit_insn (gen_cmpdf (operands[1], reg1));
4308 emit_jump_insn (gen_bge (label1));
4310 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
4311 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4312 gen_rtx (LABEL_REF, VOIDmode, label2)));
4315 emit_label (label1);
4316 emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
4317 emit_move_insn (reg3, GEN_INT (0x80000000));
4318 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4320 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
4321 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4323 emit_label (label2);
4325 /* allow REG_NOTES to be set on last insn (labels don't have enough
4326 fields, and can't be used for REG_NOTES anyway). */
4327 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4333 (define_expand "fixuns_truncsfsi2"
4334 [(set (match_operand:SI 0 "register_operand" "")
4335 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
4339 rtx reg1 = gen_reg_rtx (SFmode);
4340 rtx reg2 = gen_reg_rtx (SFmode);
4341 rtx reg3 = gen_reg_rtx (SImode);
4342 rtx label1 = gen_label_rtx ();
4343 rtx label2 = gen_label_rtx ();
4344 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
4346 if (reg1) /* turn off complaints about unreached code */
4348 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4349 do_pending_stack_adjust ();
4351 emit_insn (gen_cmpsf (operands[1], reg1));
4352 emit_jump_insn (gen_bge (label1));
4354 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
4355 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4356 gen_rtx (LABEL_REF, VOIDmode, label2)));
4359 emit_label (label1);
4360 emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
4361 emit_move_insn (reg3, GEN_INT (0x80000000));
4363 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4364 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4366 emit_label (label2);
4368 /* allow REG_NOTES to be set on last insn (labels don't have enough
4369 fields, and can't be used for REG_NOTES anyway). */
4370 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4376 (define_expand "fixuns_truncsfdi2"
4377 [(set (match_operand:DI 0 "register_operand" "")
4378 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
4379 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4382 rtx reg1 = gen_reg_rtx (SFmode);
4383 rtx reg2 = gen_reg_rtx (SFmode);
4384 rtx reg3 = gen_reg_rtx (DImode);
4385 rtx label1 = gen_label_rtx ();
4386 rtx label2 = gen_label_rtx ();
4387 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
4389 if (reg1) /* turn off complaints about unreached code */
4391 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4392 do_pending_stack_adjust ();
4394 emit_insn (gen_cmpsf (operands[1], reg1));
4395 emit_jump_insn (gen_bge (label1));
4397 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
4398 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4399 gen_rtx (LABEL_REF, VOIDmode, label2)));
4402 emit_label (label1);
4403 emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
4404 emit_move_insn (reg3, GEN_INT (0x80000000));
4405 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4407 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4408 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4410 emit_label (label2);
4412 /* allow REG_NOTES to be set on last insn (labels don't have enough
4413 fields, and can't be used for REG_NOTES anyway). */
4414 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4421 ;; ....................
4425 ;; ....................
4427 ;; Bit field extract patterns which use lwl/lwr.
4429 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
4430 ;; It isn't clear whether this will give better code.
4432 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4433 (define_expand "extv"
4434 [(set (match_operand 0 "register_operand" "")
4435 (sign_extract (match_operand:QI 1 "memory_operand" "")
4436 (match_operand 2 "immediate_operand" "")
4437 (match_operand 3 "immediate_operand" "")))]
4441 /* If the field does not start on a byte boundary, then fail. */
4442 if (INTVAL (operands[3]) % 8 != 0)
4445 /* MIPS I and MIPS II can only handle a 32bit field. */
4446 if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4449 /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
4451 && INTVAL (operands[2]) != 64
4452 && INTVAL (operands[2]) != 32)
4455 /* This can happen for a 64 bit target, when extracting a value from
4456 a 64 bit union member. extract_bit_field doesn't verify that our
4457 source matches the predicate, so we force it to be a MEM here. */
4458 if (GET_CODE (operands[1]) != MEM)
4461 /* Change the mode to BLKmode for aliasing purposes. */
4462 operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
4464 /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value. */
4465 if (INTVAL (operands[2]) == 64)
4466 emit_insn (gen_movdi_uld (operands[0], operands[1]));
4471 operands[0] = gen_lowpart (SImode, operands[0]);
4472 if (operands[0] == NULL_RTX)
4475 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4480 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4481 (define_expand "extzv"
4482 [(set (match_operand 0 "register_operand" "")
4483 (zero_extract (match_operand:QI 1 "memory_operand" "")
4484 (match_operand 2 "immediate_operand" "")
4485 (match_operand 3 "immediate_operand" "")))]
4489 /* If the field does not start on a byte boundary, then fail. */
4490 if (INTVAL (operands[3]) % 8 != 0)
4493 /* MIPS I and MIPS II can only handle a 32bit field. */
4494 if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4497 /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
4499 && INTVAL (operands[2]) != 64
4500 && INTVAL (operands[2]) != 32)
4503 /* This can happen for a 64 bit target, when extracting a value from
4504 a 64 bit union member. extract_bit_field doesn't verify that our
4505 source matches the predicate, so we force it to be a MEM here. */
4506 if (GET_CODE (operands[1]) != MEM)
4509 /* Change the mode to BLKmode for aliasing purposes. */
4510 operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
4512 /* Otherwise, emit a lwl/lwr pair to load the value. */
4513 if (INTVAL (operands[2]) == 64)
4514 emit_insn (gen_movdi_uld (operands[0], operands[1]));
4519 operands[0] = gen_lowpart (SImode, operands[0]);
4520 if (operands[0] == NULL_RTX)
4523 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4528 ;; Only specify the mode operands 0, the rest are assumed to be word_mode.
4529 (define_expand "insv"
4530 [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
4531 (match_operand 1 "immediate_operand" "")
4532 (match_operand 2 "immediate_operand" ""))
4533 (match_operand 3 "register_operand" ""))]
4537 /* If the field does not start on a byte boundary, then fail. */
4538 if (INTVAL (operands[2]) % 8 != 0)
4541 /* MIPS I and MIPS II can only handle a 32bit field. */
4542 if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
4545 /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
4547 && INTVAL (operands[1]) != 64
4548 && INTVAL (operands[1]) != 32)
4551 /* This can happen for a 64 bit target, when storing into a 32 bit union
4552 member. store_bit_field doesn't verify that our target matches the
4553 predicate, so we force it to be a MEM here. */
4554 if (GET_CODE (operands[0]) != MEM)
4557 /* Change the mode to BLKmode for aliasing purposes. */
4558 operands[0] = change_address (operands[0], BLKmode, XEXP (operands[0], 0));
4560 /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value. */
4561 if (INTVAL (operands[1]) == 64)
4562 emit_insn (gen_movdi_usd (operands[0], operands[3]));
4567 operands[3] = gen_lowpart (SImode, operands[3]);
4568 if (operands[3] == NULL_RTX)
4571 emit_insn (gen_movsi_usw (operands[0], operands[3]));
4576 ;; unaligned word moves generated by the bit field patterns
4578 (define_insn "movsi_ulw"
4579 [(set (match_operand:SI 0 "register_operand" "=&d,&d")
4580 (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
4584 rtx offset = const0_rtx;
4585 rtx addr = XEXP (operands[1], 0);
4586 rtx mem_addr = eliminate_constant_term (addr, &offset);
4590 mips_count_memory_refs (operands[1], 2);
4592 /* The stack/frame pointers are always aligned, so we can convert
4593 to the faster lw if we are referencing an aligned stack location. */
4595 if ((INTVAL (offset) & 3) == 0
4596 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4597 ret = \"lw\\t%0,%1\";
4599 ret = \"ulw\\t%0,%1\";
4601 return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4603 [(set_attr "type" "load,load")
4604 (set_attr "mode" "SI")
4605 (set_attr "length" "8,16")])
4607 (define_insn "movsi_usw"
4608 [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4609 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
4613 rtx offset = const0_rtx;
4614 rtx addr = XEXP (operands[0], 0);
4615 rtx mem_addr = eliminate_constant_term (addr, &offset);
4618 mips_count_memory_refs (operands[0], 2);
4620 /* The stack/frame pointers are always aligned, so we can convert
4621 to the faster sw if we are referencing an aligned stack location. */
4623 if ((INTVAL (offset) & 3) == 0
4624 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4625 return \"sw\\t%1,%0\";
4627 return \"usw\\t%z1,%0\";
4629 [(set_attr "type" "store")
4630 (set_attr "mode" "SI")
4631 (set_attr "length" "8,16")])
4633 ;; Bit field extract patterns which use ldl/ldr.
4635 ;; unaligned double word moves generated by the bit field patterns
4637 (define_insn "movdi_uld"
4638 [(set (match_operand:DI 0 "register_operand" "=&d,&d")
4639 (unspec:DI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
4643 rtx offset = const0_rtx;
4644 rtx addr = XEXP (operands[1], 0);
4645 rtx mem_addr = eliminate_constant_term (addr, &offset);
4649 mips_count_memory_refs (operands[1], 2);
4651 /* The stack/frame pointers are always aligned, so we can convert
4652 to the faster lw if we are referencing an aligned stack location. */
4654 if ((INTVAL (offset) & 7) == 0
4655 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4656 ret = \"ld\\t%0,%1\";
4658 ret = \"uld\\t%0,%1\";
4660 return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4662 [(set_attr "type" "load,load")
4663 (set_attr "mode" "SI")
4664 (set_attr "length" "8,16")])
4666 (define_insn "movdi_usd"
4667 [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4668 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
4672 rtx offset = const0_rtx;
4673 rtx addr = XEXP (operands[0], 0);
4674 rtx mem_addr = eliminate_constant_term (addr, &offset);
4677 mips_count_memory_refs (operands[0], 2);
4679 /* The stack/frame pointers are always aligned, so we can convert
4680 to the faster sw if we are referencing an aligned stack location. */
4682 if ((INTVAL (offset) & 7) == 0
4683 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4684 return \"sd\\t%1,%0\";
4686 return \"usd\\t%z1,%0\";
4688 [(set_attr "type" "store")
4689 (set_attr "mode" "SI")
4690 (set_attr "length" "8,16")])
4692 ;; These two patterns support loading addresses with two instructions instead
4693 ;; of using the macro instruction la.
4695 ;; ??? mips_move_1word has support for HIGH, so this pattern may be
4699 [(set (match_operand:SI 0 "register_operand" "=r")
4700 (high:SI (match_operand:SI 1 "immediate_operand" "")))]
4701 "mips_split_addresses && !TARGET_MIPS16"
4702 "lui\\t%0,%%hi(%1) # high"
4703 [(set_attr "type" "move")])
4706 [(set (match_operand:SI 0 "register_operand" "=r")
4707 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
4708 (match_operand:SI 2 "immediate_operand" "")))]
4709 "mips_split_addresses && !TARGET_MIPS16"
4710 "addiu\\t%0,%1,%%lo(%2) # low"
4711 [(set_attr "type" "arith")
4712 (set_attr "mode" "SI")])
4714 ;; 64-bit integer moves
4716 ;; Unlike most other insns, the move insns can't be split with
4717 ;; different predicates, because register spilling and other parts of
4718 ;; the compiler, have memoized the insn number already.
4720 (define_expand "movdi"
4721 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4722 (match_operand:DI 1 "general_operand" ""))]
4726 if (mips_split_addresses && mips_check_split (operands[1], DImode))
4728 enum machine_mode mode = GET_MODE (operands[0]);
4729 rtx tem = ((reload_in_progress | reload_completed)
4730 ? operands[0] : gen_reg_rtx (mode));
4732 emit_insn (gen_rtx (SET, VOIDmode, tem,
4733 gen_rtx (HIGH, mode, operands[1])));
4735 operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
4738 /* If we are generating embedded PIC code, and we are referring to a
4739 symbol in the .text section, we must use an offset from the start
4741 if (TARGET_EMBEDDED_PIC
4742 && (GET_CODE (operands[1]) == LABEL_REF
4743 || (GET_CODE (operands[1]) == SYMBOL_REF
4744 && ! SYMBOL_REF_FLAG (operands[1]))))
4748 temp = embedded_pic_offset (operands[1]);
4749 temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
4750 force_reg (DImode, temp));
4751 emit_move_insn (operands[0], force_reg (DImode, temp));
4755 /* If operands[1] is a constant address illegal for pic, then we need to
4756 handle it just like LEGITIMIZE_ADDRESS does. */
4757 if (flag_pic && pic_address_needs_scratch (operands[1]))
4759 rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
4760 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
4762 if (! SMALL_INT (temp2))
4763 temp2 = force_reg (DImode, temp2);
4765 emit_move_insn (operands[0], gen_rtx (PLUS, DImode, temp, temp2));
4769 /* On the mips16, we can handle a GP relative reference by adding in
4770 $gp. We need to check the name to see whether this is a string
4773 && register_operand (operands[0], DImode)
4774 && GET_CODE (operands[1]) == SYMBOL_REF
4775 && SYMBOL_REF_FLAG (operands[1]))
4777 char *name = XSTR (operands[1], 0);
4780 || strncmp (name + 1, LOCAL_LABEL_PREFIX,
4781 sizeof LOCAL_LABEL_PREFIX - 1) != 0)
4785 if (reload_in_progress || reload_completed)
4787 /* In movsi we use the constant table here. However, in
4788 this case, we're better off copying $28 into a
4789 register and adding, because the constant table entry
4790 would be 8 bytes. */
4791 base_reg = operands[0];
4792 emit_move_insn (base_reg,
4793 gen_rtx (CONST, DImode,
4794 gen_rtx (REG, DImode,
4795 GP_REG_FIRST + 28)));
4799 base_reg = gen_reg_rtx (Pmode);
4800 emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
4803 emit_move_insn (operands[0],
4804 gen_rtx (PLUS, Pmode, base_reg,
4805 mips16_gp_offset (operands[1])));
4810 if ((reload_in_progress | reload_completed) == 0
4811 && !register_operand (operands[0], DImode)
4812 && !register_operand (operands[1], DImode)
4814 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
4815 && operands[1] != CONST0_RTX (DImode))))
4817 rtx temp = force_reg (DImode, operands[1]);
4818 emit_move_insn (operands[0], temp);
4823 ;; For mips16, we need a special case to handle storing $31 into
4824 ;; memory, since we don't have a constraint to match $31. This
4825 ;; instruction can be generated by save_restore_insns.
4828 [(set (match_operand:DI 0 "memory_operand" "R,m")
4830 "TARGET_MIPS16 && TARGET_64BIT"
4833 operands[1] = gen_rtx (REG, DImode, 31);
4834 return mips_move_2words (operands, insn);
4836 [(set_attr "type" "store")
4837 (set_attr "mode" "DI")
4838 (set_attr "length" "4,8")])
4840 (define_insn "movdi_internal"
4841 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x")
4842 (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d"))]
4843 "!TARGET_64BIT && !TARGET_MIPS16
4844 && (register_operand (operands[0], DImode)
4845 || register_operand (operands[1], DImode)
4846 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4847 || operands[1] == CONST0_RTX (DImode))"
4848 "* return mips_move_2words (operands, insn); "
4849 [(set_attr "type" "move,arith,load,load,store,store,hilo,hilo,hilo")
4850 (set_attr "mode" "DI")
4851 (set_attr "length" "8,16,8,16,8,16,8,8,8")])
4854 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,To,*d")
4855 (match_operand:DI 1 "general_operand" "d,d,y,K,N,R,To,d,d,*x"))]
4856 "!TARGET_64BIT && TARGET_MIPS16
4857 && (register_operand (operands[0], DImode)
4858 || register_operand (operands[1], DImode))"
4859 "* return mips_move_2words (operands, insn);"
4860 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
4861 (set_attr "mode" "DI")
4862 (set_attr "length" "8,8,8,8,12,8,16,8,16,8")])
4865 [(set (match_operand:DI 0 "register_operand" "")
4866 (match_operand:DI 1 "register_operand" ""))]
4867 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4868 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
4869 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
4871 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
4872 (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
4875 (define_insn "movdi_internal2"
4876 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a")
4877 (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J"))]
4878 "TARGET_64BIT && !TARGET_MIPS16
4879 && (register_operand (operands[0], DImode)
4880 || se_register_operand (operands[1], DImode)
4881 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4882 || operands[1] == CONST0_RTX (DImode))"
4883 "* return mips_move_2words (operands, insn); "
4884 [(set_attr "type" "move,load,arith,arith,load,load,store,store,hilo,hilo,hilo,hilo")
4885 (set_attr "mode" "DI")
4886 (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,8")])
4889 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
4890 (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
4891 "TARGET_64BIT && TARGET_MIPS16
4892 && (register_operand (operands[0], DImode)
4893 || se_register_operand (operands[1], DImode))"
4894 "* return mips_move_2words (operands, insn);"
4895 [(set_attr "type" "move,move,move,arith,arith,arith,load,load,store,store,hilo")
4896 (set_attr "mode" "DI")
4897 (set_attr_alternative "length"
4901 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
4904 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
4907 (if_then_else (match_operand:VOID 1 "m16_usym5_4" "")
4916 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4917 ;; when the original load is a 4 byte instruction but the add and the
4918 ;; load are 2 2 byte instructions.
4921 [(set (match_operand:DI 0 "register_operand" "")
4922 (mem:DI (plus:DI (match_dup 0)
4923 (match_operand:DI 1 "const_int_operand" ""))))]
4924 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4925 && GET_CODE (operands[0]) == REG
4926 && M16_REG_P (REGNO (operands[0]))
4927 && GET_CODE (operands[1]) == CONST_INT
4928 && ((INTVAL (operands[1]) < 0
4929 && INTVAL (operands[1]) >= -0x10)
4930 || (INTVAL (operands[1]) >= 32 * 8
4931 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4932 || (INTVAL (operands[1]) >= 0
4933 && INTVAL (operands[1]) < 32 * 8
4934 && (INTVAL (operands[1]) & 7) != 0))"
4935 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4936 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4939 HOST_WIDE_INT val = INTVAL (operands[1]);
4942 operands[2] = GEN_INT (0);
4943 else if (val >= 32 * 8)
4947 operands[1] = GEN_INT (0x8 + off);
4948 operands[2] = GEN_INT (val - off - 0x8);
4954 operands[1] = GEN_INT (off);
4955 operands[2] = GEN_INT (val - off);
4959 ;; Handle input reloads in DImode.
4960 ;; This is mainly to handle reloading HILO_REGNUM. Note that we may
4961 ;; see it as the source or the destination, depending upon which way
4962 ;; reload handles the instruction.
4963 ;; Making the second operand TImode is a trick. The compiler may
4964 ;; reuse the same register for operand 0 and operand 2. Using TImode
4965 ;; gives us two registers, so we can always use the one which is not
4968 (define_expand "reload_indi"
4969 [(set (match_operand:DI 0 "register_operand" "=b")
4970 (match_operand:DI 1 "" "b"))
4971 (clobber (match_operand:TI 2 "register_operand" "=&d"))]
4975 rtx scratch = gen_rtx (REG, DImode,
4976 (REGNO (operands[0]) == REGNO (operands[2])
4977 ? REGNO (operands[2]) + 1
4978 : REGNO (operands[2])));
4980 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
4982 if (GET_CODE (operands[1]) == MEM)
4984 rtx memword, offword, hiword, loword;
4985 rtx addr = find_replacement (&XEXP (operands[1], 0));
4986 rtx op1 = change_address (operands[1], VOIDmode, addr);
4988 scratch = gen_rtx (REG, SImode, REGNO (scratch));
4989 memword = change_address (op1, SImode, NULL_RTX);
4990 offword = change_address (adj_offsettable_operand (op1, 4),
4992 if (BYTES_BIG_ENDIAN)
5002 emit_move_insn (scratch, hiword);
5003 emit_move_insn (gen_rtx (REG, SImode, 64), scratch);
5004 emit_move_insn (scratch, loword);
5005 emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
5006 emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
5010 emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5011 emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
5012 emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5013 emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5014 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5015 emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
5019 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5021 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5022 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5023 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5024 emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
5025 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5026 emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5027 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
5030 /* This handles moves between a float register and HI/LO. */
5031 emit_move_insn (scratch, operands[1]);
5032 emit_move_insn (operands[0], scratch);
5036 ;; Handle output reloads in DImode.
5038 ;; Reloading HILO_REG in MIPS16 mode requires two scratch registers, so we
5039 ;; use a TImode scratch reg.
5041 (define_expand "reload_outdi"
5042 [(set (match_operand:DI 0 "" "=b")
5043 (match_operand:DI 1 "se_register_operand" "b"))
5044 (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5048 rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5050 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5052 emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5053 emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
5054 emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5055 emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5056 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5057 emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
5060 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5062 if (GET_CODE (operands[0]) == MEM)
5064 rtx scratch, memword, offword, hiword, loword;
5065 rtx addr = find_replacement (&XEXP (operands[0], 0));
5066 rtx op0 = change_address (operands[0], VOIDmode, addr);
5068 scratch = gen_rtx (REG, SImode, REGNO (operands[2]));
5069 memword = change_address (op0, SImode, NULL_RTX);
5070 offword = change_address (adj_offsettable_operand (op0, 4),
5072 if (BYTES_BIG_ENDIAN)
5082 emit_move_insn (scratch, gen_rtx (REG, SImode, 64));
5083 emit_move_insn (hiword, scratch);
5084 emit_move_insn (scratch, gen_rtx (REG, SImode, 65));
5085 emit_move_insn (loword, scratch);
5086 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
5088 else if (TARGET_MIPS16 && ! M16_REG_P (REGNO (operands[0])))
5090 /* Handle the case where operand[0] is not a 'd' register,
5091 and hence we can not directly move from the HILO register
5093 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5094 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5095 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5096 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5097 emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64)));
5098 emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
5099 emit_insn (gen_iordi3 (scratch, scratch, scratch2));
5100 emit_insn (gen_movdi (operands[0], scratch));
5101 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
5105 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5106 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5107 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5108 emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
5109 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5110 emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5111 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
5115 /* This handles moves between a float register and HI/LO. */
5116 emit_move_insn (scratch, operands[1]);
5117 emit_move_insn (operands[0], scratch);
5121 ;; 32-bit Integer moves
5124 [(set (match_operand:SI 0 "register_operand" "")
5125 (match_operand:SI 1 "large_int" ""))]
5126 "!TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
5130 (ior:SI (match_dup 0)
5134 operands[2] = GEN_INT (INTVAL (operands[1]) & 0xffff0000);
5135 operands[3] = GEN_INT (INTVAL (operands[1]) & 0x0000ffff);
5138 ;; Unlike most other insns, the move insns can't be split with
5139 ;; different predicates, because register spilling and other parts of
5140 ;; the compiler, have memoized the insn number already.
5142 (define_expand "movsi"
5143 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5144 (match_operand:SI 1 "general_operand" ""))]
5148 if (mips_split_addresses && mips_check_split (operands[1], SImode))
5150 enum machine_mode mode = GET_MODE (operands[0]);
5151 rtx tem = ((reload_in_progress | reload_completed)
5152 ? operands[0] : gen_reg_rtx (mode));
5154 emit_insn (gen_rtx (SET, VOIDmode, tem,
5155 gen_rtx (HIGH, mode, operands[1])));
5157 operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
5160 /* If we are generating embedded PIC code, and we are referring to a
5161 symbol in the .text section, we must use an offset from the start
5163 if (TARGET_EMBEDDED_PIC
5164 && (GET_CODE (operands[1]) == LABEL_REF
5165 || (GET_CODE (operands[1]) == SYMBOL_REF
5166 && ! SYMBOL_REF_FLAG (operands[1]))))
5170 temp = embedded_pic_offset (operands[1]);
5171 temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
5172 force_reg (SImode, temp));
5173 emit_move_insn (operands[0], force_reg (SImode, temp));
5177 /* If operands[1] is a constant address invalid for pic, then we need to
5178 handle it just like LEGITIMIZE_ADDRESS does. */
5179 if (flag_pic && pic_address_needs_scratch (operands[1]))
5181 rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
5182 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
5184 if (! SMALL_INT (temp2))
5185 temp2 = force_reg (SImode, temp2);
5187 emit_move_insn (operands[0], gen_rtx (PLUS, SImode, temp, temp2));
5191 /* On the mips16, we can handle a GP relative reference by adding in
5192 $gp. We need to check the name to see whether this is a string
5195 && register_operand (operands[0], SImode)
5196 && GET_CODE (operands[1]) == SYMBOL_REF
5197 && SYMBOL_REF_FLAG (operands[1]))
5199 char *name = XSTR (operands[1], 0);
5202 || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5203 sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5207 if (reload_in_progress || reload_completed)
5209 /* We need to reload this address. In this case we
5210 aren't going to have a chance to combine loading the
5211 address with the load or store. That means that we
5212 can either generate a 2 byte move followed by a 4
5213 byte addition, or a 2 byte load with a 4 byte entry
5214 in the constant table. Since the entry in the
5215 constant table might be shared, we're better off, on
5216 average, loading the address from the constant table. */
5217 emit_move_insn (operands[0],
5218 force_const_mem (SImode, operands[1]));
5222 base_reg = gen_reg_rtx (Pmode);
5223 emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
5225 emit_move_insn (operands[0],
5226 gen_rtx (PLUS, Pmode, base_reg,
5227 mips16_gp_offset (operands[1])));
5232 if ((reload_in_progress | reload_completed) == 0
5233 && !register_operand (operands[0], SImode)
5234 && !register_operand (operands[1], SImode)
5236 || GET_CODE (operands[1]) != CONST_INT
5237 || INTVAL (operands[1]) != 0))
5239 rtx temp = force_reg (SImode, operands[1]);
5240 emit_move_insn (operands[0], temp);
5245 ;; For mips16, we need a special case to handle storing $31 into
5246 ;; memory, since we don't have a constraint to match $31. This
5247 ;; instruction can be generated by save_restore_insns.
5250 [(set (match_operand:SI 0 "memory_operand" "R,m")
5255 operands[1] = gen_rtx (REG, SImode, 31);
5256 return mips_move_1word (operands, insn, FALSE);
5258 [(set_attr "type" "store")
5259 (set_attr "mode" "SI")
5260 (set_attr "length" "4,8")])
5262 ;; The difference between these two is whether or not ints are allowed
5263 ;; in FP registers (off by default, use -mdebugh to enable).
5265 (define_insn "movsi_internal1"
5266 [(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")
5267 (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"))]
5268 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5269 && (register_operand (operands[0], SImode)
5270 || register_operand (operands[1], SImode)
5271 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5272 "* return mips_move_1word (operands, insn, FALSE);"
5273 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo,hilo,hilo")
5274 (set_attr "mode" "SI")
5275 (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,4,8,4,8,4,4,4,4")])
5277 (define_insn "movsi_internal2"
5278 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d")
5279 (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a"))]
5280 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5281 && (register_operand (operands[0], SImode)
5282 || register_operand (operands[1], SImode)
5283 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5284 "* return mips_move_1word (operands, insn, FALSE);"
5285 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo")
5286 (set_attr "mode" "SI")
5287 (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,4,4,4")])
5289 ;; This is the mips16 movsi instruction. We accept a small integer as
5290 ;; the source if the destination is a GP memory reference. This is
5291 ;; because we want the combine pass to turn adding a GP reference to a
5292 ;; register into a direct GP reference, but the combine pass will pass
5293 ;; in the source as a constant if it finds an equivalent one. If the
5294 ;; instruction is recognized, reload will force the constant back out
5298 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,d,R,m,*d,*d")
5299 (match_operand:SI 1 "move_operand" "d,d,y,S,K,N,s,R,m,d,d,*x,*a"))]
5301 && (register_operand (operands[0], SImode)
5302 || register_operand (operands[1], SImode)
5303 || (GET_CODE (operands[0]) == MEM
5304 && GET_CODE (XEXP (operands[0], 0)) == PLUS
5305 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST
5306 && mips16_gp_offset_p (XEXP (XEXP (operands[0], 0), 1))
5307 && GET_CODE (operands[1]) == CONST_INT
5308 && (SMALL_INT (operands[1])
5309 || SMALL_INT_UNSIGNED (operands[1]))))"
5310 "* return mips_move_1word (operands, insn, FALSE);"
5311 [(set_attr "type" "move,move,move,load,arith,arith,arith,load,load,store,store,hilo,hilo")
5312 (set_attr "mode" "SI")
5313 (set_attr_alternative "length"
5318 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5321 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5324 (if_then_else (match_operand:VOID 1 "m16_usym8_4" "")
5334 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
5335 ;; when the original load is a 4 byte instruction but the add and the
5336 ;; load are 2 2 byte instructions.
5339 [(set (match_operand:SI 0 "register_operand" "")
5340 (mem:SI (plus:SI (match_dup 0)
5341 (match_operand:SI 1 "const_int_operand" ""))))]
5342 "TARGET_MIPS16 && reload_completed
5343 && GET_CODE (operands[0]) == REG
5344 && M16_REG_P (REGNO (operands[0]))
5345 && GET_CODE (operands[1]) == CONST_INT
5346 && ((INTVAL (operands[1]) < 0
5347 && INTVAL (operands[1]) >= -0x80)
5348 || (INTVAL (operands[1]) >= 32 * 4
5349 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
5350 || (INTVAL (operands[1]) >= 0
5351 && INTVAL (operands[1]) < 32 * 4
5352 && (INTVAL (operands[1]) & 3) != 0))"
5353 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5354 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
5357 HOST_WIDE_INT val = INTVAL (operands[1]);
5360 operands[2] = GEN_INT (0);
5361 else if (val >= 32 * 4)
5365 operands[1] = GEN_INT (0x7c + off);
5366 operands[2] = GEN_INT (val - off - 0x7c);
5372 operands[1] = GEN_INT (off);
5373 operands[2] = GEN_INT (val - off);
5377 ;; On the mips16, we can split a load of certain constants into a load
5378 ;; and an add. This turns a 4 byte instruction into 2 2 byte
5382 [(set (match_operand:SI 0 "register_operand" "")
5383 (match_operand:SI 1 "const_int_operand" ""))]
5384 "TARGET_MIPS16 && reload_completed
5385 && GET_CODE (operands[0]) == REG
5386 && M16_REG_P (REGNO (operands[0]))
5387 && GET_CODE (operands[1]) == CONST_INT
5388 && INTVAL (operands[1]) >= 0x100
5389 && INTVAL (operands[1]) <= 0xff + 0x7f"
5390 [(set (match_dup 0) (match_dup 1))
5391 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
5394 int val = INTVAL (operands[1]);
5396 operands[1] = GEN_INT (0xff);
5397 operands[2] = GEN_INT (val - 0xff);
5400 ;; On the mips16, we can split a load of a negative constant into a
5401 ;; load and a neg. That's what mips_move_1word will generate anyhow.
5404 [(set (match_operand:SI 0 "register_operand" "")
5405 (match_operand:SI 1 "const_int_operand" ""))]
5406 "TARGET_MIPS16 && reload_completed
5407 && GET_CODE (operands[0]) == REG
5408 && M16_REG_P (REGNO (operands[0]))
5409 && GET_CODE (operands[1]) == CONST_INT
5410 && INTVAL (operands[1]) < 0
5411 && INTVAL (operands[1]) > - 0x8000"
5412 [(set (match_dup 0) (match_dup 1))
5413 (set (match_dup 0) (neg:SI (match_dup 0)))]
5416 operands[1] = GEN_INT (- INTVAL (operands[1]));
5419 ;; Reload HILO_REGNUM in SI mode. This needs a scratch register in
5420 ;; order to set the sign bit correctly in the HI register.
5422 (define_expand "reload_outsi"
5423 [(set (match_operand:SI 0 "general_operand" "=b")
5424 (match_operand:SI 1 "register_operand" "b"))
5425 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5426 "TARGET_64BIT || TARGET_MIPS16"
5430 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5432 emit_insn (gen_movsi (gen_rtx (REG, SImode, 65), operands[1]));
5433 emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
5434 emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
5435 emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
5438 /* Use a mult to reload LO on mips16. ??? This is hideous. */
5440 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5442 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5443 /* This is gen_mulsi3_internal, but we need to fill in the
5444 scratch registers. */
5445 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5447 gen_rtx (SET, VOIDmode,
5449 gen_rtx (MULT, SImode,
5452 gen_rtx (CLOBBER, VOIDmode,
5453 gen_rtx (REG, SImode, 64)),
5454 gen_rtx (CLOBBER, VOIDmode,
5455 gen_rtx (REG, SImode, 66)))));
5458 /* FIXME: I don't know how to get a value into the HI register. */
5459 if (GET_CODE (operands[0]) == REG
5460 && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0]))
5461 : GP_REG_P (REGNO (operands[0]))))
5463 emit_move_insn (operands[0], operands[1]);
5466 /* This handles moves between a float register and HI/LO. */
5467 emit_move_insn (operands[2], operands[1]);
5468 emit_move_insn (operands[0], operands[2]);
5472 ;; Reload a value into HI or LO. There is no mthi or mtlo on mips16,
5473 ;; so we use a mult. ??? This is hideous, and we ought to figure out
5474 ;; something better.
5476 ;; We use no predicate for operand1, because it may be a PLUS, and there
5477 ;; is no convenient predicate for that.
5479 (define_expand "reload_insi"
5480 [(set (match_operand:SI 0 "register_operand" "=b")
5481 (match_operand:SI 1 "" "b"))
5482 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5487 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5489 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5490 /* This is gen_mulsi3_internal, but we need to fill in the
5491 scratch registers. */
5492 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5494 gen_rtx (SET, VOIDmode,
5496 gen_rtx (MULT, SImode,
5499 gen_rtx (CLOBBER, VOIDmode,
5500 gen_rtx (REG, SImode, 64)),
5501 gen_rtx (CLOBBER, VOIDmode,
5502 gen_rtx (REG, SImode, 66)))));
5506 /* If this is a plus, then this must be an add of the stack pointer against
5507 either a hard register or a pseudo. */
5508 if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
5512 if (XEXP (operands[1], 0) == stack_pointer_rtx)
5513 plus_op = XEXP (operands[1], 1);
5514 else if (XEXP (operands[1], 1) == stack_pointer_rtx)
5515 plus_op = XEXP (operands[1], 0);
5519 /* We should have a register now. */
5520 if (GET_CODE (plus_op) != REG)
5523 if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
5525 /* We have to have at least one temporary register which is not
5526 overlapping plus_op. */
5527 if (! rtx_equal_p (plus_op, operands[0]))
5529 emit_move_insn (operands[0], stack_pointer_rtx);
5530 emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
5532 else if (! rtx_equal_p (plus_op, operands[2]))
5534 emit_move_insn (operands[2], stack_pointer_rtx);
5535 emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
5542 /* We need two registers in this case. */
5543 if (! rtx_equal_p (operands[0], operands[2]))
5545 emit_move_insn (operands[0], stack_pointer_rtx);
5546 emit_move_insn (operands[2], plus_op);
5547 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
5555 /* FIXME: I don't know how to get a value into the HI register. */
5556 emit_move_insn (operands[0], operands[1]);
5560 ;; This insn handles moving CCmode values. It's really just a
5561 ;; slightly simplified copy of movsi_internal2, with additional cases
5562 ;; to move a condition register to a general register and to move
5563 ;; between the general registers and the floating point registers.
5565 (define_insn "movcc"
5566 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
5567 (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
5568 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5569 "* return mips_move_1word (operands, insn, FALSE);"
5570 [(set_attr "type" "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
5571 (set_attr "mode" "SI")
5572 (set_attr "length" "8,4,4,8,4,8,4,4,4,4,8,4,8")])
5574 ;; Reload condition code registers. These need scratch registers.
5576 (define_expand "reload_incc"
5577 [(set (match_operand:CC 0 "register_operand" "=z")
5578 (match_operand:CC 1 "general_operand" "z"))
5579 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
5580 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5586 /* This is called when are copying some value into a condition code
5587 register. Operand 0 is the condition code register. Operand 1
5588 is the source. Operand 2 is a scratch register; we use TFmode
5589 because we actually need two floating point registers. */
5590 if (! ST_REG_P (true_regnum (operands[0]))
5591 || ! FP_REG_P (true_regnum (operands[2])))
5594 /* We need to get the source in SFmode so that the insn is
5596 if (GET_CODE (operands[1]) == MEM)
5597 source = change_address (operands[1], SFmode, NULL_RTX);
5598 else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
5599 source = gen_rtx (REG, SFmode, true_regnum (operands[1]));
5601 source = operands[1];
5603 fp1 = gen_rtx (REG, SFmode, REGNO (operands[2]));
5604 fp2 = gen_rtx (REG, SFmode, REGNO (operands[2]) + 1);
5606 emit_insn (gen_move_insn (fp1, source));
5607 emit_insn (gen_move_insn (fp2, gen_rtx (REG, SFmode, 0)));
5608 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
5609 gen_rtx (LT, CCmode, fp2, fp1)));
5614 (define_expand "reload_outcc"
5615 [(set (match_operand:CC 0 "general_operand" "=z")
5616 (match_operand:CC 1 "register_operand" "z"))
5617 (clobber (match_operand:CC 2 "register_operand" "=&d"))]
5618 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5621 /* This is called when we are copying a condition code register out
5622 to save it somewhere. Operand 0 should be the location we are
5623 going to save it to. Operand 1 should be the condition code
5624 register. Operand 2 should be a scratch general purpose register
5625 created for us by reload. The mips_secondary_reload_class
5626 function should have told reload that we don't need a scratch
5627 register if the destination is a general purpose register anyhow. */
5628 if (ST_REG_P (true_regnum (operands[0]))
5629 || GP_REG_P (true_regnum (operands[0]))
5630 || ! ST_REG_P (true_regnum (operands[1]))
5631 || ! GP_REG_P (true_regnum (operands[2])))
5634 /* All we have to do is copy the value from the condition code to
5635 the data register, which movcc can handle, and then store the
5636 value into the real final destination. */
5637 emit_insn (gen_move_insn (operands[2], operands[1]));
5638 emit_insn (gen_move_insn (operands[0], operands[2]));
5643 ;; MIPS4 supports loading and storing a floating point register from
5644 ;; the sum of two general registers. We use two versions for each of
5645 ;; these four instructions: one where the two general registers are
5646 ;; SImode, and one where they are DImode. This is because general
5647 ;; registers will be in SImode when they hold 32 bit values, but,
5648 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
5649 ;; instructions will still work correctly.
5651 ;; ??? Perhaps it would be better to support these instructions by
5652 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
5653 ;; these instructions can only be used to load and store floating
5654 ;; point registers, that would probably cause trouble in reload.
5657 [(set (match_operand:SF 0 "register_operand" "=f")
5658 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5659 (match_operand:SI 2 "register_operand" "d"))))]
5660 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5662 [(set_attr "type" "load")
5663 (set_attr "mode" "SF")])
5666 [(set (match_operand:SF 0 "register_operand" "=f")
5667 (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5668 (match_operand:DI 2 "se_register_operand" "d"))))]
5669 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5671 [(set_attr "type" "load")
5672 (set_attr "mode" "SF")])
5675 [(set (match_operand:DF 0 "register_operand" "=f")
5676 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5677 (match_operand:SI 2 "register_operand" "d"))))]
5678 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5680 [(set_attr "type" "load")
5681 (set_attr "mode" "DF")])
5684 [(set (match_operand:DF 0 "register_operand" "=f")
5685 (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5686 (match_operand:DI 2 "se_register_operand" "d"))))]
5687 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5689 [(set_attr "type" "load")
5690 (set_attr "mode" "DF")])
5693 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5694 (match_operand:SI 2 "register_operand" "d")))
5695 (match_operand:SF 0 "register_operand" "=f"))]
5696 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5698 [(set_attr "type" "store")
5699 (set_attr "mode" "SF")])
5702 [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5703 (match_operand:DI 2 "se_register_operand" "d")))
5704 (match_operand:SF 0 "register_operand" "=f"))]
5705 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5707 [(set_attr "type" "store")
5708 (set_attr "mode" "SF")])
5711 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5712 (match_operand:SI 2 "register_operand" "d")))
5713 (match_operand:DF 0 "register_operand" "=f"))]
5714 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5716 [(set_attr "type" "store")
5717 (set_attr "mode" "DF")])
5720 [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5721 (match_operand:DI 2 "se_register_operand" "d")))
5722 (match_operand:DF 0 "register_operand" "=f"))]
5723 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5725 [(set_attr "type" "store")
5726 (set_attr "mode" "DF")])
5728 ;; 16-bit Integer moves
5730 ;; Unlike most other insns, the move insns can't be split with
5731 ;; different predicates, because register spilling and other parts of
5732 ;; the compiler, have memoized the insn number already.
5733 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5735 (define_expand "movhi"
5736 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5737 (match_operand:HI 1 "general_operand" ""))]
5741 if ((reload_in_progress | reload_completed) == 0
5742 && !register_operand (operands[0], HImode)
5743 && !register_operand (operands[1], HImode)
5745 || (GET_CODE (operands[1]) != CONST_INT
5746 || INTVAL (operands[1]) != 0)))
5748 rtx temp = force_reg (HImode, operands[1]);
5749 emit_move_insn (operands[0], temp);
5754 ;; The difference between these two is whether or not ints are allowed
5755 ;; in FP registers (off by default, use -mdebugh to enable).
5757 (define_insn "movhi_internal1"
5758 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
5759 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
5760 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5761 && (register_operand (operands[0], HImode)
5762 || register_operand (operands[1], HImode)
5763 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5764 "* return mips_move_1word (operands, insn, TRUE);"
5765 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
5766 (set_attr "mode" "HI")
5767 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
5769 (define_insn "movhi_internal2"
5770 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
5771 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
5772 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5773 && (register_operand (operands[0], HImode)
5774 || register_operand (operands[1], HImode)
5775 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5776 "* return mips_move_1word (operands, insn, TRUE);"
5777 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
5778 (set_attr "mode" "HI")
5779 (set_attr "length" "4,4,4,8,4,8,4,4,4,4")])
5782 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
5783 (match_operand:HI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
5785 && (register_operand (operands[0], HImode)
5786 || register_operand (operands[1], HImode))"
5787 "* return mips_move_1word (operands, insn, TRUE);"
5788 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
5789 (set_attr "mode" "HI")
5790 (set_attr_alternative "length"
5794 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5797 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5807 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
5808 ;; when the original load is a 4 byte instruction but the add and the
5809 ;; load are 2 2 byte instructions.
5812 [(set (match_operand:HI 0 "register_operand" "")
5813 (mem:HI (plus:SI (match_dup 0)
5814 (match_operand:SI 1 "const_int_operand" ""))))]
5815 "TARGET_MIPS16 && reload_completed
5816 && GET_CODE (operands[0]) == REG
5817 && M16_REG_P (REGNO (operands[0]))
5818 && GET_CODE (operands[1]) == CONST_INT
5819 && ((INTVAL (operands[1]) < 0
5820 && INTVAL (operands[1]) >= -0x80)
5821 || (INTVAL (operands[1]) >= 32 * 2
5822 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
5823 || (INTVAL (operands[1]) >= 0
5824 && INTVAL (operands[1]) < 32 * 2
5825 && (INTVAL (operands[1]) & 1) != 0))"
5826 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5827 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
5830 HOST_WIDE_INT val = INTVAL (operands[1]);
5833 operands[2] = GEN_INT (0);
5834 else if (val >= 32 * 2)
5838 operands[1] = GEN_INT (0x7e + off);
5839 operands[2] = GEN_INT (val - off - 0x7e);
5845 operands[1] = GEN_INT (off);
5846 operands[2] = GEN_INT (val - off);
5850 ;; 8-bit Integer moves
5852 ;; Unlike most other insns, the move insns can't be split with
5853 ;; different predicates, because register spilling and other parts of
5854 ;; the compiler, have memoized the insn number already.
5855 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5857 (define_expand "movqi"
5858 [(set (match_operand:QI 0 "nonimmediate_operand" "")
5859 (match_operand:QI 1 "general_operand" ""))]
5863 if ((reload_in_progress | reload_completed) == 0
5864 && !register_operand (operands[0], QImode)
5865 && !register_operand (operands[1], QImode)
5867 || (GET_CODE (operands[1]) != CONST_INT
5868 || INTVAL (operands[1]) != 0)))
5870 rtx temp = force_reg (QImode, operands[1]);
5871 emit_move_insn (operands[0], temp);
5876 ;; The difference between these two is whether or not ints are allowed
5877 ;; in FP registers (off by default, use -mdebugh to enable).
5879 (define_insn "movqi_internal1"
5880 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
5881 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
5882 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5883 && (register_operand (operands[0], QImode)
5884 || register_operand (operands[1], QImode)
5885 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5886 "* return mips_move_1word (operands, insn, TRUE);"
5887 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
5888 (set_attr "mode" "QI")
5889 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
5891 (define_insn "movqi_internal2"
5892 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
5893 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
5894 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5895 && (register_operand (operands[0], QImode)
5896 || register_operand (operands[1], QImode)
5897 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5898 "* return mips_move_1word (operands, insn, TRUE);"
5899 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
5900 (set_attr "mode" "QI")
5901 (set_attr "length" "4,4,4,8,4,8,4,4,4,4")])
5904 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
5905 (match_operand:QI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
5907 && (register_operand (operands[0], QImode)
5908 || register_operand (operands[1], QImode))"
5909 "* return mips_move_1word (operands, insn, TRUE);"
5910 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
5911 (set_attr "mode" "QI")
5912 (set_attr_alternative "length"
5916 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5919 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5929 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
5930 ;; when the original load is a 4 byte instruction but the add and the
5931 ;; load are 2 2 byte instructions.
5934 [(set (match_operand:QI 0 "register_operand" "")
5935 (mem:QI (plus:SI (match_dup 0)
5936 (match_operand:SI 1 "const_int_operand" ""))))]
5937 "TARGET_MIPS16 && reload_completed
5938 && GET_CODE (operands[0]) == REG
5939 && M16_REG_P (REGNO (operands[0]))
5940 && GET_CODE (operands[1]) == CONST_INT
5941 && ((INTVAL (operands[1]) < 0
5942 && INTVAL (operands[1]) >= -0x80)
5943 || (INTVAL (operands[1]) >= 32
5944 && INTVAL (operands[1]) <= 31 + 0x7f))"
5945 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5946 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
5949 HOST_WIDE_INT val = INTVAL (operands[1]);
5952 operands[2] = GEN_INT (0);
5955 operands[1] = GEN_INT (0x7f);
5956 operands[2] = GEN_INT (val - 0x7f);
5960 ;; 32-bit floating point moves
5962 (define_expand "movsf"
5963 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5964 (match_operand:SF 1 "general_operand" ""))]
5968 if ((reload_in_progress | reload_completed) == 0
5969 && !register_operand (operands[0], SFmode)
5970 && !register_operand (operands[1], SFmode)
5972 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
5973 && operands[1] != CONST0_RTX (SFmode))))
5975 rtx temp = force_reg (SFmode, operands[1]);
5976 emit_move_insn (operands[0], temp);
5981 (define_insn "movsf_internal1"
5982 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
5983 (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
5985 && (register_operand (operands[0], SFmode)
5986 || register_operand (operands[1], SFmode)
5987 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5988 || operands[1] == CONST0_RTX (SFmode))"
5989 "* return mips_move_1word (operands, insn, FALSE);"
5990 [(set_attr "type" "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
5991 (set_attr "mode" "SF")
5992 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,8,4,8")])
5995 (define_insn "movsf_internal2"
5996 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
5997 (match_operand:SF 1 "general_operand" " Gd,R,Fm,d,d"))]
5998 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
5999 && (register_operand (operands[0], SFmode)
6000 || register_operand (operands[1], SFmode)
6001 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6002 || operands[1] == CONST0_RTX (SFmode))"
6003 "* return mips_move_1word (operands, insn, FALSE);"
6004 [(set_attr "type" "move,load,load,store,store")
6005 (set_attr "mode" "SF")
6006 (set_attr "length" "4,4,8,4,8")])
6009 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m")
6010 (match_operand:SF 1 "general_operand" "d,d,y,R,Fm,d,d"))]
6012 && (register_operand (operands[0], SFmode)
6013 || register_operand (operands[1], SFmode))"
6014 "* return mips_move_1word (operands, insn, FALSE);"
6015 [(set_attr "type" "move,move,move,load,load,store,store")
6016 (set_attr "mode" "SF")
6017 (set_attr "length" "4,4,4,4,8,4,8")])
6020 ;; 64-bit floating point moves
6022 (define_expand "movdf"
6023 [(set (match_operand:DF 0 "nonimmediate_operand" "")
6024 (match_operand:DF 1 "general_operand" ""))]
6028 if ((reload_in_progress | reload_completed) == 0
6029 && !register_operand (operands[0], DFmode)
6030 && !register_operand (operands[1], DFmode)
6032 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6033 && operands[1] != CONST0_RTX (DFmode))))
6035 rtx temp = force_reg (DFmode, operands[1]);
6036 emit_move_insn (operands[0], temp);
6041 (define_insn "movdf_internal1"
6042 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,To,f,*f,*d,*d,*d,*d,*R,*T")
6043 (match_operand:DF 1 "general_operand" "f,R,To,fG,fG,F,*d,*f,*d*G,*R,*T*F,*d,*d"))]
6044 "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
6045 && TARGET_DOUBLE_FLOAT
6046 && (register_operand (operands[0], DFmode)
6047 || register_operand (operands[1], DFmode)
6048 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6049 || operands[1] == CONST0_RTX (DFmode))"
6050 "* return mips_move_2words (operands, insn); "
6051 [(set_attr "type" "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
6052 (set_attr "mode" "DF")
6053 (set_attr "length" "4,8,16,8,16,16,8,8,8,8,16,8,16")])
6055 (define_insn "movdf_internal1a"
6056 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,f,*d,*d,*d,*To,*R")
6057 (match_operand:DF 1 "general_operand" " f,To,f,G,f,G,F,*F,*To,*R,*d,*d"))]
6058 "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
6059 && TARGET_DOUBLE_FLOAT
6060 && (register_operand (operands[0], DFmode)
6061 || register_operand (operands[1], DFmode)
6062 || (GET_CODE (operands [0]) == MEM
6063 && ((GET_CODE (operands[1]) == CONST_INT
6064 && INTVAL (operands[1]) == 0)
6065 || operands[1] == CONST0_RTX (DFmode))))"
6066 "* return mips_move_2words (operands, insn); "
6067 [(set_attr "type" "move,load,store,store,store,store,load,load,load,load,store,store")
6068 (set_attr "mode" "DF")
6069 (set_attr "length" "4,8,4,4,8,8,8,8,8,4,8,4")])
6071 (define_insn "movdf_internal2"
6072 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To")
6073 (match_operand:DF 1 "general_operand" "dG,R,ToF,d,d"))]
6074 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
6075 && (register_operand (operands[0], DFmode)
6076 || register_operand (operands[1], DFmode)
6077 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6078 || operands[1] == CONST0_RTX (DFmode))"
6079 "* return mips_move_2words (operands, insn); "
6080 [(set_attr "type" "move,load,load,store,store")
6081 (set_attr "mode" "DF")
6082 (set_attr "length" "8,8,16,8,16")])
6085 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To")
6086 (match_operand:DF 1 "general_operand" "d,d,y,R,ToF,d,d"))]
6088 && (register_operand (operands[0], DFmode)
6089 || register_operand (operands[1], DFmode))"
6090 "* return mips_move_2words (operands, insn);"
6091 [(set_attr "type" "move,move,move,load,load,store,store")
6092 (set_attr "mode" "DF")
6093 (set_attr "length" "8,8,8,8,16,8,16")])
6096 [(set (match_operand:DF 0 "register_operand" "")
6097 (match_operand:DF 1 "register_operand" ""))]
6098 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6099 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
6100 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
6101 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
6102 (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
6105 ;; Instructions to load the global pointer register.
6106 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
6107 ;; uses in front of it. All symbol_refs implicitly use the gp reg.
6109 (define_insn "loadgp"
6111 (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
6112 (match_operand:DI 1 "register_operand" "")] 2))
6113 (clobber (reg:DI 1))]
6115 "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]"
6116 [(set_attr "type" "move")
6117 (set_attr "mode" "DI")
6118 (set_attr "length" "12")])
6120 ;; Block moves, see mips.c for more details.
6121 ;; Argument 0 is the destination
6122 ;; Argument 1 is the source
6123 ;; Argument 2 is the length
6124 ;; Argument 3 is the alignment
6126 (define_expand "movstrsi"
6127 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
6128 (match_operand:BLK 1 "general_operand" ""))
6129 (use (match_operand:SI 2 "arith32_operand" ""))
6130 (use (match_operand:SI 3 "immediate_operand" ""))])]
6134 if (operands[0]) /* avoid unused code messages */
6136 expand_block_move (operands);
6141 ;; Insn generated by block moves
6143 (define_insn "movstrsi_internal"
6144 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6145 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6146 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6147 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6148 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6149 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6150 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6151 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6152 (use (const_int 0))] ;; normal block move
6154 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6155 [(set_attr "type" "store")
6156 (set_attr "mode" "none")
6157 (set_attr "length" "80")])
6159 ;; We need mips16 versions, because an offset from the stack pointer
6160 ;; is not offsettable, since the stack pointer can only handle 4 and 8
6164 [(set (match_operand:BLK 0 "memory_operand" "=d") ;; destination
6165 (match_operand:BLK 1 "memory_operand" "d")) ;; source
6166 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6167 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6168 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6169 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6170 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6171 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6172 (use (const_int 0))] ;; normal block move
6174 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6175 [(set_attr "type" "multi")
6176 (set_attr "mode" "none")
6177 (set_attr "length" "80")])
6180 [(set (match_operand:BLK 0 "memory_operand" "=d") ;; destination
6181 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6182 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6183 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6184 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6185 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6186 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6187 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6188 (use (const_int 0))] ;; normal block move
6190 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6191 [(set_attr "type" "multi")
6192 (set_attr "mode" "none")
6193 (set_attr "length" "80")])
6196 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6197 (match_operand:BLK 1 "memory_operand" "d")) ;; source
6198 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6199 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6200 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6201 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6202 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6203 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6204 (use (const_int 0))] ;; normal block move
6206 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6207 [(set_attr "type" "multi")
6208 (set_attr "mode" "none")
6209 (set_attr "length" "80")])
6211 ;; Split a block move into 2 parts, the first part is everything
6212 ;; except for the last move, and the second part is just the last
6213 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
6214 ;; fill a delay slot. This also prevents a bug in delayed branches
6215 ;; from showing up, which reuses one of the registers in our clobbers.
6218 [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
6219 (mem:BLK (match_operand:SI 1 "register_operand" "")))
6220 (clobber (match_operand:SI 4 "register_operand" ""))
6221 (clobber (match_operand:SI 5 "register_operand" ""))
6222 (clobber (match_operand:SI 6 "register_operand" ""))
6223 (clobber (match_operand:SI 7 "register_operand" ""))
6224 (use (match_operand:SI 2 "small_int" ""))
6225 (use (match_operand:SI 3 "small_int" ""))
6226 (use (const_int 0))]
6228 "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
6230 ;; All but the last move
6231 [(parallel [(set (mem:BLK (match_dup 0))
6232 (mem:BLK (match_dup 1)))
6233 (clobber (match_dup 4))
6234 (clobber (match_dup 5))
6235 (clobber (match_dup 6))
6236 (clobber (match_dup 7))
6239 (use (const_int 1))])
6241 ;; The last store, so it can fill a delay slot
6242 (parallel [(set (mem:BLK (match_dup 0))
6243 (mem:BLK (match_dup 1)))
6244 (clobber (match_dup 4))
6245 (clobber (match_dup 5))
6246 (clobber (match_dup 6))
6247 (clobber (match_dup 7))
6250 (use (const_int 2))])]
6254 (define_insn "movstrsi_internal2"
6255 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6256 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6257 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6258 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6259 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6260 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6261 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6262 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6263 (use (const_int 1))] ;; all but last store
6265 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6266 [(set_attr "type" "store")
6267 (set_attr "mode" "none")
6268 (set_attr "length" "80")])
6271 [(set (match_operand:BLK 0 "memory_operand" "=d") ;; destination
6272 (match_operand:BLK 1 "memory_operand" "d")) ;; source
6273 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6274 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6275 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6276 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6277 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6278 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6279 (use (const_int 1))] ;; all but last store
6281 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6282 [(set_attr "type" "multi")
6283 (set_attr "mode" "none")
6284 (set_attr "length" "80")])
6286 (define_insn "movstrsi_internal3"
6287 [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
6288 (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
6289 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6290 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6291 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6292 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6293 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6294 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6295 (use (const_int 2))] ;; just last store of block move
6297 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6298 [(set_attr "type" "store")
6299 (set_attr "mode" "none")])
6302 [(set (match_operand:BLK 0 "memory_operand" "=d") ;; destination
6303 (match_operand:BLK 1 "memory_operand" "d")) ;; source
6304 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6305 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6306 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6307 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6308 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6309 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6310 (use (const_int 2))] ;; just last store of block move
6312 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6313 [(set_attr "type" "store")
6314 (set_attr "mode" "none")])
6318 ;; ....................
6322 ;; ....................
6324 ;; Many of these instructions uses trivial define_expands, because we
6325 ;; want to use a different set of constraints when TARGET_MIPS16.
6327 (define_expand "ashlsi3"
6328 [(set (match_operand:SI 0 "register_operand" "=d")
6329 (ashift:SI (match_operand:SI 1 "register_operand" "d")
6330 (match_operand:SI 2 "arith_operand" "dI")))]
6334 /* On the mips16, a shift of more than 8 is a four byte instruction,
6335 so, for a shift between 8 and 16, it is just as fast to do two
6336 shifts of 8 or less. If there is a lot of shifting going on, we
6337 may win in CSE. Otherwise combine will put the shifts back
6338 together again. This can be called by function_arg, so we must
6339 be careful not to allocate a new register if we've reached the
6343 && GET_CODE (operands[2]) == CONST_INT
6344 && INTVAL (operands[2]) > 8
6345 && INTVAL (operands[2]) <= 16
6346 && ! reload_in_progress
6347 && ! reload_completed)
6349 rtx temp = gen_reg_rtx (SImode);
6351 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
6352 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
6353 GEN_INT (INTVAL (operands[2]) - 8)));
6358 (define_insn "ashlsi3_internal1"
6359 [(set (match_operand:SI 0 "register_operand" "=d")
6360 (ashift:SI (match_operand:SI 1 "register_operand" "d")
6361 (match_operand:SI 2 "arith_operand" "dI")))]
6365 if (GET_CODE (operands[2]) == CONST_INT)
6366 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6368 return \"sll\\t%0,%1,%2\";
6370 [(set_attr "type" "arith")
6371 (set_attr "mode" "SI")])
6373 (define_insn "ashlsi3_internal2"
6374 [(set (match_operand:SI 0 "register_operand" "=d,d")
6375 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
6376 (match_operand:SI 2 "arith_operand" "d,I")))]
6380 if (which_alternative == 0)
6381 return \"sll\\t%0,%2\";
6383 if (GET_CODE (operands[2]) == CONST_INT)
6384 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6386 return \"sll\\t%0,%1,%2\";
6388 [(set_attr "type" "arith")
6389 (set_attr "mode" "SI")
6390 (set_attr_alternative "length"
6392 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6396 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6399 [(set (match_operand:SI 0 "register_operand" "")
6400 (ashift:SI (match_operand:SI 1 "register_operand" "")
6401 (match_operand:SI 2 "const_int_operand" "")))]
6404 && GET_CODE (operands[2]) == CONST_INT
6405 && INTVAL (operands[2]) > 8
6406 && INTVAL (operands[2]) <= 16"
6407 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
6408 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
6411 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6414 (define_expand "ashldi3"
6415 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6416 (ashift:DI (match_operand:DI 1 "se_register_operand" "")
6417 (match_operand:SI 2 "arith_operand" "")))
6418 (clobber (match_dup 3))])]
6419 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6424 /* On the mips16, a shift of more than 8 is a four byte
6425 instruction, so, for a shift between 8 and 16, it is just as
6426 fast to do two shifts of 8 or less. If there is a lot of
6427 shifting going on, we may win in CSE. Otherwise combine will
6428 put the shifts back together again. This can be called by
6429 function_arg, so we must be careful not to allocate a new
6430 register if we've reached the reload pass. */
6433 && GET_CODE (operands[2]) == CONST_INT
6434 && INTVAL (operands[2]) > 8
6435 && INTVAL (operands[2]) <= 16
6436 && ! reload_in_progress
6437 && ! reload_completed)
6439 rtx temp = gen_reg_rtx (DImode);
6441 emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
6442 emit_insn (gen_ashldi3_internal4 (operands[0], temp,
6443 GEN_INT (INTVAL (operands[2]) - 8)));
6447 emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
6452 operands[3] = gen_reg_rtx (SImode);
6456 (define_insn "ashldi3_internal"
6457 [(set (match_operand:DI 0 "register_operand" "=&d")
6458 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6459 (match_operand:SI 2 "register_operand" "d")))
6460 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6461 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6464 operands[4] = const0_rtx;
6465 dslots_jump_total += 3;
6466 dslots_jump_filled += 2;
6468 return \"sll\\t%3,%2,26\\n\\
6469 \\tbgez\\t%3,1f\\n\\
6470 \\tsll\\t%M0,%L1,%2\\n\\
6472 \\tmove\\t%L0,%z4%)\\n\\
6475 \\t%(beq\\t%3,%z4,2f\\n\\
6476 \\tsll\\t%M0,%M1,%2%)\\n\\
6478 \\tsubu\\t%3,%z4,%2\\n\\
6479 \\tsrl\\t%3,%L1,%3\\n\\
6480 \\tor\\t%M0,%M0,%3\\n\\
6482 \\tsll\\t%L0,%L1,%2\\n\\
6485 [(set_attr "type" "darith")
6486 (set_attr "mode" "SI")
6487 (set_attr "length" "48")])
6490 (define_insn "ashldi3_internal2"
6491 [(set (match_operand:DI 0 "register_operand" "=d")
6492 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6493 (match_operand:SI 2 "small_int" "IJK")))
6494 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6495 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6496 && (INTVAL (operands[2]) & 32) != 0"
6499 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6500 operands[4] = const0_rtx;
6501 return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
6503 [(set_attr "type" "darith")
6504 (set_attr "mode" "DI")
6505 (set_attr "length" "8")])
6509 [(set (match_operand:DI 0 "register_operand" "")
6510 (ashift:DI (match_operand:DI 1 "register_operand" "")
6511 (match_operand:SI 2 "small_int" "")))
6512 (clobber (match_operand:SI 3 "register_operand" ""))]
6513 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6514 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6515 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6516 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6517 && (INTVAL (operands[2]) & 32) != 0"
6519 [(set (subreg:SI (match_dup 0) 1) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6520 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6522 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6526 [(set (match_operand:DI 0 "register_operand" "")
6527 (ashift:DI (match_operand:DI 1 "register_operand" "")
6528 (match_operand:SI 2 "small_int" "")))
6529 (clobber (match_operand:SI 3 "register_operand" ""))]
6530 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6531 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6532 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6533 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6534 && (INTVAL (operands[2]) & 32) != 0"
6536 [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
6537 (set (subreg:SI (match_dup 0) 1) (const_int 0))]
6539 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6542 (define_insn "ashldi3_internal3"
6543 [(set (match_operand:DI 0 "register_operand" "=d")
6544 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6545 (match_operand:SI 2 "small_int" "IJK")))
6546 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6547 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6548 && (INTVAL (operands[2]) & 63) < 32
6549 && (INTVAL (operands[2]) & 63) != 0"
6552 int amount = INTVAL (operands[2]);
6554 operands[2] = GEN_INT ((amount & 31));
6555 operands[4] = const0_rtx;
6556 operands[5] = GEN_INT (((-amount) & 31));
6558 return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
6560 [(set_attr "type" "darith")
6561 (set_attr "mode" "DI")
6562 (set_attr "length" "16")])
6566 [(set (match_operand:DI 0 "register_operand" "")
6567 (ashift:DI (match_operand:DI 1 "register_operand" "")
6568 (match_operand:SI 2 "small_int" "")))
6569 (clobber (match_operand:SI 3 "register_operand" ""))]
6570 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6571 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6572 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6573 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6574 && (INTVAL (operands[2]) & 63) < 32
6575 && (INTVAL (operands[2]) & 63) != 0"
6577 [(set (subreg:SI (match_dup 0) 1)
6578 (ashift:SI (subreg:SI (match_dup 1) 1)
6582 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6585 (set (subreg:SI (match_dup 0) 1)
6586 (ior:SI (subreg:SI (match_dup 0) 1)
6589 (set (subreg:SI (match_dup 0) 0)
6590 (ashift:SI (subreg:SI (match_dup 1) 0)
6594 int amount = INTVAL (operands[2]);
6595 operands[2] = GEN_INT ((amount & 31));
6596 operands[4] = GEN_INT (((-amount) & 31));
6601 [(set (match_operand:DI 0 "register_operand" "")
6602 (ashift:DI (match_operand:DI 1 "register_operand" "")
6603 (match_operand:SI 2 "small_int" "")))
6604 (clobber (match_operand:SI 3 "register_operand" ""))]
6605 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6606 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6607 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6608 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6609 && (INTVAL (operands[2]) & 63) < 32
6610 && (INTVAL (operands[2]) & 63) != 0"
6612 [(set (subreg:SI (match_dup 0) 0)
6613 (ashift:SI (subreg:SI (match_dup 1) 0)
6617 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
6620 (set (subreg:SI (match_dup 0) 0)
6621 (ior:SI (subreg:SI (match_dup 0) 0)
6624 (set (subreg:SI (match_dup 0) 1)
6625 (ashift:SI (subreg:SI (match_dup 1) 1)
6629 int amount = INTVAL (operands[2]);
6630 operands[2] = GEN_INT ((amount & 31));
6631 operands[4] = GEN_INT (((-amount) & 31));
6635 (define_insn "ashldi3_internal4"
6636 [(set (match_operand:DI 0 "register_operand" "=d")
6637 (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
6638 (match_operand:SI 2 "arith_operand" "dI")))]
6639 "TARGET_64BIT && !TARGET_MIPS16"
6642 if (GET_CODE (operands[2]) == CONST_INT)
6643 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6645 return \"dsll\\t%0,%1,%2\";
6647 [(set_attr "type" "arith")
6648 (set_attr "mode" "DI")])
6651 [(set (match_operand:DI 0 "register_operand" "=d,d")
6652 (ashift:DI (match_operand:DI 1 "se_register_operand" "0,d")
6653 (match_operand:SI 2 "arith_operand" "d,I")))]
6654 "TARGET_64BIT && TARGET_MIPS16"
6657 if (which_alternative == 0)
6658 return \"dsll\\t%0,%2\";
6660 if (GET_CODE (operands[2]) == CONST_INT)
6661 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6663 return \"dsll\\t%0,%1,%2\";
6665 [(set_attr "type" "arith")
6666 (set_attr "mode" "DI")
6667 (set_attr_alternative "length"
6669 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6674 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6677 [(set (match_operand:DI 0 "register_operand" "")
6678 (ashift:DI (match_operand:DI 1 "register_operand" "")
6679 (match_operand:SI 2 "const_int_operand" "")))]
6680 "TARGET_MIPS16 && TARGET_64BIT
6682 && GET_CODE (operands[2]) == CONST_INT
6683 && INTVAL (operands[2]) > 8
6684 && INTVAL (operands[2]) <= 16"
6685 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
6686 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
6689 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6692 (define_expand "ashrsi3"
6693 [(set (match_operand:SI 0 "register_operand" "=d")
6694 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6695 (match_operand:SI 2 "arith_operand" "dI")))]
6699 /* On the mips16, a shift of more than 8 is a four byte instruction,
6700 so, for a shift between 8 and 16, it is just as fast to do two
6701 shifts of 8 or less. If there is a lot of shifting going on, we
6702 may win in CSE. Otherwise combine will put the shifts back
6706 && GET_CODE (operands[2]) == CONST_INT
6707 && INTVAL (operands[2]) > 8
6708 && INTVAL (operands[2]) <= 16)
6710 rtx temp = gen_reg_rtx (SImode);
6712 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6713 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
6714 GEN_INT (INTVAL (operands[2]) - 8)));
6719 (define_insn "ashrsi3_internal1"
6720 [(set (match_operand:SI 0 "register_operand" "=d")
6721 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6722 (match_operand:SI 2 "arith_operand" "dI")))]
6726 if (GET_CODE (operands[2]) == CONST_INT)
6727 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6729 return \"sra\\t%0,%1,%2\";
6731 [(set_attr "type" "arith")
6732 (set_attr "mode" "SI")])
6734 (define_insn "ashrsi3_internal2"
6735 [(set (match_operand:SI 0 "register_operand" "=d,d")
6736 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6737 (match_operand:SI 2 "arith_operand" "d,I")))]
6741 if (which_alternative == 0)
6742 return \"sra\\t%0,%2\";
6744 if (GET_CODE (operands[2]) == CONST_INT)
6745 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6747 return \"sra\\t%0,%1,%2\";
6749 [(set_attr "type" "arith")
6750 (set_attr "mode" "SI")
6751 (set_attr_alternative "length"
6753 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6758 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6761 [(set (match_operand:SI 0 "register_operand" "")
6762 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6763 (match_operand:SI 2 "const_int_operand" "")))]
6766 && GET_CODE (operands[2]) == CONST_INT
6767 && INTVAL (operands[2]) > 8
6768 && INTVAL (operands[2]) <= 16"
6769 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
6770 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
6773 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6776 (define_expand "ashrdi3"
6777 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6778 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
6779 (match_operand:SI 2 "arith_operand" "")))
6780 (clobber (match_dup 3))])]
6781 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6786 /* On the mips16, a shift of more than 8 is a four byte
6787 instruction, so, for a shift between 8 and 16, it is just as
6788 fast to do two shifts of 8 or less. If there is a lot of
6789 shifting going on, we may win in CSE. Otherwise combine will
6790 put the shifts back together again. */
6793 && GET_CODE (operands[2]) == CONST_INT
6794 && INTVAL (operands[2]) > 8
6795 && INTVAL (operands[2]) <= 16)
6797 rtx temp = gen_reg_rtx (DImode);
6799 emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
6800 emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
6801 GEN_INT (INTVAL (operands[2]) - 8)));
6805 emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
6810 operands[3] = gen_reg_rtx (SImode);
6814 (define_insn "ashrdi3_internal"
6815 [(set (match_operand:DI 0 "register_operand" "=&d")
6816 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6817 (match_operand:SI 2 "register_operand" "d")))
6818 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6819 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6822 operands[4] = const0_rtx;
6823 dslots_jump_total += 3;
6824 dslots_jump_filled += 2;
6826 return \"sll\\t%3,%2,26\\n\\
6827 \\tbgez\\t%3,1f\\n\\
6828 \\tsra\\t%L0,%M1,%2\\n\\
6830 \\tsra\\t%M0,%M1,31%)\\n\\
6833 \\t%(beq\\t%3,%z4,2f\\n\\
6834 \\tsrl\\t%L0,%L1,%2%)\\n\\
6836 \\tsubu\\t%3,%z4,%2\\n\\
6837 \\tsll\\t%3,%M1,%3\\n\\
6838 \\tor\\t%L0,%L0,%3\\n\\
6840 \\tsra\\t%M0,%M1,%2\\n\\
6843 [(set_attr "type" "darith")
6844 (set_attr "mode" "DI")
6845 (set_attr "length" "48")])
6848 (define_insn "ashrdi3_internal2"
6849 [(set (match_operand:DI 0 "register_operand" "=d")
6850 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6851 (match_operand:SI 2 "small_int" "IJK")))
6852 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6853 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
6856 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6857 return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
6859 [(set_attr "type" "darith")
6860 (set_attr "mode" "DI")
6861 (set_attr "length" "8")])
6865 [(set (match_operand:DI 0 "register_operand" "")
6866 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6867 (match_operand:SI 2 "small_int" "")))
6868 (clobber (match_operand:SI 3 "register_operand" ""))]
6869 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6870 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6871 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6872 && (INTVAL (operands[2]) & 32) != 0"
6874 [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
6875 (set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (const_int 31)))]
6877 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6881 [(set (match_operand:DI 0 "register_operand" "")
6882 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6883 (match_operand:SI 2 "small_int" "")))
6884 (clobber (match_operand:SI 3 "register_operand" ""))]
6885 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6886 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6887 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6888 && (INTVAL (operands[2]) & 32) != 0"
6890 [(set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6891 (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
6893 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6896 (define_insn "ashrdi3_internal3"
6897 [(set (match_operand:DI 0 "register_operand" "=d")
6898 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6899 (match_operand:SI 2 "small_int" "IJK")))
6900 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6901 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6902 && (INTVAL (operands[2]) & 63) < 32
6903 && (INTVAL (operands[2]) & 63) != 0"
6906 int amount = INTVAL (operands[2]);
6908 operands[2] = GEN_INT ((amount & 31));
6909 operands[4] = GEN_INT (((-amount) & 31));
6911 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
6913 [(set_attr "type" "darith")
6914 (set_attr "mode" "DI")
6915 (set_attr "length" "16")])
6919 [(set (match_operand:DI 0 "register_operand" "")
6920 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6921 (match_operand:SI 2 "small_int" "")))
6922 (clobber (match_operand:SI 3 "register_operand" ""))]
6923 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6924 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6925 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6926 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6927 && (INTVAL (operands[2]) & 63) < 32
6928 && (INTVAL (operands[2]) & 63) != 0"
6930 [(set (subreg:SI (match_dup 0) 0)
6931 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6935 (ashift:SI (subreg:SI (match_dup 1) 1)
6938 (set (subreg:SI (match_dup 0) 0)
6939 (ior:SI (subreg:SI (match_dup 0) 0)
6942 (set (subreg:SI (match_dup 0) 1)
6943 (ashiftrt:SI (subreg:SI (match_dup 1) 1)
6947 int amount = INTVAL (operands[2]);
6948 operands[2] = GEN_INT ((amount & 31));
6949 operands[4] = GEN_INT (((-amount) & 31));
6954 [(set (match_operand:DI 0 "register_operand" "")
6955 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6956 (match_operand:SI 2 "small_int" "")))
6957 (clobber (match_operand:SI 3 "register_operand" ""))]
6958 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6959 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6960 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6961 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6962 && (INTVAL (operands[2]) & 63) < 32
6963 && (INTVAL (operands[2]) & 63) != 0"
6965 [(set (subreg:SI (match_dup 0) 1)
6966 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
6970 (ashift:SI (subreg:SI (match_dup 1) 0)
6973 (set (subreg:SI (match_dup 0) 1)
6974 (ior:SI (subreg:SI (match_dup 0) 1)
6977 (set (subreg:SI (match_dup 0) 0)
6978 (ashiftrt:SI (subreg:SI (match_dup 1) 0)
6982 int amount = INTVAL (operands[2]);
6983 operands[2] = GEN_INT ((amount & 31));
6984 operands[4] = GEN_INT (((-amount) & 31));
6988 (define_insn "ashrdi3_internal4"
6989 [(set (match_operand:DI 0 "register_operand" "=d")
6990 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
6991 (match_operand:SI 2 "arith_operand" "dI")))]
6992 "TARGET_64BIT && !TARGET_MIPS16"
6995 if (GET_CODE (operands[2]) == CONST_INT)
6996 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6998 return \"dsra\\t%0,%1,%2\";
7000 [(set_attr "type" "arith")
7001 (set_attr "mode" "DI")])
7004 [(set (match_operand:DI 0 "register_operand" "=d,d")
7005 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7006 (match_operand:SI 2 "arith_operand" "d,I")))]
7007 "TARGET_64BIT && TARGET_MIPS16"
7010 if (GET_CODE (operands[2]) == CONST_INT)
7011 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7013 return \"dsra\\t%0,%2\";
7015 [(set_attr "type" "arith")
7016 (set_attr "mode" "DI")
7017 (set_attr_alternative "length"
7019 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7023 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7026 [(set (match_operand:DI 0 "register_operand" "")
7027 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7028 (match_operand:SI 2 "const_int_operand" "")))]
7029 "TARGET_MIPS16 && TARGET_64BIT
7031 && GET_CODE (operands[2]) == CONST_INT
7032 && INTVAL (operands[2]) > 8
7033 && INTVAL (operands[2]) <= 16"
7034 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
7035 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
7038 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7041 (define_expand "lshrsi3"
7042 [(set (match_operand:SI 0 "register_operand" "=d")
7043 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7044 (match_operand:SI 2 "arith_operand" "dI")))]
7048 /* On the mips16, a shift of more than 8 is a four byte instruction,
7049 so, for a shift between 8 and 16, it is just as fast to do two
7050 shifts of 8 or less. If there is a lot of shifting going on, we
7051 may win in CSE. Otherwise combine will put the shifts back
7055 && GET_CODE (operands[2]) == CONST_INT
7056 && INTVAL (operands[2]) > 8
7057 && INTVAL (operands[2]) <= 16)
7059 rtx temp = gen_reg_rtx (SImode);
7061 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
7062 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
7063 GEN_INT (INTVAL (operands[2]) - 8)));
7068 (define_insn "lshrsi3_internal1"
7069 [(set (match_operand:SI 0 "register_operand" "=d")
7070 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7071 (match_operand:SI 2 "arith_operand" "dI")))]
7075 if (GET_CODE (operands[2]) == CONST_INT)
7076 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7078 return \"srl\\t%0,%1,%2\";
7080 [(set_attr "type" "arith")
7081 (set_attr "mode" "SI")])
7083 (define_insn "lshrsi3_internal2"
7084 [(set (match_operand:SI 0 "register_operand" "=d,d")
7085 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
7086 (match_operand:SI 2 "arith_operand" "d,I")))]
7090 if (which_alternative == 0)
7091 return \"srl\\t%0,%2\";
7093 if (GET_CODE (operands[2]) == CONST_INT)
7094 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7096 return \"srl\\t%0,%1,%2\";
7098 [(set_attr "type" "arith")
7099 (set_attr "mode" "SI")
7100 (set_attr_alternative "length"
7102 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7107 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7110 [(set (match_operand:SI 0 "register_operand" "")
7111 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
7112 (match_operand:SI 2 "const_int_operand" "")))]
7115 && GET_CODE (operands[2]) == CONST_INT
7116 && INTVAL (operands[2]) > 8
7117 && INTVAL (operands[2]) <= 16"
7118 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
7119 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7122 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7125 ;; If we load a byte on the mips16 as a bitfield, the resulting
7126 ;; sequence of instructions is too complicated for combine, because it
7127 ;; involves four instructions: a load, a shift, a constant load into a
7128 ;; register, and an and (the key problem here is that the mips16 does
7129 ;; not have and immediate). We recognize a shift of a load in order
7130 ;; to make it simple enough for combine to understand.
7133 [(set (match_operand:SI 0 "register_operand" "=d,d")
7134 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "R,m")
7135 (match_operand:SI 2 "immediate_operand" "I,I")))]
7137 "lw\\t%0,%1\;srl\\t%0,%2"
7138 [(set_attr "type" "load")
7139 (set_attr "mode" "SI")
7140 (set_attr_alternative "length"
7141 [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7144 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7149 [(set (match_operand:SI 0 "register_operand" "")
7150 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "")
7151 (match_operand:SI 2 "immediate_operand" "")))]
7153 [(set (match_dup 0) (match_dup 1))
7154 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7157 (define_expand "lshrdi3"
7158 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7159 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7160 (match_operand:SI 2 "arith_operand" "")))
7161 (clobber (match_dup 3))])]
7162 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7167 /* On the mips16, a shift of more than 8 is a four byte
7168 instruction, so, for a shift between 8 and 16, it is just as
7169 fast to do two shifts of 8 or less. If there is a lot of
7170 shifting going on, we may win in CSE. Otherwise combine will
7171 put the shifts back together again. */
7174 && GET_CODE (operands[2]) == CONST_INT
7175 && INTVAL (operands[2]) > 8
7176 && INTVAL (operands[2]) <= 16)
7178 rtx temp = gen_reg_rtx (DImode);
7180 emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7181 emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
7182 GEN_INT (INTVAL (operands[2]) - 8)));
7186 emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
7191 operands[3] = gen_reg_rtx (SImode);
7195 (define_insn "lshrdi3_internal"
7196 [(set (match_operand:DI 0 "register_operand" "=&d")
7197 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7198 (match_operand:SI 2 "register_operand" "d")))
7199 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7200 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7203 operands[4] = const0_rtx;
7204 dslots_jump_total += 3;
7205 dslots_jump_filled += 2;
7207 return \"sll\\t%3,%2,26\\n\\
7208 \\tbgez\\t%3,1f\\n\\
7209 \\tsrl\\t%L0,%M1,%2\\n\\
7211 \\tmove\\t%M0,%z4%)\\n\\
7214 \\t%(beq\\t%3,%z4,2f\\n\\
7215 \\tsrl\\t%L0,%L1,%2%)\\n\\
7217 \\tsubu\\t%3,%z4,%2\\n\\
7218 \\tsll\\t%3,%M1,%3\\n\\
7219 \\tor\\t%L0,%L0,%3\\n\\
7221 \\tsrl\\t%M0,%M1,%2\\n\\
7224 [(set_attr "type" "darith")
7225 (set_attr "mode" "DI")
7226 (set_attr "length" "48")])
7229 (define_insn "lshrdi3_internal2"
7230 [(set (match_operand:DI 0 "register_operand" "=d")
7231 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7232 (match_operand:SI 2 "small_int" "IJK")))
7233 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7234 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7235 && (INTVAL (operands[2]) & 32) != 0"
7238 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7239 operands[4] = const0_rtx;
7240 return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
7242 [(set_attr "type" "darith")
7243 (set_attr "mode" "DI")
7244 (set_attr "length" "8")])
7248 [(set (match_operand:DI 0 "register_operand" "")
7249 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7250 (match_operand:SI 2 "small_int" "")))
7251 (clobber (match_operand:SI 3 "register_operand" ""))]
7252 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7253 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7254 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7255 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7256 && (INTVAL (operands[2]) & 32) != 0"
7258 [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
7259 (set (subreg:SI (match_dup 0) 1) (const_int 0))]
7261 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7265 [(set (match_operand:DI 0 "register_operand" "")
7266 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7267 (match_operand:SI 2 "small_int" "")))
7268 (clobber (match_operand:SI 3 "register_operand" ""))]
7269 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7270 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7271 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7272 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7273 && (INTVAL (operands[2]) & 32) != 0"
7275 [(set (subreg:SI (match_dup 0) 1) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7276 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
7278 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7281 (define_insn "lshrdi3_internal3"
7282 [(set (match_operand:DI 0 "register_operand" "=d")
7283 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7284 (match_operand:SI 2 "small_int" "IJK")))
7285 (clobber (match_operand:SI 3 "register_operand" "=d"))]
7286 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7287 && (INTVAL (operands[2]) & 63) < 32
7288 && (INTVAL (operands[2]) & 63) != 0"
7291 int amount = INTVAL (operands[2]);
7293 operands[2] = GEN_INT ((amount & 31));
7294 operands[4] = GEN_INT (((-amount) & 31));
7296 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
7298 [(set_attr "type" "darith")
7299 (set_attr "mode" "DI")
7300 (set_attr "length" "16")])
7304 [(set (match_operand:DI 0 "register_operand" "")
7305 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7306 (match_operand:SI 2 "small_int" "")))
7307 (clobber (match_operand:SI 3 "register_operand" ""))]
7308 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7309 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7310 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7311 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7312 && (INTVAL (operands[2]) & 63) < 32
7313 && (INTVAL (operands[2]) & 63) != 0"
7315 [(set (subreg:SI (match_dup 0) 0)
7316 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7320 (ashift:SI (subreg:SI (match_dup 1) 1)
7323 (set (subreg:SI (match_dup 0) 0)
7324 (ior:SI (subreg:SI (match_dup 0) 0)
7327 (set (subreg:SI (match_dup 0) 1)
7328 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
7332 int amount = INTVAL (operands[2]);
7333 operands[2] = GEN_INT ((amount & 31));
7334 operands[4] = GEN_INT (((-amount) & 31));
7339 [(set (match_operand:DI 0 "register_operand" "")
7340 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7341 (match_operand:SI 2 "small_int" "")))
7342 (clobber (match_operand:SI 3 "register_operand" ""))]
7343 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7344 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7345 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7346 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7347 && (INTVAL (operands[2]) & 63) < 32
7348 && (INTVAL (operands[2]) & 63) != 0"
7350 [(set (subreg:SI (match_dup 0) 1)
7351 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
7355 (ashift:SI (subreg:SI (match_dup 1) 0)
7358 (set (subreg:SI (match_dup 0) 1)
7359 (ior:SI (subreg:SI (match_dup 0) 1)
7362 (set (subreg:SI (match_dup 0) 0)
7363 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7367 int amount = INTVAL (operands[2]);
7368 operands[2] = GEN_INT ((amount & 31));
7369 operands[4] = GEN_INT (((-amount) & 31));
7373 (define_insn "lshrdi3_internal4"
7374 [(set (match_operand:DI 0 "register_operand" "=d")
7375 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7376 (match_operand:SI 2 "arith_operand" "dI")))]
7377 "TARGET_64BIT && !TARGET_MIPS16"
7380 if (GET_CODE (operands[2]) == CONST_INT)
7381 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7383 return \"dsrl\\t%0,%1,%2\";
7385 [(set_attr "type" "arith")
7386 (set_attr "mode" "DI")])
7389 [(set (match_operand:DI 0 "register_operand" "=d,d")
7390 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7391 (match_operand:SI 2 "arith_operand" "d,I")))]
7392 "TARGET_64BIT && TARGET_MIPS16"
7395 if (GET_CODE (operands[2]) == CONST_INT)
7396 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7398 return \"dsrl\\t%0,%2\";
7400 [(set_attr "type" "arith")
7401 (set_attr "mode" "DI")
7402 (set_attr_alternative "length"
7404 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7408 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7411 [(set (match_operand:DI 0 "register_operand" "")
7412 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7413 (match_operand:SI 2 "const_int_operand" "")))]
7416 && GET_CODE (operands[2]) == CONST_INT
7417 && INTVAL (operands[2]) > 8
7418 && INTVAL (operands[2]) <= 16"
7419 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
7420 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
7423 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7428 ;; ....................
7432 ;; ....................
7434 ;; Flow here is rather complex:
7436 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
7437 ;; arguments into the branch_cmp array, and the type into
7438 ;; branch_type. No RTL is generated.
7440 ;; 2) The appropriate branch define_expand is called, which then
7441 ;; creates the appropriate RTL for the comparison and branch.
7442 ;; Different CC modes are used, based on what type of branch is
7443 ;; done, so that we can constrain things appropriately. There
7444 ;; are assumptions in the rest of GCC that break if we fold the
7445 ;; operands into the branchs for integer operations, and use cc0
7446 ;; for floating point, so we use the fp status register instead.
7447 ;; If needed, an appropriate temporary is created to hold the
7448 ;; of the integer compare.
7450 (define_expand "cmpsi"
7452 (compare:CC (match_operand:SI 0 "register_operand" "")
7453 (match_operand:SI 1 "arith_operand" "")))]
7457 if (operands[0]) /* avoid unused code message */
7459 branch_cmp[0] = operands[0];
7460 branch_cmp[1] = operands[1];
7461 branch_type = CMP_SI;
7466 (define_expand "tstsi"
7468 (match_operand:SI 0 "register_operand" ""))]
7472 if (operands[0]) /* avoid unused code message */
7474 branch_cmp[0] = operands[0];
7475 branch_cmp[1] = const0_rtx;
7476 branch_type = CMP_SI;
7481 (define_expand "cmpdi"
7483 (compare:CC (match_operand:DI 0 "se_register_operand" "")
7484 (match_operand:DI 1 "se_arith_operand" "")))]
7488 if (operands[0]) /* avoid unused code message */
7490 branch_cmp[0] = operands[0];
7491 branch_cmp[1] = operands[1];
7492 branch_type = CMP_DI;
7497 (define_expand "tstdi"
7499 (match_operand:DI 0 "se_register_operand" ""))]
7503 if (operands[0]) /* avoid unused code message */
7505 branch_cmp[0] = operands[0];
7506 branch_cmp[1] = const0_rtx;
7507 branch_type = CMP_DI;
7512 (define_expand "cmpdf"
7514 (compare:CC (match_operand:DF 0 "register_operand" "")
7515 (match_operand:DF 1 "register_operand" "")))]
7516 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7519 if (operands[0]) /* avoid unused code message */
7521 branch_cmp[0] = operands[0];
7522 branch_cmp[1] = operands[1];
7523 branch_type = CMP_DF;
7528 (define_expand "cmpsf"
7530 (compare:CC (match_operand:SF 0 "register_operand" "")
7531 (match_operand:SF 1 "register_operand" "")))]
7535 if (operands[0]) /* avoid unused code message */
7537 branch_cmp[0] = operands[0];
7538 branch_cmp[1] = operands[1];
7539 branch_type = CMP_SF;
7546 ;; ....................
7548 ;; CONDITIONAL BRANCHES
7550 ;; ....................
7552 ;; Conditional branches on floating-point equality tests.
7554 (define_insn "branch_fp"
7557 (match_operator:CC 0 "cmp_op"
7558 [(match_operand:CC 2 "register_operand" "z")
7560 (label_ref (match_operand 1 "" ""))
7565 return mips_output_conditional_branch (insn,
7567 /*two_operands_p=*/0,
7570 get_attr_length (insn));
7572 [(set_attr "type" "branch")
7573 (set_attr "mode" "none")])
7575 (define_insn "branch_fp_inverted"
7578 (match_operator:CC 0 "cmp_op"
7579 [(match_operand:CC 2 "register_operand" "z")
7582 (label_ref (match_operand 1 "" ""))))]
7586 return mips_output_conditional_branch (insn,
7588 /*two_operands_p=*/0,
7591 get_attr_length (insn));
7593 [(set_attr "type" "branch")
7594 (set_attr "mode" "none")])
7596 ;; Conditional branches on comparisons with zero.
7598 (define_insn "branch_zero"
7601 (match_operator:SI 0 "cmp_op"
7602 [(match_operand:SI 2 "register_operand" "d")
7604 (label_ref (match_operand 1 "" ""))
7609 return mips_output_conditional_branch (insn,
7611 /*two_operands_p=*/0,
7614 get_attr_length (insn));
7616 [(set_attr "type" "branch")
7617 (set_attr "mode" "none")])
7619 (define_insn "branch_zero_inverted"
7622 (match_operator:SI 0 "cmp_op"
7623 [(match_operand:SI 2 "register_operand" "d")
7626 (label_ref (match_operand 1 "" ""))))]
7630 return mips_output_conditional_branch (insn,
7632 /*two_operands_p=*/0,
7635 get_attr_length (insn));
7637 [(set_attr "type" "branch")
7638 (set_attr "mode" "none")])
7640 (define_insn "branch_zero_di"
7643 (match_operator:DI 0 "cmp_op"
7644 [(match_operand:DI 2 "se_register_operand" "d")
7646 (label_ref (match_operand 1 "" ""))
7651 return mips_output_conditional_branch (insn,
7653 /*two_operands_p=*/0,
7656 get_attr_length (insn));
7658 [(set_attr "type" "branch")
7659 (set_attr "mode" "none")])
7661 (define_insn "branch_zero_di_inverted"
7664 (match_operator:DI 0 "cmp_op"
7665 [(match_operand:DI 2 "se_register_operand" "d")
7668 (label_ref (match_operand 1 "" ""))))]
7672 return mips_output_conditional_branch (insn,
7674 /*two_operands_p=*/0,
7677 get_attr_length (insn));
7679 [(set_attr "type" "branch")
7680 (set_attr "mode" "none")])
7682 ;; Conditional branch on equality comparision.
7684 (define_insn "branch_equality"
7687 (match_operator:SI 0 "equality_op"
7688 [(match_operand:SI 2 "register_operand" "d")
7689 (match_operand:SI 3 "register_operand" "d")])
7690 (label_ref (match_operand 1 "" ""))
7695 return mips_output_conditional_branch (insn,
7697 /*two_operands_p=*/1,
7700 get_attr_length (insn));
7702 [(set_attr "type" "branch")
7703 (set_attr "mode" "none")])
7705 (define_insn "branch_equality_di"
7708 (match_operator:DI 0 "equality_op"
7709 [(match_operand:DI 2 "se_register_operand" "d")
7710 (match_operand:DI 3 "se_register_operand" "d")])
7711 (label_ref (match_operand 1 "" ""))
7716 return mips_output_conditional_branch (insn,
7718 /*two_operands_p=*/1,
7721 get_attr_length (insn));
7723 [(set_attr "type" "branch")
7724 (set_attr "mode" "none")])
7726 (define_insn "branch_equality_inverted"
7729 (match_operator:SI 0 "equality_op"
7730 [(match_operand:SI 2 "register_operand" "d")
7731 (match_operand:SI 3 "register_operand" "d")])
7733 (label_ref (match_operand 1 "" ""))))]
7737 return mips_output_conditional_branch (insn,
7739 /*two_operands_p=*/1,
7742 get_attr_length (insn));
7744 [(set_attr "type" "branch")
7745 (set_attr "mode" "none")])
7747 (define_insn "branch_equality_di_inverted"
7750 (match_operator:DI 0 "equality_op"
7751 [(match_operand:DI 2 "se_register_operand" "d")
7752 (match_operand:DI 3 "se_register_operand" "d")])
7754 (label_ref (match_operand 1 "" ""))))]
7758 return mips_output_conditional_branch (insn,
7760 /*two_operands_p=*/1,
7763 get_attr_length (insn));
7765 [(set_attr "type" "branch")
7766 (set_attr "mode" "none")])
7772 (if_then_else (match_operator:SI 0 "equality_op"
7773 [(match_operand:SI 1 "register_operand" "d,t")
7775 (match_operand 2 "pc_or_label_operand" "")
7776 (match_operand 3 "pc_or_label_operand" "")))]
7780 if (operands[2] != pc_rtx)
7782 if (which_alternative == 0)
7783 return \"%*b%C0z\\t%1,%2\";
7785 return \"%*bt%C0z\\t%2\";
7789 if (which_alternative == 0)
7790 return \"%*b%N0z\\t%1,%3\";
7792 return \"%*bt%N0z\\t%3\";
7795 [(set_attr "type" "branch")
7796 (set_attr "mode" "none")
7797 (set_attr "length" "8")])
7801 (if_then_else (match_operator:DI 0 "equality_op"
7802 [(match_operand:DI 1 "se_register_operand" "d,t")
7804 (match_operand 2 "pc_or_label_operand" "")
7805 (match_operand 3 "pc_or_label_operand" "")))]
7809 if (operands[2] != pc_rtx)
7811 if (which_alternative == 0)
7812 return \"%*b%C0z\\t%1,%2\";
7814 return \"%*bt%C0z\\t%2\";
7818 if (which_alternative == 0)
7819 return \"%*b%N0z\\t%1,%3\";
7821 return \"%*bt%N0z\\t%3\";
7824 [(set_attr "type" "branch")
7825 (set_attr "mode" "none")
7826 (set_attr "length" "8")])
7828 (define_expand "beq"
7830 (if_then_else (eq:CC (cc0)
7832 (label_ref (match_operand 0 "" ""))
7837 if (operands[0]) /* avoid unused code warning */
7839 gen_conditional_branch (operands, EQ);
7844 (define_expand "bne"
7846 (if_then_else (ne:CC (cc0)
7848 (label_ref (match_operand 0 "" ""))
7853 if (operands[0]) /* avoid unused code warning */
7855 gen_conditional_branch (operands, NE);
7860 (define_expand "bgt"
7862 (if_then_else (gt:CC (cc0)
7864 (label_ref (match_operand 0 "" ""))
7869 if (operands[0]) /* avoid unused code warning */
7871 gen_conditional_branch (operands, GT);
7876 (define_expand "bge"
7878 (if_then_else (ge:CC (cc0)
7880 (label_ref (match_operand 0 "" ""))
7885 if (operands[0]) /* avoid unused code warning */
7887 gen_conditional_branch (operands, GE);
7892 (define_expand "blt"
7894 (if_then_else (lt:CC (cc0)
7896 (label_ref (match_operand 0 "" ""))
7901 if (operands[0]) /* avoid unused code warning */
7903 gen_conditional_branch (operands, LT);
7908 (define_expand "ble"
7910 (if_then_else (le:CC (cc0)
7912 (label_ref (match_operand 0 "" ""))
7917 if (operands[0]) /* avoid unused code warning */
7919 gen_conditional_branch (operands, LE);
7924 (define_expand "bgtu"
7926 (if_then_else (gtu:CC (cc0)
7928 (label_ref (match_operand 0 "" ""))
7933 if (operands[0]) /* avoid unused code warning */
7935 gen_conditional_branch (operands, GTU);
7940 (define_expand "bgeu"
7942 (if_then_else (geu:CC (cc0)
7944 (label_ref (match_operand 0 "" ""))
7949 if (operands[0]) /* avoid unused code warning */
7951 gen_conditional_branch (operands, GEU);
7957 (define_expand "bltu"
7959 (if_then_else (ltu:CC (cc0)
7961 (label_ref (match_operand 0 "" ""))
7966 if (operands[0]) /* avoid unused code warning */
7968 gen_conditional_branch (operands, LTU);
7973 (define_expand "bleu"
7975 (if_then_else (leu:CC (cc0)
7977 (label_ref (match_operand 0 "" ""))
7982 if (operands[0]) /* avoid unused code warning */
7984 gen_conditional_branch (operands, LEU);
7991 ;; ....................
7993 ;; SETTING A REGISTER FROM A COMPARISON
7995 ;; ....................
7997 (define_expand "seq"
7998 [(set (match_operand:SI 0 "register_operand" "=d")
7999 (eq:SI (match_dup 1)
8004 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8007 /* set up operands from compare. */
8008 operands[1] = branch_cmp[0];
8009 operands[2] = branch_cmp[1];
8011 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8013 gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
8017 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8018 operands[2] = force_reg (SImode, operands[2]);
8020 /* fall through and generate default code */
8024 (define_insn "seq_si_zero"
8025 [(set (match_operand:SI 0 "register_operand" "=d")
8026 (eq:SI (match_operand:SI 1 "register_operand" "d")
8030 [(set_attr "type" "arith")
8031 (set_attr "mode" "SI")])
8034 [(set (match_operand:SI 0 "register_operand" "=t")
8035 (eq:SI (match_operand:SI 1 "register_operand" "d")
8039 [(set_attr "type" "arith")
8040 (set_attr "mode" "SI")])
8042 (define_insn "seq_di_zero"
8043 [(set (match_operand:DI 0 "register_operand" "=d")
8044 (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8046 "TARGET_64BIT && !TARGET_MIPS16"
8048 [(set_attr "type" "arith")
8049 (set_attr "mode" "DI")])
8052 [(set (match_operand:DI 0 "register_operand" "=t")
8053 (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8055 "TARGET_64BIT && TARGET_MIPS16"
8057 [(set_attr "type" "arith")
8058 (set_attr "mode" "DI")])
8060 (define_insn "seq_si"
8061 [(set (match_operand:SI 0 "register_operand" "=d,d")
8062 (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
8063 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8064 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8066 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8067 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8068 [(set_attr "type" "arith")
8069 (set_attr "mode" "SI")
8070 (set_attr "length" "8")])
8073 [(set (match_operand:SI 0 "register_operand" "")
8074 (eq:SI (match_operand:SI 1 "register_operand" "")
8075 (match_operand:SI 2 "uns_arith_operand" "")))]
8076 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8077 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8079 (xor:SI (match_dup 1)
8082 (ltu:SI (match_dup 0)
8086 (define_insn "seq_di"
8087 [(set (match_operand:DI 0 "register_operand" "=d,d")
8088 (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8089 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8090 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8092 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8093 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8094 [(set_attr "type" "arith")
8095 (set_attr "mode" "DI")
8096 (set_attr "length" "8")])
8099 [(set (match_operand:DI 0 "register_operand" "")
8100 (eq:DI (match_operand:DI 1 "se_register_operand" "")
8101 (match_operand:DI 2 "se_uns_arith_operand" "")))]
8102 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8104 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8106 (xor:DI (match_dup 1)
8109 (ltu:DI (match_dup 0)
8113 ;; On the mips16 the default code is better than using sltu.
8115 (define_expand "sne"
8116 [(set (match_operand:SI 0 "register_operand" "=d")
8117 (ne:SI (match_dup 1)
8122 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8125 /* set up operands from compare. */
8126 operands[1] = branch_cmp[0];
8127 operands[2] = branch_cmp[1];
8129 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
8131 gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
8135 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8136 operands[2] = force_reg (SImode, operands[2]);
8138 /* fall through and generate default code */
8141 (define_insn "sne_si_zero"
8142 [(set (match_operand:SI 0 "register_operand" "=d")
8143 (ne:SI (match_operand:SI 1 "register_operand" "d")
8147 [(set_attr "type" "arith")
8148 (set_attr "mode" "SI")])
8150 (define_insn "sne_di_zero"
8151 [(set (match_operand:DI 0 "register_operand" "=d")
8152 (ne:DI (match_operand:DI 1 "se_register_operand" "d")
8154 "TARGET_64BIT && !TARGET_MIPS16"
8156 [(set_attr "type" "arith")
8157 (set_attr "mode" "DI")])
8159 (define_insn "sne_si"
8160 [(set (match_operand:SI 0 "register_operand" "=d,d")
8161 (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
8162 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8163 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8165 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8166 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8167 [(set_attr "type" "arith")
8168 (set_attr "mode" "SI")
8169 (set_attr "length" "8")])
8172 [(set (match_operand:SI 0 "register_operand" "")
8173 (ne:SI (match_operand:SI 1 "register_operand" "")
8174 (match_operand:SI 2 "uns_arith_operand" "")))]
8175 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8176 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8178 (xor:SI (match_dup 1)
8181 (gtu:SI (match_dup 0)
8185 (define_insn "sne_di"
8186 [(set (match_operand:DI 0 "register_operand" "=d,d")
8187 (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8188 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8189 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8191 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8192 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8193 [(set_attr "type" "arith")
8194 (set_attr "mode" "DI")
8195 (set_attr "length" "8")])
8198 [(set (match_operand:DI 0 "register_operand" "")
8199 (ne:DI (match_operand:DI 1 "se_register_operand" "")
8200 (match_operand:DI 2 "se_uns_arith_operand" "")))]
8201 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8203 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8205 (xor:DI (match_dup 1)
8208 (gtu:DI (match_dup 0)
8212 (define_expand "sgt"
8213 [(set (match_operand:SI 0 "register_operand" "=d")
8214 (gt:SI (match_dup 1)
8219 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8222 /* set up operands from compare. */
8223 operands[1] = branch_cmp[0];
8224 operands[2] = branch_cmp[1];
8226 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8228 gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
8232 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8233 operands[2] = force_reg (SImode, operands[2]);
8235 /* fall through and generate default code */
8238 (define_insn "sgt_si"
8239 [(set (match_operand:SI 0 "register_operand" "=d")
8240 (gt:SI (match_operand:SI 1 "register_operand" "d")
8241 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8244 [(set_attr "type" "arith")
8245 (set_attr "mode" "SI")])
8248 [(set (match_operand:SI 0 "register_operand" "=t")
8249 (gt:SI (match_operand:SI 1 "register_operand" "d")
8250 (match_operand:SI 2 "register_operand" "d")))]
8253 [(set_attr "type" "arith")
8254 (set_attr "mode" "SI")])
8256 (define_insn "sgt_di"
8257 [(set (match_operand:DI 0 "register_operand" "=d")
8258 (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8259 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8260 "TARGET_64BIT && !TARGET_MIPS16"
8262 [(set_attr "type" "arith")
8263 (set_attr "mode" "DI")])
8266 [(set (match_operand:DI 0 "register_operand" "=d")
8267 (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8268 (match_operand:DI 2 "se_register_operand" "d")))]
8269 "TARGET_64BIT && TARGET_MIPS16"
8271 [(set_attr "type" "arith")
8272 (set_attr "mode" "DI")])
8274 (define_expand "sge"
8275 [(set (match_operand:SI 0 "register_operand" "=d")
8276 (ge:SI (match_dup 1)
8281 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8284 /* set up operands from compare. */
8285 operands[1] = branch_cmp[0];
8286 operands[2] = branch_cmp[1];
8288 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8290 gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
8294 /* fall through and generate default code */
8297 (define_insn "sge_si"
8298 [(set (match_operand:SI 0 "register_operand" "=d")
8299 (ge:SI (match_operand:SI 1 "register_operand" "d")
8300 (match_operand:SI 2 "arith_operand" "dI")))]
8301 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8302 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8303 [(set_attr "type" "arith")
8304 (set_attr "mode" "SI")
8305 (set_attr "length" "8")])
8308 [(set (match_operand:SI 0 "register_operand" "")
8309 (ge:SI (match_operand:SI 1 "register_operand" "")
8310 (match_operand:SI 2 "arith_operand" "")))]
8311 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8313 (lt:SI (match_dup 1)
8316 (xor:SI (match_dup 0)
8320 (define_insn "sge_di"
8321 [(set (match_operand:DI 0 "register_operand" "=d")
8322 (ge:DI (match_operand:DI 1 "se_register_operand" "d")
8323 (match_operand:DI 2 "se_arith_operand" "dI")))]
8324 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8325 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8326 [(set_attr "type" "arith")
8327 (set_attr "mode" "DI")
8328 (set_attr "length" "8")])
8331 [(set (match_operand:DI 0 "register_operand" "")
8332 (ge:DI (match_operand:DI 1 "se_register_operand" "")
8333 (match_operand:DI 2 "se_arith_operand" "")))]
8334 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8337 (lt:DI (match_dup 1)
8340 (xor:DI (match_dup 0)
8344 (define_expand "slt"
8345 [(set (match_operand:SI 0 "register_operand" "=d")
8346 (lt:SI (match_dup 1)
8351 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8354 /* set up operands from compare. */
8355 operands[1] = branch_cmp[0];
8356 operands[2] = branch_cmp[1];
8358 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8360 gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
8364 /* fall through and generate default code */
8367 (define_insn "slt_si"
8368 [(set (match_operand:SI 0 "register_operand" "=d")
8369 (lt:SI (match_operand:SI 1 "register_operand" "d")
8370 (match_operand:SI 2 "arith_operand" "dI")))]
8373 [(set_attr "type" "arith")
8374 (set_attr "mode" "SI")])
8377 [(set (match_operand:SI 0 "register_operand" "=t,t")
8378 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
8379 (match_operand:SI 2 "arith_operand" "d,I")))]
8382 [(set_attr "type" "arith")
8383 (set_attr "mode" "SI")
8384 (set_attr_alternative "length"
8386 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8390 (define_insn "slt_di"
8391 [(set (match_operand:DI 0 "register_operand" "=d")
8392 (lt:DI (match_operand:DI 1 "se_register_operand" "d")
8393 (match_operand:DI 2 "se_arith_operand" "dI")))]
8394 "TARGET_64BIT && !TARGET_MIPS16"
8396 [(set_attr "type" "arith")
8397 (set_attr "mode" "DI")])
8400 [(set (match_operand:DI 0 "register_operand" "=t,t")
8401 (lt:DI (match_operand:DI 1 "se_register_operand" "d,d")
8402 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8403 "TARGET_64BIT && TARGET_MIPS16"
8405 [(set_attr "type" "arith")
8406 (set_attr "mode" "DI")
8407 (set_attr_alternative "length"
8409 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8413 (define_expand "sle"
8414 [(set (match_operand:SI 0 "register_operand" "=d")
8415 (le:SI (match_dup 1)
8420 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8423 /* set up operands from compare. */
8424 operands[1] = branch_cmp[0];
8425 operands[2] = branch_cmp[1];
8427 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8429 gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
8433 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8434 operands[2] = force_reg (SImode, operands[2]);
8436 /* fall through and generate default code */
8439 (define_insn "sle_si_const"
8440 [(set (match_operand:SI 0 "register_operand" "=d")
8441 (le:SI (match_operand:SI 1 "register_operand" "d")
8442 (match_operand:SI 2 "small_int" "I")))]
8443 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8446 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8447 return \"slt\\t%0,%1,%2\";
8449 [(set_attr "type" "arith")
8450 (set_attr "mode" "SI")])
8453 [(set (match_operand:SI 0 "register_operand" "=t")
8454 (le:SI (match_operand:SI 1 "register_operand" "d")
8455 (match_operand:SI 2 "small_int" "I")))]
8456 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8459 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8460 return \"slt\\t%1,%2\";
8462 [(set_attr "type" "arith")
8463 (set_attr "mode" "SI")
8464 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8468 (define_insn "sle_di_const"
8469 [(set (match_operand:DI 0 "register_operand" "=d")
8470 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8471 (match_operand:DI 2 "small_int" "I")))]
8472 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8475 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8476 return \"slt\\t%0,%1,%2\";
8478 [(set_attr "type" "arith")
8479 (set_attr "mode" "DI")])
8482 [(set (match_operand:DI 0 "register_operand" "=t")
8483 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8484 (match_operand:DI 2 "small_int" "I")))]
8485 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8488 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8489 return \"slt\\t%1,%2\";
8491 [(set_attr "type" "arith")
8492 (set_attr "mode" "DI")
8493 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8497 (define_insn "sle_si_reg"
8498 [(set (match_operand:SI 0 "register_operand" "=d")
8499 (le:SI (match_operand:SI 1 "register_operand" "d")
8500 (match_operand:SI 2 "register_operand" "d")))]
8501 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8502 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8503 [(set_attr "type" "arith")
8504 (set_attr "mode" "SI")
8505 (set_attr "length" "8")])
8508 [(set (match_operand:SI 0 "register_operand" "")
8509 (le:SI (match_operand:SI 1 "register_operand" "")
8510 (match_operand:SI 2 "register_operand" "")))]
8511 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8513 (lt:SI (match_dup 2)
8516 (xor:SI (match_dup 0)
8520 (define_insn "sle_di_reg"
8521 [(set (match_operand:DI 0 "register_operand" "=d")
8522 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8523 (match_operand:DI 2 "se_register_operand" "d")))]
8524 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8525 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8526 [(set_attr "type" "arith")
8527 (set_attr "mode" "DI")
8528 (set_attr "length" "8")])
8531 [(set (match_operand:DI 0 "register_operand" "")
8532 (le:DI (match_operand:DI 1 "se_register_operand" "")
8533 (match_operand:DI 2 "se_register_operand" "")))]
8534 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8537 (lt:DI (match_dup 2)
8540 (xor:DI (match_dup 0)
8544 (define_expand "sgtu"
8545 [(set (match_operand:SI 0 "register_operand" "=d")
8546 (gtu:SI (match_dup 1)
8551 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8554 /* set up operands from compare. */
8555 operands[1] = branch_cmp[0];
8556 operands[2] = branch_cmp[1];
8558 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8560 gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
8564 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8565 operands[2] = force_reg (SImode, operands[2]);
8567 /* fall through and generate default code */
8570 (define_insn "sgtu_si"
8571 [(set (match_operand:SI 0 "register_operand" "=d")
8572 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8573 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8576 [(set_attr "type" "arith")
8577 (set_attr "mode" "SI")])
8580 [(set (match_operand:SI 0 "register_operand" "=t")
8581 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8582 (match_operand:SI 2 "register_operand" "d")))]
8585 [(set_attr "type" "arith")
8586 (set_attr "mode" "SI")])
8588 (define_insn "sgtu_di"
8589 [(set (match_operand:DI 0 "register_operand" "=d")
8590 (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8591 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8594 [(set_attr "type" "arith")
8595 (set_attr "mode" "DI")])
8598 [(set (match_operand:DI 0 "register_operand" "=t")
8599 (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8600 (match_operand:DI 2 "se_register_operand" "d")))]
8603 [(set_attr "type" "arith")
8604 (set_attr "mode" "DI")])
8606 (define_expand "sgeu"
8607 [(set (match_operand:SI 0 "register_operand" "=d")
8608 (geu:SI (match_dup 1)
8613 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8616 /* set up operands from compare. */
8617 operands[1] = branch_cmp[0];
8618 operands[2] = branch_cmp[1];
8620 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8622 gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
8626 /* fall through and generate default code */
8629 (define_insn "sgeu_si"
8630 [(set (match_operand:SI 0 "register_operand" "=d")
8631 (geu:SI (match_operand:SI 1 "register_operand" "d")
8632 (match_operand:SI 2 "arith_operand" "dI")))]
8633 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8634 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8635 [(set_attr "type" "arith")
8636 (set_attr "mode" "SI")
8637 (set_attr "length" "8")])
8640 [(set (match_operand:SI 0 "register_operand" "")
8641 (geu:SI (match_operand:SI 1 "register_operand" "")
8642 (match_operand:SI 2 "arith_operand" "")))]
8643 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8645 (ltu:SI (match_dup 1)
8648 (xor:SI (match_dup 0)
8652 (define_insn "sgeu_di"
8653 [(set (match_operand:DI 0 "register_operand" "=d")
8654 (geu:DI (match_operand:DI 1 "se_register_operand" "d")
8655 (match_operand:DI 2 "se_arith_operand" "dI")))]
8656 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8657 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8658 [(set_attr "type" "arith")
8659 (set_attr "mode" "DI")
8660 (set_attr "length" "8")])
8663 [(set (match_operand:DI 0 "register_operand" "")
8664 (geu:DI (match_operand:DI 1 "se_register_operand" "")
8665 (match_operand:DI 2 "se_arith_operand" "")))]
8666 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8669 (ltu:DI (match_dup 1)
8672 (xor:DI (match_dup 0)
8676 (define_expand "sltu"
8677 [(set (match_operand:SI 0 "register_operand" "=d")
8678 (ltu:SI (match_dup 1)
8683 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8686 /* set up operands from compare. */
8687 operands[1] = branch_cmp[0];
8688 operands[2] = branch_cmp[1];
8690 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8692 gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
8696 /* fall through and generate default code */
8699 (define_insn "sltu_si"
8700 [(set (match_operand:SI 0 "register_operand" "=d")
8701 (ltu:SI (match_operand:SI 1 "register_operand" "d")
8702 (match_operand:SI 2 "arith_operand" "dI")))]
8705 [(set_attr "type" "arith")
8706 (set_attr "mode" "SI")])
8709 [(set (match_operand:SI 0 "register_operand" "=t,t")
8710 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
8711 (match_operand:SI 2 "arith_operand" "d,I")))]
8714 [(set_attr "type" "arith")
8715 (set_attr "mode" "SI")
8716 (set_attr_alternative "length"
8718 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8722 (define_insn "sltu_di"
8723 [(set (match_operand:DI 0 "register_operand" "=d")
8724 (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
8725 (match_operand:DI 2 "se_arith_operand" "dI")))]
8726 "TARGET_64BIT && !TARGET_MIPS16"
8728 [(set_attr "type" "arith")
8729 (set_attr "mode" "DI")])
8732 [(set (match_operand:DI 0 "register_operand" "=t,t")
8733 (ltu:DI (match_operand:DI 1 "se_register_operand" "d,d")
8734 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8735 "TARGET_64BIT && TARGET_MIPS16"
8737 [(set_attr "type" "arith")
8738 (set_attr "mode" "DI")
8739 (set_attr_alternative "length"
8741 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8745 (define_expand "sleu"
8746 [(set (match_operand:SI 0 "register_operand" "=d")
8747 (leu:SI (match_dup 1)
8752 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8755 /* set up operands from compare. */
8756 operands[1] = branch_cmp[0];
8757 operands[2] = branch_cmp[1];
8759 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8761 gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
8765 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8766 operands[2] = force_reg (SImode, operands[2]);
8768 /* fall through and generate default code */
8771 (define_insn "sleu_si_const"
8772 [(set (match_operand:SI 0 "register_operand" "=d")
8773 (leu:SI (match_operand:SI 1 "register_operand" "d")
8774 (match_operand:SI 2 "small_int" "I")))]
8775 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8778 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8779 return \"sltu\\t%0,%1,%2\";
8781 [(set_attr "type" "arith")
8782 (set_attr "mode" "SI")])
8785 [(set (match_operand:SI 0 "register_operand" "=t")
8786 (leu:SI (match_operand:SI 1 "register_operand" "d")
8787 (match_operand:SI 2 "small_int" "I")))]
8788 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8791 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8792 return \"sltu\\t%1,%2\";
8794 [(set_attr "type" "arith")
8795 (set_attr "mode" "SI")
8796 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8800 (define_insn "sleu_di_const"
8801 [(set (match_operand:DI 0 "register_operand" "=d")
8802 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8803 (match_operand:DI 2 "small_int" "I")))]
8804 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8807 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8808 return \"sltu\\t%0,%1,%2\";
8810 [(set_attr "type" "arith")
8811 (set_attr "mode" "DI")])
8814 [(set (match_operand:DI 0 "register_operand" "=t")
8815 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8816 (match_operand:DI 2 "small_int" "I")))]
8817 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8820 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8821 return \"sltu\\t%1,%2\";
8823 [(set_attr "type" "arith")
8824 (set_attr "mode" "DI")
8825 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8829 (define_insn "sleu_si_reg"
8830 [(set (match_operand:SI 0 "register_operand" "=d")
8831 (leu:SI (match_operand:SI 1 "register_operand" "d")
8832 (match_operand:SI 2 "register_operand" "d")))]
8833 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8834 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8835 [(set_attr "type" "arith")
8836 (set_attr "mode" "SI")
8837 (set_attr "length" "8")])
8840 [(set (match_operand:SI 0 "register_operand" "")
8841 (leu:SI (match_operand:SI 1 "register_operand" "")
8842 (match_operand:SI 2 "register_operand" "")))]
8843 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8845 (ltu:SI (match_dup 2)
8848 (xor:SI (match_dup 0)
8852 (define_insn "sleu_di_reg"
8853 [(set (match_operand:DI 0 "register_operand" "=d")
8854 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8855 (match_operand:DI 2 "se_register_operand" "d")))]
8856 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8857 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8858 [(set_attr "type" "arith")
8859 (set_attr "mode" "DI")
8860 (set_attr "length" "8")])
8863 [(set (match_operand:DI 0 "register_operand" "")
8864 (leu:DI (match_operand:DI 1 "se_register_operand" "")
8865 (match_operand:DI 2 "se_register_operand" "")))]
8866 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8869 (ltu:DI (match_dup 2)
8872 (xor:DI (match_dup 0)
8878 ;; ....................
8880 ;; FLOATING POINT COMPARISONS
8882 ;; ....................
8884 (define_insn "seq_df"
8885 [(set (match_operand:CC 0 "register_operand" "=z")
8886 (eq:CC (match_operand:DF 1 "register_operand" "f")
8887 (match_operand:DF 2 "register_operand" "f")))]
8888 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8891 return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8893 [(set_attr "type" "fcmp")
8894 (set_attr "mode" "FPSW")])
8896 (define_insn "slt_df"
8897 [(set (match_operand:CC 0 "register_operand" "=z")
8898 (lt:CC (match_operand:DF 1 "register_operand" "f")
8899 (match_operand:DF 2 "register_operand" "f")))]
8900 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8903 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8905 [(set_attr "type" "fcmp")
8906 (set_attr "mode" "FPSW")])
8908 (define_insn "sle_df"
8909 [(set (match_operand:CC 0 "register_operand" "=z")
8910 (le:CC (match_operand:DF 1 "register_operand" "f")
8911 (match_operand:DF 2 "register_operand" "f")))]
8912 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8915 return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8917 [(set_attr "type" "fcmp")
8918 (set_attr "mode" "FPSW")])
8920 (define_insn "sgt_df"
8921 [(set (match_operand:CC 0 "register_operand" "=z")
8922 (gt:CC (match_operand:DF 1 "register_operand" "f")
8923 (match_operand:DF 2 "register_operand" "f")))]
8924 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8927 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8929 [(set_attr "type" "fcmp")
8930 (set_attr "mode" "FPSW")])
8932 (define_insn "sge_df"
8933 [(set (match_operand:CC 0 "register_operand" "=z")
8934 (ge:CC (match_operand:DF 1 "register_operand" "f")
8935 (match_operand:DF 2 "register_operand" "f")))]
8936 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8939 return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8941 [(set_attr "type" "fcmp")
8942 (set_attr "mode" "FPSW")])
8944 (define_insn "seq_sf"
8945 [(set (match_operand:CC 0 "register_operand" "=z")
8946 (eq:CC (match_operand:SF 1 "register_operand" "f")
8947 (match_operand:SF 2 "register_operand" "f")))]
8951 return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8953 [(set_attr "type" "fcmp")
8954 (set_attr "mode" "FPSW")])
8956 (define_insn "slt_sf"
8957 [(set (match_operand:CC 0 "register_operand" "=z")
8958 (lt:CC (match_operand:SF 1 "register_operand" "f")
8959 (match_operand:SF 2 "register_operand" "f")))]
8963 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8965 [(set_attr "type" "fcmp")
8966 (set_attr "mode" "FPSW")])
8968 (define_insn "sle_sf"
8969 [(set (match_operand:CC 0 "register_operand" "=z")
8970 (le:CC (match_operand:SF 1 "register_operand" "f")
8971 (match_operand:SF 2 "register_operand" "f")))]
8975 return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8977 [(set_attr "type" "fcmp")
8978 (set_attr "mode" "FPSW")])
8980 (define_insn "sgt_sf"
8981 [(set (match_operand:CC 0 "register_operand" "=z")
8982 (gt:CC (match_operand:SF 1 "register_operand" "f")
8983 (match_operand:SF 2 "register_operand" "f")))]
8987 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8989 [(set_attr "type" "fcmp")
8990 (set_attr "mode" "FPSW")])
8992 (define_insn "sge_sf"
8993 [(set (match_operand:CC 0 "register_operand" "=z")
8994 (ge:CC (match_operand:SF 1 "register_operand" "f")
8995 (match_operand:SF 2 "register_operand" "f")))]
8999 return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9001 [(set_attr "type" "fcmp")
9002 (set_attr "mode" "FPSW")])
9006 ;; ....................
9008 ;; UNCONDITIONAL BRANCHES
9010 ;; ....................
9012 ;; Unconditional branches.
9016 (label_ref (match_operand 0 "" "")))]
9020 if (GET_CODE (operands[0]) == REG)
9021 return \"%*j\\t%0\";
9022 /* ??? I don't know why this is necessary. This works around an
9023 assembler problem that appears when a label is defined, then referenced
9024 in a switch table, then used in a `j' instruction. */
9025 else if (mips_abi != ABI_32 && mips_abi != ABI_O64)
9026 return \"%*b\\t%l0\";
9028 return \"%*j\\t%l0\";
9030 [(set_attr "type" "jump")
9031 (set_attr "mode" "none")])
9033 ;; We need a different insn for the mips16, because a mips16 branch
9034 ;; does not have a delay slot.
9038 (label_ref (match_operand 0 "" "")))]
9039 "TARGET_MIPS16 && GET_CODE (operands[0]) != REG"
9041 [(set_attr "type" "branch")
9042 (set_attr "mode" "none")
9043 (set_attr "length" "8")])
9045 (define_expand "indirect_jump"
9046 [(set (pc) (match_operand 0 "register_operand" "d"))]
9052 if (operands[0]) /* eliminate unused code warnings */
9055 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
9056 operands[0] = copy_to_mode_reg (Pmode, dest);
9058 if (!(Pmode == DImode))
9059 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
9061 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
9067 (define_insn "indirect_jump_internal1"
9068 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
9069 "!(Pmode == DImode)"
9071 [(set_attr "type" "jump")
9072 (set_attr "mode" "none")])
9074 (define_insn "indirect_jump_internal2"
9075 [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
9078 [(set_attr "type" "jump")
9079 (set_attr "mode" "none")])
9081 (define_expand "tablejump"
9083 (match_operand 0 "register_operand" "d"))
9084 (use (label_ref (match_operand 1 "" "")))]
9088 if (operands[0]) /* eliminate unused code warnings */
9092 if (GET_MODE (operands[0]) != HImode)
9094 if (!(Pmode == DImode))
9095 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
9097 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
9101 if (GET_MODE (operands[0]) != Pmode)
9106 if (!(Pmode == DImode))
9107 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
9109 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
9113 if (!(Pmode == DImode))
9114 emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
9116 emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
9123 (define_insn "tablejump_internal1"
9125 (match_operand:SI 0 "register_operand" "d"))
9126 (use (label_ref (match_operand 1 "" "")))]
9127 "!(Pmode == DImode)"
9129 [(set_attr "type" "jump")
9130 (set_attr "mode" "none")])
9132 (define_insn "tablejump_internal2"
9134 (match_operand:DI 0 "se_register_operand" "d"))
9135 (use (label_ref (match_operand 1 "" "")))]
9138 [(set_attr "type" "jump")
9139 (set_attr "mode" "none")])
9141 (define_expand "tablejump_internal3"
9142 [(parallel [(set (pc)
9143 (plus:SI (match_operand:SI 0 "register_operand" "d")
9144 (label_ref:SI (match_operand:SI 1 "" ""))))
9145 (use (label_ref:SI (match_dup 1)))])]
9149 (define_expand "tablejump_mips161"
9150 [(set (pc) (plus:SI (sign_extend:SI
9151 (match_operand:HI 0 "register_operand" "d"))
9152 (label_ref:SI (match_operand:SI 1 "" ""))))]
9153 "TARGET_MIPS16 && !(Pmode == DImode)"
9156 if (operands[0]) /* eliminate unused code warnings. */
9160 t1 = gen_reg_rtx (SImode);
9161 t2 = gen_reg_rtx (SImode);
9162 t3 = gen_reg_rtx (SImode);
9163 emit_insn (gen_extendhisi2 (t1, operands[0]));
9164 emit_move_insn (t2, gen_rtx (LABEL_REF, SImode, operands[1]));
9165 emit_insn (gen_addsi3 (t3, t1, t2));
9166 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
9171 (define_expand "tablejump_mips162"
9172 [(set (pc) (plus:DI (sign_extend:DI
9173 (match_operand:HI 0 "register_operand" "d"))
9174 (label_ref:DI (match_operand:SI 1 "" ""))))]
9175 "TARGET_MIPS16 && Pmode == DImode"
9178 if (operands[0]) /* eliminate unused code warnings. */
9182 t1 = gen_reg_rtx (DImode);
9183 t2 = gen_reg_rtx (DImode);
9184 t3 = gen_reg_rtx (DImode);
9185 emit_insn (gen_extendhidi2 (t1, operands[0]));
9186 emit_move_insn (t2, gen_rtx (LABEL_REF, DImode, operands[1]));
9187 emit_insn (gen_adddi3 (t3, t1, t2));
9188 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
9193 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
9194 ;;; it is not valid. ??? With the USE, the condition tests may not be required
9197 ;;; ??? The length depends on the ABI. It is two for o32, and one for n32.
9198 ;;; We just use the conservative number here.
9202 (plus:SI (match_operand:SI 0 "register_operand" "d")
9203 (label_ref:SI (match_operand:SI 1 "" ""))))
9204 (use (label_ref:SI (match_dup 1)))]
9205 "!(Pmode == DImode) && next_active_insn (insn) != 0
9206 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9207 && PREV_INSN (next_active_insn (insn)) == operands[1]"
9210 /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */
9211 if (mips_abi == ABI_32 || mips_abi == ABI_O64)
9212 output_asm_insn (\".cpadd\\t%0\", operands);
9213 return \"%*j\\t%0\";
9215 [(set_attr "type" "jump")
9216 (set_attr "mode" "none")
9217 (set_attr "length" "8")])
9219 (define_expand "tablejump_internal4"
9220 [(parallel [(set (pc)
9221 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9222 (label_ref:DI (match_operand:SI 1 "" ""))))
9223 (use (label_ref:DI (match_dup 1)))])]
9227 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
9228 ;;; it is not valid. ??? With the USE, the condition tests may not be required
9233 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9234 (label_ref:DI (match_operand:SI 1 "" ""))))
9235 (use (label_ref:DI (match_dup 1)))]
9236 "Pmode == DImode && next_active_insn (insn) != 0
9237 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9238 && PREV_INSN (next_active_insn (insn)) == operands[1]"
9240 [(set_attr "type" "jump")
9241 (set_attr "mode" "none")])
9243 ;; Implement a switch statement when generating embedded PIC code.
9244 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
9246 (define_expand "casesi"
9248 (minus:SI (match_operand:SI 0 "register_operand" "d")
9249 (match_operand:SI 1 "arith_operand" "dI")))
9251 (compare:CC (match_dup 5)
9252 (match_operand:SI 2 "arith_operand" "")))
9254 (if_then_else (gtu (cc0)
9256 (label_ref (match_operand 4 "" ""))
9260 (mem:SI (plus:SI (mult:SI (match_dup 5)
9262 (label_ref (match_operand 3 "" "")))))
9263 (clobber (match_scratch:SI 6 ""))
9264 (clobber (reg:SI 31))])]
9265 "TARGET_EMBEDDED_PIC"
9268 /* We need slightly different code for eight byte table entries. */
9269 if (Pmode == DImode)
9274 rtx reg = gen_reg_rtx (SImode);
9276 /* If the index is too large, go to the default label. */
9277 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
9278 emit_insn (gen_cmpsi (reg, operands[2]));
9279 emit_insn (gen_bgtu (operands[4]));
9281 /* Do the PIC jump. */
9282 emit_insn (gen_casesi_internal (reg, operands[3], gen_reg_rtx (SImode)));
9288 ;; An embedded PIC switch statement looks like this:
9290 ;; sll $reg,$index,2
9292 ;; addu $reg,$reg,$31
9293 ;; lw $reg,$L1-$LS1($reg)
9294 ;; addu $reg,$reg,$31
9301 (define_insn "casesi_internal"
9303 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
9305 (label_ref (match_operand 1 "" "")))))
9306 (clobber (match_operand:SI 2 "register_operand" "d"))
9307 (clobber (reg:SI 31))]
9308 "TARGET_EMBEDDED_PIC"
9311 output_asm_insn (\"%(bal\\t%S1\;sll\\t%0,2\\n%~%S1:\", operands);
9312 output_asm_insn (\"addu\\t%0,%0,$31%)\", operands);
9313 output_asm_insn (\"lw\\t%0,%1-%S1(%0)\;addu\\t%0,%0,$31\", operands);
9316 [(set_attr "type" "jump")
9317 (set_attr "mode" "none")
9318 (set_attr "length" "24")])
9320 ;; For o32/n32/n64, we save the gp in the jmp_buf as well. While it is
9321 ;; possible to either pull it off the stack (in the o32 case) or recalculate
9322 ;; it given t9 and our target label, it takes 3 or 4 insns to do so, and
9325 (define_expand "builtin_setjmp_setup"
9326 [(unspec [(match_operand 0 "register_operand" "r")] 20)]
9330 if (Pmode == DImode)
9331 emit_insn (gen_builtin_setjmp_setup_64 (operands[0]));
9333 emit_insn (gen_builtin_setjmp_setup_32 (operands[0]));
9337 (define_expand "builtin_setjmp_setup_32"
9338 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
9341 "TARGET_ABICALLS && ! (Pmode == DImode)"
9344 (define_expand "builtin_setjmp_setup_64"
9345 [(set (mem:DI (plus:DI (match_operand:DI 0 "register_operand" "r")
9348 "TARGET_ABICALLS && Pmode == DImode"
9351 ;; For o32/n32/n64, we need to arrange for longjmp to put the
9352 ;; target address in t9 so that we can use it for loading $gp.
9354 (define_expand "builtin_longjmp"
9355 [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
9359 /* The elements of the buffer are, in order: */
9360 int W = (Pmode == DImode ? 8 : 4);
9361 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9362 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
9363 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
9364 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
9365 rtx pv = gen_rtx_REG (Pmode, 25);
9366 rtx gp = gen_rtx_REG (Pmode, 28);
9368 /* This bit is the same as expand_builtin_longjmp. */
9369 emit_move_insn (hard_frame_pointer_rtx, fp);
9370 emit_move_insn (pv, lab);
9371 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
9372 emit_move_insn (gp, gpv);
9373 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
9374 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9375 emit_insn (gen_rtx_USE (VOIDmode, gp));
9376 emit_indirect_jump (pv);
9381 ;; ....................
9383 ;; Function prologue/epilogue
9385 ;; ....................
9388 (define_expand "prologue"
9393 if (mips_isa >= 0) /* avoid unused code warnings */
9395 mips_expand_prologue ();
9400 ;; Block any insns from being moved before this point, since the
9401 ;; profiling call to mcount can use various registers that aren't
9402 ;; saved or used to pass arguments.
9404 (define_insn "blockage"
9405 [(unspec_volatile [(const_int 0)] 0)]
9408 [(set_attr "type" "unknown")
9409 (set_attr "mode" "none")
9410 (set_attr "length" "0")])
9412 (define_expand "epilogue"
9417 if (mips_isa >= 0) /* avoid unused code warnings */
9419 mips_expand_epilogue ();
9424 ;; Trivial return. Make it look like a normal return insn as that
9425 ;; allows jump optimizations to work better .
9426 (define_insn "return"
9428 "mips_can_use_return_insn ()"
9430 [(set_attr "type" "jump")
9431 (set_attr "mode" "none")])
9434 ;; We match any mode for the return address, so that this will work with
9435 ;; both 32 bit and 64 bit targets.
9436 (define_insn "return_internal"
9437 [(use (match_operand 0 "register_operand" ""))
9442 return \"%*j\\t%0\";
9444 [(set_attr "type" "jump")
9445 (set_attr "mode" "none")])
9447 ;; When generating embedded PIC code we need to get the address of the
9448 ;; current function. This specialized instruction does just that.
9450 (define_insn "get_fnaddr"
9451 [(set (match_operand 0 "register_operand" "=d")
9452 (unspec [(match_operand 1 "" "")] 1))
9453 (clobber (reg:SI 31))]
9454 "TARGET_EMBEDDED_PIC
9455 && GET_CODE (operands[1]) == SYMBOL_REF"
9456 "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
9457 [(set_attr "type" "call")
9458 (set_attr "mode" "none")
9459 (set_attr "length" "16")])
9463 ;; ....................
9467 ;; ....................
9469 ;; calls.c now passes a third argument, make saber happy
9471 (define_expand "call"
9472 [(parallel [(call (match_operand 0 "memory_operand" "m")
9473 (match_operand 1 "" "i"))
9474 (clobber (reg:SI 31))
9475 (use (match_operand 2 "" "")) ;; next_arg_reg
9476 (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
9482 if (operands[0]) /* eliminate unused code warnings */
9484 addr = XEXP (operands[0], 0);
9485 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9486 || ! call_insn_operand (addr, VOIDmode))
9487 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
9489 /* In order to pass small structures by value in registers
9490 compatibly with the MIPS compiler, we need to shift the value
9491 into the high part of the register. Function_arg has encoded
9492 a PARALLEL rtx, holding a vector of adjustments to be made
9493 as the next_arg_reg variable, so we split up the insns,
9494 and emit them separately. */
9496 if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
9498 rtvec adjust = XVEC (operands[2], 0);
9499 int num = GET_NUM_ELEM (adjust);
9502 for (i = 0; i < num; i++)
9503 emit_insn (RTVEC_ELT (adjust, i));
9507 && mips16_hard_float
9509 && (int) GET_MODE (operands[2]) != 0)
9511 if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1],
9512 (int) GET_MODE (operands[2])))
9516 emit_call_insn (gen_call_internal0 (operands[0], operands[1],
9517 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
9523 (define_expand "call_internal0"
9524 [(parallel [(call (match_operand 0 "" "")
9525 (match_operand 1 "" ""))
9526 (clobber (match_operand:SI 2 "" ""))])]
9530 ;; We need to recognize reg:SI 31 specially for the mips16, because we
9531 ;; don't have a constraint letter for it.
9534 [(call (mem (match_operand 0 "call_insn_operand" "ei"))
9535 (match_operand 1 "" "i"))
9536 (clobber (match_operand:SI 2 "register_operand" "=y"))]
9537 "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9538 && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9540 [(set_attr "type" "call")
9541 (set_attr "mode" "none")
9542 (set_attr "length" "8")])
9544 (define_insn "call_internal1"
9545 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9546 (match_operand 1 "" "i"))
9547 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9548 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9551 register rtx target = operands[0];
9553 if (GET_CODE (target) == SYMBOL_REF)
9554 return \"%*jal\\t%0\";
9555 else if (GET_CODE (target) == CONST_INT)
9556 return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
9558 return \"%*jal\\t%2,%0\";
9560 [(set_attr "type" "call")
9561 (set_attr "mode" "none")])
9563 (define_insn "call_internal2"
9564 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9565 (match_operand 1 "" "i"))
9566 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9567 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9570 register rtx target = operands[0];
9572 if (GET_CODE (target) == SYMBOL_REF)
9574 if (GET_MODE (target) == SImode)
9575 return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
9577 return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
9579 else if (GET_CODE (target) == CONST_INT)
9580 return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
9581 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9582 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9584 return \"jal\\t%2,%0\";
9586 [(set_attr "type" "call")
9587 (set_attr "mode" "none")
9588 (set_attr "length" "8")])
9590 (define_insn "call_internal3a"
9591 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9592 (match_operand 1 "" "i"))
9593 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9594 "!(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9596 [(set_attr "type" "call")
9597 (set_attr "mode" "none")])
9599 (define_insn "call_internal3b"
9600 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9601 (match_operand 1 "" "i"))
9602 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9603 "Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9605 [(set_attr "type" "call")
9606 (set_attr "mode" "none")])
9608 (define_insn "call_internal4a"
9609 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9610 (match_operand 1 "" "i"))
9611 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9612 "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
9615 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9616 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9618 return \"jal\\t%2,%0\";
9620 [(set_attr "type" "call")
9621 (set_attr "mode" "none")
9622 (set_attr "length" "8")])
9624 (define_insn "call_internal4b"
9625 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9626 (match_operand 1 "" "i"))
9627 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9628 "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
9631 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9632 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9634 return \"jal\\t%2,%0\";
9636 [(set_attr "type" "call")
9637 (set_attr "mode" "none")
9638 (set_attr "length" "8")])
9640 ;; calls.c now passes a fourth argument, make saber happy
9642 (define_expand "call_value"
9643 [(parallel [(set (match_operand 0 "register_operand" "=df")
9644 (call (match_operand 1 "memory_operand" "m")
9645 (match_operand 2 "" "i")))
9646 (clobber (reg:SI 31))
9647 (use (match_operand 3 "" ""))])] ;; next_arg_reg
9653 if (operands[0]) /* eliminate unused code warning */
9655 addr = XEXP (operands[1], 0);
9656 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9657 || ! call_insn_operand (addr, VOIDmode))
9658 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
9660 /* In order to pass small structures by value in registers
9661 compatibly with the MIPS compiler, we need to shift the value
9662 into the high part of the register. Function_arg has encoded
9663 a PARALLEL rtx, holding a vector of adjustments to be made
9664 as the next_arg_reg variable, so we split up the insns,
9665 and emit them separately. */
9667 if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
9669 rtvec adjust = XVEC (operands[3], 0);
9670 int num = GET_NUM_ELEM (adjust);
9673 for (i = 0; i < num; i++)
9674 emit_insn (RTVEC_ELT (adjust, i));
9678 && mips16_hard_float
9679 && ((operands[3] != 0
9680 && (int) GET_MODE (operands[3]) != 0)
9681 || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT))
9683 if (build_mips16_call_stub (operands[0], operands[1], operands[2],
9684 (operands[3] == 0 ? 0
9685 : (int) GET_MODE (operands[3]))))
9689 /* Handle Irix6 function calls that have multiple non-contiguous
9691 if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
9693 emit_call_insn (gen_call_value_multiple_internal0
9694 (XEXP (XVECEXP (operands[0], 0, 0), 0),
9695 operands[1], operands[2],
9696 XEXP (XVECEXP (operands[0], 0, 1), 0),
9697 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
9701 /* We have a call returning a DImode structure in an FP reg.
9702 Strip off the now unnecessary PARALLEL. */
9703 if (GET_CODE (operands[0]) == PARALLEL)
9704 operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
9706 emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
9707 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
9713 (define_expand "call_value_internal0"
9714 [(parallel [(set (match_operand 0 "" "")
9715 (call (match_operand 1 "" "")
9716 (match_operand 2 "" "")))
9717 (clobber (match_operand:SI 3 "" ""))])]
9721 ;; Recognize $31 specially on the mips16, because we don't have a
9722 ;; constraint letter for it.
9725 [(set (match_operand 0 "register_operand" "=d")
9726 (call (mem (match_operand 1 "call_insn_operand" "ei"))
9727 (match_operand 2 "" "i")))
9728 (clobber (match_operand:SI 3 "register_operand" "=y"))]
9729 "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9730 && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
9732 [(set_attr "type" "call")
9733 (set_attr "mode" "none")
9734 (set_attr "length" "8")])
9736 (define_insn "call_value_internal1"
9737 [(set (match_operand 0 "register_operand" "=df")
9738 (call (mem (match_operand 1 "call_insn_operand" "ri"))
9739 (match_operand 2 "" "i")))
9740 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9741 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9744 register rtx target = operands[1];
9746 if (GET_CODE (target) == SYMBOL_REF)
9747 return \"%*jal\\t%1\";
9748 else if (GET_CODE (target) == CONST_INT)
9749 return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
9751 return \"%*jal\\t%3,%1\";
9753 [(set_attr "type" "call")
9754 (set_attr "mode" "none")])
9756 (define_insn "call_value_internal2"
9757 [(set (match_operand 0 "register_operand" "=df")
9758 (call (mem (match_operand 1 "call_insn_operand" "ri"))
9759 (match_operand 2 "" "i")))
9760 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9761 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9764 register rtx target = operands[1];
9766 if (GET_CODE (target) == SYMBOL_REF)
9768 if (GET_MODE (target) == SImode)
9769 return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
9771 return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
9773 else if (GET_CODE (target) == CONST_INT)
9774 return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
9775 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9776 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9778 return \"jal\\t%3,%1\";
9780 [(set_attr "type" "call")
9781 (set_attr "mode" "none")
9782 (set_attr "length" "8")])
9784 (define_insn "call_value_internal3a"
9785 [(set (match_operand 0 "register_operand" "=df")
9786 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
9787 (match_operand 2 "" "i")))
9788 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9790 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9792 [(set_attr "type" "call")
9793 (set_attr "mode" "none")])
9795 (define_insn "call_value_internal3b"
9796 [(set (match_operand 0 "register_operand" "=df")
9797 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
9798 (match_operand 2 "" "i")))
9799 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9801 && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9803 [(set_attr "type" "call")
9804 (set_attr "mode" "none")])
9806 (define_insn "call_value_internal3c"
9807 [(set (match_operand 0 "register_operand" "=df")
9808 (call (mem:SI (match_operand:SI 1 "register_operand" "e"))
9809 (match_operand 2 "" "i")))
9810 (clobber (match_operand:SI 3 "register_operand" "=y"))]
9811 "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
9812 && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
9814 [(set_attr "type" "call")
9815 (set_attr "mode" "none")])
9817 (define_insn "call_value_internal4a"
9818 [(set (match_operand 0 "register_operand" "=df")
9819 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
9820 (match_operand 2 "" "i")))
9821 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9822 "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
9825 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
9826 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9828 return \"jal\\t%3,%1\";
9830 [(set_attr "type" "call")
9831 (set_attr "mode" "none")
9832 (set_attr "length" "8")])
9834 (define_insn "call_value_internal4b"
9835 [(set (match_operand 0 "register_operand" "=df")
9836 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
9837 (match_operand 2 "" "i")))
9838 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9839 "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
9842 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
9843 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9845 return \"jal\\t%3,%1\";
9847 [(set_attr "type" "call")
9848 (set_attr "mode" "none")
9849 (set_attr "length" "8")])
9851 (define_expand "call_value_multiple_internal0"
9852 [(parallel [(set (match_operand 0 "" "")
9853 (call (match_operand 1 "" "")
9854 (match_operand 2 "" "")))
9855 (set (match_operand 3 "" "")
9858 (clobber (match_operand:SI 4 "" ""))])]
9862 ;; ??? May eventually need all 6 versions of the call patterns with multiple
9865 (define_insn "call_value_multiple_internal2"
9866 [(set (match_operand 0 "register_operand" "=df")
9867 (call (mem (match_operand 1 "call_insn_operand" "ri"))
9868 (match_operand 2 "" "i")))
9869 (set (match_operand 3 "register_operand" "=df")
9870 (call (mem (match_dup 1))
9872 (clobber (match_operand:SI 4 "register_operand" "=d"))]
9873 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9876 register rtx target = operands[1];
9878 if (GET_CODE (target) == SYMBOL_REF)
9880 if (GET_MODE (target) == SImode)
9881 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
9883 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
9885 else if (GET_CODE (target) == CONST_INT)
9886 return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
9887 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9888 return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
9890 return \"jal\\t%4,%1\";
9892 [(set_attr "type" "call")
9893 (set_attr "mode" "none")
9894 (set_attr "length" "8")])
9897 ;; Call subroutine returning any type.
9899 (define_expand "untyped_call"
9900 [(parallel [(call (match_operand 0 "" "")
9902 (match_operand 1 "" "")
9903 (match_operand 2 "" "")])]
9907 if (operands[0]) /* silence statement not reached warnings */
9911 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
9913 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9915 rtx set = XVECEXP (operands[2], 0, i);
9916 emit_move_insn (SET_DEST (set), SET_SRC (set));
9919 emit_insn (gen_blockage ());
9925 ;; ....................
9929 ;; ....................
9936 [(set_attr "type" "nop")
9937 (set_attr "mode" "none")])
9939 ;; The MIPS chip does not seem to require stack probes.
9941 ;; (define_expand "probe"
9942 ;; [(set (match_dup 0)
9947 ;; operands[0] = gen_reg_rtx (SImode);
9948 ;; operands[1] = gen_rtx (MEM, SImode, stack_pointer_rtx);
9949 ;; MEM_VOLATILE_P (operands[1]) = TRUE;
9951 ;; /* fall through and generate default code */
9956 ;; MIPS4 Conditional move instructions.
9959 [(set (match_operand:SI 0 "register_operand" "=d,d")
9961 (match_operator 4 "equality_op"
9962 [(match_operand:SI 1 "register_operand" "d,d")
9964 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
9965 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
9970 [(set_attr "type" "move")
9971 (set_attr "mode" "SI")])
9974 [(set (match_operand:SI 0 "register_operand" "=d,d")
9976 (match_operator 4 "equality_op"
9977 [(match_operand:DI 1 "se_register_operand" "d,d")
9979 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
9980 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
9985 [(set_attr "type" "move")
9986 (set_attr "mode" "SI")])
9989 [(set (match_operand:SI 0 "register_operand" "=d,d")
9991 (match_operator 3 "equality_op" [(match_operand:CC 4
9995 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
9996 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
9997 "mips_isa >= 4 && TARGET_HARD_FLOAT"
10000 mov%t3\\t%0,%z2,%4"
10001 [(set_attr "type" "move")
10002 (set_attr "mode" "SI")])
10005 [(set (match_operand:DI 0 "register_operand" "=d,d")
10007 (match_operator 4 "equality_op"
10008 [(match_operand:SI 1 "register_operand" "d,d")
10010 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10011 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10015 mov%b4\\t%0,%z3,%1"
10016 [(set_attr "type" "move")
10017 (set_attr "mode" "DI")])
10020 [(set (match_operand:DI 0 "register_operand" "=d,d")
10022 (match_operator 4 "equality_op"
10023 [(match_operand:DI 1 "se_register_operand" "d,d")
10025 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10026 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10030 mov%b4\\t%0,%z3,%1"
10031 [(set_attr "type" "move")
10032 (set_attr "mode" "DI")])
10035 [(set (match_operand:DI 0 "register_operand" "=d,d")
10037 (match_operator 3 "equality_op" [(match_operand:CC 4
10041 (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
10042 (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
10043 "mips_isa >= 4 && TARGET_HARD_FLOAT"
10046 mov%t3\\t%0,%z2,%4"
10047 [(set_attr "type" "move")
10048 (set_attr "mode" "DI")])
10051 [(set (match_operand:SF 0 "register_operand" "=f,f")
10053 (match_operator 4 "equality_op"
10054 [(match_operand:SI 1 "register_operand" "d,d")
10056 (match_operand:SF 2 "register_operand" "f,0")
10057 (match_operand:SF 3 "register_operand" "0,f")))]
10058 "mips_isa >= 4 && TARGET_HARD_FLOAT"
10060 mov%B4.s\\t%0,%2,%1
10061 mov%b4.s\\t%0,%3,%1"
10062 [(set_attr "type" "move")
10063 (set_attr "mode" "SF")])
10066 [(set (match_operand:SF 0 "register_operand" "=f,f")
10068 (match_operator 3 "equality_op" [(match_operand:CC 4
10072 (match_operand:SF 1 "register_operand" "f,0")
10073 (match_operand:SF 2 "register_operand" "0,f")))]
10074 "mips_isa >= 4 && TARGET_HARD_FLOAT"
10076 mov%T3.s\\t%0,%1,%4
10077 mov%t3.s\\t%0,%2,%4"
10078 [(set_attr "type" "move")
10079 (set_attr "mode" "SF")])
10082 [(set (match_operand:DF 0 "register_operand" "=f,f")
10084 (match_operator 4 "equality_op"
10085 [(match_operand:SI 1 "register_operand" "d,d")
10087 (match_operand:DF 2 "register_operand" "f,0")
10088 (match_operand:DF 3 "register_operand" "0,f")))]
10089 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10091 mov%B4.d\\t%0,%2,%1
10092 mov%b4.d\\t%0,%3,%1"
10093 [(set_attr "type" "move")
10094 (set_attr "mode" "DF")])
10097 [(set (match_operand:DF 0 "register_operand" "=f,f")
10099 (match_operator 3 "equality_op" [(match_operand:CC 4
10103 (match_operand:DF 1 "register_operand" "f,0")
10104 (match_operand:DF 2 "register_operand" "0,f")))]
10105 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10107 mov%T3.d\\t%0,%1,%4
10108 mov%t3.d\\t%0,%2,%4"
10109 [(set_attr "type" "move")
10110 (set_attr "mode" "DF")])
10112 ;; These are the main define_expand's used to make conditional moves.
10114 (define_expand "movsicc"
10115 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10116 (set (match_operand:SI 0 "register_operand" "")
10117 (if_then_else:SI (match_dup 5)
10118 (match_operand:SI 2 "reg_or_0_operand" "")
10119 (match_operand:SI 3 "reg_or_0_operand" "")))]
10123 gen_conditional_move (operands);
10127 (define_expand "movdicc"
10128 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10129 (set (match_operand:DI 0 "register_operand" "")
10130 (if_then_else:DI (match_dup 5)
10131 (match_operand:DI 2 "se_reg_or_0_operand" "")
10132 (match_operand:DI 3 "se_reg_or_0_operand" "")))]
10136 gen_conditional_move (operands);
10140 (define_expand "movsfcc"
10141 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10142 (set (match_operand:SF 0 "register_operand" "")
10143 (if_then_else:SF (match_dup 5)
10144 (match_operand:SF 2 "register_operand" "")
10145 (match_operand:SF 3 "register_operand" "")))]
10146 "mips_isa >= 4 && TARGET_HARD_FLOAT"
10149 gen_conditional_move (operands);
10153 (define_expand "movdfcc"
10154 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10155 (set (match_operand:DF 0 "register_operand" "")
10156 (if_then_else:DF (match_dup 5)
10157 (match_operand:DF 2 "register_operand" "")
10158 (match_operand:DF 3 "register_operand" "")))]
10159 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10162 gen_conditional_move (operands);
10167 ;; ....................
10169 ;; mips16 inline constant tables
10171 ;; ....................
10174 (define_insn "consttable_qi"
10175 [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")] 10)]
10179 assemble_integer (operands[0], 1, 1);
10182 [(set_attr "type" "unknown")
10183 (set_attr "mode" "QI")
10184 (set_attr "length" "8")])
10186 (define_insn "consttable_hi"
10187 [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")] 11)]
10191 assemble_integer (operands[0], 2, 1);
10194 [(set_attr "type" "unknown")
10195 (set_attr "mode" "HI")
10196 (set_attr "length" "8")])
10198 (define_insn "consttable_si"
10199 [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")] 12)]
10203 assemble_integer (operands[0], 4, 1);
10206 [(set_attr "type" "unknown")
10207 (set_attr "mode" "SI")
10208 (set_attr "length" "8")])
10210 (define_insn "consttable_di"
10211 [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")] 13)]
10215 assemble_integer (operands[0], 8, 1);
10218 [(set_attr "type" "unknown")
10219 (set_attr "mode" "DI")
10220 (set_attr "length" "16")])
10222 (define_insn "consttable_sf"
10223 [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")] 14)]
10227 union real_extract u;
10229 if (GET_CODE (operands[0]) != CONST_DOUBLE)
10231 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
10232 assemble_real (u.d, SFmode);
10235 [(set_attr "type" "unknown")
10236 (set_attr "mode" "SF")
10237 (set_attr "length" "8")])
10239 (define_insn "consttable_df"
10240 [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")] 15)]
10244 union real_extract u;
10246 if (GET_CODE (operands[0]) != CONST_DOUBLE)
10248 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
10249 assemble_real (u.d, DFmode);
10252 [(set_attr "type" "unknown")
10253 (set_attr "mode" "DF")
10254 (set_attr "length" "16")])
10256 (define_insn "align_2"
10257 [(unspec_volatile [(const_int 0)] 16)]
10260 [(set_attr "type" "unknown")
10261 (set_attr "mode" "HI")
10262 (set_attr "length" "8")])
10264 (define_insn "align_4"
10265 [(unspec_volatile [(const_int 0)] 17)]
10268 [(set_attr "type" "unknown")
10269 (set_attr "mode" "SI")
10270 (set_attr "length" "8")])
10272 (define_insn "align_8"
10273 [(unspec_volatile [(const_int 0)] 18)]
10276 [(set_attr "type" "unknown")
10277 (set_attr "mode" "DI")
10278 (set_attr "length" "12")])
10281 ;; ....................
10283 ;; mips16 peepholes
10285 ;; ....................
10288 ;; On the mips16, reload will sometimes decide that a pseudo register
10289 ;; should go into $24, and then later on have to reload that register.
10290 ;; When that happens, we get a load of a general register followed by
10291 ;; a move from the general register to $24 followed by a branch.
10292 ;; These peepholes catch the common case, and fix it to just use the
10293 ;; general register for the branch.
10296 [(set (match_operand:SI 0 "register_operand" "=t")
10297 (match_operand:SI 1 "register_operand" "d"))
10299 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10301 (match_operand 3 "pc_or_label_operand" "")
10302 (match_operand 4 "pc_or_label_operand" "")))]
10304 && GET_CODE (operands[0]) == REG
10305 && REGNO (operands[0]) == 24
10306 && dead_or_set_p (insn, operands[0])
10307 && GET_CODE (operands[1]) == REG
10308 && M16_REG_P (REGNO (operands[1]))"
10311 if (operands[3] != pc_rtx)
10312 return \"%*b%C2z\\t%1,%3\";
10314 return \"%*b%N2z\\t%1,%4\";
10316 [(set_attr "type" "branch")
10317 (set_attr "mode" "none")
10318 (set_attr "length" "8")])
10321 [(set (match_operand:DI 0 "register_operand" "=t")
10322 (match_operand:DI 1 "register_operand" "d"))
10324 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10326 (match_operand 3 "pc_or_label_operand" "")
10327 (match_operand 4 "pc_or_label_operand" "")))]
10328 "TARGET_MIPS16 && TARGET_64BIT
10329 && GET_CODE (operands[0]) == REG
10330 && REGNO (operands[0]) == 24
10331 && dead_or_set_p (insn, operands[0])
10332 && GET_CODE (operands[1]) == REG
10333 && M16_REG_P (REGNO (operands[1]))"
10336 if (operands[3] != pc_rtx)
10337 return \"%*b%C2z\\t%1,%3\";
10339 return \"%*b%N2z\\t%1,%4\";
10341 [(set_attr "type" "branch")
10342 (set_attr "mode" "none")
10343 (set_attr "length" "8")])
10345 ;; We can also have the reverse reload: reload will spill $24 into
10346 ;; another register, and then do a branch on that register when it
10347 ;; could have just stuck with $24.
10350 [(set (match_operand:SI 0 "register_operand" "=d")
10351 (match_operand:SI 1 "register_operand" "t"))
10353 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10355 (match_operand 3 "pc_or_label_operand" "")
10356 (match_operand 4 "pc_or_label_operand" "")))]
10358 && GET_CODE (operands[1]) == REG
10359 && REGNO (operands[1]) == 24
10360 && GET_CODE (operands[0]) == REG
10361 && M16_REG_P (REGNO (operands[0]))
10362 && dead_or_set_p (insn, operands[0])"
10365 if (operands[3] != pc_rtx)
10366 return \"%*bt%C2z\\t%3\";
10368 return \"%*bt%N2z\\t%4\";
10370 [(set_attr "type" "branch")
10371 (set_attr "mode" "none")
10372 (set_attr "length" "8")])
10375 [(set (match_operand:DI 0 "register_operand" "=d")
10376 (match_operand:DI 1 "register_operand" "t"))
10378 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10380 (match_operand 3 "pc_or_label_operand" "")
10381 (match_operand 4 "pc_or_label_operand" "")))]
10382 "TARGET_MIPS16 && TARGET_64BIT
10383 && GET_CODE (operands[1]) == REG
10384 && REGNO (operands[1]) == 24
10385 && GET_CODE (operands[0]) == REG
10386 && M16_REG_P (REGNO (operands[0]))
10387 && dead_or_set_p (insn, operands[0])"
10390 if (operands[3] != pc_rtx)
10391 return \"%*bt%C2z\\t%3\";
10393 return \"%*bt%N2z\\t%4\";
10395 [(set_attr "type" "branch")
10396 (set_attr "mode" "none")
10397 (set_attr "length" "8")])
10399 ;; For the rare case where we need to load an address into a register
10400 ;; that can not be recognized by the normal movsi/addsi instructions.
10401 ;; I have no idea how many insns this can actually generate. It should
10402 ;; be rare, so over-estimating as 10 instructions should not have any
10403 ;; real performance impact.
10404 (define_insn "leasi"
10405 [(set (match_operand:SI 0 "register_operand" "=d")
10406 (match_operand:SI 1 "address_operand" "p"))]
10409 [(set_attr "type" "arith")
10410 (set_attr "mode" "SI")
10411 (set_attr "length" "40")])
10413 ;; Similarly for targets where we have 64bit pointers.
10414 (define_insn "leadi"
10415 [(set (match_operand:DI 0 "register_operand" "=d")
10416 (match_operand:DI 1 "address_operand" "p"))]
10419 [(set_attr "type" "arith")
10420 (set_attr "mode" "DI")
10421 (set_attr "length" "40")])