xref: /linux/arch/loongarch/lib/clear_user.S (revision 4d84f763f7e137be7eeab30cc7daa9449c9cb053)
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	addi.d	a0, a0, 8
112
113.Llt8:
11416:	st.d	zero, a2, -8
115
116	/* return */
117	move	a0, zero
118	jr	ra
119
120	.align	4
121.Lsmall:
122	pcaddi	t0, 4
123	slli.d	a2, a1, 4
124	add.d	t0, t0, a2
125	jr	t0
126
127	.align	4
128	move	a0, zero
129	jr	ra
130
131	.align	4
13217:	st.b	zero, a0, 0
133	move	a0, zero
134	jr	ra
135
136	.align	4
13718:	st.h	zero, a0, 0
138	move	a0, zero
139	jr	ra
140
141	.align	4
14219:	st.h	zero, a0, 0
14320:	st.b	zero, a0, 2
144	move	a0, zero
145	jr	ra
146
147	.align	4
14821:	st.w	zero, a0, 0
149	move	a0, zero
150	jr	ra
151
152	.align	4
15322:	st.w	zero, a0, 0
15423:	st.b	zero, a0, 4
155	move	a0, zero
156	jr	ra
157
158	.align	4
15924:	st.w	zero, a0, 0
16025:	st.h	zero, a0, 4
161	move	a0, zero
162	jr	ra
163
164	.align	4
16526:	st.w	zero, a0, 0
16627:	st.w	zero, a0, 3
167	move	a0, zero
168	jr	ra
169
170	.align	4
17128:	st.d	zero, a0, 0
172	move	a0, zero
173	jr	ra
174
175	/* fixup and ex_table */
176	_asm_extable 0b, .L_fixup_handle_0
177	_asm_extable 1b, .L_fixup_handle_0
178	_asm_extable 2b, .L_fixup_handle_1
179	_asm_extable 3b, .L_fixup_handle_2
180	_asm_extable 4b, .L_fixup_handle_3
181	_asm_extable 5b, .L_fixup_handle_4
182	_asm_extable 6b, .L_fixup_handle_5
183	_asm_extable 7b, .L_fixup_handle_6
184	_asm_extable 8b, .L_fixup_handle_7
185	_asm_extable 9b, .L_fixup_handle_0
186	_asm_extable 10b, .L_fixup_handle_1
187	_asm_extable 11b, .L_fixup_handle_2
188	_asm_extable 12b, .L_fixup_handle_3
189	_asm_extable 13b, .L_fixup_handle_0
190	_asm_extable 14b, .L_fixup_handle_1
191	_asm_extable 15b, .L_fixup_handle_0
192	_asm_extable 16b, .L_fixup_handle_0
193	_asm_extable 17b, .L_fixup_handle_s0
194	_asm_extable 18b, .L_fixup_handle_s0
195	_asm_extable 19b, .L_fixup_handle_s0
196	_asm_extable 20b, .L_fixup_handle_s2
197	_asm_extable 21b, .L_fixup_handle_s0
198	_asm_extable 22b, .L_fixup_handle_s0
199	_asm_extable 23b, .L_fixup_handle_s4
200	_asm_extable 24b, .L_fixup_handle_s0
201	_asm_extable 25b, .L_fixup_handle_s4
202	_asm_extable 26b, .L_fixup_handle_s0
203	_asm_extable 27b, .L_fixup_handle_s4
204	_asm_extable 28b, .L_fixup_handle_s0
205SYM_FUNC_END(__clear_user_fast)
206