Merge tag 'devicetree-fixes-for-5.11-1' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / arch / powerpc / lib / string_64.S
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  *
4  * Copyright (C) IBM Corporation, 2012
5  *
6  * Author: Anton Blanchard <anton@au.ibm.com>
7  */
8
9 #include <asm/ppc_asm.h>
10 #include <asm/linkage.h>
11 #include <asm/asm-offsets.h>
12 #include <asm/export.h>
13
14         .section        ".toc","aw"
15 PPC64_CACHES:
16         .tc             ppc64_caches[TC],ppc64_caches
17         .section        ".text"
18
19 /**
20  * __arch_clear_user: - Zero a block of memory in user space, with less checking.
21  * @to:   Destination address, in user space.
22  * @n:    Number of bytes to zero.
23  *
24  * Zero a block of memory in user space.  Caller must check
25  * the specified block with access_ok() before calling this function.
26  *
27  * Returns number of bytes that could not be cleared.
28  * On success, this will be zero.
29  */
30
31         .macro err1
32 100:
33         EX_TABLE(100b,.Ldo_err1)
34         .endm
35
36         .macro err2
37 200:
38         EX_TABLE(200b,.Ldo_err2)
39         .endm
40
41         .macro err3
42 300:
43         EX_TABLE(300b,.Ldo_err3)
44         .endm
45
46 .Ldo_err1:
47         mr      r3,r8
48
49 .Ldo_err2:
50         mtctr   r4
51 1:
52 err3;   stb     r0,0(r3)
53         addi    r3,r3,1
54         addi    r4,r4,-1
55         bdnz    1b
56
57 .Ldo_err3:
58         mr      r3,r4
59         blr
60
61 _GLOBAL_TOC(__arch_clear_user)
62         cmpdi   r4,32
63         neg     r6,r3
64         li      r0,0
65         blt     .Lshort_clear
66         mr      r8,r3
67         mtocrf  0x01,r6
68         clrldi  r6,r6,(64-3)
69
70         /* Get the destination 8 byte aligned */
71         bf      cr7*4+3,1f
72 err1;   stb     r0,0(r3)
73         addi    r3,r3,1
74
75 1:      bf      cr7*4+2,2f
76 err1;   sth     r0,0(r3)
77         addi    r3,r3,2
78
79 2:      bf      cr7*4+1,3f
80 err1;   stw     r0,0(r3)
81         addi    r3,r3,4
82
83 3:      sub     r4,r4,r6
84
85         cmpdi   r4,32
86         cmpdi   cr1,r4,512
87         blt     .Lshort_clear
88         bgt     cr1,.Llong_clear
89
90 .Lmedium_clear:
91         srdi    r6,r4,5
92         mtctr   r6
93
94         /* Do 32 byte chunks */
95 4:
96 err2;   std     r0,0(r3)
97 err2;   std     r0,8(r3)
98 err2;   std     r0,16(r3)
99 err2;   std     r0,24(r3)
100         addi    r3,r3,32
101         addi    r4,r4,-32
102         bdnz    4b
103
104 .Lshort_clear:
105         /* up to 31 bytes to go */
106         cmpdi   r4,16
107         blt     6f
108 err2;   std     r0,0(r3)
109 err2;   std     r0,8(r3)
110         addi    r3,r3,16
111         addi    r4,r4,-16
112
113         /* Up to 15 bytes to go */
114 6:      mr      r8,r3
115         clrldi  r4,r4,(64-4)
116         mtocrf  0x01,r4
117         bf      cr7*4+0,7f
118 err1;   std     r0,0(r3)
119         addi    r3,r3,8
120
121 7:      bf      cr7*4+1,8f
122 err1;   stw     r0,0(r3)
123         addi    r3,r3,4
124
125 8:      bf      cr7*4+2,9f
126 err1;   sth     r0,0(r3)
127         addi    r3,r3,2
128
129 9:      bf      cr7*4+3,10f
130 err1;   stb     r0,0(r3)
131
132 10:     li      r3,0
133         blr
134
135 .Llong_clear:
136         ld      r5,PPC64_CACHES@toc(r2)
137
138         bf      cr7*4+0,11f
139 err2;   std     r0,0(r3)
140         addi    r3,r3,8
141         addi    r4,r4,-8
142
143         /* Destination is 16 byte aligned, need to get it cache block aligned */
144 11:     lwz     r7,DCACHEL1LOGBLOCKSIZE(r5)
145         lwz     r9,DCACHEL1BLOCKSIZE(r5)
146
147         /*
148          * With worst case alignment the long clear loop takes a minimum
149          * of 1 byte less than 2 cachelines.
150          */
151         sldi    r10,r9,2
152         cmpd    r4,r10
153         blt     .Lmedium_clear
154
155         neg     r6,r3
156         addi    r10,r9,-1
157         and.    r5,r6,r10
158         beq     13f
159
160         srdi    r6,r5,4
161         mtctr   r6
162         mr      r8,r3
163 12:
164 err1;   std     r0,0(r3)
165 err1;   std     r0,8(r3)
166         addi    r3,r3,16
167         bdnz    12b
168
169         sub     r4,r4,r5
170
171 13:     srd     r6,r4,r7
172         mtctr   r6
173         mr      r8,r3
174 14:
175 err1;   dcbz    0,r3
176         add     r3,r3,r9
177         bdnz    14b
178
179         and     r4,r4,r10
180
181         cmpdi   r4,32
182         blt     .Lshort_clear
183         b       .Lmedium_clear
184 EXPORT_SYMBOL(__arch_clear_user)