1*c6b709f5Sjsg/* $OpenBSD: memset.S,v 1.4 2015/06/08 14:22:05 jsg Exp $ */ 27c0511a1Sdrahn/* $NetBSD: memset.S,v 1.1 2000/12/29 20:51:57 bjh21 Exp $ */ 37c0511a1Sdrahn 47c0511a1Sdrahn/* 57c0511a1Sdrahn * Copyright (c) 1995 Mark Brinicombe. 67c0511a1Sdrahn * All rights reserved. 77c0511a1Sdrahn * 87c0511a1Sdrahn * Redistribution and use in source and binary forms, with or without 97c0511a1Sdrahn * modification, are permitted provided that the following conditions 107c0511a1Sdrahn * are met: 117c0511a1Sdrahn * 1. Redistributions of source code must retain the above copyright 127c0511a1Sdrahn * notice, this list of conditions and the following disclaimer. 137c0511a1Sdrahn * 2. Redistributions in binary form must reproduce the above copyright 147c0511a1Sdrahn * notice, this list of conditions and the following disclaimer in the 157c0511a1Sdrahn * documentation and/or other materials provided with the distribution. 167c0511a1Sdrahn * 3. All advertising materials mentioning features or use of this software 177c0511a1Sdrahn * must display the following acknowledgement: 187c0511a1Sdrahn * This product includes software developed by Mark Brinicombe. 197c0511a1Sdrahn * 4. The name of the company nor the name of the author may be used to 207c0511a1Sdrahn * endorse or promote products derived from this software without specific 217c0511a1Sdrahn * prior written permission. 227c0511a1Sdrahn * 237c0511a1Sdrahn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 247c0511a1Sdrahn * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 257c0511a1Sdrahn * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 267c0511a1Sdrahn * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 277c0511a1Sdrahn * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 287c0511a1Sdrahn * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 297c0511a1Sdrahn * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 307c0511a1Sdrahn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 317c0511a1Sdrahn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 327c0511a1Sdrahn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 337c0511a1Sdrahn * SUCH DAMAGE. 347c0511a1Sdrahn */ 357c0511a1Sdrahn 367c0511a1Sdrahn#include <machine/asm.h> 377c0511a1Sdrahn 387c0511a1Sdrahn/* 397c0511a1Sdrahn * Sets a block of memory to the specified value 407c0511a1Sdrahn * 417c0511a1Sdrahn * On entry: 427c0511a1Sdrahn * r0 - dest address 437c0511a1Sdrahn * r1 - byte to write 447c0511a1Sdrahn * r2 - number of bytes to write 457c0511a1Sdrahn * 467c0511a1Sdrahn * On exit: 477c0511a1Sdrahn * r0 - dest address 487c0511a1Sdrahn */ 497c0511a1Sdrahn 50*c6b709f5Sjsg.syntax unified 51*c6b709f5Sjsg 527c0511a1SdrahnENTRY(memset) 537c0511a1Sdrahn stmfd sp!, {r0} /* Remember address for return value */ 547c0511a1Sdrahn and r1, r1, #0x000000ff /* We write bytes */ 557c0511a1Sdrahn 567c0511a1Sdrahn cmp r2, #0x00000004 /* Do we have less than 4 bytes */ 577c0511a1Sdrahn blt Lmemset_lessthanfour 587c0511a1Sdrahn 597c0511a1Sdrahn /* Ok first we will word align the address */ 607c0511a1Sdrahn 617c0511a1Sdrahn ands r3, r0, #0x00000003 /* Get the bottom two bits */ 627c0511a1Sdrahn beq Lmemset_addraligned /* The address is word aligned */ 637c0511a1Sdrahn 647c0511a1Sdrahn rsb r3, r3, #0x00000004 657c0511a1Sdrahn sub r2, r2, r3 667c0511a1Sdrahn cmp r3, #0x00000002 677c0511a1Sdrahn strb r1, [r0], #0x0001 /* Set 1 byte */ 68*c6b709f5Sjsg strbge r1, [r0], #0x0001 /* Set another byte */ 69*c6b709f5Sjsg strbgt r1, [r0], #0x0001 /* and a third */ 707c0511a1Sdrahn 717c0511a1Sdrahn cmp r2, #0x00000004 727c0511a1Sdrahn blt Lmemset_lessthanfour 737c0511a1Sdrahn 747c0511a1Sdrahn /* Now we must be word aligned */ 757c0511a1Sdrahn 767c0511a1SdrahnLmemset_addraligned: 777c0511a1Sdrahn 787c0511a1Sdrahn orr r3, r1, r1, lsl #8 /* Repeat the byte into a word */ 797c0511a1Sdrahn orr r3, r3, r3, lsl #16 807c0511a1Sdrahn 817c0511a1Sdrahn /* We know we have at least 4 bytes ... */ 827c0511a1Sdrahn 837c0511a1Sdrahn cmp r2, #0x00000020 /* If less than 32 then use words */ 847c0511a1Sdrahn blt Lmemset_lessthan32 857c0511a1Sdrahn 867c0511a1Sdrahn /* We have at least 32 so lets use quad words */ 877c0511a1Sdrahn 887c0511a1Sdrahn stmfd sp!, {r4-r6} /* Store registers */ 897c0511a1Sdrahn mov r4, r3 /* Duplicate data */ 907c0511a1Sdrahn mov r5, r3 917c0511a1Sdrahn mov r6, r3 927c0511a1Sdrahn 937c0511a1SdrahnLmemset_loop16: 947c0511a1Sdrahn stmia r0!, {r3-r6} /* Store 16 bytes */ 957c0511a1Sdrahn sub r2, r2, #0x00000010 /* Adjust count */ 967c0511a1Sdrahn cmp r2, #0x00000010 /* Still got at least 16 bytes ? */ 977c0511a1Sdrahn bgt Lmemset_loop16 987c0511a1Sdrahn 997c0511a1Sdrahn ldmfd sp!, {r4-r6} /* Restore registers */ 1007c0511a1Sdrahn 1017c0511a1Sdrahn /* Do we need to set some words as well ? */ 1027c0511a1Sdrahn 1037c0511a1Sdrahn cmp r2, #0x00000004 1047c0511a1Sdrahn blt Lmemset_lessthanfour 1057c0511a1Sdrahn 1067c0511a1Sdrahn /* Have either less than 16 or less than 32 depending on route taken */ 1077c0511a1Sdrahn 1087c0511a1SdrahnLmemset_lessthan32: 1097c0511a1Sdrahn 1107c0511a1Sdrahn /* We have at least 4 bytes so copy as words */ 1117c0511a1Sdrahn 1127c0511a1SdrahnLmemset_loop4: 1137c0511a1Sdrahn str r3, [r0], #0x0004 1147c0511a1Sdrahn sub r2, r2, #0x0004 1157c0511a1Sdrahn cmp r2, #0x00000004 1167c0511a1Sdrahn bge Lmemset_loop4 1177c0511a1Sdrahn 1187c0511a1SdrahnLmemset_lessthanfour: 1197c0511a1Sdrahn cmp r2, #0x00000000 120*c6b709f5Sjsg ldmfdeq sp!, {r0} 1217c0511a1Sdrahn moveq pc, lr /* Zero length so exit */ 1227c0511a1Sdrahn 1237c0511a1Sdrahn cmp r2, #0x00000002 1247c0511a1Sdrahn strb r1, [r0], #0x0001 /* Set 1 byte */ 125*c6b709f5Sjsg strbge r1, [r0], #0x0001 /* Set another byte */ 126*c6b709f5Sjsg strbgt r1, [r0], #0x0001 /* and a third */ 1277c0511a1Sdrahn 1287c0511a1Sdrahn ldmfd sp!, {r0} 1297c0511a1Sdrahn mov pc, lr /* Exit */ 130