arm.h (ARM_REGNO_OK_FOR_BASE_P, [...]): New macros.
authorRichard Earnshaw <rearnsha@arm.com>
Sat, 2 Dec 2000 17:10:29 +0000 (17:10 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Sat, 2 Dec 2000 17:10:29 +0000 (17:10 +0000)
* arm.h (ARM_REGNO_OK_FOR_BASE_P, THUMB_REGNO_MODE_OK_FOR_BASE_P): New
macros.
(REGNO_MODE_OK_FOR_BASE_P): Define in terms of above.
(REGNO_OK_FOR_FOR_BASE_P): Delete.
(ARM_REG_OK_FOR_BASE_P, THUMB_REG_MODE_OK_FOR_BASE_P): New macros for
both strict and non-strict uses.
(REG_MODE_OK_FOR_BASE_P): Define in terms of above.
(ARM_REG_OK_FOR_INDEX_P, THUMB_REG_OK_FOR_INDEX_P): New macros.
(REG_OK_FOR_INDEX_P): Define in terms of above.
(REG_OK_FOR_BASE_P): Delete.
(REG_OK_FOR_PRE_POST_P): Delete.
(ARM_BASE_REGISTER_RTX_P): Renamed from BASE_REGISTER_RTX_P.
(ARM_INDEX_REGISTER_RTX_P): Renamed from INDEX_REGISTER_RTX_P.
(ARM_GO_IF_LEGITIMATE_INDEX): Renamed from GO_IF_LEGITIMATE_INDEX.
(THUMB_LEGITIMATE_OFFSET): Renamed from LEGITIMATE_OFFSET.
(ARM_GO_IF_LEGITIMATE_ADDRESS): Adjust for name changes.  Use ARM
specific variants rather than general ones.  Use ARM_REG_OK_FOR_BASE_P
in pre/post increment cases.
(THUMB_GO_IF_LEGITIMATE_ADDRESS): Similarly for Thumb.
(ARM_LEGITIMIZE_ADDRESS): Similarly.
(THUMB_LEGITIMIZE_RELOAD_ADDRESS): Similarly.
* arm.c (legitimate_pic_address): Similarly.

From-SVN: r37954

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/arm.h

index 17307b5cbf74e550d0a6f8c393222328abc2ce61..0d8f01a06e93a0887f1f7a7ad021b42ef515a892 100644 (file)
@@ -1,3 +1,28 @@
+2000-12-02  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm.h (ARM_REGNO_OK_FOR_BASE_P, THUMB_REGNO_MODE_OK_FOR_BASE_P): New
+       macros.
+       (REGNO_MODE_OK_FOR_BASE_P): Define in terms of above.
+       (REGNO_OK_FOR_FOR_BASE_P): Delete.
+       (ARM_REG_OK_FOR_BASE_P, THUMB_REG_MODE_OK_FOR_BASE_P): New macros for
+       both strict and non-strict uses.
+       (REG_MODE_OK_FOR_BASE_P): Define in terms of above.
+       (ARM_REG_OK_FOR_INDEX_P, THUMB_REG_OK_FOR_INDEX_P): New macros.
+       (REG_OK_FOR_INDEX_P): Define in terms of above.
+       (REG_OK_FOR_BASE_P): Delete.
+       (REG_OK_FOR_PRE_POST_P): Delete.
+       (ARM_BASE_REGISTER_RTX_P): Renamed from BASE_REGISTER_RTX_P.
+       (ARM_INDEX_REGISTER_RTX_P): Renamed from INDEX_REGISTER_RTX_P.
+       (ARM_GO_IF_LEGITIMATE_INDEX): Renamed from GO_IF_LEGITIMATE_INDEX.
+       (THUMB_LEGITIMATE_OFFSET): Renamed from LEGITIMATE_OFFSET.
+       (ARM_GO_IF_LEGITIMATE_ADDRESS): Adjust for name changes.  Use ARM
+       specific variants rather than general ones.  Use ARM_REG_OK_FOR_BASE_P
+       in pre/post increment cases.
+       (THUMB_GO_IF_LEGITIMATE_ADDRESS): Similarly for Thumb.
+       (ARM_LEGITIMIZE_ADDRESS): Similarly.
+       (THUMB_LEGITIMIZE_RELOAD_ADDRESS): Similarly.
+       * arm.c (legitimate_pic_address): Similarly.
+
 2000-12-02  Neil Booth  <neilb@earthling.net>
 
         * tradcpp.c (struct answer, parse_assertion, parse_answer,
index 678a4819f4c185383f6da299862d4b94d8ed9c56..6e14350dff01856c73e634d524c103eaa8f3c9ab 100644 (file)
@@ -1967,7 +1967,7 @@ legitimize_pic_address (orig, mode, reg)
        {
          /* The base register doesn't really matter, we only want to
             test the index for the appropriate mode.  */
-         GO_IF_LEGITIMATE_INDEX (mode, 0, offset, win);
+         ARM_GO_IF_LEGITIMATE_INDEX (mode, 0, offset, win);
 
          if (!no_new_pseudos)
            offset = force_reg (Pmode, offset);
index 09baa5130caf01a102f03b37c26b7739b11f2761..c1a3215c7a2d56c793c6bdf41b2993266ab41113 100644 (file)
@@ -1269,7 +1269,7 @@ enum reg_class
       && GET_CODE (XEXP (X, 0)) == REG                                 \
       && XEXP (X, 0) == stack_pointer_rtx                              \
       && GET_CODE (XEXP (X, 1)) == CONST_INT                           \
-      && ! LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1))))             \
+      && ! THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1))))       \
     {                                                                  \
       rtx orig_X = X;                                                  \
       X = copy_rtx (X);                                                        \
@@ -1781,23 +1781,23 @@ typedef struct
   ((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE))
 
 /*   On the ARM, don't allow the pc to be used.  */
-#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE)                  \
-  (TARGET_THUMB ?                                              \
-    (    TEST_REGNO (REGNO, <=, LAST_LO_REGNUM)                        \
-      || (GET_MODE_SIZE (MODE) >= 4                            \
-         && TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM)))     \
-   :(                                                          \
-         TEST_REGNO (REGNO, <, PC_REGNUM)                      \
-      || TEST_REGNO (REGNO, ==, FRAME_POINTER_REGNUM)          \
-      || TEST_REGNO (REGNO, ==, ARG_POINTER_REGNUM)))
-
-/* This is like REGNO_MODE_OF_FOR_BASE_P, except that in Thumb mode
-   the stack pointer is always acceptable, hence the passing of SImode  */
-#define REGNO_OK_FOR_BASE_P(REGNO)     \
-  REGNO_MODE_OK_FOR_BASE_P (REGNO, SImode)
-
-/* We play tricks with REGNO_MODE_OK... here, so that for ARM the macros
-   are the same, but for Thumb only registers 0 - 7 are OK.  */
+#define ARM_REGNO_OK_FOR_BASE_P(REGNO)                 \
+  (TEST_REGNO (REGNO, <, PC_REGNUM)                    \
+   || TEST_REGNO (REGNO, ==, FRAME_POINTER_REGNUM)     \
+   || TEST_REGNO (REGNO, ==, ARG_POINTER_REGNUM))
+
+#define THUMB_REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE)            \
+  (TEST_REGNO (REGNO, <=, LAST_LO_REGNUM)                      \
+   || (GET_MODE_SIZE (MODE) >= 4                               \
+       && TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM)))
+
+#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE)          \
+  (TARGET_THUMB                                                \
+   ? THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE)      \
+   : ARM_REGNO_OK_FOR_BASE_P (REGNO))
+
+/* For ARM code, we don't care about the mode, but for Thumb, the index
+   must be suitable for use in a QImode load.  */
 #define REGNO_OK_FOR_INDEX_P(REGNO)    \
   REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode)
 
