summaryrefslogtreecommitdiff
path: root/include/compiler.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/compiler.h')
-rw-r--r--include/compiler.h50
1 files changed, 50 insertions, 0 deletions
diff --git a/include/compiler.h b/include/compiler.h
index b0d595f3..8e8a658d 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -198,5 +198,55 @@
#error shim has no cache_invalidate() implementation for this compiler
#endif /* __GNUC__ */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+#define GNUC_PREREQ(maj, min) \
+ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+#define GNUC_PREREQ(maj, min) 0
+#endif
+
+#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
+#define CLANG_PREREQ(maj, min) \
+ ((__clang_major__ > (maj)) || \
+ (__clang_major__ == (maj) && __clang_minor__ >= (min)))
+#else
+#define CLANG_PREREQ(maj, min) 0
+#endif
+
+#if GNUC_PREREQ(5, 1) || CLANG_PREREQ(3, 8)
+#define checked_add(addend0, addend1, sum) \
+ __builtin_add_overflow(addend0, addend1, sum)
+#define checked_sub(minuend, subtrahend, difference) \
+ __builtin_sub_overflow(minuend, subtrahend, difference)
+#define checked_mul(factor0, factor1, product) \
+ __builtin_mul_overflow(factor0, factor1, product)
+#else
+#define checked_add(a0, a1, s) \
+ ({ \
+ (*s) = ((a0) + (a1)); \
+ 0; \
+ })
+#define checked_sub(s0, s1, d) \
+ ({ \
+ (*d) = ((s0) - (s1)); \
+ 0; \
+ })
+#define checked_mul(f0, f1, p) \
+ ({ \
+ (*p) = ((f0) * (f1)); \
+ 0; \
+ })
+#endif
+
+#define checked_div(dividend, divisor, quotient) \
+ ({ \
+ bool _ret = True; \
+ if ((divisor) != 0) { \
+ _ret = False; \
+ (quotient) = (dividend) / (divisor); \
+ } \
+ _ret; \
+ })
+
#endif /* !COMPILER_H_ */
// vim:fenc=utf-8:tw=75:et