OSDN Git Service

* arm.c (thumb_base_register_rtx_p): New function.
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 23 Jan 2003 18:10:46 +0000 (18:10 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 23 Jan 2003 18:10:46 +0000 (18:10 +0000)
(thumb_index_register_rtx_p): New function.
(thumb_legitimate_address_p): New function.
(thumb_legitimate_offset_p): New function.
* arm.h (REG_STRICT_P): Define according to setting of REG_OK_STRICT.
(ARM_GO_IF_LEGITIMATE_ADDRESS): Use REG_STRICT_P to avoid dumplicate
definitions.
(THUMB_GO_IF_LEGITIMATE_ADDRESS): Use thumb_legitimate_address_p.
(THUMB_LEGITIMATE_OFFSET): Delte.
(THUMB_LEGITIMIZE_RELOAD_ADDRESS): Use thumb_legitimate_offset.
* arm-protos.h (thumb_legitimate_address_p): Add prototype.
(thumb_legitimate_offset_p): Likewise.

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

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

index abec0a1..4eac1f6 100644 (file)
@@ -1,3 +1,18 @@
+2003-01-23  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm.c (thumb_base_register_rtx_p): New function.
+       (thumb_index_register_rtx_p): New function.
+       (thumb_legitimate_address_p): New function.
+       (thumb_legitimate_offset_p): New function.
+       * arm.h (REG_STRICT_P): Define according to setting of REG_OK_STRICT.
+       (ARM_GO_IF_LEGITIMATE_ADDRESS): Use REG_STRICT_P to avoid dumplicate
+       definitions.
+       (THUMB_GO_IF_LEGITIMATE_ADDRESS): Use thumb_legitimate_address_p.
+       (THUMB_LEGITIMATE_OFFSET): Delte.
+       (THUMB_LEGITIMIZE_RELOAD_ADDRESS): Use thumb_legitimate_offset.
+       * arm-protos.h (thumb_legitimate_address_p): Add prototype.
+       (thumb_legitimate_offset_p): Likewise.
+
 2003-01-23  Andreas Schwab  <schwab@suse.de>
 
        * unwind.h (_Unwind_GetTextRelBase): Mark parameter as unused.
index 83788a0..af0320e 100644 (file)
@@ -53,6 +53,10 @@ 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    thumb_legitimate_address_p PARAMS ((enum machine_mode, rtx,
+                                                 int));
+extern int    thumb_legitimate_offset_p        PARAMS ((enum machine_mode,
+                                                HOST_WIDE_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 4a8d85a..4bffcb5 100644 (file)
@@ -71,6 +71,10 @@ 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      thumb_base_register_rtx_p      PARAMS ((rtx, 
+                                                        enum machine_mode,
+                                                        int));
+inline static int thumb_index_register_rtx_p   PARAMS ((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));
@@ -2717,7 +2721,177 @@ arm_legitimate_index_p (mode, index, strict_p)
   return (code == CONST_INT
          && INTVAL (index) < range
          && INTVAL (index) > -range);
-}  
+}
+
+/* Return nonzero if X is valid as an ARM state addressing register.  */
+static int
+thumb_base_register_rtx_p (x, mode, strict_p)
+     rtx x;
+     enum machine_mode mode;
+     int strict_p;
+{
+  int regno;
+
+  if (GET_CODE (x) != REG)
+    return 0;
+
+  regno = REGNO (x);
+
+  if (strict_p)
+    return THUMB_REGNO_MODE_OK_FOR_BASE_P (regno, mode);
+
+  return (regno <= LAST_LO_REGNUM
+         || regno >= FIRST_PSEUDO_REGISTER
+         || regno == FRAME_POINTER_REGNUM
+         || (GET_MODE_SIZE (mode) >= 4
+             && (regno == STACK_POINTER_REGNUM
+                 || x == hard_frame_pointer_rtx
+                 || x == arg_pointer_rtx)));
+}
+
+/* Return nonzero if x is a legitimate index register.  This is the case
+   for any base register that can access a QImode object.  */
+inline static int
+thumb_index_register_rtx_p (x, strict_p)
+     rtx x;
+     int strict_p;
+{
+  return thumb_base_register_rtx_p (x, QImode, strict_p);
+}
+
+/* Return nonzero if x is a legitimate Thumb-state address.
+   The AP may be eliminated to either the SP or the FP, so we use the
+   least common denominator, e.g. SImode, and offsets from 0 to 64.
+
+   ??? Verify whether the above is the right approach.
+
+   ??? Also, the FP may be eliminated to the SP, so perhaps that
+   needs special handling also.
+
+   ??? Look at how the mips16 port solves this problem.  It probably uses
+   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.  */
+int
+thumb_legitimate_address_p (mode, x, strict_p)
+     enum machine_mode mode;
+     rtx x;
+     int strict_p;
+{
+  /* ??? Not clear if this is right.  Experiment.  */
+  if (GET_MODE_SIZE (mode) < 4
+      && !(reload_in_progress || reload_completed)
+      && (reg_mentioned_p (frame_pointer_rtx, x)
+         || reg_mentioned_p (arg_pointer_rtx, x)
+         || reg_mentioned_p (virtual_incoming_args_rtx, x)
+         || reg_mentioned_p (virtual_outgoing_args_rtx, x)
+         || reg_mentioned_p (virtual_stack_dynamic_rtx, x)
+         || reg_mentioned_p (virtual_stack_vars_rtx, x)))
+    return 0;
+
+  /* Accept any base register.  SP only in SImode or larger.  */
+  else if (thumb_base_register_rtx_p (x, mode, strict_p))
+    return 1;
+
+  /* This is PC relative data before MACHINE_DEPENDENT_REORG runs.  */
+  else if (GET_MODE_SIZE (mode) >= 4 && CONSTANT_P (x)
+          && GET_CODE (x) == SYMBOL_REF
+           && CONSTANT_POOL_ADDRESS_P (x) && ! flag_pic)
+    return 1;
+
+  /* This is PC relative data after MACHINE_DEPENDENT_REORG runs.  */
+  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;
+
+  /* Post-inc indexing only supported for SImode and larger.  */
+  else if (GET_CODE (x) == POST_INC && GET_MODE_SIZE (mode) >= 4
+          && thumb_index_register_rtx_p (XEXP (x, 0), strict_p))
+    return 1;
+
+  else if (GET_CODE (x) == PLUS)
+    {
+      /* REG+REG address can be any two index registers.  */
+      /* We disallow FRAME+REG addressing since we know that FRAME
+        will be replaced with STACK, and SP relative addressing only
+        permits SP+OFFSET.  */
+      if (GET_MODE_SIZE (mode) <= 4
+         && XEXP (x, 0) != frame_pointer_rtx
+         && XEXP (x, 1) != frame_pointer_rtx
+         && XEXP (x, 0) != virtual_stack_vars_rtx
+         && XEXP (x, 1) != virtual_stack_vars_rtx
+         && thumb_index_register_rtx_p (XEXP (x, 0), strict_p)
+         && thumb_index_register_rtx_p (XEXP (x, 1), strict_p))
+       return 1;
+
+      /* REG+const has 5-7 bit offset for non-SP registers.  */
+      else if ((thumb_index_register_rtx_p (XEXP (x, 0), strict_p)
+               || XEXP (x, 0) == arg_pointer_rtx)
+              && GET_CODE (XEXP (x, 1)) == CONST_INT
+              && thumb_legitimate_offset_p (mode, INTVAL (XEXP (x, 1))))
+       return 1;
+
+      /* REG+const has 10 bit offset for SP, but only SImode and
+        larger is supported.  */
+      /* ??? Should probably check for DI/DFmode overflow here
+        just like GO_IF_LEGITIMATE_OFFSET does.  */
+      else if (GET_CODE (XEXP (x, 0)) == REG
+              && REGNO (XEXP (x, 0)) == STACK_POINTER_REGNUM
+              && GET_MODE_SIZE (mode) >= 4
+              && GET_CODE (XEXP (x, 1)) == CONST_INT
+              && INTVAL (XEXP (x, 1)) >= 0
+              && INTVAL (XEXP (x, 1)) + GET_MODE_SIZE (mode) <= 1024
+              && (INTVAL (XEXP (x, 1)) & 3) == 0)
+       return 1;
+
+      else if (GET_CODE (XEXP (x, 0)) == REG
+              && REGNO (XEXP (x, 0)) == FRAME_POINTER_REGNUM
+              && GET_MODE_SIZE (mode) >= 4
+              && GET_CODE (XEXP (x, 1)) == CONST_INT
+              && (INTVAL (XEXP (x, 1)) & 3) == 0)
+       return 1;
+    }
+
+  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;
+
+  return 0;
+}
+
+/* Return nonzero if VAL can be used as an offset in a Thumb-state address
+   instruction of mode MODE.  */
+int
+thumb_legitimate_offset_p (mode, val)
+     enum machine_mode mode;
+     HOST_WIDE_INT val;
+{
+  switch (GET_MODE_SIZE (mode))
+    {
+    case 1:
+      return val >= 0 && val < 32;
+
+    case 2:
+      return val >= 0 && val < 64 && (val & 1) == 0;
+
+    default:
+      return (val >= 0
+             && (val + GET_MODE_SIZE (mode)) <= 128
+             && (val & 3) == 0);
+    }
+}
+
 \f
 
 #define REG_OR_SUBREG_REG(X)                                           \
index c070801..2b205fc 100644 (file)
@@ -1268,7 +1268,7 @@ enum reg_class
       && GET_CODE (XEXP (X, 0)) == REG                                 \
       && XEXP (X, 0) == stack_pointer_rtx                              \
       && GET_CODE (XEXP (X, 1)) == CONST_INT                           \
-      && ! THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1))))       \
+      && ! thumb_legitimate_offset_p (MODE, INTVAL (XEXP (X, 1))))     \
     {                                                                  \
       rtx orig_X = X;                                                  \
       X = copy_rtx (X);                                                        \
@@ -1897,6 +1897,8 @@ typedef struct
           || (X) == hard_frame_pointer_rtx     \
           || (X) == arg_pointer_rtx)))
 
