Add a regs_overlap function to the isa module.

Test it with the arm32 register banks which have the most interesting
properties. Most other registers have a single register unit.
This commit is contained in:
Jakob Stoklund Olesen
2017-05-08 12:20:35 -07:00
parent aecd90a1b9
commit aaa70a677d
3 changed files with 47 additions and 2 deletions

View File

@@ -6,7 +6,7 @@ include!(concat!(env!("OUT_DIR"), "/registers-arm32.rs"));
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::INFO; use super::{INFO, GPR, S, D};
use isa::RegUnit; use isa::RegUnit;
#[test] #[test]
@@ -29,4 +29,39 @@ mod tests {
assert_eq!(uname(31), "%s31"); assert_eq!(uname(31), "%s31");
assert_eq!(uname(64), "%r0"); assert_eq!(uname(64), "%r0");
} }
#[test]
fn overlaps() {
// arm32 has the most interesting register geometries, so test `regs_overlap()` here.
use isa::regs_overlap;
let r0 = GPR.unit(0);
let r1 = GPR.unit(1);
let r2 = GPR.unit(2);
assert!(regs_overlap(GPR, r0, GPR, r0));
assert!(regs_overlap(GPR, r2, GPR, r2));
assert!(!regs_overlap(GPR, r0, GPR, r1));
assert!(!regs_overlap(GPR, r1, GPR, r0));
assert!(!regs_overlap(GPR, r2, GPR, r1));
assert!(!regs_overlap(GPR, r1, GPR, r2));
let s0 = S.unit(0);
let s1 = S.unit(1);
let s2 = S.unit(2);
let s3 = S.unit(3);
let d0 = D.unit(0);
let d1 = D.unit(1);
assert!(regs_overlap(S, s0, D, d0));
assert!(regs_overlap(S, s1, D, d0));
assert!(!regs_overlap(S, s0, D, d1));
assert!(!regs_overlap(S, s1, D, d1));
assert!(regs_overlap(S, s2, D, d1));
assert!(regs_overlap(S, s3, D, d1));
assert!(!regs_overlap(D, d1, S, s1));
assert!(regs_overlap(D, d1, S, s2));
assert!(!regs_overlap(D, d0, D, d1));
assert!(regs_overlap(D, d1, D, d1));
}
} }

View File

@@ -42,7 +42,7 @@
pub use isa::constraints::{RecipeConstraints, OperandConstraint, ConstraintKind, BranchRange}; pub use isa::constraints::{RecipeConstraints, OperandConstraint, ConstraintKind, BranchRange};
pub use isa::encoding::{Encoding, EncInfo}; pub use isa::encoding::{Encoding, EncInfo};
pub use isa::registers::{RegInfo, RegUnit, RegClass, RegClassIndex}; pub use isa::registers::{RegInfo, RegUnit, RegClass, RegClassIndex, regs_overlap};
use binemit::CodeSink; use binemit::CodeSink;
use settings; use settings;

View File

@@ -188,6 +188,16 @@ impl fmt::Display for RegClassIndex {
} }
} }
/// Test of two registers overlap.
///
/// A register is identified as a `(RegClass, RegUnit)` pair. The register class is needed to
/// determine the width (in regunits) of the register.
pub fn regs_overlap(rc1: RegClass, reg1: RegUnit, rc2: RegClass, reg2: RegUnit) -> bool {
let end1 = reg1 + rc1.width as RegUnit;
let end2 = reg2 + rc2.width as RegUnit;
!(end1 <= reg2 || end2 <= reg1)
}
/// Information about the registers in an ISA. /// Information about the registers in an ISA.
/// ///
/// The `RegUnit` data structure collects all relevant static information about the registers in an /// The `RegUnit` data structure collects all relevant static information about the registers in an