From 474038cda92c3ee8c77be7368d9c954bca922579 Mon Sep 17 00:00:00 2001 From: Greta Yorsh Date: Mon, 18 Jun 2012 18:06:35 +0100 Subject: [PATCH] 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 * 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 --- gcc/ChangeLog | 5 +++++ gcc/config/arm/arm.c | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8355d02452b..e68309da96a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2012-06-18 Greta Yorsh + + * 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 PR tree-optimization/53693 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index bb04392cec3..d00849cb0ad 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