#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
pub struct RegIdx(u8);
impl RegIdx {
#[inline(always)]
pub const fn new(idx: u8) -> Self {
debug_assert!(idx <= 31, "RegIdx out of range: must be 0..=31");
Self(idx & 0x1F)
}
#[inline(always)]
pub const fn as_usize(self) -> usize {
self.0 as usize
}
#[inline(always)]
pub const fn as_u8(self) -> u8 {
self.0
}
#[inline(always)]
pub const fn is_zero(self) -> bool {
self.0 == 0
}
}
impl From<u8> for RegIdx {
#[inline(always)]
fn from(v: u8) -> Self {
Self::new(v)
}
}
impl From<usize> for RegIdx {
#[inline(always)]
fn from(v: usize) -> Self {
debug_assert!(v <= 31, "RegIdx from usize out of range: {v}");
Self((v & 0x1F) as u8)
}
}
impl From<RegIdx> for usize {
#[inline(always)]
fn from(r: RegIdx) -> Self {
r.0 as Self
}
}
impl From<RegIdx> for u8 {
#[inline(always)]
fn from(r: RegIdx) -> Self {
r.0
}
}
impl std::fmt::Display for RegIdx {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "x{}", self.0)
}
}
pub const REG_ZERO: RegIdx = RegIdx::new(0);
pub const REG_RA: RegIdx = RegIdx::new(1);
pub const REG_SP: RegIdx = RegIdx::new(2);
pub const REG_T0: RegIdx = RegIdx::new(5);
pub const REG_A0: RegIdx = RegIdx::new(10);
pub const REG_A1: RegIdx = RegIdx::new(11);
pub const REG_A2: RegIdx = RegIdx::new(12);
pub const REG_A7: RegIdx = RegIdx::new(17);