winch_codegen/isa/
reg.rs

1use regalloc2::PReg;
2pub 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)]
12pub struct Reg(PReg);
13
14pub(crate) type WritableReg = cranelift_codegen::Writable<Reg>;
15
16/// Mark a given register as writable. This macro constructs
17/// a [`cranelift_codegen::Writable`].
18macro_rules! writable {
19    ($e:expr) => {
20        cranelift_codegen::Writable::from_reg($e)
21    };
22}
23
24pub(crate) use writable;
25
26impl Reg {
27    /// Create a register from its encoding and class.
28    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.
33    pub const fn new(raw: PReg) -> Self {
34        Reg(raw)
35    }
36
37    /// Create a new general purpose register from encoding.
38    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.
43    pub fn float(enc: usize) -> Self {
44        Self::new(PReg::new(enc, RegClass::Float))
45    }
46
47    /// Get the encoding of the underlying register.
48    pub const fn hw_enc(self) -> usize {
49        self.0.hw_enc()
50    }
51
52    /// Get the physical register representation.
53    pub(super) fn inner(&self) -> PReg {
54        self.0
55    }
56
57    /// Get the register class.
58    pub fn class(&self) -> RegClass {
59        self.0.class()
60    }
61
62    /// Returns true if the registers is a general purpose
63    /// integer register.
64    pub fn is_int(&self) -> bool {
65        self.class() == RegClass::Int
66    }
67
68    /// Returns true if the registers is a float register.
69    pub fn is_float(&self) -> bool {
70        self.class() == RegClass::Float
71    }
72}
73
74impl From<Reg> for cranelift_codegen::Reg {
75    fn from(reg: Reg) -> Self {
76        reg.inner().into()
77    }
78}
79
80impl std::fmt::Debug for Reg {
81    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
82        write!(f, "{}", self.0)
83    }
84}