diff --git a/; b/; deleted file mode 100644 index cecfcde..0000000 --- a/; +++ /dev/null @@ -1,68 +0,0 @@ -mod setup; -use setup::*; - -#[test] -fn mov() { - let c = &mut TestCtx::new("mov"); - - for dst in regs() { - for src in regs() { - eq(c, format!("mov {dst}, {src}"), |c| c.mov(dst, src)); - } - } - - for dst in regs() { - for src in mems() { - eq(c, format!("mov {dst}, {src}"), |c| c.mov(dst, src)); - } - } - - for dst in regs() { - for src in imms() { - eq(c, format!("mov {dst}, {src}"), |c| c.mov(dst, src)); - } - } - - for dst in mems() { - for src in regs() { - eq(c, format!("mov {dst}, {src}"), |c| c.mov(dst, src)); - } - } - - for dst in mems() { - for src in imms() { - eq(c, format!("mov {dst}, {src}"), |c| c.mov(dst, src)); - } - } -} - -#[test] -fn add_sub() { - let c = &mut TestCtx::new("add_sub"); - - // add - for dst in regs() { - for src in imms() { - eq(c, format!("add {dst}, {src}"), |c| c.add(dst, src)) - } - } - - for dst in regs() { - for src in regs() { - eq(c, format!("add {dst}, {src}"), |c| c.add(dst, src)) - } - } - - for dst in mems() { - for src in imms() { - eq(c, format!("add {dst}, {src}"), |c| c.add(dst, src)) - } - } - - // sub - for dst in regs() { - for src in imms() { - eq(c, format!("sub {dst}, {src}"), |c| c.sub(dst, src)) - } - } -} diff --git a/src/arch/x86_64/compile.rs b/src/arch/x86_64/compile.rs index acb395c..d19d82f 100644 --- a/src/arch/x86_64/compile.rs +++ b/src/arch/x86_64/compile.rs @@ -199,7 +199,7 @@ impl<'a> Encoder<'a> { return (seg_i, pos); } - pub fn rvm(&mut self, input: Rvm) -> RegMemKind { + pub fn rvm(&mut self, input: Rvm) -> RegMem { match input { Rvm::Reg(reg) => reg, Rvm::Var(var_id) => todo!(), diff --git a/src/arch/x86_64/encode.rs b/src/arch/x86_64/encode.rs index 639870f..930b7e1 100644 --- a/src/arch/x86_64/encode.rs +++ b/src/arch/x86_64/encode.rs @@ -11,10 +11,11 @@ pub struct Code { } impl Code { - pub fn mov(&mut self, dst: impl RegMem, src: impl Into) -> ERes { + pub fn mov(&mut self, dst: impl Into, src: impl Into) -> ERes { + let dst = dst.into(); let src = src.into(); - match dst.kind() { - RegMemKind::Reg(mut dst) => match src { + match dst { + RegMem::Reg(mut dst) => match src { RegMemImm::Reg(src) => { if dst.width() != src.width() { return Err("src and dst are not same width".into()); @@ -55,7 +56,7 @@ impl Code { self.modrm(dst, src); } }, - RegMemKind::Mem(dst) => match src { + RegMem::Mem(dst) => match src { RegMemImm::Reg(src) => { if src.width() != dst.width { return Err("register & memory sizes don't match".into()); @@ -162,7 +163,8 @@ impl Code { self.bytes.push(0xc3); } - fn add_sub(&mut self, dst: impl RegMem, src: impl Into, ext: u8) -> ERes { + fn add_sub(&mut self, dst: impl Into, src: impl Into, ext: u8) -> ERes { + let dst = dst.into(); match src.into() { RegMemImm::Reg(src) => { if src.width() != dst.width() { @@ -203,10 +205,10 @@ impl Code { self.imm(src, imm_width); } RegMemImm::Mem(src) => { - let RegMemKind::Reg(dst) = dst.kind() else { + let RegMem::Reg(dst) = dst else { return Err("cannot add memory to memory".into()); }; - if src.width() != dst.width() { + if src.width != dst.width() { return Err("incompatible widths".into()); } self.prefix32(src)?; @@ -219,11 +221,11 @@ impl Code { Ok(()) } - pub fn add(&mut self, dst: impl RegMem, src: impl Into) -> ERes { + pub fn add(&mut self, dst: impl Into, src: impl Into) -> ERes { self.add_sub(dst, src, 0) } - pub fn sub(&mut self, dst: impl RegMem, src: impl Into) -> ERes { + pub fn sub(&mut self, dst: impl Into, src: impl Into) -> ERes { self.add_sub(dst, src, 5) } diff --git a/src/arch/x86_64/types/arg.rs b/src/arch/x86_64/types/arg.rs index 632919c..6c63c73 100644 --- a/src/arch/x86_64/types/arg.rs +++ b/src/arch/x86_64/types/arg.rs @@ -1,13 +1,8 @@ use super::*; use crate::backend::Symbol; -pub trait RegMem: RexBit + RexW + ModRMRM + Copy + MaybeMem { - fn width(&self) -> Width; - fn kind(self) -> RegMemKind; -} - #[derive(Clone, Copy)] -pub enum RegMemKind { +pub enum RegMem { Reg(RegW), Mem(Mem), } @@ -23,12 +18,12 @@ pub trait MaybeMem { fn mem(&self) -> Option; } -impl RegMem for RegW { - fn width(&self) -> Width { - self.width() - } - fn kind(self) -> RegMemKind { - RegMemKind::Reg(self) +impl RegMem { + pub fn width(&self) -> Width { + match self { + RegMem::Reg(reg_w) => reg_w.width(), + RegMem::Mem(mem) => mem.width, + } } } @@ -38,21 +33,55 @@ impl MaybeMem for RegW { } } -impl RegMem for Mem { - fn width(&self) -> Width { - self.width - } - fn kind(self) -> RegMemKind { - RegMemKind::Mem(self) - } -} - impl MaybeMem for Mem { fn mem(&self) -> Option { Some(*self) } } +impl MaybeMem for RegMem { + fn mem(&self) -> Option { + match self { + RegMem::Reg(reg_w) => None, + RegMem::Mem(mem) => Some(*mem), + } + } +} + +impl RexW for RegMem { + fn rexw(&self) -> bool { + match self { + RegMem::Reg(reg_w) => reg_w.rexw(), + RegMem::Mem(mem) => mem.rexw(), + } + } +} + +impl RexBit for RegMem { + fn rex(&self) -> bool { + match self { + RegMem::Reg(reg_w) => reg_w.rex(), + RegMem::Mem(mem) => mem.rex(), + } + } +} + +impl ModRMRM for RegMem { + fn rm(&self) -> u8 { + match self { + RegMem::Reg(reg_w) => reg_w.rm(), + RegMem::Mem(mem) => mem.rm(), + } + } + + fn addr(&self) -> EffAddr { + match self { + RegMem::Reg(reg_w) => reg_w.addr(), + RegMem::Mem(mem) => mem.addr(), + } + } +} + // fromrot impl From for RegMemImm { fn from(value: RegW) -> Self { @@ -60,7 +89,7 @@ impl From for RegMemImm { } } -impl From for RegMemKind { +impl From for RegMem { fn from(value: RegW) -> Self { Self::Reg(value) } @@ -72,7 +101,7 @@ impl From for RegMemImm { } } -impl From for RegMemKind { +impl From for RegMem { fn from(value: Mem) -> Self { Self::Mem(value) }