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#include <asm/unwind_hints.h>
14
15SYM_FUNC_START(__clear_user)
16 /*
17 * Some CPUs support hardware unaligned access
18 */
19 ALTERNATIVE "b __clear_user_generic", \
20 "b __clear_user_fast", CPU_FEATURE_UAL
21SYM_FUNC_END(__clear_user)
22
23EXPORT_SYMBOL(__clear_user)
24
25/*
26 * unsigned long __clear_user_generic(void *addr, size_t size)
27 *
28 * a0: addr
29 * a1: size
30 */
31SYM_FUNC_START(__clear_user_generic)
32 beqz a1, 2f
33
341: st.b zero, a0, 0
35 addi.d a0, a0, 1
36 addi.d a1, a1, -1
37 bgtz a1, 1b
38
392: move a0, a1
40 jr ra
41
42 _asm_extable 1b, 2b
43SYM_FUNC_END(__clear_user_generic)
44
45/*
46 * unsigned long __clear_user_fast(void *addr, unsigned long size)
47 *
48 * a0: addr
49 * a1: size
50 */
51SYM_FUNC_START(__clear_user_fast)
52 sltui t0, a1, 9
53 bnez t0, .Lsmall
54
55 add.d a2, a0, a1
560: st.d zero, a0, 0
57
58 /* align up address */
59 addi.d a0, a0, 8
60 bstrins.d a0, zero, 2, 0
61
62 addi.d a3, a2, -64
63 bgeu a0, a3, .Llt64
64
65 /* set 64 bytes at a time */
66.Lloop64:
671: st.d zero, a0, 0
682: st.d zero, a0, 8
693: st.d zero, a0, 16
704: st.d zero, a0, 24
715: st.d zero, a0, 32
726: st.d zero, a0, 40
737: st.d zero, a0, 48
748: st.d zero, a0, 56
75 addi.d a0, a0, 64
76 bltu a0, a3, .Lloop64
77
78 /* set the remaining bytes */
79.Llt64:
80 addi.d a3, a2, -32
81 bgeu a0, a3, .Llt32
829: st.d zero, a0, 0
8310: st.d zero, a0, 8
8411: st.d zero, a0, 16
8512: st.d zero, a0, 24
86 addi.d a0, a0, 32
87
88.Llt32:
89 addi.d a3, a2, -16
90 bgeu a0, a3, .Llt16
9113: st.d zero, a0, 0
9214: st.d zero, a0, 8
93 addi.d a0, a0, 16
94
95.Llt16:
96 addi.d a3, a2, -8
97 bgeu a0, a3, .Llt8
9815: st.d zero, a0, 0
99 addi.d a0, a0, 8
100
101.Llt8:
10216: st.d zero, a2, -8
103
104 /* return */
105 move a0, zero
106 jr ra
107
108 .align 4
109.Lsmall:
110 pcaddi t0, 4
111 slli.d a2, a1, 4
112 add.d t0, t0, a2
113 jr t0
114
115 .align 4
116 move a0, zero
117 jr ra
118
119 .align 4
12017: st.b zero, a0, 0
121 move a0, zero
122 jr ra
123
124 .align 4
12518: st.h zero, a0, 0
126 move a0, zero
127 jr ra
128
129 .align 4
13019: st.h zero, a0, 0
13120: st.b zero, a0, 2
132 move a0, zero
133 jr ra
134
135 .align 4
13621: st.w zero, a0, 0
137 move a0, zero
138 jr ra
139
140 .align 4
14122: st.w zero, a0, 0
14223: st.b zero, a0, 4
143 move a0, zero
144 jr ra
145
146 .align 4
14724: st.w zero, a0, 0
14825: st.h zero, a0, 4
149 move a0, zero
150 jr ra
151
152 .align 4
15326: st.w zero, a0, 0
15427: st.w zero, a0, 3
155 move a0, zero
156 jr ra
157
158 .align 4
15928: st.d zero, a0, 0
160 move a0, zero
161 jr ra
162
163 /* fixup and ex_table */
164.Llarge_fixup:
165 sub.d a1, a2, a0
166
167.Lsmall_fixup:
16829: st.b zero, a0, 0
169 addi.d a0, a0, 1
170 addi.d a1, a1, -1
171 bgt a1, zero, 29b
172
173.Lexit:
174 move a0, a1
175 jr ra
176
177 _asm_extable 0b, .Lsmall_fixup
178 _asm_extable 1b, .Llarge_fixup
179 _asm_extable 2b, .Llarge_fixup
180 _asm_extable 3b, .Llarge_fixup
181 _asm_extable 4b, .Llarge_fixup
182 _asm_extable 5b, .Llarge_fixup
183 _asm_extable 6b, .Llarge_fixup
184 _asm_extable 7b, .Llarge_fixup
185 _asm_extable 8b, .Llarge_fixup
186 _asm_extable 9b, .Llarge_fixup
187 _asm_extable 10b, .Llarge_fixup
188 _asm_extable 11b, .Llarge_fixup
189 _asm_extable 12b, .Llarge_fixup
190 _asm_extable 13b, .Llarge_fixup
191 _asm_extable 14b, .Llarge_fixup
192 _asm_extable 15b, .Llarge_fixup
193 _asm_extable 16b, .Llarge_fixup
194 _asm_extable 17b, .Lexit
195 _asm_extable 18b, .Lsmall_fixup
196 _asm_extable 19b, .Lsmall_fixup
197 _asm_extable 20b, .Lsmall_fixup
198 _asm_extable 21b, .Lsmall_fixup
199 _asm_extable 22b, .Lsmall_fixup
200 _asm_extable 23b, .Lsmall_fixup
201 _asm_extable 24b, .Lsmall_fixup
202 _asm_extable 25b, .Lsmall_fixup
203 _asm_extable 26b, .Lsmall_fixup
204 _asm_extable 27b, .Lsmall_fixup
205 _asm_extable 28b, .Lsmall_fixup
206 _asm_extable 29b, .Lexit
207SYM_FUNC_END(__clear_user_fast)
208
209STACK_FRAME_NON_STANDARD __clear_user_fast
210

source code of linux/arch/loongarch/lib/clear_user.S