|
|
1.1 root 1: /* Subroutines for insn-output.c for Sun SPARC.
2: Copyright (C) 1987 Free Software Foundation, Inc.
3: Contributed by Michael Tiemann ([email protected])
4:
5: This file is part of GNU CC.
6:
7: GNU CC is distributed in the hope that it will be useful,
8: but WITHOUT ANY WARRANTY. No author or distributor
9: accepts responsibility to anyone for the consequences of using it
10: or for whether it serves any particular purpose or works at all,
11: unless he says so in writing. Refer to the GNU CC General Public
12: License for full details.
13:
14: Everyone is granted permission to copy, modify and redistribute
15: GNU CC, but only under the conditions described in the
16: GNU CC General Public License. A copy of this license is
17: supposed to have been given to you along with GNU CC so you
18: can know your rights and responsibilities. It should be in a
19: file named COPYING. Among other things, the copyright notice
20: and this notice must be preserved on all copies. */
21:
22: /* Global variables for machine-dependend things. */
23:
24: /* This should go away if we pass floats to regs via
25: the stack instead of the frame. */
26: extern int frame_pointer_needed;
27:
28: static rtx find_addr_reg ();
29:
30: #if 0
31: /* RTL expressions that we will cache during the entire compilation. */
32: rtx reg_o0_rtx, reg_o1_rtx, reg_o2_rtx, reg_i7_rtx;
33:
34: void
35: init_emit_mdep ()
36: {
37: /* These may be freely shared. */
38: reg_o0_rtx = gen_rtx (REG, SImode, 8);
39: reg_o1_rtx = gen_rtx (REG, SImode, 9);
40: reg_o2_rtx = gen_rtx (REG, SImode, 10);
41: reg_i7_rtx = gen_rtx (REG, SImode, 31);
42: }
43: #endif
44:
45: int
46: arith_operand (op, mode)
47: rtx op;
48: enum machine_mode mode;
49: {
50: return (register_operand (op, mode)
51: || (GET_CODE (op) == CONST_INT && SMALL_INT (op)));
52: }
53:
54: int
55: arith32_operand (op, mode)
56: rtx op;
57: enum machine_mode mode;
58: {
59: return (register_operand (op, mode) || GET_CODE (op) == CONST_INT);
60: }
61:
62: /* Return the best assembler insn template
63: for moving operands[1] into operands[0] as a fullword. */
64:
65: static char *
66: singlemove_string (operands)
67: rtx *operands;
68: {
69: if (GET_CODE (operands[0]) == MEM)
70: return "st %r1,%0";
71: if (GET_CODE (operands[1]) == MEM)
72: return "ld %1,%0";
73: return "add %1,%%g0,%0";
74: }
75:
76: /* Output assembler code to perform a doubleword move insn
77: with operands OPERANDS. */
78:
79: char *
80: output_move_double (operands)
81: rtx *operands;
82: {
83: enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
84: rtx latehalf[2];
85: rtx addreg0 = 0, addreg1 = 0;
86:
87: /* First classify both operands. */
88:
89: if (REG_P (operands[0]))
90: optype0 = REGOP;
91: else if (offsetable_memref_p (operands[0]))
92: optype0 = OFFSOP;
93: else if (GET_CODE (operands[0]) == MEM)
94: optype0 = MEMOP;
95: else
96: optype0 = RNDOP;
97:
98: if (REG_P (operands[1]))
99: optype1 = REGOP;
100: else if (CONSTANT_P (operands[1])
101: || GET_CODE (operands[1]) == CONST_DOUBLE)
102: optype1 = CNSTOP;
103: else if (offsetable_memref_p (operands[1]))
104: optype1 = OFFSOP;
105: else if (GET_CODE (operands[1]) == MEM)
106: optype0 = MEMOP;
107: else
108: optype1 = RNDOP;
109:
110: /* Check for the cases that the operand constraints are not
111: supposed to allow to happen. Abort if we get one,
112: because generating code for these cases is painful. */
113:
114: if (optype0 == RNDOP || optype1 == RNDOP)
115: abort ();
116:
117: /* If an operand is an unoffsettable memory ref, find a register
118: we can increment temporarily to make it refer to the second word. */
119:
120: if (optype0 == MEMOP)
121: addreg0 = find_addr_reg (operands[0]);
122:
123: if (optype1 == MEMOP)
124: addreg1 = find_addr_reg (operands[1]);
125:
126: /* Ok, we can do one word at a time.
127: Normally we do the low-numbered word first,
128: but if either operand is autodecrementing then we
129: do the high-numbered word first.
130:
131: In either case, set up in LATEHALF the operands to use
132: for the high-numbered word and in some cases alter the
133: operands in OPERANDS to be suitable for the low-numbered word. */
134:
135: if (optype0 == REGOP)
136: latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
137: else if (optype0 == OFFSOP)
138: latehalf[0] = adj_offsetable_operand (operands[0], 4);
139: else
140: latehalf[0] = operands[0];
141:
142: if (optype1 == REGOP)
143: latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
144: else if (optype1 == OFFSOP)
145: latehalf[1] = adj_offsetable_operand (operands[1], 4);
146: else if (optype1 == CNSTOP)
147: {
148: if (CONSTANT_P (operands[1]))
149: latehalf[1] = const0_rtx;
150: else if (GET_CODE (operands[1]) == CONST_DOUBLE)
151: {
152: latehalf[1] = gen_rtx (CONST_INT, VOIDmode, XINT (operands[1], 1));
153: operands[1] = gen_rtx (CONST_INT, VOIDmode, XINT (operands[1], 0));
154: }
155: }
156: else
157: latehalf[1] = operands[1];
158:
159: /* If the first move would clobber the source of the second one,
160: do them in the other order. This happens only for registers;
161: such overlap can't happen in memory unless the user explicitly
162: sets it up, and that is an undefined circumstance. */
163:
164: if (optype0 == REGOP && optype1 == REGOP
165: && REGNO (operands[0]) == REGNO (latehalf[1]))
166: {
167: /* Make any unoffsetable addresses point at high-numbered word. */
168: if (addreg0)
169: output_asm_insn ("add %0,0x4,%0", &addreg0);
170: if (addreg1)
171: output_asm_insn ("add %0,0x4,%0", &addreg1);
172:
173: /* Do that word. */
174: output_asm_insn (singlemove_string (latehalf), latehalf);
175:
176: /* Undo the adds we just did. */
177: if (addreg0)
178: output_asm_insn ("add %0,-0x4,%0", &addreg0);
179: if (addreg1)
180: output_asm_insn ("add %0,-0x4,%0", &addreg0);
181:
182: /* Do low-numbered word. */
183: return singlemove_string (operands);
184: }
185:
186: /* Normal case: do the two words, low-numbered first. */
187:
188: output_asm_insn (singlemove_string (operands), operands);
189:
190: /* Make any unoffsetable addresses point at high-numbered word. */
191: if (addreg0)
192: output_asm_insn ("add %0,0x4,%0", &addreg0);
193: if (addreg1)
194: output_asm_insn ("add %0,0x4,%0", &addreg1);
195:
196: /* Do that word. */
197: output_asm_insn (singlemove_string (latehalf), latehalf);
198:
199: /* Undo the adds we just did. */
200: if (addreg0)
201: output_asm_insn ("add %0,-0x4,%0", &addreg0);
202: if (addreg1)
203: output_asm_insn ("add %0,-0x4,%0", &addreg1);
204:
205: return "";
206: }
207:
208: static char *
209: output_fp_move_double (operands)
210: rtx *operands;
211: {
212: if (FP_REG_P (operands[0]))
213: {
214: if (FP_REG_P (operands[1]))
215: {
216: output_asm_insn ("fmovs %1,%0", operands);
217: operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1);
218: operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1);
219: return "fmovs %1,%0";
220: }
221: if (GET_CODE (operands[1]) == REG)
222: /* No good, since a signal would probably clobber that word on the stack. */
223: /* return "st %1,[%%sp-8]\n\tldd [%%sp-8],%0"; */
224: {
225: rtx xoperands[2];
226: int offset = - get_frame_size () - 8;
227: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
228: xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset + 4);
229: output_asm_insn ("st %1,[%%fp+%0]", xoperands);
230: xoperands[1] = operands[1];
231: xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset);
232: output_asm_insn ("st %1,[%%fp+%0]", xoperands);
233: xoperands[1] = operands[0];
234: output_asm_insn ("ldd [%%fp+%0],%1", xoperands);
235: return "";
236: }
237: return "ldd %1,%0";
238: }
239: else if (FP_REG_P (operands[1]))
240: {
241: if (GET_CODE (operands[0]) == REG)
242: /* No good, since a signal would probably clobber that word on the stack. */
243: /* return "std %1,[%%sp-8]\n\tldd [%%sp-8],%0"; */
244: {
245: rtx xoperands[2];
246: int offset = - get_frame_size () - 8;
247: xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset);
248: xoperands[1] = operands[1];
249: output_asm_insn ("st %1,[%%fp+%0]", xoperands);
250: xoperands[1] = operands[0];
251: output_asm_insn ("ld [%%fp+%0],%1", xoperands);
252: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
253: xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset + 4);
254: output_asm_insn ("ld [%%fp+%0],%1", xoperands);
255: return "";
256: }
257: return "std %1,%0";
258: }
259: }
260:
261: /* Return a REG that occurs in ADDR with coefficient 1.
262: ADDR can be effectively incremented by incrementing REG. */
263:
264: static rtx
265: find_addr_reg (addr)
266: rtx addr;
267: {
268: while (GET_CODE (addr) == PLUS)
269: {
270: if (GET_CODE (XEXP (addr, 0)) == REG)
271: addr = XEXP (addr, 0);
272: if (GET_CODE (XEXP (addr, 1)) == REG)
273: addr = XEXP (addr, 1);
274: if (CONSTANT_P (XEXP (addr, 0)))
275: addr = XEXP (addr, 1);
276: if (CONSTANT_P (XEXP (addr, 1)))
277: addr = XEXP (addr, 0);
278: }
279: if (GET_CODE (addr) == REG)
280: return addr;
281: return 0;
282: }
283:
284: /* Load the address specified by OPERANDS[3] into the register
285: specified by OPERANDS[0].
286:
287: OPERANDS[3] may be the result of a sum, hence it could either be:
288:
289: (1) CONST
290: (2) REG
291: (2) REG + CONST_INT
292: (3) REG + REG + CONST_INT
293:
294: All cases are handled here. */
295:
296: void
297: output_load_address (operands)
298: rtx *operands;
299: {
300: rtx base, offset;
301:
302: if (CONSTANT_P (operands[3]))
303: {
304: output_asm_insn ("set %3,%0", operands);
305: return;
306: }
307:
308: if (REG_P (operands[3]))
309: {
310: if (REGNO (operands[0]) != REGNO (operands[3]))
311: output_asm_insn ("mov %3,%0", operands);
312: return;
313: }
314:
315: base = XEXP (operands[3], 0);
316: offset = XEXP (operands[3], 1);
317:
318: if (GET_CODE (base) == CONST_INT)
319: {
320: rtx tmp = base;
321: base = offset;
322: offset = tmp;
323: }
324:
325: if (GET_CODE (offset) != CONST_INT)
326: abort ();
327:
328: if (REG_P (base))
329: {
330: operands[6] = base;
331: operands[7] = offset;
332: if (SMALL_INT (offset))
333: output_asm_insn ("add %6,%7,%0", operands);
334: else
335: output_asm_insn ("set %7,%0\n\tadd %0,%6,%0", operands);
336: }
337: else
338: {
339: operands[6] = XEXP (base, 0);
340: operands[7] = XEXP (base, 1);
341: operands[8] = offset;
342:
343: if (SMALL_INT (offset))
344: output_asm_insn ("add %6,%7,%0\n\tadd %0,%8,%0", operands);
345: else
346: output_asm_insn ("set %8,%0\n\tadd %0,%6,%0\n\tadd %0,%7,%0", operands);
347: }
348: }
349:
350: char *
351: output_block_move (operands)
352: rtx *operands;
353: {
354: static int movstrsi_label = 0;
355: int align = 4;
356:
357: rtx xoperands[9];
358: int available[3];
359: int i, j;
360:
361: /* Since we clobber untold things, nix the condition codes. */
362: CC_STATUS_INIT;
363:
364: /* Get past the MEMs. */
365: operands[0] = XEXP (operands[0], 0);
366: operands[1] = XEXP (operands[1], 0);
367:
368: xoperands[0] = 0;
369: xoperands[1] = 0;
370: xoperands[2] = 0;
371:
372: available[0] = 1;
373: available[1] = 1;
374: available[2] = 1;
375: #if 1
376: /* Prepare to juggle registers if necessary. */
377: if (REG_P (operands[0]) && (unsigned) (REGNO (operands[0]) - 8) < 3)
378: {
379: xoperands[0] = operands[0];
380: available[REGNO (operands[0]) - 8] = 0;
381: }
382: if (REG_P (operands[1]) && (unsigned) (REGNO (operands[1]) - 8) < 3)
383: {
384: xoperands[1] = operands[1];
385: available[REGNO (operands[1]) - 8] = 0;
386: }
387: if (REG_P (operands[2]) && (unsigned) (REGNO (operands[2]) - 8) < 3)
388: {
389: xoperands[2] = operands[2];
390: available[REGNO (operands[2]) - 8] = 0;
391: }
392: for (i = 0; i < 3; i++)
393: {
394: if (xoperands[i])
395: continue;
396: if (available[0])
397: {
398: xoperands[i] = gen_rtx (REG, SImode, 8);
399: available[0] = 0;
400: continue;
401: }
402: if (available[1])
403: {
404: xoperands[i] = gen_rtx (REG, SImode, 9);
405: available[1] = 0;
406: continue;
407: }
408: xoperands[i] = gen_rtx (REG, SImode, 10);
409: available[2] = 0;
410: }
411: #endif
412:
413: /* First, figure out best alignment we may assume. */
414: if (REG_P (operands[2]))
415: {
416: xoperands[5] = operands[2];
417: output_asm_insn ("sub %5,0x1,%2", xoperands);
418: align = 1;
419: }
420: else
421: {
422: int i = INTVAL (operands[2]);
423:
424: if (i & 1)
425: align = 1;
426: else if (i & 3)
427: align = 2;
428:
429: /* predecrement count. */
430: i -= align;
431: if (i < 0) abort ();
432:
433: xoperands[5] = gen_rtx (CONST_INT, VOIDmode, i);
434:
435: output_asm_insn ("set %5,%2", xoperands);
436: }
437:
438: /* Now, set up for pipelined operation: dest must contain
439: a pre-incremented address, because its index is pre-decremented. */
440:
441: xoperands[3] = plus_constant (operands[0], align);
442: output_load_address (xoperands);
443:
444: xoperands[4] = operands[1];
445: output_load_address (xoperands+1);
446:
447: xoperands[3] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++);
448: xoperands[4] = gen_rtx (CONST_INT, VOIDmode, align);
449:
450: output_asm_insn ("\nLm%3:\n\tld [%1+%2],%%o7\n\tsubcc %2,%4,%2\n\tbge Lm%3\n\tst %%o7,[%0+%2]", xoperands);
451: return "";
452: }
453:
454: #define ABS(x) ((x) < 0 ? -(x) : x)
455:
456: char *
457: output_mul_by_constant (insn, operands, unsignedp)
458: rtx insn;
459: rtx *operands;
460: int unsignedp;
461: {
462: int c; /* Size of constant */
463: int shifts[BITS_PER_WORD]; /* Table of shifts */
464: int p, log; /* A power of two, and its log */
465: int d1, d2; /* Differences of c and p */
466: int first = 1; /* True if dst has unknown data in it */
467: int i;
468:
469: c = INTVAL (operands[2]);
470: if (c == 0)
471: {
472: /* should not happen. */
473: abort ();
474: if (GET_CODE (operands[0]) == MEM)
475: return "st %%g0,%0";
476: return "mov %%g0,%0";
477: }
478:
479: #if 0
480: printf ("open coding insn:\n");
481: debug_rtx (insn);
482: printf ("done.\n");
483: #endif
484:
485: output_asm_insn ("! start open coded multiply");
486:
487: /* Clear out the table of shifts. */
488: for (i = 0; i < BITS_PER_WORD; ++i)
489: shifts[i] = 0;
490:
491: while (c)
492: {
493: /* Find the power of two nearest ABS(c) */
494: p = 1, log = 0;
495: do
496: {
497: d1 = ABS(c) - p;
498: p *= 2;
499: ++log;
500: }
501: while (p < ABS(c));
502: d2 = p - ABS(c);
503:
504: /* Make an appropriate entry in shifts for p. */
505: if (d2 < d1)
506: {
507: shifts[log] = c < 0 ? -1 : 1;
508: c = c < 0 ? d2 : -d2;
509: }
510: else
511: {
512: shifts[log - 1] = c < 0 ? -1 : 1;
513: c = c < 0 ? -d1 : d1;
514: }
515: }
516:
517: /* For now, use a known clobberable register. This could
518: be improved by looking at insn, and seeing if we
519: have a dying register contained therein. */
520: regs_ever_live[15] = 1;
521: operands[3] = gen_rtx (REG, SImode, 15);
522:
523: /* Take care of the first insn in sequence.
524: We know we have at least one. */
525:
526: /* A value of -1 in shifts says to subtract that power of two, and a value
527: of 1 says to add that power of two. */
528: for (i = 0; ; i++)
529: if (shifts[i])
530: {
531: if (i)
532: {
533: operands[2] = gen_rtx (CONST_INT, VOIDmode, i);
534: output_asm_insn ("sll %1,%2,%3", operands);
535: }
536: else if (REGNO (operands[3]) == 15)
537: output_asm_insn ("mov %1,%3", operands);
538:
539: log = i;
540: if (shifts[i] < 0)
541: output_asm_insn ("sub %%g0,%3,%0", operands);
542: else
543: output_asm_insn ("mov %3,%0", operands);
544: break;
545: }
546:
547: /* A value of -1 in shifts says to subtract that power of two, and a value
548: of 1 says to add that power of two--continued. */
549: for (i += 1; i < BITS_PER_WORD; ++i)
550: if (shifts[i])
551: {
552: if (i - log > 0)
553: {
554: operands[2] = gen_rtx (CONST_INT, VOIDmode, i - log);
555: output_asm_insn ("sll %3,%2,%3", operands);
556: }
557: else
558: {
559: operands[2] = gen_rtx (CONST_INT, VOIDmode, log - i);
560: output_asm_insn ("sra %3,%2,%3", operands);
561: }
562: log = i;
563: if (shifts[i] < 0)
564: output_asm_insn ("sub %0,%3,%0", operands);
565: else
566: output_asm_insn ("add %0,%3,%0", operands);
567: }
568:
569: output_asm_insn ("! end open coded multiply");
570:
571: return "";
572: }
573:
574: char *
575: output_mul_insn (operands, unsignedp)
576: rtx *operands;
577: int unsignedp;
578: {
579: int lucky1 = ((unsigned)REGNO (operands[1]) - 8) <= 1;
580: int lucky2 = ((unsigned)REGNO (operands[2]) - 8) <= 1;
581:
582: if (lucky1)
583: if (lucky2)
584: output_asm_insn ("call .mul,2\n\tnop", operands);
585: else
586: {
587: rtx xoperands[2];
588: xoperands[0] = gen_rtx (REG, SImode,
589: 8 ^ (REGNO (operands[1]) == 8));
590: xoperands[1] = operands[2];
591: output_asm_insn ("call .mul,2\n\tmov %1,%0", xoperands);
592: }
593: else if (lucky2)
594: {
595: rtx xoperands[2];
596: xoperands[0] = gen_rtx (REG, SImode,
597: 8 ^ (REGNO (operands[2]) == 8));
598: xoperands[1] = operands[1];
599: output_asm_insn ("call .mul,2\n\tmov %1,%0", xoperands);
600: }
601: else
602: {
603: output_asm_insn ("mov %1,%%o0\n\tcall .mul,2\n\tmov %2,%%o1",
604: operands);
605: }
606:
607: if (REGNO (operands[0]) == 8)
608: return "";
609: return "mov %%o0,%0";
610: }
611:
612: #if 0
613: /* This function does not properly protect its operands. */
614: char *
615: output_arith_insn (operands, name)
616: rtx *operands;
617: char *name;
618: {
619: extern struct _iobuf *asm_out_file;
620:
621: /* Does not commute. */
622: rtx op1 = 0;
623: rtx op2 = 0;
624:
625: abort ();
626: if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 8)
627: op1 = operands[1];
628: if (GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 8)
629: op2 = operands[2];
630:
631: if (op1 && op2)
632: {
633: /* ?? should have been done earlier. */
634: abort ();
635: }
636: else
637: {
638: if (op2)
639: {
640: op1 = operands[1];
641: if (REG_P (op1) && REGNO (op1) == 9)
642: {
643: output_asm_insn ("mov %%o1,%%o2\n\tmov %%o0,%%o1", operands);
644: fprintf (asm_out_file, "\tcall %s,2\n", name);
645: output_asm_insn ("mov %%o2,%%o0", operands);
646: goto done;
647: }
648: output_asm_insn ("mov %%o0,%%o1", operands);
649: if (GET_CODE (op1) == CONST_INT && ! SMALL_INT (op1))
650: {
651: output_asm_insn ("sethi %%hi(%1),%%o0", operands);
652: fprintf (asm_out_file, "\tcall %s,2\n", name);
653: output_asm_insn ("add %%o0,%%lo(%1),%%o0", operands);
654: }
655: else
656: {
657: fprintf (asm_out_file, "\tcall %s,2\n", name);
658: if (GET_CODE (op1) == MEM)
659: output_asm_insn ("ld %1,%%o0", operands);
660: else
661: output_asm_insn ("mov %1,%%o0", operands);
662: }
663: }
664: else if (op1)
665: {
666: op2 = operands[2];
667: if (REG_P (op2) && REGNO (operands[1]) == 9)
668: {
669: fprintf (asm_out_file, "\tcall %s,2\n\tnop\n");
670: goto done;
671: }
672: if (GET_CODE (op2) == CONST_INT && ! SMALL_INT (op2))
673: {
674: output_asm_insn ("sethi %%hi(%2),%%o1", operands);
675: fprintf (asm_out_file, "\tcall %s,2\n", name);
676: output_asm_insn ("add %%o1,%%lo(%2),%%o1", operands);
677: }
678: else
679: {
680: fprintf (asm_out_file, "\tcall %s,2\n", name);
681: if (GET_CODE (op2) == MEM)
682: output_asm_insn ("ld %2,%%o1", operands);
683: else
684: output_asm_insn ("mov %2,%%o1", operands);
685: }
686: }
687: else
688: {
689: op1 = operands[1];
690: op2 = operands[2];
691:
692: if (! REG_P (op2) || REGNO (op2) != 9)
693: if (GET_CODE (op2) == MEM)
694: output_asm_insn ("ld %2,%%o1", operands);
695: else if (GET_CODE (op2) != CONST_INT || SMALL_INT (op2))
696: output_asm_insn ("mov %2,%%o1", operands);
697: else
698: output_asm_insn ("sethi %%hi(%2),%%o1\n\tadd %%o1,%%lo(%2),%%o1", operands);
699: if (GET_CODE (op1) == CONST_INT && ! SMALL_INT (op1))
700: {
701: output_asm_insn ("sethi %%hi(%1),%%o0", operands);
702: fprintf (asm_out_file, "\tcall %s,2\n", name);
703: output_asm_insn ("add %%o0,%%lo(%1),%%o0", operands);
704: }
705: else
706: {
707: fprintf (asm_out_file, "\tcall %s,2\n", name);
708: if (GET_CODE (op1) == MEM)
709: output_asm_insn ("ld %1,%%o0", operands);
710: else
711: output_asm_insn ("mov %1,%%o0", operands);
712: }
713: }
714: done:
715: if (REG_P (operands[0]) && REGNO (operands[0]) == 8)
716: return "";
717: if (GET_CODE (operands[0]) == MEM)
718: return "st %%o0,%0";
719: return "mov %%o0,%0";
720: }
721: }
722: #endif
723:
724: /* Make floating point register f0 contain 0.
725: SIZE is the number of registers (including f0)
726: which should contain 0. */
727:
728: void
729: make_f0_contain_0 (size)
730: int size;
731: {
732: rtx xoperands[1];
733: int offset = - get_frame_size () - 8;
734:
735: xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset);
736: if (size == 1)
737: output_asm_insn ("ld [%%fp%0],%%f0", xoperands);
738: else if (size == 2)
739: output_asm_insn ("ldd [%%fp%0],%%f0", xoperands);
740: }
741:
742: #if 0
743: /* This was needed only for the "alloca" instruction. */
744: #include "tree.h"
745:
746: int
747: tree_uid (node)
748: tree node;
749: {
750: return TREE_UID (node);
751: }
752: #endif
753:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.