diff options
Diffstat (limited to 'gcc-4.9/gcc/testsuite/gcc.target/arm/handler-align.c')
-rw-r--r-- | gcc-4.9/gcc/testsuite/gcc.target/arm/handler-align.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/arm/handler-align.c b/gcc-4.9/gcc/testsuite/gcc.target/arm/handler-align.c new file mode 100644 index 000000000..6c5187b20 --- /dev/null +++ b/gcc-4.9/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; +} |