again, some minor perf improvement, probably be the last
This commit is contained in:
@@ -18,3 +18,7 @@ rgba = []
|
||||
rich_keyboard = []
|
||||
debug = ["dep:parse_int"]
|
||||
futex = ["dep:wait_on_address"]
|
||||
|
||||
# [[bench]]
|
||||
# name = "bench"
|
||||
# harness = false
|
||||
|
||||
@@ -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<u8> 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<u32> for InteruptKind {
|
||||
}
|
||||
|
||||
impl Cond {
|
||||
fn eval(self, a: u32, b: u32) -> bool {
|
||||
match self {
|
||||
#[inline(always)]
|
||||
fn eval(self, a: u32, b: u32) -> Option<bool> {
|
||||
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<Reg> 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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user