1 // Try to check that registers are preserved when the stack is unwound.
2 // { dg-do run }
3 // { dg-options -O2 }
4 
5 extern "C" void exit(int);
6 extern "C" void abort();
7 
8 // This test case triggers up to DEPTH recursive calls to function
9 // foo(), These calls are numbered so that 0 is the innermost, 1 the
10 // second innermost, and so on.  Each call caches NUM_VARS elements of
11 // both DOUBLE_SRC and INT_SRC and applies a trivial operation to each
12 // cached value.  The innermost foo() call will throw an integer call
13 // number.  The specified call should store its cached values in
14 // DOUBLE_DEST and INT_DEST, which main() will check.
15 const int num_vars = 16;
16 const int depth = 3;
17 
18 float float_src[num_vars * depth];
19 float float_dest[num_vars];
20 
21 int int_src[num_vars * depth];
22 int int_dest[num_vars];
23 
foo(int level,int throw_to)24 void foo (int level, int throw_to)
25 {
26   float *fsrc = &float_src[level * num_vars];
27   float f00 = *fsrc++ + 1.0f;
28   float f01 = *fsrc++ + 1.0f;
29   float f02 = *fsrc++ + 1.0f;
30   float f03 = *fsrc++ + 1.0f;
31   float f04 = *fsrc++ + 1.0f;
32   float f05 = *fsrc++ + 1.0f;
33   float f06 = *fsrc++ + 1.0f;
34   float f07 = *fsrc++ + 1.0f;
35   float f08 = *fsrc++ + 1.0f;
36   float f09 = *fsrc++ + 1.0f;
37   float f10 = *fsrc++ + 1.0f;
38   float f11 = *fsrc++ + 1.0f;
39   float f12 = *fsrc++ + 1.0f;
40   float f13 = *fsrc++ + 1.0f;
41   float f14 = *fsrc++ + 1.0f;
42   float f15 = *fsrc++ + 1.0f;
43 
44   int *isrc = &int_src[level * num_vars];
45   int i00 = *isrc++ + 1;
46   int i01 = *isrc++ + 1;
47   int i02 = *isrc++ + 1;
48   int i03 = *isrc++ + 1;
49   int i04 = *isrc++ + 1;
50   int i05 = *isrc++ + 1;
51   int i06 = *isrc++ + 1;
52   int i07 = *isrc++ + 1;
53   int i08 = *isrc++ + 1;
54   int i09 = *isrc++ + 1;
55   int i10 = *isrc++ + 1;
56   int i11 = *isrc++ + 1;
57   int i12 = *isrc++ + 1;
58   int i13 = *isrc++ + 1;
59   int i14 = *isrc++ + 1;
60   int i15 = *isrc++ + 1;
61 
62   try
63     {
64       if (level == 0)
65 	throw throw_to;
66       else
67 	foo (level - 1, throw_to);
68     }
69   catch (int i)
70     {
71       if (i == level)
72 	{
73 	  float *fdest = float_dest;
74 	  *fdest++ = f00;
75 	  *fdest++ = f01;
76 	  *fdest++ = f02;
77 	  *fdest++ = f03;
78 	  *fdest++ = f04;
79 	  *fdest++ = f05;
80 	  *fdest++ = f06;
81 	  *fdest++ = f07;
82 	  *fdest++ = f08;
83 	  *fdest++ = f09;
84 	  *fdest++ = f10;
85 	  *fdest++ = f11;
86 	  *fdest++ = f12;
87 	  *fdest++ = f13;
88 	  *fdest++ = f14;
89 	  *fdest++ = f15;
90 
91 	  int *idest = int_dest;
92 	  *idest++ = i00;
93 	  *idest++ = i01;
94 	  *idest++ = i02;
95 	  *idest++ = i03;
96 	  *idest++ = i04;
97 	  *idest++ = i05;
98 	  *idest++ = i06;
99 	  *idest++ = i07;
100 	  *idest++ = i08;
101 	  *idest++ = i09;
102 	  *idest++ = i10;
103 	  *idest++ = i11;
104 	  *idest++ = i12;
105 	  *idest++ = i13;
106 	  *idest++ = i14;
107 	  *idest++ = i15;
108 	}
109       else
110 	{
111 	  throw;
112 	}
113     }
114 }
115 
main()116 int main ()
117 {
118   for (int i = 0; i < depth * num_vars; i++)
119     {
120       int_src[i] = i * i;
121       float_src[i] = i * 2.0f;
122     }
123   for (int level = 0; level < depth; level++)
124     for (int throw_to = 0; throw_to <= level; throw_to++)
125       {
126 	foo (level, throw_to);
127 	float *fsrc = &float_src[throw_to * num_vars];
128 	int *isrc = &int_src[throw_to * num_vars];
129 	for (int i = 0; i < num_vars; i++)
130 	  {
131 	    if (int_dest[i] != isrc[i] + 1)
132 	      abort ();
133 	    if (float_dest[i] != fsrc[i] + 1.0f)
134 	      abort ();
135 	  }
136       }
137   exit (0);
138 }
139