+#define REG_STRICT_P 0
+
 #else /* REG_OK_STRICT */
 
 #define ARM_REG_OK_FOR_BASE_P(X)               \
@@ -1905,6 +1907,8 @@ typedef struct
 #define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE)  \
   THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO (X), MODE)
 
+#define REG_STRICT_P 1
+
 #endif /* REG_OK_STRICT */
 
 /* Now define some helpers in terms of the above.  */
@@ -1932,145 +1936,32 @@ typedef struct
 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
    that is a valid memory address for an instruction.
    The MODE argument is the machine mode for the MEM expression
-   that wants to use this address.
-
-   The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS. */
+   that wants to use this address.  */
      
-/* --------------------------------arm version----------------------------- */
 #define ARM_BASE_REGISTER_RTX_P(X)  \
   (GET_CODE (X) == REG && ARM_REG_OK_FOR_BASE_P (X))
 
 #define ARM_INDEX_REGISTER_RTX_P(X)  \
   (GET_CODE (X) == REG && ARM_REG_OK_FOR_INDEX_P (X))
 
-#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;                                                \
+#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN)               \
+  {                                                            \
+    if (arm_legitimate_address_p (MODE, X, REG_STRICT_P))      \
+      goto WIN;                                                        \
   }
-#endif
-
-/* ---------------------thumb version----------------------------------*/     
-#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)                  \
-   : ((VAL) >= 0 && ((VAL) + GET_MODE_SIZE (MODE)) <= 128              \
-      && ((VAL) & 3) == 0))
-
-/* The AP may be eliminated to either the SP or the FP, so we use the
-   least common denominator, e.g. SImode, and offsets from 0 to 64.  */
-
-/* ??? Verify whether the above is the right approach.  */
 
