1
/* Copyright (C) 2006, 2009 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, write to the Free
18
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24
* Data preload for architectures that support it (ARM V5TE and above)
26
#if (!defined (__ARM_ARCH_2__) && !defined (__ARM_ARCH_3__) \
27
&& !defined (__ARM_ARCH_3M__) && !defined (__ARM_ARCH_4__) \
28
&& !defined (__ARM_ARCH_4T__) && !defined (__ARM_ARCH_5__) \
29
&& !defined (__ARM_ARCH_5T__))
30
#define PLD(code...) code
36
* This can be used to enable code to cacheline align the source pointer.
37
* Experiments on tested architectures (StrongARM and XScale) didn't show
38
* this a worthwhile thing to do. That might be different in the future.
40
//#define CALGN(code...) code
41
#define CALGN(code...)
44
* Endian independent macros for shifting bytes within registers.
56
/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
60
stmfd sp!, {r0, r4, lr}
74
CALGN( ands ip, r1, #31 )
75
CALGN( rsb r3, ip, #32 )
76
CALGN( sbcnes r4, r3, r2 ) @ C is always set here
79
CALGN( subs r2, r2, r3 ) @ C gets set
80
CALGN( add pc, r4, ip )
83
2: PLD( subs r2, r2, #96 )
89
3: PLD( pld [r1, #124] )
90
4: ldmia r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
92
stmia r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
99
addne pc, pc, ip @ C is always clear here
123
7: ldmfd sp!, {r5 - r8}
125
8: movs r2, r2, lsl #31
133
#if defined (__ARM_ARCH_4T__) && defined(__THUMB_INTERWORK__)
134
ldmfd sp!, {r0, r4, lr}
137
ldmfd sp!, {r0, r4, pc}
160
.macro forward_copy_shift pull push
165
CALGN( ands ip, r1, #31 )
166
CALGN( rsb ip, ip, #32 )
167
CALGN( sbcnes r4, ip, r2 ) @ C is always set here
168
CALGN( subcc r2, r2, ip )
171
11: stmfd sp!, {r5 - r9}
174
PLD( subs r2, r2, #96 )
180
12: PLD( pld [r1, #124] )
181
13: ldmia r1!, {r4, r5, r6, r7}
182
mov r3, lr, pull #\pull
184
ldmia r1!, {r8, r9, ip, lr}
185
orr r3, r3, r4, push #\push
186
mov r4, r4, pull #\pull
187
orr r4, r4, r5, push #\push
188
mov r5, r5, pull #\pull
189
orr r5, r5, r6, push #\push
190
mov r6, r6, pull #\pull
191
orr r6, r6, r7, push #\push
192
mov r7, r7, pull #\pull
193
orr r7, r7, r8, push #\push
194
mov r8, r8, pull #\pull
195
orr r8, r8, r9, push #\push
196
mov r9, r9, pull #\pull
197
orr r9, r9, ip, push #\push
198
mov ip, ip, pull #\pull
199
orr ip, ip, lr, push #\push
200
stmia r0!, {r3, r4, r5, r6, r7, r8, r9, ip}
210
15: mov r3, lr, pull #\pull
213
orr r3, r3, lr, push #\push
219
16: sub r1, r1, #(\push / 8)
225
forward_copy_shift pull=8 push=24
227
17: forward_copy_shift pull=16 push=16
229
18: forward_copy_shift pull=24 push=8
232
libc_hidden_builtin_def (memcpy)