1*ea6088e7Sguenther/* $OpenBSD: memset.S,v 1.6 2017/11/29 05:13:57 guenther Exp $ */ 2d987040fSdrahn/* $NetBSD: memset.S,v 1.3 2003/04/05 23:08:52 bjh21 Exp $ */ 3d987040fSdrahn 4d987040fSdrahn/* 5d987040fSdrahn * Copyright (c) 1995 Mark Brinicombe. 6d987040fSdrahn * All rights reserved. 7d987040fSdrahn * 8d987040fSdrahn * Redistribution and use in source and binary forms, with or without 9d987040fSdrahn * modification, are permitted provided that the following conditions 10d987040fSdrahn * are met: 11d987040fSdrahn * 1. Redistributions of source code must retain the above copyright 12d987040fSdrahn * notice, this list of conditions and the following disclaimer. 13d987040fSdrahn * 2. Redistributions in binary form must reproduce the above copyright 14d987040fSdrahn * notice, this list of conditions and the following disclaimer in the 15d987040fSdrahn * documentation and/or other materials provided with the distribution. 16d987040fSdrahn * 3. All advertising materials mentioning features or use of this software 17d987040fSdrahn * must display the following acknowledgement: 18d987040fSdrahn * This product includes software developed by Mark Brinicombe. 19d987040fSdrahn * 4. The name of the company nor the name of the author may be used to 20d987040fSdrahn * endorse or promote products derived from this software without specific 21d987040fSdrahn * prior written permission. 22d987040fSdrahn * 23d987040fSdrahn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 24d987040fSdrahn * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25d987040fSdrahn * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26d987040fSdrahn * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27d987040fSdrahn * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28d987040fSdrahn * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29d987040fSdrahn * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30d987040fSdrahn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31d987040fSdrahn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32d987040fSdrahn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33d987040fSdrahn * SUCH DAMAGE. 34d987040fSdrahn */ 35d987040fSdrahn 3638848718Sguenther#include "DEFS.h" 37d987040fSdrahn 38d987040fSdrahn/* 39d987040fSdrahn * Sets a block of memory to the specified value 40d987040fSdrahn * 41d987040fSdrahn * On entry: 42d987040fSdrahn * r0 - dest address 43d987040fSdrahn * r1 - byte to write 44d987040fSdrahn * r2 - number of bytes to write 45d987040fSdrahn * 46d987040fSdrahn * On exit: 47d987040fSdrahn * r0 - dest address 48d987040fSdrahn */ 49d987040fSdrahn 50c6b709f5Sjsg.syntax unified 51c6b709f5Sjsg 52d987040fSdrahnENTRY(memset) 53d987040fSdrahn stmfd sp!, {r0} /* Remember address for return value */ 54d987040fSdrahn and r1, r1, #0x000000ff /* We write bytes */ 55d987040fSdrahn 56d987040fSdrahn cmp r2, #0x00000004 /* Do we have less than 4 bytes */ 57d987040fSdrahn blt .Lmemset_lessthanfour 58d987040fSdrahn 59d987040fSdrahn /* Ok first we will word align the address */ 60d987040fSdrahn 61d987040fSdrahn ands r3, r0, #0x00000003 /* Get the bottom two bits */ 62d987040fSdrahn beq .Lmemset_addraligned /* The address is word aligned */ 63d987040fSdrahn 64d987040fSdrahn rsb r3, r3, #0x00000004 65d987040fSdrahn sub r2, r2, r3 66d987040fSdrahn cmp r3, #0x00000002 67d987040fSdrahn strb r1, [r0], #0x0001 /* Set 1 byte */ 68c6b709f5Sjsg strbge r1, [r0], #0x0001 /* Set another byte */ 69c6b709f5Sjsg strbgt r1, [r0], #0x0001 /* and a third */ 70d987040fSdrahn 71d987040fSdrahn cmp r2, #0x00000004 72d987040fSdrahn blt .Lmemset_lessthanfour 73d987040fSdrahn 74d987040fSdrahn /* Now we must be word aligned */ 75d987040fSdrahn 76d987040fSdrahn.Lmemset_addraligned: 77d987040fSdrahn 78d987040fSdrahn orr r3, r1, r1, lsl #8 /* Repeat the byte into a word */ 79d987040fSdrahn orr r3, r3, r3, lsl #16 80d987040fSdrahn 81d987040fSdrahn /* We know we have at least 4 bytes ... */ 82d987040fSdrahn 83d987040fSdrahn cmp r2, #0x00000020 /* If less than 32 then use words */ 84d987040fSdrahn blt .Lmemset_lessthan32 85d987040fSdrahn 86d987040fSdrahn /* We have at least 32 so lets use quad words */ 87d987040fSdrahn 88d987040fSdrahn stmfd sp!, {r4-r6} /* Store registers */ 89d987040fSdrahn mov r4, r3 /* Duplicate data */ 90d987040fSdrahn mov r5, r3 91d987040fSdrahn mov r6, r3 92d987040fSdrahn 93d987040fSdrahn.Lmemset_loop16: 94d987040fSdrahn stmia r0!, {r3-r6} /* Store 16 bytes */ 95d987040fSdrahn sub r2, r2, #0x00000010 /* Adjust count */ 96d987040fSdrahn cmp r2, #0x00000010 /* Still got at least 16 bytes ? */ 97d987040fSdrahn bgt .Lmemset_loop16 98d987040fSdrahn 99d987040fSdrahn ldmfd sp!, {r4-r6} /* Restore registers */ 100d987040fSdrahn 101d987040fSdrahn /* Do we need to set some words as well ? */ 102d987040fSdrahn 103d987040fSdrahn cmp r2, #0x00000004 104d987040fSdrahn blt .Lmemset_lessthanfour 105d987040fSdrahn 106d987040fSdrahn /* Have either less than 16 or less than 32 depending on route taken */ 107d987040fSdrahn 108d987040fSdrahn.Lmemset_lessthan32: 109d987040fSdrahn 110d987040fSdrahn /* We have at least 4 bytes so copy as words */ 111d987040fSdrahn 112d987040fSdrahn.Lmemset_loop4: 113d987040fSdrahn str r3, [r0], #0x0004 114d987040fSdrahn sub r2, r2, #0x0004 115d987040fSdrahn cmp r2, #0x00000004 116d987040fSdrahn bge .Lmemset_loop4 117d987040fSdrahn 118d987040fSdrahn.Lmemset_lessthanfour: 119d987040fSdrahn cmp r2, #0x00000000 120c6b709f5Sjsg ldmfdeq sp!, {r0} 121d987040fSdrahn moveq pc, lr /* Zero length so exit */ 122d987040fSdrahn 123d987040fSdrahn cmp r2, #0x00000002 124d987040fSdrahn strb r1, [r0], #0x0001 /* Set 1 byte */ 125c6b709f5Sjsg strbge r1, [r0], #0x0001 /* Set another byte */ 126c6b709f5Sjsg strbgt r1, [r0], #0x0001 /* and a third */ 127d987040fSdrahn 128d987040fSdrahn ldmfd sp!, {r0} 129d987040fSdrahn mov pc, lr /* Exit */ 130*ea6088e7SguentherEND_BUILTIN(memset) 131