ft(interpreter): set flags for arithmatic operations
This commit is contained in:
@@ -47,28 +47,52 @@ impl Computer {
|
||||
/// Perform binary `dest` = `dest` - `src`. Sets flags.
|
||||
pub fn sub(&mut self, dest: ModRmTarget, src: Operand) {
|
||||
let op: fn(Lhs, Rhs) -> Result = |lhs, rhs| lhs - rhs;
|
||||
let flag_set: fn(&mut Flags, Result, Lhs, Rhs) = |_, _, _, _| ();
|
||||
let flag_set: fn(&mut Flags, Result, Lhs, Rhs) = |flags, result, lhs, rhs| {
|
||||
flags.cf = lhs < rhs;
|
||||
flags.of = lhs.msb() != rhs.msb() && lhs.msb() != result.msb();
|
||||
flags.zf = result.zero();
|
||||
flags.sf = result.msb();
|
||||
flags.pf = result.parity();
|
||||
};
|
||||
self.op(op, flag_set, true, dest, src);
|
||||
}
|
||||
|
||||
/// Perform binary `dest` = `dest` | `src`. Sets flags.
|
||||
pub fn or(&mut self, dest: ModRmTarget, src: Operand) {
|
||||
let op: fn(Lhs, Rhs) -> Result = |lhs, rhs| lhs | rhs;
|
||||
let flag_set: fn(&mut Flags, Result, Lhs, Rhs) = |_, _, _, _| ();
|
||||
let flag_set: fn(&mut Flags, Result, Lhs, Rhs) = |flags, result, _, _| {
|
||||
flags.cf = false;
|
||||
flags.of = false;
|
||||
flags.zf = result.zero();
|
||||
flags.sf = result.msb();
|
||||
flags.pf = result.parity();
|
||||
};
|
||||
self.op(op, flag_set, true, dest, src);
|
||||
}
|
||||
|
||||
/// Perform binary `dest` = `dest` & `src`. Sets flags.
|
||||
pub fn and(&mut self, dest: ModRmTarget, src: Operand) {
|
||||
let op: fn(Lhs, Rhs) -> Result = |lhs, rhs| lhs & rhs;
|
||||
let flag_set: fn(&mut Flags, Result, Lhs, Rhs) = |_, _, _, _| ();
|
||||
let flag_set: fn(&mut Flags, Result, Lhs, Rhs) = |flags, result, _, _rhs| {
|
||||
flags.cf = false;
|
||||
flags.of = false;
|
||||
flags.zf = result.zero();
|
||||
flags.sf = result.msb();
|
||||
flags.pf = result.parity();
|
||||
};
|
||||
self.op(op, flag_set, true, dest, src);
|
||||
}
|
||||
|
||||
/// Perform binary `dest` = `dest` ^ `src`. Sets flags.
|
||||
pub fn xor(&mut self, dest: ModRmTarget, src: Operand) {
|
||||
let op: fn(Lhs, Rhs) -> Result = |lhs, rhs| lhs ^ rhs;
|
||||
let flag_set: fn(&mut Flags, Result, Lhs, Rhs) = |_, _, _, _| ();
|
||||
let flag_set: fn(&mut Flags, Result, Lhs, Rhs) = |flags, result, _, _| {
|
||||
flags.cf = false;
|
||||
flags.of = false;
|
||||
flags.zf = result.zero();
|
||||
flags.sf = result.msb();
|
||||
flags.pf = result.parity();
|
||||
};
|
||||
self.op(op, flag_set, true, dest, src);
|
||||
}
|
||||
|
||||
@@ -76,7 +100,13 @@ impl Computer {
|
||||
/// saving the result and only setting [`Self::flags`].
|
||||
pub fn cmp(&mut self, dest: ModRmTarget, src: Operand) {
|
||||
let op: fn(Lhs, Rhs) -> Result = |lhs, rhs| lhs - rhs;
|
||||
let flag_set: fn(&mut Flags, Result, Lhs, Rhs) = |_, _, _, _| ();
|
||||
let flag_set: fn(&mut Flags, Result, Lhs, Rhs) = |flags, result, lhs, rhs| {
|
||||
flags.cf = lhs < rhs;
|
||||
flags.of = lhs.msb() != rhs.msb() && lhs.msb() != result.msb();
|
||||
flags.zf = result.zero();
|
||||
flags.sf = result.msb();
|
||||
flags.pf = result.parity();
|
||||
};
|
||||
self.op(op, flag_set, false, dest, src);
|
||||
}
|
||||
|
||||
@@ -196,5 +226,5 @@ impl fmt::Display for Computer {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
// use super::*;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user