LCOV - code coverage report
Current view: top level - vppinfra - memcpy.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 44 57 77.2 %
Date: 2023-07-05 22:20:52 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: Apache-2.0
       2             :  * Copyright(c) 2021 Cisco Systems, Inc.
       3             :  */
       4             : 
       5             : #include <vppinfra/clib.h>
       6             : #ifndef included_memcpy_h
       7             : #define included_memcpy_h
       8             : 
       9             : static_always_inline void
      10             : clib_memcpy_may_overrun (void *dst, void *src, u32 n_bytes)
      11             : {
      12             :   word n_left = n_bytes;
      13             : #if defined(CLIB_HAVE_VEC512)
      14             :   u8x64u *sv = (u8x64u *) src;
      15             :   u8x64u *dv = (u8x64u *) dst;
      16             : #elif defined(CLIB_HAVE_VEC256)
      17             :   u8x32u *sv = (u8x32u *) src;
      18             :   u8x32u *dv = (u8x32u *) dst;
      19             : #elif defined(CLIB_HAVE_VEC128)
      20             :   u8x16u *sv = (u8x16u *) src;
      21             :   u8x16u *dv = (u8x16u *) dst;
      22             : #else
      23             :   u64u *sv = (u64u *) src;
      24             :   u64u *dv = (u64u *) dst;
      25             : #endif
      26             : 
      27             :   while (n_left >= 4 * sizeof (sv[0]))
      28             :     {
      29             :       __typeof__ (*sv) v0, v1, v2, v3;
      30             :       v0 = sv[0];
      31             :       v1 = sv[1];
      32             :       v2 = sv[2];
      33             :       v3 = sv[3];
      34             :       sv += 4;
      35             :       n_left -= 4 * sizeof (sv[0]);
      36             :       dv[0] = v0;
      37             :       dv[1] = v1;
      38             :       dv[2] = v2;
      39             :       dv[3] = v3;
      40             :       dv += 4;
      41             :     }
      42             : 
      43             :   while (n_left > 0)
      44             :     {
      45             :       dv[0] = sv[0];
      46             :       sv += 1;
      47             :       dv += 1;
      48             :       n_left -= sizeof (sv[0]);
      49             :     }
      50             : }
      51             : 
      52             : #ifndef __COVERITY__
      53             : 
      54             : static_always_inline void
      55     3392871 : clib_memcpy_u32_x4 (u32 *dst, u32 *src)
      56             : {
      57             : #if defined(CLIB_HAVE_VEC128)
      58     3392871 :   u32x4_store_unaligned (u32x4_load_unaligned (src), dst);
      59             : #else
      60             :   clib_memcpy_fast (dst, src, 4 * sizeof (u32));
      61             : #endif
      62     3392867 : }
      63             : static_always_inline void
      64    78461479 : clib_memcpy_u32_x8 (u32 *dst, u32 *src)
      65             : {
      66             : #if defined(CLIB_HAVE_VEC256)
      67    76894071 :   u32x8_store_unaligned (u32x8_load_unaligned (src), dst);
      68             : #else
      69     1567408 :   clib_memcpy_u32_x4 (dst, src);
      70     1567409 :   clib_memcpy_u32_x4 (dst + 4, src + 4);
      71             : #endif
      72    78461474 : }
      73             : 
      74             : static_always_inline void
      75    38096228 : clib_memcpy_u32_x16 (u32 *dst, u32 *src)
      76             : {
      77             : #if defined(CLIB_HAVE_VEC512)
      78           0 :   u32x16_store_unaligned (u32x16_load_unaligned (src), dst);
      79             : #else
      80    38096228 :   clib_memcpy_u32_x8 (dst, src);
      81    38096219 :   clib_memcpy_u32_x8 (dst + 8, src + 8);
      82             : #endif
      83    38096121 : }
      84             : 
      85             : static_always_inline void
      86    36861514 : clib_memcpy_u32 (u32 *dst, u32 *src, u32 n_left)
      87             : {
      88             : #if defined(CLIB_HAVE_VEC128)
      89             :   if (COMPILE_TIME_CONST (n_left))
      90             :     {
      91             :       /* for n_left defined as compile-time constant we should prevent compiler
      92             :        * to use more expensive mask load/store for common cases where smaller
      93             :        * register load/store exists */
      94             :       switch (n_left)
      95             :         {
      96             :         case 4:
      97             :           clib_memcpy_u32_x4 (dst, src);
      98             :           return;
      99             :         case 8:
     100             :           clib_memcpy_u32_x8 (dst, src);
     101             :           return;
     102             :         case 12:
     103             :           clib_memcpy_u32_x8 (dst, src);
     104             :           clib_memcpy_u32_x4 (dst + 8, src + 8);
     105             :           return;
     106             :         case 16:
     107             :           clib_memcpy_u32_x16 (dst, src);
     108             :           return;
     109             :         case 32:
     110             :           clib_memcpy_u32_x16 (dst, src);
     111             :           clib_memcpy_u32_x16 (dst + 16, src + 16);
     112             :           return;
     113             :         case 64:
     114             :           clib_memcpy_u32_x16 (dst, src);
     115             :           clib_memcpy_u32_x16 (dst + 16, src + 16);
     116             :           clib_memcpy_u32_x16 (dst + 32, src + 32);
     117             :           clib_memcpy_u32_x16 (dst + 48, src + 48);
     118             :           return;
     119             :         default:
     120             :           break;
     121             :         }
     122    36861514 :     }
     123             : 
     124             : #if defined(CLIB_HAVE_VEC512)
     125           0 :   while (n_left >= 64)
     126             :     {
     127           0 :       clib_memcpy_u32_x16 (dst, src);
     128           0 :       clib_memcpy_u32_x16 (dst + 16, src + 16);
     129           0 :       clib_memcpy_u32_x16 (dst + 32, src + 32);
     130           0 :       clib_memcpy_u32_x16 (dst + 48, src + 48);
     131           0 :       dst += 64;
     132           0 :       src += 64;
     133           0 :       n_left -= 64;
     134             :     }
     135             : #endif
     136             : 
     137             : #if defined(CLIB_HAVE_VEC256)
     138    53840032 :   while (n_left >= 32)
     139             :     {
     140    17752704 :       clib_memcpy_u32_x16 (dst, src);
     141    17752704 :       clib_memcpy_u32_x16 (dst + 16, src + 16);
     142    17752704 :       dst += 32;
     143    17752704 :       src += 32;
     144    17752704 :       n_left -= 32;
     145             :     }
     146             : #endif
     147             : 
     148    39452273 :   while (n_left >= 16)
     149             :     {
     150     2590789 :       clib_memcpy_u32_x16 (dst, src);
     151     2590780 :       dst += 16;
     152     2590780 :       src += 16;
     153     2590780 :       n_left -= 16;
     154             :     }
     155             : 
     156             : #if defined(CLIB_HAVE_VEC512_MASK_LOAD_STORE)
     157           0 :   if (n_left)
     158             :     {
     159           0 :       u16 mask = pow2_mask (n_left);
     160           0 :       u32x16_mask_store (u32x16_mask_load_zero (src, mask), dst, mask);
     161             :     }
     162           0 :   return;
     163             : #endif
     164             : 
     165    36861507 :   if (n_left >= 8)
     166             :     {
     167     2269176 :       clib_memcpy_u32_x8 (dst, src);
     168     2269177 :       dst += 8;
     169     2269177 :       src += 8;
     170     2269177 :       n_left -= 8;
     171             :     }
     172             : 
     173             : #if defined(CLIB_HAVE_VEC256_MASK_LOAD_STORE)
     174    36087343 :   if (n_left)
     175             :     {
     176    29750870 :       u8 mask = pow2_mask (n_left);
     177    29750870 :       u32x8_mask_store (u32x8_mask_load_zero (src, mask), dst, mask);
     178             :     }
     179    36087363 :   return;
     180             : #endif
     181             : 
     182      774165 :   if (n_left >= 4)
     183             :     {
     184      258051 :       clib_memcpy_u32_x4 (dst, src);
     185      258051 :       dst += 4;
     186      258051 :       src += 4;
     187      258051 :       n_left -= 4;
     188             :     }
     189             : #endif
     190             : 
     191     1563063 :   while (n_left)
     192             :     {
     193      788898 :       dst[0] = src[0];
     194      788898 :       dst += 1;
     195      788898 :       src += 1;
     196      788898 :       n_left -= 1;
     197             :     }
     198             : }
     199             : 
     200             : #else /* __COVERITY__ */
     201             : static_always_inline void
     202             : clib_memcpy_u32 (u32 *dst, u32 *src, u32 n_left)
     203             : {
     204             :   memcpy (dst, src, n_left * sizeof (u32));
     205             : }
     206             : #endif
     207             : 
     208             : #endif

Generated by: LCOV version 1.14