chore(interpreter): always sign-extend ImmediateOperand::Byte when cast

This commit is contained in:
2025-06-11 17:40:38 +09:00
parent 7691b4b2ab
commit 4cea76bd1c

View File

@@ -16,11 +16,12 @@ pub type IWord = i16; // used for displacement of memory access
pub type DWord = u32; pub type DWord = u32;
#[derive(Debug, Clone, Ord, Eq, PartialEq, PartialOrd, Copy)] #[derive(Debug, Clone, Ord, Eq, PartialEq, PartialOrd, Copy)]
/// Encodes either Byte- or Word-sized immediate operands. /// Universal type to encode either Byte- or Word-sized immediate operands.
/// Also sometimes used to decide if an instruction is Byte- or Word-sized, /// Mostly used to:
/// which is usually indicated by using a value of 0 and the disregarding /// - Encode immediates, where instructions exist for both widths.
/// the value when read. /// - Encode instruction width, to select either the 8- or 16-bit register.
/// Can either be interpreted as signed or unsigned, depending on the context. /// - Encode raw immediate values, to make use of all implemented functions
/// of this type.
pub enum ImmediateOperand { pub enum ImmediateOperand {
Byte(Byte), Byte(Byte),
Word(Word), Word(Word),
@@ -44,7 +45,8 @@ impl ImmediateOperand {
/// Interprets [`Self::Byte`] as [`Self::Word`]. /// Interprets [`Self::Byte`] as [`Self::Word`].
/// Returns word, if already a [`Self::Word`]. /// Returns word, if already a [`Self::Word`].
pub fn as_word(self) -> Self { /// CAUTION: You probably want to use [`Self::sign_extend()`] instead.
fn as_word(self) -> Self {
match self { match self {
Self::Byte(b) => Self::Word(b as Word), Self::Byte(b) => Self::Word(b as Word),
Self::Word(_) => self, Self::Word(_) => self,
@@ -87,6 +89,7 @@ impl ImmediateOperand {
} }
/// Check if most significant bit is set. /// Check if most significant bit is set.
/// If the number is interpreted as signed, this acts as the sign bit.
pub fn msb(&self) -> bool { pub fn msb(&self) -> bool {
match self { match self {
Self::Byte(byte) => return (byte >> 7) == 1, Self::Byte(byte) => return (byte >> 7) == 1,
@@ -107,6 +110,15 @@ impl From<Word> for ImmediateOperand {
} }
} }
impl Into<Word> for ImmediateOperand {
fn into(self) -> u16 {
match self {
ImmediateOperand::Byte(_) => self.sign_extend().into(),
ImmediateOperand::Word(w) => w,
}
}
}
impl Into<usize> for ImmediateOperand { impl Into<usize> for ImmediateOperand {
fn into(self) -> usize { fn into(self) -> usize {
match self { match self {