|
|
1.1 root 1: /* Subroutines used for code generation on intel 80960.
2: Copyright (C) 1992 Free Software Foundation, Inc.
3: Contributed by Steven McGeady, Intel Corp.
4: Additional Work by Glenn Colon-Bonet, Jonathan Shapiro, Andy Wilson
5: Converted to GCC 2.0 by Jim Wilson and Michael Tiemann, Cygnus Support.
6:
7: This file is part of GNU CC.
8:
9: GNU CC is free software; you can redistribute it and/or modify
10: it under the terms of the GNU General Public License as published by
11: the Free Software Foundation; either version 2, or (at your option)
12: any later version.
13:
14: GNU CC is distributed in the hope that it will be useful,
15: but WITHOUT ANY WARRANTY; without even the implied warranty of
16: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17: GNU General Public License for more details.
18:
19: You should have received a copy of the GNU General Public License
20: along with GNU CC; see the file COPYING. If not, write to
21: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22:
23: #include <stdio.h>
24:
25: #include "config.h"
26: #include "rtl.h"
27: #include "regs.h"
28: #include "hard-reg-set.h"
29: #include "real.h"
30: #include "insn-config.h"
31: #include "conditions.h"
32: #include "insn-flags.h"
33: #include "output.h"
34: #include "insn-attr.h"
35: #include "flags.h"
36: #include "tree.h"
37: #include "insn-codes.h"
38: #include "assert.h"
39: #include "expr.h"
40: #include "function.h"
41: #include "recog.h"
42: #include <math.h>
43:
44: /* Save the operands last given to a compare for use when we
45: generate a scc or bcc insn. */
46:
47: rtx i960_compare_op0, i960_compare_op1;
48:
49: /* Used to implement #pragma align/noalign. Initialized by OVERRIDE_OPTIONS
50: macro in i960.h. */
51:
52: static int i960_maxbitalignment;
53: static int i960_last_maxbitalignment;
54:
55: /* Used to implement switching between MEM and ALU insn types, for better
56: C series performance. */
57:
58: enum insn_types i960_last_insn_type;
59:
60: /* The leaf-procedure return register. Set only if this is a leaf routine. */
61:
62: static int i960_leaf_ret_reg;
63:
64: /* True if replacing tail calls with jumps is OK. */
65:
66: static int tail_call_ok;
67:
68: /* A string containing a list of insns to emit in the epilogue so as to
69: restore all registers saved by the prologue. Created by the prologue
70: code as it saves registers away. */
71:
72: char epilogue_string[1000];
73:
74: /* A unique number (per function) for return labels. */
75:
76: static int ret_label = 0;
77:
78: #if 0
79: /* Handle pragmas for compatibility with Intel's compilers. */
80:
81: /* ??? This is incomplete, since it does not handle all pragmas that the
82: intel compilers understand. Also, it needs to be rewritten to accept
83: a stream instead of a string for GCC 2. */
84:
85: void
86: process_pragma(str)
87: char *str;
88: {
89: int align;
90: int i;
91:
92: if ((i = sscanf (str, " align %d", &align)) == 1)
93: switch (align)
94: {
95: case 0: /* Return to last alignment. */
96: align = i960_last_maxbitalignment / 8;
97:
98: case 16: /* Byte alignments. */
99: case 8:
100: case 4:
101: case 2:
102: case 1:
103: i960_last_maxbitalignment = i960_maxbitalignment;
104: i960_maxbitalignment = align * 8;
105: break;
106:
107: default: /* Unknown, silently ignore. */
108: break;
109: }
110:
111: /* NOTE: ic960 R3.0 pragma align definition:
112:
113: #pragma align [(size)] | (identifier=size[,...])
114: #pragma noalign [(identifier)[,...]]
115:
116: (all parens are optional)
117:
118: - size is [1,2,4,8,16]
119: - noalign means size==1
120: - applies only to component elements of a struct (and union?)
121: - identifier applies to structure tag (only)
122: - missing identifier means next struct
123:
124: - alignment rules for bitfields need more investigation */
125:
126: /* Should be pragma 'far' or equivalent for callx/balx here. */
127: }
128: #endif
129:
130: /* Initialize variables before compiling any files. */
131:
132: void
133: i960_initialize ()
134: {
135: if (TARGET_IC_COMPAT2_0)
136: {
137: i960_maxbitalignment = 8;
138: i960_last_maxbitalignment = 128;
139: }
140: else
141: {
142: i960_maxbitalignment = 128;
143: i960_last_maxbitalignment = 8;
144: }
145: }
146:
147: /* Return true if OP can be used as the source of an fp move insn. */
148:
149: int
150: fpmove_src_operand (op, mode)
151: rtx op;
152: enum machine_mode mode;
153: {
154: return (GET_CODE (op) == CONST_DOUBLE || general_operand (op, mode));
155: }
156:
157: #if 0
158: /* Return true if OP is a register or zero. */
159:
160: int
161: reg_or_zero_operand (op, mode)
162: rtx op;
163: enum machine_mode mode;
164: {
165: return register_operand (op, mode) || op == const0_rtx;
166: }
167: #endif
168:
169: /* Return truth value of whether OP can be used as an operands in a three
170: address arithmetic insn (such as add %o1,7,%l2) of mode MODE. */
171:
172: int
173: arith_operand (op, mode)
174: rtx op;
175: enum machine_mode mode;
176: {
177: return (register_operand (op, mode) || literal (op, mode));
178: }
179:
180: /* Return true if OP is a register or a valid floating point literal. */
181:
182: int
183: fp_arith_operand (op, mode)
184: rtx op;
185: enum machine_mode mode;
186: {
187: return (register_operand (op, mode) || fp_literal (op, mode));
188: }
189:
190: /* Return true is OP is a register or a valid signed integer literal. */
191:
192: int
193: signed_arith_operand (op, mode)
194: rtx op;
195: enum machine_mode mode;
196: {
197: return (register_operand (op, mode) || signed_literal (op, mode));
198: }
199:
200: /* Return truth value of whether OP is a integer which fits the
201: range constraining immediate operands in three-address insns. */
202:
203: int
204: literal (op, mode)
205: rtx op;
206: enum machine_mode mode;
207: {
208: return ((GET_CODE (op) == CONST_INT) && INTVAL(op) >= 0 && INTVAL(op) < 32);
209: }
210:
211: /* Return true if OP is a float constant of 1. */
212:
213: int
214: fp_literal_one (op, mode)
215: rtx op;
216: enum machine_mode mode;
217: {
218: return (TARGET_NUMERICS && (mode == VOIDmode || mode == GET_MODE (op))
219: && (op == CONST1_RTX (mode)));
220: }
221:
222: /* Return true if OP is a float constant of 0. */
223:
224: int
225: fp_literal_zero (op, mode)
226: rtx op;
227: enum machine_mode mode;
228: {
229: return (TARGET_NUMERICS && (mode == VOIDmode || mode == GET_MODE (op))
230: && (op == CONST0_RTX (mode)));
231: }
232:
233: /* Return true if OP is a valid floating point literal. */
234:
235: int
236: fp_literal(op, mode)
237: rtx op;
238: enum machine_mode mode;
239: {
240: return fp_literal_zero (op, mode) || fp_literal_one (op, mode);
241: }
242:
243: /* Return true if OP is a valid signed immediate constant. */
244:
245: int
246: signed_literal(op, mode)
247: rtx op;
248: enum machine_mode mode;
249: {
250: return ((GET_CODE (op) == CONST_INT) && INTVAL(op) > -32 && INTVAL(op) < 32);
251: }
252:
253: /* Return truth value of statement that OP is a symbolic memory
254: operand of mode MODE. */
255:
256: int
257: symbolic_memory_operand (op, mode)
258: rtx op;
259: enum machine_mode mode;
260: {
261: if (GET_CODE (op) == SUBREG)
262: op = SUBREG_REG (op);
263: if (GET_CODE (op) != MEM)
264: return 0;
265: op = XEXP (op, 0);
266: return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
267: || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
268: }
269:
270: /* Return truth value of whether OP is EQ or NE. */
271:
272: int
273: eq_or_neq (op, mode)
274: rtx op;
275: enum machine_mode mode;
276: {
277: return (GET_CODE (op) == EQ || GET_CODE (op) == NE);
278: }
279:
280: /* OP is an integer register or a constant. */
281:
282: int
283: arith32_operand (op, mode)
284: rtx op;
285: enum machine_mode mode;
286: {
287: if (register_operand (op, mode))
288: return 1;
289: return (CONSTANT_P (op));
290: }
291:
292: /* Return true if OP is an integer constant which is a power of 2. */
293:
294: int
295: power2_operand (op,mode)
296: rtx op;
297: enum machine_mode mode;
298: {
299: if (GET_CODE (op) != CONST_INT)
300: return 0;
301:
302: return exact_log2 (INTVAL (op)) >= 0;
303: }
304:
305: /* Return true if OP is an integer constant which is the complement of a
306: power of 2. */
307:
308: int
309: cmplpower2_operand (op, mode)
310: rtx op;
311: enum machine_mode mode;
312: {
313: if (GET_CODE (op) != CONST_INT)
314: return 0;
315:
316: return exact_log2 (~ INTVAL (op)) >= 0;
317: }
318:
319: /* If VAL has only one bit set, return the index of that bit. Otherwise
320: return -1. */
321:
322: int
323: bitpos (val)
324: unsigned int val;
325: {
326: register int i;
327:
328: for (i = 0; val != 0; i++, val >>= 1)
329: {
330: if (val & 1)
331: {
332: if (val != 1)
333: return -1;
334: return i;
335: }
336: }
337: return -1;
338: }
339:
340: /* Return non-zero if OP is a mask, i.e. all one bits are consecutive.
341: The return value indicates how many consecutive non-zero bits exist
342: if this is a mask. This is the same as the next function, except that
343: it does not indicate what the start and stop bit positions are. */
344:
345: int
346: is_mask (val)
347: unsigned int val;
348: {
349: register int start, end, i;
350:
351: start = -1;
352: for (i = 0; val != 0; val >>= 1, i++)
353: {
354: if (val & 1)
355: {
356: if (start < 0)
357: start = i;
358:
359: end = i;
360: continue;
361: }
362: /* Still looking for the first bit. */
363: if (start < 0)
364: continue;
365:
366: /* We've seen the start of a bit sequence, and now a zero. There
367: must be more one bits, otherwise we would have exited the loop.
368: Therefore, it is not a mask. */
369: if (val)
370: return 0;
371: }
372:
373: /* The bit string has ones from START to END bit positions only. */
374: return end - start + 1;
375: }
376:
377: /* If VAL is a mask, then return nonzero, with S set to the starting bit
378: position and E set to the ending bit position of the mask. The return
379: value indicates how many consecutive bits exist in the mask. This is
380: the same as the previous function, except that it also indicates the
381: start and end bit positions of the mask. */
382:
383: int
384: bitstr (val, s, e)
385: unsigned int val;
386: int *s, *e;
387: {
388: register int start, end, i;
389:
390: start = -1;
391: end = -1;
392: for (i = 0; val != 0; val >>= 1, i++)
393: {
394: if (val & 1)
395: {
396: if (start < 0)
397: start = i;
398:
399: end = i;
400: continue;
401: }
402:
403: /* Still looking for the first bit. */
404: if (start < 0)
405: continue;
406:
407: /* We've seen the start of a bit sequence, and now a zero. There
408: must be more one bits, otherwise we would have exited the loop.
409: Therefor, it is not a mask. */
410: if (val)
411: {
412: start = -1;
413: end = -1;
414: break;
415: }
416: }
417:
418: /* The bit string has ones from START to END bit positions only. */
419: *s = start;
420: *e = end;
421: return ((start < 0) ? 0 : end - start + 1);
422: }
423:
424: /* Return the machine mode to use for a comparison. */
425:
426: enum machine_mode
427: select_cc_mode (op, x)
428: RTX_CODE op;
429: rtx x;
430: {
431: if (op == GTU || op == LTU || op == GEU || op == LEU)
432: return CC_UNSmode;
433: return CCmode;
434: }
435:
436: /* X and Y are two things to compare using CODE. Emit the compare insn and
437: return the rtx for register 36 in the proper mode. */
438:
439: rtx
440: gen_compare_reg (code, x, y)
441: enum rtx_code code;
442: rtx x, y;
443: {
444: rtx cc_reg;
445: enum machine_mode ccmode = SELECT_CC_MODE (code, x, y);
446: enum machine_mode mode
447: = GET_MODE (x) == VOIDmode ? GET_MODE (y) : GET_MODE (x);
448:
449: if (mode == SImode)
450: {
451: if (! arith_operand (x, mode))
452: x = force_reg (SImode, x);
453: if (! arith_operand (y, mode))
454: y = force_reg (SImode, y);
455: }
456:
457: cc_reg = gen_rtx (REG, ccmode, 36);
458: emit_insn (gen_rtx (SET, VOIDmode, cc_reg,
459: gen_rtx (COMPARE, ccmode, x, y)));
460:
461: return cc_reg;
462: }
463:
464: /* For the i960, REG is cost 1, REG+immed CONST is cost 2, REG+REG is cost 2,
465: REG+nonimmed CONST is cost 4. REG+SYMBOL_REF, SYMBOL_REF, and similar
466: are 4. Indexed addresses are cost 6. */
467:
468: /* ??? Try using just RTX_COST, i.e. not defining ADDRESS_COST. */
469:
470: int
471: i960_address_cost (x)
472: rtx x;
473: {
474: #if 0
475: /* Handled before calling here. */
476: if (GET_CODE (x) == REG)
477: return 1;
478: #endif
479: if (GET_CODE (x) == PLUS)
480: {
481: rtx base = XEXP (x, 0);
482: rtx offset = XEXP (x, 1);
483:
484: if (GET_CODE (base) == SUBREG)
485: base = SUBREG_REG (base);
486: if (GET_CODE (offset) == SUBREG)
487: offset = SUBREG_REG (offset);
488:
489: if (GET_CODE (base) == REG)
490: {
491: if (GET_CODE (offset) == REG)
492: return 2;
493: if (GET_CODE (offset) == CONST_INT)
494: {
495: if ((unsigned)INTVAL (offset) < 2047)
496: return 2;
497: return 4;
498: }
499: if (CONSTANT_P (offset))
500: return 4;
501: }
502: if (GET_CODE (base) == PLUS || GET_CODE (base) == MULT)
503: return 6;
504:
505: /* This is an invalid address. The return value doesn't matter, but
506: for convenience we make this more expensive than anything else. */
507: return 12;
508: }
509: if (GET_CODE (x) == MULT)
510: return 6;
511:
512: /* Symbol_refs and other unrecognized addresses are cost 4. */
513: return 4;
514: }
515:
516: /* Emit insns to move operands[1] into operands[0].
517:
518: Return 1 if we have written out everything that needs to be done to
519: do the move. Otherwise, return 0 and the caller will emit the move
520: normally. */
521:
522: int
523: emit_move_sequence (operands, mode)
524: rtx *operands;
525: enum machine_mode mode;
526: {
527: register rtx operand0 = operands[0];
528: register rtx operand1 = operands[1];
529:
530: /* We can only store registers to memory. */
531:
532: if (GET_CODE (operand0) == MEM && GET_CODE (operand1) != REG)
533: operands[1] = force_reg (mode, operand1);
534:
535: return 0;
536: }
537:
538: /* Emit insns to load a constant. Uses several strategies to try to use
539: as few insns as possible. */
540:
541: char *
542: i960_output_ldconst (dst, src)
543: register rtx dst, src;
544: {
545: register int rsrc1;
546: register unsigned rsrc2;
547: enum machine_mode mode = GET_MODE (dst);
548: rtx operands[4];
549: union { long l[2]; double d; } x;
550:
551: operands[0] = operands[2] = dst;
552: operands[1] = operands[3] = src;
553:
554: /* Anything that isn't a compile time constant, such as a SYMBOL_REF,
555: must be a ldconst insn. */
556:
557: if (GET_CODE (src) != CONST_INT && GET_CODE (src) != CONST_DOUBLE)
558: {
559: output_asm_insn ("ldconst %1,%0", operands);
560: return "";
561: }
562: else if (mode == DFmode)
563: {
564: rtx first, second;
565:
566: if (fp_literal_zero (src, VOIDmode))
567: {
568: if (FP_REG_P (dst))
569: return "movrl %1,%0";
570: else
571: return "movl 0,%0";
572: }
573:
574: #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
575: split_double (src, &first, &second);
576:
577: output_asm_insn ("# ldconst %1,%0",operands);
578:
579: operands[0] = gen_rtx (REG, SImode, REGNO (dst));
580: operands[1] = first;
581: output_asm_insn (i960_output_ldconst (operands[0], operands[1]),
582: operands);
583: operands[0] = gen_rtx (REG, SImode, REGNO (dst) + 1);
584: operands[1] = second;
585: output_asm_insn (i960_output_ldconst (operands[0], operands[1]),
586: operands);
587: return "";
588: #else
589: if (fp_literal_one (src, VOIDmode))
590: return "movrl 0f1.0,%0";
591: fatal ("inline double constants not supported on this host");
592: #endif
593: }
594: else if (mode == TImode)
595: {
596: /* ??? This is currently not handled at all. */
597: abort ();
598:
599: /* Note: lowest order word goes in lowest numbered reg. */
600: rsrc1 = INTVAL (src);
601: if (rsrc1 >= 0 && rsrc1 < 32)
602: return "movq %1,%0";
603: else
604: output_asm_insn ("movq\t0,%0\t# ldconstq %1,%0",operands);
605: /* Go pick up the low-order word. */
606: }
607: else if (mode == DImode)
608: {
609: rtx upperhalf, lowerhalf, xoperands[2];
610: char *string;
611:
612: if (GET_CODE (src) == CONST_DOUBLE)
613: {
614: upperhalf = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (src));
615: lowerhalf = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (src));
616: }
617: else if (GET_CODE (src) == CONST_INT)
618: {
619: lowerhalf = src;
620: upperhalf = INTVAL (src) < 0 ? constm1_rtx : const0_rtx;
621: }
622: else
623: abort ();
624:
625: /* Note: lowest order word goes in lowest numbered reg. */
626: /* Numbers from 0 to 31 can be handled with a single insn. */
627: rsrc1 = INTVAL (lowerhalf);
628: if (upperhalf == const0_rtx && rsrc1 >= 0 && rsrc1 < 32)
629: return "movl %1,%0";
630:
631: /* Output the upper half with a recursive call. */
632: xoperands[0] = gen_rtx (REG, SImode, REGNO (dst) + 1);
633: xoperands[1] = upperhalf;
634: output_asm_insn (i960_output_ldconst (xoperands[0], xoperands[1]),
635: xoperands);
636: /* The lower word is emitted as normally. */
637: }
638: else if (mode == SFmode)
639: {
640: #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
641: REAL_VALUE_TYPE d;
642: long value;
643:
644: REAL_VALUE_FROM_CONST_DOUBLE (d, src);
645: REAL_VALUE_TO_TARGET_SINGLE (d, value);
646:
647: output_asm_insn ("# ldconst %1,%0",operands);
648: operands[0] = gen_rtx (REG, SImode, REGNO (dst));
649: operands[1] = gen_rtx (CONST_INT, VOIDmode, value);
650: output_asm_insn (i960_output_ldconst (operands[0], operands[1]),
651: operands);
652: #else
653: if (fp_literal_zero (src, VOIDmode))
654: return "movr 0f0.0,%0";
655: if (fp_literal_one (src, VOIDmode))
656: return "movr 0f1.0,%0";
657: fatal ("inline float constants not supported on this host");
658: #endif
659: return "";
660: }
661: else
662: {
663: rsrc1 = INTVAL (src);
664: if (mode == QImode)
665: {
666: if (rsrc1 > 0xff)
667: rsrc1 &= 0xff;
668: }
669: else if (mode == HImode)
670: {
671: if (rsrc1 > 0xffff)
672: rsrc1 &= 0xffff;
673: }
674: }
675:
676: if (rsrc1 >= 0)
677: {
678: /* ldconst 0..31,X -> mov 0..31,X */
679: if (rsrc1 < 32)
680: {
681: if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
682: return "lda %1,%0";
683: return "mov %1,%0";
684: }
685:
686: /* ldconst 32..63,X -> add 31,nn,X */
687: if (rsrc1 < 63)
688: {
689: if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
690: return "lda %1,%0";
691: operands[1] = gen_rtx (CONST_INT, VOIDmode, rsrc1 - 31);
692: output_asm_insn ("addo\t31,%1,%0\t# ldconst %3,%0", operands);
693: return "";
694: }
695: }
696: else if (rsrc1 < 0)
697: {
698: /* ldconst -1..-31 -> sub 0,0..31,X */
699: if (rsrc1 >= -31)
700: {
701: /* return 'sub -(%1),0,%0' */
702: operands[1] = gen_rtx (CONST_INT, VOIDmode, - rsrc1);
703: output_asm_insn ("subo\t%1,0,%0\t# ldconst %3,%0", operands);
704: return "";
705: }
706:
707: /* ldconst -32 -> not 31,X */
708: if (rsrc1 == -32)
709: {
710: operands[1] = gen_rtx (CONST_INT, VOIDmode, ~rsrc1);
711: output_asm_insn ("not\t%1,%0 # ldconst %3,%0", operands);
712: return "";
713: }
714: }
715:
716: /* If const is a single bit. */
717: if (bitpos (rsrc1) >= 0)
718: {
719: operands[1] = gen_rtx (CONST_INT, VOIDmode, bitpos (rsrc1));
720: output_asm_insn ("setbit\t%1,0,%0\t# ldconst %3,%0", operands);
721: return "";
722: }
723:
724: /* If const is a bit string of less than 6 bits (1..31 shifted). */
725: if (is_mask (rsrc1))
726: {
727: int s, e;
728:
729: if (bitstr (rsrc1, &s, &e) < 6)
730: {
731: rsrc2 = ((unsigned int) rsrc1) >> s;
732: operands[1] = gen_rtx (CONST_INT, VOIDmode, rsrc2);
733: operands[2] = gen_rtx (CONST_INT, VOIDmode, s);
734: output_asm_insn ("shlo\t%2,%1,%0\t# ldconst %3,%0", operands);
735: return "";
736: }
737: }
738:
739: /* Unimplemented cases:
740: const is in range 0..31 but rotated around end of word:
741: ror 31,3,g0 -> ldconst 0xe0000003,g0
742:
743: and any 2 instruction cases that might be worthwhile */
744:
745: output_asm_insn ("ldconst %1,%0", operands);
746: return "";
747: }
748:
749: /* Determine if there is an opportunity for a bypass optimization.
750: Bypass succeeds on the 960K* if the destination of the previous
751: instruction is the second operand of the current instruction.
752: Bypass always succeeds on the C*.
753:
754: Return 1 if the pattern should interchange the operands.
755:
756: CMPBR_FLAG is true if this is for a compare-and-branch insn.
757: OP1 and OP2 are the two source operands of a 3 operand insn. */
758:
759: int
760: i960_bypass (insn, op1, op2, cmpbr_flag)
761: register rtx insn, op1, op2;
762: int cmpbr_flag;
763: {
764: register rtx prev_insn, prev_dest;
765:
766: if (TARGET_C_SERIES)
767: return 0;
768:
769: /* Can't do this if op1 isn't a register. */
770: if (! REG_P (op1))
771: return 0;
772:
773: /* Can't do this for a compare-and-branch if both ops aren't regs. */
774: if (cmpbr_flag && ! REG_P (op2))
775: return 0;
776:
777: prev_insn = prev_real_insn (insn);
778:
779: if (prev_insn && GET_CODE (prev_insn) == INSN
780: && GET_CODE (PATTERN (prev_insn)) == SET)
781: {
782: prev_dest = SET_DEST (PATTERN (prev_insn));
783: if ((GET_CODE (prev_dest) == REG && REGNO (prev_dest) == REGNO (op1))
784: || (GET_CODE (prev_dest) == SUBREG
785: && GET_CODE (SUBREG_REG (prev_dest)) == REG
786: && REGNO (SUBREG_REG (prev_dest)) == REGNO (op1)))
787: return 1;
788: }
789: return 0;
790: }
791:
792: /* Output the code which declares the function name. This also handles
793: leaf routines, which have special requirements, and initializes some
794: global variables. */
795:
796: void
797: i960_function_name_declare (file, name, fndecl)
798: FILE *file;
799: char *name;
800: tree fndecl;
801: {
802: register int i, j;
803: int leaf_proc_ok;
804: rtx insn;
805:
806: /* Increment global return label. */
807:
808: ret_label++;
809:
810: /* Compute whether tail calls and leaf routine optimizations can be performed
811: for this function. */
812:
813: if (TARGET_TAILCALL)
814: tail_call_ok = 1;
815: else
816: tail_call_ok = 0;
817:
818: if (TARGET_LEAFPROC)
819: leaf_proc_ok = 1;
820: else
821: leaf_proc_ok = 0;
822:
823: /* Even if nobody uses extra parms, can't have leafroc or tail calls if
824: argblock, because argblock uses g14 implicitly. */
825:
826: if (current_function_args_size != 0)
827: {
828: tail_call_ok = 0;
829: leaf_proc_ok = 0;
830: }
831:
832: /* See if caller passes in an address to return value. */
833:
834: if (aggregate_value_p (DECL_RESULT (fndecl)))
835: {
836: tail_call_ok = 0;
837: leaf_proc_ok = 0;
838: }
839:
840: /* Can not use tail calls or make this a leaf routine if there is a non
841: zero frame size. */
842:
843: if (get_frame_size () != 0)
844: leaf_proc_ok = 0;
845:
846: /* I don't understand this condition, and do not think that it is correct.
847: Apparently this is just checking whether the frame pointer is used, and
848: we can't trust regs_ever_live[fp] since it is (almost?) always set. */
849:
850: if (tail_call_ok)
851: for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
852: if (GET_CODE (insn) == INSN
853: && reg_mentioned_p (frame_pointer_rtx, insn))
854: {
855: tail_call_ok = 0;
856: break;
857: }
858:
859: /* Check for CALL insns. Can not be a leaf routine if there are any. */
860:
861: if (leaf_proc_ok)
862: for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
863: if (GET_CODE (insn) == CALL_INSN)
864: {
865: leaf_proc_ok = 0;
866: break;
867: }
868:
869: /* Can not be a leaf routine if any non-call clobbered registers are
870: used in this function. */
871:
872: if (leaf_proc_ok)
873: for (i = 0, j = 0; i < FIRST_PSEUDO_REGISTER; i++)
874: if (regs_ever_live[i]
875: && ((! call_used_regs[i]) || (i > 7 && i < 12)))
876: {
877: /* Global registers. */
878: if (i < 16 && i > 7 && i != 13)
879: leaf_proc_ok = 0;
880: /* Local registers. */
881: else if (i < 32)
882: leaf_proc_ok = 0;
883: }
884:
885: /* Now choose a leaf return register, if we can find one, and if it is
886: OK for this to be a leaf routine. */
887:
888: i960_leaf_ret_reg = -1;
889:
890: if (optimize && leaf_proc_ok)
891: {
892: for (i960_leaf_ret_reg = -1, i = 0; i < 8; i++)
893: if (regs_ever_live[i] == 0)
894: {
895: i960_leaf_ret_reg = i;
896: regs_ever_live[i] = 1;
897: break;
898: }
899: }
900:
901: /* Do this after choosing the leaf return register, so it will be listed
902: if one was chosen. */
903:
904: fprintf (file, "\t# Function '%s'\n", name);
905: fprintf (file, "\t# Registers used: ");
906:
907: for (i = 0, j = 0; i < FIRST_PSEUDO_REGISTER; i++)
908: {
909: if (regs_ever_live[i])
910: {
911: fprintf (file, "%s%s ", reg_names[i], call_used_regs[i] ? "" : "*");
912:
913: if (i > 15 && j == 0)
914: {
915: fprintf (file,"\n\t#\t\t ");
916: j++;
917: }
918: }
919: }
920:
921: fprintf (file, "\n");
922:
923: if (i960_leaf_ret_reg >= 0)
924: {
925: /* Make it a leaf procedure. */
926:
927: if (TREE_PUBLIC (fndecl))
928: fprintf (file,"\t.globl %s.lf\n", name);
929:
930: fprintf (file, "\t.leafproc\t_%s,%s.lf\n", name, name);
931: fprintf (file, "_%s:\n", name);
932: fprintf (file, "\tlda LR%d,g14\n", ret_label);
933: fprintf (file, "%s.lf:\n", name);
934: fprintf (file, "\tmov g14,g%d\n", i960_leaf_ret_reg);
935:
936: if (TARGET_C_SERIES)
937: {
938: fprintf (file, "\tlda 0,g14\n");
939: i960_last_insn_type = I_TYPE_MEM;
940: }
941: else
942: {
943: fprintf (file, "\tmov 0,g14\n");
944: i960_last_insn_type = I_TYPE_REG;
945: }
946: }
947: else
948: {
949: ASM_OUTPUT_LABEL (file, name);
950: i960_last_insn_type = I_TYPE_CTRL;
951: }
952: }
953:
954: /* Compute and return the frame size. */
955:
956: int
957: compute_frame_size (size)
958: int size;
959: {
960: int actual_fsize;
961: int outgoing_args_size
962: = current_function_outgoing_args_size + current_function_pretend_args_size;
963:
964: /* The STARTING_FRAME_OFFSET is totally hidden to us as far
965: as size is concerned. */
966: actual_fsize = (size + 15) & -16;
967: actual_fsize += (outgoing_args_size + 15) & -16;
968:
969: return actual_fsize;
970: }
971:
972: /* Output code for the function prologue. */
973:
974: void
975: i960_function_prologue (file, size)
976: FILE *file;
977: unsigned int size;
978: {
979: register int i, j, nr;
980: int n_iregs = 0;
981: int rsize = 0;
982: int actual_fsize, offset;
983: char tmpstr[1000];
984: /* -1 if reg must be saved on proc entry, 0 if available, 1 if saved
985: somewhere. */
986: int regs[FIRST_PSEUDO_REGISTER];
987:
988: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
989: if (regs_ever_live[i]
990: && ((! call_used_regs[i]) || (i > 7 && i < 12)))
991: {
992: regs[i] = -1;
993: /* Count global registers that need saving. */
994: if (i < 16)
995: n_iregs++;
996: }
997: else
998: regs[i] = 0;
999:
1000: epilogue_string[0] = '\0';
1001:
1002: if (profile_flag || profile_block_flag)
1003: {
1004: /* When profiling, we may use registers 20 to 27 to save arguments, so
1005: they can't be used here for saving globals. J is the number of
1006: argument registers the mcount call will save. */
1007: for (j = 7; j >= 0 && ! regs_ever_live[j]; j--)
1008: ;
1009:
1010: for (i = 20; i <= j + 20; i++)
1011: regs[i] = -1;
1012: }
1013:
1014: /* First look for local registers to save globals in. */
1015: for (i = 0; i < 16; i++)
1016: {
1017: if (regs[i] == 0)
1018: continue;
1019:
1020: /* Start at r4, not r3. */
1021: for (j = 20; j < 32; j++)
1022: {
1023: if (regs[j] != 0)
1024: continue;
1025:
1026: regs[i] = 1;
1027: regs[j] = -1;
1028: regs_ever_live[j] = 1;
1029: nr = 1;
1030: if (i <= 14 && i % 2 == 0 && j <= 30 && j % 2 == 0
1031: && regs[i+1] != 0 && regs[j+1] == 0)
1032: {
1033: nr = 2;
1034: regs[i+1] = 1;
1035: regs[j+1] = -1;
1036: regs_ever_live[j+1] = 1;
1037: }
1038: if (nr == 2 && i <= 12 && i % 4 == 0 && j <= 28 && j % 4 == 0
1039: && regs[i+2] != 0 && regs[j+2] == 0)
1040: {
1041: nr = 3;
1042: regs[i+2] = 1;
1043: regs[j+2] = -1;
1044: regs_ever_live[j+2] = 1;
1045: }
1046: if (nr == 3 && regs[i+3] != 0 && regs[j+3] == 0)
1047: {
1048: nr = 4;
1049: regs[i+3] = 1;
1050: regs[j+3] = -1;
1051: regs_ever_live[j+3] = 1;
1052: }
1053:
1054: fprintf (file, "\tmov%s %s,%s\n",
1055: ((nr == 4) ? "q" :
1056: (nr == 3) ? "t" :
1057: (nr == 2) ? "l" : ""),
1058: reg_names[i], reg_names[j]);
1059: sprintf (tmpstr, "\tmov%s %s,%s\n",
1060: ((nr == 4) ? "q" :
1061: (nr == 3) ? "t" :
1062: (nr == 2) ? "l" : ""),
1063: reg_names[j], reg_names[i]);
1064: strcat (epilogue_string, tmpstr);
1065:
1066: n_iregs -= nr;
1067: i += nr-1;
1068: break;
1069: }
1070: }
1071:
1072: /* N_iregs is now the number of global registers that haven't been saved
1073: yet. */
1074:
1075: rsize = (n_iregs * 4);
1076: actual_fsize = compute_frame_size (size) + rsize;
1077: #if 0
1078: /* ??? The 1.2.1 compiler does this also. This is meant to round the frame
1079: size up to the nearest multiple of 16. I don't know whether this is
1080: necessary, or even desirable.
1081:
1082: The frame pointer must be aligned, but the call instruction takes care of
1083: that. If we leave the stack pointer unaligned, we may save a little on
1084: dynamic stack allocation. And we don't lose, at least according to the
1085: i960CA manual. */
1086: actual_fsize = (actual_fsize + 15) & ~0xF;
1087: #endif
1088:
1089: /* Allocate space for register save and locals. */
1090: if (actual_fsize > 0)
1091: {
1092: if (actual_fsize < 32)
1093: fprintf (file, "\taddo %d,sp,sp\n", actual_fsize);
1094: else
1095: fprintf (file, "\tlda\t%d(sp),sp\n", actual_fsize);
1096: }
1097:
1098: /* Take hardware register save area created by the call instruction
1099: into account. */
1100: offset = compute_frame_size (size) + 64;
1101: /* Save registers on stack if needed. */
1102: for (i = 0, j = n_iregs; j > 0 && i < 16; i++)
1103: {
1104: if (regs[i] != -1)
1105: continue;
1106:
1107: nr = 1;
1108:
1109: if (i <= 14 && i % 2 == 0 && regs[i+1] == -1 && offset % 2 == 0)
1110: nr = 2;
1111:
1112: if (nr == 2 && i <= 12 && i % 4 == 0 && regs[i+2] == -1
1113: && offset % 4 == 0)
1114: nr = 3;
1115:
1116: if (nr == 3 && regs[i+3] == -1)
1117: nr = 4;
1118:
1119: fprintf (file,"\tst%s %s,%d(fp)\n",
1120: ((nr == 4) ? "q" :
1121: (nr == 3) ? "t" :
1122: (nr == 2) ? "l" : ""),
1123: reg_names[i], offset);
1124: sprintf (tmpstr,"\tld%s %d(fp),%s\n",
1125: ((nr == 4) ? "q" :
1126: (nr == 3) ? "t" :
1127: (nr == 2) ? "l" : ""),
1128: offset, reg_names[i]);
1129: strcat (epilogue_string, tmpstr);
1130: i += nr-1;
1131: j -= nr;
1132: offset += nr * 4;
1133: }
1134:
1135: if (actual_fsize == 0 && size == 0 && rsize == 0)
1136: return;
1137:
1138: fprintf (file, "\t#Prologue stats:\n");
1139: fprintf (file, "\t# Total Frame Size: %d bytes\n", actual_fsize);
1140:
1141: if (size)
1142: fprintf (file, "\t# Local Variable Size: %d bytes\n", size);
1143: if (rsize)
1144: fprintf (file, "\t# Register Save Size: %d regs, %d bytes\n",
1145: n_iregs, rsize);
1146: fprintf (file, "\t#End Prologue#\n");
1147: }
1148:
1149: /* Output code for the function profiler. */
1150:
1151: void
1152: output_function_profiler (file, labelno)
1153: FILE *file;
1154: int labelno;
1155: {
1156: /* The last used parameter register. */
1157: int last_parm_reg;
1158: int i, j, increment;
1159:
1160: /* Figure out the last used parameter register. The proper thing to do
1161: is to walk incoming args of the function. A function might have live
1162: parameter registers even if it has no incoming args. Note that we
1163: don't have to save parameter registers g8 to g11 because they are
1164: call preserved. */
1165:
1166: /* See also output_function_prologue, which tries to use local registers
1167: for preserved call-saved global registers. */
1168:
1169: for (last_parm_reg = 7;
1170: last_parm_reg >= 0 && ! regs_ever_live[last_parm_reg];
1171: last_parm_reg--)
1172: ;
1173:
1174: /* Save parameter registers in regs r4 (20) to r11 (27). */
1175:
1176: for (i = 0, j = 4; i <= last_parm_reg; i += increment, j += increment)
1177: {
1178: if (i % 4 == 0 && (last_parm_reg - i) >= 3)
1179: increment = 4;
1180: else if (i % 4 == 0 && (last_parm_reg - i) >= 2)
1181: increment = 3;
1182: else if (i % 2 == 0 && (last_parm_reg - i) >= 1)
1183: increment = 2;
1184: else
1185: increment = 1;
1186:
1187: fprintf (file, "\tmov%s g%d,r%d\n",
1188: (increment == 4 ? "q" : increment == 3 ? "t"
1189: : increment == 2 ? "l": ""), i, j);
1190: }
1191:
1192: /* If this function uses the arg pointer, then save it in r3 and then
1193: set it to zero. */
1194:
1195: if (current_function_args_size != 0)
1196: fprintf (file, "\tmov g14,r3\n\tmov 0,g14\n");
1197:
1198: /* Load location address into g0 and call mcount. */
1199:
1200: fprintf (file, "\tlda\tLP%d,g0\n\tcallx\tmcount\n", labelno);
1201:
1202: /* If this function uses the arg pointer, restore it. */
1203:
1204: if (current_function_args_size != 0)
1205: fprintf (file, "\tmov r3,g14\n");
1206:
1207: /* Restore parameter registers. */
1208:
1209: for (i = 0, j = 4; i <= last_parm_reg; i += increment, j += increment)
1210: {
1211: if (i % 4 == 0 && (last_parm_reg - i) >= 3)
1212: increment = 4;
1213: else if (i % 4 == 0 && (last_parm_reg - i) >= 2)
1214: increment = 3;
1215: else if (i % 2 == 0 && (last_parm_reg - i) >= 1)
1216: increment = 2;
1217: else
1218: increment = 1;
1219:
1220: fprintf (file, "\tmov%s r%d,g%d\n",
1221: (increment == 4 ? "q" : increment == 3 ? "t"
1222: : increment == 2 ? "l": ""), j, i);
1223: }
1224: }
1225:
1226: /* Output code for the function epilogue. */
1227:
1228: void
1229: i960_function_epilogue (file, size)
1230: FILE *file;
1231: unsigned int size;
1232: {
1233: if (i960_leaf_ret_reg >= 0)
1234: {
1235: fprintf (file, "LR%d: ret\n", ret_label);
1236: return;
1237: }
1238:
1239: if (*epilogue_string == 0)
1240: {
1241: register rtx tmp;
1242:
1243: /* Emit a return insn, but only if control can fall through to here. */
1244:
1245: tmp = get_last_insn ();
1246: while (tmp)
1247: {
1248: if (GET_CODE (tmp) == BARRIER)
1249: return;
1250: if (GET_CODE (tmp) == CODE_LABEL)
1251: break;
1252: if (GET_CODE (tmp) == JUMP_INSN)
1253: {
1254: if (GET_CODE (PATTERN (tmp)) == RETURN)
1255: return;
1256: break;
1257: }
1258: if (GET_CODE (tmp) == NOTE)
1259: {
1260: tmp = PREV_INSN (tmp);
1261: continue;
1262: }
1263: break;
1264: }
1265: fprintf (file, "LR%d: ret\n", ret_label);
1266: return;
1267: }
1268:
1269: fprintf (file, "LR%d:\n", ret_label);
1270:
1271: fprintf (file, "\t#EPILOGUE#\n");
1272:
1273: /* Output the string created by the prologue which will restore all
1274: registers saved by the prologue. */
1275:
1276: if (epilogue_string[0] != '\0')
1277: fprintf (file, "%s", epilogue_string);
1278:
1279: /* Must clear g14 on return. */
1280:
1281: if (current_function_args_size != 0)
1282: fprintf (file, "\tmov 0,g14\n");
1283:
1284: fprintf (file, "\tret\n");
1285: fprintf (file, "\t#End Epilogue#\n");
1286: }
1287:
1288: /* Output code for a call insn. */
1289:
1290: char *
1291: i960_output_call_insn (target, argsize_rtx, arg_pointer, insn)
1292: register rtx target, argsize_rtx, arg_pointer, insn;
1293: {
1294: int argsize = INTVAL (argsize_rtx);
1295: rtx nexti = next_real_insn (insn);
1296: rtx operands[2];
1297:
1298: operands[0] = target;
1299: operands[1] = arg_pointer;
1300:
1301: if (current_function_args_size != 0)
1302: output_asm_insn ("mov g14,r3", operands);
1303:
1304: if (argsize > 48)
1305: output_asm_insn ("lda %a1,g14", operands);
1306: else if (current_function_args_size != 0)
1307: output_asm_insn ("mov 0,g14", operands);
1308:
1309: /* The code used to assume that calls to SYMBOL_REFs could not be more
1310: than 24 bits away (b vs bx, callj vs callx). This is not true. This
1311: feature is now implemented by relaxing in the GNU linker. It can convert
1312: bx to b if in range, and callx to calls/call/balx/bal as appropriate. */
1313:
1314: /* Nexti could be zero if the called routine is volatile. */
1315: if (optimize && (*epilogue_string == 0) && argsize == 0 && tail_call_ok
1316: && (nexti == 0 || GET_CODE (PATTERN (nexti)) == RETURN))
1317: {
1318: /* Delete following return insn. */
1319: if (nexti && no_labels_between_p (insn, nexti))
1320: delete_insn (nexti);
1321: output_asm_insn ("bx %0", operands);
1322: return "# notreached";
1323: }
1324:
1325: output_asm_insn ("callx %0", operands);
1326:
1327: if (current_function_args_size != 0)
1328: output_asm_insn ("mov r3,g14", operands);
1329:
1330: return "";
1331: }
1332:
1333: /* Output code for a return insn. */
1334:
1335: char *
1336: i960_output_ret_insn (insn)
1337: register rtx insn;
1338: {
1339: static char lbuf[20];
1340:
1341: if (*epilogue_string != 0)
1342: {
1343: if (! TARGET_CODE_ALIGN && next_real_insn (insn) == 0)
1344: return "";
1345:
1346: sprintf (lbuf, "b LR%d", ret_label);
1347: return lbuf;
1348: }
1349:
1350: if (current_function_args_size != 0)
1351: output_asm_insn ("mov 0,g14", 0);
1352:
1353: if (i960_leaf_ret_reg >= 0)
1354: {
1355: sprintf (lbuf, "bx (%s)", reg_names[i960_leaf_ret_reg]);
1356: return lbuf;
1357: }
1358: return "ret";
1359: }
1360:
1361: #if 0
1362: /* Return a character string representing the branch prediction
1363: opcode to be tacked on an instruction. This must at least
1364: return a null string. */
1365:
1366: char *
1367: i960_br_predict_opcode (lab_ref, insn)
1368: rtx lab_ref, insn;
1369: {
1370: if (TARGET_BRANCH_PREDICT)
1371: {
1372: unsigned long label_uid;
1373:
1374: if (GET_CODE (lab_ref) == CODE_LABEL)
1375: label_uid = INSN_UID (lab_ref);
1376: else if (GET_CODE (lab_ref) == LABEL_REF)
1377: label_uid = INSN_UID (XEXP (lab_ref, 0));
1378: else
1379: return ".f";
1380:
1381: /* If not optimizing, then the insn_addresses array will not be
1382: valid. In this case, always return ".t" since most branches
1383: are taken. If optimizing, return .t for backward branches
1384: and .f for forward branches. */
1385: if (! optimize
1386: || insn_addresses[label_uid] < insn_addresses[INSN_UID (insn)])
1387: return ".t";
1388: return ".f";
1389: }
1390:
1391: return "";
1392: }
1393: #endif
1394:
1395: /* Print the operand represented by rtx X formatted by code CODE. */
1396:
1397: void
1398: i960_print_operand (file, x, code)
1399: FILE *file;
1400: rtx x;
1401: char code;
1402: {
1403: enum rtx_code rtxcode = GET_CODE (x);
1404:
1405: if (rtxcode == REG)
1406: {
1407: switch (code)
1408: {
1409: case 'D':
1410: /* Second reg of a double. */
1411: fprintf (file, "%s", reg_names[REGNO (x)+1]);
1412: break;
1413:
1414: case 0:
1415: fprintf (file, "%s", reg_names[REGNO (x)]);
1416: break;
1417:
1418: default:
1419: abort ();
1420: }
1421: return;
1422: }
1423: else if (rtxcode == MEM)
1424: {
1425: output_address (XEXP (x, 0));
1426: return;
1427: }
1428: else if (rtxcode == CONST_INT)
1429: {
1430: if (INTVAL (x) > 9999 || INTVAL (x) < -999)
1431: fprintf (file, "0x%x", INTVAL (x));
1432: else
1433: fprintf (file, "%d", INTVAL (x));
1434: return;
1435: }
1436: else if (rtxcode == CONST_DOUBLE)
1437: {
1438: double d;
1439:
1440: if (x == CONST0_RTX (DFmode) || x == CONST0_RTX (SFmode))
1441: {
1442: fprintf (file, "0f0.0");
1443: return;
1444: }
1445: else if (x == CONST1_RTX (DFmode) || x == CONST1_RTX (SFmode))
1446: {
1447: fprintf (file, "0f1.0");
1448: return;
1449: }
1450:
1451: /* This better be a comment. */
1452: REAL_VALUE_FROM_CONST_DOUBLE (d, x);
1453: fprintf (file, "%#g", d);
1454: return;
1455: }
1456:
1457: switch(code)
1458: {
1459: case 'B':
1460: /* Branch or jump, depending on assembler. */
1461: if (TARGET_ASM_COMPAT)
1462: fputs ("j", file);
1463: else
1464: fputs ("b", file);
1465: break;
1466:
1467: case 'S':
1468: /* Sign of condition. */
1469: if ((rtxcode == EQ) || (rtxcode == NE) || (rtxcode == GTU)
1470: || (rtxcode == LTU) || (rtxcode == GEU) || (rtxcode == LEU))
1471: fputs ("o", file);
1472: else if ((rtxcode == GT) || (rtxcode == LT)
1473: || (rtxcode == GE) || (rtxcode == LE))
1474: fputs ("i", file);
1475: else
1476: abort();
1477: break;
1478:
1479: case 'I':
1480: /* Inverted condition. */
1481: rtxcode = reverse_condition (rtxcode);
1482: goto normal;
1483:
1484: case 'X':
1485: /* Inverted condition w/ reversed operands. */
1486: rtxcode = reverse_condition (rtxcode);
1487: /* Fallthrough. */
1488:
1489: case 'R':
1490: /* Reversed operand condition. */
1491: rtxcode = swap_condition (rtxcode);
1492: /* Fallthrough. */
1493:
1494: case 'C':
1495: /* Normal condition. */
1496: normal:
1497: if (rtxcode == EQ) { fputs ("e", file); return; }
1498: else if (rtxcode == NE) { fputs ("ne", file); return; }
1499: else if (rtxcode == GT) { fputs ("g", file); return; }
1500: else if (rtxcode == GTU) { fputs ("g", file); return; }
1501: else if (rtxcode == LT) { fputs ("l", file); return; }
1502: else if (rtxcode == LTU) { fputs ("l", file); return; }
1503: else if (rtxcode == GE) { fputs ("ge", file); return; }
1504: else if (rtxcode == GEU) { fputs ("ge", file); return; }
1505: else if (rtxcode == LE) { fputs ("le", file); return; }
1506: else if (rtxcode == LEU) { fputs ("le", file); return; }
1507: else abort ();
1508: break;
1509:
1510: case 0:
1511: output_addr_const (file, x);
1512: break;
1513:
1514: default:
1515: abort ();
1516: }
1517:
1518: return;
1519: }
1520:
1521: /* Print a memory address as an operand to reference that memory location.
1522:
1523: This is exactly the same as legitimate_address_p, except that it the prints
1524: addresses instead of recognizing them. */
1525:
1526: void
1527: i960_print_operand_addr (file, addr)
1528: FILE *file;
1529: register rtx addr;
1530: {
1531: rtx breg, ireg;
1532: rtx scale, offset;
1533:
1534: ireg = 0;
1535: breg = 0;
1536: offset = 0;
1537: scale = const1_rtx;
1538:
1539: if (GET_CODE (addr) == REG)
1540: breg = addr;
1541: else if (CONSTANT_P (addr))
1542: offset = addr;
1543: else if (GET_CODE (addr) == PLUS)
1544: {
1545: rtx op0, op1;
1546:
1547: op0 = XEXP (addr, 0);
1548: op1 = XEXP (addr, 1);
1549:
1550: if (GET_CODE (op0) == REG)
1551: {
1552: breg = op0;
1553: if (GET_CODE (op1) == REG)
1554: ireg = op1;
1555: else if (CONSTANT_P (op1))
1556: offset = op1;
1557: else
1558: abort ();
1559: }
1560: else if (GET_CODE (op0) == PLUS)
1561: {
1562: if (GET_CODE (XEXP (op0, 0)) == MULT)
1563: {
1564: ireg = XEXP (XEXP (op0, 0), 0);
1565: scale = XEXP (XEXP (op0, 0), 1);
1566: if (GET_CODE (XEXP (op0, 1)) == REG)
1567: {
1568: breg = XEXP (op0, 1);
1569: offset = op1;
1570: }
1571: else
1572: abort ();
1573: }
1574: else if (GET_CODE (XEXP (op0, 0)) == REG)
1575: {
1576: breg = XEXP (op0, 0);
1577: if (GET_CODE (XEXP (op0, 1)) == REG)
1578: {
1579: ireg = XEXP (op0, 1);
1580: offset = op1;
1581: }
1582: else
1583: abort ();
1584: }
1585: else
1586: abort ();
1587: }
1588: else if (GET_CODE (op0) == MULT)
1589: {
1590: ireg = XEXP (op0, 0);
1591: scale = XEXP (op0, 1);
1592: if (GET_CODE (op1) == REG)
1593: breg = op1;
1594: else if (CONSTANT_P (op1))
1595: offset = op1;
1596: else
1597: abort ();
1598: }
1599: else
1600: abort ();
1601: }
1602: else if (GET_CODE (addr) == MULT)
1603: {
1604: ireg = XEXP (addr, 0);
1605: scale = XEXP (addr, 1);
1606: }
1607: else
1608: abort ();
1609:
1610: if (offset)
1611: output_addr_const (file, offset);
1612: if (breg)
1613: fprintf (file, "(%s)", reg_names[REGNO (breg)]);
1614: if (ireg)
1615: fprintf (file, "[%s*%d]", reg_names[REGNO (ireg)], INTVAL (scale));
1616: }
1617:
1618: /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
1619: that is a valid memory address for an instruction.
1620: The MODE argument is the machine mode for the MEM expression
1621: that wants to use this address.
1622:
1623: On 80960, legitimate addresses are:
1624: base ld (g0),r0
1625: disp (12 or 32 bit) ld foo,r0
1626: base + index ld (g0)[g1*1],r0
1627: base + displ ld 0xf00(g0),r0
1628: base + index*scale + displ ld 0xf00(g0)[g1*4],r0
1629: index*scale + base ld (g0)[g1*4],r0
1630: index*scale + displ ld 0xf00[g1*4],r0
1631: index*scale ld [g1*4],r0
1632: index + base + displ ld 0xf00(g0)[g1*1],r0
1633:
1634: In each case, scale can be 1, 2, 4, 8, or 16. */
1635:
1636: /* This is exactly the same as i960_print_operand_addr, except that
1637: it recognizes addresses instead of printing them.
1638:
1639: It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
1640: convert common non-canonical forms to canonical form so that they will
1641: be recognized. */
1642:
1643: /* These two macros allow us to accept either a REG or a SUBREG anyplace
1644: where a register is valid. */
1645:
1646: #define RTX_OK_FOR_BASE_P(X, STRICT) \
1647: ((GET_CODE (X) == REG \
1648: && (STRICT ? REG_OK_FOR_BASE_P_STRICT (X) : REG_OK_FOR_BASE_P (X))) \
1649: || (GET_CODE (X) == SUBREG \
1650: && GET_CODE (SUBREG_REG (X)) == REG \
1651: && (STRICT ? REG_OK_FOR_BASE_P_STRICT (SUBREG_REG (X)) \
1652: : REG_OK_FOR_BASE_P (SUBREG_REG (X)))))
1653:
1654: #define RTX_OK_FOR_INDEX_P(X, STRICT) \
1655: ((GET_CODE (X) == REG \
1656: && (STRICT ? REG_OK_FOR_INDEX_P_STRICT (X) : REG_OK_FOR_INDEX_P (X)))\
1657: || (GET_CODE (X) == SUBREG \
1658: && GET_CODE (SUBREG_REG (X)) == REG \
1659: && (STRICT ? REG_OK_FOR_INDEX_P_STRICT (SUBREG_REG (X)) \
1660: : REG_OK_FOR_INDEX_P (SUBREG_REG (X)))))
1661:
1662: int
1663: legitimate_address_p (mode, addr, strict)
1664: enum machine_mode mode;
1665: register rtx addr;
1666: int strict;
1667: {
1668: if (RTX_OK_FOR_BASE_P (addr, strict))
1669: return 1;
1670: else if (CONSTANT_P (addr))
1671: return 1;
1672: else if (GET_CODE (addr) == PLUS)
1673: {
1674: rtx op0, op1;
1675:
1676: if (! TARGET_COMPLEX_ADDR && ! reload_completed)
1677: return 0;
1678:
1679: op0 = XEXP (addr, 0);
1680: op1 = XEXP (addr, 1);
1681:
1682: if (RTX_OK_FOR_BASE_P (op0, strict))
1683: {
1684: if (RTX_OK_FOR_INDEX_P (op1, strict))
1685: return 1;
1686: else if (CONSTANT_P (op1))
1687: return 1;
1688: else
1689: return 0;
1690: }
1691: else if (GET_CODE (op0) == PLUS)
1692: {
1693: if (GET_CODE (XEXP (op0, 0)) == MULT)
1694: {
1695: if (! (RTX_OK_FOR_INDEX_P (XEXP (XEXP (op0, 0), 0), strict)
1696: && SCALE_TERM_P (XEXP (XEXP (op0, 0), 1))))
1697: return 0;
1698:
1699: if (RTX_OK_FOR_BASE_P (XEXP (op0, 1), strict)
1700: && CONSTANT_P (op1))
1701: return 1;
1702: else
1703: return 0;
1704: }
1705: else if (RTX_OK_FOR_BASE_P (XEXP (op0, 0), strict))
1706: {
1707: if (RTX_OK_FOR_INDEX_P (XEXP (op0, 1), strict)
1708: && CONSTANT_P (op1))
1709: return 1;
1710: else
1711: return 0;
1712: }
1713: else
1714: return 0;
1715: }
1716: else if (GET_CODE (op0) == MULT)
1717: {
1718: if (! (RTX_OK_FOR_INDEX_P (XEXP (op0, 0), strict)
1719: && SCALE_TERM_P (XEXP (op0, 1))))
1720: return 0;
1721:
1722: if (RTX_OK_FOR_BASE_P (op1, strict))
1723: return 1;
1724: else if (CONSTANT_P (op1))
1725: return 1;
1726: else
1727: return 0;
1728: }
1729: else
1730: return 0;
1731: }
1732: else if (GET_CODE (addr) == MULT)
1733: {
1734: if (! TARGET_COMPLEX_ADDR && ! reload_completed)
1735: return 0;
1736:
1737: return (RTX_OK_FOR_INDEX_P (XEXP (addr, 0), strict)
1738: && SCALE_TERM_P (XEXP (addr, 1)));
1739: }
1740: else
1741: return 0;
1742: }
1743:
1744: /* Try machine-dependent ways of modifying an illegitimate address
1745: to be legitimate. If we find one, return the new, valid address.
1746: This macro is used in only one place: `memory_address' in explow.c.
1747:
1748: This converts some non-canonical addresses to canonical form so they
1749: can be recognized. */
1750:
1751: rtx
1752: legitimize_address (x, oldx, mode)
1753: register rtx x;
1754: register rtx oldx;
1755: enum machine_mode mode;
1756: {
1757: if (GET_CODE (x) == SYMBOL_REF)
1758: {
1759: abort ();
1760: x = copy_to_reg (x);
1761: }
1762:
1763: if (! TARGET_COMPLEX_ADDR && ! reload_completed)
1764: return x;
1765:
1766: /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
1767: into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
1768: created by virtual register instantiation, register elimination, and
1769: similar optimizations. */
1770: if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT
1771: && GET_CODE (XEXP (x, 1)) == PLUS)
1772: x = gen_rtx (PLUS, Pmode,
1773: gen_rtx (PLUS, Pmode, XEXP (x, 0), XEXP (XEXP (x, 1), 0)),
1774: XEXP (XEXP (x, 1), 1));
1775:
1776: /* Canonicalize (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
1777: into (plus (plus (mult (reg) (const)) (reg)) (const)). */
1778: else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
1779: && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
1780: && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
1781: && CONSTANT_P (XEXP (x, 1)))
1782: {
1783: rtx constant, other;
1784:
1785: if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1786: {
1787: constant = XEXP (x, 1);
1788: other = XEXP (XEXP (XEXP (x, 0), 1), 1);
1789: }
1790: else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
1791: {
1792: constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
1793: other = XEXP (x, 1);
1794: }
1795: else
1796: constant = 0;
1797:
1798: if (constant)
1799: x = gen_rtx (PLUS, Pmode,
1800: gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0),
1801: XEXP (XEXP (XEXP (x, 0), 1), 0)),
1802: plus_constant (other, INTVAL (constant)));
1803: }
1804:
1805: return x;
1806: }
1807:
1808: #if 0
1809: /* Return the most stringent alignment that we are willing to consider
1810: objects of size SIZE and known alignment ALIGN as having. */
1811:
1812: int
1813: i960_alignment (size, align)
1814: int size;
1815: int align;
1816: {
1817: int i;
1818:
1819: if (! TARGET_STRICT_ALIGN)
1820: if (TARGET_IC_COMPAT2_0 || align >= 4)
1821: {
1822: i = i960_object_bytes_bitalign (size) / BITS_PER_UNIT;
1823: if (i > align)
1824: align = i;
1825: }
1826:
1827: return align;
1828: }
1829: #endif
1830:
1831: /* Modes for condition codes. */
1832: #define C_MODES \
1833: ((1 << (int) CCmode) | (1 << (int) CC_UNSmode) | (1<< (int) CC_CHKmode))
1834:
1835: /* Modes for single-word (and smaller) quantities. */
1836: #define S_MODES \
1837: (~C_MODES \
1838: & ~ ((1 << (int) DImode) | (1 << (int) TImode) \
1839: | (1 << (int) DFmode) | (1 << (int) TFmode)))
1840:
1841: /* Modes for double-word (and smaller) quantities. */
1842: #define D_MODES \
1843: (~C_MODES \
1844: & ~ ((1 << (int) TImode) | (1 << (int) TFmode)))
1845:
1846: /* Modes for quad-word quantities. */
1847: #define T_MODES (~C_MODES)
1848:
1849: /* Modes for single-float quantities. */
1850: #define SF_MODES ((1 << (int) SFmode))
1851:
1852: /* Modes for double-float quantities. */
1853: #define DF_MODES (SF_MODES | (1 << (int) DFmode) | (1 << (int) SCmode))
1854:
1855: /* Modes for quad-float quantities. */
1856: #define TF_MODES (DF_MODES | (1 << (int) TFmode) | (1 << (int) DCmode))
1857:
1858: unsigned int hard_regno_mode_ok[FIRST_PSEUDO_REGISTER] = {
1859: T_MODES, S_MODES, D_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
1860: T_MODES, S_MODES, D_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
1861: T_MODES, S_MODES, D_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
1862: T_MODES, S_MODES, D_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
1863:
1864: TF_MODES, TF_MODES, TF_MODES, TF_MODES, C_MODES};
1865:
1866:
1867: /* Return the minimum alignment of an expression rtx X in bytes. This takes
1868: advantage of machine specific facts, such as knowing that the frame pointer
1869: is always 16 byte aligned. */
1870:
1871: int
1872: i960_expr_alignment (x, size)
1873: rtx x;
1874: int size;
1875: {
1876: int align = 1;
1877:
1878: if (x == 0)
1879: return 1;
1880:
1881: switch (GET_CODE(x))
1882: {
1883: case CONST_INT:
1884: align = INTVAL(x);
1885:
1886: if ((align & 0xf) == 0)
1887: align = 16;
1888: else if ((align & 0x7) == 0)
1889: align = 8;
1890: else if ((align & 0x3) == 0)
1891: align = 4;
1892: else if ((align & 0x1) == 0)
1893: align = 2;
1894: else
1895: align = 1;
1896: break;
1897:
1898: case PLUS:
1899: align = MIN (i960_expr_alignment (XEXP (x, 0), size),
1900: i960_expr_alignment (XEXP (x, 1), size));
1901: break;
1902:
1903: case SYMBOL_REF:
1904: /* If this is a valid program, objects are guaranteed to be
1905: correctly aligned for whatever size the reference actually is. */
1906: align = i960_object_bytes_bitalign (size) / BITS_PER_UNIT;
1907: break;
1908:
1909: case REG:
1910: if (REGNO (x) == FRAME_POINTER_REGNUM)
1911: align = 16;
1912: break;
1913:
1914: case ASHIFT:
1915: case LSHIFT:
1916: align = i960_expr_alignment (XEXP (x, 0));
1917:
1918: if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1919: {
1920: align = align << INTVAL (XEXP (x, 1));
1921: align = MIN (align, 16);
1922: }
1923: break;
1924:
1925: case MULT:
1926: align = (i960_expr_alignment (XEXP (x, 0), size) *
1927: i960_expr_alignment (XEXP (x, 1), size));
1928:
1929: align = MIN (align, 16);
1930: break;
1931: }
1932:
1933: return align;
1934: }
1935:
1936: /* Return true if it is possible to reference both BASE and OFFSET, which
1937: have alignment at least as great as 4 byte, as if they had alignment valid
1938: for an object of size SIZE. */
1939:
1940: int
1941: i960_improve_align (base, offset, size)
1942: rtx base;
1943: rtx offset;
1944: int size;
1945: {
1946: int i, j;
1947:
1948: /* We have at least a word reference to the object, so we know it has to
1949: be aligned at least to 4 bytes. */
1950:
1951: i = MIN (i960_expr_alignment (base, 4),
1952: i960_expr_alignment (offset, 4));
1953:
1954: i = MAX (i, 4);
1955:
1956: /* We know the size of the request. If strict align is not enabled, we
1957: can guess that the alignment is OK for the requested size. */
1958:
1959: if (! TARGET_STRICT_ALIGN)
1960: if ((j = (i960_object_bytes_bitalign (size) / BITS_PER_UNIT)) > i)
1961: i = j;
1962:
1963: return (i >= size);
1964: }
1965:
1966: /* Return true if it is possible to access BASE and OFFSET, which have 4 byte
1967: (SImode) alignment as if they had 16 byte (TImode) alignment. */
1968:
1969: int
1970: i960_si_ti (base, offset)
1971: rtx base;
1972: rtx offset;
1973: {
1974: return i960_improve_align (base, offset, 16);
1975: }
1976:
1977: /* Return true if it is possible to access BASE and OFFSET, which have 4 byte
1978: (SImode) alignment as if they had 8 byte (DImode) alignment. */
1979:
1980: int
1981: i960_si_di (base, offset)
1982: rtx base;
1983: rtx offset;
1984: {
1985: return i960_improve_align (base, offset, 8);
1986: }
1987:
1988: /* Return raw values of size and alignment (in words) for the data
1989: type being accessed. These values will be rounded by the caller. */
1990:
1991: static void
1992: i960_arg_size_and_align (mode, type, size_out, align_out)
1993: enum machine_mode mode;
1994: tree type;
1995: int *size_out;
1996: int *align_out;
1997: {
1998: int size, align;
1999:
2000: /* Use formal alignment requirements of type being passed, except make
2001: it at least a word. If we don't have a type, this is a library call,
2002: and the parm has to be of scalar type. In this case, consider its
2003: formal alignment requirement to be its size in words. */
2004:
2005: if (mode == BLKmode)
2006: size = (int_size_in_bytes (type) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2007: else if (mode == VOIDmode)
2008: {
2009: /* End of parm list. */
2010: assert (type != 0 && TYPE_MODE (type) == VOIDmode);
2011: size = 1;
2012: }
2013: else
2014: size = (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2015:
2016: if (type == 0)
2017: align = size;
2018: else if (TYPE_ALIGN (type) >= BITS_PER_WORD)
2019: align = TYPE_ALIGN (type) / BITS_PER_WORD;
2020: else
2021: align = 1;
2022:
2023: *size_out = size;
2024: *align_out = align;
2025: }
2026:
2027: /* On the 80960 the first 12 args are in registers and the rest are pushed.
2028: Any arg that is bigger than 4 words is placed on the stack and all
2029: subsequent arguments are placed on the stack.
2030:
2031: Additionally, parameters with an alignment requirement stronger than
2032: a word must be be aligned appropriately. */
2033:
2034: /* Update CUM to advance past an argument described by MODE and TYPE. */
2035:
2036: void
2037: i960_function_arg_advance (cum, mode, type, named)
2038: CUMULATIVE_ARGS *cum;
2039: enum machine_mode mode;
2040: tree type;
2041: int named;
2042: {
2043: int size, align;
2044:
2045: i960_arg_size_and_align (mode, type, &size, &align);
2046:
2047: if (named == 0 || size > 4 || cum->ca_nstackparms != 0
2048: || (size + ROUND_PARM (cum->ca_nregparms, align)) > NPARM_REGS
2049: || MUST_PASS_IN_STACK (mode, type))
2050: cum->ca_nstackparms = ROUND_PARM (cum->ca_nstackparms, align) + size;
2051: else
2052: cum->ca_nregparms = ROUND_PARM (cum->ca_nregparms, align) + size;
2053: }
2054:
2055: /* Return the register that the argument described by MODE and TYPE is
2056: passed in, or else return 0 if it is passed on the stack. */
2057:
2058: rtx
2059: i960_function_arg (cum, mode, type, named)
2060: CUMULATIVE_ARGS *cum;
2061: enum machine_mode mode;
2062: tree type;
2063: int named;
2064: {
2065: rtx ret;
2066: int size, align;
2067:
2068: i960_arg_size_and_align (mode, type, &size, &align);
2069:
2070: if (named == 0 || size > 4 || cum->ca_nstackparms != 0
2071: || (size + ROUND_PARM (cum->ca_nregparms, align)) > NPARM_REGS
2072: || MUST_PASS_IN_STACK (mode, type))
2073: {
2074: cum->ca_nstackparms = ROUND_PARM (cum->ca_nstackparms, align);
2075: ret = 0;
2076: }
2077: else
2078: {
2079: cum->ca_nregparms = ROUND_PARM (cum->ca_nregparms, align);
2080: ret = gen_rtx (REG, mode, cum->ca_nregparms);
2081: }
2082:
2083: return ret;
2084: }
2085:
2086: /* Floating-point support. */
2087:
2088: void
2089: i960_output_double (file, value)
2090: FILE *file;
2091: double value;
2092: {
2093: if (REAL_VALUE_ISINF (value))
2094: {
2095: fprintf (file, "\t.word 0\n");
2096: fprintf (file, "\t.word 0x7ff00000 # Infinity\n");
2097: }
2098: else
2099: fprintf (file, "\t.double 0d%.17e\n", (value));
2100: }
2101:
2102: void
2103: i960_output_float (file, value)
2104: FILE *file;
2105: double value;
2106: {
2107: if (REAL_VALUE_ISINF (value))
2108: fprintf (file, "\t.word 0x7f800000 # Infinity\n");
2109: else
2110: fprintf (file, "\t.float 0f%.12e\n", (value));
2111: }
2112:
2113: /* Return the number of bits that an object of size N bytes is aligned to. */
2114:
2115: int
2116: i960_object_bytes_bitalign (n)
2117: int n;
2118: {
2119: if (n > 8) n = 128;
2120: else if (n > 4) n = 64;
2121: else if (n > 2) n = 32;
2122: else if (n > 1) n = 16;
2123: else n = 8;
2124:
2125: return n;
2126: }
2127:
2128: /* Compute the size of an aggregate type TSIZE. */
2129:
2130: tree
2131: i960_round_size (tsize)
2132: tree tsize;
2133: {
2134: int size, byte_size, align;
2135:
2136: if (TREE_CODE (tsize) != INTEGER_CST)
2137: return tsize;
2138:
2139: size = TREE_INT_CST_LOW (tsize);
2140: byte_size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
2141: align = i960_object_bytes_bitalign (byte_size);
2142:
2143: /* Handle #pragma align. */
2144: if (align > i960_maxbitalignment)
2145: align = i960_maxbitalignment;
2146:
2147: if (size % align)
2148: size = ((size / align) + 1) * align;
2149:
2150: return size_int (size);
2151: }
2152:
2153: /* Compute the alignment for an aggregate type TSIZE. */
2154:
2155: int
2156: i960_round_align (align, tsize)
2157: int align;
2158: tree tsize;
2159: {
2160: int byte_size;
2161:
2162: if (TREE_CODE (tsize) != INTEGER_CST)
2163: return align;
2164:
2165: byte_size = (TREE_INT_CST_LOW (tsize) + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
2166: align = i960_object_bytes_bitalign (byte_size);
2167: return align;
2168: }
2169:
2170: /* Do any needed setup for a varargs function. For the i960, we must
2171: create a register parameter block if one doesn't exist, and then copy
2172: all register parameters to memory. */
2173:
2174: void
2175: i960_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
2176: CUMULATIVE_ARGS *cum;
2177: enum machine_mode mode;
2178: tree type;
2179: int *pretend_size;
2180: int no_rtl;
2181: {
2182: if (cum->ca_nregparms < NPARM_REGS)
2183: {
2184: int first_reg_offset = cum->ca_nregparms;
2185:
2186: if (first_reg_offset > NPARM_REGS)
2187: first_reg_offset = NPARM_REGS;
2188:
2189: if (! (no_rtl) && first_reg_offset != NPARM_REGS)
2190: {
2191: rtx label = gen_label_rtx ();
2192: emit_insn (gen_cmpsi (arg_pointer_rtx, const0_rtx));
2193: emit_jump_insn (gen_bne (label));
2194: emit_insn (gen_rtx (SET, VOIDmode, arg_pointer_rtx,
2195: stack_pointer_rtx));
2196: emit_insn (gen_rtx (SET, VOIDmode, stack_pointer_rtx,
2197: memory_address (SImode,
2198: plus_constant (stack_pointer_rtx,
2199: 48))));
2200: emit_label (label);
2201: move_block_from_reg
2202: (first_reg_offset,
2203: gen_rtx (MEM, BLKmode, virtual_incoming_args_rtx),
2204: NPARM_REGS - first_reg_offset,
2205: (NPARM_REGS - first_reg_offset) * UNITS_PER_WORD);
2206: }
2207: *pretend_size = (NPARM_REGS - first_reg_offset) * UNITS_PER_WORD;
2208: }
2209: }
2210:
2211: /* Calculate the final size of the reg parm stack space for the current
2212: function, based on how many bytes would be allocated on the stack. */
2213:
2214: int
2215: i960_final_reg_parm_stack_space (const_size, var_size)
2216: int const_size;
2217: tree var_size;
2218: {
2219: if (var_size || const_size > 48)
2220: return 48;
2221: else
2222: return 0;
2223: }
2224:
2225: /* Calculate the size of the reg parm stack space. This is a bit complicated
2226: on the i960. */
2227:
2228: int
2229: i960_reg_parm_stack_space (fndecl)
2230: tree fndecl;
2231: {
2232: /* In this case, we are called from emit_library_call, and we don't need
2233: to pretend we have more space for parameters than what's apparent. */
2234: if (fndecl == 0)
2235: return 0;
2236:
2237: /* In this case, we are called from locate_and_pad_parms when we're
2238: not IN_REGS, so we have an arg block. */
2239: if (fndecl != current_function_decl)
2240: return 48;
2241:
2242: /* Otherwise, we have an arg block if the current function has more than
2243: 48 bytes of parameters. */
2244: if (current_function_args_size != 0)
2245: return 48;
2246: else
2247: return 0;
2248: }
2249:
2250: /* Return the register class of a scratch register needed to copy IN into
2251: or out of a register in CLASS in MODE. If it can be done directly,
2252: NO_REGS is returned. */
2253:
2254: enum reg_class
2255: secondary_reload_class (class, mode, in)
2256: enum reg_class class;
2257: enum machine_mode mode;
2258: rtx in;
2259: {
2260: int regno = -1;
2261:
2262: if (GET_CODE (in) == REG || GET_CODE (in) == SUBREG)
2263: regno = true_regnum (in);
2264:
2265: /* We can place anything into LOCAL_OR_GLOBAL_REGS and can put
2266: LOCAL_OR_GLOBAL_REGS into anything. */
2267: if (class == LOCAL_OR_GLOBAL_REGS || class == LOCAL_REGS
2268: || class == GLOBAL_REGS || (regno >= 0 && regno < 32))
2269: return NO_REGS;
2270:
2271: /* We can place any hard register, 0.0, and 1.0 into FP_REGS. */
2272: if (class == FP_REGS
2273: && ((regno >= 0 && regno < FIRST_PSEUDO_REGISTER)
2274: || in == CONST0_RTX (mode) || in == CONST1_RTX (mode)))
2275: return NO_REGS;
2276:
2277: return LOCAL_OR_GLOBAL_REGS;
2278: }
2279:
2280: /* Look at the opcode P, and set i96_last_insn_type to indicate which
2281: function unit it executed on. */
2282:
2283: /* ??? This would make more sense as an attribute. */
2284:
2285: void
2286: i960_scan_opcode (p)
2287: char *p;
2288: {
2289: switch (*p)
2290: {
2291: case 'a':
2292: case 'd':
2293: case 'e':
2294: case 'm':
2295: case 'n':
2296: case 'o':
2297: case 'r':
2298: /* Ret is not actually of type REG, but it won't matter, because no
2299: insn will ever follow it. */
2300: case 'u':
2301: case 'x':
2302: i960_last_insn_type = I_TYPE_REG;
2303: break;
2304:
2305: case 'b':
2306: if (p[1] == 'x' || p[3] == 'x')
2307: i960_last_insn_type = I_TYPE_MEM;
2308: i960_last_insn_type = I_TYPE_CTRL;
2309: break;
2310:
2311: case 'f':
2312: case 't':
2313: i960_last_insn_type = I_TYPE_CTRL;
2314: break;
2315:
2316: case 'c':
2317: if (p[1] == 'a')
2318: {
2319: if (p[4] == 'x')
2320: i960_last_insn_type = I_TYPE_MEM;
2321: else
2322: i960_last_insn_type = I_TYPE_CTRL;
2323: }
2324: else if (p[1] == 'm')
2325: {
2326: if (p[3] == 'd')
2327: i960_last_insn_type = I_TYPE_REG;
2328: else if (p[4] == 'b' || p[4] == 'j')
2329: i960_last_insn_type = I_TYPE_CTRL;
2330: else
2331: i960_last_insn_type = I_TYPE_REG;
2332: }
2333: else
2334: i960_last_insn_type = I_TYPE_REG;
2335: break;
2336:
2337: case 'l':
2338: i960_last_insn_type = I_TYPE_MEM;
2339: break;
2340:
2341: case 's':
2342: if (p[1] == 't')
2343: i960_last_insn_type = I_TYPE_MEM;
2344: else
2345: i960_last_insn_type = I_TYPE_REG;
2346: break;
2347: }
2348: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.