Skip to content

Commit 7bee516

Browse files
committed
[libc][math][c23] Add ldexpf16 C23 math function
1 parent e55d975 commit 7bee516

File tree

13 files changed

+99
-10
lines changed

13 files changed

+99
-10
lines changed

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
519519
libc.src.math.fromfpf16
520520
libc.src.math.fromfpxf16
521521
libc.src.math.ilogbf16
522+
libc.src.math.ldexpf16
522523
libc.src.math.llrintf16
523524
libc.src.math.llroundf16
524525
libc.src.math.lrintf16

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
551551
libc.src.math.fromfpf16
552552
libc.src.math.fromfpxf16
553553
libc.src.math.ilogbf16
554+
libc.src.math.ldexpf16
554555
libc.src.math.llrintf16
555556
libc.src.math.llroundf16
556557
libc.src.math.lrintf16

libc/docs/math/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ Basic Operations
170170
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
171171
| ilogb | |check| | |check| | |check| | |check| | |check| | 7.12.6.8 | F.10.3.8 |
172172
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
173-
| ldexp | |check| | |check| | |check| | | |check| | 7.12.6.9 | F.10.3.9 |
173+
| ldexp | |check| | |check| | |check| | |check| | |check| | 7.12.6.9 | F.10.3.9 |
174174
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
175175
| llogb | |check| | |check| | |check| | | |check| | 7.12.6.10 | F.10.3.10 |
176176
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+

libc/spec/stdc.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ def StdC : StandardSpec<"stdc"> {
527527
FunctionSpec<"ldexp", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>]>,
528528
FunctionSpec<"ldexpf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>]>,
529529
FunctionSpec<"ldexpl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>]>,
530+
GuardedFunctionSpec<"ldexpf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<IntType>], "LIBC_TYPES_HAS_FLOAT16">,
530531
GuardedFunctionSpec<"ldexpf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<IntType>], "LIBC_TYPES_HAS_FLOAT128">,
531532

532533
FunctionSpec<"log10", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,

libc/src/__support/FPUtil/ManipulationFunctions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ LIBC_INLINE constexpr T ldexp(T x, int exp) {
186186
}
187187

188188
// For all other values, NormalFloat to T conversion handles it the right way.
189-
DyadicFloat<FPBits<T>::STORAGE_LEN> normal(bits.get_val());
189+
DyadicFloat<cpp::max(FPBits<T>::STORAGE_LEN, 32)> normal(bits.get_val());
190190
normal.exponent += exp;
191191
return static_cast<T>(normal);
192192
}

libc/src/__support/FPUtil/dyadic_float.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "src/__support/CPP/type_traits.h"
1515
#include "src/__support/big_int.h"
1616
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
17+
#include "src/__support/macros/properties/types.h" // float16
1718

1819
#include <stddef.h>
1920

@@ -183,6 +184,10 @@ template <size_t Bits> struct DyadicFloat {
183184
return r;
184185
}
185186

