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/crsn/src/asm/data/literal.rs

119 lines
2.4 KiB

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<u64> for Addr {
fn from(n: u64) -> Self {
Self(n)
}
}
impl From<usize> for Addr {
fn from(n: usize) -> Self {
Self(n as u64)
}
}
impl From<Addr> 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<String> 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<String> for RoutineName {
fn from(n: String) -> Self {
Self(n)
}
}