1/* $OpenBSD: bzero.S,v 1.2 2001/08/20 20:15:29 jason Exp $ */ 2/* $NetBSD: bzero.S,v 1.1.1.1 1998/06/20 05:18:14 eeh Exp $ */ 3 4/* 5 * Copyright (c) 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This software was developed by the Computer Systems Engineering group 9 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 10 * contributed to Berkeley. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the University of 23 * California, Berkeley and its contributors. 24 * 4. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * Header: bzero.s,v 1.1 92/06/25 12:52:46 torek Exp 41 */ 42 43#if defined(LIBC_SCCS) && !defined(lint) 44#ifdef notdef 45 .asciz "@(#)bzero.s 8.1 (Berkeley) 6/4/93" 46#endif 47 .asciz "$NetBSD: bzero.S,v 1.1.1.1 1998/06/20 05:18:14 eeh Exp $" 48#endif /* LIBC_SCCS and not lint */ 49 50#include "DEFS.h" 51 52/* 53 * bzero(addr, len) 54 * 55 * We should unroll the loop, but at the moment this would 56 * gain nothing since the `std' instructions are what limits us. 57 * 58 * I just changed all the `std's to `stx's. It still needs proper 59 * optimization using the block load/store ASIs. 60 */ 61ENTRY(bzero) 62#ifdef NOT_DEBUG 63 save %sp, -176, %sp 64 mov %i0, %o1 65 set 9f, %o0 66 call prom_printf 67 mov %i1, %o2 68 ba 8f 69 restore 709: .asciz "bzero(%p,%x)\r\n" 71 .align 4 728: 73#endif 74 ! %o0 = addr, %o1 = len 75 76 ! Optimize a common case: addr and len are both multiples of 8. 77 or %o0, %o1, %o2 78 andcc %o2, 7, %g0 ! ((addr | len) & 7) != 0? 79 bnz 1f ! if so, cannot optimize 80 clr %g1 ! in any case, we want g1=0 81 82 /* `Good' operands, can just store doubles. */ 830: 84 deccc 8, %o1 ! while ((len -= 8) >= 0) 85 bge,a 0b 86 stx %g0, [%o0 + %o1] ! *(quad *)(addr + len) = 0; 87 retl 88 nop 89 90 /* 91 * Either the address is unaligned, or the count is not a 92 * multiple of 8, or both. We will have to align the address 93 * in order to use anything `better' than stb. 94 */ 951: 96 cmp %o1, 15 ! len >= 15? 97 bge,a Lstd ! yes, use std 98 andcc %o0, 1, %g0 ! (but first check alignment) 99 100 ! not enough to bother: do byte-at-a-time loop. 1012: 102 deccc %o1 ! while (--len >= 0) 103 bge,a 2b 104 stb %g0, [%o0 + %o1] ! addr[len] = 0; 105 retl 106 nop 107 108Lstd: 109 /* 110 * There are at least 15 bytes to zero. 111 * We may have to zero some initial stuff to align 112 * the address. 113 */ 114 bz,a 1f ! if (addr & 1) { 115 andcc %o0, 2, %g0 116 stb %g0, [%o0] ! *addr = 0; 117 inc %o0 ! addr++; 118 dec %o1 ! len--; 119 andcc %o0, 2, %g0 ! } 1201: 121 bz,a 1f ! if (addr & 2) { 122 andcc %o0, 4, %g0 123 sth %g0, [%o0] ! *(short *)addr = 0; 124 inc 2, %o0 ! addr += 2; 125 dec 2, %o1 ! len -= 2; 126 andcc %o0, 4, %g0 ! } 1271: 128 bz 1f ! if (addr & 4) { 129 dec 8, %o1 130 st %g0, [%o0] ! *(int *)addr = 0; 131 inc 4, %o0 ! addr += 4; 132 dec 4, %o1 ! len -= 4; 133 ! } 134 /* 135 * Address is double word aligned; len is 8 less than 136 * the number of bytes remaining (i.e., len is 0 if 137 * the remaining count is 8, 1 if it is 9, etc.). 138 */ 1391: 140 stx %g0, [%o0] ! do { 1412: ! *(quad *)addr = 0; 142 inc 8, %o0 ! addr += 8; 143 deccc 8, %o1 ! } while ((len -= 8) >= 0); 144 bge,a 2b 145 stx %g0, [%o0] 146 147 /* 148 * Len is in [-8..-1] where -8 => done, -7 => 1 byte to zero, 149 * -6 => two bytes, etc. Mop up this remainder, if any. 150 */ 151 andcc %o1, 4, %g0 152 bz 1f ! if (len & 4) { 153 andcc %o1, 2, %g0 154 st %g0, [%o0] ! *(int *)addr = 0; 155 inc 4, %o0 ! addr += 4; 1561: 157 bz 1f ! if (len & 2) { 158 andcc %o1, 1, %g0 159 sth %g0, [%o0] ! *(short *)addr = 0; 160 inc 2, %o0 ! addr += 2; 1611: 162 bnz,a 1f ! if (len & 1) 163 stb %g0, [%o0] ! *addr = 0; 1641: 165 retl 166 nop 167