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 int 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 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 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