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