diff --git a/AK/BuiltinWrappers.h b/AK/BuiltinWrappers.h index 2ea6b68c025..81c27d58463 100644 --- a/AK/BuiltinWrappers.h +++ b/AK/BuiltinWrappers.h @@ -97,6 +97,24 @@ inline constexpr int count_leading_zeroes(IntType value) #endif } +#ifdef __SIZEOF_INT128__ +// This is required for math.cpp internal_scalbn +inline constexpr int count_leading_zeroes(unsigned __int128 value) +{ +# if defined(AK_COMPILER_CLANG) || defined(AK_COMPILER_GCC) + return (value > __UINT64_MAX__) ? __builtin_clzll(value >> 64) : 64 + __builtin_clzll(value); +# else + unsigned __int128 mask = (unsigned __int128)1 << 127; + int ret = 0; + while ((value & mask) == 0) { + ++ret; + mask >>= 1; + } + return ret; +# endif +} +#endif + // The function will return the number of leading zeroes in the type. If // the given number is zero, this function will return the number of bits // in the IntType. diff --git a/AK/FloatingPoint.h b/AK/FloatingPoint.h index eeca5ea6b64..fea42d575cb 100644 --- a/AK/FloatingPoint.h +++ b/AK/FloatingPoint.h @@ -15,6 +15,26 @@ namespace AK { template union FloatExtractor; +#ifdef AK_HAS_FLOAT_128 +template<> +union FloatExtractor { + static constexpr int mantissa_bits = 112; + static constexpr unsigned __int128 mantissa_max = (((unsigned __int128)1) << 112) - 1; + static constexpr int exponent_bias = 16383; + static constexpr int exponent_bits = 15; + static constexpr unsigned exponent_max = 32767; + struct { + unsigned __int128 mantissa : 112; + unsigned exponent : 15; + unsigned sign : 1; + }; + f128 d; +}; +// Validate that f128 and the FloatExtractor union are 128 bits. +static_assert(sizeof(f128) == 16); +static_assert(sizeof(FloatExtractor) == 16); +#endif + #ifdef AK_HAS_FLOAT_80 template<> union FloatExtractor { diff --git a/AK/IntegralMath.h b/AK/IntegralMath.h index 415e485bf9d..4bf90181395 100644 --- a/AK/IntegralMath.h +++ b/AK/IntegralMath.h @@ -31,7 +31,7 @@ constexpr T ceil_log2(T x) return 0; T log = AK::log2(x); - log += (x & ((1 << (log - 1)) - 1)) != 0; + log += (x & ((((T)1) << (log - 1)) - 1)) != 0; return log; }