1 /* Macros to emit "L Nxx R" for each octal number xx between 000 and 037.  */
2 #define OP1(L, N, R, I, J) L N##I##J R
3 #define OP2(L, N, R, I) \
4     OP1(L, N, R, 0, I), OP1(L, N, R, 1, I), \
5     OP1(L, N, R, 2, I), OP1(L, N, R, 3, I)
6 #define OP(L, N, R) \
7     OP2(L, N, R, 0), OP2(L, N, R, 1), OP2(L, N, R, 2), OP2(L, N, R, 3), \
8     OP2(L, N, R, 4), OP2(L, N, R, 5), OP2(L, N, R, 6), OP2(L, N, R, 7)
9 
10 /* Declare 32 unique variables with prefix N.  */
11 #define DECLARE(N) OP (, N,)
12 
13 /* Copy 32 variables with prefix N from the array at ADDR.
14    Leave ADDR pointing to the end of the array.  */
15 #define COPYIN(N, ADDR) OP (, N, = *(ADDR++))
16 
17 /* Likewise, but copy the other way.  */
18 #define COPYOUT(N, ADDR) OP (*(ADDR++) =, N,)
19 
20 /* Add the contents of the array at ADDR to 32 variables with prefix N.
21    Leave ADDR pointing to the end of the array.  */
22 #define ADD(N, ADDR) OP (, N, += *(ADDR++))
23 
24 volatile double gd[32];
25 volatile float gf[32];
26 
foo(int n)27 void foo (int n)
28 {
29   double DECLARE(d);
30   float DECLARE(f);
31   volatile double *pd;
32   volatile float *pf;
33   int i;
34 
35   pd = gd; COPYIN (d, pd);
36   for (i = 0; i < n; i++)
37     {
38       pf = gf; COPYIN (f, pf);
39       pd = gd; ADD (d, pd);
40       pd = gd; ADD (d, pd);
41       pd = gd; ADD (d, pd);
42       pf = gf; COPYOUT (f, pf);
43     }
44   pd = gd; COPYOUT (d, pd);
45 }
46 
main()47 int main ()
48 {
49   int i;
50 
51   for (i = 0; i < 32; i++)
52     gd[i] = i, gf[i] = i;
53   foo (1);
54   for (i = 0; i < 32; i++)
55     if (gd[i] != i * 4 || gf[i] != i)
56       abort ();
57   exit (0);
58 }
59