--- /dev/null
+
+#include <stdlib.h>
+#include <stdio.h>
+
+typedef unsigned int UInt;
+typedef unsigned long long int ULong;
+typedef unsigned char UChar;
+typedef unsigned short int UShort;
+
+
+/////////////////////////////////////////////////////////////////
+
+UInt do_s_crc32b ( UInt crcIn, UChar b )
+{
+ UInt i, crc = (b & 0xFF) ^ crcIn;
+ for (i = 0; i < 8; i++)
+ crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78 : 0);
+ return crc;
+}
+
+UInt do_s_crc32w ( UInt crcIn, UShort w )
+{
+ UInt i, crc = (w & 0xFFFF) ^ crcIn;
+ for (i = 0; i < 16; i++)
+ crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78 : 0);
+ return crc;
+}
+
+UInt do_s_crc32l ( UInt crcIn, UInt l )
+{
+ UInt i, crc = l ^ crcIn;
+ for (i = 0; i < 32; i++)
+ crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78 : 0);
+ return crc;
+}
+
+UInt do_s_crc32q ( UInt crcIn, ULong q )
+{
+ UInt crc = do_s_crc32l(crcIn, (UInt)q);
+ return do_s_crc32l(crc, (UInt)(q >> 32));
+}
+
+UInt do_h_crc32b ( UInt crcIn, UChar b )
+{
+ __asm__ __volatile__(
+ "crc32b %%cl,%%esi\n\t"
+ : "=S"(crcIn) : "0"(crcIn), "c"(b)
+ );
+ return crcIn;
+}
+
+UInt do_h_crc32w ( UInt crcIn, UShort w )
+{
+ __asm__ __volatile__(
+ "crc32w %%cx,%%esi\n\t"
+ : "=S"(crcIn) : "0"(crcIn), "c"(w)
+ );
+ return crcIn;
+}
+
+UInt do_h_crc32l ( UInt crcIn, UInt l )
+{
+ __asm__ __volatile__(
+ "crc32l %%ecx,%%esi\n\t"
+ : "=S"(crcIn) : "0"(crcIn), "c"(l)
+ );
+ return crcIn;
+}
+
+UInt do_h_crc32q ( UInt crcIn, ULong q )
+{
+ __asm__ __volatile__(
+ "crc32q %%rcx,%%rsi\n\t"
+ : "=S"(crcIn) : "0"(crcIn), "c"(q)
+ );
+ return crcIn;
+}
+
+////////////////
+
+UInt do_h_crc32b_mem ( UInt crcIn, UChar* a )
+{
+ __asm__ __volatile__(
+ "crc32b (%2),%%esi\n\t"
+ : "=S"(crcIn) : "0"(crcIn), "r"(a)
+ );
+ return crcIn;
+}
+
+UInt do_h_crc32w_mem ( UInt crcIn, UShort* a )
+{
+ __asm__ __volatile__(
+ "crc32w (%2),%%esi\n\t"
+ : "=S"(crcIn) : "0"(crcIn), "r"(a)
+ );
+ return crcIn;
+}
+
+UInt do_h_crc32l_mem ( UInt crcIn, UInt* a )
+{
+ __asm__ __volatile__(
+ "crc32l (%2),%%esi\n\t"
+ : "=S"(crcIn) : "0"(crcIn), "r"(a)
+ );
+ return crcIn;
+}
+
+UInt do_h_crc32q_mem ( UInt crcIn, ULong* a )
+{
+ __asm__ __volatile__(
+ "crc32q (%2),%%rsi\n\t"
+ : "=S"(crcIn) : "0"(crcIn), "r"(a)
+ );
+ return crcIn;
+}
+
+void try_simple ( void )
+{
+ UInt c0 = 0xFFFFFFFF;
+ UChar c = 0x42;
+
+ UInt cs = do_s_crc32b(c0, c);
+ UInt ch = do_h_crc32b(c0, c);
+ printf("b %08x %08x\n", cs, ch);
+
+ UShort w = 0xed78;;
+ cs = do_s_crc32w(c0, w);
+ ch = do_h_crc32w(c0, w);
+ printf("w %08x %08x\n", cs, ch);
+
+ UInt i = 0xCAFEBABE;
+ cs = do_s_crc32l(c0, i);
+ ch = do_h_crc32l(c0, i);
+ printf("l %08x %08x\n", cs, ch);
+
+ ULong q = 0x0ddC0ffeeBadF00d;
+ cs = do_s_crc32q(c0, q);
+ ch = do_h_crc32q(c0, q);
+ printf("q %08x %08x\n", cs, ch);
+}
+
+#define NMEM 1000
+void try_mem ( void )
+{
+ UInt al, i;
+ UChar* b = malloc(NMEM);
+ for (i = 0; i < NMEM; i++)
+ b[i] = (UChar)(i % 177);
+
+ for (al = 0; al < 1; al++) {
+ UInt crc = 0xFFFFFFFF;
+ for (i = 0; i <= 1000-1-al; i += 1)
+ crc = do_h_crc32b_mem( crc, &b[i+al] );
+ printf("mem b misalign %d = %08x\n", al, crc);
+ }
+
+ for (al = 0; al < 2; al++) {
+ UInt crc = 0xFFFFFFFF;
+ for (i = 0; i <= 1000-2-al; i += 2)
+ crc = do_h_crc32w_mem( crc, (UShort*)&b[i+al] );
+ printf("mem w misalign %d = %08x\n", al, crc);
+ }
+
+ for (al = 0; al < 4; al++) {
+ UInt crc = 0xFFFFFFFF;
+ for (i = 0; i <= 1000-4-al; i += 4)
+ crc = do_h_crc32l_mem( crc, (UInt*)&b[i+al] );
+ printf("mem l misalign %d = %08x\n", al, crc);
+ }
+
+ for (al = 0; al < 8; al++) {
+ UInt crc = 0xFFFFFFFF;
+ for (i = 0; i <= 1000-8-al; i += 8)
+ crc = do_h_crc32q_mem( crc, (ULong*)&b[i+al] );
+ printf("mem q misalign %d = %08x\n", al, crc);
+ }
+
+ free(b);
+}
+
+void try_misc ( void )
+{
+ ULong res = 0xAAAAAAAAAAAAAAAAULL;
+ __asm__ __volatile__(
+ "movabsq $0x5555555555555555, %%rax" "\n\t"
+ "movabsq $042, %%rbx" "\n\t"
+ "crc32b %%bl,%%rax" "\n\t"
+ "movq %%rax, %0" "\n"
+ : "=r"(res) : : "rax","rbx"
+ );
+ printf("try_misc 64bit-dst 0x%016llx\n", res);
+
+ __asm__ __volatile__(
+ "movabsq $0x5555555555555555, %%rax" "\n\t"
+ "movabsq $042, %%rbx" "\n\t"
+ "crc32b %%bl,%%eax" "\n\t"
+ "movq %%rax, %0" "\n"
+ : "=r"(res) : : "rax","rbx"
+ );
+ printf("try_misc 32bit-dst 0x%016llx\n", res);
+}
+
+/////////////////////////////////////////////////////////////////
+
+
+
+int main ( int argc, char** argv )
+{
+ try_simple();
+ try_mem();
+ try_misc();
+ return 0;
+}