1#include "harness.h"
2#include <stdarg.h>
3#include <stddef.h>
4#include <string.h>
5
6typedef struct n_a
7{
8  signed char m1;
9  short m2;
10  int m3;
11  double m4;
12  vector float m5;
13}
14n_a;
15
16static n_a gn_a;
17
18static int
19lay(char *p, int start, int end, int n)
20{
21  int b;
22  unsigned char ch;
23  unsigned int mask;
24
25  start *= 8;
26  end *= 8;
27  n *= 8;
28
29  for (b = 0; b + 8 <= start; b += 8)
30    {
31      ch = *p++;
32      if (ch != 0xff)
33	for (mask = 0x80; mask; b++, mask >>= 1)
34	  if ((ch & mask) != mask)
35	    return b;
36    }
37
38  if (b < start)
39    {
40      ch = *p++;
41      for (mask = 0x80; b < start; b++, mask >>= 1)
42	if ((ch & mask) != mask)
43	  return b;
44      for (; mask && b < end; b++, mask >>= 1)
45	if ((ch & mask) != 0)
46	  return b;
47    }
48
49  for (; b + 8 <= end; b += 8)
50    {
51      ch = *p++;
52      if (ch != 0)
53	for (mask = 0x80; mask; b++, mask >>= 1)
54	  if ((ch & mask) != 0)
55	    return b;
56    }
57
58  if (b < end)
59    {
60      ch = *p++;
61      for (mask = 0x80; b < end; b++, mask >>= 1)
62	if ((ch & mask) != 0)
63	  return b;
64      for (; mask && b < n; b++, mask >>= 1)
65	if ((ch & mask) != mask)
66	  return b;
67    }
68
69  for (; b + 8 <= n; b += 8)
70    {
71      ch = *p++;
72      if (ch != 0xff)
73	for (mask = 0x80; mask; b++, mask >>= 1)
74	  if ((ch & mask) != mask)
75	    return b;
76    }
77
78  return n;
79}
80
81static void
82initn_a(signed char p1, short p2, int p3, double p4, vector float p5)
83{
84  n_a i;
85
86  i.m1 = p1;
87  i.m2 = p2;
88  i.m3 = p3;
89  i.m4 = p4;
90  i.m5 = p5;
91
92  check(i.m1 == 77, "i.m1");
93  check(i.m2 == 1924, "i.m2");
94  check(i.m3 == -1471601920, "i.m3");
95  check(vec_all_eq(i.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
96	"i.m5");
97
98  check(sizeof(n_a) == 32, "sizeof(n_a)");
99
100  check(offsetof(n_a, m1) == 0,  "offsetof(m1)");
101  check(offsetof(n_a, m2) == 2,  "offsetof(m2)");
102  check(offsetof(n_a, m3) == 4,  "offsetof(m3)");
103  check(offsetof(n_a, m4) == 8,  "offsetof(m4)");
104  check(offsetof(n_a, m5) == 16, "offsetof(m5)");
105
106  check(sizeof(i.m1) == 1,  "sizeof(m1)");
107  check(sizeof(i.m2) == 2,  "sizeof(m2)");
108  check(sizeof(i.m3) == 4,  "sizeof(m3)");
109  check(sizeof(i.m4) == 8,  "sizeof(m4)");
110  check(sizeof(i.m5) == 16, "sizeof(m5)");
111
112#define lay_check(field) do {				\
113  memset((char *)&i, 0xFF, sizeof(i));			\
114  lay_reset(field);					\
115  check(lay((char *)&i,					\
116	    offsetof(n_a, field),			\
117	    offsetof(n_a, field) + sizeof(i.field),	\
118	    sizeof(i)) == sizeof(i)*8,			\
119	"lay(" #field ")");				\
120  } while (0)
121#define lay_reset(field) i.field = 0
122
123  lay_check(m1);
124  lay_check(m2);
125  lay_check(m3);
126  lay_check(m4);
127#undef lay_reset
128#define lay_reset(field) i.field = ((vector float){0,0,0,0})
129  lay_check(m5);
130
131#undef lay_check
132#undef lay_reset
133}
134
135n_a
136valuen_a(void)
137{
138  return gn_a;
139}
140
141n_a *
142addrn_a(void)
143{
144  return &gn_a;
145}
146
147static void
148eqn_a(n_a * a)
149{
150  check(a->m1 == 77, "a->m1");
151  check(a->m2 == 1924, "a->m2");
152  check(a->m3 == -1471601920, "a->m3");
153  check(vec_all_eq(a->m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
154	"a->m5");
155}
156
157static void
158getsn_a(n_a * a)
159{
160  a->m1 = 77;
161  a->m2 = 1924;
162  a->m3 = -1471601920;
163  a->m4 = 3.65e+18;
164  a->m5 = ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08});
165}
166
167static void
168varlistn_a(signed char p1, va_list ap)
169{
170  n_a q;
171  q.m1 = p1;
172  q.m2 = va_arg(ap, int);
173  q.m3 = va_arg(ap, int);
174  q.m4 = va_arg(ap, double);
175  q.m5 = va_arg(ap, vector float);
176
177  check(q.m1 == 77, "q.m1");
178  check(q.m2 == 1924, "q.m2");
179  check(q.m3 == -1471601920, "q.m3");
180  check(vec_all_eq(q.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
181	"q.m5");
182}
183
184static void
185varargsn_a(signed char p1, ...)
186{
187  n_a q, r;
188  va_list ap;
189
190  va_start(ap, p1);
191  q.m1 = p1;
192  q.m2 = va_arg(ap, int);
193  q.m3 = va_arg(ap, int);
194  q.m4 = va_arg(ap, double);
195  q.m5 = va_arg(ap, vector float);
196  va_end(ap);
197
198  check(q.m1 == 77, "q.m1");
199  check(q.m2 == 1924, "q.m2");
200  check(q.m3 == -1471601920, "q.m3");
201  check(vec_all_eq(q.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
202	"q.m5");
203
204  va_start(ap, p1);
205  r.m1 = p1;
206  r.m2 = va_arg(ap, int);
207  r.m3 = va_arg(ap, int);
208  r.m4 = va_arg(ap, double);
209  r.m5 = va_arg(ap, vector float);
210  va_end(ap);
211
212  check(r.m1 == 77, "r.m1");
213  check(r.m2 == 1924, "r.m2");
214  check(r.m3 == -1471601920, "r.m3");
215  check(vec_all_eq(r.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
216	"r.m5");
217
218  va_start(ap, p1);
219  varlistn_a(p1, ap);
220  va_end(ap);
221}
222
223static void
224test()
225{
226  static struct
227  {
228    char a;
229    n_a b;
230  }
231  s;
232  n_a v[3], a, *p;
233
234  static n_a i = { 77, 1924, -1471601920, 3.65e+18, {-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08} };
235
236  memset((char *)&(v), -1, sizeof(v));
237  v[1] = s.b;
238  check(lay((char *)&v, sizeof(n_a), sizeof(n_a)*2, sizeof(n_a)*3) == sizeof(n_a)*3*8,
239	"structure assignment");
240
241  check(i.m1 == 77, "i.m1");
242  check(i.m2 == 1924, "i.m2");
243  check(i.m3 == -1471601920, "i.m3");
244  check(vec_all_eq(i.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
245	"i.m5");
246
247  initn_a(77, 1924, -1471601920, 3.65e+18, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08}));
248  varargsn_a(77, 1924, -1471601920, 3.65e+18, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08}));
249
250  gn_a.m1 = 77;
251  gn_a.m2 = 1924;
252  gn_a.m3 = -1471601920;
253  gn_a.m4 = 3.65e+18;
254  gn_a.m5 = ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08});
255  a = valuen_a();
256
257  check(a.m1 == 77, "a.m1");
258  check(a.m2 == 1924, "a.m2");
259  check(a.m3 == -1471601920, "a.m3");
260  check(vec_all_eq(a.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
261	"a.m5");
262
263  p = addrn_a();
264
265  check(p->m1 == 77, "p->m1");
266  check(p->m2 == 1924, "p->m2");
267  check(p->m3 == -1471601920, "p->m3");
268  check(vec_all_eq(p->m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
269	"p->m5");
270
271  eqn_a(&a);
272
273  check(gn_a.m1 == 77, "gn_a.m1");
274  check(gn_a.m2 == 1924, "gn_a.m2");
275  check(gn_a.m3 == -1471601920, "gn_a.m3");
276  check(vec_all_eq(gn_a.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
277	"gn_a.m5");
278
279  getsn_a(&v[0]);
280  v[2].m1 = v[0].m1;
281  v[2].m2 = v[0].m2;
282  v[2].m3 = v[0].m3;
283  v[2].m4 = v[0].m4;
284  v[2].m5 = v[0].m5;
285
286  check(v[2].m1 == 77, "v[2].m1");
287  check(v[2].m2 == 1924, "v[2].m2");
288  check(v[2].m3 == -1471601920, "v[2].m3");
289  check(vec_all_eq(v[2].m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
290	"v[2].m5");
291}
292