use crate::{isa::reg::Reg, regset::RegSet};
pub(crate) struct RegAlloc {
pub scratch: Reg,
regset: RegSet,
}
impl RegAlloc {
pub fn new(regset: RegSet, scratch: Reg) -> Self {
Self { regset, scratch }
}
pub fn any_gpr<F>(&mut self, spill: &mut F) -> Reg
where
F: FnMut(&mut RegAlloc),
{
self.regset.any_gpr().unwrap_or_else(|| {
spill(self);
self.regset.any_gpr().expect("any gpr to be available")
})
}
pub fn gpr_available(&self, reg: Reg) -> bool {
self.regset.named_gpr_available(reg.hw_enc() as u32)
}
pub fn gpr<F>(&mut self, named: Reg, spill: &mut F) -> Reg
where
F: FnMut(&mut RegAlloc),
{
if named == self.scratch {
return named;
}
self.regset.gpr(named).unwrap_or_else(|| {
spill(self);
self.regset
.gpr(named)
.expect(&format!("gpr {:?} to be available", named))
})
}
pub fn free_gpr(&mut self, reg: Reg) {
if reg != self.scratch {
self.regset.free_gpr(reg);
}
}
}