Add AArch64 support

This commit is contained in:
Gary Guo 2021-09-06 23:27:01 +01:00
parent e39f404854
commit 789082f176
3 changed files with 152 additions and 0 deletions

View File

@ -33,3 +33,21 @@ mod riscv {
}
#[cfg(any(target_arch = "riscv64", target_arch = "riscv32"))]
pub use riscv::*;
#[cfg(target_arch = "aarch64")]
mod aarch64 {
use gimli::{AArch64, Register};
pub struct Arch;
#[allow(unused)]
impl Arch {
pub const SP: Register = AArch64::SP;
pub const RA: Register = AArch64::X30;
pub const UNWIND_DATA_REG: (Register, Register) = (AArch64::X0, AArch64::X1);
pub const UNWIND_PRIVATE_DATA_SIZE: usize = 2;
}
}
#[cfg(target_arch = "aarch64")]
pub use aarch64::*;

View File

@ -0,0 +1,129 @@
use core::fmt;
use core::ops;
use gimli::{AArch64, Register};
#[repr(C)]
#[derive(Clone, Default)]
pub struct Context {
pub gp: [usize; 31],
pub sp: usize,
pub fp: [usize; 32],
}
impl fmt::Debug for Context {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut fmt = fmt.debug_struct("Context");
for i in 0..=30 {
fmt.field(
AArch64::register_name(Register(i as _)).unwrap(),
&self.gp[i],
);
}
fmt.field("sp", &self.sp);
for i in 0..=31 {
fmt.field(
AArch64::register_name(Register((i + 64) as _)).unwrap(),
&self.fp[i],
);
}
fmt.finish()
}
}
impl ops::Index<Register> for Context {
type Output = usize;
fn index(&self, reg: Register) -> &usize {
match reg {
Register(0..=30) => &self.gp[reg.0 as usize],
AArch64::SP => &self.sp,
Register(64..=95) => &self.fp[(reg.0 - 64) as usize],
_ => unimplemented!(),
}
}
}
impl ops::IndexMut<gimli::Register> for Context {
fn index_mut(&mut self, reg: Register) -> &mut usize {
match reg {
Register(0..=30) => &mut self.gp[reg.0 as usize],
AArch64::SP => &mut self.sp,
Register(64..=95) => &mut self.fp[(reg.0 - 64) as usize],
_ => unimplemented!(),
}
}
}
#[naked]
pub extern "C-unwind" fn save_context() -> Context {
// No need to save caller-saved registers here.
unsafe {
asm!(
"
stp d8, d9, [x8, 0x140]
stp d10, d11, [x8, 0x150]
stp d12, d13, [x8, 0x160]
stp d14, d15, [x8, 0x170]
str x19, [x8, 0x98]
stp x20, x21, [x8, 0xA0]
stp x22, x23, [x8, 0xB0]
stp x24, x25, [x8, 0xC0]
stp x26, x27, [x8, 0xD0]
stp x28, x29, [x8, 0xE0]
mov x0, sp
stp x30, x0, [x8, 0xF0]
ret
",
options(noreturn)
);
}
}
#[naked]
pub unsafe extern "C" fn restore_context(ctx: &Context) -> ! {
unsafe {
asm!(
"
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]
ldp x8, x9, [x0, 0x40]
ldp x10, x11, [x0, 0x50]
ldp x12, x13, [x0, 0x60]
ldp x14, x15, [x0, 0x70]
ldp x16, x17, [x0, 0x80]
ldp x18, x19, [x0, 0x90]
ldp x20, x21, [x0, 0xA0]
ldp x22, x23, [x0, 0xB0]
ldp x24, x25, [x0, 0xC0]
ldp x26, x27, [x0, 0xD0]
ldp x28, x29, [x0, 0xE0]
ldp x30, x1, [x0, 0xF0]
mov sp, x1
ldp x0, x1, [x0, 0x00]
ret
",
options(noreturn)
);
}
}

View File

@ -7,3 +7,8 @@ pub use x86_64::*;
mod riscv64;
#[cfg(target_arch = "riscv64")]
pub use riscv64::*;
#[cfg(target_arch = "aarch64")]
mod aarch64;
#[cfg(target_arch = "aarch64")]
pub use aarch64::*;