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:
@@ -6,7 +6,7 @@ include!(concat!(env!("OUT_DIR"), "/registers-arm32.rs"));
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::INFO;
|
||||
use super::{INFO, GPR, S, D};
|
||||
use isa::RegUnit;
|
||||
|
||||
#[test]
|
||||
@@ -29,4 +29,39 @@ mod tests {
|
||||
assert_eq!(uname(31), "%s31");
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
pub use isa::constraints::{RecipeConstraints, OperandConstraint, ConstraintKind, BranchRange};
|
||||
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 settings;
|
||||
|
||||
@@ -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.
|
||||
///
|
||||
/// The `RegUnit` data structure collects all relevant static information about the registers in an
|
||||
|
||||
Reference in New Issue
Block a user