use core::num::NonZeroUsize; use gdbstub::arch::RegId; /// TI-MSP430 register identifier. /// /// GDB does not provide a XML file for the MSP430. /// The best file to reference is [msp430-tdep.c](https://github.com/bminor/binutils-gdb/blob/master/gdb/msp430-tdep.c). #[derive(Debug, Clone, Copy)] #[non_exhaustive] pub enum Msp430RegId { /// Program Counter (R0) Pc, /// Stack Pointer (R1) Sp, /// Status Register (R2) Sr, /// Constant Generator (R3) Cg, /// General Purpose Registers (R4-R15) Gpr(u8), #[doc(hidden)] _Size(core::marker::PhantomData), } fn from_raw_id(id: usize) -> Option<(Msp430RegId, Option)> { let reg = match id { 0 => Msp430RegId::Pc, 1 => Msp430RegId::Sp, 2 => Msp430RegId::Sr, 3 => Msp430RegId::Cg, 4..=15 => Msp430RegId::Gpr((id as u8) - 4), _ => return None, }; let ptrsize = core::mem::size_of::(); Some((reg, Some(NonZeroUsize::new(ptrsize)?))) } impl RegId for Msp430RegId { fn from_raw_id(id: usize) -> Option<(Self, Option)> { from_raw_id::(id) } } impl RegId for Msp430RegId { fn from_raw_id(id: usize) -> Option<(Self, Option)> { from_raw_id::(id) } } #[cfg(test)] mod tests { use gdbstub::arch::RegId; use gdbstub::arch::Registers; fn test() { // Obtain the data length written by `gdb_serialize` by passing a custom // closure. let mut serialized_data_len = 0; let counter = |b: Option| { if b.is_some() { serialized_data_len += 1; } }; Rs::default().gdb_serialize(counter); // The `Msp430Regs` implementation does not increment the size for // the CG register since it will always be the constant zero. serialized_data_len += RId::from_raw_id(3).unwrap().1.unwrap().get(); // Accumulate register sizes returned by `from_raw_id`. let mut i = 0; let mut sum_reg_sizes = 0; while let Some((_, size)) = RId::from_raw_id(i) { sum_reg_sizes += size.unwrap().get(); i += 1; } assert_eq!(serialized_data_len, sum_reg_sizes); } #[test] fn test_msp430() { test::, crate::msp430::reg::id::Msp430RegId>() } #[test] fn test_msp430x() { test::, crate::msp430::reg::id::Msp430RegId>() } }