chore(interpreter): reduce code complexity

This commit is contained in:
2025-06-11 17:04:34 +09:00
parent e5e0edd713
commit 7691b4b2ab
2 changed files with 17 additions and 119 deletions

View File

@@ -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`].

View File

@@ -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