mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 17:51:28 +00:00
134 lines
4.2 KiB
C
134 lines
4.2 KiB
C
/* functable.c -- Choose relevant optimized functions at runtime
|
|
* Copyright (C) 2017 Hans Kristian Rosbach
|
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
|
*/
|
|
|
|
#include "zbuild.h"
|
|
#include "functable.h"
|
|
#include "deflate.h"
|
|
#include "deflate_p.h"
|
|
|
|
#include "gzendian.h"
|
|
|
|
/* insert_string */
|
|
#ifdef X86_SSE4_2_CRC_HASH
|
|
extern Pos insert_string_sse(deflate_state *const s, const Pos str, unsigned int count);
|
|
#elif defined(ARM_ACLE_CRC_HASH)
|
|
extern Pos insert_string_acle(deflate_state *const s, const Pos str, unsigned int count);
|
|
#endif
|
|
|
|
/* fill_window */
|
|
#ifdef X86_SSE2
|
|
extern void fill_window_sse(deflate_state *s);
|
|
#elif defined(__arm__) || defined(__aarch64__) || defined(_M_ARM)
|
|
extern void fill_window_arm(deflate_state *s);
|
|
#endif
|
|
|
|
/* adler32 */
|
|
extern uint32_t adler32_c(uint32_t adler, const unsigned char *buf, size_t len);
|
|
#if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && defined(ARM_NEON_ADLER32)
|
|
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 DYNAMIC_CRC_TABLE
|
|
extern volatile int crc_table_empty;
|
|
extern void make_crc_table(void);
|
|
#endif
|
|
|
|
#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 __thread struct functable_s functable = {fill_window_stub,insert_string_stub,adler32_stub,crc32_stub};
|
|
|
|
|
|
/* stub functions */
|
|
ZLIB_INTERNAL Pos insert_string_stub(deflate_state *const s, const Pos str, unsigned int count) {
|
|
// Initialize default
|
|
functable.insert_string=&insert_string_c;
|
|
|
|
#ifdef X86_SSE4_2_CRC_HASH
|
|
if (x86_cpu_has_sse42)
|
|
functable.insert_string=&insert_string_sse;
|
|
#elif defined(__ARM_FEATURE_CRC32) && defined(ARM_ACLE_CRC_HASH)
|
|
if (arm_cpu_has_crc32)
|
|
functable.insert_string=&insert_string_acle;
|
|
#endif
|
|
|
|
return functable.insert_string(s, str, count);
|
|
}
|
|
|
|
ZLIB_INTERNAL void fill_window_stub(deflate_state *s) {
|
|
// Initialize default
|
|
functable.fill_window=&fill_window_c;
|
|
|
|
#ifdef X86_SSE2
|
|
# if !defined(__x86_64__) && !defined(_M_X64) && !defined(X86_NOCHECK_SSE2)
|
|
if (x86_cpu_has_sse2)
|
|
# endif
|
|
functable.fill_window=&fill_window_sse;
|
|
#elif defined(__arm__) || defined(__aarch64__) || defined(_M_ARM)
|
|
functable.fill_window=&fill_window_arm;
|
|
#endif
|
|
|
|
functable.fill_window(s);
|
|
}
|
|
|
|
ZLIB_INTERNAL uint32_t adler32_stub(uint32_t adler, const unsigned char *buf, size_t len) {
|
|
// Initialize default
|
|
functable.adler32=&adler32_c;
|
|
|
|
#if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && defined(ARM_NEON_ADLER32)
|
|
if (arm_cpu_has_neon)
|
|
functable.adler32=&adler32_neon;
|
|
#endif
|
|
|
|
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
|
|
functable.crc32=crc32_little;
|
|
# if defined(__ARM_FEATURE_CRC32) && defined(ARM_ACLE_CRC_HASH)
|
|
if (arm_cpu_has_crc32)
|
|
functable.crc32=crc32_acle;
|
|
# 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);
|
|
}
|