aboutsummaryrefslogtreecommitdiff
path: root/libc/utils/FPUtil/ManipulationFunctions.h
diff options
context:
space:
mode:
Diffstat (limited to 'libc/utils/FPUtil/ManipulationFunctions.h')
-rw-r--r--libc/utils/FPUtil/ManipulationFunctions.h111
1 files changed, 14 insertions, 97 deletions
diff --git a/libc/utils/FPUtil/ManipulationFunctions.h b/libc/utils/FPUtil/ManipulationFunctions.h
index ce5400f..f233fcd 100644
--- a/libc/utils/FPUtil/ManipulationFunctions.h
+++ b/libc/utils/FPUtil/ManipulationFunctions.h
@@ -6,37 +6,20 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_UTILS_FPUTIL_MANIPULATION_FUNCTIONS_H
+#define LLVM_LIBC_UTILS_FPUTIL_MANIPULATION_FUNCTIONS_H
+
#include "FPBits.h"
#include "NearestIntegerOperations.h"
+#include "NormalFloat.h"
#include "utils/CPP/TypeTraits.h"
-#ifndef LLVM_LIBC_UTILS_FPUTIL_MANIPULATION_FUNCTIONS_H
-#define LLVM_LIBC_UTILS_FPUTIL_MANIPULATION_FUNCTIONS_H
-
namespace __llvm_libc {
namespace fputil {
-#if defined(__x86_64__) || defined(__i386__)
-template <typename T> struct Standard754Type {
- static constexpr bool Value =
- cpp::IsSame<float, cpp::RemoveCVType<T>>::Value ||
- cpp::IsSame<double, cpp::RemoveCVType<T>>::Value;
-};
-#else
-template <typename T> struct Standard754Type {
- static constexpr bool Value = cpp::IsFloatingPointType<T>::Value;
-};
-#endif
-
-template <typename T> static inline T frexp_impl(FPBits<T> &bits, int &exp) {
- exp = bits.getExponent() + 1;
- static constexpr uint16_t resultExponent = FPBits<T>::exponentBias - 1;
- bits.exponent = resultExponent;
- return bits;
-}
-
-template <typename T, cpp::EnableIfType<Standard754Type<T>::Value, int> = 0>
+template <typename T,
+ cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
static inline T frexp(T x, int &exp) {
FPBits<T> bits(x);
if (bits.isInfOrNaN())
@@ -46,42 +29,12 @@ static inline T frexp(T x, int &exp) {
return x;
}
- return frexp_impl(bits, exp);
+ NormalFloat<T> normal(bits);
+ exp = normal.exponent + 1;
+ normal.exponent = -1;
+ return normal;
}
-#if defined(__x86_64__) || defined(__i386__)
-static inline long double frexp(long double x, int &exp) {
- FPBits<long double> bits(x);
- if (bits.isInfOrNaN())
- return x;
- if (bits.isZero()) {
- exp = 0;
- return x;
- }
-
- if (bits.exponent != 0 || bits.implicitBit == 1)
- return frexp_impl(bits, exp);
-
- exp = bits.getExponent();
- int shiftCount = 0;
- uint64_t fullMantissa = *reinterpret_cast<uint64_t *>(&bits);
- static constexpr uint64_t msBitMask = uint64_t(1) << 63;
- for (; (fullMantissa & msBitMask) == uint64_t(0);
- fullMantissa <<= 1, ++shiftCount) {
- // This for loop will terminate as fullMantissa is != 0. If it were 0,
- // then x will be NaN and handled before control reaches here.
- // When the loop terminates, fullMantissa will represent the full mantissa
- // of a normal long double value. That is, the implicit bit has the value
- // of 1.
- }
-
- exp = exp - shiftCount + 1;
- *reinterpret_cast<uint64_t *>(&bits) = fullMantissa;
- bits.exponent = FPBits<long double>::exponentBias - 1;
- return bits;
-}
-#endif
-
template <typename T,
cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
static inline T modf(T x, T &iptr) {
@@ -112,11 +65,8 @@ static inline T copysign(T x, T y) {
return xbits;
}
-template <typename T> static inline T logb_impl(const FPBits<T> &bits) {
- return bits.getExponent();
-}
-
-template <typename T, cpp::EnableIfType<Standard754Type<T>::Value, int> = 0>
+template <typename T,
+ cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
static inline T logb(T x) {
FPBits<T> bits(x);
if (bits.isZero()) {
@@ -130,42 +80,9 @@ static inline T logb(T x) {
return FPBits<T>::inf();
}
- return logb_impl(bits);
-}
-
-#if defined(__x86_64__) || defined(__i386__)
-static inline long double logb(long double x) {
- FPBits<long double> bits(x);
- if (bits.isZero()) {
- // TODO(Floating point exception): Raise div-by-zero exception.
- // TODO(errno): POSIX requires setting errno to ERANGE.
- return FPBits<long double>::negInf();
- } else if (bits.isNaN()) {
- return x;
- } else if (bits.isInf()) {
- // Return positive infinity.
- return FPBits<long double>::inf();
- }
-
- if (bits.exponent != 0 || bits.implicitBit == 1)
- return logb_impl(bits);
-
- int exp = bits.getExponent();
- int shiftCount = 0;
- uint64_t fullMantissa = *reinterpret_cast<uint64_t *>(&bits);
- static constexpr uint64_t msBitMask = uint64_t(1) << 63;
- for (; (fullMantissa & msBitMask) == uint64_t(0);
- fullMantissa <<= 1, ++shiftCount) {
- // This for loop will terminate as fullMantissa is != 0. If it were 0,
- // then x will be NaN and handled before control reaches here.
- // When the loop terminates, fullMantissa will represent the full mantissa
- // of a normal long double value. That is, the implicit bit has the value
- // of 1.
- }
-
- return exp - shiftCount;
+ NormalFloat<T> normal(bits);
+ return normal.exponent;
}
-#endif
} // namespace fputil
} // namespace __llvm_libc