1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
5 #ifndef _RTE_HASH_CRC_H_
6 #define _RTE_HASH_CRC_H_
20 #include <rte_branch_prediction.h>
21 #include <rte_common.h>
22 #include <rte_config.h>
23 #include <rte_cpuflags.h>
26 #include "rte_crc_sw.h"
28 #define CRC32_SW (1U << 0)
29 #define CRC32_SSE42 (1U << 1)
30 #define CRC32_x64 (1U << 2)
31 #define CRC32_SSE42_x64 (CRC32_x64|CRC32_SSE42)
32 #define CRC32_ARM64 (1U << 3)
34 static uint8_t crc32_alg = CRC32_SW;
36 #if defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_CRC32)
37 #include "rte_crc_arm64.h"
38 #elif defined(RTE_ARCH_X86)
39 #include "rte_crc_x86.h"
41 #include "rte_crc_generic.h"
45 * Allow or disallow use of SSE4.2/ARMv8 intrinsics for CRC32 hash
49 * An OR of following flags:
50 * - (CRC32_SW) Don't use SSE4.2/ARMv8 intrinsics (default non-[x86/ARMv8])
51 * - (CRC32_SSE42) Use SSE4.2 intrinsics if available
52 * - (CRC32_SSE42_x64) Use 64-bit SSE4.2 intrinsic if available (default x86)
53 * - (CRC32_ARM64) Use ARMv8 CRC intrinsic if available (default ARMv8)
57 rte_hash_crc_set_alg(uint8_t alg)
64 #if defined RTE_ARCH_X86
65 if (!(alg & CRC32_SSE42_x64))
66 RTE_LOG(WARNING, HASH,
67 "Unsupported CRC32 algorithm requested using CRC32_x64/CRC32_SSE42\n");
68 if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_EM64T) || alg == CRC32_SSE42)
69 crc32_alg = CRC32_SSE42;
71 crc32_alg = CRC32_SSE42_x64;
74 #if defined RTE_ARCH_ARM64
75 if (!(alg & CRC32_ARM64))
76 RTE_LOG(WARNING, HASH,
77 "Unsupported CRC32 algorithm requested using CRC32_ARM64\n");
78 if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_CRC32))
79 crc32_alg = CRC32_ARM64;
82 if (crc32_alg == CRC32_SW)
83 RTE_LOG(WARNING, HASH,
84 "Unsupported CRC32 algorithm requested using CRC32_SW\n");
87 /* Setting the best available algorithm */
88 RTE_INIT(rte_hash_crc_init_alg)
90 #if defined(RTE_ARCH_X86)
91 rte_hash_crc_set_alg(CRC32_SSE42_x64);
92 #elif defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_CRC32)
93 rte_hash_crc_set_alg(CRC32_ARM64);
95 rte_hash_crc_set_alg(CRC32_SW);
102 * Use single CRC32 instruction to perform a hash on a byte value.
105 * Data to perform hash on.
107 * Value to initialise hash generator.
109 * 32bit calculated hash value.
111 static inline uint32_t
112 rte_hash_crc_1byte(uint8_t data, uint32_t init_val);
115 * Use single CRC32 instruction to perform a hash on a 2 bytes value.
118 * Data to perform hash on.
120 * Value to initialise hash generator.
122 * 32bit calculated hash value.
124 static inline uint32_t
125 rte_hash_crc_2byte(uint16_t data, uint32_t init_val);
128 * Use single CRC32 instruction to perform a hash on a 4 bytes value.
131 * Data to perform hash on.
133 * Value to initialise hash generator.
135 * 32bit calculated hash value.
137 static inline uint32_t
138 rte_hash_crc_4byte(uint32_t data, uint32_t init_val);
141 * Use single CRC32 instruction to perform a hash on a 8 bytes value.
144 * Data to perform hash on.
146 * Value to initialise hash generator.
148 * 32bit calculated hash value.
150 static inline uint32_t
151 rte_hash_crc_8byte(uint64_t data, uint32_t init_val);
153 #endif /* __DOXYGEN__ */
156 * Calculate CRC32 hash on user-supplied byte array.
159 * Data to perform hash on.
161 * How many bytes to use to calculate hash value.
163 * Value to initialise hash generator.
165 * 32bit calculated hash value.
167 static inline uint32_t
168 rte_hash_crc(const void *data, uint32_t data_len, uint32_t init_val)
171 uintptr_t pd = (uintptr_t) data;
173 for (i = 0; i < data_len / 8; i++) {
174 init_val = rte_hash_crc_8byte(*(const uint64_t *)pd, init_val);
178 if (data_len & 0x4) {
179 init_val = rte_hash_crc_4byte(*(const uint32_t *)pd, init_val);
183 if (data_len & 0x2) {
184 init_val = rte_hash_crc_2byte(*(const uint16_t *)pd, init_val);
189 init_val = rte_hash_crc_1byte(*(const uint8_t *)pd, init_val);
198 #endif /* _RTE_HASH_CRC_H_ */