Fixed findMSB generic path

This commit is contained in:
Christophe Riccio
2012-09-13 00:43:46 +02:00
parent a2ba0ea86f
commit 8a7d6080d1
2 changed files with 138 additions and 35 deletions

View File

@@ -522,39 +522,9 @@ namespace glm
}
// findMSB
/*
#if((GLM_ARCH != GLM_ARCH_PURE) && (GLM_COMPILER & GLM_COMPILER_VC))
template <typename genIUType>
GLM_FUNC_QUALIFIER int findMSB
(
genIUType const & Value
)
{
unsigned long Result(0);
_BitScanReverse(&Result, Value);
return int(Result);
}
#elif((GLM_ARCH != GLM_ARCH_PURE) && (GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC40))
template <typename genIUType>
GLM_FUNC_QUALIFIER int findMSB
(
genIUType const & Value
)
{
/**
* clz returns the number or trailing 0-bits; see
* http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Other-Builtins.html
*
* NoteBecause __builtin_clz only works for unsigned ints, this
* implementation will not work for 64-bit integers.
*/
return 31 - __builtin_clz(Value);
}
#else
template <typename genIUType>
GLM_FUNC_QUALIFIER int findMSB
(
@@ -565,11 +535,61 @@ namespace glm
if(Value == 0)
return -1;
genIUType bit = genIUType(-1);
for(genIUType tmp = Value; tmp; tmp >>= 1, ++bit){}
return bit;
unsigned long Result(0);
_BitScanReverse(&Result, Value);
return int(Result);
}
#endif//(GLM_COMPILER)
// __builtin_clz seems to be buggy as it crasks for some values, from 0x00200000 to 80000000
#elif((GLM_ARCH != GLM_ARCH_PURE) && (GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC40))
template <typename genIUType>
GLM_FUNC_QUALIFIER int findMSB
(
genIUType const & Value
)
{
GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'findMSB' only accept integer values");
if(Value == 0)
return -1;
// clz returns the number or trailing 0-bits; see
// http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Other-Builtins.html
//
// NoteBecause __builtin_clz only works for unsigned ints, this
// implementation will not work for 64-bit integers.
//
return 31 - __builtin_clzl(Value);
}
#else
*/
template <typename genIUType>
GLM_FUNC_QUALIFIER int findMSB
(
genIUType const & Value
)
{
GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'findMSB' only accept integer values");
if(Value == 0 || Value == -1)
return -1;
else if(Value > 0)
{
genIUType Bit = genIUType(-1);
for(genIUType tmp = Value; tmp > 0; tmp >>= 1, ++Bit){}
return Bit;
}
else //if(Value < 0)
{
int const BitCount(sizeof(genIUType) * 8);
int MostSignificantBit(-1);
for(int BitIndex(0); BitIndex < BitCount; ++BitIndex)
MostSignificantBit = (Value & (1 << BitIndex)) ? MostSignificantBit : BitIndex;
assert(MostSignificantBit >= 0);
return MostSignificantBit;
}
}
//#endif//(GLM_COMPILER)
template <typename T>
GLM_FUNC_QUALIFIER detail::tvec2<int> findMSB