arm.c (arm_legtimize_address): New function.
authorRichard Earnshaw <rearnsha@arm.com>
Wed, 29 Jan 2003 16:50:34 +0000 (16:50 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Wed, 29 Jan 2003 16:50:34 +0000 (16:50 +0000)
* arm.c (arm_legtimize_address): New function.
* arm-protos.h (arm_legtimize_address): Add prototype.
* arm.h (ARM_LEGITIMIZE_ADDRESS): Use arm_legitimize_address.
(LEGITIMIZE_ADDRESS, THUMB_LEGITIMIZE_ADDRESS): Wrap with
do ... while (0)

From-SVN: r62091

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

index 52d3f9efeb4513c59c22f230ccefff825137ed79..744f12683d5f54051024bb2f3b6085e5d042f400 100644 (file)
@@ -1,3 +1,11 @@
+2003-01-29  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm.c (arm_legtimize_address): New function.
+       * arm-protos.h (arm_legtimize_address): Add prototype.
+       * arm.h (ARM_LEGITIMIZE_ADDRESS): Use arm_legitimize_address.
+       (LEGITIMIZE_ADDRESS, THUMB_LEGITIMIZE_ADDRESS): Wrap with
+       do ... while (0)
+
 2003-01-29     Joel Sherrill <joel@OARcorp.com>
 
        * gthr-rtems.h: Define __GTHREAD_MUTEX_INIT.  Apparently no code
index 1c3764d61c1530fc07f885194c620ca744067e5a..6fce0ce391a212a5698b02c90fee3ec5d38a158e 100644 (file)
@@ -57,6 +57,7 @@ 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 rtx    arm_legitimize_address   PARAMS ((rtx, rtx, enum machine_mode));
 extern int    const_double_rtx_ok_for_fpu      PARAMS ((rtx));
 extern int    neg_const_double_rtx_ok_for_fpu  PARAMS ((rtx));
 
index 427f68e7bf613eb49a8523d18dec99acc911bc50..576d038a7281506cc449604b9c8af996e886ff14 100644 (file)
@@ -2905,6 +2905,91 @@ thumb_legitimate_offset_p (mode, val)
     }
 }
 
+/* Try machine-dependent ways of modifying an illegitimate address
+   to be legitimate.  If we find one, return the new, valid address.  */
+
+rtx
+arm_legitimize_address (x, orig_x, mode)
+     rtx x;
+     rtx orig_x;
+     enum machine_mode mode;
+{
+  if (GET_CODE (x) == PLUS)
+    {
+      rtx xop0 = XEXP (x, 0);
+      rtx xop1 = XEXP (x, 1);
+
+      if (CONSTANT_P (xop0) && !symbol_mentioned_p (xop0))
+       xop0 = force_reg (SImode, xop0);
+
+      if (CONSTANT_P (xop1) && !symbol_mentioned_p (xop1))
+       xop1 = force_reg (SImode, xop1);
+
+      if (ARM_BASE_REGISTER_RTX_P (xop0)
+         && GET_CODE (xop1) == CONST_INT)
+       {
+         HOST_WIDE_INT n, low_n;
+         rtx base_reg, val;
+         n = INTVAL (xop1);
+
+         if (mode == DImode || (TARGET_SOFT_FLOAT && mode == DFmode))
+           {
+             low_n = n & 0x0f;
+             n &= ~0x0f;
+             if (low_n > 4)
+               {
+                 n += 16;
+                 low_n -= 16;
+               }
+           }
+         else
+           {
+             low_n = ((mode) == TImode ? 0
+                      : n >= 0 ? (n & 0xfff) : -((-n) & 0xfff));
+             n -= low_n;
+           }
+
+         base_reg = gen_reg_rtx (SImode);
+         val = force_operand (gen_rtx_PLUS (SImode, xop0,
+                                            GEN_INT (n)), NULL_RTX);
+         emit_move_insn (base_reg, val);
+         x = (low_n == 0 ? base_reg
+              : gen_rtx_PLUS (SImode, base_reg, GEN_INT (low_n)));
+       }
+      else if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
+       x = gen_rtx_PLUS (SImode, xop0, xop1);
+    }
+
+  /* XXX We don't allow MINUS any more -- see comment in
+     arm_legitimate_address_p ().  */
+  else if (GET_CODE (x) == MINUS)
+    {
+      rtx xop0 = XEXP (x, 0);
+      rtx xop1 = XEXP (x, 1);
+
+      if (CONSTANT_P (xop0))
+       xop0 = force_reg (SImode, xop0);
+
+      if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1))
+       xop1 = force_reg (SImode, xop1);
+
+      if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
+       x = gen_rtx_MINUS (SImode, xop0, xop1);
+    }
+
+  if (flag_pic)
+    {
+      /* We need to find and carefully transform any SYMBOL and LABEL
+        references; so go back to the original address expression.  */
+      rtx new_x = legitimize_pic_address (orig_x, mode, NULL_RTX);
+
+      if (new_x != orig_x)
+       x = new_x;
+    }
+
+  return x;
+}
+
 \f
 
 #define REG_OR_SUBREG_REG(X)                                           \
