]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
8a625c1f NK |
2 | #ifndef _TOOLS_LINUX_COMPILER_H_ |
3 | #define _TOOLS_LINUX_COMPILER_H_ | |
5a116dd2 | 4 | |
19261401 ACM |
5 | #ifdef __GNUC__ |
6 | #include <linux/compiler-gcc.h> | |
7 | #endif | |
8 | ||
49006538 ACM |
9 | #ifndef __compiletime_error |
10 | # define __compiletime_error(message) | |
11 | #endif | |
12 | ||
5ac69737 ACM |
13 | /* Optimization barrier */ |
14 | /* The "volatile" is due to gcc bugs */ | |
15 | #define barrier() __asm__ __volatile__("": : :"memory") | |
16 | ||
5a116dd2 | 17 | #ifndef __always_inline |
7a10822a | 18 | # define __always_inline inline __attribute__((always_inline)) |
5a116dd2 | 19 | #endif |
7a10822a | 20 | |
9dd4ca47 ACM |
21 | #ifndef noinline |
22 | #define noinline | |
23 | #endif | |
24 | ||
f6441aff ACM |
25 | /* Are two types/vars the same type (ignoring qualifiers)? */ |
26 | #ifndef __same_type | |
27 | # define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) | |
28 | #endif | |
29 | ||
8c98abff ACM |
30 | #ifdef __ANDROID__ |
31 | /* | |
32 | * FIXME: Big hammer to get rid of tons of: | |
33 | * "warning: always_inline function might not be inlinable" | |
34 | * | |
35 | * At least on android-ndk-r12/platforms/android-24/arch-arm | |
36 | */ | |
37 | #undef __always_inline | |
38 | #define __always_inline inline | |
39 | #endif | |
40 | ||
5a116dd2 | 41 | #define __user |
12ea6539 MW |
42 | #define __rcu |
43 | #define __read_mostly | |
7a10822a | 44 | |
195bcbf5 | 45 | #ifndef __attribute_const__ |
7a10822a | 46 | # define __attribute_const__ |
195bcbf5 | 47 | #endif |
5a116dd2 | 48 | |
1d037ca1 | 49 | #ifndef __maybe_unused |
7a10822a IM |
50 | # define __maybe_unused __attribute__((unused)) |
51 | #endif | |
52 | ||
e58e871b LASL |
53 | #ifndef __used |
54 | # define __used __attribute__((__unused__)) | |
55 | #endif | |
56 | ||
7a10822a IM |
57 | #ifndef __packed |
58 | # define __packed __attribute__((__packed__)) | |
1d037ca1 | 59 | #endif |
618038df | 60 | |
86d5a70c | 61 | #ifndef __force |
7a10822a | 62 | # define __force |
86d5a70c IT |
63 | #endif |
64 | ||
fb1c9185 IM |
65 | #ifndef __weak |
66 | # define __weak __attribute__((weak)) | |
67 | #endif | |
68 | ||
835d44b9 NK |
69 | #ifndef likely |
70 | # define likely(x) __builtin_expect(!!(x), 1) | |
71 | #endif | |
72 | ||
73 | #ifndef unlikely | |
74 | # define unlikely(x) __builtin_expect(!!(x), 0) | |
75 | #endif | |
76 | ||
e58e871b LASL |
77 | #ifndef __init |
78 | # define __init | |
79 | #endif | |
80 | ||
81 | #ifndef noinline | |
82 | # define noinline | |
83 | #endif | |
84 | ||
12ea6539 MW |
85 | #define uninitialized_var(x) x = *(&(x)) |
86 | ||
728abda6 ACM |
87 | #include <linux/types.h> |
88 | ||
c95f3432 JO |
89 | /* |
90 | * Following functions are taken from kernel sources and | |
91 | * break aliasing rules in their original form. | |
92 | * | |
93 | * While kernel is compiled with -fno-strict-aliasing, | |
94 | * perf uses -Wstrict-aliasing=3 which makes build fail | |
95 | * under gcc 4.4. | |
96 | * | |
97 | * Using extra __may_alias__ type to allow aliasing | |
98 | * in this case. | |
99 | */ | |
100 | typedef __u8 __attribute__((__may_alias__)) __u8_alias_t; | |
101 | typedef __u16 __attribute__((__may_alias__)) __u16_alias_t; | |
102 | typedef __u32 __attribute__((__may_alias__)) __u32_alias_t; | |
103 | typedef __u64 __attribute__((__may_alias__)) __u64_alias_t; | |
104 | ||
728abda6 ACM |
105 | static __always_inline void __read_once_size(const volatile void *p, void *res, int size) |
106 | { | |
107 | switch (size) { | |
c95f3432 JO |
108 | case 1: *(__u8_alias_t *) res = *(volatile __u8_alias_t *) p; break; |
109 | case 2: *(__u16_alias_t *) res = *(volatile __u16_alias_t *) p; break; | |
110 | case 4: *(__u32_alias_t *) res = *(volatile __u32_alias_t *) p; break; | |
111 | case 8: *(__u64_alias_t *) res = *(volatile __u64_alias_t *) p; break; | |
728abda6 ACM |
112 | default: |
113 | barrier(); | |
114 | __builtin_memcpy((void *)res, (const void *)p, size); | |
115 | barrier(); | |
116 | } | |
117 | } | |
118 | ||
119 | static __always_inline void __write_once_size(volatile void *p, void *res, int size) | |
120 | { | |
121 | switch (size) { | |
c95f3432 JO |
122 | case 1: *(volatile __u8_alias_t *) p = *(__u8_alias_t *) res; break; |
123 | case 2: *(volatile __u16_alias_t *) p = *(__u16_alias_t *) res; break; | |
124 | case 4: *(volatile __u32_alias_t *) p = *(__u32_alias_t *) res; break; | |
125 | case 8: *(volatile __u64_alias_t *) p = *(__u64_alias_t *) res; break; | |
728abda6 ACM |
126 | default: |
127 | barrier(); | |
128 | __builtin_memcpy((void *)p, (const void *)res, size); | |
129 | barrier(); | |
130 | } | |
131 | } | |
132 | ||
133 | /* | |
134 | * Prevent the compiler from merging or refetching reads or writes. The | |
135 | * compiler is also forbidden from reordering successive instances of | |
2a22f692 MR |
136 | * READ_ONCE and WRITE_ONCE, but only when the compiler is aware of some |
137 | * particular ordering. One way to make the compiler aware of ordering is to | |
138 | * put the two invocations of READ_ONCE or WRITE_ONCE in different C | |
139 | * statements. | |
728abda6 | 140 | * |
2a22f692 MR |
141 | * These two macros will also work on aggregate data types like structs or |
142 | * unions. If the size of the accessed data type exceeds the word size of | |
143 | * the machine (e.g., 32 bits or 64 bits) READ_ONCE() and WRITE_ONCE() will | |
144 | * fall back to memcpy and print a compile-time warning. | |
728abda6 ACM |
145 | * |
146 | * Their two major use cases are: (1) Mediating communication between | |
147 | * process-level code and irq/NMI handlers, all running on the same CPU, | |
2a22f692 | 148 | * and (2) Ensuring that the compiler does not fold, spindle, or otherwise |
728abda6 ACM |
149 | * mutilate accesses that either do not require ordering or that interact |
150 | * with an explicit memory barrier or atomic instruction that provides the | |
151 | * required ordering. | |
152 | */ | |
153 | ||
154 | #define READ_ONCE(x) \ | |
155 | ({ union { typeof(x) __val; char __c[1]; } __u; __read_once_size(&(x), __u.__c, sizeof(x)); __u.__val; }) | |
156 | ||
157 | #define WRITE_ONCE(x, val) \ | |
158 | ({ union { typeof(x) __val; char __c[1]; } __u = { .__val = (val) }; __write_once_size(&(x), __u.__c, sizeof(x)); __u.__val; }) | |
159 | ||
b5bf1733 ACM |
160 | |
161 | #ifndef __fallthrough | |
19261401 | 162 | # define __fallthrough |
b5bf1733 ACM |
163 | #endif |
164 | ||
8a625c1f | 165 | #endif /* _TOOLS_LINUX_COMPILER_H */ |