aboutsummaryrefslogtreecommitdiffstats
path: root/src/vppinfra/vector_avx512.h
diff options
context:
space:
mode:
authorDamjan Marion <damarion@cisco.com>2019-04-12 17:44:35 +0200
committerFlorin Coras <florin.coras@gmail.com>2019-04-12 22:05:03 +0000
commit4e08316f3ec2c98165f156c6551f1e6557931739 (patch)
tree7fc2ce897f5196fdb54ac63d7bf73e6339a90c1b /src/vppinfra/vector_avx512.h
parentd54815c441c77f0b50d375848aef7fc4ff639492 (diff)
vppinfra: AVX-512 transpose (u32x16 and u64x8)
Change-Id: Iefe9d20799a6f5f271aa5b675ea2b19ac3efbe1e Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'src/vppinfra/vector_avx512.h')
-rw-r--r--src/vppinfra/vector_avx512.h126
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