@@ -1928,48 +1928,51 @@ typedef struct
    The symbol REG_OK_STRICT causes the latter definition to be used.  */
 #ifndef REG_OK_STRICT
 
-#define REG_MODE_OK_FOR_BASE_P(X, MODE)                \
-  (TARGET_THUMB ?                              \
-    (   REGNO (X) <= LAST_LO_REGNUM            \
-     || REGNO (X) >= FIRST_PSEUDO_REGISTER     \
-     || (GET_MODE_SIZE (MODE) >= 4             \
-        && (REGNO (X) == STACK_POINTER_REGNUM  \
-             ||   (X) == hard_frame_pointer_rtx \
-             ||   (X) == arg_pointer_rtx)))    \
-   :(                                          \
-        REGNO (X) <= LAST_ARM_REGNUM           \
-     || REGNO (X) >= FIRST_PSEUDO_REGISTER     \
-     || REGNO (X) == FRAME_POINTER_REGNUM      \
-     || REGNO (X) == ARG_POINTER_REGNUM))
-
-/* Nonzero if X is a hard reg that can be used as a base reg
-   or if it is a pseudo reg.  */
-#define REG_OK_FOR_BASE_P(X)                           \
-  REG_MODE_OK_FOR_BASE_P (X, SImode)  
+#define ARM_REG_OK_FOR_BASE_P(X)               \
+  (REGNO (X) <= LAST_ARM_REGNUM                        \
+   || REGNO (X) >= FIRST_PSEUDO_REGISTER       \
+   || REGNO (X) == FRAME_POINTER_REGNUM                \
+   || REGNO (X) == ARG_POINTER_REGNUM)
 
