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