[reland][libc] Add bcopy

Differential Revision: https://reviews.llvm.org/D138994
This commit is contained in:
Guillaume Chatelet 2022-12-01 10:06:36 +00:00
parent bcdf590b81
commit 436c8f4420
14 changed files with 197 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -36,6 +36,7 @@ Function Name Available
============= =========
bzero |check|
bcmp |check|
bcopy |check|
memcpy |check|
memset |check|
memcmp |check|

View File

@ -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>,

View File

@ -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
@ -28,7 +36,6 @@ add_entrypoint_object(
memccpy.h
)
add_entrypoint_object(
mempcpy
SRCS

19
libc/src/string/bcopy.cpp Normal file
View File

@ -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
libc/src/string/bcopy.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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"],

View File

@ -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"],