/* Subroutines used for code generation on intel 80960.
- Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by Steven McGeady, Intel Corp.
Additional Work by Glenn Colon-Bonet, Jonathan Shapiro, Andy Wilson
Converted to GCC 2.0 by Jim Wilson and Michael Tiemann, Cygnus Support.
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <stdio.h>
-
#include "config.h"
+#include <stdio.h>
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "flags.h"
#include "tree.h"
#include "insn-codes.h"
-#include "assert.h"
#include "expr.h"
+#include "except.h"
#include "function.h"
#include "recog.h"
#include <math.h>
intel compilers understand. */
int
-process_pragma (finput, c)
+process_pragma (finput, t)
FILE *finput;
- int c;
+ tree t;
{
int i;
+ register int c;
+ register char *pname;
+
+ if (TREE_CODE (t) != IDENTIFIER_NODE)
+ return 0;
- while (c == ' ' || c == '\t')
- c = getc (finput);
+ pname = IDENTIFIER_POINTER (t);
- if (c == 'a'
- && getc (finput) == 'l'
- && getc (finput) == 'i'
- && getc (finput) == 'g'
- && getc (finput) == 'n'
- && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'))
+ if (strcmp (pname, "align") == 0)
{
char buf[20];
char *s = buf;
int align;
- while (c == ' ' || c == '\t')
+ do {
c = getc (finput);
+ } while (c == ' ' || c == '\t');
+
if (c == '(')
c = getc (finput);
while (c >= '0' && c <= '9')
}
*s = '\0';
+ /* We had to read a non-numerical character to get out of the
+ while loop---often a newline. So, we have to put it back to
+ make sure we continue to parse everything properly. */
+ ungetc (c, finput);
+
align = atoi (buf);
switch (align)
{
- missing identifier means next struct
- alignment rules for bitfields need more investigation */
+
+ return 1;
}
/* Should be pragma 'far' or equivalent for callx/balx here. */
- while (c != '\n' && c != EOF)
- c = getc (finput);
- return c;
+ return 0;
}
/* Initialize variables before compiling any files. */
if (GET_CODE (x) == REG)
return 1;
#endif
+ /* This is a MEMA operand -- it's free. */
+ if (GET_CODE (x) == CONST_INT
+ && INTVAL (x) >= 0
+ && INTVAL (x) < 4096)
+ return 0;
+
if (GET_CODE (x) == PLUS)
{
rtx base = XEXP (x, 0);
adding 4 to the memory address may not yield a valid insn. */
/* ??? We don't always need the scratch, but that would complicate things.
Maybe later. */
+ /* ??? We must also handle stores to pseudos here, because the pseudo may be
+ replaced with a MEM later. This would be cleaner if we didn't have
+ a separate pattern for unaligned DImode/TImode stores. */
if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
- && GET_CODE (operands[0]) == MEM
+ && (GET_CODE (operands[0]) == MEM
+ || (GET_CODE (operands[0]) == REG
+ && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
&& GET_CODE (operands[1]) == REG
&& REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
&& ! HARD_REGNO_MODE_OK (REGNO (operands[1]), mode))
output_asm_insn ("# ldconst %1,%0",operands);
operands[0] = gen_rtx (REG, SImode, REGNO (dst));
- operands[1] = gen_rtx (CONST_INT, VOIDmode, value);
+ operands[1] = GEN_INT (value);
output_asm_insn (i960_output_ldconst (operands[0], operands[1]),
operands);
return "";
{
if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
return "lda %1,%0";
- operands[1] = gen_rtx (CONST_INT, VOIDmode, rsrc1 - 31);
+ operands[1] = GEN_INT (rsrc1 - 31);
output_asm_insn ("addo\t31,%1,%0\t# ldconst %3,%0", operands);
return "";
}
if (rsrc1 >= -31)
{
/* return 'sub -(%1),0,%0' */
- operands[1] = gen_rtx (CONST_INT, VOIDmode, - rsrc1);
+ operands[1] = GEN_INT (- rsrc1);
output_asm_insn ("subo\t%1,0,%0\t# ldconst %3,%0", operands);
return "";
}
/* ldconst -32 -> not 31,X */
if (rsrc1 == -32)
{
- operands[1] = gen_rtx (CONST_INT, VOIDmode, ~rsrc1);
+ operands[1] = GEN_INT (~rsrc1);
output_asm_insn ("not\t%1,%0 # ldconst %3,%0", operands);
return "";
}
/* If const is a single bit. */
if (bitpos (rsrc1) >= 0)
{
- operands[1] = gen_rtx (CONST_INT, VOIDmode, bitpos (rsrc1));
+ operands[1] = GEN_INT (bitpos (rsrc1));
output_asm_insn ("setbit\t%1,0,%0\t# ldconst %3,%0", operands);
return "";
}
if (bitstr (rsrc1, &s, &e) < 6)
{
rsrc2 = ((unsigned int) rsrc1) >> s;
- operands[1] = gen_rtx (CONST_INT, VOIDmode, rsrc2);
- operands[2] = gen_rtx (CONST_INT, VOIDmode, s);
+ operands[1] = GEN_INT (rsrc2);
+ operands[2] = GEN_INT (s);
output_asm_insn ("shlo\t%2,%1,%0\t# ldconst %3,%0", operands);
return "";
}
}
#endif
\f
-/* Modes for condition codes. */
-#define C_MODES \
- ((1 << (int) CCmode) | (1 << (int) CC_UNSmode) | (1<< (int) CC_CHKmode))
-
-/* Modes for single-word (and smaller) quantities. */
-#define S_MODES \
- (~C_MODES \
- & ~ ((1 << (int) DImode) | (1 << (int) TImode) \
- | (1 << (int) DFmode) | (1 << (int) XFmode)))
-/* Modes for double-word (and smaller) quantities. */
-#define D_MODES \
- (~C_MODES \
- & ~ ((1 << (int) TImode) | (1 << (int) XFmode)))
+int
+hard_regno_mode_ok (regno, mode)
+ int regno;
+ enum machine_mode mode;
+{
+ if (regno < 32)
+ {
+ switch (mode)
+ {
+ case CCmode: case CC_UNSmode: case CC_CHKmode:
+ return 0;
-/* Modes for quad-word quantities. */
-#define T_MODES (~C_MODES)
+ case DImode: case DFmode:
+ return (regno & 1) == 0;
-/* Modes for single-float quantities. */
-#define SF_MODES ((1 << (int) SFmode))
+ case TImode: case XFmode:
+ return (regno & 3) == 0;
-/* Modes for double-float quantities. */
-#define DF_MODES (SF_MODES | (1 << (int) DFmode) | (1 << (int) SCmode))
+ default:
+ return 1;
+ }
+ }
+ else if (regno >= 32 && regno < 36)
+ {
+ switch (mode)
+ {
+ case SFmode: case DFmode: case XFmode:
+ case SCmode: case DCmode:
+ return 1;
-/* Modes for quad-float quantities. */
-#define XF_MODES (DF_MODES | (1 << (int) XFmode) | (1 << (int) DCmode))
+ default:
+ return 0;
+ }
+ }
+ else if (regno == 36)
+ {
+ switch (mode)
+ {
+ case CCmode: case CC_UNSmode: case CC_CHKmode:
+ return 1;
-unsigned int hard_regno_mode_ok[FIRST_PSEUDO_REGISTER] = {
- T_MODES, S_MODES, D_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
- T_MODES, S_MODES, D_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
- T_MODES, S_MODES, D_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
- T_MODES, S_MODES, D_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
+ default:
+ return 0;
+ }
+ }
+ else if (regno == 37)
+ return 0;
- XF_MODES, XF_MODES, XF_MODES, XF_MODES, C_MODES};
+ abort ();
+}
\f
/* Return the minimum alignment of an expression rtx X in bytes. This takes
else if (mode == VOIDmode)
{
/* End of parm list. */
- assert (type != 0 && TYPE_MODE (type) == VOIDmode);
+ if (type == 0 || TYPE_MODE (type) != VOIDmode)
+ abort ();
size = 1;
}
else