Skip to content

Commit c532857

Browse files
committed
Refactor LoongArch64 context save and restore macros to improve register handling and streamline assembly code generation
1 parent a18e6d1 commit c532857

File tree

1 file changed

+74
-44
lines changed

1 file changed

+74
-44
lines changed

src/unwinder/arch/loongarch64.rs

Lines changed: 74 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,71 @@ impl ops::IndexMut<gimli::Register> for Context {
5656
}
5757
}
5858

59-
macro_rules! ctx_helper {
59+
macro_rules! save_regs {
60+
(gp$(, $fp:ident)?) => {
61+
core::arch::naked_asm!(
62+
maybe_cfi!(".cfi_startproc"),
63+
"
64+
move $r12, $r3
65+
addi.d $r3, $r3, -0x210
66+
",
67+
maybe_cfi!(".cfi_def_cfa_offset 0x210"),
68+
"
69+
st.d $r1, $r3, 0x200
70+
",
71+
maybe_cfi!(".cfi_offset 1, -16"), // ra
72+
helper!(save_gp),
73+
save_regs!(maybe_save_fp($($fp)?)),
74+
"
75+
move $r12, $r4
76+
move $r4, $r3 // argument a0 pointing the ctx base
77+
78+
addi.d $r13, $r3, 0x210
79+
st.d $r13, $r3, 0x18 // save sp
80+
81+
jirl $r1, $r12, 0 // call f
82+
83+
ld.d $r1, $r3, 0x200
84+
addi.d $r3, $r3, 0x210 // restore ra and sp
85+
",
86+
maybe_cfi!(".cfi_def_cfa_offset 0"),
87+
maybe_cfi!(".cfi_restore 1"), // ra
88+
"
89+
ret
90+
",
91+
maybe_cfi!(".cfi_endproc"),
92+
)
93+
};
94+
(maybe_save_fp(fp)) => {
95+
helper!(save_fp)
96+
};
97+
(maybe_save_fp()) => {
98+
""
99+
};
100+
}
101+
102+
macro_rules! restore_regs {
103+
($ctx:expr, gp$(, $fp:ident)?) => {
104+
core::arch::asm!(
105+
restore_regs!(maybe_restore_fp($($fp)?)),
106+
helper!(restore_gp),
107+
"
108+
ld.d $r4, $r4, 0x20
109+
ret
110+
",
111+
in("$r4") $ctx,
112+
options(noreturn)
113+
)
114+
};
115+
(maybe_restore_fp(fp)) => {
116+
helper!(restore_fp)
117+
};
118+
(maybe_restore_fp()) => {
119+
""
120+
};
121+
}
122+
123+
macro_rules! helper {
60124
// see https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html for ABI conventions
61125
(save_gp) => {
62126
"
@@ -94,7 +158,7 @@ macro_rules! ctx_helper {
94158
ld.d $r1, $r4, 0x8 // ra
95159
ld.d $r2, $r4, 0x10 // tp
96160
ld.d $r3, $r4, 0x18 // sp
97-
// a0 is restored later
161+
// r4(a0) is restored later
98162
ld.d $r5, $r4, 0x28 // a1
99163
ld.d $r6, $r4, 0x30 // a2
100164
ld.d $r7, $r4, 0x38 // a3
@@ -166,52 +230,18 @@ macro_rules! ctx_helper {
166230
pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Context, *mut ()), ptr: *mut ()) {
167231
#[allow(unused_unsafe)]
168232
unsafe {
169-
core::arch::naked_asm!(
170-
maybe_cfi!(".cfi_startproc"),
171-
"
172-
move $r12, $r3
173-
addi.d $r3, $r3, -0x210
174-
",
175-
maybe_cfi!(".cfi_def_cfa_offset 0x210"),
176-
"
177-
st.d $r1, $r3, 0x200
178-
",
179-
maybe_cfi!(".cfi_offset 1, -16"), // ra
180-
ctx_helper!(save_gp),
181-
ctx_helper!(save_fp),
182-
"
183-
move $r12, $r4
184-
move $r4, $r3 // argument a0 pointing the ctx base
185-
186-
addi.d $r13, $r3, 0x210
187-
st.d $r13, $r3, 0x18 // save sp
188-
189-
jirl $r1, $r12, 0 // call f
190-
191-
ld.d $r1, $r3, 0x200
192-
addi.d $r3, $r3, 0x210 // restore ra and sp
193-
",
194-
maybe_cfi!(".cfi_def_cfa_offset 0"),
195-
maybe_cfi!(".cfi_restore 1"), // ra
196-
"
197-
ret
198-
",
199-
maybe_cfi!(".cfi_endproc"),
200-
)
233+
#[cfg(target_feature = "d")]
234+
save_regs!(gp, fp);
235+
#[cfg(not(target_feature = "d"))]
236+
save_regs!(gp);
201237
}
202238
}
203239

204240
pub unsafe fn restore_context(ctx: &Context) -> ! {
205241
unsafe {
206-
core::arch::asm!(
207-
ctx_helper!(restore_gp),
208-
ctx_helper!(restore_fp),
209-
"
210-
ld.d $r4, $r4, 0x20
211-
ret
212-
",
213-
in("$r4") ctx,
214-
options(noreturn)
215-
);
242+
#[cfg(target_feature = "d")]
243+
restore_regs!(ctx, gp, fp);
244+
#[cfg(not(target_feature = "d"))]
245+
restore_regs!(ctx, gp);
216246
}
217247
}

0 commit comments

Comments
 (0)