| @@ -1,375 +1,378 @@ | | | @@ -1,375 +1,378 @@ |
1 | /* $NetBSD: bzero.S,v 1.9 2011/01/16 02:43:10 matt Exp $ */ | | 1 | /* $NetBSD: bzero.S,v 1.10 2011/01/19 02:47:01 matt Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (C) 2001 Martin J. Laubach <mjl@NetBSD.org> | | 4 | * Copyright (C) 2001 Martin J. Laubach <mjl@NetBSD.org> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
15 | * 3. The name of the author may not be used to endorse or promote products | | 15 | * 3. The name of the author may not be used to endorse or promote products |
16 | * derived from this software without specific prior written permission. | | 16 | * derived from this software without specific prior written permission. |
17 | * | | 17 | * |
18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | | 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 27 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | */ | | 28 | */ |
29 | /*----------------------------------------------------------------------*/ | | 29 | /*----------------------------------------------------------------------*/ |
30 | | | 30 | |
31 | #include <machine/asm.h> | | 31 | #include <machine/asm.h> |
32 | | | 32 | |
33 | | | 33 | |
34 | #if defined(LIBC_SCCS) && !defined(lint) | | 34 | #if defined(LIBC_SCCS) && !defined(lint) |
35 | __RCSID("$NetBSD: bzero.S,v 1.9 2011/01/16 02:43:10 matt Exp $") | | 35 | __RCSID("$NetBSD: bzero.S,v 1.10 2011/01/19 02:47:01 matt Exp $") |
36 | #endif /* LIBC_SCCS && !lint */ | | 36 | #endif /* LIBC_SCCS && !lint */ |
37 | | | 37 | |
38 | #ifdef _KERNEL | | 38 | #ifdef _KERNEL |
39 | #include <assym.h> | | 39 | #include <assym.h> |
40 | #endif | | 40 | #endif |
41 | | | 41 | |
42 | #define USE_STSWX 0 /* don't. slower than trivial copy loop */ | | 42 | #define USE_STSWX 0 /* don't. slower than trivial copy loop */ |
43 | | | 43 | |
44 | /*----------------------------------------------------------------------*/ | | 44 | /*----------------------------------------------------------------------*/ |
45 | /* | | 45 | /* |
46 | void bzero(void *b %r3, size_t len %r4); | | 46 | void bzero(void *b %r3, size_t len %r4); |
47 | void * memset(void *b %r3, int c %r4, size_t len %r5); | | 47 | void * memset(void *b %r3, int c %r4, size_t len %r5); |
48 | */ | | 48 | */ |
49 | /*----------------------------------------------------------------------*/ | | 49 | /*----------------------------------------------------------------------*/ |
50 | | | 50 | |
51 | #define r_dst %r3 | | 51 | #define r_dst %r3 |
52 | #define r_len %r4 | | 52 | #define r_len %r4 |
53 | #define r_val %r0 | | 53 | #define r_val %r0 |
54 | | | 54 | |
55 | .text | | 55 | .text |
56 | .align 4 | | 56 | .align 4 |
57 | ENTRY(bzero) | | 57 | ENTRY(bzero) |
58 | li r_val, 0 /* Value to stuff in */ | | 58 | li r_val, 0 /* Value to stuff in */ |
59 | b cb_memset | | 59 | b cb_memset |
60 | END(bzero) | | 60 | END(bzero) |
61 | | | 61 | |
62 | ENTRY(memset) | | 62 | ENTRY(memset) |
63 | cmplwi cr1, %r5, 0 | | 63 | cmplwi cr1, %r5, 0 |
64 | mr. %r0, %r4 | | 64 | mr. %r0, %r4 |
65 | mr %r8, %r3 | | 65 | mr %r8, %r3 |
66 | beqlr- cr1 /* Nothing to do */ | | 66 | beqlr- cr1 /* Nothing to do */ |
67 | | | 67 | |
68 | rlwimi %r0, %r4, 8, 16, 23 /* word extend fill value */ | | 68 | rlwimi %r0, %r4, 8, 16, 23 /* word extend fill value */ |
69 | rlwimi %r0, %r0, 16, 0, 15 | | 69 | rlwimi %r0, %r0, 16, 0, 15 |
70 | mr %r4, %r5 | | 70 | mr %r4, %r5 |
71 | bne- simple_fill /* =! 0, use trivial fill */ | | 71 | bne- simple_fill /* =! 0, use trivial fill */ |
72 | cb_memset: | | 72 | cb_memset: |
73 | | | 73 | |
74 | /*----------------------------------------------------------------------*/ | | 74 | /*----------------------------------------------------------------------*/ |
75 | #ifndef _KERNEL | | 75 | #ifndef _KERNEL |
76 | /* First find out cache line size */ | | 76 | /* First find out cache line size */ |
77 | #ifdef PIC | | | |
78 | mflr %r9 | | 77 | mflr %r9 |
| | | 78 | #ifdef PIC |
79 | PIC_GOTSETUP(%r10) | | 79 | PIC_GOTSETUP(%r10) |
80 | mtlr %r9 | | 80 | mtlr %r9 |
81 | lwz %r5,cache_info@got(%r10) | | 81 | lwz %r5,cache_info@got(%r10) |
82 | #else | | 82 | #else |
83 | lis %r5,cache_info@h | | 83 | lis %r5,cache_info@h |
84 | ori %r5,%r5,cache_info@l | | 84 | ori %r5,%r5,cache_info@l |
85 | #endif | | 85 | #endif |
86 | lwz %r6, 4(%r5) | | 86 | lwz %r6, 4(%r5) |
87 | cmpwi %r6, -1 | | 87 | cmpwi %r6, -1 |
88 | bne+ cb_cacheline_known | | 88 | bne+ cb_cacheline_known |
89 | | | 89 | |
90 | /*----------------------------------------------------------------------*/ | | 90 | /*----------------------------------------------------------------------*/ |
91 | #define CTL_MACHDEP 7 | | 91 | #define CTL_MACHDEP 7 |
92 | #define CPU_CACHELINE 1 | | 92 | #define CPU_CACHELINE 1 |
93 | #define CPU_CACHEINFO 5 | | 93 | #define CPU_CACHEINFO 5 |
94 | | | 94 | |
95 | #define STKFRAME_SZ 64 | | 95 | #define STKFRAME_SZ 64 |
96 | #define MIB 8 | | 96 | #define MIB 8 |
97 | #define OLDPLEN 16 | | 97 | #define OLDPLEN 16 |
98 | #define R3_SAVE 20 | | 98 | #define R3_SAVE 20 |
99 | #define R4_SAVE 24 | | 99 | #define R4_SAVE 24 |
100 | #define R0_SAVE 28 | | 100 | #define R0_SAVE 28 |
101 | #define R8_SAVE 32 | | 101 | #define R8_SAVE 32 |
102 | #define R31_SAVE 36 | | 102 | #define R31_SAVE 36 |
103 | #ifdef PIC | | 103 | #ifdef PIC |
104 | #define R30_SAVE 40 | | 104 | #define R30_SAVE 40 |
105 | #endif | | 105 | #endif |
106 | | | 106 | |
107 | stw %r9, 4(%r1) | | 107 | stw %r9, 4(%r1) |
108 | stwu %r1, -STKFRAME_SZ(%r1) | | 108 | stwu %r1, -STKFRAME_SZ(%r1) |
109 | | | 109 | |
110 | stw %r31, R31_SAVE(%r1) | | 110 | stw %r31, R31_SAVE(%r1) |
111 | mr %r31, %r5 /* cache info */ | | 111 | mr %r31, %r5 /* cache info */ |
112 | | | 112 | |
113 | #ifdef PIC | | 113 | #ifdef PIC |
114 | stw %r30, R30_SAVE(%r1) | | 114 | stw %r30, R30_SAVE(%r1) |
115 | PIC_TOCSETUP(cb_memset,%r30) | | 115 | PIC_TOCSETUP(cb_memset,%r30) |
116 | #endif | | 116 | #endif |
117 | | | 117 | |
118 | stw %r8, R8_SAVE(%r1) | | 118 | stw %r8, R8_SAVE(%r1) |
119 | stw %r3, R3_SAVE(%r1) | | 119 | stw %r3, R3_SAVE(%r1) |
120 | stw %r4, R4_SAVE(%r1) | | 120 | stw %r4, R4_SAVE(%r1) |
121 | stw %r0, R0_SAVE(%r1) | | 121 | stw %r0, R0_SAVE(%r1) |
122 | | | 122 | |
123 | li %r0, CTL_MACHDEP /* Construct MIB */ | | 123 | li %r0, CTL_MACHDEP /* Construct MIB */ |
124 | stw %r0, MIB(%r1) | | 124 | stw %r0, MIB(%r1) |
125 | li %r0, CPU_CACHEINFO | | 125 | li %r0, CPU_CACHEINFO |
126 | stw %r0, MIB+4(%r1) | | 126 | stw %r0, MIB+4(%r1) |
127 | | | 127 | |
128 | li %r0, 4*4 /* Oldlenp := 4*4 */ | | 128 | li %r0, 4*4 /* Oldlenp := 4*4 */ |
129 | stw %r0, OLDPLEN(%r1) | | 129 | stw %r0, OLDPLEN(%r1) |
130 | | | 130 | |
131 | addi %r3, %r1, MIB | | 131 | addi %r3, %r1, MIB |
132 | li %r4, 2 /* namelen */ | | 132 | li %r4, 2 /* namelen */ |
133 | /* %r5 already contains &cache_info */ | | 133 | /* %r5 already contains &cache_info */ |
134 | addi %r6, %r1, OLDPLEN | | 134 | addi %r6, %r1, OLDPLEN |
135 | li %r7, 0 | | 135 | li %r7, 0 |
136 | li %r8, 0 | | 136 | li %r8, 0 |
137 | bl PIC_PLT(_C_LABEL(sysctl)) | | 137 | bl PIC_PLT(_C_LABEL(sysctl)) |
138 | | | 138 | |
139 | cmpwi %r3, 0 /* Check result */ | | 139 | cmpwi %r3, 0 /* Check result */ |
140 | beq 1f | | 140 | beq 1f |
141 | | | 141 | |
142 | /* Failure, try older sysctl */ | | 142 | /* Failure, try older sysctl */ |
143 | | | 143 | |
144 | li %r0, CTL_MACHDEP /* Construct MIB */ | | 144 | li %r0, CTL_MACHDEP /* Construct MIB */ |
145 | stw %r0, MIB(%r1) | | 145 | stw %r0, MIB(%r1) |
146 | li %r0, CPU_CACHELINE | | 146 | li %r0, CPU_CACHELINE |
147 | stw %r0, MIB+4(%r1) | | 147 | stw %r0, MIB+4(%r1) |
148 | | | 148 | |
149 | li %r0, 4 /* Oldlenp := 4 */ | | 149 | li %r0, 4 /* Oldlenp := 4 */ |
150 | stw %r0, OLDPLEN(%r1) | | 150 | stw %r0, OLDPLEN(%r1) |
151 | | | 151 | |
152 | addi %r3, %r1, MIB | | 152 | addi %r3, %r1, MIB |
153 | li %r4, 2 /* namelen */ | | 153 | li %r4, 2 /* namelen */ |
154 | addi %r5, %r31, 4 | | 154 | addi %r5, %r31, 4 |
155 | addi %r6, %r1, OLDPLEN | | 155 | addi %r6, %r1, OLDPLEN |
156 | li %r7, 0 | | 156 | li %r7, 0 |
157 | li %r8, 0 | | 157 | li %r8, 0 |
158 | bl PIC_PLT(_C_LABEL(sysctl)) | | 158 | bl PIC_PLT(_C_LABEL(sysctl)) |
159 | 1: | | 159 | 1: |
160 | lwz %r8, R8_SAVE(%r1) | | | |
161 | lwz %r3, R3_SAVE(%r1) | | 160 | lwz %r3, R3_SAVE(%r1) |
162 | lwz %r4, R4_SAVE(%r1) | | 161 | lwz %r4, R4_SAVE(%r1) |
| | | 162 | lwz %r8, R8_SAVE(%r1) |
163 | lwz %r0, R0_SAVE(%r1) | | 163 | lwz %r0, R0_SAVE(%r1) |
164 | lwz %r9, 4(%r31) | | 164 | lwz %r9, 4(%r31) |
165 | lwz %r31, R31_SAVE(%r1) | | 165 | lwz %r31, R31_SAVE(%r1) |
166 | #ifdef PIC | | 166 | #ifdef PIC |
167 | lwz %r30, R30_SAVE(%r1) | | 167 | lwz %r30, R30_SAVE(%r1) |
168 | #endif | | 168 | #endif |
169 | la %r1, STKFRAME_SZ(%r1) | | 169 | addi %r1, %r1, STKFRAME_SZ |
170 | lwz %r5, 4(%r1) | | 170 | lwz %r0, 4(%r1) |
171 | mtlr %r5 | | 171 | mtlr %r0 |
172 | | | 172 | |
173 | cntlzw %r6, %r9 /* compute shift value */ | | 173 | cntlzw %r6, %r9 /* compute shift value */ |
174 | li %r5, 31 | | 174 | li %r5, 31 |
175 | subf %r5, %r6, %r5 | | 175 | subf %r5, %r6, %r5 |
176 | | | 176 | |
177 | #ifdef PIC | | 177 | #ifdef PIC |
| | | 178 | mflr %r9 |
| | | 179 | PIC_GOTSETUP(%r10) |
| | | 180 | mtlr %r9 |
178 | lwz %r6, cache_sh@got(%r10) | | 181 | lwz %r6, cache_sh@got(%r10) |
179 | stw %r5, 0(%r6) | | 182 | stw %r5, 0(%r6) |
180 | #else | | 183 | #else |
181 | lis %r6, cache_sh@ha | | 184 | lis %r6, cache_sh@ha |
182 | stw %r5, cache_sh@l(%r6) | | 185 | stw %r5, cache_sh@l(%r6) |
183 | #endif | | 186 | #endif |
184 | /*----------------------------------------------------------------------*/ | | 187 | /*----------------------------------------------------------------------*/ |
185 | /* Okay, we know the cache line size (%r9) and shift value (%r10) */ | | 188 | /* Okay, we know the cache line size (%r9) and shift value (%r10) */ |
186 | cb_cacheline_known: | | 189 | cb_cacheline_known: |
187 | #ifdef PIC | | 190 | #ifdef PIC |
188 | lwz %r5, cache_info@got(%r10) | | 191 | lwz %r5, cache_info@got(%r10) |
189 | lwz %r9, 4(%r5) | | 192 | lwz %r9, 4(%r5) |
190 | lwz %r5, cache_sh@got(%r10) | | 193 | lwz %r5, cache_sh@got(%r10) |
191 | lwz %r10, 0(%r5) | | 194 | lwz %r10, 0(%r5) |
192 | #else | | 195 | #else |
193 | lis %r9, cache_info+4@ha | | 196 | lis %r9, cache_info+4@ha |
194 | lwz %r9, cache_info+4@l(%r9) | | 197 | lwz %r9, cache_info+4@l(%r9) |
195 | lis %r10, cache_sh@ha | | 198 | lis %r10, cache_sh@ha |
196 | lwz %r10, cache_sh@l(%r10) | | 199 | lwz %r10, cache_sh@l(%r10) |
197 | #endif | | 200 | #endif |
198 | | | 201 | |
199 | #else /* _KERNEL */ | | 202 | #else /* _KERNEL */ |
200 | #ifdef MULTIPROCESSOR | | 203 | #ifdef MULTIPROCESSOR |
201 | mfsprg %r10, 0 /* Get cpu_info pointer */ | | 204 | mfsprg %r10, 0 /* Get cpu_info pointer */ |
202 | #else | | 205 | #else |
203 | lis %r10, cpu_info_store@ha | | 206 | lis %r10, cpu_info_store@ha |
204 | addi %r10, %r10, cpu_info_store@l | | 207 | addi %r10, %r10, cpu_info_store@l |
205 | #endif | | 208 | #endif |
206 | lwz %r9, CPU_CI+4(%r10) /* Load D$ line size */ | | 209 | lwz %r9, CPU_CI+4(%r10) /* Load D$ line size */ |
207 | cntlzw %r10, %r9 /* Calculate shift.. */ | | 210 | cntlzw %r10, %r9 /* Calculate shift.. */ |
208 | li %r6, 31 | | 211 | li %r6, 31 |
209 | subf %r10, %r10, %r6 | | 212 | subf %r10, %r10, %r6 |
210 | #endif /* _KERNEL */ | | 213 | #endif /* _KERNEL */ |
211 | /* Back in memory filling business */ | | 214 | /* Back in memory filling business */ |
212 | | | 215 | |
213 | cmplwi cr1, r_len, 0 /* Nothing to do? */ | | 216 | cmplwi cr1, r_len, 0 /* Nothing to do? */ |
214 | add %r5, %r9, %r9 | | 217 | add %r5, %r9, %r9 |
215 | cmplw r_len, %r5 /* <= 2*CL bytes to move? */ | | 218 | cmplw r_len, %r5 /* <= 2*CL bytes to move? */ |
216 | beqlr- cr1 /* then do nothing */ | | 219 | beqlr- cr1 /* then do nothing */ |
217 | | | 220 | |
218 | blt+ simple_fill /* a trivial fill routine */ | | 221 | blt+ simple_fill /* a trivial fill routine */ |
219 | | | 222 | |
220 | /* Word align the block, fill bytewise until dst even*/ | | 223 | /* Word align the block, fill bytewise until dst even*/ |
221 | | | 224 | |
222 | andi. %r5, r_dst, 0x03 | | 225 | andi. %r5, r_dst, 0x03 |
223 | li %r6, 4 | | 226 | li %r6, 4 |
224 | beq+ cb_aligned_w /* already aligned to word? */ | | 227 | beq+ cb_aligned_w /* already aligned to word? */ |
225 | | | 228 | |
226 | subf %r5, %r5, %r6 /* bytes to fill to align4 */ | | 229 | subf %r5, %r5, %r6 /* bytes to fill to align4 */ |
227 | #if USE_STSWX | | 230 | #if USE_STSWX |
228 | mtxer %r5 | | 231 | mtxer %r5 |
229 | stswx %r0, 0, r_dst | | 232 | stswx %r0, 0, r_dst |
230 | add r_dst, %r5, r_dst | | 233 | add r_dst, %r5, r_dst |
231 | #else | | 234 | #else |
232 | mtctr %r5 | | 235 | mtctr %r5 |
233 | | | 236 | |
234 | subi r_dst, r_dst, 1 | | 237 | subi r_dst, r_dst, 1 |
235 | 1: stbu r_val, 1(r_dst) /* Fill bytewise */ | | 238 | 1: stbu r_val, 1(r_dst) /* Fill bytewise */ |
236 | bdnz 1b | | 239 | bdnz 1b |
237 | | | 240 | |
238 | addi r_dst, r_dst, 1 | | 241 | addi r_dst, r_dst, 1 |
239 | #endif | | 242 | #endif |
240 | subf r_len, %r5, r_len | | 243 | subf r_len, %r5, r_len |
241 | | | 244 | |
242 | cb_aligned_w: /* Cache block align, fill wordwise until dst aligned */ | | 245 | cb_aligned_w: /* Cache block align, fill wordwise until dst aligned */ |
243 | | | 246 | |
244 | /* I know I have something to do since we had > 2*CL initially */ | | 247 | /* I know I have something to do since we had > 2*CL initially */ |
245 | /* so no need to check for r_len = 0 */ | | 248 | /* so no need to check for r_len = 0 */ |
246 | | | 249 | |
247 | subi %r6, %r9, 1 /* CL mask */ | | 250 | subi %r6, %r9, 1 /* CL mask */ |
248 | and. %r5, r_dst, %r6 | | 251 | and. %r5, r_dst, %r6 |
249 | srwi %r5, %r5, 2 | | 252 | srwi %r5, %r5, 2 |
250 | srwi %r6, %r9, 2 | | 253 | srwi %r6, %r9, 2 |
251 | beq cb_aligned_cb /* already on CL boundary? */ | | 254 | beq cb_aligned_cb /* already on CL boundary? */ |
252 | | | 255 | |
253 | subf %r5, %r5, %r6 /* words to fill to alignment */ | | 256 | subf %r5, %r5, %r6 /* words to fill to alignment */ |
254 | mtctr %r5 | | 257 | mtctr %r5 |
255 | slwi %r5, %r5, 2 | | 258 | slwi %r5, %r5, 2 |
256 | subf r_len, %r5, r_len | | 259 | subf r_len, %r5, r_len |
257 | | | 260 | |
258 | subi r_dst, r_dst, 4 | | 261 | subi r_dst, r_dst, 4 |
259 | 1: stwu r_val, 4(r_dst) /* Fill wordwise */ | | 262 | 1: stwu r_val, 4(r_dst) /* Fill wordwise */ |
260 | bdnz 1b | | 263 | bdnz 1b |
261 | addi r_dst, r_dst, 4 | | 264 | addi r_dst, r_dst, 4 |
262 | | | 265 | |
263 | cb_aligned_cb: /* no need to check r_len, see above */ | | 266 | cb_aligned_cb: /* no need to check r_len, see above */ |
264 | | | 267 | |
265 | srw. %r5, r_len, %r10 /* Number of cache blocks */ | | 268 | srw. %r5, r_len, %r10 /* Number of cache blocks */ |
266 | mtctr %r5 | | 269 | mtctr %r5 |
267 | beq cblocks_done | | 270 | beq cblocks_done |
268 | | | 271 | |
269 | slw %r5, %r5, %r10 | | 272 | slw %r5, %r5, %r10 |
270 | subf r_len, %r5, r_len | | 273 | subf r_len, %r5, r_len |
271 | | | 274 | |
272 | 1: dcbz 0, r_dst /* Clear blockwise */ | | 275 | 1: dcbz 0, r_dst /* Clear blockwise */ |
273 | add r_dst, r_dst, %r9 | | 276 | add r_dst, r_dst, %r9 |
274 | bdnz 1b | | 277 | bdnz 1b |
275 | | | 278 | |
276 | cblocks_done: /* still CL aligned, but less than CL bytes left */ | | 279 | cblocks_done: /* still CL aligned, but less than CL bytes left */ |
277 | cmplwi cr1, r_len, 0 | | 280 | cmplwi cr1, r_len, 0 |
278 | cmplwi r_len, 8 | | 281 | cmplwi r_len, 8 |
279 | beq- cr1, sf_return | | 282 | beq- cr1, sf_return |
280 | | | 283 | |
281 | blt- sf_bytewise /* <8 remaining? */ | | 284 | blt- sf_bytewise /* <8 remaining? */ |
282 | b sf_aligned_w | | 285 | b sf_aligned_w |
283 | | | 286 | |
284 | /*----------------------------------------------------------------------*/ | | 287 | /*----------------------------------------------------------------------*/ |
285 | wbzero: li r_val, 0 | | 288 | wbzero: li r_val, 0 |
286 | | | 289 | |
287 | cmplwi r_len, 0 | | 290 | cmplwi r_len, 0 |
288 | beqlr- /* Nothing to do */ | | 291 | beqlr- /* Nothing to do */ |
289 | | | 292 | |
290 | simple_fill: | | 293 | simple_fill: |
291 | #if USE_STSWX | | 294 | #if USE_STSWX |
292 | cmplwi cr1, r_len, 12 /* < 12 bytes to move? */ | | 295 | cmplwi cr1, r_len, 12 /* < 12 bytes to move? */ |
293 | #else | | 296 | #else |
294 | cmplwi cr1, r_len, 8 /* < 8 bytes to move? */ | | 297 | cmplwi cr1, r_len, 8 /* < 8 bytes to move? */ |
295 | #endif | | 298 | #endif |
296 | andi. %r5, r_dst, 0x03 /* bytes to fill to align4 */ | | 299 | andi. %r5, r_dst, 0x03 /* bytes to fill to align4 */ |
297 | blt cr1, sf_bytewise /* trivial byte mover */ | | 300 | blt cr1, sf_bytewise /* trivial byte mover */ |
298 | | | 301 | |
299 | li %r6, 4 | | 302 | li %r6, 4 |
300 | subf %r5, %r5, %r6 | | 303 | subf %r5, %r5, %r6 |
301 | beq+ sf_aligned_w /* dest is word aligned */ | | 304 | beq+ sf_aligned_w /* dest is word aligned */ |
302 | | | 305 | |
303 | #if USE_STSWX | | 306 | #if USE_STSWX |
304 | mtxer %r5 | | 307 | mtxer %r5 |
305 | stswx %r0, 0, r_dst | | 308 | stswx %r0, 0, r_dst |
306 | add r_dst, %r5, r_dst | | 309 | add r_dst, %r5, r_dst |
307 | #else | | 310 | #else |
308 | mtctr %r5 /* nope, then fill bytewise */ | | 311 | mtctr %r5 /* nope, then fill bytewise */ |
309 | subi r_dst, r_dst, 1 /* until it is */ | | 312 | subi r_dst, r_dst, 1 /* until it is */ |
310 | 1: stbu r_val, 1(r_dst) | | 313 | 1: stbu r_val, 1(r_dst) |
311 | bdnz 1b | | 314 | bdnz 1b |
312 | | | 315 | |
313 | addi r_dst, r_dst, 1 | | 316 | addi r_dst, r_dst, 1 |
314 | #endif | | 317 | #endif |
315 | subf r_len, %r5, r_len | | 318 | subf r_len, %r5, r_len |
316 | | | 319 | |
317 | sf_aligned_w: /* no need to check r_len since it were >= 8 bytes initially */ | | 320 | sf_aligned_w: /* no need to check r_len since it were >= 8 bytes initially */ |
318 | #if USE_STSWX | | 321 | #if USE_STSWX |
319 | mr %r6, %r0 | | 322 | mr %r6, %r0 |
320 | mr %r7, %r0 | | 323 | mr %r7, %r0 |
321 | | | 324 | |
322 | srwi %r5, r_len, 3 | | 325 | srwi %r5, r_len, 3 |
323 | mtctr %r5 | | 326 | mtctr %r5 |
324 | | | 327 | |
325 | slwi %r5, %r5, 3 /* adjust len */ | | 328 | slwi %r5, %r5, 3 /* adjust len */ |
326 | subf. r_len, %r5, r_len | | 329 | subf. r_len, %r5, r_len |
327 | | | 330 | |
328 | 1: stswi %r6, r_dst, 8 | | 331 | 1: stswi %r6, r_dst, 8 |
329 | addi r_dst, r_dst, 8 | | 332 | addi r_dst, r_dst, 8 |
330 | bdnz 1b | | 333 | bdnz 1b |
331 | #else | | 334 | #else |
332 | srwi %r5, r_len, 2 /* words to fill */ | | 335 | srwi %r5, r_len, 2 /* words to fill */ |
333 | mtctr %r5 | | 336 | mtctr %r5 |
334 | | | 337 | |
335 | slwi %r5, %r5, 2 | | 338 | slwi %r5, %r5, 2 |
336 | subf. r_len, %r5, r_len /* adjust len for fill */ | | 339 | subf. r_len, %r5, r_len /* adjust len for fill */ |
337 | | | 340 | |
338 | subi r_dst, r_dst, 4 | | 341 | subi r_dst, r_dst, 4 |
339 | 1: stwu r_val, 4(r_dst) | | 342 | 1: stwu r_val, 4(r_dst) |
340 | bdnz 1b | | 343 | bdnz 1b |
341 | addi r_dst, r_dst, 4 | | 344 | addi r_dst, r_dst, 4 |
342 | #endif | | 345 | #endif |
343 | | | 346 | |
344 | sf_word_done: bne- sf_bytewise | | 347 | sf_word_done: bne- sf_bytewise |
345 | | | 348 | |
346 | sf_return: mr %r3, %r8 /* restore orig ptr */ | | 349 | sf_return: mr %r3, %r8 /* restore orig ptr */ |
347 | blr /* for memset functionality */ | | 350 | blr /* for memset functionality */ |
348 | | | 351 | |
349 | sf_bytewise: | | 352 | sf_bytewise: |
350 | #if USE_STSWX | | 353 | #if USE_STSWX |
351 | mr %r5, %r0 | | 354 | mr %r5, %r0 |
352 | mr %r6, %r0 | | 355 | mr %r6, %r0 |
353 | mr %r7, %r0 | | 356 | mr %r7, %r0 |
354 | | | 357 | |
355 | mtxer r_len | | 358 | mtxer r_len |
356 | stswx %r5, 0, r_dst | | 359 | stswx %r5, 0, r_dst |
357 | #else | | 360 | #else |
358 | mtctr r_len | | 361 | mtctr r_len |
359 | | | 362 | |
360 | subi r_dst, r_dst, 1 | | 363 | subi r_dst, r_dst, 1 |
361 | 1: stbu r_val, 1(r_dst) | | 364 | 1: stbu r_val, 1(r_dst) |
362 | bdnz 1b | | 365 | bdnz 1b |
363 | #endif | | 366 | #endif |
364 | mr %r3, %r8 /* restore orig ptr */ | | 367 | mr %r3, %r8 /* restore orig ptr */ |
365 | blr /* for memset functionality */ | | 368 | blr /* for memset functionality */ |
366 | END(memset) | | 369 | END(memset) |
367 | | | 370 | |
368 | /*----------------------------------------------------------------------*/ | | 371 | /*----------------------------------------------------------------------*/ |
369 | #ifndef _KERNEL | | 372 | #ifndef _KERNEL |
370 | .data | | 373 | .data |
371 | cache_info: .long -1, -1, -1, -1 | | 374 | cache_info: .long -1, -1, -1, -1 |
372 | cache_sh: .long 0 | | 375 | cache_sh: .long 0 |
373 | | | 376 | |
374 | #endif | | 377 | #endif |
375 | /*----------------------------------------------------------------------*/ | | 378 | /*----------------------------------------------------------------------*/ |