1 
2 #include <stdlib.h>
3 #include <stdio.h>
4 
5 typedef  unsigned int            UInt;
6 typedef  unsigned long long int  ULong;
7 typedef  unsigned char           UChar;
8 typedef  unsigned short int      UShort;
9 
10 
11 /////////////////////////////////////////////////////////////////
12 
do_s_crc32b(UInt crcIn,UChar b)13 UInt 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 
do_s_crc32w(UInt crcIn,UShort w)21 UInt 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 
do_s_crc32l(UInt crcIn,UInt l)29 UInt 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 
do_s_crc32q(UInt crcIn,ULong q)37 UInt 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 
do_h_crc32b(UInt crcIn,UChar b)43 UInt 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 
do_h_crc32w(UInt crcIn,UShort w)52 UInt 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 
do_h_crc32l(UInt crcIn,UInt l)61 UInt 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 
do_h_crc32q(UInt crcIn,ULong q)70 UInt 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 
do_h_crc32b_mem(UInt crcIn,UChar * a)81 UInt 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 
do_h_crc32w_mem(UInt crcIn,UShort * a)90 UInt 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 
do_h_crc32l_mem(UInt crcIn,UInt * a)99 UInt 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 
do_h_crc32q_mem(UInt crcIn,ULong * a)108 UInt 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 
try_simple(void)117 void 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
try_mem(void)143 void 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 
try_misc(void)181 void 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 
main(int argc,char ** argv)207 int main ( int argc, char** argv )
208 {
209    try_simple();
210    try_mem();
211    try_misc();
212    return 0;
213 }
214