Line data Source code
1 : /* SPDX-License-Identifier: Apache-2.0 2 : * Copyright(c) 2021 Cisco Systems, Inc. 3 : */ 4 : 5 : #ifndef included_vector_array_mask_h 6 : #define included_vector_array_mask_h 7 : #include <vppinfra/clib.h> 8 : 9 : /** \brief Mask array of 32-bit elemments 10 : 11 : @param src source array of u32 elements 12 : @param mask use to mask the values of source array 13 : @param n_elts number of elements in the source array 14 : @return masked values are return in source array 15 : */ 16 : 17 : static_always_inline void 18 0 : clib_array_mask_u32 (u32 *src, u32 mask, u32 n_elts) 19 : { 20 : #if defined(CLIB_HAVE_VEC512) 21 0 : u32x16 mask16 = u32x16_splat (mask); 22 0 : if (n_elts <= 16) 23 : { 24 0 : u32 m = pow2_mask (n_elts); 25 0 : u32x16 r = u32x16_mask_load_zero (src, m); 26 0 : u32x16_mask_store (r & mask16, src, m); 27 0 : return; 28 : } 29 0 : for (int i = 0; i < n_elts; i += 16) 30 0 : *((u32x16u *) (src + i)) &= mask16; 31 0 : *((u32x16u *) (src + n_elts - 16)) &= mask16; 32 : #elif defined(CLIB_HAVE_VEC256) 33 0 : u32x8 mask8 = u32x8_splat (mask); 34 : #if defined(CLIB_HAVE_VEC256_MASK_LOAD_STORE) 35 0 : if (n_elts <= 8) 36 : { 37 0 : u32 m = pow2_mask (n_elts); 38 0 : u32x8 r = u32x8_mask_load_zero (src, m); 39 0 : u32x8_mask_store (r & mask8, src, m); 40 0 : return; 41 : } 42 : #else 43 0 : if (PREDICT_FALSE (n_elts < 4)) 44 : { 45 0 : if (n_elts & 2) 46 : { 47 0 : src[0] &= mask; 48 0 : src[1] &= mask; 49 0 : src += 2; 50 : } 51 0 : if (n_elts & 1) 52 0 : src[0] &= mask; 53 0 : return; 54 : } 55 0 : if (n_elts <= 8) 56 : { 57 0 : u32x4 mask4 = u32x4_splat (mask); 58 0 : *(u32x4u *) src &= mask4; 59 0 : *(u32x4u *) (src + n_elts - 4) &= mask4; 60 : } 61 : #endif 62 : 63 0 : for (int i = 0; i < n_elts; i += 8) 64 0 : *((u32x8u *) (src + i)) &= mask8; 65 0 : *((u32x8u *) (src + n_elts - 8)) &= mask8; 66 : #elif defined(CLIB_HAVE_VEC128) 67 0 : u32x4 mask4 = u32x4_splat (mask); 68 : 69 0 : if (PREDICT_FALSE (n_elts < 4)) 70 : { 71 0 : if (n_elts & 2) 72 : { 73 0 : src[0] &= mask; 74 0 : src[1] &= mask; 75 0 : src += 2; 76 : } 77 0 : if (n_elts & 1) 78 0 : src[0] &= mask; 79 0 : return; 80 : } 81 : 82 0 : for (int i = 0; i < n_elts; i += 4) 83 0 : *((u32x4u *) (src + i)) &= mask4; 84 0 : *((u32x4u *) (src + n_elts - 4)) &= mask4; 85 0 : return; 86 : #else 87 : while (n_elts > 0) 88 : { 89 : src[0] &= mask; 90 : src++; 91 : n_elts--; 92 : } 93 : #endif 94 : } 95 : 96 : static_always_inline void 97 : clib_array_mask_set_u32_x64 (u32 *a, u32 v, uword bmp, int n_elts) 98 : { 99 : #if defined(CLIB_HAVE_VEC512_MASK_LOAD_STORE) 100 : u32x16 r = u32x16_splat (v); 101 : for (; n_elts > 0; n_elts -= 16, a += 16, bmp >>= 16) 102 : u32x16_mask_store (r, a, bmp); 103 : #elif defined(CLIB_HAVE_VEC256_MASK_LOAD_STORE) 104 : u32x8 r = u32x8_splat (v); 105 : for (; n_elts > 0; n_elts -= 8, a += 8, bmp >>= 8) 106 : u32x8_mask_store (r, a, bmp); 107 : #else 108 : while (bmp) 109 : { 110 : a[get_lowest_set_bit_index (bmp)] = v; 111 : bmp = clear_lowest_set_bit (bmp); 112 : } 113 : #endif 114 : } 115 : 116 : static_always_inline void 117 : clib_array_mask_set_u32 (u32 *a, u32 v, uword *bmp, u32 n_elts) 118 : { 119 : while (n_elts >= uword_bits) 120 : { 121 : clib_array_mask_set_u32_x64 (a, v, bmp++[0], uword_bits); 122 : a += uword_bits; 123 : n_elts -= uword_bits; 124 : } 125 : 126 : clib_array_mask_set_u32_x64 (a, v, bmp[0] & pow2_mask (n_elts), n_elts); 127 : } 128 : 129 : #endif