1  #include "harness.h"
       2  #include <stdarg.h>
       3  #include <stddef.h>
       4  #include <string.h>
       5  
       6  typedef struct n_a
       7  {
       8    signed char m1;
       9    short m2;
      10    int m3;
      11    double m4;
      12    vector float m5;
      13  }
      14  n_a;
      15  
      16  static n_a gn_a;
      17  
      18  static int
      19  lay(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  
      81  static void
      82  initn_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  
     135  n_a
     136  valuen_a(void)
     137  {
     138    return gn_a;
     139  }
     140  
     141  n_a *
     142  addrn_a(void)
     143  {
     144    return &gn_a;
     145  }
     146  
     147  static void
     148  eqn_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  
     157  static void
     158  getsn_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  
     167  static void
     168  varlistn_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  
     184  static void
     185  varargsn_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  
     223  static void
     224  test()
     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  }