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