aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/testsuite/gcc.target/i386/pr9771-1.c
blob: 9fa21ff0fa0d72b6b12c48c8ffff7c8c39eddc8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/* PR rtl-optimization/9771 */
/* { dg-do run } */
/* { dg-require-effective-target ia32 } */
/* { dg-options "-O2 -fomit-frame-pointer -ffixed-ebp" } */

extern void abort(void);
extern void exit(int);

register long *B asm ("ebp");

long x = 10;
long y = 20;

void bar(void)
{
  B = &y;
}

void foo()
{
  long *adr = B;
  long save = *adr;

  *adr = 123;

  bar();

  *adr = save;
}

/* This must not be inlined because main() requires the frame pointer
   for stack alignment.  */
void test(void) __attribute__((noinline));
void test(void)
{
  B = &x;

  foo();

  if (x != 10 || y != 20)
    abort();

  /* We can't return, as our caller may assume %ebp is preserved!  */
  /* We could save/restore it (like foo), but its easier to exit.  */
  exit(0);
}

/* main usually performs dynamic realignment of the stack in case
   _start would fail to properly align the stack, but for dynamic
   stack realignment we need frame pointer which is incompatible
   with -ffixed-ebp and the global register var.  So, cheat here
   and hide from the compiler that main is really main.  */
#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
#define ASMNAME2(prefix, cname) STRING (prefix) cname
#define STRING(x)    #x
int real_main() __asm (ASMNAME ("main"));

int real_main()
{
  test();
  return 0;

}