2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * @OSF_FREE_COPYRIGHT@
27 #include <ppc/proc_reg.h> /* For CACHE_LINE_SIZE */
30 * void bzero(char *addr, unsigned int length)
32 * bzero implementation for PowerPC
33 * - assumes cacheable memory (i.e. uses DCBZ)
34 * - assumes non-pic code
36 * returns start address in r3, as per memset (called by memset)
39 ENTRY(bzero, TAG_NO_FRAME_USED)
41 cmpwi cr0, r4, 0 /* no bytes to zero? */
43 mr r8, r3 /* use r8 as counter to where we are */
45 cmpwi cr0, r4, CACHE_LINE_SIZE /* clear less than a block? */
46 li r0, 0 /* use r0 as source of zeros */
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 */
65 /* clear words up to the next block boundary */
67 addis r6, 0, HIGH_CADDR(.L_bzeroBlock)
68 addi r6, r6, LOW_ADDR(.L_bzeroBlock)
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 */
87 /* clear cache blocks */
89 addi r8, r8, 4 /* remove update adjust */
90 sub r5, r8, r7 /* bytes zeroed */
92 srwi. r5, r4, CACHE_LINE_POW2 /* blocks to zero */
98 addi r8, r8, CACHE_LINE_SIZE
101 /* clear remaining words */
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 */
120 /* clear remaining bytes */
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 */
128 sub r6, r6, r5 /* back from word clear to execute */
140 * void *memset(void *from, int c, vm_size_t nbytes)
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.
148 ENTRY(memset, TAG_NO_FRAME_USED)
152 /* optimised case - do a bzero */
155 /* If count is zero, return straight away */
159 /* Now, ARG0 = addr, ARG1=len, ARG3=value */
161 subi ARG2, ARG0, 1 /* use ARG2 as our counter */
169 /* Return original address in ARG0 */