]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
alpha.c (alpha_legitimate_address_p): New.
authorRichard Henderson <rth@redhat.com>
Wed, 5 Sep 2001 08:43:13 +0000 (01:43 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 5 Sep 2001 08:43:13 +0000 (01:43 -0700)
        * config/alpha/alpha.c (alpha_legitimate_address_p): New.
        * config/alpha/alpha-protos.h: Declare it.
        * config/alpha/alpha.h (GO_IF_LEGITIMATE_ADDRESS): Move to c file.
        (NONSTRICT_REG_OK_FOR_BASE_P): Rename from non-strict macro.
        (NONSTRICT_REG_OK_FP_BASE_P): Likewise.
        (STRICT_REG_OK_FOR_BASE_P): Rename from strict macro.
        (REG_OK_FOR_BASE_P): Select one of the above.

From-SVN: r45405

gcc/ChangeLog
gcc/config/alpha/alpha-protos.h
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/alpha/alpha.md

index 93113e7d9d606aad2a7f985a884e09eef5b1c6d3..7554869b88ff5776d379031821569e1c4c521abc 100644 (file)
@@ -1,3 +1,13 @@
+2001-09-05  Richard Henderson  <rth@redhat.com>
+
+       * config/alpha/alpha.c (alpha_legitimate_address_p): New.
+       * config/alpha/alpha-protos.h: Declare it.
+       * config/alpha/alpha.h (GO_IF_LEGITIMATE_ADDRESS): Move to c file.
+       (NONSTRICT_REG_OK_FOR_BASE_P): Rename from non-strict macro.
+       (NONSTRICT_REG_OK_FP_BASE_P): Likewise.
+       (STRICT_REG_OK_FOR_BASE_P): Rename from strict macro.
+       (REG_OK_FOR_BASE_P): Select one of the above.
+
 2001-09-05  Richard Sandiford  <rsandifo@redhat.com>
 
        * config/mips/t-elf (EXTRA_PARTS): Use EXTRA_MULTILIB_PARTS instead.
index 025f3af5e8796517c5e8b1727f8f09859956193b..7de2c62d717236332d1bea4f4ad5e39e92eba77a 100644 (file)
@@ -73,6 +73,7 @@ extern int addition_operation PARAMS ((rtx, enum machine_mode));
 extern rtx alpha_tablejump_addr_vec PARAMS ((rtx));
 extern rtx alpha_tablejump_best_label PARAMS ((rtx));
 
+extern bool alpha_legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
 extern rtx alpha_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
 extern rtx alpha_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
                                                    int, int, int));
index ca4be61da34a5defb24319a759d8515fb978f060..45b6f72472dee5b2d4976621ca5ffcf9abec0e77 100644 (file)
@@ -1154,6 +1154,77 @@ alpha_tablejump_best_label (insn)
   return best_label ? best_label : const0_rtx;
 }
 \f
