blob: bd5f8f1ac51a153096aebdcb20490fc6eb2acefa [file] [log] [blame]
Gabe Black7a6651c2013-07-07 14:15:22 -07001/*
2 * linux/arch/arm/lib/memmove.S
3 *
4 * Author: Nicolas Pitre
5 * Created: Sep 28, 2005
6 * Copyright: (C) MontaVista Software Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
Julius Wernerd65e2142013-12-13 12:59:57 -080013#include <arch/asm.h>
14#include "asmlib.h"
Gabe Black7a6651c2013-07-07 14:15:22 -070015
Gabe Black7a6651c2013-07-07 14:15:22 -070016/*
17 * Prototype: void *memmove(void *dest, const void *src, size_t n);
18 *
19 * Note:
20 *
21 * If the memory regions don't overlap, we simply branch to memcpy which is
22 * normally a bit faster. Otherwise the copy is done going downwards. This
23 * is a transposition of the code from copy_template.S but with the copy
24 * occurring in the opposite direction.
25 */
26
Julius Wernerd65e2142013-12-13 12:59:57 -080027ENTRY(memmove)
28
Gabe Black7a6651c2013-07-07 14:15:22 -070029 subs ip, r0, r1
30 cmphi r2, ip
31 bls memcpy
32
33 stmfd sp!, {r0, r4, lr}
34 add r1, r1, r2
35 add r0, r0, r2
36 subs r2, r2, #4
37 blt 8f
38 ands ip, r0, #3
39 PLD( pld [r1, #-4] )
40 bne 9f
41 ands ip, r1, #3
42 bne 10f
43
441: subs r2, r2, #(28)
45 stmfd sp!, {r5 - r8}
46 blt 5f
47
48 CALGN( ands ip, r0, #31 )
49 CALGN( sbcnes r4, ip, r2 ) @ C is always set here
50 CALGN( bcs 2f )
51 CALGN( adr r4, 6f )
52 CALGN( subs r2, r2, ip ) @ C is set here
53 CALGN( rsb ip, ip, #32 )
54 CALGN( add pc, r4, ip )
55
56 PLD( pld [r1, #-4] )
572: PLD( subs r2, r2, #96 )
58 PLD( pld [r1, #-32] )
59 PLD( blt 4f )
60 PLD( pld [r1, #-64] )
61 PLD( pld [r1, #-96] )
62
633: PLD( pld [r1, #-128] )
644: ldmdb r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
65 subs r2, r2, #32
66 stmdb r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
67 bge 3b
68 PLD( cmn r2, #96 )
69 PLD( bge 4b )
70
715: ands ip, r2, #28
72 rsb ip, ip, #32
73 addne pc, pc, ip @ C is always clear here
74 b 7f
756: W(nop)
76 W(ldr) r3, [r1, #-4]!
77 W(ldr) r4, [r1, #-4]!
78 W(ldr) r5, [r1, #-4]!
79 W(ldr) r6, [r1, #-4]!
80 W(ldr) r7, [r1, #-4]!
81 W(ldr) r8, [r1, #-4]!
82 W(ldr) lr, [r1, #-4]!
83
84 add pc, pc, ip
85 nop
86 W(nop)
87 W(str) r3, [r0, #-4]!
88 W(str) r4, [r0, #-4]!
89 W(str) r5, [r0, #-4]!
90 W(str) r6, [r0, #-4]!
91 W(str) r7, [r0, #-4]!
92 W(str) r8, [r0, #-4]!
93 W(str) lr, [r0, #-4]!
94
95 CALGN( bcs 2b )
96
977: ldmfd sp!, {r5 - r8}
98
998: movs r2, r2, lsl #31
100 ldrneb r3, [r1, #-1]!
101 ldrcsb r4, [r1, #-1]!
102 ldrcsb ip, [r1, #-1]
103 strneb r3, [r0, #-1]!
104 strcsb r4, [r0, #-1]!
105 strcsb ip, [r0, #-1]
106 ldmfd sp!, {r0, r4, pc}
107
1089: cmp ip, #2
109 ldrgtb r3, [r1, #-1]!
110 ldrgeb r4, [r1, #-1]!
111 ldrb lr, [r1, #-1]!
112 strgtb r3, [r0, #-1]!
113 strgeb r4, [r0, #-1]!
114 subs r2, r2, ip
115 strb lr, [r0, #-1]!
116 blt 8b
117 ands ip, r1, #3
118 beq 1b
119
12010: bic r1, r1, #3
121 cmp ip, #2
122 ldr r3, [r1, #0]
123 beq 17f
124 blt 18f
125
126
127 .macro backward_copy_shift push pull
128
129 subs r2, r2, #28
130 blt 14f
131
132 CALGN( ands ip, r0, #31 )
133 CALGN( sbcnes r4, ip, r2 ) @ C is always set here
134 CALGN( subcc r2, r2, ip )
135 CALGN( bcc 15f )
136
13711: stmfd sp!, {r5 - r9}
138
139 PLD( pld [r1, #-4] )
140 PLD( subs r2, r2, #96 )
141 PLD( pld [r1, #-32] )
142 PLD( blt 13f )
143 PLD( pld [r1, #-64] )
144 PLD( pld [r1, #-96] )
145
14612: PLD( pld [r1, #-128] )
14713: ldmdb r1!, {r7, r8, r9, ip}
148 mov lr, r3, push #\push
149 subs r2, r2, #32
150 ldmdb r1!, {r3, r4, r5, r6}
151 orr lr, lr, ip, pull #\pull
152 mov ip, ip, push #\push
153 orr ip, ip, r9, pull #\pull
154 mov r9, r9, push #\push
155 orr r9, r9, r8, pull #\pull
156 mov r8, r8, push #\push
157 orr r8, r8, r7, pull #\pull
158 mov r7, r7, push #\push
159 orr r7, r7, r6, pull #\pull
160 mov r6, r6, push #\push
161 orr r6, r6, r5, pull #\pull
162 mov r5, r5, push #\push
163 orr r5, r5, r4, pull #\pull
164 mov r4, r4, push #\push
165 orr r4, r4, r3, pull #\pull
166 stmdb r0!, {r4 - r9, ip, lr}
167 bge 12b
168 PLD( cmn r2, #96 )
169 PLD( bge 13b )
170
171 ldmfd sp!, {r5 - r9}
172
17314: ands ip, r2, #28
174 beq 16f
175
17615: mov lr, r3, push #\push
177 ldr r3, [r1, #-4]!
178 subs ip, ip, #4
179 orr lr, lr, r3, pull #\pull
180 str lr, [r0, #-4]!
181 bgt 15b
182 CALGN( cmp r2, #0 )
183 CALGN( bge 11b )
184
18516: add r1, r1, #(\pull / 8)
186 b 8b
187
188 .endm
189
190
191 backward_copy_shift push=8 pull=24
192
19317: backward_copy_shift push=16 pull=16
194
19518: backward_copy_shift push=24 pull=8
Julius Wernerd65e2142013-12-13 12:59:57 -0800196
197ENDPROC(memmove)