diff --git a/lib/cretonne/src/ir/valueloc.rs b/lib/cretonne/src/ir/valueloc.rs index ea7dea39d9..db1ee2baf2 100644 --- a/lib/cretonne/src/ir/valueloc.rs +++ b/lib/cretonne/src/ir/valueloc.rs @@ -3,8 +3,9 @@ //! The register allocator assigns every SSA value to either a register or a stack slot. This //! assignment is represented by a `ValueLoc` object. -use isa::RegUnit; +use isa::{RegInfo, RegUnit}; use ir::StackSlot; +use std::fmt; /// Value location. #[derive(Copy, Clone, Debug)] @@ -23,6 +24,35 @@ impl Default for ValueLoc { } } +impl ValueLoc { + /// Return an object that can display this value location, using the register info from the + /// target ISA. + pub fn display<'a, R: Into>>(self, regs: R) -> DisplayValueLoc<'a> { + DisplayValueLoc(self, regs.into()) + } +} + +/// Displaying a `ValueLoc` correctly requires the associated `RegInfo` from the target ISA. +/// Without the register info, register units are simply show as numbers. +/// +/// The `DisplayValueLoc` type can display the contained `ValueLoc`. +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), + } + } +} + /// Function argument location. /// /// The ABI specifies how arguments are passed to a function, and where return values appear after @@ -56,3 +86,32 @@ impl Default for ArgumentLoc { ArgumentLoc::Unassigned } } + +impl ArgumentLoc { + /// Return an object that can display this argument location, using the register info from the + /// target ISA. + pub fn display<'a, R: Into>>(self, regs: R) -> DisplayArgumentLoc<'a> { + DisplayArgumentLoc(self, regs.into()) + } +} + +/// Displaying a `ArgumentLoc` correctly requires the associated `RegInfo` from the target ISA. +/// Without the register info, register units are simply show as numbers. +/// +/// The `DisplayArgumentLoc` type can display the contained `ArgumentLoc`. +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), + } + } +} diff --git a/lib/cretonne/src/write.rs b/lib/cretonne/src/write.rs index eca9909961..957f8a036d 100644 --- a/lib/cretonne/src/write.rs +++ b/lib/cretonne/src/write.rs @@ -4,7 +4,7 @@ //! equivalent textual representation. This textual representation can be read back by the //! `cretonne-reader` crate. -use ir::{Function, Ebb, Inst, Value, Type, ValueLoc}; +use ir::{Function, Ebb, Inst, Value, Type}; use isa::TargetIsa; use std::fmt::{Result, Error, Write}; use std::result; @@ -177,11 +177,7 @@ fn write_instruction(w: &mut Write, if !func.locations.is_empty() { let regs = isa.register_info(); for r in func.dfg.inst_results(inst) { - match func.locations[r] { - ValueLoc::Unassigned => write!(s, ",-")?, - ValueLoc::Reg(ru) => write!(s, ",{}", regs.display_regunit(ru))?, - ValueLoc::Stack(ss) => write!(s, ",{}", ss)?, - } + write!(s, ",{}", func.locations[r].display(®s))? } } write!(s, "]")?;