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:
Amanieu d'Antras
2022-09-20 03:23:53 +08:00
committed by GitHub
parent aeef47a06b
commit 1495c1e342
6 changed files with 67 additions and 13 deletions

View File

@@ -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 {