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