[go: up one dir, main page]

wide/
i32x16_.rs

1use super::*;
2
3pick! {
4  if #[cfg(target_feature="avx512f")] {
5    #[derive(Default, Clone, Copy, PartialEq, Eq)]
6    #[repr(C, align(64))]
7    pub struct i32x16 { pub(crate) avx512: m512i }
8  } else {
9    #[derive(Default, Clone, Copy, PartialEq, Eq)]
10    #[repr(C, align(64))]
11    pub struct i32x16 { pub(crate) a : i32x8, pub(crate) b : i32x8 }
12  }
13}
14
15int_uint_consts!(i32, 16, i32x16, 512);
16
17unsafe impl Zeroable for i32x16 {}
18unsafe impl Pod for i32x16 {}
19
20impl AlignTo for i32x16 {
21  type Elem = i32;
22}
23
24impl Add for i32x16 {
25  type Output = Self;
26  #[inline]
27  fn add(self, rhs: Self) -> Self::Output {
28    pick! {
29      if #[cfg(target_feature="avx512f")] {
30        Self { avx512: add_i32_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 i32x16 {
42  type Output = Self;
43  #[inline]
44  fn sub(self, rhs: Self) -> Self::Output {
45    pick! {
46      if #[cfg(target_feature="avx512f")] {
47        Self { avx512: sub_i32_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 i32x16 {
59  type Output = Self;
60  #[inline]
61  fn mul(self, rhs: Self) -> Self::Output {
62    pick! {
63      if #[cfg(target_feature="avx512f")] {
64        Self { avx512: mul_i32_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<i32> for i32x16 {
73  type Output = Self;
74  #[inline]
75  fn add(self, rhs: i32) -> Self::Output {
76    self.add(Self::splat(rhs))
77  }
78}
79
80impl Sub<i32> for i32x16 {
81  type Output = Self;
82  #[inline]
83  fn sub(self, rhs: i32) -> Self::Output {
84    self.sub(Self::splat(rhs))
85  }
86}
87
88impl Mul<i32> for i32x16 {
89  type Output = Self;
90  #[inline]
91  fn mul(self, rhs: i32) -> Self::Output {
92    self.mul(Self::splat(rhs))
93  }
94}
95
96impl Add<i32x16> for i32 {
97  type Output = i32x16;
98  #[inline]
99  fn add(self, rhs: i32x16) -> Self::Output {
100    i32x16::splat(self).add(rhs)
101  }
102}
103
104impl Sub<i32x16> for i32 {
105  type Output = i32x16;
106  #[inline]
107  fn sub(self, rhs: i32x16) -> Self::Output {
108    i32x16::splat(self).sub(rhs)
109  }
110}
111
112impl Mul<i32x16> for i32 {
113  type Output = i32x16;
114  #[inline]
115  fn mul(self, rhs: i32x16) -> Self::Output {
116    i32x16::splat(self).mul(rhs)
117  }
118}
119
120impl BitAnd for i32x16 {
121  type Output = Self;
122  #[inline]
123  fn bitand(self, rhs: Self) -> Self::Output {
124    pick! {
125      if #[cfg(target_feature="avx512f")] {
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 i32x16 {
138  type Output = Self;
139  #[inline]
140  fn bitor(self, rhs: Self) -> Self::Output {
141    pick! {
142    if #[cfg(target_feature="avx512f")] {
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 i32x16 {
155  type Output = Self;
156  #[inline]
157  fn bitxor(self, rhs: Self) -> Self::Output {
158    pick! {
159      if #[cfg(target_feature="avx512f")] {
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_i32x16 {
172  ($($shift_type:ty),+ $(,)?) => {
173    $(impl Shl<$shift_type> for i32x16 {
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="avx512f")] {
180            let shift = cast(rhs as u32);
181            Self { avx512: shl_all_u32_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_i32x16!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128);
194
195macro_rules! impl_shr_t_for_i32x16 {
196  ($($shift_type:ty),+ $(,)?) => {
197    $(impl Shr<$shift_type> for i32x16 {
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="avx512f")] {
204            let shift = cast(rhs as u32);
205            Self { avx512: shr_all_i32_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_i32x16!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128);
218
219impl CmpEq for i32x16 {
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 i32x16 {
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 i32x16 {
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 i32x16 {
244  #[inline]
245  #[must_use]
246  pub const fn new(array: [i32; 16]) -> Self {
247    unsafe { core::mem::transmute(array) }
248  }
249
250  #[inline]
251  #[must_use]
252  pub fn simd_eq(self, rhs: Self) -> Self {
253    pick! {
254      if #[cfg(target_feature="avx512f")] {
255        Self { avx512: cmp_op_mask_i32_m512i::<{cmp_int_op!(Eq)}>(self.avx512, rhs.avx512) }
256      } else {
257        Self {
258          a : self.a.simd_eq(rhs.a),
259          b : self.b.simd_eq(rhs.b),
260        }
261      }
262    }
263  }
264
265  #[inline]
266  #[must_use]
267  pub fn simd_gt(self, rhs: Self) -> Self {
268    pick! {
269      if #[cfg(target_feature="avx512f")] {
270        Self { avx512: cmp_op_mask_i32_m512i::<{cmp_int_op!(Nle)}>(self.avx512, rhs.avx512) }
271      } else {
272        Self {
273          a : self.a.simd_gt(rhs.a),
274          b : self.b.simd_gt(rhs.b),
275        }
276      }
277    }
278  }
279
280  #[inline]
281  #[must_use]
282  pub fn simd_lt(self, rhs: Self) -> Self {
283    pick! {
284      if #[cfg(target_feature="avx512f")] {
285        Self { avx512: cmp_op_mask_i32_m512i::<{cmp_int_op!(Lt)}>(self.avx512, rhs.avx512) }
286      } else {
287        Self {
288          a : rhs.a.simd_gt(self.a),
289          b : rhs.b.simd_gt(self.b),
290        }
291      }
292    }
293  }
294
295  #[inline]
296  #[must_use]
297  pub fn blend(self, t: Self, f: Self) -> Self {
298    pick! {
299      if #[cfg(target_feature="avx512f")] {
300        Self { avx512: blend_varying_i8_m512i(f.avx512,t.avx512,movepi8_mask_m512i(self.avx512)) }
301      } else {
302        Self {
303          a : self.a.blend(t.a, f.a),
304          b : self.b.blend(t.b, f.b),
305        }
306      }
307    }
308  }
309
310  #[inline]
311  #[must_use]
312  pub fn min(self, rhs: Self) -> Self {
313    pick! {
314      if #[cfg(target_feature="avx512f")] {
315        Self { avx512: min_i32_m512i(self.avx512, rhs.avx512) }
316      } else {
317        Self {
318          a: self.a.min(rhs.a),
319          b: self.b.min(rhs.b),
320        }
321      }
322    }
323  }
324
325  #[inline]
326  #[must_use]
327  pub fn max(self, rhs: Self) -> Self {
328    pick! {
329      if #[cfg(target_feature="avx512f")] {
330        Self { avx512: max_i32_m512i(self.avx512, rhs.avx512) }
331      } else {
332        Self {
333          a: self.a.max(rhs.a),
334          b: self.b.max(rhs.b),
335        }
336      }
337    }
338  }
339  
340  #[inline]
341  #[must_use]
342  pub fn to_bitmask(self) -> u32 {
343    pick! {
344      if #[cfg(target_feature="avx512dq")] {
345        movepi32_mask_m512i(self.avx512) as u32
346      } else {
347        self.a.to_bitmask() | (self.b.to_bitmask() << 8)
348      }
349    }
350  }
351
352  #[inline]
353  pub fn to_array(self) -> [i32; 16] {
354    cast(self)
355  }
356
357  #[inline]
358  pub fn as_array(&self) -> &[i32; 16] {
359    cast_ref(self)
360  }
361
362  #[inline]
363  pub fn as_mut_array(&mut self) -> &mut [i32; 16] {
364    cast_mut(self)
365  }
366
367  #[inline]
368  #[must_use]
369  pub fn round_float(self) -> f32x16 {
370    pick! {
371      if #[cfg(target_feature="avx512f")] {
372        cast(convert_to_m512_from_i32_m512i(self.avx512))
373      } else {
374        f32x16 {
375          a: self.a.round_float(),
376          b: self.b.round_float(),
377        }
378      }
379    }
380  }
381}
382
383impl Not for i32x16 {
384  type Output = Self;
385  #[inline]
386  fn not(self) -> Self::Output {
387    pick! {
388      if #[cfg(target_feature="avx512f")] {
389        Self { avx512: bitxor_m512i(self.avx512, set_splat_i32_m512i(-1)) }
390      } else {
391        Self {
392          a : self.a.not(),
393          b : self.b.not(),
394        }
395      }
396    }
397  }
398}