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