]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
mips64: do correct 32-bit comparison for Iop_CmpNE32
authorPetar Jovanovic <mips32r2@gmail.com>
Mon, 13 Feb 2017 16:15:24 +0000 (16:15 +0000)
committerPetar Jovanovic <mips32r2@gmail.com>
Mon, 13 Feb 2017 16:15:24 +0000 (16:15 +0000)
Make sure that we take into account 32-bit size of values in comparison
on MIPS64-platforms. This is done either by sign extending these values
before comparison or sign extending xored values (depending on what
comparison we do). This should avoid false-positives like the one
reported in BZ #341481.

Patch based on code provided by Crestez Dan Leonard and Tamara Vlahovic.

git-svn-id: svn://svn.valgrind.org/vex/trunk@3304

VEX/priv/host_mips_defs.c
VEX/priv/host_mips_isel.c

index ce202d121cb9b20f1c0d83baa588e267c96a14b2..ac5b9a74b35752a3f20f04dd40c0495827c5fa68 100644 (file)
@@ -1584,8 +1584,15 @@ void getRegUsage_MIPSInstr(HRegUsage * u, const MIPSInstr * i, Bool mode64)
          addHRegUse(u, HRmWrite, i->Min.Shft.dst);
          return;
       case Min_Cmp:
-         addHRegUse(u, HRmRead, i->Min.Cmp.srcL);
-         addHRegUse(u, HRmRead, i->Min.Cmp.srcR);
+         if (i->Min.Cmp.sz32 && mode64 &&
+            (i->Min.Cmp.cond != MIPScc_EQ) &&
+            (i->Min.Cmp.cond != MIPScc_NE)) {
+            addHRegUse(u, HRmModify, i->Min.Cmp.srcL);
+            addHRegUse(u, HRmModify, i->Min.Cmp.srcR);
+         } else {
+            addHRegUse(u, HRmRead, i->Min.Cmp.srcL);
+            addHRegUse(u, HRmRead, i->Min.Cmp.srcR);
+         }
          addHRegUse(u, HRmWrite, i->Min.Cmp.dst);
          return;
       case Min_Unary:
@@ -2754,35 +2761,68 @@ Int emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc,
          UInt r_srcL = iregNo(i->Min.Cmp.srcL, mode64);
          UInt r_srcR = iregNo(i->Min.Cmp.srcR, mode64);
          UInt r_dst = iregNo(i->Min.Cmp.dst, mode64);
+         Bool sz32 = i->Min.Cmp.sz32;
 
          switch (i->Min.Cmp.cond) {
             case MIPScc_EQ:
                /* xor r_dst, r_srcL, r_srcR
                   sltiu r_dst, r_dst, 1 */
                p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 38);
+               if (mode64 && sz32) {
+                  /* sll r_dst, r_dst, 0 */
+                  p = mkFormS(p, 0, r_dst, 0, r_dst, 0, 0);
+               }
                p = mkFormI(p, 11, r_dst, r_dst, 1);
                break;
             case MIPScc_NE:
                /* xor r_dst, r_srcL, r_srcR
                   sltu r_dst, zero, r_dst */
                p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 38);
+               if (mode64 && sz32) {
+                  /* sll r_dst, r_dst, 0 */
+                  p = mkFormS(p, 0, r_dst, 0, r_dst, 0, 0);
+               }
                p = mkFormR(p, 0, 0, r_dst, r_dst, 0, 43);
                break;
             case MIPScc_LT:
+               if (mode64 && sz32) {
+                  /* sll r_srcL, r_srcL, 0
+                     sll r_srcR, r_srcR, 0 */
+                  p = mkFormS(p, 0, r_srcL, 0, r_srcL, 0, 0);
+                  p = mkFormS(p, 0, r_srcR, 0, r_srcR, 0, 0);
+               }
                /* slt r_dst, r_srcL, r_srcR */
                p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 42);
                break;
             case MIPScc_LO:
+               if (mode64 && sz32) {
+                  /* sll r_srcL, r_srcL, 0
+                     sll r_srcR, r_srcR, 0 */
+                  p = mkFormS(p, 0, r_srcL, 0, r_srcL, 0, 0);
+                  p = mkFormS(p, 0, r_srcR, 0, r_srcR, 0, 0);
+               }
                /* sltu r_dst, r_srcL, r_srcR */
                p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 43);
                break;
             case MIPScc_LE:
+               if (mode64 && sz32) {
+                  /* sll r_srcL, r_srcL, 0
+                     sll r_srcR, r_srcR, 0 */
+                  p = mkFormS(p, 0, r_srcL, 0, r_srcL, 0, 0);
+                  p = mkFormS(p, 0, r_srcR, 0, r_srcR, 0, 0);
+               }
                /* slt r_dst, r_srcR, r_srcL
                   xori r_dst, r_dst, 1 */
                p = mkFormR(p, 0, r_srcR, r_srcL, r_dst, 0, 42);
                p = mkFormI(p, 14, r_dst, r_dst, 1);
                break;
             case MIPScc_LS:
+               if (mode64 && sz32) {
+                  /* sll r_srcL, r_srcL, 0
+                     sll r_srcR, r_srcR, 0 */
+                  p = mkFormS(p, 0, r_srcL, 0, r_srcL, 0, 0);
+                  p = mkFormS(p, 0, r_srcR, 0, r_srcR, 0, 0);
+               }
                /* sltu r_dst, rsrcR, r_srcL
                   xori r_dsr, r_dst, 1 */
                p = mkFormR(p, 0, r_srcR, r_srcL, r_dst, 0, 43);
index 9e44dd44076d47ad3bf2cace7b3fd86890c4a8e8..aa7231894174356c13766cf476c5345700908222 100644 (file)
@@ -1000,7 +1000,7 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
                   break;
                case Iop_CmpNE64:
                   cc = MIPScc_NE;
-                  size32 = True;
+                  size32 = False;
                   break;
                case Iop_CmpLT32S:
                   cc = MIPScc_LT;
@@ -2080,7 +2080,7 @@ static MIPSCondCode iselCondCode_wrk(ISelEnv * env, IRExpr * e)
             break;
          case Iop_CmpNE64:
             cc = MIPScc_NE;
-            size32 = True;
+            size32 = False;
             break;
          case Iop_CmpLT32S:
             cc = MIPScc_LT;