soc/intel/xeon_sp/util: Enhance lock_pam0123
[coreboot2.git] / payloads / libpayload / arch / arm64 / memset.S
blob15ab5903f6e2c3418e0af1be99694026042e5213
1 /* Copyright (c) 2012-2013, Linaro Limited
2    All rights reserved.
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. */
27 /* Assumptions:
28  *
29  * ARMv8-a, AArch64
30  * Unaligned accesses
31  *
32  */
34 #define dstin           x0
35 #define val             w1
36 #define count           x2
37 #define tmp1            x3
38 #define tmp1w           w3
39 #define tmp2            x4
40 #define tmp2w           w4
41 #define zva_len_x       x5
42 #define zva_len         w5
43 #define zva_bits_x      x6
45 #define A_l             x7
46 #define A_lw            w7
47 #define dst             x8
48 #define tmp3w           w9
50 .macro def_fn f p2align=0
51 .text
52 .p2align \p2align
53 .global \f
54 .type \f, %function
55 \f:
56 .endm
58 def_fn memset p2align=6
60         mov     dst, dstin              /* Preserve return value.  */
61         ands    A_lw, val, #255
62         orr     A_lw, A_lw, A_lw, lsl #8
63         orr     A_lw, A_lw, A_lw, lsl #16
64         orr     A_l, A_l, A_l, lsl #32
65 .Ltail_maybe_long:
66         cmp     count, #64
67         b.ge    .Lnot_short
68 .Ltail_maybe_tiny:
69         cmp     count, #15
70         b.le    .Ltail15tiny
71 .Ltail63:
72         ands    tmp1, count, #0x30
73         b.eq    .Ltail15
74         add     dst, dst, tmp1
75         cmp     tmp1w, #0x20
76         b.eq    1f
77         b.lt    2f
78         stp     A_l, A_l, [dst, #-48]
80         stp     A_l, A_l, [dst, #-32]
82         stp     A_l, A_l, [dst, #-16]
84 .Ltail15:
85         and     count, count, #15
86         add     dst, dst, count
87         stp     A_l, A_l, [dst, #-16]   /* Repeat some/all of last store. */
88         ret
90 .Ltail15tiny:
91         /* Set up to 15 bytes.  Does not assume earlier memory
92            being set.  */
93         tbz     count, #3, 1f
94         str     A_l, [dst], #8
96         tbz     count, #2, 1f
97         str     A_lw, [dst], #4
99         tbz     count, #1, 1f
100         strh    A_lw, [dst], #2
102         tbz     count, #0, 1f
103         strb    A_lw, [dst]
105         ret
107         /* Critical loop.  Start at a new cache line boundary.  Assuming
108          * 64 bytes per line, this ensures the entire loop is in one line.  */
109         .p2align 6
110 .Lnot_short:
111         neg     tmp2, dst
112         ands    tmp2, tmp2, #15
113         b.eq    2f
114         /* Bring DST to 128-bit (16-byte) alignment.  We know that there's
115          * more than that to set, so we simply store 16 bytes and advance by
116          * the amount required to reach alignment.  */
117         sub     count, count, tmp2
118         stp     A_l, A_l, [dst]
119         add     dst, dst, tmp2
120         /* There may be less than 63 bytes to go now.  */
121         cmp     count, #63
122         b.le    .Ltail63
124         sub     dst, dst, #16           /* Pre-bias.  */
125         sub     count, count, #64
127         stp     A_l, A_l, [dst, #16]
128         stp     A_l, A_l, [dst, #32]
129         stp     A_l, A_l, [dst, #48]
130         stp     A_l, A_l, [dst, #64]!
131         subs    count, count, #64
132         b.ge    1b
133         tst     count, #0x3f
134         add     dst, dst, #16
135         b.ne    .Ltail63
136         ret