/* * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * */ #include #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; }