From aaa70a677d3604ee90d03ef240710bab4137752b Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Mon, 8 May 2017 12:20:35 -0700 Subject: [PATCH] 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. --- lib/cretonne/src/isa/arm32/registers.rs | 37 ++++++++++++++++++++++++- lib/cretonne/src/isa/mod.rs | 2 +- lib/cretonne/src/isa/registers.rs | 10 +++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/lib/cretonne/src/isa/arm32/registers.rs b/lib/cretonne/src/isa/arm32/registers.rs index 69571976cb..283f113d1e 100644 --- a/lib/cretonne/src/isa/arm32/registers.rs +++ b/lib/cretonne/src/isa/arm32/registers.rs @@ -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)); + } } diff --git a/lib/cretonne/src/isa/mod.rs b/lib/cretonne/src/isa/mod.rs index 4b618e0798..34d3e21ef6 100644 --- a/lib/cretonne/src/isa/mod.rs +++ b/lib/cretonne/src/isa/mod.rs @@ -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; diff --git a/lib/cretonne/src/isa/registers.rs b/lib/cretonne/src/isa/registers.rs index 15a089db17..76fd39685a 100644 --- a/lib/cretonne/src/isa/registers.rs +++ b/lib/cretonne/src/isa/registers.rs @@ -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