aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2019-01-30 04:07:32 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2019-01-30 04:07:32 +0000
commit8fe3ce424dad0a95872b73993befbc496ed2df32 (patch)
treec3892eb363dbb91bdac682f77b6b0233cb5a6492
parent7c5a2591c96e95d634582ebf825169a66a38eae8 (diff)
parentaff3e6af56a10644ee05508d454a34673687532e (diff)
downloadlibopus-8fe3ce424dad0a95872b73993befbc496ed2df32.tar.gz
Snap for 5268116 from aff3e6af56a10644ee05508d454a34673687532e to qt-release
Change-Id: Iac5d0e1a34507228f7a6aed350bc5d00b93446a4
-rw-r--r--silk/SigProc_FIX.h29
-rw-r--r--silk/macros.h31
2 files changed, 50 insertions, 10 deletions
diff --git a/silk/SigProc_FIX.h b/silk/SigProc_FIX.h
index f9ae3263..a9068908 100644
--- a/silk/SigProc_FIX.h
+++ b/silk/SigProc_FIX.h
@@ -448,13 +448,29 @@ static OPUS_INLINE opus_int32 silk_ROR32( opus_int32 a32, opus_int rot )
/* Adds two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour
(just standard two's complement implementation-specific behaviour) */
-#define silk_ADD32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) + (opus_uint32)(b)))
+static OPUS_INLINE opus_int32 silk_ADD32_ovflw(opus_int32 a, opus_int32 b) {
+ opus_int32 _c;
+ __builtin_add_overflow(a, b, &_c);
+ return _c;
+}
+
/* Subtractss two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour
(just standard two's complement implementation-specific behaviour) */
-#define silk_SUB32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) - (opus_uint32)(b)))
+static OPUS_INLINE opus_int32 silk_SUB32_ovflw(opus_int32 a, opus_int32 b) {
+ opus_int32 _c;
+ __builtin_sub_overflow(a, b, &_c);
+ return _c;
+}
/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */
-#define silk_MLA_ovflw(a32, b32, c32) silk_ADD32_ovflw((a32), (opus_uint32)(b32) * (opus_uint32)(c32))
+/* .. also ignoring multiply overflows; caller has comment about this happening occasionally */
+static OPUS_INLINE opus_int32 silk_MLA_ovflw(opus_int32 a, opus_int32 b, opus_int32 c) {
+ opus_int32 _d, _e;
+ __builtin_mul_overflow(b, c, &_d);
+ __builtin_add_overflow(a, _d, &_e);
+ return _e;
+}
+
#define silk_SMLABB_ovflw(a32, b32, c32) (silk_ADD32_ovflw((a32) , ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32))))
#define silk_DIV32_16(a32, b16) ((opus_int32)((a32) / (b16)))
@@ -496,7 +512,12 @@ static OPUS_INLINE opus_int32 silk_ROR32( opus_int32 a32, opus_int rot )
/* Add with saturation for positive input values */
#define silk_ADD_POS_SAT8(a, b) ((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b)))
#define silk_ADD_POS_SAT16(a, b) ((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b)))
-#define silk_ADD_POS_SAT32(a, b) ((((opus_uint32)(a)+(opus_uint32)(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b)))
+static OPUS_INLINE opus_int32 silk_ADD_POS_SAT32(opus_int32 a, opus_int32 b) {
+ opus_int32 _c;
+ if (__builtin_add_overflow(a, b, &_c))
+ return silk_int32_MAX;
+ return _c;
+}
#define silk_LSHIFT8(a, shift) ((opus_int8)((opus_uint8)(a)<<(shift))) /* shift >= 0, shift < 8 */
#define silk_LSHIFT16(a, shift) ((opus_int16)((opus_uint16)(a)<<(shift))) /* shift >= 0, shift < 16 */
diff --git a/silk/macros.h b/silk/macros.h
index 3c67b6e5..00ccca31 100644
--- a/silk/macros.h
+++ b/silk/macros.h
@@ -33,6 +33,7 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
#include "opus_types.h"
+#include "typedef.h"
#include "opus_defines.h"
#include "arch.h"
@@ -96,13 +97,31 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
/* add/subtract with output saturated */
-#define silk_ADD_SAT32(a, b) ((((opus_uint32)(a) + (opus_uint32)(b)) & 0x80000000) == 0 ? \
- ((((a) & (b)) & 0x80000000) != 0 ? silk_int32_MIN : (a)+(b)) : \
- ((((a) | (b)) & 0x80000000) == 0 ? silk_int32_MAX : (a)+(b)) )
+/* use clang builtin overflow detectors */
+static OPUS_INLINE opus_int32 silk_ADD_SAT32(opus_int32 a, opus_int32 b) {
+ opus_int32 c;
+ if (__builtin_add_overflow(a, b, &c)) {
+ // overflowed
+ if (a < 0) // neg+X can only overflow towards -inf
+ c = silk_int32_MIN;
+ else
+ c = silk_int32_MAX;
+ }
+ return c;
+}
-#define silk_SUB_SAT32(a, b) ((((opus_uint32)(a)-(opus_uint32)(b)) & 0x80000000) == 0 ? \
- (( (a) & ((b)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a)-(b)) : \
- ((((a)^0x80000000) & (b) & 0x80000000) ? silk_int32_MAX : (a)-(b)) )
+/* use clang builtin overflow detectors */
+static OPUS_INLINE opus_int32 silk_SUB_SAT32(opus_int32 a, opus_int32 b) {
+ opus_int32 c;
+ if (__builtin_sub_overflow(a, b, &c)) {
+ // overflowed,
+ if (a < 0) // neg-X only overflows towards -inf
+ c = silk_int32_MIN;
+ else
+ c = silk_int32_MAX;
+ }
+ return c;
+}
#if defined(MIPSr1_ASM)
#include "mips/macros_mipsr1.h"