Add fixed-non-allocatable operand support (#77)
This allows a non-allocatable `PReg` to be passed on directly to the allocations vector without any liverange tracking from the register allocator. The main intended use case is to support ISA-specific special registers such as a fixed zero register.
This commit is contained in:
24
src/lib.rs
24
src/lib.rs
@@ -677,6 +677,19 @@ impl Operand {
|
||||
)
|
||||
}
|
||||
|
||||
/// Create an `Operand` that always results in an assignment to the
|
||||
/// given fixed `preg`, *without* tracking liveranges in that
|
||||
/// `preg`. Must only be used for non-allocatable registers.
|
||||
#[inline(always)]
|
||||
pub fn fixed_nonallocatable(preg: PReg) -> Self {
|
||||
Operand::new(
|
||||
VReg::new(VReg::MAX, preg.class()),
|
||||
OperandConstraint::FixedReg(preg),
|
||||
OperandKind::Use,
|
||||
OperandPos::Early,
|
||||
)
|
||||
}
|
||||
|
||||
/// Get the virtual register designated by an operand. Every
|
||||
/// operand must name some virtual register, even if it constrains
|
||||
/// the operand to a fixed physical register as well; the vregs
|
||||
@@ -744,6 +757,17 @@ impl Operand {
|
||||
}
|
||||
}
|
||||
|
||||
/// If this operand is for a fixed non-allocatable register (see
|
||||
/// [`Operand::fixed`]), then returns the physical register that it will
|
||||
/// be assigned to.
|
||||
#[inline(always)]
|
||||
pub fn as_fixed_nonallocatable(self) -> Option<PReg> {
|
||||
match self.constraint() {
|
||||
OperandConstraint::FixedReg(preg) if self.vreg().vreg() == VReg::MAX => Some(preg),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the raw 32-bit encoding of this operand's fields.
|
||||
#[inline(always)]
|
||||
pub fn bits(self) -> u32 {
|
||||
|
||||
Reference in New Issue
Block a user