1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdio.h>
3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdlib.h>
4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <assert.h>
5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef  signed int              Int;
7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef  unsigned int            UInt;
8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef  unsigned long long int  Addr64;
9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef  unsigned char           UChar;
10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef  unsigned long int       UWord;
11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic inline UInt ROL32 ( UInt x, UInt n ) {
13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  assert(n != 0);
14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  n &= 31;
15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  x = (x << n) | (x >> (32-n));
16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  return x;
17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//////////////////////////////////////////////////////////
20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef
22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   struct {
23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Addr64 ga;
24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Int    nbytes;
25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UChar* bytes;
26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UChar* actual;
27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   GuestBytes;
29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovGuestBytes* read_one ( FILE* f )
31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  Int r;
33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  UInt i;
34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  UInt esum, csum;
35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  GuestBytes* gb = malloc(sizeof(GuestBytes));
37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  assert(gb);
38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  if (feof(f)) return NULL;
40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  assert(!ferror(f));
41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  r= fscanf(f, "GuestBytes %llx %d  ", &gb->ga, &gb->nbytes);
43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  if (0) printf("r = %d\n", r);
44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  assert(r == 2);
45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  assert(gb->ga != 0);
47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  assert(gb->nbytes > 0);
48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  assert(gb->nbytes < 5000); // let's say
49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  Int nToAlloc = gb->nbytes + (gb->ga & 3);
51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  gb->bytes  = malloc( gb->nbytes + nToAlloc);
53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  gb->actual = gb->bytes + (gb->ga & 3);
54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  assert(gb->bytes);
55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  csum = 0;
57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  for (i = 0; i < gb->nbytes; i++) {
58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    UInt b;
59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    r= fscanf(f, "%02x ", &b);
60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    assert(r == 1);
61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    gb->actual[i] = b;
62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    csum = (csum << 1) ^ b;
63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  }
64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  r= fscanf(f, " %08x\n", &esum);
66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  assert(r == 1);
67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  assert(esum == csum);
69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  return gb;
71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//////////////////////////////////////////////////////////
74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid apply_to_all ( FILE* f,
76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    void(*fn)( GuestBytes*, void* ),
77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    void* opaque )
78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  while (!feof(f)) {
80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    GuestBytes* gb = read_one(f);
81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if (0) printf("got %llu %d\n", gb->ga, gb->nbytes);
82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    fn( gb, opaque );
83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    free(gb->bytes);
84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    free(gb);
85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  }
86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//////////////////////////////////////////////////////////
89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt hash_const_zero ( GuestBytes* gb ) {
91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  return 0;
92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt hash_sum ( GuestBytes* gb ) {
95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  UInt i, sum = 0;
96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  for (i = 0; i < gb->nbytes; i++)
97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    sum += (UInt)gb->actual[i];
98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  return sum;
99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt hash_rol ( GuestBytes* gb ) {
102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  UInt i, sum = 0;
103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  for (i = 0; i < gb->nbytes; i++) {
104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    sum ^= (UInt)gb->actual[i];
105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    sum = ROL32(sum,7);
106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  }
107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  return sum;
108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt cand0 ( GuestBytes* gb )
111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UWord addr = (UWord)gb->actual;
113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UWord len = gb->nbytes;
114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UInt sum = 0;
115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* pull up to 4-alignment */
116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while ((addr & 3) != 0 && len >= 1) {
117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UChar* p = (UChar*)addr;
118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sum = (sum << 8) | (UInt)p[0];
119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      addr++;
120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      len--;
121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* vectorised + unrolled */
123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (len >= 16) {
124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UInt* p = (UInt*)addr;
125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sum = ROL32(sum ^ p[0], 13);
126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sum = ROL32(sum ^ p[1], 13);
127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sum = ROL32(sum ^ p[2], 13);
128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sum = ROL32(sum ^ p[3], 13);
129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      addr += 16;
130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      len -= 16;
131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* vectorised fixup */
133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (len >= 4) {
134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UInt* p = (UInt*)addr;
135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sum = ROL32(sum ^ p[0], 13);
136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      addr += 4;
137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      len -= 4;
138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* scalar fixup */
140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (len >= 1) {
141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UChar* p = (UChar*)addr;
142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sum = ROL32(sum ^ (UInt)p[0], 19);
143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      addr++;
144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      len--;
145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sum;
147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt cand1 ( GuestBytes* gb )
150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UWord addr = (UWord)gb->actual;
152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UWord len = gb->nbytes;
153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UInt sum1 = 0, sum2 = 0;
154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* pull up to 4-alignment */
155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while ((addr & 3) != 0 && len >= 1) {
156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UChar* p = (UChar*)addr;
157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sum1 = (sum1 << 8) | (UInt)p[0];
158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      addr++;
159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      len--;
160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* vectorised + unrolled */
162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (len >= 16) {
163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UInt* p = (UInt*)addr;
164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UInt  w;
165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      addr += 16;
170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      len  -= 16;
171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sum1 ^= sum2;
172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* vectorised fixup */
174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (len >= 4) {
175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UInt* p = (UInt*)addr;
176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UInt  w = p[0];
177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      addr += 4;
179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      len  -= 4;
180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sum1 ^= sum2;
181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* scalar fixup */
183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (len >= 1) {
184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UChar* p = (UChar*)addr;
185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UInt   w = (UInt)p[0];
186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      addr++;
188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      len--;
189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sum1 + sum2;
191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt adler32 ( GuestBytes* gb )
194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UWord addr = (UWord)gb->actual;
196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UWord len = gb->nbytes;
197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UInt   s1 = 1;
198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UInt   s2 = 0;
199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UChar* buf = (UChar*)addr;
200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (len >= 4) {
201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      s1 += buf[0];
202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      s2 += s1;
203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      s1 += buf[1];
204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      s2 += s1;
205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      s1 += buf[2];
206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      s2 += s1;
207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      s1 += buf[3];
208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      s2 += s1;
209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      buf += 4;
210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      len -= 4;
211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (len > 0) {
213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      s1 += buf[0];
214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      s2 += s1;
215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      len--;
216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      buf++;
217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return (s2 << 16) + s1;
219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//////////////////////////////////////////////////////////
225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt (*theFn)(GuestBytes*) =
227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  //hash_const_zero;
228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  //hash_sum;
229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//hash_rol;
230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//cand0;
231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  cand1;
232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  //adler32;
233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovInt cmp_UInt_ps ( UInt* p1, UInt* p2 ) {
235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  if (*p1 < *p2) return -1;
236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  if (*p1 > *p2) return 1;
237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  return 0;
238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovInt nSetBits ( UInt w )
241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  Int i, j;
243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  j = 0;
244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  for (i = 0; i < 32; i++)
245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if (w & (1<<i))
246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      j++;
247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  return j;
248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovInt    toc_nblocks           = 0;
251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovInt    toc_nblocks_with_zero = 0;
252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovdouble toc_sum_of_avgs       = 0.0;
253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid invertBit ( UChar* b, UInt ix, UInt bix ) {
255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   b[ix] ^= (1 << bix);
256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid try_onebit_changes( GuestBytes* gb, void* opaque )
259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   toc_nblocks++;
261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* collect up the hash values for all one bit changes of the key,
262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      and also that for the unmodified key.  Then compute the number
263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      of changed bits for all of them. */
264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UInt  hashIx  = 0;
265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UInt  nHashes = 8 * gb->nbytes;
266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UInt* hashes  = malloc( nHashes * sizeof(UInt) );
267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UInt byteIx, bitIx;
269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UInt hInit, hFinal, hRunning;
270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Int dist, totDist = 0, nNoDist = 0;
271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   assert(hashes);
272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   hInit = theFn( gb );
273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    for (byteIx = 0; byteIx < gb->nbytes; byteIx++) {
274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      for (bitIx = 0; bitIx < 8; bitIx++) {
275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         invertBit(gb->actual, byteIx, bitIx);
277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         //invertBit(gb->actual, byteIx, bitIx ^ 4);
278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         hRunning = theFn( gb );
280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         dist = nSetBits(hRunning ^ hInit);
282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         totDist += dist;
283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (dist == 0) nNoDist++;
284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         hashes[hashIx++] = hRunning;
286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         invertBit(gb->actual, byteIx, bitIx);
288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         //invertBit(gb->actual, byteIx, bitIx ^ 4);
289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (0) printf("  %02d.%d  %08x  %d\n",
291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                       byteIx, bitIx, hRunning ^ hInit, dist);
292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   hFinal = theFn( gb );
295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   assert(hFinal == hInit);
296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   assert(hashIx == nHashes);
297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
298b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (nNoDist > 0)
299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      printf("%4d  measurements,  %5.2f avg dist,  %2d zeroes\n",
300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             (Int)nHashes, (double)totDist / (double)nHashes,  nNoDist);
301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   else
302b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      printf("%4d  measurements,  %5.2f avg dist\n",
303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             (Int)nHashes, (double)totDist / (double)nHashes);
304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (nNoDist > 0)
306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      toc_nblocks_with_zero++;
307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   toc_sum_of_avgs += (double)totDist / (double)nHashes;
309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   free(hashes);
311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//////////////////////////////////////////////////////////
314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint main ( void )
316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  FILE* f = stdin;
318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  apply_to_all(f, try_onebit_changes, NULL);
319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  printf("\n%d blocks,  %d with a zero,  %5.2f avg avg\n\n",
320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         toc_nblocks, toc_nblocks_with_zero, toc_sum_of_avgs / (double)toc_nblocks );
321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  return 0;
322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//////////////////////////////////////////////////////////
325