blob: b24a39d85fa634b328d8e22c1163812f153fc645 [file] [log] [blame]
/*
* Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <string.h>
#include "crt_impl_private.h"
static void *memcpy_r(void *dest, const void *src, size_t n)
{
union tfm_mem_addr_t p_dest, p_src;
p_dest.uint_addr = (uintptr_t)dest + n;
p_src.uint_addr = (uintptr_t)src + n;
/* Byte copy for unaligned address. check the last bit of address. */
while (n && (GET_MEM_ADDR_BIT0(p_dest.uint_addr) ||
GET_MEM_ADDR_BIT0(p_src.uint_addr))) {
*(--p_dest.p_byte) = *(--p_src.p_byte);
n--;
}
/* Double byte copy for aligned address.
* Check the 2nd last bit of address.
*/
while (n >= sizeof(uint16_t) && (GET_MEM_ADDR_BIT1(p_dest.uint_addr) ||
GET_MEM_ADDR_BIT1(p_src.uint_addr))) {
*(--p_dest.p_dbyte) = *(--p_src.p_dbyte);
n -= sizeof(uint16_t);
}
/* Quad byte copy for aligned address. */
while (n >= sizeof(uint32_t)) {
*(--p_dest.p_qbyte) = *(--p_src.p_qbyte);
n -= sizeof(uint32_t);
}
/* Byte copy for the remaining bytes. */
while (n--) {
*(--p_dest.p_byte) = *(--p_src.p_byte);
}
return dest;
}
/*
* For overlapped memory area:
* 1) overlapped: use reverse memory move.
* 2) non-overlapped: use forward memory move.
*/
void *memmove(void *dest, const void *src, size_t n)
{
/*
* FixMe: Add a "assert (dest == NULL || src == NULL)" here
* after "assert()" for sprtl is implemented.
*/
if (src >= dest) {
memcpy(dest, src, n);
} else {
memcpy_r(dest, src, n);
}
return dest;
}