1/* { dg-do run { target *-*-linux* *-*-gnu* } } */ 2/* { dg-require-effective-target ia32 } */ 3/* { dg-options "-O2 -fomit-frame-pointer" } */ 4 5extern void abort (void); 6extern void exit (int); 7 8struct s { 9 struct { int a; } a; 10 int b; 11 struct { struct { int a; } a; struct t { struct t *a, *b; } b; } c; 12}; 13 14int bar(int (*fn)(void *), void *arg, unsigned long flags) 15{ 16 return 0; 17} 18 19int baz(void *x) 20{ 21 return 0; 22} 23 24void do_check (struct s *) asm ("do_check") __attribute__((regparm(1))); 25 26void __attribute__((regparm(1))) do_check(struct s *x) 27{ 28 if (x->a.a || x->b || x->c.a.a) 29 abort(); 30 if (x->c.b.a != &x->c.b || x->c.b.b != &x->c.b) 31 abort(); 32} 33 34#define NT "\n\t" 35 36asm ("\n" 37"___checkme:" 38NT "pushl %eax; pushl %ebx; pushl %ecx; pushl %edx; pushl %esi; pushl %edi" 39 40NT "pushl $0; pushl $0; pushl $0; pushl $0; pushl $0" 41NT "pushl $0; pushl $0; pushl $0; pushl $0; pushl $0" 42 43NT "movl %ecx, %eax" 44NT "call do_check" 45 46NT "popl %eax; popl %eax; popl %eax; popl %eax; popl %eax" 47NT "popl %eax; popl %eax; popl %eax; popl %eax; popl %eax" 48 49NT "popl %edi; popl %esi; popl %edx; popl %ecx; popl %ebx; popl %eax" 50NT "ret" 51); 52 53extern inline void do_asm(struct s * x) 54{ 55 asm volatile("call ___checkme" : : "c" (x) : "memory"); 56} 57 58int foo(void) 59{ 60 struct s x = { { 0 }, 0, { { 0 }, { &x.c.b, &x.c.b } } }; 61 bar(baz, &x, 1); 62 do_asm(&x); 63 bar(baz, &x, 1); 64 do_asm(&x); 65 return 0; 66} 67 68int main() 69{ 70 foo(); 71 exit(0); 72} 73