Commit c0f050e7 authored by Jean-Marc Valin's avatar Jean-Marc Valin
Browse files

Making sure to avoid undefined behaviour

Mainly implementing signed overflow behaviour in a way that isn't
undefined in the C standard
parent c4ca21fc
......@@ -117,7 +117,7 @@ static inline opus_int32 silk_DIV32_varQ( /* O returns a good approximatio
result = SKP_SMULWB(a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */
/* Compute residual by subtracting product of denominator and first approximation */
a32_nrm -= SKP_LSHIFT_ovflw( SKP_SMMUL(b32_nrm, result), 3 ); /* Q: a_headrm */
a32_nrm -= SKP_LSHIFT( SKP_SMMUL(b32_nrm, result), 3 ); /* Q: a_headrm */
/* Refinement */
result = SKP_SMLAWB(result, a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */
......@@ -159,7 +159,7 @@ static inline opus_int32 silk_INVERSE32_varQ( /* O returns a good approxim
result = SKP_LSHIFT(b32_inv, 16); /* Q: 61 - b_headrm */
/* Compute residual by subtracting product of denominator and first approximation from one */
err_Q32 = SKP_LSHIFT_ovflw( -SKP_SMULWB(b32_nrm, b32_inv), 3 ); /* Q32 */
err_Q32 = SKP_LSHIFT( (1<<29)-SKP_SMULWB(b32_nrm, b32_inv), 3 ); /* Q32 */
/* Refinement */
result = SKP_SMLAWW(result, err_Q32, b32_inv); /* Q: 61 - b_headrm */
......
......@@ -296,14 +296,6 @@ static inline opus_int32 SKP_SMLAWW(opus_int32 a32, opus_int32 b32, opus_int32 c
#define SKP_MLA_ovflw(a32, b32, c32) ((a32) + ((b32) * (c32)))
#undef SKP_SMLABB_ovflw
#define SKP_SMLABB_ovflw(a32, b32, c32) ((a32) + ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32)))
#undef SKP_SMLABT_ovflw
#define SKP_SMLABT_ovflw(a32, b32, c32) ((a32) + ((opus_int32)((opus_int16)(b32))) * ((c32) >> 16))
#undef SKP_SMLATT_ovflw
#define SKP_SMLATT_ovflw(a32, b32, c32) ((a32) + ((b32) >> 16) * ((c32) >> 16))
#undef SKP_SMLAWB_ovflw
#define SKP_SMLAWB_ovflw(a32, b32, c32) ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16)))
#undef SKP_SMLAWT_ovflw
#define SKP_SMLAWT_ovflw(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16))
/* no checking needed for SKP_SMULL
no checking needed for SKP_SMLAL
......
......@@ -353,7 +353,7 @@ static inline void silk_noise_shape_quantizer(
NSQ->sLTP_buf_idx++;
/* Make dither dependent on quantized signal */
NSQ->rand_seed += pulses[ i ];
NSQ->rand_seed = SKP_ADD32_ovflw(NSQ->rand_seed, pulses[ i ]);
}
/* Update LPC synth buffer */
......
......@@ -398,7 +398,9 @@ static inline opus_int32 silk_ROR32( opus_int32 a32, opus_int rot )
opus_uint32 x = (opus_uint32) a32;
opus_uint32 r = (opus_uint32) rot;
opus_uint32 m = (opus_uint32) -rot;
if(rot <= 0)
if (rot==0)
return a32;
else if(rot < 0)
return (opus_int32) ((x << m) | (x >> (32 - m)));
else
return (opus_int32) ((x << (32 - r)) | (x >> r));
......@@ -440,15 +442,15 @@ static inline opus_int32 silk_ROR32( opus_int32 a32, opus_int rot )
/* (a32 * b32) */
#define SKP_SMULL(a32, b32) ((opus_int64)(a32) * /*(opus_int64)*/(b32))
/* 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 SKP_ADD32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) + (opus_uint32)(b)))
/* multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode)*/
#define SKP_MLA_ovflw(a32, b32, c32) SKP_MLA(a32, b32, c32)
#define SKP_MLA_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32),(opus_uint32)(b32) * (opus_uint32)(c32))
#ifndef SKP_SMLABB_ovflw
# define SKP_SMLABB_ovflw(a32, b32, c32) SKP_SMLABB(a32, b32, c32)
# define SKP_SMLABB_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), (opus_int32)((opus_int16)(b32)) * (opus_int32)((opus_int16)(c32)))
#endif
#define SKP_SMLABT_ovflw(a32, b32, c32) SKP_SMLABT(a32, b32, c32)
#define SKP_SMLATT_ovflw(a32, b32, c32) SKP_SMLATT(a32, b32, c32)
#define SKP_SMLAWB_ovflw(a32, b32, c32) SKP_SMLAWB(a32, b32, c32)
#define SKP_SMLAWT_ovflw(a32, b32, c32) SKP_SMLAWT(a32, b32, c32)
#define SKP_DIV32_16(a32, b16) ((opus_int32)((a32) / (b16)))
#define SKP_DIV32(a32, b32) ((opus_int32)((a32) / (b32)))
......
......@@ -73,7 +73,7 @@ void silk_decode_core(
psDec->exc_Q10[ i ] += offset_Q10;
psDec->exc_Q10[ i ] ^= SKP_RSHIFT( rand_seed, 31 );
rand_seed += pulses[ i ];
rand_seed = SKP_ADD32_ovflw(rand_seed, pulses[ i ]);
}
#ifdef SAVE_ALL_INTERNAL_DATA
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment