xref: /openbmc/linux/arch/loongarch/lib/clear_user.S (revision a275a82d)
1559671e0SHuacai Chen/* SPDX-License-Identifier: GPL-2.0 */
2559671e0SHuacai Chen/*
3559671e0SHuacai Chen * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4559671e0SHuacai Chen */
5559671e0SHuacai Chen
6*a275a82dSHuacai 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>
10*a275a82dSHuacai Chen#include <asm/cpu.h>
11559671e0SHuacai Chen#include <asm/export.h>
12559671e0SHuacai Chen#include <asm/regdef.h>
13559671e0SHuacai Chen
14*a275a82dSHuacai Chen.irp to, 0, 1, 2, 3, 4, 5, 6, 7
15912bcfafSYouling Tang.L_fixup_handle_\to\():
16912bcfafSYouling Tang	addi.d	a0, a1, (\to) * (-8)
17559671e0SHuacai Chen	jr	ra
18912bcfafSYouling Tang.endr
19559671e0SHuacai Chen
20*a275a82dSHuacai ChenSYM_FUNC_START(__clear_user)
21559671e0SHuacai Chen	/*
22*a275a82dSHuacai Chen	 * Some CPUs support hardware unaligned access
23*a275a82dSHuacai Chen	 */
24*a275a82dSHuacai Chen	ALTERNATIVE	"b __clear_user_generic",	\
25*a275a82dSHuacai Chen			"b __clear_user_fast", CPU_FEATURE_UAL
26*a275a82dSHuacai ChenSYM_FUNC_END(__clear_user)
27*a275a82dSHuacai Chen
28*a275a82dSHuacai ChenEXPORT_SYMBOL(__clear_user)
29*a275a82dSHuacai Chen
30*a275a82dSHuacai Chen/*
31*a275a82dSHuacai Chen * unsigned long __clear_user_generic(void *addr, size_t size)
32559671e0SHuacai Chen *
33559671e0SHuacai Chen * a0: addr
34559671e0SHuacai Chen * a1: size
35559671e0SHuacai Chen */
36*a275a82dSHuacai ChenSYM_FUNC_START(__clear_user_generic)
37559671e0SHuacai Chen	beqz	a1, 2f
38559671e0SHuacai Chen
39559671e0SHuacai Chen1:	st.b	zero, a0, 0
40559671e0SHuacai Chen	addi.d	a0, a0, 1
41559671e0SHuacai Chen	addi.d	a1, a1, -1
421fdb9a92SWANG Xuerui	bgtz	a1, 1b
43559671e0SHuacai Chen
44559671e0SHuacai Chen2:	move	a0, a1
45559671e0SHuacai Chen	jr	ra
46559671e0SHuacai Chen
47912bcfafSYouling Tang	_asm_extable 1b, .L_fixup_handle_0
48*a275a82dSHuacai ChenSYM_FUNC_END(__clear_user_generic)
49559671e0SHuacai Chen
50*a275a82dSHuacai Chen/*
51*a275a82dSHuacai Chen * unsigned long __clear_user_fast(void *addr, unsigned long size)
52*a275a82dSHuacai Chen *
53*a275a82dSHuacai Chen * a0: addr
54*a275a82dSHuacai Chen * a1: size
55*a275a82dSHuacai Chen */
56*a275a82dSHuacai ChenSYM_FUNC_START(__clear_user_fast)
57*a275a82dSHuacai Chen	beqz	a1, 10f
58*a275a82dSHuacai Chen
59*a275a82dSHuacai Chen	ori	a2, zero, 64
60*a275a82dSHuacai Chen	blt	a1, a2, 9f
61*a275a82dSHuacai Chen
62*a275a82dSHuacai Chen	/* set 64 bytes at a time */
63*a275a82dSHuacai Chen1:	st.d	zero, a0, 0
64*a275a82dSHuacai Chen2:	st.d	zero, a0, 8
65*a275a82dSHuacai Chen3:	st.d	zero, a0, 16
66*a275a82dSHuacai Chen4:	st.d	zero, a0, 24
67*a275a82dSHuacai Chen5:	st.d	zero, a0, 32
68*a275a82dSHuacai Chen6:	st.d	zero, a0, 40
69*a275a82dSHuacai Chen7:	st.d	zero, a0, 48
70*a275a82dSHuacai Chen8:	st.d	zero, a0, 56
71*a275a82dSHuacai Chen
72*a275a82dSHuacai Chen	addi.d	a0, a0, 64
73*a275a82dSHuacai Chen	addi.d	a1, a1, -64
74*a275a82dSHuacai Chen	bge	a1, a2, 1b
75*a275a82dSHuacai Chen
76*a275a82dSHuacai Chen	beqz	a1, 10f
77*a275a82dSHuacai Chen
78*a275a82dSHuacai Chen	/* set the remaining bytes */
79*a275a82dSHuacai Chen9:	st.b	zero, a0, 0
80*a275a82dSHuacai Chen	addi.d	a0, a0, 1
81*a275a82dSHuacai Chen	addi.d	a1, a1, -1
82*a275a82dSHuacai Chen	bgt	a1, zero, 9b
83*a275a82dSHuacai Chen
84*a275a82dSHuacai Chen	/* return */
85*a275a82dSHuacai Chen10:	move	a0, a1
86*a275a82dSHuacai Chen	jr	ra
87*a275a82dSHuacai Chen
88*a275a82dSHuacai Chen	/* fixup and ex_table */
89*a275a82dSHuacai Chen	_asm_extable 1b, .L_fixup_handle_0
90*a275a82dSHuacai Chen	_asm_extable 2b, .L_fixup_handle_1
91*a275a82dSHuacai Chen	_asm_extable 3b, .L_fixup_handle_2
92*a275a82dSHuacai Chen	_asm_extable 4b, .L_fixup_handle_3
93*a275a82dSHuacai Chen	_asm_extable 5b, .L_fixup_handle_4
94*a275a82dSHuacai Chen	_asm_extable 6b, .L_fixup_handle_5
95*a275a82dSHuacai Chen	_asm_extable 7b, .L_fixup_handle_6
96*a275a82dSHuacai Chen	_asm_extable 8b, .L_fixup_handle_7
97*a275a82dSHuacai Chen	_asm_extable 9b, .L_fixup_handle_0
98*a275a82dSHuacai ChenSYM_FUNC_END(__clear_user_fast)
99