2 * linux/arch/arm/lib/copy_template.s
4 * Code template for optimized memory copy functions
6 * Author: Nicolas Pitre
7 * Created: Sep 28, 2005
8 * Copyright: MontaVista Software, Inc.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
16 * This can be used to enable code to cacheline align the source pointer.
17 * Experiments on tested architectures (StrongARM and XScale) didn't show
18 * this a worthwhile thing to do. That might be different in the future.
20 //#define CALGN(code...) code
21 #define CALGN(code...)
27 * This file provides the core code for a forward memory copy used in
28 * the implementation of memcopy(), copy_to_user() and copy_from_user().
30 * The including file must define the following accessor macros
31 * according to the need of the given function:
35 * This loads one word from 'ptr', stores it in 'reg' and increments
36 * 'ptr' to the next word. The 'abort' argument is used for fixup tables.
38 * ldr4w ptr reg1 reg2 reg3 reg4 abort
39 * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
41 * This loads four or eight words starting from 'ptr', stores them
42 * in provided registers and increments 'ptr' past those words.
43 * The'abort' argument is used for fixup tables.
45 * ldr1b ptr reg cond abort
47 * Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
48 * It also must apply the condition code if provided, otherwise the
49 * "al" condition is assumed by default.
52 * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
53 * str1b ptr reg cond abort
55 * Same as their ldr* counterparts, but data is stored to 'ptr' location
56 * rather than being loaded.
60 * Preserve the provided registers on the stack plus any additional
61 * data as needed by the implementation including this code. Called
66 * Restore registers with the values previously saved with the
67 * 'preserv' macro. Called upon code termination.
85 CALGN( ands ip, r1, #31 )
86 CALGN( rsb r3, ip, #32 )
87 CALGN( sbcnes r4, r3, r2 ) @ C is always set here
90 CALGN( subs r2, r2, r3 ) @ C gets set
91 CALGN( add pc, r4, ip )
94 2: PLD( subs r2, r2, #96 )
100 3: PLD( pld [r1, #124] )
101 4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
103 str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
110 addne pc, pc, ip @ C is always clear here
113 ldr1w r1, r3, abort=20f
114 ldr1w r1, r4, abort=20f
115 ldr1w r1, r5, abort=20f
116 ldr1w r1, r6, abort=20f
117 ldr1w r1, r7, abort=20f
118 ldr1w r1, r8, abort=20f
119 ldr1w r1, lr, abort=20f
124 str1w r0, r3, abort=20f
125 str1w r0, r4, abort=20f
126 str1w r0, r5, abort=20f
127 str1w r0, r6, abort=20f
128 str1w r0, r7, abort=20f
129 str1w r0, r8, abort=20f
130 str1w r0, lr, abort=20f
134 7: ldmfd sp!, {r5 - r8}
136 8: movs r2, r2, lsl #31
137 ldr1b r1, r3, ne, abort=21f
138 ldr1b r1, r4, cs, abort=21f
139 ldr1b r1, ip, cs, abort=21f
140 str1b r0, r3, ne, abort=21f
141 str1b r0, r4, cs, abort=21f
142 str1b r0, ip, cs, abort=21f
148 ldr1b r1, r3, gt, abort=21f
149 ldr1b r1, r4, ge, abort=21f
150 ldr1b r1, lr, abort=21f
151 str1b r0, r3, gt, abort=21f
152 str1b r0, r4, ge, abort=21f
154 str1b r0, lr, abort=21f
161 ldr1w r1, lr, abort=21f
166 .macro forward_copy_shift pull push
171 CALGN( ands ip, r1, #31 )
172 CALGN( rsb ip, ip, #32 )
173 CALGN( sbcnes r4, ip, r2 ) @ C is always set here
174 CALGN( subcc r2, r2, ip )
177 11: stmfd sp!, {r5 - r9}
180 PLD( subs r2, r2, #96 )
186 12: PLD( pld [r1, #124] )
187 13: ldr4w r1, r4, r5, r6, r7, abort=19f
188 mov r3, lr, pull #\pull
190 ldr4w r1, r8, r9, ip, lr, abort=19f
191 orr r3, r3, r4, push #\push
192 mov r4, r4, pull #\pull
193 orr r4, r4, r5, push #\push
194 mov r5, r5, pull #\pull
195 orr r5, r5, r6, push #\push
196 mov r6, r6, pull #\pull
197 orr r6, r6, r7, push #\push
198 mov r7, r7, pull #\pull
199 orr r7, r7, r8, push #\push
200 mov r8, r8, pull #\pull
201 orr r8, r8, r9, push #\push
202 mov r9, r9, pull #\pull
203 orr r9, r9, ip, push #\push
204 mov ip, ip, pull #\pull
205 orr ip, ip, lr, push #\push
206 str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
216 15: mov r3, lr, pull #\pull
217 ldr1w r1, lr, abort=21f
219 orr r3, r3, lr, push #\push
220 str1w r0, r3, abort=21f
225 16: sub r1, r1, #(\push / 8)
231 forward_copy_shift pull=8 push=24
233 17: forward_copy_shift pull=16 push=16
235 18: forward_copy_shift pull=24 push=8
239 * Abort preamble and completion macros.
240 * If a fixup handler is required then those macros must surround it.
241 * It is assumed that the fixup code will handle the private part of
245 .macro copy_abort_preamble
246 19: ldmfd sp!, {r5 - r9}
248 20: ldmfd sp!, {r5 - r8}
252 .macro copy_abort_end