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 246