Skip to content

Commit 2203b8d

Browse files
committed
fast_float_parser.h: copy nlz_int64 from the bigdecimal gem
1 parent 8d2a1ff commit 2203b8d

1 file changed

Lines changed: 21 additions & 5 deletions

File tree

ext/json/ext/vendor/fast_float_parser.h

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -713,21 +713,37 @@ static inline double ffp_bits2double(uint64_t bits) {
713713
# include <intrin.h>
714714
#endif
715715

716+
#if defined(_MSC_VER) && defined(__AVX2__)
717+
# pragma intrinsic(__lzcnt64)
718+
#endif
719+
716720
static inline unsigned int
717721
ffc_nlz_int64(uint64_t x)
718722
{
719-
#if defined(_MSC_VER) && defined(__AVX2__)
723+
#if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT64)
720724
return (unsigned int)__lzcnt64(x);
721725

722-
#elif defined(__x86_64__) && defined(__LZCNT__)
726+
#elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U64)
723727
return (unsigned int)_lzcnt_u64(x);
724728

725-
#elif defined(_WIN64) && defined(_MSC_VER) /* &&! defined(__AVX2__) */
729+
#elif defined(_WIN64) && defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE64)
726730
unsigned long r;
727731
return _BitScanReverse64(&r, x) ? (63u - (unsigned int)r) : 64;
728732

729-
#elif defined(__has_builtin) && __has_builtin(__builtin_clzll)
730-
return (unsigned int)__builtin_clzll((unsigned long long)x);
733+
#elif __has_builtin(__builtin_clzl) && __has_builtin(__builtin_clzll) && !(defined(__sun) && defined(__sparc))
734+
if (x == 0) {
735+
return 64;
736+
}
737+
else if (sizeof(long) * CHAR_BIT == 64) {
738+
return (unsigned int)__builtin_clzl((unsigned long)x);
739+
}
740+
else if (sizeof(long long) * CHAR_BIT == 64) {
741+
return (unsigned int)__builtin_clzll((unsigned long long)x);
742+
}
743+
else {
744+
/* :FIXME: Is there a way to make this branch a compile-time error? */
745+
__builtin_unreachable();
746+
}
731747

732748
#else
733749
uint64_t y;

0 commit comments

Comments
 (0)