use std::fmt::{Debug, Display, Formatter}; use std::fmt; use crate::asm::data::{RdData, Register}; use crate::asm::data::literal::Value; use crate::runtime::run_thread::RunState; use crate::runtime::fault::Fault; /// Data source argument (read-only) #[derive(Clone, Copy, Eq, PartialEq)] pub struct Rd(pub RdData); impl Rd { pub const fn new(src: RdData) -> Self { Rd(src) } pub const fn immediate(val: Value) -> Rd { Rd(RdData::Immediate(val)) } pub fn is_immediate_equal(self, other: Value) -> bool { match self.0 { RdData::Immediate(val) => { val == other } _ => false } } } impl From<&Rd> for Rd { fn from(a: &Rd) -> Self { *a } } impl Display for Rd { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) // TODO mask, when implemented } } impl Debug for Rd { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "Rd({})", self.0) } } /// Reference an object through a handle #[derive(Clone, Copy, Eq, PartialEq)] pub enum RdObj { Reg(Register), Imm(Value), } impl RdObj { pub const fn from_reg(reg: Register) -> Self { RdObj::Reg(reg) } pub const fn from_value(value: Value) -> Self { RdObj::Imm(value) } pub fn read(self, state: &mut RunState) -> Result { Ok(match self { RdObj::Reg(r) => state.read(Rd::new(RdData::Register(r)))?, RdObj::Imm(v) => v, }) } } impl From<&RdObj> for RdObj { fn from(a: &RdObj) -> Self { *a } } impl Display for RdObj { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { RdObj::Reg(r) => write!(f, "@{}", r), RdObj::Imm(v) => write!(f, "@{:#x}", v) } } } impl Debug for RdObj { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { RdObj::Reg(r) => write!(f, "Obj({})", r), RdObj::Imm(v) => write!(f, "Obj({:#x})", v) } } }