[codegen] Add a pinned register that's entirely under the control of the user;
This commit is contained in:
@@ -154,6 +154,12 @@ pub struct RegClassData {
|
||||
|
||||
/// The global `RegInfo` instance containing this register class.
|
||||
pub info: &'static RegInfo,
|
||||
|
||||
/// The "pinned" register of the associated register bank.
|
||||
///
|
||||
/// This register must be non-volatile (callee-preserved) and must not be the fixed
|
||||
/// output register of any instruction.
|
||||
pub pinned_reg: Option<RegUnit>,
|
||||
}
|
||||
|
||||
impl RegClassData {
|
||||
@@ -201,6 +207,15 @@ impl RegClassData {
|
||||
pub fn contains(&self, regunit: RegUnit) -> bool {
|
||||
self.mask[(regunit / 32) as usize] & (1u32 << (regunit % 32)) != 0
|
||||
}
|
||||
|
||||
/// If the pinned register is used, is the given regunit the pinned register of this class?
|
||||
#[inline]
|
||||
pub fn is_pinned_reg(&self, enabled: bool, regunit: RegUnit) -> bool {
|
||||
enabled
|
||||
&& self
|
||||
.pinned_reg
|
||||
.map_or(false, |pinned_reg| pinned_reg == regunit)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RegClassData {
|
||||
|
||||
@@ -89,9 +89,8 @@ impl ArgAssigner for Args {
|
||||
let reg = FPR.unit(self.fpr_used);
|
||||
self.fpr_used += 1;
|
||||
return ArgumentLoc::Reg(reg).into();
|
||||
} else {
|
||||
return ValueConversion::VectorSplit.into();
|
||||
}
|
||||
return ValueConversion::VectorSplit.into();
|
||||
}
|
||||
|
||||
// Large integers and booleans are broken down to fit in a register.
|
||||
@@ -229,7 +228,7 @@ pub fn regclass_for_abi_type(ty: ir::Type) -> RegClass {
|
||||
}
|
||||
|
||||
/// Get the set of allocatable registers for `func`.
|
||||
pub fn allocatable_registers(_func: &ir::Function, triple: &Triple) -> RegisterSet {
|
||||
pub fn allocatable_registers(triple: &Triple, flags: &shared_settings::Flags) -> RegisterSet {
|
||||
let mut regs = RegisterSet::new();
|
||||
regs.take(GPR, RU::rsp as RegUnit);
|
||||
regs.take(GPR, RU::rbp as RegUnit);
|
||||
@@ -240,6 +239,15 @@ pub fn allocatable_registers(_func: &ir::Function, triple: &Triple) -> RegisterS
|
||||
regs.take(GPR, GPR.unit(i));
|
||||
regs.take(FPR, FPR.unit(i));
|
||||
}
|
||||
if flags.enable_pinned_reg() {
|
||||
unimplemented!("Pinned register not implemented on x86-32.");
|
||||
}
|
||||
} else {
|
||||
// Choose r15 as the pinned register on 64-bits: it is non-volatile on native ABIs and
|
||||
// isn't the fixed output register of any instruction.
|
||||
if flags.enable_pinned_reg() {
|
||||
regs.take(GPR, RU::r15 as RegUnit);
|
||||
}
|
||||
}
|
||||
|
||||
regs
|
||||
|
||||
@@ -119,8 +119,8 @@ impl TargetIsa for Isa {
|
||||
abi::regclass_for_abi_type(ty)
|
||||
}
|
||||
|
||||
fn allocatable_registers(&self, func: &ir::Function) -> regalloc::RegisterSet {
|
||||
abi::allocatable_registers(func, &self.triple)
|
||||
fn allocatable_registers(&self, _func: &ir::Function) -> regalloc::RegisterSet {
|
||||
abi::allocatable_registers(&self.triple, &self.shared_flags)
|
||||
}
|
||||
|
||||
#[cfg(feature = "testing_hooks")]
|
||||
|
||||
Reference in New Issue
Block a user