aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-nofloat-2.c
blob: 59621a4c19bbfaddb384544b2604a38ef16fb060 (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
/* { dg-do run } */
/* { dg-options "-O3 -mhtm -Wa,-march=zEC12,-mzarch --save-temps" } */

/* __builtin_tbegin has to emit clobbers for all FPRs since the tbegin
   instruction does not automatically preserves them.  If the
   transaction body is fully contained in a function the backend tries
   after reload to get rid of the FPR save/restore operations
   triggered by the clobbers.  This testcase failed since the backend
   was able to get rid of all FPR saves/restores and since these were
   the only stack operations also of the entire stack space.  So even
   the save/restore of the stack pointer was omitted in the end.
   However, since the frame layout has been fixed before, the prologue
   still generated the stack pointer decrement making foo return with
   a modified stack pointer.  */

void abort(void);

void __attribute__((noinline))
foo (int a)
{
  /* This is just to prevent the tbegin code from actually being
     executed.  That way the test may even run on machines prior to
     zEC12.  */
  if (a == 42)
    return;

  if (__builtin_tbegin (0) == 0)
    __builtin_tend ();
}

#ifdef __s390x__
#define GET_STACK_POINTER(SP)			\
  asm volatile ("stg %%r15, %0" : "=QRST" (SP));
#else
#define GET_STACK_POINTER(SP)			\
  asm volatile ("st %%r15, %0" : "=QR" (SP));
#endif

int main(void)
{
  unsigned long new_sp, old_sp;

  GET_STACK_POINTER (old_sp);
  foo(42);
  GET_STACK_POINTER (new_sp);

  if (old_sp != new_sp)
    abort ();

  return 0;
}

/* Make sure no FPR saves/restores are emitted.  */
/* { dg-final { scan-assembler-not "\tstd\t" } } */
/* { dg-final { scan-assembler-not "\tld\t" } } */