diff --git a/simu/Cargo.toml b/simu/Cargo.toml index 4c4fe61..18de5a6 100644 --- a/simu/Cargo.toml +++ b/simu/Cargo.toml @@ -18,3 +18,7 @@ rgba = [] rich_keyboard = [] debug = ["dep:parse_int"] futex = ["dep:wait_on_address"] + +# [[bench]] +# name = "bench" +# harness = false diff --git a/simu/src/cpu.rs b/simu/src/cpu.rs index 1f7eb91..08b61a1 100644 --- a/simu/src/cpu.rs +++ b/simu/src/cpu.rs @@ -32,17 +32,26 @@ enum Op2 { } struct Reg(u8); + +#[allow(unused)] //constructed by transmute +#[repr(u8)] enum Cond { - Ifeq, - Ifne, - Iflt, - Ifge, - Ifgt, - Ifle, - Ifult, - Ifuge, - Ifugt, - Ifule, + Ifeq = 0b000, + Ifne = 0b0001, + UK1 = 2, + UK2 = 3, + UK3 = 4, + UK4 = 5, + UK5 = 6, + UK6 = 7, + Iflt = 0b1000, + Ifge = 0b1001, + Ifgt = 0b1010, + Ifle = 0b1011, + Ifult = 0b1100, + Ifuge = 0b1101, + Ifugt = 0b1110, + Ifule = 0b1111, } #[derive(Debug)] @@ -73,20 +82,10 @@ pub enum MMIOInterupt { } impl From for Cond { + #[inline(always)] fn from(value: u8) -> Self { - match value { - 0b0000 => Cond::Ifeq, - 0b0001 => Cond::Ifne, - 0b1000 => Cond::Iflt, - 0b1001 => Cond::Ifge, - 0b1010 => Cond::Ifgt, - 0b1011 => Cond::Ifle, - 0b1100 => Cond::Ifult, - 0b1101 => Cond::Ifuge, - 0b1110 => Cond::Ifugt, - 0b1111 => Cond::Ifule, - _ => iot(), - } + //unsafe if called with value >= 15 buuut only ever called on actually an u4 so it's ok + unsafe { transmute(value) } } } @@ -108,8 +107,9 @@ impl From for InteruptKind { } impl Cond { - fn eval(self, a: u32, b: u32) -> bool { - match self { + #[inline(always)] + fn eval(self, a: u32, b: u32) -> Option { + Some(match self { Cond::Ifeq => a == b, Cond::Ifne => a != b, Cond::Iflt => (a as i32) < (b as i32), @@ -120,7 +120,8 @@ impl Cond { Cond::Ifuge => a >= b, Cond::Ifugt => a > b, Cond::Ifule => a <= b, - } + _ => return None + }) } } @@ -274,6 +275,7 @@ impl Display for Cond { Cond::Ifuge => write!(f, "ifuge"), Cond::Ifugt => write!(f, "ifugt"), Cond::Ifule => write!(f, "ifule"), + _ => write!(f, "unknown"), } } } @@ -354,10 +356,6 @@ impl IndexMut for Computer { } } -fn iot() -> ! { - exit(1); -} - impl Computer { pub fn new(filename: String) -> Self { let mut new = Self { @@ -586,8 +584,12 @@ impl Computer { } Instruction::Skip(d, cond, reg, op2) => { self.pc += 1; - if cond.eval(self[reg], self.resolve(op2)) { - self.pc += d as usize + match cond.eval(self[reg], self.resolve(op2)) { + Some(false) => {/*Nothing*/} + Some(true) => {self.pc += d as usize} + None => { + cold_path(); + self.serve_interupt(InteruptKind::IllegalOpcode, [next_opcode])} } } Instruction::Jump(addr) => { @@ -743,6 +745,7 @@ impl Computer { } } } + #[inline(always)] fn resolve(&self, op2: Op2) -> u32 { match op2 { Op2::Direct(v) => v, diff --git a/simu/src/main.rs b/simu/src/main.rs index 105a301..5131663 100644 --- a/simu/src/main.rs +++ b/simu/src/main.rs @@ -300,6 +300,8 @@ fn main() -> Result<(), Error> { loop { simulation.step(64); } + + //ugly debug code, I should improve that using a real TUI crate #[cfg(feature = "debug")] { let mut input = std::io::stdin().lines();