From: Julian Seward Date: Sun, 2 Sep 2012 20:38:00 +0000 (+0000) Subject: Merge from trunk, r2478 (Fix LZCNT and TZCNT properly. Fixes #295808.) X-Git-Tag: svn/VALGRIND_3_8_1^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b33388486d8eb7701cdab0ab7cbaa091970a8662;p=thirdparty%2Fvalgrind.git Merge from trunk, r2478 (Fix LZCNT and TZCNT properly. Fixes #295808.) git-svn-id: svn://svn.valgrind.org/vex/branches/VEX_3_8_BRANCH@2505 --- diff --git a/VEX/priv/guest_amd64_toIR.c b/VEX/priv/guest_amd64_toIR.c index 26269c31ab..506b5331a9 100644 --- a/VEX/priv/guest_amd64_toIR.c +++ b/VEX/priv/guest_amd64_toIR.c @@ -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; } diff --git a/VEX/priv/guest_x86_toIR.c b/VEX/priv/guest_x86_toIR.c index cf95adc80f..21a4864448 100644 --- a/VEX/priv/guest_x86_toIR.c +++ b/VEX/priv/guest_x86_toIR.c @@ -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 */ case 0xA5: dis_REP_op ( &dres, X86CondAlways, dis_MOVS, sz, eip_orig,