1 //===-- Implementation of memmove -----------------------------------------===// 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 9 #include "src/string/memmove.h" 10 #include "src/__support/common.h" 11 #include "src/stdlib/abs_utils.h" 12 #include "src/string/memcpy.h" 13 #include <stddef.h> // size_t, ptrdiff_t 14 15 namespace __llvm_libc { 16 17 static inline void move_byte_forward(char *dest_m, const char *src_m, 18 size_t count) { 19 for (size_t offset = 0; count; --count, ++offset) 20 dest_m[offset] = src_m[offset]; 21 } 22 23 static inline void move_byte_backward(char *dest_m, const char *src_m, 24 size_t count) { 25 for (size_t offset = count - 1; count; --count, --offset) 26 dest_m[offset] = src_m[offset]; 27 } 28 29 LLVM_LIBC_FUNCTION(void *, memmove, 30 (void *dest, const void *src, size_t count)) { 31 char *dest_c = reinterpret_cast<char *>(dest); 32 const char *src_c = reinterpret_cast<const char *>(src); 33 34 // If the distance between src_c and dest_c is equal to or greater 35 // than count (integer_abs(src_c - dest_c) >= count), they would not overlap. 36 // e.g. greater equal overlapping 37 // [12345678] [12345678] [12345678] 38 // src_c: [_ab_____] [_ab_____] [_ab_____] 39 // dest_c:[_____yz_] [___yz___] [__yz____] 40 41 // Use memcpy if src_c and dest_c do not overlap. 42 if (__llvm_libc::integer_abs(src_c - dest_c) >= static_cast<ptrdiff_t>(count)) 43 return __llvm_libc::memcpy(dest_c, src_c, count); 44 45 // Overlap cases. 46 // If dest_c starts before src_c (dest_c < src_c), copy forward(pointer add 1) 47 // from beginning to end. 48 // If dest_c starts after src_c (dest_c > src_c), copy backward(pointer add 49 // -1) from end to beginning. 50 // If dest_c and src_c start at the same address (dest_c == src_c), 51 // just return dest. 52 // e.g. forward backward 53 // *--> <--* 54 // src_c : [___abcde_] [_abcde___] 55 // dest_c: [_abc--___] [___--cde_] 56 57 // TODO: Optimize `move_byte_xxx(...)` functions. 58 if (dest_c < src_c) 59 move_byte_forward(dest_c, src_c, count); 60 if (dest_c > src_c) 61 move_byte_backward(dest_c, src_c, count); 62 return dest; 63 } 64 65 } // namespace __llvm_libc 66