fearless_simd/core_arch/x86/
avx2.rs

1// Copyright 2024 the Fearless_SIMD Authors
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3
4#![expect(
5    clippy::missing_safety_doc,
6    reason = "TODO: https://github.com/linebender/fearless_simd/issues/40"
7)]
8
9//! Access to AVX2 intrinsics.
10
11use crate::impl_macros::delegate;
12#[cfg(target_arch = "x86")]
13use core::arch::x86 as arch;
14#[cfg(target_arch = "x86_64")]
15use core::arch::x86_64 as arch;
16
17use arch::*;
18
19/// A token for AVX2 intrinsics on `x86` and `x86_64`.
20#[derive(Clone, Copy, Debug)]
21pub struct Avx2 {
22    _private: (),
23}
24
25impl Avx2 {
26    /// Create a SIMD token.
27    ///
28    /// # Safety
29    ///
30    /// The required CPU features must be available.
31    pub unsafe fn new_unchecked() -> Self {
32        Self { _private: () }
33    }
34
35    delegate! { arch:
36        fn _mm256_abs_epi32(a: __m256i) -> __m256i;
37        fn _mm256_abs_epi16(a: __m256i) -> __m256i;
38        fn _mm256_abs_epi8(a: __m256i) -> __m256i;
39        fn _mm256_add_epi64(a: __m256i, b: __m256i) -> __m256i;
40        fn _mm256_add_epi32(a: __m256i, b: __m256i) -> __m256i;
41        fn _mm256_add_epi16(a: __m256i, b: __m256i) -> __m256i;
42        fn _mm256_add_epi8(a: __m256i, b: __m256i) -> __m256i;
43        fn _mm256_adds_epi8(a: __m256i, b: __m256i) -> __m256i;
44        fn _mm256_adds_epi16(a: __m256i, b: __m256i) -> __m256i;
45        fn _mm256_adds_epu8(a: __m256i, b: __m256i) -> __m256i;
46        fn _mm256_adds_epu16(a: __m256i, b: __m256i) -> __m256i;
47        fn _mm256_alignr_epi8<const IMM8: i32>(a: __m256i, b: __m256i) -> __m256i;
48        fn _mm256_and_si256(a: __m256i, b: __m256i) -> __m256i;
49        fn _mm256_andnot_si256(a: __m256i, b: __m256i) -> __m256i;
50        fn _mm256_avg_epu16(a: __m256i, b: __m256i) -> __m256i;
51        fn _mm256_avg_epu8(a: __m256i, b: __m256i) -> __m256i;
52        fn _mm_blend_epi32<const IMM4: i32>(a: __m128i, b: __m128i) -> __m128i;
53        fn _mm256_blend_epi32<const IMM8: i32>(a: __m256i, b: __m256i) -> __m256i;
54        fn _mm256_blend_epi16<const IMM8: i32>(a: __m256i, b: __m256i) -> __m256i;
55        fn _mm256_blendv_epi8(a: __m256i, b: __m256i, mask: __m256i) -> __m256i;
56        fn _mm_broadcastb_epi8(a: __m128i) -> __m128i;
57        fn _mm256_broadcastb_epi8(a: __m128i) -> __m256i;
58        fn _mm_broadcastd_epi32(a: __m128i) -> __m128i;
59        fn _mm256_broadcastd_epi32(a: __m128i) -> __m256i;
60        fn _mm_broadcastq_epi64(a: __m128i) -> __m128i;
61        fn _mm256_broadcastq_epi64(a: __m128i) -> __m256i;
62        fn _mm_broadcastsd_pd(a: __m128d) -> __m128d;
63        fn _mm256_broadcastsd_pd(a: __m128d) -> __m256d;
64        fn _mm256_broadcastsi128_si256(a: __m128i) -> __m256i;
65        fn _mm_broadcastss_ps(a: __m128) -> __m128;
66        fn _mm256_broadcastss_ps(a: __m128) -> __m256;
67        fn _mm_broadcastw_epi16(a: __m128i) -> __m128i;
68        fn _mm256_broadcastw_epi16(a: __m128i) -> __m256i;
69        fn _mm256_cmpeq_epi64(a: __m256i, b: __m256i) -> __m256i;
70        fn _mm256_cmpeq_epi32(a: __m256i, b: __m256i) -> __m256i;
71        fn _mm256_cmpeq_epi16(a: __m256i, b: __m256i) -> __m256i;
72        fn _mm256_cmpeq_epi8(a: __m256i, b: __m256i) -> __m256i;
73        fn _mm256_cmpgt_epi64(a: __m256i, b: __m256i) -> __m256i;
74        fn _mm256_cmpgt_epi32(a: __m256i, b: __m256i) -> __m256i;
75        fn _mm256_cmpgt_epi16(a: __m256i, b: __m256i) -> __m256i;
76        fn _mm256_cmpgt_epi8(a: __m256i, b: __m256i) -> __m256i;
77        fn _mm256_cvtepi16_epi32(a: __m128i) -> __m256i;
78        fn _mm256_cvtepi16_epi64(a: __m128i) -> __m256i;
79        fn _mm256_cvtepi32_epi64(a: __m128i) -> __m256i;
80        fn _mm256_cvtepi8_epi16(a: __m128i) -> __m256i;
81        fn _mm256_cvtepi8_epi32(a: __m128i) -> __m256i;
82        fn _mm256_cvtepi8_epi64(a: __m128i) -> __m256i;
83        fn _mm256_cvtepu16_epi32(a: __m128i) -> __m256i;
84        fn _mm256_cvtepu16_epi64(a: __m128i) -> __m256i;
85        fn _mm256_cvtepu32_epi64(a: __m128i) -> __m256i;
86        fn _mm256_cvtepu8_epi16(a: __m128i) -> __m256i;
87        fn _mm256_cvtepu8_epi32(a: __m128i) -> __m256i;
88        fn _mm256_cvtepu8_epi64(a: __m128i) -> __m256i;
89        fn _mm256_extracti128_si256<const IMM1: i32>(a: __m256i) -> __m128i;
90        fn _mm256_hadd_epi16(a: __m256i, b: __m256i) -> __m256i;
91        fn _mm256_hadd_epi32(a: __m256i, b: __m256i) -> __m256i;
92        fn _mm256_hadds_epi16(a: __m256i, b: __m256i) -> __m256i;
93        fn _mm256_hsub_epi16(a: __m256i, b: __m256i) -> __m256i;
94        fn _mm256_hsub_epi32(a: __m256i, b: __m256i) -> __m256i;
95        fn _mm256_hsubs_epi16(a: __m256i, b: __m256i) -> __m256i;
96        unsafe fn _mm_i32gather_epi32<const SCALE: i32>(
97            slice: *const i32,
98            offsets: __m128i,
99        ) -> __m128i;
100        unsafe fn _mm_mask_i32gather_epi32<const SCALE: i32>(
101            src: __m128i,
102            slice: *const i32,
103            offsets: __m128i,
104            mask: __m128i,
105        ) -> __m128i;
106        unsafe fn _mm256_i32gather_epi32<const SCALE: i32>(
107            slice: *const i32,
108            offsets: __m256i,
109        ) -> __m256i;
110        unsafe fn _mm256_mask_i32gather_epi32<const SCALE: i32>(
111            src: __m256i,
112            slice: *const i32,
113            offsets: __m256i,
114            mask: __m256i,
115        ) -> __m256i;
116        unsafe fn _mm_i32gather_ps<const SCALE: i32>(slice: *const f32, offsets: __m128i)
117        -> __m128;
118        unsafe fn _mm_mask_i32gather_ps<const SCALE: i32>(
119            src: __m128,
120            slice: *const f32,
121            offsets: __m128i,
122            mask: __m128,
123        ) -> __m128;
124        unsafe fn _mm256_i32gather_ps<const SCALE: i32>(
125            slice: *const f32,
126            offsets: __m256i,
127        ) -> __m256;
128        unsafe fn _mm256_mask_i32gather_ps<const SCALE: i32>(
129            src: __m256,
130            slice: *const f32,
131            offsets: __m256i,
132            mask: __m256,
133        ) -> __m256;
134        unsafe fn _mm_i32gather_epi64<const SCALE: i32>(
135            slice: *const i64,
136            offsets: __m128i,
137        ) -> __m128i;
138        unsafe fn _mm_mask_i32gather_epi64<const SCALE: i32>(
139            src: __m128i,
140            slice: *const i64,
141            offsets: __m128i,
142            mask: __m128i,
143        ) -> __m128i;
144        unsafe fn _mm256_i32gather_epi64<const SCALE: i32>(
145            slice: *const i64,
146            offsets: __m128i,
147        ) -> __m256i;
148        unsafe fn _mm256_mask_i32gather_epi64<const SCALE: i32>(
149            src: __m256i,
150            slice: *const i64,
151            offsets: __m128i,
152            mask: __m256i,
153        ) -> __m256i;
154        unsafe fn _mm_i32gather_pd<const SCALE: i32>(
155            slice: *const f64,
156            offsets: __m128i,
157        ) -> __m128d;
158        unsafe fn _mm_mask_i32gather_pd<const SCALE: i32>(
159            src: __m128d,
160            slice: *const f64,
161            offsets: __m128i,
162            mask: __m128d,
163        ) -> __m128d;
164        unsafe fn _mm256_i32gather_pd<const SCALE: i32>(
165            slice: *const f64,
166            offsets: __m128i,
167        ) -> __m256d;
168        unsafe fn _mm256_mask_i32gather_pd<const SCALE: i32>(
169            src: __m256d,
170            slice: *const f64,
171            offsets: __m128i,
172            mask: __m256d,
173        ) -> __m256d;
174        unsafe fn _mm_i64gather_epi32<const SCALE: i32>(
175            slice: *const i32,
176            offsets: __m128i,
177        ) -> __m128i;
178        unsafe fn _mm_mask_i64gather_epi32<const SCALE: i32>(
179            src: __m128i,
180            slice: *const i32,
181            offsets: __m128i,
182            mask: __m128i,
183        ) -> __m128i;
184        unsafe fn _mm256_i64gather_epi32<const SCALE: i32>(
185            slice: *const i32,
186            offsets: __m256i,
187        ) -> __m128i;
188        unsafe fn _mm256_mask_i64gather_epi32<const SCALE: i32>(
189            src: __m128i,
190            slice: *const i32,
191            offsets: __m256i,
192            mask: __m128i,
193        ) -> __m128i;
194        unsafe fn _mm_i64gather_ps<const SCALE: i32>(slice: *const f32, offsets: __m128i)
195        -> __m128;
196        unsafe fn _mm_mask_i64gather_ps<const SCALE: i32>(
197            src: __m128,
198            slice: *const f32,
199            offsets: __m128i,
200            mask: __m128,
201        ) -> __m128;
202        unsafe fn _mm256_i64gather_ps<const SCALE: i32>(
203            slice: *const f32,
204            offsets: __m256i,
205        ) -> __m128;
206        unsafe fn _mm256_mask_i64gather_ps<const SCALE: i32>(
207            src: __m128,
208            slice: *const f32,
209            offsets: __m256i,
210            mask: __m128,
211        ) -> __m128;
212        unsafe fn _mm_i64gather_epi64<const SCALE: i32>(
213            slice: *const i64,
214            offsets: __m128i,
215        ) -> __m128i;
216        unsafe fn _mm_mask_i64gather_epi64<const SCALE: i32>(
217            src: __m128i,
218            slice: *const i64,
219            offsets: __m128i,
220            mask: __m128i,
221        ) -> __m128i;
222        unsafe fn _mm256_i64gather_epi64<const SCALE: i32>(
223            slice: *const i64,
224            offsets: __m256i,
225        ) -> __m256i;
226        unsafe fn _mm256_mask_i64gather_epi64<const SCALE: i32>(
227            src: __m256i,
228            slice: *const i64,
229            offsets: __m256i,
230            mask: __m256i,
231        ) -> __m256i;
232        unsafe fn _mm_i64gather_pd<const SCALE: i32>(
233            slice: *const f64,
234            offsets: __m128i,
235        ) -> __m128d;
236        unsafe fn _mm_mask_i64gather_pd<const SCALE: i32>(
237            src: __m128d,
238            slice: *const f64,
239            offsets: __m128i,
240            mask: __m128d,
241        ) -> __m128d;
242        unsafe fn _mm256_i64gather_pd<const SCALE: i32>(
243            slice: *const f64,
244            offsets: __m256i,
245        ) -> __m256d;
246        unsafe fn _mm256_mask_i64gather_pd<const SCALE: i32>(
247            src: __m256d,
248            slice: *const f64,
249            offsets: __m256i,
250            mask: __m256d,
251        ) -> __m256d;
252        fn _mm256_inserti128_si256<const IMM1: i32>(a: __m256i, b: __m128i) -> __m256i;
253        fn _mm256_madd_epi16(a: __m256i, b: __m256i) -> __m256i;
254        fn _mm256_maddubs_epi16(a: __m256i, b: __m256i) -> __m256i;
255        unsafe fn _mm_maskload_epi32(mem_addr: *const i32, mask: __m128i) -> __m128i;
256        unsafe fn _mm256_maskload_epi32(mem_addr: *const i32, mask: __m256i) -> __m256i;
257        unsafe fn _mm_maskload_epi64(mem_addr: *const i64, mask: __m128i) -> __m128i;
258        unsafe fn _mm256_maskload_epi64(mem_addr: *const i64, mask: __m256i) -> __m256i;
259        unsafe fn _mm_maskstore_epi32(mem_addr: *mut i32, mask: __m128i, a: __m128i);
260        unsafe fn _mm256_maskstore_epi32(mem_addr: *mut i32, mask: __m256i, a: __m256i);
261        unsafe fn _mm_maskstore_epi64(mem_addr: *mut i64, mask: __m128i, a: __m128i);
262        unsafe fn _mm256_maskstore_epi64(mem_addr: *mut i64, mask: __m256i, a: __m256i);
263        fn _mm256_max_epi16(a: __m256i, b: __m256i) -> __m256i;
264        fn _mm256_max_epi32(a: __m256i, b: __m256i) -> __m256i;
265        fn _mm256_max_epi8(a: __m256i, b: __m256i) -> __m256i;
266        fn _mm256_max_epu16(a: __m256i, b: __m256i) -> __m256i;
267        fn _mm256_max_epu32(a: __m256i, b: __m256i) -> __m256i;
268        fn _mm256_max_epu8(a: __m256i, b: __m256i) -> __m256i;
269        fn _mm256_min_epi16(a: __m256i, b: __m256i) -> __m256i;
270        fn _mm256_min_epi32(a: __m256i, b: __m256i) -> __m256i;
271        fn _mm256_min_epi8(a: __m256i, b: __m256i) -> __m256i;
272        fn _mm256_min_epu16(a: __m256i, b: __m256i) -> __m256i;
273        fn _mm256_min_epu32(a: __m256i, b: __m256i) -> __m256i;
274        fn _mm256_min_epu8(a: __m256i, b: __m256i) -> __m256i;
275        fn _mm256_movemask_epi8(a: __m256i) -> i32;
276        fn _mm256_mpsadbw_epu8<const IMM8: i32>(a: __m256i, b: __m256i) -> __m256i;
277        fn _mm256_mul_epi32(a: __m256i, b: __m256i) -> __m256i;
278        fn _mm256_mul_epu32(a: __m256i, b: __m256i) -> __m256i;
279        fn _mm256_mulhi_epi16(a: __m256i, b: __m256i) -> __m256i;
280        fn _mm256_mulhi_epu16(a: __m256i, b: __m256i) -> __m256i;
281        fn _mm256_mullo_epi16(a: __m256i, b: __m256i) -> __m256i;
282        fn _mm256_mullo_epi32(a: __m256i, b: __m256i) -> __m256i;
283        fn _mm256_mulhrs_epi16(a: __m256i, b: __m256i) -> __m256i;
284        fn _mm256_or_si256(a: __m256i, b: __m256i) -> __m256i;
285        fn _mm256_packs_epi16(a: __m256i, b: __m256i) -> __m256i;
286        fn _mm256_packs_epi32(a: __m256i, b: __m256i) -> __m256i;
287        fn _mm256_packus_epi16(a: __m256i, b: __m256i) -> __m256i;
288        fn _mm256_packus_epi32(a: __m256i, b: __m256i) -> __m256i;
289        fn _mm256_permutevar8x32_epi32(a: __m256i, b: __m256i) -> __m256i;
290        fn _mm256_permute4x64_epi64<const IMM8: i32>(a: __m256i) -> __m256i;
291        fn _mm256_permute2x128_si256<const IMM8: i32>(a: __m256i, b: __m256i) -> __m256i;
292        fn _mm256_permute4x64_pd<const IMM8: i32>(a: __m256d) -> __m256d;
293        fn _mm256_permutevar8x32_ps(a: __m256, idx: __m256i) -> __m256;
294        fn _mm256_sad_epu8(a: __m256i, b: __m256i) -> __m256i;
295        fn _mm256_shuffle_epi8(a: __m256i, b: __m256i) -> __m256i;
296        fn _mm256_shuffle_epi32<const MASK: i32>(a: __m256i) -> __m256i;
297        fn _mm256_shufflehi_epi16<const IMM8: i32>(a: __m256i) -> __m256i;
298        fn _mm256_shufflelo_epi16<const IMM8: i32>(a: __m256i) -> __m256i;
299        fn _mm256_sign_epi16(a: __m256i, b: __m256i) -> __m256i;
300        fn _mm256_sign_epi32(a: __m256i, b: __m256i) -> __m256i;
301        fn _mm256_sign_epi8(a: __m256i, b: __m256i) -> __m256i;
302        fn _mm256_sll_epi16(a: __m256i, count: __m128i) -> __m256i;
303        fn _mm256_sll_epi32(a: __m256i, count: __m128i) -> __m256i;
304        fn _mm256_sll_epi64(a: __m256i, count: __m128i) -> __m256i;
305        fn _mm256_slli_epi16<const IMM8: i32>(a: __m256i) -> __m256i;
306        fn _mm256_slli_epi32<const IMM8: i32>(a: __m256i) -> __m256i;
307        fn _mm256_slli_epi64<const IMM8: i32>(a: __m256i) -> __m256i;
308        fn _mm256_slli_si256<const IMM8: i32>(a: __m256i) -> __m256i;
309        fn _mm256_bslli_epi128<const IMM8: i32>(a: __m256i) -> __m256i;
310        fn _mm_sllv_epi32(a: __m128i, count: __m128i) -> __m128i;
311        fn _mm256_sllv_epi32(a: __m256i, count: __m256i) -> __m256i;
312        fn _mm_sllv_epi64(a: __m128i, count: __m128i) -> __m128i;
313        fn _mm256_sllv_epi64(a: __m256i, count: __m256i) -> __m256i;
314        fn _mm256_sra_epi16(a: __m256i, count: __m128i) -> __m256i;
315        fn _mm256_sra_epi32(a: __m256i, count: __m128i) -> __m256i;
316        fn _mm256_srai_epi16<const IMM8: i32>(a: __m256i) -> __m256i;
317        fn _mm256_srai_epi32<const IMM8: i32>(a: __m256i) -> __m256i;
318        fn _mm_srav_epi32(a: __m128i, count: __m128i) -> __m128i;
319        fn _mm256_srav_epi32(a: __m256i, count: __m256i) -> __m256i;
320        fn _mm256_srli_si256<const IMM8: i32>(a: __m256i) -> __m256i;
321        fn _mm256_bsrli_epi128<const IMM8: i32>(a: __m256i) -> __m256i;
322        fn _mm256_srl_epi16(a: __m256i, count: __m128i) -> __m256i;
323        fn _mm256_srl_epi32(a: __m256i, count: __m128i) -> __m256i;
324        fn _mm256_srl_epi64(a: __m256i, count: __m128i) -> __m256i;
325        fn _mm256_srli_epi16<const IMM8: i32>(a: __m256i) -> __m256i;
326        fn _mm256_srli_epi32<const IMM8: i32>(a: __m256i) -> __m256i;
327        fn _mm256_srli_epi64<const IMM8: i32>(a: __m256i) -> __m256i;
328        fn _mm_srlv_epi32(a: __m128i, count: __m128i) -> __m128i;
329        fn _mm256_srlv_epi32(a: __m256i, count: __m256i) -> __m256i;
330        fn _mm_srlv_epi64(a: __m128i, count: __m128i) -> __m128i;
331        fn _mm256_srlv_epi64(a: __m256i, count: __m256i) -> __m256i;
332        fn _mm256_sub_epi16(a: __m256i, b: __m256i) -> __m256i;
333        fn _mm256_sub_epi32(a: __m256i, b: __m256i) -> __m256i;
334        fn _mm256_sub_epi64(a: __m256i, b: __m256i) -> __m256i;
335        fn _mm256_sub_epi8(a: __m256i, b: __m256i) -> __m256i;
336        fn _mm256_subs_epi16(a: __m256i, b: __m256i) -> __m256i;
337        fn _mm256_subs_epi8(a: __m256i, b: __m256i) -> __m256i;
338        fn _mm256_subs_epu16(a: __m256i, b: __m256i) -> __m256i;
339        fn _mm256_subs_epu8(a: __m256i, b: __m256i) -> __m256i;
340        fn _mm256_unpackhi_epi8(a: __m256i, b: __m256i) -> __m256i;
341        fn _mm256_unpacklo_epi8(a: __m256i, b: __m256i) -> __m256i;
342        fn _mm256_unpackhi_epi16(a: __m256i, b: __m256i) -> __m256i;
343        fn _mm256_unpacklo_epi16(a: __m256i, b: __m256i) -> __m256i;
344        fn _mm256_unpackhi_epi32(a: __m256i, b: __m256i) -> __m256i;
345        fn _mm256_unpacklo_epi32(a: __m256i, b: __m256i) -> __m256i;
346        fn _mm256_unpackhi_epi64(a: __m256i, b: __m256i) -> __m256i;
347        fn _mm256_unpacklo_epi64(a: __m256i, b: __m256i) -> __m256i;
348        fn _mm256_xor_si256(a: __m256i, b: __m256i) -> __m256i;
349        fn _mm256_extract_epi8<const INDEX: i32>(a: __m256i) -> i32;
350        fn _mm256_extract_epi16<const INDEX: i32>(a: __m256i) -> i32;
351        fn _mm256_extract_epi32<const INDEX: i32>(a: __m256i) -> i32;
352        fn _mm256_cvtsd_f64(a: __m256d) -> f64;
353        fn _mm256_cvtsi256_si32(a: __m256i) -> i32;
354    }
355}