139 lines
3.1 KiB
C
139 lines
3.1 KiB
C
// 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);
|
|
}
|