remove intermediate enum / directly encode assembly

This commit is contained in:
2026-06-11 21:49:04 -04:00
parent 91f5db6950
commit b03f755252
11 changed files with 414 additions and 668 deletions
+36 -103
View File
@@ -1,22 +1,8 @@
#[derive(Clone, Copy, PartialEq)]
pub struct Reg(u8);
#[derive(Clone, Copy)]
pub struct RegH {
pub reg: Reg,
pub high: bool,
}
#[derive(Clone, Copy)]
pub struct RegWH {
pub regh: RegH,
pub width: Width,
}
#[derive(Clone, Copy)]
pub struct Reg64 {
pub reg: Reg,
pub width: Width64,
pub struct Reg {
val: u8,
high: bool,
width: Width,
}
#[derive(Debug, Clone, Copy, PartialEq)]
@@ -27,22 +13,16 @@ pub enum Width {
B8,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Width64 {
B64,
B32,
}
def_regs! { Reg;
0b0000 : rax eax ax al,
0b0001 : rcx ecx cx cl,
0b0010 : rdx edx dx dl,
0b0011 : rbx ebx bx bl,
def_regs! { RegWH;
0b0000 : rax eax ax al ah=spl,
0b0001 : rcx ecx cx cl ch=bpl,
0b0010 : rdx edx dx dl dh=sil,
0b0011 : rbx ebx bx bl bh=dil,
0b0100 : rsp esp sp spl,
0b0101 : rbp ebp bp bpl,
0b0110 : rsi esi si sil,
0b0111 : rdi edi di dil,
0b0100 : rsp esp sp spl norex=ah,
0b0101 : rbp ebp bp bpl norex=ch,
0b0110 : rsi esi si sil norex=dh,
0b0111 : rdi edi di dil norex=bh,
0b1000 : r8 r8d r8w r8b,
0b1001 : r9 r9d r9w r9b,
@@ -56,36 +36,35 @@ def_regs! { RegWH;
impl Reg {
pub fn base(&self) -> u8 {
self.0 & 0b111
self.val & 0b111
}
/// checks if register is not one of the first 8 (0-7)
pub fn gt8(&self) -> bool {
self.0 >= 0b1000
self.val >= 0b1000
}
pub fn gt4(&self) -> bool {
self.0 >= 0b0100
self.val >= 0b0100
}
}
impl RegH {
pub fn requires_rex(&self, width: Width) -> bool {
self.gt8() || width == Width::B64 || (self.gt4() && width == Width::B8 && !self.high)
pub fn high(&self) -> bool {
self.high
}
}
impl RegWH {
const fn new(val: u8, width: Width, high: bool) -> Self {
Self {
regh: RegH {
reg: Reg(val),
high,
},
width,
}
pub fn width(&self) -> Width {
self.width
}
pub fn requires_rex(&self) -> bool {
self.regh.requires_rex(self.width)
self.gt8()
|| self.width == Width::B64
|| (self.gt4() && self.width == Width::B8 && !self.high)
}
pub fn incompatible(&self, other: &Reg) -> bool {
(self.requires_rex() && other.high) || (self.high && other.requires_rex())
}
const fn new(val: u8, width: Width, high: bool) -> Self {
Self { val, high, width }
}
}
@@ -112,44 +91,8 @@ impl Width {
}
}
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<Reg64> for Reg {
fn from(value: Reg64) -> Self {
value.reg
}
}
impl From<RegWH> for RegH {
fn from(value: RegWH) -> Self {
value.regh
}
}
impl TryFrom<Width> for Width64 {
type Error = ();
fn try_from(value: Width) -> Result<Self, Self::Error> {
match value {
Width::B64 => Ok(Self::B64),
Width::B32 => Ok(Self::B32),
_ => Err(()),
}
}
}
macro_rules! def_regs {
($Struct: ident; $($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 $(norex=$B8H:ident)?,)*) => {
$(
#[allow(non_upper_case_globals)]
pub const $B64: $Struct = $Struct::new($val, Width::B64, false);
@@ -161,7 +104,7 @@ macro_rules! def_regs {
pub const $B8 : $Struct = $Struct::new($val, Width::B8 , false);
$(
#[allow(non_upper_case_globals)]
pub const $B8H: $Struct = $Struct::new($hval.regh.reg.0, Width::B8, true);
pub const $B8H: $Struct = $Struct::new($val, Width::B8, true);
)?
)*
impl $Struct {
@@ -185,18 +128,8 @@ macro_rules! def_regs {
use def_regs;
impl std::ops::Deref for RegWH {
type Target = RegH;
fn deref(&self) -> &Self::Target {
&self.regh
}
}
impl std::ops::Deref for RegH {
type Target = Reg;
fn deref(&self) -> &Self::Target {
&self.reg
impl From<Reg> for Width {
fn from(value: Reg) -> Self {
value.width
}
}