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