Use gcc intrinsic for BSR. TODO: look into gcc sources for better C version
authorMathis Rosenhauer <rosenhauer@dkrz.de>
Fri, 7 Dec 2012 20:00:17 +0000 (21:00 +0100)
committerThomas Jahns <jahns@dkrz.de>
Tue, 19 Feb 2013 10:33:02 +0000 (11:33 +0100)
configure.ac
src/decode.c

index ee8980b..caab303 100644 (file)
@@ -30,6 +30,16 @@ AC_TYPE_UINT8_T
 
 # Checks for library functions.
 AC_CHECK_FUNCS([memset strstr])
+AC_MSG_CHECKING(for __builtin_clzl)
+AC_TRY_LINK([],[
+  __builtin_clzl(1);
+],[
+  AC_DEFINE(AEC_HAVE___BUILTIN_CLZL, 1, \
+  [Define to 1 if you have the '__builtin__clzl' function.])
+  AC_MSG_RESULT(yes)
+],[
+  AC_MSG_RESULT(no)
+])
 
 AC_CONFIG_FILES([Makefile         \
                  src/Makefile     \
index 4385036..739c218 100644 (file)
@@ -255,15 +255,21 @@ static inline uint32_t direct_get_fs(struct aec_stream *strm)
     uint32_t fs = 0;
     struct internal_state *state = strm->state;
 
-    if ((state->acc & ((1ULL << state->bitp) - 1)) == 0)
+    state->acc &= ((1ULL << state->bitp) - 1);
+
+    if (state->acc == 0)
         fill_acc(strm);
 
+#ifdef AEC_HAVE___BUILTIN_CLZL
+    fs = __builtin_clzll(state->acc) - (64 - state->bitp);
+    state->bitp -= fs + 1;
+#else
     state->bitp--;
     while ((state->acc & (1ULL << state->bitp)) == 0) {
         state->bitp--;
         fs++;
     }
-
+#endif
     return fs;
 }