Croissant Runtime
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
crsn/asm/src/data/mod.rs

188 lines
4.7 KiB

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, is_negative, 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<SrcDisp> 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<DstDisp> 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),
}
}
}
/// 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<DataDisp> for SrcDisp {
type Error = AsmError;
fn try_from(value: DataDisp) -> Result<Self, Self::Error> {
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),
}
impl From<DstDisp> 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),
}
}
}
impl TryFrom<DataDisp> for DstDisp {
type Error = AsmError;
fn try_from(value: DataDisp) -> Result<Self, Self::Error> {
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
}
}
/// 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)
}
}
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, ")")
}
}