浏览代码

spec: change `BitVector` to a trait

Changes the `BitVector` struct to a helper function `has_bit`.

`HartMask` uses the new helper internally to test for `hart_id`
membership.

Allows for code re-use of the `has_bit` function without wrapping a type.
rmsyn 11 月之前
父节点
当前提交
7eb0000160
共有 1 个文件被更改,包括 54 次插入39 次删除
  1. 54 39
      sbi-spec/src/binary.rs

+ 54 - 39
sbi-spec/src/binary.rs

@@ -673,58 +673,73 @@ impl SbiRet {
     }
 }
 
+/// Check if the implementation contains the provided `bit`.
+///
+/// ## Parameters
+///
+/// - `mask`: bitmask defining the range of bits.
+/// - `base`: the starting bit index. (default: `0`)
+/// - `ignore`: if `base` is equal to this value, ignore the `mask` parameter, and consider all `bit`s set.
+/// - `bit`: the bit index to check for membership in the `mask`.
+pub(crate) const fn has_bit(mask: usize, base: usize, ignore: usize, bit: usize) -> bool {
+    if base == ignore {
+        // ignore the `mask`, consider all `bit`s as set.
+        true
+    } else if bit < base {
+        // invalid index, under minimum range.
+        false
+    } else if (bit - base) >= usize::BITS as usize {
+        // invalid index, over max range.
+        false
+    } else {
+        // index is in range, check if it is set in the mask.
+        mask & (1 << (bit - base)) != 0
+    }
+}
+
 /// Hart mask structure in SBI function calls.
-#[derive(Debug, Copy, Clone)]
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
 pub struct HartMask {
-    inner: BitVector,
+    hart_mask: usize,
+    hart_mask_base: usize,
 }
 
 impl HartMask {
-    /// Construct a hart mask from mask value and base hart id.
-    #[inline]
-    pub const fn from_mask_base(hart_mask: usize, hart_mask_base: usize) -> HartMask {
-        HartMask {
-            inner: BitVector {
-                hart_mask,
-                hart_mask_base,
-            },
+    /// Special value to ignore the `mask`, and consider all `bit`s as set.
+    pub const IGNORE_MASK: usize = usize::MAX;
+
+    /// Construct a [HartMask] from mask value and base hart id.
+    #[inline]
+    pub const fn from_mask_base(hart_mask: usize, hart_mask_base: usize) -> Self {
+        Self {
+            hart_mask,
+            hart_mask_base,
         }
     }
 
-    /// Returns `hart_mask` and `hart_mask_base` parameters from the hart mask structure.
+    /// Gets the special value for ignoring the `mask` parameter.
     #[inline]
-    pub const fn into_inner(self) -> (usize, usize) {
-        (self.inner.hart_mask, self.inner.hart_mask_base)
+    pub const fn ignore_mask(&self) -> usize {
+        Self::IGNORE_MASK
     }
 
-    /// Check if the `hart_id` is included in this hart mask structure.
+    /// Returns `mask` and `base` parameters from the [HartMask].
     #[inline]
-    pub const fn has_bit(&self, hart_id: usize) -> bool {
-        let BitVector {
-            hart_mask,
-            hart_mask_base,
-        } = self.inner;
-        if hart_mask_base == usize::MAX {
-            // If `hart_mask_base` equals `usize::MAX`, that means `hart_mask` is ignored
-            // and all available harts must be considered.
-            return true;
-        }
-        let Some(idx) = hart_id.checked_sub(hart_mask_base) else {
-            // hart_id < hart_mask_base, not in current mask range
-            return false;
-        };
-        if idx >= usize::BITS as usize {
-            // hart_idx >= hart_mask_base + XLEN, not in current mask range
-            return false;
-        }
-        hart_mask & (1 << idx) != 0
+    pub const fn into_inner(self) -> (usize, usize) {
+        (self.hart_mask, self.hart_mask_base)
     }
-}
 
-#[derive(Debug, Copy, Clone)]
-struct BitVector {
-    hart_mask: usize,
-    hart_mask_base: usize,
+    /// Returns whether the [HartMask] contains the provided `hart_id`.
+    #[inline]
+    pub const fn has_bit(self, hart_id: usize) -> bool {
+        has_bit(
+            self.hart_mask,
+            self.hart_mask_base,
+            Self::IGNORE_MASK,
+            hart_id,
+        )
+    }
 }
 
 /// Physical slice wrapper with type annotation.
@@ -873,7 +888,7 @@ impl<T> Copy for SharedPtr<T> {}
 
 #[cfg(test)]
 mod tests {
-    use super::HartMask;
+    use super::*;
 
     #[test]
     fn rustsbi_hart_mask() {