|
@@ -58,22 +58,17 @@ impl ops::IndexMut<gimli::Register> for Context {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#[naked]
|
|
|
-pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Context, *mut ()), ptr: *mut ()) {
|
|
|
- // No need to save caller-saved registers here.
|
|
|
- unsafe {
|
|
|
+macro_rules! save {
|
|
|
+ (gp$(, $fp:ident)?) => {
|
|
|
asm!(
|
|
|
"
|
|
|
stp x29, x30, [sp, -16]!
|
|
|
sub sp, sp, 512
|
|
|
mov x8, x0
|
|
|
mov x0, sp
|
|
|
-
|
|
|
- stp d8, d9, [sp, 0x140]
|
|
|
- stp d10, d11, [sp, 0x150]
|
|
|
- stp d12, d13, [sp, 0x160]
|
|
|
- stp d14, d15, [sp, 0x170]
|
|
|
-
|
|
|
+ ",
|
|
|
+ save!(maybesavefp($($fp)?)),
|
|
|
+ "
|
|
|
str x19, [sp, 0x98]
|
|
|
stp x20, x21, [sp, 0xA0]
|
|
|
stp x22, x23, [sp, 0xB0]
|
|
@@ -91,30 +86,34 @@ pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Context, *mut ()), p
|
|
|
",
|
|
|
options(noreturn)
|
|
|
);
|
|
|
- }
|
|
|
+ };
|
|
|
+ (maybesavefp(fp)) => {
|
|
|
+ "
|
|
|
+ stp d8, d9, [sp, 0x140]
|
|
|
+ stp d10, d11, [sp, 0x150]
|
|
|
+ stp d12, d13, [sp, 0x160]
|
|
|
+ stp d14, d15, [sp, 0x170]
|
|
|
+ "
|
|
|
+ };
|
|
|
+ (maybesavefp()) => { "" };
|
|
|
}
|
|
|
|
|
|
-pub unsafe fn restore_context(ctx: &Context) -> ! {
|
|
|
+#[naked]
|
|
|
+pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Context, *mut ()), ptr: *mut ()) {
|
|
|
+ // No need to save caller-saved registers here.
|
|
|
unsafe {
|
|
|
+ #[cfg(target_feature = "fp-armv8")]
|
|
|
+ save!(gp, fp);
|
|
|
+ #[cfg(not(target_feature = "fp-armv8"))]
|
|
|
+ save!(gp);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+macro_rules! restore {
|
|
|
+ ($ctx:expr, gp$(, $fp:ident)?) => {
|
|
|
asm!(
|
|
|
+ restore!(mayberestore($($fp)?)),
|
|
|
"
|
|
|
- ldp d0, d1, [x0, 0x100]
|
|
|
- ldp d2, d3, [x0, 0x110]
|
|
|
- ldp d4, d5, [x0, 0x120]
|
|
|
- ldp d6, d7, [x0, 0x130]
|
|
|
- ldp d8, d9, [x0, 0x140]
|
|
|
- ldp d10, d11, [x0, 0x150]
|
|
|
- ldp d12, d13, [x0, 0x160]
|
|
|
- ldp d14, d15, [x0, 0x170]
|
|
|
- ldp d16, d17, [x0, 0x180]
|
|
|
- ldp d18, d19, [x0, 0x190]
|
|
|
- ldp d20, d21, [x0, 0x1A0]
|
|
|
- ldp d22, d23, [x0, 0x1B0]
|
|
|
- ldp d24, d25, [x0, 0x1C0]
|
|
|
- ldp d26, d27, [x0, 0x1D0]
|
|
|
- ldp d28, d29, [x0, 0x1E0]
|
|
|
- ldp d30, d31, [x0, 0x1F0]
|
|
|
-
|
|
|
ldp x2, x3, [x0, 0x10]
|
|
|
ldp x4, x5, [x0, 0x20]
|
|
|
ldp x6, x7, [x0, 0x30]
|
|
@@ -135,8 +134,38 @@ pub unsafe fn restore_context(ctx: &Context) -> ! {
|
|
|
ldp x0, x1, [x0, 0x00]
|
|
|
ret
|
|
|
",
|
|
|
- in("x0") ctx,
|
|
|
+ in("x0") $ctx,
|
|
|
options(noreturn)
|
|
|
);
|
|
|
+ };
|
|
|
+ (mayberestore(fp)) => {
|
|
|
+ "
|
|
|
+ ldp d0, d1, [x0, 0x100]
|
|
|
+ ldp d2, d3, [x0, 0x110]
|
|
|
+ ldp d4, d5, [x0, 0x120]
|
|
|
+ ldp d6, d7, [x0, 0x130]
|
|
|
+ ldp d8, d9, [x0, 0x140]
|
|
|
+ ldp d10, d11, [x0, 0x150]
|
|
|
+ ldp d12, d13, [x0, 0x160]
|
|
|
+ ldp d14, d15, [x0, 0x170]
|
|
|
+ ldp d16, d17, [x0, 0x180]
|
|
|
+ ldp d18, d19, [x0, 0x190]
|
|
|
+ ldp d20, d21, [x0, 0x1A0]
|
|
|
+ ldp d22, d23, [x0, 0x1B0]
|
|
|
+ ldp d24, d25, [x0, 0x1C0]
|
|
|
+ ldp d26, d27, [x0, 0x1D0]
|
|
|
+ ldp d28, d29, [x0, 0x1E0]
|
|
|
+ ldp d30, d31, [x0, 0x1F0]
|
|
|
+ "
|
|
|
+ };
|
|
|
+ (mayberestore()) => { "" };
|
|
|
+}
|
|
|
+
|
|
|
+pub unsafe fn restore_context(ctx: &Context) -> ! {
|
|
|
+ unsafe {
|
|
|
+ #[cfg(target_feature = "fp-armv8")]
|
|
|
+ restore!(ctx, gp, fp);
|
|
|
+ #[cfg(not(target_feature = "fp-armv8"))]
|
|
|
+ restore!(ctx, gp);
|
|
|
}
|
|
|
}
|