xref: /dpdk/lib/table/rte_table_hash_func.h (revision 097ea8e2)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2010-2018 Intel Corporation
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
599a2dd95SBruce Richardson #ifndef __INCLUDE_RTE_TABLE_HASH_FUNC_H__
699a2dd95SBruce Richardson #define __INCLUDE_RTE_TABLE_HASH_FUNC_H__
799a2dd95SBruce Richardson 
899a2dd95SBruce Richardson #ifdef __cplusplus
999a2dd95SBruce Richardson extern "C" {
1099a2dd95SBruce Richardson #endif
1199a2dd95SBruce Richardson 
1299a2dd95SBruce Richardson #include <stdint.h>
1399a2dd95SBruce Richardson 
1499a2dd95SBruce Richardson #include <rte_compat.h>
1599a2dd95SBruce Richardson #include <rte_common.h>
1699a2dd95SBruce Richardson 
1799a2dd95SBruce Richardson __rte_experimental
1899a2dd95SBruce Richardson static inline uint64_t
rte_crc32_u64_generic(uint64_t crc,uint64_t value)1999a2dd95SBruce Richardson rte_crc32_u64_generic(uint64_t crc, uint64_t value)
2099a2dd95SBruce Richardson {
2199a2dd95SBruce Richardson 	int i;
2299a2dd95SBruce Richardson 
2399a2dd95SBruce Richardson 	crc = (crc & 0xFFFFFFFFLLU) ^ value;
2499a2dd95SBruce Richardson 	for (i = 63; i >= 0; i--) {
2599a2dd95SBruce Richardson 		uint64_t mask;
2699a2dd95SBruce Richardson 
2799a2dd95SBruce Richardson 		mask = -(crc & 1LLU);
2899a2dd95SBruce Richardson 		crc = (crc >> 1LLU) ^ (0x82F63B78LLU & mask);
2999a2dd95SBruce Richardson 	}
3099a2dd95SBruce Richardson 
3199a2dd95SBruce Richardson 	return crc;
3299a2dd95SBruce Richardson }
3399a2dd95SBruce Richardson 
3499a2dd95SBruce Richardson #if defined(RTE_ARCH_X86_64)
3599a2dd95SBruce Richardson 
3699a2dd95SBruce Richardson #include <x86intrin.h>
3799a2dd95SBruce Richardson 
3899a2dd95SBruce Richardson static inline uint64_t
rte_crc32_u64(uint64_t crc,uint64_t v)3999a2dd95SBruce Richardson rte_crc32_u64(uint64_t crc, uint64_t v)
4099a2dd95SBruce Richardson {
4199a2dd95SBruce Richardson 	return _mm_crc32_u64(crc, v);
4299a2dd95SBruce Richardson }
4399a2dd95SBruce Richardson 
4499a2dd95SBruce Richardson #elif defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_CRC32)
4599a2dd95SBruce Richardson #include "rte_table_hash_func_arm64.h"
4699a2dd95SBruce Richardson #else
4799a2dd95SBruce Richardson 
4899a2dd95SBruce Richardson static inline uint64_t
rte_crc32_u64(uint64_t crc,uint64_t v)4999a2dd95SBruce Richardson rte_crc32_u64(uint64_t crc, uint64_t v)
5099a2dd95SBruce Richardson {
5199a2dd95SBruce Richardson 	return rte_crc32_u64_generic(crc, v);
5299a2dd95SBruce Richardson }
5399a2dd95SBruce Richardson 
5499a2dd95SBruce Richardson #endif
5599a2dd95SBruce Richardson 
5699a2dd95SBruce Richardson __rte_experimental
5799a2dd95SBruce Richardson static inline uint64_t
rte_table_hash_crc_key8(void * key,void * mask,__rte_unused uint32_t key_size,uint64_t seed)5899a2dd95SBruce Richardson rte_table_hash_crc_key8(void *key, void *mask, __rte_unused uint32_t key_size,
5999a2dd95SBruce Richardson 	uint64_t seed)
6099a2dd95SBruce Richardson {
61*097ea8e2SBruce Richardson 	uint64_t *k = (uint64_t *)key;
62*097ea8e2SBruce Richardson 	uint64_t *m = (uint64_t *)mask;
6399a2dd95SBruce Richardson 	uint64_t crc0;
6499a2dd95SBruce Richardson 
6599a2dd95SBruce Richardson 	crc0 = rte_crc32_u64(seed, k[0] & m[0]);
6699a2dd95SBruce Richardson 
6799a2dd95SBruce Richardson 	return crc0;
6899a2dd95SBruce Richardson }
6999a2dd95SBruce Richardson 
7099a2dd95SBruce Richardson __rte_experimental
7199a2dd95SBruce Richardson static inline uint64_t
rte_table_hash_crc_key16(void * key,void * mask,__rte_unused uint32_t key_size,uint64_t seed)7299a2dd95SBruce Richardson rte_table_hash_crc_key16(void *key, void *mask, __rte_unused uint32_t key_size,
7399a2dd95SBruce Richardson 	uint64_t seed)
7499a2dd95SBruce Richardson {
75*097ea8e2SBruce Richardson 	uint64_t *k = (uint64_t *)key;
76*097ea8e2SBruce Richardson 	uint64_t *m = (uint64_t *)mask;
7799a2dd95SBruce Richardson 	uint64_t k0, crc0, crc1;
7899a2dd95SBruce Richardson 
7999a2dd95SBruce Richardson 	k0 = k[0] & m[0];
8099a2dd95SBruce Richardson 
8199a2dd95SBruce Richardson 	crc0 = rte_crc32_u64(k0, seed);
8299a2dd95SBruce Richardson 	crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
8399a2dd95SBruce Richardson 
8499a2dd95SBruce Richardson 	crc0 ^= crc1;
8599a2dd95SBruce Richardson 
8699a2dd95SBruce Richardson 	return crc0;
8799a2dd95SBruce Richardson }
8899a2dd95SBruce Richardson 
8999a2dd95SBruce Richardson __rte_experimental
9099a2dd95SBruce Richardson static inline uint64_t
rte_table_hash_crc_key24(void * key,void * mask,__rte_unused uint32_t key_size,uint64_t seed)9199a2dd95SBruce Richardson rte_table_hash_crc_key24(void *key, void *mask, __rte_unused uint32_t key_size,
9299a2dd95SBruce Richardson 	uint64_t seed)
9399a2dd95SBruce Richardson {
94*097ea8e2SBruce Richardson 	uint64_t *k = (uint64_t *)key;
95*097ea8e2SBruce Richardson 	uint64_t *m = (uint64_t *)mask;
9699a2dd95SBruce Richardson 	uint64_t k0, k2, crc0, crc1;
9799a2dd95SBruce Richardson 
9899a2dd95SBruce Richardson 	k0 = k[0] & m[0];
9999a2dd95SBruce Richardson 	k2 = k[2] & m[2];
10099a2dd95SBruce Richardson 
10199a2dd95SBruce Richardson 	crc0 = rte_crc32_u64(k0, seed);
10299a2dd95SBruce Richardson 	crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
10399a2dd95SBruce Richardson 
10499a2dd95SBruce Richardson 	crc0 = rte_crc32_u64(crc0, k2);
10599a2dd95SBruce Richardson 
10699a2dd95SBruce Richardson 	crc0 ^= crc1;
10799a2dd95SBruce Richardson 
10899a2dd95SBruce Richardson 	return crc0;
10999a2dd95SBruce Richardson }
11099a2dd95SBruce Richardson 
11199a2dd95SBruce Richardson __rte_experimental
11299a2dd95SBruce Richardson static inline uint64_t
rte_table_hash_crc_key32(void * key,void * mask,__rte_unused uint32_t key_size,uint64_t seed)11399a2dd95SBruce Richardson rte_table_hash_crc_key32(void *key, void *mask, __rte_unused uint32_t key_size,
11499a2dd95SBruce Richardson 	uint64_t seed)
11599a2dd95SBruce Richardson {
116*097ea8e2SBruce Richardson 	uint64_t *k = (uint64_t *)key;
117*097ea8e2SBruce Richardson 	uint64_t *m = (uint64_t *)mask;
11899a2dd95SBruce Richardson 	uint64_t k0, k2, crc0, crc1, crc2, crc3;
11999a2dd95SBruce Richardson 
12099a2dd95SBruce Richardson 	k0 = k[0] & m[0];
12199a2dd95SBruce Richardson 	k2 = k[2] & m[2];
12299a2dd95SBruce Richardson 
12399a2dd95SBruce Richardson 	crc0 = rte_crc32_u64(k0, seed);
12499a2dd95SBruce Richardson 	crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
12599a2dd95SBruce Richardson 
12699a2dd95SBruce Richardson 	crc2 = rte_crc32_u64(k2, k[3] & m[3]);
12799a2dd95SBruce Richardson 	crc3 = k2 >> 32;
12899a2dd95SBruce Richardson 
12999a2dd95SBruce Richardson 	crc0 = rte_crc32_u64(crc0, crc1);
13099a2dd95SBruce Richardson 	crc1 = rte_crc32_u64(crc2, crc3);
13199a2dd95SBruce Richardson 
13299a2dd95SBruce Richardson 	crc0 ^= crc1;
13399a2dd95SBruce Richardson 
13499a2dd95SBruce Richardson 	return crc0;
13599a2dd95SBruce Richardson }
13699a2dd95SBruce Richardson 
13799a2dd95SBruce Richardson __rte_experimental
13899a2dd95SBruce Richardson static inline uint64_t
rte_table_hash_crc_key40(void * key,void * mask,__rte_unused uint32_t key_size,uint64_t seed)13999a2dd95SBruce Richardson rte_table_hash_crc_key40(void *key, void *mask, __rte_unused uint32_t key_size,
14099a2dd95SBruce Richardson 	uint64_t seed)
14199a2dd95SBruce Richardson {
142*097ea8e2SBruce Richardson 	uint64_t *k = (uint64_t *)key;
143*097ea8e2SBruce Richardson 	uint64_t *m = (uint64_t *)mask;
14499a2dd95SBruce Richardson 	uint64_t k0, k2, crc0, crc1, crc2, crc3;
14599a2dd95SBruce Richardson 
14699a2dd95SBruce Richardson 	k0 = k[0] & m[0];
14799a2dd95SBruce Richardson 	k2 = k[2] & m[2];
14899a2dd95SBruce Richardson 
14999a2dd95SBruce Richardson 	crc0 = rte_crc32_u64(k0, seed);
15099a2dd95SBruce Richardson 	crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
15199a2dd95SBruce Richardson 
15299a2dd95SBruce Richardson 	crc2 = rte_crc32_u64(k2, k[3] & m[3]);
15399a2dd95SBruce Richardson 	crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]);
15499a2dd95SBruce Richardson 
15599a2dd95SBruce Richardson 	crc0 = rte_crc32_u64(crc0, crc1);
15699a2dd95SBruce Richardson 	crc1 = rte_crc32_u64(crc2, crc3);
15799a2dd95SBruce Richardson 
15899a2dd95SBruce Richardson 	crc0 ^= crc1;
15999a2dd95SBruce Richardson 
16099a2dd95SBruce Richardson 	return crc0;
16199a2dd95SBruce Richardson }
16299a2dd95SBruce Richardson 
16399a2dd95SBruce Richardson __rte_experimental
16499a2dd95SBruce Richardson static inline uint64_t
rte_table_hash_crc_key48(void * key,void * mask,__rte_unused uint32_t key_size,uint64_t seed)16599a2dd95SBruce Richardson rte_table_hash_crc_key48(void *key, void *mask, __rte_unused uint32_t key_size,
16699a2dd95SBruce Richardson 	uint64_t seed)
16799a2dd95SBruce Richardson {
168*097ea8e2SBruce Richardson 	uint64_t *k = (uint64_t *)key;
169*097ea8e2SBruce Richardson 	uint64_t *m = (uint64_t *)mask;
17099a2dd95SBruce Richardson 	uint64_t k0, k2, k5, crc0, crc1, crc2, crc3;
17199a2dd95SBruce Richardson 
17299a2dd95SBruce Richardson 	k0 = k[0] & m[0];
17399a2dd95SBruce Richardson 	k2 = k[2] & m[2];
17499a2dd95SBruce Richardson 	k5 = k[5] & m[5];
17599a2dd95SBruce Richardson 
17699a2dd95SBruce Richardson 	crc0 = rte_crc32_u64(k0, seed);
17799a2dd95SBruce Richardson 	crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
17899a2dd95SBruce Richardson 
17999a2dd95SBruce Richardson 	crc2 = rte_crc32_u64(k2, k[3] & m[3]);
18099a2dd95SBruce Richardson 	crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]);
18199a2dd95SBruce Richardson 
18299a2dd95SBruce Richardson 	crc0 = rte_crc32_u64(crc0, (crc1 << 32) ^ crc2);
18399a2dd95SBruce Richardson 	crc1 = rte_crc32_u64(crc3, k5);
18499a2dd95SBruce Richardson 
18599a2dd95SBruce Richardson 	crc0 ^= crc1;
18699a2dd95SBruce Richardson 
18799a2dd95SBruce Richardson 	return crc0;
18899a2dd95SBruce Richardson }
18999a2dd95SBruce Richardson 
19099a2dd95SBruce Richardson __rte_experimental
19199a2dd95SBruce Richardson static inline uint64_t
rte_table_hash_crc_key56(void * key,void * mask,__rte_unused uint32_t key_size,uint64_t seed)19299a2dd95SBruce Richardson rte_table_hash_crc_key56(void *key, void *mask, __rte_unused uint32_t key_size,
19399a2dd95SBruce Richardson 	uint64_t seed)
19499a2dd95SBruce Richardson {
195*097ea8e2SBruce Richardson 	uint64_t *k = (uint64_t *)key;
196*097ea8e2SBruce Richardson 	uint64_t *m = (uint64_t *)mask;
19799a2dd95SBruce Richardson 	uint64_t k0, k2, k5, crc0, crc1, crc2, crc3, crc4, crc5;
19899a2dd95SBruce Richardson 
19999a2dd95SBruce Richardson 	k0 = k[0] & m[0];
20099a2dd95SBruce Richardson 	k2 = k[2] & m[2];
20199a2dd95SBruce Richardson 	k5 = k[5] & m[5];
20299a2dd95SBruce Richardson 
20399a2dd95SBruce Richardson 	crc0 = rte_crc32_u64(k0, seed);
20499a2dd95SBruce Richardson 	crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
20599a2dd95SBruce Richardson 
20699a2dd95SBruce Richardson 	crc2 = rte_crc32_u64(k2, k[3] & m[3]);
20799a2dd95SBruce Richardson 	crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]);
20899a2dd95SBruce Richardson 
20999a2dd95SBruce Richardson 	crc4 = rte_crc32_u64(k5, k[6] & m[6]);
21099a2dd95SBruce Richardson 	crc5 = k5 >> 32;
21199a2dd95SBruce Richardson 
21299a2dd95SBruce Richardson 	crc0 = rte_crc32_u64(crc0, (crc1 << 32) ^ crc2);
21399a2dd95SBruce Richardson 	crc1 = rte_crc32_u64(crc3, (crc4 << 32) ^ crc5);
21499a2dd95SBruce Richardson 
21599a2dd95SBruce Richardson 	crc0 ^= crc1;
21699a2dd95SBruce Richardson 
21799a2dd95SBruce Richardson 	return crc0;
21899a2dd95SBruce Richardson }
21999a2dd95SBruce Richardson 
22099a2dd95SBruce Richardson __rte_experimental
22199a2dd95SBruce Richardson static inline uint64_t
rte_table_hash_crc_key64(void * key,void * mask,__rte_unused uint32_t key_size,uint64_t seed)22299a2dd95SBruce Richardson rte_table_hash_crc_key64(void *key, void *mask, __rte_unused uint32_t key_size,
22399a2dd95SBruce Richardson 	uint64_t seed)
22499a2dd95SBruce Richardson {
225*097ea8e2SBruce Richardson 	uint64_t *k = (uint64_t *)key;
226*097ea8e2SBruce Richardson 	uint64_t *m = (uint64_t *)mask;
22799a2dd95SBruce Richardson 	uint64_t k0, k2, k5, crc0, crc1, crc2, crc3, crc4, crc5;
22899a2dd95SBruce Richardson 
22999a2dd95SBruce Richardson 	k0 = k[0] & m[0];
23099a2dd95SBruce Richardson 	k2 = k[2] & m[2];
23199a2dd95SBruce Richardson 	k5 = k[5] & m[5];
23299a2dd95SBruce Richardson 
23399a2dd95SBruce Richardson 	crc0 = rte_crc32_u64(k0, seed);
23499a2dd95SBruce Richardson 	crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
23599a2dd95SBruce Richardson 
23699a2dd95SBruce Richardson 	crc2 = rte_crc32_u64(k2, k[3] & m[3]);
23799a2dd95SBruce Richardson 	crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]);
23899a2dd95SBruce Richardson 
23999a2dd95SBruce Richardson 	crc4 = rte_crc32_u64(k5, k[6] & m[6]);
24099a2dd95SBruce Richardson 	crc5 = rte_crc32_u64(k5 >> 32, k[7] & m[7]);
24199a2dd95SBruce Richardson 
24299a2dd95SBruce Richardson 	crc0 = rte_crc32_u64(crc0, (crc1 << 32) ^ crc2);
24399a2dd95SBruce Richardson 	crc1 = rte_crc32_u64(crc3, (crc4 << 32) ^ crc5);
24499a2dd95SBruce Richardson 
24599a2dd95SBruce Richardson 	crc0 ^= crc1;
24699a2dd95SBruce Richardson 
24799a2dd95SBruce Richardson 	return crc0;
24899a2dd95SBruce Richardson }
24999a2dd95SBruce Richardson 
25099a2dd95SBruce Richardson #ifdef __cplusplus
25199a2dd95SBruce Richardson }
25299a2dd95SBruce Richardson #endif
25399a2dd95SBruce Richardson 
25499a2dd95SBruce Richardson #endif
255