Skip to content
Snippets Groups Projects
Commit 94a4989c authored by Jean-Marc Valin's avatar Jean-Marc Valin
Browse files

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).
parent 367c3948
No related branches found
No related tags found
No related merge requests found
...@@ -98,7 +98,7 @@ static inline opus_int16 silk_ADD_SAT16( opus_int16 a16, opus_int16 b16 ) { ...@@ -98,7 +98,7 @@ static inline opus_int16 silk_ADD_SAT16( opus_int16 a16, opus_int16 b16 ) {
#undef silk_ADD_SAT32 #undef silk_ADD_SAT32
static inline opus_int32 silk_ADD_SAT32(opus_int32 a32, opus_int32 b32){ static inline opus_int32 silk_ADD_SAT32(opus_int32 a32, opus_int32 b32){
opus_int32 res; 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_MIN : (a32)+(b32)) : \
((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) ); ((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) );
silk_assert( res == silk_SAT32( (opus_int64)a32 + (opus_int64)b32 ) ); silk_assert( res == silk_SAT32( (opus_int64)a32 + (opus_int64)b32 ) );
...@@ -133,7 +133,7 @@ static inline opus_int16 silk_SUB_SAT16( opus_int16 a16, opus_int16 b16 ) { ...@@ -133,7 +133,7 @@ static inline opus_int16 silk_SUB_SAT16( opus_int16 a16, opus_int16 b16 ) {
#undef silk_SUB_SAT32 #undef silk_SUB_SAT32
static inline opus_int32 silk_SUB_SAT32( opus_int32 a32, opus_int32 b32 ) { static inline opus_int32 silk_SUB_SAT32( opus_int32 a32, opus_int32 b32 ) {
opus_int32 res; 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) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \
((((a32)^0x80000000) & (b32) & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) ); ((((a32)^0x80000000) & (b32) & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) );
silk_assert( res == silk_SAT32( (opus_int64)a32 - (opus_int64)b32 ) ); silk_assert( res == silk_SAT32( (opus_int64)a32 - (opus_int64)b32 ) );
......
...@@ -68,11 +68,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ...@@ -68,11 +68,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define silk_SMLAWW(a32, b32, c32) silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16)) #define silk_SMLAWW(a32, b32, c32) silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16))
/* add/subtract with output saturated */ /* 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_MIN : (a)+(b)) : \
((((a) | (b)) & 0x80000000) == 0 ? silk_int32_MAX : (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) & ((b)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a)-(b)) : \
((((a)^0x80000000) & (b) & 0x80000000) ? silk_int32_MAX : (a)-(b)) ) ((((a)^0x80000000) & (b) & 0x80000000) ? silk_int32_MAX : (a)-(b)) )
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment