1/* $NetBSD: memset.S,v 1.9 2023/01/19 18:03:03 mlelstv 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(_BZERO) && !defined(_RUMPKERNEL) 72ENTRY(__aeabi_memset) 73 mov r3, r1 74 mov r1, r2 75 mov r2, r3 76 b memset 77END(__aeabi_memset) 78STRONG_ALIAS(__aeabi_memset4, __aeabi_memset) 79STRONG_ALIAS(__aeabi_memset8, __aeabi_memset) 80 81ENTRY(__aeabi_memclr) 82 mov r2, r1 83 mov r1, #0 84 b memset 85END(__aeabi_memclr) 86STRONG_ALIAS(__aeabi_memclr4, __aeabi_memclr) 87STRONG_ALIAS(__aeabi_memclr8, __aeabi_memclr) 88#endif 89 90/* 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) */ 103ENTRY(bzero) 104 mov r3, #0x00 105#else 106/* LINTSTUB: Func: void *memset(void *, int, size_t) */ 107ENTRY(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 blo .Lmemset_lessthanfour 114 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 */ 118 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 blo .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 blo .Lmemset_loop32 141 142 /* Do 128 bytes at a time */ 143.Lmemset_loop128: 144 subs r1, r1, #0x80 145#ifdef _ARM_ARCH_DWORD_OK 146 strdhs r2, r3, [ip], #0x08 147 strdhs r2, r3, [ip], #0x08 148 strdhs r2, r3, [ip], #0x08 149 strdhs r2, r3, [ip], #0x08 150 strdhs r2, r3, [ip], #0x08 151 strdhs r2, r3, [ip], #0x08 152 strdhs r2, r3, [ip], #0x08 153 strdhs r2, r3, [ip], #0x08 154 strdhs r2, r3, [ip], #0x08 155 strdhs r2, r3, [ip], #0x08 156 strdhs r2, r3, [ip], #0x08 157 strdhs r2, r3, [ip], #0x08 158 strdhs r2, r3, [ip], #0x08 159 strdhs r2, r3, [ip], #0x08 160 strdhs r2, r3, [ip], #0x08 161 strdhs r2, r3, [ip], #0x08 162#else 163 stmiahs ip!, {r2-r3} 164 stmiahs ip!, {r2-r3} 165 stmiahs ip!, {r2-r3} 166 stmiahs ip!, {r2-r3} 167 stmiahs ip!, {r2-r3} 168 stmiahs ip!, {r2-r3} 169 stmiahs ip!, {r2-r3} 170 stmiahs ip!, {r2-r3} 171 stmiahs ip!, {r2-r3} 172 stmiahs ip!, {r2-r3} 173 stmiahs ip!, {r2-r3} 174 stmiahs ip!, {r2-r3} 175 stmiahs ip!, {r2-r3} 176 stmiahs ip!, {r2-r3} 177 stmiahs ip!, {r2-r3} 178 stmiahs ip!, {r2-r3} 179#endif 180 bhi .Lmemset_loop128 181 RETc(eq) /* Zero length so just exit */ 182 183 add r1, r1, #0x80 /* Adjust for extra sub */ 184 185 /* Do 32 bytes at a time */ 186.Lmemset_loop32: 187 subs r1, r1, #0x20 188#ifdef _ARM_ARCH_DWORD_OK 189 strdhs r2, r3, [ip], #0x08 190 strdhs r2, r3, [ip], #0x08 191 strdhs r2, r3, [ip], #0x08 192 strdhs r2, r3, [ip], #0x08 193#else 194 stmiahs ip!, {r2-r3} 195 stmiahs ip!, {r2-r3} 196 stmiahs ip!, {r2-r3} 197 stmiahs ip!, {r2-r3} 198#endif 199 bhi .Lmemset_loop32 200 RETc(eq) /* Zero length so just exit */ 201 202 adds r1, r1, #0x10 /* Partially adjust for extra sub */ 203 204 /* Deal with 16 bytes or more */ 205#ifdef _ARM_ARCH_DWORD_OK 206 strdhs r2, r3, [ip], #0x08 207 strdhs r2, r3, [ip], #0x08 208#else 209 stmiahs ip!, {r2-r3} 210 stmiahs ip!, {r2-r3} 211#endif 212 RETc(eq) /* Zero length so just exit */ 213 214 addlo r1, r1, #0x10 /* Possibly adjust for extra sub */ 215 216 /* We have at least 4 bytes so copy as words */ 217.Lmemset_loop4: 218 subs r1, r1, #0x04 219 strhs r3, [ip], #0x04 220 bhi .Lmemset_loop4 221 RETc(eq) /* Zero length so just exit */ 222 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 231 232 strb r3, [ip], #0x01 /* Set 1 byte */ 233 strbhs r3, [ip], #0x01 /* Set another byte */ 234 strbhi r3, [ip] /* and a third */ 235 RET /* Exit */ 236 237.Lmemset_wordunaligned: 238 rsb r2, r2, #0x004 239 strb r3, [ip], #0x01 /* Set 1 byte */ 240 cmp r2, #0x02 241 strbhs r3, [ip], #0x01 /* Set another byte */ 242 sub r1, r1, r2 243 strbhi r3, [ip], #0x01 /* and a third */ 244 cmp r1, #0x04 /* More than 4 bytes left? */ 245 bhs .Lmemset_wordaligned /* Yup */ 246 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 strbhs r3, [ip], #0x01 /* Set another byte */ 253 strbhi r3, [ip] /* and a third */ 254 RET /* Exit */ 255#ifdef _BZERO 256END(bzero) 257#else 258END(memset) 259#endif 260