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.
113 lines
2.5 KiB
113 lines
2.5 KiB
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 new_imm(val: Value) -> Rd {
|
|
Rd(RdData::Immediate(val))
|
|
}
|
|
|
|
/// Construct new from float
|
|
pub fn new_float(val: f64) -> Rd { // TODO const when stabilized
|
|
Rd(RdData::Immediate(val.to_bits()))
|
|
}
|
|
|
|
/// Convert immediate read to float
|
|
pub fn imm_to_float(self) -> Rd {
|
|
match self {
|
|
Rd(RdData::Immediate(v)) => {
|
|
let signed : i64 = unsafe { std::mem::transmute(v) };
|
|
Rd::new_float(signed as f64)
|
|
}
|
|
other => other
|
|
}
|
|
}
|
|
|
|
pub fn is_imm_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<Value, Fault> {
|
|
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)
|
|
}
|
|
}
|
|
}
|
|
|