Improve accuracy of simulation of bsf/bsr instructions when the word
being scanned is zero. (Zoltan Hidvegi)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@205 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_helpers.S b/coregrind/vg_helpers.S
index e802081..62db9ec 100644
--- a/coregrind/vg_helpers.S
+++ b/coregrind/vg_helpers.S
@@ -343,16 +343,18 @@
.global VG_(helper_bsr)
VG_(helper_bsr):
pushl %eax
+ movl 12(%esp), %eax
bsrl 8(%esp), %eax
- movl %eax, 8(%esp)
+ movl %eax, 12(%esp)
popl %eax
ret
.global VG_(helper_bsf)
VG_(helper_bsf):
pushl %eax
+ movl 12(%esp), %eax
bsfl 8(%esp), %eax
- movl %eax, 8(%esp)
+ movl %eax, 12(%esp)
popl %eax
ret
diff --git a/coregrind/vg_to_ucode.c b/coregrind/vg_to_ucode.c
index 691ef26..4be838c 100644
--- a/coregrind/vg_to_ucode.c
+++ b/coregrind/vg_to_ucode.c
@@ -2758,7 +2758,7 @@
static
Addr dis_bs_E_G ( UCodeBlock* cb, Int sz, Addr eip, Bool fwds )
{
- Int t, ta, helper;
+ Int t, t1, ta, helper;
UInt pair;
UChar dis_buf[50];
UChar modrm;
@@ -2768,8 +2768,13 @@
helper = fwds ? VGOFF_(helper_bsf) : VGOFF_(helper_bsr);
modrm = getUChar(eip);
+ t1 = newTemp(cb);
t = newTemp(cb);
+ uInstr0(cb, CALLM_S, 0);
+ uInstr2(cb, GET, sz, ArchReg, gregOfRM(modrm), TempReg, t1);
+ uInstr1(cb, PUSH, sz, TempReg, t1);
+
if (epartIsReg(modrm)) {
eip++;
uInstr2(cb, GET, sz, ArchReg, eregOfRM(modrm), TempReg, t);
@@ -2790,11 +2795,11 @@
nameIReg(sz, gregOfRM(modrm)));
}
- uInstr0(cb, CALLM_S, 0);
uInstr1(cb, PUSH, sz, TempReg, t);
uInstr1(cb, CALLM, 0, Lit16, helper);
uFlagsRWU(cb, FlagsEmpty, FlagZ, FlagsOSACP);
uInstr1(cb, POP, sz, TempReg, t);
+ uInstr1(cb, POP, sz, TempReg, t);
uInstr2(cb, PUT, sz, TempReg, t, ArchReg, gregOfRM(modrm));
uInstr0(cb, CALLM_E, 0);
diff --git a/vg_helpers.S b/vg_helpers.S
index e802081..62db9ec 100644
--- a/vg_helpers.S
+++ b/vg_helpers.S
@@ -343,16 +343,18 @@
.global VG_(helper_bsr)
VG_(helper_bsr):
pushl %eax
+ movl 12(%esp), %eax
bsrl 8(%esp), %eax
- movl %eax, 8(%esp)
+ movl %eax, 12(%esp)
popl %eax
ret
.global VG_(helper_bsf)
VG_(helper_bsf):
pushl %eax
+ movl 12(%esp), %eax
bsfl 8(%esp), %eax
- movl %eax, 8(%esp)
+ movl %eax, 12(%esp)
popl %eax
ret
diff --git a/vg_to_ucode.c b/vg_to_ucode.c
index 691ef26..4be838c 100644
--- a/vg_to_ucode.c
+++ b/vg_to_ucode.c
@@ -2758,7 +2758,7 @@
static
Addr dis_bs_E_G ( UCodeBlock* cb, Int sz, Addr eip, Bool fwds )
{
- Int t, ta, helper;
+ Int t, t1, ta, helper;
UInt pair;
UChar dis_buf[50];
UChar modrm;
@@ -2768,8 +2768,13 @@
helper = fwds ? VGOFF_(helper_bsf) : VGOFF_(helper_bsr);
modrm = getUChar(eip);
+ t1 = newTemp(cb);
t = newTemp(cb);
+ uInstr0(cb, CALLM_S, 0);
+ uInstr2(cb, GET, sz, ArchReg, gregOfRM(modrm), TempReg, t1);
+ uInstr1(cb, PUSH, sz, TempReg, t1);
+
if (epartIsReg(modrm)) {
eip++;
uInstr2(cb, GET, sz, ArchReg, eregOfRM(modrm), TempReg, t);
@@ -2790,11 +2795,11 @@
nameIReg(sz, gregOfRM(modrm)));
}
- uInstr0(cb, CALLM_S, 0);
uInstr1(cb, PUSH, sz, TempReg, t);
uInstr1(cb, CALLM, 0, Lit16, helper);
uFlagsRWU(cb, FlagsEmpty, FlagZ, FlagsOSACP);
uInstr1(cb, POP, sz, TempReg, t);
+ uInstr1(cb, POP, sz, TempReg, t);
uInstr2(cb, PUT, sz, TempReg, t, ArchReg, gregOfRM(modrm));
uInstr0(cb, CALLM_E, 0);