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