summaryrefslogtreecommitdiff
path: root/utils/hwstub/stmp/memset.S
diff options
context:
space:
mode:
Diffstat (limited to 'utils/hwstub/stmp/memset.S')
-rw-r--r--utils/hwstub/stmp/memset.S98
1 files changed, 98 insertions, 0 deletions
diff --git a/utils/hwstub/stmp/memset.S b/utils/hwstub/stmp/memset.S
new file mode 100644
index 0000000000..682da874ce
--- /dev/null
+++ b/utils/hwstub/stmp/memset.S
@@ -0,0 +1,98 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Thom Johansen
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22
23 .section .icode,"ax",%progbits
24
25 .align 2
26
27/* The following code is based on code found in Linux kernel version 2.6.15.3
28 * linux/arch/arm/lib/memset.S
29 *
30 * Copyright (C) 1995-2000 Russell King
31 */
32
33/* This code will align a pointer for memset, if needed */
341: cmp r2, #4 @ 1 do we have enough
35 blt 5f @ 1 bytes to align with?
36 cmp r3, #2 @ 1
37 strgtb r1, [r0, #-1]! @ 1
38 strgeb r1, [r0, #-1]! @ 1
39 strb r1, [r0, #-1]! @ 1
40 sub r2, r2, r3 @ 1 r2 = r2 - r3
41 b 2f
42
43 .global memset
44 .type memset,%function
45memset:
46 add r0, r0, r2 @ we'll write backwards in memory
47 ands r3, r0, #3 @ 1 unaligned?
48 bne 1b @ 1
492:
50/*
51 * we know that the pointer in r0 is aligned to a word boundary.
52 */
53 orr r1, r1, r1, lsl #8
54 orr r1, r1, r1, lsl #16
55 mov r3, r1
56 cmp r2, #16
57 blt 5f
58/*
59 * We need an extra register for this loop - save the return address and
60 * use the LR
61 */
62 str lr, [sp, #-4]!
63 mov ip, r1
64 mov lr, r1
65
663: subs r2, r2, #64
67 stmgedb r0!, {r1, r3, ip, lr} @ 64 bytes at a time.
68 stmgedb r0!, {r1, r3, ip, lr}
69 stmgedb r0!, {r1, r3, ip, lr}
70 stmgedb r0!, {r1, r3, ip, lr}
71 bgt 3b
72 ldrpc cond=eq @ Now <64 bytes to go.
73/*
74 * No need to correct the count; we're only testing bits from now on
75 */
76 tst r2, #32
77 stmnedb r0!, {r1, r3, ip, lr}
78 stmnedb r0!, {r1, r3, ip, lr}
79 tst r2, #16
80 stmnedb r0!, {r1, r3, ip, lr}
81 ldr lr, [sp], #4
82
835: tst r2, #8
84 stmnedb r0!, {r1, r3}
85 tst r2, #4
86 strne r1, [r0, #-4]!
87/*
88 * When we get here, we've got less than 4 bytes to zero. We
89 * may have an unaligned pointer as well.
90 */
916: tst r2, #2
92 strneb r1, [r0, #-1]!
93 strneb r1, [r0, #-1]!
94 tst r2, #1
95 strneb r1, [r0, #-1]!
96 bx lr
97.end:
98 .size memset,.end-memset