memset.S revision 137464
1238405Sjkim/*	$NetBSD: memset.S,v 1.4 2003/10/14 07:51:45 scw Exp $	*/
2238405Sjkim
3238405Sjkim/*
4238405Sjkim * Copyright 2003 Wasabi Systems, Inc.
5238405Sjkim * All rights reserved.
6238405Sjkim *
7238405Sjkim * Written by Steve C. Woodford for Wasabi Systems, Inc.
8238405Sjkim *
9238405Sjkim * Redistribution and use in source and binary forms, with or without
10238405Sjkim * modification, are permitted provided that the following conditions
11238405Sjkim * are met:
12238405Sjkim * 1. Redistributions of source code must retain the above copyright
13238405Sjkim *    notice, this list of conditions and the following disclaimer.
14238405Sjkim * 2. Redistributions in binary form must reproduce the above copyright
15238405Sjkim *    notice, this list of conditions and the following disclaimer in the
16238405Sjkim *    documentation and/or other materials provided with the distribution.
17238405Sjkim * 3. All advertising materials mentioning features or use of this software
18238405Sjkim *    must display the following acknowledgement:
19238405Sjkim *      This product includes software developed for the NetBSD Project by
20238405Sjkim *      Wasabi Systems, Inc.
21238405Sjkim * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22238405Sjkim *    or promote products derived from this software without specific prior
23238405Sjkim *    written permission.
24238405Sjkim *
25238405Sjkim * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26238405Sjkim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27238405Sjkim * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28238405Sjkim * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29238405Sjkim * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30238405Sjkim * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31238405Sjkim * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32238405Sjkim * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33238405Sjkim * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34238405Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35238405Sjkim * POSSIBILITY OF SUCH DAMAGE.
36238405Sjkim */
37238405Sjkim/*
38238405Sjkim * Copyright (c) 1995 Mark Brinicombe.
39238405Sjkim * All rights reserved.
40238405Sjkim *
41238405Sjkim * Redistribution and use in source and binary forms, with or without
42238405Sjkim * modification, are permitted provided that the following conditions
43238405Sjkim * are met:
44238405Sjkim * 1. Redistributions of source code must retain the above copyright
45238405Sjkim *    notice, this list of conditions and the following disclaimer.
46238405Sjkim * 2. Redistributions in binary form must reproduce the above copyright
47238405Sjkim *    notice, this list of conditions and the following disclaimer in the
48238405Sjkim *    documentation and/or other materials provided with the distribution.
49238405Sjkim * 3. All advertising materials mentioning features or use of this software
50238405Sjkim *    must display the following acknowledgement:
51238405Sjkim *	This product includes software developed by Mark Brinicombe.
52238405Sjkim * 4. The name of the company nor the name of the author may be used to
53238405Sjkim *    endorse or promote products derived from this software without specific
54238405Sjkim *    prior written permission.
55238405Sjkim *
56238405Sjkim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
57238405Sjkim * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
58238405Sjkim * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
59238405Sjkim * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
60238405Sjkim * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
61238405Sjkim * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
62238405Sjkim * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63238405Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64238405Sjkim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65238405Sjkim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66238405Sjkim * SUCH DAMAGE.
67238405Sjkim */
68238405Sjkim
69238405Sjkim#include <machine/asm.h>
70238405Sjkim__FBSDID("$FreeBSD: head/lib/libc/arm/string/memset.S 137464 2004-11-09 16:49:14Z cognet $");
71238405Sjkim
72238405Sjkim/*
73238405Sjkim * memset: Sets a block of memory to the specified value
74238405Sjkim *
75238405Sjkim * On entry:
76238405Sjkim *   r0 - dest address
77238405Sjkim *   r1 - byte to write
78238405Sjkim *   r2 - number of bytes to write
79238405Sjkim *
80238405Sjkim * On exit:
81238405Sjkim *   r0 - dest address
82238405Sjkim */
83238405Sjkim#ifdef _BZERO
84238405Sjkim/* LINTSTUB: Func: void bzero(void *, size_t) */
85238405SjkimENTRY(bzero)
86238405Sjkim	mov	r3, #0x00
87238405Sjkim#else
88238405Sjkim/* LINTSTUB: Func: void *memset(void *, int, size_t) */
89238405SjkimENTRY(memset)
90238405Sjkim	and	r3, r1, #0xff		/* We deal with bytes */
91238405Sjkim	mov	r1, r2
92238405Sjkim#endif
93238405Sjkim	cmp	r1, #0x04		/* Do we have less than 4 bytes */
94238405Sjkim	mov	ip, r0
95238405Sjkim	blt	.Lmemset_lessthanfour
96238405Sjkim
97238405Sjkim	/* Ok first we will word align the address */
98238405Sjkim	ands	r2, ip, #0x03		/* Get the bottom two bits */
99238405Sjkim	bne	.Lmemset_wordunaligned	/* The address is not word aligned */
100238405Sjkim
101238405Sjkim	/* We are now word aligned */
102238405Sjkim.Lmemset_wordaligned:
103238405Sjkim#ifndef _BZERO
104238405Sjkim	orr	r3, r3, r3, lsl #8	/* Extend value to 16-bits */
105238405Sjkim#endif
106238405Sjkim#ifdef __XSCALE__
107238405Sjkim	tst	ip, #0x04		/* Quad-align for Xscale */
108238405Sjkim#else
109238405Sjkim	cmp	r1, #0x10
110238405Sjkim#endif
111238405Sjkim#ifndef _BZERO
112238405Sjkim	orr	r3, r3, r3, lsl #16	/* Extend value to 32-bits */
113238405Sjkim#endif
114238405Sjkim#ifdef __XSCALE__
115238405Sjkim	subne	r1, r1, #0x04		/* Quad-align if necessary */
116238405Sjkim	strne	r3, [ip], #0x04
117238405Sjkim	cmp	r1, #0x10
118238405Sjkim#endif
119238405Sjkim	blt	.Lmemset_loop4		/* If less than 16 then use words */
120238405Sjkim	mov	r2, r3			/* Duplicate data */
121238405Sjkim	cmp	r1, #0x80		/* If < 128 then skip the big loop */
122238405Sjkim	blt	.Lmemset_loop32
123238405Sjkim
124238405Sjkim	/* Do 128 bytes at a time */
125238405Sjkim.Lmemset_loop128:
126238405Sjkim	subs	r1, r1, #0x80
127238405Sjkim#ifdef __XSCALE__
128238405Sjkim	strged	r2, [ip], #0x08
129238405Sjkim	strged	r2, [ip], #0x08
130238405Sjkim	strged	r2, [ip], #0x08
131238405Sjkim	strged	r2, [ip], #0x08
132238405Sjkim	strged	r2, [ip], #0x08
133238405Sjkim	strged	r2, [ip], #0x08
134238405Sjkim	strged	r2, [ip], #0x08
135238405Sjkim	strged	r2, [ip], #0x08
136238405Sjkim	strged	r2, [ip], #0x08
137238405Sjkim	strged	r2, [ip], #0x08
138238405Sjkim	strged	r2, [ip], #0x08
139238405Sjkim	strged	r2, [ip], #0x08
140238405Sjkim	strged	r2, [ip], #0x08
141238405Sjkim	strged	r2, [ip], #0x08
142238405Sjkim	strged	r2, [ip], #0x08
143238405Sjkim	strged	r2, [ip], #0x08
144238405Sjkim#else
145238405Sjkim	stmgeia	ip!, {r2-r3}
146238405Sjkim	stmgeia	ip!, {r2-r3}
147238405Sjkim	stmgeia	ip!, {r2-r3}
148238405Sjkim	stmgeia	ip!, {r2-r3}
149238405Sjkim	stmgeia	ip!, {r2-r3}
150238405Sjkim	stmgeia	ip!, {r2-r3}
151238405Sjkim	stmgeia	ip!, {r2-r3}
152238405Sjkim	stmgeia	ip!, {r2-r3}
153238405Sjkim	stmgeia	ip!, {r2-r3}
154238405Sjkim	stmgeia	ip!, {r2-r3}
155238405Sjkim	stmgeia	ip!, {r2-r3}
156238405Sjkim	stmgeia	ip!, {r2-r3}
157238405Sjkim	stmgeia	ip!, {r2-r3}
158238405Sjkim	stmgeia	ip!, {r2-r3}
159238405Sjkim	stmgeia	ip!, {r2-r3}
160238405Sjkim	stmgeia	ip!, {r2-r3}
161238405Sjkim#endif
162238405Sjkim	bgt	.Lmemset_loop128
163238405Sjkim	RETeq			/* Zero length so just exit */
164238405Sjkim
165238405Sjkim	add	r1, r1, #0x80		/* Adjust for extra sub */
166238405Sjkim
167238405Sjkim	/* Do 32 bytes at a time */
168238405Sjkim.Lmemset_loop32:
169238405Sjkim	subs	r1, r1, #0x20
170238405Sjkim#ifdef __XSCALE__
171238405Sjkim	strged	r2, [ip], #0x08
172238405Sjkim	strged	r2, [ip], #0x08
173238405Sjkim	strged	r2, [ip], #0x08
174238405Sjkim	strged	r2, [ip], #0x08
175238405Sjkim#else
176238405Sjkim	stmgeia	ip!, {r2-r3}
177238405Sjkim	stmgeia	ip!, {r2-r3}
178238405Sjkim	stmgeia	ip!, {r2-r3}
179238405Sjkim	stmgeia	ip!, {r2-r3}
180238405Sjkim#endif
181238405Sjkim	bgt	.Lmemset_loop32
182238405Sjkim	RETeq			/* Zero length so just exit */
183238405Sjkim
184238405Sjkim	adds	r1, r1, #0x10		/* Partially adjust for extra sub */
185238405Sjkim
186238405Sjkim	/* Deal with 16 bytes or more */
187238405Sjkim#ifdef __XSCALE__
188238405Sjkim	strged	r2, [ip], #0x08
189238405Sjkim	strged	r2, [ip], #0x08
190238405Sjkim#else
191238405Sjkim	stmgeia	ip!, {r2-r3}
192238405Sjkim	stmgeia	ip!, {r2-r3}
193238405Sjkim#endif
194238405Sjkim	RETeq			/* Zero length so just exit */
195238405Sjkim
196238405Sjkim	addlt	r1, r1, #0x10		/* Possibly adjust for extra sub */
197238405Sjkim
198238405Sjkim	/* We have at least 4 bytes so copy as words */
199238405Sjkim.Lmemset_loop4:
200238405Sjkim	subs	r1, r1, #0x04
201238405Sjkim	strge	r3, [ip], #0x04
202238405Sjkim	bgt	.Lmemset_loop4
203238405Sjkim	RETeq			/* Zero length so just exit */
204238405Sjkim
205238405Sjkim#ifdef __XSCALE__
206238405Sjkim	/* Compensate for 64-bit alignment check */
207238405Sjkim	adds	r1, r1, #0x04
208238405Sjkim	RETeq
209238405Sjkim	cmp	r1, #2
210238405Sjkim#else
211238405Sjkim	cmp	r1, #-2
212238405Sjkim#endif
213238405Sjkim
214238405Sjkim	strb	r3, [ip], #0x01		/* Set 1 byte */
215238405Sjkim	strgeb	r3, [ip], #0x01		/* Set another byte */
216238405Sjkim	strgtb	r3, [ip]		/* and a third */
217238405Sjkim	RET			/* Exit */
218238405Sjkim
219238405Sjkim.Lmemset_wordunaligned:
220238405Sjkim	rsb	r2, r2, #0x004
221238405Sjkim	strb	r3, [ip], #0x01		/* Set 1 byte */
222238405Sjkim	cmp	r2, #0x02
223238405Sjkim	strgeb	r3, [ip], #0x01		/* Set another byte */
224238405Sjkim	sub	r1, r1, r2
225238405Sjkim	strgtb	r3, [ip], #0x01		/* and a third */
226238405Sjkim	cmp	r1, #0x04		/* More than 4 bytes left? */
227238405Sjkim	bge	.Lmemset_wordaligned	/* Yup */
228238405Sjkim
229238405Sjkim.Lmemset_lessthanfour:
230238405Sjkim	cmp	r1, #0x00
231238405Sjkim	RETeq			/* Zero length so exit */
232238405Sjkim	strb	r3, [ip], #0x01		/* Set 1 byte */
233238405Sjkim	cmp	r1, #0x02
234238405Sjkim	strgeb	r3, [ip], #0x01		/* Set another byte */
235238405Sjkim	strgtb	r3, [ip]		/* and a third */
236238405Sjkim	RET			/* Exit */
237238405Sjkim