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