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