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 pick! {
188 if #[cfg(target_feature="avx2")] {
189 Self { avx : !(cmp_gt_mask_i8_m256i(self.avx,rhs.avx) ^ cmp_eq_mask_i8_m256i(self.avx,rhs.avx)) }
190 } else {
191 Self {
192 a : self.a.cmp_lt(rhs.a),
193 b : self.b.cmp_lt(rhs.b),
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::intrinsics::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 #[inline]
235 #[must_use]
236 pub fn max(self, rhs: Self) -> Self {
237 pick! {
238 if #[cfg(target_feature="avx2")] {
239 Self { avx: max_i8_m256i(self.avx,rhs.avx) }
240 } else {
241 Self {
242 a : self.a.max(rhs.a),
243 b : self.b.max(rhs.b),
244 }
245 }
246 }
247 }
248 #[inline]
249 #[must_use]
250 pub fn min(self, rhs: Self) -> Self {
251 pick! {
252 if #[cfg(target_feature="avx2")] {
253 Self { avx: min_i8_m256i(self.avx,rhs.avx) }
254 } else {
255 Self {
256 a : self.a.min(rhs.a),
257 b : self.b.min(rhs.b),
258 }
259 }
260 }
261 }
262
263 #[inline]
264 #[must_use]
265 pub fn saturating_add(self, rhs: Self) -> Self {
266 pick! {
267 if #[cfg(target_feature="avx2")] {
268 Self { avx: add_saturating_i8_m256i(self.avx, rhs.avx) }
269 } else {
270 Self {
271 a : self.a.saturating_add(rhs.a),
272 b : self.b.saturating_add(rhs.b),
273 }
274 }
275 }
276 }
277 #[inline]
278 #[must_use]
279 pub fn saturating_sub(self, rhs: Self) -> Self {
280 pick! {
281 if #[cfg(target_feature="avx2")] {
282 Self { avx: sub_saturating_i8_m256i(self.avx, rhs.avx) }
283 } else {
284 Self {
285 a : self.a.saturating_sub(rhs.a),
286 b : self.b.saturating_sub(rhs.b),
287 }
288 }
289 }
290 }
291
292 #[inline]
293 #[must_use]
294 pub fn move_mask(self) -> i32 {
295 pick! {
296 if #[cfg(target_feature="avx2")] {
297 move_mask_i8_m256i(self.avx)
298 } else {
299 self.a.move_mask() | (self.b.move_mask() << 16)
300 }
301 }
302 }
303
304 #[inline]
305 #[must_use]
306 pub fn any(self) -> bool {
307 pick! {
308 if #[cfg(target_feature="avx2")] {
309 move_mask_i8_m256i(self.avx) != 0
310 } else {
311 (self.a | self.b).any()
312 }
313 }
314 }
315
316 #[inline]
317 #[must_use]
318 pub fn all(self) -> bool {
319 pick! {
320 if #[cfg(target_feature="avx2")] {
321 move_mask_i8_m256i(self.avx) == -1
322 } else {
323 (self.a & self.b).all()
324 }
325 }
326 }
327
328 #[inline]
329 #[must_use]
330 pub fn none(self) -> bool {
331 !self.any()
332 }
333
334 #[inline]
343 pub fn swizzle_half(self, rhs: i8x32) -> i8x32 {
344 pick! {
345 if #[cfg(target_feature="avx2")] {
346 Self { avx: shuffle_av_i8z_half_m256i(self.avx, rhs.saturating_add(i8x32::splat(0x60)).avx) }
347 } else {
348 Self {
349 a : self.a.swizzle(rhs.a),
350 b : self.b.swizzle(rhs.b),
351 }
352 }
353 }
354 }
355
356 #[inline]
366 pub fn swizzle_half_relaxed(self, rhs: i8x32) -> i8x32 {
367 pick! {
368 if #[cfg(target_feature="avx2")] {
369 Self { avx: shuffle_av_i8z_half_m256i(self.avx, rhs.avx) }
370 } else {
371 Self {
372 a : self.a.swizzle_relaxed(rhs.a),
373 b : self.b.swizzle_relaxed(rhs.b),
374 }
375 }
376 }
377 }
378
379 #[inline]
380 pub fn to_array(self) -> [i8; 32] {
381 cast(self)
382 }
383
384 #[inline]
385 pub fn as_array_ref(&self) -> &[i8; 32] {
386 cast_ref(self)
387 }
388
389 #[inline]
390 pub fn as_array_mut(&mut self) -> &mut [i8; 32] {
391 cast_mut(self)
392 }
393}