1*54400Storek/* 2*54400Storek * Copyright (c) 1992 The Regents of the University of California. 3*54400Storek * All rights reserved. 4*54400Storek * 5*54400Storek * This software was developed by the Computer Systems Engineering group 6*54400Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7*54400Storek * contributed to Berkeley. 8*54400Storek * 9*54400Storek * %sccs.include.redist.c% 10*54400Storek * 11*54400Storek * from: $Header: bzero.s,v 1.1 92/06/25 12:52:46 torek Exp $ 12*54400Storek */ 13*54400Storek 14*54400Storek#if defined(LIBC_SCCS) && !defined(lint) 15*54400Storek .asciz "@(#)bzero.s 5.1 (Berkeley) 06/25/92" 16*54400Storek#endif /* LIBC_SCCS and not lint */ 17*54400Storek 18*54400Storek#include "DEFS.h" 19*54400Storek 20*54400Storek/* 21*54400Storek * bzero(addr, len) 22*54400Storek * 23*54400Storek * We should unroll the loop, but at the moment this would 24*54400Storek * gain nothing since the `std' instructions are what limits us. 25*54400Storek */ 26*54400StorekENTRY(bzero) 27*54400Storek ! %o0 = addr, %o1 = len 28*54400Storek 29*54400Storek ! Optimize a common case: addr and len are both multiples of 8. 30*54400Storek or %o0, %o1, %o2 31*54400Storek btst 7, %o2 ! ((addr | len) & 7) != 0? 32*54400Storek bnz 1f ! if so, cannot optimize 33*54400Storek clr %g1 ! in any case, we want g1=0 34*54400Storek 35*54400Storek /* `Good' operands, can just store doubles. */ 36*54400Storek0: 37*54400Storek deccc 8, %o1 ! while ((len -= 8) >= 0) 38*54400Storek bge,a 0b 39*54400Storek std %g0, [%o0 + %o1] ! *(quad *)(addr + len) = 0; 40*54400Storek retl 41*54400Storek nop 42*54400Storek 43*54400Storek /* 44*54400Storek * Either the address is unaligned, or the count is not a 45*54400Storek * multiple of 8, or both. We will have to align the address 46*54400Storek * in order to use anything `better' than stb. 47*54400Storek */ 48*54400Storek1: 49*54400Storek cmp %o1, 15 ! len >= 15? 50*54400Storek bge,a Lstd ! yes, use std 51*54400Storek btst 1, %o0 ! (but first check alignment) 52*54400Storek 53*54400Storek ! not enough to bother: do byte-at-a-time loop. 54*54400Storek2: 55*54400Storek deccc %o1 ! while (--len >= 0) 56*54400Storek bge,a 2b 57*54400Storek stb %g0, [%o0 + %o1] ! addr[len] = 0; 58*54400Storek retl 59*54400Storek nop 60*54400Storek 61*54400StorekLstd: 62*54400Storek /* 63*54400Storek * There are at least 15 bytes to zero. 64*54400Storek * We may have to zero some initial stuff to align 65*54400Storek * the address. 66*54400Storek */ 67*54400Storek bz,a 1f ! if (addr & 1) { 68*54400Storek btst 2, %o0 69*54400Storek stb %g0, [%o0] ! *addr = 0; 70*54400Storek inc %o0 ! addr++; 71*54400Storek dec %o1 ! len--; 72*54400Storek btst 2, %o0 ! } 73*54400Storek1: 74*54400Storek bz,a 1f ! if (addr & 2) { 75*54400Storek btst 4, %o0 76*54400Storek sth %g0, [%o0] ! *(short *)addr = 0; 77*54400Storek inc 2, %o0 ! addr += 2; 78*54400Storek dec 2, %o1 ! len -= 2; 79*54400Storek btst 4, %o0 ! } 80*54400Storek1: 81*54400Storek bz 1f ! if (addr & 4) { 82*54400Storek dec 8, %o1 83*54400Storek st %g0, [%o0] ! *(int *)addr = 0; 84*54400Storek inc 4, %o0 ! addr += 4; 85*54400Storek dec 4, %o1 ! len -= 4; 86*54400Storek ! } 87*54400Storek /* 88*54400Storek * Address is double word aligned; len is 8 less than 89*54400Storek * the number of bytes remaining (i.e., len is 0 if 90*54400Storek * the remaining count is 8, 1 if it is 9, etc.). 91*54400Storek */ 92*54400Storek1: 93*54400Storek std %g0, [%o0] ! do { 94*54400Storek2: ! *(quad *)addr = 0; 95*54400Storek inc 8, %o0 ! addr += 8; 96*54400Storek deccc 8, %o1 ! } while ((len -= 8) >= 0); 97*54400Storek bge,a 2b 98*54400Storek std %g0, [%o0] 99*54400Storek 100*54400Storek /* 101*54400Storek * Len is in [-8..-1] where -8 => done, -7 => 1 byte to zero, 102*54400Storek * -6 => two bytes, etc. Mop up this remainder, if any. 103*54400Storek */ 104*54400Storek btst 4, %o1 105*54400Storek bz 1f ! if (len & 4) { 106*54400Storek btst 2, %o1 107*54400Storek st %g0, [%o0] ! *(int *)addr = 0; 108*54400Storek inc 4, %o0 ! addr += 4; 109*54400Storek1: 110*54400Storek bz 1f ! if (len & 2) { 111*54400Storek btst 1, %o1 112*54400Storek sth %g0, [%o0] ! *(short *)addr = 0; 113*54400Storek inc 2, %o0 ! addr += 2; 114*54400Storek1: 115*54400Storek bnz,a 1f ! if (len & 1) 116*54400Storek stb %g0, [%o0] ! *addr = 0; 117*54400Storek1: 118*54400Storek retl 119*54400Storek nop 120