1 //===-- Memcmp implementation for aarch64 -----------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
8 #ifndef LIBC_SRC_STRING_MEMORY_UTILS_X86_64_MEMCMP_IMPLEMENTATIONS_H
9 #define LIBC_SRC_STRING_MEMORY_UTILS_X86_64_MEMCMP_IMPLEMENTATIONS_H
11 #include "src/__support/macros/config.h" // LIBC_INLINE
12 #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
13 #include "src/string/memory_utils/op_aarch64.h"
14 #include "src/string/memory_utils/op_generic.h"
15 #include "src/string/memory_utils/utils.h" // MemcmpReturnType
17 namespace __llvm_libc
{
19 [[maybe_unused
]] LIBC_INLINE MemcmpReturnType
20 inline_memcmp_generic_gt16(CPtr p1
, CPtr p2
, size_t count
) {
21 if (LIBC_UNLIKELY(count
>= 384)) {
22 if (auto value
= generic::Memcmp
<16>::block(p1
, p2
))
24 align_to_next_boundary
<16, Arg::P1
>(p1
, p2
, count
);
26 return generic::Memcmp
<16>::loop_and_tail(p1
, p2
, count
);
29 [[maybe_unused
]] LIBC_INLINE MemcmpReturnType
30 inline_memcmp_aarch64_neon_gt16(CPtr p1
, CPtr p2
, size_t count
) {
31 if (LIBC_UNLIKELY(count
>= 128)) { // [128, ∞]
32 if (auto value
= generic::Memcmp
<16>::block(p1
, p2
))
34 align_to_next_boundary
<16, Arg::P1
>(p1
, p2
, count
);
35 return generic::Memcmp
<32>::loop_and_tail(p1
, p2
, count
);
37 if (generic::Bcmp
<16>::block(p1
, p2
)) // [16, 16]
38 return generic::Memcmp
<16>::block(p1
, p2
);
39 if (count
< 32) // [17, 31]
40 return generic::Memcmp
<16>::tail(p1
, p2
, count
);
41 if (generic::Bcmp
<16>::block(p1
+ 16, p2
+ 16)) // [32, 32]
42 return generic::Memcmp
<16>::block(p1
+ 16, p2
+ 16);
43 if (count
< 64) // [33, 63]
44 return generic::Memcmp
<32>::tail(p1
, p2
, count
);
46 return generic::Memcmp
<16>::loop_and_tail(p1
+ 32, p2
+ 32, count
- 32);
49 LIBC_INLINE MemcmpReturnType
inline_memcmp_aarch64(CPtr p1
, CPtr p2
,
52 return MemcmpReturnType::ZERO();
54 return generic::Memcmp
<1>::block(p1
, p2
);
56 return generic::Memcmp
<2>::block(p1
, p2
);
58 return generic::Memcmp
<3>::block(p1
, p2
);
60 return generic::Memcmp
<4>::head_tail(p1
, p2
, count
);
62 return generic::Memcmp
<8>::head_tail(p1
, p2
, count
);
63 if constexpr (aarch64::kNeon
)
64 return inline_memcmp_aarch64_neon_gt16(p1
, p2
, count
);
66 return inline_memcmp_generic_gt16(p1
, p2
, count
);
68 } // namespace __llvm_libc
70 #endif // LIBC_SRC_STRING_MEMORY_UTILS_X86_64_MEMCMP_IMPLEMENTATIONS_H