xref: /llvm-project/libc/src/string/memory_utils/aarch64/inline_memset.h (revision 5ff3ff33ff930e4ec49da7910612d8a41eb068cb)
11f578347SGuillaume Chatelet //===-- Memset implementation for aarch64 -----------------------*- C++ -*-===//
21f578347SGuillaume Chatelet //
31f578347SGuillaume Chatelet // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41f578347SGuillaume Chatelet // See https://llvm.org/LICENSE.txt for license information.
51f578347SGuillaume Chatelet // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61f578347SGuillaume Chatelet //
71f578347SGuillaume Chatelet //===----------------------------------------------------------------------===//
81f578347SGuillaume Chatelet #ifndef LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_MEMSET_H
91f578347SGuillaume Chatelet #define LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_MEMSET_H
101f578347SGuillaume Chatelet 
111f578347SGuillaume Chatelet #include "src/__support/macros/attributes.h" // LIBC_INLINE
12*5ff3ff33SPetr Hosek #include "src/__support/macros/config.h"
131f578347SGuillaume Chatelet #include "src/string/memory_utils/op_aarch64.h"
141f578347SGuillaume Chatelet #include "src/string/memory_utils/op_generic.h"
151f578347SGuillaume Chatelet #include "src/string/memory_utils/utils.h" // Ptr, CPtr
161f578347SGuillaume Chatelet 
171f578347SGuillaume Chatelet #include <stddef.h> // size_t
181f578347SGuillaume Chatelet 
19*5ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL {
201f578347SGuillaume Chatelet 
211f578347SGuillaume Chatelet [[maybe_unused]] LIBC_INLINE static void
221f578347SGuillaume Chatelet inline_memset_aarch64(Ptr dst, uint8_t value, size_t count) {
231f578347SGuillaume Chatelet   static_assert(aarch64::kNeon, "aarch64 supports vector types");
241f578347SGuillaume Chatelet   using uint128_t = generic_v128;
251f578347SGuillaume Chatelet   using uint256_t = generic_v256;
261f578347SGuillaume Chatelet   using uint512_t = generic_v512;
271f578347SGuillaume Chatelet   if (count == 0)
281f578347SGuillaume Chatelet     return;
291f578347SGuillaume Chatelet   if (count <= 3) {
301f578347SGuillaume Chatelet     generic::Memset<uint8_t>::block(dst, value);
311f578347SGuillaume Chatelet     if (count > 1)
321f578347SGuillaume Chatelet       generic::Memset<uint16_t>::tail(dst, value, count);
331f578347SGuillaume Chatelet     return;
341f578347SGuillaume Chatelet   }
351f578347SGuillaume Chatelet   if (count <= 8)
361f578347SGuillaume Chatelet     return generic::Memset<uint32_t>::head_tail(dst, value, count);
371f578347SGuillaume Chatelet   if (count <= 16)
381f578347SGuillaume Chatelet     return generic::Memset<uint64_t>::head_tail(dst, value, count);
391f578347SGuillaume Chatelet   if (count <= 32)
401f578347SGuillaume Chatelet     return generic::Memset<uint128_t>::head_tail(dst, value, count);
411f578347SGuillaume Chatelet   if (count <= (32 + 64)) {
421f578347SGuillaume Chatelet     generic::Memset<uint256_t>::block(dst, value);
431f578347SGuillaume Chatelet     if (count <= 64)
441f578347SGuillaume Chatelet       return generic::Memset<uint256_t>::tail(dst, value, count);
451f578347SGuillaume Chatelet     generic::Memset<uint256_t>::block(dst + 32, value);
461f578347SGuillaume Chatelet     generic::Memset<uint256_t>::tail(dst, value, count);
471f578347SGuillaume Chatelet     return;
481f578347SGuillaume Chatelet   }
491f578347SGuillaume Chatelet   if (count >= 448 && value == 0 && aarch64::neon::hasZva()) {
501f578347SGuillaume Chatelet     generic::Memset<uint512_t>::block(dst, 0);
511f578347SGuillaume Chatelet     align_to_next_boundary<64>(dst, count);
521f578347SGuillaume Chatelet     return aarch64::neon::BzeroCacheLine::loop_and_tail(dst, 0, count);
531f578347SGuillaume Chatelet   } else {
541f578347SGuillaume Chatelet     generic::Memset<uint128_t>::block(dst, value);
551f578347SGuillaume Chatelet     align_to_next_boundary<16>(dst, count);
561f578347SGuillaume Chatelet     return generic::Memset<uint512_t>::loop_and_tail(dst, value, count);
571f578347SGuillaume Chatelet   }
581f578347SGuillaume Chatelet }
591f578347SGuillaume Chatelet 
60*5ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL
611f578347SGuillaume Chatelet 
621f578347SGuillaume Chatelet #endif // LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_MEMSET_H
63