1*0a6a1f1dSLionel Sambuc/* $NetBSD: memset.S,v 1.8 2015/03/26 13:34:51 justin 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*0a6a1f1dSLionel Sambuc#if defined(__ARM_EABI__) && !defined(_BZERO) && !defined(_RUMPKERNEL) 725ae1a533SBen GrasENTRY(__aeabi_memset) 735ae1a533SBen Gras mov r3, r1 745ae1a533SBen Gras mov r1, r2 755ae1a533SBen Gras mov r2, r3 765ae1a533SBen Gras b memset 775ae1a533SBen GrasEND(__aeabi_memset) 785ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memset4, __aeabi_memset) 795ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memset8, __aeabi_memset) 805ae1a533SBen Gras 815ae1a533SBen GrasENTRY(__aeabi_memclr) 825ae1a533SBen Gras mov r2, r1 835ae1a533SBen Gras mov r1, #0 845ae1a533SBen Gras b memset 855ae1a533SBen GrasEND(__aeabi_memclr) 865ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memclr4, __aeabi_memclr) 875ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memclr8, __aeabi_memclr) 8884d9c625SLionel Sambuc#endif 8984d9c625SLionel Sambuc 90b6cbf720SGianluca Guida/* 91b6cbf720SGianluca Guida * memset: Sets a block of memory to the specified value 92b6cbf720SGianluca Guida * 93b6cbf720SGianluca Guida * On entry: 94b6cbf720SGianluca Guida * r0 - dest address 95b6cbf720SGianluca Guida * r1 - byte to write 96b6cbf720SGianluca Guida * r2 - number of bytes to write 97b6cbf720SGianluca Guida * 98b6cbf720SGianluca Guida * On exit: 99b6cbf720SGianluca Guida * r0 - dest address 100b6cbf720SGianluca Guida */ 101b6cbf720SGianluca Guida#ifdef _BZERO 102b6cbf720SGianluca Guida/* LINTSTUB: Func: void bzero(void *, size_t) */ 103b6cbf720SGianluca GuidaENTRY(bzero) 104b6cbf720SGianluca Guida mov r3, #0x00 105b6cbf720SGianluca Guida#else 106b6cbf720SGianluca Guida/* LINTSTUB: Func: void *memset(void *, int, size_t) */ 107b6cbf720SGianluca GuidaENTRY(memset) 108b6cbf720SGianluca Guida and r3, r1, #0xff /* We deal with bytes */ 109b6cbf720SGianluca Guida mov r1, r2 110b6cbf720SGianluca Guida#endif 111b6cbf720SGianluca Guida cmp r1, #0x04 /* Do we have less than 4 bytes */ 112b6cbf720SGianluca Guida mov ip, r0 113b6cbf720SGianluca Guida blt .Lmemset_lessthanfour 114b6cbf720SGianluca Guida 115b6cbf720SGianluca Guida /* Ok first we will word align the address */ 116b6cbf720SGianluca Guida ands r2, ip, #0x03 /* Get the bottom two bits */ 117b6cbf720SGianluca Guida bne .Lmemset_wordunaligned /* The address is not word aligned */ 118b6cbf720SGianluca Guida 119b6cbf720SGianluca Guida /* We are now word aligned */ 120b6cbf720SGianluca Guida.Lmemset_wordaligned: 121b6cbf720SGianluca Guida#ifndef _BZERO 122b6cbf720SGianluca Guida orr r3, r3, r3, lsl #8 /* Extend value to 16-bits */ 123b6cbf720SGianluca Guida#endif 12484d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK 125b6cbf720SGianluca Guida tst ip, #0x04 /* Quad-align for Xscale */ 126b6cbf720SGianluca Guida#else 127b6cbf720SGianluca Guida cmp r1, #0x10 128b6cbf720SGianluca Guida#endif 129b6cbf720SGianluca Guida#ifndef _BZERO 130b6cbf720SGianluca Guida orr r3, r3, r3, lsl #16 /* Extend value to 32-bits */ 131b6cbf720SGianluca Guida#endif 13284d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK 133b6cbf720SGianluca Guida subne r1, r1, #0x04 /* Quad-align if necessary */ 134b6cbf720SGianluca Guida strne r3, [ip], #0x04 135b6cbf720SGianluca Guida cmp r1, #0x10 136b6cbf720SGianluca Guida#endif 137b6cbf720SGianluca Guida blt .Lmemset_loop4 /* If less than 16 then use words */ 138b6cbf720SGianluca Guida mov r2, r3 /* Duplicate data */ 139b6cbf720SGianluca Guida cmp r1, #0x80 /* If < 128 then skip the big loop */ 140b6cbf720SGianluca Guida blt .Lmemset_loop32 141b6cbf720SGianluca Guida 142b6cbf720SGianluca Guida /* Do 128 bytes at a time */ 143b6cbf720SGianluca Guida.Lmemset_loop128: 144b6cbf720SGianluca Guida subs r1, r1, #0x80 14584d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK 14684d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 14784d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 14884d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 14984d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 15084d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 15184d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 15284d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 15384d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 15484d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 15584d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 15684d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 15784d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 15884d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 15984d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 16084d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 16184d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 162b6cbf720SGianluca Guida#else 16384d9c625SLionel Sambuc stmiage ip!, {r2-r3} 16484d9c625SLionel Sambuc stmiage ip!, {r2-r3} 16584d9c625SLionel Sambuc stmiage ip!, {r2-r3} 16684d9c625SLionel Sambuc stmiage ip!, {r2-r3} 16784d9c625SLionel Sambuc stmiage ip!, {r2-r3} 16884d9c625SLionel Sambuc stmiage ip!, {r2-r3} 16984d9c625SLionel Sambuc stmiage ip!, {r2-r3} 17084d9c625SLionel Sambuc stmiage ip!, {r2-r3} 17184d9c625SLionel Sambuc stmiage ip!, {r2-r3} 17284d9c625SLionel Sambuc stmiage ip!, {r2-r3} 17384d9c625SLionel Sambuc stmiage ip!, {r2-r3} 17484d9c625SLionel Sambuc stmiage ip!, {r2-r3} 17584d9c625SLionel Sambuc stmiage ip!, {r2-r3} 17684d9c625SLionel Sambuc stmiage ip!, {r2-r3} 17784d9c625SLionel Sambuc stmiage ip!, {r2-r3} 17884d9c625SLionel Sambuc stmiage ip!, {r2-r3} 179b6cbf720SGianluca Guida#endif 180b6cbf720SGianluca Guida bgt .Lmemset_loop128 181b6cbf720SGianluca Guida RETc(eq) /* Zero length so just exit */ 182b6cbf720SGianluca Guida 183b6cbf720SGianluca Guida add r1, r1, #0x80 /* Adjust for extra sub */ 184b6cbf720SGianluca Guida 185b6cbf720SGianluca Guida /* Do 32 bytes at a time */ 186b6cbf720SGianluca Guida.Lmemset_loop32: 187b6cbf720SGianluca Guida subs r1, r1, #0x20 18884d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK 18984d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 19084d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 19184d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 19284d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 193b6cbf720SGianluca Guida#else 19484d9c625SLionel Sambuc stmiage ip!, {r2-r3} 19584d9c625SLionel Sambuc stmiage ip!, {r2-r3} 19684d9c625SLionel Sambuc stmiage ip!, {r2-r3} 19784d9c625SLionel Sambuc stmiage ip!, {r2-r3} 198b6cbf720SGianluca Guida#endif 199b6cbf720SGianluca Guida bgt .Lmemset_loop32 200b6cbf720SGianluca Guida RETc(eq) /* Zero length so just exit */ 201b6cbf720SGianluca Guida 202b6cbf720SGianluca Guida adds r1, r1, #0x10 /* Partially adjust for extra sub */ 203b6cbf720SGianluca Guida 204b6cbf720SGianluca Guida /* Deal with 16 bytes or more */ 20584d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK 20684d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 20784d9c625SLionel Sambuc strdge r2, r3, [ip], #0x08 208b6cbf720SGianluca Guida#else 20984d9c625SLionel Sambuc stmiage ip!, {r2-r3} 21084d9c625SLionel Sambuc stmiage ip!, {r2-r3} 211b6cbf720SGianluca Guida#endif 212b6cbf720SGianluca Guida RETc(eq) /* Zero length so just exit */ 213b6cbf720SGianluca Guida 214b6cbf720SGianluca Guida addlt r1, r1, #0x10 /* Possibly adjust for extra sub */ 215b6cbf720SGianluca Guida 216b6cbf720SGianluca Guida /* We have at least 4 bytes so copy as words */ 217b6cbf720SGianluca Guida.Lmemset_loop4: 218b6cbf720SGianluca Guida subs r1, r1, #0x04 219b6cbf720SGianluca Guida strge r3, [ip], #0x04 220b6cbf720SGianluca Guida bgt .Lmemset_loop4 221b6cbf720SGianluca Guida RETc(eq) /* Zero length so just exit */ 222b6cbf720SGianluca Guida 22384d9c625SLionel Sambuc#ifdef _ARM_ARCH_DWORD_OK 224b6cbf720SGianluca Guida /* Compensate for 64-bit alignment check */ 225b6cbf720SGianluca Guida adds r1, r1, #0x04 226b6cbf720SGianluca Guida RETc(eq) 227b6cbf720SGianluca Guida cmp r1, #2 228b6cbf720SGianluca Guida#else 229b6cbf720SGianluca Guida cmp r1, #-2 230b6cbf720SGianluca Guida#endif 231b6cbf720SGianluca Guida 232b6cbf720SGianluca Guida strb r3, [ip], #0x01 /* Set 1 byte */ 23384d9c625SLionel Sambuc strbge r3, [ip], #0x01 /* Set another byte */ 23484d9c625SLionel Sambuc strbgt r3, [ip] /* and a third */ 235b6cbf720SGianluca Guida RET /* Exit */ 236b6cbf720SGianluca Guida 237b6cbf720SGianluca Guida.Lmemset_wordunaligned: 238b6cbf720SGianluca Guida rsb r2, r2, #0x004 239b6cbf720SGianluca Guida strb r3, [ip], #0x01 /* Set 1 byte */ 240b6cbf720SGianluca Guida cmp r2, #0x02 24184d9c625SLionel Sambuc strbge r3, [ip], #0x01 /* Set another byte */ 242b6cbf720SGianluca Guida sub r1, r1, r2 24384d9c625SLionel Sambuc strbgt r3, [ip], #0x01 /* and a third */ 244b6cbf720SGianluca Guida cmp r1, #0x04 /* More than 4 bytes left? */ 245b6cbf720SGianluca Guida bge .Lmemset_wordaligned /* Yup */ 246b6cbf720SGianluca Guida 247b6cbf720SGianluca Guida.Lmemset_lessthanfour: 248b6cbf720SGianluca Guida cmp r1, #0x00 249b6cbf720SGianluca Guida RETc(eq) /* Zero length so exit */ 250b6cbf720SGianluca Guida strb r3, [ip], #0x01 /* Set 1 byte */ 251b6cbf720SGianluca Guida cmp r1, #0x02 25284d9c625SLionel Sambuc strbge r3, [ip], #0x01 /* Set another byte */ 25384d9c625SLionel Sambuc strbgt r3, [ip] /* and a third */ 254b6cbf720SGianluca Guida RET /* Exit */ 25584d9c625SLionel Sambuc#ifdef _BZERO 25684d9c625SLionel SambucEND(bzero) 25784d9c625SLionel Sambuc#else 25884d9c625SLionel SambucEND(memset) 25984d9c625SLionel Sambuc#endif 260