Annotation of sys/lib/libkern/arch/m88k/bzero.S, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: bzero.S,v 1.1 2006/11/17 22:32:38 miod Exp $ */
2: /*
3: * Mach Operating System
4: * Copyright (c) 1993-1992 Carnegie Mellon University
5: * Copyright (c) 1991 OMRON Corporation
6: * Copyright (c) 1996 Nivas Madhur
7: * Copyright (c) 1998 Steve Murphree, Jr.
8: * All Rights Reserved.
9: *
10: * Permission to use, copy, modify and distribute this software and its
11: * documentation is hereby granted, provided that both the copyright
12: * notice and this permission notice appear in all copies of the
13: * software, derivative works or modified versions, and any portions
14: * thereof, and that both notices appear in supporting documentation.
15: *
16: * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17: * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
18: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19: *
20: * Carnegie Mellon requests users of this software to return to
21: *
22: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23: * School of Computer Science
24: * Carnegie Mellon University
25: * Pittsburgh PA 15213-3890
26: *
27: * any improvements or extensions that they make and grant Carnegie the
28: * rights to redistribute these changes.
29: */
30:
31: #include <machine/asm.h>
32:
33: /*######################################################################*/
34:
35: /*
36: * April 1990, Omron Corporation
37: * jfriedl@nff.ncl.omron.co.jp
38: *
39: * void bzero(destination, length)
40: *
41: * Clear (set to zero) LENGTH bytes of memory starting at DESTINATION.
42: * Note that there is no return value.
43: *
44: * This is fast. Really fast. Especially for long lengths.
45: */
46: #define R_dest r2
47: #define R_len r3
48:
49: #define R_bytes r4
50: #define R_mark_address r5
51: #define R_addr r6 /* R_addr && R_temp SHARE */
52: #define R_temp r6 /* R_addr && R_temp SHARE */
53:
54: ENTRY(bzero)
55: /*
56: * If the destination is not word aligned, we'll word align
57: * it first to make things easier.
58: *
59: * We'll check to see first if bit #0 is set and then bit #1
60: * (of the destination address). If either are set, it's
61: * not word aligned.
62: */
63: bb1 0, R_dest, _ASM_LABEL(not_initially_word_aligned)
64: bb1 1, R_dest, _ASM_LABEL(not_initially_word_aligned)
65:
66: ASLOCAL(now_word_aligned)
67: /*
68: * before we get into the main loop, grab the
69: * address of the label "mark" below.
70: */
71: or.u R_mark_address, r0, hi16(_ASM_LABEL(mark))
72: or R_mark_address, R_mark_address, lo16(_ASM_LABEL(mark))
73:
74: ASLOCAL(top_of_main_loop)
75: #define MAX_AT_ONE_TIME 128
76: /*
77: * Now we find out how many words we can zero-fill in a row.
78: * We do this by doing something like:
79: *
80: * bytes &= 0xfffffffc;
81: * if (bytes > MAX_AT_ONE_TIME)
82: * bytes = MAX_AT_ONE_TIME;
83: */
84:
85: /*
86: * Clear lower two bits of length to give us the number of bytes
87: * ALIGNED TO THE WORD LENGTH remaining to move.
88: */
89: clr R_bytes, R_len, 2<0>
90:
91: /* if we're done clearing WORDS, jump out */
92: bcnd eq0, R_bytes, _ASM_LABEL(done_doing_words)
93:
94: /* if the number of bytes > MAX_AT_ONE_TIME, do only the max */
95: cmp R_temp, R_bytes, MAX_AT_ONE_TIME
96: bb1 lt, R_temp, 1f
97:
98: /*
99: * Since we're doing the max, we know exactly where we're
100: * jumping (the first one in the list!), so we can jump
101: * right there. However, we've still got to adjust
102: * the length, so we'll jump to where we ajust the length
103: * which just happens to fall through to the first store zero
104: * in the list.
105: *
106: * Note, however, that we're jumping to an instruction that
107: * would be in the delay slot for the jump in front of it,
108: * so if you change things here, WATCH OUT.
109: */
110: br.n do_max
111: or R_bytes, r0, MAX_AT_ONE_TIME
112:
113: 1:
114: /*
115: * Now we have the number of bytes to zero during this iteration,
116: * (which, as it happens, is the last iteration if we're here).
117: * We'll calculate the proper place to jump and then jump there,
118: * after adjusting the length. NOTE that there is a label between
119: * the "jmp.n" and the "subu" below... the "subu" is NOT always
120: * executed in the delay slot of the "jmp.n".
121: */
122: subu R_addr, R_mark_address, R_bytes
123:
124: /* and go there (after adjusting the length via ".n") */
125: jmp.n R_addr
126: ASLOCAL(do_max)
127: subu R_len, R_len, R_bytes /* NOTE: this is in the delay slot! */
128:
129: st r0, R_dest, 0x7c /* 128 */
130: st r0, R_dest, 0x78 /* 124 */
131: st r0, R_dest, 0x74 /* 120 */
132: st r0, R_dest, 0x70 /* 116 */
133: st r0, R_dest, 0x6c /* 112 */
134: st r0, R_dest, 0x68 /* 108 */
135: st r0, R_dest, 0x64 /* 104 */
136: st r0, R_dest, 0x60 /* 100 */
137: st r0, R_dest, 0x5c /* 96 */
138: st r0, R_dest, 0x58 /* 92 */
139: st r0, R_dest, 0x54 /* 88 */
140: st r0, R_dest, 0x50 /* 84 */
141: st r0, R_dest, 0x4c /* 80 */
142: st r0, R_dest, 0x48 /* 76 */
143: st r0, R_dest, 0x44 /* 72 */
144: st r0, R_dest, 0x40 /* 68 */
145: st r0, R_dest, 0x3c /* 64 */
146: st r0, R_dest, 0x38 /* 60 */
147: st r0, R_dest, 0x34 /* 56 */
148: st r0, R_dest, 0x30 /* 52 */
149: st r0, R_dest, 0x2c /* 44 */
150: st r0, R_dest, 0x28 /* 40 */
151: st r0, R_dest, 0x24 /* 36 */
152: st r0, R_dest, 0x20 /* 32 */
153: st r0, R_dest, 0x1c /* 28 */
154: st r0, R_dest, 0x18 /* 24 */
155: st r0, R_dest, 0x14 /* 20 */
156: st r0, R_dest, 0x10 /* 16 */
157: st r0, R_dest, 0x0c /* 12 */
158: st r0, R_dest, 0x08 /* 8 */
159: st r0, R_dest, 0x04 /* 4 */
160: st r0, R_dest, 0x00 /* 0 */
161:
162: ASLOCAL(mark)
163: br.n _ASM_LABEL(top_of_main_loop)
164: addu R_dest, R_dest, R_bytes /* bump up the dest address */
165:
166: ASLOCAL(done_doing_words)
167: bcnd ne0, R_len, 1f
168: jmp r1
169:
170: 1:
171: subu R_len, R_len, 1
172: bcnd.n ne0, R_len, 1b
173: st.b r0, R_dest, R_len
174: 1:
175: jmp r1
176:
177: ASLOCAL(not_initially_word_aligned)
178: /*
179: * Bzero to word-align the address (at least if the length allows it).
180: */
181: bcnd eq0, R_len, 1b
182: st.b r0, R_dest, 0
183: addu R_dest, R_dest, 1
184: mask R_temp, R_dest, 0x3
185: bcnd.n eq0, R_temp, _ASM_LABEL(now_word_aligned)
186: subu R_len, R_len, 1
187: br _ASM_LABEL(not_initially_word_aligned)
188:
189: #undef R_dest
190: #undef R_len
191: #undef R_bytes
192: #undef R_mark_address
193: #undef R_addr
194: #undef R_temp
195: #undef MAX_AT_ONE_TIME
CVSweb