xref: /openbsd-src/sys/lib/libkern/arch/sparc64/bzero.S (revision db3296cf5c1dd9058ceecc3a29fe4aaa0bd26000)
1/*	$OpenBSD: bzero.S,v 1.3 2003/06/02 23:28:09 millert 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. Neither the name of the University nor the names of its contributors
21 *    may be used to endorse or promote products derived from this software
22 *    without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * Header: bzero.s,v 1.1 92/06/25 12:52:46 torek Exp
37 */
38
39#if defined(LIBC_SCCS) && !defined(lint)
40#ifdef notdef
41	.asciz "@(#)bzero.s	8.1 (Berkeley) 6/4/93"
42#endif
43	.asciz "$NetBSD: bzero.S,v 1.1.1.1 1998/06/20 05:18:14 eeh Exp $"
44#endif  /* LIBC_SCCS and not lint */
45
46#include "DEFS.h"
47
48/*
49 * bzero(addr, len)
50 *
51 * We should unroll the loop, but at the moment this would
52 * gain nothing since the `std' instructions are what limits us.
53 *
54 * I just changed all the `std's to `stx's.  It still needs proper
55 * optimization using the block load/store ASIs.
56 */
57ENTRY(bzero)
58#ifdef NOT_DEBUG
59	save	%sp, -176, %sp
60	mov	%i0, %o1
61	set	9f, %o0
62	call	prom_printf
63	 mov	%i1, %o2
64	ba	8f
65	 restore
669:	.asciz	"bzero(%p,%x)\r\n"
67	.align	4
688:
69#endif
70	! %o0 = addr, %o1 = len
71
72	! Optimize a common case: addr and len are both multiples of 8.
73	or	%o0, %o1, %o2
74	andcc	%o2, 7, %g0		! ((addr | len) & 7) != 0?
75	bnz	1f			! if so, cannot optimize
76	 clr	%g1			! in any case, we want g1=0
77
78	/* `Good' operands, can just store doubles. */
790:
80	deccc	8, %o1			! while ((len -= 8) >= 0)
81	bge,a	0b
82	 stx	%g0, [%o0 + %o1]	!	*(quad *)(addr + len) = 0;
83	retl
84	 nop
85
86	/*
87	 * Either the address is unaligned, or the count is not a
88	 * multiple of 8, or both.  We will have to align the address
89	 * in order to use anything `better' than stb.
90	 */
911:
92	cmp	%o1, 15			! len >= 15?
93	bge,a	Lstd			! yes, use std
94	 andcc	%o0, 1, %g0		! (but first check alignment)
95
96	! not enough to bother: do byte-at-a-time loop.
972:
98	deccc	%o1			! while (--len >= 0)
99	bge,a	2b
100	 stb	%g0, [%o0 + %o1]	!	addr[len] = 0;
101	retl
102	 nop
103
104Lstd:
105	/*
106	 * There are at least 15 bytes to zero.
107	 * We may have to zero some initial stuff to align
108	 * the address.
109	 */
110	bz,a	1f			! if (addr & 1) {
111	 andcc	%o0, 2, %g0
112	stb	%g0, [%o0]		!	*addr = 0;
113	inc	%o0			!	addr++;
114	dec	%o1			!	len--;
115	andcc	%o0, 2, %g0			! }
1161:
117	bz,a	1f			! if (addr & 2) {
118	 andcc	%o0, 4, %g0
119	sth	%g0, [%o0]		!	*(short *)addr = 0;
120	inc	2, %o0			!	addr += 2;
121	dec	2, %o1			!	len -= 2;
122	andcc	%o0, 4, %g0		! }
1231:
124	bz	1f			! if (addr & 4) {
125	 dec	8, %o1
126	st	%g0, [%o0]		!	*(int *)addr = 0;
127	inc	4, %o0			!	addr += 4;
128	dec	4, %o1			!	len -= 4;
129					! }
130	/*
131	 * Address is double word aligned; len is 8 less than
132	 * the number of bytes remaining (i.e., len is 0 if
133	 * the remaining count is 8, 1 if it is 9, etc.).
134	 */
1351:
136	stx	%g0, [%o0]		! do {
1372:					!	*(quad *)addr = 0;
138	inc	8, %o0			!	addr += 8;
139	deccc	8, %o1			! } while ((len -= 8) >= 0);
140	bge,a	2b
141	 stx	%g0, [%o0]
142
143	/*
144	 * Len is in [-8..-1] where -8 => done, -7 => 1 byte to zero,
145	 * -6 => two bytes, etc.  Mop up this remainder, if any.
146	 */
147	andcc	%o1, 4, %g0
148	bz	1f			! if (len & 4) {
149	 andcc	%o1, 2, %g0
150	st	%g0, [%o0]		!	*(int *)addr = 0;
151	inc	4, %o0			!	addr += 4;
1521:
153	bz	1f			! if (len & 2) {
154	 andcc	%o1, 1, %g0
155	sth	%g0, [%o0]		!	*(short *)addr = 0;
156	inc	2, %o0			!	addr += 2;
1571:
158	bnz,a	1f			! if (len & 1)
159	 stb	%g0, [%o0]		!	*addr = 0;
1601:
161	retl
162	 nop
163