diff --git a/gdbstub_arch/src/aarch64/fpu.xml b/gdbstub_arch/src/aarch64/fpu.xml
index 780416b..ac8c477 100644
--- a/gdbstub_arch/src/aarch64/fpu.xml
+++ b/gdbstub_arch/src/aarch64/fpu.xml
@@ -121,7 +121,7 @@
operations. -->
-
+
@@ -156,5 +156,5 @@
-
+
diff --git a/gdbstub_arch/src/aarch64/reg/aarch64_core.rs b/gdbstub_arch/src/aarch64/reg/aarch64_core.rs
index c503c79..083c8c1 100644
--- a/gdbstub_arch/src/aarch64/reg/aarch64_core.rs
+++ b/gdbstub_arch/src/aarch64/reg/aarch64_core.rs
@@ -16,6 +16,12 @@ pub struct AArch64CoreRegs {
pub pc: u64,
/// Process State (GDB uses the AArch32 CPSR name)
pub cpsr: u32,
+ /// FP & SIMD Registers (V0-V31)
+ pub v: [u128; 32],
+ /// Floating-point Control Register
+ pub fpcr: u32,
+ /// Floating-point Status Register
+ pub fpsr: u32,
}
impl Registers for AArch64CoreRegs {
@@ -40,16 +46,24 @@ impl Registers for AArch64CoreRegs {
write_bytes!(self.sp);
write_bytes!(self.pc);
write_bytes!(self.cpsr);
+ for reg in self.v.iter() {
+ write_bytes!(reg);
+ }
+ write_bytes!(self.fpcr);
+ write_bytes!(self.fpsr);
}
fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> {
- const U64_END: usize = core::mem::size_of::() * 33;
+ const CPSR_OFF: usize = core::mem::size_of::() * 33;
+ const FPSIMD_OFF: usize = CPSR_OFF + core::mem::size_of::();
+ const FPCR_OFF: usize = FPSIMD_OFF + core::mem::size_of::() * 32;
+ const END: usize = FPCR_OFF + core::mem::size_of::() * 2;
- if bytes.len() % core::mem::size_of::() != 0 {
+ if bytes.len() < END {
return Err(());
}
- let mut regs = bytes[0..U64_END]
+ let mut regs = bytes[0..CPSR_OFF]
.chunks_exact(core::mem::size_of::())
.map(|c| u64::from_le_bytes(c.try_into().unwrap()));
@@ -59,12 +73,27 @@ impl Registers for AArch64CoreRegs {
self.sp = regs.next().ok_or(())?;
self.pc = regs.next().ok_or(())?;
- let mut regs = bytes[U64_END..]
+ let mut regs = bytes[CPSR_OFF..FPSIMD_OFF]
.chunks_exact(core::mem::size_of::())
.map(|c| u32::from_le_bytes(c.try_into().unwrap()));
self.cpsr = regs.next().ok_or(())?;
+ let mut regs = bytes[FPSIMD_OFF..FPCR_OFF]
+ .chunks_exact(core::mem::size_of::())
+ .map(|c| u128::from_le_bytes(c.try_into().unwrap()));
+
+ for reg in self.v.iter_mut() {
+ *reg = regs.next().ok_or(())?
+ }
+
+ let mut regs = bytes[FPCR_OFF..]
+ .chunks_exact(core::mem::size_of::())
+ .map(|c| u32::from_le_bytes(c.try_into().unwrap()));
+
+ self.fpcr = regs.next().ok_or(())?;
+ self.fpsr = regs.next().ok_or(())?;
+
Ok(())
}
}
diff --git a/gdbstub_arch/src/aarch64/reg/id.rs b/gdbstub_arch/src/aarch64/reg/id.rs
index 437f248..3d4acc1 100644
--- a/gdbstub_arch/src/aarch64/reg/id.rs
+++ b/gdbstub_arch/src/aarch64/reg/id.rs
@@ -54,6 +54,8 @@ impl RegId for AArch64RegId {
32 => Self::Pc,
33 => Self::Pstate,
34..=65 => Self::V((id - 34) as u8),
+ 66 => Self::FPSR,
+ 67 => Self::FPCR,
#[allow(clippy::unusual_byte_groupings)]
// We configure GDB to use regnums that correspond to the architectural u16 opcode
// and avoid clashes with core registers thanks to op0==0b00 and op0==0b01 not being