Remove dependency on hard-coded ordering of x86 register banks
With this change, register banks can now be re-ordered and other components (e.g. unwinding, regalloc) will no longer break. The previous behavior assumed that GPR registers always started at `RegUnit` 0.
This commit is contained in:
@@ -180,7 +180,7 @@ impl RegClassData {
|
||||
/// Returns true if `other` is a subclass of this register class.
|
||||
/// A register class is considered to be a subclass of itself.
|
||||
pub fn has_subclass<RCI: Into<RegClassIndex>>(&self, other: RCI) -> bool {
|
||||
self.subclasses & (1 << other.into().0) != 0
|
||||
self.subclasses & (1 << other.into().0) as u32 != 0
|
||||
}
|
||||
|
||||
/// Get the top-level register class containing this class.
|
||||
@@ -196,7 +196,7 @@ impl RegClassData {
|
||||
|
||||
/// Does this register class contain `regunit`?
|
||||
pub fn contains(&self, regunit: RegUnit) -> bool {
|
||||
self.mask[(regunit / 32) as usize] & (1u32 << (regunit % 32)) != 0
|
||||
self.mask[(regunit / 32) as usize] & (1u32 << (regunit % 32) as u32) != 0
|
||||
}
|
||||
|
||||
/// If the pinned register is used, is the given regunit the pinned register of this class?
|
||||
@@ -207,6 +207,17 @@ impl RegClassData {
|
||||
.pinned_reg
|
||||
.map_or(false, |pinned_reg| pinned_reg == regunit)
|
||||
}
|
||||
|
||||
/// Calculate the index of the register inside the class.
|
||||
pub fn index_of(&self, regunit: RegUnit) -> u16 {
|
||||
assert!(
|
||||
self.contains(regunit),
|
||||
"the {} register class does not contain {}",
|
||||
self.name,
|
||||
regunit
|
||||
);
|
||||
regunit - self.first
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RegClassData {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Unwind information for x64 Windows.
|
||||
|
||||
use super::registers::RU;
|
||||
use super::registers::{GPR, RU};
|
||||
use crate::binemit::FrameUnwindSink;
|
||||
use crate::ir::{Function, InstructionData, Opcode};
|
||||
use crate::isa::{CallConv, RegUnit, TargetIsa};
|
||||
@@ -54,7 +54,8 @@ impl UnwindCode {
|
||||
write_u8(sink, *offset);
|
||||
write_u8(
|
||||
sink,
|
||||
((*reg as u8) << 4) | (UnwindOperation::PushNonvolatileRegister as u8),
|
||||
((GPR.index_of(*reg) as u8) << 4)
|
||||
| (UnwindOperation::PushNonvolatileRegister as u8),
|
||||
);
|
||||
}
|
||||
Self::StackAlloc { offset, size } => {
|
||||
@@ -262,7 +263,10 @@ impl UnwindInfo {
|
||||
write_u8(sink, node_count as u8);
|
||||
|
||||
if let Some(reg) = self.frame_register {
|
||||
write_u8(sink, (self.frame_register_offset << 4) | reg as u8);
|
||||
write_u8(
|
||||
sink,
|
||||
(self.frame_register_offset << 4) | GPR.index_of(reg) as u8,
|
||||
);
|
||||
} else {
|
||||
write_u8(sink, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user