aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJoey Ye <jye2@gcc.gnu.org>2011-08-19 08:28:08 +0000
committerJoey Ye <jye2@gcc.gnu.org>2011-08-19 08:28:08 +0000
commita3f94870980063aac37a66443fa6a0a3b0f91706 (patch)
tree8281e26538384c97a1c8906992dce3cbfd1ca615 /gcc
parent96332fd82cc1ec2f4162bf153e37a5b8c5fe9c3a (diff)
downloadgcc-a3f94870980063aac37a66443fa6a0a3b0f91706.zip
gcc-a3f94870980063aac37a66443fa6a0a3b0f91706.tar.gz
gcc-a3f94870980063aac37a66443fa6a0a3b0f91706.tar.bz2
re PR target/49437 (interrupt return pop sometimes corrupts sp)
PR target/49437 * config/arm/arm.c (arm_output_epilogue): Properly handle epilogue when stack was realigned in interrupt handler prologue. testsuite: PR target/49437 * gcc.target/arm/handler-align.c: New test. * lib/target-supports.exp (check_effective_target_arm_cortex_m): New Function. From-SVN: r177891
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/arm/arm.c1
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.target/arm/handler-align.c42
-rw-r--r--gcc/testsuite/lib/target-supports.exp13
5 files changed, 69 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 14723eb..7c0c7b5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2011-08-19 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-18 Joseph Myers <joseph@codesourcery.com>
* c-decl.c (shadow_tag_warned): Check for _Noreturn.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index d1a3490..3162b30 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -15230,6 +15230,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/ChangeLog b/gcc/testsuite/ChangeLog
index 3f286ed..0cadc3c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,12 @@
2011-08-19 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.
+
+2011-08-19 Joey Ye <joey.ye@arm.com>
+
* gcc.c-torture/execute/20101011-1.c (DO_TEST): Skip on ARM.
2011-08-19 Mikael Morin <mikael.morin@sfr.fr>
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 28dedc9..54dc6b6 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2116,6 +2116,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.