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-2019 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 1.9.6
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 htons
45  #undef htons
46 #endif
47 
48 #ifdef htonl
49  #undef htonl
50 #endif
51 
52 #ifdef NTOHS
53  #undef NTOHS
54 #endif
55 
56 #ifdef NTOHL
57  #undef NTOHL
58 #endif
59 
60 #ifdef ntohs
61  #undef ntohs
62 #endif
63 
64 #ifdef ntohl
65  #undef ntohl
66 #endif
67 
68 #ifdef HTOLE16
69  #undef HTOLE16
70 #endif
71 
72 #ifdef HTOLE32
73  #undef HTOLE32
74 #endif
75 
76 #ifdef HTOLE64
77  #undef HTOLE64
78 #endif
79 
80 #ifdef htole16
81  #undef htole16
82 #endif
83 
84 #ifdef htole32
85  #undef htole32
86 #endif
87 
88 #ifdef htole64
89  #undef htole64
90 #endif
91 
92 #ifdef LETOH16
93  #undef LETOH16
94 #endif
95 
96 #ifdef LETOH32
97  #undef LETOH32
98 #endif
99 
100 #ifdef LETOH64
101  #undef LETOH64
102 #endif
103 
104 #ifdef letoh16
105  #undef letoh16
106 #endif
107 
108 #ifdef letoh32
109  #undef letoh32
110 #endif
111 
112 #ifdef letoh64
113  #undef letoh64
114 #endif
115 
116 #ifdef HTOBE16
117  #undef HTOBE16
118 #endif
119 
120 #ifdef HTOBE32
121  #undef HTOBE32
122 #endif
123 
124 #ifdef HTOBE64
125  #undef HTOBE64
126 #endif
127 
128 #ifdef htobe16
129  #undef htobe16
130 #endif
131 
132 #ifdef htobe32
133  #undef htobe32
134 #endif
135 
136 #ifdef htobe64
137  #undef htobe64
138 #endif
139 
140 #ifdef BETOH16
141  #undef BETOH16
142 #endif
143 
144 #ifdef BETOH32
145  #undef BETOH32
146 #endif
147 
148 #ifdef BETOH64
149  #undef BETOH64
150 #endif
151 
152 #ifdef betoh16
153  #undef betoh16
154 #endif
155 
156 #ifdef betoh32
157  #undef betoh32
158 #endif
159 
160 #ifdef betoh64
161  #undef betoh64
162 #endif
163 
164 //Load unaligned 16-bit integer (little-endian encoding)
165 #define LOAD16LE(p) ( \
166  ((uint16_t)(((uint8_t *)(p))[0]) << 0) | \
167  ((uint16_t)(((uint8_t *)(p))[1]) << 8))
168 
169 //Load unaligned 16-bit integer (big-endian encoding)
170 #define LOAD16BE(p) ( \
171  ((uint16_t)(((uint8_t *)(p))[0]) << 8) | \
172  ((uint16_t)(((uint8_t *)(p))[1]) << 0))
173 
174 //Load unaligned 24-bit integer (little-endian encoding)
175 #define LOAD24LE(p) ( \
176  ((uint32_t)(((uint8_t *)(p))[0]) << 0)| \
177  ((uint32_t)(((uint8_t *)(p))[1]) << 8) | \
178  ((uint32_t)(((uint8_t *)(p))[2]) << 16))
179 
180 //Load unaligned 24-bit integer (big-endian encoding)
181 #define LOAD24BE(p) ( \
182  ((uint32_t)(((uint8_t *)(p))[0]) << 16) | \
183  ((uint32_t)(((uint8_t *)(p))[1]) << 8) | \
184  ((uint32_t)(((uint8_t *)(p))[2]) << 0))
185 
186 //Load unaligned 32-bit integer (little-endian encoding)
187 #define LOAD32LE(p) ( \
188  ((uint32_t)(((uint8_t *)(p))[0]) << 0) | \
189  ((uint32_t)(((uint8_t *)(p))[1]) << 8) | \
190  ((uint32_t)(((uint8_t *)(p))[2]) << 16) | \
191  ((uint32_t)(((uint8_t *)(p))[3]) << 24))
192 
193 //Load unaligned 32-bit integer (big-endian encoding)
194 #define LOAD32BE(p) ( \
195  ((uint32_t)(((uint8_t *)(p))[0]) << 24) | \
196  ((uint32_t)(((uint8_t *)(p))[1]) << 16) | \
197  ((uint32_t)(((uint8_t *)(p))[2]) << 8) | \
198  ((uint32_t)(((uint8_t *)(p))[3]) << 0))
199 
200 //Load unaligned 48-bit integer (little-endian encoding)
201 #define LOAD48LE(p) ( \
202  ((uint64_t)(((uint8_t *)(p))[0]) << 0) | \
203  ((uint64_t)(((uint8_t *)(p))[1]) << 8) | \
204  ((uint64_t)(((uint8_t *)(p))[2]) << 16) | \
205  ((uint64_t)(((uint8_t *)(p))[3]) << 24) | \
206  ((uint64_t)(((uint8_t *)(p))[4]) << 32) | \
207  ((uint64_t)(((uint8_t *)(p))[5]) << 40)
208 
209 //Load unaligned 48-bit integer (big-endian encoding)
210 #define LOAD48BE(p) ( \
211  ((uint64_t)(((uint8_t *)(p))[0]) << 40) | \
212  ((uint64_t)(((uint8_t *)(p))[1]) << 32) | \
213  ((uint64_t)(((uint8_t *)(p))[2]) << 24) | \
214  ((uint64_t)(((uint8_t *)(p))[3]) << 16) | \
215  ((uint64_t)(((uint8_t *)(p))[4]) << 8) | \
216  ((uint64_t)(((uint8_t *)(p))[5]) << 0))
217 
218 //Load unaligned 64-bit integer (little-endian encoding)
219 #define LOAD64LE(p) ( \
220  ((uint64_t)(((uint8_t *)(p))[0]) << 0) | \
221  ((uint64_t)(((uint8_t *)(p))[1]) << 8) | \
222  ((uint64_t)(((uint8_t *)(p))[2]) << 16) | \
223  ((uint64_t)(((uint8_t *)(p))[3]) << 24) | \
224  ((uint64_t)(((uint8_t *)(p))[4]) << 32) | \
225  ((uint64_t)(((uint8_t *)(p))[5]) << 40) | \
226  ((uint64_t)(((uint8_t *)(p))[6]) << 48) | \
227  ((uint64_t)(((uint8_t *)(p))[7]) << 56))
228 
229 //Load unaligned 64-bit integer (big-endian encoding)
230 #define LOAD64BE(p) ( \
231  ((uint64_t)(((uint8_t *)(p))[0]) << 56) | \
232  ((uint64_t)(((uint8_t *)(p))[1]) << 48) | \
233  ((uint64_t)(((uint8_t *)(p))[2]) << 40) | \
234  ((uint64_t)(((uint8_t *)(p))[3]) << 32) | \
235  ((uint64_t)(((uint8_t *)(p))[4]) << 24) | \
236  ((uint64_t)(((uint8_t *)(p))[5]) << 16) | \
237  ((uint64_t)(((uint8_t *)(p))[6]) << 8) | \
238  ((uint64_t)(((uint8_t *)(p))[7]) << 0))
239 
240 //Store unaligned 16-bit integer (little-endian encoding)
241 #define STORE16LE(a, p) \
242  ((uint8_t *)(p))[0] = ((uint16_t)(a) >> 0) & 0xFFU, \
243  ((uint8_t *)(p))[1] = ((uint16_t)(a) >> 8) & 0xFFU
244 
245 //Store unaligned 32-bit integer (big-endian encoding)
246 #define STORE16BE(a, p) \
247  ((uint8_t *)(p))[0] = ((uint16_t)(a) >> 8) & 0xFFU, \
248  ((uint8_t *)(p))[1] = ((uint16_t)(a) >> 0) & 0xFFU
249 
250 //Store unaligned 24-bit integer (little-endian encoding)
251 #define STORE24LE(a, p) \
252  ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 0) & 0xFFU, \
253  ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 8) & 0xFFU, \
254  ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 16) & 0xFFU
255 
256 //Store unaligned 24-bit integer (big-endian encoding)
257 #define STORE24BE(a, p) \
258  ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 16) & 0xFFU, \
259  ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 8) & 0xFFU, \
260  ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 0) & 0xFFU
261 
262 //Store unaligned 32-bit integer (little-endian encoding)
263 #define STORE32LE(a, p) \
264  ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 0) & 0xFFU, \
265  ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 8) & 0xFFU, \
266  ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 16) & 0xFFU, \
267  ((uint8_t *)(p))[3] = ((uint32_t)(a) >> 24) & 0xFFU
268 
269 //Store unaligned 32-bit integer (big-endian encoding)
270 #define STORE32BE(a, p) \
271  ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 24) & 0xFFU, \
272  ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 16) & 0xFFU, \
273  ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 8) & 0xFFU, \
274  ((uint8_t *)(p))[3] = ((uint32_t)(a) >> 0) & 0xFFU
275 
276 //Store unaligned 48-bit integer (little-endian encoding)
277 #define STORE48LE(a, p) \
278  ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 0) & 0xFFU, \
279  ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 8) & 0xFFU, \
280  ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 16) & 0xFFU, \
281  ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 24) & 0xFFU, \
282  ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 32) & 0xFFU, \
283  ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 40) & 0xFFU,
284 
285 //Store unaligned 48-bit integer (big-endian encoding)
286 #define STORE48BE(a, p) \
287  ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 40) & 0xFFU, \
288  ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 32) & 0xFFU, \
289  ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 24) & 0xFFU, \
290  ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 16) & 0xFFU, \
291  ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 8) & 0xFFU, \
292  ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 0) & 0xFFU
293 
294 //Store unaligned 64-bit integer (little-endian encoding)
295 #define STORE64LE(a, p) \
296  ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 0) & 0xFFU, \
297  ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 8) & 0xFFU, \
298  ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 16) & 0xFFU, \
299  ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 24) & 0xFFU, \
300  ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 32) & 0xFFU, \
301  ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 40) & 0xFFU, \
302  ((uint8_t *)(p))[6] = ((uint64_t)(a) >> 48) & 0xFFU, \
303  ((uint8_t *)(p))[7] = ((uint64_t)(a) >> 56) & 0xFFU
304 
305 //Store unaligned 64-bit integer (big-endian encoding)
306 #define STORE64BE(a, p) \
307  ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 56) & 0xFFU, \
308  ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 48) & 0xFFU, \
309  ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 40) & 0xFFU, \
310  ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 32) & 0xFFU, \
311  ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 24) & 0xFFU, \
312  ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 16) & 0xFFU, \
313  ((uint8_t *)(p))[6] = ((uint64_t)(a) >> 8) & 0xFFU, \
314  ((uint8_t *)(p))[7] = ((uint64_t)(a) >> 0) & 0xFFU
315 
316 //Swap a 16-bit integer
317 #define SWAPINT16(x) ( \
318  (((uint16_t)(x) & 0x00FFU) << 8) | \
319  (((uint16_t)(x) & 0xFF00U) >> 8))
320 
321 //Swap a 32-bit integer
322 #define SWAPINT32(x) ( \
323  (((uint32_t)(x) & 0x000000FFUL) << 24) | \
324  (((uint32_t)(x) & 0x0000FF00UL) << 8) | \
325  (((uint32_t)(x) & 0x00FF0000UL) >> 8) | \
326  (((uint32_t)(x) & 0xFF000000UL) >> 24))
327 
328 //Swap a 64-bit integer
329 #define SWAPINT64(x) ( \
330  (((uint64_t)(x) & 0x00000000000000FFULL) << 56) | \
331  (((uint64_t)(x) & 0x000000000000FF00ULL) << 40) | \
332  (((uint64_t)(x) & 0x0000000000FF0000ULL) << 24) | \
333  (((uint64_t)(x) & 0x00000000FF000000ULL) << 8) | \
334  (((uint64_t)(x) & 0x000000FF00000000ULL) >> 8) | \
335  (((uint64_t)(x) & 0x0000FF0000000000ULL) >> 24) | \
336  (((uint64_t)(x) & 0x00FF000000000000ULL) >> 40) | \
337  (((uint64_t)(x) & 0xFF00000000000000ULL) >> 56))
338 
339 //Big-endian machine?
340 #ifdef _CPU_BIG_ENDIAN
341 
342 //Host byte order to network byte order
343 #define HTONS(value) (value)
344 #define HTONL(value) (value)
345 #define htons(value) ((uint16_t) (value))
346 #define htonl(value) ((uint32_t) (value))
347 
348 //Network byte order to host byte order
349 #define NTOHS(value) (value)
350 #define NTOHL(value) (value)
351 #define ntohs(value) ((uint16_t) (value))
352 #define ntohl(value) ((uint32_t) (value))
353 
354 //Host byte order to little-endian byte order
355 #define HTOLE16(value) SWAPINT16(value)
356 #define HTOLE32(value) SWAPINT32(value)
357 #define HTOLE64(value) SWAPINT64(value)
358 #define htole16(value) swapInt16((uint16_t) (value))
359 #define htole32(value) swapInt32((uint32_t) (value))
360 #define htole64(value) swapInt64((uint64_t) (value))
361 
362 //Little-endian byte order to host byte order
363 #define LETOH16(value) SWAPINT16(value)
364 #define LETOH32(value) SWAPINT32(value)
365 #define LETOH64(value) SWAPINT64(value)
366 #define letoh16(value) swapInt16((uint16_t) (value))
367 #define letoh32(value) swapInt32((uint32_t) (value))
368 #define letoh64(value) swapInt64((uint64_t) (value))
369 
370 //Host byte order to big-endian byte order
371 #define HTOBE16(value) (value)
372 #define HTOBE32(value) (value)
373 #define HTOBE64(value) (value)
374 #define htobe16(value) ((uint16_t) (value))
375 #define htobe32(value) ((uint32_t) (value))
376 #define htobe64(value) ((uint64_t) (value))
377 
378 //Big-endian byte order to host byte order
379 #define BETOH16(value) (value)
380 #define BETOH32(value) (value)
381 #define BETOH64(value) (value)
382 #define betoh16(value) ((uint16_t) (value))
383 #define betoh32(value) ((uint32_t) (value))
384 #define betoh64(value) ((uint64_t) (value))
385 
386 //Little-endian machine?
387 #else
388 
389 //Host byte order to network byte order
390 #define HTONS(value) SWAPINT16(value)
391 #define HTONL(value) SWAPINT32(value)
392 #define htons(value) swapInt16((uint16_t) (value))
393 #define htonl(value) swapInt32((uint32_t) (value))
394 
395 //Network byte order to host byte order
396 #define NTOHS(value) SWAPINT16(value)
397 #define NTOHL(value) SWAPINT32(value)
398 #define ntohs(value) swapInt16((uint16_t) (value))
399 #define ntohl(value) swapInt32((uint32_t) (value))
400 
401 //Host byte order to little-endian byte order
402 #define HTOLE16(value) (value)
403 #define HTOLE32(value) (value)
404 #define HTOLE64(value) (value)
405 #define htole16(value) ((uint16_t) (value))
406 #define htole32(value) ((uint32_t) (value))
407 #define htole64(value) ((uint64_t) (value))
408 
409 //Little-endian byte order to host byte order
410 #define LETOH16(value) (value)
411 #define LETOH32(value) (value)
412 #define LETOH64(value) (value)
413 #define letoh16(value) ((uint16_t) (value))
414 #define letoh32(value) ((uint32_t) (value))
415 #define letoh64(value) ((uint64_t) (value))
416 
417 //Host byte order to big-endian byte order
418 #define HTOBE16(value) SWAPINT16(value)
419 #define HTOBE32(value) SWAPINT32(value)
420 #define HTOBE64(value) SWAPINT64(value)
421 #define htobe16(value) swapInt16((uint16_t) (value))
422 #define htobe32(value) swapInt32((uint32_t) (value))
423 #define htobe64(value) swapInt64((uint64_t) (value))
424 
425 //Big-endian byte order to host byte order
426 #define BETOH16(value) SWAPINT16(value)
427 #define BETOH32(value) SWAPINT32(value)
428 #define BETOH64(value) SWAPINT64(value)
429 #define betoh16(value) swapInt16((uint16_t) (value))
430 #define betoh32(value) swapInt32((uint32_t) (value))
431 #define betoh64(value) swapInt64((uint64_t) (value))
432 
433 #endif
434 
435 //C++ guard
436 #ifdef __cplusplus
437 extern "C" {
438 #endif
439 
440 //Byte order conversion functions
441 uint16_t swapInt16(uint16_t value);
442 uint32_t swapInt32(uint32_t value);
443 uint64_t swapInt64(uint64_t value);
444 
445 //Bit reversal functions
446 uint8_t reverseInt4(uint8_t value);
447 uint8_t reverseInt8(uint8_t value);
448 uint16_t reverseInt16(uint16_t value);
449 uint32_t reverseInt32(uint32_t value);
450 uint64_t reverseInt64(uint64_t value);
451 
452 //C++ guard
453 #ifdef __cplusplus
454 }
455 #endif
456 
457 #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 reverseInt4(uint8_t value)
Reverse bit order in a 4-bit word.
Definition: cpu_endian.c:75
uint8_t value[]
Definition: dtls_misc.h:150
RTOS abstraction layer.
uint16_t reverseInt16(uint16_t value)
Reverse bit order in a 16-bit word.
Definition: cpu_endian.c:106