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