Skip to content

Commit

Permalink
[reland][libc] Add bcopy
Browse files Browse the repository at this point in the history
Differential Revision: https://reviews.llvm.org/D138994
  • Loading branch information
gchatelet committed Dec 1, 2022
1 parent bcdf590 commit 436c8f4
Show file tree
Hide file tree
Showing 14 changed files with 197 additions and 1 deletion.
1 change: 1 addition & 0 deletions libc/config/darwin/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ set(TARGET_LIBC_ENTRYPOINTS

# string.h entrypoints
libc.src.string.bcmp
libc.src.string.bcopy
libc.src.string.bzero
libc.src.string.memccpy
libc.src.string.memchr
Expand Down
1 change: 1 addition & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ set(TARGET_LIBC_ENTRYPOINTS

# string.h entrypoints
libc.src.string.bcmp
libc.src.string.bcopy
libc.src.string.bzero
libc.src.string.memccpy
libc.src.string.memchr
Expand Down
1 change: 1 addition & 0 deletions libc/config/linux/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ set(TARGET_LIBC_ENTRYPOINTS

# string.h entrypoints
libc.src.string.bcmp
libc.src.string.bcopy
libc.src.string.bzero
libc.src.string.memccpy
libc.src.string.memchr
Expand Down
1 change: 1 addition & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ set(TARGET_LIBC_ENTRYPOINTS

# string.h entrypoints
libc.src.string.bcmp
libc.src.string.bcopy
libc.src.string.bzero
libc.src.string.memccpy
libc.src.string.memchr
Expand Down
1 change: 1 addition & 0 deletions libc/config/windows/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ set(TARGET_LIBC_ENTRYPOINTS

# string.h entrypoints
libc.src.string.bcmp
libc.src.string.bcopy
libc.src.string.bzero
libc.src.string.memccpy
libc.src.string.memchr
Expand Down
1 change: 1 addition & 0 deletions libc/docs/strings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Function Name Available
============= =========
bzero |check|
bcmp |check|
bcopy |check|
memcpy |check|
memset |check|
memcmp |check|
Expand Down
5 changes: 5 additions & 0 deletions libc/spec/llvm_libc_ext.td
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ def LLVMLibcExt : StandardSpec<"llvm_libc_ext"> {
[], // Types
[], // Enumerations
[
FunctionSpec<
"bcopy",
RetValSpec<VoidType>,
[ArgSpec<ConstVoidPtr>, ArgSpec<VoidPtr>, ArgSpec<SizeTType>]
>,
FunctionSpec<
"bzero",
RetValSpec<VoidType>,
Expand Down
9 changes: 8 additions & 1 deletion libc/src/string/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ add_header_library(
.memory_utils.memcpy_implementation
)

add_entrypoint_object(
bcopy
SRCS
bcopy.cpp
HDRS
bcopy.h
)

add_entrypoint_object(
memccpy
SRCS
Expand All @@ -28,7 +36,6 @@ add_entrypoint_object(
memccpy.h
)


add_entrypoint_object(
mempcpy
SRCS
Expand Down
19 changes: 19 additions & 0 deletions libc/src/string/bcopy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of bcopy -------------------------------------------===//
//
// 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/string/bcopy.h"
#include "src/__support/common.h"
#include "src/string/memory_utils/memmove_implementations.h"

namespace __llvm_libc {

LLVM_LIBC_FUNCTION(void, bcopy, (const void *src, void *dst, size_t count)) {
return inline_memmove(dst, src, count);
}

} // namespace __llvm_libc
20 changes: 20 additions & 0 deletions libc/src/string/bcopy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for bcopy -------------------------*- 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_STRING_BCOPY_H
#define LLVM_LIBC_SRC_STRING_BCOPY_H

#include <stddef.h> // size_t

namespace __llvm_libc {

void bcopy(const void *src, void *dest, size_t count);

} // namespace __llvm_libc

#endif // LLVM_LIBC_SRC_STRING_BCOPY_H
12 changes: 12 additions & 0 deletions libc/test/src/string/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@ add_libc_testsuite(libc_string_unittests)

add_subdirectory(memory_utils)

add_libc_unittest(
bcopy_test
SUITE
libc_string_unittests
SRCS
bcopy_test.cpp
DEPENDS
libc.src.string.bcopy
LINK_LIBRARIES
LibcMemoryHelpers
)

add_libc_unittest(
memccpy_test
SUITE
Expand Down
104 changes: 104 additions & 0 deletions libc/test/src/string/bcopy_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
//===-- Unittests for bcopy -----------------------------------------------===//
//
// 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/__support/CPP/span.h"
#include "src/string/bcopy.h"
#include "utils/UnitTest/MemoryMatcher.h"
#include "utils/UnitTest/Test.h"

using __llvm_libc::cpp::array;
using __llvm_libc::cpp::span;

TEST(LlvmLibcBcopyTest, MoveZeroByte) {
char Buffer[] = {'a', 'b', 'y', 'z'};
const char Expected[] = {'a', 'b', 'y', 'z'};
void *const Dst = Buffer;
__llvm_libc::bcopy(Buffer + 2, Dst, 0);
ASSERT_MEM_EQ(Buffer, Expected);
}

TEST(LlvmLibcBcopyTest, DstAndSrcPointToSameAddress) {
char Buffer[] = {'a', 'b'};
const char Expected[] = {'a', 'b'};
void *const Dst = Buffer;
__llvm_libc::bcopy(Buffer, Dst, 1);
ASSERT_MEM_EQ(Buffer, Expected);
}

TEST(LlvmLibcBcopyTest, DstStartsBeforeSrc) {
// Set boundary at beginning and end for not overstepping when
// copy forward or backward.
char Buffer[] = {'z', 'a', 'b', 'c', 'z'};
const char Expected[] = {'z', 'b', 'c', 'c', 'z'};
void *const Dst = Buffer + 1;
__llvm_libc::bcopy(Buffer + 2, Dst, 2);
ASSERT_MEM_EQ(Buffer, Expected);
}

TEST(LlvmLibcBcopyTest, DstStartsAfterSrc) {
char Buffer[] = {'z', 'a', 'b', 'c', 'z'};
const char Expected[] = {'z', 'a', 'a', 'b', 'z'};
void *const Dst = Buffer + 2;
__llvm_libc::bcopy(Buffer + 1, Dst, 2);
ASSERT_MEM_EQ(Buffer, Expected);
}

// e.g. `Dst` follow `src`.
// str: [abcdefghij]
// [__src_____]
// [_____Dst__]
TEST(LlvmLibcBcopyTest, SrcFollowDst) {
char Buffer[] = {'z', 'a', 'b', 'z'};
const char Expected[] = {'z', 'b', 'b', 'z'};
void *const Dst = Buffer + 1;
__llvm_libc::bcopy(Buffer + 2, Dst, 1);
ASSERT_MEM_EQ(Buffer, Expected);
}

TEST(LlvmLibcBcopyTest, DstFollowSrc) {
char Buffer[] = {'z', 'a', 'b', 'z'};
const char Expected[] = {'z', 'a', 'a', 'z'};
void *const Dst = Buffer + 2;
__llvm_libc::bcopy(Buffer + 1, Dst, 1);
ASSERT_MEM_EQ(Buffer, Expected);
}

static constexpr int kMaxSize = 512;

char GetRandomChar() {
static constexpr const uint64_t A = 1103515245;
static constexpr const uint64_t C = 12345;
static constexpr const uint64_t M = 1ULL << 31;
static uint64_t Seed = 123456789;
Seed = (A * Seed + C) % M;
return Seed;
}

void Randomize(span<char> Buffer) {
for (auto &current : Buffer)
current = GetRandomChar();
}

TEST(LlvmLibcBcopyTest, SizeSweep) {
using LargeBuffer = array<char, 3 * kMaxSize>;
LargeBuffer GroundTruth;
Randomize(GroundTruth);
for (int Size = 0; Size < kMaxSize; ++Size) {
for (int Offset = -Size; Offset < Size; ++Offset) {
LargeBuffer Buffer = GroundTruth;
LargeBuffer Expected = GroundTruth;
size_t DstOffset = kMaxSize;
size_t SrcOffset = kMaxSize + Offset;
for (int I = 0; I < Size; ++I)
Expected[DstOffset + I] = GroundTruth[SrcOffset + I];
void *const Dst = Buffer.data() + DstOffset;
__llvm_libc::bcopy(Buffer.data() + SrcOffset, Dst, Size);
ASSERT_MEM_EQ(Buffer, Expected);
}
}
}
11 changes: 11 additions & 0 deletions utils/bazel/llvm-project-overlay/libc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,17 @@ libc_function(
],
)

libc_function(
name = "bcopy",
srcs = ["src/string/bcopy.cpp"],
hdrs = ["src/string/bcopy.h"],
features = no_sanitize_features,
deps = [
":__support_common",
":string_memory_utils",
],
)

libc_function(
name = "memcmp",
srcs = ["src/string/memcmp.cpp"],
Expand Down
12 changes: 12 additions & 0 deletions utils/bazel/llvm-project-overlay/libc/test/src/string/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,18 @@ libc_test(
],
)

libc_test(
name = "bcopy_test",
srcs = ["bcopy_test.cpp"],
libc_function_deps = [
"//libc:bcopy",
],
deps = [
"//libc:__support_cpp_span",
"//libc/utils/UnitTest:memory_matcher",
],
)

libc_test(
name = "memcmp_test",
srcs = ["memcmp_test.cpp"],
Expand Down

0 comments on commit 436c8f4

Please sign in to comment.