chore(interpreter): reduce code complexity
This commit is contained in:
@@ -163,103 +163,17 @@ impl Computer {
|
|||||||
O: Fn(Lhs, Rhs) -> ArithmeticResult,
|
O: Fn(Lhs, Rhs) -> ArithmeticResult,
|
||||||
F: Fn(&mut Flags, ArithmeticResult, Lhs, Rhs),
|
F: Fn(&mut Flags, ArithmeticResult, Lhs, Rhs),
|
||||||
{
|
{
|
||||||
match src {
|
let lhs = self.read_modrm(dest);
|
||||||
Operand::ModRmTarget(src_target) => {
|
let rhs = match src {
|
||||||
self.op_modrm(op, flag_set, write, dest, src_target)
|
Operand::Immediate(imm) => imm,
|
||||||
}
|
Operand::ModRmTarget(target) => self.read_modrm(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);
|
let result = op(lhs, rhs);
|
||||||
if write {
|
if write {
|
||||||
self.memory.write(&self.regs, dest_memory_idx, result);
|
self.write_modrm(dest, result);
|
||||||
}
|
}
|
||||||
flag_set(&mut self.flags, result, lhs, rhs);
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Write an [`ImmediateOperand`] into [`Self::memory`] or [`Self::regs`].
|
/// Write an [`ImmediateOperand`] into [`Self::memory`] or [`Self::regs`].
|
||||||
pub fn write_modrm(&mut self, target: ModRmTarget, val: ImmediateOperand) {
|
pub fn write_modrm(&mut self, target: ModRmTarget, val: ImmediateOperand) {
|
||||||
|
|||||||
@@ -277,18 +277,10 @@ impl Interpreter {
|
|||||||
.computer
|
.computer
|
||||||
.regs
|
.regs
|
||||||
.write(reg, self.computer.regs.read(reg) + 1),
|
.write(reg, self.computer.regs.read(reg) + 1),
|
||||||
Mnemonic::INC_Mod(target) => match target {
|
Mnemonic::INC_Mod(target) => {
|
||||||
ModRmTarget::Memory(idx) => {
|
let val = self.computer.read_modrm(target);
|
||||||
let val = self.computer.memory.read(&mut self.computer.regs, idx);
|
self.computer.write_modrm(target, val + 1);
|
||||||
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),
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DEC
|
* DEC
|
||||||
@@ -297,18 +289,10 @@ impl Interpreter {
|
|||||||
.computer
|
.computer
|
||||||
.regs
|
.regs
|
||||||
.write(reg, self.computer.regs.read(reg) - 1),
|
.write(reg, self.computer.regs.read(reg) - 1),
|
||||||
Mnemonic::DEC_Mod(target) => match target {
|
Mnemonic::DEC_Mod(target) => {
|
||||||
ModRmTarget::Memory(idx) => {
|
let val = self.computer.read_modrm(target);
|
||||||
let val = self.computer.memory.read(&mut self.computer.regs, idx);
|
self.computer.write_modrm(target, val - 1);
|
||||||
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),
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Conditional short jumps
|
* Conditional short jumps
|
||||||
|
|||||||
Reference in New Issue
Block a user