summaryrefslogtreecommitdiff
path: root/lib/libc/arch/arm/string/memset.S
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2004-02-01 05:30:42 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2004-02-01 05:30:42 +0000
commitbbe153543609373d88dea33ea360b4448bafae68 (patch)
tree069e4042efecb6d85e76ba55bf69db104d240acf /lib/libc/arch/arm/string/memset.S
parentc1a6705a877c9497fa15fa79ad08373d82634725 (diff)
arm libc support. From NetBSD. currently supports softfloat.
Diffstat (limited to 'lib/libc/arch/arm/string/memset.S')
-rw-r--r--lib/libc/arch/arm/string/memset.S126
1 files changed, 126 insertions, 0 deletions
diff --git a/lib/libc/arch/arm/string/memset.S b/lib/libc/arch/arm/string/memset.S
new file mode 100644
index 00000000000..564c5d9e219
--- /dev/null
+++ b/lib/libc/arch/arm/string/memset.S
@@ -0,0 +1,126 @@
+/* $NetBSD: memset.S,v 1.3 2003/04/05 23:08:52 bjh21 Exp $ */
+
+/*
+ * Copyright (c) 1995 Mark Brinicombe.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mark Brinicombe.
+ * 4. The name of the company nor the name of the author may be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+/*
+ * Sets a block of memory to the specified value
+ *
+ * On entry:
+ * r0 - dest address
+ * r1 - byte to write
+ * r2 - number of bytes to write
+ *
+ * On exit:
+ * r0 - dest address
+ */
+
+ENTRY(memset)
+ stmfd sp!, {r0} /* Remember address for return value */
+ and r1, r1, #0x000000ff /* We write bytes */
+
+ cmp r2, #0x00000004 /* Do we have less than 4 bytes */
+ blt .Lmemset_lessthanfour
+
+ /* Ok first we will word align the address */
+
+ ands r3, r0, #0x00000003 /* Get the bottom two bits */
+ beq .Lmemset_addraligned /* The address is word aligned */
+
+ rsb r3, r3, #0x00000004
+ sub r2, r2, r3
+ cmp r3, #0x00000002
+ strb r1, [r0], #0x0001 /* Set 1 byte */
+ strgeb r1, [r0], #0x0001 /* Set another byte */
+ strgtb r1, [r0], #0x0001 /* and a third */
+
+ cmp r2, #0x00000004
+ blt .Lmemset_lessthanfour
+
+ /* Now we must be word aligned */
+
+.Lmemset_addraligned:
+
+ orr r3, r1, r1, lsl #8 /* Repeat the byte into a word */
+ orr r3, r3, r3, lsl #16
+
+ /* We know we have at least 4 bytes ... */
+
+ cmp r2, #0x00000020 /* If less than 32 then use words */
+ blt .Lmemset_lessthan32
+
+ /* We have at least 32 so lets use quad words */
+
+ stmfd sp!, {r4-r6} /* Store registers */
+ mov r4, r3 /* Duplicate data */
+ mov r5, r3
+ mov r6, r3
+
+.Lmemset_loop16:
+ stmia r0!, {r3-r6} /* Store 16 bytes */
+ sub r2, r2, #0x00000010 /* Adjust count */
+ cmp r2, #0x00000010 /* Still got at least 16 bytes ? */
+ bgt .Lmemset_loop16
+
+ ldmfd sp!, {r4-r6} /* Restore registers */
+
+ /* Do we need to set some words as well ? */
+
+ cmp r2, #0x00000004
+ blt .Lmemset_lessthanfour
+
+ /* Have either less than 16 or less than 32 depending on route taken */
+
+.Lmemset_lessthan32:
+
+ /* We have at least 4 bytes so copy as words */
+
+.Lmemset_loop4:
+ str r3, [r0], #0x0004
+ sub r2, r2, #0x0004
+ cmp r2, #0x00000004
+ bge .Lmemset_loop4
+
+.Lmemset_lessthanfour:
+ cmp r2, #0x00000000
+ ldmeqfd sp!, {r0}
+ moveq pc, lr /* Zero length so exit */
+
+ cmp r2, #0x00000002
+ strb r1, [r0], #0x0001 /* Set 1 byte */
+ strgeb r1, [r0], #0x0001 /* Set another byte */
+ strgtb r1, [r0], #0x0001 /* and a third */
+
+ ldmfd sp!, {r0}
+ mov pc, lr /* Exit */