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