#[macro_export]
macro_rules! bit_slice {
($n:expr, $i:expr) => {
($n & (0b1 << $i)) >> $i
};
($n:expr, $msb:expr, $lsb:expr) => {
($n & (((0b1 << ($msb - $lsb + 1)) - 1) << $lsb)) >> $lsb
};
}
#[macro_export]
macro_rules! bit_concat {
($($x:expr),*) => {{
let mut i = 0;
let mut t = 0;
for n in [$($x),*].iter().rev() {
t += n.0 << i;
i += n.1;
}
t
}}
}
#[macro_export]
macro_rules! bit_extend {
($n:expr, $r:expr) => {
match $n {
0 => 0,
_ => (0..$r).map(|i| 1 << i).sum(),
}
};
}
#[macro_export]
macro_rules! sized_bit_slice {
($n: expr, $i:expr) => {
(bit_slice!($n, $i), 1)
};
($n: expr, $msb:expr, $lsb:expr) => {
(bit_slice!($n, $msb, $lsb), $msb - $lsb + 1)
};
}
#[macro_export]
macro_rules! sized_bit_extend {
($n: expr, $r:expr) => {
(bit_extend!($n, $r), $r)
};
}
#[cfg(test)]
mod tests {
#[test]
fn bit_slice() {
let x = 0b1011;
assert_eq!(0b1, bit_slice!(x, 3));
assert_eq!(0b0, bit_slice!(x, 2));
assert_eq!(0b1, bit_slice!(x, 1));
assert_eq!(0b1, bit_slice!(x, 0));
assert_eq!(0b10, bit_slice!(x, 3, 2));
assert_eq!(0b101, bit_slice!(x, 3, 1));
assert_eq!(0b1011, bit_slice!(x, 3, 0));
assert_eq!(0b011, bit_slice!(x, 2, 0));
assert_eq!(0b11, bit_slice!(x, 1, 0));
}
#[test]
fn bit_concat() {
assert_eq!(0b1101, bit_concat!((0b11, 2), (0b01, 2)));
}
#[test]
fn bit_extend() {
assert_eq!(0b1111, bit_extend!(1, 4));
assert_eq!(0b0, bit_extend!(0, 32));
}
}