Skip to content

Commit a4fc344

Browse files
authored
feat: support save and restore fp regs for loongarch (#14)
* feat: support save and restore fp regs for loongarch * fix: Fix format
1 parent ff55304 commit a4fc344

3 files changed

Lines changed: 183 additions & 0 deletions

File tree

polyhal/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ repository = { workspace = true }
1313
trap = []
1414
boot = []
1515
logger = []
16+
fp_simd = []
1617

1718
graphic = []
1819

polyhal/src/components/kcontext/loongarch64.rs

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use core::mem::offset_of;
12
use 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

66219
impl 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]
184362
pub extern "C" fn read_current_tp() -> usize {
185363
unsafe {

polyhal/src/components/kcontext/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,7 @@ pub enum KContextArgs {
2020
}
2121

2222
pub_use_arch!(context_switch, context_switch_pt);
23+
24+
#[cfg(feature = "fp_simd")]
25+
#[cfg(target_arch = "loongarch64")]
26+
pub_use_arch!(save_fp_regs, restore_fp_regs);

0 commit comments

Comments
 (0)