xref: /rk3399_ARM-atf/lib/zlib/crc32.c (revision a194255d75ed9e2ef56bd6e14349a3e7d86af934)
1221b1638SMasahiro Yamada /* crc32.c -- compute the CRC-32 of a data stream
2*a194255dSDaniel Boulby  * Copyright (C) 1995-2022 Mark Adler
3221b1638SMasahiro Yamada  * For conditions of distribution and use, see copyright notice in zlib.h
4221b1638SMasahiro Yamada  *
5*a194255dSDaniel Boulby  * This interleaved implementation of a CRC makes use of pipelined multiple
6*a194255dSDaniel Boulby  * arithmetic-logic units, commonly found in modern CPU cores. It is due to
7*a194255dSDaniel Boulby  * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution.
8221b1638SMasahiro Yamada  */
9221b1638SMasahiro Yamada 
10221b1638SMasahiro Yamada /* @(#) $Id$ */
11221b1638SMasahiro Yamada 
12221b1638SMasahiro Yamada /*
13221b1638SMasahiro Yamada   Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
14221b1638SMasahiro Yamada   protection on the static variables used to control the first-use generation
15221b1638SMasahiro Yamada   of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
16221b1638SMasahiro Yamada   first call get_crc_table() to initialize the tables before allowing more than
17221b1638SMasahiro Yamada   one thread to use crc32().
18221b1638SMasahiro Yamada 
19*a194255dSDaniel Boulby   MAKECRCH can be #defined to write out crc32.h. A main() routine is also
20*a194255dSDaniel Boulby   produced, so that this one source file can be compiled to an executable.
21221b1638SMasahiro Yamada  */
22221b1638SMasahiro Yamada 
23221b1638SMasahiro Yamada #ifdef MAKECRCH
24221b1638SMasahiro Yamada #  include <stdio.h>
25221b1638SMasahiro Yamada #  ifndef DYNAMIC_CRC_TABLE
26221b1638SMasahiro Yamada #    define DYNAMIC_CRC_TABLE
27221b1638SMasahiro Yamada #  endif /* !DYNAMIC_CRC_TABLE */
28221b1638SMasahiro Yamada #endif /* MAKECRCH */
29221b1638SMasahiro Yamada 
30*a194255dSDaniel Boulby #include "zutil.h"      /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */
31221b1638SMasahiro Yamada 
32*a194255dSDaniel Boulby  /*
33*a194255dSDaniel Boulby   A CRC of a message is computed on N braids of words in the message, where
34*a194255dSDaniel Boulby   each word consists of W bytes (4 or 8). If N is 3, for example, then three
35*a194255dSDaniel Boulby   running sparse CRCs are calculated respectively on each braid, at these
36*a194255dSDaniel Boulby   indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ...
37*a194255dSDaniel Boulby   This is done starting at a word boundary, and continues until as many blocks
38*a194255dSDaniel Boulby   of N * W bytes as are available have been processed. The results are combined
39*a194255dSDaniel Boulby   into a single CRC at the end. For this code, N must be in the range 1..6 and
40*a194255dSDaniel Boulby   W must be 4 or 8. The upper limit on N can be increased if desired by adding
41*a194255dSDaniel Boulby   more #if blocks, extending the patterns apparent in the code. In addition,
42*a194255dSDaniel Boulby   crc32.h would need to be regenerated, if the maximum N value is increased.
43*a194255dSDaniel Boulby 
44*a194255dSDaniel Boulby   N and W are chosen empirically by benchmarking the execution time on a given
45*a194255dSDaniel Boulby   processor. The choices for N and W below were based on testing on Intel Kaby
46*a194255dSDaniel Boulby   Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64
47*a194255dSDaniel Boulby   Octeon II processors. The Intel, AMD, and ARM processors were all fastest
48*a194255dSDaniel Boulby   with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4.
49*a194255dSDaniel Boulby   They were all tested with either gcc or clang, all using the -O3 optimization
50*a194255dSDaniel Boulby   level. Your mileage may vary.
51*a194255dSDaniel Boulby  */
52*a194255dSDaniel Boulby 
53*a194255dSDaniel Boulby /* Define N */
54*a194255dSDaniel Boulby #ifdef Z_TESTN
55*a194255dSDaniel Boulby #  define N Z_TESTN
56221b1638SMasahiro Yamada #else
57*a194255dSDaniel Boulby #  define N 5
58*a194255dSDaniel Boulby #endif
59*a194255dSDaniel Boulby #if N < 1 || N > 6
60*a194255dSDaniel Boulby #  error N must be in 1..6
61*a194255dSDaniel Boulby #endif
62221b1638SMasahiro Yamada 
63*a194255dSDaniel Boulby /*
64*a194255dSDaniel Boulby   z_crc_t must be at least 32 bits. z_word_t must be at least as long as
65*a194255dSDaniel Boulby   z_crc_t. It is assumed here that z_word_t is either 32 bits or 64 bits, and
66*a194255dSDaniel Boulby   that bytes are eight bits.
67*a194255dSDaniel Boulby  */
68221b1638SMasahiro Yamada 
69*a194255dSDaniel Boulby /*
70*a194255dSDaniel Boulby   Define W and the associated z_word_t type. If W is not defined, then a
71*a194255dSDaniel Boulby   braided calculation is not used, and the associated tables and code are not
72*a194255dSDaniel Boulby   compiled.
73*a194255dSDaniel Boulby  */
74*a194255dSDaniel Boulby #ifdef Z_TESTW
75*a194255dSDaniel Boulby #  if Z_TESTW-1 != -1
76*a194255dSDaniel Boulby #    define W Z_TESTW
77*a194255dSDaniel Boulby #  endif
78*a194255dSDaniel Boulby #else
79*a194255dSDaniel Boulby #  ifdef MAKECRCH
80*a194255dSDaniel Boulby #    define W 8         /* required for MAKECRCH */
81*a194255dSDaniel Boulby #  else
82*a194255dSDaniel Boulby #    if defined(__x86_64__) || defined(__aarch64__)
83*a194255dSDaniel Boulby #      define W 8
84*a194255dSDaniel Boulby #    else
85*a194255dSDaniel Boulby #      define W 4
86*a194255dSDaniel Boulby #    endif
87*a194255dSDaniel Boulby #  endif
88*a194255dSDaniel Boulby #endif
89*a194255dSDaniel Boulby #ifdef W
90*a194255dSDaniel Boulby #  if W == 8 && defined(Z_U8)
91*a194255dSDaniel Boulby      typedef Z_U8 z_word_t;
92*a194255dSDaniel Boulby #  elif defined(Z_U4)
93*a194255dSDaniel Boulby #    undef W
94*a194255dSDaniel Boulby #    define W 4
95*a194255dSDaniel Boulby      typedef Z_U4 z_word_t;
96*a194255dSDaniel Boulby #  else
97*a194255dSDaniel Boulby #    undef W
98*a194255dSDaniel Boulby #  endif
99*a194255dSDaniel Boulby #endif
100*a194255dSDaniel Boulby 
101*a194255dSDaniel Boulby /* If available, use the ARM processor CRC32 instruction. */
102*a194255dSDaniel Boulby #if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8
103*a194255dSDaniel Boulby #  define ARMCRC32
104*a194255dSDaniel Boulby #endif
105*a194255dSDaniel Boulby 
106*a194255dSDaniel Boulby /* Local functions. */
107*a194255dSDaniel Boulby local z_crc_t multmodp OF((z_crc_t a, z_crc_t b));
108*a194255dSDaniel Boulby local z_crc_t x2nmodp OF((z_off64_t n, unsigned k));
109*a194255dSDaniel Boulby 
110*a194255dSDaniel Boulby #if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
111*a194255dSDaniel Boulby     local z_word_t byte_swap OF((z_word_t word));
112*a194255dSDaniel Boulby #endif
113*a194255dSDaniel Boulby 
114*a194255dSDaniel Boulby #if defined(W) && !defined(ARMCRC32)
115*a194255dSDaniel Boulby     local z_crc_t crc_word OF((z_word_t data));
116*a194255dSDaniel Boulby     local z_word_t crc_word_big OF((z_word_t data));
117*a194255dSDaniel Boulby #endif
118*a194255dSDaniel Boulby 
119*a194255dSDaniel Boulby #if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
120*a194255dSDaniel Boulby /*
121*a194255dSDaniel Boulby   Swap the bytes in a z_word_t to convert between little and big endian. Any
122*a194255dSDaniel Boulby   self-respecting compiler will optimize this to a single machine byte-swap
123*a194255dSDaniel Boulby   instruction, if one is available. This assumes that word_t is either 32 bits
124*a194255dSDaniel Boulby   or 64 bits.
125*a194255dSDaniel Boulby  */
126*a194255dSDaniel Boulby local z_word_t byte_swap(word)
127*a194255dSDaniel Boulby     z_word_t word;
128*a194255dSDaniel Boulby {
129*a194255dSDaniel Boulby #  if W == 8
130*a194255dSDaniel Boulby     return
131*a194255dSDaniel Boulby         (word & 0xff00000000000000) >> 56 |
132*a194255dSDaniel Boulby         (word & 0xff000000000000) >> 40 |
133*a194255dSDaniel Boulby         (word & 0xff0000000000) >> 24 |
134*a194255dSDaniel Boulby         (word & 0xff00000000) >> 8 |
135*a194255dSDaniel Boulby         (word & 0xff000000) << 8 |
136*a194255dSDaniel Boulby         (word & 0xff0000) << 24 |
137*a194255dSDaniel Boulby         (word & 0xff00) << 40 |
138*a194255dSDaniel Boulby         (word & 0xff) << 56;
139*a194255dSDaniel Boulby #  else   /* W == 4 */
140*a194255dSDaniel Boulby     return
141*a194255dSDaniel Boulby         (word & 0xff000000) >> 24 |
142*a194255dSDaniel Boulby         (word & 0xff0000) >> 8 |
143*a194255dSDaniel Boulby         (word & 0xff00) << 8 |
144*a194255dSDaniel Boulby         (word & 0xff) << 24;
145*a194255dSDaniel Boulby #  endif
146*a194255dSDaniel Boulby }
147*a194255dSDaniel Boulby #endif
148*a194255dSDaniel Boulby 
149*a194255dSDaniel Boulby /* CRC polynomial. */
150*a194255dSDaniel Boulby #define POLY 0xedb88320         /* p(x) reflected, with x^32 implied */
151221b1638SMasahiro Yamada 
152221b1638SMasahiro Yamada #ifdef DYNAMIC_CRC_TABLE
153221b1638SMasahiro Yamada 
154*a194255dSDaniel Boulby local z_crc_t FAR crc_table[256];
155*a194255dSDaniel Boulby local z_crc_t FAR x2n_table[32];
156221b1638SMasahiro Yamada local void make_crc_table OF((void));
157*a194255dSDaniel Boulby #ifdef W
158*a194255dSDaniel Boulby    local z_word_t FAR crc_big_table[256];
159*a194255dSDaniel Boulby    local z_crc_t FAR crc_braid_table[W][256];
160*a194255dSDaniel Boulby    local z_word_t FAR crc_braid_big_table[W][256];
161*a194255dSDaniel Boulby    local void braid OF((z_crc_t [][256], z_word_t [][256], int, int));
162*a194255dSDaniel Boulby #endif
163221b1638SMasahiro Yamada #ifdef MAKECRCH
164*a194255dSDaniel Boulby    local void write_table OF((FILE *, const z_crc_t FAR *, int));
165*a194255dSDaniel Boulby    local void write_table32hi OF((FILE *, const z_word_t FAR *, int));
166*a194255dSDaniel Boulby    local void write_table64 OF((FILE *, const z_word_t FAR *, int));
167221b1638SMasahiro Yamada #endif /* MAKECRCH */
168*a194255dSDaniel Boulby 
169*a194255dSDaniel Boulby /*
170*a194255dSDaniel Boulby   Define a once() function depending on the availability of atomics. If this is
171*a194255dSDaniel Boulby   compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in
172*a194255dSDaniel Boulby   multiple threads, and if atomics are not available, then get_crc_table() must
173*a194255dSDaniel Boulby   be called to initialize the tables and must return before any threads are
174*a194255dSDaniel Boulby   allowed to compute or combine CRCs.
175*a194255dSDaniel Boulby  */
176*a194255dSDaniel Boulby 
177*a194255dSDaniel Boulby /* Definition of once functionality. */
178*a194255dSDaniel Boulby typedef struct once_s once_t;
179*a194255dSDaniel Boulby local void once OF((once_t *, void (*)(void)));
180*a194255dSDaniel Boulby 
181*a194255dSDaniel Boulby /* Check for the availability of atomics. */
182*a194255dSDaniel Boulby #if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \
183*a194255dSDaniel Boulby     !defined(__STDC_NO_ATOMICS__)
184*a194255dSDaniel Boulby 
185*a194255dSDaniel Boulby #include <stdatomic.h>
186*a194255dSDaniel Boulby 
187*a194255dSDaniel Boulby /* Structure for once(), which must be initialized with ONCE_INIT. */
188*a194255dSDaniel Boulby struct once_s {
189*a194255dSDaniel Boulby     atomic_flag begun;
190*a194255dSDaniel Boulby     atomic_int done;
191*a194255dSDaniel Boulby };
192*a194255dSDaniel Boulby #define ONCE_INIT {ATOMIC_FLAG_INIT, 0}
193*a194255dSDaniel Boulby 
194*a194255dSDaniel Boulby /*
195*a194255dSDaniel Boulby   Run the provided init() function exactly once, even if multiple threads
196*a194255dSDaniel Boulby   invoke once() at the same time. The state must be a once_t initialized with
197*a194255dSDaniel Boulby   ONCE_INIT.
198*a194255dSDaniel Boulby  */
199*a194255dSDaniel Boulby local void once(state, init)
200*a194255dSDaniel Boulby     once_t *state;
201*a194255dSDaniel Boulby     void (*init)(void);
202*a194255dSDaniel Boulby {
203*a194255dSDaniel Boulby     if (!atomic_load(&state->done)) {
204*a194255dSDaniel Boulby         if (atomic_flag_test_and_set(&state->begun))
205*a194255dSDaniel Boulby             while (!atomic_load(&state->done))
206*a194255dSDaniel Boulby                 ;
207*a194255dSDaniel Boulby         else {
208*a194255dSDaniel Boulby             init();
209*a194255dSDaniel Boulby             atomic_store(&state->done, 1);
210*a194255dSDaniel Boulby         }
211*a194255dSDaniel Boulby     }
212*a194255dSDaniel Boulby }
213*a194255dSDaniel Boulby 
214*a194255dSDaniel Boulby #else   /* no atomics */
215*a194255dSDaniel Boulby 
216*a194255dSDaniel Boulby /* Structure for once(), which must be initialized with ONCE_INIT. */
217*a194255dSDaniel Boulby struct once_s {
218*a194255dSDaniel Boulby     volatile int begun;
219*a194255dSDaniel Boulby     volatile int done;
220*a194255dSDaniel Boulby };
221*a194255dSDaniel Boulby #define ONCE_INIT {0, 0}
222*a194255dSDaniel Boulby 
223*a194255dSDaniel Boulby /* Test and set. Alas, not atomic, but tries to minimize the period of
224*a194255dSDaniel Boulby    vulnerability. */
225*a194255dSDaniel Boulby local int test_and_set OF((int volatile *));
226*a194255dSDaniel Boulby local int test_and_set(flag)
227*a194255dSDaniel Boulby     int volatile *flag;
228*a194255dSDaniel Boulby {
229*a194255dSDaniel Boulby     int was;
230*a194255dSDaniel Boulby 
231*a194255dSDaniel Boulby     was = *flag;
232*a194255dSDaniel Boulby     *flag = 1;
233*a194255dSDaniel Boulby     return was;
234*a194255dSDaniel Boulby }
235*a194255dSDaniel Boulby 
236*a194255dSDaniel Boulby /* Run the provided init() function once. This is not thread-safe. */
237*a194255dSDaniel Boulby local void once(state, init)
238*a194255dSDaniel Boulby     once_t *state;
239*a194255dSDaniel Boulby     void (*init)(void);
240*a194255dSDaniel Boulby {
241*a194255dSDaniel Boulby     if (!state->done) {
242*a194255dSDaniel Boulby         if (test_and_set(&state->begun))
243*a194255dSDaniel Boulby             while (!state->done)
244*a194255dSDaniel Boulby                 ;
245*a194255dSDaniel Boulby         else {
246*a194255dSDaniel Boulby             init();
247*a194255dSDaniel Boulby             state->done = 1;
248*a194255dSDaniel Boulby         }
249*a194255dSDaniel Boulby     }
250*a194255dSDaniel Boulby }
251*a194255dSDaniel Boulby 
252*a194255dSDaniel Boulby #endif
253*a194255dSDaniel Boulby 
254*a194255dSDaniel Boulby /* State for once(). */
255*a194255dSDaniel Boulby local once_t made = ONCE_INIT;
256*a194255dSDaniel Boulby 
257221b1638SMasahiro Yamada /*
258221b1638SMasahiro Yamada   Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
259221b1638SMasahiro Yamada   x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
260221b1638SMasahiro Yamada 
261221b1638SMasahiro Yamada   Polynomials over GF(2) are represented in binary, one bit per coefficient,
262221b1638SMasahiro Yamada   with the lowest powers in the most significant bit. Then adding polynomials
263221b1638SMasahiro Yamada   is just exclusive-or, and multiplying a polynomial by x is a right shift by
264221b1638SMasahiro Yamada   one. If we call the above polynomial p, and represent a byte as the
265221b1638SMasahiro Yamada   polynomial q, also with the lowest power in the most significant bit (so the
266*a194255dSDaniel Boulby   byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p,
267221b1638SMasahiro Yamada   where a mod b means the remainder after dividing a by b.
268221b1638SMasahiro Yamada 
269221b1638SMasahiro Yamada   This calculation is done using the shift-register method of multiplying and
270221b1638SMasahiro Yamada   taking the remainder. The register is initialized to zero, and for each
271221b1638SMasahiro Yamada   incoming bit, x^32 is added mod p to the register if the bit is a one (where
272*a194255dSDaniel Boulby   x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x
273*a194255dSDaniel Boulby   (which is shifting right by one and adding x^32 mod p if the bit shifted out
274*a194255dSDaniel Boulby   is a one). We start with the highest power (least significant bit) of q and
275*a194255dSDaniel Boulby   repeat for all eight bits of q.
276221b1638SMasahiro Yamada 
277*a194255dSDaniel Boulby   The table is simply the CRC of all possible eight bit values. This is all the
278*a194255dSDaniel Boulby   information needed to generate CRCs on data a byte at a time for all
279*a194255dSDaniel Boulby   combinations of CRC register values and incoming bytes.
280221b1638SMasahiro Yamada  */
281*a194255dSDaniel Boulby 
282221b1638SMasahiro Yamada local void make_crc_table()
283221b1638SMasahiro Yamada {
284*a194255dSDaniel Boulby     unsigned i, j, n;
285*a194255dSDaniel Boulby     z_crc_t p;
286221b1638SMasahiro Yamada 
287*a194255dSDaniel Boulby     /* initialize the CRC of bytes tables */
288*a194255dSDaniel Boulby     for (i = 0; i < 256; i++) {
289*a194255dSDaniel Boulby         p = i;
290*a194255dSDaniel Boulby         for (j = 0; j < 8; j++)
291*a194255dSDaniel Boulby             p = p & 1 ? (p >> 1) ^ POLY : p >> 1;
292*a194255dSDaniel Boulby         crc_table[i] = p;
293*a194255dSDaniel Boulby #ifdef W
294*a194255dSDaniel Boulby         crc_big_table[i] = byte_swap(p);
295*a194255dSDaniel Boulby #endif
296221b1638SMasahiro Yamada     }
297221b1638SMasahiro Yamada 
298*a194255dSDaniel Boulby     /* initialize the x^2^n mod p(x) table */
299*a194255dSDaniel Boulby     p = (z_crc_t)1 << 30;         /* x^1 */
300*a194255dSDaniel Boulby     x2n_table[0] = p;
301*a194255dSDaniel Boulby     for (n = 1; n < 32; n++)
302*a194255dSDaniel Boulby         x2n_table[n] = p = multmodp(p, p);
303221b1638SMasahiro Yamada 
304*a194255dSDaniel Boulby #ifdef W
305*a194255dSDaniel Boulby     /* initialize the braiding tables -- needs x2n_table[] */
306*a194255dSDaniel Boulby     braid(crc_braid_table, crc_braid_big_table, N, W);
307*a194255dSDaniel Boulby #endif
308221b1638SMasahiro Yamada 
309221b1638SMasahiro Yamada #ifdef MAKECRCH
310221b1638SMasahiro Yamada     {
311*a194255dSDaniel Boulby         /*
312*a194255dSDaniel Boulby           The crc32.h header file contains tables for both 32-bit and 64-bit
313*a194255dSDaniel Boulby           z_word_t's, and so requires a 64-bit type be available. In that case,
314*a194255dSDaniel Boulby           z_word_t must be defined to be 64-bits. This code then also generates
315*a194255dSDaniel Boulby           and writes out the tables for the case that z_word_t is 32 bits.
316*a194255dSDaniel Boulby          */
317*a194255dSDaniel Boulby #if !defined(W) || W != 8
318*a194255dSDaniel Boulby #  error Need a 64-bit integer type in order to generate crc32.h.
319*a194255dSDaniel Boulby #endif
320221b1638SMasahiro Yamada         FILE *out;
321*a194255dSDaniel Boulby         int k, n;
322*a194255dSDaniel Boulby         z_crc_t ltl[8][256];
323*a194255dSDaniel Boulby         z_word_t big[8][256];
324221b1638SMasahiro Yamada 
325221b1638SMasahiro Yamada         out = fopen("crc32.h", "w");
326221b1638SMasahiro Yamada         if (out == NULL) return;
327*a194255dSDaniel Boulby 
328*a194255dSDaniel Boulby         /* write out little-endian CRC table to crc32.h */
329*a194255dSDaniel Boulby         fprintf(out,
330*a194255dSDaniel Boulby             "/* crc32.h -- tables for rapid CRC calculation\n"
331*a194255dSDaniel Boulby             " * Generated automatically by crc32.c\n */\n"
332*a194255dSDaniel Boulby             "\n"
333*a194255dSDaniel Boulby             "local const z_crc_t FAR crc_table[] = {\n"
334*a194255dSDaniel Boulby             "    ");
335*a194255dSDaniel Boulby         write_table(out, crc_table, 256);
336*a194255dSDaniel Boulby         fprintf(out,
337*a194255dSDaniel Boulby             "};\n");
338*a194255dSDaniel Boulby 
339*a194255dSDaniel Boulby         /* write out big-endian CRC table for 64-bit z_word_t to crc32.h */
340*a194255dSDaniel Boulby         fprintf(out,
341*a194255dSDaniel Boulby             "\n"
342*a194255dSDaniel Boulby             "#ifdef W\n"
343*a194255dSDaniel Boulby             "\n"
344*a194255dSDaniel Boulby             "#if W == 8\n"
345*a194255dSDaniel Boulby             "\n"
346*a194255dSDaniel Boulby             "local const z_word_t FAR crc_big_table[] = {\n"
347*a194255dSDaniel Boulby             "    ");
348*a194255dSDaniel Boulby         write_table64(out, crc_big_table, 256);
349*a194255dSDaniel Boulby         fprintf(out,
350*a194255dSDaniel Boulby             "};\n");
351*a194255dSDaniel Boulby 
352*a194255dSDaniel Boulby         /* write out big-endian CRC table for 32-bit z_word_t to crc32.h */
353*a194255dSDaniel Boulby         fprintf(out,
354*a194255dSDaniel Boulby             "\n"
355*a194255dSDaniel Boulby             "#else /* W == 4 */\n"
356*a194255dSDaniel Boulby             "\n"
357*a194255dSDaniel Boulby             "local const z_word_t FAR crc_big_table[] = {\n"
358*a194255dSDaniel Boulby             "    ");
359*a194255dSDaniel Boulby         write_table32hi(out, crc_big_table, 256);
360*a194255dSDaniel Boulby         fprintf(out,
361*a194255dSDaniel Boulby             "};\n"
362*a194255dSDaniel Boulby             "\n"
363*a194255dSDaniel Boulby             "#endif\n");
364*a194255dSDaniel Boulby 
365*a194255dSDaniel Boulby         /* write out braid tables for each value of N */
366*a194255dSDaniel Boulby         for (n = 1; n <= 6; n++) {
367*a194255dSDaniel Boulby             fprintf(out,
368*a194255dSDaniel Boulby             "\n"
369*a194255dSDaniel Boulby             "#if N == %d\n", n);
370*a194255dSDaniel Boulby 
371*a194255dSDaniel Boulby             /* compute braid tables for this N and 64-bit word_t */
372*a194255dSDaniel Boulby             braid(ltl, big, n, 8);
373*a194255dSDaniel Boulby 
374*a194255dSDaniel Boulby             /* write out braid tables for 64-bit z_word_t to crc32.h */
375*a194255dSDaniel Boulby             fprintf(out,
376*a194255dSDaniel Boulby             "\n"
377*a194255dSDaniel Boulby             "#if W == 8\n"
378*a194255dSDaniel Boulby             "\n"
379*a194255dSDaniel Boulby             "local const z_crc_t FAR crc_braid_table[][256] = {\n");
380*a194255dSDaniel Boulby             for (k = 0; k < 8; k++) {
381*a194255dSDaniel Boulby                 fprintf(out, "   {");
382*a194255dSDaniel Boulby                 write_table(out, ltl[k], 256);
383*a194255dSDaniel Boulby                 fprintf(out, "}%s", k < 7 ? ",\n" : "");
384221b1638SMasahiro Yamada             }
385*a194255dSDaniel Boulby             fprintf(out,
386*a194255dSDaniel Boulby             "};\n"
387*a194255dSDaniel Boulby             "\n"
388*a194255dSDaniel Boulby             "local const z_word_t FAR crc_braid_big_table[][256] = {\n");
389*a194255dSDaniel Boulby             for (k = 0; k < 8; k++) {
390*a194255dSDaniel Boulby                 fprintf(out, "   {");
391*a194255dSDaniel Boulby                 write_table64(out, big[k], 256);
392*a194255dSDaniel Boulby                 fprintf(out, "}%s", k < 7 ? ",\n" : "");
393*a194255dSDaniel Boulby             }
394*a194255dSDaniel Boulby             fprintf(out,
395*a194255dSDaniel Boulby             "};\n");
396*a194255dSDaniel Boulby 
397*a194255dSDaniel Boulby             /* compute braid tables for this N and 32-bit word_t */
398*a194255dSDaniel Boulby             braid(ltl, big, n, 4);
399*a194255dSDaniel Boulby 
400*a194255dSDaniel Boulby             /* write out braid tables for 32-bit z_word_t to crc32.h */
401*a194255dSDaniel Boulby             fprintf(out,
402*a194255dSDaniel Boulby             "\n"
403*a194255dSDaniel Boulby             "#else /* W == 4 */\n"
404*a194255dSDaniel Boulby             "\n"
405*a194255dSDaniel Boulby             "local const z_crc_t FAR crc_braid_table[][256] = {\n");
406*a194255dSDaniel Boulby             for (k = 0; k < 4; k++) {
407*a194255dSDaniel Boulby                 fprintf(out, "   {");
408*a194255dSDaniel Boulby                 write_table(out, ltl[k], 256);
409*a194255dSDaniel Boulby                 fprintf(out, "}%s", k < 3 ? ",\n" : "");
410*a194255dSDaniel Boulby             }
411*a194255dSDaniel Boulby             fprintf(out,
412*a194255dSDaniel Boulby             "};\n"
413*a194255dSDaniel Boulby             "\n"
414*a194255dSDaniel Boulby             "local const z_word_t FAR crc_braid_big_table[][256] = {\n");
415*a194255dSDaniel Boulby             for (k = 0; k < 4; k++) {
416*a194255dSDaniel Boulby                 fprintf(out, "   {");
417*a194255dSDaniel Boulby                 write_table32hi(out, big[k], 256);
418*a194255dSDaniel Boulby                 fprintf(out, "}%s", k < 3 ? ",\n" : "");
419*a194255dSDaniel Boulby             }
420*a194255dSDaniel Boulby             fprintf(out,
421*a194255dSDaniel Boulby             "};\n"
422*a194255dSDaniel Boulby             "\n"
423*a194255dSDaniel Boulby             "#endif\n"
424*a194255dSDaniel Boulby             "\n"
425*a194255dSDaniel Boulby             "#endif\n");
426*a194255dSDaniel Boulby         }
427*a194255dSDaniel Boulby         fprintf(out,
428*a194255dSDaniel Boulby             "\n"
429*a194255dSDaniel Boulby             "#endif\n");
430*a194255dSDaniel Boulby 
431*a194255dSDaniel Boulby         /* write out zeros operator table to crc32.h */
432*a194255dSDaniel Boulby         fprintf(out,
433*a194255dSDaniel Boulby             "\n"
434*a194255dSDaniel Boulby             "local const z_crc_t FAR x2n_table[] = {\n"
435*a194255dSDaniel Boulby             "    ");
436*a194255dSDaniel Boulby         write_table(out, x2n_table, 32);
437*a194255dSDaniel Boulby         fprintf(out,
438*a194255dSDaniel Boulby             "};\n");
439221b1638SMasahiro Yamada         fclose(out);
440221b1638SMasahiro Yamada     }
441221b1638SMasahiro Yamada #endif /* MAKECRCH */
442221b1638SMasahiro Yamada }
443221b1638SMasahiro Yamada 
444221b1638SMasahiro Yamada #ifdef MAKECRCH
445*a194255dSDaniel Boulby 
446*a194255dSDaniel Boulby /*
447*a194255dSDaniel Boulby    Write the 32-bit values in table[0..k-1] to out, five per line in
448*a194255dSDaniel Boulby    hexadecimal separated by commas.
449*a194255dSDaniel Boulby  */
450*a194255dSDaniel Boulby local void write_table(out, table, k)
451221b1638SMasahiro Yamada     FILE *out;
452221b1638SMasahiro Yamada     const z_crc_t FAR *table;
453*a194255dSDaniel Boulby     int k;
454221b1638SMasahiro Yamada {
455221b1638SMasahiro Yamada     int n;
456221b1638SMasahiro Yamada 
457*a194255dSDaniel Boulby     for (n = 0; n < k; n++)
458*a194255dSDaniel Boulby         fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : "    ",
459221b1638SMasahiro Yamada                 (unsigned long)(table[n]),
460*a194255dSDaniel Boulby                 n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", "));
461221b1638SMasahiro Yamada }
462*a194255dSDaniel Boulby 
463*a194255dSDaniel Boulby /*
464*a194255dSDaniel Boulby    Write the high 32-bits of each value in table[0..k-1] to out, five per line
465*a194255dSDaniel Boulby    in hexadecimal separated by commas.
466*a194255dSDaniel Boulby  */
467*a194255dSDaniel Boulby local void write_table32hi(out, table, k)
468*a194255dSDaniel Boulby FILE *out;
469*a194255dSDaniel Boulby const z_word_t FAR *table;
470*a194255dSDaniel Boulby int k;
471*a194255dSDaniel Boulby {
472*a194255dSDaniel Boulby     int n;
473*a194255dSDaniel Boulby 
474*a194255dSDaniel Boulby     for (n = 0; n < k; n++)
475*a194255dSDaniel Boulby         fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : "    ",
476*a194255dSDaniel Boulby                 (unsigned long)(table[n] >> 32),
477*a194255dSDaniel Boulby                 n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", "));
478*a194255dSDaniel Boulby }
479*a194255dSDaniel Boulby 
480*a194255dSDaniel Boulby /*
481*a194255dSDaniel Boulby   Write the 64-bit values in table[0..k-1] to out, three per line in
482*a194255dSDaniel Boulby   hexadecimal separated by commas. This assumes that if there is a 64-bit
483*a194255dSDaniel Boulby   type, then there is also a long long integer type, and it is at least 64
484*a194255dSDaniel Boulby   bits. If not, then the type cast and format string can be adjusted
485*a194255dSDaniel Boulby   accordingly.
486*a194255dSDaniel Boulby  */
487*a194255dSDaniel Boulby local void write_table64(out, table, k)
488*a194255dSDaniel Boulby     FILE *out;
489*a194255dSDaniel Boulby     const z_word_t FAR *table;
490*a194255dSDaniel Boulby     int k;
491*a194255dSDaniel Boulby {
492*a194255dSDaniel Boulby     int n;
493*a194255dSDaniel Boulby 
494*a194255dSDaniel Boulby     for (n = 0; n < k; n++)
495*a194255dSDaniel Boulby         fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : "    ",
496*a194255dSDaniel Boulby                 (unsigned long long)(table[n]),
497*a194255dSDaniel Boulby                 n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", "));
498*a194255dSDaniel Boulby }
499*a194255dSDaniel Boulby 
500*a194255dSDaniel Boulby /* Actually do the deed. */
501*a194255dSDaniel Boulby int main()
502*a194255dSDaniel Boulby {
503*a194255dSDaniel Boulby     make_crc_table();
504*a194255dSDaniel Boulby     return 0;
505*a194255dSDaniel Boulby }
506*a194255dSDaniel Boulby 
507221b1638SMasahiro Yamada #endif /* MAKECRCH */
508221b1638SMasahiro Yamada 
509*a194255dSDaniel Boulby #ifdef W
510*a194255dSDaniel Boulby /*
511*a194255dSDaniel Boulby   Generate the little and big-endian braid tables for the given n and z_word_t
512*a194255dSDaniel Boulby   size w. Each array must have room for w blocks of 256 elements.
513*a194255dSDaniel Boulby  */
514*a194255dSDaniel Boulby local void braid(ltl, big, n, w)
515*a194255dSDaniel Boulby     z_crc_t ltl[][256];
516*a194255dSDaniel Boulby     z_word_t big[][256];
517*a194255dSDaniel Boulby     int n;
518*a194255dSDaniel Boulby     int w;
519*a194255dSDaniel Boulby {
520*a194255dSDaniel Boulby     int k;
521*a194255dSDaniel Boulby     z_crc_t i, p, q;
522*a194255dSDaniel Boulby     for (k = 0; k < w; k++) {
523*a194255dSDaniel Boulby         p = x2nmodp((n * w + 3 - k) << 3, 0);
524*a194255dSDaniel Boulby         ltl[k][0] = 0;
525*a194255dSDaniel Boulby         big[w - 1 - k][0] = 0;
526*a194255dSDaniel Boulby         for (i = 1; i < 256; i++) {
527*a194255dSDaniel Boulby             ltl[k][i] = q = multmodp(i << 24, p);
528*a194255dSDaniel Boulby             big[w - 1 - k][i] = byte_swap(q);
529*a194255dSDaniel Boulby         }
530*a194255dSDaniel Boulby     }
531*a194255dSDaniel Boulby }
532*a194255dSDaniel Boulby #endif
533*a194255dSDaniel Boulby 
534221b1638SMasahiro Yamada #else /* !DYNAMIC_CRC_TABLE */
535221b1638SMasahiro Yamada /* ========================================================================
536*a194255dSDaniel Boulby  * Tables for byte-wise and braided CRC-32 calculations, and a table of powers
537*a194255dSDaniel Boulby  * of x for combining CRC-32s, all made by make_crc_table().
538221b1638SMasahiro Yamada  */
539221b1638SMasahiro Yamada #include "crc32.h"
540221b1638SMasahiro Yamada #endif /* DYNAMIC_CRC_TABLE */
541221b1638SMasahiro Yamada 
542*a194255dSDaniel Boulby /* ========================================================================
543*a194255dSDaniel Boulby  * Routines used for CRC calculation. Some are also required for the table
544*a194255dSDaniel Boulby  * generation above.
545*a194255dSDaniel Boulby  */
546*a194255dSDaniel Boulby 
547*a194255dSDaniel Boulby /*
548*a194255dSDaniel Boulby   Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,
549*a194255dSDaniel Boulby   reflected. For speed, this requires that a not be zero.
550*a194255dSDaniel Boulby  */
551*a194255dSDaniel Boulby local z_crc_t multmodp(a, b)
552*a194255dSDaniel Boulby     z_crc_t a;
553*a194255dSDaniel Boulby     z_crc_t b;
554*a194255dSDaniel Boulby {
555*a194255dSDaniel Boulby     z_crc_t m, p;
556*a194255dSDaniel Boulby 
557*a194255dSDaniel Boulby     m = (z_crc_t)1 << 31;
558*a194255dSDaniel Boulby     p = 0;
559*a194255dSDaniel Boulby     for (;;) {
560*a194255dSDaniel Boulby         if (a & m) {
561*a194255dSDaniel Boulby             p ^= b;
562*a194255dSDaniel Boulby             if ((a & (m - 1)) == 0)
563*a194255dSDaniel Boulby                 break;
564*a194255dSDaniel Boulby         }
565*a194255dSDaniel Boulby         m >>= 1;
566*a194255dSDaniel Boulby         b = b & 1 ? (b >> 1) ^ POLY : b >> 1;
567*a194255dSDaniel Boulby     }
568*a194255dSDaniel Boulby     return p;
569*a194255dSDaniel Boulby }
570*a194255dSDaniel Boulby 
571*a194255dSDaniel Boulby /*
572*a194255dSDaniel Boulby   Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been
573*a194255dSDaniel Boulby   initialized.
574*a194255dSDaniel Boulby  */
575*a194255dSDaniel Boulby local z_crc_t x2nmodp(n, k)
576*a194255dSDaniel Boulby     z_off64_t n;
577*a194255dSDaniel Boulby     unsigned k;
578*a194255dSDaniel Boulby {
579*a194255dSDaniel Boulby     z_crc_t p;
580*a194255dSDaniel Boulby 
581*a194255dSDaniel Boulby     p = (z_crc_t)1 << 31;           /* x^0 == 1 */
582*a194255dSDaniel Boulby     while (n) {
583*a194255dSDaniel Boulby         if (n & 1)
584*a194255dSDaniel Boulby             p = multmodp(x2n_table[k & 31], p);
585*a194255dSDaniel Boulby         n >>= 1;
586*a194255dSDaniel Boulby         k++;
587*a194255dSDaniel Boulby     }
588*a194255dSDaniel Boulby     return p;
589*a194255dSDaniel Boulby }
590*a194255dSDaniel Boulby 
591221b1638SMasahiro Yamada /* =========================================================================
592*a194255dSDaniel Boulby  * This function can be used by asm versions of crc32(), and to force the
593*a194255dSDaniel Boulby  * generation of the CRC tables in a threaded application.
594221b1638SMasahiro Yamada  */
595221b1638SMasahiro Yamada const z_crc_t FAR * ZEXPORT get_crc_table()
596221b1638SMasahiro Yamada {
597221b1638SMasahiro Yamada #ifdef DYNAMIC_CRC_TABLE
598*a194255dSDaniel Boulby     once(&made, make_crc_table);
599221b1638SMasahiro Yamada #endif /* DYNAMIC_CRC_TABLE */
600221b1638SMasahiro Yamada     return (const z_crc_t FAR *)crc_table;
601221b1638SMasahiro Yamada }
602221b1638SMasahiro Yamada 
603*a194255dSDaniel Boulby /* =========================================================================
604*a194255dSDaniel Boulby  * Use ARM machine instructions if available. This will compute the CRC about
605*a194255dSDaniel Boulby  * ten times faster than the braided calculation. This code does not check for
606*a194255dSDaniel Boulby  * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will
607*a194255dSDaniel Boulby  * only be defined if the compilation specifies an ARM processor architecture
608*a194255dSDaniel Boulby  * that has the instructions. For example, compiling with -march=armv8.1-a or
609*a194255dSDaniel Boulby  * -march=armv8-a+crc, or -march=native if the compile machine has the crc32
610*a194255dSDaniel Boulby  * instructions.
611*a194255dSDaniel Boulby  */
612*a194255dSDaniel Boulby #ifdef ARMCRC32
613*a194255dSDaniel Boulby 
614*a194255dSDaniel Boulby /*
615*a194255dSDaniel Boulby    Constants empirically determined to maximize speed. These values are from
616*a194255dSDaniel Boulby    measurements on a Cortex-A57. Your mileage may vary.
617*a194255dSDaniel Boulby  */
618*a194255dSDaniel Boulby #define Z_BATCH 3990                /* number of words in a batch */
619*a194255dSDaniel Boulby #define Z_BATCH_ZEROS 0xa10d3d0c    /* computed from Z_BATCH = 3990 */
620*a194255dSDaniel Boulby #define Z_BATCH_MIN 800             /* fewest words in a final batch */
621*a194255dSDaniel Boulby 
622*a194255dSDaniel Boulby unsigned long ZEXPORT crc32_z(crc, buf, len)
623*a194255dSDaniel Boulby     unsigned long crc;
624*a194255dSDaniel Boulby     const unsigned char FAR *buf;
625*a194255dSDaniel Boulby     z_size_t len;
626*a194255dSDaniel Boulby {
627*a194255dSDaniel Boulby     z_crc_t val;
628*a194255dSDaniel Boulby     z_word_t crc1, crc2;
629*a194255dSDaniel Boulby     const z_word_t *word;
630*a194255dSDaniel Boulby     z_word_t val0, val1, val2;
631*a194255dSDaniel Boulby     z_size_t last, last2, i;
632*a194255dSDaniel Boulby     z_size_t num;
633*a194255dSDaniel Boulby 
634*a194255dSDaniel Boulby     /* Return initial CRC, if requested. */
635*a194255dSDaniel Boulby     if (buf == Z_NULL) return 0;
636*a194255dSDaniel Boulby 
637*a194255dSDaniel Boulby #ifdef DYNAMIC_CRC_TABLE
638*a194255dSDaniel Boulby     once(&made, make_crc_table);
639*a194255dSDaniel Boulby #endif /* DYNAMIC_CRC_TABLE */
640*a194255dSDaniel Boulby 
641*a194255dSDaniel Boulby     /* Pre-condition the CRC */
642*a194255dSDaniel Boulby     crc = (~crc) & 0xffffffff;
643*a194255dSDaniel Boulby 
644*a194255dSDaniel Boulby     /* Compute the CRC up to a word boundary. */
645*a194255dSDaniel Boulby     while (len && ((z_size_t)buf & 7) != 0) {
646*a194255dSDaniel Boulby         len--;
647*a194255dSDaniel Boulby         val = *buf++;
648*a194255dSDaniel Boulby         __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val));
649*a194255dSDaniel Boulby     }
650*a194255dSDaniel Boulby 
651*a194255dSDaniel Boulby     /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */
652*a194255dSDaniel Boulby     word = (z_word_t const *)buf;
653*a194255dSDaniel Boulby     num = len >> 3;
654*a194255dSDaniel Boulby     len &= 7;
655*a194255dSDaniel Boulby 
656*a194255dSDaniel Boulby     /* Do three interleaved CRCs to realize the throughput of one crc32x
657*a194255dSDaniel Boulby        instruction per cycle. Each CRC is calculated on Z_BATCH words. The
658*a194255dSDaniel Boulby        three CRCs are combined into a single CRC after each set of batches. */
659*a194255dSDaniel Boulby     while (num >= 3 * Z_BATCH) {
660*a194255dSDaniel Boulby         crc1 = 0;
661*a194255dSDaniel Boulby         crc2 = 0;
662*a194255dSDaniel Boulby         for (i = 0; i < Z_BATCH; i++) {
663*a194255dSDaniel Boulby             val0 = word[i];
664*a194255dSDaniel Boulby             val1 = word[i + Z_BATCH];
665*a194255dSDaniel Boulby             val2 = word[i + 2 * Z_BATCH];
666*a194255dSDaniel Boulby             __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0));
667*a194255dSDaniel Boulby             __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1));
668*a194255dSDaniel Boulby             __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2));
669*a194255dSDaniel Boulby         }
670*a194255dSDaniel Boulby         word += 3 * Z_BATCH;
671*a194255dSDaniel Boulby         num -= 3 * Z_BATCH;
672*a194255dSDaniel Boulby         crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1;
673*a194255dSDaniel Boulby         crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2;
674*a194255dSDaniel Boulby     }
675*a194255dSDaniel Boulby 
676*a194255dSDaniel Boulby     /* Do one last smaller batch with the remaining words, if there are enough
677*a194255dSDaniel Boulby        to pay for the combination of CRCs. */
678*a194255dSDaniel Boulby     last = num / 3;
679*a194255dSDaniel Boulby     if (last >= Z_BATCH_MIN) {
680*a194255dSDaniel Boulby         last2 = last << 1;
681*a194255dSDaniel Boulby         crc1 = 0;
682*a194255dSDaniel Boulby         crc2 = 0;
683*a194255dSDaniel Boulby         for (i = 0; i < last; i++) {
684*a194255dSDaniel Boulby             val0 = word[i];
685*a194255dSDaniel Boulby             val1 = word[i + last];
686*a194255dSDaniel Boulby             val2 = word[i + last2];
687*a194255dSDaniel Boulby             __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0));
688*a194255dSDaniel Boulby             __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1));
689*a194255dSDaniel Boulby             __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2));
690*a194255dSDaniel Boulby         }
691*a194255dSDaniel Boulby         word += 3 * last;
692*a194255dSDaniel Boulby         num -= 3 * last;
693*a194255dSDaniel Boulby         val = x2nmodp(last, 6);
694*a194255dSDaniel Boulby         crc = multmodp(val, crc) ^ crc1;
695*a194255dSDaniel Boulby         crc = multmodp(val, crc) ^ crc2;
696*a194255dSDaniel Boulby     }
697*a194255dSDaniel Boulby 
698*a194255dSDaniel Boulby     /* Compute the CRC on any remaining words. */
699*a194255dSDaniel Boulby     for (i = 0; i < num; i++) {
700*a194255dSDaniel Boulby         val0 = word[i];
701*a194255dSDaniel Boulby         __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0));
702*a194255dSDaniel Boulby     }
703*a194255dSDaniel Boulby     word += num;
704*a194255dSDaniel Boulby 
705*a194255dSDaniel Boulby     /* Complete the CRC on any remaining bytes. */
706*a194255dSDaniel Boulby     buf = (const unsigned char FAR *)word;
707*a194255dSDaniel Boulby     while (len) {
708*a194255dSDaniel Boulby         len--;
709*a194255dSDaniel Boulby         val = *buf++;
710*a194255dSDaniel Boulby         __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val));
711*a194255dSDaniel Boulby     }
712*a194255dSDaniel Boulby 
713*a194255dSDaniel Boulby     /* Return the CRC, post-conditioned. */
714*a194255dSDaniel Boulby     return crc ^ 0xffffffff;
715*a194255dSDaniel Boulby }
716*a194255dSDaniel Boulby 
717*a194255dSDaniel Boulby #else
718*a194255dSDaniel Boulby 
719*a194255dSDaniel Boulby #ifdef W
720*a194255dSDaniel Boulby 
721*a194255dSDaniel Boulby /*
722*a194255dSDaniel Boulby   Return the CRC of the W bytes in the word_t data, taking the
723*a194255dSDaniel Boulby   least-significant byte of the word as the first byte of data, without any pre
724*a194255dSDaniel Boulby   or post conditioning. This is used to combine the CRCs of each braid.
725*a194255dSDaniel Boulby  */
726*a194255dSDaniel Boulby local z_crc_t crc_word(data)
727*a194255dSDaniel Boulby     z_word_t data;
728*a194255dSDaniel Boulby {
729*a194255dSDaniel Boulby     int k;
730*a194255dSDaniel Boulby     for (k = 0; k < W; k++)
731*a194255dSDaniel Boulby         data = (data >> 8) ^ crc_table[data & 0xff];
732*a194255dSDaniel Boulby     return (z_crc_t)data;
733*a194255dSDaniel Boulby }
734*a194255dSDaniel Boulby 
735*a194255dSDaniel Boulby local z_word_t crc_word_big(data)
736*a194255dSDaniel Boulby     z_word_t data;
737*a194255dSDaniel Boulby {
738*a194255dSDaniel Boulby     int k;
739*a194255dSDaniel Boulby     for (k = 0; k < W; k++)
740*a194255dSDaniel Boulby         data = (data << 8) ^
741*a194255dSDaniel Boulby             crc_big_table[(data >> ((W - 1) << 3)) & 0xff];
742*a194255dSDaniel Boulby     return data;
743*a194255dSDaniel Boulby }
744*a194255dSDaniel Boulby 
745*a194255dSDaniel Boulby #endif
746221b1638SMasahiro Yamada 
747221b1638SMasahiro Yamada /* ========================================================================= */
748221b1638SMasahiro Yamada unsigned long ZEXPORT crc32_z(crc, buf, len)
749221b1638SMasahiro Yamada     unsigned long crc;
750221b1638SMasahiro Yamada     const unsigned char FAR *buf;
751221b1638SMasahiro Yamada     z_size_t len;
752221b1638SMasahiro Yamada {
753*a194255dSDaniel Boulby     /* Return initial CRC, if requested. */
754*a194255dSDaniel Boulby     if (buf == Z_NULL) return 0;
755221b1638SMasahiro Yamada 
756221b1638SMasahiro Yamada #ifdef DYNAMIC_CRC_TABLE
757*a194255dSDaniel Boulby     once(&made, make_crc_table);
758221b1638SMasahiro Yamada #endif /* DYNAMIC_CRC_TABLE */
759221b1638SMasahiro Yamada 
760*a194255dSDaniel Boulby     /* Pre-condition the CRC */
761*a194255dSDaniel Boulby     crc = (~crc) & 0xffffffff;
762221b1638SMasahiro Yamada 
763*a194255dSDaniel Boulby #ifdef W
764*a194255dSDaniel Boulby 
765*a194255dSDaniel Boulby     /* If provided enough bytes, do a braided CRC calculation. */
766*a194255dSDaniel Boulby     if (len >= N * W + W - 1) {
767*a194255dSDaniel Boulby         z_size_t blks;
768*a194255dSDaniel Boulby         z_word_t const *words;
769*a194255dSDaniel Boulby         unsigned endian;
770*a194255dSDaniel Boulby         int k;
771*a194255dSDaniel Boulby 
772*a194255dSDaniel Boulby         /* Compute the CRC up to a z_word_t boundary. */
773*a194255dSDaniel Boulby         while (len && ((z_size_t)buf & (W - 1)) != 0) {
774*a194255dSDaniel Boulby             len--;
775*a194255dSDaniel Boulby             crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
776*a194255dSDaniel Boulby         }
777*a194255dSDaniel Boulby 
778*a194255dSDaniel Boulby         /* Compute the CRC on as many N z_word_t blocks as are available. */
779*a194255dSDaniel Boulby         blks = len / (N * W);
780*a194255dSDaniel Boulby         len -= blks * N * W;
781*a194255dSDaniel Boulby         words = (z_word_t const *)buf;
782*a194255dSDaniel Boulby 
783*a194255dSDaniel Boulby         /* Do endian check at execution time instead of compile time, since ARM
784*a194255dSDaniel Boulby            processors can change the endianess at execution time. If the
785*a194255dSDaniel Boulby            compiler knows what the endianess will be, it can optimize out the
786*a194255dSDaniel Boulby            check and the unused branch. */
787221b1638SMasahiro Yamada         endian = 1;
788*a194255dSDaniel Boulby         if (*(unsigned char *)&endian) {
789*a194255dSDaniel Boulby             /* Little endian. */
790*a194255dSDaniel Boulby 
791*a194255dSDaniel Boulby             z_crc_t crc0;
792*a194255dSDaniel Boulby             z_word_t word0;
793*a194255dSDaniel Boulby #if N > 1
794*a194255dSDaniel Boulby             z_crc_t crc1;
795*a194255dSDaniel Boulby             z_word_t word1;
796*a194255dSDaniel Boulby #if N > 2
797*a194255dSDaniel Boulby             z_crc_t crc2;
798*a194255dSDaniel Boulby             z_word_t word2;
799*a194255dSDaniel Boulby #if N > 3
800*a194255dSDaniel Boulby             z_crc_t crc3;
801*a194255dSDaniel Boulby             z_word_t word3;
802*a194255dSDaniel Boulby #if N > 4
803*a194255dSDaniel Boulby             z_crc_t crc4;
804*a194255dSDaniel Boulby             z_word_t word4;
805*a194255dSDaniel Boulby #if N > 5
806*a194255dSDaniel Boulby             z_crc_t crc5;
807*a194255dSDaniel Boulby             z_word_t word5;
808*a194255dSDaniel Boulby #endif
809*a194255dSDaniel Boulby #endif
810*a194255dSDaniel Boulby #endif
811*a194255dSDaniel Boulby #endif
812*a194255dSDaniel Boulby #endif
813*a194255dSDaniel Boulby 
814*a194255dSDaniel Boulby             /* Initialize the CRC for each braid. */
815*a194255dSDaniel Boulby             crc0 = crc;
816*a194255dSDaniel Boulby #if N > 1
817*a194255dSDaniel Boulby             crc1 = 0;
818*a194255dSDaniel Boulby #if N > 2
819*a194255dSDaniel Boulby             crc2 = 0;
820*a194255dSDaniel Boulby #if N > 3
821*a194255dSDaniel Boulby             crc3 = 0;
822*a194255dSDaniel Boulby #if N > 4
823*a194255dSDaniel Boulby             crc4 = 0;
824*a194255dSDaniel Boulby #if N > 5
825*a194255dSDaniel Boulby             crc5 = 0;
826*a194255dSDaniel Boulby #endif
827*a194255dSDaniel Boulby #endif
828*a194255dSDaniel Boulby #endif
829*a194255dSDaniel Boulby #endif
830*a194255dSDaniel Boulby #endif
831*a194255dSDaniel Boulby 
832*a194255dSDaniel Boulby             /*
833*a194255dSDaniel Boulby               Process the first blks-1 blocks, computing the CRCs on each braid
834*a194255dSDaniel Boulby               independently.
835*a194255dSDaniel Boulby              */
836*a194255dSDaniel Boulby             while (--blks) {
837*a194255dSDaniel Boulby                 /* Load the word for each braid into registers. */
838*a194255dSDaniel Boulby                 word0 = crc0 ^ words[0];
839*a194255dSDaniel Boulby #if N > 1
840*a194255dSDaniel Boulby                 word1 = crc1 ^ words[1];
841*a194255dSDaniel Boulby #if N > 2
842*a194255dSDaniel Boulby                 word2 = crc2 ^ words[2];
843*a194255dSDaniel Boulby #if N > 3
844*a194255dSDaniel Boulby                 word3 = crc3 ^ words[3];
845*a194255dSDaniel Boulby #if N > 4
846*a194255dSDaniel Boulby                 word4 = crc4 ^ words[4];
847*a194255dSDaniel Boulby #if N > 5
848*a194255dSDaniel Boulby                 word5 = crc5 ^ words[5];
849*a194255dSDaniel Boulby #endif
850*a194255dSDaniel Boulby #endif
851*a194255dSDaniel Boulby #endif
852*a194255dSDaniel Boulby #endif
853*a194255dSDaniel Boulby #endif
854*a194255dSDaniel Boulby                 words += N;
855*a194255dSDaniel Boulby 
856*a194255dSDaniel Boulby                 /* Compute and update the CRC for each word. The loop should
857*a194255dSDaniel Boulby                    get unrolled. */
858*a194255dSDaniel Boulby                 crc0 = crc_braid_table[0][word0 & 0xff];
859*a194255dSDaniel Boulby #if N > 1
860*a194255dSDaniel Boulby                 crc1 = crc_braid_table[0][word1 & 0xff];
861*a194255dSDaniel Boulby #if N > 2
862*a194255dSDaniel Boulby                 crc2 = crc_braid_table[0][word2 & 0xff];
863*a194255dSDaniel Boulby #if N > 3
864*a194255dSDaniel Boulby                 crc3 = crc_braid_table[0][word3 & 0xff];
865*a194255dSDaniel Boulby #if N > 4
866*a194255dSDaniel Boulby                 crc4 = crc_braid_table[0][word4 & 0xff];
867*a194255dSDaniel Boulby #if N > 5
868*a194255dSDaniel Boulby                 crc5 = crc_braid_table[0][word5 & 0xff];
869*a194255dSDaniel Boulby #endif
870*a194255dSDaniel Boulby #endif
871*a194255dSDaniel Boulby #endif
872*a194255dSDaniel Boulby #endif
873*a194255dSDaniel Boulby #endif
874*a194255dSDaniel Boulby                 for (k = 1; k < W; k++) {
875*a194255dSDaniel Boulby                     crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff];
876*a194255dSDaniel Boulby #if N > 1
877*a194255dSDaniel Boulby                     crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff];
878*a194255dSDaniel Boulby #if N > 2
879*a194255dSDaniel Boulby                     crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff];
880*a194255dSDaniel Boulby #if N > 3
881*a194255dSDaniel Boulby                     crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff];
882*a194255dSDaniel Boulby #if N > 4
883*a194255dSDaniel Boulby                     crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff];
884*a194255dSDaniel Boulby #if N > 5
885*a194255dSDaniel Boulby                     crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff];
886*a194255dSDaniel Boulby #endif
887*a194255dSDaniel Boulby #endif
888*a194255dSDaniel Boulby #endif
889*a194255dSDaniel Boulby #endif
890*a194255dSDaniel Boulby #endif
891221b1638SMasahiro Yamada                 }
892*a194255dSDaniel Boulby             }
893*a194255dSDaniel Boulby 
894*a194255dSDaniel Boulby             /*
895*a194255dSDaniel Boulby               Process the last block, combining the CRCs of the N braids at the
896*a194255dSDaniel Boulby               same time.
897*a194255dSDaniel Boulby              */
898*a194255dSDaniel Boulby             crc = crc_word(crc0 ^ words[0]);
899*a194255dSDaniel Boulby #if N > 1
900*a194255dSDaniel Boulby             crc = crc_word(crc1 ^ words[1] ^ crc);
901*a194255dSDaniel Boulby #if N > 2
902*a194255dSDaniel Boulby             crc = crc_word(crc2 ^ words[2] ^ crc);
903*a194255dSDaniel Boulby #if N > 3
904*a194255dSDaniel Boulby             crc = crc_word(crc3 ^ words[3] ^ crc);
905*a194255dSDaniel Boulby #if N > 4
906*a194255dSDaniel Boulby             crc = crc_word(crc4 ^ words[4] ^ crc);
907*a194255dSDaniel Boulby #if N > 5
908*a194255dSDaniel Boulby             crc = crc_word(crc5 ^ words[5] ^ crc);
909*a194255dSDaniel Boulby #endif
910*a194255dSDaniel Boulby #endif
911*a194255dSDaniel Boulby #endif
912*a194255dSDaniel Boulby #endif
913*a194255dSDaniel Boulby #endif
914*a194255dSDaniel Boulby             words += N;
915*a194255dSDaniel Boulby         }
916*a194255dSDaniel Boulby         else {
917*a194255dSDaniel Boulby             /* Big endian. */
918*a194255dSDaniel Boulby 
919*a194255dSDaniel Boulby             z_word_t crc0, word0, comb;
920*a194255dSDaniel Boulby #if N > 1
921*a194255dSDaniel Boulby             z_word_t crc1, word1;
922*a194255dSDaniel Boulby #if N > 2
923*a194255dSDaniel Boulby             z_word_t crc2, word2;
924*a194255dSDaniel Boulby #if N > 3
925*a194255dSDaniel Boulby             z_word_t crc3, word3;
926*a194255dSDaniel Boulby #if N > 4
927*a194255dSDaniel Boulby             z_word_t crc4, word4;
928*a194255dSDaniel Boulby #if N > 5
929*a194255dSDaniel Boulby             z_word_t crc5, word5;
930*a194255dSDaniel Boulby #endif
931*a194255dSDaniel Boulby #endif
932*a194255dSDaniel Boulby #endif
933*a194255dSDaniel Boulby #endif
934*a194255dSDaniel Boulby #endif
935*a194255dSDaniel Boulby 
936*a194255dSDaniel Boulby             /* Initialize the CRC for each braid. */
937*a194255dSDaniel Boulby             crc0 = byte_swap(crc);
938*a194255dSDaniel Boulby #if N > 1
939*a194255dSDaniel Boulby             crc1 = 0;
940*a194255dSDaniel Boulby #if N > 2
941*a194255dSDaniel Boulby             crc2 = 0;
942*a194255dSDaniel Boulby #if N > 3
943*a194255dSDaniel Boulby             crc3 = 0;
944*a194255dSDaniel Boulby #if N > 4
945*a194255dSDaniel Boulby             crc4 = 0;
946*a194255dSDaniel Boulby #if N > 5
947*a194255dSDaniel Boulby             crc5 = 0;
948*a194255dSDaniel Boulby #endif
949*a194255dSDaniel Boulby #endif
950*a194255dSDaniel Boulby #endif
951*a194255dSDaniel Boulby #endif
952*a194255dSDaniel Boulby #endif
953*a194255dSDaniel Boulby 
954*a194255dSDaniel Boulby             /*
955*a194255dSDaniel Boulby               Process the first blks-1 blocks, computing the CRCs on each braid
956*a194255dSDaniel Boulby               independently.
957*a194255dSDaniel Boulby              */
958*a194255dSDaniel Boulby             while (--blks) {
959*a194255dSDaniel Boulby                 /* Load the word for each braid into registers. */
960*a194255dSDaniel Boulby                 word0 = crc0 ^ words[0];
961*a194255dSDaniel Boulby #if N > 1
962*a194255dSDaniel Boulby                 word1 = crc1 ^ words[1];
963*a194255dSDaniel Boulby #if N > 2
964*a194255dSDaniel Boulby                 word2 = crc2 ^ words[2];
965*a194255dSDaniel Boulby #if N > 3
966*a194255dSDaniel Boulby                 word3 = crc3 ^ words[3];
967*a194255dSDaniel Boulby #if N > 4
968*a194255dSDaniel Boulby                 word4 = crc4 ^ words[4];
969*a194255dSDaniel Boulby #if N > 5
970*a194255dSDaniel Boulby                 word5 = crc5 ^ words[5];
971*a194255dSDaniel Boulby #endif
972*a194255dSDaniel Boulby #endif
973*a194255dSDaniel Boulby #endif
974*a194255dSDaniel Boulby #endif
975*a194255dSDaniel Boulby #endif
976*a194255dSDaniel Boulby                 words += N;
977*a194255dSDaniel Boulby 
978*a194255dSDaniel Boulby                 /* Compute and update the CRC for each word. The loop should
979*a194255dSDaniel Boulby                    get unrolled. */
980*a194255dSDaniel Boulby                 crc0 = crc_braid_big_table[0][word0 & 0xff];
981*a194255dSDaniel Boulby #if N > 1
982*a194255dSDaniel Boulby                 crc1 = crc_braid_big_table[0][word1 & 0xff];
983*a194255dSDaniel Boulby #if N > 2
984*a194255dSDaniel Boulby                 crc2 = crc_braid_big_table[0][word2 & 0xff];
985*a194255dSDaniel Boulby #if N > 3
986*a194255dSDaniel Boulby                 crc3 = crc_braid_big_table[0][word3 & 0xff];
987*a194255dSDaniel Boulby #if N > 4
988*a194255dSDaniel Boulby                 crc4 = crc_braid_big_table[0][word4 & 0xff];
989*a194255dSDaniel Boulby #if N > 5
990*a194255dSDaniel Boulby                 crc5 = crc_braid_big_table[0][word5 & 0xff];
991*a194255dSDaniel Boulby #endif
992*a194255dSDaniel Boulby #endif
993*a194255dSDaniel Boulby #endif
994*a194255dSDaniel Boulby #endif
995*a194255dSDaniel Boulby #endif
996*a194255dSDaniel Boulby                 for (k = 1; k < W; k++) {
997*a194255dSDaniel Boulby                     crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff];
998*a194255dSDaniel Boulby #if N > 1
999*a194255dSDaniel Boulby                     crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff];
1000*a194255dSDaniel Boulby #if N > 2
1001*a194255dSDaniel Boulby                     crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff];
1002*a194255dSDaniel Boulby #if N > 3
1003*a194255dSDaniel Boulby                     crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff];
1004*a194255dSDaniel Boulby #if N > 4
1005*a194255dSDaniel Boulby                     crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff];
1006*a194255dSDaniel Boulby #if N > 5
1007*a194255dSDaniel Boulby                     crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff];
1008*a194255dSDaniel Boulby #endif
1009*a194255dSDaniel Boulby #endif
1010*a194255dSDaniel Boulby #endif
1011*a194255dSDaniel Boulby #endif
1012*a194255dSDaniel Boulby #endif
1013*a194255dSDaniel Boulby                 }
1014*a194255dSDaniel Boulby             }
1015*a194255dSDaniel Boulby 
1016*a194255dSDaniel Boulby             /*
1017*a194255dSDaniel Boulby               Process the last block, combining the CRCs of the N braids at the
1018*a194255dSDaniel Boulby               same time.
1019*a194255dSDaniel Boulby              */
1020*a194255dSDaniel Boulby             comb = crc_word_big(crc0 ^ words[0]);
1021*a194255dSDaniel Boulby #if N > 1
1022*a194255dSDaniel Boulby             comb = crc_word_big(crc1 ^ words[1] ^ comb);
1023*a194255dSDaniel Boulby #if N > 2
1024*a194255dSDaniel Boulby             comb = crc_word_big(crc2 ^ words[2] ^ comb);
1025*a194255dSDaniel Boulby #if N > 3
1026*a194255dSDaniel Boulby             comb = crc_word_big(crc3 ^ words[3] ^ comb);
1027*a194255dSDaniel Boulby #if N > 4
1028*a194255dSDaniel Boulby             comb = crc_word_big(crc4 ^ words[4] ^ comb);
1029*a194255dSDaniel Boulby #if N > 5
1030*a194255dSDaniel Boulby             comb = crc_word_big(crc5 ^ words[5] ^ comb);
1031*a194255dSDaniel Boulby #endif
1032*a194255dSDaniel Boulby #endif
1033*a194255dSDaniel Boulby #endif
1034*a194255dSDaniel Boulby #endif
1035*a194255dSDaniel Boulby #endif
1036*a194255dSDaniel Boulby             words += N;
1037*a194255dSDaniel Boulby             crc = byte_swap(comb);
1038*a194255dSDaniel Boulby         }
1039*a194255dSDaniel Boulby 
1040*a194255dSDaniel Boulby         /*
1041*a194255dSDaniel Boulby           Update the pointer to the remaining bytes to process.
1042*a194255dSDaniel Boulby          */
1043*a194255dSDaniel Boulby         buf = (unsigned char const *)words;
1044*a194255dSDaniel Boulby     }
1045*a194255dSDaniel Boulby 
1046*a194255dSDaniel Boulby #endif /* W */
1047*a194255dSDaniel Boulby 
1048*a194255dSDaniel Boulby     /* Complete the computation of the CRC on any remaining bytes. */
1049221b1638SMasahiro Yamada     while (len >= 8) {
1050221b1638SMasahiro Yamada         len -= 8;
1051*a194255dSDaniel Boulby         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1052*a194255dSDaniel Boulby         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1053*a194255dSDaniel Boulby         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1054*a194255dSDaniel Boulby         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1055*a194255dSDaniel Boulby         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1056*a194255dSDaniel Boulby         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1057*a194255dSDaniel Boulby         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1058*a194255dSDaniel Boulby         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1059221b1638SMasahiro Yamada     }
1060*a194255dSDaniel Boulby     while (len) {
1061*a194255dSDaniel Boulby         len--;
1062*a194255dSDaniel Boulby         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1063221b1638SMasahiro Yamada     }
1064221b1638SMasahiro Yamada 
1065*a194255dSDaniel Boulby     /* Return the CRC, post-conditioned. */
1066*a194255dSDaniel Boulby     return crc ^ 0xffffffff;
1067*a194255dSDaniel Boulby }
1068*a194255dSDaniel Boulby 
1069*a194255dSDaniel Boulby #endif
1070*a194255dSDaniel Boulby 
1071221b1638SMasahiro Yamada /* ========================================================================= */
1072221b1638SMasahiro Yamada unsigned long ZEXPORT crc32(crc, buf, len)
1073221b1638SMasahiro Yamada     unsigned long crc;
1074221b1638SMasahiro Yamada     const unsigned char FAR *buf;
1075221b1638SMasahiro Yamada     uInt len;
1076221b1638SMasahiro Yamada {
1077221b1638SMasahiro Yamada     return crc32_z(crc, buf, len);
1078221b1638SMasahiro Yamada }
1079221b1638SMasahiro Yamada 
1080221b1638SMasahiro Yamada /* ========================================================================= */
1081*a194255dSDaniel Boulby uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
1082221b1638SMasahiro Yamada     uLong crc1;
1083221b1638SMasahiro Yamada     uLong crc2;
1084221b1638SMasahiro Yamada     z_off64_t len2;
1085221b1638SMasahiro Yamada {
1086*a194255dSDaniel Boulby #ifdef DYNAMIC_CRC_TABLE
1087*a194255dSDaniel Boulby     once(&made, make_crc_table);
1088*a194255dSDaniel Boulby #endif /* DYNAMIC_CRC_TABLE */
1089*a194255dSDaniel Boulby     return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff);
1090221b1638SMasahiro Yamada }
1091221b1638SMasahiro Yamada 
1092221b1638SMasahiro Yamada /* ========================================================================= */
1093221b1638SMasahiro Yamada uLong ZEXPORT crc32_combine(crc1, crc2, len2)
1094221b1638SMasahiro Yamada     uLong crc1;
1095221b1638SMasahiro Yamada     uLong crc2;
1096221b1638SMasahiro Yamada     z_off_t len2;
1097221b1638SMasahiro Yamada {
1098*a194255dSDaniel Boulby     return crc32_combine64(crc1, crc2, (z_off64_t)len2);
1099221b1638SMasahiro Yamada }
1100221b1638SMasahiro Yamada 
1101*a194255dSDaniel Boulby /* ========================================================================= */
1102*a194255dSDaniel Boulby uLong ZEXPORT crc32_combine_gen64(len2)
1103221b1638SMasahiro Yamada     z_off64_t len2;
1104221b1638SMasahiro Yamada {
1105*a194255dSDaniel Boulby #ifdef DYNAMIC_CRC_TABLE
1106*a194255dSDaniel Boulby     once(&made, make_crc_table);
1107*a194255dSDaniel Boulby #endif /* DYNAMIC_CRC_TABLE */
1108*a194255dSDaniel Boulby     return x2nmodp(len2, 3);
1109*a194255dSDaniel Boulby }
1110*a194255dSDaniel Boulby 
1111*a194255dSDaniel Boulby /* ========================================================================= */
1112*a194255dSDaniel Boulby uLong ZEXPORT crc32_combine_gen(len2)
1113*a194255dSDaniel Boulby     z_off_t len2;
1114*a194255dSDaniel Boulby {
1115*a194255dSDaniel Boulby     return crc32_combine_gen64((z_off64_t)len2);
1116*a194255dSDaniel Boulby }
1117*a194255dSDaniel Boulby 
1118*a194255dSDaniel Boulby /* ========================================================================= */
1119*a194255dSDaniel Boulby uLong ZEXPORT crc32_combine_op(crc1, crc2, op)
1120*a194255dSDaniel Boulby     uLong crc1;
1121*a194255dSDaniel Boulby     uLong crc2;
1122*a194255dSDaniel Boulby     uLong op;
1123*a194255dSDaniel Boulby {
1124*a194255dSDaniel Boulby     return multmodp(op, crc1) ^ (crc2 & 0xffffffff);
1125221b1638SMasahiro Yamada }
1126