[libc-commits] [libc] [libc][math][c23] Add {fromfp, fromfpx, ufromfp, ufromfpx}f16 C23 math functions (PR #94254)
via libc-commits
libc-commits at lists.llvm.org
Mon Jun 3 09:51:21 PDT 2024
https://github.com/overmighty created https://github.com/llvm/llvm-project/pull/94254
cc @lntue
>From 1561fc2fb9ea06d3a3fb49a42d2b032d98a0507b Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Mon, 3 Jun 2024 17:55:30 +0200
Subject: [PATCH 1/4] [libc][math][c23] Add fromfpf16 C23 math function
---
libc/config/linux/aarch64/entrypoints.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/docs/c23.rst | 2 +-
libc/docs/math/index.rst | 2 +-
libc/spec/stdc.td | 3 +-
.../FPUtil/NearestIntegerOperations.h | 12 +-
libc/src/math/CMakeLists.txt | 1 +
libc/src/math/fromfpf16.h | 20 ++++
libc/src/math/generic/CMakeLists.txt | 45 +++++---
libc/src/math/generic/fromfpf16.cpp | 20 ++++
libc/test/src/math/smoke/CMakeLists.txt | 12 ++
libc/test/src/math/smoke/FromfpTest.h | 106 +++++++++---------
libc/test/src/math/smoke/fromfpf16_test.cpp | 13 +++
13 files changed, 161 insertions(+), 77 deletions(-)
create mode 100644 libc/src/math/fromfpf16.h
create mode 100644 libc/src/math/generic/fromfpf16.cpp
create mode 100644 libc/test/src/math/smoke/fromfpf16_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index ca0418c3618ae..37cc94cc41095 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -500,6 +500,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
list(APPEND TARGET_LIBM_ENTRYPOINTS
# math.h C23 _Float16 entrypoints
libc.src.math.fabsf16
+ libc.src.math.fromfpf16
)
endif()
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 367db7d384d23..0e0ea50f19b5c 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -533,6 +533,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
list(APPEND TARGET_LIBM_ENTRYPOINTS
# math.h C23 _Float16 entrypoints
libc.src.math.fabsf16
+ libc.src.math.fromfpf16
)
endif()
diff --git a/libc/docs/c23.rst b/libc/docs/c23.rst
index 8ccfd46271797..80231ccf64422 100644
--- a/libc/docs/c23.rst
+++ b/libc/docs/c23.rst
@@ -55,7 +55,7 @@ Additions:
* powr*
* rootn*
* roundeven* |check|
- * fromfp*
+ * fromfp* |check|
* ufromfp*
* fromfpx*
* nextup*
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index cd90b6ae85769..063be2d2dfc92 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -162,7 +162,7 @@ Basic Operations
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| frexp | |check| | |check| | |check| | | |check| | 7.12.6.7 | F.10.3.7 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fromfp | |check| | |check| | |check| | | |check| | 7.12.9.10 | F.10.6.10 |
+| fromfp | |check| | |check| | |check| | |check| | |check| | 7.12.9.10 | F.10.6.10 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fromfpx | |check| | |check| | |check| | | |check| | 7.12.9.11 | F.10.6.11 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 109721b8b12a0..721abf5645ad9 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -474,7 +474,8 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"fromfp", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
FunctionSpec<"fromfpf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
FunctionSpec<"fromfpl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
- GuardedFunctionSpec<"fromfpf128", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>], "LIBC_TYPES_HAS_FLOAT128">,
+ GuardedFunctionSpec<"fromfpf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>], "LIBC_TYPES_HAS_FLOAT16">,
+ GuardedFunctionSpec<"fromfpf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>], "LIBC_TYPES_HAS_FLOAT128">,
FunctionSpec<"fromfpx", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
FunctionSpec<"fromfpxf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
diff --git a/libc/src/__support/FPUtil/NearestIntegerOperations.h b/libc/src/__support/FPUtil/NearestIntegerOperations.h
index 4645ab0b5350b..97ca91d36ba15 100644
--- a/libc/src/__support/FPUtil/NearestIntegerOperations.h
+++ b/libc/src/__support/FPUtil/NearestIntegerOperations.h
@@ -181,7 +181,9 @@ round_using_specific_rounding_mode(T x, int rnd) {
uint32_t trim_size = FPBits<T>::FRACTION_LEN - exponent;
FPBits<T> new_bits = bits;
- new_bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size);
+ StorageType trunc_mantissa =
+ static_cast<StorageType>((bits.get_mantissa() >> trim_size) << trim_size);
+ new_bits.set_mantissa(trunc_mantissa);
T trunc_value = new_bits.get_val();
// If x is already an integer, return it.
@@ -190,7 +192,8 @@ round_using_specific_rounding_mode(T x, int rnd) {
StorageType trim_value =
bits.get_mantissa() & ((StorageType(1) << trim_size) - 1);
- StorageType half_value = (StorageType(1) << (trim_size - 1));
+ StorageType half_value =
+ static_cast<StorageType>((StorageType(1) << (trim_size - 1)));
// If exponent is 0, trimSize will be equal to the mantissa width, and
// truncIsOdd` will not be correct. So, we handle it as a special case
// below.
@@ -271,7 +274,8 @@ fromfp(T x, int rnd, unsigned int width) {
if (width - 1 > FPBits<T>::EXP_BIAS)
return rounded_value;
- StorageType range_exp = width - 1U + FPBits<T>::EXP_BIAS;
+ StorageType range_exp =
+ static_cast<StorageType>(width - 1 + FPBits<T>::EXP_BIAS);
// rounded_value < -2^(width - 1)
T range_min =
FPBits<T>::create_value(Sign::NEG, range_exp, EXPLICIT_BIT).get_val();
@@ -300,7 +304,7 @@ fromfp(T x, int rnd, unsigned int width) {
if (width > FPBits<T>::EXP_BIAS)
return rounded_value;
- StorageType range_exp = width + FPBits<T>::EXP_BIAS;
+ StorageType range_exp = static_cast<StorageType>(width + FPBits<T>::EXP_BIAS);
// rounded_value > 2^width - 1
T range_max =
FPBits<T>::create_value(Sign::POS, range_exp, EXPLICIT_BIT).get_val() -
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 31df5d0ab8809..5f8d5fbd2472e 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -178,6 +178,7 @@ add_math_entrypoint_object(frexpf128)
add_math_entrypoint_object(fromfp)
add_math_entrypoint_object(fromfpf)
add_math_entrypoint_object(fromfpl)
+add_math_entrypoint_object(fromfpf16)
add_math_entrypoint_object(fromfpf128)
add_math_entrypoint_object(fromfpx)
diff --git a/libc/src/math/fromfpf16.h b/libc/src/math/fromfpf16.h
new file mode 100644
index 0000000000000..6e37c2de2e016
--- /dev/null
+++ b/libc/src/math/fromfpf16.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for fromfpf16 ---------------------*- 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_FROMFPF16_H
+#define LLVM_LIBC_SRC_MATH_FROMFPF16_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float16 fromfpf16(float16 x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFPF16_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 04656e3186181..c52ba20f70206 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -2543,7 +2543,7 @@ add_entrypoint_object(
HDRS
../fromfp.h
DEPENDS
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
@@ -2555,7 +2555,7 @@ add_entrypoint_object(
HDRS
../fromfpf.h
DEPENDS
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
@@ -2567,7 +2567,20 @@ add_entrypoint_object(
HDRS
../fromfpl.h
DEPENDS
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
+ COMPILE_OPTIONS
+ -O3
+)
+
+add_entrypoint_object(
+ fromfpf16
+ SRCS
+ fromfpf16.cpp
+ HDRS
+ ../fromfpf16.h
+ DEPENDS
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
@@ -2580,7 +2593,7 @@ add_entrypoint_object(
../fromfpf128.h
DEPENDS
libc.src.__support.macros.properties.types
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
@@ -2592,7 +2605,7 @@ add_entrypoint_object(
HDRS
../fromfpx.h
DEPENDS
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
@@ -2604,7 +2617,7 @@ add_entrypoint_object(
HDRS
../fromfpxf.h
DEPENDS
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
@@ -2616,7 +2629,7 @@ add_entrypoint_object(
HDRS
../fromfpxl.h
DEPENDS
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
@@ -2629,7 +2642,7 @@ add_entrypoint_object(
../fromfpxf128.h
DEPENDS
libc.src.__support.macros.properties.types
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
@@ -2641,7 +2654,7 @@ add_entrypoint_object(
HDRS
../ufromfp.h
DEPENDS
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
@@ -2653,7 +2666,7 @@ add_entrypoint_object(
HDRS
../ufromfpf.h
DEPENDS
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
@@ -2665,7 +2678,7 @@ add_entrypoint_object(
HDRS
../ufromfpl.h
DEPENDS
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
@@ -2678,7 +2691,7 @@ add_entrypoint_object(
../ufromfpf128.h
DEPENDS
libc.src.__support.macros.properties.types
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
@@ -2690,7 +2703,7 @@ add_entrypoint_object(
HDRS
../ufromfpx.h
DEPENDS
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
@@ -2702,7 +2715,7 @@ add_entrypoint_object(
HDRS
../ufromfpxf.h
DEPENDS
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
@@ -2714,7 +2727,7 @@ add_entrypoint_object(
HDRS
../ufromfpxl.h
DEPENDS
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
@@ -2727,7 +2740,7 @@ add_entrypoint_object(
../ufromfpxf128.h
DEPENDS
libc.src.__support.macros.properties.types
- libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.nearest_integer_operations
COMPILE_OPTIONS
-O3
)
diff --git a/libc/src/math/generic/fromfpf16.cpp b/libc/src/math/generic/fromfpf16.cpp
new file mode 100644
index 0000000000000..36040049fe3aa
--- /dev/null
+++ b/libc/src/math/generic/fromfpf16.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of fromfpf16 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/fromfpf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float16, fromfpf16,
+ (float16 x, int rnd, unsigned int width)) {
+ return fputil::fromfp</*IsSigned=*/true>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index b46fe5e902c67..316036c7d2f73 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -960,6 +960,18 @@ add_fp_unittest(
libc.src.math.fromfpl
)
+add_fp_unittest(
+ fromfpf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fromfpf16_test.cpp
+ HDRS
+ FromfpTest.h
+ DEPENDS
+ libc.src.math.fromfpf16
+)
+
add_fp_unittest(
fromfpf128_test
SUITE
diff --git a/libc/test/src/math/smoke/FromfpTest.h b/libc/test/src/math/smoke/FromfpTest.h
index f19f21ce47e7f..56205187d731c 100644
--- a/libc/test/src/math/smoke/FromfpTest.h
+++ b/libc/test/src/math/smoke/FromfpTest.h
@@ -85,10 +85,10 @@ class FromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ(T(-10.0), func(T(-10.32), FP_INT_UPWARD, 5U));
EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_UPWARD, 5U));
EXPECT_FP_EQ(T(-10.0), func(T(-10.65), FP_INT_UPWARD, 5U));
- EXPECT_FP_EQ(T(1235.0), func(T(1234.38), FP_INT_UPWARD, 12U));
- EXPECT_FP_EQ(T(-1234.0), func(T(-1234.38), FP_INT_UPWARD, 12U));
- EXPECT_FP_EQ(T(1235.0), func(T(1234.96), FP_INT_UPWARD, 12U));
- EXPECT_FP_EQ(T(-1234.0), func(T(-1234.96), FP_INT_UPWARD, 12U));
+ EXPECT_FP_EQ(T(124.0), func(T(123.38), FP_INT_UPWARD, 8U));
+ EXPECT_FP_EQ(T(-123.0), func(T(-123.38), FP_INT_UPWARD, 8U));
+ EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_UPWARD, 8U));
+ EXPECT_FP_EQ(T(-123.0), func(T(-123.96), FP_INT_UPWARD, 8U));
}
void testFractionsUpwardOutsideRange(FromfpFunc func) {
@@ -112,13 +112,13 @@ class FromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_UPWARD, 4U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_UPWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_UPWARD, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_UPWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_UPWARD, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_UPWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_UPWARD, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_UPWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_UPWARD, 7U),
FE_INVALID);
}
@@ -139,10 +139,10 @@ class FromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ(T(-11.0), func(T(-10.32), FP_INT_DOWNWARD, 5U));
EXPECT_FP_EQ(T(10.0), func(T(10.65), FP_INT_DOWNWARD, 5U));
EXPECT_FP_EQ(T(-11.0), func(T(-10.65), FP_INT_DOWNWARD, 5U));
- EXPECT_FP_EQ(T(1234.0), func(T(1234.38), FP_INT_DOWNWARD, 12U));
- EXPECT_FP_EQ(T(-1235.0), func(T(-1234.38), FP_INT_DOWNWARD, 12U));
- EXPECT_FP_EQ(T(1234.0), func(T(1234.96), FP_INT_DOWNWARD, 12U));
- EXPECT_FP_EQ(T(-1235.0), func(T(-1234.96), FP_INT_DOWNWARD, 12U));
+ EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_DOWNWARD, 8U));
+ EXPECT_FP_EQ(T(-124.0), func(T(-123.38), FP_INT_DOWNWARD, 8U));
+ EXPECT_FP_EQ(T(123.0), func(T(123.96), FP_INT_DOWNWARD, 8U));
+ EXPECT_FP_EQ(T(-124.0), func(T(-123.96), FP_INT_DOWNWARD, 8U));
}
void testFractionsDownwardOutsideRange(FromfpFunc func) {
@@ -166,13 +166,13 @@ class FromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_DOWNWARD, 4U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_DOWNWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_DOWNWARD, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_DOWNWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_DOWNWARD, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_DOWNWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_DOWNWARD, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_DOWNWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_DOWNWARD, 7U),
FE_INVALID);
}
@@ -193,10 +193,10 @@ class FromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ(T(-10.0), func(T(-10.32), FP_INT_TOWARDZERO, 5U));
EXPECT_FP_EQ(T(10.0), func(T(10.65), FP_INT_TOWARDZERO, 5U));
EXPECT_FP_EQ(T(-10.0), func(T(-10.65), FP_INT_TOWARDZERO, 5U));
- EXPECT_FP_EQ(T(1234.0), func(T(1234.38), FP_INT_TOWARDZERO, 12U));
- EXPECT_FP_EQ(T(-1234.0), func(T(-1234.38), FP_INT_TOWARDZERO, 12U));
- EXPECT_FP_EQ(T(1234.0), func(T(1234.96), FP_INT_TOWARDZERO, 12U));
- EXPECT_FP_EQ(T(-1234.0), func(T(-1234.96), FP_INT_TOWARDZERO, 12U));
+ EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TOWARDZERO, 8U));
+ EXPECT_FP_EQ(T(-123.0), func(T(-123.38), FP_INT_TOWARDZERO, 8U));
+ EXPECT_FP_EQ(T(123.0), func(T(123.96), FP_INT_TOWARDZERO, 8U));
+ EXPECT_FP_EQ(T(-123.0), func(T(-123.96), FP_INT_TOWARDZERO, 8U));
}
void testFractionsTowardZeroOutsideRange(FromfpFunc func) {
@@ -214,13 +214,13 @@ class FromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TOWARDZERO, 4U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TOWARDZERO, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_TOWARDZERO, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TOWARDZERO, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_TOWARDZERO, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TOWARDZERO, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_TOWARDZERO, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TOWARDZERO, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_TOWARDZERO, 7U),
FE_INVALID);
}
@@ -241,10 +241,10 @@ class FromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ(T(-10.0), func(T(-10.32), FP_INT_TONEARESTFROMZERO, 5U));
EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_TONEARESTFROMZERO, 5U));
EXPECT_FP_EQ(T(-11.0), func(T(-10.65), FP_INT_TONEARESTFROMZERO, 5U));
- EXPECT_FP_EQ(T(1234.0), func(T(1234.38), FP_INT_TONEARESTFROMZERO, 12U));
- EXPECT_FP_EQ(T(-1234.0), func(T(-1234.38), FP_INT_TONEARESTFROMZERO, 12U));
- EXPECT_FP_EQ(T(1235.0), func(T(1234.96), FP_INT_TONEARESTFROMZERO, 12U));
- EXPECT_FP_EQ(T(-1235.0), func(T(-1234.96), FP_INT_TONEARESTFROMZERO, 12U));
+ EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TONEARESTFROMZERO, 8U));
+ EXPECT_FP_EQ(T(-123.0), func(T(-123.38), FP_INT_TONEARESTFROMZERO, 8U));
+ EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_TONEARESTFROMZERO, 8U));
+ EXPECT_FP_EQ(T(-124.0), func(T(-123.96), FP_INT_TONEARESTFROMZERO, 8U));
}
void testFractionsToNearestFromZeroOutsideRange(FromfpFunc func) {
@@ -271,13 +271,13 @@ class FromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_WITH_EXCEPTION(
aNaN, func(T(-10.65), FP_INT_TONEARESTFROMZERO, 4U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.38), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ aNaN, func(T(123.38), FP_INT_TONEARESTFROMZERO, 7U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.38), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ aNaN, func(T(-123.38), FP_INT_TONEARESTFROMZERO, 7U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.96), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ aNaN, func(T(123.96), FP_INT_TONEARESTFROMZERO, 7U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.96), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ aNaN, func(T(-123.96), FP_INT_TONEARESTFROMZERO, 7U), FE_INVALID);
}
void testFractionsToNearestWithinRange(FromfpFunc func) {
@@ -297,10 +297,10 @@ class FromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ(T(-10.0), func(T(-10.32), FP_INT_TONEAREST, 5U));
EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_TONEAREST, 5U));
EXPECT_FP_EQ(T(-11.0), func(T(-10.65), FP_INT_TONEAREST, 5U));
- EXPECT_FP_EQ(T(1234.0), func(T(1234.38), FP_INT_TONEAREST, 12U));
- EXPECT_FP_EQ(T(-1234.0), func(T(-1234.38), FP_INT_TONEAREST, 12U));
- EXPECT_FP_EQ(T(1235.0), func(T(1234.96), FP_INT_TONEAREST, 12U));
- EXPECT_FP_EQ(T(-1235.0), func(T(-1234.96), FP_INT_TONEAREST, 12U));
+ EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TONEAREST, 8U));
+ EXPECT_FP_EQ(T(-123.0), func(T(-123.38), FP_INT_TONEAREST, 8U));
+ EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_TONEAREST, 8U));
+ EXPECT_FP_EQ(T(-124.0), func(T(-123.96), FP_INT_TONEAREST, 8U));
EXPECT_FP_EQ(T(2.0), func(T(2.3), FP_INT_TONEAREST, 3U));
EXPECT_FP_EQ(T(-2.0), func(T(-2.3), FP_INT_TONEAREST, 2U));
@@ -337,13 +337,13 @@ class FromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TONEAREST, 4U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TONEAREST, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_TONEAREST, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TONEAREST, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_TONEAREST, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TONEAREST, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_TONEAREST, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TONEAREST, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_TONEAREST, 7U),
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.3), FP_INT_TONEAREST, 2U),
@@ -391,14 +391,14 @@ class FromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ(T(11.0), func(T(10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 5U));
EXPECT_FP_EQ(T(-11.0),
func(T(-10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 5U));
- EXPECT_FP_EQ(T(1234.0),
- func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U));
- EXPECT_FP_EQ(T(-1234.0),
- func(T(-1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U));
- EXPECT_FP_EQ(T(1235.0),
- func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U));
- EXPECT_FP_EQ(T(-1235.0),
- func(T(-1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U));
+ EXPECT_FP_EQ(T(123.0),
+ func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U));
+ EXPECT_FP_EQ(T(-123.0),
+ func(T(-123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U));
+ EXPECT_FP_EQ(T(124.0),
+ func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U));
+ EXPECT_FP_EQ(T(-124.0),
+ func(T(-123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U));
EXPECT_FP_EQ(T(2.0), func(T(2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U));
EXPECT_FP_EQ(T(-2.0), func(T(-2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U));
@@ -436,16 +436,14 @@ class FromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_WITH_EXCEPTION(
aNaN, func(T(-10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
- FE_INVALID);
+ aNaN, func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ aNaN, func(T(-123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U),
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
- FE_INVALID);
+ aNaN, func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ aNaN, func(T(-123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U),
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
diff --git a/libc/test/src/math/smoke/fromfpf16_test.cpp b/libc/test/src/math/smoke/fromfpf16_test.cpp
new file mode 100644
index 0000000000000..6c3ae94944670
--- /dev/null
+++ b/libc/test/src/math/smoke/fromfpf16_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fromfpf16 -------------------------------------------===//
+//
+// 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 "FromfpTest.h"
+
+#include "src/math/fromfpf16.h"
+
+LIST_FROMFP_TESTS(float16, LIBC_NAMESPACE::fromfpf16)
>From fdfe9d00a747d3034217f16111a159ef36047724 Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Mon, 3 Jun 2024 18:06:50 +0200
Subject: [PATCH 2/4] [libc][math][c23] Add ufromfpf16 C23 math function
---
libc/config/linux/aarch64/entrypoints.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/docs/c23.rst | 2 +-
libc/docs/math/index.rst | 2 +-
libc/spec/stdc.td | 3 +-
libc/src/math/CMakeLists.txt | 1 +
libc/src/math/generic/CMakeLists.txt | 13 ++++
libc/src/math/generic/ufromfpf16.cpp | 20 +++++
libc/src/math/ufromfpf16.h | 20 +++++
libc/test/src/math/smoke/CMakeLists.txt | 12 +++
libc/test/src/math/smoke/UfromfpTest.h | 78 ++++++++++----------
libc/test/src/math/smoke/ufromfpf16_test.cpp | 13 ++++
12 files changed, 123 insertions(+), 43 deletions(-)
create mode 100644 libc/src/math/generic/ufromfpf16.cpp
create mode 100644 libc/src/math/ufromfpf16.h
create mode 100644 libc/test/src/math/smoke/ufromfpf16_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 37cc94cc41095..e600c69aea193 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -501,6 +501,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
# math.h C23 _Float16 entrypoints
libc.src.math.fabsf16
libc.src.math.fromfpf16
+ libc.src.math.ufromfpf16
)
endif()
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 0e0ea50f19b5c..510fe383d3ad6 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -534,6 +534,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
# math.h C23 _Float16 entrypoints
libc.src.math.fabsf16
libc.src.math.fromfpf16
+ libc.src.math.ufromfpf16
)
endif()
diff --git a/libc/docs/c23.rst b/libc/docs/c23.rst
index 80231ccf64422..3915dbd26ed53 100644
--- a/libc/docs/c23.rst
+++ b/libc/docs/c23.rst
@@ -56,7 +56,7 @@ Additions:
* rootn*
* roundeven* |check|
* fromfp* |check|
- * ufromfp*
+ * ufromfp* |check|
* fromfpx*
* nextup*
* nextdown*
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index 063be2d2dfc92..19b67a4e5b40b 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -212,7 +212,7 @@ Basic Operations
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| trunc | |check| | |check| | |check| | | |check| | 7.12.9.9 | F.10.6.9 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| ufromfp | |check| | |check| | |check| | | |check| | 7.12.9.10 | F.10.6.10 |
+| ufromfp | |check| | |check| | |check| | |check| | |check| | 7.12.9.10 | F.10.6.10 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| ufromfpx | |check| | |check| | |check| | | |check| | 7.12.9.11 | F.10.6.11 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 721abf5645ad9..0b990e8e0e9cc 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -485,7 +485,8 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"ufromfp", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
FunctionSpec<"ufromfpf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
FunctionSpec<"ufromfpl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
- GuardedFunctionSpec<"ufromfpf128", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>], "LIBC_TYPES_HAS_FLOAT128">,
+ GuardedFunctionSpec<"ufromfpf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>], "LIBC_TYPES_HAS_FLOAT16">,
+ GuardedFunctionSpec<"ufromfpf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>], "LIBC_TYPES_HAS_FLOAT128">,
FunctionSpec<"ufromfpx", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
FunctionSpec<"ufromfpxf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 5f8d5fbd2472e..3d9b7f29bed74 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -337,6 +337,7 @@ add_math_entrypoint_object(truncf128)
add_math_entrypoint_object(ufromfp)
add_math_entrypoint_object(ufromfpf)
add_math_entrypoint_object(ufromfpl)
+add_math_entrypoint_object(ufromfpf16)
add_math_entrypoint_object(ufromfpf128)
add_math_entrypoint_object(ufromfpx)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index c52ba20f70206..45acfb73a968f 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -2683,6 +2683,19 @@ add_entrypoint_object(
-O3
)
+add_entrypoint_object(
+ ufromfpf16
+ SRCS
+ ufromfpf16.cpp
+ HDRS
+ ../ufromfpf16.h
+ DEPENDS
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.nearest_integer_operations
+ COMPILE_OPTIONS
+ -O3
+)
+
add_entrypoint_object(
ufromfpf128
SRCS
diff --git a/libc/src/math/generic/ufromfpf16.cpp b/libc/src/math/generic/ufromfpf16.cpp
new file mode 100644
index 0000000000000..bf041f463115a
--- /dev/null
+++ b/libc/src/math/generic/ufromfpf16.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of ufromfpf16 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/ufromfpf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float16, ufromfpf16,
+ (float16 x, int rnd, unsigned int width)) {
+ return fputil::fromfp</*IsSigned=*/false>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/ufromfpf16.h b/libc/src/math/ufromfpf16.h
new file mode 100644
index 0000000000000..07a38bd232fc7
--- /dev/null
+++ b/libc/src/math/ufromfpf16.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for ufromfpf16 --------------------*- 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_UFROMFPF16_H
+#define LLVM_LIBC_SRC_MATH_UFROMFPF16_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float16 ufromfpf16(float16 x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_UFROMFPF16_H
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 316036c7d2f73..90dc9d7a52751 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -1068,6 +1068,18 @@ add_fp_unittest(
libc.src.math.ufromfpl
)
+add_fp_unittest(
+ ufromfpf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ ufromfpf16_test.cpp
+ HDRS
+ UfromfpTest.h
+ DEPENDS
+ libc.src.math.ufromfpf16
+)
+
add_fp_unittest(
ufromfpf128_test
SUITE
diff --git a/libc/test/src/math/smoke/UfromfpTest.h b/libc/test/src/math/smoke/UfromfpTest.h
index 1c04049ebb4fa..84c9f805193ed 100644
--- a/libc/test/src/math/smoke/UfromfpTest.h
+++ b/libc/test/src/math/smoke/UfromfpTest.h
@@ -76,8 +76,8 @@ class UfromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ(T(2.0), func(T(1.75), FP_INT_UPWARD, 2U));
EXPECT_FP_EQ(T(11.0), func(T(10.32), FP_INT_UPWARD, 4U));
EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_UPWARD, 4U));
- EXPECT_FP_EQ(T(1235.0), func(T(1234.38), FP_INT_UPWARD, 11U));
- EXPECT_FP_EQ(T(1235.0), func(T(1234.96), FP_INT_UPWARD, 11U));
+ EXPECT_FP_EQ(T(124.0), func(T(123.38), FP_INT_UPWARD, 7U));
+ EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_UPWARD, 7U));
}
void testFractionsUpwardOutsideRange(UfromfpFunc func) {
@@ -101,13 +101,13 @@ class UfromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_UPWARD, 3U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_UPWARD, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_UPWARD, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_UPWARD, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_UPWARD, 32U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_UPWARD, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_UPWARD, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_UPWARD, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_UPWARD, 32U),
FE_INVALID);
}
@@ -120,8 +120,8 @@ class UfromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ(T(1.0), func(T(1.75), FP_INT_DOWNWARD, 1U));
EXPECT_FP_EQ(T(10.0), func(T(10.32), FP_INT_DOWNWARD, 4U));
EXPECT_FP_EQ(T(10.0), func(T(10.65), FP_INT_DOWNWARD, 4U));
- EXPECT_FP_EQ(T(1234.0), func(T(1234.38), FP_INT_DOWNWARD, 11U));
- EXPECT_FP_EQ(T(1234.0), func(T(1234.96), FP_INT_DOWNWARD, 11U));
+ EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_DOWNWARD, 7U));
+ EXPECT_FP_EQ(T(123.0), func(T(123.96), FP_INT_DOWNWARD, 7U));
}
void testFractionsDownwardOutsideRange(UfromfpFunc func) {
@@ -145,13 +145,13 @@ class UfromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_DOWNWARD, 32U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_DOWNWARD, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_DOWNWARD, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_DOWNWARD, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_DOWNWARD, 32U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_DOWNWARD, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_DOWNWARD, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_DOWNWARD, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_DOWNWARD, 32U),
FE_INVALID);
}
@@ -167,8 +167,8 @@ class UfromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ(T(1.0), func(T(1.75), FP_INT_TOWARDZERO, 1U));
EXPECT_FP_EQ(T(10.0), func(T(10.32), FP_INT_TOWARDZERO, 4U));
EXPECT_FP_EQ(T(10.0), func(T(10.65), FP_INT_TOWARDZERO, 4U));
- EXPECT_FP_EQ(T(1234.0), func(T(1234.38), FP_INT_TOWARDZERO, 11U));
- EXPECT_FP_EQ(T(1234.0), func(T(1234.96), FP_INT_TOWARDZERO, 11U));
+ EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TOWARDZERO, 7U));
+ EXPECT_FP_EQ(T(123.0), func(T(123.96), FP_INT_TOWARDZERO, 7U));
}
void testFractionsTowardZeroOutsideRange(UfromfpFunc func) {
@@ -186,13 +186,13 @@ class UfromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TOWARDZERO, 32U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TOWARDZERO, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_TOWARDZERO, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TOWARDZERO, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_TOWARDZERO, 32U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TOWARDZERO, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_TOWARDZERO, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TOWARDZERO, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_TOWARDZERO, 32U),
FE_INVALID);
}
@@ -206,8 +206,8 @@ class UfromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ(T(2.0), func(T(1.75), FP_INT_TONEARESTFROMZERO, 2U));
EXPECT_FP_EQ(T(10.0), func(T(10.32), FP_INT_TONEARESTFROMZERO, 4U));
EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_TONEARESTFROMZERO, 4U));
- EXPECT_FP_EQ(T(1234.0), func(T(1234.38), FP_INT_TONEARESTFROMZERO, 11U));
- EXPECT_FP_EQ(T(1235.0), func(T(1234.96), FP_INT_TONEARESTFROMZERO, 11U));
+ EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TONEARESTFROMZERO, 7U));
+ EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_TONEARESTFROMZERO, 7U));
}
void testFractionsToNearestFromZeroOutsideRange(UfromfpFunc func) {
@@ -234,13 +234,13 @@ class UfromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_WITH_EXCEPTION(
aNaN, func(T(-10.65), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.38), FP_INT_TONEARESTFROMZERO, 10U), FE_INVALID);
+ aNaN, func(T(123.38), FP_INT_TONEARESTFROMZERO, 6U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.38), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ aNaN, func(T(-123.38), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.96), FP_INT_TONEARESTFROMZERO, 10U), FE_INVALID);
+ aNaN, func(T(123.96), FP_INT_TONEARESTFROMZERO, 6U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.96), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ aNaN, func(T(-123.96), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
}
void testFractionsToNearestWithinRange(UfromfpFunc func) {
@@ -254,8 +254,8 @@ class UfromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ(T(2.0), func(T(1.75), FP_INT_TONEAREST, 2U));
EXPECT_FP_EQ(T(10.0), func(T(10.32), FP_INT_TONEAREST, 4U));
EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_TONEAREST, 4U));
- EXPECT_FP_EQ(T(1234.0), func(T(1234.38), FP_INT_TONEAREST, 11U));
- EXPECT_FP_EQ(T(1235.0), func(T(1234.96), FP_INT_TONEAREST, 11U));
+ EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TONEAREST, 7U));
+ EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_TONEAREST, 7U));
EXPECT_FP_EQ(T(2.0), func(T(2.3), FP_INT_TONEAREST, 2U));
EXPECT_FP_EQ(T(2.0), func(T(2.5), FP_INT_TONEAREST, 2U));
@@ -286,13 +286,13 @@ class UfromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TONEAREST, 32U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TONEAREST, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_TONEAREST, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TONEAREST, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_TONEAREST, 32U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TONEAREST, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_TONEAREST, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TONEAREST, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_TONEAREST, 32U),
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.3), FP_INT_TONEAREST, 1U),
@@ -332,10 +332,10 @@ class UfromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ(T(2.0), func(T(1.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U));
EXPECT_FP_EQ(T(10.0), func(T(10.32), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U));
EXPECT_FP_EQ(T(11.0), func(T(10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U));
- EXPECT_FP_EQ(T(1234.0),
- func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U));
- EXPECT_FP_EQ(T(1235.0),
- func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U));
+ EXPECT_FP_EQ(T(123.0),
+ func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U));
+ EXPECT_FP_EQ(T(124.0),
+ func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U));
EXPECT_FP_EQ(T(2.0), func(T(2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U));
EXPECT_FP_EQ(T(2.0), func(T(2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U));
@@ -370,16 +370,14 @@ class UfromfpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
aNaN, func(T(-10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 10U),
- FE_INVALID);
+ aNaN, func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 6U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
+ aNaN, func(T(-123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 10U),
- FE_INVALID);
+ aNaN, func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 6U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
+ aNaN, func(T(-123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
diff --git a/libc/test/src/math/smoke/ufromfpf16_test.cpp b/libc/test/src/math/smoke/ufromfpf16_test.cpp
new file mode 100644
index 0000000000000..641ba823cd03f
--- /dev/null
+++ b/libc/test/src/math/smoke/ufromfpf16_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for ufromfpf16 ------------------------------------------===//
+//
+// 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 "UfromfpTest.h"
+
+#include "src/math/ufromfpf16.h"
+
+LIST_UFROMFP_TESTS(float16, LIBC_NAMESPACE::ufromfpf16)
>From 740ddab6725bb7a545918b28c5352bdbbb6b7e87 Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Mon, 3 Jun 2024 18:22:09 +0200
Subject: [PATCH 3/4] [libc][math][c23] Add fromfpxf16 C23 math function
---
libc/config/linux/aarch64/entrypoints.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/docs/c23.rst | 2 +-
libc/docs/math/index.rst | 2 +-
libc/spec/stdc.td | 3 +-
libc/src/math/CMakeLists.txt | 1 +
libc/src/math/fromfpxf16.h | 20 ++++
libc/src/math/generic/CMakeLists.txt | 13 +++
libc/src/math/generic/fromfpxf16.cpp | 20 ++++
libc/test/src/math/smoke/CMakeLists.txt | 12 ++
libc/test/src/math/smoke/FromfpxTest.h | 112 +++++++++----------
libc/test/src/math/smoke/fromfpxf16_test.cpp | 13 +++
12 files changed, 139 insertions(+), 61 deletions(-)
create mode 100644 libc/src/math/fromfpxf16.h
create mode 100644 libc/src/math/generic/fromfpxf16.cpp
create mode 100644 libc/test/src/math/smoke/fromfpxf16_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index e600c69aea193..b604c69bdb67b 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -501,6 +501,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
# math.h C23 _Float16 entrypoints
libc.src.math.fabsf16
libc.src.math.fromfpf16
+ libc.src.math.fromfpxf16
libc.src.math.ufromfpf16
)
endif()
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 510fe383d3ad6..98e6e82ea9b66 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -534,6 +534,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
# math.h C23 _Float16 entrypoints
libc.src.math.fabsf16
libc.src.math.fromfpf16
+ libc.src.math.fromfpxf16
libc.src.math.ufromfpf16
)
endif()
diff --git a/libc/docs/c23.rst b/libc/docs/c23.rst
index 3915dbd26ed53..a5a7f5bbf25b2 100644
--- a/libc/docs/c23.rst
+++ b/libc/docs/c23.rst
@@ -57,7 +57,7 @@ Additions:
* roundeven* |check|
* fromfp* |check|
* ufromfp* |check|
- * fromfpx*
+ * fromfpx* |check|
* nextup*
* nextdown*
* canonicalize*
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index 19b67a4e5b40b..334b6e6f8bebd 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -164,7 +164,7 @@ Basic Operations
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fromfp | |check| | |check| | |check| | |check| | |check| | 7.12.9.10 | F.10.6.10 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fromfpx | |check| | |check| | |check| | | |check| | 7.12.9.11 | F.10.6.11 |
+| fromfpx | |check| | |check| | |check| | |check| | |check| | 7.12.9.11 | F.10.6.11 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fsub | N/A | | | N/A | | 7.12.14.2 | F.10.11 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 0b990e8e0e9cc..594e29af8f03a 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -480,7 +480,8 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"fromfpx", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
FunctionSpec<"fromfpxf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
FunctionSpec<"fromfpxl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
- GuardedFunctionSpec<"fromfpxf128", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>], "LIBC_TYPES_HAS_FLOAT128">,
+ GuardedFunctionSpec<"fromfpxf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>], "LIBC_TYPES_HAS_FLOAT16">,
+ GuardedFunctionSpec<"fromfpxf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>], "LIBC_TYPES_HAS_FLOAT128">,
FunctionSpec<"ufromfp", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
FunctionSpec<"ufromfpf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 3d9b7f29bed74..8bb21e9aaf94d 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -184,6 +184,7 @@ add_math_entrypoint_object(fromfpf128)
add_math_entrypoint_object(fromfpx)
add_math_entrypoint_object(fromfpxf)
add_math_entrypoint_object(fromfpxl)
+add_math_entrypoint_object(fromfpxf16)
add_math_entrypoint_object(fromfpxf128)
add_math_entrypoint_object(hypot)
diff --git a/libc/src/math/fromfpxf16.h b/libc/src/math/fromfpxf16.h
new file mode 100644
index 0000000000000..f53afbcf3ffdf
--- /dev/null
+++ b/libc/src/math/fromfpxf16.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for fromfpxf16 --------------------*- 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_FROMFPXF16_H
+#define LLVM_LIBC_SRC_MATH_FROMFPXF16_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float16 fromfpxf16(float16 x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFPXF16_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 45acfb73a968f..da170c9c51154 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -2634,6 +2634,19 @@ add_entrypoint_object(
-O3
)
+add_entrypoint_object(
+ fromfpxf16
+ SRCS
+ fromfpxf16.cpp
+ HDRS
+ ../fromfpxf16.h
+ DEPENDS
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.nearest_integer_operations
+ COMPILE_OPTIONS
+ -O3
+)
+
add_entrypoint_object(
fromfpxf128
SRCS
diff --git a/libc/src/math/generic/fromfpxf16.cpp b/libc/src/math/generic/fromfpxf16.cpp
new file mode 100644
index 0000000000000..0854cb6613513
--- /dev/null
+++ b/libc/src/math/generic/fromfpxf16.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of fromfpxf16 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/fromfpxf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float16, fromfpxf16,
+ (float16 x, int rnd, unsigned int width)) {
+ return fputil::fromfpx</*IsSigned=*/true>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 90dc9d7a52751..b7fd5e8214821 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -1020,6 +1020,18 @@ add_fp_unittest(
libc.src.math.fromfpxl
)
+add_fp_unittest(
+ fromfpxf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fromfpxf16_test.cpp
+ HDRS
+ FromfpxTest.h
+ DEPENDS
+ libc.src.math.fromfpxf16
+)
+
add_fp_unittest(
fromfpxf128_test
SUITE
diff --git a/libc/test/src/math/smoke/FromfpxTest.h b/libc/test/src/math/smoke/FromfpxTest.h
index 4aa47a68bb178..a175a66e21b64 100644
--- a/libc/test/src/math/smoke/FromfpxTest.h
+++ b/libc/test/src/math/smoke/FromfpxTest.h
@@ -101,14 +101,14 @@ class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(-10.0), func(T(-10.65), FP_INT_UPWARD, 5U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(1235.0), func(T(1234.38), FP_INT_UPWARD, 12U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.38), FP_INT_UPWARD, 8U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-1234.0), func(T(-1234.38), FP_INT_UPWARD, 12U), FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(1235.0), func(T(1234.96), FP_INT_UPWARD, 12U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-123.0), func(T(-123.38), FP_INT_UPWARD, 8U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.96), FP_INT_UPWARD, 8U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-123.0), func(T(-123.96), FP_INT_UPWARD, 8U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-1234.0), func(T(-1234.96), FP_INT_UPWARD, 12U), FE_INEXACT);
}
void testFractionsUpwardOutsideRange(FromfpxFunc func) {
@@ -132,13 +132,13 @@ class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_UPWARD, 4U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_UPWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_UPWARD, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_UPWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_UPWARD, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_UPWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_UPWARD, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_UPWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_UPWARD, 7U),
FE_INVALID);
}
@@ -175,14 +175,14 @@ class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(-11.0), func(T(-10.65), FP_INT_DOWNWARD, 5U),
FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.38), FP_INT_DOWNWARD, 8U),
+ FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1234.0), func(T(1234.38), FP_INT_DOWNWARD, 12U), FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-1235.0), func(T(-1234.38), FP_INT_DOWNWARD, 12U), FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1234.0), func(T(1234.96), FP_INT_DOWNWARD, 12U), FE_INEXACT);
+ T(-124.0), func(T(-123.38), FP_INT_DOWNWARD, 8U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.96), FP_INT_DOWNWARD, 8U),
+ FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-1235.0), func(T(-1234.96), FP_INT_DOWNWARD, 12U), FE_INEXACT);
+ T(-124.0), func(T(-123.96), FP_INT_DOWNWARD, 8U), FE_INEXACT);
}
void testFractionsDownwardOutsideRange(FromfpxFunc func) {
@@ -206,13 +206,13 @@ class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_DOWNWARD, 4U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_DOWNWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_DOWNWARD, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_DOWNWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_DOWNWARD, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_DOWNWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_DOWNWARD, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_DOWNWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_DOWNWARD, 7U),
FE_INVALID);
}
@@ -250,13 +250,13 @@ class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_WITH_EXCEPTION(
T(-10.0), func(T(-10.65), FP_INT_TOWARDZERO, 5U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1234.0), func(T(1234.38), FP_INT_TOWARDZERO, 12U), FE_INEXACT);
+ T(123.0), func(T(123.38), FP_INT_TOWARDZERO, 8U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-1234.0), func(T(-1234.38), FP_INT_TOWARDZERO, 12U), FE_INEXACT);
+ T(-123.0), func(T(-123.38), FP_INT_TOWARDZERO, 8U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1234.0), func(T(1234.96), FP_INT_TOWARDZERO, 12U), FE_INEXACT);
+ T(123.0), func(T(123.96), FP_INT_TOWARDZERO, 8U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-1234.0), func(T(-1234.96), FP_INT_TOWARDZERO, 12U), FE_INEXACT);
+ T(-123.0), func(T(-123.96), FP_INT_TOWARDZERO, 8U), FE_INEXACT);
}
void testFractionsTowardZeroOutsideRange(FromfpxFunc func) {
@@ -274,13 +274,13 @@ class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TOWARDZERO, 4U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TOWARDZERO, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_TOWARDZERO, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TOWARDZERO, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_TOWARDZERO, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TOWARDZERO, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_TOWARDZERO, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TOWARDZERO, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_TOWARDZERO, 7U),
FE_INVALID);
}
@@ -318,15 +318,13 @@ class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_WITH_EXCEPTION(
T(-11.0), func(T(-10.65), FP_INT_TONEARESTFROMZERO, 5U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1234.0), func(T(1234.38), FP_INT_TONEARESTFROMZERO, 12U), FE_INEXACT);
+ T(123.0), func(T(123.38), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-1234.0), func(T(-1234.38), FP_INT_TONEARESTFROMZERO, 12U),
- FE_INEXACT);
+ T(-123.0), func(T(-123.38), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1235.0), func(T(1234.96), FP_INT_TONEARESTFROMZERO, 12U), FE_INEXACT);
+ T(124.0), func(T(123.96), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-1235.0), func(T(-1234.96), FP_INT_TONEARESTFROMZERO, 12U),
- FE_INEXACT);
+ T(-124.0), func(T(-123.96), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT);
}
void testFractionsToNearestFromZeroOutsideRange(FromfpxFunc func) {
@@ -353,13 +351,13 @@ class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_WITH_EXCEPTION(
aNaN, func(T(-10.65), FP_INT_TONEARESTFROMZERO, 4U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.38), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ aNaN, func(T(123.38), FP_INT_TONEARESTFROMZERO, 7U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.38), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ aNaN, func(T(-123.38), FP_INT_TONEARESTFROMZERO, 7U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.96), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ aNaN, func(T(123.96), FP_INT_TONEARESTFROMZERO, 7U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.96), FP_INT_TONEARESTFROMZERO, 11U), FE_INVALID);
+ aNaN, func(T(-123.96), FP_INT_TONEARESTFROMZERO, 7U), FE_INVALID);
}
void testFractionsToNearestWithinRange(FromfpxFunc func) {
@@ -395,14 +393,14 @@ class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(-11.0), func(T(-10.65), FP_INT_TONEAREST, 5U),
FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.38), FP_INT_TONEAREST, 8U),
+ FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1234.0), func(T(1234.38), FP_INT_TONEAREST, 12U), FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-1234.0), func(T(-1234.38), FP_INT_TONEAREST, 12U), FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1235.0), func(T(1234.96), FP_INT_TONEAREST, 12U), FE_INEXACT);
+ T(-123.0), func(T(-123.38), FP_INT_TONEAREST, 8U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.96), FP_INT_TONEAREST, 8U),
+ FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-1235.0), func(T(-1234.96), FP_INT_TONEAREST, 12U), FE_INEXACT);
+ T(-124.0), func(T(-123.96), FP_INT_TONEAREST, 8U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(2.3), FP_INT_TONEAREST, 3U),
FE_INEXACT);
@@ -451,13 +449,13 @@ class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TONEAREST, 4U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TONEAREST, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_TONEAREST, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TONEAREST, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_TONEAREST, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TONEAREST, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_TONEAREST, 7U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TONEAREST, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_TONEAREST, 7U),
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.3), FP_INT_TONEAREST, 2U),
@@ -532,16 +530,16 @@ class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
T(-11.0), func(T(-10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 5U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1234.0), func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U),
+ T(123.0), func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-1234.0), func(T(-1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U),
+ T(-123.0), func(T(-123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1235.0), func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U),
+ T(124.0), func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-1235.0), func(T(-1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 12U),
+ T(-124.0), func(T(-123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
@@ -598,16 +596,14 @@ class FromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_WITH_EXCEPTION(
aNaN, func(T(-10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
- FE_INVALID);
+ aNaN, func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ aNaN, func(T(-123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U),
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
- FE_INVALID);
+ aNaN, func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ aNaN, func(T(-123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U),
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
diff --git a/libc/test/src/math/smoke/fromfpxf16_test.cpp b/libc/test/src/math/smoke/fromfpxf16_test.cpp
new file mode 100644
index 0000000000000..04ab9e6615b3a
--- /dev/null
+++ b/libc/test/src/math/smoke/fromfpxf16_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fromfpxf16 ------------------------------------------===//
+//
+// 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 "FromfpxTest.h"
+
+#include "src/math/fromfpxf16.h"
+
+LIST_FROMFPX_TESTS(float16, LIBC_NAMESPACE::fromfpxf16)
>From 2e3c1bf2334496b4117a6b78501083f8d93ac7e2 Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Mon, 3 Jun 2024 18:35:45 +0200
Subject: [PATCH 4/4] [libc][math][c23] Add ufromfpxf16 C23 math function
---
libc/config/linux/aarch64/entrypoints.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/docs/c23.rst | 1 +
libc/docs/math/index.rst | 2 +-
libc/spec/stdc.td | 3 +-
libc/src/math/CMakeLists.txt | 1 +
libc/src/math/generic/CMakeLists.txt | 13 +++
libc/src/math/generic/ufromfpxf16.cpp | 20 +++++
libc/src/math/ufromfpxf16.h | 20 +++++
libc/test/src/math/smoke/CMakeLists.txt | 12 +++
libc/test/src/math/smoke/UfromfpxTest.h | 82 +++++++++----------
libc/test/src/math/smoke/ufromfpxf16_test.cpp | 13 +++
12 files changed, 125 insertions(+), 44 deletions(-)
create mode 100644 libc/src/math/generic/ufromfpxf16.cpp
create mode 100644 libc/src/math/ufromfpxf16.h
create mode 100644 libc/test/src/math/smoke/ufromfpxf16_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index b604c69bdb67b..43199e080cd9c 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -503,6 +503,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.fromfpf16
libc.src.math.fromfpxf16
libc.src.math.ufromfpf16
+ libc.src.math.ufromfpxf16
)
endif()
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 98e6e82ea9b66..dbaa288d431ca 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -536,6 +536,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.fromfpf16
libc.src.math.fromfpxf16
libc.src.math.ufromfpf16
+ libc.src.math.ufromfpxf16
)
endif()
diff --git a/libc/docs/c23.rst b/libc/docs/c23.rst
index a5a7f5bbf25b2..33896b5d2fd4d 100644
--- a/libc/docs/c23.rst
+++ b/libc/docs/c23.rst
@@ -58,6 +58,7 @@ Additions:
* fromfp* |check|
* ufromfp* |check|
* fromfpx* |check|
+ * ufromfpx* |check|
* nextup*
* nextdown*
* canonicalize*
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index 334b6e6f8bebd..251eea851071e 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -214,7 +214,7 @@ Basic Operations
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| ufromfp | |check| | |check| | |check| | |check| | |check| | 7.12.9.10 | F.10.6.10 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| ufromfpx | |check| | |check| | |check| | | |check| | 7.12.9.11 | F.10.6.11 |
+| ufromfpx | |check| | |check| | |check| | |check| | |check| | 7.12.9.11 | F.10.6.11 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 594e29af8f03a..f492cebaab4e3 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -492,7 +492,8 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"ufromfpx", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
FunctionSpec<"ufromfpxf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
FunctionSpec<"ufromfpxl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
- GuardedFunctionSpec<"ufromfpxf128", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>], "LIBC_TYPES_HAS_FLOAT128">,
+ GuardedFunctionSpec<"ufromfpxf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>], "LIBC_TYPES_HAS_FLOAT16">,
+ GuardedFunctionSpec<"ufromfpxf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>], "LIBC_TYPES_HAS_FLOAT128">,
FunctionSpec<"hypot", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"hypotf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 8bb21e9aaf94d..ec089c34233fc 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -344,4 +344,5 @@ add_math_entrypoint_object(ufromfpf128)
add_math_entrypoint_object(ufromfpx)
add_math_entrypoint_object(ufromfpxf)
add_math_entrypoint_object(ufromfpxl)
+add_math_entrypoint_object(ufromfpxf16)
add_math_entrypoint_object(ufromfpxf128)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index da170c9c51154..18fbfda2b5240 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -2758,6 +2758,19 @@ add_entrypoint_object(
-O3
)
+add_entrypoint_object(
+ ufromfpxf16
+ SRCS
+ ufromfpxf16.cpp
+ HDRS
+ ../ufromfpxf16.h
+ DEPENDS
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.nearest_integer_operations
+ COMPILE_OPTIONS
+ -O3
+)
+
add_entrypoint_object(
ufromfpxf128
SRCS
diff --git a/libc/src/math/generic/ufromfpxf16.cpp b/libc/src/math/generic/ufromfpxf16.cpp
new file mode 100644
index 0000000000000..aeb7aa8d76b63
--- /dev/null
+++ b/libc/src/math/generic/ufromfpxf16.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of ufromfpxf16 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/ufromfpxf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float16, ufromfpxf16,
+ (float16 x, int rnd, unsigned int width)) {
+ return fputil::fromfpx</*IsSigned=*/false>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/ufromfpxf16.h b/libc/src/math/ufromfpxf16.h
new file mode 100644
index 0000000000000..988092bde319c
--- /dev/null
+++ b/libc/src/math/ufromfpxf16.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for ufromfpxf16 -------------------*- 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_UFROMFPXF16_H
+#define LLVM_LIBC_SRC_MATH_UFROMFPXF16_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float16 ufromfpxf16(float16 x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_UFROMFPXF16_H
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index b7fd5e8214821..d01a4662efc2d 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -1140,6 +1140,18 @@ add_fp_unittest(
libc.src.math.ufromfpxl
)
+add_fp_unittest(
+ ufromfpxf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ ufromfpxf16_test.cpp
+ HDRS
+ UfromfpxTest.h
+ DEPENDS
+ libc.src.math.ufromfpxf16
+)
+
add_fp_unittest(
ufromfpxf128_test
SUITE
diff --git a/libc/test/src/math/smoke/UfromfpxTest.h b/libc/test/src/math/smoke/UfromfpxTest.h
index 973bc8a4d1be7..5916492d79187 100644
--- a/libc/test/src/math/smoke/UfromfpxTest.h
+++ b/libc/test/src/math/smoke/UfromfpxTest.h
@@ -87,9 +87,9 @@ class UfromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(11.0), func(T(10.65), FP_INT_UPWARD, 4U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(1235.0), func(T(1234.38), FP_INT_UPWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.38), FP_INT_UPWARD, 7U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(1235.0), func(T(1234.96), FP_INT_UPWARD, 11U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.96), FP_INT_UPWARD, 7U),
FE_INEXACT);
}
@@ -114,13 +114,13 @@ class UfromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_UPWARD, 3U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_UPWARD, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_UPWARD, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_UPWARD, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_UPWARD, 32U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_UPWARD, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_UPWARD, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_UPWARD, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_UPWARD, 32U),
FE_INVALID);
}
@@ -141,10 +141,10 @@ class UfromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(10.0), func(T(10.65), FP_INT_DOWNWARD, 4U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1234.0), func(T(1234.38), FP_INT_DOWNWARD, 11U), FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1234.0), func(T(1234.96), FP_INT_DOWNWARD, 11U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.38), FP_INT_DOWNWARD, 7U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.96), FP_INT_DOWNWARD, 7U),
+ FE_INEXACT);
}
void testFractionsDownwardOutsideRange(UfromfpxFunc func) {
@@ -168,13 +168,13 @@ class UfromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_DOWNWARD, 32U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_DOWNWARD, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_DOWNWARD, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_DOWNWARD, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_DOWNWARD, 32U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_DOWNWARD, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_DOWNWARD, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_DOWNWARD, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_DOWNWARD, 32U),
FE_INVALID);
}
@@ -202,9 +202,9 @@ class UfromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_WITH_EXCEPTION(T(10.0), func(T(10.65), FP_INT_TOWARDZERO, 4U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1234.0), func(T(1234.38), FP_INT_TOWARDZERO, 11U), FE_INEXACT);
+ T(123.0), func(T(123.38), FP_INT_TOWARDZERO, 7U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1234.0), func(T(1234.96), FP_INT_TOWARDZERO, 11U), FE_INEXACT);
+ T(123.0), func(T(123.96), FP_INT_TOWARDZERO, 7U), FE_INEXACT);
}
void testFractionsTowardZeroOutsideRange(UfromfpxFunc func) {
@@ -222,13 +222,13 @@ class UfromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TOWARDZERO, 32U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TOWARDZERO, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_TOWARDZERO, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TOWARDZERO, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_TOWARDZERO, 32U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TOWARDZERO, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_TOWARDZERO, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TOWARDZERO, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_TOWARDZERO, 32U),
FE_INVALID);
}
@@ -252,9 +252,9 @@ class UfromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_WITH_EXCEPTION(
T(11.0), func(T(10.65), FP_INT_TONEARESTFROMZERO, 4U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1234.0), func(T(1234.38), FP_INT_TONEARESTFROMZERO, 11U), FE_INEXACT);
+ T(123.0), func(T(123.38), FP_INT_TONEARESTFROMZERO, 7U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1235.0), func(T(1234.96), FP_INT_TONEARESTFROMZERO, 11U), FE_INEXACT);
+ T(124.0), func(T(123.96), FP_INT_TONEARESTFROMZERO, 7U), FE_INEXACT);
}
void testFractionsToNearestFromZeroOutsideRange(UfromfpxFunc func) {
@@ -281,13 +281,13 @@ class UfromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_WITH_EXCEPTION(
aNaN, func(T(-10.65), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.38), FP_INT_TONEARESTFROMZERO, 10U), FE_INVALID);
+ aNaN, func(T(123.38), FP_INT_TONEARESTFROMZERO, 6U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.38), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ aNaN, func(T(-123.38), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.96), FP_INT_TONEARESTFROMZERO, 10U), FE_INVALID);
+ aNaN, func(T(123.96), FP_INT_TONEARESTFROMZERO, 6U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.96), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
+ aNaN, func(T(-123.96), FP_INT_TONEARESTFROMZERO, 32U), FE_INVALID);
}
void testFractionsToNearestWithinRange(UfromfpxFunc func) {
@@ -311,10 +311,10 @@ class UfromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(11.0), func(T(10.65), FP_INT_TONEAREST, 4U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1234.0), func(T(1234.38), FP_INT_TONEAREST, 11U), FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1235.0), func(T(1234.96), FP_INT_TONEAREST, 11U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.38), FP_INT_TONEAREST, 7U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.96), FP_INT_TONEAREST, 7U),
+ FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(2.3), FP_INT_TONEAREST, 2U),
FE_INEXACT);
@@ -351,13 +351,13 @@ class UfromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-10.65), FP_INT_TONEAREST, 32U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.38), FP_INT_TONEAREST, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.38), FP_INT_TONEAREST, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.38), FP_INT_TONEAREST, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.38), FP_INT_TONEAREST, 32U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(1234.96), FP_INT_TONEAREST, 10U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(123.96), FP_INT_TONEAREST, 6U),
FE_INVALID);
- EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-1234.96), FP_INT_TONEAREST, 32U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(-123.96), FP_INT_TONEAREST, 32U),
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, func(T(2.3), FP_INT_TONEAREST, 1U),
@@ -414,10 +414,10 @@ class UfromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
T(11.0), func(T(10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1234.0), func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ T(123.0), func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(1235.0), func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 11U),
+ T(124.0), func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
@@ -459,16 +459,14 @@ class UfromfpxTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
aNaN, func(T(-10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 10U),
- FE_INVALID);
+ aNaN, func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 6U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
+ aNaN, func(T(-123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 10U),
- FE_INVALID);
+ aNaN, func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 6U), FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
- aNaN, func(T(-1234.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
+ aNaN, func(T(-123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 32U),
FE_INVALID);
EXPECT_FP_EQ_WITH_EXCEPTION(
diff --git a/libc/test/src/math/smoke/ufromfpxf16_test.cpp b/libc/test/src/math/smoke/ufromfpxf16_test.cpp
new file mode 100644
index 0000000000000..50d93b2545c47
--- /dev/null
+++ b/libc/test/src/math/smoke/ufromfpxf16_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for ufromfpxf16 -----------------------------------------===//
+//
+// 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 "UfromfpxTest.h"
+
+#include "src/math/ufromfpxf16.h"
+
+LIST_UFROMFPX_TESTS(float16, LIBC_NAMESPACE::ufromfpxf16)
More information about the libc-commits
mailing list