1 /* Copyright (C) 2006-2013 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 Contributed by MontaVista Software, Inc. (written by Nicolas Pitre)
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library. If not, see
18 <http://www.gnu.org/licenses/>. */
23 * Data preload for architectures that support it (ARM V5TE and above)
25 #if (!defined (__ARM_ARCH_2__) && !defined (__ARM_ARCH_3__) \
26 && !defined (__ARM_ARCH_3M__) && !defined (__ARM_ARCH_4__) \
27 && !defined (__ARM_ARCH_4T__) && !defined (__ARM_ARCH_5__) \
28 && !defined (__ARM_ARCH_5T__))
29 #define PLD(code...) code
35 * This can be used to enable code to cacheline align the source pointer.
36 * Experiments on tested architectures (StrongARM and XScale) didn't show
37 * this a worthwhile thing to do. That might be different in the future.
39 //#define CALGN(code...) code
40 #define CALGN(code...)
43 * Endian independent macros for shifting bytes within registers.
56 * Prototype: void *memmove(void *dest, const void *src, size_t n);
60 * If the memory regions don't overlap, we simply branch to memcpy which is
61 * normally a bit faster. Otherwise the copy is done going downwards.
71 bls HIDDEN_JUMPTARGET(memcpy)
74 stmfd sp!, {r0, r4, lr}
75 cfi_adjust_cfa_offset (12)
76 cfi_rel_offset (r4, 4)
77 cfi_rel_offset (lr, 8)
93 cfi_adjust_cfa_offset (16)
94 cfi_rel_offset (r5, 0)
95 cfi_rel_offset (r6, 4)
96 cfi_rel_offset (r7, 8)
97 cfi_rel_offset (r8, 12)
100 CALGN( ands ip, r1, #31 )
101 CALGN( sbcnes r4, ip, r2 ) @ C is always set here
104 CALGN( subs r2, r2, ip ) @ C is set here
105 CALGN( add pc, r4, ip )
108 2: PLD( subs r2, r2, #96 )
109 PLD( pld [r1, #-32] )
111 PLD( pld [r1, #-64] )
112 PLD( pld [r1, #-96] )
114 3: PLD( pld [r1, #-128] )
115 4: ldmdb r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
117 stmdb r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
124 addne pc, pc, ip @ C is always clear here
148 7: ldmfd sp!, {r5 - r8}
149 cfi_adjust_cfa_offset (-16)
155 8: movs r2, r2, lsl #31
156 ldrneb r3, [r1, #-1]!
157 ldrcsb r4, [r1, #-1]!
159 strneb r3, [r0, #-1]!
160 strcsb r4, [r0, #-1]!
163 #if defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__)
164 ldmfd sp!, {r0, r4, lr}
165 cfi_adjust_cfa_offset (-12)
170 ldmfd sp!, {r0, r4, pc}
176 ldrgtb r3, [r1, #-1]!
177 ldrgeb r4, [r1, #-1]!
179 strgtb r3, [r0, #-1]!
180 strgeb r4, [r0, #-1]!
194 .macro backward_copy_shift push pull
199 CALGN( ands ip, r1, #31 )
200 CALGN( rsb ip, ip, #32 )
201 CALGN( sbcnes r4, ip, r2 ) @ C is always set here
202 CALGN( subcc r2, r2, ip )
205 11: stmfd sp!, {r5 - r9}
206 cfi_adjust_cfa_offset (20)
207 cfi_rel_offset (r5, 0)
208 cfi_rel_offset (r6, 4)
209 cfi_rel_offset (r7, 8)
210 cfi_rel_offset (r8, 12)
211 cfi_rel_offset (r9, 16)
214 PLD( subs r2, r2, #96 )
215 PLD( pld [r1, #-32] )
217 PLD( pld [r1, #-64] )
218 PLD( pld [r1, #-96] )
220 12: PLD( pld [r1, #-128] )
221 13: ldmdb r1!, {r7, r8, r9, ip}
222 mov lr, r3, push #\push
224 ldmdb r1!, {r3, r4, r5, r6}
225 orr lr, lr, ip, pull #\pull
226 mov ip, ip, push #\push
227 orr ip, ip, r9, pull #\pull
228 mov r9, r9, push #\push
229 orr r9, r9, r8, pull #\pull
230 mov r8, r8, push #\push
231 orr r8, r8, r7, pull #\pull
232 mov r7, r7, push #\push
233 orr r7, r7, r6, pull #\pull
234 mov r6, r6, push #\push
235 orr r6, r6, r5, pull #\pull
236 mov r5, r5, push #\push
237 orr r5, r5, r4, pull #\pull
238 mov r4, r4, push #\push
239 orr r4, r4, r3, pull #\pull
240 stmdb r0!, {r4 - r9, ip, lr}
246 cfi_adjust_cfa_offset (-20)
256 15: mov lr, r3, push #\push
259 orr lr, lr, r3, pull #\pull
265 16: add r1, r1, #(\pull / 8)
271 backward_copy_shift push=8 pull=24
273 17: backward_copy_shift push=16 pull=16
275 18: backward_copy_shift push=24 pull=8
279 libc_hidden_builtin_def (memmove)