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