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