+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
/* 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
\f
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
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
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)))]
"