shithub: opus

Download patch

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 */