Opimization of mask, bitfieldInsert, bitfieldExtract and bitCount

This commit is contained in:
Christophe Riccio
2014-10-25 21:16:49 +02:00
parent eb915ed808
commit 0c522117c8
6 changed files with 222 additions and 58 deletions

View File

@@ -39,8 +39,15 @@
#endif//(GLM_ARCH != GLM_ARCH_PURE)
#include <limits>
namespace glm
namespace glm{
namespace detail
{
GLM_FUNC_QUALIFIER int mask(int Bits)
{
return Bits >= 32 ? 0xffffffff : (static_cast<int>(1) << Bits) - static_cast<int>(1);
}
}//namespace detail
// uaddCarry
GLM_FUNC_QUALIFIER uint uaddCarry(uint const & x, uint const & y, uint & Carry)
{
@@ -139,16 +146,8 @@ namespace glm
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_integer, "'bitfieldExtract' only accept integer inputs");
int GenSize = int(sizeof(T)) << int(3);
assert(Offset + Bits <= GenSize);
vecType<T, P> ShiftLeft(0);
if(Bits)
ShiftLeft = Value << static_cast<T>(GenSize - (Bits + Offset));
vecType<T, P> const ShiftBack = ShiftLeft >> static_cast<T>(GenSize - Bits);
return ShiftBack;
int const Mask = detail::mask(Bits);
return (Value >> static_cast<T>(Offset)) & static_cast<T>(Mask);
}
// bitfieldInsert
@@ -163,13 +162,7 @@ namespace glm
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_integer, "'bitfieldInsert' only accept integer values");
if(Bits == 0)
return Base;
vecType<T, P> Mask(0);
for(int Bit = Offset; Bit < Offset + Bits; ++Bit)
Mask |= (static_cast<int>(1) << Bit);
T Mask = static_cast<T>(detail::mask(Bits) << Offset);
return (Base & ~Mask) | (Insert & Mask);
}
@@ -186,7 +179,6 @@ namespace glm
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_integer, "'bitfieldReverse' only accept integer values");
vecType<T, P> Result(0);
vecType<T, P> const Null(0);
T const BitSize = static_cast<T>(sizeof(T) * 8);
for(T i = 0; i < BitSize; ++i)
{
@@ -210,11 +202,8 @@ namespace glm
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_integer, "'bitCount' only accept integer values");
vecType<int, P> Count(0);
for(std::size_t i = 0; i < sizeof(T) * std::size_t(8); ++i)
{
if(v & (static_cast<T>(1) << i))
++Count;
}
for(T i = 0, n = static_cast<T>(sizeof(T) * 8); i < n; ++i)
Count += vecType<int, P>((v >> i) & static_cast<T>(1));
return Count;
}

View File

@@ -41,6 +41,7 @@
// Dependencies
#include "../detail/type_int.hpp"
#include "../detail/setup.hpp"
#include "../detail/precision.hpp"
#include <cstddef>
#if(defined(GLM_MESSAGES) && !defined(GLM_EXT_INCLUDED))
@@ -54,8 +55,10 @@ namespace glm
/// Build a mask of 'count' bits
/// @see gtx_bit
template <typename genIType>
GLM_FUNC_DECL genIType mask(genIType const & count);
GLM_FUNC_DECL int mask(int Bits);
template <precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<int, P> mask(vecType<int, P> const & v);
//! Find the highest bit set to 1 in a integer variable and return its value.
/// @see gtx_bit

View File

@@ -12,16 +12,16 @@
namespace glm
{
template <typename genIType>
GLM_FUNC_QUALIFIER genIType mask
(
genIType const & count
)
GLM_FUNC_QUALIFIER int mask(int Bits)
{
return ((genIType(1) << (count)) - genIType(1));
return Bits >= sizeof(Bits) * 8 ? ~static_cast<int>(0) : (static_cast<int>(1) << Bits) - static_cast<int>(1);
}
VECTORIZE_VEC(mask)
template <precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<int, P> mask(vecType<int, P> const & v)
{
return detail::functor1<int, int, P, vecType>::call(mask, v);
}
// highestBitValue
template <typename genType>