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