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