------------------------------------------------------------------------ r2478 | sewardj | 2012-08-23 22:14:51 +0200 (Thu, 23 Aug 2012) | 4 lines Fix LZCNT and TZCNT properly. Fixes #295808. (Jakub Jelinek, jakub@redhat.com) ------------------------------------------------------------------------ Index: priv/guest_amd64_toIR.c =================================================================== --- valgrind-3.8.0/VEX/priv/guest_amd64_toIR.c (revision 2477) +++ valgrind-3.8.0/VEX/priv/guest_amd64_toIR.c (revision 2478) @@ -20084,13 +20084,16 @@ 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: priv/guest_x86_toIR.c =================================================================== --- valgrind-3.8.0/VEX/priv/guest_x86_toIR.c (revision 2477) +++ valgrind-3.8.0/VEX/priv/guest_x86_toIR.c (revision 2478) @@ -14021,12 +14021,28 @@ 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 */ case 0xA5: dis_REP_op ( &dres, X86CondAlways, dis_MOVS, sz, eip_orig,