summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/basedefs.h
blob: c378635befb8d1a16bf1b24f6a4fbb66e65d3dad (plain) (blame)
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
/**
 * @file
 *
 * @ingroup Score
 *
 * @brief Basic Definitions
 */

/*
 *  COPYRIGHT (c) 1989-2007.
 *  On-Line Applications Research Corporation (OAR).
 *
 *  Copyright (c) 2010-2015 embedded brains GmbH.
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.org/license/LICENSE.
 */

#ifndef _RTEMS_BASEDEFS_H
#define _RTEMS_BASEDEFS_H

/**
 *  @defgroup ScoreBaseDefs Basic Definitions
 *
 *  @ingroup Score
 */
/**@{*/

#include <rtems/score/cpuopts.h>

#ifndef ASM
  #include <stddef.h>
  #include <stdbool.h>
  #include <stdint.h>

  /*
   * FIXME: This include should not be present.  In older RTEMS versions
   * <rtems.h> provided <limits.h> indirectly.  This include is here to not
   * break application source files that relied on this accidentally.
   */
  #include <limits.h>

  /*
   * FIXME: This include should not be present.  In older RTEMS versions
   * <rtems.h> provided <string.h> indirectly.  This include is here to not
   * break application source files that relied on this accidentally.
   */
  #include <string.h>
#endif

#ifndef TRUE
  /**
   *  This ensures that RTEMS has TRUE defined in all situations.
   */
  #define TRUE 1
#endif

#ifndef FALSE
  /**
   *  This ensures that RTEMS has FALSE defined in all situations.
   */
  #define FALSE 0
#endif

#if TRUE == FALSE
  #error "TRUE equals FALSE"
#endif

/**
 *  The following (in conjunction with compiler arguments) are used
 *  to choose between the use of static inline functions and macro
 *  functions.   The static inline implementation allows better
 *  type checking with no cost in code size or execution speed.
 */
#ifdef __GNUC__
  #define RTEMS_INLINE_ROUTINE static __inline__
#else
  #define RTEMS_INLINE_ROUTINE static inline
#endif

/**
 *  The following macro is a compiler specific way to ensure that memory
 *  writes are not reordered around certian points.  This specifically can
 *  impact interrupt disable and thread dispatching critical sections.
 */
#ifdef __GNUC__
  #define RTEMS_COMPILER_MEMORY_BARRIER() __asm__ volatile("" ::: "memory")
#else
  #define RTEMS_COMPILER_MEMORY_BARRIER()
#endif

/**
 *  The following macro is a compiler specific way to indicate that
 *  the method will NOT return to the caller.  This can assist the
 *  compiler in code generation and avoid unreachable paths.  This
 *  can impact the code generated following calls to
 *  rtems_fatal_error_occurred and _Terminate.
 */
#if defined(RTEMS_SCHEDSIM)
  #define RTEMS_NO_RETURN
#elif defined(__GNUC__) && !defined(RTEMS_DEBUG)
  #define RTEMS_NO_RETURN __attribute__((__noreturn__))
#else
  #define RTEMS_NO_RETURN
#endif

/* Provided for backward compatibility */
#define RTEMS_COMPILER_NO_RETURN_ATTRIBUTE RTEMS_NO_RETURN

/**
 *  The following defines a compiler specific attribute which informs
 *  the compiler that the method has no effect except the return value
 *  and that the return value depends only on parameters and/or global
 *  variables.
 */
#ifdef __GNUC__
  #define RTEMS_PURE __attribute__((__pure__))
#else
  #define RTEMS_PURE
#endif

/* Provided for backward compatibility */
#define RTEMS_COMPILER_PURE_ATTRIBUTE RTEMS_PURE

/**
 *  Instructs the compiler to issue a warning whenever a variable or function
 *  with this attribute will be used.
 */
#ifdef __GNUC__
  #define RTEMS_DEPRECATED __attribute__((__deprecated__))
#else
  #define RTEMS_DEPRECATED
#endif

/* Provided for backward compatibility */
#define RTEMS_COMPILER_DEPRECATED_ATTRIBUTE RTEMS_DEPRECATED

/**
 * @brief Instructs the compiler to place a specific variable or function in
 * the specified section.
 */
