summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/eh/registers1.C
blob: 6633e834d7281de4d4b301dfb1921a1e12ba8973 (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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Try to check that registers are preserved when the stack is unwound.
// { dg-do run }
// { dg-options -O2 }

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

// This test case triggers up to DEPTH recursive calls to function
// foo(), These calls are numbered so that 0 is the innermost, 1 the
// second innermost, and so on.  Each call caches NUM_VARS elements of
// both DOUBLE_SRC and INT_SRC and applies a trivial operation to each
// cached value.  The innermost foo() call will throw an integer call
// number.  The specified call should store its cached values in
// DOUBLE_DEST and INT_DEST, which main() will check.
const int num_vars = 16;
const int depth = 3;

float float_src[num_vars * depth];
float float_dest[num_vars];

int int_src[num_vars * depth];
int int_dest[num_vars];

void foo (int level, int throw_to)
{
  float *fsrc = &float_src[level * num_vars];
  float f00 = *fsrc++ + 1.0f;
  float f01 = *fsrc++ + 1.0f;
  float f02 = *fsrc++ + 1.0f;
  float f03 = *fsrc++ + 1.0f;
  float f04 = *fsrc++ + 1.0f;
  float f05 = *fsrc++ + 1.0f;
  float f06 = *fsrc++ + 1.0f;
  float f07 = *fsrc++ + 1.0f;
  float f08 = *fsrc++ + 1.0f;
  float f09 = *fsrc++ + 1.0f;
  float f10 = *fsrc++ + 1.0f;
  float f11 = *fsrc++ + 1.0f;
  float f12 = *fsrc++ + 1.0f;
  float f13 = *fsrc++ + 1.0f;
  float f14 = *fsrc++ + 1.0f;
  float f15 = *fsrc++ + 1.0f;

  int *isrc = &int_src[level * num_vars];
  int i00 = *isrc++ + 1;
  int i01 = *isrc++ + 1;
  int i02 = *isrc++ + 1;
  int i03 = *isrc++ + 1;
  int i04 = *isrc++ + 1;
  int i05 = *isrc++ + 1;
  int i06 = *isrc++ + 1;
  int i07 = *isrc++ + 1;
  int i08 = *isrc++ + 1;
  int i09 = *isrc++ + 1;
  int i10 = *isrc++ + 1;
  int i11 = *isrc++ + 1;
  int i12 = *isrc++ + 1;
  int i13 = *isrc++ + 1;
  int i14 = *isrc++ + 1;
  int i15 = *isrc++ + 1;

  try
    {
      if (level == 0)
	throw throw_to;
      else
	foo (level - 1, throw_to);
    }
  catch (int i)
    {
      if (i == level)
	{
	  float *fdest = float_dest;
	  *fdest++ = f00;
	  *fdest++ = f01;
	  *fdest++ = f02;
	  *fdest++ = f03;
	  *fdest++ = f04;
	  *fdest++ = f05;
	  *fdest++ = f06;
	  *fdest++ = f07;
	  *fdest++ = f08;
	  *fdest++ = f09;
	  *fdest++ = f10;
	  *fdest++ = f11;
	  *fdest++ = f12;
	  *fdest++ = f13;
	  *fdest++ = f14;
	  *fdest++ = f15;

	  int *idest = int_dest;
	  *idest++ = i00;
	  *idest++ = i01;
	  *idest++ = i02;
	  *idest++ = i03;
	  *idest++ = i04;
	  *idest++ = i05;
	  *idest++ = i06;
	  *idest++ = i07;
	  *idest++ = i08;
	  *idest++ = i09;
	  *idest++ = i10;
	  *idest++ = i11;
	  *idest++ = i12;
	  *idest++ = i13;
	  *idest++ = i14;
	  *idest++ = i15;
	}
      else
	{
	  throw;
	}
    }
}

int main ()
{
  for (int i = 0; i < depth * num_vars; i++)
    {
      int_src[i] = i * i;
      float_src[i] = i * 2.0f;
    }
  for (int level = 0; level < depth; level++)
    for (int throw_to = 0; throw_to <= level; throw_to++)
      {
	foo (level, throw_to);
	float *fsrc = &float_src[throw_to * num_vars];
	int *isrc = &int_src[throw_to * num_vars];
	for (int i = 0; i < num_vars; i++)
	  {
	    if (int_dest[i] != isrc[i] + 1)
	      abort ();
	    if (float_dest[i] != fsrc[i] + 1.0f)
	      abort ();
	  }
      }
  exit (0);
}