xref: /linux/arch/loongarch/lib/clear_user.S (revision 79790b6818e96c58fe2bffee1b418c16e64e7b80)
1559671e0SHuacai Chen/* SPDX-License-Identifier: GPL-2.0 */
2559671e0SHuacai Chen/*
3559671e0SHuacai Chen * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4559671e0SHuacai Chen */
5559671e0SHuacai Chen
655b46ff9SMasahiro Yamada#include <linux/export.h>
7a275a82dSHuacai Chen#include <asm/alternative-asm.h>
8559671e0SHuacai Chen#include <asm/asm.h>
9559671e0SHuacai Chen#include <asm/asmmacro.h>
10508f28c6SYouling Tang#include <asm/asm-extable.h>
11a275a82dSHuacai Chen#include <asm/cpu.h>
12559671e0SHuacai Chen#include <asm/regdef.h>
13*cb8a2ef0STiezhu Yang#include <asm/unwind_hints.h>
14559671e0SHuacai Chen
15a275a82dSHuacai ChenSYM_FUNC_START(__clear_user)
16559671e0SHuacai Chen	/*
17a275a82dSHuacai Chen	 * Some CPUs support hardware unaligned access
18a275a82dSHuacai Chen	 */
19a275a82dSHuacai Chen	ALTERNATIVE	"b __clear_user_generic",	\
20a275a82dSHuacai Chen			"b __clear_user_fast", CPU_FEATURE_UAL
21a275a82dSHuacai ChenSYM_FUNC_END(__clear_user)
22a275a82dSHuacai Chen
23a275a82dSHuacai ChenEXPORT_SYMBOL(__clear_user)
24a275a82dSHuacai Chen
25a275a82dSHuacai Chen/*
26a275a82dSHuacai Chen * unsigned long __clear_user_generic(void *addr, size_t size)
27559671e0SHuacai Chen *
28559671e0SHuacai Chen * a0: addr
29559671e0SHuacai Chen * a1: size
30559671e0SHuacai Chen */
31a275a82dSHuacai ChenSYM_FUNC_START(__clear_user_generic)
32559671e0SHuacai Chen	beqz	a1, 2f
33559671e0SHuacai Chen
34559671e0SHuacai Chen1:	st.b	zero, a0, 0
35559671e0SHuacai Chen	addi.d	a0, a0, 1
36559671e0SHuacai Chen	addi.d	a1, a1, -1
371fdb9a92SWANG Xuerui	bgtz	a1, 1b
38559671e0SHuacai Chen
39559671e0SHuacai Chen2:	move	a0, a1
40559671e0SHuacai Chen	jr	ra
41559671e0SHuacai Chen
42937f6593SWeihao Li	_asm_extable 1b, 2b
43a275a82dSHuacai ChenSYM_FUNC_END(__clear_user_generic)
44559671e0SHuacai Chen
45a275a82dSHuacai Chen/*
46a275a82dSHuacai Chen * unsigned long __clear_user_fast(void *addr, unsigned long size)
47a275a82dSHuacai Chen *
48a275a82dSHuacai Chen * a0: addr
49a275a82dSHuacai Chen * a1: size
50a275a82dSHuacai Chen */
51a275a82dSHuacai ChenSYM_FUNC_START(__clear_user_fast)
528941e93cSWANG Rui	sltui	t0, a1, 9
538941e93cSWANG Rui	bnez	t0, .Lsmall
54a275a82dSHuacai Chen
558941e93cSWANG Rui	add.d	a2, a0, a1
568941e93cSWANG Rui0:	st.d	zero, a0, 0
578941e93cSWANG Rui
588941e93cSWANG Rui	/* align up address */
598941e93cSWANG Rui	addi.d	a0, a0, 8
608941e93cSWANG Rui	bstrins.d	a0, zero, 2, 0
618941e93cSWANG Rui
628941e93cSWANG Rui	addi.d	a3, a2, -64
638941e93cSWANG Rui	bgeu	a0, a3, .Llt64
64a275a82dSHuacai Chen
65a275a82dSHuacai Chen	/* set 64 bytes at a time */
668941e93cSWANG Rui.Lloop64:
67a275a82dSHuacai Chen1:	st.d	zero, a0, 0
68a275a82dSHuacai Chen2:	st.d	zero, a0, 8
69a275a82dSHuacai Chen3:	st.d	zero, a0, 16
70a275a82dSHuacai Chen4:	st.d	zero, a0, 24
71a275a82dSHuacai Chen5:	st.d	zero, a0, 32
72a275a82dSHuacai Chen6:	st.d	zero, a0, 40
73a275a82dSHuacai Chen7:	st.d	zero, a0, 48
74a275a82dSHuacai Chen8:	st.d	zero, a0, 56
75a275a82dSHuacai Chen	addi.d	a0, a0, 64
768941e93cSWANG Rui	bltu	a0, a3, .Lloop64
77a275a82dSHuacai Chen
78a275a82dSHuacai Chen	/* set the remaining bytes */
798941e93cSWANG Rui.Llt64:
808941e93cSWANG Rui	addi.d	a3, a2, -32
818941e93cSWANG Rui	bgeu	a0, a3, .Llt32
828941e93cSWANG Rui9:	st.d	zero, a0, 0
838941e93cSWANG Rui10:	st.d	zero, a0, 8
848941e93cSWANG Rui11:	st.d	zero, a0, 16
858941e93cSWANG Rui12:	st.d	zero, a0, 24
868941e93cSWANG Rui	addi.d	a0, a0, 32
878941e93cSWANG Rui
888941e93cSWANG Rui.Llt32:
898941e93cSWANG Rui	addi.d	a3, a2, -16
908941e93cSWANG Rui	bgeu	a0, a3, .Llt16
918941e93cSWANG Rui13:	st.d	zero, a0, 0
928941e93cSWANG Rui14:	st.d	zero, a0, 8
938941e93cSWANG Rui	addi.d	a0, a0, 16
948941e93cSWANG Rui
958941e93cSWANG Rui.Llt16:
968941e93cSWANG Rui	addi.d	a3, a2, -8
978941e93cSWANG Rui	bgeu	a0, a3, .Llt8
988941e93cSWANG Rui15:	st.d	zero, a0, 0
99e66d511fSWANG Rui	addi.d	a0, a0, 8
1008941e93cSWANG Rui
1018941e93cSWANG Rui.Llt8:
1028941e93cSWANG Rui16:	st.d	zero, a2, -8
103a275a82dSHuacai Chen
104a275a82dSHuacai Chen	/* return */
1058941e93cSWANG Rui	move	a0, zero
1068941e93cSWANG Rui	jr	ra
1078941e93cSWANG Rui
1088941e93cSWANG Rui	.align	4
1098941e93cSWANG Rui.Lsmall:
1108941e93cSWANG Rui	pcaddi	t0, 4
1118941e93cSWANG Rui	slli.d	a2, a1, 4
1128941e93cSWANG Rui	add.d	t0, t0, a2
1138941e93cSWANG Rui	jr	t0
1148941e93cSWANG Rui
1158941e93cSWANG Rui	.align	4
1168941e93cSWANG Rui	move	a0, zero
1178941e93cSWANG Rui	jr	ra
1188941e93cSWANG Rui
1198941e93cSWANG Rui	.align	4
1208941e93cSWANG Rui17:	st.b	zero, a0, 0
1218941e93cSWANG Rui	move	a0, zero
1228941e93cSWANG Rui	jr	ra
1238941e93cSWANG Rui
1248941e93cSWANG Rui	.align	4
1258941e93cSWANG Rui18:	st.h	zero, a0, 0
1268941e93cSWANG Rui	move	a0, zero
1278941e93cSWANG Rui	jr	ra
1288941e93cSWANG Rui
1298941e93cSWANG Rui	.align	4
1308941e93cSWANG Rui19:	st.h	zero, a0, 0
1318941e93cSWANG Rui20:	st.b	zero, a0, 2
1328941e93cSWANG Rui	move	a0, zero
1338941e93cSWANG Rui	jr	ra
1348941e93cSWANG Rui
1358941e93cSWANG Rui	.align	4
1368941e93cSWANG Rui21:	st.w	zero, a0, 0
1378941e93cSWANG Rui	move	a0, zero
1388941e93cSWANG Rui	jr	ra
1398941e93cSWANG Rui
1408941e93cSWANG Rui	.align	4
1418941e93cSWANG Rui22:	st.w	zero, a0, 0
1428941e93cSWANG Rui23:	st.b	zero, a0, 4
1438941e93cSWANG Rui	move	a0, zero
1448941e93cSWANG Rui	jr	ra
1458941e93cSWANG Rui
1468941e93cSWANG Rui	.align	4
1478941e93cSWANG Rui24:	st.w	zero, a0, 0
1488941e93cSWANG Rui25:	st.h	zero, a0, 4
1498941e93cSWANG Rui	move	a0, zero
1508941e93cSWANG Rui	jr	ra
1518941e93cSWANG Rui
1528941e93cSWANG Rui	.align	4
1538941e93cSWANG Rui26:	st.w	zero, a0, 0
1548941e93cSWANG Rui27:	st.w	zero, a0, 3
1558941e93cSWANG Rui	move	a0, zero
1568941e93cSWANG Rui	jr	ra
1578941e93cSWANG Rui
1588941e93cSWANG Rui	.align	4
1598941e93cSWANG Rui28:	st.d	zero, a0, 0
1608941e93cSWANG Rui	move	a0, zero
161a275a82dSHuacai Chen	jr	ra
162a275a82dSHuacai Chen
163a275a82dSHuacai Chen	/* fixup and ex_table */
164937f6593SWeihao Li.Llarge_fixup:
165937f6593SWeihao Li	sub.d	a1, a2, a0
166937f6593SWeihao Li
167937f6593SWeihao Li.Lsmall_fixup:
168937f6593SWeihao Li29:	st.b	zero, a0, 0
169937f6593SWeihao Li	addi.d	a0, a0, 1
170937f6593SWeihao Li	addi.d	a1, a1, -1
171937f6593SWeihao Li	bgt	a1, zero, 29b
172937f6593SWeihao Li
173937f6593SWeihao Li.Lexit:
174937f6593SWeihao Li	move	a0, a1
175937f6593SWeihao Li	jr	ra
176937f6593SWeihao Li
177937f6593SWeihao Li	_asm_extable 0b, .Lsmall_fixup
178937f6593SWeihao Li	_asm_extable 1b, .Llarge_fixup
179937f6593SWeihao Li	_asm_extable 2b, .Llarge_fixup
180937f6593SWeihao Li	_asm_extable 3b, .Llarge_fixup
181937f6593SWeihao Li	_asm_extable 4b, .Llarge_fixup
182937f6593SWeihao Li	_asm_extable 5b, .Llarge_fixup
183937f6593SWeihao Li	_asm_extable 6b, .Llarge_fixup
184937f6593SWeihao Li	_asm_extable 7b, .Llarge_fixup
185937f6593SWeihao Li	_asm_extable 8b, .Llarge_fixup
186937f6593SWeihao Li	_asm_extable 9b, .Llarge_fixup
187937f6593SWeihao Li	_asm_extable 10b, .Llarge_fixup
188937f6593SWeihao Li	_asm_extable 11b, .Llarge_fixup
189937f6593SWeihao Li	_asm_extable 12b, .Llarge_fixup
190937f6593SWeihao Li	_asm_extable 13b, .Llarge_fixup
191937f6593SWeihao Li	_asm_extable 14b, .Llarge_fixup
192937f6593SWeihao Li	_asm_extable 15b, .Llarge_fixup
193937f6593SWeihao Li	_asm_extable 16b, .Llarge_fixup
194937f6593SWeihao Li	_asm_extable 17b, .Lexit
195937f6593SWeihao Li	_asm_extable 18b, .Lsmall_fixup
196937f6593SWeihao Li	_asm_extable 19b, .Lsmall_fixup
197937f6593SWeihao Li	_asm_extable 20b, .Lsmall_fixup
198937f6593SWeihao Li	_asm_extable 21b, .Lsmall_fixup
199937f6593SWeihao Li	_asm_extable 22b, .Lsmall_fixup
200937f6593SWeihao Li	_asm_extable 23b, .Lsmall_fixup
201937f6593SWeihao Li	_asm_extable 24b, .Lsmall_fixup
202937f6593SWeihao Li	_asm_extable 25b, .Lsmall_fixup
203937f6593SWeihao Li	_asm_extable 26b, .Lsmall_fixup
204937f6593SWeihao Li	_asm_extable 27b, .Lsmall_fixup
205937f6593SWeihao Li	_asm_extable 28b, .Lsmall_fixup
206937f6593SWeihao Li	_asm_extable 29b, .Lexit
207a275a82dSHuacai ChenSYM_FUNC_END(__clear_user_fast)
208*cb8a2ef0STiezhu Yang
209*cb8a2ef0STiezhu YangSTACK_FRAME_NON_STANDARD __clear_user_fast
210