diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 7e13a7c5793c3..99182e7f92ac0 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -431,8 +431,10 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.math.nexttowardl libc.src.math.nextdown libc.src.math.nextdownf + libc.src.math.nextdownl libc.src.math.nextup libc.src.math.nextupf + libc.src.math.nextupl libc.src.math.powf libc.src.math.remainderf libc.src.math.remainder diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst index 3240a8c5d2456..dbcffc1432e8b 100644 --- a/libc/docs/math/index.rst +++ b/libc/docs/math/index.rst @@ -275,12 +275,28 @@ Basic Operations +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | nextafterf128| |check| | |check| | | |check| | | | | | | | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ +| nextdown | |check| | | | | | | | | | | | | ++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ +| nextdownf | |check| | | | | | | | | | | | | ++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ +| nextdownl | |check| | | | | | | | | | | | | ++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ +| nextdownf128 | |check| | | | | | | | | | | | | ++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | nexttoward | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | nexttowardf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | nexttowardl | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ +| nextup | |check| | | | | | | | | | | | | ++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ +| nextupf | |check| | | | | | | | | | | | | ++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ +| nextupl | |check| | | | | | | | | | | | | ++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ +| nextupf128 | |check| | | | | | | | | | | | | ++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | remainder | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | remainderf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index b438fc6732b08..84d28cc335030 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -538,10 +538,12 @@ def StdC : StandardSpec<"stdc"> { FunctionSpec<"nextdown", RetValSpec, [ArgSpec]>, FunctionSpec<"nextdownf", RetValSpec, [ArgSpec]>, + FunctionSpec<"nextdownl", RetValSpec, [ArgSpec]>, GuardedFunctionSpec<"nextdownf128", RetValSpec, [ArgSpec], "LIBC_TYPES_HAS_FLOAT128">, FunctionSpec<"nextup", RetValSpec, [ArgSpec]>, FunctionSpec<"nextupf", RetValSpec, [ArgSpec]>, + FunctionSpec<"nextupl", RetValSpec, [ArgSpec]>, GuardedFunctionSpec<"nextupf128", RetValSpec, [ArgSpec], "LIBC_TYPES_HAS_FLOAT128">, FunctionSpec<"powf", RetValSpec, [ArgSpec, ArgSpec]>, diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h index 1301caa497da4..201c2b3071040 100644 --- a/libc/src/__support/FPUtil/ManipulationFunctions.h +++ b/libc/src/__support/FPUtil/ManipulationFunctions.h @@ -259,6 +259,7 @@ LIBC_INLINE constexpr T nextupdown(T x) { #ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80 #include "x86_64/NextAfterLongDouble.h" +#include "x86_64/NextUpDownLongDouble.h" #endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80 #endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_MANIPULATIONFUNCTIONS_H diff --git a/libc/src/__support/FPUtil/x86_64/NextUpDownLongDouble.h b/libc/src/__support/FPUtil/x86_64/NextUpDownLongDouble.h new file mode 100644 index 0000000000000..1bc849500be04 --- /dev/null +++ b/libc/src/__support/FPUtil/x86_64/NextUpDownLongDouble.h @@ -0,0 +1,60 @@ +//===-- nextupdown implementation for x86 long double 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_X86_64_NEXTUPDOWNLONGDOUBLE_H +#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_X86_64_NEXTUPDOWNLONGDOUBLE_H + +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/macros/attributes.h" +#include "src/__support/macros/properties/architectures.h" + +#if !defined(LIBC_TARGET_ARCH_IS_X86) +#error "Invalid include" +#endif + +namespace LIBC_NAMESPACE::fputil { + +template +LIBC_INLINE constexpr long double nextupdown(long double x) { + constexpr Sign sign = IsDown ? Sign::NEG : Sign::POS; + + using FPBits_t = FPBits; + FPBits_t xbits(x); + if (xbits.is_nan() || xbits == FPBits_t::max_normal(sign) || + xbits == FPBits_t::inf(sign)) + return x; + + if (x == 0.0l) + return FPBits_t::min_subnormal(sign).get_val(); + + using StorageType = typename FPBits_t::StorageType; + + if (xbits.sign() == sign) { + if (xbits.get_mantissa() == FPBits_t::FRACTION_MASK) { + xbits.set_mantissa(0); + xbits.set_biased_exponent(xbits.get_biased_exponent() + 1); + } else { + xbits = FPBits_t(StorageType(xbits.uintval() + 1)); + } + + return xbits.get_val(); + } + + if (xbits.get_mantissa() == 0) { + xbits.set_mantissa(FPBits_t::FRACTION_MASK); + xbits.set_biased_exponent(xbits.get_biased_exponent() - 1); + } else { + xbits = FPBits_t(StorageType(xbits.uintval() - 1)); + } + + return xbits.get_val(); +} + +} // namespace LIBC_NAMESPACE::fputil + +#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_X86_64_NEXTUPDOWNLONGDOUBLE_H diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt index 6c82caafba4f4..5e2e6e699d0e0 100644 --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -207,10 +207,12 @@ add_math_entrypoint_object(nexttowardl) add_math_entrypoint_object(nextdown) add_math_entrypoint_object(nextdownf) +add_math_entrypoint_object(nextdownl) add_math_entrypoint_object(nextdownf128) add_math_entrypoint_object(nextup) add_math_entrypoint_object(nextupf) +add_math_entrypoint_object(nextupl) add_math_entrypoint_object(nextupf128) add_math_entrypoint_object(pow) diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index ca99863ebffbc..b0a35c652cd58 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -1890,6 +1890,18 @@ add_entrypoint_object( -O3 ) +add_entrypoint_object( + nextdownl + SRCS + nextdownl.cpp + HDRS + ../nextdownl.h + DEPENDS + libc.src.__support.FPUtil.manipulation_functions + COMPILE_OPTIONS + -O3 +) + add_entrypoint_object( nextdownf SRCS @@ -1927,6 +1939,18 @@ add_entrypoint_object( -O3 ) +add_entrypoint_object( + nextupl + SRCS + nextupl.cpp + HDRS + ../nextupl.h + DEPENDS + libc.src.__support.FPUtil.manipulation_functions + COMPILE_OPTIONS + -O3 +) + add_entrypoint_object( nextupf SRCS diff --git a/libc/src/math/generic/nextdownl.cpp b/libc/src/math/generic/nextdownl.cpp new file mode 100644 index 0000000000000..06a09c9daea59 --- /dev/null +++ b/libc/src/math/generic/nextdownl.cpp @@ -0,0 +1,19 @@ +//===-- Implementation of nextdownl 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/nextdownl.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/common.h" + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(long double, nextdownl, (long double x)) { + return fputil::nextupdown(x); +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/math/generic/nextupl.cpp b/libc/src/math/generic/nextupl.cpp new file mode 100644 index 0000000000000..ccc52445eec5c --- /dev/null +++ b/libc/src/math/generic/nextupl.cpp @@ -0,0 +1,19 @@ +//===-- Implementation of nextupl 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/nextupl.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/common.h" + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(long double, nextupl, (long double x)) { + return fputil::nextupdown(x); +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/math/nextdownl.h b/libc/src/math/nextdownl.h new file mode 100644 index 0000000000000..9cb274a89b1c5 --- /dev/null +++ b/libc/src/math/nextdownl.h @@ -0,0 +1,18 @@ +//===-- Implementation header for nextdownl ---------------------*- 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_NEXTDOWNL_H +#define LLVM_LIBC_SRC_MATH_NEXTDOWNL_H + +namespace LIBC_NAMESPACE { + +long double nextdownl(long double x); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_MATH_NEXTDOWNL_H diff --git a/libc/src/math/nextupl.h b/libc/src/math/nextupl.h new file mode 100644 index 0000000000000..cbc6a168e4bea --- /dev/null +++ b/libc/src/math/nextupl.h @@ -0,0 +1,18 @@ +//===-- Implementation header for nextupl -----------------------*- 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_NEXTUPL_H +#define LLVM_LIBC_SRC_MATH_NEXTUPL_H + +namespace LIBC_NAMESPACE { + +long double nextupl(long double x); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_MATH_NEXTUPL_H diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt index 72cb4e9b3c033..85dacce3b21dc 100644 --- a/libc/test/src/math/smoke/CMakeLists.txt +++ b/libc/test/src/math/smoke/CMakeLists.txt @@ -1658,6 +1658,20 @@ add_fp_unittest( libc.src.__support.FPUtil.manipulation_functions ) +add_fp_unittest( + nextdownl_test + SUITE + libc-math-smoke-tests + SRCS + nextdownl_test.cpp + HDRS + NextDownTest.h + DEPENDS + libc.include.math + libc.src.math.nextdownl + libc.src.__support.FPUtil.manipulation_functions +) + add_fp_unittest( nextdownf128_test SUITE @@ -1700,6 +1714,20 @@ add_fp_unittest( libc.src.__support.FPUtil.manipulation_functions ) +add_fp_unittest( + nextupl_test + SUITE + libc-math-smoke-tests + SRCS + nextupl_test.cpp + HDRS + NextUpTest.h + DEPENDS + libc.include.math + libc.src.math.nextupl + libc.src.__support.FPUtil.manipulation_functions +) + add_fp_unittest( nextupf128_test SUITE diff --git a/libc/test/src/math/smoke/nextdownl_test.cpp b/libc/test/src/math/smoke/nextdownl_test.cpp new file mode 100644 index 0000000000000..f1785eb58ce51 --- /dev/null +++ b/libc/test/src/math/smoke/nextdownl_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for nextdownl -------------------------------------------===// +// +// 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 "NextDownTest.h" + +#include "src/math/nextdownl.h" + +LIST_NEXTDOWN_TESTS(long double, LIBC_NAMESPACE::nextdownl) diff --git a/libc/test/src/math/smoke/nextupl_test.cpp b/libc/test/src/math/smoke/nextupl_test.cpp new file mode 100644 index 0000000000000..50f765633c2a5 --- /dev/null +++ b/libc/test/src/math/smoke/nextupl_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for nextupl ---------------------------------------------===// +// +// 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 "NextUpTest.h" + +#include "src/math/nextupl.h" + +LIST_NEXTUP_TESTS(long double, LIBC_NAMESPACE::nextupl) diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 073353a89c890..5e997458c2c60 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -727,7 +727,10 @@ libc_support_library( libc_support_library( name = "__support_fputil_manipulation_functions", hdrs = ["src/__support/FPUtil/ManipulationFunctions.h"], - textual_hdrs = ["src/__support/FPUtil/x86_64/NextAfterLongDouble.h"], + textual_hdrs = [ + "src/__support/FPUtil/x86_64/NextAfterLongDouble.h" + "src/__support/FPUtil/x86_64/NextUpDownLongDouble.h" + ], deps = [ ":__support_common", ":__support_cpp_bit",