1 //===-- Implementation of memcmp ------------------------------------------===//
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
9 #ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_MEMCMP_IMPLEMENTATIONS_H
10 #define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_MEMCMP_IMPLEMENTATIONS_H
11
12 #include "src/__support/architectures.h"
13 #include "src/__support/common.h"
14 #include "src/string/memory_utils/elements.h"
15
16 #include <stddef.h> // size_t
17
18 namespace __llvm_libc {
19
inline_memcmp(const char * lhs,const char * rhs,size_t count)20 static inline int inline_memcmp(const char *lhs, const char *rhs,
21 size_t count) {
22 #if defined(LLVM_LIBC_ARCH_X86)
23 /////////////////////////////////////////////////////////////////////////////
24 // LLVM_LIBC_ARCH_X86
25 /////////////////////////////////////////////////////////////////////////////
26 using namespace __llvm_libc::x86;
27 if (count == 0)
28 return 0;
29 if (count == 1)
30 return three_way_compare<_1>(lhs, rhs);
31 if (count == 2)
32 return three_way_compare<_2>(lhs, rhs);
33 if (count == 3)
34 return three_way_compare<_3>(lhs, rhs);
35 if (count <= 8)
36 return three_way_compare<HeadTail<_4>>(lhs, rhs, count);
37 if (count <= 16)
38 return three_way_compare<HeadTail<_8>>(lhs, rhs, count);
39 if (count <= 32)
40 return three_way_compare<HeadTail<_16>>(lhs, rhs, count);
41 if (count <= 64)
42 return three_way_compare<HeadTail<_32>>(lhs, rhs, count);
43 if (count <= 128)
44 return three_way_compare<HeadTail<_64>>(lhs, rhs, count);
45 return three_way_compare<Align<_32>::Then<Loop<_32>>>(lhs, rhs, count);
46 #elif defined(LLVM_LIBC_ARCH_AARCH64)
47 /////////////////////////////////////////////////////////////////////////////
48 // LLVM_LIBC_ARCH_AARCH64
49 /////////////////////////////////////////////////////////////////////////////
50 using namespace ::__llvm_libc::aarch64;
51 if (count == 0) // [0, 0]
52 return 0;
53 if (count == 1) // [1, 1]
54 return three_way_compare<_1>(lhs, rhs);
55 if (count == 2) // [2, 2]
56 return three_way_compare<_2>(lhs, rhs);
57 if (count == 3) // [3, 3]
58 return three_way_compare<_3>(lhs, rhs);
59 if (count < 8) // [4, 7]
60 return three_way_compare<HeadTail<_4>>(lhs, rhs, count);
61 if (count < 16) // [8, 15]
62 return three_way_compare<HeadTail<_8>>(lhs, rhs, count);
63 if (unlikely(count >= 128)) // [128, ∞]
64 return three_way_compare<Align<_16>::Then<Loop<_32>>>(lhs, rhs, count);
65 if (!equals<_16>(lhs, rhs)) // [16, 16]
66 return three_way_compare<_16>(lhs, rhs);
67 if (count < 32) // [17, 31]
68 return three_way_compare<Tail<_16>>(lhs, rhs, count);
69 if (!equals<Skip<16>::Then<_16>>(lhs, rhs)) // [32, 32]
70 return three_way_compare<Skip<16>::Then<_16>>(lhs, rhs);
71 if (count < 64) // [33, 63]
72 return three_way_compare<Tail<_32>>(lhs, rhs, count);
73 // [64, 127]
74 return three_way_compare<Skip<32>::Then<Loop<_16>>>(lhs, rhs, count);
75 #else
76 /////////////////////////////////////////////////////////////////////////////
77 // Default
78 /////////////////////////////////////////////////////////////////////////////
79 using namespace ::__llvm_libc::scalar;
80
81 if (count == 0)
82 return 0;
83 if (count == 1)
84 return three_way_compare<_1>(lhs, rhs);
85 if (count == 2)
86 return three_way_compare<_2>(lhs, rhs);
87 if (count == 3)
88 return three_way_compare<_3>(lhs, rhs);
89 if (count <= 8)
90 return three_way_compare<HeadTail<_4>>(lhs, rhs, count);
91 if (count <= 16)
92 return three_way_compare<HeadTail<_8>>(lhs, rhs, count);
93 if (count <= 32)
94 return three_way_compare<HeadTail<_16>>(lhs, rhs, count);
95 if (count <= 64)
96 return three_way_compare<HeadTail<_32>>(lhs, rhs, count);
97 if (count <= 128)
98 return three_way_compare<HeadTail<_64>>(lhs, rhs, count);
99 return three_way_compare<Align<_32>::Then<Loop<_32>>>(lhs, rhs, count);
100 #endif
101 }
102
103 } // namespace __llvm_libc
104
105 #endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_MEMCMP_IMPLEMENTATIONS_H
106