xref: /wasmtime-44.0.1/winch/codegen/src/isa/reg.rs (revision 6a5a4f27)
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