cpu_endian.h
Go to the documentation of this file.
1 /**
2  * @file cpu_endian.h
3  * @brief Byte order conversion
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 2.4.4
27  **/
28 
29 #ifndef _CPU_ENDIAN_H
30 #define _CPU_ENDIAN_H
31 
32 //Dependencies
33 #include "os_port.h"
34 
35 //Undefine conflicting definitions
36 #ifdef HTONS
37  #undef HTONS
38 #endif
39 
40 #ifdef HTONL
41  #undef HTONL
42 #endif
43 
44 #ifdef HTONLL
45  #undef HTONLL
46 #endif
47 
48 #ifdef htons
49  #undef htons
50 #endif
51 
52 #ifdef htonl
53  #undef htonl
54 #endif
55 
56 #ifdef htonll
57  #undef htonll
58 #endif
59 
60 #ifdef NTOHS
61  #undef NTOHS
62 #endif
63 
64 #ifdef NTOHL
65  #undef NTOHL
66 #endif
67 
68 #ifdef NTOHLL
69  #undef NTOHLL
70 #endif
71 
72 #ifdef ntohs
73  #undef ntohs
74 #endif
75 
76 #ifdef ntohl
77  #undef ntohl
78 #endif
79 
80 #ifdef ntohll
81  #undef ntohll
82 #endif
83 
84 #ifdef HTOLE16
85  #undef HTOLE16
86 #endif
87 
88 #ifdef HTOLE32
89  #undef HTOLE32
90 #endif
91 
92 #ifdef HTOLE64
93  #undef HTOLE64
94 #endif
95 
96 #ifdef htole16
97  #undef htole16
98 #endif
99 
100 #ifdef htole32
101  #undef htole32
102 #endif
103 
104 #ifdef htole64
105  #undef htole64
106 #endif
107 
108 #ifdef LETOH16
109  #undef LETOH16
110 #endif
111 
112 #ifdef LETOH32
113  #undef LETOH32
114 #endif
115 
116 #ifdef LETOH64
117  #undef LETOH64
118 #endif
119 
120 #ifdef letoh16
121  #undef letoh16
122 #endif
123 
124 #ifdef letoh32
125  #undef letoh32
126 #endif
127 
128 #ifdef letoh64
129  #undef letoh64
130 #endif
131 
132 #ifdef HTOBE16
133  #undef HTOBE16
134 #endif
135 
136 #ifdef HTOBE32
137  #undef HTOBE32
138 #endif
139 
140 #ifdef HTOBE64
141  #undef HTOBE64
142 #endif
143 
144 #ifdef htobe16
145  #undef htobe16
146 #endif
147 
148 #ifdef htobe32
149  #undef htobe32
150 #endif
151 
152 #ifdef htobe64
153  #undef htobe64
154 #endif
155 
156 #ifdef BETOH16
157  #undef BETOH16
158 #endif
159 
160 #ifdef BETOH32
161  #undef BETOH32
162 #endif
163 
164 #ifdef BETOH64
165  #undef BETOH64
166 #endif
167 
168 #ifdef betoh16
169  #undef betoh16
170 #endif
171 
172 #ifdef betoh32
173  #undef betoh32
174 #endif
175 
176 #ifdef betoh64
177  #undef betoh64
178 #endif
179 
180 //Load unaligned 16-bit integer (little-endian encoding)
181 #define LOAD16LE(p) ( \
182  ((uint16_t)(((uint8_t *)(p))[0]) << 0) | \
183  ((uint16_t)(((uint8_t *)(p))[1]) << 8))
184 
185 //Load unaligned 16-bit integer (big-endian encoding)
186 #define LOAD16BE(p) ( \
187  ((uint16_t)(((uint8_t *)(p))[0]) << 8) | \
188  ((uint16_t)(((uint8_t *)(p))[1]) << 0))
189 
190 //Load unaligned 24-bit integer (little-endian encoding)
191 #define LOAD24LE(p) ( \
192  ((uint32_t)(((uint8_t *)(p))[0]) << 0)| \
193  ((uint32_t)(((uint8_t *)(p))[1]) << 8) | \
194  ((uint32_t)(((uint8_t *)(p))[2]) << 16))
195 
196 //Load unaligned 24-bit integer (big-endian encoding)
197 #define LOAD24BE(p) ( \
198  ((uint32_t)(((uint8_t *)(p))[0]) << 16) | \
199  ((uint32_t)(((uint8_t *)(p))[1]) << 8) | \
200  ((uint32_t)(((uint8_t *)(p))[2]) << 0))
201 
202 //Load unaligned 32-bit integer (little-endian encoding)
203 #define LOAD32LE(p) ( \
204  ((uint32_t)(((uint8_t *)(p))[0]) << 0) | \
205  ((uint32_t)(((uint8_t *)(p))[1]) << 8) | \
206  ((uint32_t)(((uint8_t *)(p))[2]) << 16) | \
207  ((uint32_t)(((uint8_t *)(p))[3]) << 24))
208 
209 //Load unaligned 32-bit integer (big-endian encoding)
210 #define LOAD32BE(p) ( \
211  ((uint32_t)(((uint8_t *)(p))[0]) << 24) | \
212  ((uint32_t)(((uint8_t *)(p))[1]) << 16) | \
213  ((uint32_t)(((uint8_t *)(p))[2]) << 8) | \
214  ((uint32_t)(((uint8_t *)(p))[3]) << 0))
215 
216 //Load unaligned 48-bit integer (little-endian encoding)
217 #define LOAD48LE(p) ( \
218  ((uint64_t)(((uint8_t *)(p))[0]) << 0) | \
219  ((uint64_t)(((uint8_t *)(p))[1]) << 8) | \
220  ((uint64_t)(((uint8_t *)(p))[2]) << 16) | \
221  ((uint64_t)(((uint8_t *)(p))[3]) << 24) | \
222  ((uint64_t)(((uint8_t *)(p))[4]) << 32) | \
223  ((uint64_t)(((uint8_t *)(p))[5]) << 40)
224 
225 //Load unaligned 48-bit integer (big-endian encoding)
226 #define LOAD48BE(p) ( \
227  ((uint64_t)(((uint8_t *)(p))[0]) << 40) | \
228  ((uint64_t)(((uint8_t *)(p))[1]) << 32) | \
229  ((uint64_t)(((uint8_t *)(p))[2]) << 24) | \
230  ((uint64_t)(((uint8_t *)(p))[3]) << 16) | \
231  ((uint64_t)(((uint8_t *)(p))[4]) << 8) | \
232  ((uint64_t)(((uint8_t *)(p))[5]) << 0))
233 
234 //Load unaligned 64-bit integer (little-endian encoding)
235 #define LOAD64LE(p) ( \
236  ((uint64_t)(((uint8_t *)(p))[0]) << 0) | \
237  ((uint64_t)(((uint8_t *)(p))[1]) << 8) | \
238  ((uint64_t)(((uint8_t *)(p))[2]) << 16) | \
239  ((uint64_t)(((uint8_t *)(p))[3]) << 24) | \
240  ((uint64_t)(((uint8_t *)(p))[4]) << 32) | \
241  ((uint64_t)(((uint8_t *)(p))[5]) << 40) | \
242  ((uint64_t)(((uint8_t *)(p))[6]) << 48) | \
243  ((uint64_t)(((uint8_t *)(p))[7]) << 56))
244 
245 //Load unaligned 64-bit integer (big-endian encoding)
246 #define LOAD64BE(p) ( \
247  ((uint64_t)(((uint8_t *)(p))[0]) << 56) | \
248  ((uint64_t)(((uint8_t *)(p))[1]) << 48) | \
249  ((uint64_t)(((uint8_t *)(p))[2]) << 40) | \
250  ((uint64_t)(((uint8_t *)(p))[3]) << 32) | \
251  ((uint64_t)(((uint8_t *)(p))[4]) << 24) | \
252  ((uint64_t)(((uint8_t *)(p))[5]) << 16) | \
253  ((uint64_t)(((uint8_t *)(p))[6]) << 8) | \
254  ((uint64_t)(((uint8_t *)(p))[7]) << 0))
255 
256 //Store unaligned 16-bit integer (little-endian encoding)
257 #define STORE16LE(a, p) \
258  ((uint8_t *)(p))[0] = ((uint16_t)(a) >> 0) & 0xFFU, \
259  ((uint8_t *)(p))[1] = ((uint16_t)(a) >> 8) & 0xFFU
260 
261 //Store unaligned 16-bit integer (big-endian encoding)
262 #define STORE16BE(a, p) \
263  ((uint8_t *)(p))[0] = ((uint16_t)(a) >> 8) & 0xFFU, \
264  ((uint8_t *)(p))[1] = ((uint16_t)(a) >> 0) & 0xFFU
265 
266 //Store unaligned 24-bit integer (little-endian encoding)
267 #define STORE24LE(a, p) \
268  ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 0) & 0xFFU, \
269  ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 8) & 0xFFU, \
270  ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 16) & 0xFFU
271 
272 //Store unaligned 24-bit integer (big-endian encoding)
273 #define STORE24BE(a, p) \
274  ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 16) & 0xFFU, \
275  ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 8) & 0xFFU, \
276  ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 0) & 0xFFU
277 
278 //Store unaligned 32-bit integer (little-endian encoding)
279 #define STORE32LE(a, p) \
280  ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 0) & 0xFFU, \
281  ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 8) & 0xFFU, \
282  ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 16) & 0xFFU, \
283  ((uint8_t *)(p))[3] = ((uint32_t)(a) >> 24) & 0xFFU
284 
285 //Store unaligned 32-bit integer (big-endian encoding)
286 #define STORE32BE(a, p) \
287  ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 24) & 0xFFU, \
288  ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 16) & 0xFFU, \
289  ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 8) & 0xFFU, \
290  ((uint8_t *)(p))[3] = ((uint32_t)(a) >> 0) & 0xFFU
291 
292 //Store unaligned 48-bit integer (little-endian encoding)
293 #define STORE48LE(a, p) \
294  ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 0) & 0xFFU, \
295  ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 8) & 0xFFU, \
296  ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 16) & 0xFFU, \
297  ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 24) & 0xFFU, \
298  ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 32) & 0xFFU, \
299  ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 40) & 0xFFU,
300 
301 //Store unaligned 48-bit integer (big-endian encoding)
302 #define STORE48BE(a, p) \
303  ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 40) & 0xFFU, \
304  ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 32) & 0xFFU, \
305  ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 24) & 0xFFU, \
306  ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 16) & 0xFFU, \
307  ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 8) & 0xFFU, \
308  ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 0) & 0xFFU
309 
310 //Store unaligned 64-bit integer (little-endian encoding)
311 #define STORE64LE(a, p) \
312  ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 0) & 0xFFU, \
313  ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 8) & 0xFFU, \
314  ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 16) & 0xFFU, \
315  ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 24) & 0xFFU, \
316  ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 32) & 0xFFU, \
317  ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 40) & 0xFFU, \
318  ((uint8_t *)(p))[6] = ((uint64_t)(a) >> 48) & 0xFFU, \
319  ((uint8_t *)(p))[7] = ((uint64_t)(a) >> 56) & 0xFFU
320 
321 //Store unaligned 64-bit integer (big-endian encoding)
322 #define STORE64BE(a, p) \
323  ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 56) & 0xFFU, \
324  ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 48) & 0xFFU, \
325  ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 40) & 0xFFU, \
326  ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 32) & 0xFFU, \
327  ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 24) & 0xFFU, \
328  ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 16) & 0xFFU, \
329  ((uint8_t *)(p))[6] = ((uint64_t)(a) >> 8) & 0xFFU, \
330  ((uint8_t *)(p))[7] = ((uint64_t)(a) >> 0) & 0xFFU
331 
332 //Swap a 16-bit integer
333 #define SWAPINT16(x) ( \
334  (((uint16_t)(x) & 0x00FFU) << 8) | \
335  (((uint16_t)(x) & 0xFF00U) >> 8))
336 
337 //Swap a 32-bit integer
338 #define SWAPINT32(x) ( \
339  (((uint32_t)(x) & 0x000000FFUL) << 24) | \
340  (((uint32_t)(x) & 0x0000FF00UL) << 8) | \
341  (((uint32_t)(x) & 0x00FF0000UL) >> 8) | \
342  (((uint32_t)(x) & 0xFF000000UL) >> 24))
343 
344 //Swap a 64-bit integer
345 #define SWAPINT64(x) ( \
346  (((uint64_t)(x) & 0x00000000000000FFULL) << 56) | \
347  (((uint64_t)(x) & 0x000000000000FF00ULL) << 40) | \
348  (((uint64_t)(x) & 0x0000000000FF0000ULL) << 24) | \
349  (((uint64_t)(x) & 0x00000000FF000000ULL) << 8) | \
350  (((uint64_t)(x) & 0x000000FF00000000ULL) >> 8) | \
351  (((uint64_t)(x) & 0x0000FF0000000000ULL) >> 24) | \
352  (((uint64_t)(x) & 0x00FF000000000000ULL) >> 40) | \
353  (((uint64_t)(x) & 0xFF00000000000000ULL) >> 56))
354 
355 //Big-endian machine?
356 #ifdef _CPU_BIG_ENDIAN
357 
358 //Host byte order to network byte order
359 #define HTONS(value) (value)
360 #define HTONL(value) (value)
361 #define HTONLL(value) (value)
362 #define htons(value) ((uint16_t) (value))
363 #define htonl(value) ((uint32_t) (value))
364 #define htonll(value) ((uint64_t) (value))
365 
366 //Network byte order to host byte order
367 #define NTOHS(value) (value)
368 #define NTOHL(value) (value)
369 #define NTOHLL(value) (value)
370 #define ntohs(value) ((uint16_t) (value))
371 #define ntohl(value) ((uint32_t) (value))
372 #define ntohll(value) ((uint64_t) (value))
373 
374 //Host byte order to little-endian byte order
375 #define HTOLE16(value) SWAPINT16(value)
376 #define HTOLE32(value) SWAPINT32(value)
377 #define HTOLE64(value) SWAPINT64(value)
378 #define htole16(value) swapInt16((uint16_t) (value))
379 #define htole32(value) swapInt32((uint32_t) (value))
380 #define htole64(value) swapInt64((uint64_t) (value))
381 
382 //Little-endian byte order to host byte order
383 #define LETOH16(value) SWAPINT16(value)
384 #define LETOH32(value) SWAPINT32(value)
385 #define LETOH64(value) SWAPINT64(value)
386 #define letoh16(value) swapInt16((uint16_t) (value))
387 #define letoh32(value) swapInt32((uint32_t) (value))
388 #define letoh64(value) swapInt64((uint64_t) (value))
389 
390 //Host byte order to big-endian byte order
391 #define HTOBE16(value) (value)
392 #define HTOBE32(value) (value)
393 #define HTOBE64(value) (value)
394 #define htobe16(value) ((uint16_t) (value))
395 #define htobe32(value) ((uint32_t) (value))
396 #define htobe64(value) ((uint64_t) (value))
397 
398 //Big-endian byte order to host byte order
399 #define BETOH16(value) (value)
400 #define BETOH32(value) (value)
401 #define BETOH64(value) (value)
402 #define betoh16(value) ((uint16_t) (value))
403 #define betoh32(value) ((uint32_t) (value))
404 #define betoh64(value) ((uint64_t) (value))
405 
406 //Little-endian machine?
407 #else
408 
409 //Host byte order to network byte order
410 #define HTONS(value) SWAPINT16(value)
411 #define HTONL(value) SWAPINT32(value)
412 #define HTONLL(value) SWAPINT64(value)
413 #define htons(value) swapInt16((uint16_t) (value))
414 #define htonl(value) swapInt32((uint32_t) (value))
415 #define htonll(value) swapInt64((uint64_t) (value))
416 
417 //Network byte order to host byte order
418 #define NTOHS(value) SWAPINT16(value)
419 #define NTOHL(value) SWAPINT32(value)
420 #define NTOHLL(value) SWAPINT64(value)
421 #define ntohs(value) swapInt16((uint16_t) (value))
422 #define ntohl(value) swapInt32((uint32_t) (value))
423 #define ntohll(value) swapInt64((uint64_t) (value))
424 
425 //Host byte order to little-endian byte order
426 #define HTOLE16(value) (value)
427 #define HTOLE32(value) (value)
428 #define HTOLE64(value) (value)
429 #define htole16(value) ((uint16_t) (value))
430 #define htole32(value) ((uint32_t) (value))
431 #define htole64(value) ((uint64_t) (value))
432 
433 //Little-endian byte order to host byte order
434 #define LETOH16(value) (value)
435 #define LETOH32(value) (value)
436 #define LETOH64(value) (value)
437 #define letoh16(value) ((uint16_t) (value))
438 #define letoh32(value) ((uint32_t) (value))
439 #define letoh64(value) ((uint64_t) (value))
440 
441 //Host byte order to big-endian byte order
442 #define HTOBE16(value) SWAPINT16(value)
443 #define HTOBE32(value) SWAPINT32(value)
444 #define HTOBE64(value) SWAPINT64(value)
445 #define htobe16(value) swapInt16((uint16_t) (value))
446 #define htobe32(value) swapInt32((uint32_t) (value))
447 #define htobe64(value) swapInt64((uint64_t) (value))
448 
449 //Big-endian byte order to host byte order
450 #define BETOH16(value) SWAPINT16(value)
451 #define BETOH32(value) SWAPINT32(value)
452 #define BETOH64(value) SWAPINT64(value)
453 #define betoh16(value) swapInt16((uint16_t) (value))
454 #define betoh32(value) swapInt32((uint32_t) (value))
455 #define betoh64(value) swapInt64((uint64_t) (value))
456 
457 #endif
458 
459 //C++ guard
460 #ifdef __cplusplus
461 extern "C" {
462 #endif
463 
464 //Byte order conversion functions
465 uint16_t swapInt16(uint16_t value);
466 uint32_t swapInt32(uint32_t value);
467 uint64_t swapInt64(uint64_t value);
468 
469 //Bit reversal functions
470 uint8_t reverseInt4(uint8_t value);
471 uint8_t reverseInt8(uint8_t value);
472 uint16_t reverseInt16(uint16_t value);
473 uint32_t reverseInt32(uint32_t value);
474 uint64_t reverseInt64(uint64_t value);
475 
476 //C++ guard
477 #ifdef __cplusplus
478 }
479 #endif
480 
481 #endif
uint32_t swapInt32(uint32_t value)
Reverse the byte order of a 32-bit word.
Definition: cpu_endian.c:51
uint16_t swapInt16(uint16_t value)
Reverse the byte order of a 16-bit word.
Definition: cpu_endian.c:39
uint8_t reverseInt8(uint8_t value)
Reverse bit order in a byte.
Definition: cpu_endian.c:90
uint32_t reverseInt32(uint32_t value)
Reverse bit order in a 32-bit word.
Definition: cpu_endian.c:123
uint64_t swapInt64(uint64_t value)
Reverse the byte order of a 64-bit word.
Definition: cpu_endian.c:63
uint64_t reverseInt64(uint64_t value)
Reverse bit order in a 64-bit word.
Definition: cpu_endian.c:141
uint8_t value[]
Definition: tcp.h:369
uint8_t reverseInt4(uint8_t value)
Reverse bit order in a 4-bit word.
Definition: cpu_endian.c:75
RTOS abstraction layer.
uint16_t reverseInt16(uint16_t value)
Reverse bit order in a 16-bit word.
Definition: cpu_endian.c:106