13#define HAVE_CRC32_INTRINSIC __builtin_cpu_supports("sse4.2")
15#define HAVE_CRC32_INTRINSIC 0
19static uint64_t gf2_mul_mod(uint64_t a,
const uint64_t b,
const uint64_t polynomial,
const uint8_t bits) {
21 for (uint8_t i = 0; i < bits; i++) {
22 if (b & UINT64_C(1) << i)
24 if (a & UINT64_C(1) << (bits - 1))
25 a = a << 1 ^ polynomial;
29 return res & (bits == 64 ? UINT64_C(-1) : (UINT64_C(1) << bits) - 1);
33static uint64_t gf2_mul_mod_reflected(uint64_t a,
const uint64_t b,
const uint64_t polynomial,
const uint8_t bits) {
35 for (uint8_t i = 0; i < bits; i++) {
36 if (b & UINT64_C(1) << i)
39 a = a >> 1 ^ polynomial;
46uint64_t
clod_crc64_add(uint64_t crc,
const void *restrict data,
size_t data_len) {
47 const uint8_t *restrict bytes = data;
49 for (
size_t i = 0; i < data_len; i++)
50 crc = crc64_table[(crc >> 56) ^ bytes[i]] ^ crc << 8;
52 for (uint8_t b = 0; data_len > 0; b++, data_len >>= 1)
54 crc = gf2_mul_mod(crc, crc64_power_table[b], CRC64_NORMALISED_POLYNOMIAL, 64);
58uint32_t
clod_crc32_add(uint32_t crc,
const void *restrict data,
size_t data_len) {
59 const uint8_t *restrict bytes = data;
62 if (HAVE_CRC32_INTRINSIC) {
64 while (((uintptr_t)data + i ) % 8 != 0 && i < data_len)
65 crc = _mm_crc32_u8(crc, bytes[i++]);
68 for (; i + 8 <= data_len; i += 8)
69 crc64 = _mm_crc32_u64(crc64, *(uint64_t*)((
char*)data + i));
71 crc = (uint32_t)crc64;
73 crc = _mm_crc32_u8(crc, bytes[i++]);
78 for (
size_t i = 0; i < data_len; i++)
79 crc = crc32_table[(crc & 0xff) ^ bytes[i]] ^ crc >> 8;
81 for (uint8_t b = 0; data_len > 0; b++, data_len >>= 1)
83 crc = (uint32_t)gf2_mul_mod_reflected(crc, crc32_power_table[b], CRC32_NORMALISED_POLYNOMIAL, 32);
87uint32_t
clod_crc24_add(uint32_t crc,
const void *restrict data,
size_t data_len) {
88 const uint8_t *restrict bytes = data;
89 crc = crc & 0x00FFFFFF;
91 for (
size_t i = 0; i < data_len; i++)
92 crc = (crc24_table[(crc >> 16) ^ bytes[i]] ^ crc << 8) & 0x00FFFFFF;
94 for (uint8_t b = 0; data_len > 0; b++, data_len >>= 1)
96 crc = (uint32_t)gf2_mul_mod(crc, crc24_power_table[b], CRC24_NORMALISED_POLYNOMIAL, 24);
100uint16_t
clod_crc16_add(uint16_t crc,
const void *restrict data,
size_t data_len) {
101 const uint8_t *restrict bytes = data;
103 for (
size_t i = 0; i < data_len; i++)
104 crc = crc16_table[(crc & 0xff) ^ bytes[i]] ^ (uint16_t)(crc >> 8);
106 for (uint8_t b = 0; data_len > 0; b++, data_len >>= 1)
108 crc = (uint16_t)gf2_mul_mod_reflected(crc, crc16_power_table[b], CRC16_NORMALISED_POLYNOMIAL, 16);
112uint8_t
clod_crc8_add(uint8_t crc,
const void *restrict data,
size_t data_len) {
113 const uint8_t *restrict bytes = data;
115 for (
size_t i = 0; i < data_len; i++)
116 crc = crc8_table[(crc & 0xff) ^ bytes[i]] ^ (uint8_t)(crc >> 8);
118 for (uint8_t b = 0; data_len > 0; b++, data_len >>= 1)
120 crc = (uint8_t)gf2_mul_mod(crc, crc8_power_table[b], CRC8_NORMALISED_POLYNOMIAL, 8);
uint64_t clod_crc64_add(uint64_t crc, const void *data, size_t data_len)
uint8_t clod_crc8_add(uint8_t crc, const void *data, size_t data_len)
uint32_t clod_crc24_add(uint32_t crc, const void *data, size_t data_len)
uint32_t clod_crc32_add(uint32_t crc, const void *data, size_t data_len)
uint16_t clod_crc16_add(uint16_t crc, const void *data, size_t data_len)