]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright(c) 2010-2014 Intel Corporation | |
3 | */ | |
4 | ||
5 | #ifndef _RTE_BYTEORDER_H_ | |
6 | #define _RTE_BYTEORDER_H_ | |
7 | ||
8 | /** | |
9 | * @file | |
10 | * | |
11 | * Byte Swap Operations | |
12 | * | |
13 | * This file defines a generic API for byte swap operations. Part of | |
14 | * the implementation is architecture-specific. | |
15 | */ | |
16 | ||
17 | #include <stdint.h> | |
9f95a23c | 18 | #ifdef RTE_EXEC_ENV_FREEBSD |
11fdf7f2 TL |
19 | #include <sys/endian.h> |
20 | #else | |
21 | #include <endian.h> | |
22 | #endif | |
23 | ||
24 | #include <rte_common.h> | |
25 | #include <rte_config.h> | |
26 | ||
27 | /* | |
28 | * Compile-time endianness detection | |
29 | */ | |
30 | #define RTE_BIG_ENDIAN 1 | |
31 | #define RTE_LITTLE_ENDIAN 2 | |
32 | #if defined __BYTE_ORDER__ | |
33 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | |
34 | #define RTE_BYTE_ORDER RTE_BIG_ENDIAN | |
35 | #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ | |
36 | #define RTE_BYTE_ORDER RTE_LITTLE_ENDIAN | |
37 | #endif /* __BYTE_ORDER__ */ | |
38 | #elif defined __BYTE_ORDER | |
39 | #if __BYTE_ORDER == __BIG_ENDIAN | |
40 | #define RTE_BYTE_ORDER RTE_BIG_ENDIAN | |
41 | #elif __BYTE_ORDER == __LITTLE_ENDIAN | |
42 | #define RTE_BYTE_ORDER RTE_LITTLE_ENDIAN | |
43 | #endif /* __BYTE_ORDER */ | |
44 | #elif defined __BIG_ENDIAN__ | |
45 | #define RTE_BYTE_ORDER RTE_BIG_ENDIAN | |
46 | #elif defined __LITTLE_ENDIAN__ | |
47 | #define RTE_BYTE_ORDER RTE_LITTLE_ENDIAN | |
48 | #endif | |
49 | #if !defined(RTE_BYTE_ORDER) | |
50 | #error Unknown endianness. | |
51 | #endif | |
52 | ||
53 | #define RTE_STATIC_BSWAP16(v) \ | |
54 | ((((uint16_t)(v) & UINT16_C(0x00ff)) << 8) | \ | |
55 | (((uint16_t)(v) & UINT16_C(0xff00)) >> 8)) | |
56 | ||
57 | #define RTE_STATIC_BSWAP32(v) \ | |
58 | ((((uint32_t)(v) & UINT32_C(0x000000ff)) << 24) | \ | |
59 | (((uint32_t)(v) & UINT32_C(0x0000ff00)) << 8) | \ | |
60 | (((uint32_t)(v) & UINT32_C(0x00ff0000)) >> 8) | \ | |
61 | (((uint32_t)(v) & UINT32_C(0xff000000)) >> 24)) | |
62 | ||
63 | #define RTE_STATIC_BSWAP64(v) \ | |
64 | ((((uint64_t)(v) & UINT64_C(0x00000000000000ff)) << 56) | \ | |
65 | (((uint64_t)(v) & UINT64_C(0x000000000000ff00)) << 40) | \ | |
66 | (((uint64_t)(v) & UINT64_C(0x0000000000ff0000)) << 24) | \ | |
67 | (((uint64_t)(v) & UINT64_C(0x00000000ff000000)) << 8) | \ | |
68 | (((uint64_t)(v) & UINT64_C(0x000000ff00000000)) >> 8) | \ | |
69 | (((uint64_t)(v) & UINT64_C(0x0000ff0000000000)) >> 24) | \ | |
70 | (((uint64_t)(v) & UINT64_C(0x00ff000000000000)) >> 40) | \ | |
71 | (((uint64_t)(v) & UINT64_C(0xff00000000000000)) >> 56)) | |
72 | ||
73 | /* | |
74 | * These macros are functionally similar to rte_cpu_to_(be|le)(16|32|64)(), | |
75 | * they take values in host CPU order and return them converted to the | |
76 | * intended endianness. | |
77 | * | |
78 | * They resolve at compilation time to integer constants which can safely be | |
79 | * used with static initializers, since those cannot involve function calls. | |
80 | * | |
81 | * On the other hand, they are not as optimized as their rte_cpu_to_*() | |
82 | * counterparts, therefore applications should refrain from using them on | |
83 | * variable values, particularly inside performance-sensitive code. | |
84 | */ | |
85 | #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN | |
86 | #define RTE_BE16(v) (rte_be16_t)(v) | |
87 | #define RTE_BE32(v) (rte_be32_t)(v) | |
88 | #define RTE_BE64(v) (rte_be64_t)(v) | |
89 | #define RTE_LE16(v) (rte_le16_t)(RTE_STATIC_BSWAP16(v)) | |
90 | #define RTE_LE32(v) (rte_le32_t)(RTE_STATIC_BSWAP32(v)) | |
91 | #define RTE_LE64(v) (rte_le64_t)(RTE_STATIC_BSWAP64(v)) | |
92 | #elif RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN | |
93 | #define RTE_BE16(v) (rte_be16_t)(RTE_STATIC_BSWAP16(v)) | |
94 | #define RTE_BE32(v) (rte_be32_t)(RTE_STATIC_BSWAP32(v)) | |
95 | #define RTE_BE64(v) (rte_be64_t)(RTE_STATIC_BSWAP64(v)) | |
96 | #define RTE_LE16(v) (rte_be16_t)(v) | |
97 | #define RTE_LE32(v) (rte_be32_t)(v) | |
98 | #define RTE_LE64(v) (rte_be64_t)(v) | |
99 | #else | |
100 | #error Unsupported endianness. | |
101 | #endif | |
102 | ||
103 | /* | |
104 | * The following types should be used when handling values according to a | |
105 | * specific byte ordering, which may differ from that of the host CPU. | |
106 | * | |
107 | * Libraries, public APIs and applications are encouraged to use them for | |
108 | * documentation purposes. | |
109 | */ | |
110 | typedef uint16_t rte_be16_t; /**< 16-bit big-endian value. */ | |
111 | typedef uint32_t rte_be32_t; /**< 32-bit big-endian value. */ | |
112 | typedef uint64_t rte_be64_t; /**< 64-bit big-endian value. */ | |
113 | typedef uint16_t rte_le16_t; /**< 16-bit little-endian value. */ | |
114 | typedef uint32_t rte_le32_t; /**< 32-bit little-endian value. */ | |
115 | typedef uint64_t rte_le64_t; /**< 64-bit little-endian value. */ | |
116 | ||
117 | /* | |
118 | * An internal function to swap bytes in a 16-bit value. | |
119 | * | |
120 | * It is used by rte_bswap16() when the value is constant. Do not use | |
121 | * this function directly; rte_bswap16() is preferred. | |
122 | */ | |
123 | static inline uint16_t | |
124 | rte_constant_bswap16(uint16_t x) | |
125 | { | |
126 | return (uint16_t)RTE_STATIC_BSWAP16(x); | |
127 | } | |
128 | ||
129 | /* | |
130 | * An internal function to swap bytes in a 32-bit value. | |
131 | * | |
132 | * It is used by rte_bswap32() when the value is constant. Do not use | |
133 | * this function directly; rte_bswap32() is preferred. | |
134 | */ | |
135 | static inline uint32_t | |
136 | rte_constant_bswap32(uint32_t x) | |
137 | { | |
138 | return (uint32_t)RTE_STATIC_BSWAP32(x); | |
139 | } | |
140 | ||
141 | /* | |
142 | * An internal function to swap bytes of a 64-bit value. | |
143 | * | |
144 | * It is used by rte_bswap64() when the value is constant. Do not use | |
145 | * this function directly; rte_bswap64() is preferred. | |
146 | */ | |
147 | static inline uint64_t | |
148 | rte_constant_bswap64(uint64_t x) | |
149 | { | |
150 | return (uint64_t)RTE_STATIC_BSWAP64(x); | |
151 | } | |
152 | ||
153 | ||
154 | #ifdef __DOXYGEN__ | |
155 | ||
156 | /** | |
157 | * Swap bytes in a 16-bit value. | |
158 | */ | |
159 | static uint16_t rte_bswap16(uint16_t _x); | |
160 | ||
161 | /** | |
162 | * Swap bytes in a 32-bit value. | |
163 | */ | |
164 | static uint32_t rte_bswap32(uint32_t x); | |
165 | ||
166 | /** | |
167 | * Swap bytes in a 64-bit value. | |
168 | */ | |
169 | static uint64_t rte_bswap64(uint64_t x); | |
170 | ||
171 | /** | |
172 | * Convert a 16-bit value from CPU order to little endian. | |
173 | */ | |
174 | static rte_le16_t rte_cpu_to_le_16(uint16_t x); | |
175 | ||
176 | /** | |
177 | * Convert a 32-bit value from CPU order to little endian. | |
178 | */ | |
179 | static rte_le32_t rte_cpu_to_le_32(uint32_t x); | |
180 | ||
181 | /** | |
182 | * Convert a 64-bit value from CPU order to little endian. | |
183 | */ | |
184 | static rte_le64_t rte_cpu_to_le_64(uint64_t x); | |
185 | ||
186 | ||
187 | /** | |
188 | * Convert a 16-bit value from CPU order to big endian. | |
189 | */ | |
190 | static rte_be16_t rte_cpu_to_be_16(uint16_t x); | |
191 | ||
192 | /** | |
193 | * Convert a 32-bit value from CPU order to big endian. | |
194 | */ | |
195 | static rte_be32_t rte_cpu_to_be_32(uint32_t x); | |
196 | ||
197 | /** | |
198 | * Convert a 64-bit value from CPU order to big endian. | |
199 | */ | |
200 | static rte_be64_t rte_cpu_to_be_64(uint64_t x); | |
201 | ||
202 | ||
203 | /** | |
204 | * Convert a 16-bit value from little endian to CPU order. | |
205 | */ | |
206 | static uint16_t rte_le_to_cpu_16(rte_le16_t x); | |
207 | ||
208 | /** | |
209 | * Convert a 32-bit value from little endian to CPU order. | |
210 | */ | |
211 | static uint32_t rte_le_to_cpu_32(rte_le32_t x); | |
212 | ||
213 | /** | |
214 | * Convert a 64-bit value from little endian to CPU order. | |
215 | */ | |
216 | static uint64_t rte_le_to_cpu_64(rte_le64_t x); | |
217 | ||
218 | ||
219 | /** | |
220 | * Convert a 16-bit value from big endian to CPU order. | |
221 | */ | |
222 | static uint16_t rte_be_to_cpu_16(rte_be16_t x); | |
223 | ||
224 | /** | |
225 | * Convert a 32-bit value from big endian to CPU order. | |
226 | */ | |
227 | static uint32_t rte_be_to_cpu_32(rte_be32_t x); | |
228 | ||
229 | /** | |
230 | * Convert a 64-bit value from big endian to CPU order. | |
231 | */ | |
232 | static uint64_t rte_be_to_cpu_64(rte_be64_t x); | |
233 | ||
234 | #endif /* __DOXYGEN__ */ | |
235 | ||
236 | #ifdef RTE_FORCE_INTRINSICS | |
237 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) | |
238 | #define rte_bswap16(x) __builtin_bswap16(x) | |
239 | #endif | |
240 | ||
241 | #define rte_bswap32(x) __builtin_bswap32(x) | |
242 | ||
243 | #define rte_bswap64(x) __builtin_bswap64(x) | |
244 | ||
245 | #endif | |
246 | ||
247 | #endif /* _RTE_BYTEORDER_H_ */ |