forked from OSchip/llvm-project
[reland][libc] Add bcopy
Differential Revision: https://reviews.llvm.org/D138994
This commit is contained in:
parent
bcdf590b81
commit
436c8f4420
|
@ -19,6 +19,7 @@ set(TARGET_LIBC_ENTRYPOINTS
|
||||||
|
|
||||||
# string.h entrypoints
|
# string.h entrypoints
|
||||||
libc.src.string.bcmp
|
libc.src.string.bcmp
|
||||||
|
libc.src.string.bcopy
|
||||||
libc.src.string.bzero
|
libc.src.string.bzero
|
||||||
libc.src.string.memccpy
|
libc.src.string.memccpy
|
||||||
libc.src.string.memchr
|
libc.src.string.memchr
|
||||||
|
|
|
@ -28,6 +28,7 @@ set(TARGET_LIBC_ENTRYPOINTS
|
||||||
|
|
||||||
# string.h entrypoints
|
# string.h entrypoints
|
||||||
libc.src.string.bcmp
|
libc.src.string.bcmp
|
||||||
|
libc.src.string.bcopy
|
||||||
libc.src.string.bzero
|
libc.src.string.bzero
|
||||||
libc.src.string.memccpy
|
libc.src.string.memccpy
|
||||||
libc.src.string.memchr
|
libc.src.string.memchr
|
||||||
|
|
|
@ -19,6 +19,7 @@ set(TARGET_LIBC_ENTRYPOINTS
|
||||||
|
|
||||||
# string.h entrypoints
|
# string.h entrypoints
|
||||||
libc.src.string.bcmp
|
libc.src.string.bcmp
|
||||||
|
libc.src.string.bcopy
|
||||||
libc.src.string.bzero
|
libc.src.string.bzero
|
||||||
libc.src.string.memccpy
|
libc.src.string.memccpy
|
||||||
libc.src.string.memchr
|
libc.src.string.memchr
|
||||||
|
|
|
@ -28,6 +28,7 @@ set(TARGET_LIBC_ENTRYPOINTS
|
||||||
|
|
||||||
# string.h entrypoints
|
# string.h entrypoints
|
||||||
libc.src.string.bcmp
|
libc.src.string.bcmp
|
||||||
|
libc.src.string.bcopy
|
||||||
libc.src.string.bzero
|
libc.src.string.bzero
|
||||||
libc.src.string.memccpy
|
libc.src.string.memccpy
|
||||||
libc.src.string.memchr
|
libc.src.string.memchr
|
||||||
|
|
|
@ -19,6 +19,7 @@ set(TARGET_LIBC_ENTRYPOINTS
|
||||||
|
|
||||||
# string.h entrypoints
|
# string.h entrypoints
|
||||||
libc.src.string.bcmp
|
libc.src.string.bcmp
|
||||||
|
libc.src.string.bcopy
|
||||||
libc.src.string.bzero
|
libc.src.string.bzero
|
||||||
libc.src.string.memccpy
|
libc.src.string.memccpy
|
||||||
libc.src.string.memchr
|
libc.src.string.memchr
|
||||||
|
|
|
@ -36,6 +36,7 @@ Function Name Available
|
||||||
============= =========
|
============= =========
|
||||||
bzero |check|
|
bzero |check|
|
||||||
bcmp |check|
|
bcmp |check|
|
||||||
|
bcopy |check|
|
||||||
memcpy |check|
|
memcpy |check|
|
||||||
memset |check|
|
memset |check|
|
||||||
memcmp |check|
|
memcmp |check|
|
||||||
|
|
|
@ -5,6 +5,11 @@ def LLVMLibcExt : StandardSpec<"llvm_libc_ext"> {
|
||||||
[], // Types
|
[], // Types
|
||||||
[], // Enumerations
|
[], // Enumerations
|
||||||
[
|
[
|
||||||
|
FunctionSpec<
|
||||||
|
"bcopy",
|
||||||
|
RetValSpec<VoidType>,
|
||||||
|
[ArgSpec<ConstVoidPtr>, ArgSpec<VoidPtr>, ArgSpec<SizeTType>]
|
||||||
|
>,
|
||||||
FunctionSpec<
|
FunctionSpec<
|
||||||
"bzero",
|
"bzero",
|
||||||
RetValSpec<VoidType>,
|
RetValSpec<VoidType>,
|
||||||
|
|
|
@ -20,6 +20,14 @@ add_header_library(
|
||||||
.memory_utils.memcpy_implementation
|
.memory_utils.memcpy_implementation
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_entrypoint_object(
|
||||||
|
bcopy
|
||||||
|
SRCS
|
||||||
|
bcopy.cpp
|
||||||
|
HDRS
|
||||||
|
bcopy.h
|
||||||
|
)
|
||||||
|
|
||||||
add_entrypoint_object(
|
add_entrypoint_object(
|
||||||
memccpy
|
memccpy
|
||||||
SRCS
|
SRCS
|
||||||
|
@ -28,7 +36,6 @@ add_entrypoint_object(
|
||||||
memccpy.h
|
memccpy.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
add_entrypoint_object(
|
add_entrypoint_object(
|
||||||
mempcpy
|
mempcpy
|
||||||
SRCS
|
SRCS
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -2,6 +2,18 @@ add_libc_testsuite(libc_string_unittests)
|
||||||
|
|
||||||
add_subdirectory(memory_utils)
|
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(
|
add_libc_unittest(
|
||||||
memccpy_test
|
memccpy_test
|
||||||
SUITE
|
SUITE
|
||||||
|
|
|
@ -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 ¤t : 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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(
|
libc_function(
|
||||||
name = "memcmp",
|
name = "memcmp",
|
||||||
srcs = ["src/string/memcmp.cpp"],
|
srcs = ["src/string/memcmp.cpp"],
|
||||||
|
|
|
@ -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(
|
libc_test(
|
||||||
name = "memcmp_test",
|
name = "memcmp_test",
|
||||||
srcs = ["memcmp_test.cpp"],
|
srcs = ["memcmp_test.cpp"],
|
||||||
|
|
Loading…
Reference in New Issue