summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>2005-02-01 14:07:02 +0000
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>2005-02-01 14:07:02 +0000
commit841b213df69c6dbd7bd794fe4e7bbabd07e8989e (patch)
treeb002db16121df7244942e9e496db7e59f414ecdf /gcc
parent6e8739c9b4474c1f831b8e414d6698c59b773504 (diff)
downloadgcc-841b213df69c6dbd7bd794fe4e7bbabd07e8989e.tar.gz
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c32
3 files changed, 34 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b5b35c8169f..88add3a5776 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2005-02-01 Richard Earnshaw <rearnsha@arm.com>
+
+ 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 <stevenb@suse.de>
PR optimization/15242
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 99c79231d78..5c040bda1ce 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 649fde30299..95fe7fe48f1 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;
}