Skip to content

Commit cf839a3

Browse files
committed
Check the function availabilities separately
1 parent 9809878 commit cf839a3

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

ext/bigdecimal/bits.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
#include "static_assert.h"
66

77
#if defined(__x86_64__) && defined(HAVE_X86INTRIN_H)
8-
# include <x86intrin.h> /* for _lzcnt_u64 */
9-
#elif defined(_MSC_VER) && _MSC_VER >= 1310
8+
# include <x86intrin.h> /* for _lzcnt_u64, etc. */
9+
#elif defined(_MSC_VER) && defined(HAVE_INTRIN_H)
1010
# include <intrin.h> /* for the following intrinsics */
1111
#endif
1212

@@ -48,17 +48,17 @@ static inline unsigned nlz_int128(uint128_t x);
4848
static inline unsigned int
4949
nlz_int32(uint32_t x)
5050
{
51-
#if defined(_MSC_VER) && defined(__AVX2__)
51+
#if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT)
5252
/* Note: It seems there is no such thing like __LZCNT__ predefined in MSVC.
5353
* AMD CPUs have had this instruction for decades (since K10) but for
5454
* Intel, Haswell is the oldest one. We need to use __AVX2__ for maximum
5555
* safety. */
5656
return (unsigned int)__lzcnt(x);
5757

58-
#elif defined(__x86_64__) && defined(__LZCNT__) /* && ! defined(MJIT_HEADER) */
58+
#elif defined(__x86_64__) && defined(HAVE__LZCNT_U32)
5959
return (unsigned int)_lzcnt_u32(x);
6060

61-
#elif defined(_MSC_VER) && _MSC_VER >= 1400 /* &&! defined(__AVX2__) */
61+
#elif defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE)
6262
unsigned long r;
6363
return _BitScanReverse(&r, x) ? (31 - (int)r) : 32;
6464

@@ -81,17 +81,17 @@ nlz_int32(uint32_t x)
8181
static inline unsigned int
8282
nlz_int64(uint64_t x)
8383
{
84-
#if defined(_MSC_VER) && defined(__AVX2__)
84+
#if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT64)
8585
return (unsigned int)__lzcnt64(x);
8686

87-
#elif defined(__x86_64__) && defined(__LZCNT__) /* && ! defined(MJIT_HEADER) */
87+
#elif defined(__x86_64__) && defined(HAVE__LZCNT_U64)
8888
return (unsigned int)_lzcnt_u64(x);
8989

90-
#elif defined(_WIN64) && defined(_MSC_VER) && _MSC_VER >= 1400 /* &&! defined(__AVX2__) */
90+
#elif defined(_WIN64) && defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE64)
9191
unsigned long r;
9292
return _BitScanReverse64(&r, x) ? (63u - (unsigned int)r) : 64;
9393

94-
#elif __has_builtin(__builtin_clzl) && !(defined(__sun) && defined(__sparc))
94+
#elif __has_builtin(__builtin_clzl) && __has_builtin(__builtin_clzll) && !(defined(__sun) && defined(__sparc))
9595
if (x == 0) {
9696
return 64;
9797
}

ext/bigdecimal/extconf.rb

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,22 @@ def have_builtin_func(name, check_expr, opt = "", &b)
4444

4545
have_builtin_func("__builtin_clz", "__builtin_clz(0)")
4646
have_builtin_func("__builtin_clzl", "__builtin_clzl(0)")
47+
have_builtin_func("__builtin_clzll", "__builtin_clzll(0)")
4748

4849
have_header("float.h")
4950
have_header("math.h")
5051
have_header("stdbool.h")
5152
have_header("stdlib.h")
5253

53-
if have_func("_lzcnt_u64", "x86intrin.h") # check availability
54-
$defs << "-DHAVE_X86INTRIN_H"
55-
end
54+
have_header("x86intrin.h")
55+
have_func("_lzcnt_u32", "x86intrin.h")
56+
have_func("_lzcnt_u64", "x86intrin.h")
57+
58+
have_header("intrin.h")
59+
have_func("__lzcnt", "intrin.h")
60+
have_func("__lzcnt64", "intrin.h")
61+
have_func("_BitScanReverse", "intrin.h")
62+
have_func("_BitScanReverse64", "intrin.h")
5663

5764
have_func("labs", "stdlib.h")
5865
have_func("llabs", "stdlib.h")

0 commit comments

Comments
 (0)