aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/arm/arm.c10
2 files changed, 15 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8355d02..e68309d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2012-06-18 Greta Yorsh <Greta.Yorsh@arm.com>
+
+ * config/arm/arm.c (ldm_stm_operation_p): Require SP
+ as base register for loads if SP is in the register list.
+
2012-06-18 Richard Guenther <rguenther@suse.de>
PR tree-optimization/53693
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index bb04392..d00849c 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -10080,6 +10080,12 @@ ldm_stm_operation_p (rtx op, bool load, enum machine_mode mode,
if (!REG_P (addr))
return false;
+ /* Don't allow SP to be loaded unless it is also the base register. It
+ guarantees that SP is reset correctly when an LDM instruction
+ is interruptted. Otherwise, we might end up with a corrupt stack. */
+ if (load && (REGNO (reg) == SP_REGNUM) && (REGNO (addr) != SP_REGNUM))
+ return false;
+
for (; i < count; i++)
{
elt = XVECEXP (op, 0, i);
@@ -10103,6 +10109,10 @@ ldm_stm_operation_p (rtx op, bool load, enum machine_mode mode,
|| (consecutive
&& (REGNO (reg) !=
(unsigned int) (first_regno + regs_per_val * (i - base))))
+ /* Don't allow SP to be loaded unless it is also the base register. It
+ guarantees that SP is reset correctly when an LDM instruction
+ is interrupted. Otherwise, we might end up with a corrupt stack. */
+ || (load && (REGNO (reg) == SP_REGNUM) && (REGNO (addr) != SP_REGNUM))
|| !MEM_P (mem)
|| GET_MODE (mem) != mode
|| ((GET_CODE (XEXP (mem, 0)) != PLUS