|
|
1.1 root 1: /* Subroutines used for code generation on intel 80960.
2: Copyright (C) 1992 Free Software Foundation, Inc.
3: Contributed by Steven McGeady, Intel Corp.
4: Additional Work by Glenn Colon-Bonet, Jonathan Shapiro, Andy Wilson
5: Converted to GCC 2.0 by Jim Wilson and Michael Tiemann, Cygnus Support.
6:
7: This file is part of GNU CC.
8:
9: GNU CC is free software; you can redistribute it and/or modify
10: it under the terms of the GNU General Public License as published by
11: the Free Software Foundation; either version 2, or (at your option)
12: any later version.
13:
14: GNU CC is distributed in the hope that it will be useful,
15: but WITHOUT ANY WARRANTY; without even the implied warranty of
16: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17: GNU General Public License for more details.
18:
19: You should have received a copy of the GNU General Public License
20: along with GNU CC; see the file COPYING. If not, write to
21: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22:
23: #include <stdio.h>
24:
25: #include "config.h"
26: #include "rtl.h"
27: #include "regs.h"
28: #include "hard-reg-set.h"
29: #include "real.h"
30: #include "insn-config.h"
31: #include "conditions.h"
32: #include "insn-flags.h"
33: #include "output.h"
34: #include "insn-attr.h"
35: #include "flags.h"
36: #include "tree.h"
37: #include "insn-codes.h"
38: #include "assert.h"
39: #include "expr.h"
40: #include "function.h"
41: #include "recog.h"
42: #include <math.h>
43:
44: /* Save the operands last given to a compare for use when we
45: generate a scc or bcc insn. */
46:
47: rtx i960_compare_op0, i960_compare_op1;
48:
49: /* Used to implement #pragma align/noalign. Initialized by OVERRIDE_OPTIONS
50: macro in i960.h. */
51:
52: static int i960_maxbitalignment;
53: static int i960_last_maxbitalignment;
54:
55: /* Used to implement switching between MEM and ALU insn types, for better
56: C series performance. */
57:
58: enum insn_types i960_last_insn_type;
59:
60: /* The leaf-procedure return register. Set only if this is a leaf routine. */
61:
62: static int i960_leaf_ret_reg;
63:
64: /* True if replacing tail calls with jumps is OK. */
65:
66: static int tail_call_ok;
67:
68: /* A string containing a list of insns to emit in the epilogue so as to
69: restore all registers saved by the prologue. Created by the prologue
70: code as it saves registers away. */
71:
72: char epilogue_string[1000];
73:
74: /* A unique number (per function) for return labels. */
75:
76: static int ret_label = 0;
77:
78: #if 0
79: /* Handle pragmas for compatibility with Intel's compilers. */
80:
81: /* ??? This is incomplete, since it does not handle all pragmas that the
82: intel compilers understand. Also, it needs to be rewritten to accept
83: a stream instead of a string for GCC 2. */
84:
85: void
86: process_pragma(str)
87: char *str;
88: {
89: int align;
90: int i;
91:
92: if ((i = sscanf (str, " align %d", &align)) == 1)
93: switch (align)
94: {
95: case 0: /* Return to last alignment. */
96: align = i960_last_maxbitalignment / 8;
97:
98: case 16: /* Byte alignments. */
99: case 8:
100: case 4:
101: case 2:
102: case 1:
103: i960_last_maxbitalignment = i960_maxbitalignment;
104: i960_maxbitalignment = align * 8;
105: break;
106:
107: default: /* Unknown, silently ignore. */
108: break;
109: }
110:
111: /* NOTE: ic960 R3.0 pragma align definition:
112:
113: #pragma align [(size)] | (identifier=size[,...])
114: #pragma noalign [(identifier)[,...]]
115:
116: (all parens are optional)
117:
118: - size is [1,2,4,8,16]
119: - noalign means size==1
120: - applies only to component elements of a struct (and union?)
121: - identifier applies to structure tag (only)
122: - missing identifier means next struct
123:
124: - alignment rules for bitfields need more investigation */
125:
126: /* Should be pragma 'far' or equivalent for callx/balx here. */
127: }
128: #endif
129:
130: /* Initialize variables before compiling any files. */
131:
132: void
133: i960_initialize ()
134: {
135: if (TARGET_IC_COMPAT2_0)
136: {
137: i960_maxbitalignment = 8;
138: i960_last_maxbitalignment = 128;
139: }
140: else
141: {
142: i960_maxbitalignment = 128;
143: i960_last_maxbitalignment = 8;
144: }
145: }
146:
147: /* Return true if OP can be used as the source of an fp move insn. */
148:
149: int
150: fpmove_src_operand (op, mode)
151: rtx op;
152: enum machine_mode mode;
153: {
154: return (GET_CODE (op) == CONST_DOUBLE || general_operand (op, mode));
155: }
156:
157: #if 0
158: /* Return true if OP is a register or zero. */
159:
160: int
161: reg_or_zero_operand (op, mode)
162: rtx op;
163: enum machine_mode mode;
164: {
165: return register_operand (op, mode) || op == const0_rtx;
166: }
167: #endif
168:
169: /* Return truth value of whether OP can be used as an operands in a three
170: address arithmetic insn (such as add %o1,7,%l2) of mode MODE. */
171:
172: int
173: arith_operand (op, mode)
174: rtx op;
175: enum machine_mode mode;
176: {
177: return (register_operand (op, mode) || literal (op, mode));
178: }
179:
180: /* Return true if OP is a register or a valid floating point literal. */
181:
182: int
183: fp_arith_operand (op, mode)
184: rtx op;
185: enum machine_mode mode;
186: {
187: return (register_operand (op, mode) || fp_literal (op, mode));
188: }
189:
190: /* Return true is OP is a register or a valid signed integer literal. */
191:
192: int
193: signed_arith_operand (op, mode)
194: rtx op;
195: enum machine_mode mode;
196: {
197: return (register_operand (op, mode) || signed_literal (op, mode));
198: }
199:
200: /* Return truth value of whether OP is a integer which fits the
201: range constraining immediate operands in three-address insns. */
202:
203: int
204: literal (op, mode)
205: rtx op;
206: enum machine_mode mode;
207: {
208: return ((GET_CODE (op) == CONST_INT) && INTVAL(op) >= 0 && INTVAL(op) < 32);
209: }
210:
211: /* Return true if OP is a float constant of 1. */
212:
213: int
214: fp_literal_one (op, mode)
215: rtx op;
216: enum machine_mode mode;
217: {
218: return (TARGET_NUMERICS && (mode == VOIDmode || mode == GET_MODE (op))
219: && (op == CONST1_RTX (mode)));
220: }
221:
222: /* Return true if OP is a float constant of 0. */
223:
224: int
225: fp_literal_zero (op, mode)
226: rtx op;
227: enum machine_mode mode;
228: {
229: return (TARGET_NUMERICS && (mode == VOIDmode || mode == GET_MODE (op))
230: && (op == CONST0_RTX (mode)));
231: }
232:
233: /* Return true if OP is a valid floating point literal. */
234:
235: int
236: fp_literal(op, mode)
237: rtx op;
238: enum machine_mode mode;
239: {
240: return fp_literal_zero (op, mode) || fp_literal_one (op, mode);
241: }
242:
243: /* Return true if OP is a valid signed immediate constant. */
244:
245: int
246: signed_literal(op, mode)
247: rtx op;
248: enum machine_mode mode;
249: {
250: return ((GET_CODE (op) == CONST_INT) && INTVAL(op) > -32 && INTVAL(op) < 32);
251: }
252:
253: /* Return truth value of statement that OP is a symbolic memory
254: operand of mode MODE. */
255:
256: int
257: symbolic_memory_operand (op, mode)
258: rtx op;
259: enum machine_mode mode;
260: {
261: if (GET_CODE (op) == SUBREG)
262: op = SUBREG_REG (op);
263: if (GET_CODE (op) != MEM)
264: return 0;
265: op = XEXP (op, 0);
266: return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
267: || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
268: }
269:
270: /* Return truth value of whether OP is EQ or NE. */
271:
272: int
273: eq_or_neq (op, mode)
274: rtx op;
275: enum machine_mode mode;
276: {
277: return (GET_CODE (op) == EQ || GET_CODE (op) == NE);
278: }
279:
280: /* OP is an integer register or a constant. */
281:
282: int
283: arith32_operand (op, mode)
284: rtx op;
285: enum machine_mode mode;
286: {
287: if (register_operand (op, mode))
288: return 1;
289: return (CONSTANT_P (op));
290: }
291:
292: /* Return true if OP is an integer constant which is a power of 2. */
293:
294: int
295: power2_operand (op,mode)
296: rtx op;
297: enum machine_mode mode;
298: {
299: if (GET_CODE(op) != CONST_INT)
300: return 0;
301:
302: return exact_log2 (INTVAL (op)) >= 0;
303: }
304:
305: /* If VAL has only one bit set, return the index of that bit. Otherwise
306: return -1. */
307:
308: int
309: bitpos (val)
310: unsigned int val;
311: {
312: register int i;
313:
314: for (i = 0; val != 0; i++, val >>= 1)
315: {
316: if (val & 1)
317: {
318: if (val != 1)
319: return -1;
320: return i;
321: }
322: }
323: return -1;
324: }
325:
326: /* Return non-zero if OP is a mask, i.e. all one bits are consecutive.
327: The return value indicates how many consecutive non-zero bits exist
328: if this is a mask. This is the same as the next function, except that
329: it does not indicate what the start and stop bit positions are. */
330:
331: int
332: is_mask (val)
333: unsigned int val;
334: {
335: register int start, end, i;
336:
337: start = -1;
338: for (i = 0; val != 0; val >>= 1, i++)
339: {
340: if (val & 1)
341: {
342: if (start < 0)
343: start = i;
344:
345: end = i;
346: continue;
347: }
348: /* Still looking for the first bit. */
349: if (start < 0)
350: continue;
351:
352: /* We've seen the start of a bit sequence, and now a zero. There
353: must be more one bits, otherwise we would have exited the loop.
354: Therefore, it is not a mask. */
355: if (val)
356: return 0;
357: }
358:
359: /* The bit string has ones from START to END bit positions only. */
360: return end - start + 1;
361: }
362:
363: /* If VAL is a mask, then return nonzero, with S set to the starting bit
364: position and E set to the ending bit position of the mask. The return
365: value indicates how many consecutive bits exist in the mask. This is
366: the same as the previous function, except that it also indicates the
367: start and end bit positions of the mask. */
368:
369: int
370: bitstr (val, s, e)
371: unsigned int val;
372: int *s, *e;
373: {
374: register int start, end, i;
375:
376: start = -1;
377: end = -1;
378: for (i = 0; val != 0; val >>= 1, i++)
379: {
380: if (val & 1)
381: {
382: if (start < 0)
383: start = i;
384:
385: end = i;
386: continue;
387: }
388:
389: /* Still looking for the first bit. */
390: if (start < 0)
391: continue;
392:
393: /* We've seen the start of a bit sequence, and now a zero. There
394: must be more one bits, otherwise we would have exited the loop.
395: Therefor, it is not a mask. */
396: if (val)
397: {
398: start = -1;
399: end = -1;
400: break;
401: }
402: }
403:
404: /* The bit string has ones from START to END bit positions only. */
405: *s = start;
406: *e = end;
407: return ((start < 0) ? 0 : end - start + 1);
408: }
409:
410: /* Return the machine mode to use for a comparison. */
411:
412: enum machine_mode
413: select_cc_mode (op, x)
414: RTX_CODE op;
415: rtx x;
416: {
417: if (op == GTU || op == LTU || op == GEU || op == LEU)
418: return CC_UNSmode;
419: return CCmode;
420: }
421:
422: /* X and Y are two things to compare using CODE. Emit the compare insn and
423: return the rtx for register 36 in the proper mode. */
424:
425: rtx
426: gen_compare_reg (code, x, y)
427: enum rtx_code code;
428: rtx x, y;
429: {
430: rtx cc_reg;
1.1.1.2 ! root 431: enum machine_mode ccmode = SELECT_CC_MODE (code, x, y);
1.1 root 432: enum machine_mode mode
433: = GET_MODE (x) == VOIDmode ? GET_MODE (y) : GET_MODE (x);
434:
435: if (mode == SImode)
436: {
437: if (! arith_operand (x, mode))
438: x = force_reg (SImode, x);
439: if (! arith_operand (y, mode))
440: y = force_reg (SImode, y);
441: }
442:
443: cc_reg = gen_rtx (REG, ccmode, 36);
444: emit_insn (gen_rtx (SET, VOIDmode, cc_reg,
445: gen_rtx (COMPARE, ccmode, x, y)));
446:
447: return cc_reg;
448: }
449:
450: /* For the i960, REG is cost 1, REG+immed CONST is cost 2, REG+REG is cost 2,
451: REG+nonimmed CONST is cost 4. REG+SYMBOL_REF, SYMBOL_REF, and similar
452: are 4. Indexed addresses are cost 6. */
453:
454: /* ??? Try using just RTX_COST, i.e. not defining ADDRESS_COST. */
455:
456: int
457: i960_address_cost (x)
458: rtx x;
459: {
460: #if 0
461: /* Handled before calling here. */
462: if (GET_CODE (x) == REG)
463: return 1;
464: #endif
465: if (GET_CODE (x) == PLUS)
466: {
467: rtx base = XEXP (x, 0);
468: rtx offset = XEXP (x, 1);
469:
470: if (GET_CODE (base) == SUBREG)
471: base = SUBREG_REG (base);
472: if (GET_CODE (offset) == SUBREG)
473: offset = SUBREG_REG (offset);
474:
475: if (GET_CODE (base) == REG)
476: {
477: if (GET_CODE (offset) == REG)
478: return 2;
479: if (GET_CODE (offset) == CONST_INT)
480: {
481: if ((unsigned)INTVAL (offset) < 2047)
482: return 2;
483: return 4;
484: }
485: if (CONSTANT_P (offset))
486: return 4;
487: }
488: if (GET_CODE (base) == PLUS || GET_CODE (base) == MULT)
489: return 6;
490:
1.1.1.2 ! root 491: /* This is an invalid address. The return value doesn't matter, but
! 492: for convenience we make this more expensive than anything else. */
! 493: return 12;
1.1 root 494: }
495: if (GET_CODE (x) == MULT)
496: return 6;
497:
498: /* Symbol_refs and other unrecognized addresses are cost 4. */
499: return 4;
500: }
501:
502: /* Emit insns to move operands[1] into operands[0].
503:
504: Return 1 if we have written out everything that needs to be done to
505: do the move. Otherwise, return 0 and the caller will emit the move
506: normally. */
507:
508: int
509: emit_move_sequence (operands, mode)
510: rtx *operands;
511: enum machine_mode mode;
512: {
513: register rtx operand0 = operands[0];
514: register rtx operand1 = operands[1];
515:
516: /* We can only store registers to memory. */
517:
518: if (GET_CODE (operand0) == MEM && GET_CODE (operand1) != REG)
519: operands[1] = force_reg (mode, operand1);
520:
521: return 0;
522: }
523:
524: /* Emit insns to load a constant. Uses several strategies to try to use
525: as few insns as possible. */
526:
527: char *
528: i960_output_ldconst (dst, src)
529: register rtx dst, src;
530: {
531: register int rsrc1;
532: register unsigned rsrc2;
533: enum machine_mode mode = GET_MODE (dst);
534: rtx operands[4];
535: union { long l[2]; double d; } x;
536:
537: operands[0] = operands[2] = dst;
538: operands[1] = operands[3] = src;
539:
540: /* Anything that isn't a compile time constant, such as a SYMBOL_REF,
541: must be a ldconst insn. */
542:
543: if (GET_CODE (src) != CONST_INT && GET_CODE (src) != CONST_DOUBLE)
544: {
545: output_asm_insn ("ldconst %1,%0", operands);
546: return "";
547: }
548: else if (mode == DFmode)
549: {
550: rtx first, second;
551:
552: if (fp_literal_zero (src, VOIDmode))
553: {
554: if (FP_REG_P (dst))
555: return "movrl %1,%0";
556: else
557: return "movl 0,%0";
558: }
559:
560: #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
561: split_double (src, &first, &second);
562:
563: output_asm_insn ("# ldconst %1,%0",operands);
564:
565: operands[0] = gen_rtx (REG, SImode, REGNO (dst));
566: operands[1] = first;
567: output_asm_insn (i960_output_ldconst (operands[0], operands[1]),
568: operands);
569: operands[0] = gen_rtx (REG, SImode, REGNO (dst) + 1);
570: operands[1] = second;
571: output_asm_insn (i960_output_ldconst (operands[0], operands[1]),
572: operands);
573: return "";
574: #else
575: if (fp_literal_one (src, VOIDmode))
576: return "movrl 0f1.0,%0";
577: fatal ("inline double constants not supported on this host");
578: #endif
579: }
580: else if (mode == TImode)
581: {
582: /* ??? This is currently not handled at all. */
583: abort ();
584:
585: /* Note: lowest order word goes in lowest numbered reg. */
586: rsrc1 = INTVAL (src);
587: if (rsrc1 >= 0 && rsrc1 < 32)
588: return "movq %1,%0";
589: else
590: output_asm_insn ("movq\t0,%0\t# ldconstq %1,%0",operands);
591: /* Go pick up the low-order word. */
592: }
593: else if (mode == DImode)
594: {
1.1.1.2 ! root 595: rtx upperhalf, lowerhalf, xoperands[2];
1.1 root 596: char *string;
597:
598: if (GET_CODE (src) == CONST_DOUBLE)
599: {
600: upperhalf = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (src));
601: lowerhalf = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (src));
602: }
603: else if (GET_CODE (src) == CONST_INT)
604: {
605: lowerhalf = src;
606: upperhalf = INTVAL (src) < 0 ? constm1_rtx : const0_rtx;
607: }
608: else
609: abort ();
610:
611: /* Note: lowest order word goes in lowest numbered reg. */
612: /* Numbers from 0 to 31 can be handled with a single insn. */
613: rsrc1 = INTVAL (lowerhalf);
614: if (upperhalf == const0_rtx && rsrc1 >= 0 && rsrc1 < 32)
615: return "movl %1,%0";
616:
617: /* Output the upper half with a recursive call. */
1.1.1.2 ! root 618: xoperands[0] = gen_rtx (REG, SImode, REGNO (dst) + 1);
! 619: xoperands[1] = upperhalf;
! 620: output_asm_insn (i960_output_ldconst (xoperands[0], xoperands[1]),
! 621: xoperands);
1.1 root 622: /* The lower word is emitted as normally. */
623: }
624: else if (mode == SFmode)
625: {
626: #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
1.1.1.2 ! root 627: REAL_VALUE_TYPE d;
! 628: long value;
1.1 root 629:
1.1.1.2 ! root 630: REAL_VALUE_FROM_CONST_DOUBLE (d, src);
! 631: REAL_VALUE_TO_TARGET_SINGLE (d, value);
1.1 root 632:
633: output_asm_insn ("# ldconst %1,%0",operands);
634: operands[0] = gen_rtx (REG, SImode, REGNO (dst));
1.1.1.2 ! root 635: operands[1] = gen_rtx (CONST_INT, VOIDmode, value);
1.1 root 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.
1.1.1.2 ! root 736: Bypass succeeds on the 960K* if the destination of the previous
1.1 root 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 *
1.1.1.2 ! root 1188: i960_output_call_insn (target, argsize_rtx, arg_pointer, scratch_reg, insn)
! 1189: register rtx target, argsize_rtx, arg_pointer, scratch_reg, insn;
1.1 root 1190: {
1191: int argsize = INTVAL (argsize_rtx);
1192: rtx nexti = next_real_insn (insn);
1.1.1.2 ! root 1193: rtx operands[3];
1.1 root 1194:
1195: operands[0] = target;
1.1.1.2 ! root 1196: operands[1] = arg_pointer;
! 1197: operands[2] = scratch_reg;
1.1 root 1198:
1.1.1.2 ! root 1199: if (current_function_args_size != 0)
! 1200: output_asm_insn ("mov g14,%2", operands);
! 1201:
! 1202: if (argsize > 48)
! 1203: output_asm_insn ("lda %a1,g14", operands);
! 1204: else if (current_function_args_size != 0)
! 1205: output_asm_insn ("mov 0,g14", operands);
! 1206:
! 1207: /* The code used to assume that calls to SYMBOL_REFs could not be more
! 1208: than 24 bits away (b vs bx, callj vs callx). This is not true. This
! 1209: feature is now implemented by relaxing in the GNU linker. It can convert
! 1210: bx to b if in range, and callx to calls/call/balx/bal as appropriate. */
1.1 root 1211:
1212: /* Nexti could be zero if the called routine is volatile. */
1213: if (optimize && (*epilogue_string == 0) && argsize == 0 && tail_call_ok
1214: && (nexti == 0 || GET_CODE (PATTERN (nexti)) == RETURN))
1215: {
1216: /* Delete following return insn. */
1217: if (nexti && no_labels_between_p (insn, nexti))
1218: delete_insn (nexti);
1.1.1.2 ! root 1219: output_asm_insn ("bx %0", operands);
1.1 root 1220: return "# notreached";
1221: }
1222:
1.1.1.2 ! root 1223: output_asm_insn ("callx %0", operands);
! 1224:
! 1225: if (current_function_args_size != 0)
! 1226: output_asm_insn ("mov %2,g14", operands);
! 1227:
1.1 root 1228: return "";
1229: }
1230:
1231: /* Output code for a return insn. */
1232:
1233: char *
1234: i960_output_ret_insn (insn)
1235: register rtx insn;
1236: {
1237: static char lbuf[20];
1238:
1239: if (*epilogue_string != 0)
1240: {
1241: if (! TARGET_CODE_ALIGN && next_real_insn (insn) == 0)
1242: return "";
1243:
1244: sprintf (lbuf, "b LR%d", ret_label);
1245: return lbuf;
1246: }
1247:
1248: if (current_function_args_size != 0)
1249: output_asm_insn ("mov 0,g14", 0);
1250:
1251: if (i960_leaf_ret_reg >= 0)
1252: {
1253: sprintf (lbuf, "bx (%s)", reg_names[i960_leaf_ret_reg]);
1254: return lbuf;
1255: }
1256: return "ret";
1257: }
1258:
1259: #if 0
1260: /* Return a character string representing the branch prediction
1261: opcode to be tacked on an instruction. This must at least
1262: return a null string. */
1263:
1264: char *
1265: i960_br_predict_opcode (lab_ref, insn)
1266: rtx lab_ref, insn;
1267: {
1268: if (TARGET_BRANCH_PREDICT)
1269: {
1270: unsigned long label_uid;
1271:
1272: if (GET_CODE (lab_ref) == CODE_LABEL)
1273: label_uid = INSN_UID (lab_ref);
1274: else if (GET_CODE (lab_ref) == LABEL_REF)
1275: label_uid = INSN_UID (XEXP (lab_ref, 0));
1276: else
1277: return ".f";
1278:
1279: /* If not optimizing, then the insn_addresses array will not be
1280: valid. In this case, always return ".t" since most branches
1281: are taken. If optimizing, return .t for backward branches
1282: and .f for forward branches. */
1283: if (! optimize
1284: || insn_addresses[label_uid] < insn_addresses[INSN_UID (insn)])
1285: return ".t";
1286: return ".f";
1287: }
1288:
1289: return "";
1290: }
1291: #endif
1292:
1293: /* Print the operand represented by rtx X formatted by code CODE. */
1294:
1295: void
1296: i960_print_operand (file, x, code)
1297: FILE *file;
1298: rtx x;
1299: char code;
1300: {
1301: enum rtx_code rtxcode = GET_CODE (x);
1302:
1303: if (rtxcode == REG)
1304: {
1305: switch (code)
1306: {
1307: case 'D':
1308: /* Second reg of a double. */
1309: fprintf (file, "%s", reg_names[REGNO (x)+1]);
1310: break;
1311:
1312: case 0:
1313: fprintf (file, "%s", reg_names[REGNO (x)]);
1314: break;
1315:
1316: default:
1317: abort ();
1318: }
1319: return;
1320: }
1321: else if (rtxcode == MEM)
1322: {
1323: output_address (XEXP (x, 0));
1324: return;
1325: }
1326: else if (rtxcode == CONST_INT)
1327: {
1328: if (INTVAL (x) > 9999 || INTVAL (x) < -999)
1329: fprintf (file, "0x%x", INTVAL (x));
1330: else
1331: fprintf (file, "%d", INTVAL (x));
1332: return;
1333: }
1334: else if (rtxcode == CONST_DOUBLE)
1335: {
1336: double d;
1337:
1338: if (x == CONST0_RTX (DFmode) || x == CONST0_RTX (SFmode))
1339: {
1340: fprintf (file, "0f0.0");
1341: return;
1342: }
1343: else if (x == CONST1_RTX (DFmode) || x == CONST1_RTX (SFmode))
1344: {
1345: fprintf (file, "0f1.0");
1346: return;
1347: }
1348:
1349: /* This better be a comment. */
1350: REAL_VALUE_FROM_CONST_DOUBLE (d, x);
1351: fprintf (file, "%#g", d);
1352: return;
1353: }
1354:
1355: switch(code)
1356: {
1357: case 'B':
1358: /* Branch or jump, depending on assembler. */
1359: if (TARGET_ASM_COMPAT)
1360: fputs ("j", file);
1361: else
1362: fputs ("b", file);
1363: break;
1364:
1365: case 'S':
1366: /* Sign of condition. */
1367: if ((rtxcode == EQ) || (rtxcode == NE) || (rtxcode == GTU)
1368: || (rtxcode == LTU) || (rtxcode == GEU) || (rtxcode == LEU))
1369: fputs ("o", file);
1370: else if ((rtxcode == GT) || (rtxcode == LT)
1371: || (rtxcode == GE) || (rtxcode == LE))
1372: fputs ("i", file);
1373: else
1374: abort();
1375: break;
1376:
1377: case 'I':
1378: /* Inverted condition. */
1379: rtxcode = reverse_condition (rtxcode);
1380: goto normal;
1381:
1382: case 'X':
1383: /* Inverted condition w/ reversed operands. */
1384: rtxcode = reverse_condition (rtxcode);
1385: /* Fallthrough. */
1386:
1387: case 'R':
1388: /* Reversed operand condition. */
1389: rtxcode = swap_condition (rtxcode);
1390: /* Fallthrough. */
1391:
1392: case 'C':
1393: /* Normal condition. */
1394: normal:
1395: if (rtxcode == EQ) { fputs ("e", file); return; }
1396: else if (rtxcode == NE) { fputs ("ne", file); return; }
1397: else if (rtxcode == GT) { fputs ("g", file); return; }
1398: else if (rtxcode == GTU) { fputs ("g", file); return; }
1399: else if (rtxcode == LT) { fputs ("l", file); return; }
1400: else if (rtxcode == LTU) { fputs ("l", file); return; }
1401: else if (rtxcode == GE) { fputs ("ge", file); return; }
1402: else if (rtxcode == GEU) { fputs ("ge", file); return; }
1403: else if (rtxcode == LE) { fputs ("le", file); return; }
1404: else if (rtxcode == LEU) { fputs ("le", file); return; }
1405: else abort ();
1406: break;
1407:
1408: case 0:
1409: output_addr_const (file, x);
1410: break;
1411:
1412: default:
1413: abort ();
1414: }
1415:
1416: return;
1417: }
1418:
1419: /* Print a memory address as an operand to reference that memory location.
1420:
1421: This is exactly the same as legitimate_address_p, except that it the prints
1422: addresses instead of recognizing them. */
1423:
1424: void
1425: i960_print_operand_addr (file, addr)
1426: FILE *file;
1427: register rtx addr;
1428: {
1429: rtx breg, ireg;
1430: rtx scale, offset;
1431:
1432: ireg = 0;
1433: breg = 0;
1434: offset = 0;
1435: scale = const1_rtx;
1436:
1437: if (GET_CODE (addr) == REG)
1438: breg = addr;
1439: else if (CONSTANT_P (addr))
1440: offset = addr;
1441: else if (GET_CODE (addr) == PLUS)
1442: {
1443: rtx op0, op1;
1444:
1445: op0 = XEXP (addr, 0);
1446: op1 = XEXP (addr, 1);
1447:
1448: if (GET_CODE (op0) == REG)
1449: {
1450: breg = op0;
1451: if (GET_CODE (op1) == REG)
1452: ireg = op1;
1453: else if (CONSTANT_P (op1))
1454: offset = op1;
1455: else
1456: abort ();
1457: }
1458: else if (GET_CODE (op0) == PLUS)
1459: {
1460: if (GET_CODE (XEXP (op0, 0)) == MULT)
1461: {
1462: ireg = XEXP (XEXP (op0, 0), 0);
1463: scale = XEXP (XEXP (op0, 0), 1);
1464: if (GET_CODE (XEXP (op0, 1)) == REG)
1465: {
1466: breg = XEXP (op0, 1);
1467: offset = op1;
1468: }
1469: else
1470: abort ();
1471: }
1472: else if (GET_CODE (XEXP (op0, 0)) == REG)
1473: {
1474: breg = XEXP (op0, 0);
1475: if (GET_CODE (XEXP (op0, 1)) == REG)
1476: {
1477: ireg = XEXP (op0, 1);
1478: offset = op1;
1479: }
1480: else
1481: abort ();
1482: }
1483: else
1484: abort ();
1485: }
1486: else if (GET_CODE (op0) == MULT)
1487: {
1488: ireg = XEXP (op0, 0);
1489: scale = XEXP (op0, 1);
1490: if (GET_CODE (op1) == REG)
1491: breg = op1;
1492: else if (CONSTANT_P (op1))
1493: offset = op1;
1494: else
1495: abort ();
1496: }
1497: else
1498: abort ();
1499: }
1500: else if (GET_CODE (addr) == MULT)
1501: {
1502: breg = XEXP (addr, 0);
1503: scale = XEXP (addr, 1);
1504: }
1505: else
1506: abort ();
1507:
1508: if (offset)
1509: output_addr_const (file, offset);
1510: if (breg)
1511: fprintf (file, "(%s)", reg_names[REGNO (breg)]);
1512: if (ireg)
1513: fprintf (file, "[%s*%d]", reg_names[REGNO (ireg)], INTVAL (scale));
1514: }
1515:
1516: /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
1517: that is a valid memory address for an instruction.
1518: The MODE argument is the machine mode for the MEM expression
1519: that wants to use this address.
1520:
1521: On 80960, legitimate addresses are:
1522: base ld (g0),r0
1523: disp (12 or 32 bit) ld foo,r0
1524: base + index ld (g0)[g1*1],r0
1525: base + displ ld 0xf00(g0),r0
1526: base + index*scale + displ ld 0xf00(g0)[g1*4],r0
1527: index*scale + base ld (g0)[g1*4],r0
1528: index*scale + displ ld 0xf00[g1*4],r0
1529: index*scale ld [g1*4],r0
1530: index + base + displ ld 0xf00(g0)[g1*1],r0
1531:
1532: In each case, scale can be 1, 2, 4, 8, or 16. */
1533:
1534: /* This is exactly the same as i960_print_operand_addr, except that
1535: it recognizes addresses instead of printing them.
1536:
1537: It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
1538: convert common non-canonical forms to canonical form so that they will
1539: be recognized. */
1540:
1541: int
1542: legitimate_address_p (mode, addr, strict)
1543: enum machine_mode mode;
1544: register rtx addr;
1545: int strict;
1546: {
1547: if (GET_CODE (addr) == REG)
1548: return (strict ? REG_OK_FOR_BASE_P_STRICT (addr)
1549: : REG_OK_FOR_BASE_P (addr));
1550: else if (CONSTANT_P (addr))
1551: return 1;
1552: else if (GET_CODE (addr) == PLUS)
1553: {
1554: rtx op0, op1;
1555:
1556: if (! TARGET_COMPLEX_ADDR && ! reload_completed)
1557: return 0;
1558:
1559: op0 = XEXP (addr, 0);
1560: op1 = XEXP (addr, 1);
1561:
1562: if (GET_CODE (op0) == REG)
1563: {
1564: if (! (strict ? REG_OK_FOR_BASE_P_STRICT (op0)
1565: : REG_OK_FOR_BASE_P (op0)))
1566: return 0;
1567:
1568: if (GET_CODE (op1) == REG)
1569: return (strict ? REG_OK_FOR_INDEX_P_STRICT (op1)
1570: : REG_OK_FOR_INDEX_P (op1));
1571: else if (CONSTANT_P (op1))
1572: return 1;
1573: else
1574: return 0;
1575: }
1576: else if (GET_CODE (op0) == PLUS)
1577: {
1578: if (GET_CODE (XEXP (op0, 0)) == MULT)
1579: {
1580: if (! (GET_CODE (XEXP (XEXP (op0, 0), 0)) == REG
1581: && (strict ? REG_OK_FOR_INDEX_P_STRICT (XEXP (XEXP (op0, 0), 0))
1582: : REG_OK_FOR_INDEX_P (XEXP (XEXP (op0, 0), 0)))
1583: && SCALE_TERM_P (XEXP (XEXP (op0, 0), 1))))
1584: return 0;
1585:
1586: if (GET_CODE (XEXP (op0, 1)) == REG)
1587: return ((strict ? REG_OK_FOR_BASE_P_STRICT (XEXP (op0, 1))
1588: : REG_OK_FOR_BASE_P (XEXP (op0, 1)))
1589: && CONSTANT_P (op1));
1590: else
1591: return 0;
1592: }
1593: else if (GET_CODE (XEXP (op0, 0)) == REG)
1594: {
1595: if (! (strict ? REG_OK_FOR_BASE_P_STRICT (XEXP (op0, 0))
1596: : REG_OK_FOR_BASE_P (XEXP (op0, 0))))
1597: return 0;
1598:
1599: if (GET_CODE (XEXP (op0, 1)) == REG)
1600: return ((strict ? REG_OK_FOR_INDEX_P_STRICT (XEXP (op0, 1))
1601: : REG_OK_FOR_INDEX_P (XEXP (op0, 1)))
1602: && CONSTANT_P (op1));
1603: else
1604: return 0;
1605: }
1606: else
1607: return 0;
1608: }
1609: else if (GET_CODE (op0) == MULT)
1610: {
1611: if (! (GET_CODE (XEXP (op0, 0)) == REG
1612: && (strict ? REG_OK_FOR_INDEX_P_STRICT (XEXP (op0, 0))
1613: : REG_OK_FOR_INDEX_P (XEXP (op0, 0)))
1614: && SCALE_TERM_P (XEXP (op0, 1))))
1615: return 0;
1616:
1617: if (GET_CODE (op1) == REG)
1618: return (strict ? REG_OK_FOR_BASE_P_STRICT (op1)
1619: : REG_OK_FOR_BASE_P (op1));
1620: else if (CONSTANT_P (op1))
1621: return 1;
1622: else
1623: return 0;
1624: }
1625: else
1626: return 0;
1627: }
1628: else if (GET_CODE (addr) == MULT)
1629: {
1630: if (! TARGET_COMPLEX_ADDR && ! reload_completed)
1631: return 0;
1632:
1633: return (GET_CODE (XEXP (addr, 0)) == REG
1634: && (strict ? REG_OK_FOR_INDEX_P_STRICT (XEXP (addr, 0))
1635: : REG_OK_FOR_INDEX_P (XEXP (addr, 0)))
1636: && SCALE_TERM_P (XEXP (addr, 1)));
1637: }
1638: else
1639: return 0;
1640: }
1641:
1642: /* Try machine-dependent ways of modifying an illegitimate address
1643: to be legitimate. If we find one, return the new, valid address.
1644: This macro is used in only one place: `memory_address' in explow.c.
1645:
1646: This converts some non-canonical addresses to canonical form so they
1647: can be recognized. */
1648:
1649: rtx
1650: legitimize_address (x, oldx, mode)
1651: register rtx x;
1652: register rtx oldx;
1653: enum machine_mode mode;
1654: {
1655: if (GET_CODE (x) == SYMBOL_REF)
1656: {
1657: abort ();
1658: x = copy_to_reg (x);
1659: }
1660:
1661: if (! TARGET_COMPLEX_ADDR && ! reload_completed)
1662: return x;
1663:
1664: /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
1665: into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
1666: created by virtual register instantiation, register elimination, and
1667: similar optimizations. */
1668: if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT
1669: && GET_CODE (XEXP (x, 1)) == PLUS)
1670: x = gen_rtx (PLUS, Pmode,
1671: gen_rtx (PLUS, Pmode, XEXP (x, 0), XEXP (XEXP (x, 1), 0)),
1672: XEXP (XEXP (x, 1), 1));
1673:
1674: /* Canonicalize (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
1675: into (plus (plus (mult (reg) (const)) (reg)) (const)). */
1676: else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
1677: && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
1678: && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
1679: && CONSTANT_P (XEXP (x, 1)))
1680: {
1681: rtx constant, other;
1682:
1683: if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1684: {
1685: constant = XEXP (x, 1);
1686: other = XEXP (XEXP (XEXP (x, 0), 1), 1);
1687: }
1688: else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
1689: {
1690: constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
1691: other = XEXP (x, 1);
1692: }
1693: else
1694: constant = 0;
1695:
1696: if (constant)
1697: x = gen_rtx (PLUS, Pmode,
1698: gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0),
1699: XEXP (XEXP (XEXP (x, 0), 1), 0)),
1700: plus_constant (other, INTVAL (constant)));
1701: }
1702:
1703: return x;
1704: }
1705:
1706: #if 0
1707: /* Return the most stringent alignment that we are willing to consider
1708: objects of size SIZE and known alignment ALIGN as having. */
1709:
1710: int
1711: i960_alignment (size, align)
1712: int size;
1713: int align;
1714: {
1715: int i;
1716:
1717: if (! TARGET_STRICT_ALIGN)
1718: if (TARGET_IC_COMPAT2_0 || align >= 4)
1719: {
1720: i = i960_object_bytes_bitalign (size) / BITS_PER_UNIT;
1721: if (i > align)
1722: align = i;
1723: }
1724:
1725: return align;
1726: }
1727: #endif
1728:
1729: /* Modes for condition codes. */
1730: #define C_MODES \
1731: ((1 << (int) CCmode) | (1 << (int) CC_UNSmode) | (1<< (int) CC_CHKmode))
1732:
1733: /* Modes for single-word (and smaller) quantities. */
1734: #define S_MODES \
1735: (~C_MODES \
1736: & ~ ((1 << (int) DImode) | (1 << (int) TImode) \
1737: | (1 << (int) DFmode) | (1 << (int) TFmode)))
1738:
1739: /* Modes for double-word (and smaller) quantities. */
1740: #define D_MODES \
1741: (~C_MODES \
1742: & ~ ((1 << (int) TImode) | (1 << (int) TFmode)))
1743:
1744: /* Modes for quad-word quantities. */
1745: #define T_MODES (~C_MODES)
1746:
1747: /* Modes for single-float quantities. */
1748: #define SF_MODES ((1 << (int) SFmode))
1749:
1750: /* Modes for double-float quantities. */
1751: #define DF_MODES (SF_MODES | (1 << (int) DFmode) | (1 << (int) SCmode))
1752:
1753: /* Modes for quad-float quantities. */
1754: #define TF_MODES (DF_MODES | (1 << (int) TFmode) | (1 << (int) DCmode))
1755:
1756: unsigned int hard_regno_mode_ok[FIRST_PSEUDO_REGISTER] = {
1757: T_MODES, S_MODES, D_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
1758: T_MODES, S_MODES, D_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
1759: T_MODES, S_MODES, D_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
1760: T_MODES, S_MODES, D_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
1761:
1762: TF_MODES, TF_MODES, TF_MODES, TF_MODES, C_MODES};
1763:
1764:
1765: /* Return the minimum alignment of an expression rtx X in bytes. This takes
1766: advantage of machine specific facts, such as knowing that the frame pointer
1767: is always 16 byte aligned. */
1768:
1769: int
1770: i960_expr_alignment (x, size)
1771: rtx x;
1772: int size;
1773: {
1774: int align = 1;
1775:
1776: if (x == 0)
1777: return 1;
1778:
1779: switch (GET_CODE(x))
1780: {
1781: case CONST_INT:
1782: align = INTVAL(x);
1783:
1784: if ((align & 0xf) == 0)
1785: align = 16;
1786: else if ((align & 0x7) == 0)
1787: align = 8;
1788: else if ((align & 0x3) == 0)
1789: align = 4;
1790: else if ((align & 0x1) == 0)
1791: align = 2;
1792: else
1793: align = 1;
1794: break;
1795:
1796: case PLUS:
1797: align = MIN (i960_expr_alignment (XEXP (x, 0), size),
1798: i960_expr_alignment (XEXP (x, 1), size));
1799: break;
1800:
1801: case SYMBOL_REF:
1802: /* If this is a valid program, objects are guaranteed to be
1803: correctly aligned for whatever size the reference actually is. */
1804: align = i960_object_bytes_bitalign (size) / BITS_PER_UNIT;
1805: break;
1806:
1807: case REG:
1808: if (REGNO (x) == FRAME_POINTER_REGNUM)
1809: align = 16;
1810: break;
1811:
1812: case ASHIFT:
1813: case LSHIFT:
1814: align = i960_expr_alignment (XEXP (x, 0));
1815:
1816: if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1817: {
1818: align = align << INTVAL (XEXP (x, 1));
1819: align = MIN (align, 16);
1820: }
1821: break;
1822:
1823: case MULT:
1824: align = (i960_expr_alignment (XEXP (x, 0), size) *
1825: i960_expr_alignment (XEXP (x, 1), size));
1826:
1827: align = MIN (align, 16);
1828: break;
1829: }
1830:
1831: return align;
1832: }
1833:
1834: /* Return true if it is possible to reference both BASE and OFFSET, which
1835: have alignment at least as great as 4 byte, as if they had alignment valid
1836: for an object of size SIZE. */
1837:
1838: int
1839: i960_improve_align (base, offset, size)
1840: rtx base;
1841: rtx offset;
1842: int size;
1843: {
1844: int i, j;
1845:
1846: /* We have at least a word reference to the object, so we know it has to
1847: be aligned at least to 4 bytes. */
1848:
1849: i = MIN (i960_expr_alignment (base, 4),
1850: i960_expr_alignment (offset, 4));
1851:
1852: i = MAX (i, 4);
1853:
1854: /* We know the size of the request. If strict align is not enabled, we
1855: can guess that the alignment is OK for the requested size. */
1856:
1857: if (! TARGET_STRICT_ALIGN)
1858: if ((j = (i960_object_bytes_bitalign (size) / BITS_PER_UNIT)) > i)
1859: i = j;
1860:
1861: return (i >= size);
1862: }
1863:
1864: /* Return true if it is possible to access BASE and OFFSET, which have 4 byte
1865: (SImode) alignment as if they had 16 byte (TImode) alignment. */
1866:
1867: int
1868: i960_si_ti (base, offset)
1869: rtx base;
1870: rtx offset;
1871: {
1872: return i960_improve_align (base, offset, 16);
1873: }
1874:
1875: /* Return true if it is possible to access BASE and OFFSET, which have 4 byte
1876: (SImode) alignment as if they had 8 byte (DImode) alignment. */
1877:
1878: int
1879: i960_si_di (base, offset)
1880: rtx base;
1881: rtx offset;
1882: {
1883: return i960_improve_align (base, offset, 8);
1884: }
1885:
1886: /* Return raw values of size and alignment (in words) for the data
1887: type being accessed. These values will be rounded by the caller. */
1888:
1889: static void
1890: i960_arg_size_and_align (mode, type, size_out, align_out)
1891: enum machine_mode mode;
1892: tree type;
1893: int *size_out;
1894: int *align_out;
1895: {
1896: int size, align;
1897:
1898: /* Use formal alignment requirements of type being passed, except make
1899: it at least a word. If we don't have a type, this is a library call,
1900: and the parm has to be of scalar type. In this case, consider its
1901: formal alignment requirement to be its size in words. */
1902:
1903: if (mode == BLKmode)
1904: size = (int_size_in_bytes (type) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1905: else if (mode == VOIDmode)
1906: {
1907: /* End of parm list. */
1908: assert (type != 0 && TYPE_MODE (type) == VOIDmode);
1909: size = 1;
1910: }
1911: else
1912: size = (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1913:
1914: if (type == 0)
1915: align = size;
1916: else if (TYPE_ALIGN (type) >= BITS_PER_WORD)
1917: align = TYPE_ALIGN (type) / BITS_PER_WORD;
1918: else
1919: align = 1;
1920:
1921: *size_out = size;
1922: *align_out = align;
1923: }
1924:
1925: /* On the 80960 the first 12 args are in registers and the rest are pushed.
1926: Any arg that is bigger than 4 words is placed on the stack and all
1927: subsequent arguments are placed on the stack.
1928:
1929: Additionally, parameters with an alignment requirement stronger than
1930: a word must be be aligned appropriately. */
1931:
1932: /* Update CUM to advance past an argument described by MODE and TYPE. */
1933:
1934: void
1935: i960_function_arg_advance (cum, mode, type, named)
1936: CUMULATIVE_ARGS *cum;
1937: enum machine_mode mode;
1938: tree type;
1939: int named;
1940: {
1941: int size, align;
1942:
1943: i960_arg_size_and_align (mode, type, &size, &align);
1944:
1945: if (named == 0 || size > 4 || cum->ca_nstackparms != 0
1946: || (size + ROUND (cum->ca_nregparms, align)) > NPARM_REGS
1947: || MUST_PASS_IN_STACK (mode, type))
1948: cum->ca_nstackparms = ROUND (cum->ca_nstackparms, align) + size;
1949: else
1950: cum->ca_nregparms = ROUND (cum->ca_nregparms, align) + size;
1951: }
1952:
1953: /* Return the register that the argument described by MODE and TYPE is
1954: passed in, or else return 0 if it is passed on the stack. */
1955:
1956: rtx
1957: i960_function_arg (cum, mode, type, named)
1958: CUMULATIVE_ARGS *cum;
1959: enum machine_mode mode;
1960: tree type;
1961: int named;
1962: {
1963: rtx ret;
1964: int size, align;
1965:
1966: i960_arg_size_and_align (mode, type, &size, &align);
1967:
1968: if (named == 0 || size > 4 || cum->ca_nstackparms != 0
1969: || (size + ROUND (cum->ca_nregparms, align)) > NPARM_REGS
1970: || MUST_PASS_IN_STACK (mode, type))
1971: {
1972: cum->ca_nstackparms = ROUND (cum->ca_nstackparms, align);
1973: ret = 0;
1974: }
1975: else
1976: {
1977: cum->ca_nregparms = ROUND (cum->ca_nregparms, align);
1978: ret = gen_rtx (REG, mode, cum->ca_nregparms);
1979: }
1980:
1981: return ret;
1982: }
1983:
1984: /* Floating-point support. */
1985:
1986: void
1987: i960_output_double (file, value)
1988: FILE *file;
1989: double value;
1990: {
1991: if (REAL_VALUE_ISINF (value))
1992: {
1993: fprintf (file, "\t.word 0\n");
1994: fprintf (file, "\t.word 0x7ff00000 # Infinity\n");
1995: }
1996: else
1997: fprintf (file, "\t.double 0d%.17e\n", (value));
1998: }
1999:
2000: void
2001: i960_output_float (file, value)
2002: FILE *file;
2003: double value;
2004: {
2005: if (REAL_VALUE_ISINF (value))
2006: fprintf (file, "\t.word 0x7f800000 # Infinity\n");
2007: else
2008: fprintf (file, "\t.float 0f%.12e\n", (value));
2009: }
2010:
2011: /* Return the number of bits that an object of size N bytes is aligned to. */
2012:
2013: int
2014: i960_object_bytes_bitalign (n)
2015: int n;
2016: {
2017: if (n > 8) n = 128;
2018: else if (n > 4) n = 64;
2019: else if (n > 2) n = 32;
2020: else if (n > 1) n = 16;
2021: else n = 8;
2022:
2023: return n;
2024: }
2025:
2026: /* Compute the size of an aggregate type TSIZE. */
2027:
2028: tree
2029: i960_round_size (tsize)
2030: tree tsize;
2031: {
1.1.1.2 ! root 2032: int size, byte_size, align;
1.1 root 2033:
2034: if (TREE_CODE (tsize) != INTEGER_CST)
2035: return tsize;
2036:
2037: size = TREE_INT_CST_LOW (tsize);
1.1.1.2 ! root 2038: byte_size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
! 2039: align = i960_object_bytes_bitalign (byte_size);
1.1 root 2040:
2041: /* Handle #pragma align. */
2042: if (align > i960_maxbitalignment)
2043: align = i960_maxbitalignment;
2044:
2045: if (size % align)
2046: size = ((size / align) + 1) * align;
2047:
2048: return size_int (size);
2049: }
2050:
2051: /* Compute the alignment for an aggregate type TSIZE. */
2052:
2053: int
2054: i960_round_align (align, tsize)
2055: int align;
2056: tree tsize;
2057: {
1.1.1.2 ! root 2058: int byte_size;
! 2059:
1.1 root 2060: if (TREE_CODE (tsize) != INTEGER_CST)
2061: return align;
2062:
1.1.1.2 ! root 2063: byte_size = (TREE_INT_CST_LOW (tsize) + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
! 2064: align = i960_object_bytes_bitalign (byte_size);
1.1 root 2065: return align;
2066: }
2067:
2068: /* Do any needed setup for a varargs function. For the i960, we must
1.1.1.2 ! root 2069: create a register parameter block if one doesn't exist, and then copy
1.1 root 2070: all register parameters to memory. */
2071:
2072: void
2073: i960_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
2074: CUMULATIVE_ARGS *cum;
2075: enum machine_mode mode;
2076: tree type;
2077: int *pretend_size;
2078: int no_rtl;
2079: {
2080: if (cum->ca_nregparms < NPARM_REGS)
2081: {
2082: int first_reg_offset = cum->ca_nregparms;
2083:
2084: if (first_reg_offset > NPARM_REGS)
2085: first_reg_offset = NPARM_REGS;
2086:
2087: if (! (no_rtl) && first_reg_offset != NPARM_REGS)
2088: {
2089: rtx label = gen_label_rtx ();
2090: emit_insn (gen_cmpsi (arg_pointer_rtx, const0_rtx));
2091: emit_jump_insn (gen_bne (label));
2092: emit_insn (gen_rtx (SET, VOIDmode, arg_pointer_rtx,
2093: stack_pointer_rtx));
2094: emit_insn (gen_rtx (SET, VOIDmode, stack_pointer_rtx,
2095: memory_address (SImode,
2096: plus_constant (stack_pointer_rtx,
2097: 48))));
2098: emit_label (label);
2099: move_block_from_reg
2100: (first_reg_offset,
2101: gen_rtx (MEM, BLKmode, virtual_incoming_args_rtx),
2102: NPARM_REGS - first_reg_offset);
2103: }
2104: *pretend_size = (NPARM_REGS - first_reg_offset) * UNITS_PER_WORD;
2105: }
2106: }
2107:
2108: /* Calculate the final size of the reg parm stack space for the current
2109: function, based on how many bytes would be allocated on the stack. */
2110:
2111: int
2112: i960_final_reg_parm_stack_space (const_size, var_size)
2113: int const_size;
2114: tree var_size;
2115: {
2116: if (var_size || const_size > 48)
2117: return 48;
2118: else
2119: return 0;
2120: }
2121:
2122: /* Calculate the size of the reg parm stack space. This is a bit complicated
2123: on the i960. */
2124:
2125: int
2126: i960_reg_parm_stack_space (fndecl)
2127: tree fndecl;
2128: {
2129: /* In this case, we are called from emit_library_call, and we don't need
2130: to pretend we have more space for parameters than what's apparent. */
2131: if (fndecl == 0)
2132: return 0;
2133:
2134: /* In this case, we are called from locate_and_pad_parms when we're
2135: not IN_REGS, so we have an arg block. */
2136: if (fndecl != current_function_decl)
2137: return 48;
2138:
2139: /* Otherwise, we have an arg block if the current function has more than
2140: 48 bytes of parameters. */
2141: if (current_function_args_size != 0)
2142: return 48;
2143: else
2144: return 0;
2145: }
2146:
2147: /* Return the register class of a scratch register needed to copy IN into
2148: or out of a register in CLASS in MODE. If it can be done directly,
2149: NO_REGS is returned. */
2150:
2151: enum reg_class
2152: secondary_reload_class (class, mode, in)
2153: enum reg_class class;
2154: enum machine_mode mode;
2155: rtx in;
2156: {
2157: int regno = -1;
2158:
2159: if (GET_CODE (in) == REG || GET_CODE (in) == SUBREG)
2160: regno = true_regnum (in);
2161:
2162: /* We can place anything into LOCAL_OR_GLOBAL_REGS and can put
2163: LOCAL_OR_GLOBAL_REGS into anything. */
2164: if (class == LOCAL_OR_GLOBAL_REGS || class == LOCAL_REGS
2165: || class == GLOBAL_REGS || (regno >= 0 && regno < 32))
2166: return NO_REGS;
2167:
2168: /* We can place any hard register, 0.0, and 1.0 into FP_REGS. */
2169: if (class == FP_REGS
2170: && ((regno >= 0 && regno <= FIRST_PSEUDO_REGISTER)
2171: || in == CONST0_RTX (mode) || in == CONST1_RTX (mode)))
2172: return NO_REGS;
2173:
2174: return LOCAL_OR_GLOBAL_REGS;
2175: }
2176:
2177: /* Look at the opcode P, and set i96_last_insn_type to indicate which
2178: function unit it executed on. */
2179:
2180: /* ??? This would make more sense as an attribute. */
2181:
2182: void
2183: i960_scan_opcode (p)
2184: char *p;
2185: {
2186: switch (*p)
2187: {
2188: case 'a':
2189: case 'd':
2190: case 'e':
2191: case 'm':
2192: case 'n':
2193: case 'o':
2194: case 'r':
2195: /* Ret is not actually of type REG, but it won't matter, because no
2196: insn will ever follow it. */
2197: case 'u':
2198: case 'x':
2199: i960_last_insn_type = I_TYPE_REG;
2200: break;
2201:
2202: case 'b':
2203: if (p[1] == 'x' || p[3] == 'x')
2204: i960_last_insn_type = I_TYPE_MEM;
2205: i960_last_insn_type = I_TYPE_CTRL;
2206: break;
2207:
2208: case 'f':
2209: case 't':
2210: i960_last_insn_type = I_TYPE_CTRL;
2211: break;
2212:
2213: case 'c':
2214: if (p[1] == 'a')
2215: {
2216: if (p[4] == 'x')
2217: i960_last_insn_type = I_TYPE_MEM;
2218: else
2219: i960_last_insn_type = I_TYPE_CTRL;
2220: }
2221: else if (p[1] == 'm')
2222: {
2223: if (p[3] == 'd')
2224: i960_last_insn_type = I_TYPE_REG;
2225: else if (p[4] == 'b' || p[4] == 'j')
2226: i960_last_insn_type = I_TYPE_CTRL;
2227: else
2228: i960_last_insn_type = I_TYPE_REG;
2229: }
2230: else
2231: i960_last_insn_type = I_TYPE_REG;
2232: break;
2233:
2234: case 'l':
2235: i960_last_insn_type = I_TYPE_MEM;
2236: break;
2237:
2238: case 's':
2239: if (p[1] == 't')
2240: i960_last_insn_type = I_TYPE_MEM;
2241: else
2242: i960_last_insn_type = I_TYPE_REG;
2243: break;
2244: }
2245: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.