rhdl_bits/
shr.rs

1use std::ops::Shr;
2use std::ops::ShrAssign;
3
4use crate::bits::Bits;
5use crate::signed_bits::SignedBits;
6
7impl<const N: usize> Shr<u128> for Bits<N> {
8    type Output = Self;
9    fn shr(self, rhs: u128) -> Self::Output {
10        self >> Bits::<8>::from(rhs)
11    }
12}
13
14impl<const N: usize> Shr<Bits<N>> for u128 {
15    type Output = Bits<N>;
16    fn shr(self, rhs: Bits<N>) -> Self::Output {
17        assert!(N <= 8, "Shift amount must be less than 8 bits");
18        Bits::<N>::from(self) >> rhs
19    }
20}
21
22impl<const M: usize, const N: usize> Shr<Bits<M>> for Bits<N> {
23    type Output = Self;
24    fn shr(self, rhs: Bits<M>) -> Self::Output {
25        assert!(M <= 8, "Shift amount must be less than 8 bits");
26        Self(u128::wrapping_shr(self.0, rhs.0 as u32) & Self::mask().0)
27    }
28}
29
30impl<const M: usize, const N: usize> ShrAssign<Bits<M>> for Bits<N> {
31    fn shr_assign(&mut self, rhs: Bits<M>) {
32        *self = *self >> rhs;
33    }
34}
35
36impl<const N: usize> ShrAssign<u128> for Bits<N> {
37    fn shr_assign(&mut self, rhs: u128) {
38        *self = *self >> rhs;
39    }
40}
41
42impl<const M: usize, const N: usize> Shr<Bits<M>> for SignedBits<N> {
43    type Output = Self;
44    fn shr(self, rhs: Bits<M>) -> Self::Output {
45        assert!(M <= 8, "Shift amount must be less than 8 bits");
46        Self(i128::wrapping_shr(self.0, rhs.0 as u32))
47    }
48}
49
50impl<const N: usize> Shr<u128> for SignedBits<N> {
51    type Output = Self;
52    fn shr(self, rhs: u128) -> Self::Output {
53        self >> Bits::<8>::from(rhs)
54    }
55}
56
57impl<const M: usize, const N: usize> ShrAssign<Bits<M>> for SignedBits<N> {
58    fn shr_assign(&mut self, rhs: Bits<M>) {
59        *self = *self >> rhs;
60    }
61}
62
63impl<const N: usize> ShrAssign<u128> for SignedBits<N> {
64    fn shr_assign(&mut self, rhs: u128) {
65        *self = *self >> rhs;
66    }
67}
68
69#[cfg(test)]
70mod test {
71    use super::*;
72
73    #[test]
74    fn test_shr_bits() {
75        let bits: Bits<8> = 0b1101_1010.into();
76        let result = bits >> 4;
77        assert_eq!(result.0, 0b0000_1101_u128);
78        let bits: Bits<16> = 0b1101_1010_0000_0000.into();
79        let result = bits >> 8;
80        assert_eq!(result.0, 0b0000_0000_1101_1010_u128);
81        let shift: Bits<8> = 8.into();
82        let result = bits >> shift;
83        assert_eq!(result.0, 0b0000_0000_1101_1010_u128);
84        let bits: Bits<8> = 0b1101_1010.into();
85        let result = bits >> 8;
86        assert_eq!(result.0, 0);
87    }
88
89    #[test]
90    fn test_shr_signed_i8_sane() {
91        let i = -128_i8;
92        let j = i >> 1;
93        assert_eq!(j, -64_i8);
94        let j = i8::wrapping_shr(i, 1);
95        assert_eq!(j, -64_i8);
96    }
97
98    #[test]
99    fn test_shr_signed() {
100        for i in i8::MIN..i8::MAX {
101            for shift in 0..10_u32 {
102                let bits: SignedBits<8> = (i as i128).into();
103                let result = bits >> (shift as u128);
104                assert_eq!(
105                    result.0,
106                    i128::wrapping_shr(i as i128, shift),
107                    "i = {:b}, shift = {}",
108                    i,
109                    shift
110                );
111                let shift_as_bits: Bits<8> = (shift as u128).into();
112                let result = bits >> shift_as_bits;
113                assert_eq!(result.0, i128::wrapping_shr(i as i128, shift));
114            }
115        }
116    }
117}