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