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