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