1 /*
2  * Copyright (c) 2010-2014 Wind River Systems, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_COMMON_H_
8 #define ZEPHYR_INCLUDE_TOOLCHAIN_COMMON_H_
9 
10 #include <misc/__assert.h>
11 /**
12  * @file
13  * @brief Common toolchain abstraction
14  *
15  * Macros to abstract compiler capabilities (common to all toolchains).
16  */
17 
18 /* Abstract use of extern keyword for compatibility between C and C++ */
19 #ifdef __cplusplus
20 #define EXTERN_C extern "C"
21 #else
22 #define EXTERN_C extern
23 #endif
24 
25 /* Use TASK_ENTRY_CPP to tag task entry points defined in C++ files. */
26 
27 #ifdef __cplusplus
28 #define TASK_ENTRY_CPP  extern "C"
29 #endif
30 
31 /*
32  * Generate a reference to an external symbol.
33  * The reference indicates to the linker that the symbol is required
34  * by the module containing the reference and should be included
35  * in the image if the module is in the image.
36  *
37  * The assembler directive ".set" is used to define a local symbol.
38  * No memory is allocated, and the local symbol does not appear in
39  * the symbol table.
40  */
41 
42 #ifdef _ASMLANGUAGE
43   #define REQUIRES(sym) .set sym ## _Requires, sym
44 #else
45   #define REQUIRES(sym) __asm__ (".set " # sym "_Requires, " # sym "\n\t");
46 #endif
47 
48 #ifdef _ASMLANGUAGE
49   #define SECTION .section
50 #endif
51 
52 /*
53  * If the project is being built for speed (i.e. not for minimum size) then
54  * align functions and branches in executable sections to improve performance.
55  */
56 
57 #ifdef _ASMLANGUAGE
58 
59   #if defined(CONFIG_X86)
60 
61     #ifdef PERF_OPT
62       #define PERFOPT_ALIGN .balign 16
63     #else
64       #define PERFOPT_ALIGN .balign  1
65     #endif
66 
67   #elif defined(CONFIG_ARM)
68 
69     #define PERFOPT_ALIGN .balign  4
70 
71   #elif defined(CONFIG_ARC)
72 
73     #define PERFOPT_ALIGN .balign  4
74 
75   #elif defined(CONFIG_NIOS2) || defined(CONFIG_RISCV) || \
76 	  defined(CONFIG_XTENSA)
77     #define PERFOPT_ALIGN .balign 4
78 
79   #elif defined(CONFIG_ARCH_POSIX)
80 
81   #else
82 
83     #error Architecture unsupported
84 
85   #endif
86 
87   #define GC_SECTION(sym) SECTION .text.##sym, "ax"
88 
89 #endif /* _ASMLANGUAGE */
90 
91 /* force inlining a function */
92 
93 #if !defined(_ASMLANGUAGE)
94   #ifdef CONFIG_COVERAGE
95     /*
96      * The always_inline attribute forces a function to be inlined,
97      * even ignoring -fno-inline. So for code coverage, do not
98      * force inlining of these functions to keep their bodies around
99      * so their number of executions can be counted.
100      *
101      * Note that "inline" is kept here for kobject_hash.c and
102      * priv_stacks_hash.c. These are built without compiler flags
103      * used for coverage. ALWAYS_INLINE cannot be empty as compiler
104      * would complain about unused functions. Attaching unused
105      * attribute would result in their text sections ballon more than
106      * 10 times in size, as those functions are kept in text section.
107      * So just keep "inline" here.
108      */
109     #define ALWAYS_INLINE inline
110   #else
111     #define ALWAYS_INLINE inline __attribute__((always_inline))
112   #endif
113 #endif
114 
115 #define Z_STRINGIFY(x) #x
116 #define STRINGIFY(s) Z_STRINGIFY(s)
117 
118 /* concatenate the values of the arguments into one */
119 #define _DO_CONCAT(x, y) x ## y
120 #define _CONCAT(x, y) _DO_CONCAT(x, y)
121 
122 /* Additionally used as a sentinel by gen_syscalls.py to identify what
123  * functions are system calls
124  *
125  * Note POSIX unit tests don't still generate the system call stubs, so
126  * until https://github.com/zephyrproject-rtos/zephyr/issues/5006 is
127  * fixed via possibly #4174, we introduce this hack -- which will
128  * disallow us to test system calls in POSIX unit testing (currently
129  * not used).
130  */
131 #ifndef ZTEST_UNITTEST
132 #define __syscall static inline
133 #else
134 #define __syscall
135 #endif /* #ifndef ZTEST_UNITTEST */
136 
137 /* Definitions for struct declaration tags. These are sentinel values used by
138  * parse_syscalls.py to gather a list of names of struct declarations that
139  * have these tags applied for them.
140  */
141 
142 /* Indicates this is a driver subsystem */
143 #define __subsystem
144 
145 /* Indicates this is a network socket object */
146 #define __net_socket
147 
148 #ifndef BUILD_ASSERT
149 /* Compile-time assertion that makes the build to fail.
150  * Common implementation swallows the message.
151  */
152 #define BUILD_ASSERT(EXPR, MSG...) \
153 	enum _CONCAT(__build_assert_enum, __COUNTER__) { \
154 		_CONCAT(__build_assert, __COUNTER__) = 1 / !!(EXPR) \
155 	}
156 #endif
157 
158 #ifndef BUILD_ASSERT_MSG
159 #define BUILD_ASSERT_MSG(EXPR, MSG) __DEPRECATED_MACRO BUILD_ASSERT(EXPR, MSG)
160 #endif
161 
162 /*
163  * This is meant to be used in conjunction with __in_section() and similar
164  * where scattered structure instances are concatened together by the linker
165  * and walked by the code at run time just like a contiguous array of such
166  * structures.
167  *
168  * Assemblers and linkers may insert alignment padding by default whose
169  * size is larger than the natural alignment for those structures when
170  * gathering various section segments together, messing up the array walk.
171  * To prevent this, we need to provide an explicit alignment not to rely
172  * on the default that might just work by luck.
173  *
174  * Alignment statements in  linker scripts are not sufficient as
175  * the assembler may add padding by itself to each segment when switching
176  * between sections within the same file even if it merges many such segments
177  * into a single section in the end.
178  */
179 #define Z_DECL_ALIGN(type) __aligned(__alignof(type)) type
180 
181 /*
182  * Convenience helper combining __in_section() and Z_DECL_ALIGN().
183  * The section name is the struct type prepended with an underscore.
184  * The subsection is "static" and the subsubsection is the variable name.
185  */
186 #define Z_STRUCT_SECTION_ITERABLE(struct_type, name) \
187 	Z_DECL_ALIGN(struct struct_type) name \
188 	__in_section(_##struct_type, static, name) // __used
189 
190 /*
191  * Itterator for structure instances gathered by Z_STRUCT_SECTION_ITERABLE().
192  * The linker must provide a _<struct_type>_list_start symbol and a
193  * _<struct_type>_list_end symbol to mark the start and the end of the
194  * list of struct objects to iterate over.
195  */
196 #define Z_STRUCT_SECTION_FOREACH(struct_type, iterator) \
197 	extern struct struct_type _CONCAT(_##struct_type, _list_start)[]; \
198 	extern struct struct_type _CONCAT(_##struct_type, _list_end)[]; \
199 	for (struct struct_type *iterator = \
200 			_CONCAT(_##struct_type, _list_start); \
201 	     ({ __ASSERT(iterator <= _CONCAT(_##struct_type, _list_end), \
202 			 "unexpected list end location"); \
203 		iterator < _CONCAT(_##struct_type, _list_end); }); \
204 	     iterator++)
205 
206 #endif /* ZEPHYR_INCLUDE_TOOLCHAIN_COMMON_H_ */
207