187+
LIBC_INLINE explicit constexpr operator float16() const {
188+
return static_cast<float16>(static_cast<float>(*this));
189+
}
190+
186191
LIBC_INLINE explicit constexpr operator MantissaType() const {
187192
if (mantissa.is_zero())
188193
return 0;

libc/src/math/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ add_math_entrypoint_object(llogbf128)
220220
add_math_entrypoint_object(ldexp)
221221
add_math_entrypoint_object(ldexpf)
222222
add_math_entrypoint_object(ldexpl)
223+
add_math_entrypoint_object(ldexpf16)
223224
add_math_entrypoint_object(ldexpf128)
224225

225226
add_math_entrypoint_object(log10)

libc/src/math/generic/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,6 +1474,19 @@ add_entrypoint_object(
14741474
libc.src.__support.FPUtil.manipulation_functions
14751475
)
14761476

1477+
add_entrypoint_object(
1478+
ldexpf16
1479+
SRCS
1480+
ldexpf16.cpp
1481+
HDRS
1482+
../ldexpf16.h
1483+
COMPILE_OPTIONS
1484+
-O0 -ggdb3
1485+
DEPENDS
1486+
libc.src.__support.macros.properties.types
1487+
libc.src.__support.FPUtil.manipulation_functions
1488+
)
1489+
14771490
add_entrypoint_object(
14781491
ldexpf128
14791492
SRCS

libc/src/math/generic/ldexpf16.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//===-- Implementation of ldexpf16 function -------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/math/ldexpf16.h"
10+
#include "src/__support/FPUtil/ManipulationFunctions.h"
11+
#include "src/__support/common.h"
12+
13+
namespace LIBC_NAMESPACE {
14+
15+
LLVM_LIBC_FUNCTION(float16, ldexpf16, (float16 x, int exp)) {
16+
return fputil::ldexp(x, exp);
17+
}
18+
19+
} // namespace LIBC_NAMESPACE

libc/src/math/ldexpf16.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation header for ldexpf16 ----------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_MATH_LDEXPF16_H
10+
#define LLVM_LIBC_SRC_MATH_LDEXPF16_H
11+
12+
#include "src/__support/macros/properties/types.h"
13+
14+
namespace LIBC_NAMESPACE {
15+
16+
float16 ldexpf16(float16 x, int exp);
17+
18+
} // namespace LIBC_NAMESPACE
19+
20+
#endif // LLVM_LIBC_SRC_MATH_LDEXPF16_H

libc/test/src/math/smoke/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,6 +1535,21 @@ add_fp_unittest(
15351535
libc.src.__support.FPUtil.normal_float
15361536
)
15371537

1538+
add_fp_unittest(
1539+
ldexpf16_test
1540+
SUITE
1541+
libc-math-smoke-tests
1542+
SRCS
1543+
ldexpf16_test.cpp
1544+
HDRS
1545+
LdExpTest.h
1546+
DEPENDS
1547+
libc.src.math.ldexpf16
1548+
libc.src.__support.CPP.limits
1549+
libc.src.__support.FPUtil.fp_bits
1550+
libc.src.__support.FPUtil.normal_float
1551+
)
1552+
15381553
add_fp_unittest(
15391554
ldexpf128_test
15401555
SUITE

libc/test/src/math/smoke/LdExpTest.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
3131
const T nan = FPBits::quiet_nan().get_val();
3232

3333
// A normalized mantissa to be used with tests.
34-
static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x1234;
34+
static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x123;
3535

3636
public:
3737
typedef T (*LdExpFunc)(T, int);
@@ -60,7 +60,7 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
6060

6161
void testOverflow(LdExpFunc func) {
6262
NormalFloat x(Sign::POS, FPBits::MAX_BIASED_EXPONENT - 10,
63-
NormalFloat::ONE + 0xF00BA);
63+
NormalFloat::ONE + 0xF00);
6464
for (int32_t exp = 10; exp < 100; ++exp) {
6565
ASSERT_FP_EQ(inf, func(T(x), exp));
6666
ASSERT_FP_EQ(neg_inf, func(-T(x), exp));
@@ -95,10 +95,10 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
9595

9696
void testNormalOperation(LdExpFunc func) {
9797
T val_array[] = {// Normal numbers
98-
NormalFloat(Sign::POS, 100, MANTISSA),
99-
NormalFloat(Sign::POS, -100, MANTISSA),
100-
NormalFloat(Sign::NEG, 100, MANTISSA),
101-
NormalFloat(Sign::NEG, -100, MANTISSA),
98+
NormalFloat(Sign::POS, 10, MANTISSA),
99+
NormalFloat(Sign::POS, -10, MANTISSA),
100+
NormalFloat(Sign::NEG, 10, MANTISSA),
101+
NormalFloat(Sign::NEG, -10, MANTISSA),
102102
// Subnormal numbers
103103
NormalFloat(Sign::POS, -FPBits::EXP_BIAS, MANTISSA),
104104
NormalFloat(Sign::NEG, -FPBits::EXP_BIAS, MANTISSA)};
@@ -114,8 +114,8 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
114114
NormalFloat two_to_exp = NormalFloat(static_cast<T>(1.L));
115115
two_to_exp = two_to_exp.mul2(exp);
116116

117-
ASSERT_FP_EQ(func(x, exp), x * two_to_exp);
118-
ASSERT_FP_EQ(func(x, -exp), x / two_to_exp);
117+
ASSERT_FP_EQ(func(x, exp), x * static_cast<T>(two_to_exp));
118+
ASSERT_FP_EQ(func(x, -exp), x / static_cast<T>(two_to_exp));
119119
}
120120
}
121121

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//===-- Unittests for ldexpf16 --------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "LdExpTest.h"
10+
11+
#include "src/math/ldexpf16.h"
12+
13+
LIST_LDEXP_TESTS(float16, LIBC_NAMESPACE::ldexpf16);

0 commit comments

Comments
 (0)