1 use gdbstub::arch::RegId; 2 3 /// TI-MSP430 register identifier. 4 /// 5 /// GDB does not provide a XML file for the MSP430. 6 /// The best file to reference is [msp430-tdep.c](https://github.com/bminor/binutils-gdb/blob/master/gdb/msp430-tdep.c). 7 #[derive(Debug, Clone, Copy)] 8 #[non_exhaustive] 9 pub enum Msp430RegId { 10 /// Program Counter (R0) 11 Pc, 12 /// Stack Pointer (R1) 13 Sp, 14 /// Status Register (R2) 15 Sr, 16 /// Constant Generator (R3) 17 Cg, 18 /// General Purpose Registers (R4-R15) 19 Gpr(u8), 20 } 21 22 impl RegId for Msp430RegId { from_raw_id(id: usize) -> Option<(Self, usize)>23 fn from_raw_id(id: usize) -> Option<(Self, usize)> { 24 let reg = match id { 25 0 => Self::Pc, 26 1 => Self::Sp, 27 2 => Self::Sr, 28 3 => Self::Cg, 29 4..=15 => Self::Gpr((id as u8) - 4), 30 _ => return None, 31 }; 32 Some((reg, 2)) 33 } 34 } 35 36 #[cfg(test)] 37 mod tests { 38 use gdbstub::arch::RegId; 39 use gdbstub::arch::Registers; 40 test<Rs: Registers, RId: RegId>()41 fn test<Rs: Registers, RId: RegId>() { 42 // Obtain the data length written by `gdb_serialize` by passing a custom 43 // closure. 44 let mut serialized_data_len = 0; 45 let counter = |b: Option<u8>| { 46 if b.is_some() { 47 serialized_data_len += 1; 48 } 49 }; 50 Rs::default().gdb_serialize(counter); 51 52 // The `Msp430Regs` implementation does not increment the size for 53 // the CG register since it will always be the constant zero. 54 serialized_data_len += 4; 55 56 // Accumulate register sizes returned by `from_raw_id`. 57 let mut i = 0; 58 let mut sum_reg_sizes = 0; 59 while let Some((_, size)) = RId::from_raw_id(i) { 60 sum_reg_sizes += size; 61 i += 1; 62 } 63 64 assert_eq!(serialized_data_len, sum_reg_sizes); 65 } 66 67 #[test] test_msp430()68 fn test_msp430() { 69 test::<crate::msp430::reg::Msp430Regs, crate::msp430::reg::id::Msp430RegId>() 70 } 71 } 72