1
2#include <stdlib.h>
3#include <stdio.h>
4
5typedef  unsigned int            UInt;
6typedef  unsigned long long int  ULong;
7typedef  unsigned char           UChar;
8typedef  unsigned short int      UShort;
9
10
11/////////////////////////////////////////////////////////////////
12
13UInt do_s_crc32b ( UInt crcIn, UChar b )
14{
15   UInt i, crc = (b & 0xFF) ^ crcIn;
16   for (i = 0; i < 8; i++)
17      crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78 : 0);
18   return crc;
19}
20
21UInt do_s_crc32w ( UInt crcIn, UShort w )
22{
23   UInt i, crc = (w & 0xFFFF) ^ crcIn;
24   for (i = 0; i < 16; i++)
25      crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78 : 0);
26   return crc;
27}
28
29UInt do_s_crc32l ( UInt crcIn, UInt l )
30{
31   UInt i, crc = l ^ crcIn;
32   for (i = 0; i < 32; i++)
33      crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78 : 0);
34   return crc;
35}
36
37UInt do_s_crc32q ( UInt crcIn, ULong q )
38{
39   UInt crc = do_s_crc32l(crcIn, (UInt)q);
40   return do_s_crc32l(crc, (UInt)(q >> 32));
41}
42
43UInt do_h_crc32b ( UInt crcIn, UChar b )
44{
45   __asm__ __volatile__(
46      "crc32b %%cl,%%esi\n\t"
47      : "=S"(crcIn) : "0"(crcIn), "c"(b)
48   );
49   return crcIn;
50}
51
52UInt do_h_crc32w ( UInt crcIn, UShort w )
53{
54   __asm__ __volatile__(
55      "crc32w %%cx,%%esi\n\t"
56      : "=S"(crcIn) : "0"(crcIn), "c"(w)
57   );
58   return crcIn;
59}
60
61UInt do_h_crc32l ( UInt crcIn, UInt l )
62{
63   __asm__ __volatile__(
64      "crc32l %%ecx,%%esi\n\t"
65      : "=S"(crcIn) : "0"(crcIn), "c"(l)
66   );
67   return crcIn;
68}
69
70UInt do_h_crc32q ( UInt crcIn, ULong q )
71{
72   __asm__ __volatile__(
73      "crc32q %%rcx,%%rsi\n\t"
74      : "=S"(crcIn) : "0"(crcIn), "c"(q)
75   );
76   return crcIn;
77}
78
79////////////////
80
81UInt do_h_crc32b_mem ( UInt crcIn, UChar* a )
82{
83   __asm__ __volatile__(
84      "crc32b (%2),%%esi\n\t"
85      : "=S"(crcIn) : "0"(crcIn), "r"(a)
86   );
87   return crcIn;
88}
89
90UInt do_h_crc32w_mem ( UInt crcIn, UShort* a )
91{
92   __asm__ __volatile__(
93      "crc32w (%2),%%esi\n\t"
94      : "=S"(crcIn) : "0"(crcIn), "r"(a)
95   );
96   return crcIn;
97}
98
99UInt do_h_crc32l_mem ( UInt crcIn, UInt* a )
100{
101   __asm__ __volatile__(
102      "crc32l (%2),%%esi\n\t"
103      : "=S"(crcIn) : "0"(crcIn), "r"(a)
104   );
105   return crcIn;
106}
107
108UInt do_h_crc32q_mem ( UInt crcIn, ULong* a )
109{
110   __asm__ __volatile__(
111      "crc32q (%2),%%rsi\n\t"
112      : "=S"(crcIn) : "0"(crcIn), "r"(a)
113   );
114   return crcIn;
115}
116
117void try_simple ( void )
118{
119   UInt c0 = 0xFFFFFFFF;
120   UChar c = 0x42;
121
122   UInt cs = do_s_crc32b(c0, c);
123   UInt ch = do_h_crc32b(c0, c);
124   printf("b  %08x %08x\n", cs, ch);
125
126   UShort w = 0xed78;;
127   cs = do_s_crc32w(c0, w);
128   ch = do_h_crc32w(c0, w);
129   printf("w  %08x %08x\n", cs, ch);
130
131   UInt i = 0xCAFEBABE;
132   cs = do_s_crc32l(c0, i);
133   ch = do_h_crc32l(c0, i);
134   printf("l  %08x %08x\n", cs, ch);
135
136   ULong q = 0x0ddC0ffeeBadF00d;
137   cs = do_s_crc32q(c0, q);
138   ch = do_h_crc32q(c0, q);
139   printf("q  %08x %08x\n", cs, ch);
140}
141
142#define NMEM 1000
143void try_mem ( void )
144{
145  UInt al, i;
146  UChar* b = malloc(NMEM);
147  for (i = 0; i < NMEM; i++)
148     b[i] = (UChar)(i % 177);
149
150  for (al = 0; al < 1; al++) {
151     UInt crc = 0xFFFFFFFF;
152     for (i = 0; i <= 1000-1-al; i += 1)
153        crc = do_h_crc32b_mem( crc, &b[i+al] );
154     printf("mem b misalign %d = %08x\n", al, crc);
155  }
156
157  for (al = 0; al < 2; al++) {
158     UInt crc = 0xFFFFFFFF;
159     for (i = 0; i <= 1000-2-al; i += 2)
160       crc = do_h_crc32w_mem( crc, (UShort*)&b[i+al] );
161     printf("mem w misalign %d = %08x\n", al, crc);
162  }
163
164  for (al = 0; al < 4; al++) {
165     UInt crc = 0xFFFFFFFF;
166     for (i = 0; i <= 1000-4-al; i += 4)
167       crc = do_h_crc32l_mem( crc, (UInt*)&b[i+al] );
168     printf("mem l misalign %d = %08x\n", al, crc);
169  }
170
171  for (al = 0; al < 8; al++) {
172     UInt crc = 0xFFFFFFFF;
173     for (i = 0; i <= 1000-8-al; i += 8)
174       crc = do_h_crc32q_mem( crc, (ULong*)&b[i+al] );
175     printf("mem q misalign %d = %08x\n", al, crc);
176  }
177
178  free(b);
179}
180
181void try_misc ( void )
182{
183   ULong res = 0xAAAAAAAAAAAAAAAAULL;
184   __asm__ __volatile__(
185      "movabsq $0x5555555555555555, %%rax"  "\n\t"
186      "movabsq $042, %%rbx"  "\n\t"
187      "crc32b %%bl,%%rax"  "\n\t"
188      "movq %%rax, %0"  "\n"
189      : "=r"(res) : : "rax","rbx"
190   );
191   printf("try_misc 64bit-dst 0x%016llx\n", res);
192
193   __asm__ __volatile__(
194      "movabsq $0x5555555555555555, %%rax"  "\n\t"
195      "movabsq $042, %%rbx"  "\n\t"
196      "crc32b %%bl,%%eax"  "\n\t"
197      "movq %%rax, %0"  "\n"
198      : "=r"(res) : : "rax","rbx"
199   );
200   printf("try_misc 32bit-dst 0x%016llx\n", res);
201}
202
203/////////////////////////////////////////////////////////////////
204
205
206
207int main ( int argc, char** argv )
208{
209   try_simple();
210   try_mem();
211   try_misc();
212   return 0;
213}
214