• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- Bcmp implementation for aarch64 -------------------------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 #ifndef LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_BCMP_H
9 #define LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_BCMP_H
10 
11 #include "src/__support/macros/attributes.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" // Ptr, CPtr
16 
17 #include <stddef.h> // size_t
18 
19 namespace LIBC_NAMESPACE {
20 
inline_bcmp_aarch64(CPtr p1,CPtr p2,size_t count)21 [[maybe_unused]] LIBC_INLINE BcmpReturnType inline_bcmp_aarch64(CPtr p1,
22                                                                 CPtr p2,
23                                                                 size_t count) {
24   if (LIBC_LIKELY(count <= 32)) {
25     if (LIBC_UNLIKELY(count >= 16)) {
26       return aarch64::Bcmp<16>::head_tail(p1, p2, count);
27     }
28     switch (count) {
29     case 0:
30       return BcmpReturnType::zero();
31     case 1:
32       return generic::Bcmp<uint8_t>::block(p1, p2);
33     case 2:
34       return generic::Bcmp<uint16_t>::block(p1, p2);
35     case 3:
36       return generic::Bcmp<uint16_t>::head_tail(p1, p2, count);
37     case 4:
38       return generic::Bcmp<uint32_t>::block(p1, p2);
39     case 5:
40     case 6:
41     case 7:
42       return generic::Bcmp<uint32_t>::head_tail(p1, p2, count);
43     case 8:
44       return generic::Bcmp<uint64_t>::block(p1, p2);
45     case 9:
46     case 10:
47     case 11:
48     case 12:
49     case 13:
50     case 14:
51     case 15:
52       return generic::Bcmp<uint64_t>::head_tail(p1, p2, count);
53     }
54   }
55 
56   if (count <= 64)
57     return aarch64::Bcmp<32>::head_tail(p1, p2, count);
58 
59   // Aligned loop if > 256, otherwise normal loop
60   if (LIBC_UNLIKELY(count > 256)) {
61     if (auto value = aarch64::Bcmp<32>::block(p1, p2))
62       return value;
63     align_to_next_boundary<16, Arg::P1>(p1, p2, count);
64   }
65   return aarch64::Bcmp<32>::loop_and_tail(p1, p2, count);
66 }
67 
68 } // namespace LIBC_NAMESPACE
69 
70 #endif // LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_BCMP_H
71