From f4ff0d493c87b9fd301a222bc73bdc3288a47d1f Mon Sep 17 00:00:00 2001 From: Paris Oplopoios Date: Tue, 3 Sep 2024 20:41:22 +0300 Subject: [PATCH] Set CF correctly on BLSI patch (#722) * Set CF correctly on BLSI patch * Remove redundant CLC --- src/core/cpu_patches.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/core/cpu_patches.cpp b/src/core/cpu_patches.cpp index 151d34986..07253b46f 100644 --- a/src/core/cpu_patches.cpp +++ b/src/core/cpu_patches.cpp @@ -307,9 +307,24 @@ static void GenerateBLSI(const ZydisDecodedOperand* operands, Xbyak::CodeGenerat SaveRegisters(c, {scratch}); + // BLSI sets CF to zero if source is zero, otherwise it sets CF to one. + Xbyak::Label set_carry, clear_carry, end; + c.mov(scratch, *src); - c.neg(scratch); + c.neg(scratch); // NEG, like BLSI, clears CF if the source is zero and sets it otherwise + c.jc(set_carry); + c.jmp(clear_carry); + + c.L(set_carry); c.and_(scratch, *src); + c.stc(); // setting/clearing carry needs to happen after the AND because that clears CF + c.jmp(end); + + c.L(clear_carry); + c.and_(scratch, *src); + // We don't need to clear carry here since AND does that for us + + c.L(end); c.mov(dst, scratch); RestoreRegisters(c, {scratch});