+/* legitimate_address_p 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.
+
+   For Alpha, we have either a constant address or the sum of a
+   register and a constant address, or just a register.  For DImode,
+   any of those forms can be surrounded with an AND that clear the
+   low-order three bits; this is an "unaligned" access.  */
+
+bool
+alpha_legitimate_address_p (mode, x, strict)
+     enum machine_mode mode;
+     rtx x;
+     int strict;
+{
+  /* If this is an ldq_u type address, discard the outer AND.  */
+  if (mode == DImode
+      && GET_CODE (x) == AND
+      && GET_CODE (XEXP (x, 1)) == CONST_INT
+      && INTVAL (XEXP (x, 1)) == -8)
+    x = XEXP (x, 0);
+
+  /* Discard non-paradoxical subregs.  */
+  if (GET_CODE (x) == SUBREG
+      && (GET_MODE_SIZE (GET_MODE (x))
+         < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
+    x = SUBREG_REG (x);
+
+  /* Unadorned general registers are valid.  */
+  if (REG_P (x)
+      && (strict
+         ? STRICT_REG_OK_FOR_BASE_P (x)
+         : NONSTRICT_REG_OK_FOR_BASE_P (x)))
+    return true;
+
+  /* Constant addresses (i.e. +/- 32k) are valid.  */
+  if (CONSTANT_ADDRESS_P (x))
+    return true;
+
+  /* Register plus a small constant offset is valid.  */
+  if (GET_CODE (x) == PLUS)
+    {
+      rtx ofs = XEXP (x, 1);
+      x = XEXP (x, 0);
+
+      /* Discard non-paradoxical subregs.  */
+      if (GET_CODE (x) == SUBREG
+          && (GET_MODE_SIZE (GET_MODE (x))
+             < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
+       x = SUBREG_REG (x);
+
+      if (REG_P (x))
+       {
+         if (! strict
+             && NONSTRICT_REG_OK_FP_BASE_P (x)
+             && GET_CODE (ofs) == CONST_INT)
+           return true;
+         if ((strict
+              ? STRICT_REG_OK_FOR_BASE_P (x)
+              : NONSTRICT_REG_OK_FOR_BASE_P (x))
+             && CONSTANT_ADDRESS_P (ofs))
+           return true;
+       }
+      else if (GET_CODE (x) == ADDRESSOF
+              && GET_CODE (ofs) == CONST_INT)
+       return true;
+    }
+
+  return false;
+}
+
 /* Try machine-dependent ways of modifying an illegitimate address
    to be legitimate.  If we find one, return the new, valid address.  */
 
index 0af83743c294455898fade0f98ccb9b737d8d090..c320701d37d0df2d5433f735339546a2064f4ebb 100644 (file)
@@ -1359,15 +1359,13 @@ do {                                            \
    After reload, it makes no difference, since pseudo regs have
    been eliminated by then.  */
 
-#ifndef REG_OK_STRICT
-
 /* Nonzero if X is a hard reg that can be used as an index
    or if it is a pseudo reg.  */
 #define REG_OK_FOR_INDEX_P(X) 0
 
 /* 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)  \
+#define NONSTRICT_REG_OK_FOR_BASE_P(X)  \
   (REGNO (X) < 32 || REGNO (X) == 63 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
 
 /* ??? Nonzero if X is the frame pointer, or some virtual register
@@ -1375,92 +1373,40 @@ do {                                            \
    have offsets greater than 32K.  This is done because register
    elimination offsets will change the hi/lo split, and if we split
    before reload, we will require additional instructions.   */
-#define REG_OK_FP_BASE_P(X)                    \
+#define NONSTRICT_REG_OK_FP_BASE_P(X)          \
   (REGNO (X) == 31 || REGNO (X) == 63          \
    || (REGNO (X) >= FIRST_PSEUDO_REGISTER      \
        && REGNO (X) < LAST_VIRTUAL_REGISTER))
 
-#else
-
-/* 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))
-
 /* 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 REG_OK_FP_BASE_P(X) 0
+#define STRICT_REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
 
+#ifdef REG_OK_STRICT
+#define REG_OK_FOR_BASE_P(X)   STRICT_REG_OK_FOR_BASE_P (X)
+#else
+#define REG_OK_FOR_BASE_P(X)   NONSTRICT_REG_OK_FOR_BASE_P (X)
 #endif
 \f
-/* 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. 
-
-   For Alpha, we have either a constant address or the sum of a register
-   and a constant address, or just a register.  For DImode, any of those
-   forms can be surrounded with an AND that clear the low-order three bits;
-   this is an "unaligned" access.
-
-   First define the basic valid address.  */
-
-#define GO_IF_LEGITIMATE_SIMPLE_ADDRESS(MODE, X, ADDR)                 \
-{                                                                      \
-  rtx tmp = (X);                                                       \
-  if (GET_CODE (tmp) == SUBREG                                         \
-      && (GET_MODE_SIZE (GET_MODE (tmp))                               \
-         < GET_MODE_SIZE (GET_MODE (SUBREG_REG (tmp)))))               \
-    tmp = SUBREG_REG (tmp);                                            \
-  if (REG_P (tmp) && REG_OK_FOR_BASE_P (tmp))                          \
-    goto ADDR;                                                         \
-  if (CONSTANT_ADDRESS_P (X))                                          \
-    goto ADDR;                                                         \
-  if (GET_CODE (X) == PLUS)                                            \
-    {                                                                  \
-      tmp = XEXP (X, 0);                                               \
-      if (GET_CODE (tmp) == SUBREG                                     \
-          && (GET_MODE_SIZE (GET_MODE (tmp))                           \
-             < GET_MODE_SIZE (GET_MODE (SUBREG_REG (tmp)))))           \
-        tmp = SUBREG_REG (tmp);                                                \
-      if (REG_P (tmp))                                                 \
-       {                                                               \
-         if (REG_OK_FP_BASE_P (tmp)                                    \
-             && GET_CODE (XEXP (X, 1)) == CONST_INT)                   \
-           goto ADDR;                                                  \
-         if (REG_OK_FOR_BASE_P (tmp)                                   \
-             && CONSTANT_ADDRESS_P (XEXP (X, 1)))                      \
-           goto ADDR;                                                  \
-       }                                                               \
-      else if (GET_CODE (tmp) == ADDRESSOF                             \
-              && CONSTANT_ADDRESS_P (XEXP (X, 1)))                     \
-       goto ADDR;                                                      \
-    }                                                                  \
-}
-
-/* Now accept the simple address, or, for DImode only, an AND of a simple
-   address that turns off the low three bits.  */
+/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a
+   valid memory address for an instruction.  */
 
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ GO_IF_LEGITIMATE_SIMPLE_ADDRESS (MODE, X, ADDR); \
-  if ((MODE) == DImode                         \
-      && GET_CODE (X) == AND                   \
-      && GET_CODE (XEXP (X, 1)) == CONST_INT   \
-      && INTVAL (XEXP (X, 1)) == -8)           \
-    GO_IF_LEGITIMATE_SIMPLE_ADDRESS (MODE, XEXP (X, 0), ADDR); \
-}
+#ifdef REG_OK_STRICT
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
+do {                                           \
+  if (alpha_legitimate_address_p (MODE, X, 1)) \
+    goto WIN;                                  \
+} while (0)
+#else
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
+do {                                           \
+  if (alpha_legitimate_address_p (MODE, X, 0)) \
+    goto WIN;                                  \
+} while (0)
+#endif
 
 /* 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.  */
+   This macro is used in only one place: `memory_address' in explow.c.  */
 
 #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)            \
 do {                                                   \
index 87458038c4b687a689ad195b34bc3d9f96b654bf..828024b37a1805cb2b1e78b97a7ab27980c1e138 100644 (file)
@@ -663,7 +663,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r")
                 (match_operand:DI 2 "const_int_operand" "n")))]
-  "REG_OK_FP_BASE_P (operands[1])
+  "NONSTRICT_REG_OK_FP_BASE_P (operands[1])
    && INTVAL (operands[2]) >= 0
    /* This is the largest constant an lda+ldah pair can add, minus
       an upper bound on the displacement between SP and AP during