1 /* Test epilogue of a realigned interrupt handler. */ 2 /* { dg-do run } */ 3 /* { dg-options "-mthumb -Os" } */ 4 /* { dg-skip-if "" { ! { arm_thumb1_ok || arm_thumb2_ok } } } */ 5 /* { dg-require-effective-target arm_cortex_m } */ 6 /* { dg-require-effective-target arm_eabi } */ 7 8 extern __attribute__((noreturn)) void abort(void); 9 extern int snprintf(char *, int, const char *, ...); 10 11 #define BUFF_LEN 256 12 char buff[BUFF_LEN]; 13 get_buffer(void)14char *get_buffer(void) 15 { 16 return buff; 17 } 18 foo(void)19void __attribute__((interrupt)) foo(void) 20 { 21 char *msg = get_buffer(); 22 snprintf(msg, BUFF_LEN, "%d %p", 1, buff+BUFF_LEN); 23 } 24 25 volatile void * save_sp; main()26int main() 27 { 28 register volatile void * sp asm("sp"); 29 /* Check stack pointer before/after calling the interrupt 30 * handler. Not equal means that handler doesn't restore 31 * stack correctly. */ 32 save_sp = sp; 33 foo(); 34 /* Abort here instead of return non-zero. Due to wrong sp, lr value, 35 * returning from main may not work. */ 36 if (save_sp != sp) 37 { 38 sp = save_sp; 39 abort(); 40 } 41 return 0; 42 } 43