1 /* { dg-do run { target i?86-*-* x86_64-*-* } } */
2 /* { dg-skip-if "PR81693 sp not aligned to 16 bytes" { "*-*-darwin*" } } */
3 /* { dg-options "-mgeneral-regs-only" } */
4 
5 extern void exit (int);
6 
7 typedef unsigned int uword_t __attribute__ ((mode (__word__)));
8 
9 #define ERROR		0x12345670
10 #define IP		0x12345671
11 #define CS		0x12345672
12 #define FLAGS		0x12345673
13 #define SP		0x12345674
14 #define SS		0x12345675
15 
16 #define STRING(x)	XSTRING(x)
17 #define XSTRING(x)	#x
18 #define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
19 #define ASMNAME2(prefix, cname) XSTRING (prefix) cname
20 
21 struct interrupt_frame
22 {
23   uword_t ip;
24   uword_t cs;
25   uword_t flags;
26   uword_t sp;
27   uword_t ss;
28 };
29 
30 __attribute__((naked, used))
31 void
fn(void)32 fn (void)
33 {
34   register uword_t *sp __asm__("sp");
35   uword_t error = *sp;
36   struct interrupt_frame *frame = (struct interrupt_frame *) (sp + 1);
37   if (ERROR != error)		/* BREAK */
38     __builtin_abort ();
39   if (IP != frame->ip)
40     __builtin_abort ();
41   if (CS != frame->cs)
42     __builtin_abort ();
43   if (FLAGS != frame->flags)
44     __builtin_abort ();
45   if (SP != frame->sp)
46     __builtin_abort ();
47   if (SS != frame->ss)
48     __builtin_abort ();
49 
50   exit (0);
51 }
52 
53 int
main()54 main ()
55 {
56   asm ("push	$" STRING (SS) ";		\
57 	push	$" STRING (SP) ";		\
58 	push	$" STRING (FLAGS) ";		\
59 	push	$" STRING (CS) ";		\
60 	push	$" STRING (IP) ";		\
61 	push	$" STRING (ERROR) ";		\
62 	jmp	 " ASMNAME ("fn"));
63   return 0;
64 }
65