diff --git a/libc/utils/FPUtil/FloatProperties.h b/libc/utils/FPUtil/FloatProperties.h --- a/libc/utils/FPUtil/FloatProperties.h +++ b/libc/utils/FPUtil/FloatProperties.h @@ -9,6 +9,7 @@ #ifndef LLVM_LIBC_UTILS_FPUTIL_FLOAT_PROPERTIES_H #define LLVM_LIBC_UTILS_FPUTIL_FLOAT_PROPERTIES_H +#include "PlatformDefs.h" #include namespace __llvm_libc { @@ -24,6 +25,7 @@ static constexpr uint32_t bitWidth = sizeof(BitsType) << 3; static constexpr uint32_t mantissaWidth = 23; + static constexpr uint32_t exponentWidth = 8; static constexpr BitsType mantissaMask = 0x007fffffU; static constexpr BitsType signMask = 0x80000000U; static constexpr BitsType exponentMask = ~(signMask | mantissaMask); @@ -43,6 +45,7 @@ static constexpr uint32_t bitWidth = sizeof(BitsType) << 3; static constexpr uint32_t mantissaWidth = 52; + static constexpr uint32_t exponentWidth = 11; static constexpr BitsType mantissaMask = 0x000fffffffffffffU; static constexpr BitsType signMask = 0x8000000000000000ULL; static constexpr BitsType exponentMask = ~(signMask | mantissaMask); @@ -54,6 +57,64 @@ static constexpr BitsType quietNaNMask = 0x0008000000000000ULL; }; +#if defined(LONG_DOUBLE_IS_DOUBLE) +// Properties for long double on Windows platform, same as double precision. +template <> struct FloatProperties { + typedef uint64_t BitsType; + static_assert(sizeof(BitsType) == sizeof(double), + "Unexpected size of 'double' type."); + + static constexpr uint32_t bitWidth = FloatProperties::bitWidth; + + static constexpr uint32_t mantissaWidth = + FloatProperties::mantissaWidth; + static constexpr uint32_t exponentWidth = + FloatProperties::exponentWidth; + static constexpr BitsType mantissaMask = + FloatProperties::mantissaMask; + static constexpr BitsType signMask = FloatProperties::signMask; + static constexpr BitsType exponentMask = + FloatProperties::exponentMask; + static constexpr uint32_t exponentOffset = + FloatProperties::exponentOffset; +}; + +#elif defined(SPECIAL_X86_LONG_DOUBLE) +// Properties for long double on non-Windows x86 platforms. +template <> struct FloatProperties { + typedef __uint128_t BitsType; + static_assert(sizeof(BitsType) == sizeof(long double), + "Unexpected size of 'long double' type."); + + static constexpr uint32_t bitWidth = sizeof(BitsType) << 3; + + static constexpr uint32_t mantissaWidth = 64; + static constexpr uint32_t exponentWidth = 15; + static constexpr BitsType mantissaMask = 0xffffffffffffffffULL; + static constexpr BitsType signMask = BitsType(0x00008000U) << 64; + static constexpr BitsType exponentMask = ~(signMask | mantissaMask); + static constexpr uint32_t exponentOffset = 16383; +}; + +#else +// Properties for long double on non x86 platform. +template <> struct FloatProperties { + typedef __uint128_t BitsType; + static_assert(sizeof(BitsType) == sizeof(long double), + "Unexpected size of 'long double' type."); + + static constexpr uint32_t bitWidth = sizeof(BitsType) << 3; + + static constexpr uint32_t mantissaWidth = 112; + static constexpr uint32_t exponentWidth = 15; + static constexpr BitsType mantissaMask = + (BitsType(0x0000ffffffffffffULL) << 64) | BitsType(0xffffffffffffffffULL); + static constexpr BitsType signMask = BitsType(0x8000000000000000U) << 64; + static constexpr BitsType exponentMask = ~(signMask | mantissaMask); + static constexpr uint32_t exponentOffset = 16383; +}; +#endif + // Define the float type corresponding to the BitsType. template struct FloatType;