1 #[cfg(target_arch = "x86")]
2 use core::arch::x86::*;
3 #[cfg(target_arch = "x86_64")]
4 use core::arch::x86_64::*;
5 use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not};
6 
7 #[derive(Copy, Clone, Debug)]
8 #[repr(transparent)]
9 pub struct Block(pub(super) __m256i);
10 
11 impl Block {
12     #[inline]
is_empty(self) -> bool13     pub fn is_empty(self) -> bool {
14         unsafe { _mm256_testz_si256(self.0, self.0) == 1 }
15     }
16 
17     #[inline]
andnot(self, other: Self) -> Self18     pub fn andnot(self, other: Self) -> Self {
19         Self(unsafe { _mm256_andnot_si256(other.0, self.0) })
20     }
21 }
22 
23 impl Not for Block {
24     type Output = Block;
25     #[inline]
not(self) -> Self::Output26     fn not(self) -> Self::Output {
27         unsafe { Self(_mm256_xor_si256(self.0, Self::ALL.0)) }
28     }
29 }
30 
31 impl BitAnd for Block {
32     type Output = Block;
33     #[inline]
bitand(self, other: Self) -> Self::Output34     fn bitand(self, other: Self) -> Self::Output {
35         unsafe { Self(_mm256_and_si256(self.0, other.0)) }
36     }
37 }
38 
39 impl BitAndAssign for Block {
40     #[inline]
bitand_assign(&mut self, other: Self)41     fn bitand_assign(&mut self, other: Self) {
42         unsafe {
43             self.0 = _mm256_and_si256(self.0, other.0);
44         }
45     }
46 }
47 
48 impl BitOr for Block {
49     type Output = Block;
50     #[inline]
bitor(self, other: Self) -> Self::Output51     fn bitor(self, other: Self) -> Self::Output {
52         unsafe { Self(_mm256_or_si256(self.0, other.0)) }
53     }
54 }
55 
56 impl BitOrAssign for Block {
57     #[inline]
bitor_assign(&mut self, other: Self)58     fn bitor_assign(&mut self, other: Self) {
59         unsafe {
60             self.0 = _mm256_or_si256(self.0, other.0);
61         }
62     }
63 }
64 
65 impl BitXor for Block {
66     type Output = Block;
67     #[inline]
bitxor(self, other: Self) -> Self::Output68     fn bitxor(self, other: Self) -> Self::Output {
69         unsafe { Self(_mm256_xor_si256(self.0, other.0)) }
70     }
71 }
72 
73 impl BitXorAssign for Block {
74     #[inline]
bitxor_assign(&mut self, other: Self)75     fn bitxor_assign(&mut self, other: Self) {
76         unsafe { self.0 = _mm256_xor_si256(self.0, other.0) }
77     }
78 }
79 
80 impl PartialEq for Block {
81     #[inline]
eq(&self, other: &Self) -> bool82     fn eq(&self, other: &Self) -> bool {
83         unsafe {
84             let neq = _mm256_xor_si256(self.0, other.0);
85             _mm256_testz_si256(neq, neq) == 1
86         }
87     }
88 }
89