source: rtems/cpukit/include/rtems/score/basedefs.h @ 3a882e5

5
Last change on this file since 3a882e5 was 3a882e5, checked in by Sebastian Huber <sebastian.huber@…>, on 04/05/20 at 08:30:43

score: Add and use RTEMS_SYMBOL_NAME()

Update #3799.

  • Property mode set to 100644
File size: 15.8 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSScore
5 *
6 * @brief Basic Definitions
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2007.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  Copyright (C) 2010, 2019 embedded brains GmbH
14 *
15 *  The license and distribution terms for this file may be
16 *  found in the file LICENSE in this distribution or at
17 *  http://www.rtems.org/license/LICENSE.
18 */
19
20#ifndef _RTEMS_BASEDEFS_H
21#define _RTEMS_BASEDEFS_H
22
23/**
24 * @defgroup RTEMSScoreBaseDefs Basic Definitions
25 *
26 * @ingroup RTEMSScore
27 *
28 * @{
29 */
30
31#include <rtems/score/cpuopts.h>
32
33#ifndef ASM
34  #include <stddef.h>
35  #include <stdbool.h>
36  #include <stdint.h>
37#endif
38
39#ifndef TRUE
40  /**
41   *  This ensures that RTEMS has TRUE defined in all situations.
42   */
43  #define TRUE 1
44#endif
45
46#ifndef FALSE
47  /**
48   *  This ensures that RTEMS has FALSE defined in all situations.
49   */
50  #define FALSE 0
51#endif
52
53#if TRUE == FALSE
54  #error "TRUE equals FALSE"
55#endif
56
57/**
58 *  The following (in conjunction with compiler arguments) are used
59 *  to choose between the use of static inline functions and macro
60 *  functions.   The static inline implementation allows better
61 *  type checking with no cost in code size or execution speed.
62 */
63#ifdef __GNUC__
64  #define RTEMS_INLINE_ROUTINE static __inline__
65#else
66  #define RTEMS_INLINE_ROUTINE static inline
67#endif
68
69/**
70 *  The following macro is a compiler specific way to ensure that memory
71 *  writes are not reordered around certain points.  This specifically can
72 *  impact interrupt disable and thread dispatching critical sections.
73 */
74#ifdef __GNUC__
75  #define RTEMS_COMPILER_MEMORY_BARRIER() __asm__ volatile("" ::: "memory")
76#else
77  #define RTEMS_COMPILER_MEMORY_BARRIER()
78#endif
79
80/**
81 *  The following defines a compiler specific attribute which informs
82 *  the compiler that the method must not be inlined.
83 */
84#ifdef __GNUC__
85  #define RTEMS_NO_INLINE __attribute__((__noinline__))
86#else
87  #define RTEMS_NO_INLINE
88#endif
89
90/**
91 *  The following macro is a compiler specific way to indicate that
92 *  the method will NOT return to the caller.  This can assist the
93 *  compiler in code generation and avoid unreachable paths.  This
94 *  can impact the code generated following calls to
95 *  rtems_fatal_error_occurred and _Terminate.
96 */
97#if defined(RTEMS_SCHEDSIM)
98  #define RTEMS_NO_RETURN
99#elif defined(__GNUC__) && !defined(RTEMS_DEBUG)
100  #define RTEMS_NO_RETURN __attribute__((__noreturn__))
101#else
102  #define RTEMS_NO_RETURN
103#endif
104
105/* Provided for backward compatibility */
106#define RTEMS_COMPILER_NO_RETURN_ATTRIBUTE RTEMS_NO_RETURN
107
108/**
109 *  The following defines a compiler specific attribute which informs
110 *  the compiler that the method has no effect except the return value
111 *  and that the return value depends only the value of parameters.
112 */
113#ifdef __GNUC__
114  #define RTEMS_CONST __attribute__((__const__))
115#else
116  #define RTEMS_CONST
117#endif
118
119/**
120 *  The following defines a compiler specific attribute which informs
121 *  the compiler that the method has no effect except the return value
122 *  and that the return value depends only on parameters and/or global
123 *  variables.
124 */
125#ifdef __GNUC__
126  #define RTEMS_PURE __attribute__((__pure__))
127#else
128  #define RTEMS_PURE
129#endif
130
131/* Provided for backward compatibility */
132#define RTEMS_COMPILER_PURE_ATTRIBUTE RTEMS_PURE
133
134/**
135 *  Instructs the compiler to issue a warning whenever a variable or function
136 *  with this attribute will be used.
137 */
138#ifdef __GNUC__
139  #define RTEMS_DEPRECATED __attribute__((__deprecated__))
140#else
141  #define RTEMS_DEPRECATED
142#endif
143
144/* Provided for backward compatibility */
145#define RTEMS_COMPILER_DEPRECATED_ATTRIBUTE RTEMS_DEPRECATED
146
147/**
148 * @brief Instructs the compiler to place a specific variable or function in
149 * the specified section.
150 */
151#if defined(__GNUC__)
152  #define RTEMS_SECTION( _section ) __attribute__((__section__(_section)))
153#else
154  #define RTEMS_SECTION( _section )
155#endif
156
157/**
158 * @brief Instructs the compiler that a specific variable or function is used.
159 */
160#if defined(__GNUC__)
161  #define RTEMS_USED __attribute__((__used__))
162#else
163  #define RTEMS_USED
164#endif
165
166/**
167 *  Instructs the compiler that a specific variable is deliberately unused.
168 *  This can occur when reading volatile device memory or skipping arguments
169 *  in a variable argument method.
170 */
171#if defined(__GNUC__)
172  #define RTEMS_UNUSED __attribute__((__unused__))
173#else
174  #define RTEMS_UNUSED
175#endif
176
177/* Provided for backward compatibility */
178#define RTEMS_COMPILER_UNUSED_ATTRIBUTE RTEMS_UNUSED
179
180/**
181 *  Instructs the compiler that a specific structure or union members will be
182 *  placed so that the least memory is used.
183 */
184#if defined(__GNUC__)
185  #define RTEMS_PACKED __attribute__((__packed__))
186#else
187  #define RTEMS_PACKED
188#endif
189
190/**
191 * @brief Instructs the compiler to generate an alias to the specified target
192 * function.
193 */
194#if defined(__GNUC__)
195  #define RTEMS_ALIAS( _target ) __attribute__((__alias__(#_target)))
196#else
197  #define RTEMS_ALIAS( _target )
198#endif
199
200/**
201 * @brief Instructs the compiler to generate a weak alias to the specified
202 * target function.
203 */
204#if defined(__GNUC__)
205  #define RTEMS_WEAK_ALIAS( _target ) __attribute__((__weak__, __alias__(#_target)))
206#else
207  #define RTEMS_WEAK_ALIAS( _target )
208#endif
209
210/**
211 * @brief Instructs the compiler to enforce the specified alignment.
212 */
213#if defined(__GNUC__)
214  #define RTEMS_ALIGNED( _alignment ) __attribute__((__aligned__(_alignment)))
215#else
216  #define RTEMS_ALIGNED( _alignment )
217#endif
218
219/* Provided for backward compatibility */
220#define RTEMS_COMPILER_PACKED_ATTRIBUTE RTEMS_PACKED
221
222#if defined(RTEMS_DEBUG) && !defined(RTEMS_SCHEDSIM)
223  #define _Assert_Unreachable() _Assert( 0 )
224#else
225  #define _Assert_Unreachable() do { } while ( 0 )
226#endif
227
228/**
229 * @brief Tells the compiler that this program point is unreachable.
230 */
231#if defined(__GNUC__) && !defined(RTEMS_SCHEDSIM)
232  #define RTEMS_UNREACHABLE() \
233    do { \
234      __builtin_unreachable(); \
235      _Assert_Unreachable(); \
236    } while ( 0 )
237#else
238  #define RTEMS_UNREACHABLE() _Assert_Unreachable()
239#endif
240
241/**
242 * @brief Tells the compiler that this function expects printf()-like
243 * arguments.
244 */
245#if defined(__GNUC__)
246  #define RTEMS_PRINTFLIKE( _format_pos, _ap_pos ) \
247    __attribute__((__format__(__printf__, _format_pos, _ap_pos)))
248#else
249  #define RTEMS_PRINTFLIKE( _format_pos, _ap_pos )
250#endif
251
252/**
253 * @brief Tells the compiler that this function is a memory allocation function
254 * similar to malloc().
255 */
256#if defined(__GNUC__)
257  #define RTEMS_MALLOCLIKE __attribute__((__malloc__))
258#else
259  #define RTEMS_MALLOCLIKE
260#endif
261
262/**
263 * @brief Tells the compiler the memory allocation size parameter of this
264 * function similar to malloc().
265 */
266#if defined(__GNUC__)
267  #define RTEMS_ALLOC_SIZE( _index ) __attribute__((__alloc_size__(_index)))
268#else
269  #define RTEMS_ALLOC_SIZE( _index )
270#endif
271
272/**
273 * @brief Tells the compiler the memory allocation item count and item size
274 * parameter of this function similar to calloc().
275 */
276#if defined(__GNUC__)
277  #define RTEMS_ALLOC_SIZE_2( _count_index, _size_index ) \
278     __attribute__((__alloc_size__(_count_index, _size_index)))
279#else
280  #define RTEMS_ALLOC_SIZE_2( _count_index, _size_index )
281#endif
282
283/**
284 * @brief Tells the compiler the memory allocation alignment parameter of this
285 * function similar to aligned_alloc().
286 */
287#if defined(__GNUC__)
288  #define RTEMS_ALLOC_ALIGN( _index ) __attribute__((__alloc_align__(_index)))
289#else
290  #define RTEMS_ALLOC_ALIGN( _index )
291#endif
292
293/**
294 * @brief Tells the compiler that the result of this function should be used.
295 */
296#if defined(__GNUC__)
297  #define RTEMS_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
298#else
299  #define RTEMS_WARN_UNUSED_RESULT
300#endif
301
302/**
303 * @brief Obfuscates the variable so that the compiler cannot perform
304 * optimizations based on the variable value.
305 *
306 * The variable must be simple enough to fit into a register.
307 */
308#if defined(__GNUC__)
309  #define RTEMS_OBFUSCATE_VARIABLE( _var ) __asm__("" : "+r" (_var))
310#else
311  #define RTEMS_OBFUSCATE_VARIABLE( _var ) (void) (_var)
312#endif
313
314/**
315 * @brief Declares a global symbol with the specified name.
316 *
317 * This macro must be placed at file scope.
318 *
319 * The name must be a valid designator.
320 */
321#define RTEMS_DECLARE_GLOBAL_SYMBOL( _name ) \
322  extern char _name[]
323
324/**
325 * @brief Constructs a symbol name.
326 *
327 * @param _name The user defined name of the symbol.  The name shall be a valid
328 *   designator.  On the name a macro expansion is performed.
329 */
330#if defined(__USER_LABEL_PREFIX__)
331  #define RTEMS_SYMBOL_NAME( _name ) \
332    RTEMS_XCONCAT( __USER_LABEL_PREFIX__, _name )
333#else
334  /* Helper to perform the macro expansion */
335  #define _RTEMS_SYMBOL_NAME( _name ) _name
336
337  #define RTEMS_SYMBOL_NAME( _name ) _RTEMS_SYMBOL_NAME( _name )
338#endif
339
340/**
341 * @brief Defines a global symbol with the specified name and value.
342 *
343 * This macro shall be placed at file scope.
344 *
345 * @param _name The user defined name of the symbol.  The name shall be a valid
346 *   designator.  On the name a macro expansion is performed and afterwards it
347 *   is stringified.
348 * @param _value The value of the symbol.  On the value a macro expansion is
349 *   performed and afterwards it is stringified.  It shall expand to an integer
350 *   expression understood by the assembler.
351 */
352#if defined(__GNUC__)
353  #define RTEMS_DEFINE_GLOBAL_SYMBOL( _name, _value ) \
354    __asm__( \
355      "\t.globl " RTEMS_XSTRING( RTEMS_SYMBOL_NAME( _name ) ) \
356      "\n\t.set " RTEMS_XSTRING( RTEMS_SYMBOL_NAME( _name ) ) \
357      ", " RTEMS_STRING( _value ) "\n" \
358    )
359#else
360  #define RTEMS_DEFINE_GLOBAL_SYMBOL( _name, _value )
361#endif
362
363/**
364 * @brief Defines a global symbol with the specified name in the specified
365 * section.
366 *
367 * The name must be a valid designator.  The alignment of the symbol depends on
368 * the current location counter of the section.
369 */
370#if defined(__GNUC__)
371  #define RTEMS_DEFINE_GLOBAL_SYMBOL_IN_SECTION( _name, _section ) \
372    __asm__( \
373      ".pushsection \"" _section "\"\n" \
374      "\t.globl " \
375      RTEMS_XSTRING( RTEMS_SYMBOL_NAME( _name ) ) "\n" \
376      RTEMS_XSTRING( RTEMS_SYMBOL_NAME( _name ) ) ":\n" \
377      "\t.popsection\n" \
378    )
379#else
380  #define RTEMS_DEFINE_GLOBAL_SYMBOL_IN_SECTION( _name, section )
381#endif
382
383/**
384 * @brief Returns the value of the specified integral expression and tells the
385 * compiler that the predicted value is true (1).
386 *
387 * @param[in] _exp The expression.
388 *
389 * @return The value of the expression.
390 */
391#if defined(__GNUC__)
392  #define RTEMS_PREDICT_TRUE( _exp ) __builtin_expect( ( _exp ), 1 )
393#else
394  #define RTEMS_PREDICT_TRUE( _exp ) ( _exp )
395#endif
396
397/**
398 * @brief Returns the value of the specified integral expression and tells the
399 * compiler that the predicted value is false (0).
400 *
401 * @param[in] _exp The expression.
402 *
403 * @return The value of the expression.
404 */
405#if defined(__GNUC__)
406  #define RTEMS_PREDICT_FALSE( _exp ) __builtin_expect( ( _exp ), 0 )
407#else
408  #define RTEMS_PREDICT_FALSE( _exp ) ( _exp )
409#endif
410
411/**
412 * @brief Returns the return address of the current function.
413 *
414 * @return The return address.
415 */
416#if defined(__GNUC__)
417  #define RTEMS_RETURN_ADDRESS() __builtin_return_address( 0 )
418#else
419  #define RTEMS_RETURN_ADDRESS() NULL
420#endif
421
422#if __cplusplus >= 201103L
423  #define RTEMS_STATIC_ASSERT(cond, msg) \
424    static_assert(cond, # msg)
425#elif __STDC_VERSION__ >= 201112L
426  #define RTEMS_STATIC_ASSERT(cond, msg) \
427    _Static_assert(cond, # msg)
428#else
429  #define RTEMS_STATIC_ASSERT(cond, msg) \
430    struct rtems_static_assert_ ## msg \
431      { int rtems_static_assert_ ## msg : (cond) ? 1 : -1; }
432#endif
433
434#define RTEMS_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
435
436/*
437 * Zero-length arrays are valid in C99 as flexible array members.  C++11
438 * doesn't allow flexible array members.  Use the GNU extension which is also
439 * supported by other compilers.
440 */
441#define RTEMS_ZERO_LENGTH_ARRAY 0
442
443/**
444 * @brief Returns a pointer to the container of a specified member pointer.
445 *
446 * @param[in] _m The pointer to a member of the container.
447 * @param[in] _type The type of the container.
448 * @param[in] _member_name The designator name of the container member.
449 */
450#define RTEMS_CONTAINER_OF( _m, _type, _member_name ) \
451  ( (_type *) ( (uintptr_t) ( _m ) - offsetof( _type, _member_name ) ) )
452
453#ifdef __cplusplus
454#define RTEMS_DEQUALIFY_DEPTHX( _ptr_level, _type, _var ) \
455            (const_cast<_type>( _var ))
456#else /* Standard C code */
457
458/* The reference type idea based on libHX by Jan Engelhardt */
459#define RTEMS_TYPEOF_REFX(_ptr_level, _ptr_type) \
460  __typeof__(_ptr_level(union { int z; __typeof__(_ptr_type) x; }){0}.x)
461
462#if defined(__GNUC__) && !defined(ASM)
463#if  ((__GNUC__ * 1000 + __GNUC_MINOR__) >= 4004)
464extern void* RTEMS_DEQUALIFY_types_not_compatible(void)
465  __attribute__((error ("RTEMS_DEQUALIFY types differ not only by volatile and const")));
466#else
467extern void RTEMS_DEQUALIFY_types_not_compatible(void);
468#endif
469#define RTEMS_DEQUALIFY_DEPTHX( _ptr_level, _type, _var ) ( \
470    __builtin_choose_expr( __builtin_types_compatible_p ( \
471        RTEMS_TYPEOF_REFX( _ptr_level, _var ), \
472        RTEMS_TYPEOF_REFX( _ptr_level, _type ) \
473      ) || __builtin_types_compatible_p ( _type, void * ), \
474    (_type)(_var), \
475    RTEMS_DEQUALIFY_types_not_compatible() \
476  ) \
477)
478#endif /*__GNUC__*/
479#endif /*__cplusplus*/
480
481#ifndef RTEMS_DECONST
482#ifdef RTEMS_DEQUALIFY_DEPTHX
483#define RTEMS_DECONST( _type, _var ) \
484  RTEMS_DEQUALIFY_DEPTHX( *, _type, _var )
485#else /*RTEMS_DEQUALIFY_DEPTHX*/
486/**
487 * @brief Removes the const qualifier from a type of a variable.
488 *
489 * @param[in] _type The target type for the variable.
490 * @param[in] _var The variable.
491 */
492#define RTEMS_DECONST( _type, _var ) \
493  ((_type)(uintptr_t)(const void *) ( _var ))
494
495#endif /*RTEMS_DEQUALIFY_DEPTHX*/
496#endif /*RTEMS_DECONST*/
497
498#ifndef RTEMS_DEVOLATILE
499#ifdef RTEMS_DEQUALIFY_DEPTHX
500#define RTEMS_DEVOLATILE( _type, _var ) \
501  RTEMS_DEQUALIFY_DEPTHX( *, _type, _var )
502#else /*RTEMS_DEQUALIFY_DEPTHX*/
503/**
504 * @brief Removes the volatile qualifier from a type of a variable.
505 *
506 * @param[in] _type The target type for the variable.
507 * @param[in] _var The variable.
508 */
509#define RTEMS_DEVOLATILE( _type, _var ) \
510  ((_type)(uintptr_t)(volatile void *) ( _var ))
511
512#endif /*RTEMS_DEQUALIFY_DEPTHX*/
513#endif /*RTEMS_DEVOLATILE*/
514
515#ifndef RTEMS_DEQUALIFY
516#ifdef RTEMS_DEQUALIFY_DEPTHX
517#define RTEMS_DEQUALIFY( _type, _var ) \
518  RTEMS_DEQUALIFY_DEPTHX( *, _type, _var )
519#else /*RTEMS_DEQUALIFY_DEPTHX*/
520/**
521 * @brief Removes the all qualifiers from a type of a variable.
522 *
523 * @param[in] _type The target type for the variable.
524 * @param[in] _var The variable.
525 */
526#define RTEMS_DEQUALIFY( _type, _var ) \
527  ((_type)(uintptr_t)(const volatile void *) ( _var ))
528
529#endif /*RTEMS_DEQUALIFY_DEPTHX*/
530#endif /*RTEMS_DEQUALIFY*/
531
532/**
533 * @brief Evaluates to true if the members of two types have the same type.
534 *
535 * @param[in] _t_lhs Left hand side type.
536 * @param[in] _m_lhs Left hand side member.
537 * @param[in] _t_rhs Right hand side type.
538 * @param[in] _m_rhs Right hand side member.
539 */
540#ifdef __GNUC__
541  #define RTEMS_HAVE_MEMBER_SAME_TYPE( _t_lhs, _m_lhs, _t_rhs, _m_rhs ) \
542    __builtin_types_compatible_p( \
543      __typeof__( ( (_t_lhs *) 0 )->_m_lhs ), \
544      __typeof__( ( (_t_rhs *) 0 )->_m_rhs ) \
545    )
546#else
547  #define RTEMS_HAVE_MEMBER_SAME_TYPE( _t_lhs, _m_lhs, _t_rhs, _m_rhs ) \
548    true
549#endif
550
551/**
552 * @brief Concatenates _x and _y without expanding.
553 */
554#define RTEMS_CONCAT( _x, _y ) _x##_y
555
556/**
557 * @brief Concatenates expansion of _x and expansion of _y.
558 */
559#define RTEMS_XCONCAT( _x, _y ) RTEMS_CONCAT( _x, _y )
560
561/**
562 * @brief Stringifies _x  without expanding.
563 */
564#define RTEMS_STRING( _x ) #_x
565
566/**
567 * @brief Stringifies expansion of _x.
568 */
569#define RTEMS_XSTRING( _x ) RTEMS_STRING( _x )
570
571#ifndef ASM
572  #ifdef RTEMS_DEPRECATED_TYPES
573    typedef bool boolean RTEMS_DEPRECATED;
574    typedef float single_precision RTEMS_DEPRECATED;
575    typedef double double_precision RTEMS_DEPRECATED;
576  #endif
577
578  /**
579   * XXX: Eventually proc_ptr needs to disappear!!!
580   */
581  typedef void * proc_ptr RTEMS_DEPRECATED;
582#endif
583
584/** @} */
585
586#endif /* _RTEMS_BASEDEFS_H */
Note: See TracBrowser for help on using the repository browser.