-/* ??? Also, the FP may be eliminated to the SP, so perhaps that
-   needs special handling also.  */
-
-/* ??? Look at how the mips16 port solves this problem.  It probably uses
-   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.  */
-#define THUMB_GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN)                   \
-{                                                                      \
-/* ??? Not clear if this is right.  Experiment.  */                    \
-  if (GET_MODE_SIZE (MODE) < 4                                         \
-      && ! (reload_in_progress || reload_completed)                    \
-      && (   reg_mentioned_p (frame_pointer_rtx, X)                    \
-         || reg_mentioned_p (arg_pointer_rtx, X)                       \
-         || reg_mentioned_p (virtual_incoming_args_rtx, X)             \
-         || reg_mentioned_p (virtual_outgoing_args_rtx, X)             \
-         || reg_mentioned_p (virtual_stack_dynamic_rtx, X)             \
-         || reg_mentioned_p (virtual_stack_vars_rtx, X)))              \
-    ;                                                                  \
-  /* Accept any base register.  SP only in SImode or larger.  */       \
-  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)                 \
-          && GET_CODE (X) == SYMBOL_REF                                \
-           && CONSTANT_POOL_ADDRESS_P (X) && ! flag_pic)               \
-    goto WIN;                                                          \
-  /* This is PC relative data after MACHINE_DEPENDENT_REORG runs.  */  \
-  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 WIN;                                                          \
-  /* 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                             \
-          && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)))                   \
-    goto WIN;                                                          \
-  else if (GET_CODE (X) == PLUS)                                       \
-    {                                                                  \
-      /* REG+REG address can be any two index registers.  */           \
-      /* We disallow FRAME+REG addressing since we know that FRAME     \
-        will be replaced with STACK, and SP relative addressing only   \
-        permits SP+OFFSET.  */                                         \
-      if (GET_MODE_SIZE (MODE) <= 4                                    \
-         && GET_CODE (XEXP (X, 0)) == REG                              \
-         && GET_CODE (XEXP (X, 1)) == REG                              \
-         && XEXP (X, 0) != frame_pointer_rtx                           \
-         && XEXP (X, 1) != frame_pointer_rtx                           \
-         && XEXP (X, 0) != virtual_stack_vars_rtx                      \
-         && XEXP (X, 1) != virtual_stack_vars_rtx                      \
-         && 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                           \
-              && (THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0))               \
-                  || XEXP (X, 0) == arg_pointer_rtx)                   \
-              && GET_CODE (XEXP (X, 1)) == CONST_INT                   \
-              && 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.  */                                       \
-      /* ??? Should probably check for DI/DFmode overflow here         \
-        just like GO_IF_LEGITIMATE_OFFSET does.  */                    \
-      else if (GET_CODE (XEXP (X, 0)) == REG                           \
-              && REGNO (XEXP (X, 0)) == STACK_POINTER_REGNUM           \
-              && GET_MODE_SIZE (MODE) >= 4                             \
-              && GET_CODE (XEXP (X, 1)) == CONST_INT                   \
-              && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (X, 1))        \
-                  + GET_MODE_SIZE (MODE)) <= 1024                      \
-              && (INTVAL (XEXP (X, 1)) & 3) == 0)                      \
-       goto WIN;                                                       \
-      else if (GET_CODE (XEXP (X, 0)) == REG                           \
-              && REGNO (XEXP (X, 0)) == FRAME_POINTER_REGNUM           \
-              && GET_MODE_SIZE (MODE) >= 4                             \
-              && GET_CODE (XEXP (X, 1)) == CONST_INT                   \
-              && (INTVAL (XEXP (X, 1)) & 3) == 0)                      \
-       goto WIN;                                                       \
-    }                                                                  \
-  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 WIN;                                                          \
-}
+#define THUMB_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN)             \
+  {                                                            \
+    if (thumb_legitimate_address_p (MODE, X, REG_STRICT_P))    \
+      goto WIN;                                                        \
+  }
 
-/* ------------------------------------------------------------------- */
 #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN)                         \
   if (TARGET_ARM)                                                      \
     ARM_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN)                        \
   else /* if (TARGET_THUMB) */                                         \
     THUMB_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN)      
-/* ------------------------------------------------------------------- */
+
 \f
 /* Try machine-dependent ways of modifying an illegitimate address
    to be legitimate.  If we find one, return the new, valid address.