sbi_spec/binary/
counter_mask.rs1use super::{mask_commons::has_bit, sbi_ret::SbiRegister};
2
3#[repr(C)]
5#[derive(Debug, Copy, Clone, Eq, PartialEq)]
6pub struct CounterMask<T = usize> {
7 counter_idx_mask: T,
8 counter_idx_base: T,
9}
10
11impl<T: SbiRegister> CounterMask<T> {
12 pub const IGNORE_MASK: T = T::FULL_MASK;
14
15 #[inline]
17 pub const fn from_mask_base(counter_idx_mask: T, counter_idx_base: T) -> Self {
18 Self {
19 counter_idx_mask,
20 counter_idx_base,
21 }
22 }
23
24 #[inline]
26 pub const fn ignore_mask(&self) -> T {
27 Self::IGNORE_MASK
28 }
29
30 #[inline]
32 pub const fn into_inner(self) -> (T, T) {
33 (self.counter_idx_mask, self.counter_idx_base)
34 }
35}
36
37impl CounterMask<usize> {
40 #[inline]
42 pub const fn has_bit(self, counter: usize) -> bool {
43 has_bit(
44 self.counter_idx_mask,
45 self.counter_idx_base,
46 Self::IGNORE_MASK,
47 counter,
48 )
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn rustsbi_counter_index_mask() {
58 let mask = CounterMask::from_mask_base(0b1, 400);
59 assert!(!mask.has_bit(0));
60 assert!(mask.has_bit(400));
61 assert!(!mask.has_bit(401));
62 let mask = CounterMask::from_mask_base(0b110, 500);
63 assert!(!mask.has_bit(0));
64 assert!(!mask.has_bit(500));
65 assert!(mask.has_bit(501));
66 assert!(mask.has_bit(502));
67 assert!(!mask.has_bit(500 + (usize::BITS as usize)));
68 let max_bit = 1 << (usize::BITS - 1);
69 let mask = CounterMask::from_mask_base(max_bit, 600);
70 assert!(mask.has_bit(600 + (usize::BITS as usize) - 1));
71 assert!(!mask.has_bit(600 + (usize::BITS as usize)));
72 let mask = CounterMask::from_mask_base(0b11, usize::MAX - 1);
73 assert!(!mask.has_bit(usize::MAX - 2));
74 assert!(mask.has_bit(usize::MAX - 1));
75 assert!(mask.has_bit(usize::MAX));
76 assert!(!mask.has_bit(0));
77 let mask = CounterMask::from_mask_base(0, usize::MAX);
78 let null_mask = CounterMask::from_mask_base(0, 0);
79 (0..=usize::BITS as usize).for_each(|i| {
80 assert!(mask.has_bit(i));
81 assert!(!null_mask.has_bit(i));
82 });
83 assert!(mask.has_bit(usize::MAX));
84 }
85
86 #[test]
87 fn rustsbi_counter_mask_non_usize() {
88 assert_eq!(CounterMask::<i32>::IGNORE_MASK, -1);
89 assert_eq!(CounterMask::<i64>::IGNORE_MASK, -1);
90 assert_eq!(CounterMask::<i128>::IGNORE_MASK, -1);
91 assert_eq!(CounterMask::<u32>::IGNORE_MASK, u32::MAX);
92 assert_eq!(CounterMask::<u64>::IGNORE_MASK, u64::MAX);
93 assert_eq!(CounterMask::<u128>::IGNORE_MASK, u128::MAX);
94 }
95}