xref: /dpdk/lib/hash/rte_hash_crc.h (revision 719834a6849e1daf4a70ff7742bbcc3ae7e25607)
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