aboutsummaryrefslogtreecommitdiff
path: root/libc
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
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')
-rw-r--r--libc/src/math/ceil.cpp2
-rw-r--r--libc/src/math/ceilf.cpp2
-rw-r--r--libc/src/math/fabs.cpp2
-rw-r--r--libc/src/math/fabsf.cpp2
-rw-r--r--libc/src/math/floor.cpp2
-rw-r--r--libc/src/math/floorf.cpp2
-rw-r--r--libc/src/math/round.cpp2
-rw-r--r--libc/src/math/roundf.cpp2
-rw-r--r--libc/src/math/trunc.cpp2
-rw-r--r--libc/src/math/truncf.cpp2
-rw-r--r--libc/test/src/math/cosf_test.cpp1
-rw-r--r--libc/test/src/math/exp2f_test.cpp1
-rw-r--r--libc/test/src/math/expf_test.cpp1
-rw-r--r--libc/test/src/math/frexp_test.cpp2
-rw-r--r--libc/test/src/math/frexpf_test.cpp2
-rw-r--r--libc/test/src/math/modf_test.cpp2
-rw-r--r--libc/test/src/math/modff_test.cpp2
-rw-r--r--libc/test/src/math/sincosf_test.cpp1
-rw-r--r--libc/test/src/math/sinf_test.cpp1
-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
24 files changed, 301 insertions, 227 deletions
diff --git a/libc/src/math/ceil.cpp b/libc/src/math/ceil.cpp
index c9af520..06ef903 100644
--- a/libc/src/math/ceil.cpp
+++ b/libc/src/math/ceil.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/common.h"
-#include "utils/FPUtil/FloatOperations.h"
+#include "utils/FPUtil/NearestIntegerOperations.h"
namespace __llvm_libc {
diff --git a/libc/src/math/ceilf.cpp b/libc/src/math/ceilf.cpp
index 2d2fb90..d44e273 100644
--- a/libc/src/math/ceilf.cpp
+++ b/libc/src/math/ceilf.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/common.h"
-#include "utils/FPUtil/FloatOperations.h"
+#include "utils/FPUtil/NearestIntegerOperations.h"
namespace __llvm_libc {
diff --git a/libc/src/math/fabs.cpp b/libc/src/math/fabs.cpp
index 15c60e8..ff78f1b 100644
--- a/libc/src/math/fabs.cpp
+++ b/libc/src/math/fabs.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/common.h"
-#include "utils/FPUtil/FloatOperations.h"
+#include "utils/FPUtil/BasicOperations.h"
namespace __llvm_libc {
diff --git a/libc/src/math/fabsf.cpp b/libc/src/math/fabsf.cpp
index dd2b055..9aa1419 100644
--- a/libc/src/math/fabsf.cpp
+++ b/libc/src/math/fabsf.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/common.h"
-#include "utils/FPUtil/FloatOperations.h"
+#include "utils/FPUtil/BasicOperations.h"
namespace __llvm_libc {
diff --git a/libc/src/math/floor.cpp b/libc/src/math/floor.cpp
index b2d5f87..cc2fde5 100644
--- a/libc/src/math/floor.cpp
+++ b/libc/src/math/floor.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/common.h"
-#include "utils/FPUtil/FloatOperations.h"
+#include "utils/FPUtil/NearestIntegerOperations.h"
namespace __llvm_libc {
diff --git a/libc/src/math/floorf.cpp b/libc/src/math/floorf.cpp
index 397602e..e220ab4 100644
--- a/libc/src/math/floorf.cpp
+++ b/libc/src/math/floorf.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/common.h"
-#include "utils/FPUtil/FloatOperations.h"
+#include "utils/FPUtil/NearestIntegerOperations.h"
namespace __llvm_libc {
diff --git a/libc/src/math/round.cpp b/libc/src/math/round.cpp
index 0a6e548..44a1119 100644
--- a/libc/src/math/round.cpp
+++ b/libc/src/math/round.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/common.h"
-#include "utils/FPUtil/FloatOperations.h"
+#include "utils/FPUtil/NearestIntegerOperations.h"
namespace __llvm_libc {
diff --git a/libc/src/math/roundf.cpp b/libc/src/math/roundf.cpp
index bdfcd0a..8cbb315 100644
--- a/libc/src/math/roundf.cpp
+++ b/libc/src/math/roundf.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/common.h"
-#include "utils/FPUtil/FloatOperations.h"
+#include "utils/FPUtil/NearestIntegerOperations.h"
namespace __llvm_libc {
diff --git a/libc/src/math/trunc.cpp b/libc/src/math/trunc.cpp
index 7e42fe4..0749e11 100644
--- a/libc/src/math/trunc.cpp
+++ b/libc/src/math/trunc.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/common.h"
-#include "utils/FPUtil/FloatOperations.h"
+#include "utils/FPUtil/NearestIntegerOperations.h"
namespace __llvm_libc {
diff --git a/libc/src/math/truncf.cpp b/libc/src/math/truncf.cpp
index c567865..0372571 100644
--- a/libc/src/math/truncf.cpp
+++ b/libc/src/math/truncf.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/common.h"
-#include "utils/FPUtil/FloatOperations.h"
+#include "utils/FPUtil/NearestIntegerOperations.h"
namespace __llvm_libc {
diff --git a/libc/test/src/math/cosf_test.cpp b/libc/test/src/math/cosf_test.cpp
index 3ba0fcd..ac6020e 100644
--- a/libc/test/src/math/cosf_test.cpp
+++ b/libc/test/src/math/cosf_test.cpp
@@ -13,6 +13,7 @@
#include "test/src/math/sdcomp26094.h"
#include "utils/CPP/Array.h"
#include "utils/FPUtil/BitPatterns.h"
+#include "utils/FPUtil/ClassificationFunctions.h"
#include "utils/FPUtil/FloatOperations.h"
#include "utils/FPUtil/FloatProperties.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
diff --git a/libc/test/src/math/exp2f_test.cpp b/libc/test/src/math/exp2f_test.cpp
index c900ec6..fe9955f 100644
--- a/libc/test/src/math/exp2f_test.cpp
+++ b/libc/test/src/math/exp2f_test.cpp
@@ -11,6 +11,7 @@
#include "src/errno/llvmlibc_errno.h"
#include "src/math/exp2f.h"
#include "utils/FPUtil/BitPatterns.h"
+#include "utils/FPUtil/ClassificationFunctions.h"
#include "utils/FPUtil/FloatOperations.h"
#include "utils/FPUtil/FloatProperties.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
diff --git a/libc/test/src/math/expf_test.cpp b/libc/test/src/math/expf_test.cpp
index c99058d..577f5e4 100644
--- a/libc/test/src/math/expf_test.cpp
+++ b/libc/test/src/math/expf_test.cpp
@@ -11,6 +11,7 @@
#include "src/errno/llvmlibc_errno.h"
#include "src/math/expf.h"
#include "utils/FPUtil/BitPatterns.h"
+#include "utils/FPUtil/ClassificationFunctions.h"
#include "utils/FPUtil/FloatOperations.h"
#include "utils/FPUtil/FloatProperties.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
diff --git a/libc/test/src/math/frexp_test.cpp b/libc/test/src/math/frexp_test.cpp
index a7fb953..f828d51 100644
--- a/libc/test/src/math/frexp_test.cpp
+++ b/libc/test/src/math/frexp_test.cpp
@@ -8,7 +8,9 @@
#include "include/math.h"
#include "src/math/frexp.h"
+#include "utils/FPUtil/BasicOperations.h"
#include "utils/FPUtil/BitPatterns.h"
+#include "utils/FPUtil/ClassificationFunctions.h"
#include "utils/FPUtil/FloatOperations.h"
#include "utils/FPUtil/FloatProperties.h"
#include "utils/UnitTest/Test.h"
diff --git a/libc/test/src/math/frexpf_test.cpp b/libc/test/src/math/frexpf_test.cpp
index d90532b..e15f384 100644
--- a/libc/test/src/math/frexpf_test.cpp
+++ b/libc/test/src/math/frexpf_test.cpp
@@ -9,7 +9,9 @@
#include "include/math.h"
#include "src/math/frexpf.h"
+#include "utils/FPUtil/BasicOperations.h"
#include "utils/FPUtil/BitPatterns.h"
+#include "utils/FPUtil/ClassificationFunctions.h"
#include "utils/FPUtil/FloatOperations.h"
#include "utils/FPUtil/FloatProperties.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
diff --git a/libc/test/src/math/modf_test.cpp b/libc/test/src/math/modf_test.cpp
index fa4436d6..774ad8b6 100644
--- a/libc/test/src/math/modf_test.cpp
+++ b/libc/test/src/math/modf_test.cpp
@@ -8,9 +8,11 @@
#include "include/math.h"
#include "src/math/modf.h"
+#include "utils/FPUtil/BasicOperations.h"
#include "utils/FPUtil/BitPatterns.h"
#include "utils/FPUtil/FloatOperations.h"
#include "utils/FPUtil/FloatProperties.h"
+#include "utils/FPUtil/NearestIntegerOperations.h"
#include "utils/UnitTest/Test.h"
using __llvm_libc::fputil::valueAsBits;
diff --git a/libc/test/src/math/modff_test.cpp b/libc/test/src/math/modff_test.cpp
index db3b7c8..fbd3b86 100644
--- a/libc/test/src/math/modff_test.cpp
+++ b/libc/test/src/math/modff_test.cpp
@@ -9,9 +9,11 @@
#include "include/math.h"
#include "src/math/modff.h"
+#include "utils/FPUtil/BasicOperations.h"
#include "utils/FPUtil/BitPatterns.h"
#include "utils/FPUtil/FloatOperations.h"
#include "utils/FPUtil/FloatProperties.h"
+#include "utils/FPUtil/NearestIntegerOperations.h"
#include "utils/UnitTest/Test.h"
using __llvm_libc::fputil::valueAsBits;
diff --git a/libc/test/src/math/sincosf_test.cpp b/libc/test/src/math/sincosf_test.cpp
index 66b247a..2211ef1 100644
--- a/libc/test/src/math/sincosf_test.cpp
+++ b/libc/test/src/math/sincosf_test.cpp
@@ -13,6 +13,7 @@
#include "test/src/math/sdcomp26094.h"
#include "utils/CPP/Array.h"
#include "utils/FPUtil/BitPatterns.h"
+#include "utils/FPUtil/ClassificationFunctions.h"
#include "utils/FPUtil/FloatOperations.h"
#include "utils/FPUtil/FloatProperties.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
diff --git a/libc/test/src/math/sinf_test.cpp b/libc/test/src/math/sinf_test.cpp
index 115359b..17c6671 100644
--- a/libc/test/src/math/sinf_test.cpp
+++ b/libc/test/src/math/sinf_test.cpp
@@ -13,6 +13,7 @@
#include "test/src/math/sdcomp26094.h"
#include "utils/CPP/Array.h"
#include "utils/FPUtil/BitPatterns.h"
+#include "utils/FPUtil/ClassificationFunctions.h"
#include "utils/FPUtil/FloatOperations.h"
#include "utils/FPUtil/FloatProperties.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
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