1
/* Copyright (c) 2012, Linaro Limited
4
Redistribution and use in source and binary forms, with or without
5
modification, are permitted provided that the following conditions are met:
6
* Redistributions of source code must retain the above copyright
7
notice, this list of conditions and the following disclaimer.
8
* Redistributions in binary form must reproduce the above copyright
9
notice, this list of conditions and the following disclaimer in the
10
documentation and/or other materials provided with the distribution.
11
* Neither the name of the Linaro nor the
12
names of its contributors may be used to endorse or promote products
13
derived from this software without specific prior written permission.
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 FOR
18
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
35
/* By default we assume that the DC instruction can be used to zero
36
data blocks more efficiently. In some circumstances this might be
37
unsafe, for example in an asymmetric multiprocessor environment with
38
different DC clear lengths (neither the upper nor lower lengths are
39
safe to use). The feature can be disabled by defining DONT_USE_DC.
41
If code may be run in a virtualized environment, then define
42
MAYBE_VIRT. This will cause the code to cache the system register
43
values rather than re-reading them each call. */
62
.macro def_fn f p2align=0
70
def_fn memset p2align=6
72
mov dst, dstin /* Preserve return value. */
77
orr A_lw, A_lw, A_lw, lsl #8
78
orr A_lw, A_lw, A_lw, lsl #16
79
orr A_l, A_l, A_l, lsl #32
87
ands tmp1, count, #0x30
93
stp A_l, A_l, [dst, #-48]
95
stp A_l, A_l, [dst, #-32]
97
stp A_l, A_l, [dst, #-16]
100
and count, count, #15
102
stp A_l, A_l, [dst, #-16] /* Repeat some/all of last store. */
106
/* Set up to 15 bytes. Does not assume earlier memory
122
/* Critical loop. Start at a new cache line boundary. Assuming
123
* 64 bytes per line, this ensures the entire loop is in one line. */
129
/* Bring DST to 128-bit (16-byte) alignment. We know that there's
130
* more than that to set, so we simply store 16 bytes and advance by
131
* the amount required to reach alignment. */
132
sub count, count, tmp2
135
/* There may be less than 63 bytes to go now. */
139
sub dst, dst, #16 /* Pre-bias. */
140
sub count, count, #64
142
stp A_l, A_l, [dst, #16]
143
stp A_l, A_l, [dst, #32]
144
stp A_l, A_l, [dst, #48]
145
stp A_l, A_l, [dst, #64]!
146
subs count, count, #64
154
/* For zeroing memory, check to see if we can use the ZVA feature to
155
* zero entire 'cache' lines. */
159
b.le .Ltail_maybe_tiny
163
sub count, count, tmp2
169
/* For zeroing small amounts of memory, it's not worth setting up
170
* the line-clear code. */
174
/* For efficiency when virtualized, we cache the ZVA capability. */
175
adrp tmp2, .Lcache_clear
176
ldr zva_len, [tmp2, #:lo12:.Lcache_clear]
177
tbnz zva_len, #31, .Lnot_short
178
cbnz zva_len, .Lzero_by_line
181
/* ZVA not available. Remember this for next time. */
183
str zva_len, [tmp2, #:lo12:.Lcache_clear]
187
and zva_len, tmp1w, #15 /* Safety: other bits reserved. */
188
lsl zva_len, tmp3w, zva_len
189
str zva_len, [tmp2, #:lo12:.Lcache_clear]
192
tbnz tmp1, #4, .Lnot_short
194
and zva_len, tmp1w, #15 /* Safety: other bits reserved. */
195
lsl zva_len, tmp3w, zva_len
199
/* Compute how far we need to go to become suitably aligned. We're
200
* already at quad-word alignment. */
202
b.lt .Lnot_short /* Not enough to reach alignment. */
203
sub zva_bits_x, zva_len_x, #1
205
ands tmp2, tmp2, zva_bits_x
206
b.eq 1f /* Already aligned. */
207
/* Not aligned, check that there's enough to copy after alignment. */
208
sub tmp1, count, tmp2
210
ccmp tmp1, zva_len_x, #8, ge /* NZCV=0b1000 */
212
/* We know that there's at least 64 bytes to zero and that it's safe
213
* to overrun by 64 bytes. */
217
stp A_l, A_l, [dst, #16]
218
stp A_l, A_l, [dst, #32]
220
stp A_l, A_l, [dst, #48]
223
/* We've overrun a bit, so adjust dst downwards. */
226
sub count, count, zva_len_x
229
add dst, dst, zva_len_x
230
subs count, count, zva_len_x
232
ands count, count, zva_bits_x
233
b.ne .Ltail_maybe_long
241
#endif /* DONT_USE_DC */