I'm actually using a loop like this:
Code: Select all
for (count=32; bits; bits>>=1)
count--;
Any ideas?
x86 assembler welcome again.

Code: Select all
for (count=32; bits; bits>>=1)
count--;

Code: Select all
int highbit( int val )
{
int bitnum=0;
if( val&0xffff0000 )
{
bitnum += 16;
val>>=16;
}
if( val&0xff00 )
{
bitnum += 8;
val>>=8;
}
if( val&0xf0 )
{
bitnum += 4;
val>>=4;
}
if( val&0xc )
{
bitnum += 2;
val>>2;
}
if( val&0x2 )
{
bitnum +=1;
}
return( bitnum );
}


Cor, thanks pogo!


IA64 may well do this, the new versions have extendedThe Pentium and K6 use micro-coded loops.
Athlon and Pentium 4 use a binary search, but it's still 8-10 clocks. A
2-cycle popcount would give a 4-cycle bsf. If a bit-reverse instruction were
also added, bsr could be emulated in 6-cycles.
Code: Select all
uint32 MSB(int32 n)
{
uint32 sigbits;
if((n == 0) || (n == -1))
{
sigbits = 0;
}
else
{
//n = n if positive, n = ~n if negative
n = (n ^ (n >> 31));
//fold n into itself to get a new value where all bits below the
//most significant one bit have also been set to one.
n |= (n >> 1);
n |= (n >> 2);
n |= (n >> 4);
n |= (n >> 8);
n |= (n >> 16);
//get the ones count
n -= ((n >> 1) & 0x55555555);
n = (((n >> 2) & 0x33333333) + (n & 0x33333333));
n = (((n >> 4) + n) & 0x0f0f0f0f);
n += (n >> 8);
n += (n >> 16);
//return the ones count... if n was orignally 0 or -1 then the ones count
//will be zero which is exactly what we want
sigbits = ((uint32)n) & 0x1FUL;
}
return sigbits;
}
Maybe I'm being stupid here but is your code really faster thanRiff wrote:Code: Select all
uint32 MSB(int32 n) { uint32 sigbits; if((n == 0) || (n == -1)) { sigbits = 0; } else { //n = n if positive, n = ~n if negative n = (n ^ (n >> 31)); //fold n into itself to get a new value where all bits below the //most significant one bit have also been set to one. n |= (n >> 1); n |= (n >> 2); n |= (n >> 4); n |= (n >> 8); n |= (n >> 16); //get the ones count n -= ((n >> 1) & 0x55555555); n = (((n >> 2) & 0x33333333) + (n & 0x33333333)); n = (((n >> 4) + n) & 0x0f0f0f0f); n += (n >> 8); n += (n >> 16); //return the ones count... if n was orignally 0 or -1 then the ones count //will be zero which is exactly what we want sigbits = ((uint32)n) & 0x1FUL; } return sigbits; }
Kemper_Boyd wrote: *googles*
IA64 may well do this, the new versions have extendedThe Pentium and K6 use micro-coded loops.
Athlon and Pentium 4 use a binary search, but it's still 8-10 clocks.
A 2-cycle popcount would give a 4-cycle bsf. If a bit-reverse instruction were also added, bsr could be emulated in 6-cycles.
support for popcount, probably to keep a very big but
quiet customer happy.

Code: Select all
mov cx, 32
@@:
rol eax, 1
loopnc @b