sched/doc: Update documentation for base_slice_ns and CONFIG_HZ relation
[sfrench/cifs-2.6.git] / arch / loongarch / lib / copy_user.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4  */
5
6 #include <linux/export.h>
7 #include <asm/alternative-asm.h>
8 #include <asm/asm.h>
9 #include <asm/asmmacro.h>
10 #include <asm/asm-extable.h>
11 #include <asm/cpu.h>
12 #include <asm/regdef.h>
13
14 SYM_FUNC_START(__copy_user)
15         /*
16          * Some CPUs support hardware unaligned access
17          */
18         ALTERNATIVE     "b __copy_user_generic",        \
19                         "b __copy_user_fast", CPU_FEATURE_UAL
20 SYM_FUNC_END(__copy_user)
21
22 EXPORT_SYMBOL(__copy_user)
23
24 /*
25  * unsigned long __copy_user_generic(void *to, const void *from, size_t n)
26  *
27  * a0: to
28  * a1: from
29  * a2: n
30  */
31 SYM_FUNC_START(__copy_user_generic)
32         beqz    a2, 3f
33
34 1:      ld.b    t0, a1, 0
35 2:      st.b    t0, a0, 0
36         addi.d  a0, a0, 1
37         addi.d  a1, a1, 1
38         addi.d  a2, a2, -1
39         bgtz    a2, 1b
40
41 3:      move    a0, a2
42         jr      ra
43
44         _asm_extable 1b, 3b
45         _asm_extable 2b, 3b
46 SYM_FUNC_END(__copy_user_generic)
47
48 /*
49  * unsigned long __copy_user_fast(void *to, const void *from, unsigned long n)
50  *
51  * a0: to
52  * a1: from
53  * a2: n
54  */
55 SYM_FUNC_START(__copy_user_fast)
56         sltui   t0, a2, 9
57         bnez    t0, .Lsmall
58
59 0:      ld.d    t0, a1, 0
60 1:      st.d    t0, a0, 0
61         add.d   a3, a1, a2
62         add.d   a2, a0, a2
63
64         /* align up destination address */
65         andi    t1, a0, 7
66         sub.d   t0, zero, t1
67         addi.d  t0, t0, 8
68         add.d   a1, a1, t0
69         add.d   a0, a0, t0
70
71         addi.d  a4, a3, -64
72         bgeu    a1, a4, .Llt64
73
74         /* copy 64 bytes at a time */
75 .Lloop64:
76 2:      ld.d    t0, a1, 0
77 3:      ld.d    t1, a1, 8
78 4:      ld.d    t2, a1, 16
79 5:      ld.d    t3, a1, 24
80 6:      ld.d    t4, a1, 32
81 7:      ld.d    t5, a1, 40
82 8:      ld.d    t6, a1, 48
83 9:      ld.d    t7, a1, 56
84 10:     st.d    t0, a0, 0
85 11:     st.d    t1, a0, 8
86 12:     st.d    t2, a0, 16
87 13:     st.d    t3, a0, 24
88 14:     st.d    t4, a0, 32
89 15:     st.d    t5, a0, 40
90 16:     st.d    t6, a0, 48
91 17:     st.d    t7, a0, 56
92         addi.d  a1, a1, 64
93         addi.d  a0, a0, 64
94         bltu    a1, a4, .Lloop64
95
96         /* copy the remaining bytes */
97 .Llt64:
98         addi.d  a4, a3, -32
99         bgeu    a1, a4, .Llt32
100 18:     ld.d    t0, a1, 0
101 19:     ld.d    t1, a1, 8
102 20:     ld.d    t2, a1, 16
103 21:     ld.d    t3, a1, 24
104 22:     st.d    t0, a0, 0
105 23:     st.d    t1, a0, 8
106 24:     st.d    t2, a0, 16
107 25:     st.d    t3, a0, 24
108         addi.d  a1, a1, 32
109         addi.d  a0, a0, 32
110
111 .Llt32:
112         addi.d  a4, a3, -16
113         bgeu    a1, a4, .Llt16
114 26:     ld.d    t0, a1, 0
115 27:     ld.d    t1, a1, 8
116 28:     st.d    t0, a0, 0
117 29:     st.d    t1, a0, 8
118         addi.d  a1, a1, 16
119         addi.d  a0, a0, 16
120
121 .Llt16:
122         addi.d  a4, a3, -8
123         bgeu    a1, a4, .Llt8
124 30:     ld.d    t0, a1, 0
125 31:     st.d    t0, a0, 0
126         addi.d  a1, a1, 8
127         addi.d  a0, a0, 8
128
129 .Llt8:
130 32:     ld.d    t0, a3, -8
131 33:     st.d    t0, a2, -8
132
133         /* return */
134         move    a0, zero
135         jr      ra
136
137         .align  5
138 .Lsmall:
139         pcaddi  t0, 8
140         slli.d  a3, a2, 5
141         add.d   t0, t0, a3
142         jr      t0
143
144         .align  5
145         move    a0, zero
146         jr      ra
147
148         .align  5
149 34:     ld.b    t0, a1, 0
150 35:     st.b    t0, a0, 0
151         move    a0, zero
152         jr      ra
153
154         .align  5
155 36:     ld.h    t0, a1, 0
156 37:     st.h    t0, a0, 0
157         move    a0, zero
158         jr      ra
159
160         .align  5
161 38:     ld.h    t0, a1, 0
162 39:     ld.b    t1, a1, 2
163 40:     st.h    t0, a0, 0
164 41:     st.b    t1, a0, 2
165         move    a0, zero
166         jr      ra
167
168         .align  5
169 42:     ld.w    t0, a1, 0
170 43:     st.w    t0, a0, 0
171         move    a0, zero
172         jr      ra
173
174         .align  5
175 44:     ld.w    t0, a1, 0
176 45:     ld.b    t1, a1, 4
177 46:     st.w    t0, a0, 0
178 47:     st.b    t1, a0, 4
179         move    a0, zero
180         jr      ra
181
182         .align  5
183 48:     ld.w    t0, a1, 0
184 49:     ld.h    t1, a1, 4
185 50:     st.w    t0, a0, 0
186 51:     st.h    t1, a0, 4
187         move    a0, zero
188         jr      ra
189
190         .align  5
191 52:     ld.w    t0, a1, 0
192 53:     ld.w    t1, a1, 3
193 54:     st.w    t0, a0, 0
194 55:     st.w    t1, a0, 3
195         move    a0, zero
196         jr      ra
197
198         .align  5
199 56:     ld.d    t0, a1, 0
200 57:     st.d    t0, a0, 0
201         move    a0, zero
202         jr      ra
203
204         /* fixup and ex_table */
205 .Llarge_fixup:
206         sub.d   a2, a2, a0
207
208 .Lsmall_fixup:
209 58:     ld.b    t0, a1, 0
210 59:     st.b    t0, a0, 0
211         addi.d  a0, a0, 1
212         addi.d  a1, a1, 1
213         addi.d  a2, a2, -1
214         bgt     a2, zero, 58b
215
216 .Lexit:
217         move    a0, a2
218         jr      ra
219
220         _asm_extable 0b, .Lsmall_fixup
221         _asm_extable 1b, .Lsmall_fixup
222         _asm_extable 2b, .Llarge_fixup
223         _asm_extable 3b, .Llarge_fixup
224         _asm_extable 4b, .Llarge_fixup
225         _asm_extable 5b, .Llarge_fixup
226         _asm_extable 6b, .Llarge_fixup
227         _asm_extable 7b, .Llarge_fixup
228         _asm_extable 8b, .Llarge_fixup
229         _asm_extable 9b, .Llarge_fixup
230         _asm_extable 10b, .Llarge_fixup
231         _asm_extable 11b, .Llarge_fixup
232         _asm_extable 12b, .Llarge_fixup
233         _asm_extable 13b, .Llarge_fixup
234         _asm_extable 14b, .Llarge_fixup
235         _asm_extable 15b, .Llarge_fixup
236         _asm_extable 16b, .Llarge_fixup
237         _asm_extable 17b, .Llarge_fixup
238         _asm_extable 18b, .Llarge_fixup
239         _asm_extable 19b, .Llarge_fixup
240         _asm_extable 20b, .Llarge_fixup
241         _asm_extable 21b, .Llarge_fixup
242         _asm_extable 22b, .Llarge_fixup
243         _asm_extable 23b, .Llarge_fixup
244         _asm_extable 24b, .Llarge_fixup
245         _asm_extable 25b, .Llarge_fixup
246         _asm_extable 26b, .Llarge_fixup
247         _asm_extable 27b, .Llarge_fixup
248         _asm_extable 28b, .Llarge_fixup
249         _asm_extable 29b, .Llarge_fixup
250         _asm_extable 30b, .Llarge_fixup
251         _asm_extable 31b, .Llarge_fixup
252         _asm_extable 32b, .Llarge_fixup
253         _asm_extable 33b, .Llarge_fixup
254         _asm_extable 34b, .Lexit
255         _asm_extable 35b, .Lexit
256         _asm_extable 36b, .Lsmall_fixup
257         _asm_extable 37b, .Lsmall_fixup
258         _asm_extable 38b, .Lsmall_fixup
259         _asm_extable 39b, .Lsmall_fixup
260         _asm_extable 40b, .Lsmall_fixup
261         _asm_extable 41b, .Lsmall_fixup
262         _asm_extable 42b, .Lsmall_fixup
263         _asm_extable 43b, .Lsmall_fixup
264         _asm_extable 44b, .Lsmall_fixup
265         _asm_extable 45b, .Lsmall_fixup
266         _asm_extable 46b, .Lsmall_fixup
267         _asm_extable 47b, .Lsmall_fixup
268         _asm_extable 48b, .Lsmall_fixup
269         _asm_extable 49b, .Lsmall_fixup
270         _asm_extable 50b, .Lsmall_fixup
271         _asm_extable 51b, .Lsmall_fixup
272         _asm_extable 52b, .Lsmall_fixup
273         _asm_extable 53b, .Lsmall_fixup
274         _asm_extable 54b, .Lsmall_fixup
275         _asm_extable 55b, .Lsmall_fixup
276         _asm_extable 56b, .Lsmall_fixup
277         _asm_extable 57b, .Lsmall_fixup
278         _asm_extable 58b, .Lexit
279         _asm_extable 59b, .Lexit
280 SYM_FUNC_END(__copy_user_fast)