1 use core::num::NonZeroUsize;
2 use gdbstub::arch::RegId;
3 
4 /// RISC-V Register identifier.
5 #[derive(Debug, Clone, Copy)]
6 #[non_exhaustive]
7 pub enum RiscvRegId<U> {
8     /// General Purpose Register (x0-x31).
9     Gpr(u8),
10     /// Floating Point Register (f0-f31).
11     Fpr(u8),
12     /// Program Counter.
13     Pc,
14     /// Control and Status Register.
15     Csr(u16),
16     /// Privilege level.
17     Priv,
18 
19     #[doc(hidden)]
20     _Marker(core::marker::PhantomData<U>),
21 }
22 
23 macro_rules! impl_riscv_reg_id {
24     ($usize:ty) => {
25         impl RegId for RiscvRegId<$usize> {
26             fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> {
27                 const USIZE: usize = core::mem::size_of::<$usize>();
28 
29                 let (id, size) = match id {
30                     0..=31 => (Self::Gpr(id as u8), USIZE),
31                     32 => (Self::Pc, USIZE),
32                     33..=64 => (Self::Fpr((id - 33) as u8), USIZE),
33                     65..=4160 => (Self::Csr((id - 65) as u16), USIZE),
34                     4161 => (Self::Priv, 1),
35                     _ => return None,
36                 };
37 
38                 Some((id, Some(NonZeroUsize::new(size)?)))
39             }
40         }
41     };
42 }
43 
44 impl_riscv_reg_id!(u32);
45 impl_riscv_reg_id!(u64);
46