ft(interpreter): impl mul and div
This commit is contained in:
@@ -668,10 +668,42 @@ impl Interpreter {
|
|||||||
/*
|
/*
|
||||||
* MUL
|
* MUL
|
||||||
*/
|
*/
|
||||||
|
Mnemonic::MUL(target) => {
|
||||||
|
let src = self.computer.read_modrm(target)?;
|
||||||
|
let dest = self.computer.regs.ax.read();
|
||||||
|
let (ax, dx) = src.mul(dest.into());
|
||||||
|
self.computer.regs.ax.write(ax);
|
||||||
|
self.computer.regs.dx.write(dx);
|
||||||
|
self.computer.flags.of = if dx == 0 { false } else { true };
|
||||||
|
self.computer.flags.cf = if dx == 0 { false } else { true };
|
||||||
|
}
|
||||||
|
Mnemonic::IMUL(_) => todo!(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DIV
|
* DIV
|
||||||
*/
|
*/
|
||||||
|
Mnemonic::DIV(target) => {
|
||||||
|
// byte: Unsigned divide AX by r/m8, with result stored in AL ← Quotient, AH ← Remainder.
|
||||||
|
// word: Unsigned divide DX:AX by r/m16, with result stored in AX ← Quotient, DX ← Remainder.
|
||||||
|
let src = self.computer.read_modrm(target)?;
|
||||||
|
let ax = self.computer.regs.ax.read();
|
||||||
|
match src {
|
||||||
|
ImmediateOperand::Byte(b) => {
|
||||||
|
self.computer.regs.ax.lower = (ax / b as Word) as Byte;
|
||||||
|
self.computer.regs.ax.upper = (ax % b as Word) as Byte;
|
||||||
|
}
|
||||||
|
ImmediateOperand::Word(w) => {
|
||||||
|
let dx = self.computer.regs.dx.read();
|
||||||
|
let num: u32 = ((dx as u32) << 16) | (ax as u32);
|
||||||
|
let quot: u16 = (num / w as u32) as Word;
|
||||||
|
let rem: u16 = (num % w as u32) as Word;
|
||||||
|
|
||||||
|
self.computer.regs.ax.write(quot);
|
||||||
|
self.computer.regs.dx.write(rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Mnemonic::IDIV(_) => todo!(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HLT
|
* HLT
|
||||||
|
|||||||
@@ -107,6 +107,32 @@ impl ImmediateOperand {
|
|||||||
Self::Word(word) => return (word >> 15) == 1,
|
Self::Word(word) => return (word >> 15) == 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Multiply values and return the extended u32, split into two words.
|
||||||
|
pub fn mul(&self, other: Self) -> (Word, Word) {
|
||||||
|
let result: u32 = match self {
|
||||||
|
Self::Byte(lhsb) => match other {
|
||||||
|
Self::Byte(rhsb) => *lhsb as u32 * rhsb as u32,
|
||||||
|
Self::Word(rhsw) => match other.sign_extend() {
|
||||||
|
Self::Word(lhsw) => lhsw as u32 * rhsw as u32,
|
||||||
|
_ => panic!("unreachable"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Self::Word(lhsw) => match other {
|
||||||
|
Self::Word(rhsw) => *lhsw as u32 * rhsw as u32,
|
||||||
|
Self::Byte(_) => match other.sign_extend() {
|
||||||
|
Self::Word(rhsw) => *lhsw as u32 * rhsw as u32,
|
||||||
|
_ => panic!("unreachable"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let bytes = result.to_le_bytes();
|
||||||
|
let lower = Word::from_le_bytes([bytes[0], bytes[1]]);
|
||||||
|
let upper = Word::from_le_bytes([bytes[2], bytes[3]]);
|
||||||
|
|
||||||
|
(lower, upper)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd for ImmediateOperand {
|
impl PartialOrd for ImmediateOperand {
|
||||||
@@ -262,29 +288,6 @@ impl Sub<Byte> for ImmediateOperand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Mul for ImmediateOperand {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn mul(self, other: Self) -> Self {
|
|
||||||
match self {
|
|
||||||
ImmediateOperand::Byte(lhsb) => match other {
|
|
||||||
ImmediateOperand::Byte(rhsb) => ImmediateOperand::Byte(lhsb.wrapping_mul(rhsb)),
|
|
||||||
ImmediateOperand::Word(rhsw) => ImmediateOperand::Word(match other.sign_extend() {
|
|
||||||
ImmediateOperand::Word(lhsw) => lhsw.wrapping_mul(rhsw),
|
|
||||||
_ => panic!("unreachable"),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
ImmediateOperand::Word(lhsw) => match other {
|
|
||||||
ImmediateOperand::Word(rhsw) => ImmediateOperand::Word(lhsw.wrapping_mul(rhsw)),
|
|
||||||
ImmediateOperand::Byte(_) => ImmediateOperand::Word(match other.sign_extend() {
|
|
||||||
ImmediateOperand::Word(rhsw) => lhsw.wrapping_mul(rhsw),
|
|
||||||
_ => panic!("unreachable"),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Shl for ImmediateOperand {
|
impl Shl for ImmediateOperand {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user