use crate::{
isa::reg::{Reg, RegClass},
regset::{RegBitSet, RegSet},
};
pub(crate) struct RegAlloc {
regset: RegSet,
}
impl RegAlloc {
pub fn from(gpr: RegBitSet, fpr: RegBitSet) -> Self {
let rs = RegSet::new(gpr, fpr);
Self { regset: rs }
}
pub fn reg_for_class<F>(&mut self, class: RegClass, spill: &mut F) -> Reg
where
F: FnMut(&mut RegAlloc),
{
self.regset.reg_for_class(class).unwrap_or_else(|| {
spill(self);
self.regset.reg_for_class(class).unwrap_or_else(|| {
panic!("expected register for class {:?}, to be available", class)
})
})
}
pub fn reg_available(&self, reg: Reg) -> bool {
self.regset.named_reg_available(reg)
}
pub fn reg<F>(&mut self, named: Reg, mut spill: F) -> Reg
where
F: FnMut(&mut RegAlloc),
{
self.regset.reg(named).unwrap_or_else(|| {
spill(self);
self.regset
.reg(named)
.unwrap_or_else(|| panic!("Expected register {:?} to be available", named))
})
}
pub fn free(&mut self, reg: Reg) {
self.regset.free(reg);
}
}