X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvppinfra%2Fstring.h;h=a3db9264cac9eb1561b0defcc7e63a92ab935429;hb=419e15f0c1205d27b4b9ae4fd4eaa516b8f4844d;hp=d9cd8fe1af9d071016d92a5f5d72a361d3bc8868;hpb=e58041f242bf4bd120ecc9619b88348d80b94c17;p=vpp.git diff --git a/src/vppinfra/string.h b/src/vppinfra/string.h index d9cd8fe1af9..a3db9264cac 100644 --- a/src/vppinfra/string.h +++ b/src/vppinfra/string.h @@ -213,6 +213,84 @@ memset_s_inline (void *s, rsize_t smax, int c, rsize_t n) */ #define clib_memset(s,c,n) memset_s_inline(s,n,c,n) +static_always_inline void +clib_memcpy_le (u8 * dst, u8 * src, u8 len, u8 max_len) +{ +#if defined (CLIB_HAVE_VEC256) + u8x32 s0, s1, d0, d1; + u8x32 mask = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + }; + u8x32 lv = u8x32_splat (len); + u8x32 add = u8x32_splat (32); + + s0 = u8x32_load_unaligned (src); + s1 = u8x32_load_unaligned (src + 32); + d0 = u8x32_load_unaligned (dst); + d1 = u8x32_load_unaligned (dst + 32); + + d0 = u8x32_blend (d0, s0, u8x32_is_greater (lv, mask)); + u8x32_store_unaligned (d0, dst); + + if (max_len <= 32) + return; + + mask += add; + d1 = u8x32_blend (d1, s1, u8x32_is_greater (lv, mask)); + u8x32_store_unaligned (d1, dst + 32); + +#elif defined (CLIB_HAVE_VEC128) + u8x16 s0, s1, s2, s3, d0, d1, d2, d3; + u8x16 mask = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; + u8x16 lv = u8x16_splat (len); + u8x16 add = u8x16_splat (16); + + s0 = u8x16_load_unaligned (src); + s1 = u8x16_load_unaligned (src + 16); + s2 = u8x16_load_unaligned (src + 32); + s3 = u8x16_load_unaligned (src + 48); + d0 = u8x16_load_unaligned (dst); + d1 = u8x16_load_unaligned (dst + 16); + d2 = u8x16_load_unaligned (dst + 32); + d3 = u8x16_load_unaligned (dst + 48); + + d0 = u8x16_blend (d0, s0, u8x16_is_greater (lv, mask)); + u8x16_store_unaligned (d0, dst); + + if (max_len <= 16) + return; + + mask += add; + d1 = u8x16_blend (d1, s1, u8x16_is_greater (lv, mask)); + u8x16_store_unaligned (d1, dst + 16); + + if (max_len <= 32) + return; + + mask += add; + d2 = u8x16_blend (d2, s2, u8x16_is_greater (lv, mask)); + u8x16_store_unaligned (d2, dst + 32); + + mask += add; + d3 = u8x16_blend (d3, s3, u8x16_is_greater (lv, mask)); + u8x16_store_unaligned (d3, dst + 48); +#else + memmove (dst, src, len); +#endif +} + +static_always_inline void +clib_memcpy_le64 (u8 * dst, u8 * src, u8 len) +{ + clib_memcpy_le (dst, src, len, 64); +} + +static_always_inline void +clib_memcpy_le32 (u8 * dst, u8 * src, u8 len) +{ + clib_memcpy_le (dst, src, len, 32); +} + static_always_inline void clib_memset_u64 (void *p, u64 val, uword count) {