Warning: This file is not a C or C++ file. It does not have highlighting.

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/config.h" // LIBC_NAMESPACE_DECL
13#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
14#include "src/string/memory_utils/op_aarch64.h"
15#include "src/string/memory_utils/op_generic.h"
16#include "src/string/memory_utils/utils.h" // Ptr, CPtr
17
18#include <stddef.h> // size_t
19
20namespace LIBC_NAMESPACE_DECL {
21
22[[maybe_unused]] LIBC_INLINE BcmpReturnType
23inline_bcmp_aarch64_no_fp(CPtr p1, CPtr p2, size_t count) {
24 if (LIBC_LIKELY(count < 16)) {
25 switch (count) {
26 case 0:
27 return BcmpReturnType::zero();
28 case 1:
29 return generic::Bcmp<uint8_t>::block(p1, p2);
30 case 2:
31 return generic::Bcmp<uint16_t>::block(p1, p2);
32 case 3:
33 return generic::Bcmp<uint16_t>::head_tail(p1, p2, count);
34 case 4:
35 return generic::Bcmp<uint32_t>::block(p1, p2);
36 case 5:
37 case 6:
38 case 7:
39 return generic::Bcmp<uint32_t>::head_tail(p1, p2, count);
40 case 8:
41 return generic::Bcmp<uint64_t>::block(p1, p2);
42 case 9:
43 case 10:
44 case 11:
45 case 12:
46 case 13:
47 case 14:
48 case 15:
49 return generic::Bcmp<uint64_t>::head_tail(p1, p2, count);
50 }
51 }
52
53 return generic::Bcmp<uint64_t>::loop_and_tail_align_above(256, p1, p2, count);
54}
55
56#ifdef __ARM_NEON
57[[maybe_unused]] LIBC_INLINE BcmpReturnType
58inline_bcmp_aarch64_with_fp(CPtr p1, CPtr p2, size_t count) {
59 if (LIBC_LIKELY(count <= 32)) {
60 if (LIBC_UNLIKELY(count >= 16)) {
61 return aarch64::Bcmp<16>::head_tail(p1, p2, count);
62 }
63 switch (count) {
64 case 0:
65 return BcmpReturnType::zero();
66 case 1:
67 return generic::Bcmp<uint8_t>::block(p1, p2);
68 case 2:
69 return generic::Bcmp<uint16_t>::block(p1, p2);
70 case 3:
71 return generic::Bcmp<uint16_t>::head_tail(p1, p2, count);
72 case 4:
73 return generic::Bcmp<uint32_t>::block(p1, p2);
74 case 5:
75 case 6:
76 case 7:
77 return generic::Bcmp<uint32_t>::head_tail(p1, p2, count);
78 case 8:
79 return generic::Bcmp<uint64_t>::block(p1, p2);
80 case 9:
81 case 10:
82 case 11:
83 case 12:
84 case 13:
85 case 14:
86 case 15:
87 return generic::Bcmp<uint64_t>::head_tail(p1, p2, count);
88 }
89 }
90
91 if (count <= 64)
92 return aarch64::Bcmp<32>::head_tail(p1, p2, count);
93
94 // Aligned loop if > 256, otherwise normal loop
95 if (LIBC_UNLIKELY(count > 256)) {
96 if (auto value = aarch64::Bcmp<32>::block(p1, p2))
97 return value;
98 align_to_next_boundary<16, Arg::P1>(p1, p2, count);
99 }
100 return aarch64::Bcmp<32>::loop_and_tail(p1, p2, count);
101}
102#endif
103
104[[gnu::flatten]] LIBC_INLINE BcmpReturnType
105inline_bcmp_aarch64_dispatch(CPtr p1, CPtr p2, size_t count) {
106#if defined(__ARM_NEON)
107 return inline_bcmp_aarch64_with_fp(p1, p2, count);
108#else
109 return inline_bcmp_aarch64_no_fp(p1, p2, count);
110#endif
111}
112
113} // namespace LIBC_NAMESPACE_DECL
114
115#endif // LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_BCMP_H
116

Warning: This file is not a C or C++ file. It does not have highlighting.

source code of libc/src/string/memory_utils/aarch64/inline_bcmp.h