Skip to content

Commit c171e34

Browse files
committed
fast_float_parser.h: add portable __builtin_clzll
Required for Windows support.
1 parent 4185ef1 commit c171e34

1 file changed

Lines changed: 32 additions & 2 deletions

File tree

ext/json/ext/vendor/fast_float_parser.h

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,36 @@ static inline double ffp_bits2double(uint64_t bits) {
707707
return d;
708708
}
709709

710+
static inline unsigned int
711+
ffc_nlz_int64(uint64_t x)
712+
{
713+
#if defined(_MSC_VER) && defined(__AVX2__)
714+
return (unsigned int)__lzcnt64(x);
715+
716+
#elif defined(__x86_64__) && defined(__LZCNT__)
717+
return (unsigned int)_lzcnt_u64(x);
718+
719+
#elif defined(_WIN64) && defined(_MSC_VER) /* &&! defined(__AVX2__) */
720+
unsigned long r;
721+
return _BitScanReverse64(&r, x) ? (63u - (unsigned int)r) : 64;
722+
723+
#elif __has_builtin(__builtin_clzll)
724+
return (unsigned int)__builtin_clzll((unsigned long long)x);
725+
726+
#else
727+
uint64_t y;
728+
unsigned int n = 64;
729+
y = x >> 32; if (y) {n -= 32; x = y;}
730+
y = x >> 16; if (y) {n -= 16; x = y;}
731+
y = x >> 8; if (y) {n -= 8; x = y;}
732+
y = x >> 4; if (y) {n -= 4; x = y;}
733+
y = x >> 2; if (y) {n -= 2; x = y;}
734+
y = x >> 1; if (y) {return n - 2;}
735+
return (unsigned int)(n - x);
736+
737+
#endif
738+
}
739+
710740
/* q = power of ten, w = mantissa (exact, fits in uint64). neg = sign. */
711741
static inline double ffp_s2d(int64_t q, uint64_t w, bool neg) {
712742
if (w == 0) {
@@ -716,14 +746,14 @@ static inline double ffp_s2d(int64_t q, uint64_t w, bool neg) {
716746
const uint64_t sign = (uint64_t)(neg != 0) << 63;
717747
uint64_t mantissa, prod_hi, prod_lo, sp_hi, sp_lo;
718748
int32_t power2;
719-
int lz, upperbit, shift, index;
749+
int upperbit, shift, index;
720750

721751
if (q < FFP_SMALLEST_POW10) return ffp_bits2double(sign); /* underflow -> 0 */
722752
if (q > FFP_LARGEST_POW10) {
723753
return ffp_bits2double(sign | ((uint64_t)FFP_INFINITE_POWER << FFP_MANTISSA_BITS));
724754
}
725755

726-
lz = __builtin_clzll(w);
756+
unsigned int lz = ffc_nlz_int64(w);
727757
w <<= lz;
728758

729759
/* compute_product_approximation<mantissa_bits + 3 = 55>: precision_mask = 0x1FF. */

0 commit comments

Comments
 (0)