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