|
|
1.1 root 1: /* Subroutines for insn-output.c for Intel 860
2: Copyright (C) 1989, 1991 Free Software Foundation, Inc.
3: Derived from sparc.c.
4:
5: Written by Richard Stallman ([email protected]).
6:
7: Hacked substantially by Ron Guilmette ([email protected]) to cater
8: to the whims of the System V Release 4 assembler.
9:
10: This file is part of GNU CC.
11:
12: GNU CC is free software; you can redistribute it and/or modify
13: it under the terms of the GNU General Public License as published by
14: the Free Software Foundation; either version 2, or (at your option)
15: any later version.
16:
17: GNU CC is distributed in the hope that it will be useful,
18: but WITHOUT ANY WARRANTY; without even the implied warranty of
19: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20: GNU General Public License for more details.
21:
22: You should have received a copy of the GNU General Public License
23: along with GNU CC; see the file COPYING. If not, write to
24: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
25:
26:
27: #include "config.h"
28: #include "flags.h"
29: #include "rtl.h"
30: #include "regs.h"
31: #include "hard-reg-set.h"
32: #include "real.h"
33: #include "insn-config.h"
34: #include "conditions.h"
35: #include "insn-flags.h"
36: #include "output.h"
37: #include "recog.h"
38: #include "insn-attr.h"
39:
40: #include <stdio.h>
41:
42: static rtx find_addr_reg ();
43:
44: #ifndef I860_REG_PREFIX
45: #define I860_REG_PREFIX ""
46: #endif
47:
48: char *i860_reg_prefix = I860_REG_PREFIX;
49:
50: /* Save information from a "cmpxx" operation until the branch is emitted. */
51:
52: rtx i860_compare_op0, i860_compare_op1;
53:
54: /* Return non-zero if this pattern, can be evaluated safely, even if it
55: was not asked for. */
56: int
57: safe_insn_src_p (op, mode)
58: rtx op;
59: enum machine_mode mode;
60: {
61: /* Just experimenting. */
62:
63: /* No floating point src is safe if it contains an arithmetic
64: operation, since that operation may trap. */
65: switch (GET_CODE (op))
66: {
67: case CONST_INT:
68: case LABEL_REF:
69: case SYMBOL_REF:
70: case CONST:
71: return 1;
72:
73: case REG:
74: return 1;
75:
76: case MEM:
77: return CONSTANT_ADDRESS_P (XEXP (op, 0));
78:
79: /* We never need to negate or complement constants. */
80: case NEG:
81: return (mode != SFmode && mode != DFmode);
82: case NOT:
83: case ZERO_EXTEND:
84: return 1;
85:
86: case EQ:
87: case NE:
88: case LT:
89: case GT:
90: case LE:
91: case GE:
92: case LTU:
93: case GTU:
94: case LEU:
95: case GEU:
96: case MINUS:
97: case PLUS:
98: return (mode != SFmode && mode != DFmode);
99: case AND:
100: case IOR:
101: case XOR:
102: case LSHIFT:
103: case ASHIFT:
104: case ASHIFTRT:
105: case LSHIFTRT:
106: if ((GET_CODE (XEXP (op, 0)) == CONST_INT && ! SMALL_INT (XEXP (op, 0)))
107: || (GET_CODE (XEXP (op, 1)) == CONST_INT && ! SMALL_INT (XEXP (op, 1))))
108: return 0;
109: return 1;
110:
111: default:
112: return 0;
113: }
114: }
115:
116: /* Return 1 if REG is clobbered in IN.
117: Return 2 if REG is used in IN.
118: Return 3 if REG is both used and clobbered in IN.
119: Return 0 if neither. */
120:
121: static int
122: reg_clobbered_p (reg, in)
123: rtx reg;
124: rtx in;
125: {
126: register enum rtx_code code;
127:
128: if (in == 0)
129: return 0;
130:
131: code = GET_CODE (in);
132:
133: if (code == SET || code == CLOBBER)
134: {
135: rtx dest = SET_DEST (in);
136: int set = 0;
137: int used = 0;
138:
139: while (GET_CODE (dest) == STRICT_LOW_PART
140: || GET_CODE (dest) == SUBREG
141: || GET_CODE (dest) == SIGN_EXTRACT
142: || GET_CODE (dest) == ZERO_EXTRACT)
143: dest = XEXP (dest, 0);
144:
145: if (dest == reg)
146: set = 1;
147: else if (GET_CODE (dest) == REG
148: && refers_to_regno_p (REGNO (reg),
149: REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
150: SET_DEST (in), 0))
151: {
152: set = 1;
153: /* Anything that sets just part of the register
154: is considered using as well as setting it.
155: But note that a straight SUBREG of a single-word value
156: clobbers the entire value. */
157: if (dest != SET_DEST (in)
158: && ! (GET_CODE (SET_DEST (in)) == SUBREG
159: || UNITS_PER_WORD >= GET_MODE_SIZE (GET_MODE (dest))))
160: used = 1;
161: }
162:
163: if (code == SET)
164: {
165: if (set)
166: used = refers_to_regno_p (REGNO (reg),
167: REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
168: SET_SRC (in), 0);
169: else
170: used = refers_to_regno_p (REGNO (reg),
171: REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
172: in, 0);
173: }
174:
175: return set + used * 2;
176: }
177:
178: if (refers_to_regno_p (REGNO (reg),
179: REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
180: in, 0))
181: return 2;
182: return 0;
183: }
184:
185: /* Return non-zero if OP can be written to without screwing up
186: GCC's model of what's going on. It is assumed that this operand
187: appears in the dest position of a SET insn in a conditional
188: branch's delay slot. AFTER is the label to start looking from. */
189: int
190: operand_clobbered_before_used_after (op, after)
191: rtx op;
192: rtx after;
193: {
194: /* Just experimenting. */
195: if (GET_CODE (op) == CC0)
196: return 1;
197: if (GET_CODE (op) == REG)
198: {
199: rtx insn;
200:
201: if (op == stack_pointer_rtx)
202: return 0;
203:
204: /* Scan forward from the label, to see if the value of OP
205: is clobbered before the first use. */
206:
207: for (insn = NEXT_INSN (after); insn; insn = NEXT_INSN (insn))
208: {
209: if (GET_CODE (insn) == NOTE)
210: continue;
211: if (GET_CODE (insn) == INSN
212: || GET_CODE (insn) == JUMP_INSN
213: || GET_CODE (insn) == CALL_INSN)
214: {
215: switch (reg_clobbered_p (op, PATTERN (insn)))
216: {
217: default:
218: return 0;
219: case 1:
220: return 1;
221: case 0:
222: break;
223: }
224: }
225: /* If we reach another label without clobbering OP,
226: then we cannot safely write it here. */
227: else if (GET_CODE (insn) == CODE_LABEL)
228: return 0;
229: if (GET_CODE (insn) == JUMP_INSN)
230: {
231: if (condjump_p (insn))
232: return 0;
233: /* This is a jump insn which has already
234: been mangled. We can't tell what it does. */
235: if (GET_CODE (PATTERN (insn)) == PARALLEL)
236: return 0;
237: if (! JUMP_LABEL (insn))
238: return 0;
239: /* Keep following jumps. */
240: insn = JUMP_LABEL (insn);
241: }
242: }
243: return 1;
244: }
245:
246: /* In both of these cases, the first insn executed
247: for this op will be a orh whatever%h,%?r0,%?r31,
248: which is tolerable. */
249: if (GET_CODE (op) == MEM)
250: return (CONSTANT_ADDRESS_P (XEXP (op, 0)));
251:
252: return 0;
253: }
254:
255: /* Return non-zero if this pattern, as a source to a "SET",
256: is known to yield an instruction of unit size. */
257: int
258: single_insn_src_p (op, mode)
259: rtx op;
260: enum machine_mode mode;
261: {
262: switch (GET_CODE (op))
263: {
264: case CONST_INT:
265: /* This is not always a single insn src, technically,
266: but output_delayed_branch knows how to deal with it. */
267: return 1;
268:
269: case SYMBOL_REF:
270: case CONST:
271: /* This is not a single insn src, technically,
272: but output_delayed_branch knows how to deal with it. */
273: return 1;
274:
275: case REG:
276: return 1;
277:
278: case MEM:
279: return 1;
280:
281: /* We never need to negate or complement constants. */
282: case NEG:
283: return (mode != DFmode);
284: case NOT:
285: case ZERO_EXTEND:
286: return 1;
287:
288: case PLUS:
289: case MINUS:
290: /* Detect cases that require multiple instructions. */
291: if (CONSTANT_P (XEXP (op, 1))
292: && !(GET_CODE (XEXP (op, 1)) == CONST_INT
293: && SMALL_INT (XEXP (op, 1))))
294: return 0;
295: case EQ:
296: case NE:
297: case LT:
298: case GT:
299: case LE:
300: case GE:
301: case LTU:
302: case GTU:
303: case LEU:
304: case GEU:
305: /* Not doing floating point, since they probably
306: take longer than the branch slot they might fill. */
307: return (mode != SFmode && mode != DFmode);
308:
309: case AND:
310: if (GET_CODE (XEXP (op, 1)) == NOT)
311: {
312: rtx arg = XEXP (XEXP (op, 1), 0);
313: if (CONSTANT_P (arg)
314: && !(GET_CODE (arg) == CONST_INT
315: && (SMALL_INT (arg)
316: || INTVAL (arg) & 0xffff == 0)))
317: return 0;
318: }
319: case IOR:
320: case XOR:
321: /* Both small and round numbers take one instruction;
322: others take two. */
323: if (CONSTANT_P (XEXP (op, 1))
324: && !(GET_CODE (XEXP (op, 1)) == CONST_INT
325: && (SMALL_INT (XEXP (op, 1))
326: || INTVAL (XEXP (op, 1)) & 0xffff == 0)))
327: return 0;
328:
329: case LSHIFT:
330: case ASHIFT:
331: case ASHIFTRT:
332: case LSHIFTRT:
333: return 1;
334:
335: case SUBREG:
336: if (SUBREG_WORD (op) != 0)
337: return 0;
338: return single_insn_src_p (SUBREG_REG (op), mode);
339:
340: /* Not doing floating point, since they probably
341: take longer than the branch slot they might fill. */
342: case FLOAT_EXTEND:
343: case FLOAT_TRUNCATE:
344: case FLOAT:
345: case FIX:
346: case UNSIGNED_FLOAT:
347: case UNSIGNED_FIX:
348: return 0;
349:
350: default:
351: return 0;
352: }
353: }
354:
355: /* Nonzero only if this *really* is a single insn operand. */
356: int
357: strict_single_insn_op_p (op, mode)
358: rtx op;
359: enum machine_mode mode;
360: {
361: if (mode == VOIDmode)
362: mode = GET_MODE (op);
363:
364: switch (GET_CODE (op))
365: {
366: case CC0:
367: return 1;
368:
369: case CONST_INT:
370: if (SMALL_INT (op))
371: return 1;
372: /* We can put this set insn into delay slot, because this is one
373: insn; `orh'. */
374: if ((INTVAL (op) & 0xffff) == 0)
375: return 1;
376: return 0;
377:
378: case SYMBOL_REF:
379: return 0;
380:
381: case REG:
382: #if 0
383: /* This loses when moving an freg to a general reg. */
384: return HARD_REGNO_NREGS (REGNO (op), mode) == 1;
385: #endif
386: return (mode != DFmode && mode != DImode);
387:
388: case MEM:
389: if (! CONSTANT_ADDRESS_P (XEXP (op, 0)))
390: return (mode != DFmode && mode != DImode);
391: return 0;
392:
393: /* We never need to negate or complement constants. */
394: case NEG:
395: return (mode != DFmode);
396: case NOT:
397: case ZERO_EXTEND:
398: return 1;
399:
400: case PLUS:
401: case MINUS:
402: /* Detect cases that require multiple instructions. */
403: if (CONSTANT_P (XEXP (op, 1))
404: && !(GET_CODE (XEXP (op, 1)) == CONST_INT
405: && SMALL_INT (XEXP (op, 1))))
406: return 0;
407: case EQ:
408: case NE:
409: case LT:
410: case GT:
411: case LE:
412: case GE:
413: case LTU:
414: case GTU:
415: case LEU:
416: case GEU:
417: return 1;
418:
419: case AND:
420: if (GET_CODE (XEXP (op, 1)) == NOT)
421: {
422: rtx arg = XEXP (XEXP (op, 1), 0);
423: if (CONSTANT_P (arg)
424: && !(GET_CODE (arg) == CONST_INT
425: && (SMALL_INT (arg)
426: || INTVAL (arg) & 0xffff == 0)))
427: return 0;
428: }
429: case IOR:
430: case XOR:
431: /* Both small and round numbers take one instruction;
432: others take two. */
433: if (CONSTANT_P (XEXP (op, 1))
434: && !(GET_CODE (XEXP (op, 1)) == CONST_INT
435: && (SMALL_INT (XEXP (op, 1))
436: || INTVAL (XEXP (op, 1)) & 0xffff == 0)))
437: return 0;
438:
439: case LSHIFT:
440: case ASHIFT:
441: case ASHIFTRT:
442: case LSHIFTRT:
443: return 1;
444:
445: case SUBREG:
446: if (SUBREG_WORD (op) != 0)
447: return 0;
448: return strict_single_insn_op_p (SUBREG_REG (op), mode);
449:
450: case SIGN_EXTEND:
451: if (GET_CODE (XEXP (op, 0)) == MEM
452: && ! CONSTANT_ADDRESS_P (XEXP (XEXP (op, 0), 0)))
453: return 1;
454: return 0;
455:
456: /* Not doing floating point, since they probably
457: take longer than the branch slot they might fill. */
458: case FLOAT_EXTEND:
459: case FLOAT_TRUNCATE:
460: case FLOAT:
461: case FIX:
462: case UNSIGNED_FLOAT:
463: case UNSIGNED_FIX:
464: return 0;
465:
466: default:
467: return 0;
468: }
469: }
470:
471: /* Return truth value of whether OP is a relational operator. */
472: int
473: relop (op, mode)
474: rtx op;
475: enum machine_mode mode;
476: {
477: switch (GET_CODE (op))
478: {
479: case EQ:
480: case NE:
481: case GT:
482: case GE:
483: case LT:
484: case LE:
485: case GTU:
486: case GEU:
487: case LTU:
488: case LEU:
489: return 1;
490: }
491: return 0;
492: }
493:
494: /* Return non-zero only if OP is a register of mode MODE,
495: or const0_rtx. */
496: int
497: reg_or_0_operand (op, mode)
498: rtx op;
499: enum machine_mode mode;
500: {
501: return (op == const0_rtx || register_operand (op, mode)
502: || op == CONST0_RTX (mode));
503: }
504:
505: /* Return truth value of whether OP can be used as an operands in a three
506: address add/subtract insn (such as add %o1,7,%l2) of mode MODE. */
507:
508: int
509: arith_operand (op, mode)
510: rtx op;
511: enum machine_mode mode;
512: {
513: return (register_operand (op, mode)
514: || (GET_CODE (op) == CONST_INT && SMALL_INT (op)));
515: }
516:
517: /* Return 1 if OP is a valid first operand for a logical insn of mode MODE. */
518:
519: int
520: logic_operand (op, mode)
521: rtx op;
522: enum machine_mode mode;
523: {
524: return (register_operand (op, mode)
525: || (GET_CODE (op) == CONST_INT && LOGIC_INT (op)));
526: }
527:
528: /* Return 1 if OP is a valid first operand for a shift insn of mode MODE. */
529:
530: int
531: shift_operand (op, mode)
532: rtx op;
533: enum machine_mode mode;
534: {
535: return (register_operand (op, mode)
536: || (GET_CODE (op) == CONST_INT));
537: }
538:
539: /* Return 1 if OP is a valid first operand for either a logical insn
540: or an add insn of mode MODE. */
541:
542: int
543: compare_operand (op, mode)
544: rtx op;
545: enum machine_mode mode;
546: {
547: return (register_operand (op, mode)
548: || (GET_CODE (op) == CONST_INT && SMALL_INT (op) && LOGIC_INT (op)));
549: }
550:
551: /* Return truth value of whether OP can be used as the 5-bit immediate
552: operand of a bte or btne insn. */
553:
554: int
555: bte_operand (op, mode)
556: rtx op;
557: enum machine_mode mode;
558: {
559: return (register_operand (op, mode)
560: || (GET_CODE (op) == CONST_INT
561: && (unsigned) INTVAL (op) < 0x20));
562: }
563:
564: /* Return 1 if OP is an indexed memory reference of mode MODE. */
565:
566: int
567: indexed_operand (op, mode)
568: rtx op;
569: enum machine_mode mode;
570: {
571: return (GET_CODE (op) == MEM && GET_MODE (op) == mode
572: && GET_CODE (XEXP (op, 0)) == PLUS
573: && GET_MODE (XEXP (op, 0)) == SImode
574: && register_operand (XEXP (XEXP (op, 0), 0), SImode)
575: && register_operand (XEXP (XEXP (op, 0), 1), SImode));
576: }
577:
578: /* Return 1 if OP is a suitable source operand for a load insn
579: with mode MODE. */
580:
581: int
582: load_operand (op, mode)
583: rtx op;
584: enum machine_mode mode;
585: {
586: return (memory_operand (op, mode) || indexed_operand (op, mode));
587: }
588:
589: /* Return truth value of whether OP is a integer which fits the
590: range constraining immediate operands in add/subtract insns. */
591:
592: int
593: small_int (op, mode)
594: rtx op;
595: enum machine_mode mode;
596: {
597: return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
598: }
599:
600: /* Return truth value of whether OP is a integer which fits the
601: range constraining immediate operands in logic insns. */
602:
603: int
604: logic_int (op, mode)
605: rtx op;
606: enum machine_mode mode;
607: {
608: return (GET_CODE (op) == CONST_INT && LOGIC_INT (op));
609: }
610:
611: /* Return the best assembler insn template
612: for moving operands[1] into operands[0] as a fullword. */
613:
614: static char *
615: singlemove_string (operands)
616: rtx *operands;
617: {
618: if (GET_CODE (operands[0]) == MEM)
619: {
620: if (GET_CODE (operands[1]) != MEM)
621: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
622: {
623: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
624: && (cc_prev_status.flags & CC_HI_R31_ADJ)
625: && cc_prev_status.mdep == XEXP (operands[0], 0)))
626: {
627: CC_STATUS_INIT;
628: output_asm_insn ("orh %h0,%?r0,%?r31", operands);
629: }
630: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
631: cc_status.mdep = XEXP (operands[0], 0);
632: return "st.l %r1,%L0(%?r31)";
633: }
634: else
635: return "st.l %r1,%0";
636: else
637: abort ();
638: #if 0
639: {
640: rtx xoperands[2];
641:
642: cc_status.flags &= ~CC_F0_IS_0;
643: xoperands[0] = gen_rtx (REG, SFmode, 32);
644: xoperands[1] = operands[1];
645: output_asm_insn (singlemove_string (xoperands), xoperands);
646: xoperands[1] = xoperands[0];
647: xoperands[0] = operands[0];
648: output_asm_insn (singlemove_string (xoperands), xoperands);
649: return "";
650: }
651: #endif
652: }
653: if (GET_CODE (operands[1]) == MEM)
654: {
655: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
656: {
657: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
658: && (cc_prev_status.flags & CC_HI_R31_ADJ)
659: && cc_prev_status.mdep == XEXP (operands[1], 0)))
660: {
661: CC_STATUS_INIT;
662: output_asm_insn ("orh %h1,%?r0,%?r31", operands);
663: }
664: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
665: cc_status.mdep = XEXP (operands[1], 0);
666: return "ld.l %L1(%?r31),%0";
667: }
668: return "ld.l %m1,%0";
669: }
670: if (GET_CODE (operands[1]) == CONST_INT)
671: {
1.1.1.3 ! root 672: if (operands[1] == const0_rtx)
! 673: return "mov %?r0,%0";
1.1 root 674: if((INTVAL (operands[1]) & 0xffff0000) == 0)
675: return "or %L1,%?r0,%0";
1.1.1.3 ! root 676: if((INTVAL (operands[1]) & 0xffff8000) == 0xffff8000)
! 677: return "adds %1,%?r0,%0";
1.1 root 678: if((INTVAL (operands[1]) & 0x0000ffff) == 0)
679: return "orh %H1,%?r0,%0";
680: }
681: return "mov %1,%0";
682: }
683:
684: /* Output assembler code to perform a doubleword move insn
685: with operands OPERANDS. */
686:
687: char *
688: output_move_double (operands)
689: rtx *operands;
690: {
691: enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
692: rtx latehalf[2];
693: rtx addreg0 = 0, addreg1 = 0;
694:
695: /* First classify both operands. */
696:
697: if (REG_P (operands[0]))
698: optype0 = REGOP;
699: else if (offsettable_memref_p (operands[0]))
700: optype0 = OFFSOP;
701: else if (GET_CODE (operands[0]) == MEM)
702: optype0 = MEMOP;
703: else
704: optype0 = RNDOP;
705:
706: if (REG_P (operands[1]))
707: optype1 = REGOP;
708: else if (CONSTANT_P (operands[1]))
709: optype1 = CNSTOP;
710: else if (offsettable_memref_p (operands[1]))
711: optype1 = OFFSOP;
712: else if (GET_CODE (operands[1]) == MEM)
713: optype1 = MEMOP;
714: else
715: optype1 = RNDOP;
716:
717: /* Check for the cases that the operand constraints are not
718: supposed to allow to happen. Abort if we get one,
719: because generating code for these cases is painful. */
720:
721: if (optype0 == RNDOP || optype1 == RNDOP)
722: abort ();
723:
724: /* If an operand is an unoffsettable memory ref, find a register
725: we can increment temporarily to make it refer to the second word. */
726:
727: if (optype0 == MEMOP)
728: addreg0 = find_addr_reg (XEXP (operands[0], 0));
729:
730: if (optype1 == MEMOP)
731: addreg1 = find_addr_reg (XEXP (operands[1], 0));
732:
733: /* ??? Perhaps in some cases move double words
734: if there is a spare pair of floating regs. */
735:
736: /* Ok, we can do one word at a time.
737: Normally we do the low-numbered word first,
738: but if either operand is autodecrementing then we
739: do the high-numbered word first.
740:
741: In either case, set up in LATEHALF the operands to use
742: for the high-numbered word and in some cases alter the
743: operands in OPERANDS to be suitable for the low-numbered word. */
744:
745: if (optype0 == REGOP)
746: latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
747: else if (optype0 == OFFSOP)
748: latehalf[0] = adj_offsettable_operand (operands[0], 4);
749: else
750: latehalf[0] = operands[0];
751:
752: if (optype1 == REGOP)
753: latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
754: else if (optype1 == OFFSOP)
755: latehalf[1] = adj_offsettable_operand (operands[1], 4);
756: else if (optype1 == CNSTOP)
757: {
758: if (GET_CODE (operands[1]) == CONST_DOUBLE)
759: split_double (operands[1], &operands[1], &latehalf[1]);
760: else if (CONSTANT_P (operands[1]))
761: latehalf[1] = const0_rtx;
762: }
763: else
764: latehalf[1] = operands[1];
765:
766: /* If the first move would clobber the source of the second one,
767: do them in the other order.
768:
769: RMS says "This happens only for registers;
770: such overlap can't happen in memory unless the user explicitly
771: sets it up, and that is an undefined circumstance."
772:
773: but it happens on the sparc when loading parameter registers,
774: so I am going to define that circumstance, and make it work
775: as expected. */
776:
777: if (optype0 == REGOP && optype1 == REGOP
778: && REGNO (operands[0]) == REGNO (latehalf[1]))
779: {
780: CC_STATUS_PARTIAL_INIT;
781: /* Make any unoffsettable addresses point at high-numbered word. */
782: if (addreg0)
783: output_asm_insn ("adds 0x4,%0,%0", &addreg0);
784: if (addreg1)
785: output_asm_insn ("adds 0x4,%0,%0", &addreg1);
786:
787: /* Do that word. */
788: output_asm_insn (singlemove_string (latehalf), latehalf);
789:
790: /* Undo the adds we just did. */
791: if (addreg0)
792: output_asm_insn ("adds -0x4,%0,%0", &addreg0);
793: if (addreg1)
794: output_asm_insn ("adds -0x4,%0,%0", &addreg1);
795:
796: /* Do low-numbered word. */
797: return singlemove_string (operands);
798: }
799: else if (optype0 == REGOP && optype1 != REGOP
800: && reg_overlap_mentioned_p (operands[0], operands[1]))
801: {
802: /* Do the late half first. */
803: output_asm_insn (singlemove_string (latehalf), latehalf);
804: /* Then clobber. */
805: return singlemove_string (operands);
806: }
807:
808: /* Normal case: do the two words, low-numbered first. */
809:
810: output_asm_insn (singlemove_string (operands), operands);
811:
812: CC_STATUS_PARTIAL_INIT;
813: /* Make any unoffsettable addresses point at high-numbered word. */
814: if (addreg0)
815: output_asm_insn ("adds 0x4,%0,%0", &addreg0);
816: if (addreg1)
817: output_asm_insn ("adds 0x4,%0,%0", &addreg1);
818:
819: /* Do that word. */
820: output_asm_insn (singlemove_string (latehalf), latehalf);
821:
822: /* Undo the adds we just did. */
823: if (addreg0)
824: output_asm_insn ("adds -0x4,%0,%0", &addreg0);
825: if (addreg1)
826: output_asm_insn ("adds -0x4,%0,%0", &addreg1);
827:
828: return "";
829: }
830:
831: char *
832: output_fp_move_double (operands)
833: rtx *operands;
834: {
835: /* If the source operand is any sort of zero, use f0 instead. */
836:
837: if (operands[1] == CONST0_RTX (GET_MODE (operands[1])))
838: operands[1] = gen_rtx (REG, DFmode, F0_REGNUM);
839:
840: if (FP_REG_P (operands[0]))
841: {
842: if (FP_REG_P (operands[1]))
843: return "fmov.dd %1,%0";
844: if (GET_CODE (operands[1]) == REG)
845: {
846: output_asm_insn ("ixfr %1,%0", operands);
847: operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1);
848: operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1);
849: return "ixfr %1,%0";
850: }
851: if (operands[1] == CONST0_RTX (DFmode))
852: return "fmov.dd f0,%0";
853: if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
854: {
855: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
856: && (cc_prev_status.flags & CC_HI_R31_ADJ)
857: && cc_prev_status.mdep == XEXP (operands[1], 0)))
858: {
859: CC_STATUS_INIT;
860: output_asm_insn ("orh %h1,%?r0,%?r31", operands);
861: }
862: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
863: cc_status.mdep = XEXP (operands[1], 0);
864: return "fld.d %L1(%?r31),%0";
865: }
866: return "fld.d %1,%0";
867: }
868: else if (FP_REG_P (operands[1]))
869: {
870: if (GET_CODE (operands[0]) == REG)
871: {
872: output_asm_insn ("fxfr %1,%0", operands);
873: operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1);
874: operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1);
875: return "fxfr %1,%0";
876: }
877: if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
878: {
879: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
880: && (cc_prev_status.flags & CC_HI_R31_ADJ)
881: && cc_prev_status.mdep == XEXP (operands[0], 0)))
882: {
883: CC_STATUS_INIT;
884: output_asm_insn ("orh %h0,%?r0,%?r31", operands);
885: }
886: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
887: cc_status.mdep = XEXP (operands[0], 0);
888: return "fst.d %1,%L0(%?r31)";
889: }
890: return "fst.d %1,%0";
891: }
892: else
893: abort ();
894: /* NOTREACHED */
895: return NULL;
896: }
897:
898: /* Return a REG that occurs in ADDR with coefficient 1.
899: ADDR can be effectively incremented by incrementing REG. */
900:
901: static rtx
902: find_addr_reg (addr)
903: rtx addr;
904: {
905: while (GET_CODE (addr) == PLUS)
906: {
907: if (GET_CODE (XEXP (addr, 0)) == REG)
908: addr = XEXP (addr, 0);
909: else if (GET_CODE (XEXP (addr, 1)) == REG)
910: addr = XEXP (addr, 1);
911: else if (CONSTANT_P (XEXP (addr, 0)))
912: addr = XEXP (addr, 1);
913: else if (CONSTANT_P (XEXP (addr, 1)))
914: addr = XEXP (addr, 0);
915: else
916: abort ();
917: }
918: if (GET_CODE (addr) == REG)
919: return addr;
920: abort ();
921: /* NOTREACHED */
922: return NULL;
923: }
924:
925: /* Return a template for a load instruction with mode MODE and
926: arguments from the string ARGS.
927:
928: This string is in static storage. */
929:
930: static char *
931: load_opcode (mode, args, reg)
932: enum machine_mode mode;
933: char *args;
934: rtx reg;
935: {
936: static char buf[30];
937: char *opcode;
938:
939: switch (mode)
940: {
941: case QImode:
942: opcode = "ld.b";
943: break;
944:
945: case HImode:
946: opcode = "ld.s";
947: break;
948:
949: case SImode:
950: case SFmode:
951: if (FP_REG_P (reg))
952: opcode = "fld.l";
953: else
954: opcode = "ld.l";
955: break;
956:
957: case DImode:
958: if (!FP_REG_P (reg))
959: abort ();
960: case DFmode:
961: opcode = "fld.d";
962: break;
963:
964: default:
965: abort ();
966: }
967:
968: sprintf (buf, "%s %s", opcode, args);
969: return buf;
970: }
971:
972: /* Return a template for a store instruction with mode MODE and
973: arguments from the string ARGS.
974:
975: This string is in static storage. */
976:
977: static char *
978: store_opcode (mode, args, reg)
979: enum machine_mode mode;
980: char *args;
981: rtx reg;
982: {
983: static char buf[30];
984: char *opcode;
985:
986: switch (mode)
987: {
988: case QImode:
989: opcode = "st.b";
990: break;
991:
992: case HImode:
993: opcode = "st.s";
994: break;
995:
996: case SImode:
997: case SFmode:
998: if (FP_REG_P (reg))
999: opcode = "fst.l";
1000: else
1001: opcode = "st.l";
1002: break;
1003:
1004: case DImode:
1005: if (!FP_REG_P (reg))
1006: abort ();
1007: case DFmode:
1008: opcode = "fst.d";
1009: break;
1010:
1011: default:
1012: abort ();
1013: }
1014:
1015: sprintf (buf, "%s %s", opcode, args);
1016: return buf;
1017: }
1018:
1019: /* Output a store-in-memory whose operands are OPERANDS[0,1].
1020: OPERANDS[0] is a MEM, and OPERANDS[1] is a reg or zero.
1021:
1022: This function returns a template for an insn.
1023: This is in static storage.
1024:
1025: It may also output some insns directly.
1026: It may alter the values of operands[0] and operands[1]. */
1027:
1028: char *
1029: output_store (operands)
1030: rtx *operands;
1031: {
1032: enum machine_mode mode = GET_MODE (operands[0]);
1033: rtx address = XEXP (operands[0], 0);
1034: char *string;
1035:
1036: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1037: cc_status.mdep = address;
1038:
1039: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1040: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1041: && address == cc_prev_status.mdep))
1042: {
1043: CC_STATUS_INIT;
1044: output_asm_insn ("orh %h0,%?r0,%?r31", operands);
1045: cc_prev_status.mdep = address;
1046: }
1047:
1048: /* Store zero in two parts when appropriate. */
1049: if (mode == DFmode && operands[1] == CONST0_RTX (DFmode))
1050: return store_opcode (DFmode, "%r1,%L0(%?r31)", operands[1]);
1051:
1052: /* Code below isn't smart enough to move a doubleword in two parts,
1053: so use output_move_double to do that in the cases that require it. */
1054: if ((mode == DImode || mode == DFmode)
1055: && ! FP_REG_P (operands[1]))
1056: return output_move_double (operands);
1057:
1058: return store_opcode (mode, "%r1,%L0(%?r31)", operands[1]);
1059: }
1060:
1061: /* Output a load-from-memory whose operands are OPERANDS[0,1].
1062: OPERANDS[0] is a reg, and OPERANDS[1] is a mem.
1063:
1064: This function returns a template for an insn.
1065: This is in static storage.
1066:
1067: It may also output some insns directly.
1068: It may alter the values of operands[0] and operands[1]. */
1069:
1070: char *
1071: output_load (operands)
1072: rtx *operands;
1073: {
1074: enum machine_mode mode = GET_MODE (operands[0]);
1075: rtx address = XEXP (operands[1], 0);
1076:
1077: /* We don't bother trying to see if we know %hi(address).
1078: This is because we are doing a load, and if we know the
1079: %hi value, we probably also know that value in memory. */
1080: cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1081: cc_status.mdep = address;
1082:
1083: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1084: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1085: && address == cc_prev_status.mdep
1086: && cc_prev_status.mdep == cc_status.mdep))
1087: {
1088: CC_STATUS_INIT;
1089: output_asm_insn ("orh %h1,%?r0,%?r31", operands);
1090: cc_prev_status.mdep = address;
1091: }
1092:
1093: /* Code below isn't smart enough to move a doubleword in two parts,
1094: so use output_move_double to do that in the cases that require it. */
1095: if ((mode == DImode || mode == DFmode)
1096: && ! FP_REG_P (operands[0]))
1097: return output_move_double (operands);
1098:
1099: return load_opcode (mode, "%L1(%?r31),%0", operands[0]);
1100: }
1101:
1102: #if 0
1103: /* Load the address specified by OPERANDS[3] into the register
1104: specified by OPERANDS[0].
1105:
1106: OPERANDS[3] may be the result of a sum, hence it could either be:
1107:
1108: (1) CONST
1109: (2) REG
1110: (2) REG + CONST_INT
1111: (3) REG + REG + CONST_INT
1112: (4) REG + REG (special case of 3).
1113:
1114: Note that (3) is not a legitimate address.
1115: All cases are handled here. */
1116:
1117: void
1118: output_load_address (operands)
1119: rtx *operands;
1120: {
1121: rtx base, offset;
1122:
1123: if (CONSTANT_P (operands[3]))
1124: {
1125: output_asm_insn ("mov %3,%0", operands);
1126: return;
1127: }
1128:
1129: if (REG_P (operands[3]))
1130: {
1131: if (REGNO (operands[0]) != REGNO (operands[3]))
1132: output_asm_insn ("shl %?r0,%3,%0", operands);
1133: return;
1134: }
1135:
1136: if (GET_CODE (operands[3]) != PLUS)
1137: abort ();
1138:
1139: base = XEXP (operands[3], 0);
1140: offset = XEXP (operands[3], 1);
1141:
1142: if (GET_CODE (base) == CONST_INT)
1143: {
1144: rtx tmp = base;
1145: base = offset;
1146: offset = tmp;
1147: }
1148:
1149: if (GET_CODE (offset) != CONST_INT)
1150: {
1151: /* Operand is (PLUS (REG) (REG)). */
1152: base = operands[3];
1153: offset = const0_rtx;
1154: }
1155:
1156: if (REG_P (base))
1157: {
1158: operands[6] = base;
1159: operands[7] = offset;
1160: CC_STATUS_PARTIAL_INIT;
1161: if (SMALL_INT (offset))
1162: output_asm_insn ("adds %7,%6,%0", operands);
1163: else
1164: output_asm_insn ("mov %7,%0\n\tadds %0,%6,%0", operands);
1165: }
1166: else if (GET_CODE (base) == PLUS)
1167: {
1168: operands[6] = XEXP (base, 0);
1169: operands[7] = XEXP (base, 1);
1170: operands[8] = offset;
1171:
1172: CC_STATUS_PARTIAL_INIT;
1173: if (SMALL_INT (offset))
1174: output_asm_insn ("adds %6,%7,%0\n\tadds %8,%0,%0", operands);
1175: else
1176: output_asm_insn ("mov %8,%0\n\tadds %0,%6,%0\n\tadds %0,%7,%0", operands);
1177: }
1178: else
1179: abort ();
1180: }
1181: #endif
1182:
1183: /* Output code to place a size count SIZE in register REG.
1184: Because block moves are pipelined, we don't include the
1185: first element in the transfer of SIZE to REG.
1186: For this, we subtract ALIGN. (Actually, I think it is not
1187: right to subtract on this machine, so right now we don't.) */
1188:
1189: static void
1190: output_size_for_block_move (size, reg, align)
1191: rtx size, reg, align;
1192: {
1193: rtx xoperands[3];
1194:
1195: xoperands[0] = reg;
1196: xoperands[1] = size;
1197: xoperands[2] = align;
1198:
1199: #if 1
1200: cc_status.flags &= ~ CC_KNOW_HI_R31;
1.1.1.3 ! root 1201: output_asm_insn (singlemove_string (xoperands), xoperands);
1.1 root 1202: #else
1203: if (GET_CODE (size) == REG)
1204: output_asm_insn ("sub %2,%1,%0", xoperands);
1205: else
1206: {
1207: xoperands[1]
1208: = gen_rtx (CONST_INT, VOIDmode, INTVAL (size) - INTVAL (align));
1209: cc_status.flags &= ~ CC_KNOW_HI_R31;
1210: output_asm_insn ("mov %1,%0", xoperands);
1211: }
1212: #endif
1213: }
1214:
1215: /* Emit code to perform a block move.
1216:
1217: OPERANDS[0] is the destination.
1218: OPERANDS[1] is the source.
1219: OPERANDS[2] is the size.
1220: OPERANDS[3] is the known safe alignment.
1221: OPERANDS[4..6] are pseudos we can safely clobber as temps. */
1222:
1223: char *
1224: output_block_move (operands)
1225: rtx *operands;
1226: {
1227: /* A vector for our computed operands. Note that load_output_address
1228: makes use of (and can clobber) up to the 8th element of this vector. */
1229: rtx xoperands[10];
1230: rtx zoperands[10];
1231: static int movstrsi_label = 0;
1232: int i, j;
1233: rtx temp1 = operands[4];
1234: rtx alignrtx = operands[3];
1235: int align = INTVAL (alignrtx);
1236: int chunk_size;
1237:
1238: xoperands[0] = operands[0];
1239: xoperands[1] = operands[1];
1240: xoperands[2] = temp1;
1241:
1242: /* We can't move more than four bytes at a time
1243: because we have only one register to move them through. */
1244: if (align > 4)
1245: {
1246: align = 4;
1247: alignrtx = gen_rtx (CONST_INT, VOIDmode, 4);
1248: }
1249:
1250: /* Recognize special cases of block moves. These occur
1251: when GNU C++ is forced to treat something as BLKmode
1252: to keep it in memory, when its mode could be represented
1253: with something smaller.
1254:
1255: We cannot do this for global variables, since we don't know
1256: what pages they don't cross. Sigh. */
1257: if (GET_CODE (operands[2]) == CONST_INT
1258: && ! CONSTANT_ADDRESS_P (operands[0])
1259: && ! CONSTANT_ADDRESS_P (operands[1]))
1260: {
1261: int size = INTVAL (operands[2]);
1262: rtx op0 = xoperands[0];
1263: rtx op1 = xoperands[1];
1264:
1265: if ((align & 3) == 0 && (size & 3) == 0 && (size >> 2) <= 16)
1266: {
1267: if (memory_address_p (SImode, plus_constant (op0, size))
1268: && memory_address_p (SImode, plus_constant (op1, size)))
1269: {
1270: cc_status.flags &= ~CC_KNOW_HI_R31;
1271: for (i = (size>>2)-1; i >= 0; i--)
1272: {
1273: xoperands[0] = plus_constant (op0, i * 4);
1274: xoperands[1] = plus_constant (op1, i * 4);
1275: output_asm_insn ("ld.l %a1,%?r31\n\tst.l %?r31,%a0",
1276: xoperands);
1277: }
1278: return "";
1279: }
1280: }
1281: else if ((align & 1) == 0 && (size & 1) == 0 && (size >> 1) <= 16)
1282: {
1283: if (memory_address_p (HImode, plus_constant (op0, size))
1284: && memory_address_p (HImode, plus_constant (op1, size)))
1285: {
1286: cc_status.flags &= ~CC_KNOW_HI_R31;
1287: for (i = (size>>1)-1; i >= 0; i--)
1288: {
1289: xoperands[0] = plus_constant (op0, i * 2);
1290: xoperands[1] = plus_constant (op1, i * 2);
1291: output_asm_insn ("ld.s %a1,%?r31\n\tst.s %?r31,%a0",
1292: xoperands);
1293: }
1294: return "";
1295: }
1296: }
1297: else if (size <= 16)
1298: {
1299: if (memory_address_p (QImode, plus_constant (op0, size))
1300: && memory_address_p (QImode, plus_constant (op1, size)))
1301: {
1302: cc_status.flags &= ~CC_KNOW_HI_R31;
1303: for (i = size-1; i >= 0; i--)
1304: {
1305: xoperands[0] = plus_constant (op0, i);
1306: xoperands[1] = plus_constant (op1, i);
1307: output_asm_insn ("ld.b %a1,%?r31\n\tst.b %?r31,%a0",
1308: xoperands);
1309: }
1310: return "";
1311: }
1312: }
1313: }
1314:
1315: /* Since we clobber untold things, nix the condition codes. */
1316: CC_STATUS_INIT;
1317:
1318: /* This is the size of the transfer.
1319: Either use the register which already contains the size,
1320: or use a free register (used by no operands). */
1321: output_size_for_block_move (operands[2], operands[4], alignrtx);
1322:
1323: #if 0
1324: /* Also emit code to decrement the size value by ALIGN. */
1325: zoperands[0] = operands[0];
1326: zoperands[3] = plus_constant (operands[0], align);
1327: output_load_address (zoperands);
1328: #endif
1329:
1330: /* Generate number for unique label. */
1331:
1332: xoperands[3] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++);
1333:
1334: /* Calculate the size of the chunks we will be trying to move first. */
1335:
1336: #if 0
1337: if ((align & 3) == 0)
1338: chunk_size = 4;
1339: else if ((align & 1) == 0)
1340: chunk_size = 2;
1341: else
1342: #endif
1343: chunk_size = 1;
1344:
1345: /* Copy the increment (negative) to a register for bla insn. */
1346:
1347: xoperands[4] = gen_rtx (CONST_INT, VOIDmode, - chunk_size);
1348: xoperands[5] = operands[5];
1349: output_asm_insn ("adds %4,%?r0,%5", xoperands);
1350:
1351: /* Predecrement the loop counter. This happens again also in the `bla'
1.1.1.2 root 1352: instruction which precedes the loop, but we need to have it done
1353: two times before we enter the loop because of the bizarre semantics
1.1 root 1354: of the bla instruction. */
1355:
1356: output_asm_insn ("adds %5,%2,%2", xoperands);
1357:
1358: /* Check for the case where the original count was less than or equal to
1359: zero. Avoid going through the loop at all if the original count was
1360: indeed less than or equal to zero. Note that we treat the count as
1361: if it were a signed 32-bit quantity here, rather than an unsigned one,
1362: even though we really shouldn't. We have to do this because of the
1363: semantics of the `ble' instruction, which assume that the count is
1364: a signed 32-bit value. Anyway, in practice it won't matter because
1365: nobody is going to try to do a memcpy() of more than half of the
1366: entire address space (i.e. 2 gigabytes) anyway. */
1367:
1368: output_asm_insn ("bc .Le%3", xoperands);
1369:
1370: /* Make available a register which is a temporary. */
1371:
1372: xoperands[6] = operands[6];
1373:
1374: /* Now the actual loop.
1375: In xoperands, elements 1 and 0 are the input and output vectors.
1376: Element 2 is the loop index. Element 5 is the increment. */
1377:
1378: output_asm_insn ("subs %1,%5,%1", xoperands);
1379: output_asm_insn ("bla %5,%2,.Lm%3", xoperands);
1380: output_asm_insn ("adds %0,%2,%6", xoperands);
1381: output_asm_insn ("\n.Lm%3:", xoperands); /* Label for bla above. */
1382: output_asm_insn ("\n.Ls%3:", xoperands); /* Loop start label. */
1383: output_asm_insn ("adds %5,%6,%6", xoperands);
1384:
1385: /* NOTE: The code here which is supposed to handle the cases where the
1386: sources and destinations are known to start on a 4 or 2 byte boundary
1387: are currently broken. They fail to do anything about the overflow
1388: bytes which might still need to be copied even after we have copied
1389: some number of words or halfwords. Thus, for now we use the lowest
1390: common denominator, i.e. the code which just copies some number of
1391: totally unaligned individual bytes. (See the calculation of
1392: chunk_size above. */
1393:
1394: if (chunk_size == 4)
1395: {
1396: output_asm_insn ("ld.l %2(%1),%?r31", xoperands);
1397: output_asm_insn ("bla %5,%2,.Ls%3", xoperands);
1398: output_asm_insn ("st.l %?r31,8(%6)", xoperands);
1399: }
1400: else if (chunk_size == 2)
1401: {
1402: output_asm_insn ("ld.s %2(%1),%?r31", xoperands);
1403: output_asm_insn ("bla %5,%2,.Ls%3", xoperands);
1404: output_asm_insn ("st.s %?r31,4(%6)", xoperands);
1405: }
1406: else /* chunk_size == 1 */
1407: {
1408: output_asm_insn ("ld.b %2(%1),%?r31", xoperands);
1409: output_asm_insn ("bla %5,%2,.Ls%3", xoperands);
1410: output_asm_insn ("st.b %?r31,2(%6)", xoperands);
1411: }
1412: output_asm_insn ("\n.Le%3:", xoperands); /* Here if count <= 0. */
1413:
1414: return "";
1415: }
1416:
1417: /* Output a delayed branch insn with the delay insn in its
1418: branch slot. The delayed branch insn template is in TEMPLATE,
1419: with operands OPERANDS. The insn in its delay slot is INSN.
1420:
1421: As a special case, since we know that all memory transfers are via
1422: ld/st insns, if we see a (MEM (SYMBOL_REF ...)) we divide the memory
1423: reference around the branch as
1424:
1425: orh ha%x,%?r0,%?r31
1426: b ...
1427: ld/st l%x(%?r31),...
1428:
1429: As another special case, we handle loading (SYMBOL_REF ...) and
1430: other large constants around branches as well:
1431:
1432: orh h%x,%?r0,%0
1433: b ...
1434: or l%x,%0,%1
1435:
1436: */
1437:
1438: char *
1439: output_delayed_branch (template, operands, insn)
1440: char *template;
1441: rtx *operands;
1442: rtx insn;
1443: {
1444: rtx src = XVECEXP (PATTERN (insn), 0, 1);
1445: rtx dest = XVECEXP (PATTERN (insn), 0, 0);
1446:
1447: /* See if we are doing some branch together with setting some register
1448: to some 32-bit value which does (or may) have some of the high-order
1449: 16 bits set. If so, we need to set the register in two stages. One
1450: stage must be done before the branch, and the other one can be done
1451: in the delay slot. */
1452:
1453: if ( (GET_CODE (src) == CONST_INT
1454: && ((unsigned) INTVAL (src) & (unsigned) 0xffff0000) != (unsigned) 0)
1455: || (GET_CODE (src) == SYMBOL_REF)
1456: || (GET_CODE (src) == LABEL_REF)
1457: || (GET_CODE (src) == CONST))
1458: {
1459: rtx xoperands[2];
1460: xoperands[0] = dest;
1461: xoperands[1] = src;
1462:
1463: CC_STATUS_PARTIAL_INIT;
1464: /* Output the `orh' insn. */
1465: output_asm_insn ("orh %H1,%?r0,%0", xoperands);
1466:
1467: /* Output the branch instruction next. */
1468: output_asm_insn (template, operands);
1469:
1470: /* Now output the `or' insn. */
1471: output_asm_insn ("or %L1,%0,%0", xoperands);
1472: }
1473: else if ((GET_CODE (src) == MEM
1474: && CONSTANT_ADDRESS_P (XEXP (src, 0)))
1475: || (GET_CODE (dest) == MEM
1476: && CONSTANT_ADDRESS_P (XEXP (dest, 0))))
1477: {
1478: rtx xoperands[2];
1479: char *split_template;
1480: xoperands[0] = dest;
1481: xoperands[1] = src;
1482:
1483: /* Output the `orh' insn. */
1484: if (GET_CODE (src) == MEM)
1485: {
1486: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1487: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1488: && cc_prev_status.mdep == XEXP (operands[1], 0)))
1489: {
1490: CC_STATUS_INIT;
1491: output_asm_insn ("orh %h1,%?r0,%?r31", xoperands);
1492: }
1493: split_template = load_opcode (GET_MODE (dest),
1494: "%L1(%?r31),%0", dest);
1495: }
1496: else
1497: {
1498: if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1499: && (cc_prev_status.flags & CC_HI_R31_ADJ)
1500: && cc_prev_status.mdep == XEXP (operands[0], 0)))
1501: {
1502: CC_STATUS_INIT;
1503: output_asm_insn ("orh %h0,%?r0,%?r31", xoperands);
1504: }
1505: split_template = store_opcode (GET_MODE (dest),
1506: "%r1,%L0(%?r31)", src);
1507: }
1508:
1509: /* Output the branch instruction next. */
1510: output_asm_insn (template, operands);
1511:
1512: /* Now output the load or store.
1513: No need to do a CC_STATUS_INIT, because we are branching anyway. */
1514: output_asm_insn (split_template, xoperands);
1515: }
1516: else
1517: {
1518: int insn_code_number;
1519: rtx pat = gen_rtx (SET, VOIDmode, dest, src);
1520: rtx delay_insn = gen_rtx (INSN, VOIDmode, 0, 0, 0, pat, -1, 0, 0);
1521: int i;
1522:
1523: /* Output the branch instruction first. */
1524: output_asm_insn (template, operands);
1525:
1526: /* Now recognize the insn which we put in its delay slot.
1.1.1.2 root 1527: We must do this after outputting the branch insn,
1.1 root 1528: since operands may just be a pointer to `recog_operand'. */
1529: INSN_CODE (delay_insn) = insn_code_number = recog (pat, delay_insn);
1530: if (insn_code_number == -1)
1531: abort ();
1532:
1533: for (i = 0; i < insn_n_operands[insn_code_number]; i++)
1534: {
1535: if (GET_CODE (recog_operand[i]) == SUBREG)
1536: recog_operand[i] = alter_subreg (recog_operand[i]);
1537: }
1538:
1539: insn_extract (delay_insn);
1540: if (! constrain_operands (insn_code_number, 1))
1541: fatal_insn_not_found (delay_insn);
1542:
1543: template = insn_template[insn_code_number];
1544: if (template == 0)
1545: template = (*insn_outfun[insn_code_number]) (recog_operand, delay_insn);
1546: output_asm_insn (template, recog_operand);
1547: }
1548: CC_STATUS_INIT;
1549: return "";
1550: }
1551:
1552: /* Output a newly constructed insn DELAY_INSN. */
1553: char *
1554: output_delay_insn (delay_insn)
1555: rtx delay_insn;
1556: {
1557: char *template;
1558: int insn_code_number;
1559: int i;
1560:
1561: /* Now recognize the insn which we put in its delay slot.
1.1.1.2 root 1562: We must do this after outputting the branch insn,
1.1 root 1563: since operands may just be a pointer to `recog_operand'. */
1564: insn_code_number = recog_memoized (delay_insn);
1565: if (insn_code_number == -1)
1566: abort ();
1567:
1568: /* Extract the operands of this delay insn. */
1569: INSN_CODE (delay_insn) = insn_code_number;
1570: insn_extract (delay_insn);
1571:
1.1.1.2 root 1572: /* It is possible that this insn has not been properly scanned by final
1.1 root 1573: yet. If this insn's operands don't appear in the peephole's
1574: actual operands, then they won't be fixed up by final, so we
1575: make sure they get fixed up here. -- This is a kludge. */
1576: for (i = 0; i < insn_n_operands[insn_code_number]; i++)
1577: {
1578: if (GET_CODE (recog_operand[i]) == SUBREG)
1579: recog_operand[i] = alter_subreg (recog_operand[i]);
1580: }
1581:
1582: #ifdef REGISTER_CONSTRAINTS
1583: if (! constrain_operands (insn_code_number))
1584: abort ();
1585: #endif
1586:
1587: cc_prev_status = cc_status;
1588:
1589: /* Update `cc_status' for this instruction.
1590: The instruction's output routine may change it further.
1591: If the output routine for a jump insn needs to depend
1592: on the cc status, it should look at cc_prev_status. */
1593:
1594: NOTICE_UPDATE_CC (PATTERN (delay_insn), delay_insn);
1595:
1596: /* Now get the template for what this insn would
1597: have been, without the branch. */
1598:
1599: template = insn_template[insn_code_number];
1600: if (template == 0)
1601: template = (*insn_outfun[insn_code_number]) (recog_operand, delay_insn);
1602: output_asm_insn (template, recog_operand);
1603: return "";
1604: }
1605:
1606: /* Special routine to convert an SFmode value represented as a
1607: CONST_DOUBLE into its equivalent unsigned long bit pattern.
1608: We convert the value from a double precision floating-point
1609: value to single precision first, and thence to a bit-wise
1610: equivalent unsigned long value. This routine is used when
1611: generating an immediate move of an SFmode value directly
1612: into a general register because the svr4 assembler doesn't
1613: grok floating literals in instruction operand contexts. */
1614:
1615: unsigned long
1616: sfmode_constant_to_ulong (x)
1617: rtx x;
1618: {
1.1.1.2 root 1619: REAL_VALUE_TYPE d;
1.1 root 1620: union { float f; unsigned long i; } u2;
1621:
1622: if (GET_CODE (x) != CONST_DOUBLE || GET_MODE (x) != SFmode)
1623: abort ();
1624:
1.1.1.2 root 1625: #if TARGET_FLOAT_FORMAT != HOST_FLOAT_FORMAT
1.1.1.3 ! root 1626: error IEEE emulation needed
1.1 root 1627: #endif
1.1.1.2 root 1628: REAL_VALUE_FROM_CONST_DOUBLE (d, x);
1629: u2.f = d;
1.1 root 1630: return u2.i;
1631: }
1632:
1633: /* This function generates the assembly code for function entry.
1634: The macro FUNCTION_PROLOGUE in i860.h is defined to call this function.
1635:
1636: ASM_FILE is a stdio stream to output the code to.
1637: SIZE is an int: how many units of temporary storage to allocate.
1638:
1639: Refer to the array `regs_ever_live' to determine which registers
1640: to save; `regs_ever_live[I]' is nonzero if register number I
1641: is ever used in the function. This macro is responsible for
1642: knowing which registers should not be saved even if used.
1643:
1644: NOTE: `frame_lower_bytes' is the count of bytes which will lie
1645: between the new `fp' value and the new `sp' value after the
1646: prologue is done. `frame_upper_bytes' is the count of bytes
1647: that will lie between the new `fp' and the *old* `sp' value
1648: after the new `fp' is setup (in the prologue). The upper
1649: part of each frame always includes at least 2 words (8 bytes)
1650: to hold the saved frame pointer and the saved return address.
1651:
1652: The svr4 ABI for the i860 now requires that the values of the
1653: stack pointer and frame pointer registers be kept aligned to
1654: 16-byte boundaries at all times. We obey that restriction here.
1655:
1656: The svr4 ABI for the i860 is entirely vague when it comes to specifying
1657: exactly where the "preserved" registers should be saved. The native
1658: svr4 C compiler I now have doesn't help to clarify the requirements
1659: very much because it is plainly out-of-date and non-ABI-compliant
1660: (in at least one important way, i.e. how it generates function
1661: epilogues).
1662:
1663: The native svr4 C compiler saves the "preserved" registers (i.e.
1664: r4-r15 and f2-f7) in the lower part of a frame (i.e. at negative
1665: offsets from the frame pointer).
1666:
1667: Previous versions of GCC also saved the "preserved" registers in the
1.1.1.2 root 1668: "negative" part of the frame, but they saved them using positive
1.1 root 1669: offsets from the (adjusted) stack pointer (after it had been adjusted
1670: to allocate space for the new frame). That's just plain wrong
1671: because if the current function calls alloca(), the stack pointer
1672: will get moved, and it will be impossible to restore the registers
1673: properly again after that.
1674:
1675: Both compilers handled parameter registers (i.e. r16-r27 and f8-f15)
1676: by copying their values either into various "preserved" registers or
1677: into stack slots in the lower part of the current frame (as seemed
1678: appropriate, depending upon subsequent usage of these values).
1679:
1680: Here we want to save the preserved registers at some offset from the
1681: frame pointer register so as to avoid any possible problems arising
1682: from calls to alloca(). We can either save them at small positive
1683: offsets from the frame pointer, or at small negative offsets from
1684: the frame pointer. If we save them at small negative offsets from
1685: the frame pointer (i.e. in the lower part of the frame) then we
1686: must tell the rest of GCC (via STARTING_FRAME_OFFSET) exactly how
1687: many bytes of space we plan to use in the lower part of the frame
1688: for this purpose. Since other parts of the compiler reference the
1689: value of STARTING_FRAME_OFFSET long before final() calls this function,
1690: we would have to go ahead and assume the worst-case storage requirements
1691: for saving all of the "preserved" registers (and use that number, i.e.
1692: `80', to define STARTING_FRAME_OFFSET) if we wanted to save them in
1693: the lower part of the frame. That could potentially be very wasteful,
1694: and that wastefulness could really hamper people compiling for embedded
1695: i860 targets with very tight limits on stack space. Thus, we choose
1696: here to save the preserved registers in the upper part of the
1697: frame, so that we can decide at the very last minute how much (or how
1698: little) space we must allocate for this purpose.
1699:
1700: To satisfy the needs of the svr4 ABI "tdesc" scheme, preserved
1701: registers must always be saved so that the saved values of registers
1702: with higher numbers are at higher addresses. We obey that restriction
1703: here.
1704:
1705: There are two somewhat different ways that you can generate prologues
1706: here... i.e. pedantically ABI-compliant, and the "other" way. The
1.1.1.2 root 1707: "other" way is more consistent with what is currently generated by the
1.1 root 1708: "native" svr4 C compiler for the i860. That's important if you want
1709: to use the current (as of 8/91) incarnation of svr4 SDB for the i860.
1710: The SVR4 SDB for the i860 insists on having function prologues be
1711: non-ABI-compliant!
1712:
1713: To get fully ABI-compliant prologues, define I860_STRICT_ABI_PROLOGUES
1714: in the i860svr4.h file. (By default this is *not* defined).
1715:
1716: The differences between the ABI-compliant and non-ABI-compliant prologues
1717: are that (a) the ABI version seems to require the use of *signed*
1718: (rather than unsigned) adds and subtracts, and (b) the ordering of
1719: the various steps (e.g. saving preserved registers, saving the
1720: return address, setting up the new frame pointer value) is different.
1721:
1722: For strict ABI compliance, it seems to be the case that the very last
1723: thing that is supposed to happen in the prologue is getting the frame
1724: pointer set to its new value (but only after everything else has
1725: already been properly setup). We do that here, but only if the symbol
1726: I860_STRICT_ABI_PROLOGUES is defined.
1727: */
1728:
1729: #ifndef STACK_ALIGNMENT
1730: #define STACK_ALIGNMENT 16
1731: #endif
1732:
1733: extern char call_used_regs[];
1734: extern int leaf_function_p ();
1735:
1736: char *current_function_original_name;
1737:
1738: static int must_preserve_r1;
1739: static unsigned must_preserve_bytes;
1740:
1741: void
1742: function_prologue (asm_file, local_bytes)
1743: register FILE *asm_file;
1744: register unsigned local_bytes;
1745: {
1746: register unsigned frame_lower_bytes;
1747: register unsigned frame_upper_bytes;
1748: register unsigned total_fsize;
1749: register unsigned preserved_reg_bytes = 0;
1750: register unsigned i;
1751: register unsigned preserved_so_far = 0;
1752:
1753: must_preserve_r1 = (optimize < 2 || ! leaf_function_p ());
1754: must_preserve_bytes = 4 + (must_preserve_r1 ? 4 : 0);
1755:
1756: /* Count registers that need preserving. Ignore r0. It never needs
1757: preserving. */
1758:
1759: for (i = 1; i < FIRST_PSEUDO_REGISTER; i++)
1760: {
1761: if (regs_ever_live[i] && ! call_used_regs[i])
1762: preserved_reg_bytes += 4;
1763: }
1764:
1765: /* Round-up the frame_lower_bytes so that it's a multiple of 16. */
1766:
1767: frame_lower_bytes = (local_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT;
1768:
1769: /* The upper part of each frame will contain the saved fp,
1770: the saved r1, and stack slots for all of the other "preserved"
1771: registers that we find we will need to save & restore. */
1772:
1773: frame_upper_bytes = must_preserve_bytes + preserved_reg_bytes;
1774:
1775: /* Round-up the frame_upper_bytes so that it's a multiple of 16. */
1776:
1777: frame_upper_bytes
1778: = (frame_upper_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT;
1779:
1780: total_fsize = frame_upper_bytes + frame_lower_bytes;
1781:
1782: #ifndef I860_STRICT_ABI_PROLOGUES
1783:
1784: /* There are two kinds of function prologues.
1785: You use the "small" version if the total frame size is
1786: small enough so that it can fit into an immediate 16-bit
1787: value in one instruction. Otherwise, you use the "large"
1788: version of the function prologue. */
1789:
1790: if (total_fsize > 0x7fff)
1791: {
1792: /* Adjust the stack pointer. The ABI sez to do this using `adds',
1793: but the native C compiler on svr4 uses `addu'. */
1794:
1795: fprintf (asm_file, "\taddu -%d,%ssp,%ssp\n",
1796: frame_upper_bytes, i860_reg_prefix, i860_reg_prefix);
1797:
1798: /* Save the old frame pointer. */
1799:
1800: fprintf (asm_file, "\tst.l %sfp,0(%ssp)\n",
1801: i860_reg_prefix, i860_reg_prefix);
1802:
1803: /* Setup the new frame pointer. The ABI sez to do this after
1804: preserving registers (using adds), but that's not what the
1805: native C compiler on svr4 does. */
1806:
1807: fprintf (asm_file, "\taddu 0,%ssp,%sfp\n",
1808: i860_reg_prefix, i860_reg_prefix);
1809:
1810: /* Get the value of frame_lower_bytes into r31. */
1811:
1812: fprintf (asm_file, "\torh %d,%sr0,%sr31\n",
1813: frame_lower_bytes >> 16, i860_reg_prefix, i860_reg_prefix);
1814: fprintf (asm_file, "\tor %d,%sr31,%sr31\n",
1815: frame_lower_bytes & 0xffff, i860_reg_prefix, i860_reg_prefix);
1816:
1817: /* Now re-adjust the stack pointer using the value in r31.
1818: The ABI sez to do this with `subs' but SDB may prefer `subu'. */
1819:
1820: fprintf (asm_file, "\tsubu %ssp,%sr31,%ssp\n",
1821: i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);
1822:
1823: /* Preserve registers. The ABI sez to do this before setting
1824: up the new frame pointer, but that's not what the native
1825: C compiler on svr4 does. */
1826:
1827: for (i = 1; i < 32; i++)
1828: if (regs_ever_live[i] && ! call_used_regs[i])
1829: fprintf (asm_file, "\tst.l %s%s,%d(%sfp)\n",
1830: i860_reg_prefix, reg_names[i],
1831: must_preserve_bytes + (4 * preserved_so_far++),
1832: i860_reg_prefix);
1833:
1834: for (i = 32; i < 64; i++)
1835: if (regs_ever_live[i] && ! call_used_regs[i])
1836: fprintf (asm_file, "\tfst.l %s%s,%d(%sfp)\n",
1837: i860_reg_prefix, reg_names[i],
1838: must_preserve_bytes + (4 * preserved_so_far++),
1839: i860_reg_prefix);
1840:
1841: /* Save the return address. */
1842:
1843: if (must_preserve_r1)
1844: fprintf (asm_file, "\tst.l %sr1,4(%sfp)\n",
1845: i860_reg_prefix, i860_reg_prefix);
1846: }
1847: else
1848: {
1849: /* Adjust the stack pointer. The ABI sez to do this using `adds',
1850: but the native C compiler on svr4 uses `addu'. */
1851:
1852: fprintf (asm_file, "\taddu -%d,%ssp,%ssp\n",
1853: total_fsize, i860_reg_prefix, i860_reg_prefix);
1854:
1855: /* Save the old frame pointer. */
1856:
1857: fprintf (asm_file, "\tst.l %sfp,%d(%ssp)\n",
1858: i860_reg_prefix, frame_lower_bytes, i860_reg_prefix);
1859:
1860: /* Setup the new frame pointer. The ABI sez to do this after
1861: preserving registers and after saving the return address,
1862: (and its saz to do this using adds), but that's not what the
1863: native C compiler on svr4 does. */
1864:
1865: fprintf (asm_file, "\taddu %d,%ssp,%sfp\n",
1866: frame_lower_bytes, i860_reg_prefix, i860_reg_prefix);
1867:
1868: /* Preserve registers. The ABI sez to do this before setting
1869: up the new frame pointer, but that's not what the native
1870: compiler on svr4 does. */
1871:
1872: for (i = 1; i < 32; i++)
1873: if (regs_ever_live[i] && ! call_used_regs[i])
1874: fprintf (asm_file, "\tst.l %s%s,%d(%sfp)\n",
1875: i860_reg_prefix, reg_names[i],
1876: must_preserve_bytes + (4 * preserved_so_far++),
1877: i860_reg_prefix);
1878:
1879: for (i = 32; i < 64; i++)
1880: if (regs_ever_live[i] && ! call_used_regs[i])
1881: fprintf (asm_file, "\tfst.l %s%s,%d(%sfp)\n",
1882: i860_reg_prefix, reg_names[i],
1883: must_preserve_bytes + (4 * preserved_so_far++),
1884: i860_reg_prefix);
1885:
1886: /* Save the return address. The ABI sez to do this earlier,
1887: and also via an offset from %sp, but the native C compiler
1888: on svr4 does it later (i.e. now) and uses an offset from
1889: %fp. */
1890:
1891: if (must_preserve_r1)
1892: fprintf (asm_file, "\tst.l %sr1,4(%sfp)\n",
1893: i860_reg_prefix, i860_reg_prefix);
1894: }
1895:
1896: #else /* defined(I860_STRICT_ABI_PROLOGUES) */
1897:
1898: /* There are two kinds of function prologues.
1899: You use the "small" version if the total frame size is
1900: small enough so that it can fit into an immediate 16-bit
1901: value in one instruction. Otherwise, you use the "large"
1902: version of the function prologue. */
1903:
1904: if (total_fsize > 0x7fff)
1905: {
1906: /* Adjust the stack pointer (thereby allocating a new frame). */
1907:
1908: fprintf (asm_file, "\tadds -%d,%ssp,%ssp\n",
1909: frame_upper_bytes, i860_reg_prefix, i860_reg_prefix);
1910:
1911: /* Save the caller's frame pointer. */
1912:
1913: fprintf (asm_file, "\tst.l %sfp,0(%ssp)\n",
1914: i860_reg_prefix, i860_reg_prefix);
1915:
1916: /* Save return address. */
1917:
1918: if (must_preserve_r1)
1919: fprintf (asm_file, "\tst.l %sr1,4(%ssp)\n",
1920: i860_reg_prefix, i860_reg_prefix);
1921:
1922: /* Get the value of frame_lower_bytes into r31 for later use. */
1923:
1924: fprintf (asm_file, "\torh %d,%sr0,%sr31\n",
1925: frame_lower_bytes >> 16, i860_reg_prefix, i860_reg_prefix);
1926: fprintf (asm_file, "\tor %d,%sr31,%sr31\n",
1927: frame_lower_bytes & 0xffff, i860_reg_prefix, i860_reg_prefix);
1928:
1929: /* Now re-adjust the stack pointer using the value in r31. */
1930:
1931: fprintf (asm_file, "\tsubs %ssp,%sr31,%ssp\n",
1932: i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);
1933:
1934: /* Pre-compute value to be used as the new frame pointer. */
1935:
1936: fprintf (asm_file, "\tadds %ssp,%sr31,%sr31\n",
1937: i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);
1938:
1939: /* Preserve registers. */
1940:
1941: for (i = 1; i < 32; i++)
1942: if (regs_ever_live[i] && ! call_used_regs[i])
1943: fprintf (asm_file, "\tst.l %s%s,%d(%sr31)\n",
1944: i860_reg_prefix, reg_names[i],
1945: must_preserve_bytes + (4 * preserved_so_far++),
1946: i860_reg_prefix);
1947:
1948: for (i = 32; i < 64; i++)
1949: if (regs_ever_live[i] && ! call_used_regs[i])
1950: fprintf (asm_file, "\tfst.l %s%s,%d(%sr31)\n",
1951: i860_reg_prefix, reg_names[i],
1952: must_preserve_bytes + (4 * preserved_so_far++),
1953: i860_reg_prefix);
1954:
1955: /* Actually set the new value of the frame pointer. */
1956:
1957: fprintf (asm_file, "\tmov %sr31,%sfp\n",
1958: i860_reg_prefix, i860_reg_prefix);
1959: }
1960: else
1961: {
1962: /* Adjust the stack pointer. */
1963:
1964: fprintf (asm_file, "\tadds -%d,%ssp,%ssp\n",
1965: total_fsize, i860_reg_prefix, i860_reg_prefix);
1966:
1967: /* Save the caller's frame pointer. */
1968:
1969: fprintf (asm_file, "\tst.l %sfp,%d(%ssp)\n",
1970: i860_reg_prefix, frame_lower_bytes, i860_reg_prefix);
1971:
1972: /* Save the return address. */
1973:
1974: if (must_preserve_r1)
1975: fprintf (asm_file, "\tst.l %sr1,%d(%ssp)\n",
1976: i860_reg_prefix, frame_lower_bytes + 4, i860_reg_prefix);
1977:
1978: /* Preserve registers. */
1979:
1980: for (i = 1; i < 32; i++)
1981: if (regs_ever_live[i] && ! call_used_regs[i])
1982: fprintf (asm_file, "\tst.l %s%s,%d(%ssp)\n",
1983: i860_reg_prefix, reg_names[i],
1984: frame_lower_bytes + must_preserve_bytes + (4 * preserved_so_far++),
1985: i860_reg_prefix);
1986:
1987: for (i = 32; i < 64; i++)
1988: if (regs_ever_live[i] && ! call_used_regs[i])
1989: fprintf (asm_file, "\tfst.l %s%s,%d(%ssp)\n",
1990: i860_reg_prefix, reg_names[i],
1991: frame_lower_bytes + must_preserve_bytes + (4 * preserved_so_far++),
1992: i860_reg_prefix);
1993:
1994: /* Setup the new frame pointer. */
1995:
1996: fprintf (asm_file, "\tadds %d,%ssp,%sfp\n",
1997: frame_lower_bytes, i860_reg_prefix, i860_reg_prefix);
1998: }
1999: #endif /* defined(I860_STRICT_ABI_PROLOGUES) */
2000:
2001: #ifdef ASM_OUTPUT_PROLOGUE_SUFFIX
2002: ASM_OUTPUT_PROLOGUE_SUFFIX (asm_file);
2003: #endif /* defined(ASM_OUTPUT_PROLOGUE_SUFFIX) */
2004: }
2005:
2006: /* This function generates the assembly code for function exit.
2007: The macro FUNCTION_EPILOGUE in i860.h is defined to call this function.
2008:
2009: ASM_FILE is a stdio stream to output the code to.
2010: SIZE is an int: how many units of temporary storage to allocate.
2011:
2012: The function epilogue should not depend on the current stack pointer!
2013: It should use the frame pointer only. This is mandatory because
2014: of alloca; we also take advantage of it to omit stack adjustments
2015: before returning.
2016:
2017: Note that when we go to restore the preserved register values we must
2018: not try to address their slots by using offsets from the stack pointer.
2019: That's because the stack pointer may have been moved during the function
2020: execution due to a call to alloca(). Rather, we must restore all
2021: preserved registers via offsets from the frame pointer value.
2022:
2023: Note also that when the current frame is being "popped" (by adjusting
2024: the value of the stack pointer) on function exit, we must (for the
2025: sake of alloca) set the new value of the stack pointer based upon
2026: the current value of the frame pointer. We can't just add what we
2027: believe to be the (static) frame size to the stack pointer because
2028: if we did that, and alloca() had been called during this function,
2029: we would end up returning *without* having fully deallocated all of
2030: the space grabbed by alloca. If that happened, and a function
2031: containing one or more alloca() calls was called over and over again,
2032: then the stack would grow without limit!
2033:
2034: Finally note that the epilogues generated here are completely ABI
2035: compliant. They go out of their way to insure that the value in
2036: the frame pointer register is never less than the value in the stack
2037: pointer register. It's not clear why this relationship needs to be
2038: maintained at all times, but maintaining it only costs one extra
2039: instruction, so what the hell.
2040: */
2041:
1.1.1.3 ! root 2042: /* This corresponds to a version 4 TDESC structure. Lower numbered
! 2043: versions successively omit the last word of the structure. We
! 2044: don't try to handle version 5 here. */
! 2045:
! 2046: typedef struct TDESC_flags {
! 2047: int version:4;
! 2048: int reg_packing:1;
! 2049: int callable_block:1;
! 2050: int reserved:4;
! 2051: int fregs:6; /* fp regs 2-7 */
! 2052: int iregs:16; /* regs 0-15 */
! 2053: } TDESC_flags;
! 2054:
! 2055: typedef struct TDESC {
! 2056: TDESC_flags flags;
! 2057: int integer_reg_offset; /* same as must_preserve_bytes */
! 2058: int floating_point_reg_offset;
! 2059: unsigned int positive_frame_size; /* same as frame_upper_bytes */
! 2060: unsigned int negative_frame_size; /* same as frame_lower_bytes */
! 2061: } TDESC;
! 2062:
1.1 root 2063: void
2064: function_epilogue (asm_file, local_bytes)
2065: register FILE *asm_file;
2066: register unsigned local_bytes;
2067: {
2068: register unsigned frame_upper_bytes;
1.1.1.3 ! root 2069: register unsigned frame_lower_bytes;
1.1 root 2070: register unsigned preserved_reg_bytes = 0;
2071: register unsigned i;
2072: register unsigned restored_so_far = 0;
1.1.1.3 ! root 2073: register unsigned int_restored;
! 2074: register unsigned mask;
! 2075: unsigned intflags=0;
! 2076: register TDESC_flags *flags = (TDESC_flags *) &intflags;
! 2077:
! 2078: flags->version = 4;
! 2079: flags->reg_packing = 1;
! 2080: flags->iregs = 8; /* old fp always gets saved */
! 2081:
! 2082: /* Round-up the frame_lower_bytes so that it's a multiple of 16. */
! 2083:
! 2084: frame_lower_bytes = (local_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT;
1.1 root 2085:
2086: /* Count the number of registers that were preserved in the prologue.
2087: Ignore r0. It is never preserved. */
2088:
2089: for (i = 1; i < FIRST_PSEUDO_REGISTER; i++)
2090: {
2091: if (regs_ever_live[i] && ! call_used_regs[i])
2092: preserved_reg_bytes += 4;
2093: }
2094:
2095: /* The upper part of each frame will contain only saved fp,
2096: the saved r1, and stack slots for all of the other "preserved"
2097: registers that we find we will need to save & restore. */
2098:
2099: frame_upper_bytes = must_preserve_bytes + preserved_reg_bytes;
2100:
2101: /* Round-up frame_upper_bytes so that t is a multiple of 16. */
2102:
2103: frame_upper_bytes
2104: = (frame_upper_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT;
2105:
2106: /* Restore all of the "preserved" registers that need restoring. */
2107:
1.1.1.3 ! root 2108: mask = 2;
! 2109:
! 2110: for (i = 1; i < 32; i++, mask<<=1)
! 2111: if (regs_ever_live[i] && ! call_used_regs[i]) {
1.1 root 2112: fprintf (asm_file, "\tld.l %d(%sfp),%s%s\n",
2113: must_preserve_bytes + (4 * restored_so_far++),
2114: i860_reg_prefix, i860_reg_prefix, reg_names[i]);
1.1.1.3 ! root 2115: if (i > 3 && i < 16)
! 2116: flags->iregs |= mask;
! 2117: }
1.1 root 2118:
1.1.1.3 ! root 2119: int_restored = restored_so_far;
! 2120: mask = 1;
! 2121:
! 2122: for (i = 32; i < 64; i++) {
! 2123: if (regs_ever_live[i] && ! call_used_regs[i]) {
1.1 root 2124: fprintf (asm_file, "\tfld.l %d(%sfp),%s%s\n",
2125: must_preserve_bytes + (4 * restored_so_far++),
2126: i860_reg_prefix, i860_reg_prefix, reg_names[i]);
1.1.1.3 ! root 2127: if (i > 33 & i < 40)
! 2128: flags->fregs |= mask;
! 2129: }
! 2130: if (i > 33 && i < 40)
! 2131: mask<<=1;
! 2132: }
1.1 root 2133:
2134: /* Get the value we plan to use to restore the stack pointer into r31. */
2135:
2136: fprintf (asm_file, "\tadds %d,%sfp,%sr31\n",
2137: frame_upper_bytes, i860_reg_prefix, i860_reg_prefix);
2138:
2139: /* Restore the return address and the old frame pointer. */
2140:
1.1.1.3 ! root 2141: if (must_preserve_r1) {
1.1 root 2142: fprintf (asm_file, "\tld.l 4(%sfp),%sr1\n",
2143: i860_reg_prefix, i860_reg_prefix);
1.1.1.3 ! root 2144: flags->iregs |= 2;
! 2145: }
1.1 root 2146:
2147: fprintf (asm_file, "\tld.l 0(%sfp),%sfp\n",
2148: i860_reg_prefix, i860_reg_prefix);
2149:
2150: /* Return and restore the old stack pointer value. */
2151:
2152: fprintf (asm_file, "\tbri %sr1\n\tmov %sr31,%ssp\n",
2153: i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);
1.1.1.3 ! root 2154:
! 2155: #ifdef OUTPUT_TDESC /* Output an ABI-compliant TDESC entry */
! 2156: if (! frame_lower_bytes) {
! 2157: flags->version--;
! 2158: if (! frame_upper_bytes) {
! 2159: flags->version--;
! 2160: if (restored_so_far == int_restored) /* No FP saves */
! 2161: flags->version--;
! 2162: }
! 2163: }
! 2164: assemble_name(asm_file,current_function_original_name);
! 2165: fputs(".TDESC:\n", asm_file);
! 2166: fprintf(asm_file, "%s 0x%0x\n", ASM_LONG, intflags);
! 2167: fprintf(asm_file, "%s %d\n", ASM_LONG,
! 2168: int_restored ? must_preserve_bytes : 0);
! 2169: if (flags->version > 1) {
! 2170: fprintf(asm_file, "%s %d\n", ASM_LONG,
! 2171: (restored_so_far == int_restored) ? 0 : must_preserve_bytes +
! 2172: (4 * int_restored));
! 2173: if (flags->version > 2) {
! 2174: fprintf(asm_file, "%s %d\n", ASM_LONG, frame_upper_bytes);
! 2175: if (flags->version > 3)
! 2176: fprintf(asm_file, "%s %d\n", ASM_LONG, frame_lower_bytes);
! 2177: }
! 2178: }
! 2179: tdesc_section();
! 2180: fprintf(asm_file, "%s ", ASM_LONG);
! 2181: assemble_name(asm_file, current_function_original_name);
! 2182: fprintf(asm_file, "\n%s ", ASM_LONG);
! 2183: assemble_name(asm_file, current_function_original_name);
! 2184: fputs(".TDESC\n", asm_file);
! 2185: text_section();
! 2186: #endif
1.1 root 2187: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.