From 31854403b3398e1c7fa642dca9d2dfe02b171371 Mon Sep 17 00:00:00 2001 From: Kenta Murata Date: Tue, 5 Jan 2021 08:12:39 +0900 Subject: [ruby/bigdecimal] Check the function availabilities separately https://github.com/ruby/bigdecimal/commit/cf839a34c8 https://github.com/ruby/bigdecimal/commit/75db4dabb9 --- ext/bigdecimal/bits.h | 18 +++++++++--------- ext/bigdecimal/extconf.rb | 13 ++++++++++--- 2 files changed, 19 insertions(+), 12 deletions(-) (limited to 'ext/bigdecimal') diff --git a/ext/bigdecimal/bits.h b/ext/bigdecimal/bits.h index 3835fe3a4d..6e1e4776e3 100644 --- a/ext/bigdecimal/bits.h +++ b/ext/bigdecimal/bits.h @@ -5,8 +5,8 @@ #include "static_assert.h" #if defined(__x86_64__) && defined(HAVE_X86INTRIN_H) -# include /* for _lzcnt_u64 */ -#elif defined(_MSC_VER) && _MSC_VER >= 1310 +# include /* for _lzcnt_u64, etc. */ +#elif defined(_MSC_VER) && defined(HAVE_INTRIN_H) # include /* for the following intrinsics */ #endif @@ -48,17 +48,17 @@ static inline unsigned nlz_int128(uint128_t x); static inline unsigned int nlz_int32(uint32_t x) { -#if defined(_MSC_VER) && defined(__AVX2__) +#if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT) /* Note: It seems there is no such thing like __LZCNT__ predefined in MSVC. * AMD CPUs have had this instruction for decades (since K10) but for * Intel, Haswell is the oldest one. We need to use __AVX2__ for maximum * safety. */ return (unsigned int)__lzcnt(x); -#elif defined(__x86_64__) && defined(__LZCNT__) /* && ! defined(MJIT_HEADER) */ +#elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U32) return (unsigned int)_lzcnt_u32(x); -#elif defined(_MSC_VER) && _MSC_VER >= 1400 /* &&! defined(__AVX2__) */ +#elif defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE) unsigned long r; return _BitScanReverse(&r, x) ? (31 - (int)r) : 32; @@ -81,17 +81,17 @@ nlz_int32(uint32_t x) static inline unsigned int nlz_int64(uint64_t x) { -#if defined(_MSC_VER) && defined(__AVX2__) +#if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT64) return (unsigned int)__lzcnt64(x); -#elif defined(__x86_64__) && defined(__LZCNT__) /* && ! defined(MJIT_HEADER) */ +#elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U64) return (unsigned int)_lzcnt_u64(x); -#elif defined(_WIN64) && defined(_MSC_VER) && _MSC_VER >= 1400 /* &&! defined(__AVX2__) */ +#elif defined(_WIN64) && defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE64) unsigned long r; return _BitScanReverse64(&r, x) ? (63u - (unsigned int)r) : 64; -#elif __has_builtin(__builtin_clzl) && !(defined(__sun) && defined(__sparc)) +#elif __has_builtin(__builtin_clzl) && __has_builtin(__builtin_clzll) && !(defined(__sun) && defined(__sparc)) if (x == 0) { return 64; } diff --git a/ext/bigdecimal/extconf.rb b/ext/bigdecimal/extconf.rb index 5055e10ffa..d5140e8a1d 100644 --- a/ext/bigdecimal/extconf.rb +++ b/ext/bigdecimal/extconf.rb @@ -44,15 +44,22 @@ check_bigdecimal_version(gemspec_path) have_builtin_func("__builtin_clz", "__builtin_clz(0)") have_builtin_func("__builtin_clzl", "__builtin_clzl(0)") +have_builtin_func("__builtin_clzll", "__builtin_clzll(0)") have_header("float.h") have_header("math.h") have_header("stdbool.h") have_header("stdlib.h") -if have_func("_lzcnt_u64", "x86intrin.h") # check availability - $defs << "-DHAVE_X86INTRIN_H" -end +have_header("x86intrin.h") +have_func("_lzcnt_u32", "x86intrin.h") +have_func("_lzcnt_u64", "x86intrin.h") + +have_header("intrin.h") +have_func("__lzcnt", "intrin.h") +have_func("__lzcnt64", "intrin.h") +have_func("_BitScanReverse", "intrin.h") +have_func("_BitScanReverse64", "intrin.h") have_func("labs", "stdlib.h") have_func("llabs", "stdlib.h") -- cgit v1.2.3