xref: /minix/common/lib/libc/arch/arm/string/memset.S (revision 0a6a1f1d)
1*0a6a1f1dSLionel Sambuc/*	$NetBSD: memset.S,v 1.8 2015/03/26 13:34:51 justin 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*0a6a1f1dSLionel Sambuc#if defined(__ARM_EABI__) && !defined(_BZERO) && !defined(_RUMPKERNEL)
725ae1a533SBen GrasENTRY(__aeabi_memset)
735ae1a533SBen Gras	mov	r3, r1
745ae1a533SBen Gras	mov	r1, r2
755ae1a533SBen Gras	mov	r2, r3
765ae1a533SBen Gras	b	memset
775ae1a533SBen GrasEND(__aeabi_memset)
785ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memset4, __aeabi_memset)
795ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memset8, __aeabi_memset)
805ae1a533SBen Gras
815ae1a533SBen GrasENTRY(__aeabi_memclr)
825ae1a533SBen Gras	mov	r2, r1
835ae1a533SBen Gras	mov	r1, #0
845ae1a533SBen Gras	b	memset
855ae1a533SBen GrasEND(__aeabi_memclr)
865ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memclr4, __aeabi_memclr)
875ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memclr8, __aeabi_memclr)
8884d9c625SLionel Sambuc#endif
8984d9c625SLionel Sambuc
90b6cbf720SGianluca Guida/*
91b6cbf720SGianluca Guida * memset: Sets a block of memory to the specified value
92b6cbf720SGianluca Guida *
93b6cbf720SGianluca Guida * On entry:
94b6cbf720SGianluca Guida *   r0 - dest address
95b6cbf720SGianluca Guida *   r1 - byte to write
96b6cbf720SGianluca Guida *   r2 - number of bytes to write
97b6cbf720SGianluca Guida *
98b6cbf720SGianluca Guida * On exit:
99b6cbf720SGianluca Guida *   r0 - dest address
100b6cbf720SGianluca Guida */
101b6cbf720SGianluca Guida#ifdef _BZERO
102b6cbf720SGianluca Guida/* LINTSTUB: Func: void bzero(void *, size_t) */
103b6cbf720SGianluca GuidaENTRY(bzero)
104b6cbf720SGianluca Guida	mov	r3, #0x00
105b6cbf720SGianluca Guida#else
106b6cbf720SGianluca Guida/* LINTSTUB: Func: void *memset(void *, int, size_t) */
107b6cbf720SGianluca GuidaENTRY(memset)
108b6cbf720SGianluca Guida	and	r3, r1, #0xff		/* We deal with bytes */
109b6cbf720SGianluca Guida	mov	r1, r2
110b6cbf720SGianluca Guida#endif
111b6cbf720SGianluca Guida	cmp	r1, #0x04		/* Do we have less than 4 bytes */
112b6cbf720SGianluca Guida	mov	ip, r0
113b6cbf720SGianluca Guida	blt	.Lmemset_lessthanfour
114b6cbf720SGianluca Guida
115b6cbf720SGianluca Guida	/* Ok first we will word align the address */
116b6cbf720SGianluca Guida	ands	r2, ip, #0x03		/* Get the bottom two bits */
117b6cbf720SGianluca Guida	bne	.Lmemset_wordunaligned	/* The address is not word aligned */
118b6cbf720SGianluca Guida
119b6cbf720SGianluca Guida	/* We are now word aligned */
120b6cbf720SGianluca Guida.Lmemset_wordaligned:
121b6cbf720SGianluca Guida#ifndef _BZERO
122b6cbf720SGianluca Guida	orr	r3, r3, r3, lsl #8	/* Extend value to 16-bits */
123b6cbf720SGianluca Guida#endif
12484d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK
125b6cbf720SGianluca Guida	tst	ip, #0x04		/* Quad-align for Xscale */
126b6cbf720SGianluca Guida#else
127b6cbf720SGianluca Guida	cmp	r1, #0x10
128b6cbf720SGianluca Guida#endif
129b6cbf720SGianluca Guida#ifndef _BZERO
130b6cbf720SGianluca Guida	orr	r3, r3, r3, lsl #16	/* Extend value to 32-bits */
131b6cbf720SGianluca Guida#endif
13284d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK
133b6cbf720SGianluca Guida	subne	r1, r1, #0x04		/* Quad-align if necessary */
134b6cbf720SGianluca Guida	strne	r3, [ip], #0x04
135b6cbf720SGianluca Guida	cmp	r1, #0x10
136b6cbf720SGianluca Guida#endif
137b6cbf720SGianluca Guida	blt	.Lmemset_loop4		/* If less than 16 then use words */
138b6cbf720SGianluca Guida	mov	r2, r3			/* Duplicate data */
139b6cbf720SGianluca Guida	cmp	r1, #0x80		/* If < 128 then skip the big loop */
140b6cbf720SGianluca Guida	blt	.Lmemset_loop32
141b6cbf720SGianluca Guida
142b6cbf720SGianluca Guida	/* Do 128 bytes at a time */
143b6cbf720SGianluca Guida.Lmemset_loop128:
144b6cbf720SGianluca Guida	subs	r1, r1, #0x80
14584d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK
14684d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
14784d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
14884d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
14984d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
15084d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
15184d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
15284d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
15384d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
15484d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
15584d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
15684d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
15784d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
15884d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
15984d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
16084d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
16184d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
162b6cbf720SGianluca Guida#else
16384d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
16484d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
16584d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
16684d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
16784d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
16884d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
16984d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
17084d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
17184d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
17284d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
17384d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
17484d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
17584d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
17684d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
17784d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
17884d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
179b6cbf720SGianluca Guida#endif
180b6cbf720SGianluca Guida	bgt	.Lmemset_loop128
181b6cbf720SGianluca Guida	RETc(eq)			/* Zero length so just exit */
182b6cbf720SGianluca Guida
183b6cbf720SGianluca Guida	add	r1, r1, #0x80		/* Adjust for extra sub */
184b6cbf720SGianluca Guida
185b6cbf720SGianluca Guida	/* Do 32 bytes at a time */
186b6cbf720SGianluca Guida.Lmemset_loop32:
187b6cbf720SGianluca Guida	subs	r1, r1, #0x20
18884d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK
18984d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
19084d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
19184d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
19284d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
193b6cbf720SGianluca Guida#else
19484d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
19584d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
19684d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
19784d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
198b6cbf720SGianluca Guida#endif
199b6cbf720SGianluca Guida	bgt	.Lmemset_loop32
200b6cbf720SGianluca Guida	RETc(eq)			/* Zero length so just exit */
201b6cbf720SGianluca Guida
202b6cbf720SGianluca Guida	adds	r1, r1, #0x10		/* Partially adjust for extra sub */
203b6cbf720SGianluca Guida
204b6cbf720SGianluca Guida	/* Deal with 16 bytes or more */
20584d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK
20684d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
20784d9c625SLionel Sambuc	strdge	r2, r3, [ip], #0x08
208b6cbf720SGianluca Guida#else
20984d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
21084d9c625SLionel Sambuc	stmiage	ip!, {r2-r3}
211b6cbf720SGianluca Guida#endif
212b6cbf720SGianluca Guida	RETc(eq)			/* Zero length so just exit */
213b6cbf720SGianluca Guida
214b6cbf720SGianluca Guida	addlt	r1, r1, #0x10		/* Possibly adjust for extra sub */
215b6cbf720SGianluca Guida
216b6cbf720SGianluca Guida	/* We have at least 4 bytes so copy as words */
217b6cbf720SGianluca Guida.Lmemset_loop4:
218b6cbf720SGianluca Guida	subs	r1, r1, #0x04
219b6cbf720SGianluca Guida	strge	r3, [ip], #0x04
220b6cbf720SGianluca Guida	bgt	.Lmemset_loop4
221b6cbf720SGianluca Guida	RETc(eq)			/* Zero length so just exit */
222b6cbf720SGianluca Guida
22384d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK
224b6cbf720SGianluca Guida	/* Compensate for 64-bit alignment check */
225b6cbf720SGianluca Guida	adds	r1, r1, #0x04
226b6cbf720SGianluca Guida	RETc(eq)
227b6cbf720SGianluca Guida	cmp	r1, #2
228b6cbf720SGianluca Guida#else
229b6cbf720SGianluca Guida	cmp	r1, #-2
230b6cbf720SGianluca Guida#endif
231b6cbf720SGianluca Guida
232b6cbf720SGianluca Guida	strb	r3, [ip], #0x01		/* Set 1 byte */
23384d9c625SLionel Sambuc	strbge	r3, [ip], #0x01		/* Set another byte */
23484d9c625SLionel Sambuc	strbgt	r3, [ip]		/* and a third */
235b6cbf720SGianluca Guida	RET				/* Exit */
236b6cbf720SGianluca Guida
237b6cbf720SGianluca Guida.Lmemset_wordunaligned:
238b6cbf720SGianluca Guida	rsb	r2, r2, #0x004
239b6cbf720SGianluca Guida	strb	r3, [ip], #0x01		/* Set 1 byte */
240b6cbf720SGianluca Guida	cmp	r2, #0x02
24184d9c625SLionel Sambuc	strbge	r3, [ip], #0x01		/* Set another byte */
242b6cbf720SGianluca Guida	sub	r1, r1, r2
24384d9c625SLionel Sambuc	strbgt	r3, [ip], #0x01		/* and a third */
244b6cbf720SGianluca Guida	cmp	r1, #0x04		/* More than 4 bytes left? */
245b6cbf720SGianluca Guida	bge	.Lmemset_wordaligned	/* Yup */
246b6cbf720SGianluca Guida
247b6cbf720SGianluca Guida.Lmemset_lessthanfour:
248b6cbf720SGianluca Guida	cmp	r1, #0x00
249b6cbf720SGianluca Guida	RETc(eq)				/* Zero length so exit */
250b6cbf720SGianluca Guida	strb	r3, [ip], #0x01		/* Set 1 byte */
251b6cbf720SGianluca Guida	cmp	r1, #0x02
25284d9c625SLionel Sambuc	strbge	r3, [ip], #0x01		/* Set another byte */
25384d9c625SLionel Sambuc	strbgt	r3, [ip]		/* and a third */
254b6cbf720SGianluca Guida	RET				/* Exit */
25584d9c625SLionel Sambuc#ifdef _BZERO
25684d9c625SLionel SambucEND(bzero)
25784d9c625SLionel Sambuc#else
25884d9c625SLionel SambucEND(memset)
25984d9c625SLionel Sambuc#endif
260