This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch, ARM][1/8] Epilogue in RTL: update ldm_stm_operation_p
- From: Richard Earnshaw <rearnsha at arm dot com>
- To: Greta Yorsh <Greta dot Yorsh at arm dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 15 Jun 2012 09:31:02 +0100
- Subject: Re: [Patch, ARM][1/8] Epilogue in RTL: update ldm_stm_operation_p
- References: <000001cd3f33$5b5c25a0$121470e0$@Yorsh@arm.com> <000201cd3f34$61351350$239f39f0$@Yorsh@arm.com>
On 31/05/12 14:50, Greta Yorsh wrote:
> 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.
>
> ChangeLog:
>
> gcc
>
> 2012-05-31 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.
>
>
> 1-update-predicate.patch.txt
>
>
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index e3290e2..4717725 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -10247,6 +10247,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);
> @@ -10270,6 +10276,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
OK.
R.