use super::error::AsmError; pub mod literal; pub mod reg; pub mod mask; pub use reg::Register; pub use mask::Mask; use literal::Addr; use std::convert::TryFrom; use crate::data::literal::{Value, as_signed}; use std::fmt::{Debug, Formatter, Display}; use std::fmt; /// Data source disposition #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum DataDisp { /// Constant value Immediate(Value), /// Constant memory address ImmediatePtr(Addr), /// Register Register(Register), /// Pointer into memory, stored in a numbered register RegisterPtr(Register), } impl Display for DataDisp { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { DataDisp::Immediate(v) => { write!(f, "{}", as_signed(*v)) } DataDisp::ImmediatePtr(a) => { write!(f, "@0x{:#18x}", a.0) } DataDisp::Register(r) => { write!(f, "{}", r) } DataDisp::RegisterPtr(r) => { write!(f, "@{}", r) } } } } impl From for DataDisp { fn from(s: SrcDisp) -> Self { match s { SrcDisp::Immediate(x) => DataDisp::Immediate(x), SrcDisp::ImmediatePtr(x) => DataDisp::ImmediatePtr(x), SrcDisp::Register(x) => DataDisp::Register(x), SrcDisp::RegisterPtr(x) => DataDisp::RegisterPtr(x), } } } impl From for DataDisp { fn from(s: DstDisp) -> Self { match s { DstDisp::ImmediatePtr(x) => DataDisp::ImmediatePtr(x), DstDisp::Register(x) => DataDisp::Register(x), DstDisp::RegisterPtr(x) => DataDisp::RegisterPtr(x), DstDisp::Discard => DataDisp::Immediate(0), } } } /// Data source disposition #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum SrcDisp { /// Constant value Immediate(Value), /// Constant memory address ImmediatePtr(Addr), /// Register Register(Register), /// Pointer into memory, stored in a numbered register RegisterPtr(Register), } impl TryFrom for SrcDisp { type Error = AsmError; fn try_from(value: DataDisp) -> Result { match value { DataDisp::Immediate(x) => Ok(SrcDisp::Immediate(x)), DataDisp::ImmediatePtr(x) => Ok(SrcDisp::ImmediatePtr(x)), DataDisp::Register(x) => Ok(SrcDisp::Register(x)), DataDisp::RegisterPtr(x) => Ok(SrcDisp::RegisterPtr(x)), } } } /// Data destination disposition #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum DstDisp { /// Constant memory address ImmediatePtr(Addr), /// Register Register(Register), /// Pointer into memory, stored in a numbered register RegisterPtr(Register), /// Discard the written value Discard, } impl From for SrcDisp { fn from(s: DstDisp) -> Self { match s { DstDisp::ImmediatePtr(x) => SrcDisp::ImmediatePtr(x), DstDisp::Register(x) => SrcDisp::Register(x), DstDisp::RegisterPtr(x) => SrcDisp::RegisterPtr(x), DstDisp::Discard => SrcDisp::Immediate(0), } } } impl TryFrom for DstDisp { type Error = AsmError; fn try_from(value: DataDisp) -> Result { match value { DataDisp::Immediate(_x) => Err(AsmError::ValueAsOutput), DataDisp::ImmediatePtr(x) => Ok(DstDisp::ImmediatePtr(x)), DataDisp::Register(x) => Ok(DstDisp::Register(x)), DataDisp::RegisterPtr(x) => Ok(DstDisp::RegisterPtr(x)), } } } /// Data source argument (read-only) #[derive(Clone, Copy, Eq, PartialEq)] pub struct Rd(SrcDisp, Mask); impl Rd { pub fn new(src: SrcDisp) -> Self { Rd(src, Mask::default()) } pub fn d(self) -> SrcDisp { self.0 } pub fn mask(self) -> Mask { self.1 } pub fn immediate(val : Value) -> Rd { Rd(SrcDisp::Immediate(val), Mask::default()) } } /// Data destination argument (read-write) #[derive(Clone, Copy, Eq, PartialEq)] pub struct Wr(DstDisp, Mask); impl Wr { pub fn new(dst: DstDisp) -> Self { Wr(dst, Mask::default()) } pub fn d(self) -> DstDisp { self.0 } pub fn mask(self) -> Mask { self.1 } pub fn as_rd(&self) -> Rd { Rd(self.0.into(), self.1) } pub fn discard() -> Wr { Wr(DstDisp::Discard, Mask::default()) } } impl Debug for Rd { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "Rd(")?; let disp : DataDisp = self.0.into(); write!(f, "{}", disp)?; if !self.mask().is_default() { write!(f, ",{:?}", self.mask())?; } write!(f, ")") } } impl Debug for Wr { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "Wr(")?; let disp : DataDisp = self.0.into(); write!(f, "{}", disp)?; if !self.mask().is_default() { write!(f, ",{:?}", self.mask())?; } write!(f, ")") } }