1 #ifndef __LINUX_COMPILER_H
2 #define __LINUX_COMPILER_H
3 
4 #if CONFIG_CC_IS_GCC
5 
6 # if defined(CONFIG_RISCV) && CONFIG_GCC_VERSION < 120200
7 #  error Sorry, please use GCC >= 12.2
8 # elif CONFIG_GCC_VERSION < 50100
9 #  error Sorry, please use GCC >= 5.1
10 # endif
11 
12 #elif CONFIG_CC_IS_CLANG
13 
14 # if CONFIG_CLANG_VERSION < 110000
15 #  error Sorry, please use Clang >= 11
16 # endif
17 
18 #endif /* Compiler checks. */
19 
20 /* Results in more efficient PIC code (no indirections through GOT or PLT). */
21 #pragma GCC visibility push(hidden)
22 
23 #define barrier()     __asm__ __volatile__("": : :"memory")
24 
25 #define likely(x)     __builtin_expect(!!(x),1)
26 #define unlikely(x)   __builtin_expect(!!(x),0)
27 
28 #define always_inline inline __attribute__((__always_inline__))
29 #define gnu_inline    inline __attribute__((__gnu_inline__))
30 #define noinline      __attribute__((__noinline__))
31 
32 #define noreturn      __attribute__((__noreturn__))
33 
34 #define __packed      __attribute__((__packed__))
35 
36 #define __weak        __attribute__((__weak__))
37 
38 #if !defined(CONFIG_CC_IS_CLANG) || CONFIG_CLANG_VERSION >= 140000
39 # define nocall       __attribute__((__error__("Nonstandard ABI")))
40 #else
41 # define nocall
42 #endif
43 
44 #ifdef CONFIG_XEN_IBT
45 # define cf_check     __attribute__((__cf_check__))
46 #else
47 # define cf_check
48 #endif
49 
50 #define unreachable() __builtin_unreachable()
51 
52 /*
53  * Compilers estimate the size of an asm() block for inlining purposes.
54  *
55  * Constructs with embedded metadata (BUG_FRAME, ALTERNATIVE, EXTABLE, etc)
56  * appear large, depsite typically only being a handful of instructions.  asm
57  * inline() overrides the estimation to identify the block as being small.
58  *
59  * Note: __inline is needed to avoid getting caught up in INIT_SECTIONS_ONLY.
60  */
61 #if CONFIG_CC_HAS_ASM_INLINE
62 # define asm_inline asm __inline
63 #else
64 # define asm_inline asm
65 #endif
66 
67 /*
68  * Add the pseudo keyword 'fallthrough' so case statement blocks
69  * must end with any of these keywords:
70  *   break;
71  *   fallthrough;
72  *   goto <label>;
73  *   return [expression];
74  *
75  *  gcc: https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#Statement-Attributes
76  */
77 #if (!defined(__clang__) && (__GNUC__ >= 7))
78 # define fallthrough        __attribute__((__fallthrough__))
79 #else
80 # define fallthrough        do {} while (0)  /* fallthrough */
81 #endif
82 
83 #ifdef __clang__
84 /* Clang can replace some vars with new automatic ones that go in .data;
85  * mark all explicit-segment vars 'used' to prevent that. */
86 #define __section(s)      __used __attribute__((__section__(s)))
87 #else
88 #define __section(s)      __attribute__((__section__(s)))
89 #endif
90 #define __used_section(s) __used __attribute__((__section__(s)))
91 #define __text_section(s) __attribute__((__section__(s)))
92 
93 #define __aligned(a) __attribute__((__aligned__(a)))
94 
95 #ifdef INIT_SECTIONS_ONLY
96 /*
97  * For sources indicated to have only init code, make sure even
98  * inline functions not expanded inline get placed in .init.text.
99  */
100 #include <xen/init.h>
101 /* SAF-3-safe MISRA C Rule 20.4: allow section checks to pass when not inlined */
102 #define inline inline __init
103 #endif
104 
105 #define __constructor       __attribute__((__constructor__)) cf_check
106 #define __pure              __attribute__((__pure__))
107 #define attr_const          __attribute__((__const__))
108 #define __transparent__     __attribute__((__transparent_union__))
109 
110 /*
111  * The difference between the following two attributes is that __used is
112  * intended to be used in cases where a reference to an identifier may be
113  * invisible to the compiler (e.g. an inline assembly operand not listed
114  * in the asm()'s operands), preventing the compiler from eliminating the
115  * variable or function.
116  * __maybe_unused otoh is to be used to merely prevent warnings (e.g. when
117  * an identifier is used only inside a preprocessor conditional, yet putting
118  * its declaration/definition inside another conditional would harm code
119  * readability).
120  */
121 #define __used         __attribute__((__used__))
122 #define __maybe_unused __attribute__((__unused__))
123 
124 #define __must_check __attribute__((__warn_unused_result__))
125 #define __nonnull(...) __attribute__((__nonnull__(__VA_ARGS__)))
126 
127 #define offsetof(a,b) __builtin_offsetof(a,b)
128 
129 #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L
130 #define alignof __alignof__
131 #endif
132 
133 /* &a[0] degrades to a pointer: a different type from an array */
134 #define __must_be_array(a) \
135   BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&(a)[0])))
136 
137 /* Make the optimizer believe the variable can be manipulated arbitrarily. */
138 #define OPTIMIZER_HIDE_VAR(var) __asm__ ( "" : "+g" (var) )
139 
140 /* This macro obfuscates arithmetic on a variable address so that gcc
141    shouldn't recognize the original var, and make assumptions about it */
142 /*
143  * Versions of the ppc64 compiler before 4.1 had a bug where use of
144  * RELOC_HIDE could trash r30. The bug can be worked around by changing
145  * the inline assembly constraint from =g to =r, in this particular
146  * case either is valid.
147  */
148 #define RELOC_HIDE(ptr, off)                    \
149   ({ unsigned long __ptr;                       \
150     __asm__ ("" : "=r"(__ptr) : "0"(ptr));      \
151     (typeof(ptr)) (__ptr + (off)); })
152 
153 /* See gcc bug 100680. */
154 #if CONFIG_GCC_VERSION >= 110000 && CONFIG_GCC_VERSION < 110300
155 # define gcc11_wrap(x) RELOC_HIDE(x, 0)
156 #else
157 # define gcc11_wrap(x) (x)
158 #endif
159 
160 #ifdef __GCC_ASM_FLAG_OUTPUTS__
161 # define ASM_FLAG_OUT(yes, no) yes
162 #else
163 # define ASM_FLAG_OUT(yes, no) no
164 #endif
165 
166 /* Mark a function or variable as being used only to interface with asm */
167 #ifndef asmlinkage
168 #define asmlinkage
169 #endif
170 
171 /*
172  * NB: we need to disable the gcc-compat warnings for clang in some places or
173  * else it will complain with: "'break' is bound to loop, GCC binds it to
174  * switch" when a switch is used inside of a while expression inside of a
175  * switch statement, ie:
176  *
177  * switch ( ... )
178  * {
179  * case ...:
180  *      while ( ({ int x; switch ( foo ) { case 1: x = 1; break; } x }) )
181  *      {
182  *              ...
183  *
184  * This has already been reported upstream:
185  * http://bugs.llvm.org/show_bug.cgi?id=32595
186  */
187 #ifdef __clang__
188 # define CLANG_DISABLE_WARN_GCC_COMPAT_START                    \
189     _Pragma("clang diagnostic push")                            \
190     _Pragma("clang diagnostic ignored \"-Wgcc-compat\"")
191 # define CLANG_DISABLE_WARN_GCC_COMPAT_END                      \
192     _Pragma("clang diagnostic pop")
193 #else
194 # define CLANG_DISABLE_WARN_GCC_COMPAT_START
195 # define CLANG_DISABLE_WARN_GCC_COMPAT_END
196 #endif
197 
198 #endif /* __LINUX_COMPILER_H */
199