From 841b213df69c6dbd7bd794fe4e7bbabd07e8989e Mon Sep 17 00:00:00 2001 From: rearnsha Date: Tue, 1 Feb 2005 14:07:02 +0000 Subject: [PATCH] PR target/16201 * arm.c (arm_eliminable_register): New function. (adjacent_mem_locations): Don't allow eliminable registers. Use HOST_WIDE_INT for address offsets. * arm-protos.h (arm_eliminable_register): Add prototype. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94540 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++++++++ gcc/config/arm/arm-protos.h | 1 + gcc/config/arm/arm.c | 32 +++++++++++++++++++++++++------- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b5b35c8..88add3a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2005-02-01 Richard Earnshaw + + PR target/16201 + * arm.c (arm_eliminable_register): New function. + (adjacent_mem_locations): Don't allow eliminable registers. Use + HOST_WIDE_INT for address offsets. + * arm-protos.h (arm_eliminable_register): Add prototype. + 2005-02-01 Steven Bosscher PR optimization/15242 diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 99c7923..5c040bd 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -115,6 +115,7 @@ extern int arm_emit_vector_const (FILE *, rtx); extern const char * arm_output_load_gr (rtx *); extern const char *vfp_output_fstmx (rtx *); extern void arm_set_return_address (rtx, rtx); +extern int arm_eliminable_register (rtx); #if defined TREE_CODE extern rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 649fde3..95fe7fe 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -4815,6 +4815,15 @@ arm_coproc_mem_operand (rtx op, bool wb) return FALSE; } +/* Return true if X is a register that will be eliminated later on. */ +int +arm_eliminable_register (rtx x) +{ + return REG_P (x) && (REGNO (x) == FRAME_POINTER_REGNUM + || REGNO (x) == ARG_POINTER_REGNUM + || (REGNO (x) >= FIRST_VIRTUAL_REGISTER + && REGNO (x) <= LAST_VIRTUAL_REGISTER)); +} /* Return GENERAL_REGS if a scratch register required to reload x to/from VFP registers. Otherwise return NO_REGS. */ @@ -5086,24 +5095,25 @@ adjacent_mem_locations (rtx a, rtx b) || (GET_CODE (XEXP (b, 0)) == PLUS && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT))) { - int val0 = 0, val1 = 0; - int reg0, reg1; + HOST_WIDE_INT val0 = 0, val1 = 0; + rtx reg0, reg1; + int val_diff; if (GET_CODE (XEXP (a, 0)) == PLUS) { - reg0 = REGNO (XEXP (XEXP (a, 0), 0)); + reg0 = XEXP (XEXP (a, 0), 0); val0 = INTVAL (XEXP (XEXP (a, 0), 1)); } else - reg0 = REGNO (XEXP (a, 0)); + reg0 = XEXP (a, 0); if (GET_CODE (XEXP (b, 0)) == PLUS) { - reg1 = REGNO (XEXP (XEXP (b, 0), 0)); + reg1 = XEXP (XEXP (b, 0), 0); val1 = INTVAL (XEXP (XEXP (b, 0), 1)); } else - reg1 = REGNO (XEXP (b, 0)); + reg1 = XEXP (b, 0); /* Don't accept any offset that will require multiple instructions to handle, since this would cause the @@ -5111,8 +5121,16 @@ adjacent_mem_locations (rtx a, rtx b) if (!const_ok_for_op (PLUS, val0) || !const_ok_for_op (PLUS, val1)) return 0; - return (reg0 == reg1) && ((val1 - val0) == 4 || (val0 - val1) == 4); + /* Don't allow an eliminable register: register elimination can make + the offset too large. */ + if (arm_eliminable_register (reg0)) + return 0; + + val_diff = val1 - val0; + return ((REGNO (reg0) == REGNO (reg1)) + && (val_diff == 4 || val_diff == -4)); } + return 0; } -- 2.7.4