hashbrown/control/group/
neon.rs1use super::super::{BitMask, Tag};
2use core::arch::aarch64 as neon;
3use core::mem;
4use core::num::NonZeroU64;
5
6pub(crate) type BitMaskWord = u64;
7pub(crate) type NonZeroBitMaskWord = NonZeroU64;
8pub(crate) const BITMASK_STRIDE: usize = 8;
9pub(crate) const BITMASK_MASK: BitMaskWord = !0;
10pub(crate) const BITMASK_ITER_MASK: BitMaskWord = 0x8080_8080_8080_8080;
11
12#[derive(Copy, Clone)]
17pub(crate) struct Group(neon::uint8x8_t);
18
19#[allow(clippy::use_self)]
20impl Group {
21 pub(crate) const WIDTH: usize = mem::size_of::<Self>();
23
24 #[inline]
29 pub(crate) const fn static_empty() -> &'static [Tag; Group::WIDTH] {
30 #[repr(C)]
31 struct AlignedTags {
32 _align: [Group; 0],
33 tags: [Tag; Group::WIDTH],
34 }
35 const ALIGNED_TAGS: AlignedTags = AlignedTags {
36 _align: [],
37 tags: [Tag::EMPTY; Group::WIDTH],
38 };
39 &ALIGNED_TAGS.tags
40 }
41
42 #[inline]
44 #[allow(clippy::cast_ptr_alignment)] pub(crate) unsafe fn load(ptr: *const Tag) -> Self {
46 Group(neon::vld1_u8(ptr.cast()))
47 }
48
49 #[inline]
52 #[allow(clippy::cast_ptr_alignment)]
53 pub(crate) unsafe fn load_aligned(ptr: *const Tag) -> Self {
54 debug_assert_eq!(ptr.align_offset(mem::align_of::<Self>()), 0);
55 Group(neon::vld1_u8(ptr.cast()))
56 }
57
58 #[inline]
61 #[allow(clippy::cast_ptr_alignment)]
62 pub(crate) unsafe fn store_aligned(self, ptr: *mut Tag) {
63 debug_assert_eq!(ptr.align_offset(mem::align_of::<Self>()), 0);
64 neon::vst1_u8(ptr.cast(), self.0);
65 }
66
67 #[inline]
70 pub(crate) fn match_tag(self, tag: Tag) -> BitMask {
71 unsafe {
72 let cmp = neon::vceq_u8(self.0, neon::vdup_n_u8(tag.0));
73 BitMask(neon::vget_lane_u64(neon::vreinterpret_u64_u8(cmp), 0))
74 }
75 }
76
77 #[inline]
80 pub(crate) fn match_empty(self) -> BitMask {
81 self.match_tag(Tag::EMPTY)
82 }
83
84 #[inline]
87 pub(crate) fn match_empty_or_deleted(self) -> BitMask {
88 unsafe {
89 let cmp = neon::vcltz_s8(neon::vreinterpret_s8_u8(self.0));
90 BitMask(neon::vget_lane_u64(neon::vreinterpret_u64_u8(cmp), 0))
91 }
92 }
93
94 #[inline]
96 pub(crate) fn match_full(self) -> BitMask {
97 unsafe {
98 let cmp = neon::vcgez_s8(neon::vreinterpret_s8_u8(self.0));
99 BitMask(neon::vget_lane_u64(neon::vreinterpret_u64_u8(cmp), 0))
100 }
101 }
102
103 #[inline]
108 pub(crate) fn convert_special_to_empty_and_full_to_deleted(self) -> Self {
109 unsafe {
117 let special = neon::vcltz_s8(neon::vreinterpret_s8_u8(self.0));
118 Group(neon::vorr_u8(special, neon::vdup_n_u8(0x80)))
119 }
120 }
121}