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