OpcodeDispatcher: optimize 32-bit tzcnt

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
Alyssa Rosenzweig committed 2024-01-29 13:11:25 -04:00
1 parent ad9aa0bc87
commit 16a54742e6
2 files changed
+7 -1

No files matched your search

@@ -1219,6 +1219,11 @@ DEF_OP(FindTrailingZeroes) {
rbit(EmitSize, Dst, Src);
if (OpSize == 2) {
// This orr does two things. First, if the (masked) source is zero, it
// reverses to zero in the top so it forces clz to return 16. Second, it
// ensures garbage in the upper bits of the source don't affect clz, because
// they'll rbit to garbage in the bottom below the 0x8000 and be ignored by
// the clz. So we handle Src upper garbage without explicitly masking.
orr(EmitSize, Dst, Dst, 0x8000);
}
@@ -5371,7 +5371,8 @@ void OpDispatchBuilder::INTOp(OpcodeArgs) {
}
void OpDispatchBuilder::TZCNT(OpcodeArgs) {
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags);
// _FindTrailingZeroes ignores upper garbage so we don't need to mask
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, {.AllowUpperGarbage = true});
Src = _FindTrailingZeroes(OpSizeFromSrc(Op), Src);
StoreResult(GPRClass, Op, Src, -1);