1*5ae1a533SBen Gras/* $NetBSD: memset.S,v 1.7 2013/12/02 21:21:33 joerg Exp $ */ 2433d6423SLionel Sambuc 3433d6423SLionel Sambuc/* 4433d6423SLionel Sambuc * Copyright 2003 Wasabi Systems, Inc. 5433d6423SLionel Sambuc * All rights reserved. 6433d6423SLionel Sambuc * 7433d6423SLionel Sambuc * Written by Steve C. Woodford for Wasabi Systems, Inc. 8433d6423SLionel Sambuc * 9433d6423SLionel Sambuc * Redistribution and use in source and binary forms, with or without 10433d6423SLionel Sambuc * modification, are permitted provided that the following conditions 11433d6423SLionel Sambuc * are met: 12433d6423SLionel Sambuc * 1. Redistributions of source code must retain the above copyright 13433d6423SLionel Sambuc * notice, this list of conditions and the following disclaimer. 14433d6423SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright 15433d6423SLionel Sambuc * notice, this list of conditions and the following disclaimer in the 16433d6423SLionel Sambuc * documentation and/or other materials provided with the distribution. 17433d6423SLionel Sambuc * 3. All advertising materials mentioning features or use of this software 18433d6423SLionel Sambuc * must display the following acknowledgement: 19433d6423SLionel Sambuc * This product includes software developed for the NetBSD Project by 20433d6423SLionel Sambuc * Wasabi Systems, Inc. 21433d6423SLionel Sambuc * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22433d6423SLionel Sambuc * or promote products derived from this software without specific prior 23433d6423SLionel Sambuc * written permission. 24433d6423SLionel Sambuc * 25433d6423SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26433d6423SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27433d6423SLionel Sambuc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28433d6423SLionel Sambuc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29433d6423SLionel Sambuc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30433d6423SLionel Sambuc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31433d6423SLionel Sambuc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32433d6423SLionel Sambuc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33433d6423SLionel Sambuc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34433d6423SLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35433d6423SLionel Sambuc * POSSIBILITY OF SUCH DAMAGE. 36433d6423SLionel Sambuc */ 37433d6423SLionel Sambuc/* 38433d6423SLionel Sambuc * Copyright (c) 1995 Mark Brinicombe. 39433d6423SLionel Sambuc * All rights reserved. 40433d6423SLionel Sambuc * 41433d6423SLionel Sambuc * Redistribution and use in source and binary forms, with or without 42433d6423SLionel Sambuc * modification, are permitted provided that the following conditions 43433d6423SLionel Sambuc * are met: 44433d6423SLionel Sambuc * 1. Redistributions of source code must retain the above copyright 45433d6423SLionel Sambuc * notice, this list of conditions and the following disclaimer. 46433d6423SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright 47433d6423SLionel Sambuc * notice, this list of conditions and the following disclaimer in the 48433d6423SLionel Sambuc * documentation and/or other materials provided with the distribution. 49433d6423SLionel Sambuc * 3. All advertising materials mentioning features or use of this software 50433d6423SLionel Sambuc * must display the following acknowledgement: 51433d6423SLionel Sambuc * This product includes software developed by Mark Brinicombe. 52433d6423SLionel Sambuc * 4. The name of the company nor the name of the author may be used to 53433d6423SLionel Sambuc * endorse or promote products derived from this software without specific 54433d6423SLionel Sambuc * prior written permission. 55433d6423SLionel Sambuc * 56433d6423SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 57433d6423SLionel Sambuc * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 58433d6423SLionel Sambuc * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 59433d6423SLionel Sambuc * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 60433d6423SLionel Sambuc * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 61433d6423SLionel Sambuc * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 62433d6423SLionel Sambuc * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63433d6423SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 64433d6423SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 65433d6423SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 66433d6423SLionel Sambuc * SUCH DAMAGE. 67433d6423SLionel Sambuc */ 68433d6423SLionel Sambuc 69433d6423SLionel Sambuc#include <machine/asm.h> 70433d6423SLionel Sambuc 71*5ae1a533SBen Gras#if 0 && defined(__minix) 72*5ae1a533SBen Gras#if defined(__ARM_EABI__) && !defined(_BZERO) 73*5ae1a533SBen GrasENTRY(__aeabi_memset) 74*5ae1a533SBen Gras mov r3, r1 75*5ae1a533SBen Gras mov r1, r2 76*5ae1a533SBen Gras mov r2, r3 77*5ae1a533SBen Gras b memset 78*5ae1a533SBen GrasEND(__aeabi_memset) 79*5ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memset4, __aeabi_memset) 80*5ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memset8, __aeabi_memset) 81*5ae1a533SBen Gras 82*5ae1a533SBen GrasENTRY(__aeabi_memclr) 83*5ae1a533SBen Gras mov r2, r1 84*5ae1a533SBen Gras mov r1, #0 85*5ae1a533SBen Gras b memset 86*5ae1a533SBen GrasEND(__aeabi_memclr) 87*5ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memclr4, __aeabi_memclr) 88*5ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memclr8, __aeabi_memclr) 89*5ae1a533SBen Gras#endif 90*5ae1a533SBen Gras#endif /* #if 0 && defined(__minix) */ 91*5ae1a533SBen Gras 92433d6423SLionel Sambuc/* 93433d6423SLionel Sambuc * memset: Sets a block of memory to the specified value 94433d6423SLionel Sambuc * 95433d6423SLionel Sambuc * On entry: 96433d6423SLionel Sambuc * r0 - dest address 97433d6423SLionel Sambuc * r1 - byte to write 98433d6423SLionel Sambuc * r2 - number of bytes to write 99433d6423SLionel Sambuc * 100433d6423SLionel Sambuc * On exit: 101433d6423SLionel Sambuc * r0 - dest address 102433d6423SLionel Sambuc */ 103433d6423SLionel Sambuc#ifdef _BZERO 104433d6423SLionel Sambuc/* LINTSTUB: Func: void bzero(void *, size_t) */ 105433d6423SLionel SambucENTRY(bzero) 106433d6423SLionel Sambuc mov r3, #0x00 107433d6423SLionel Sambuc#else 108433d6423SLionel Sambuc#if defined(__minix) 109433d6423SLionel Sambuc/* LINTSTUB: Func: void *phys_memset(void *, int, size_t) */ 110433d6423SLionel SambucENTRY(phys_memset) 111433d6423SLionel Sambuc#else 112433d6423SLionel Sambuc/* LINTSTUB: Func: void *memset(void *, int, size_t) */ 113433d6423SLionel SambucENTRY(memset) 114433d6423SLionel Sambuc#endif 115433d6423SLionel Sambuc and r3, r1, #0xff /* We deal with bytes */ 116433d6423SLionel Sambuc mov r1, r2 117433d6423SLionel Sambuc#endif 118433d6423SLionel Sambuc cmp r1, #0x04 /* Do we have less than 4 bytes */ 119433d6423SLionel Sambuc mov ip, r0 120433d6423SLionel Sambuc blt .Lmemset_lessthanfour 121433d6423SLionel Sambuc 122433d6423SLionel Sambuc /* Ok first we will word align the address */ 123433d6423SLionel Sambuc ands r2, ip, #0x03 /* Get the bottom two bits */ 124433d6423SLionel Sambuc bne .Lmemset_wordunaligned /* The address is not word aligned */ 125433d6423SLionel Sambuc 126433d6423SLionel Sambuc /* We are now word aligned */ 127433d6423SLionel Sambuc.Lmemset_wordaligned: 128433d6423SLionel Sambuc#ifndef _BZERO 129433d6423SLionel Sambuc orr r3, r3, r3, lsl #8 /* Extend value to 16-bits */ 130433d6423SLionel Sambuc#endif 131*5ae1a533SBen Gras#ifdef _ARM_ARCH_DWORD_OK 132433d6423SLionel Sambuc tst ip, #0x04 /* Quad-align for Xscale */ 133433d6423SLionel Sambuc#else 134433d6423SLionel Sambuc cmp r1, #0x10 135433d6423SLionel Sambuc#endif 136433d6423SLionel Sambuc#ifndef _BZERO 137433d6423SLionel Sambuc orr r3, r3, r3, lsl #16 /* Extend value to 32-bits */ 138433d6423SLionel Sambuc#endif 139*5ae1a533SBen Gras#ifdef _ARM_ARCH_DWORD_OK 140433d6423SLionel Sambuc subne r1, r1, #0x04 /* Quad-align if necessary */ 141433d6423SLionel Sambuc strne r3, [ip], #0x04 142433d6423SLionel Sambuc cmp r1, #0x10 143433d6423SLionel Sambuc#endif 144433d6423SLionel Sambuc blt .Lmemset_loop4 /* If less than 16 then use words */ 145433d6423SLionel Sambuc mov r2, r3 /* Duplicate data */ 146433d6423SLionel Sambuc cmp r1, #0x80 /* If < 128 then skip the big loop */ 147433d6423SLionel Sambuc blt .Lmemset_loop32 148433d6423SLionel Sambuc 149433d6423SLionel Sambuc /* Do 128 bytes at a time */ 150433d6423SLionel Sambuc.Lmemset_loop128: 151433d6423SLionel Sambuc subs r1, r1, #0x80 152*5ae1a533SBen Gras#ifdef _ARM_ARCH_DWORD_OK 153*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 154*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 155*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 156*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 157*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 158*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 159*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 160*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 161*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 162*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 163*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 164*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 165*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 166*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 167*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 168*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 169433d6423SLionel Sambuc#else 170*5ae1a533SBen Gras stmiage ip!, {r2-r3} 171*5ae1a533SBen Gras stmiage ip!, {r2-r3} 172*5ae1a533SBen Gras stmiage ip!, {r2-r3} 173*5ae1a533SBen Gras stmiage ip!, {r2-r3} 174*5ae1a533SBen Gras stmiage ip!, {r2-r3} 175*5ae1a533SBen Gras stmiage ip!, {r2-r3} 176*5ae1a533SBen Gras stmiage ip!, {r2-r3} 177*5ae1a533SBen Gras stmiage ip!, {r2-r3} 178*5ae1a533SBen Gras stmiage ip!, {r2-r3} 179*5ae1a533SBen Gras stmiage ip!, {r2-r3} 180*5ae1a533SBen Gras stmiage ip!, {r2-r3} 181*5ae1a533SBen Gras stmiage ip!, {r2-r3} 182*5ae1a533SBen Gras stmiage ip!, {r2-r3} 183*5ae1a533SBen Gras stmiage ip!, {r2-r3} 184*5ae1a533SBen Gras stmiage ip!, {r2-r3} 185*5ae1a533SBen Gras stmiage ip!, {r2-r3} 186433d6423SLionel Sambuc#endif 187433d6423SLionel Sambuc bgt .Lmemset_loop128 188433d6423SLionel Sambuc#if defined(__minix) 189433d6423SLionel Sambuc moveq r0, #0 190433d6423SLionel Sambuc#endif 191433d6423SLionel Sambuc RETc(eq) /* Zero length so just exit */ 192433d6423SLionel Sambuc 193433d6423SLionel Sambuc add r1, r1, #0x80 /* Adjust for extra sub */ 194433d6423SLionel Sambuc 195433d6423SLionel Sambuc /* Do 32 bytes at a time */ 196433d6423SLionel Sambuc.Lmemset_loop32: 197433d6423SLionel Sambuc subs r1, r1, #0x20 198*5ae1a533SBen Gras#ifdef _ARM_ARCH_DWORD_OK 199*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 200*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 201*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 202*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 203433d6423SLionel Sambuc#else 204*5ae1a533SBen Gras stmiage ip!, {r2-r3} 205*5ae1a533SBen Gras stmiage ip!, {r2-r3} 206*5ae1a533SBen Gras stmiage ip!, {r2-r3} 207*5ae1a533SBen Gras stmiage ip!, {r2-r3} 208433d6423SLionel Sambuc#endif 209433d6423SLionel Sambuc bgt .Lmemset_loop32 210433d6423SLionel Sambuc#if defined(__minix) 211433d6423SLionel Sambuc moveq r0, #0 212433d6423SLionel Sambuc#endif 213433d6423SLionel Sambuc RETc(eq) /* Zero length so just exit */ 214433d6423SLionel Sambuc 215433d6423SLionel Sambuc adds r1, r1, #0x10 /* Partially adjust for extra sub */ 216433d6423SLionel Sambuc 217433d6423SLionel Sambuc /* Deal with 16 bytes or more */ 218*5ae1a533SBen Gras#ifdef _ARM_ARCH_DWORD_OK 219*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 220*5ae1a533SBen Gras strdge r2, r3, [ip], #0x08 221433d6423SLionel Sambuc#else 222*5ae1a533SBen Gras stmiage ip!, {r2-r3} 223*5ae1a533SBen Gras stmiage ip!, {r2-r3} 224433d6423SLionel Sambuc#endif 225433d6423SLionel Sambuc#if defined(__minix) 226433d6423SLionel Sambuc moveq r0, #0 227433d6423SLionel Sambuc#endif 228433d6423SLionel Sambuc RETc(eq) /* Zero length so just exit */ 229433d6423SLionel Sambuc 230433d6423SLionel Sambuc addlt r1, r1, #0x10 /* Possibly adjust for extra sub */ 231433d6423SLionel Sambuc 232433d6423SLionel Sambuc /* We have at least 4 bytes so copy as words */ 233433d6423SLionel Sambuc.Lmemset_loop4: 234433d6423SLionel Sambuc subs r1, r1, #0x04 235433d6423SLionel Sambuc strge r3, [ip], #0x04 236433d6423SLionel Sambuc bgt .Lmemset_loop4 237433d6423SLionel Sambuc#if defined(__minix) 238433d6423SLionel Sambuc moveq r0, #0 239433d6423SLionel Sambuc#endif 240433d6423SLionel Sambuc RETc(eq) /* Zero length so just exit */ 241433d6423SLionel Sambuc 242*5ae1a533SBen Gras#ifdef _ARM_ARCH_DWORD_OK 243433d6423SLionel Sambuc /* Compensate for 64-bit alignment check */ 244433d6423SLionel Sambuc adds r1, r1, #0x04 245433d6423SLionel Sambuc#if defined(__minix) 246433d6423SLionel Sambuc moveq r0, #0 247433d6423SLionel Sambuc#endif 248433d6423SLionel Sambuc RETc(eq) 249433d6423SLionel Sambuc cmp r1, #2 250433d6423SLionel Sambuc#else 251433d6423SLionel Sambuc cmp r1, #-2 252433d6423SLionel Sambuc#endif 253433d6423SLionel Sambuc 254433d6423SLionel Sambuc strb r3, [ip], #0x01 /* Set 1 byte */ 255*5ae1a533SBen Gras strbge r3, [ip], #0x01 /* Set another byte */ 256*5ae1a533SBen Gras strbgt r3, [ip] /* and a third */ 257433d6423SLionel Sambuc#if defined(__minix) 258433d6423SLionel Sambuc mov r0, #0 259433d6423SLionel Sambuc#endif 260433d6423SLionel Sambuc RET /* Exit */ 261433d6423SLionel Sambuc 262433d6423SLionel Sambuc.Lmemset_wordunaligned: 263433d6423SLionel Sambuc rsb r2, r2, #0x004 264433d6423SLionel Sambuc strb r3, [ip], #0x01 /* Set 1 byte */ 265433d6423SLionel Sambuc cmp r2, #0x02 266*5ae1a533SBen Gras strbge r3, [ip], #0x01 /* Set another byte */ 267433d6423SLionel Sambuc sub r1, r1, r2 268*5ae1a533SBen Gras strbgt r3, [ip], #0x01 /* and a third */ 269433d6423SLionel Sambuc cmp r1, #0x04 /* More than 4 bytes left? */ 270433d6423SLionel Sambuc bge .Lmemset_wordaligned /* Yup */ 271433d6423SLionel Sambuc 272433d6423SLionel Sambuc.Lmemset_lessthanfour: 273433d6423SLionel Sambuc cmp r1, #0x00 274433d6423SLionel Sambuc#if defined(__minix) 275433d6423SLionel Sambuc moveq r0, #0 276433d6423SLionel Sambuc#endif 277433d6423SLionel Sambuc RETc(eq) /* Zero length so exit */ 278433d6423SLionel Sambuc strb r3, [ip], #0x01 /* Set 1 byte */ 279433d6423SLionel Sambuc cmp r1, #0x02 280*5ae1a533SBen Gras strbge r3, [ip], #0x01 /* Set another byte */ 281*5ae1a533SBen Gras strbgt r3, [ip] /* and a third */ 282433d6423SLionel Sambuc#if defined(__minix) 283433d6423SLionel Sambuc mov r0, #0 284433d6423SLionel Sambuc#endif 285433d6423SLionel Sambuc RET /* Exit */ 286*5ae1a533SBen Gras#ifdef _BZERO 287*5ae1a533SBen GrasEND(bzero) 288*5ae1a533SBen Gras#else 289*5ae1a533SBen Gras#if !defined(__minix) 290*5ae1a533SBen GrasEND(memset) 291*5ae1a533SBen Gras#else 292*5ae1a533SBen GrasEND(phys_memset) 293*5ae1a533SBen Gras#endif 294*5ae1a533SBen Gras#endif 295433d6423SLionel Sambuc 296433d6423SLionel Sambuc#if defined(__minix) 297433d6423SLionel SambucLABEL(memset_fault) /* kernel can send us here */ 298433d6423SLionel Sambuc mov r0, #0 299433d6423SLionel Sambuc RET 300433d6423SLionel Sambuc 301433d6423SLionel SambucLABEL(memset_fault_in_kernel) /* kernel can send us here */ 302433d6423SLionel Sambuc mrc p15, 0, r0, c6, c0, 0 /* Read DFAR */ 303433d6423SLionel Sambuc RET 304433d6423SLionel Sambuc#endif 305