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 #endif 7 8 #define barrier() __asm__ __volatile__("": : :"memory") 9 10 #define likely(x) __builtin_expect(!!(x),1) 11 #define unlikely(x) __builtin_expect(!!(x),0) 12 13 #define inline __inline__ 14 #define always_inline __inline__ __attribute__ ((__always_inline__)) 15 #define noinline __attribute__((__noinline__)) 16 17 #define noreturn __attribute__((__noreturn__)) 18 19 #define __packed __attribute__((__packed__)) 20 21 #if (!defined(__clang__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 5)) 22 #define unreachable() do {} while (1) 23 #else 24 #define unreachable() __builtin_unreachable() 25 #endif 26 27 #ifdef __clang__ 28 /* Clang can replace some vars with new automatic ones that go in .data; 29 * mark all explicit-segment vars 'used' to prevent that. */ 30 #define __section(s) __used __attribute__((__section__(s))) 31 #else 32 #define __section(s) __attribute__((__section__(s))) 33 #endif 34 #define __used_section(s) __used __attribute__((__section__(s))) 35 #define __text_section(s) __attribute__((__section__(s))) 36 37 #define __aligned(a) __attribute__((__aligned__(a))) 38 39 #ifdef INIT_SECTIONS_ONLY 40 /* 41 * For sources indicated to have only init code, make sure even 42 * inline functions not expanded inline get placed in .init.text. 43 */ 44 #include <xen/init.h> 45 #define __inline__ __inline__ __init 46 #endif 47 48 #define __attribute_pure__ __attribute__((__pure__)) 49 #define __attribute_const__ __attribute__((__const__)) 50 #define __transparent__ __attribute__((__transparent_union__)) 51 52 /* 53 * The difference between the following two attributes is that __used is 54 * intended to be used in cases where a reference to an identifier may be 55 * invisible to the compiler (e.g. an inline assembly operand not listed 56 * in the asm()'s operands), preventing the compiler from eliminating the 57 * variable or function. 58 * __maybe_unused otoh is to be used to merely prevent warnings (e.g. when 59 * an identifier is used only inside a preprocessor conditional, yet putting 60 * its declaration/definition inside another conditional would harm code 61 * readability). 62 */ 63 #define __used __attribute__((__used__)) 64 #define __maybe_unused __attribute__((__unused__)) 65 66 #define __must_check __attribute__((__warn_unused_result__)) 67 #define __nonnull(...) __attribute__((__nonnull__(__VA_ARGS__))) 68 69 #define offsetof(a,b) __builtin_offsetof(a,b) 70 71 #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L 72 #define alignof __alignof__ 73 #endif 74 75 /* &a[0] degrades to a pointer: a different type from an array */ 76 #define __must_be_array(a) \ 77 BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0]))) 78 79 #ifdef GCC_HAS_VISIBILITY_ATTRIBUTE 80 /* Results in more efficient PIC code (no indirections through GOT or PLT). */ 81 #pragma GCC visibility push(hidden) 82 #endif 83 84 /* This macro obfuscates arithmetic on a variable address so that gcc 85 shouldn't recognize the original var, and make assumptions about it */ 86 /* 87 * Versions of the ppc64 compiler before 4.1 had a bug where use of 88 * RELOC_HIDE could trash r30. The bug can be worked around by changing 89 * the inline assembly constraint from =g to =r, in this particular 90 * case either is valid. 91 */ 92 #define RELOC_HIDE(ptr, off) \ 93 ({ unsigned long __ptr; \ 94 __asm__ ("" : "=r"(__ptr) : "0"(ptr)); \ 95 (typeof(ptr)) (__ptr + (off)); }) 96 97 #ifdef __GCC_ASM_FLAG_OUTPUTS__ 98 # define ASM_FLAG_OUT(yes, no) yes 99 #else 100 # define ASM_FLAG_OUT(yes, no) no 101 #endif 102 103 /* 104 * NB: we need to disable the gcc-compat warnings for clang in some places or 105 * else it will complain with: "'break' is bound to loop, GCC binds it to 106 * switch" when a switch is used inside of a while expression inside of a 107 * switch statement, ie: 108 * 109 * switch ( ... ) 110 * { 111 * case ...: 112 * while ( ({ int x; switch ( foo ) { case 1: x = 1; break; } x }) ) 113 * { 114 * ... 115 * 116 * This has already been reported upstream: 117 * http://bugs.llvm.org/show_bug.cgi?id=32595 118 */ 119 #ifdef __clang__ 120 # define CLANG_DISABLE_WARN_GCC_COMPAT_START \ 121 _Pragma("clang diagnostic push") \ 122 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") 123 # define CLANG_DISABLE_WARN_GCC_COMPAT_END \ 124 _Pragma("clang diagnostic pop") 125 #else 126 # define CLANG_DISABLE_WARN_GCC_COMPAT_START 127 # define CLANG_DISABLE_WARN_GCC_COMPAT_END 128 #endif 129 130 #endif /* __LINUX_COMPILER_H */ 131