diff options
Diffstat (limited to 'libc/src/string/memmove.cpp')
| -rw-r--r-- | libc/src/string/memmove.cpp | 53 |
1 files changed, 14 insertions, 39 deletions
diff --git a/libc/src/string/memmove.cpp b/libc/src/string/memmove.cpp index 294716586ea8..f24257893b20 100644 --- a/libc/src/string/memmove.cpp +++ b/libc/src/string/memmove.cpp @@ -9,61 +9,36 @@ #include "src/string/memmove.h" #include "src/__support/common.h" -#include "src/string/memory_utils/op_aarch64.h" -#include "src/string/memory_utils/op_generic.h" -#include "src/string/memory_utils/op_x86.h" +#include "src/__support/integer_operations.h" +#include "src/string/memory_utils/elements.h" #include <stddef.h> // size_t, ptrdiff_t -#include <stdio.h> - namespace __llvm_libc { static inline void inline_memmove(char *dst, const char *src, size_t count) { -#if defined(LLVM_LIBC_ARCH_X86) || defined(LLVM_LIBC_ARCH_AARCH64) -#if defined(LLVM_LIBC_ARCH_X86) - static constexpr size_t kMaxSize = x86::kAvx512F ? 64 - : x86::kAvx ? 32 - : x86::kSse2 ? 16 - : 8; -#elif defined(LLVM_LIBC_ARCH_AARCH64) - static constexpr size_t kMaxSize = aarch64::kNeon ? 16 : 8; -#endif + using namespace __llvm_libc::scalar; if (count == 0) return; if (count == 1) - return generic::Memmove<1, kMaxSize>::block(dst, src); + return move<_1>(dst, src); if (count <= 4) - return generic::Memmove<2, kMaxSize>::head_tail(dst, src, count); + return move<HeadTail<_2>>(dst, src, count); if (count <= 8) - return generic::Memmove<4, kMaxSize>::head_tail(dst, src, count); + return move<HeadTail<_4>>(dst, src, count); if (count <= 16) - return generic::Memmove<8, kMaxSize>::head_tail(dst, src, count); + return move<HeadTail<_8>>(dst, src, count); if (count <= 32) - return generic::Memmove<16, kMaxSize>::head_tail(dst, src, count); + return move<HeadTail<_16>>(dst, src, count); if (count <= 64) - return generic::Memmove<32, kMaxSize>::head_tail(dst, src, count); + return move<HeadTail<_32>>(dst, src, count); if (count <= 128) - return generic::Memmove<64, kMaxSize>::head_tail(dst, src, count); + return move<HeadTail<_64>>(dst, src, count); - if (dst < src) { - generic::Memmove<32, kMaxSize>::align_forward<Arg::Src>(dst, src, count); - return generic::Memmove<64, kMaxSize>::loop_and_tail_forward(dst, src, - count); - } else { - generic::Memmove<32, kMaxSize>::align_backward<Arg::Src>(dst, src, count); - return generic::Memmove<64, kMaxSize>::loop_and_tail_backward(dst, src, - count); - } -#elif defined(LLVM_LIBC_ARCH_ARM) - if (count == 0) - return; + using AlignedMoveLoop = Align<_16, Arg::Src>::Then<Loop<_64>>; if (dst < src) - return generic::Memmove<1, 1>::loop_forward(dst, src, count); - else - return generic::Memmove<1, 1>::loop_backward(dst, src, count); -#else -#error "Unsupported platform" -#endif + return move<AlignedMoveLoop>(dst, src, count); + else if (dst > src) + return move_backward<AlignedMoveLoop>(dst, src, count); } LLVM_LIBC_FUNCTION(void *, memmove, |
