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