chore(interpreter): rename Operand -> ArithmeticOperand
This commit is contained in:
@@ -6,7 +6,7 @@ use super::{flags::Flags, interpreter::InterpreterError, memory::Memory, registe
|
||||
|
||||
/// Wrapper for easier argument passing of polymorph arithmetic operations.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Operand {
|
||||
pub enum ArithmeticOperand {
|
||||
Immediate(crate::operands::ImmediateOperand),
|
||||
ModRmTarget(ModRmTarget),
|
||||
}
|
||||
@@ -61,7 +61,7 @@ impl Computer {
|
||||
}
|
||||
|
||||
/// Perform binary `dest` = `dest` + `src`. Sets flags.
|
||||
pub fn add(&mut self, dest: ModRmTarget, src: Operand) {
|
||||
pub fn add(&mut self, dest: ModRmTarget, src: ArithmeticOperand) {
|
||||
let op: fn(Lhs, Rhs) -> ArithmeticResult = |lhs, rhs| lhs + rhs;
|
||||
let flag_set: fn(&mut Flags, ArithmeticResult, Lhs, Rhs) = |flags, result, lhs, rhs| {
|
||||
flags.cf = result < rhs;
|
||||
@@ -74,7 +74,7 @@ impl Computer {
|
||||
}
|
||||
|
||||
/// Perform binary `dest` = `dest` - `src`. Sets flags.
|
||||
pub fn sub(&mut self, dest: ModRmTarget, src: Operand) {
|
||||
pub fn sub(&mut self, dest: ModRmTarget, src: ArithmeticOperand) {
|
||||
let op: fn(Lhs, Rhs) -> ArithmeticResult = |lhs, rhs| lhs - rhs;
|
||||
let flag_set: fn(&mut Flags, ArithmeticResult, Lhs, Rhs) = |flags, result, lhs, rhs| {
|
||||
flags.cf = lhs < rhs;
|
||||
@@ -87,7 +87,7 @@ impl Computer {
|
||||
}
|
||||
|
||||
/// Perform binary `dest` = `dest` | `src`. Sets flags.
|
||||
pub fn or(&mut self, dest: ModRmTarget, src: Operand) {
|
||||
pub fn or(&mut self, dest: ModRmTarget, src: ArithmeticOperand) {
|
||||
let op: fn(Lhs, Rhs) -> ArithmeticResult = |lhs, rhs| lhs | rhs;
|
||||
let flag_set: fn(&mut Flags, ArithmeticResult, Lhs, Rhs) = |flags, result, _, _| {
|
||||
flags.cf = false;
|
||||
@@ -100,7 +100,7 @@ impl Computer {
|
||||
}
|
||||
|
||||
/// Perform binary `dest` = `dest` & `src`. Sets flags.
|
||||
pub fn and(&mut self, dest: ModRmTarget, src: Operand) {
|
||||
pub fn and(&mut self, dest: ModRmTarget, src: ArithmeticOperand) {
|
||||
let op: fn(Lhs, Rhs) -> ArithmeticResult = |lhs, rhs| lhs & rhs;
|
||||
let flag_set: fn(&mut Flags, ArithmeticResult, Lhs, Rhs) = |flags, result, _, _rhs| {
|
||||
flags.cf = false;
|
||||
@@ -113,7 +113,7 @@ impl Computer {
|
||||
}
|
||||
|
||||
/// Perform binary `dest` = `dest` ^ `src`. Sets flags.
|
||||
pub fn xor(&mut self, dest: ModRmTarget, src: Operand) {
|
||||
pub fn xor(&mut self, dest: ModRmTarget, src: ArithmeticOperand) {
|
||||
let op: fn(Lhs, Rhs) -> ArithmeticResult = |lhs, rhs| lhs ^ rhs;
|
||||
let flag_set: fn(&mut Flags, ArithmeticResult, Lhs, Rhs) = |flags, result, _, _| {
|
||||
flags.cf = false;
|
||||
@@ -127,7 +127,7 @@ impl Computer {
|
||||
|
||||
/// Perform compare operation, which acts like [`Self::sub()`], but without
|
||||
/// saving the result and only setting [`Self::flags`].
|
||||
pub fn cmp(&mut self, dest: ModRmTarget, src: Operand) {
|
||||
pub fn cmp(&mut self, dest: ModRmTarget, src: ArithmeticOperand) {
|
||||
let op: fn(Lhs, Rhs) -> ArithmeticResult = |lhs, rhs| lhs - rhs;
|
||||
let flag_set: fn(&mut Flags, ArithmeticResult, Lhs, Rhs) = |flags, result, lhs, rhs| {
|
||||
flags.cf = lhs < rhs;
|
||||
@@ -141,7 +141,7 @@ impl Computer {
|
||||
|
||||
/// Perform test operation, which acts like [`Self::and()`], but without
|
||||
/// saving the result and only setting [`Self::flags`].
|
||||
pub fn test(&mut self, dest: ModRmTarget, src: Operand) {
|
||||
pub fn test(&mut self, dest: ModRmTarget, src: ArithmeticOperand) {
|
||||
let op: fn(Lhs, Rhs) -> ArithmeticResult = |lhs, rhs| lhs & rhs;
|
||||
let flag_set: fn(&mut Flags, ArithmeticResult, Lhs, Rhs) = |flags, result, _, _| {
|
||||
flags.cf = false;
|
||||
@@ -154,15 +154,19 @@ impl Computer {
|
||||
}
|
||||
|
||||
/// Perform `dest` = `dest` + `src` + CF. Sets flags.
|
||||
pub fn adc(&mut self, dest: ModRmTarget, src: Operand) {
|
||||
pub fn adc(&mut self, dest: ModRmTarget, src: ArithmeticOperand) {
|
||||
let cf = self.flags.cf as u8;
|
||||
// cheating, by flattening into immediates, but this allows to easily add the opt. carry
|
||||
let src_with_carry = match src {
|
||||
Operand::Immediate(immediate_operand) => Operand::Immediate(immediate_operand + cf),
|
||||
Operand::ModRmTarget(mod_rm_target) => Operand::Immediate(match mod_rm_target {
|
||||
ModRmTarget::Memory(idx) => self.memory.read(&self.regs, idx) + cf,
|
||||
ModRmTarget::Register(reg) => self.regs.read(reg) + cf,
|
||||
}),
|
||||
ArithmeticOperand::Immediate(immediate_operand) => {
|
||||
ArithmeticOperand::Immediate(immediate_operand + cf)
|
||||
}
|
||||
ArithmeticOperand::ModRmTarget(mod_rm_target) => {
|
||||
ArithmeticOperand::Immediate(match mod_rm_target {
|
||||
ModRmTarget::Memory(idx) => self.memory.read(&self.regs, idx) + cf,
|
||||
ModRmTarget::Register(reg) => self.regs.read(reg) + cf,
|
||||
})
|
||||
}
|
||||
};
|
||||
let op: fn(Lhs, Rhs) -> ArithmeticResult = |lhs, rhs| lhs + rhs;
|
||||
let flag_set: fn(&mut Flags, ArithmeticResult, Lhs, Rhs) = |flags, result, lhs, rhs| {
|
||||
@@ -176,15 +180,19 @@ impl Computer {
|
||||
}
|
||||
|
||||
/// Perform `dest` = `dest` - (`src` + CF). Sets flags.
|
||||
pub fn sbb(&mut self, dest: ModRmTarget, src: Operand) {
|
||||
pub fn sbb(&mut self, dest: ModRmTarget, src: ArithmeticOperand) {
|
||||
let cf = self.flags.cf as u8;
|
||||
// cheating, by flattening into immediates, but this allows to easily add the opt. carry
|
||||
let src_with_carry = match src {
|
||||
Operand::Immediate(immediate_operand) => Operand::Immediate(immediate_operand + cf),
|
||||
Operand::ModRmTarget(mod_rm_target) => Operand::Immediate(match mod_rm_target {
|
||||
ModRmTarget::Memory(idx) => self.memory.read(&self.regs, idx) + cf,
|
||||
ModRmTarget::Register(reg) => self.regs.read(reg) + cf,
|
||||
}),
|
||||
ArithmeticOperand::Immediate(immediate_operand) => {
|
||||
ArithmeticOperand::Immediate(immediate_operand + cf)
|
||||
}
|
||||
ArithmeticOperand::ModRmTarget(mod_rm_target) => {
|
||||
ArithmeticOperand::Immediate(match mod_rm_target {
|
||||
ModRmTarget::Memory(idx) => self.memory.read(&self.regs, idx) + cf,
|
||||
ModRmTarget::Register(reg) => self.regs.read(reg) + cf,
|
||||
})
|
||||
}
|
||||
};
|
||||
let op: fn(Lhs, Rhs) -> ArithmeticResult = |lhs, rhs| lhs - rhs;
|
||||
let flag_set: fn(&mut Flags, ArithmeticResult, Lhs, Rhs) = |flags, result, lhs, rhs| {
|
||||
@@ -201,15 +209,21 @@ impl Computer {
|
||||
/// it to `dest`, if `write` is set, and sets flags, according to [`F`].
|
||||
/// A result can never be saved to an immediate Operand, so `dest` can only
|
||||
/// be a [`ModRmTarget`].
|
||||
fn op<O, F>(&mut self, op: O, flag_set: F, write: bool, dest: ModRmTarget, src: Operand)
|
||||
where
|
||||
fn op<O, F>(
|
||||
&mut self,
|
||||
op: O,
|
||||
flag_set: F,
|
||||
write: bool,
|
||||
dest: ModRmTarget,
|
||||
src: ArithmeticOperand,
|
||||
) where
|
||||
O: Fn(Lhs, Rhs) -> ArithmeticResult,
|
||||
F: Fn(&mut Flags, ArithmeticResult, Lhs, Rhs),
|
||||
{
|
||||
let lhs = self.read_modrm(dest);
|
||||
let rhs = match src {
|
||||
Operand::Immediate(imm) => imm,
|
||||
Operand::ModRmTarget(target) => self.read_modrm(target),
|
||||
ArithmeticOperand::Immediate(imm) => imm,
|
||||
ArithmeticOperand::ModRmTarget(target) => self.read_modrm(target),
|
||||
};
|
||||
let result = op(lhs, rhs);
|
||||
if write {
|
||||
|
||||
Reference in New Issue
Block a user