wide/
u16x32_.rs

1use super::*;
2
3pick! {
4  if #[cfg(target_feature="avx512bw")] {
5    #[derive(Default, Clone, Copy, PartialEq, Eq)]
6    #[repr(C, align(64))]
7    pub struct u16x32 { pub(crate) avx512: m512i }
8  } else {
9    #[derive(Default, Clone, Copy, PartialEq, Eq)]
10    #[repr(C, align(64))]
11    pub struct u16x32 { pub(crate) a : u16x16, pub(crate) b : u16x16 }
12  }
13}
14
15int_uint_consts!(u16, 32, u16x32, 512);
16
17unsafe impl Zeroable for u16x32 {}
18unsafe impl Pod for u16x32 {}
19
20impl AlignTo for u16x32 {
21  type Elem = u16;
22}
23
24impl Add for u16x32 {
25  type Output = Self;
26  #[inline]
27  fn add(self, rhs: Self) -> Self::Output {
28    pick! {
29      if #[cfg(target_feature="avx512bw")] {
30        Self { avx512: add_i16_m512i(self.avx512, rhs.avx512) }
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 u16x32 {
42  type Output = Self;
43  #[inline]
44  fn sub(self, rhs: Self) -> Self::Output {
45    pick! {
46      if #[cfg(target_feature="avx512bw")] {
47        Self { avx512: sub_i16_m512i(self.avx512, rhs.avx512) }
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 Mul for u16x32 {
59  type Output = Self;
60  #[inline]
61  fn mul(self, rhs: Self) -> Self::Output {
62    pick! {
63      if #[cfg(target_feature="avx512bw")] {
64        Self { avx512: mul_i16_keep_low_m512i(self.avx512, rhs.avx512) }
65      } else {
66        Self { a: self.a.mul(rhs.a), b: self.b.mul(rhs.b) }
67      }
68    }
69  }
70}
71
72impl Add<u16> for u16x32 {
73  type Output = Self;
74  #[inline]
75  fn add(self, rhs: u16) -> Self::Output {
76    self.add(Self::splat(rhs))
77  }
78}
79
80impl Sub<u16> for u16x32 {
81  type Output = Self;
82  #[inline]
83  fn sub(self, rhs: u16) -> Self::Output {
84    self.sub(Self::splat(rhs))
85  }
86}
87
88impl Mul<u16> for u16x32 {
89  type Output = Self;
90  #[inline]
91  fn mul(self, rhs: u16) -> Self::Output {
92    self.mul(Self::splat(rhs))
93  }
94}
95
96impl Add<u16x32> for u16 {
97  type Output = u16x32;
98  #[inline]
99  fn add(self, rhs: u16x32) -> Self::Output {
100    u16x32::splat(self).add(rhs)
101  }
102}
103
104impl Sub<u16x32> for u16 {
105  type Output = u16x32;
106  #[inline]
107  fn sub(self, rhs: u16x32) -> Self::Output {
108    u16x32::splat(self).sub(rhs)
109  }
110}
111
112impl Mul<u16x32> for u16 {
113  type Output = u16x32;
114  #[inline]
115  fn mul(self, rhs: u16x32) -> Self::Output {
116    u16x32::splat(self).mul(rhs)
117  }
118}
119
120impl BitAnd for u16x32 {
121  type Output = Self;
122  #[inline]
123  fn bitand(self, rhs: Self) -> Self::Output {
124    pick! {
125      if #[cfg(target_feature="avx512bw")] {
126        Self { avx512: bitand_m512i(self.avx512, rhs.avx512) }
127      } else {
128        Self {
129          a : self.a.bitand(rhs.a),
130          b : self.b.bitand(rhs.b),
131        }
132      }
133    }
134  }
135}
136
137impl BitOr for u16x32 {
138  type Output = Self;
139  #[inline]
140  fn bitor(self, rhs: Self) -> Self::Output {
141    pick! {
142    if #[cfg(target_feature="avx512bw")] {
143        Self { avx512: bitor_m512i(self.avx512, rhs.avx512) }
144      } else {
145        Self {
146          a : self.a.bitor(rhs.a),
147          b : self.b.bitor(rhs.b),
148        }
149      }
150    }
151  }
152}
153
154impl BitXor for u16x32 {
155  type Output = Self;
156  #[inline]
157  fn bitxor(self, rhs: Self) -> Self::Output {
158    pick! {
159      if #[cfg(target_feature="avx512bw")] {
160        Self { avx512: bitxor_m512i(self.avx512, rhs.avx512) }
161      } else {
162        Self {
163          a : self.a.bitxor(rhs.a),
164          b : self.b.bitxor(rhs.b),
165        }
166      }
167    }
168  }
169}
170
171macro_rules! impl_shl_t_for_u16x32 {
172  ($($shift_type:ty),+ $(,)?) => {
173    $(impl Shl<$shift_type> for u16x32 {
174      type Output = Self;
175      /// Shifts all lanes by the value given.
176      #[inline]
177      fn shl(self, rhs: $shift_type) -> Self::Output {
178        pick! {
179          if #[cfg(target_feature="avx512bw")] {
180            let shift = cast(rhs as u16);
181            Self { avx512: shl_all_u16_m512i(self.avx512, shift) }
182          } else {
183            Self {
184              a : self.a.shl(rhs),
185              b : self.b.shl(rhs),
186            }
187          }
188        }
189      }
190    })+
191  };
192}
193impl_shl_t_for_u16x32!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128);
194
195macro_rules! impl_shr_t_for_u16x32 {
196  ($($shift_type:ty),+ $(,)?) => {
197    $(impl Shr<$shift_type> for u16x32 {
198      type Output = Self;
199      /// Shifts all lanes by the value given.
200      #[inline]
201      fn shr(self, rhs: $shift_type) -> Self::Output {
202        pick! {
203          if #[cfg(target_feature="avx512bw")] {
204            let shift = cast(rhs as u16);
205            Self { avx512: shr_all_u16_m512i(self.avx512, shift) }
206          } else {
207            Self {
208              a : self.a.shr(rhs),
209              b : self.b.shr(rhs),
210            }
211          }
212        }
213      }
214    })+
215  };
216}
217impl_shr_t_for_u16x32!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128);
218
219impl CmpEq for u16x32 {
220  type Output = Self;
221  #[inline]
222  fn simd_eq(self, rhs: Self) -> Self::Output {
223    Self::simd_eq(self, rhs)
224  }
225}
226
227impl CmpLt for u16x32 {
228  type Output = Self;
229  #[inline]
230  fn simd_lt(self, rhs: Self) -> Self::Output {
231    Self::simd_lt(self, rhs)
232  }
233}
234
235impl CmpGt for u16x32 {
236  type Output = Self;
237  #[inline]
238  fn simd_gt(self, rhs: Self) -> Self::Output {
239    Self::simd_gt(self, rhs)
240  }
241}
242
243impl Not for u16x32 {
244  type Output = Self;
245  #[inline]
246  fn not(self) -> Self::Output {
247    pick! {
248      if #[cfg(target_feature="avx512bw")] {
249        Self { avx512: bitxor_m512i(self.avx512, set_splat_i16_m512i(-1)) }
250      } else {
251        Self {
252          a : self.a.not(),
253          b : self.b.not(),
254        }
255      }
256    }
257  }
258}
259
260impl u16x32 {
261  #[inline]
262  #[must_use]
263  pub const fn new(array: [u16; 32]) -> Self {
264    unsafe { core::mem::transmute(array) }
265  }
266
267  #[inline]
268  #[must_use]
269  pub fn simd_eq(self, rhs: Self) -> Self {
270    pick! {
271      if #[cfg(target_feature="avx512bw")] {
272        Self { avx512: cmp_op_mask_u16_m512i::<{cmp_int_op!(Eq)}>(self.avx512, rhs.avx512) }
273      } else {
274        Self {
275          a : self.a.simd_eq(rhs.a),
276          b : self.b.simd_eq(rhs.b),
277        }
278      }
279    }
280  }
281
282  #[inline]
283  #[must_use]
284  pub fn simd_gt(self, rhs: Self) -> Self {
285    pick! {
286      if #[cfg(target_feature="avx512bw")] {
287        Self { avx512: cmp_op_mask_u16_m512i::<{cmp_int_op!(Nle)}>(self.avx512, rhs.avx512) }
288      } else {
289        Self {
290          a : self.a.simd_gt(rhs.a),
291          b : self.b.simd_gt(rhs.b),
292        }
293      }
294    }
295  }
296
297  #[inline]
298  #[must_use]
299  pub fn simd_lt(self, rhs: Self) -> Self {
300    pick! {
301      if #[cfg(target_feature="avx512bw")] {
302        Self { avx512: cmp_op_mask_u16_m512i::<{cmp_int_op!(Lt)}>(self.avx512, rhs.avx512) }
303      } else {
304        Self {
305          a : rhs.a.simd_gt(self.a),
306          b : rhs.b.simd_gt(self.b),
307        }
308      }
309    }
310  }
311
312  #[inline]
313  #[must_use]
314  pub fn blend(self, t: Self, f: Self) -> Self {
315    pick! {
316      if #[cfg(target_feature="avx512bw")] {
317        Self { avx512: blend_varying_i8_m512i(f.avx512,t.avx512,movepi8_mask_m512i(self.avx512)) }
318      } else {
319        Self {
320          a : self.a.blend(t.a, f.a),
321          b : self.b.blend(t.b, f.b),
322        }
323      }
324    }
325  }
326
327  #[inline]
328  #[must_use]
329  pub fn min(self, rhs: Self) -> Self {
330    pick! {
331      if #[cfg(target_feature="avx512bw")] {
332        Self { avx512: min_u16_m512i(self.avx512, rhs.avx512) }
333      } else {
334        Self {
335          a: self.a.min(rhs.a),
336          b: self.b.min(rhs.b),
337        }
338      }
339    }
340  }
341
342  #[inline]
343  #[must_use]
344  pub fn max(self, rhs: Self) -> Self {
345    pick! {
346      if #[cfg(target_feature="avx512bw")] {
347        Self { avx512: max_u16_m512i(self.avx512, rhs.avx512) }
348      } else {
349        Self {
350          a: self.a.max(rhs.a),
351          b: self.b.max(rhs.b),
352        }
353      }
354    }
355  }
356
357  #[inline]
358  #[must_use]
359  pub fn saturating_add(self, rhs: Self) -> Self {
360    pick! {
361      if #[cfg(target_feature="avx512bw")] {
362        Self { avx512: add_saturating_u16_m512i(self.avx512, rhs.avx512) }
363      } else {
364        Self {
365          a: self.a.saturating_add(rhs.a),
366          b: self.b.saturating_add(rhs.b),
367        }
368      }
369    }
370  }
371
372  #[inline]
373  #[must_use]
374  pub fn saturating_sub(self, rhs: Self) -> Self {
375    pick! {
376      if #[cfg(target_feature="avx512bw")] {
377        Self { avx512: sub_saturating_u16_m512i(self.avx512, rhs.avx512) }
378      } else {
379        Self {
380          a: self.a.saturating_sub(rhs.a),
381          b: self.b.saturating_sub(rhs.b),
382        }
383      }
384    }
385  }
386
387  #[inline]
388  #[must_use]
389  #[doc(alias("movemask", "move_mask"))]
390  pub fn to_bitmask(self) -> u32 {
391    i16x32::to_bitmask(cast(self))
392  }
393
394  #[inline]
395  pub fn to_array(self) -> [u16; 32] {
396    cast(self)
397  }
398
399  #[inline]
400  pub fn as_array(&self) -> &[u16; 32] {
401    cast_ref(self)
402  }
403
404  #[inline]
405  pub fn as_mut_array(&mut self) -> &mut [u16; 32] {
406    cast_mut(self)
407  }
408}