i have a struct with multiple fields, each of which have meaning associated with specific bits. so, it looks something like this:
#[repr(C)]
pub struct Instruction {
first_item: u8,
second_item: u8,
}
impl Instruction {
fn is_cool(&self) -> bool {
self.first_item & 0x80 != 0
}
fn is_nice(&self) -> bool {
self.second_item & 0xc0 != 0
}
}
now, i have some logic to run only when an instruction is_cool and is_nice, which would look like
pub fn unfortunate_check(x: &MultipleFields) -> bool {
x.is_cool() && x.is_nice()
}
why is this unfortunate you ask? rustc will turn this into...
example::unfortunate_check:
cmp byte ptr [rdi], 0
sets cl
cmp byte ptr [rdi + 1], 64
setae al
and al, cl
ret
which is to say, it checks is_cool, then is_nice, and ands the results together. but as long as the bytes are sequential you could actually check both conditions at once! looking at the layout of the struct fields and masks...
byte 0 byte 1
first_item second_item
mask 0 mask 1
0x80 0xc0
!!!!
mask (u16): 0xc080
!!!!
you could mask the whole instruction by 0xc080 in one step and be done with it! check both conditions at once! get two bytes with one test! and in fact:
pub fn check_but_better(x: &MultipleFields) -> bool {
let lol: &u16 = unsafe { std::mem::transmute(x) };
*lol & 0xc080 != 0
}
then compiles to
example::check_but_better:
movzx eax, word ptr [rdi]
test eax, 49280
setne al
ret
two fewer instructions, presumably ever-so-slightly faster.