chore(interpreter): reduce code complexity
This commit is contained in:
@@ -163,102 +163,16 @@ impl Computer {
|
||||
O: Fn(Lhs, Rhs) -> ArithmeticResult,
|
||||
F: Fn(&mut Flags, ArithmeticResult, Lhs, Rhs),
|
||||
{
|
||||
match src {
|
||||
Operand::ModRmTarget(src_target) => {
|
||||
self.op_modrm(op, flag_set, write, dest, src_target)
|
||||
}
|
||||
Operand::Immediate(src_operand) => self.op_imm(op, flag_set, write, dest, src_operand),
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies a binary operator [`O`] to two memory locations, pointed to by a
|
||||
/// [`ModRmTargets`]s, saves it to dest, if `write` is set, and sets flags,
|
||||
/// according to [`F`].
|
||||
fn op_modrm<O, F>(
|
||||
&mut self,
|
||||
op: O,
|
||||
flag_set: F,
|
||||
write: bool,
|
||||
dest: ModRmTarget,
|
||||
src: ModRmTarget,
|
||||
) where
|
||||
O: Fn(Lhs, Rhs) -> ArithmeticResult,
|
||||
F: Fn(&mut Flags, ArithmeticResult, Lhs, Rhs),
|
||||
{
|
||||
match dest {
|
||||
ModRmTarget::Memory(dest_memory_idx) => match src {
|
||||
// mem, mem
|
||||
ModRmTarget::Memory(_) => {
|
||||
panic!("Cannot apply binary operator from Memory to Memory!")
|
||||
}
|
||||
// mem, reg
|
||||
ModRmTarget::Register(src_register) => {
|
||||
let lhs = self.memory.read(&self.regs, dest_memory_idx);
|
||||
let rhs = self.regs.read(src_register);
|
||||
let result = op(lhs, rhs);
|
||||
if write {
|
||||
self.memory.write(&self.regs, dest_memory_idx, result);
|
||||
}
|
||||
flag_set(&mut self.flags, result, lhs, rhs);
|
||||
}
|
||||
},
|
||||
ModRmTarget::Register(dest_register) => match src {
|
||||
// reg, mem
|
||||
ModRmTarget::Memory(src_memory_index) => {
|
||||
let lhs = self.regs.read(dest_register);
|
||||
let rhs = self.memory.read(&self.regs, src_memory_index);
|
||||
let result = op(lhs, rhs);
|
||||
if write {
|
||||
self.regs.write(dest_register, result);
|
||||
}
|
||||
flag_set(&mut self.flags, result, lhs, rhs);
|
||||
}
|
||||
// reg, reg
|
||||
ModRmTarget::Register(src_register) => {
|
||||
let lhs = self.regs.read(dest_register);
|
||||
let rhs = self.regs.read(src_register);
|
||||
let result = op(lhs, rhs);
|
||||
if write {
|
||||
self.regs.write(dest_register, result);
|
||||
}
|
||||
flag_set(&mut self.flags, result, lhs, rhs);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies a binary operator [`O`] to [`ImmediateOperand`] and a location
|
||||
/// pointed to by a [`ModRmTarget`], saves it to dest, if `write` is set
|
||||
/// and sets flags, according to [`F`].
|
||||
fn op_imm<O, F>(
|
||||
&mut self,
|
||||
op: O,
|
||||
flag_set: F,
|
||||
write: bool,
|
||||
dest: ModRmTarget,
|
||||
src: ImmediateOperand,
|
||||
) where
|
||||
O: Fn(Lhs, Rhs) -> ArithmeticResult,
|
||||
F: Fn(&mut Flags, ArithmeticResult, Lhs, Rhs),
|
||||
{
|
||||
match dest {
|
||||
ModRmTarget::Memory(dest_mem) => {
|
||||
let lhs = self.memory.read(&self.regs, dest_mem);
|
||||
let result = op(lhs, src);
|
||||
if write {
|
||||
self.memory.write(&self.regs, dest_mem, result);
|
||||
}
|
||||
flag_set(&mut self.flags, result, lhs, src);
|
||||
}
|
||||
ModRmTarget::Register(dest_reg) => {
|
||||
let lhs = self.regs.read(dest_reg);
|
||||
let result = op(lhs, src);
|
||||
if write {
|
||||
self.regs.write(dest_reg, result);
|
||||
}
|
||||
flag_set(&mut self.flags, result, lhs, src);
|
||||
}
|
||||
let lhs = self.read_modrm(dest);
|
||||
let rhs = match src {
|
||||
Operand::Immediate(imm) => imm,
|
||||
Operand::ModRmTarget(target) => self.read_modrm(target),
|
||||
};
|
||||
let result = op(lhs, rhs);
|
||||
if write {
|
||||
self.write_modrm(dest, result);
|
||||
}
|
||||
flag_set(&mut self.flags, result, lhs, rhs);
|
||||
}
|
||||
|
||||
/// Write an [`ImmediateOperand`] into [`Self::memory`] or [`Self::regs`].
|
||||
|
||||
@@ -277,18 +277,10 @@ impl Interpreter {
|
||||
.computer
|
||||
.regs
|
||||
.write(reg, self.computer.regs.read(reg) + 1),
|
||||
Mnemonic::INC_Mod(target) => match target {
|
||||
ModRmTarget::Memory(idx) => {
|
||||
let val = self.computer.memory.read(&mut self.computer.regs, idx);
|
||||
self.computer
|
||||
.memory
|
||||
.write(&mut self.computer.regs, idx, val + 1);
|
||||
}
|
||||
ModRmTarget::Register(reg) => self
|
||||
.computer
|
||||
.regs
|
||||
.write(reg, self.computer.regs.read(reg) + 1),
|
||||
},
|
||||
Mnemonic::INC_Mod(target) => {
|
||||
let val = self.computer.read_modrm(target);
|
||||
self.computer.write_modrm(target, val + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* DEC
|
||||
@@ -297,18 +289,10 @@ impl Interpreter {
|
||||
.computer
|
||||
.regs
|
||||
.write(reg, self.computer.regs.read(reg) - 1),
|
||||
Mnemonic::DEC_Mod(target) => match target {
|
||||
ModRmTarget::Memory(idx) => {
|
||||
let val = self.computer.memory.read(&mut self.computer.regs, idx);
|
||||
self.computer
|
||||
.memory
|
||||
.write(&mut self.computer.regs, idx, val - 1);
|
||||
}
|
||||
ModRmTarget::Register(reg) => self
|
||||
.computer
|
||||
.regs
|
||||
.write(reg, self.computer.regs.read(reg) - 1),
|
||||
},
|
||||
Mnemonic::DEC_Mod(target) => {
|
||||
let val = self.computer.read_modrm(target);
|
||||
self.computer.write_modrm(target, val - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Conditional short jumps
|
||||
|
||||
Reference in New Issue
Block a user