summaryrefslogtreecommitdiff
path: root/src/common/tusb_compiler.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/tusb_compiler.h')
-rw-r--r--src/common/tusb_compiler.h155
1 files changed, 69 insertions, 86 deletions
diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h
index 9b33a6f61..a8971c3df 100644
--- a/src/common/tusb_compiler.h
+++ b/src/common/tusb_compiler.h
@@ -24,30 +24,22 @@
* This file is part of the TinyUSB stack.
*/
-/** \ingroup Group_Common
- * \defgroup Group_Compiler Compiler
- * \brief Group_Compiler brief
- * @{ */
-
-#ifndef _TUSB_COMPILER_H_
-#define _TUSB_COMPILER_H_
+#pragma once
#define TU_TOKEN(x) x
#define TU_STRING(x) #x ///< stringify without expand
#define TU_XSTRING(x) TU_STRING(x) ///< expand then stringify
-
#define TU_STRCAT(a, b) a##b ///< concat without expand
#define TU_STRCAT3(a, b, c) a##b##c ///< concat without expand
-
#define TU_XSTRCAT(a, b) TU_STRCAT(a, b) ///< expand then concat
#define TU_XSTRCAT3(a, b, c) TU_STRCAT3(a, b, c) ///< expand then concat 3 tokens
#define TU_INCLUDE_PATH(_dir,_file) TU_XSTRING( TU_TOKEN(_dir)TU_TOKEN(_file) )
#if defined __COUNTER__ && __COUNTER__ != __COUNTER__
- #define _TU_COUNTER_ __COUNTER__
+ #define TU_COUNTER __COUNTER__
#else
- #define _TU_COUNTER_ __LINE__
+ #define TU_COUNTER __LINE__
#endif
// Compile-time Assert
@@ -56,9 +48,9 @@
#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define TU_VERIFY_STATIC _Static_assert
#elif defined(__CCRX__)
- #define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT(_verify_static_, _TU_COUNTER_)[(const_expr) ? 1 : 0];
+ #define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT(_verify_static_, TU_COUNTER)[(const_expr) ? 1 : 0];
#else
- #define TU_VERIFY_STATIC(const_expr, _mess) enum { TU_XSTRCAT(_verify_static_, _TU_COUNTER_) = 1/(!!(const_expr)) }
+ #define TU_VERIFY_STATIC(const_expr, _mess) enum { TU_XSTRCAT(_verify_static_, TU_COUNTER) = 1/(!!(const_expr)) }
#endif
/* --------------------- Fuzzing types -------------------------------------- */
@@ -68,28 +60,31 @@
#define tu_static static
#endif
-// for declaration of reserved field, make use of _TU_COUNTER_
-#define TU_RESERVED TU_XSTRCAT(reserved, _TU_COUNTER_)
+// for declaration of reserved field, make use of TU_COUNTER
+#define TU_RESERVED TU_XSTRCAT(reserved, TU_COUNTER)
#define TU_LITTLE_ENDIAN (0x12u)
#define TU_BIG_ENDIAN (0x21u)
+#define TU_BITFIELD_LE (0x34u)
+#define TU_BITFIELD_BE (0x43u)
+
/*------------------------------------------------------------------*/
/* Count number of arguments of __VA_ARGS__
- * - reference https://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments
- * - _GET_NTH_ARG() takes args >= N (64) but only expand to Nth one (64th)
- * - _RSEQ_N() is reverse sequential to N to add padding to have
+ * - reference www.stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments
+ * - TU_GET_NTH_ARG() takes args >= N (64) but only expand to Nth one (64th)
+ * - TU_NARG_RSEQ_N() is reverse sequential to N to add padding to have
* Nth position is the same as the number of arguments
* - ##__VA_ARGS__ is used to deal with 0 paramerter (swallows comma)
*------------------------------------------------------------------*/
-#if !defined(__CCRX__)
-#define TU_ARGS_NUM(...) _TU_NARG(_0, ##__VA_ARGS__, _RSEQ_N())
+#if defined(__CCRX__)
+#define TU_ARGS_NUM(...) TU_NARG_IMPL(_0, __VA_ARGS__, TU_NARG_RSEQ_N())
#else
-#define TU_ARGS_NUM(...) _TU_NARG(_0, __VA_ARGS__, _RSEQ_N())
+#define TU_ARGS_NUM(...) TU_NARG_IMPL(_0, ##__VA_ARGS__, TU_NARG_RSEQ_N())
#endif
-#define _TU_NARG(...) _GET_NTH_ARG(__VA_ARGS__)
-#define _GET_NTH_ARG( \
+#define TU_NARG_IMPL(...) TU_GET_NTH_ARG(__VA_ARGS__)
+#define TU_GET_NTH_ARG( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
@@ -97,7 +92,7 @@
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,N,...) N
-#define _RSEQ_N() \
+#define TU_NARG_RSEQ_N() \
62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
@@ -106,17 +101,29 @@
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
-// Apply an macro X to each of the arguments with an separated of choice
-#define TU_ARGS_APPLY(_X, _s, ...) TU_XSTRCAT(_TU_ARGS_APPLY_, TU_ARGS_NUM(__VA_ARGS__))(_X, _s, __VA_ARGS__)
+// Apply a macro X to each of the arguments with a separation/delimiter
+#define TU_ARGS_APPLY(_X, _s, ...) TU_XSTRCAT(TU_ARGS_APPLY_, TU_ARGS_NUM(__VA_ARGS__))(_X, _s, __VA_ARGS__)
+
+#define TU_ARGS_APPLY_1(_X, _s, _a1) _X(_a1)
+#define TU_ARGS_APPLY_2(_X, _s, _a1, _a2) _X(_a1) _s _X(_a2)
+#define TU_ARGS_APPLY_3(_X, _s, _a1, _a2, _a3) _X(_a1) _s TU_ARGS_APPLY_2(_X, _s, _a2, _a3)
+#define TU_ARGS_APPLY_4(_X, _s, _a1, _a2, _a3, _a4) _X(_a1) _s TU_ARGS_APPLY_3(_X, _s, _a2, _a3, _a4)
+#define TU_ARGS_APPLY_5(_X, _s, _a1, _a2, _a3, _a4, _a5) _X(_a1) _s TU_ARGS_APPLY_4(_X, _s, _a2, _a3, _a4, _a5)
+#define TU_ARGS_APPLY_6(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6) _X(_a1) _s TU_ARGS_APPLY_5(_X, _s, _a2, _a3, _a4, _a5, _a6)
+#define TU_ARGS_APPLY_7(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7) _X(_a1) _s TU_ARGS_APPLY_6(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7)
+#define TU_ARGS_APPLY_8(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) _X(_a1) _s TU_ARGS_APPLY_7(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7, _a8)
-#define _TU_ARGS_APPLY_1(_X, _s, _a1) _X(_a1)
-#define _TU_ARGS_APPLY_2(_X, _s, _a1, _a2) _X(_a1) _s _X(_a2)
-#define _TU_ARGS_APPLY_3(_X, _s, _a1, _a2, _a3) _X(_a1) _s _TU_ARGS_APPLY_2(_X, _s, _a2, _a3)
-#define _TU_ARGS_APPLY_4(_X, _s, _a1, _a2, _a3, _a4) _X(_a1) _s _TU_ARGS_APPLY_3(_X, _s, _a2, _a3, _a4)
-#define _TU_ARGS_APPLY_5(_X, _s, _a1, _a2, _a3, _a4, _a5) _X(_a1) _s _TU_ARGS_APPLY_4(_X, _s, _a2, _a3, _a4, _a5)
-#define _TU_ARGS_APPLY_6(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6) _X(_a1) _s _TU_ARGS_APPLY_5(_X, _s, _a2, _a3, _a4, _a5, _a6)
-#define _TU_ARGS_APPLY_7(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7) _X(_a1) _s _TU_ARGS_APPLY_6(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7)
-#define _TU_ARGS_APPLY_8(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) _X(_a1) _s _TU_ARGS_APPLY_7(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7, _a8)
+// Apply a macro X to each of the arguments and expand the result with comma
+#define TU_ARGS_APPLY_EXPAND(_X, ...) TU_XSTRCAT(TU_ARGS_APPLY_EXPAND_, TU_ARGS_NUM(__VA_ARGS__))(_X, __VA_ARGS__)
+
+#define TU_ARGS_APPLY_EXPAND_1(_X, _a1) _X(_a1)
+#define TU_ARGS_APPLY_EXPAND_2(_X, _a1, _a2) _X(_a1), _X(_a2)
+#define TU_ARGS_APPLY_EXPAND_3(_X, _a1, _a2, _a3) _X(_a1), TU_ARGS_APPLY_EXPAND_2(_X, _a2, _a3)
+#define TU_ARGS_APPLY_EXPAND_4(_X, _a1, _a2, _a3, _a4) _X(_a1), TU_ARGS_APPLY_EXPAND_3(_X, _a2, _a3, _a4)
+#define TU_ARGS_APPLY_EXPAND_5(_X, _a1, _a2, _a3, _a4, _a5) _X(_a1), TU_ARGS_APPLY_EXPAND_4(_X, _a2, _a3, _a4, _a5)
+#define TU_ARGS_APPLY_EXPAND_6(_X, _a1, _a2, _a3, _a4, _a5, _a6) _X(_a1), TU_ARGS_APPLY_EXPAND_5(_X, _a2, _a3, _a4, _a5, _a6)
+#define TU_ARGS_APPLY_EXPAND_7(_X, _a1, _a2, _a3, _a4, _a5, _a6, _a7) _X(_a1), TU_ARGS_APPLY_EXPAND_6(_X, _a2, _a3, _a4, _a5, _a6, _a7)
+#define TU_ARGS_APPLY_EXPAND_8(_X, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) _X(_a1), TU_ARGS_APPLY_EXPAND_7(_X, _a2, _a3, _a4, _a5, _a6, _a7, _a8)
//--------------------------------------------------------------------+
// Macro for function default arguments
@@ -127,18 +134,20 @@
#define TU_FUNC_OPTIONAL_ARG(func, ...) TU_XSTRCAT(func##_arg, TU_ARGS_NUM(__VA_ARGS__))(__VA_ARGS__)
//--------------------------------------------------------------------+
-// Compiler porting with Attribute and Endian
+// Compiler Attribute Abstraction
//--------------------------------------------------------------------+
+#if defined(__GNUC__) || defined(__ICCARM__) || defined(__TI_COMPILER_VERSION__)
+ #if defined(__ICCARM__)
+ #include <intrinsics.h> // for builtin functions
+ #endif
-// TODO refactor since __attribute__ is supported across many compiler
-#if defined(__GNUC__)
- #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
- #define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name)))
- #define TU_ATTR_PACKED __attribute__ ((packed))
- #define TU_ATTR_WEAK __attribute__ ((weak))
- // #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f)))
- #ifndef TU_ATTR_ALWAYS_INLINE // allow to override for debug
- #define TU_ATTR_ALWAYS_INLINE __attribute__ ((always_inline))
+ #define TU_ATTR_ALIGNED(Bytes) __attribute__((aligned(Bytes)))
+ #define TU_ATTR_SECTION(sec_name) __attribute__((section(#sec_name)))
+ #define TU_ATTR_PACKED __attribute__((packed))
+ #define TU_ATTR_WEAK __attribute__((weak))
+// #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f)))
+ #ifndef TU_ATTR_ALWAYS_INLINE // allow to override for debug
+ #define TU_ATTR_ALWAYS_INLINE __attribute__((always_inline))
#endif
#define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used
#define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused
@@ -149,21 +158,22 @@
#define TU_ATTR_BIT_FIELD_ORDER_BEGIN
#define TU_ATTR_BIT_FIELD_ORDER_END
- #if __GNUC__ < 5
- #define TU_ATTR_FALLTHROUGH do {} while (0) /* fallthrough */
+ #if (defined(__has_attribute) && __has_attribute(__fallthrough__)) || defined(__TI_COMPILER_VERSION__)
+ #define TU_ATTR_FALLTHROUGH __attribute__((fallthrough))
#else
- #if __has_attribute(__fallthrough__)
- #define TU_ATTR_FALLTHROUGH __attribute__((fallthrough))
- #else
- #define TU_ATTR_FALLTHROUGH do {} while (0) /* fallthrough */
- #endif
+ #define TU_ATTR_FALLTHROUGH \
+ do { \
+ } while (0) /* fallthrough */
#endif
- // Endian conversion use well-known host to network (big endian) naming
- #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+// Endian conversion use well-known host to network (big endian) naming
+// For TI ARM compiler, __BYTE_ORDER__ is not defined for MSP430 but still LE
+ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || defined(__MSP430__)
#define TU_BYTE_ORDER TU_LITTLE_ENDIAN
+ #define TU_BITFIELD_ORDER TU_BITFIELD_LE
#else
#define TU_BYTE_ORDER TU_BIG_ENDIAN
+ #define TU_BITFIELD_ORDER TU_BITFIELD_BE
#endif
// Unfortunately XC16 doesn't provide builtins for 32bit endian conversion
@@ -178,39 +188,12 @@
#define TU_BSWAP32(u32) (__builtin_bswap32(u32))
#endif
- #ifndef __ARMCC_VERSION
// List of obsolete callback function that is renamed and should not be defined.
// Put it here since only gcc support this pragma
- #pragma GCC poison tud_vendor_control_request_cb
- #endif
-
-#elif defined(__TI_COMPILER_VERSION__)
- #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
- #define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name)))
- #define TU_ATTR_PACKED __attribute__ ((packed))
- #define TU_ATTR_WEAK __attribute__ ((weak))
- // #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f)))
- #define TU_ATTR_ALWAYS_INLINE __attribute__ ((always_inline))
- #define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used
- #define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused
- #define TU_ATTR_USED __attribute__ ((used))
- #define TU_ATTR_FALLTHROUGH __attribute__((fallthrough))
-
- #define TU_ATTR_PACKED_BEGIN
- #define TU_ATTR_PACKED_END
- #define TU_ATTR_BIT_FIELD_ORDER_BEGIN
- #define TU_ATTR_BIT_FIELD_ORDER_END
-
- // __BYTE_ORDER is defined in the TI ARM compiler, but not MSP430 (which is little endian)
- #if ((__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__)) || defined(__MSP430__)
- #define TU_BYTE_ORDER TU_LITTLE_ENDIAN
- #else
- #define TU_BYTE_ORDER TU_BIG_ENDIAN
+ #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__)
+ #pragma GCC poison tud_vendor_control_request_cb
#endif
- #define TU_BSWAP16(u16) (__builtin_bswap16(u16))
- #define TU_BSWAP32(u32) (__builtin_bswap32(u32))
-
#elif defined(__ICCARM__)
#include <intrinsics.h>
#define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
@@ -234,8 +217,10 @@
// Endian conversion use well-known host to network (big endian) naming
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define TU_BYTE_ORDER TU_LITTLE_ENDIAN
+ #define TU_BITFIELD_ORDER TU_BITFIELD_LE
#else
#define TU_BYTE_ORDER TU_BIG_ENDIAN
+ #define TU_BITFIELD_ORDER TU_BITFIELD_BE
#endif
#define TU_BSWAP16(u16) (__iar_builtin_REV16(u16))
@@ -261,8 +246,10 @@
// Endian conversion use well-known host to network (big endian) naming
#if defined(__LIT)
#define TU_BYTE_ORDER TU_LITTLE_ENDIAN
+ #define TU_BITFIELD_ORDER TU_BITFIELD_LE
#else
#define TU_BYTE_ORDER TU_BIG_ENDIAN
+ #define TU_BITFIELD_ORDER TU_BITFIELD_BE
#endif
#define TU_BSWAP16(u16) ((unsigned short)_builtin_revw((unsigned long)u16))
@@ -304,7 +291,3 @@
#else
#error Byte order is undefined
#endif
-
-#endif /* _TUSB_COMPILER_H_ */
-
-/// @}