xref: /aosp_15_r20/external/zlib/crc32.c (revision 86ee64e75fa5f8bce2c8c356138035642429cd05)
1*86ee64e7SAndroid Build Coastguard Worker /* crc32.c -- compute the CRC-32 of a data stream
2*86ee64e7SAndroid Build Coastguard Worker  * Copyright (C) 1995-2022 Mark Adler
3*86ee64e7SAndroid Build Coastguard Worker  * For conditions of distribution and use, see copyright notice in zlib.h
4*86ee64e7SAndroid Build Coastguard Worker  *
5*86ee64e7SAndroid Build Coastguard Worker  * This interleaved implementation of a CRC makes use of pipelined multiple
6*86ee64e7SAndroid Build Coastguard Worker  * arithmetic-logic units, commonly found in modern CPU cores. It is due to
7*86ee64e7SAndroid Build Coastguard Worker  * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution.
8*86ee64e7SAndroid Build Coastguard Worker  */
9*86ee64e7SAndroid Build Coastguard Worker 
10*86ee64e7SAndroid Build Coastguard Worker /* @(#) $Id$ */
11*86ee64e7SAndroid Build Coastguard Worker 
12*86ee64e7SAndroid Build Coastguard Worker /*
13*86ee64e7SAndroid Build Coastguard Worker   Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
14*86ee64e7SAndroid Build Coastguard Worker   protection on the static variables used to control the first-use generation
15*86ee64e7SAndroid Build Coastguard Worker   of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
16*86ee64e7SAndroid Build Coastguard Worker   first call get_crc_table() to initialize the tables before allowing more than
17*86ee64e7SAndroid Build Coastguard Worker   one thread to use crc32().
18*86ee64e7SAndroid Build Coastguard Worker 
19*86ee64e7SAndroid Build Coastguard Worker   MAKECRCH can be #defined to write out crc32.h. A main() routine is also
20*86ee64e7SAndroid Build Coastguard Worker   produced, so that this one source file can be compiled to an executable.
21*86ee64e7SAndroid Build Coastguard Worker  */
22*86ee64e7SAndroid Build Coastguard Worker 
23*86ee64e7SAndroid Build Coastguard Worker #ifdef MAKECRCH
24*86ee64e7SAndroid Build Coastguard Worker #  include <stdio.h>
25*86ee64e7SAndroid Build Coastguard Worker #  ifndef DYNAMIC_CRC_TABLE
26*86ee64e7SAndroid Build Coastguard Worker #    define DYNAMIC_CRC_TABLE
27*86ee64e7SAndroid Build Coastguard Worker #  endif /* !DYNAMIC_CRC_TABLE */
28*86ee64e7SAndroid Build Coastguard Worker #endif /* MAKECRCH */
29*86ee64e7SAndroid Build Coastguard Worker 
30*86ee64e7SAndroid Build Coastguard Worker #include "deflate.h"
31*86ee64e7SAndroid Build Coastguard Worker #include "cpu_features.h"
32*86ee64e7SAndroid Build Coastguard Worker #include "zutil.h"      /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */
33*86ee64e7SAndroid Build Coastguard Worker 
34*86ee64e7SAndroid Build Coastguard Worker #if defined(CRC32_SIMD_SSE42_PCLMUL) || defined(CRC32_ARMV8_CRC32)
35*86ee64e7SAndroid Build Coastguard Worker #include "crc32_simd.h"
36*86ee64e7SAndroid Build Coastguard Worker #endif
37*86ee64e7SAndroid Build Coastguard Worker 
38*86ee64e7SAndroid Build Coastguard Worker  /*
39*86ee64e7SAndroid Build Coastguard Worker   A CRC of a message is computed on N braids of words in the message, where
40*86ee64e7SAndroid Build Coastguard Worker   each word consists of W bytes (4 or 8). If N is 3, for example, then three
41*86ee64e7SAndroid Build Coastguard Worker   running sparse CRCs are calculated respectively on each braid, at these
42*86ee64e7SAndroid Build Coastguard Worker   indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ...
43*86ee64e7SAndroid Build Coastguard Worker   This is done starting at a word boundary, and continues until as many blocks
44*86ee64e7SAndroid Build Coastguard Worker   of N * W bytes as are available have been processed. The results are combined
45*86ee64e7SAndroid Build Coastguard Worker   into a single CRC at the end. For this code, N must be in the range 1..6 and
46*86ee64e7SAndroid Build Coastguard Worker   W must be 4 or 8. The upper limit on N can be increased if desired by adding
47*86ee64e7SAndroid Build Coastguard Worker   more #if blocks, extending the patterns apparent in the code. In addition,
48*86ee64e7SAndroid Build Coastguard Worker   crc32.h would need to be regenerated, if the maximum N value is increased.
49*86ee64e7SAndroid Build Coastguard Worker 
50*86ee64e7SAndroid Build Coastguard Worker   N and W are chosen empirically by benchmarking the execution time on a given
51*86ee64e7SAndroid Build Coastguard Worker   processor. The choices for N and W below were based on testing on Intel Kaby
52*86ee64e7SAndroid Build Coastguard Worker   Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64
53*86ee64e7SAndroid Build Coastguard Worker   Octeon II processors. The Intel, AMD, and ARM processors were all fastest
54*86ee64e7SAndroid Build Coastguard Worker   with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4.
55*86ee64e7SAndroid Build Coastguard Worker   They were all tested with either gcc or clang, all using the -O3 optimization
56*86ee64e7SAndroid Build Coastguard Worker   level. Your mileage may vary.
57*86ee64e7SAndroid Build Coastguard Worker  */
58*86ee64e7SAndroid Build Coastguard Worker 
59*86ee64e7SAndroid Build Coastguard Worker /* Define N */
60*86ee64e7SAndroid Build Coastguard Worker #ifdef Z_TESTN
61*86ee64e7SAndroid Build Coastguard Worker #  define N Z_TESTN
62*86ee64e7SAndroid Build Coastguard Worker #else
63*86ee64e7SAndroid Build Coastguard Worker #  define N 5
64*86ee64e7SAndroid Build Coastguard Worker #endif
65*86ee64e7SAndroid Build Coastguard Worker #if N < 1 || N > 6
66*86ee64e7SAndroid Build Coastguard Worker #  error N must be in 1..6
67*86ee64e7SAndroid Build Coastguard Worker #endif
68*86ee64e7SAndroid Build Coastguard Worker 
69*86ee64e7SAndroid Build Coastguard Worker /*
70*86ee64e7SAndroid Build Coastguard Worker   z_crc_t must be at least 32 bits. z_word_t must be at least as long as
71*86ee64e7SAndroid Build Coastguard Worker   z_crc_t. It is assumed here that z_word_t is either 32 bits or 64 bits, and
72*86ee64e7SAndroid Build Coastguard Worker   that bytes are eight bits.
73*86ee64e7SAndroid Build Coastguard Worker  */
74*86ee64e7SAndroid Build Coastguard Worker 
75*86ee64e7SAndroid Build Coastguard Worker /*
76*86ee64e7SAndroid Build Coastguard Worker   Define W and the associated z_word_t type. If W is not defined, then a
77*86ee64e7SAndroid Build Coastguard Worker   braided calculation is not used, and the associated tables and code are not
78*86ee64e7SAndroid Build Coastguard Worker   compiled.
79*86ee64e7SAndroid Build Coastguard Worker  */
80*86ee64e7SAndroid Build Coastguard Worker #ifdef Z_TESTW
81*86ee64e7SAndroid Build Coastguard Worker #  if Z_TESTW-1 != -1
82*86ee64e7SAndroid Build Coastguard Worker #    define W Z_TESTW
83*86ee64e7SAndroid Build Coastguard Worker #  endif
84*86ee64e7SAndroid Build Coastguard Worker #else
85*86ee64e7SAndroid Build Coastguard Worker #  ifdef MAKECRCH
86*86ee64e7SAndroid Build Coastguard Worker #    define W 8         /* required for MAKECRCH */
87*86ee64e7SAndroid Build Coastguard Worker #  else
88*86ee64e7SAndroid Build Coastguard Worker #    if defined(__x86_64__) || defined(__aarch64__)
89*86ee64e7SAndroid Build Coastguard Worker #      define W 8
90*86ee64e7SAndroid Build Coastguard Worker #    else
91*86ee64e7SAndroid Build Coastguard Worker #      define W 4
92*86ee64e7SAndroid Build Coastguard Worker #    endif
93*86ee64e7SAndroid Build Coastguard Worker #  endif
94*86ee64e7SAndroid Build Coastguard Worker #endif
95*86ee64e7SAndroid Build Coastguard Worker #ifdef W
96*86ee64e7SAndroid Build Coastguard Worker #  if W == 8 && defined(Z_U8)
97*86ee64e7SAndroid Build Coastguard Worker      typedef Z_U8 z_word_t;
98*86ee64e7SAndroid Build Coastguard Worker #  elif defined(Z_U4)
99*86ee64e7SAndroid Build Coastguard Worker #    undef W
100*86ee64e7SAndroid Build Coastguard Worker #    define W 4
101*86ee64e7SAndroid Build Coastguard Worker      typedef Z_U4 z_word_t;
102*86ee64e7SAndroid Build Coastguard Worker #  else
103*86ee64e7SAndroid Build Coastguard Worker #    undef W
104*86ee64e7SAndroid Build Coastguard Worker #  endif
105*86ee64e7SAndroid Build Coastguard Worker #endif
106*86ee64e7SAndroid Build Coastguard Worker 
107*86ee64e7SAndroid Build Coastguard Worker /* If available, use the ARM processor CRC32 instruction. */
108*86ee64e7SAndroid Build Coastguard Worker #if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 \
109*86ee64e7SAndroid Build Coastguard Worker     && defined(USE_CANONICAL_ARMV8_CRC32)
110*86ee64e7SAndroid Build Coastguard Worker #  define ARMCRC32_CANONICAL_ZLIB
111*86ee64e7SAndroid Build Coastguard Worker #endif
112*86ee64e7SAndroid Build Coastguard Worker 
113*86ee64e7SAndroid Build Coastguard Worker #if defined(W) && (!defined(ARMCRC32_CANONICAL_ZLIB) || defined(DYNAMIC_CRC_TABLE))
114*86ee64e7SAndroid Build Coastguard Worker /*
115*86ee64e7SAndroid Build Coastguard Worker   Swap the bytes in a z_word_t to convert between little and big endian. Any
116*86ee64e7SAndroid Build Coastguard Worker   self-respecting compiler will optimize this to a single machine byte-swap
117*86ee64e7SAndroid Build Coastguard Worker   instruction, if one is available. This assumes that word_t is either 32 bits
118*86ee64e7SAndroid Build Coastguard Worker   or 64 bits.
119*86ee64e7SAndroid Build Coastguard Worker  */
byte_swap(z_word_t word)120*86ee64e7SAndroid Build Coastguard Worker local z_word_t byte_swap(z_word_t word) {
121*86ee64e7SAndroid Build Coastguard Worker #  if W == 8
122*86ee64e7SAndroid Build Coastguard Worker     return
123*86ee64e7SAndroid Build Coastguard Worker         (word & 0xff00000000000000) >> 56 |
124*86ee64e7SAndroid Build Coastguard Worker         (word & 0xff000000000000) >> 40 |
125*86ee64e7SAndroid Build Coastguard Worker         (word & 0xff0000000000) >> 24 |
126*86ee64e7SAndroid Build Coastguard Worker         (word & 0xff00000000) >> 8 |
127*86ee64e7SAndroid Build Coastguard Worker         (word & 0xff000000) << 8 |
128*86ee64e7SAndroid Build Coastguard Worker         (word & 0xff0000) << 24 |
129*86ee64e7SAndroid Build Coastguard Worker         (word & 0xff00) << 40 |
130*86ee64e7SAndroid Build Coastguard Worker         (word & 0xff) << 56;
131*86ee64e7SAndroid Build Coastguard Worker #  else   /* W == 4 */
132*86ee64e7SAndroid Build Coastguard Worker     return
133*86ee64e7SAndroid Build Coastguard Worker         (word & 0xff000000) >> 24 |
134*86ee64e7SAndroid Build Coastguard Worker         (word & 0xff0000) >> 8 |
135*86ee64e7SAndroid Build Coastguard Worker         (word & 0xff00) << 8 |
136*86ee64e7SAndroid Build Coastguard Worker         (word & 0xff) << 24;
137*86ee64e7SAndroid Build Coastguard Worker #  endif
138*86ee64e7SAndroid Build Coastguard Worker }
139*86ee64e7SAndroid Build Coastguard Worker #endif
140*86ee64e7SAndroid Build Coastguard Worker 
141*86ee64e7SAndroid Build Coastguard Worker #ifdef DYNAMIC_CRC_TABLE
142*86ee64e7SAndroid Build Coastguard Worker /* =========================================================================
143*86ee64e7SAndroid Build Coastguard Worker  * Table of powers of x for combining CRC-32s, filled in by make_crc_table()
144*86ee64e7SAndroid Build Coastguard Worker  * below.
145*86ee64e7SAndroid Build Coastguard Worker  */
146*86ee64e7SAndroid Build Coastguard Worker    local z_crc_t FAR x2n_table[32];
147*86ee64e7SAndroid Build Coastguard Worker #else
148*86ee64e7SAndroid Build Coastguard Worker /* =========================================================================
149*86ee64e7SAndroid Build Coastguard Worker  * Tables for byte-wise and braided CRC-32 calculations, and a table of powers
150*86ee64e7SAndroid Build Coastguard Worker  * of x for combining CRC-32s, all made by make_crc_table().
151*86ee64e7SAndroid Build Coastguard Worker  */
152*86ee64e7SAndroid Build Coastguard Worker #  include "crc32.h"
153*86ee64e7SAndroid Build Coastguard Worker #endif
154*86ee64e7SAndroid Build Coastguard Worker 
155*86ee64e7SAndroid Build Coastguard Worker /* CRC polynomial. */
156*86ee64e7SAndroid Build Coastguard Worker #define POLY 0xedb88320         /* p(x) reflected, with x^32 implied */
157*86ee64e7SAndroid Build Coastguard Worker 
158*86ee64e7SAndroid Build Coastguard Worker /*
159*86ee64e7SAndroid Build Coastguard Worker   Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,
160*86ee64e7SAndroid Build Coastguard Worker   reflected. For speed, this requires that a not be zero.
161*86ee64e7SAndroid Build Coastguard Worker  */
multmodp(z_crc_t a,z_crc_t b)162*86ee64e7SAndroid Build Coastguard Worker local z_crc_t multmodp(z_crc_t a, z_crc_t b) {
163*86ee64e7SAndroid Build Coastguard Worker     z_crc_t m, p;
164*86ee64e7SAndroid Build Coastguard Worker 
165*86ee64e7SAndroid Build Coastguard Worker     m = (z_crc_t)1 << 31;
166*86ee64e7SAndroid Build Coastguard Worker     p = 0;
167*86ee64e7SAndroid Build Coastguard Worker     for (;;) {
168*86ee64e7SAndroid Build Coastguard Worker         if (a & m) {
169*86ee64e7SAndroid Build Coastguard Worker             p ^= b;
170*86ee64e7SAndroid Build Coastguard Worker             if ((a & (m - 1)) == 0)
171*86ee64e7SAndroid Build Coastguard Worker                 break;
172*86ee64e7SAndroid Build Coastguard Worker         }
173*86ee64e7SAndroid Build Coastguard Worker         m >>= 1;
174*86ee64e7SAndroid Build Coastguard Worker         b = b & 1 ? (b >> 1) ^ POLY : b >> 1;
175*86ee64e7SAndroid Build Coastguard Worker     }
176*86ee64e7SAndroid Build Coastguard Worker     return p;
177*86ee64e7SAndroid Build Coastguard Worker }
178*86ee64e7SAndroid Build Coastguard Worker 
179*86ee64e7SAndroid Build Coastguard Worker /*
180*86ee64e7SAndroid Build Coastguard Worker   Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been
181*86ee64e7SAndroid Build Coastguard Worker   initialized.
182*86ee64e7SAndroid Build Coastguard Worker  */
x2nmodp(z_off64_t n,unsigned k)183*86ee64e7SAndroid Build Coastguard Worker local z_crc_t x2nmodp(z_off64_t n, unsigned k) {
184*86ee64e7SAndroid Build Coastguard Worker     z_crc_t p;
185*86ee64e7SAndroid Build Coastguard Worker 
186*86ee64e7SAndroid Build Coastguard Worker     p = (z_crc_t)1 << 31;           /* x^0 == 1 */
187*86ee64e7SAndroid Build Coastguard Worker     while (n) {
188*86ee64e7SAndroid Build Coastguard Worker         if (n & 1)
189*86ee64e7SAndroid Build Coastguard Worker             p = multmodp(x2n_table[k & 31], p);
190*86ee64e7SAndroid Build Coastguard Worker         n >>= 1;
191*86ee64e7SAndroid Build Coastguard Worker         k++;
192*86ee64e7SAndroid Build Coastguard Worker     }
193*86ee64e7SAndroid Build Coastguard Worker     return p;
194*86ee64e7SAndroid Build Coastguard Worker }
195*86ee64e7SAndroid Build Coastguard Worker 
196*86ee64e7SAndroid Build Coastguard Worker #ifdef DYNAMIC_CRC_TABLE
197*86ee64e7SAndroid Build Coastguard Worker /* =========================================================================
198*86ee64e7SAndroid Build Coastguard Worker  * Build the tables for byte-wise and braided CRC-32 calculations, and a table
199*86ee64e7SAndroid Build Coastguard Worker  * of powers of x for combining CRC-32s.
200*86ee64e7SAndroid Build Coastguard Worker  */
201*86ee64e7SAndroid Build Coastguard Worker local z_crc_t FAR crc_table[256];
202*86ee64e7SAndroid Build Coastguard Worker #ifdef W
203*86ee64e7SAndroid Build Coastguard Worker    local z_word_t FAR crc_big_table[256];
204*86ee64e7SAndroid Build Coastguard Worker    local z_crc_t FAR crc_braid_table[W][256];
205*86ee64e7SAndroid Build Coastguard Worker    local z_word_t FAR crc_braid_big_table[W][256];
206*86ee64e7SAndroid Build Coastguard Worker    local void braid(z_crc_t [][256], z_word_t [][256], int, int);
207*86ee64e7SAndroid Build Coastguard Worker #endif
208*86ee64e7SAndroid Build Coastguard Worker #ifdef MAKECRCH
209*86ee64e7SAndroid Build Coastguard Worker    local void write_table(FILE *, const z_crc_t FAR *, int);
210*86ee64e7SAndroid Build Coastguard Worker    local void write_table32hi(FILE *, const z_word_t FAR *, int);
211*86ee64e7SAndroid Build Coastguard Worker    local void write_table64(FILE *, const z_word_t FAR *, int);
212*86ee64e7SAndroid Build Coastguard Worker #endif /* MAKECRCH */
213*86ee64e7SAndroid Build Coastguard Worker 
214*86ee64e7SAndroid Build Coastguard Worker /*
215*86ee64e7SAndroid Build Coastguard Worker   Define a once() function depending on the availability of atomics. If this is
216*86ee64e7SAndroid Build Coastguard Worker   compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in
217*86ee64e7SAndroid Build Coastguard Worker   multiple threads, and if atomics are not available, then get_crc_table() must
218*86ee64e7SAndroid Build Coastguard Worker   be called to initialize the tables and must return before any threads are
219*86ee64e7SAndroid Build Coastguard Worker   allowed to compute or combine CRCs.
220*86ee64e7SAndroid Build Coastguard Worker  */
221*86ee64e7SAndroid Build Coastguard Worker 
222*86ee64e7SAndroid Build Coastguard Worker /* Definition of once functionality. */
223*86ee64e7SAndroid Build Coastguard Worker typedef struct once_s once_t;
224*86ee64e7SAndroid Build Coastguard Worker 
225*86ee64e7SAndroid Build Coastguard Worker /* Check for the availability of atomics. */
226*86ee64e7SAndroid Build Coastguard Worker #if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \
227*86ee64e7SAndroid Build Coastguard Worker     !defined(__STDC_NO_ATOMICS__)
228*86ee64e7SAndroid Build Coastguard Worker 
229*86ee64e7SAndroid Build Coastguard Worker #include <stdatomic.h>
230*86ee64e7SAndroid Build Coastguard Worker 
231*86ee64e7SAndroid Build Coastguard Worker /* Structure for once(), which must be initialized with ONCE_INIT. */
232*86ee64e7SAndroid Build Coastguard Worker struct once_s {
233*86ee64e7SAndroid Build Coastguard Worker     atomic_flag begun;
234*86ee64e7SAndroid Build Coastguard Worker     atomic_int done;
235*86ee64e7SAndroid Build Coastguard Worker };
236*86ee64e7SAndroid Build Coastguard Worker #define ONCE_INIT {ATOMIC_FLAG_INIT, 0}
237*86ee64e7SAndroid Build Coastguard Worker 
238*86ee64e7SAndroid Build Coastguard Worker /*
239*86ee64e7SAndroid Build Coastguard Worker   Run the provided init() function exactly once, even if multiple threads
240*86ee64e7SAndroid Build Coastguard Worker   invoke once() at the same time. The state must be a once_t initialized with
241*86ee64e7SAndroid Build Coastguard Worker   ONCE_INIT.
242*86ee64e7SAndroid Build Coastguard Worker  */
once(once_t * state,void (* init)(void))243*86ee64e7SAndroid Build Coastguard Worker local void once(once_t *state, void (*init)(void)) {
244*86ee64e7SAndroid Build Coastguard Worker     if (!atomic_load(&state->done)) {
245*86ee64e7SAndroid Build Coastguard Worker         if (atomic_flag_test_and_set(&state->begun))
246*86ee64e7SAndroid Build Coastguard Worker             while (!atomic_load(&state->done))
247*86ee64e7SAndroid Build Coastguard Worker                 ;
248*86ee64e7SAndroid Build Coastguard Worker         else {
249*86ee64e7SAndroid Build Coastguard Worker             init();
250*86ee64e7SAndroid Build Coastguard Worker             atomic_store(&state->done, 1);
251*86ee64e7SAndroid Build Coastguard Worker         }
252*86ee64e7SAndroid Build Coastguard Worker     }
253*86ee64e7SAndroid Build Coastguard Worker }
254*86ee64e7SAndroid Build Coastguard Worker 
255*86ee64e7SAndroid Build Coastguard Worker #else   /* no atomics */
256*86ee64e7SAndroid Build Coastguard Worker 
257*86ee64e7SAndroid Build Coastguard Worker /* Structure for once(), which must be initialized with ONCE_INIT. */
258*86ee64e7SAndroid Build Coastguard Worker struct once_s {
259*86ee64e7SAndroid Build Coastguard Worker     volatile int begun;
260*86ee64e7SAndroid Build Coastguard Worker     volatile int done;
261*86ee64e7SAndroid Build Coastguard Worker };
262*86ee64e7SAndroid Build Coastguard Worker #define ONCE_INIT {0, 0}
263*86ee64e7SAndroid Build Coastguard Worker 
264*86ee64e7SAndroid Build Coastguard Worker /* Test and set. Alas, not atomic, but tries to minimize the period of
265*86ee64e7SAndroid Build Coastguard Worker    vulnerability. */
test_and_set(int volatile * flag)266*86ee64e7SAndroid Build Coastguard Worker local int test_and_set(int volatile *flag) {
267*86ee64e7SAndroid Build Coastguard Worker     int was;
268*86ee64e7SAndroid Build Coastguard Worker 
269*86ee64e7SAndroid Build Coastguard Worker     was = *flag;
270*86ee64e7SAndroid Build Coastguard Worker     *flag = 1;
271*86ee64e7SAndroid Build Coastguard Worker     return was;
272*86ee64e7SAndroid Build Coastguard Worker }
273*86ee64e7SAndroid Build Coastguard Worker 
274*86ee64e7SAndroid Build Coastguard Worker /* Run the provided init() function once. This is not thread-safe. */
once(once_t * state,void (* init)(void))275*86ee64e7SAndroid Build Coastguard Worker local void once(once_t *state, void (*init)(void)) {
276*86ee64e7SAndroid Build Coastguard Worker     if (!state->done) {
277*86ee64e7SAndroid Build Coastguard Worker         if (test_and_set(&state->begun))
278*86ee64e7SAndroid Build Coastguard Worker             while (!state->done)
279*86ee64e7SAndroid Build Coastguard Worker                 ;
280*86ee64e7SAndroid Build Coastguard Worker         else {
281*86ee64e7SAndroid Build Coastguard Worker             init();
282*86ee64e7SAndroid Build Coastguard Worker             state->done = 1;
283*86ee64e7SAndroid Build Coastguard Worker         }
284*86ee64e7SAndroid Build Coastguard Worker     }
285*86ee64e7SAndroid Build Coastguard Worker }
286*86ee64e7SAndroid Build Coastguard Worker 
287*86ee64e7SAndroid Build Coastguard Worker #endif
288*86ee64e7SAndroid Build Coastguard Worker 
289*86ee64e7SAndroid Build Coastguard Worker /* State for once(). */
290*86ee64e7SAndroid Build Coastguard Worker local once_t made = ONCE_INIT;
291*86ee64e7SAndroid Build Coastguard Worker 
292*86ee64e7SAndroid Build Coastguard Worker /*
293*86ee64e7SAndroid Build Coastguard Worker   Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
294*86ee64e7SAndroid Build Coastguard Worker   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.
295*86ee64e7SAndroid Build Coastguard Worker 
296*86ee64e7SAndroid Build Coastguard Worker   Polynomials over GF(2) are represented in binary, one bit per coefficient,
297*86ee64e7SAndroid Build Coastguard Worker   with the lowest powers in the most significant bit. Then adding polynomials
298*86ee64e7SAndroid Build Coastguard Worker   is just exclusive-or, and multiplying a polynomial by x is a right shift by
299*86ee64e7SAndroid Build Coastguard Worker   one. If we call the above polynomial p, and represent a byte as the
300*86ee64e7SAndroid Build Coastguard Worker   polynomial q, also with the lowest power in the most significant bit (so the
301*86ee64e7SAndroid Build Coastguard Worker   byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p,
302*86ee64e7SAndroid Build Coastguard Worker   where a mod b means the remainder after dividing a by b.
303*86ee64e7SAndroid Build Coastguard Worker 
304*86ee64e7SAndroid Build Coastguard Worker   This calculation is done using the shift-register method of multiplying and
305*86ee64e7SAndroid Build Coastguard Worker   taking the remainder. The register is initialized to zero, and for each
306*86ee64e7SAndroid Build Coastguard Worker   incoming bit, x^32 is added mod p to the register if the bit is a one (where
307*86ee64e7SAndroid Build Coastguard Worker   x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x
308*86ee64e7SAndroid Build Coastguard Worker   (which is shifting right by one and adding x^32 mod p if the bit shifted out
309*86ee64e7SAndroid Build Coastguard Worker   is a one). We start with the highest power (least significant bit) of q and
310*86ee64e7SAndroid Build Coastguard Worker   repeat for all eight bits of q.
311*86ee64e7SAndroid Build Coastguard Worker 
312*86ee64e7SAndroid Build Coastguard Worker   The table is simply the CRC of all possible eight bit values. This is all the
313*86ee64e7SAndroid Build Coastguard Worker   information needed to generate CRCs on data a byte at a time for all
314*86ee64e7SAndroid Build Coastguard Worker   combinations of CRC register values and incoming bytes.
315*86ee64e7SAndroid Build Coastguard Worker  */
make_crc_table(void)316*86ee64e7SAndroid Build Coastguard Worker local void make_crc_table(void)
317*86ee64e7SAndroid Build Coastguard Worker {
318*86ee64e7SAndroid Build Coastguard Worker     unsigned i, j, n;
319*86ee64e7SAndroid Build Coastguard Worker     z_crc_t p;
320*86ee64e7SAndroid Build Coastguard Worker 
321*86ee64e7SAndroid Build Coastguard Worker     /* initialize the CRC of bytes tables */
322*86ee64e7SAndroid Build Coastguard Worker     for (i = 0; i < 256; i++) {
323*86ee64e7SAndroid Build Coastguard Worker         p = i;
324*86ee64e7SAndroid Build Coastguard Worker         for (j = 0; j < 8; j++)
325*86ee64e7SAndroid Build Coastguard Worker             p = p & 1 ? (p >> 1) ^ POLY : p >> 1;
326*86ee64e7SAndroid Build Coastguard Worker         crc_table[i] = p;
327*86ee64e7SAndroid Build Coastguard Worker #ifdef W
328*86ee64e7SAndroid Build Coastguard Worker         crc_big_table[i] = byte_swap(p);
329*86ee64e7SAndroid Build Coastguard Worker #endif
330*86ee64e7SAndroid Build Coastguard Worker     }
331*86ee64e7SAndroid Build Coastguard Worker 
332*86ee64e7SAndroid Build Coastguard Worker     /* initialize the x^2^n mod p(x) table */
333*86ee64e7SAndroid Build Coastguard Worker     p = (z_crc_t)1 << 30;         /* x^1 */
334*86ee64e7SAndroid Build Coastguard Worker     x2n_table[0] = p;
335*86ee64e7SAndroid Build Coastguard Worker     for (n = 1; n < 32; n++)
336*86ee64e7SAndroid Build Coastguard Worker         x2n_table[n] = p = multmodp(p, p);
337*86ee64e7SAndroid Build Coastguard Worker 
338*86ee64e7SAndroid Build Coastguard Worker #ifdef W
339*86ee64e7SAndroid Build Coastguard Worker     /* initialize the braiding tables -- needs x2n_table[] */
340*86ee64e7SAndroid Build Coastguard Worker     braid(crc_braid_table, crc_braid_big_table, N, W);
341*86ee64e7SAndroid Build Coastguard Worker #endif
342*86ee64e7SAndroid Build Coastguard Worker 
343*86ee64e7SAndroid Build Coastguard Worker #ifdef MAKECRCH
344*86ee64e7SAndroid Build Coastguard Worker     {
345*86ee64e7SAndroid Build Coastguard Worker         /*
346*86ee64e7SAndroid Build Coastguard Worker           The crc32.h header file contains tables for both 32-bit and 64-bit
347*86ee64e7SAndroid Build Coastguard Worker           z_word_t's, and so requires a 64-bit type be available. In that case,
348*86ee64e7SAndroid Build Coastguard Worker           z_word_t must be defined to be 64-bits. This code then also generates
349*86ee64e7SAndroid Build Coastguard Worker           and writes out the tables for the case that z_word_t is 32 bits.
350*86ee64e7SAndroid Build Coastguard Worker          */
351*86ee64e7SAndroid Build Coastguard Worker #if !defined(W) || W != 8
352*86ee64e7SAndroid Build Coastguard Worker #  error Need a 64-bit integer type in order to generate crc32.h.
353*86ee64e7SAndroid Build Coastguard Worker #endif
354*86ee64e7SAndroid Build Coastguard Worker         FILE *out;
355*86ee64e7SAndroid Build Coastguard Worker         int k, n;
356*86ee64e7SAndroid Build Coastguard Worker         z_crc_t ltl[8][256];
357*86ee64e7SAndroid Build Coastguard Worker         z_word_t big[8][256];
358*86ee64e7SAndroid Build Coastguard Worker 
359*86ee64e7SAndroid Build Coastguard Worker         out = fopen("crc32.h", "w");
360*86ee64e7SAndroid Build Coastguard Worker         if (out == NULL) return;
361*86ee64e7SAndroid Build Coastguard Worker 
362*86ee64e7SAndroid Build Coastguard Worker         /* write out little-endian CRC table to crc32.h */
363*86ee64e7SAndroid Build Coastguard Worker         fprintf(out,
364*86ee64e7SAndroid Build Coastguard Worker             "/* crc32.h -- tables for rapid CRC calculation\n"
365*86ee64e7SAndroid Build Coastguard Worker             " * Generated automatically by crc32.c\n */\n"
366*86ee64e7SAndroid Build Coastguard Worker             "\n"
367*86ee64e7SAndroid Build Coastguard Worker             "local const z_crc_t FAR crc_table[] = {\n"
368*86ee64e7SAndroid Build Coastguard Worker             "    ");
369*86ee64e7SAndroid Build Coastguard Worker         write_table(out, crc_table, 256);
370*86ee64e7SAndroid Build Coastguard Worker         fprintf(out,
371*86ee64e7SAndroid Build Coastguard Worker             "};\n");
372*86ee64e7SAndroid Build Coastguard Worker 
373*86ee64e7SAndroid Build Coastguard Worker         /* write out big-endian CRC table for 64-bit z_word_t to crc32.h */
374*86ee64e7SAndroid Build Coastguard Worker         fprintf(out,
375*86ee64e7SAndroid Build Coastguard Worker             "\n"
376*86ee64e7SAndroid Build Coastguard Worker             "#ifdef W\n"
377*86ee64e7SAndroid Build Coastguard Worker             "\n"
378*86ee64e7SAndroid Build Coastguard Worker             "#if W == 8\n"
379*86ee64e7SAndroid Build Coastguard Worker             "\n"
380*86ee64e7SAndroid Build Coastguard Worker             "local const z_word_t FAR crc_big_table[] = {\n"
381*86ee64e7SAndroid Build Coastguard Worker             "    ");
382*86ee64e7SAndroid Build Coastguard Worker         write_table64(out, crc_big_table, 256);
383*86ee64e7SAndroid Build Coastguard Worker         fprintf(out,
384*86ee64e7SAndroid Build Coastguard Worker             "};\n");
385*86ee64e7SAndroid Build Coastguard Worker 
386*86ee64e7SAndroid Build Coastguard Worker         /* write out big-endian CRC table for 32-bit z_word_t to crc32.h */
387*86ee64e7SAndroid Build Coastguard Worker         fprintf(out,
388*86ee64e7SAndroid Build Coastguard Worker             "\n"
389*86ee64e7SAndroid Build Coastguard Worker             "#else /* W == 4 */\n"
390*86ee64e7SAndroid Build Coastguard Worker             "\n"
391*86ee64e7SAndroid Build Coastguard Worker             "local const z_word_t FAR crc_big_table[] = {\n"
392*86ee64e7SAndroid Build Coastguard Worker             "    ");
393*86ee64e7SAndroid Build Coastguard Worker         write_table32hi(out, crc_big_table, 256);
394*86ee64e7SAndroid Build Coastguard Worker         fprintf(out,
395*86ee64e7SAndroid Build Coastguard Worker             "};\n"
396*86ee64e7SAndroid Build Coastguard Worker             "\n"
397*86ee64e7SAndroid Build Coastguard Worker             "#endif\n");
398*86ee64e7SAndroid Build Coastguard Worker 
399*86ee64e7SAndroid Build Coastguard Worker         /* write out braid tables for each value of N */
400*86ee64e7SAndroid Build Coastguard Worker         for (n = 1; n <= 6; n++) {
401*86ee64e7SAndroid Build Coastguard Worker             fprintf(out,
402*86ee64e7SAndroid Build Coastguard Worker             "\n"
403*86ee64e7SAndroid Build Coastguard Worker             "#if N == %d\n", n);
404*86ee64e7SAndroid Build Coastguard Worker 
405*86ee64e7SAndroid Build Coastguard Worker             /* compute braid tables for this N and 64-bit word_t */
406*86ee64e7SAndroid Build Coastguard Worker             braid(ltl, big, n, 8);
407*86ee64e7SAndroid Build Coastguard Worker 
408*86ee64e7SAndroid Build Coastguard Worker             /* write out braid tables for 64-bit z_word_t to crc32.h */
409*86ee64e7SAndroid Build Coastguard Worker             fprintf(out,
410*86ee64e7SAndroid Build Coastguard Worker             "\n"
411*86ee64e7SAndroid Build Coastguard Worker             "#if W == 8\n"
412*86ee64e7SAndroid Build Coastguard Worker             "\n"
413*86ee64e7SAndroid Build Coastguard Worker             "local const z_crc_t FAR crc_braid_table[][256] = {\n");
414*86ee64e7SAndroid Build Coastguard Worker             for (k = 0; k < 8; k++) {
415*86ee64e7SAndroid Build Coastguard Worker                 fprintf(out, "   {");
416*86ee64e7SAndroid Build Coastguard Worker                 write_table(out, ltl[k], 256);
417*86ee64e7SAndroid Build Coastguard Worker                 fprintf(out, "}%s", k < 7 ? ",\n" : "");
418*86ee64e7SAndroid Build Coastguard Worker             }
419*86ee64e7SAndroid Build Coastguard Worker             fprintf(out,
420*86ee64e7SAndroid Build Coastguard Worker             "};\n"
421*86ee64e7SAndroid Build Coastguard Worker             "\n"
422*86ee64e7SAndroid Build Coastguard Worker             "local const z_word_t FAR crc_braid_big_table[][256] = {\n");
423*86ee64e7SAndroid Build Coastguard Worker             for (k = 0; k < 8; k++) {
424*86ee64e7SAndroid Build Coastguard Worker                 fprintf(out, "   {");
425*86ee64e7SAndroid Build Coastguard Worker                 write_table64(out, big[k], 256);
426*86ee64e7SAndroid Build Coastguard Worker                 fprintf(out, "}%s", k < 7 ? ",\n" : "");
427*86ee64e7SAndroid Build Coastguard Worker             }
428*86ee64e7SAndroid Build Coastguard Worker             fprintf(out,
429*86ee64e7SAndroid Build Coastguard Worker             "};\n");
430*86ee64e7SAndroid Build Coastguard Worker 
431*86ee64e7SAndroid Build Coastguard Worker             /* compute braid tables for this N and 32-bit word_t */
432*86ee64e7SAndroid Build Coastguard Worker             braid(ltl, big, n, 4);
433*86ee64e7SAndroid Build Coastguard Worker 
434*86ee64e7SAndroid Build Coastguard Worker             /* write out braid tables for 32-bit z_word_t to crc32.h */
435*86ee64e7SAndroid Build Coastguard Worker             fprintf(out,
436*86ee64e7SAndroid Build Coastguard Worker             "\n"
437*86ee64e7SAndroid Build Coastguard Worker             "#else /* W == 4 */\n"
438*86ee64e7SAndroid Build Coastguard Worker             "\n"
439*86ee64e7SAndroid Build Coastguard Worker             "local const z_crc_t FAR crc_braid_table[][256] = {\n");
440*86ee64e7SAndroid Build Coastguard Worker             for (k = 0; k < 4; k++) {
441*86ee64e7SAndroid Build Coastguard Worker                 fprintf(out, "   {");
442*86ee64e7SAndroid Build Coastguard Worker                 write_table(out, ltl[k], 256);
443*86ee64e7SAndroid Build Coastguard Worker                 fprintf(out, "}%s", k < 3 ? ",\n" : "");
444*86ee64e7SAndroid Build Coastguard Worker             }
445*86ee64e7SAndroid Build Coastguard Worker             fprintf(out,
446*86ee64e7SAndroid Build Coastguard Worker             "};\n"
447*86ee64e7SAndroid Build Coastguard Worker             "\n"
448*86ee64e7SAndroid Build Coastguard Worker             "local const z_word_t FAR crc_braid_big_table[][256] = {\n");
449*86ee64e7SAndroid Build Coastguard Worker             for (k = 0; k < 4; k++) {
450*86ee64e7SAndroid Build Coastguard Worker                 fprintf(out, "   {");
451*86ee64e7SAndroid Build Coastguard Worker                 write_table32hi(out, big[k], 256);
452*86ee64e7SAndroid Build Coastguard Worker                 fprintf(out, "}%s", k < 3 ? ",\n" : "");
453*86ee64e7SAndroid Build Coastguard Worker             }
454*86ee64e7SAndroid Build Coastguard Worker             fprintf(out,
455*86ee64e7SAndroid Build Coastguard Worker             "};\n"
456*86ee64e7SAndroid Build Coastguard Worker             "\n"
457*86ee64e7SAndroid Build Coastguard Worker             "#endif\n"
458*86ee64e7SAndroid Build Coastguard Worker             "\n"
459*86ee64e7SAndroid Build Coastguard Worker             "#endif\n");
460*86ee64e7SAndroid Build Coastguard Worker         }
461*86ee64e7SAndroid Build Coastguard Worker         fprintf(out,
462*86ee64e7SAndroid Build Coastguard Worker             "\n"
463*86ee64e7SAndroid Build Coastguard Worker             "#endif\n");
464*86ee64e7SAndroid Build Coastguard Worker 
465*86ee64e7SAndroid Build Coastguard Worker         /* write out zeros operator table to crc32.h */
466*86ee64e7SAndroid Build Coastguard Worker         fprintf(out,
467*86ee64e7SAndroid Build Coastguard Worker             "\n"
468*86ee64e7SAndroid Build Coastguard Worker             "local const z_crc_t FAR x2n_table[] = {\n"
469*86ee64e7SAndroid Build Coastguard Worker             "    ");
470*86ee64e7SAndroid Build Coastguard Worker         write_table(out, x2n_table, 32);
471*86ee64e7SAndroid Build Coastguard Worker         fprintf(out,
472*86ee64e7SAndroid Build Coastguard Worker             "};\n");
473*86ee64e7SAndroid Build Coastguard Worker         fclose(out);
474*86ee64e7SAndroid Build Coastguard Worker     }
475*86ee64e7SAndroid Build Coastguard Worker #endif /* MAKECRCH */
476*86ee64e7SAndroid Build Coastguard Worker }
477*86ee64e7SAndroid Build Coastguard Worker 
478*86ee64e7SAndroid Build Coastguard Worker #ifdef MAKECRCH
479*86ee64e7SAndroid Build Coastguard Worker 
480*86ee64e7SAndroid Build Coastguard Worker /*
481*86ee64e7SAndroid Build Coastguard Worker    Write the 32-bit values in table[0..k-1] to out, five per line in
482*86ee64e7SAndroid Build Coastguard Worker    hexadecimal separated by commas.
483*86ee64e7SAndroid Build Coastguard Worker  */
write_table(FILE * out,const z_crc_t FAR * table,int k)484*86ee64e7SAndroid Build Coastguard Worker local void write_table(FILE *out, const z_crc_t FAR *table, int k) {
485*86ee64e7SAndroid Build Coastguard Worker     int n;
486*86ee64e7SAndroid Build Coastguard Worker 
487*86ee64e7SAndroid Build Coastguard Worker     for (n = 0; n < k; n++)
488*86ee64e7SAndroid Build Coastguard Worker         fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : "    ",
489*86ee64e7SAndroid Build Coastguard Worker                 (unsigned long)(table[n]),
490*86ee64e7SAndroid Build Coastguard Worker                 n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", "));
491*86ee64e7SAndroid Build Coastguard Worker }
492*86ee64e7SAndroid Build Coastguard Worker 
493*86ee64e7SAndroid Build Coastguard Worker /*
494*86ee64e7SAndroid Build Coastguard Worker    Write the high 32-bits of each value in table[0..k-1] to out, five per line
495*86ee64e7SAndroid Build Coastguard Worker    in hexadecimal separated by commas.
496*86ee64e7SAndroid Build Coastguard Worker  */
write_table32hi(FILE * out,const z_word_t FAR * table,int k)497*86ee64e7SAndroid Build Coastguard Worker local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) {
498*86ee64e7SAndroid Build Coastguard Worker     int n;
499*86ee64e7SAndroid Build Coastguard Worker 
500*86ee64e7SAndroid Build Coastguard Worker     for (n = 0; n < k; n++)
501*86ee64e7SAndroid Build Coastguard Worker         fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : "    ",
502*86ee64e7SAndroid Build Coastguard Worker                 (unsigned long)(table[n] >> 32),
503*86ee64e7SAndroid Build Coastguard Worker                 n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", "));
504*86ee64e7SAndroid Build Coastguard Worker }
505*86ee64e7SAndroid Build Coastguard Worker 
506*86ee64e7SAndroid Build Coastguard Worker /*
507*86ee64e7SAndroid Build Coastguard Worker   Write the 64-bit values in table[0..k-1] to out, three per line in
508*86ee64e7SAndroid Build Coastguard Worker   hexadecimal separated by commas. This assumes that if there is a 64-bit
509*86ee64e7SAndroid Build Coastguard Worker   type, then there is also a long long integer type, and it is at least 64
510*86ee64e7SAndroid Build Coastguard Worker   bits. If not, then the type cast and format string can be adjusted
511*86ee64e7SAndroid Build Coastguard Worker   accordingly.
512*86ee64e7SAndroid Build Coastguard Worker  */
write_table64(FILE * out,const z_word_t FAR * table,int k)513*86ee64e7SAndroid Build Coastguard Worker local void write_table64(FILE *out, const z_word_t FAR *table, int k) {
514*86ee64e7SAndroid Build Coastguard Worker     int n;
515*86ee64e7SAndroid Build Coastguard Worker 
516*86ee64e7SAndroid Build Coastguard Worker     for (n = 0; n < k; n++)
517*86ee64e7SAndroid Build Coastguard Worker         fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : "    ",
518*86ee64e7SAndroid Build Coastguard Worker                 (unsigned long long)(table[n]),
519*86ee64e7SAndroid Build Coastguard Worker                 n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", "));
520*86ee64e7SAndroid Build Coastguard Worker }
521*86ee64e7SAndroid Build Coastguard Worker 
522*86ee64e7SAndroid Build Coastguard Worker /* Actually do the deed. */
main(void)523*86ee64e7SAndroid Build Coastguard Worker int main(void) {
524*86ee64e7SAndroid Build Coastguard Worker     make_crc_table();
525*86ee64e7SAndroid Build Coastguard Worker     return 0;
526*86ee64e7SAndroid Build Coastguard Worker }
527*86ee64e7SAndroid Build Coastguard Worker 
528*86ee64e7SAndroid Build Coastguard Worker #endif /* MAKECRCH */
529*86ee64e7SAndroid Build Coastguard Worker 
530*86ee64e7SAndroid Build Coastguard Worker #ifdef W
531*86ee64e7SAndroid Build Coastguard Worker /*
532*86ee64e7SAndroid Build Coastguard Worker   Generate the little and big-endian braid tables for the given n and z_word_t
533*86ee64e7SAndroid Build Coastguard Worker   size w. Each array must have room for w blocks of 256 elements.
534*86ee64e7SAndroid Build Coastguard Worker  */
braid(z_crc_t ltl[][256],z_word_t big[][256],int n,int w)535*86ee64e7SAndroid Build Coastguard Worker local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) {
536*86ee64e7SAndroid Build Coastguard Worker     int k;
537*86ee64e7SAndroid Build Coastguard Worker     z_crc_t i, p, q;
538*86ee64e7SAndroid Build Coastguard Worker     for (k = 0; k < w; k++) {
539*86ee64e7SAndroid Build Coastguard Worker         p = x2nmodp((n * w + 3 - k) << 3, 0);
540*86ee64e7SAndroid Build Coastguard Worker         ltl[k][0] = 0;
541*86ee64e7SAndroid Build Coastguard Worker         big[w - 1 - k][0] = 0;
542*86ee64e7SAndroid Build Coastguard Worker         for (i = 1; i < 256; i++) {
543*86ee64e7SAndroid Build Coastguard Worker             ltl[k][i] = q = multmodp(i << 24, p);
544*86ee64e7SAndroid Build Coastguard Worker             big[w - 1 - k][i] = byte_swap(q);
545*86ee64e7SAndroid Build Coastguard Worker         }
546*86ee64e7SAndroid Build Coastguard Worker     }
547*86ee64e7SAndroid Build Coastguard Worker }
548*86ee64e7SAndroid Build Coastguard Worker #endif
549*86ee64e7SAndroid Build Coastguard Worker 
550*86ee64e7SAndroid Build Coastguard Worker #endif /* DYNAMIC_CRC_TABLE */
551*86ee64e7SAndroid Build Coastguard Worker 
552*86ee64e7SAndroid Build Coastguard Worker /* =========================================================================
553*86ee64e7SAndroid Build Coastguard Worker  * This function can be used by asm versions of crc32(), and to force the
554*86ee64e7SAndroid Build Coastguard Worker  * generation of the CRC tables in a threaded application.
555*86ee64e7SAndroid Build Coastguard Worker  */
get_crc_table(void)556*86ee64e7SAndroid Build Coastguard Worker const z_crc_t FAR * ZEXPORT get_crc_table(void) {
557*86ee64e7SAndroid Build Coastguard Worker #ifdef DYNAMIC_CRC_TABLE
558*86ee64e7SAndroid Build Coastguard Worker     once(&made, make_crc_table);
559*86ee64e7SAndroid Build Coastguard Worker #endif /* DYNAMIC_CRC_TABLE */
560*86ee64e7SAndroid Build Coastguard Worker     return (const z_crc_t FAR *)crc_table;
561*86ee64e7SAndroid Build Coastguard Worker }
562*86ee64e7SAndroid Build Coastguard Worker 
563*86ee64e7SAndroid Build Coastguard Worker /* =========================================================================
564*86ee64e7SAndroid Build Coastguard Worker  * Use ARM machine instructions if available. This will compute the CRC about
565*86ee64e7SAndroid Build Coastguard Worker  * ten times faster than the braided calculation. This code does not check for
566*86ee64e7SAndroid Build Coastguard Worker  * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will
567*86ee64e7SAndroid Build Coastguard Worker  * only be defined if the compilation specifies an ARM processor architecture
568*86ee64e7SAndroid Build Coastguard Worker  * that has the instructions. For example, compiling with -march=armv8.1-a or
569*86ee64e7SAndroid Build Coastguard Worker  * -march=armv8-a+crc, or -march=native if the compile machine has the crc32
570*86ee64e7SAndroid Build Coastguard Worker  * instructions.
571*86ee64e7SAndroid Build Coastguard Worker  */
572*86ee64e7SAndroid Build Coastguard Worker #if ARMCRC32_CANONICAL_ZLIB
573*86ee64e7SAndroid Build Coastguard Worker 
574*86ee64e7SAndroid Build Coastguard Worker /*
575*86ee64e7SAndroid Build Coastguard Worker    Constants empirically determined to maximize speed. These values are from
576*86ee64e7SAndroid Build Coastguard Worker    measurements on a Cortex-A57. Your mileage may vary.
577*86ee64e7SAndroid Build Coastguard Worker  */
578*86ee64e7SAndroid Build Coastguard Worker #define Z_BATCH 3990                /* number of words in a batch */
579*86ee64e7SAndroid Build Coastguard Worker #define Z_BATCH_ZEROS 0xa10d3d0c    /* computed from Z_BATCH = 3990 */
580*86ee64e7SAndroid Build Coastguard Worker #define Z_BATCH_MIN 800             /* fewest words in a final batch */
581*86ee64e7SAndroid Build Coastguard Worker 
crc32_z(unsigned long crc,const unsigned char FAR * buf,z_size_t len)582*86ee64e7SAndroid Build Coastguard Worker unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
583*86ee64e7SAndroid Build Coastguard Worker                               z_size_t len) {
584*86ee64e7SAndroid Build Coastguard Worker     z_crc_t val;
585*86ee64e7SAndroid Build Coastguard Worker     z_word_t crc1, crc2;
586*86ee64e7SAndroid Build Coastguard Worker     const z_word_t *word;
587*86ee64e7SAndroid Build Coastguard Worker     z_word_t val0, val1, val2;
588*86ee64e7SAndroid Build Coastguard Worker     z_size_t last, last2, i;
589*86ee64e7SAndroid Build Coastguard Worker     z_size_t num;
590*86ee64e7SAndroid Build Coastguard Worker 
591*86ee64e7SAndroid Build Coastguard Worker     /* Return initial CRC, if requested. */
592*86ee64e7SAndroid Build Coastguard Worker     if (buf == Z_NULL) return 0;
593*86ee64e7SAndroid Build Coastguard Worker 
594*86ee64e7SAndroid Build Coastguard Worker #ifdef DYNAMIC_CRC_TABLE
595*86ee64e7SAndroid Build Coastguard Worker     once(&made, make_crc_table);
596*86ee64e7SAndroid Build Coastguard Worker #endif /* DYNAMIC_CRC_TABLE */
597*86ee64e7SAndroid Build Coastguard Worker 
598*86ee64e7SAndroid Build Coastguard Worker     /* Pre-condition the CRC */
599*86ee64e7SAndroid Build Coastguard Worker     crc = (~crc) & 0xffffffff;
600*86ee64e7SAndroid Build Coastguard Worker 
601*86ee64e7SAndroid Build Coastguard Worker     /* Compute the CRC up to a word boundary. */
602*86ee64e7SAndroid Build Coastguard Worker     while (len && ((z_size_t)buf & 7) != 0) {
603*86ee64e7SAndroid Build Coastguard Worker         len--;
604*86ee64e7SAndroid Build Coastguard Worker         val = *buf++;
605*86ee64e7SAndroid Build Coastguard Worker         __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val));
606*86ee64e7SAndroid Build Coastguard Worker     }
607*86ee64e7SAndroid Build Coastguard Worker 
608*86ee64e7SAndroid Build Coastguard Worker     /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */
609*86ee64e7SAndroid Build Coastguard Worker     word = (z_word_t const *)buf;
610*86ee64e7SAndroid Build Coastguard Worker     num = len >> 3;
611*86ee64e7SAndroid Build Coastguard Worker     len &= 7;
612*86ee64e7SAndroid Build Coastguard Worker 
613*86ee64e7SAndroid Build Coastguard Worker     /* Do three interleaved CRCs to realize the throughput of one crc32x
614*86ee64e7SAndroid Build Coastguard Worker        instruction per cycle. Each CRC is calculated on Z_BATCH words. The
615*86ee64e7SAndroid Build Coastguard Worker        three CRCs are combined into a single CRC after each set of batches. */
616*86ee64e7SAndroid Build Coastguard Worker     while (num >= 3 * Z_BATCH) {
617*86ee64e7SAndroid Build Coastguard Worker         crc1 = 0;
618*86ee64e7SAndroid Build Coastguard Worker         crc2 = 0;
619*86ee64e7SAndroid Build Coastguard Worker         for (i = 0; i < Z_BATCH; i++) {
620*86ee64e7SAndroid Build Coastguard Worker             val0 = word[i];
621*86ee64e7SAndroid Build Coastguard Worker             val1 = word[i + Z_BATCH];
622*86ee64e7SAndroid Build Coastguard Worker             val2 = word[i + 2 * Z_BATCH];
623*86ee64e7SAndroid Build Coastguard Worker             __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0));
624*86ee64e7SAndroid Build Coastguard Worker             __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1));
625*86ee64e7SAndroid Build Coastguard Worker             __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2));
626*86ee64e7SAndroid Build Coastguard Worker         }
627*86ee64e7SAndroid Build Coastguard Worker         word += 3 * Z_BATCH;
628*86ee64e7SAndroid Build Coastguard Worker         num -= 3 * Z_BATCH;
629*86ee64e7SAndroid Build Coastguard Worker         crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1;
630*86ee64e7SAndroid Build Coastguard Worker         crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2;
631*86ee64e7SAndroid Build Coastguard Worker     }
632*86ee64e7SAndroid Build Coastguard Worker 
633*86ee64e7SAndroid Build Coastguard Worker     /* Do one last smaller batch with the remaining words, if there are enough
634*86ee64e7SAndroid Build Coastguard Worker        to pay for the combination of CRCs. */
635*86ee64e7SAndroid Build Coastguard Worker     last = num / 3;
636*86ee64e7SAndroid Build Coastguard Worker     if (last >= Z_BATCH_MIN) {
637*86ee64e7SAndroid Build Coastguard Worker         last2 = last << 1;
638*86ee64e7SAndroid Build Coastguard Worker         crc1 = 0;
639*86ee64e7SAndroid Build Coastguard Worker         crc2 = 0;
640*86ee64e7SAndroid Build Coastguard Worker         for (i = 0; i < last; i++) {
641*86ee64e7SAndroid Build Coastguard Worker             val0 = word[i];
642*86ee64e7SAndroid Build Coastguard Worker             val1 = word[i + last];
643*86ee64e7SAndroid Build Coastguard Worker             val2 = word[i + last2];
644*86ee64e7SAndroid Build Coastguard Worker             __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0));
645*86ee64e7SAndroid Build Coastguard Worker             __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1));
646*86ee64e7SAndroid Build Coastguard Worker             __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2));
647*86ee64e7SAndroid Build Coastguard Worker         }
648*86ee64e7SAndroid Build Coastguard Worker         word += 3 * last;
649*86ee64e7SAndroid Build Coastguard Worker         num -= 3 * last;
650*86ee64e7SAndroid Build Coastguard Worker         val = x2nmodp(last, 6);
651*86ee64e7SAndroid Build Coastguard Worker         crc = multmodp(val, crc) ^ crc1;
652*86ee64e7SAndroid Build Coastguard Worker         crc = multmodp(val, crc) ^ crc2;
653*86ee64e7SAndroid Build Coastguard Worker     }
654*86ee64e7SAndroid Build Coastguard Worker 
655*86ee64e7SAndroid Build Coastguard Worker     /* Compute the CRC on any remaining words. */
656*86ee64e7SAndroid Build Coastguard Worker     for (i = 0; i < num; i++) {
657*86ee64e7SAndroid Build Coastguard Worker         val0 = word[i];
658*86ee64e7SAndroid Build Coastguard Worker         __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0));
659*86ee64e7SAndroid Build Coastguard Worker     }
660*86ee64e7SAndroid Build Coastguard Worker     word += num;
661*86ee64e7SAndroid Build Coastguard Worker 
662*86ee64e7SAndroid Build Coastguard Worker     /* Complete the CRC on any remaining bytes. */
663*86ee64e7SAndroid Build Coastguard Worker     buf = (const unsigned char FAR *)word;
664*86ee64e7SAndroid Build Coastguard Worker     while (len) {
665*86ee64e7SAndroid Build Coastguard Worker         len--;
666*86ee64e7SAndroid Build Coastguard Worker         val = *buf++;
667*86ee64e7SAndroid Build Coastguard Worker         __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val));
668*86ee64e7SAndroid Build Coastguard Worker     }
669*86ee64e7SAndroid Build Coastguard Worker 
670*86ee64e7SAndroid Build Coastguard Worker     /* Return the CRC, post-conditioned. */
671*86ee64e7SAndroid Build Coastguard Worker     return crc ^ 0xffffffff;
672*86ee64e7SAndroid Build Coastguard Worker }
673*86ee64e7SAndroid Build Coastguard Worker 
674*86ee64e7SAndroid Build Coastguard Worker #else
675*86ee64e7SAndroid Build Coastguard Worker 
676*86ee64e7SAndroid Build Coastguard Worker #ifdef W
677*86ee64e7SAndroid Build Coastguard Worker 
678*86ee64e7SAndroid Build Coastguard Worker /*
679*86ee64e7SAndroid Build Coastguard Worker   Return the CRC of the W bytes in the word_t data, taking the
680*86ee64e7SAndroid Build Coastguard Worker   least-significant byte of the word as the first byte of data, without any pre
681*86ee64e7SAndroid Build Coastguard Worker   or post conditioning. This is used to combine the CRCs of each braid.
682*86ee64e7SAndroid Build Coastguard Worker  */
crc_word(z_word_t data)683*86ee64e7SAndroid Build Coastguard Worker local z_crc_t crc_word(z_word_t data) {
684*86ee64e7SAndroid Build Coastguard Worker     int k;
685*86ee64e7SAndroid Build Coastguard Worker     for (k = 0; k < W; k++)
686*86ee64e7SAndroid Build Coastguard Worker         data = (data >> 8) ^ crc_table[data & 0xff];
687*86ee64e7SAndroid Build Coastguard Worker     return (z_crc_t)data;
688*86ee64e7SAndroid Build Coastguard Worker }
689*86ee64e7SAndroid Build Coastguard Worker 
crc_word_big(z_word_t data)690*86ee64e7SAndroid Build Coastguard Worker local z_word_t crc_word_big(z_word_t data) {
691*86ee64e7SAndroid Build Coastguard Worker     int k;
692*86ee64e7SAndroid Build Coastguard Worker     for (k = 0; k < W; k++)
693*86ee64e7SAndroid Build Coastguard Worker         data = (data << 8) ^
694*86ee64e7SAndroid Build Coastguard Worker             crc_big_table[(data >> ((W - 1) << 3)) & 0xff];
695*86ee64e7SAndroid Build Coastguard Worker     return data;
696*86ee64e7SAndroid Build Coastguard Worker }
697*86ee64e7SAndroid Build Coastguard Worker 
698*86ee64e7SAndroid Build Coastguard Worker #endif
699*86ee64e7SAndroid Build Coastguard Worker 
700*86ee64e7SAndroid Build Coastguard Worker /* ========================================================================= */
crc32_z(unsigned long crc,const unsigned char FAR * buf,z_size_t len)701*86ee64e7SAndroid Build Coastguard Worker unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
702*86ee64e7SAndroid Build Coastguard Worker                               z_size_t len) {
703*86ee64e7SAndroid Build Coastguard Worker     /*
704*86ee64e7SAndroid Build Coastguard Worker      * zlib convention is to call crc32(0, NULL, 0); before making
705*86ee64e7SAndroid Build Coastguard Worker      * calls to crc32(). So this is a good, early (and infrequent)
706*86ee64e7SAndroid Build Coastguard Worker      * place to cache CPU features if needed for those later, more
707*86ee64e7SAndroid Build Coastguard Worker      * interesting crc32() calls.
708*86ee64e7SAndroid Build Coastguard Worker      */
709*86ee64e7SAndroid Build Coastguard Worker #if defined(CRC32_SIMD_SSE42_PCLMUL) || defined(CRC32_ARMV8_CRC32) \
710*86ee64e7SAndroid Build Coastguard Worker     || defined(RISCV_RVV)
711*86ee64e7SAndroid Build Coastguard Worker     /*
712*86ee64e7SAndroid Build Coastguard Worker      * Since this routine can be freely used, check CPU features here.
713*86ee64e7SAndroid Build Coastguard Worker      */
714*86ee64e7SAndroid Build Coastguard Worker     if (buf == Z_NULL) {
715*86ee64e7SAndroid Build Coastguard Worker         if (!len) /* Assume user is calling crc32(0, NULL, 0); */
716*86ee64e7SAndroid Build Coastguard Worker             cpu_check_features();
717*86ee64e7SAndroid Build Coastguard Worker         return 0UL;
718*86ee64e7SAndroid Build Coastguard Worker     }
719*86ee64e7SAndroid Build Coastguard Worker 
720*86ee64e7SAndroid Build Coastguard Worker #endif
721*86ee64e7SAndroid Build Coastguard Worker #if defined(CRC32_SIMD_AVX512_PCLMUL)
722*86ee64e7SAndroid Build Coastguard Worker     if (x86_cpu_enable_avx512 && len >= Z_CRC32_AVX512_MINIMUM_LENGTH) {
723*86ee64e7SAndroid Build Coastguard Worker         /* crc32 64-byte chunks */
724*86ee64e7SAndroid Build Coastguard Worker         z_size_t chunk_size = len & ~Z_CRC32_AVX512_CHUNKSIZE_MASK;
725*86ee64e7SAndroid Build Coastguard Worker         crc = ~crc32_avx512_simd_(buf, chunk_size, ~(uint32_t)crc);
726*86ee64e7SAndroid Build Coastguard Worker         /* check remaining data */
727*86ee64e7SAndroid Build Coastguard Worker         len -= chunk_size;
728*86ee64e7SAndroid Build Coastguard Worker         if (!len)
729*86ee64e7SAndroid Build Coastguard Worker             return crc;
730*86ee64e7SAndroid Build Coastguard Worker         /* Fall into the default crc32 for the remaining data. */
731*86ee64e7SAndroid Build Coastguard Worker         buf += chunk_size;
732*86ee64e7SAndroid Build Coastguard Worker     }
733*86ee64e7SAndroid Build Coastguard Worker #elif defined(CRC32_SIMD_SSE42_PCLMUL)
734*86ee64e7SAndroid Build Coastguard Worker     if (x86_cpu_enable_simd && len >= Z_CRC32_SSE42_MINIMUM_LENGTH) {
735*86ee64e7SAndroid Build Coastguard Worker         /* crc32 16-byte chunks */
736*86ee64e7SAndroid Build Coastguard Worker         z_size_t chunk_size = len & ~Z_CRC32_SSE42_CHUNKSIZE_MASK;
737*86ee64e7SAndroid Build Coastguard Worker         crc = ~crc32_sse42_simd_(buf, chunk_size, ~(uint32_t)crc);
738*86ee64e7SAndroid Build Coastguard Worker         /* check remaining data */
739*86ee64e7SAndroid Build Coastguard Worker         len -= chunk_size;
740*86ee64e7SAndroid Build Coastguard Worker         if (!len)
741*86ee64e7SAndroid Build Coastguard Worker             return crc;
742*86ee64e7SAndroid Build Coastguard Worker         /* Fall into the default crc32 for the remaining data. */
743*86ee64e7SAndroid Build Coastguard Worker         buf += chunk_size;
744*86ee64e7SAndroid Build Coastguard Worker     }
745*86ee64e7SAndroid Build Coastguard Worker #elif defined(CRC32_ARMV8_CRC32)
746*86ee64e7SAndroid Build Coastguard Worker     if (arm_cpu_enable_crc32) {
747*86ee64e7SAndroid Build Coastguard Worker #if defined(__aarch64__)
748*86ee64e7SAndroid Build Coastguard Worker         /* PMULL is 64bit only, plus code needs at least a 64 bytes buffer. */
749*86ee64e7SAndroid Build Coastguard Worker         if (arm_cpu_enable_pmull && (len > Z_CRC32_PMULL_MINIMUM_LENGTH)) {
750*86ee64e7SAndroid Build Coastguard Worker             const size_t chunk_size = len & ~Z_CRC32_PMULL_CHUNKSIZE_MASK;
751*86ee64e7SAndroid Build Coastguard Worker             crc = ~armv8_crc32_pmull_little(buf, chunk_size, ~(uint32_t)crc);
752*86ee64e7SAndroid Build Coastguard Worker             /* Check remaining data. */
753*86ee64e7SAndroid Build Coastguard Worker             len -= chunk_size;
754*86ee64e7SAndroid Build Coastguard Worker             if (!len)
755*86ee64e7SAndroid Build Coastguard Worker                 return crc;
756*86ee64e7SAndroid Build Coastguard Worker 
757*86ee64e7SAndroid Build Coastguard Worker             /* Fall through for the remaining data. */
758*86ee64e7SAndroid Build Coastguard Worker             buf += chunk_size;
759*86ee64e7SAndroid Build Coastguard Worker         }
760*86ee64e7SAndroid Build Coastguard Worker #endif
761*86ee64e7SAndroid Build Coastguard Worker         return armv8_crc32_little(buf, len, crc); /* Armv8@32bit or tail. */
762*86ee64e7SAndroid Build Coastguard Worker     }
763*86ee64e7SAndroid Build Coastguard Worker #else
764*86ee64e7SAndroid Build Coastguard Worker     if (buf == Z_NULL) {
765*86ee64e7SAndroid Build Coastguard Worker         return 0UL;
766*86ee64e7SAndroid Build Coastguard Worker     }
767*86ee64e7SAndroid Build Coastguard Worker #endif /* CRC32_SIMD */
768*86ee64e7SAndroid Build Coastguard Worker 
769*86ee64e7SAndroid Build Coastguard Worker #ifdef DYNAMIC_CRC_TABLE
770*86ee64e7SAndroid Build Coastguard Worker     once(&made, make_crc_table);
771*86ee64e7SAndroid Build Coastguard Worker #endif /* DYNAMIC_CRC_TABLE */
772*86ee64e7SAndroid Build Coastguard Worker     /* Pre-condition the CRC */
773*86ee64e7SAndroid Build Coastguard Worker     crc = (~crc) & 0xffffffff;
774*86ee64e7SAndroid Build Coastguard Worker 
775*86ee64e7SAndroid Build Coastguard Worker #ifdef W
776*86ee64e7SAndroid Build Coastguard Worker 
777*86ee64e7SAndroid Build Coastguard Worker     /* If provided enough bytes, do a braided CRC calculation. */
778*86ee64e7SAndroid Build Coastguard Worker     if (len >= N * W + W - 1) {
779*86ee64e7SAndroid Build Coastguard Worker         z_size_t blks;
780*86ee64e7SAndroid Build Coastguard Worker         z_word_t const *words;
781*86ee64e7SAndroid Build Coastguard Worker         unsigned endian;
782*86ee64e7SAndroid Build Coastguard Worker         int k;
783*86ee64e7SAndroid Build Coastguard Worker 
784*86ee64e7SAndroid Build Coastguard Worker         /* Compute the CRC up to a z_word_t boundary. */
785*86ee64e7SAndroid Build Coastguard Worker         while (len && ((z_size_t)buf & (W - 1)) != 0) {
786*86ee64e7SAndroid Build Coastguard Worker             len--;
787*86ee64e7SAndroid Build Coastguard Worker             crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
788*86ee64e7SAndroid Build Coastguard Worker         }
789*86ee64e7SAndroid Build Coastguard Worker 
790*86ee64e7SAndroid Build Coastguard Worker         /* Compute the CRC on as many N z_word_t blocks as are available. */
791*86ee64e7SAndroid Build Coastguard Worker         blks = len / (N * W);
792*86ee64e7SAndroid Build Coastguard Worker         len -= blks * N * W;
793*86ee64e7SAndroid Build Coastguard Worker         words = (z_word_t const *)buf;
794*86ee64e7SAndroid Build Coastguard Worker 
795*86ee64e7SAndroid Build Coastguard Worker         /* Do endian check at execution time instead of compile time, since ARM
796*86ee64e7SAndroid Build Coastguard Worker            processors can change the endianness at execution time. If the
797*86ee64e7SAndroid Build Coastguard Worker            compiler knows what the endianness will be, it can optimize out the
798*86ee64e7SAndroid Build Coastguard Worker            check and the unused branch. */
799*86ee64e7SAndroid Build Coastguard Worker         endian = 1;
800*86ee64e7SAndroid Build Coastguard Worker         if (*(unsigned char *)&endian) {
801*86ee64e7SAndroid Build Coastguard Worker             /* Little endian. */
802*86ee64e7SAndroid Build Coastguard Worker 
803*86ee64e7SAndroid Build Coastguard Worker             z_crc_t crc0;
804*86ee64e7SAndroid Build Coastguard Worker             z_word_t word0;
805*86ee64e7SAndroid Build Coastguard Worker #if N > 1
806*86ee64e7SAndroid Build Coastguard Worker             z_crc_t crc1;
807*86ee64e7SAndroid Build Coastguard Worker             z_word_t word1;
808*86ee64e7SAndroid Build Coastguard Worker #if N > 2
809*86ee64e7SAndroid Build Coastguard Worker             z_crc_t crc2;
810*86ee64e7SAndroid Build Coastguard Worker             z_word_t word2;
811*86ee64e7SAndroid Build Coastguard Worker #if N > 3
812*86ee64e7SAndroid Build Coastguard Worker             z_crc_t crc3;
813*86ee64e7SAndroid Build Coastguard Worker             z_word_t word3;
814*86ee64e7SAndroid Build Coastguard Worker #if N > 4
815*86ee64e7SAndroid Build Coastguard Worker             z_crc_t crc4;
816*86ee64e7SAndroid Build Coastguard Worker             z_word_t word4;
817*86ee64e7SAndroid Build Coastguard Worker #if N > 5
818*86ee64e7SAndroid Build Coastguard Worker             z_crc_t crc5;
819*86ee64e7SAndroid Build Coastguard Worker             z_word_t word5;
820*86ee64e7SAndroid Build Coastguard Worker #endif
821*86ee64e7SAndroid Build Coastguard Worker #endif
822*86ee64e7SAndroid Build Coastguard Worker #endif
823*86ee64e7SAndroid Build Coastguard Worker #endif
824*86ee64e7SAndroid Build Coastguard Worker #endif
825*86ee64e7SAndroid Build Coastguard Worker 
826*86ee64e7SAndroid Build Coastguard Worker             /* Initialize the CRC for each braid. */
827*86ee64e7SAndroid Build Coastguard Worker             crc0 = crc;
828*86ee64e7SAndroid Build Coastguard Worker #if N > 1
829*86ee64e7SAndroid Build Coastguard Worker             crc1 = 0;
830*86ee64e7SAndroid Build Coastguard Worker #if N > 2
831*86ee64e7SAndroid Build Coastguard Worker             crc2 = 0;
832*86ee64e7SAndroid Build Coastguard Worker #if N > 3
833*86ee64e7SAndroid Build Coastguard Worker             crc3 = 0;
834*86ee64e7SAndroid Build Coastguard Worker #if N > 4
835*86ee64e7SAndroid Build Coastguard Worker             crc4 = 0;
836*86ee64e7SAndroid Build Coastguard Worker #if N > 5
837*86ee64e7SAndroid Build Coastguard Worker             crc5 = 0;
838*86ee64e7SAndroid Build Coastguard Worker #endif
839*86ee64e7SAndroid Build Coastguard Worker #endif
840*86ee64e7SAndroid Build Coastguard Worker #endif
841*86ee64e7SAndroid Build Coastguard Worker #endif
842*86ee64e7SAndroid Build Coastguard Worker #endif
843*86ee64e7SAndroid Build Coastguard Worker 
844*86ee64e7SAndroid Build Coastguard Worker             /*
845*86ee64e7SAndroid Build Coastguard Worker               Process the first blks-1 blocks, computing the CRCs on each braid
846*86ee64e7SAndroid Build Coastguard Worker               independently.
847*86ee64e7SAndroid Build Coastguard Worker              */
848*86ee64e7SAndroid Build Coastguard Worker             while (--blks) {
849*86ee64e7SAndroid Build Coastguard Worker                 /* Load the word for each braid into registers. */
850*86ee64e7SAndroid Build Coastguard Worker                 word0 = crc0 ^ words[0];
851*86ee64e7SAndroid Build Coastguard Worker #if N > 1
852*86ee64e7SAndroid Build Coastguard Worker                 word1 = crc1 ^ words[1];
853*86ee64e7SAndroid Build Coastguard Worker #if N > 2
854*86ee64e7SAndroid Build Coastguard Worker                 word2 = crc2 ^ words[2];
855*86ee64e7SAndroid Build Coastguard Worker #if N > 3
856*86ee64e7SAndroid Build Coastguard Worker                 word3 = crc3 ^ words[3];
857*86ee64e7SAndroid Build Coastguard Worker #if N > 4
858*86ee64e7SAndroid Build Coastguard Worker                 word4 = crc4 ^ words[4];
859*86ee64e7SAndroid Build Coastguard Worker #if N > 5
860*86ee64e7SAndroid Build Coastguard Worker                 word5 = crc5 ^ words[5];
861*86ee64e7SAndroid Build Coastguard Worker #endif
862*86ee64e7SAndroid Build Coastguard Worker #endif
863*86ee64e7SAndroid Build Coastguard Worker #endif
864*86ee64e7SAndroid Build Coastguard Worker #endif
865*86ee64e7SAndroid Build Coastguard Worker #endif
866*86ee64e7SAndroid Build Coastguard Worker                 words += N;
867*86ee64e7SAndroid Build Coastguard Worker 
868*86ee64e7SAndroid Build Coastguard Worker                 /* Compute and update the CRC for each word. The loop should
869*86ee64e7SAndroid Build Coastguard Worker                    get unrolled. */
870*86ee64e7SAndroid Build Coastguard Worker                 crc0 = crc_braid_table[0][word0 & 0xff];
871*86ee64e7SAndroid Build Coastguard Worker #if N > 1
872*86ee64e7SAndroid Build Coastguard Worker                 crc1 = crc_braid_table[0][word1 & 0xff];
873*86ee64e7SAndroid Build Coastguard Worker #if N > 2
874*86ee64e7SAndroid Build Coastguard Worker                 crc2 = crc_braid_table[0][word2 & 0xff];
875*86ee64e7SAndroid Build Coastguard Worker #if N > 3
876*86ee64e7SAndroid Build Coastguard Worker                 crc3 = crc_braid_table[0][word3 & 0xff];
877*86ee64e7SAndroid Build Coastguard Worker #if N > 4
878*86ee64e7SAndroid Build Coastguard Worker                 crc4 = crc_braid_table[0][word4 & 0xff];
879*86ee64e7SAndroid Build Coastguard Worker #if N > 5
880*86ee64e7SAndroid Build Coastguard Worker                 crc5 = crc_braid_table[0][word5 & 0xff];
881*86ee64e7SAndroid Build Coastguard Worker #endif
882*86ee64e7SAndroid Build Coastguard Worker #endif
883*86ee64e7SAndroid Build Coastguard Worker #endif
884*86ee64e7SAndroid Build Coastguard Worker #endif
885*86ee64e7SAndroid Build Coastguard Worker #endif
886*86ee64e7SAndroid Build Coastguard Worker                 for (k = 1; k < W; k++) {
887*86ee64e7SAndroid Build Coastguard Worker                     crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff];
888*86ee64e7SAndroid Build Coastguard Worker #if N > 1
889*86ee64e7SAndroid Build Coastguard Worker                     crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff];
890*86ee64e7SAndroid Build Coastguard Worker #if N > 2
891*86ee64e7SAndroid Build Coastguard Worker                     crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff];
892*86ee64e7SAndroid Build Coastguard Worker #if N > 3
893*86ee64e7SAndroid Build Coastguard Worker                     crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff];
894*86ee64e7SAndroid Build Coastguard Worker #if N > 4
895*86ee64e7SAndroid Build Coastguard Worker                     crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff];
896*86ee64e7SAndroid Build Coastguard Worker #if N > 5
897*86ee64e7SAndroid Build Coastguard Worker                     crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff];
898*86ee64e7SAndroid Build Coastguard Worker #endif
899*86ee64e7SAndroid Build Coastguard Worker #endif
900*86ee64e7SAndroid Build Coastguard Worker #endif
901*86ee64e7SAndroid Build Coastguard Worker #endif
902*86ee64e7SAndroid Build Coastguard Worker #endif
903*86ee64e7SAndroid Build Coastguard Worker                 }
904*86ee64e7SAndroid Build Coastguard Worker             }
905*86ee64e7SAndroid Build Coastguard Worker 
906*86ee64e7SAndroid Build Coastguard Worker             /*
907*86ee64e7SAndroid Build Coastguard Worker               Process the last block, combining the CRCs of the N braids at the
908*86ee64e7SAndroid Build Coastguard Worker               same time.
909*86ee64e7SAndroid Build Coastguard Worker              */
910*86ee64e7SAndroid Build Coastguard Worker             crc = crc_word(crc0 ^ words[0]);
911*86ee64e7SAndroid Build Coastguard Worker #if N > 1
912*86ee64e7SAndroid Build Coastguard Worker             crc = crc_word(crc1 ^ words[1] ^ crc);
913*86ee64e7SAndroid Build Coastguard Worker #if N > 2
914*86ee64e7SAndroid Build Coastguard Worker             crc = crc_word(crc2 ^ words[2] ^ crc);
915*86ee64e7SAndroid Build Coastguard Worker #if N > 3
916*86ee64e7SAndroid Build Coastguard Worker             crc = crc_word(crc3 ^ words[3] ^ crc);
917*86ee64e7SAndroid Build Coastguard Worker #if N > 4
918*86ee64e7SAndroid Build Coastguard Worker             crc = crc_word(crc4 ^ words[4] ^ crc);
919*86ee64e7SAndroid Build Coastguard Worker #if N > 5
920*86ee64e7SAndroid Build Coastguard Worker             crc = crc_word(crc5 ^ words[5] ^ crc);
921*86ee64e7SAndroid Build Coastguard Worker #endif
922*86ee64e7SAndroid Build Coastguard Worker #endif
923*86ee64e7SAndroid Build Coastguard Worker #endif
924*86ee64e7SAndroid Build Coastguard Worker #endif
925*86ee64e7SAndroid Build Coastguard Worker #endif
926*86ee64e7SAndroid Build Coastguard Worker             words += N;
927*86ee64e7SAndroid Build Coastguard Worker         }
928*86ee64e7SAndroid Build Coastguard Worker         else {
929*86ee64e7SAndroid Build Coastguard Worker             /* Big endian. */
930*86ee64e7SAndroid Build Coastguard Worker 
931*86ee64e7SAndroid Build Coastguard Worker             z_word_t crc0, word0, comb;
932*86ee64e7SAndroid Build Coastguard Worker #if N > 1
933*86ee64e7SAndroid Build Coastguard Worker             z_word_t crc1, word1;
934*86ee64e7SAndroid Build Coastguard Worker #if N > 2
935*86ee64e7SAndroid Build Coastguard Worker             z_word_t crc2, word2;
936*86ee64e7SAndroid Build Coastguard Worker #if N > 3
937*86ee64e7SAndroid Build Coastguard Worker             z_word_t crc3, word3;
938*86ee64e7SAndroid Build Coastguard Worker #if N > 4
939*86ee64e7SAndroid Build Coastguard Worker             z_word_t crc4, word4;
940*86ee64e7SAndroid Build Coastguard Worker #if N > 5
941*86ee64e7SAndroid Build Coastguard Worker             z_word_t crc5, word5;
942*86ee64e7SAndroid Build Coastguard Worker #endif
943*86ee64e7SAndroid Build Coastguard Worker #endif
944*86ee64e7SAndroid Build Coastguard Worker #endif
945*86ee64e7SAndroid Build Coastguard Worker #endif
946*86ee64e7SAndroid Build Coastguard Worker #endif
947*86ee64e7SAndroid Build Coastguard Worker 
948*86ee64e7SAndroid Build Coastguard Worker             /* Initialize the CRC for each braid. */
949*86ee64e7SAndroid Build Coastguard Worker             crc0 = byte_swap(crc);
950*86ee64e7SAndroid Build Coastguard Worker #if N > 1
951*86ee64e7SAndroid Build Coastguard Worker             crc1 = 0;
952*86ee64e7SAndroid Build Coastguard Worker #if N > 2
953*86ee64e7SAndroid Build Coastguard Worker             crc2 = 0;
954*86ee64e7SAndroid Build Coastguard Worker #if N > 3
955*86ee64e7SAndroid Build Coastguard Worker             crc3 = 0;
956*86ee64e7SAndroid Build Coastguard Worker #if N > 4
957*86ee64e7SAndroid Build Coastguard Worker             crc4 = 0;
958*86ee64e7SAndroid Build Coastguard Worker #if N > 5
959*86ee64e7SAndroid Build Coastguard Worker             crc5 = 0;
960*86ee64e7SAndroid Build Coastguard Worker #endif
961*86ee64e7SAndroid Build Coastguard Worker #endif
962*86ee64e7SAndroid Build Coastguard Worker #endif
963*86ee64e7SAndroid Build Coastguard Worker #endif
964*86ee64e7SAndroid Build Coastguard Worker #endif
965*86ee64e7SAndroid Build Coastguard Worker 
966*86ee64e7SAndroid Build Coastguard Worker             /*
967*86ee64e7SAndroid Build Coastguard Worker               Process the first blks-1 blocks, computing the CRCs on each braid
968*86ee64e7SAndroid Build Coastguard Worker               independently.
969*86ee64e7SAndroid Build Coastguard Worker              */
970*86ee64e7SAndroid Build Coastguard Worker             while (--blks) {
971*86ee64e7SAndroid Build Coastguard Worker                 /* Load the word for each braid into registers. */
972*86ee64e7SAndroid Build Coastguard Worker                 word0 = crc0 ^ words[0];
973*86ee64e7SAndroid Build Coastguard Worker #if N > 1
974*86ee64e7SAndroid Build Coastguard Worker                 word1 = crc1 ^ words[1];
975*86ee64e7SAndroid Build Coastguard Worker #if N > 2
976*86ee64e7SAndroid Build Coastguard Worker                 word2 = crc2 ^ words[2];
977*86ee64e7SAndroid Build Coastguard Worker #if N > 3
978*86ee64e7SAndroid Build Coastguard Worker                 word3 = crc3 ^ words[3];
979*86ee64e7SAndroid Build Coastguard Worker #if N > 4
980*86ee64e7SAndroid Build Coastguard Worker                 word4 = crc4 ^ words[4];
981*86ee64e7SAndroid Build Coastguard Worker #if N > 5
982*86ee64e7SAndroid Build Coastguard Worker                 word5 = crc5 ^ words[5];
983*86ee64e7SAndroid Build Coastguard Worker #endif
984*86ee64e7SAndroid Build Coastguard Worker #endif
985*86ee64e7SAndroid Build Coastguard Worker #endif
986*86ee64e7SAndroid Build Coastguard Worker #endif
987*86ee64e7SAndroid Build Coastguard Worker #endif
988*86ee64e7SAndroid Build Coastguard Worker                 words += N;
989*86ee64e7SAndroid Build Coastguard Worker 
990*86ee64e7SAndroid Build Coastguard Worker                 /* Compute and update the CRC for each word. The loop should
991*86ee64e7SAndroid Build Coastguard Worker                    get unrolled. */
992*86ee64e7SAndroid Build Coastguard Worker                 crc0 = crc_braid_big_table[0][word0 & 0xff];
993*86ee64e7SAndroid Build Coastguard Worker #if N > 1
994*86ee64e7SAndroid Build Coastguard Worker                 crc1 = crc_braid_big_table[0][word1 & 0xff];
995*86ee64e7SAndroid Build Coastguard Worker #if N > 2
996*86ee64e7SAndroid Build Coastguard Worker                 crc2 = crc_braid_big_table[0][word2 & 0xff];
997*86ee64e7SAndroid Build Coastguard Worker #if N > 3
998*86ee64e7SAndroid Build Coastguard Worker                 crc3 = crc_braid_big_table[0][word3 & 0xff];
999*86ee64e7SAndroid Build Coastguard Worker #if N > 4
1000*86ee64e7SAndroid Build Coastguard Worker                 crc4 = crc_braid_big_table[0][word4 & 0xff];
1001*86ee64e7SAndroid Build Coastguard Worker #if N > 5
1002*86ee64e7SAndroid Build Coastguard Worker                 crc5 = crc_braid_big_table[0][word5 & 0xff];
1003*86ee64e7SAndroid Build Coastguard Worker #endif
1004*86ee64e7SAndroid Build Coastguard Worker #endif
1005*86ee64e7SAndroid Build Coastguard Worker #endif
1006*86ee64e7SAndroid Build Coastguard Worker #endif
1007*86ee64e7SAndroid Build Coastguard Worker #endif
1008*86ee64e7SAndroid Build Coastguard Worker                 for (k = 1; k < W; k++) {
1009*86ee64e7SAndroid Build Coastguard Worker                     crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff];
1010*86ee64e7SAndroid Build Coastguard Worker #if N > 1
1011*86ee64e7SAndroid Build Coastguard Worker                     crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff];
1012*86ee64e7SAndroid Build Coastguard Worker #if N > 2
1013*86ee64e7SAndroid Build Coastguard Worker                     crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff];
1014*86ee64e7SAndroid Build Coastguard Worker #if N > 3
1015*86ee64e7SAndroid Build Coastguard Worker                     crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff];
1016*86ee64e7SAndroid Build Coastguard Worker #if N > 4
1017*86ee64e7SAndroid Build Coastguard Worker                     crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff];
1018*86ee64e7SAndroid Build Coastguard Worker #if N > 5
1019*86ee64e7SAndroid Build Coastguard Worker                     crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff];
1020*86ee64e7SAndroid Build Coastguard Worker #endif
1021*86ee64e7SAndroid Build Coastguard Worker #endif
1022*86ee64e7SAndroid Build Coastguard Worker #endif
1023*86ee64e7SAndroid Build Coastguard Worker #endif
1024*86ee64e7SAndroid Build Coastguard Worker #endif
1025*86ee64e7SAndroid Build Coastguard Worker                 }
1026*86ee64e7SAndroid Build Coastguard Worker             }
1027*86ee64e7SAndroid Build Coastguard Worker 
1028*86ee64e7SAndroid Build Coastguard Worker             /*
1029*86ee64e7SAndroid Build Coastguard Worker               Process the last block, combining the CRCs of the N braids at the
1030*86ee64e7SAndroid Build Coastguard Worker               same time.
1031*86ee64e7SAndroid Build Coastguard Worker              */
1032*86ee64e7SAndroid Build Coastguard Worker             comb = crc_word_big(crc0 ^ words[0]);
1033*86ee64e7SAndroid Build Coastguard Worker #if N > 1
1034*86ee64e7SAndroid Build Coastguard Worker             comb = crc_word_big(crc1 ^ words[1] ^ comb);
1035*86ee64e7SAndroid Build Coastguard Worker #if N > 2
1036*86ee64e7SAndroid Build Coastguard Worker             comb = crc_word_big(crc2 ^ words[2] ^ comb);
1037*86ee64e7SAndroid Build Coastguard Worker #if N > 3
1038*86ee64e7SAndroid Build Coastguard Worker             comb = crc_word_big(crc3 ^ words[3] ^ comb);
1039*86ee64e7SAndroid Build Coastguard Worker #if N > 4
1040*86ee64e7SAndroid Build Coastguard Worker             comb = crc_word_big(crc4 ^ words[4] ^ comb);
1041*86ee64e7SAndroid Build Coastguard Worker #if N > 5
1042*86ee64e7SAndroid Build Coastguard Worker             comb = crc_word_big(crc5 ^ words[5] ^ comb);
1043*86ee64e7SAndroid Build Coastguard Worker #endif
1044*86ee64e7SAndroid Build Coastguard Worker #endif
1045*86ee64e7SAndroid Build Coastguard Worker #endif
1046*86ee64e7SAndroid Build Coastguard Worker #endif
1047*86ee64e7SAndroid Build Coastguard Worker #endif
1048*86ee64e7SAndroid Build Coastguard Worker             words += N;
1049*86ee64e7SAndroid Build Coastguard Worker             crc = byte_swap(comb);
1050*86ee64e7SAndroid Build Coastguard Worker         }
1051*86ee64e7SAndroid Build Coastguard Worker 
1052*86ee64e7SAndroid Build Coastguard Worker         /*
1053*86ee64e7SAndroid Build Coastguard Worker           Update the pointer to the remaining bytes to process.
1054*86ee64e7SAndroid Build Coastguard Worker          */
1055*86ee64e7SAndroid Build Coastguard Worker         buf = (unsigned char const *)words;
1056*86ee64e7SAndroid Build Coastguard Worker     }
1057*86ee64e7SAndroid Build Coastguard Worker 
1058*86ee64e7SAndroid Build Coastguard Worker #endif /* W */
1059*86ee64e7SAndroid Build Coastguard Worker 
1060*86ee64e7SAndroid Build Coastguard Worker     /* Complete the computation of the CRC on any remaining bytes. */
1061*86ee64e7SAndroid Build Coastguard Worker     while (len >= 8) {
1062*86ee64e7SAndroid Build Coastguard Worker         len -= 8;
1063*86ee64e7SAndroid Build Coastguard Worker         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1064*86ee64e7SAndroid Build Coastguard Worker         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1065*86ee64e7SAndroid Build Coastguard Worker         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1066*86ee64e7SAndroid Build Coastguard Worker         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1067*86ee64e7SAndroid Build Coastguard Worker         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1068*86ee64e7SAndroid Build Coastguard Worker         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1069*86ee64e7SAndroid Build Coastguard Worker         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1070*86ee64e7SAndroid Build Coastguard Worker         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1071*86ee64e7SAndroid Build Coastguard Worker     }
1072*86ee64e7SAndroid Build Coastguard Worker     while (len) {
1073*86ee64e7SAndroid Build Coastguard Worker         len--;
1074*86ee64e7SAndroid Build Coastguard Worker         crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
1075*86ee64e7SAndroid Build Coastguard Worker     }
1076*86ee64e7SAndroid Build Coastguard Worker 
1077*86ee64e7SAndroid Build Coastguard Worker     /* Return the CRC, post-conditioned. */
1078*86ee64e7SAndroid Build Coastguard Worker     return crc ^ 0xffffffff;
1079*86ee64e7SAndroid Build Coastguard Worker }
1080*86ee64e7SAndroid Build Coastguard Worker 
1081*86ee64e7SAndroid Build Coastguard Worker #endif
1082*86ee64e7SAndroid Build Coastguard Worker 
1083*86ee64e7SAndroid Build Coastguard Worker /* ========================================================================= */
crc32(unsigned long crc,const unsigned char FAR * buf,uInt len)1084*86ee64e7SAndroid Build Coastguard Worker unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf,
1085*86ee64e7SAndroid Build Coastguard Worker                             uInt len) {
1086*86ee64e7SAndroid Build Coastguard Worker     /* Some bots compile with optimizations disabled, others will emulate
1087*86ee64e7SAndroid Build Coastguard Worker      * ARM on x86 and other weird combinations.
1088*86ee64e7SAndroid Build Coastguard Worker      */
1089*86ee64e7SAndroid Build Coastguard Worker #if defined(CRC32_SIMD_SSE42_PCLMUL) || defined(CRC32_ARMV8_CRC32) \
1090*86ee64e7SAndroid Build Coastguard Worker     || defined(RISCV_RVV)
1091*86ee64e7SAndroid Build Coastguard Worker     /* We got to verify CPU features, so exploit the common usage pattern
1092*86ee64e7SAndroid Build Coastguard Worker      * of calling this function with Z_NULL for an initial valid crc value.
1093*86ee64e7SAndroid Build Coastguard Worker      * This allows to cache the result of the feature check and avoid extraneous
1094*86ee64e7SAndroid Build Coastguard Worker      * function calls.
1095*86ee64e7SAndroid Build Coastguard Worker      */
1096*86ee64e7SAndroid Build Coastguard Worker     if (buf == Z_NULL) {
1097*86ee64e7SAndroid Build Coastguard Worker         if (!len) /* Assume user is calling crc32(0, NULL, 0); */
1098*86ee64e7SAndroid Build Coastguard Worker             cpu_check_features();
1099*86ee64e7SAndroid Build Coastguard Worker         return 0UL;
1100*86ee64e7SAndroid Build Coastguard Worker     }
1101*86ee64e7SAndroid Build Coastguard Worker #endif
1102*86ee64e7SAndroid Build Coastguard Worker 
1103*86ee64e7SAndroid Build Coastguard Worker #if defined(CRC32_ARMV8_CRC32)
1104*86ee64e7SAndroid Build Coastguard Worker     if (arm_cpu_enable_crc32) {
1105*86ee64e7SAndroid Build Coastguard Worker #if defined(__aarch64__)
1106*86ee64e7SAndroid Build Coastguard Worker         /* PMULL is 64bit only, plus code needs at least a 64 bytes buffer. */
1107*86ee64e7SAndroid Build Coastguard Worker         if (arm_cpu_enable_pmull && (len > Z_CRC32_PMULL_MINIMUM_LENGTH)) {
1108*86ee64e7SAndroid Build Coastguard Worker             const size_t chunk_size = len & ~Z_CRC32_PMULL_CHUNKSIZE_MASK;
1109*86ee64e7SAndroid Build Coastguard Worker             crc = ~armv8_crc32_pmull_little(buf, chunk_size, ~(uint32_t)crc);
1110*86ee64e7SAndroid Build Coastguard Worker             /* Check remaining data. */
1111*86ee64e7SAndroid Build Coastguard Worker             len -= chunk_size;
1112*86ee64e7SAndroid Build Coastguard Worker             if (!len)
1113*86ee64e7SAndroid Build Coastguard Worker                 return crc;
1114*86ee64e7SAndroid Build Coastguard Worker 
1115*86ee64e7SAndroid Build Coastguard Worker             /* Fall through for the remaining data. */
1116*86ee64e7SAndroid Build Coastguard Worker             buf += chunk_size;
1117*86ee64e7SAndroid Build Coastguard Worker         }
1118*86ee64e7SAndroid Build Coastguard Worker #endif
1119*86ee64e7SAndroid Build Coastguard Worker         return armv8_crc32_little(buf, len, crc); /* Armv8@32bit or tail. */
1120*86ee64e7SAndroid Build Coastguard Worker     }
1121*86ee64e7SAndroid Build Coastguard Worker #endif
1122*86ee64e7SAndroid Build Coastguard Worker     return crc32_z(crc, buf, len); /* Armv7 or Armv8 w/o crypto extensions. */
1123*86ee64e7SAndroid Build Coastguard Worker }
1124*86ee64e7SAndroid Build Coastguard Worker 
1125*86ee64e7SAndroid Build Coastguard Worker /* ========================================================================= */
crc32_combine64(uLong crc1,uLong crc2,z_off64_t len2)1126*86ee64e7SAndroid Build Coastguard Worker uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) {
1127*86ee64e7SAndroid Build Coastguard Worker #ifdef DYNAMIC_CRC_TABLE
1128*86ee64e7SAndroid Build Coastguard Worker     once(&made, make_crc_table);
1129*86ee64e7SAndroid Build Coastguard Worker #endif /* DYNAMIC_CRC_TABLE */
1130*86ee64e7SAndroid Build Coastguard Worker     return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff);
1131*86ee64e7SAndroid Build Coastguard Worker }
1132*86ee64e7SAndroid Build Coastguard Worker 
1133*86ee64e7SAndroid Build Coastguard Worker /* ========================================================================= */
crc32_combine(uLong crc1,uLong crc2,z_off_t len2)1134*86ee64e7SAndroid Build Coastguard Worker uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) {
1135*86ee64e7SAndroid Build Coastguard Worker     return crc32_combine64(crc1, crc2, (z_off64_t)len2);
1136*86ee64e7SAndroid Build Coastguard Worker }
1137*86ee64e7SAndroid Build Coastguard Worker /* ========================================================================= */
crc32_combine_gen64(z_off64_t len2)1138*86ee64e7SAndroid Build Coastguard Worker uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) {
1139*86ee64e7SAndroid Build Coastguard Worker #ifdef DYNAMIC_CRC_TABLE
1140*86ee64e7SAndroid Build Coastguard Worker     once(&made, make_crc_table);
1141*86ee64e7SAndroid Build Coastguard Worker #endif /* DYNAMIC_CRC_TABLE */
1142*86ee64e7SAndroid Build Coastguard Worker     return x2nmodp(len2, 3);
1143*86ee64e7SAndroid Build Coastguard Worker }
1144*86ee64e7SAndroid Build Coastguard Worker 
1145*86ee64e7SAndroid Build Coastguard Worker /* ========================================================================= */
crc32_combine_gen(z_off_t len2)1146*86ee64e7SAndroid Build Coastguard Worker uLong ZEXPORT crc32_combine_gen(z_off_t len2) {
1147*86ee64e7SAndroid Build Coastguard Worker     return crc32_combine_gen64((z_off64_t)len2);
1148*86ee64e7SAndroid Build Coastguard Worker }
1149*86ee64e7SAndroid Build Coastguard Worker 
1150*86ee64e7SAndroid Build Coastguard Worker /* ========================================================================= */
crc32_combine_op(uLong crc1,uLong crc2,uLong op)1151*86ee64e7SAndroid Build Coastguard Worker uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) {
1152*86ee64e7SAndroid Build Coastguard Worker     return multmodp(op, crc1) ^ (crc2 & 0xffffffff);
1153*86ee64e7SAndroid Build Coastguard Worker }
1154*86ee64e7SAndroid Build Coastguard Worker 
crc_reset(deflate_state * const s)1155*86ee64e7SAndroid Build Coastguard Worker ZLIB_INTERNAL void crc_reset(deflate_state *const s)
1156*86ee64e7SAndroid Build Coastguard Worker {
1157*86ee64e7SAndroid Build Coastguard Worker #ifdef CRC32_SIMD_SSE42_PCLMUL
1158*86ee64e7SAndroid Build Coastguard Worker     if (x86_cpu_enable_simd) {
1159*86ee64e7SAndroid Build Coastguard Worker         crc_fold_init(s);
1160*86ee64e7SAndroid Build Coastguard Worker         return;
1161*86ee64e7SAndroid Build Coastguard Worker     }
1162*86ee64e7SAndroid Build Coastguard Worker #endif
1163*86ee64e7SAndroid Build Coastguard Worker     s->strm->adler = crc32(0L, Z_NULL, 0);
1164*86ee64e7SAndroid Build Coastguard Worker }
1165*86ee64e7SAndroid Build Coastguard Worker 
crc_finalize(deflate_state * const s)1166*86ee64e7SAndroid Build Coastguard Worker ZLIB_INTERNAL void crc_finalize(deflate_state *const s)
1167*86ee64e7SAndroid Build Coastguard Worker {
1168*86ee64e7SAndroid Build Coastguard Worker #ifdef CRC32_SIMD_SSE42_PCLMUL
1169*86ee64e7SAndroid Build Coastguard Worker     if (x86_cpu_enable_simd)
1170*86ee64e7SAndroid Build Coastguard Worker         s->strm->adler = crc_fold_512to32(s);
1171*86ee64e7SAndroid Build Coastguard Worker #endif
1172*86ee64e7SAndroid Build Coastguard Worker }
1173*86ee64e7SAndroid Build Coastguard Worker 
copy_with_crc(z_streamp strm,Bytef * dst,long size)1174*86ee64e7SAndroid Build Coastguard Worker ZLIB_INTERNAL void copy_with_crc(z_streamp strm, Bytef *dst, long size)
1175*86ee64e7SAndroid Build Coastguard Worker {
1176*86ee64e7SAndroid Build Coastguard Worker #ifdef CRC32_SIMD_SSE42_PCLMUL
1177*86ee64e7SAndroid Build Coastguard Worker     if (x86_cpu_enable_simd) {
1178*86ee64e7SAndroid Build Coastguard Worker         crc_fold_copy(strm->state, dst, strm->next_in, size);
1179*86ee64e7SAndroid Build Coastguard Worker         return;
1180*86ee64e7SAndroid Build Coastguard Worker     }
1181*86ee64e7SAndroid Build Coastguard Worker #endif
1182*86ee64e7SAndroid Build Coastguard Worker     zmemcpy(dst, strm->next_in, size);
1183*86ee64e7SAndroid Build Coastguard Worker     strm->adler = crc32(strm->adler, dst, size);
1184*86ee64e7SAndroid Build Coastguard Worker }
1185