Improved version of trace cache patch:
- configure support - ability to configure legacy ICACHE without trace cache - only with legacy ICACHE - still support INSTR_OPCODE callback - info in main.cc
This commit is contained in:
parent
91add6a05a
commit
06550b3fdd
@ -1,7 +1,77 @@
|
||||
diff -ur bochs/config.h.in bochs-trace-cache/config.h.in
|
||||
--- bochs/config.h.in 2007-11-22 08:28:05.000000000 +0200
|
||||
+++ bochs-trace-cache/config.h.in 2007-11-26 19:37:19.218750000 +0200
|
||||
@@ -730,6 +730,11 @@
|
||||
#define BX_SupportHostAsms 0
|
||||
|
||||
#define BX_SUPPORT_ICACHE 0
|
||||
+#define BX_SUPPORT_TRACE_CACHE 0
|
||||
+
|
||||
+#if (BX_SUPPORT_TRACE_CACHE && BX_SUPPORT_ICACHE==0)
|
||||
+#error Trace cache optimizatin cannot be compiled without iCache!
|
||||
+#endif
|
||||
|
||||
// if 1, don't do gpf on MSRs that we don't implement
|
||||
#define BX_IGNORE_BAD_MSR 0
|
||||
diff -ur bochs/configure.in bochs-trace-cache/configure.in
|
||||
--- bochs/configure.in 2007-11-23 14:47:12.000000000 +0200
|
||||
+++ bochs-trace-cache/configure.in 2007-11-26 19:39:44.546875000 +0200
|
||||
@@ -1006,6 +1006,27 @@
|
||||
]
|
||||
)
|
||||
|
||||
+AC_MSG_CHECKING(for instruction trace cache support)
|
||||
+AC_ARG_ENABLE(trace-cache,
|
||||
+ [ --enable-trace-cache support instruction trace cache],
|
||||
+ [if test "$enableval" = yes; then
|
||||
+ AC_MSG_RESULT(yes)
|
||||
+ speedup_TraceCache=1
|
||||
+ else
|
||||
+ AC_MSG_RESULT(no)
|
||||
+ speedup_TraceCache=0
|
||||
+ fi],
|
||||
+ [
|
||||
+ if test "$speedup_TraceCache " = 1; then
|
||||
+ AC_MSG_RESULT(yes)
|
||||
+ speedup_TraceCache=1
|
||||
+ else
|
||||
+ AC_MSG_RESULT(no)
|
||||
+ speedup_TraceCache=0
|
||||
+ fi
|
||||
+ ]
|
||||
+ )
|
||||
+
|
||||
AC_MSG_CHECKING(for instruction cache support)
|
||||
AC_ARG_ENABLE(icache,
|
||||
[ --enable-icache support instruction cache],
|
||||
@@ -1262,6 +1283,10 @@
|
||||
speedup_fastcall=1
|
||||
fi
|
||||
|
||||
+if test "$speedup_iCache" = 0 -a "$speedup_TraceCache" = 1; then
|
||||
+ AC_MSG_ERROR([iCache is require to compile with trace cache optimization])
|
||||
+fi
|
||||
+
|
||||
if test "$speedup_guest2host_tlb" = 1; then
|
||||
AC_DEFINE(BX_SupportGuest2HostTLB, 1)
|
||||
else
|
||||
@@ -1292,6 +1317,12 @@
|
||||
AC_DEFINE(BX_FAST_FUNC_CALL, 0)
|
||||
fi
|
||||
|
||||
+if test "$speedup_TraceCache" = 1; then
|
||||
+ AC_DEFINE(BX_SUPPORT_TRACE_CACHE, 1)
|
||||
+else
|
||||
+ AC_DEFINE(BX_SUPPORT_TRACE_CACHE, 0)
|
||||
+fi
|
||||
+
|
||||
|
||||
READLINE_LIB=""
|
||||
rl_without_curses_ok=no
|
||||
diff -ur bochs/cpu/cpu.cc bochs-trace-cache/cpu/cpu.cc
|
||||
--- bochs/cpu/cpu.cc 2007-11-24 16:22:32.000000000 +0200
|
||||
+++ bochs-trace-cache/cpu/cpu.cc 2007-11-24 16:29:57.078125000 +0200
|
||||
@@ -62,16 +62,19 @@
|
||||
+++ bochs-trace-cache/cpu/cpu.cc 2007-11-26 19:32:46.359375000 +0200
|
||||
@@ -62,16 +62,20 @@
|
||||
#if InstrumentICACHE
|
||||
static unsigned iCacheLookups=0;
|
||||
static unsigned iCacheMisses=0;
|
||||
@ -20,53 +90,33 @@ diff -ur bochs/cpu/cpu.cc bochs-trace-cache/cpu/cpu.cc
|
||||
(iCacheLookups-iCacheMisses) * 100.0 / iCacheLookups)); \
|
||||
- iCacheLookups = iCacheMisses = 0; \
|
||||
+ iCacheLookups = iCacheMisses = iCacheMergeTraces = 0; \
|
||||
+ for (int i=0;i<=BX_MAX_TRACE_LENGTH;i++) iCacheLength[i] = 0; \
|
||||
} \
|
||||
}
|
||||
#define InstrICache_Increment(v) (v)++
|
||||
@@ -90,49 +93,125 @@
|
||||
@@ -90,7 +94,118 @@
|
||||
#define RCX ECX
|
||||
#endif
|
||||
|
||||
-BX_CPP_INLINE bxInstruction_c* BX_CPU_C::fetchInstruction(bxInstruction_c *iStorage, bx_address eipBiased)
|
||||
-{
|
||||
- unsigned ret;
|
||||
- bxInstruction_c *i = iStorage;
|
||||
-
|
||||
#if BX_SUPPORT_ICACHE
|
||||
+#if BX_SUPPORT_TRACE_CACHE
|
||||
+
|
||||
+bxICacheEntry_c* BX_CPU_C::fetchInstructionTrace(bxInstruction_c *iStorage, bx_address eipBiased)
|
||||
+{
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrA20Page + eipBiased;
|
||||
unsigned iCacheHash = BX_CPU_THIS_PTR iCache.hash(pAddr);
|
||||
- bxICacheEntry_c *cache_entry = &(BX_CPU_THIS_PTR iCache.entry[iCacheHash]);
|
||||
- i = &(cache_entry->i);
|
||||
-
|
||||
+ bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrA20Page + eipBiased;
|
||||
+ unsigned iCacheHash = BX_CPU_THIS_PTR iCache.hash(pAddr);
|
||||
+ bxICacheEntry_c *trace = &(BX_CPU_THIS_PTR iCache.entry[iCacheHash]);
|
||||
Bit32u pageWriteStamp = *(BX_CPU_THIS_PTR currPageWriteStampPtr);
|
||||
|
||||
InstrICache_Increment(iCacheLookups);
|
||||
InstrICache_Stats();
|
||||
|
||||
- if ((cache_entry->pAddr == pAddr) &&
|
||||
- (cache_entry->writeStamp == pageWriteStamp))
|
||||
+ Bit32u pageWriteStamp = *(BX_CPU_THIS_PTR currPageWriteStampPtr);
|
||||
+
|
||||
+ InstrICache_Increment(iCacheLookups);
|
||||
+ InstrICache_Stats();
|
||||
+
|
||||
+ if ((trace->pAddr == pAddr) &&
|
||||
+ (trace->writeStamp == pageWriteStamp))
|
||||
{
|
||||
- // iCache hit. Instruction is already decoded and stored in the
|
||||
- // instruction cache.
|
||||
-#if BX_INSTRUMENTATION
|
||||
- // An instruction was found in the iCache.
|
||||
- BX_INSTR_OPCODE(BX_CPU_ID, BX_CPU_THIS_PTR eipFetchPtr + eipBiased,
|
||||
- i->ilen(), BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b, Is64BitMode());
|
||||
-#endif
|
||||
- return i;
|
||||
+ {
|
||||
+ return trace; // We are lucky - trace cache hit !
|
||||
}
|
||||
-#endif
|
||||
|
||||
- // iCache miss. No validated instruction with matching fetch parameters
|
||||
- // is in the iCache. Or we're not compiling iCache support in, in which
|
||||
- // case we always have an iCache miss. :^)
|
||||
+ }
|
||||
+
|
||||
+ // We are not so lucky, but let's be optimistic - try to build trace from
|
||||
+ // incoming instruction bytes stream !
|
||||
+ trace->pAddr = pAddr;
|
||||
@ -75,16 +125,12 @@ diff -ur bochs/cpu/cpu.cc bochs-trace-cache/cpu/cpu.cc
|
||||
+
|
||||
+ InstrICache_Increment(iCacheMisses);
|
||||
+
|
||||
bx_address remainingInPage = (BX_CPU_THIS_PTR eipPageWindowSize - eipBiased);
|
||||
unsigned maxFetch = 15;
|
||||
if (remainingInPage < 15) maxFetch = remainingInPage;
|
||||
Bit8u *fetchPtr = BX_CPU_THIS_PTR eipFetchPtr + eipBiased;
|
||||
+ bx_address remainingInPage = (BX_CPU_THIS_PTR eipPageWindowSize - eipBiased);
|
||||
+ unsigned maxFetch = 15;
|
||||
+ if (remainingInPage < 15) maxFetch = remainingInPage;
|
||||
+ Bit8u *fetchPtr = BX_CPU_THIS_PTR eipFetchPtr + eipBiased;
|
||||
+ unsigned ret;
|
||||
|
||||
-#if BX_SUPPORT_ICACHE
|
||||
- // The entry will be marked valid if fetchdecode will succeed
|
||||
- cache_entry->writeStamp = ICacheWriteStampInvalid;
|
||||
- InstrICache_Increment(iCacheMisses);
|
||||
+
|
||||
+ // We could include in trace maximum BX_MAX_TRACE_LEN instructions
|
||||
+ unsigned max_length = BX_MAX_TRACE_LENGTH;
|
||||
+ if ((pageWriteStamp & ICacheWriteStampMask) != ICacheWriteStampStart)
|
||||
@ -98,7 +144,7 @@ diff -ur bochs/cpu/cpu.cc bochs-trace-cache/cpu/cpu.cc
|
||||
+ if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64)
|
||||
+ ret = fetchDecode64(fetchPtr, i, maxFetch);
|
||||
+ else
|
||||
#endif
|
||||
+#endif
|
||||
+ ret = fetchDecode32(fetchPtr, i, maxFetch);
|
||||
+
|
||||
+ if (ret==0) {
|
||||
@ -164,39 +210,11 @@ diff -ur bochs/cpu/cpu.cc bochs-trace-cache/cpu/cpu.cc
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+BX_CPP_INLINE bxInstruction_c* BX_CPU_C::fetchInstruction(bxInstruction_c *iStorage, bx_address eipBiased)
|
||||
+{
|
||||
+ bxInstruction_c *i = iStorage;
|
||||
+ bx_address remainingInPage = (BX_CPU_THIS_PTR eipPageWindowSize - eipBiased);
|
||||
+ unsigned maxFetch = 15;
|
||||
+ if (remainingInPage < 15) maxFetch = remainingInPage;
|
||||
+ Bit8u *fetchPtr = BX_CPU_THIS_PTR eipFetchPtr + eipBiased;
|
||||
+ unsigned ret;
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64)
|
||||
@@ -142,26 +221,14 @@
|
||||
ret = fetchDecode32(fetchPtr, i, maxFetch);
|
||||
|
||||
if (ret==0) {
|
||||
- // return iStorage and leave icache entry invalid (do not cache instr)
|
||||
- boundaryFetch(fetchPtr, remainingInPage, iStorage);
|
||||
- return iStorage;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
-#if BX_SUPPORT_ICACHE
|
||||
- cache_entry->pAddr = pAddr;
|
||||
- cache_entry->writeStamp = pageWriteStamp;
|
||||
-#endif
|
||||
-#if BX_INSTRUMENTATION
|
||||
- // An instruction was either fetched, or found in the iCache.
|
||||
- BX_INSTR_OPCODE(BX_CPU_ID, fetchPtr, i->ilen(),
|
||||
- BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b, Is64BitMode());
|
||||
-#endif
|
||||
+ boundaryFetch(fetchPtr, remainingInPage, i);
|
||||
}
|
||||
|
||||
+bxInstruction_c* BX_CPU_C::fetchInstruction(bxInstruction_c *iStorage, bx_address eipBiased)
|
||||
{
|
||||
unsigned ret;
|
||||
bxInstruction_c *i = iStorage;
|
||||
@@ -162,6 +277,8 @@
|
||||
return i;
|
||||
}
|
||||
|
||||
@ -205,27 +223,25 @@ diff -ur bochs/cpu/cpu.cc bochs-trace-cache/cpu/cpu.cc
|
||||
// The CHECK_MAX_INSTRUCTIONS macro allows cpu_loop to execute a few
|
||||
// instructions and then return so that the other processors have a chance to
|
||||
// run. This is used by bochs internal debugger or when simulating
|
||||
@@ -244,47 +309,68 @@
|
||||
@@ -244,47 +359,67 @@
|
||||
eipBiased = RIP + BX_CPU_THIS_PTR eipPageBias;
|
||||
}
|
||||
|
||||
- // fetch and decode next instruction
|
||||
- bxInstruction_c *i = fetchInstruction(&iStorage, eipBiased);
|
||||
+#if BX_SUPPORT_TRACE_CACHE == 0
|
||||
+ // fetch and decode single instruction
|
||||
bxInstruction_c *i = fetchInstruction(&iStorage, eipBiased);
|
||||
+#else
|
||||
+ unsigned n, length = 1;
|
||||
+ bxInstruction_c *i = &iStorage;
|
||||
+ unsigned length = 1, n;
|
||||
+
|
||||
+#if BX_SUPPORT_ICACHE
|
||||
+ bxICacheEntry_c *trace = fetchInstructionTrace(&iStorage, eipBiased);
|
||||
+ if (trace) {
|
||||
+ i = trace->i; // execute from first instruction in trace
|
||||
+ length = trace->ilen;
|
||||
+ }
|
||||
+#else
|
||||
+ // fetch and decode single instruction
|
||||
+ i = fetchInstruction(&iStorage, eipBiased);
|
||||
+#endif
|
||||
+
|
||||
+ for (n=0; n < length; n++, i++) {
|
||||
+#endif
|
||||
|
||||
- BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
||||
+ BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
||||
@ -288,19 +304,19 @@ diff -ur bochs/cpu/cpu.cc bochs-trace-cache/cpu/cpu.cc
|
||||
- CHECK_MAX_INSTRUCTIONS(max_instr_count);
|
||||
+ CHECK_MAX_INSTRUCTIONS(max_instr_count);
|
||||
+
|
||||
+#if BX_SUPPORT_ICACHE
|
||||
+#if BX_SUPPORT_TRACE_CACHE
|
||||
+ if (trace && trace->writeStamp != *(BX_CPU_THIS_PTR currPageWriteStampPtr))
|
||||
+ break; // probably it is self modifying code ...
|
||||
+#endif
|
||||
+
|
||||
+ if (BX_CPU_THIS_PTR async_event) break;
|
||||
+ }
|
||||
+#endif
|
||||
} // while (1)
|
||||
}
|
||||
|
||||
diff -ur bochs/cpu/cpu.h bochs-trace-cache/cpu/cpu.h
|
||||
--- bochs/cpu/cpu.h 2007-11-24 16:22:32.000000000 +0200
|
||||
+++ bochs-trace-cache/cpu/cpu.h 2007-11-24 16:27:05.218750000 +0200
|
||||
--- bochs/cpu/cpu.h 2007-11-25 22:22:06.000000000 +0200
|
||||
+++ bochs-trace-cache/cpu/cpu.h 2007-11-26 19:30:42.984375000 +0200
|
||||
@@ -615,9 +615,10 @@
|
||||
void (BX_CPU_C::*execute)(bxInstruction_c *);
|
||||
#endif
|
||||
@ -318,7 +334,7 @@ diff -ur bochs/cpu/cpu.h bochs-trace-cache/cpu/cpu.h
|
||||
metaInfo3 = (metaInfo3 & ~3) | (value);
|
||||
}
|
||||
|
||||
+#if BX_SUPPORT_ICACHE
|
||||
+#if BX_SUPPORT_TRACE_CACHE
|
||||
+ BX_CPP_INLINE void setStopTraceAttr(void) {
|
||||
+ metaInfo3 |= (1<<3);
|
||||
+ }
|
||||
@ -339,11 +355,11 @@ diff -ur bochs/cpu/cpu.h bochs-trace-cache/cpu/cpu.h
|
||||
}
|
||||
};
|
||||
// <TAG-CLASS-INSTRUCTION-END>
|
||||
@@ -2917,7 +2927,12 @@
|
||||
@@ -2931,7 +2941,12 @@
|
||||
#if BX_SUPPORT_X86_64
|
||||
BX_SMF unsigned fetchDecode64(Bit8u *, bxInstruction_c *, unsigned);
|
||||
#endif
|
||||
+#if BX_SUPPORT_ICACHE
|
||||
+#if BX_SUPPORT_TRACE_CACHE
|
||||
+ BX_SMF bxICacheEntry_c* fetchInstructionTrace(bxInstruction_c *, bx_address);
|
||||
+ BX_SMF bx_bool mergeTraces(bxICacheEntry_c *trace, bxInstruction_c *i, bx_phy_address pAddr);
|
||||
+#else
|
||||
@ -352,11 +368,11 @@ diff -ur bochs/cpu/cpu.h bochs-trace-cache/cpu/cpu.h
|
||||
BX_SMF void UndefinedOpcode(bxInstruction_c *);
|
||||
BX_SMF void BxError(bxInstruction_c *i);
|
||||
|
||||
@@ -3742,6 +3757,12 @@
|
||||
@@ -3756,6 +3771,12 @@
|
||||
#define BxLockable 0x0100 // bit 8
|
||||
#define Bx3ByteOpcode 0x0200 // bit 9
|
||||
|
||||
+#if BX_SUPPORT_ICACHE
|
||||
+#if BX_SUPPORT_TRACE_CACHE
|
||||
+ #define BxTraceEnd 0x2000 // bit 13
|
||||
+#else
|
||||
+ #define BxTraceEnd 0
|
||||
@ -366,8 +382,8 @@ diff -ur bochs/cpu/cpu.h bochs-trace-cache/cpu/cpu.h
|
||||
#define BxGroup2 BxGroupN
|
||||
#define BxGroup3 BxGroupN
|
||||
diff -ur bochs/cpu/fetchdecode.cc bochs-trace-cache/cpu/fetchdecode.cc
|
||||
--- bochs/cpu/fetchdecode.cc 2007-11-23 18:37:05.000000000 +0200
|
||||
+++ bochs-trace-cache/cpu/fetchdecode.cc 2007-11-24 16:27:06.890625000 +0200
|
||||
--- bochs/cpu/fetchdecode.cc 2007-11-25 22:22:06.000000000 +0200
|
||||
+++ bochs-trace-cache/cpu/fetchdecode.cc 2007-11-26 19:34:29.234375000 +0200
|
||||
@@ -207,7 +207,7 @@
|
||||
/* 14 /wr */ { BxImmediate_Ib, &BX_CPU_C::ADC_ALIb },
|
||||
/* 15 /wr */ { BxImmediate_Iv, &BX_CPU_C::ADC_AXIw },
|
||||
@ -860,7 +876,7 @@ diff -ur bochs/cpu/fetchdecode.cc bochs-trace-cache/cpu/fetchdecode.cc
|
||||
/* 0F B8 /dr */ { BxPrefixSSE, NULL, BxOpcodeGroupSSE_0fb8d },
|
||||
- /* 0F B9 /dr */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
+ /* 0F B9 /dr */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
/* 0F BA /dr */ { BxGroup8, NULL, BxOpcodeInfoG8EdIb },
|
||||
/* 0F BA /dr */ { BxGroup8, NULL, BxOpcodeInfoG8EdIbR },
|
||||
/* 0F BB /dr */ { 0, &BX_CPU_C::BTC_EdGdR },
|
||||
/* 0F BC /dr */ { 0, &BX_CPU_C::BSF_GdEd },
|
||||
@@ -1342,7 +1342,7 @@
|
||||
@ -1112,7 +1128,7 @@ diff -ur bochs/cpu/fetchdecode.cc bochs-trace-cache/cpu/fetchdecode.cc
|
||||
/* 0F B8 /wm */ { BxPrefixSSE, NULL, BxOpcodeGroupSSE_0fb8w },
|
||||
- /* 0F B9 /wm */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
+ /* 0F B9 /wm */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
/* 0F BA /wm */ { BxGroup8, NULL, BxOpcodeInfoG8EwIb },
|
||||
/* 0F BA /wm */ { BxGroup8, NULL, BxOpcodeInfoG8EwIbM },
|
||||
/* 0F BB /wm */ { BxLockable, &BX_CPU_C::BTC_EwGwM },
|
||||
/* 0F BC /wm */ { 0, &BX_CPU_C::BSF_GwEw },
|
||||
@@ -1906,7 +1906,7 @@
|
||||
@ -1364,12 +1380,12 @@ diff -ur bochs/cpu/fetchdecode.cc bochs-trace-cache/cpu/fetchdecode.cc
|
||||
/* 0F B8 /dm */ { BxPrefixSSE, NULL, BxOpcodeGroupSSE_0fb8d },
|
||||
- /* 0F B9 /dm */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
+ /* 0F B9 /dm */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
/* 0F BA /dm */ { BxGroup8, NULL, BxOpcodeInfoG8EdIb },
|
||||
/* 0F BA /dm */ { BxGroup8, NULL, BxOpcodeInfoG8EdIbM },
|
||||
/* 0F BB /dm */ { BxLockable, &BX_CPU_C::BTC_EdGdM },
|
||||
/* 0F BC /dm */ { 0, &BX_CPU_C::BSF_GdEd },
|
||||
@@ -2799,10 +2799,15 @@
|
||||
// lock prefix not allowed or destination operand is not memory
|
||||
if ((mod == 0xc0) || !(attr & BxLockable)) {
|
||||
@@ -2800,10 +2800,15 @@
|
||||
// mod == 0xc0 can't be BxLockable in fetchdecode tables
|
||||
if (/*(mod == 0xc0) ||*/ !(attr & BxLockable)) {
|
||||
BX_INFO(("LOCK prefix unallowed (op1=0x%x, attr=0x%x, mod=0x%x, nnn=%u)", b1, attr, mod, nnn));
|
||||
- UndefinedOpcode(instruction);
|
||||
+ // replace execution function with undefined-opcode
|
||||
@ -1377,18 +1393,18 @@ diff -ur bochs/cpu/fetchdecode.cc bochs-trace-cache/cpu/fetchdecode.cc
|
||||
}
|
||||
}
|
||||
|
||||
+#if BX_SUPPORT_ICACHE
|
||||
+#if BX_SUPPORT_TRACE_CACHE
|
||||
+ if (attr & BxTraceEnd) instruction->setStopTraceAttr();
|
||||
+#endif
|
||||
+
|
||||
imm_mode = attr & BxImmediate;
|
||||
if (imm_mode) {
|
||||
switch (imm_mode) {
|
||||
@@ -2937,8 +2942,16 @@
|
||||
@@ -2938,8 +2943,16 @@
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_SEG_REG_DS);
|
||||
|
||||
+#if BX_SUPPORT_ICACHE
|
||||
+#if BX_SUPPORT_TRACE_CACHE
|
||||
+ // set stop-trace attribute for invalid instructions
|
||||
+ if(instruction->execute == &BX_CPU_C::BxError) {
|
||||
+ instruction->setStopTraceAttr();
|
||||
@ -1402,8 +1418,8 @@ diff -ur bochs/cpu/fetchdecode.cc bochs-trace-cache/cpu/fetchdecode.cc
|
||||
}
|
||||
|
||||
diff -ur bochs/cpu/fetchdecode.h bochs-trace-cache/cpu/fetchdecode.h
|
||||
--- bochs/cpu/fetchdecode.h 2007-11-18 01:28:31.000000000 +0200
|
||||
+++ bochs-trace-cache/cpu/fetchdecode.h 2007-11-23 15:33:02.234375000 +0200
|
||||
--- bochs/cpu/fetchdecode.h 2007-11-25 22:22:10.000000000 +0200
|
||||
+++ bochs-trace-cache/cpu/fetchdecode.h 2007-11-26 19:30:46.515625000 +0200
|
||||
@@ -2869,10 +2869,10 @@
|
||||
// attributes defined in main area
|
||||
/* 0 */ { BxLockable, &BX_CPU_C::INC_EwM },
|
||||
@ -1610,10 +1626,10 @@ diff -ur bochs/cpu/fetchdecode.h bochs-trace-cache/cpu/fetchdecode.h
|
||||
};
|
||||
#endif
|
||||
|
||||
Files bochs/cpu/fetchdecode.o and bochs-trace-cache/cpu/fetchdecode.o differ
|
||||
Only in bochs-trace-cache/cpu: fetchdecode.o
|
||||
diff -ur bochs/cpu/fetchdecode64.cc bochs-trace-cache/cpu/fetchdecode64.cc
|
||||
--- bochs/cpu/fetchdecode64.cc 2007-11-24 16:22:33.000000000 +0200
|
||||
+++ bochs-trace-cache/cpu/fetchdecode64.cc 2007-11-24 16:29:38.359375000 +0200
|
||||
--- bochs/cpu/fetchdecode64.cc 2007-11-25 22:22:10.000000000 +0200
|
||||
+++ bochs-trace-cache/cpu/fetchdecode64.cc 2007-11-26 19:34:57.875000000 +0200
|
||||
@@ -285,22 +285,22 @@
|
||||
/* 6D /wr */ { 0, &BX_CPU_C::REP_INSW_YwDX },
|
||||
/* 6E /wr */ { 0, &BX_CPU_C::REP_OUTSB_DXXb },
|
||||
@ -1811,7 +1827,7 @@ diff -ur bochs/cpu/fetchdecode64.cc bochs-trace-cache/cpu/fetchdecode64.cc
|
||||
/* 0F B8 /wr */ { BxPrefixSSE, NULL, BxOpcodeGroupSSE_0fb8w },
|
||||
- /* 0F B9 /wr */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
+ /* 0F B9 /wr */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
/* 0F BA /wr */ { BxGroup8, NULL, BxOpcodeInfoG8EwIb },
|
||||
/* 0F BA /wr */ { BxGroup8, NULL, BxOpcodeInfoG8EwIbR },
|
||||
/* 0F BB /wr */ { 0, &BX_CPU_C::BTC_EwGwR },
|
||||
/* 0F BC /wr */ { 0, &BX_CPU_C::BSF_GwEw },
|
||||
@@ -814,22 +814,22 @@
|
||||
@ -2011,7 +2027,7 @@ diff -ur bochs/cpu/fetchdecode64.cc bochs-trace-cache/cpu/fetchdecode64.cc
|
||||
/* 0F B8 /dr */ { BxPrefixSSE, NULL, BxOpcodeGroupSSE_0fb8d },
|
||||
- /* 0F B9 /dr */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
+ /* 0F B9 /dr */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
/* 0F BA /dr */ { BxGroup8, NULL, BxOpcodeInfoG8EdIb },
|
||||
/* 0F BA /dr */ { BxGroup8, NULL, BxOpcodeInfoG8EdIbR },
|
||||
/* 0F BB /dr */ { 0, &BX_CPU_C::BTC_EdGdR },
|
||||
/* 0F BC /dr */ { 0, &BX_CPU_C::BSF_GdEd },
|
||||
@@ -1343,22 +1343,22 @@
|
||||
@ -2211,7 +2227,7 @@ diff -ur bochs/cpu/fetchdecode64.cc bochs-trace-cache/cpu/fetchdecode64.cc
|
||||
/* 0F B8 /qr */ { BxPrefixSSE, NULL, BxOpcodeGroupSSE_0fb8q },
|
||||
- /* 0F B9 /qr */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
+ /* 0F B9 /qr */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
/* 0F BA /qr */ { BxGroup8, NULL, BxOpcodeInfo64G8EqIb },
|
||||
/* 0F BA /qr */ { BxGroup8, NULL, BxOpcodeInfo64G8EqIbR },
|
||||
/* 0F BB /qr */ { 0, &BX_CPU_C::BTC_EqGqR },
|
||||
/* 0F BC /qr */ { 0, &BX_CPU_C::BSF_GqEq },
|
||||
@@ -1878,22 +1878,22 @@
|
||||
@ -2411,7 +2427,7 @@ diff -ur bochs/cpu/fetchdecode64.cc bochs-trace-cache/cpu/fetchdecode64.cc
|
||||
/* 0F B8 /wm */ { BxPrefixSSE, NULL, BxOpcodeGroupSSE_0fb8w },
|
||||
- /* 0F B9 /wm */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
+ /* 0F B9 /wm */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
/* 0F BA /wm */ { BxGroup8, NULL, BxOpcodeInfoG8EwIb },
|
||||
/* 0F BA /wm */ { BxGroup8, NULL, BxOpcodeInfoG8EwIbM },
|
||||
/* 0F BB /wm */ { BxLockable, &BX_CPU_C::BTC_EwGwM },
|
||||
/* 0F BC /wm */ { 0, &BX_CPU_C::BSF_GwEw },
|
||||
@@ -2407,22 +2407,22 @@
|
||||
@ -2611,7 +2627,7 @@ diff -ur bochs/cpu/fetchdecode64.cc bochs-trace-cache/cpu/fetchdecode64.cc
|
||||
/* 0F B8 /dm */ { BxPrefixSSE, NULL, BxOpcodeGroupSSE_0fb8d },
|
||||
- /* 0F B9 /dm */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
+ /* 0F B9 /dm */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
/* 0F BA /dm */ { BxGroup8, NULL, BxOpcodeInfoG8EdIb },
|
||||
/* 0F BA /dm */ { BxGroup8, NULL, BxOpcodeInfoG8EdIbM },
|
||||
/* 0F BB /dm */ { BxLockable, &BX_CPU_C::BTC_EdGdM },
|
||||
/* 0F BC /dm */ { 0, &BX_CPU_C::BSF_GdEd },
|
||||
@@ -2936,22 +2936,22 @@
|
||||
@ -2811,12 +2827,12 @@ diff -ur bochs/cpu/fetchdecode64.cc bochs-trace-cache/cpu/fetchdecode64.cc
|
||||
/* 0F B8 /qm */ { BxPrefixSSE, NULL, BxOpcodeGroupSSE_0fb8q },
|
||||
- /* 0F B9 /qm */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
+ /* 0F B9 /qm */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode
|
||||
/* 0F BA /qm */ { BxGroup8, NULL, BxOpcodeInfo64G8EqIb },
|
||||
/* 0F BA /qm */ { BxGroup8, NULL, BxOpcodeInfo64G8EqIbM },
|
||||
/* 0F BB /qm */ { BxLockable, &BX_CPU_C::BTC_EqGqM },
|
||||
/* 0F BC /qm */ { 0, &BX_CPU_C::BSF_GqEq },
|
||||
@@ -3767,10 +3767,15 @@
|
||||
// lock prefix not allowed or destination operand is not memory
|
||||
if ((mod == 0xc0) || !(attr & BxLockable)) {
|
||||
@@ -3768,10 +3768,15 @@
|
||||
// mod == 0xc0 can't be BxLockable in fetchdecode tables
|
||||
if (/*(mod == 0xc0) ||*/ !(attr & BxLockable)) {
|
||||
BX_INFO(("LOCK prefix unallowed (op1=0x%x, mod=%u, nnn=%u)", b1, mod, nnn));
|
||||
- UndefinedOpcode(instruction);
|
||||
+ // replace execution function with undefined-opcode
|
||||
@ -2824,18 +2840,18 @@ diff -ur bochs/cpu/fetchdecode64.cc bochs-trace-cache/cpu/fetchdecode64.cc
|
||||
}
|
||||
}
|
||||
|
||||
+#if BX_SUPPORT_ICACHE
|
||||
+#if BX_SUPPORT_TRACE_CACHE
|
||||
+ if (attr & BxTraceEnd) instruction->setStopTraceAttr();
|
||||
+#endif
|
||||
+
|
||||
imm_mode = attr & BxImmediate;
|
||||
if (imm_mode) {
|
||||
switch (imm_mode) {
|
||||
@@ -3889,6 +3894,13 @@
|
||||
@@ -3890,6 +3895,13 @@
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
instruction->setSeg(BX_SEG_REG_DS);
|
||||
|
||||
+#if BX_SUPPORT_ICACHE
|
||||
+#if BX_SUPPORT_TRACE_CACHE
|
||||
+ // set stop-trace attribute for invalid instructions
|
||||
+ if(instruction->execute == &BX_CPU_C::BxError) {
|
||||
+ instruction->setStopTraceAttr();
|
||||
@ -2847,12 +2863,14 @@ diff -ur bochs/cpu/fetchdecode64.cc bochs-trace-cache/cpu/fetchdecode64.cc
|
||||
return(1);
|
||||
diff -ur bochs/cpu/icache.h bochs-trace-cache/cpu/icache.h
|
||||
--- bochs/cpu/icache.h 2007-11-22 19:32:00.000000000 +0200
|
||||
+++ bochs-trace-cache/cpu/icache.h 2007-11-23 15:37:53.703125000 +0200
|
||||
@@ -115,12 +115,15 @@
|
||||
+++ bochs-trace-cache/cpu/icache.h 2007-11-26 18:03:18.316625600 +0200
|
||||
@@ -115,12 +115,21 @@
|
||||
|
||||
#define BxICacheEntries (64 * 1024) // Must be a power of 2.
|
||||
|
||||
+#if BX_SUPPORT_TRACE_CACHE
|
||||
+#define BX_MAX_TRACE_LENGTH 16
|
||||
+#endif
|
||||
+
|
||||
struct bxICacheEntry_c
|
||||
{
|
||||
@ -2860,8 +2878,23 @@ diff -ur bochs/cpu/icache.h bochs-trace-cache/cpu/icache.h
|
||||
Bit32u writeStamp; // Generation ID. Each write to a physical page
|
||||
// decrements this value
|
||||
- bxInstruction_c i; // The instruction decode information
|
||||
+#if BX_SUPPORT_TRACE_CACHE
|
||||
+ Bit32u ilen; // Trace length in instructions
|
||||
+ bxInstruction_c i[BX_MAX_TRACE_LENGTH];
|
||||
+#else
|
||||
+ bxInstruction_c i;
|
||||
+#endif
|
||||
};
|
||||
|
||||
class BOCHSAPI bxICache_c {
|
||||
diff -ur bochs/main.cc bochs-trace-cache/main.cc
|
||||
--- bochs/main.cc 2007-11-20 20:36:26.000000000 +0200
|
||||
+++ bochs-trace-cache/main.cc 2007-11-26 19:41:46.671875000 +0200
|
||||
@@ -1003,6 +1003,7 @@
|
||||
BX_INFO((" Guest2HostTLB support: %s",BX_SupportGuest2HostTLB?"yes":"no"));
|
||||
BX_INFO((" RepeatSpeedups support: %s",BX_SupportRepeatSpeedups?"yes":"no"));
|
||||
BX_INFO((" Icache support: %s",BX_SUPPORT_ICACHE?"yes":"no"));
|
||||
+ BX_INFO((" Trace cache support: %s",BX_SUPPORT_TRACE_CACHE?"yes":"no"));
|
||||
BX_INFO((" Fast function calls: %s",BX_FAST_FUNC_CALL?"yes":"no"));
|
||||
BX_INFO(("Devices configuration"));
|
||||
BX_INFO((" ACPI support: %s",BX_SUPPORT_ACPI?"yes":"no"));
|
||||
|
Loading…
Reference in New Issue
Block a user