aboutsummaryrefslogtreecommitdiff
path: root/libc/utils
diff options
context:
space:
mode:
authorSiva Chandra Reddy <sivachandra@google.com>2020-06-15 21:06:24 -0700
committerSiva Chandra Reddy <sivachandra@google.com>2020-06-15 23:12:00 -0700
commit6fb7f3a3cf69e322b6792a7059c198c9cf4802ac (patch)
tree569e1d03f4af17ec7ed0395184f42263e50b5cb3 /libc/utils
parent462e3ccdd0d0ce233b8844e976432906d56f8a43 (diff)
downloadllvm-6fb7f3a3cf69e322b6792a7059c198c9cf4802ac.zip
llvm-6fb7f3a3cf69e322b6792a7059c198c9cf4802ac.tar.gz
llvm-6fb7f3a3cf69e322b6792a7059c198c9cf4802ac.tar.bz2
[lib][NFC] Split the floating point util functions into multiple files.
The grouping now reflects the grouping on cppreference.com.
Diffstat (limited to 'libc/utils')
-rw-r--r--libc/utils/FPUtil/BasicOperations.h21
-rw-r--r--libc/utils/FPUtil/ClassificationFunctions.h90
-rw-r--r--libc/utils/FPUtil/FloatOperations.h216
-rw-r--r--libc/utils/FPUtil/ManipulationFunctions.h4
-rw-r--r--libc/utils/FPUtil/NearestIntegerOperations.h164
5 files changed, 278 insertions, 217 deletions
diff --git a/libc/utils/FPUtil/BasicOperations.h b/libc/utils/FPUtil/BasicOperations.h
new file mode 100644
index 0000000..d5c7004
--- /dev/null
+++ b/libc/utils/FPUtil/BasicOperations.h
@@ -0,0 +1,21 @@
+//===-- Basic operations on floating point numbers --------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "FloatOperations.h"
+
+namespace __llvm_libc {
+namespace fputil {
+
+template <typename T,
+ cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
+static inline T abs(T x) {
+ return valueFromBits(absBits(x));
+}
+
+} // namespace fputil
+} // namespace __llvm_libc
diff --git a/libc/utils/FPUtil/ClassificationFunctions.h b/libc/utils/FPUtil/ClassificationFunctions.h
new file mode 100644
index 0000000..a80e349
--- /dev/null
+++ b/libc/utils/FPUtil/ClassificationFunctions.h
@@ -0,0 +1,90 @@
+//===-- Floating point classification functions -----------------*- 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_CLASSIFICATION_FUNCTIONS_H
+#define LLVM_LIBC_UTILS_FPUTIL_CLASSIFICATION_FUNCTIONS_H
+
+#include "BitPatterns.h"
+#include "FloatOperations.h"
+#include "FloatProperties.h"
+
+#include "utils/CPP/TypeTraits.h"
+
+namespace __llvm_libc {
+namespace fputil {
+
+template <typename BitsType> static inline bool bitsAreInf(BitsType bits) {
+ using FPType = typename FloatType<BitsType>::Type;
+ return ((bits & BitPatterns<FPType>::inf) == BitPatterns<FPType>::inf) &&
+ ((bits & FloatProperties<FPType>::mantissaMask) == 0);
+}
+
+// Return true if x is infinity (positive or negative.)
+template <typename T,
+ cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
+static inline bool isInf(T x) {
+ return bitsAreInf(valueAsBits(x));
+}
+
+template <typename BitsType> static inline bool bitsAreNaN(BitsType bits) {
+ using FPType = typename FloatType<BitsType>::Type;
+ return ((bits & BitPatterns<FPType>::inf) == BitPatterns<FPType>::inf) &&
+ ((bits & FloatProperties<FPType>::mantissaMask) != 0);
+}
+
+// Return true if x is a NAN (quiet or signalling.)
+template <typename T,
+ cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
+static inline bool isNaN(T x) {
+ return bitsAreNaN(valueAsBits(x));
+}
+
+template <typename BitsType> static inline bool bitsAreInfOrNaN(BitsType bits) {
+ using FPType = typename FloatType<BitsType>::Type;
+ return (bits & BitPatterns<FPType>::inf) == BitPatterns<FPType>::inf;
+}
+
+template <typename BitsType> static inline bool bitsAreZero(BitsType bits) {
+ using FPType = typename FloatType<BitsType>::Type;
+ return (bits == BitPatterns<FPType>::zero) ||
+ (bits == BitPatterns<FPType>::negZero);
+}
+
+// Return true if x is any kind of NaN or infinity.
+template <typename T,
+ cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
+static inline bool isInfOrNaN(T x) {
+ return bitsAreInfOrNaN(valueAsBits(x));
+}
+
+// Return true if x is a quiet NAN.
+template <typename T,
+ cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
+static inline bool isQuietNaN(T x) {
+ using Properties = FloatProperties<T>;
+ using BitsType = typename FloatProperties<T>::BitsType;
+ BitsType bits = valueAsBits(x);
+ return ((bits & BitPatterns<T>::inf) == BitPatterns<T>::inf) &&
+ ((bits & Properties::quietNaNMask) != 0);
+}
+
+// Return true if x is a quiet NAN with sign bit set.
+template <typename T,
+ cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
+static inline bool isNegativeQuietNaN(T x) {
+ using Properties = FloatProperties<T>;
+ using BitsType = typename FloatProperties<T>::BitsType;
+ BitsType bits = valueAsBits(x);
+ return ((bits & BitPatterns<T>::negInf) == BitPatterns<T>::negInf) &&
+ ((bits & Properties::quietNaNMask) != 0);
+}
+
+} // namespace fputil
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_UTILS_FPUTIL_CLASSIFICATION_FUNCTIONS_H
diff --git a/libc/utils/FPUtil/FloatOperations.h b/libc/utils/FPUtil/FloatOperations.h
index b599aad..0739548f 100644
--- a/libc/utils/FPUtil/FloatOperations.h
+++ b/libc/utils/FPUtil/FloatOperations.h
@@ -57,222 +57,6 @@ static inline int getExponent(T x) {
return getExponentFromBits(valueAsBits(x));
}
-template <typename BitsType> static inline bool bitsAreInf(BitsType bits) {
- using FPType = typename FloatType<BitsType>::Type;
- return ((bits & BitPatterns<FPType>::inf) == BitPatterns<FPType>::inf) &&
- ((bits & FloatProperties<FPType>::mantissaMask) == 0);
-}
-
-// Return true if x is infinity (positive or negative.)
-template <typename T,
- cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
-static inline bool isInf(T x) {
- return bitsAreInf(valueAsBits(x));
-}
-
-template <typename BitsType> static inline bool bitsAreNaN(BitsType bits) {
- using FPType = typename FloatType<BitsType>::Type;
- return ((bits & BitPatterns<FPType>::inf) == BitPatterns<FPType>::inf) &&
- ((bits & FloatProperties<FPType>::mantissaMask) != 0);
-}
-
-// Return true if x is a NAN (quiet or signalling.)
-template <typename T,
- cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
-static inline bool isNaN(T x) {
- return bitsAreNaN(valueAsBits(x));
-}
-
-template <typename BitsType> static inline bool bitsAreInfOrNaN(BitsType bits) {
- using FPType = typename FloatType<BitsType>::Type;
- return (bits & BitPatterns<FPType>::inf) == BitPatterns<FPType>::inf;
-}
-
-template <typename BitsType> static inline bool bitsAreZero(BitsType bits) {
- using FPType = typename FloatType<BitsType>::Type;
- return (bits == BitPatterns<FPType>::zero) ||
- (bits == BitPatterns<FPType>::negZero);
-}
-
-// Return true if x is any kind of NaN or infinity.
-template <typename T,
- cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
-static inline bool isInfOrNaN(T x) {
- return bitsAreInfOrNaN(valueAsBits(x));
-}
-
-// Return true if x is a quiet NAN.
-template <typename T,
- cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
-static inline bool isQuietNaN(T x) {
- using Properties = FloatProperties<T>;
- using BitsType = typename FloatProperties<T>::BitsType;
- BitsType bits = valueAsBits(x);
- return ((bits & BitPatterns<T>::inf) == BitPatterns<T>::inf) &&
- ((bits & Properties::quietNaNMask) != 0);
-}
-
-// Return true if x is a quiet NAN with sign bit set.
-template <typename T,
- cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
-static inline bool isNegativeQuietNaN(T x) {
- using Properties = FloatProperties<T>;
- using BitsType = typename FloatProperties<T>::BitsType;
- BitsType bits = valueAsBits(x);
- return ((bits & BitPatterns<T>::negInf) == BitPatterns<T>::negInf) &&
- ((bits & Properties::quietNaNMask) != 0);
-}
-
-// Return the absolute value of x.
-template <typename T,
- cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
-static inline T abs(T x) {
- return valueFromBits(absBits(x));
-}
-
-// Return the trucated value of x. If x is non-negative, then the return value
-// is greatest integer less than or equal to x. Otherwise, return the smallest
-// integer greater than or equal to x. That is, return the integer value rounded
-// toward zero.
-template <typename T,
- cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
-static inline T trunc(T x) {
- using Properties = FloatProperties<T>;
- using BitsType = typename FloatProperties<T>::BitsType;
-
- BitsType bits = valueAsBits(x);
-
- // If x is infinity, NaN or zero, return it.
- if (bitsAreInfOrNaN(bits) || bitsAreZero(bits))
- return x;
-
- int exponent = getExponentFromBits(bits);
-
- // If the exponent is greater than the most negative mantissa
- // exponent, then x is already an integer.
- if (exponent >= static_cast<int>(Properties::mantissaWidth))
- return x;
-
- // If the exponent is such that abs(x) is less than 1, then return 0.
- if (exponent <= -1) {
- if (Properties::signMask & bits)
- return T(-0.0);
- else
- return T(0.0);
- }
-
- uint32_t trimSize = Properties::mantissaWidth - exponent;
- return valueFromBits((bits >> trimSize) << trimSize);
-}
-
-template <typename T,
- cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
-static inline T ceil(T x) {
- using Properties = FloatProperties<T>;
- using BitsType = typename FloatProperties<T>::BitsType;
-
- BitsType bits = valueAsBits(x);
-
- // If x is infinity NaN or zero, return it.
- if (bitsAreInfOrNaN(bits) || bitsAreZero(bits))
- return x;
-
- bool isNeg = bits & Properties::signMask;
- int exponent = getExponentFromBits(bits);
-
- // If the exponent is greater than the most negative mantissa
- // exponent, then x is already an integer.
- if (exponent >= static_cast<int>(Properties::mantissaWidth))
- return x;
-
- if (exponent <= -1) {
- if (isNeg)
- return T(-0.0);
- else
- return T(1.0);
- }
-
- uint32_t trimSize = Properties::mantissaWidth - exponent;
- // If x is already an integer, return it.
- if ((bits << (Properties::bitWidth - trimSize)) == 0)
- return x;
-
- BitsType truncBits = (bits >> trimSize) << trimSize;
- T truncValue = valueFromBits(truncBits);
-
- // If x is negative, the ceil operation is equivalent to the trunc operation.
- if (isNeg)
- return truncValue;
-
- return truncValue + T(1.0);
-}
-
-template <typename T,
- cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
-static inline T floor(T x) {
- auto bits = valueAsBits(x);
- if (FloatProperties<T>::signMask & bits) {
- return -ceil(-x);
- } else {
- return trunc(x);
- }
-}
-
-template <typename T,
- cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
-static inline T round(T x) {
- using Properties = FloatProperties<T>;
- using BitsType = typename FloatProperties<T>::BitsType;
-
- BitsType bits = valueAsBits(x);
-
- // If x is infinity, NaN or zero, return it.
- if (bitsAreInfOrNaN(bits) || bitsAreZero(bits))
- return x;
-
- bool isNeg = bits & Properties::signMask;
- int exponent = getExponentFromBits(bits);
-
- // If the exponent is greater than the most negative mantissa
- // exponent, then x is already an integer.
- if (exponent >= static_cast<int>(Properties::mantissaWidth))
- return x;
-
- if (exponent == -1) {
- // Absolute value of x is greater than equal to 0.5 but less than 1.
- if (isNeg)
- return T(-1.0);
- else
- return T(1.0);
- }
-
- if (exponent <= -2) {
- // Absolute value of x is less than 0.5.
- if (isNeg)
- return T(-0.0);
- else
- return T(0.0);
- }
-
- uint32_t trimSize = Properties::mantissaWidth - exponent;
- // If x is already an integer, return it.
- if ((bits << (Properties::bitWidth - trimSize)) == 0)
- return x;
-
- BitsType truncBits = (bits >> trimSize) << trimSize;
- T truncValue = valueFromBits(truncBits);
-
- if ((bits & (BitsType(1) << (trimSize - 1))) == 0) {
- // Franctional part is less than 0.5 so round value is the
- // same as the trunc value.
- return truncValue;
- }
-
- if (isNeg)
- return truncValue - T(1.0);
- else
- return truncValue + T(1.0);
-}
} // namespace fputil
} // namespace __llvm_libc
diff --git a/libc/utils/FPUtil/ManipulationFunctions.h b/libc/utils/FPUtil/ManipulationFunctions.h
index a59c0a7..b1e06f7 100644
--- a/libc/utils/FPUtil/ManipulationFunctions.h
+++ b/libc/utils/FPUtil/ManipulationFunctions.h
@@ -1,4 +1,4 @@
-//===-- Common operations on floating point numbers -------------*- C++ -*-===//
+//===-- Floating-point manipulation functions -------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,8 +7,10 @@
//===----------------------------------------------------------------------===//
#include "BitPatterns.h"
+#include "ClassificationFunctions.h"
#include "FloatOperations.h"
#include "FloatProperties.h"
+#include "NearestIntegerOperations.h"
#include "utils/CPP/TypeTraits.h"
diff --git a/libc/utils/FPUtil/NearestIntegerOperations.h b/libc/utils/FPUtil/NearestIntegerOperations.h
new file mode 100644
index 0000000..7f93de6
--- /dev/null
+++ b/libc/utils/FPUtil/NearestIntegerOperations.h
@@ -0,0 +1,164 @@
+//===-- Nearest integer floating-point operations ---------------*- 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_NEAREST_INTEGER_OPERATIONS_H
+#define LLVM_LIBC_UTILS_FPUTIL_NEAREST_INTEGER_OPERATIONS_H
+
+#include "ClassificationFunctions.h"
+#include "FloatOperations.h"
+#include "FloatProperties.h"
+
+#include "utils/CPP/TypeTraits.h"
+
+namespace __llvm_libc {
+namespace fputil {
+
+template <typename T,
+ cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
+static inline T trunc(T x) {
+ using Properties = FloatProperties<T>;
+ using BitsType = typename FloatProperties<T>::BitsType;
+
+ BitsType bits = valueAsBits(x);
+
+ // If x is infinity, NaN or zero, return it.
+ if (bitsAreInfOrNaN(bits) || bitsAreZero(bits))
+ return x;
+
+ int exponent = getExponentFromBits(bits);
+
+ // If the exponent is greater than the most negative mantissa
+ // exponent, then x is already an integer.
+ if (exponent >= static_cast<int>(Properties::mantissaWidth))
+ return x;
+
+ // If the exponent is such that abs(x) is less than 1, then return 0.
+ if (exponent <= -1) {
+ if (Properties::signMask & bits)
+ return T(-0.0);
+ else
+ return T(0.0);
+ }
+
+ uint32_t trimSize = Properties::mantissaWidth - exponent;
+ return valueFromBits((bits >> trimSize) << trimSize);
+}
+
+template <typename T,
+ cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
+static inline T ceil(T x) {
+ using Properties = FloatProperties<T>;
+ using BitsType = typename FloatProperties<T>::BitsType;
+
+ BitsType bits = valueAsBits(x);
+
+ // If x is infinity NaN or zero, return it.
+ if (bitsAreInfOrNaN(bits) || bitsAreZero(bits))
+ return x;
+
+ bool isNeg = bits & Properties::signMask;
+ int exponent = getExponentFromBits(bits);
+
+ // If the exponent is greater than the most negative mantissa
+ // exponent, then x is already an integer.
+ if (exponent >= static_cast<int>(Properties::mantissaWidth))
+ return x;
+
+ if (exponent <= -1) {
+ if (isNeg)
+ return T(-0.0);
+ else
+ return T(1.0);
+ }
+
+ uint32_t trimSize = Properties::mantissaWidth - exponent;
+ // If x is already an integer, return it.
+ if ((bits << (Properties::bitWidth - trimSize)) == 0)
+ return x;
+
+ BitsType truncBits = (bits >> trimSize) << trimSize;
+ T truncValue = valueFromBits(truncBits);
+
+ // If x is negative, the ceil operation is equivalent to the trunc operation.
+ if (isNeg)
+ return truncValue;
+
+ return truncValue + T(1.0);
+}
+
+template <typename T,
+ cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
+static inline T floor(T x) {
+ auto bits = valueAsBits(x);
+ if (FloatProperties<T>::signMask & bits) {
+ return -ceil(-x);
+ } else {
+ return trunc(x);
+ }
+}
+
+template <typename T,
+ cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
+static inline T round(T x) {
+ using Properties = FloatProperties<T>;
+ using BitsType = typename FloatProperties<T>::BitsType;
+
+ BitsType bits = valueAsBits(x);
+
+ // If x is infinity, NaN or zero, return it.
+ if (bitsAreInfOrNaN(bits) || bitsAreZero(bits))
+ return x;
+
+ bool isNeg = bits & Properties::signMask;
+ int exponent = getExponentFromBits(bits);
+
+ // If the exponent is greater than the most negative mantissa
+ // exponent, then x is already an integer.
+ if (exponent >= static_cast<int>(Properties::mantissaWidth))
+ return x;
+
+ if (exponent == -1) {
+ // Absolute value of x is greater than equal to 0.5 but less than 1.
+ if (isNeg)
+ return T(-1.0);
+ else
+ return T(1.0);
+ }
+
+ if (exponent <= -2) {
+ // Absolute value of x is less than 0.5.
+ if (isNeg)
+ return T(-0.0);
+ else
+ return T(0.0);
+ }
+
+ uint32_t trimSize = Properties::mantissaWidth - exponent;
+ // If x is already an integer, return it.
+ if ((bits << (Properties::bitWidth - trimSize)) == 0)
+ return x;
+
+ BitsType truncBits = (bits >> trimSize) << trimSize;
+ T truncValue = valueFromBits(truncBits);
+
+ if ((bits & (BitsType(1) << (trimSize - 1))) == 0) {
+ // Franctional part is less than 0.5 so round value is the
+ // same as the trunc value.
+ return truncValue;
+ }
+
+ if (isNeg)
+ return truncValue - T(1.0);
+ else
+ return truncValue + T(1.0);
+}
+
+} // namespace fputil
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_UTILS_FPUTIL_NEAREST_INTEGER_OPERATIONS_H