* arm.c (arm_address_register_rtx_p): New function.
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Jan 2003 16:01:43 +0000 (16:01 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Jan 2003 16:01:43 +0000 (16:01 +0000)
(arm_legitimate_address_p): New function.
(arm_legitimate_index_p): New function.
(legitimize_pic_address): Use arm_legitimate_index_p.
* arm-protos.h (arm_legtimate_address_p): Add prototype.
* arm.h (ARM_GO_IF_LEGITIMATE_INDEX): Delete.
(ARM_GO_IF_LEGITIMATE_ADDRESS): Call arm_legitimate_address_p.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@61592 138bc75d-0d04-0410-961f-82ee72b054a4

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

index bc7370c..e110c0e 100644 (file)
@@ -1,3 +1,13 @@
+2003-01-22  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm.c (arm_address_register_rtx_p): New function.
+       (arm_legitimate_address_p): New function.
+       (arm_legitimate_index_p): New function.
+       (legitimize_pic_address): Use arm_legitimate_index_p.
+       * arm-protos.h (arm_legtimate_address_p): Add prototype.
+       * arm.h (ARM_GO_IF_LEGITIMATE_INDEX): Delete.
+       (ARM_GO_IF_LEGITIMATE_ADDRESS): Call arm_legitimate_address_p.
+
 2003-01-22  Hartmut Penner  <hpenner@de.ibm.com>
 
        * config/s390/s390.md (floatdfdi2): Insn has type 'itof'.
index 861642a..83788a0 100644 (file)
@@ -52,6 +52,7 @@ extern int    arm_split_constant      PARAMS ((RTX_CODE, enum machine_mode,
 extern RTX_CODE arm_canonicalize_comparison PARAMS ((RTX_CODE, rtx *));
 extern int    legitimate_pic_operand_p PARAMS ((rtx));
 extern rtx    legitimize_pic_address   PARAMS ((rtx, enum machine_mode, rtx));
+extern int    arm_legitimate_address_p  PARAMS ((enum machine_mode, rtx, int));
 extern int    arm_rtx_costs            PARAMS ((rtx, RTX_CODE, RTX_CODE));
 extern int    const_double_rtx_ok_for_fpu      PARAMS ((rtx));
 extern int    neg_const_double_rtx_ok_for_fpu  PARAMS ((rtx));
index 9f65028..4a8d85a 100644 (file)
@@ -68,6 +68,9 @@ const struct attribute_spec arm_attribute_table[];
 static void      arm_add_gc_roots              PARAMS ((void));
 static int       arm_gen_constant              PARAMS ((enum rtx_code, Mmode, Hint, rtx, rtx, int, int));
 static unsigned  bit_count                     PARAMS ((Ulong));
+static int      arm_address_register_rtx_p     PARAMS ((rtx, int));
+static int      arm_legitimate_index_p         PARAMS ((enum machine_mode,
+                                                        rtx, int));
 static int       const_ok_for_op               PARAMS ((Hint, enum rtx_code));
 static int       eliminate_lr2ip               PARAMS ((rtx *));
 static rtx      emit_multi_reg_push            PARAMS ((int));
@@ -2357,6 +2360,10 @@ arm_function_ok_for_sibcall (decl, exp)
 }
 
 \f
+/* Addressing mode support functions.  */
+
+/* Return non-zero if X is a legitimate immediate operand when compiling
+   for PIC.  */
 int
 legitimate_pic_operand_p (x)
      rtx x;
@@ -2463,14 +2470,14 @@ legitimize_pic_address (orig, mode, reg)
        {
          /* The base register doesn't really matter, we only want to
             test the index for the appropriate mode.  */
-         ARM_GO_IF_LEGITIMATE_INDEX (mode, 0, offset, win);
-
-         if (!no_new_pseudos)
-           offset = force_reg (Pmode, offset);
-         else
-           abort ();
+         if (!arm_legitimate_index_p (mode, offset, 0))
+           {
+             if (!no_new_pseudos)
+               offset = force_reg (Pmode, offset);
+             else
+               abort ();
+           }
 
-       win:
          if (GET_CODE (offset) == CONST_INT)
            return plus_constant (base, INTVAL (offset));
        }
@@ -2548,6 +2555,171 @@ arm_finalize_pic (prologue)
 #endif /* AOF_ASSEMBLER */
 }
 
+/* Return nonzero if X is valid as an ARM state addressing register.  */
+static int
+arm_address_register_rtx_p (x, strict_p)
+     rtx x;
+     int strict_p;
+{
+  int regno;
+
+  if (GET_CODE (x) != REG)
+    return 0;
+
+  regno = REGNO (x);
+
+  if (strict_p)
+    return ARM_REGNO_OK_FOR_BASE_P (regno);
+
+  return (regno <= LAST_ARM_REGNUM
+         || regno >= FIRST_PSEUDO_REGISTER
+         || regno == FRAME_POINTER_REGNUM
+         || regno == ARG_POINTER_REGNUM);
+}
+
+/* Return nonzero if X is a valid ARM state address operand.  */
+int
+arm_legitimate_address_p (mode, x, strict_p)
+     enum machine_mode mode;
+     rtx x;
+     int strict_p;
+{
+  if (arm_address_register_rtx_p (x, strict_p))
+    return 1;
+
+  else if (GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC)
+    return arm_address_register_rtx_p (XEXP (x, 0), strict_p);
+
+  else if ((GET_CODE (x) == POST_MODIFY || GET_CODE (x) == PRE_MODIFY)
+          && GET_MODE_SIZE (mode) <= 4
+          && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
+          && GET_CODE (XEXP (x, 1)) == PLUS
+          && XEXP (XEXP (x, 1), 0) == XEXP (x, 0))
+    return arm_legitimate_index_p (mode, XEXP (XEXP (x, 1), 1), strict_p);
+
+  /* After reload constants split into minipools will have addresses
+     from a LABEL_REF.  */
+  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)))
+    return 1;
+
+  else if (mode == TImode)
+    return 0;
+
+  else if (mode == DImode || (TARGET_SOFT_FLOAT && mode == DFmode))
+    {
+      if (GET_CODE (x) == PLUS
+         && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
+         && GET_CODE (XEXP (x, 1)) == CONST_INT)
+       {
+         HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
+
+          if (val == 4 || val == -4 || val == -8)
+           return 1;
+       }
+    }
+
+  else if (GET_CODE (x) == PLUS)
+    {
+      rtx xop0 = XEXP (x, 0);
+      rtx xop1 = XEXP (x, 1);
+
+      return ((arm_address_register_rtx_p (xop0, strict_p)
+              && arm_legitimate_index_p (mode, xop1, strict_p))
+             || (arm_address_register_rtx_p (xop1, strict_p)
+                 && arm_legitimate_index_p (mode, xop0, strict_p)));
+    }
+
+#if 0
+  /* 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);
+
+      return (arm_address_register_rtx_p (xop0, strict_p)
+             && arm_legitimate_index_p (mode, xop1, strict_p));
+    }
+#endif
+
+  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))))
+    return 1;
+
+  else if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == POST_DEC)
+          && (GET_MODE_SIZE (mode) <= 4)
+          && arm_address_register_rtx_p (XEXP (x, 0), strict_p))
+    return 1;
+
+  return 0;
+}
+
+/* Return nonzero if INDEX is valid for an address index operand in
+   ARM state.  */
+static int
+arm_legitimate_index_p (mode, index, strict_p)
+     enum machine_mode mode;
+     rtx index;
+     int strict_p;
+{
+  HOST_WIDE_INT range;
+  enum rtx_code code = GET_CODE (index);
+
+  if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
+    return (code == CONST_INT && INTVAL (index) < 1024
+           && INTVAL (index) > -1024
+           && (INTVAL (index) & 3) == 0);
+
+  if (arm_address_register_rtx_p (index, strict_p)
+      && GET_MODE_SIZE (mode) <= 4)
+    return 1;
+
+  /* XXX What about ldrsb?  */
+  if (GET_MODE_SIZE (mode) <= 4  && code == MULT
+      && (!arm_arch4 || (mode) != HImode))
+    {
+      rtx xiop0 = XEXP (index, 0);
+      rtx xiop1 = XEXP (index, 1);
+
+      return ((arm_address_register_rtx_p (xiop0, strict_p)
+              && power_of_two_operand (xiop1, SImode))
+             || (arm_address_register_rtx_p (xiop1, strict_p)
+                 && power_of_two_operand (xiop0, SImode)));
+    }
+
+  if (GET_MODE_SIZE (mode) <= 4
+      && (code == LSHIFTRT || code == ASHIFTRT
+         || code == ASHIFT || code == ROTATERT)
+      && (!arm_arch4 || (mode) != HImode))
+    {
+      rtx op = XEXP (index, 1);
+
+      return (arm_address_register_rtx_p (XEXP (index, 0), strict_p)
+             && GET_CODE (op) == CONST_INT
+             && INTVAL (op) > 0
+             && INTVAL (op) <= 31);
+    }
+
+  /* XXX For ARM v4 we may be doing a sign-extend operation during the
+     load, but that has a restricted addressing range and we are unable
+     to tell here whether that is the case.  To be safe we restrict all
+     loads to that range.  */
+  range = ((mode) == HImode || (mode) == QImode)
+    ? (arm_arch4 ? 256 : 4095) : 4096;
+
+  return (code == CONST_INT
+         && INTVAL (index) < range
+         && INTVAL (index) > -range);
+}  
+\f
+
 #define REG_OR_SUBREG_REG(X)                                           \
   (GET_CODE (X) == REG                                                 \
    || (GET_CODE (X) == SUBREG && GET_CODE (SUBREG_REG (X)) == REG))
