xref: /linux/arch/loongarch/kernel/fpu.S (revision 928f79a188aacc057ba36c85b36b6d1e99c8f595)
1803b0fc5SHuacai Chen/* SPDX-License-Identifier: GPL-2.0 */
2803b0fc5SHuacai Chen/*
3803b0fc5SHuacai Chen * Author: Lu Zeng <zenglu@loongson.cn>
4803b0fc5SHuacai Chen *         Pei Huang <huangpei@loongson.cn>
5803b0fc5SHuacai Chen *         Huacai Chen <chenhuacai@loongson.cn>
6803b0fc5SHuacai Chen *
7803b0fc5SHuacai Chen * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
8803b0fc5SHuacai Chen */
955b46ff9SMasahiro Yamada#include <linux/export.h>
10803b0fc5SHuacai Chen#include <asm/asm.h>
11803b0fc5SHuacai Chen#include <asm/asmmacro.h>
12508f28c6SYouling Tang#include <asm/asm-extable.h>
13803b0fc5SHuacai Chen#include <asm/asm-offsets.h>
14803b0fc5SHuacai Chen#include <asm/errno.h>
15803b0fc5SHuacai Chen#include <asm/fpregdef.h>
16803b0fc5SHuacai Chen#include <asm/loongarch.h>
17803b0fc5SHuacai Chen#include <asm/regdef.h>
18cb8a2ef0STiezhu Yang#include <asm/unwind_hints.h>
19803b0fc5SHuacai Chen
20803b0fc5SHuacai Chen#define FPU_REG_WIDTH		8
21803b0fc5SHuacai Chen#define LSX_REG_WIDTH		16
22803b0fc5SHuacai Chen#define LASX_REG_WIDTH		32
23803b0fc5SHuacai Chen
24803b0fc5SHuacai Chen	.macro	EX insn, reg, src, offs
25803b0fc5SHuacai Chen.ex\@:	\insn	\reg, \src, \offs
268f58c571STiezhu Yang	_asm_extable .ex\@, .L_fpu_fault
27803b0fc5SHuacai Chen	.endm
28803b0fc5SHuacai Chen
29803b0fc5SHuacai Chen	.macro sc_save_fp base
30803b0fc5SHuacai Chen	EX	fst.d	$f0,  \base, (0 * FPU_REG_WIDTH)
31803b0fc5SHuacai Chen	EX	fst.d	$f1,  \base, (1 * FPU_REG_WIDTH)
32803b0fc5SHuacai Chen	EX	fst.d	$f2,  \base, (2 * FPU_REG_WIDTH)
33803b0fc5SHuacai Chen	EX	fst.d	$f3,  \base, (3 * FPU_REG_WIDTH)
34803b0fc5SHuacai Chen	EX	fst.d	$f4,  \base, (4 * FPU_REG_WIDTH)
35803b0fc5SHuacai Chen	EX	fst.d	$f5,  \base, (5 * FPU_REG_WIDTH)
36803b0fc5SHuacai Chen	EX	fst.d	$f6,  \base, (6 * FPU_REG_WIDTH)
37803b0fc5SHuacai Chen	EX	fst.d	$f7,  \base, (7 * FPU_REG_WIDTH)
38803b0fc5SHuacai Chen	EX	fst.d	$f8,  \base, (8 * FPU_REG_WIDTH)
39803b0fc5SHuacai Chen	EX	fst.d	$f9,  \base, (9 * FPU_REG_WIDTH)
40803b0fc5SHuacai Chen	EX	fst.d	$f10, \base, (10 * FPU_REG_WIDTH)
41803b0fc5SHuacai Chen	EX	fst.d	$f11, \base, (11 * FPU_REG_WIDTH)
42803b0fc5SHuacai Chen	EX	fst.d	$f12, \base, (12 * FPU_REG_WIDTH)
43803b0fc5SHuacai Chen	EX	fst.d	$f13, \base, (13 * FPU_REG_WIDTH)
44803b0fc5SHuacai Chen	EX	fst.d	$f14, \base, (14 * FPU_REG_WIDTH)
45803b0fc5SHuacai Chen	EX	fst.d	$f15, \base, (15 * FPU_REG_WIDTH)
46803b0fc5SHuacai Chen	EX	fst.d	$f16, \base, (16 * FPU_REG_WIDTH)
47803b0fc5SHuacai Chen	EX	fst.d	$f17, \base, (17 * FPU_REG_WIDTH)
48803b0fc5SHuacai Chen	EX	fst.d	$f18, \base, (18 * FPU_REG_WIDTH)
49803b0fc5SHuacai Chen	EX	fst.d	$f19, \base, (19 * FPU_REG_WIDTH)
50803b0fc5SHuacai Chen	EX	fst.d	$f20, \base, (20 * FPU_REG_WIDTH)
51803b0fc5SHuacai Chen	EX	fst.d	$f21, \base, (21 * FPU_REG_WIDTH)
52803b0fc5SHuacai Chen	EX	fst.d	$f22, \base, (22 * FPU_REG_WIDTH)
53803b0fc5SHuacai Chen	EX	fst.d	$f23, \base, (23 * FPU_REG_WIDTH)
54803b0fc5SHuacai Chen	EX	fst.d	$f24, \base, (24 * FPU_REG_WIDTH)
55803b0fc5SHuacai Chen	EX	fst.d	$f25, \base, (25 * FPU_REG_WIDTH)
56803b0fc5SHuacai Chen	EX	fst.d	$f26, \base, (26 * FPU_REG_WIDTH)
57803b0fc5SHuacai Chen	EX	fst.d	$f27, \base, (27 * FPU_REG_WIDTH)
58803b0fc5SHuacai Chen	EX	fst.d	$f28, \base, (28 * FPU_REG_WIDTH)
59803b0fc5SHuacai Chen	EX	fst.d	$f29, \base, (29 * FPU_REG_WIDTH)
60803b0fc5SHuacai Chen	EX	fst.d	$f30, \base, (30 * FPU_REG_WIDTH)
61803b0fc5SHuacai Chen	EX	fst.d	$f31, \base, (31 * FPU_REG_WIDTH)
62803b0fc5SHuacai Chen	.endm
63803b0fc5SHuacai Chen
64803b0fc5SHuacai Chen	.macro sc_restore_fp base
65803b0fc5SHuacai Chen	EX	fld.d	$f0,  \base, (0 * FPU_REG_WIDTH)
66803b0fc5SHuacai Chen	EX	fld.d	$f1,  \base, (1 * FPU_REG_WIDTH)
67803b0fc5SHuacai Chen	EX	fld.d	$f2,  \base, (2 * FPU_REG_WIDTH)
68803b0fc5SHuacai Chen	EX	fld.d	$f3,  \base, (3 * FPU_REG_WIDTH)
69803b0fc5SHuacai Chen	EX	fld.d	$f4,  \base, (4 * FPU_REG_WIDTH)
70803b0fc5SHuacai Chen	EX	fld.d	$f5,  \base, (5 * FPU_REG_WIDTH)
71803b0fc5SHuacai Chen	EX	fld.d	$f6,  \base, (6 * FPU_REG_WIDTH)
72803b0fc5SHuacai Chen	EX	fld.d	$f7,  \base, (7 * FPU_REG_WIDTH)
73803b0fc5SHuacai Chen	EX	fld.d	$f8,  \base, (8 * FPU_REG_WIDTH)
74803b0fc5SHuacai Chen	EX	fld.d	$f9,  \base, (9 * FPU_REG_WIDTH)
75803b0fc5SHuacai Chen	EX	fld.d	$f10, \base, (10 * FPU_REG_WIDTH)
76803b0fc5SHuacai Chen	EX	fld.d	$f11, \base, (11 * FPU_REG_WIDTH)
77803b0fc5SHuacai Chen	EX	fld.d	$f12, \base, (12 * FPU_REG_WIDTH)
78803b0fc5SHuacai Chen	EX	fld.d	$f13, \base, (13 * FPU_REG_WIDTH)
79803b0fc5SHuacai Chen	EX	fld.d	$f14, \base, (14 * FPU_REG_WIDTH)
80803b0fc5SHuacai Chen	EX	fld.d	$f15, \base, (15 * FPU_REG_WIDTH)
81803b0fc5SHuacai Chen	EX	fld.d	$f16, \base, (16 * FPU_REG_WIDTH)
82803b0fc5SHuacai Chen	EX	fld.d	$f17, \base, (17 * FPU_REG_WIDTH)
83803b0fc5SHuacai Chen	EX	fld.d	$f18, \base, (18 * FPU_REG_WIDTH)
84803b0fc5SHuacai Chen	EX	fld.d	$f19, \base, (19 * FPU_REG_WIDTH)
85803b0fc5SHuacai Chen	EX	fld.d	$f20, \base, (20 * FPU_REG_WIDTH)
86803b0fc5SHuacai Chen	EX	fld.d	$f21, \base, (21 * FPU_REG_WIDTH)
87803b0fc5SHuacai Chen	EX	fld.d	$f22, \base, (22 * FPU_REG_WIDTH)
88803b0fc5SHuacai Chen	EX	fld.d	$f23, \base, (23 * FPU_REG_WIDTH)
89803b0fc5SHuacai Chen	EX	fld.d	$f24, \base, (24 * FPU_REG_WIDTH)
90803b0fc5SHuacai Chen	EX	fld.d	$f25, \base, (25 * FPU_REG_WIDTH)
91803b0fc5SHuacai Chen	EX	fld.d	$f26, \base, (26 * FPU_REG_WIDTH)
92803b0fc5SHuacai Chen	EX	fld.d	$f27, \base, (27 * FPU_REG_WIDTH)
93803b0fc5SHuacai Chen	EX	fld.d	$f28, \base, (28 * FPU_REG_WIDTH)
94803b0fc5SHuacai Chen	EX	fld.d	$f29, \base, (29 * FPU_REG_WIDTH)
95803b0fc5SHuacai Chen	EX	fld.d	$f30, \base, (30 * FPU_REG_WIDTH)
96803b0fc5SHuacai Chen	EX	fld.d	$f31, \base, (31 * FPU_REG_WIDTH)
97803b0fc5SHuacai Chen	.endm
98803b0fc5SHuacai Chen
99803b0fc5SHuacai Chen	.macro sc_save_fcc base, tmp0, tmp1
100803b0fc5SHuacai Chen	movcf2gr	\tmp0, $fcc0
101803b0fc5SHuacai Chen	move		\tmp1, \tmp0
102803b0fc5SHuacai Chen	movcf2gr	\tmp0, $fcc1
103803b0fc5SHuacai Chen	bstrins.d	\tmp1, \tmp0, 15, 8
104803b0fc5SHuacai Chen	movcf2gr	\tmp0, $fcc2
105803b0fc5SHuacai Chen	bstrins.d	\tmp1, \tmp0, 23, 16
106803b0fc5SHuacai Chen	movcf2gr	\tmp0, $fcc3
107803b0fc5SHuacai Chen	bstrins.d	\tmp1, \tmp0, 31, 24
108803b0fc5SHuacai Chen	movcf2gr	\tmp0, $fcc4
109803b0fc5SHuacai Chen	bstrins.d	\tmp1, \tmp0, 39, 32
110803b0fc5SHuacai Chen	movcf2gr	\tmp0, $fcc5
111803b0fc5SHuacai Chen	bstrins.d	\tmp1, \tmp0, 47, 40
112803b0fc5SHuacai Chen	movcf2gr	\tmp0, $fcc6
113803b0fc5SHuacai Chen	bstrins.d	\tmp1, \tmp0, 55, 48
114803b0fc5SHuacai Chen	movcf2gr	\tmp0, $fcc7
115803b0fc5SHuacai Chen	bstrins.d	\tmp1, \tmp0, 63, 56
116803b0fc5SHuacai Chen	EX	st.d	\tmp1, \base, 0
117803b0fc5SHuacai Chen	.endm
118803b0fc5SHuacai Chen
119803b0fc5SHuacai Chen	.macro sc_restore_fcc base, tmp0, tmp1
120803b0fc5SHuacai Chen	EX	ld.d	\tmp0, \base, 0
121803b0fc5SHuacai Chen	bstrpick.d	\tmp1, \tmp0, 7, 0
122803b0fc5SHuacai Chen	movgr2cf	$fcc0, \tmp1
123803b0fc5SHuacai Chen	bstrpick.d	\tmp1, \tmp0, 15, 8
124803b0fc5SHuacai Chen	movgr2cf	$fcc1, \tmp1
125803b0fc5SHuacai Chen	bstrpick.d	\tmp1, \tmp0, 23, 16
126803b0fc5SHuacai Chen	movgr2cf	$fcc2, \tmp1
127803b0fc5SHuacai Chen	bstrpick.d	\tmp1, \tmp0, 31, 24
128803b0fc5SHuacai Chen	movgr2cf	$fcc3, \tmp1
129803b0fc5SHuacai Chen	bstrpick.d	\tmp1, \tmp0, 39, 32
130803b0fc5SHuacai Chen	movgr2cf	$fcc4, \tmp1
131803b0fc5SHuacai Chen	bstrpick.d	\tmp1, \tmp0, 47, 40
132803b0fc5SHuacai Chen	movgr2cf	$fcc5, \tmp1
133803b0fc5SHuacai Chen	bstrpick.d	\tmp1, \tmp0, 55, 48
134803b0fc5SHuacai Chen	movgr2cf	$fcc6, \tmp1
135803b0fc5SHuacai Chen	bstrpick.d	\tmp1, \tmp0, 63, 56
136803b0fc5SHuacai Chen	movgr2cf	$fcc7, \tmp1
137803b0fc5SHuacai Chen	.endm
138803b0fc5SHuacai Chen
139803b0fc5SHuacai Chen	.macro sc_save_fcsr base, tmp0
140803b0fc5SHuacai Chen	movfcsr2gr	\tmp0, fcsr0
141803b0fc5SHuacai Chen	EX	st.w	\tmp0, \base, 0
142bd3c5798SQi Hu#if defined(CONFIG_CPU_HAS_LBT)
143bd3c5798SQi Hu	/* TM bit is always 0 if LBT not supported */
144bd3c5798SQi Hu	andi		\tmp0, \tmp0, FPU_CSR_TM
145bd3c5798SQi Hu	beqz		\tmp0, 1f
146bd3c5798SQi Hu	x86clrtm
147bd3c5798SQi Hu1:
148bd3c5798SQi Hu#endif
149803b0fc5SHuacai Chen	.endm
150803b0fc5SHuacai Chen
151803b0fc5SHuacai Chen	.macro sc_restore_fcsr base, tmp0
152803b0fc5SHuacai Chen	EX	ld.w	\tmp0, \base, 0
153803b0fc5SHuacai Chen	movgr2fcsr	fcsr0, \tmp0
154803b0fc5SHuacai Chen	.endm
155803b0fc5SHuacai Chen
15661650023SHuacai Chen	.macro sc_save_lsx base
15761650023SHuacai Chen#ifdef CONFIG_CPU_HAS_LSX
15861650023SHuacai Chen	EX	vst	$vr0,  \base, (0 * LSX_REG_WIDTH)
15961650023SHuacai Chen	EX	vst	$vr1,  \base, (1 * LSX_REG_WIDTH)
16061650023SHuacai Chen	EX	vst	$vr2,  \base, (2 * LSX_REG_WIDTH)
16161650023SHuacai Chen	EX	vst	$vr3,  \base, (3 * LSX_REG_WIDTH)
16261650023SHuacai Chen	EX	vst	$vr4,  \base, (4 * LSX_REG_WIDTH)
16361650023SHuacai Chen	EX	vst	$vr5,  \base, (5 * LSX_REG_WIDTH)
16461650023SHuacai Chen	EX	vst	$vr6,  \base, (6 * LSX_REG_WIDTH)
16561650023SHuacai Chen	EX	vst	$vr7,  \base, (7 * LSX_REG_WIDTH)
16661650023SHuacai Chen	EX	vst	$vr8,  \base, (8 * LSX_REG_WIDTH)
16761650023SHuacai Chen	EX	vst	$vr9,  \base, (9 * LSX_REG_WIDTH)
16861650023SHuacai Chen	EX	vst	$vr10, \base, (10 * LSX_REG_WIDTH)
16961650023SHuacai Chen	EX	vst	$vr11, \base, (11 * LSX_REG_WIDTH)
17061650023SHuacai Chen	EX	vst	$vr12, \base, (12 * LSX_REG_WIDTH)
17161650023SHuacai Chen	EX	vst	$vr13, \base, (13 * LSX_REG_WIDTH)
17261650023SHuacai Chen	EX	vst	$vr14, \base, (14 * LSX_REG_WIDTH)
17361650023SHuacai Chen	EX	vst	$vr15, \base, (15 * LSX_REG_WIDTH)
17461650023SHuacai Chen	EX	vst	$vr16, \base, (16 * LSX_REG_WIDTH)
17561650023SHuacai Chen	EX	vst	$vr17, \base, (17 * LSX_REG_WIDTH)
17661650023SHuacai Chen	EX	vst	$vr18, \base, (18 * LSX_REG_WIDTH)
17761650023SHuacai Chen	EX	vst	$vr19, \base, (19 * LSX_REG_WIDTH)
17861650023SHuacai Chen	EX	vst	$vr20, \base, (20 * LSX_REG_WIDTH)
17961650023SHuacai Chen	EX	vst	$vr21, \base, (21 * LSX_REG_WIDTH)
18061650023SHuacai Chen	EX	vst	$vr22, \base, (22 * LSX_REG_WIDTH)
18161650023SHuacai Chen	EX	vst	$vr23, \base, (23 * LSX_REG_WIDTH)
18261650023SHuacai Chen	EX	vst	$vr24, \base, (24 * LSX_REG_WIDTH)
18361650023SHuacai Chen	EX	vst	$vr25, \base, (25 * LSX_REG_WIDTH)
18461650023SHuacai Chen	EX	vst	$vr26, \base, (26 * LSX_REG_WIDTH)
18561650023SHuacai Chen	EX	vst	$vr27, \base, (27 * LSX_REG_WIDTH)
18661650023SHuacai Chen	EX	vst	$vr28, \base, (28 * LSX_REG_WIDTH)
18761650023SHuacai Chen	EX	vst	$vr29, \base, (29 * LSX_REG_WIDTH)
18861650023SHuacai Chen	EX	vst	$vr30, \base, (30 * LSX_REG_WIDTH)
18961650023SHuacai Chen	EX	vst	$vr31, \base, (31 * LSX_REG_WIDTH)
19061650023SHuacai Chen#endif
19161650023SHuacai Chen	.endm
19261650023SHuacai Chen
19361650023SHuacai Chen	.macro sc_restore_lsx base
19461650023SHuacai Chen#ifdef CONFIG_CPU_HAS_LSX
19561650023SHuacai Chen	EX	vld	$vr0,  \base, (0 * LSX_REG_WIDTH)
19661650023SHuacai Chen	EX	vld	$vr1,  \base, (1 * LSX_REG_WIDTH)
19761650023SHuacai Chen	EX	vld	$vr2,  \base, (2 * LSX_REG_WIDTH)
19861650023SHuacai Chen	EX	vld	$vr3,  \base, (3 * LSX_REG_WIDTH)
19961650023SHuacai Chen	EX	vld	$vr4,  \base, (4 * LSX_REG_WIDTH)
20061650023SHuacai Chen	EX	vld	$vr5,  \base, (5 * LSX_REG_WIDTH)
20161650023SHuacai Chen	EX	vld	$vr6,  \base, (6 * LSX_REG_WIDTH)
20261650023SHuacai Chen	EX	vld	$vr7,  \base, (7 * LSX_REG_WIDTH)
20361650023SHuacai Chen	EX	vld	$vr8,  \base, (8 * LSX_REG_WIDTH)
20461650023SHuacai Chen	EX	vld	$vr9,  \base, (9 * LSX_REG_WIDTH)
20561650023SHuacai Chen	EX	vld	$vr10, \base, (10 * LSX_REG_WIDTH)
20661650023SHuacai Chen	EX	vld	$vr11, \base, (11 * LSX_REG_WIDTH)
20761650023SHuacai Chen	EX	vld	$vr12, \base, (12 * LSX_REG_WIDTH)
20861650023SHuacai Chen	EX	vld	$vr13, \base, (13 * LSX_REG_WIDTH)
20961650023SHuacai Chen	EX	vld	$vr14, \base, (14 * LSX_REG_WIDTH)
21061650023SHuacai Chen	EX	vld	$vr15, \base, (15 * LSX_REG_WIDTH)
21161650023SHuacai Chen	EX	vld	$vr16, \base, (16 * LSX_REG_WIDTH)
21261650023SHuacai Chen	EX	vld	$vr17, \base, (17 * LSX_REG_WIDTH)
21361650023SHuacai Chen	EX	vld	$vr18, \base, (18 * LSX_REG_WIDTH)
21461650023SHuacai Chen	EX	vld	$vr19, \base, (19 * LSX_REG_WIDTH)
21561650023SHuacai Chen	EX	vld	$vr20, \base, (20 * LSX_REG_WIDTH)
21661650023SHuacai Chen	EX	vld	$vr21, \base, (21 * LSX_REG_WIDTH)
21761650023SHuacai Chen	EX	vld	$vr22, \base, (22 * LSX_REG_WIDTH)
21861650023SHuacai Chen	EX	vld	$vr23, \base, (23 * LSX_REG_WIDTH)
21961650023SHuacai Chen	EX	vld	$vr24, \base, (24 * LSX_REG_WIDTH)
22061650023SHuacai Chen	EX	vld	$vr25, \base, (25 * LSX_REG_WIDTH)
22161650023SHuacai Chen	EX	vld	$vr26, \base, (26 * LSX_REG_WIDTH)
22261650023SHuacai Chen	EX	vld	$vr27, \base, (27 * LSX_REG_WIDTH)
22361650023SHuacai Chen	EX	vld	$vr28, \base, (28 * LSX_REG_WIDTH)
22461650023SHuacai Chen	EX	vld	$vr29, \base, (29 * LSX_REG_WIDTH)
22561650023SHuacai Chen	EX	vld	$vr30, \base, (30 * LSX_REG_WIDTH)
22661650023SHuacai Chen	EX	vld	$vr31, \base, (31 * LSX_REG_WIDTH)
22761650023SHuacai Chen#endif
22861650023SHuacai Chen	.endm
22961650023SHuacai Chen
23061650023SHuacai Chen	.macro sc_save_lasx base
23161650023SHuacai Chen#ifdef CONFIG_CPU_HAS_LASX
23261650023SHuacai Chen	EX	xvst	$xr0,  \base, (0 * LASX_REG_WIDTH)
23361650023SHuacai Chen	EX	xvst	$xr1,  \base, (1 * LASX_REG_WIDTH)
23461650023SHuacai Chen	EX	xvst	$xr2,  \base, (2 * LASX_REG_WIDTH)
23561650023SHuacai Chen	EX	xvst	$xr3,  \base, (3 * LASX_REG_WIDTH)
23661650023SHuacai Chen	EX	xvst	$xr4,  \base, (4 * LASX_REG_WIDTH)
23761650023SHuacai Chen	EX	xvst	$xr5,  \base, (5 * LASX_REG_WIDTH)
23861650023SHuacai Chen	EX	xvst	$xr6,  \base, (6 * LASX_REG_WIDTH)
23961650023SHuacai Chen	EX	xvst	$xr7,  \base, (7 * LASX_REG_WIDTH)
24061650023SHuacai Chen	EX	xvst	$xr8,  \base, (8 * LASX_REG_WIDTH)
24161650023SHuacai Chen	EX	xvst	$xr9,  \base, (9 * LASX_REG_WIDTH)
24261650023SHuacai Chen	EX	xvst	$xr10, \base, (10 * LASX_REG_WIDTH)
24361650023SHuacai Chen	EX	xvst	$xr11, \base, (11 * LASX_REG_WIDTH)
24461650023SHuacai Chen	EX	xvst	$xr12, \base, (12 * LASX_REG_WIDTH)
24561650023SHuacai Chen	EX	xvst	$xr13, \base, (13 * LASX_REG_WIDTH)
24661650023SHuacai Chen	EX	xvst	$xr14, \base, (14 * LASX_REG_WIDTH)
24761650023SHuacai Chen	EX	xvst	$xr15, \base, (15 * LASX_REG_WIDTH)
24861650023SHuacai Chen	EX	xvst	$xr16, \base, (16 * LASX_REG_WIDTH)
24961650023SHuacai Chen	EX	xvst	$xr17, \base, (17 * LASX_REG_WIDTH)
25061650023SHuacai Chen	EX	xvst	$xr18, \base, (18 * LASX_REG_WIDTH)
25161650023SHuacai Chen	EX	xvst	$xr19, \base, (19 * LASX_REG_WIDTH)
25261650023SHuacai Chen	EX	xvst	$xr20, \base, (20 * LASX_REG_WIDTH)
25361650023SHuacai Chen	EX	xvst	$xr21, \base, (21 * LASX_REG_WIDTH)
25461650023SHuacai Chen	EX	xvst	$xr22, \base, (22 * LASX_REG_WIDTH)
25561650023SHuacai Chen	EX	xvst	$xr23, \base, (23 * LASX_REG_WIDTH)
25661650023SHuacai Chen	EX	xvst	$xr24, \base, (24 * LASX_REG_WIDTH)
25761650023SHuacai Chen	EX	xvst	$xr25, \base, (25 * LASX_REG_WIDTH)
25861650023SHuacai Chen	EX	xvst	$xr26, \base, (26 * LASX_REG_WIDTH)
25961650023SHuacai Chen	EX	xvst	$xr27, \base, (27 * LASX_REG_WIDTH)
26061650023SHuacai Chen	EX	xvst	$xr28, \base, (28 * LASX_REG_WIDTH)
26161650023SHuacai Chen	EX	xvst	$xr29, \base, (29 * LASX_REG_WIDTH)
26261650023SHuacai Chen	EX	xvst	$xr30, \base, (30 * LASX_REG_WIDTH)
26361650023SHuacai Chen	EX	xvst	$xr31, \base, (31 * LASX_REG_WIDTH)
26461650023SHuacai Chen#endif
26561650023SHuacai Chen	.endm
26661650023SHuacai Chen
26761650023SHuacai Chen	.macro sc_restore_lasx base
26861650023SHuacai Chen#ifdef CONFIG_CPU_HAS_LASX
26961650023SHuacai Chen	EX	xvld	$xr0,  \base, (0 * LASX_REG_WIDTH)
27061650023SHuacai Chen	EX	xvld	$xr1,  \base, (1 * LASX_REG_WIDTH)
27161650023SHuacai Chen	EX	xvld	$xr2,  \base, (2 * LASX_REG_WIDTH)
27261650023SHuacai Chen	EX	xvld	$xr3,  \base, (3 * LASX_REG_WIDTH)
27361650023SHuacai Chen	EX	xvld	$xr4,  \base, (4 * LASX_REG_WIDTH)
27461650023SHuacai Chen	EX	xvld	$xr5,  \base, (5 * LASX_REG_WIDTH)
27561650023SHuacai Chen	EX	xvld	$xr6,  \base, (6 * LASX_REG_WIDTH)
27661650023SHuacai Chen	EX	xvld	$xr7,  \base, (7 * LASX_REG_WIDTH)
27761650023SHuacai Chen	EX	xvld	$xr8,  \base, (8 * LASX_REG_WIDTH)
27861650023SHuacai Chen	EX	xvld	$xr9,  \base, (9 * LASX_REG_WIDTH)
27961650023SHuacai Chen	EX	xvld	$xr10, \base, (10 * LASX_REG_WIDTH)
28061650023SHuacai Chen	EX	xvld	$xr11, \base, (11 * LASX_REG_WIDTH)
28161650023SHuacai Chen	EX	xvld	$xr12, \base, (12 * LASX_REG_WIDTH)
28261650023SHuacai Chen	EX	xvld	$xr13, \base, (13 * LASX_REG_WIDTH)
28361650023SHuacai Chen	EX	xvld	$xr14, \base, (14 * LASX_REG_WIDTH)
28461650023SHuacai Chen	EX	xvld	$xr15, \base, (15 * LASX_REG_WIDTH)
28561650023SHuacai Chen	EX	xvld	$xr16, \base, (16 * LASX_REG_WIDTH)
28661650023SHuacai Chen	EX	xvld	$xr17, \base, (17 * LASX_REG_WIDTH)
28761650023SHuacai Chen	EX	xvld	$xr18, \base, (18 * LASX_REG_WIDTH)
28861650023SHuacai Chen	EX	xvld	$xr19, \base, (19 * LASX_REG_WIDTH)
28961650023SHuacai Chen	EX	xvld	$xr20, \base, (20 * LASX_REG_WIDTH)
29061650023SHuacai Chen	EX	xvld	$xr21, \base, (21 * LASX_REG_WIDTH)
29161650023SHuacai Chen	EX	xvld	$xr22, \base, (22 * LASX_REG_WIDTH)
29261650023SHuacai Chen	EX	xvld	$xr23, \base, (23 * LASX_REG_WIDTH)
29361650023SHuacai Chen	EX	xvld	$xr24, \base, (24 * LASX_REG_WIDTH)
29461650023SHuacai Chen	EX	xvld	$xr25, \base, (25 * LASX_REG_WIDTH)
29561650023SHuacai Chen	EX	xvld	$xr26, \base, (26 * LASX_REG_WIDTH)
29661650023SHuacai Chen	EX	xvld	$xr27, \base, (27 * LASX_REG_WIDTH)
29761650023SHuacai Chen	EX	xvld	$xr28, \base, (28 * LASX_REG_WIDTH)
29861650023SHuacai Chen	EX	xvld	$xr29, \base, (29 * LASX_REG_WIDTH)
29961650023SHuacai Chen	EX	xvld	$xr30, \base, (30 * LASX_REG_WIDTH)
30061650023SHuacai Chen	EX	xvld	$xr31, \base, (31 * LASX_REG_WIDTH)
30161650023SHuacai Chen#endif
30261650023SHuacai Chen	.endm
30361650023SHuacai Chen
304803b0fc5SHuacai Chen/*
305803b0fc5SHuacai Chen * Save a thread's fp context.
306803b0fc5SHuacai Chen */
307803b0fc5SHuacai ChenSYM_FUNC_START(_save_fp)
308803b0fc5SHuacai Chen	fpu_save_csr	a0 t1
309803b0fc5SHuacai Chen	fpu_save_double	a0 t1			# clobbers t1
310803b0fc5SHuacai Chen	fpu_save_cc	a0 t1 t2		# clobbers t1, t2
31107b48069SWANG Xuerui	jr		ra
312803b0fc5SHuacai ChenSYM_FUNC_END(_save_fp)
313803b0fc5SHuacai ChenEXPORT_SYMBOL(_save_fp)
314803b0fc5SHuacai Chen
315803b0fc5SHuacai Chen/*
316803b0fc5SHuacai Chen * Restore a thread's fp context.
317803b0fc5SHuacai Chen */
318803b0fc5SHuacai ChenSYM_FUNC_START(_restore_fp)
319803b0fc5SHuacai Chen	fpu_restore_double	a0 t1		# clobbers t1
320bd3c5798SQi Hu	fpu_restore_csr		a0 t1 t2
321803b0fc5SHuacai Chen	fpu_restore_cc		a0 t1 t2	# clobbers t1, t2
32207b48069SWANG Xuerui	jr			ra
323803b0fc5SHuacai ChenSYM_FUNC_END(_restore_fp)
324803b0fc5SHuacai Chen
32561650023SHuacai Chen#ifdef CONFIG_CPU_HAS_LSX
32661650023SHuacai Chen
32761650023SHuacai Chen/*
32861650023SHuacai Chen * Save a thread's LSX vector context.
32961650023SHuacai Chen */
33061650023SHuacai ChenSYM_FUNC_START(_save_lsx)
33161650023SHuacai Chen	lsx_save_all	a0 t1 t2
33261650023SHuacai Chen	jr	ra
33361650023SHuacai ChenSYM_FUNC_END(_save_lsx)
33461650023SHuacai ChenEXPORT_SYMBOL(_save_lsx)
33561650023SHuacai Chen
33661650023SHuacai Chen/*
33761650023SHuacai Chen * Restore a thread's LSX vector context.
33861650023SHuacai Chen */
33961650023SHuacai ChenSYM_FUNC_START(_restore_lsx)
34061650023SHuacai Chen	lsx_restore_all	a0 t1 t2
34161650023SHuacai Chen	jr	ra
34261650023SHuacai ChenSYM_FUNC_END(_restore_lsx)
34361650023SHuacai Chen
34461650023SHuacai ChenSYM_FUNC_START(_save_lsx_upper)
34561650023SHuacai Chen	lsx_save_all_upper a0 t0 t1
34661650023SHuacai Chen	jr	ra
34761650023SHuacai ChenSYM_FUNC_END(_save_lsx_upper)
34861650023SHuacai Chen
34961650023SHuacai ChenSYM_FUNC_START(_restore_lsx_upper)
35061650023SHuacai Chen	lsx_restore_all_upper a0 t0 t1
35161650023SHuacai Chen	jr	ra
35261650023SHuacai ChenSYM_FUNC_END(_restore_lsx_upper)
353db1ecca2STianrui ZhaoEXPORT_SYMBOL(_restore_lsx_upper)
35461650023SHuacai Chen
35561650023SHuacai ChenSYM_FUNC_START(_init_lsx_upper)
35661650023SHuacai Chen	lsx_init_all_upper t1
35761650023SHuacai Chen	jr	ra
35861650023SHuacai ChenSYM_FUNC_END(_init_lsx_upper)
35961650023SHuacai Chen#endif
36061650023SHuacai Chen
36161650023SHuacai Chen#ifdef CONFIG_CPU_HAS_LASX
36261650023SHuacai Chen
36361650023SHuacai Chen/*
36461650023SHuacai Chen * Save a thread's LASX vector context.
36561650023SHuacai Chen */
36661650023SHuacai ChenSYM_FUNC_START(_save_lasx)
36761650023SHuacai Chen	lasx_save_all	a0 t1 t2
36861650023SHuacai Chen	jr	ra
36961650023SHuacai ChenSYM_FUNC_END(_save_lasx)
37061650023SHuacai ChenEXPORT_SYMBOL(_save_lasx)
37161650023SHuacai Chen
37261650023SHuacai Chen/*
37361650023SHuacai Chen * Restore a thread's LASX vector context.
37461650023SHuacai Chen */
37561650023SHuacai ChenSYM_FUNC_START(_restore_lasx)
37661650023SHuacai Chen	lasx_restore_all a0 t1 t2
37761650023SHuacai Chen	jr	ra
37861650023SHuacai ChenSYM_FUNC_END(_restore_lasx)
37961650023SHuacai Chen
38061650023SHuacai ChenSYM_FUNC_START(_save_lasx_upper)
38161650023SHuacai Chen	lasx_save_all_upper a0 t0 t1
38261650023SHuacai Chen	jr	ra
38361650023SHuacai ChenSYM_FUNC_END(_save_lasx_upper)
38461650023SHuacai Chen
38561650023SHuacai ChenSYM_FUNC_START(_restore_lasx_upper)
38661650023SHuacai Chen	lasx_restore_all_upper a0 t0 t1
38761650023SHuacai Chen	jr	ra
38861650023SHuacai ChenSYM_FUNC_END(_restore_lasx_upper)
389118e10cdSTianrui ZhaoEXPORT_SYMBOL(_restore_lasx_upper)
39061650023SHuacai Chen
39161650023SHuacai ChenSYM_FUNC_START(_init_lasx_upper)
39261650023SHuacai Chen	lasx_init_all_upper t1
39361650023SHuacai Chen	jr	ra
39461650023SHuacai ChenSYM_FUNC_END(_init_lasx_upper)
39561650023SHuacai Chen#endif
39661650023SHuacai Chen
397803b0fc5SHuacai Chen/*
398803b0fc5SHuacai Chen * Load the FPU with signalling NANS.  This bit pattern we're using has
399803b0fc5SHuacai Chen * the property that no matter whether considered as single or as double
400803b0fc5SHuacai Chen * precision represents signaling NANS.
401803b0fc5SHuacai Chen *
402803b0fc5SHuacai Chen * The value to initialize fcsr0 to comes in $a0.
403803b0fc5SHuacai Chen */
404803b0fc5SHuacai Chen
405803b0fc5SHuacai ChenSYM_FUNC_START(_init_fpu)
406803b0fc5SHuacai Chen	li.w	t1, CSR_EUEN_FPEN
407803b0fc5SHuacai Chen	csrxchg	t1, t1, LOONGARCH_CSR_EUEN
408803b0fc5SHuacai Chen
409803b0fc5SHuacai Chen	movgr2fcsr	fcsr0, a0
410803b0fc5SHuacai Chen
411803b0fc5SHuacai Chen	li.w	t1, -1				# SNaN
412803b0fc5SHuacai Chen
413803b0fc5SHuacai Chen	movgr2fr.d	$f0, t1
414803b0fc5SHuacai Chen	movgr2fr.d	$f1, t1
415803b0fc5SHuacai Chen	movgr2fr.d	$f2, t1
416803b0fc5SHuacai Chen	movgr2fr.d	$f3, t1
417803b0fc5SHuacai Chen	movgr2fr.d	$f4, t1
418803b0fc5SHuacai Chen	movgr2fr.d	$f5, t1
419803b0fc5SHuacai Chen	movgr2fr.d	$f6, t1
420803b0fc5SHuacai Chen	movgr2fr.d	$f7, t1
421803b0fc5SHuacai Chen	movgr2fr.d	$f8, t1
422803b0fc5SHuacai Chen	movgr2fr.d	$f9, t1
423803b0fc5SHuacai Chen	movgr2fr.d	$f10, t1
424803b0fc5SHuacai Chen	movgr2fr.d	$f11, t1
425803b0fc5SHuacai Chen	movgr2fr.d	$f12, t1
426803b0fc5SHuacai Chen	movgr2fr.d	$f13, t1
427803b0fc5SHuacai Chen	movgr2fr.d	$f14, t1
428803b0fc5SHuacai Chen	movgr2fr.d	$f15, t1
429803b0fc5SHuacai Chen	movgr2fr.d	$f16, t1
430803b0fc5SHuacai Chen	movgr2fr.d	$f17, t1
431803b0fc5SHuacai Chen	movgr2fr.d	$f18, t1
432803b0fc5SHuacai Chen	movgr2fr.d	$f19, t1
433803b0fc5SHuacai Chen	movgr2fr.d	$f20, t1
434803b0fc5SHuacai Chen	movgr2fr.d	$f21, t1
435803b0fc5SHuacai Chen	movgr2fr.d	$f22, t1
436803b0fc5SHuacai Chen	movgr2fr.d	$f23, t1
437803b0fc5SHuacai Chen	movgr2fr.d	$f24, t1
438803b0fc5SHuacai Chen	movgr2fr.d	$f25, t1
439803b0fc5SHuacai Chen	movgr2fr.d	$f26, t1
440803b0fc5SHuacai Chen	movgr2fr.d	$f27, t1
441803b0fc5SHuacai Chen	movgr2fr.d	$f28, t1
442803b0fc5SHuacai Chen	movgr2fr.d	$f29, t1
443803b0fc5SHuacai Chen	movgr2fr.d	$f30, t1
444803b0fc5SHuacai Chen	movgr2fr.d	$f31, t1
445803b0fc5SHuacai Chen
44607b48069SWANG Xuerui	jr	ra
447803b0fc5SHuacai ChenSYM_FUNC_END(_init_fpu)
448803b0fc5SHuacai Chen
449803b0fc5SHuacai Chen/*
450803b0fc5SHuacai Chen * a0: fpregs
451803b0fc5SHuacai Chen * a1: fcc
452803b0fc5SHuacai Chen * a2: fcsr
453803b0fc5SHuacai Chen */
454803b0fc5SHuacai ChenSYM_FUNC_START(_save_fp_context)
455803b0fc5SHuacai Chen	sc_save_fcc	a1 t1 t2
456803b0fc5SHuacai Chen	sc_save_fcsr	a2 t1
457803b0fc5SHuacai Chen	sc_save_fp	a0
458803b0fc5SHuacai Chen	li.w		a0, 0				# success
45907b48069SWANG Xuerui	jr		ra
460803b0fc5SHuacai ChenSYM_FUNC_END(_save_fp_context)
461803b0fc5SHuacai Chen
462803b0fc5SHuacai Chen/*
463803b0fc5SHuacai Chen * a0: fpregs
464803b0fc5SHuacai Chen * a1: fcc
465803b0fc5SHuacai Chen * a2: fcsr
466803b0fc5SHuacai Chen */
467803b0fc5SHuacai ChenSYM_FUNC_START(_restore_fp_context)
468803b0fc5SHuacai Chen	sc_restore_fp	a0
469803b0fc5SHuacai Chen	sc_restore_fcc	a1 t1 t2
470803b0fc5SHuacai Chen	sc_restore_fcsr	a2 t1
471803b0fc5SHuacai Chen	li.w		a0, 0				# success
47207b48069SWANG Xuerui	jr		ra
473803b0fc5SHuacai ChenSYM_FUNC_END(_restore_fp_context)
474803b0fc5SHuacai Chen
47561650023SHuacai Chen/*
47661650023SHuacai Chen * a0: fpregs
47761650023SHuacai Chen * a1: fcc
47861650023SHuacai Chen * a2: fcsr
47961650023SHuacai Chen */
48061650023SHuacai ChenSYM_FUNC_START(_save_lsx_context)
48161650023SHuacai Chen	sc_save_fcc a1, t0, t1
48261650023SHuacai Chen	sc_save_fcsr a2, t0
48361650023SHuacai Chen	sc_save_lsx a0
48461650023SHuacai Chen	li.w	a0, 0					# success
48561650023SHuacai Chen	jr	ra
48661650023SHuacai ChenSYM_FUNC_END(_save_lsx_context)
48761650023SHuacai Chen
48861650023SHuacai Chen/*
48961650023SHuacai Chen * a0: fpregs
49061650023SHuacai Chen * a1: fcc
49161650023SHuacai Chen * a2: fcsr
49261650023SHuacai Chen */
49361650023SHuacai ChenSYM_FUNC_START(_restore_lsx_context)
49461650023SHuacai Chen	sc_restore_lsx a0
49561650023SHuacai Chen	sc_restore_fcc a1, t1, t2
49661650023SHuacai Chen	sc_restore_fcsr a2, t1
49761650023SHuacai Chen	li.w	a0, 0					# success
49861650023SHuacai Chen	jr	ra
49961650023SHuacai ChenSYM_FUNC_END(_restore_lsx_context)
50061650023SHuacai Chen
50161650023SHuacai Chen/*
50261650023SHuacai Chen * a0: fpregs
50361650023SHuacai Chen * a1: fcc
50461650023SHuacai Chen * a2: fcsr
50561650023SHuacai Chen */
50661650023SHuacai ChenSYM_FUNC_START(_save_lasx_context)
50761650023SHuacai Chen	sc_save_fcc a1, t0, t1
50861650023SHuacai Chen	sc_save_fcsr a2, t0
50961650023SHuacai Chen	sc_save_lasx a0
51061650023SHuacai Chen	li.w	a0, 0					# success
51161650023SHuacai Chen	jr	ra
51261650023SHuacai ChenSYM_FUNC_END(_save_lasx_context)
51361650023SHuacai Chen
51461650023SHuacai Chen/*
51561650023SHuacai Chen * a0: fpregs
51661650023SHuacai Chen * a1: fcc
51761650023SHuacai Chen * a2: fcsr
51861650023SHuacai Chen */
51961650023SHuacai ChenSYM_FUNC_START(_restore_lasx_context)
52061650023SHuacai Chen	sc_restore_lasx a0
52161650023SHuacai Chen	sc_restore_fcc a1, t1, t2
52261650023SHuacai Chen	sc_restore_fcsr a2, t1
52361650023SHuacai Chen	li.w	a0, 0					# success
52461650023SHuacai Chen	jr	ra
52561650023SHuacai ChenSYM_FUNC_END(_restore_lasx_context)
52661650023SHuacai Chen
5278f58c571STiezhu Yang.L_fpu_fault:
528803b0fc5SHuacai Chen	li.w	a0, -EFAULT				# failure
52907b48069SWANG Xuerui	jr	ra
530cb8a2ef0STiezhu Yang
531cb8a2ef0STiezhu Yang#ifdef CONFIG_CPU_HAS_LBT
532cb8a2ef0STiezhu YangSTACK_FRAME_NON_STANDARD _restore_fp
533*80376323STiezhu Yang#ifdef CONFIG_CPU_HAS_LSX
534cb8a2ef0STiezhu YangSTACK_FRAME_NON_STANDARD _restore_lsx
535*80376323STiezhu Yang#endif
536*80376323STiezhu Yang#ifdef CONFIG_CPU_HAS_LASX
537cb8a2ef0STiezhu YangSTACK_FRAME_NON_STANDARD _restore_lasx
538cb8a2ef0STiezhu Yang#endif
539*80376323STiezhu Yang#endif
540