/* $NetBSD: memset.S,v 1.4 2003/10/14 07:51:45 scw Exp $ */12/*3* Copyright 2003 Wasabi Systems, Inc.4* All rights reserved.5*6* Written by Steve C. Woodford for Wasabi Systems, Inc.7*8* Redistribution and use in source and binary forms, with or without9* modification, are permitted provided that the following conditions10* are met:11* 1. Redistributions of source code must retain the above copyright12* notice, this list of conditions and the following disclaimer.13* 2. Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in the15* documentation and/or other materials provided with the distribution.16* 3. All advertising materials mentioning features or use of this software17* must display the following acknowledgement:18* This product includes software developed for the NetBSD Project by19* Wasabi Systems, Inc.20* 4. The name of Wasabi Systems, Inc. may not be used to endorse21* or promote products derived from this software without specific prior22* written permission.23*24* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND25* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED26* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR27* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC28* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR29* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF30* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS31* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN32* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)33* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE34* POSSIBILITY OF SUCH DAMAGE.35*/36/*37* Copyright (c) 1995 Mark Brinicombe.38* All rights reserved.39*40* Redistribution and use in source and binary forms, with or without41* modification, are permitted provided that the following conditions42* are met:43* 1. Redistributions of source code must retain the above copyright44* notice, this list of conditions and the following disclaimer.45* 2. Redistributions in binary form must reproduce the above copyright46* notice, this list of conditions and the following disclaimer in the47* documentation and/or other materials provided with the distribution.48* 3. All advertising materials mentioning features or use of this software49* must display the following acknowledgement:50* This product includes software developed by Mark Brinicombe.51* 4. The name of the company nor the name of the author may be used to52* endorse or promote products derived from this software without specific53* prior written permission.54*55* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED56* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF57* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.58* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,59* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES60* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR61* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)62* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT63* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY64* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF65* SUCH DAMAGE.66*/6768#include <machine/asm.h>69.syntax unified7071/*72* memset: Sets a block of memory to the specified value73*74* On entry:75* r0 - dest address76* r1 - byte to write77* r2 - number of bytes to write78*79* On exit:80* r0 - dest address81*/82#ifdef _BZERO83/* LINTSTUB: Func: void bzero(void *, size_t) */84ENTRY(bzero)85mov r3, #0x0086#else87/* LINTSTUB: Func: void *memset(void *, int, size_t) */88ENTRY(memset)89and r3, r1, #0xff /* We deal with bytes */90mov r1, r291#endif92cmp r1, #0x04 /* Do we have less than 4 bytes */93mov ip, r094blt .Lmemset_lessthanfour9596/* Ok first we will word align the address */97ands r2, ip, #0x03 /* Get the bottom two bits */98bne .Lmemset_wordunaligned /* The address is not word aligned */99100/* We are now word aligned */101.Lmemset_wordaligned:102#ifndef _BZERO103orr r3, r3, r3, lsl #8 /* Extend value to 16-bits */104#endif105tst ip, #0x04 /* Quad-align for armv5e */106#ifndef _BZERO107orr r3, r3, r3, lsl #16 /* Extend value to 32-bits */108#endif109itt ne110subne r1, r1, #0x04 /* Quad-align if necessary */111strne r3, [ip], #0x04112cmp r1, #0x10113blt .Lmemset_loop4 /* If less than 16 then use words */114mov r2, r3 /* Duplicate data */115cmp r1, #0x80 /* If < 128 then skip the big loop */116blt .Lmemset_loop32117118/* Do 128 bytes at a time */119.Lmemset_loop128:120subs r1, r1, #0x80121itttt ge122strdge r2, [ip], #0x08123strdge r2, [ip], #0x08124strdge r2, [ip], #0x08125strdge r2, [ip], #0x08126itttt ge127strdge r2, [ip], #0x08128strdge r2, [ip], #0x08129strdge r2, [ip], #0x08130strdge r2, [ip], #0x08131itttt ge132strdge r2, [ip], #0x08133strdge r2, [ip], #0x08134strdge r2, [ip], #0x08135strdge r2, [ip], #0x08136itttt ge137strdge r2, [ip], #0x08138strdge r2, [ip], #0x08139strdge r2, [ip], #0x08140strdge r2, [ip], #0x08141bgt .Lmemset_loop128142it eq143RETeq /* Zero length so just exit */144145add r1, r1, #0x80 /* Adjust for extra sub */146147/* Do 32 bytes at a time */148.Lmemset_loop32:149subs r1, r1, #0x20150itttt ge151strdge r2, [ip], #0x08152strdge r2, [ip], #0x08153strdge r2, [ip], #0x08154strdge r2, [ip], #0x08155bgt .Lmemset_loop32156it eq157RETeq /* Zero length so just exit */158159adds r1, r1, #0x10 /* Partially adjust for extra sub */160161/* Deal with 16 bytes or more */162itt ge163strdge r2, [ip], #0x08164strdge r2, [ip], #0x08165it eq166RETeq /* Zero length so just exit */167168it lt169addlt r1, r1, #0x10 /* Possibly adjust for extra sub */170171/* We have at least 4 bytes so copy as words */172.Lmemset_loop4:173subs r1, r1, #0x04174it ge175strge r3, [ip], #0x04176bgt .Lmemset_loop4177it eq178RETeq /* Zero length so just exit */179180/* Compensate for 64-bit alignment check */181adds r1, r1, #0x04182it eq183RETeq184cmp r1, #2185186strb r3, [ip], #0x01 /* Set 1 byte */187it ge188strbge r3, [ip], #0x01 /* Set another byte */189it gt190strbgt r3, [ip] /* and a third */191RET /* Exit */192193.Lmemset_wordunaligned:194rsb r2, r2, #0x004195strb r3, [ip], #0x01 /* Set 1 byte */196cmp r2, #0x02197it ge198strbge r3, [ip], #0x01 /* Set another byte */199sub r1, r1, r2200it gt201strbgt r3, [ip], #0x01 /* and a third */202cmp r1, #0x04 /* More than 4 bytes left? */203it ge204bge .Lmemset_wordaligned /* Yup */205206.Lmemset_lessthanfour:207cmp r1, #0x00208it eq209RETeq /* Zero length so exit */210strb r3, [ip], #0x01 /* Set 1 byte */211cmp r1, #0x02212it ge213strbge r3, [ip], #0x01 /* Set another byte */214it gt215strbgt r3, [ip] /* and a third */216RET /* Exit */217#ifdef _BZERO218END(bzero)219#else220END(memset)221#endif222223.section .note.GNU-stack,"",%progbits224225226