blob: 102d54128dfcf5d099968115366f16c057640673 [file] [log] [blame]
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080028
Henrik Smiding884e4f82010-11-05 15:07:53 +010029#include <machine/cpu-features.h>
Kenny Root420878c2011-02-16 11:55:58 -080030#include <machine/asm.h>
Henrik Smiding884e4f82010-11-05 15:07:53 +010031
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080032 /*
33 * Optimized memset() for ARM.
34 *
35 * memset() returns its first argument.
36 */
Henrik Smiding884e4f82010-11-05 15:07:53 +010037
38#if defined(__ARM_NEON__)
39 .fpu neon
40#endif
41
Kenny Root420878c2011-02-16 11:55:58 -080042ENTRY(bzero)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080043 mov r2, r1
44 mov r1, #0
Elliott Hughes67195002013-02-13 15:12:32 -080045 // Fall through to memset...
Kenny Root420878c2011-02-16 11:55:58 -080046END(bzero)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080047
Kenny Root420878c2011-02-16 11:55:58 -080048ENTRY(memset)
Henrik Smiding884e4f82010-11-05 15:07:53 +010049#if defined(__ARM_NEON__)
50
51#ifdef NEON_MEMSET_DIVIDER
52 cmp r2, #NEON_MEMSET_DIVIDER
53 bhi 11f
54#endif
55 .save {r0}
56 stmfd sp!, {r0}
57
58 vdup.8 q0, r1
59
60#ifndef NEON_UNALIGNED_ACCESS
61 /* do we have at least 16-bytes to write (needed for alignment below) */
62 cmp r2, #16
63 blo 3f
64
65 /* align destination to 16 bytes for the write-buffer */
66 rsb r3, r0, #0
67 ands r3, r3, #0xF
68 beq 2f
69
70 /* write up to 15-bytes (count in r3) */
71 sub r2, r2, r3
72 movs ip, r3, lsl #31
73 strmib r1, [r0], #1
74 strcsb r1, [r0], #1
75 strcsb r1, [r0], #1
76 movs ip, r3, lsl #29
77 bge 1f
78
79 // writes 4 bytes, 32-bits aligned
80 vst1.32 {d0[0]}, [r0, :32]!
811: bcc 2f
82
83 // writes 8 bytes, 64-bits aligned
84 vst1.8 {d0}, [r0, :64]!
852:
86#endif
87 /* make sure we have at least 32 bytes to write */
88 subs r2, r2, #32
89 blo 2f
90 vmov q1, q0
91
921: /* The main loop writes 32 bytes at a time */
93 subs r2, r2, #32
94#ifndef NEON_UNALIGNED_ACCESS
95 vst1.8 {d0 - d3}, [r0, :128]!
96#else
97 vst1.8 {d0 - d3}, [r0]!
98#endif
99 bhs 1b
100
1012: /* less than 32 left */
102 add r2, r2, #32
103 tst r2, #0x10
104 beq 3f
105
106 // writes 16 bytes, 128-bits aligned
107#ifndef NEON_UNALIGNED_ACCESS
108 vst1.8 {d0, d1}, [r0, :128]!
109#else
110 vst1.8 {d0, d1}, [r0]!
111#endif
1123: /* write up to 15-bytes (count in r2) */
113 movs ip, r2, lsl #29
114 bcc 1f
115 vst1.8 {d0}, [r0]!
1161: bge 2f
117 vst1.32 {d0[0]}, [r0]!
1182: movs ip, r2, lsl #31
119 strmib r1, [r0], #1
120 strcsb r1, [r0], #1
121 strcsb r1, [r0], #1
122 ldmfd sp!, {r0}
123 bx lr
12411:
125#endif
126
127 /*
128 * Optimized memset() for ARM.
129 *
130 * memset() returns its first argument.
131 */
132
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800133 /* compute the offset to align the destination
134 * offset = (4-(src&3))&3 = -src & 3
135 */
Henrik Smiding884e4f82010-11-05 15:07:53 +0100136
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800137 .save {r0, r4-r7, lr}
138 stmfd sp!, {r0, r4-r7, lr}
139 rsb r3, r0, #0
140 ands r3, r3, #3
141 cmp r3, r2
142 movhi r3, r2
143
144 /* splat r1 */
145 mov r1, r1, lsl #24
146 orr r1, r1, r1, lsr #8
147 orr r1, r1, r1, lsr #16
148
149 movs r12, r3, lsl #31
150 strcsb r1, [r0], #1 /* can't use strh (alignment unknown) */
151 strcsb r1, [r0], #1
152 strmib r1, [r0], #1
153 subs r2, r2, r3
154 ldmlsfd sp!, {r0, r4-r7, lr} /* return */
155 bxls lr
156
157 /* align the destination to a cache-line */
158 mov r12, r1
159 mov lr, r1
160 mov r4, r1
161 mov r5, r1
162 mov r6, r1
163 mov r7, r1
Henrik Smiding884e4f82010-11-05 15:07:53 +0100164
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800165 rsb r3, r0, #0
166 ands r3, r3, #0x1C
Mathias Agopian7e7d6c42009-10-19 16:34:38 -0700167 beq 3f
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800168 cmp r3, r2
169 andhi r3, r2, #0x1C
170 sub r2, r2, r3
171
Henrik Smiding884e4f82010-11-05 15:07:53 +0100172 /* conditionally writes 0 to 7 words (length in r3) */
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800173 movs r3, r3, lsl #28
174 stmcsia r0!, {r1, lr}
175 stmcsia r0!, {r1, lr}
176 stmmiia r0!, {r1, lr}
177 movs r3, r3, lsl #2
178 strcs r1, [r0], #4
179
Mathias Agopian7e7d6c42009-10-19 16:34:38 -07001803:
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800181 subs r2, r2, #32
182 mov r3, r1
183 bmi 2f
1841: subs r2, r2, #32
185 stmia r0!, {r1,r3,r4,r5,r6,r7,r12,lr}
186 bhs 1b
1872: add r2, r2, #32
188
Henrik Smiding884e4f82010-11-05 15:07:53 +0100189 /* conditionally stores 0 to 31 bytes */
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800190 movs r2, r2, lsl #28
191 stmcsia r0!, {r1,r3,r12,lr}
192 stmmiia r0!, {r1, lr}
193 movs r2, r2, lsl #2
194 strcs r1, [r0], #4
195 strmih r1, [r0], #2
196 movs r2, r2, lsl #2
197 strcsb r1, [r0]
198 ldmfd sp!, {r0, r4-r7, lr}
199 bx lr
Kenny Root420878c2011-02-16 11:55:58 -0800200END(memset)