Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * linux/arch/arm/lib/memset.S | |
3 | * | |
4 | * Copyright (C) 1995-2000 Russell King | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 as | |
8 | * published by the Free Software Foundation. | |
9 | * | |
10 | * ASM optimised string functions | |
11 | */ | |
12 | #include <linux/linkage.h> | |
13 | #include <asm/assembler.h> | |
c2459d35 | 14 | #include <asm/unwind.h> |
4dd1837d | 15 | #include <asm/export.h> |
1da177e4 LT |
16 | |
17 | .text | |
18 | .align 5 | |
1da177e4 | 19 | |
1bd46782 | 20 | ENTRY(mmioset) |
1da177e4 | 21 | ENTRY(memset) |
c2459d35 | 22 | UNWIND( .fnstart ) |
418df63a NP |
23 | ands r3, r0, #3 @ 1 unaligned? |
24 | mov ip, r0 @ preserve r0 as return value | |
25 | bne 6f @ 1 | |
1da177e4 | 26 | /* |
455bd4c4 | 27 | * we know that the pointer in ip is aligned to a word boundary. |
1da177e4 | 28 | */ |
418df63a | 29 | 1: orr r1, r1, r1, lsl #8 |
1da177e4 LT |
30 | orr r1, r1, r1, lsl #16 |
31 | mov r3, r1 | |
32 | cmp r2, #16 | |
33 | blt 4f | |
f91a8dcc NP |
34 | |
35 | #if ! CALGN(1)+0 | |
36 | ||
1da177e4 | 37 | /* |
455bd4c4 | 38 | * We need 2 extra registers for this loop - use r8 and the LR |
1da177e4 | 39 | */ |
455bd4c4 | 40 | stmfd sp!, {r8, lr} |
c2459d35 LY |
41 | UNWIND( .fnend ) |
42 | UNWIND( .fnstart ) | |
43 | UNWIND( .save {r8, lr} ) | |
455bd4c4 | 44 | mov r8, r1 |
1da177e4 LT |
45 | mov lr, r1 |
46 | ||
47 | 2: subs r2, r2, #64 | |
455bd4c4 ID |
48 | stmgeia ip!, {r1, r3, r8, lr} @ 64 bytes at a time. |
49 | stmgeia ip!, {r1, r3, r8, lr} | |
50 | stmgeia ip!, {r1, r3, r8, lr} | |
51 | stmgeia ip!, {r1, r3, r8, lr} | |
1da177e4 | 52 | bgt 2b |
455bd4c4 | 53 | ldmeqfd sp!, {r8, pc} @ Now <64 bytes to go. |
1da177e4 LT |
54 | /* |
55 | * No need to correct the count; we're only testing bits from now on | |
56 | */ | |
57 | tst r2, #32 | |
455bd4c4 ID |
58 | stmneia ip!, {r1, r3, r8, lr} |
59 | stmneia ip!, {r1, r3, r8, lr} | |
1da177e4 | 60 | tst r2, #16 |
455bd4c4 ID |
61 | stmneia ip!, {r1, r3, r8, lr} |
62 | ldmfd sp!, {r8, lr} | |
c2459d35 | 63 | UNWIND( .fnend ) |
1da177e4 | 64 | |
f91a8dcc NP |
65 | #else |
66 | ||
67 | /* | |
68 | * This version aligns the destination pointer in order to write | |
69 | * whole cache lines at once. | |
70 | */ | |
71 | ||
455bd4c4 | 72 | stmfd sp!, {r4-r8, lr} |
c2459d35 LY |
73 | UNWIND( .fnend ) |
74 | UNWIND( .fnstart ) | |
75 | UNWIND( .save {r4-r8, lr} ) | |
f91a8dcc NP |
76 | mov r4, r1 |
77 | mov r5, r1 | |
78 | mov r6, r1 | |
79 | mov r7, r1 | |
455bd4c4 | 80 | mov r8, r1 |
f91a8dcc NP |
81 | mov lr, r1 |
82 | ||
83 | cmp r2, #96 | |
455bd4c4 | 84 | tstgt ip, #31 |
f91a8dcc NP |
85 | ble 3f |
86 | ||
455bd4c4 ID |
87 | and r8, ip, #31 |
88 | rsb r8, r8, #32 | |
89 | sub r2, r2, r8 | |
90 | movs r8, r8, lsl #(32 - 4) | |
91 | stmcsia ip!, {r4, r5, r6, r7} | |
92 | stmmiia ip!, {r4, r5} | |
93 | tst r8, #(1 << 30) | |
94 | mov r8, r1 | |
95 | strne r1, [ip], #4 | |
f91a8dcc NP |
96 | |
97 | 3: subs r2, r2, #64 | |
455bd4c4 ID |
98 | stmgeia ip!, {r1, r3-r8, lr} |
99 | stmgeia ip!, {r1, r3-r8, lr} | |
f91a8dcc | 100 | bgt 3b |
455bd4c4 | 101 | ldmeqfd sp!, {r4-r8, pc} |
f91a8dcc NP |
102 | |
103 | tst r2, #32 | |
455bd4c4 | 104 | stmneia ip!, {r1, r3-r8, lr} |
f91a8dcc | 105 | tst r2, #16 |
455bd4c4 ID |
106 | stmneia ip!, {r4-r7} |
107 | ldmfd sp!, {r4-r8, lr} | |
c2459d35 | 108 | UNWIND( .fnend ) |
f91a8dcc NP |
109 | |
110 | #endif | |
111 | ||
c2459d35 | 112 | UNWIND( .fnstart ) |
1da177e4 | 113 | 4: tst r2, #8 |
455bd4c4 | 114 | stmneia ip!, {r1, r3} |
1da177e4 | 115 | tst r2, #4 |
455bd4c4 | 116 | strne r1, [ip], #4 |
1da177e4 LT |
117 | /* |
118 | * When we get here, we've got less than 4 bytes to zero. We | |
119 | * may have an unaligned pointer as well. | |
120 | */ | |
121 | 5: tst r2, #2 | |
455bd4c4 ID |
122 | strneb r1, [ip], #1 |
123 | strneb r1, [ip], #1 | |
1da177e4 | 124 | tst r2, #1 |
455bd4c4 | 125 | strneb r1, [ip], #1 |
6ebbf2ce | 126 | ret lr |
418df63a NP |
127 | |
128 | 6: subs r2, r2, #4 @ 1 do we have enough | |
129 | blt 5b @ 1 bytes to align with? | |
130 | cmp r3, #2 @ 1 | |
131 | strltb r1, [ip], #1 @ 1 | |
132 | strleb r1, [ip], #1 @ 1 | |
133 | strb r1, [ip], #1 @ 1 | |
134 | add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3)) | |
135 | b 1b | |
c2459d35 | 136 | UNWIND( .fnend ) |
93ed3970 | 137 | ENDPROC(memset) |
1bd46782 | 138 | ENDPROC(mmioset) |
4dd1837d AV |
139 | EXPORT_SYMBOL(memset) |
140 | EXPORT_SYMBOL(mmioset) |