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