/src/cmp_tool/lib/common/compiler.h
Line | Count | Source |
1 | | /** |
2 | | * @file compiler.h |
3 | | * @author Armin Luntzer (armin.luntzer@univie.ac.at) |
4 | | * @date 2015 |
5 | | * |
6 | | * @copyright GPLv2 |
7 | | * This program is free software; you can redistribute it and/or modify it |
8 | | * under the terms and conditions of the GNU General Public License, |
9 | | * version 2, as published by the Free Software Foundation. |
10 | | * |
11 | | * This program is distributed in the hope it will be useful, but WITHOUT |
12 | | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
14 | | * more details. |
15 | | * |
16 | | * @brief a collection of preprocessor macros |
17 | | */ |
18 | | |
19 | | |
20 | | #ifndef COMPILER_H |
21 | | #define COMPILER_H |
22 | | |
23 | | |
24 | | /* Derived from Linux "Features Test Macro" header Convenience macros to test |
25 | | * the versions of gcc (or a compatible compiler). |
26 | | * Use them like this: |
27 | | * #if GNUC_PREREQ (2,8) |
28 | | * ... code requiring gcc 2.8 or later ... |
29 | | * #endif |
30 | | */ |
31 | | |
32 | | #if defined(__GNUC__) && defined(__GNUC_MINOR__) |
33 | | # define GNUC_PREREQ(maj, min) \ |
34 | | ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) |
35 | | #else |
36 | | #define GNUC_PREREQ(maj, min) 0 |
37 | | #endif |
38 | | |
39 | | |
40 | | /** |
41 | | * same with the stuff below |
42 | | */ |
43 | | |
44 | | #define likely(x) __builtin_expect(!!(x), 1) |
45 | 260k | #define unlikely(x) __builtin_expect(!!(x), 0) |
46 | | |
47 | | /** |
48 | | * |
49 | | * ARRAY_SIZE - get the number of elements in a visible array |
50 | | * @param x the array whose size you want |
51 | | * |
52 | | * This does not work on pointers, or arrays declared as [], or |
53 | | * function parameters. With correct compiler support, such usage |
54 | | * will cause a build error |
55 | | */ |
56 | | |
57 | 3.35k | #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) |
58 | | |
59 | | #define bitsizeof(x) (CHAR_BIT * sizeof(x)) |
60 | | |
61 | | #define maximum_signed_value_of_type(a) \ |
62 | | (INTMAX_MAX >> (bitsizeof(intmax_t) - bitsizeof(a))) |
63 | | |
64 | | #define maximum_unsigned_value_of_type(a) \ |
65 | | (UINTMAX_MAX >> (bitsizeof(uintmax_t) - bitsizeof(a))) |
66 | | |
67 | | /* |
68 | | * Signed integer overflow is undefined in C, so here's a helper macro |
69 | | * to detect if the sum of two integers will overflow. |
70 | | * |
71 | | * Requires: a >= 0, typeof(a) equals typeof(b) |
72 | | */ |
73 | | #define signed_add_overflows(a, b) \ |
74 | | ((b) > maximum_signed_value_of_type(a) - (a)) |
75 | | |
76 | | #define unsigned_add_overflows(a, b) \ |
77 | | ((b) > maximum_unsigned_value_of_type(a) - (a)) |
78 | | |
79 | | |
80 | 132k | #define __get_unaligned_t(type, ptr) __extension__ ({ \ |
81 | 132k | const struct { type x; } __attribute__((packed)) *__pptr = (__typeof__(__pptr))(ptr); \ |
82 | 132k | __pptr->x; \ |
83 | 132k | }) |
84 | | |
85 | 4.46k | #define __put_unaligned_t(type, val, ptr) do { \ |
86 | 4.46k | struct { type x; } __attribute__((packed)) *__pptr = (__typeof__(__pptr))(ptr); \ |
87 | 4.46k | __pptr->x = (val); \ |
88 | 4.46k | } while (0) |
89 | | |
90 | | |
91 | | /** |
92 | | * @brief read from an unaligned address |
93 | | * |
94 | | * @param ptr pointer to the address to read from (can be unaligned) |
95 | | * |
96 | | * @return the value read from the (unaligned) address in system endianness |
97 | | * @note the size of the value is determined by the pointer type |
98 | | */ |
99 | | |
100 | 132k | #define get_unaligned(ptr) __get_unaligned_t(__typeof__(*(ptr)), (ptr)) |
101 | | |
102 | | |
103 | | /** |
104 | | * @brief write to an unaligned address |
105 | | * |
106 | | * @param val the value to write |
107 | | * @param ptr pointer to the address to write to (can be unaligned) |
108 | | * |
109 | | * @note the size of the value is determined by the pointer type |
110 | | */ |
111 | | |
112 | 4.46k | #define put_unaligned(val, ptr) __put_unaligned_t(__typeof__(*(ptr)), (val), (ptr)) |
113 | | |
114 | | |
115 | | /** |
116 | | * @brief mark a variable as unused to suppress compiler warnings. |
117 | | * |
118 | | * This macro is used to indicate that a variable is intentionally left unused |
119 | | * in the code. It helps suppress compiler warnings about unused variables. |
120 | | * It also tries to prevent the actual use of the "unused" variables. |
121 | | */ |
122 | | |
123 | | #if GNUC_PREREQ(4, 5) || defined(__clang__) |
124 | | #define UNUSED __attribute__((unused)) \ |
125 | | __attribute__((deprecated ("parameter declared as UNUSED"))) |
126 | | #elif defined(__GNUC__) |
127 | | #define UNUSED __attribute__((unused)) \ |
128 | | __attribute__((deprecated)) |
129 | | #else |
130 | | #define UNUSED |
131 | | #endif |
132 | | |
133 | | |
134 | | /** |
135 | | * @brief mark a variable as potentially unused to suppress compiler warnings. |
136 | | * |
137 | | * This macro is used to indicate that a variable may be intentionally left unused |
138 | | * in the code. It helps suppress compiler warnings about unused variables. |
139 | | * It does *not* protect against the actual use of the "unused" variables. |
140 | | */ |
141 | | |
142 | | #if (DEBUGLEVEL == 0) |
143 | 10 | #define MAYBE_UNUSED __attribute__((unused)) |
144 | | #else |
145 | | #define MAYBE_UNUSED |
146 | | #endif |
147 | | |
148 | | |
149 | | /** |
150 | | * Compile time check usable outside of function scope. |
151 | | * Stolen from Linux (hpi_internal.h) |
152 | | */ |
153 | | #define compile_time_assert(cond, msg) UNUSED typedef char ASSERT_##msg[(cond) ? 1 : -1] |
154 | | |
155 | | |
156 | | #endif /* COMPILER_H */ |