]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Merge from trunk, r2478 (Fix LZCNT and TZCNT properly. Fixes #295808.)
authorJulian Seward <jseward@acm.org>
Sun, 2 Sep 2012 20:38:00 +0000 (20:38 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 2 Sep 2012 20:38:00 +0000 (20:38 +0000)
git-svn-id: svn://svn.valgrind.org/vex/branches/VEX_3_8_BRANCH@2505

VEX/priv/guest_amd64_toIR.c
VEX/priv/guest_x86_toIR.c

index 26269c31ab010b345f5e3a35dde3d5d2b6d07436..506b5331a94622ff73c0cf08f085ff00b171364e 100644 (file)
@@ -20084,13 +20084,16 @@ Long dis_ESC_0F (
       return delta;
 
    case 0xBC: /* BSF Gv,Ev */
-      if (haveF2orF3(pfx)) goto decode_failure;
+      if (haveF2(pfx)) goto decode_failure;
       delta = dis_bs_E_G ( vbi, pfx, sz, delta, True );
       return delta;
 
    case 0xBD: /* BSR Gv,Ev */
-      if (!haveF2orF3(pfx)) {
-         /* no-F2 no-F3 0F BD = BSR */
+      if (!haveF2orF3(pfx)
+          || (haveF3noF2(pfx)
+              && 0 == (archinfo->hwcaps & VEX_HWCAPS_AMD64_LZCNT))) {
+         /* no-F2 no-F3 0F BD = BSR
+                  or F3 0F BD = REP; BSR on older CPUs.  */
          delta = dis_bs_E_G ( vbi, pfx, sz, delta, False );
          return delta;
       }
index cf95adc80f8358357928414b47c4554e05c6d63e..21a48644486e678e60a0713d3ecc6cd473e5558e 100644 (file)
@@ -14021,12 +14021,28 @@ DisResult disInstr_X86_WRK (
       for the rest, it means REP) */
    case 0xF3: { 
       Addr32 eip_orig = guest_EIP_bbstart + delta_start;
-      if (sorb != 0) goto decode_failure;
       abyte = getIByte(delta); delta++;
 
       if (abyte == 0x66) { sz = 2; abyte = getIByte(delta); delta++; }
 
+      if (sorb != 0 && abyte != 0x0F) goto decode_failure;
+
       switch (abyte) {
+      case 0x0F:
+         switch (getIByte(delta)) {
+         /* On older CPUs, TZCNT behaves the same as BSF.  */
+         case 0xBC: /* REP BSF Gv,Ev */
+            delta = dis_bs_E_G ( sorb, sz, delta + 1, True );
+            break;
+         /* On older CPUs, LZCNT behaves the same as BSR.  */
+         case 0xBD: /* REP BSR Gv,Ev */
+            delta = dis_bs_E_G ( sorb, sz, delta + 1, False );
+            break;
+         default:
+            goto decode_failure;
+         }
+         break;
+
       case 0xA4: sz = 1;   /* REP MOVS<sz> */
       case 0xA5:
          dis_REP_op ( &dres, X86CondAlways, dis_MOVS, sz, eip_orig,