Commit 5c44cd7d authored by Erik de Castro Lopo's avatar Erik de Castro Lopo
Browse files

Add GCC specific optimisation for log base 2 operations.

Based on a patch from Cristian Rodríguez.
parent 238b2676
......@@ -58,10 +58,16 @@
* ilog2(17) = 4
* ilog2(18) = 4
*/
#ifndef __GNUC__
/* For GNUC, use static inline version in include/private/bitmath.h. */
unsigned FLAC__bitmath_ilog2(FLAC__uint32 v)
{
unsigned l = 0;
FLAC__ASSERT(v > 0);
unsigned l = 0;
if (v == 0)
return 0;
while(v >>= 1)
l++;
return l;
......@@ -70,11 +76,13 @@ unsigned FLAC__bitmath_ilog2(FLAC__uint32 v)
unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v)
{
unsigned l = 0;
FLAC__ASSERT(v > 0);
if (v == 0)
return 0;
while(v >>= 1)
l++;
return l;
}
#endif
/* An example of what FLAC__bitmath_silog2() computes:
*
......
......@@ -55,14 +55,24 @@ typedef FLAC__uint32 brword;
#else
#define SWAP_BE_WORD_TO_HOST(x) ENDSWAP_32(x)
#endif
#if defined(__GNUC__)
/* "int __builtin_clz (unsigned int x) If x is 0, the result is undefined" */
static inline uint32_t
COUNT_ZERO_MSBS (uint32_t word)
{
if (word == 0)
return 32;
return __builtin_clz (word);
}
#else
/* counts the # of zero MSBs in a word */
#define COUNT_ZERO_MSBS(word) ( \
(word) <= 0xffff ? \
( (word) <= 0xff? byte_to_unary_table[word] + 24 : byte_to_unary_table[(word) >> 8] + 16 ) : \
( (word) <= 0xffffff? byte_to_unary_table[word >> 16] + 8 : byte_to_unary_table[(word) >> 24] ) \
)
/* this alternate might be slightly faster on some systems/compilers: */
#define COUNT_ZERO_MSBS2(word) ( (word) <= 0xff ? byte_to_unary_table[word] + 24 : ((word) <= 0xffff ? byte_to_unary_table[(word) >> 8] + 16 : ((word) <= 0xffffff ? byte_to_unary_table[(word) >> 16] + 8 : byte_to_unary_table[(word) >> 24])) )
#endif
/*
......
......@@ -34,8 +34,30 @@
#include "FLAC/ordinals.h"
#if defined(__GNUC__)
static inline unsigned FLAC__bitmath_ilog2(FLAC__uint32 v)
{
if (v == 0)
return 0;
return sizeof(FLAC__uint32) * __CHAR_BIT__ - 1 - __builtin_clz(v);
}
static inline unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v)
{
if (v == 0)
return 0;
return sizeof(FLAC__uint64) * __CHAR_BIT__ - 1 - __builtin_clzll(v);
}
#else
unsigned FLAC__bitmath_ilog2(FLAC__uint32 v);
unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v);
#endif
unsigned FLAC__bitmath_silog2(int v);
unsigned FLAC__bitmath_silog2_wide(FLAC__int64 v);
......
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