ref: 94a4989cdbb07e310d3e9486fa3e81a8b2e68bf9
parent: 367c39486618fe6a6f9ffe85e834d59cae241253
author: Jean-Marc Valin <[email protected]>
date: Thu Apr 12 12:35:19 EDT 2012
Makes silk_ADD_SAT32() conform to the C standard This changes the saturation test to ensure that it relies on the unsigned overflow behaviour (which is allowed) rather than the signed overflow behaviour (which is undefined).
--- a/silk/MacroDebug.h
+++ b/silk/MacroDebug.h
@@ -98,7 +98,7 @@
#undef silk_ADD_SAT32
static inline opus_int32 silk_ADD_SAT32(opus_int32 a32, opus_int32 b32){
opus_int32 res;
- res = ((((a32) + (b32)) & 0x80000000) == 0 ? \
+ res = ((((opus_uint32)(a32) + (opus_uint32)(b32)) & 0x80000000) == 0 ? \
((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \
((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) );
silk_assert( res == silk_SAT32( (opus_int64)a32 + (opus_int64)b32 ) );
@@ -133,7 +133,7 @@
#undef silk_SUB_SAT32
static inline opus_int32 silk_SUB_SAT32( opus_int32 a32, opus_int32 b32 ) {
opus_int32 res;
- res = ((((a32)-(b32)) & 0x80000000) == 0 ? \
+ res = ((((opus_uint32)(a32)-(opus_uint32)(b32)) & 0x80000000) == 0 ? \
(( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \
((((a32)^0x80000000) & (b32) & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) );
silk_assert( res == silk_SAT32( (opus_int64)a32 - (opus_int64)b32 ) );
--- a/silk/macros.h
+++ b/silk/macros.h
@@ -68,11 +68,11 @@
#define silk_SMLAWW(a32, b32, c32) silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16))
/* add/subtract with output saturated */
-#define silk_ADD_SAT32(a, b) ((((a) + (b)) & 0x80000000) == 0 ? \
+#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)) )
-#define silk_SUB_SAT32(a, b) ((((a)-(b)) & 0x80000000) == 0 ? \
+#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)) )