1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #ifndef _RTE_HASH_CRC_H_ 6 #define _RTE_HASH_CRC_H_ 7 8 /** 9 * @file 10 * 11 * RTE CRC Hash 12 */ 13 14 #include <stdint.h> 15 16 #include <rte_branch_prediction.h> 17 #include <rte_common.h> 18 #include <rte_config.h> 19 20 #include "rte_crc_sw.h" 21 22 #define CRC32_SW (1U << 0) 23 #define CRC32_SSE42 (1U << 1) 24 #define CRC32_x64 (1U << 2) 25 #define CRC32_SSE42_x64 (CRC32_x64|CRC32_SSE42) 26 #define CRC32_ARM64 (1U << 3) 27 28 extern uint8_t rte_hash_crc32_alg; 29 30 #if defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_CRC32) 31 #include "rte_crc_arm64.h" 32 #elif defined(RTE_ARCH_X86) 33 #include "rte_crc_x86.h" 34 #else 35 #include "rte_crc_generic.h" 36 #endif 37 38 #ifdef __cplusplus 39 extern "C" { 40 #endif 41 42 /** 43 * Allow or disallow use of SSE4.2/ARMv8 intrinsics for CRC32 hash 44 * calculation. 45 * 46 * @param alg 47 * An OR of following flags: 48 * - (CRC32_SW) Don't use SSE4.2/ARMv8 intrinsics (default non-[x86/ARMv8]) 49 * - (CRC32_SSE42) Use SSE4.2 intrinsics if available 50 * - (CRC32_SSE42_x64) Use 64-bit SSE4.2 intrinsic if available (default x86) 51 * - (CRC32_ARM64) Use ARMv8 CRC intrinsic if available (default ARMv8) 52 */ 53 void 54 rte_hash_crc_set_alg(uint8_t alg); 55 56 #ifdef __DOXYGEN__ 57 58 /** 59 * Use single CRC32 instruction to perform a hash on a byte value. 60 * 61 * @param data 62 * Data to perform hash on. 63 * @param init_val 64 * Value to initialise hash generator. 65 * @return 66 * 32bit calculated hash value. 67 */ 68 static inline uint32_t 69 rte_hash_crc_1byte(uint8_t data, uint32_t init_val); 70 71 /** 72 * Use single CRC32 instruction to perform a hash on a 2 bytes value. 73 * 74 * @param data 75 * Data to perform hash on. 76 * @param init_val 77 * Value to initialise hash generator. 78 * @return 79 * 32bit calculated hash value. 80 */ 81 static inline uint32_t 82 rte_hash_crc_2byte(uint16_t data, uint32_t init_val); 83 84 /** 85 * Use single CRC32 instruction to perform a hash on a 4 bytes value. 86 * 87 * @param data 88 * Data to perform hash on. 89 * @param init_val 90 * Value to initialise hash generator. 91 * @return 92 * 32bit calculated hash value. 93 */ 94 static inline uint32_t 95 rte_hash_crc_4byte(uint32_t data, uint32_t init_val); 96 97 /** 98 * Use single CRC32 instruction to perform a hash on a 8 bytes value. 99 * 100 * @param data 101 * Data to perform hash on. 102 * @param init_val 103 * Value to initialise hash generator. 104 * @return 105 * 32bit calculated hash value. 106 */ 107 static inline uint32_t 108 rte_hash_crc_8byte(uint64_t data, uint32_t init_val); 109 110 #endif /* __DOXYGEN__ */ 111 112 /** 113 * Calculate CRC32 hash on user-supplied byte array. 114 * 115 * @param data 116 * Data to perform hash on. 117 * @param data_len 118 * How many bytes to use to calculate hash value. 119 * @param init_val 120 * Value to initialise hash generator. 121 * @return 122 * 32bit calculated hash value. 123 */ 124 static inline uint32_t 125 rte_hash_crc(const void *data, uint32_t data_len, uint32_t init_val) 126 { 127 unsigned i; 128 uintptr_t pd = (uintptr_t) data; 129 130 for (i = 0; i < data_len / 8; i++) { 131 init_val = rte_hash_crc_8byte(*(const uint64_t *)pd, init_val); 132 pd += 8; 133 } 134 135 if (data_len & 0x4) { 136 init_val = rte_hash_crc_4byte(*(const uint32_t *)pd, init_val); 137 pd += 4; 138 } 139 140 if (data_len & 0x2) { 141 init_val = rte_hash_crc_2byte(*(const uint16_t *)pd, init_val); 142 pd += 2; 143 } 144 145 if (data_len & 0x1) 146 init_val = rte_hash_crc_1byte(*(const uint8_t *)pd, init_val); 147 148 return init_val; 149 } 150 151 #ifdef __cplusplus 152 } 153 #endif 154 155 #endif /* _RTE_HASH_CRC_H_ */ 156