summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/eh/dfp-saves-aarch64.C
blob: 062034105004c22f15729c88222f150804928506 (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
// { dg-do run { target aarch64*-*-* } }
// { dg-require-effective-target dfp }

/* Test unwinding of AArch64 register saves.  */
/* We cannot use #include <decimal/decimal> because it defines
   decimal* types as classes, which cannot be assigned to register
   variables.  Hence the use the mode attribute trick.  */

#ifdef __aarch64__

typedef float dec64 __attribute__((mode(DD)));

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

void
foo (void)
{
  register dec64 v10 asm("v10") = 0;
  register dec64 v11 asm("v11") = 1;
  register dec64 v12 asm("v12") = 2;
  register dec64 v13 asm("v13") = 3;
  asm volatile ("" : "+w" (v10), "+w" (v11), "+w" (v12), "+w" (v13));
  throw "";
}

int
main (void)
{
  register dec64 v10 asm("v10") = 10;
  register dec64 v11 asm("v11") = 11;
  register dec64 v12 asm("v12") = 12;
  register dec64 v13 asm("v13") = 13;
  asm volatile ("" : "+w" (v10), "+w" (v11), "+w" (v12), "+w" (v13));
  try {
    foo ();
  } catch (...) {
    asm volatile ("" : "+w" (v10), "+w" (v11), "+w" (v12), "+w" (v13));
    if (v10 != 10 || v11 != 11 || v12 != 12 || v13 != 13)
      abort ();
  }
  exit (0);
}
#else
int
main (void)
{
}
#endif