This patch updates ldm_stm_operation_p to check for loads that if SP is in the regist...
authorGreta Yorsh <greta.yorsh@arm.com>
Mon, 18 Jun 2012 17:06:35 +0000 (18:06 +0100)
committerGreta Yorsh <gretay@gcc.gnu.org>
Mon, 18 Jun 2012 17:06:35 +0000 (18:06 +0100)
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

gcc/ChangeLog
gcc/config/arm/arm.c

index 8355d02452b8ed1f29794d6fa9a0c88085a392d1..e68309da96a414ac11e5927dfe97ec12994f26fe 100644 (file)
@@ -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
index bb04392cec31c3933bda468d050fba6091be074d..d00849cb0ad65670ecc4abd788ccea6e676c92fb 100644 (file)
@@ -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