-/* Nonzero if X is a hard reg that can be used as an index
-   or if it is a pseudo reg.  On the Thumb, the stack pointer
-   is not suitable.  */
-#define REG_OK_FOR_INDEX_P(X)  \
-  REG_MODE_OK_FOR_BASE_P (X, QImode)  
-
-/* Just like REG_OK_FOR_BASE_P except that we also allow the PC.  */
-#define REG_OK_FOR_PRE_POST_P(X) \
-  (REG_OK_FOR_BASE_P (X) || REGNO(X) == PC_REGNUM)
+#define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE)  \
+  (REGNO (X) <= LAST_LO_REGNUM                 \
+   || REGNO (X) >= FIRST_PSEUDO_REGISTER       \
+   || (GET_MODE_SIZE (MODE) >= 4               \
+       && (REGNO (X) == STACK_POINTER_REGNUM   \
+          || (X) == hard_frame_pointer_rtx     \
+          || (X) == arg_pointer_rtx)))
 
 #else /* REG_OK_STRICT */
 
-/* Nonzero if X is a hard reg that can be used as a base reg.  */
-#define REG_OK_FOR_BASE_P(X)  REGNO_OK_FOR_BASE_P (REGNO (X))
+#define ARM_REG_OK_FOR_BASE_P(X)               \
+  ARM_REGNO_OK_FOR_BASE_P (REGNO (X))
 
-/* Nonzero if X is a hard reg that can be used as an index.  */
-#define REG_OK_FOR_INDEX_P(X)  REGNO_OK_FOR_INDEX_P (REGNO (X))
-
-/* Just like REG_OK_FOR_BASE_P except that we also allow the PC.  */
-#define REG_OK_FOR_PRE_POST_P(X) \
-  (REG_OK_FOR_BASE_P (X) || TEST_REGNO (REGNO (X), ==, PC_REGNUM))
+#define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE)  \
+  THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO (X), MODE)
 
 #endif /* REG_OK_STRICT */
+
+/* Now define some helpers in terms of the above.  */
+
+#define REG_MODE_OK_FOR_BASE_P(X, MODE)                \
+  (TARGET_THUMB                                        \
+   ? THUMB_REG_MODE_OK_FOR_BASE_P (X, MODE)    \
+   : ARM_REG_OK_FOR_BASE_P (X))
+
+#define ARM_REG_OK_FOR_INDEX_P(X) ARM_REG_OK_FOR_BASE_P (X)
+
+/* For Thumb, a valid index register is anything that can be used in
+   a byte load instruction.  */
+#define THUMB_REG_OK_FOR_INDEX_P(X) THUMB_REG_MODE_OK_FOR_BASE_P (X, QImode)
+
+/* Nonzero if X is a hard reg that can be used as an index
+   or if it is a pseudo reg.  On the Thumb, the stack pointer
+   is not suitable.  */
+#define REG_OK_FOR_INDEX_P(X)                  \
+  (TARGET_THUMB                                        \
+   ? THUMB_REG_OK_FOR_INDEX_P (X)              \
+   : ARM_REG_OK_FOR_INDEX_P (X))
+
 \f
 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
    that is a valid memory address for an instruction.
@@ -1979,132 +1982,135 @@ typedef struct
    The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS. */
      
 /* --------------------------------arm version----------------------------- */
