New upstream version 17.11-rc3
[deb_dpdk.git] / lib / librte_member / rte_member_x86.h
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2017 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #ifndef _RTE_MEMBER_X86_H_
35 #define _RTE_MEMBER_X86_H_
36
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40
41 #include <x86intrin.h>
42
43 #if defined(RTE_MACHINE_CPUFLAG_AVX2)
44
45 static inline int
46 update_entry_search_avx(uint32_t bucket_id, member_sig_t tmp_sig,
47                 struct member_ht_bucket *buckets,
48                 member_set_t set_id)
49 {
50         uint32_t hitmask = _mm256_movemask_epi8((__m256i)_mm256_cmpeq_epi16(
51                 _mm256_load_si256((__m256i const *)buckets[bucket_id].sigs),
52                 _mm256_set1_epi16(tmp_sig)));
53         if (hitmask) {
54                 uint32_t hit_idx = __builtin_ctzl(hitmask) >> 1;
55                 buckets[bucket_id].sets[hit_idx] = set_id;
56                 return 1;
57         }
58         return 0;
59 }
60
61 static inline int
62 search_bucket_single_avx(uint32_t bucket_id, member_sig_t tmp_sig,
63                 struct member_ht_bucket *buckets,
64                 member_set_t *set_id)
65 {
66         uint32_t hitmask = _mm256_movemask_epi8((__m256i)_mm256_cmpeq_epi16(
67                 _mm256_load_si256((__m256i const *)buckets[bucket_id].sigs),
68                 _mm256_set1_epi16(tmp_sig)));
69         while (hitmask) {
70                 uint32_t hit_idx = __builtin_ctzl(hitmask) >> 1;
71                 if (buckets[bucket_id].sets[hit_idx] != RTE_MEMBER_NO_MATCH) {
72                         *set_id = buckets[bucket_id].sets[hit_idx];
73                         return 1;
74                 }
75                 hitmask &= ~(3U << ((hit_idx) << 1));
76         }
77         return 0;
78 }
79
80 static inline void
81 search_bucket_multi_avx(uint32_t bucket_id, member_sig_t tmp_sig,
82                                 struct member_ht_bucket *buckets,
83                                 uint32_t *counter,
84                                 uint32_t match_per_key,
85                                 member_set_t *set_id)
86 {
87         uint32_t hitmask = _mm256_movemask_epi8((__m256i)_mm256_cmpeq_epi16(
88                 _mm256_load_si256((__m256i const *)buckets[bucket_id].sigs),
89                 _mm256_set1_epi16(tmp_sig)));
90         while (hitmask) {
91                 uint32_t hit_idx = __builtin_ctzl(hitmask) >> 1;
92                 if (buckets[bucket_id].sets[hit_idx] != RTE_MEMBER_NO_MATCH) {
93                         set_id[*counter] = buckets[bucket_id].sets[hit_idx];
94                         (*counter)++;
95                         if (*counter >= match_per_key)
96                                 return;
97                 }
98                 hitmask &= ~(3U << ((hit_idx) << 1));
99         }
100 }
101 #endif
102
103 #ifdef __cplusplus
104 }
105 #endif
106
107 #endif /* _RTE_MEMBER_X86_H_ */