1 // © 2021 Qualcomm Innovation Center, Inc. All rights reserved.
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 // Macros wrapping miscellaneous compiler builtins to make them easier to use
6 // correctly. Note that this is not intended for compiler independence, only
7 // for readability.
8 
9 // Branch probability hints.
10 //
11 // Note that the argument and result of each of these macros must be
12 // essentially boolean (MISRA rule 14.4), but the argument and result of
13 // __builtin_expect have type long.
14 #define compiler_expected(x)   (__builtin_expect((x) ? 1 : 0, 1) != 0)
15 #define compiler_unexpected(x) (__builtin_expect((x) ? 1 : 0, 0) != 0)
16 
17 // Bit operations.
18 //
19 // On ARM, prefer clz and clrsb as they expand to single instructions (CLZ and
20 // CLS). ffs and ctz need an extra RBIT first.
21 
22 // clang-format off
23 #define compiler_ffs(x) (index_t)_Generic(				       \
24 	(x),								       \
25 	long long: __builtin_ffsll(x),					       \
26 	unsigned long long: __builtin_ffsll((long long)(x)),		       \
27 	long: __builtin_ffsl(x),					       \
28 	unsigned long: __builtin_ffsl((long)(x)),			       \
29 	int: __builtin_ffs(x),						       \
30 	unsigned int: __builtin_ffs((int)(x)))
31 
32 #define compiler_clz(x) (assert((x) != 0U), (index_t)_Generic(		       \
33 	(x),								       \
34 	unsigned long long: __builtin_clzll,				       \
35 	unsigned long: __builtin_clzl,				       \
36 	unsigned int: __builtin_clz)(x))
37 
38 #define compiler_ctz(x) (assert((x) != 0U), (index_t)_Generic(		       \
39 	(x),								       \
40 	unsigned long long: __builtin_ctzll,				       \
41 	unsigned long: __builtin_ctzl,				       \
42 	unsigned int: __builtin_ctz)(x))
43 
44 #define compiler_clrsb(x) (index_t)_Generic(				       \
45 	(x), long long: __builtin_clrsbll,				       \
46 	long: __builtin_clrsbl,					       \
47 	int: __builtin_clrsb)(x)
48 
49 #define compiler_popcount(x) (assert((x) != 0U), (index_t)_Generic(	       \
50 	(x),								       \
51 	unsigned long long: __builtin_popcountll,			       \
52 	unsigned long: __builtin_popcountl,				       \
53 	unsigned int: __builtin_popcount)(x))
54 // clang-format on
55 
56 #define compiler_msb(x) ((sizeof(x) * 8U) - 1U - compiler_clz(x))
57 
58 // Object sizes, for use in minimum buffer size assertions. These return
59 // (size_t)-1 if the size cannot be determined statically, so the assertion
60 // should become a no-op in that case. LLVM has an intrinsic for this, so
61 // the static determination can be made after inlining by LTO.
62 #define compiler_sizeof_object(ptr)    __builtin_object_size((ptr), 1)
63 #define compiler_sizeof_container(ptr) __builtin_object_size((ptr), 0)
64 
65 // Mark a break statement as unreachable. This expected to be used at the end of
66 // switch cases to comply with MISRA rule 16.3, which requires a break statement
67 // to end the case regardless of whether it is reachable.
68 
69 // clang-format off
70 #define compiler_unreachable_break \
71 	_Pragma("clang diagnostic push")                                       \
72 	_Pragma("clang diagnostic ignored \"-Wunreachable-code\"")             \
73 	break                                                                  \
74 	_Pragma("clang diagnostic pop")
75 // clang-format on
76