Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.strings.bcmp
libc.src.strings.bcopy
libc.src.strings.bzero
libc.src.strings.ffs
libc.src.strings.ffsl
libc.src.strings.ffsll
libc.src.strings.index
libc.src.strings.rindex
libc.src.strings.strcasecmp
Expand Down
3 changes: 3 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.strings.bcmp
libc.src.strings.bcopy
libc.src.strings.bzero
libc.src.strings.ffs
libc.src.strings.ffsl
libc.src.strings.ffsll
libc.src.strings.index
libc.src.strings.rindex
libc.src.strings.strcasecmp
Expand Down
18 changes: 18 additions & 0 deletions libc/include/strings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,24 @@ functions:
arguments:
- type: void *
- type: size_t
- name: ffs
standards:
- POSIX
return_type: int
arguments:
- type: int
- name: ffsl
standards:
- POSIX
return_type: int
arguments:
- type: long
- name: ffsll
standards:
- POSIX
return_type: int
arguments:
- type: long long
- name: index
standards:
- BSDExtensions
Expand Down
30 changes: 30 additions & 0 deletions libc/src/strings/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,36 @@ add_entrypoint_object(
bcopy.h
)

add_entrypoint_object(
ffs
SRCS
ffs.cpp
HDRS
ffs.h
DEPENDS
libc.src.__support.math_extras
)

add_entrypoint_object(
ffsl
SRCS
ffsl.cpp
HDRS
ffsl.h
DEPENDS
libc.src.__support.math_extras
)

add_entrypoint_object(
ffsll
SRCS
ffsll.cpp
HDRS
ffsll.h
DEPENDS
libc.src.__support.math_extras
)

add_entrypoint_object(
index
SRCS
Expand Down
20 changes: 20 additions & 0 deletions libc/src/strings/ffs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of ffs ---------------------------------------------===//
//
// 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/strings/ffs.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, ffs, (int i)) {
return first_trailing_one(static_cast<unsigned>(i));
}

} // namespace LIBC_NAMESPACE_DECL
20 changes: 20 additions & 0 deletions libc/src/strings/ffs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for ffs ---------------------------*- 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_STRINGS_FFS_H
#define LLVM_LIBC_SRC_STRINGS_FFS_H

#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {

int ffs(int i);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_STRINGS_FFS_H
20 changes: 20 additions & 0 deletions libc/src/strings/ffsl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of ffsl --------------------------------------------===//
//
// 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/strings/ffsl.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, ffsl, (long i)) {
return first_trailing_one(static_cast<unsigned long>(i));
}

} // namespace LIBC_NAMESPACE_DECL
20 changes: 20 additions & 0 deletions libc/src/strings/ffsl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for ffsl --------------------------*- 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_STRINGS_FFSL_H
#define LLVM_LIBC_SRC_STRINGS_FFSL_H

#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {

int ffsl(long i);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_STRINGS_FFSL_H
20 changes: 20 additions & 0 deletions libc/src/strings/ffsll.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of ffsll -------------------------------------------===//
//
// 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/strings/ffsll.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/math_extras.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, ffsll, (long long i)) {
return first_trailing_one(static_cast<unsigned long long>(i));
}

} // namespace LIBC_NAMESPACE_DECL
20 changes: 20 additions & 0 deletions libc/src/strings/ffsll.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for ffsll -------------------------*- 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_STRINGS_FFSLL_H
#define LLVM_LIBC_SRC_STRINGS_FFSLL_H

#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {

int ffsll(long long i);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_STRINGS_FFSLL_H
30 changes: 30 additions & 0 deletions libc/test/src/strings/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,36 @@ add_libc_test(
LibcMemoryHelpers
)

add_libc_test(
ffs_test
SUITE
libc-strings-tests
SRCS
ffs_test.cpp
DEPENDS
libc.src.strings.ffs
)

add_libc_test(
ffsl_test
SUITE
libc-strings-tests
SRCS
ffsl_test.cpp
DEPENDS
libc.src.strings.ffsl
)

add_libc_test(
ffsll_test
SUITE
libc-strings-tests
SRCS
ffsll_test.cpp
DEPENDS
libc.src.strings.ffsll
)

