*
* \brief Additional support macros for compiler independance
*
- * \version $Id$
* \author Bernie Innocenti <bernie@codewiz.org>
*/
#pragma c99 on
#endif
-#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
- #define COMPILER_C99 1
-#else
- #define COMPILER_C99 0
+#if defined(__STDC_VERSION__)
+ #if (__STDC_VERSION__ == 199409L) // IAR
+ #define COMPILER_C99 1 // not true, because partial C99, avoid miscompilation
+ #elif (__STDC_VERSION__ >= 199901L) // GCC
+ #define COMPILER_C99 1
+ #else
+ #define COMPILER_C99 0
+ #endif
#endif
#define PP_STRINGIZE__(x) #x
+/**
+ */
+#if COMPILER_C99
+ #define COUNT_PARMS2(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _, ...) _
+ #define COUNT_PARMS(...) \
+ COUNT_PARMS2(11 , ## __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
+
+ /**
+ * usage:
+ * \code
+ * #define foo_init(...) PP_CAT(foo_init_, COUNT_PARMS(__VA_ARGS__)) (__VA_ARGS__)
+ * \endcode
+ */
+
+#else
+ #define COUNT_PARMS2(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _, ...) _
+ #define COUNT_PARMS(args...) \
+ COUNT_PARMS2(11 , ## args, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
+
+ /**
+ * usage:
+ * \code
+ * #define foo_init(args...) PP_CAT(foo_init_, COUNT_PARMS(args)) (args)
+ * \endcode
+ */
+
+#endif
+
#if defined(__IAR_SYSTEMS_ICC) || defined(__IAR_SYSTEMS_ICC__)
#pragma language=extended
- #if CPU_ARM
+ /* IAR iccarm specific functions */
+ #include <intrinsics.h>
+ #pragma diag_suppress=Pe940
+ #pragma inline = forced
+
+ #define MEMORY_BARRIER asm("")
+
+ #if CPU_ARM || CPU_CM3
#define COMPILER_VARIADIC_MACROS 1
#define INTERRUPT(x) __irq __arm void x (void)
#define INLINE static inline
+ #define NAKED
/* Include some standard C89/C99 stuff */
#include <stddef.h>
#define UNUSED_VAR(type,name) __attribute__((__unused__)) type name
#define USED_VAR(type,name) __attribute__((__used__)) type name
#define INLINE static inline __attribute__((__always_inline__))
+ #define NOINLINE __attribute__((noinline))
#define LIKELY(x) __builtin_expect(!!(x), 1)
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
#define PURE_FUNC __attribute__((pure))
#define RESTRICT __restrict__
#define MUST_CHECK __attribute__((warn_unused_result))
#define PACKED __attribute__((packed))
+ #define ALIGNED(x) __attribute__ ((__aligned__(x)))
+ #if CPU_ARM | CPU_CM3
+ #define NAKED __attribute__((naked))
+ #else
+ #define NAKED
+ #endif
+
/**
- * Force compiler to realod context variable.
+ * Force compiler to reload context variable.
*/
#define MEMORY_BARRIER asm volatile ("" : : : "memory")
#ifndef INLINE
#define INLINE static inline
#endif
+#ifndef NOINLINE
+#define NOINLINE /* nothing */
+#endif
#ifndef NORETURN
#define NORETURN /* nothing */
#endif
#ifndef PACKED
#define PACKED /* nothing */
#endif
+#ifndef ALIGNED
+#define ALIGNED /* nothing */
+#endif
#ifndef MEMORY_BARRIER
#define MEMORY_BARRIER /* nothing */
#warning No memory barrier defined for select compiler. If you use the kernel check it.
#endif
#endif
+/** User defined callback type */
+typedef void (*Hook)(void *);
+
/** Bulk storage large enough for both pointers or integers. */
typedef void * iptr_t;
typedef unsigned char sigbit_t; /**< Type for signal bits. */
typedef unsigned char sigmask_t; /**< Type for signal masks. */
-typedef unsigned char page_t; /**< Type for banked memory pages. */
+/**
+ * Signal structure
+ */
+typedef struct Signal
+{
+ sigmask_t wait; /**< Signals the process is waiting for */
+ sigmask_t recv; /**< Received signals */
+} Signal;
/**
* \name Standard type definitions.
typedef long ssize_t;
#elif CPU_ARM || CPU_CM3
typedef int ssize_t;
- #elif CPU_AVR
- /* 16bit (missing in avr-libc's sys/types.h). */
+ #elif CPU_AVR || CPU_MSP430
+ /* 16bit (missing in avr-/msp430-libc's sys/types.h). */
typedef int ssize_t;
#else
#error Unknown CPU
*
* \note This macro is non-standard, but implements a very common idiom
*/
- #define countof(a) (sizeof(a) / sizeof(*(a)))
+ #if defined(__GNUC__) && !defined(__cplusplus)
+ /*
+ * Perform a compile time type checking: countof() can only
+ * work with static arrays, so throw a compile time error if a
+ * pointer is passed as argument.
+ *
+ * NOTE: the construct __builtin_types_compatible_p() is only
+ * available for C.
+ */
+ #define countof(a) (sizeof(a) / sizeof(*(a)) + \
+ STATIC_ASSERT_EXPR( \
+ !__builtin_types_compatible_p( \
+ typeof(a), typeof(&a[0]))))
+ #else
+ #define countof(a) (sizeof(a) / sizeof(*(a)))
+ #endif
#endif
#ifndef alignof
/**
#define STATIC_ASSERT(condition) \
UNUSED_VAR(extern char, STATIC_ASSERTION_FAILED__[(condition) ? 1 : -1])
+/**
+ * Issue a compilation error if \a __cond is false (this can be used inside an
+ * expression).
+ */
+#define STATIC_ASSERT_EXPR(__cond) \
+ (sizeof(struct { int STATIC_ASSERTION_FAILED__:!!(__cond); }) * 0)
+
#ifndef ASSERT_TYPE_EQUAL
/** Ensure two variables have the same type. */
#define ASSERT_TYPE_EQUAL(var1, var2) \
do { (void)(&(var) == (type *)0); } while(0)
#endif
+/**
+ * Prevent the compiler from optimizing access to the variable \a x, enforcing
+ * a refetch from memory. This also forbid from reordering successing instances
+ * of ACCESS_SAFE().
+ */
+#ifdef __ICCARM__
+#define ACCESS_SAFE(x) x
+#else
+#define ACCESS_SAFE(x) (*(volatile typeof(x) *)&(x))
+#endif
+
#endif /* BERTOS_COMPILER_H */