fix: dont always flip sign_extend msb

This commit is contained in:
2025-06-10 20:00:07 +09:00
parent 3756ada3e0
commit 037d74ac6a
2 changed files with 44 additions and 7 deletions

View File

@@ -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::*;
}

View File

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