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