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