Steinar H. Gunderson: Decompilation patterns, part 17: Loop rotation
Occasionally, you'll see code like this (after initial cleanup):
var_v0_2 = crc & 0x80000000;
do {
if (var_v0_2 != 0) {
crc = (crc << 1) ^ 0x1EDC6F41;
} else {
crc <<= 1;
}
var_a0 += 1;
var_v0_2 = crc & 0x80000000;
} while (var_a0 < 8U);
The thing with var_v0_2 is unnatural. GCC sometimes does these loop rotation tricks, seemingly
to save registers (don't ask me how exactly it does). You want to un-rotate
back into:
do {
var_v0_2 = crc & 0x80000000;
if (var_v0_2 != 0) {
crc = (crc << 1) ^ 0x1EDC6F41;
} else {
crc <<= 1;
}
var_a0 += 1;
} while (var_a0 < 8U);
and then of course, you can clean up the rest:
for (i = 0; i < 8; ++i) {
if (crc & 0x80000000) {
crc = (crc << 1) ^ 0x1EDC6F41;
} else {
crc <<= 1;
}
}
Last one tomorrow, I think.