xref: /llvm-project/libc/src/string/memory_utils/generic/byte_per_byte.h (revision 2cc97951400ca2ab79d6bdeccffa6e431882a86e)
1dbaa5838SGuillaume Chatelet //===-- Trivial byte per byte implementations  ----------------------------===//
2dbaa5838SGuillaume Chatelet //
3dbaa5838SGuillaume Chatelet // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4dbaa5838SGuillaume Chatelet // See https://llvm.org/LICENSE.txt for license information.
5dbaa5838SGuillaume Chatelet // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6dbaa5838SGuillaume Chatelet //
7dbaa5838SGuillaume Chatelet //===----------------------------------------------------------------------===//
8dbaa5838SGuillaume Chatelet // Straightforward implementations targeting the smallest code size possible.
9dbaa5838SGuillaume Chatelet // This needs to be compiled with '-Os' or '-Oz'.
10dbaa5838SGuillaume Chatelet //===----------------------------------------------------------------------===//
11dbaa5838SGuillaume Chatelet 
12dbaa5838SGuillaume Chatelet #ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_BYTE_PER_BYTE_H
13dbaa5838SGuillaume Chatelet #define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_BYTE_PER_BYTE_H
14dbaa5838SGuillaume Chatelet 
15*2cc97951Sc8ef #include "src/__support/macros/attributes.h"   // LIBC_INLINE
16dbaa5838SGuillaume Chatelet #include "src/__support/macros/optimization.h" // LIBC_LOOP_NOUNROLL
17dbaa5838SGuillaume Chatelet #include "src/string/memory_utils/utils.h"     // Ptr, CPtr
18dbaa5838SGuillaume Chatelet 
19dbaa5838SGuillaume Chatelet #include <stddef.h> // size_t
20dbaa5838SGuillaume Chatelet 
215ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL {
22dbaa5838SGuillaume Chatelet 
23dbaa5838SGuillaume Chatelet [[maybe_unused]] LIBC_INLINE void
24dbaa5838SGuillaume Chatelet inline_memcpy_byte_per_byte(Ptr dst, CPtr src, size_t count,
25dbaa5838SGuillaume Chatelet                             size_t offset = 0) {
26dbaa5838SGuillaume Chatelet   LIBC_LOOP_NOUNROLL
27dbaa5838SGuillaume Chatelet   for (; offset < count; ++offset)
28dbaa5838SGuillaume Chatelet     dst[offset] = src[offset];
29dbaa5838SGuillaume Chatelet }
30dbaa5838SGuillaume Chatelet 
31dbaa5838SGuillaume Chatelet [[maybe_unused]] LIBC_INLINE void
32dbaa5838SGuillaume Chatelet inline_memmove_byte_per_byte(Ptr dst, CPtr src, size_t count) {
33dbaa5838SGuillaume Chatelet   if (count == 0 || dst == src)
34dbaa5838SGuillaume Chatelet     return;
35dbaa5838SGuillaume Chatelet   if (dst < src) {
36dbaa5838SGuillaume Chatelet     LIBC_LOOP_NOUNROLL
37dbaa5838SGuillaume Chatelet     for (size_t offset = 0; offset < count; ++offset)
38dbaa5838SGuillaume Chatelet       dst[offset] = src[offset];
39dbaa5838SGuillaume Chatelet   } else {
40dbaa5838SGuillaume Chatelet     LIBC_LOOP_NOUNROLL
41dbaa5838SGuillaume Chatelet     for (ptrdiff_t offset = count - 1; offset >= 0; --offset)
42dbaa5838SGuillaume Chatelet       dst[offset] = src[offset];
43dbaa5838SGuillaume Chatelet   }
44dbaa5838SGuillaume Chatelet }
45dbaa5838SGuillaume Chatelet 
46dbaa5838SGuillaume Chatelet [[maybe_unused]] LIBC_INLINE static void
47dbaa5838SGuillaume Chatelet inline_memset_byte_per_byte(Ptr dst, uint8_t value, size_t count,
48dbaa5838SGuillaume Chatelet                             size_t offset = 0) {
49dbaa5838SGuillaume Chatelet   LIBC_LOOP_NOUNROLL
50dbaa5838SGuillaume Chatelet   for (; offset < count; ++offset)
51dbaa5838SGuillaume Chatelet     dst[offset] = static_cast<cpp::byte>(value);
52dbaa5838SGuillaume Chatelet }
53dbaa5838SGuillaume Chatelet 
54dbaa5838SGuillaume Chatelet [[maybe_unused]] LIBC_INLINE BcmpReturnType
55dbaa5838SGuillaume Chatelet inline_bcmp_byte_per_byte(CPtr p1, CPtr p2, size_t count, size_t offset = 0) {
56dbaa5838SGuillaume Chatelet   LIBC_LOOP_NOUNROLL
57dbaa5838SGuillaume Chatelet   for (; offset < count; ++offset)
58dbaa5838SGuillaume Chatelet     if (p1[offset] != p2[offset])
5927352e60SNick Desaulniers       return BcmpReturnType::nonzero();
606f8d826bSNick Desaulniers   return BcmpReturnType::zero();
61dbaa5838SGuillaume Chatelet }
62dbaa5838SGuillaume Chatelet 
63dbaa5838SGuillaume Chatelet [[maybe_unused]] LIBC_INLINE MemcmpReturnType
64dbaa5838SGuillaume Chatelet inline_memcmp_byte_per_byte(CPtr p1, CPtr p2, size_t count, size_t offset = 0) {
65dbaa5838SGuillaume Chatelet   LIBC_LOOP_NOUNROLL
66dbaa5838SGuillaume Chatelet   for (; offset < count; ++offset) {
67dbaa5838SGuillaume Chatelet     const int32_t a = static_cast<int32_t>(p1[offset]);
68dbaa5838SGuillaume Chatelet     const int32_t b = static_cast<int32_t>(p2[offset]);
69dbaa5838SGuillaume Chatelet     const int32_t diff = a - b;
70dbaa5838SGuillaume Chatelet     if (diff)
71dbaa5838SGuillaume Chatelet       return diff;
72dbaa5838SGuillaume Chatelet   }
736f8d826bSNick Desaulniers   return MemcmpReturnType::zero();
74dbaa5838SGuillaume Chatelet }
75dbaa5838SGuillaume Chatelet 
765ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL
77dbaa5838SGuillaume Chatelet 
78dbaa5838SGuillaume Chatelet #endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_BYTE_PER_BYTE_H
79