16 #ifndef included_vector_avx2_h 17 #define included_vector_avx2_h 20 #include <x86intrin.h> 23 #define foreach_avx2_vec256i \ 24 _(i,8,32,epi8) _(i,16,16,epi16) _(i,32,8,epi32) _(i,64,4,epi64) 25 #define foreach_avx2_vec256u \ 26 _(u,8,32,epi8) _(u,16,16,epi16) _(u,32,8,epi32) _(u,64,4,epi64) 27 #define foreach_avx2_vec256f \ 28 _(f,32,8,ps) _(f,64,4,pd) 30 #define _mm256_set1_epi64 _mm256_set1_epi64x 34 #define _(t, s, c, i) \ 35 static_always_inline t##s##x##c \ 36 t##s##x##c##_splat (t##s x) \ 37 { return (t##s##x##c) _mm256_set1_##i (x); } \ 39 static_always_inline t##s##x##c \ 40 t##s##x##c##_load_unaligned (void *p) \ 41 { return (t##s##x##c) _mm256_loadu_si256 (p); } \ 43 static_always_inline void \ 44 t##s##x##c##_store_unaligned (t##s##x##c v, void *p) \ 45 { _mm256_storeu_si256 ((__m256i *) p, (__m256i) v); } \ 47 static_always_inline int \ 48 t##s##x##c##_is_all_zero (t##s##x##c x) \ 49 { return _mm256_testz_si256 ((__m256i) x, (__m256i) x); } \ 51 static_always_inline int \ 52 t##s##x##c##_is_equal (t##s##x##c a, t##s##x##c b) \ 53 { return t##s##x##c##_is_all_zero (a ^ b); } \ 55 static_always_inline int \ 56 t##s##x##c##_is_all_equal (t##s##x##c v, t##s x) \ 57 { return t##s##x##c##_is_equal (v, t##s##x##c##_splat (x)); } \ 59 static_always_inline t##s##x##c \ 60 t##s##x##c##_interleave_lo (t##s##x##c a, t##s##x##c b) \ 61 { return (t##s##x##c) _mm256_unpacklo_##i ((__m256i) a, (__m256i) b); } \ 63 static_always_inline t##s##x##c \ 64 t##s##x##c##_interleave_hi (t##s##x##c a, t##s##x##c b) \ 65 { return (t##s##x##c) _mm256_unpackhi_##i ((__m256i) a, (__m256i) b); } \ 75 return (u32x8) _mm256_permutevar8x32_epi32 ((__m256i) v, (__m256i) idx);
78 #define u64x4_permute(v, m0, m1, m2, m3) \ 79 (u64x4) _mm256_permute4x64_epi64 ( \ 80 (__m256i) v, ((m0) | (m1) << 2 | (m2) << 4 | (m3) << 6)) 86 t2##_extract_lo (t2 v) \ 87 { return (t1) _mm256_extracti128_si256 ((__m256i) v, 0); } \ 90 t2##_extract_hi (t2 v) \ 91 { return (t1) _mm256_extracti128_si256 ((__m256i) v, 1); } \ 94 t2##_insert_lo (t2 v1, t1 v2) \ 95 { return (t2) _mm256_inserti128_si256 ((__m256i) v1, (__m128i) v2, 0); }\ 98 t2##_insert_hi (t2 v1, t1 v2) \ 99 { return (t2) _mm256_inserti128_si256 ((__m256i) v1, (__m128i) v2, 1); }\ 109 #define _(f, t, fn) \ 110 always_inline t t##_pack (f lo, f hi) \ 112 return (t) fn ((__m256i) lo, (__m256i) hi); \ 115 _ (i16x16, i8x32, _mm256_packs_epi16)
116 _ (i16x16, u8x32, _mm256_packus_epi16)
117 _ (i32x8, i16x16, _mm256_packs_epi32)
118 _ (i32x8, u16x16, _mm256_packus_epi32)
125 return _mm256_movemask_epi8 ((__m256i) v);
131 return _mm256_movemask_epi8 ((__m256i) v);
137 static_always_inline t \ 139 { return (t) _mm256_cvt##i ((__m128i) x); } 141 _(u16x8, u32x8, epu16_epi32)
142 _(u16x8, u64x4, epu16_epi64)
143 _(u32x4, u64x4, epu32_epi64)
144 _ (u8x16, u16x16, epu8_epi16)
145 _(u8x16, u32x8, epu8_epi32)
146 _(u8x16, u64x4, epu8_epi64)
147 _(i16x8, i32x8, epi16_epi32)
148 _(i16x8, i64x4, epi16_epi64)
149 _(i32x4, i64x4, epi32_epi64)
150 _ (i8x16, i16x16, epi8_epi16)
151 _(i8x16, i32x8, epi8_epi32)
152 _(i8x16, i64x4, epi8_epi64)
160 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8,
161 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8,
163 return (u64x4) _mm256_shuffle_epi8 ((__m256i) v, (__m256i) swap);
170 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12,
171 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
173 return (u32x8) _mm256_shuffle_epi8 ((__m256i) v, (__m256i) swap);
180 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14,
181 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14
183 return (u16x16) _mm256_shuffle_epi8 ((__m256i) v, (__m256i) swap);
189 return (u8x32) _mm256_shuffle_epi8 ((__m256i) v, (__m256i) m);
192 #define u8x32_align_right(a, b, imm) \ 193 (u8x32) _mm256_alignr_epi8 ((__m256i) a, (__m256i) b, imm) 200 return sum8[0] + sum8[4];
206 return (u32x8) _mm256_hadd_epi32 ((__m256i) v1, (__m256i) v2);
212 const u16x16 masks[17] = {
218 {-1, -1, -1, -1, -1},
219 {-1, -1, -1, -1, -1, -1},
220 {-1, -1, -1, -1, -1, -1, -1},
221 {-1, -1, -1, -1, -1, -1, -1, -1},
222 {-1, -1, -1, -1, -1, -1, -1, -1, -1},
223 {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
224 {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
225 {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
226 {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
227 {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
228 {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
229 {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
234 return v & masks[16 - n_last];
240 return (f32x8) _mm256_cvtepi32_ps ((__m256i) v);
246 return (u32x8) _mm256_cvttps_epi32 ((__m256) v);
249 #define u32x8_blend(a,b,m) \ 250 (u32x8) _mm256_blend_epi32 ((__m256i) a, (__m256i) b, m) 252 #define u16x16_blend(v1, v2, mask) \ 253 (u16x16) _mm256_blend_epi16 ((__m256i) (v1), (__m256i) (v2), mask) 265 u32x8_gather (
void *p0,
void *p1,
void *p2,
void *p3,
void *p4,
void *p5,
287 void *p5,
void *p6,
void *p7)
302 *(
u64 *) p = r[index];
308 *(
u32 *) p = r[index];
314 return (u8x32) _mm256_cmpgt_epi8 ((__m256i) v1, (__m256i) v2);
320 return (u8x32) _mm256_blendv_epi8 ((__m256i) v1, (__m256i) v2,
324 #define u32x8_permute_lanes(a, b, m) \ 325 (u32x8) _mm256_permute2x128_si256 ((__m256i) a, (__m256i) b, m) 326 #define u64x4_permute_lanes(a, b, m) \ 327 (u64x4) _mm256_permute2x128_si256 ((__m256i) a, (__m256i) b, m) 332 return (u32x8) _mm256_min_epu32 ((__m256i) a, (__m256i) b);
339 u32x8_extract_hi (v)));
347 r[0] = (
u64x4) u32x8_interleave_lo (a[0], a[1]);
348 r[1] = (
u64x4) u32x8_interleave_hi (a[0], a[1]);
349 r[2] = (
u64x4) u32x8_interleave_lo (a[2], a[3]);
350 r[3] = (
u64x4) u32x8_interleave_hi (a[2], a[3]);
351 r[4] = (
u64x4) u32x8_interleave_lo (a[4], a[5]);
352 r[5] = (
u64x4) u32x8_interleave_hi (a[4], a[5]);
353 r[6] = (
u64x4) u32x8_interleave_lo (a[6], a[7]);
354 r[7] = (
u64x4) u32x8_interleave_hi (a[6], a[7]);
356 x = u64x4_interleave_lo (r[0], r[2]);
357 y = u64x4_interleave_lo (r[4], r[6]);
361 x = u64x4_interleave_hi (r[0], r[2]);
362 y = u64x4_interleave_hi (r[4], r[6]);
366 x = u64x4_interleave_lo (r[1], r[3]);
367 y = u64x4_interleave_lo (r[5], r[7]);
371 x = u64x4_interleave_hi (r[1], r[3]);
372 y = u64x4_interleave_hi (r[5], r[7]);
382 r[0] = u64x4_interleave_lo (a[0], a[1]);
383 r[1] = u64x4_interleave_hi (a[0], a[1]);
384 r[2] = u64x4_interleave_lo (a[2], a[3]);
385 r[3] = u64x4_interleave_hi (a[2], a[3]);
static_always_inline u8x32 u8x32_shuffle(u8x32 v, u8x32 m)
vnet_hw_if_output_node_runtime_t * r
foreach_avx2_vec256i static foreach_avx2_vec256u u32x8 u32x8_permute(u32x8 v, u32x8 idx)
static_always_inline u32 u32x8_min_scalar(u32x8 v)
epu16_epi64 epu8_epi16 epu8_epi64 epi16_epi64 epi8_epi16 epi8_epi64 static_always_inline u64x4 u64x4_byte_swap(u64x4 v)
static_always_inline u16x16 u16x16_mask_last(u16x16 v, u8 n_last)
static_always_inline void u64x4_scatter(u64x4 r, void *p0, void *p1, void *p2, void *p3)
#define static_always_inline
static_always_inline void u64x4_scatter_one(u64x4 r, int index, void *p)
#define foreach_avx2_vec256i
epu8_epi32 epu16_epi32 u64x2
static_always_inline void u32x8_scatter(u32x8 r, void *p0, void *p1, void *p2, void *p3, void *p4, void *p5, void *p6, void *p7)
static_always_inline u64x4 u64x4_gather(void *p0, void *p1, void *p2, void *p3)
static_always_inline u32x8 u32x8_byte_swap(u32x8 v)
static_always_inline void u32x8_transpose(u32x8 a[8])
static_always_inline u16x16 u16x16_byte_swap(u16x16 v)
static_always_inline void u32x8_scatter_one(u32x8 r, int index, void *p)
static_always_inline u32 u32x8_sum_elts(u32x8 sum8)
static_always_inline u32 u32x4_min_scalar(u32x4 v)
static_always_inline u32x8 u32x8_hadd(u32x8 v1, u32x8 v2)
static_always_inline u32x8 u32x8_min(u32x8 a, u32x8 b)
static_always_inline u8x32 u8x32_is_greater(u8x32 v1, u8x32 v2)
#define u64x4_permute_lanes(a, b, m)
_mm256_packus_epi16 _mm256_packus_epi32 static_always_inline u32 u8x32_msb_mask(u8x32 v)
#define foreach_avx2_vec256u
static_always_inline u32x8 u32x8_from_f32x8(f32x8 v)
static_always_inline u32 i8x32_msb_mask(i8x32 v)
#define u32x8_permute_lanes(a, b, m)
#define u8x32_align_right(a, b, imm)
static_always_inline void u64x4_transpose(u64x4 a[8])
static_always_inline f32x8 f32x8_from_u32x8(u32x8 v)
static_always_inline u8x32 u8x32_blend(u8x32 v1, u8x32 v2, u8x32 mask)
static_always_inline u32x8 u32x8_gather(void *p0, void *p1, void *p2, void *p3, void *p4, void *p5, void *p6, void *p7)