Re-reading old code and I’m reminded of this old trick for doing bit-manipulation:

I was trying to shift right an u8 by a value between 1 and 8 bits:

myu8 >> (8 - shift)

If shift equals 0, this would be an 8 bits shift, I wanted the result to be zero (all bits shifted), but that's not how (some) CPUs work; so it's undefined behaviour, and in Rust, the compiler will throw a compile error (if it's a const shift), or panic at runtime in debug mode.

One could test if shift is 8, and adjust code accordingly, but this adds branches and even more code.

So the trick to work around that is simply... to shift twice ! One time for the first bit, and another for the last (potential 7):

(myu8 >> 1) >> (8 - shift - 1)

And that's how one can do this operation fully branchless.

(another version of this post appeared on a now-defunct instance)

#RustLang #bitmap #BitManip

The real takeaway here is that +1 and -1 have simple and predictable effects on bit-masks and are really valuable for complex bit manipulation. If you're doing crazy stuff with bits, they're handy tools to keep close.

#bitmanip

Nice! #LLVM can now assemble and disassemble #RISCV with #BitManip extensions: