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 pub(crate) type WritableReg = cranelift_codegen::Writable<Reg>; 15 16 /// Mark a given register as writable. This macro constructs 17 /// a [`cranelift_codegen::Writable`]. 18 macro_rules! writable { 19 ($e:expr) => { 20 cranelift_codegen::Writable::from_reg($e) 21 }; 22 } 23 24 pub(crate) use writable; 25 26 impl Reg { 27 /// Create a register from its encoding and class. from(class: RegClass, enc: usize) -> Self28 pub fn from(class: RegClass, enc: usize) -> Self { 29 Self::new(PReg::new(enc, class)) 30 } 31 32 /// Create a new register from a physical register. new(raw: PReg) -> Self33 pub const fn new(raw: PReg) -> Self { 34 Reg(raw) 35 } 36 37 /// Create a new general purpose register from encoding. int(enc: usize) -> Self38 pub fn int(enc: usize) -> Self { 39 Self::new(PReg::new(enc, RegClass::Int)) 40 } 41 42 /// Create a new floating point register from encoding. float(enc: usize) -> Self43 pub fn float(enc: usize) -> Self { 44 Self::new(PReg::new(enc, RegClass::Float)) 45 } 46 47 /// Get the encoding of the underlying register. hw_enc(self) -> usize48 pub const fn hw_enc(self) -> usize { 49 self.0.hw_enc() 50 } 51 52 /// Get the physical register representation. inner(&self) -> PReg53 pub(super) fn inner(&self) -> PReg { 54 self.0 55 } 56 57 /// Get the register class. class(&self) -> RegClass58 pub fn class(&self) -> RegClass { 59 self.0.class() 60 } 61 62 /// Returns true if the registers is a general purpose 63 /// integer register. is_int(&self) -> bool64 pub fn is_int(&self) -> bool { 65 self.class() == RegClass::Int 66 } 67 68 /// Returns true if the registers is a float register. is_float(&self) -> bool69 pub fn is_float(&self) -> bool { 70 self.class() == RegClass::Float 71 } 72 } 73 74 impl From<Reg> for cranelift_codegen::Reg { from(reg: Reg) -> Self75 fn from(reg: Reg) -> Self { 76 reg.inner().into() 77 } 78 } 79 80 impl std::fmt::Debug for Reg { fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result81 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 82 write!(f, "{}", self.0) 83 } 84 } 85