-#define BASE_REGISTER_RTX_P(X)  \
-  (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))
+#define ARM_BASE_REGISTER_RTX_P(X)  \
+  (GET_CODE (X) == REG && ARM_REG_OK_FOR_BASE_P (X))
 
-#define INDEX_REGISTER_RTX_P(X)  \
-  (GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X))
+#define ARM_INDEX_REGISTER_RTX_P(X)  \
+  (GET_CODE (X) == REG && ARM_REG_OK_FOR_INDEX_P (X))
 
 /* A C statement (sans semicolon) to jump to LABEL for legitimate index RTXs
    used by the macro GO_IF_LEGITIMATE_ADDRESS.  Floating point indices can
    only be small constants. */
-#define GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL)                         \
-  do                                                                                   \
-    {                                                                                  \
-      HOST_WIDE_INT range;                                                             \
-      enum rtx_code code = GET_CODE (INDEX);                                           \
-                                                                                       \
-      if (TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT)                    \
-       {                                                                               \
-         if (code == CONST_INT && INTVAL (INDEX) < 1024                                \
-             && INTVAL (INDEX) > -1024                                                 \
-             && (INTVAL (INDEX) & 3) == 0)                                             \
-           goto LABEL;                                                                 \
-       }                                                                               \
-      else                                                                             \
-       {                                                                               \
-         if (INDEX_REGISTER_RTX_P (INDEX) && GET_MODE_SIZE (MODE) <= 4)                \
-           goto LABEL;                                                                 \
-         if (GET_MODE_SIZE (MODE) <= 4  && code == MULT                                \
-             && (! arm_arch4 || (MODE) != HImode))                                     \
-           {                                                                           \
-             rtx xiop0 = XEXP (INDEX, 0);                                              \
-             rtx xiop1 = XEXP (INDEX, 1);                                              \
-             if (INDEX_REGISTER_RTX_P (xiop0)                                          \
-                 && power_of_two_operand (xiop1, SImode))                              \
-               goto LABEL;                                                             \
-             if (INDEX_REGISTER_RTX_P (xiop1)                                          \
-                 && power_of_two_operand (xiop0, SImode))                              \
-               goto LABEL;                                                             \
-           }                                                                           \
-         if (GET_MODE_SIZE (MODE) <= 4                                                 \
-             && (code == LSHIFTRT || code == ASHIFTRT                                  \
-                 || code == ASHIFT || code == ROTATERT)                                \
-             && (! arm_arch4 || (MODE) != HImode))                                     \
-           {                                                                           \
-             rtx op = XEXP (INDEX, 1);                                                 \
-             if (INDEX_REGISTER_RTX_P (XEXP (INDEX, 0))                                \
-                 && GET_CODE (op) == CONST_INT && INTVAL (op) > 0                      \
-                 && INTVAL (op) <= 31)                                                 \
-               goto LABEL;                                                             \
-           }                                                                           \
-         /* NASTY: Since this limits the addressing of unsigned byte loads */          \
-         range = ((MODE) == HImode || (MODE) == QImode)                                \
-           ? (arm_arch4 ? 256 : 4095) : 4096;                                          \
-         if (code == CONST_INT && INTVAL (INDEX) < range                               \
-             && INTVAL (INDEX) > -range)                                               \
-           goto LABEL;                                                                 \
-       }                                                                               \
-    }                                                                                  \
-  while (0)
-
-/* Jump to LABEL if X is a valid address RTX.  This must also take
-   REG_OK_STRICT into account when deciding about valid registers, but it uses
-   the above macros so we are in luck.  Allow REG, REG+REG, REG+INDEX,
-   INDEX+REG, REG-INDEX, and non floating SYMBOL_REF to the constant pool.
-   Allow REG-only and AUTINC-REG if handling TImode or HImode.  Other symbol
-   refs must be forced though a static cell to ensure addressability.  */
-#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL)                   \
-{                                                                      \
-  if (BASE_REGISTER_RTX_P (X))                                         \
-    goto LABEL;                                                                \
-  else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC)       \
-          && GET_CODE (XEXP (X, 0)) == REG                             \
-          && REG_OK_FOR_PRE_POST_P (XEXP (X, 0)))                      \
-    goto LABEL;                                                                \
-  else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed               \
-          && (GET_CODE (X) == LABEL_REF                                \
-              || (GET_CODE (X) == CONST                                \
-                  && GET_CODE (XEXP ((X), 0)) == PLUS                  \
-                  && GET_CODE (XEXP (XEXP ((X), 0), 0)) == LABEL_REF   \
-                  && GET_CODE (XEXP (XEXP ((X), 0), 1)) == CONST_INT)))\
-    goto LABEL;                                                                \
-  else if ((MODE) == TImode)                                           \
-    ;                                                                  \
-  else if ((MODE) == DImode || (TARGET_SOFT_FLOAT && (MODE) == DFmode))        \
-    {                                                                  \
-      if (GET_CODE (X) == PLUS && BASE_REGISTER_RTX_P (XEXP (X, 0))    \
-         && GET_CODE (XEXP (X, 1)) == CONST_INT)                       \
-       {                                                               \
-         HOST_WIDE_INT val = INTVAL (XEXP (X, 1));                     \
-          if (val == 4 || val == -4 || val == -8)                      \
-           goto LABEL;                                                 \
-       }                                                               \
-    }                                                                  \
-  else if (GET_CODE (X) == PLUS)                                       \
+#define ARM_GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL)     \
+  do                                                                   \
     {                                                                  \
-      rtx xop0 = XEXP (X, 0);                                          \
-      rtx xop1 = XEXP (X, 1);                                          \
+      HOST_WIDE_INT range;                                             \
+      enum rtx_code code = GET_CODE (INDEX);                           \
                                                                        \
-      if (BASE_REGISTER_RTX_P (xop0))                                  \
-       GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL);       \
-      else if (BASE_REGISTER_RTX_P (xop1))                             \
-       GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL);       \
+      if (TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT)    \
+       {                                                               \
+         if (code == CONST_INT && INTVAL (INDEX) < 1024                \
+             && INTVAL (INDEX) > -1024                                 \
+             && (INTVAL (INDEX) & 3) == 0)                             \
+           goto LABEL;                                                 \
+       }                                                               \
+      else                                                             \
+       {                                                               \
+         if (ARM_INDEX_REGISTER_RTX_P (INDEX)                          \
+             && GET_MODE_SIZE (MODE) <= 4)                             \
+           goto LABEL;                                                 \
+         if (GET_MODE_SIZE (MODE) <= 4  && code == MULT                \
+             && (! arm_arch4 || (MODE) != HImode))                     \
+           {                                                           \
+             rtx xiop0 = XEXP (INDEX, 0);                              \
+             rtx xiop1 = XEXP (INDEX, 1);                              \
+             if (ARM_INDEX_REGISTER_RTX_P (xiop0)                      \
+                 && power_of_two_operand (xiop1, SImode))              \
+               goto LABEL;                                             \
+             if (ARM_INDEX_REGISTER_RTX_P (xiop1)                      \
+                 && power_of_two_operand (xiop0, SImode))              \
+               goto LABEL;                                             \
+           }                                                           \
+         if (GET_MODE_SIZE (MODE) <= 4                                 \
+             && (code == LSHIFTRT || code == ASHIFTRT                  \
+                 || code == ASHIFT || code == ROTATERT)                \
+             && (! arm_arch4 || (MODE) != HImode))                     \
+           {                                                           \
+             rtx op = XEXP (INDEX, 1);                                 \
+             if (ARM_INDEX_REGISTER_RTX_P (XEXP (INDEX, 0))            \
+                 && GET_CODE (op) == CONST_INT && INTVAL (op) > 0      \
+                 && INTVAL (op) <= 31)                                 \
+               goto LABEL;                                             \
+           }                                                           \
+         /* NASTY: Since this limits the addressing of unsigned        \
+            byte loads.  */                                            \
+         range = ((MODE) == HImode || (MODE) == QImode)                \
+           ? (arm_arch4 ? 256 : 4095) : 4096;                          \
+         if (code == CONST_INT && INTVAL (INDEX) < range               \
+             && INTVAL (INDEX) > -range)                               \
+           goto LABEL;                                                 \
+       }                                                               \
     }                                                                  \
