145cc0367Storek/* 2*7f4519afSbostic * Copyright (c) 1992, 1993 3*7f4519afSbostic * The Regents of the University of California. All rights reserved. 445cc0367Storek * 545cc0367Storek * This software was developed by the Computer Systems Engineering group 645cc0367Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 745cc0367Storek * contributed to Berkeley. 845cc0367Storek * 945cc0367Storek * %sccs.include.redist.c% 1045cc0367Storek * 1145cc0367Storek * from: $Header: bzero.s,v 1.1 92/06/25 12:52:46 torek Exp $ 1245cc0367Storek */ 1345cc0367Storek 1445cc0367Storek#if defined(LIBC_SCCS) && !defined(lint) 15*7f4519afSbostic .asciz "@(#)bzero.s 8.1 (Berkeley) 06/04/93" 1645cc0367Storek#endif /* LIBC_SCCS and not lint */ 1745cc0367Storek 1845cc0367Storek#include "DEFS.h" 1945cc0367Storek 2045cc0367Storek/* 2145cc0367Storek * bzero(addr, len) 2245cc0367Storek * 2345cc0367Storek * We should unroll the loop, but at the moment this would 2445cc0367Storek * gain nothing since the `std' instructions are what limits us. 2545cc0367Storek */ 2645cc0367StorekENTRY(bzero) 2745cc0367Storek ! %o0 = addr, %o1 = len 2845cc0367Storek 2945cc0367Storek ! Optimize a common case: addr and len are both multiples of 8. 3045cc0367Storek or %o0, %o1, %o2 3145cc0367Storek btst 7, %o2 ! ((addr | len) & 7) != 0? 3245cc0367Storek bnz 1f ! if so, cannot optimize 3345cc0367Storek clr %g1 ! in any case, we want g1=0 3445cc0367Storek 3545cc0367Storek /* `Good' operands, can just store doubles. */ 3645cc0367Storek0: 3745cc0367Storek deccc 8, %o1 ! while ((len -= 8) >= 0) 3845cc0367Storek bge,a 0b 3945cc0367Storek std %g0, [%o0 + %o1] ! *(quad *)(addr + len) = 0; 4045cc0367Storek retl 4145cc0367Storek nop 4245cc0367Storek 4345cc0367Storek /* 4445cc0367Storek * Either the address is unaligned, or the count is not a 4545cc0367Storek * multiple of 8, or both. We will have to align the address 4645cc0367Storek * in order to use anything `better' than stb. 4745cc0367Storek */ 4845cc0367Storek1: 4945cc0367Storek cmp %o1, 15 ! len >= 15? 5045cc0367Storek bge,a Lstd ! yes, use std 5145cc0367Storek btst 1, %o0 ! (but first check alignment) 5245cc0367Storek 5345cc0367Storek ! not enough to bother: do byte-at-a-time loop. 5445cc0367Storek2: 5545cc0367Storek deccc %o1 ! while (--len >= 0) 5645cc0367Storek bge,a 2b 5745cc0367Storek stb %g0, [%o0 + %o1] ! addr[len] = 0; 5845cc0367Storek retl 5945cc0367Storek nop 6045cc0367Storek 6145cc0367StorekLstd: 6245cc0367Storek /* 6345cc0367Storek * There are at least 15 bytes to zero. 6445cc0367Storek * We may have to zero some initial stuff to align 6545cc0367Storek * the address. 6645cc0367Storek */ 6745cc0367Storek bz,a 1f ! if (addr & 1) { 6845cc0367Storek btst 2, %o0 6945cc0367Storek stb %g0, [%o0] ! *addr = 0; 7045cc0367Storek inc %o0 ! addr++; 7145cc0367Storek dec %o1 ! len--; 7245cc0367Storek btst 2, %o0 ! } 7345cc0367Storek1: 7445cc0367Storek bz,a 1f ! if (addr & 2) { 7545cc0367Storek btst 4, %o0 7645cc0367Storek sth %g0, [%o0] ! *(short *)addr = 0; 7745cc0367Storek inc 2, %o0 ! addr += 2; 7845cc0367Storek dec 2, %o1 ! len -= 2; 7945cc0367Storek btst 4, %o0 ! } 8045cc0367Storek1: 8145cc0367Storek bz 1f ! if (addr & 4) { 8245cc0367Storek dec 8, %o1 8345cc0367Storek st %g0, [%o0] ! *(int *)addr = 0; 8445cc0367Storek inc 4, %o0 ! addr += 4; 8545cc0367Storek dec 4, %o1 ! len -= 4; 8645cc0367Storek ! } 8745cc0367Storek /* 8845cc0367Storek * Address is double word aligned; len is 8 less than 8945cc0367Storek * the number of bytes remaining (i.e., len is 0 if 9045cc0367Storek * the remaining count is 8, 1 if it is 9, etc.). 9145cc0367Storek */ 9245cc0367Storek1: 9345cc0367Storek std %g0, [%o0] ! do { 9445cc0367Storek2: ! *(quad *)addr = 0; 9545cc0367Storek inc 8, %o0 ! addr += 8; 9645cc0367Storek deccc 8, %o1 ! } while ((len -= 8) >= 0); 9745cc0367Storek bge,a 2b 9845cc0367Storek std %g0, [%o0] 9945cc0367Storek 10045cc0367Storek /* 10145cc0367Storek * Len is in [-8..-1] where -8 => done, -7 => 1 byte to zero, 10245cc0367Storek * -6 => two bytes, etc. Mop up this remainder, if any. 10345cc0367Storek */ 10445cc0367Storek btst 4, %o1 10545cc0367Storek bz 1f ! if (len & 4) { 10645cc0367Storek btst 2, %o1 10745cc0367Storek st %g0, [%o0] ! *(int *)addr = 0; 10845cc0367Storek inc 4, %o0 ! addr += 4; 10945cc0367Storek1: 11045cc0367Storek bz 1f ! if (len & 2) { 11145cc0367Storek btst 1, %o1 11245cc0367Storek sth %g0, [%o0] ! *(short *)addr = 0; 11345cc0367Storek inc 2, %o0 ! addr += 2; 11445cc0367Storek1: 11545cc0367Storek bnz,a 1f ! if (len & 1) 11645cc0367Storek stb %g0, [%o0] ! *addr = 0; 11745cc0367Storek1: 11845cc0367Storek retl 11945cc0367Storek nop 120