From: Florian K. <fk...@so...> - 2025-08-02 12:44:54
|
https://sourceware.org/cgit/valgrind/commit/?id=697efef3720d5c78c7957ba107fb2f3307f53fd8 commit 697efef3720d5c78c7957ba107fb2f3307f53fd8 Author: Florian Krohm <fl...@ei...> Date: Sat Aug 2 12:43:54 2025 +0000 mips specific changes for BZ 507033 Rework code to use Iop_ClzNat32 instead of the deprecated Iop_Clz32. Likewise for Iop_Clz64. For Iop_Clz32 a CLZ insn will be emitted which behaves naturally when its input is 0. That is: CLZ(0) == 32. Similarly, for Iop_Clz64 a DCLZ will be emitted with DCLZ(0) == 64. That means we can replace Iop_Clz32/64 with Iop_ClzNat32/64 and remove any IR that handles the input-is-zero case. See also commit a5c48217e94. Part of fixing https://bugs.kde.org/show_bug.cgi?id=507033 Diff: --- VEX/priv/guest_mips_toIR.c | 74 +++++++++------------------------------- VEX/priv/host_mips_isel.c | 6 ++-- memcheck/tests/vbit-test/irops.c | 8 ++--- 3 files changed, 23 insertions(+), 65 deletions(-) diff --git a/VEX/priv/guest_mips_toIR.c b/VEX/priv/guest_mips_toIR.c index 1285edad0b..e42fc27825 100644 --- a/VEX/priv/guest_mips_toIR.c +++ b/VEX/priv/guest_mips_toIR.c @@ -17086,14 +17086,10 @@ static UInt disInstr_MIPS_WRK_Special(UInt cins, const VexArchInfo* archinfo, IRTemp tmpRs32 = newTemp(Ity_I32); assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); - assign(tmpClz32, unop(Iop_Clz32, mkexpr(tmpRs32))); + assign(tmpClz32, unop(Iop_ClzNat32, mkexpr(tmpRs32))); putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClz32), True)); } else { - t1 = newTemp(Ity_I1); - assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0))); - putIReg(rd, IRExpr_ITE(mkexpr(t1), - mkU32(0x00000020), - unop(Iop_Clz32, getIReg(rs)))); + putIReg(rd, unop(Iop_ClzNat32, getIReg(rs))); } } else { ILLEGAL_INSTRUCTON; @@ -17126,21 +17122,14 @@ static UInt disInstr_MIPS_WRK_Special(UInt cins, const VexArchInfo* archinfo, IRTemp tmpRs32 = newTemp(Ity_I32); assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); - t1 = newTemp(Ity_I1); - assign(t1, binop(Iop_CmpEQ32, mkexpr(tmpRs32), mkU32(0xffffffff))); - assign(tmpClo32, IRExpr_ITE(mkexpr(t1), - mkU32(0x00000020), - unop(Iop_Clz32, unop(Iop_Not32, mkexpr(tmpRs32))))); + assign(tmpClo32, unop(Iop_ClzNat32, + unop(Iop_Not32, mkexpr(tmpRs32)))); putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClo32), True)); break; } else { - t1 = newTemp(Ity_I1); - assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0xffffffff))); - putIReg(rd, IRExpr_ITE(mkexpr(t1), - mkU32(0x00000020), - unop(Iop_Clz32, - unop(Iop_Not32, getIReg(rs))))); + putIReg(rd, unop(Iop_ClzNat32, + unop(Iop_Not32, getIReg(rs)))); } } else { ILLEGAL_INSTRUCTON; @@ -17188,11 +17177,7 @@ static UInt disInstr_MIPS_WRK_Special(UInt cins, const VexArchInfo* archinfo, case 1: DIP("dclz r%u, r%u", rd, rs); - t1 = newTemp(Ity_I1); - assign(t1, binop(Iop_CmpEQ64, getIReg(rs), mkU64(0))); - putIReg(rd, IRExpr_ITE(mkexpr(t1), - mkU64(0x00000040), - unop(Iop_Clz64, getIReg(rs)))); + putIReg(rd, unop(Iop_ClzNat64, getIReg(rs))); break; } @@ -17225,13 +17210,8 @@ static UInt disInstr_MIPS_WRK_Special(UInt cins, const VexArchInfo* archinfo, case 1: DIP("dclo r%u, r%u", rd, rs); - t1 = newTemp(Ity_I1); - assign(t1, binop(Iop_CmpEQ64, getIReg(rs), - mkU64(0xffffffffffffffffULL))); - putIReg(rd, IRExpr_ITE(mkexpr(t1), - mkU64(0x40), - unop(Iop_Clz64, unop(Iop_Not64, - getIReg(rs))))); + putIReg(rd, unop(Iop_ClzNat64, + unop(Iop_Not64, getIReg(rs)))); break; } @@ -18772,14 +18752,10 @@ static UInt disInstr_MIPS_WRK_Special2(UInt cins, const VexArchInfo* archinfo, IRTemp tmpRs32 = newTemp(Ity_I32); assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); - assign(tmpClz32, unop(Iop_Clz32, mkexpr(tmpRs32))); + assign(tmpClz32, unop(Iop_ClzNat32, mkexpr(tmpRs32))); putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClz32), True)); } else { - t1 = newTemp(Ity_I1); - assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0))); - putIReg(rd, IRExpr_ITE(mkexpr(t1), - mkU32(0x00000020), - unop(Iop_Clz32, getIReg(rs)))); + putIReg(rd, unop(Iop_ClzNat32, getIReg(rs))); } break; @@ -18793,43 +18769,25 @@ static UInt disInstr_MIPS_WRK_Special2(UInt cins, const VexArchInfo* archinfo, IRTemp tmpRs32 = newTemp(Ity_I32); assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); - t1 = newTemp(Ity_I1); - assign(t1, binop(Iop_CmpEQ32, mkexpr(tmpRs32), mkU32(0xffffffff))); - assign(tmpClo32, IRExpr_ITE(mkexpr(t1), - mkU32(0x00000020), - unop(Iop_Clz32, unop(Iop_Not32, mkexpr(tmpRs32))))); + assign(tmpClo32, unop(Iop_ClzNat32, + unop(Iop_Not32, mkexpr(tmpRs32)))); putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClo32), True)); break; } else { - t1 = newTemp(Ity_I1); - assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0xffffffff))); - putIReg(rd, IRExpr_ITE(mkexpr(t1), - mkU32(0x00000020), - unop(Iop_Clz32, - unop(Iop_Not32, getIReg(rs))))); + putIReg(rd, unop(Iop_ClzNat32, unop(Iop_Not32, getIReg(rs)))); break; } } case 0x24: /* Count Leading Zeros in Doubleword - DCLZ; MIPS64 */ DIP("dclz r%u, r%u", rd, rs); - t1 = newTemp(Ity_I1); - assign(t1, binop(Iop_CmpEQ64, getIReg(rs), mkU64(0))); - putIReg(rd, IRExpr_ITE(mkexpr(t1), - mkU64(0x00000040), - unop(Iop_Clz64, getIReg(rs)))); + putIReg(rd, unop(Iop_ClzNat64, getIReg(rs))); break; case 0x25: /* Count Leading Ones in Doubleword - DCLO; MIPS64 */ DIP("dclo r%u, r%u", rd, rs); - t1 = newTemp(Ity_I1); - assign(t1, binop(Iop_CmpEQ64, getIReg(rs), - mkU64(0xffffffffffffffffULL))); - putIReg(rd, IRExpr_ITE(mkexpr(t1), - mkU64(0x40), - unop(Iop_Clz64, unop(Iop_Not64, - getIReg(rs))))); + putIReg(rd, unop(Iop_ClzNat64, unop(Iop_Not64, getIReg(rs)))); break; default: diff --git a/VEX/priv/host_mips_isel.c b/VEX/priv/host_mips_isel.c index 33e4f52169..2bdfa4a648 100644 --- a/VEX/priv/host_mips_isel.c +++ b/VEX/priv/host_mips_isel.c @@ -2155,13 +2155,13 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e) return r_dst; } - case Iop_Clz64: + case Iop_ClzNat64: vassert(mode64); /* fallthrough */ - case Iop_Clz32: { + case Iop_ClzNat32: { HReg r_dst = newVRegI(env); HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); - MIPSUnaryOp op = (op_unop == Iop_Clz64) ? Mun_DCLZ : Mun_CLZ; + MIPSUnaryOp op = (op_unop == Iop_ClzNat64) ? Mun_DCLZ : Mun_CLZ; addInstr(env, MIPSInstr_Unary(op, r_dst, r_src)); return r_dst; } diff --git a/memcheck/tests/vbit-test/irops.c b/memcheck/tests/vbit-test/irops.c index e104c18acb..fdea8919e4 100644 --- a/memcheck/tests/vbit-test/irops.c +++ b/memcheck/tests/vbit-test/irops.c @@ -108,12 +108,12 @@ static irop_t irops[] = { { DEFOP(Iop_MullU16, UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 =0, .mips64 = 0 }, { DEFOP(Iop_MullU32, UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 =0, .mips64 = 1 }, // mips asserts { DEFOP(Iop_MullU64, UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 1 }, // ppc32, mips assert - { DEFOP(Iop_Clz64, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 1 }, // ppc32 asserts - { DEFOP(Iop_Clz32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 =1, .mips64 = 1 }, + { DEFOP(Iop_Clz64, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 0 }, // ppc32 asserts + { DEFOP(Iop_Clz32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 =0, .mips64 = 0 }, { DEFOP(Iop_Ctz64, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 =0, .mips64 = 0 }, { DEFOP(Iop_Ctz32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 =0, .mips64 = 0 }, - { DEFOP(Iop_ClzNat64, UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 0 }, // ppc32 asserts - { DEFOP(Iop_ClzNat32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 =0, .mips64 = 0 }, + { DEFOP(Iop_ClzNat64, UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 1 }, // ppc32 asserts + { DEFOP(Iop_ClzNat32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 =1, .mips64 = 1 }, { DEFOP(Iop_CtzNat64, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 0 }, { DEFOP(Iop_CtzNat32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 1, .mips32 =0, .mips64 = 0 }, { DEFOP(Iop_PopCount64, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 0 }, |