1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
3 */
4
5 #ifndef _RTE_CRC_X86_H_
6 #define _RTE_CRC_X86_H_
7
8 #include <rte_vect.h>
9
10 static inline uint32_t
crc32c_sse42_u8(uint8_t data,uint32_t init_val)11 crc32c_sse42_u8(uint8_t data, uint32_t init_val)
12 {
13 return _mm_crc32_u8(init_val, data);
14 }
15
16 static inline uint32_t
crc32c_sse42_u16(uint16_t data,uint32_t init_val)17 crc32c_sse42_u16(uint16_t data, uint32_t init_val)
18 {
19 return _mm_crc32_u16(init_val, data);
20 }
21
22 static inline uint32_t
crc32c_sse42_u32(uint32_t data,uint32_t init_val)23 crc32c_sse42_u32(uint32_t data, uint32_t init_val)
24 {
25 return _mm_crc32_u32(init_val, data);
26 }
27
28 #ifdef RTE_ARCH_X86_64
29 static inline uint32_t
crc32c_sse42_u64(uint64_t data,uint64_t init_val)30 crc32c_sse42_u64(uint64_t data, uint64_t init_val)
31 {
32 return _mm_crc32_u64(init_val, data);
33 }
34 #endif
35
36 static inline uint32_t
crc32c_sse42_u64_mimic(uint64_t data,uint64_t init_val)37 crc32c_sse42_u64_mimic(uint64_t data, uint64_t init_val)
38 {
39 union {
40 uint32_t u32[2];
41 uint64_t u64;
42 } d;
43
44 d.u64 = data;
45 init_val = crc32c_sse42_u32(d.u32[0], (uint32_t)init_val);
46 init_val = crc32c_sse42_u32(d.u32[1], (uint32_t)init_val);
47 return (uint32_t)init_val;
48 }
49
50 /*
51 * Use single crc32 instruction to perform a hash on a byte value.
52 * Fall back to software crc32 implementation in case SSE4.2 is
53 * not supported.
54 */
55 static inline uint32_t
rte_hash_crc_1byte(uint8_t data,uint32_t init_val)56 rte_hash_crc_1byte(uint8_t data, uint32_t init_val)
57 {
58 if (likely(rte_hash_crc32_alg & CRC32_SSE42))
59 return crc32c_sse42_u8(data, init_val);
60
61 return crc32c_1byte(data, init_val);
62 }
63
64 /*
65 * Use single crc32 instruction to perform a hash on a 2 bytes value.
66 * Fall back to software crc32 implementation in case SSE4.2 is
67 * not supported.
68 */
69 static inline uint32_t
rte_hash_crc_2byte(uint16_t data,uint32_t init_val)70 rte_hash_crc_2byte(uint16_t data, uint32_t init_val)
71 {
72 if (likely(rte_hash_crc32_alg & CRC32_SSE42))
73 return crc32c_sse42_u16(data, init_val);
74
75 return crc32c_2bytes(data, init_val);
76 }
77
78 /*
79 * Use single crc32 instruction to perform a hash on a 4 byte value.
80 * Fall back to software crc32 implementation in case SSE4.2 is
81 * not supported.
82 */
83 static inline uint32_t
rte_hash_crc_4byte(uint32_t data,uint32_t init_val)84 rte_hash_crc_4byte(uint32_t data, uint32_t init_val)
85 {
86 if (likely(rte_hash_crc32_alg & CRC32_SSE42))
87 return crc32c_sse42_u32(data, init_val);
88
89 return crc32c_1word(data, init_val);
90 }
91
92 /*
93 * Use single crc32 instruction to perform a hash on a 8 byte value.
94 * Fall back to software crc32 implementation in case SSE4.2 is
95 * not supported.
96 */
97 static inline uint32_t
rte_hash_crc_8byte(uint64_t data,uint32_t init_val)98 rte_hash_crc_8byte(uint64_t data, uint32_t init_val)
99 {
100 #ifdef RTE_ARCH_X86_64
101 if (likely(rte_hash_crc32_alg == CRC32_SSE42_x64))
102 return crc32c_sse42_u64(data, init_val);
103 #endif
104
105 if (likely(rte_hash_crc32_alg & CRC32_SSE42))
106 return crc32c_sse42_u64_mimic(data, init_val);
107
108 return crc32c_2words(data, init_val);
109 }
110
111 #endif /* _RTE_CRC_X86_H_ */
112