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