]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4sys/include/compiler.h
update: sync
[l4.git] / l4 / pkg / l4sys / include / compiler.h
1 /*****************************************************************************/
2 /**
3  * \file
4  * \brief   L4 compiler related defines.
5  * \ingroup l4_api
6  */
7 /*
8  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
9  *               Alexander Warg <warg@os.inf.tu-dresden.de>,
10  *               Frank Mehnert <fm3@os.inf.tu-dresden.de>,
11  *               Jork Löser <jork@os.inf.tu-dresden.de>,
12  *               Ronald Aigner <ra3@os.inf.tu-dresden.de>
13  *     economic rights: Technische Universität Dresden (Germany)
14  *
15  * This file is part of TUD:OS and distributed under the terms of the
16  * GNU General Public License 2.
17  * Please see the COPYING-GPL-2 file for details.
18  *
19  * As a special exception, you may use this file as part of a free software
20  * library without restriction.  Specifically, if other files instantiate
21  * templates or use macros or inline functions from this file, or you compile
22  * this file and link it with other files to produce an executable, this
23  * file does not by itself cause the resulting executable to be covered by
24  * the GNU General Public License.  This exception does not however
25  * invalidate any other reasons why the executable file might be covered by
26  * the GNU General Public License.
27  */
28 /*****************************************************************************/
29 #ifndef __L4_COMPILER_H__
30 #define __L4_COMPILER_H__
31
32 #if !defined(__ASSEMBLY__) && !defined(__ASSEMBLER__)
33
34 /**
35  * \addtogroup l4sys_defines
36  *
37  * <c>\#include <l4/sys/compiler.h></c>
38  */
39 /*@{*/
40
41 /**
42  * L4 Inline function attribute.
43  * \hideinitializer
44  */
45 #ifndef L4_INLINE
46 #ifndef __cplusplus
47 #  ifdef __OPTIMIZE__
48 #    define L4_INLINE_STATIC static __inline__
49 #    define L4_INLINE_EXTERN extern __inline__
50      /* gcc-4.3 implements c99 inline behaviour, i.e. we use the
51       * 'extern  inline' there, 4.2 and below use 'static inline' */
52 #    if (__GNUC__ == 4 && __GNUC_MINOR__ <= 2) || __GNUC__ <= 3
53 #      define L4_INLINE L4_INLINE_STATIC
54 #    else
55 #      ifdef __GNUC_STDC_INLINE__
56 #        define L4_INLINE L4_INLINE_STATIC
57 #      else
58 #        define L4_INLINE L4_INLINE_EXTERN
59 #      endif
60 #    endif
61 #  else /* ! __OPTIMIZE__ */
62 #    define L4_INLINE static
63 #  endif /* ! __OPTIMIZE__ */
64 #else /* __cplusplus */
65 #  define L4_INLINE inline
66 #endif  /* __cplusplus */
67 #endif  /* L4_INLINE */
68
69 #if ((__GNUC__ * 100 + __GNUC_MINOR__) >= 405)
70 # define L4_DECLARE_CONSTRUCTOR(func, prio) \
71   static inline __attribute__((constructor(prio))) void func ## _ctor_func(void) { func(); }
72 #else
73
74
75 /**
76  * \brief Handcoded version of __attribute__((constructor(xx))).
77  * \param func function declaration (prototype)
78  * \param prio the prio must be 65535 - \a gcc_prio
79  */
80 #if defined (__ARM_EABI__)
81 #  define L4_DECLARE_CONSTRUCTOR(func, prio) \
82     static __typeof(&func) func ## _ctor__ __attribute__((used,section(".init_array." L4_stringify(prio)))) = &func;
83 #else
84 #  define L4_DECLARE_CONSTRUCTOR(func, prio) \
85     static __typeof(&func) func ## _ctor__ __attribute__((used,section(".ctors." L4_stringify(prio)))) = &func;
86 #endif
87 #endif
88
89
90
91 /**
92  * Start section with C types and functions.
93  * \def     __BEGIN_DECLS
94  * \hideinitializer
95  */
96 /**
97  * End section with C types and functions.
98  * \def     __END_DECLS
99  * \hideinitializer
100  */
101 /**
102  * Start section with C types and functions.
103  * \def     EXTERN_C_BEGIN
104  * \hideinitializer
105  */
106 /**
107  * End section with C types and functions.
108  * \def     EXTERN_C_END
109  * \hideinitializer
110  */
111 /**
112  * Mark C types and functions.
113  * \def     EXTERN_C
114  * \hideinitializer
115  */
116
117 /**
118  * \def L4_NOTHROW
119  * \hideinitializer
120  * \brief Mark a function declaration and definition as never
121  *        throwing an exception. (Also for C code).
122  *
123  * This macro shall be used to mark C and C++ functions that never
124  * throw any exception.  Note that also C functions may throw exceptions
125  * according to the compilers ABI and shall be marke with L4_NOTHROW
126  * if they never do.  In C++ this is equvalent to \c throw().
127  *
128  * \code
129  * int foo() L4_NOTHROW;
130  * ...
131  * int foo() L4_NOTHROW
132  * {
133  *   ...
134  *   return result;
135  * }
136  * \endcode
137  *
138  */
139
140 /**
141  * \def L4_EXPORT
142  * \hideinitializer
143  * \brief Attribute to mark functions, variables, and data types as being
144  *        exported from a library.
145  *
146  * All data types, functions, and global variables that shall be exported
147  * from a library shall be marked with this attribute.  The default may become
148  * to hide everything that is not marked as L4_EXPORT from the users of a
149  * library and provide the possibility for aggressive optimization of all
150  * those internal functionality of a library.
151  *
152  * Usage:
153  * \code
154  * class L4_EXPORT My_class
155  * {
156  *   ...
157  * };
158  *
159  * int L4_EXPORT function(void);
160  *
161  * int L4_EXPORT global_data; // global data is not recommended
162  * \endcode
163  *
164  */
165
166 /**
167  * \def L4_HIDDEN
168  * \hideinitializer
169  * \brief Attribute to mark functions, variables, and data types as being
170  *        explicitly hidden from users of a library.
171  *
172  * This attribute is intended for functions, data, and data types that
173  * shall never be visible outside of a library.  In particular, for shared
174  * libraries this may result in much faster code within the library and short
175  * linking times.
176  *
177  * \code
178  * class L4_HIDDEN My_class
179  * {
180  *   ...
181  * };
182  *
183  * int L4_HIDDEN function(void);
184  *
185  * int L4_HIDDEN global_data; // global data is not recommended
186  * \endcode
187  */
188 #ifndef __cplusplus
189 #  define L4_NOTHROW__A       __attribute__((nothrow))
190 #  define L4_NOTHROW
191 #  define EXTERN_C_BEGIN
192 #  define EXTERN_C_END
193 #  define EXTERN_C
194 #  ifndef __BEGIN_DECLS
195 #    define __BEGIN_DECLS
196 #  endif
197 #  ifndef __END_DECLS
198 #    define __END_DECLS
199 #  endif
200 #  define L4_DEFAULT_PARAM(x)
201 #else /* __cplusplus */
202 #  define L4_NOTHROW throw()
203 #  define EXTERN_C_BEGIN extern "C" {
204 #  define EXTERN_C_END }
205 #  define EXTERN_C extern "C"
206 #  ifndef __BEGIN_DECLS
207 #    define __BEGIN_DECLS extern "C" {
208 #  endif
209 #  ifndef __END_DECLS
210 #    define __END_DECLS }
211 #  endif
212 #  define L4_DEFAULT_PARAM(x) = x
213 #endif /* __cplusplus */
214
215 /**
216  * Noreturn function attribute.
217  * \hideinitializer
218  */
219 #define L4_NORETURN __attribute__((noreturn))
220
221 /**
222  * No instrumentation function attribute.
223  * \hideinitializer
224  */
225 #define L4_NOINSTRUMENT __attribute__((no_instrument_function))
226 #ifndef L4_HIDDEN
227 #  define L4_HIDDEN __attribute__((visibility("hidden")))
228 #endif
229 #ifndef L4_EXPORT
230 #  define L4_EXPORT __attribute__((visibility("default")))
231 #endif
232 #define L4_STRONG_ALIAS(name, aliasname) L4__STRONG_ALIAS(name, aliasname)
233 #define L4__STRONG_ALIAS(name, aliasname) \
234   extern __typeof (name) aliasname __attribute__ ((alias (#name)));
235
236
237 #endif /* !__ASSEMBLY__ */
238
239 #include <l4/sys/linkage.h>
240
241 #if __GNUC__ == 2 && __GNUC_MINOR__ < 96
242 #define __builtin_expect(x, expected_value) (x)
243 #endif
244
245 #define EXPECT_TRUE(x)  __builtin_expect((x),1)   ///< Expression is likely to execute. \hideinitializer
246 #define EXPECT_FALSE(x) __builtin_expect((x),0)   ///< Expression is unlikely to execute. \hideinitializer
247
248 #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ >= 4
249 /* Make sure that the function is not removed by optimization. Without the
250  * "used" attribute, unreferenced static functions are removed. */
251 #define L4_STICKY(x)    __attribute__((used)) x         ///< Mark symbol sticky (even not there) \hideinitializer
252 /* The deprecated attribute is available with 3.1 and higher (3.3 as here
253  * is ok for us */
254 # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) || __GNUC__ >= 5
255 # define L4_DEPRECATED(s) __attribute__((deprecated(s)))     ///< Mark symbol deprecated. \hideinitializer
256 # else
257 # define L4_DEPRECATED(s) __attribute__((deprecated))     ///< Mark symbol deprecated. \hideinitializer
258 # endif
259 #else
260 /* The "used" attribute is not available with older gcc versions so simply
261  * make sure that gcc doesn't warn about unused functions. */
262 #define L4_STICKY(x)    __attribute__((unused)) x       ///< Mark symbol sticky (even not there).
263 #define L4_DEPRECATED(s)                                ///< Mark symbol deprecated
264 #endif
265
266 #ifndef __GXX_EXPERIMENTAL_CXX0X__
267 #ifndef static_assert
268 #define static_assert(x, y) \
269   do { (void)sizeof(char[-(!(x))]); } while (0)
270 #endif
271 #endif
272
273 #define L4_stringify_helper(x) #x                       ///< stringify helper. \hideinitializer
274 #define L4_stringify(x)        L4_stringify_helper(x)   ///< stringify. \hideinitializer
275
276 #ifndef __ASSEMBLER__
277 /**
278  * \brief Memory barrier.
279  */
280 L4_INLINE void l4_barrier(void);
281
282 /**
283  * \brief Memory barrier.
284  */
285 L4_INLINE void l4_mb(void);
286
287 /**
288  * \brief Write memory barrier.
289  */
290 L4_INLINE void l4_wmb(void);
291
292
293 /* Implementations */
294 L4_INLINE void l4_barrier(void)
295 {
296   __asm__ __volatile__ ("" : : : "memory");
297 }
298
299 L4_INLINE void l4_mb(void)
300 {
301   __asm__ __volatile__ ("" : : : "memory");
302 }
303
304 L4_INLINE void l4_wmb(void)
305 {
306   __asm__ __volatile__ ("" : : : "memory");
307 }
308 #endif
309
310 /*@}*/
311
312 #endif /* !__L4_COMPILER_H__ */