summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/common/memset_a.S81
1 files changed, 81 insertions, 0 deletions
diff --git a/firmware/common/memset_a.S b/firmware/common/memset_a.S
index 9403e8d68e..b6a9ca8f71 100644
--- a/firmware/common/memset_a.S
+++ b/firmware/common/memset_a.S
@@ -18,7 +18,11 @@
18 ****************************************************************************/ 18 ****************************************************************************/
19#include "config.h" 19#include "config.h"
20 20
21#ifdef CPU_ARM
22 .section .icode,"ax",%progbits
23#elif
21 .section .icode,"ax",@progbits 24 .section .icode,"ax",@progbits
25#endif
22 26
23 .align 2 27 .align 2
24#if CONFIG_CPU == SH7034 28#if CONFIG_CPU == SH7034
@@ -234,4 +238,81 @@ memset:
234 238
235.end: 239.end:
236 .size memset,.end-memset 240 .size memset,.end-memset
241
242#elif defined(CPU_ARM)
243
244/* The following code is taken from the Linux kernel version 2.6.15.3
245 * linux/arch/arm/lib/memset.S
246 *
247 * Copyright (C) 1995-2000 Russell King
248 */
249
250@ .word 0
2511: subs r2, r2, #4 @ 1 do we have enough
252 blt 5f @ 1 bytes to align with?
253 cmp r3, #2 @ 1
254 strltb r1, [r0], #1 @ 1
255 strleb r1, [r0], #1 @ 1
256 strb r1, [r0], #1 @ 1
257 add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
258/*
259 * The pointer is now aligned and the length is adjusted. Try doing the
260 * memzero again.
261 */
262
263 .global memset
264 .type memset,%function
265memset:
266 ands r3, r0, #3 @ 1 unaligned?
267 bne 1b @ 1
268/*
269 * we know that the pointer in r0 is aligned to a word boundary.
270 */
271 orr r1, r1, r1, lsl #8
272 orr r1, r1, r1, lsl #16
273 mov r3, r1
274 cmp r2, #16
275 blt 4f
276/*
277 * We need an extra register for this loop - save the return address and
278 * use the LR
279 */
280 str lr, [sp, #-4]!
281 mov ip, r1
282 mov lr, r1
283
2842: subs r2, r2, #64
285 stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time.
286 stmgeia r0!, {r1, r3, ip, lr}
287 stmgeia r0!, {r1, r3, ip, lr}
288 stmgeia r0!, {r1, r3, ip, lr}
289 bgt 2b
290 ldmeqfd sp!, {pc} @ Now <64 bytes to go.
291/*
292 * No need to correct the count; we're only testing bits from now on
293 */
294 tst r2, #32
295 stmneia r0!, {r1, r3, ip, lr}
296 stmneia r0!, {r1, r3, ip, lr}
297 tst r2, #16
298 stmneia r0!, {r1, r3, ip, lr}
299 ldr lr, [sp], #4
300
3014: tst r2, #8
302 stmneia r0!, {r1, r3}
303 tst r2, #4
304 strne r1, [r0], #4
305/*
306 * When we get here, we've got less than 4 bytes to zero. We
307 * may have an unaligned pointer as well.
308 */
3095: tst r2, #2
310 strneb r1, [r0], #1
311 strneb r1, [r0], #1
312 tst r2, #1
313 strneb r1, [r0], #1
314 mov pc, lr
315end:
316 .size memset,.end-memset
237#endif 317#endif
318