|
|
1.1 root 1: /* Subroutines for insn-output.c for Sun SPARC.
2: Copyright (C) 1987, 1988, 1989, 1992 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 free software; you can redistribute it and/or modify
8: it under the terms of the GNU General Public License as published by
9: the Free Software Foundation; either version 2, or (at your option)
10: any later version.
11:
12: GNU CC is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with GNU CC; see the file COPYING. If not, write to
19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20:
21: #include <stdio.h>
22: #include "config.h"
23: #include "tree.h"
24: #include "rtl.h"
25: #include "regs.h"
26: #include "hard-reg-set.h"
27: #include "real.h"
28: #include "insn-config.h"
29: #include "conditions.h"
30: #include "insn-flags.h"
31: #include "output.h"
32: #include "insn-attr.h"
33: #include "flags.h"
34: #include "expr.h"
35: #include "recog.h"
36:
37: /* Global variables for machine-dependent things. */
38:
39: /* Save the operands last given to a compare for use when we
40: generate a scc or bcc insn. */
41:
42: rtx sparc_compare_op0, sparc_compare_op1;
43:
44: /* We may need an epilogue if we spill too many registers.
45: If this is non-zero, then we branch here for the epilogue. */
46: static rtx leaf_label;
47:
48: #ifdef LEAF_REGISTERS
49:
50: /* Vector to say how input registers are mapped to output
51: registers. FRAME_POINTER_REGNUM cannot be remapped by
52: this function to eliminate it. You must use -fomit-frame-pointer
53: to get that. */
54: char leaf_reg_remap[] =
55: { 0, 1, 2, 3, 4, 5, 6, 7,
56: -1, -1, -1, -1, -1, -1, 14, -1,
57: -1, -1, -1, -1, -1, -1, -1, -1,
58: 8, 9, 10, 11, 12, 13, -1, 15,
59:
60: 32, 33, 34, 35, 36, 37, 38, 39,
61: 40, 41, 42, 43, 44, 45, 46, 47,
62: 48, 49, 50, 51, 52, 53, 54, 55,
63: 56, 57, 58, 59, 60, 61, 62, 63};
64:
65: char leaf_reg_backmap[] =
66: { 0, 1, 2, 3, 4, 5, 6, 7,
67: 24, 25, 26, 27, 28, 29, 14, 31,
68: -1, -1, -1, -1, -1, -1, -1, -1,
69: -1, -1, -1, -1, -1, -1, -1, -1,
70:
71: 32, 33, 34, 35, 36, 37, 38, 39,
72: 40, 41, 42, 43, 44, 45, 46, 47,
73: 48, 49, 50, 51, 52, 53, 54, 55,
74: 56, 57, 58, 59, 60, 61, 62, 63};
75: #endif
76:
77: /* Global variables set by FUNCTION_PROLOGUE. */
78: /* Size of frame. Need to know this to emit return insns from
79: leaf procedures. */
80: int apparent_fsize;
81: int actual_fsize;
82:
83: /* Name of where we pretend to think the frame pointer points.
84: Normally, this is "%fp", but if we are in a leaf procedure,
85: this is "%sp+something". */
86: char *frame_base_name;
87:
88: static rtx find_addr_reg ();
89:
90: /* Return non-zero only if OP is a register of mode MODE,
91: or const0_rtx. */
92: int
93: reg_or_0_operand (op, mode)
94: rtx op;
95: enum machine_mode mode;
96: {
97: if (op == const0_rtx || register_operand (op, mode))
98: return 1;
99: if (GET_CODE (op) == CONST_DOUBLE
100: && CONST_DOUBLE_HIGH (op) == 0
101: && CONST_DOUBLE_LOW (op) == 0)
102: return 1;
103: return 0;
104: }
105:
106: /* Nonzero if OP can appear as the dest of a RESTORE insn. */
107: int
108: restore_operand (op, mode)
109: rtx op;
110: enum machine_mode mode;
111: {
112: return (GET_CODE (op) == REG && GET_MODE (op) == mode
113: && (REGNO (op) < 8 || (REGNO (op) >= 24 && REGNO (op) < 32)));
114: }
115:
116: /* Call insn on SPARC can take a PC-relative constant address, or any regular
117: memory address. */
118:
119: int
120: call_operand (op, mode)
121: rtx op;
122: enum machine_mode mode;
123: {
124: if (GET_CODE (op) != MEM)
125: abort ();
126: op = XEXP (op, 0);
127: return (CONSTANT_P (op) || memory_address_p (Pmode, op));
128: }
129:
130: int
131: call_operand_address (op, mode)
132: rtx op;
133: enum machine_mode mode;
134: {
135: return (CONSTANT_P (op) || memory_address_p (Pmode, op));
136: }
137:
138: /* Returns 1 if OP is either a symbol reference or a sum of a symbol
139: reference and a constant. */
140:
141: int
142: symbolic_operand (op, mode)
143: register rtx op;
144: enum machine_mode mode;
145: {
146: switch (GET_CODE (op))
147: {
148: case SYMBOL_REF:
149: case LABEL_REF:
150: return 1;
151:
152: case CONST:
153: op = XEXP (op, 0);
154: return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
155: || GET_CODE (XEXP (op, 0)) == LABEL_REF)
156: && GET_CODE (XEXP (op, 1)) == CONST_INT);
157:
158: /* ??? This clause seems to be irrelevant. */
159: case CONST_DOUBLE:
160: return GET_MODE (op) == mode;
161:
162: default:
163: return 0;
164: }
165: }
166:
167: /* Return truth value of statement that OP is a symbolic memory
168: operand of mode MODE. */
169:
170: int
171: symbolic_memory_operand (op, mode)
172: rtx op;
173: enum machine_mode mode;
174: {
175: if (GET_CODE (op) == SUBREG)
176: op = SUBREG_REG (op);
177: if (GET_CODE (op) != MEM)
178: return 0;
179: op = XEXP (op, 0);
180: return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
181: || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
182: }
183:
184: /* Return 1 if the operand is either a register or a memory operand that is
185: not symbolic. */
186:
187: int
188: reg_or_nonsymb_mem_operand (op, mode)
189: register rtx op;
190: enum machine_mode mode;
191: {
192: if (register_operand (op, mode))
193: return 1;
194:
195: if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
196: return 1;
197:
198: return 0;
199: }
200:
201: int
202: sparc_operand (op, mode)
203: rtx op;
204: enum machine_mode mode;
205: {
206: if (register_operand (op, mode))
207: return 1;
208: if (GET_CODE (op) == CONST_INT)
209: return SMALL_INT (op);
210: if (GET_MODE (op) != mode)
211: return 0;
212: if (GET_CODE (op) == SUBREG)
213: op = SUBREG_REG (op);
214: if (GET_CODE (op) != MEM)
215: return 0;
216:
217: op = XEXP (op, 0);
218: if (GET_CODE (op) == LO_SUM)
219: return (GET_CODE (XEXP (op, 0)) == REG
220: && symbolic_operand (XEXP (op, 1), Pmode));
221: return memory_address_p (mode, op);
222: }
223:
224: int
225: move_operand (op, mode)
226: rtx op;
227: enum machine_mode mode;
228: {
229: if (mode == DImode && arith_double_operand (op, mode))
230: return 1;
231: if (register_operand (op, mode))
232: return 1;
233: if (GET_CODE (op) == CONST_INT)
234: return (SMALL_INT (op) || (INTVAL (op) & 0x3ff) == 0);
235:
236: if (GET_MODE (op) != mode)
237: return 0;
238: if (GET_CODE (op) == SUBREG)
239: op = SUBREG_REG (op);
240: if (GET_CODE (op) != MEM)
241: return 0;
242: op = XEXP (op, 0);
243: if (GET_CODE (op) == LO_SUM)
244: return (register_operand (XEXP (op, 0), Pmode)
245: && CONSTANT_P (XEXP (op, 1)));
246: return memory_address_p (mode, op);
247: }
248:
249: int
250: move_pic_label (op, mode)
251: rtx op;
252: enum machine_mode mode;
253: {
254: /* Special case for PIC. */
255: if (flag_pic && GET_CODE (op) == LABEL_REF)
256: return 1;
257: return 0;
258: }
259:
260: /* The rtx for the global offset table which is a special form
261: that *is* a position independent symbolic constant. */
262: rtx pic_pc_rtx;
263:
264: /* Ensure that we are not using patterns that are not OK with PIC. */
265:
266: int
267: check_pic (i)
268: int i;
269: {
270: switch (flag_pic)
271: {
272: case 1:
273: if (GET_CODE (recog_operand[i]) == SYMBOL_REF
274: || (GET_CODE (recog_operand[i]) == CONST
275: && ! rtx_equal_p (pic_pc_rtx, recog_operand[i])))
276: abort ();
277: case 2:
278: default:
279: return 1;
280: }
281: }
282:
283: /* Return true if X is an address which needs a temporary register when
284: reloaded while generating PIC code. */
285:
286: int
287: pic_address_needs_scratch (x)
288: rtx x;
289: {
290: /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */
291: if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS
292: && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
293: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
294: && ! SMALL_INT (XEXP (XEXP (x, 0), 1)))
295: return 1;
296:
297: return 0;
298: }
299:
300: int
301: memop (op, mode)
302: rtx op;
303: enum machine_mode mode;
304: {
305: if (GET_CODE (op) == MEM)
306: return (mode == VOIDmode || mode == GET_MODE (op));
307: return 0;
308: }
309:
310: /* Return truth value of whether OP is EQ or NE. */
311:
312: int
313: eq_or_neq (op, mode)
314: rtx op;
315: enum machine_mode mode;
316: {
317: return (GET_CODE (op) == EQ || GET_CODE (op) == NE);
318: }
319:
320: /* Return 1 if this is a comparison operator, but not an EQ, NE, GEU,
321: or LTU for non-floating-point. We handle those specially. */
322:
323: int
324: normal_comp_operator (op, mode)
325: rtx op;
326: enum machine_mode mode;
327: {
328: enum rtx_code code = GET_CODE (op);
329:
330: if (GET_RTX_CLASS (code) != '<')
331: return 0;
332:
333: if (GET_MODE (XEXP (op, 0)) == CCFPmode
334: || GET_MODE (XEXP (op, 0)) == CCFPEmode)
335: return 1;
336:
337: return (code != NE && code != EQ && code != GEU && code != LTU);
338: }
339:
340: /* Return 1 if this is a comparison operator. This allows the use of
341: MATCH_OPERATOR to recognize all the branch insns. */
342:
343: int
344: noov_compare_op (op, mode)
345: register rtx op;
346: enum machine_mode mode;
347: {
348: enum rtx_code code = GET_CODE (op);
349:
350: if (GET_RTX_CLASS (code) != '<')
351: return 0;
352:
353: if (GET_MODE (XEXP (op, 0)) == CC_NOOVmode)
354: /* These are the only branches which work with CC_NOOVmode. */
355: return (code == EQ || code == NE || code == GE || code == LT);
356: return 1;
357: }
358:
359: /* Return 1 if this is a SIGN_EXTEND or ZERO_EXTEND operation. */
360:
361: int
362: extend_op (op, mode)
363: rtx op;
364: enum machine_mode mode;
365: {
366: return GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND;
367: }
368:
369: /* Return nonzero if OP is an operator of mode MODE which can set
370: the condition codes explicitly. We do not include PLUS and MINUS
371: because these require CC_NOOVmode, which we handle explicitly. */
372:
373: int
374: cc_arithop (op, mode)
375: rtx op;
376: enum machine_mode mode;
377: {
378: if (GET_CODE (op) == AND
379: || GET_CODE (op) == IOR
380: || GET_CODE (op) == XOR)
381: return 1;
382:
383: return 0;
384: }
385:
386: /* Return nonzero if OP is an operator of mode MODE which can bitwise
387: complement its second operand and set the condition codes explicitly. */
388:
389: int
390: cc_arithopn (op, mode)
391: rtx op;
392: enum machine_mode mode;
393: {
394: /* XOR is not here because combine canonicalizes (xor (not ...) ...)
395: and (xor ... (not ...)) to (not (xor ...)). */
396: return (GET_CODE (op) == AND
397: || GET_CODE (op) == IOR);
398: }
399:
400: /* Return true if OP is a register, or is a CONST_INT that can fit in a 13
401: bit immediate field. This is an acceptable SImode operand for most 3
402: address instructions. */
403:
404: int
405: arith_operand (op, mode)
406: rtx op;
407: enum machine_mode mode;
408: {
409: return (register_operand (op, mode)
410: || (GET_CODE (op) == CONST_INT && SMALL_INT (op)));
411: }
412:
413: /* Return true if OP is a register, or is a CONST_INT or CONST_DOUBLE that
414: can fit in a 13 bit immediate field. This is an acceptable DImode operand
415: for most 3 address instructions. */
416:
417: int
418: arith_double_operand (op, mode)
419: rtx op;
420: enum machine_mode mode;
421: {
422: return (register_operand (op, mode)
423: || (GET_CODE (op) == CONST_DOUBLE
424: && (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode)
425: && (unsigned) (CONST_DOUBLE_LOW (op) + 0x1000) < 0x2000
426: && ((CONST_DOUBLE_HIGH (op) == -1
427: && (CONST_DOUBLE_LOW (op) & 0x1000) == 0x1000)
428: || (CONST_DOUBLE_HIGH (op) == 0
429: && (CONST_DOUBLE_LOW (op) & 0x1000) == 0)))
430: || (GET_CODE (op) == CONST_INT
431: && (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode)
432: && (unsigned) (INTVAL (op) + 0x1000) < 0x2000));
433: }
434:
435: /* Return truth value of whether OP is a integer which fits the
436: range constraining immediate operands in most three-address insns,
437: which have a 13 bit immediate field. */
438:
439: int
440: small_int (op, mode)
441: rtx op;
442: enum machine_mode mode;
443: {
444: return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
445: }
446:
447: /* Return truth value of statement that OP is a call-clobbered register. */
448: int
449: clobbered_register (op, mode)
450: rtx op;
451: enum machine_mode mode;
452: {
453: return (GET_CODE (op) == REG && call_used_regs[REGNO (op)]);
454: }
455:
456: /* X and Y are two things to compare using CODE. Emit the compare insn and
457: return the rtx for register 0 in the proper mode. */
458:
459: rtx
460: gen_compare_reg (code, x, y)
461: enum rtx_code code;
462: rtx x, y;
463: {
464: enum machine_mode mode = SELECT_CC_MODE (code, x, y);
465: rtx cc_reg = gen_rtx (REG, mode, 0);
466:
467: emit_insn (gen_rtx (SET, VOIDmode, cc_reg,
468: gen_rtx (COMPARE, mode, x, y)));
469:
470: return cc_reg;
471: }
472:
473: /* Return nonzero if a return peephole merging return with
474: setting of output register is ok. */
475: int
476: leaf_return_peephole_ok ()
477: {
478: return (actual_fsize == 0);
479: }
480:
481: /* Return nonzero if TRIAL can go into the function epilogue's
482: delay slot. SLOT is the slot we are trying to fill. */
483:
484: int
485: eligible_for_epilogue_delay (trial, slot)
486: rtx trial;
487: int slot;
488: {
489: rtx pat, src;
490:
491: if (slot >= 1)
492: return 0;
493: if (GET_CODE (trial) != INSN
494: || GET_CODE (PATTERN (trial)) != SET)
495: return 0;
496: if (get_attr_length (trial) != 1)
497: return 0;
498:
499: /* In the case of a true leaf function, anything can go into the delay slot.
500: A delay slot only exists however if the frame size is zero, otherwise
501: we will put an insn to adjust the stack after the return. */
502: if (leaf_function)
503: {
504: if (leaf_return_peephole_ok ())
505: return (get_attr_in_uncond_branch_delay (trial) == IN_BRANCH_DELAY_TRUE);
506: return 0;
507: }
508:
509: /* Otherwise, only operations which can be done in tandem with
510: a `restore' insn can go into the delay slot. */
511: pat = PATTERN (trial);
512: if (GET_CODE (SET_DEST (pat)) != REG
513: || REGNO (SET_DEST (pat)) == 0
514: || REGNO (SET_DEST (pat)) >= 32
515: || REGNO (SET_DEST (pat)) < 24)
516: return 0;
517:
518: src = SET_SRC (pat);
519: if (arith_operand (src, GET_MODE (src)))
520: return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (SImode);
521: if (arith_double_operand (src, GET_MODE (src)))
522: return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (DImode);
523: if (GET_CODE (src) == PLUS)
524: {
525: if (register_operand (XEXP (src, 0), SImode)
526: && arith_operand (XEXP (src, 1), SImode))
527: return 1;
528: if (register_operand (XEXP (src, 1), SImode)
529: && arith_operand (XEXP (src, 0), SImode))
530: return 1;
531: if (register_operand (XEXP (src, 0), DImode)
532: && arith_double_operand (XEXP (src, 1), DImode))
533: return 1;
534: if (register_operand (XEXP (src, 1), DImode)
535: && arith_double_operand (XEXP (src, 0), DImode))
536: return 1;
537: }
538: if (GET_CODE (src) == MINUS
539: && register_operand (XEXP (src, 0), SImode)
540: && small_int (XEXP (src, 1), VOIDmode))
541: return 1;
542: if (GET_CODE (src) == MINUS
543: && register_operand (XEXP (src, 0), DImode)
544: && !register_operand (XEXP (src, 1), DImode)
545: && arith_double_operand (XEXP (src, 1), DImode))
546: return 1;
547: return 0;
548: }
549:
550: int
551: short_branch (uid1, uid2)
552: int uid1, uid2;
553: {
554: unsigned int delta = insn_addresses[uid1] - insn_addresses[uid2];
555: if (delta + 1024 < 2048)
556: return 1;
557: /* warning ("long branch, distance %d", delta); */
558: return 0;
559: }
560:
561: /* Return non-zero if REG is not used after INSN.
562: We assume REG is a reload reg, and therefore does
563: not live past labels or calls or jumps. */
564: int
565: reg_unused_after (reg, insn)
566: rtx reg;
567: rtx insn;
568: {
569: enum rtx_code code, prev_code = UNKNOWN;
570:
571: while (insn = NEXT_INSN (insn))
572: {
573: if (prev_code == CALL_INSN && call_used_regs[REGNO (reg)])
574: return 1;
575:
576: code = GET_CODE (insn);
577: if (GET_CODE (insn) == CODE_LABEL)
578: return 1;
579:
580: if (GET_RTX_CLASS (code) == 'i')
581: {
582: rtx set = single_set (insn);
583: int in_src = set && reg_overlap_mentioned_p (reg, SET_SRC (set));
584: if (set && in_src)
585: return 0;
586: if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
587: return 1;
588: if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
589: return 0;
590: }
591: prev_code = code;
592: }
593: return 1;
594: }
595:
596: /* Legitimize PIC addresses. If the address is already position-independent,
597: we return ORIG. Newly generated position-independent addresses go into a
598: reg. This is REG if non zero, otherwise we allocate register(s) as
599: necessary. If this is called during reload, and we need a second temp
600: register, then we use SCRATCH, which is provided via the
601: SECONDARY_INPUT_RELOAD_CLASS mechanism. */
602:
603: rtx
604: legitimize_pic_address (orig, mode, reg, scratch)
605: rtx orig;
606: enum machine_mode mode;
607: rtx reg, scratch;
608: {
609: if (GET_CODE (orig) == SYMBOL_REF)
610: {
611: rtx pic_ref, address;
612: rtx insn;
613:
614: if (reg == 0)
615: {
616: if (reload_in_progress || reload_completed)
617: abort ();
618: else
619: reg = gen_reg_rtx (Pmode);
620: }
621:
622: if (flag_pic == 2)
623: {
624: /* If not during reload, allocate another temp reg here for loading
625: in the address, so that these instructions can be optimized
626: properly. */
627: rtx temp_reg = ((reload_in_progress || reload_completed)
628: ? reg : gen_reg_rtx (Pmode));
629:
630: /* Must put the SYMBOL_REF inside an UNSPEC here so that cse
631: won't get confused into thinking that these two instructions
632: are loading in the true address of the symbol. If in the
633: future a PIC rtx exists, that should be used instead. */
634: emit_insn (gen_rtx (SET, VOIDmode, temp_reg,
635: gen_rtx (HIGH, Pmode,
636: gen_rtx (UNSPEC, Pmode,
637: gen_rtvec (1, orig),
638: 0))));
639: emit_insn (gen_rtx (SET, VOIDmode, temp_reg,
640: gen_rtx (LO_SUM, Pmode, temp_reg,
641: gen_rtx (UNSPEC, Pmode,
642: gen_rtvec (1, orig),
643: 0))));
644: address = temp_reg;
645: }
646: else
647: address = orig;
648:
649: pic_ref = gen_rtx (MEM, Pmode,
650: gen_rtx (PLUS, Pmode,
651: pic_offset_table_rtx, address));
652: current_function_uses_pic_offset_table = 1;
653: RTX_UNCHANGING_P (pic_ref) = 1;
654: insn = emit_move_insn (reg, pic_ref);
655: /* Put a REG_EQUAL note on this insn, so that it can be optimized
656: by loop. */
657: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, orig,
658: REG_NOTES (insn));
659: return reg;
660: }
661: else if (GET_CODE (orig) == CONST)
662: {
663: rtx base, offset;
664:
665: if (GET_CODE (XEXP (orig, 0)) == PLUS
666: && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
667: return orig;
668:
669: if (reg == 0)
670: {
671: if (reload_in_progress || reload_completed)
672: abort ();
673: else
674: reg = gen_reg_rtx (Pmode);
675: }
676:
677: if (GET_CODE (XEXP (orig, 0)) == PLUS)
678: {
679: base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode,
680: reg, 0);
681: offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
682: base == reg ? 0 : reg, 0);
683: }
684: else
685: abort ();
686:
687: if (GET_CODE (offset) == CONST_INT)
688: {
689: if (SMALL_INT (offset))
690: return plus_constant_for_output (base, INTVAL (offset));
691: else if (! reload_in_progress && ! reload_completed)
692: offset = force_reg (Pmode, offset);
693: /* We can't create any new registers during reload, so use the
694: SCRATCH reg provided by the reload_insi pattern. */
695: else if (scratch)
696: {
697: emit_move_insn (scratch, offset);
698: offset = scratch;
699: }
700: else
701: /* If we reach here, then the SECONDARY_INPUT_RELOAD_CLASS
702: macro needs to be adjusted so that a scratch reg is provided
703: for this address. */
704: abort ();
705: }
706: return gen_rtx (PLUS, Pmode, base, offset);
707: }
708: else if (GET_CODE (orig) == LABEL_REF)
709: current_function_uses_pic_offset_table = 1;
710:
711: return orig;
712: }
713:
714: /* Set up PIC-specific rtl. This should not cause any insns
715: to be emitted. */
716:
717: void
718: initialize_pic ()
719: {
720: }
721:
722: /* Emit special PIC prologues and epilogues. */
723:
724: void
725: finalize_pic ()
726: {
727: /* The table we use to reference PIC data. */
728: rtx global_offset_table;
729: /* Labels to get the PC in the prologue of this function. */
730: rtx l1, l2;
731: rtx seq;
732: int orig_flag_pic = flag_pic;
733:
734: if (current_function_uses_pic_offset_table == 0)
735: return;
736:
737: if (! flag_pic)
738: abort ();
739:
740: flag_pic = 0;
741: l1 = gen_label_rtx ();
742: l2 = gen_label_rtx ();
743:
744: start_sequence ();
745:
746: emit_label (l1);
747: /* Note that we pun calls and jumps here! */
748: emit_jump_insn (gen_rtx (PARALLEL, VOIDmode,
749: gen_rtvec (2,
750: gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (LABEL_REF, VOIDmode, l2)),
751: gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 15), gen_rtx (LABEL_REF, VOIDmode, l2)))));
752: emit_label (l2);
753:
754: /* Initialize every time through, since we can't easily
755: know this to be permanent. */
756: global_offset_table = gen_rtx (SYMBOL_REF, Pmode, "_GLOBAL_OFFSET_TABLE_");
757: pic_pc_rtx = gen_rtx (CONST, Pmode,
758: gen_rtx (MINUS, Pmode,
759: global_offset_table,
760: gen_rtx (CONST, Pmode,
761: gen_rtx (MINUS, Pmode,
762: gen_rtx (LABEL_REF, VOIDmode, l1),
763: pc_rtx))));
764:
765: emit_insn (gen_rtx (SET, VOIDmode, pic_offset_table_rtx,
766: gen_rtx (HIGH, Pmode, pic_pc_rtx)));
767: emit_insn (gen_rtx (SET, VOIDmode,
768: pic_offset_table_rtx,
769: gen_rtx (LO_SUM, Pmode,
770: pic_offset_table_rtx, pic_pc_rtx)));
771: emit_insn (gen_rtx (SET, VOIDmode,
772: pic_offset_table_rtx,
773: gen_rtx (PLUS, Pmode,
774: pic_offset_table_rtx, gen_rtx (REG, Pmode, 15))));
775: /* emit_insn (gen_rtx (ASM_INPUT, VOIDmode, "!#PROLOGUE# 1")); */
776: LABEL_PRESERVE_P (l1) = 1;
777: LABEL_PRESERVE_P (l2) = 1;
778: flag_pic = orig_flag_pic;
779:
780: seq = gen_sequence ();
781: end_sequence ();
782: emit_insn_after (seq, get_insns ());
783:
784: /* Need to emit this whether or not we obey regdecls,
785: since setjmp/longjmp can cause life info to screw up. */
786: emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx));
787: }
788:
789: /* For the SPARC, REG and REG+CONST is cost 0, REG+REG is cost 1,
790: and addresses involving symbolic constants are cost 2.
791:
792: We make REG+REG slightly more expensive because it might keep
793: a register live for longer than we might like.
794:
795: PIC addresses are very expensive.
796:
797: It is no coincidence that this has the same structure
798: as GO_IF_LEGITIMATE_ADDRESS. */
799: int
800: sparc_address_cost (X)
801: rtx X;
802: {
803: #if 0
804: /* Handled before calling here. */
805: if (GET_CODE (X) == REG)
806: { return 1; }
807: #endif
808: if (GET_CODE (X) == PLUS)
809: {
810: if (GET_CODE (XEXP (X, 0)) == REG
811: && GET_CODE (XEXP (X, 1)) == REG)
812: return 2;
813: return 1;
814: }
815: else if (GET_CODE (X) == LO_SUM)
816: return 1;
817: else if (GET_CODE (X) == HIGH)
818: return 2;
819: return 4;
820: }
821:
822: /* Emit insns to move operands[1] into operands[0].
823:
824: Return 1 if we have written out everything that needs to be done to
825: do the move. Otherwise, return 0 and the caller will emit the move
826: normally.
827:
828: SCRATCH_REG if non zero can be used as a scratch register for the move
829: operation. It is provided by a SECONDARY_RELOAD_* macro if needed. */
830:
831: int
832: emit_move_sequence (operands, mode, scratch_reg)
833: rtx *operands;
834: enum machine_mode mode;
835: rtx scratch_reg;
836: {
837: register rtx operand0 = operands[0];
838: register rtx operand1 = operands[1];
839:
840: /* Handle most common case first: storing into a register. */
841: if (register_operand (operand0, mode))
842: {
843: if (register_operand (operand1, mode)
844: || (GET_CODE (operand1) == CONST_INT && SMALL_INT (operand1))
845: || (GET_CODE (operand1) == CONST_DOUBLE
846: && arith_double_operand (operand1, DImode))
847: || (GET_CODE (operand1) == HIGH && GET_MODE (operand1) != DImode)
848: /* Only `general_operands' can come here, so MEM is ok. */
849: || GET_CODE (operand1) == MEM)
850: {
851: /* Run this case quickly. */
852: emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));
853: return 1;
854: }
855: }
856: else if (GET_CODE (operand0) == MEM)
857: {
858: if (register_operand (operand1, mode) || operand1 == const0_rtx)
859: {
860: /* Run this case quickly. */
861: emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));
862: return 1;
863: }
864: if (! reload_in_progress)
865: {
866: operands[0] = validize_mem (operand0);
867: operands[1] = operand1 = force_reg (mode, operand1);
868: }
869: }
870:
871: /* Simplify the source if we need to. Must handle DImode HIGH operators
872: here because such a move needs a clobber added. */
873: if ((GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode))
874: || (GET_CODE (operand1) == HIGH && GET_MODE (operand1) == DImode))
875: {
876: if (flag_pic && symbolic_operand (operand1, mode))
877: {
878: rtx temp_reg = reload_in_progress ? operand0 : 0;
879:
880: operands[1] = legitimize_pic_address (operand1, mode, temp_reg,
881: scratch_reg);
882: }
883: else if (GET_CODE (operand1) == CONST_INT
884: ? (! SMALL_INT (operand1)
885: && (INTVAL (operand1) & 0x3ff) != 0)
886: : (GET_CODE (operand1) == CONST_DOUBLE
887: ? ! arith_double_operand (operand1, DImode)
888: : 1))
889: {
890: /* For DImode values, temp must be operand0 because of the way
891: HI and LO_SUM work. The LO_SUM operator only copies half of
892: the LSW from the dest of the HI operator. If the LO_SUM dest is
893: not the same as the HI dest, then the MSW of the LO_SUM dest will
894: never be set.
895:
896: ??? The real problem here is that the ...(HI:DImode pattern emits
897: multiple instructions, and the ...(LO_SUM:DImode pattern emits
898: one instruction. This fails, because the compiler assumes that
899: LO_SUM copies all bits of the first operand to its dest. Better
900: would be to have the HI pattern emit one instruction and the
901: LO_SUM pattern multiple instructions. Even better would be
902: to use four rtl insns. */
903: rtx temp = ((reload_in_progress || mode == DImode)
904: ? operand0 : gen_reg_rtx (mode));
905:
906: emit_insn (gen_rtx (SET, VOIDmode, temp,
907: gen_rtx (HIGH, mode, operand1)));
908: operands[1] = gen_rtx (LO_SUM, mode, temp, operand1);
909: }
910: }
911:
912: if (GET_CODE (operand1) == LABEL_REF && flag_pic)
913: {
914: /* The procedure for doing this involves using a call instruction to
915: get the pc into o7. We need to indicate this explicitly because
916: the tablejump pattern assumes that it can use this value also. */
917: emit_insn (gen_rtx (PARALLEL, VOIDmode,
918: gen_rtvec (2,
919: gen_rtx (SET, VOIDmode, operand0,
920: operand1),
921: gen_rtx (SET, VOIDmode,
922: gen_rtx (REG, mode, 15),
923: pc_rtx))));
924: return 1;
925: }
926:
927: /* Now have insn-emit do whatever it normally does. */
928: return 0;
929: }
930:
931: /* Return the best assembler insn template
932: for moving operands[1] into operands[0] as a fullword. */
933:
934: char *
935: singlemove_string (operands)
936: rtx *operands;
937: {
938: if (GET_CODE (operands[0]) == MEM)
939: {
940: if (GET_CODE (operands[1]) != MEM)
941: return "st %r1,%0";
942: else
943: abort ();
944: }
945: else if (GET_CODE (operands[1]) == MEM)
946: return "ld %1,%0";
947: else if (GET_CODE (operands[1]) == CONST_DOUBLE)
948: {
949: int i;
950: union real_extract u;
951: union float_extract { float f; int i; } v;
952:
953: /* Must be SFmode, otherwise this doesn't make sense. */
954: if (GET_MODE (operands[1]) != SFmode)
955: abort ();
956:
957: bcopy (&CONST_DOUBLE_LOW (operands[1]), &u, sizeof u);
958: v.f = REAL_VALUE_TRUNCATE (SFmode, u.d);
959: i = v.i;
960:
961: operands[1] = gen_rtx (CONST_INT, VOIDmode, i);
962:
963: if (CONST_OK_FOR_LETTER_P (i, 'I'))
964: return "mov %1,%0";
965: else if ((i & 0x000003FF) != 0)
966: return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0";
967: else
968: return "sethi %%hi(%a1),%0";
969: }
970: else if (GET_CODE (operands[1]) == CONST_INT
971: && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I'))
972: {
973: int i = INTVAL (operands[1]);
974:
975: /* If all low order 10 bits are clear, then we only need a single
976: sethi insn to load the constant. */
977: if ((i & 0x000003FF) != 0)
978: return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0";
979: else
980: return "sethi %%hi(%a1),%0";
981: }
982: /* Operand 1 must be a register, or a 'I' type CONST_INT. */
983: return "mov %1,%0";
984: }
985:
986: /* Return non-zero if it is OK to assume that the given memory operand is
987: aligned at least to a 8-byte boundary. This should only be called
988: for memory accesses whose size is 8 bytes or larger. */
989:
990: int
991: mem_aligned_8 (mem)
992: register rtx mem;
993: {
994: register rtx addr;
995: register rtx base;
996: register rtx offset;
997:
998: if (GET_CODE (mem) != MEM)
999: return 0; /* It's gotta be a MEM! */
1000:
1001: addr = XEXP (mem, 0);
1002:
1003: /* Now that all misaligned double parms are copied on function entry,
1004: we can assume any 64-bit object is 64-bit aligned except those which
1005: are at unaligned offsets from the stack or frame pointer. If the
1006: TARGET_UNALIGNED_DOUBLES switch is given, we do not make this
1007: assumption. */
1008:
1009: /* See what register we use in the address. */
1010: base = 0;
1011: if (GET_CODE (addr) == PLUS)
1012: {
1013: if (GET_CODE (XEXP (addr, 0)) == REG
1014: && GET_CODE (XEXP (addr, 1)) == CONST_INT)
1015: {
1016: base = XEXP (addr, 0);
1017: offset = XEXP (addr, 1);
1018: }
1019: }
1020: else if (GET_CODE (addr) == REG)
1021: {
1022: base = addr;
1023: offset = const0_rtx;
1024: }
1025:
1026: /* If it's the stack or frame pointer, check offset alignment.
1027: We can have improper alignment in the function entry code. */
1028: if (base
1029: && (REGNO (base) == FRAME_POINTER_REGNUM
1030: || REGNO (base) == STACK_POINTER_REGNUM))
1031: {
1032: if ((INTVAL (offset) & 0x7) == 0)
1033: return 1;
1034: }
1035: /* Anything else we know is properly aligned unless TARGET_UNALIGNED_DOUBLES
1036: is true, in which case we can only assume that an access is aligned if
1037: it is to an aggregate, it is to a constant address, or the address
1038: involves a LO_SUM. */
1039: else if (! TARGET_UNALIGNED_DOUBLES || MEM_IN_STRUCT_P (mem)
1040: || CONSTANT_P (addr) || GET_CODE (addr) == LO_SUM)
1041: return 1;
1042:
1043: /* An obviously unaligned address. */
1044: return 0;
1045: }
1046:
1047: enum optype { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP };
1048:
1049: /* Output assembler code to perform a doubleword move insn
1050: with operands OPERANDS. This is very similar to the following
1051: output_move_quad function. */
1052:
1053: char *
1054: output_move_double (operands)
1055: rtx *operands;
1056: {
1057: register rtx op0 = operands[0];
1058: register rtx op1 = operands[1];
1059: register enum optype optype0;
1060: register enum optype optype1;
1061: rtx latehalf[2];
1062: rtx addreg0 = 0;
1063: rtx addreg1 = 0;
1064:
1065: /* First classify both operands. */
1066:
1067: if (REG_P (op0))
1068: optype0 = REGOP;
1069: else if (offsettable_memref_p (op0))
1070: optype0 = OFFSOP;
1071: else if (GET_CODE (op0) == MEM)
1072: optype0 = MEMOP;
1073: else
1074: optype0 = RNDOP;
1075:
1076: if (REG_P (op1))
1077: optype1 = REGOP;
1078: else if (CONSTANT_P (op1))
1079: optype1 = CNSTOP;
1080: else if (offsettable_memref_p (op1))
1081: optype1 = OFFSOP;
1082: else if (GET_CODE (op1) == MEM)
1083: optype1 = MEMOP;
1084: else
1085: optype1 = RNDOP;
1086:
1087: /* Check for the cases that the operand constraints are not
1088: supposed to allow to happen. Abort if we get one,
1089: because generating code for these cases is painful. */
1090:
1091: if (optype0 == RNDOP || optype1 == RNDOP
1092: || (optype0 == MEM && optype1 == MEM))
1093: abort ();
1094:
1095: /* If an operand is an unoffsettable memory ref, find a register
1096: we can increment temporarily to make it refer to the second word. */
1097:
1098: if (optype0 == MEMOP)
1099: addreg0 = find_addr_reg (XEXP (op0, 0));
1100:
1101: if (optype1 == MEMOP)
1102: addreg1 = find_addr_reg (XEXP (op1, 0));
1103:
1104: /* Ok, we can do one word at a time.
1105: Set up in LATEHALF the operands to use for the
1106: high-numbered (least significant) word and in some cases alter the
1107: operands in OPERANDS to be suitable for the low-numbered word. */
1108:
1109: if (optype0 == REGOP)
1110: latehalf[0] = gen_rtx (REG, SImode, REGNO (op0) + 1);
1111: else if (optype0 == OFFSOP)
1112: latehalf[0] = adj_offsettable_operand (op0, 4);
1113: else
1114: latehalf[0] = op0;
1115:
1116: if (optype1 == REGOP)
1117: latehalf[1] = gen_rtx (REG, SImode, REGNO (op1) + 1);
1118: else if (optype1 == OFFSOP)
1119: latehalf[1] = adj_offsettable_operand (op1, 4);
1120: else if (optype1 == CNSTOP)
1121: split_double (op1, &operands[1], &latehalf[1]);
1122: else
1123: latehalf[1] = op1;
1124:
1125: /* Easy case: try moving both words at once. Check for moving between
1126: an even/odd register pair and a memory location. */
1127: if ((optype0 == REGOP && optype1 != REGOP && optype1 != CNSTOP
1128: && (REGNO (op0) & 1) == 0)
1129: || (optype0 != REGOP && optype0 != CNSTOP && optype1 == REGOP
1130: && (REGNO (op1) & 1) == 0))
1131: {
1132: register rtx mem;
1133:
1134: if (optype0 == REGOP)
1135: mem = op1;
1136: else
1137: mem = op0;
1138:
1139: if (mem_aligned_8 (mem))
1140: return (mem == op1 ? "ldd %1,%0" : "std %1,%0");
1141: }
1142:
1143: /* If the first move would clobber the source of the second one,
1144: do them in the other order. */
1145:
1146: /* Overlapping registers. */
1147: if (optype0 == REGOP && optype1 == REGOP
1148: && REGNO (op0) == REGNO (latehalf[1]))
1149: {
1150: /* Do that word. */
1151: output_asm_insn (singlemove_string (latehalf), latehalf);
1152: /* Do low-numbered word. */
1153: return singlemove_string (operands);
1154: }
1155: /* Loading into a register which overlaps a register used in the address. */
1156: else if (optype0 == REGOP && optype1 != REGOP
1157: && reg_overlap_mentioned_p (op0, op1))
1158: {
1159: /* ??? This fails if the address is a double register address, each
1160: of which is clobbered by operand 0. */
1161: /* Do the late half first. */
1162: output_asm_insn (singlemove_string (latehalf), latehalf);
1163: /* Then clobber. */
1164: return singlemove_string (operands);
1165: }
1166:
1167: /* Normal case: do the two words, low-numbered first. */
1168:
1169: output_asm_insn (singlemove_string (operands), operands);
1170:
1171: /* Make any unoffsettable addresses point at high-numbered word. */
1172: if (addreg0)
1173: output_asm_insn ("add %0,0x4,%0", &addreg0);
1174: if (addreg1)
1175: output_asm_insn ("add %0,0x4,%0", &addreg1);
1176:
1177: /* Do that word. */
1178: output_asm_insn (singlemove_string (latehalf), latehalf);
1179:
1180: /* Undo the adds we just did. */
1181: if (addreg0)
1182: output_asm_insn ("add %0,-0x4,%0", &addreg0);
1183: if (addreg1)
1184: output_asm_insn ("add %0,-0x4,%0", &addreg1);
1185:
1186: return "";
1187: }
1188:
1189: /* Output assembler code to perform a quadword move insn
1190: with operands OPERANDS. This is very similar to the preceding
1191: output_move_double function. */
1192:
1193: char *
1194: output_move_quad (operands)
1195: rtx *operands;
1196: {
1197: register rtx op0 = operands[0];
1198: register rtx op1 = operands[1];
1199: register enum optype optype0;
1200: register enum optype optype1;
1201: rtx wordpart[4][2];
1202: rtx addreg0 = 0;
1203: rtx addreg1 = 0;
1204:
1205: /* First classify both operands. */
1206:
1207: if (REG_P (op0))
1208: optype0 = REGOP;
1209: else if (offsettable_memref_p (op0))
1210: optype0 = OFFSOP;
1211: else if (GET_CODE (op0) == MEM)
1212: optype0 = MEMOP;
1213: else
1214: optype0 = RNDOP;
1215:
1216: if (REG_P (op1))
1217: optype1 = REGOP;
1218: else if (CONSTANT_P (op1))
1219: optype1 = CNSTOP;
1220: else if (offsettable_memref_p (op1))
1221: optype1 = OFFSOP;
1222: else if (GET_CODE (op1) == MEM)
1223: optype1 = MEMOP;
1224: else
1225: optype1 = RNDOP;
1226:
1227: /* Check for the cases that the operand constraints are not
1228: supposed to allow to happen. Abort if we get one,
1229: because generating code for these cases is painful. */
1230:
1231: if (optype0 == RNDOP || optype1 == RNDOP
1232: || (optype0 == MEM && optype1 == MEM))
1233: abort ();
1234:
1235: /* If an operand is an unoffsettable memory ref, find a register
1236: we can increment temporarily to make it refer to the later words. */
1237:
1238: if (optype0 == MEMOP)
1239: addreg0 = find_addr_reg (XEXP (op0, 0));
1240:
1241: if (optype1 == MEMOP)
1242: addreg1 = find_addr_reg (XEXP (op1, 0));
1243:
1244: /* Ok, we can do one word at a time.
1245: Set up in wordpart the operands to use for each word of the arguments. */
1246:
1247: if (optype0 == REGOP)
1248: {
1249: wordpart[0][0] = gen_rtx (REG, SImode, REGNO (op0) + 0);
1250: wordpart[1][0] = gen_rtx (REG, SImode, REGNO (op0) + 1);
1251: wordpart[2][0] = gen_rtx (REG, SImode, REGNO (op0) + 2);
1252: wordpart[3][0] = gen_rtx (REG, SImode, REGNO (op0) + 3);
1253: }
1254: else if (optype0 == OFFSOP)
1255: {
1256: wordpart[0][0] = adj_offsettable_operand (op0, 0);
1257: wordpart[1][0] = adj_offsettable_operand (op0, 4);
1258: wordpart[2][0] = adj_offsettable_operand (op0, 8);
1259: wordpart[3][0] = adj_offsettable_operand (op0, 12);
1260: }
1261: else
1262: {
1263: wordpart[0][0] = op0;
1264: wordpart[1][0] = op0;
1265: wordpart[2][0] = op0;
1266: wordpart[3][0] = op0;
1267: }
1268:
1269: if (optype1 == REGOP)
1270: {
1271: wordpart[0][1] = gen_rtx (REG, SImode, REGNO (op1) + 0);
1272: wordpart[1][1] = gen_rtx (REG, SImode, REGNO (op1) + 1);
1273: wordpart[2][1] = gen_rtx (REG, SImode, REGNO (op1) + 2);
1274: wordpart[3][1] = gen_rtx (REG, SImode, REGNO (op1) + 3);
1275: }
1276: else if (optype1 == OFFSOP)
1277: {
1278: wordpart[0][1] = adj_offsettable_operand (op1, 0);
1279: wordpart[1][1] = adj_offsettable_operand (op1, 4);
1280: wordpart[2][1] = adj_offsettable_operand (op1, 8);
1281: wordpart[3][1] = adj_offsettable_operand (op1, 12);
1282: }
1283: else if (optype1 == CNSTOP)
1284: {
1285: /* This case isn't implemented yet, because there is no internal
1286: representation for quad-word constants, and there is no split_quad
1287: function. */
1288: #if 0
1289: split_quad (op1, &wordpart[0][1], &wordpart[1][1],
1290: &wordpart[2][1], &wordpart[3][1]);
1291: #else
1292: abort ();
1293: #endif
1294: }
1295: else
1296: {
1297: wordpart[0][1] = op1;
1298: wordpart[1][1] = op1;
1299: wordpart[2][1] = op1;
1300: wordpart[3][1] = op1;
1301: }
1302:
1303: /* Easy case: try moving the quad as two pairs. Check for moving between
1304: an even/odd register pair and a memory location. */
1305: /* ??? Should also handle the case of non-offsettable addresses here.
1306: We can at least do the first pair as a ldd/std, and then do the third
1307: and fourth words individually. */
1308: if ((optype0 == REGOP && optype1 == OFFSOP && (REGNO (op0) & 1) == 0)
1309: || (optype0 == OFFSOP && optype1 == REGOP && (REGNO (op1) & 1) == 0))
1310: {
1311: rtx mem;
1312:
1313: if (optype0 == REGOP)
1314: mem = op1;
1315: else
1316: mem = op0;
1317:
1318: if (mem_aligned_8 (mem))
1319: {
1320: operands[2] = adj_offsettable_operand (mem, 8);
1321: if (mem == op1)
1322: return "ldd %1,%0;ldd %2,%S0";
1323: else
1324: return "std %1,%0;std %S1,%2";
1325: }
1326: }
1327:
1328: /* If the first move would clobber the source of the second one,
1329: do them in the other order. */
1330:
1331: /* Overlapping registers. */
1332: if (optype0 == REGOP && optype1 == REGOP
1333: && (REGNO (op0) == REGNO (wordpart[1][3])
1334: || REGNO (op0) == REGNO (wordpart[1][2])
1335: || REGNO (op0) == REGNO (wordpart[1][1])))
1336: {
1337: /* Do fourth word. */
1338: output_asm_insn (singlemove_string (wordpart[3]), wordpart[3]);
1339: /* Do the third word. */
1340: output_asm_insn (singlemove_string (wordpart[2]), wordpart[2]);
1341: /* Do the second word. */
1342: output_asm_insn (singlemove_string (wordpart[1]), wordpart[1]);
1343: /* Do lowest-numbered word. */
1344: return singlemove_string (wordpart[0]);
1345: }
1346: /* Loading into a register which overlaps a register used in the address. */
1347: if (optype0 == REGOP && optype1 != REGOP
1348: && reg_overlap_mentioned_p (op0, op1))
1349: {
1350: /* ??? Not implemented yet. This is a bit complicated, because we
1351: must load which ever part overlaps the address last. If the address
1352: is a double-reg address, then there are two parts which need to
1353: be done last, which is impossible. We would need a scratch register
1354: in that case. */
1355: abort ();
1356: }
1357:
1358: /* Normal case: move the four words in lowest to higest address order. */
1359:
1360: output_asm_insn (singlemove_string (wordpart[0]), wordpart[0]);
1361:
1362: /* Make any unoffsettable addresses point at the second word. */
1363: if (addreg0)
1364: output_asm_insn ("add %0,0x4,%0", &addreg0);
1365: if (addreg1)
1366: output_asm_insn ("add %0,0x4,%0", &addreg1);
1367:
1368: /* Do the second word. */
1369: output_asm_insn (singlemove_string (wordpart[1]), wordpart[1]);
1370:
1371: /* Make any unoffsettable addresses point at the third word. */
1372: if (addreg0)
1373: output_asm_insn ("add %0,0x4,%0", &addreg0);
1374: if (addreg1)
1375: output_asm_insn ("add %0,0x4,%0", &addreg1);
1376:
1377: /* Do the third word. */
1378: output_asm_insn (singlemove_string (wordpart[2]), wordpart[2]);
1379:
1380: /* Make any unoffsettable addresses point at the fourth word. */
1381: if (addreg0)
1382: output_asm_insn ("add %0,0x4,%0", &addreg0);
1383: if (addreg1)
1384: output_asm_insn ("add %0,0x4,%0", &addreg1);
1385:
1386: /* Do the fourth word. */
1387: output_asm_insn (singlemove_string (wordpart[3]), wordpart[3]);
1388:
1389: /* Undo the adds we just did. */
1390: if (addreg0)
1391: output_asm_insn ("add %0,-0xc,%0", &addreg0);
1392: if (addreg1)
1393: output_asm_insn ("add %0,-0xc,%0", &addreg1);
1394:
1395: return "";
1396: }
1397:
1398: /* Output assembler code to perform a doubleword move insn with operands
1399: OPERANDS, one of which must be a floating point register. */
1400:
1401: char *
1402: output_fp_move_double (operands)
1403: rtx *operands;
1404: {
1405: if (FP_REG_P (operands[0]))
1406: {
1407: if (FP_REG_P (operands[1]))
1408: return "fmovs %1,%0\n\tfmovs %R1,%R0";
1409: else if (GET_CODE (operands[1]) == REG)
1410: abort ();
1411: else
1412: return output_move_double (operands);
1413: }
1414: else if (FP_REG_P (operands[1]))
1415: {
1416: if (GET_CODE (operands[0]) == REG)
1417: abort ();
1418: else
1419: return output_move_double (operands);
1420: }
1421: else abort ();
1422: }
1423:
1424: /* Output assembler code to perform a quadword move insn with operands
1425: OPERANDS, one of which must be a floating point register. */
1426:
1427: char *
1428: output_fp_move_quad (operands)
1429: rtx *operands;
1430: {
1431: register rtx op0 = operands[0];
1432: register rtx op1 = operands[1];
1433:
1434: if (FP_REG_P (op0))
1435: {
1436: if (FP_REG_P (op1))
1437: return "fmovs %1,%0\n\tfmovs %R1,%R0\n\tfmovs %S1,%S0\n\tfmovs %T1,%T0";
1438: else if (GET_CODE (op1) == REG)
1439: abort ();
1440: else
1441: return output_move_quad (operands);
1442: }
1443: else if (FP_REG_P (op1))
1444: {
1445: if (GET_CODE (op0) == REG)
1446: abort ();
1447: else
1448: return output_move_quad (operands);
1449: }
1450: else
1451: abort ();
1452: }
1453:
1454: /* Return a REG that occurs in ADDR with coefficient 1.
1455: ADDR can be effectively incremented by incrementing REG. */
1456:
1457: static rtx
1458: find_addr_reg (addr)
1459: rtx addr;
1460: {
1461: while (GET_CODE (addr) == PLUS)
1462: {
1463: /* We absolutely can not fudge the frame pointer here, because the
1464: frame pointer must always be 8 byte aligned. It also confuses
1465: debuggers. */
1466: if (GET_CODE (XEXP (addr, 0)) == REG
1467: && REGNO (XEXP (addr, 0)) != FRAME_POINTER_REGNUM)
1468: addr = XEXP (addr, 0);
1469: else if (GET_CODE (XEXP (addr, 1)) == REG
1470: && REGNO (XEXP (addr, 1)) != FRAME_POINTER_REGNUM)
1471: addr = XEXP (addr, 1);
1472: else if (CONSTANT_P (XEXP (addr, 0)))
1473: addr = XEXP (addr, 1);
1474: else if (CONSTANT_P (XEXP (addr, 1)))
1475: addr = XEXP (addr, 0);
1476: else
1477: abort ();
1478: }
1479: if (GET_CODE (addr) == REG)
1480: return addr;
1481: abort ();
1482: }
1483:
1484: void
1485: output_sized_memop (opname, mode, signedp)
1486: char *opname;
1487: enum machine_mode mode;
1488: int signedp;
1489: {
1490: static char *ld_size_suffix_u[] = { "ub", "uh", "", "?", "d" };
1491: static char *ld_size_suffix_s[] = { "sb", "sh", "", "?", "d" };
1492: static char *st_size_suffix[] = { "b", "h", "", "?", "d" };
1493: char **opnametab, *modename;
1494:
1495: if (opname[0] == 'l')
1496: if (signedp)
1497: opnametab = ld_size_suffix_s;
1498: else
1499: opnametab = ld_size_suffix_u;
1500: else
1501: opnametab = st_size_suffix;
1502: modename = opnametab[GET_MODE_SIZE (mode) >> 1];
1503:
1504: fprintf (asm_out_file, "\t%s%s", opname, modename);
1505: }
1506:
1507: void
1508: output_move_with_extension (operands)
1509: rtx *operands;
1510: {
1511: if (GET_MODE (operands[2]) == HImode)
1512: output_asm_insn ("sll %2,0x10,%0", operands);
1513: else if (GET_MODE (operands[2]) == QImode)
1514: output_asm_insn ("sll %2,0x18,%0", operands);
1515: else
1516: abort ();
1517: }
1518:
1519: #if 0
1520: /* ??? These are only used by the movstrsi pattern, but we get better code
1521: in general without that, because emit_block_move can do just as good a
1522: job as this function does when alignment and size are known. When they
1523: aren't known, a call to strcpy may be faster anyways, because it is
1524: likely to be carefully crafted assembly language code, and below we just
1525: do a byte-wise copy.
1526:
1527: Also, emit_block_move expands into multiple read/write RTL insns, which
1528: can then be optimized, whereas our movstrsi pattern can not be optimized
1529: at all. */
1530:
1531: /* Load the address specified by OPERANDS[3] into the register
1532: specified by OPERANDS[0].
1533:
1534: OPERANDS[3] may be the result of a sum, hence it could either be:
1535:
1536: (1) CONST
1537: (2) REG
1538: (2) REG + CONST_INT
1539: (3) REG + REG + CONST_INT
1540: (4) REG + REG (special case of 3).
1541:
1542: Note that (3) is not a legitimate address.
1543: All cases are handled here. */
1544:
1545: void
1546: output_load_address (operands)
1547: rtx *operands;
1548: {
1549: rtx base, offset;
1550:
1551: if (CONSTANT_P (operands[3]))
1552: {
1553: output_asm_insn ("set %3,%0", operands);
1554: return;
1555: }
1556:
1557: if (REG_P (operands[3]))
1558: {
1559: if (REGNO (operands[0]) != REGNO (operands[3]))
1560: output_asm_insn ("mov %3,%0", operands);
1561: return;
1562: }
1563:
1564: if (GET_CODE (operands[3]) != PLUS)
1565: abort ();
1566:
1567: base = XEXP (operands[3], 0);
1568: offset = XEXP (operands[3], 1);
1569:
1570: if (GET_CODE (base) == CONST_INT)
1571: {
1572: rtx tmp = base;
1573: base = offset;
1574: offset = tmp;
1575: }
1576:
1577: if (GET_CODE (offset) != CONST_INT)
1578: {
1579: /* Operand is (PLUS (REG) (REG)). */
1580: base = operands[3];
1581: offset = const0_rtx;
1582: }
1583:
1584: if (REG_P (base))
1585: {
1586: operands[6] = base;
1587: operands[7] = offset;
1588: if (SMALL_INT (offset))
1589: output_asm_insn ("add %6,%7,%0", operands);
1590: else
1591: output_asm_insn ("set %7,%0\n\tadd %0,%6,%0", operands);
1592: }
1593: else if (GET_CODE (base) == PLUS)
1594: {
1595: operands[6] = XEXP (base, 0);
1596: operands[7] = XEXP (base, 1);
1597: operands[8] = offset;
1598:
1599: if (SMALL_INT (offset))
1600: output_asm_insn ("add %6,%7,%0\n\tadd %0,%8,%0", operands);
1601: else
1602: output_asm_insn ("set %8,%0\n\tadd %0,%6,%0\n\tadd %0,%7,%0", operands);
1603: }
1604: else
1605: abort ();
1606: }
1607:
1608: /* Output code to place a size count SIZE in register REG.
1609: ALIGN is the size of the unit of transfer.
1610:
1611: Because block moves are pipelined, we don't include the
1612: first element in the transfer of SIZE to REG. */
1613:
1614: static void
1615: output_size_for_block_move (size, reg, align)
1616: rtx size, reg;
1617: rtx align;
1618: {
1619: rtx xoperands[3];
1620:
1621: xoperands[0] = reg;
1622: xoperands[1] = size;
1623: xoperands[2] = align;
1624: if (GET_CODE (size) == REG)
1625: output_asm_insn ("sub %1,%2,%0", xoperands);
1626: else
1627: {
1628: xoperands[1]
1629: = gen_rtx (CONST_INT, VOIDmode, INTVAL (size) - INTVAL (align));
1630: output_asm_insn ("set %1,%0", xoperands);
1631: }
1632: }
1633:
1634: /* Emit code to perform a block move.
1635:
1636: OPERANDS[0] is the destination.
1637: OPERANDS[1] is the source.
1638: OPERANDS[2] is the size.
1639: OPERANDS[3] is the alignment safe to use.
1640: OPERANDS[4] is a register we can safely clobber as a temp. */
1641:
1642: char *
1643: output_block_move (operands)
1644: rtx *operands;
1645: {
1646: /* A vector for our computed operands. Note that load_output_address
1647: makes use of (and can clobber) up to the 8th element of this vector. */
1648: rtx xoperands[10];
1649: rtx zoperands[10];
1650: static int movstrsi_label = 0;
1651: int i;
1652: rtx temp1 = operands[4];
1653: rtx sizertx = operands[2];
1654: rtx alignrtx = operands[3];
1655: int align = INTVAL (alignrtx);
1656: char label3[30], label5[30];
1657:
1658: xoperands[0] = operands[0];
1659: xoperands[1] = operands[1];
1660: xoperands[2] = temp1;
1661:
1662: /* We can't move more than this many bytes at a time because we have only
1663: one register, %g1, to move them through. */
1664: if (align > UNITS_PER_WORD)
1665: {
1666: align = UNITS_PER_WORD;
1667: alignrtx = gen_rtx (CONST_INT, VOIDmode, UNITS_PER_WORD);
1668: }
1669:
1670: /* We consider 8 ld/st pairs, for a total of 16 inline insns to be
1671: reasonable here. (Actually will emit a maximum of 18 inline insns for
1672: the case of size == 31 and align == 4). */
1673:
1674: if (GET_CODE (sizertx) == CONST_INT && (INTVAL (sizertx) / align) <= 8
1675: && memory_address_p (QImode, plus_constant_for_output (xoperands[0],
1676: INTVAL (sizertx)))
1677: && memory_address_p (QImode, plus_constant_for_output (xoperands[1],
1678: INTVAL (sizertx))))
1679: {
1680: int size = INTVAL (sizertx);
1681: int offset = 0;
1682:
1683: /* We will store different integers into this particular RTX. */
1684: xoperands[2] = rtx_alloc (CONST_INT);
1685: PUT_MODE (xoperands[2], VOIDmode);
1686:
1687: /* This case is currently not handled. Abort instead of generating
1688: bad code. */
1689: if (align > 4)
1690: abort ();
1691:
1692: if (align >= 4)
1693: {
1694: for (i = (size >> 2) - 1; i >= 0; i--)
1695: {
1696: INTVAL (xoperands[2]) = (i << 2) + offset;
1697: output_asm_insn ("ld [%a1+%2],%%g1\n\tst %%g1,[%a0+%2]",
1698: xoperands);
1699: }
1700: offset += (size & ~0x3);
1701: size = size & 0x3;
1702: if (size == 0)
1703: return "";
1704: }
1705:
1706: if (align >= 2)
1707: {
1708: for (i = (size >> 1) - 1; i >= 0; i--)
1709: {
1710: INTVAL (xoperands[2]) = (i << 1) + offset;
1711: output_asm_insn ("lduh [%a1+%2],%%g1\n\tsth %%g1,[%a0+%2]",
1712: xoperands);
1713: }
1714: offset += (size & ~0x1);
1715: size = size & 0x1;
1716: if (size == 0)
1717: return "";
1718: }
1719:
1720: if (align >= 1)
1721: {
1722: for (i = size - 1; i >= 0; i--)
1723: {
1724: INTVAL (xoperands[2]) = i + offset;
1725: output_asm_insn ("ldub [%a1+%2],%%g1\n\tstb %%g1,[%a0+%2]",
1726: xoperands);
1727: }
1728: return "";
1729: }
1730:
1731: /* We should never reach here. */
1732: abort ();
1733: }
1734:
1735: /* If the size isn't known to be a multiple of the alignment,
1736: we have to do it in smaller pieces. If we could determine that
1737: the size was a multiple of 2 (or whatever), we could be smarter
1738: about this. */
1739: if (GET_CODE (sizertx) != CONST_INT)
1740: align = 1;
1741: else
1742: {
1743: int size = INTVAL (sizertx);
1744: while (size % align)
1745: align >>= 1;
1746: }
1747:
1748: if (align != INTVAL (alignrtx))
1749: alignrtx = gen_rtx (CONST_INT, VOIDmode, align);
1750:
1751: xoperands[3] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++);
1752: xoperands[4] = gen_rtx (CONST_INT, VOIDmode, align);
1753: xoperands[5] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++);
1754:
1755: ASM_GENERATE_INTERNAL_LABEL (label3, "Lm", INTVAL (xoperands[3]));
1756: ASM_GENERATE_INTERNAL_LABEL (label5, "Lm", INTVAL (xoperands[5]));
1757:
1758: /* This is the size of the transfer. Emit code to decrement the size
1759: value by ALIGN, and store the result in the temp1 register. */
1760: output_size_for_block_move (sizertx, temp1, alignrtx);
1761:
1762: /* Must handle the case when the size is zero or negative, so the first thing
1763: we do is compare the size against zero, and only copy bytes if it is
1764: zero or greater. Note that we have already subtracted off the alignment
1765: once, so we must copy 1 alignment worth of bytes if the size is zero
1766: here.
1767:
1768: The SUN assembler complains about labels in branch delay slots, so we
1769: do this before outputting the load address, so that there will always
1770: be a harmless insn between the branch here and the next label emitted
1771: below. */
1772:
1773: {
1774: char pattern[100];
1775:
1776: sprintf (pattern, "cmp %%2,0\n\tbl %s", &label5[1]);
1777: output_asm_insn (pattern, xoperands);
1778: }
1779:
1780: zoperands[0] = operands[0];
1781: zoperands[3] = plus_constant_for_output (operands[0], align);
1782: output_load_address (zoperands);
1783:
1784: /* ??? This might be much faster if the loops below were preconditioned
1785: and unrolled.
1786:
1787: That is, at run time, copy enough bytes one at a time to ensure that the
1788: target and source addresses are aligned to the the largest possible
1789: alignment. Then use a preconditioned unrolled loop to copy say 16
1790: bytes at a time. Then copy bytes one at a time until finish the rest. */
1791:
1792: /* Output the first label separately, so that it is spaced properly. */
1793:
1794: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "Lm", INTVAL (xoperands[3]));
1795:
1796: {
1797: char pattern[200];
1798: register char *ld_suffix = (align == 1) ? "ub" : (align == 2) ? "uh" : "";
1799: register char *st_suffix = (align == 1) ? "b" : (align == 2) ? "h" : "";
1800:
1801: sprintf (pattern, "ld%s [%%1+%%2],%%%%g1\n\tsubcc %%2,%%4,%%2\n\tbge %s\n\tst%s %%%%g1,[%%0+%%2]\n%s:", ld_suffix, &label3[1], st_suffix, &label5[1]);
1802: output_asm_insn (pattern, xoperands);
1803: }
1804:
1805: return "";
1806: }
1807: #endif
1808:
1809: /* Output reasonable peephole for set-on-condition-code insns.
1810: Note that these insns assume a particular way of defining
1811: labels. Therefore, *both* sparc.h and this function must
1812: be changed if a new syntax is needed. */
1813:
1814: char *
1815: output_scc_insn (operands, insn)
1816: rtx operands[];
1817: rtx insn;
1818: {
1819: static char string[100];
1820: rtx label = 0, next = insn;
1821: int need_label = 0;
1822:
1823: /* Try doing a jump optimization which jump.c can't do for us
1824: because we did not expose that setcc works by using branches.
1825:
1826: If this scc insn is followed by an unconditional branch, then have
1827: the jump insn emitted here jump to that location, instead of to
1828: the end of the scc sequence as usual. */
1829:
1830: do
1831: {
1832: if (GET_CODE (next) == CODE_LABEL)
1833: label = next;
1834: next = NEXT_INSN (next);
1835: if (next == 0)
1836: break;
1837: }
1838: while (GET_CODE (next) == NOTE || GET_CODE (next) == CODE_LABEL);
1839:
1840: /* If we are in a sequence, and the following insn is a sequence also,
1841: then just following the current insn's next field will take us to the
1842: first insn of the next sequence, which is the wrong place. We don't
1843: want to optimize with a branch that has had its delay slot filled.
1844: Avoid this by verifying that NEXT_INSN (PREV_INSN (next)) == next
1845: which fails only if NEXT is such a branch. */
1846:
1847: if (next && GET_CODE (next) == JUMP_INSN && simplejump_p (next)
1848: && (! final_sequence || NEXT_INSN (PREV_INSN (next)) == next))
1849: label = JUMP_LABEL (next);
1850: /* If not optimizing, jump label fields are not set. To be safe, always
1851: check here to whether label is still zero. */
1852: if (label == 0)
1853: {
1854: label = gen_label_rtx ();
1855: need_label = 1;
1856: }
1857:
1858: LABEL_NUSES (label) += 1;
1859:
1860: operands[2] = label;
1861:
1862: /* If we are in a delay slot, assume it is the delay slot of an fpcc
1863: insn since our type isn't allowed anywhere else. */
1864:
1865: /* ??? Fpcc instructions no longer have delay slots, so this code is
1866: probably obsolete. */
1867:
1868: /* The fastest way to emit code for this is an annulled branch followed
1869: by two move insns. This will take two cycles if the branch is taken,
1870: and three cycles if the branch is not taken.
1871:
1872: However, if we are in the delay slot of another branch, this won't work,
1873: because we can't put a branch in the delay slot of another branch.
1874: The above sequence would effectively take 3 or 4 cycles respectively
1875: since a no op would have be inserted between the two branches.
1876: In this case, we want to emit a move, annulled branch, and then the
1877: second move. This sequence always takes 3 cycles, and hence is faster
1878: when we are in a branch delay slot. */
1879:
1880: if (final_sequence)
1881: {
1882: strcpy (string, "mov 0,%0\n\t");
1883: strcat (string, output_cbranch (operands[1], 2, 0, 1, 0));
1884: strcat (string, "\n\tmov 1,%0");
1885: }
1886: else
1887: {
1888: strcpy (string, output_cbranch (operands[1], 2, 0, 1, 0));
1889: strcat (string, "\n\tmov 1,%0\n\tmov 0,%0");
1890: }
1891:
1892: if (need_label)
1893: strcat (string, "\n%l2:");
1894:
1895: return string;
1896: }
1897:
1898: /* Vectors to keep interesting information about registers where
1899: it can easily be got. */
1900:
1901: /* Modes for condition codes. */
1902: #define C_MODES \
1903: ((1 << (int) CCmode) | (1 << (int) CC_NOOVmode) \
1904: | (1 << (int) CCFPmode) | (1 << (int) CCFPEmode))
1905:
1906: /* Modes for single-word (and smaller) quantities. */
1907: #define S_MODES \
1908: ((1 << (int) QImode) | (1 << (int) HImode) | (1 << (int) SImode) \
1909: | (1 << (int) QFmode) | (1 << (int) HFmode) | (1 << (int) SFmode) \
1910: | (1 << (int) CQImode) | (1 << (int) CHImode))
1911:
1912: /* Modes for double-word (and smaller) quantities. */
1913: #define D_MODES \
1914: (S_MODES | (1 << (int) DImode) | (1 << (int) DFmode) \
1915: | (1 << (int) CSImode) | (1 << (int) SCmode))
1916:
1917: /* Modes for quad-word quantities. */
1918: #define T_MODES \
1919: (D_MODES | (1 << (int) TImode) | (1 << (int) TFmode) \
1920: | (1 << (int) DCmode) | (1 << (int) CDImode))
1921:
1922: /* Modes for single-float quantities. We must allow any single word or
1923: smaller quantity. This is because the fix/float conversion instructions
1924: take integer inputs/outputs from the float registers. */
1925: #define SF_MODES (S_MODES)
1926:
1927: /* Modes for double-float quantities. */
1928: #define DF_MODES (SF_MODES | (1 << (int) DFmode) | (1 << (int) SCmode))
1929:
1930: /* Modes for quad-float quantities. */
1931: #define TF_MODES (DF_MODES | (1 << (int) TFmode) | (1 << (int) DCmode))
1932:
1933: /* Value is 1 if register/mode pair is acceptable on sparc.
1934: The funny mixture of D and T modes is because integer operations
1935: do not specially operate on tetra quantities, so non-quad-aligned
1936: registers can hold quadword quantities (except %o4 and %i4 because
1937: they cross fixed registers. */
1938:
1939: int hard_regno_mode_ok[] = {
1940: C_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
1941: T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, D_MODES, S_MODES,
1942: T_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
1943: T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, D_MODES, S_MODES,
1944:
1945: TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES,
1946: TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES,
1947: TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES,
1948: TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES};
1949:
1950: #ifdef __GNUC__
1951: inline
1952: #endif
1953: static int
1954: save_regs (file, low, high, base, offset, n_fregs)
1955: FILE *file;
1956: int low, high;
1957: char *base;
1958: int offset;
1959: int n_fregs;
1960: {
1961: int i;
1962:
1963: for (i = low; i < high; i += 2)
1964: {
1965: if (regs_ever_live[i] && ! call_used_regs[i])
1966: if (regs_ever_live[i+1] && ! call_used_regs[i+1])
1967: fprintf (file, "\tstd %s,[%s+%d]\n",
1968: reg_names[i], base, offset + 4 * n_fregs),
1969: n_fregs += 2;
1970: else
1971: fprintf (file, "\tst %s,[%s+%d]\n",
1972: reg_names[i], base, offset + 4 * n_fregs),
1973: n_fregs += 2;
1974: else if (regs_ever_live[i+1] && ! call_used_regs[i+1])
1975: fprintf (file, "\tst %s,[%s+%d]\n",
1976: reg_names[i+1], base, offset + 4 * n_fregs),
1977: n_fregs += 2;
1978: }
1979: return n_fregs;
1980: }
1981:
1982: #ifdef __GNUC__
1983: inline
1984: #endif
1985: static int
1986: restore_regs (file, low, high, base, offset, n_fregs)
1987: FILE *file;
1988: int low, high;
1989: char *base;
1990: int offset;
1991: {
1992: int i;
1993:
1994: for (i = low; i < high; i += 2)
1995: {
1996: if (regs_ever_live[i] && ! call_used_regs[i])
1997: if (regs_ever_live[i+1] && ! call_used_regs[i+1])
1998: fprintf (file, "\tldd [%s+%d], %s\n",
1999: base, offset + 4 * n_fregs, reg_names[i]),
2000: n_fregs += 2;
2001: else
2002: fprintf (file, "\tld [%s+%d],%s\n",
2003: base, offset + 4 * n_fregs, reg_names[i]),
2004: n_fregs += 2;
2005: else if (regs_ever_live[i+1] && ! call_used_regs[i+1])
2006: fprintf (file, "\tld [%s+%d],%s\n",
2007: base, offset + 4 * n_fregs, reg_names[i+1]),
2008: n_fregs += 2;
2009: }
2010: return n_fregs;
2011: }
2012:
2013: /* Static variables we want to share between prologue and epilogue. */
2014:
2015: /* Number of live floating point registers needed to be saved. */
2016: static int num_fregs;
2017:
2018: int
2019: compute_frame_size (size, leaf_function)
2020: int size;
2021: int leaf_function;
2022: {
2023: int fregs_ever_live = 0;
2024: int n_fregs = 0, i;
2025: int outgoing_args_size = (current_function_outgoing_args_size
2026: + REG_PARM_STACK_SPACE (current_function_decl));
2027:
2028: apparent_fsize = ((size) + 7 - STARTING_FRAME_OFFSET) & -8;
2029: for (i = 32; i < FIRST_PSEUDO_REGISTER; i += 2)
2030: fregs_ever_live |= regs_ever_live[i]|regs_ever_live[i+1];
2031:
2032: if (TARGET_EPILOGUE && fregs_ever_live)
2033: {
2034: for (i = 32; i < FIRST_PSEUDO_REGISTER; i += 2)
2035: if ((regs_ever_live[i] && ! call_used_regs[i])
2036: || (regs_ever_live[i+1] && ! call_used_regs[i+1]))
2037: n_fregs += 2;
2038: }
2039:
2040: /* Set up values for use in `function_epilogue'. */
2041: num_fregs = n_fregs;
2042:
2043: apparent_fsize += (outgoing_args_size+7) & -8;
2044: if (leaf_function && n_fregs == 0
2045: && apparent_fsize == (REG_PARM_STACK_SPACE (current_function_decl)
2046: - STARTING_FRAME_OFFSET))
2047: apparent_fsize = 0;
2048:
2049: actual_fsize = apparent_fsize + n_fregs*4;
2050:
2051: /* Make sure nothing can clobber our register windows.
2052: If a SAVE must be done, or there is a stack-local variable,
2053: the register window area must be allocated. */
2054: if (leaf_function == 0 || size > 0)
2055: actual_fsize += (16 * UNITS_PER_WORD)+8;
2056:
2057: return actual_fsize;
2058: }
2059:
2060: /* Output code for the function prologue. */
2061:
2062: void
2063: output_function_prologue (file, size, leaf_function)
2064: FILE *file;
2065: int size;
2066: int leaf_function;
2067: {
2068: /* ??? This should be %sp+actual_fsize for a leaf function. I think it
2069: works only because it is never used. */
2070: if (leaf_function)
2071: frame_base_name = "%sp+80";
2072: else
2073: frame_base_name = "%fp";
2074:
2075: /* Need to use actual_fsize, since we are also allocating
2076: space for our callee (and our own register save area). */
2077: actual_fsize = compute_frame_size (size, leaf_function);
2078:
2079: fprintf (file, "\t!#PROLOGUE# 0\n");
2080: if (actual_fsize == 0)
2081: /* do nothing. */ ;
2082: else if (actual_fsize <= 4096)
2083: {
2084: if (! leaf_function)
2085: fprintf (file, "\tsave %%sp,-%d,%%sp\n", actual_fsize);
2086: else
2087: fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize);
2088: }
2089: else if (actual_fsize <= 8192)
2090: {
2091: /* For frames in the range 4097..8192, we can use just two insns. */
2092: if (! leaf_function)
2093: {
2094: fprintf (file, "\tsave %%sp,-4096,%%sp\n");
2095: fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize - 4096);
2096: }
2097: else
2098: {
2099: fprintf (file, "\tadd %%sp,-4096,%%sp\n");
2100: fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize - 4096);
2101: }
2102: }
2103: else
2104: {
2105: if (! leaf_function)
2106: {
2107: fprintf (file, "\tsethi %%hi(-%d),%%g1\n", actual_fsize);
2108: if ((actual_fsize & 0x3ff) != 0)
2109: fprintf (file, "\tor %%g1,%%lo(-%d),%%g1\n", actual_fsize);
2110: fprintf (file, "\tsave %%sp,%%g1,%%sp\n");
2111: }
2112: else
2113: {
2114: fprintf (file, "\tsethi %%hi(-%d),%%g1\n", actual_fsize);
2115: if ((actual_fsize & 0x3ff) != 0)
2116: fprintf (file, "\tor %%g1,%%lo(-%d),%%g1\n", actual_fsize);
2117: fprintf (file, "\tadd %%sp,%%g1,%%sp\n");
2118: }
2119: }
2120:
2121: /* If doing anything with PIC, do it now. */
2122: if (! flag_pic)
2123: fprintf (file, "\t!#PROLOGUE# 1\n");
2124:
2125: /* Figure out where to save any special registers. */
2126: if (num_fregs)
2127: {
2128: int offset, n_fregs = num_fregs;
2129:
2130: /* ??? This should always be -apparent_fsize. */
2131: if (! leaf_function)
2132: offset = -apparent_fsize;
2133: else
2134: offset = 0;
2135:
2136: if (TARGET_EPILOGUE && ! leaf_function)
2137: n_fregs = save_regs (file, 0, 16, frame_base_name, offset, 0);
2138: else if (leaf_function)
2139: n_fregs = save_regs (file, 0, 32, frame_base_name, offset, 0);
2140: if (TARGET_EPILOGUE)
2141: save_regs (file, 32, FIRST_PSEUDO_REGISTER,
2142: frame_base_name, offset, n_fregs);
2143: }
2144:
2145: leaf_label = 0;
2146: if (leaf_function && actual_fsize != 0)
2147: {
2148: /* warning ("leaf procedure with frame size %d", actual_fsize); */
2149: if (! TARGET_EPILOGUE)
2150: leaf_label = gen_label_rtx ();
2151: }
2152: }
2153:
2154: /* Output code for the function epilogue. */
2155:
2156: void
2157: output_function_epilogue (file, size, leaf_function)
2158: FILE *file;
2159: int size;
2160: int leaf_function;
2161: {
2162: char *ret;
2163:
2164: if (leaf_label)
2165: {
2166: emit_label_after (leaf_label, get_last_insn ());
2167: final_scan_insn (get_last_insn (), file, 0, 0, 1);
2168: }
2169:
2170: if (num_fregs)
2171: {
2172: int offset, n_fregs = num_fregs;
2173:
2174: /* ??? This should always be -apparent_fsize. */
2175: if (! leaf_function)
2176: offset = -apparent_fsize;
2177: else
2178: offset = 0;
2179:
2180: if (TARGET_EPILOGUE && ! leaf_function)
2181: n_fregs = restore_regs (file, 0, 16, frame_base_name, offset, 0);
2182: else if (leaf_function)
2183: n_fregs = restore_regs (file, 0, 32, frame_base_name, offset, 0);
2184: if (TARGET_EPILOGUE)
2185: restore_regs (file, 32, FIRST_PSEUDO_REGISTER,
2186: frame_base_name, offset, n_fregs);
2187: }
2188:
2189: /* Work out how to skip the caller's unimp instruction if required. */
2190: if (leaf_function)
2191: ret = (current_function_returns_struct ? "jmp %o7+12" : "retl");
2192: else
2193: ret = (current_function_returns_struct ? "jmp %i7+12" : "ret");
2194:
2195: if (TARGET_EPILOGUE || leaf_label)
2196: {
2197: int old_target_epilogue = TARGET_EPILOGUE;
2198: target_flags &= ~old_target_epilogue;
2199:
2200: if (! leaf_function)
2201: {
2202: /* If we wound up with things in our delay slot, flush them here. */
2203: if (current_function_epilogue_delay_list)
2204: {
2205: rtx insn = emit_jump_insn_after (gen_rtx (RETURN, VOIDmode),
2206: get_last_insn ());
2207: PATTERN (insn) = gen_rtx (PARALLEL, VOIDmode,
2208: gen_rtvec (2,
2209: PATTERN (XEXP (current_function_epilogue_delay_list, 0)),
2210: PATTERN (insn)));
2211: final_scan_insn (insn, file, 1, 0, 1);
2212: }
2213: else
2214: fprintf (file, "\t%s\n\trestore\n", ret);
2215: }
2216: /* All of the following cases are for leaf functions. */
2217: else if (current_function_epilogue_delay_list)
2218: {
2219: /* eligible_for_epilogue_delay_slot ensures that if this is a
2220: leaf function, then we will only have insn in the delay slot
2221: if the frame size is zero, thus no adjust for the stack is
2222: needed here. */
2223: if (actual_fsize != 0)
2224: abort ();
2225: fprintf (file, "\t%s\n", ret);
2226: final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),
2227: file, 1, 0, 1);
2228: }
2229: /* Output 'nop' instead of 'sub %sp,-0,%sp' when no frame, so as to
2230: avoid generating confusing assembly language output. */
2231: else if (actual_fsize == 0)
2232: fprintf (file, "\t%s\n\tnop\n", ret);
2233: else if (actual_fsize <= 4096)
2234: fprintf (file, "\t%s\n\tsub %%sp,-%d,%%sp\n", ret, actual_fsize);
2235: else if (actual_fsize <= 8192)
2236: fprintf (file, "\tsub %%sp,-4096,%%sp\n\t%s\n\tsub %%sp,-%d,%%sp\n",
2237: ret, actual_fsize - 4096);
2238: else if ((actual_fsize & 0x3ff) == 0)
2239: fprintf (file, "\tsethi %%hi(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n",
2240: actual_fsize, ret);
2241: else
2242: fprintf (file, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n",
2243: actual_fsize, actual_fsize, ret);
2244: target_flags |= old_target_epilogue;
2245: }
2246: }
2247:
2248: /* Do what is necessary for `va_start'. The argument is ignored;
2249: We look at the current function to determine if stdarg or varargs
2250: is used and return the address of the first unnamed parameter. */
2251:
2252: rtx
2253: sparc_builtin_saveregs (arglist)
2254: tree arglist;
2255: {
2256: tree fntype = TREE_TYPE (current_function_decl);
2257: int stdarg = (TYPE_ARG_TYPES (fntype) != 0
2258: && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2259: != void_type_node));
2260: int first_reg = current_function_args_info;
2261: rtx address;
2262: int regno;
2263:
2264: #if 0 /* This code seemed to have no effect except to make
2265: varargs not work right when va_list wasn't the first arg. */
2266: if (! stdarg)
2267: first_reg = 0;
2268: #endif
2269:
2270: for (regno = first_reg; regno < NPARM_REGS; regno++)
2271: emit_move_insn (gen_rtx (MEM, word_mode,
2272: gen_rtx (PLUS, Pmode,
2273: frame_pointer_rtx,
2274: GEN_INT (STACK_POINTER_OFFSET
2275: + UNITS_PER_WORD * regno))),
2276: gen_rtx (REG, word_mode, BASE_INCOMING_ARG_REG (word_mode)
2277: + regno));
2278:
2279: address = gen_rtx (PLUS, Pmode,
2280: frame_pointer_rtx,
2281: GEN_INT (STACK_POINTER_OFFSET
2282: + UNITS_PER_WORD * first_reg));
2283:
2284: return address;
2285: }
2286:
2287: /* Return the string to output a conditional branch to LABEL, which is
2288: the operand number of the label. OP is the conditional expression. The
2289: mode of register 0 says what kind of comparison we made.
2290:
2291: REVERSED is non-zero if we should reverse the sense of the comparison.
2292:
2293: ANNUL is non-zero if we should generate an annulling branch.
2294:
2295: NOOP is non-zero if we have to follow this branch by a noop. */
2296:
2297: char *
2298: output_cbranch (op, label, reversed, annul, noop)
2299: rtx op;
2300: int label;
2301: int reversed, annul, noop;
2302: {
2303: static char string[20];
2304: enum rtx_code code = GET_CODE (op);
2305: enum machine_mode mode = GET_MODE (XEXP (op, 0));
2306: static char labelno[] = " %lX";
2307:
2308: /* ??? FP branches can not be preceded by another floating point insn.
2309: Because there is currently no concept of pre-delay slots, we can fix
2310: this only by always emitting a nop before a floating point branch. */
2311:
2312: if (mode == CCFPmode || mode == CCFPEmode)
2313: strcpy (string, "nop\n\t");
2314:
2315: /* If not floating-point or if EQ or NE, we can just reverse the code. */
2316: if (reversed
2317: && ((mode != CCFPmode && mode != CCFPEmode) || code == EQ || code == NE))
2318: code = reverse_condition (code), reversed = 0;
2319:
2320: /* Start by writing the branch condition. */
2321: switch (code)
2322: {
2323: case NE:
2324: if (mode == CCFPmode || mode == CCFPEmode)
2325: strcat (string, "fbne");
2326: else
2327: strcpy (string, "bne");
2328: break;
2329:
2330: case EQ:
2331: if (mode == CCFPmode || mode == CCFPEmode)
2332: strcat (string, "fbe");
2333: else
2334: strcpy (string, "be");
2335: break;
2336:
2337: case GE:
2338: if (mode == CCFPmode || mode == CCFPEmode)
2339: {
2340: if (reversed)
2341: strcat (string, "fbul");
2342: else
2343: strcat (string, "fbge");
2344: }
2345: else if (mode == CC_NOOVmode)
2346: strcpy (string, "bpos");
2347: else
2348: strcpy (string, "bge");
2349: break;
2350:
2351: case GT:
2352: if (mode == CCFPmode || mode == CCFPEmode)
2353: {
2354: if (reversed)
2355: strcat (string, "fbule");
2356: else
2357: strcat (string, "fbg");
2358: }
2359: else
2360: strcpy (string, "bg");
2361: break;
2362:
2363: case LE:
2364: if (mode == CCFPmode || mode == CCFPEmode)
2365: {
2366: if (reversed)
2367: strcat (string, "fbug");
2368: else
2369: strcat (string, "fble");
2370: }
2371: else
2372: strcpy (string, "ble");
2373: break;
2374:
2375: case LT:
2376: if (mode == CCFPmode || mode == CCFPEmode)
2377: {
2378: if (reversed)
2379: strcat (string, "fbuge");
2380: else
2381: strcat (string, "fbl");
2382: }
2383: else if (mode == CC_NOOVmode)
2384: strcpy (string, "bneg");
2385: else
2386: strcpy (string, "bl");
2387: break;
2388:
2389: case GEU:
2390: strcpy (string, "bgeu");
2391: break;
2392:
2393: case GTU:
2394: strcpy (string, "bgu");
2395: break;
2396:
2397: case LEU:
2398: strcpy (string, "bleu");
2399: break;
2400:
2401: case LTU:
2402: strcpy (string, "blu");
2403: break;
2404: }
2405:
2406: /* Now add the annulling, the label, and a possible noop. */
2407: if (annul)
2408: strcat (string, ",a");
2409:
2410: labelno[3] = label + '0';
2411: strcat (string, labelno);
2412:
2413: if (noop)
2414: strcat (string, "\n\tnop");
2415:
2416: return string;
2417: }
2418:
2419: /* Output assembler code to return from a function. */
2420:
2421: char *
2422: output_return (operands)
2423: rtx *operands;
2424: {
2425: if (leaf_label)
2426: {
2427: operands[0] = leaf_label;
2428: return "b,a %l0";
2429: }
2430: else if (leaf_function)
2431: {
2432: /* If we didn't allocate a frame pointer for the current function,
2433: the stack pointer might have been adjusted. Output code to
2434: restore it now. */
2435:
2436: operands[0] = gen_rtx (CONST_INT, VOIDmode, actual_fsize);
2437:
2438: /* Use sub of negated value in first two cases instead of add to
2439: allow actual_fsize == 4096. */
2440:
2441: if (actual_fsize <= 4096)
2442: {
2443: if (current_function_returns_struct)
2444: return "jmp %%o7+12\n\tsub %%sp,-%0,%%sp";
2445: else
2446: return "retl\n\tsub %%sp,-%0,%%sp";
2447: }
2448: else if (actual_fsize <= 8192)
2449: {
2450: operands[0] = gen_rtx (CONST_INT, VOIDmode, actual_fsize - 4096);
2451: if (current_function_returns_struct)
2452: return "sub %%sp,-4096,%%sp\n\tjmp %%o7+12\n\tsub %%sp,-%0,%%sp";
2453: else
2454: return "sub %%sp,-4096,%%sp\n\tretl\n\tsub %%sp,-%0,%%sp";
2455: }
2456: else if (current_function_returns_struct)
2457: {
2458: if ((actual_fsize & 0x3ff) != 0)
2459: return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp";
2460: else
2461: return "sethi %%hi(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp";
2462: }
2463: else
2464: {
2465: if ((actual_fsize & 0x3ff) != 0)
2466: return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp";
2467: else
2468: return "sethi %%hi(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp";
2469: }
2470: }
2471: else
2472: {
2473: if (current_function_returns_struct)
2474: return "jmp %%i7+12\n\trestore";
2475: else
2476: return "ret\n\trestore";
2477: }
2478: }
2479:
2480: /* Leaf functions and non-leaf functions have different needs. */
2481:
2482: static int
2483: reg_leaf_alloc_order[] = REG_LEAF_ALLOC_ORDER;
2484:
2485: static int
2486: reg_nonleaf_alloc_order[] = REG_ALLOC_ORDER;
2487:
2488: static int *reg_alloc_orders[] = {
2489: reg_leaf_alloc_order,
2490: reg_nonleaf_alloc_order};
2491:
2492: void
2493: order_regs_for_local_alloc ()
2494: {
2495: static int last_order_nonleaf = 1;
2496:
2497: if (regs_ever_live[15] != last_order_nonleaf)
2498: {
2499: last_order_nonleaf = !last_order_nonleaf;
2500: bcopy (reg_alloc_orders[last_order_nonleaf], reg_alloc_order,
2501: FIRST_PSEUDO_REGISTER * sizeof (int));
2502: }
2503: }
2504:
2505: /* Return 1 if REGNO (reg1) is even and REGNO (reg1) == REGNO (reg2) - 1.
2506: This makes them candidates for using ldd and std insns.
2507:
2508: Note reg1 and reg2 *must* be hard registers. To be sure we will
2509: abort if we are passed pseudo registers. */
2510:
2511: int
2512: registers_ok_for_ldd_peep (reg1, reg2)
2513: rtx reg1, reg2;
2514: {
2515:
2516: /* We might have been passed a SUBREG. */
2517: if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
2518: return 0;
2519:
2520: if (REGNO (reg1) % 2 != 0)
2521: return 0;
2522:
2523: return (REGNO (reg1) == REGNO (reg2) - 1);
2524:
2525: }
2526:
2527: /* Return 1 if addr1 and addr2 are suitable for use in an ldd or
2528: std insn.
2529:
2530: This can only happen when addr1 and addr2 are consecutive memory
2531: locations (addr1 + 4 == addr2). addr1 must also be aligned on a
2532: 64 bit boundary (addr1 % 8 == 0).
2533:
2534: We know %sp and %fp are kept aligned on a 64 bit boundary. Other
2535: registers are assumed to *never* be properly aligned and are
2536: rejected.
2537:
2538: Knowing %sp and %fp are kept aligned on a 64 bit boundary, we
2539: need only check that the offset for addr1 % 8 == 0. */
2540:
2541: int
2542: addrs_ok_for_ldd_peep (addr1, addr2)
2543: rtx addr1, addr2;
2544: {
2545: int reg1, offset1;
2546:
2547: /* Extract a register number and offset (if used) from the first addr. */
2548: if (GET_CODE (addr1) == PLUS)
2549: {
2550: /* If not a REG, return zero. */
2551: if (GET_CODE (XEXP (addr1, 0)) != REG)
2552: return 0;
2553: else
2554: {
2555: reg1 = REGNO (XEXP (addr1, 0));
2556: /* The offset must be constant! */
2557: if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
2558: return 0;
2559: offset1 = INTVAL (XEXP (addr1, 1));
2560: }
2561: }
2562: else if (GET_CODE (addr1) != REG)
2563: return 0;
2564: else
2565: {
2566: reg1 = REGNO (addr1);
2567: /* This was a simple (mem (reg)) expression. Offset is 0. */
2568: offset1 = 0;
2569: }
2570:
2571: /* Make sure the second address is a (mem (plus (reg) (const_int). */
2572: if (GET_CODE (addr2) != PLUS)
2573: return 0;
2574:
2575: if (GET_CODE (XEXP (addr2, 0)) != REG
2576: || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
2577: return 0;
2578:
2579: /* Only %fp and %sp are allowed. Additionally both addresses must
2580: use the same register. */
2581: if (reg1 != FRAME_POINTER_REGNUM && reg1 != STACK_POINTER_REGNUM)
2582: return 0;
2583:
2584: if (reg1 != REGNO (XEXP (addr2, 0)))
2585: return 0;
2586:
2587: /* The first offset must be evenly divisible by 8 to ensure the
2588: address is 64 bit aligned. */
2589: if (offset1 % 8 != 0)
2590: return 0;
2591:
2592: /* The offset for the second addr must be 4 more than the first addr. */
2593: if (INTVAL (XEXP (addr2, 1)) != offset1 + 4)
2594: return 0;
2595:
2596: /* All the tests passed. addr1 and addr2 are valid for ldd and std
2597: instructions. */
2598: return 1;
2599: }
2600:
2601: /* Return 1 if reg is a pseudo, or is the first register in
2602: a hard register pair. This makes it a candidate for use in
2603: ldd and std insns. */
2604:
2605: int
2606: register_ok_for_ldd (reg)
2607: rtx reg;
2608: {
2609:
2610: /* We might have been passed a SUBREG. */
2611: if (GET_CODE (reg) != REG)
2612: return 0;
2613:
2614: if (REGNO (reg) < FIRST_PSEUDO_REGISTER)
2615: return (REGNO (reg) % 2 == 0);
2616: else
2617: return 1;
2618:
2619: }
2620:
2621: /* Print operand X (an rtx) in assembler syntax to file FILE.
2622: CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
2623: For `%' followed by punctuation, CODE is the punctuation and X is null. */
2624:
2625: void
2626: print_operand (file, x, code)
2627: FILE *file;
2628: rtx x;
2629: int code;
2630: {
2631: switch (code)
2632: {
2633: case '#':
2634: /* Output a 'nop' if there's nothing for the delay slot. */
2635: if (dbr_sequence_length () == 0)
2636: fputs ("\n\tnop", file);
2637: return;
2638: case '*':
2639: /* Output an annul flag if there's nothing for the delay slot and we
2640: are optimizing. This is always used with '(' below. */
2641: /* Sun OS 4.1.1 dbx can't handle an annulled unconditional branch;
2642: this is a dbx bug. So, we only do this when optimizing. */
2643: if (dbr_sequence_length () == 0 && optimize)
2644: fputs (",a", file);
2645: return;
2646: case '(':
2647: /* Output a 'nop' if there's nothing for the delay slot and we are
2648: not optimizing. This is always used with '*' above. */
2649: if (dbr_sequence_length () == 0 && ! optimize)
2650: fputs ("\n\tnop", file);
2651: return;
2652: case 'Y':
2653: /* Adjust the operand to take into account a RESTORE operation. */
2654: if (GET_CODE (x) != REG)
2655: output_operand_lossage ("Invalid %%Y operand");
2656: else if (REGNO (x) < 8)
2657: fputs (reg_names[REGNO (x)], file);
2658: else if (REGNO (x) >= 24 && REGNO (x) < 32)
2659: fputs (reg_names[REGNO (x)-16], file);
2660: else
2661: output_operand_lossage ("Invalid %%Y operand");
2662: return;
2663: case 'R':
2664: /* Print out the second register name of a register pair or quad.
2665: I.e., R (%o0) => %o1. */
2666: fputs (reg_names[REGNO (x)+1], file);
2667: return;
2668: case 'S':
2669: /* Print out the third register name of a register quad.
2670: I.e., S (%o0) => %o2. */
2671: fputs (reg_names[REGNO (x)+2], file);
2672: return;
2673: case 'T':
2674: /* Print out the fourth register name of a register quad.
2675: I.e., T (%o0) => %o3. */
2676: fputs (reg_names[REGNO (x)+3], file);
2677: return;
2678: case 'm':
2679: /* Print the operand's address only. */
2680: output_address (XEXP (x, 0));
2681: return;
2682: case 'r':
2683: /* In this case we need a register. Use %g0 if the
2684: operand is const0_rtx. */
2685: if (x == const0_rtx
2686: || (GET_MODE (x) != VOIDmode && x == CONST0_RTX (GET_MODE (x))))
2687: {
2688: fputs ("%g0", file);
2689: return;
2690: }
2691: else
2692: break;
2693:
2694: case 'A':
2695: switch (GET_CODE (x))
2696: {
2697: case IOR: fputs ("or", file); break;
2698: case AND: fputs ("and", file); break;
2699: case XOR: fputs ("xor", file); break;
2700: default: output_operand_lossage ("Invalid %%A operand");
2701: }
2702: return;
2703:
2704: case 'B':
2705: switch (GET_CODE (x))
2706: {
2707: case IOR: fputs ("orn", file); break;
2708: case AND: fputs ("andn", file); break;
2709: case XOR: fputs ("xnor", file); break;
2710: default: output_operand_lossage ("Invalid %%B operand");
2711: }
2712: return;
2713:
2714: case 'b':
2715: {
2716: /* Print a sign-extended character. */
2717: int i = INTVAL (x) & 0xff;
2718: if (i & 0x80)
2719: i |= 0xffffff00;
2720: fprintf (file, "%d", i);
2721: return;
2722: }
2723:
2724: case 0:
2725: /* Do nothing special. */
2726: break;
2727:
2728: default:
2729: /* Undocumented flag. */
2730: output_operand_lossage ("invalid operand output code");
2731: }
2732:
2733: if (GET_CODE (x) == REG)
2734: fputs (reg_names[REGNO (x)], file);
2735: else if (GET_CODE (x) == MEM)
2736: {
2737: fputc ('[', file);
2738: if (CONSTANT_P (XEXP (x, 0)))
2739: /* Poor Sun assembler doesn't understand absolute addressing. */
2740: fputs ("%g0+", file);
2741: output_address (XEXP (x, 0));
2742: fputc (']', file);
2743: }
2744: else if (GET_CODE (x) == HIGH)
2745: {
2746: fputs ("%hi(", file);
2747: output_addr_const (file, XEXP (x, 0));
2748: fputc (')', file);
2749: }
2750: else if (GET_CODE (x) == LO_SUM)
2751: {
2752: print_operand (file, XEXP (x, 0), 0);
2753: fputs ("+%lo(", file);
2754: output_addr_const (file, XEXP (x, 1));
2755: fputc (')', file);
2756: }
2757: else if (GET_CODE (x) == CONST_DOUBLE
2758: && (GET_MODE (x) == VOIDmode
2759: || GET_MODE_CLASS (GET_MODE (x)) == MODE_INT))
2760: {
2761: if (CONST_DOUBLE_HIGH (x) == 0)
2762: fprintf (file, "%u", CONST_DOUBLE_LOW (x));
2763: else if (CONST_DOUBLE_HIGH (x) == -1
2764: && CONST_DOUBLE_LOW (x) < 0)
2765: fprintf (file, "%d", CONST_DOUBLE_LOW (x));
2766: else
2767: output_operand_lossage ("long long constant not a valid immediate operand");
2768: }
2769: else if (GET_CODE (x) == CONST_DOUBLE)
2770: output_operand_lossage ("floating point constant not a valid immediate operand");
2771: else { output_addr_const (file, x); }
2772: }
2773:
2774: /* This function outputs assembler code for VALUE to FILE, where VALUE is
2775: a 64 bit (DImode) value. */
2776:
2777: /* ??? If there is a 64 bit counterpart to .word that the assembler
2778: understands, then using that would simply this code greatly. */
2779:
2780: void
2781: output_double_int (file, value)
2782: FILE *file;
2783: rtx value;
2784: {
2785: if (GET_CODE (value) == CONST_INT)
2786: {
2787: if (INTVAL (value) < 0)
2788: ASM_OUTPUT_INT (file, constm1_rtx);
2789: else
2790: ASM_OUTPUT_INT (file, const0_rtx);
2791: ASM_OUTPUT_INT (file, value);
2792: }
2793: else if (GET_CODE (value) == CONST_DOUBLE)
2794: {
2795: ASM_OUTPUT_INT (file, gen_rtx (CONST_INT, VOIDmode,
2796: CONST_DOUBLE_HIGH (value)));
2797: ASM_OUTPUT_INT (file, gen_rtx (CONST_INT, VOIDmode,
2798: CONST_DOUBLE_LOW (value)));
2799: }
2800: else if (GET_CODE (value) == SYMBOL_REF
2801: || GET_CODE (value) == CONST
2802: || GET_CODE (value) == PLUS)
2803: {
2804: /* Addresses are only 32 bits. */
2805: ASM_OUTPUT_INT (file, const0_rtx);
2806: ASM_OUTPUT_INT (file, value);
2807: }
2808: else
2809: abort ();
2810: }
2811:
2812: #ifndef CHAR_TYPE_SIZE
2813: #define CHAR_TYPE_SIZE BITS_PER_UNIT
2814: #endif
2815:
2816: #ifndef SHORT_TYPE_SIZE
2817: #define SHORT_TYPE_SIZE (BITS_PER_UNIT * 2)
2818: #endif
2819:
2820: #ifndef INT_TYPE_SIZE
2821: #define INT_TYPE_SIZE BITS_PER_WORD
2822: #endif
2823:
2824: #ifndef LONG_TYPE_SIZE
2825: #define LONG_TYPE_SIZE BITS_PER_WORD
2826: #endif
2827:
2828: #ifndef LONG_LONG_TYPE_SIZE
2829: #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)
2830: #endif
2831:
2832: #ifndef FLOAT_TYPE_SIZE
2833: #define FLOAT_TYPE_SIZE BITS_PER_WORD
2834: #endif
2835:
2836: #ifndef DOUBLE_TYPE_SIZE
2837: #define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
2838: #endif
2839:
2840: #ifndef LONG_DOUBLE_TYPE_SIZE
2841: #define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
2842: #endif
2843:
2844: unsigned long
2845: sparc_type_code (type)
2846: register tree type;
2847: {
2848: register unsigned long qualifiers = 0;
2849: register unsigned shift = 6;
2850:
2851: for (;;)
2852: {
2853: switch (TREE_CODE (type))
2854: {
2855: case ERROR_MARK:
2856: return qualifiers;
2857:
2858: case ARRAY_TYPE:
2859: qualifiers |= (3 << shift);
2860: shift += 2;
2861: type = TREE_TYPE (type);
2862: break;
2863:
2864: case FUNCTION_TYPE:
2865: case METHOD_TYPE:
2866: qualifiers |= (2 << shift);
2867: shift += 2;
2868: type = TREE_TYPE (type);
2869: break;
2870:
2871: case POINTER_TYPE:
2872: case REFERENCE_TYPE:
2873: case OFFSET_TYPE:
2874: qualifiers |= (1 << shift);
2875: shift += 2;
2876: type = TREE_TYPE (type);
2877: break;
2878:
2879: case RECORD_TYPE:
2880: return (qualifiers | 8);
2881:
2882: case UNION_TYPE:
2883: return (qualifiers | 9);
2884:
2885: case ENUMERAL_TYPE:
2886: return (qualifiers | 10);
2887:
2888: case VOID_TYPE:
2889: return (qualifiers | 16);
2890:
2891: case INTEGER_TYPE:
2892: /* Carefully distinguish all the standard types of C,
2893: without messing up if the language is not C.
2894: Note that we check only for the names that contain spaces;
2895: other names might occur by coincidence in other languages. */
2896: if (TYPE_NAME (type) != 0
2897: && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
2898: && DECL_NAME (TYPE_NAME (type)) != 0
2899: && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE)
2900: {
2901: char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
2902:
2903: if (!strcmp (name, "unsigned char"))
2904: return (qualifiers | 12);
2905: if (!strcmp (name, "signed char"))
2906: return (qualifiers | 2);
2907: if (!strcmp (name, "unsigned int"))
2908: return (qualifiers | 14);
2909: if (!strcmp (name, "short int"))
2910: return (qualifiers | 3);
2911: if (!strcmp (name, "short unsigned int"))
2912: return (qualifiers | 13);
2913: if (!strcmp (name, "long int"))
2914: return (qualifiers | 5);
2915: if (!strcmp (name, "long unsigned int"))
2916: return (qualifiers | 15);
2917: if (!strcmp (name, "long long int"))
2918: return (qualifiers | 5); /* Who knows? */
2919: if (!strcmp (name, "long long unsigned int"))
2920: return (qualifiers | 15); /* Who knows? */
2921: }
2922:
2923: /* Most integer types will be sorted out above, however, for the
2924: sake of special `array index' integer types, the following code
2925: is also provided. */
2926:
2927: if (TYPE_PRECISION (type) == INT_TYPE_SIZE)
2928: return (qualifiers | (TREE_UNSIGNED (type) ? 14 : 4));
2929:
2930: if (TYPE_PRECISION (type) == LONG_TYPE_SIZE)
2931: return (qualifiers | (TREE_UNSIGNED (type) ? 15 : 5));
2932:
2933: if (TYPE_PRECISION (type) == LONG_LONG_TYPE_SIZE)
2934: return (qualifiers | (TREE_UNSIGNED (type) ? 15 : 5));
2935:
2936: if (TYPE_PRECISION (type) == SHORT_TYPE_SIZE)
2937: return (qualifiers | (TREE_UNSIGNED (type) ? 13 : 3));
2938:
2939: if (TYPE_PRECISION (type) == CHAR_TYPE_SIZE)
2940: return (qualifiers | (TREE_UNSIGNED (type) ? 12 : 2));
2941:
2942: abort ();
2943:
2944: case REAL_TYPE:
2945: /* Carefully distinguish all the standard types of C,
2946: without messing up if the language is not C. */
2947: if (TYPE_NAME (type) != 0
2948: && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
2949: && DECL_NAME (TYPE_NAME (type)) != 0
2950: && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE)
2951: {
2952: char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
2953:
2954: if (!strcmp (name, "long double"))
2955: return (qualifiers | 7); /* Who knows? */
2956: }
2957:
2958: if (TYPE_PRECISION (type) == DOUBLE_TYPE_SIZE)
2959: return (qualifiers | 7);
2960: if (TYPE_PRECISION (type) == FLOAT_TYPE_SIZE)
2961: return (qualifiers | 6);
2962: if (TYPE_PRECISION (type) == LONG_DOUBLE_TYPE_SIZE)
2963: return (qualifiers | 7); /* Who knows? */
2964: abort ();
2965:
2966: case COMPLEX_TYPE: /* GNU Fortran COMPLEX type. */
2967: /* ??? We need to distinguish between double and float complex types,
2968: but I don't know how yet because I can't reach this code from
2969: existing front-ends. */
2970: return (qualifiers | 7); /* Who knows? */
2971:
2972: case CHAR_TYPE: /* GNU Pascal CHAR type. Not used in C. */
2973: case BOOLEAN_TYPE: /* GNU Fortran BOOLEAN type. */
2974: case FILE_TYPE: /* GNU Pascal FILE type. */
2975: case STRING_TYPE: /* GNU Fortran STRING type. */
2976: case LANG_TYPE: /* ? */
2977: abort ();
2978:
2979: default:
2980: abort (); /* Not a type! */
2981: }
2982: }
2983: }
2984:
2985: /* Subroutines to support a flat (single) register window calling
2986: convention. */
2987:
2988: /* Single-register window sparc stack frames look like:
2989:
2990: Before call After call
2991: +-----------------------+ +-----------------------+
2992: high | | | |
2993: mem. | | | |
2994: | caller's temps. | | caller's temps. |
2995: | | | |
2996: +-----------------------+ +-----------------------+
2997: | | | |
2998: | arguments on stack. | | arguments on stack. |
2999: | |FP+92->| |
3000: +-----------------------+ +-----------------------+
3001: | 6 words to save | | 6 words to save |
3002: | arguments passed | | arguments passed |
3003: | in registers, even | | in registers, even |
3004: SP+68->| if not passed. |FP+68->| if not passed. |
3005: +-----------------------+ +-----------------------+
3006: | 1 word struct addr |FP+64->| 1 word struct addr |
3007: +-----------------------+ +-----------------------+
3008: | | | |
3009: | 16 word reg save area | | 16 word reg save area |
3010: SP->| | FP->| |
3011: +-----------------------+ +-----------------------+
3012: | 4 word area for |
3013: FP-16->| fp/alu reg moves |
3014: +-----------------------+
3015: | |
3016: | local variables |
3017: | |
3018: +-----------------------+
3019: | |
3020: | fp register save |
3021: | |
3022: +-----------------------+
3023: | |
3024: | gp register save |
3025: | |
3026: +-----------------------+
3027: | |
3028: | alloca allocations |
3029: | |
3030: +-----------------------+
3031: | |
3032: | arguments on stack |
3033: SP+92->| |
3034: +-----------------------+
3035: | 6 words to save |
3036: | arguments passed |
3037: | in registers, even |
3038: low SP+68->| if not passed. |
3039: memory +-----------------------+
3040: SP+64->| 1 word struct addr |
3041: +-----------------------+
3042: | |
3043: I 16 word reg save area |
3044: SP->| |
3045: +-----------------------+ */
3046:
3047: /* Structure to be filled in by sparc_frw_compute_frame_size with register
3048: save masks, and offsets for the current function. */
3049:
3050: struct sparc_frame_info
3051: {
3052: unsigned long total_size; /* # bytes that the entire frame takes up. */
3053: unsigned long var_size; /* # bytes that variables take up. */
3054: unsigned long args_size; /* # bytes that outgoing arguments take up. */
3055: unsigned long extra_size; /* # bytes of extra gunk. */
3056: unsigned int gp_reg_size; /* # bytes needed to store gp regs. */
3057: unsigned int fp_reg_size; /* # bytes needed to store fp regs. */
3058: unsigned long mask; /* Mask of saved gp registers. */
3059: unsigned long fmask; /* Mask of saved fp registers. */
3060: unsigned long gp_sp_offset; /* Offset from new sp to store gp regs. */
3061: unsigned long fp_sp_offset; /* Offset from new sp to store fp regs. */
3062: int initialized; /* Nonzero if frame size already calculated. */
3063: };
3064:
3065: /* Current frame information calculated by sparc_frw_compute_frame_size. */
3066: struct sparc_frame_info current_frame_info;
3067:
3068: /* Zero structure to initialize current_frame_info. */
3069: struct sparc_frame_info zero_frame_info;
3070:
3071: /* Tell prologue and epilogue if register REGNO should be saved / restored. */
3072:
3073: #define MUST_SAVE_REGISTER(regno) \
3074: ((regs_ever_live[regno] && !call_used_regs[regno]) \
3075: || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed) \
3076: || (regno == 15 && regs_ever_live[15]))
3077:
3078: /* Return the bytes needed to compute the frame pointer from the current
3079: stack pointer. */
3080:
3081: unsigned long
3082: sparc_frw_compute_frame_size (size)
3083: int size; /* # of var. bytes allocated. */
3084: {
3085: int regno;
3086: unsigned long total_size; /* # bytes that the entire frame takes up. */
3087: unsigned long var_size; /* # bytes that variables take up. */
3088: unsigned long args_size; /* # bytes that outgoing arguments take up. */
3089: unsigned long extra_size; /* # extra bytes. */
3090: unsigned int gp_reg_size; /* # bytes needed to store gp regs. */
3091: unsigned int fp_reg_size; /* # bytes needed to store fp regs. */
3092: unsigned long mask; /* Mask of saved gp registers. */
3093: unsigned long fmask; /* Mask of saved fp registers. */
3094:
3095: /* This is the size of the 16 word reg save area, 1 word struct addr
3096: area, and 4 word fp/alu register copy area. */
3097: extra_size = -STARTING_FRAME_OFFSET + FIRST_PARM_OFFSET(0);
3098: var_size = size;
3099: /* Also include the size needed for the 6 parameter registers. */
3100: args_size = current_function_outgoing_args_size + 24;
3101: total_size = var_size + args_size + extra_size;
3102: gp_reg_size = 0;
3103: fp_reg_size = 0;
3104: mask = 0;
3105: fmask = 0;
3106:
3107: /* Calculate space needed for gp registers. */
3108: for (regno = 1; regno <= 31; regno++)
3109: {
3110: if (MUST_SAVE_REGISTER (regno))
3111: {
3112: if ((regno & 0x1) == 0 && MUST_SAVE_REGISTER (regno+1))
3113: {
3114: if (gp_reg_size % 8 != 0)
3115: gp_reg_size += UNITS_PER_WORD;
3116: gp_reg_size += 2 * UNITS_PER_WORD;
3117: mask |= 3 << regno;
3118: regno++;
3119: }
3120: else
3121: {
3122: gp_reg_size += UNITS_PER_WORD;
3123: mask |= 1 << regno;
3124: }
3125: }
3126: }
3127: /* Add extra word in case we have to align the space to a double word
3128: boundary. */
3129: if (gp_reg_size != 0)
3130: gp_reg_size += UNITS_PER_WORD;
3131:
3132: /* Calculate space needed for fp registers. */
3133: for (regno = 32; regno <= 63; regno++)
3134: {
3135: if (regs_ever_live[regno] && !call_used_regs[regno])
3136: {
3137: fp_reg_size += UNITS_PER_WORD;
3138: fmask |= 1 << (regno - 32);
3139: }
3140: }
3141:
3142: total_size += gp_reg_size + fp_reg_size;
3143:
3144: if (total_size == extra_size)
3145: total_size = extra_size = 0;
3146:
3147: total_size = SPARC_STACK_ALIGN (total_size);
3148:
3149: /* Save other computed information. */
3150: current_frame_info.total_size = total_size;
3151: current_frame_info.var_size = var_size;
3152: current_frame_info.args_size = args_size;
3153: current_frame_info.extra_size = extra_size;
3154: current_frame_info.gp_reg_size = gp_reg_size;
3155: current_frame_info.fp_reg_size = fp_reg_size;
3156: current_frame_info.mask = mask;
3157: current_frame_info.fmask = fmask;
3158: current_frame_info.initialized = reload_completed;
3159:
3160: if (mask)
3161: {
3162: unsigned long offset = args_size;
3163: if (extra_size)
3164: offset += FIRST_PARM_OFFSET(0);
3165: current_frame_info.gp_sp_offset = offset;
3166: }
3167:
3168: if (fmask)
3169: {
3170: unsigned long offset = args_size + gp_reg_size;
3171: if (extra_size)
3172: offset += FIRST_PARM_OFFSET(0);
3173: current_frame_info.fp_sp_offset = offset;
3174: }
3175:
3176: /* Ok, we're done. */
3177: return total_size;
3178: }
3179:
3180: /* Common code to save/restore registers. */
3181:
3182: void
3183: sparc_frw_save_restore (file, word_op, doubleword_op)
3184: FILE *file; /* Stream to write to. */
3185: char *word_op; /* Operation to do for one word. */
3186: char *doubleword_op; /* Operation to do for doubleword. */
3187: {
3188: int regno;
3189: unsigned long mask = current_frame_info.mask;
3190: unsigned long fmask = current_frame_info.fmask;
3191: unsigned long gp_offset;
3192: unsigned long fp_offset;
3193: unsigned long max_offset;
3194: char *base_reg;
3195:
3196: if (mask == 0 && fmask == 0)
3197: return;
3198:
3199: base_reg = reg_names[STACK_POINTER_REGNUM];
3200: gp_offset = current_frame_info.gp_sp_offset;
3201: fp_offset = current_frame_info.fp_sp_offset;
3202: max_offset = (gp_offset > fp_offset) ? gp_offset : fp_offset;
3203:
3204: /* Deal with calling functions with a large structure. */
3205: if (max_offset >= 4096)
3206: {
3207: char *temp = "%g2";
3208: fprintf (file, "\tset %ld,%s\n", max_offset, temp);
3209: fprintf (file, "\tadd %s,%s,%s\n", temp, base_reg, temp);
3210: base_reg = temp;
3211: gp_offset = max_offset - gp_offset;
3212: fp_offset = max_offset - fp_offset;
3213: }
3214:
3215: /* Save registers starting from high to low. The debuggers prefer
3216: at least the return register be stored at func+4, and also it
3217: allows us not to need a nop in the epilog if at least one
3218: register is reloaded in addition to return address. */
3219:
3220: if (mask || frame_pointer_needed)
3221: {
3222: for (regno = 1; regno <= 31; regno++)
3223: {
3224: if ((mask & (1L << regno)) != 0
3225: || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed))
3226: {
3227: if ((regno & 0x1) == 0 && ((mask & (1L << regno+1)) != 0))
3228: {
3229: if (gp_offset % 8 != 0)
3230: gp_offset += UNITS_PER_WORD;
3231:
3232: if (word_op[0] == 's')
3233: fprintf (file, "\t%s %s,[%s+%d]\n",
3234: doubleword_op, reg_names[regno],
3235: base_reg, gp_offset);
3236: else
3237: fprintf (file, "\t%s [%s+%d],%s\n",
3238: doubleword_op, base_reg, gp_offset,
3239: reg_names[regno]);
3240:
3241: gp_offset += 2 * UNITS_PER_WORD;
3242: regno++;
3243: }
3244: else
3245: {
3246: if (word_op[0] == 's')
3247: fprintf (file, "\t%s %s,[%s+%d]\n",
3248: word_op, reg_names[regno],
3249: base_reg, gp_offset);
3250: else
3251: fprintf (file, "\t%s [%s+%d],%s\n",
3252: word_op, base_reg, gp_offset, reg_names[regno]);
3253:
3254: gp_offset += UNITS_PER_WORD;
3255: }
3256: }
3257: }
3258: }
3259:
3260: if (fmask)
3261: {
3262: for (regno = 32; regno <= 63; regno++)
3263: {
3264: if ((fmask & (1L << (regno - 32))) != 0)
3265: {
3266: if (word_op[0] == 's')
3267: fprintf (file, "\t%s %s,[%s+%d]\n",
3268: word_op, reg_names[regno],
3269: base_reg, gp_offset);
3270: else
3271: fprintf (file, "\t%s [%s+%d],%s\n",
3272: word_op, base_reg, gp_offset, reg_names[regno]);
3273:
3274: fp_offset += UNITS_PER_WORD;
3275: }
3276: }
3277: }
3278: }
3279:
3280: /* Set up the stack and frame (if desired) for the function. */
3281:
3282: void
3283: sparc_frw_output_function_prologue (file, size, ignored)
3284: FILE *file;
3285: int size;
3286: {
3287: extern char call_used_regs[];
3288: int tsize;
3289: char *sp_str = reg_names[STACK_POINTER_REGNUM];
3290:
3291: /* ??? This should be %sp+actual_fsize for a leaf function. I think it
3292: works only because it is never used. */
3293: frame_base_name
3294: = (!frame_pointer_needed) ? "%sp+80" : reg_names[FRAME_POINTER_REGNUM];
3295:
3296: fprintf (file, "\t!#PROLOGUE# 0\n");
3297:
3298: size = SPARC_STACK_ALIGN (size);
3299: tsize = (! current_frame_info.initialized
3300: ? sparc_frw_compute_frame_size (size)
3301: : current_frame_info.total_size);
3302:
3303: if (tsize > 0)
3304: {
3305: if (tsize <= 4095)
3306: fprintf (file,
3307: "\tsub %s,%d,%s\t\t!# vars= %d, regs= %d/%d, args = %d, extra= %d\n",
3308: sp_str, tsize, sp_str, current_frame_info.var_size,
3309: current_frame_info.gp_reg_size / 4,
3310: current_frame_info.fp_reg_size / 8,
3311: current_function_outgoing_args_size,
3312: current_frame_info.extra_size);
3313: else
3314: fprintf (file,
3315: "\tset %d,%s\n\tsub\t%s,%s,%s\t\t!# vars= %d, regs= %d/%d, args = %d, sfo= %d\n",
3316: tsize, "%g1", sp_str, "%g1",
3317: sp_str, current_frame_info.var_size,
3318: current_frame_info.gp_reg_size / 4,
3319: current_frame_info.fp_reg_size / 8,
3320: current_function_outgoing_args_size,
3321: current_frame_info.extra_size);
3322: }
3323:
3324: sparc_frw_save_restore (file, "st", "std");
3325:
3326: if (frame_pointer_needed)
3327: {
3328: if (tsize <= 4095)
3329: fprintf (file, "\tadd %s,%d,%s\t!# set up frame pointer\n", sp_str,
3330: tsize, frame_base_name);
3331: else
3332: fprintf (file, "\tadd %s,%s,%s\t!# set up frame pointer\n", sp_str,
3333: "%g1", frame_base_name);
3334: }
3335: }
3336:
3337: /* Do any necessary cleanup after a function to restore stack, frame,
3338: and regs. */
3339:
3340: void
3341: sparc_frw_output_function_epilogue (file, size, ignored1, ignored2)
3342: FILE *file;
3343: int size;
3344: {
3345: extern FILE *asm_out_data_file, *asm_out_file;
3346: extern char call_used_regs[];
3347: extern int frame_pointer_needed;
3348: int tsize;
3349: char *sp_str = reg_names[STACK_POINTER_REGNUM];
3350: char *t1_str = "%g1";
3351: rtx epilogue_delay = current_function_epilogue_delay_list;
3352: int noepilogue = FALSE;
3353:
3354: /* The epilogue does not depend on any registers, but the stack
3355: registers, so we assume that if we have 1 pending nop, it can be
3356: ignored, and 2 it must be filled (2 nops occur for integer
3357: multiply and divide). */
3358:
3359: size = SPARC_STACK_ALIGN (size);
3360: tsize = (!current_frame_info.initialized
3361: ? sparc_frw_compute_frame_size (size)
3362: : current_frame_info.total_size);
3363:
3364: if (tsize == 0 && epilogue_delay == 0)
3365: {
3366: rtx insn = get_last_insn ();
3367:
3368: /* If the last insn was a BARRIER, we don't have to write any code
3369: because a jump (aka return) was put there. */
3370: if (GET_CODE (insn) == NOTE)
3371: insn = prev_nonnote_insn (insn);
3372: if (insn && GET_CODE (insn) == BARRIER)
3373: noepilogue = TRUE;
3374: }
3375:
3376: if (!noepilogue)
3377: {
3378: /* In the reload sequence, we don't need to fill the load delay
3379: slots for most of the loads, also see if we can fill the final
3380: delay slot if not otherwise filled by the reload sequence. */
3381:
3382: if (tsize > 4095)
3383: fprintf (file, "\tset %d,%s\n", tsize, t1_str);
3384:
3385: if (frame_pointer_needed)
3386: {
3387: char *fp_str = reg_names[FRAME_POINTER_REGNUM];
3388: if (tsize > 4095)
3389: fprintf (file,"\tsub %s,%s,%s\t\t!# sp not trusted here\n",
3390: fp_str, t1_str, sp_str);
3391: else
3392: fprintf (file,"\tsub %s,%d,%s\t\t!# sp not trusted here\n",
3393: fp_str, tsize, sp_str);
3394: }
3395:
3396: sparc_frw_save_restore (file, "ld", "ldd");
3397:
3398: if (current_function_returns_struct)
3399: fprintf (file, "\tjmp %%o7+12\n");
3400: else
3401: fprintf (file, "\tretl\n");
3402:
3403: /* If the only register saved is the return address, we need a
3404: nop, unless we have an instruction to put into it. Otherwise
3405: we don't since reloading multiple registers doesn't reference
3406: the register being loaded. */
3407:
3408: if (epilogue_delay)
3409: {
3410: if (tsize)
3411: abort ();
3412: final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1);
3413: }
3414:
3415: else if (tsize > 4095)
3416: fprintf (file, "\tadd %s,%s,%s\n", sp_str, t1_str, sp_str);
3417:
3418: else if (tsize > 0)
3419: fprintf (file, "\tadd %s,%d,%s\n", sp_str, tsize, sp_str);
3420:
3421: else
3422: fprintf (file, "\tnop\n");
3423: }
3424:
3425: /* Reset state info for each function. */
3426: current_frame_info = zero_frame_info;
3427: }
3428:
3429: /* Define the number of delay slots needed for the function epilogue.
3430:
3431: On the sparc, we need a slot if either no stack has been allocated,
3432: or the only register saved is the return register. */
3433:
3434: int
3435: sparc_frw_epilogue_delay_slots ()
3436: {
3437: if (!current_frame_info.initialized)
3438: (void) sparc_frw_compute_frame_size (get_frame_size ());
3439:
3440: if (current_frame_info.total_size == 0)
3441: return 1;
3442:
3443: return 0;
3444: }
3445:
3446: /* Return true is TRIAL is a valid insn for the epilogue delay slot.
3447: Any single length instruction which doesn't reference the stack or frame
3448: pointer is OK. */
3449:
3450: int
3451: sparc_frw_eligible_for_epilogue_delay (trial, slot)
3452: rtx trial;
3453: int slot;
3454: {
3455: if (get_attr_length (trial) == 1
3456: && ! reg_mentioned_p (stack_pointer_rtx, PATTERN (trial))
3457: && ! reg_mentioned_p (frame_pointer_rtx, PATTERN (trial)))
3458: return 1;
3459: return 0;
3460: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.