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