11/* crc32.c -- compute the CRC-32 of a data stream
2- * Copyright (C) 1995-2022 Mark Adler
2+ * Copyright (C) 1995-2026 Mark Adler
33 * For conditions of distribution and use, see copyright notice in zlib.h
44 *
55 * This interleaved implementation of a CRC makes use of pipelined multiple
2424# include <stdio.h>
2525# ifndef DYNAMIC_CRC_TABLE
2626# define DYNAMIC_CRC_TABLE
27- # endif /* !DYNAMIC_CRC_TABLE */
28- #endif /* MAKECRCH */
27+ # endif
28+ #endif
29+ #ifdef DYNAMIC_CRC_TABLE
30+ # define Z_ONCE
31+ #endif
2932
3033#include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */
3134
35+ #ifdef HAVE_S390X_VX
36+ # include "contrib/crc32vx/crc32_vx_hooks.h"
37+ #endif
38+
3239 /*
3340 A CRC of a message is computed on N braids of words in the message, where
3441 each word consists of W bytes (4 or 8). If N is 3, for example, then three
99106#endif
100107
101108/* If available, use the ARM processor CRC32 instruction. */
102- #if defined(__aarch64__ ) && defined(__ARM_FEATURE_CRC32 ) && W == 8
109+ #if defined(__aarch64__ ) && defined(__ARM_FEATURE_CRC32 ) && \
110+ defined(W ) && W == 8
103111# define ARMCRC32
104112#endif
105113
@@ -152,10 +160,10 @@ local z_word_t byte_swap(z_word_t word) {
152160 Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,
153161 reflected. For speed, this requires that a not be zero.
154162 */
155- local z_crc_t multmodp (z_crc_t a , z_crc_t b ) {
156- z_crc_t m , p ;
163+ local uLong multmodp (uLong a , uLong b ) {
164+ uLong m , p ;
157165
158- m = (z_crc_t )1 << 31 ;
166+ m = (uLong )1 << 31 ;
159167 p = 0 ;
160168 for (;;) {
161169 if (a & m ) {
@@ -171,12 +179,12 @@ local z_crc_t multmodp(z_crc_t a, z_crc_t b) {
171179
172180/*
173181 Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been
174- initialized.
182+ initialized. n must not be negative.
175183 */
176- local z_crc_t x2nmodp (z_off64_t n , unsigned k ) {
177- z_crc_t p ;
184+ local uLong x2nmodp (z_off64_t n , unsigned k ) {
185+ uLong p ;
178186
179- p = (z_crc_t )1 << 31 ; /* x^0 == 1 */
187+ p = (uLong )1 << 31 ; /* x^0 == 1 */
180188 while (n ) {
181189 if (n & 1 )
182190 p = multmodp (x2n_table [k & 31 ], p );
@@ -204,83 +212,8 @@ local z_crc_t FAR crc_table[256];
204212 local void write_table64 (FILE * , const z_word_t FAR * , int );
205213#endif /* MAKECRCH */
206214
207- /*
208- Define a once() function depending on the availability of atomics. If this is
209- compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in
210- multiple threads, and if atomics are not available, then get_crc_table() must
211- be called to initialize the tables and must return before any threads are
212- allowed to compute or combine CRCs.
213- */
214-
215- /* Definition of once functionality. */
216- typedef struct once_s once_t ;
217-
218- /* Check for the availability of atomics. */
219- #if defined(__STDC__ ) && __STDC_VERSION__ >= 201112L && \
220- !defined(__STDC_NO_ATOMICS__ )
221-
222- #include <stdatomic.h>
223-
224- /* Structure for once(), which must be initialized with ONCE_INIT. */
225- struct once_s {
226- atomic_flag begun ;
227- atomic_int done ;
228- };
229- #define ONCE_INIT {ATOMIC_FLAG_INIT, 0}
230-
231- /*
232- Run the provided init() function exactly once, even if multiple threads
233- invoke once() at the same time. The state must be a once_t initialized with
234- ONCE_INIT.
235- */
236- local void once (once_t * state , void (* init )(void )) {
237- if (!atomic_load (& state -> done )) {
238- if (atomic_flag_test_and_set (& state -> begun ))
239- while (!atomic_load (& state -> done ))
240- ;
241- else {
242- init ();
243- atomic_store (& state -> done , 1 );
244- }
245- }
246- }
247-
248- #else /* no atomics */
249-
250- /* Structure for once(), which must be initialized with ONCE_INIT. */
251- struct once_s {
252- volatile int begun ;
253- volatile int done ;
254- };
255- #define ONCE_INIT {0, 0}
256-
257- /* Test and set. Alas, not atomic, but tries to minimize the period of
258- vulnerability. */
259- local int test_and_set (int volatile * flag ) {
260- int was ;
261-
262- was = * flag ;
263- * flag = 1 ;
264- return was ;
265- }
266-
267- /* Run the provided init() function once. This is not thread-safe. */
268- local void once (once_t * state , void (* init )(void )) {
269- if (!state -> done ) {
270- if (test_and_set (& state -> begun ))
271- while (!state -> done )
272- ;
273- else {
274- init ();
275- state -> done = 1 ;
276- }
277- }
278- }
279-
280- #endif
281-
282215/* State for once(). */
283- local once_t made = ONCE_INIT ;
216+ local z_once_t made = Z_ONCE_INIT ;
284217
285218/*
286219 Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
@@ -326,7 +259,7 @@ local void make_crc_table(void) {
326259 p = (z_crc_t )1 << 30 ; /* x^1 */
327260 x2n_table [0 ] = p ;
328261 for (n = 1 ; n < 32 ; n ++ )
329- x2n_table [n ] = p = multmodp (p , p );
262+ x2n_table [n ] = p = ( z_crc_t ) multmodp (p , p );
330263
331264#ifdef W
332265 /* initialize the braiding tables -- needs x2n_table[] */
@@ -529,11 +462,11 @@ local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) {
529462 int k ;
530463 z_crc_t i , p , q ;
531464 for (k = 0 ; k < w ; k ++ ) {
532- p = x2nmodp ((n * w + 3 - k ) << 3 , 0 );
465+ p = ( z_crc_t ) x2nmodp ((n * w + 3 - k ) << 3 , 0 );
533466 ltl [k ][0 ] = 0 ;
534467 big [w - 1 - k ][0 ] = 0 ;
535468 for (i = 1 ; i < 256 ; i ++ ) {
536- ltl [k ][i ] = q = multmodp (i << 24 , p );
469+ ltl [k ][i ] = q = ( z_crc_t ) multmodp (i << 24 , p );
537470 big [w - 1 - k ][i ] = byte_swap (q );
538471 }
539472 }
@@ -548,7 +481,7 @@ local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) {
548481 */
549482const z_crc_t FAR * ZEXPORT get_crc_table (void ) {
550483#ifdef DYNAMIC_CRC_TABLE
551- once (& made , make_crc_table );
484+ z_once (& made , make_crc_table );
552485#endif /* DYNAMIC_CRC_TABLE */
553486 return (const z_crc_t FAR * )crc_table ;
554487}
@@ -572,9 +505,8 @@ const z_crc_t FAR * ZEXPORT get_crc_table(void) {
572505#define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */
573506#define Z_BATCH_MIN 800 /* fewest words in a final batch */
574507
575- unsigned long ZEXPORT crc32_z (unsigned long crc , const unsigned char FAR * buf ,
576- z_size_t len ) {
577- z_crc_t val ;
508+ uLong ZEXPORT crc32_z (uLong crc , const unsigned char FAR * buf , z_size_t len ) {
509+ uLong val ;
578510 z_word_t crc1 , crc2 ;
579511 const z_word_t * word ;
580512 z_word_t val0 , val1 , val2 ;
@@ -585,7 +517,7 @@ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
585517 if (buf == Z_NULL ) return 0 ;
586518
587519#ifdef DYNAMIC_CRC_TABLE
588- once (& made , make_crc_table );
520+ z_once (& made , make_crc_table );
589521#endif /* DYNAMIC_CRC_TABLE */
590522
591523 /* Pre-condition the CRC */
@@ -640,7 +572,7 @@ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
640572 }
641573 word += 3 * last ;
642574 num -= 3 * last ;
643- val = x2nmodp (last , 6 );
575+ val = x2nmodp (( int ) last , 6 );
644576 crc = multmodp (val , crc ) ^ crc1 ;
645577 crc = multmodp (val , crc ) ^ crc2 ;
646578 }
@@ -691,13 +623,12 @@ local z_word_t crc_word_big(z_word_t data) {
691623#endif
692624
693625/* ========================================================================= */
694- unsigned long ZEXPORT crc32_z (unsigned long crc , const unsigned char FAR * buf ,
695- z_size_t len ) {
626+ uLong ZEXPORT crc32_z (uLong crc , const unsigned char FAR * buf , z_size_t len ) {
696627 /* Return initial CRC, if requested. */
697628 if (buf == Z_NULL ) return 0 ;
698629
699630#ifdef DYNAMIC_CRC_TABLE
700- once (& made , make_crc_table );
631+ z_once (& made , make_crc_table );
701632#endif /* DYNAMIC_CRC_TABLE */
702633
703634 /* Pre-condition the CRC */
@@ -1012,38 +943,41 @@ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
1012943#endif
1013944
1014945/* ========================================================================= */
1015- unsigned long ZEXPORT crc32 (unsigned long crc , const unsigned char FAR * buf ,
1016- uInt len ) {
946+ uLong ZEXPORT crc32 (uLong crc , const unsigned char FAR * buf , uInt len ) {
947+ #ifdef HAVE_S390X_VX
948+ return crc32_z_hook (crc , buf , len );
949+ #endif
1017950 return crc32_z (crc , buf , len );
1018951}
1019952
1020953/* ========================================================================= */
1021- uLong ZEXPORT crc32_combine64 (uLong crc1 , uLong crc2 , z_off64_t len2 ) {
954+ uLong ZEXPORT crc32_combine_gen64 (z_off64_t len2 ) {
955+ if (len2 < 0 )
956+ return 0 ;
1022957#ifdef DYNAMIC_CRC_TABLE
1023- once (& made , make_crc_table );
958+ z_once (& made , make_crc_table );
1024959#endif /* DYNAMIC_CRC_TABLE */
1025- return multmodp ( x2nmodp (len2 , 3 ), crc1 ) ^ ( crc2 & 0xffffffff );
960+ return x2nmodp (len2 , 3 );
1026961}
1027962
1028963/* ========================================================================= */
1029- uLong ZEXPORT crc32_combine ( uLong crc1 , uLong crc2 , z_off_t len2 ) {
1030- return crc32_combine64 ( crc1 , crc2 , (z_off64_t )len2 );
964+ uLong ZEXPORT crc32_combine_gen ( z_off_t len2 ) {
965+ return crc32_combine_gen64 ( (z_off64_t )len2 );
1031966}
1032967
1033968/* ========================================================================= */
1034- uLong ZEXPORT crc32_combine_gen64 (z_off64_t len2 ) {
1035- #ifdef DYNAMIC_CRC_TABLE
1036- once (& made , make_crc_table );
1037- #endif /* DYNAMIC_CRC_TABLE */
1038- return x2nmodp (len2 , 3 );
969+ uLong ZEXPORT crc32_combine_op (uLong crc1 , uLong crc2 , uLong op ) {
970+ if (op == 0 )
971+ return 0 ;
972+ return multmodp (op , crc1 & 0xffffffff ) ^ (crc2 & 0xffffffff );
1039973}
1040974
1041975/* ========================================================================= */
1042- uLong ZEXPORT crc32_combine_gen ( z_off_t len2 ) {
1043- return crc32_combine_gen64 (( z_off64_t ) len2 );
976+ uLong ZEXPORT crc32_combine64 ( uLong crc1 , uLong crc2 , z_off64_t len2 ) {
977+ return crc32_combine_op ( crc1 , crc2 , crc32_combine_gen64 (len2 ) );
1044978}
1045979
1046980/* ========================================================================= */
1047- uLong ZEXPORT crc32_combine_op (uLong crc1 , uLong crc2 , uLong op ) {
1048- return multmodp ( op , crc1 ) ^ ( crc2 & 0xffffffff );
981+ uLong ZEXPORT crc32_combine (uLong crc1 , uLong crc2 , z_off_t len2 ) {
982+ return crc32_combine64 ( crc1 , crc2 , ( z_off64_t ) len2 );
1049983}
0 commit comments