From 5d02b6c26134b170071255fad492963561dfbd50 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 17 Apr 1999 16:31:34 -0700 Subject: [PATCH] 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 --- gcc/ChangeLog | 8 ++++++++ gcc/config/alpha/alpha.h | 26 ++++++++++++++++++++++---- gcc/config/alpha/alpha.md | 20 +++++++++++++++++--- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9411c209b2f..6c2b370af8a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +Sat Apr 17 22:54:17 1999 Richard Henderson + + * 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 * config/c4x/c4x.c (legitimize_operands): Use rtx_cost diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index fe31dc3be0b..2026ca9760b 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 ab569510ad5..501443799af 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)))] " -- 2.30.2