1 //===-- Trivial byte per byte implementations ----------------------------===// 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 // Straightforward implementations targeting the smallest code size possible. 9 // This needs to be compiled with '-Os' or '-Oz'. 10 //===----------------------------------------------------------------------===// 11 12 #ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_BYTE_PER_BYTE_H 13 #define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_BYTE_PER_BYTE_H 14 15 #include "src/__support/macros/attributes.h" // LIBC_INLINE 16 #include "src/__support/macros/optimization.h" // LIBC_LOOP_NOUNROLL 17 #include "src/string/memory_utils/utils.h" // Ptr, CPtr 18 19 #include <stddef.h> // size_t 20 21 namespace LIBC_NAMESPACE_DECL { 22 23 [[maybe_unused]] LIBC_INLINE void 24 inline_memcpy_byte_per_byte(Ptr dst, CPtr src, size_t count, 25 size_t offset = 0) { 26 LIBC_LOOP_NOUNROLL 27 for (; offset < count; ++offset) 28 dst[offset] = src[offset]; 29 } 30 31 [[maybe_unused]] LIBC_INLINE void 32 inline_memmove_byte_per_byte(Ptr dst, CPtr src, size_t count) { 33 if (count == 0 || dst == src) 34 return; 35 if (dst < src) { 36 LIBC_LOOP_NOUNROLL 37 for (size_t offset = 0; offset < count; ++offset) 38 dst[offset] = src[offset]; 39 } else { 40 LIBC_LOOP_NOUNROLL 41 for (ptrdiff_t offset = count - 1; offset >= 0; --offset) 42 dst[offset] = src[offset]; 43 } 44 } 45 46 [[maybe_unused]] LIBC_INLINE static void 47 inline_memset_byte_per_byte(Ptr dst, uint8_t value, size_t count, 48 size_t offset = 0) { 49 LIBC_LOOP_NOUNROLL 50 for (; offset < count; ++offset) 51 dst[offset] = static_cast<cpp::byte>(value); 52 } 53 54 [[maybe_unused]] LIBC_INLINE BcmpReturnType 55 inline_bcmp_byte_per_byte(CPtr p1, CPtr p2, size_t count, size_t offset = 0) { 56 LIBC_LOOP_NOUNROLL 57 for (; offset < count; ++offset) 58 if (p1[offset] != p2[offset]) 59 return BcmpReturnType::nonzero(); 60 return BcmpReturnType::zero(); 61 } 62 63 [[maybe_unused]] LIBC_INLINE MemcmpReturnType 64 inline_memcmp_byte_per_byte(CPtr p1, CPtr p2, size_t count, size_t offset = 0) { 65 LIBC_LOOP_NOUNROLL 66 for (; offset < count; ++offset) { 67 const int32_t a = static_cast<int32_t>(p1[offset]); 68 const int32_t b = static_cast<int32_t>(p2[offset]); 69 const int32_t diff = a - b; 70 if (diff) 71 return diff; 72 } 73 return MemcmpReturnType::zero(); 74 } 75 76 } // namespace LIBC_NAMESPACE_DECL 77 78 #endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_BYTE_PER_BYTE_H 79