summaryrefslogtreecommitdiff
path: root/libc/src/string/memory_utils/aarch64/inline_bcmp.h
diff options
context:
space:
mode:
Diffstat (limited to 'libc/src/string/memory_utils/aarch64/inline_bcmp.h')
-rw-r--r--libc/src/string/memory_utils/aarch64/inline_bcmp.h50
1 files changed, 47 insertions, 3 deletions
diff --git a/libc/src/string/memory_utils/aarch64/inline_bcmp.h b/libc/src/string/memory_utils/aarch64/inline_bcmp.h
index e41ac202dbaa..66d24378095b 100644
--- a/libc/src/string/memory_utils/aarch64/inline_bcmp.h
+++ b/libc/src/string/memory_utils/aarch64/inline_bcmp.h
@@ -19,9 +19,43 @@
namespace LIBC_NAMESPACE_DECL {
-[[maybe_unused]] LIBC_INLINE BcmpReturnType inline_bcmp_aarch64(CPtr p1,
- CPtr p2,
- size_t count) {
+[[maybe_unused]] LIBC_INLINE BcmpReturnType
+inline_bcmp_aarch64_no_fp(CPtr p1, CPtr p2, size_t count) {
+ if (LIBC_LIKELY(count < 16)) {
+ switch (count) {
+ case 0:
+ return BcmpReturnType::zero();
+ case 1:
+ return generic::Bcmp<uint8_t>::block(p1, p2);
+ case 2:
+ return generic::Bcmp<uint16_t>::block(p1, p2);
+ case 3:
+ return generic::Bcmp<uint16_t>::head_tail(p1, p2, count);
+ case 4:
+ return generic::Bcmp<uint32_t>::block(p1, p2);
+ case 5:
+ case 6:
+ case 7:
+ return generic::Bcmp<uint32_t>::head_tail(p1, p2, count);
+ case 8:
+ return generic::Bcmp<uint64_t>::block(p1, p2);
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ return generic::Bcmp<uint64_t>::head_tail(p1, p2, count);
+ }
+ }
+
+ return generic::Bcmp<uint64_t>::loop_and_tail_align_above(256, p1, p2, count);
+}
+
+#ifdef __ARM_NEON
+[[maybe_unused]] LIBC_INLINE BcmpReturnType
+inline_bcmp_aarch64_with_fp(CPtr p1, CPtr p2, size_t count) {
if (LIBC_LIKELY(count <= 32)) {
if (LIBC_UNLIKELY(count >= 16)) {
return aarch64::Bcmp<16>::head_tail(p1, p2, count);
@@ -65,6 +99,16 @@ namespace LIBC_NAMESPACE_DECL {
}
return aarch64::Bcmp<32>::loop_and_tail(p1, p2, count);
}
+#endif
+
+[[gnu::flatten]] LIBC_INLINE BcmpReturnType
+inline_bcmp_aarch64_dispatch(CPtr p1, CPtr p2, size_t count) {
+#if defined(__ARM_NEON)
+ return inline_bcmp_aarch64_with_fp(p1, p2, count);
+#else
+ return inline_bcmp_aarch64_no_fp(p1, p2, count);
+#endif
+}
} // namespace LIBC_NAMESPACE_DECL