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