diff options
author | Joey Ye <jye2@gcc.gnu.org> | 2011-08-19 08:28:08 +0000 |
---|---|---|
committer | Joey Ye <jye2@gcc.gnu.org> | 2011-08-19 08:28:08 +0000 |
commit | a3f94870980063aac37a66443fa6a0a3b0f91706 (patch) | |
tree | 8281e26538384c97a1c8906992dce3cbfd1ca615 /gcc | |
parent | 96332fd82cc1ec2f4162bf153e37a5b8c5fe9c3a (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/handler-align.c | 42 | ||||
-rw-r--r-- | gcc/testsuite/lib/target-supports.exp | 13 |
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. |