use ir::StackSlot;
use isa::{RegInfo, RegUnit};
use std::fmt;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ValueLoc {
Unassigned,
Reg(RegUnit),
Stack(StackSlot),
}
impl Default for ValueLoc {
fn default() -> Self {
ValueLoc::Unassigned
}
}
impl ValueLoc {
pub fn is_assigned(self) -> bool {
match self {
ValueLoc::Unassigned => false,
_ => true,
}
}
pub fn unwrap_reg(self) -> RegUnit {
match self {
ValueLoc::Reg(ru) => ru,
_ => panic!("Expected register: {:?}", self),
}
}
pub fn unwrap_stack(self) -> StackSlot {
match self {
ValueLoc::Stack(ss) => ss,
_ => panic!("Expected stack slot: {:?}", self),
}
}
pub fn display<'a, R: Into<Option<&'a RegInfo>>>(self, regs: R) -> DisplayValueLoc<'a> {
DisplayValueLoc(self, regs.into())
}
}
pub struct DisplayValueLoc<'a>(ValueLoc, Option<&'a RegInfo>);
impl<'a> fmt::Display for DisplayValueLoc<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.0 {
ValueLoc::Unassigned => write!(f, "-"),
ValueLoc::Reg(ru) => match self.1 {
Some(regs) => write!(f, "{}", regs.display_regunit(ru)),
None => write!(f, "%{}", ru),
},
ValueLoc::Stack(ss) => write!(f, "{}", ss),
}
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum ArgumentLoc {
Unassigned,
Reg(RegUnit),
Stack(i32),
}
impl Default for ArgumentLoc {
fn default() -> Self {
ArgumentLoc::Unassigned
}
}
impl ArgumentLoc {
pub fn is_assigned(self) -> bool {
match self {
ArgumentLoc::Unassigned => false,
_ => true,
}
}
pub fn is_reg(self) -> bool {
match self {
ArgumentLoc::Reg(_) => true,
_ => false,
}
}
pub fn is_stack(self) -> bool {
match self {
ArgumentLoc::Stack(_) => true,
_ => false,
}
}
pub fn display<'a, R: Into<Option<&'a RegInfo>>>(self, regs: R) -> DisplayArgumentLoc<'a> {
DisplayArgumentLoc(self, regs.into())
}
}
pub struct DisplayArgumentLoc<'a>(ArgumentLoc, Option<&'a RegInfo>);
impl<'a> fmt::Display for DisplayArgumentLoc<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.0 {
ArgumentLoc::Unassigned => write!(f, "-"),
ArgumentLoc::Reg(ru) => match self.1 {
Some(regs) => write!(f, "{}", regs.display_regunit(ru)),
None => write!(f, "%{}", ru),
},
ArgumentLoc::Stack(offset) => write!(f, "{}", offset),
}
}
}