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