kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
Log | Files | Refs | README

commit 7d1a9246ba3e7f2fd0cb90592e133377a1312821
parent 9aab29627f3ba5bbfe45b9496733d1b29581e551
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date:   Sat, 30 Jul 2016 19:32:59 +0300

Emulate __builtin_{add/sub}_overflow on old compilers

Diffstat:
Mtests/intrinsic_test.cpp | 45+++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/tests/intrinsic_test.cpp b/tests/intrinsic_test.cpp @@ -54,10 +54,51 @@ inline T ref_abs(T x) } template <typename T> +bool builtin_add_overflow(T x, T y, T* r) +{ +#if __has_builtin(__builtin_add_overflow) + return __builtin_add_overflow(x, y, r); +#else + *r = x + y; + return static_cast<long long>(x) + static_cast<long long>(y) != static_cast<long long>(*r); +#endif +} +template <> +bool builtin_add_overflow<u64>(u64 x, u64 y, u64* r) +{ + return __builtin_uaddll_overflow(x, y, reinterpret_cast<unsigned long long*>(r)); +} +template <> +bool builtin_add_overflow<i64>(i64 x, i64 y, i64* r) +{ + return __builtin_saddll_overflow(x, y, reinterpret_cast<long long*>(r)); +} +template <typename T> +bool builtin_sub_overflow(T x, T y, T* r) +{ +#if __has_builtin(__builtin_sub_overflow) + return __builtin_sub_overflow(x, y, r); +#else + *r = x - y; + return static_cast<long long>(x) - static_cast<long long>(y) != static_cast<long long>(*r); +#endif +} +template <> +bool builtin_sub_overflow<u64>(u64 x, u64 y, u64* r) +{ + return __builtin_usubll_overflow(x, y, reinterpret_cast<unsigned long long*>(r)); +} +template <> +bool builtin_sub_overflow<i64>(i64 x, i64 y, i64* r) +{ + return __builtin_ssubll_overflow(x, y, reinterpret_cast<long long*>(r)); +} +//#endif +template <typename T> inline T ref_satadd(T x, T y) { T result; - if (__builtin_add_overflow(x, y, &result)) + if (builtin_add_overflow(x, y, &result)) return x < 0 ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max(); else return result; @@ -67,7 +108,7 @@ template <typename T> inline T ref_satsub(T x, T y) { T result; - if (__builtin_sub_overflow(x, y, &result)) + if (builtin_sub_overflow(x, y, &result)) return x < y ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max(); else return result;