diff options
author | OverMighty <its.overmighty@gmail.com> | 2024-06-20 19:33:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-20 13:33:34 -0400 |
commit | 1107575c95577f32678ad60a96be6eaf29cf0f65 (patch) | |
tree | c0b395399cb7bc243ced228a5dfab3e7dd9de92c /libc/src | |
parent | f1edc0459a4cc8cd4d00331c2a5cb318955318b2 (diff) | |
download | llvm-1107575c95577f32678ad60a96be6eaf29cf0f65.zip llvm-1107575c95577f32678ad60a96be6eaf29cf0f65.tar.gz llvm-1107575c95577f32678ad60a96be6eaf29cf0f65.tar.bz2 |
[libc][math][c23] Add {getpayload,setpayload,setpayloadsig}f16 C23 math functions (#95159)
Part of #93566.
Diffstat (limited to 'libc/src')
-rw-r--r-- | libc/src/__support/FPUtil/BasicOperations.h | 42 | ||||
-rw-r--r-- | libc/src/math/CMakeLists.txt | 6 | ||||
-rw-r--r-- | libc/src/math/generic/CMakeLists.txt | 39 | ||||
-rw-r--r-- | libc/src/math/generic/getpayloadf16.cpp | 19 | ||||
-rw-r--r-- | libc/src/math/generic/setpayloadf16.cpp | 19 | ||||
-rw-r--r-- | libc/src/math/generic/setpayloadsigf16.cpp | 19 | ||||
-rw-r--r-- | libc/src/math/getpayloadf16.h | 20 | ||||
-rw-r--r-- | libc/src/math/setpayloadf16.h | 20 | ||||
-rw-r--r-- | libc/src/math/setpayloadsigf16.h | 20 |
9 files changed, 204 insertions, 0 deletions
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h index beb8e48..17eee7b 100644 --- a/libc/src/__support/FPUtil/BasicOperations.h +++ b/libc/src/__support/FPUtil/BasicOperations.h @@ -265,6 +265,48 @@ totalordermag(T x, T y) { return FPBits<T>(x).abs().uintval() <= FPBits<T>(y).abs().uintval(); } +template <typename T> +LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> getpayload(T x) { + using FPBits = FPBits<T>; + FPBits x_bits(x); + + if (!x_bits.is_nan()) + return T(-1.0); + + return T(x_bits.uintval() & (FPBits::FRACTION_MASK >> 1)); +} + +template <bool IsSignaling, typename T> +LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool> +setpayload(T &res, T pl) { + using FPBits = FPBits<T>; + FPBits pl_bits(pl); + + // Signaling NaNs don't have the mantissa's MSB set to 1, so they need a + // non-zero payload to distinguish them from infinities. + if (!IsSignaling && pl_bits.is_zero()) { + res = FPBits::quiet_nan(Sign::POS).get_val(); + return false; + } + + int pl_exp = pl_bits.get_exponent(); + + if (pl_bits.is_neg() || pl_exp < 0 || pl_exp >= FPBits::FRACTION_LEN - 1 || + ((pl_bits.get_mantissa() << pl_exp) & FPBits::FRACTION_MASK) != 0) { + res = T(0.0); + return true; + } + + using StorageType = typename FPBits::StorageType; + StorageType v(pl_bits.get_explicit_mantissa() >> (FPBits::SIG_LEN - pl_exp)); + + if constexpr (IsSignaling) + res = FPBits::signaling_nan(Sign::POS, v).get_val(); + else + res = FPBits::quiet_nan(Sign::POS, v).get_val(); + return false; +} + } // namespace fputil } // namespace LIBC_NAMESPACE diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt index 4472367..92e0cd2 100644 --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -210,6 +210,8 @@ add_math_entrypoint_object(fromfpxl) add_math_entrypoint_object(fromfpxf16) add_math_entrypoint_object(fromfpxf128) +add_math_entrypoint_object(getpayloadf16) + add_math_entrypoint_object(hypot) add_math_entrypoint_object(hypotf) @@ -350,6 +352,10 @@ add_math_entrypoint_object(scalbnf) add_math_entrypoint_object(scalbnl) add_math_entrypoint_object(scalbnf128) +add_math_entrypoint_object(setpayloadf16) + +add_math_entrypoint_object(setpayloadsigf16) + add_math_entrypoint_object(sincos) add_math_entrypoint_object(sincosf) diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index aa0069d..f509b97 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -3603,6 +3603,45 @@ add_entrypoint_object( ) add_entrypoint_object( + getpayloadf16 + SRCS + getpayloadf16.cpp + HDRS + ../getpayloadf16.h + DEPENDS + libc.src.__support.macros.properties.types + libc.src.__support.FPUtil.basic_operations + COMPILE_OPTIONS + -O3 +) + +add_entrypoint_object( + setpayloadf16 + SRCS + setpayloadf16.cpp + HDRS + ../setpayloadf16.h + DEPENDS + libc.src.__support.macros.properties.types + libc.src.__support.FPUtil.basic_operations + COMPILE_OPTIONS + -O3 +) + +add_entrypoint_object( + setpayloadsigf16 + SRCS + setpayloadsigf16.cpp + HDRS + ../setpayloadsigf16.h + DEPENDS + libc.src.__support.macros.properties.types + libc.src.__support.FPUtil.basic_operations + COMPILE_OPTIONS + -O3 +) + +add_entrypoint_object( f16fmaf SRCS f16fmaf.cpp diff --git a/libc/src/math/generic/getpayloadf16.cpp b/libc/src/math/generic/getpayloadf16.cpp new file mode 100644 index 0000000..0923226 --- /dev/null +++ b/libc/src/math/generic/getpayloadf16.cpp @@ -0,0 +1,19 @@ +//===-- Implementation of getpayloadf16 function --------------------------===// +// +// 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 "src/math/getpayloadf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/common.h" + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(float16, getpayloadf16, (const float16 *x)) { + return fputil::getpayload(*x); +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/math/generic/setpayloadf16.cpp b/libc/src/math/generic/setpayloadf16.cpp new file mode 100644 index 0000000..98fc239 --- /dev/null +++ b/libc/src/math/generic/setpayloadf16.cpp @@ -0,0 +1,19 @@ +//===-- Implementation of setpayloadf16 function --------------------------===// +// +// 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 "src/math/setpayloadf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/common.h" + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, setpayloadf16, (float16 * res, float16 pl)) { + return static_cast<int>(fputil::setpayload</*IsSignaling=*/false>(*res, pl)); +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/math/generic/setpayloadsigf16.cpp b/libc/src/math/generic/setpayloadsigf16.cpp new file mode 100644 index 0000000..c79620f --- /dev/null +++ b/libc/src/math/generic/setpayloadsigf16.cpp @@ -0,0 +1,19 @@ +//===-- Implementation of setpayloadsigf16 function -----------------------===// +// +// 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 "src/math/setpayloadsigf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/common.h" + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, setpayloadsigf16, (float16 * res, float16 pl)) { + return static_cast<int>(fputil::setpayload</*IsSignaling=*/true>(*res, pl)); +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/math/getpayloadf16.h b/libc/src/math/getpayloadf16.h new file mode 100644 index 0000000..1349dfd --- /dev/null +++ b/libc/src/math/getpayloadf16.h @@ -0,0 +1,20 @@ +//===-- Implementation header for getpayloadf16 -----------------*- 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_SRC_MATH_GETPAYLOADF16_H +#define LLVM_LIBC_SRC_MATH_GETPAYLOADF16_H + +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE { + +float16 getpayloadf16(const float16 *x); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_MATH_GETPAYLOADF16_H diff --git a/libc/src/math/setpayloadf16.h b/libc/src/math/setpayloadf16.h new file mode 100644 index 0000000..8705e28 --- /dev/null +++ b/libc/src/math/setpayloadf16.h @@ -0,0 +1,20 @@ +//===-- Implementation header for setpayloadf16 -----------------*- 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_SRC_MATH_SETPAYLOADF16_H +#define LLVM_LIBC_SRC_MATH_SETPAYLOADF16_H + +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE { + +int setpayloadf16(float16 *res, float16 pl); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_MATH_SETPAYLOADF16_H diff --git a/libc/src/math/setpayloadsigf16.h b/libc/src/math/setpayloadsigf16.h new file mode 100644 index 0000000..ee9bc38 --- /dev/null +++ b/libc/src/math/setpayloadsigf16.h @@ -0,0 +1,20 @@ +//===-- Implementation header for setpayloadsigf16 --------------*- 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_SRC_MATH_SETPAYLOADSIGF16_H +#define LLVM_LIBC_SRC_MATH_SETPAYLOADSIGF16_H + +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE { + +int setpayloadsigf16(float16 *res, float16 pl); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_MATH_SETPAYLOADSIGF16_H |