xref: /minix3/common/lib/libc/arch/arm/string/memset.S (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc/*	$NetBSD: memset.S,v 1.6 2013/11/30 21:09:11 joerg Exp $	*/
2b6cbf720SGianluca Guida
3b6cbf720SGianluca Guida/*
4b6cbf720SGianluca Guida * Copyright 2003 Wasabi Systems, Inc.
5b6cbf720SGianluca Guida * All rights reserved.
6b6cbf720SGianluca Guida *
7b6cbf720SGianluca Guida * Written by Steve C. Woodford for Wasabi Systems, Inc.
8b6cbf720SGianluca Guida *
9b6cbf720SGianluca Guida * Redistribution and use in source and binary forms, with or without
10b6cbf720SGianluca Guida * modification, are permitted provided that the following conditions
11b6cbf720SGianluca Guida * are met:
12b6cbf720SGianluca Guida * 1. Redistributions of source code must retain the above copyright
13b6cbf720SGianluca Guida *    notice, this list of conditions and the following disclaimer.
14b6cbf720SGianluca Guida * 2. Redistributions in binary form must reproduce the above copyright
15b6cbf720SGianluca Guida *    notice, this list of conditions and the following disclaimer in the
16b6cbf720SGianluca Guida *    documentation and/or other materials provided with the distribution.
17b6cbf720SGianluca Guida * 3. All advertising materials mentioning features or use of this software
18b6cbf720SGianluca Guida *    must display the following acknowledgement:
19b6cbf720SGianluca Guida *      This product includes software developed for the NetBSD Project by
20b6cbf720SGianluca Guida *      Wasabi Systems, Inc.
21b6cbf720SGianluca Guida * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22b6cbf720SGianluca Guida *    or promote products derived from this software without specific prior
23b6cbf720SGianluca Guida *    written permission.
24b6cbf720SGianluca Guida *
25b6cbf720SGianluca Guida * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26b6cbf720SGianluca Guida * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27b6cbf720SGianluca Guida * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28b6cbf720SGianluca Guida * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29b6cbf720SGianluca Guida * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30b6cbf720SGianluca Guida * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31b6cbf720SGianluca Guida * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32b6cbf720SGianluca Guida * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33b6cbf720SGianluca Guida * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34b6cbf720SGianluca Guida * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35b6cbf720SGianluca Guida * POSSIBILITY OF SUCH DAMAGE.
36b6cbf720SGianluca Guida */
37b6cbf720SGianluca Guida/*
38b6cbf720SGianluca Guida * Copyright (c) 1995 Mark Brinicombe.
39b6cbf720SGianluca Guida * All rights reserved.
40b6cbf720SGianluca Guida *
41b6cbf720SGianluca Guida * Redistribution and use in source and binary forms, with or without
42b6cbf720SGianluca Guida * modification, are permitted provided that the following conditions
43b6cbf720SGianluca Guida * are met:
44b6cbf720SGianluca Guida * 1. Redistributions of source code must retain the above copyright
45b6cbf720SGianluca Guida *    notice, this list of conditions and the following disclaimer.
46b6cbf720SGianluca Guida * 2. Redistributions in binary form must reproduce the above copyright
47b6cbf720SGianluca Guida *    notice, this list of conditions and the following disclaimer in the
48b6cbf720SGianluca Guida *    documentation and/or other materials provided with the distribution.
49b6cbf720SGianluca Guida * 3. All advertising materials mentioning features or use of this software
50b6cbf720SGianluca Guida *    must display the following acknowledgement:
51b6cbf720SGianluca Guida *	This product includes software developed by Mark Brinicombe.
52b6cbf720SGianluca Guida * 4. The name of the company nor the name of the author may be used to
53b6cbf720SGianluca Guida *    endorse or promote products derived from this software without specific
54b6cbf720SGianluca Guida *    prior written permission.
55b6cbf720SGianluca Guida *
56b6cbf720SGianluca Guida * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
57b6cbf720SGianluca Guida * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
58b6cbf720SGianluca Guida * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
59b6cbf720SGianluca Guida * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
60b6cbf720SGianluca Guida * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
61b6cbf720SGianluca Guida * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
62b6cbf720SGianluca Guida * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63b6cbf720SGianluca Guida * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64b6cbf720SGianluca Guida * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65b6cbf720SGianluca Guida * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66b6cbf720SGianluca Guida * SUCH DAMAGE.
67b6cbf720SGianluca Guida */
68b6cbf720SGianluca Guida
69b6cbf720SGianluca Guida#include <machine/asm.h>
70b6cbf720SGianluca Guida
71*84d9c625SLionel Sambuc#if defined(__ARM_EABI__) && !defined(BZER0)
72*84d9c625SLionel SambucSTRONG_ALIAS(__aeabi_memset, memset)
73*84d9c625SLionel Sambuc#endif
74*84d9c625SLionel Sambuc
75b6cbf720SGianluca Guida/*
76b6cbf720SGianluca Guida * memset: Sets a block of memory to the specified value
77b6cbf720SGianluca Guida *
78b6cbf720SGianluca Guida * On entry:
79b6cbf720SGianluca Guida *   r0 - dest address
80b6cbf720SGianluca Guida *   r1 - byte to write
81b6cbf720SGianluca Guida *   r2 - number of bytes to write
82b6cbf720SGianluca Guida *
83b6cbf720SGianluca Guida * On exit:
84b6cbf720SGianluca Guida *   r0 - dest address
85b6cbf720SGianluca Guida */
86b6cbf720SGianluca Guida#ifdef _BZERO
87b6cbf720SGianluca Guida/* LINTSTUB: Func: void bzero(void *, size_t) */
88b6cbf720SGianluca GuidaENTRY(bzero)
89b6cbf720SGianluca Guida	mov	r3, #0x00
90b6cbf720SGianluca Guida#else
91b6cbf720SGianluca Guida/* LINTSTUB: Func: void *memset(void *, int, size_t) */
92b6cbf720SGianluca GuidaENTRY(memset)
93b6cbf720SGianluca Guida	and	r3, r1, #0xff		/* We deal with bytes */
94b6cbf720SGianluca Guida	mov	r1, r2
95b6cbf720SGianluca Guida#endif
96b6cbf720SGianluca Guida	cmp	r1, #0x04		/* Do we have less than 4 bytes */
97b6cbf720SGianluca Guida	mov	ip, r0
98b6cbf720SGianluca Guida	blt	.Lmemset_lessthanfour
99b6cbf720SGianluca Guida
100b6cbf720SGianluca Guida	/* Ok first we will word align the address */
101b6cbf720SGianluca Guida	ands	r2, ip, #0x03		/* Get the bottom two bits */
102b6cbf720SGianluca Guida	bne	.Lmemset_wordunaligned	/* The address is not word aligned */
103b6cbf720SGianluca Guida
104b6cbf720SGianluca Guida	/* We are now word aligned */
105b6cbf720SGianluca Guida.Lmemset_wordaligned:
106b6cbf720SGianluca Guida#ifndef _BZERO
107b6cbf720SGianluca Guida	orr	r3, r3, r3, lsl #8	/* Extend value to 16-bits */
108b6cbf720SGianluca Guida#endif
109*84d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK
110b6cbf720SGianluca Guida	tst	ip, #0x04		/* Quad-align for Xscale */
111b6cbf720SGianluca Guida#else
112b6cbf720SGianluca Guida	cmp	r1, #0x10
113b6cbf720SGianluca Guida#endif
114b6cbf720SGianluca Guida#ifndef _BZERO
115b6cbf720SGianluca Guida	orr	r3, r3, r3, lsl #16	/* Extend value to 32-bits */
116b6cbf720SGianluca Guida#endif
117*84d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK
118b6cbf720SGianluca Guida	subne	r1, r1, #0x04		/* Quad-align if necessary */
119b6cbf720SGianluca Guida	strne	r3, [ip], #0x04
120b6cbf720SGianluca Guida	cmp	r1, #0x10
121b6cbf720SGianluca Guida#endif
122b6cbf720SGianluca Guida	blt	.Lmemset_loop4		/* If less than 16 then use words */
123b6cbf720SGianluca Guida	mov	r2, r3			/* Duplicate data */
124b6cbf720SGianluca Guida	cmp	r1, #0x80		/* If < 128 then skip the big loop */
125b6cbf720SGianluca Guida	blt	.Lmemset_loop32
126b6cbf720SGianluca Guida
127b6cbf720SGianluca Guida	/* Do 128 bytes at a time */
128b6cbf720SGianluca Guida.Lmemset_loop128:
129b6cbf720SGianluca Guida	subs	r1, r1, #0x80
130*84d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK
131*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
132*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
133*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
134*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
135*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
136*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
137*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
138*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
139*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
140*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
141*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
142*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
143*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
144*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
145*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
146*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
147b6cbf720SGianluca Guida#else
148*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
149*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
150*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
151*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
152*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
153*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
154*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
155*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
156*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
157*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
158*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
159*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
160*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
161*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
162*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
163*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
164b6cbf720SGianluca Guida#endif
165b6cbf720SGianluca Guida	bgt	.Lmemset_loop128
166b6cbf720SGianluca Guida	RETc(eq)			/* Zero length so just exit */
167b6cbf720SGianluca Guida
168b6cbf720SGianluca Guida	add	r1, r1, #0x80		/* Adjust for extra sub */
169b6cbf720SGianluca Guida
170b6cbf720SGianluca Guida	/* Do 32 bytes at a time */
171b6cbf720SGianluca Guida.Lmemset_loop32:
172b6cbf720SGianluca Guida	subs	r1, r1, #0x20
173*84d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK
174*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
175*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
176*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
177*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
178b6cbf720SGianluca Guida#else
179*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
180*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
181*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
182*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
183b6cbf720SGianluca Guida#endif
184b6cbf720SGianluca Guida	bgt	.Lmemset_loop32
185b6cbf720SGianluca Guida	RETc(eq)			/* Zero length so just exit */
186b6cbf720SGianluca Guida
187b6cbf720SGianluca Guida	adds	r1, r1, #0x10		/* Partially adjust for extra sub */
188b6cbf720SGianluca Guida
189b6cbf720SGianluca Guida	/* Deal with 16 bytes or more */
190*84d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK
191*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
192*84d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
193b6cbf720SGianluca Guida#else
194*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
195*84d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
196b6cbf720SGianluca Guida#endif
197b6cbf720SGianluca Guida	RETc(eq)			/* Zero length so just exit */
198b6cbf720SGianluca Guida
199b6cbf720SGianluca Guida	addlt	r1, r1, #0x10		/* Possibly adjust for extra sub */
200b6cbf720SGianluca Guida
201b6cbf720SGianluca Guida	/* We have at least 4 bytes so copy as words */
202b6cbf720SGianluca Guida.Lmemset_loop4:
203b6cbf720SGianluca Guida	subs	r1, r1, #0x04
204b6cbf720SGianluca Guida	strge	r3, [ip], #0x04
205b6cbf720SGianluca Guida	bgt	.Lmemset_loop4
206b6cbf720SGianluca Guida	RETc(eq)			/* Zero length so just exit */
207b6cbf720SGianluca Guida
208*84d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK
209b6cbf720SGianluca Guida	/* Compensate for 64-bit alignment check */
210b6cbf720SGianluca Guida	adds	r1, r1, #0x04
211b6cbf720SGianluca Guida	RETc(eq)
212b6cbf720SGianluca Guida	cmp	r1, #2
213b6cbf720SGianluca Guida#else
214b6cbf720SGianluca Guida	cmp	r1, #-2
215b6cbf720SGianluca Guida#endif
216b6cbf720SGianluca Guida
217b6cbf720SGianluca Guida	strb	r3, [ip], #0x01		/* Set 1 byte */
218*84d9c625SLionel Sambuc	strbge	r3, [ip], #0x01		/* Set another byte */
219*84d9c625SLionel Sambuc	strbgt	r3, [ip]		/* and a third */
220b6cbf720SGianluca Guida	RET				/* Exit */
221b6cbf720SGianluca Guida
222b6cbf720SGianluca Guida.Lmemset_wordunaligned:
223b6cbf720SGianluca Guida	rsb	r2, r2, #0x004
224b6cbf720SGianluca Guida	strb	r3, [ip], #0x01		/* Set 1 byte */
225b6cbf720SGianluca Guida	cmp	r2, #0x02
226*84d9c625SLionel Sambuc	strbge	r3, [ip], #0x01		/* Set another byte */
227b6cbf720SGianluca Guida	sub	r1, r1, r2
228*84d9c625SLionel Sambuc	strbgt	r3, [ip], #0x01		/* and a third */
229b6cbf720SGianluca Guida	cmp	r1, #0x04		/* More than 4 bytes left? */
230b6cbf720SGianluca Guida	bge	.Lmemset_wordaligned	/* Yup */
231b6cbf720SGianluca Guida
232b6cbf720SGianluca Guida.Lmemset_lessthanfour:
233b6cbf720SGianluca Guida	cmp	r1, #0x00
234b6cbf720SGianluca Guida	RETc(eq)				/* Zero length so exit */
235b6cbf720SGianluca Guida	strb	r3, [ip], #0x01		/* Set 1 byte */
236b6cbf720SGianluca Guida	cmp	r1, #0x02
237*84d9c625SLionel Sambuc	strbge	r3, [ip], #0x01		/* Set another byte */
238*84d9c625SLionel Sambuc	strbgt	r3, [ip]		/* and a third */
239b6cbf720SGianluca Guida	RET				/* Exit */
240*84d9c625SLionel Sambuc#ifdef _BZERO
241*84d9c625SLionel SambucEND(bzero)
242*84d9c625SLionel Sambuc#else
243*84d9c625SLionel SambucEND(memset)
244*84d9c625SLionel Sambuc#endif
245