1use super::*;
2
3pick! {
4 if #[cfg(target_feature="avx2")] {
5 #[derive(Default, Clone, Copy, PartialEq, Eq)]
6 #[repr(C, align(32))]
7 pub struct i8x32 { avx: m256i }
8 } else {
9 #[derive(Default, Clone, Copy, PartialEq, Eq)]
10 #[repr(C, align(32))]
11 pub struct i8x32 { a : i8x16, b : i8x16 }
12 }
13}
14
15int_uint_consts!(i8, 32, i8x32, 256);
16
17unsafe impl Zeroable for i8x32 {}
18unsafe impl Pod for i8x32 {}
19
20impl Add for i8x32 {
21 type Output = Self;
22 #[inline]
23 #[must_use]
24 fn add(self, rhs: Self) -> Self::Output {
25 pick! {
26 if #[cfg(target_feature="avx2")] {
27 Self { avx: add_i8_m256i(self.avx,rhs.avx) }
28 } else {
29 Self {
30 a : self.a.add(rhs.a),
31 b : self.b.add(rhs.b),
32 }
33 }
34 }
35 }
36}
37
38impl Sub for i8x32 {
39 type Output = Self;
40 #[inline]
41 #[must_use]
42 fn sub(self, rhs: Self) -> Self::Output {
43 pick! {
44 if #[cfg(target_feature="avx2")] {
45 Self { avx: sub_i8_m256i(self.avx,rhs.avx) }
46 } else {
47 Self {
48 a : self.a.sub(rhs.a),
49 b : self.b.sub(rhs.b),
50 }
51 }
52 }
53 }
54}
55
56impl Add<i8> for i8x32 {
57 type Output = Self;
58 #[inline]
59 #[must_use]
60 fn add(self, rhs: i8) -> Self::Output {
61 self.add(Self::splat(rhs))
62 }
63}
64
65impl Sub<i8> for i8x32 {
66 type Output = Self;
67 #[inline]
68 #[must_use]
69 fn sub(self, rhs: i8) -> Self::Output {
70 self.sub(Self::splat(rhs))
71 }
72}
73
74impl Add<i8x32> for i8 {
75 type Output = i8x32;
76 #[inline]
77 #[must_use]
78 fn add(self, rhs: i8x32) -> Self::Output {
79 i8x32::splat(self).add(rhs)
80 }
81}
82
83impl Sub<i8x32> for i8 {
84 type Output = i8x32;
85 #[inline]
86 #[must_use]
87 fn sub(self, rhs: i8x32) -> Self::Output {
88 i8x32::splat(self).sub(rhs)
89 }
90}
91
92impl BitAnd for i8x32 {
93 type Output = Self;
94 #[inline]
95 #[must_use]
96 fn bitand(self, rhs: Self) -> Self::Output {
97 pick! {
98 if #[cfg(target_feature="avx2")] {
99 Self { avx : bitand_m256i(self.avx,rhs.avx) }
100 } else {
101 Self {
102 a : self.a.bitand(rhs.a),
103 b : self.b.bitand(rhs.b),
104 }
105 }
106 }
107 }
108}
109
110impl BitOr for i8x32 {
111 type Output = Self;
112 #[inline]
113 #[must_use]
114 fn bitor(self, rhs: Self) -> Self::Output {
115 pick! {
116 if #[cfg(target_feature="avx2")] {
117 Self { avx : bitor_m256i(self.avx,rhs.avx) }
118 } else {
119 Self {
120 a : self.a.bitor(rhs.a),
121 b : self.b.bitor(rhs.b),
122 }
123 }
124 }
125 }
126}
127
128impl BitXor for i8x32 {
129 type Output = Self;
130 #[inline]
131 #[must_use]
132 fn bitxor(self, rhs: Self) -> Self::Output {
133 pick! {
134 if #[cfg(target_feature="avx2")] {
135 Self { avx : bitxor_m256i(self.avx,rhs.avx) }
136 } else {
137 Self {
138 a : self.a.bitxor(rhs.a),
139 b : self.b.bitxor(rhs.b),
140 }
141 }
142 }
143 }
144}
145
146impl CmpEq for i8x32 {
147 type Output = Self;
148 #[inline]
149 #[must_use]
150 fn cmp_eq(self, rhs: Self) -> Self::Output {
151 pick! {
152 if #[cfg(target_feature="avx2")] {
153 Self { avx : cmp_eq_mask_i8_m256i(self.avx,rhs.avx) }
154 } else {
155 Self {
156 a : self.a.cmp_eq(rhs.a),
157 b : self.b.cmp_eq(rhs.b),
158 }
159 }
160 }
161 }
162}
163
164impl CmpGt for i8x32 {
165 type Output = Self;
166 #[inline]
167 #[must_use]
168 fn cmp_gt(self, rhs: Self) -> Self::Output {
169 pick! {
170 if #[cfg(target_feature="avx2")] {
171 Self { avx : cmp_gt_mask_i8_m256i(self.avx,rhs.avx) }
172 } else {
173 Self {
174 a : self.a.cmp_gt(rhs.a),
175 b : self.b.cmp_gt(rhs.b),
176 }
177 }
178 }
179 }
180}
181
182impl CmpLt for i8x32 {
183 type Output = Self;
184 #[inline]
185 #[must_use]
186 fn cmp_lt(self, rhs: Self) -> Self::Output {
187 rhs.cmp_gt(self)
188 }
189}
190
191impl Not for i8x32 {
192 type Output = Self;
193 #[inline]
194 fn not(self) -> Self {
195 pick! {
196 if #[cfg(target_feature="avx2")] {
197 Self { avx: self.avx.not() }
198 } else {
199 Self {
200 a : self.a.not(),
201 b : self.b.not(),
202 }
203 }
204 }
205 }
206}
207
208impl i8x32 {
209 #[inline]
210 #[must_use]
211 pub const fn new(array: [i8; 32]) -> Self {
212 unsafe { core::mem::transmute(array) }
213 }
214 #[inline]
215 #[must_use]
216 pub fn blend(self, t: Self, f: Self) -> Self {
217 pick! {
218 if #[cfg(target_feature="avx2")] {
219 Self { avx: blend_varying_i8_m256i(f.avx, t.avx, self.avx) }
220 } else {
221 Self {
222 a : self.a.blend(t.a, f.a),
223 b : self.b.blend(t.b, f.b),
224 }
225 }
226 }
227 }
228 #[inline]
229 #[must_use]
230 pub fn abs(self) -> Self {
231 pick! {
232 if #[cfg(target_feature="avx2")] {
233 Self { avx: abs_i8_m256i(self.avx) }
234 } else {
235 Self {
236 a : self.a.abs(),
237 b : self.b.abs(),
238 }
239 }
240 }
241 }
242
243 #[inline]
244 #[must_use]
245 pub fn unsigned_abs(self) -> u8x32 {
246 pick! {
247 if #[cfg(target_feature="avx2")] {
248 u8x32 { avx: abs_i8_m256i(self.avx) }
249 } else {
250 u8x32 {
251 a : self.a.unsigned_abs(),
252 b : self.b.unsigned_abs(),
253 }
254 }
255 }
256 }
257
258 #[inline]
259 #[must_use]
260 pub fn max(self, rhs: Self) -> Self {
261 pick! {
262 if #[cfg(target_feature="avx2")] {
263 Self { avx: max_i8_m256i(self.avx,rhs.avx) }
264 } else {
265 Self {
266 a : self.a.max(rhs.a),
267 b : self.b.max(rhs.b),
268 }
269 }
270 }
271 }
272 #[inline]
273 #[must_use]
274 pub fn min(self, rhs: Self) -> Self {
275 pick! {
276 if #[cfg(target_feature="avx2")] {
277 Self { avx: min_i8_m256i(self.avx,rhs.avx) }
278 } else {
279 Self {
280 a : self.a.min(rhs.a),
281 b : self.b.min(rhs.b),
282 }
283 }
284 }
285 }
286
287 #[inline]
288 #[must_use]
289 pub fn saturating_add(self, rhs: Self) -> Self {
290 pick! {
291 if #[cfg(target_feature="avx2")] {
292 Self { avx: add_saturating_i8_m256i(self.avx, rhs.avx) }
293 } else {
294 Self {
295 a : self.a.saturating_add(rhs.a),
296 b : self.b.saturating_add(rhs.b),
297 }
298 }
299 }
300 }
301 #[inline]
302 #[must_use]
303 pub fn saturating_sub(self, rhs: Self) -> Self {
304 pick! {
305 if #[cfg(target_feature="avx2")] {
306 Self { avx: sub_saturating_i8_m256i(self.avx, rhs.avx) }
307 } else {
308 Self {
309 a : self.a.saturating_sub(rhs.a),
310 b : self.b.saturating_sub(rhs.b),
311 }
312 }
313 }
314 }
315
316 #[inline]
317 #[must_use]
318 pub fn move_mask(self) -> i32 {
319 pick! {
320 if #[cfg(target_feature="avx2")] {
321 move_mask_i8_m256i(self.avx)
322 } else {
323 self.a.move_mask() | (self.b.move_mask() << 16)
324 }
325 }
326 }
327
328 #[inline]
329 #[must_use]
330 pub fn any(self) -> bool {
331 pick! {
332 if #[cfg(target_feature="avx2")] {
333 move_mask_i8_m256i(self.avx) != 0
334 } else {
335 (self.a | self.b).any()
336 }
337 }
338 }
339
340 #[inline]
341 #[must_use]
342 pub fn all(self) -> bool {
343 pick! {
344 if #[cfg(target_feature="avx2")] {
345 move_mask_i8_m256i(self.avx) == -1
346 } else {
347 (self.a & self.b).all()
348 }
349 }
350 }
351
352 #[inline]
353 #[must_use]
354 pub fn none(self) -> bool {
355 !self.any()
356 }
357
358 #[inline]
367 pub fn swizzle_half(self, rhs: i8x32) -> i8x32 {
368 pick! {
369 if #[cfg(target_feature="avx2")] {
370 Self { avx: shuffle_av_i8z_half_m256i(self.avx, rhs.saturating_add(i8x32::splat(0x60)).avx) }
371 } else {
372 Self {
373 a : self.a.swizzle(rhs.a),
374 b : self.b.swizzle(rhs.b),
375 }
376 }
377 }
378 }
379
380 #[inline]
390 pub fn swizzle_half_relaxed(self, rhs: i8x32) -> i8x32 {
391 pick! {
392 if #[cfg(target_feature="avx2")] {
393 Self { avx: shuffle_av_i8z_half_m256i(self.avx, rhs.avx) }
394 } else {
395 Self {
396 a : self.a.swizzle_relaxed(rhs.a),
397 b : self.b.swizzle_relaxed(rhs.b),
398 }
399 }
400 }
401 }
402
403 #[inline]
404 pub fn to_array(self) -> [i8; 32] {
405 cast(self)
406 }
407
408 #[inline]
409 pub fn as_array_ref(&self) -> &[i8; 32] {
410 cast_ref(self)
411 }
412
413 #[inline]
414 pub fn as_array_mut(&mut self) -> &mut [i8; 32] {
415 cast_mut(self)
416 }
417}