Add a few register utilities.

This commit is contained in:
Jakob Stoklund Olesen
2017-05-02 09:59:58 -07:00
parent aaa70a677d
commit f8a3a01f96
3 changed files with 51 additions and 1 deletions

View File

@@ -151,6 +151,11 @@ impl RegClassData {
let uoffset = offset * self.width as usize; let uoffset = offset * self.width as usize;
self.first + uoffset as RegUnit self.first + uoffset as RegUnit
} }
/// Does this register class contain `regunit`?
pub fn contains(&self, regunit: RegUnit) -> bool {
self.mask[(regunit / 32) as usize] & (1u32 << (regunit % 32)) != 0
}
} }
impl fmt::Display for RegClassData { impl fmt::Display for RegClassData {

View File

@@ -6,7 +6,7 @@ include!(concat!(env!("OUT_DIR"), "/registers-riscv.rs"));
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::INFO; use super::{INFO, GPR, FPR};
use isa::RegUnit; use isa::RegUnit;
#[test] #[test]
@@ -34,4 +34,16 @@ mod tests {
assert_eq!(uname(63), "%f31"); assert_eq!(uname(63), "%f31");
assert_eq!(uname(64), "%INVALID64"); assert_eq!(uname(64), "%INVALID64");
} }
#[test]
fn classes() {
assert!(GPR.contains(GPR.unit(0)));
assert!(GPR.contains(GPR.unit(31)));
assert!(!FPR.contains(GPR.unit(0)));
assert!(!FPR.contains(GPR.unit(31)));
assert!(!GPR.contains(FPR.unit(0)));
assert!(!GPR.contains(FPR.unit(31)));
assert!(FPR.contains(FPR.unit(0)));
assert!(FPR.contains(FPR.unit(31)));
}
} }

View File

@@ -78,6 +78,25 @@ impl AllocatableSet {
} }
rsi rsi
} }
/// Check if any register units allocated out of this set interferes with units allocated out
/// of `other`.
///
/// This assumes that unused bits are 1.
pub fn interferes_with(&self, other: &AllocatableSet) -> bool {
self.avail
.iter()
.zip(&other.avail)
.any(|(&x, &y)| (x | y) != !0)
}
/// Intersect this set of allocatable registers with `other`. This has the effect of removing
/// any register units from this set that are not in `other`.
pub fn intersect(&mut self, other: &AllocatableSet) {
for (x, &y) in self.avail.iter_mut().zip(&other.avail) {
*x &= y;
}
}
} }
/// Iterator over available registers in a register class. /// Iterator over available registers in a register class.
@@ -179,4 +198,18 @@ mod tests {
assert_eq!(regs.iter(GPR).count(), 7); assert_eq!(regs.iter(GPR).count(), 7);
assert_eq!(regs.iter(DPR).collect::<Vec<_>>(), [30, 33, 35]); assert_eq!(regs.iter(DPR).collect::<Vec<_>>(), [30, 33, 35]);
} }
#[test]
fn interference() {
let mut regs1 = AllocatableSet::new();
let mut regs2 = AllocatableSet::new();
assert!(!regs1.interferes_with(&regs2));
regs1.take(&GPR, 32);
assert!(!regs1.interferes_with(&regs2));
regs2.take(&GPR, 31);
assert!(!regs1.interferes_with(&regs2));
regs1.intersect(&regs2);
assert!(regs1.interferes_with(&regs2));
}
} }