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)]
|
#[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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user