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_
19 #include <rte_config.h>
20 #include <rte_cpuflags.h>
21 #include <rte_branch_prediction.h>
22 #include <rte_common.h>
24 #include "rte_crc_sw.h"
26 #define CRC32_SW (1U << 0)
27 #define CRC32_SSE42 (1U << 1)
28 #define CRC32_x64 (1U << 2)
29 #define CRC32_SSE42_x64 (CRC32_x64|CRC32_SSE42)
30 #define CRC32_ARM64 (1U << 3)
32 static uint8_t crc32_alg = CRC32_SW;
34 #if defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_CRC32)
35 #include "rte_crc_arm64.h"
37 #include "rte_crc_x86.h"
40 * Allow or disallow use of SSE4.2 instrinsics for CRC32 hash
44 * An OR of following flags:
45 * - (CRC32_SW) Don't use SSE4.2 intrinsics
46 * - (CRC32_SSE42) Use SSE4.2 intrinsics if available
47 * - (CRC32_SSE42_x64) Use 64-bit SSE4.2 intrinsic if available (default)
51 rte_hash_crc_set_alg(uint8_t alg)
53 #if defined(RTE_ARCH_X86)
54 if (alg == CRC32_SSE42_x64 &&
55 !rte_cpu_get_flag_enabled(RTE_CPUFLAG_EM64T))
61 /* Setting the best available algorithm */
62 RTE_INIT(rte_hash_crc_init_alg)
64 rte_hash_crc_set_alg(CRC32_SSE42_x64);
68 * Use single crc32 instruction to perform a hash on a byte value.
69 * Fall back to software crc32 implementation in case SSE4.2 is
73 * Data to perform hash on.
75 * Value to initialise hash generator.
77 * 32bit calculated hash value.
79 static inline uint32_t
80 rte_hash_crc_1byte(uint8_t data, uint32_t init_val)
82 #if defined RTE_ARCH_X86
83 if (likely(crc32_alg & CRC32_SSE42))
84 return crc32c_sse42_u8(data, init_val);
87 return crc32c_1byte(data, init_val);
91 * Use single crc32 instruction to perform a hash on a 2 bytes value.
92 * Fall back to software crc32 implementation in case SSE4.2 is
96 * Data to perform hash on.
98 * Value to initialise hash generator.
100 * 32bit calculated hash value.
102 static inline uint32_t
103 rte_hash_crc_2byte(uint16_t data, uint32_t init_val)
105 #if defined RTE_ARCH_X86
106 if (likely(crc32_alg & CRC32_SSE42))
107 return crc32c_sse42_u16(data, init_val);
110 return crc32c_2bytes(data, init_val);
114 * Use single crc32 instruction to perform a hash on a 4 byte value.
115 * Fall back to software crc32 implementation in case SSE4.2 is
119 * Data to perform hash on.
121 * Value to initialise hash generator.
123 * 32bit calculated hash value.
125 static inline uint32_t
126 rte_hash_crc_4byte(uint32_t data, uint32_t init_val)
128 #if defined RTE_ARCH_X86
129 if (likely(crc32_alg & CRC32_SSE42))
130 return crc32c_sse42_u32(data, init_val);
133 return crc32c_1word(data, init_val);
137 * Use single crc32 instruction to perform a hash on a 8 byte value.
138 * Fall back to software crc32 implementation in case SSE4.2 is
142 * Data to perform hash on.
144 * Value to initialise hash generator.
146 * 32bit calculated hash value.
148 static inline uint32_t
149 rte_hash_crc_8byte(uint64_t data, uint32_t init_val)
151 #ifdef RTE_ARCH_X86_64
152 if (likely(crc32_alg == CRC32_SSE42_x64))
153 return crc32c_sse42_u64(data, init_val);
156 #if defined RTE_ARCH_X86
157 if (likely(crc32_alg & CRC32_SSE42))
158 return crc32c_sse42_u64_mimic(data, init_val);
161 return crc32c_2words(data, init_val);
167 * Calculate CRC32 hash on user-supplied byte array.
170 * Data to perform hash on.
172 * How many bytes to use to calculate hash value.
174 * Value to initialise hash generator.
176 * 32bit calculated hash value.
178 static inline uint32_t
179 rte_hash_crc(const void *data, uint32_t data_len, uint32_t init_val)
182 uintptr_t pd = (uintptr_t) data;
184 for (i = 0; i < data_len / 8; i++) {
185 init_val = rte_hash_crc_8byte(*(const uint64_t *)pd, init_val);
189 if (data_len & 0x4) {
190 init_val = rte_hash_crc_4byte(*(const uint32_t *)pd, init_val);
194 if (data_len & 0x2) {
195 init_val = rte_hash_crc_2byte(*(const uint16_t *)pd, init_val);
200 init_val = rte_hash_crc_1byte(*(const uint8_t *)pd, init_val);
209 #endif /* _RTE_HASH_CRC_H_ */