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