1 //! Pretty-printing for machine code (virtual-registerized or final).
2 
3 use regalloc::{RealRegUniverse, Reg, Writable};
4 
5 use std::fmt::Debug;
6 use std::hash::Hash;
7 use std::string::{String, ToString};
8 
9 // FIXME: Should this go into regalloc.rs instead?
10 
11 /// A trait for printing instruction bits and pieces, with the the ability to
12 /// take a contextualising RealRegUniverse that is used to give proper names to
13 /// registers.
14 pub trait ShowWithRRU {
15     /// Return a string that shows the implementing object in context of the
16     /// given `RealRegUniverse`, if provided.
show_rru(&self, mb_rru: Option<&RealRegUniverse>) -> String17     fn show_rru(&self, mb_rru: Option<&RealRegUniverse>) -> String;
18 
19     /// The same as |show_rru|, but with an optional hint giving a size in
20     /// bytes.  Its interpretation is object-dependent, and it is intended to
21     /// pass around enough information to facilitate printing sub-parts of
22     /// real registers correctly.  Objects may ignore size hints that are
23     /// irrelevant to them.
show_rru_sized(&self, mb_rru: Option<&RealRegUniverse>, _size: u8) -> String24     fn show_rru_sized(&self, mb_rru: Option<&RealRegUniverse>, _size: u8) -> String {
25         // Default implementation is to ignore the hint.
26         self.show_rru(mb_rru)
27     }
28 }
29 
30 impl ShowWithRRU for Reg {
show_rru(&self, mb_rru: Option<&RealRegUniverse>) -> String31     fn show_rru(&self, mb_rru: Option<&RealRegUniverse>) -> String {
32         if self.is_real() {
33             if let Some(rru) = mb_rru {
34                 let reg_ix = self.get_index();
35                 if reg_ix < rru.regs.len() {
36                     return rru.regs[reg_ix].1.to_string();
37                 } else {
38                     // We have a real reg which isn't listed in the universe.
39                     // Per the regalloc.rs interface requirements, this is
40                     // Totally Not Allowed.  Print it generically anyway, so
41                     // we have something to debug.
42                     return format!("!!{:?}!!", self);
43                 }
44             }
45         }
46         // The reg is virtual, or we have no universe.  Be generic.
47         format!("%{:?}", self)
48     }
49 
show_rru_sized(&self, _mb_rru: Option<&RealRegUniverse>, _size: u8) -> String50     fn show_rru_sized(&self, _mb_rru: Option<&RealRegUniverse>, _size: u8) -> String {
51         // For the specific case of Reg, we demand not to have a size hint,
52         // since interpretation of the size is target specific, but this code
53         // is used by all targets.
54         panic!("Reg::show_rru_sized: impossible to implement");
55     }
56 }
57 
58 impl<R: ShowWithRRU + Copy + Ord + Hash + Eq + Debug> ShowWithRRU for Writable<R> {
show_rru(&self, mb_rru: Option<&RealRegUniverse>) -> String59     fn show_rru(&self, mb_rru: Option<&RealRegUniverse>) -> String {
60         self.to_reg().show_rru(mb_rru)
61     }
62 
show_rru_sized(&self, mb_rru: Option<&RealRegUniverse>, size: u8) -> String63     fn show_rru_sized(&self, mb_rru: Option<&RealRegUniverse>, size: u8) -> String {
64         self.to_reg().show_rru_sized(mb_rru, size)
65     }
66 }
67