Annotation of sys/lib/libkern/arch/m88k/bzero.S, Revision 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