diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index f75b267931399..bc09f48812286 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -386,6 +386,7 @@ if(LIBC_COMPILER_HAS_FLOAT128) libc.src.math.floorf128 libc.src.math.fmaxf128 libc.src.math.fminf128 + libc.src.math.frexpf128 libc.src.math.roundf128 libc.src.math.sqrtf128 libc.src.math.truncf128 diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index 762beb9040154..02412e7549a3d 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -395,6 +395,7 @@ if(LIBC_COMPILER_HAS_FLOAT128) libc.src.math.floorf128 libc.src.math.fmaxf128 libc.src.math.fminf128 + libc.src.math.frexpf128 libc.src.math.roundf128 libc.src.math.sqrtf128 libc.src.math.truncf128 diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 52a3ce0132bdc..8ca9375895c49 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -414,6 +414,7 @@ if(LIBC_COMPILER_HAS_FLOAT128) libc.src.math.floorf128 libc.src.math.fmaxf128 libc.src.math.fminf128 + libc.src.math.frexpf128 libc.src.math.roundf128 libc.src.math.sqrtf128 libc.src.math.truncf128 diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst index 2758b42610d0e..94604491a73ec 100644 --- a/libc/docs/math/index.rst +++ b/libc/docs/math/index.rst @@ -176,6 +176,8 @@ Basic Operations +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | frexpl | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ +| frexpf128 | |check| | |check| | | |check| | | | | | | | | | ++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | ilogb | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | ilogbf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index 9c8b5e5c46627..afddc77b07da6 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -401,6 +401,7 @@ def StdC : StandardSpec<"stdc"> { FunctionSpec<"frexp", RetValSpec, [ArgSpec, ArgSpec]>, FunctionSpec<"frexpf", RetValSpec, [ArgSpec, ArgSpec]>, FunctionSpec<"frexpl", RetValSpec, [ArgSpec, ArgSpec]>, + GuardedFunctionSpec<"frexpf128", RetValSpec, [ArgSpec, ArgSpec]], "LIBC_COMPILER_HAS_FLOAT128">, FunctionSpec<"hypot", RetValSpec, [ArgSpec, ArgSpec]>, FunctionSpec<"hypotf", RetValSpec, [ArgSpec, ArgSpec]>, diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt index 8cdd84a0f6711..985585cbfb890 100644 --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -137,6 +137,7 @@ add_math_entrypoint_object(fmodf) add_math_entrypoint_object(frexp) add_math_entrypoint_object(frexpf) add_math_entrypoint_object(frexpl) +add_math_entrypoint_object(frexpf128) add_math_entrypoint_object(hypot) add_math_entrypoint_object(hypotf) diff --git a/libc/src/math/frexpf128.h b/libc/src/math/frexpf128.h new file mode 100644 index 0000000000000..5d70860fa1559 --- /dev/null +++ b/libc/src/math/frexpf128.h @@ -0,0 +1,20 @@ +//===-- Implementation header for frexpf128 ---------------------*- 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_FREXPF128_H +#define LLVM_LIBC_SRC_MATH_FREXPF128_H + +#include "src/__support/macros/properties/float.h" + +namespace LIBC_NAMESPACE { + +float128 frexpf128(float128 x, int *exp); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_MATH_FREXPF128_H diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index 3216ec39401f3..fdf383f070697 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -916,10 +916,10 @@ add_entrypoint_object( frexp.cpp HDRS ../frexp.h + COMPILE_OPTIONS + -O3 DEPENDS libc.src.__support.FPUtil.manipulation_functions - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -928,10 +928,10 @@ add_entrypoint_object( frexpf.cpp HDRS ../frexpf.h + COMPILE_OPTIONS + -O3 DEPENDS libc.src.__support.FPUtil.manipulation_functions - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -940,10 +940,23 @@ add_entrypoint_object( frexpl.cpp HDRS ../frexpl.h + COMPILE_OPTIONS + -O3 DEPENDS libc.src.__support.FPUtil.manipulation_functions +) + +add_entrypoint_object( + frexpf128 + SRCS + frexpf128.cpp + HDRS + ../frexpf128.h COMPILE_OPTIONS - -O2 + -O3 + DEPENDS + libc.src.__support.macros.properties.float + libc.src.__support.FPUtil.manipulation_functions ) add_entrypoint_object( diff --git a/libc/src/math/generic/frexpf128.cpp b/libc/src/math/generic/frexpf128.cpp new file mode 100644 index 0000000000000..b50f37d2dab4b --- /dev/null +++ b/libc/src/math/generic/frexpf128.cpp @@ -0,0 +1,19 @@ +//===-- Implementation of frexpf128 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/frexpf128.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/common.h" + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(float128, frexpf128, (float128 x, int *exp)) { + return fputil::frexp(x, *exp); +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt index 93ce0b716cce8..0d55be5d98bdc 100644 --- a/libc/test/src/math/smoke/CMakeLists.txt +++ b/libc/test/src/math/smoke/CMakeLists.txt @@ -779,9 +779,7 @@ add_fp_unittest( HDRS FrexpTest.h DEPENDS - libc.include.math libc.src.math.frexp - libc.src.__support.FPUtil.basic_operations ) add_fp_unittest( @@ -793,9 +791,7 @@ add_fp_unittest( HDRS FrexpTest.h DEPENDS - libc.include.math libc.src.math.frexpf - libc.src.__support.FPUtil.basic_operations ) add_fp_unittest( @@ -807,9 +803,19 @@ add_fp_unittest( HDRS FrexpTest.h DEPENDS - libc.include.math libc.src.math.frexpl - libc.src.__support.FPUtil.basic_operations +) + +add_fp_unittest( + frexpf128_test + SUITE + libc-math-smoke-tests + SRCS + frexpf128_test.cpp + HDRS + FrexpTest.h + DEPENDS + libc.src.math.frexpf128 ) # FIXME: These tests are currently broken for NVPTX. diff --git a/libc/test/src/math/smoke/FrexpTest.h b/libc/test/src/math/smoke/FrexpTest.h index 981872aa128e1..bf99a9a559f05 100644 --- a/libc/test/src/math/smoke/FrexpTest.h +++ b/libc/test/src/math/smoke/FrexpTest.h @@ -10,81 +10,76 @@ #include "test/UnitTest/FPMatcher.h" #include "test/UnitTest/Test.h" -#include - template class FrexpTest : public LIBC_NAMESPACE::testing::Test { DECLARE_SPECIAL_CONSTANTS(T) - static constexpr StorageType HIDDEN_BIT = - StorageType(1) << LIBC_NAMESPACE::fputil::FPBits::FRACTION_LEN; - public: typedef T (*FrexpFunc)(T, int *); void testSpecialNumbers(FrexpFunc func) { int exponent; - ASSERT_FP_EQ(aNaN, func(aNaN, &exponent)); - ASSERT_FP_EQ(inf, func(inf, &exponent)); - ASSERT_FP_EQ(neg_inf, func(neg_inf, &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(aNaN, &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(inf, func(inf, &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, func(neg_inf, &exponent)); - ASSERT_FP_EQ(0.0, func(0.0, &exponent)); - ASSERT_EQ(exponent, 0); + EXPECT_FP_EQ_ALL_ROUNDING(0.0, func(0.0, &exponent)); + EXPECT_EQ(exponent, 0); - ASSERT_FP_EQ(-0.0, func(-0.0, &exponent)); - ASSERT_EQ(exponent, 0); + EXPECT_FP_EQ_ALL_ROUNDING(-0.0, func(-0.0, &exponent)); + EXPECT_EQ(exponent, 0); } void testPowersOfTwo(FrexpFunc func) { int exponent; - EXPECT_FP_EQ(T(0.5), func(T(1.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(1.0), &exponent)); EXPECT_EQ(exponent, 1); - EXPECT_FP_EQ(T(-0.5), func(T(-1.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-1.0), &exponent)); EXPECT_EQ(exponent, 1); - EXPECT_FP_EQ(T(0.5), func(T(2.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(2.0), &exponent)); EXPECT_EQ(exponent, 2); - EXPECT_FP_EQ(T(-0.5), func(T(-2.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-2.0), &exponent)); EXPECT_EQ(exponent, 2); - EXPECT_FP_EQ(T(0.5), func(T(4.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(4.0), &exponent)); EXPECT_EQ(exponent, 3); - EXPECT_FP_EQ(T(-0.5), func(T(-4.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-4.0), &exponent)); EXPECT_EQ(exponent, 3); - EXPECT_FP_EQ(T(0.5), func(T(8.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(8.0), &exponent)); EXPECT_EQ(exponent, 4); - EXPECT_FP_EQ(T(-0.5), func(T(-8.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-8.0), &exponent)); EXPECT_EQ(exponent, 4); - EXPECT_FP_EQ(T(0.5), func(T(16.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(16.0), &exponent)); EXPECT_EQ(exponent, 5); - EXPECT_FP_EQ(T(-0.5), func(T(-16.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-16.0), &exponent)); EXPECT_EQ(exponent, 5); - EXPECT_FP_EQ(T(0.5), func(T(32.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(32.0), &exponent)); EXPECT_EQ(exponent, 6); - EXPECT_FP_EQ(T(-0.5), func(T(-32.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-32.0), &exponent)); EXPECT_EQ(exponent, 6); } void testSomeIntegers(FrexpFunc func) { int exponent; - EXPECT_FP_EQ(T(0.75), func(T(24.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(0.75), func(T(24.0), &exponent)); EXPECT_EQ(exponent, 5); - EXPECT_FP_EQ(T(-0.75), func(T(-24.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(-0.75), func(T(-24.0), &exponent)); EXPECT_EQ(exponent, 5); - EXPECT_FP_EQ(T(0.625), func(T(40.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(0.625), func(T(40.0), &exponent)); EXPECT_EQ(exponent, 6); - EXPECT_FP_EQ(T(-0.625), func(T(-40.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(-0.625), func(T(-40.0), &exponent)); EXPECT_EQ(exponent, 6); - EXPECT_FP_EQ(T(0.78125), func(T(800.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(0.78125), func(T(800.0), &exponent)); EXPECT_EQ(exponent, 10); - EXPECT_FP_EQ(T(-0.78125), func(T(-800.0), &exponent)); + EXPECT_FP_EQ_ALL_ROUNDING(T(-0.78125), func(T(-800.0), &exponent)); EXPECT_EQ(exponent, 10); } }; @@ -93,4 +88,5 @@ template class FrexpTest : public LIBC_NAMESPACE::testing::Test { using LlvmLibcFrexpTest = FrexpTest; \ TEST_F(LlvmLibcFrexpTest, SpecialNumbers) { testSpecialNumbers(&func); } \ TEST_F(LlvmLibcFrexpTest, PowersOfTwo) { testPowersOfTwo(&func); } \ - TEST_F(LlvmLibcFrexpTest, SomeIntegers) { testSomeIntegers(&func); } + TEST_F(LlvmLibcFrexpTest, SomeIntegers) { testSomeIntegers(&func); } \ + static_assert(true, "Require semicolon.") diff --git a/libc/test/src/math/smoke/frexp_test.cpp b/libc/test/src/math/smoke/frexp_test.cpp index 4d078baffcb39..79aa9723d3147 100644 --- a/libc/test/src/math/smoke/frexp_test.cpp +++ b/libc/test/src/math/smoke/frexp_test.cpp @@ -10,4 +10,4 @@ #include "src/math/frexp.h" -LIST_FREXP_TESTS(double, LIBC_NAMESPACE::frexp) +LIST_FREXP_TESTS(double, LIBC_NAMESPACE::frexp); diff --git a/libc/test/src/math/smoke/frexpf128_test.cpp b/libc/test/src/math/smoke/frexpf128_test.cpp new file mode 100644 index 0000000000000..a0df32f5fbdd9 --- /dev/null +++ b/libc/test/src/math/smoke/frexpf128_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for frexpf128 -------------------------------------------===// +// +// 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 "FrexpTest.h" + +#include "src/math/frexpf128.h" + +LIST_FREXP_TESTS(float128, LIBC_NAMESPACE::frexpf128); diff --git a/libc/test/src/math/smoke/frexpf_test.cpp b/libc/test/src/math/smoke/frexpf_test.cpp index 577eb9609cfcc..f2ae637e9a6c9 100644 --- a/libc/test/src/math/smoke/frexpf_test.cpp +++ b/libc/test/src/math/smoke/frexpf_test.cpp @@ -10,4 +10,4 @@ #include "src/math/frexpf.h" -LIST_FREXP_TESTS(float, LIBC_NAMESPACE::frexpf) +LIST_FREXP_TESTS(float, LIBC_NAMESPACE::frexpf); diff --git a/libc/test/src/math/smoke/frexpl_test.cpp b/libc/test/src/math/smoke/frexpl_test.cpp index e5184cd225bcf..3e1f8b4204e6a 100644 --- a/libc/test/src/math/smoke/frexpl_test.cpp +++ b/libc/test/src/math/smoke/frexpl_test.cpp @@ -10,4 +10,4 @@ #include "src/math/frexpl.h" -LIST_FREXP_TESTS(long double, LIBC_NAMESPACE::frexpl) +LIST_FREXP_TESTS(long double, LIBC_NAMESPACE::frexpl);