mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 22:00:10 +00:00
[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
|
||||
libc.src.string.bcmp
|
||||
libc.src.string.bcopy
|
||||
libc.src.string.bzero
|
||||
libc.src.string.memccpy
|
||||
libc.src.string.memchr
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -36,6 +36,7 @@ Function Name Available
|
||||
============= =========
|
||||
bzero |check|
|
||||
bcmp |check|
|
||||
bcopy |check|
|
||||
memcpy |check|
|
||||
memset |check|
|
||||
memcmp |check|
|
||||
|
@ -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>,
|
||||
|
@ -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
19
libc/src/string/bcopy.cpp
Normal 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
20
libc/src/string/bcopy.h
Normal 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
|
@ -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
|
||||
|
104
libc/test/src/string/bcopy_test.cpp
Normal file
104
libc/test/src/string/bcopy_test.cpp
Normal 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 ¤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(
|
||||
name = "memcmp",
|
||||
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(
|
||||
name = "memcmp_test",
|
||||
srcs = ["memcmp_test.cpp"],
|
||||
|
Loading…
Reference in New Issue
Block a user