endif()
set(CMAKE_REQUIRED_FLAGS)
+#
+# check for __builtin_bitreverse16() support in the compiler
+#
+set(CMAKE_REQUIRED_FLAGS ${ZNOLTOFLAG})
+check_c_source_compiles(
+ "int main(void) {
+ unsigned short val = 0x1234;
+ unsigned short test = __builtin_bitreverse16(val);
+ (void)test;
+ return 0;
+ }"
+ HAVE_BUILTIN_BITREVERSE16
+)
+if(HAVE_BUILTIN_BITREVERSE16)
+ add_definitions(-DHAVE_BUILTIN_BITREVERSE16)
+endif()
+set(CMAKE_REQUIRED_FLAGS)
+
#
# check for ptrdiff_t support
#
echo "Checking for __builtin_ctzll ... No." | tee -a configure.log
fi
+# Check for __builtin_bitreverse16() support in compiler
+cat > $test.c << EOF
+unsigned short f(unsigned short x) { return __builtin_bitreverse16(x); }
+int main(void) { return 0; }
+EOF
+if try ${CC} ${CFLAGS} $test.c $LDSHAREDLIBC; then
+ echo "Checking for __builtin_bitreverse16 ... Yes." | tee -a configure.log
+ CFLAGS="$CFLAGS -DHAVE_BUILTIN_BITREVERSE16"
+ SFLAGS="$SFLAGS -DHAVE_BUILTIN_BITREVERSE16"
+else
+ echo "Checking for __builtin_bitreverse16 ... No." | tee -a configure.log
+fi
+
check_avx2_intrinsics() {
# Check whether compiler supports AVX2 intrinsics
cat > $test.c << EOF
#define DEFLATE_P_H
#include "functable.h"
+#include "fallback_builtins.h"
/* Forward declare common non-inlined functions declared in deflate.c */
/* ===========================================================================
* Reverse the first len bits of a code using bit manipulation
*/
-static inline uint16_t bi_reverse(unsigned code, int len) {
+Z_FORCEINLINE static uint16_t bi_reverse(unsigned code, int len) {
/* code: the value to invert */
/* len: its bit length */
Assert(len >= 1 && len <= 15, "code length must be 1-15");
-#define bitrev8(b) \
- (uint8_t)((((uint8_t)(b) * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32)
- return (bitrev8(code >> 8) | (uint16_t)bitrev8(code) << 8) >> (16 - len);
+ return __builtin_bitreverse16((uint16_t)code) >> (16 - len);
}
/* ===========================================================================
* If tzcnt instruction is not supported, the cpu will itself execute bsf instead.
* Performance tzcnt/bsf is identical on Intel cpu, tzcnt is faster than bsf on AMD cpu.
*/
-static __forceinline int __builtin_ctz(unsigned int value) {
+Z_FORCEINLINE static int __builtin_ctz(unsigned int value) {
Assert(value != 0, "Invalid input value: 0");
# if defined(X86_FEATURES) && !(_MSC_VER < 1700)
return (int)_tzcnt_u32(value);
/* This is not a general purpose replacement for __builtin_ctzll. The function expects that value is != 0.
* Because of that assumption trailing_zero is not initialized and the return value is not checked.
*/
-static __forceinline int __builtin_ctzll(unsigned long long value) {
+Z_FORCEINLINE static int __builtin_ctzll(unsigned long long value) {
Assert(value != 0, "Invalid input value: 0");
# if defined(X86_FEATURES) && !(_MSC_VER < 1700)
return (int)_tzcnt_u64(value);
#endif // Microsoft AMD64/IA64/x86/ARM/ARM64 test
#endif // _MSC_VER & !clang
+#ifndef HAVE_BUILTIN_BITREVERSE16
+/* Bit reversal for 8-bit values using multiplication method */
+#define bitrev8(value) \
+ (uint8_t)((((uint8_t)(value) * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32)
+
+/* General purpose bit reversal for 16-bit values */
+Z_FORCEINLINE static uint16_t __builtin_bitreverse16(uint16_t value) {
+ return ((bitrev8(value >> 8) | (uint16_t)bitrev8(value) << 8));
+}
+#define HAVE_BUILTIN_BITREVERSE16
+#endif
+
#endif // include guard FALLBACK_BUILTINS_H