add_libc_test(
index_test
SUITE
Expand Down
32 changes: 32 additions & 0 deletions libc/test/src/strings/ffs_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//===-- Unittests for ffs -------------------------------------------------===//
//
// 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/strings/ffs.h"

#include "src/__support/macros/config.h"
#include "test/UnitTest/Test.h"

namespace LIBC_NAMESPACE_DECL {

TEST(LlvmLibcFfsTest, SimpleFfs) {
ASSERT_EQ(ffs(0x00000000), 0);
ASSERT_EQ(ffs(0x00000001), 1);
ASSERT_EQ(ffs(0x00000020), 6);
ASSERT_EQ(ffs(0x00000400), 11);
ASSERT_EQ(ffs(0x00008000), 16);
ASSERT_EQ(ffs(0x00010000), 17);
ASSERT_EQ(ffs(0x00200000), 22);
ASSERT_EQ(ffs(0x04000000), 27);
ASSERT_EQ(ffs(0x80000000), 32);
ASSERT_EQ(ffs(0xfbe71), 1);
ASSERT_EQ(ffs(0xfbe70), 5);
ASSERT_EQ(ffs(0x10), 5);
ASSERT_EQ(ffs(0x100), 9);
}

} // namespace LIBC_NAMESPACE_DECL
40 changes: 40 additions & 0 deletions libc/test/src/strings/ffsl_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//===-- Unittests for ffsl ------------------------------------------------===//
//
// 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/strings/ffsl.h"

#include "src/__support/macros/config.h"
#include "test/UnitTest/Test.h"

namespace LIBC_NAMESPACE_DECL {

TEST(LlvmLibcFfslTest, SimpleFfsl) {
ASSERT_EQ(ffsl(0x00000000L), 0);
ASSERT_EQ(ffsl(0x00000001L), 1);
ASSERT_EQ(ffsl(0x00000020L), 6);
ASSERT_EQ(ffsl(0x00000400L), 11);
ASSERT_EQ(ffsl(0x00008000L), 16);
ASSERT_EQ(ffsl(0x00010000L), 17);
ASSERT_EQ(ffsl(0x00200000L), 22);
ASSERT_EQ(ffsl(0x04000000L), 27);
ASSERT_EQ(ffsl(0x80000000L), 32);
ASSERT_EQ(ffsl(0x0000000100000000L), 33);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you guard this part, because long might be 32-bit on some platforms.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I almost forgot about this. Thanks for reminding me!

ASSERT_EQ(ffsl(0x0000002000000000L), 38);
ASSERT_EQ(ffsl(0x0000040000000000L), 43);
ASSERT_EQ(ffsl(0x0000800000000000L), 48);
ASSERT_EQ(ffsl(0x0001000000000000L), 49);
ASSERT_EQ(ffsl(0x0020000000000000L), 54);
ASSERT_EQ(ffsl(0x0400000000000000L), 59);
ASSERT_EQ(ffsl(0x8000000000000000L), 64);
ASSERT_EQ(ffsl(0xfbe71L), 1);
ASSERT_EQ(ffsl(0xfbe70L), 5);
ASSERT_EQ(ffsl(0x10L), 5);
ASSERT_EQ(ffsl(0x100L), 9);
}

} // namespace LIBC_NAMESPACE_DECL
40 changes: 40 additions & 0 deletions libc/test/src/strings/ffsll_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//===-- Unittests for ffsll -----------------------------------------------===//
//
// 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/strings/ffsll.h"

#include "src/__support/macros/config.h"
#include "test/UnitTest/Test.h"

namespace LIBC_NAMESPACE_DECL {

TEST(LlvmLibcFfsllTest, SimpleFfsll) {
ASSERT_EQ(ffsll(0x0000000000000000LL), 0);
ASSERT_EQ(ffsll(0x0000000000000001LL), 1);
ASSERT_EQ(ffsll(0x0000000000000020LL), 6);
ASSERT_EQ(ffsll(0x0000000000000400LL), 11);
ASSERT_EQ(ffsll(0x0000000000008000LL), 16);
ASSERT_EQ(ffsll(0x0000000000010000LL), 17);
ASSERT_EQ(ffsll(0x0000000000200000LL), 22);
ASSERT_EQ(ffsll(0x0000000004000000LL), 27);
ASSERT_EQ(ffsll(0x0000000080000000LL), 32);
ASSERT_EQ(ffsll(0x0000000100000000LL), 33);
ASSERT_EQ(ffsll(0x0000002000000000LL), 38);
ASSERT_EQ(ffsll(0x0000040000000000LL), 43);
ASSERT_EQ(ffsll(0x0000800000000000LL), 48);
ASSERT_EQ(ffsll(0x0001000000000000LL), 49);
ASSERT_EQ(ffsll(0x0020000000000000LL), 54);
ASSERT_EQ(ffsll(0x0400000000000000LL), 59);
ASSERT_EQ(ffsll(0x8000000000000000LL), 64);
ASSERT_EQ(ffsll(0xfbe71LL), 1);
ASSERT_EQ(ffsll(0xfbe70LL), 5);
ASSERT_EQ(ffsll(0x10LL), 5);
ASSERT_EQ(ffsll(0x100LL), 9);
}

} // namespace LIBC_NAMESPACE_DECL