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