1/* $OpenBSD: bzero.S,v 1.2 2013/01/05 11:20:56 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 54ENTRY(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 66ASLOCAL(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 74ASLOCAL(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 1131: 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 126ASLOCAL(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 162ASLOCAL(mark) 163 br.n _ASM_LABEL(top_of_main_loop) 164 addu R_dest, R_dest, R_bytes /* bump up the dest address */ 165 166ASLOCAL(done_doing_words) 167 bcnd ne0, R_len, 1f 168 jmp %r1 169 1701: 171 subu R_len, R_len, 1 172 bcnd.n ne0, R_len, 1b 173 st.b %r0, R_dest, R_len 1741: 175 jmp %r1 176 177ASLOCAL(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 196