56#if defined(__aarch64__) && !defined(__AARCH64EB__)
60#if !defined(__ARM_FEATURE_CRC32) && defined(__linux__)
67#define POLY 0x82f63b78
69#if defined(__x86_64__) || defined(CRC32C_HW_ARM)
77static inline uint32_t gf2_matrix_times(uint32_t *mat, uint32_t vec) {
90static inline void gf2_matrix_square(uint32_t *square, uint32_t *mat) {
91 for (
unsigned n = 0; n < 32; n++)
92 square[n] = gf2_matrix_times(mat, mat[n]);
100static void crc32c_zeros_op(uint32_t *even,
size_t len) {
106 for (
unsigned n = 1; n < 32; n++) {
112 gf2_matrix_square(even, odd);
115 gf2_matrix_square(odd, even);
121 gf2_matrix_square(even, odd);
125 gf2_matrix_square(odd, even);
130 for (
unsigned n = 0; n < 32; n++)
136static void crc32c_zeros(uint32_t zeros[][256],
size_t len) {
139 crc32c_zeros_op(op, len);
140 for (
unsigned n = 0; n < 256; n++) {
141 zeros[0][n] = gf2_matrix_times(op, n);
142 zeros[1][n] = gf2_matrix_times(op, n << 8);
143 zeros[2][n] = gf2_matrix_times(op, n << 16);
144 zeros[3][n] = gf2_matrix_times(op, n << 24);
149static inline uint32_t crc32c_shift(uint32_t zeros[][256], uint32_t crc) {
150 return zeros[0][crc & 0xff] ^ zeros[1][(crc >> 8) & 0xff] ^
151 zeros[2][(crc >> 16) & 0xff] ^ zeros[3][crc >> 24];
159#define LONGx2 "16384"
165static pthread_once_t crc32c_once_hw = PTHREAD_ONCE_INIT;
166static uint32_t crc32c_long[4][256];
167static uint32_t crc32c_short[4][256];
170static void crc32c_init_hw(
void) {
171 crc32c_zeros(crc32c_long, LONG);
172 crc32c_zeros(crc32c_short, SHORT);
180static uint32_t crc32c_hw(uint32_t crc,
void const *buf,
size_t len) {
182 pthread_once(&crc32c_once_hw, crc32c_init_hw);
191 unsigned char const *next = (
unsigned char const *)buf;
197 while (len >= LONG*3) {
200 unsigned char const *
const end = next + LONG;
202 __asm__(
"crc32q\t" "(%3), %0\n\t"
203 "crc32q\t" LONGx1
"(%3), %1\n\t"
204 "crc32q\t" LONGx2
"(%3), %2"
205 :
"=r"(crc0),
"=r"(crc1),
"=r"(crc2)
206 :
"r"(next),
"0"(crc0),
"1"(crc1),
"2"(crc2));
208 }
while (next < end);
209 crc0 = crc32c_shift(crc32c_long, crc0) ^ crc1;
210 crc0 = crc32c_shift(crc32c_long, crc0) ^ crc2;
217 while (len >= SHORT*3) {
220 unsigned char const *
const end = next + SHORT;
222 __asm__(
"crc32q\t" "(%3), %0\n\t"
223 "crc32q\t" SHORTx1
"(%3), %1\n\t"
224 "crc32q\t" SHORTx2
"(%3), %2"
225 :
"=r"(crc0),
"=r"(crc1),
"=r"(crc2)
226 :
"r"(next),
"0"(crc0),
"1"(crc1),
"2"(crc2));
228 }
while (next < end);
229 crc0 = crc32c_shift(crc32c_short, crc0) ^ crc1;
230 crc0 = crc32c_shift(crc32c_short, crc0) ^ crc2;
238 unsigned char const *
const end = next + (len - (len & 7));
240 __asm__(
"crc32q\t" "(%1), %0"
242 :
"r"(next),
"0"(crc0));
252 __asm__(
"crc32l\t" "(%1), %0"
254 :
"r"(next),
"0"(crc));
258 __asm__(
"crc32w\t" "(%1), %0"
260 :
"r"(next),
"0"(crc));
264 __asm__(
"crc32b\t" "(%1), %0"
266 :
"r"(next),
"0"(crc));
286 (have) = (ecx >> 20) & 1; \
289static int crc32c_have_sse42(
void) {
299uint32_t
crc32c(uint32_t crc,
void const *buf,
size_t len) {
300 static const int sse42 = crc32c_have_sse42();
302 return sse42 ? crc32c_hw(crc, buf, len) :
crc32c_sw(crc, buf, len);
305#elif defined(CRC32C_HW_ARM)
309#ifdef __ARM_FEATURE_CRC32
310#define CRC32C_TARGET_CRC
312#define CRC32C_TARGET_CRC __attribute__((target("+crc")))
316static inline uint64_t crc32c_load64(
unsigned char const *next) {
318 memcpy(&word, next,
sizeof(word));
326static uint32_t crc32c_hw(uint32_t crc,
void const *buf,
size_t len) {
328 pthread_once(&crc32c_once_hw, crc32c_init_hw);
330 uint32_t crc0 = ~crc;
331 unsigned char const *next = (
unsigned char const *)buf;
335 while (len >= LONG*3) {
338 unsigned char const *
const end = next + LONG;
340 crc0 = __crc32cd(crc0, crc32c_load64(next));
341 crc1 = __crc32cd(crc1, crc32c_load64(next + LONG));
342 crc2 = __crc32cd(crc2, crc32c_load64(next + LONG*2));
344 }
while (next < end);
345 crc0 = crc32c_shift(crc32c_long, crc0) ^ crc1;
346 crc0 = crc32c_shift(crc32c_long, crc0) ^ crc2;
353 while (len >= SHORT*3) {
356 unsigned char const *
const end = next + SHORT;
358 crc0 = __crc32cd(crc0, crc32c_load64(next));
359 crc1 = __crc32cd(crc1, crc32c_load64(next + SHORT));
360 crc2 = __crc32cd(crc2, crc32c_load64(next + SHORT*2));
362 }
while (next < end);
363 crc0 = crc32c_shift(crc32c_short, crc0) ^ crc1;
364 crc0 = crc32c_shift(crc32c_short, crc0) ^ crc2;
372 crc0 = __crc32cd(crc0, crc32c_load64(next));
381 memcpy(&word, next,
sizeof(word));
382 crc0 = __crc32cw(crc0, word);
387 memcpy(&half, next,
sizeof(half));
388 crc0 = __crc32ch(crc0, half);
392 crc0 = __crc32cb(crc0, *next);
400static int crc32c_have_crc(
void) {
401#if defined(__ARM_FEATURE_CRC32)
403#elif defined(__linux__) && defined(HWCAP_CRC32)
404 return (getauxval(AT_HWCAP) & HWCAP_CRC32) != 0;
413uint32_t
crc32c(uint32_t crc,
void const *buf,
size_t len) {
414 static const int hw = crc32c_have_crc();
416 return hw ? crc32c_hw(crc, buf, len) :
crc32c_sw(crc, buf, len);
421uint32_t
crc32c(uint32_t crc,
void const *buf,
size_t len) {
431 for (
unsigned n = 0; n < 256; n++) {
433 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
434 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
435 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
436 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
437 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
438 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
439 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
440 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
443 for (
unsigned n = 0; n < 256; n++) {
445 for (
unsigned k = 1; k < 8; k++) {
455 unsigned char const *next = (
unsigned char const *)buf;
459 while (len && ((uintptr_t)next & 7) != 0) {
466 crcw ^= *(uint64_t
const *)next;
488#if defined(__has_builtin) || (defined(__GNUC__) && \
489 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
490# define swap __builtin_bswap64
492static inline uint64_t
swap(uint64_t x) {
493 x = ((x << 8) & 0xff00ff00ff00ff00) | ((x >> 8) & 0xff00ff00ff00ff);
494 x = ((x << 16) & 0xffff0000ffff0000) | ((x >> 16) & 0xffff0000ffff);
495 return (x << 32) | (x >> 32);
504 for (
unsigned n = 0; n < 256; n++) {
506 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
507 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
508 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
509 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
510 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
511 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
512 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
513 crc = crc & 1 ? (crc >> 1) ^
POLY : crc >> 1;
516 for (
unsigned n = 0; n < 256; n++) {
519 for (
unsigned k = 1; k < 8; k++) {
529 unsigned char const *next = (
unsigned char const *)buf;
533 while (len && ((uintptr_t)next & 7) != 0) {
538 uint64_t crcw =
swap(crc);
540 crcw ^= *(uint64_t
const *)next;
568uint32_t
crc32c_sw(uint32_t crc,
void const *buf,
size_t len) {
569 static int const little = 1;
570 if (*(
char const *)&little)
618 const uint32_t CrcBits = 32;
620 uint32_t odd [CrcBits];
621 uint32_t even[CrcBits];
625 for (
int i = 1; i < (int)CrcBits; i++)
626 odd[i] = 1 << (i - 1);
630 for (
int i = 0; i < (int)CrcBits; i++)
632 uint32_t vec = odd[i];
634 for (
int j = 0; vec != 0; j++, vec >>= 1)
640 for (
int i = 0; i < (int)CrcBits; i++)
642 uint32_t vec = even[i];
644 for (
int j = 0; vec != 0; j++, vec >>= 1)
653 for (; lengthB > 0; lengthB >>= 1)
656 for (
int i = 0; i < (int)CrcBits; i++)
660 for (
int j = 0; vec != 0; j++, vec >>= 1)
670 for (
int i = 0; crcA != 0; i++, crcA >>= 1)
677 uint32_t* t = a; a = b; b = t;
694int main(
int argc,
char **argv) {
697 fputs(
"only one argument permitted\n", stderr);
700 long rep = argc == 1 ? 1 : strtol(argv[1], NULL, 10);
702 fputs(
"usage: crc32c [[-]nnn] < data\n"
703 " where nnn is the number of times to repeat\n"
704 " negative forces the software implementation\n", stderr);
714 int ret = load(stdin, 0, &dat, &size, &len);
716 fputs(
"error reading from stdin\n", stderr);
727 printf(
"0x%08x\n", crc);
int main(int argc, char *argv[])
static pthread_once_t crc32c_once_little
uint32_t crc32c(uint32_t crc, void const *buf, size_t len)
static uint64_t swap(uint64_t x)
uint32_t crc32c_sw_big(uint32_t crc, void const *buf, size_t len)
uint32_t crc32c_sw(uint32_t crc, void const *buf, size_t len)
static uint64_t crc32c_table_big[8][256]
static void crc32c_init_sw_little(void)
static uint32_t crc32c_table_big_byte[256]
static void crc32c_init_sw_big(void)
uint32_t crc32c_sw_little(uint32_t crc, void const *buf, size_t len)
static uint32_t crc32c_table_little[8][256]
static pthread_once_t crc32c_once_big
uint32_t crc32c_combine(uint32_t crcA, uint32_t crcB, size_t lengthB)
merge two CRC32 such that result = crc32(dataB, lengthB, crc32(dataA, lengthA))