Mark Wielaard c06a5e
------------------------------------------------------------------------
Mark Wielaard c06a5e
r2478 | sewardj | 2012-08-23 22:14:51 +0200 (Thu, 23 Aug 2012) | 4 lines
Mark Wielaard c06a5e
Mark Wielaard c06a5e
Fix LZCNT and TZCNT properly.  Fixes #295808.  (Jakub Jelinek,
Mark Wielaard c06a5e
jakub@redhat.com)
Mark Wielaard c06a5e
Mark Wielaard c06a5e
Mark Wielaard c06a5e
------------------------------------------------------------------------
Mark Wielaard c06a5e
Index: priv/guest_amd64_toIR.c
Mark Wielaard c06a5e
===================================================================
Mark Wielaard c06a5e
--- valgrind-3.8.0/VEX/priv/guest_amd64_toIR.c	(revision 2477)
Mark Wielaard c06a5e
+++ valgrind-3.8.0/VEX/priv/guest_amd64_toIR.c	(revision 2478)
Mark Wielaard c06a5e
@@ -20084,13 +20084,16 @@
Mark Wielaard c06a5e
       return delta;
Mark Wielaard c06a5e
 
Mark Wielaard c06a5e
    case 0xBC: /* BSF Gv,Ev */
Mark Wielaard c06a5e
-      if (haveF2orF3(pfx)) goto decode_failure;
Mark Wielaard c06a5e
+      if (haveF2(pfx)) goto decode_failure;
Mark Wielaard c06a5e
       delta = dis_bs_E_G ( vbi, pfx, sz, delta, True );
Mark Wielaard c06a5e
       return delta;
Mark Wielaard c06a5e
 
Mark Wielaard c06a5e
    case 0xBD: /* BSR Gv,Ev */
Mark Wielaard c06a5e
-      if (!haveF2orF3(pfx)) {
Mark Wielaard c06a5e
-         /* no-F2 no-F3 0F BD = BSR */
Mark Wielaard c06a5e
+      if (!haveF2orF3(pfx)
Mark Wielaard c06a5e
+          || (haveF3noF2(pfx)
Mark Wielaard c06a5e
+              && 0 == (archinfo->hwcaps & VEX_HWCAPS_AMD64_LZCNT))) {
Mark Wielaard c06a5e
+         /* no-F2 no-F3 0F BD = BSR
Mark Wielaard c06a5e
+                  or F3 0F BD = REP; BSR on older CPUs.  */
Mark Wielaard c06a5e
          delta = dis_bs_E_G ( vbi, pfx, sz, delta, False );
Mark Wielaard c06a5e
          return delta;
Mark Wielaard c06a5e
       }
Mark Wielaard c06a5e
Index: priv/guest_x86_toIR.c
Mark Wielaard c06a5e
===================================================================
Mark Wielaard c06a5e
--- valgrind-3.8.0/VEX/priv/guest_x86_toIR.c	(revision 2477)
Mark Wielaard c06a5e
+++ valgrind-3.8.0/VEX/priv/guest_x86_toIR.c	(revision 2478)
Mark Wielaard c06a5e
@@ -14021,12 +14021,28 @@
Mark Wielaard c06a5e
       for the rest, it means REP) */
Mark Wielaard c06a5e
    case 0xF3: { 
Mark Wielaard c06a5e
       Addr32 eip_orig = guest_EIP_bbstart + delta_start;
Mark Wielaard c06a5e
-      if (sorb != 0) goto decode_failure;
Mark Wielaard c06a5e
       abyte = getIByte(delta); delta++;
Mark Wielaard c06a5e
 
Mark Wielaard c06a5e
       if (abyte == 0x66) { sz = 2; abyte = getIByte(delta); delta++; }
Mark Wielaard c06a5e
 
Mark Wielaard c06a5e
+      if (sorb != 0 && abyte != 0x0F) goto decode_failure;
Mark Wielaard c06a5e
+
Mark Wielaard c06a5e
       switch (abyte) {
Mark Wielaard c06a5e
+      case 0x0F:
Mark Wielaard c06a5e
+         switch (getIByte(delta)) {
Mark Wielaard c06a5e
+         /* On older CPUs, TZCNT behaves the same as BSF.  */
Mark Wielaard c06a5e
+         case 0xBC: /* REP BSF Gv,Ev */
Mark Wielaard c06a5e
+            delta = dis_bs_E_G ( sorb, sz, delta + 1, True );
Mark Wielaard c06a5e
+            break;
Mark Wielaard c06a5e
+         /* On older CPUs, LZCNT behaves the same as BSR.  */
Mark Wielaard c06a5e
+         case 0xBD: /* REP BSR Gv,Ev */
Mark Wielaard c06a5e
+            delta = dis_bs_E_G ( sorb, sz, delta + 1, False );
Mark Wielaard c06a5e
+            break;
Mark Wielaard c06a5e
+         default:
Mark Wielaard c06a5e
+            goto decode_failure;
Mark Wielaard c06a5e
+         }
Mark Wielaard c06a5e
+         break;
Mark Wielaard c06a5e
+
Mark Wielaard c06a5e
       case 0xA4: sz = 1;   /* REP MOVS<sz> */
Mark Wielaard c06a5e
       case 0xA5:
Mark Wielaard c06a5e
          dis_REP_op ( &dres, X86CondAlways, dis_MOVS, sz, eip_orig,