1 /*
2 * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <string.h>
9 #include "crt_impl_private.h"
10
memcpy_r(void * dest,const void * src,size_t n)11 static void *memcpy_r(void *dest, const void *src, size_t n)
12 {
13 union composite_addr_t p_dst, p_src;
14
15 p_dst.uint_addr = (uintptr_t)dest + n;
16 p_src.uint_addr = (uintptr_t)src + n;
17
18 /* Byte copy for unaligned address. check the last bit of address. */
19 while (n && (ADDR_WORD_UNALIGNED(p_dst.uint_addr) ||
20 ADDR_WORD_UNALIGNED(p_src.uint_addr))) {
21 *(--p_dst.p_byte) = *(--p_src.p_byte);
22 n--;
23 }
24
25 /* Quad byte copy for aligned address. */
26 while (n >= sizeof(uint32_t)) {
27 *(--p_dst.p_word) = *(--p_src.p_word);
28 n -= sizeof(uint32_t);
29 }
30
31 /* Byte copy for the remaining bytes. */
32 while (n--) {
33 *(--p_dst.p_byte) = *(--p_src.p_byte);
34 }
35
36 return dest;
37 }
38
39 /* Mind the direction for copying in memcpy! */
40 #define memcpy_f memcpy
41
42 /*
43 * For overlapped memory area:
44 * 1) overlapped: use reverse memory move.
45 * 2) non-overlapped: use forward memory move.
46 */
memmove(void * dest,const void * src,size_t n)47 void *memmove(void *dest, const void *src, size_t n)
48 {
49 if (src >= dest) {
50 return memcpy_f(dest, src, n);
51 } else {
52 return memcpy_r(dest, src, n);
53 }
54 }
55