Skip to content

Commit 2f605ee

Browse files
committed
refactor: 用宏合并 rv32/64 的裸汇编
Signed-off-by: YdrMaster <[email protected]>
1 parent b2d8ca7 commit 2f605ee

File tree

4 files changed

+167
-280
lines changed

4 files changed

+167
-280
lines changed

fast-trap/src/hal/mod.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
mod riscv;
2-
#[cfg(target_arch = "riscv32")]
3-
mod riscv32_trap;
4-
#[cfg(target_arch = "riscv64")]
5-
mod riscv64_trap;
62
#[cfg(feature = "riscv-m")]
73
#[macro_use]
84
mod riscv_m;
@@ -11,10 +7,6 @@ mod riscv_m;
117
mod riscv_s;
128

139
pub use riscv::*;
14-
#[cfg(target_arch = "riscv32")]
15-
pub use riscv32_trap::*;
16-
#[cfg(target_arch = "riscv64")]
17-
pub use riscv64_trap::*;
1810
#[cfg(feature = "riscv-m")]
1911
pub use riscv_m::*;
2012
#[cfg(feature = "riscv-s")]

fast-trap/src/hal/riscv.rs

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,47 @@
11
use crate::TrapHandler;
22
use core::alloc::Layout;
33

4+
#[cfg(target_arch = "riscv32")]
5+
#[macro_use]
6+
mod arch {
7+
macro_rules! save {
8+
($reg:expr => $ptr:expr; $pos:expr) => {
9+
concat!("sw ", $reg, ", 4*", $pos, "(", $ptr, ")")
10+
};
11+
}
12+
13+
macro_rules! load {
14+
($ptr:expr; $pos:expr => $reg:expr) => {
15+
concat!("lw ", $reg, ", 4*", $pos, "(", $ptr, ")")
16+
};
17+
18+
($ptr:expr; $pos:expr => $reg:expr, label: $label:expr) => {
19+
concat!($label, ":", load!($ptr;$pos => $reg))
20+
};
21+
}
22+
}
23+
#[cfg(target_arch = "riscv64")]
24+
#[macro_use]
25+
mod arch {
26+
macro_rules! save {
27+
($reg:expr => $ptr:expr; $pos:expr) => {
28+
concat!("sd ", $reg, ", 8*", $pos, '(', $ptr, ')')
29+
};
30+
}
31+
32+
macro_rules! load {
33+
($ptr:expr; $pos:expr => $reg:expr) => {
34+
concat!("ld ", $reg, ", 8*", $pos, '(', $ptr, ')')
35+
};
36+
37+
($ptr:expr; $pos:expr => $reg:expr, label: $label:expr) => {
38+
concat!($label, ':', load!($ptr;$pos => $reg))
39+
};
40+
}
41+
}
42+
43+
use super::{exchange, r#return};
44+
445
/// 陷入上下文。
546
///
647
/// 保存了陷入时的寄存器状态。包括所有通用寄存器和 `pc`。
@@ -49,3 +90,129 @@ pub unsafe extern "C" fn reuse_stack_for_trap() {
4990
options(noreturn)
5091
)
5192
}
93+
94+
/// 陷入处理例程。
95+
///
96+
/// # Safety
97+
///
98+
/// 不要直接调用这个函数。暴露它仅仅是为了提供其入口的符号链接。
99+
#[naked]
100+
pub unsafe extern "C" fn trap_entry() {
101+
core::arch::asm!(
102+
".align 2",
103+
// 换栈
104+
exchange!(),
105+
// 加载上下文指针
106+
save!("a0" => "sp";2),
107+
load!("sp";0 => "a0"),
108+
// 保存尽量少的寄存器
109+
save!("ra" => "a0";0),
110+
save!("t0" => "a0";1),
111+
save!("t1" => "a0";2),
112+
save!("t2" => "a0";3),
113+
save!("t3" => "a0";4),
114+
save!("t4" => "a0";5),
115+
save!("t5" => "a0";6),
116+
save!("t6" => "a0";7),
117+
// 调用快速路径函数
118+
//
119+
// | reg | position
120+
// | ------ | -
121+
// | ra | `TrapHandler.context`
122+
// | t0-t6 | `TrapHandler.context`
123+
// | a0 | `TrapHandler.scratch`
124+
// | a1-a7 | 参数寄存器
125+
// | sp | sscratch
126+
// | gp, tp | gp, tp
127+
// | s0-s11 | 不支持
128+
//
129+
// > 若要保留陷入上下文,
130+
// > 必须在快速路径保存 a0-a7 到 `TrapHandler.context`,
131+
// > 并进入完整路径执行后续操作。
132+
// >
133+
// > 若要切换上下文,在快速路径设置 gp/tp/sscratch/sepc 和 sstatus。
134+
"mv a0, sp",
135+
load!("sp";1 => "ra"),
136+
"jalr ra",
137+
// 加载上下文指针
138+
load!("sp";0 => "a1", label: 0),
139+
// 0:设置少量参数寄存器
140+
" beqz a0, 0f",
141+
// 1:设置所有参数寄存器
142+
" addi a0, a0, -1
143+
beqz a0, 1f
144+
",
145+
// 2:设置所有调用者寄存器
146+
" addi a0, a0, -1
147+
beqz a0, 2f
148+
",
149+
// 3:设置所有寄存器
150+
" addi a0, a0, -1
151+
beqz a0, 3f
152+
",
153+
// 4:完整路径
154+
save!("s0" => "a1";16),
155+
save!("s1" => "a1";17),
156+
save!("s2" => "a1";18),
157+
save!("s3" => "a1";19),
158+
save!("s4" => "a1";20),
159+
save!("s5" => "a1";21),
160+
save!("s6" => "a1";22),
161+
save!("s7" => "a1";23),
162+
save!("s8" => "a1";24),
163+
save!("s9" => "a1";25),
164+
save!("s10" => "a1";26),
165+
save!("s11" => "a1";27),
166+
// 调用完整路径函数
167+
//
168+
// | reg | position
169+
// | ------ | -
170+
// | sp | sscratch
171+
// | gp, tp | gp, tp
172+
// | else | `TrapHandler.context`
173+
//
174+
// > 若要保留陷入上下文,
175+
// > 在完整路径中保存 gp/tp/sp/pc 到 `TrapHandler.context`。
176+
// >
177+
// > 若要切换上下文,在完整路径设置 gp/tp/sscratch/sepc 和 sstatus。
178+
"mv a0, sp",
179+
load!("sp"; 2 => "ra"),
180+
"jalr ra",
181+
"j 0b",
182+
// 设置所有寄存器
183+
load!("a1";16 => "s0", label: 3),
184+
load!("a1";17 => "s1"),
185+
load!("a1";18 => "s2"),
186+
load!("a1";19 => "s3"),
187+
load!("a1";20 => "s4"),
188+
load!("a1";21 => "s5"),
189+
load!("a1";22 => "s6"),
190+
load!("a1";23 => "s7"),
191+
load!("a1";24 => "s8"),
192+
load!("a1";25 => "s9"),
193+
load!("a1";26 => "s10"),
194+
load!("a1";27 => "s11"),
195+
// 设置所有调用者寄存器
196+
load!("a1"; 0 => "ra", label: 2),
197+
load!("a1"; 1 => "t0"),
198+
load!("a1"; 2 => "t1"),
199+
load!("a1"; 3 => "t2"),
200+
load!("a1"; 4 => "t3"),
201+
load!("a1"; 5 => "t4"),
202+
load!("a1"; 6 => "t5"),
203+
load!("a1"; 7 => "t6"),
204+
// 设置所有参数寄存器
205+
load!("a1";10 => "a2", label: 1),
206+
load!("a1";11 => "a3"),
207+
load!("a1";12 => "a4"),
208+
load!("a1";13 => "a5"),
209+
load!("a1";14 => "a6"),
210+
load!("a1";15 => "a7"),
211+
// 设置少量参数寄存器
212+
load!("a1"; 8 => "a0", label: 0),
213+
load!("a1"; 9 => "a1"),
214+
exchange!(),
215+
r#return!(),
216+
options(noreturn),
217+
)
218+
}

fast-trap/src/hal/riscv32_trap.rs

Lines changed: 0 additions & 136 deletions
This file was deleted.

0 commit comments

Comments
 (0)