1
linux/arch/avr32/lib/memcpy.S
Sebastian Andrzej Siewior 251ab1a37d avr32/lib: fix unaligned memcpy where len < 4
in case of memcpy(p, unaligned, 1..3) we get 1..3 as the
return value instead of p

Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
2009-07-27 12:37:28 +02:00

73 lines
1.2 KiB
ArmAsm

/*
* Copyright (C) 2004-2006 Atmel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/*
* void *memcpy(void *to, const void *from, unsigned long n)
*
* This implementation does word-aligned loads in the main loop,
* possibly sacrificing alignment of stores.
*
* Hopefully, in most cases, both "to" and "from" will be
* word-aligned to begin with.
*/
.text
.global memcpy
.type memcpy, @function
memcpy:
mov r9, r11
andl r9, 3, COH
brne 1f
/* At this point, "from" is word-aligned */
2: mov r9, r12
5: sub r10, 4
brlt 4f
3: ld.w r8, r11++
sub r10, 4
st.w r12++, r8
brge 3b
4: neg r10
reteq r9
/* Handle unaligned count */
lsl r10, 2
add pc, pc, r10
ld.ub r8, r11++
st.b r12++, r8
ld.ub r8, r11++
st.b r12++, r8
ld.ub r8, r11++
st.b r12++, r8
retal r9
/* Handle unaligned "from" pointer */
1: sub r10, 4
movlt r9, r12
brlt 4b
add r10, r9
lsl r9, 2
add pc, pc, r9
ld.ub r8, r11++
st.b r12++, r8
ld.ub r8, r11++
st.b r12++, r8
ld.ub r8, r11++
st.b r12++, r8
mov r8, r12
add pc, pc, r9
sub r8, 1
nop
sub r8, 1
nop
sub r8, 1
nop
mov r9, r8
rjmp 5b