lots of refactoring
This commit is contained in:
+126
-38
@@ -2,47 +2,35 @@
|
||||
pub struct Reg(u8);
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct RegMode {
|
||||
pub struct RegH {
|
||||
pub reg: Reg,
|
||||
pub width: BitWidth,
|
||||
pub high: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct RegWH {
|
||||
pub reg: Reg,
|
||||
pub widthh: WidthH,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum BitWidth {
|
||||
pub enum Width {
|
||||
B64,
|
||||
B32,
|
||||
B16,
|
||||
B8,
|
||||
}
|
||||
|
||||
impl Reg {
|
||||
pub fn base(&self) -> u8 {
|
||||
self.0 & 0b111
|
||||
}
|
||||
/// checks if register is not one of the first 8 (0-7)
|
||||
pub fn gt8(&self) -> bool {
|
||||
self.0 >= 0b1000
|
||||
}
|
||||
pub fn gt4(&self) -> bool {
|
||||
self.0 >= 0b0100
|
||||
}
|
||||
/// width that also specifies if high for 8 bit
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum WidthH {
|
||||
B64,
|
||||
B32,
|
||||
B16,
|
||||
B8 { high: bool },
|
||||
}
|
||||
|
||||
impl RegMode {
|
||||
pub fn base(&self) -> u8 {
|
||||
self.reg.base()
|
||||
}
|
||||
/// checks if register is not one of the first 8 (0-7)
|
||||
pub fn gt8(&self) -> bool {
|
||||
self.reg.gt8()
|
||||
}
|
||||
pub fn gt4(&self) -> bool {
|
||||
self.reg.gt4()
|
||||
}
|
||||
}
|
||||
|
||||
def_regs! {
|
||||
def_regs! { RegWH;
|
||||
0b0000 : rax eax ax al ah=spl,
|
||||
0b0001 : rcx ecx cx cl ch=bpl,
|
||||
0b0010 : rdx edx dx dl dh=sil,
|
||||
@@ -63,13 +51,40 @@ def_regs! {
|
||||
0b1111 : r15 r15d r15w r15b,
|
||||
}
|
||||
|
||||
impl BitWidth {
|
||||
impl Reg {
|
||||
pub fn base(&self) -> u8 {
|
||||
self.0 & 0b111
|
||||
}
|
||||
/// checks if register is not one of the first 8 (0-7)
|
||||
pub fn gt8(&self) -> bool {
|
||||
self.0 >= 0b1000
|
||||
}
|
||||
pub fn gt4(&self) -> bool {
|
||||
self.0 >= 0b0100
|
||||
}
|
||||
}
|
||||
|
||||
impl RegWH {
|
||||
pub fn requires_rex(&self) -> bool {
|
||||
self.gt8()
|
||||
|| self.widthh == WidthH::B64
|
||||
|| (self.gt4() && self.widthh == WidthH::B8 { high: false })
|
||||
}
|
||||
}
|
||||
|
||||
impl RegH {
|
||||
pub fn requires_rex(&self, width: Width) -> bool {
|
||||
self.gt8() || width == Width::B64 || (self.gt4() && width == Width::B8 && !self.high)
|
||||
}
|
||||
}
|
||||
|
||||
impl WidthH {
|
||||
pub const fn max(&self) -> u64 {
|
||||
match self {
|
||||
Self::B64 => u64::MAX,
|
||||
Self::B32 => u32::MAX as u64,
|
||||
Self::B16 => u16::MAX as u64,
|
||||
Self::B8 => u8::MAX as u64,
|
||||
Self::B8 { .. } => u8::MAX as u64,
|
||||
}
|
||||
}
|
||||
pub const fn bytes(&self) -> usize {
|
||||
@@ -77,28 +92,84 @@ impl BitWidth {
|
||||
Self::B64 => 8,
|
||||
Self::B32 => 4,
|
||||
Self::B16 => 2,
|
||||
Self::B8 => 1,
|
||||
Self::B8 { .. } => 1,
|
||||
}
|
||||
}
|
||||
/// greater than 8 bits
|
||||
pub const fn gt8(&self) -> bool {
|
||||
!matches!(self, Self::B8 { .. })
|
||||
}
|
||||
|
||||
pub const fn width(&self) -> Width {
|
||||
match self {
|
||||
WidthH::B64 => Width::B64,
|
||||
WidthH::B32 => Width::B32,
|
||||
WidthH::B16 => Width::B16,
|
||||
WidthH::B8 { .. } => Width::B8,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Width {
|
||||
/// greater than 8 bits
|
||||
pub const fn gt8(&self) -> bool {
|
||||
!matches!(self, Self::B8)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RegWH> for Reg {
|
||||
fn from(value: RegWH) -> Self {
|
||||
value.reg
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RegH> for Reg {
|
||||
fn from(value: RegH) -> Self {
|
||||
value.reg
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RegWH> for RegH {
|
||||
fn from(value: RegWH) -> Self {
|
||||
Self {
|
||||
reg: value.reg,
|
||||
high: if let WidthH::B8 { high } = value.widthh {
|
||||
high
|
||||
} else {
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WidthH> for Width {
|
||||
fn from(value: WidthH) -> Self {
|
||||
match value {
|
||||
WidthH::B64 => Self::B64,
|
||||
WidthH::B32 => Self::B32,
|
||||
WidthH::B16 => Self::B16,
|
||||
WidthH::B8 { .. } => Self::B8,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! def_regs {
|
||||
($($val:literal : $B64:ident $B32:ident $B16:ident $B8:ident $($B8H:ident=$hval:expr)?,)*) => {
|
||||
($Struct: ident; $($val:literal : $B64:ident $B32:ident $B16:ident $B8:ident $($B8H:ident=$hval:expr)?,)*) => {
|
||||
$(
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const $B64: RegMode = RegMode { reg: Reg($val), width: BitWidth::B64, high: false };
|
||||
pub const $B64: $Struct = $Struct { reg: Reg($val), widthh: WidthH::B64 };
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const $B32: RegMode = RegMode { reg: Reg($val), width: BitWidth::B32, high: false };
|
||||
pub const $B32: $Struct = $Struct { reg: Reg($val), widthh: WidthH::B32 };
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const $B16: RegMode = RegMode { reg: Reg($val), width: BitWidth::B16, high: false };
|
||||
pub const $B16: $Struct = $Struct { reg: Reg($val), widthh: WidthH::B16 };
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const $B8 : RegMode = RegMode { reg: Reg($val), width: BitWidth::B8, high: false };
|
||||
pub const $B8 : $Struct = $Struct { reg: Reg($val), widthh: WidthH::B8 { high: false } };
|
||||
$(
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const $B8H: RegMode = RegMode { reg: $hval.reg, width: BitWidth::B8, high: true };
|
||||
pub const $B8H: $Struct = $Struct { reg: $hval.reg, widthh: WidthH::B8 { high: true } };
|
||||
)?
|
||||
)*
|
||||
impl RegMode {
|
||||
impl $Struct {
|
||||
pub fn parse(s: &str) -> Option<Self> {
|
||||
Some(match s.to_lowercase().as_str() {
|
||||
$(
|
||||
@@ -116,4 +187,21 @@ macro_rules! def_regs {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
use def_regs;
|
||||
|
||||
impl std::ops::Deref for RegWH {
|
||||
type Target = Reg;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.reg
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for RegH {
|
||||
type Target = Reg;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.reg
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user