From 53079305353cd5631b42264bef29f6d465ec71a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Fri, 4 Mar 2016 11:38:51 +0100 Subject: [PATCH] Use gcc builtins (if gcc 5 or newer) for saturating math --- include/ucore/saturating_math.h | 35 ++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/include/ucore/saturating_math.h b/include/ucore/saturating_math.h index 6b9228f..84f9a62 100644 --- a/include/ucore/saturating_math.h +++ b/include/ucore/saturating_math.h @@ -10,10 +10,34 @@ * * multiplication, subtraction and addition operations are provided.*/ +//Use gcc builtins, supported since GCC 5 +#if __GNUC__ >= 5 + +#define UC_SAT_ADD(a, b, type, max_val)\ +({type res ;\ +if (__builtin_add_overflow(a, b, &res)) {\ + res = max_val;}\ +res;}) + + +#define UC_SAT_SUB(a, b, type)\ +({type res ;\ +if (__builtin_sub_overflow(a, b, &res)) {\ + res = 0;}\ +res;}) + +#define UC_SAT_MULT(a, b, type, max_val)\ +({type res ;\ +if (__builtin_mul_overflow(a, b, &res)) {\ + res = max_val;}\ +res;}) + +#else + #define UC_SAT_ADD(a, b, type, max_val)\ ((type)((a) + (b)) >= (a) ? (a) + (b) : (max_val)) -#define UC_SAT_SUB(a, b)\ +#define UC_SAT_SUB(a, b, type)\ ((a) >= (b) ? (a) - (b) : 0) #define UC_SAT_MULT(a, b, type, max_val)\ @@ -21,6 +45,7 @@ (a) <= (max_val) / (b) ? (type) (a) * (type) (b) \ : (max_val)) +#endif static inline uint8_t uc_sat_addu8(uint8_t a, uint8_t b) { @@ -29,7 +54,7 @@ static inline uint8_t uc_sat_addu8(uint8_t a, uint8_t b) static inline uint8_t uc_sat_subu8(uint8_t a, uint8_t b) { - return UC_SAT_SUB(a, b); + return UC_SAT_SUB(a, b, uint8_t); } static inline uint8_t uc_sat_multu8(uint8_t a, uint8_t b) @@ -44,7 +69,7 @@ static inline uint16_t uc_sat_addu16(uint16_t a, uint16_t b) static inline uint16_t uc_sat_subu16(uint16_t a, uint16_t b) { - return UC_SAT_SUB(a, b); + return UC_SAT_SUB(a, b, uint16_t); } static inline uint16_t uc_sat_multu16(uint16_t a, uint16_t b) @@ -59,7 +84,7 @@ static inline uint32_t uc_sat_addu32(uint32_t a, uint32_t b) static inline uint32_t uc_sat_subu32(uint32_t a, uint32_t b) { - return UC_SAT_SUB(a, b); + return UC_SAT_SUB(a, b, uint32_t); } static inline uint32_t uc_sat_multu32(uint32_t a, uint32_t b) @@ -74,7 +99,7 @@ static inline uint64_t uc_sat_addu64(uint64_t a, uint64_t b) static inline uint64_t uc_sat_subu64(uint64_t a, uint64_t b) { - return UC_SAT_SUB(a, b); + return UC_SAT_SUB(a, b, uint64_t); } static inline uint64_t uc_sat_multu64(uint64_t a, uint64_t b)