Skip to content

Commit 2bd9b14

Browse files
committed
[libc][math][c23] Add ldexpf16 C23 math function
1 parent 2cf1439 commit 2bd9b14

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
@@ -520,6 +520,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
520520
libc.src.math.fromfpf16
521521
libc.src.math.fromfpxf16
522522
libc.src.math.ilogbf16
523+
libc.src.math.ldexpf16
523524
libc.src.math.llogbf16
524525
libc.src.math.llrintf16
525526
libc.src.math.llroundf16

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
553553
libc.src.math.fromfpf16
554554
libc.src.math.fromfpxf16
555555
libc.src.math.ilogbf16
556+
libc.src.math.ldexpf16
556557
libc.src.math.llogbf16
557558
libc.src.math.llrintf16
558559
libc.src.math.llroundf16

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| | |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
@@ -532,6 +532,7 @@ def StdC : StandardSpec<"stdc"> {
532532
FunctionSpec<"ldexp", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>]>,
533533
FunctionSpec<"ldexpf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>]>,
534534
FunctionSpec<"ldexpl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>]>,
535+
GuardedFunctionSpec<"ldexpf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<IntType>], "LIBC_TYPES_HAS_FLOAT16">,
535536
GuardedFunctionSpec<"ldexpf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<IntType>], "LIBC_TYPES_HAS_FLOAT128">,
536537

537538
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
@@ -224,6 +224,7 @@ add_math_entrypoint_object(llogbf128)
224224
add_math_entrypoint_object(ldexp)
225225
add_math_entrypoint_object(ldexpf)
226226
add_math_entrypoint_object(ldexpl)
227+
add_math_entrypoint_object(ldexpf16)
227228
add_math_entrypoint_object(ldexpf128)
228229

229230
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
@@ -1487,6 +1487,19 @@ add_entrypoint_object(
14871487
libc.src.__support.FPUtil.manipulation_functions
14881488
)
14891489

1490+
add_entrypoint_object(
1491+
ldexpf16
1492+
SRCS
1493+
ldexpf16.cpp
1494+
HDRS
1495+
../ldexpf16.h
1496+
COMPILE_OPTIONS
1497+
-O0 -ggdb3
1498+
DEPENDS
1499+
libc.src.__support.macros.properties.types
1500+
libc.src.__support.FPUtil.manipulation_functions
1501+
)
1502+
14901503
add_entrypoint_object(
14911504
ldexpf128
14921505
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
@@ -1550,6 +1550,21 @@ add_fp_unittest(
15501550
libc.src.__support.FPUtil.normal_float
15511551
)
15521552

1553+
add_fp_unittest(
1554+
ldexpf16_test
1555+
SUITE
1556+
libc-math-smoke-tests
1557+
SRCS
1558+
ldexpf16_test.cpp
1559+
HDRS
1560+
LdExpTest.h
1561+
DEPENDS
1562+
libc.src.math.ldexpf16
1563+
libc.src.__support.CPP.limits
1564+
libc.src.__support.FPUtil.fp_bits
1565+
libc.src.__support.FPUtil.normal_float
1566+
)
1567+
15531568
add_fp_unittest(
15541569
ldexpf128_test
15551570
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)