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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 207 int main ( int argc, char** argv ) 208 { 209 try_simple(); 210 try_mem(); 211 try_misc(); 212 return 0; 213 } 214