-
Notifications
You must be signed in to change notification settings - Fork 15.4k
Description
This code:
export fn foo(a: u64) u64 {
return ~blsmsk(a);
}
fn blsmsk(a: u64) u64 {
return (a ^ (a - 1));
}Gives this emit:
foo:
mov rax, rdi
neg rax
xor rax, rdi
retWith inline assembly, we can force the compiler to do the thing we want:
export fn bar(a: u64) u64 {
return ~blsmsk_asm(a);
}
inline fn blsmsk_asm(src: u64) u64 {
return asm ("blsmsk %[src], %[ret]"
: [ret] "=r" (-> u64),
: [src] "r" (src),
);
}bar:
blsmsk rax, rdi
not rax
retIn my real code, I was doing a bitwise AND on ~blsmsk(a). Meaning the not can be folded into an ANDN instruction.
export fn foo(a: u64, b: u64) u64 {
return ~blsmsk(a) & b;
}foo:
mov rax, rdi
neg rax
xor rax, rdi
and rax, rsi
retAgain, with inline assembly, we can get:
bar:
blsmsk rax, rdi
andn rax, rax, rsi
ret