diff mbox

[ARM] Fix PR target/49437 Thumb2 epilog with stack realignment

Message ID 000001cc5176$8a702d60$9f508820$@ye@arm.com
State New
Headers show

Commit Message

Joey Ye Aug. 3, 2011, 12:44 a.m. UTC
This patch fixes PR49437 with a single line change in ARM backend 
and a regression test case for ARM target

ChangeLog:
2011-08-02  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
        PR target/49437
        * config/arm/arm.c (arm_output_epilogue): Properly handle epilogue
        when stack was realigned in interrupt handler prologue.

2011-08-02  Joey Ye  <joey.ye@arm.com>
        PR target/49437
        * gcc.target/arm/handler-align.c: New test.
        * lib/target-supports.exp (check_effective_target_arm_cortex_m):
          New Function.
diff mbox

Patch

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index d9763d2..427c58d 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -14878,6 +14878,7 @@  arm_output_epilogue (rtx sibling)
 		  && !crtl->calls_eh_return
 		  && bit_count(saved_regs_mask) * 4 == count
 		  && !IS_INTERRUPT (func_type)
+		  && !IS_STACKALIGN (func_type)
 		  && !crtl->tail_call_emit)
 		{
 		  unsigned long mask;
diff --git a/gcc/testsuite/gcc.target/arm/handler-align.c
b/gcc/testsuite/gcc.target/arm/handler-align.c
new file mode 100644
index 0000000..6c5187b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/handler-align.c
@@ -0,0 +1,42 @@ 
+/* Test epilogue of a realigned interrupt handler. */
+/* { dg-do run } */
+/* { dg-options "-mthumb -Os" } */
+/* { dg-skip-if "" { ! { arm_thumb1_ok || arm_thumb2_ok } } } */
+/* { dg-require-effective-target arm_cortex_m } */
+/* { dg-require-effective-target arm_eabi } */
+
+extern __attribute__((noreturn)) void abort(void);
+extern int snprintf(char *, int, const char *, ...);
+
+#define BUFF_LEN 256
+char buff[BUFF_LEN];
+
+char *get_buffer(void)
+{
+	return buff;
+}
+
+void __attribute__((interrupt)) foo(void)
+{
+        char *msg = get_buffer();
+        snprintf(msg, BUFF_LEN, "%d %p", 1, buff+BUFF_LEN);
+}
+
+volatile void * save_sp;
+int main()
+{
+	register volatile void * sp asm("sp");
+	/* Check stack pointer before/after calling the interrupt
+         * handler. Not equal means that handler doesn't restore
+         * stack correctly.  */
+	save_sp = sp;
+	foo();
+	/* Abort here instead of return non-zero. Due to wrong sp, lr value,
+	 * returning from main may not work.  */
+	if (save_sp != sp)
+	{
+		sp = save_sp;
+		abort();
+	}
+	return 0;
+}
diff --git a/gcc/testsuite/lib/target-supports.exp
b/gcc/testsuite/lib/target-supports.exp
index cf44f1e..10cfcb4 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2108,6 +2108,19 @@  proc check_effective_target_arm_thumb2 { } {
     } ""]
 }
 
+# Return 1 if this is an ARM cortex-M profile cpu
+
+proc check_effective_target_arm_cortex_m { } {
+    return [check_no_compiler_messages arm_cortex_m assembly {
+	#if !defined(__ARM_ARCH_7M__) \
+            && !defined (__ARM_ARCH_7EM__) \
+            && !defined (__ARM_ARCH_6M__)
+	#error FOO
+	#endif
+	int i;
+    } "-mthumb"]
+}
+
 # Return 1 if the target supports executing NEON instructions, 0
 # otherwise.  Cache the result.