aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>1999-04-17 16:31:34 -0700
committerRichard Henderson <rth@gcc.gnu.org>1999-04-17 16:31:34 -0700
commit5d02b6c26134b170071255fad492963561dfbd50 (patch)
tree0ae169b0fd890824a422f22950f870a0f346e88d
parent87ba694401df1d06dda4b8c14b50528a740eef6d (diff)
downloadgcc-5d02b6c26134b170071255fad492963561dfbd50.zip
gcc-5d02b6c26134b170071255fad492963561dfbd50.tar.gz
gcc-5d02b6c26134b170071255fad492963561dfbd50.tar.bz2
alpha.h (REG_OK_FP_BASE_P): New macro.
* alpha.h (REG_OK_FP_BASE_P): New macro. (GO_IF_LEGITIMATE_SIMPLE_ADDRESS): Use it. * alpha.md (adddi3+1): New insn to handle large constants off the soft frame pointer. (adddi3+2): Don't split soft frame pointer or arg pointer additions. From-SVN: r26530
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/alpha/alpha.h26
-rw-r--r--gcc/config/alpha/alpha.md20
3 files changed, 47 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9411c20..6c2b370 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+Sat Apr 17 22:54:17 1999 Richard Henderson <rth@cygnus.com>
+
+ * alpha.h (REG_OK_FP_BASE_P): New macro.
+ (GO_IF_LEGITIMATE_SIMPLE_ADDRESS): Use it.
+ * alpha.md (adddi3+1): New insn to handle large constants off
+ the soft frame pointer.
+ (adddi3+2): Don't split soft frame pointer or arg pointer additions.
+
Sun Apr 18 17:24:10 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
* config/c4x/c4x.c (legitimize_operands): Use rtx_cost
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index fe31dc3..2026ca9 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -1386,18 +1386,32 @@ extern void alpha_init_expanders ();
/* 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) \
(REGNO (X) < 32 || REGNO (X) == 63 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
+/* ??? Nonzero if X is the frame pointer, or some virtual register
+ that may eliminate to the frame pointer. These will be allowed to
+ 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) \
+ (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
+
#endif
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
@@ -1418,10 +1432,14 @@ extern void alpha_init_expanders ();
if (CONSTANT_ADDRESS_P (X)) \
goto ADDR; \
if (GET_CODE (X) == PLUS \
- && REG_P (XEXP (X, 0)) \
- && REG_OK_FOR_BASE_P (XEXP (X, 0)) \
- && CONSTANT_ADDRESS_P (XEXP (X, 1))) \
- goto ADDR; \
+ && REG_P (XEXP (X, 0))) \
+ { \
+ if (REG_OK_FP_BASE_P (XEXP (X, 0))) \
+ goto ADDR; \
+ if (REG_OK_FOR_BASE_P (XEXP (X, 0)) \
+ && CONSTANT_ADDRESS_P (XEXP (X, 1))) \
+ goto ADDR; \
+ } \
}
/* Now accept the simple address, or, for DImode only, an AND of a simple
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index ab56951..5014437 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -563,14 +563,28 @@
return pattern[which];
}")
-;; Don't do this if we are adjusting SP since we don't want to do
-;; it in two steps.
+;; ??? Allow large constants when basing off the frame pointer or some
+;; virtual register that may eliminate to the frame pointer. 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_insn ""
+ [(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])"
+ "#")
+
+;; Don't do this if we are adjusting SP since we don't want to do it
+;; in two steps. Don't split FP sources for the reason listed above.
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(plus:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "const_int_operand" "")))]
"! add_operand (operands[2], DImode)
- && operands[0] != stack_pointer_rtx"
+ && operands[0] != stack_pointer_rtx
+ && operands[1] != frame_pointer_rtx
+ && operands[1] != arg_pointer_rtx"
[(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
"