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