From 7389eabaf3190f6525c890a72aa4fccbc592d25a Mon Sep 17 00:00:00 2001 From: Florian Krohm Date: Tue, 26 Aug 2025 20:52:26 +0000 Subject: [PATCH] Fix Iop_ClzNat32/64 and Iop_CtzNat32/64 on x86 and amd64. Handle the special case of 0 operand. Fixes https://bugs.kde.org/show_bug.cgi?id=507033 --- VEX/priv/host_amd64_isel.c | 10 ++++++++++ VEX/priv/host_x86_isel.c | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/VEX/priv/host_amd64_isel.c b/VEX/priv/host_amd64_isel.c index f0e21ab98..113dc1bf3 100644 --- a/VEX/priv/host_amd64_isel.c +++ b/VEX/priv/host_amd64_isel.c @@ -1633,6 +1633,11 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, const IRExpr* e ) HReg dst = newVRegI(env); HReg src = iselIntExpr_R(env, e->Iex.Unop.arg); addInstr(env, AMD64Instr_Bsfr64(True,src,dst)); + /* Patch the result in case there was a 0 operand. */ + IRExpr *cond = unop(Iop_CmpNEZ64, e->Iex.Unop.arg); + AMD64CondCode cc = iselCondCode_C(env, cond); + HReg ifz = iselIntExpr_R(env, IRExpr_Const(IRConst_U64(64))); + addInstr(env, AMD64Instr_CMov64(cc ^ 1, ifz, dst)); return dst; } case Iop_ClzNat64: { @@ -1647,6 +1652,11 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, const IRExpr* e ) AMD64RMI_Imm(63), dst)); addInstr(env, AMD64Instr_Alu64R(Aalu_SUB, AMD64RMI_Reg(tmp), dst)); + /* Patch the result in case there was a 0 operand. */ + IRExpr *cond = unop(Iop_CmpNEZ64, e->Iex.Unop.arg); + AMD64CondCode cc = iselCondCode_C(env, cond); + HReg ifz = iselIntExpr_R(env, IRExpr_Const(IRConst_U64(64))); + addInstr(env, AMD64Instr_CMov64(cc ^ 1, ifz, dst)); return dst; } diff --git a/VEX/priv/host_x86_isel.c b/VEX/priv/host_x86_isel.c index d35df8fc4..b80d1116a 100644 --- a/VEX/priv/host_x86_isel.c +++ b/VEX/priv/host_x86_isel.c @@ -1311,6 +1311,11 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, const IRExpr* e ) HReg dst = newVRegI(env); HReg src = iselIntExpr_R(env, e->Iex.Unop.arg); addInstr(env, X86Instr_Bsfr32(True,src,dst)); + /* Patch the result in case there was a 0 operand. */ + IRExpr *cond = unop(Iop_CmpNEZ32, e->Iex.Unop.arg); + X86CondCode cc = iselCondCode(env, cond); + X86RM *ifz = iselIntExpr_RM(env, IRExpr_Const(IRConst_U32(32))); + addInstr(env, X86Instr_CMov32(cc ^ 1, ifz, dst)); return dst; } case Iop_ClzNat32: { @@ -1325,6 +1330,11 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, const IRExpr* e ) X86RMI_Imm(31), dst)); addInstr(env, X86Instr_Alu32R(Xalu_SUB, X86RMI_Reg(tmp), dst)); + /* Patch the result in case there was a 0 operand. */ + IRExpr *cond = unop(Iop_CmpNEZ32, e->Iex.Unop.arg); + X86CondCode cc = iselCondCode(env, cond); + X86RM *ifz = iselIntExpr_RM(env, IRExpr_Const(IRConst_U32(32))); + addInstr(env, X86Instr_CMov32(cc ^ 1, ifz, dst)); return dst; } -- 2.47.3