1+ use core:: mem:: offset_of;
12use core:: {
23 arch:: naked_asm,
34 ops:: { Index , IndexMut } ,
@@ -47,6 +48,155 @@ macro_rules! restore_callee_regs {
4748 } ;
4849}
4950
51+ #[ cfg( feature = "fp_simd" ) ]
52+ macro_rules! save_fp_regs {
53+ ( ) => {
54+ "
55+ // LoongArch64 specific floating point macros
56+ fst.d $f0, $a0, 0*8
57+ fst.d $f1, $a0, 1*8
58+ fst.d $f2, $a0, 2*8
59+ fst.d $f3, $a0, 3*8
60+ fst.d $f4, $a0, 4*8
61+ fst.d $f5, $a0, 5*8
62+ fst.d $f6, $a0, 6*8
63+ fst.d $f7, $a0, 7*8
64+ fst.d $f8, $a0, 8*8
65+ fst.d $f9, $a0, 9*8
66+ fst.d $f10, $a0, 10*8
67+ fst.d $f11, $a0, 11*8
68+ fst.d $f12, $a0, 12*8
69+ fst.d $f13, $a0, 13*8
70+ fst.d $f14, $a0, 14*8
71+ fst.d $f15, $a0, 15*8
72+ fst.d $f16, $a0, 16*8
73+ fst.d $f17, $a0, 17*8
74+ fst.d $f18, $a0, 18*8
75+ fst.d $f19, $a0, 19*8
76+ fst.d $f20, $a0, 20*8
77+ fst.d $f21, $a0, 21*8
78+ fst.d $f22, $a0, 22*8
79+ fst.d $f23, $a0, 23*8
80+ fst.d $f24, $a0, 24*8
81+ fst.d $f25, $a0, 25*8
82+ fst.d $f26, $a0, 26*8
83+ fst.d $f27, $a0, 27*8
84+ fst.d $f28, $a0, 28*8
85+ fst.d $f29, $a0, 29*8
86+ fst.d $f30, $a0, 30*8
87+ fst.d $f31, $a0, 31*8
88+
89+ addi.d $t8, $a0, 32*8
90+
91+ // SAVE_FCC
92+ movcf2gr $t0, $fcc0
93+ move $t1, $t0
94+ movcf2gr $t0, $fcc1
95+ bstrins.d $t1, $t0, 15, 8
96+ movcf2gr $t0, $fcc2
97+ bstrins.d $t1, $t0, 23, 16
98+ movcf2gr $t0, $fcc3
99+ bstrins.d $t1, $t0, 31, 24
100+ movcf2gr $t0, $fcc4
101+ bstrins.d $t1, $t0, 39, 32
102+ movcf2gr $t0, $fcc5
103+ bstrins.d $t1, $t0, 47, 40
104+ movcf2gr $t0, $fcc6
105+ bstrins.d $t1, $t0, 55, 48
106+ movcf2gr $t0, $fcc7
107+ bstrins.d $t1, $t0, 63, 56
108+ st.d $t1, $t8, 0
109+
110+ addi.d $t8, $a0, 33*8
111+
112+ // SAVE_FCSR
113+ movfcsr2gr $t0, $fcsr0
114+ st.w $t0, $t8, 0
115+ "
116+ } ;
117+ }
118+
119+ #[ cfg( feature = "fp_simd" ) ]
120+ macro_rules! restore_fp_regs {
121+ ( ) => {
122+ "
123+ // LoongArch64 specific floating point macros
124+ fld.d $f0, $a0, 0*8
125+ fld.d $f1, $a0, 1*8
126+ fld.d $f2, $a0, 2*8
127+ fld.d $f3, $a0, 3*8
128+ fld.d $f4, $a0, 4*8
129+ fld.d $f5, $a0, 5*8
130+ fld.d $f6, $a0, 6*8
131+ fld.d $f7, $a0, 7*8
132+ fld.d $f8, $a0, 8*8
133+ fld.d $f9, $a0, 9*8
134+ fld.d $f10, $a0, 10*8
135+ fld.d $f11, $a0, 11*8
136+ fld.d $f12, $a0, 12*8
137+ fld.d $f13, $a0, 13*8
138+ fld.d $f14, $a0, 14*8
139+ fld.d $f15, $a0, 15*8
140+ fld.d $f16, $a0, 16*8
141+ fld.d $f17, $a0, 17*8
142+ fld.d $f18, $a0, 18*8
143+ fld.d $f19, $a0, 19*8
144+ fld.d $f20, $a0, 20*8
145+ fld.d $f21, $a0, 21*8
146+ fld.d $f22, $a0, 22*8
147+ fld.d $f23, $a0, 23*8
148+ fld.d $f24, $a0, 24*8
149+ fld.d $f25, $a0, 25*8
150+ fld.d $f26, $a0, 26*8
151+ fld.d $f27, $a0, 27*8
152+ fld.d $f28, $a0, 28*8
153+ fld.d $f29, $a0, 29*8
154+ fld.d $f30, $a0, 30*8
155+ fld.d $f31, $a0, 31*8
156+
157+ addi.d $t8, $a0, 32*8
158+
159+ // RESTORE_FCC
160+ ld.d $t0, $t8, 0
161+ bstrpick.d $t1, $t0, 7, 0
162+ movgr2cf $fcc0, $t1
163+ bstrpick.d $t1, $t0, 15, 8
164+ movgr2cf $fcc1, $t1
165+ bstrpick.d $t1, $t0, 23, 16
166+ movgr2cf $fcc2, $t1
167+ bstrpick.d $t1, $t0, 31, 24
168+ movgr2cf $fcc3, $t1
169+ bstrpick.d $t1, $t0, 39, 32
170+ movgr2cf $fcc4, $t1
171+ bstrpick.d $t1, $t0, 47, 40
172+ movgr2cf $fcc5, $t1
173+ bstrpick.d $t1, $t0, 55, 48
174+ movgr2cf $fcc6, $t1
175+ bstrpick.d $t1, $t0, 63, 56
176+ movgr2cf $fcc7, $t1
177+
178+ addi.d $t8, $a0, 33*8
179+
180+ // RESTORE_FCSR
181+ ld.w $t0, $t8, 0
182+ movgr2fcsr $fcsr0, $t0
183+ "
184+ } ;
185+ }
186+
187+ /// Floating-point registers of LoongArch64.
188+ #[ cfg( feature = "fp_simd" ) ]
189+ #[ repr( C ) ]
190+ #[ derive( Debug , Default , Clone , Copy ) ]
191+ pub struct FpStatus {
192+ /// Floating-point registers (f0-f31)
193+ pub fp : [ u64 ; 32 ] ,
194+ /// Floating-point Condition Code register
195+ pub fcc : [ u8 ; 8 ] ,
196+ /// Floating-point Control and Status register
197+ pub fcsr : usize ,
198+ }
199+
50200/// Kernel Context
51201///
52202/// Kernel Context is used to switch context between kernel task.
@@ -61,6 +211,9 @@ pub struct KContext {
61211 _sregs : [ usize ; 10 ] ,
62212 /// Kernel Program Counter, Will return to this address.
63213 kpc : usize ,
214+ #[ cfg( feature = "fp_simd" ) ]
215+ /// Floating Point Status
216+ fp_status : FpStatus ,
64217}
65218
66219impl KContext {
@@ -71,6 +224,8 @@ impl KContext {
71224 ktp : 0 ,
72225 _sregs : [ 0 ; 10 ] ,
73226 kpc : 0 ,
227+ #[ cfg( feature = "fp_simd" ) ]
228+ fp_status : FpStatus :: default ( ) ,
74229 }
75230 }
76231}
@@ -180,6 +335,29 @@ unsafe extern "C" fn context_switch_pt_impl(
180335 )
181336}
182337
338+ #[ cfg( feature = "fp_simd" ) ]
339+ #[ naked]
340+ pub unsafe extern "C" fn save_fp_regs ( from : * mut KContext ) {
341+ naked_asm ! (
342+ // Save floating point registers.
343+ "addi.d $a0, $a0, {fp_offset}" ,
344+ save_fp_regs!( ) ,
345+ "ret" ,
346+ fp_offset = const offset_of!( KContext , fp_status)
347+ )
348+ }
349+
350+ #[ cfg( feature = "fp_simd" ) ]
351+ #[ naked]
352+ pub unsafe extern "C" fn restore_fp_regs ( to : * const KContext ) {
353+ naked_asm ! (
354+ "addi.d $a0, $a0, {fp_offset}" ,
355+ restore_fp_regs!( ) ,
356+ "ret" ,
357+ fp_offset = const offset_of!( KContext , fp_status)
358+ )
359+ }
360+
183361#[ naked]
184362pub extern "C" fn read_current_tp ( ) -> usize {
185363 unsafe {
0 commit comments