diff options
author | Damjan Marion <damarion@cisco.com> | 2019-04-12 17:44:35 +0200 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2019-04-12 22:05:03 +0000 |
commit | 4e08316f3ec2c98165f156c6551f1e6557931739 (patch) | |
tree | 7fc2ce897f5196fdb54ac63d7bf73e6339a90c1b /src | |
parent | d54815c441c77f0b50d375848aef7fc4ff639492 (diff) |
vppinfra: AVX-512 transpose (u32x16 and u64x8)
Change-Id: Iefe9d20799a6f5f271aa5b675ea2b19ac3efbe1e
Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/vppinfra/vector_avx512.h | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/src/vppinfra/vector_avx512.h b/src/vppinfra/vector_avx512.h index f69c67e697c..a5d6739a5d1 100644 --- a/src/vppinfra/vector_avx512.h +++ b/src/vppinfra/vector_avx512.h @@ -69,6 +69,132 @@ u16x32_msb_mask (u16x32 v) return (u32) _mm512_movepi16_mask ((__m512i) v); } + +static_always_inline void +u32x16_transpose (u32x16 m[16]) +{ + __m512i r[16], a, b, c, d, x, y; + + /* *INDENT-OFF* */ + __m512i pm1 = (__m512i) (u64x8) { 0, 1, 8, 9, 4, 5, 12, 13}; + __m512i pm2 = (__m512i) (u64x8) { 2, 3, 10, 11, 6, 7, 14, 15}; + __m512i pm3 = (__m512i) (u64x8) { 0, 1, 2, 3, 8, 9, 10, 11}; + __m512i pm4 = (__m512i) (u64x8) { 4, 5, 6, 7, 12, 13, 14, 15}; + /* *INDENT-ON* */ + + r[0] = _mm512_unpacklo_epi32 ((__m512i) m[0], (__m512i) m[1]); + r[1] = _mm512_unpacklo_epi32 ((__m512i) m[2], (__m512i) m[3]); + r[2] = _mm512_unpacklo_epi32 ((__m512i) m[4], (__m512i) m[5]); + r[3] = _mm512_unpacklo_epi32 ((__m512i) m[6], (__m512i) m[7]); + r[4] = _mm512_unpacklo_epi32 ((__m512i) m[8], (__m512i) m[9]); + r[5] = _mm512_unpacklo_epi32 ((__m512i) m[10], (__m512i) m[11]); + r[6] = _mm512_unpacklo_epi32 ((__m512i) m[12], (__m512i) m[13]); + r[7] = _mm512_unpacklo_epi32 ((__m512i) m[14], (__m512i) m[15]); + + r[8] = _mm512_unpackhi_epi32 ((__m512i) m[0], (__m512i) m[1]); + r[9] = _mm512_unpackhi_epi32 ((__m512i) m[2], (__m512i) m[3]); + r[10] = _mm512_unpackhi_epi32 ((__m512i) m[4], (__m512i) m[5]); + r[11] = _mm512_unpackhi_epi32 ((__m512i) m[6], (__m512i) m[7]); + r[12] = _mm512_unpackhi_epi32 ((__m512i) m[8], (__m512i) m[9]); + r[13] = _mm512_unpackhi_epi32 ((__m512i) m[10], (__m512i) m[11]); + r[14] = _mm512_unpackhi_epi32 ((__m512i) m[12], (__m512i) m[13]); + r[15] = _mm512_unpackhi_epi32 ((__m512i) m[14], (__m512i) m[15]); + + a = _mm512_unpacklo_epi64 (r[0], r[1]); + b = _mm512_unpacklo_epi64 (r[2], r[3]); + c = _mm512_unpacklo_epi64 (r[4], r[5]); + d = _mm512_unpacklo_epi64 (r[6], r[7]); + x = _mm512_permutex2var_epi64 (a, pm1, b); + y = _mm512_permutex2var_epi64 (c, pm1, d); + m[0] = (u32x16) _mm512_permutex2var_epi64 (x, pm3, y); + m[8] = (u32x16) _mm512_permutex2var_epi64 (x, pm4, y); + x = _mm512_permutex2var_epi64 (a, pm2, b); + y = _mm512_permutex2var_epi64 (c, pm2, d); + m[4] = (u32x16) _mm512_permutex2var_epi64 (x, pm3, y); + m[12] = (u32x16) _mm512_permutex2var_epi64 (x, pm4, y); + + a = _mm512_unpacklo_epi64 (r[8], r[9]); + b = _mm512_unpacklo_epi64 (r[10], r[11]); + c = _mm512_unpacklo_epi64 (r[12], r[13]); + d = _mm512_unpacklo_epi64 (r[14], r[15]); + x = _mm512_permutex2var_epi64 (a, pm1, b); + y = _mm512_permutex2var_epi64 (c, pm1, d); + m[2] = (u32x16) _mm512_permutex2var_epi64 (x, pm3, y); + m[10] = (u32x16) _mm512_permutex2var_epi64 (x, pm4, y); + x = _mm512_permutex2var_epi64 (a, pm2, b); + y = _mm512_permutex2var_epi64 (c, pm2, d); + m[6] = (u32x16) _mm512_permutex2var_epi64 (x, pm3, y); + m[14] = (u32x16) _mm512_permutex2var_epi64 (x, pm4, y); + + a = _mm512_unpackhi_epi64 (r[0], r[1]); + b = _mm512_unpackhi_epi64 (r[2], r[3]); + c = _mm512_unpackhi_epi64 (r[4], r[5]); + d = _mm512_unpackhi_epi64 (r[6], r[7]); + x = _mm512_permutex2var_epi64 (a, pm1, b); + y = _mm512_permutex2var_epi64 (c, pm1, d); + m[1] = (u32x16) _mm512_permutex2var_epi64 (x, pm3, y); + m[9] = (u32x16) _mm512_permutex2var_epi64 (x, pm4, y); + x = _mm512_permutex2var_epi64 (a, pm2, b); + y = _mm512_permutex2var_epi64 (c, pm2, d); + m[5] = (u32x16) _mm512_permutex2var_epi64 (x, pm3, y); + m[13] = (u32x16) _mm512_permutex2var_epi64 (x, pm4, y); + + a = _mm512_unpackhi_epi64 (r[8], r[9]); + b = _mm512_unpackhi_epi64 (r[10], r[11]); + c = _mm512_unpackhi_epi64 (r[12], r[13]); + d = _mm512_unpackhi_epi64 (r[14], r[15]); + x = _mm512_permutex2var_epi64 (a, pm1, b); + y = _mm512_permutex2var_epi64 (c, pm1, d); + m[3] = (u32x16) _mm512_permutex2var_epi64 (x, pm3, y); + m[11] = (u32x16) _mm512_permutex2var_epi64 (x, pm4, y); + x = _mm512_permutex2var_epi64 (a, pm2, b); + y = _mm512_permutex2var_epi64 (c, pm2, d); + m[7] = (u32x16) _mm512_permutex2var_epi64 (x, pm3, y); + m[15] = (u32x16) _mm512_permutex2var_epi64 (x, pm4, y); +} + + + +static_always_inline void +u64x8_transpose (u64x8 m[8]) +{ + __m512i r[8], x, y; + + /* *INDENT-OFF* */ + __m512i pm1 = (__m512i) (u64x8) { 0, 1, 8, 9, 4, 5, 12, 13}; + __m512i pm2 = (__m512i) (u64x8) { 2, 3, 10, 11, 6, 7, 14, 15}; + __m512i pm3 = (__m512i) (u64x8) { 0, 1, 2, 3, 8, 9, 10, 11}; + __m512i pm4 = (__m512i) (u64x8) { 4, 5, 6, 7, 12, 13, 14, 15}; + /* *INDENT-ON* */ + + r[0] = _mm512_unpacklo_epi64 ((__m512i) m[0], (__m512i) m[1]); + r[1] = _mm512_unpacklo_epi64 ((__m512i) m[2], (__m512i) m[3]); + r[2] = _mm512_unpacklo_epi64 ((__m512i) m[4], (__m512i) m[5]); + r[3] = _mm512_unpacklo_epi64 ((__m512i) m[6], (__m512i) m[7]); + r[4] = _mm512_unpackhi_epi64 ((__m512i) m[0], (__m512i) m[1]); + r[5] = _mm512_unpackhi_epi64 ((__m512i) m[2], (__m512i) m[3]); + r[6] = _mm512_unpackhi_epi64 ((__m512i) m[4], (__m512i) m[5]); + r[7] = _mm512_unpackhi_epi64 ((__m512i) m[6], (__m512i) m[7]); + + x = _mm512_permutex2var_epi64 (r[0], pm1, r[1]); + y = _mm512_permutex2var_epi64 (r[2], pm1, r[3]); + m[0] = (u64x8) _mm512_permutex2var_epi64 (x, pm3, y); + m[4] = (u64x8) _mm512_permutex2var_epi64 (x, pm4, y); + x = _mm512_permutex2var_epi64 (r[0], pm2, r[1]); + y = _mm512_permutex2var_epi64 (r[2], pm2, r[3]); + m[2] = (u64x8) _mm512_permutex2var_epi64 (x, pm3, y); + m[6] = (u64x8) _mm512_permutex2var_epi64 (x, pm4, y); + + x = _mm512_permutex2var_epi64 (r[4], pm1, r[5]); + y = _mm512_permutex2var_epi64 (r[6], pm1, r[7]); + m[1] = (u64x8) _mm512_permutex2var_epi64 (x, pm3, y); + m[5] = (u64x8) _mm512_permutex2var_epi64 (x, pm4, y); + x = _mm512_permutex2var_epi64 (r[4], pm2, r[5]); + y = _mm512_permutex2var_epi64 (r[6], pm2, r[7]); + m[3] = (u64x8) _mm512_permutex2var_epi64 (x, pm3, y); + m[7] = (u64x8) _mm512_permutex2var_epi64 (x, pm4, y); +} + #endif /* included_vector_avx512_h */ /* * fd.io coding-style-patch-verification: ON |