index 48292a4..c070801 100644 (file)
@@ -1943,134 +1943,19 @@ typedef struct
 #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 ARM_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 (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;                                                 \
-       }                                                               \
-    }                                                                  \
-  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_CODE (X) == POST_MODIFY || GET_CODE (X) == PRE_MODIFY)  \
-          && GET_MODE_SIZE (MODE) <= 4                                  \
-          && GET_CODE (XEXP (X, 0)) == REG                              \
-          && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0))                        \
-          && GET_CODE (XEXP (X, 1)) == PLUS                             \
-          && XEXP (XEXP (X, 1), 0) == XEXP (X, 0))                      \
-    ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (XEXP (X, 0)),              \
-                               XEXP (XEXP (X, 1), 1), 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;                                                                 \
-}
+#ifdef REG_OK_STRICT
+#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN)       \
+  {                                                    \
+    if (arm_legitimate_address_p (MODE, X, 1))         \
+      goto WIN;                                                \
+  }
+#else
+#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN)       \
+  {                                                    \
+    if (arm_legitimate_address_p (MODE, X, 0))         \
+      goto WIN;                                                \
+  }
+#endif
 
 /* ---------------------thumb version----------------------------------*/     
 #define THUMB_LEGITIMATE_OFFSET(MODE, VAL)                             \