|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
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.
11: *
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
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * @OSF_FREE_COPYRIGHT@
24: */
25:
26: #include <ppc/asm.h>
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:
39: ENTRY(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:
148: ENTRY(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:
163: 0:
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.