lib_rv32_common/
bits.rs

1/// Returns a bitmask for the n'th bit.
2#[macro_export]
3macro_rules! bit {
4    ($n:expr) => {
5        ((0b1 as u32) << $n)
6    };
7}
8
9/// Macro to help with bit level access to integers. Example
10/// attempts to mimic Verilog syntax.
11///
12/// Example:
13///
14/// ```
15/// # use lib_rv32_common::bit_slice;
16/// bit_slice!(0b1101, 3, 2) == 0b11;
17/// bit_slice!(0b1101, 1) == 0b0;
18/// ```
19#[macro_export]
20macro_rules! bit_slice {
21    ($n:expr, $i:expr) => {
22        ($n & (0b1 << $i)) >> $i
23    };
24
25    ($n:expr, $msb:expr, $lsb:expr) => {
26        ($n & (((0b1 << ($msb - $lsb + 1)) - 1) << $lsb)) >> $lsb
27    };
28}
29
30/// Concatenate the bits of integers.
31///
32/// Example:
33///
34/// ```
35/// # use lib_rv32_common::bit_concat;
36/// bit_concat!(
37///     (0b111, 3),
38///     (0b01, 2)
39/// ) == 0b11101;
40/// ```
41#[macro_export]
42macro_rules! bit_concat {
43    ($($x:expr),*) => {{
44        let mut i = 0;
45        let mut t = 0;
46        for n in [$($x),*].iter().rev() {
47            t += n.0 << i;
48            i += n.1;
49        }
50        t
51    }}
52}
53
54/// Extend a bit (useful for sign extension).
55///
56/// Example:
57///
58/// ```
59/// # use lib_rv32_common::bit_extend;
60/// bit_extend!(0b1, 8) == 0b1111_1111;
61/// ```
62#[macro_export]
63macro_rules! bit_extend {
64    ($n:expr, $r:expr) => {
65        match $n {
66            0 => 0,
67            _ => (0..$r).map(|i| 1 << i).sum(),
68        }
69    };
70}
71
72/// Like `bit_slice`, but outputs the result and its
73/// size in a tuple.
74#[macro_export]
75macro_rules! sized_bit_slice {
76    ($n: expr, $i:expr) => {
77        (bit_slice!($n, $i), 1)
78    };
79
80    ($n: expr, $msb:expr, $lsb:expr) => {
81        (bit_slice!($n, $msb, $lsb), $msb - $lsb + 1)
82    };
83}
84
85/// Like `bit_extend`, but outputs the result and its
86/// size in a tuple.
87#[macro_export]
88macro_rules! sized_bit_extend {
89    ($n: expr, $r:expr) => {
90        (bit_extend!($n, $r), $r)
91    };
92}
93
94#[cfg(test)]
95mod tests {
96    #[test]
97    fn test_bit_slice() {
98        let x = 0b1011;
99
100        assert_eq!(0b1, bit_slice!(x, 3));
101        assert_eq!(0b0, bit_slice!(x, 2));
102        assert_eq!(0b1, bit_slice!(x, 1));
103        assert_eq!(0b1, bit_slice!(x, 0));
104
105        assert_eq!(0b10, bit_slice!(x, 3, 2));
106        assert_eq!(0b101, bit_slice!(x, 3, 1));
107        assert_eq!(0b1011, bit_slice!(x, 3, 0));
108        assert_eq!(0b011, bit_slice!(x, 2, 0));
109        assert_eq!(0b11, bit_slice!(x, 1, 0));
110    }
111
112    #[test]
113    fn test_bit_concat() {
114        assert_eq!(0b1101, bit_concat!((0b11, 2), (0b01, 2)));
115    }
116
117    #[test]
118    fn test_bit_extend() {
119        assert_eq!(0b1111, bit_extend!(1, 4));
120        assert_eq!(0b0, bit_extend!(0, 32));
121    }
122}