162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _TOOLS_LINUX_COMPILER_H_
362306a36Sopenharmony_ci#define _TOOLS_LINUX_COMPILER_H_
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/compiler_types.h>
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#ifndef __compiletime_error
862306a36Sopenharmony_ci# define __compiletime_error(message)
962306a36Sopenharmony_ci#endif
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifdef __OPTIMIZE__
1262306a36Sopenharmony_ci# define __compiletime_assert(condition, msg, prefix, suffix)		\
1362306a36Sopenharmony_ci	do {								\
1462306a36Sopenharmony_ci		extern void prefix ## suffix(void) __compiletime_error(msg); \
1562306a36Sopenharmony_ci		if (!(condition))					\
1662306a36Sopenharmony_ci			prefix ## suffix();				\
1762306a36Sopenharmony_ci	} while (0)
1862306a36Sopenharmony_ci#else
1962306a36Sopenharmony_ci# define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0)
2062306a36Sopenharmony_ci#endif
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#define _compiletime_assert(condition, msg, prefix, suffix) \
2362306a36Sopenharmony_ci	__compiletime_assert(condition, msg, prefix, suffix)
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/**
2662306a36Sopenharmony_ci * compiletime_assert - break build and emit msg if condition is false
2762306a36Sopenharmony_ci * @condition: a compile-time constant condition to check
2862306a36Sopenharmony_ci * @msg:       a message to emit if condition is false
2962306a36Sopenharmony_ci *
3062306a36Sopenharmony_ci * In tradition of POSIX assert, this macro will break the build if the
3162306a36Sopenharmony_ci * supplied condition is *false*, emitting the supplied error message if the
3262306a36Sopenharmony_ci * compiler has support to do so.
3362306a36Sopenharmony_ci */
3462306a36Sopenharmony_ci#define compiletime_assert(condition, msg) \
3562306a36Sopenharmony_ci	_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci/* Optimization barrier */
3862306a36Sopenharmony_ci/* The "volatile" is due to gcc bugs */
3962306a36Sopenharmony_ci#define barrier() __asm__ __volatile__("": : :"memory")
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#ifndef __always_inline
4262306a36Sopenharmony_ci# define __always_inline	inline __attribute__((always_inline))
4362306a36Sopenharmony_ci#endif
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#ifndef __always_unused
4662306a36Sopenharmony_ci#define __always_unused __attribute__((__unused__))
4762306a36Sopenharmony_ci#endif
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci#ifndef __noreturn
5062306a36Sopenharmony_ci#define __noreturn __attribute__((__noreturn__))
5162306a36Sopenharmony_ci#endif
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci#ifndef unreachable
5462306a36Sopenharmony_ci#define unreachable() __builtin_unreachable()
5562306a36Sopenharmony_ci#endif
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci#ifndef noinline
5862306a36Sopenharmony_ci#define noinline
5962306a36Sopenharmony_ci#endif
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci/* Are two types/vars the same type (ignoring qualifiers)? */
6262306a36Sopenharmony_ci#ifndef __same_type
6362306a36Sopenharmony_ci# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
6462306a36Sopenharmony_ci#endif
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci#ifdef __ANDROID__
6762306a36Sopenharmony_ci/*
6862306a36Sopenharmony_ci * FIXME: Big hammer to get rid of tons of:
6962306a36Sopenharmony_ci *   "warning: always_inline function might not be inlinable"
7062306a36Sopenharmony_ci *
7162306a36Sopenharmony_ci * At least on android-ndk-r12/platforms/android-24/arch-arm
7262306a36Sopenharmony_ci */
7362306a36Sopenharmony_ci#undef __always_inline
7462306a36Sopenharmony_ci#define __always_inline	inline
7562306a36Sopenharmony_ci#endif
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci#define __user
7862306a36Sopenharmony_ci#define __rcu
7962306a36Sopenharmony_ci#define __read_mostly
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci#ifndef __attribute_const__
8262306a36Sopenharmony_ci# define __attribute_const__
8362306a36Sopenharmony_ci#endif
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci#ifndef __maybe_unused
8662306a36Sopenharmony_ci# define __maybe_unused		__attribute__((unused))
8762306a36Sopenharmony_ci#endif
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci#ifndef __used
9062306a36Sopenharmony_ci# define __used		__attribute__((__unused__))
9162306a36Sopenharmony_ci#endif
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci#ifndef __packed
9462306a36Sopenharmony_ci# define __packed		__attribute__((__packed__))
9562306a36Sopenharmony_ci#endif
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci#ifndef __force
9862306a36Sopenharmony_ci# define __force
9962306a36Sopenharmony_ci#endif
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci#ifndef __weak
10262306a36Sopenharmony_ci# define __weak			__attribute__((weak))
10362306a36Sopenharmony_ci#endif
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci#ifndef likely
10662306a36Sopenharmony_ci# define likely(x)		__builtin_expect(!!(x), 1)
10762306a36Sopenharmony_ci#endif
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci#ifndef unlikely
11062306a36Sopenharmony_ci# define unlikely(x)		__builtin_expect(!!(x), 0)
11162306a36Sopenharmony_ci#endif
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci#ifndef __init
11462306a36Sopenharmony_ci# define __init
11562306a36Sopenharmony_ci#endif
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci#include <linux/types.h>
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci/*
12062306a36Sopenharmony_ci * Following functions are taken from kernel sources and
12162306a36Sopenharmony_ci * break aliasing rules in their original form.
12262306a36Sopenharmony_ci *
12362306a36Sopenharmony_ci * While kernel is compiled with -fno-strict-aliasing,
12462306a36Sopenharmony_ci * perf uses -Wstrict-aliasing=3 which makes build fail
12562306a36Sopenharmony_ci * under gcc 4.4.
12662306a36Sopenharmony_ci *
12762306a36Sopenharmony_ci * Using extra __may_alias__ type to allow aliasing
12862306a36Sopenharmony_ci * in this case.
12962306a36Sopenharmony_ci */
13062306a36Sopenharmony_citypedef __u8  __attribute__((__may_alias__))  __u8_alias_t;
13162306a36Sopenharmony_citypedef __u16 __attribute__((__may_alias__)) __u16_alias_t;
13262306a36Sopenharmony_citypedef __u32 __attribute__((__may_alias__)) __u32_alias_t;
13362306a36Sopenharmony_citypedef __u64 __attribute__((__may_alias__)) __u64_alias_t;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistatic __always_inline void __read_once_size(const volatile void *p, void *res, int size)
13662306a36Sopenharmony_ci{
13762306a36Sopenharmony_ci	switch (size) {
13862306a36Sopenharmony_ci	case 1: *(__u8_alias_t  *) res = *(volatile __u8_alias_t  *) p; break;
13962306a36Sopenharmony_ci	case 2: *(__u16_alias_t *) res = *(volatile __u16_alias_t *) p; break;
14062306a36Sopenharmony_ci	case 4: *(__u32_alias_t *) res = *(volatile __u32_alias_t *) p; break;
14162306a36Sopenharmony_ci	case 8: *(__u64_alias_t *) res = *(volatile __u64_alias_t *) p; break;
14262306a36Sopenharmony_ci	default:
14362306a36Sopenharmony_ci		barrier();
14462306a36Sopenharmony_ci		__builtin_memcpy((void *)res, (const void *)p, size);
14562306a36Sopenharmony_ci		barrier();
14662306a36Sopenharmony_ci	}
14762306a36Sopenharmony_ci}
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_cistatic __always_inline void __write_once_size(volatile void *p, void *res, int size)
15062306a36Sopenharmony_ci{
15162306a36Sopenharmony_ci	switch (size) {
15262306a36Sopenharmony_ci	case 1: *(volatile  __u8_alias_t *) p = *(__u8_alias_t  *) res; break;
15362306a36Sopenharmony_ci	case 2: *(volatile __u16_alias_t *) p = *(__u16_alias_t *) res; break;
15462306a36Sopenharmony_ci	case 4: *(volatile __u32_alias_t *) p = *(__u32_alias_t *) res; break;
15562306a36Sopenharmony_ci	case 8: *(volatile __u64_alias_t *) p = *(__u64_alias_t *) res; break;
15662306a36Sopenharmony_ci	default:
15762306a36Sopenharmony_ci		barrier();
15862306a36Sopenharmony_ci		__builtin_memcpy((void *)p, (const void *)res, size);
15962306a36Sopenharmony_ci		barrier();
16062306a36Sopenharmony_ci	}
16162306a36Sopenharmony_ci}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci/*
16462306a36Sopenharmony_ci * Prevent the compiler from merging or refetching reads or writes. The
16562306a36Sopenharmony_ci * compiler is also forbidden from reordering successive instances of
16662306a36Sopenharmony_ci * READ_ONCE and WRITE_ONCE, but only when the compiler is aware of some
16762306a36Sopenharmony_ci * particular ordering. One way to make the compiler aware of ordering is to
16862306a36Sopenharmony_ci * put the two invocations of READ_ONCE or WRITE_ONCE in different C
16962306a36Sopenharmony_ci * statements.
17062306a36Sopenharmony_ci *
17162306a36Sopenharmony_ci * These two macros will also work on aggregate data types like structs or
17262306a36Sopenharmony_ci * unions. If the size of the accessed data type exceeds the word size of
17362306a36Sopenharmony_ci * the machine (e.g., 32 bits or 64 bits) READ_ONCE() and WRITE_ONCE() will
17462306a36Sopenharmony_ci * fall back to memcpy and print a compile-time warning.
17562306a36Sopenharmony_ci *
17662306a36Sopenharmony_ci * Their two major use cases are: (1) Mediating communication between
17762306a36Sopenharmony_ci * process-level code and irq/NMI handlers, all running on the same CPU,
17862306a36Sopenharmony_ci * and (2) Ensuring that the compiler does not fold, spindle, or otherwise
17962306a36Sopenharmony_ci * mutilate accesses that either do not require ordering or that interact
18062306a36Sopenharmony_ci * with an explicit memory barrier or atomic instruction that provides the
18162306a36Sopenharmony_ci * required ordering.
18262306a36Sopenharmony_ci */
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci#define READ_ONCE(x)					\
18562306a36Sopenharmony_ci({							\
18662306a36Sopenharmony_ci	union { typeof(x) __val; char __c[1]; } __u =	\
18762306a36Sopenharmony_ci		{ .__c = { 0 } };			\
18862306a36Sopenharmony_ci	__read_once_size(&(x), __u.__c, sizeof(x));	\
18962306a36Sopenharmony_ci	__u.__val;					\
19062306a36Sopenharmony_ci})
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci#define WRITE_ONCE(x, val)				\
19362306a36Sopenharmony_ci({							\
19462306a36Sopenharmony_ci	union { typeof(x) __val; char __c[1]; } __u =	\
19562306a36Sopenharmony_ci		{ .__val = (val) }; 			\
19662306a36Sopenharmony_ci	__write_once_size(&(x), __u.__c, sizeof(x));	\
19762306a36Sopenharmony_ci	__u.__val;					\
19862306a36Sopenharmony_ci})
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci/* Indirect macros required for expanded argument pasting, eg. __LINE__. */
20262306a36Sopenharmony_ci#define ___PASTE(a, b) a##b
20362306a36Sopenharmony_ci#define __PASTE(a, b) ___PASTE(a, b)
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci#ifndef OPTIMIZER_HIDE_VAR
20662306a36Sopenharmony_ci/* Make the optimizer believe the variable can be manipulated arbitrarily. */
20762306a36Sopenharmony_ci#define OPTIMIZER_HIDE_VAR(var)						\
20862306a36Sopenharmony_ci	__asm__ ("" : "=r" (var) : "0" (var))
20962306a36Sopenharmony_ci#endif
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci#endif /* _TOOLS_LINUX_COMPILER_H */
212