24# ifndef DYNAMIC_CRC_TABLE
25# define DYNAMIC_CRC_TABLE
59# error N must be in 1..6
81# if defined(__x86_64__) || defined(__aarch64__)
89# if W == 8 && defined(Z_U8)
90 typedef Z_U8 z_word_t;
94 typedef Z_U4 z_word_t;
105#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8
109#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
116local z_word_t byte_swap(word)
121 (word & 0xff00000000000000) >> 56 |
122 (word & 0xff000000000000) >> 40 |
123 (word & 0xff0000000000) >> 24 |
124 (word & 0xff00000000) >> 8 |
125 (word & 0xff000000) << 8 |
126 (word & 0xff0000) << 24 |
127 (word & 0xff00) << 40 |
131 (word & 0xff000000) >> 24 |
132 (word & 0xff0000) >> 8 |
133 (word & 0xff00) << 8 |
140#define POLY 0xedb88320
142#ifdef DYNAMIC_CRC_TABLE
146local void make_crc_table
OF((
void));
148 local z_word_t FAR crc_big_table[256];
149 local z_crc_t FAR crc_braid_table[
W][256];
150 local z_word_t FAR crc_braid_big_table[
W][256];
151 local void braid
OF((z_crc_t [][256], z_word_t [][256],
int,
int));
154 local void write_table
OF((FILE *,
const z_crc_t FAR *,
int));
155 local void write_table32hi
OF((FILE *,
const z_word_t FAR *,
int));
156 local void write_table64
OF((FILE *,
const z_word_t FAR *,
int));
168typedef struct once_s once_t;
169local void once
OF((once_t *,
void (*)(
void)));
172#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \
173 !defined(__STDC_NO_ATOMICS__)
175#include <stdatomic.h>
182#define ONCE_INIT {ATOMIC_FLAG_INIT, 0}
189local void once(state, init)
193 if (!atomic_load(&state->done)) {
194 if (atomic_flag_test_and_set(&state->begun))
195 while (!atomic_load(&state->done))
199 atomic_store(&state->done, 1);
211#define ONCE_INIT {0, 0}
215local int test_and_set
OF((
int volatile *));
216local int test_and_set(flag)
227local void once(state, init)
232 if (test_and_set(&state->begun))
245local once_t made = ONCE_INIT;
272local void make_crc_table()
278 for (i = 0; i < 256; i++) {
280 for (j = 0; j < 8; j++)
281 p = p & 1 ? (p >> 1) ^
POLY : p >> 1;
284 crc_big_table[i] = byte_swap(p);
289 p = (z_crc_t)1 << 30;
291 for (n = 1;
n < 32;
n++)
296 braid(crc_braid_table, crc_braid_big_table,
N,
W);
307#if !defined(W) || W != 8
308# error Need a 64-bit integer type in order to generate crc32.h.
313 z_word_t big[8][256];
315 out = fopen(
"crc32.h",
"w");
316 if (out == NULL)
return;
320 "/* crc32.h -- tables for rapid CRC calculation\n"
321 " * Generated automatically by crc32.c\n */\n"
323 "local const z_crc_t FAR crc_table[] = {\n"
336 "local const z_word_t FAR crc_big_table[] = {\n"
338 write_table64(out, crc_big_table, 256);
345 "#else /* W == 4 */\n"
347 "local const z_word_t FAR crc_big_table[] = {\n"
349 write_table32hi(out, crc_big_table, 256);
356 for (n = 1;
n <= 6;
n++) {
362 braid(ltl, big, n, 8);
369 "local const z_crc_t FAR crc_braid_table[][256] = {\n");
370 for (k = 0; k < 8; k++) {
372 write_table(out, ltl[k], 256);
373 fprintf(out,
"}%s", k < 7 ?
",\n" :
"");
378 "local const z_word_t FAR crc_braid_big_table[][256] = {\n");
379 for (k = 0; k < 8; k++) {
381 write_table64(out, big[k], 256);
382 fprintf(out,
"}%s", k < 7 ?
",\n" :
"");
388 braid(ltl, big, n, 4);
393 "#else /* W == 4 */\n"
395 "local const z_crc_t FAR crc_braid_table[][256] = {\n");
396 for (k = 0; k < 4; k++) {
398 write_table(out, ltl[k], 256);
399 fprintf(out,
"}%s", k < 3 ?
",\n" :
"");
404 "local const z_word_t FAR crc_braid_big_table[][256] = {\n");
405 for (k = 0; k < 4; k++) {
407 write_table32hi(out, big[k], 256);
408 fprintf(out,
"}%s", k < 3 ?
",\n" :
"");
424 "local const z_crc_t FAR x2n_table[] = {\n"
440local void write_table(out, table, k)
442 const z_crc_t FAR *table;
447 for (n = 0;
n < k;
n++)
448 fprintf(out,
"%s0x%08lx%s", n == 0 || n % 5 ?
"" :
" ",
449 (
unsigned long)(table[n]),
450 n == k - 1 ?
"" : (n % 5 == 4 ?
",\n" :
", "));
457local void write_table32hi(out, table, k)
459const z_word_t FAR *table;
464 for (n = 0;
n < k;
n++)
465 fprintf(out,
"%s0x%08lx%s", n == 0 || n % 5 ?
"" :
" ",
466 (
unsigned long)(table[n] >> 32),
467 n == k - 1 ?
"" : (n % 5 == 4 ?
",\n" :
", "));
477local void write_table64(out, table, k)
479 const z_word_t FAR *table;
484 for (n = 0;
n < k;
n++)
485 fprintf(out,
"%s0x%016llx%s", n == 0 || n % 3 ?
"" :
" ",
486 (
unsigned long long)(table[n]),
487 n == k - 1 ?
"" : (n % 3 == 2 ?
",\n" :
", "));
504local void braid(ltl, big, n, w)
512 for (k = 0; k < w; k++) {
513 p =
x2nmodp((n * w + 3 - k) << 3, 0);
515 big[w - 1 - k][0] = 0;
516 for (i = 1; i < 256; i++) {
517 ltl[k][i] = q =
multmodp(i << 24, p);
518 big[w - 1 - k][i] = byte_swap(q);
547 m = (z_crc_t)1 << 31;
552 if ((a & (m - 1)) == 0)
556 b = b & 1 ? (b >> 1) ^
POLY : b >> 1;
571 p = (z_crc_t)1 << 31;
587#ifdef DYNAMIC_CRC_TABLE
588 once(&made, make_crc_table);
609#define Z_BATCH_ZEROS 0xa10d3d0c
610#define Z_BATCH_MIN 800
612unsigned long ZEXPORT
crc32_z(crc, buf, len)
614 const unsigned char FAR *buf;
619 const z_word_t *word;
620 z_word_t val0, val1, val2;
621 z_size_t last, last2, i;
625 if (buf ==
Z_NULL)
return 0;
627#ifdef DYNAMIC_CRC_TABLE
628 once(&made, make_crc_table);
635 while (len && ((z_size_t)buf & 7) != 0) {
638 __asm__
volatile(
"crc32b %w0, %w0, %w1" :
"+r"(crc) :
"r"(val));
642 word = (z_word_t
const *)buf;
649 while (num >= 3 * Z_BATCH) {
652 for (i = 0; i < Z_BATCH; i++) {
654 val1 = word[i + Z_BATCH];
655 val2 = word[i + 2 * Z_BATCH];
656 __asm__
volatile(
"crc32x %w0, %w0, %x1" :
"+r"(crc) :
"r"(val0));
657 __asm__
volatile(
"crc32x %w0, %w0, %x1" :
"+r"(crc1) :
"r"(val1));
658 __asm__
volatile(
"crc32x %w0, %w0, %x1" :
"+r"(crc2) :
"r"(val2));
662 crc =
multmodp(Z_BATCH_ZEROS, crc) ^ crc1;
663 crc =
multmodp(Z_BATCH_ZEROS, crc) ^ crc2;
669 if (last >= Z_BATCH_MIN) {
673 for (i = 0; i < last; i++) {
675 val1 = word[i + last];
676 val2 = word[i + last2];
677 __asm__
volatile(
"crc32x %w0, %w0, %x1" :
"+r"(crc) :
"r"(val0));
678 __asm__
volatile(
"crc32x %w0, %w0, %x1" :
"+r"(crc1) :
"r"(val1));
679 __asm__
volatile(
"crc32x %w0, %w0, %x1" :
"+r"(crc2) :
"r"(val2));
689 for (i = 0; i < num; i++) {
691 __asm__
volatile(
"crc32x %w0, %w0, %x1" :
"+r"(crc) :
"r"(val0));
696 buf = (
const unsigned char FAR *)word;
700 __asm__
volatile(
"crc32b %w0, %w0, %w1" :
"+r"(crc) :
"r"(val));
704 return crc ^ 0xffffffff;
716local z_crc_t crc_word(data)
720 for (k = 0; k <
W; k++)
721 data = (data >> 8) ^
crc_table[data & 0xff];
722 return (z_crc_t)data;
725local z_word_t crc_word_big(data)
729 for (k = 0; k <
W; k++)
731 crc_big_table[(data >> ((
W - 1) << 3)) & 0xff];
740 const unsigned char FAR *buf;
744 if (buf ==
Z_NULL)
return 0;
746#ifdef DYNAMIC_CRC_TABLE
747 once(&made, make_crc_table);
756 if (len >=
N *
W +
W - 1) {
758 z_word_t
const *words;
763 while (len && ((z_size_t)buf & (
W - 1)) != 0) {
765 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
769 blks = len / (
N *
W);
771 words = (z_word_t
const *)buf;
778 if (*(
unsigned char *)&endian) {
828 word0 = crc0 ^ words[0];
830 word1 = crc1 ^ words[1];
832 word2 = crc2 ^ words[2];
834 word3 = crc3 ^ words[3];
836 word4 = crc4 ^ words[4];
838 word5 = crc5 ^ words[5];
848 crc0 = crc_braid_table[0][word0 & 0xff];
850 crc1 = crc_braid_table[0][word1 & 0xff];
852 crc2 = crc_braid_table[0][word2 & 0xff];
854 crc3 = crc_braid_table[0][word3 & 0xff];
856 crc4 = crc_braid_table[0][word4 & 0xff];
858 crc5 = crc_braid_table[0][word5 & 0xff];
864 for (k = 1; k <
W; k++) {
865 crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff];
867 crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff];
869 crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff];
871 crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff];
873 crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff];
875 crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff];
888 crc = crc_word(crc0 ^ words[0]);
890 crc = crc_word(crc1 ^ words[1] ^ crc);
892 crc = crc_word(crc2 ^ words[2] ^ crc);
894 crc = crc_word(crc3 ^ words[3] ^ crc);
896 crc = crc_word(crc4 ^ words[4] ^ crc);
898 crc = crc_word(crc5 ^ words[5] ^ crc);
909 z_word_t crc0, word0, comb;
911 z_word_t crc1, word1;
913 z_word_t crc2, word2;
915 z_word_t crc3, word3;
917 z_word_t crc4, word4;
919 z_word_t crc5, word5;
927 crc0 = byte_swap(crc);
950 word0 = crc0 ^ words[0];
952 word1 = crc1 ^ words[1];
954 word2 = crc2 ^ words[2];
956 word3 = crc3 ^ words[3];
958 word4 = crc4 ^ words[4];
960 word5 = crc5 ^ words[5];
970 crc0 = crc_braid_big_table[0][word0 & 0xff];
972 crc1 = crc_braid_big_table[0][word1 & 0xff];
974 crc2 = crc_braid_big_table[0][word2 & 0xff];
976 crc3 = crc_braid_big_table[0][word3 & 0xff];
978 crc4 = crc_braid_big_table[0][word4 & 0xff];
980 crc5 = crc_braid_big_table[0][word5 & 0xff];
986 for (k = 1; k <
W; k++) {
987 crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff];
989 crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff];
991 crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff];
993 crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff];
995 crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff];
997 crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff];
1010 comb = crc_word_big(crc0 ^ words[0]);
1012 comb = crc_word_big(crc1 ^ words[1] ^ comb);
1014 comb = crc_word_big(crc2 ^ words[2] ^ comb);
1016 comb = crc_word_big(crc3 ^ words[3] ^ comb);
1018 comb = crc_word_big(crc4 ^ words[4] ^ comb);
1020 comb = crc_word_big(crc5 ^ words[5] ^ comb);
1027 crc = byte_swap(comb);
1033 buf = (
unsigned char const *)words;
1041 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1042 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1043 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1044 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1045 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1046 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1047 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1048 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1052 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1056 return crc ^ 0xffffffff;
1062unsigned long ZEXPORT
crc32(crc, buf, len)
1064 const unsigned char FAR *buf;
1067 return crc32_z(crc, buf, len);
1076#ifdef DYNAMIC_CRC_TABLE
1077 once(&made, make_crc_table);
1095#ifdef DYNAMIC_CRC_TABLE
1096 once(&made, make_crc_table);
const z_crc_t FAR *ZEXPORT get_crc_table()
z_crc_t x2nmodp(z_off64_t n, unsigned k)
unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, z_size_t len)
uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2)
uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2)
uLong ZEXPORT crc32_combine_gen(z_off_t len2)
z_crc_t multmodp(z_crc_t a, z_crc_t b)
uLong ZEXPORT crc32_combine_gen64(z_off64_t len2)
uLong crc32_combine_op(uLong crc1, uLong crc2, uLong op)
unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uInt len)
const z_crc_t FAR crc_table[]
const z_crc_t FAR x2n_table[]
voidpf alloc_func OF((voidpf opaque, uInt items, uInt size))