1747ad3c4Slazypassion //! Source locations. 2747ad3c4Slazypassion //! 3747ad3c4Slazypassion //! Cranelift tracks the original source location of each instruction, and preserves the source 4747ad3c4Slazypassion //! location when instructions are transformed. 5747ad3c4Slazypassion 6747ad3c4Slazypassion use core::fmt; 79e884b44SArtur Jamro #[cfg(feature = "enable-serde")] 8*9ec02f9dSChristopher Serr use serde_derive::{Deserialize, Serialize}; 9747ad3c4Slazypassion 10747ad3c4Slazypassion /// A source location. 11747ad3c4Slazypassion /// 12747ad3c4Slazypassion /// This is an opaque 32-bit number attached to each Cranelift IR instruction. Cranelift does not 13747ad3c4Slazypassion /// interpret source locations in any way, they are simply preserved from the input to the output. 14747ad3c4Slazypassion /// 15747ad3c4Slazypassion /// The default source location uses the all-ones bit pattern `!0`. It is used for instructions 16747ad3c4Slazypassion /// that can't be given a real source location. 172be12a51SChris Fallin #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 189e884b44SArtur Jamro #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] 19747ad3c4Slazypassion pub struct SourceLoc(u32); 20747ad3c4Slazypassion 21747ad3c4Slazypassion impl SourceLoc { 22747ad3c4Slazypassion /// Create a new source location with the given bits. new(bits: u32) -> Self23747ad3c4Slazypassion pub fn new(bits: u32) -> Self { 249f506692SPeter Huene Self(bits) 25747ad3c4Slazypassion } 26747ad3c4Slazypassion 27747ad3c4Slazypassion /// Is this the default source location? is_default(self) -> bool28747ad3c4Slazypassion pub fn is_default(self) -> bool { 29747ad3c4Slazypassion self == Default::default() 30747ad3c4Slazypassion } 31747ad3c4Slazypassion 32747ad3c4Slazypassion /// Read the bits of this source location. bits(self) -> u3233747ad3c4Slazypassion pub fn bits(self) -> u32 { 34747ad3c4Slazypassion self.0 35747ad3c4Slazypassion } 36747ad3c4Slazypassion } 37747ad3c4Slazypassion 38747ad3c4Slazypassion impl Default for SourceLoc { default() -> Self39747ad3c4Slazypassion fn default() -> Self { 409f506692SPeter Huene Self(!0) 41747ad3c4Slazypassion } 42747ad3c4Slazypassion } 43747ad3c4Slazypassion 44747ad3c4Slazypassion impl fmt::Display for SourceLoc { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result45747ad3c4Slazypassion fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 46747ad3c4Slazypassion if self.is_default() { 47747ad3c4Slazypassion write!(f, "@-") 48747ad3c4Slazypassion } else { 49747ad3c4Slazypassion write!(f, "@{:04x}", self.0) 50747ad3c4Slazypassion } 51747ad3c4Slazypassion } 52747ad3c4Slazypassion } 53747ad3c4Slazypassion 548a9b1a90SBenjamin Bouvier /// Source location relative to another base source location. 558a9b1a90SBenjamin Bouvier #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 568a9b1a90SBenjamin Bouvier #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] 578a9b1a90SBenjamin Bouvier pub struct RelSourceLoc(u32); 588a9b1a90SBenjamin Bouvier 598a9b1a90SBenjamin Bouvier impl RelSourceLoc { 608a9b1a90SBenjamin Bouvier /// Create a new relative source location with the given bits. new(bits: u32) -> Self618a9b1a90SBenjamin Bouvier pub fn new(bits: u32) -> Self { 628a9b1a90SBenjamin Bouvier Self(bits) 638a9b1a90SBenjamin Bouvier } 648a9b1a90SBenjamin Bouvier 658a9b1a90SBenjamin Bouvier /// Creates a new `RelSourceLoc` based on the given base and offset. from_base_offset(base: SourceLoc, offset: SourceLoc) -> Self668a9b1a90SBenjamin Bouvier pub fn from_base_offset(base: SourceLoc, offset: SourceLoc) -> Self { 678a9b1a90SBenjamin Bouvier if base.is_default() || offset.is_default() { 688a9b1a90SBenjamin Bouvier Self::default() 698a9b1a90SBenjamin Bouvier } else { 708a9b1a90SBenjamin Bouvier Self(offset.bits().wrapping_sub(base.bits())) 718a9b1a90SBenjamin Bouvier } 728a9b1a90SBenjamin Bouvier } 738a9b1a90SBenjamin Bouvier 748a9b1a90SBenjamin Bouvier /// Expands the relative source location into an absolute one, using the given base. expand(&self, base: SourceLoc) -> SourceLoc758a9b1a90SBenjamin Bouvier pub fn expand(&self, base: SourceLoc) -> SourceLoc { 768a9b1a90SBenjamin Bouvier if self.is_default() || base.is_default() { 778a9b1a90SBenjamin Bouvier Default::default() 788a9b1a90SBenjamin Bouvier } else { 798a9b1a90SBenjamin Bouvier SourceLoc::new(self.0.wrapping_add(base.bits())) 808a9b1a90SBenjamin Bouvier } 818a9b1a90SBenjamin Bouvier } 828a9b1a90SBenjamin Bouvier 838a9b1a90SBenjamin Bouvier /// Is this the default relative source location? is_default(self) -> bool848a9b1a90SBenjamin Bouvier pub fn is_default(self) -> bool { 858a9b1a90SBenjamin Bouvier self == Default::default() 868a9b1a90SBenjamin Bouvier } 878a9b1a90SBenjamin Bouvier } 888a9b1a90SBenjamin Bouvier 898a9b1a90SBenjamin Bouvier impl Default for RelSourceLoc { default() -> Self908a9b1a90SBenjamin Bouvier fn default() -> Self { 918a9b1a90SBenjamin Bouvier Self(!0) 928a9b1a90SBenjamin Bouvier } 938a9b1a90SBenjamin Bouvier } 948a9b1a90SBenjamin Bouvier 958a9b1a90SBenjamin Bouvier impl fmt::Display for RelSourceLoc { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result968a9b1a90SBenjamin Bouvier fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 978a9b1a90SBenjamin Bouvier if self.is_default() { 988a9b1a90SBenjamin Bouvier write!(f, "@-") 998a9b1a90SBenjamin Bouvier } else { 1008a9b1a90SBenjamin Bouvier write!(f, "@+{:04x}", self.0) 1018a9b1a90SBenjamin Bouvier } 1028a9b1a90SBenjamin Bouvier } 1038a9b1a90SBenjamin Bouvier } 1048a9b1a90SBenjamin Bouvier 105747ad3c4Slazypassion #[cfg(test)] 106747ad3c4Slazypassion mod tests { 107747ad3c4Slazypassion use crate::ir::SourceLoc; 10810e226f9Sbjorn3 use alloc::string::ToString; 109747ad3c4Slazypassion 110747ad3c4Slazypassion #[test] display()111747ad3c4Slazypassion fn display() { 112747ad3c4Slazypassion assert_eq!(SourceLoc::default().to_string(), "@-"); 113747ad3c4Slazypassion assert_eq!(SourceLoc::new(0).to_string(), "@0000"); 114747ad3c4Slazypassion assert_eq!(SourceLoc::new(16).to_string(), "@0010"); 115747ad3c4Slazypassion assert_eq!(SourceLoc::new(0xabcdef).to_string(), "@abcdef"); 116747ad3c4Slazypassion } 117747ad3c4Slazypassion } 118