14#if defined(__SSE__) && defined(__x86_64__)
15#define HAVE_HWCRC32C 1
18#ifdef __ARM_FEATURE_CRC32
64#define POLY 0x82f63b78
75 for (
n = 0;
n < 256;
n++) {
77 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
78 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
79 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
80 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
81 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
82 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
83 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
84 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
87 for (
n = 0;
n < 256;
n++) {
89 for (
k = 1;
k < 8;
k++) {
99uint32_t
crc32c_sw(uint32_t crci,
const void *buf,
size_t len)
101 const unsigned char *next = (
const unsigned char*)buf;
105 crc = crci ^ 0xffffffff;
106 while (len && ((uintptr_t)next & 7) != 0) {
107 crc =
crc32c_table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8);
111 crc ^= *(uint64_t *)next;
124 crc =
crc32c_table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8);
127 return (uint32_t)crc ^ 0xffffffff;
154 for (
n = 0;
n < 32;
n++)
165static void crc32c_zeros_op(uint32_t *even,
size_t len)
174 for (
n = 1;
n < 32;
n++) {
198 for (
n = 0;
n < 32;
n++)
204static void crc32c_zeros(uint32_t zeros[][256],
size_t len)
209 crc32c_zeros_op(op, len);
210 for (
n = 0;
n < 256;
n++) {
221static inline uint32_t
crc32c_shift(uint32_t zeros[][256], uint32_t crc)
223 return zeros[0][crc & 0xff] ^ zeros[1][(crc >> 8) & 0xff] ^
224 zeros[2][(crc >> 16) & 0xff] ^ zeros[3][crc >> 24];
232#define LONGx2 "16384"
240static pthread_once_t crc32c_once_hw = PTHREAD_ONCE_INIT;
241static uint32_t crc32c_long[4][256];
242static uint32_t crc32c_short[4][256];
245static void crc32c_init_hw(
void)
247 crc32c_zeros(crc32c_long,
LONG);
248 crc32c_zeros(crc32c_short,
SHORT);
252uint32_t
crc32c_hw(uint32_t crc,
const void *buf,
size_t len)
254 const unsigned char *next = (
const unsigned char*)buf;
255 const unsigned char *
end;
256 uint64_t crc0, crc1, crc2;
259 pthread_once(&crc32c_once_hw, crc32c_init_hw);
262 crc0 = crc ^ 0xffffffff;
266 while (len && ((uintptr_t)next & 7) != 0) {
267 __asm__(
"crc32b\t" "(%1), %0"
269 :
"r"(next),
"0"(crc0));
278 while (len >=
LONG*3) {
283 __asm__(
"crc32q\t" "(%3), %0\n\t"
284 "crc32q\t" LONGx1 "(%3), %1\n\t"
285 "crc32q\t" LONGx2 "(%3), %2"
286 :
"=r"(crc0),
"=r"(crc1),
"=r"(crc2)
287 :
"r"(next),
"0"(crc0),
"1"(crc1),
"2"(crc2));
289 }
while (next <
end);
298 while (len >=
SHORT*3) {
303 __asm__(
"crc32q\t" "(%3), %0\n\t"
304 "crc32q\t" SHORTx1 "(%3), %1\n\t"
306 :
"=r"(crc0),
"=r"(crc1),
"=r"(crc2)
307 :
"r"(next),
"0"(crc0),
"1"(crc1),
"2"(crc2));
309 }
while (next <
end);
318 end = next + (len - (len & 7));
320 __asm__(
"crc32q\t" "(%1), %0"
322 :
"r"(next),
"0"(crc0));
329 __asm__(
"crc32b\t" "(%1), %0"
331 :
"r"(next),
"0"(crc0));
337 return (uint32_t)crc0 ^ 0xffffffff;
353 (have) = (ecx >> 20) & 1; \
358#ifdef __ARM_FEATURE_CRC32
360uint32_t crc32c_arm_hw(uint32_t crc,
const void *buf,
size_t len)
363 uint8_t *pd = (uint8_t *)buf;
366 while (((uintptr_t)pd & 7) && len > 0) {
367 crc = __crc32cb(crc, *(uint8_t *)pd);
373 crc = __crc32cd(crc, *(uint64_t *)pd);
379 crc = __crc32cb(crc, *(uint8_t *)pd);
391uint32_t
crc32c(uint32_t crc,
const void *buf,
size_t len)
398#elif defined(__ARM_FEATURE_CRC32)
399 return crc32c_arm_hw(crc, buf, len);
401#warning Hardware accelerated CRC32C is not available.
408#define SIZE (262144*3)
411int main(
int argc,
char **argv)
420 buf = (
char*)malloc(
SIZE);
422 fputs(
"out of memory", stderr);
425 while ((got =
read(0, buf,
SIZE)) > 0) {
428 n = (size_t)got - off;
431 crc = argc > 1 ?
crc32c_sw(crc, buf + off,
n) :
434 }
while (off < (
size_t)got);
438 fputs(
"read error\n", stderr);
441 printf(
"%08x\n", crc);
static uint32_t gf2_matrix_times(uint32_t *mat, uint32_t vec)
uint32_t crc32c(uint32_t crc, const void *buf, size_t len)
static uint32_t crc32c_table[8][256]
static pthread_once_t crc32c_once_sw
static uint32_t crc32c_shift(uint32_t zeros[][256], uint32_t crc)
static void crc32c_init_sw(void)
static void gf2_matrix_square(uint32_t *square, uint32_t *mat)
uint32_t crc32c_sw(uint32_t crci, const void *buf, size_t len)
uint32_t crc32c_hw(uint32_t crc, const void *buf, size_t len)