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)14 char *get_buffer(void)
15 {
16 	return buff;
17 }
18 
foo(void)19 void __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()26 int 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