Remove building with NOCRYPTO option
[minix.git] / common / lib / libc / arch / arm / string / memset.S
blobc3e0ad377d25cc2f9b328754047d20fa7b769aca
1 /*      $NetBSD: memset.S,v 1.8 2015/03/26 13:34:51 justin Exp $        */
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  */
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  */
69 #include <machine/asm.h>
71 #if defined(__ARM_EABI__) && !defined(_BZERO) && !defined(_RUMPKERNEL)
72 ENTRY(__aeabi_memset)
73         mov     r3, r1
74         mov     r1, r2
75         mov     r2, r3
76         b       memset
77 END(__aeabi_memset)
78 STRONG_ALIAS(__aeabi_memset4, __aeabi_memset)
79 STRONG_ALIAS(__aeabi_memset8, __aeabi_memset)
81 ENTRY(__aeabi_memclr)
82         mov     r2, r1
83         mov     r1, #0
84         b       memset
85 END(__aeabi_memclr)
86 STRONG_ALIAS(__aeabi_memclr4, __aeabi_memclr)
87 STRONG_ALIAS(__aeabi_memclr8, __aeabi_memclr)
88 #endif
91  * memset: Sets a block of memory to the specified value
92  *
93  * On entry:
94  *   r0 - dest address
95  *   r1 - byte to write
96  *   r2 - number of bytes to write
97  *
98  * On exit:
99  *   r0 - dest address
100  */
101 #ifdef _BZERO
102 /* LINTSTUB: Func: void bzero(void *, size_t) */
103 ENTRY(bzero)
104         mov     r3, #0x00
105 #else
106 /* LINTSTUB: Func: void *memset(void *, int, size_t) */
107 ENTRY(memset)
108         and     r3, r1, #0xff           /* We deal with bytes */
109         mov     r1, r2
110 #endif
111         cmp     r1, #0x04               /* Do we have less than 4 bytes */
112         mov     ip, r0
113         blt     .Lmemset_lessthanfour
115         /* Ok first we will word align the address */
116         ands    r2, ip, #0x03           /* Get the bottom two bits */
117         bne     .Lmemset_wordunaligned  /* The address is not word aligned */
119         /* We are now word aligned */
120 .Lmemset_wordaligned:
121 #ifndef _BZERO
122         orr     r3, r3, r3, lsl #8      /* Extend value to 16-bits */
123 #endif
124 #ifdef _ARM_ARCH_DWORD_OK
125         tst     ip, #0x04               /* Quad-align for Xscale */
126 #else
127         cmp     r1, #0x10
128 #endif
129 #ifndef _BZERO
130         orr     r3, r3, r3, lsl #16     /* Extend value to 32-bits */
131 #endif
132 #ifdef _ARM_ARCH_DWORD_OK
133         subne   r1, r1, #0x04           /* Quad-align if necessary */
134         strne   r3, [ip], #0x04
135         cmp     r1, #0x10
136 #endif
137         blt     .Lmemset_loop4          /* If less than 16 then use words */
138         mov     r2, r3                  /* Duplicate data */
139         cmp     r1, #0x80               /* If < 128 then skip the big loop */
140         blt     .Lmemset_loop32
142         /* Do 128 bytes at a time */
143 .Lmemset_loop128:
144         subs    r1, r1, #0x80
145 #ifdef _ARM_ARCH_DWORD_OK
146         strdge  r2, r3, [ip], #0x08
147         strdge  r2, r3, [ip], #0x08
148         strdge  r2, r3, [ip], #0x08
149         strdge  r2, r3, [ip], #0x08
150         strdge  r2, r3, [ip], #0x08
151         strdge  r2, r3, [ip], #0x08
152         strdge  r2, r3, [ip], #0x08
153         strdge  r2, r3, [ip], #0x08
154         strdge  r2, r3, [ip], #0x08
155         strdge  r2, r3, [ip], #0x08
156         strdge  r2, r3, [ip], #0x08
157         strdge  r2, r3, [ip], #0x08
158         strdge  r2, r3, [ip], #0x08
159         strdge  r2, r3, [ip], #0x08
160         strdge  r2, r3, [ip], #0x08
161         strdge  r2, r3, [ip], #0x08
162 #else
163         stmiage ip!, {r2-r3}
164         stmiage ip!, {r2-r3}
165         stmiage ip!, {r2-r3}
166         stmiage ip!, {r2-r3}
167         stmiage ip!, {r2-r3}
168         stmiage ip!, {r2-r3}
169         stmiage ip!, {r2-r3}
170         stmiage ip!, {r2-r3}
171         stmiage ip!, {r2-r3}
172         stmiage ip!, {r2-r3}
173         stmiage ip!, {r2-r3}
174         stmiage ip!, {r2-r3}
175         stmiage ip!, {r2-r3}
176         stmiage ip!, {r2-r3}
177         stmiage ip!, {r2-r3}
178         stmiage ip!, {r2-r3}
179 #endif
180         bgt     .Lmemset_loop128
181         RETc(eq)                        /* Zero length so just exit */
183         add     r1, r1, #0x80           /* Adjust for extra sub */
185         /* Do 32 bytes at a time */
186 .Lmemset_loop32:
187         subs    r1, r1, #0x20
188 #ifdef _ARM_ARCH_DWORD_OK
189         strdge  r2, r3, [ip], #0x08
190         strdge  r2, r3, [ip], #0x08
191         strdge  r2, r3, [ip], #0x08
192         strdge  r2, r3, [ip], #0x08
193 #else
194         stmiage ip!, {r2-r3}
195         stmiage ip!, {r2-r3}
196         stmiage ip!, {r2-r3}
197         stmiage ip!, {r2-r3}
198 #endif
199         bgt     .Lmemset_loop32
200         RETc(eq)                        /* Zero length so just exit */
202         adds    r1, r1, #0x10           /* Partially adjust for extra sub */
204         /* Deal with 16 bytes or more */
205 #ifdef _ARM_ARCH_DWORD_OK
206         strdge  r2, r3, [ip], #0x08
207         strdge  r2, r3, [ip], #0x08
208 #else
209         stmiage ip!, {r2-r3}
210         stmiage ip!, {r2-r3}
211 #endif
212         RETc(eq)                        /* Zero length so just exit */
214         addlt   r1, r1, #0x10           /* Possibly adjust for extra sub */
216         /* We have at least 4 bytes so copy as words */
217 .Lmemset_loop4:
218         subs    r1, r1, #0x04
219         strge   r3, [ip], #0x04
220         bgt     .Lmemset_loop4
221         RETc(eq)                        /* Zero length so just exit */
223 #ifdef _ARM_ARCH_DWORD_OK
224         /* Compensate for 64-bit alignment check */
225         adds    r1, r1, #0x04
226         RETc(eq)
227         cmp     r1, #2
228 #else
229         cmp     r1, #-2
230 #endif
232         strb    r3, [ip], #0x01         /* Set 1 byte */
233         strbge  r3, [ip], #0x01         /* Set another byte */
234         strbgt  r3, [ip]                /* and a third */
235         RET                             /* Exit */
237 .Lmemset_wordunaligned:
238         rsb     r2, r2, #0x004
239         strb    r3, [ip], #0x01         /* Set 1 byte */
240         cmp     r2, #0x02
241         strbge  r3, [ip], #0x01         /* Set another byte */
242         sub     r1, r1, r2
243         strbgt  r3, [ip], #0x01         /* and a third */
244         cmp     r1, #0x04               /* More than 4 bytes left? */
245         bge     .Lmemset_wordaligned    /* Yup */
247 .Lmemset_lessthanfour:
248         cmp     r1, #0x00
249         RETc(eq)                                /* Zero length so exit */
250         strb    r3, [ip], #0x01         /* Set 1 byte */
251         cmp     r1, #0x02
252         strbge  r3, [ip], #0x01         /* Set another byte */
253         strbgt  r3, [ip]                /* and a third */
254         RET                             /* Exit */
255 #ifdef _BZERO
256 END(bzero)
257 #else
258 END(memset)
259 #endif