// Count Leading Zeros static inline uint16 _uint16_cntlz( uint16 x ) { #ifdef __GNUC__ /* On PowerPC, this will map to insn: cntlzw */ /* On Pentium, this will map to insn: clz */ uint16 nlz32 = (uint16)_uint32_cntlz( (uint32)x ); uint32 nlz = _uint32_sub( nlz32, 16 ); return (nlz); #elif _NV_OS_XBOX_ uint16 nlz32 = (uint16)_CountLeadingZeros( (uint32)x ); return _uint32_sub( nlz32, 16); #else const uint16 x0 = _uint16_srl( x, 1 ); const uint16 x1 = _uint16_or( x, x0 ); const uint16 x2 = _uint16_srl( x1, 2 ); const uint16 x3 = _uint16_or( x1, x2 ); const uint16 x4 = _uint16_srl( x3, 4 ); const uint16 x5 = _uint16_or( x3, x4 ); const uint16 x6 = _uint16_srl( x5, 8 ); const uint16 x7 = _uint16_or( x5, x6 ); const uint16 x8 = _uint16_not( x7 ); const uint16 x9 = _uint16_srlm( x8, 1, 0x5555 ); const uint16 xA = _uint16_sub( x8, x9 ); const uint16 xB = _uint16_and( xA, 0x3333 ); const uint16 xC = _uint16_srlm( xA, 2, 0x3333 ); const uint16 xD = _uint16_add( xB, xC ); const uint16 xE = _uint16_srl( xD, 4 ); const uint16 xF = _uint16_addm( xD, xE, 0x0f0f ); const uint16 x10 = _uint16_srl( xF, 8 ); const uint16 x11 = _uint16_addm( xF, x10, 0x001f ); return ( x11 ); #endif }
inline unsigned int CountTrailingZeros( unsigned int elem ) { // this implements CountTrailingZeros() / BitScanForward() unsigned int mask = elem-1; unsigned int comp = ~elem; elem = mask & comp; return (32 - _CountLeadingZeros(elem)); }
int SendProp::GetNumArrayLengthBits() const { Assert( GetType() == DPT_Array ); #if _X360 int elemCount = GetNumElements(); if ( !elemCount ) return 1; return (32 - _CountLeadingZeros(GetNumElements())); #else return Q_log2( GetNumElements() ) + 1; #endif }
// Count Leading Zeros static inline uint32 _uint32_cntlz( uint32 x ) { #if NV_CC_GCC /* On PowerPC, this will map to insn: cntlzw */ /* On Pentium, this will map to insn: clz */ uint32 is_x_nez_msb = _uint32_neg( x ); uint32 nlz = __builtin_clz( x ); uint32 result = _uint32_sels( is_x_nez_msb, nlz, 0x00000020 ); return (result); #elif NV_OS_XBOX // Xbox PPC has this as an intrinsic. return _CountLeadingZeros(x); #elif NV_CC_MSVC uint32 is_x_nez_msb = _uint32_neg( x ); uint32 nlz = _uint32_nlz( x ); uint32 result = _uint32_sels( is_x_nez_msb, nlz, 0x00000020 ); return (result); #else const uint32 x0 = _uint32_srl( x, 1 ); const uint32 x1 = _uint32_or( x, x0 ); const uint32 x2 = _uint32_srl( x1, 2 ); const uint32 x3 = _uint32_or( x1, x2 ); const uint32 x4 = _uint32_srl( x3, 4 ); const uint32 x5 = _uint32_or( x3, x4 ); const uint32 x6 = _uint32_srl( x5, 8 ); const uint32 x7 = _uint32_or( x5, x6 ); const uint32 x8 = _uint32_srl( x7, 16 ); const uint32 x9 = _uint32_or( x7, x8 ); const uint32 xA = _uint32_not( x9 ); const uint32 xB = _uint32_srl( xA, 1 ); const uint32 xC = _uint32_and( xB, 0x55555555 ); const uint32 xD = _uint32_sub( xA, xC ); const uint32 xE = _uint32_and( xD, 0x33333333 ); const uint32 xF = _uint32_srl( xD, 2 ); const uint32 x10 = _uint32_and( xF, 0x33333333 ); const uint32 x11 = _uint32_add( xE, x10 ); const uint32 x12 = _uint32_srl( x11, 4 ); const uint32 x13 = _uint32_add( x11, x12 ); const uint32 x14 = _uint32_and( x13, 0x0f0f0f0f ); const uint32 x15 = _uint32_srl( x14, 8 ); const uint32 x16 = _uint32_add( x14, x15 ); const uint32 x17 = _uint32_srl( x16, 16 ); const uint32 x18 = _uint32_add( x16, x17 ); const uint32 x19 = _uint32_and( x18, 0x0000003f ); return ( x19 ); #endif }
// -------------------------------------------------------------------------- // Calculate inverse of fixed point number // // Parameters: // a - the number whose inverse should be calculated // -------------------------------------------------------------------------- EGL_Fixed EGL_Inverse(EGL_Fixed a) { I32 exp; EGL_Fixed x; /* 1/(4x) */ static const I32 __gl_rcp_tab[] = { /* domain 0.5 .. 1.0-1/16 */ 0x8000, 0x71c7, 0x6666, 0x5d17, 0x5555, 0x4ec4, 0x4924, 0x4444 }; if (a == EGL_ZERO) return 0x7fffffff; bool sign = false; if (a < 0) { sign = true; a = -a; } #ifdef EGL_USE_CLZ exp = _CountLeadingZeros(a); #else x = a; exp = 31; if (x & 0xffff0000) { exp -= 16; x >>= 16; }