fix: dont always flip sign_extend msb
This commit is contained in:
@@ -140,3 +140,8 @@ impl fmt::Display for Computer {
|
|||||||
write!(f, "{} | {}", self.regs, self.flags)
|
write!(f, "{} | {}", self.regs, self.flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,14 +32,11 @@ impl ImmediateOperand {
|
|||||||
pub fn sign_extend(self) -> Self {
|
pub fn sign_extend(self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
Self::Byte(_) => {
|
Self::Byte(_) => {
|
||||||
let sign = self.msb();
|
return if self.msb() {
|
||||||
let byte = self.flip_sign();
|
self.flip_sign().as_word().flip_sign()
|
||||||
let word = byte.as_word();
|
|
||||||
if sign {
|
|
||||||
return word.flip_sign();
|
|
||||||
} else {
|
} else {
|
||||||
return word;
|
self.as_word()
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
Self::Word(_) => self,
|
Self::Word(_) => self,
|
||||||
}
|
}
|
||||||
@@ -391,6 +388,34 @@ impl std::fmt::Display for Pointer32 {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_byte_byte() {
|
||||||
|
let a = ImmediateOperand::Byte(5);
|
||||||
|
let b = ImmediateOperand::Byte(7);
|
||||||
|
assert_eq!(a + b, ImmediateOperand::Byte(5 + 7))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_word_word() {
|
||||||
|
let a = ImmediateOperand::Word(5);
|
||||||
|
let b = ImmediateOperand::Word(7);
|
||||||
|
assert_eq!(a + b, ImmediateOperand::Word(5 + 7))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_byte_word() {
|
||||||
|
let a = ImmediateOperand::Byte(5);
|
||||||
|
let b = ImmediateOperand::Word(7);
|
||||||
|
assert_eq!(b + a, ImmediateOperand::Word(5 + 7))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sub_byte_word() {
|
||||||
|
let a = ImmediateOperand::Byte(5);
|
||||||
|
let b = ImmediateOperand::Word(7);
|
||||||
|
assert_eq!(b - a, ImmediateOperand::Word(7 - 5))
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_msb() {
|
fn test_msb() {
|
||||||
let pos = ImmediateOperand::Byte(1 << 4);
|
let pos = ImmediateOperand::Byte(1 << 4);
|
||||||
@@ -431,6 +456,13 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_sign_extend() {
|
fn test_sign_extend() {
|
||||||
|
let byte = ImmediateOperand::Byte(0b01010101);
|
||||||
|
let word = ImmediateOperand::Word(0b0000000001010101);
|
||||||
|
assert_eq!(byte.sign_extend(), word);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sign_extend_neg() {
|
||||||
let byte = ImmediateOperand::Byte(1 << 7);
|
let byte = ImmediateOperand::Byte(1 << 7);
|
||||||
let word = ImmediateOperand::Word(1 << 15);
|
let word = ImmediateOperand::Word(1 << 15);
|
||||||
assert_eq!(byte.sign_extend(), word);
|
assert_eq!(byte.sign_extend(), word);
|
||||||
|
|||||||
Reference in New Issue
Block a user