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