Description
https://doc.rust-lang.org/nightly/reference/inline-assembly.html#register-names
says about k0
"This is a constant zero register which can't be modified."
That's the same phrasing as AArch64 xzr
, so I assume the author thought it was architecturally hard-wired, rather than a software choice to keep it zeroed (like often done with AVR r0
). (Which I don't think would make much sense; most instructions with an all-zero mask are no-ops so you don't normally want one.)
k0
is special in that it can't be used as a mask, because that register number means no-masking if used in an instruction like vmovaps (%rdi), %xmm0{%k1}{z}
. But it can be the destination of instructions like compare-into-mask or vptestmd %ymm0, %ymm0, %k0
, and then stored to memory or copied to a GP-integer reg with kmovd %k0, %eax
, tested with kortest
, combine with other masks with kunpck
or kadd
or whatever.
Leaving it unused prevents false dependencies when materializing an all-ones mask with kxnord %k0, %k0, %k1
(e.g. before a gather), but otherwise there's no reason to avoid it if your uses for that mask don't include applying masking to other instructions.
You do definitely want there to be a constraint that can only pick k1..7, not k0, like GNU C inline asm's Yk
(https://stackoverflow.com/questions/55946103/gnu-c-inline-asm-input-constraint-for-avx512-mask-registers-k1-k7), but there's no reason to disallow k0
as an explicit choice. If people don't want to know about details like k0 being special, they can use intrinsics.
Probably not much reason to invent a constraint like Yk
but which can pick k0..7, though, but it's possible it could help register allocation of mask regs with surrounding code. (But would be more documentation to wade through, and could end up wasting some people's time if they find the constraint which can pick k0 when they need one which can't.)