-  /* Reload currently can't handle MINUS, so disable this for now */   \
-  /* else if (GET_CODE (X) == MINUS)                                   \
-    {                                                                  \
-      rtx xop0 = XEXP (X,0);                                           \
-      rtx xop1 = XEXP (X,1);                                           \
-                                                                       \
-      if (BASE_REGISTER_RTX_P (xop0))                                  \
-       GO_IF_LEGITIMATE_INDEX (MODE, -1, xop1, LABEL);                 \
-    } */                                                               \
-  else if (GET_MODE_CLASS (MODE) != MODE_FLOAT                         \
-          && GET_CODE (X) == SYMBOL_REF                                \
-          && CONSTANT_POOL_ADDRESS_P (X)                               \
-          && ! (flag_pic                                               \
-                && symbol_mentioned_p (get_pool_constant (X))))        \
-    goto LABEL;                                                                \
-  else if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_DEC)       \
-          && (GET_MODE_SIZE (MODE) <= 4)                               \
-          && GET_CODE (XEXP (X, 0)) == REG                             \
-          && REG_OK_FOR_PRE_POST_P (XEXP (X, 0)))                      \
-    goto LABEL;                                                                \
+  while (0)
+
+/* Jump to LABEL if X is a valid address RTX.  This must take
+   REG_OK_STRICT into account when deciding about valid registers.
+
+   Allow REG, REG+REG, REG+INDEX, INDEX+REG, REG-INDEX, and non
+   floating SYMBOL_REF to the constant pool.  Allow REG-only and
+   AUTINC-REG if handling TImode or HImode.  Other symbol refs must be
+   forced though a static cell to ensure addressability.  */
+#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL)                    \
+{                                                                       \
+  if (ARM_BASE_REGISTER_RTX_P (X))                                      \
+    goto LABEL;                                                                 \
+  else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC)        \
+          && GET_CODE (XEXP (X, 0)) == REG                              \
+          && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0)))                       \
+    goto LABEL;                                                                 \
+  else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed                \
+          && (GET_CODE (X) == LABEL_REF                                 \
+              || (GET_CODE (X) == CONST                                 \
+                  && GET_CODE (XEXP ((X), 0)) == PLUS                   \
+                  && GET_CODE (XEXP (XEXP ((X), 0), 0)) == LABEL_REF    \
+                  && GET_CODE (XEXP (XEXP ((X), 0), 1)) == CONST_INT))) \
+    goto LABEL;                                                                 \
+  else if ((MODE) == TImode)                                            \
+    ;                                                                   \
+  else if ((MODE) == DImode || (TARGET_SOFT_FLOAT && (MODE) == DFmode))         \
+    {                                                                   \
+      if (GET_CODE (X) == PLUS && ARM_BASE_REGISTER_RTX_P (XEXP (X, 0))         \
+         && GET_CODE (XEXP (X, 1)) == CONST_INT)                        \
+       {                                                                \
+         HOST_WIDE_INT val = INTVAL (XEXP (X, 1));                      \
+          if (val == 4 || val == -4 || val == -8)                       \
+           goto LABEL;                                                  \
+       }                                                                \
+    }                                                                   \
+  else if (GET_CODE (X) == PLUS)                                        \
+    {                                                                   \
+      rtx xop0 = XEXP (X, 0);                                           \
+      rtx xop1 = XEXP (X, 1);                                           \
+                                                                        \
+      if (ARM_BASE_REGISTER_RTX_P (xop0))                               \
+       ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL);    \
+      else if (ARM_BASE_REGISTER_RTX_P (xop1))                          \
+       ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL);    \
+    }                                                                   \
+  /* Reload currently can't handle MINUS, so disable this for now */    \
+  /* else if (GET_CODE (X) == MINUS)                                    \
+    {                                                                   \
+      rtx xop0 = XEXP (X,0);                                            \
+      rtx xop1 = XEXP (X,1);                                            \
+                                                                        \
+      if (ARM_BASE_REGISTER_RTX_P (xop0))                               \
+       ARM_GO_IF_LEGITIMATE_INDEX (MODE, -1, xop1, LABEL);              \
+    } */                                                                \
+  else if (GET_MODE_CLASS (MODE) != MODE_FLOAT                          \
+          && GET_CODE (X) == SYMBOL_REF                                 \
+          && CONSTANT_POOL_ADDRESS_P (X)                                \
+          && ! (flag_pic                                                \
+                && symbol_mentioned_p (get_pool_constant (X))))         \
+    goto LABEL;                                                                 \
+  else if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_DEC)        \
+          && (GET_MODE_SIZE (MODE) <= 4)                                \
+          && GET_CODE (XEXP (X, 0)) == REG                              \
+          && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0)))                       \
+    goto LABEL;                                                                 \
 }
      
 /* ---------------------thumb version----------------------------------*/     
