New upstream version 18.11-rc1
[deb_dpdk.git] / lib / librte_table / rte_table_hash_func.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2018 Intel Corporation
3  */
4
5 #ifndef __INCLUDE_RTE_TABLE_HASH_FUNC_H__
6 #define __INCLUDE_RTE_TABLE_HASH_FUNC_H__
7
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11
12 #include <stdint.h>
13
14 #include <rte_compat.h>
15 #include <rte_common.h>
16
17 static inline uint64_t __rte_experimental
18 rte_crc32_u64_generic(uint64_t crc, uint64_t value)
19 {
20         int i;
21
22         crc = (crc & 0xFFFFFFFFLLU) ^ value;
23         for (i = 63; i >= 0; i--) {
24                 uint64_t mask;
25
26                 mask = -(crc & 1LLU);
27                 crc = (crc >> 1LLU) ^ (0x82F63B78LLU & mask);
28         }
29
30         return crc;
31 }
32
33 #if defined(RTE_ARCH_X86_64)
34
35 #include <x86intrin.h>
36
37 static inline uint64_t
38 rte_crc32_u64(uint64_t crc, uint64_t v)
39 {
40         return _mm_crc32_u64(crc, v);
41 }
42
43 #elif defined(RTE_ARCH_ARM64)
44 #include "rte_table_hash_func_arm64.h"
45 #else
46
47 static inline uint64_t
48 rte_crc32_u64(uint64_t crc, uint64_t v)
49 {
50         return rte_crc32_u64_generic(crc, v);
51 }
52
53 #endif
54
55 static inline uint64_t __rte_experimental
56 rte_table_hash_crc_key8(void *key, void *mask, __rte_unused uint32_t key_size,
57         uint64_t seed)
58 {
59         uint64_t *k = key;
60         uint64_t *m = mask;
61         uint64_t crc0;
62
63         crc0 = rte_crc32_u64(seed, k[0] & m[0]);
64
65         return crc0;
66 }
67
68 static inline uint64_t __rte_experimental
69 rte_table_hash_crc_key16(void *key, void *mask, __rte_unused uint32_t key_size,
70         uint64_t seed)
71 {
72         uint64_t *k = key;
73         uint64_t *m = mask;
74         uint64_t k0, crc0, crc1;
75
76         k0 = k[0] & m[0];
77
78         crc0 = rte_crc32_u64(k0, seed);
79         crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
80
81         crc0 ^= crc1;
82
83         return crc0;
84 }
85
86 static inline uint64_t __rte_experimental
87 rte_table_hash_crc_key24(void *key, void *mask, __rte_unused uint32_t key_size,
88         uint64_t seed)
89 {
90         uint64_t *k = key;
91         uint64_t *m = mask;
92         uint64_t k0, k2, crc0, crc1;
93
94         k0 = k[0] & m[0];
95         k2 = k[2] & m[2];
96
97         crc0 = rte_crc32_u64(k0, seed);
98         crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
99
100         crc0 = rte_crc32_u64(crc0, k2);
101
102         crc0 ^= crc1;
103
104         return crc0;
105 }
106
107 static inline uint64_t __rte_experimental
108 rte_table_hash_crc_key32(void *key, void *mask, __rte_unused uint32_t key_size,
109         uint64_t seed)
110 {
111         uint64_t *k = key;
112         uint64_t *m = mask;
113         uint64_t k0, k2, crc0, crc1, crc2, crc3;
114
115         k0 = k[0] & m[0];
116         k2 = k[2] & m[2];
117
118         crc0 = rte_crc32_u64(k0, seed);
119         crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
120
121         crc2 = rte_crc32_u64(k2, k[3] & m[3]);
122         crc3 = k2 >> 32;
123
124         crc0 = rte_crc32_u64(crc0, crc1);
125         crc1 = rte_crc32_u64(crc2, crc3);
126
127         crc0 ^= crc1;
128
129         return crc0;
130 }
131
132 static inline uint64_t __rte_experimental
133 rte_table_hash_crc_key40(void *key, void *mask, __rte_unused uint32_t key_size,
134         uint64_t seed)
135 {
136         uint64_t *k = key;
137         uint64_t *m = mask;
138         uint64_t k0, k2, crc0, crc1, crc2, crc3;
139
140         k0 = k[0] & m[0];
141         k2 = k[2] & m[2];
142
143         crc0 = rte_crc32_u64(k0, seed);
144         crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
145
146         crc2 = rte_crc32_u64(k2, k[3] & m[3]);
147         crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]);
148
149         crc0 = rte_crc32_u64(crc0, crc1);
150         crc1 = rte_crc32_u64(crc2, crc3);
151
152         crc0 ^= crc1;
153
154         return crc0;
155 }
156
157 static inline uint64_t __rte_experimental
158 rte_table_hash_crc_key48(void *key, void *mask, __rte_unused uint32_t key_size,
159         uint64_t seed)
160 {
161         uint64_t *k = key;
162         uint64_t *m = mask;
163         uint64_t k0, k2, k5, crc0, crc1, crc2, crc3;
164
165         k0 = k[0] & m[0];
166         k2 = k[2] & m[2];
167         k5 = k[5] & m[5];
168
169         crc0 = rte_crc32_u64(k0, seed);
170         crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
171
172         crc2 = rte_crc32_u64(k2, k[3] & m[3]);
173         crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]);
174
175         crc0 = rte_crc32_u64(crc0, (crc1 << 32) ^ crc2);
176         crc1 = rte_crc32_u64(crc3, k5);
177
178         crc0 ^= crc1;
179
180         return crc0;
181 }
182
183 static inline uint64_t __rte_experimental
184 rte_table_hash_crc_key56(void *key, void *mask, __rte_unused uint32_t key_size,
185         uint64_t seed)
186 {
187         uint64_t *k = key;
188         uint64_t *m = mask;
189         uint64_t k0, k2, k5, crc0, crc1, crc2, crc3, crc4, crc5;
190
191         k0 = k[0] & m[0];
192         k2 = k[2] & m[2];
193         k5 = k[5] & m[5];
194
195         crc0 = rte_crc32_u64(k0, seed);
196         crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
197
198         crc2 = rte_crc32_u64(k2, k[3] & m[3]);
199         crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]);
200
201         crc4 = rte_crc32_u64(k5, k[6] & m[6]);
202         crc5 = k5 >> 32;
203
204         crc0 = rte_crc32_u64(crc0, (crc1 << 32) ^ crc2);
205         crc1 = rte_crc32_u64(crc3, (crc4 << 32) ^ crc5);
206
207         crc0 ^= crc1;
208
209         return crc0;
210 }
211
212 static inline uint64_t __rte_experimental
213 rte_table_hash_crc_key64(void *key, void *mask, __rte_unused uint32_t key_size,
214         uint64_t seed)
215 {
216         uint64_t *k = key;
217         uint64_t *m = mask;
218         uint64_t k0, k2, k5, crc0, crc1, crc2, crc3, crc4, crc5;
219
220         k0 = k[0] & m[0];
221         k2 = k[2] & m[2];
222         k5 = k[5] & m[5];
223
224         crc0 = rte_crc32_u64(k0, seed);
225         crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
226
227         crc2 = rte_crc32_u64(k2, k[3] & m[3]);
228         crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]);
229
230         crc4 = rte_crc32_u64(k5, k[6] & m[6]);
231         crc5 = rte_crc32_u64(k5 >> 32, k[7] & m[7]);
232
233         crc0 = rte_crc32_u64(crc0, (crc1 << 32) ^ crc2);
234         crc1 = rte_crc32_u64(crc3, (crc4 << 32) ^ crc5);
235
236         crc0 ^= crc1;
237
238         return crc0;
239 }
240
241 #ifdef __cplusplus
242 }
243 #endif
244
245 #endif