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