.text
ENTRY(__memmove)
WEAK(memmove)
UNWIND( .fnstart )
subs ip, r0, r1
cmphi r2, ip
bls __memcpy
UNWIND( .fnend )
UNWIND( .fnstart )
UNWIND( .save {r0, r4, fpreg, lr} )
stmfd sp!, {r0, r4, UNWIND(fpreg,) lr}
UNWIND( .setfp fpreg, sp )
UNWIND( mov fpreg, sp )
add r1, r1, r2
add r0, r0, r2
subs r2, r2,
blt 8f
ands ip, r0,
PLD( pld [r1,
bne 9f
ands ip, r1,
bne 10f
1: subs r2, r2,
stmfd sp!, {r5, r6, r8, r9}
blt 5f
CALGN( ands ip, r0,
CALGN( sbcsne r4, ip, r2 ) @ C is always set here
CALGN( bcs 2f )
CALGN( adr r4, 6f )
CALGN( subs r2, r2, ip ) @ C is set here
CALGN( rsb ip, ip,
CALGN( add pc, r4, ip )
PLD( pld [r1,
2: PLD( subs r2, r2,
PLD( pld [r1,
PLD( blt 4f )
PLD( pld [r1,
PLD( pld [r1,
3: PLD( pld [r1,
4: ldmdb r1!, {r3, r4, r5, r6, r8, r9, ip, lr}
subs r2, r2,
stmdb r0!, {r3, r4, r5, r6, r8, r9, ip, lr}
bge 3b
PLD( cmn r2,
PLD( bge 4b )
5: ands ip, r2,
rsb ip, ip,
addne pc, pc, ip @ C is always clear here
b 7f
6: W(nop)
W(ldr) r3, [r1,
W(ldr) r4, [r1,
W(ldr) r5, [r1,
W(ldr) r6, [r1,
W(ldr) r8, [r1,
W(ldr) r9, [r1,
W(ldr) lr, [r1,
add pc, pc, ip
nop
W(nop)
W(str) r3, [r0,
W(str) r4, [r0,
W(str) r5, [r0,
W(str) r6, [r0,
W(str) r8, [r0,
W(str) r9, [r0,
W(str) lr, [r0,
CALGN( bcs 2b )
7: ldmfd sp!, {r5, r6, r8, r9}
8: movs r2, r2, lsl
ldrbne r3, [r1,
ldrbcs r4, [r1,
ldrbcs ip, [r1,
strbne r3, [r0,
strbcs r4, [r0,
strbcs ip, [r0,
ldmfd sp!, {r0, r4, UNWIND(fpreg,) pc}
9: cmp ip,
ldrbgt r3, [r1,
ldrbge r4, [r1,
ldrb lr, [r1,
strbgt r3, [r0,
strbge r4, [r0,
subs r2, r2, ip
strb lr, [r0,
blt 8b
ands ip, r1,
beq 1b
10: bic r1, r1,
cmp ip,
ldr r3, [r1,
beq 17f
blt 18f
.macro backward_copy_shift push pull
subs r2, r2,
blt 14f
CALGN( ands ip, r0,
CALGN( sbcsne r4, ip, r2 ) @ C is always set here
CALGN( subcc r2, r2, ip )
CALGN( bcc 15f )
11: stmfd sp!, {r5, r6, r8 - r10}
PLD( pld [r1,
PLD( subs r2, r2,
PLD( pld [r1,
PLD( blt 13f )
PLD( pld [r1,
PLD( pld [r1,
12: PLD( pld [r1,
13: ldmdb r1!, {r8, r9, r10, ip}
mov lr, r3, lspush
subs r2, r2,
ldmdb r1!, {r3, r4, r5, r6}
orr lr, lr, ip, lspull
mov ip, ip, lspush
orr ip, ip, r10, lspull
mov r10, r10, lspush
orr r10, r10, r9, lspull
mov r9, r9, lspush
orr r9, r9, r8, lspull
mov r8, r8, lspush
orr r8, r8, r6, lspull
mov r6, r6, lspush
orr r6, r6, r5, lspull
mov r5, r5, lspush
orr r5, r5, r4, lspull
mov r4, r4, lspush
orr r4, r4, r3, lspull
stmdb r0!, {r4 - r6, r8 - r10, ip, lr}
bge 12b
PLD( cmn r2,
PLD( bge 13b )
ldmfd sp!, {r5, r6, r8 - r10}
14: ands ip, r2,
beq 16f
15: mov lr, r3, lspush
ldr r3, [r1,
subs ip, ip,
orr lr, lr, r3, lspull
str lr, [r0,
bgt 15b
CALGN( cmp r2,
CALGN( bge 11b )
16: add r1, r1,
b 8b
.endm
backward_copy_shift push=8 pull=24
17: backward_copy_shift push=16 pull=16
18: backward_copy_shift push=24 pull=8
UNWIND( .fnend )
ENDPROC(memmove)
ENDPROC(__memmove)