forked from OSchip/llvm-project
[libc] Add a trivial implementation for bcmp
Differential Revision: https://reviews.llvm.org/D108225
This commit is contained in:
parent
6c75ce1b8b
commit
c8f79892af
|
@ -171,6 +171,7 @@ add_libc_multi_impl_benchmark(memcpy)
|
|||
add_libc_multi_impl_benchmark(memset)
|
||||
add_libc_multi_impl_benchmark(bzero)
|
||||
add_libc_multi_impl_benchmark(memcmp)
|
||||
add_libc_multi_impl_benchmark(bcmp)
|
||||
|
||||
#==============================================================================
|
||||
# Google Benchmarking tool
|
||||
|
@ -188,6 +189,7 @@ target_link_libraries(libc.benchmarks.memory_functions.opt_host
|
|||
PRIVATE
|
||||
libc-memory-benchmark
|
||||
libc.src.string.memcmp_opt_host
|
||||
libc.src.string.bcmp_opt_host
|
||||
libc.src.string.memcpy_opt_host
|
||||
libc.src.string.memset_opt_host
|
||||
libc.src.string.bzero_opt_host
|
||||
|
|
|
@ -27,6 +27,7 @@ extern void *memcpy(void *__restrict, const void *__restrict, size_t);
|
|||
extern void *memset(void *, int, size_t);
|
||||
extern void bzero(void *, size_t);
|
||||
extern int memcmp(const void *, const void *, size_t);
|
||||
extern int bcmp(const void *, const void *, size_t);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
|
@ -76,6 +77,9 @@ using BenchmarkSetup = SetSetup;
|
|||
#elif defined(LIBC_BENCHMARK_FUNCTION_MEMCMP)
|
||||
#define LIBC_BENCHMARK_FUNCTION LIBC_BENCHMARK_FUNCTION_MEMCMP
|
||||
using BenchmarkSetup = ComparisonSetup;
|
||||
#elif defined(LIBC_BENCHMARK_FUNCTION_BCMP)
|
||||
#define LIBC_BENCHMARK_FUNCTION LIBC_BENCHMARK_FUNCTION_BCMP
|
||||
using BenchmarkSetup = ComparisonSetup;
|
||||
#else
|
||||
#error "Missing LIBC_BENCHMARK_FUNCTION_XXX definition"
|
||||
#endif
|
||||
|
|
|
@ -28,6 +28,7 @@ extern void *memcpy(void *__restrict, const void *__restrict, size_t);
|
|||
extern void *memset(void *, int, size_t);
|
||||
extern void bzero(void *, size_t);
|
||||
extern int memcmp(const void *, const void *, size_t);
|
||||
extern int bcmp(const void *, const void *, size_t);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
|
@ -38,6 +39,9 @@ static constexpr MemcpyConfiguration kMemcpyConfigurations[] = {
|
|||
static constexpr MemcmpConfiguration kMemcmpConfigurations[] = {
|
||||
{__llvm_libc::memcmp, "__llvm_libc::memcmp"}};
|
||||
|
||||
static constexpr MemcmpConfiguration kBcmpConfigurations[] = {
|
||||
{__llvm_libc::bcmp, "__llvm_libc::bcmp"}};
|
||||
|
||||
static constexpr MemsetConfiguration kMemsetConfigurations[] = {
|
||||
{__llvm_libc::memset, "__llvm_libc::memset"}};
|
||||
|
||||
|
@ -116,6 +120,8 @@ BENCHMARK_MEMORY_FUNCTION(BM_Memcpy, CopySetup, MemcpyConfiguration,
|
|||
llvm::makeArrayRef(kMemcpyConfigurations));
|
||||
BENCHMARK_MEMORY_FUNCTION(BM_Memcmp, ComparisonSetup, MemcmpConfiguration,
|
||||
llvm::makeArrayRef(kMemcmpConfigurations));
|
||||
BENCHMARK_MEMORY_FUNCTION(BM_Bcmp, ComparisonSetup, MemcmpConfiguration,
|
||||
llvm::makeArrayRef(kBcmpConfigurations));
|
||||
BENCHMARK_MEMORY_FUNCTION(BM_Memset, SetSetup, MemsetConfiguration,
|
||||
llvm::makeArrayRef(kMemsetConfigurations));
|
||||
BENCHMARK_MEMORY_FUNCTION(BM_Bzero, SetSetup, BzeroConfiguration,
|
||||
|
|
|
@ -21,6 +21,7 @@ set(TARGET_LIBC_ENTRYPOINTS
|
|||
libc.src.errno.__errno_location
|
||||
|
||||
# string.h entrypoints
|
||||
libc.src.string.bcmp
|
||||
libc.src.string.bzero
|
||||
libc.src.string.memchr
|
||||
libc.src.string.memcmp
|
||||
|
|
|
@ -21,6 +21,7 @@ set(TARGET_LIBC_ENTRYPOINTS
|
|||
libc.src.errno.__errno_location
|
||||
|
||||
# string.h entrypoints
|
||||
libc.src.string.bcmp
|
||||
libc.src.string.bzero
|
||||
libc.src.string.memchr
|
||||
libc.src.string.memcmp
|
||||
|
|
|
@ -8,8 +8,21 @@ def LLVMLibcExt : StandardSpec<"llvm_libc_ext"> {
|
|||
FunctionSpec<
|
||||
"bzero",
|
||||
RetValSpec<VoidType>,
|
||||
[ArgSpec<VoidPtr>,
|
||||
ArgSpec<SizeTType>]
|
||||
[ArgSpec<VoidPtr>, ArgSpec<SizeTType>]
|
||||
>,
|
||||
]
|
||||
>;
|
||||
|
||||
HeaderSpec String = HeaderSpec<
|
||||
"string.h",
|
||||
[], // Macros
|
||||
[], // Types
|
||||
[], // Enumerations
|
||||
[
|
||||
FunctionSpec<
|
||||
"bcmp",
|
||||
RetValSpec<IntType>,
|
||||
[ArgSpec<ConstVoidPtr>, ArgSpec<ConstVoidPtr>, ArgSpec<SizeTType>]
|
||||
>,
|
||||
]
|
||||
>;
|
||||
|
@ -23,10 +36,7 @@ def LLVMLibcExt : StandardSpec<"llvm_libc_ext"> {
|
|||
FunctionSpec<
|
||||
"__assert_fail",
|
||||
RetValSpec<NoReturn>,
|
||||
[ArgSpec<ConstCharPtr>,
|
||||
ArgSpec<ConstCharPtr>,
|
||||
ArgSpec<UnsignedType>,
|
||||
ArgSpec<ConstCharPtr>,]
|
||||
[ArgSpec<ConstCharPtr>, ArgSpec<ConstCharPtr>, ArgSpec<UnsignedType>, ArgSpec<ConstCharPtr>]
|
||||
|
||||
>,
|
||||
]
|
||||
|
|
|
@ -331,3 +331,35 @@ else()
|
|||
add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE})
|
||||
add_memcmp(memcmp)
|
||||
endif()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# bcmp
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
function(add_bcmp bcmp_name)
|
||||
add_implementation(bcmp ${bcmp_name}
|
||||
SRCS ${LIBC_BCMP_SRC}
|
||||
HDRS ${LIBC_SOURCE_DIR}/src/string/bcmp.h
|
||||
DEPENDS
|
||||
.memory_utils.memory_utils
|
||||
libc.include.string
|
||||
COMPILE_OPTIONS
|
||||
-fno-builtin-memcmp
|
||||
-fno-builtin-bcmp
|
||||
${ARGN}
|
||||
)
|
||||
endfunction()
|
||||
|
||||
if(${LIBC_TARGET_ARCHITECTURE_IS_X86})
|
||||
set(LIBC_BCMP_SRC ${LIBC_SOURCE_DIR}/src/string/bcmp.cpp)
|
||||
add_bcmp(bcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2)
|
||||
add_bcmp(bcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2)
|
||||
add_bcmp(bcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2)
|
||||
add_bcmp(bcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F)
|
||||
add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE})
|
||||
add_bcmp(bcmp)
|
||||
else()
|
||||
set(LIBC_BCMP_SRC ${LIBC_SOURCE_DIR}/src/string/bcmp.cpp)
|
||||
add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE})
|
||||
add_bcmp(bcmp)
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
//===-- Implementation of bcmp --------------------------------------------===//
|
||||
//
|
||||
// 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/bcmp.h"
|
||||
#include "src/__support/common.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
LLVM_LIBC_FUNCTION(int, bcmp,
|
||||
(const void *lhs, const void *rhs, size_t count)) {
|
||||
const unsigned char *_lhs = reinterpret_cast<const unsigned char *>(lhs);
|
||||
const unsigned char *_rhs = reinterpret_cast<const unsigned char *>(rhs);
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
if (_lhs[i] != _rhs[i]) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// count is 0 or _lhs and _rhs are the same.
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace __llvm_libc
|
|
@ -0,0 +1,20 @@
|
|||
//===-- Implementation header for bzero -------------------------*- 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_BCMP_H
|
||||
#define LLVM_LIBC_SRC_STRING_BCMP_H
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
int bcmp(const void *lhs, const void *rhs, size_t count);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SRC_STRING_BCMP_H
|
|
@ -199,4 +199,5 @@ add_libc_multi_impl_test(memcpy SRCS memcpy_test.cpp)
|
|||
add_libc_multi_impl_test(memset SRCS memset_test.cpp)
|
||||
add_libc_multi_impl_test(bzero SRCS bzero_test.cpp)
|
||||
add_libc_multi_impl_test(memcmp SRCS memcmp_test.cpp)
|
||||
add_libc_multi_impl_test(bcmp SRCS bcmp_test.cpp)
|
||||
add_libc_multi_impl_test(memmove SRCS memmove_test.cpp)
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
//===-- Unittests for bcmp ------------------------------------------------===//
|
||||
//
|
||||
// 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/bcmp.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
TEST(LlvmLibcBcmpTest, CmpZeroByte) {
|
||||
const char *lhs = "ab";
|
||||
const char *rhs = "bc";
|
||||
EXPECT_EQ(__llvm_libc::bcmp(lhs, rhs, 0), 0);
|
||||
}
|
||||
|
||||
TEST(LlvmLibcBcmpTest, LhsRhsAreTheSame) {
|
||||
const char *lhs = "ab";
|
||||
const char *rhs = "ab";
|
||||
EXPECT_EQ(__llvm_libc::bcmp(lhs, rhs, 2), 0);
|
||||
}
|
||||
|
||||
TEST(LlvmLibcBcmpTest, LhsBeforeRhsLexically) {
|
||||
const char *lhs = "ab";
|
||||
const char *rhs = "ac";
|
||||
EXPECT_EQ(__llvm_libc::bcmp(lhs, rhs, 2), 1);
|
||||
}
|
||||
|
||||
TEST(LlvmLibcBcmpTest, LhsAfterRhsLexically) {
|
||||
const char *lhs = "ac";
|
||||
const char *rhs = "ab";
|
||||
EXPECT_EQ(__llvm_libc::bcmp(lhs, rhs, 2), 1);
|
||||
}
|
||||
|
||||
TEST(LlvmLibcBcmpTest, Sweep) {
|
||||
static constexpr size_t kMaxSize = 1024;
|
||||
char lhs[kMaxSize];
|
||||
char rhs[kMaxSize];
|
||||
|
||||
const auto reset = [](char *const ptr) {
|
||||
for (size_t i = 0; i < kMaxSize; ++i)
|
||||
ptr[i] = 'a';
|
||||
};
|
||||
|
||||
reset(lhs);
|
||||
reset(rhs);
|
||||
for (size_t i = 0; i < kMaxSize; ++i)
|
||||
EXPECT_EQ(__llvm_libc::bcmp(lhs, rhs, i), 0);
|
||||
|
||||
reset(lhs);
|
||||
reset(rhs);
|
||||
for (size_t i = 0; i < kMaxSize; ++i) {
|
||||
rhs[i] = 'b';
|
||||
EXPECT_EQ(__llvm_libc::bcmp(lhs, rhs, kMaxSize), 1);
|
||||
rhs[i] = 'a';
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue