ft(interpreter): impl shift and rotate
This commit is contained in:
@@ -7,7 +7,7 @@ use crate::register::SegmentRegister;
|
||||
|
||||
use crate::{disasm::DisasmError, register::Register};
|
||||
use core::fmt;
|
||||
use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Sub};
|
||||
use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Shl, Shr, Sub};
|
||||
|
||||
pub type Byte = u8; // b
|
||||
pub type IByte = i8; // used for displacements of memory access
|
||||
@@ -28,6 +28,14 @@ pub enum ImmediateOperand {
|
||||
}
|
||||
|
||||
impl ImmediateOperand {
|
||||
/// Return bits of internal value.
|
||||
pub fn bits(self) -> Vec<bool> {
|
||||
match self {
|
||||
ImmediateOperand::Byte(b) => (0..8).map(|i| (b & (1 << i)) != 0).collect(),
|
||||
ImmediateOperand::Word(w) => (0..8).map(|i| (w & (1 << i)) != 0).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sign-extend [`Self::Byte`] into [`Self::Word`].
|
||||
/// Returns [`Self::Word`], if already a word.
|
||||
pub fn sign_extend(self) -> Self {
|
||||
@@ -98,6 +106,26 @@ impl ImmediateOperand {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<bool>> for ImmediateOperand {
|
||||
fn from(bits: Vec<bool>) -> Self {
|
||||
if bits.len() == 8 {
|
||||
let val = bits
|
||||
.iter()
|
||||
.enumerate()
|
||||
.fold(0, |acc, (i, &bit)| acc | ((bit as u8) << i));
|
||||
Self::Byte(val)
|
||||
} else if bits.len() == 16 {
|
||||
let val = bits
|
||||
.iter()
|
||||
.enumerate()
|
||||
.fold(0, |acc, (i, &bit)| acc | ((bit as u16) << i));
|
||||
Self::Word(val)
|
||||
} else {
|
||||
panic!("Invalid bit length");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Byte> for ImmediateOperand {
|
||||
fn from(value: Byte) -> Self {
|
||||
Self::Byte(value)
|
||||
@@ -252,6 +280,62 @@ impl Mul for ImmediateOperand {
|
||||
}
|
||||
}
|
||||
|
||||
impl Shl for ImmediateOperand {
|
||||
type Output = Self;
|
||||
|
||||
fn shl(self, rhs: Self) -> Self::Output {
|
||||
match self {
|
||||
Self::Byte(b) => match rhs {
|
||||
ImmediateOperand::Byte(sb) => Self::Byte(b << sb),
|
||||
ImmediateOperand::Word(sw) => Self::Byte(b << sw),
|
||||
},
|
||||
Self::Word(w) => match rhs {
|
||||
ImmediateOperand::Byte(sb) => Self::Word(w << sb),
|
||||
ImmediateOperand::Word(sw) => Self::Word(w << sw),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Shl<u8> for ImmediateOperand {
|
||||
type Output = Self;
|
||||
|
||||
fn shl(self, rhs: u8) -> Self::Output {
|
||||
match self {
|
||||
Self::Byte(b) => Self::Byte(b << rhs),
|
||||
Self::Word(w) => Self::Word(w << rhs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Shr for ImmediateOperand {
|
||||
type Output = Self;
|
||||
|
||||
fn shr(self, rhs: Self) -> Self::Output {
|
||||
match self {
|
||||
Self::Byte(b) => match rhs {
|
||||
ImmediateOperand::Byte(sb) => Self::Byte(b >> sb),
|
||||
ImmediateOperand::Word(sw) => Self::Byte(b >> sw),
|
||||
},
|
||||
Self::Word(w) => match rhs {
|
||||
ImmediateOperand::Byte(sb) => Self::Word(w >> sb),
|
||||
ImmediateOperand::Word(sw) => Self::Word(w >> sw),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Shr<u8> for ImmediateOperand {
|
||||
type Output = Self;
|
||||
|
||||
fn shr(self, rhs: u8) -> Self::Output {
|
||||
match self {
|
||||
Self::Byte(b) => Self::Byte(b >> rhs),
|
||||
Self::Word(w) => Self::Word(w >> rhs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Div for ImmediateOperand {
|
||||
type Output = Self;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user