#if defined(__GNUC__)
  #define RTEMS_SECTION( _section ) __attribute__((__section__(_section)))
#else
  #define RTEMS_SECTION( _section )
#endif

/**
 * @brief Instructs the compiler that a specific variable or function is used.
 */
#if defined(__GNUC__)
  #define RTEMS_USED __attribute__((__used__))
#else
  #define RTEMS_USED
#endif

/**
 *  Instructs the compiler that a specific variable is deliberately unused.
 *  This can occur when reading volatile device memory or skipping arguments
 *  in a variable argument method.
 */
#if defined(__GNUC__)
  #define RTEMS_UNUSED __attribute__((__unused__))
#else
  #define RTEMS_UNUSED
#endif

/* Provided for backward compatibility */
#define RTEMS_COMPILER_UNUSED_ATTRIBUTE RTEMS_UNUSED

/**
 *  Instructs the compiler that a specific structure or union members will be
 *  placed so that the least memory is used.
 */
#if defined(__GNUC__)
  #define RTEMS_PACKED __attribute__((__packed__))
#else
  #define RTEMS_PACKED
#endif

/**
 * @brief Instructs the compiler to enforce the specified alignment.
 */
#if defined(__GNUC__)
  #define RTEMS_ALIGNED( _alignment ) __attribute__((__aligned__(_alignment)))
#else
  #define RTEMS_ALIGNED( _alignment )
#endif

/* Provided for backward compatibility */
#define RTEMS_COMPILER_PACKED_ATTRIBUTE RTEMS_PACKED

#if defined(RTEMS_DEBUG) && !defined(RTEMS_SCHEDSIM)
  #define _Assert_Unreachable() _Assert( 0 )
#else
  #define _Assert_Unreachable() do { } while ( 0 )
#endif

/**
 * @brief Tells the compiler that this program point is unreachable.
 */
#if defined(__GNUC__) && !defined(RTEMS_SCHEDSIM)
  #define RTEMS_UNREACHABLE() \
    do { \
      __builtin_unreachable(); \
      _Assert_Unreachable(); \
    } while ( 0 )
#else
  #define RTEMS_UNREACHABLE() _Assert_Unreachable()
#endif

/**
 * @brief Tells the compiler that this function expects printf()-like
 * arguments.
 */
#if defined(__GNUC__)
  #define RTEMS_PRINTFLIKE( _format_pos, _ap_pos ) \
    __attribute__((__format__(__printf__, _format_pos, _ap_pos)))
#else
  #define RTEMS_PRINTFLIKE( _format_pos, _ap_pos )
#endif

