xref: /linux-6.15/tools/include/linux/compiler.h (revision 712676ea)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
28a625c1fSNamhyung Kim #ifndef _TOOLS_LINUX_COMPILER_H_
38a625c1fSNamhyung Kim #define _TOOLS_LINUX_COMPILER_H_
48a625c1fSNamhyung Kim 
5*712676eaSAdhemerval Zanella #ifndef __ASSEMBLY__
6*712676eaSAdhemerval Zanella 
74bba4c4bSArnaldo Carvalho de Melo #include <linux/compiler_types.h>
819261401SArnaldo Carvalho de Melo 
949006538SArnaldo Carvalho de Melo #ifndef __compiletime_error
1049006538SArnaldo Carvalho de Melo # define __compiletime_error(message)
1149006538SArnaldo Carvalho de Melo #endif
1249006538SArnaldo Carvalho de Melo 
135b992addSArnaldo Carvalho de Melo #ifdef __OPTIMIZE__
145b992addSArnaldo Carvalho de Melo # define __compiletime_assert(condition, msg, prefix, suffix)		\
155b992addSArnaldo Carvalho de Melo 	do {								\
165b992addSArnaldo Carvalho de Melo 		extern void prefix ## suffix(void) __compiletime_error(msg); \
175b992addSArnaldo Carvalho de Melo 		if (!(condition))					\
185b992addSArnaldo Carvalho de Melo 			prefix ## suffix();				\
195b992addSArnaldo Carvalho de Melo 	} while (0)
205b992addSArnaldo Carvalho de Melo #else
215b992addSArnaldo Carvalho de Melo # define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0)
225b992addSArnaldo Carvalho de Melo #endif
235b992addSArnaldo Carvalho de Melo 
245b992addSArnaldo Carvalho de Melo #define _compiletime_assert(condition, msg, prefix, suffix) \
255b992addSArnaldo Carvalho de Melo 	__compiletime_assert(condition, msg, prefix, suffix)
265b992addSArnaldo Carvalho de Melo 
275b992addSArnaldo Carvalho de Melo /**
285b992addSArnaldo Carvalho de Melo  * compiletime_assert - break build and emit msg if condition is false
295b992addSArnaldo Carvalho de Melo  * @condition: a compile-time constant condition to check
305b992addSArnaldo Carvalho de Melo  * @msg:       a message to emit if condition is false
315b992addSArnaldo Carvalho de Melo  *
325b992addSArnaldo Carvalho de Melo  * In tradition of POSIX assert, this macro will break the build if the
335b992addSArnaldo Carvalho de Melo  * supplied condition is *false*, emitting the supplied error message if the
345b992addSArnaldo Carvalho de Melo  * compiler has support to do so.
355b992addSArnaldo Carvalho de Melo  */
365b992addSArnaldo Carvalho de Melo #define compiletime_assert(condition, msg) \
375b992addSArnaldo Carvalho de Melo 	_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
385b992addSArnaldo Carvalho de Melo 
395ac69737SArnaldo Carvalho de Melo /* Optimization barrier */
405ac69737SArnaldo Carvalho de Melo /* The "volatile" is due to gcc bugs */
415ac69737SArnaldo Carvalho de Melo #define barrier() __asm__ __volatile__("": : :"memory")
425ac69737SArnaldo Carvalho de Melo 
438a625c1fSNamhyung Kim #ifndef __always_inline
448a625c1fSNamhyung Kim # define __always_inline	inline __attribute__((always_inline))
458a625c1fSNamhyung Kim #endif
468a625c1fSNamhyung Kim 
4751e6ac1fSMark Brown #ifndef __always_unused
4851e6ac1fSMark Brown #define __always_unused __attribute__((__unused__))
4951e6ac1fSMark Brown #endif
5051e6ac1fSMark Brown 
5151e6ac1fSMark Brown #ifndef __noreturn
5251e6ac1fSMark Brown #define __noreturn __attribute__((__noreturn__))
5351e6ac1fSMark Brown #endif
5451e6ac1fSMark Brown 
5551e6ac1fSMark Brown #ifndef unreachable
5651e6ac1fSMark Brown #define unreachable() __builtin_unreachable()
5751e6ac1fSMark Brown #endif
5851e6ac1fSMark Brown 
599dd4ca47SArnaldo Carvalho de Melo #ifndef noinline
609dd4ca47SArnaldo Carvalho de Melo #define noinline
619dd4ca47SArnaldo Carvalho de Melo #endif
629dd4ca47SArnaldo Carvalho de Melo 
63af8d27bfSJiri Olsa #ifndef __nocf_check
64af8d27bfSJiri Olsa #define __nocf_check __attribute__((nocf_check))
65af8d27bfSJiri Olsa #endif
66af8d27bfSJiri Olsa 
673e8e2576SJiri Olsa #ifndef __naked
683e8e2576SJiri Olsa #define __naked __attribute__((__naked__))
693e8e2576SJiri Olsa #endif
703e8e2576SJiri Olsa 
71f6441affSArnaldo Carvalho de Melo /* Are two types/vars the same type (ignoring qualifiers)? */
72f6441affSArnaldo Carvalho de Melo #ifndef __same_type
73f6441affSArnaldo Carvalho de Melo # define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
74f6441affSArnaldo Carvalho de Melo #endif
75f6441affSArnaldo Carvalho de Melo 
76598f0ac1SDavid Laight /*
77598f0ac1SDavid Laight  * This returns a constant expression while determining if an argument is
78598f0ac1SDavid Laight  * a constant expression, most importantly without evaluating the argument.
79598f0ac1SDavid Laight  * Glory to Martin Uecker <[email protected]>
80598f0ac1SDavid Laight  */
81598f0ac1SDavid Laight #define __is_constexpr(x) \
82598f0ac1SDavid Laight 	(sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8)))
83598f0ac1SDavid Laight 
848c98abffSArnaldo Carvalho de Melo #ifdef __ANDROID__
858c98abffSArnaldo Carvalho de Melo /*
868c98abffSArnaldo Carvalho de Melo  * FIXME: Big hammer to get rid of tons of:
878c98abffSArnaldo Carvalho de Melo  *   "warning: always_inline function might not be inlinable"
888c98abffSArnaldo Carvalho de Melo  *
898c98abffSArnaldo Carvalho de Melo  * At least on android-ndk-r12/platforms/android-24/arch-arm
908c98abffSArnaldo Carvalho de Melo  */
918c98abffSArnaldo Carvalho de Melo #undef __always_inline
928c98abffSArnaldo Carvalho de Melo #define __always_inline	inline
938c98abffSArnaldo Carvalho de Melo #endif
948c98abffSArnaldo Carvalho de Melo 
958a625c1fSNamhyung Kim #define __user
9612ea6539SMatthew Wilcox #define __rcu
9712ea6539SMatthew Wilcox #define __read_mostly
988a625c1fSNamhyung Kim 
998a625c1fSNamhyung Kim #ifndef __attribute_const__
1008a625c1fSNamhyung Kim # define __attribute_const__
1018a625c1fSNamhyung Kim #endif
1028a625c1fSNamhyung Kim 
1038a625c1fSNamhyung Kim #ifndef __maybe_unused
1048a625c1fSNamhyung Kim # define __maybe_unused		__attribute__((unused))
1058a625c1fSNamhyung Kim #endif
1068a625c1fSNamhyung Kim 
107e58e871bSLevin, Alexander (Sasha Levin) #ifndef __used
108e58e871bSLevin, Alexander (Sasha Levin) # define __used		__attribute__((__unused__))
109e58e871bSLevin, Alexander (Sasha Levin) #endif
110e58e871bSLevin, Alexander (Sasha Levin) 
1118a625c1fSNamhyung Kim #ifndef __packed
1128a625c1fSNamhyung Kim # define __packed		__attribute__((__packed__))
1138a625c1fSNamhyung Kim #endif
1148a625c1fSNamhyung Kim 
1158a625c1fSNamhyung Kim #ifndef __force
1168a625c1fSNamhyung Kim # define __force
1178a625c1fSNamhyung Kim #endif
1188a625c1fSNamhyung Kim 
1198a625c1fSNamhyung Kim #ifndef __weak
1208a625c1fSNamhyung Kim # define __weak			__attribute__((weak))
1218a625c1fSNamhyung Kim #endif
1228a625c1fSNamhyung Kim 
123835d44b9SNamhyung Kim #ifndef likely
124835d44b9SNamhyung Kim # define likely(x)		__builtin_expect(!!(x), 1)
125835d44b9SNamhyung Kim #endif
126835d44b9SNamhyung Kim 
127835d44b9SNamhyung Kim #ifndef unlikely
128835d44b9SNamhyung Kim # define unlikely(x)		__builtin_expect(!!(x), 0)
129835d44b9SNamhyung Kim #endif
130835d44b9SNamhyung Kim 
131e58e871bSLevin, Alexander (Sasha Levin) #include <linux/types.h>
132e58e871bSLevin, Alexander (Sasha Levin) 
133e58e871bSLevin, Alexander (Sasha Levin) /*
134e58e871bSLevin, Alexander (Sasha Levin)  * Following functions are taken from kernel sources and
135728abda6SArnaldo Carvalho de Melo  * break aliasing rules in their original form.
136728abda6SArnaldo Carvalho de Melo  *
137c95f3432SJiri Olsa  * While kernel is compiled with -fno-strict-aliasing,
138c95f3432SJiri Olsa  * perf uses -Wstrict-aliasing=3 which makes build fail
139c95f3432SJiri Olsa  * under gcc 4.4.
140c95f3432SJiri Olsa  *
141c95f3432SJiri Olsa  * Using extra __may_alias__ type to allow aliasing
142c95f3432SJiri Olsa  * in this case.
143c95f3432SJiri Olsa  */
144c95f3432SJiri Olsa typedef __u8  __attribute__((__may_alias__))  __u8_alias_t;
145c95f3432SJiri Olsa typedef __u16 __attribute__((__may_alias__)) __u16_alias_t;
146c95f3432SJiri Olsa typedef __u32 __attribute__((__may_alias__)) __u32_alias_t;
147c95f3432SJiri Olsa typedef __u64 __attribute__((__may_alias__)) __u64_alias_t;
148c95f3432SJiri Olsa 
__read_once_size(const volatile void * p,void * res,int size)149c95f3432SJiri Olsa static __always_inline void __read_once_size(const volatile void *p, void *res, int size)
150c95f3432SJiri Olsa {
151c95f3432SJiri Olsa 	switch (size) {
152c95f3432SJiri Olsa 	case 1: *(__u8_alias_t  *) res = *(volatile __u8_alias_t  *) p; break;
153728abda6SArnaldo Carvalho de Melo 	case 2: *(__u16_alias_t *) res = *(volatile __u16_alias_t *) p; break;
154728abda6SArnaldo Carvalho de Melo 	case 4: *(__u32_alias_t *) res = *(volatile __u32_alias_t *) p; break;
155728abda6SArnaldo Carvalho de Melo 	case 8: *(__u64_alias_t *) res = *(volatile __u64_alias_t *) p; break;
156c95f3432SJiri Olsa 	default:
157c95f3432SJiri Olsa 		barrier();
158c95f3432SJiri Olsa 		__builtin_memcpy((void *)res, (const void *)p, size);
159c95f3432SJiri Olsa 		barrier();
160728abda6SArnaldo Carvalho de Melo 	}
161728abda6SArnaldo Carvalho de Melo }
162728abda6SArnaldo Carvalho de Melo 
__write_once_size(volatile void * p,void * res,int size)163728abda6SArnaldo Carvalho de Melo static __always_inline void __write_once_size(volatile void *p, void *res, int size)
164728abda6SArnaldo Carvalho de Melo {
165728abda6SArnaldo Carvalho de Melo 	switch (size) {
166728abda6SArnaldo Carvalho de Melo 	case 1: *(volatile  __u8_alias_t *) p = *(__u8_alias_t  *) res; break;
167728abda6SArnaldo Carvalho de Melo 	case 2: *(volatile __u16_alias_t *) p = *(__u16_alias_t *) res; break;
168728abda6SArnaldo Carvalho de Melo 	case 4: *(volatile __u32_alias_t *) p = *(__u32_alias_t *) res; break;
169728abda6SArnaldo Carvalho de Melo 	case 8: *(volatile __u64_alias_t *) p = *(__u64_alias_t *) res; break;
170c95f3432SJiri Olsa 	default:
171c95f3432SJiri Olsa 		barrier();
172c95f3432SJiri Olsa 		__builtin_memcpy((void *)p, (const void *)res, size);
173c95f3432SJiri Olsa 		barrier();
174728abda6SArnaldo Carvalho de Melo 	}
175728abda6SArnaldo Carvalho de Melo }
176728abda6SArnaldo Carvalho de Melo 
177728abda6SArnaldo Carvalho de Melo /*
178728abda6SArnaldo Carvalho de Melo  * Prevent the compiler from merging or refetching reads or writes. The
179728abda6SArnaldo Carvalho de Melo  * compiler is also forbidden from reordering successive instances of
180728abda6SArnaldo Carvalho de Melo  * READ_ONCE and WRITE_ONCE, but only when the compiler is aware of some
181728abda6SArnaldo Carvalho de Melo  * particular ordering. One way to make the compiler aware of ordering is to
182728abda6SArnaldo Carvalho de Melo  * put the two invocations of READ_ONCE or WRITE_ONCE in different C
183728abda6SArnaldo Carvalho de Melo  * statements.
1842a22f692SMark Rutland  *
1852a22f692SMark Rutland  * These two macros will also work on aggregate data types like structs or
1862a22f692SMark Rutland  * unions. If the size of the accessed data type exceeds the word size of
1872a22f692SMark Rutland  * the machine (e.g., 32 bits or 64 bits) READ_ONCE() and WRITE_ONCE() will
188728abda6SArnaldo Carvalho de Melo  * fall back to memcpy and print a compile-time warning.
1892a22f692SMark Rutland  *
1902a22f692SMark Rutland  * Their two major use cases are: (1) Mediating communication between
1912a22f692SMark Rutland  * process-level code and irq/NMI handlers, all running on the same CPU,
1922a22f692SMark Rutland  * and (2) Ensuring that the compiler does not fold, spindle, or otherwise
193728abda6SArnaldo Carvalho de Melo  * mutilate accesses that either do not require ordering or that interact
194728abda6SArnaldo Carvalho de Melo  * with an explicit memory barrier or atomic instruction that provides the
195728abda6SArnaldo Carvalho de Melo  * required ordering.
196728abda6SArnaldo Carvalho de Melo  */
197728abda6SArnaldo Carvalho de Melo 
198728abda6SArnaldo Carvalho de Melo #define READ_ONCE(x)					\
199728abda6SArnaldo Carvalho de Melo ({							\
200728abda6SArnaldo Carvalho de Melo 	union { typeof(x) __val; char __c[1]; } __u =	\
201728abda6SArnaldo Carvalho de Melo 		{ .__c = { 0 } };			\
202728abda6SArnaldo Carvalho de Melo 	__read_once_size(&(x), __u.__c, sizeof(x));	\
2034d3b57daSMark Rutland 	__u.__val;					\
2044d3b57daSMark Rutland })
2054d3b57daSMark Rutland 
2064d3b57daSMark Rutland #define WRITE_ONCE(x, val)				\
2074d3b57daSMark Rutland ({							\
2084d3b57daSMark Rutland 	union { typeof(x) __val; char __c[1]; } __u =	\
209728abda6SArnaldo Carvalho de Melo 		{ .__val = (val) }; 			\
210728abda6SArnaldo Carvalho de Melo 	__write_once_size(&(x), __u.__c, sizeof(x));	\
2114d3b57daSMark Rutland 	__u.__val;					\
2124d3b57daSMark Rutland })
2134d3b57daSMark Rutland 
2144d3b57daSMark Rutland 
2154d3b57daSMark Rutland /* Indirect macros required for expanded argument pasting, eg. __LINE__. */
2164d3b57daSMark Rutland #define ___PASTE(a, b) a##b
217728abda6SArnaldo Carvalho de Melo #define __PASTE(a, b) ___PASTE(a, b)
218b5bf1733SArnaldo Carvalho de Melo 
219e5a0516eSJiri Olsa #ifndef OPTIMIZER_HIDE_VAR
220e5a0516eSJiri Olsa /* Make the optimizer believe the variable can be manipulated arbitrarily. */
221e5a0516eSJiri Olsa #define OPTIMIZER_HIDE_VAR(var)						\
222e5a0516eSJiri Olsa 	__asm__ ("" : "=r" (var) : "0" (var))
223e5d51a66SMark Brown #endif
224e5d51a66SMark Brown 
225e5d51a66SMark Brown #endif /* __ASSEMBLY__ */
226e5d51a66SMark Brown 
227e5d51a66SMark Brown #endif /* _TOOLS_LINUX_COMPILER_H */
228e5d51a66SMark Brown