use std::borrow::Cow; use std::fmt::{self, Display, Formatter}; use std::sync::atomic::AtomicU32; pub type DebugMsg = Cow<'static, str>; /// Immediate value pub type Value = u64; pub fn is_positive(val: Value) -> bool { 0 == (val & 0x8000_0000_0000_0000) } pub fn is_negative(val: Value) -> bool { 0 != (val & 0x8000_0000_0000_0000) } pub fn as_signed(val: Value) -> i64 { i64::from_ne_bytes(val.to_ne_bytes()) } /// Immediate address #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] pub struct Addr(pub u64); impl Addr { pub fn advance(&mut self, add: i64) { if add < 0 { self.0 = self.0.wrapping_sub(-add as u64); } else { self.0 = self.0.wrapping_add(add as u64); } } } impl Display for Addr { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { if self.0 > 0x7fff_ffff_ffff_ffff { write!(f, "{}", i64::from_ne_bytes(self.0.to_ne_bytes())) } else { write!(f, "{}", self.0) } } } impl From for Addr { fn from(n: u64) -> Self { Self(n) } } impl From for Addr { fn from(n: usize) -> Self { Self(n as u64) } } impl From for u64 { fn from(addr: Addr) -> Self { addr.0 } } /// Label name #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub enum Label { Named(String), Numbered(u32), } impl Label { /// Generate a unique numbered label from a counter pub fn unique(counter: &AtomicU32) -> Self { Label::Numbered(counter.fetch_add(1, std::sync::atomic::Ordering::Relaxed)) } } impl Display for Label { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { Label::Named(name) => write!(f, ":{}", name), Label::Numbered(num) => write!(f, ":#{}", num), } } } impl From<&str> for Label { fn from(n: &str) -> Self { Self::Named(n.to_string()) } } impl From for Label { fn from(n: String) -> Self { Self::Named(n) } } /// Routine name #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct RoutineName(pub String); impl Display for RoutineName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) } } impl From<&str> for RoutineName { fn from(n: &str) -> Self { Self(n.to_string()) } } impl From for RoutineName { fn from(n: String) -> Self { Self(n) } }