Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / nlio / repo / include / nlbyteorder.h
1 /**
2  *    Copyright (c) 2020 nlio Authors. All Rights Reserved.
3  *    Copyright 2012-2017 Nest Labs Inc. All Rights Reserved.
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17
18 /**
19  *    @file
20  *      This file defines macros for performing in place byte-
21  *      swapping of compile-time constants via the C preprocessor as
22  *      well as functions for performing byte-swapping by value and in
23  *      place by pointer for 16-, 32-, and 64-bit types.
24  */
25
26 #ifndef NLBYTEORDER_H
27 #define NLBYTEORDER_H
28
29 #include <nlio-private.h>
30
31 #include <stdint.h>
32
33 /*
34  * If we are compiling under clang, GCC, or any such compatible
35  * compiler, in which -fno-builtins or -ffreestanding might be
36  * asserted, thereby eliminating built-in function optimization, we
37  * STILL want to leverage built-in bswap{16,32,64}, if available. We
38  * want this because it allows the compiler to use
39  * architecture-specific machine instructions or inline code
40  * generation to optimize an otherwise-generic and non-optimized code
41  * for byte reordering, which is exactly the kind of efficiency that
42  * would be expected of nlByteOrder.
43  */
44
45 #if __nlIOHasBuiltin(__builtin_bswap16)
46 #define __nlBYTEORDER_BSWAP16 __builtin_bswap16
47 #else
48 #define __nlBYTEORDER_BSWAP16 nlByteOrderConstantSwap16
49 #endif
50
51 #if __nlIOHasBuiltin(__builtin_bswap32)
52 #define __nlBYTEORDER_BSWAP32 __builtin_bswap32
53 #else
54 #define __nlBYTEORDER_BSWAP32 nlByteOrderConstantSwap32
55 #endif
56
57 #if __nlIOHasBuiltin(__builtin_bswap64)
58 #define __nlBYTEORDER_BSWAP64 __builtin_bswap64
59 #else
60 #define __nlBYTEORDER_BSWAP64 nlByteOrderConstantSwap64
61 #endif
62
63 #ifdef __cplusplus
64 extern "C" {
65 #endif
66
67 /**
68  *  @def nlByteOrderConstantSwap16
69  *
70  *  @brief
71  *     Performs a preprocessor-compatible in place byte swap of the
72  *     provided 16-bit value.
73  *
74  */
75 #define nlByteOrderConstantSwap16(c)                                 \
76     ((uint16_t)                                                      \
77         ((((uint16_t)(c) & (uint16_t)0x00ffU) << 8) |                \
78          (((uint16_t)(c) & (uint16_t)0xff00U) >> 8)))
79
80 /**
81  *  @def nlByteOrderConstantSwap32
82  *
83  *  @brief
84  *     Performs a preprocessor-compatible in place byte swap of the
85  *     provided 32-bit value.
86  *
87  */
88 #define nlByteOrderConstantSwap32(c)                                 \
89     ((uint32_t)                                                      \
90         ((((uint32_t)(c) & (uint32_t)0x000000ffUL) << 24) |          \
91          (((uint32_t)(c) & (uint32_t)0x0000ff00UL) <<  8) |          \
92          (((uint32_t)(c) & (uint32_t)0x00ff0000UL) >>  8) |          \
93          (((uint32_t)(c) & (uint32_t)0xff000000UL) >> 24)))
94
95 /**
96  *  @def nlByteOrderConstantSwap64
97  *
98  *  @brief
99  *     Performs a preprocessor-compatible in place byte swap of the
100  *     provided 64-bit value.
101  *
102  */
103 #define nlByteOrderConstantSwap64(c)                                 \
104     ((uint64_t)                                                      \
105         ((((uint64_t)(c) & (uint64_t)0x00000000000000ffULL) << 56) | \
106          (((uint64_t)(c) & (uint64_t)0x000000000000ff00ULL) << 40) | \
107          (((uint64_t)(c) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
108          (((uint64_t)(c) & (uint64_t)0x00000000ff000000ULL) <<  8) | \
109          (((uint64_t)(c) & (uint64_t)0x000000ff00000000ULL) >>  8) | \
110          (((uint64_t)(c) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
111          (((uint64_t)(c) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
112          (((uint64_t)(c) & (uint64_t)0xff00000000000000ULL) >> 56)))
113
114 /**
115  *  @def NLBYTEORDER_LITTLE_ENDIAN
116  *
117  *  @brief
118  *     Constant preprocessor definition used to test #NLBYTEORDER
119  *     against to determine whether the target system uses little
120  *     endian byte ordering.
121  *
122  *  @code
123  *  #if NLBYTEORDER == NLBYTEORDER_LITTLE_ENDIAN
124  *  
125  *      Do something that is little endian byte ordering-specific.
126  *
127  *  #endif
128  *  @endcode
129  *
130  */
131 #define NLBYTEORDER_LITTLE_ENDIAN       0x1234
132
133 /**
134  *  @def NLBYTEORDER_BIG_ENDIAN
135  *
136  *  @brief
137  *     Constant preprocessor definition used to test #NLBYTEORDER
138  *     against to determine whether the target system uses big
139  *     endian byte ordering.
140  *
141  *  @code
142  *  #if NLBYTEORDER == NLBYTEORDER_BIG_ENDIAN
143  *  
144  *      Do something that is little endian byte ordering-specific.
145  *
146  *  #endif
147  *  @endcode
148  *
149  */
150 #define NLBYTEORDER_BIG_ENDIAN          0x4321
151
152 /**
153  *  @def NLBYTEORDER_UNKNOWN_ENDIAN
154  *
155  *  @brief
156  *     Constant preprocessor definition used to test #NLBYTEORDER
157  *     against to determine whether the target system uses unknown
158  *     byte ordering.
159  *
160  *  @code
161  *  #elif NLBYTEORDER == NLBYTEORDER_UNKNOWN_ENDIAN
162  *  #error "Unknown byte ordering!"
163  *  #endif
164  *  @endcode
165  *
166  */
167 #define NLBYTEORDER_UNKNOWN_ENDIAN      0xFFFF
168
169 /**
170  *  @def NLBYTEORDER
171  *
172  *  @brief
173  *     Constant preprocessor definition containing the target system
174  *     byte ordering. May be one of:
175  *
176  *       - NLBYTEORDER_BIG_ENDIAN
177  *       - NLBYTEORDER_LITTLE_ENDIAN
178  *       - NLBYTEORDER_UNKNOWN_ENDIAN
179  *
180  */
181 #if defined(__BYTE_ORDER__)
182 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
183 #  define NLBYTEORDER NLBYTEORDER_LITTLE_ENDIAN
184 # elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
185 #  define NLBYTEORDER NLBYTEORDER_BIG_ENDIAN
186 # endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
187 #elif defined(__LITTLE_ENDIAN__) && (__LITTLE_ENDIAN__ == 1)
188 #define NLBYTEORDER NLBYTEORDER_LITTLE_ENDIAN
189 #elif defined(__BIG_ENDIAN__) && (__BIG_ENDIAN__ == 1)
190 #define NLBYTEORDER NLBYTEORDER_BIG_ENDIAN
191 #else
192 #error "Endianness undefined!"
193 #define NLBYTEORDER NLBYTEORDER_UNKNOWN_ENDIAN
194 #endif /* defined(__BYTE_ORDER__) */
195
196 enum {
197     nlByteOrderUnknown      = NLBYTEORDER_UNKNOWN_ENDIAN,
198     nlByteOrderLittleEndian = NLBYTEORDER_LITTLE_ENDIAN,
199     nlByteOrderBigEndian    = NLBYTEORDER_BIG_ENDIAN
200 };
201
202 /**
203  * This represents a type for a byte ordering.
204  */
205 typedef uint16_t nlByteOrder;
206
207 /**
208  * This returns the byte order of the current system.
209  *
210  * @return The byte order of the current system.
211  */
212 static inline nlByteOrder nlByteOrderGetCurrent(void)
213 {
214 #if (NLBYTEORDER == NLBYTEORDER_LITTLE_ENDIAN)
215     return nlByteOrderLittleEndian;
216 #elif (NLBYTEORDER == NLBYTEORDER_BIG_ENDIAN)
217     return nlByteOrderBigEndian;
218 #else
219     return nlByteOrderUnknown;
220 #endif
221 }
222
223 /**
224  * This unconditionally performs a byte order swap by value of the
225  * specified 16-bit value.
226  *
227  * @param[in]  inValue  The 16-bit value to be byte order swapped.
228  *
229  * @return The input value, byte order swapped.
230  */
231 static inline uint16_t nlByteOrderValueSwap16(uint16_t inValue)
232 {
233     return __nlBYTEORDER_BSWAP16(inValue);
234 }
235
236 /**
237  * This unconditionally performs a byte order swap by value of the
238  * specified 32-bit value.
239  *
240  * @param[in]  inValue  The 32-bit value to be byte order swapped.
241  *
242  * @return The input value, byte order swapped.
243  */
244 static inline uint32_t nlByteOrderValueSwap32(uint32_t inValue)
245 {
246     return __nlBYTEORDER_BSWAP32(inValue);
247 }
248
249 /**
250  * This unconditionally performs a byte order swap by value of the
251  * specified 64-bit value.
252  *
253  * @param[in]  inValue  The 64-bit value to be byte order swapped.
254  *
255  * @return The input value, byte order swapped.
256  */
257 static inline uint64_t nlByteOrderValueSwap64(uint64_t inValue)
258 {
259     return __nlBYTEORDER_BSWAP64(inValue);
260 }
261
262 /**
263  * This unconditionally performs a byte order swap by pointer in place
264  * of the specified 16-bit value.
265  *
266  * @warning  The input value is assumed to be on a natural alignment
267  * boundary for the target system. It is the responsibility of the
268  * caller to perform any necessary alignment to avoid system faults
269  * for systems that do not support unaligned accesses.
270  *
271  * @param[inout]  inValue  A pointer to the 16-bit value to be byte
272  *                         order swapped.
273  */
274 static inline void nlByteOrderPointerSwap16(uint16_t *inValue)
275 {
276     *inValue = nlByteOrderValueSwap16(*inValue);
277 }
278
279 /**
280  * This unconditionally performs a byte order swap by pointer in place
281  * of the specified 32-bit value.
282  *
283  * @warning  The input value is assumed to be on a natural alignment
284  * boundary for the target system. It is the responsibility of the
285  * caller to perform any necessary alignment to avoid system faults
286  * for systems that do not support unaligned accesses.
287  *
288  * @param[inout]  inValue  A pointer to the 32-bit value to be byte
289  *                         order swapped.
290  */
291 static inline void nlByteOrderPointerSwap32(uint32_t *inValue)
292 {
293     *inValue = nlByteOrderValueSwap32(*inValue);
294 }
295
296 /**
297  * This unconditionally performs a byte order swap by pointer in place
298  * of the specified 64-bit value.
299  *
300  * @warning  The input value is assumed to be on a natural alignment
301  * boundary for the target system. It is the responsibility of the
302  * caller to perform any necessary alignment to avoid system faults
303  * for systems that do not support unaligned accesses.
304  *
305  * @param[inout]  inValue  A pointer to the 64-bit value to be byte
306  *                         order swapped.
307  */
308 static inline void nlByteOrderPointerSwap64(uint64_t *inValue)
309 {
310     *inValue = nlByteOrderValueSwap64(*inValue);
311 }
312
313 #if (NLBYTEORDER == NLBYTEORDER_LITTLE_ENDIAN)
314 #include <nlbyteorder-little.h>
315 #elif (NLBYTEORDER == NLBYTEORDER_BIG_ENDIAN)
316 #include <nlbyteorder-big.h>
317 #endif /* (NLBYTEORDER == NLBYTEORDER_LITTLE_ENDIAN) */
318
319 #ifdef __cplusplus
320 }
321 #endif
322
323 #undef __nlBYTEORDER_BSWAP16
324 #undef __nlBYTEORDER_BSWAP32
325 #undef __nlBYTEORDER_BSWAP64
326
327 #endif /* NLBYTEORDER_H */
328
329