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