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) __m256d);
10 
11 impl Block {
12     #[inline]
is_empty(self) -> bool13     pub fn is_empty(self) -> bool {
14         unsafe {
15             let value = _mm256_castpd_si256(self.0);
16             _mm256_testz_si256(value, value) == 1
17         }
18     }
19 
20     #[inline]
andnot(self, other: Self) -> Self21     pub fn andnot(self, other: Self) -> Self {
22         unsafe { Self(_mm256_andnot_pd(other.0, self.0)) }
23     }
24 }
25 
26 impl Not for Block {
27     type Output = Block;
28     #[inline]
not(self) -> Self::Output29     fn not(self) -> Self::Output {
30         unsafe { Self(_mm256_xor_pd(self.0, Self::ALL.0)) }
31     }
32 }
33 
34 impl BitAnd for Block {
35     type Output = Block;
36     #[inline]
bitand(self, other: Self) -> Self::Output37     fn bitand(self, other: Self) -> Self::Output {
38         unsafe { Self(_mm256_and_pd(self.0, other.0)) }
39     }
40 }
41 
42 impl BitAndAssign for Block {
43     #[inline]
bitand_assign(&mut self, other: Self)44     fn bitand_assign(&mut self, other: Self) {
45         unsafe {
46             self.0 = _mm256_and_pd(self.0, other.0);
47         }
48     }
49 }
50 
51 impl BitOr for Block {
52     type Output = Block;
53     #[inline]
bitor(self, other: Self) -> Self::Output54     fn bitor(self, other: Self) -> Self::Output {
55         unsafe { Self(_mm256_or_pd(self.0, other.0)) }
56     }
57 }
58 
59 impl BitOrAssign for Block {
60     #[inline]
bitor_assign(&mut self, other: Self)61     fn bitor_assign(&mut self, other: Self) {
62         unsafe {
63             self.0 = _mm256_or_pd(self.0, other.0);
64         }
65     }
66 }
67 
68 impl BitXor for Block {
69     type Output = Block;
70     #[inline]
bitxor(self, other: Self) -> Self::Output71     fn bitxor(self, other: Self) -> Self::Output {
72         unsafe { Self(_mm256_xor_pd(self.0, other.0)) }
73     }
74 }
75 
76 impl BitXorAssign for Block {
77     #[inline]
bitxor_assign(&mut self, other: Self)78     fn bitxor_assign(&mut self, other: Self) {
79         unsafe { self.0 = _mm256_xor_pd(self.0, other.0) }
80     }
81 }
82 
83 impl PartialEq for Block {
84     #[inline]
eq(&self, other: &Self) -> bool85     fn eq(&self, other: &Self) -> bool {
86         unsafe {
87             let new = _mm256_xor_pd(self.0, other.0);
88             let neq = _mm256_castpd_si256(new);
89             _mm256_testz_si256(neq, neq) == 1
90         }
91     }
92 }
93