Heya
It seems the distorm-arm project is going to be called Armstorm, after asking the guys on Twitter.
Anyway, as I’m working on this project, I just came up with the following cool snippet and wanted to submit it as a riddle:
int base = 0;
int runLength = 0;
while (mask && (~mask & 1)) base++, mask >>= 1;
while (mask && (mask & 1)) runLength++, mask >>= 1;
if (!mask && runLength > 2) {
...
}
Any idea what does it do or why I need it ?
find position of first 0 bit and first 1 bit in the mask?
Not really… because it continues to count even though it found a zero bit… until when?
finds the location of the rightmost 1’s block (first while), and its length (second while).
The condition in the if ensures that this 1’s block was in fact the single one, of size at least 3.
Also, the second while condition can be shortened to ‘while (mask & 1)’.
Maybe its for analysis of R/M portions of opcodes?
Nice Ofek!
It could be really shortened, that what happens when you write code at 2:30 AM :)
I use this code to format a registers-list for some instructions. For example:
PUSH {R0-R7}
STMIA R0!, {R4-R6}
I want to show a sequence of more than 2 registers in the %d-%d format, and the rest will be separated (it wasn’t part of the snippet).
Suppose:
POP {R0, R5, R7}
Thumbs up ;)
of course, it’s faster if you avoid checking mask==0 repeatedly:
if (mask)
{
int base = 0;
int runLength = 0;
while (~mask & 1) base++, mask >>= 1;
//mask is never zero here, always &1 initially
while (mask & 1) runLength++, mask >>= 1;
if (!mask && runLength > 2)
{
…
}
}
actually, that first while should say !(mask & 1).
you don’t want to be performing ~mask every time, either.
Sweet, thanks.
I really like the (~mask & 1) -> !(mask & 1), I wonder if the compiler could know to do it on its own…
You will want to check the __builtin_ctz() function (for GCC) and/or _BitScanReverse() (for MSVC, iirc.)