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