From ad9aa0bc87eff3d5059bbfd34cda870ed5397914 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Wed, 24 Jan 2024 16:30:15 -0400 Subject: [PATCH] OpcodeDispatcher: optimize 32-bit lzcnt Signed-off-by: Alyssa Rosenzweig --- FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp | 2 ++ FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp index 95f67911b..ddbe9d732 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp @@ -1236,6 +1236,8 @@ DEF_OP(CountLeadingZeroes) { const auto Src = GetReg(Op->Src.ID()); if (OpSize == 2) { + // Expressing as lsl+orr+clz clears away any garbage in the upper bits + // (alternatively could do uxth+clz+sub.. equal cost in total). lsl(EmitSize, Dst, Src, 16); orr(EmitSize, Dst, Dst, 0x8000); clz(EmitSize, Dst, Dst); diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 5229c6bb7..1059f918c 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -5380,7 +5380,8 @@ void OpDispatchBuilder::TZCNT(OpcodeArgs) { } void OpDispatchBuilder::LZCNT(OpcodeArgs) { - OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags); + // _CountLeadingZeroes clears upper garbage so we don't need to mask + OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, {.AllowUpperGarbage = true}); auto Res = _CountLeadingZeroes(OpSizeFromSrc(Op), Src); StoreResult(GPRClass, Op, Res, -1);