Make more PReg & VReg methods const (#76)

Also remove the previous workaround for const-assert now that it is
available on stable Rust.
This commit is contained in:
Amanieu d'Antras
2022-09-12 19:03:29 +02:00
committed by GitHub
parent be47ac39e8
commit aeef47a06b

View File

@@ -95,14 +95,7 @@ impl PReg {
/// Create a new PReg. The `hw_enc` range is 6 bits. /// Create a new PReg. The `hw_enc` range is 6 bits.
#[inline(always)] #[inline(always)]
pub const fn new(hw_enc: usize, class: RegClass) -> Self { pub const fn new(hw_enc: usize, class: RegClass) -> Self {
// We don't have const panics yet (rust-lang/rust#85194) so we debug_assert!(hw_enc <= PReg::MAX);
// need to use a little indexing trick here. We unfortunately
// can't use the `static-assertions` crate because we need
// this to work both for const `hw_enc` and for runtime
// values.
const HW_ENC_MUST_BE_IN_BOUNDS: &[bool; PReg::MAX + 1] = &[true; PReg::MAX + 1];
let _ = HW_ENC_MUST_BE_IN_BOUNDS[hw_enc];
PReg { PReg {
bits: ((class as u8) << Self::MAX_BITS) | (hw_enc as u8), bits: ((class as u8) << Self::MAX_BITS) | (hw_enc as u8),
} }
@@ -110,13 +103,13 @@ impl PReg {
/// The physical register number, as encoded by the ISA for the particular register class. /// The physical register number, as encoded by the ISA for the particular register class.
#[inline(always)] #[inline(always)]
pub fn hw_enc(self) -> usize { pub const fn hw_enc(self) -> usize {
self.bits as usize & Self::MAX self.bits as usize & Self::MAX
} }
/// The register class. /// The register class.
#[inline(always)] #[inline(always)]
pub fn class(self) -> RegClass { pub const fn class(self) -> RegClass {
if self.bits & (1 << Self::MAX_BITS) == 0 { if self.bits & (1 << Self::MAX_BITS) == 0 {
RegClass::Int RegClass::Int
} else { } else {
@@ -143,7 +136,7 @@ impl PReg {
/// Return the "invalid PReg", which can be used to initialize /// Return the "invalid PReg", which can be used to initialize
/// data structures. /// data structures.
#[inline(always)] #[inline(always)]
pub fn invalid() -> Self { pub const fn invalid() -> Self {
PReg::new(Self::MAX, RegClass::Int) PReg::new(Self::MAX, RegClass::Int)
} }
} }
@@ -264,11 +257,7 @@ impl VReg {
#[inline(always)] #[inline(always)]
pub const fn new(virt_reg: usize, class: RegClass) -> Self { pub const fn new(virt_reg: usize, class: RegClass) -> Self {
// See comment in `PReg::new()`: we are emulating a const debug_assert!(virt_reg <= VReg::MAX);
// assert here until const panics are stable.
const VIRT_REG_MUST_BE_IN_BOUNDS: &[bool; VReg::MAX + 1] = &[true; VReg::MAX + 1];
let _ = VIRT_REG_MUST_BE_IN_BOUNDS[virt_reg];
VReg { VReg {
bits: ((virt_reg as u32) << 1) | (class as u8 as u32), bits: ((virt_reg as u32) << 1) | (class as u8 as u32),
} }
@@ -281,7 +270,7 @@ impl VReg {
} }
#[inline(always)] #[inline(always)]
pub fn class(self) -> RegClass { pub const fn class(self) -> RegClass {
match self.bits & 1 { match self.bits & 1 {
0 => RegClass::Int, 0 => RegClass::Int,
1 => RegClass::Float, 1 => RegClass::Float,
@@ -290,7 +279,7 @@ impl VReg {
} }
#[inline(always)] #[inline(always)]
pub fn invalid() -> Self { pub const fn invalid() -> Self {
VReg::new(Self::MAX, RegClass::Int) VReg::new(Self::MAX, RegClass::Int)
} }
} }