From: Daniel Black Date: Fri, 16 Feb 2018 10:41:44 +0000 (+1100) Subject: wrap crc32 in functable (#145) X-Git-Tag: 1.9.9-b1~647 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9ec0d91a0178d61e0cde400959156b85718438ad;p=thirdparty%2Fzlib-ng.git wrap crc32 in functable (#145) * wrap crc32 in functable * change internal crc32 api to use uint64_t rather than size_t for length --- diff --git a/arch/aarch64/crc32_acle.c b/arch/aarch64/crc32_acle.c index 4e1de9a8..f4ea283e 100644 --- a/arch/aarch64/crc32_acle.c +++ b/arch/aarch64/crc32_acle.c @@ -12,7 +12,7 @@ # include #endif -uint32_t crc32_acle(uint32_t crc, const unsigned char *buf, size_t len) { +uint32_t crc32_acle(uint32_t crc, const unsigned char *buf, uint64_t len) { register uint32_t c; register const uint16_t *buf2; register const uint32_t *buf4; diff --git a/arch/arm/crc32_acle.c b/arch/arm/crc32_acle.c index d8a35368..5fa3c833 100644 --- a/arch/arm/crc32_acle.c +++ b/arch/arm/crc32_acle.c @@ -12,7 +12,7 @@ # include #endif -uint32_t crc32_acle(uint32_t crc, const unsigned char *buf, size_t len) { +uint32_t crc32_acle(uint32_t crc, const unsigned char *buf, uint64_t len) { register uint32_t c; register const uint16_t *buf2; register const uint32_t *buf4; diff --git a/crc32.c b/crc32.c index 88e4c5b5..8883358b 100644 --- a/crc32.c +++ b/crc32.c @@ -11,40 +11,7 @@ /* @(#) $Id$ */ -#ifdef __MINGW32__ -# include -#elif defined(WIN32) || defined(_WIN32) -# define LITTLE_ENDIAN 1234 -# define BIG_ENDIAN 4321 -# if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64) || defined (_M_ARM) -# define BYTE_ORDER LITTLE_ENDIAN -# else -# error Unknown endianness! -# endif -#elif defined(__linux__) -# include -#elif defined(__APPLE__) || defined(__arm__) || defined(__aarch64__) -# include -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) -# include -#elif defined(__sun) || defined(sun) -# include -# if !defined(LITTLE_ENDIAN) -# define LITTLE_ENDIAN 4321 -# endif -# if !defined(BIG_ENDIAN) -# define BIG_ENDIAN 1234 -# endif -# if !defined(BYTE_ORDER) -# if defined(_BIG_ENDIAN) -# define BYTE_ORDER BIG_ENDIAN -# else -# define BYTE_ORDER LITTLE_ENDIAN -# endif -# endif -#else -# include -#endif +# include "gzendian.h" /* Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore @@ -64,18 +31,8 @@ #endif /* MAKECRCH */ #include "deflate.h" +#include "functable.h" -ZLIB_INTERNAL uint32_t crc32_generic(uint32_t, const unsigned char *, z_off64_t); - -#ifdef __ARM_FEATURE_CRC32 -extern uint32_t crc32_acle(uint32_t, const unsigned char *, z_off64_t); -#endif - -#if BYTE_ORDER == LITTLE_ENDIAN -ZLIB_INTERNAL uint32_t crc32_little(uint32_t, const unsigned char *, size_t); -#elif BYTE_ORDER == BIG_ENDIAN -ZLIB_INTERNAL uint32_t crc32_big(uint32_t, const unsigned char *, size_t); -#endif /* Local functions for crc concatenation */ static uint32_t gf2_matrix_times(uint32_t *mat, uint32_t vec); @@ -216,33 +173,15 @@ const uint32_t * ZEXPORT PREFIX(get_crc_table)(void) { uint32_t ZEXPORT PREFIX(crc32_z)(uint32_t crc, const unsigned char *buf, size_t len) { if (buf == NULL) return 0; -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - - if (sizeof(void *) == sizeof(ptrdiff_t)) { -#if BYTE_ORDER == LITTLE_ENDIAN -# if __ARM_FEATURE_CRC32 - return crc32_acle(crc, buf, len); -# else - return crc32_little(crc, buf, len); -# endif -#elif BYTE_ORDER == BIG_ENDIAN - return crc32_big(crc, buf, len); -#endif - } - - return crc32_generic(crc, buf, len); + return functable.crc32(crc, buf, len); } - /* ========================================================================= */ #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 #define DO4 DO1; DO1; DO1; DO1 /* ========================================================================= */ -ZLIB_INTERNAL uint32_t crc32_generic(uint32_t crc, const unsigned char *buf, z_off64_t len) +ZLIB_INTERNAL uint32_t crc32_generic(uint32_t crc, const unsigned char *buf, uint64_t len) { crc = crc ^ 0xffffffff; @@ -288,7 +227,7 @@ uint32_t ZEXPORT PREFIX(crc32)(uint32_t crc, const unsigned char *buf, uint32_t #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 /* ========================================================================= */ -ZLIB_INTERNAL uint32_t crc32_little(uint32_t crc, const unsigned char *buf, size_t len) { +ZLIB_INTERNAL uint32_t crc32_little(uint32_t crc, const unsigned char *buf, uint64_t len) { register uint32_t c; register const uint32_t *buf4; @@ -330,7 +269,7 @@ ZLIB_INTERNAL uint32_t crc32_little(uint32_t crc, const unsigned char *buf, size #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 /* ========================================================================= */ -ZLIB_INTERNAL uint32_t crc32_big(uint32_t crc, const unsigned char *buf, size_t len) { +ZLIB_INTERNAL uint32_t crc32_big(uint32_t crc, const unsigned char *buf, uint64_t len) { register uint32_t c; register const uint32_t *buf4; diff --git a/functable.c b/functable.c index 06dc41fb..3921fc9d 100644 --- a/functable.c +++ b/functable.c @@ -7,6 +7,8 @@ #include "deflate.h" #include "deflate_p.h" +#include "gzendian.h" + #if defined(X86_CPUID) # include "arch/x86/x86.h" #endif @@ -32,13 +34,26 @@ extern uint32_t adler32_c(uint32_t adler, const unsigned char *buf, size_t len); extern uint32_t adler32_neon(uint32_t adler, const unsigned char *buf, size_t len); #endif +ZLIB_INTERNAL uint32_t crc32_generic(uint32_t, const unsigned char *, uint64_t); + +#ifdef __ARM_FEATURE_CRC32 +extern uint32_t crc32_acle(uint32_t, const unsigned char *, uint64_t); +#endif + +#if BYTE_ORDER == LITTLE_ENDIAN +extern uint32_t crc32_little(uint32_t, const unsigned char *, uint64_t); +#elif BYTE_ORDER == BIG_ENDIAN +extern uint32_t crc32_big(uint32_t, const unsigned char *, uint64_t); +#endif + /* stub definitions */ ZLIB_INTERNAL Pos insert_string_stub(deflate_state *const s, const Pos str, unsigned int count); ZLIB_INTERNAL void fill_window_stub(deflate_state *s); ZLIB_INTERNAL uint32_t adler32_stub(uint32_t adler, const unsigned char *buf, size_t len); +ZLIB_INTERNAL uint32_t crc32_stub(uint32_t crc, const unsigned char *buf, uint64_t len); /* functable init */ -ZLIB_INTERNAL struct functable_s functable = {fill_window_stub,insert_string_stub,adler32_stub}; +ZLIB_INTERNAL struct functable_s functable = {fill_window_stub,insert_string_stub,adler32_stub,crc32_stub}; /* stub functions */ @@ -82,3 +97,34 @@ ZLIB_INTERNAL uint32_t adler32_stub(uint32_t adler, const unsigned char *buf, si return functable.adler32(adler, buf, len); } + +ZLIB_INTERNAL uint32_t crc32_stub(uint32_t crc, const unsigned char *buf, uint64_t len) { + + + Assert(sizeof(uint64_t) >= sizeof(size_t), + "crc32_z takes size_t but internally we have a uint64_t len"); +/* return a function pointer for optimized arches here after a capability test */ + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + + if (sizeof(void *) == sizeof(ptrdiff_t)) { +#if BYTE_ORDER == LITTLE_ENDIAN +# if __ARM_FEATURE_CRC32 + functable.crc32=crc32_acle; +# else + functable.crc32=crc32_little; +# endif +#elif BYTE_ORDER == BIG_ENDIAN + functable.crc32=crc32_big; +#else +# error No endian defined +#endif + } else { + functable.crc32=crc32_generic; + } + + return functable.crc32(crc, buf, len); +} diff --git a/functable.h b/functable.h index 4e6f53ee..a8e8b706 100644 --- a/functable.h +++ b/functable.h @@ -12,6 +12,7 @@ struct functable_s { void (* fill_window) (deflate_state *s); Pos (* insert_string) (deflate_state *const s, const Pos str, unsigned int count); uint32_t (* adler32) (uint32_t adler, const unsigned char *buf, size_t len); + uint32_t (* crc32) (uint32_t crc, const unsigned char *buf, uint64_t len); }; ZLIB_INTERNAL extern struct functable_s functable; diff --git a/gzendian.h b/gzendian.h new file mode 100644 index 00000000..267467d1 --- /dev/null +++ b/gzendian.h @@ -0,0 +1,41 @@ +/* gzendian.h -- define BYTE_ORDER for endian tests + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ENDIAN_H_ +#define ENDIAN_H_ + +#ifdef __MINGW32__ +# include +#elif defined(WIN32) || defined(_WIN32) +# define LITTLE_ENDIAN 1234 +# define BIG_ENDIAN 4321 +# if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64) || defined (_M_ARM) +# define BYTE_ORDER LITTLE_ENDIAN +# else +# error Unknown endianness! +# endif +#elif defined(__APPLE__) || defined(__arm__) || defined(__aarch64__) +# include +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) +# include +#elif defined(__sun) || defined(sun) +# include +# if !defined(LITTLE_ENDIAN) +# define LITTLE_ENDIAN 4321 +# endif +# if !defined(BIG_ENDIAN) +# define BIG_ENDIAN 1234 +# endif +# if !defined(BYTE_ORDER) +# if defined(_BIG_ENDIAN) +# define BYTE_ORDER BIG_ENDIAN +# else +# define BYTE_ORDER LITTLE_ENDIAN +# endif +# endif +#else +# include +#endif + +#endif