index fb82ebcf68ba7cfc4e312b54f651cc9f3fad7f33..9f3420beb26cf324935fb76e57fe5a158ecca5b0 100644 (file)
@@ -1964,92 +1964,28 @@ typedef struct
 
 \f
 /* Try machine-dependent ways of modifying an illegitimate address
-   to be legitimate.  If we find one, return the new, valid address.
-   This macro is used in only one place: `memory_address' in explow.c.
-
-   OLDX is the address as it was before break_out_memory_refs was called.
-   In some cases it is useful to look at this to decide what needs to be done.
-
-   MODE and WIN are passed so that this macro can use
-   GO_IF_LEGITIMATE_ADDRESS.
-
-   It is always safe for this macro to do nothing.  It exists to recognize
-   opportunities to optimize the output.
-
-   On the ARM, try to convert [REG, #BIGCONST]
-   into ADD BASE, REG, #UPPERCONST and [BASE, #VALIDCONST],
-   where VALIDCONST == 0 in case of TImode.  */
-#define ARM_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)                      \
-{                                                                       \
-  if (GET_CODE (X) == PLUS)                                             \
-    {                                                                   \
-      rtx xop0 = XEXP (X, 0);                                           \
-      rtx xop1 = XEXP (X, 1);                                           \
-                                                                        \
-      if (CONSTANT_P (xop0) && ! symbol_mentioned_p (xop0))             \
-       xop0 = force_reg (SImode, xop0);                                 \
-      if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1))             \
-       xop1 = force_reg (SImode, xop1);                                 \
-      if (ARM_BASE_REGISTER_RTX_P (xop0)                                \
-         && GET_CODE (xop1) == CONST_INT)                               \
-       {                                                                \
-         HOST_WIDE_INT n, low_n;                                        \
-         rtx base_reg, val;                                             \
-         n = INTVAL (xop1);                                             \
-                                                                        \
-         if (MODE == DImode || (TARGET_SOFT_FLOAT && MODE == DFmode))   \
-           {                                                            \
-             low_n = n & 0x0f;                                          \
-             n &= ~0x0f;                                                \
-             if (low_n > 4)                                             \
-               {                                                        \
-                 n += 16;                                               \
-                 low_n -= 16;                                           \
-               }                                                        \
-           }                                                            \
-         else                                                           \
-           {                                                            \
-             low_n = ((MODE) == TImode ? 0                              \
-                      : n >= 0 ? (n & 0xfff) : -((-n) & 0xfff));        \
-             n -= low_n;                                                \
-           }                                                            \
-         base_reg = gen_reg_rtx (SImode);                               \
-         val = force_operand (gen_rtx_PLUS (SImode, xop0,               \
-                                            GEN_INT (n)), NULL_RTX);    \
-         emit_move_insn (base_reg, val);                                \
-         (X) = (low_n == 0 ? base_reg                                   \
-                : gen_rtx_PLUS (SImode, base_reg, GEN_INT (low_n)));    \
-       }                                                                \
-      else if (xop0 != XEXP (X, 0) || xop1 != XEXP (x, 1))              \
-       (X) = gen_rtx_PLUS (SImode, xop0, xop1);                         \
-    }                                                                   \
-  else if (GET_CODE (X) == MINUS)                                       \
-    {                                                                   \
-      rtx xop0 = XEXP (X, 0);                                           \
-      rtx xop1 = XEXP (X, 1);                                           \
-                                                                        \
-      if (CONSTANT_P (xop0))                                            \
-       xop0 = force_reg (SImode, xop0);                                 \
-      if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1))             \
-       xop1 = force_reg (SImode, xop1);                                 \
-      if (xop0 != XEXP (X, 0) || xop1 != XEXP (X, 1))                   \
-       (X) = gen_rtx_MINUS (SImode, xop0, xop1);                        \
-    }                                                                   \
-  if (flag_pic)                                                                 \
-    (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX);                \
-  if (memory_address_p (MODE, X))                                       \
-    goto WIN;                                                           \
-}
+   to be legitimate.  If we find one, return the new, valid address.  */
+#define ARM_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)     \
+do {                                                   \
+  X = arm_legitimize_address (X, OLDX, MODE);          \
+                                                       \
+  if (memory_address_p (MODE, X))                      \
+    goto WIN;                                          \
+} while (0)
 
-#define THUMB_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)   \
-  if (flag_pic)                                                \
-    (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX);               
-     
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-  if (TARGET_ARM)                              \
-    ARM_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN)        \
-  else                                         \
-    THUMB_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN)
+#define THUMB_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)           \
+do {                                                           \
+  if (flag_pic)                                                        \
+    (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX);       \
+} while (0)
+
+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)         \
+do {                                                   \
+  if (TARGET_ARM)                                      \
+    ARM_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN);       \
+  else                                                 \
+    THUMB_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN);     \
+} while (0)
      
 /* Go to LABEL if ADDR (a legitimate address expression)
    has an effect that depends on the machine mode it is used for.  */