ref: a16cef62255a83ba9c9cbf2951f3e8503987910a
parent: 80ad38370c299edb50a229597114d5bfbf88feb6
author: Timothy B. Terriberry <[email protected]>
date: Sun May 19 14:25:45 EDT 2013
Replace silk_CLZ functions with EC_ILOG(). In most cases these will use __builtin_clz(). In a follow-up, we should audit usage of silk_CLZ32() and convert the places where its argument must be non-zero to use EC_ILOG() directly to avoid the test for zero (which is necessary on x86).
--- a/silk/macros.h
+++ b/silk/macros.h
@@ -76,50 +76,16 @@
(( (a) & ((b)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a)-(b)) : \
((((a)^0x80000000) & (b) & 0x80000000) ? silk_int32_MAX : (a)-(b)) )
+#include "ecintrin.h"
+
static inline opus_int32 silk_CLZ16(opus_int16 in16)
{
- opus_int32 out32 = 0;
- if( in16 == 0 ) {
- return 16;
- }
- /* test nibbles */
- if( in16 & 0xFF00 ) {
- if( in16 & 0xF000 ) {
- in16 >>= 12;
- } else {
- out32 += 4;
- in16 >>= 8;
- }
- } else {
- if( in16 & 0xFFF0 ) {
- out32 += 8;
- in16 >>= 4;
- } else {
- out32 += 12;
- }
- }
- /* test bits and return */
- if( in16 & 0xC ) {
- if( in16 & 0x8 )
- return out32 + 0;
- else
- return out32 + 1;
- } else {
- if( in16 & 0xE )
- return out32 + 2;
- else
- return out32 + 3;
- }
+ return 32 - EC_ILOG(in16<<16|0x8000);
}
static inline opus_int32 silk_CLZ32(opus_int32 in32)
{
- /* test highest 16 bits and convert to opus_int16 */
- if( in32 & 0xFFFF0000 ) {
- return silk_CLZ16((opus_int16)(in32 >> 16));
- } else {
- return silk_CLZ16((opus_int16)in32) + 16;
- }
+ return in32 ? 32 - EC_ILOG(in32) : 0;
}
/* Row based */