Super User's BSD Cross Reference: /OpenBSD/sys/lib/libkern/arch/arm/memset.S

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

AltStyle によって変換されたページ (->オリジナル) /