-
Notifications
You must be signed in to change notification settings - Fork 48
Fix several bugs #129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix several bugs #129
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -125,7 +125,7 @@ impl PReg { | |
| /// The register class. | ||
| #[inline(always)] | ||
| pub const fn class(self) -> RegClass { | ||
| match self.bits & (0b11 << Self::MAX_BITS) { | ||
| match (self.bits >> Self::MAX_BITS) & 0b11 { | ||
| 0 => RegClass::Int, | ||
| 1 => RegClass::Float, | ||
| 2 => RegClass::Vector, | ||
|
|
@@ -188,49 +188,54 @@ impl core::fmt::Display for PReg { | |
| #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] | ||
| #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] | ||
| pub struct PRegSet { | ||
| bits: u128, | ||
| bits: [u128; 2], | ||
| } | ||
|
|
||
| impl PRegSet { | ||
| /// Create an empty set. | ||
| pub const fn empty() -> Self { | ||
| Self { bits: 0 } | ||
| Self { bits: [0; 2] } | ||
| } | ||
|
|
||
| /// Returns whether the given register is part of the set. | ||
| pub fn contains(&self, reg: PReg) -> bool { | ||
| let bit = reg.index(); | ||
| debug_assert!(bit < 128); | ||
| self.bits & 1u128 << bit != 0 | ||
| debug_assert!(reg.index() < 256); | ||
| let bit = reg.index() & 127; | ||
| let index = reg.index() >> 7; | ||
| self.bits[index] & (1u128 << bit) != 0 | ||
| } | ||
|
|
||
| /// Add a physical register (PReg) to the set, returning the new value. | ||
| pub const fn with(self, reg: PReg) -> Self { | ||
| let bit = reg.index(); | ||
| debug_assert!(bit < 128); | ||
| Self { | ||
| bits: self.bits | (1u128 << bit), | ||
| } | ||
| debug_assert!(reg.index() < 256); | ||
| let bit = reg.index() & 127; | ||
| let index = reg.index() >> 7; | ||
| let mut out = self; | ||
| out.bits[index] |= 1u128 << bit; | ||
| out | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that this logic has become slightly more complex, perhaps we could delegate to ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried that at first, but it's not possible since |
||
| } | ||
|
|
||
| /// Add a physical register (PReg) to the set. | ||
| pub fn add(&mut self, reg: PReg) { | ||
| let bit = reg.index(); | ||
| debug_assert!(bit < 128); | ||
| self.bits |= 1u128 << bit; | ||
| debug_assert!(reg.index() < 256); | ||
| let bit = reg.index() & 127; | ||
| let index = reg.index() >> 7; | ||
| self.bits[index] |= 1u128 << bit; | ||
| } | ||
|
|
||
| /// Remove a physical register (PReg) from the set. | ||
| pub fn remove(&mut self, reg: PReg) { | ||
| let bit = reg.index(); | ||
| debug_assert!(bit < 128); | ||
| self.bits &= !(1u128 << bit); | ||
| debug_assert!(reg.index() < 256); | ||
| let bit = reg.index() & 127; | ||
| let index = reg.index() >> 7; | ||
| self.bits[index] &= !(1u128 << bit); | ||
| } | ||
|
|
||
| /// Add all of the registers in one set to this one, mutating in | ||
| /// place. | ||
| pub fn union_from(&mut self, other: PRegSet) { | ||
| self.bits |= other.bits; | ||
| self.bits[0] |= other.bits[0]; | ||
| self.bits[1] |= other.bits[1]; | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -243,18 +248,22 @@ impl IntoIterator for PRegSet { | |
| } | ||
|
|
||
| pub struct PRegSetIter { | ||
| bits: u128, | ||
| bits: [u128; 2], | ||
| } | ||
|
|
||
| impl Iterator for PRegSetIter { | ||
| type Item = PReg; | ||
| fn next(&mut self) -> Option<PReg> { | ||
| if self.bits == 0 { | ||
| None | ||
| } else { | ||
| let index = self.bits.trailing_zeros(); | ||
| self.bits &= !(1u128 << index); | ||
| if self.bits[0] != 0 { | ||
| let index = self.bits[0].trailing_zeros(); | ||
| self.bits[0] &= !(1u128 << index); | ||
| Some(PReg::from_index(index as usize)) | ||
| } else if self.bits[1] != 0 { | ||
| let index = self.bits[1].trailing_zeros(); | ||
| self.bits[1] &= !(1u128 << index); | ||
| Some(PReg::from_index(index as usize + 128)) | ||
| } else { | ||
| None | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -822,6 +831,9 @@ impl core::fmt::Debug for Operand { | |
|
|
||
| impl core::fmt::Display for Operand { | ||
| fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { | ||
| if let Some(preg) = self.as_fixed_nonallocatable() { | ||
| return write!(f, "Fixed: {preg}"); | ||
| } | ||
| match (self.kind(), self.pos()) { | ||
| (OperandKind::Def, OperandPos::Late) | (OperandKind::Use, OperandPos::Early) => { | ||
| write!(f, "{:?}", self.kind())?; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And, yikes, thanks for catching this -- sorry I missed it in review!