xref: /linux/arch/loongarch/lib/clear_user.S (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4 */
5
6#include <asm/alternative-asm.h>
7#include <asm/asm.h>
8#include <asm/asmmacro.h>
9#include <asm/asm-extable.h>
10#include <asm/cpu.h>
11#include <asm/export.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, a1, -\to
24	jr	ra
25.endr
26
27SYM_FUNC_START(__clear_user)
28	/*
29	 * Some CPUs support hardware unaligned access
30	 */
31	ALTERNATIVE	"b __clear_user_generic",	\
32			"b __clear_user_fast", CPU_FEATURE_UAL
33SYM_FUNC_END(__clear_user)
34
35EXPORT_SYMBOL(__clear_user)
36
37/*
38 * unsigned long __clear_user_generic(void *addr, size_t size)
39 *
40 * a0: addr
41 * a1: size
42 */
43SYM_FUNC_START(__clear_user_generic)
44	beqz	a1, 2f
45
461:	st.b	zero, a0, 0
47	addi.d	a0, a0, 1
48	addi.d	a1, a1, -1
49	bgtz	a1, 1b
50
512:	move	a0, a1
52	jr	ra
53
54	_asm_extable 1b, .L_fixup_handle_s0
55SYM_FUNC_END(__clear_user_generic)
56
57/*
58 * unsigned long __clear_user_fast(void *addr, unsigned long size)
59 *
60 * a0: addr
61 * a1: size
62 */
63SYM_FUNC_START(__clear_user_fast)
64	sltui	t0, a1, 9
65	bnez	t0, .Lsmall
66
67	add.d	a2, a0, a1
680:	st.d	zero, a0, 0
69
70	/* align up address */
71	addi.d	a0, a0, 8
72	bstrins.d	a0, zero, 2, 0
73
74	addi.d	a3, a2, -64
75	bgeu	a0, a3, .Llt64
76
77	/* set 64 bytes at a time */
78.Lloop64:
791:	st.d	zero, a0, 0
802:	st.d	zero, a0, 8
813:	st.d	zero, a0, 16
824:	st.d	zero, a0, 24
835:	st.d	zero, a0, 32
846:	st.d	zero, a0, 40
857:	st.d	zero, a0, 48
868:	st.d	zero, a0, 56
87	addi.d	a0, a0, 64
88	bltu	a0, a3, .Lloop64
89
90	/* set the remaining bytes */
91.Llt64:
92	addi.d	a3, a2, -32
93	bgeu	a0, a3, .Llt32
949:	st.d	zero, a0, 0
9510:	st.d	zero, a0, 8
9611:	st.d	zero, a0, 16
9712:	st.d	zero, a0, 24
98	addi.d	a0, a0, 32
99
100.Llt32:
101	addi.d	a3, a2, -16
102	bgeu	a0, a3, .Llt16
10313:	st.d	zero, a0, 0
10414:	st.d	zero, a0, 8
105	addi.d	a0, a0, 16
106
107.Llt16:
108	addi.d	a3, a2, -8
109	bgeu	a0, a3, .Llt8
11015:	st.d	zero, a0, 0
111
112.Llt8:
11316:	st.d	zero, a2, -8
114
115	/* return */
116	move	a0, zero
117	jr	ra
118
119	.align	4
120.Lsmall:
121	pcaddi	t0, 4
122	slli.d	a2, a1, 4
123	add.d	t0, t0, a2
124	jr	t0
125
126	.align	4
127	move	a0, zero
128	jr	ra
129
130	.align	4
13117:	st.b	zero, a0, 0
132	move	a0, zero
133	jr	ra
134
135	.align	4
13618:	st.h	zero, a0, 0
137	move	a0, zero
138	jr	ra
139
140	.align	4
14119:	st.h	zero, a0, 0
14220:	st.b	zero, a0, 2
143	move	a0, zero
144	jr	ra
145
146	.align	4
14721:	st.w	zero, a0, 0
148	move	a0, zero
149	jr	ra
150
151	.align	4
15222:	st.w	zero, a0, 0
15323:	st.b	zero, a0, 4
154	move	a0, zero
155	jr	ra
156
157	.align	4
15824:	st.w	zero, a0, 0
15925:	st.h	zero, a0, 4
160	move	a0, zero
161	jr	ra
162
163	.align	4
16426:	st.w	zero, a0, 0
16527:	st.w	zero, a0, 3
166	move	a0, zero
167	jr	ra
168
169	.align	4
17028:	st.d	zero, a0, 0
171	move	a0, zero
172	jr	ra
173
174	/* fixup and ex_table */
175	_asm_extable 0b, .L_fixup_handle_0
176	_asm_extable 1b, .L_fixup_handle_0
177	_asm_extable 2b, .L_fixup_handle_1
178	_asm_extable 3b, .L_fixup_handle_2
179	_asm_extable 4b, .L_fixup_handle_3
180	_asm_extable 5b, .L_fixup_handle_4
181	_asm_extable 6b, .L_fixup_handle_5
182	_asm_extable 7b, .L_fixup_handle_6
183	_asm_extable 8b, .L_fixup_handle_7
184	_asm_extable 9b, .L_fixup_handle_0
185	_asm_extable 10b, .L_fixup_handle_1
186	_asm_extable 11b, .L_fixup_handle_2
187	_asm_extable 12b, .L_fixup_handle_3
188	_asm_extable 13b, .L_fixup_handle_0
189	_asm_extable 14b, .L_fixup_handle_1
190	_asm_extable 15b, .L_fixup_handle_0
191	_asm_extable 16b, .L_fixup_handle_1
192	_asm_extable 17b, .L_fixup_handle_s0
193	_asm_extable 18b, .L_fixup_handle_s0
194	_asm_extable 19b, .L_fixup_handle_s0
195	_asm_extable 20b, .L_fixup_handle_s2
196	_asm_extable 21b, .L_fixup_handle_s0
197	_asm_extable 22b, .L_fixup_handle_s0
198	_asm_extable 23b, .L_fixup_handle_s4
199	_asm_extable 24b, .L_fixup_handle_s0
200	_asm_extable 25b, .L_fixup_handle_s4
201	_asm_extable 26b, .L_fixup_handle_s0
202	_asm_extable 27b, .L_fixup_handle_s4
203	_asm_extable 28b, .L_fixup_handle_s0
204SYM_FUNC_END(__clear_user_fast)
205