soc/intel/xeon_sp/util: Enhance lock_pam0123
[coreboot2.git] / payloads / libpayload / arch / arm / memset.S
blob0c1102deb4c1f71e1e5c52df39b7b012047f2acf
1 /*
2  *  linux/arch/arm/lib/memset.S
3  *
4  *  Copyright (C) 1995-2000 Russell King
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  *  ASM optimised string functions
11  */
13 #include <arch/asm.h>
14 #include "asmlib.h"
16 ENTRY(memset)
17         ands    r3, r0, #3              @ 1 unaligned?
18         mov     ip, r0                  @ preserve r0 as return value
19         bne     6f                      @ 1
21  * we know that the pointer in ip is aligned to a word boundary.
22  */
23 1:      orr     r1, r1, r1, lsl #8
24         orr     r1, r1, r1, lsl #16
25         mov     r3, r1
26         cmp     r2, #16
27         blt     4f
29 #if ! CALGN(1)+0
32  * We need 2 extra registers for this loop - use r8 and the LR
33  */
34         stmfd   sp!, {r8, lr}
35         mov     r8, r1
36         mov     lr, r1
38 2:      subs    r2, r2, #64
39         stmgeia ip!, {r1, r3, r8, lr}   @ 64 bytes at a time.
40         stmgeia ip!, {r1, r3, r8, lr}
41         stmgeia ip!, {r1, r3, r8, lr}
42         stmgeia ip!, {r1, r3, r8, lr}
43         bgt     2b
44         ldmeqfd sp!, {r8, pc}           @ Now <64 bytes to go.
46  * No need to correct the count; we're only testing bits from now on
47  */
48         tst     r2, #32
49         stmneia ip!, {r1, r3, r8, lr}
50         stmneia ip!, {r1, r3, r8, lr}
51         tst     r2, #16
52         stmneia ip!, {r1, r3, r8, lr}
53         ldmfd   sp!, {r8, lr}
55 #else
58  * This version aligns the destination pointer in order to write
59  * whole cache lines at once.
60  */
62         stmfd   sp!, {r4-r8, lr}
63         mov     r4, r1
64         mov     r5, r1
65         mov     r6, r1
66         mov     r7, r1
67         mov     r8, r1
68         mov     lr, r1
70         cmp     r2, #96
71         tstgt   ip, #31
72         ble     3f
74         and     r8, ip, #31
75         rsb     r8, r8, #32
76         sub     r2, r2, r8
77         movs    r8, r8, lsl #(32 - 4)
78         stmcsia ip!, {r4, r5, r6, r7}
79         stmmiia ip!, {r4, r5}
80         tst     r8, #(1 << 30)
81         mov     r8, r1
82         strne   r1, [ip], #4
84 3:      subs    r2, r2, #64
85         stmgeia ip!, {r1, r3-r8, lr}
86         stmgeia ip!, {r1, r3-r8, lr}
87         bgt     3b
88         ldmeqfd sp!, {r4-r8, pc}
90         tst     r2, #32
91         stmneia ip!, {r1, r3-r8, lr}
92         tst     r2, #16
93         stmneia ip!, {r4-r7}
94         ldmfd   sp!, {r4-r8, lr}
96 #endif
98 4:      tst     r2, #8
99         stmneia ip!, {r1, r3}
100         tst     r2, #4
101         strne   r1, [ip], #4
103  * When we get here, we've got less than 4 bytes to zero.  We
104  * may have an unaligned pointer as well.
105  */
106 5:      tst     r2, #2
107         strneb  r1, [ip], #1
108         strneb  r1, [ip], #1
109         tst     r2, #1
110         strneb  r1, [ip], #1
111         mov     pc, lr
113 6:      subs    r2, r2, #4              @ 1 do we have enough
114         blt     5b                      @ 1 bytes to align with?
115         cmp     r3, #2                  @ 1
116         strltb  r1, [ip], #1            @ 1
117         strleb  r1, [ip], #1            @ 1
118         strb    r1, [ip], #1            @ 1
119         add     r2, r2, r3              @ 1 (r2 = r2 - (4 - r3))
120         b       1b
121 ENDPROC(memset)