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
24volatile double gd[32];
25volatile float gf[32];
26
27void 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
47int 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