-#define LEGITIMATE_OFFSET(MODE, VAL)                                   \
+#define THUMB_LEGITIMATE_OFFSET(MODE, VAL)                             \
   (GET_MODE_SIZE (MODE) == 1 ? ((unsigned HOST_WIDE_INT) (VAL) < 32)   \
    : GET_MODE_SIZE (MODE) == 2 ? ((unsigned HOST_WIDE_INT) (VAL) < 64  \
                                  && ((VAL) & 1) == 0)                  \
@@ -2123,9 +2129,9 @@ typedef struct
    better ways to solve some of these problems.  */
 
 /* Although it is not incorrect, we don't accept QImode and HImode
-   addresses based on the frame pointer or arg pointer until the reload pass starts.
-   This is so that eliminating such addresses into stack based ones
-   won't produce impossible code.  */
+   addresses based on the frame pointer or arg pointer until the
+   reload pass starts.  This is so that eliminating such addresses
+   into stack based ones won't produce impossible code.  */
 #define THUMB_GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN)                   \
 {                                                                      \
 /* ??? Not clear if this is right.  Experiment.  */                    \
@@ -2139,7 +2145,8 @@ typedef struct
          || reg_mentioned_p (virtual_stack_vars_rtx, X)))              \
     ;                                                                  \
   /* Accept any base register.  SP only in SImode or larger.  */       \
