fixedbitset/block/
sse2.rs

1#![allow(clippy::undocumented_unsafe_blocks)]
2
3#[cfg(target_arch = "x86")]
4use core::arch::x86::*;
5#[cfg(target_arch = "x86_64")]
6use core::arch::x86_64::*;
7use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not};
8
9#[derive(Copy, Clone, Debug)]
10#[repr(transparent)]
11pub struct Block(pub(super) __m128i);
12
13impl Block {
14    #[inline]
15    pub fn is_empty(self) -> bool {
16        #[cfg(not(target_feature = "sse4.1"))]
17        {
18            self == Self::NONE
19        }
20        #[cfg(target_feature = "sse4.1")]
21        {
22            unsafe { _mm_test_all_zeros(self.0, self.0) == 1 }
23        }
24    }
25
26    #[inline]
27    pub fn andnot(self, other: Self) -> Self {
28        Self(unsafe { _mm_andnot_si128(other.0, self.0) })
29    }
30}
31
32impl Not for Block {
33    type Output = Block;
34    #[inline]
35    fn not(self) -> Self::Output {
36        unsafe { Self(_mm_xor_si128(self.0, Self::ALL.0)) }
37    }
38}
39
40impl BitAnd for Block {
41    type Output = Block;
42    #[inline]
43    fn bitand(self, other: Self) -> Self::Output {
44        unsafe { Self(_mm_and_si128(self.0, other.0)) }
45    }
46}
47
48impl BitAndAssign for Block {
49    #[inline]
50    fn bitand_assign(&mut self, other: Self) {
51        unsafe {
52            self.0 = _mm_and_si128(self.0, other.0);
53        }
54    }
55}
56
57impl BitOr for Block {
58    type Output = Block;
59    #[inline]
60    fn bitor(self, other: Self) -> Self::Output {
61        unsafe { Self(_mm_or_si128(self.0, other.0)) }
62    }
63}
64
65impl BitOrAssign for Block {
66    #[inline]
67    fn bitor_assign(&mut self, other: Self) {
68        unsafe {
69            self.0 = _mm_or_si128(self.0, other.0);
70        }
71    }
72}
73
74impl BitXor for Block {
75    type Output = Block;
76    #[inline]
77    fn bitxor(self, other: Self) -> Self::Output {
78        unsafe { Self(_mm_xor_si128(self.0, other.0)) }
79    }
80}
81
82impl BitXorAssign for Block {
83    #[inline]
84    fn bitxor_assign(&mut self, other: Self) {
85        unsafe { self.0 = _mm_xor_si128(self.0, other.0) }
86    }
87}
88
89impl PartialEq for Block {
90    #[inline]
91    fn eq(&self, other: &Self) -> bool {
92        unsafe {
93            #[cfg(not(target_feature = "sse4.1"))]
94            {
95                _mm_movemask_epi8(_mm_cmpeq_epi8(self.0, other.0)) == 0xffff
96            }
97            #[cfg(target_feature = "sse4.1")]
98            {
99                let neq = _mm_xor_si128(self.0, other.0);
100                _mm_test_all_zeros(neq, neq) == 1
101            }
102        }
103    }
104}