Replace silk_CLZ functions with EC_ILOG().
authorTimothy B. Terriberry <tterribe@xiph.org>
Mon, 20 May 2013 01:25:45 +0000 (18:25 -0700)
committerTimothy B. Terriberry <tterribe@xiph.org>
Mon, 20 May 2013 02:16:15 +0000 (19:16 -0700)
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).

silk/macros.h

index adce8a6..5161b39 100644 (file)
@@ -76,50 +76,16 @@ POSSIBILITY OF SUCH DAMAGE.
                                         (( (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 */