25# ifndef DYNAMIC_CRC_TABLE
26# define DYNAMIC_CRC_TABLE
60# error N must be in 1..6
82# if defined(__x86_64__) || defined(__aarch64__)
90# if W == 8 && defined(Z_U8)
91 typedef Z_U8 z_word_t;
95 typedef Z_U4 z_word_t;
102#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8
110#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
111 local z_word_t byte_swap
OF((z_word_t word));
114#if defined(W) && !defined(ARMCRC32)
115 local z_crc_t crc_word
OF((z_word_t data));
116 local z_word_t crc_word_big
OF((z_word_t data));
119#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
126local z_word_t byte_swap(word)
131 (word & 0xff00000000000000) >> 56 |
132 (word & 0xff000000000000) >> 40 |
133 (word & 0xff0000000000) >> 24 |
134 (word & 0xff00000000) >> 8 |
135 (word & 0xff000000) << 8 |
136 (word & 0xff0000) << 24 |
137 (word & 0xff00) << 40 |
141 (word & 0xff000000) >> 24 |
142 (word & 0xff0000) >> 8 |
143 (word & 0xff00) << 8 |
150#define POLY 0xedb88320
152#ifdef DYNAMIC_CRC_TABLE
156local void make_crc_table
OF((
void));
158 local z_word_t FAR crc_big_table[256];
159 local z_crc_t FAR crc_braid_table[
W][256];
160 local z_word_t FAR crc_braid_big_table[
W][256];
161 local void braid
OF((z_crc_t [][256], z_word_t [][256],
int,
int));
164 local void write_table
OF((FILE *,
const z_crc_t FAR *,
int));
165 local void write_table32hi
OF((FILE *,
const z_word_t FAR *,
int));
166 local void write_table64
OF((FILE *,
const z_word_t FAR *,
int));
178typedef struct once_s once_t;
179local void once
OF((once_t *,
void (*)(
void)));
182#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \
183 !defined(__STDC_NO_ATOMICS__)
185#include <stdatomic.h>
192#define ONCE_INIT {ATOMIC_FLAG_INIT, 0}
199local void once(state, init)
203 if (!atomic_load(&state->done)) {
204 if (atomic_flag_test_and_set(&state->begun))
205 while (!atomic_load(&state->done))
209 atomic_store(&state->done, 1);
221#define ONCE_INIT {0, 0}
225local int test_and_set
OF((
int volatile *));
226local int test_and_set(flag)
237local void once(state, init)
242 if (test_and_set(&state->begun))
255local once_t made = ONCE_INIT;
282local void make_crc_table()
288 for (i = 0; i < 256; i++) {
290 for (j = 0; j < 8; j++)
291 p = p & 1 ? (p >> 1) ^
POLY : p >> 1;
294 crc_big_table[i] = byte_swap(p);
299 p = (z_crc_t)1 << 30;
301 for (n = 1;
n < 32;
n++)
306 braid(crc_braid_table, crc_braid_big_table,
N,
W);
317#if !defined(W) || W != 8
318# error Need a 64-bit integer type in order to generate crc32.h.
323 z_word_t big[8][256];
325 out = fopen(
"crc32.h",
"w");
326 if (out == NULL)
return;
330 "/* crc32.h -- tables for rapid CRC calculation\n"
331 " * Generated automatically by crc32.c\n */\n"
333 "local const z_crc_t FAR crc_table[] = {\n"
346 "local const z_word_t FAR crc_big_table[] = {\n"
348 write_table64(out, crc_big_table, 256);
355 "#else /* W == 4 */\n"
357 "local const z_word_t FAR crc_big_table[] = {\n"
359 write_table32hi(out, crc_big_table, 256);
366 for (n = 1;
n <= 6;
n++) {
372 braid(ltl, big, n, 8);
379 "local const z_crc_t FAR crc_braid_table[][256] = {\n");
380 for (k = 0; k < 8; k++) {
382 write_table(out, ltl[k], 256);
383 fprintf(out,
"}%s", k < 7 ?
",\n" :
"");
388 "local const z_word_t FAR crc_braid_big_table[][256] = {\n");
389 for (k = 0; k < 8; k++) {
391 write_table64(out, big[k], 256);
392 fprintf(out,
"}%s", k < 7 ?
",\n" :
"");
398 braid(ltl, big, n, 4);
403 "#else /* W == 4 */\n"
405 "local const z_crc_t FAR crc_braid_table[][256] = {\n");
406 for (k = 0; k < 4; k++) {
408 write_table(out, ltl[k], 256);
409 fprintf(out,
"}%s", k < 3 ?
",\n" :
"");
414 "local const z_word_t FAR crc_braid_big_table[][256] = {\n");
415 for (k = 0; k < 4; k++) {
417 write_table32hi(out, big[k], 256);
418 fprintf(out,
"}%s", k < 3 ?
",\n" :
"");
434 "local const z_crc_t FAR x2n_table[] = {\n"
450local void write_table(out, table, k)
452 const z_crc_t FAR *table;
457 for (n = 0;
n < k;
n++)
458 fprintf(out,
"%s0x%08lx%s", n == 0 || n % 5 ?
"" :
" ",
459 (
unsigned long)(table[n]),
460 n == k - 1 ?
"" : (n % 5 == 4 ?
",\n" :
", "));
467local void write_table32hi(out, table, k)
469const z_word_t FAR *table;
474 for (n = 0;
n < k;
n++)
475 fprintf(out,
"%s0x%08lx%s", n == 0 || n % 5 ?
"" :
" ",
476 (
unsigned long)(table[n] >> 32),
477 n == k - 1 ?
"" : (n % 5 == 4 ?
",\n" :
", "));
487local void write_table64(out, table, k)
489 const z_word_t FAR *table;
494 for (n = 0;
n < k;
n++)
495 fprintf(out,
"%s0x%016llx%s", n == 0 || n % 3 ?
"" :
" ",
496 (
unsigned long long)(table[n]),
497 n == k - 1 ?
"" : (n % 3 == 2 ?
",\n" :
", "));
514local void braid(ltl, big, n, w)
522 for (k = 0; k < w; k++) {
523 p =
x2nmodp((n * w + 3 - k) << 3, 0);
525 big[w - 1 - k][0] = 0;
526 for (i = 1; i < 256; i++) {
527 ltl[k][i] = q =
multmodp(i << 24, p);
528 big[w - 1 - k][i] = byte_swap(q);
557 m = (z_crc_t)1 << 31;
562 if ((a & (m - 1)) == 0)
566 b = b & 1 ? (b >> 1) ^
POLY : b >> 1;
581 p = (z_crc_t)1 << 31;
597#ifdef DYNAMIC_CRC_TABLE
598 once(&made, make_crc_table);
619#define Z_BATCH_ZEROS 0xa10d3d0c
620#define Z_BATCH_MIN 800
622unsigned long ZEXPORT
crc32_z(crc, buf, len)
624 const unsigned char FAR *buf;
629 const z_word_t *word;
630 z_word_t val0, val1, val2;
631 z_size_t last, last2, i;
635 if (buf ==
Z_NULL)
return 0;
637#ifdef DYNAMIC_CRC_TABLE
638 once(&made, make_crc_table);
642 crc = (~crc) & 0xffffffff;
645 while (len && ((z_size_t)buf & 7) != 0) {
648 __asm__
volatile(
"crc32b %w0, %w0, %w1" :
"+r"(crc) :
"r"(val));
652 word = (z_word_t
const *)buf;
659 while (num >= 3 * Z_BATCH) {
662 for (i = 0; i < Z_BATCH; i++) {
664 val1 = word[i + Z_BATCH];
665 val2 = word[i + 2 * Z_BATCH];
666 __asm__
volatile(
"crc32x %w0, %w0, %x1" :
"+r"(crc) :
"r"(val0));
667 __asm__
volatile(
"crc32x %w0, %w0, %x1" :
"+r"(crc1) :
"r"(val1));
668 __asm__
volatile(
"crc32x %w0, %w0, %x1" :
"+r"(crc2) :
"r"(val2));
672 crc =
multmodp(Z_BATCH_ZEROS, crc) ^ crc1;
673 crc =
multmodp(Z_BATCH_ZEROS, crc) ^ crc2;
679 if (last >= Z_BATCH_MIN) {
683 for (i = 0; i < last; i++) {
685 val1 = word[i + last];
686 val2 = word[i + last2];
687 __asm__
volatile(
"crc32x %w0, %w0, %x1" :
"+r"(crc) :
"r"(val0));
688 __asm__
volatile(
"crc32x %w0, %w0, %x1" :
"+r"(crc1) :
"r"(val1));
689 __asm__
volatile(
"crc32x %w0, %w0, %x1" :
"+r"(crc2) :
"r"(val2));
699 for (i = 0; i < num; i++) {
701 __asm__
volatile(
"crc32x %w0, %w0, %x1" :
"+r"(crc) :
"r"(val0));
706 buf = (
const unsigned char FAR *)word;
710 __asm__
volatile(
"crc32b %w0, %w0, %w1" :
"+r"(crc) :
"r"(val));
714 return crc ^ 0xffffffff;
726local z_crc_t crc_word(data)
730 for (k = 0; k <
W; k++)
731 data = (data >> 8) ^
crc_table[data & 0xff];
732 return (z_crc_t)data;
735local z_word_t crc_word_big(data)
739 for (k = 0; k <
W; k++)
741 crc_big_table[(data >> ((
W - 1) << 3)) & 0xff];
750 const unsigned char FAR *buf;
754 if (buf ==
Z_NULL)
return 0;
756#ifdef DYNAMIC_CRC_TABLE
757 once(&made, make_crc_table);
761 crc = (~crc) & 0xffffffff;
766 if (len >=
N *
W +
W - 1) {
768 z_word_t
const *words;
773 while (len && ((z_size_t)buf & (
W - 1)) != 0) {
775 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
779 blks = len / (
N *
W);
781 words = (z_word_t
const *)buf;
788 if (*(
unsigned char *)&endian) {
838 word0 = crc0 ^ words[0];
840 word1 = crc1 ^ words[1];
842 word2 = crc2 ^ words[2];
844 word3 = crc3 ^ words[3];
846 word4 = crc4 ^ words[4];
848 word5 = crc5 ^ words[5];
858 crc0 = crc_braid_table[0][word0 & 0xff];
860 crc1 = crc_braid_table[0][word1 & 0xff];
862 crc2 = crc_braid_table[0][word2 & 0xff];
864 crc3 = crc_braid_table[0][word3 & 0xff];
866 crc4 = crc_braid_table[0][word4 & 0xff];
868 crc5 = crc_braid_table[0][word5 & 0xff];
874 for (k = 1; k <
W; k++) {
875 crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff];
877 crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff];
879 crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff];
881 crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff];
883 crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff];
885 crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff];
898 crc = crc_word(crc0 ^ words[0]);
900 crc = crc_word(crc1 ^ words[1] ^ crc);
902 crc = crc_word(crc2 ^ words[2] ^ crc);
904 crc = crc_word(crc3 ^ words[3] ^ crc);
906 crc = crc_word(crc4 ^ words[4] ^ crc);
908 crc = crc_word(crc5 ^ words[5] ^ crc);
919 z_word_t crc0, word0, comb;
921 z_word_t crc1, word1;
923 z_word_t crc2, word2;
925 z_word_t crc3, word3;
927 z_word_t crc4, word4;
929 z_word_t crc5, word5;
937 crc0 = byte_swap(crc);
960 word0 = crc0 ^ words[0];
962 word1 = crc1 ^ words[1];
964 word2 = crc2 ^ words[2];
966 word3 = crc3 ^ words[3];
968 word4 = crc4 ^ words[4];
970 word5 = crc5 ^ words[5];
980 crc0 = crc_braid_big_table[0][word0 & 0xff];
982 crc1 = crc_braid_big_table[0][word1 & 0xff];
984 crc2 = crc_braid_big_table[0][word2 & 0xff];
986 crc3 = crc_braid_big_table[0][word3 & 0xff];
988 crc4 = crc_braid_big_table[0][word4 & 0xff];
990 crc5 = crc_braid_big_table[0][word5 & 0xff];
996 for (k = 1; k <
W; k++) {
997 crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff];
999 crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff];
1001 crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff];
1003 crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff];
1005 crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff];
1007 crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff];
1020 comb = crc_word_big(crc0 ^ words[0]);
1022 comb = crc_word_big(crc1 ^ words[1] ^ comb);
1024 comb = crc_word_big(crc2 ^ words[2] ^ comb);
1026 comb = crc_word_big(crc3 ^ words[3] ^ comb);
1028 comb = crc_word_big(crc4 ^ words[4] ^ comb);
1030 comb = crc_word_big(crc5 ^ words[5] ^ comb);
1037 crc = byte_swap(comb);
1043 buf = (
unsigned char const *)words;
1051 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1052 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1053 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1054 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1055 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1056 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1057 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1058 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1062 crc = (crc >> 8) ^
crc_table[(crc ^ *buf++) & 0xff];
1066 return crc ^ 0xffffffff;
1072unsigned long ZEXPORT
crc32(crc, buf, len)
1074 const unsigned char FAR *buf;
1077 return crc32_z(crc, buf, len);
1086#ifdef DYNAMIC_CRC_TABLE
1087 once(&made, make_crc_table);
1105#ifdef DYNAMIC_CRC_TABLE
1106 once(&made, make_crc_table);
1124 return multmodp(op, crc1) ^ (crc2 & 0xffffffff);
const z_crc_t FAR *ZEXPORT get_crc_table()
local z_crc_t x2nmodp(z_off64_t n, unsigned k)
local z_crc_t multmodp(z_crc_t a, z_crc_t b)
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_op(uLong crc1, uLong crc2, uLong op)
uLong ZEXPORT crc32_combine_gen(z_off_t len2)
uLong ZEXPORT crc32_combine_gen64(z_off64_t len2)
unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uInt len)
local const z_crc_t FAR crc_table[]
local const z_crc_t FAR x2n_table[]
voidpf alloc_func OF((voidpf opaque, uInt items, uInt size))