Home | History | Annotate | Download | only in gtx
      1 ///////////////////////////////////////////////////////////////////////////////////////////////////
      2 // OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
      3 ///////////////////////////////////////////////////////////////////////////////////////////////////
      4 // Created : 2007-03-14
      5 // Updated : 2013-12-25
      6 // Licence : This source is under MIT License
      7 // File    : glm/gtx/bit.inl
      8 ///////////////////////////////////////////////////////////////////////////////////////////////////
      9 
     10 #include "../detail/_vectorize.hpp"
     11 #include <limits>
     12 
     13 namespace glm
     14 {
     15 	template <typename genIType>
     16 	GLM_FUNC_QUALIFIER genIType mask
     17 	(
     18 		genIType const & count
     19 	)
     20 	{
     21 		return ((genIType(1) << (count)) - genIType(1));
     22 	}
     23 
     24 	VECTORIZE_VEC(mask)
     25 
     26 	// highestBitValue
     27 	template <typename genType>
     28 	GLM_FUNC_QUALIFIER genType highestBitValue
     29 	(
     30 		genType const & value
     31 	)
     32 	{
     33 		genType tmp = value;
     34 		genType result = genType(0);
     35 		while(tmp)
     36 		{
     37 			result = (tmp & (~tmp + 1)); // grab lowest bit
     38 			tmp &= ~result; // clear lowest bit
     39 		}
     40 		return result;
     41 	}
     42 
     43 	template <typename T, precision P>
     44 	GLM_FUNC_QUALIFIER detail::tvec2<int, P> highestBitValue
     45 	(
     46 		detail::tvec2<T, P> const & value
     47 	)
     48 	{
     49 		return detail::tvec2<int, P>(
     50 			highestBitValue(value[0]),
     51 			highestBitValue(value[1]));
     52 	}
     53 
     54 	template <typename T, precision P>
     55 	GLM_FUNC_QUALIFIER detail::tvec3<int, P> highestBitValue
     56 	(
     57 		detail::tvec3<T, P> const & value
     58 	)
     59 	{
     60 		return detail::tvec3<int, P>(
     61 			highestBitValue(value[0]),
     62 			highestBitValue(value[1]),
     63 			highestBitValue(value[2]));
     64 	}
     65 
     66 	template <typename T, precision P>
     67 	GLM_FUNC_QUALIFIER detail::tvec4<int, P> highestBitValue
     68 	(
     69 		detail::tvec4<T, P> const & value
     70 	)
     71 	{
     72 		return detail::tvec4<int, P>(
     73 			highestBitValue(value[0]),
     74 			highestBitValue(value[1]),
     75 			highestBitValue(value[2]),
     76 			highestBitValue(value[3]));
     77 	}
     78 
     79 	// isPowerOfTwo
     80 	template <typename genType>
     81 	GLM_FUNC_QUALIFIER bool isPowerOfTwo(genType const & Value)
     82 	{
     83 		//detail::If<std::numeric_limits<genType>::is_signed>::apply(abs, Value);
     84 		//return !(Value & (Value - 1));
     85 
     86 		// For old complier?
     87 		genType Result = Value;
     88 		if(std::numeric_limits<genType>::is_signed)
     89 			Result = abs(Result);
     90 		return !(Result & (Result - 1));
     91 	}
     92 
     93 	template <typename T, precision P>
     94 	GLM_FUNC_QUALIFIER detail::tvec2<bool, P> isPowerOfTwo
     95 	(
     96 		detail::tvec2<T, P> const & value
     97 	)
     98 	{
     99 		return detail::tvec2<bool, P>(
    100 			isPowerOfTwo(value[0]),
    101 			isPowerOfTwo(value[1]));
    102 	}
    103 
    104 	template <typename T, precision P>
    105 	GLM_FUNC_QUALIFIER detail::tvec3<bool, P> isPowerOfTwo
    106 	(
    107 		detail::tvec3<T, P> const & value
    108 	)
    109 	{
    110 		return detail::tvec3<bool, P>(
    111 			isPowerOfTwo(value[0]),
    112 			isPowerOfTwo(value[1]),
    113 			isPowerOfTwo(value[2]));
    114 	}
    115 
    116 	template <typename T, precision P>
    117 	GLM_FUNC_QUALIFIER detail::tvec4<bool, P> isPowerOfTwo
    118 	(
    119 		detail::tvec4<T, P> const & value
    120 	)
    121 	{
    122 		return detail::tvec4<bool, P>(
    123 			isPowerOfTwo(value[0]),
    124 			isPowerOfTwo(value[1]),
    125 			isPowerOfTwo(value[2]),
    126 			isPowerOfTwo(value[3]));
    127 	}
    128 
    129 	// powerOfTwoAbove
    130 	template <typename genType>
    131 	GLM_FUNC_QUALIFIER genType powerOfTwoAbove(genType const & value)
    132 	{
    133 		return isPowerOfTwo(value) ? value : highestBitValue(value) << 1;
    134 	}
    135 
    136 	VECTORIZE_VEC(powerOfTwoAbove)
    137 
    138 	// powerOfTwoBelow
    139 	template <typename genType>
    140 	GLM_FUNC_QUALIFIER genType powerOfTwoBelow
    141 	(
    142 		genType const & value
    143 	)
    144 	{
    145 		return isPowerOfTwo(value) ? value : highestBitValue(value);
    146 	}
    147 
    148 	VECTORIZE_VEC(powerOfTwoBelow)
    149 
    150 	// powerOfTwoNearest
    151 	template <typename genType>
    152 	GLM_FUNC_QUALIFIER genType powerOfTwoNearest
    153 	(
    154 		genType const & value
    155 	)
    156 	{
    157 		if(isPowerOfTwo(value))
    158 			return value;
    159 
    160 		genType prev = highestBitValue(value);
    161 		genType next = prev << 1;
    162 		return (next - value) < (value - prev) ? next : prev;
    163 	}
    164 
    165 	VECTORIZE_VEC(powerOfTwoNearest)
    166 
    167 	template <typename genType>
    168 	GLM_FUNC_QUALIFIER genType bitRevert(genType const & In)
    169 	{
    170 		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRevert' only accept integer values");
    171 
    172 		genType Out = 0;
    173 		std::size_t BitSize = sizeof(genType) * 8;
    174 		for(std::size_t i = 0; i < BitSize; ++i)
    175 			if(In & (genType(1) << i))
    176 				Out |= genType(1) << (BitSize - 1 - i);
    177 		return Out;
    178 	}
    179 
    180 	VECTORIZE_VEC(bitRevert)
    181 
    182 	template <typename genType>
    183 	GLM_FUNC_QUALIFIER genType bitRotateRight(genType const & In, std::size_t Shift)
    184 	{
    185 		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateRight' only accept integer values");
    186 
    187 		std::size_t BitSize = sizeof(genType) * 8;
    188 		return (In << Shift) | (In >> (BitSize - Shift));
    189 	}
    190 
    191 	template <typename T, precision P>
    192 	GLM_FUNC_QUALIFIER detail::tvec2<T, P> bitRotateRight
    193 	(
    194 		detail::tvec2<T, P> const & Value, 
    195 		std::size_t Shift
    196 	)
    197 	{
    198 		return detail::tvec2<T, P>(
    199 			bitRotateRight(Value[0], Shift),
    200 			bitRotateRight(Value[1], Shift));
    201 	}
    202 
    203 	template <typename T, precision P>
    204 	GLM_FUNC_QUALIFIER detail::tvec3<T, P> bitRotateRight
    205 	(
    206 		detail::tvec3<T, P> const & Value, 
    207 		std::size_t Shift
    208 	)
    209 	{
    210 		return detail::tvec3<T, P>(
    211 			bitRotateRight(Value[0], Shift),
    212 			bitRotateRight(Value[1], Shift),
    213 			bitRotateRight(Value[2], Shift));
    214 	}
    215 
    216 	template <typename T, precision P>
    217 	GLM_FUNC_QUALIFIER detail::tvec4<T, P> bitRotateRight
    218 	(
    219 		detail::tvec4<T, P> const & Value, 
    220 		std::size_t Shift
    221 	)
    222 	{
    223 		return detail::tvec4<T, P>(
    224 			bitRotateRight(Value[0], Shift),
    225 			bitRotateRight(Value[1], Shift),
    226 			bitRotateRight(Value[2], Shift),
    227 			bitRotateRight(Value[3], Shift));
    228 	}
    229 
    230 	template <typename genType>
    231 	GLM_FUNC_QUALIFIER genType bitRotateLeft(genType const & In, std::size_t Shift)
    232 	{
    233 		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateLeft' only accept integer values");
    234 
    235 		std::size_t BitSize = sizeof(genType) * 8;
    236 		return (In >> Shift) | (In << (BitSize - Shift));
    237 	}
    238 
    239 	template <typename T, precision P>
    240 	GLM_FUNC_QUALIFIER detail::tvec2<T, P> bitRotateLeft
    241 	(
    242 		detail::tvec2<T, P> const & Value, 
    243 		std::size_t Shift
    244 	)
    245 	{
    246 		return detail::tvec2<T, P>(
    247 			bitRotateLeft(Value[0], Shift),
    248 			bitRotateLeft(Value[1], Shift));
    249 	}
    250 
    251 	template <typename T, precision P>
    252 	GLM_FUNC_QUALIFIER detail::tvec3<T, P> bitRotateLeft
    253 	(
    254 		detail::tvec3<T, P> const & Value, 
    255 		std::size_t Shift
    256 	)
    257 	{
    258 		return detail::tvec3<T, P>(
    259 			bitRotateLeft(Value[0], Shift),
    260 			bitRotateLeft(Value[1], Shift),
    261 			bitRotateLeft(Value[2], Shift));
    262 	}
    263 
    264 	template <typename T, precision P>
    265 	GLM_FUNC_QUALIFIER detail::tvec4<T, P> bitRotateLeft
    266 	(
    267 		detail::tvec4<T, P> const & Value, 
    268 		std::size_t Shift
    269 	)
    270 	{
    271 		return detail::tvec4<T, P>(
    272 			bitRotateLeft(Value[0], Shift),
    273 			bitRotateLeft(Value[1], Shift),
    274 			bitRotateLeft(Value[2], Shift),
    275 			bitRotateLeft(Value[3], Shift));
    276 	}
    277 
    278 	template <typename genIUType>
    279 	GLM_FUNC_QUALIFIER genIUType fillBitfieldWithOne
    280 	(
    281 		genIUType const & Value,
    282 		int const & FromBit, 
    283 		int const & ToBit
    284 	)
    285 	{
    286 		assert(FromBit <= ToBit);
    287 		assert(ToBit <= sizeof(genIUType) * std::size_t(8));
    288 
    289 		genIUType Result = Value;
    290 		for(std::size_t i = 0; i <= ToBit; ++i)
    291 			Result |= (1 << i);
    292 		return Result;
    293 	}
    294 
    295 	template <typename genIUType>
    296 	GLM_FUNC_QUALIFIER genIUType fillBitfieldWithZero
    297 	(
    298 		genIUType const & Value,
    299 		int const & FromBit, 
    300 		int const & ToBit
    301 	)
    302 	{
    303 		assert(FromBit <= ToBit);
    304 		assert(ToBit <= sizeof(genIUType) * std::size_t(8));
    305 
    306 		genIUType Result = Value;
    307 		for(std::size_t i = 0; i <= ToBit; ++i)
    308 			Result &= ~(1 << i);
    309 		return Result;
    310 	}
    311 
    312 	namespace detail
    313 	{
    314 		template <typename PARAM, typename RET>
    315 		GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y);
    316 
    317 		template <typename PARAM, typename RET>
    318 		GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z);
    319 
    320 		template <typename PARAM, typename RET>
    321 		GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z, PARAM w);
    322 
    323 /*
    324 		template <typename PARAM, typename RET>
    325 		inline RET bitfieldInterleave(PARAM x, PARAM y)
    326 		{
    327 			RET Result = 0; 
    328 			for (int i = 0; i < sizeof(PARAM) * 8; i++)
    329 				Result |= (x & 1U << i) << i | (y & 1U << i) << (i + 1);
    330 			return Result;
    331 		}
    332 
    333 		template <typename PARAM, typename RET>
    334 		inline RET bitfieldInterleave(PARAM x, PARAM y, PARAM z)
    335 		{
    336 			RET Result = 0; 
    337 			for (RET i = 0; i < sizeof(PARAM) * 8; i++)
    338 			{
    339 				Result |= ((RET(x) & (RET(1) << i)) << ((i << 1) + 0));
    340 				Result |= ((RET(y) & (RET(1) << i)) << ((i << 1) + 1));
    341 				Result |= ((RET(z) & (RET(1) << i)) << ((i << 1) + 2));
    342 			}
    343 			return Result;
    344 		}
    345 
    346 		template <typename PARAM, typename RET>
    347 		inline RET bitfieldInterleave(PARAM x, PARAM y, PARAM z, PARAM w)
    348 		{
    349 			RET Result = 0; 
    350 			for (int i = 0; i < sizeof(PARAM) * 8; i++)
    351 			{
    352 				Result |= ((((RET(x) >> i) & RET(1))) << RET((i << 2) + 0));
    353 				Result |= ((((RET(y) >> i) & RET(1))) << RET((i << 2) + 1));
    354 				Result |= ((((RET(z) >> i) & RET(1))) << RET((i << 2) + 2));
    355 				Result |= ((((RET(w) >> i) & RET(1))) << RET((i << 2) + 3));
    356 			}
    357 			return Result;
    358 		}
    359 */
    360 		template <>
    361 		GLM_FUNC_QUALIFIER glm::uint16 bitfieldInterleave(glm::uint8 x, glm::uint8 y)
    362 		{
    363 			glm::uint16 REG1(x);
    364 			glm::uint16 REG2(y);
    365 
    366 			REG1 = ((REG1 <<  4) | REG1) & glm::uint16(0x0F0F);
    367 			REG2 = ((REG2 <<  4) | REG2) & glm::uint16(0x0F0F);
    368 
    369 			REG1 = ((REG1 <<  2) | REG1) & glm::uint16(0x3333);
    370 			REG2 = ((REG2 <<  2) | REG2) & glm::uint16(0x3333);
    371 
    372 			REG1 = ((REG1 <<  1) | REG1) & glm::uint16(0x5555);
    373 			REG2 = ((REG2 <<  1) | REG2) & glm::uint16(0x5555);
    374 
    375 			return REG1 | (REG2 << 1);
    376 		}
    377 
    378 		template <>
    379 		GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint16 x, glm::uint16 y)
    380 		{
    381 			glm::uint32 REG1(x);
    382 			glm::uint32 REG2(y);
    383 
    384 			REG1 = ((REG1 <<  8) | REG1) & glm::uint32(0x00FF00FF);
    385 			REG2 = ((REG2 <<  8) | REG2) & glm::uint32(0x00FF00FF);
    386 
    387 			REG1 = ((REG1 <<  4) | REG1) & glm::uint32(0x0F0F0F0F);
    388 			REG2 = ((REG2 <<  4) | REG2) & glm::uint32(0x0F0F0F0F);
    389 
    390 			REG1 = ((REG1 <<  2) | REG1) & glm::uint32(0x33333333);
    391 			REG2 = ((REG2 <<  2) | REG2) & glm::uint32(0x33333333);
    392 
    393 			REG1 = ((REG1 <<  1) | REG1) & glm::uint32(0x55555555);
    394 			REG2 = ((REG2 <<  1) | REG2) & glm::uint32(0x55555555);
    395 
    396 			return REG1 | (REG2 << 1);
    397 		}
    398 
    399 		template <>
    400 		GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y)
    401 		{
    402 			glm::uint64 REG1(x);
    403 			glm::uint64 REG2(y);
    404 
    405 			REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF);
    406 			REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF);
    407 
    408 			REG1 = ((REG1 <<  8) | REG1) & glm::uint64(0x00FF00FF00FF00FF);
    409 			REG2 = ((REG2 <<  8) | REG2) & glm::uint64(0x00FF00FF00FF00FF);
    410 
    411 			REG1 = ((REG1 <<  4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F);
    412 			REG2 = ((REG2 <<  4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F);
    413 
    414 			REG1 = ((REG1 <<  2) | REG1) & glm::uint64(0x3333333333333333);
    415 			REG2 = ((REG2 <<  2) | REG2) & glm::uint64(0x3333333333333333);
    416 
    417 			REG1 = ((REG1 <<  1) | REG1) & glm::uint64(0x5555555555555555);
    418 			REG2 = ((REG2 <<  1) | REG2) & glm::uint64(0x5555555555555555);
    419 
    420 			return REG1 | (REG2 << 1);
    421 		}
    422 
    423 		template <>
    424 		GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z)
    425 		{
    426 			glm::uint32 REG1(x);
    427 			glm::uint32 REG2(y);
    428 			glm::uint32 REG3(z);
    429 			
    430 			REG1 = ((REG1 << 16) | REG1) & glm::uint32(0x00FF0000FF0000FF);
    431 			REG2 = ((REG2 << 16) | REG2) & glm::uint32(0x00FF0000FF0000FF);
    432 			REG3 = ((REG3 << 16) | REG3) & glm::uint32(0x00FF0000FF0000FF);
    433 			
    434 			REG1 = ((REG1 <<  8) | REG1) & glm::uint32(0xF00F00F00F00F00F);
    435 			REG2 = ((REG2 <<  8) | REG2) & glm::uint32(0xF00F00F00F00F00F);
    436 			REG3 = ((REG3 <<  8) | REG3) & glm::uint32(0xF00F00F00F00F00F);
    437 			
    438 			REG1 = ((REG1 <<  4) | REG1) & glm::uint32(0x30C30C30C30C30C3);
    439 			REG2 = ((REG2 <<  4) | REG2) & glm::uint32(0x30C30C30C30C30C3);
    440 			REG3 = ((REG3 <<  4) | REG3) & glm::uint32(0x30C30C30C30C30C3);
    441 			
    442 			REG1 = ((REG1 <<  2) | REG1) & glm::uint32(0x9249249249249249);
    443 			REG2 = ((REG2 <<  2) | REG2) & glm::uint32(0x9249249249249249);
    444 			REG3 = ((REG3 <<  2) | REG3) & glm::uint32(0x9249249249249249);
    445 			
    446 			return REG1 | (REG2 << 1) | (REG3 << 2);
    447 		}
    448 		
    449 		template <>
    450 		GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z)
    451 		{
    452 			glm::uint64 REG1(x);
    453 			glm::uint64 REG2(y);
    454 			glm::uint64 REG3(z);
    455 			
    456 			REG1 = ((REG1 << 32) | REG1) & glm::uint64(0xFFFF00000000FFFF);
    457 			REG2 = ((REG2 << 32) | REG2) & glm::uint64(0xFFFF00000000FFFF);
    458 			REG3 = ((REG3 << 32) | REG3) & glm::uint64(0xFFFF00000000FFFF);
    459 			
    460 			REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x00FF0000FF0000FF);
    461 			REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x00FF0000FF0000FF);
    462 			REG3 = ((REG3 << 16) | REG3) & glm::uint64(0x00FF0000FF0000FF);
    463 			
    464 			REG1 = ((REG1 <<  8) | REG1) & glm::uint64(0xF00F00F00F00F00F);
    465 			REG2 = ((REG2 <<  8) | REG2) & glm::uint64(0xF00F00F00F00F00F);
    466 			REG3 = ((REG3 <<  8) | REG3) & glm::uint64(0xF00F00F00F00F00F);
    467 			
    468 			REG1 = ((REG1 <<  4) | REG1) & glm::uint64(0x30C30C30C30C30C3);
    469 			REG2 = ((REG2 <<  4) | REG2) & glm::uint64(0x30C30C30C30C30C3);
    470 			REG3 = ((REG3 <<  4) | REG3) & glm::uint64(0x30C30C30C30C30C3);
    471 			
    472 			REG1 = ((REG1 <<  2) | REG1) & glm::uint64(0x9249249249249249);
    473 			REG2 = ((REG2 <<  2) | REG2) & glm::uint64(0x9249249249249249);
    474 			REG3 = ((REG3 <<  2) | REG3) & glm::uint64(0x9249249249249249);
    475 			
    476 			return REG1 | (REG2 << 1) | (REG3 << 2);
    477 		}
    478 		
    479 		template <>
    480 		GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y, glm::uint32 z)
    481 		{
    482 			glm::uint64 REG1(x);
    483 			glm::uint64 REG2(y);
    484 			glm::uint64 REG3(z);
    485 
    486 			REG1 = ((REG1 << 32) | REG1) & glm::uint64(0xFFFF00000000FFFF);
    487 			REG2 = ((REG2 << 32) | REG2) & glm::uint64(0xFFFF00000000FFFF);
    488 			REG3 = ((REG3 << 32) | REG3) & glm::uint64(0xFFFF00000000FFFF);
    489 
    490 			REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x00FF0000FF0000FF);
    491 			REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x00FF0000FF0000FF);
    492 			REG3 = ((REG3 << 16) | REG3) & glm::uint64(0x00FF0000FF0000FF);
    493 
    494 			REG1 = ((REG1 <<  8) | REG1) & glm::uint64(0xF00F00F00F00F00F);
    495 			REG2 = ((REG2 <<  8) | REG2) & glm::uint64(0xF00F00F00F00F00F);
    496 			REG3 = ((REG3 <<  8) | REG3) & glm::uint64(0xF00F00F00F00F00F);
    497 
    498 			REG1 = ((REG1 <<  4) | REG1) & glm::uint64(0x30C30C30C30C30C3);
    499 			REG2 = ((REG2 <<  4) | REG2) & glm::uint64(0x30C30C30C30C30C3);
    500 			REG3 = ((REG3 <<  4) | REG3) & glm::uint64(0x30C30C30C30C30C3);
    501 
    502 			REG1 = ((REG1 <<  2) | REG1) & glm::uint64(0x9249249249249249);
    503 			REG2 = ((REG2 <<  2) | REG2) & glm::uint64(0x9249249249249249);
    504 			REG3 = ((REG3 <<  2) | REG3) & glm::uint64(0x9249249249249249);
    505 
    506 			return REG1 | (REG2 << 1) | (REG3 << 2);
    507 		}
    508 
    509 		template <>
    510 		GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z, glm::uint8 w)
    511 		{
    512 			glm::uint32 REG1(x);
    513 			glm::uint32 REG2(y);
    514 			glm::uint32 REG3(z);
    515 			glm::uint32 REG4(w);
    516 			
    517 			REG1 = ((REG1 << 12) | REG1) & glm::uint32(0x000F000F000F000F);
    518 			REG2 = ((REG2 << 12) | REG2) & glm::uint32(0x000F000F000F000F);
    519 			REG3 = ((REG3 << 12) | REG3) & glm::uint32(0x000F000F000F000F);
    520 			REG4 = ((REG4 << 12) | REG4) & glm::uint32(0x000F000F000F000F);
    521 			
    522 			REG1 = ((REG1 <<  6) | REG1) & glm::uint32(0x0303030303030303);
    523 			REG2 = ((REG2 <<  6) | REG2) & glm::uint32(0x0303030303030303);
    524 			REG3 = ((REG3 <<  6) | REG3) & glm::uint32(0x0303030303030303);
    525 			REG4 = ((REG4 <<  6) | REG4) & glm::uint32(0x0303030303030303);
    526 			
    527 			REG1 = ((REG1 <<  3) | REG1) & glm::uint32(0x1111111111111111);
    528 			REG2 = ((REG2 <<  3) | REG2) & glm::uint32(0x1111111111111111);
    529 			REG3 = ((REG3 <<  3) | REG3) & glm::uint32(0x1111111111111111);
    530 			REG4 = ((REG4 <<  3) | REG4) & glm::uint32(0x1111111111111111);
    531 			
    532 			return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3);
    533 		}
    534 		
    535 		template <>
    536 		GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z, glm::uint16 w)
    537 		{
    538 			glm::uint64 REG1(x);
    539 			glm::uint64 REG2(y);
    540 			glm::uint64 REG3(z);
    541 			glm::uint64 REG4(w);
    542 
    543 			REG1 = ((REG1 << 24) | REG1) & glm::uint64(0x000000FF000000FF);
    544 			REG2 = ((REG2 << 24) | REG2) & glm::uint64(0x000000FF000000FF);
    545 			REG3 = ((REG3 << 24) | REG3) & glm::uint64(0x000000FF000000FF);
    546 			REG4 = ((REG4 << 24) | REG4) & glm::uint64(0x000000FF000000FF);
    547 
    548 			REG1 = ((REG1 << 12) | REG1) & glm::uint64(0x000F000F000F000F);
    549 			REG2 = ((REG2 << 12) | REG2) & glm::uint64(0x000F000F000F000F);
    550 			REG3 = ((REG3 << 12) | REG3) & glm::uint64(0x000F000F000F000F);
    551 			REG4 = ((REG4 << 12) | REG4) & glm::uint64(0x000F000F000F000F);
    552 
    553 			REG1 = ((REG1 <<  6) | REG1) & glm::uint64(0x0303030303030303);
    554 			REG2 = ((REG2 <<  6) | REG2) & glm::uint64(0x0303030303030303);
    555 			REG3 = ((REG3 <<  6) | REG3) & glm::uint64(0x0303030303030303);
    556 			REG4 = ((REG4 <<  6) | REG4) & glm::uint64(0x0303030303030303);
    557 
    558 			REG1 = ((REG1 <<  3) | REG1) & glm::uint64(0x1111111111111111);
    559 			REG2 = ((REG2 <<  3) | REG2) & glm::uint64(0x1111111111111111);
    560 			REG3 = ((REG3 <<  3) | REG3) & glm::uint64(0x1111111111111111);
    561 			REG4 = ((REG4 <<  3) | REG4) & glm::uint64(0x1111111111111111);
    562 
    563 			return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3);
    564 		}
    565 	}//namespace detail
    566 
    567 	GLM_FUNC_QUALIFIER int16 bitfieldInterleave(int8 x, int8 y)
    568 	{
    569 		union sign8
    570 		{
    571 			int8 i;
    572 			uint8 u;
    573 		} sign_x, sign_y;
    574 
    575 		union sign16
    576 		{
    577 			int16 i;
    578 			uint16 u;
    579 		} result;
    580 
    581 		sign_x.i = x;
    582 		sign_y.i = y;
    583 		result.u = bitfieldInterleave(sign_x.u, sign_y.u);
    584 
    585 		return result.i;
    586 	}
    587 
    588 	GLM_FUNC_QUALIFIER uint16 bitfieldInterleave(uint8 x, uint8 y)
    589 	{
    590 		return detail::bitfieldInterleave<uint8, uint16>(x, y);
    591 	}
    592 
    593 	GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int16 x, int16 y)
    594 	{
    595 		union sign16
    596 		{
    597 			int16 i;
    598 			uint16 u;
    599 		} sign_x, sign_y;
    600 
    601 		union sign32
    602 		{
    603 			int32 i;
    604 			uint32 u;
    605 		} result;
    606 
    607 		sign_x.i = x;
    608 		sign_y.i = y;
    609 		result.u = bitfieldInterleave(sign_x.u, sign_y.u);
    610 
    611 		return result.i;
    612 	}
    613 
    614 	GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint16 x, uint16 y)
    615 	{
    616 		return detail::bitfieldInterleave<uint16, uint32>(x, y);
    617 	}
    618 
    619 	GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y)
    620 	{
    621 		union sign32
    622 		{
    623 			int32 i;
    624 			uint32 u;
    625 		} sign_x, sign_y;
    626 
    627 		union sign64
    628 		{
    629 			int64 i;
    630 			uint64 u;
    631 		} result;
    632 
    633 		sign_x.i = x;
    634 		sign_y.i = y;
    635 		result.u = bitfieldInterleave(sign_x.u, sign_y.u);
    636 
    637 		return result.i;
    638 	}
    639 
    640 	GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y)
    641 	{
    642 		return detail::bitfieldInterleave<uint32, uint64>(x, y);
    643 	}
    644 
    645 	GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z)
    646 	{
    647 		union sign8
    648 		{
    649 			int8 i;
    650 			uint8 u;
    651 		} sign_x, sign_y, sign_z;
    652 
    653 		union sign32
    654 		{
    655 			int32 i;
    656 			uint32 u;
    657 		} result;
    658 
    659 		sign_x.i = x;
    660 		sign_y.i = y;
    661 		sign_z.i = z;
    662 		result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u);
    663 
    664 		return result.i;
    665 	}
    666 
    667 	GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z)
    668 	{
    669 		return detail::bitfieldInterleave<uint8, uint32>(x, y, z);
    670 	}
    671 
    672 	GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z)
    673 	{
    674 		union sign16
    675 		{
    676 			int16 i;
    677 			uint16 u;
    678 		} sign_x, sign_y, sign_z;
    679 
    680 		union sign64
    681 		{
    682 			int64 i;
    683 			uint64 u;
    684 		} result;
    685 
    686 		sign_x.i = x;
    687 		sign_y.i = y;
    688 		sign_z.i = z;
    689 		result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u);
    690 
    691 		return result.i;
    692 	}
    693 
    694 	GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z)
    695 	{
    696 		return detail::bitfieldInterleave<uint32, uint64>(x, y, z);
    697 	}
    698 
    699 	GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y, int32 z)
    700 	{
    701 		union sign16
    702 		{
    703 			int32 i;
    704 			uint32 u;
    705 		} sign_x, sign_y, sign_z;
    706 
    707 		union sign64
    708 		{
    709 			int64 i;
    710 			uint64 u;
    711 		} result;
    712 
    713 		sign_x.i = x;
    714 		sign_y.i = y;
    715 		sign_z.i = z;
    716 		result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u);
    717 
    718 		return result.i;
    719 	}
    720 
    721 	GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y, uint32 z)
    722 	{
    723 		return detail::bitfieldInterleave<uint32, uint64>(x, y, z);
    724 	}
    725 
    726 	GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z, int8 w)
    727 	{
    728 		union sign8
    729 		{
    730 			int8 i;
    731 			uint8 u;
    732 		} sign_x, sign_y, sign_z, sign_w;
    733 
    734 		union sign32
    735 		{
    736 			int32 i;
    737 			uint32 u;
    738 		} result;
    739 
    740 		sign_x.i = x;
    741 		sign_y.i = y;
    742 		sign_z.i = z;
    743 		sign_w.i = w;
    744 		result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u);
    745 
    746 		return result.i;
    747 	}
    748 
    749 	GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z, uint8 w)
    750 	{
    751 		return detail::bitfieldInterleave<uint8, uint32>(x, y, z, w);
    752 	}
    753 
    754 	GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z, int16 w)
    755 	{
    756 		union sign16
    757 		{
    758 			int16 i;
    759 			uint16 u;
    760 		} sign_x, sign_y, sign_z, sign_w;
    761 
    762 		union sign64
    763 		{
    764 			int64 i;
    765 			uint64 u;
    766 		} result;
    767 
    768 		sign_x.i = x;
    769 		sign_y.i = y;
    770 		sign_z.i = z;
    771 		sign_w.i = w;
    772 		result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u);
    773 
    774 		return result.i;
    775 	}
    776 
    777 	GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z, uint16 w)
    778 	{
    779 		return detail::bitfieldInterleave<uint16, uint64>(x, y, z, w);
    780 	}
    781 
    782 }//namespace glm
    783