#if __cplusplus >= 201103L
  #define RTEMS_STATIC_ASSERT(cond, msg) \
    static_assert(cond, # msg)
#elif __STDC_VERSION__ >= 201112L
  #define RTEMS_STATIC_ASSERT(cond, msg) \
    _Static_assert(cond, # msg)
#else
  #define RTEMS_STATIC_ASSERT(cond, msg) \
    typedef int rtems_static_assert_ ## msg [(cond) ? 1 : -1]
#endif

#define RTEMS_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))

/*
 * Zero-length arrays are valid in C99 as flexible array members.  C++11
 * doesn't allow flexible array members.  Use the GNU extension which is also
 * supported by other compilers.
 */
#define RTEMS_ZERO_LENGTH_ARRAY 0

/**
 * @brief Returns a pointer to the container of a specified member pointer.
 *
 * @param[in] _m The pointer to a member of the container.
 * @param[in] _type The type of the container.
 * @param[in] _member_name The designator name of the container member.
 */
#define RTEMS_CONTAINER_OF( _m, _type, _member_name ) \
  ( (_type *) ( (uintptr_t) ( _m ) - offsetof( _type, _member_name ) ) )

#ifdef __cplusplus
#define RTEMS_DEQUALIFY_DEPTHX( _ptr_level, _type, _var ) \
            (const_cast<_type>( _var ))
#else /* Standard C code */

/* The reference type idea based on libHX by Jan Engelhardt */
#define RTEMS_TYPEOF_REFX(_ptr_level, _ptr_type) \
  typeof(_ptr_level(union { int z; typeof(_ptr_type) x; }){0}.x)

#if defined(__GNUC__) && !defined(ASM)
#if  ((__GNUC__ * 1000 + __GNUC_MINOR__) >= 4004)
extern void* RTEMS_DEQUALIFY_types_not_compatible(void)
  __attribute__((error ("RTEMS_DEQUALIFY types differ not only by volatile and const")));
#else
extern void RTEMS_DEQUALIFY_types_not_compatible(void);
#endif
#define RTEMS_DEQUALIFY_DEPTHX( _ptr_level, _type, _var ) ( \
    __builtin_choose_expr( __builtin_types_compatible_p ( \
        RTEMS_TYPEOF_REFX( _ptr_level, _var ), \
        RTEMS_TYPEOF_REFX( _ptr_level, _type ) \
      ) || __builtin_types_compatible_p ( _type, void * ), \
    (_type)(_var), \
    RTEMS_DEQUALIFY_types_not_compatible() \
  ) \
)
#endif /*__GNUC__*/
#endif /*__cplusplus*/

#ifndef RTEMS_DECONST
#ifdef RTEMS_DEQUALIFY_DEPTHX
#define RTEMS_DECONST( _type, _var ) \
  RTEMS_DEQUALIFY_DEPTHX( *, _type, _var )
#else /*RTEMS_DEQUALIFY_DEPTHX*/
/**
 * @brief Removes the const qualifier from a type of a variable.
 *
 * @param[in] _type The target type for the variable.
 * @param[in] _var The variable.
 */
#define RTEMS_DECONST( _type, _var ) \
  ((_type)(uintptr_t)(const void *) ( _var ))

#endif /*RTEMS_DEQUALIFY_DEPTHX*/
#endif /*RTEMS_DECONST*/

#ifndef RTEMS_DEVOLATILE
#ifdef RTEMS_DEQUALIFY_DEPTHX
#define RTEMS_DEVOLATILE( _type, _var ) \
  RTEMS_DEQUALIFY_DEPTHX( *, _type, _var )
#else /*RTEMS_DEQUALIFY_DEPTHX*/
/**
 * @brief Removes the volatile qualifier from a type of a variable.
 *
 * @param[in] _type The target type for the variable.
 * @param[in] _var The variable.
 */
#define RTEMS_DEVOLATILE( _type, _var ) \
  ((_type)(uintptr_t)(volatile void *) ( _var ))

#endif /*RTEMS_DEQUALIFY_DEPTHX*/
#endif /*RTEMS_DEVOLATILE*/

#ifndef RTEMS_DEQUALIFY
#ifdef RTEMS_DEQUALIFY_DEPTHX
#define RTEMS_DEQUALIFY( _type, _var ) \
  RTEMS_DEQUALIFY_DEPTHX( *, _type, _var )
#else /*RTEMS_DEQUALIFY_DEPTHX*/
/**
 * @brief Removes the all qualifiers from a type of a variable.
 *
 * @param[in] _type The target type for the variable.
 * @param[in] _var The variable.
 */
#define RTEMS_DEQUALIFY( _type, _var ) \
  ((_type)(uintptr_t)(const volatile void *) ( _var ))

#endif /*RTEMS_DEQUALIFY_DEPTHX*/
#endif /*RTEMS_DEQUALIFY*/

/**
 * @brief Concatenates _x and _y without expanding.
 */
#define RTEMS_CONCAT( _x, _y ) _x##_y

/**
 * @brief Concatenates expansion of _x and expansion of _y.
 */
#define RTEMS_XCONCAT( _x, _y ) RTEMS_CONCAT( _x, _y )

/**
 * @brief Stringifies _x  without expanding.
 */
#define RTEMS_STRING( _x ) #_x

/**
 * @brief Stringifies expansion of _x.
 */
#define RTEMS_XSTRING( _x ) RTEMS_STRING( _x )

#ifndef ASM
  #ifdef RTEMS_DEPRECATED_TYPES
    typedef bool boolean;
    typedef float single_precision;
    typedef double double_precision;
  #endif

  /**
   * XXX: Eventually proc_ptr needs to disappear!!!
   */
  typedef void * proc_ptr;
#endif

/**@}*/

#endif /* _RTEMS_BASEDEFS_H */