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, 91, 92, 93, 94, 95 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 ;; ??? MIPS4 has 8 floating point condition codes. This is not supported yet.
27 ;; ??? MIPS4 has floating point doubleword/word load/stores that accept a
28 ;; base+index addressing mode. There are no such load/stores for the integer
29 ;; registers. This is not supported yet.
31 ;; ??? Currently does not have define_function_unit support for the R8000.
32 ;; Must include new entries for fmadd in addition to existing entries.
36 ;; ....................
40 ;; ....................
42 ;; Classification of each insn.
43 ;; branch conditional branch
44 ;; jump unconditional jump
45 ;; call unconditional call
46 ;; load load instruction(s)
47 ;; store store instruction(s)
48 ;; move data movement within same register set
49 ;; xfer transfer to/from coprocessor
50 ;; hilo transfer of hi/lo registers
51 ;; arith integer arithmetic instruction
52 ;; darith double precision integer arithmetic instructions
53 ;; imul integer multiply
54 ;; idiv integer divide
55 ;; icmp integer compare
56 ;; fadd floating point add/subtract
57 ;; fmul floating point multiply
58 ;; fmadd floating point multiply-add
59 ;; fdiv floating point divide
60 ;; fabs floating point absolute value
61 ;; fneg floating point negation
62 ;; fcmp floating point compare
63 ;; fcvt floating point convert
64 ;; fsqrt floating point square root
65 ;; multi multiword sequence (or user asm statements)
69 "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"
70 (const_string "unknown"))
72 ;; Main data type used by the insn
73 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
75 ;; # instructions (4 bytes each)
76 (define_attr "length" "" (const_int 1))
78 ;; whether or not an instruction has a mandatory delay slot
79 (define_attr "dslot" "no,yes"
80 (if_then_else (eq_attr "type" "branch,jump,call,load,xfer,hilo,fcmp")
84 ;; Attribute describing the processor. This attribute must match exactly
85 ;; with the processor_type enumeration in mips.h.
87 ;; Attribute describing the processor
88 ;; (define_attr "cpu" "default,r3000,r6000,r4000"
90 ;; (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000")) (const_string "r3000")
91 ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000")) (const_string "r4000")
92 ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000")) (const_string "r6000")]
93 ;; (const_string "default"))))
95 ;; ??? Fix everything that tests this attribute.
96 (define_attr "cpu" "default,r3000,r6000,r4000,r4600,r4650,r8000"
97 (const (symbol_ref "mips_cpu_attr")))
99 ;; Attribute defining whether or not we can use the branch-likely instructions
100 ;; (MIPS ISA level 2)
102 (define_attr "branch_likely" "no,yes"
104 (if_then_else (ge (symbol_ref "mips_isa") (const_int 2))
106 (const_string "no"))))
109 ;; Describe a user's asm statement.
110 (define_asm_attributes
111 [(set_attr "type" "multi")])
113 ;; whether or not generating calls to position independent functions
114 (define_attr "abicalls" "no,yes"
115 (const (symbol_ref "mips_abicalls_attr")))
119 ;; .........................
121 ;; Delay slots, can't describe load/fcmp/xfer delay slots here
123 ;; .........................
125 (define_delay (eq_attr "type" "branch")
126 [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
128 (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "1")))])
130 (define_delay (eq_attr "type" "jump")
131 [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
135 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
136 [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
142 ;; .........................
146 ;; .........................
148 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
149 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
151 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
153 (define_function_unit "memory" 1 0
154 (and (eq_attr "type" "load") (eq_attr "cpu" "!r3000,r4600,r4650"))
157 (define_function_unit "memory" 1 0
158 (and (eq_attr "type" "load") (eq_attr "cpu" "r3000,r4600,r4650"))
161 (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
163 (define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)
165 (define_function_unit "imuldiv" 1 0
166 (eq_attr "type" "hilo")
169 (define_function_unit "imuldiv" 1 0
170 (and (eq_attr "type" "imul") (eq_attr "cpu" "!r3000,r4000,r4600,r4650"))
173 (define_function_unit "imuldiv" 1 0
174 (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000"))
177 (define_function_unit "imuldiv" 1 0
178 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
181 (define_function_unit "imuldiv" 1 0
182 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4650"))
185 (define_function_unit "imuldiv" 1 0
186 (and (eq_attr "type" "idiv") (eq_attr "cpu" "!r3000,r4000,r4600,r4650"))
189 (define_function_unit "imuldiv" 1 0
190 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000"))
193 (define_function_unit "imuldiv" 1 0
194 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
197 (define_function_unit "imuldiv" 1 0
198 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
201 (define_function_unit "imuldiv" 1 0
202 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
205 (define_function_unit "adder" 1 1
206 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r6000"))
209 (define_function_unit "adder" 1 1
210 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r6000"))
213 (define_function_unit "adder" 1 1
214 (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r6000"))
217 (define_function_unit "adder" 1 1
218 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000"))
221 (define_function_unit "adder" 1 1
222 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
225 (define_function_unit "adder" 1 1
226 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "!r3000,r4600,r4650"))
229 (define_function_unit "adder" 1 1
230 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r4600,r4650"))
233 (define_function_unit "mult" 1 1
234 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000,r4600,r4650")))
237 (define_function_unit "mult" 1 1
238 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000")))
241 (define_function_unit "mult" 1 1
242 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
245 (define_function_unit "mult" 1 1
246 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
249 (define_function_unit "mult" 1 1
250 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000")))
253 (define_function_unit "mult" 1 1
254 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000")))
257 (define_function_unit "mult" 1 1
258 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
261 (define_function_unit "divide" 1 1
262 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000,r4600,r4650")))
265 (define_function_unit "divide" 1 1
266 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000")))
269 (define_function_unit "divide" 1 1
270 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
273 (define_function_unit "divide" 1 1
274 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
277 (define_function_unit "divide" 1 1
278 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000,r4600,r4650")))
281 (define_function_unit "divide" 1 1
282 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000")))
285 (define_function_unit "divide" 1 1
286 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
289 (define_function_unit "divide" 1 1
290 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
293 ;;; ??? Is this number right?
294 (define_function_unit "divide" 1 1
295 (and (eq_attr "type" "fsqrt") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650")))
297 (define_function_unit "divide" 1 1
298 (and (eq_attr "type" "fsqrt") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
301 ;;; ??? Is this number right?
302 (define_function_unit "divide" 1 1
303 (and (eq_attr "type" "fsqrt") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650")))
305 (define_function_unit "divide" 1 1
306 (and (eq_attr "type" "fsqrt") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
310 ;; The following functional units do not use the cpu type, and use
311 ;; much less memory in genattrtab.c.
313 ;; (define_function_unit "memory" 1 0 (eq_attr "type" "load") 3 0)
314 ;; (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
316 ;; (define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0)
318 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0)
319 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0)
321 ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "imul") 17 0)
322 ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "idiv") 38 0)
324 ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fadd") 4 0)
325 ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fabs,fneg") 2 0)
327 ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF")) 7 0)
328 ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF")) 8 0)
330 ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF")) 23 0)
331 ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF")) 36 0)
333 ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0)
334 ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
338 ;; ....................
342 ;; ....................
345 (define_insn "adddf3"
346 [(set (match_operand:DF 0 "register_operand" "=f")
347 (plus:DF (match_operand:DF 1 "register_operand" "f")
348 (match_operand:DF 2 "register_operand" "f")))]
349 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
351 [(set_attr "type" "fadd")
352 (set_attr "mode" "DF")
353 (set_attr "length" "1")])
355 (define_insn "addsf3"
356 [(set (match_operand:SF 0 "register_operand" "=f")
357 (plus:SF (match_operand:SF 1 "register_operand" "f")
358 (match_operand:SF 2 "register_operand" "f")))]
361 [(set_attr "type" "fadd")
362 (set_attr "mode" "SF")
363 (set_attr "length" "1")])
365 (define_expand "addsi3"
366 [(set (match_operand:SI 0 "register_operand" "=d")
367 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
368 (match_operand:SI 2 "arith_operand" "dI")))]
372 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
373 operands[2] = force_reg (SImode, operands[2]);
376 (define_insn "addsi3_internal"
377 [(set (match_operand:SI 0 "register_operand" "=d")
378 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
379 (match_operand:SI 2 "arith_operand" "dI")))]
380 "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768"
382 [(set_attr "type" "arith")
383 (set_attr "mode" "SI")
384 (set_attr "length" "1")])
386 (define_expand "adddi3"
387 [(parallel [(set (match_operand:DI 0 "register_operand" "")
388 (plus:DI (match_operand:DI 1 "register_operand" "")
389 (match_operand:DI 2 "arith_operand" "")))
390 (clobber (match_dup 3))])]
391 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
394 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
395 operands[2] = force_reg (DImode, operands[2]);
399 emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
404 operands[3] = gen_reg_rtx (SImode);
407 (define_insn "adddi3_internal_1"
408 [(set (match_operand:DI 0 "register_operand" "=d,&d")
409 (plus:DI (match_operand:DI 1 "register_operand" "0,d")
410 (match_operand:DI 2 "register_operand" "d,d")))
411 (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
412 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
415 return (REGNO (operands[0]) == REGNO (operands[1])
416 && REGNO (operands[0]) == REGNO (operands[2]))
417 ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
418 : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
420 [(set_attr "type" "darith")
421 (set_attr "mode" "DI")
422 (set_attr "length" "4")])
425 [(set (match_operand:DI 0 "register_operand" "")
426 (plus:DI (match_operand:DI 1 "register_operand" "")
427 (match_operand:DI 2 "register_operand" "")))
428 (clobber (match_operand:SI 3 "register_operand" ""))]
429 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
430 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
431 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
432 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
433 && (REGNO (operands[0]) != REGNO (operands[1])
434 || REGNO (operands[0]) != REGNO (operands[2]))"
436 [(set (subreg:SI (match_dup 0) 0)
437 (plus:SI (subreg:SI (match_dup 1) 0)
438 (subreg:SI (match_dup 2) 0)))
441 (ltu:SI (subreg:SI (match_dup 0) 0)
442 (subreg:SI (match_dup 2) 0)))
444 (set (subreg:SI (match_dup 0) 1)
445 (plus:SI (subreg:SI (match_dup 1) 1)
446 (subreg:SI (match_dup 2) 1)))
448 (set (subreg:SI (match_dup 0) 1)
449 (plus:SI (subreg:SI (match_dup 0) 1)
454 [(set (match_operand:DI 0 "register_operand" "")
455 (plus:DI (match_operand:DI 1 "register_operand" "")
456 (match_operand:DI 2 "register_operand" "")))
457 (clobber (match_operand:SI 3 "register_operand" ""))]
458 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
459 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
460 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
461 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
462 && (REGNO (operands[0]) != REGNO (operands[1])
463 || REGNO (operands[0]) != REGNO (operands[2]))"
465 [(set (subreg:SI (match_dup 0) 1)
466 (plus:SI (subreg:SI (match_dup 1) 1)
467 (subreg:SI (match_dup 2) 1)))
470 (ltu:SI (subreg:SI (match_dup 0) 1)
471 (subreg:SI (match_dup 2) 1)))
473 (set (subreg:SI (match_dup 0) 0)
474 (plus:SI (subreg:SI (match_dup 1) 0)
475 (subreg:SI (match_dup 2) 0)))
477 (set (subreg:SI (match_dup 0) 0)
478 (plus:SI (subreg:SI (match_dup 0) 0)
482 (define_insn "adddi3_internal_2"
483 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
484 (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
485 (match_operand:DI 2 "small_int" "P,J,N")))
486 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
487 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768"
489 addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
490 move\\t%L0,%L1\;move\\t%M0,%M1
491 subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
492 [(set_attr "type" "darith")
493 (set_attr "mode" "DI")
494 (set_attr "length" "3,2,4")])
497 [(set (match_operand:DI 0 "register_operand" "")
498 (plus:DI (match_operand:DI 1 "register_operand" "")
499 (match_operand:DI 2 "small_int" "")))
500 (clobber (match_operand:SI 3 "register_operand" "=d"))]
501 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
502 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
503 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
504 && INTVAL (operands[2]) > 0"
506 [(set (subreg:SI (match_dup 0) 0)
507 (plus:SI (subreg:SI (match_dup 1) 0)
511 (ltu:SI (subreg:SI (match_dup 0) 0)
514 (set (subreg:SI (match_dup 0) 1)
515 (plus:SI (subreg:SI (match_dup 1) 1)
520 [(set (match_operand:DI 0 "register_operand" "")
521 (plus:DI (match_operand:DI 1 "register_operand" "")
522 (match_operand:DI 2 "small_int" "")))
523 (clobber (match_operand:SI 3 "register_operand" "=d"))]
524 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
525 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
526 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
527 && INTVAL (operands[2]) > 0"
529 [(set (subreg:SI (match_dup 0) 1)
530 (plus:SI (subreg:SI (match_dup 1) 1)
534 (ltu:SI (subreg:SI (match_dup 0) 1)
537 (set (subreg:SI (match_dup 0) 0)
538 (plus:SI (subreg:SI (match_dup 1) 0)
542 (define_insn "adddi3_internal_3"
543 [(set (match_operand:DI 0 "register_operand" "=d")
544 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ")
545 (match_operand:DI 2 "arith_operand" "dI")))]
546 "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
549 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
550 ? \"dsubu\\t%0,%z1,%n2\"
551 : \"daddu\\t%0,%z1,%2\";
553 [(set_attr "type" "darith")
554 (set_attr "mode" "DI")
555 (set_attr "length" "1")])
558 (define_insn "addsi3_internal_2"
559 [(set (match_operand:DI 0 "register_operand" "=d")
560 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
561 (match_operand:SI 2 "arith_operand" "dI"))))]
562 "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
565 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
566 ? \"subu\\t%0,%z1,%n2\"
567 : \"addu\\t%0,%z1,%2\";
569 [(set_attr "type" "arith")
570 (set_attr "mode" "SI")
571 (set_attr "length" "1")])
575 ;; ....................
579 ;; ....................
582 (define_insn "subdf3"
583 [(set (match_operand:DF 0 "register_operand" "=f")
584 (minus:DF (match_operand:DF 1 "register_operand" "f")
585 (match_operand:DF 2 "register_operand" "f")))]
586 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
588 [(set_attr "type" "fadd")
589 (set_attr "mode" "DF")
590 (set_attr "length" "1")])
592 (define_insn "subsf3"
593 [(set (match_operand:SF 0 "register_operand" "=f")
594 (minus:SF (match_operand:SF 1 "register_operand" "f")
595 (match_operand:SF 2 "register_operand" "f")))]
598 [(set_attr "type" "fadd")
599 (set_attr "mode" "SF")
600 (set_attr "length" "1")])
602 (define_expand "subsi3"
603 [(set (match_operand:SI 0 "register_operand" "=d")
604 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
605 (match_operand:SI 2 "arith_operand" "dI")))]
609 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
610 operands[2] = force_reg (SImode, operands[2]);
613 (define_insn "subsi3_internal"
614 [(set (match_operand:SI 0 "register_operand" "=d")
615 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
616 (match_operand:SI 2 "arith_operand" "dI")))]
617 "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768"
619 [(set_attr "type" "arith")
620 (set_attr "mode" "SI")
621 (set_attr "length" "1")])
623 (define_expand "subdi3"
624 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
625 (minus:DI (match_operand:DI 1 "register_operand" "d")
626 (match_operand:DI 2 "register_operand" "d")))
627 (clobber (match_dup 3))])]
628 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
633 emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
638 operands[3] = gen_reg_rtx (SImode);
641 (define_insn "subdi3_internal"
642 [(set (match_operand:DI 0 "register_operand" "=d")
643 (minus:DI (match_operand:DI 1 "register_operand" "d")
644 (match_operand:DI 2 "register_operand" "d")))
645 (clobber (match_operand:SI 3 "register_operand" "=d"))]
646 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
647 "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
648 [(set_attr "type" "darith")
649 (set_attr "mode" "DI")
650 (set_attr "length" "4")])
653 [(set (match_operand:DI 0 "register_operand" "")
654 (minus:DI (match_operand:DI 1 "register_operand" "")
655 (match_operand:DI 2 "register_operand" "")))
656 (clobber (match_operand:SI 3 "register_operand" ""))]
657 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
658 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
659 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
660 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
663 (ltu:SI (subreg:SI (match_dup 1) 0)
664 (subreg:SI (match_dup 2) 0)))
666 (set (subreg:SI (match_dup 0) 0)
667 (minus:SI (subreg:SI (match_dup 1) 0)
668 (subreg:SI (match_dup 2) 0)))
670 (set (subreg:SI (match_dup 0) 1)
671 (minus:SI (subreg:SI (match_dup 1) 1)
672 (subreg:SI (match_dup 2) 1)))
674 (set (subreg:SI (match_dup 0) 1)
675 (minus:SI (subreg:SI (match_dup 0) 1)
680 [(set (match_operand:DI 0 "register_operand" "")
681 (minus:DI (match_operand:DI 1 "register_operand" "")
682 (match_operand:DI 2 "register_operand" "")))
683 (clobber (match_operand:SI 3 "register_operand" ""))]
684 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
685 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
686 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
687 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
690 (ltu:SI (subreg:SI (match_dup 1) 1)
691 (subreg:SI (match_dup 2) 1)))
693 (set (subreg:SI (match_dup 0) 1)
694 (minus:SI (subreg:SI (match_dup 1) 1)
695 (subreg:SI (match_dup 2) 1)))
697 (set (subreg:SI (match_dup 0) 0)
698 (minus:SI (subreg:SI (match_dup 1) 0)
699 (subreg:SI (match_dup 2) 0)))
701 (set (subreg:SI (match_dup 0) 0)
702 (minus:SI (subreg:SI (match_dup 0) 0)
706 (define_insn "subdi3_internal_2"
707 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
708 (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
709 (match_operand:DI 2 "small_int" "P,J,N")))
710 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
711 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768"
713 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
714 move\\t%L0,%L1\;move\\t%M0,%M1
715 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
716 [(set_attr "type" "darith")
717 (set_attr "mode" "DI")
718 (set_attr "length" "3,2,4")])
721 [(set (match_operand:DI 0 "register_operand" "")
722 (minus:DI (match_operand:DI 1 "register_operand" "")
723 (match_operand:DI 2 "small_int" "")))
724 (clobber (match_operand:SI 3 "register_operand" ""))]
725 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
726 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
727 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
728 && INTVAL (operands[2]) > 0"
731 (ltu:SI (subreg:SI (match_dup 1) 0)
734 (set (subreg:SI (match_dup 0) 0)
735 (minus:SI (subreg:SI (match_dup 1) 0)
738 (set (subreg:SI (match_dup 0) 1)
739 (minus:SI (subreg:SI (match_dup 1) 1)
744 [(set (match_operand:DI 0 "register_operand" "")
745 (minus:DI (match_operand:DI 1 "register_operand" "")
746 (match_operand:DI 2 "small_int" "")))
747 (clobber (match_operand:SI 3 "register_operand" ""))]
748 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
749 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
750 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
751 && INTVAL (operands[2]) > 0"
754 (ltu:SI (subreg:SI (match_dup 1) 1)
757 (set (subreg:SI (match_dup 0) 1)
758 (minus:SI (subreg:SI (match_dup 1) 1)
761 (set (subreg:SI (match_dup 0) 0)
762 (minus:SI (subreg:SI (match_dup 1) 0)
766 (define_insn "subdi3_internal_3"
767 [(set (match_operand:DI 0 "register_operand" "=d")
768 (minus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ")
769 (match_operand:DI 2 "arith_operand" "dI")))]
770 "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
773 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
774 ? \"daddu\\t%0,%z1,%n2\"
775 : \"dsubu\\t%0,%z1,%2\";
777 [(set_attr "type" "darith")
778 (set_attr "mode" "DI")
779 (set_attr "length" "1")])
782 (define_insn "subsi3_internal_2"
783 [(set (match_operand:DI 0 "register_operand" "=d")
784 (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
785 (match_operand:SI 2 "arith_operand" "dI"))))]
786 "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
789 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
790 ? \"addu\\t%0,%z1,%n2\"
791 : \"subu\\t%0,%z1,%2\";
793 [(set_attr "type" "arith")
794 (set_attr "mode" "DI")
795 (set_attr "length" "1")])
799 ;; ....................
803 ;; ....................
806 (define_insn "muldf3"
807 [(set (match_operand:DF 0 "register_operand" "=f")
808 (mult:DF (match_operand:DF 1 "register_operand" "f")
809 (match_operand:DF 2 "register_operand" "f")))]
810 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
812 [(set_attr "type" "fmul")
813 (set_attr "mode" "DF")
814 (set_attr "length" "1")])
816 (define_insn "mulsf3"
817 [(set (match_operand:SF 0 "register_operand" "=f")
818 (mult:SF (match_operand:SF 1 "register_operand" "f")
819 (match_operand:SF 2 "register_operand" "f")))]
822 [(set_attr "type" "fmul")
823 (set_attr "mode" "SF")
824 (set_attr "length" "1")])
826 ;; ??? The R4000 (only) has a cpu bug. If a double-word shift executes while
827 ;; a multiply is in progress, it may give an incorrect result. Avoid
828 ;; this by keeping the mflo with the mult on the R4000.
830 (define_expand "mulsi3"
831 [(set (match_operand:SI 0 "register_operand" "=l")
832 (mult:SI (match_operand:SI 1 "register_operand" "d")
833 (match_operand:SI 2 "register_operand" "d")))
834 (clobber (match_scratch:SI 3 "=h"))
835 (clobber (match_scratch:SI 4 "=a"))]
840 emit_insn (gen_mulsi3_r4650 (operands[0], operands[1], operands[2]));
841 else if (mips_cpu != PROCESSOR_R4000)
842 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
844 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
848 (define_insn "mulsi3_internal"
849 [(set (match_operand:SI 0 "register_operand" "=l")
850 (mult:SI (match_operand:SI 1 "register_operand" "d")
851 (match_operand:SI 2 "register_operand" "d")))
852 (clobber (match_scratch:SI 3 "=h"))
853 (clobber (match_scratch:SI 4 "=a"))]
854 "mips_cpu != PROCESSOR_R4000"
856 [(set_attr "type" "imul")
857 (set_attr "mode" "SI")
858 (set_attr "length" "1")])
860 (define_insn "mulsi3_r4000"
861 [(set (match_operand:SI 0 "register_operand" "=d")
862 (mult:SI (match_operand:SI 1 "register_operand" "d")
863 (match_operand:SI 2 "register_operand" "d")))
864 (clobber (match_scratch:SI 3 "=h"))
865 (clobber (match_scratch:SI 4 "=l"))
866 (clobber (match_scratch:SI 5 "=a"))]
867 "mips_cpu == PROCESSOR_R4000"
872 xoperands[0] = operands[0];
873 xoperands[1] = gen_rtx (REG, SImode, LO_REGNUM);
875 output_asm_insn (\"mult\\t%1,%2\", operands);
876 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
879 [(set_attr "type" "imul")
880 (set_attr "mode" "SI")
881 (set_attr "length" "3")]) ;; mult + mflo + delay
883 (define_insn "mulsi3_r4650"
884 [(set (match_operand:SI 0 "register_operand" "=d")
885 (mult:SI (match_operand:SI 1 "register_operand" "d")
886 (match_operand:SI 2 "register_operand" "d")))
887 (clobber (match_scratch:SI 3 "=h"))
888 (clobber (match_scratch:SI 4 "=l"))
889 (clobber (match_scratch:SI 5 "=a"))]
892 [(set_attr "type" "imul")
893 (set_attr "mode" "SI")
894 (set_attr "length" "1")])
896 (define_expand "muldi3"
897 [(set (match_operand:DI 0 "register_operand" "=l")
898 (mult:DI (match_operand:DI 1 "register_operand" "d")
899 (match_operand:DI 2 "register_operand" "d")))
900 (clobber (match_scratch:DI 3 "=h"))
901 (clobber (match_scratch:DI 4 "=a"))]
905 if (mips_cpu != PROCESSOR_R4000)
906 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
908 emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
912 (define_insn "muldi3_internal"
913 [(set (match_operand:DI 0 "register_operand" "=l")
914 (mult:DI (match_operand:DI 1 "register_operand" "d")
915 (match_operand:DI 2 "register_operand" "d")))
916 (clobber (match_scratch:DI 3 "=h"))
917 (clobber (match_scratch:DI 4 "=a"))]
918 "TARGET_64BIT && mips_cpu != PROCESSOR_R4000"
920 [(set_attr "type" "imul")
921 (set_attr "mode" "DI")
922 (set_attr "length" "1")])
924 (define_insn "muldi3_r4000"
925 [(set (match_operand:DI 0 "register_operand" "=d")
926 (mult:DI (match_operand:DI 1 "register_operand" "d")
927 (match_operand:DI 2 "register_operand" "d")))
928 (clobber (match_scratch:DI 3 "=h"))
929 (clobber (match_scratch:DI 4 "=l"))
930 (clobber (match_scratch:DI 5 "=a"))]
931 "TARGET_64BIT && mips_cpu == PROCESSOR_R4000"
936 xoperands[0] = operands[0];
937 xoperands[1] = gen_rtx (REG, DImode, LO_REGNUM);
939 output_asm_insn (\"dmult\\t%1,%2\", operands);
940 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
943 [(set_attr "type" "imul")
944 (set_attr "mode" "DI")
945 (set_attr "length" "3")]) ;; mult + mflo + delay
947 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
949 (define_expand "mulsidi3"
950 [(set (match_operand:DI 0 "register_operand" "=x")
951 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
952 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
957 emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2]));
959 emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2]));
963 (define_insn "mulsidi3_internal"
964 [(set (match_operand:DI 0 "register_operand" "=x")
965 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
966 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
967 (clobber (match_scratch:SI 3 "=a"))]
970 [(set_attr "type" "imul")
971 (set_attr "mode" "SI")
972 (set_attr "length" "1")])
974 (define_insn "mulsidi3_64bit"
975 [(set (match_operand:DI 0 "register_operand" "=a")
976 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
977 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
978 (clobber (match_scratch:DI 3 "=l"))
979 (clobber (match_scratch:DI 4 "=h"))]
982 [(set_attr "type" "imul")
983 (set_attr "mode" "SI")
984 (set_attr "length" "1")])
986 (define_insn "smulsi3_highpart"
987 [(set (match_operand:SI 0 "register_operand" "=h")
989 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
990 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
992 (clobber (match_scratch:SI 3 "=l"))
993 (clobber (match_scratch:SI 4 "=a"))]
996 [(set_attr "type" "imul")
997 (set_attr "mode" "SI")
998 (set_attr "length" "1")])
1000 (define_expand "umulsidi3"
1001 [(set (match_operand:DI 0 "register_operand" "=x")
1002 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1003 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1008 emit_insn (gen_umulsidi3_64bit (operands[0], operands[1], operands[2]));
1010 emit_insn (gen_umulsidi3_internal (operands[0], operands[1], operands[2]));
1014 (define_insn "umulsidi3_internal"
1015 [(set (match_operand:DI 0 "register_operand" "=x")
1016 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1017 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1018 (clobber (match_scratch:SI 3 "=a"))]
1021 [(set_attr "type" "imul")
1022 (set_attr "mode" "SI")
1023 (set_attr "length" "1")])
1025 (define_insn "umulsidi3_64bit"
1026 [(set (match_operand:DI 0 "register_operand" "=a")
1027 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1028 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1029 (clobber (match_scratch:DI 3 "=l"))
1030 (clobber (match_scratch:DI 4 "=h"))]
1033 [(set_attr "type" "imul")
1034 (set_attr "mode" "SI")
1035 (set_attr "length" "1")])
1037 (define_insn "umulsi3_highpart"
1038 [(set (match_operand:SI 0 "register_operand" "=h")
1040 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1041 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1043 (clobber (match_scratch:SI 3 "=l"))
1044 (clobber (match_scratch:SI 4 "=a"))]
1047 [(set_attr "type" "imul")
1048 (set_attr "mode" "SI")
1049 (set_attr "length" "1")])
1051 (define_insn "smuldi3_highpart"
1052 [(set (match_operand:DI 0 "register_operand" "=h")
1054 (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "register_operand" "d"))
1055 (sign_extend:TI (match_operand:DI 2 "register_operand" "d")))
1057 (clobber (match_scratch:DI 3 "=l"))
1058 (clobber (match_scratch:DI 4 "=a"))]
1061 [(set_attr "type" "imul")
1062 (set_attr "mode" "DI")
1063 (set_attr "length" "1")])
1065 (define_insn "umuldi3_highpart"
1066 [(set (match_operand:DI 0 "register_operand" "=h")
1068 (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "d"))
1069 (zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
1071 (clobber (match_scratch:DI 3 "=l"))
1072 (clobber (match_scratch:DI 4 "=a"))]
1075 [(set_attr "type" "imul")
1076 (set_attr "mode" "DI")
1077 (set_attr "length" "1")])
1079 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1080 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
1082 (define_insn "madsi"
1083 [(set (match_operand:SI 0 "register_operand" "+l")
1084 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1085 (match_operand:SI 2 "register_operand" "d"))
1087 (clobber (match_scratch:SI 3 "=h"))
1088 (clobber (match_scratch:SI 4 "=a"))]
1091 [(set_attr "type" "imul")
1092 (set_attr "mode" "SI")
1093 (set_attr "length" "1")])
1095 (define_insn "maddi"
1096 [(set (match_operand:DI 0 "register_operand" "+x")
1097 (plus:DI (mult:DI (sign_extend:DI
1098 (match_operand:SI 1 "register_operand" "d"))
1100 (match_operand:SI 2 "register_operand" "d")))
1102 (clobber (match_scratch:SI 3 "=a"))]
1103 "TARGET_MAD && ! TARGET_64BIT"
1105 [(set_attr "type" "imul")
1106 (set_attr "mode" "SI")
1107 (set_attr "length" "1")])
1109 (define_insn "maddi_64bit"
1110 [(set (match_operand:DI 0 "register_operand" "+a")
1111 (plus:DI (mult:DI (sign_extend:DI
1112 (match_operand:SI 1 "register_operand" "d"))
1114 (match_operand:SI 2 "register_operand" "d")))
1116 (clobber (match_scratch:DI 3 "=l"))
1117 (clobber (match_scratch:DI 4 "=h"))]
1118 "TARGET_MAD && TARGET_64BIT"
1120 [(set_attr "type" "imul")
1121 (set_attr "mode" "SI")
1122 (set_attr "length" "1")])
1124 (define_insn "umaddi"
1125 [(set (match_operand:DI 0 "register_operand" "+x")
1126 (plus:DI (mult:DI (zero_extend:DI
1127 (match_operand:SI 1 "register_operand" "d"))
1129 (match_operand:SI 2 "register_operand" "d")))
1131 (clobber (match_scratch:SI 3 "=a"))]
1132 "TARGET_MAD && ! TARGET_64BIT"
1134 [(set_attr "type" "imul")
1135 (set_attr "mode" "SI")
1136 (set_attr "length" "1")])
1138 (define_insn "umaddi_64bit"
1139 [(set (match_operand:DI 0 "register_operand" "+a")
1140 (plus:DI (mult:DI (zero_extend:DI
1141 (match_operand:SI 1 "register_operand" "d"))
1143 (match_operand:SI 2 "register_operand" "d")))
1145 (clobber (match_scratch:DI 3 "=l"))
1146 (clobber (match_scratch:DI 4 "=h"))]
1147 "TARGET_MAD && TARGET_64BIT"
1149 [(set_attr "type" "imul")
1150 (set_attr "mode" "SI")
1151 (set_attr "length" "1")])
1153 ;; Floating point multiply accumulate instructions.
1156 [(set (match_operand:DF 0 "register_operand" "=f")
1157 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1158 (match_operand:DF 2 "register_operand" "f"))
1159 (match_operand:DF 3 "register_operand" "f")))]
1160 "mips_isa >= 4 && TARGET_HARD_FLOAT"
1161 "madd.d\\t%0,%3,%1,%2"
1162 [(set_attr "type" "fmadd")
1163 (set_attr "mode" "DF")
1164 (set_attr "length" "1")])
1167 [(set (match_operand:SF 0 "register_operand" "=f")
1168 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1169 (match_operand:SF 2 "register_operand" "f"))
1170 (match_operand:SF 3 "register_operand" "f")))]
1171 "mips_isa >= 4 && TARGET_HARD_FLOAT"
1172 "madd.s\\t%0,%3,%1,%2"
1173 [(set_attr "type" "fmadd")
1174 (set_attr "mode" "SF")
1175 (set_attr "length" "1")])
1178 [(set (match_operand:DF 0 "register_operand" "=f")
1179 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1180 (match_operand:DF 2 "register_operand" "f"))
1181 (match_operand:DF 3 "register_operand" "f")))]
1182 "mips_isa >= 4 && TARGET_HARD_FLOAT"
1183 "msub.d\\t%0,%3,%1,%2"
1184 [(set_attr "type" "fmadd")
1185 (set_attr "mode" "DF")
1186 (set_attr "length" "1")])
1189 [(set (match_operand:SF 0 "register_operand" "=f")
1190 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1191 (match_operand:SF 2 "register_operand" "f"))
1192 (match_operand:SF 3 "register_operand" "f")))]
1194 "mips_isa >= 4 && TARGET_HARD_FLOAT"
1195 "msub.s\\t%0,%3,%1,%2"
1196 [(set_attr "type" "fmadd")
1197 (set_attr "mode" "SF")
1198 (set_attr "length" "1")])
1201 [(set (match_operand:DF 0 "register_operand" "=f")
1202 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1203 (match_operand:DF 2 "register_operand" "f"))
1204 (match_operand:DF 3 "register_operand" "f"))))]
1205 "mips_isa >= 4 && TARGET_HARD_FLOAT"
1206 "nmadd.d\\t%0,%3,%1,%2"
1207 [(set_attr "type" "fmadd")
1208 (set_attr "mode" "DF")
1209 (set_attr "length" "1")])
1212 [(set (match_operand:SF 0 "register_operand" "=f")
1213 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1214 (match_operand:SF 2 "register_operand" "f"))
1215 (match_operand:SF 3 "register_operand" "f"))))]
1216 "mips_isa >= 4 && TARGET_HARD_FLOAT"
1217 "nmadd.s\\t%0,%3,%1,%2"
1218 [(set_attr "type" "fmadd")
1219 (set_attr "mode" "SF")
1220 (set_attr "length" "1")])
1223 [(set (match_operand:DF 0 "register_operand" "=f")
1224 (minus:DF (match_operand:DF 1 "register_operand" "f")
1225 (mult:DF (match_operand:DF 2 "register_operand" "f")
1226 (match_operand:DF 3 "register_operand" "f"))))]
1227 "mips_isa >= 4 && TARGET_HARD_FLOAT"
1228 "nmsub.d\\t%0,%1,%2,%3"
1229 [(set_attr "type" "fmadd")
1230 (set_attr "mode" "DF")
1231 (set_attr "length" "1")])
1234 [(set (match_operand:SF 0 "register_operand" "=f")
1235 (minus:SF (match_operand:SF 1 "register_operand" "f")
1236 (mult:SF (match_operand:SF 2 "register_operand" "f")
1237 (match_operand:SF 3 "register_operand" "f"))))]
1238 "mips_isa >= 4 && TARGET_HARD_FLOAT"
1239 "nmsub.s\\t%0,%1,%2,%3"
1240 [(set_attr "type" "fmadd")
1241 (set_attr "mode" "SF")
1242 (set_attr "length" "1")])
1245 ;; ....................
1247 ;; DIVISION and REMAINDER
1249 ;; ....................
1252 (define_insn "divdf3"
1253 [(set (match_operand:DF 0 "register_operand" "=f")
1254 (div:DF (match_operand:DF 1 "register_operand" "f")
1255 (match_operand:DF 2 "register_operand" "f")))]
1256 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1258 [(set_attr "type" "fdiv")
1259 (set_attr "mode" "DF")
1260 (set_attr "length" "1")])
1262 (define_insn "divsf3"
1263 [(set (match_operand:SF 0 "register_operand" "=f")
1264 (div:SF (match_operand:SF 1 "register_operand" "f")
1265 (match_operand:SF 2 "register_operand" "f")))]
1268 [(set_attr "type" "fdiv")
1269 (set_attr "mode" "SF")
1270 (set_attr "length" "1")])
1272 ;; If optimizing, prefer the divmod functions over separate div and
1273 ;; mod functions, since this will allow using one instruction for both
1274 ;; the quotient and remainder. At present, the divmod is not moved out
1275 ;; of loops if it is constant within the loop, so allow -mdebugc to
1276 ;; use the old method of doing things.
1278 ;; 64 is the multiply/divide hi register
1279 ;; 65 is the multiply/divide lo register
1281 ;; ??? We can't accept constants here, because the MIPS assembler will replace
1282 ;; a divide by power of 2 with a shift, and then the remainder is no longer
1285 (define_insn "divmodsi4"
1286 [(set (match_operand:SI 0 "register_operand" "=d")
1287 (div:SI (match_operand:SI 1 "register_operand" "d")
1288 (match_operand:SI 2 "register_operand" "d")))
1289 (set (match_operand:SI 3 "register_operand" "=d")
1290 (mod:SI (match_dup 1)
1292 (clobber (match_scratch:SI 4 "=l"))
1293 (clobber (match_scratch:SI 5 "=h"))
1294 (clobber (match_scratch:SI 6 "=a"))]
1298 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1299 return \"div\\t%0,%1,%2\";
1301 if (find_reg_note (insn, REG_UNUSED, operands[0]))
1302 return \"rem\\t%3,%1,%2\";
1304 return \"div\\t%0,%1,%2\;mfhi\\t%3\";
1306 [(set_attr "type" "idiv")
1307 (set_attr "mode" "SI")
1308 (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
1310 (define_insn "divmoddi4"
1311 [(set (match_operand:DI 0 "register_operand" "=d")
1312 (div:DI (match_operand:DI 1 "register_operand" "d")
1313 (match_operand:DI 2 "register_operand" "d")))
1314 (set (match_operand:DI 3 "register_operand" "=d")
1315 (mod:DI (match_dup 1)
1317 (clobber (match_scratch:DI 4 "=l"))
1318 (clobber (match_scratch:DI 5 "=h"))
1319 (clobber (match_scratch:DI 6 "=a"))]
1320 "TARGET_64BIT && optimize"
1323 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1324 return \"ddiv\\t%0,%1,%2\";
1326 if (find_reg_note (insn, REG_UNUSED, operands[0]))
1327 return \"drem\\t%3,%1,%2\";
1329 return \"ddiv\\t%0,%1,%2\;mfhi\\t%3\";
1331 [(set_attr "type" "idiv")
1332 (set_attr "mode" "DI")
1333 (set_attr "length" "15")]) ;; various tests for dividing by 0 and such
1335 (define_insn "udivmodsi4"
1336 [(set (match_operand:SI 0 "register_operand" "=d")
1337 (udiv:SI (match_operand:SI 1 "register_operand" "d")
1338 (match_operand:SI 2 "register_operand" "d")))
1339 (set (match_operand:SI 3 "register_operand" "=d")
1340 (umod:SI (match_dup 1)
1342 (clobber (match_scratch:SI 4 "=l"))
1343 (clobber (match_scratch:SI 5 "=h"))
1344 (clobber (match_scratch:SI 6 "=a"))]
1348 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1349 return \"divu\\t%0,%1,%2\";
1351 if (find_reg_note (insn, REG_UNUSED, operands[0]))
1352 return \"remu\\t%3,%1,%2\";
1354 return \"divu\\t%0,%1,%2\;mfhi\\t%3\";
1356 [(set_attr "type" "idiv")
1357 (set_attr "mode" "SI")
1358 (set_attr "length" "8")]) ;; various tests for dividing by 0 and such
1360 (define_insn "udivmoddi4"
1361 [(set (match_operand:DI 0 "register_operand" "=d")
1362 (udiv:DI (match_operand:DI 1 "register_operand" "d")
1363 (match_operand:DI 2 "register_operand" "d")))
1364 (set (match_operand:DI 3 "register_operand" "=d")
1365 (umod:DI (match_dup 1)
1367 (clobber (match_scratch:DI 4 "=l"))
1368 (clobber (match_scratch:DI 5 "=h"))
1369 (clobber (match_scratch:DI 6 "=a"))]
1370 "TARGET_64BIT && optimize"
1373 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1374 return \"ddivu\\t%0,%1,%2\";
1376 if (find_reg_note (insn, REG_UNUSED, operands[0]))
1377 return \"dremu\\t%3,%1,%2\";
1379 return \"ddivu\\t%0,%1,%2\;mfhi\\t%3\";
1381 [(set_attr "type" "idiv")
1382 (set_attr "mode" "DI")
1383 (set_attr "length" "8")]) ;; various tests for dividing by 0 and such
1385 (define_insn "divsi3"
1386 [(set (match_operand:SI 0 "register_operand" "=d")
1387 (div:SI (match_operand:SI 1 "register_operand" "d")
1388 (match_operand:SI 2 "nonmemory_operand" "di")))
1389 (clobber (match_scratch:SI 3 "=l"))
1390 (clobber (match_scratch:SI 4 "=h"))
1391 (clobber (match_scratch:SI 6 "=a"))]
1394 [(set_attr "type" "idiv")
1395 (set_attr "mode" "SI")
1396 (set_attr "length" "13")]) ;; various tests for dividing by 0 and such
1398 (define_insn "divdi3"
1399 [(set (match_operand:DI 0 "register_operand" "=d")
1400 (div:DI (match_operand:DI 1 "register_operand" "d")
1401 (match_operand:DI 2 "nonmemory_operand" "di")))
1402 (clobber (match_scratch:DI 3 "=l"))
1403 (clobber (match_scratch:DI 4 "=h"))
1404 (clobber (match_scratch:DI 6 "=a"))]
1405 "TARGET_64BIT && !optimize"
1407 [(set_attr "type" "idiv")
1408 (set_attr "mode" "DI")
1409 (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
1411 (define_insn "modsi3"
1412 [(set (match_operand:SI 0 "register_operand" "=d")
1413 (mod:SI (match_operand:SI 1 "register_operand" "d")
1414 (match_operand:SI 2 "nonmemory_operand" "di")))
1415 (clobber (match_scratch:SI 3 "=l"))
1416 (clobber (match_scratch:SI 4 "=h"))
1417 (clobber (match_scratch:SI 6 "=a"))]
1420 [(set_attr "type" "idiv")
1421 (set_attr "mode" "SI")
1422 (set_attr "length" "13")]) ;; various tests for dividing by 0 and such
1424 (define_insn "moddi3"
1425 [(set (match_operand:DI 0 "register_operand" "=d")
1426 (mod:DI (match_operand:DI 1 "register_operand" "d")
1427 (match_operand:DI 2 "nonmemory_operand" "di")))
1428 (clobber (match_scratch:DI 3 "=l"))
1429 (clobber (match_scratch:DI 4 "=h"))
1430 (clobber (match_scratch:DI 6 "=a"))]
1431 "TARGET_64BIT && !optimize"
1433 [(set_attr "type" "idiv")
1434 (set_attr "mode" "DI")
1435 (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
1437 (define_insn "udivsi3"
1438 [(set (match_operand:SI 0 "register_operand" "=d")
1439 (udiv:SI (match_operand:SI 1 "register_operand" "d")
1440 (match_operand:SI 2 "nonmemory_operand" "di")))
1441 (clobber (match_scratch:SI 3 "=l"))
1442 (clobber (match_scratch:SI 4 "=h"))
1443 (clobber (match_scratch:SI 6 "=a"))]
1446 [(set_attr "type" "idiv")
1447 (set_attr "mode" "SI")
1448 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
1450 (define_insn "udivdi3"
1451 [(set (match_operand:DI 0 "register_operand" "=d")
1452 (udiv:DI (match_operand:DI 1 "register_operand" "d")
1453 (match_operand:DI 2 "nonmemory_operand" "di")))
1454 (clobber (match_scratch:DI 3 "=l"))
1455 (clobber (match_scratch:DI 4 "=h"))
1456 (clobber (match_scratch:DI 6 "=a"))]
1457 "TARGET_64BIT && !optimize"
1459 [(set_attr "type" "idiv")
1460 (set_attr "mode" "DI")
1461 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
1463 (define_insn "umodsi3"
1464 [(set (match_operand:SI 0 "register_operand" "=d")
1465 (umod:SI (match_operand:SI 1 "register_operand" "d")
1466 (match_operand:SI 2 "nonmemory_operand" "di")))
1467 (clobber (match_scratch:SI 3 "=l"))
1468 (clobber (match_scratch:SI 4 "=h"))
1469 (clobber (match_scratch:SI 6 "=a"))]
1472 [(set_attr "type" "idiv")
1473 (set_attr "mode" "SI")
1474 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
1476 (define_insn "umoddi3"
1477 [(set (match_operand:DI 0 "register_operand" "=d")
1478 (umod:DI (match_operand:DI 1 "register_operand" "d")
1479 (match_operand:DI 2 "nonmemory_operand" "di")))
1480 (clobber (match_scratch:DI 3 "=l"))
1481 (clobber (match_scratch:DI 4 "=h"))
1482 (clobber (match_scratch:DI 6 "=a"))]
1483 "TARGET_64BIT && !optimize"
1485 [(set_attr "type" "idiv")
1486 (set_attr "mode" "DI")
1487 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
1491 ;; ....................
1495 ;; ....................
1497 (define_insn "sqrtdf2"
1498 [(set (match_operand:DF 0 "register_operand" "=f")
1499 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
1500 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
1502 [(set_attr "type" "fsqrt")
1503 (set_attr "mode" "DF")
1504 (set_attr "length" "1")])
1506 (define_insn "sqrtsf2"
1507 [(set (match_operand:SF 0 "register_operand" "=f")
1508 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
1509 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
1511 [(set_attr "type" "fsqrt")
1512 (set_attr "mode" "SF")
1513 (set_attr "length" "1")])
1517 ;; ....................
1521 ;; ....................
1523 ;; Do not use the integer abs macro instruction, since that signals an
1524 ;; exception on -2147483648 (sigh).
1526 (define_insn "abssi2"
1527 [(set (match_operand:SI 0 "register_operand" "=d")
1528 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
1532 dslots_jump_total++;
1533 dslots_jump_filled++;
1534 operands[2] = const0_rtx;
1536 if (REGNO (operands[0]) == REGNO (operands[1]))
1539 return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
1541 return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n1:\";
1544 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
1546 [(set_attr "type" "multi")
1547 (set_attr "mode" "SI")
1548 (set_attr "length" "3")])
1550 (define_insn "absdi2"
1551 [(set (match_operand:DI 0 "register_operand" "=d")
1552 (abs:DI (match_operand:DI 1 "register_operand" "d")))]
1556 dslots_jump_total++;
1557 dslots_jump_filled++;
1558 operands[2] = const0_rtx;
1560 if (REGNO (operands[0]) == REGNO (operands[1]))
1561 return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
1563 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
1565 [(set_attr "type" "multi")
1566 (set_attr "mode" "DI")
1567 (set_attr "length" "3")])
1569 (define_insn "absdf2"
1570 [(set (match_operand:DF 0 "register_operand" "=f")
1571 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
1572 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1574 [(set_attr "type" "fabs")
1575 (set_attr "mode" "DF")
1576 (set_attr "length" "1")])
1578 (define_insn "abssf2"
1579 [(set (match_operand:SF 0 "register_operand" "=f")
1580 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
1583 [(set_attr "type" "fabs")
1584 (set_attr "mode" "SF")
1585 (set_attr "length" "1")])
1589 ;; ....................
1591 ;; FIND FIRST BIT INSTRUCTION
1593 ;; ....................
1596 (define_insn "ffssi2"
1597 [(set (match_operand:SI 0 "register_operand" "=&d")
1598 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
1599 (clobber (match_scratch:SI 2 "=&d"))
1600 (clobber (match_scratch:SI 3 "=&d"))]
1604 dslots_jump_total += 2;
1605 dslots_jump_filled += 2;
1606 operands[4] = const0_rtx;
1608 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
1611 \\tbeq\\t%1,%z4,2f\\n\\
1612 1:\\tand\\t%2,%1,0x0001\\n\\
1613 \\taddu\\t%0,%0,1\\n\\
1614 \\tbeq\\t%2,%z4,1b\\n\\
1615 \\tsrl\\t%1,%1,1\\n\\
1620 \\tmove\\t%3,%1\\n\\
1621 \\tbeq\\t%3,%z4,2f\\n\\
1622 1:\\tand\\t%2,%3,0x0001\\n\\
1623 \\taddu\\t%0,%0,1\\n\\
1624 \\tbeq\\t%2,%z4,1b\\n\\
1625 \\tsrl\\t%3,%3,1\\n\\
1628 [(set_attr "type" "multi")
1629 (set_attr "mode" "SI")
1630 (set_attr "length" "6")])
1632 (define_insn "ffsdi2"
1633 [(set (match_operand:DI 0 "register_operand" "=&d")
1634 (ffs:DI (match_operand:DI 1 "register_operand" "d")))
1635 (clobber (match_scratch:DI 2 "=&d"))
1636 (clobber (match_scratch:DI 3 "=&d"))]
1640 dslots_jump_total += 2;
1641 dslots_jump_filled += 2;
1642 operands[4] = const0_rtx;
1644 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
1647 \\tbeq\\t%1,%z4,2f\\n\\
1648 1:\\tand\\t%2,%1,0x0001\\n\\
1649 \\tdaddu\\t%0,%0,1\\n\\
1650 \\tbeq\\t%2,%z4,1b\\n\\
1651 \\tdsrl\\t%1,%1,1\\n\\
1656 \\tmove\\t%3,%1\\n\\
1657 \\tbeq\\t%3,%z4,2f\\n\\
1658 1:\\tand\\t%2,%3,0x0001\\n\\
1659 \\tdaddu\\t%0,%0,1\\n\\
1660 \\tbeq\\t%2,%z4,1b\\n\\
1661 \\tdsrl\\t%3,%3,1\\n\\
1664 [(set_attr "type" "multi")
1665 (set_attr "mode" "DI")
1666 (set_attr "length" "6")])
1670 ;; ....................
1672 ;; NEGATION and ONE'S COMPLEMENT
1674 ;; ....................
1676 (define_insn "negsi2"
1677 [(set (match_operand:SI 0 "register_operand" "=d")
1678 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
1682 operands[2] = const0_rtx;
1683 return \"subu\\t%0,%z2,%1\";
1685 [(set_attr "type" "arith")
1686 (set_attr "mode" "SI")
1687 (set_attr "length" "1")])
1689 (define_expand "negdi2"
1690 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1691 (neg:DI (match_operand:DI 1 "register_operand" "d")))
1692 (clobber (match_dup 2))])]
1693 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
1698 emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
1702 operands[2] = gen_reg_rtx (SImode);
1705 (define_insn "negdi2_internal"
1706 [(set (match_operand:DI 0 "register_operand" "=d")
1707 (neg:DI (match_operand:DI 1 "register_operand" "d")))
1708 (clobber (match_operand:SI 2 "register_operand" "=d"))]
1709 "! TARGET_64BIT && !TARGET_DEBUG_G_MODE"
1712 operands[3] = const0_rtx;
1713 return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
1715 [(set_attr "type" "darith")
1716 (set_attr "mode" "DI")
1717 (set_attr "length" "4")])
1719 (define_insn "negdi2_internal_2"
1720 [(set (match_operand:DI 0 "register_operand" "=d")
1721 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
1725 operands[2] = const0_rtx;
1726 return \"dsubu\\t%0,%z2,%1\";
1728 [(set_attr "type" "arith")
1729 (set_attr "mode" "DI")
1730 (set_attr "length" "1")])
1732 (define_insn "negdf2"
1733 [(set (match_operand:DF 0 "register_operand" "=f")
1734 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1735 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1737 [(set_attr "type" "fneg")
1738 (set_attr "mode" "DF")
1739 (set_attr "length" "1")])
1741 (define_insn "negsf2"
1742 [(set (match_operand:SF 0 "register_operand" "=f")
1743 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1746 [(set_attr "type" "fneg")
1747 (set_attr "mode" "SF")
1748 (set_attr "length" "1")])
1750 (define_insn "one_cmplsi2"
1751 [(set (match_operand:SI 0 "register_operand" "=d")
1752 (not:SI (match_operand:SI 1 "register_operand" "d")))]
1756 operands[2] = const0_rtx;
1757 return \"nor\\t%0,%z2,%1\";
1759 [(set_attr "type" "arith")
1760 (set_attr "mode" "SI")
1761 (set_attr "length" "1")])
1763 (define_insn "one_cmpldi2"
1764 [(set (match_operand:DI 0 "register_operand" "=d")
1765 (not:DI (match_operand:DI 1 "register_operand" "d")))]
1769 operands[2] = const0_rtx;
1771 return \"nor\\t%0,%z2,%1\";
1772 return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
1774 [(set_attr "type" "darith")
1775 (set_attr "mode" "DI")
1776 (set (attr "length")
1777 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
1782 [(set (match_operand:DI 0 "register_operand" "")
1783 (not:DI (match_operand:DI 1 "register_operand" "")))]
1784 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1785 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1786 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
1788 [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
1789 (set (subreg:SI (match_dup 0) 1) (not:SI (subreg:SI (match_dup 1) 1)))]
1792 ;; Simple hack to recognize the "nor" instruction on the MIPS
1793 ;; This must appear before the normal or patterns, so that the
1794 ;; combiner will correctly fold things.
1796 (define_insn "norsi3"
1797 [(set (match_operand:SI 0 "register_operand" "=d")
1798 (not:SI (ior:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1799 (match_operand:SI 2 "reg_or_0_operand" "dJ"))))]
1802 [(set_attr "type" "arith")
1803 (set_attr "mode" "SI")
1804 (set_attr "length" "1")])
1806 (define_insn "nordi3"
1807 [(set (match_operand:DI 0 "register_operand" "=d")
1808 (not:DI (ior:DI (match_operand:DI 1 "register_operand" "d")
1809 (match_operand:DI 2 "register_operand" "d"))))]
1814 return \"nor\\t%0,%z1,%z2\";
1815 return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
1817 [(set_attr "type" "darith")
1818 (set_attr "mode" "DI")
1819 (set (attr "length")
1820 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
1825 [(set (match_operand:DI 0 "register_operand" "")
1826 (not:DI (ior:DI (match_operand:DI 1 "register_operand" "")
1827 (match_operand:DI 2 "register_operand" ""))))]
1828 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1829 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1830 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1831 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1833 [(set (subreg:SI (match_dup 0) 0) (not:SI (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0))))
1834 (set (subreg:SI (match_dup 0) 1) (not:SI (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1))))]
1839 ;; ....................
1843 ;; ....................
1846 (define_insn "andsi3"
1847 [(set (match_operand:SI 0 "register_operand" "=d,d")
1848 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
1849 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
1854 [(set_attr "type" "arith")
1855 (set_attr "mode" "SI")
1856 (set_attr "length" "1")])
1858 (define_insn "anddi3"
1859 [(set (match_operand:DI 0 "register_operand" "=d")
1860 (and:DI (match_operand:DI 1 "register_operand" "d")
1861 (match_operand:DI 2 "register_operand" "d")))]
1862 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
1866 return \"and\\t%0,%1,%2\";
1867 return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
1869 [(set_attr "type" "darith")
1870 (set_attr "mode" "DI")
1871 (set (attr "length")
1872 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
1877 [(set (match_operand:DI 0 "register_operand" "")
1878 (and:DI (match_operand:DI 1 "register_operand" "")
1879 (match_operand:DI 2 "register_operand" "")))]
1880 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1881 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1882 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1883 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1885 [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
1886 (set (subreg:SI (match_dup 0) 1) (and:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
1889 (define_insn "anddi3_internal1"
1890 [(set (match_operand:DI 0 "register_operand" "=d,d")
1891 (and:DI (match_operand:DI 1 "register_operand" "%d,d")
1892 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
1897 [(set_attr "type" "arith")
1898 (set_attr "mode" "DI")
1899 (set_attr "length" "1")])
1901 (define_insn "iorsi3"
1902 [(set (match_operand:SI 0 "register_operand" "=d,d")
1903 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
1904 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
1909 [(set_attr "type" "arith")
1910 (set_attr "mode" "SI")
1911 (set_attr "length" "1")])
1913 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
1916 (define_insn "iordi3"
1917 [(set (match_operand:DI 0 "register_operand" "=d")
1918 (ior:DI (match_operand:DI 1 "register_operand" "d")
1919 (match_operand:DI 2 "register_operand" "d")))]
1920 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
1924 return \"or\\t%0,%1,%2\";
1925 return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
1927 [(set_attr "type" "darith")
1928 (set_attr "mode" "DI")
1929 (set (attr "length")
1930 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
1935 [(set (match_operand:DI 0 "register_operand" "")
1936 (ior:DI (match_operand:DI 1 "register_operand" "")
1937 (match_operand:DI 2 "register_operand" "")))]
1938 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1939 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1940 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1941 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1943 [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
1944 (set (subreg:SI (match_dup 0) 1) (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
1947 (define_insn "xorsi3"
1948 [(set (match_operand:SI 0 "register_operand" "=d,d")
1949 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
1950 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
1955 [(set_attr "type" "arith")
1956 (set_attr "mode" "SI")
1957 (set_attr "length" "1")])
1959 ;; ??? If delete the 32-bit long long patterns, then could merge this with
1960 ;; the following xordi3_internal pattern.
1961 (define_insn "xordi3"
1962 [(set (match_operand:DI 0 "register_operand" "=d")
1963 (xor:DI (match_operand:DI 1 "register_operand" "d")
1964 (match_operand:DI 2 "register_operand" "d")))]
1965 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
1969 return \"xor\\t%0,%1,%2\";
1970 return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
1972 [(set_attr "type" "darith")
1973 (set_attr "mode" "DI")
1974 (set (attr "length")
1975 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
1980 [(set (match_operand:DI 0 "register_operand" "")
1981 (xor:DI (match_operand:DI 1 "register_operand" "")
1982 (match_operand:DI 2 "register_operand" "")))]
1983 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1984 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1985 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1986 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1988 [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
1989 (set (subreg:SI (match_dup 0) 1) (xor:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
1992 (define_insn "xordi3_immed"
1993 [(set (match_operand:DI 0 "register_operand" "d")
1994 (xor:DI (match_operand:DI 1 "register_operand" "d")
1995 (match_operand:DI 2 "uns_arith_operand" "K")))]
1998 [(set_attr "type" "arith")
1999 (set_attr "mode" "DI")
2000 (set_attr "length" "1")])
2004 ;; ....................
2008 ;; ....................
2010 (define_insn "truncdfsf2"
2011 [(set (match_operand:SF 0 "register_operand" "=f")
2012 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2013 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2015 [(set_attr "type" "fcvt")
2016 (set_attr "mode" "SF")
2017 (set_attr "length" "1")])
2019 (define_insn "truncdisi2"
2020 [(set (match_operand:SI 0 "register_operand" "=d")
2021 (truncate:SI (match_operand:DI 1 "register_operand" "d")))]
2023 "dsll\\t%0,%1,32\;dsra\\t%0,%0,32"
2024 [(set_attr "type" "darith")
2025 (set_attr "mode" "SI")
2026 (set_attr "length" "2")])
2028 (define_insn "truncdihi2"
2029 [(set (match_operand:HI 0 "register_operand" "=d")
2030 (truncate:HI (match_operand:DI 1 "register_operand" "d")))]
2032 "andi\\t%0,%1,0xffff"
2033 [(set_attr "type" "darith")
2034 (set_attr "mode" "HI")
2035 (set_attr "length" "1")])
2037 (define_insn "truncdiqi2"
2038 [(set (match_operand:QI 0 "register_operand" "=d")
2039 (truncate:QI (match_operand:DI 1 "register_operand" "d")))]
2041 "andi\\t%0,%1,0x00ff"
2042 [(set_attr "type" "darith")
2043 (set_attr "mode" "QI")
2044 (set_attr "length" "1")])
2046 ;; Combiner patterns to optimize shift/truncate combinations.
2048 [(set (match_operand:SI 0 "register_operand" "=d")
2049 (truncate:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2050 (match_operand:DI 2 "small_int" "I"))))]
2054 int shift_amt = INTVAL (operands[2]) & 0x3f;
2058 operands[2] = GEN_INT (32 - shift_amt);
2059 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
2063 operands[2] = GEN_INT (shift_amt);
2064 return \"dsra\\t%0,%1,%2\";
2067 [(set_attr "type" "darith")
2068 (set_attr "mode" "SI")
2069 (set_attr "length" "2")])
2072 [(set (match_operand:SI 0 "register_operand" "=d")
2073 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2074 (match_operand:DI 2 "small_int" "I"))))]
2078 int shift_amt = INTVAL (operands[2]) & 0x3f;
2082 operands[2] = GEN_INT (32 - shift_amt);
2083 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
2085 else if (shift_amt == 32)
2086 return \"dsra\\t%0,%1,32\";
2089 operands[2] = GEN_INT (shift_amt);
2090 return \"dsrl\\t%0,%1,%2\";
2093 [(set_attr "type" "darith")
2094 (set_attr "mode" "SI")
2095 (set_attr "length" "2")])
2098 [(set (match_operand:SI 0 "register_operand" "=d")
2099 (truncate:SI (ashift:DI (match_operand:DI 1 "register_operand" "d")
2100 (match_operand:DI 2 "small_int" "I"))))]
2104 int shift_amt = INTVAL (operands[2]) & 0x3f;
2108 operands[2] = GEN_INT (32 + shift_amt);
2109 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
2112 return \"move\\t%0,%.\";
2114 [(set_attr "type" "darith")
2115 (set_attr "mode" "SI")
2116 (set_attr "length" "2")])
2118 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2121 [(set (match_operand:SI 0 "register_operand" "=d")
2122 (zero_extend:SI (truncate:HI
2123 (match_operand:DI 1 "register_operand" "d"))))]
2125 "andi\\t%0,%1,0xffff"
2126 [(set_attr "type" "darith")
2127 (set_attr "mode" "SI")
2128 (set_attr "length" "1")])
2131 [(set (match_operand:SI 0 "register_operand" "=d")
2132 (zero_extend:SI (truncate:QI
2133 (match_operand:DI 1 "register_operand" "d"))))]
2136 [(set_attr "type" "darith")
2137 (set_attr "mode" "SI")
2138 (set_attr "length" "1")])
2141 [(set (match_operand:HI 0 "register_operand" "=d")
2142 (zero_extend:HI (truncate:QI
2143 (match_operand:DI 1 "register_operand" "d"))))]
2146 [(set_attr "type" "darith")
2147 (set_attr "mode" "HI")
2148 (set_attr "length" "1")])
2151 ;; ....................
2155 ;; ....................
2158 ;; Those for integer source operand are ordered widest source type first.
2160 (define_expand "zero_extendsidi2"
2161 [(set (match_operand:DI 0 "register_operand" "")
2162 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
2166 if (optimize && GET_CODE (operands[1]) == MEM)
2167 operands[1] = force_not_mem (operands[1]);
2169 if (GET_CODE (operands[1]) != MEM)
2171 rtx op1 = gen_lowpart (DImode, operands[1]);
2172 rtx temp = gen_reg_rtx (DImode);
2173 rtx shift = gen_rtx (CONST_INT, VOIDmode, 32);
2175 emit_insn (gen_ashldi3 (temp, op1, shift));
2176 emit_insn (gen_lshrdi3 (operands[0], temp, shift));
2181 (define_insn "zero_extendsidi2_internal"
2182 [(set (match_operand:DI 0 "register_operand" "=d,d")
2183 (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
2185 "* return mips_move_1word (operands, insn, TRUE);"
2186 [(set_attr "type" "load")
2187 (set_attr "mode" "DI")
2188 (set_attr "length" "1,2")])
2190 (define_insn "zero_extendhisi2"
2191 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
2192 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
2196 if (which_alternative == 0)
2197 return \"andi\\t%0,%1,0xffff\";
2199 return mips_move_1word (operands, insn, TRUE);
2201 [(set_attr "type" "arith,load,load")
2202 (set_attr "mode" "SI")
2203 (set_attr "length" "1,1,2")])
2205 (define_insn "zero_extendhidi2"
2206 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
2207 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
2211 if (which_alternative == 0)
2212 return \"andi\\t%0,%1,0xffff\";
2214 return mips_move_1word (operands, insn, TRUE);
2216 [(set_attr "type" "arith,load,load")
2217 (set_attr "mode" "DI")
2218 (set_attr "length" "1,1,2")])
2220 (define_insn "zero_extendqihi2"
2221 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
2222 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
2226 if (which_alternative == 0)
2227 return \"andi\\t%0,%1,0x00ff\";
2229 return mips_move_1word (operands, insn, TRUE);
2231 [(set_attr "type" "arith,load,load")
2232 (set_attr "mode" "HI")
2233 (set_attr "length" "1,1,2")])
2235 (define_insn "zero_extendqisi2"
2236 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
2237 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
2241 if (which_alternative == 0)
2242 return \"andi\\t%0,%1,0x00ff\";
2244 return mips_move_1word (operands, insn, TRUE);
2246 [(set_attr "type" "arith,load,load")
2247 (set_attr "mode" "SI")
2248 (set_attr "length" "1,1,2")])
2250 (define_insn "zero_extendqidi2"
2251 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
2252 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
2256 if (which_alternative == 0)
2257 return \"andi\\t%0,%1,0x00ff\";
2259 return mips_move_1word (operands, insn, TRUE);
2261 [(set_attr "type" "arith,load,load")
2262 (set_attr "mode" "DI")
2263 (set_attr "length" "1,1,2")])
2267 ;; ....................
2271 ;; ....................
2274 ;; Those for integer source operand are ordered widest source type first.
2276 (define_expand "extendsidi2"
2277 [(set (match_operand:DI 0 "register_operand" "")
2278 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
2282 if (optimize && GET_CODE (operands[1]) == MEM)
2283 operands[1] = force_not_mem (operands[1]);
2285 if (GET_CODE (operands[1]) != MEM)
2287 rtx op1 = gen_lowpart (DImode, operands[1]);
2288 rtx temp = gen_reg_rtx (DImode);
2289 rtx shift = gen_rtx (CONST_INT, VOIDmode, 32);
2291 emit_insn (gen_ashldi3 (temp, op1, shift));
2292 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
2297 (define_insn "extendsidi2_internal"
2298 [(set (match_operand:DI 0 "register_operand" "=d,d")
2299 (sign_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
2301 "* return mips_move_1word (operands, insn, FALSE);"
2302 [(set_attr "type" "load")
2303 (set_attr "mode" "DI")
2304 (set_attr "length" "1,2")])
2306 ;; These patterns originally accepted general_operands, however, slightly
2307 ;; better code is generated by only accepting register_operands, and then
2308 ;; letting combine generate the lh and lb insns.
2310 (define_expand "extendhidi2"
2311 [(set (match_operand:DI 0 "register_operand" "")
2312 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
2316 if (optimize && GET_CODE (operands[1]) == MEM)
2317 operands[1] = force_not_mem (operands[1]);
2319 if (GET_CODE (operands[1]) != MEM)
2321 rtx op1 = gen_lowpart (DImode, operands[1]);
2322 rtx temp = gen_reg_rtx (DImode);
2323 rtx shift = gen_rtx (CONST_INT, VOIDmode, 48);
2325 emit_insn (gen_ashldi3 (temp, op1, shift));
2326 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
2331 (define_insn "extendhidi2_internal"
2332 [(set (match_operand:DI 0 "register_operand" "=d,d")
2333 (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
2335 "* return mips_move_1word (operands, insn, FALSE);"
2336 [(set_attr "type" "load")
2337 (set_attr "mode" "DI")
2338 (set_attr "length" "1,2")])
2340 (define_expand "extendhisi2"
2341 [(set (match_operand:SI 0 "register_operand" "")
2342 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2346 if (optimize && GET_CODE (operands[1]) == MEM)
2347 operands[1] = force_not_mem (operands[1]);
2349 if (GET_CODE (operands[1]) != MEM)
2351 rtx op1 = gen_lowpart (SImode, operands[1]);
2352 rtx temp = gen_reg_rtx (SImode);
2353 rtx shift = gen_rtx (CONST_INT, VOIDmode, 16);
2355 emit_insn (gen_ashlsi3 (temp, op1, shift));
2356 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
2361 (define_insn "extendhisi2_internal"
2362 [(set (match_operand:SI 0 "register_operand" "=d,d")
2363 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
2365 "* return mips_move_1word (operands, insn, FALSE);"
2366 [(set_attr "type" "load")
2367 (set_attr "mode" "SI")
2368 (set_attr "length" "1,2")])
2370 (define_expand "extendqihi2"
2371 [(set (match_operand:HI 0 "register_operand" "")
2372 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2376 if (optimize && GET_CODE (operands[1]) == MEM)
2377 operands[1] = force_not_mem (operands[1]);
2379 if (GET_CODE (operands[1]) != MEM)
2381 rtx op0 = gen_lowpart (SImode, operands[0]);
2382 rtx op1 = gen_lowpart (SImode, operands[1]);
2383 rtx temp = gen_reg_rtx (SImode);
2384 rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
2386 emit_insn (gen_ashlsi3 (temp, op1, shift));
2387 emit_insn (gen_ashrsi3 (op0, temp, shift));
2392 (define_insn "extendqihi2_internal"
2393 [(set (match_operand:HI 0 "register_operand" "=d,d")
2394 (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
2396 "* return mips_move_1word (operands, insn, FALSE);"
2397 [(set_attr "type" "load")
2398 (set_attr "mode" "SI")
2399 (set_attr "length" "1,2")])
2402 (define_expand "extendqisi2"
2403 [(set (match_operand:SI 0 "register_operand" "")
2404 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2408 if (optimize && GET_CODE (operands[1]) == MEM)
2409 operands[1] = force_not_mem (operands[1]);
2411 if (GET_CODE (operands[1]) != MEM)
2413 rtx op1 = gen_lowpart (SImode, operands[1]);
2414 rtx temp = gen_reg_rtx (SImode);
2415 rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
2417 emit_insn (gen_ashlsi3 (temp, op1, shift));
2418 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
2423 (define_insn "extendqisi2_insn"
2424 [(set (match_operand:SI 0 "register_operand" "=d,d")
2425 (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
2427 "* return mips_move_1word (operands, insn, FALSE);"
2428 [(set_attr "type" "load")
2429 (set_attr "mode" "SI")
2430 (set_attr "length" "1,2")])
2432 (define_expand "extendqidi2"
2433 [(set (match_operand:DI 0 "register_operand" "")
2434 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
2438 if (optimize && GET_CODE (operands[1]) == MEM)
2439 operands[1] = force_not_mem (operands[1]);
2441 if (GET_CODE (operands[1]) != MEM)
2443 rtx op1 = gen_lowpart (DImode, operands[1]);
2444 rtx temp = gen_reg_rtx (DImode);
2445 rtx shift = gen_rtx (CONST_INT, VOIDmode, 56);
2447 emit_insn (gen_ashldi3 (temp, op1, shift));
2448 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
2453 (define_insn "extendqidi2_insn"
2454 [(set (match_operand:DI 0 "register_operand" "=d,d")
2455 (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
2457 "* return mips_move_1word (operands, insn, FALSE);"
2458 [(set_attr "type" "load")
2459 (set_attr "mode" "DI")
2460 (set_attr "length" "1,2")])
2463 (define_insn "extendsfdf2"
2464 [(set (match_operand:DF 0 "register_operand" "=f")
2465 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2466 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2468 [(set_attr "type" "fcvt")
2469 (set_attr "mode" "DF")
2470 (set_attr "length" "1")])
2475 ;; ....................
2479 ;; ....................
2481 ;; The SImode scratch register can not be shared with address regs used for
2482 ;; operand zero, because then the address in the move instruction will be
2483 ;; clobbered. We mark the scratch register as early clobbered to prevent this.
2485 (define_insn "fix_truncdfsi2"
2486 [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o")
2487 (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
2488 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
2489 (clobber (match_scratch:DF 3 "=f,*X,f,f"))]
2490 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2495 if (which_alternative == 1)
2496 return \"trunc.w.d %0,%1,%2\";
2498 output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
2500 xoperands[0] = operands[0];
2501 xoperands[1] = operands[3];
2502 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2505 [(set_attr "type" "fcvt")
2506 (set_attr "mode" "DF")
2507 (set_attr "length" "11,9,10,11")])
2510 (define_insn "fix_truncsfsi2"
2511 [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o")
2512 (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
2513 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
2514 (clobber (match_scratch:SF 3 "=f,*X,f,f"))]
2520 if (which_alternative == 1)
2521 return \"trunc.w.s %0,%1,%2\";
2523 output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
2525 xoperands[0] = operands[0];
2526 xoperands[1] = operands[3];
2527 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2530 [(set_attr "type" "fcvt")
2531 (set_attr "mode" "SF")
2532 (set_attr "length" "11,9,10,11")])
2535 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
2536 ;;; but not in the chapter that describes the FPU. It is not mentioned at all
2537 ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
2539 ;;; Deleting this means that we now need two libgcc2.a libraries. One for
2540 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
2542 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
2544 (define_insn "fix_truncdfdi2"
2545 [(set (match_operand:DI 0 "general_operand" "=d,*f,R,o")
2546 (fix:DI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
2547 (clobber (match_scratch:DF 2 "=f,*X,f,f"))]
2548 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2553 if (which_alternative == 1)
2554 return \"trunc.l.d %0,%1\";
2556 output_asm_insn (\"trunc.l.d %2,%1\", operands);
2558 xoperands[0] = operands[0];
2559 xoperands[1] = operands[2];
2560 output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
2563 [(set_attr "type" "fcvt")
2564 (set_attr "mode" "DF")
2565 (set_attr "length" "2,1,2,3")])
2568 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
2569 ;;; but not in the chapter that describes the FPU. It is not mentioned at all
2570 ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
2571 (define_insn "fix_truncsfdi2"
2572 [(set (match_operand:DI 0 "general_operand" "=d,*f,R,o")
2573 (fix:DI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
2574 (clobber (match_scratch:DF 2 "=f,*X,f,f"))]
2575 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2580 if (which_alternative == 1)
2581 return \"trunc.l.s %0,%1\";
2583 output_asm_insn (\"trunc.l.s %2,%1\", operands);
2585 xoperands[0] = operands[0];
2586 xoperands[1] = operands[2];
2587 output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
2590 [(set_attr "type" "fcvt")
2591 (set_attr "mode" "SF")
2592 (set_attr "length" "2,1,2,3")])
2595 (define_insn "floatsidf2"
2596 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
2597 (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
2598 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2601 dslots_load_total++;
2602 if (GET_CODE (operands[1]) == MEM)
2603 return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
2605 return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
2607 [(set_attr "type" "fcvt")
2608 (set_attr "mode" "DF")
2609 (set_attr "length" "3,4,3")])
2612 (define_insn "floatdidf2"
2613 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
2614 (float:DF (match_operand:DI 1 "nonimmediate_operand" "d,R,m")))]
2615 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2618 dslots_load_total++;
2619 if (GET_CODE (operands[1]) == MEM)
2620 return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
2622 return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
2624 [(set_attr "type" "fcvt")
2625 (set_attr "mode" "DF")
2626 (set_attr "length" "3,4,3")])
2629 (define_insn "floatsisf2"
2630 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
2631 (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
2635 dslots_load_total++;
2636 if (GET_CODE (operands[1]) == MEM)
2637 return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
2639 return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
2641 [(set_attr "type" "fcvt")
2642 (set_attr "mode" "SF")
2643 (set_attr "length" "3,4,3")])
2646 (define_insn "floatdisf2"
2647 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
2648 (float:SF (match_operand:DI 1 "nonimmediate_operand" "d,R,m")))]
2649 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2652 dslots_load_total++;
2653 if (GET_CODE (operands[1]) == MEM)
2654 return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
2656 return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
2658 [(set_attr "type" "fcvt")
2659 (set_attr "mode" "SF")
2660 (set_attr "length" "3,4,3")])
2663 (define_expand "fixuns_truncdfsi2"
2664 [(set (match_operand:SI 0 "register_operand" "")
2665 (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
2666 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2669 rtx reg1 = gen_reg_rtx (DFmode);
2670 rtx reg2 = gen_reg_rtx (DFmode);
2671 rtx reg3 = gen_reg_rtx (SImode);
2672 rtx label1 = gen_label_rtx ();
2673 rtx label2 = gen_label_rtx ();
2674 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
2676 if (reg1) /* turn off complaints about unreached code */
2678 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
2679 do_pending_stack_adjust ();
2681 emit_insn (gen_cmpdf (operands[1], reg1));
2682 emit_jump_insn (gen_bge (label1));
2684 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2685 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
2686 gen_rtx (LABEL_REF, VOIDmode, label2)));
2689 emit_label (label1);
2690 emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
2691 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
2693 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2694 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2696 emit_label (label2);
2698 /* allow REG_NOTES to be set on last insn (labels don't have enough
2699 fields, and can't be used for REG_NOTES anyway). */
2700 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2706 (define_expand "fixuns_truncdfdi2"
2707 [(set (match_operand:DI 0 "register_operand" "")
2708 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
2709 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2712 rtx reg1 = gen_reg_rtx (DFmode);
2713 rtx reg2 = gen_reg_rtx (DFmode);
2714 rtx reg3 = gen_reg_rtx (DImode);
2715 rtx label1 = gen_label_rtx ();
2716 rtx label2 = gen_label_rtx ();
2717 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
2719 if (reg1) /* turn off complaints about unreached code */
2721 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
2722 do_pending_stack_adjust ();
2724 emit_insn (gen_cmpdf (operands[1], reg1));
2725 emit_jump_insn (gen_bge (label1));
2727 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2728 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
2729 gen_rtx (LABEL_REF, VOIDmode, label2)));
2732 emit_label (label1);
2733 emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
2734 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
2735 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2737 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2738 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2740 emit_label (label2);
2742 /* allow REG_NOTES to be set on last insn (labels don't have enough
2743 fields, and can't be used for REG_NOTES anyway). */
2744 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2750 (define_expand "fixuns_truncsfsi2"
2751 [(set (match_operand:SI 0 "register_operand" "")
2752 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
2756 rtx reg1 = gen_reg_rtx (SFmode);
2757 rtx reg2 = gen_reg_rtx (SFmode);
2758 rtx reg3 = gen_reg_rtx (SImode);
2759 rtx label1 = gen_label_rtx ();
2760 rtx label2 = gen_label_rtx ();
2761 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
2763 if (reg1) /* turn off complaints about unreached code */
2765 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
2766 do_pending_stack_adjust ();
2768 emit_insn (gen_cmpsf (operands[1], reg1));
2769 emit_jump_insn (gen_bge (label1));
2771 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2772 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
2773 gen_rtx (LABEL_REF, VOIDmode, label2)));
2776 emit_label (label1);
2777 emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
2778 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
2780 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2781 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2783 emit_label (label2);
2785 /* allow REG_NOTES to be set on last insn (labels don't have enough
2786 fields, and can't be used for REG_NOTES anyway). */
2787 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2793 (define_expand "fixuns_truncsfdi2"
2794 [(set (match_operand:DI 0 "register_operand" "")
2795 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
2796 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2799 rtx reg1 = gen_reg_rtx (SFmode);
2800 rtx reg2 = gen_reg_rtx (SFmode);
2801 rtx reg3 = gen_reg_rtx (DImode);
2802 rtx label1 = gen_label_rtx ();
2803 rtx label2 = gen_label_rtx ();
2804 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
2806 if (reg1) /* turn off complaints about unreached code */
2808 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
2809 do_pending_stack_adjust ();
2811 emit_insn (gen_cmpsf (operands[1], reg1));
2812 emit_jump_insn (gen_bge (label1));
2814 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
2815 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
2816 gen_rtx (LABEL_REF, VOIDmode, label2)));
2819 emit_label (label1);
2820 emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
2821 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
2822 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2824 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
2825 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2827 emit_label (label2);
2829 /* allow REG_NOTES to be set on last insn (labels don't have enough
2830 fields, and can't be used for REG_NOTES anyway). */
2831 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2838 ;; ....................
2842 ;; ....................
2844 ;; Bit field extract patterns which use lwl/lwr.
2846 ;; ??? There should be DImode variants for 64 bit code, but the current
2847 ;; bitfield scheme can't handle that. We would need to add new optabs
2848 ;; in order to make that work.
2850 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
2851 ;; It isn't clear whether this will give better code.
2853 (define_expand "extv"
2854 [(set (match_operand:SI 0 "register_operand" "")
2855 (sign_extract:SI (match_operand:QI 1 "memory_operand" "")
2856 (match_operand:SI 2 "immediate_operand" "")
2857 (match_operand:SI 3 "immediate_operand" "")))]
2861 /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
2863 if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
2866 /* This can happen for a 64 bit target, when extracting a value from
2867 a 64 bit union member. extract_bit_field doesn't verify that our
2868 source matches the predicate, so we force it to be a MEM here. */
2869 if (GET_CODE (operands[1]) != MEM)
2872 /* Otherwise, emit a lwl/lwr pair to load the value. */
2873 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
2877 (define_expand "extzv"
2878 [(set (match_operand:SI 0 "register_operand" "")
2879 (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
2880 (match_operand:SI 2 "immediate_operand" "")
2881 (match_operand:SI 3 "immediate_operand" "")))]
2885 /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
2887 if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
2890 /* This can happen for a 64 bit target, when extracting a value from
2891 a 64 bit union member. extract_bit_field doesn't verify that our
2892 source matches the predicate, so we force it to be a MEM here. */
2893 if (GET_CODE (operands[1]) != MEM)
2896 /* Otherwise, emit a lwl/lwr pair to load the value. */
2897 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
2901 (define_expand "insv"
2902 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
2903 (match_operand:SI 1 "immediate_operand" "")
2904 (match_operand:SI 2 "immediate_operand" ""))
2905 (match_operand:SI 3 "register_operand" ""))]
2909 /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
2911 if (INTVAL (operands[1]) != 32 || (INTVAL (operands[2]) % 8) != 0)
2914 /* This can happen for a 64 bit target, when storing into a 32 bit union
2915 member. store_bit_field doesn't verify that our target matches the
2916 predicate, so we force it to be a MEM here. */
2917 if (GET_CODE (operands[0]) != MEM)
2920 /* Otherwise, emit a swl/swr pair to load the value. */
2921 emit_insn (gen_movsi_usw (operands[0], operands[3]));
2925 ;; unaligned word moves generated by the bit field patterns
2927 (define_insn "movsi_ulw"
2928 [(set (match_operand:SI 0 "register_operand" "=&d,&d")
2929 (unspec [(match_operand:QI 1 "general_operand" "R,o")] 0))]
2933 rtx offset = const0_rtx;
2934 rtx addr = XEXP (operands[1], 0);
2935 rtx mem_addr = eliminate_constant_term (addr, &offset);
2939 mips_count_memory_refs (operands[1], 2);
2941 /* The stack/frame pointers are always aligned, so we can convert
2942 to the faster lw if we are referencing an aligned stack location. */
2944 if ((INTVAL (offset) & 3) == 0
2945 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
2946 ret = \"lw\\t%0,%1\";
2948 ret = \"ulw\\t%0,%1\";
2950 return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
2952 [(set_attr "type" "load,load")
2953 (set_attr "mode" "SI")
2954 (set_attr "length" "2,4")])
2956 (define_insn "movsi_usw"
2957 [(set (match_operand:QI 0 "memory_operand" "=R,o")
2958 (unspec [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
2962 rtx offset = const0_rtx;
2963 rtx addr = XEXP (operands[0], 0);
2964 rtx mem_addr = eliminate_constant_term (addr, &offset);
2967 mips_count_memory_refs (operands[0], 2);
2969 /* The stack/frame pointers are always aligned, so we can convert
2970 to the faster sw if we are referencing an aligned stack location. */
2972 if ((INTVAL (offset) & 3) == 0
2973 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
2974 return \"sw\\t%1,%0\";
2976 return \"usw\\t%z1,%0\";
2978 [(set_attr "type" "store")
2979 (set_attr "mode" "SI")
2980 (set_attr "length" "2,4")])
2982 ;; 64-bit integer moves
2984 ;; Unlike most other insns, the move insns can't be split with
2985 ;; different predicates, because register spilling and other parts of
2986 ;; the compiler, have memoized the insn number already.
2988 (define_expand "movdi"
2989 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2990 (match_operand:DI 1 "general_operand" ""))]
2994 /* If we are generating embedded PIC code, and we are referring to a
2995 symbol in the .text section, we must use an offset from the start
2997 if (TARGET_EMBEDDED_PIC
2998 && (GET_CODE (operands[1]) == LABEL_REF
2999 || (GET_CODE (operands[1]) == SYMBOL_REF
3000 && ! SYMBOL_REF_FLAG (operands[1]))))
3004 temp = embedded_pic_offset (operands[1]);
3005 temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
3006 force_reg (DImode, temp));
3007 emit_move_insn (operands[0], force_reg (DImode, temp));
3011 /* If operands[1] is a constant address illegal for pic, then we need to
3012 handle it just like LEGITIMIZE_ADDRESS does. */
3013 if (flag_pic && pic_address_needs_scratch (operands[1]))
3015 rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
3016 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
3018 if (! SMALL_INT (temp2))
3019 temp2 = force_reg (DImode, temp2);
3021 emit_move_insn (operands[0], gen_rtx (PLUS, DImode, temp, temp2));
3025 if ((reload_in_progress | reload_completed) == 0
3026 && !register_operand (operands[0], DImode)
3027 && !register_operand (operands[1], DImode)
3028 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
3029 && operands[1] != CONST0_RTX (DImode))
3031 rtx temp = force_reg (DImode, operands[1]);
3032 emit_move_insn (operands[0], temp);
3037 (define_insn "movdi_internal"
3038 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*d,*x")
3039 (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,*x,*d"))]
3041 && (register_operand (operands[0], DImode)
3042 || register_operand (operands[1], DImode)
3043 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3044 || operands[1] == CONST0_RTX (DImode))"
3045 "* return mips_move_2words (operands, insn); "
3046 [(set_attr "type" "move,arith,load,load,store,store,hilo,hilo")
3047 (set_attr "mode" "DI")
3048 (set_attr "length" "2,4,2,4,2,4,2,2")])
3051 [(set (match_operand:DI 0 "register_operand" "")
3052 (match_operand:DI 1 "register_operand" ""))]
3053 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3054 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3055 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3057 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
3058 (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
3061 (define_insn "movdi_internal2"
3062 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*x,*a")
3063 (match_operand:DI 1 "general_operand" " d,S,IKL,Mnis,R,m,dJ,dJ,*x,*d,*I"))]
3065 && (register_operand (operands[0], DImode)
3066 || register_operand (operands[1], DImode)
3067 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3068 || operands[1] == CONST0_RTX (DImode))"
3069 "* return mips_move_2words (operands, insn); "
3070 [(set_attr "type" "move,load,arith,arith,load,load,store,store,hilo,hilo,hilo")
3071 (set_attr "mode" "DI")
3072 (set_attr "length" "1,2,1,2,1,2,1,2,1,1,2")])
3074 ;; Handle input reloads in DImode.
3075 ;; This is mainly to handle reloading HILO_REGNUM. Note that we may
3076 ;; see it as the source or the destination, depending upon which way
3077 ;; reload handles the instruction.
3078 ;; Making the second operand TImode is a trick. The compiler may
3079 ;; reuse the same register for operand 0 and operand 2. Using TImode
3080 ;; gives us two registers, so we can always use the one which is not
3083 (define_expand "reload_indi"
3084 [(set (match_operand:DI 0 "register_operand" "=b")
3085 (match_operand:DI 1 "general_operand" "b"))
3086 (clobber (match_operand:TI 2 "register_operand" "=&d"))]
3090 rtx scratch = gen_rtx (REG, DImode,
3091 (REGNO (operands[0]) == REGNO (operands[2])
3092 ? REGNO (operands[2]) + 1
3093 : REGNO (operands[2])));
3095 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
3097 if (GET_CODE (operands[1]) == MEM)
3099 rtx memword, offword, hiword, loword;
3101 scratch = gen_rtx (REG, SImode, REGNO (scratch));
3102 memword = change_address (operands[1], SImode, NULL_RTX);
3103 offword = change_address (adj_offsettable_operand (operands[1], 4),
3105 if (BYTES_BIG_ENDIAN)
3115 emit_move_insn (scratch, hiword);
3116 emit_move_insn (gen_rtx (REG, SImode, 64), scratch);
3117 emit_move_insn (scratch, loword);
3118 emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
3122 emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
3123 emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
3124 emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
3125 emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
3126 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
3130 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
3132 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
3133 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
3134 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
3135 emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
3136 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
3137 emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
3140 /* This handles moves between a float register and HI/LO. */
3141 emit_move_insn (scratch, operands[1]);
3142 emit_move_insn (operands[0], scratch);
3146 ;; Handle output reloads in DImode.
3148 (define_expand "reload_outdi"
3149 [(set (match_operand:DI 0 "general_operand" "=b")
3150 (match_operand:DI 1 "register_operand" "b"))
3151 (clobber (match_operand:DI 2 "register_operand" "=&d"))]
3155 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
3157 emit_insn (gen_ashrdi3 (operands[2], operands[1], GEN_INT (32)));
3158 emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), operands[2]));
3159 emit_insn (gen_ashldi3 (operands[2], operands[1], GEN_INT (32)));
3160 emit_insn (gen_ashrdi3 (operands[2], operands[2], GEN_INT (32)));
3161 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), operands[2]));
3164 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
3166 if (GET_CODE (operands[0]) == MEM)
3168 rtx scratch, memword, offword, hiword, loword;
3170 scratch = gen_rtx (REG, SImode, REGNO (operands[2]));
3171 memword = change_address (operands[0], SImode, NULL_RTX);
3172 offword = change_address (adj_offsettable_operand (operands[0], 4),
3174 if (BYTES_BIG_ENDIAN)
3184 emit_move_insn (scratch, gen_rtx (REG, SImode, 64));
3185 emit_move_insn (hiword, scratch);
3186 emit_move_insn (scratch, gen_rtx (REG, SImode, 65));
3187 emit_move_insn (loword, scratch);
3191 emit_insn (gen_movdi (operands[2], gen_rtx (REG, DImode, 65)));
3192 emit_insn (gen_ashldi3 (operands[2], operands[2], GEN_INT (32)));
3193 emit_insn (gen_lshrdi3 (operands[2], operands[2], GEN_INT (32)));
3194 emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
3195 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
3196 emit_insn (gen_iordi3 (operands[0], operands[0], operands[2]));
3200 /* This handles moves between a float register and HI/LO. */
3201 emit_move_insn (operands[2], operands[1]);
3202 emit_move_insn (operands[0], operands[2]);
3206 ;; 32-bit Integer moves
3209 [(set (match_operand:SI 0 "register_operand" "")
3210 (match_operand:SI 1 "large_int" ""))]
3211 "!TARGET_DEBUG_D_MODE"
3215 (ior:SI (match_dup 0)
3219 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff0000);
3220 operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0x0000ffff);
3223 ;; Unlike most other insns, the move insns can't be split with
3224 ;; different predicates, because register spilling and other parts of
3225 ;; the compiler, have memoized the insn number already.
3227 (define_expand "movsi"
3228 [(set (match_operand:SI 0 "nonimmediate_operand" "")
3229 (match_operand:SI 1 "general_operand" ""))]
3233 /* If we are generating embedded PIC code, and we are referring to a
3234 symbol in the .text section, we must use an offset from the start
3236 if (TARGET_EMBEDDED_PIC
3237 && (GET_CODE (operands[1]) == LABEL_REF
3238 || (GET_CODE (operands[1]) == SYMBOL_REF
3239 && ! SYMBOL_REF_FLAG (operands[1]))))
3243 temp = embedded_pic_offset (operands[1]);
3244 temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
3245 force_reg (SImode, temp));
3246 emit_move_insn (operands[0], force_reg (SImode, temp));
3250 /* If operands[1] is a constant address invalid for pic, then we need to
3251 handle it just like LEGITIMIZE_ADDRESS does. */
3252 if (flag_pic && pic_address_needs_scratch (operands[1]))
3254 rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
3255 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
3257 if (! SMALL_INT (temp2))
3258 temp2 = force_reg (SImode, temp2);
3260 emit_move_insn (operands[0], gen_rtx (PLUS, SImode, temp, temp2));
3264 if ((reload_in_progress | reload_completed) == 0
3265 && !register_operand (operands[0], SImode)
3266 && !register_operand (operands[1], SImode)
3267 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
3269 rtx temp = force_reg (SImode, operands[1]);
3270 emit_move_insn (operands[0], temp);
3275 ;; The difference between these two is whether or not ints are allowed
3276 ;; in FP registers (off by default, use -mdebugh to enable).
3278 (define_insn "movsi_internal1"
3279 [(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")
3280 (match_operand:SI 1 "general_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*f*z,*d,*f,*R,*m,*f,*f,I,*d,*x,*a"))]
3281 "TARGET_DEBUG_H_MODE
3282 && (register_operand (operands[0], SImode)
3283 || register_operand (operands[1], SImode)
3284 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3285 "* return mips_move_1word (operands, insn, FALSE);"
3286 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo,hilo,hilo")
3287 (set_attr "mode" "SI")
3288 (set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1,2,1,2,1,1,1,1")])
3290 (define_insn "movsi_internal2"
3291 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d")
3292 (match_operand:SI 1 "general_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,I,*x,*d,*a"))]
3293 "!TARGET_DEBUG_H_MODE
3294 && (register_operand (operands[0], SImode)
3295 || register_operand (operands[1], SImode)
3296 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3297 "* return mips_move_1word (operands, insn, FALSE);"
3298 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo")
3299 (set_attr "mode" "SI")
3300 (set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1,1,1")])
3302 ;; Reload HILO_REGNUM in SI mode. This needs a scratch register in
3303 ;; order to set the sign bit correctly in the HI register.
3305 (define_expand "reload_outsi"
3306 [(set (match_operand:SI 0 "general_operand" "=b")
3307 (match_operand:SI 1 "register_operand" "d"))
3308 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
3312 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
3314 emit_insn (gen_movsi (gen_rtx (REG, SImode, 65), operands[1]));
3315 emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
3316 emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
3319 /* This handles moves between a float register and HI/LO. */
3320 emit_move_insn (operands[2], operands[1]);
3321 emit_move_insn (operands[0], operands[2]);
3325 ;; 16-bit Integer moves
3327 ;; Unlike most other insns, the move insns can't be split with
3328 ;; different predicates, because register spilling and other parts of
3329 ;; the compiler, have memoized the insn number already.
3330 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
3332 (define_expand "movhi"
3333 [(set (match_operand:HI 0 "nonimmediate_operand" "")
3334 (match_operand:HI 1 "general_operand" ""))]
3338 if ((reload_in_progress | reload_completed) == 0
3339 && !register_operand (operands[0], HImode)
3340 && !register_operand (operands[1], HImode)
3341 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
3343 rtx temp = force_reg (HImode, operands[1]);
3344 emit_move_insn (operands[0], temp);
3349 ;; The difference between these two is whether or not ints are allowed
3350 ;; in FP registers (off by default, use -mdebugh to enable).
3352 (define_insn "movhi_internal1"
3353 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
3354 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
3355 "TARGET_DEBUG_H_MODE
3356 && (register_operand (operands[0], HImode)
3357 || register_operand (operands[1], HImode)
3358 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3359 "* return mips_move_1word (operands, insn, TRUE);"
3360 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
3361 (set_attr "mode" "HI")
3362 (set_attr "length" "1,1,1,2,1,2,1,1,1,1,1")])
3364 (define_insn "movhi_internal2"
3365 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
3366 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
3367 "!TARGET_DEBUG_H_MODE
3368 && (register_operand (operands[0], HImode)
3369 || register_operand (operands[1], HImode)
3370 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3371 "* return mips_move_1word (operands, insn, TRUE);"
3372 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
3373 (set_attr "mode" "HI")
3374 (set_attr "length" "1,1,1,2,1,2,1,1,1,1")])
3377 ;; 8-bit Integer moves
3379 ;; Unlike most other insns, the move insns can't be split with
3380 ;; different predicates, because register spilling and other parts of
3381 ;; the compiler, have memoized the insn number already.
3382 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
3384 (define_expand "movqi"
3385 [(set (match_operand:QI 0 "nonimmediate_operand" "")
3386 (match_operand:QI 1 "general_operand" ""))]
3390 if ((reload_in_progress | reload_completed) == 0
3391 && !register_operand (operands[0], QImode)
3392 && !register_operand (operands[1], QImode)
3393 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
3395 rtx temp = force_reg (QImode, operands[1]);
3396 emit_move_insn (operands[0], temp);
3401 ;; The difference between these two is whether or not ints are allowed
3402 ;; in FP registers (off by default, use -mdebugh to enable).
3404 (define_insn "movqi_internal1"
3405 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
3406 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
3407 "TARGET_DEBUG_H_MODE
3408 && (register_operand (operands[0], QImode)
3409 || register_operand (operands[1], QImode)
3410 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3411 "* return mips_move_1word (operands, insn, TRUE);"
3412 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
3413 (set_attr "mode" "QI")
3414 (set_attr "length" "1,1,1,2,1,2,1,1,1,1,1")])
3416 (define_insn "movqi_internal2"
3417 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
3418 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
3419 "!TARGET_DEBUG_H_MODE
3420 && (register_operand (operands[0], QImode)
3421 || register_operand (operands[1], QImode)
3422 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3423 "* return mips_move_1word (operands, insn, TRUE);"
3424 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
3425 (set_attr "mode" "QI")
3426 (set_attr "length" "1,1,1,2,1,2,1,1,1,1")])
3429 ;; 32-bit floating point moves
3431 (define_expand "movsf"
3432 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3433 (match_operand:SF 1 "general_operand" ""))]
3437 if ((reload_in_progress | reload_completed) == 0
3438 && !register_operand (operands[0], SFmode)
3439 && !register_operand (operands[1], SFmode)
3440 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
3441 && operands[1] != CONST0_RTX (SFmode))
3443 rtx temp = force_reg (SFmode, operands[1]);
3444 emit_move_insn (operands[0], temp);
3449 (define_insn "movsf_internal1"
3450 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
3451 (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
3453 && (register_operand (operands[0], SFmode)
3454 || register_operand (operands[1], SFmode)
3455 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3456 || operands[1] == CONST0_RTX (SFmode))"
3457 "* return mips_move_1word (operands, insn, FALSE);"
3458 [(set_attr "type" "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
3459 (set_attr "mode" "SF")
3460 (set_attr "length" "1,1,1,2,1,2,1,1,1,1,2,1,2")])
3463 (define_insn "movsf_internal2"
3464 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
3465 (match_operand:SF 1 "general_operand" " Gd,R,Fm,d,d"))]
3467 && (register_operand (operands[0], SFmode)
3468 || register_operand (operands[1], SFmode)
3469 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3470 || operands[1] == CONST0_RTX (SFmode))"
3471 "* return mips_move_1word (operands, insn, FALSE);"
3472 [(set_attr "type" "move,load,load,store,store")
3473 (set_attr "mode" "SF")
3474 (set_attr "length" "1,1,2,1,2")])
3477 ;; 64-bit floating point moves
3479 (define_expand "movdf"
3480 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3481 (match_operand:DF 1 "general_operand" ""))]
3485 if ((reload_in_progress | reload_completed) == 0
3486 && !register_operand (operands[0], DFmode)
3487 && !register_operand (operands[1], DFmode)
3488 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
3489 && operands[1] != CONST0_RTX (DFmode))
3491 rtx temp = force_reg (DFmode, operands[1]);
3492 emit_move_insn (operands[0], temp);
3497 (define_insn "movdf_internal1"
3498 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,o,f,*f,*d,*d,*d,*d,*R,*o")
3499 (match_operand:DF 1 "general_operand" "f,R,o,fG,fG,F,*d,*f,*d*G,*R,*o*F,*d,*d"))]
3500 "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
3501 && TARGET_DOUBLE_FLOAT
3502 && (register_operand (operands[0], DFmode)
3503 || register_operand (operands[1], DFmode)
3504 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3505 || operands[1] == CONST0_RTX (DFmode))"
3506 "* return mips_move_2words (operands, insn); "
3507 [(set_attr "type" "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
3508 (set_attr "mode" "DF")
3509 (set_attr "length" "1,2,4,2,4,4,2,2,2,2,4,2,4")])
3511 (define_insn "movdf_internal1a"
3512 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,o,o,f,*d,*d,*d,*o,*R")
3513 (match_operand:DF 1 "general_operand" " f,o,f,G,f,G,F,*F,*o,*R,*d,*d"))]
3514 "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
3515 && TARGET_DOUBLE_FLOAT
3516 && (register_operand (operands[0], DFmode)
3517 || register_operand (operands[1], DFmode))
3518 || (GET_CODE (operands [0]) == MEM
3519 && ((GET_CODE (operands[1]) == CONST_INT
3520 && INTVAL (operands[1]) == 0)
3521 || operands[1] == CONST0_RTX (DFmode)))"
3522 "* return mips_move_2words (operands, insn); "
3523 [(set_attr "type" "move,load,store,store,store,store,load,load,load,load,store,store")
3524 (set_attr "mode" "DF")
3525 (set_attr "length" "1,2,1,1,2,2,2,2,2,1,2,1")])
3527 (define_insn "movdf_internal2"
3528 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,o")
3529 (match_operand:DF 1 "general_operand" "dG,R,oF,d,d"))]
3530 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT)
3531 && (register_operand (operands[0], DFmode)
3532 || register_operand (operands[1], DFmode)
3533 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3534 || operands[1] == CONST0_RTX (DFmode))"
3535 "* return mips_move_2words (operands, insn); "
3536 [(set_attr "type" "move,load,load,store,store")
3537 (set_attr "mode" "DF")
3538 (set_attr "length" "2,2,4,2,4")])
3541 [(set (match_operand:DF 0 "register_operand" "")
3542 (match_operand:DF 1 "register_operand" ""))]
3543 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3544 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3545 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3546 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
3547 (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
3550 ;; Instructions to load the global pointer register.
3551 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
3552 ;; uses in front of it. All symbol_refs implicitly use the gp reg.
3554 (define_insn "loadgp"
3556 (unspec_volatile [(match_operand:DI 0 "address_operand" "")] 2))
3557 (clobber (reg:DI 1))]
3559 "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,$25%]"
3560 [(set_attr "type" "move")
3561 (set_attr "mode" "DI")
3562 (set_attr "length" "3")])
3564 ;; Block moves, see mips.c for more details.
3565 ;; Argument 0 is the destination
3566 ;; Argument 1 is the source
3567 ;; Argument 2 is the length
3568 ;; Argument 3 is the alignment
3570 (define_expand "movstrsi"
3571 [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
3572 (mem:BLK (match_operand:BLK 1 "general_operand" "")))
3573 (use (match_operand:SI 2 "arith32_operand" ""))
3574 (use (match_operand:SI 3 "immediate_operand" ""))])]
3578 if (operands[0]) /* avoid unused code messages */
3580 expand_block_move (operands);
3585 ;; Insn generated by block moves
3587 (define_insn "movstrsi_internal"
3588 [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
3589 (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
3590 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
3591 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
3592 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
3593 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
3594 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
3595 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
3596 (use (const_int 0))] ;; normal block move
3598 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
3599 [(set_attr "type" "multi")
3600 (set_attr "mode" "none")
3601 (set_attr "length" "20")])
3603 ;; Split a block move into 2 parts, the first part is everything
3604 ;; except for the last move, and the second part is just the last
3605 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
3606 ;; fill a delay slot. This also prevents a bug in delayed branches
3607 ;; from showing up, which reuses one of the registers in our clobbers.
3610 [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
3611 (mem:BLK (match_operand:SI 1 "register_operand" "")))
3612 (clobber (match_operand:SI 4 "register_operand" ""))
3613 (clobber (match_operand:SI 5 "register_operand" ""))
3614 (clobber (match_operand:SI 6 "register_operand" ""))
3615 (clobber (match_operand:SI 7 "register_operand" ""))
3616 (use (match_operand:SI 2 "small_int" ""))
3617 (use (match_operand:SI 3 "small_int" ""))
3618 (use (const_int 0))]
3620 "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
3622 ;; All but the last move
3623 [(parallel [(set (mem:BLK (match_dup 0))
3624 (mem:BLK (match_dup 1)))
3625 (clobber (match_dup 4))
3626 (clobber (match_dup 5))
3627 (clobber (match_dup 6))
3628 (clobber (match_dup 7))
3631 (use (const_int 1))])
3633 ;; The last store, so it can fill a delay slot
3634 (parallel [(set (mem:BLK (match_dup 0))
3635 (mem:BLK (match_dup 1)))
3636 (clobber (match_dup 4))
3637 (clobber (match_dup 5))
3638 (clobber (match_dup 6))
3639 (clobber (match_dup 7))
3642 (use (const_int 2))])]
3646 (define_insn "movstrsi_internal2"
3647 [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
3648 (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
3649 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
3650 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
3651 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
3652 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
3653 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
3654 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
3655 (use (const_int 1))] ;; all but last store
3657 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
3658 [(set_attr "type" "multi")
3659 (set_attr "mode" "none")
3660 (set_attr "length" "20")])
3662 (define_insn "movstrsi_internal3"
3663 [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
3664 (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
3665 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
3666 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
3667 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
3668 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
3669 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
3670 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
3671 (use (const_int 2))] ;; just last store of block move
3673 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
3674 [(set_attr "type" "store")
3675 (set_attr "mode" "none")
3676 (set_attr "length" "1")])
3680 ;; ....................
3684 ;; ....................
3686 (define_insn "ashlsi3"
3687 [(set (match_operand:SI 0 "register_operand" "=d")
3688 (ashift:SI (match_operand:SI 1 "register_operand" "d")
3689 (match_operand:SI 2 "arith_operand" "dI")))]
3693 if (GET_CODE (operands[2]) == CONST_INT)
3694 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
3696 return \"sll\\t%0,%1,%2\";
3698 [(set_attr "type" "arith")
3699 (set_attr "mode" "SI")
3700 (set_attr "length" "1")])
3703 (define_expand "ashldi3"
3704 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3705 (ashift:DI (match_operand:DI 1 "register_operand" "")
3706 (match_operand:SI 2 "arith_operand" "")))
3707 (clobber (match_dup 3))])]
3708 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3713 emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
3718 operands[3] = gen_reg_rtx (SImode);
3722 (define_insn "ashldi3_internal"
3723 [(set (match_operand:DI 0 "register_operand" "=&d")
3724 (ashift:DI (match_operand:DI 1 "register_operand" "d")
3725 (match_operand:SI 2 "register_operand" "d")))
3726 (clobber (match_operand:SI 3 "register_operand" "=d"))]
3727 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
3730 operands[4] = const0_rtx;
3731 dslots_jump_total += 3;
3732 dslots_jump_filled += 2;
3734 return \"sll\\t%3,%2,26\\n\\
3735 \\tbgez\\t%3,1f\\n\\
3736 \\tsll\\t%M0,%L1,%2\\n\\
3738 \\tmove\\t%L0,%z4%)\\n\\
3741 \\t%(beq\\t%3,%z4,2f\\n\\
3742 \\tsll\\t%M0,%M1,%2%)\\n\\
3744 \\tsubu\\t%3,%z4,%2\\n\\
3745 \\tsrl\\t%3,%L1,%3\\n\\
3746 \\tor\\t%M0,%M0,%3\\n\\
3748 \\tsll\\t%L0,%L1,%2\\n\\
3751 [(set_attr "type" "darith")
3752 (set_attr "mode" "SI")
3753 (set_attr "length" "12")])
3756 (define_insn "ashldi3_internal2"
3757 [(set (match_operand:DI 0 "register_operand" "=d")
3758 (ashift:DI (match_operand:DI 1 "register_operand" "d")
3759 (match_operand:SI 2 "small_int" "IJK")))
3760 (clobber (match_operand:SI 3 "register_operand" "=d"))]
3761 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
3764 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
3765 operands[4] = const0_rtx;
3766 return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
3768 [(set_attr "type" "darith")
3769 (set_attr "mode" "DI")
3770 (set_attr "length" "2")])
3774 [(set (match_operand:DI 0 "register_operand" "")
3775 (ashift:DI (match_operand:DI 1 "register_operand" "")
3776 (match_operand:SI 2 "small_int" "")))
3777 (clobber (match_operand:SI 3 "register_operand" ""))]
3778 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3779 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3780 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3781 && (INTVAL (operands[2]) & 32) != 0"
3783 [(set (subreg:SI (match_dup 0) 1) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
3784 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
3786 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
3790 [(set (match_operand:DI 0 "register_operand" "")
3791 (ashift:DI (match_operand:DI 1 "register_operand" "")
3792 (match_operand:SI 2 "small_int" "")))
3793 (clobber (match_operand:SI 3 "register_operand" ""))]
3794 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3795 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3796 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3797 && (INTVAL (operands[2]) & 32) != 0"
3799 [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
3800 (set (subreg:SI (match_dup 0) 1) (const_int 0))]
3802 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
3805 (define_insn "ashldi3_internal3"
3806 [(set (match_operand:DI 0 "register_operand" "=d")
3807 (ashift:DI (match_operand:DI 1 "register_operand" "d")
3808 (match_operand:SI 2 "small_int" "IJK")))
3809 (clobber (match_operand:SI 3 "register_operand" "=d"))]
3810 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE
3811 && (INTVAL (operands[2]) & 63) < 32
3812 && (INTVAL (operands[2]) & 63) != 0"
3815 int amount = INTVAL (operands[2]);
3817 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
3818 operands[4] = const0_rtx;
3819 operands[5] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
3821 return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
3823 [(set_attr "type" "darith")
3824 (set_attr "mode" "DI")
3825 (set_attr "length" "4")])
3829 [(set (match_operand:DI 0 "register_operand" "")
3830 (ashift:DI (match_operand:DI 1 "register_operand" "")
3831 (match_operand:SI 2 "small_int" "")))
3832 (clobber (match_operand:SI 3 "register_operand" ""))]
3833 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3834 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3835 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3836 && (INTVAL (operands[2]) & 63) < 32
3837 && (INTVAL (operands[2]) & 63) != 0"
3839 [(set (subreg:SI (match_dup 0) 1)
3840 (ashift:SI (subreg:SI (match_dup 1) 1)
3844 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
3847 (set (subreg:SI (match_dup 0) 1)
3848 (ior:SI (subreg:SI (match_dup 0) 1)
3851 (set (subreg:SI (match_dup 0) 0)
3852 (ashift:SI (subreg:SI (match_dup 1) 0)
3856 int amount = INTVAL (operands[2]);
3857 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
3858 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
3863 [(set (match_operand:DI 0 "register_operand" "")
3864 (ashift:DI (match_operand:DI 1 "register_operand" "")
3865 (match_operand:SI 2 "small_int" "")))
3866 (clobber (match_operand:SI 3 "register_operand" ""))]
3867 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3868 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3869 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3870 && (INTVAL (operands[2]) & 63) < 32
3871 && (INTVAL (operands[2]) & 63) != 0"
3873 [(set (subreg:SI (match_dup 0) 0)
3874 (ashift:SI (subreg:SI (match_dup 1) 0)
3878 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
3881 (set (subreg:SI (match_dup 0) 0)
3882 (ior:SI (subreg:SI (match_dup 0) 0)
3885 (set (subreg:SI (match_dup 0) 1)
3886 (ashift:SI (subreg:SI (match_dup 1) 1)
3890 int amount = INTVAL (operands[2]);
3891 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
3892 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
3896 (define_insn "ashldi3_internal4"
3897 [(set (match_operand:DI 0 "register_operand" "=d")
3898 (ashift:DI (match_operand:DI 1 "register_operand" "d")
3899 (match_operand:SI 2 "arith_operand" "dI")))]
3903 if (GET_CODE (operands[2]) == CONST_INT)
3904 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
3906 return \"dsll\\t%0,%1,%2\";
3908 [(set_attr "type" "arith")
3909 (set_attr "mode" "DI")
3910 (set_attr "length" "1")])
3913 (define_insn "ashrsi3"
3914 [(set (match_operand:SI 0 "register_operand" "=d")
3915 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
3916 (match_operand:SI 2 "arith_operand" "dI")))]
3920 if (GET_CODE (operands[2]) == CONST_INT)
3921 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
3923 return \"sra\\t%0,%1,%2\";
3925 [(set_attr "type" "arith")
3926 (set_attr "mode" "SI")
3927 (set_attr "length" "1")])
3930 (define_expand "ashrdi3"
3931 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3932 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
3933 (match_operand:SI 2 "arith_operand" "")))
3934 (clobber (match_dup 3))])]
3935 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3940 emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
3945 operands[3] = gen_reg_rtx (SImode);
3949 (define_insn "ashrdi3_internal"
3950 [(set (match_operand:DI 0 "register_operand" "=&d")
3951 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
3952 (match_operand:SI 2 "register_operand" "d")))
3953 (clobber (match_operand:SI 3 "register_operand" "=d"))]
3954 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
3957 operands[4] = const0_rtx;
3958 dslots_jump_total += 3;
3959 dslots_jump_filled += 2;
3961 return \"sll\\t%3,%2,26\\n\\
3962 \\tbgez\\t%3,1f\\n\\
3963 \\tsra\\t%L0,%M1,%2\\n\\
3965 \\tsra\\t%M0,%M1,31%)\\n\\
3968 \\t%(beq\\t%3,%z4,2f\\n\\
3969 \\tsrl\\t%L0,%L1,%2%)\\n\\
3971 \\tsubu\\t%3,%z4,%2\\n\\
3972 \\tsll\\t%3,%M1,%3\\n\\
3973 \\tor\\t%L0,%L0,%3\\n\\
3975 \\tsra\\t%M0,%M1,%2\\n\\
3978 [(set_attr "type" "darith")
3979 (set_attr "mode" "DI")
3980 (set_attr "length" "12")])
3983 (define_insn "ashrdi3_internal2"
3984 [(set (match_operand:DI 0 "register_operand" "=d")
3985 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
3986 (match_operand:SI 2 "small_int" "IJK")))
3987 (clobber (match_operand:SI 3 "register_operand" "=d"))]
3988 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
3991 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
3992 return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
3994 [(set_attr "type" "darith")
3995 (set_attr "mode" "DI")
3996 (set_attr "length" "2")])
4000 [(set (match_operand:DI 0 "register_operand" "")
4001 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4002 (match_operand:SI 2 "small_int" "")))
4003 (clobber (match_operand:SI 3 "register_operand" ""))]
4004 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4005 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4006 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4007 && (INTVAL (operands[2]) & 32) != 0"
4009 [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
4010 (set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (const_int 31)))]
4012 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4016 [(set (match_operand:DI 0 "register_operand" "")
4017 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4018 (match_operand:SI 2 "small_int" "")))
4019 (clobber (match_operand:SI 3 "register_operand" ""))]
4020 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4021 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4022 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4023 && (INTVAL (operands[2]) & 32) != 0"
4025 [(set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
4026 (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
4028 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4031 (define_insn "ashrdi3_internal3"
4032 [(set (match_operand:DI 0 "register_operand" "=d")
4033 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4034 (match_operand:SI 2 "small_int" "IJK")))
4035 (clobber (match_operand:SI 3 "register_operand" "=d"))]
4036 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE
4037 && (INTVAL (operands[2]) & 63) < 32
4038 && (INTVAL (operands[2]) & 63) != 0"
4041 int amount = INTVAL (operands[2]);
4043 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4044 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4046 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
4048 [(set_attr "type" "darith")
4049 (set_attr "mode" "DI")
4050 (set_attr "length" "4")])
4054 [(set (match_operand:DI 0 "register_operand" "")
4055 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4056 (match_operand:SI 2 "small_int" "")))
4057 (clobber (match_operand:SI 3 "register_operand" ""))]
4058 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4059 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4060 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4061 && (INTVAL (operands[2]) & 63) < 32
4062 && (INTVAL (operands[2]) & 63) != 0"
4064 [(set (subreg:SI (match_dup 0) 0)
4065 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
4069 (ashift:SI (subreg:SI (match_dup 1) 1)
4072 (set (subreg:SI (match_dup 0) 0)
4073 (ior:SI (subreg:SI (match_dup 0) 0)
4076 (set (subreg:SI (match_dup 0) 1)
4077 (ashiftrt:SI (subreg:SI (match_dup 1) 1)
4081 int amount = INTVAL (operands[2]);
4082 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4083 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4088 [(set (match_operand:DI 0 "register_operand" "")
4089 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4090 (match_operand:SI 2 "small_int" "")))
4091 (clobber (match_operand:SI 3 "register_operand" ""))]
4092 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4093 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4094 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4095 && (INTVAL (operands[2]) & 63) < 32
4096 && (INTVAL (operands[2]) & 63) != 0"
4098 [(set (subreg:SI (match_dup 0) 1)
4099 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
4103 (ashift:SI (subreg:SI (match_dup 1) 0)
4106 (set (subreg:SI (match_dup 0) 1)
4107 (ior:SI (subreg:SI (match_dup 0) 1)
4110 (set (subreg:SI (match_dup 0) 0)
4111 (ashiftrt:SI (subreg:SI (match_dup 1) 0)
4115 int amount = INTVAL (operands[2]);
4116 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4117 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4121 (define_insn "ashrdi3_internal4"
4122 [(set (match_operand:DI 0 "register_operand" "=d")
4123 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4124 (match_operand:SI 2 "arith_operand" "dI")))]
4128 if (GET_CODE (operands[2]) == CONST_INT)
4129 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4131 return \"dsra\\t%0,%1,%2\";
4133 [(set_attr "type" "arith")
4134 (set_attr "mode" "DI")
4135 (set_attr "length" "1")])
4138 (define_insn "lshrsi3"
4139 [(set (match_operand:SI 0 "register_operand" "=d")
4140 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
4141 (match_operand:SI 2 "arith_operand" "dI")))]
4145 if (GET_CODE (operands[2]) == CONST_INT)
4146 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
4148 return \"srl\\t%0,%1,%2\";
4150 [(set_attr "type" "arith")
4151 (set_attr "mode" "SI")
4152 (set_attr "length" "1")])
4155 (define_expand "lshrdi3"
4156 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4157 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4158 (match_operand:SI 2 "arith_operand" "")))
4159 (clobber (match_dup 3))])]
4160 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
4165 emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
4170 operands[3] = gen_reg_rtx (SImode);
4174 (define_insn "lshrdi3_internal"
4175 [(set (match_operand:DI 0 "register_operand" "=&d")
4176 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4177 (match_operand:SI 2 "register_operand" "d")))
4178 (clobber (match_operand:SI 3 "register_operand" "=d"))]
4179 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
4182 operands[4] = const0_rtx;
4183 dslots_jump_total += 3;
4184 dslots_jump_filled += 2;
4186 return \"sll\\t%3,%2,26\\n\\
4187 \\tbgez\\t%3,1f\\n\\
4188 \\tsrl\\t%L0,%M1,%2\\n\\
4190 \\tmove\\t%M0,%z4%)\\n\\
4193 \\t%(beq\\t%3,%z4,2f\\n\\
4194 \\tsrl\\t%L0,%L1,%2%)\\n\\
4196 \\tsubu\\t%3,%z4,%2\\n\\
4197 \\tsll\\t%3,%M1,%3\\n\\
4198 \\tor\\t%L0,%L0,%3\\n\\
4200 \\tsrl\\t%M0,%M1,%2\\n\\
4203 [(set_attr "type" "darith")
4204 (set_attr "mode" "DI")
4205 (set_attr "length" "12")])
4208 (define_insn "lshrdi3_internal2"
4209 [(set (match_operand:DI 0 "register_operand" "=d")
4210 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4211 (match_operand:SI 2 "small_int" "IJK")))
4212 (clobber (match_operand:SI 3 "register_operand" "=d"))]
4213 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
4216 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
4217 operands[4] = const0_rtx;
4218 return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
4220 [(set_attr "type" "darith")
4221 (set_attr "mode" "DI")
4222 (set_attr "length" "2")])
4226 [(set (match_operand:DI 0 "register_operand" "")
4227 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4228 (match_operand:SI 2 "small_int" "")))
4229 (clobber (match_operand:SI 3 "register_operand" ""))]
4230 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4231 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4232 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4233 && (INTVAL (operands[2]) & 32) != 0"
4235 [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
4236 (set (subreg:SI (match_dup 0) 1) (const_int 0))]
4238 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4242 [(set (match_operand:DI 0 "register_operand" "")
4243 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4244 (match_operand:SI 2 "small_int" "")))
4245 (clobber (match_operand:SI 3 "register_operand" ""))]
4246 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4247 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4248 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4249 && (INTVAL (operands[2]) & 32) != 0"
4251 [(set (subreg:SI (match_dup 0) 1) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
4252 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
4254 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4257 (define_insn "lshrdi3_internal3"
4258 [(set (match_operand:DI 0 "register_operand" "=d")
4259 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4260 (match_operand:SI 2 "small_int" "IJK")))
4261 (clobber (match_operand:SI 3 "register_operand" "=d"))]
4262 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE
4263 && (INTVAL (operands[2]) & 63) < 32
4264 && (INTVAL (operands[2]) & 63) != 0"
4267 int amount = INTVAL (operands[2]);
4269 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4270 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4272 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
4274 [(set_attr "type" "darith")
4275 (set_attr "mode" "DI")
4276 (set_attr "length" "4")])
4280 [(set (match_operand:DI 0 "register_operand" "")
4281 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4282 (match_operand:SI 2 "small_int" "")))
4283 (clobber (match_operand:SI 3 "register_operand" ""))]
4284 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4285 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4286 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4287 && (INTVAL (operands[2]) & 63) < 32
4288 && (INTVAL (operands[2]) & 63) != 0"
4290 [(set (subreg:SI (match_dup 0) 0)
4291 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
4295 (ashift:SI (subreg:SI (match_dup 1) 1)
4298 (set (subreg:SI (match_dup 0) 0)
4299 (ior:SI (subreg:SI (match_dup 0) 0)
4302 (set (subreg:SI (match_dup 0) 1)
4303 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
4307 int amount = INTVAL (operands[2]);
4308 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4309 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4314 [(set (match_operand:DI 0 "register_operand" "")
4315 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4316 (match_operand:SI 2 "small_int" "")))
4317 (clobber (match_operand:SI 3 "register_operand" ""))]
4318 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4319 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4320 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4321 && (INTVAL (operands[2]) & 63) < 32
4322 && (INTVAL (operands[2]) & 63) != 0"
4324 [(set (subreg:SI (match_dup 0) 1)
4325 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
4329 (ashift:SI (subreg:SI (match_dup 1) 0)
4332 (set (subreg:SI (match_dup 0) 1)
4333 (ior:SI (subreg:SI (match_dup 0) 1)
4336 (set (subreg:SI (match_dup 0) 0)
4337 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
4341 int amount = INTVAL (operands[2]);
4342 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4343 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4347 (define_insn "lshrdi3_internal4"
4348 [(set (match_operand:DI 0 "register_operand" "=d")
4349 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4350 (match_operand:SI 2 "arith_operand" "dI")))]
4354 if (GET_CODE (operands[2]) == CONST_INT)
4355 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4357 return \"dsrl\\t%0,%1,%2\";
4359 [(set_attr "type" "arith")
4360 (set_attr "mode" "DI")
4361 (set_attr "length" "1")])
4365 ;; ....................
4369 ;; ....................
4371 ;; Flow here is rather complex:
4373 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
4374 ;; arguments into the branch_cmp array, and the type into
4375 ;; branch_type. No RTL is generated.
4377 ;; 2) The appropriate branch define_expand is called, which then
4378 ;; creates the appropriate RTL for the comparison and branch.
4379 ;; Different CC modes are used, based on what type of branch is
4380 ;; done, so that we can constrain things appropriately. There
4381 ;; are assumptions in the rest of GCC that break if we fold the
4382 ;; operands into the branchs for integer operations, and use cc0
4383 ;; for floating point, so we use the fp status register instead.
4384 ;; If needed, an appropriate temporary is created to hold the
4385 ;; of the integer compare.
4387 (define_expand "cmpsi"
4389 (compare:CC (match_operand:SI 0 "register_operand" "")
4390 (match_operand:SI 1 "arith_operand" "")))]
4394 if (operands[0]) /* avoid unused code message */
4396 branch_cmp[0] = operands[0];
4397 branch_cmp[1] = operands[1];
4398 branch_type = CMP_SI;
4403 (define_expand "tstsi"
4405 (match_operand:SI 0 "register_operand" ""))]
4409 if (operands[0]) /* avoid unused code message */
4411 branch_cmp[0] = operands[0];
4412 branch_cmp[1] = const0_rtx;
4413 branch_type = CMP_SI;
4418 (define_expand "cmpdi"
4420 (compare:CC (match_operand:DI 0 "register_operand" "")
4421 (match_operand:DI 1 "arith_operand" "")))]
4425 if (operands[0]) /* avoid unused code message */
4427 branch_cmp[0] = operands[0];
4428 branch_cmp[1] = operands[1];
4429 branch_type = CMP_DI;
4434 (define_expand "tstdi"
4436 (match_operand:DI 0 "register_operand" ""))]
4440 if (operands[0]) /* avoid unused code message */
4442 branch_cmp[0] = operands[0];
4443 branch_cmp[1] = const0_rtx;
4444 branch_type = CMP_DI;
4449 (define_expand "cmpdf"
4451 (compare:CC_FP (match_operand:DF 0 "register_operand" "")
4452 (match_operand:DF 1 "register_operand" "")))]
4453 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4456 if (operands[0]) /* avoid unused code message */
4458 branch_cmp[0] = operands[0];
4459 branch_cmp[1] = operands[1];
4460 branch_type = CMP_DF;
4465 (define_expand "cmpsf"
4467 (compare:CC_FP (match_operand:SF 0 "register_operand" "")
4468 (match_operand:SF 1 "register_operand" "")))]
4472 if (operands[0]) /* avoid unused code message */
4474 branch_cmp[0] = operands[0];
4475 branch_cmp[1] = operands[1];
4476 branch_type = CMP_SF;
4483 ;; ....................
4485 ;; CONDITIONAL BRANCHES
4487 ;; ....................
4489 (define_insn "branch_fp_ne"
4491 (if_then_else (ne:CC_FP (reg:CC_FP 67)
4493 (match_operand 0 "pc_or_label_operand" "")
4494 (match_operand 1 "pc_or_label_operand" "")))]
4498 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
4499 return (operands[0] != pc_rtx) ? \"%*bc1t%?\\t%0\" : \"%*bc1f%?\\t%1\";
4501 [(set_attr "type" "branch")
4502 (set_attr "mode" "none")
4503 (set_attr "length" "1")])
4505 (define_insn "branch_fp_ne_rev"
4507 (if_then_else (ne:CC_REV_FP (reg:CC_REV_FP 67)
4509 (match_operand 0 "pc_or_label_operand" "")
4510 (match_operand 1 "pc_or_label_operand" "")))]
4514 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
4515 return (operands[0] != pc_rtx) ? \"%*bc1f%?\\t%0\" : \"%*bc1t%?\\t%1\";
4517 [(set_attr "type" "branch")
4518 (set_attr "mode" "none")
4519 (set_attr "length" "1")])
4521 (define_insn "branch_fp_eq"
4523 (if_then_else (eq:CC_FP (reg:CC_FP 67)
4525 (match_operand 0 "pc_or_label_operand" "")
4526 (match_operand 1 "pc_or_label_operand" "")))]
4530 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
4531 return (operands[0] != pc_rtx) ? \"%*bc1f%?\\t%0\" : \"%*bc1t%?\\t%1\";
4533 [(set_attr "type" "branch")
4534 (set_attr "mode" "none")
4535 (set_attr "length" "1")])
4537 (define_insn "branch_fp_eq_rev"
4539 (if_then_else (eq:CC_REV_FP (reg:CC_REV_FP 67)
4541 (match_operand 0 "pc_or_label_operand" "")
4542 (match_operand 1 "pc_or_label_operand" "")))]
4546 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
4547 return (operands[0] != pc_rtx) ? \"%*bc1t%?\\t%0\" : \"%*bc1f%?\\t%1\";
4549 [(set_attr "type" "branch")
4550 (set_attr "mode" "none")
4551 (set_attr "length" "1")])
4554 (define_insn "branch_zero"
4556 (if_then_else (match_operator:SI 0 "cmp_op"
4557 [(match_operand:SI 1 "register_operand" "d")
4559 (match_operand 2 "pc_or_label_operand" "")
4560 (match_operand 3 "pc_or_label_operand" "")))]
4564 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
4565 if (operands[2] != pc_rtx)
4567 switch (GET_CODE (operands[0]))
4569 case EQ: return \"%*beq%?\\t%z1,%.,%2\";
4570 case NE: return \"%*bne%?\\t%z1,%.,%2\";
4571 case GTU: return \"%*bne%?\\t%z1,%.,%2\";
4572 case LEU: return \"%*beq%?\\t%z1,%.,%2\";
4573 case GEU: return \"%*j\\t%2\";
4574 case LTU: return \"%*bne%?\\t%.,%.,%2\";
4577 return \"%*b%C0z%?\\t%z1,%2\";
4580 { /* inverted jump */
4581 switch (GET_CODE (operands[0]))
4583 case EQ: return \"%*bne%?\\t%z1,%.,%3\";
4584 case NE: return \"%*beq%?\\t%z1,%.,%3\";
4585 case GTU: return \"%*beq%?\\t%z1,%.,%3\";
4586 case LEU: return \"%*bne%?\\t%z1,%.,%3\";
4587 case GEU: return \"%*beq%?\\t%.,%.,%3\";
4588 case LTU: return \"%*j\\t%3\";
4591 return \"%*b%N0z%?\\t%z1,%3\";
4594 [(set_attr "type" "branch")
4595 (set_attr "mode" "none")
4596 (set_attr "length" "1")])
4599 (define_insn "branch_zero_di"
4601 (if_then_else (match_operator:DI 0 "cmp_op"
4602 [(match_operand:DI 1 "register_operand" "d")
4604 (match_operand 2 "pc_or_label_operand" "")
4605 (match_operand 3 "pc_or_label_operand" "")))]
4609 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
4610 if (operands[2] != pc_rtx)
4612 switch (GET_CODE (operands[0]))
4614 case EQ: return \"%*beq%?\\t%z1,%.,%2\";
4615 case NE: return \"%*bne%?\\t%z1,%.,%2\";
4616 case GTU: return \"%*bne%?\\t%z1,%.,%2\";
4617 case LEU: return \"%*beq%?\\t%z1,%.,%2\";
4618 case GEU: return \"%*j\\t%2\";
4619 case LTU: return \"%*bne%?\\t%.,%.,%2\";
4622 return \"%*b%C0z%?\\t%z1,%2\";
4625 { /* inverted jump */
4626 switch (GET_CODE (operands[0]))
4628 case EQ: return \"%*bne%?\\t%z1,%.,%3\";
4629 case NE: return \"%*beq%?\\t%z1,%.,%3\";
4630 case GTU: return \"%*beq%?\\t%z1,%.,%3\";
4631 case LEU: return \"%*bne%?\\t%z1,%.,%3\";
4632 case GEU: return \"%*beq%?\\t%.,%.,%3\";
4633 case LTU: return \"%*j\\t%3\";
4636 return \"%*b%N0z%?\\t%z1,%3\";
4639 [(set_attr "type" "branch")
4640 (set_attr "mode" "none")
4641 (set_attr "length" "1")])
4644 (define_insn "branch_equality"
4646 (if_then_else (match_operator:SI 0 "equality_op"
4647 [(match_operand:SI 1 "register_operand" "d")
4648 (match_operand:SI 2 "register_operand" "d")])
4649 (match_operand 3 "pc_or_label_operand" "")
4650 (match_operand 4 "pc_or_label_operand" "")))]
4654 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
4655 return (operands[3] != pc_rtx)
4656 ? \"%*b%C0%?\\t%z1,%z2,%3\"
4657 : \"%*b%N0%?\\t%z1,%z2,%4\";
4659 [(set_attr "type" "branch")
4660 (set_attr "mode" "none")
4661 (set_attr "length" "1")])
4664 (define_insn "branch_equality_di"
4666 (if_then_else (match_operator:DI 0 "equality_op"
4667 [(match_operand:DI 1 "register_operand" "d")
4668 (match_operand:DI 2 "register_operand" "d")])
4669 (match_operand 3 "pc_or_label_operand" "")
4670 (match_operand 4 "pc_or_label_operand" "")))]
4674 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
4675 return (operands[3] != pc_rtx)
4676 ? \"%*b%C0%?\\t%z1,%z2,%3\"
4677 : \"%*b%N0%?\\t%z1,%z2,%4\";
4679 [(set_attr "type" "branch")
4680 (set_attr "mode" "none")
4681 (set_attr "length" "1")])
4684 (define_expand "beq"
4686 (if_then_else (eq:CC_EQ (cc0)
4688 (label_ref (match_operand 0 "" ""))
4693 if (operands[0]) /* avoid unused code warning */
4695 gen_conditional_branch (operands, EQ);
4700 (define_expand "bne"
4702 (if_then_else (ne:CC_EQ (cc0)
4704 (label_ref (match_operand 0 "" ""))
4709 if (operands[0]) /* avoid unused code warning */
4711 gen_conditional_branch (operands, NE);
4716 (define_expand "bgt"
4718 (if_then_else (gt:CC (cc0)
4720 (label_ref (match_operand 0 "" ""))
4725 if (operands[0]) /* avoid unused code warning */
4727 gen_conditional_branch (operands, GT);
4732 (define_expand "bge"
4734 (if_then_else (ge:CC (cc0)
4736 (label_ref (match_operand 0 "" ""))
4741 if (operands[0]) /* avoid unused code warning */
4743 gen_conditional_branch (operands, GE);
4748 (define_expand "blt"
4750 (if_then_else (lt:CC (cc0)
4752 (label_ref (match_operand 0 "" ""))
4757 if (operands[0]) /* avoid unused code warning */
4759 gen_conditional_branch (operands, LT);
4764 (define_expand "ble"
4766 (if_then_else (le:CC (cc0)
4768 (label_ref (match_operand 0 "" ""))
4773 if (operands[0]) /* avoid unused code warning */
4775 gen_conditional_branch (operands, LE);
4780 (define_expand "bgtu"
4782 (if_then_else (gtu:CC (cc0)
4784 (label_ref (match_operand 0 "" ""))
4789 if (operands[0]) /* avoid unused code warning */
4791 gen_conditional_branch (operands, GTU);
4796 (define_expand "bgeu"
4798 (if_then_else (geu:CC (cc0)
4800 (label_ref (match_operand 0 "" ""))
4805 if (operands[0]) /* avoid unused code warning */
4807 gen_conditional_branch (operands, GEU);
4813 (define_expand "bltu"
4815 (if_then_else (ltu:CC (cc0)
4817 (label_ref (match_operand 0 "" ""))
4822 if (operands[0]) /* avoid unused code warning */
4824 gen_conditional_branch (operands, LTU);
4829 (define_expand "bleu"
4831 (if_then_else (leu:CC (cc0)
4833 (label_ref (match_operand 0 "" ""))
4838 if (operands[0]) /* avoid unused code warning */
4840 gen_conditional_branch (operands, LEU);
4847 ;; ....................
4849 ;; SETTING A REGISTER FROM A COMPARISON
4851 ;; ....................
4853 (define_expand "seq"
4854 [(set (match_operand:SI 0 "register_operand" "=d")
4855 (eq:SI (match_dup 1)
4860 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
4863 /* set up operands from compare. */
4864 operands[1] = branch_cmp[0];
4865 operands[2] = branch_cmp[1];
4867 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
4869 gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
4873 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
4874 operands[2] = force_reg (SImode, operands[2]);
4876 /* fall through and generate default code */
4880 (define_insn "seq_si_zero"
4881 [(set (match_operand:SI 0 "register_operand" "=d")
4882 (eq:SI (match_operand:SI 1 "register_operand" "d")
4886 [(set_attr "type" "arith")
4887 (set_attr "mode" "SI")
4888 (set_attr "length" "1")])
4890 (define_insn "seq_di_zero"
4891 [(set (match_operand:DI 0 "register_operand" "=d")
4892 (eq:DI (match_operand:DI 1 "register_operand" "d")
4896 [(set_attr "type" "arith")
4897 (set_attr "mode" "DI")
4898 (set_attr "length" "1")])
4900 (define_insn "seq_si"
4901 [(set (match_operand:SI 0 "register_operand" "=d,d")
4902 (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
4903 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
4904 "TARGET_DEBUG_C_MODE"
4906 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
4907 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
4908 [(set_attr "type" "arith")
4909 (set_attr "mode" "SI")
4910 (set_attr "length" "2")])
4913 [(set (match_operand:SI 0 "register_operand" "")
4914 (eq:SI (match_operand:SI 1 "register_operand" "")
4915 (match_operand:SI 2 "uns_arith_operand" "")))]
4916 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
4917 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
4919 (xor:SI (match_dup 1)
4922 (ltu:SI (match_dup 0)
4926 (define_insn "seq_di"
4927 [(set (match_operand:DI 0 "register_operand" "=d,d")
4928 (eq:DI (match_operand:DI 1 "register_operand" "%d,d")
4929 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
4930 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
4932 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
4933 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
4934 [(set_attr "type" "arith")
4935 (set_attr "mode" "DI")
4936 (set_attr "length" "2")])
4939 [(set (match_operand:DI 0 "register_operand" "")
4940 (eq:DI (match_operand:DI 1 "register_operand" "")
4941 (match_operand:DI 2 "uns_arith_operand" "")))]
4942 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
4943 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
4945 (xor:DI (match_dup 1)
4948 (ltu:DI (match_dup 0)
4952 (define_expand "sne"
4953 [(set (match_operand:SI 0 "register_operand" "=d")
4954 (ne:SI (match_dup 1)
4959 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
4962 /* set up operands from compare. */
4963 operands[1] = branch_cmp[0];
4964 operands[2] = branch_cmp[1];
4966 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
4968 gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
4972 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
4973 operands[2] = force_reg (SImode, operands[2]);
4975 /* fall through and generate default code */
4978 (define_insn "sne_si_zero"
4979 [(set (match_operand:SI 0 "register_operand" "=d")
4980 (ne:SI (match_operand:SI 1 "register_operand" "d")
4984 [(set_attr "type" "arith")
4985 (set_attr "mode" "SI")
4986 (set_attr "length" "1")])
4988 (define_insn "sne_di_zero"
4989 [(set (match_operand:DI 0 "register_operand" "=d")
4990 (ne:DI (match_operand:DI 1 "register_operand" "d")
4994 [(set_attr "type" "arith")
4995 (set_attr "mode" "DI")
4996 (set_attr "length" "1")])
4998 (define_insn "sne_si"
4999 [(set (match_operand:SI 0 "register_operand" "=d,d")
5000 (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
5001 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
5002 "TARGET_DEBUG_C_MODE"
5004 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
5005 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
5006 [(set_attr "type" "arith")
5007 (set_attr "mode" "SI")
5008 (set_attr "length" "2")])
5011 [(set (match_operand:SI 0 "register_operand" "")
5012 (ne:SI (match_operand:SI 1 "register_operand" "")
5013 (match_operand:SI 2 "uns_arith_operand" "")))]
5014 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
5015 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
5017 (xor:SI (match_dup 1)
5020 (gtu:SI (match_dup 0)
5024 (define_insn "sne_di"
5025 [(set (match_operand:DI 0 "register_operand" "=d,d")
5026 (ne:DI (match_operand:DI 1 "register_operand" "%d,d")
5027 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
5028 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5030 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
5031 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
5032 [(set_attr "type" "arith")
5033 (set_attr "mode" "DI")
5034 (set_attr "length" "2")])
5037 [(set (match_operand:DI 0 "register_operand" "")
5038 (ne:DI (match_operand:DI 1 "register_operand" "")
5039 (match_operand:DI 2 "uns_arith_operand" "")))]
5040 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
5041 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
5043 (xor:DI (match_dup 1)
5046 (gtu:DI (match_dup 0)
5050 (define_expand "sgt"
5051 [(set (match_operand:SI 0 "register_operand" "=d")
5052 (gt:SI (match_dup 1)
5057 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5060 /* set up operands from compare. */
5061 operands[1] = branch_cmp[0];
5062 operands[2] = branch_cmp[1];
5064 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5066 gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
5070 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
5071 operands[2] = force_reg (SImode, operands[2]);
5073 /* fall through and generate default code */
5076 (define_insn "sgt_si"
5077 [(set (match_operand:SI 0 "register_operand" "=d")
5078 (gt:SI (match_operand:SI 1 "register_operand" "d")
5079 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
5082 [(set_attr "type" "arith")
5083 (set_attr "mode" "SI")
5084 (set_attr "length" "1")])
5086 (define_insn "sgt_di"
5087 [(set (match_operand:DI 0 "register_operand" "=d")
5088 (gt:DI (match_operand:DI 1 "register_operand" "d")
5089 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
5092 [(set_attr "type" "arith")
5093 (set_attr "mode" "DI")
5094 (set_attr "length" "1")])
5096 (define_expand "sge"
5097 [(set (match_operand:SI 0 "register_operand" "=d")
5098 (ge:SI (match_dup 1)
5103 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5106 /* set up operands from compare. */
5107 operands[1] = branch_cmp[0];
5108 operands[2] = branch_cmp[1];
5110 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5112 gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
5116 /* fall through and generate default code */
5119 (define_insn "sge_si"
5120 [(set (match_operand:SI 0 "register_operand" "=d")
5121 (ge:SI (match_operand:SI 1 "register_operand" "d")
5122 (match_operand:SI 2 "arith_operand" "dI")))]
5123 "TARGET_DEBUG_C_MODE"
5124 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5125 [(set_attr "type" "arith")
5126 (set_attr "mode" "SI")
5127 (set_attr "length" "2")])
5130 [(set (match_operand:SI 0 "register_operand" "")
5131 (ge:SI (match_operand:SI 1 "register_operand" "")
5132 (match_operand:SI 2 "arith_operand" "")))]
5133 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5135 (lt:SI (match_dup 1)
5138 (xor:SI (match_dup 0)
5142 (define_insn "sge_di"
5143 [(set (match_operand:DI 0 "register_operand" "=d")
5144 (ge:DI (match_operand:DI 1 "register_operand" "d")
5145 (match_operand:DI 2 "arith_operand" "dI")))]
5146 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5147 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5148 [(set_attr "type" "arith")
5149 (set_attr "mode" "DI")
5150 (set_attr "length" "2")])
5153 [(set (match_operand:DI 0 "register_operand" "")
5154 (ge:DI (match_operand:DI 1 "register_operand" "")
5155 (match_operand:DI 2 "arith_operand" "")))]
5156 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5158 (lt:DI (match_dup 1)
5161 (xor:DI (match_dup 0)
5165 (define_expand "slt"
5166 [(set (match_operand:SI 0 "register_operand" "=d")
5167 (lt:SI (match_dup 1)
5172 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5175 /* set up operands from compare. */
5176 operands[1] = branch_cmp[0];
5177 operands[2] = branch_cmp[1];
5179 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5181 gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
5185 /* fall through and generate default code */
5188 (define_insn "slt_si"
5189 [(set (match_operand:SI 0 "register_operand" "=d")
5190 (lt:SI (match_operand:SI 1 "register_operand" "d")
5191 (match_operand:SI 2 "arith_operand" "dI")))]
5194 [(set_attr "type" "arith")
5195 (set_attr "mode" "SI")
5196 (set_attr "length" "1")])
5198 (define_insn "slt_di"
5199 [(set (match_operand:DI 0 "register_operand" "=d")
5200 (lt:DI (match_operand:DI 1 "register_operand" "d")
5201 (match_operand:DI 2 "arith_operand" "dI")))]
5204 [(set_attr "type" "arith")
5205 (set_attr "mode" "DI")
5206 (set_attr "length" "1")])
5208 (define_expand "sle"
5209 [(set (match_operand:SI 0 "register_operand" "=d")
5210 (le:SI (match_dup 1)
5215 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5218 /* set up operands from compare. */
5219 operands[1] = branch_cmp[0];
5220 operands[2] = branch_cmp[1];
5222 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5224 gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
5228 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
5229 operands[2] = force_reg (SImode, operands[2]);
5231 /* fall through and generate default code */
5234 (define_insn "sle_si_const"
5235 [(set (match_operand:SI 0 "register_operand" "=d")
5236 (le:SI (match_operand:SI 1 "register_operand" "d")
5237 (match_operand:SI 2 "small_int" "I")))]
5238 "INTVAL (operands[2]) < 32767"
5241 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
5242 return \"slt\\t%0,%1,%2\";
5244 [(set_attr "type" "arith")
5245 (set_attr "mode" "SI")
5246 (set_attr "length" "1")])
5248 (define_insn "sle_di_const"
5249 [(set (match_operand:DI 0 "register_operand" "=d")
5250 (le:DI (match_operand:DI 1 "register_operand" "d")
5251 (match_operand:DI 2 "small_int" "I")))]
5252 "TARGET_64BIT && INTVAL (operands[2]) < 32767"
5255 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
5256 return \"slt\\t%0,%1,%2\";
5258 [(set_attr "type" "arith")
5259 (set_attr "mode" "DI")
5260 (set_attr "length" "1")])
5262 (define_insn "sle_si_reg"
5263 [(set (match_operand:SI 0 "register_operand" "=d")
5264 (le:SI (match_operand:SI 1 "register_operand" "d")
5265 (match_operand:SI 2 "register_operand" "d")))]
5266 "TARGET_DEBUG_C_MODE"
5267 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
5268 [(set_attr "type" "arith")
5269 (set_attr "mode" "SI")
5270 (set_attr "length" "2")])
5273 [(set (match_operand:SI 0 "register_operand" "")
5274 (le:SI (match_operand:SI 1 "register_operand" "")
5275 (match_operand:SI 2 "register_operand" "")))]
5276 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5278 (lt:SI (match_dup 2)
5281 (xor:SI (match_dup 0)
5285 (define_insn "sle_di_reg"
5286 [(set (match_operand:DI 0 "register_operand" "=d")
5287 (le:DI (match_operand:DI 1 "register_operand" "d")
5288 (match_operand:DI 2 "register_operand" "d")))]
5289 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5290 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
5291 [(set_attr "type" "arith")
5292 (set_attr "mode" "DI")
5293 (set_attr "length" "2")])
5296 [(set (match_operand:DI 0 "register_operand" "")
5297 (le:DI (match_operand:DI 1 "register_operand" "")
5298 (match_operand:DI 2 "register_operand" "")))]
5299 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5301 (lt:DI (match_dup 2)
5304 (xor:DI (match_dup 0)
5308 (define_expand "sgtu"
5309 [(set (match_operand:SI 0 "register_operand" "=d")
5310 (gtu:SI (match_dup 1)
5315 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5318 /* set up operands from compare. */
5319 operands[1] = branch_cmp[0];
5320 operands[2] = branch_cmp[1];
5322 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5324 gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
5328 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
5329 operands[2] = force_reg (SImode, operands[2]);
5331 /* fall through and generate default code */
5334 (define_insn "sgtu_si"
5335 [(set (match_operand:SI 0 "register_operand" "=d")
5336 (gtu:SI (match_operand:SI 1 "register_operand" "d")
5337 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
5340 [(set_attr "type" "arith")
5341 (set_attr "mode" "SI")
5342 (set_attr "length" "1")])
5344 (define_insn "sgtu_di"
5345 [(set (match_operand:DI 0 "register_operand" "=d")
5346 (gtu:DI (match_operand:DI 1 "register_operand" "d")
5347 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
5350 [(set_attr "type" "arith")
5351 (set_attr "mode" "DI")
5352 (set_attr "length" "1")])
5354 (define_expand "sgeu"
5355 [(set (match_operand:SI 0 "register_operand" "=d")
5356 (geu:SI (match_dup 1)
5361 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5364 /* set up operands from compare. */
5365 operands[1] = branch_cmp[0];
5366 operands[2] = branch_cmp[1];
5368 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5370 gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
5374 /* fall through and generate default code */
5377 (define_insn "sgeu_si"
5378 [(set (match_operand:SI 0 "register_operand" "=d")
5379 (geu:SI (match_operand:SI 1 "register_operand" "d")
5380 (match_operand:SI 2 "arith_operand" "dI")))]
5381 "TARGET_DEBUG_C_MODE"
5382 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5383 [(set_attr "type" "arith")
5384 (set_attr "mode" "SI")
5385 (set_attr "length" "2")])
5388 [(set (match_operand:SI 0 "register_operand" "")
5389 (geu:SI (match_operand:SI 1 "register_operand" "")
5390 (match_operand:SI 2 "arith_operand" "")))]
5391 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5393 (ltu:SI (match_dup 1)
5396 (xor:SI (match_dup 0)
5400 (define_insn "sgeu_di"
5401 [(set (match_operand:DI 0 "register_operand" "=d")
5402 (geu:DI (match_operand:DI 1 "register_operand" "d")
5403 (match_operand:DI 2 "arith_operand" "dI")))]
5404 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5405 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5406 [(set_attr "type" "arith")
5407 (set_attr "mode" "DI")
5408 (set_attr "length" "2")])
5411 [(set (match_operand:DI 0 "register_operand" "")
5412 (geu:DI (match_operand:DI 1 "register_operand" "")
5413 (match_operand:DI 2 "arith_operand" "")))]
5414 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5416 (ltu:DI (match_dup 1)
5419 (xor:DI (match_dup 0)
5423 (define_expand "sltu"
5424 [(set (match_operand:SI 0 "register_operand" "=d")
5425 (ltu:SI (match_dup 1)
5430 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5433 /* set up operands from compare. */
5434 operands[1] = branch_cmp[0];
5435 operands[2] = branch_cmp[1];
5437 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5439 gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
5443 /* fall through and generate default code */
5446 (define_insn "sltu_si"
5447 [(set (match_operand:SI 0 "register_operand" "=d")
5448 (ltu:SI (match_operand:SI 1 "register_operand" "d")
5449 (match_operand:SI 2 "arith_operand" "dI")))]
5452 [(set_attr "type" "arith")
5453 (set_attr "mode" "SI")
5454 (set_attr "length" "1")])
5456 (define_insn "sltu_di"
5457 [(set (match_operand:DI 0 "register_operand" "=d")
5458 (ltu:DI (match_operand:DI 1 "register_operand" "d")
5459 (match_operand:DI 2 "arith_operand" "dI")))]
5462 [(set_attr "type" "arith")
5463 (set_attr "mode" "DI")
5464 (set_attr "length" "1")])
5466 (define_expand "sleu"
5467 [(set (match_operand:SI 0 "register_operand" "=d")
5468 (leu:SI (match_dup 1)
5473 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5476 /* set up operands from compare. */
5477 operands[1] = branch_cmp[0];
5478 operands[2] = branch_cmp[1];
5480 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5482 gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
5486 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
5487 operands[2] = force_reg (SImode, operands[2]);
5489 /* fall through and generate default code */
5492 (define_insn "sleu_si_const"
5493 [(set (match_operand:SI 0 "register_operand" "=d")
5494 (leu:SI (match_operand:SI 1 "register_operand" "d")
5495 (match_operand:SI 2 "small_int" "I")))]
5496 "INTVAL (operands[2]) < 32767"
5499 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
5500 return \"sltu\\t%0,%1,%2\";
5502 [(set_attr "type" "arith")
5503 (set_attr "mode" "SI")
5504 (set_attr "length" "1")])
5506 (define_insn "sleu_di_const"
5507 [(set (match_operand:DI 0 "register_operand" "=d")
5508 (leu:DI (match_operand:DI 1 "register_operand" "d")
5509 (match_operand:DI 2 "small_int" "I")))]
5510 "TARGET_64BIT && INTVAL (operands[2]) < 32767"
5513 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
5514 return \"sltu\\t%0,%1,%2\";
5516 [(set_attr "type" "arith")
5517 (set_attr "mode" "DI")
5518 (set_attr "length" "1")])
5520 (define_insn "sleu_si_reg"
5521 [(set (match_operand:SI 0 "register_operand" "=d")
5522 (leu:SI (match_operand:SI 1 "register_operand" "d")
5523 (match_operand:SI 2 "register_operand" "d")))]
5524 "TARGET_DEBUG_C_MODE"
5525 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
5526 [(set_attr "type" "arith")
5527 (set_attr "mode" "SI")
5528 (set_attr "length" "2")])
5531 [(set (match_operand:SI 0 "register_operand" "")
5532 (leu:SI (match_operand:SI 1 "register_operand" "")
5533 (match_operand:SI 2 "register_operand" "")))]
5534 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5536 (ltu:SI (match_dup 2)
5539 (xor:SI (match_dup 0)
5543 (define_insn "sleu_di_reg"
5544 [(set (match_operand:DI 0 "register_operand" "=d")
5545 (leu:DI (match_operand:DI 1 "register_operand" "d")
5546 (match_operand:DI 2 "register_operand" "d")))]
5547 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5548 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
5549 [(set_attr "type" "arith")
5550 (set_attr "mode" "DI")
5551 (set_attr "length" "2")])
5554 [(set (match_operand:DI 0 "register_operand" "")
5555 (leu:DI (match_operand:DI 1 "register_operand" "")
5556 (match_operand:DI 2 "register_operand" "")))]
5557 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5559 (ltu:DI (match_dup 2)
5562 (xor:DI (match_dup 0)
5568 ;; ....................
5570 ;; FLOATING POINT COMPARISONS
5572 ;; ....................
5574 (define_insn "seq_df"
5575 [(set (reg:CC_FP 67)
5576 (eq:CC_FP (match_operand:DF 0 "register_operand" "f")
5577 (match_operand:DF 1 "register_operand" "f")))]
5578 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5582 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5583 xoperands[1] = operands[0];
5584 xoperands[2] = operands[1];
5586 return mips_fill_delay_slot (\"c.eq.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5588 [(set_attr "type" "fcmp")
5589 (set_attr "mode" "FPSW")
5590 (set_attr "length" "1")])
5592 (define_insn "sne_df"
5593 [(set (reg:CC_REV_FP 67)
5594 (ne:CC_REV_FP (match_operand:DF 0 "register_operand" "f")
5595 (match_operand:DF 1 "register_operand" "f")))]
5596 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5600 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5601 xoperands[1] = operands[0];
5602 xoperands[2] = operands[1];
5604 return mips_fill_delay_slot (\"c.eq.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5606 [(set_attr "type" "fcmp")
5607 (set_attr "mode" "FPSW")
5608 (set_attr "length" "1")])
5610 (define_insn "slt_df"
5611 [(set (reg:CC_FP 67)
5612 (lt:CC_FP (match_operand:DF 0 "register_operand" "f")
5613 (match_operand:DF 1 "register_operand" "f")))]
5614 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5618 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5619 xoperands[1] = operands[0];
5620 xoperands[2] = operands[1];
5622 return mips_fill_delay_slot (\"c.lt.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5624 [(set_attr "type" "fcmp")
5625 (set_attr "mode" "FPSW")
5626 (set_attr "length" "1")])
5628 (define_insn "sle_df"
5629 [(set (reg:CC_FP 67)
5630 (le:CC_FP (match_operand:DF 0 "register_operand" "f")
5631 (match_operand:DF 1 "register_operand" "f")))]
5632 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5636 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5637 xoperands[1] = operands[0];
5638 xoperands[2] = operands[1];
5640 return mips_fill_delay_slot (\"c.le.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5642 [(set_attr "type" "fcmp")
5643 (set_attr "mode" "FPSW")
5644 (set_attr "length" "1")])
5646 (define_insn "sgt_df"
5647 [(set (reg:CC_FP 67)
5648 (gt:CC_FP (match_operand:DF 0 "register_operand" "f")
5649 (match_operand:DF 1 "register_operand" "f")))]
5650 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5654 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5655 xoperands[1] = operands[0];
5656 xoperands[2] = operands[1];
5658 return mips_fill_delay_slot (\"c.lt.d\\t%1,%0\", DELAY_FCMP, xoperands, insn);
5660 [(set_attr "type" "fcmp")
5661 (set_attr "mode" "FPSW")
5662 (set_attr "length" "1")])
5664 (define_insn "sge_df"
5665 [(set (reg:CC_FP 67)
5666 (ge:CC_FP (match_operand:DF 0 "register_operand" "f")
5667 (match_operand:DF 1 "register_operand" "f")))]
5668 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5672 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5673 xoperands[1] = operands[0];
5674 xoperands[2] = operands[1];
5676 return mips_fill_delay_slot (\"c.le.d\\t%1,%0\", DELAY_FCMP, xoperands, insn);
5678 [(set_attr "type" "fcmp")
5679 (set_attr "mode" "FPSW")
5680 (set_attr "length" "1")])
5682 (define_insn "seq_sf"
5683 [(set (reg:CC_FP 67)
5684 (eq:CC_FP (match_operand:SF 0 "register_operand" "f")
5685 (match_operand:SF 1 "register_operand" "f")))]
5690 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5691 xoperands[1] = operands[0];
5692 xoperands[2] = operands[1];
5694 return mips_fill_delay_slot (\"c.eq.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5696 [(set_attr "type" "fcmp")
5697 (set_attr "mode" "FPSW")
5698 (set_attr "length" "1")])
5700 (define_insn "sne_sf"
5701 [(set (reg:CC_REV_FP 67)
5702 (ne:CC_REV_FP (match_operand:SF 0 "register_operand" "f")
5703 (match_operand:SF 1 "register_operand" "f")))]
5708 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5709 xoperands[1] = operands[0];
5710 xoperands[2] = operands[1];
5712 return mips_fill_delay_slot (\"c.eq.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5714 [(set_attr "type" "fcmp")
5715 (set_attr "mode" "FPSW")
5716 (set_attr "length" "1")])
5718 (define_insn "slt_sf"
5719 [(set (reg:CC_FP 67)
5720 (lt:CC_FP (match_operand:SF 0 "register_operand" "f")
5721 (match_operand:SF 1 "register_operand" "f")))]
5726 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5727 xoperands[1] = operands[0];
5728 xoperands[2] = operands[1];
5730 return mips_fill_delay_slot (\"c.lt.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5732 [(set_attr "type" "fcmp")
5733 (set_attr "mode" "FPSW")
5734 (set_attr "length" "1")])
5736 (define_insn "sle_sf"
5737 [(set (reg:CC_FP 67)
5738 (le:CC_FP (match_operand:SF 0 "register_operand" "f")
5739 (match_operand:SF 1 "register_operand" "f")))]
5744 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5745 xoperands[1] = operands[0];
5746 xoperands[2] = operands[1];
5748 return mips_fill_delay_slot (\"c.le.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5750 [(set_attr "type" "fcmp")
5751 (set_attr "mode" "FPSW")
5752 (set_attr "length" "1")])
5754 (define_insn "sgt_sf"
5755 [(set (reg:CC_FP 67)
5756 (gt:CC_FP (match_operand:SF 0 "register_operand" "f")
5757 (match_operand:SF 1 "register_operand" "f")))]
5762 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5763 xoperands[1] = operands[0];
5764 xoperands[2] = operands[1];
5766 return mips_fill_delay_slot (\"c.lt.s\\t%1,%0\", DELAY_FCMP, xoperands, insn);
5768 [(set_attr "type" "fcmp")
5769 (set_attr "mode" "FPSW")
5770 (set_attr "length" "1")])
5772 (define_insn "sge_sf"
5773 [(set (reg:CC_FP 67)
5774 (ge:CC_FP (match_operand:SF 0 "register_operand" "f")
5775 (match_operand:SF 1 "register_operand" "f")))]
5780 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5781 xoperands[1] = operands[0];
5782 xoperands[2] = operands[1];
5784 return mips_fill_delay_slot (\"c.le.s\\t%1,%0\", DELAY_FCMP, xoperands, insn);
5786 [(set_attr "type" "fcmp")
5787 (set_attr "mode" "FPSW")
5788 (set_attr "length" "1")])
5792 ;; ....................
5794 ;; UNCONDITIONAL BRANCHES
5796 ;; ....................
5798 ;; Unconditional branches.
5802 (label_ref (match_operand 0 "" "")))]
5806 if (GET_CODE (operands[0]) == REG)
5807 return \"%*j\\t%0\";
5808 /* ??? I don't know why this is necessary. This works around an
5809 assembler problem that appears when a label is defined, then referenced
5810 in a switch table, then used in a `j' instruction. */
5811 else if (mips_abi != ABI_32)
5812 return \"%*b\\t%l0\";
5814 return \"%*j\\t%l0\";
5816 [(set_attr "type" "jump")
5817 (set_attr "mode" "none")
5818 (set_attr "length" "1")])
5820 (define_expand "indirect_jump"
5821 [(set (pc) (match_operand 0 "register_operand" "d"))]
5827 if (operands[0]) /* eliminate unused code warnings */
5830 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
5831 operands[0] = copy_to_mode_reg (Pmode, dest);
5834 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
5836 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
5842 (define_insn "indirect_jump_internal1"
5843 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
5846 [(set_attr "type" "jump")
5847 (set_attr "mode" "none")
5848 (set_attr "length" "1")])
5850 (define_insn "indirect_jump_internal2"
5851 [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
5854 [(set_attr "type" "jump")
5855 (set_attr "mode" "none")
5856 (set_attr "length" "1")])
5858 (define_expand "tablejump"
5860 (match_operand 0 "register_operand" "d"))
5861 (use (label_ref (match_operand 1 "" "")))]
5867 if (operands[0]) /* eliminate unused code warnings */
5869 if (GET_MODE (operands[0]) != Pmode)
5875 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
5877 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
5882 emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
5884 emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
5891 (define_insn "tablejump_internal1"
5893 (match_operand:SI 0 "register_operand" "d"))
5894 (use (label_ref (match_operand 1 "" "")))]
5897 [(set_attr "type" "jump")
5898 (set_attr "mode" "none")
5899 (set_attr "length" "1")])
5901 (define_insn "tablejump_internal2"
5903 (match_operand:DI 0 "register_operand" "d"))
5904 (use (label_ref (match_operand 1 "" "")))]
5907 [(set_attr "type" "jump")
5908 (set_attr "mode" "none")
5909 (set_attr "length" "1")])
5911 (define_expand "tablejump_internal3"
5913 (plus:SI (match_operand:SI 0 "register_operand" "d")
5914 (label_ref:SI (match_operand:SI 1 "" ""))))]
5918 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
5919 ;;; it is not valid.
5921 ;;; ??? The length depends on the ABI. It is two for o32, and one for n32.
5922 ;;; We just use the conservative number here.
5926 (plus:SI (match_operand:SI 0 "register_operand" "d")
5927 (label_ref:SI (match_operand:SI 1 "" ""))))]
5928 "!TARGET_LONG64 && next_active_insn (insn) != 0
5929 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
5930 && PREV_INSN (next_active_insn (insn)) == operands[1]"
5933 /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */
5934 if (mips_abi == ABI_32)
5935 output_asm_insn (\".cpadd\\t%0\", operands);
5936 return \"%*j\\t%0\";
5938 [(set_attr "type" "jump")
5939 (set_attr "mode" "none")
5940 (set_attr "length" "2")])
5942 (define_expand "tablejump_internal4"
5944 (plus:DI (match_operand:DI 0 "register_operand" "d")
5945 (label_ref:DI (match_operand:SI 1 "" ""))))]
5949 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
5950 ;;; it is not valid.
5954 (plus:DI (match_operand:DI 0 "register_operand" "d")
5955 (label_ref:DI (match_operand:SI 1 "" ""))))]
5956 "TARGET_LONG64 && next_active_insn (insn) != 0
5957 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
5958 && PREV_INSN (next_active_insn (insn)) == operands[1]"
5960 [(set_attr "type" "jump")
5961 (set_attr "mode" "none")
5962 (set_attr "length" "1")])
5964 ;; Function return, only allow after optimization, so that we can
5965 ;; eliminate jumps to jumps if no stack space is used.
5967 ;; (define_expand "return"
5968 ;; [(set (pc) (reg:SI 31))]
5969 ;; "simple_epilogue_p ()"
5972 (define_expand "return"
5973 [(parallel [(return)
5974 (use (reg:SI 31))])]
5975 "simple_epilogue_p ()"
5978 (define_insn "return_internal"
5979 [(parallel [(return)
5980 (use (match_operand:SI 0 "register_operand" "d"))])]
5983 [(set_attr "type" "jump")
5984 (set_attr "mode" "none")
5985 (set_attr "length" "1")])
5987 ;; Implement a switch statement when generating embedded PIC code.
5988 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
5990 (define_expand "casesi"
5992 (minus:SI (match_operand:SI 0 "register_operand" "d")
5993 (match_operand:SI 1 "arith_operand" "dI")))
5995 (compare:CC (match_dup 5)
5996 (match_operand:SI 2 "arith_operand" "")))
5998 (if_then_else (gtu (cc0)
6000 (label_ref (match_operand 4 "" ""))
6004 (mem:SI (plus:SI (mult:SI (match_dup 5)
6006 (label_ref (match_operand 3 "" "")))))
6007 (clobber (match_scratch:SI 6 ""))
6008 (clobber (reg:SI 31))])]
6009 "TARGET_EMBEDDED_PIC"
6012 /* We need slightly different code for eight byte table entries. */
6018 rtx reg = gen_reg_rtx (SImode);
6020 /* If the index is too large, go to the default label. */
6021 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
6022 emit_insn (gen_cmpsi (reg, operands[2]));
6023 emit_insn (gen_bgtu (operands[4]));
6025 /* Do the PIC jump. */
6026 emit_insn (gen_casesi_internal (reg, operands[3], gen_reg_rtx (SImode)));
6032 ;; An embedded PIC switch statement looks like this:
6034 ;; sll $reg,$index,2
6036 ;; addu $reg,$reg,$31
6037 ;; lw $reg,$L1-$LS1($reg)
6038 ;; addu $reg,$reg,$31
6045 (define_insn "casesi_internal"
6047 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
6049 (label_ref (match_operand 1 "" "")))))
6050 (clobber (match_operand:SI 2 "register_operand" "d"))
6051 (clobber (reg:SI 31))]
6052 "TARGET_EMBEDDED_PIC"
6055 output_asm_insn (\"%(bal\\t%S1\;sll\\t%0,2\\n%S1:\", operands);
6056 output_asm_insn (\"addu\\t%0,%0,$31%)\", operands);
6057 output_asm_insn (\"lw\\t%0,%1-%S1(%0)\;addu\\t%0,%0,$31\", operands);
6060 [(set_attr "type" "jump")
6061 (set_attr "mode" "none")
6062 (set_attr "length" "6")])
6066 ;; ....................
6068 ;; Function prologue/epilogue
6070 ;; ....................
6073 (define_expand "prologue"
6078 if (mips_isa >= 0) /* avoid unused code warnings */
6080 mips_expand_prologue ();
6085 ;; Block any insns from being moved before this point, since the
6086 ;; profiling call to mcount can use various registers that aren't
6087 ;; saved or used to pass arguments.
6089 (define_insn "blockage"
6090 [(unspec_volatile [(const_int 0)] 0)]
6093 [(set_attr "type" "unknown")
6094 (set_attr "mode" "none")
6095 (set_attr "length" "0")])
6097 ;; At present, don't expand the epilogue, reorg.c will clobber the
6098 ;; return register in compiling gen_lowpart (emit-rtl.c).
6100 ;; (define_expand "epilogue"
6105 ;; if (mips_isa >= 0) /* avoid unused code warnings */
6107 ;; mips_expand_epilogue ();
6112 ;; When generating embedded PIC code we need to get the address of the
6113 ;; current function. This specialized instruction does just that.
6115 (define_insn "get_fnaddr"
6116 [(set (match_operand 0 "register_operand" "=d")
6117 (unspec [(match_operand 1 "" "")] 1))
6118 (clobber (reg:SI 31))]
6119 "TARGET_EMBEDDED_PIC
6120 && GET_CODE (operands[1]) == SYMBOL_REF"
6121 "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
6122 [(set_attr "type" "call")
6123 (set_attr "mode" "none")
6124 (set_attr "length" "4")])
6128 ;; ....................
6132 ;; ....................
6134 ;; calls.c now passes a third argument, make saber happy
6136 (define_expand "call"
6137 [(parallel [(call (match_operand 0 "memory_operand" "m")
6138 (match_operand 1 "" "i"))
6139 (clobber (reg:SI 31))
6140 (use (match_operand 2 "" "")) ;; next_arg_reg
6141 (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
6147 if (operands[0]) /* eliminate unused code warnings */
6149 addr = XEXP (operands[0], 0);
6150 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
6151 || ! call_insn_operand (operands[0], VOIDmode))
6152 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
6154 /* In order to pass small structures by value in registers
6155 compatibly with the MIPS compiler, we need to shift the value
6156 into the high part of the register. Function_arg has encoded
6157 a PARALLEL rtx, holding a vector of adjustments to be made
6158 as the next_arg_reg variable, so we split up the insns,
6159 and emit them separately. */
6161 if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
6163 rtvec adjust = XVEC (operands[2], 0);
6164 int num = GET_NUM_ELEM (adjust);
6167 for (i = 0; i < num; i++)
6168 emit_insn (RTVEC_ELT (adjust, i));
6171 emit_call_insn (gen_call_internal1 (operands[0], operands[1],
6172 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
6177 (define_insn "call_internal1"
6178 [(call (match_operand 0 "call_insn_operand" "m")
6179 (match_operand 1 "" "i"))
6180 (clobber (match_operand:SI 2 "register_operand" "=d"))]
6181 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
6184 register rtx target = XEXP (operands[0], 0);
6186 if (GET_CODE (target) == SYMBOL_REF)
6187 return \"%*jal\\t%0\";
6189 else if (GET_CODE (target) == CONST_INT)
6191 operands[0] = target;
6192 return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
6197 operands[0] = target;
6198 return \"%*jal\\t%2,%0\";
6201 [(set_attr "type" "call")
6202 (set_attr "mode" "none")
6203 (set_attr "length" "1")])
6205 (define_insn "call_internal2"
6206 [(call (match_operand 0 "call_insn_operand" "m")
6207 (match_operand 1 "" "i"))
6208 (clobber (match_operand:SI 2 "register_operand" "=d"))]
6209 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
6212 register rtx target = XEXP (operands[0], 0);
6214 if (GET_CODE (target) == SYMBOL_REF)
6215 return \"jal\\t%0\";
6217 else if (GET_CODE (target) == CONST_INT)
6219 operands[0] = target;
6220 return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
6225 operands[0] = target;
6226 if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
6227 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
6229 return \"jal\\t%2,%0\";
6232 [(set_attr "type" "call")
6233 (set_attr "mode" "none")
6234 (set_attr "length" "2")])
6236 (define_insn "call_internal3a"
6237 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
6238 (match_operand 1 "" "i"))
6239 (clobber (match_operand:SI 2 "register_operand" "=d"))]
6240 "!TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6242 [(set_attr "type" "call")
6243 (set_attr "mode" "none")
6244 (set_attr "length" "1")])
6246 (define_insn "call_internal3b"
6247 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
6248 (match_operand 1 "" "i"))
6249 (clobber (match_operand:SI 2 "register_operand" "=d"))]
6250 "TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6252 [(set_attr "type" "call")
6253 (set_attr "mode" "none")
6254 (set_attr "length" "1")])
6256 (define_insn "call_internal4a"
6257 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
6258 (match_operand 1 "" "i"))
6259 (clobber (match_operand:SI 2 "register_operand" "=d"))]
6260 "!TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6263 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
6264 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
6266 return \"jal\\t%2,%0\";
6268 [(set_attr "type" "call")
6269 (set_attr "mode" "none")
6270 (set_attr "length" "2")])
6272 (define_insn "call_internal4b"
6273 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
6274 (match_operand 1 "" "i"))
6275 (clobber (match_operand:SI 2 "register_operand" "=d"))]
6276 "TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6279 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
6280 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
6282 return \"jal\\t%2,%0\";
6284 [(set_attr "type" "call")
6285 (set_attr "mode" "none")
6286 (set_attr "length" "2")])
6288 ;; calls.c now passes a fourth argument, make saber happy
6290 (define_expand "call_value"
6291 [(parallel [(set (match_operand 0 "register_operand" "=df")
6292 (call (match_operand 1 "memory_operand" "m")
6293 (match_operand 2 "" "i")))
6294 (clobber (reg:SI 31))
6295 (use (match_operand 3 "" ""))])] ;; next_arg_reg
6301 if (operands[0]) /* eliminate unused code warning */
6303 addr = XEXP (operands[1], 0);
6304 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
6305 || ! call_insn_operand (operands[1], VOIDmode))
6306 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
6308 /* In order to pass small structures by value in registers
6309 compatibly with the MIPS compiler, we need to shift the value
6310 into the high part of the register. Function_arg has encoded
6311 a PARALLEL rtx, holding a vector of adjustments to be made
6312 as the next_arg_reg variable, so we split up the insns,
6313 and emit them separately. */
6315 if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
6317 rtvec adjust = XVEC (operands[3], 0);
6318 int num = GET_NUM_ELEM (adjust);
6321 for (i = 0; i < num; i++)
6322 emit_insn (RTVEC_ELT (adjust, i));
6325 /* Handle Irix6 function calls that have multiple non-contiguous
6327 if (GET_CODE (operands[0]) == PARALLEL)
6329 emit_call_insn (gen_call_value_multiple_internal2
6330 (XEXP (XVECEXP (operands[0], 0, 0), 0),
6331 operands[1], operands[2],
6332 XEXP (XVECEXP (operands[0], 0, 1), 0),
6333 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
6337 emit_call_insn (gen_call_value_internal1 (operands[0], operands[1], operands[2],
6338 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
6344 (define_insn "call_value_internal1"
6345 [(set (match_operand 0 "register_operand" "=df")
6346 (call (match_operand 1 "call_insn_operand" "m")
6347 (match_operand 2 "" "i")))
6348 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6349 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
6352 register rtx target = XEXP (operands[1], 0);
6354 if (GET_CODE (target) == SYMBOL_REF)
6355 return \"%*jal\\t%1\";
6357 else if (GET_CODE (target) == CONST_INT)
6359 operands[1] = target;
6360 return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
6365 operands[1] = target;
6366 return \"%*jal\\t%3,%1\";
6369 [(set_attr "type" "call")
6370 (set_attr "mode" "none")
6371 (set_attr "length" "1")])
6373 (define_insn "call_value_internal2"
6374 [(set (match_operand 0 "register_operand" "=df")
6375 (call (match_operand 1 "call_insn_operand" "m")
6376 (match_operand 2 "" "i")))
6377 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6378 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
6381 register rtx target = XEXP (operands[1], 0);
6383 if (GET_CODE (target) == SYMBOL_REF)
6384 return \"jal\\t%1\";
6386 else if (GET_CODE (target) == CONST_INT)
6388 operands[1] = target;
6389 return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
6394 operands[1] = target;
6395 if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
6396 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
6398 return \"jal\\t%3,%1\";
6401 [(set_attr "type" "call")
6402 (set_attr "mode" "none")
6403 (set_attr "length" "2")])
6405 (define_insn "call_value_internal3a"
6406 [(set (match_operand 0 "register_operand" "=df")
6407 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
6408 (match_operand 2 "" "i")))
6409 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6410 "!TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6412 [(set_attr "type" "call")
6413 (set_attr "mode" "none")
6414 (set_attr "length" "1")])
6416 (define_insn "call_value_internal3b"
6417 [(set (match_operand 0 "register_operand" "=df")
6418 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
6419 (match_operand 2 "" "i")))
6420 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6421 "TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6423 [(set_attr "type" "call")
6424 (set_attr "mode" "none")
6425 (set_attr "length" "1")])
6427 (define_insn "call_value_internal4a"
6428 [(set (match_operand 0 "register_operand" "=df")
6429 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
6430 (match_operand 2 "" "i")))
6431 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6432 "!TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6435 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
6436 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
6438 return \"jal\\t%3,%1\";
6440 [(set_attr "type" "call")
6441 (set_attr "mode" "none")
6442 (set_attr "length" "2")])
6444 (define_insn "call_value_internal4b"
6445 [(set (match_operand 0 "register_operand" "=df")
6446 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
6447 (match_operand 2 "" "i")))
6448 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6449 "TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6452 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
6453 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
6455 return \"jal\\t%3,%1\";
6457 [(set_attr "type" "call")
6458 (set_attr "mode" "none")
6459 (set_attr "length" "2")])
6461 ;; ??? May eventually need all 6 versions of the call patterns with multiple
6464 (define_insn "call_value_multiple_internal2"
6465 [(set (match_operand 0 "register_operand" "=df")
6466 (call (match_operand 1 "call_insn_operand" "m")
6467 (match_operand 2 "" "i")))
6468 (set (match_operand 3 "register_operand" "=df")
6471 (clobber (match_operand:SI 4 "register_operand" "=d"))]
6472 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
6475 register rtx target = XEXP (operands[1], 0);
6477 if (GET_CODE (target) == SYMBOL_REF)
6478 return \"jal\\t%1\";
6480 else if (GET_CODE (target) == CONST_INT)
6482 operands[1] = target;
6483 return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
6488 operands[1] = target;
6489 if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
6490 return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
6492 return \"jal\\t%4,%1\";
6495 [(set_attr "type" "call")
6496 (set_attr "mode" "none")
6497 (set_attr "length" "2")])
6500 ;; Call subroutine returning any type.
6502 (define_expand "untyped_call"
6503 [(parallel [(call (match_operand 0 "" "")
6505 (match_operand 1 "" "")
6506 (match_operand 2 "" "")])]
6510 if (operands[0]) /* silence statement not reached warnings */
6514 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
6516 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6518 rtx set = XVECEXP (operands[2], 0, i);
6519 emit_move_insn (SET_DEST (set), SET_SRC (set));
6522 emit_insn (gen_blockage ());
6528 ;; ....................
6532 ;; ....................
6539 [(set_attr "type" "nop")
6540 (set_attr "mode" "none")
6541 (set_attr "length" "1")])
6543 (define_expand "probe"
6549 operands[0] = gen_reg_rtx (SImode);
6550 operands[1] = gen_rtx (MEM, SImode, stack_pointer_rtx);
6551 MEM_VOLATILE_P (operands[1]) = TRUE;
6553 /* fall through and generate default code */
6557 ;; MIPS4 Conditional move instructions.
6560 [(set (match_operand:SI 0 "register_operand" "=d,d")
6562 (match_operator 4 "equality_op"
6563 [(match_operand:SI 1 "register_operand" "d,d")
6565 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
6566 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
6571 [(set_attr "type" "move")
6572 (set_attr "mode" "SI")])
6575 [(set (match_operand:SI 0 "register_operand" "=d,d")
6577 (match_operator 4 "equality_op"
6578 [(match_operand:DI 1 "register_operand" "d,d")
6580 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
6581 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
6586 [(set_attr "type" "move")
6587 (set_attr "mode" "SI")])
6590 [(set (match_operand:SI 0 "register_operand" "=d,d")
6592 (match_operator 3 "equality_op" [(reg:CC_FP 67) (const_int 0)])
6593 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
6594 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
6597 mov%T3\\t%0,%z1,$fcc0
6598 mov%t3\\t%0,%z2,$fcc0"
6599 [(set_attr "type" "move")
6600 (set_attr "mode" "SI")])
6603 [(set (match_operand:DI 0 "register_operand" "=d,d")
6605 (match_operator 4 "equality_op"
6606 [(match_operand:SI 1 "register_operand" "d,d")
6608 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
6609 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
6614 [(set_attr "type" "move")
6615 (set_attr "mode" "DI")])
6618 [(set (match_operand:DI 0 "register_operand" "=d,d")
6620 (match_operator 4 "equality_op"
6621 [(match_operand:DI 1 "register_operand" "d,d")
6623 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
6624 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
6629 [(set_attr "type" "move")
6630 (set_attr "mode" "DI")])
6633 [(set (match_operand:DI 0 "register_operand" "=d,d")
6635 (match_operator 3 "equality_op" [(reg:CC_FP 67) (const_int 0)])
6636 (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
6637 (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
6640 mov%T3\\t%0,%z1,$fcc0
6641 mov%t3\\t%0,%z2,$fcc0"
6642 [(set_attr "type" "move")
6643 (set_attr "mode" "DI")])
6646 [(set (match_operand:SF 0 "register_operand" "=f,f")
6648 (match_operator 4 "equality_op"
6649 [(match_operand:SI 1 "register_operand" "d,d")
6651 (match_operand:SF 2 "register_operand" "f,0")
6652 (match_operand:SF 3 "register_operand" "0,f")))]
6653 "mips_isa >= 4 && TARGET_HARD_FLOAT"
6656 mov%b4.s\\t%0,%3,%1"
6657 [(set_attr "type" "move")
6658 (set_attr "mode" "SF")])
6661 [(set (match_operand:SF 0 "register_operand" "=f,f")
6663 (match_operator 3 "equality_op" [(reg:CC_FP 67) (const_int 0)])
6664 (match_operand:SF 1 "register_operand" "f,0")
6665 (match_operand:SF 2 "register_operand" "0,f")))]
6666 "mips_isa >= 4 && TARGET_HARD_FLOAT"
6668 mov%T3.s\\t%0,%1,$fcc0
6669 mov%t3.s\\t%0,%2,$fcc0"
6670 [(set_attr "type" "move")
6671 (set_attr "mode" "SF")])
6674 [(set (match_operand:DF 0 "register_operand" "=f,f")
6676 (match_operator 4 "equality_op"
6677 [(match_operand:SI 1 "register_operand" "d,d")
6679 (match_operand:DF 2 "register_operand" "f,0")
6680 (match_operand:DF 3 "register_operand" "0,f")))]
6681 "mips_isa >= 4 && TARGET_HARD_FLOAT"
6684 mov%b4.d\\t%0,%3,%1"
6685 [(set_attr "type" "move")
6686 (set_attr "mode" "DF")])
6689 [(set (match_operand:DF 0 "register_operand" "=f,f")
6691 (match_operator 3 "equality_op" [(reg:CC_FP 67) (const_int 0)])
6692 (match_operand:DF 1 "register_operand" "f,0")
6693 (match_operand:DF 2 "register_operand" "0,f")))]
6694 "mips_isa >= 4 && TARGET_HARD_FLOAT"
6696 mov%T3.d\\t%0,%1,$fcc0
6697 mov%t3.d\\t%0,%2,$fcc0"
6698 [(set_attr "type" "move")
6699 (set_attr "mode" "DF")])
6701 ;; These are the main define_expand's used to make conditional moves.
6703 (define_expand "movsicc"
6704 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
6705 (set (match_operand:SI 0 "register_operand" "")
6706 (if_then_else:SI (match_dup 5)
6707 (match_operand:SI 2 "reg_or_0_operand" "")
6708 (match_operand:SI 3 "reg_or_0_operand" "")))]
6712 rtx op0 = branch_cmp[0];
6713 rtx op1 = branch_cmp[1];
6714 enum machine_mode mode = GET_MODE (branch_cmp[0]);
6715 enum rtx_code compare_code = GET_CODE (operands[1]);
6716 enum rtx_code move_code = NE;
6718 if (GET_MODE_CLASS (mode) != MODE_FLOAT)
6720 switch (compare_code)
6737 op0 = force_reg (mode, branch_cmp[1]);
6738 op1 = branch_cmp[0];
6742 op0 = force_reg (mode, branch_cmp[1]);
6743 op1 = branch_cmp[0];
6754 op0 = force_reg (mode, branch_cmp[1]);
6755 op1 = branch_cmp[0];
6759 op0 = force_reg (mode, branch_cmp[1]);
6760 op1 = branch_cmp[0];
6769 if (compare_code == NE)
6771 /* ??? Perhaps we need to use CC_FP_REVmode here? */
6777 if (mode == SImode || mode == DImode)
6779 operands[1] = gen_rtx (compare_code, mode, op0, op1);
6780 operands[4] = gen_reg_rtx (mode);
6782 else if (mode == SFmode || mode == DFmode)
6784 operands[1] = gen_rtx (compare_code, CC_FPmode, op0, op1);
6785 operands[4] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
6788 operands[5] = gen_rtx (move_code, VOIDmode, operands[4],
6789 CONST0_RTX (SImode));
6792 ;; ??? Need movdicc, movsfcc, and movdfcc patterns. They should be
6793 ;; very similar to the above movsicc pattern.