use crate::reification::ReifiedRegister;
#[derive(Clone, Debug)]
pub struct Variable<R> {
pub(crate) label: String,
pub(crate) registers: Vec<R>,
}
#[derive(Debug, PartialEq)]
pub struct Instruction<R> {
pub(crate) opcode: String,
pub(crate) results: Vec<ReifiedRegister<R>>,
pub(crate) operands: Vec<ReifiedRegister<R>>,
pub(crate) modifiers: Modifier,
}
#[derive(Debug, PartialEq)]
pub(crate) enum Modifier {
None,
Imm(u64),
ImmLsl(u16, u8),
Lsl(u8),
Cond(String),
}
impl<R: std::fmt::Display> std::fmt::Display for Instruction<R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let regs: String = self
.extract_registers()
.map(|x| x.to_string())
.collect::<Vec<_>>()
.join(", ");
let extra = match &self.modifiers {
Modifier::None => String::new(),
Modifier::Imm(imm) => format!(", #{imm}"),
Modifier::Cond(cond) => format!(", {cond}"),
Modifier::ImmLsl(imm, shift) => format!(", #{imm}, lsl {shift}"),
Modifier::Lsl(imm) => format!(", #{imm}"),
};
let inst = &self.opcode;
write!(f, "{inst} {regs}{extra}")
}
}
impl<R> Instruction<R> {
pub(crate) fn extract_registers(&self) -> impl Iterator<Item = &ReifiedRegister<R>> {
self.results.iter().chain(&self.operands)
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct FreshRegister(pub(crate) u64);
impl std::fmt::Display for FreshRegister {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl From<u64> for FreshRegister {
fn from(value: u64) -> Self {
Self(value)
}
}
#[derive(PartialEq, Debug, Hash, Ord, PartialOrd, Eq, Clone, Copy)]
pub struct HardwareRegister(pub(crate) u64);
impl std::fmt::Display for HardwareRegister {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Clone, Copy, PartialEq, Debug, Eq, Ord, PartialOrd)]
pub enum TypedHardwareRegister {
General(HardwareRegister),
Vector(HardwareRegister),
}
impl TypedHardwareRegister {
pub(crate) fn reg(&self) -> HardwareRegister {
match self {
TypedHardwareRegister::General(reg) | TypedHardwareRegister::Vector(reg) => *reg,
}
}
}
impl std::fmt::Display for TypedHardwareRegister {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TypedHardwareRegister::General(reg) => write!(f, "x{}", reg.0),
TypedHardwareRegister::Vector(reg) => write!(f, "v{}", reg.0),
}
}
}