1 use regalloc2::PReg; 2 pub use regalloc2::RegClass; 3 4 /// A newtype abstraction on top of a physical register. 5 // 6 // NOTE 7 // This is temporary; the intention behind this newtype 8 // is to keep the usage of PReg contained to this module 9 // so that the rest of Winch should only need to operate 10 // on top of the concept of `Reg`. 11 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 12 pub struct Reg(PReg); 13 14 impl Reg { 15 /// Create a register from its encoding and class. 16 pub fn from(class: RegClass, enc: usize) -> Self { 17 Self::new(PReg::new(enc, class)) 18 } 19 20 /// Create a new register from a physical register. 21 pub const fn new(raw: PReg) -> Self { 22 Reg(raw) 23 } 24 25 /// Create a new general purpose register from encoding. 26 pub fn int(enc: usize) -> Self { 27 Self::new(PReg::new(enc, RegClass::Int)) 28 } 29 30 /// Create a new floating point register from encoding. 31 #[allow(dead_code)] 32 pub fn float(enc: usize) -> Self { 33 Self::new(PReg::new(enc, RegClass::Float)) 34 } 35 36 /// Get the encoding of the underlying register. 37 pub const fn hw_enc(self) -> usize { 38 self.0.hw_enc() 39 } 40 41 /// Get the physical register representation. 42 pub(super) fn inner(&self) -> PReg { 43 self.0 44 } 45 46 /// Get the register class. 47 pub fn class(&self) -> RegClass { 48 self.0.class() 49 } 50 51 /// Returns true if the registers is a general purpose 52 /// integer register. 53 pub fn is_int(&self) -> bool { 54 self.class() == RegClass::Int 55 } 56 57 /// Returns true if the registers is a float register. 58 pub fn is_float(&self) -> bool { 59 self.class() == RegClass::Float 60 } 61 } 62 63 impl From<Reg> for cranelift_codegen::Reg { 64 fn from(reg: Reg) -> Self { 65 reg.inner().into() 66 } 67 } 68 69 impl std::fmt::Debug for Reg { 70 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 71 write!(f, "{}", self.0) 72 } 73 } 74