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, "]")?;