[codegen] Add a pinned register that's entirely under the control of the user;

This commit is contained in:
Benjamin Bouvier
2019-08-28 17:33:45 +02:00
parent d1d2e790b9
commit 660b8b28b8
15 changed files with 229 additions and 30 deletions

View File

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

View File

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

View File

@@ -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")]