vppinfra: put each vector function into own file
[vpp.git] / src / vppinfra / vector / compress.h
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright(c) 2021 Cisco Systems, Inc.
3  */
4
5 #ifndef included_vector_compress_h
6 #define included_vector_compress_h
7 #include <vppinfra/clib.h>
8 #include <vppinfra/memcpy.h>
9
10 static_always_inline u32 *
11 clib_compress_u32_x64 (u32 *dst, u32 *src, u64 mask)
12 {
13 #if defined(CLIB_HAVE_VEC512_COMPRESS)
14   u32x16u *sv = (u32x16u *) src;
15   for (int i = 0; i < 4; i++)
16     {
17       int cnt = _popcnt32 ((u16) mask);
18       u32x16_compress_store (sv[i], mask, dst);
19       dst += cnt;
20       mask >>= 16;
21     }
22
23 #elif defined(CLIB_HAVE_VEC256_COMPRESS)
24   u32x8u *sv = (u32x8u *) src;
25   for (int i = 0; i < 8; i++)
26     {
27       int cnt = _popcnt32 ((u8) mask);
28       u32x8_compress_store (sv[i], mask, dst);
29       dst += cnt;
30       mask >>= 8;
31     }
32 #else
33   while (mask)
34     {
35       u16 bit = count_trailing_zeros (mask);
36       mask = clear_lowest_set_bit (mask);
37       dst++[0] = src[bit];
38     }
39 #endif
40   return dst;
41 }
42
43 /** \brief Compress array of 32-bit elemments into destination array based on
44  * mask
45
46     @param dst destination array of u32 elements
47     @param src source array of u32 elements
48     @param mask array of u64 values representing compress mask
49     @param n_elts number of elements in the source array
50     @return number of elements stored in destionation array
51 */
52
53 static_always_inline u32
54 clib_compress_u32 (u32 *dst, u32 *src, u64 *mask, u32 n_elts)
55 {
56   u32 *dst0 = dst;
57   while (n_elts >= 64)
58     {
59       if (mask[0] == ~0ULL)
60         {
61           clib_memcpy_u32 (dst, src, 64);
62           dst += 64;
63         }
64       else
65         dst = clib_compress_u32_x64 (dst, src, mask[0]);
66
67       mask++;
68       src += 64;
69       n_elts -= 64;
70     }
71
72   if (PREDICT_TRUE (n_elts == 0))
73     return dst - dst0;
74
75   return clib_compress_u32_x64 (dst, src, mask[0] & pow2_mask (n_elts)) - dst0;
76 }
77
78 #endif