|
|
1.1.1.3 root 1:
1.1 root 2: ;;- Machine description for SPARC chip for GNU C compiler
3: ;; Copyright (C) 1988, 1989 Free Software Foundation, Inc.
4: ;; Contributed by Michael Tiemann ([email protected])
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 1, 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: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24:
25: ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
26: ;;- updates for most instructions.
27:
28: ;;- Operand classes for the register allocator:
29:
30: ;; Compare instructions.
31: ;; This controls RTL generation and register allocation.
32:
33: ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
34:
35: (define_insn "cmpsi"
36: [(set (cc0)
37: (compare (match_operand:SI 0 "arith_operand" "r,rI")
38: (match_operand:SI 1 "arith_operand" "I,r")))]
39: ""
40: "*
41: {
42: if (! REG_P (operands[0]))
43: {
44: cc_status.flags |= CC_REVERSED;
45: return \"cmp %1,%0\";
46: }
47: return \"cmp %0,%1\";
48: }")
49:
50: (define_expand "cmpdf"
51: [(set (cc0)
52: (compare (match_operand:DF 0 "nonmemory_operand" "f,fG")
53: (match_operand:DF 1 "nonmemory_operand" "G,f")))]
54: ""
55: "emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, DFmode, 32)));")
56:
57: (define_insn ""
58: [(set (cc0)
59: (compare (match_operand:DF 0 "nonmemory_operand" "f,fG")
60: (match_operand:DF 1 "nonmemory_operand" "G,f")))]
1.1.1.3 root 61: "GET_CODE (operands[0]) != CONST_INT && GET_CODE (operands[1]) != CONST_INT"
1.1 root 62: "*
63: {
64: if (GET_CODE (operands[0]) == CONST_DOUBLE
65: || GET_CODE (operands[1]) == CONST_DOUBLE)
66: make_f0_contain_0 (2);
67:
68: cc_status.flags |= CC_IN_FCCR;
69: if (GET_CODE (operands[0]) == CONST_DOUBLE)
70: return \"fcmped %%f0,%1\;nop\";
71: if (GET_CODE (operands[1]) == CONST_DOUBLE)
72: return \"fcmped %0,%%f0\;nop\";
73: return \"fcmped %0,%1\;nop\";
74: }")
75:
76: (define_expand "cmpsf"
77: [(set (cc0)
78: (compare (match_operand:SF 0 "nonmemory_operand" "f,fG")
79: (match_operand:SF 1 "nonmemory_operand" "G,f")))]
80: ""
81: "emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SFmode, 32)));")
82:
83: (define_insn ""
84: [(set (cc0)
85: (compare (match_operand:SF 0 "nonmemory_operand" "f,fG")
86: (match_operand:SF 1 "nonmemory_operand" "G,f")))]
1.1.1.3 root 87: "GET_CODE (operands[0]) != CONST_INT && GET_CODE (operands[1]) != CONST_INT"
1.1 root 88: "*
89: {
90: if (GET_CODE (operands[0]) == CONST_DOUBLE
91: || GET_CODE (operands[1]) == CONST_DOUBLE)
92: make_f0_contain_0 (1);
93:
94: cc_status.flags |= CC_IN_FCCR;
95: if (GET_CODE (operands[0]) == CONST_DOUBLE)
96: return \"fcmpes %%f0,%1\;nop\";
97: if (GET_CODE (operands[1]) == CONST_DOUBLE)
98: return \"fcmpes %0,%%f0\;nop\";
99: return \"fcmpes %0,%1\;nop\";
100: }")
101:
102: ;; Put tstsi first among test insns so it matches a CONST_INT operand.
103:
104: (define_insn "tstsi"
105: [(set (cc0)
106: (match_operand:SI 0 "register_operand" "r"))]
107: ""
108: "tst %0")
109:
110: ;; Need this to take a general operand because cse can make
111: ;; a CONST which won't be in a register.
112: (define_insn ""
113: [(set (cc0)
114: (match_operand:SI 0 "immediate_operand" "i"))]
115: ""
116: "set %0,%%g1\;tst %%g1")
117:
118: ;; Optimize the case of following a reg-reg move with a test
119: ;; of reg just moved.
120:
121: (define_peephole
122: [(set (match_operand:SI 0 "register_operand" "=r")
123: (match_operand:SI 1 "register_operand" "r"))
124: (set (cc0) (match_operand:SI 2 "register_operand" "r"))]
125: "operands[2] == operands[0]
126: || operands[2] == operands[1]"
127: "orcc %1,%%g0,%0 ! 2-insn combine")
128:
129: ;; Optimize 5(6) insn sequence to 3(4) insns.
130: ;; These patterns could also optimize more complicated sets
131: ;; before conditional branches.
132:
133: ;; Turned off because (1) this case is rarely encounted
134: ;; (2) to be correct, more conditions must be checked
135: ;; (3) the conditions must be checked with rtx_equal_p, not ==
136: ;; (4) when branch scheduling is added to the compiler,
137: ;; this optimization will be performed by the branch scheduler
138: ;; Bottom line: it is not worth the trouble of fixing or
139: ;; maintaining it.
140:
141: ;(define_peephole
142: ; [(set (match_operand:SI 0 "register_operand" "=r")
143: ; (match_operand:SI 1 "general_operand" "g"))
144: ; (set (match_operand:SI 2 "register_operand" "=r")
145: ; (match_operand:SI 3 "reg_or_0_operand" "rJ"))
146: ; (set (cc0) (match_operand:SI 4 "register_operand" "r"))
147: ; (set (pc) (match_operand 5 "" ""))]
148: ; "GET_CODE (operands[5]) == IF_THEN_ELSE
149: ; && operands[0] != operands[3]
150: ; && ! reg_mentioned_p (operands[2], operands[1])
151: ; && (operands[4] == operands[0]
152: ; || operands[4] == operands[2]
153: ; || operands[4] == operands[3])"
154: ; "*
155: ;{
156: ; rtx xoperands[2];
157: ; int parity;
158: ; xoperands[0] = XEXP (operands[5], 0);
159: ; if (GET_CODE (XEXP (operands[5], 1)) == PC)
160: ; {
161: ; parity = 1;
162: ; xoperands[1] = XEXP (XEXP (operands[5], 2), 0);
163: ; }
164: ; else
165: ; {
166: ; parity = 0;
167: ; xoperands[1] = XEXP (XEXP (operands[5], 1), 0);
168: ; }
169: ;
170: ; if (operands[4] == operands[0])
171: ; {
172: ; /* Although the constraints for operands[1] permit a general
173: ; operand (and hence possibly a const_int), we know that
174: ; in this branch it cannot be a CONST_INT, since that would give
175: ; us a fixed condition, and those should have been optimized away. */
176: ; if (REG_P (operands[1]))
177: ; output_asm_insn (\"orcc %1,%%g0,%0 ! 3-insn reorder\", operands);
178: ; else if (GET_CODE (operands[1]) != MEM)
179: ; abort ();
180: ; else
181: ; {
182: ; if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
183: ; output_asm_insn (\"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;tst %0 ! 4-insn reorder\", operands);
184: ; else
185: ; output_asm_insn (\"ld %1,%0\;tst %0 ! 3.5-insn reorder\", operands);
186: ; }
187: ; XVECEXP (PATTERN (insn), 0, 0) = XVECEXP (PATTERN (insn), 0, 2);
188: ; XVECEXP (PATTERN (insn), 0, 1) = XVECEXP (PATTERN (insn), 0, 3);
189: ; }
190: ; else
191: ; {
192: ; output_asm_insn (\"orcc %3,%%g0,%2 ! 3-insn reorder\", operands);
193: ; }
194: ; if (parity)
195: ; return output_delayed_branch (\"b%N0 %l1\", xoperands, insn);
196: ; else
197: ; return output_delayed_branch (\"b%C0 %l1\", xoperands, insn);
198: ;}")
199:
200: ;; By default, operations don't set the condition codes.
201: ;; These patterns allow cc's to be set, while doing some work
202:
203: (define_insn ""
204: [(set (cc0)
205: (zero_extend:SI (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)))]
206: ""
207: "andcc %0,0xff,%%g0")
208:
209: (define_insn ""
210: [(set (cc0)
211: (plus:SI (match_operand:SI 0 "register_operand" "r%")
212: (match_operand:SI 1 "arith_operand" "rI")))]
1.1.1.3 root 213: "ignore_overflow_conditional_p (NEXT_INSN (insn))"
214: "*
215: {
216: cc_status.flags |= CC_NO_OVERFLOW;
217: return \"addcc %0,%1,%%g0\";
218: }")
1.1 root 219:
220: (define_insn ""
221: [(set (cc0)
222: (plus:SI (match_operand:SI 0 "register_operand" "r%")
223: (match_operand:SI 1 "arith_operand" "rI")))
224: (set (match_operand:SI 2 "register_operand" "=r")
225: (plus:SI (match_dup 0) (match_dup 1)))]
1.1.1.3 root 226: "ignore_overflow_conditional_p (NEXT_INSN (insn))"
227: "*
228: {
229: cc_status.flags |= CC_NO_OVERFLOW;
230: return \"addcc %0,%1,%2\";
231: }")
232:
233: (define_insn ""
234: [(set (cc0)
235: (minus:SI (match_operand:SI 0 "register_operand" "r")
236: (match_operand:SI 1 "arith_operand" "rI")))]
237: "ignore_overflow_conditional_p (NEXT_INSN (insn))"
238: "*
239: {
240: cc_status.flags |= CC_NO_OVERFLOW;
241: return \"subcc %0,%1,%%g0\";
242: }")
1.1 root 243:
244: (define_insn ""
245: [(set (cc0)
246: (minus:SI (match_operand:SI 0 "register_operand" "r")
247: (match_operand:SI 1 "arith_operand" "rI")))
248: (set (match_operand:SI 2 "register_operand" "=r")
249: (minus:SI (match_dup 0) (match_dup 1)))]
1.1.1.3 root 250: "ignore_overflow_conditional_p (NEXT_INSN (insn))"
251: "*
252: {
253: cc_status.flags |= CC_NO_OVERFLOW;
254: return \"subcc %0,%1,%2\";
255: }")
1.1 root 256:
257: (define_insn ""
258: [(set (cc0)
259: (and:SI (match_operand:SI 0 "register_operand" "r%")
260: (match_operand:SI 1 "arith_operand" "rI")))]
261: ""
262: "andcc %0,%1,%%g0")
263:
264: (define_insn ""
265: [(set (cc0)
266: (and:SI (match_operand:SI 0 "register_operand" "r%")
267: (match_operand:SI 1 "arith_operand" "rI")))
268: (set (match_operand:SI 2 "register_operand" "=r")
269: (and:SI (match_dup 0) (match_dup 1)))]
270: ""
271: "andcc %0,%1,%2")
272:
273: (define_insn ""
274: [(set (cc0)
1.1.1.3 root 275: (and:SI (match_operand:SI 0 "register_operand" "r")
1.1 root 276: (not:SI (match_operand:SI 1 "arith_operand" "rI"))))]
277: ""
278: "andncc %0,%1,%%g0")
279:
280: (define_insn ""
281: [(set (cc0)
1.1.1.3 root 282: (and:SI (match_operand:SI 0 "register_operand" "r")
1.1 root 283: (not:SI (match_operand:SI 1 "arith_operand" "rI"))))
284: (set (match_operand:SI 2 "register_operand" "=r")
285: (and:SI (match_dup 0) (not:SI (match_dup 1))))]
286: ""
287: "andncc %0,%1,%2")
288:
289: (define_insn ""
290: [(set (cc0)
291: (ior:SI (match_operand:SI 0 "register_operand" "r%")
292: (match_operand:SI 1 "arith_operand" "rI")))]
293: ""
294: "orcc %0,%1,%%g0")
295:
296: (define_insn ""
297: [(set (cc0)
298: (ior:SI (match_operand:SI 0 "register_operand" "r%")
299: (match_operand:SI 1 "arith_operand" "rI")))
300: (set (match_operand:SI 2 "register_operand" "=r")
301: (ior:SI (match_dup 0) (match_dup 1)))]
302: ""
303: "orcc %0,%1,%2")
304:
305: (define_insn ""
306: [(set (cc0)
1.1.1.3 root 307: (ior:SI (match_operand:SI 0 "register_operand" "r")
1.1 root 308: (not:SI (match_operand:SI 1 "arith_operand" "rI"))))]
309: ""
310: "orncc %0,%1,%%g0")
311:
312: (define_insn ""
313: [(set (cc0)
1.1.1.3 root 314: (ior:SI (match_operand:SI 0 "register_operand" "r")
1.1 root 315: (not:SI (match_operand:SI 1 "arith_operand" "rI"))))
316: (set (match_operand:SI 2 "register_operand" "=r")
317: (ior:SI (match_dup 0) (not:SI (match_dup 1))))]
318: ""
319: "orncc %0,%1,%2")
320:
321: (define_insn ""
322: [(set (cc0)
323: (xor:SI (match_operand:SI 0 "register_operand" "r%")
324: (match_operand:SI 1 "arith_operand" "rI")))]
325: ""
326: "xorcc %0,%1,%%g0")
327:
328: (define_insn ""
329: [(set (cc0)
330: (xor:SI (match_operand:SI 0 "register_operand" "r%")
331: (match_operand:SI 1 "arith_operand" "rI")))
332: (set (match_operand:SI 2 "register_operand" "=r")
333: (xor:SI (match_dup 0) (match_dup 1)))]
334: ""
335: "xorcc %0,%1,%2")
336:
337: (define_insn ""
338: [(set (cc0)
1.1.1.3 root 339: (xor:SI (match_operand:SI 0 "register_operand" "r")
1.1 root 340: (not:SI (match_operand:SI 1 "arith_operand" "rI"))))]
341: ""
342: "xnorcc %0,%1,%%g0")
343:
344: (define_insn ""
345: [(set (cc0)
1.1.1.3 root 346: (xor:SI (match_operand:SI 0 "register_operand" "r")
1.1 root 347: (not:SI (match_operand:SI 1 "arith_operand" "rI"))))
348: (set (match_operand:SI 2 "register_operand" "=r")
349: (xor:SI (match_dup 0) (not:SI (match_dup 1))))]
350: ""
351: "xnorcc %0,%1,%2")
352:
353: (define_expand "tstdf"
354: [(set (cc0)
355: (match_operand:DF 0 "register_operand" "f"))]
356: ""
1.1.1.3 root 357: "emit_insn (gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, DFmode, 32)));")
1.1 root 358:
359: (define_insn ""
360: [(set (cc0)
361: (match_operand:DF 0 "register_operand" "f"))]
362: ""
363: "*
364: {
365: make_f0_contain_0 (2);
366: cc_status.flags |= CC_IN_FCCR;
367: return \"fcmped %0,%%f0\;nop\";
368: }")
369:
370: (define_expand "tstsf"
371: [(set (cc0)
372: (match_operand:SF 0 "register_operand" "f"))]
373: ""
1.1.1.3 root 374: "emit_insn (gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SFmode, 32)));")
1.1 root 375:
376: (define_insn ""
377: [(set (cc0)
378: (match_operand:SF 0 "register_operand" "f"))]
379: ""
380: "*
381: {
382: make_f0_contain_0 (1);
383: cc_status.flags |= CC_IN_FCCR;
384: return \"fcmpes %0,%%f0\;nop\";
385: }")
386:
387: ;; There are no logical links for the condition codes. This
388: ;; would not normally be a problem, but on the SPARC (and possibly
389: ;; other RISC machines), when argument passing, the insn which sets
390: ;; the condition code and the insn which uses the set condition code
391: ;; may not be performed adjacently (due to optimizations performed
392: ;; in combine.c). To make up for this, we emit insn patterns which
393: ;; cannot possibly be rearranged on us.
394: (define_expand "seq"
395: [(set (match_operand:SI 0 "general_operand" "=r")
396: (eq (cc0) (const_int 0)))]
397: ""
398: "gen_scc_insn (EQ, VOIDmode, operands); DONE;")
399:
400: (define_expand "sne"
401: [(set (match_operand:SI 0 "general_operand" "=r")
402: (ne (cc0) (const_int 0)))]
403: ""
404: "gen_scc_insn (NE, VOIDmode, operands); DONE;")
405:
406: (define_insn ""
407: [(set (match_operand:SI 0 "general_operand" "=r,r")
408: (match_operator 1 "eq_or_neq"
409: [(compare (match_operand:SI 2 "general_operand" "r,rI")
410: (match_operand:SI 3 "general_operand" "I,r"))
411: (const_int 0)]))]
412: ""
413: "*
414: {
415: CC_STATUS_INIT;
416: cc_status.value1 = operands[0];
417: if (! REG_P (operands[2]))
418: {
419: output_asm_insn (\"cmp %3,%2\", operands);
420: cc_status.flags |= CC_REVERSED;
421: }
422: else
423: output_asm_insn (\"cmp %2,%3\", operands);
424: return output_scc_insn (GET_CODE (operands[1]), operands[0]);
425: }")
426:
427: (define_insn ""
428: [(set (match_operand:SI 0 "general_operand" "=r")
429: (match_operator 1 "eq_or_neq"
430: [(match_operand:SI 2 "general_operand" "r")
431: (const_int 0)]))]
432: ""
433: "*
434: {
435: CC_STATUS_INIT;
436: cc_status.value1 = operands[0];
437: output_asm_insn (\"tst %2\", operands);
438: return output_scc_insn (GET_CODE (operands[1]), operands[0]);
439: }")
440:
441: (define_insn ""
442: [(set (match_operand:SI 0 "general_operand" "=r,r")
443: (match_operator 1 "eq_or_neq"
444: [(compare (match_operand:DF 2 "general_operand" "f,fG")
445: (match_operand:DF 3 "general_operand" "G,f"))
446: (const_int 0)]))]
447: ""
448: "*
449: {
450: CC_STATUS_INIT;
451: cc_status.value1 = operands[0];
452: cc_status.flags |= CC_IN_FCCR;
453:
454: if (GET_CODE (operands[2]) == CONST_DOUBLE
455: || GET_CODE (operands[3]) == CONST_DOUBLE)
456: make_f0_contain_0 (2);
457:
458: if (GET_CODE (operands[2]) == CONST_DOUBLE)
459: output_asm_insn (\"fcmped %%f0,%3\;nop\", operands);
460: else if (GET_CODE (operands[3]) == CONST_DOUBLE)
461: output_asm_insn (\"fcmped %2,%%f0\;nop\", operands);
462: else output_asm_insn (\"fcmped %2,%3\;nop\", operands);
463: return output_scc_insn (GET_CODE (operands[1]), operands[0]);
464: }")
465:
466: (define_insn ""
467: [(set (match_operand:SI 0 "general_operand" "=r")
468: (match_operator 1 "eq_or_neq"
469: [(match_operand:DF 2 "general_operand" "f")
470: (const_int 0)]))]
471: ""
472: "*
473: {
474: CC_STATUS_INIT;
475: cc_status.value1 = operands[0];
476: cc_status.flags |= CC_IN_FCCR;
477:
478: make_f0_contain_0 (2);
479: output_asm_insn (\"fcmped %2,%%f0\;nop\", operands);
480: return output_scc_insn (GET_CODE (operands[1]), operands[0]);
481: }")
482:
483: (define_insn ""
484: [(set (match_operand:SI 0 "general_operand" "=r,r")
485: (match_operator 1 "eq_or_neq"
486: [(compare (match_operand:SF 2 "general_operand" "f,fG")
487: (match_operand:SF 3 "general_operand" "G,f"))
488: (const_int 0)]))]
489: ""
490: "*
491: {
492: CC_STATUS_INIT;
493: cc_status.value1 = operands[0];
494: cc_status.flags |= CC_IN_FCCR;
495:
496: if (GET_CODE (operands[2]) == CONST_DOUBLE
497: || GET_CODE (operands[3]) == CONST_DOUBLE)
498: make_f0_contain_0 (1);
499:
500: if (GET_CODE (operands[2]) == CONST_DOUBLE)
501: output_asm_insn (\"fcmpes %%f0,%3\;nop\", operands);
502: else if (GET_CODE (operands[3]) == CONST_DOUBLE)
503: output_asm_insn (\"fcmpes %2,%%f0\;nop\", operands);
504: else output_asm_insn (\"fcmpes %2,%3\;nop\", operands);
505: return output_scc_insn (GET_CODE (operands[1]), operands[0]);
506: }")
507:
508: (define_insn ""
509: [(set (match_operand:SI 0 "general_operand" "=r")
510: (match_operator 1 "eq_or_neq"
511: [(match_operand:SF 2 "general_operand" "f")
512: (const_int 0)]))]
513: ""
514: "*
515: {
516: CC_STATUS_INIT;
517: cc_status.value1 = operands[0];
518: cc_status.flags |= CC_IN_FCCR;
519:
520: make_f0_contain_0 (1);
521: output_asm_insn (\"fcmpes %2,%%f0\;nop\", operands);
522: return output_scc_insn (GET_CODE (operands[1]), operands[0]);
523: }")
524:
525: ;; These control RTL generation for conditional jump insns
526: ;; and match them for register allocation.
527:
528: (define_insn "beq"
529: [(set (pc)
530: (if_then_else (eq (cc0)
531: (const_int 0))
532: (label_ref (match_operand 0 "" ""))
533: (pc)))]
534: ""
535: "*
536: {
1.1.1.3 root 537: OUTPUT_JUMP (\"be %l0\;nop\", \"be %l0\;nop\", \"fbe %l0\;nop\");
1.1 root 538: }")
539:
540: (define_insn "bne"
541: [(set (pc)
542: (if_then_else (ne (cc0)
543: (const_int 0))
544: (label_ref (match_operand 0 "" ""))
545: (pc)))]
546: ""
547: "*
548: {
1.1.1.3 root 549: OUTPUT_JUMP (\"bne %l0\;nop\", \"bne %l0\;nop\", \"fbne %l0\;nop\");
1.1 root 550: }")
551:
552: (define_insn "bgt"
553: [(set (pc)
554: (if_then_else (gt (cc0)
555: (const_int 0))
556: (label_ref (match_operand 0 "" ""))
557: (pc)))]
558: ""
559: "*
560: {
1.1.1.3 root 561: OUTPUT_JUMP (\"bg %l0\;nop\", 0, \"fbg %l0\;nop\");
1.1 root 562: }")
563:
564: (define_insn "bgtu"
565: [(set (pc)
566: (if_then_else (gtu (cc0)
567: (const_int 0))
568: (label_ref (match_operand 0 "" ""))
569: (pc)))]
570: ""
571: "*
572: {
573: if (cc_prev_status.flags & CC_IN_FCCR)
574: abort ();
575: return \"bgu %l0\;nop\";
576: }")
577:
578: (define_insn "blt"
579: [(set (pc)
580: (if_then_else (lt (cc0)
581: (const_int 0))
582: (label_ref (match_operand 0 "" ""))
583: (pc)))]
584: ""
585: "*
586: {
1.1.1.3 root 587: OUTPUT_JUMP (\"bl %l0\;nop\", \"bneg %l0\;nop\", \"fbl %l0\;nop\");
1.1 root 588: }")
589:
590: (define_insn "bltu"
591: [(set (pc)
592: (if_then_else (ltu (cc0)
593: (const_int 0))
594: (label_ref (match_operand 0 "" ""))
595: (pc)))]
596: ""
597: "*
598: {
599: if (cc_prev_status.flags & CC_IN_FCCR)
600: abort ();
601: return \"blu %l0\;nop\";
602: }")
603:
604: (define_insn "bge"
605: [(set (pc)
606: (if_then_else (ge (cc0)
607: (const_int 0))
608: (label_ref (match_operand 0 "" ""))
609: (pc)))]
610: ""
611: "*
612: {
1.1.1.3 root 613: OUTPUT_JUMP (\"bge %l0\;nop\", \"bpos %l0\;nop\", \"fbge %l0\;nop\");
1.1 root 614: }")
615:
616: (define_insn "bgeu"
617: [(set (pc)
618: (if_then_else (geu (cc0)
619: (const_int 0))
620: (label_ref (match_operand 0 "" ""))
621: (pc)))]
622: ""
623: "*
624: {
625: if (cc_prev_status.flags & CC_IN_FCCR)
626: abort ();
627: return \"bgeu %l0\;nop\";
628: }")
629:
630: (define_insn "ble"
631: [(set (pc)
632: (if_then_else (le (cc0)
633: (const_int 0))
634: (label_ref (match_operand 0 "" ""))
635: (pc)))]
636: ""
637: "*
638: {
1.1.1.3 root 639: OUTPUT_JUMP (\"ble %l0\;nop\", 0, \"fble %l0\;nop\");
1.1 root 640: }")
641:
642: (define_insn "bleu"
643: [(set (pc)
644: (if_then_else (leu (cc0)
645: (const_int 0))
646: (label_ref (match_operand 0 "" ""))
647: (pc)))]
648: ""
649: "*
650: {
651: if (cc_prev_status.flags & CC_IN_FCCR)
652: abort ();
653: return \"bleu %l0\;nop\";
654: }")
655:
656: ;; This matches inverted jump insns for register allocation.
657:
658: (define_insn ""
659: [(set (pc)
660: (if_then_else (match_operator 0 "relop" [(cc0) (const_int 0)])
661: (pc)
662: (label_ref (match_operand 1 "" ""))))]
663: ""
664: "*
665: {
1.1.1.3 root 666: if (cc_prev_status.flags & CC_NO_OVERFLOW)
667: {
668: if (GET_CODE (operands[0]) == GT || GET_CODE (operands[0]) == LE)
669: /* These two conditions can't ignore overflow,
670: so reinsert the deleted test instruction. */
671: return 0;
672: return \"b%U0 %l1\;nop\";
673: }
1.1 root 674: if (cc_prev_status.flags & CC_IN_FCCR)
675: return \"fb%F0 %l1\;nop\";
676: return \"b%N0 %l1\;nop\";
677: }")
678:
679: ;; Move instructions
680:
681: (define_insn "swapsi"
682: [(set (match_operand:SI 0 "general_operand" "r,rm")
683: (match_operand:SI 1 "general_operand" "m,r"))
684: (set (match_dup 1) (match_dup 0))]
685: ""
686: "*
687: {
688: if (GET_CODE (operands[1]) == MEM)
689: {
690: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
691: output_asm_insn (\"set %a1,%%g1\", operands),
692: operands[1] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 1)),
693: cc_status.flags &= ~CC_KNOW_HI_G1;
694: output_asm_insn (\"swap %1,%0\", operands);
695: }
696: if (REG_P (operands[0]))
697: {
698: if (REGNO (operands[0]) == REGNO (operands[1]))
699: return \"\";
700: return \"xor %0,%1,%0\;xor %1,%0,%1\;xor %0,%1,%0\";
701: }
702: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
703: {
704: output_asm_insn (\"set %a0,%%g1\", operands);
705: operands[0] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 1));
706: cc_status.flags &= ~CC_KNOW_HI_G1;
707: }
708: return \"swap %0,%1\";
709: }")
710:
711: (define_insn "movsi"
712: [(set (match_operand:SI 0 "general_operand" "=r,m")
713: (match_operand:SI 1 "general_operand" "rmif,rJ"))]
714: ""
715: "*
716: {
717: if (GET_CODE (operands[0]) == MEM)
718: {
719: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
720: return output_store (operands);
721: return \"st %r1,%0\";
722: }
723: if (GET_CODE (operands[1]) == MEM)
724: {
725: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
726: return output_load_fixed (operands);
727: return \"ld %1,%0\";
728: }
729: if (FP_REG_P (operands[1]))
730: return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\";
731: if (REG_P (operands[1])
732: || (GET_CODE (operands[1]) == CONST_INT
733: && SMALL_INT (operands[1])))
734: return \"mov %1,%0\";
735: if (GET_CODE (operands[1]) == CONST_INT
736: && (INTVAL (operands[1]) & 0x3ff) == 0)
737: return \"sethi %%hi(%1),%0\";
738: return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\";
739: }")
740:
741: (define_insn "movhi"
742: [(set (match_operand:HI 0 "general_operand" "=r,m")
743: (match_operand:HI 1 "general_operand" "rmi,rJ"))]
744: ""
745: "*
746: {
747: if (GET_CODE (operands[0]) == MEM)
748: {
749: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
750: return output_store (operands);
751: return \"sth %r1,%0\";
752: }
753: if (GET_CODE (operands[1]) == MEM)
754: {
755: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
756: return output_load_fixed (operands);
757: return \"ldsh %1,%0\";
758: }
759: if (REG_P (operands[1])
760: || (GET_CODE (operands[1]) == CONST_INT
761: && SMALL_INT (operands[1])))
762: return \"mov %1,%0\";
763: return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\";
764: }")
765:
766: (define_insn "movqi"
767: [(set (match_operand:QI 0 "general_operand" "=r,m")
768: (match_operand:QI 1 "general_operand" "rmi,rJ"))]
769: ""
770: "*
771: {
772: if (GET_CODE (operands[0]) == MEM)
773: {
774: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
775: return output_store (operands);
776: return \"stb %r1,%0\";
777: }
778: if (GET_CODE (operands[1]) == MEM)
779: {
780: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
781: return output_load_fixed (operands);
782: return \"ldsb %1,%0\";
783: }
784: if (REG_P (operands[1])
785: || (GET_CODE (operands[1]) == CONST_INT
786: && SMALL_INT (operands[1])))
787: return \"mov %1,%0\";
788: return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\";
789: }")
790:
791: ;; The definition of this insn does not really explain what it does,
792: ;; but it should suffice
793: ;; that anything generated as this insn will be recognized as one
794: ;; and that it won't successfully combine with anything.
795: (define_expand "movstrsi"
796: [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
797: (mem:BLK (match_operand:BLK 1 "general_operand" "")))
798: (use (match_operand:SI 2 "arith32_operand" ""))
799: (use (match_operand:SI 3 "immediate_operand" ""))
800: (clobber (match_dup 4))
801: (clobber (match_dup 0))
802: (clobber (match_dup 1))])]
803: ""
804: "
805: {
806: operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
807: operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
808: operands[4] = gen_reg_rtx (SImode);
809: }")
810:
811: (define_insn ""
812: [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
813: (mem:BLK (match_operand:SI 1 "register_operand" "r")))
814: (use (match_operand:SI 2 "arith32_operand" "rn"))
815: (use (match_operand:SI 3 "immediate_operand" "i"))
816: (clobber (match_operand:SI 4 "register_operand" "=r"))
817: (clobber (match_operand:SI 5 "register_operand" "=0"))
818: (clobber (match_operand:SI 6 "register_operand" "=1"))]
819: ""
820: "* return output_block_move (operands);")
821:
822: ;; Floating point move insns
823:
824: ;; This pattern forces (set (reg:DF ...) (const_double ...))
825: ;; to be reloaded by putting the constant into memory.
826: ;; It must come before the more general movdf pattern.
827: (define_insn ""
828: [(set (match_operand:DF 0 "general_operand" "=r,f,o")
829: (match_operand:DF 1 "" "mG,m,G"))]
830: "GET_CODE (operands[1]) == CONST_DOUBLE"
831: "*
832: {
833: if (FP_REG_P (operands[0]))
834: return output_fp_move_double (operands);
835: if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == REG)
836: {
837: operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
838: return \"mov %%g0,%0\;mov %%g0,%1\";
839: }
840: if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == MEM)
841: {
842: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
843: {
844: if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
845: && XEXP (operands[0], 0) == cc_prev_status.mdep))
846: {
847: cc_status.flags |= CC_KNOW_HI_G1;
848: cc_status.mdep = XEXP (operands[0], 0);
849: output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
850: }
851: return \"st %%g0,[%%g1+%%lo(%%m0)]\;st %%g0,[%%g1+%%lo(%%m0)+4]\";
852: }
853: operands[1] = adj_offsettable_operand (operands[0], 4);
854: return \"st %%g0,%0\;st %%g0,%1\";
855: }
856: return output_move_double (operands);
857: }")
858:
859: (define_insn "movdf"
860: [(set (match_operand:DF 0 "general_operand" "=rm,&r,?f,?rm")
861: (match_operand:DF 1 "general_operand" "r,m,rfm,f"))]
862: ""
863: "*
864: {
865: if (GET_CODE (operands[0]) == MEM
866: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
867: return output_store (operands);
868: if (GET_CODE (operands[1]) == MEM
869: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
870: return output_load_floating (operands);
871:
872: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
873: return output_fp_move_double (operands);
874: return output_move_double (operands);
875: }")
876:
877: (define_insn "movdi"
878: [(set (match_operand:DI 0 "general_operand" "=rm,&r,?f,?rm")
879: (match_operand:DI 1 "general_operand" "r,mi,rfm,f"))]
880: ""
881: "*
882: {
883: if (GET_CODE (operands[0]) == MEM
884: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
885: return output_store (operands);
886: if (GET_CODE (operands[1]) == MEM
887: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
888: return output_load_fixed (operands);
889:
890: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
891: return output_fp_move_double (operands);
892: return output_move_double (operands);
893: }")
894:
895: (define_insn "movsf"
896: [(set (match_operand:SF 0 "general_operand" "=rf,m")
897: (match_operand:SF 1 "general_operand" "rfm,rf"))]
898: ""
899: "*
900: {
901: if (GET_CODE (operands[0]) == MEM
902: && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
903: return output_store (operands);
904: if (GET_CODE (operands[1]) == MEM
905: && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
906: return output_load_floating (operands);
907: if (FP_REG_P (operands[0]))
908: {
909: if (FP_REG_P (operands[1]))
910: return \"fmovs %1,%0\";
911: if (GET_CODE (operands[1]) == REG)
912: return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\";
913: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
914: {
915: cc_status.flags |= CC_KNOW_HI_G1;
916: cc_status.mdep = XEXP (operands[1], 0);
917: return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\";
918: }
919: return \"ld %1,%0\";
920: }
921: if (FP_REG_P (operands[1]))
922: {
923: if (GET_CODE (operands[0]) == REG)
924: return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\";
925: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
926: {
927: if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
928: && XEXP (operands[0], 0) == cc_prev_status.mdep))
929: {
930: cc_status.flags |= CC_KNOW_HI_G1;
931: cc_status.mdep = XEXP (operands[0], 0);
932: output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
933: }
934: return \"st %r1,[%%g1+%%lo(%m0)]\";
935: }
936: return \"st %r1,%0\";
937: }
938: if (GET_CODE (operands[0]) == MEM)
939: return \"st %r1,%0\";
940: if (GET_CODE (operands[1]) == MEM)
941: return \"ld %1,%0\";
942: return \"mov %1,%0\";
943: }")
944:
945: ;;- truncation instructions
946: (define_insn "truncsiqi2"
947: [(set (match_operand:QI 0 "general_operand" "=g")
948: (truncate:QI
949: (match_operand:SI 1 "register_operand" "r")))]
950: ""
951: "*
952: {
953: if (GET_CODE (operands[0]) == MEM)
954: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
955: {
956: if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
957: && XEXP (operands[0], 0) == cc_prev_status.mdep))
958: {
959: cc_status.flags |= CC_KNOW_HI_G1;
960: cc_status.mdep = XEXP (operands[0], 0);
961: output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
962: }
963: return \"stb %1,[%%g1+%%lo(%m0)]\";
964: }
965: else
966: return \"stb %1,%0\";
967: return \"mov %1,%0\";
968: }")
969:
970: (define_insn "trunchiqi2"
971: [(set (match_operand:QI 0 "general_operand" "=g")
972: (truncate:QI
973: (match_operand:HI 1 "register_operand" "r")))]
974: ""
975: "*
976: {
977: if (GET_CODE (operands[0]) == MEM)
978: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
979: {
980: if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
981: && XEXP (operands[0], 0) == cc_prev_status.mdep))
982: {
983: cc_status.flags |= CC_KNOW_HI_G1;
984: cc_status.mdep = XEXP (operands[0], 0);
985: output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
986: }
987: return \"stb %1,[%%g1+%%lo(%m0)]\";
988: }
989: else
990: return \"stb %1,%0\";
991: return \"mov %1,%0\";
992: }")
993:
994: (define_insn "truncsihi2"
995: [(set (match_operand:HI 0 "general_operand" "=g")
996: (truncate:HI
997: (match_operand:SI 1 "register_operand" "r")))]
998: ""
999: "*
1000: {
1001: if (GET_CODE (operands[0]) == MEM)
1002: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1003: {
1004: if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
1005: && XEXP (operands[0], 0) == cc_prev_status.mdep))
1006: {
1007: cc_status.flags |= CC_KNOW_HI_G1;
1008: cc_status.mdep = XEXP (operands[0], 0);
1009: output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
1010: }
1011: return \"sth %1,[%%g1+%%lo(%m0)]\";
1012: }
1013: else
1014: return \"sth %1,%0\";
1015: return \"mov %1,%0\";
1016: }")
1017:
1018: ;;- zero extension instructions
1019:
1020: ;; Note that the one starting from HImode comes before those for QImode
1021: ;; so that a constant operand will match HImode, not QImode.
1022:
1023: (define_insn "zero_extendhisi2"
1024: [(set (match_operand:SI 0 "register_operand" "=r")
1025: (zero_extend:SI
1026: (match_operand:HI 1 "general_operand" "g")))]
1027: ""
1028: "*
1029: {
1030: if (REG_P (operands[1]))
1031: return \"sll %1,0x10,%0\;srl %0,0x10,%0\";
1032: if (GET_CODE (operands[1]) == CONST_INT)
1.1.1.2 root 1033: {
1034: operands[1] = gen_rtx (CONST_INT, VOIDmode,
1035: INTVAL (operands[1]) & 0xffff);
1036: output_asm_insn (\"set %1,%0\", operands);
1037: return \"\";
1038: }
1.1 root 1039: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1040: {
1041: cc_status.flags |= CC_KNOW_HI_G1;
1042: cc_status.mdep = XEXP (operands[1], 0);
1043: return \"sethi %%hi(%m1),%%g1\;lduh [%%g1+%%lo(%m1)],%0\";
1044: }
1045: else
1046: return \"lduh %1,%0\";
1047: }")
1048:
1049: (define_insn "zero_extendqihi2"
1050: [(set (match_operand:HI 0 "register_operand" "=r")
1051: (zero_extend:HI
1052: (match_operand:QI 1 "general_operand" "g")))]
1053: ""
1054: "*
1055: {
1056: if (REG_P (operands[1]))
1057: return \"and %1,0xff,%0\";
1058: if (GET_CODE (operands[1]) == CONST_INT)
1.1.1.2 root 1059: {
1060: operands[1] = gen_rtx (CONST_INT, VOIDmode,
1061: INTVAL (operands[1]) & 0xff);
1062: output_asm_insn (\"set %1,%0\", operands);
1063: return \"\";
1064: }
1.1 root 1065: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1066: {
1067: cc_status.flags |= CC_KNOW_HI_G1;
1068: cc_status.mdep = XEXP (operands[1], 0);
1069: return \"sethi %%hi(%m1),%%g1\;ldub [%%g1+%%lo(%m1)],%0\";
1070: }
1071: else
1072: return \"ldub %1,%0\";
1073: }")
1074:
1075: (define_insn "zero_extendqisi2"
1076: [(set (match_operand:SI 0 "register_operand" "=r")
1077: (zero_extend:SI
1078: (match_operand:QI 1 "general_operand" "g")))]
1079: ""
1080: "*
1081: {
1082: if (REG_P (operands[1]))
1083: return \"and %1,0xff,%0\";
1084: if (GET_CODE (operands[1]) == CONST_INT)
1.1.1.2 root 1085: {
1086: operands[1] = gen_rtx (CONST_INT, VOIDmode,
1087: INTVAL (operands[1]) & 0xff);
1088: output_asm_insn (\"set %1,%0\", operands);
1089: return \"\";
1090: }
1.1 root 1091: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1092: {
1093: cc_status.flags |= CC_KNOW_HI_G1;
1094: cc_status.mdep = XEXP (operands[1], 0);
1095: return \"sethi %%hi(%m1),%%g1\;ldub [%%g1+%%lo(%m1)],%0\";
1096: }
1097: else
1098: return \"ldub %1,%0\";
1099: }")
1100:
1101: ;;- sign extension instructions
1102: ;; Note that the one starting from HImode comes before those for QImode
1103: ;; so that a constant operand will match HImode, not QImode.
1104:
1105: (define_insn "extendhisi2"
1106: [(set (match_operand:SI 0 "register_operand" "=r")
1107: (sign_extend:SI
1108: (match_operand:HI 1 "general_operand" "g")))]
1109: ""
1110: "*
1111: {
1112: if (REG_P (operands[1]))
1113: return \"sll %1,0x10,%0\;sra %0,0x10,%0\";
1114: if (GET_CODE (operands[1]) == CONST_INT)
1.1.1.2 root 1115: {
1116: int i = (short)INTVAL (operands[1]);
1117: operands[1] = gen_rtx (CONST_INT, VOIDmode, i);
1118: output_asm_insn (\"set %1,%0\", operands);
1119: return \"\";
1120: }
1.1 root 1121: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1122: {
1123: cc_status.flags |= CC_KNOW_HI_G1;
1124: cc_status.mdep = XEXP (operands[1], 0);
1125: return \"sethi %%hi(%m1),%%g1\;ldsh [%%g1+%%lo(%m1)],%0\";
1126: }
1127: else
1128: return \"ldsh %1,%0\";
1129: }")
1130:
1131: (define_insn "extendqihi2"
1132: [(set (match_operand:HI 0 "register_operand" "=r")
1133: (sign_extend:HI
1134: (match_operand:QI 1 "general_operand" "g")))]
1135: ""
1136: "*
1137: {
1138: if (REG_P (operands[1]))
1139: return \"sll %1,0x18,%0\;sra %0,0x18,%0\";
1140: if (GET_CODE (operands[1]) == CONST_INT)
1.1.1.2 root 1141: {
1142: int i = (char)INTVAL (operands[1]);
1143: operands[1] = gen_rtx (CONST_INT, VOIDmode, i);
1144: output_asm_insn (\"set %1,%0\", operands);
1145: return \"\";
1146: }
1.1 root 1147: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1148: {
1149: cc_status.flags |= CC_KNOW_HI_G1;
1150: cc_status.mdep = XEXP (operands[1], 0);
1151: return \"sethi %%hi(%m1),%%g1\;ldsb [%%g1+%%lo(%m1)],%0\";
1152: }
1153: else
1154: return \"ldsb %1,%0\";
1155: }")
1156:
1157: (define_insn "extendqisi2"
1158: [(set (match_operand:SI 0 "register_operand" "=r")
1159: (sign_extend:SI
1160: (match_operand:QI 1 "general_operand" "g")))]
1161: ""
1162: "*
1163: {
1164: if (REG_P (operands[1]))
1165: return \"sll %1,0x18,%0\;sra %0,0x18,%0\";
1166: if (GET_CODE (operands[1]) == CONST_INT)
1.1.1.2 root 1167: {
1168: int i = (char)INTVAL (operands[1]);
1169: operands[1] = gen_rtx (CONST_INT, VOIDmode, i);
1170: output_asm_insn (\"set %1,%0\", operands);
1171: return \"\";
1172: }
1.1 root 1173: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1174: {
1175: cc_status.flags |= CC_KNOW_HI_G1;
1176: cc_status.mdep = XEXP (operands[1], 0);
1177: return \"sethi %%hi(%m1),%%g1\;ldsb [%%g1+%%lo(%m1)],%0\";
1178: }
1179: else
1180: return \"ldsb %1,%0\";
1181: }")
1182:
1183: ;; Signed bitfield extractions come out looking like
1184: ;; (shiftrt (shift (sign_extend <Y>) <C1>) <C2>)
1185: ;; which we expand poorly as four shift insns.
1186: ;; These patters yeild two shifts:
1187: ;; (shiftrt (shift <Y> <C3>) <C4>)
1188: (define_insn ""
1189: [(set (match_operand:SI 0 "register_operand" "=r")
1190: (ashiftrt:SI
1191: (sign_extend:SI
1192: (match_operand:QI 1 "register_operand" "r"))
1193: (match_operand:SI 2 "small_int" "n")))]
1194: ""
1195: "sll %1,0x18,%0\;sra %0,0x18+%2,%0")
1196:
1197: (define_insn ""
1198: [(set (match_operand:SI 0 "register_operand" "=r")
1199: (ashiftrt:SI
1200: (sign_extend:SI
1201: (subreg:QI (ashift:SI (match_operand:SI 1 "register_operand" "r")
1202: (match_operand:SI 2 "small_int" "n")) 0))
1203: (match_operand:SI 3 "small_int" "n")))]
1204: ""
1205: "sll %1,0x18+%2,%0\;sra %0,0x18+%3,%0")
1206:
1207: ;; Special patterns for optimizing bit-field instructions.
1208:
1209: ;; First two patterns are for bitfields that came from memory
1210: ;; testing only the high bit. They work with old combiner.
1211: ;; @@ Actually, the second pattern does not work if we
1212: ;; @@ need to set the N bit.
1213: (define_insn ""
1214: [(set (cc0)
1215: (zero_extend:SI (subreg:QI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1216: (const_int 7)) 0)))]
1217: "0"
1218: "andcc %0,128,%%g0")
1219:
1220: (define_insn ""
1221: [(set (cc0)
1222: (sign_extend:SI (subreg:QI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1223: (const_int 7)) 0)))]
1224: "0"
1225: "andcc %0,128,%%g0")
1226:
1227: ;; next two patterns are good for bitfields coming from memory
1228: ;; (via pseudo-register) or from a register, though this optimization
1229: ;; is only good for values contained wholly within the bottom 13 bits
1230: (define_insn ""
1231: [(set (cc0)
1232: (and:SI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1233: (match_operand:SI 1 "small_int" "n"))
1234: (match_operand:SI 2 "small_int" "n")))]
1235: "(unsigned)((INTVAL (operands[2]) << INTVAL (operands[1])) + 0x1000) < 0x2000"
1236: "andcc %0,%2<<%1,%%g0")
1237:
1238: (define_insn ""
1239: [(set (cc0)
1240: (and:SI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1241: (match_operand:SI 1 "small_int" "n"))
1242: (match_operand:SI 2 "small_int" "n")))]
1243: "(unsigned)((INTVAL (operands[2]) << INTVAL (operands[1])) + 0x1000) < 0x2000"
1244: "andcc %0,%2<<%1,%%g0")
1245:
1246: ;; Conversions between float and double.
1247:
1248: (define_insn "extendsfdf2"
1249: [(set (match_operand:DF 0 "register_operand" "=f")
1250: (float_extend:DF
1251: (match_operand:SF 1 "register_operand" "f")))]
1252: ""
1253: "fstod %1,%0")
1254:
1255: (define_insn "truncdfsf2"
1256: [(set (match_operand:SF 0 "register_operand" "=f")
1257: (float_truncate:SF
1258: (match_operand:DF 1 "register_operand" "f")))]
1259: ""
1260: "fdtos %1,%0")
1261:
1262: ;; Conversion between fixed point and floating point.
1263: ;; Note that among the fix-to-float insns
1264: ;; the ones that start with SImode come first.
1265: ;; That is so that an operand that is a CONST_INT
1266: ;; (and therefore lacks a specific machine mode).
1267: ;; will be recognized as SImode (which is always valid)
1268: ;; rather than as QImode or HImode.
1269:
1270: ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
1271: ;; to be reloaded by putting the constant into memory.
1272: ;; It must come before the more general floatsisf2 pattern.
1273: (define_insn ""
1274: [(set (match_operand:SF 0 "general_operand" "=f")
1275: (float:SF (match_operand 1 "" "m")))]
1276: "GET_CODE (operands[1]) == CONST_INT"
1277: "*
1278: {
1279: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1280: {
1281: cc_status.flags |= CC_KNOW_HI_G1;
1282: cc_status.mdep = XEXP (operands[1], 0);
1283: return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitos %0,%0\";
1284: }
1285: return \"ld %1,%0\;fitos %0,%0\";
1286: }")
1287:
1288: (define_insn "floatsisf2"
1.1.1.4 ! root 1289: [(set (match_operand:SF 0 "general_operand" "=f,f")
! 1290: (float:SF (match_operand:SI 1 "general_operand" "r,fm")))]
1.1 root 1291: ""
1292: "*
1293: {
1294: if (GET_CODE (operands[1]) == MEM)
1295: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1296: {
1297: cc_status.flags |= CC_KNOW_HI_G1;
1298: cc_status.mdep = XEXP (operands[1], 0);
1299: return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitos %0,%0\";
1300: }
1301: else
1302: return \"ld %1,%0\;fitos %0,%0\";
1303: else if (FP_REG_P (operands[1]))
1304: return \"fitos %1,%0\";
1305: return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\;fitos %0,%0\";
1306: }")
1307:
1308: ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
1309: ;; to be reloaded by putting the constant into memory.
1310: ;; It must come before the more general floatsidf2 pattern.
1311: (define_insn ""
1312: [(set (match_operand:DF 0 "general_operand" "=f")
1313: (float:DF (match_operand 1 "" "m")))]
1314: "GET_CODE (operands[1]) == CONST_INT"
1315: "*
1316: {
1317: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1318: {
1319: cc_status.flags |= CC_KNOW_HI_G1;
1320: cc_status.mdep = XEXP (operands[1], 0);
1321: return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitod %0,%0\";
1322: }
1323: return \"ld %1,%0\;fitod %0,%0\";
1324: }")
1325:
1326: (define_insn "floatsidf2"
1.1.1.4 ! root 1327: [(set (match_operand:DF 0 "general_operand" "=f,f")
! 1328: (float:DF (match_operand:SI 1 "general_operand" "r,fm")))]
1.1 root 1329: ""
1330: "*
1331: {
1332: if (GET_CODE (operands[1]) == MEM)
1333: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1334: {
1335: cc_status.flags |= CC_KNOW_HI_G1;
1336: cc_status.mdep = XEXP (operands[1], 0);
1337: return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitod %0,%0\";
1338: }
1339: else
1340: return \"ld %1,%0\;fitod %0,%0\";
1341: else if (FP_REG_P (operands[1]))
1342: return \"fitod %1,%0\";
1343: else
1344: return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\;fitod %0,%0\";
1345: }")
1346:
1347: ;; Convert a float to an actual integer.
1348: ;; Truncation is performed as part of the conversion.
1349: (define_insn "fix_truncsfsi2"
1350: [(set (match_operand:SI 0 "general_operand" "=rm")
1351: (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))]
1352: ""
1353: "*
1354: {
1355: cc_status.flags &= ~(CC_F1_IS_0);
1356: if (FP_REG_P (operands[1]))
1357: output_asm_insn (\"fstoi %1,%%f1\", operands);
1358: else if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1359: {
1360: cc_status.flags |= CC_KNOW_HI_G1;
1361: cc_status.mdep = XEXP (operands[1], 0);
1362: output_asm_insn (\"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%%f1\;fstoi %%f1,%%f1\", operands);
1363: }
1364: else
1365: output_asm_insn (\"ld %1,%%f1\;fstoi %%f1,%%f1\", operands);
1366: if (GET_CODE (operands[0]) == MEM)
1367: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1368: {
1369: if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
1370: && XEXP (operands[0], 0) == cc_prev_status.mdep))
1371: {
1372: cc_status.flags |= CC_KNOW_HI_G1;
1373: cc_status.mdep = XEXP (operands[0], 0);
1374: output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
1375: }
1376: return \"st %%f1,[%%g1+%%lo(%m0)]\";
1377: }
1378: else
1379: return \"st %%f1,%0\";
1380: else
1381: return \"st %%f1,[%%fp-4]\;ld [%%fp-4],%0\";
1382: }")
1383:
1384: (define_insn "fix_truncdfsi2"
1385: [(set (match_operand:SI 0 "general_operand" "=rm")
1386: (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))]
1387: ""
1388: "*
1389: {
1390: cc_status.flags &= ~CC_F0_IS_0;
1391: if (FP_REG_P (operands[1]))
1392: output_asm_insn (\"fdtoi %1,%%f0\", operands);
1393: else
1394: {
1395: rtx xoperands[2];
1396: xoperands[0] = gen_rtx (REG, DFmode, 32);
1397: xoperands[1] = operands[1];
1398: output_asm_insn (output_fp_move_double (xoperands), xoperands);
1399: output_asm_insn (\"fdtoi %%f0,%%f0\", 0);
1400: }
1401: if (GET_CODE (operands[0]) == MEM)
1402: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1403: {
1404: if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
1405: && XEXP (operands[0], 0) == cc_prev_status.mdep))
1406: {
1407: cc_status.flags |= CC_KNOW_HI_G1;
1408: cc_status.mdep = XEXP (operands[0], 0);
1409: output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
1410: }
1411: return \"st %%f0,[%%g1+%%lo(%m0)]\";
1412: }
1413: else
1414: return \"st %%f0,%0\";
1415: else
1416: return \"st %%f0,[%%fp-4]\;ld [%%fp-4],%0\";
1417: }")
1418:
1419: ;;- arithmetic instructions
1420:
1421: (define_insn "addsi3"
1422: [(set (match_operand:SI 0 "register_operand" "=r")
1423: (plus:SI (match_operand:SI 1 "arith32_operand" "%r")
1424: (match_operand:SI 2 "arith32_operand" "rn")))]
1425: ""
1426: "*
1427: {
1428: if (REG_P (operands[2]))
1429: return \"add %1,%2,%0\";
1430: if (SMALL_INT (operands[2]))
1431: return \"add %1,%2,%0\";
1432: cc_status.flags &= ~CC_KNOW_HI_G1;
1433: return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;add %1,%%g1,%0\";
1434: }")
1435:
1436: (define_insn "subsi3"
1437: [(set (match_operand:SI 0 "register_operand" "=r")
1438: (minus:SI (match_operand:SI 1 "register_operand" "r")
1439: (match_operand:SI 2 "arith32_operand" "rn")))]
1440: ""
1441: "*
1442: {
1443: if (REG_P (operands[2]))
1444: return \"sub %1,%2,%0\";
1445: if (SMALL_INT (operands[2]))
1446: return \"sub %1,%2,%0\";
1447: cc_status.flags &= ~CC_KNOW_HI_G1;
1448: return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;sub %1,%%g1,%0\";
1449: }")
1450:
1451: (define_expand "mulsi3"
1452: [(set (match_operand:SI 0 "register_operand" "r")
1453: (mult:SI (match_operand:SI 1 "general_operand" "")
1454: (match_operand:SI 2 "general_operand" "")))]
1455: ""
1456: "
1457: {
1458: rtx src;
1459:
1460: if (GET_CODE (operands[1]) == CONST_INT)
1461: if (GET_CODE (operands[2]) == CONST_INT)
1462: {
1463: emit_move_insn (operands[0],
1464: gen_rtx (CONST_INT, VOIDmode,
1465: INTVAL (operands[1]) * INTVAL (operands[2])));
1466: DONE;
1467: }
1468: else
1469: src = gen_rtx (MULT, SImode,
1470: copy_to_mode_reg (SImode, operands[2]),
1471: operands[1]);
1472: else if (GET_CODE (operands[2]) == CONST_INT)
1473: src = gen_rtx (MULT, SImode,
1474: copy_to_mode_reg (SImode, operands[1]),
1475: operands[2]);
1476: else src = 0;
1477:
1478: if (src)
1479: emit_insn (gen_rtx (SET, VOIDmode, operands[0], src));
1480: else
1481: emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5,
1482: gen_rtx (SET, VOIDmode, operands[0],
1483: gen_rtx (MULT, SImode, operands[1], operands[2])),
1484: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 8)),
1485: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 9)),
1486: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 12)),
1487: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 13)))));
1488: DONE;
1489: }")
1490:
1491: (define_expand "umulsi3"
1492: [(set (match_operand:SI 0 "register_operand" "r")
1493: (umult:SI (match_operand:SI 1 "general_operand" "")
1494: (match_operand:SI 2 "general_operand" "")))]
1495: ""
1496: "
1497: {
1498: rtx src;
1499:
1500: if (GET_CODE (operands[1]) == CONST_INT)
1501: if (GET_CODE (operands[2]) == CONST_INT)
1502: {
1503: emit_move_insn (operands[0],
1504: gen_rtx (CONST_INT, VOIDmode,
1505: (unsigned)INTVAL (operands[1]) * (unsigned)INTVAL (operands[2])));
1506: DONE;
1507: }
1508: else
1509: src = gen_rtx (UMULT, SImode,
1510: copy_to_mode_reg (SImode, operands[2]),
1511: operands[1]);
1512: else if (GET_CODE (operands[2]) == CONST_INT)
1513: src = gen_rtx (UMULT, SImode,
1514: copy_to_mode_reg (SImode, operands[1]),
1515: operands[2]);
1516: else src = 0;
1517:
1518: if (src)
1519: emit_insn (gen_rtx (SET, VOIDmode, operands[0], src));
1520: else
1521: emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5,
1522: gen_rtx (SET, VOIDmode, operands[0],
1523: gen_rtx (UMULT, SImode, operands[1], operands[2])),
1524: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 8)),
1525: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 9)),
1526: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 12)),
1527: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 13)))));
1528: DONE;
1529: }")
1530:
1531: (define_insn ""
1532: [(set (match_operand:SI 0 "register_operand" "=r")
1533: (mult:SI (match_operand:SI 1 "register_operand" "r")
1534: (match_operand:SI 2 "immediate_operand" "n")))]
1535: ""
1536: "* return output_mul_by_constant (insn, operands, 0);")
1537:
1538: (define_insn ""
1539: [(set (match_operand:SI 0 "register_operand" "=r")
1540: (umult:SI (match_operand:SI 1 "register_operand" "r")
1541: (match_operand:SI 2 "immediate_operand" "n")))]
1542: ""
1543: "* return output_mul_by_constant (insn, operands, 1);")
1544:
1545: (define_insn ""
1546: [(set (match_operand:SI 0 "register_operand" "=r")
1547: (mult:SI (match_operand:SI 1 "general_operand" "%r")
1548: (match_operand:SI 2 "general_operand" "r")))
1549: (clobber (reg:SI 8))
1550: (clobber (reg:SI 9))
1551: (clobber (reg:SI 12))
1552: (clobber (reg:SI 13))]
1553: ""
1554: "* return output_mul_insn (operands, 0);")
1555:
1556: (define_insn ""
1557: [(set (match_operand:SI 0 "register_operand" "=r")
1558: (umult:SI (match_operand:SI 1 "general_operand" "%r")
1559: (match_operand:SI 2 "general_operand" "r")))
1560: (clobber (reg:SI 8))
1561: (clobber (reg:SI 9))
1562: (clobber (reg:SI 12))
1563: (clobber (reg:SI 13))]
1564: ""
1565: "* return output_mul_insn (operands, 1);")
1566:
1567: ;; this pattern is needed because cse may eliminate the multiplication,
1568: ;; but leave the clobbers behind.
1569:
1570: (define_insn ""
1571: [(set (match_operand:SI 0 "register_operand" "=r")
1572: (match_operand:SI 1 "general_operand" "g"))
1573: (clobber (reg:SI 8))
1574: (clobber (reg:SI 9))
1575: (clobber (reg:SI 12))
1576: (clobber (reg:SI 13))]
1577: ""
1578: "*
1579: {
1580: if (GET_CODE (operands[1]) == CONST_INT)
1581: {
1582: if (SMALL_INT (operands[1]))
1583: return \"mov %1,%0\";
1584: return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\";
1585: }
1586: if (GET_CODE (operands[1]) == MEM)
1587: return \"ld %1,%0\";
1588: return \"mov %1,%0\";
1589: }")
1590:
1.1.1.2 root 1591: ;; In case constant factor turns out to be -1.
1592: (define_insn ""
1593: [(set (match_operand:SI 0 "register_operand" "=r")
1594: (neg:SI (match_operand:SI 1 "general_operand" "rI")))
1595: (clobber (reg:SI 8))
1596: (clobber (reg:SI 9))
1597: (clobber (reg:SI 12))
1598: (clobber (reg:SI 13))]
1599: ""
1600: "sub %%g0,%1,%0")
1601:
1.1 root 1602: ;;- and instructions (with compliment also)
1603: (define_insn "andsi3"
1604: [(set (match_operand:SI 0 "register_operand" "=r")
1605: (and:SI (match_operand:SI 1 "arith32_operand" "%r")
1606: (match_operand:SI 2 "arith32_operand" "rn")))]
1607: ""
1608: "*
1609: {
1610: if (REG_P (operands[2]) || SMALL_INT (operands[2]))
1611: return \"and %1,%2,%0\";
1612: cc_status.flags &= ~CC_KNOW_HI_G1;
1613: return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;and %1,%%g1,%0\";
1614: }")
1615:
1616: (define_insn "andcbsi3"
1617: [(set (match_operand:SI 0 "register_operand" "=r")
1618: (and:SI (match_operand:SI 1 "register_operand" "r")
1619: (not:SI (match_operand:SI 2 "register_operand" "r"))))]
1620: ""
1621: "andn %1,%2,%0")
1622:
1623: (define_insn "iorsi3"
1624: [(set (match_operand:SI 0 "register_operand" "=r")
1625: (ior:SI (match_operand:SI 1 "arith32_operand" "%r")
1626: (match_operand:SI 2 "arith32_operand" "rn")))]
1627: ""
1628: "*
1629: {
1630: if (REG_P (operands[2]) || SMALL_INT (operands[2]))
1631: return \"or %1,%2,%0\";
1632: cc_status.flags &= ~CC_KNOW_HI_G1;
1633: return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;or %1,%%g1,%0\";
1634: }")
1635:
1636: (define_insn "iorcbsi3"
1637: [(set (match_operand:SI 0 "register_operand" "=r")
1638: (ior:SI (match_operand:SI 1 "register_operand" "r")
1639: (not:SI (match_operand:SI 2 "register_operand" "r"))))]
1640: ""
1641: "orn %1,%2,%0")
1642:
1643: (define_insn "xorsi3"
1644: [(set (match_operand:SI 0 "register_operand" "=r")
1645: (xor:SI (match_operand:SI 1 "arith32_operand" "%r")
1646: (match_operand:SI 2 "arith32_operand" "rn")))]
1647: ""
1648: "*
1649: {
1650: if (REG_P (operands[2]) || SMALL_INT (operands[2]))
1651: return \"xor %1,%2,%0\";
1652: cc_status.flags &= ~CC_KNOW_HI_G1;
1653: return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;xor %1,%%g1,%0\";
1654: }")
1655:
1656: (define_insn "xorcbsi3"
1657: [(set (match_operand:SI 0 "register_operand" "=r")
1658: (xor:SI (match_operand:SI 1 "register_operand" "r")
1659: (not:SI (match_operand:SI 2 "register_operand" "r"))))]
1660: ""
1661: "xnor %1,%2,%0")
1662:
1663: ;; We cannot use the "neg" pseudo insn because the Sun assembler
1664: ;; does not know how to make it work for constants.
1665: (define_insn "negsi2"
1666: [(set (match_operand:SI 0 "general_operand" "=r")
1667: (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
1668: ""
1669: "sub %%g0,%1,%0")
1670:
1671: ;; We cannot use the "not" pseudo insn because the Sun assembler
1672: ;; does not know how to make it work for constants.
1673: (define_insn "one_cmplsi2"
1674: [(set (match_operand:SI 0 "general_operand" "=r")
1675: (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
1676: ""
1677: "xnor %%g0,%1,%0")
1678:
1679: ;; Floating point arithmetic instructions.
1680:
1681: (define_insn "adddf3"
1682: [(set (match_operand:DF 0 "register_operand" "=f")
1683: (plus:DF (match_operand:DF 1 "register_operand" "f")
1684: (match_operand:DF 2 "register_operand" "f")))]
1685: ""
1686: "faddd %1,%2,%0")
1687:
1688: (define_insn "addsf3"
1689: [(set (match_operand:SF 0 "register_operand" "=f")
1690: (plus:SF (match_operand:SF 1 "register_operand" "f")
1691: (match_operand:SF 2 "register_operand" "f")))]
1692: ""
1693: "fadds %1,%2,%0")
1694:
1695: (define_insn "subdf3"
1696: [(set (match_operand:DF 0 "register_operand" "=f")
1697: (minus:DF (match_operand:DF 1 "register_operand" "f")
1698: (match_operand:DF 2 "register_operand" "f")))]
1699: ""
1700: "fsubd %1,%2,%0")
1701:
1702: (define_insn "subsf3"
1703: [(set (match_operand:SF 0 "register_operand" "=f")
1704: (minus:SF (match_operand:SF 1 "register_operand" "f")
1705: (match_operand:SF 2 "register_operand" "f")))]
1706: ""
1707: "fsubs %1,%2,%0")
1708:
1709: (define_insn "muldf3"
1710: [(set (match_operand:DF 0 "register_operand" "=f")
1711: (mult:DF (match_operand:DF 1 "register_operand" "f")
1712: (match_operand:DF 2 "register_operand" "f")))]
1713: ""
1714: "fmuld %1,%2,%0")
1715:
1716: (define_insn "mulsf3"
1717: [(set (match_operand:SF 0 "register_operand" "=f")
1718: (mult:SF (match_operand:SF 1 "register_operand" "f")
1719: (match_operand:SF 2 "register_operand" "f")))]
1720: ""
1721: "fmuls %1,%2,%0")
1722:
1723: (define_insn "divdf3"
1724: [(set (match_operand:DF 0 "register_operand" "=f")
1725: (div:DF (match_operand:DF 1 "register_operand" "f")
1726: (match_operand:DF 2 "register_operand" "f")))]
1727: ""
1728: "fdivd %1,%2,%0")
1729:
1730: (define_insn "divsf3"
1731: [(set (match_operand:SF 0 "register_operand" "=f")
1732: (div:SF (match_operand:SF 1 "register_operand" "f")
1733: (match_operand:SF 2 "register_operand" "f")))]
1734: ""
1735: "fdivs %1,%2,%0")
1736:
1737: (define_insn "negdf2"
1738: [(set (match_operand:DF 0 "register_operand" "=f")
1739: (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1740: ""
1741: "*
1742: {
1743: output_asm_insn (\"fnegs %1,%0\", operands);
1744: if (REGNO (operands[0]) != REGNO (operands[1]))
1745: {
1746: operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1);
1747: operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1);
1748: output_asm_insn (\"fmovs %1,%0\", operands);
1749: }
1750: return \"\";
1751: }")
1752:
1753: (define_insn "negsf2"
1754: [(set (match_operand:SF 0 "register_operand" "=f")
1755: (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1756: ""
1757: "fnegs %1,%0")
1758:
1759: (define_insn "absdf2"
1760: [(set (match_operand:DF 0 "register_operand" "=f")
1761: (abs:DF (match_operand:DF 1 "register_operand" "f")))]
1762: ""
1763: "*
1764: {
1765: output_asm_insn (\"fabss %1,%0\", operands);
1766: if (REGNO (operands[0]) != REGNO (operands[1]))
1767: {
1768: operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1);
1769: operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1);
1770: output_asm_insn (\"fmovs %1,%0\", operands);
1771: }
1772: return \"\";
1773: }")
1774:
1775: (define_insn "abssf2"
1776: [(set (match_operand:SF 0 "register_operand" "=f")
1777: (abs:SF (match_operand:SF 1 "register_operand" "f")))]
1778: ""
1779: "fabss %1,%0")
1780:
1781: ;; Shift instructions
1782:
1783: ;; Optimized special case of shifting.
1784: ;; Must precede the general case.
1785:
1786: (define_insn ""
1787: [(set (match_operand:SI 0 "register_operand" "=r")
1788: (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
1789: (const_int 24)))]
1790: ""
1791: "*
1792: {
1793: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1794: {
1795: cc_status.flags |= CC_KNOW_HI_G1;
1796: cc_status.mdep = XEXP (operands[1], 0);
1797: return \"sethi %%hi(%m1),%%g1\;ldsb [%%g1+%%lo(%m1)],%0\";
1798: }
1799: return \"ldsb %1,%0\";
1800: }")
1801:
1802: (define_insn ""
1803: [(set (match_operand:SI 0 "register_operand" "=r")
1804: (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
1805: (const_int 24)))]
1806: ""
1807: "*
1808: {
1809: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1810: {
1811: cc_status.flags |= CC_KNOW_HI_G1;
1812: cc_status.mdep = XEXP (operands[1], 0);
1813: return \"sethi %%hi(%m1),%%g1\;ldub [%%g1+%%lo(%m1)],%0\";
1814: }
1815: return \"ldub %1,%0\";
1816: }")
1817:
1818: ;;- arithmetic shift instructions
1819: (define_insn "ashlsi3"
1820: [(set (match_operand:SI 0 "register_operand" "=r")
1821: (ashift:SI (match_operand:SI 1 "register_operand" "r")
1822: (match_operand:SI 2 "arith32_operand" "rn")))]
1823: ""
1824: "*
1825: {
1826: if (GET_CODE (operands[2]) == CONST_INT
1827: && INTVAL (operands[2]) >= 32)
1828: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31);
1829: return \"sll %1,%2,%0\";
1830: }")
1831:
1832: (define_insn "ashrsi3"
1833: [(set (match_operand:SI 0 "register_operand" "=r")
1834: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
1835: (match_operand:SI 2 "arith32_operand" "rn")))]
1836: ""
1837: "*
1838: {
1839: if (GET_CODE (operands[2]) == CONST_INT
1840: && INTVAL (operands[2]) >= 32)
1841: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31);
1842: return \"sra %1,%2,%0\";
1843: }")
1844:
1845: (define_insn "lshrsi3"
1846: [(set (match_operand:SI 0 "register_operand" "=r")
1847: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1848: (match_operand:SI 2 "arith32_operand" "rn")))]
1849: ""
1850: "*
1851: {
1852: if (GET_CODE (operands[2]) == CONST_INT
1853: && INTVAL (operands[2]) >= 32)
1854: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31);
1855: return \"srl %1,%2,%0\";
1856: }")
1857:
1858: ;; Unconditional and other jump instructions
1859: ;; Note that for the Sparc, by setting the annul bit on an unconditional
1860: ;; branch, the following insn is never executed. This saves us a nop,
1861: ;; but requires a debugger which can handle annuled branches.
1862: (define_insn "jump"
1863: [(set (pc) (label_ref (match_operand 0 "" "")))]
1864: ""
1865: "*
1866: {
1867: extern int optimize;
1868: extern int flag_no_peephole;
1869:
1870: if (optimize && !flag_no_peephole)
1871: return \"b,a %l0\";
1872: return \"b %l0\;nop\";
1873: }")
1874:
1875: ;; Peephole optimizers recognize a few simple cases when delay insns are safe.
1876: ;; Complex ones are up front. Simple ones after.
1877:
1878: ;; This pattern is just like the following one, but matches when there
1879: ;; is a jump insn after the "delay" insn. Without this pattern, we
1880: ;; de-optimize that case.
1881:
1882: (define_peephole
1883: [(set (pc) (match_operand 0 "" ""))
1884: (set (match_operand:SI 1 "" "")
1885: (match_operand:SI 2 "" ""))
1886: (set (pc) (label_ref (match_operand 3 "" "")))]
1887: "TARGET_EAGER && operands_satisfy_eager_branch_peephole (operands, 2)"
1888: "*
1889: {
1890: rtx xoperands[2];
1891: rtx pat = gen_rtx (SET, VOIDmode, operands[1], operands[2]);
1892: rtx delay_insn = gen_rtx (INSN, VOIDmode, 0, 0, 0, pat, -1, 0, 0);
1893: rtx label, head;
1894: int parity;
1895:
1896: if (GET_CODE (XEXP (operands[0], 1)) == PC)
1897: {
1898: parity = 1;
1899: label = XEXP (XEXP (operands[0], 2), 0);
1900: }
1901: else
1902: {
1903: parity = 0;
1904: label = XEXP (XEXP (operands[0], 1), 0);
1905: }
1906: xoperands[0] = XEXP (operands[0], 0);
1907: xoperands[1] = label;
1908:
1909: head = next_real_insn_no_labels (label);
1910:
1911: /* If at the target of this label we set the condition codes,
1912: and the condition codes are already set for that value,
1913: advance, if we can, to the following insn. */
1914: if (GET_CODE (PATTERN (head)) == SET
1915: && GET_CODE (SET_DEST (PATTERN (head))) == CC0
1916: && cc_status.value2 == SET_SRC (PATTERN (head)))
1917: {
1918: rtx nhead = next_real_insn_no_labels (head);
1919: if (nhead
1920: && GET_CODE (nhead) == INSN
1921: && GET_CODE (PATTERN (nhead)) == SET
1922: && strict_single_insn_op_p (SET_SRC (PATTERN (nhead)),
1923: GET_MODE (SET_DEST (PATTERN (nhead))))
1.1.1.2 root 1924: && strict_single_insn_op_p (SET_DEST (PATTERN (nhead)), VOIDmode)
1925: /* Moves between FP regs and CPU regs are two insns. */
1926: && !(GET_CODE (SET_SRC (PATTERN (nhead))) == REG
1927: && GET_CODE (SET_DEST (PATTERN (nhead))) == REG
1928: && (FP_REG_P (SET_SRC (PATTERN (nhead)))
1929: != FP_REG_P (SET_DEST (PATTERN (nhead))))))
1.1 root 1930: {
1931: head = nhead;
1932: }
1933: }
1934:
1935: /* Output the branch instruction first. */
1936: if (cc_prev_status.flags & CC_IN_FCCR)
1937: {
1938: if (parity)
1939: output_asm_insn (\"fb%F0,a %l1 ! eager\", xoperands);
1940: else
1941: output_asm_insn (\"fb%C0,a %l1 ! eager\", xoperands);
1942: }
1.1.1.3 root 1943: else if (cc_prev_status.flags & CC_NO_OVERFLOW)
1944: {
1945: if (parity)
1946: output_asm_insn (\"b%U0,a %l1 ! eager\", xoperands);
1947: else
1948: output_asm_insn (\"b%I0,a %l1 ! eager\", xoperands);
1949: }
1.1 root 1950: else
1951: {
1952: if (parity)
1953: output_asm_insn (\"b%N0,a %l1 ! eager\", xoperands);
1954: else
1955: output_asm_insn (\"b%C0,a %l1 ! eager\", xoperands);
1956: }
1957:
1958: /* Now steal the first insn of the target. */
1959: output_eager_then_insn (head, operands);
1960:
1961: XVECEXP (PATTERN (insn), 0, 0) = XVECEXP (PATTERN (insn), 0, 1);
1962: XVECEXP (PATTERN (insn), 0, 1) = XVECEXP (PATTERN (insn), 0, 2);
1963:
1964: return output_delayed_branch (\"b %l3 ! eager2\", operands, insn);
1965: }")
1966:
1967: ;; Here is a peephole which recognizes where delay insns can be made safe:
1968: ;; (1) following a conditional branch, if the target of the conditional branch
1969: ;; has only one user (this insn), move the first insn into our delay slot
1970: ;; and emit an annulled branch.
1971: ;; (2) following a conditional branch, if we can execute the fall-through
1972: ;; insn without risking any evil effects, then do that instead of a nop.
1973:
1974: (define_peephole
1975: [(set (pc) (match_operand 0 "" ""))
1976: (set (match_operand:SI 1 "" "")
1977: (match_operand:SI 2 "" ""))]
1978: "TARGET_EAGER && operands_satisfy_eager_branch_peephole (operands, 1)"
1979: "*
1980: {
1981: rtx xoperands[2];
1982: rtx pat = gen_rtx (SET, VOIDmode, operands[1], operands[2]);
1983: rtx delay_insn = gen_rtx (INSN, VOIDmode, 0, 0, 0, pat, -1, 0, 0);
1984: rtx label, head, prev = (rtx)1;
1985: int parity;
1986:
1987: if (GET_CODE (XEXP (operands[0], 1)) == PC)
1988: {
1989: parity = 1;
1990: label = XEXP (XEXP (operands[0], 2), 0);
1991: }
1992: else
1993: {
1994: parity = 0;
1995: label = XEXP (XEXP (operands[0], 1), 0);
1996: }
1997: xoperands[0] = XEXP (operands[0], 0);
1998: xoperands[1] = label;
1999:
2000: if (LABEL_NUSES (label) == 1)
2001: {
2002: prev = PREV_INSN (label);
2003: while (prev
2004: && (GET_CODE (prev) == NOTE
2005: || (GET_CODE (prev) == INSN
2006: && (GET_CODE (PATTERN (prev)) == CLOBBER
2007: || GET_CODE (PATTERN (prev)) == USE))))
2008: prev = PREV_INSN (prev);
2009: if (prev == 0
2010: || GET_CODE (prev) == BARRIER)
2011: {
2012: prev = 0;
2013: head = next_real_insn_no_labels (label);
2014: }
2015: }
2016: if (prev == 0
2017: && head != 0
2018: && ! INSN_DELETED_P (head)
2019: && GET_CODE (head) == INSN
2020: && GET_CODE (PATTERN (head)) == SET
2021: && strict_single_insn_op_p (SET_SRC (PATTERN (head)),
2022: GET_MODE (SET_DEST (PATTERN (head))))
1.1.1.2 root 2023: && strict_single_insn_op_p (SET_DEST (PATTERN (head)), VOIDmode)
2024: /* Moves between FP regs and CPU regs are two insns. */
2025: && !(GET_CODE (SET_SRC (PATTERN (head))) == REG
2026: && GET_CODE (SET_DEST (PATTERN (head))) == REG
2027: && (FP_REG_P (SET_SRC (PATTERN (head)))
2028: != FP_REG_P (SET_DEST (PATTERN (head))))))
1.1 root 2029: {
2030: /* If at the target of this label we set the condition codes,
2031: and the condition codes are already set for that value,
2032: advance, if we can, to the following insn. */
2033: if (GET_CODE (PATTERN (head)) == SET
2034: && GET_CODE (SET_DEST (PATTERN (head))) == CC0
2035: && cc_status.value2 == SET_SRC (PATTERN (head)))
2036: {
2037: rtx nhead = next_real_insn_no_labels (head);
2038: if (nhead
2039: && GET_CODE (nhead) == INSN
2040: && GET_CODE (PATTERN (nhead)) == SET
2041: && strict_single_insn_op_p (SET_SRC (PATTERN (nhead)),
2042: GET_MODE (SET_DEST (nhead)))
1.1.1.2 root 2043: && strict_single_insn_op_p (SET_DEST (PATTERN (nhead)), VOIDmode)
2044: /* Moves between FP regs and CPU regs are two insns. */
2045: && !(GET_CODE (SET_SRC (PATTERN (nhead))) == REG
2046: && GET_CODE (SET_DEST (PATTERN (nhead))) == REG
2047: && (FP_REG_P (SET_SRC (PATTERN (nhead)))
2048: != FP_REG_P (SET_DEST (PATTERN (nhead))))))
1.1 root 2049: head = nhead;
2050: }
2051:
2052: /* Output the branch instruction first. */
2053: if (cc_prev_status.flags & CC_IN_FCCR)
2054: {
2055: if (parity)
2056: output_asm_insn (\"fb%F0,a %l1 ! eager\", xoperands);
2057: else
2058: output_asm_insn (\"fb%C0,a %l1 ! eager\", xoperands);
2059: }
1.1.1.3 root 2060: else if (cc_prev_status.flags & CC_NO_OVERFLOW)
2061: {
2062: if (parity)
2063: output_asm_insn (\"b%U0,a %l1 ! eager\", xoperands);
2064: else
2065: output_asm_insn (\"b%I0,a %l1 ! eager\", xoperands);
2066: }
1.1 root 2067: else
2068: {
2069: if (parity)
2070: output_asm_insn (\"b%N0,a %l1 ! eager\", xoperands);
2071: else
2072: output_asm_insn (\"b%C0,a %l1 ! eager\", xoperands);
2073: }
2074:
2075: /* Now steal the first insn of the target. */
2076: output_eager_then_insn (head, operands);
2077: }
2078: else
2079: {
2080: /* Output the branch instruction first. */
2081: if (cc_prev_status.flags & CC_IN_FCCR)
2082: {
2083: if (parity)
2084: output_asm_insn (\"fb%F0 %l1 ! eager\", xoperands);
2085: else
2086: output_asm_insn (\"fb%C0 %l1 ! eager\", xoperands);
2087: }
1.1.1.3 root 2088: else if (cc_prev_status.flags & CC_NO_OVERFLOW)
2089: {
2090: if (parity)
2091: output_asm_insn (\"b%U0,a %l1 ! eager\", xoperands);
2092: else
2093: output_asm_insn (\"b%I0,a %l1 ! eager\", xoperands);
2094: }
1.1 root 2095: else
2096: {
2097: if (parity)
2098: output_asm_insn (\"b%N0 %l1 ! eager\", xoperands);
2099: else
2100: output_asm_insn (\"b%C0 %l1 ! eager\", xoperands);
2101: }
2102: }
2103: return output_delay_insn (delay_insn);
2104: }")
2105:
2106: ;; Here are two simple peepholes which fill the delay slot of
2107: ;; an unconditional branch.
2108:
2109: (define_peephole
2110: [(set (match_operand:SI 0 "register_operand" "=r")
2111: (match_operand:SI 1 "single_insn_src_p" "p"))
2112: (set (pc) (label_ref (match_operand 2 "" "")))]
1.1.1.2 root 2113: "single_insn_extra_test (operands[0], operands[1])"
1.1 root 2114: "* return output_delayed_branch (\"b %l2\", operands, insn);")
2115:
2116: (define_peephole
2117: [(set (match_operand:SI 0 "memory_operand" "=m")
2118: (match_operand:SI 1 "reg_or_0_operand" "rJ"))
2119: (set (pc) (label_ref (match_operand 2 "" "")))]
2120: ""
2121: "* return output_delayed_branch (\"b %l2\", operands, insn);")
2122:
2123: (define_insn "tablejump"
2124: [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2125: (use (label_ref (match_operand 1 "" "")))]
2126: ""
2127: "jmp %0\;nop")
2128:
2129: (define_peephole
2130: [(set (match_operand:SI 0 "register_operand" "=r")
2131: (match_operand:SI 1 "single_insn_src_p" "p"))
1.1.1.2 root 2132: (parallel [(set (pc) (match_operand:SI 2 "register_operand" "r"))
2133: (use (label_ref (match_operand 3 "" "")))])]
2134: "REGNO (operands[0]) != REGNO (operands[2])
2135: && single_insn_extra_test (operands[0], operands[1])"
1.1 root 2136: "* return output_delayed_branch (\"jmp %2\", operands, insn);")
2137:
2138: (define_peephole
2139: [(set (match_operand:SI 0 "memory_operand" "=m")
2140: (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1.1.1.2 root 2141: (parallel [(set (pc) (match_operand:SI 2 "register_operand" "r"))
2142: (use (label_ref (match_operand 3 "" "")))])]
1.1 root 2143: ""
2144: "* return output_delayed_branch (\"jmp %2\", operands, insn);")
2145:
2146: ;;- jump to subroutine
2147: (define_expand "call"
2148: [(call (match_operand:SI 0 "memory_operand" "m")
2149: (match_operand 1 "" "i"))]
2150: ;; operand[2] is next_arg_register
2151: ""
2152: "
2153: {
2154: rtx fn_rtx, nregs_rtx;
2155:
2156: if (TARGET_SUN_ASM && GET_CODE (XEXP (operands[0], 0)) == REG)
2157: {
2158: rtx g1_rtx = gen_rtx (REG, SImode, 1);
2159: emit_move_insn (g1_rtx, XEXP (operands[0], 0));
2160: fn_rtx = gen_rtx (MEM, SImode, g1_rtx);
2161: }
2162: else
2163: fn_rtx = operands[0];
2164:
2165: /* Count the number of parameter registers being used by this call.
2166: if that argument is NULL, it means we are using them all, which
2167: means 6 on the sparc. */
2168: #if 0
2169: if (operands[2])
2170: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
2171: else
2172: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2173: #else
2174: nregs_rtx = const0_rtx;
2175: #endif
2176:
2177: emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2178: gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2179: gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 31)))));
2180: DONE;
2181: }")
2182:
2183: (define_insn ""
2184: [(call (match_operand:SI 0 "memory_operand" "m")
2185: (match_operand 1 "" "i"))
2186: (use (reg:SI 31))]
2187: ;;- Don't use operand 1 for most machines.
1.1.1.3 root 2188: "CONSTANT_P (XEXP (operands[0], 0))
2189: || GET_CODE (XEXP (operands[0], 0)) == REG"
1.1 root 2190: "*
2191: {
2192: /* strip the MEM. */
2193: operands[0] = XEXP (operands[0], 0);
2194: CC_STATUS_INIT;
2195: if (TARGET_SUN_ASM && GET_CODE (operands[0]) == REG)
2196: return \"jmpl %a0,%%o7\;nop\";
2197: return \"call %a0,%1\;nop\";
2198: }")
2199:
2200: (define_peephole
2201: [(set (match_operand:SI 0 "register_operand" "=r")
2202: (match_operand:SI 1 "single_insn_src_p" "p"))
2203: (parallel [(call (match_operand:SI 2 "memory_operand" "m")
2204: (match_operand 3 "" "i"))
2205: (use (reg:SI 31))])]
2206: ;;- Don't use operand 1 for most machines.
1.1.1.2 root 2207: "! reg_mentioned_p (operands[0], operands[2])
2208: && single_insn_extra_test (operands[0], operands[1])"
1.1 root 2209: "*
2210: {
2211: /* strip the MEM. */
2212: operands[2] = XEXP (operands[2], 0);
2213: if (TARGET_SUN_ASM && GET_CODE (operands[2]) == REG)
2214: return output_delayed_branch (\"jmpl %a2,%%o7\", operands, insn);
2215: return output_delayed_branch (\"call %a2,%3\", operands, insn);
2216: }")
2217:
2218: (define_peephole
2219: [(set (match_operand:SI 0 "memory_operand" "=m")
2220: (match_operand:SI 1 "reg_or_0_operand" "rJ"))
2221: (parallel [(call (match_operand:SI 2 "memory_operand" "m")
2222: (match_operand 3 "" "i"))
2223: (use (reg:SI 31))])]
2224: ;;- Don't use operand 1 for most machines.
2225: ""
2226: "*
2227: {
2228: /* strip the MEM. */
2229: operands[2] = XEXP (operands[2], 0);
2230: if (TARGET_SUN_ASM && GET_CODE (operands[2]) == REG)
2231: return output_delayed_branch (\"jmpl %a2,%%o7\", operands, insn);
2232: return output_delayed_branch (\"call %a2,%3\", operands, insn);
2233: }")
2234:
2235: (define_expand "call_value"
2236: [(set (match_operand 0 "register_operand" "=rf")
2237: (call (match_operand:SI 1 "memory_operand" "m")
2238: (match_operand 2 "" "i")))]
2239: ;; operand 3 is next_arg_register
2240: ""
2241: "
2242: {
2243: rtx fn_rtx, nregs_rtx;
2244: rtvec vec;
2245:
2246: if (TARGET_SUN_ASM && GET_CODE (XEXP (operands[1], 0)) == REG)
2247: {
2248: rtx g1_rtx = gen_rtx (REG, SImode, 1);
2249: emit_move_insn (g1_rtx, XEXP (operands[1], 0));
2250: fn_rtx = gen_rtx (MEM, SImode, g1_rtx);
2251: }
2252: else
2253: fn_rtx = operands[1];
2254:
2255: #if 0
2256: if (operands[3])
2257: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
2258: else
2259: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2260: #else
2261: nregs_rtx = const0_rtx;
2262: #endif
2263:
2264: vec = gen_rtvec (2,
2265: gen_rtx (SET, VOIDmode, operands[0],
2266: gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
2267: gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 31)));
2268:
2269: emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
2270: DONE;
2271: }")
2272:
2273: (define_insn ""
2274: [(set (match_operand 0 "" "=rf")
2275: (call (match_operand:SI 1 "memory_operand" "m")
2276: (match_operand 2 "" "i")))
2277: (use (reg:SI 31))]
2278: ;;- Don't use operand 2 for most machines.
1.1.1.3 root 2279: "CONSTANT_P (XEXP (operands[1], 0))
2280: || GET_CODE (XEXP (operands[1], 0)) == REG"
1.1 root 2281: "*
2282: {
2283: /* strip the MEM. */
2284: operands[1] = XEXP (operands[1], 0);
2285: CC_STATUS_INIT;
2286: if (TARGET_SUN_ASM && GET_CODE (operands[1]) == REG)
2287: return \"jmpl %a1,%%o7\;nop\";
2288: return \"call %a1,%2\;nop\";
2289: }")
2290:
2291: (define_peephole
2292: [(set (match_operand:SI 0 "register_operand" "=r")
2293: (match_operand:SI 1 "single_insn_src_p" "p"))
2294: (parallel [(set (match_operand 2 "" "=rf")
2295: (call (match_operand:SI 3 "memory_operand" "m")
2296: (match_operand 4 "" "i")))
2297: (use (reg:SI 31))])]
2298: ;;- Don't use operand 4 for most machines.
1.1.1.2 root 2299: "! reg_mentioned_p (operands[0], operands[3])
2300: && single_insn_extra_test (operands[0], operands[1])"
1.1 root 2301: "*
2302: {
2303: /* strip the MEM. */
2304: operands[3] = XEXP (operands[3], 0);
2305: if (TARGET_SUN_ASM && GET_CODE (operands[3]) == REG)
2306: return output_delayed_branch (\"jmpl %a3,%%o7\", operands, insn);
2307: return output_delayed_branch (\"call %a3,%4\", operands, insn);
2308: }")
2309:
2310: (define_peephole
2311: [(set (match_operand:SI 0 "memory_operand" "=m")
2312: (match_operand:SI 1 "reg_or_0_operand" "rJ"))
2313: (parallel [(set (match_operand 2 "" "=rf")
2314: (call (match_operand:SI 3 "memory_operand" "m")
2315: (match_operand 4 "" "i")))
2316: (use (reg:SI 31))])]
2317: ;;- Don't use operand 4 for most machines.
2318: ""
2319: "*
2320: {
2321: /* strip the MEM. */
2322: operands[3] = XEXP (operands[3], 0);
2323: if (TARGET_SUN_ASM && GET_CODE (operands[3]) == REG)
2324: return output_delayed_branch (\"jmpl %a3,%%o7\", operands, insn);
2325: return output_delayed_branch (\"call %a3,%4\", operands, insn);
2326: }")
2327:
2328: (define_insn "return"
2329: [(return)]
2330: "! TARGET_EPILOGUE"
2331: "ret\;restore")
2332:
2333: (define_peephole
2334: [(set (reg:SI 24)
2335: (match_operand:SI 0 "reg_or_0_operand" "rJ"))
2336: (return)]
2337: "! TARGET_EPILOGUE"
2338: "ret\;restore %r0,0x0,%%o0")
2339:
2340: (define_peephole
2341: [(set (reg:SI 24)
2342: (plus:SI (match_operand:SI 0 "register_operand" "r%")
2343: (match_operand:SI 1 "arith_operand" "rI")))
2344: (return)]
2345: "! TARGET_EPILOGUE"
2346: "ret\;restore %r0,%1,%%o0")
2347:
2348: (define_peephole
2349: [(set (reg:SI 24)
2350: (minus:SI (match_operand:SI 0 "register_operand" "r")
2351: (match_operand:SI 1 "small_int" "I")))
2352: (return)]
2353: "! TARGET_EPILOGUE"
2354: "ret\;restore %0,-(%1),%%o0")
2355:
2356: (define_insn "nop"
2357: [(const_int 0)]
2358: ""
2359: "nop")
2360:
2361: ;;- Local variables:
2362: ;;- mode:emacs-lisp
2363: ;;- comment-start: ";;- "
2364: ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
2365: ;;- eval: (modify-syntax-entry ?[ "(]")
2366: ;;- eval: (modify-syntax-entry ?] ")[")
2367: ;;- eval: (modify-syntax-entry ?{ "(}")
2368: ;;- eval: (modify-syntax-entry ?} "){")
2369: ;;- End:
2370:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.