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
|
/* Test of setjmp()/longjmp(): preservation call-saved registers.
$Id: setjmp-2.c,v 1.1.2.2 2008/03/24 11:29:55 dmix Exp $ */
#include <stdlib.h>
#include <setjmp.h>
jmp_buf env;
/* foo2() uses (and destroys) call-saved registers. Complex return
value is used to force allocate all variables. */
int foo2 (void)
{
int v1, v2, v3, v4, v5, v6, v7, v8;
srand (1);
v1 = rand ();
v2 = rand ();
v3 = rand ();
v4 = rand ();
v5 = rand ();
v6 = rand ();
v7 = rand ();
v8 = rand ();
v1 *= rand ();
v1 += v2 * rand ();
v1 += v3 * rand ();
v1 += v4 * rand ();
v1 += v5 * rand ();
v1 += v6 * rand ();
v1 += v7 * rand ();
v1 += v8 * rand ();
while (!v1) v1 = rand ();
longjmp (env, v1);
}
/* Recalculate result above. */
int calc (int initial)
{
int v1, v2, v3, v4, v5, v6, v7, v8;
srand (initial);
v1 = rand ();
v2 = rand ();
v3 = rand ();
v4 = rand ();
v5 = rand ();
v6 = rand ();
v7 = rand ();
v8 = rand ();
v1 *= rand ();
v1 += v2 * rand ();
v1 += v3 * rand ();
v1 += v4 * rand ();
v1 += v5 * rand ();
v1 += v6 * rand ();
v1 += v7 * rand ();
v1 += v8 * rand ();
while (!v1) v1 = rand ();
return v1;
}
/* foo1() does not use call-save registers.
The setjmp() must do this. */
void foo1 (void)
{
int x;
if ( (x = setjmp (env)) != 0) {
if (x != calc (1))
exit (__LINE__);
return;
}
foo2 ();
exit (__LINE__);
}
/* main() allocates many variables in call-saved registers.
*/
int main ()
{
int v1, v2, v3, v4, v5, v6, v7, v8;
srand (2);
v1 = rand ();
v2 = rand ();
v3 = rand ();
v4 = rand ();
v5 = rand ();
v6 = rand ();
v7 = rand ();
v8 = rand ();
foo1 ();
srand (2);
if ( v1 != rand()
|| v2 != rand()
|| v3 != rand()
|| v4 != rand()
|| v5 != rand()
|| v6 != rand()
|| v7 != rand()
|| v8 != rand())
{
exit (__LINE__);
}
return 0;
}
|