154400Storek/* 2*61174Sbostic * Copyright (c) 1992, 1993 3*61174Sbostic * The Regents of the University of California. All rights reserved. 454400Storek * 554400Storek * This software was developed by the Computer Systems Engineering group 654400Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 754400Storek * contributed to Berkeley. 854400Storek * 954400Storek * %sccs.include.redist.c% 1054400Storek * 1154400Storek * from: $Header: bzero.s,v 1.1 92/06/25 12:52:46 torek Exp $ 1254400Storek */ 1354400Storek 1454400Storek#if defined(LIBC_SCCS) && !defined(lint) 15*61174Sbostic .asciz "@(#)bzero.s 8.1 (Berkeley) 06/04/93" 1654400Storek#endif /* LIBC_SCCS and not lint */ 1754400Storek 1854400Storek#include "DEFS.h" 1954400Storek 2054400Storek/* 2154400Storek * bzero(addr, len) 2254400Storek * 2354400Storek * We should unroll the loop, but at the moment this would 2454400Storek * gain nothing since the `std' instructions are what limits us. 2554400Storek */ 2654400StorekENTRY(bzero) 2754400Storek ! %o0 = addr, %o1 = len 2854400Storek 2954400Storek ! Optimize a common case: addr and len are both multiples of 8. 3054400Storek or %o0, %o1, %o2 3154400Storek btst 7, %o2 ! ((addr | len) & 7) != 0? 3254400Storek bnz 1f ! if so, cannot optimize 3354400Storek clr %g1 ! in any case, we want g1=0 3454400Storek 3554400Storek /* `Good' operands, can just store doubles. */ 3654400Storek0: 3754400Storek deccc 8, %o1 ! while ((len -= 8) >= 0) 3854400Storek bge,a 0b 3954400Storek std %g0, [%o0 + %o1] ! *(quad *)(addr + len) = 0; 4054400Storek retl 4154400Storek nop 4254400Storek 4354400Storek /* 4454400Storek * Either the address is unaligned, or the count is not a 4554400Storek * multiple of 8, or both. We will have to align the address 4654400Storek * in order to use anything `better' than stb. 4754400Storek */ 4854400Storek1: 4954400Storek cmp %o1, 15 ! len >= 15? 5054400Storek bge,a Lstd ! yes, use std 5154400Storek btst 1, %o0 ! (but first check alignment) 5254400Storek 5354400Storek ! not enough to bother: do byte-at-a-time loop. 5454400Storek2: 5554400Storek deccc %o1 ! while (--len >= 0) 5654400Storek bge,a 2b 5754400Storek stb %g0, [%o0 + %o1] ! addr[len] = 0; 5854400Storek retl 5954400Storek nop 6054400Storek 6154400StorekLstd: 6254400Storek /* 6354400Storek * There are at least 15 bytes to zero. 6454400Storek * We may have to zero some initial stuff to align 6554400Storek * the address. 6654400Storek */ 6754400Storek bz,a 1f ! if (addr & 1) { 6854400Storek btst 2, %o0 6954400Storek stb %g0, [%o0] ! *addr = 0; 7054400Storek inc %o0 ! addr++; 7154400Storek dec %o1 ! len--; 7254400Storek btst 2, %o0 ! } 7354400Storek1: 7454400Storek bz,a 1f ! if (addr & 2) { 7554400Storek btst 4, %o0 7654400Storek sth %g0, [%o0] ! *(short *)addr = 0; 7754400Storek inc 2, %o0 ! addr += 2; 7854400Storek dec 2, %o1 ! len -= 2; 7954400Storek btst 4, %o0 ! } 8054400Storek1: 8154400Storek bz 1f ! if (addr & 4) { 8254400Storek dec 8, %o1 8354400Storek st %g0, [%o0] ! *(int *)addr = 0; 8454400Storek inc 4, %o0 ! addr += 4; 8554400Storek dec 4, %o1 ! len -= 4; 8654400Storek ! } 8754400Storek /* 8854400Storek * Address is double word aligned; len is 8 less than 8954400Storek * the number of bytes remaining (i.e., len is 0 if 9054400Storek * the remaining count is 8, 1 if it is 9, etc.). 9154400Storek */ 9254400Storek1: 9354400Storek std %g0, [%o0] ! do { 9454400Storek2: ! *(quad *)addr = 0; 9554400Storek inc 8, %o0 ! addr += 8; 9654400Storek deccc 8, %o1 ! } while ((len -= 8) >= 0); 9754400Storek bge,a 2b 9854400Storek std %g0, [%o0] 9954400Storek 10054400Storek /* 10154400Storek * Len is in [-8..-1] where -8 => done, -7 => 1 byte to zero, 10254400Storek * -6 => two bytes, etc. Mop up this remainder, if any. 10354400Storek */ 10454400Storek btst 4, %o1 10554400Storek bz 1f ! if (len & 4) { 10654400Storek btst 2, %o1 10754400Storek st %g0, [%o0] ! *(int *)addr = 0; 10854400Storek inc 4, %o0 ! addr += 4; 10954400Storek1: 11054400Storek bz 1f ! if (len & 2) { 11154400Storek btst 1, %o1 11254400Storek sth %g0, [%o0] ! *(short *)addr = 0; 11354400Storek inc 2, %o0 ! addr += 2; 11454400Storek1: 11554400Storek bnz,a 1f ! if (len & 1) 11654400Storek stb %g0, [%o0] ! *addr = 0; 11754400Storek1: 11854400Storek retl 11954400Storek nop 120