inc/ecu/endian.h Source File

ECU: inc/ecu/endian.h Source File
ECU
endian.h
Go to the documentation of this file.
1 
14 #ifndef ECU_ENDIAN_H_
15 #define ECU_ENDIAN_H_
16 
17 /*------------------------------------------------------------*/
18 /*------------------------- INCLUDES -------------------------*/
19 /*------------------------------------------------------------*/
20 
21 /* STDLib. */
22 #include <stdint.h>
23 
24 /*------------------------------------------------------------*/
25 /*------------------ COMPILE TIME BYTE SWAPS -----------------*/
26 /*------------------------------------------------------------*/
27 
39 #define ECU_SWAP16_COMPILETIME(x_) \
40  ((uint16_t)((((x_) & 0xFF00) >> 8) | \
41  (((x_) & 0x00FF) << 8)))
42 
50 #define ECU_SWAP32_COMPILETIME(x_) \
51  ((uint32_t)((((x_) & 0xFF000000UL) >> 24) | \
52  (((x_) & 0x00FF0000UL) >> 8) | \
53  (((x_) & 0x0000FF00UL) << 8) | \
54  (((x_) & 0x000000FFUL) << 24)))
55 
63 #define ECU_SWAP64_COMPILETIME(x_) \
64  ((uint64_t)((((x_) & 0xFF00000000000000ULL) >> 56) | \
65  (((x_) & 0x00FF000000000000ULL) >> 40) | \
66  (((x_) & 0x0000FF0000000000ULL) >> 24) | \
67  (((x_) & 0x000000FF00000000ULL) >> 8) | \
68  (((x_) & 0x00000000FF000000ULL) << 8) | \
69  (((x_) & 0x0000000000FF0000ULL) << 24) | \
70  (((x_) & 0x000000000000FF00ULL) << 40) | \
71  (((x_) & 0x00000000000000FFULL) << 56)))
74 /*------------------------------------------------------------*/
75 /*-------------------- RUNTIME BYTE SWAPS --------------------*/
76 /*------------------------------------------------------------*/
77 
78 #ifdef __cplusplus
79 extern "C" {
80 #endif
81 
92 static inline uint16_t ecu_swap16_runtime(uint_fast16_t val)
93 {
94  /* Avoid type punning via (uint8_t *) or using a union so behavior
95  is defined in both C and C++. Compiler will implicitly typecast if
96  uint_fast16_t has higher precedence over int. Otherwise int promotion
97  happens no matter what. */
98  return (((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8));
99 }
100 
107 static inline uint32_t ecu_swap32_runtime(uint_fast32_t val)
108 {
109  /* Avoid type punning via (uint8_t *) or using a union so behavior
110  is defined in both C and C++. Explicitly cast in case int cannot hold
111  these raw hexadecimal values and also so faster operation occurs. */
112  return (((val & (uint_fast32_t)0xFF000000) >> 24) |
113  ((val & (uint_fast32_t)0x00FF0000) >> 8) |
114  ((val & (uint_fast32_t)0x0000FF00) << 8) |
115  ((val & (uint_fast32_t)0x000000FF) << 24));
116 }
117 
124 static inline uint64_t ecu_swap64_runtime(uint_fast64_t val)
125 {
126  /* Avoid type punning via (uint8_t *) or using a union so behavior
127  is defined in both C and C++. Explicitly cast in case int cannot hold
128  these raw hexadecimal values and also so faster operation occurs. */
129  return (((val & (uint_fast64_t)0xFF00000000000000) >> 56) |
130  ((val & (uint_fast64_t)0x00FF000000000000) >> 40) |
131  ((val & (uint_fast64_t)0x0000FF0000000000) >> 24) |
132  ((val & (uint_fast64_t)0x000000FF00000000) >> 8) |
133  ((val & (uint_fast64_t)0x00000000FF000000) << 8) |
134  ((val & (uint_fast64_t)0x0000000000FF0000) << 24) |
135  ((val & (uint_fast64_t)0x000000000000FF00) << 40) |
136  ((val & (uint_fast64_t)0x00000000000000FF) << 56));
137 }
140 #ifdef __cplusplus
141 }
142 #endif
143 
144 /*------------------------------------------------------------*/
145 /*--------------------- ENDIANNESS MACROS --------------------*/
146 /*------------------------------------------------------------*/
147 
148 #if defined(ECU_DOXYGEN)
158  #define ECU_BE16_TO_CPU_COMPILETIME(x_)
159  #define ECU_BE32_TO_CPU_COMPILETIME(x_)
160  #define ECU_BE64_TO_CPU_COMPILETIME(x_)
161 
167  #define ECU_BE32_TO_CPU_RUNTIME(x_)
168  #define ECU_BE64_TO_CPU_RUNTIME(x_)
169  #define ECU_BE16_TO_CPU_RUNTIME(x_)
181  #define ECU_LE16_TO_CPU_COMPILETIME(x_)
182  #define ECU_LE32_TO_CPU_COMPILETIME(x_)
183  #define ECU_LE64_TO_CPU_COMPILETIME(x_)
184 
190  #define ECU_LE16_TO_CPU_RUNTIME(x_)
191  #define ECU_LE32_TO_CPU_RUNTIME(x_)
192  #define ECU_LE64_TO_CPU_RUNTIME(x_)
204  #define ECU_CPU_TO_BE16_COMPILETIME(x_)
205  #define ECU_CPU_TO_BE32_COMPILETIME(x_)
206  #define ECU_CPU_TO_BE64_COMPILETIME(x_)
207 
213  #define ECU_CPU_TO_BE16_RUNTIME(x_)
214  #define ECU_CPU_TO_BE32_RUNTIME(x_)
215  #define ECU_CPU_TO_BE64_RUNTIME(x_)
227  #define ECU_CPU_TO_LE16_COMPILETIME(x_)
228  #define ECU_CPU_TO_LE32_COMPILETIME(x_)
229  #define ECU_CPU_TO_LE64_COMPILETIME(x_)
230 
236  #define ECU_CPU_TO_LE16_RUNTIME(x_)
237  #define ECU_CPU_TO_LE32_RUNTIME(x_)
238  #define ECU_CPU_TO_LE64_RUNTIME(x_)
240 #else
241  #if defined(ECU_LITTLE_ENDIAN) /* Defined by CMake build system. */
242  #define ECU_BE16_TO_CPU_COMPILETIME(x_) ECU_SWAP16_COMPILETIME(x_)
243  #define ECU_BE32_TO_CPU_COMPILETIME(x_) ECU_SWAP32_COMPILETIME(x_)
244  #define ECU_BE64_TO_CPU_COMPILETIME(x_) ECU_SWAP64_COMPILETIME(x_)
245  #define ECU_BE16_TO_CPU_RUNTIME(x_) ecu_swap16_runtime(x_)
246  #define ECU_BE32_TO_CPU_RUNTIME(x_) ecu_swap32_runtime(x_)
247  #define ECU_BE64_TO_CPU_RUNTIME(x_) ecu_swap64_runtime(x_)
248 
249  #define ECU_LE16_TO_CPU_COMPILETIME(x_) (x_)
250  #define ECU_LE32_TO_CPU_COMPILETIME(x_) (x_)
251  #define ECU_LE64_TO_CPU_COMPILETIME(x_) (x_)
252  #define ECU_LE16_TO_CPU_RUNTIME(x_) (x_)
253  #define ECU_LE32_TO_CPU_RUNTIME(x_) (x_)
254  #define ECU_LE64_TO_CPU_RUNTIME(x_) (x_)
255 
256  #define ECU_CPU_TO_BE16_COMPILETIME(x_) ECU_SWAP16_COMPILETIME(x_)
257  #define ECU_CPU_TO_BE32_COMPILETIME(x_) ECU_SWAP32_COMPILETIME(x_)
258  #define ECU_CPU_TO_BE64_COMPILETIME(x_) ECU_SWAP64_COMPILETIME(x_)
259  #define ECU_CPU_TO_BE16_RUNTIME(x_) ecu_swap16_runtime(x_)
260  #define ECU_CPU_TO_BE32_RUNTIME(x_) ecu_swap32_runtime(x_)
261  #define ECU_CPU_TO_BE64_RUNTIME(x_) ecu_swap64_runtime(x_)
262 
263  #define ECU_CPU_TO_LE16_COMPILETIME(x_) (x_)
264  #define ECU_CPU_TO_LE32_COMPILETIME(x_) (x_)
265  #define ECU_CPU_TO_LE64_COMPILETIME(x_) (x_)
266  #define ECU_CPU_TO_LE16_RUNTIME(x_) (x_)
267  #define ECU_CPU_TO_LE32_RUNTIME(x_) (x_)
268  #define ECU_CPU_TO_LE64_RUNTIME(x_) (x_)
269  #elif defined(ECU_BIG_ENDIAN) /* Defined by CMake build system. */
270  #define ECU_BE16_TO_CPU_COMPILETIME(x_) (x_)
271  #define ECU_BE32_TO_CPU_COMPILETIME(x_) (x_)
272  #define ECU_BE64_TO_CPU_COMPILETIME(x_) (x_)
273  #define ECU_BE16_TO_CPU_RUNTIME(x_) (x_)
274  #define ECU_BE32_TO_CPU_RUNTIME(x_) (x_)
275  #define ECU_BE64_TO_CPU_RUNTIME(x_) (x_)
276 
277  #define ECU_LE16_TO_CPU_COMPILETIME(x_) ECU_SWAP16_COMPILETIME(x_)
278  #define ECU_LE32_TO_CPU_COMPILETIME(x_) ECU_SWAP32_COMPILETIME(x_)
279  #define ECU_LE64_TO_CPU_COMPILETIME(x_) ECU_SWAP64_COMPILETIME(x_)
280  #define ECU_LE16_TO_CPU_RUNTIME(x_) ecu_swap16_runtime(x_)
281  #define ECU_LE32_TO_CPU_RUNTIME(x_) ecu_swap32_runtime(x_)
282  #define ECU_LE64_TO_CPU_RUNTIME(x_) ecu_swap64_runtime(x_)
283 
284  #define ECU_CPU_TO_BE16_COMPILETIME(x_) (x_)
285  #define ECU_CPU_TO_BE32_COMPILETIME(x_) (x_)
286  #define ECU_CPU_TO_BE64_COMPILETIME(x_) (x_)
287  #define ECU_CPU_TO_BE16_RUNTIME(x_) (x_)
288  #define ECU_CPU_TO_BE32_RUNTIME(x_) (x_)
289  #define ECU_CPU_TO_BE64_RUNTIME(x_) (x_)
290 
291  #define ECU_CPU_TO_LE16_COMPILETIME(x_) ECU_SWAP16_COMPILETIME(x_)
292  #define ECU_CPU_TO_LE32_COMPILETIME(x_) ECU_SWAP32_COMPILETIME(x_)
293  #define ECU_CPU_TO_LE64_COMPILETIME(x_) ECU_SWAP64_COMPILETIME(x_)
294  #define ECU_CPU_TO_LE16_RUNTIME(x_) ecu_swap16_runtime(x_)
295  #define ECU_CPU_TO_LE32_RUNTIME(x_) ecu_swap32_runtime(x_)
296  #define ECU_CPU_TO_LE64_RUNTIME(x_) ecu_swap64_runtime(x_)
297  #else
298  /* clang-format off */
299  #error "CMake build system unable to detect target endianness from CMAKE_C_BYTE_ORDER variable. "
300  "Manually define ECU_LITTLE_ENDIAN or ECU_BIG_ENDIAN to use this module."
301  /* clang-format on */
302  #endif
303 #endif /* ECU_DOXYGEN */
304 
305 #endif /* ECU_ENDIAN_H_ */
static uint64_t ecu_swap64_runtime(uint_fast64_t val)
Returns byte-swapped value (switches endianness) of 64-bit input at runtime. Can handle signed inputs...
Definition: endian.h:124
static uint16_t ecu_swap16_runtime(uint_fast16_t val)
Returns byte-swapped value (switches endianness) of 16-bit input at runtime. Can handle signed inputs...
Definition: endian.h:92
static uint32_t ecu_swap32_runtime(uint_fast32_t val)
Returns byte-swapped value (switches endianness) of 32-bit input at runtime. Can handle signed inputs...
Definition: endian.h:107