|
|
1.1 root 1: ;; Mips.md Machine Description for MIPS based processors
2: ;; Contributed by A. Lichnewsky, [email protected]
3: ;; Changes by Michael Meissner, [email protected]
4: ;; Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
5:
6: ;; This file is part of GNU CC.
7:
8: ;; GNU CC is free software; you can redistribute it and/or modify
9: ;; it under the terms of the GNU General Public License as published by
10: ;; the Free Software Foundation; either version 2, or (at your option)
11: ;; any later version.
12:
13: ;; GNU CC is distributed in the hope that it will be useful,
14: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16: ;; GNU General Public License for more details.
17:
18: ;; You should have received a copy of the GNU General Public License
19: ;; along with GNU CC; see the file COPYING. If not, write to
20: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21:
22:
23:
24: ;; ....................
25: ;;
26: ;; Attributes
27: ;;
28: ;; ....................
29:
30: ;; Classification of each insn.
31: ;; branch conditional branch
32: ;; jump unconditional jump
33: ;; call unconditional call
34: ;; load load instruction(s)
35: ;; store store instruction(s)
36: ;; move data movement within same register set
37: ;; xfer transfer to/from coprocessor
38: ;; hilo transfer of hi/lo registers
39: ;; arith integer arithmetic instruction
40: ;; darith double precision integer arithmetic instructions
41: ;; imul integer multiply
42: ;; idiv integer divide
43: ;; icmp integer compare
44: ;; fadd floating point add/subtract
45: ;; fmul floating point multiply
46: ;; fdiv floating point divide
47: ;; fabs floating point absolute value
48: ;; fneg floating point negation
49: ;; fcmp floating point compare
50: ;; fcvt floating point convert
51: ;; fsqrt floating point square root
52: ;; multi multiword sequence (or user asm statements)
53: ;; nop no operation
54: ;; pic OSF/rose half pic load
55:
56: (define_attr "type"
57: "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,idiv,icmp,fadd,fmul,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,multi,nop,pic"
58: (const_string "unknown"))
59:
60: ;; Main data type used by the insn
1.1.1.3 ! root 61: (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
1.1 root 62:
63: ;; # instructions (4 bytes each)
64: (define_attr "length" "" (const_int 1))
65:
1.1.1.2 root 66: ;; whether or not an instruction has a mandatory delay slot
1.1 root 67: (define_attr "dslot" "no,yes"
1.1.1.3 ! root 68: (if_then_else (eq_attr "type" "branch,jump,call,load,xfer,hilo,fcmp,pic")
1.1 root 69: (const_string "yes")
70: (const_string "no")))
71:
1.1.1.3 ! root 72: ;; Attribute describing the processor. This attribute must match exactly
! 73: ;; with the processor_type enumeration in mips.h.
! 74:
1.1 root 75: ;; Attribute describing the processor
1.1.1.3 ! root 76: ;; (define_attr "cpu" "default,r3000,r6000,r4000"
! 77: ;; (const
! 78: ;; (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000")) (const_string "r3000")
! 79: ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000")) (const_string "r4000")
! 80: ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000")) (const_string "r6000")]
! 81: ;; (const_string "default"))))
! 82:
! 83: (define_attr "cpu" "default,r3000,r6000,r4000"
! 84: (const (symbol_ref "mips_cpu_attr")))
1.1 root 85:
86: ;; Attribute defining whether or not we can use the branch-likely instructions
87: ;; (MIPS ISA level 2)
88:
89: (define_attr "branch_likely" "no,yes"
1.1.1.2 root 90: (const
1.1 root 91: (if_then_else (ge (symbol_ref "mips_isa") (const_int 2))
92: (const_string "yes")
1.1.1.2 root 93: (const_string "no"))))
1.1 root 94:
95:
96: ;; Describe a user's asm statement.
97: (define_asm_attributes
98: [(set_attr "type" "multi")])
99:
100:
101:
102: ;; .........................
103: ;;
104: ;; Delay slots, can't describe load/fcmp/xfer delay slots here
105: ;;
106: ;; .........................
107:
108: (define_delay (eq_attr "type" "branch")
109: [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
110: (nil)
1.1.1.3 ! root 111: (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "1")))])
1.1 root 112:
113: (define_delay (eq_attr "type" "call,jump")
114: [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
115: (nil)
116: (nil)])
117:
118:
119:
120: ;; .........................
121: ;;
122: ;; Functional units
123: ;;
124: ;; .........................
125:
126: ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
127: ; TEST READY-DELAY BUSY-DELAY [CONFLICT-LIST])
128:
129: ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
1.1.1.2 root 130:
131: (define_function_unit "memory" 1 0
132: (and (eq_attr "type" "load,pic") (eq_attr "cpu" "!r3000"))
133: 3 0)
134:
135: (define_function_unit "memory" 1 0
136: (and (eq_attr "type" "load,pic") (eq_attr "cpu" "r3000"))
137: 2 0)
138:
1.1.1.3 ! root 139: (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
1.1.1.2 root 140:
1.1.1.3 ! root 141: (define_function_unit "addr" 1 0 (eq_attr "type" "fcmp") 2 0)
! 142:
! 143: (define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)
! 144: (define_function_unit "memory" 1 0 (eq_attr "type" "hilo") 3 0)
1.1.1.2 root 145:
146: (define_function_unit "imuldiv" 1 1
147: (and (eq_attr "type" "imul") (eq_attr "cpu" "!r3000,r4000"))
148: 17 34)
149:
150: (define_function_unit "imuldiv" 1 1
151: (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000"))
152: 12 24)
153:
154: (define_function_unit "imuldiv" 1 1
155: (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000"))
156: 10 20)
157:
158: (define_function_unit "imuldiv" 1 1
159: (and (eq_attr "type" "idiv") (eq_attr "cpu" "!r3000,r4000"))
160: 38 76)
161:
162: (define_function_unit "imuldiv" 1 1
163: (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000"))
164: 35 70)
165:
166: (define_function_unit "imuldiv" 1 1
167: (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
168: 69 138)
169:
170: (define_function_unit "adder" 1 1
171: (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r6000"))
172: 4 8)
173:
174: (define_function_unit "adder" 1 1
175: (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000"))
176: 2 4)
177:
178: (define_function_unit "adder" 1 1
179: (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
180: 3 6)
181:
1.1.1.3 ! root 182: (define_function_unit "adder" 1 1
1.1.1.2 root 183: (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "!r3000"))
184: 2 4)
185:
1.1.1.3 ! root 186: (define_function_unit "adder" 1 1
1.1.1.2 root 187: (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000"))
188: 1 2)
189:
190: (define_function_unit "mult" 1 1
191: (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000")))
192: 7 14)
193:
194: (define_function_unit "mult" 1 1
195: (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000")))
196: 4 8)
197:
198: (define_function_unit "mult" 1 1
199: (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
200: 5 10)
201:
202: (define_function_unit "mult" 1 1
203: (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000")))
204: 8 16)
205:
206: (define_function_unit "mult" 1 1
207: (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000")))
208: 5 10)
209:
210: (define_function_unit "mult" 1 1
211: (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
212: 6 12)
213:
214: (define_function_unit "divide" 1 1
215: (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000")))
216: 23 46)
217:
218: (define_function_unit "divide" 1 1
219: (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000")))
220: 12 24)
221:
222: (define_function_unit "divide" 1 1
223: (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
224: 15 30)
225:
226: (define_function_unit "divide" 1 1
227: (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000")))
228: 36 72)
229:
230: (define_function_unit "divide" 1 1
231: (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000")))
232: 19 34)
233:
234: (define_function_unit "divide" 1 1
235: (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
236: 16 32)
237:
1.1.1.3 ! root 238: (define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 108)
! 239: (define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 224)
! 240:
! 241:
! 242: ;; The following functional units do not use the cpu type, and use
! 243: ;; much less memory in genattrtab.c.
! 244:
! 245: ;; (define_function_unit "memory" 1 0 (eq_attr "type" "load,pic") 3 0)
! 246: ;; (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
! 247: ;;
! 248: ;; (define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0)
! 249: ;;
! 250: ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0)
! 251: ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0)
! 252: ;;
! 253: ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "imul") 17 34)
! 254: ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "idiv") 38 76)
! 255: ;;
! 256: ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fadd") 4 8)
! 257: ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fabs,fneg") 2 4)
! 258: ;;
! 259: ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF")) 7 14)
! 260: ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF")) 8 16)
! 261: ;;
! 262: ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF")) 23 46)
! 263: ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF")) 36 72)
! 264: ;;
! 265: ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 108)
! 266: ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 224)
1.1 root 267:
268:
269: ;;
270: ;; ....................
271: ;;
272: ;; ADDITION
273: ;;
274: ;; ....................
275: ;;
276:
277: (define_insn "adddf3"
278: [(set (match_operand:DF 0 "register_operand" "=f")
279: (plus:DF (match_operand:DF 1 "register_operand" "f")
280: (match_operand:DF 2 "register_operand" "f")))]
281: "TARGET_HARD_FLOAT"
282: "add.d\\t%0,%1,%2"
283: [(set_attr "type" "fadd")
284: (set_attr "mode" "DF")
285: (set_attr "length" "1")])
286:
287: (define_insn "addsf3"
288: [(set (match_operand:SF 0 "register_operand" "=f")
289: (plus:SF (match_operand:SF 1 "register_operand" "f")
290: (match_operand:SF 2 "register_operand" "f")))]
291: "TARGET_HARD_FLOAT"
292: "add.s\\t%0,%1,%2"
293: [(set_attr "type" "fadd")
294: (set_attr "mode" "SF")
295: (set_attr "length" "1")])
296:
297: (define_insn "addsi3"
298: [(set (match_operand:SI 0 "register_operand" "=d")
299: (plus:SI (match_operand:SI 1 "arith_operand" "%d")
300: (match_operand:SI 2 "arith_operand" "dI")))]
301: ""
302: "*
303: {
304: return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
305: ? \"subu\\t%0,%1,%n2\"
306: : \"addu\\t%0,%1,%2\";
307: }"
308: [(set_attr "type" "arith")
309: (set_attr "mode" "SI")
310: (set_attr "length" "1")])
311:
312: (define_expand "adddi3"
313: [(parallel [(set (match_operand:DI 0 "register_operand" "")
314: (plus:DI (match_operand:DI 1 "register_operand" "")
315: (match_operand:DI 2 "arith_operand" "")))
316: (clobber (match_dup 3))])]
317: "!TARGET_DEBUG_G_MODE"
1.1.1.3 ! root 318: "
! 319: {
! 320: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
! 321: operands[2] = force_reg (SImode, operands[2]);
! 322:
! 323: operands[3] = gen_reg_rtx (SImode);
! 324: }")
1.1 root 325:
326: (define_insn "adddi3_internal_1"
327: [(set (match_operand:DI 0 "register_operand" "=d,&d")
328: (plus:DI (match_operand:DI 1 "register_operand" "0,d")
329: (match_operand:DI 2 "register_operand" "d,d")))
330: (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
331: "!TARGET_DEBUG_G_MODE"
332: "*
333: {
334: return (REGNO (operands[0]) == REGNO (operands[1])
335: && REGNO (operands[0]) == REGNO (operands[2]))
336: ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
337: : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
338: }"
1.1.1.3 ! root 339: [(set_attr "type" "darith")
! 340: (set_attr "mode" "DI")
! 341: (set_attr "length" "4")])
1.1 root 342:
343: (define_split
344: [(set (match_operand:DI 0 "register_operand" "")
345: (plus:DI (match_operand:DI 1 "register_operand" "")
346: (match_operand:DI 2 "register_operand" "")))
347: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 348: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 349: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
350: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
351: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
352: && (REGNO (operands[0]) != REGNO (operands[1])
353: || REGNO (operands[0]) != REGNO (operands[2]))"
354:
355: [(set (subreg:SI (match_dup 0) 0)
356: (plus:SI (subreg:SI (match_dup 1) 0)
357: (subreg:SI (match_dup 2) 0)))
358:
359: (set (match_dup 3)
1.1.1.3 ! root 360: (ltu:SI (subreg:SI (match_dup 0) 0)
1.1 root 361: (subreg:SI (match_dup 2) 0)))
362:
363: (set (subreg:SI (match_dup 0) 1)
364: (plus:SI (subreg:SI (match_dup 1) 1)
365: (subreg:SI (match_dup 2) 1)))
366:
367: (set (subreg:SI (match_dup 0) 1)
368: (plus:SI (subreg:SI (match_dup 0) 1)
369: (match_dup 3)))]
370: "")
371:
372: (define_split
373: [(set (match_operand:DI 0 "register_operand" "")
374: (plus:DI (match_operand:DI 1 "register_operand" "")
375: (match_operand:DI 2 "register_operand" "")))
376: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 377: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 378: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
379: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
380: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
381: && (REGNO (operands[0]) != REGNO (operands[1])
382: || REGNO (operands[0]) != REGNO (operands[2]))"
383:
384: [(set (subreg:SI (match_dup 0) 1)
385: (plus:SI (subreg:SI (match_dup 1) 1)
386: (subreg:SI (match_dup 2) 1)))
387:
388: (set (match_dup 3)
1.1.1.3 ! root 389: (ltu:SI (subreg:SI (match_dup 0) 1)
1.1 root 390: (subreg:SI (match_dup 2) 1)))
391:
392: (set (subreg:SI (match_dup 0) 0)
393: (plus:SI (subreg:SI (match_dup 1) 0)
394: (subreg:SI (match_dup 2) 0)))
395:
396: (set (subreg:SI (match_dup 0) 0)
397: (plus:SI (subreg:SI (match_dup 0) 0)
398: (match_dup 3)))]
399: "")
400:
401: (define_insn "adddi3_internal_2"
402: [(set (match_operand:DI 0 "register_operand" "=d,d,d")
403: (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
404: (match_operand:DI 2 "small_int" "P,J,N")))
405: (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
406: "!TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768"
407: "@
408: addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
409: move\\t%L0,%L1\;move\\t%M0,%M1
410: subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
1.1.1.3 ! root 411: [(set_attr "type" "darith")
! 412: (set_attr "mode" "DI")
1.1 root 413: (set_attr "length" "3,2,4")])
414:
415: (define_split
416: [(set (match_operand:DI 0 "register_operand" "")
417: (plus:DI (match_operand:DI 1 "register_operand" "")
418: (match_operand:DI 2 "small_int" "")))
419: (clobber (match_operand:SI 3 "register_operand" "=d"))]
1.1.1.3 ! root 420: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 421: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
422: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
423: && INTVAL (operands[2]) > 0"
424:
425: [(set (subreg:SI (match_dup 0) 0)
426: (plus:SI (subreg:SI (match_dup 1) 0)
427: (match_dup 2)))
428:
429: (set (match_dup 3)
1.1.1.3 ! root 430: (ltu:SI (subreg:SI (match_dup 0) 0)
1.1 root 431: (match_dup 2)))
432:
433: (set (subreg:SI (match_dup 0) 1)
434: (plus:SI (subreg:SI (match_dup 1) 1)
435: (match_dup 3)))]
436: "")
437:
438: (define_split
439: [(set (match_operand:DI 0 "register_operand" "")
440: (plus:DI (match_operand:DI 1 "register_operand" "")
441: (match_operand:DI 2 "small_int" "")))
442: (clobber (match_operand:SI 3 "register_operand" "=d"))]
1.1.1.3 ! root 443: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 444: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
445: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
446: && INTVAL (operands[2]) > 0"
447:
448: [(set (subreg:SI (match_dup 0) 1)
449: (plus:SI (subreg:SI (match_dup 1) 1)
450: (match_dup 2)))
451:
452: (set (match_dup 3)
1.1.1.3 ! root 453: (ltu:SI (subreg:SI (match_dup 0) 1)
1.1 root 454: (match_dup 2)))
455:
456: (set (subreg:SI (match_dup 0) 0)
457: (plus:SI (subreg:SI (match_dup 1) 0)
458: (match_dup 3)))]
459: "")
460:
461: ;;
462: ;; ....................
463: ;;
464: ;; SUBTRACTION
465: ;;
466: ;; ....................
467: ;;
468:
469: (define_insn "subdf3"
470: [(set (match_operand:DF 0 "register_operand" "=f")
471: (minus:DF (match_operand:DF 1 "register_operand" "f")
472: (match_operand:DF 2 "register_operand" "f")))]
473: "TARGET_HARD_FLOAT"
474: "sub.d\\t%0,%1,%2"
475: [(set_attr "type" "fadd")
476: (set_attr "mode" "DF")
477: (set_attr "length" "1")])
478:
479: (define_insn "subsf3"
480: [(set (match_operand:SF 0 "register_operand" "=f")
481: (minus:SF (match_operand:SF 1 "register_operand" "f")
482: (match_operand:SF 2 "register_operand" "f")))]
483: "TARGET_HARD_FLOAT"
484: "sub.s\\t%0,%1,%2"
485: [(set_attr "type" "fadd")
486: (set_attr "mode" "SF")
487: (set_attr "length" "1")])
488:
489: (define_insn "subsi3"
490: [(set (match_operand:SI 0 "register_operand" "=d")
491: (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
492: (match_operand:SI 2 "arith_operand" "dI")))]
493: ""
494: "*
495: {
496: return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
497: ? \"addu\\t%0,%z1,%n2\"
498: : \"subu\\t%0,%z1,%2\";
499: }"
500: [(set_attr "type" "arith")
501: (set_attr "mode" "SI")
502: (set_attr "length" "1")])
503:
504: (define_expand "subdi3"
505: [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
506: (minus:DI (match_operand:DI 1 "register_operand" "d")
507: (match_operand:DI 2 "register_operand" "d")))
508: (clobber (match_dup 3))])]
509: "!TARGET_DEBUG_G_MODE"
510: "operands[3] = gen_reg_rtx (SImode);")
511:
512: (define_insn "subdi3_internal"
513: [(set (match_operand:DI 0 "register_operand" "=d")
514: (minus:DI (match_operand:DI 1 "register_operand" "d")
515: (match_operand:DI 2 "register_operand" "d")))
516: (clobber (match_operand:SI 3 "register_operand" "=d"))]
517: "!TARGET_DEBUG_G_MODE"
518: "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
519: [(set_attr "type" "darith")
520: (set_attr "mode" "DI")
521: (set_attr "length" "4")])
522:
523: (define_split
524: [(set (match_operand:DI 0 "register_operand" "")
525: (minus:DI (match_operand:DI 1 "register_operand" "")
526: (match_operand:DI 2 "register_operand" "")))
527: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 528: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 529: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
530: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
531: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
532:
533: [(set (match_dup 3)
1.1.1.3 ! root 534: (ltu:SI (subreg:SI (match_dup 1) 0)
1.1.1.2 root 535: (subreg:SI (match_dup 2) 0)))
1.1 root 536:
537: (set (subreg:SI (match_dup 0) 0)
538: (minus:SI (subreg:SI (match_dup 1) 0)
539: (subreg:SI (match_dup 2) 0)))
540:
541: (set (subreg:SI (match_dup 0) 1)
542: (minus:SI (subreg:SI (match_dup 1) 1)
543: (subreg:SI (match_dup 2) 1)))
544:
545: (set (subreg:SI (match_dup 0) 1)
546: (minus:SI (subreg:SI (match_dup 0) 1)
547: (match_dup 3)))]
548: "")
549:
550: (define_split
551: [(set (match_operand:DI 0 "register_operand" "")
552: (minus:DI (match_operand:DI 1 "register_operand" "")
553: (match_operand:DI 2 "register_operand" "")))
554: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 555: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 556: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
557: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
558: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
559:
560: [(set (match_dup 3)
1.1.1.3 ! root 561: (ltu:SI (subreg:SI (match_dup 1) 1)
1.1.1.2 root 562: (subreg:SI (match_dup 2) 1)))
1.1 root 563:
564: (set (subreg:SI (match_dup 0) 1)
565: (minus:SI (subreg:SI (match_dup 1) 1)
566: (subreg:SI (match_dup 2) 1)))
567:
568: (set (subreg:SI (match_dup 0) 0)
569: (minus:SI (subreg:SI (match_dup 1) 0)
570: (subreg:SI (match_dup 2) 0)))
571:
572: (set (subreg:SI (match_dup 0) 0)
573: (minus:SI (subreg:SI (match_dup 0) 0)
574: (match_dup 3)))]
575: "")
576:
577: (define_insn "subdi3_internal_2"
578: [(set (match_operand:DI 0 "register_operand" "=d,d,d")
579: (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
580: (match_operand:DI 2 "small_int" "P,J,N")))
581: (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
582: "!TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768"
583: "@
584: sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
585: move\\t%L0,%L1\;move\\t%M0,%M1
586: sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
1.1.1.3 ! root 587: [(set_attr "type" "darith")
! 588: (set_attr "mode" "DI")
1.1 root 589: (set_attr "length" "3,2,4")])
590:
591: (define_split
592: [(set (match_operand:DI 0 "register_operand" "")
593: (minus:DI (match_operand:DI 1 "register_operand" "")
594: (match_operand:DI 2 "small_int" "")))
595: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 596: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 597: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
598: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
599: && INTVAL (operands[2]) > 0"
600:
601: [(set (match_dup 3)
1.1.1.3 ! root 602: (ltu:SI (subreg:SI (match_dup 1) 0)
1.1 root 603: (match_dup 2)))
604:
605: (set (subreg:SI (match_dup 0) 0)
606: (minus:SI (subreg:SI (match_dup 1) 0)
607: (match_dup 2)))
608:
609: (set (subreg:SI (match_dup 0) 1)
610: (minus:SI (subreg:SI (match_dup 1) 1)
611: (match_dup 3)))]
612: "")
613:
614: (define_split
615: [(set (match_operand:DI 0 "register_operand" "")
616: (minus:DI (match_operand:DI 1 "register_operand" "")
617: (match_operand:DI 2 "small_int" "")))
618: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 619: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 620: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
621: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
622: && INTVAL (operands[2]) > 0"
623:
624: [(set (match_dup 3)
1.1.1.3 ! root 625: (ltu:SI (subreg:SI (match_dup 1) 1)
1.1 root 626: (match_dup 2)))
627:
628: (set (subreg:SI (match_dup 0) 1)
629: (minus:SI (subreg:SI (match_dup 1) 1)
630: (match_dup 2)))
631:
632: (set (subreg:SI (match_dup 0) 0)
633: (minus:SI (subreg:SI (match_dup 1) 0)
634: (match_dup 3)))]
635: "")
636:
637:
638: ;;
639: ;; ....................
640: ;;
641: ;; MULTIPLICATION
642: ;;
643: ;; ....................
644: ;;
645:
646: (define_insn "muldf3"
647: [(set (match_operand:DF 0 "register_operand" "=f")
648: (mult:DF (match_operand:DF 1 "register_operand" "f")
649: (match_operand:DF 2 "register_operand" "f")))]
650: "TARGET_HARD_FLOAT"
651: "mul.d\\t%0,%1,%2"
652: [(set_attr "type" "fmul")
653: (set_attr "mode" "DF")
654: (set_attr "length" "1")])
655:
656: (define_insn "mulsf3"
657: [(set (match_operand:SF 0 "register_operand" "=f")
658: (mult:SF (match_operand:SF 1 "register_operand" "f")
659: (match_operand:SF 2 "register_operand" "f")))]
660: "TARGET_HARD_FLOAT"
661: "mul.s\\t%0,%1,%2"
662: [(set_attr "type" "fmul")
663: (set_attr "mode" "SF")
664: (set_attr "length" "1")])
665:
666: (define_insn "mulsi3"
667: [(set (match_operand:SI 0 "register_operand" "=d")
668: (mult:SI (match_operand:SI 1 "register_operand" "d")
669: (match_operand:SI 2 "register_operand" "d")))
670: (clobber (reg:SI 64))
671: (clobber (reg:SI 65))]
672: ""
673: "*
674: {
675: rtx xoperands[10];
676:
677: xoperands[0] = operands[0];
678: xoperands[1] = gen_rtx (REG, SImode, LO_REGNUM);
679:
680: output_asm_insn (\"mult\\t%1,%2\", operands);
681: output_asm_insn (mips_move_1word (xoperands, insn), xoperands);
682: return \"\";
683: }"
684: [(set_attr "type" "imul")
685: (set_attr "mode" "SI")
686: (set_attr "length" "3")]) ;; mult + mflo + delay
687:
688: (define_split
689: [(set (match_operand:SI 0 "register_operand" "")
690: (mult:SI (match_operand:SI 1 "register_operand" "")
691: (match_operand:SI 2 "register_operand" "")))
692: (clobber (reg:SI 64))
693: (clobber (reg:SI 65))]
1.1.1.3 ! root 694: "!TARGET_DEBUG_D_MODE"
1.1 root 695: [(parallel [(set (reg:SI 65) ;; low register
696: (mult:SI (match_dup 1)
697: (match_dup 2)))
698: (clobber (reg:SI 64))])
699: (set (match_dup 0)
700: (reg:SI 65))]
701: "")
702:
703: (define_insn "mulsi3_internal"
704: [(set (reg:SI 65) ;; low register
705: (mult:SI (match_operand:SI 0 "register_operand" "d")
706: (match_operand:SI 1 "register_operand" "d")))
707: (clobber (reg:SI 64))]
708: ""
709: "mult\\t%0,%1"
710: [(set_attr "type" "imul")
711: (set_attr "mode" "SI")
712: (set_attr "length" "1")])
713:
714: (define_insn "mulsidi3"
715: [(set (match_operand:DI 0 "register_operand" "=d")
716: (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
717: (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
718: (clobber (reg:DI 64))]
719: ""
720: "*
721: {
722: rtx xoperands[10];
723:
724: xoperands[0] = operands[0];
725: xoperands[1] = gen_rtx (REG, DImode, MD_REG_FIRST);
726:
727: output_asm_insn (\"mult\\t%1,%2\", operands);
728: output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
729: return \"\";
730: }"
731: [(set_attr "type" "imul")
732: (set_attr "mode" "SI")
733: (set_attr "length" "4")]) ;; mult + mflo + mfhi + delay
734:
735: (define_insn "umulsidi3"
736: [(set (match_operand:DI 0 "register_operand" "=d")
737: (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
738: (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
739: (clobber (reg:DI 64))]
740: ""
741: "*
742: {
743: rtx xoperands[10];
744:
745: xoperands[0] = operands[0];
746: xoperands[1] = gen_rtx (REG, DImode, MD_REG_FIRST);
747:
748: output_asm_insn (\"multu\\t%1,%2\", operands);
749: output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
750: return \"\";
751: }"
752: [(set_attr "type" "imul")
753: (set_attr "mode" "SI")
754: (set_attr "length" "4")]) ;; mult + mflo + mfhi + delay
755:
756:
757: ;;
758: ;; ....................
759: ;;
760: ;; DIVISION and REMAINDER
761: ;;
762: ;; ....................
763: ;;
764:
765: (define_insn "divdf3"
766: [(set (match_operand:DF 0 "register_operand" "=f")
767: (div:DF (match_operand:DF 1 "register_operand" "f")
768: (match_operand:DF 2 "register_operand" "f")))]
769: "TARGET_HARD_FLOAT"
770: "div.d\\t%0,%1,%2"
771: [(set_attr "type" "fdiv")
772: (set_attr "mode" "DF")
773: (set_attr "length" "1")])
774:
775: (define_insn "divsf3"
776: [(set (match_operand:SF 0 "register_operand" "=f")
777: (div:SF (match_operand:SF 1 "register_operand" "f")
778: (match_operand:SF 2 "register_operand" "f")))]
779: "TARGET_HARD_FLOAT"
780: "div.s\\t%0,%1,%2"
781: [(set_attr "type" "fdiv")
782: (set_attr "mode" "SF")
783: (set_attr "length" "1")])
784:
785: ;; If optimizing, prefer the divmod functions over separate div and
786: ;; mod functions, since this will allow using one instruction for both
787: ;; the quotient and remainder. At present, the divmod is not moved out
788: ;; of loops if it is constant within the loop, so allow -mdebugc to
789: ;; use the old method of doing things.
790:
791: ;; 64 is the multiply/divide hi register
792: ;; 65 is the multiply/divide lo register
793:
794: (define_insn "divmodsi4"
1.1.1.3 ! root 795: [(set (match_operand:SI 0 "register_operand" "=d")
! 796: (div:SI (match_operand:SI 1 "register_operand" "d")
! 797: (match_operand:SI 2 "register_operand" "d")))
! 798: (set (match_operand:SI 3 "register_operand" "=d")
! 799: (mod:SI (match_dup 1)
! 800: (match_dup 2)))
! 801: (clobber (reg:SI 64))
! 802: (clobber (reg:SI 65))]
! 803: "optimize"
1.1 root 804: "*
805: {
806: if (find_reg_note (insn, REG_UNUSED, operands[3]))
807: return \"div\\t%0,%1,%2\";
808:
809: if (find_reg_note (insn, REG_UNUSED, operands[0]))
810: return \"rem\\t%3,%1,%2\";
811:
812: return \"div\\t%0,%1,%2\;mfhi\\t%3\";
813: }"
814: [(set_attr "type" "idiv")
815: (set_attr "mode" "SI")
816: (set_attr "length" "13")]) ;; various tests for dividing by 0 and such
817:
818: (define_insn "udivmodsi4"
1.1.1.3 ! root 819: [(set (match_operand:SI 0 "register_operand" "=d")
! 820: (udiv:SI (match_operand:SI 1 "register_operand" "d")
! 821: (match_operand:SI 2 "register_operand" "d")))
! 822: (set (match_operand:SI 3 "register_operand" "=d")
! 823: (umod:SI (match_dup 1)
! 824: (match_dup 2)))
! 825: (clobber (reg:SI 64))
! 826: (clobber (reg:SI 65))]
! 827: "optimize"
1.1 root 828: "*
829: {
830: if (find_reg_note (insn, REG_UNUSED, operands[3]))
831: return \"divu\\t%0,%1,%2\";
832:
833: if (find_reg_note (insn, REG_UNUSED, operands[0]))
834: return \"remu\\t%3,%1,%2\";
835:
836: return \"divu\\t%0,%1,%2\;mfhi\\t%3\";
837: }"
838: [(set_attr "type" "idiv")
839: (set_attr "mode" "SI")
840: (set_attr "length" "13")]) ;; various tests for dividing by 0 and such
841:
842: (define_insn "divsi3"
843: [(set (match_operand:SI 0 "register_operand" "=d")
844: (div:SI (match_operand:SI 1 "register_operand" "d")
845: (match_operand:SI 2 "register_operand" "d")))
846: (clobber (reg:SI 64))
847: (clobber (reg:SI 65))]
1.1.1.3 ! root 848: "!optimize"
1.1 root 849: "div\\t%0,%1,%2"
850: [(set_attr "type" "idiv")
851: (set_attr "mode" "SI")
852: (set_attr "length" "13")]) ;; various tests for dividing by 0 and such
853:
854: (define_insn "modsi3"
855: [(set (match_operand:SI 0 "register_operand" "=d")
856: (mod:SI (match_operand:SI 1 "register_operand" "d")
857: (match_operand:SI 2 "register_operand" "d")))
858: (clobber (reg:SI 64))
859: (clobber (reg:SI 65))]
1.1.1.3 ! root 860: "!optimize"
1.1 root 861: "rem\\t%0,%1,%2"
862: [(set_attr "type" "idiv")
863: (set_attr "mode" "SI")
864: (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
865:
866: (define_insn "udivsi3"
867: [(set (match_operand:SI 0 "register_operand" "=d")
868: (udiv:SI (match_operand:SI 1 "register_operand" "d")
869: (match_operand:SI 2 "register_operand" "d")))
870: (clobber (reg:SI 64))
871: (clobber (reg:SI 65))]
1.1.1.3 ! root 872: "!optimize"
1.1 root 873: "divu\\t%0,%1,%2"
874: [(set_attr "type" "idiv")
875: (set_attr "mode" "SI")
876: (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
877:
878: (define_insn "umodsi3"
879: [(set (match_operand:SI 0 "register_operand" "=d")
880: (umod:SI (match_operand:SI 1 "register_operand" "d")
881: (match_operand:SI 2 "register_operand" "d")))
882: (clobber (reg:SI 64))
883: (clobber (reg:SI 65))]
1.1.1.3 ! root 884: "!optimize"
1.1 root 885: "remu\\t%0,%1,%2"
886: [(set_attr "type" "idiv")
887: (set_attr "mode" "SI")
888: (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
889:
890:
891: ;;
892: ;; ....................
893: ;;
894: ;; SQUARE ROOT
895: ;;
896: ;; ....................
897:
898: (define_insn "sqrtdf2"
899: [(set (match_operand:DF 0 "register_operand" "=f")
900: (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
901: "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
902: "sqrt.d\\t%0,%1"
903: [(set_attr "type" "fabs")
904: (set_attr "mode" "DF")
905: (set_attr "length" "1")])
906:
907: (define_insn "sqrtsf2"
908: [(set (match_operand:SF 0 "register_operand" "=f")
909: (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
910: "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
911: "sqrt.s\\t%0,%1"
912: [(set_attr "type" "fabs")
913: (set_attr "mode" "SF")
914: (set_attr "length" "1")])
915:
916:
917: ;;
918: ;; ....................
919: ;;
920: ;; ABSOLUTE VALUE
921: ;;
922: ;; ....................
923:
924: ;; Do not use the integer abs macro instruction, since that signals an
925: ;; exception on -2147483648 (sigh).
926:
927: (define_insn "abssi2"
928: [(set (match_operand:SI 0 "register_operand" "=d")
929: (abs:SI (match_operand:SI 1 "register_operand" "d")))]
930: ""
931: "*
932: {
933: dslots_jump_total++;
934: dslots_jump_filled++;
935: operands[2] = const0_rtx;
936:
937: return (REGNO (operands[0]) == REGNO (operands[1]))
938: ? \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n1:\"
939: : \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
940: }"
941: [(set_attr "type" "multi")
942: (set_attr "mode" "SI")
943: (set_attr "length" "3")])
944:
945: (define_insn "absdf2"
946: [(set (match_operand:DF 0 "register_operand" "=f")
947: (abs:DF (match_operand:DF 1 "register_operand" "f")))]
948: "TARGET_HARD_FLOAT"
949: "abs.d\\t%0,%1"
950: [(set_attr "type" "fabs")
951: (set_attr "mode" "DF")
952: (set_attr "length" "1")])
953:
954: (define_insn "abssf2"
955: [(set (match_operand:SF 0 "register_operand" "=f")
956: (abs:SF (match_operand:SF 1 "register_operand" "f")))]
957: "TARGET_HARD_FLOAT"
958: "abs.s\\t%0,%1"
959: [(set_attr "type" "fabs")
960: (set_attr "mode" "SF")
961: (set_attr "length" "1")])
962:
963:
964: ;;
965: ;; ....................
966: ;;
967: ;; FIND FIRST BIT INSTRUCTION
968: ;;
969: ;; ....................
970: ;;
971:
972: (define_insn "ffssi2"
973: [(set (match_operand:SI 0 "register_operand" "=&d")
974: (ffs:SI (match_operand:SI 1 "register_operand" "d")))
975: (clobber (match_scratch:SI 2 "d"))
976: (clobber (match_scratch:SI 3 "d"))]
977: ""
978: "*
979: {
980: dslots_jump_total += 2;
981: dslots_jump_filled += 2;
982: operands[4] = const0_rtx;
983:
984: if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
985: return \"%(\\
986: move\\t%0,%z4\\n\\
987: \\tbeq\\t%1,%z4,2f\\n\\
988: 1:\\tand\\t%2,%1,0x0001\\n\\
989: \\taddu\\t%0,%0,1\\n\\
990: \\tbeq\\t%2,%z4,1b\\n\\
991: \\tsrl\\t%1,%1,1\\n\\
992: 2:%)\";
993:
994: return \"%(\\
995: move\\t%0,%z4\\n\\
996: \\tmove\\t%3,%1\\n\\
997: \\tbeq\\t%3,%z4,2f\\n\\
998: 1:\\tand\\t%2,%3,0x0001\\n\\
999: \\taddu\\t%0,%0,1\\n\\
1000: \\tbeq\\t%2,%z4,1b\\n\\
1001: \\tsrl\\t%3,%3,1\\n\\
1002: 2:%)\";
1003: }"
1004: [(set_attr "type" "multi")
1005: (set_attr "mode" "SI")
1006: (set_attr "length" "6")])
1007:
1008:
1009: ;;
1010: ;; ....................
1011: ;;
1012: ;; NEGATION and ONE'S COMPLEMENT
1013: ;;
1014: ;; ....................
1015:
1016: (define_insn "negsi2"
1017: [(set (match_operand:SI 0 "register_operand" "=d")
1018: (neg:SI (match_operand:SI 1 "register_operand" "d")))]
1019: ""
1020: "*
1021: {
1022: operands[2] = const0_rtx;
1023: return \"subu\\t%0,%z2,%1\";
1024: }"
1025: [(set_attr "type" "arith")
1026: (set_attr "mode" "SI")
1027: (set_attr "length" "1")])
1028:
1029: (define_expand "negdi3"
1030: [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1031: (neg:DI (match_operand:DI 1 "register_operand" "d")))
1032: (clobber (match_dup 2))])]
1033: "!TARGET_DEBUG_G_MODE"
1034: "operands[2] = gen_reg_rtx (SImode);")
1035:
1036: (define_insn "negdi3_internal"
1037: [(set (match_operand:DI 0 "register_operand" "=d")
1038: (neg:DI (match_operand:DI 1 "register_operand" "d")))
1039: (clobber (match_operand:SI 2 "register_operand" "=d"))]
1040: "!TARGET_DEBUG_G_MODE"
1041: "*
1042: {
1043: operands[3] = const0_rtx;
1044: return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
1045: }"
1046: [(set_attr "type" "darith")
1047: (set_attr "mode" "DI")
1048: (set_attr "length" "4")])
1049:
1050: (define_insn "negdf2"
1051: [(set (match_operand:DF 0 "register_operand" "=f")
1052: (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1053: "TARGET_HARD_FLOAT"
1054: "neg.d\\t%0,%1"
1055: [(set_attr "type" "fneg")
1056: (set_attr "mode" "DF")
1057: (set_attr "length" "1")])
1058:
1059: (define_insn "negsf2"
1060: [(set (match_operand:SF 0 "register_operand" "=f")
1061: (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1062: "TARGET_HARD_FLOAT"
1063: "neg.s\\t%0,%1"
1064: [(set_attr "type" "fneg")
1065: (set_attr "mode" "SF")
1066: (set_attr "length" "1")])
1067:
1068: (define_insn "one_cmplsi2"
1069: [(set (match_operand:SI 0 "register_operand" "=d")
1070: (not:SI (match_operand:SI 1 "register_operand" "d")))]
1071: ""
1072: "*
1073: {
1074: operands[2] = const0_rtx;
1075: return \"nor\\t%0,%z2,%1\";
1076: }"
1077: [(set_attr "type" "arith")
1078: (set_attr "mode" "SI")
1079: (set_attr "length" "1")])
1080:
1081: (define_insn "one_cmpldi2"
1082: [(set (match_operand:DI 0 "register_operand" "=d")
1083: (not:SI (match_operand:DI 1 "register_operand" "d")))]
1084: ""
1085: "*
1086: {
1087: operands[2] = const0_rtx;
1088: return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
1089: }"
1090: [(set_attr "type" "darith")
1091: (set_attr "mode" "DI")
1092: (set_attr "length" "2")])
1093:
1094: (define_split
1095: [(set (match_operand:DI 0 "register_operand" "")
1096: (not:DI (match_operand:DI 1 "register_operand" "")))]
1.1.1.3 ! root 1097: "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 1098: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1099: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
1100:
1101: [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
1102: (set (subreg:SI (match_dup 0) 1) (not:SI (subreg:SI (match_dup 1) 1)))]
1103: "")
1104:
1105: ;; Simple hack to recognize the "nor" instruction on the MIPS
1106: ;; This must appear before the normal or patterns, so that the
1107: ;; combiner will correctly fold things.
1108:
1109: (define_insn "norsi3"
1110: [(set (match_operand:SI 0 "register_operand" "=d")
1111: (not:SI (ior:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1112: (match_operand:SI 2 "reg_or_0_operand" "dJ"))))]
1113: ""
1114: "nor\\t%0,%z1,%z2"
1115: [(set_attr "type" "arith")
1116: (set_attr "mode" "SI")
1117: (set_attr "length" "1")])
1118:
1119: (define_insn "nordi3"
1120: [(set (match_operand:DI 0 "register_operand" "=d")
1121: (not:DI (ior:DI (match_operand:DI 1 "register_operand" "d")
1122: (match_operand:DI 2 "register_operand" "d"))))]
1123: ""
1124: "nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2"
1125: [(set_attr "type" "darith")
1126: (set_attr "mode" "DI")
1127: (set_attr "length" "2")])
1128:
1129: (define_split
1130: [(set (match_operand:DI 0 "register_operand" "")
1131: (not:DI (ior:DI (match_operand:DI 1 "register_operand" "")
1132: (match_operand:DI 2 "register_operand" ""))))]
1.1.1.3 ! root 1133: "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 1134: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1135: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1136: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1137:
1138: [(set (subreg:SI (match_dup 0) 0) (not:SI (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0))))
1139: (set (subreg:SI (match_dup 0) 1) (not:SI (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1))))]
1140: "")
1141:
1142:
1143: ;;
1144: ;; ....................
1145: ;;
1146: ;; LOGICAL
1147: ;;
1148: ;; ....................
1149: ;;
1150:
1151: ;; Be more liberal in allowing logical operations than the machine actually
1152: ;; supports. This causes better code to be generated for bitfields, since
1153: ;; the optimizer can fold things together, at the expense of not moving the
1154: ;; constant out of loops.
1155:
1156: (define_insn "andsi3"
1157: [(set (match_operand:SI 0 "register_operand" "=d,d,?d,?d")
1158: (and:SI (match_operand:SI 1 "arith32_operand" "%d,d,d,d")
1159: (match_operand:SI 2 "arith32_operand" "d,K,I,M")))]
1160: ""
1161: "@
1162: and\\t%0,%1,%2
1163: andi\\t%0,%1,%x2
1164: %[li\\t%@,%X2\;and\\t%0,%1,%@%]
1165: %[li\\t%@,%X2\;and\\t%0,%1,%@%]"
1166: [(set_attr "type" "arith,arith,multi,multi")
1.1.1.3 ! root 1167: (set_attr "mode" "SI")
1.1 root 1168: (set_attr "length" "1,1,2,3")])
1169:
1170: (define_insn "anddi3"
1171: [(set (match_operand:DI 0 "register_operand" "=d")
1172: (and:DI (match_operand:DI 1 "register_operand" "d")
1173: (match_operand:DI 2 "register_operand" "d")))]
1174: "!TARGET_DEBUG_G_MODE"
1175: "and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2"
1176: [(set_attr "type" "darith")
1177: (set_attr "mode" "DI")
1178: (set_attr "length" "2")])
1179:
1180: (define_split
1181: [(set (match_operand:DI 0 "register_operand" "")
1182: (and:DI (match_operand:DI 1 "register_operand" "")
1183: (match_operand:DI 2 "register_operand" "")))]
1.1.1.3 ! root 1184: "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 1185: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1186: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1187: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1188:
1189: [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
1190: (set (subreg:SI (match_dup 0) 1) (and:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
1191: "")
1192:
1193: (define_insn "iorsi3"
1194: [(set (match_operand:SI 0 "register_operand" "=d,d,?d,?d")
1195: (ior:SI (match_operand:SI 1 "arith32_operand" "%d,d,d,d")
1196: (match_operand:SI 2 "arith32_operand" "d,K,I,M")))]
1197: ""
1198: "@
1199: or\\t%0,%1,%2
1200: ori\\t%0,%1,%x2
1201: %[li\\t%@,%X2\;or\\t%0,%1,%@%]
1202: %[li\\t%@,%X2\;or\\t%0,%1,%@%]"
1203: [(set_attr "type" "arith,arith,multi,multi")
1.1.1.3 ! root 1204: (set_attr "mode" "SI")
1.1 root 1205: (set_attr "length" "1,1,2,3")])
1206:
1207: (define_insn "iordi3"
1208: [(set (match_operand:DI 0 "register_operand" "=d")
1209: (ior:DI (match_operand:DI 1 "register_operand" "d")
1210: (match_operand:DI 2 "register_operand" "d")))]
1211: "!TARGET_DEBUG_G_MODE"
1212: "or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2"
1213: [(set_attr "type" "darith")
1214: (set_attr "mode" "DI")
1215: (set_attr "length" "2")])
1216:
1217: (define_split
1218: [(set (match_operand:DI 0 "register_operand" "")
1219: (ior:DI (match_operand:DI 1 "register_operand" "")
1220: (match_operand:DI 2 "register_operand" "")))]
1.1.1.3 ! root 1221: "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 1222: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1223: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1224: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1225:
1226: [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
1227: (set (subreg:SI (match_dup 0) 1) (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
1228: "")
1229:
1230: (define_insn "xorsi3"
1231: [(set (match_operand:SI 0 "register_operand" "=d,d,?d,?d")
1232: (xor:SI (match_operand:SI 1 "arith32_operand" "%d,d,d,d")
1233: (match_operand:SI 2 "arith32_operand" "d,K,I,M")))]
1234: ""
1235: "@
1236: xor\\t%0,%1,%2
1237: xori\\t%0,%1,%x2
1238: %[li\\t%@,%X2\;xor\\t%0,%1,%@%]
1239: %[li\\t%@,%X2\;xor\\t%0,%1,%@%]"
1240: [(set_attr "type" "arith,arith,multi,multi")
1.1.1.3 ! root 1241: (set_attr "mode" "SI")
1.1 root 1242: (set_attr "length" "1,1,2,3")])
1243:
1244: (define_insn "xordi3"
1245: [(set (match_operand:DI 0 "register_operand" "=d")
1246: (xor:DI (match_operand:DI 1 "register_operand" "d")
1247: (match_operand:DI 2 "register_operand" "d")))]
1248: "!TARGET_DEBUG_G_MODE"
1249: "xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2"
1250: [(set_attr "type" "darith")
1251: (set_attr "mode" "DI")
1252: (set_attr "length" "2")])
1253:
1254: (define_split
1255: [(set (match_operand:DI 0 "register_operand" "")
1256: (xor:DI (match_operand:DI 1 "register_operand" "")
1257: (match_operand:DI 2 "register_operand" "")))]
1.1.1.3 ! root 1258: "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 1259: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1260: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1261: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1262:
1263: [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
1264: (set (subreg:SI (match_dup 0) 1) (xor:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
1265: "")
1266:
1267:
1268: ;;
1269: ;; ....................
1270: ;;
1271: ;; TRUNCATION
1272: ;;
1273: ;; ....................
1274:
1275: (define_insn "truncdfsf2"
1276: [(set (match_operand:SF 0 "register_operand" "=f")
1277: (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
1278: "TARGET_HARD_FLOAT"
1279: "cvt.s.d\\t%0,%1"
1280: [(set_attr "type" "fcvt")
1281: (set_attr "mode" "SF")
1282: (set_attr "length" "1")])
1283:
1284:
1285: ;;
1286: ;; ....................
1287: ;;
1288: ;; ZERO EXTENSION
1289: ;;
1290: ;; ....................
1291:
1292: ;; Extension insns.
1293: ;; Those for integer source operand
1294: ;; are ordered widest source type first.
1295:
1296: (define_insn "zero_extendhisi2"
1297: [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1298: (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
1299: ""
1300: "*
1301: {
1302: if (which_alternative == 0)
1303: return \"andi\\t%0,%1,0xffff\";
1304: else
1305: return mips_move_1word (operands, insn, TRUE);
1306: }"
1307: [(set_attr "type" "arith,load,load")
1.1.1.3 ! root 1308: (set_attr "mode" "SI")
1.1 root 1309: (set_attr "length" "1,1,2")])
1310:
1311: (define_insn "zero_extendqihi2"
1312: [(set (match_operand:HI 0 "register_operand" "=d,d,d")
1313: (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
1314: ""
1315: "*
1316: {
1317: if (which_alternative == 0)
1318: return \"andi\\t%0,%1,0x00ff\";
1319: else
1320: return mips_move_1word (operands, insn, TRUE);
1321: }"
1322: [(set_attr "type" "arith,load,load")
1.1.1.3 ! root 1323: (set_attr "mode" "HI")
1.1 root 1324: (set_attr "length" "1,1,2")])
1325:
1326: (define_insn "zero_extendqisi2"
1327: [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1328: (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
1329: ""
1330: "*
1331: {
1332: if (which_alternative == 0)
1333: return \"andi\\t%0,%1,0x00ff\";
1334: else
1335: return mips_move_1word (operands, insn, TRUE);
1336: }"
1337: [(set_attr "type" "arith,load,load")
1.1.1.3 ! root 1338: (set_attr "mode" "SI")
1.1 root 1339: (set_attr "length" "1,1,2")])
1340:
1341:
1342: ;;
1343: ;; ....................
1344: ;;
1345: ;; SIGN EXTENSION
1346: ;;
1347: ;; ....................
1348:
1349: ;; Extension insns.
1350: ;; Those for integer source operand
1351: ;; are ordered widest source type first.
1352:
1353: ;; These patterns originally accepted general_operands, however, slightly
1354: ;; better code is generated by only accepting register_operands, and then
1355: ;; letting combine generate the lh and lb insns.
1356:
1357: (define_expand "extendhisi2"
1358: [(set (match_operand:SI 0 "register_operand" "")
1359: (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1360: ""
1361: "
1362: {
1363: if (optimize && GET_CODE (operands[1]) == MEM)
1364: operands[1] = force_not_mem (operands[1]);
1365:
1366: if (GET_CODE (operands[1]) != MEM)
1367: {
1368: rtx op1 = gen_lowpart (SImode, operands[1]);
1369: rtx temp = gen_reg_rtx (SImode);
1370: rtx shift = gen_rtx (CONST_INT, VOIDmode, 16);
1371:
1372: emit_insn (gen_ashlsi3 (temp, op1, shift));
1373: emit_insn (gen_ashrsi3 (operands[0], temp, shift));
1374: DONE;
1375: }
1376: }")
1377:
1378: (define_insn "extendhisi2_internal"
1379: [(set (match_operand:SI 0 "register_operand" "=d,d")
1380: (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
1381: ""
1382: "* return mips_move_1word (operands, insn, FALSE);"
1.1.1.3 ! root 1383: [(set_attr "type" "load")
! 1384: (set_attr "mode" "SI")
1.1 root 1385: (set_attr "length" "1,2")])
1386:
1387: (define_expand "extendqihi2"
1388: [(set (match_operand:HI 0 "register_operand" "")
1389: (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1390: ""
1391: "
1392: {
1393: if (optimize && GET_CODE (operands[1]) == MEM)
1394: operands[1] = force_not_mem (operands[1]);
1395:
1396: if (GET_CODE (operands[1]) != MEM)
1397: {
1398: rtx op0 = gen_lowpart (SImode, operands[0]);
1399: rtx op1 = gen_lowpart (SImode, operands[1]);
1400: rtx temp = gen_reg_rtx (SImode);
1401: rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
1402:
1403: emit_insn (gen_ashlsi3 (temp, op1, shift));
1404: emit_insn (gen_ashrsi3 (op0, temp, shift));
1405: DONE;
1406: }
1407: }")
1408:
1409: (define_insn "extendqihi2_internal"
1410: [(set (match_operand:HI 0 "register_operand" "=d,d")
1411: (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
1412: ""
1413: "* return mips_move_1word (operands, insn, FALSE);"
1.1.1.3 ! root 1414: [(set_attr "type" "load")
! 1415: (set_attr "mode" "SI")
1.1 root 1416: (set_attr "length" "1,2")])
1417:
1418:
1419: (define_expand "extendqisi2"
1420: [(set (match_operand:SI 0 "register_operand" "")
1421: (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1422: ""
1423: "
1424: {
1425: if (optimize && GET_CODE (operands[1]) == MEM)
1426: operands[1] = force_not_mem (operands[1]);
1427:
1428: if (GET_CODE (operands[1]) != MEM)
1429: {
1430: rtx op1 = gen_lowpart (SImode, operands[1]);
1431: rtx temp = gen_reg_rtx (SImode);
1432: rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
1433:
1434: emit_insn (gen_ashlsi3 (temp, op1, shift));
1435: emit_insn (gen_ashrsi3 (operands[0], temp, shift));
1436: DONE;
1437: }
1438: }")
1439:
1440: (define_insn "extendqisi2_insn"
1441: [(set (match_operand:SI 0 "register_operand" "=d,d")
1442: (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
1443: ""
1444: "* return mips_move_1word (operands, insn, FALSE);"
1.1.1.3 ! root 1445: [(set_attr "type" "load")
! 1446: (set_attr "mode" "SI")
1.1 root 1447: (set_attr "length" "1,2")])
1448:
1449:
1450: (define_insn "extendsfdf2"
1451: [(set (match_operand:DF 0 "register_operand" "=f")
1452: (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
1453: "TARGET_HARD_FLOAT"
1454: "cvt.d.s\\t%0,%1"
1455: [(set_attr "type" "fcvt")
1456: (set_attr "mode" "DF")
1457: (set_attr "length" "1")])
1458:
1459:
1460:
1461: ;;
1462: ;; ....................
1463: ;;
1464: ;; CONVERSIONS
1465: ;;
1466: ;; ....................
1467:
1468: (define_insn "fix_truncdfsi2_internal"
1469: [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o")
1470: (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
1471: (clobber (match_operand:SI 2 "register_operand" "d,*d,d,d"))
1472: (clobber (match_operand:DF 3 "register_operand" "f,*f,f,f"))]
1473: "TARGET_HARD_FLOAT"
1474: "*
1475: {
1476: rtx xoperands[10];
1477:
1478: if (which_alternative == 1)
1479: return \"trunc.w.d %0,%1,%2\";
1480:
1481: output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
1482:
1483: xoperands[0] = operands[0];
1484: xoperands[1] = operands[3];
1485: output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1486: return \"\";
1487: }"
1.1.1.3 ! root 1488: [(set_attr "type" "fcvt")
! 1489: (set_attr "mode" "DF")
1.1 root 1490: (set_attr "length" "14,12,13,14")])
1491:
1492:
1493: (define_expand "fix_truncdfsi2"
1494: [(parallel [(set (match_operand:SI 0 "register_operand" "=d")
1495: (fix:SI (match_operand:DF 1 "register_operand" "f")))
1496: (clobber (match_dup 2))
1497: (clobber (match_dup 3))])]
1498: "TARGET_HARD_FLOAT"
1499: "
1500: {
1501: operands[2] = gen_reg_rtx (SImode); /* gp reg that saves FP status bits */
1502: operands[3] = gen_reg_rtx (DFmode); /* fp reg that gets the conversion */
1503:
1504: /* Fall through and generate default code */
1505: }")
1506:
1507: (define_insn "fix_truncsfsi2_internal"
1508: [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o")
1509: (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
1510: (clobber (match_operand:SI 2 "register_operand" "d,*d,d,d"))
1511: (clobber (match_operand:SF 3 "register_operand" "f,*f,f,f"))]
1512: "TARGET_HARD_FLOAT"
1513: "*
1514: {
1515: rtx xoperands[10];
1516:
1517: if (which_alternative == 1)
1518: return \"trunc.w.s %0,%1,%2\";
1519:
1520: output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
1521:
1522: xoperands[0] = operands[0];
1523: xoperands[1] = operands[3];
1524: output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1525: return \"\";
1526: }"
1.1.1.3 ! root 1527: [(set_attr "type" "fcvt")
! 1528: (set_attr "mode" "SF")
1.1 root 1529: (set_attr "length" "14,12,13,14")])
1530:
1531:
1532: (define_expand "fix_truncsfsi2"
1533: [(parallel [(set (match_operand:SI 0 "register_operand" "=f")
1534: (fix:SI (match_operand:SF 1 "register_operand" "f")))
1535: (clobber (match_dup 2))
1536: (clobber (match_dup 3))])]
1537: "TARGET_HARD_FLOAT"
1538: "
1539: {
1540: operands[2] = gen_reg_rtx (SImode); /* gp reg that saves FP status bits */
1541: operands[3] = gen_reg_rtx (SFmode); /* fp reg that gets the conversion */
1542:
1543: /* Fall through and generate default code */
1544: }")
1545:
1546:
1547: (define_insn "floatsidf2"
1.1.1.3 ! root 1548: [(set (match_operand:DF 0 "register_operand" "=f,f,f")
! 1549: (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
1.1 root 1550: "TARGET_HARD_FLOAT"
1.1.1.3 ! root 1551: "*
! 1552: {
! 1553: dslots_load_total++;
! 1554: if (GET_CODE (operands[1]) == MEM)
! 1555: return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
! 1556:
! 1557: return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
! 1558: }"
1.1 root 1559: [(set_attr "type" "fcvt")
1560: (set_attr "mode" "DF")
1.1.1.3 ! root 1561: (set_attr "length" "3,4,3")])
1.1 root 1562:
1563: (define_insn "floatsisf2"
1.1.1.3 ! root 1564: [(set (match_operand:SF 0 "register_operand" "=f,f,f")
! 1565: (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
1.1 root 1566: "TARGET_HARD_FLOAT"
1.1.1.3 ! root 1567: "*
! 1568: {
! 1569: dslots_load_total++;
! 1570: if (GET_CODE (operands[1]) == MEM)
! 1571: return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
! 1572:
! 1573: return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
! 1574: }"
1.1 root 1575: [(set_attr "type" "fcvt")
1576: (set_attr "mode" "SF")
1.1.1.3 ! root 1577: (set_attr "length" "3,4,3")])
! 1578:
1.1 root 1579:
1580: (define_expand "fixuns_truncdfsi2"
1581: [(set (match_operand:SI 0 "register_operand" "")
1582: (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
1583: "TARGET_HARD_FLOAT"
1584: "
1585: {
1586: rtx reg1 = gen_reg_rtx (DFmode);
1587: rtx reg2 = gen_reg_rtx (DFmode);
1588: rtx reg3 = gen_reg_rtx (SImode);
1589: rtx label1 = gen_label_rtx ();
1590: rtx label2 = gen_label_rtx ();
1591: REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
1592:
1593: if (reg1) /* turn off complaints about unreached code */
1594: {
1595: extern rtx gen_cmpdf ();
1596: emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
1597: do_pending_stack_adjust ();
1598:
1599: emit_insn (gen_cmpdf (operands[1], reg1));
1600: emit_jump_insn (gen_bge (label1));
1601:
1602: emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
1603: emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
1604: gen_rtx (LABEL_REF, VOIDmode, label2)));
1605: emit_barrier ();
1606:
1607: emit_label (label1);
1608: emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
1609: emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
1610:
1611: emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
1612: emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
1613:
1614: emit_label (label2);
1615:
1616: /* allow REG_NOTES to be set on last insn (labels don't have enough
1617: fields, and can't be used for REG_NOTES anyway). */
1618: emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
1619: DONE;
1620: }
1621: }")
1622:
1623: (define_expand "fixuns_truncsfsi2"
1624: [(set (match_operand:SI 0 "register_operand" "")
1625: (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
1626: "TARGET_HARD_FLOAT"
1627: "
1628: {
1629: rtx reg1 = gen_reg_rtx (SFmode);
1630: rtx reg2 = gen_reg_rtx (SFmode);
1631: rtx reg3 = gen_reg_rtx (SImode);
1632: rtx label1 = gen_label_rtx ();
1633: rtx label2 = gen_label_rtx ();
1634: REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
1635:
1636: if (reg1) /* turn off complaints about unreached code */
1637: {
1638: extern rtx gen_cmpsf ();
1639: emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
1640: do_pending_stack_adjust ();
1641:
1642: emit_insn (gen_cmpsf (operands[1], reg1));
1643: emit_jump_insn (gen_bge (label1));
1644:
1645: emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
1646: emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
1647: gen_rtx (LABEL_REF, VOIDmode, label2)));
1648: emit_barrier ();
1649:
1650: emit_label (label1);
1651: emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
1652: emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
1653:
1654: emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
1655: emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
1656:
1657: emit_label (label2);
1658:
1659: /* allow REG_NOTES to be set on last insn (labels don't have enough
1660: fields, and can't be used for REG_NOTES anyway). */
1661: emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
1662: DONE;
1663: }
1664: }")
1665:
1666:
1667: ;;
1668: ;; ....................
1669: ;;
1670: ;; DATA MOVEMENT
1671: ;;
1672: ;; ....................
1673:
1674: ;; unaligned word moves generated by the block moves.
1675:
1676: (define_expand "movsi_unaligned"
1.1.1.2 root 1677: [(set (match_operand:SI 0 "general_operand" "")
1678: (unspec [(match_operand:SI 1 "general_operand" "")] 0))]
1.1 root 1679: ""
1680: "
1681: {
1682: extern rtx gen_movsi_ulw ();
1683: extern rtx gen_movsi ();
1684:
1.1.1.3 ! root 1685: /* Handle loads. */
! 1686: if (GET_CODE (operands[0]) == MEM)
1.1 root 1687: {
1688: rtx reg = gen_reg_rtx (SImode);
1.1.1.3 ! root 1689: rtx insn = emit_insn (gen_movsi_ulw (reg, operands[1]));
! 1690: rtx addr = XEXP (operands[0], 0);
! 1691: if (CONSTANT_P (addr))
! 1692: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUIV, addr, REG_NOTES (insn));
! 1693:
! 1694: if (reg_or_0_operand (operands[1], SImode))
! 1695: DONE;
1.1 root 1696:
1697: operands[1] = reg;
1698: }
1699:
1700: /* Generate appropriate load, store. If not a load or store,
1701: do a normal movsi. */
1702: if (GET_CODE (operands[0]) != MEM && GET_CODE (operands[1]) != MEM)
1703: {
1704: emit_insn (gen_movsi (operands[0], operands[1]));
1705: DONE;
1706: }
1707:
1708: /* Fall through and generate normal code. */
1709: }")
1710:
1711: (define_insn "movsi_ulw"
1712: [(set (match_operand:SI 0 "register_operand" "=&d,&d,d,d")
1.1.1.2 root 1713: (unspec [(match_operand:SI 1 "general_operand" "R,o,dIKL,M")] 0))]
1.1 root 1714: ""
1715: "*
1716: {
1717: extern rtx eliminate_constant_term ();
1718: enum rtx_code code;
1719: char *ret;
1.1.1.2 root 1720: rtx offset;
1.1 root 1721: rtx addr;
1722: rtx mem_addr;
1723:
1724: if (which_alternative != 0)
1725: return mips_move_1word (operands, insn, FALSE);
1726:
1727: if (TARGET_STATS)
1728: mips_count_memory_refs (operands[1], 2);
1729:
1730: /* The stack/frame pointers are always aligned, so we can convert
1731: to the faster lw if we are referencing an aligned stack location. */
1732:
1.1.1.2 root 1733: offset = const0_rtx;
1.1 root 1734: addr = XEXP (operands[1], 0);
1735: mem_addr = eliminate_constant_term (addr, &offset);
1736:
1.1.1.2 root 1737: if ((INTVAL (offset) & (UNITS_PER_WORD-1)) == 0
1.1 root 1738: && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
1739: ret = \"lw\\t%0,%1\";
1740:
1741: else
1742: {
1743: ret = \"ulw\\t%0,%1\";
1744: if (TARGET_GAS)
1745: {
1746: enum rtx_code code = GET_CODE (addr);
1747:
1748: if (code == CONST || code == SYMBOL_REF || code == LABEL_REF)
1749: {
1750: operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 1);
1751: ret = \"%[la\\t%2,%1\;ulw\\t%0,0(%2)%]\";
1752: }
1753: }
1754: }
1755:
1756: return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
1757: }"
1758: [(set_attr "type" "load,load,move,arith")
1.1.1.3 ! root 1759: (set_attr "mode" "SI")
1.1 root 1760: (set_attr "length" "2,4,1,2")])
1761:
1762: (define_insn "movsi_usw"
1763: [(set (match_operand:SI 0 "memory_operand" "=R,o")
1.1.1.2 root 1764: (unspec [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 0))]
1.1 root 1765: ""
1766: "*
1767: {
1768: extern rtx eliminate_constant_term ();
1.1.1.2 root 1769: rtx offset = const0_rtx;
1.1 root 1770: rtx addr = XEXP (operands[0], 0);
1771: rtx mem_addr = eliminate_constant_term (addr, &offset);
1772:
1773: if (TARGET_STATS)
1774: mips_count_memory_refs (operands[0], 2);
1775:
1776: /* The stack/frame pointers are always aligned, so we can convert
1777: to the faster sw if we are referencing an aligned stack location. */
1778:
1.1.1.2 root 1779: if ((INTVAL (offset) & (UNITS_PER_WORD-1)) == 0
1.1 root 1780: && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
1781: return \"sw\\t%1,%0\";
1782:
1783:
1784: if (TARGET_GAS)
1785: {
1786: enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
1787:
1788: if (code == CONST || code == SYMBOL_REF || code == LABEL_REF)
1789: {
1790: operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 1);
1791: return \"%[la\\t%2,%0\;usw\\t%z1,0(%2)%]\";
1792: }
1793: }
1794:
1795: return \"usw\\t%z1,%0\";
1796: }"
1.1.1.3 ! root 1797: [(set_attr "type" "store")
! 1798: (set_attr "mode" "SI")
1.1 root 1799: (set_attr "length" "2,4")])
1800:
1801: ;; 64-bit integer moves
1802:
1803: ;; Unlike most other insns, the move insns can't be split with
1804: ;; different predicates, because register spilling and other parts of
1805: ;; the compiler, have memoized the insn number already.
1806:
1807: (define_insn "movdi"
1.1.1.2 root 1808: [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*d,*x")
1809: (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,*x,*d"))]
1.1 root 1810: ""
1811: "* return mips_move_2words (operands, insn); "
1.1.1.2 root 1812: [(set_attr "type" "move,arith,load,load,store,store,hilo,hilo")
1.1.1.3 ! root 1813: (set_attr "mode" "DI")
1.1.1.2 root 1814: (set_attr "length" "2,4,2,4,2,4,2,2")])
1.1 root 1815:
1816: (define_split
1817: [(set (match_operand:DI 0 "register_operand" "")
1818: (match_operand:DI 1 "register_operand" ""))]
1.1.1.3 ! root 1819: "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 1820: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1821: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
1822:
1823: [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
1824: (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
1825: "")
1826:
1827:
1828: ;; 32-bit Integer moves
1829:
1830: (define_split
1831: [(set (match_operand:SI 0 "register_operand" "")
1832: (match_operand:SI 1 "large_int" ""))]
1.1.1.3 ! root 1833: "!TARGET_DEBUG_D_MODE"
1.1 root 1834: [(set (match_dup 0)
1835: (match_dup 2))
1836: (set (match_dup 0)
1837: (ior:SI (match_dup 0)
1838: (match_dup 3)))]
1839: "
1840: {
1841: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff0000);
1842: operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0x0000ffff);
1843: }")
1844:
1845: ;; Unlike most other insns, the move insns can't be split with
1846: ;; different predicates, because register spilling and other parts of
1847: ;; the compiler, have memoized the insn number already.
1848:
1.1.1.3 ! root 1849: (define_expand "movsi"
! 1850: [(set (match_operand:SI 0 "nonimmediate_operand" "")
! 1851: (match_operand:SI 1 "general_operand" ""))]
! 1852: ""
! 1853: "
! 1854: {
! 1855: /* If this is a half-pic address being moved to a register, convert the
! 1856: address into a load, so that scheduling and stuff works properly. */
! 1857:
! 1858: if (HALF_PIC_P()
! 1859: && GET_CODE (operands[0]) == REG
! 1860: && GET_CODE (operands[1]) == SYMBOL_REF
! 1861: && HALF_PIC_ADDRESS_P (operands[1]))
! 1862: {
! 1863: rtx ptr = HALF_PIC_PTR (operands[1]);
! 1864: if (XSTR (ptr, 0) != XSTR (operands[1], 0))
! 1865: {
! 1866: emit_move_insn (operands[0], gen_rtx (MEM, Pmode, ptr));
! 1867: DONE;
! 1868: }
! 1869: }
! 1870: }")
! 1871:
! 1872: (define_insn "movsi_internal"
! 1873: [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*fz,*f,*f,*f,*R,*m,*x,*d")
! 1874: (match_operand:SI 1 "general_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*fz,*d,*f,*R,*m,*f,*f,*d,*x"))]
1.1 root 1875: ""
1876: "* return mips_move_1word (operands, insn, TRUE);"
1877: [(set_attr "type" "move,pic,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo")
1.1.1.3 ! root 1878: (set_attr "mode" "SI")
1.1 root 1879: (set_attr "length" "1,4,1,2,1,2,1,2,1,1,1,1,2,1,2,1,1")])
1880:
1881: ;; 16-bit Integer moves
1882:
1883: ;; Unlike most other insns, the move insns can't be split with
1884: ;; different predicates, because register spilling and other parts of
1885: ;; the compiler, have memoized the insn number already.
1886: ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
1887:
1888: (define_insn "movhi"
1889: [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f,*x,*d")
1.1.1.3 ! root 1890: (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*fz,*d,*f,*d,*x"))]
1.1 root 1891: ""
1892: "* return mips_move_1word (operands, insn, TRUE);"
1893: [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
1.1.1.3 ! root 1894: (set_attr "mode" "HI")
1.1 root 1895: (set_attr "length" "1,1,1,2,1,2,1,1,1,1,1")])
1896:
1897: ;; 8-bit Integer moves
1898:
1899: ;; Unlike most other insns, the move insns can't be split with
1900: ;; different predicates, because register spilling and other parts of
1901: ;; the compiler, have memoized the insn number already.
1902: ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
1903:
1904: (define_insn "movqi"
1905: [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f,*x,*d")
1.1.1.3 ! root 1906: (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*fz,*d,*f,*d,*x"))]
1.1 root 1907: ""
1908: "* return mips_move_1word (operands, insn, TRUE);"
1909: [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
1.1.1.3 ! root 1910: (set_attr "mode" "QI")
1.1 root 1911: (set_attr "length" "1,1,1,2,1,2,1,1,1,1,1")])
1912:
1913:
1914: ;; 32-bit floating point moves
1915:
1916: (define_insn "movsf"
1917: [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
1918: (match_operand:SF 1 "general_operand" "f,G,R,Em,fG,fG,*d,*f,*Gd,*R,*Em,*d,*d"))]
1919: ""
1920: "* return mips_move_1word (operands, insn, FALSE);"
1921: [(set_attr "type" "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
1.1.1.3 ! root 1922: (set_attr "mode" "SF")
1.1 root 1923: (set_attr "length" "1,1,1,2,1,2,1,1,1,1,2,1,2")])
1924:
1925: ;; 64-bit floating point moves
1926:
1927: (define_insn "movdf"
1928: [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,o,f,*f,*d,*d,*d,*d,*R,*o")
1929: (match_operand:DF 1 "general_operand" "f,R,o,fG,fG,E,*d,*f,*dG,*R,*oE,*d,*d"))]
1930: ""
1931: "* return mips_move_2words (operands, insn); "
1932: [(set_attr "type" "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
1.1.1.3 ! root 1933: (set_attr "mode" "DF")
1.1 root 1934: (set_attr "length" "1,2,4,2,4,4,2,2,2,2,4,2,4")])
1935:
1936: (define_split
1937: [(set (match_operand:DF 0 "register_operand" "")
1938: (match_operand:DF 1 "register_operand" ""))]
1.1.1.3 ! root 1939: "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 1940: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1941: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
1942:
1943: [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
1944: (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
1945: "")
1946:
1.1.1.3 ! root 1947:
1.1 root 1948: ;; Block moves, see mips.c for more details.
1949: ;; Argument 0 is the destination
1950: ;; Argument 1 is the source
1951: ;; Argument 2 is the length
1952: ;; Argument 3 is the alignment
1953:
1954: (define_expand "movstrsi"
1955: [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1956: (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1957: (use (match_operand:SI 2 "arith32_operand" ""))
1958: (use (match_operand:SI 3 "immediate_operand" ""))])]
1959: ""
1960: "
1961: {
1962: if (operands[0]) /* avoid unused code messages */
1963: {
1964: expand_block_move (operands);
1965: DONE;
1966: }
1967: }")
1968:
1.1.1.3 ! root 1969: ;; Insn generated by block moves
! 1970:
! 1971: (define_insn "movstrsi_internal"
! 1972: [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
! 1973: (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
! 1974: (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
! 1975: (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
! 1976: (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
! 1977: (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
! 1978: (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
! 1979: (use (match_operand:SI 3 "small_int" "I")) ;; alignment
! 1980: (use (const_int 0))] ;; normal block move
! 1981: ""
! 1982: "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
! 1983: [(set_attr "type" "multi")
! 1984: (set_attr "mode" "none")
! 1985: (set_attr "length" "20")])
! 1986:
! 1987: ;; Split a block move into 2 parts, the first part is everything
! 1988: ;; except for the last move, and the second part is just the last
! 1989: ;; store, which is exactly 1 instruction (ie, not a usw), so it can
! 1990: ;; fill a delay slot. This also prevents a bug in delayed branches
! 1991: ;; from showing up, which reuses one of the registers in our clobbers.
! 1992:
! 1993: (define_split
! 1994: [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
! 1995: (mem:BLK (match_operand:SI 1 "register_operand" "")))
! 1996: (clobber (match_operand:SI 4 "register_operand" ""))
! 1997: (clobber (match_operand:SI 5 "register_operand" ""))
! 1998: (clobber (match_operand:SI 6 "register_operand" ""))
! 1999: (clobber (match_operand:SI 7 "register_operand" ""))
! 2000: (use (match_operand:SI 2 "small_int" ""))
! 2001: (use (match_operand:SI 3 "small_int" ""))
! 2002: (use (const_int 0))]
! 2003:
! 2004: "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
! 2005:
! 2006: ;; All but the last move
! 2007: [(parallel [(set (mem:BLK (match_dup 0))
! 2008: (mem:BLK (match_dup 1)))
! 2009: (clobber (match_dup 4))
! 2010: (clobber (match_dup 5))
! 2011: (clobber (match_dup 6))
! 2012: (clobber (match_dup 7))
! 2013: (use (match_dup 2))
! 2014: (use (match_dup 3))
! 2015: (use (const_int 1))])
! 2016:
! 2017: ;; The last store, so it can fill a delay slot
! 2018: (parallel [(set (mem:BLK (match_dup 0))
! 2019: (mem:BLK (match_dup 1)))
! 2020: (clobber (match_dup 4))
! 2021: (clobber (match_dup 5))
! 2022: (clobber (match_dup 6))
! 2023: (clobber (match_dup 7))
! 2024: (use (match_dup 2))
! 2025: (use (match_dup 3))
! 2026: (use (const_int 2))])]
! 2027:
! 2028: "")
! 2029:
! 2030: (define_insn "movstrsi_internal2"
! 2031: [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
! 2032: (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
! 2033: (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
! 2034: (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
! 2035: (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
! 2036: (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
! 2037: (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
! 2038: (use (match_operand:SI 3 "small_int" "I")) ;; alignment
! 2039: (use (const_int 1))] ;; all but last store
! 2040: ""
! 2041: "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
! 2042: [(set_attr "type" "multi")
! 2043: (set_attr "mode" "none")
! 2044: (set_attr "length" "20")])
! 2045:
! 2046: (define_insn "movstrsi_internal3"
! 2047: [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
! 2048: (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
! 2049: (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
! 2050: (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
! 2051: (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
! 2052: (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
! 2053: (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
! 2054: (use (match_operand:SI 3 "small_int" "I")) ;; alignment
! 2055: (use (const_int 2))] ;; just last store of block mvoe
! 2056: ""
! 2057: "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
! 2058: [(set_attr "type" "store")
! 2059: (set_attr "mode" "none")
! 2060: (set_attr "length" "1")])
! 2061:
1.1 root 2062:
2063: ;;
2064: ;; ....................
2065: ;;
2066: ;; SHIFTS
2067: ;;
2068: ;; ....................
2069:
2070: (define_insn "ashlsi3"
2071: [(set (match_operand:SI 0 "register_operand" "=d")
2072: (ashift:SI (match_operand:SI 1 "register_operand" "d")
2073: (match_operand:SI 2 "arith_operand" "dI")))]
2074: ""
2075: "*
2076: {
2077: if (GET_CODE (operands[2]) == CONST_INT)
2078: operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
2079:
2080: return \"sll\\t%0,%1,%2\";
2081: }"
2082: [(set_attr "type" "arith")
2083: (set_attr "mode" "SI")
2084: (set_attr "length" "1")])
2085:
2086:
2087: (define_expand "ashldi3"
2088: [(parallel [(set (match_operand:DI 0 "register_operand" "")
2089: (ashift:DI (match_operand:DI 1 "register_operand" "")
2090: (match_operand:SI 2 "arith_operand" "")))
2091: (clobber (match_dup 3))])]
2092: "!TARGET_DEBUG_G_MODE"
2093: "operands[3] = gen_reg_rtx (SImode);")
2094:
2095:
2096: (define_insn "ashldi3_internal"
2097: [(set (match_operand:DI 0 "register_operand" "=d")
2098: (ashift:DI (match_operand:DI 1 "register_operand" "d")
2099: (match_operand:SI 2 "register_operand" "d")))
2100: (clobber (match_operand:SI 3 "register_operand" "=d"))]
2101: "!TARGET_DEBUG_G_MODE"
2102: "*
2103: {
2104: operands[4] = const0_rtx;
2105: dslots_jump_total += 3;
2106: dslots_jump_filled += 2;
2107:
2108: return \"sll\\t%3,%2,26\\n\\
2109: \\tbgez\\t%3,1f\\n\\
2110: \\tsll\\t%M0,%L1,%2\\n\\
2111: \\t%(b\\t3f\\n\\
2112: \\tmove\\t%L0,%z4%)\\n\\
2113: \\n\\
2114: 1:\\n\\
2115: \\t%(beq\\t%3,%z4,2f\\n\\
2116: \\tsll\\t%M0,%M1,%2%)\\n\\
2117: \\n\\
2118: \\tsubu\\t%3,%z4,%2\\n\\
2119: \\tsrl\\t%3,%L1,%3\\n\\
2120: \\tor\\t%M0,%M0,%3\\n\\
2121: 2:\\n\\
2122: \\tsll\\t%L0,%L1,%2\\n\\
2123: 3:\";
2124: }"
2125: [(set_attr "type" "darith")
2126: (set_attr "mode" "SI")
2127: (set_attr "length" "12")])
2128:
2129:
2130: (define_insn "ashldi3_internal2"
2131: [(set (match_operand:DI 0 "register_operand" "=d")
2132: (ashift:DI (match_operand:DI 1 "register_operand" "d")
2133: (match_operand:SI 2 "small_int" "IJK")))
2134: (clobber (match_operand:SI 3 "register_operand" "=d"))]
2135: "!TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
2136: "*
2137: {
2138: operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
2139: operands[4] = const0_rtx;
2140: return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
2141: }"
2142: [(set_attr "type" "darith")
2143: (set_attr "mode" "DI")
2144: (set_attr "length" "2")])
2145:
2146:
2147: (define_split
2148: [(set (match_operand:DI 0 "register_operand" "")
2149: (ashift:DI (match_operand:DI 1 "register_operand" "")
2150: (match_operand:SI 2 "small_int" "")))
2151: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 2152: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 2153: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2154: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2155: && (INTVAL (operands[2]) & 32) != 0"
2156:
2157: [(set (subreg:SI (match_dup 0) 1) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
2158: (set (subreg:SI (match_dup 0) 0) (const_int 0))]
2159:
2160: "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
2161:
2162:
2163: (define_split
2164: [(set (match_operand:DI 0 "register_operand" "")
2165: (ashift:DI (match_operand:DI 1 "register_operand" "")
2166: (match_operand:SI 2 "small_int" "")))
2167: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 2168: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 2169: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2170: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2171: && (INTVAL (operands[2]) & 32) != 0"
2172:
2173: [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
2174: (set (subreg:SI (match_dup 0) 1) (const_int 0))]
2175:
2176: "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
2177:
2178:
2179: (define_insn "ashldi3_internal3"
2180: [(set (match_operand:DI 0 "register_operand" "=d")
2181: (ashift:DI (match_operand:DI 1 "register_operand" "d")
2182: (match_operand:SI 2 "small_int" "IJK")))
2183: (clobber (match_operand:SI 3 "register_operand" "=d"))]
2184: "!TARGET_DEBUG_G_MODE
2185: && (INTVAL (operands[2]) & 63) < 32
2186: && (INTVAL (operands[2]) & 63) != 0"
2187: "*
2188: {
2189: int amount = INTVAL (operands[2]);
2190:
2191: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2192: operands[4] = const0_rtx;
2193: operands[5] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2194:
2195: return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
2196: }"
2197: [(set_attr "type" "darith")
2198: (set_attr "mode" "DI")
2199: (set_attr "length" "4")])
2200:
2201:
2202: (define_split
2203: [(set (match_operand:DI 0 "register_operand" "")
2204: (ashift:DI (match_operand:DI 1 "register_operand" "")
2205: (match_operand:SI 2 "small_int" "")))
2206: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 2207: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 2208: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2209: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2210: && (INTVAL (operands[2]) & 63) < 32
2211: && (INTVAL (operands[2]) & 63) != 0"
2212:
2213: [(set (subreg:SI (match_dup 0) 1)
2214: (ashift:SI (subreg:SI (match_dup 1) 1)
2215: (match_dup 2)))
2216:
2217: (set (match_dup 3)
2218: (lshiftrt:SI (subreg:SI (match_dup 1) 0)
2219: (match_dup 4)))
2220:
2221: (set (subreg:SI (match_dup 0) 1)
2222: (ior:SI (subreg:SI (match_dup 0) 1)
2223: (match_dup 3)))
2224:
2225: (set (subreg:SI (match_dup 0) 0)
2226: (ashift:SI (subreg:SI (match_dup 1) 0)
2227: (match_dup 2)))]
2228: "
2229: {
2230: int amount = INTVAL (operands[2]);
2231: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2232: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2233: }")
2234:
2235:
2236: (define_split
2237: [(set (match_operand:DI 0 "register_operand" "")
2238: (ashift:DI (match_operand:DI 1 "register_operand" "")
2239: (match_operand:SI 2 "small_int" "")))
2240: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 2241: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 2242: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2243: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2244: && (INTVAL (operands[2]) & 63) < 32
2245: && (INTVAL (operands[2]) & 63) != 0"
2246:
2247: [(set (subreg:SI (match_dup 0) 0)
2248: (ashift:SI (subreg:SI (match_dup 1) 0)
2249: (match_dup 2)))
2250:
2251: (set (match_dup 3)
2252: (lshiftrt:SI (subreg:SI (match_dup 1) 1)
2253: (match_dup 4)))
2254:
2255: (set (subreg:SI (match_dup 0) 0)
2256: (ior:SI (subreg:SI (match_dup 0) 0)
2257: (match_dup 3)))
2258:
2259: (set (subreg:SI (match_dup 0) 1)
2260: (ashift:SI (subreg:SI (match_dup 1) 1)
2261: (match_dup 2)))]
2262: "
2263: {
2264: int amount = INTVAL (operands[2]);
2265: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2266: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2267: }")
2268:
2269:
2270: (define_insn "ashrsi3"
2271: [(set (match_operand:SI 0 "register_operand" "=d")
2272: (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
2273: (match_operand:SI 2 "arith_operand" "dI")))]
2274: ""
2275: "*
2276: {
2277: if (GET_CODE (operands[2]) == CONST_INT)
2278: operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
2279:
2280: return \"sra\\t%0,%1,%2\";
2281: }"
2282: [(set_attr "type" "arith")
2283: (set_attr "mode" "SI")
2284: (set_attr "length" "1")])
2285:
2286:
2287: (define_expand "ashrdi3"
2288: [(parallel [(set (match_operand:DI 0 "register_operand" "")
2289: (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
2290: (match_operand:SI 2 "arith_operand" "")))
2291: (clobber (match_dup 3))])]
2292: "!TARGET_DEBUG_G_MODE"
2293: "operands[3] = gen_reg_rtx (SImode);")
2294:
2295:
2296: (define_insn "ashrdi3_internal"
2297: [(set (match_operand:DI 0 "register_operand" "=d")
2298: (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2299: (match_operand:SI 2 "register_operand" "d")))
2300: (clobber (match_operand:SI 3 "register_operand" "=d"))]
2301: "!TARGET_DEBUG_G_MODE"
2302: "*
2303: {
2304: operands[4] = const0_rtx;
2305: dslots_jump_total += 3;
2306: dslots_jump_filled += 2;
2307:
2308: return \"sll\\t%3,%2,26\\n\\
2309: \\tbgez\\t%3,1f\\n\\
2310: \\tsra\\t%L0,%M1,%2\\n\\
2311: \\t%(b\\t3f\\n\\
2312: \\tsra\\t%M0,%M1,31%)\\n\\
2313: \\n\\
2314: 1:\\n\\
2315: \\t%(beq\\t%3,%z4,2f\\n\\
2316: \\tsrl\\t%L0,%L1,%2%)\\n\\
2317: \\n\\
2318: \\tsubu\\t%3,%z4,%2\\n\\
2319: \\tsll\\t%3,%M1,%3\\n\\
2320: \\tor\\t%L0,%L0,%3\\n\\
2321: 2:\\n\\
2322: \\tsra\\t%M0,%M1,%2\\n\\
2323: 3:\";
2324: }"
2325: [(set_attr "type" "darith")
2326: (set_attr "mode" "DI")
2327: (set_attr "length" "12")])
2328:
2329:
2330: (define_insn "ashrdi3_internal2"
2331: [(set (match_operand:DI 0 "register_operand" "=d")
2332: (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2333: (match_operand:SI 2 "small_int" "IJK")))
2334: (clobber (match_operand:SI 3 "register_operand" "=d"))]
2335: "!TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
2336: "*
2337: {
2338: operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
2339: return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
2340: }"
2341: [(set_attr "type" "darith")
2342: (set_attr "mode" "DI")
2343: (set_attr "length" "2")])
2344:
2345:
2346: (define_split
2347: [(set (match_operand:DI 0 "register_operand" "")
2348: (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
2349: (match_operand:SI 2 "small_int" "")))
2350: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 2351: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 2352: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2353: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2354: && (INTVAL (operands[2]) & 32) != 0"
2355:
2356: [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
2357: (set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (const_int 31)))]
2358:
2359: "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
2360:
2361:
2362: (define_split
2363: [(set (match_operand:DI 0 "register_operand" "")
2364: (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
2365: (match_operand:SI 2 "small_int" "")))
2366: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 2367: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 2368: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2369: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2370: && (INTVAL (operands[2]) & 32) != 0"
2371:
2372: [(set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
2373: (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
2374:
2375: "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
2376:
2377:
2378: (define_insn "ashrdi3_internal3"
2379: [(set (match_operand:DI 0 "register_operand" "=d")
2380: (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2381: (match_operand:SI 2 "small_int" "IJK")))
2382: (clobber (match_operand:SI 3 "register_operand" "=d"))]
2383: "!TARGET_DEBUG_G_MODE
2384: && (INTVAL (operands[2]) & 63) < 32
2385: && (INTVAL (operands[2]) & 63) != 0"
2386: "*
2387: {
2388: int amount = INTVAL (operands[2]);
2389:
2390: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2391: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2392:
2393: return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
2394: }"
2395: [(set_attr "type" "darith")
2396: (set_attr "mode" "DI")
2397: (set_attr "length" "4")])
2398:
2399:
2400: (define_split
2401: [(set (match_operand:DI 0 "register_operand" "")
2402: (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
2403: (match_operand:SI 2 "small_int" "")))
2404: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 2405: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 2406: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2407: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2408: && (INTVAL (operands[2]) & 63) < 32
2409: && (INTVAL (operands[2]) & 63) != 0"
2410:
2411: [(set (subreg:SI (match_dup 0) 0)
2412: (lshiftrt:SI (subreg:SI (match_dup 1) 0)
2413: (match_dup 2)))
2414:
2415: (set (match_dup 3)
2416: (ashift:SI (subreg:SI (match_dup 1) 1)
2417: (match_dup 4)))
2418:
2419: (set (subreg:SI (match_dup 0) 0)
2420: (ior:SI (subreg:SI (match_dup 0) 0)
2421: (match_dup 3)))
2422:
2423: (set (subreg:SI (match_dup 0) 1)
2424: (ashiftrt:SI (subreg:SI (match_dup 1) 1)
2425: (match_dup 2)))]
2426: "
2427: {
2428: int amount = INTVAL (operands[2]);
2429: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2430: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2431: }")
2432:
2433:
2434: (define_split
2435: [(set (match_operand:DI 0 "register_operand" "")
2436: (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
2437: (match_operand:SI 2 "small_int" "")))
2438: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 2439: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 2440: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2441: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2442: && (INTVAL (operands[2]) & 63) < 32
2443: && (INTVAL (operands[2]) & 63) != 0"
2444:
2445: [(set (subreg:SI (match_dup 0) 1)
2446: (lshiftrt:SI (subreg:SI (match_dup 1) 1)
2447: (match_dup 2)))
2448:
2449: (set (match_dup 3)
2450: (ashift:SI (subreg:SI (match_dup 1) 0)
2451: (match_dup 4)))
2452:
2453: (set (subreg:SI (match_dup 0) 1)
2454: (ior:SI (subreg:SI (match_dup 0) 1)
2455: (match_dup 3)))
2456:
2457: (set (subreg:SI (match_dup 0) 0)
2458: (ashiftrt:SI (subreg:SI (match_dup 1) 0)
2459: (match_dup 2)))]
2460: "
2461: {
2462: int amount = INTVAL (operands[2]);
2463: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2464: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2465: }")
2466:
2467:
2468: (define_insn "lshrsi3"
2469: [(set (match_operand:SI 0 "register_operand" "=d")
2470: (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
2471: (match_operand:SI 2 "arith_operand" "dI")))]
2472: ""
2473: "*
2474: {
2475: if (GET_CODE (operands[2]) == CONST_INT)
2476: operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
2477:
2478: return \"srl\\t%0,%1,%2\";
2479: }"
2480: [(set_attr "type" "arith")
2481: (set_attr "mode" "SI")
2482: (set_attr "length" "1")])
2483:
2484:
2485: (define_expand "lshrdi3"
2486: [(parallel [(set (match_operand:DI 0 "register_operand" "")
2487: (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
2488: (match_operand:SI 2 "arith_operand" "")))
2489: (clobber (match_dup 3))])]
2490: "!TARGET_DEBUG_G_MODE"
2491: "operands[3] = gen_reg_rtx (SImode);")
2492:
2493:
2494: (define_insn "lshrdi3_internal"
2495: [(set (match_operand:DI 0 "register_operand" "=&d")
2496: (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2497: (match_operand:SI 2 "register_operand" "d")))
2498: (clobber (match_operand:SI 3 "register_operand" "=d"))]
2499: "!TARGET_DEBUG_G_MODE"
2500: "*
2501: {
2502: operands[4] = const0_rtx;
2503: dslots_jump_total += 3;
2504: dslots_jump_filled += 2;
2505:
2506: return \"sll\\t%3,%2,26\\n\\
2507: \\tbgez\\t%3,1f\\n\\
2508: \\tsrl\\t%L0,%M1,%2\\n\\
2509: \\t%(b\\t3f\\n\\
2510: \\tmove\\t%M0,%z4%)\\n\\
2511: \\n\\
2512: 1:\\n\\
2513: \\t%(beq\\t%3,%z4,2f\\n\\
2514: \\tsrl\\t%L0,%L1,%2%)\\n\\
2515: \\n\\
2516: \\tsubu\\t%3,%z4,%2\\n\\
2517: \\tsll\\t%3,%M1,%3\\n\\
2518: \\tor\\t%L0,%L0,%3\\n\\
2519: 2:\\n\\
2520: \\tsrl\\t%M0,%M1,%2\\n\\
2521: 3:\";
2522: }"
2523: [(set_attr "type" "darith")
2524: (set_attr "mode" "DI")
2525: (set_attr "length" "12")])
2526:
2527:
2528: (define_insn "lshrdi3_internal2"
2529: [(set (match_operand:DI 0 "register_operand" "=d")
2530: (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2531: (match_operand:SI 2 "small_int" "IJK")))
2532: (clobber (match_operand:SI 3 "register_operand" "=d"))]
2533: "!TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
2534: "*
2535: {
2536: operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
2537: operands[4] = const0_rtx;
2538: return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
2539: }"
2540: [(set_attr "type" "darith")
2541: (set_attr "mode" "DI")
2542: (set_attr "length" "2")])
2543:
2544:
2545: (define_split
2546: [(set (match_operand:DI 0 "register_operand" "")
2547: (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
2548: (match_operand:SI 2 "small_int" "")))
2549: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 2550: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 2551: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2552: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2553: && (INTVAL (operands[2]) & 32) != 0"
2554:
2555: [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
2556: (set (subreg:SI (match_dup 0) 1) (const_int 0))]
2557:
2558: "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
2559:
2560:
2561: (define_split
2562: [(set (match_operand:DI 0 "register_operand" "")
2563: (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
2564: (match_operand:SI 2 "small_int" "")))
2565: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 2566: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 2567: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2568: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2569: && (INTVAL (operands[2]) & 32) != 0"
2570:
2571: [(set (subreg:SI (match_dup 0) 1) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
2572: (set (subreg:SI (match_dup 0) 0) (const_int 0))]
2573:
2574: "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
2575:
2576:
2577: (define_insn "lshrdi3_internal3"
2578: [(set (match_operand:DI 0 "register_operand" "=d")
2579: (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2580: (match_operand:SI 2 "small_int" "IJK")))
2581: (clobber (match_operand:SI 3 "register_operand" "=d"))]
2582: "!TARGET_DEBUG_G_MODE
2583: && (INTVAL (operands[2]) & 63) < 32
2584: && (INTVAL (operands[2]) & 63) != 0"
2585: "*
2586: {
2587: int amount = INTVAL (operands[2]);
2588:
2589: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2590: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2591:
2592: return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
2593: }"
2594: [(set_attr "type" "darith")
2595: (set_attr "mode" "DI")
2596: (set_attr "length" "4")])
2597:
2598:
2599: (define_split
2600: [(set (match_operand:DI 0 "register_operand" "")
2601: (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
2602: (match_operand:SI 2 "small_int" "")))
2603: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 2604: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 2605: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2606: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2607: && (INTVAL (operands[2]) & 63) < 32
2608: && (INTVAL (operands[2]) & 63) != 0"
2609:
2610: [(set (subreg:SI (match_dup 0) 0)
2611: (lshiftrt:SI (subreg:SI (match_dup 1) 0)
2612: (match_dup 2)))
2613:
2614: (set (match_dup 3)
2615: (ashift:SI (subreg:SI (match_dup 1) 1)
2616: (match_dup 4)))
2617:
2618: (set (subreg:SI (match_dup 0) 0)
2619: (ior:SI (subreg:SI (match_dup 0) 0)
2620: (match_dup 3)))
2621:
2622: (set (subreg:SI (match_dup 0) 1)
2623: (lshiftrt:SI (subreg:SI (match_dup 1) 1)
2624: (match_dup 2)))]
2625: "
2626: {
2627: int amount = INTVAL (operands[2]);
2628: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2629: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2630: }")
2631:
2632:
2633: (define_split
2634: [(set (match_operand:DI 0 "register_operand" "")
2635: (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
2636: (match_operand:SI 2 "small_int" "")))
2637: (clobber (match_operand:SI 3 "register_operand" ""))]
1.1.1.3 ! root 2638: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1.1 root 2639: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2640: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2641: && (INTVAL (operands[2]) & 63) < 32
2642: && (INTVAL (operands[2]) & 63) != 0"
2643:
2644: [(set (subreg:SI (match_dup 0) 1)
2645: (lshiftrt:SI (subreg:SI (match_dup 1) 1)
2646: (match_dup 2)))
2647:
2648: (set (match_dup 3)
2649: (ashift:SI (subreg:SI (match_dup 1) 0)
2650: (match_dup 4)))
2651:
2652: (set (subreg:SI (match_dup 0) 1)
2653: (ior:SI (subreg:SI (match_dup 0) 1)
2654: (match_dup 3)))
2655:
2656: (set (subreg:SI (match_dup 0) 0)
2657: (lshiftrt:SI (subreg:SI (match_dup 1) 0)
2658: (match_dup 2)))]
2659: "
2660: {
2661: int amount = INTVAL (operands[2]);
2662: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2663: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2664: }")
2665:
2666:
2667: ;;
2668: ;; ....................
2669: ;;
2670: ;; COMPARISONS
2671: ;;
2672: ;; ....................
2673:
2674: ;; Flow here is rather complex:
2675: ;;
2676: ;; 1) The cmp{si,sf,df} routine is called. It deposits the
2677: ;; arguments into the branch_cmp array, and the type into
2678: ;; branch_type. No RTL is generated.
2679: ;;
2680: ;; 2) The appropriate branch define_expand is called, which then
2681: ;; creates the appropriate RTL for the comparison and branch.
2682: ;; Different CC modes are used, based on what type of branch is
2683: ;; done, so that we can constrain things appropriately. There
2684: ;; are assumptions in the rest of GCC that break if we fold the
2685: ;; operands into the branchs for integer operations, and use cc0
1.1.1.3 ! root 2686: ;; for floating point, so we use the fp status register instead.
! 2687: ;; If needed, an appropriate temporary is created to hold the
! 2688: ;; of the integer compare.
1.1 root 2689:
2690: (define_expand "cmpsi"
2691: [(set (cc0)
2692: (compare:CC (match_operand:SI 0 "register_operand" "")
2693: (match_operand:SI 1 "arith_operand" "")))]
2694: ""
2695: "
2696: {
2697: if (operands[0]) /* avoid unused code message */
2698: {
2699: branch_cmp[0] = operands[0];
2700: branch_cmp[1] = operands[1];
2701: branch_type = CMP_SI;
2702: DONE;
2703: }
2704: }")
2705:
2706: (define_expand "tstsi"
2707: [(set (cc0)
2708: (match_operand:SI 0 "register_operand" ""))]
2709: ""
2710: "
2711: {
2712: if (operands[0]) /* avoid unused code message */
2713: {
2714: branch_cmp[0] = operands[0];
2715: branch_cmp[1] = const0_rtx;
2716: branch_type = CMP_SI;
2717: DONE;
2718: }
2719: }")
2720:
2721: (define_expand "cmpdf"
2722: [(set (cc0)
2723: (compare:CC_FP (match_operand:DF 0 "register_operand" "")
2724: (match_operand:DF 1 "register_operand" "")))]
2725: "TARGET_HARD_FLOAT"
2726: "
2727: {
2728: if (operands[0]) /* avoid unused code message */
2729: {
2730: branch_cmp[0] = operands[0];
2731: branch_cmp[1] = operands[1];
2732: branch_type = CMP_DF;
2733: DONE;
2734: }
2735: }")
2736:
2737: (define_expand "cmpsf"
2738: [(set (cc0)
2739: (compare:CC_FP (match_operand:SF 0 "register_operand" "")
2740: (match_operand:SF 1 "register_operand" "")))]
2741: "TARGET_HARD_FLOAT"
2742: "
2743: {
2744: if (operands[0]) /* avoid unused code message */
2745: {
2746: branch_cmp[0] = operands[0];
2747: branch_cmp[1] = operands[1];
2748: branch_type = CMP_SF;
2749: DONE;
2750: }
2751: }")
2752:
2753:
2754: ;;
2755: ;; ....................
2756: ;;
2757: ;; CONDITIONAL BRANCHES
2758: ;;
2759: ;; ....................
2760:
1.1.1.3 ! root 2761: (define_insn "branch_fp_ne"
1.1 root 2762: [(set (pc)
1.1.1.3 ! root 2763: (if_then_else (ne:CC_FP (reg:CC_FP 66)
! 2764: (const_int 0))
! 2765: (match_operand 0 "pc_or_label_operand" "")
! 2766: (match_operand 1 "pc_or_label_operand" "")))]
1.1 root 2767: ""
2768: "*
2769: {
2770: mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
1.1.1.3 ! root 2771: return (operands[0] != pc_rtx) ? \"%*bc1t%?\\t%0\" : \"%*bc1f%?\\t%1\";
1.1 root 2772: }"
2773: [(set_attr "type" "branch")
2774: (set_attr "mode" "none")
1.1.1.3 ! root 2775: (set_attr "length" "1")])
1.1 root 2776:
1.1.1.3 ! root 2777: (define_insn "branch_fp_ne_rev"
1.1 root 2778: [(set (pc)
1.1.1.3 ! root 2779: (if_then_else (ne:CC_REV_FP (reg:CC_REV_FP 66)
! 2780: (const_int 0))
! 2781: (match_operand 0 "pc_or_label_operand" "")
! 2782: (match_operand 1 "pc_or_label_operand" "")))]
1.1 root 2783: ""
2784: "*
2785: {
2786: mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
1.1.1.3 ! root 2787: return (operands[0] != pc_rtx) ? \"%*bc1f%?\\t%0\" : \"%*bc1t%?\\t%1\";
1.1 root 2788: }"
2789: [(set_attr "type" "branch")
2790: (set_attr "mode" "none")
1.1.1.3 ! root 2791: (set_attr "length" "1")])
1.1 root 2792:
1.1.1.3 ! root 2793: (define_insn "branch_fp_eq"
1.1 root 2794: [(set (pc)
1.1.1.3 ! root 2795: (if_then_else (eq:CC_FP (reg:CC_FP 66)
! 2796: (const_int 0))
! 2797: (match_operand 0 "pc_or_label_operand" "")
! 2798: (match_operand 1 "pc_or_label_operand" "")))]
1.1 root 2799: ""
2800: "*
2801: {
2802: mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
1.1.1.3 ! root 2803: return (operands[0] != pc_rtx) ? \"%*bc1f%?\\t%0\" : \"%*bc1t%?\\t%1\";
1.1 root 2804: }"
2805: [(set_attr "type" "branch")
2806: (set_attr "mode" "none")
2807: (set_attr "length" "1")])
2808:
1.1.1.3 ! root 2809: (define_insn "branch_fp_eq_rev"
1.1 root 2810: [(set (pc)
1.1.1.3 ! root 2811: (if_then_else (eq:CC_REV_FP (reg:CC_REV_FP 66)
! 2812: (const_int 0))
! 2813: (match_operand 0 "pc_or_label_operand" "")
! 2814: (match_operand 1 "pc_or_label_operand" "")))]
1.1 root 2815: ""
2816: "*
2817: {
2818: mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
1.1.1.3 ! root 2819: return (operands[0] != pc_rtx) ? \"%*bc1t%?\\t%0\" : \"%*bc1f%?\\t%1\";
1.1 root 2820: }"
2821: [(set_attr "type" "branch")
2822: (set_attr "mode" "none")
2823: (set_attr "length" "1")])
2824:
1.1.1.3 ! root 2825:
! 2826: (define_insn "branch_zero"
1.1 root 2827: [(set (pc)
1.1.1.3 ! root 2828: (if_then_else (match_operator:SI 0 "cmp_op"
! 2829: [(match_operand:SI 1 "arith32_operand" "rn")
! 2830: (const_int 0)])
! 2831: (match_operand 2 "pc_or_label_operand" "")
! 2832: (match_operand 3 "pc_or_label_operand" "")))]
1.1 root 2833: ""
2834: "*
2835: {
2836: mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2837:
1.1.1.3 ! root 2838: /* Handle places where CSE has folded a constant into the register operand. */
! 2839: if (GET_CODE (operands[1]) == CONST_INT)
1.1 root 2840: {
1.1.1.3 ! root 2841: int value = INTVAL (operands[1]);
! 2842: int truth = 0;
! 2843:
! 2844: switch (GET_CODE (operands[0]))
! 2845: {
! 2846: default: abort ();
! 2847: case EQ: truth = (value == 0); break;
! 2848: case NE: truth = (value != 0); break;
! 2849: case GT: truth = (value > 0); break;
! 2850: case GE: truth = (value >= 0); break;
! 2851: case LT: truth = (value < 0); break;
! 2852: case LE: truth = (value <= 0); break;
! 2853: case GTU: truth = (((unsigned)value) > 0); break;
! 2854: case GEU: truth = 1; break;
! 2855: case LTU: truth = 0; break;
! 2856: case LEU: truth = (((unsigned)value) <= 0); break;
! 2857: }
! 2858:
! 2859: if (operands[2] != pc_rtx)
! 2860: return (truth) ? \"%*beq%?\\t%.,%.,%2\" : \"%*bne%?\\t%.,%.,%2\";
! 2861: else
! 2862: return (truth) ? \"%*bne%?\\t%.,%.,%2\" : \"%*beq%?\\t%.,%.,%2\";
1.1 root 2863: }
2864:
1.1.1.3 ! root 2865: if (operands[2] != pc_rtx)
! 2866: { /* normal jump */
! 2867: switch (GET_CODE (operands[0]))
! 2868: {
! 2869: case EQ: return \"%*beq%?\\t%z1,%.,%2\";
! 2870: case NE: return \"%*bne%?\\t%z1,%.,%2\";
! 2871: case GTU: return \"%*bne%?\\t%z1,%.,%2\";
! 2872: case LEU: return \"%*beq%?\\t%z1,%.,%2\";
! 2873: case GEU: return \"%*j\\t%2\";
! 2874: case LTU: return \"#%*bltuz\\t%z1,%2\";
! 2875: }
1.1 root 2876:
1.1.1.3 ! root 2877: return \"%*b%C0z%?\\t%z1,%2\";
1.1 root 2878: }
1.1.1.3 ! root 2879: else
! 2880: { /* inverted jump */
! 2881: switch (GET_CODE (operands[0]))
! 2882: {
! 2883: case EQ: return \"%*bne%?\\t%z1,%.,%3\";
! 2884: case NE: return \"%*beq%?\\t%z1,%.,%3\";
! 2885: case GTU: return \"%*beq%?\\t%z1,%.,%3\";
! 2886: case LEU: return \"%*bne%?\\t%z1,%.,%3\";
! 2887: case GEU: return \"#%*bgeuz\\t%z1,%3\";
! 2888: case LTU: return \"%*j\\t%3\";
! 2889: }
1.1 root 2890:
1.1.1.3 ! root 2891: return \"%*b%N0z%?\\t%z1,%3\";
! 2892: }
1.1 root 2893: }"
2894: [(set_attr "type" "branch")
2895: (set_attr "mode" "none")
2896: (set_attr "length" "1")])
2897:
2898:
1.1.1.3 ! root 2899: (define_insn "branch_equality"
1.1 root 2900: [(set (pc)
1.1.1.3 ! root 2901: (if_then_else (match_operator:SI 0 "equality_op"
! 2902: [(match_operand:SI 1 "register_operand" "d")
! 2903: (match_operand:SI 2 "register_operand" "d")])
! 2904: (match_operand 3 "pc_or_label_operand" "")
! 2905: (match_operand 4 "pc_or_label_operand" "")))]
1.1 root 2906: ""
2907: "*
2908: {
2909: mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
1.1.1.3 ! root 2910: return (operands[3] != pc_rtx)
! 2911: ? \"%*b%C0%?\\t%z1,%z2,%3\"
! 2912: : \"%*b%N0%?\\t%z1,%z2,%4\";
1.1 root 2913: }"
2914: [(set_attr "type" "branch")
2915: (set_attr "mode" "none")
1.1.1.3 ! root 2916: (set_attr "length" "1")])
! 2917:
1.1 root 2918:
2919: (define_expand "beq"
2920: [(set (pc)
2921: (if_then_else (eq:CC_EQ (cc0)
2922: (const_int 0))
2923: (label_ref (match_operand 0 "" ""))
2924: (pc)))]
2925: ""
2926: "
2927: {
2928: if (operands[0]) /* avoid unused code warning */
2929: {
2930: gen_conditional_branch (operands, EQ);
2931: DONE;
2932: }
2933: }")
2934:
2935: (define_expand "bne"
2936: [(set (pc)
2937: (if_then_else (ne:CC_EQ (cc0)
2938: (const_int 0))
2939: (label_ref (match_operand 0 "" ""))
2940: (pc)))]
2941: ""
2942: "
2943: {
2944: if (operands[0]) /* avoid unused code warning */
2945: {
2946: gen_conditional_branch (operands, NE);
2947: DONE;
2948: }
2949: }")
2950:
2951: (define_expand "bgt"
2952: [(set (pc)
2953: (if_then_else (gt:CC (cc0)
2954: (const_int 0))
2955: (label_ref (match_operand 0 "" ""))
2956: (pc)))]
2957: ""
2958: "
2959: {
2960: if (operands[0]) /* avoid unused code warning */
2961: {
2962: gen_conditional_branch (operands, GT);
2963: DONE;
2964: }
2965: }")
2966:
2967: (define_expand "bge"
2968: [(set (pc)
2969: (if_then_else (ge:CC (cc0)
2970: (const_int 0))
2971: (label_ref (match_operand 0 "" ""))
2972: (pc)))]
2973: ""
2974: "
2975: {
2976: if (operands[0]) /* avoid unused code warning */
2977: {
2978: gen_conditional_branch (operands, GE);
2979: DONE;
2980: }
2981: }")
2982:
2983: (define_expand "blt"
2984: [(set (pc)
2985: (if_then_else (lt:CC (cc0)
2986: (const_int 0))
2987: (label_ref (match_operand 0 "" ""))
2988: (pc)))]
2989: ""
2990: "
2991: {
2992: if (operands[0]) /* avoid unused code warning */
2993: {
2994: gen_conditional_branch (operands, LT);
2995: DONE;
2996: }
2997: }")
2998:
2999: (define_expand "ble"
3000: [(set (pc)
3001: (if_then_else (le:CC (cc0)
3002: (const_int 0))
3003: (label_ref (match_operand 0 "" ""))
3004: (pc)))]
3005: ""
3006: "
3007: {
3008: if (operands[0]) /* avoid unused code warning */
3009: {
3010: gen_conditional_branch (operands, LE);
3011: DONE;
3012: }
3013: }")
3014:
3015: (define_expand "bgtu"
3016: [(set (pc)
3017: (if_then_else (gtu:CC (cc0)
3018: (const_int 0))
3019: (label_ref (match_operand 0 "" ""))
3020: (pc)))]
3021: ""
3022: "
3023: {
3024: if (operands[0]) /* avoid unused code warning */
3025: {
3026: gen_conditional_branch (operands, GTU);
3027: DONE;
3028: }
3029: }")
3030:
3031: (define_expand "bgeu"
3032: [(set (pc)
3033: (if_then_else (geu:CC (cc0)
3034: (const_int 0))
3035: (label_ref (match_operand 0 "" ""))
3036: (pc)))]
3037: ""
3038: "
3039: {
3040: if (operands[0]) /* avoid unused code warning */
3041: {
3042: gen_conditional_branch (operands, GEU);
3043: DONE;
3044: }
3045: }")
3046:
3047:
3048: (define_expand "bltu"
3049: [(set (pc)
3050: (if_then_else (ltu:CC (cc0)
3051: (const_int 0))
3052: (label_ref (match_operand 0 "" ""))
3053: (pc)))]
3054: ""
3055: "
3056: {
3057: if (operands[0]) /* avoid unused code warning */
3058: {
3059: gen_conditional_branch (operands, LTU);
3060: DONE;
3061: }
3062: }")
3063:
3064: (define_expand "bleu"
3065: [(set (pc)
3066: (if_then_else (leu:CC (cc0)
3067: (const_int 0))
3068: (label_ref (match_operand 0 "" ""))
3069: (pc)))]
3070: ""
3071: "
3072: {
3073: if (operands[0]) /* avoid unused code warning */
3074: {
3075: gen_conditional_branch (operands, LEU);
3076: DONE;
3077: }
3078: }")
3079:
3080:
3081: ;;
3082: ;; ....................
3083: ;;
3084: ;; SETTING A REGISTER FROM A COMPARISON
3085: ;;
3086: ;; ....................
3087:
3088: (define_expand "seq"
3089: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3090: (eq:SI (match_dup 1)
! 3091: (match_dup 2)))]
1.1 root 3092: ""
3093: "
3094: {
3095: extern rtx force_reg ();
3096:
3097: if (branch_type != CMP_SI)
3098: FAIL;
3099:
3100: /* set up operands from compare. */
3101: operands[1] = branch_cmp[0];
3102: operands[2] = branch_cmp[1];
3103:
1.1.1.3 ! root 3104: if (!TARGET_DEBUG_C_MODE)
! 3105: {
! 3106: gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
! 3107: DONE;
! 3108: }
! 3109:
1.1 root 3110: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
3111: operands[2] = force_reg (SImode, operands[2]);
3112:
3113: /* fall through and generate default code */
3114: }")
3115:
1.1.1.3 ! root 3116:
! 3117: (define_insn "seq_si_zero"
! 3118: [(set (match_operand:SI 0 "register_operand" "=d")
! 3119: (eq:SI (match_operand:SI 1 "register_operand" "d")
! 3120: (const_int 0)))]
1.1 root 3121: ""
1.1.1.3 ! root 3122: "sltu\\t%0,%1,1"
! 3123: [(set_attr "type" "arith")
! 3124: (set_attr "mode" "SI")
! 3125: (set_attr "length" "1")])
! 3126:
! 3127: (define_insn "seq_si"
! 3128: [(set (match_operand:SI 0 "register_operand" "=d,d")
! 3129: (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
! 3130: (match_operand:SI 2 "uns_arith_operand" "d,K")))]
! 3131: "TARGET_DEBUG_C_MODE"
1.1 root 3132: "@
3133: xor\\t%0,%1,%2\;sltu\\t%0,%0,1
1.1.1.3 ! root 3134: xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
! 3135: [(set_attr "type" "arith")
! 3136: (set_attr "mode" "SI")
! 3137: (set_attr "length" "2")])
1.1 root 3138:
3139: (define_split
3140: [(set (match_operand:SI 0 "register_operand" "")
1.1.1.3 ! root 3141: (eq:SI (match_operand:SI 1 "register_operand" "")
! 3142: (match_operand:SI 2 "uns_arith_operand" "")))]
! 3143: "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
! 3144: && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
1.1 root 3145: [(set (match_dup 0)
3146: (xor:SI (match_dup 1)
3147: (match_dup 2)))
3148: (set (match_dup 0)
1.1.1.3 ! root 3149: (ltu:SI (match_dup 0)
1.1 root 3150: (const_int 1)))]
3151: "")
3152:
3153: (define_expand "sne"
3154: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3155: (ne:SI (match_dup 1)
! 3156: (match_dup 2)))]
1.1 root 3157: ""
3158: "
3159: {
3160: extern rtx force_reg ();
3161:
3162: if (branch_type != CMP_SI)
3163: FAIL;
3164:
3165: /* set up operands from compare. */
3166: operands[1] = branch_cmp[0];
3167: operands[2] = branch_cmp[1];
3168:
1.1.1.3 ! root 3169: if (!TARGET_DEBUG_C_MODE)
! 3170: {
! 3171: gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
! 3172: DONE;
! 3173: }
! 3174:
1.1 root 3175: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
3176: operands[2] = force_reg (SImode, operands[2]);
3177:
3178: /* fall through and generate default code */
3179: }")
3180:
1.1.1.3 ! root 3181: (define_insn "sne_si_zero"
! 3182: [(set (match_operand:SI 0 "register_operand" "=d")
! 3183: (ne:SI (match_operand:SI 1 "register_operand" "d")
! 3184: (const_int 0)))]
1.1 root 3185: ""
1.1.1.3 ! root 3186: "sltu\\t%0,%.,%1"
! 3187: [(set_attr "type" "arith")
! 3188: (set_attr "mode" "SI")
! 3189: (set_attr "length" "1")])
1.1 root 3190:
1.1.1.3 ! root 3191: (define_insn "sne_si"
! 3192: [(set (match_operand:SI 0 "register_operand" "=d,d")
! 3193: (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
! 3194: (match_operand:SI 2 "uns_arith_operand" "d,K")))]
! 3195: "TARGET_DEBUG_C_MODE"
! 3196: "@
! 3197: xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
! 3198: xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
! 3199: [(set_attr "type" "arith")
! 3200: (set_attr "mode" "SI")
! 3201: (set_attr "length" "2")])
1.1 root 3202:
3203: (define_split
3204: [(set (match_operand:SI 0 "register_operand" "")
1.1.1.3 ! root 3205: (ne:SI (match_operand:SI 1 "register_operand" "")
! 3206: (match_operand:SI 2 "uns_arith_operand" "")))]
! 3207: "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
! 3208: && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
1.1 root 3209: [(set (match_dup 0)
3210: (xor:SI (match_dup 1)
3211: (match_dup 2)))
3212: (set (match_dup 0)
1.1.1.3 ! root 3213: (gtu:SI (match_dup 0)
1.1 root 3214: (const_int 0)))]
3215: "")
3216:
3217: (define_expand "sgt"
3218: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3219: (gt:SI (match_dup 1)
1.1 root 3220: (match_dup 2)))]
3221: ""
3222: "
3223: {
3224: extern rtx force_reg ();
3225:
3226: if (branch_type != CMP_SI)
3227: FAIL;
3228:
3229: /* set up operands from compare. */
3230: operands[1] = branch_cmp[0];
3231: operands[2] = branch_cmp[1];
3232:
1.1.1.3 ! root 3233: if (!TARGET_DEBUG_C_MODE)
! 3234: {
! 3235: gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
! 3236: DONE;
! 3237: }
! 3238:
1.1 root 3239: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
3240: operands[2] = force_reg (SImode, operands[2]);
3241:
3242: /* fall through and generate default code */
3243: }")
3244:
3245: (define_insn "sgt_si"
3246: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3247: (gt:SI (match_operand:SI 1 "register_operand" "d")
1.1 root 3248: (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
3249: ""
3250: "slt\\t%0,%z2,%1"
3251: [(set_attr "type" "arith")
3252: (set_attr "mode" "SI")
3253: (set_attr "length" "1")])
3254:
3255: (define_expand "sge"
3256: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3257: (ge:SI (match_dup 1)
1.1 root 3258: (match_dup 2)))]
3259: ""
3260: "
3261: {
3262: if (branch_type != CMP_SI)
3263: FAIL;
3264:
3265: /* set up operands from compare. */
3266: operands[1] = branch_cmp[0];
3267: operands[2] = branch_cmp[1];
3268:
1.1.1.3 ! root 3269: if (!TARGET_DEBUG_C_MODE)
! 3270: {
! 3271: gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
! 3272: DONE;
! 3273: }
! 3274:
1.1 root 3275: /* fall through and generate default code */
3276: }")
3277:
3278: (define_insn "sge_si"
3279: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3280: (ge:SI (match_operand:SI 1 "register_operand" "d")
1.1 root 3281: (match_operand:SI 2 "arith_operand" "dI")))]
1.1.1.3 ! root 3282: "TARGET_DEBUG_C_MODE"
1.1 root 3283: "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
3284: [(set_attr "type" "arith")
3285: (set_attr "mode" "SI")
3286: (set_attr "length" "2")])
3287:
3288: (define_split
3289: [(set (match_operand:SI 0 "register_operand" "")
1.1.1.3 ! root 3290: (ge:SI (match_operand:SI 1 "register_operand" "")
1.1 root 3291: (match_operand:SI 2 "arith_operand" "")))]
1.1.1.3 ! root 3292: "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
1.1 root 3293: [(set (match_dup 0)
1.1.1.3 ! root 3294: (lt:SI (match_dup 1)
1.1 root 3295: (match_dup 2)))
3296: (set (match_dup 0)
3297: (xor:SI (match_dup 0)
3298: (const_int 1)))]
3299: "")
3300:
3301: (define_expand "slt"
3302: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3303: (lt:SI (match_dup 1)
1.1 root 3304: (match_dup 2)))]
3305: ""
3306: "
3307: {
3308: if (branch_type != CMP_SI)
3309: FAIL;
3310:
3311: /* set up operands from compare. */
3312: operands[1] = branch_cmp[0];
3313: operands[2] = branch_cmp[1];
3314:
1.1.1.3 ! root 3315: if (!TARGET_DEBUG_C_MODE)
! 3316: {
! 3317: gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
! 3318: DONE;
! 3319: }
! 3320:
1.1 root 3321: /* fall through and generate default code */
3322: }")
3323:
3324: (define_insn "slt_si"
3325: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3326: (lt:SI (match_operand:SI 1 "register_operand" "d")
1.1 root 3327: (match_operand:SI 2 "arith_operand" "dI")))]
3328: ""
3329: "slt\\t%0,%1,%2"
3330: [(set_attr "type" "arith")
3331: (set_attr "mode" "SI")
3332: (set_attr "length" "1")])
3333:
3334: (define_expand "sle"
3335: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3336: (le:SI (match_dup 1)
1.1 root 3337: (match_dup 2)))]
3338: ""
3339: "
3340: {
3341: extern rtx force_reg ();
3342:
3343: if (branch_type != CMP_SI)
3344: FAIL;
3345:
3346: /* set up operands from compare. */
3347: operands[1] = branch_cmp[0];
3348: operands[2] = branch_cmp[1];
3349:
1.1.1.3 ! root 3350: if (!TARGET_DEBUG_C_MODE)
! 3351: {
! 3352: gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
! 3353: DONE;
! 3354: }
! 3355:
1.1 root 3356: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
3357: operands[2] = force_reg (SImode, operands[2]);
3358:
3359: /* fall through and generate default code */
3360: }")
3361:
1.1.1.3 ! root 3362: (define_insn "sle_si_const"
! 3363: [(set (match_operand:SI 0 "register_operand" "=d")
! 3364: (le:SI (match_operand:SI 1 "register_operand" "d")
! 3365: (match_operand:SI 2 "small_int" "I")))]
! 3366: "INTVAL (operands[2]) < 32767"
! 3367: "*
! 3368: {
! 3369: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
! 3370: return \"slt\\t%0,%1,%2\";
! 3371: }"
! 3372: [(set_attr "type" "arith")
! 3373: (set_attr "mode" "SI")
! 3374: (set_attr "length" "1")])
! 3375:
! 3376: (define_insn "sle_si_reg"
! 3377: [(set (match_operand:SI 0 "register_operand" "=d")
! 3378: (le:SI (match_operand:SI 1 "register_operand" "d")
! 3379: (match_operand:SI 2 "register_operand" "d")))]
! 3380: "TARGET_DEBUG_C_MODE"
! 3381: "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
! 3382: [(set_attr "type" "arith")
! 3383: (set_attr "mode" "SI")
! 3384: (set_attr "length" "2")])
1.1 root 3385:
3386: (define_split
3387: [(set (match_operand:SI 0 "register_operand" "")
1.1.1.3 ! root 3388: (le:SI (match_operand:SI 1 "register_operand" "")
1.1 root 3389: (match_operand:SI 2 "register_operand" "")))]
1.1.1.3 ! root 3390: "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
1.1 root 3391: [(set (match_dup 0)
1.1.1.3 ! root 3392: (lt:SI (match_dup 2)
1.1 root 3393: (match_dup 1)))
3394: (set (match_dup 0)
3395: (xor:SI (match_dup 0)
3396: (const_int 1)))]
3397: "")
3398:
3399: (define_expand "sgtu"
3400: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3401: (gtu:SI (match_dup 1)
1.1 root 3402: (match_dup 2)))]
3403: ""
3404: "
3405: {
3406: extern rtx force_reg ();
3407:
3408: if (branch_type != CMP_SI)
3409: FAIL;
3410:
3411: /* set up operands from compare. */
3412: operands[1] = branch_cmp[0];
3413: operands[2] = branch_cmp[1];
3414:
1.1.1.3 ! root 3415: if (!TARGET_DEBUG_C_MODE)
! 3416: {
! 3417: gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
! 3418: DONE;
! 3419: }
! 3420:
1.1 root 3421: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
3422: operands[2] = force_reg (SImode, operands[2]);
3423:
3424: /* fall through and generate default code */
3425: }")
3426:
3427: (define_insn "sgtu_si"
3428: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3429: (gtu:SI (match_operand:SI 1 "register_operand" "d")
1.1 root 3430: (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
3431: ""
3432: "sltu\\t%0,%z2,%1"
3433: [(set_attr "type" "arith")
3434: (set_attr "mode" "SI")
3435: (set_attr "length" "1")])
3436:
3437: (define_expand "sgeu"
3438: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3439: (geu:SI (match_dup 1)
1.1 root 3440: (match_dup 2)))]
3441: ""
3442: "
3443: {
3444: if (branch_type != CMP_SI)
3445: FAIL;
3446:
3447: /* set up operands from compare. */
3448: operands[1] = branch_cmp[0];
3449: operands[2] = branch_cmp[1];
3450:
1.1.1.3 ! root 3451: if (!TARGET_DEBUG_C_MODE)
! 3452: {
! 3453: gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
! 3454: DONE;
! 3455: }
! 3456:
1.1 root 3457: /* fall through and generate default code */
3458: }")
3459:
3460: (define_insn "sgeu_si"
3461: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3462: (geu:SI (match_operand:SI 1 "register_operand" "d")
1.1 root 3463: (match_operand:SI 2 "arith_operand" "dI")))]
1.1.1.3 ! root 3464: "TARGET_DEBUG_C_MODE"
1.1 root 3465: "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
3466: [(set_attr "type" "arith")
3467: (set_attr "mode" "SI")
3468: (set_attr "length" "2")])
3469:
3470: (define_split
3471: [(set (match_operand:SI 0 "register_operand" "")
1.1.1.3 ! root 3472: (geu:SI (match_operand:SI 1 "register_operand" "")
1.1 root 3473: (match_operand:SI 2 "arith_operand" "")))]
1.1.1.3 ! root 3474: "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
1.1 root 3475: [(set (match_dup 0)
1.1.1.3 ! root 3476: (ltu:SI (match_dup 1)
1.1 root 3477: (match_dup 2)))
3478: (set (match_dup 0)
3479: (xor:SI (match_dup 0)
3480: (const_int 1)))]
3481: "")
3482:
3483: (define_expand "sltu"
3484: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3485: (ltu:SI (match_dup 1)
1.1 root 3486: (match_dup 2)))]
3487: ""
3488: "
3489: {
3490: if (branch_type != CMP_SI)
3491: FAIL;
3492:
3493: /* set up operands from compare. */
3494: operands[1] = branch_cmp[0];
3495: operands[2] = branch_cmp[1];
3496:
1.1.1.3 ! root 3497: if (!TARGET_DEBUG_C_MODE)
! 3498: {
! 3499: gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
! 3500: DONE;
! 3501: }
! 3502:
1.1 root 3503: /* fall through and generate default code */
3504: }")
3505:
3506: (define_insn "sltu_si"
3507: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3508: (ltu:SI (match_operand:SI 1 "register_operand" "d")
1.1 root 3509: (match_operand:SI 2 "arith_operand" "dI")))]
3510: ""
3511: "sltu\\t%0,%1,%2"
3512: [(set_attr "type" "arith")
3513: (set_attr "mode" "SI")
3514: (set_attr "length" "1")])
3515:
3516: (define_expand "sleu"
3517: [(set (match_operand:SI 0 "register_operand" "=d")
1.1.1.3 ! root 3518: (leu:SI (match_dup 1)
1.1 root 3519: (match_dup 2)))]
3520: ""
3521: "
3522: {
3523: extern rtx force_reg ();
3524:
3525: if (branch_type != CMP_SI)
3526: FAIL;
3527:
3528: /* set up operands from compare. */
3529: operands[1] = branch_cmp[0];
3530: operands[2] = branch_cmp[1];
3531:
1.1.1.3 ! root 3532: if (!TARGET_DEBUG_C_MODE)
! 3533: {
! 3534: gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
! 3535: DONE;
! 3536: }
! 3537:
1.1 root 3538: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
3539: operands[2] = force_reg (SImode, operands[2]);
3540:
3541: /* fall through and generate default code */
3542: }")
3543:
1.1.1.3 ! root 3544: (define_insn "sleu_si_const"
! 3545: [(set (match_operand:SI 0 "register_operand" "=d")
! 3546: (leu:SI (match_operand:SI 1 "register_operand" "d")
! 3547: (match_operand:SI 2 "small_int" "I")))]
! 3548: "INTVAL (operands[2]) < 32767"
! 3549: "*
! 3550: {
! 3551: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
! 3552: return \"sltu\\t%0,%1,%2\";
! 3553: }"
! 3554: [(set_attr "type" "arith")
! 3555: (set_attr "mode" "SI")
! 3556: (set_attr "length" "1")])
! 3557:
! 3558: (define_insn "sleu_si_reg"
! 3559: [(set (match_operand:SI 0 "register_operand" "=d")
! 3560: (leu:SI (match_operand:SI 1 "register_operand" "d")
! 3561: (match_operand:SI 2 "register_operand" "d")))]
! 3562: "TARGET_DEBUG_C_MODE"
! 3563: "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
! 3564: [(set_attr "type" "arith")
! 3565: (set_attr "mode" "SI")
! 3566: (set_attr "length" "2")])
1.1 root 3567:
3568: (define_split
3569: [(set (match_operand:SI 0 "register_operand" "")
1.1.1.3 ! root 3570: (leu:SI (match_operand:SI 1 "register_operand" "")
1.1 root 3571: (match_operand:SI 2 "register_operand" "")))]
1.1.1.3 ! root 3572: "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
1.1 root 3573: [(set (match_dup 0)
1.1.1.3 ! root 3574: (ltu:SI (match_dup 2)
1.1 root 3575: (match_dup 1)))
3576: (set (match_dup 0)
3577: (xor:SI (match_dup 0)
3578: (const_int 1)))]
3579: "")
3580:
3581:
3582: ;;
3583: ;; ....................
3584: ;;
1.1.1.3 ! root 3585: ;; FLOATING POINT COMPARISONS
! 3586: ;;
! 3587: ;; ....................
! 3588:
! 3589: (define_insn "seq_df"
! 3590: [(set (reg:CC_FP 66)
! 3591: (eq:CC_FP (match_operand:DF 0 "register_operand" "f")
! 3592: (match_operand:DF 1 "register_operand" "f")))]
! 3593: ""
! 3594: "*
! 3595: {
! 3596: rtx xoperands[10];
! 3597: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
! 3598: xoperands[1] = operands[0];
! 3599: xoperands[2] = operands[1];
! 3600:
! 3601: return mips_fill_delay_slot (\"c.eq.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
! 3602: }"
! 3603: [(set_attr "type" "fcmp")
! 3604: (set_attr "mode" "FPSW")
! 3605: (set_attr "length" "1")])
! 3606:
! 3607: (define_insn "sne_df"
! 3608: [(set (reg:CC_REV_FP 66)
! 3609: (ne:CC_REV_FP (match_operand:DF 0 "register_operand" "f")
! 3610: (match_operand:DF 1 "register_operand" "f")))]
! 3611: ""
! 3612: "*
! 3613: {
! 3614: rtx xoperands[10];
! 3615: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
! 3616: xoperands[1] = operands[0];
! 3617: xoperands[2] = operands[1];
! 3618:
! 3619: return mips_fill_delay_slot (\"c.eq.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
! 3620: }"
! 3621: [(set_attr "type" "fcmp")
! 3622: (set_attr "mode" "FPSW")
! 3623: (set_attr "length" "1")])
! 3624:
! 3625: (define_insn "slt_df"
! 3626: [(set (reg:CC_FP 66)
! 3627: (lt:CC_FP (match_operand:DF 0 "register_operand" "f")
! 3628: (match_operand:DF 1 "register_operand" "f")))]
! 3629: ""
! 3630: "*
! 3631: {
! 3632: rtx xoperands[10];
! 3633: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
! 3634: xoperands[1] = operands[0];
! 3635: xoperands[2] = operands[1];
! 3636:
! 3637: return mips_fill_delay_slot (\"c.lt.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
! 3638: }"
! 3639: [(set_attr "type" "fcmp")
! 3640: (set_attr "mode" "FPSW")
! 3641: (set_attr "length" "1")])
! 3642:
! 3643: (define_insn "sle_df"
! 3644: [(set (reg:CC_FP 66)
! 3645: (le:CC_FP (match_operand:DF 0 "register_operand" "f")
! 3646: (match_operand:DF 1 "register_operand" "f")))]
! 3647: ""
! 3648: "*
! 3649: {
! 3650: rtx xoperands[10];
! 3651: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
! 3652: xoperands[1] = operands[0];
! 3653: xoperands[2] = operands[1];
! 3654:
! 3655: return mips_fill_delay_slot (\"c.le.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
! 3656: }"
! 3657: [(set_attr "type" "fcmp")
! 3658: (set_attr "mode" "FPSW")
! 3659: (set_attr "length" "1")])
! 3660:
! 3661: (define_insn "sgt_df"
! 3662: [(set (reg:CC_FP 66)
! 3663: (gt:CC_FP (match_operand:DF 0 "register_operand" "f")
! 3664: (match_operand:DF 1 "register_operand" "f")))]
! 3665: ""
! 3666: "*
! 3667: {
! 3668: rtx xoperands[10];
! 3669: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
! 3670: xoperands[1] = operands[0];
! 3671: xoperands[2] = operands[1];
! 3672:
! 3673: return mips_fill_delay_slot (\"c.lt.d\\t%1,%0\", DELAY_FCMP, xoperands, insn);
! 3674: }"
! 3675: [(set_attr "type" "fcmp")
! 3676: (set_attr "mode" "FPSW")
! 3677: (set_attr "length" "1")])
! 3678:
! 3679: (define_insn "sge_df"
! 3680: [(set (reg:CC_FP 66)
! 3681: (ge:CC_FP (match_operand:DF 0 "register_operand" "f")
! 3682: (match_operand:DF 1 "register_operand" "f")))]
! 3683: ""
! 3684: "*
! 3685: {
! 3686: rtx xoperands[10];
! 3687: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
! 3688: xoperands[1] = operands[0];
! 3689: xoperands[2] = operands[1];
! 3690:
! 3691: return mips_fill_delay_slot (\"c.le.d\\t%1,%0\", DELAY_FCMP, xoperands, insn);
! 3692: }"
! 3693: [(set_attr "type" "fcmp")
! 3694: (set_attr "mode" "FPSW")
! 3695: (set_attr "length" "1")])
! 3696:
! 3697: (define_insn "seq_sf"
! 3698: [(set (reg:CC_FP 66)
! 3699: (eq:CC_FP (match_operand:SF 0 "register_operand" "f")
! 3700: (match_operand:SF 1 "register_operand" "f")))]
! 3701: ""
! 3702: "*
! 3703: {
! 3704: rtx xoperands[10];
! 3705: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
! 3706: xoperands[1] = operands[0];
! 3707: xoperands[2] = operands[1];
! 3708:
! 3709: return mips_fill_delay_slot (\"c.eq.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
! 3710: }"
! 3711: [(set_attr "type" "fcmp")
! 3712: (set_attr "mode" "FPSW")
! 3713: (set_attr "length" "1")])
! 3714:
! 3715: (define_insn "sne_sf"
! 3716: [(set (reg:CC_REV_FP 66)
! 3717: (ne:CC_REV_FP (match_operand:SF 0 "register_operand" "f")
! 3718: (match_operand:SF 1 "register_operand" "f")))]
! 3719: ""
! 3720: "*
! 3721: {
! 3722: rtx xoperands[10];
! 3723: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
! 3724: xoperands[1] = operands[0];
! 3725: xoperands[2] = operands[1];
! 3726:
! 3727: return mips_fill_delay_slot (\"c.eq.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
! 3728: }"
! 3729: [(set_attr "type" "fcmp")
! 3730: (set_attr "mode" "FPSW")
! 3731: (set_attr "length" "1")])
! 3732:
! 3733: (define_insn "slt_sf"
! 3734: [(set (reg:CC_FP 66)
! 3735: (lt:CC_FP (match_operand:SF 0 "register_operand" "f")
! 3736: (match_operand:SF 1 "register_operand" "f")))]
! 3737: ""
! 3738: "*
! 3739: {
! 3740: rtx xoperands[10];
! 3741: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
! 3742: xoperands[1] = operands[0];
! 3743: xoperands[2] = operands[1];
! 3744:
! 3745: return mips_fill_delay_slot (\"c.lt.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
! 3746: }"
! 3747: [(set_attr "type" "fcmp")
! 3748: (set_attr "mode" "FPSW")
! 3749: (set_attr "length" "1")])
! 3750:
! 3751: (define_insn "sle_sf"
! 3752: [(set (reg:CC_FP 66)
! 3753: (le:CC_FP (match_operand:SF 0 "register_operand" "f")
! 3754: (match_operand:SF 1 "register_operand" "f")))]
! 3755: ""
! 3756: "*
! 3757: {
! 3758: rtx xoperands[10];
! 3759: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
! 3760: xoperands[1] = operands[0];
! 3761: xoperands[2] = operands[1];
! 3762:
! 3763: return mips_fill_delay_slot (\"c.le.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
! 3764: }"
! 3765: [(set_attr "type" "fcmp")
! 3766: (set_attr "mode" "FPSW")
! 3767: (set_attr "length" "1")])
! 3768:
! 3769: (define_insn "sgt_sf"
! 3770: [(set (reg:CC_FP 66)
! 3771: (gt:CC_FP (match_operand:SF 0 "register_operand" "f")
! 3772: (match_operand:SF 1 "register_operand" "f")))]
! 3773: ""
! 3774: "*
! 3775: {
! 3776: rtx xoperands[10];
! 3777: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
! 3778: xoperands[1] = operands[0];
! 3779: xoperands[2] = operands[1];
! 3780:
! 3781: return mips_fill_delay_slot (\"c.lt.s\\t%1,%0\", DELAY_FCMP, xoperands, insn);
! 3782: }"
! 3783: [(set_attr "type" "fcmp")
! 3784: (set_attr "mode" "FPSW")
! 3785: (set_attr "length" "1")])
! 3786:
! 3787: (define_insn "sge_sf"
! 3788: [(set (reg:CC_FP 66)
! 3789: (ge:CC_FP (match_operand:SF 0 "register_operand" "f")
! 3790: (match_operand:SF 1 "register_operand" "f")))]
! 3791: ""
! 3792: "*
! 3793: {
! 3794: rtx xoperands[10];
! 3795: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
! 3796: xoperands[1] = operands[0];
! 3797: xoperands[2] = operands[1];
! 3798:
! 3799: return mips_fill_delay_slot (\"c.le.s\\t%1,%0\", DELAY_FCMP, xoperands, insn);
! 3800: }"
! 3801: [(set_attr "type" "fcmp")
! 3802: (set_attr "mode" "FPSW")
! 3803: (set_attr "length" "1")])
! 3804:
! 3805:
! 3806: ;;
! 3807: ;; ....................
! 3808: ;;
1.1 root 3809: ;; UNCONDITIONAL BRANCHES
3810: ;;
3811: ;; ....................
3812:
3813: ;; Unconditional branches.
3814:
3815: (define_insn "jump"
3816: [(set (pc)
3817: (label_ref (match_operand 0 "" "")))]
3818: ""
3819: "*
3820: {
3821: if (GET_CODE (operands[0]) == REG)
3822: return \"%*j\\t%0\";
3823: else
3824: return \"%*j\\t%l0\";
3825: }"
3826: [(set_attr "type" "jump")
3827: (set_attr "mode" "none")
3828: (set_attr "length" "1")])
3829:
3830: (define_insn "indirect_jump"
3831: [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
3832: ""
3833: "%*j\\t%0"
3834: [(set_attr "type" "jump")
3835: (set_attr "mode" "none")
3836: (set_attr "length" "1")])
3837:
3838: (define_insn "tablejump"
3839: [(set (pc)
3840: (match_operand:SI 0 "register_operand" "d"))
3841: (use (label_ref (match_operand 1 "" "")))]
3842: ""
3843: "%*j\\t%0"
3844: [(set_attr "type" "jump")
3845: (set_attr "mode" "none")
3846: (set_attr "length" "1")])
3847:
3848: ;; Function return, only allow after optimization, so that we can
3849: ;; eliminate jumps to jumps if no stack space is used.
3850:
3851: (define_insn "return"
3852: [(return)]
3853: "null_epilogue ()"
3854: "*
3855: {
3856: operands[0] = gen_rtx (REG, SImode, GP_REG_FIRST + 31);
3857: return \"%*j\\t%0\";
3858: }"
3859: [(set_attr "type" "jump")
3860: (set_attr "mode" "none")
3861: (set_attr "length" "1")])
3862:
3863:
3864: ;;
3865: ;; ....................
3866: ;;
3867: ;; FUNCTION CALLS
3868: ;;
3869: ;; ....................
3870:
3871: ;; calls.c now passes a third argument, make saber happy
3872:
3873: (define_expand "call"
1.1.1.3 ! root 3874: [(parallel [(call (match_operand 0 "memory_operand" "m")
1.1 root 3875: (match_operand 1 "" "i"))
3876: (clobber (match_operand 2 "" ""))])] ;; overwrite op2 with $31
3877: ""
3878: "
3879: {
3880: rtx addr;
3881:
3882: operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 31);
3883:
3884: addr = XEXP (operands[0], 0);
1.1.1.3 ! root 3885: if (GET_CODE (addr) != REG && !CONSTANT_ADDRESS_P (addr))
1.1 root 3886: XEXP (operands[0], 0) = force_reg (FUNCTION_MODE, addr);
3887: }")
3888:
3889: (define_insn "call_internal"
1.1.1.3 ! root 3890: [(call (match_operand 0 "memory_operand" "m")
1.1 root 3891: (match_operand 1 "" "i"))
3892: (clobber (match_operand:SI 2 "register_operand" "=d"))]
3893: ""
3894: "*
3895: {
3896: register rtx target = XEXP (operands[0], 0);
3897:
3898: if (GET_CODE (target) == SYMBOL_REF)
3899: return \"%*jal\\t%0\";
3900:
3901: else
3902: {
3903: operands[0] = target;
3904: operands[1] = gen_rtx (REG, SImode, GP_REG_FIRST + 31);
3905: return \"%*jal\\t%1,%0\";
3906: }
3907: }"
3908: [(set_attr "type" "call")
3909: (set_attr "mode" "none")
3910: (set_attr "length" "1")])
3911:
3912: ;; calls.c now passes a fourth argument, make saber happy
3913:
3914: (define_expand "call_value"
3915: [(parallel [(set (match_operand 0 "register_operand" "=df")
1.1.1.3 ! root 3916: (call (match_operand 1 "memory_operand" "m")
1.1 root 3917: (match_operand 2 "" "i")))
3918: (clobber (match_operand 3 "" ""))])] ;; overwrite op3 with $31
3919: ""
3920: "
3921: {
3922: rtx addr;
3923:
3924: operands[3] = gen_rtx (REG, SImode, GP_REG_FIRST + 31);
3925:
3926: addr = XEXP (operands[1], 0);
1.1.1.3 ! root 3927: if (GET_CODE (addr) != REG && !CONSTANT_ADDRESS_P (addr))
1.1 root 3928: XEXP (operands[1], 0) = force_reg (FUNCTION_MODE, addr);
3929: }")
3930:
3931: (define_insn "call_value_internal"
3932: [(set (match_operand 0 "register_operand" "=df")
1.1.1.3 ! root 3933: (call (match_operand 1 "memory_operand" "m")
1.1 root 3934: (match_operand 2 "" "i")))
3935: (clobber (match_operand:SI 3 "register_operand" "=d"))]
3936: ""
3937: "*
3938: {
3939: register rtx target = XEXP (operands[1], 0);
3940:
3941: if (GET_CODE (target) == SYMBOL_REF)
3942: return \"%*jal\\t%1\";
3943:
3944: else
3945: {
3946: operands[1] = target;
3947: operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 31);
3948: return \"%*jal\\t%2,%1\";
3949: }
3950: }"
3951: [(set_attr "type" "call")
3952: (set_attr "mode" "none")
3953: (set_attr "length" "1")])
3954:
3955:
3956: ;;
3957: ;; ....................
3958: ;;
3959: ;; MISC.
3960: ;;
3961: ;; ....................
3962: ;;
3963:
3964: (define_insn "nop"
3965: [(const_int 0)]
3966: ""
3967: "%(nop%)"
3968: [(set_attr "type" "nop")
3969: (set_attr "mode" "none")
3970: (set_attr "length" "1")])
3971:
3972: (define_expand "probe"
3973: [(set (match_dup 0)
3974: (match_dup 1))]
3975: ""
3976: "
3977: {
3978: operands[0] = gen_reg_rtx (SImode);
3979: operands[1] = gen_rtx (MEM, SImode, stack_pointer_rtx);
3980: MEM_VOLATILE_P (operands[1]) = TRUE;
3981:
3982: /* fall through and generate default code */
3983: }")
3984:
3985:
3986: ;;
3987: ;; Local variables:
3988: ;; mode:emacs-lisp
3989: ;; comment-start: ";; "
3990: ;; eval: (set-syntax-table (copy-sequence (syntax-table)))
3991: ;; eval: (modify-syntax-entry ?[ "(]")
3992: ;; eval: (modify-syntax-entry ?] ")[")
3993: ;; eval: (modify-syntax-entry ?{ "(}")
3994: ;; eval: (modify-syntax-entry ?} "){")
3995: ;; End:
1.1.1.3 ! root 3996:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.