diff --git a/libc/utils/FPUtil/FPBits.h b/libc/utils/FPUtil/FPBits.h index bc69829ca720ca..2e05c231202924 100644 --- a/libc/utils/FPUtil/FPBits.h +++ b/libc/utils/FPUtil/FPBits.h @@ -9,6 +9,8 @@ #ifndef LLVM_LIBC_UTILS_FPUTIL_FP_BITS_H #define LLVM_LIBC_UTILS_FPUTIL_FP_BITS_H +#include "PlatformDefs.h" + #include "utils/CPP/TypeTraits.h" #include @@ -39,13 +41,17 @@ template struct FPUIntType {}; template <> struct FPUIntType { using Type = uint32_t; }; template <> struct FPUIntType { using Type = uint64_t; }; -#if !(defined(__x86_64__) || defined(__i386__)) -// TODO: This has to be extended for visual studio where long double and -// double are equivalent. +#ifdef LONG_DOUBLE_IS_DOUBLE +template <> struct MantissaWidth { + static constexpr unsigned value = MantissaWidth::value; +}; +template <> struct FPUIntType { + using Type = FPUIntType::Type; +}; +#elif !defined(SPECIAL_X86_LONG_DOUBLE) template <> struct MantissaWidth { static constexpr unsigned value = 112; }; - template <> struct FPUIntType { using Type = __uint128_t; }; #endif @@ -150,7 +156,7 @@ template union FPBits { } // namespace fputil } // namespace __llvm_libc -#if defined(__x86_64__) || defined(__i386__) +#ifdef SPECIAL_X86_LONG_DOUBLE #include "utils/FPUtil/LongDoubleBitsX86.h" #endif diff --git a/libc/utils/FPUtil/ManipulationFunctions.h b/libc/utils/FPUtil/ManipulationFunctions.h index 9bd54ec3e979df..2dfd8e1b71084c 100644 --- a/libc/utils/FPUtil/ManipulationFunctions.h +++ b/libc/utils/FPUtil/ManipulationFunctions.h @@ -12,6 +12,7 @@ #include "FPBits.h" #include "NearestIntegerOperations.h" #include "NormalFloat.h" +#include "PlatformDefs.h" #include "utils/CPP/TypeTraits.h" @@ -178,8 +179,8 @@ static inline T nextafter(T from, T to) { } // namespace fputil } // namespace __llvm_libc -#if (defined(__x86_64__) || defined(__i386__)) +#ifdef SPECIAL_X86_LONG_DOUBLE #include "NextAfterLongDoubleX86.h" -#endif // defined(__x86_64__) || defined(__i386__) +#endif // SPECIAL_X86_LONG_DOUBLE #endif // LLVM_LIBC_UTILS_FPUTIL_MANIPULATION_FUNCTIONS_H diff --git a/libc/utils/FPUtil/NormalFloat.h b/libc/utils/FPUtil/NormalFloat.h index 07bb91bc4fd99c..c0fb85746f70a3 100644 --- a/libc/utils/FPUtil/NormalFloat.h +++ b/libc/utils/FPUtil/NormalFloat.h @@ -169,7 +169,7 @@ template struct NormalFloat { } }; -#if defined(__x86_64__) || defined(__i386__) +#ifdef SPECIAL_X86_LONG_DOUBLE template <> inline void NormalFloat::initFromBits(FPBits bits) { sign = bits.encoding.sign; @@ -256,7 +256,7 @@ template <> inline NormalFloat::operator long double() const { result.encoding.implicitBit = 1; return static_cast(result); } -#endif +#endif // SPECIAL_X86_LONG_DOUBLE } // namespace fputil } // namespace __llvm_libc diff --git a/libc/utils/FPUtil/PlatformDefs.h b/libc/utils/FPUtil/PlatformDefs.h new file mode 100644 index 00000000000000..30ed24d4fdda60 --- /dev/null +++ b/libc/utils/FPUtil/PlatformDefs.h @@ -0,0 +1,24 @@ +//===-- Platform specific macro definitions ---------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_UTILS_FPUTIL_PLATFORM_DEFS_H +#define LLVM_LIBC_UTILS_FPUTIL_PLATFORM_DEFS_H + +#if defined(__x86_64__) || defined(__i386__) +#define X87_FPU +#endif + +#if defined(_WIN32) || defined(_WIN64) +#define LONG_DOUBLE_IS_DOUBLE +#endif + +#if !defined(LONG_DOUBLE_IS_DOUBLE) && defined(X87_FPU) +#define SPECIAL_X86_LONG_DOUBLE +#endif + +#endif // LLVM_LIBC_UTILS_FPUTIL_PLATFORM_DEFS_H diff --git a/libc/utils/FPUtil/Sqrt.h b/libc/utils/FPUtil/Sqrt.h index 097818ca031391..2986e8483bde50 100644 --- a/libc/utils/FPUtil/Sqrt.h +++ b/libc/utils/FPUtil/Sqrt.h @@ -10,6 +10,7 @@ #define LLVM_LIBC_UTILS_FPUTIL_SQRT_H #include "FPBits.h" +#include "PlatformDefs.h" #include "utils/CPP/TypeTraits.h" @@ -61,7 +62,12 @@ template <> inline void normalize(int &exponent, uint64_t &mantissa) { } } -#if !(defined(__x86_64__) || defined(__i386__)) +#ifdef LONG_DOUBLE_IS_DOUBLE +template <> +inline void normalize(int &exponent, uint64_t &mantissa) { + normalize(exponent, mantissa); +} +#elif !defined(SPECIAL_X86_LONG_DOUBLE) template <> inline void normalize(int &exponent, __uint128_t &mantissa) { // Use binary search to shift the leading 1 bit similar to float. @@ -179,8 +185,8 @@ static inline T sqrt(T x) { } // namespace fputil } // namespace __llvm_libc -#if (defined(__x86_64__) || defined(__i386__)) +#ifdef SPECIAL_X86_LONG_DOUBLE #include "SqrtLongDoubleX86.h" -#endif // defined(__x86_64__) || defined(__i386__) +#endif // SPECIAL_X86_LONG_DOUBLE #endif // LLVM_LIBC_UTILS_FPUTIL_SQRT_H diff --git a/libc/utils/FPUtil/SqrtLongDoubleX86.h b/libc/utils/FPUtil/SqrtLongDoubleX86.h index 8ea4ea5a9c4705..953c4a476105f3 100644 --- a/libc/utils/FPUtil/SqrtLongDoubleX86.h +++ b/libc/utils/FPUtil/SqrtLongDoubleX86.h @@ -17,7 +17,6 @@ namespace __llvm_libc { namespace fputil { -#if (defined(__x86_64__) || defined(__i386__)) namespace internal { template <> @@ -136,7 +135,6 @@ template <> inline long double sqrt(long double x) { return out; } } -#endif // defined(__x86_64__) || defined(__i386__) } // namespace fputil } // namespace __llvm_libc