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