xref: /openbsd-src/sys/lib/libkern/arch/sparc64/bzero.S (revision 2badd5e3f47d2d4252969cd98d7042b4e701b5ac)
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