]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
mips specific changes for BZ 507033
authorFlorian Krohm <flo2030@eich-krohm.de>
Sat, 2 Aug 2025 12:43:54 +0000 (12:43 +0000)
committerFlorian Krohm <flo2030@eich-krohm.de>
Sat, 2 Aug 2025 12:43:54 +0000 (12:43 +0000)
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

VEX/priv/guest_mips_toIR.c
VEX/priv/host_mips_isel.c
memcheck/tests/vbit-test/irops.c

index 1285edad0b83b0f0a6b21fc63d2235d50f94d204..e42fc27825dba30a50729f28dc3d2d74bc2594cc 100644 (file)
@@ -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:
index 33e4f52169a7654a030a90e689e764f1fff97dec..2bdfa4a6488afb6cd67a6a6279198b9aee9f9f64 100644 (file)
@@ -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;
          }
index e104c18acb28074e990efa09e1aa2c7e5d78404b..fdea8919e43de44b1166cc743fdf2652ede4906b 100644 (file)
@@ -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 },