LCOV - code coverage report
Current view: top level - vppinfra - vector_sse42.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 54 63 85.7 %
Date: 2023-10-26 01:39:38 Functions: 28 33 84.8 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2015 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       5             :  * You may obtain a copy of the License at:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       9             :  * Unless required by applicable law or agreed to in writing, software
      10             :  * distributed under the License is distributed on an "AS IS" BASIS,
      11             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             :  * See the License for the specific language governing permissions and
      13             :  * limitations under the License.
      14             :  */
      15             : /*
      16             :   Copyright (c) 2005 Eliot Dresselhaus
      17             : 
      18             :   Permission is hereby granted, free of charge, to any person obtaining
      19             :   a copy of this software and associated documentation files (the
      20             :   "Software"), to deal in the Software without restriction, including
      21             :   without limitation the rights to use, copy, modify, merge, publish,
      22             :   distribute, sublicense, and/or sell copies of the Software, and to
      23             :   permit persons to whom the Software is furnished to do so, subject to
      24             :   the following conditions:
      25             : 
      26             :   The above copyright notice and this permission notice shall be
      27             :   included in all copies or substantial portions of the Software.
      28             : 
      29             :   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      30             :   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      31             :   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
      32             :   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
      33             :   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
      34             :   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
      35             :   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      36             : */
      37             : 
      38             : #ifndef included_vector_sse2_h
      39             : #define included_vector_sse2_h
      40             : 
      41             : #include <vppinfra/error_bootstrap.h>     /* for ASSERT */
      42             : #include <x86intrin.h>
      43             : 
      44             : /* *INDENT-OFF* */
      45             : #define foreach_sse42_vec128i \
      46             :   _(i,8,16,epi8) _(i,16,8,epi16) _(i,32,4,epi32)  _(i,64,2,epi64x)
      47             : #define foreach_sse42_vec128u \
      48             :   _(u,8,16,epi8) _(u,16,8,epi16) _(u,32,4,epi32)  _(u,64,2,epi64x)
      49             : #define foreach_sse42_vec128f \
      50             :   _(f,32,4,ps) _(f,64,2,pd)
      51             : 
      52             : /* splat, load_unaligned, store_unaligned, is_all_zero, is_equal,
      53             :    is_all_equal */
      54             : #define _(t, s, c, i) \
      55             : static_always_inline t##s##x##c                                         \
      56             : t##s##x##c##_splat (t##s x)                                             \
      57             : { return (t##s##x##c) _mm_set1_##i (x); }                               \
      58             : \
      59             : static_always_inline t##s##x##c                                         \
      60             : t##s##x##c##_load_unaligned (void *p)                                   \
      61             : { return (t##s##x##c) _mm_loadu_si128 (p); }                            \
      62             : \
      63             : static_always_inline void                                               \
      64             : t##s##x##c##_store_unaligned (t##s##x##c v, void *p)                    \
      65             : { _mm_storeu_si128 ((__m128i *) p, (__m128i) v); }                      \
      66             : \
      67             : static_always_inline int                                                \
      68             : t##s##x##c##_is_all_zero (t##s##x##c x)                                 \
      69             : { return _mm_testz_si128 ((__m128i) x, (__m128i) x); }                  \
      70             : \
      71             : static_always_inline int                                                \
      72             : t##s##x##c##_is_equal (t##s##x##c a, t##s##x##c b)                      \
      73             : { return t##s##x##c##_is_all_zero (a ^ b); }                            \
      74             : \
      75             : static_always_inline int                                                \
      76             : t##s##x##c##_is_all_equal (t##s##x##c v, t##s x)                        \
      77             : { return t##s##x##c##_is_equal (v, t##s##x##c##_splat (x)); };          \
      78             : 
      79 67370872142 : foreach_sse42_vec128i foreach_sse42_vec128u
      80             : #undef _
      81             : 
      82             : /* min, max */
      83             : #define _(t, s, c, i) \
      84             : static_always_inline t##s##x##c                                         \
      85             : t##s##x##c##_min (t##s##x##c a, t##s##x##c b)                           \
      86             : { return (t##s##x##c) _mm_min_##i ((__m128i) a, (__m128i) b); }         \
      87             : \
      88             : static_always_inline t##s##x##c                                         \
      89             : t##s##x##c##_max (t##s##x##c a, t##s##x##c b)                           \
      90             : { return (t##s##x##c) _mm_max_##i ((__m128i) a, (__m128i) b); }         \
      91             : 
      92             : _(i,8,16,epi8) _(i,16,8,epi16) _(i,32,4,epi32)  _(i,64,2,epi64)
      93       41056 : _(u,8,16,epu8) _(u,16,8,epu16) _(u,32,4,epu32)  _(u,64,2,epu64)
      94             : #undef _
      95             : /* *INDENT-ON* */
      96             : 
      97             : #define CLIB_VEC128_SPLAT_DEFINED
      98             : #define CLIB_HAVE_VEC128_UNALIGNED_LOAD_STORE
      99             : 
     100             : /* 128 bit interleaves. */
     101             : always_inline u8x16
     102             : u8x16_interleave_hi (u8x16 a, u8x16 b)
     103             : {
     104             :   return (u8x16) _mm_unpackhi_epi8 ((__m128i) a, (__m128i) b);
     105             : }
     106             : 
     107             : always_inline u8x16
     108             : u8x16_interleave_lo (u8x16 a, u8x16 b)
     109             : {
     110             :   return (u8x16) _mm_unpacklo_epi8 ((__m128i) a, (__m128i) b);
     111             : }
     112             : 
     113             : always_inline u16x8
     114             : u16x8_interleave_hi (u16x8 a, u16x8 b)
     115             : {
     116             :   return (u16x8) _mm_unpackhi_epi16 ((__m128i) a, (__m128i) b);
     117             : }
     118             : 
     119             : always_inline u16x8
     120             : u16x8_interleave_lo (u16x8 a, u16x8 b)
     121             : {
     122             :   return (u16x8) _mm_unpacklo_epi16 ((__m128i) a, (__m128i) b);
     123             : }
     124             : 
     125             : always_inline u32x4
     126   575503000 : u32x4_interleave_hi (u32x4 a, u32x4 b)
     127             : {
     128  1151010000 :   return (u32x4) _mm_unpackhi_epi32 ((__m128i) a, (__m128i) b);
     129             : }
     130             : 
     131             : always_inline u32x4
     132   575503000 : u32x4_interleave_lo (u32x4 a, u32x4 b)
     133             : {
     134  1151010000 :   return (u32x4) _mm_unpacklo_epi32 ((__m128i) a, (__m128i) b);
     135             : }
     136             : 
     137             : always_inline u64x2
     138             : u64x2_interleave_hi (u64x2 a, u64x2 b)
     139             : {
     140             :   return (u64x2) _mm_unpackhi_epi64 ((__m128i) a, (__m128i) b);
     141             : }
     142             : 
     143             : always_inline u64x2
     144             : u64x2_interleave_lo (u64x2 a, u64x2 b)
     145             : {
     146             :   return (u64x2) _mm_unpacklo_epi64 ((__m128i) a, (__m128i) b);
     147             : }
     148             : 
     149             : /* 128 bit packs. */
     150             : #define _(f, t, fn)                                                           \
     151             :   always_inline t t##_pack (f lo, f hi)                                       \
     152             :   {                                                                           \
     153             :     return (t) fn ((__m128i) lo, (__m128i) hi);                               \
     154             :   }
     155             : 
     156           0 : _ (i16x8, i8x16, _mm_packs_epi16)
     157             : _ (i16x8, u8x16, _mm_packus_epi16)
     158           0 : _ (i32x4, i16x8, _mm_packs_epi32)
     159             : _ (i32x4, u16x8, _mm_packus_epi32)
     160             : 
     161             : #undef _
     162             : 
     163             : #define _signed_binop(n,m,f,g)                                         \
     164             :   /* Unsigned */                                                       \
     165             :   always_inline u##n##x##m                                             \
     166             :   u##n##x##m##_##f (u##n##x##m x, u##n##x##m y)                        \
     167             :   { return (u##n##x##m) _mm_##g##n ((__m128i) x, (__m128i) y); } \
     168             :                                                                        \
     169             :   /* Signed */                                                         \
     170             :   always_inline i##n##x##m                                             \
     171             :   i##n##x##m##_##f (i##n##x##m x, i##n##x##m y)                        \
     172             :   { return (i##n##x##m) _mm_##g##n ((__m128i) x, (__m128i) y); }
     173             : /* Addition/subtraction with saturation. */
     174             : _signed_binop (8, 16, add_saturate, adds_epu)
     175             : _signed_binop (16, 8, add_saturate, adds_epu)
     176             : _signed_binop (8, 16, sub_saturate, subs_epu)
     177             : _signed_binop (16, 8, sub_saturate, subs_epu)
     178             : /* Multiplication. */
     179             :      always_inline i16x8 i16x8_mul_lo (i16x8 x, i16x8 y)
     180             : {
     181             :   return (i16x8) _mm_mullo_epi16 ((__m128i) x, (__m128i) y);
     182             : }
     183             : 
     184             : always_inline u16x8
     185             : u16x8_mul_lo (u16x8 x, u16x8 y)
     186             : {
     187             :   return (u16x8) _mm_mullo_epi16 ((__m128i) x, (__m128i) y);
     188             : }
     189             : 
     190             : always_inline i16x8
     191             : i16x8_mul_hi (i16x8 x, i16x8 y)
     192             : {
     193             :   return (i16x8) _mm_mulhi_epu16 ((__m128i) x, (__m128i) y);
     194             : }
     195             : 
     196             : always_inline u16x8
     197             : u16x8_mul_hi (u16x8 x, u16x8 y)
     198             : {
     199             :   return (u16x8) _mm_mulhi_epu16 ((__m128i) x, (__m128i) y);
     200             : }
     201             : 
     202             : /* 128 bit shifts. */
     203             : 
     204             : #define _(p,a,b,c,f)           \
     205             :   always_inline p##a##x##b p##a##x##b##_ishift_##c (p##a##x##b x, int i)       \
     206             :   { return (p##a##x##b) _mm_##f##i_epi##a ((__m128i) x, i); }                  \
     207             :                                                                                \
     208             :   always_inline p##a##x##b p##a##x##b##_shift_##c (p##a##x##b x, p##a##x##b y) \
     209             :   { return (p##a##x##b) _mm_##f##_epi##a ((__m128i) x, (__m128i) y); }
     210             : 
     211             : _(u, 16, 8, left, sll)
     212             : _(u, 32, 4, left, sll)
     213             : _(u, 64, 2, left, sll)
     214             : _(u, 16, 8, right, srl)
     215             : _(u, 32, 4, right, srl)
     216             : _(u, 64, 2, right, srl)
     217             : _(i, 16, 8, left, sll)
     218             : _(i, 32, 4, left, sll)
     219             : _(i, 64, 2, left, sll) _(i, 16, 8, right, sra) _(i, 32, 4, right, sra)
     220             : #undef _
     221             : 
     222             : #define u8x16_word_shift_left(a,n)  (u8x16) _mm_slli_si128((__m128i) a, n)
     223             : #define u8x16_word_shift_right(a,n) (u8x16) _mm_srli_si128((__m128i) a, n)
     224             : 
     225             : #define i8x16_word_shift_left(a,n) \
     226             :   ((i8x16) u8x16_word_shift_left((u8x16) (a), (n)))
     227             : #define i8x16_word_shift_right(a,n) \
     228             :   ((i8x16) u8x16_word_shift_right((u8x16) (a), (n)))
     229             : 
     230             : #define u16x8_word_shift_left(a,n) \
     231             :   ((u16x8) u8x16_word_shift_left((u8x16) (a), (n) * sizeof (u16)))
     232             : #define i16x8_word_shift_left(a,n) \
     233             :   ((u16x8) u8x16_word_shift_left((u8x16) (a), (n) * sizeof (u16)))
     234             : #define u16x8_word_shift_right(a,n) \
     235             :   ((u16x8) u8x16_word_shift_right((u8x16) (a), (n) * sizeof (u16)))
     236             : #define i16x8_word_shift_right(a,n) \
     237             :   ((i16x8) u8x16_word_shift_right((u8x16) (a), (n) * sizeof (u16)))
     238             : 
     239             : #define u32x4_word_shift_left(a,n) \
     240             :   ((u32x4) u8x16_word_shift_left((u8x16) (a), (n) * sizeof (u32)))
     241             : #define i32x4_word_shift_left(a,n) \
     242             :   ((u32x4) u8x16_word_shift_left((u8x16) (a), (n) * sizeof (u32)))
     243             : #define u32x4_word_shift_right(a,n) \
     244             :   ((u32x4) u8x16_word_shift_right((u8x16) (a), (n) * sizeof (u32)))
     245             : #define i32x4_word_shift_right(a,n) \
     246             :   ((i32x4) u8x16_word_shift_right((u8x16) (a), (n) * sizeof (u32)))
     247             : 
     248             : #define u64x2_word_shift_left(a,n) \
     249             :   ((u64x2) u8x16_word_shift_left((u8x16) (a), (n) * sizeof (u64)))
     250             : #define i64x2_word_shift_left(a,n) \
     251             :   ((u64x2) u8x16_word_shift_left((u8x16) (a), (n) * sizeof (u64)))
     252             : #define u64x2_word_shift_right(a,n) \
     253             :   ((u64x2) u8x16_word_shift_right((u8x16) (a), (n) * sizeof (u64)))
     254             : #define i64x2_word_shift_right(a,n) \
     255             :   ((i64x2) u8x16_word_shift_right((u8x16) (a), (n) * sizeof (u64)))
     256             : 
     257             : /* SSE2 has no rotate instructions: use shifts to simulate them. */
     258             : #define _(t,n,lr1,lr2)                                  \
     259             :   always_inline t##x##n                                 \
     260             :   t##x##n##_irotate_##lr1 (t##x##n w, int i)            \
     261             :   {                                                     \
     262             :     ASSERT (i >= 0 && i <= BITS (t));                     \
     263             :     return (t##x##n##_ishift_##lr1 (w, i)               \
     264             :             | t##x##n##_ishift_##lr2 (w, BITS (t) - i)); \
     265             :   }                                                     \
     266             :                                                         \
     267             :   always_inline t##x##n                                 \
     268             :   t##x##n##_rotate_##lr1 (t##x##n w, t##x##n i)         \
     269             :   {                                                     \
     270             :     t##x##n j = t##x##n##_splat (BITS (t));             \
     271             :     return (t##x##n##_shift_##lr1 (w, i)                \
     272             :             | t##x##n##_shift_##lr2 (w, j - i));        \
     273             :   }
     274             : 
     275             : _(u16, 8, left, right);
     276             : _(u16, 8, right, left);
     277             : _(u32, 4, left, right);
     278             : _(u32, 4, right, left);
     279             : _(u64, 2, left, right);
     280             : _(u64, 2, right, left);
     281             : 
     282             : #undef _
     283             : 
     284             : always_inline u32
     285             : u8x16_max_scalar (u8x16 x)
     286             : {
     287             :   x = u8x16_max (x, u8x16_word_shift_right (x, 8));
     288             :   x = u8x16_max (x, u8x16_word_shift_right (x, 4));
     289             :   x = u8x16_max (x, u8x16_word_shift_right (x, 2));
     290             :   x = u8x16_max (x, u8x16_word_shift_right (x, 1));
     291             :   return _mm_extract_epi16 ((__m128i) x, 0) & 0xff;
     292             : }
     293             : 
     294             : always_inline u8
     295             : u8x16_min_scalar (u8x16 x)
     296             : {
     297             :   x = u8x16_min (x, u8x16_word_shift_right (x, 8));
     298             :   x = u8x16_min (x, u8x16_word_shift_right (x, 4));
     299             :   x = u8x16_min (x, u8x16_word_shift_right (x, 2));
     300             :   x = u8x16_min (x, u8x16_word_shift_right (x, 1));
     301             :   return _mm_extract_epi16 ((__m128i) x, 0) & 0xff;
     302             : }
     303             : 
     304             : always_inline i16
     305             : i16x8_max_scalar (i16x8 x)
     306             : {
     307             :   x = i16x8_max (x, i16x8_word_shift_right (x, 4));
     308             :   x = i16x8_max (x, i16x8_word_shift_right (x, 2));
     309             :   x = i16x8_max (x, i16x8_word_shift_right (x, 1));
     310             :   return _mm_extract_epi16 ((__m128i) x, 0);
     311             : }
     312             : 
     313             : always_inline i16
     314             : i16x8_min_scalar (i16x8 x)
     315             : {
     316             :   x = i16x8_min (x, i16x8_word_shift_right (x, 4));
     317             :   x = i16x8_min (x, i16x8_word_shift_right (x, 2));
     318             :   x = i16x8_min (x, i16x8_word_shift_right (x, 1));
     319             :   return _mm_extract_epi16 ((__m128i) x, 0);
     320             : }
     321             : 
     322             : #define u8x16_align_right(a, b, imm) \
     323             :   (u8x16) _mm_alignr_epi8 ((__m128i) a, (__m128i) b, imm)
     324             : 
     325             : static_always_inline u32
     326       10264 : u32x4_min_scalar (u32x4 v)
     327             : {
     328       10264 :   v = u32x4_min (v, (u32x4) u8x16_align_right ((u8x16) v, (u8x16) v, 8));
     329       10264 :   v = u32x4_min (v, (u32x4) u8x16_align_right ((u8x16) v, (u8x16) v, 4));
     330       10264 :   return v[0];
     331             : }
     332             : 
     333             : static_always_inline u32
     334             : u32x4_max_scalar (u32x4 v)
     335             : {
     336             :   v = u32x4_max (v, (u32x4) u8x16_align_right ((u8x16) v, (u8x16) v, 8));
     337             :   v = u32x4_max (v, (u32x4) u8x16_align_right ((u8x16) v, (u8x16) v, 4));
     338             :   return v[0];
     339             : }
     340             : 
     341             : static_always_inline u32
     342             : i32x4_min_scalar (i32x4 v)
     343             : {
     344             :   v = i32x4_min (v, (i32x4) u8x16_align_right ((u8x16) v, (u8x16) v, 8));
     345             :   v = i32x4_min (v, (i32x4) u8x16_align_right ((u8x16) v, (u8x16) v, 4));
     346             :   return v[0];
     347             : }
     348             : 
     349             : static_always_inline u32
     350             : i32x4_max_scalar (i32x4 v)
     351             : {
     352             :   v = i32x4_max (v, (i32x4) u8x16_align_right ((u8x16) v, (u8x16) v, 8));
     353             :   v = i32x4_max (v, (i32x4) u8x16_align_right ((u8x16) v, (u8x16) v, 4));
     354             :   return v[0];
     355             : }
     356             : 
     357             : static_always_inline u16
     358           0 : u8x16_msb_mask (u8x16 v)
     359             : {
     360           0 :   return _mm_movemask_epi8 ((__m128i) v);
     361             : }
     362             : 
     363             : static_always_inline u16
     364           0 : i8x16_msb_mask (i8x16 v)
     365             : {
     366           0 :   return _mm_movemask_epi8 ((__m128i) v);
     367             : }
     368             : 
     369             : #define CLIB_HAVE_VEC128_MSB_MASK
     370             : 
     371             : #undef _signed_binop
     372             : 
     373             : static_always_inline u32x4
     374             : u32x4_byte_swap (u32x4 v)
     375             : {
     376             :   u8x16 swap = {
     377             :     3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
     378             :   };
     379             :   return (u32x4) _mm_shuffle_epi8 ((__m128i) v, (__m128i) swap);
     380             : }
     381             : 
     382             : static_always_inline u16x8
     383             : u16x8_byte_swap (u16x8 v)
     384             : {
     385             :   u8x16 swap = {
     386             :     1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14,
     387             :   };
     388             :   return (u16x8) _mm_shuffle_epi8 ((__m128i) v, (__m128i) swap);
     389             : }
     390             : 
     391             : static_always_inline u8x16
     392     8036920 : u8x16_reflect (u8x16 v)
     393             : {
     394     8036920 :   u8x16 mask = {
     395             :     15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
     396             :   };
     397    16073800 :   return (u8x16) _mm_shuffle_epi8 ((__m128i) v, (__m128i) mask);
     398             : }
     399             : 
     400             : static_always_inline u32x4
     401             : u32x4_hadd (u32x4 v1, u32x4 v2)
     402             : {
     403             :   return (u32x4) _mm_hadd_epi32 ((__m128i) v1, (__m128i) v2);
     404             : }
     405             : 
     406             : static_always_inline u32 __clib_unused
     407             : u32x4_sum_elts (u32x4 sum4)
     408             : {
     409             :   sum4 += (u32x4) u8x16_align_right (sum4, sum4, 8);
     410             :   sum4 += (u32x4) u8x16_align_right (sum4, sum4, 4);
     411             :   return sum4[0];
     412             : }
     413             : 
     414             : /* _from_ */
     415             : /* *INDENT-OFF* */
     416             : #define _(f,t,i) \
     417             : static_always_inline t                                                  \
     418             : t##_from_##f (f x)                                                      \
     419             : { return (t) _mm_cvt##i ((__m128i) x); }
     420             : 
     421             : _(u8x16, u16x8, epu8_epi16)
     422             : _(u8x16, u32x4, epu8_epi32)
     423             : _(u8x16, u64x2, epu8_epi64)
     424             : _(u16x8, u32x4, epu16_epi32)
     425             : _(u16x8, u64x2, epu16_epi64)
     426    43715582 : _(u32x4, u64x2, epu32_epi64)
     427             : 
     428             : _(i8x16, i16x8, epi8_epi16)
     429             : _(i8x16, i32x4, epi8_epi32)
     430             : _(i8x16, i64x2, epi8_epi64)
     431             : _(i16x8, i32x4, epi16_epi32)
     432             : _(i16x8, i64x2, epi16_epi64)
     433             : _(i32x4, i64x2, epi32_epi64)
     434             : #undef _
     435             : /* *INDENT-ON* */
     436             : 
     437             : static_always_inline u64x2
     438             : u64x2_gather (void *p0, void *p1)
     439             : {
     440             :   u64x2 r = { *(u64 *) p0, *(u64 *) p1 };
     441             :   return r;
     442             : }
     443             : 
     444             : static_always_inline u32x4
     445         106 : u32x4_gather (void *p0, void *p1, void *p2, void *p3)
     446             : {
     447         106 :   u32x4 r = { *(u32 *) p0, *(u32 *) p1, *(u32 *) p2, *(u32 *) p3 };
     448         106 :   return r;
     449             : }
     450             : 
     451             : 
     452             : static_always_inline void
     453             : u64x2_scatter (u64x2 r, void *p0, void *p1)
     454             : {
     455             :   *(u64 *) p0 = r[0];
     456             :   *(u64 *) p1 = r[1];
     457             : }
     458             : 
     459             : static_always_inline void
     460             : u32x4_scatter (u32x4 r, void *p0, void *p1, void *p2, void *p3)
     461             : {
     462             :   *(u32 *) p0 = r[0];
     463             :   *(u32 *) p1 = r[1];
     464             :   *(u32 *) p2 = r[2];
     465             :   *(u32 *) p3 = r[3];
     466             : }
     467             : 
     468             : static_always_inline void
     469             : u64x2_scatter_one (u64x2 r, int index, void *p)
     470             : {
     471             :   *(u64 *) p = r[index];
     472             : }
     473             : 
     474             : static_always_inline void
     475             : u32x4_scatter_one (u32x4 r, int index, void *p)
     476             : {
     477             :   *(u32 *) p = r[index];
     478             : }
     479             : 
     480             : static_always_inline u8x16
     481           0 : u8x16_blend (u8x16 v1, u8x16 v2, u8x16 mask)
     482             : {
     483           0 :   return (u8x16) _mm_blendv_epi8 ((__m128i) v1, (__m128i) v2, (__m128i) mask);
     484             : }
     485             : 
     486             : static_always_inline u8x16
     487    19665892 : u8x16_xor3 (u8x16 a, u8x16 b, u8x16 c)
     488             : {
     489             : #if __AVX512F__
     490    19665892 :   return (u8x16) _mm_ternarylogic_epi32 ((__m128i) a, (__m128i) b,
     491             :                                          (__m128i) c, 0x96);
     492             : #endif
     493           0 :   return a ^ b ^ c;
     494             : }
     495             : 
     496             : static_always_inline u8x16
     497      131379 : u8x16_load_partial (u8 *data, uword n)
     498             : {
     499      131379 :   u8x16 r = {};
     500             : #if defined(CLIB_HAVE_VEC128_MASK_LOAD_STORE)
     501             :   return u8x16_mask_load_zero (data, pow2_mask (n));
     502             : #endif
     503      131379 :   if (n > 7)
     504             :     {
     505             :       u64x2 r;
     506       26939 :       r[1] = *(u64u *) (data + n - 8);
     507       26939 :       r >>= (16 - n) * 8;
     508       26939 :       r[0] = *(u64u *) data;
     509       26939 :       return (u8x16) r;
     510             :     }
     511      104440 :   else if (n > 3)
     512             :     {
     513      103821 :       u32x4 r = {};
     514      103821 :       r[1] = *(u32u *) (data + n - 4);
     515      103821 :       r >>= (8 - n) * 8;
     516      103821 :       r[0] = *(u32u *) data;
     517      103821 :       return (u8x16) r;
     518             :     }
     519         619 :   else if (n > 1)
     520             :     {
     521         441 :       u16x8 r = {};
     522         441 :       r[1] = *(u16u *) (data + n - 2);
     523         441 :       r >>= (4 - n) * 8;
     524         441 :       r[0] = *(u16u *) data;
     525         441 :       return (u8x16) r;
     526             :     }
     527         178 :   else if (n > 0)
     528         178 :     r[0] = *data;
     529         178 :   return r;
     530             : }
     531             : 
     532             : static_always_inline void
     533      131379 : u8x16_store_partial (u8x16 r, u8 *data, uword n)
     534             : {
     535             : #if defined(CLIB_HAVE_VEC256_MASK_LOAD_STORE)
     536             :   u8x16_mask_store (r, data, pow2_mask (n));
     537             : #else
     538      131379 :   if (n > 7)
     539             :     {
     540       26939 :       *(u64u *) (data + n - 8) = ((u64x2) r)[1] << ((16 - n) * 8);
     541       26939 :       *(u64u *) data = ((u64x2) r)[0];
     542             :     }
     543      104440 :   else if (n > 3)
     544             :     {
     545      103821 :       *(u32u *) (data + n - 4) = ((u32x4) r)[1] << ((8 - n) * 8);
     546      103821 :       *(u32u *) data = ((u32x4) r)[0];
     547             :     }
     548         619 :   else if (n > 1)
     549             :     {
     550         441 :       *(u16u *) (data + n - 2) = ((u16x8) r)[1] << ((4 - n) * 8);
     551         441 :       *(u16u *) data = ((u16x8) r)[0];
     552             :     }
     553         178 :   else if (n > 0)
     554         178 :     data[0] = r[0];
     555             : #endif
     556      131379 : }
     557             : 
     558             : #endif /* included_vector_sse2_h */
     559             : 
     560             : /*
     561             :  * fd.io coding-style-patch-verification: ON
     562             :  *
     563             :  * Local Variables:
     564             :  * eval: (c-set-style "gnu")
     565             :  * End:
     566             :  */

Generated by: LCOV version 1.14