@@ -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. */
711741static 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