summaryrefslogtreecommitdiffstats
path: root/src/vppinfra/vector/compress.h
diff options
context:
space:
mode:
authorDamjan Marion <damarion@cisco.com>2021-07-13 21:12:41 +0200
committerFlorin Coras <florin.coras@gmail.com>2021-07-13 20:06:19 +0000
commitd154a17989b1da7abbfdb87b98b90cc5f4d3295f (patch)
tree9353de897ec10d0afd3005dd2cf26e0b7ac512ef /src/vppinfra/vector/compress.h
parentb7e4d4487c0fa02f3869d24799c6573452276396 (diff)
vppinfra: put each vector function into own file
Type: refactor Change-Id: I2dd9a18497992ac7e2686c14f5d17eccccda0cda Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'src/vppinfra/vector/compress.h')
-rw-r--r--src/vppinfra/vector/compress.h78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/vppinfra/vector/compress.h b/src/vppinfra/vector/compress.h
new file mode 100644
index 00000000000..1d5d84e77ea
--- /dev/null
+++ b/src/vppinfra/vector/compress.h
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright(c) 2021 Cisco Systems, Inc.
+ */
+
+#ifndef included_vector_compress_h
+#define included_vector_compress_h
+#include <vppinfra/clib.h>
+#include <vppinfra/memcpy.h>
+
+static_always_inline u32 *
+clib_compress_u32_x64 (u32 *dst, u32 *src, u64 mask)
+{
+#if defined(CLIB_HAVE_VEC512_COMPRESS)
+ u32x16u *sv = (u32x16u *) src;
+ for (int i = 0; i < 4; i++)
+ {
+ int cnt = _popcnt32 ((u16) mask);
+ u32x16_compress_store (sv[i], mask, dst);
+ dst += cnt;
+ mask >>= 16;
+ }
+
+#elif defined(CLIB_HAVE_VEC256_COMPRESS)
+ u32x8u *sv = (u32x8u *) src;
+ for (int i = 0; i < 8; i++)
+ {
+ int cnt = _popcnt32 ((u8) mask);
+ u32x8_compress_store (sv[i], mask, dst);
+ dst += cnt;
+ mask >>= 8;
+ }
+#else
+ while (mask)
+ {
+ u16 bit = count_trailing_zeros (mask);
+ mask = clear_lowest_set_bit (mask);
+ dst++[0] = src[bit];
+ }
+#endif
+ return dst;
+}
+
+/** \brief Compress array of 32-bit elemments into destination array based on
+ * mask
+
+ @param dst destination array of u32 elements
+ @param src source array of u32 elements
+ @param mask array of u64 values representing compress mask
+ @param n_elts number of elements in the source array
+ @return number of elements stored in destionation array
+*/
+
+static_always_inline u32
+clib_compress_u32 (u32 *dst, u32 *src, u64 *mask, u32 n_elts)
+{
+ u32 *dst0 = dst;
+ while (n_elts >= 64)
+ {
+ if (mask[0] == ~0ULL)
+ {
+ clib_memcpy_u32 (dst, src, 64);
+ dst += 64;
+ }
+ else
+ dst = clib_compress_u32_x64 (dst, src, mask[0]);
+
+ mask++;
+ src += 64;
+ n_elts -= 64;
+ }
+
+ if (PREDICT_TRUE (n_elts == 0))
+ return dst - dst0;
+
+ return clib_compress_u32_x64 (dst, src, mask[0] & pow2_mask (n_elts)) - dst0;
+}
+
+#endif