I need to find out how to do a Bit Scan Reverse (return the index of the highest set bit) for 8-bit, 16-bit, 32-bit and 64-bit integers in platform-independent ANSI C for use in an industrial process.
I know about x86's _BitScanReverse, I can't use that here. GCC's __builtin_clz is also a no go.
Sorry to clarify we're using an ancient company-made internal compiler. Any intrinsics would have to be written in AT&T-style assembly and compiled and then linked to.
I've come up with this:
//Count leading zeros
unsigned long long clz(unsigned long long x)
{
unsigned long long y = 0;
unsigned long long n = 64;
y = x >> 32; if (y != 0) { n = n - 32; x = y; }
y = x >> 16; if (y != 0) { n = n - 16; x = y; }
y = x >> 8; if (y != 0) { n = n - 8; x = y; }
y = x >> 4; if (y != 0) { n = n - 4; x = y; }
y = x >> 2; if (y != 0) { n = n - 2; x = y; }
y = x >> 1; if (y != 0) return (n - 2);
return (n - x);
}
//Extrapolate highest set bit from clz
unsigned long long bsr(unsigned long long x)
{
return (sizeof(x) * CHAR_BIT) - clz(x) - 1;
}
This is painfully slow compared to the bsr instruction available on x86/amd64. So I'd like to know if there are any good options to speed this up for 8088, MIPS-16, MIPS-32, ARM-32, ARM-64 or SOCs capable of basic arithmetic(+,-,*,/,%), bit wise operations (&,|,^,~), and bit shifting (<<, >>).
I also need to know if I need to make adjustments to account for endian-ness. These systems use a mix of big-endian and little-endian.
Must be in ANSI C with the exception of calls to compiled assembly.
Thanks in advance.