@@ -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+
716720static inline unsigned int
717721ffc_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