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