~linaro-toolchain-dev/cortex-strings/trunk

1 by Michael Hope
Pulled in the initial versions
1
/* Copyright (C) 2006, 2009 Free Software Foundation, Inc.
2
   This file is part of the GNU C Library.
3
4
   Contributed by MontaVista Software, Inc. (written by Nicolas Pitre)
5
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.
10
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.
15
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
19
   02111-1307 USA.  */
20
21
/*
22
 * Data preload for architectures that support it (ARM V5TE and above)
23
 */
24
#if (!defined (__ARM_ARCH_2__) && !defined (__ARM_ARCH_3__) \
25
     && !defined (__ARM_ARCH_3M__) && !defined (__ARM_ARCH_4__) \
26
     && !defined (__ARM_ARCH_4T__) && !defined (__ARM_ARCH_5__) \
27
     && !defined (__ARM_ARCH_5T__))
28
#define PLD(code...)    code
29
#else
30
#define PLD(code...)
31
#endif
32
33
/*
34
 * This can be used to enable code to cacheline align the source pointer.
35
 * Experiments on tested architectures (StrongARM and XScale) didn't show
36
 * this a worthwhile thing to do.  That might be different in the future.
37
 */
38
//#define CALGN(code...)        code
39
#define CALGN(code...)
40
41
/*
42
 * Endian independent macros for shifting bytes within registers.
43
 */
44
#ifndef __ARMEB__
45
#define pull            lsr
46
#define push            lsl
47
#else
48
#define pull            lsl
49
#define push            lsr
50
#endif
51
77 by Michael Hope
Added function type attributes to all reference assembly versions.
52
	.text
53
	.global	memcpy
54
	.type	memcpy, %function
1 by Michael Hope
Pulled in the initial versions
55
56
/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
57
2 by Michael Hope
Made the different routines compile. Expanded the tests.
58
memcpy:
1 by Michael Hope
Pulled in the initial versions
59
60
		stmfd	sp!, {r0, r4, lr}
61
62
		subs	r2, r2, #4
63
		blt	8f
64
		ands	ip, r0, #3
65
	PLD(	pld	[r1, #0]		)
66
		bne	9f
67
		ands	ip, r1, #3
68
		bne	10f
69
70
1:		subs	r2, r2, #(28)
71
		stmfd	sp!, {r5 - r8}
72
		blt	5f
73
74
	CALGN(	ands	ip, r1, #31		)
75
	CALGN(	rsb	r3, ip, #32		)
76
	CALGN(	sbcnes	r4, r3, r2		)  @ C is always set here
77
	CALGN(	bcs	2f			)
78
	CALGN(	adr	r4, 6f			)
79
	CALGN(	subs	r2, r2, r3		)  @ C gets set
80
	CALGN(	add	pc, r4, ip		)
81
82
	PLD(	pld	[r1, #0]		)
83
2:	PLD(	subs	r2, r2, #96		)
84
	PLD(	pld	[r1, #28]		)
85
	PLD(	blt	4f			)
86
	PLD(	pld	[r1, #60]		)
87
	PLD(	pld	[r1, #92]		)
88
89
3:	PLD(	pld	[r1, #124]		)
90
4:		ldmia	r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
91
		subs	r2, r2, #32
92
		stmia	r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
93
		bge	3b
94
	PLD(	cmn	r2, #96			)
95
	PLD(	bge	4b			)
96
97
5:		ands	ip, r2, #28
98
		rsb	ip, ip, #32
99
		addne	pc, pc, ip		@ C is always clear here
100
		b	7f
101
6:		nop
102
		ldr	r3, [r1], #4
103
		ldr	r4, [r1], #4
104
		ldr	r5, [r1], #4
105
		ldr	r6, [r1], #4
106
		ldr	r7, [r1], #4
107
		ldr	r8, [r1], #4
108
		ldr	lr, [r1], #4
109
110
		add	pc, pc, ip
111
		nop
112
		nop
113
		str	r3, [r0], #4
114
		str	r4, [r0], #4
115
		str	r5, [r0], #4
116
		str	r6, [r0], #4
117
		str	r7, [r0], #4
118
		str	r8, [r0], #4
119
		str	lr, [r0], #4
120
121
	CALGN(	bcs	2b			)
122
123
7:		ldmfd	sp!, {r5 - r8}
124
125
8:		movs	r2, r2, lsl #31
126
		ldrneb	r3, [r1], #1
127
		ldrcsb	r4, [r1], #1
128
		ldrcsb	ip, [r1]
129
		strneb	r3, [r0], #1
130
		strcsb	r4, [r0], #1
131
		strcsb	ip, [r0]
132
133
#if defined (__ARM_ARCH_4T__) && defined(__THUMB_INTERWORK__)
134
		ldmfd	sp!, {r0, r4, lr}
135
		bx      lr
136
#else
137
		ldmfd	sp!, {r0, r4, pc}
138
#endif
139
140
9:		rsb	ip, ip, #4
141
		cmp	ip, #2
142
		ldrgtb	r3, [r1], #1
143
		ldrgeb	r4, [r1], #1
144
		ldrb	lr, [r1], #1
145
		strgtb	r3, [r0], #1
146
		strgeb	r4, [r0], #1
147
		subs	r2, r2, ip
148
		strb	lr, [r0], #1
149
		blt	8b
150
		ands	ip, r1, #3
151
		beq	1b
152
153
10:		bic	r1, r1, #3
154
		cmp	ip, #2
155
		ldr	lr, [r1], #4
156
		beq	17f
157
		bgt	18f
158
159
160
		.macro	forward_copy_shift pull push
161
162
		subs	r2, r2, #28
163
		blt	14f
164
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		)
169
	CALGN(	bcc	15f			)
170
171
11:		stmfd	sp!, {r5 - r9}
172
173
	PLD(	pld	[r1, #0]		)
174
	PLD(	subs	r2, r2, #96		)
175
	PLD(	pld	[r1, #28]		)
176
	PLD(	blt	13f			)
177
	PLD(	pld	[r1, #60]		)
178
	PLD(	pld	[r1, #92]		)
179
180
12:	PLD(	pld	[r1, #124]		)
181
13:		ldmia	r1!, {r4, r5, r6, r7}
182
		mov	r3, lr, pull #\pull
183
		subs	r2, r2, #32
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}
201
		bge	12b
202
	PLD(	cmn	r2, #96			)
203
	PLD(	bge	13b			)
204
205
		ldmfd	sp!, {r5 - r9}
206
207
14:		ands	ip, r2, #28
208
		beq	16f
209
210
15:		mov	r3, lr, pull #\pull
211
		ldr	lr, [r1], #4
212
		subs	ip, ip, #4
213
		orr	r3, r3, lr, push #\push
214
		str	r3, [r0], #4
215
		bgt	15b
216
	CALGN(	cmp	r2, #0			)
217
	CALGN(	bge	11b			)
218
219
16:		sub	r1, r1, #(\push / 8)
220
		b	8b
221
222
		.endm
223
224
225
		forward_copy_shift	pull=8	push=24
226
227
17:		forward_copy_shift	pull=16	push=16
228
229
18:		forward_copy_shift	pull=24	push=8