Skip to content

Commit 6a3fde6

Browse files
[libc] implement stdc_leading_ones (C23) (#80082)
1 parent ecb5a1b commit 6a3fde6

22 files changed

+468
-8
lines changed

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ set(TARGET_LIBC_ENTRYPOINTS
9797
libc.src.stdbit.stdc_leading_zeros_ui
9898
libc.src.stdbit.stdc_leading_zeros_ul
9999
libc.src.stdbit.stdc_leading_zeros_ull
100+
libc.src.stdbit.stdc_leading_ones_uc
101+
libc.src.stdbit.stdc_leading_ones_us
102+
libc.src.stdbit.stdc_leading_ones_ui
103+
libc.src.stdbit.stdc_leading_ones_ul
104+
libc.src.stdbit.stdc_leading_ones_ull
100105

101106
# stdlib.h entrypoints
102107
libc.src.stdlib.abs

libc/docs/stdbit.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ stdc_leading_zeros_us |check|
3636
stdc_leading_zeros_ui |check|
3737
stdc_leading_zeros_ul |check|
3838
stdc_leading_zeros_ull |check|
39-
stdc_leading_ones_uc
40-
stdc_leading_ones_us
41-
stdc_leading_ones_ui
42-
stdc_leading_ones_ul
43-
stdc_leading_ones_ull
39+
stdc_leading_ones_uc |check|
40+
stdc_leading_ones_us |check|
41+
stdc_leading_ones_ui |check|
42+
stdc_leading_ones_ul |check|
43+
stdc_leading_ones_ull |check|
4444
stdc_trailing_zeros_uc
4545
stdc_trailing_zeros_us
4646
stdc_trailing_zeros_ui
@@ -115,7 +115,7 @@ __STDC_ENDIAN_LITTLE__
115115
__STDC_ENDIAN_BIG__
116116
__STDC_ENDIAN_NATIVE__
117117
stdc_leading_zeros |check|
118-
stdc_leading_ones
118+
stdc_leading_ones |check|
119119
stdc_trailing_zeros
120120
stdc_trailing_ones
121121
stdc_first_leading_zero

libc/include/llvm-libc-macros/stdbit-macros.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,21 @@ inline unsigned long stdc_leading_zeros(unsigned long x) {
2525
inline unsigned long long stdc_leading_zeros(unsigned long long x) {
2626
return stdc_leading_zeros_ull(x);
2727
}
28+
inline unsigned char stdc_leading_ones(unsigned char x) {
29+
return stdc_leading_ones_uc(x);
30+
}
31+
inline unsigned short stdc_leading_ones(unsigned short x) {
32+
return stdc_leading_ones_us(x);
33+
}
34+
inline unsigned stdc_leading_ones(unsigned x) {
35+
return stdc_leading_ones_ui(x);
36+
}
37+
inline unsigned long stdc_leading_ones(unsigned long x) {
38+
return stdc_leading_ones_ul(x);
39+
}
40+
inline unsigned long long stdc_leading_ones(unsigned long long x) {
41+
return stdc_leading_ones_ull(x);
42+
}
2843
#else
2944
#define stdc_leading_zeros(x) \
3045
_Generic((x), \
@@ -33,6 +48,13 @@ inline unsigned long long stdc_leading_zeros(unsigned long long x) {
3348
unsigned: stdc_leading_zeros_ui, \
3449
unsigned long: stdc_leading_zeros_ul, \
3550
unsigned long long: stdc_leading_zeros_ull)(x)
51+
#define stdc_leading_ones(x) \
52+
_Generic((x), \
53+
unsigned char: stdc_leading_ones_uc, \
54+
unsigned short: stdc_leading_ones_us, \
55+
unsigned: stdc_leading_ones_ui, \
56+
unsigned long: stdc_leading_ones_ul, \
57+
unsigned long long: stdc_leading_ones_ull)(x)
3658
#endif // __cplusplus
3759

3860
#endif // __LLVM_LIBC_MACROS_STDBIT_MACROS_H

libc/spec/stdc.td

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,12 @@ def StdC : StandardSpec<"stdc"> {
779779
FunctionSpec<"stdc_leading_zeros_us", RetValSpec<UnsignedShortType>, [ArgSpec<UnsignedShortType>]>,
780780
FunctionSpec<"stdc_leading_zeros_ui", RetValSpec<UnsignedIntType>, [ArgSpec<UnsignedIntType>]>,
781781
FunctionSpec<"stdc_leading_zeros_ul", RetValSpec<UnsignedLongType>, [ArgSpec<UnsignedLongType>]>,
782-
FunctionSpec<"stdc_leading_zeros_ull", RetValSpec<UnsignedLongLongType>, [ArgSpec<UnsignedLongLongType>]>
782+
FunctionSpec<"stdc_leading_zeros_ull", RetValSpec<UnsignedLongLongType>, [ArgSpec<UnsignedLongLongType>]>,
783+
FunctionSpec<"stdc_leading_ones_uc", RetValSpec<UnsignedCharType>, [ArgSpec<UnsignedCharType>]>,
784+
FunctionSpec<"stdc_leading_ones_us", RetValSpec<UnsignedShortType>, [ArgSpec<UnsignedShortType>]>,
785+
FunctionSpec<"stdc_leading_ones_ui", RetValSpec<UnsignedIntType>, [ArgSpec<UnsignedIntType>]>,
786+
FunctionSpec<"stdc_leading_ones_ul", RetValSpec<UnsignedLongType>, [ArgSpec<UnsignedLongType>]>,
787+
FunctionSpec<"stdc_leading_ones_ull", RetValSpec<UnsignedLongLongType>, [ArgSpec<UnsignedLongLongType>]>
783788
] // Functions
784789
>;
785790

libc/src/stdbit/CMakeLists.txt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,53 @@ add_entrypoint_object(
4747
DEPENDS
4848
libc.src.__support.CPP.bit
4949
)
50+
51+
add_entrypoint_object(
52+
stdc_leading_ones_uc
53+
SRCS
54+
stdc_leading_ones_uc.cpp
55+
HDRS
56+
stdc_leading_ones_uc.h
57+
DEPENDS
58+
libc.src.__support.CPP.bit
59+
)
60+
61+
add_entrypoint_object(
62+
stdc_leading_ones_us
63+
SRCS
64+
stdc_leading_ones_us.cpp
65+
HDRS
66+
stdc_leading_ones_us.h
67+
DEPENDS
68+
libc.src.__support.CPP.bit
69+
)
70+
71+
add_entrypoint_object(
72+
stdc_leading_ones_ui
73+
SRCS
74+
stdc_leading_ones_ui.cpp
75+
HDRS
76+
stdc_leading_ones_ui.h
77+
DEPENDS
78+
libc.src.__support.CPP.bit
79+
)
80+
81+
add_entrypoint_object(
82+
stdc_leading_ones_ul
83+
SRCS
84+
stdc_leading_ones_ul.cpp
85+
HDRS
86+
stdc_leading_ones_ul.h
87+
DEPENDS
88+
libc.src.__support.CPP.bit
89+
)
90+
91+
add_entrypoint_object(
92+
stdc_leading_ones_ull
93+
SRCS
94+
stdc_leading_ones_ull.cpp
95+
HDRS
96+
stdc_leading_ones_ull.h
97+
DEPENDS
98+
libc.src.__support.CPP.bit
99+
)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation of stdc_leading_ones_uc ----------------------------===//
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/stdbit/stdc_leading_ones_uc.h"
10+
11+
#include "src/__support/CPP/bit.h"
12+
#include "src/__support/common.h"
13+
14+
namespace LIBC_NAMESPACE {
15+
16+
LLVM_LIBC_FUNCTION(unsigned char, stdc_leading_ones_uc, (unsigned char value)) {
17+
return static_cast<unsigned char>(cpp::countl_one(value));
18+
}
19+
20+
} // namespace LIBC_NAMESPACE
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//===-- Implementation header for stdc_leading_ones_uc ----------*- 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_STDBIT_STDC_LEADING_ONES_UC_H
10+
#define LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_UC_H
11+
12+
namespace LIBC_NAMESPACE {
13+
14+
unsigned char stdc_leading_ones_uc(unsigned char value);
15+
16+
} // namespace LIBC_NAMESPACE
17+
18+
#endif // LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_UC_H
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation of stdc_leading_ones_ui ----------------------------===//
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/stdbit/stdc_leading_ones_ui.h"
10+
11+
#include "src/__support/CPP/bit.h"
12+
#include "src/__support/common.h"
13+
14+
namespace LIBC_NAMESPACE {
15+
16+
LLVM_LIBC_FUNCTION(unsigned, stdc_leading_ones_ui, (unsigned value)) {
17+
return static_cast<unsigned>(cpp::countl_one(value));
18+
}
19+
20+
} // namespace LIBC_NAMESPACE
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//===-- Implementation header for stdc_leading_ones_ui ----------*- 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_STDBIT_STDC_LEADING_ONES_UI_H
10+
#define LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_UI_H
11+
12+
namespace LIBC_NAMESPACE {
13+
14+
unsigned stdc_leading_ones_ui(unsigned value);
15+
16+
} // namespace LIBC_NAMESPACE
17+
18+
#endif // LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_UI_H
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation of stdc_leading_ones_ul ----------------------------===//
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/stdbit/stdc_leading_ones_ul.h"
10+
11+
#include "src/__support/CPP/bit.h"
12+
#include "src/__support/common.h"
13+
14+
namespace LIBC_NAMESPACE {
15+
16+
LLVM_LIBC_FUNCTION(unsigned long, stdc_leading_ones_ul, (unsigned long value)) {
17+
return static_cast<unsigned long>(cpp::countl_one(value));
18+
}
19+
20+
} // namespace LIBC_NAMESPACE
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//===-- Implementation header for stdc_leading_ones_ul ----------*- 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_STDBIT_STDC_LEADING_ONES_UL_H
10+
#define LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_UL_H
11+
12+
namespace LIBC_NAMESPACE {
13+
14+
unsigned long stdc_leading_ones_ul(unsigned long value);
15+
16+
} // namespace LIBC_NAMESPACE
17+
18+
#endif // LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_UL_H
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation of stdc_leading_ones_ull ---------------------------===//
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/stdbit/stdc_leading_ones_ull.h"
10+
11+
#include "src/__support/CPP/bit.h"
12+
#include "src/__support/common.h"
13+
14+
namespace LIBC_NAMESPACE {
15+
16+
LLVM_LIBC_FUNCTION(unsigned long long, stdc_leading_ones_ull,
17+
(unsigned long long value)) {
18+
return static_cast<unsigned long long>(cpp::countl_one(value));
19+
}
20+
21+
} // namespace LIBC_NAMESPACE
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//===-- Implementation header for stdc_leading_ones_ull ---------*- 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_STDBIT_STDC_LEADING_ONES_ULL_H
10+
#define LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_ULL_H
11+
12+
namespace LIBC_NAMESPACE {
13+
14+
unsigned long long stdc_leading_ones_ull(unsigned long long value);
15+
16+
} // namespace LIBC_NAMESPACE
17+
18+
#endif // LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_ULL_H
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation of stdc_leading_ones_us ----------------------------===//
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/stdbit/stdc_leading_ones_us.h"
10+
11+
#include "src/__support/CPP/bit.h"
12+
#include "src/__support/common.h"
13+
14+
namespace LIBC_NAMESPACE {
15+
16+
LLVM_LIBC_FUNCTION(unsigned short, stdc_leading_ones_us,
17+
(unsigned short value)) {
18+
return static_cast<unsigned short>(cpp::countl_one(value));
19+
}
20+
21+
} // namespace LIBC_NAMESPACE
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//===-- Implementation header for stdc_leading_ones_us ----------*- 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_STDBIT_STDC_LEADING_ONES_US_H
10+
#define LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_US_H
11+
12+
namespace LIBC_NAMESPACE {
13+
14+
unsigned short stdc_leading_ones_us(unsigned short value);
15+
16+
} // namespace LIBC_NAMESPACE
17+
18+
#endif // LLVM_LIBC_SRC_STDBIT_STDC_LEADING_ONES_US_H

libc/test/include/stdbit_test.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,13 @@ unsigned short stdc_leading_zeros_us(unsigned short) { return 0xAB; }
2323
unsigned stdc_leading_zeros_ui(unsigned) { return 0xAC; }
2424
unsigned long stdc_leading_zeros_ul(unsigned long) { return 0xAD; }
2525
unsigned long long stdc_leading_zeros_ull(unsigned long long) { return 0xAF; }
26+
unsigned char stdc_leading_ones_uc(unsigned char) { return 0xBA; }
27+
unsigned short stdc_leading_ones_us(unsigned short) { return 0xBB; }
28+
unsigned stdc_leading_ones_ui(unsigned) { return 0xBC; }
29+
unsigned long stdc_leading_ones_ul(unsigned long) { return 0xBD; }
30+
unsigned long long stdc_leading_ones_ull(unsigned long long) { return 0xBF; }
2631

27-
TEST(LlvmLibcStdbitTest, TypeGenericMacro) {
32+
TEST(LlvmLibcStdbitTest, TypeGenericMacroLeadingZeros) {
2833
EXPECT_EQ(stdc_leading_zeros(static_cast<unsigned char>(0U)),
2934
static_cast<unsigned char>(0xAA));
3035
EXPECT_EQ(stdc_leading_zeros(static_cast<unsigned short>(0U)),
@@ -33,3 +38,13 @@ TEST(LlvmLibcStdbitTest, TypeGenericMacro) {
3338
EXPECT_EQ(stdc_leading_zeros(0UL), static_cast<unsigned long>(0xAD));
3439
EXPECT_EQ(stdc_leading_zeros(0ULL), static_cast<unsigned long long>(0xAF));
3540
}
41+
42+
TEST(LlvmLibcStdbitTest, TypeGenericMacroLeadingOnes) {
43+
EXPECT_EQ(stdc_leading_ones(static_cast<unsigned char>(0U)),
44+
static_cast<unsigned char>(0xBA));
45+
EXPECT_EQ(stdc_leading_ones(static_cast<unsigned short>(0U)),
46+
static_cast<unsigned short>(0xBB));
47+
EXPECT_EQ(stdc_leading_ones(0U), static_cast<unsigned>(0xBC));
48+
EXPECT_EQ(stdc_leading_ones(0UL), static_cast<unsigned long>(0xBD));
49+
EXPECT_EQ(stdc_leading_ones(0ULL), static_cast<unsigned long long>(0xBF));
50+
}

0 commit comments

Comments
 (0)