From: Florian Krohm Date: Thu, 31 Jul 2025 21:28:39 +0000 (+0000) Subject: nanomips specific changes for BZ 507033 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a5c48217e94;p=thirdparty%2Fvalgrind.git nanomips specific changes for BZ 507033 Rework code to use Iop_ClzNat32 instead of the deprecated Iop_Clz32. Iop_Clz32 is used to implement the CLZ insn which behaves naturally when the input is 0: CLZ(0) == 32 So it seems as if using Iop_Clz32 is wrong because it has undefined behaviour when the input value is 0. However, the VEX pipeline does this: CLZ insn --ir--> Iop_Clz32 --isel--> NMun_CLZ --emit--> CLZ So it all works out. Essentially the semantics of Iop_Clz32 were redefined to be like Iop_ClzNat32. In IR generation we can drop the special handling for CLO(0) because Iop_ClzNat32 takes care of that. Part of fixing https://bugs.kde.org/show_bug.cgi?id=507033 --- diff --git a/VEX/priv/guest_nanomips_toIR.c b/VEX/priv/guest_nanomips_toIR.c index 3827ac3fc..fddc1afa4 100644 --- a/VEX/priv/guest_nanomips_toIR.c +++ b/VEX/priv/guest_nanomips_toIR.c @@ -864,23 +864,17 @@ static void nano_pool32Axf_4(DisResult *dres, UInt cins) { UChar rs = (cins >> 16) & 0x1F; UChar rt = (cins >> 21) & 0x1F; - IRTemp t1; switch ((cins >> 9) & 0x7F) { case nano_POOL32Axf4_CLO: { /* clo */ DIP("clo r%u, r%u", rt, rs); - t1 = newTemp(Ity_I1); - assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0xffffffff))); - putIReg(rt, IRExpr_ITE(mkexpr(t1), - mkU32(0x00000020), - unop(Iop_Clz32, - unop(Iop_Not32, getIReg(rs))))); + putIReg(rt, unop(Iop_ClzNat32, unop(Iop_Not32, getIReg(rs)))); break; } case nano_POOL32Axf4_CLZ: { /* clz */ DIP("clz r%u, r%u", rt, rs); - putIReg(rt, unop(Iop_Clz32, getIReg(rs))); + putIReg(rt, unop(Iop_ClzNat32, getIReg(rs))); break; } } diff --git a/VEX/priv/host_nanomips_isel.c b/VEX/priv/host_nanomips_isel.c index c4a8f4fe3..05e4cc512 100644 --- a/VEX/priv/host_nanomips_isel.c +++ b/VEX/priv/host_nanomips_isel.c @@ -815,7 +815,7 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e) return r_dst; } - case Iop_Clz32: { + case Iop_ClzNat32: { HReg r_dst = newVRegI(env); HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); addInstr(env, NANOMIPSInstr_Unary(NMun_CLZ, r_dst, r_src));