]> git.saurik.com Git - apple/xnu.git/blame - osfmk/ppc/bzero.s
xnu-344.23.tar.gz
[apple/xnu.git] / osfmk / ppc / bzero.s
CommitLineData
1c79356b 1/*
de355530 2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
1c79356b
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
de355530
A
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
1c79356b 11 *
de355530
A
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
de355530
A
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
1c79356b
A
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
de355530
A
22 /*
23 * @OSF_FREE_COPYRIGHT@
24 */
1c79356b
A
25
26#include <ppc/asm.h>
de355530
A
27#include <ppc/proc_reg.h> /* For CACHE_LINE_SIZE */
28
29/*
30 * void bzero(char *addr, unsigned int length)
31 *
32 * bzero implementation for PowerPC
33 * - assumes cacheable memory (i.e. uses DCBZ)
34 * - assumes non-pic code
35 *
36 * returns start address in r3, as per memset (called by memset)
37 */
38
39ENTRY(bzero, TAG_NO_FRAME_USED)
40
41 cmpwi cr0, r4, 0 /* no bytes to zero? */
42 mr r7, r3
43 mr r8, r3 /* use r8 as counter to where we are */
44 beqlr-
45 cmpwi cr0, r4, CACHE_LINE_SIZE /* clear less than a block? */
46 li r0, 0 /* use r0 as source of zeros */
47 blt .L_bzeroEndWord
48
49/* first, clear bytes up to the next word boundary */
50 addis r6, 0, HIGH_CADDR(.L_bzeroBeginWord)
51 addi r6, r6, LOW_ADDR(.L_bzeroBeginWord)
52 /* extract byte offset as word offset */
53 rlwinm. r5, r8, 2, 28, 29
54 addi r8, r8, -1 /* adjust for update */
55 beq .L_bzeroBeginWord /* no bytes to zero */
56 subfic r5, r5, 16 /* compute the number of instructions */
57 sub r6, r6, r5 /* back from word clear to execute */
58 mtctr r6
59 bctr
60
61 stbu r0, 1(r8)
62 stbu r0, 1(r8)
63 stbu r0, 1(r8)
64
65/* clear words up to the next block boundary */
66.L_bzeroBeginWord:
67 addis r6, 0, HIGH_CADDR(.L_bzeroBlock)
68 addi r6, r6, LOW_ADDR(.L_bzeroBlock)
69 addi r8, r8, 1
70 rlwinm. r5, r8, 0, 27, 29 /* extract word offset */
71 addi r8, r8, -4 /* adjust for update */
72 beq .L_bzeroBlock /* no words to zero */
73 /* compute the number of instructions */
74 subfic r5, r5, CACHE_LINE_SIZE
75 sub r6, r6, r5 /* back from word clear to execute */
76 mtctr r6
77 bctr
78
79 stwu r0, 4(r8)
80 stwu r0, 4(r8)
81 stwu r0, 4(r8)
82 stwu r0, 4(r8)
83 stwu r0, 4(r8)
84 stwu r0, 4(r8)
85 stwu r0, 4(r8)
86
87 /* clear cache blocks */
88.L_bzeroBlock:
89 addi r8, r8, 4 /* remove update adjust */
90 sub r5, r8, r7 /* bytes zeroed */
91 sub r4, r4, r5
92 srwi. r5, r4, CACHE_LINE_POW2 /* blocks to zero */
93 beq .L_bzeroEndWord
94 mtctr r5
95
96.L_bzeroBlock1:
97 dcbz 0, r8
98 addi r8, r8, CACHE_LINE_SIZE
99 bdnz .L_bzeroBlock1
100
101 /* clear remaining words */
102.L_bzeroEndWord:
103 addis r6, 0, HIGH_CADDR(.L_bzeroEndByte)
104 addi r6, r6, LOW_ADDR(.L_bzeroEndByte)
105 rlwinm. r5, r4, 0, 27, 29 /* extract word offset */
106 addi r8, r8, -4 /* adjust for update */
107 beq .L_bzeroEndByte /* no words to zero */
108 sub r6, r6, r5 /* back from word clear to execute */
109 mtctr r6
110 bctr
111
112 stwu r0, 4(r8)
113 stwu r0, 4(r8)
114 stwu r0, 4(r8)
115 stwu r0, 4(r8)
116 stwu r0, 4(r8)
117 stwu r0, 4(r8)
118 stwu r0, 4(r8)
119
120 /* clear remaining bytes */
121.L_bzeroEndByte:
122 addis r6, 0, HIGH_CADDR(.L_bzeroEnd)
123 addi r6, r6, LOW_ADDR(.L_bzeroEnd)
124 /* extract byte offset as word offset */
125 rlwinm. r5, r4, 2, 28, 29
126 addi r8, r8, 3 /* adjust for update */
127 beqlr
128 sub r6, r6, r5 /* back from word clear to execute */
129 mtctr r6
130 bctr
131
132 stbu r0, 1(r8)
133 stbu r0, 1(r8)
134 stbu r0, 1(r8)
135
136.L_bzeroEnd:
137 blr
138
139/*
140 * void *memset(void *from, int c, vm_size_t nbytes)
141 *
142 * almost everywhere in the kernel
143 * this appears to be called with argument c==0. We optimise for those
144 * cases and call bzero if we can.
145 *
146 */
147
148ENTRY(memset, TAG_NO_FRAME_USED)
149
150 mr. ARG3, ARG1
151 mr ARG1, ARG2
152 /* optimised case - do a bzero */
153 beq+ EXT(bzero)
154
155 /* If count is zero, return straight away */
156 cmpi cr0, ARG1, 0
157 beqlr-
158
159 /* Now, ARG0 = addr, ARG1=len, ARG3=value */
160
161 subi ARG2, ARG0, 1 /* use ARG2 as our counter */
162
1630:
164 subi ARG1, ARG1, 1
165 cmpi cr0, ARG1, 0
166 stbu ARG3, 1(ARG2)
167 bne+ 0b
168
169 /* Return original address in ARG0 */
170
171 blr
172
173/*
174 * void bzero_nc(char *addr, unsigned int length)
175 *
176 * bzero implementation for PowerPC
177 * - assumes non-pic code
178 *
179 * returns start address in r3, as per memset (called by memset)
180 */
181
182ENTRY(bzero_nc, TAG_NO_FRAME_USED)
183
184 cmpwi cr0, r4, 0 /* no bytes to zero? */
185 mr r7, r3
186 mr r8, r3 /* use r8 as counter to where we are */
187 beqlr-
188 cmpwi cr0, r4, CACHE_LINE_SIZE /* clear less than a block? */
189 li r0, 0 /* use r0 as source of zeros */
190 blt .L_bzeroNCEndWord
191
192/* first, clear bytes up to the next word boundary */
193 addis r6, 0, HIGH_CADDR(.L_bzeroNCBeginWord)
194 addi r6, r6, LOW_ADDR(.L_bzeroNCBeginWord)
195 /* extract byte offset as word offset */
196 rlwinm. r5, r8, 2, 28, 29
197 addi r8, r8, -1 /* adjust for update */
198 beq .L_bzeroNCBeginWord /* no bytes to zero */
199 subfic r5, r5, 16 /* compute the number of instructions */
200 sub r6, r6, r5 /* back from word clear to execute */
201 mtctr r6
202 bctr
203
204 stbu r0, 1(r8)
205 stbu r0, 1(r8)
206 stbu r0, 1(r8)
207
208/* clear words up to the next block boundary */
209.L_bzeroNCBeginWord:
210 addis r6, 0, HIGH_CADDR(.L_bzeroNCBlock)
211 addi r6, r6, LOW_ADDR(.L_bzeroNCBlock)
212 addi r8, r8, 1
213 rlwinm. r5, r8, 0, 27, 29 /* extract word offset */
214 addi r8, r8, -4 /* adjust for update */
215 beq .L_bzeroNCBlock /* no words to zero */
216 /* compute the number of instructions */
217 subfic r5, r5, CACHE_LINE_SIZE
218 sub r6, r6, r5 /* back from word clear to execute */
219 mtctr r6
220 bctr
221
222 stwu r0, 4(r8)
223 stwu r0, 4(r8)
224 stwu r0, 4(r8)
225 stwu r0, 4(r8)
226 stwu r0, 4(r8)
227 stwu r0, 4(r8)
228 stwu r0, 4(r8)
229
230 /* clear cache blocks */
231.L_bzeroNCBlock:
232 addi r8, r8, 4 /* remove update adjust */
233 sub r5, r8, r7 /* bytes zeroed */
234 sub r4, r4, r5
235 srwi. r5, r4, CACHE_LINE_POW2 /* blocks to zero */
236 beq .L_bzeroNCEndWord
237 mtctr r5
238
239.L_bzeroNCBlock1:
240 stw r0, 0(r8)
241 stw r0, 4(r8)
242 stw r0, 8(r8)
243 stw r0, 12(r8)
244 stw r0, 16(r8)
245 stw r0, 20(r8)
246 stw r0, 24(r8)
247 stw r0, 28(r8)
248 addi r8, r8, CACHE_LINE_SIZE
249 bdnz .L_bzeroNCBlock1
250
251 /* clear remaining words */
252.L_bzeroNCEndWord:
253 addis r6, 0, HIGH_CADDR(.L_bzeroNCEndByte)
254 addi r6, r6, LOW_ADDR(.L_bzeroNCEndByte)
255 rlwinm. r5, r4, 0, 27, 29 /* extract word offset */
256 addi r8, r8, -4 /* adjust for update */
257 beq .L_bzeroNCEndByte /* no words to zero */
258 sub r6, r6, r5 /* back from word clear to execute */
259 mtctr r6
260 bctr
261
262 stwu r0, 4(r8)
263 stwu r0, 4(r8)
264 stwu r0, 4(r8)
265 stwu r0, 4(r8)
266 stwu r0, 4(r8)
267 stwu r0, 4(r8)
268 stwu r0, 4(r8)
269
270 /* clear remaining bytes */
271.L_bzeroNCEndByte:
272 addis r6, 0, HIGH_CADDR(.L_bzeroNCEnd)
273 addi r6, r6, LOW_ADDR(.L_bzeroNCEnd)
274 /* extract byte offset as word offset */
275 rlwinm. r5, r4, 2, 28, 29
276 addi r8, r8, 3 /* adjust for update */
277 beqlr
278 sub r6, r6, r5 /* back from word clear to execute */
279 mtctr r6
280 bctr
281
282 stbu r0, 1(r8)
283 stbu r0, 1(r8)
284 stbu r0, 1(r8)
9bccf70c 285
de355530
A
286.L_bzeroNCEnd:
287 blr