i960.c (i960_address_cost): MEMA operands with positive offsets < 4096 are free.
[gcc.git] / gcc / config / i960 / i960.c
index 32903afbaf0e26253315e60e3c114c1411d0fd33..6189b4dee51e9f6ddffd403486341f643b202259 100644 (file)
@@ -1,5 +1,5 @@
 /* Subroutines used for code generation on intel 80960.
-   Copyright (C) 1992, 1995, 1996, 1997 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.
@@ -531,6 +531,12 @@ i960_address_cost (x)
   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);
@@ -589,8 +595,13 @@ emit_move_sequence (operands, mode)
      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))
@@ -2062,40 +2073,57 @@ i960_alignment (size, align)
 }
 #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