aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreta Yorsh <greta.yorsh@arm.com>2012-06-18 18:06:35 +0100
committerGreta Yorsh <gretay@gcc.gnu.org>2012-06-18 18:06:35 +0100
commit474038cda92c3ee8c77be7368d9c954bca922579 (patch)
treee117f2034e4cf63a61ebd6df25b430c8d1647229
parent9ef7adc086571bf7d2d3664dc7cdeaee27fc3a9b (diff)
downloadgcc-474038cda92c3ee8c77be7368d9c954bca922579.zip
gcc-474038cda92c3ee8c77be7368d9c954bca922579.tar.gz
gcc-474038cda92c3ee8c77be7368d9c954bca922579.tar.bz2
This patch updates ldm_stm_operation_p to check for loads that if SP is in the register list...
This patch updates ldm_stm_operation_p to check for loads that if SP is in the register list, then the base register is SP. It guarantees that SP is reset correctly when an LDM instruction is interrupted. Otherwise, we might end up with a corrupt stack. gcc/ 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. From-SVN: r188738
-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