/* * Copyright (C) 2004-2007 Atmel Corporation * * This file is subject to the terms and conditions of the GNU Lesser General * Public License. See the file "COPYING.LIB" in the main directory of this * archive for more details. */ #define dst r12 #define src r11 #define len r10 .text .global memmove .type memmove, @function memmove: cp.w src, dst brge HIDDEN_JUMPTARGET(memcpy) add dst, len add src, len pref src[-1] /* * The rest is basically the same as in memcpy.S except that * the direction is reversed. */ cp.w len, 32 brge .Lmore_than_31 sub len, 1 retlt r12 1: ld.ub r8, --src st.b --dst, r8 sub len, 1 brge 1b retal r12 .Lmore_than_31: pushm r0-r7, lr /* Check alignment */ mov r8, src andl r8, 31, COH brne .Lunaligned_src mov r8, r12 andl r8, 3, COH brne .Lunaligned_dst .Laligned_copy: sub len, 32 brlt .Lless_than_32 1: /* Copy 32 bytes at a time */ sub src, 32 ldm src, r0-r7 sub dst, 32 sub len, 32 stm dst, r0-r7 brge 1b .Lless_than_32: /* Copy 16 more bytes if possible */ sub len, -16 brlt .Lless_than_16 sub src, 16 ldm src, r0-r3 sub dst, 16 sub len, 16 stm dst, r0-r3 .Lless_than_16: /* Do the remaining as byte copies */ sub len, -16 breq 2f 1: ld.ub r0, --src st.b --dst, r0 sub len, 1 brne 1b 2: popm r0-r7, pc .Lunaligned_src: /* Make src cacheline-aligned. r8 = (src & 31) */ sub len, r8 1: ld.ub r0, --src st.b --dst, r0 sub r8, 1 brne 1b /* If dst is word-aligned, we're ready to go */ pref src[-4] mov r8, 3 tst dst, r8 breq .Laligned_copy .Lunaligned_dst: /* src is aligned, but dst is not. Expect bad performance */ sub len, 4 brlt 2f 1: ld.w r0, --src st.w --dst, r0 sub len, 4 brge 1b 2: neg len add pc, pc, len << 2 .rept 3 ld.ub r0, --src st.b --dst, r0 .endr popm r0-r7, pc .size memmove, . - memmove libc_hidden_def(memmove)