#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;
}