xref: /openbmc/linux/arch/loongarch/lib/clear_user.S (revision 8941e93c)
1559671e0SHuacai Chen/* SPDX-License-Identifier: GPL-2.0 */
2559671e0SHuacai Chen/*
3559671e0SHuacai Chen * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4559671e0SHuacai Chen */
5559671e0SHuacai Chen
6a275a82dSHuacai Chen#include <asm/alternative-asm.h>
7559671e0SHuacai Chen#include <asm/asm.h>
8559671e0SHuacai Chen#include <asm/asmmacro.h>
9508f28c6SYouling Tang#include <asm/asm-extable.h>
10a275a82dSHuacai Chen#include <asm/cpu.h>
11559671e0SHuacai Chen#include <asm/export.h>
12559671e0SHuacai Chen#include <asm/regdef.h>
13559671e0SHuacai Chen
14a275a82dSHuacai Chen.irp to, 0, 1, 2, 3, 4, 5, 6, 7
15912bcfafSYouling Tang.L_fixup_handle_\to\():
16*8941e93cSWANG Rui	sub.d	a0, a2, a0
17*8941e93cSWANG Rui	addi.d	a0, a0, (\to) * (-8)
18*8941e93cSWANG Rui	jr	ra
19*8941e93cSWANG Rui.endr
20*8941e93cSWANG Rui
21*8941e93cSWANG Rui.irp to, 0, 2, 4
22*8941e93cSWANG Rui.L_fixup_handle_s\to\():
23*8941e93cSWANG Rui	addi.d	a0, a1, -\to
24559671e0SHuacai Chen	jr	ra
25912bcfafSYouling Tang.endr
26559671e0SHuacai Chen
27a275a82dSHuacai ChenSYM_FUNC_START(__clear_user)
28559671e0SHuacai Chen	/*
29a275a82dSHuacai Chen	 * Some CPUs support hardware unaligned access
30a275a82dSHuacai Chen	 */
31a275a82dSHuacai Chen	ALTERNATIVE	"b __clear_user_generic",	\
32a275a82dSHuacai Chen			"b __clear_user_fast", CPU_FEATURE_UAL
33a275a82dSHuacai ChenSYM_FUNC_END(__clear_user)
34a275a82dSHuacai Chen
35a275a82dSHuacai ChenEXPORT_SYMBOL(__clear_user)
36a275a82dSHuacai Chen
37a275a82dSHuacai Chen/*
38a275a82dSHuacai Chen * unsigned long __clear_user_generic(void *addr, size_t size)
39559671e0SHuacai Chen *
40559671e0SHuacai Chen * a0: addr
41559671e0SHuacai Chen * a1: size
42559671e0SHuacai Chen */
43a275a82dSHuacai ChenSYM_FUNC_START(__clear_user_generic)
44559671e0SHuacai Chen	beqz	a1, 2f
45559671e0SHuacai Chen
46559671e0SHuacai Chen1:	st.b	zero, a0, 0
47559671e0SHuacai Chen	addi.d	a0, a0, 1
48559671e0SHuacai Chen	addi.d	a1, a1, -1
491fdb9a92SWANG Xuerui	bgtz	a1, 1b
50559671e0SHuacai Chen
51559671e0SHuacai Chen2:	move	a0, a1
52559671e0SHuacai Chen	jr	ra
53559671e0SHuacai Chen
54*8941e93cSWANG Rui	_asm_extable 1b, .L_fixup_handle_s0
55a275a82dSHuacai ChenSYM_FUNC_END(__clear_user_generic)
56559671e0SHuacai Chen
57a275a82dSHuacai Chen/*
58a275a82dSHuacai Chen * unsigned long __clear_user_fast(void *addr, unsigned long size)
59a275a82dSHuacai Chen *
60a275a82dSHuacai Chen * a0: addr
61a275a82dSHuacai Chen * a1: size
62a275a82dSHuacai Chen */
63a275a82dSHuacai ChenSYM_FUNC_START(__clear_user_fast)
64*8941e93cSWANG Rui	sltui	t0, a1, 9
65*8941e93cSWANG Rui	bnez	t0, .Lsmall
66a275a82dSHuacai Chen
67*8941e93cSWANG Rui	add.d	a2, a0, a1
68*8941e93cSWANG Rui0:	st.d	zero, a0, 0
69*8941e93cSWANG Rui
70*8941e93cSWANG Rui	/* align up address */
71*8941e93cSWANG Rui	addi.d	a0, a0, 8
72*8941e93cSWANG Rui	bstrins.d	a0, zero, 2, 0
73*8941e93cSWANG Rui
74*8941e93cSWANG Rui	addi.d	a3, a2, -64
75*8941e93cSWANG Rui	bgeu	a0, a3, .Llt64
76a275a82dSHuacai Chen
77a275a82dSHuacai Chen	/* set 64 bytes at a time */
78*8941e93cSWANG Rui.Lloop64:
79a275a82dSHuacai Chen1:	st.d	zero, a0, 0
80a275a82dSHuacai Chen2:	st.d	zero, a0, 8
81a275a82dSHuacai Chen3:	st.d	zero, a0, 16
82a275a82dSHuacai Chen4:	st.d	zero, a0, 24
83a275a82dSHuacai Chen5:	st.d	zero, a0, 32
84a275a82dSHuacai Chen6:	st.d	zero, a0, 40
85a275a82dSHuacai Chen7:	st.d	zero, a0, 48
86a275a82dSHuacai Chen8:	st.d	zero, a0, 56
87a275a82dSHuacai Chen	addi.d	a0, a0, 64
88*8941e93cSWANG Rui	bltu	a0, a3, .Lloop64
89a275a82dSHuacai Chen
90a275a82dSHuacai Chen	/* set the remaining bytes */
91*8941e93cSWANG Rui.Llt64:
92*8941e93cSWANG Rui	addi.d	a3, a2, -32
93*8941e93cSWANG Rui	bgeu	a0, a3, .Llt32
94*8941e93cSWANG Rui9:	st.d	zero, a0, 0
95*8941e93cSWANG Rui10:	st.d	zero, a0, 8
96*8941e93cSWANG Rui11:	st.d	zero, a0, 16
97*8941e93cSWANG Rui12:	st.d	zero, a0, 24
98*8941e93cSWANG Rui	addi.d	a0, a0, 32
99*8941e93cSWANG Rui
100*8941e93cSWANG Rui.Llt32:
101*8941e93cSWANG Rui	addi.d	a3, a2, -16
102*8941e93cSWANG Rui	bgeu	a0, a3, .Llt16
103*8941e93cSWANG Rui13:	st.d	zero, a0, 0
104*8941e93cSWANG Rui14:	st.d	zero, a0, 8
105*8941e93cSWANG Rui	addi.d	a0, a0, 16
106*8941e93cSWANG Rui
107*8941e93cSWANG Rui.Llt16:
108*8941e93cSWANG Rui	addi.d	a3, a2, -8
109*8941e93cSWANG Rui	bgeu	a0, a3, .Llt8
110*8941e93cSWANG Rui15:	st.d	zero, a0, 0
111*8941e93cSWANG Rui
112*8941e93cSWANG Rui.Llt8:
113*8941e93cSWANG Rui16:	st.d	zero, a2, -8
114a275a82dSHuacai Chen
115a275a82dSHuacai Chen	/* return */
116*8941e93cSWANG Rui	move	a0, zero
117*8941e93cSWANG Rui	jr	ra
118*8941e93cSWANG Rui
119*8941e93cSWANG Rui	.align	4
120*8941e93cSWANG Rui.Lsmall:
121*8941e93cSWANG Rui	pcaddi	t0, 4
122*8941e93cSWANG Rui	slli.d	a2, a1, 4
123*8941e93cSWANG Rui	add.d	t0, t0, a2
124*8941e93cSWANG Rui	jr	t0
125*8941e93cSWANG Rui
126*8941e93cSWANG Rui	.align	4
127*8941e93cSWANG Rui	move	a0, zero
128*8941e93cSWANG Rui	jr	ra
129*8941e93cSWANG Rui
130*8941e93cSWANG Rui	.align	4
131*8941e93cSWANG Rui17:	st.b	zero, a0, 0
132*8941e93cSWANG Rui	move	a0, zero
133*8941e93cSWANG Rui	jr	ra
134*8941e93cSWANG Rui
135*8941e93cSWANG Rui	.align	4
136*8941e93cSWANG Rui18:	st.h	zero, a0, 0
137*8941e93cSWANG Rui	move	a0, zero
138*8941e93cSWANG Rui	jr	ra
139*8941e93cSWANG Rui
140*8941e93cSWANG Rui	.align	4
141*8941e93cSWANG Rui19:	st.h	zero, a0, 0
142*8941e93cSWANG Rui20:	st.b	zero, a0, 2
143*8941e93cSWANG Rui	move	a0, zero
144*8941e93cSWANG Rui	jr	ra
145*8941e93cSWANG Rui
146*8941e93cSWANG Rui	.align	4
147*8941e93cSWANG Rui21:	st.w	zero, a0, 0
148*8941e93cSWANG Rui	move	a0, zero
149*8941e93cSWANG Rui	jr	ra
150*8941e93cSWANG Rui
151*8941e93cSWANG Rui	.align	4
152*8941e93cSWANG Rui22:	st.w	zero, a0, 0
153*8941e93cSWANG Rui23:	st.b	zero, a0, 4
154*8941e93cSWANG Rui	move	a0, zero
155*8941e93cSWANG Rui	jr	ra
156*8941e93cSWANG Rui
157*8941e93cSWANG Rui	.align	4
158*8941e93cSWANG Rui24:	st.w	zero, a0, 0
159*8941e93cSWANG Rui25:	st.h	zero, a0, 4
160*8941e93cSWANG Rui	move	a0, zero
161*8941e93cSWANG Rui	jr	ra
162*8941e93cSWANG Rui
163*8941e93cSWANG Rui	.align	4
164*8941e93cSWANG Rui26:	st.w	zero, a0, 0
165*8941e93cSWANG Rui27:	st.w	zero, a0, 3
166*8941e93cSWANG Rui	move	a0, zero
167*8941e93cSWANG Rui	jr	ra
168*8941e93cSWANG Rui
169*8941e93cSWANG Rui	.align	4
170*8941e93cSWANG Rui28:	st.d	zero, a0, 0
171*8941e93cSWANG Rui	move	a0, zero
172a275a82dSHuacai Chen	jr	ra
173a275a82dSHuacai Chen
174a275a82dSHuacai Chen	/* fixup and ex_table */
175*8941e93cSWANG Rui	_asm_extable 0b, .L_fixup_handle_0
176a275a82dSHuacai Chen	_asm_extable 1b, .L_fixup_handle_0
177a275a82dSHuacai Chen	_asm_extable 2b, .L_fixup_handle_1
178a275a82dSHuacai Chen	_asm_extable 3b, .L_fixup_handle_2
179a275a82dSHuacai Chen	_asm_extable 4b, .L_fixup_handle_3
180a275a82dSHuacai Chen	_asm_extable 5b, .L_fixup_handle_4
181a275a82dSHuacai Chen	_asm_extable 6b, .L_fixup_handle_5
182a275a82dSHuacai Chen	_asm_extable 7b, .L_fixup_handle_6
183a275a82dSHuacai Chen	_asm_extable 8b, .L_fixup_handle_7
184a275a82dSHuacai Chen	_asm_extable 9b, .L_fixup_handle_0
185*8941e93cSWANG Rui	_asm_extable 10b, .L_fixup_handle_1
186*8941e93cSWANG Rui	_asm_extable 11b, .L_fixup_handle_2
187*8941e93cSWANG Rui	_asm_extable 12b, .L_fixup_handle_3
188*8941e93cSWANG Rui	_asm_extable 13b, .L_fixup_handle_0
189*8941e93cSWANG Rui	_asm_extable 14b, .L_fixup_handle_1
190*8941e93cSWANG Rui	_asm_extable 15b, .L_fixup_handle_0
191*8941e93cSWANG Rui	_asm_extable 16b, .L_fixup_handle_1
192*8941e93cSWANG Rui	_asm_extable 17b, .L_fixup_handle_s0
193*8941e93cSWANG Rui	_asm_extable 18b, .L_fixup_handle_s0
194*8941e93cSWANG Rui	_asm_extable 19b, .L_fixup_handle_s0
195*8941e93cSWANG Rui	_asm_extable 20b, .L_fixup_handle_s2
196*8941e93cSWANG Rui	_asm_extable 21b, .L_fixup_handle_s0
197*8941e93cSWANG Rui	_asm_extable 22b, .L_fixup_handle_s0
198*8941e93cSWANG Rui	_asm_extable 23b, .L_fixup_handle_s4
199*8941e93cSWANG Rui	_asm_extable 24b, .L_fixup_handle_s0
200*8941e93cSWANG Rui	_asm_extable 25b, .L_fixup_handle_s4
201*8941e93cSWANG Rui	_asm_extable 26b, .L_fixup_handle_s0
202*8941e93cSWANG Rui	_asm_extable 27b, .L_fixup_handle_s4
203*8941e93cSWANG Rui	_asm_extable 28b, .L_fixup_handle_s0
204a275a82dSHuacai ChenSYM_FUNC_END(__clear_user_fast)
205