-  else if (GET_CODE (X) == REG && REG_MODE_OK_FOR_BASE_P (X, MODE))    \
+  else if (GET_CODE (X) == REG                                         \
+          && THUMB_REG_MODE_OK_FOR_BASE_P (X, MODE))                   \
     goto WIN;                                                          \
   /* This is PC relative data before MACHINE_DEPENDENT_REORG runs.  */ \
   else if (GET_MODE_SIZE (MODE) >= 4 && CONSTANT_P (X)                 \
@@ -2156,7 +2163,7 @@ typedef struct
   /* Post-inc indexing only supported for SImode and larger.  */       \
   else if (GET_CODE (X) == POST_INC && GET_MODE_SIZE (MODE) >= 4       \
           && GET_CODE (XEXP (X, 0)) == REG                             \
-          && REG_OK_FOR_INDEX_P (XEXP (X, 0)))                         \
+          && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)))                   \
     goto WIN;                                                          \
   else if (GET_CODE (X) == PLUS)                                       \
     {                                                                  \
@@ -2171,15 +2178,15 @@ typedef struct
          && XEXP (X, 1) != frame_pointer_rtx                           \
          && XEXP (X, 0) != virtual_stack_vars_rtx                      \
          && XEXP (X, 1) != virtual_stack_vars_rtx                      \
-         && REG_OK_FOR_INDEX_P (XEXP (X, 0))                           \
-         && REG_OK_FOR_INDEX_P (XEXP (X, 1)))                          \
+         && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0))                     \
+         && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 1)))                    \
        goto WIN;                                                       \
       /* REG+const has 5-7 bit offset for non-SP registers.  */                \
       else if (GET_CODE (XEXP (X, 0)) == REG                           \
-              && (REG_OK_FOR_INDEX_P (XEXP (X, 0))                     \
+              && (THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0))               \
                   || XEXP (X, 0) == arg_pointer_rtx)                   \
               && GET_CODE (XEXP (X, 1)) == CONST_INT                   \
-              && LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1))))       \
+              && THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
        goto WIN;                                                       \
       /* REG+const has 10 bit offset for SP, but only SImode and       \
         larger is supported.  */                                       \
@@ -2243,7 +2250,8 @@ typedef struct
        xop0 = force_reg (SImode, xop0);                                 \
       if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1))             \
        xop1 = force_reg (SImode, xop1);                                 \
-      if (BASE_REGISTER_RTX_P (xop0) && GET_CODE (xop1) == CONST_INT)   \
+      if (ARM_BASE_REGISTER_RTX_P (xop0)                                \
+         && GET_CODE (xop1) == CONST_INT)                               \
        {                                                                \
          HOST_WIDE_INT n, low_n;                                        \
          rtx base_reg, val;                                             \