x86/amd64 front ends: don't chase a conditional branch that leads
back to the start of the trace. It's better to leave the IR loop
unroller to handle such cases.
git-svn-id: svn://svn.valgrind.org/vex/trunk@1959 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/guest_amd64_toIR.c b/priv/guest_amd64_toIR.c
index 0eba8f0..901792f 100644
--- a/priv/guest_amd64_toIR.c
+++ b/priv/guest_amd64_toIR.c
@@ -14007,12 +14007,15 @@
delta++;
if (resteerCisOk
&& vex_control.guest_chase_cond
+ && (Addr64)d64 != (Addr64)guest_RIP_bbstart
&& jmpDelta < 0
&& resteerOkFn( callback_opaque, d64) ) {
/* Speculation: assume this backward branch is taken. So we
need to emit a side-exit to the insn following this one,
on the negation of the condition, and continue at the
- branch target address (d64). */
+ branch target address (d64). If we wind up back at the
+ first instruction of the trace, just stop; it's better to
+ let the IR loop unroller handle that case. */
stmt( IRStmt_Exit(
mk_amd64g_calculate_condition(
(AMD64Condcode)(1 ^ (opc - 0x70))),
@@ -14025,6 +14028,7 @@
else
if (resteerCisOk
&& vex_control.guest_chase_cond
+ && (Addr64)d64 != (Addr64)guest_RIP_bbstart
&& jmpDelta >= 0
&& resteerOkFn( callback_opaque, guest_RIP_bbstart+delta ) ) {
/* Speculation: assume this forward branch is not taken. So
@@ -15843,12 +15847,15 @@
delta += 4;
if (resteerCisOk
&& vex_control.guest_chase_cond
+ && (Addr64)d64 != (Addr64)guest_RIP_bbstart
&& jmpDelta < 0
&& resteerOkFn( callback_opaque, d64) ) {
/* Speculation: assume this backward branch is taken. So
we need to emit a side-exit to the insn following this
one, on the negation of the condition, and continue at
- the branch target address (d64). */
+ the branch target address (d64). If we wind up back at
+ the first instruction of the trace, just stop; it's
+ better to let the IR loop unroller handle that case. */
stmt( IRStmt_Exit(
mk_amd64g_calculate_condition(
(AMD64Condcode)(1 ^ (opc - 0x80))),
@@ -15861,6 +15868,7 @@
else
if (resteerCisOk
&& vex_control.guest_chase_cond
+ && (Addr64)d64 != (Addr64)guest_RIP_bbstart
&& jmpDelta >= 0
&& resteerOkFn( callback_opaque, guest_RIP_bbstart+delta ) ) {
/* Speculation: assume this forward branch is not taken.
@@ -15868,7 +15876,8 @@
continue disassembling at the insn immediately
following this one. */
stmt( IRStmt_Exit(
- mk_amd64g_calculate_condition((AMD64Condcode)(opc - 0x80)),
+ mk_amd64g_calculate_condition((AMD64Condcode)
+ (opc - 0x80)),
Ijk_Boring,
IRConst_U64(d64) ) );
dres.whatNext = Dis_ResteerC;
diff --git a/priv/guest_x86_toIR.c b/priv/guest_x86_toIR.c
index 7597b9e..edf4e33 100644
--- a/priv/guest_x86_toIR.c
+++ b/priv/guest_x86_toIR.c
@@ -12933,12 +12933,15 @@
delta++;
if (resteerCisOk
&& vex_control.guest_chase_cond
+ && (Addr32)d32 != (Addr32)guest_EIP_bbstart
&& jmpDelta < 0
&& resteerOkFn( callback_opaque, (Addr64)(Addr32)d32) ) {
/* Speculation: assume this backward branch is taken. So we
need to emit a side-exit to the insn following this one,
on the negation of the condition, and continue at the
- branch target address (d32). */
+ branch target address (d32). If we wind up back at the
+ first instruction of the trace, just stop; it's better to
+ let the IR loop unroller handle that case. */
stmt( IRStmt_Exit(
mk_x86g_calculate_condition((X86Condcode)(1 ^ (opc - 0x70))),
Ijk_Boring,
@@ -12950,6 +12953,7 @@
else
if (resteerCisOk
&& vex_control.guest_chase_cond
+ && (Addr32)d32 != (Addr32)guest_EIP_bbstart
&& jmpDelta >= 0
&& resteerOkFn( callback_opaque,
(Addr64)(Addr32)(guest_EIP_bbstart+delta)) ) {
@@ -14484,14 +14488,18 @@
delta += 4;
if (resteerCisOk
&& vex_control.guest_chase_cond
+ && (Addr32)d32 != (Addr32)guest_EIP_bbstart
&& jmpDelta < 0
&& resteerOkFn( callback_opaque, (Addr64)(Addr32)d32) ) {
/* Speculation: assume this backward branch is taken. So
we need to emit a side-exit to the insn following this
one, on the negation of the condition, and continue at
- the branch target address (d32). */
+ the branch target address (d32). If we wind up back at
+ the first instruction of the trace, just stop; it's
+ better to let the IR loop unroller handle that case.*/
stmt( IRStmt_Exit(
- mk_x86g_calculate_condition((X86Condcode)(1 ^ (opc - 0x80))),
+ mk_x86g_calculate_condition((X86Condcode)
+ (1 ^ (opc - 0x80))),
Ijk_Boring,
IRConst_U32(guest_EIP_bbstart+delta) ) );
dres.whatNext = Dis_ResteerC;
@@ -14501,6 +14509,7 @@
else
if (resteerCisOk
&& vex_control.guest_chase_cond
+ && (Addr32)d32 != (Addr32)guest_EIP_bbstart
&& jmpDelta >= 0
&& resteerOkFn( callback_opaque,
(Addr64)(Addr32)(guest_EIP_bbstart+delta)) ) {