1 // Generated from vec_mask.rs.tera template. Edit the template, not the generated file.
2
3 use core::fmt;
4 use core::ops::*;
5
6 use core::arch::aarch64::*;
7
8 #[repr(C)]
9 union UnionCast {
10 a: [u32; 4],
11 v: BVec4A,
12 }
13
14 /// Creates a 4-dimensional `bool` vector mask.
15 #[inline(always)]
16 #[must_use]
bvec4a(x: bool, y: bool, z: bool, w: bool) -> BVec4A17 pub const fn bvec4a(x: bool, y: bool, z: bool, w: bool) -> BVec4A {
18 BVec4A::new(x, y, z, w)
19 }
20
21 /// A 4-dimensional SIMD vector mask.
22 ///
23 /// This type is 16 byte aligned.
24 #[derive(Clone, Copy)]
25 #[repr(transparent)]
26 pub struct BVec4A(pub(crate) uint32x4_t);
27
28 const MASK: [u32; 2] = [0, 0xff_ff_ff_ff];
29
30 impl BVec4A {
31 /// All false.
32 pub const FALSE: Self = Self::splat(false);
33
34 /// All true.
35 pub const TRUE: Self = Self::splat(true);
36
37 /// Creates a new vector mask.
38 #[inline(always)]
39 #[must_use]
new(x: bool, y: bool, z: bool, w: bool) -> Self40 pub const fn new(x: bool, y: bool, z: bool, w: bool) -> Self {
41 unsafe {
42 UnionCast {
43 a: [
44 MASK[x as usize],
45 MASK[y as usize],
46 MASK[z as usize],
47 MASK[w as usize],
48 ],
49 }
50 .v
51 }
52 }
53
54 /// Creates a vector mask with all elements set to `v`.
55 #[inline]
56 #[must_use]
splat(v: bool) -> Self57 pub const fn splat(v: bool) -> Self {
58 Self::new(v, v, v, v)
59 }
60
61 /// Creates a new vector mask from a bool array.
62 #[inline]
63 #[must_use]
from_array(a: [bool; 4]) -> Self64 pub const fn from_array(a: [bool; 4]) -> Self {
65 Self::new(a[0], a[1], a[2], a[3])
66 }
67
68 /// Returns a bitmask with the lowest 4 bits set from the elements of `self`.
69 ///
70 /// A true element results in a `1` bit and a false element in a `0` bit. Element `x` goes
71 /// into the first lowest bit, element `y` into the second, etc.
72 #[inline]
73 #[must_use]
bitmask(self) -> u3274 pub fn bitmask(self) -> u32 {
75 unsafe {
76 let mma = vandq_u32(self.0, vld1q_u32([1, 2, 4, 8].as_ptr())); // [0 1 2 3]
77 let mmb = vextq_u32(mma, mma, 2); // [2 3 0 1]
78 let mmc = vorrq_u32(mma, mmb); // [0+2 1+3 0+2 1+3]
79 let mmd = vextq_u32(mmc, mmc, 3); // [1+3 0+2 1+3 0+2]
80 let mme = vorrq_u32(mmc, mmd); // [0+1+2+3 ...]
81 vgetq_lane_u32(mme, 0)
82 }
83 }
84
85 /// Returns true if any of the elements are true, false otherwise.
86 #[inline]
87 #[must_use]
any(self) -> bool88 pub fn any(self) -> bool {
89 self.bitmask() != 0
90 }
91
92 /// Returns true if all the elements are true, false otherwise.
93 #[inline]
94 #[must_use]
all(self) -> bool95 pub fn all(self) -> bool {
96 self.bitmask() == 0xf
97 }
98
99 /// Tests the value at `index`.
100 ///
101 /// Panics if `index` is greater than 3.
102 #[inline]
103 #[must_use]
test(&self, index: usize) -> bool104 pub fn test(&self, index: usize) -> bool {
105 match index {
106 0 => (self.bitmask() & (1 << 0)) != 0,
107 1 => (self.bitmask() & (1 << 1)) != 0,
108 2 => (self.bitmask() & (1 << 2)) != 0,
109 3 => (self.bitmask() & (1 << 3)) != 0,
110 _ => panic!("index out of bounds"),
111 }
112 }
113
114 /// Sets the element at `index`.
115 ///
116 /// Panics if `index` is greater than 3.
117 #[inline]
set(&mut self, index: usize, value: bool)118 pub fn set(&mut self, index: usize, value: bool) {
119 self.0 = match index {
120 0 => unsafe { vsetq_lane_u32(MASK[value as usize], self.0, 0) },
121 1 => unsafe { vsetq_lane_u32(MASK[value as usize], self.0, 1) },
122 2 => unsafe { vsetq_lane_u32(MASK[value as usize], self.0, 2) },
123 3 => unsafe { vsetq_lane_u32(MASK[value as usize], self.0, 3) },
124 _ => panic!("index out of bounds"),
125 }
126 }
127
128 #[inline]
129 #[must_use]
into_bool_array(self) -> [bool; 4]130 fn into_bool_array(self) -> [bool; 4] {
131 let bitmask = self.bitmask();
132 [
133 (bitmask & 1) != 0,
134 (bitmask & 2) != 0,
135 (bitmask & 4) != 0,
136 (bitmask & 8) != 0,
137 ]
138 }
139
140 #[inline]
141 #[must_use]
into_u32_array(self) -> [u32; 4]142 fn into_u32_array(self) -> [u32; 4] {
143 let bitmask = self.bitmask();
144 [
145 MASK[(bitmask & 1) as usize],
146 MASK[((bitmask >> 1) & 1) as usize],
147 MASK[((bitmask >> 2) & 1) as usize],
148 MASK[((bitmask >> 3) & 1) as usize],
149 ]
150 }
151 }
152
153 impl Default for BVec4A {
154 #[inline]
default() -> Self155 fn default() -> Self {
156 Self::FALSE
157 }
158 }
159
160 impl PartialEq for BVec4A {
161 #[inline]
eq(&self, rhs: &Self) -> bool162 fn eq(&self, rhs: &Self) -> bool {
163 self.bitmask().eq(&rhs.bitmask())
164 }
165 }
166
167 impl Eq for BVec4A {}
168
169 impl core::hash::Hash for BVec4A {
170 #[inline]
hash<H: core::hash::Hasher>(&self, state: &mut H)171 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
172 self.bitmask().hash(state);
173 }
174 }
175
176 impl BitAnd for BVec4A {
177 type Output = Self;
178 #[inline]
bitand(self, rhs: Self) -> Self179 fn bitand(self, rhs: Self) -> Self {
180 Self(unsafe { vandq_u32(self.0, rhs.0) })
181 }
182 }
183
184 impl BitAndAssign for BVec4A {
185 #[inline]
bitand_assign(&mut self, rhs: Self)186 fn bitand_assign(&mut self, rhs: Self) {
187 *self = self.bitand(rhs);
188 }
189 }
190
191 impl BitOr for BVec4A {
192 type Output = Self;
193 #[inline]
bitor(self, rhs: Self) -> Self194 fn bitor(self, rhs: Self) -> Self {
195 Self(unsafe { vorrq_u32(self.0, rhs.0) })
196 }
197 }
198
199 impl BitOrAssign for BVec4A {
200 #[inline]
bitor_assign(&mut self, rhs: Self)201 fn bitor_assign(&mut self, rhs: Self) {
202 *self = self.bitor(rhs);
203 }
204 }
205
206 impl BitXor for BVec4A {
207 type Output = Self;
208 #[inline]
bitxor(self, rhs: Self) -> Self209 fn bitxor(self, rhs: Self) -> Self {
210 Self(unsafe { veorq_u32(self.0, rhs.0) })
211 }
212 }
213
214 impl BitXorAssign for BVec4A {
215 #[inline]
bitxor_assign(&mut self, rhs: Self)216 fn bitxor_assign(&mut self, rhs: Self) {
217 *self = self.bitxor(rhs);
218 }
219 }
220
221 impl Not for BVec4A {
222 type Output = Self;
223 #[inline]
not(self) -> Self224 fn not(self) -> Self {
225 Self(unsafe { vmvnq_u32(self.0) })
226 }
227 }
228
229 impl From<BVec4A> for uint32x4_t {
230 #[inline]
from(t: BVec4A) -> Self231 fn from(t: BVec4A) -> Self {
232 t.0
233 }
234 }
235
236 impl fmt::Debug for BVec4A {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result237 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
238 let arr = self.into_u32_array();
239 write!(
240 f,
241 "{}({:#x}, {:#x}, {:#x}, {:#x})",
242 stringify!(BVec4A),
243 arr[0],
244 arr[1],
245 arr[2],
246 arr[3]
247 )
248 }
249 }
250
251 impl fmt::Display for BVec4A {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result252 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
253 let arr = self.into_bool_array();
254 write!(f, "[{}, {}, {}, {}]", arr[0], arr[1], arr[2], arr[3])
255 }
256 }
257
258 impl From<[bool; 4]> for BVec4A {
259 #[inline]
from(a: [bool; 4]) -> Self260 fn from(a: [bool; 4]) -> Self {
261 Self::from_array(a)
262 }
263 }
264
265 impl From<BVec4A> for [bool; 4] {
266 #[inline]
from(mask: BVec4A) -> Self267 fn from(mask: BVec4A) -> Self {
268 mask.into_bool_array()
269 }
270 }
271
272 impl From<BVec4A> for [u32; 4] {
273 #[inline]
from(mask: BVec4A) -> Self274 fn from(mask: BVec4A) -> Self {
275 mask.into_u32_array()
276 }
277 }
278