blob: 535f4a2570e116d7db7cbe335871bea0245b6201 [file] [log] [blame]
/*
* 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)