|
FD.io VPP
v21.10.1-2-g0a485f517
Vector Packet Processing
|
Go to the documentation of this file.
44 #ifndef included_clib_string_h
45 #define included_clib_string_h
51 #ifdef CLIB_LINUX_KERNEL
52 #include <linux/string.h>
59 #ifdef CLIB_STANDALONE
60 #include <vppinfra/standalone_string.h>
64 #include <x86intrin.h>
77 #define clib_memcpy_fast_arch(a, b, c) clib_memcpy_fast_avx512 (a, b, c)
80 #define clib_memcpy_fast_arch(a, b, c) clib_memcpy_fast_avx2 (a, b, c)
83 #define clib_memcpy_fast_arch(a, b, c) clib_memcpy_fast_sse3 (a, b, c)
87 #ifndef clib_memcpy_fast_arch
88 #define clib_memcpy_fast_arch(a, b, c) memcpy (a, b, c)
95 "memcpy(src, dst, n) with src == NULL or dst == NULL is undefined "
100 #undef clib_memcpy_fast_arch
128 #define CLIB_STRING_MACRO_MAX 4096
160 bad = (dest == 0) + (
src == 0) + (n > dmax) + (dest ==
src) + (n == 0);
197 #define clib_memcpy(d,s,n) memcpy_s_inline(d,n,s,n)
206 bad = (s == 0) + (n > smax);
231 #define clib_memset(s,c,n) memset_s_inline(s,n,c,n)
236 #if defined (CLIB_HAVE_VEC256)
237 u8x32 s0, s1, d0, d1;
238 u8x32 mask = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
239 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
242 u8x32 add = u8x32_splat (32);
244 s0 = u8x32_load_unaligned (
src);
245 s1 = u8x32_load_unaligned (
src + 32);
246 d0 = u8x32_load_unaligned (
dst);
247 d1 = u8x32_load_unaligned (
dst + 32);
250 u8x32_store_unaligned (d0,
dst);
257 u8x32_store_unaligned (d1,
dst + 32);
259 #elif defined (CLIB_HAVE_VEC128)
260 u8x16 s0, s1, s2, s3, d0, d1, d2, d3;
261 u8x16 mask = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
263 u8x16 add = u8x16_splat (16);
265 s0 = u8x16_load_unaligned (
src);
266 s1 = u8x16_load_unaligned (
src + 16);
267 s2 = u8x16_load_unaligned (
src + 32);
268 s3 = u8x16_load_unaligned (
src + 48);
269 d0 = u8x16_load_unaligned (
dst);
270 d1 = u8x16_load_unaligned (
dst + 16);
271 d2 = u8x16_load_unaligned (
dst + 32);
272 d3 = u8x16_load_unaligned (
dst + 48);
275 u8x16_store_unaligned (d0,
dst);
282 u8x16_store_unaligned (d1,
dst + 16);
289 u8x16_store_unaligned (d2,
dst + 32);
293 u8x16_store_unaligned (d3,
dst + 48);
315 #if defined(CLIB_HAVE_VEC512)
316 u64x8 v512 = u64x8_splat (val);
319 u64x8_store_unaligned (v512, ptr);
326 #if defined(CLIB_HAVE_VEC256)
327 u64x4 v256 = u64x4_splat (val);
330 u64x4_store_unaligned (v256, ptr);
339 ptr[0] = ptr[1] = ptr[2] = ptr[3] = val;
352 #if defined(CLIB_HAVE_VEC512)
353 u32x16 v512 = u32x16_splat (val);
356 u32x16_store_unaligned (v512, ptr);
363 #if defined(CLIB_HAVE_VEC256)
364 u32x8 v256 = u32x8_splat (val);
367 u32x8_store_unaligned (v256, ptr);
374 #if defined(CLIB_HAVE_VEC128) && defined(CLIB_HAVE_VEC128_UNALIGNED_LOAD_STORE)
375 u32x4 v128 = u32x4_splat (val);
378 u32x4_store_unaligned (v128, ptr);
385 ptr[0] = ptr[1] = ptr[2] = ptr[3] = val;
398 #if defined(CLIB_HAVE_VEC512)
399 u16x32 v512 = u16x32_splat (val);
402 u16x32_store_unaligned (v512, ptr);
409 #if defined(CLIB_HAVE_VEC256)
410 u16x16 v256 = u16x16_splat (val);
413 u16x16_store_unaligned (v256, ptr);
420 #if defined(CLIB_HAVE_VEC128) && defined(CLIB_HAVE_VEC128_UNALIGNED_LOAD_STORE)
421 u16x8 v128 = u16x8_splat (val);
424 u16x8_store_unaligned (v128, ptr);
431 ptr[0] = ptr[1] = ptr[2] = ptr[3] = val;
444 #if defined(CLIB_HAVE_VEC512)
445 u8x64 v512 = u8x64_splat (val);
448 u8x64_store_unaligned (v512, ptr);
455 #if defined(CLIB_HAVE_VEC256)
456 u8x32 v256 = u8x32_splat (val);
459 u8x32_store_unaligned (v256, ptr);
466 #if defined(CLIB_HAVE_VEC128) && defined(CLIB_HAVE_VEC128_UNALIGNED_LOAD_STORE)
467 u8x16 v128 = u8x16_splat (val);
470 u8x16_store_unaligned (v128, ptr);
477 ptr[0] = ptr[1] = ptr[2] = ptr[3] = val;
500 #if defined(CLIB_HAVE_VEC256)
502 while (
count + 3 < max_count)
506 if (bmp != 0xffffffff)
518 while (
count + 3 < max_count &&
548 #if defined(CLIB_HAVE_VEC256)
549 u32x8 splat = u32x8_splat (
first);
550 while (
count + 7 < max_count)
554 if (bmp != 0xffffffff)
563 #elif defined(CLIB_HAVE_VEC128) && defined(CLIB_HAVE_VEC128_MSB_MASK)
565 while (
count + 3 < max_count)
581 while (
count + 3 < max_count &&
611 #if defined(CLIB_HAVE_VEC256)
613 while (
count + 15 < max_count)
617 if (bmp != 0xffffffff)
626 #elif defined(CLIB_HAVE_VEC128) && defined(CLIB_HAVE_VEC128_MSB_MASK)
628 while (
count + 7 < max_count)
644 while (
count + 3 < max_count &&
674 #if defined(CLIB_HAVE_VEC256)
676 while (
count + 31 < max_count)
680 if (bmp != 0xffffffff)
686 #elif defined(CLIB_HAVE_VEC128) && defined(CLIB_HAVE_VEC128_MSB_MASK)
688 while (
count + 15 < max_count)
704 while (
count + 3 < max_count &&
734 #define clib_memcmp(s1,s2,m1) \
736 memcmp_s_inline (s1, m1, s2, m1, &__diff); \
749 bad = (s1 == 0) + (s2 == 0) + (diff == 0) + (s2max > s1max) + (s2max == 0) +
775 *diff = memcmp (s1, s2, s2max);
782 #define clib_strnlen(s,m) strnlen_s_inline(s,m)
784 size_t strnlen_s (
const char *s,
size_t maxsize);
791 bad = (s == 0) + (maxsize == 0);
800 return strnlen (s, maxsize);
823 #define clib_strcmp(s1,s2) \
824 ({ int __indicator = 0; \
825 strcmp_s_inline (s1, CLIB_STRING_MACRO_MAX, s2, &__indicator); \
838 bad = (indicator == 0) + (s1 == 0) + (s2 == 0) + (s1max == 0) +
843 if (indicator == NULL)
851 if (s1 && s1max && s1[
clib_strnlen (s1, s1max)] !=
'\0')
856 *indicator = strcmp (s1, s2);
877 #define clib_strncmp(s1,s2,n) \
878 ({ int __indicator = 0; \
879 strncmp_s_inline (s1, CLIB_STRING_MACRO_MAX, s2, n, &__indicator); \
891 u8 s1_greater_s1max = (s1 && s1max && n >
clib_strnlen (s1, s1max));
901 *indicator = strncmp (s1, s2, n);
905 bad = (s1 == 0) + (s2 == 0) + (indicator == 0) + (s1max == 0) +
906 (s1 && s1max && s1[
clib_strnlen (s1, s1max)] !=
'\0') + s1_greater_s1max;
910 if (indicator == NULL)
918 if (s1 && s1max && s1[
clib_strnlen (s1, s1max)] !=
'\0')
920 if (s1_greater_s1max)
925 *indicator = strncmp (s1, s2, n);
935 #define clib_strcpy(d,s) strcpy_s_inline(d,CLIB_STRING_MACRO_MAX,s)
938 const char *__restrict__
src);
942 const char *__restrict__
src)
948 bad = (dest == 0) + (dmax == 0) + (
src == 0);
992 #define clib_strncpy(d,s,n) strncpy_s_inline(d,CLIB_STRING_MACRO_MAX,s,n)
1007 bad = (dest == 0) + (dmax == 0) + (
src == 0) + (n == 0);
1051 if (
low + (m - 1) >=
hi)
1071 #define clib_strcat(d,s) strcat_s_inline(d,CLIB_STRING_MACRO_MAX,s)
1074 const char *__restrict__
src);
1078 const char *__restrict__
src)
1082 size_t m, n, dest_size;
1084 bad = (dest == 0) + (dmax == 0) + (
src == 0);
1097 m = dmax - dest_size;
1120 dest[dest_size + n] =
'\0';
1132 #define clib_strncat(d,s,n) strncat_s_inline(d,CLIB_STRING_MACRO_MAX,s,n)
1143 size_t m, dest_size, allowed_size;
1146 bad = (dest == 0) + (
src == 0) + (dmax == 0) + (n == 0);
1172 allowed_size = dmax - dest_size;
1188 if (m >= allowed_size)
1190 m = allowed_size - 1;
1198 dest[dest_size + m] =
'\0';
1211 #define clib_strtok(s1,s2,p) \
1212 ({ rsize_t __s1max = CLIB_STRING_MACRO_MAX; \
1213 strtok_s_inline (s1, &__s1max, s2, p); \
1217 const char *__restrict__ s2,
char **__restrict__ ptr);
1221 const char *__restrict__ s2,
char **__restrict__ ptr)
1223 #define STRTOK_DELIM_MAX_LEN 16
1229 bad = (s1max == 0) + (s2 == 0) + (ptr == 0) +
1230 ((s1 == 0) && ptr && (*ptr == 0));
1240 if ((s1 == 0) && ptr && (*ptr == 0))
1253 while (*s1 !=
'\0' && !ptoken)
1363 #define clib_strstr(s1,s2) \
1364 ({ char * __substring = 0; \
1365 strstr_s_inline (s1, CLIB_STRING_MACRO_MAX, s2, CLIB_STRING_MACRO_MAX, \
1378 size_t s1_size, s2_size;
1381 (s1 == 0) + (s2 == 0) + (substring == 0) + (s1max == 0) + (s2max == 0) +
1382 (s1 && s1max && (s1[
clib_strnlen (s1, s1max)] !=
'\0')) +
1383 (s2 && s2max && (s2[
clib_strnlen (s2, s2max)] !=
'\0'));
1396 if (s1 && s1max && (s1[
clib_strnlen (s1, s1max)] !=
'\0'))
1398 if (s2 && s2max && (s2[
clib_strnlen (s2, s1max)] !=
'\0'))
1420 *substring = strstr (s1, s2);
1421 if (*substring == 0)
errno_t strncpy_s(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src, rsize_t n)
copy src string to dest string, no more than n characters
static errno_t strcat_s_inline(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src)
#define count_trailing_zeros(x)
static_always_inline u8x32 u8x32_is_greater(u8x32 v1, u8x32 v2)
errno_t memcpy_s(void *__restrict__ dest, rsize_t dmax, const void *__restrict__ src, rsize_t n)
copy src to dest, at most n bytes, up to dmax
errno_t strstr_s(char *s1, rsize_t s1max, const char *s2, rsize_t s2max, char **substring)
locate the first occurrence of the substring s2 in s1
static_always_inline void clib_memset_u16(void *p, u16 val, uword count)
static_always_inline u16 u8x16_msb_mask(u8x16 v)
static_always_inline uword clib_count_equal_u64(u64 *data, uword max_count)
static size_t strnlen_s_inline(const char *s, size_t maxsize)
errno_t strcmp_s(const char *s1, rsize_t s1max, const char *s2, int *indicator)
compare string s2 to string s1, and their difference is returned in indicator
char * strtok_s(char *__restrict__ s1, rsize_t *__restrict__ s1max, const char *__restrict__ s2, char **__restrict__ ptr)
tokenize string s1 with delimiter specified in s2.
static heap_elt_t * first(heap_header_t *h)
static_always_inline void clib_memset_u64(void *p, u64 val, uword count)
static_always_inline void clib_memcpy_le32(u8 *dst, u8 *src, u8 len)
#define STRTOK_DELIM_MAX_LEN
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
_mm512_packus_epi16 u16x32
static_always_inline u8x32 u8x32_blend(u8x32 v1, u8x32 v2, u8x32 mask)
static_always_inline void clib_memcpy_le(u8 *dst, u8 *src, u8 len, u8 max_len)
static_always_inline u8x16 u8x16_blend(u8x16 v1, u8x16 v2, u8x16 mask)
static_always_inline void clib_memset_u32(void *p, u32 val, uword count)
static errno_t strcpy_s_inline(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src)
#define clib_memcpy_fast_arch(a, b, c)
errno_t memcmp_s(const void *s1, rsize_t s1max, const void *s2, rsize_t s2max, int *diff)
compare memory until they differ, and their difference is returned in diff
static_always_inline void clib_memcpy_le64(u8 *dst, u8 *src, u8 len)
#define COMPILE_TIME_CONST(x)
#define static_always_inline
errno_t strcpy_s(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src)
copy src string to dest string
static errno_t strncmp_s_inline(const char *s1, rsize_t s1max, const char *s2, rsize_t n, int *indicator)
errno_t memset_s(void *s, rsize_t smax, int c, rsize_t n)
set n bytes starting at s to the specified c value
static errno_t memset_s_inline(void *s, rsize_t smax, int c, rsize_t n)
_mm256_packus_epi16 _mm256_packus_epi32 static_always_inline u32 u8x32_msb_mask(u8x32 v)
size_t strnlen_s(const char *s, size_t maxsize)
compute the length in s, no more than maxsize
static_always_inline uword clib_count_equal_u32(u32 *data, uword max_count)
static_always_inline uword clib_count_equal_u8(u8 *data, uword max_count)
errno_t strcat_s(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src)
append src string to dest string, including null
static errno_t memcpy_s_inline(void *__restrict__ dest, rsize_t dmax, const void *__restrict__ src, rsize_t n)
static_always_inline u8x16 u8x16_is_greater(u8x16 v1, u8x16 v2)
static_always_inline void clib_memset_u8(void *p, u8 val, uword count)
errno_t strncmp_s(const char *s1, rsize_t s1max, const char *s2, rsize_t n, int *indicator)
compare string s2 to string s1, no more than n characters, and their difference is returned in indica...
static errno_t memcmp_s_inline(const void *s1, rsize_t s1max, const void *s2, rsize_t s2max, int *diff)
#define clib_strnlen(s, m)
void clib_c11_violation(const char *s)
static errno_t strncat_s_inline(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src, rsize_t n)
static_always_inline uword clib_count_equal_u16(u16 *data, uword max_count)
void clib_memswap(void *_a, void *_b, uword bytes)
static char * strtok_s_inline(char *__restrict__ s1, rsize_t *__restrict__ s1max, const char *__restrict__ s2, char **__restrict__ ptr)
static errno_t strcmp_s_inline(const char *s1, rsize_t s1max, const char *s2, int *indicator)
static errno_t strncpy_s_inline(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src, rsize_t n)
errno_t strncat_s(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src, rsize_t n)
append src string to dest string, including null, no more than n characters
_mm256_packus_epi16 u16x16
static errno_t strstr_s_inline(char *s1, rsize_t s1max, const char *s2, rsize_t s2max, char **substring)