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