diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt --- a/libc/src/string/CMakeLists.txt +++ b/libc/src/string/CMakeLists.txt @@ -322,7 +322,7 @@ function(add_memcmp memcmp_name) add_implementation(memcmp ${memcmp_name} - SRCS ${LIBC_MEMCMP_SRC} + SRCS ${LIBC_SOURCE_DIR}/src/string/memcmp.cpp HDRS ${LIBC_SOURCE_DIR}/src/string/memcmp.h DEPENDS .memory_utils.memory_utils @@ -334,7 +334,6 @@ endfunction() if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) - set(LIBC_MEMCMP_SRC ${LIBC_SOURCE_DIR}/src/string/memcmp.cpp) add_memcmp(memcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) add_memcmp(memcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) add_memcmp(memcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) @@ -342,11 +341,9 @@ add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) add_memcmp(memcmp) elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) - set(LIBC_MEMCMP_SRC ${LIBC_SOURCE_DIR}/src/string/aarch64/memcmp.cpp) - add_memcmp(memcmp) add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) + add_memcmp(memcmp) else() - set(LIBC_MEMCMP_SRC ${LIBC_SOURCE_DIR}/src/string/memcmp.cpp) add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) add_memcmp(memcmp) endif() diff --git a/libc/src/string/aarch64/memcmp.cpp b/libc/src/string/aarch64/memcmp.cpp deleted file mode 100644 --- a/libc/src/string/aarch64/memcmp.cpp +++ /dev/null @@ -1,52 +0,0 @@ -//===-- Implementation of memcmp ------------------------------------------===// -// -// 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/memcmp.h" -#include "src/__support/common.h" -#include "src/string/memory_utils/elements.h" -#include // size_t - -namespace __llvm_libc { - -static int memcmp_aarch64(const char *lhs, const char *rhs, size_t count) { - // Use aarch64 strategies (_1, _2, _3 ...) - using namespace __llvm_libc::aarch64; - - if (count == 0) // [0, 0] - return 0; - if (count == 1) // [1, 1] - return ThreeWayCompare<_1>(lhs, rhs); - if (count == 2) // [2, 2] - return ThreeWayCompare<_2>(lhs, rhs); - if (count == 3) // [3, 3] - return ThreeWayCompare<_3>(lhs, rhs); - if (count < 8) // [4, 7] - return ThreeWayCompare>(lhs, rhs, count); - if (count < 16) // [8, 15] - return ThreeWayCompare>(lhs, rhs, count); - if (unlikely(count >= 128)) // [128, ∞] - return ThreeWayCompare::Then>>(lhs, rhs, count); - if (!Equals<_16>(lhs, rhs)) // [16, 16] - return ThreeWayCompare<_16>(lhs, rhs); - if (count < 32) // [17, 31] - return ThreeWayCompare>(lhs, rhs, count); - if (!Equals::Then<_16>>(lhs, rhs)) // [32, 32] - return ThreeWayCompare::Then<_16>>(lhs, rhs); - if (count < 64) // [33, 63] - return ThreeWayCompare>(lhs, rhs, count); - // [64, 127] - return ThreeWayCompare::Then>>(lhs, rhs, count); -} - -LLVM_LIBC_FUNCTION(int, memcmp, - (const void *lhs, const void *rhs, size_t count)) { - return memcmp_aarch64(reinterpret_cast(lhs), - reinterpret_cast(rhs), count); -} - -} // namespace __llvm_libc diff --git a/libc/src/string/memcmp.cpp b/libc/src/string/memcmp.cpp --- a/libc/src/string/memcmp.cpp +++ b/libc/src/string/memcmp.cpp @@ -7,46 +7,16 @@ //===----------------------------------------------------------------------===// #include "src/string/memcmp.h" -#include "src/__support/architectures.h" -#include "src/__support/common.h" -#include "src/string/memory_utils/elements.h" +#include "src/string/memory_utils/memcmp_implementations.inl" #include // size_t namespace __llvm_libc { -static int memcmp_impl(const char *lhs, const char *rhs, size_t count) { -#if defined(LLVM_LIBC_ARCH_X86) - using namespace ::__llvm_libc::x86; -#else - using namespace ::__llvm_libc::scalar; -#endif - - if (count == 0) - return 0; - if (count == 1) - return ThreeWayCompare<_1>(lhs, rhs); - if (count == 2) - return ThreeWayCompare<_2>(lhs, rhs); - if (count == 3) - return ThreeWayCompare<_3>(lhs, rhs); - if (count <= 8) - return ThreeWayCompare>(lhs, rhs, count); - if (count <= 16) - return ThreeWayCompare>(lhs, rhs, count); - if (count <= 32) - return ThreeWayCompare>(lhs, rhs, count); - if (count <= 64) - return ThreeWayCompare>(lhs, rhs, count); - if (count <= 128) - return ThreeWayCompare>(lhs, rhs, count); - return ThreeWayCompare::Then>>(lhs, rhs, count); -} - LLVM_LIBC_FUNCTION(int, memcmp, (const void *lhs, const void *rhs, size_t count)) { - return memcmp_impl(static_cast(lhs), - static_cast(rhs), count); + return inlined_memcmp(static_cast(lhs), + static_cast(rhs), count); } } // namespace __llvm_libc diff --git a/libc/src/string/memory_utils/memcmp_implementations.inl b/libc/src/string/memory_utils/memcmp_implementations.inl new file mode 100644 --- /dev/null +++ b/libc/src/string/memory_utils/memcmp_implementations.inl @@ -0,0 +1,100 @@ +//===-- Implementation of memcmp ------------------------------------------===// +// +// 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/architectures.h" +#include "src/__support/common.h" +#include "src/string/memory_utils/elements.h" + +#include // size_t + +namespace __llvm_libc { + +static inline int inlined_memcmp(const char *lhs, const char *rhs, + size_t count) { +#if defined(LLVM_LIBC_ARCH_X86) + ///////////////////////////////////////////////////////////////////////////// + // LLVM_LIBC_ARCH_X86 + ///////////////////////////////////////////////////////////////////////////// + using namespace __llvm_libc::x86; + if (count == 0) + return 0; + if (count == 1) + return ThreeWayCompare<_1>(lhs, rhs); + if (count == 2) + return ThreeWayCompare<_2>(lhs, rhs); + if (count == 3) + return ThreeWayCompare<_3>(lhs, rhs); + if (count <= 8) + return ThreeWayCompare>(lhs, rhs, count); + if (count <= 16) + return ThreeWayCompare>(lhs, rhs, count); + if (count <= 32) + return ThreeWayCompare>(lhs, rhs, count); + if (count <= 64) + return ThreeWayCompare>(lhs, rhs, count); + if (count <= 128) + return ThreeWayCompare>(lhs, rhs, count); + return ThreeWayCompare::Then>>(lhs, rhs, count); +#elif defined(LLVM_LIBC_ARCH_AARCH64) + ///////////////////////////////////////////////////////////////////////////// + // LLVM_LIBC_ARCH_AARCH64 + ///////////////////////////////////////////////////////////////////////////// + using namespace ::__llvm_libc::aarch64; + if (count == 0) // [0, 0] + return 0; + if (count == 1) // [1, 1] + return ThreeWayCompare<_1>(lhs, rhs); + if (count == 2) // [2, 2] + return ThreeWayCompare<_2>(lhs, rhs); + if (count == 3) // [3, 3] + return ThreeWayCompare<_3>(lhs, rhs); + if (count < 8) // [4, 7] + return ThreeWayCompare>(lhs, rhs, count); + if (count < 16) // [8, 15] + return ThreeWayCompare>(lhs, rhs, count); + if (unlikely(count >= 128)) // [128, ∞] + return ThreeWayCompare::Then>>(lhs, rhs, count); + if (!Equals<_16>(lhs, rhs)) // [16, 16] + return ThreeWayCompare<_16>(lhs, rhs); + if (count < 32) // [17, 31] + return ThreeWayCompare>(lhs, rhs, count); + if (!Equals::Then<_16>>(lhs, rhs)) // [32, 32] + return ThreeWayCompare::Then<_16>>(lhs, rhs); + if (count < 64) // [33, 63] + return ThreeWayCompare>(lhs, rhs, count); + // [64, 127] + return ThreeWayCompare::Then>>(lhs, rhs, count); +#else + ///////////////////////////////////////////////////////////////////////////// + // Default + ///////////////////////////////////////////////////////////////////////////// + using namespace ::__llvm_libc::scalar; + + if (count == 0) + return 0; + if (count == 1) + return ThreeWayCompare<_1>(lhs, rhs); + if (count == 2) + return ThreeWayCompare<_2>(lhs, rhs); + if (count == 3) + return ThreeWayCompare<_3>(lhs, rhs); + if (count <= 8) + return ThreeWayCompare>(lhs, rhs, count); + if (count <= 16) + return ThreeWayCompare>(lhs, rhs, count); + if (count <= 32) + return ThreeWayCompare>(lhs, rhs, count); + if (count <= 64) + return ThreeWayCompare>(lhs, rhs, count); + if (count <= 128) + return ThreeWayCompare>(lhs, rhs, count); + return ThreeWayCompare::Then>>(lhs, rhs, count); +#endif +} + +} // namespace __llvm_libc