From d471dea4357568fd23a46179ad1091dbbd5688ab Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Wed, 7 Mar 2007 20:26:02 +0000 Subject: [PATCH] Added trace cache patch --- bochs/patches/bochs-trace-cache.patch.v6 | 1717 ++++++++++++++++++++++ 1 file changed, 1717 insertions(+) create mode 100755 bochs/patches/bochs-trace-cache.patch.v6 diff --git a/bochs/patches/bochs-trace-cache.patch.v6 b/bochs/patches/bochs-trace-cache.patch.v6 new file mode 100755 index 000000000..bd52b428d --- /dev/null +++ b/bochs/patches/bochs-trace-cache.patch.v6 @@ -0,0 +1,1717 @@ +---------------------------------------------------------------------- +Patch name: Trace Cache Speedup +Author: Stanislav Shwartsman +Date: 7 Mar 2007 +Status: + +Detailed description: + +This patch implements trace cache to speed up Bochs simuation. +Measured speedup is between 10% and 15%. + +Patch was created with: + cvs diff -u +Instructions: + To patch, go to main bochs directory. + Type "patch -p0 < THIS_PATCH_FILE". +---------------------------------------------------------------------- + +diff -u -r bochs-trace-cache-root/cpu/cpu.cc bochs-trace-cache/cpu/cpu.cc +--- bochs-trace-cache-root/cpu/cpu.cc 2007-03-06 19:47:18.000000000 +0200 ++++ bochs-trace-cache/cpu/cpu.cc 2007-03-07 20:56:27.921875000 +0200 +@@ -77,16 +77,19 @@ + #if InstrumentICACHE + static unsigned iCacheLookups=0; + static unsigned iCacheMisses=0; ++static unsigned iCacheMergeTraces=0; ++static unsigned iCacheLength[BX_MAX_TRACE_LENGTH+1]; + + #define InstrICache_StatsMask 0xffffff + + #define InstrICache_Stats() {\ + if ((iCacheLookups & InstrICache_StatsMask) == 0) { \ +- BX_INFO(("ICACHE lookups: %u, misses: %u, hit rate = %6.2f%% ", \ ++ BX_INFO(("ICACHE lookups: %u, misses: %u, merges: %u, hit rate = %6.2f%% ", \ + iCacheLookups, \ + iCacheMisses, \ ++ iCacheMergeTraces, \ + (iCacheLookups-iCacheMisses) * 100.0 / iCacheLookups)); \ +- iCacheLookups = iCacheMisses = 0; \ ++ iCacheLookups = iCacheMisses = iCacheMergeTraces = 0; \ + } \ + } + #define InstrICache_Increment(v) (v)++ +@@ -118,49 +121,125 @@ + #define RSP ESP + #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 ++ ++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); +- ++ 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)) ++ 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; ++ trace->writeStamp = ICacheWriteStampInvalid; ++ trace->ilen = 0; ++ ++ 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; ++ 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) ++ max_length = 1; // seems like the entry has SMC ping-pong problem ++ ++ bxInstruction_c *i = trace->i; ++ ++ for (unsigned len=0;len 0) { ++ // The trace is already valid, it has several instructions inside, ++ // in this case just drop the boundary instruction and stop ++ // tracing. ++ break; ++ } ++ // First instruction is boundary fetch, return iStorage and leave ++ // the trace cache entry invalid (do not cache the instruction) ++ boundaryFetch(fetchPtr, remainingInPage, iStorage); ++ return 0; ++ } ++ ++ // add instruction to the trace ... ++ unsigned iLen = i->ilen(); ++ trace->writeStamp = pageWriteStamp; ++ trace->ilen++; ++ if (i->getStopTraceAttr()) break; ++ ++ // ... and continue to the next instruction ++ remainingInPage -= iLen; ++ if (remainingInPage == 0) break; ++ if (remainingInPage < 15) maxFetch = remainingInPage; ++ fetchPtr += iLen; ++ pAddr += iLen; ++ i++; ++ ++ if (mergeTraces(trace, i, pAddr)) break; ++ } ++ ++ InstrICache_Increment(iCacheLength[trace->ilen-1]); ++ ++ return trace; ++} ++ ++bx_bool BX_CPU_C::mergeTraces(bxICacheEntry_c *trace, bxInstruction_c *i, bx_phy_address pAddr) ++{ ++ bxICacheEntry_c *e = &(BX_CPU_THIS_PTR iCache.entry[BX_CPU_THIS_PTR iCache.hash(pAddr)]); ++ ++ if ((e->pAddr == pAddr) && (e->writeStamp == trace->writeStamp)) ++ { ++ // We are lucky - another trace hit ! ++ InstrICache_Increment(iCacheMergeTraces); ++ ++ // determine max amount of instruction to take from another trace ++ unsigned max_length = e->ilen; ++ if (max_length + trace->ilen > BX_MAX_TRACE_LENGTH) ++ max_length = BX_MAX_TRACE_LENGTH - trace->ilen; ++ if(max_length == 0) return 0; ++ ++ memcpy(i, e->i, sizeof(bxInstruction_c)*max_length); ++ trace->ilen += max_length; ++ BX_ASSERT(trace->ilen <= BX_MAX_TRACE_LENGTH); ++ ++ return 1; ++ } ++ ++ return 0; ++} ++ ++#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) +@@ -170,26 +249,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); + } + + return i; + } + ++#endif ++ + void BX_CPU_C::cpu_loop(Bit32u max_instr_count) + { + bxInstruction_c iStorage BX_CPP_AlignN(32); +@@ -207,9 +274,7 @@ + // only from exception function can we get here ... + BX_INSTR_NEW_INSTRUCTION(BX_CPU_ID); + #if BX_GDBSTUB +- if (bx_dbg.gdbstub_enabled) { +- return; +- } ++ if (bx_dbg.gdbstub_enabled) return; + #endif + } + +@@ -251,43 +316,57 @@ + eipBiased = RIP + BX_CPU_THIS_PTR eipPageBias; + } + +- // fetch and decode next instruction +- bxInstruction_c *i = fetchInstruction(&iStorage, eipBiased); +- BxExecutePtr_tR resolveModRM = i->ResolveModrm; // Get as soon as possible for speculation +- BxExecutePtr_t execute = i->execute; // fetch as soon as possible for speculation +- if (resolveModRM) +- BX_CPU_CALL_METHODR(resolveModRM, (i)); +- +- // An instruction will have been fetched using either the normal case, +- // or the boundary fetch (across pages), by this point. +- BX_INSTR_FETCH_DECODE_COMPLETED(BX_CPU_ID, i); ++ 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++) { ++ ++ BxExecutePtr_tR resolveModRM = i->ResolveModrm; // Get as soon as possible for speculation ++ BxExecutePtr_t execute = i->execute; // fetch as soon as possible for speculation ++ if (resolveModRM) ++ BX_CPU_CALL_METHODR(resolveModRM, (i)); ++ ++ // An instruction will have been fetched using either the normal case, ++ // or the boundary fetch (across pages), by this point. ++ BX_INSTR_FETCH_DECODE_COMPLETED(BX_CPU_ID, i); + + #if BX_DEBUGGER || BX_EXTERNAL_DEBUGGER || BX_GDBSTUB + if (dbg_instruction_prolog()) return; + #endif + + #if BX_DISASM +- if (BX_CPU_THIS_PTR trace) { +- // print the instruction that is about to be executed ++ if (BX_CPU_THIS_PTR trace) { ++ // print the instruction that is about to be executed + #if BX_DEBUGGER +- bx_dbg_disassemble_current(BX_CPU_ID, 1); // only one cpu, print time stamp ++ bx_dbg_disassemble_current(BX_CPU_ID, 1); // only one cpu, print time stamp + #else +- debug_disasm_instruction(BX_CPU_THIS_PTR prev_eip); ++ debug_disasm_instruction(BX_CPU_THIS_PTR prev_eip); + #endif +- } ++ } + #endif + +- // decoding instruction compeleted -> continue with execution +- BX_INSTR_BEFORE_EXECUTION(BX_CPU_ID, i); +- RIP += i->ilen(); +- BX_CPU_CALL_METHOD(execute, (i)); // might iterate repeat instruction +- BX_CPU_THIS_PTR prev_eip = RIP; // commit new RIP +- BX_CPU_THIS_PTR prev_esp = RSP; // commit new RSP +- BX_INSTR_AFTER_EXECUTION(BX_CPU_ID, i); +- BX_TICK1_IF_SINGLE_PROCESSOR(); ++ // decoding instruction compeleted -> continue with execution ++ BX_INSTR_BEFORE_EXECUTION(BX_CPU_ID, i); ++ RIP += i->ilen(); ++ BX_CPU_CALL_METHOD(execute, (i)); // might iterate repeat instruction ++ BX_CPU_THIS_PTR prev_eip = RIP; // commit new RIP ++ BX_CPU_THIS_PTR prev_esp = RSP; // commit new RSP ++ BX_INSTR_AFTER_EXECUTION(BX_CPU_ID, i); ++ BX_TICK1_IF_SINGLE_PROCESSOR(); + +- // inform instrumentation about new instruction +- BX_INSTR_NEW_INSTRUCTION(BX_CPU_ID); ++ // inform instrumentation about new instruction ++ BX_INSTR_NEW_INSTRUCTION(BX_CPU_ID); + + // note instr generating exceptions never reach this point + #if BX_DEBUGGER || BX_EXTERNAL_DEBUGGER || BX_GDBSTUB +@@ -295,13 +374,24 @@ + #endif + + #if BX_SUPPORT_SMP || BX_DEBUGGER +- // 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 only when simulating multiple processors. If only +- // one processor, don't waste any cycles on it! +- CHECK_MAX_INSTRUCTIONS(max_instr_count); ++ // 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 only when simulating multiple processors. If only ++ // one processor, don't waste any cycles on it! ++ CHECK_MAX_INSTRUCTIONS(max_instr_count); + #endif + ++#if BX_SUPPORT_ICACHE ++ if (length > 1) { ++ if (trace->writeStamp != *(BX_CPU_THIS_PTR currPageWriteStampPtr)) ++ break; // probably it is self modifying code ... ++ } ++#endif ++ ++ if (BX_CPU_THIS_PTR async_event) break; ++ ++ } // trace execution ++ + } // while (1) + } + +diff -u -r bochs-trace-cache-root/cpu/cpu.h bochs-trace-cache/cpu/cpu.h +--- bochs-trace-cache-root/cpu/cpu.h 2007-03-06 19:47:18.000000000 +0200 ++++ bochs-trace-cache/cpu/cpu.h 2007-03-07 20:53:30.046875000 +0200 +@@ -659,7 +659,7 @@ + // 6...6 os64 + // 5...5 as32 + // 4...4 os32 +- // 3...3 (unused) ++ // 3...3 stop trace (using with trace cache) + // 2...0 seg + Bit32u metaInfo; + +@@ -839,6 +839,15 @@ + } + #endif + ++#if BX_SUPPORT_ICACHE ++ BX_CPP_INLINE void setStopTraceAttr(void) { ++ metaInfo |= (1<<3); ++ } ++ BX_CPP_INLINE unsigned getStopTraceAttr(void) { ++ return metaInfo & (1<<3); ++ } ++#endif ++ + BX_CPP_INLINE unsigned repUsedL(void) { + return metaInfo & (3<<9); + } +@@ -2511,7 +2520,6 @@ + BX_SMF void CMPXCHG16B(bxInstruction_c *); + #endif // #if BX_SUPPORT_X86_64 + +- // mch added + BX_SMF void INVLPG(bxInstruction_c *); + BX_SMF void RSM(bxInstruction_c *); + +@@ -2526,7 +2534,12 @@ + #if BX_SUPPORT_X86_64 + BX_SMF unsigned fetchDecode64(Bit8u *, bxInstruction_c *, unsigned); + #endif ++#if BX_SUPPORT_ICACHE ++ 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 + BX_SMF bxInstruction_c* fetchInstruction(bxInstruction_c *, bx_address); ++#endif + BX_SMF void UndefinedOpcode(bxInstruction_c *); + BX_SMF void BxError(bxInstruction_c *i); + +@@ -2671,6 +2684,10 @@ + BX_SMF bx_bool dbg_instruction_prolog(void); + BX_SMF bx_bool dbg_instruction_epilog(void); + #endif ++#if BX_DEBUGGER || BX_EXTERNAL_DEBUGGER || BX_GDBSTUB ++ BX_SMF bx_bool dbg_instruction_prolog(void); ++ BX_SMF bx_bool dbg_instruction_epilog(void); ++#endif + #if BX_DEBUGGER || BX_DISASM || BX_INSTRUMENTATION || BX_GDBSTUB + BX_SMF bx_bool dbg_xlate_linear2phy(bx_address linear, bx_phy_address *phy); + #endif +@@ -3354,6 +3371,12 @@ + #define BxLockable 0x0200 // bit 9 + #define Bx3ByteOpcode 0x0400 // bit 10 + ++#if BX_SUPPORT_ICACHE ++ #define BxTraceEnd 0x2000 // bit 13 ++#else ++ #define BxTraceEnd 0 ++#endif ++ + #define BxGroup1 BxGroupN + #define BxGroup2 BxGroupN + #define BxGroup3 BxGroupN +diff -u -r bochs-trace-cache-root/cpu/fetchdecode.cc bochs-trace-cache/cpu/fetchdecode.cc +--- bochs-trace-cache-root/cpu/fetchdecode.cc 2007-01-28 23:27:30.000000000 +0200 ++++ bochs-trace-cache/cpu/fetchdecode.cc 2007-03-07 21:34:51.718750000 +0200 +@@ -261,10 +261,10 @@ + // attributes defined in main area + /* 0 */ { BxLockable, &BX_CPU_C::INC_Ew }, + /* 1 */ { BxLockable, &BX_CPU_C::DEC_Ew }, +- /* 2 */ { 0, &BX_CPU_C::CALL_Ew }, +- /* 3 */ { 0, &BX_CPU_C::CALL16_Ep }, +- /* 4 */ { 0, &BX_CPU_C::JMP_Ew }, +- /* 5 */ { 0, &BX_CPU_C::JMP16_Ep }, ++ /* 2 */ { BxTraceEnd, &BX_CPU_C::CALL_Ew }, ++ /* 3 */ { BxTraceEnd, &BX_CPU_C::CALL16_Ep }, ++ /* 4 */ { BxTraceEnd, &BX_CPU_C::JMP_Ew }, ++ /* 5 */ { BxTraceEnd, &BX_CPU_C::JMP16_Ep }, + /* 6 */ { 0, &BX_CPU_C::PUSH_Ew }, + /* 7 */ { 0, &BX_CPU_C::BxError } + }; +@@ -273,10 +273,10 @@ + // attributes defined in main area + /* 0 */ { BxLockable, &BX_CPU_C::INC_Ed }, + /* 1 */ { BxLockable, &BX_CPU_C::DEC_Ed }, +- /* 2 */ { 0, &BX_CPU_C::CALL_Ed }, +- /* 3 */ { 0, &BX_CPU_C::CALL32_Ep }, +- /* 4 */ { 0, &BX_CPU_C::JMP_Ed }, +- /* 5 */ { 0, &BX_CPU_C::JMP32_Ep }, ++ /* 2 */ { BxTraceEnd, &BX_CPU_C::CALL_Ed }, ++ /* 3 */ { BxTraceEnd, &BX_CPU_C::CALL32_Ep }, ++ /* 4 */ { BxTraceEnd, &BX_CPU_C::JMP_Ed }, ++ /* 5 */ { BxTraceEnd, &BX_CPU_C::JMP32_Ep }, + /* 6 */ { 0, &BX_CPU_C::PUSH_Ed }, + /* 7 */ { 0, &BX_CPU_C::BxError } + }; +@@ -296,12 +296,12 @@ + static const BxOpcodeInfo_t BxOpcodeInfoG7[8] = { + /* 0 */ { 0, &BX_CPU_C::SGDT_Ms }, + /* 1 */ { 0, &BX_CPU_C::SIDT_Ms }, +- /* 2 */ { 0, &BX_CPU_C::LGDT_Ms }, +- /* 3 */ { 0, &BX_CPU_C::LIDT_Ms }, ++ /* 2 */ { BxTraceEnd, &BX_CPU_C::LGDT_Ms }, ++ /* 3 */ { BxTraceEnd, &BX_CPU_C::LIDT_Ms }, + /* 4 */ { 0, &BX_CPU_C::SMSW_Ew }, + /* 5 */ { 0, &BX_CPU_C::BxError }, +- /* 6 */ { 0, &BX_CPU_C::LMSW_Ew }, +- /* 7 */ { 0, &BX_CPU_C::INVLPG } ++ /* 6 */ { BxTraceEnd, &BX_CPU_C::LMSW_Ew }, ++ /* 7 */ { BxTraceEnd, &BX_CPU_C::INVLPG } + }; + + static const BxOpcodeInfo_t BxOpcodeInfoG8EwIb[8] = { +@@ -512,22 +512,22 @@ + /* 6D */ { 0, &BX_CPU_C::REP_INSW_YwDX }, + /* 6E */ { 0, &BX_CPU_C::REP_OUTSB_DXXb }, + /* 6F */ { 0, &BX_CPU_C::REP_OUTSW_DXXw }, +- /* 70 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw }, +- /* 71 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw }, +- /* 72 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw }, +- /* 73 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw }, +- /* 74 */ { BxImmediate_BrOff8, &BX_CPU_C::JZ_Jw }, +- /* 75 */ { BxImmediate_BrOff8, &BX_CPU_C::JNZ_Jw }, +- /* 76 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw }, +- /* 77 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw }, +- /* 78 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw }, +- /* 79 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw }, +- /* 7A */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw }, +- /* 7B */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw }, +- /* 7C */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw }, +- /* 7D */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw }, +- /* 7E */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw }, +- /* 7F */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw }, ++ /* 70 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 71 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 72 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 73 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 74 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JZ_Jw }, ++ /* 75 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JNZ_Jw }, ++ /* 76 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 77 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 78 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 79 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 7A */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 7B */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 7C */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 7D */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 7E */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 7F */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, + /* 80 */ { BxAnother | BxGroup1, NULL, BxOpcodeInfoG1EbIb }, + /* 81 */ { BxAnother | BxGroup1 | BxImmediate_Iv, NULL, BxOpcodeInfoG1Ew }, + /* 82 */ { BxAnother | BxGroup1, NULL, BxOpcodeInfoG1EbIb }, +@@ -554,7 +554,7 @@ + /* 97 */ { 0, &BX_CPU_C::XCHG_RXAX }, + /* 98 */ { 0, &BX_CPU_C::CBW }, + /* 99 */ { 0, &BX_CPU_C::CWD }, +- /* 9A */ { BxImmediate_IvIw, &BX_CPU_C::CALL16_Ap }, ++ /* 9A */ { BxImmediate_IvIw | BxTraceEnd, &BX_CPU_C::CALL16_Ap }, + /* 9B */ { 0, &BX_CPU_C::FWAIT }, + /* 9C */ { 0, &BX_CPU_C::PUSHF_Fw }, + /* 9D */ { 0, &BX_CPU_C::POPF_Fw }, +@@ -594,20 +594,20 @@ + /* BF */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw }, + /* C0 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Eb }, + /* C1 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Ew }, +- /* C2 */ { BxImmediate_Iw, &BX_CPU_C::RETnear16_Iw }, +- /* C3 */ { 0, &BX_CPU_C::RETnear16 }, ++ /* C2 */ { BxImmediate_Iw | BxTraceEnd, &BX_CPU_C::RETnear16_Iw }, ++ /* C3 */ { BxTraceEnd, &BX_CPU_C::RETnear16 }, + /* C4 */ { BxAnother, &BX_CPU_C::LES_GvMp }, + /* C5 */ { BxAnother, &BX_CPU_C::LDS_GvMp }, + /* C6 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::MOV_EbIb }, + /* C7 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::MOV_EwIw }, + /* C8 */ { BxImmediate_IwIb, &BX_CPU_C::ENTER_IwIb }, + /* C9 */ { 0, &BX_CPU_C::LEAVE }, +- /* CA */ { BxImmediate_Iw, &BX_CPU_C::RETfar16_Iw }, +- /* CB */ { 0, &BX_CPU_C::RETfar16 }, +- /* CC */ { 0, &BX_CPU_C::INT3 }, +- /* CD */ { BxImmediate_Ib, &BX_CPU_C::INT_Ib }, +- /* CE */ { 0, &BX_CPU_C::INTO }, +- /* CF */ { 0, &BX_CPU_C::IRET16 }, ++ /* CA */ { BxImmediate_Iw | BxTraceEnd, &BX_CPU_C::RETfar16_Iw }, ++ /* CB */ { BxTraceEnd, &BX_CPU_C::RETfar16 }, ++ /* CC */ { BxTraceEnd, &BX_CPU_C::INT3 }, ++ /* CD */ { BxImmediate_Ib | BxTraceEnd, &BX_CPU_C::INT_Ib }, ++ /* CE */ { BxTraceEnd, &BX_CPU_C::INTO }, ++ /* CF */ { BxTraceEnd, &BX_CPU_C::IRET16 }, + /* D0 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Eb }, + /* D1 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Ew }, + /* D2 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Eb }, +@@ -636,27 +636,27 @@ + /* DE */ { BxAnother, &BX_CPU_C::FPU_ESC }, + /* DF */ { BxAnother, &BX_CPU_C::FPU_ESC }, + #endif +- /* E0 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPNE_Jb }, +- /* E1 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPE_Jb }, +- /* E2 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOP_Jb }, +- /* E3 */ { BxImmediate_BrOff8, &BX_CPU_C::JCXZ_Jb }, ++ /* E0 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::LOOPNE_Jb }, ++ /* E1 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::LOOPE_Jb }, ++ /* E2 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::LOOP_Jb }, ++ /* E3 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCXZ_Jb }, + /* E4 */ { BxImmediate_Ib, &BX_CPU_C::IN_ALIb }, + /* E5 */ { BxImmediate_Ib, &BX_CPU_C::IN_AXIb }, + /* E6 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbAL }, + /* E7 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbAX }, +- /* E8 */ { BxImmediate_BrOff16, &BX_CPU_C::CALL_Aw }, +- /* E9 */ { BxImmediate_BrOff16, &BX_CPU_C::JMP_Jw }, +- /* EA */ { BxImmediate_IvIw, &BX_CPU_C::JMP_Ap }, +- /* EB */ { BxImmediate_BrOff8, &BX_CPU_C::JMP_Jw }, ++ /* E8 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::CALL_Aw }, ++ /* E9 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JMP_Jw }, ++ /* EA */ { BxImmediate_IvIw | BxTraceEnd, &BX_CPU_C::JMP_Ap }, ++ /* EB */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JMP_Jw }, + /* EC */ { 0, &BX_CPU_C::IN_ALDX }, + /* ED */ { 0, &BX_CPU_C::IN_AXDX }, + /* EE */ { 0, &BX_CPU_C::OUT_DXAL }, + /* EF */ { 0, &BX_CPU_C::OUT_DXAX }, + /* F0 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // LOCK +- /* F1 */ { 0, &BX_CPU_C::INT1 }, ++ /* F1 */ { BxTraceEnd, &BX_CPU_C::INT1 }, + /* F2 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REPNE/REPNZ + /* F3 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REP, REPE/REPZ +- /* F4 */ { 0, &BX_CPU_C::HLT }, ++ /* F4 */ { BxTraceEnd, &BX_CPU_C::HLT }, + /* F5 */ { 0, &BX_CPU_C::CMC }, + /* F6 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfoG3Eb }, + /* F7 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfoG3Ew }, +@@ -675,22 +675,22 @@ + /* 0F 03 */ { BxAnother, &BX_CPU_C::LSL_GvEw }, + /* 0F 04 */ { 0, &BX_CPU_C::BxError }, + #if BX_SUPPORT_X86_64 +- /* 0F 05 */ { 0, &BX_CPU_C::SYSCALL }, ++ /* 0F 05 */ { BxTraceEnd, &BX_CPU_C::SYSCALL }, + #elif BX_CPU_LEVEL == 2 +- /* 0F 05 */ { 0, &BX_CPU_C::LOADALL }, ++ /* 0F 05 */ { BxTraceEnd, &BX_CPU_C::LOADALL }, + #else + /* 0F 05 */ { 0, &BX_CPU_C::BxError }, + #endif + /* 0F 06 */ { 0, &BX_CPU_C::CLTS }, + #if BX_SUPPORT_X86_64 +- /* 0F 07 */ { 0, &BX_CPU_C::SYSRET }, ++ /* 0F 07 */ { BxTraceEnd, &BX_CPU_C::SYSRET }, + #else + /* 0F 07 */ { 0, &BX_CPU_C::BxError }, + #endif +- /* 0F 08 */ { 0, &BX_CPU_C::INVD }, +- /* 0F 09 */ { 0, &BX_CPU_C::WBINVD }, ++ /* 0F 08 */ { BxTraceEnd, &BX_CPU_C::INVD }, ++ /* 0F 09 */ { BxTraceEnd, &BX_CPU_C::WBINVD }, + /* 0F 0A */ { 0, &BX_CPU_C::BxError }, +- /* 0F 0B */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode ++ /* 0F 0B */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode + /* 0F 0C */ { 0, &BX_CPU_C::BxError }, + #if BX_SUPPORT_X86_64 || BX_SUPPORT_3DNOW + /* 0F 0D */ { BxAnother, &BX_CPU_C::NOP }, // 3DNow! PREFETCH on AMD, NOP on Intel +@@ -726,11 +726,11 @@ + #endif + /* 0F 20 */ { BxAnother, &BX_CPU_C::MOV_RdCd }, + /* 0F 21 */ { BxAnother, &BX_CPU_C::MOV_RdDd }, +- /* 0F 22 */ { BxAnother, &BX_CPU_C::MOV_CdRd }, ++ /* 0F 22 */ { BxAnother | BxTraceEnd, &BX_CPU_C::MOV_CdRd }, + /* 0F 23 */ { BxAnother, &BX_CPU_C::MOV_DdRd }, +- /* 0F 24 */ { BxAnother, &BX_CPU_C::MOV_RdTd }, ++ /* 0F 24 */ { BxAnother | BxTraceEnd, &BX_CPU_C::MOV_RdTd }, + /* 0F 25 */ { 0, &BX_CPU_C::BxError }, +- /* 0F 26 */ { BxAnother, &BX_CPU_C::MOV_TdRd }, ++ /* 0F 26 */ { BxAnother | BxTraceEnd, &BX_CPU_C::MOV_TdRd }, + /* 0F 27 */ { 0, &BX_CPU_C::BxError }, + /* 0F 28 */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f28 }, + /* 0F 29 */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f29 }, +@@ -740,12 +740,12 @@ + /* 0F 2D */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f2d }, + /* 0F 2E */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f2e }, + /* 0F 2F */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f2f }, +- /* 0F 30 */ { 0, &BX_CPU_C::WRMSR }, ++ /* 0F 30 */ { BxTraceEnd, &BX_CPU_C::WRMSR }, + /* 0F 31 */ { 0, &BX_CPU_C::RDTSC }, + /* 0F 32 */ { 0, &BX_CPU_C::RDMSR }, + /* 0F 33 */ { 0, &BX_CPU_C::RDPMC }, +- /* 0F 34 */ { 0, &BX_CPU_C::SYSENTER }, +- /* 0F 35 */ { 0, &BX_CPU_C::SYSEXIT }, ++ /* 0F 34 */ { BxTraceEnd, &BX_CPU_C::SYSENTER }, ++ /* 0F 35 */ { BxTraceEnd, &BX_CPU_C::SYSEXIT }, + /* 0F 36 */ { 0, &BX_CPU_C::BxError }, + /* 0F 37 */ { 0, &BX_CPU_C::BxError }, + #if BX_SUPPORT_SSE3E || BX_SUPPORT_SSE >= 4 +@@ -828,22 +828,22 @@ + /* 0F 7D */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f7d }, + /* 0F 7E */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f7e }, + /* 0F 7F */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f7f }, +- /* 0F 80 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw }, +- /* 0F 81 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw }, +- /* 0F 82 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw }, +- /* 0F 83 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw }, +- /* 0F 84 */ { BxImmediate_BrOff16, &BX_CPU_C::JZ_Jw }, +- /* 0F 85 */ { BxImmediate_BrOff16, &BX_CPU_C::JNZ_Jw }, +- /* 0F 86 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw }, +- /* 0F 87 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw }, +- /* 0F 88 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw }, +- /* 0F 89 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw }, +- /* 0F 8A */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw }, +- /* 0F 8B */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw }, +- /* 0F 8C */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw }, +- /* 0F 8D */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw }, +- /* 0F 8E */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw }, +- /* 0F 8F */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw }, ++ /* 0F 80 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 0F 81 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 0F 82 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 0F 83 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 0F 84 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JZ_Jw }, ++ /* 0F 85 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JNZ_Jw }, ++ /* 0F 86 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 0F 87 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 0F 88 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 0F 89 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 0F 8A */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 0F 8B */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 0F 8C */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 0F 8D */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 0F 8E */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, ++ /* 0F 8F */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jw }, + /* 0F 90 */ { BxAnother, &BX_CPU_C::SETO_Eb }, + /* 0F 91 */ { BxAnother, &BX_CPU_C::SETNO_Eb }, + /* 0F 92 */ { BxAnother, &BX_CPU_C::SETB_Eb }, +@@ -866,11 +866,11 @@ + /* 0F A3 */ { BxAnother, &BX_CPU_C::BT_EwGw }, + /* 0F A4 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::SHLD_EwGw }, + /* 0F A5 */ { BxAnother, &BX_CPU_C::SHLD_EwGw }, +- /* 0F A6 */ { 0, &BX_CPU_C::CMPXCHG_XBTS }, +- /* 0F A7 */ { 0, &BX_CPU_C::CMPXCHG_IBTS }, ++ /* 0F A6 */ { BxTraceEnd, &BX_CPU_C::CMPXCHG_XBTS }, // Undefined Opcode ++ /* 0F A7 */ { BxTraceEnd, &BX_CPU_C::CMPXCHG_IBTS }, // Undefined Opcode + /* 0F A8 */ { 0, &BX_CPU_C::PUSH16_GS }, + /* 0F A9 */ { 0, &BX_CPU_C::POP16_GS }, +- /* 0F AA */ { 0, &BX_CPU_C::RSM }, ++ /* 0F AA */ { BxTraceEnd, &BX_CPU_C::RSM }, + /* 0F AB */ { BxAnother | BxLockable, &BX_CPU_C::BTS_EwGw }, + /* 0F AC */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::SHRD_EwGw }, + /* 0F AD */ { BxAnother, &BX_CPU_C::SHRD_EwGw }, +@@ -885,7 +885,7 @@ + /* 0F B6 */ { BxAnother, &BX_CPU_C::MOVZX_GwEb }, + /* 0F B7 */ { BxAnother | BxSplitMod11b, NULL, opcodesMOV_GwEw }, // MOVZX_GwEw + /* 0F B8 */ { 0, &BX_CPU_C::BxError }, +- /* 0F B9 */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode ++ /* 0F B9 */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode + /* 0F BA */ { BxAnother | BxGroup8, NULL, BxOpcodeInfoG8EwIb }, + /* 0F BB */ { BxAnother | BxLockable, &BX_CPU_C::BTC_EwGw }, + /* 0F BC */ { BxAnother, &BX_CPU_C::BSF_GwEw }, +@@ -1070,22 +1070,22 @@ + /* 6D */ { 0, &BX_CPU_C::REP_INSD_YdDX }, + /* 6E */ { 0, &BX_CPU_C::REP_OUTSB_DXXb }, + /* 6F */ { 0, &BX_CPU_C::REP_OUTSD_DXXd }, +- /* 70 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd }, +- /* 71 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd }, +- /* 72 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd }, +- /* 73 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd }, +- /* 74 */ { BxImmediate_BrOff8, &BX_CPU_C::JZ_Jd }, +- /* 75 */ { BxImmediate_BrOff8, &BX_CPU_C::JNZ_Jd }, +- /* 76 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd }, +- /* 77 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd }, +- /* 78 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd }, +- /* 79 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd }, +- /* 7A */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd }, +- /* 7B */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd }, +- /* 7C */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd }, +- /* 7D */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd }, +- /* 7E */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd }, +- /* 7F */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd }, ++ /* 70 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 71 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 72 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 73 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 74 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JZ_Jd }, ++ /* 75 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JNZ_Jd }, ++ /* 76 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 77 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 78 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 79 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 7A */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 7B */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 7C */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 7D */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 7E */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 7F */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, + /* 80 */ { BxAnother | BxGroup1, NULL, BxOpcodeInfoG1EbIb }, + /* 81 */ { BxAnother | BxGroup1 | BxImmediate_Iv, NULL, BxOpcodeInfoG1Ed }, + /* 82 */ { BxAnother | BxGroup1, NULL, BxOpcodeInfoG1EbIb }, +@@ -1112,7 +1112,7 @@ + /* 97 */ { 0, &BX_CPU_C::XCHG_ERXEAX }, + /* 98 */ { 0, &BX_CPU_C::CWDE }, + /* 99 */ { 0, &BX_CPU_C::CDQ }, +- /* 9A */ { BxImmediate_IvIw, &BX_CPU_C::CALL32_Ap }, ++ /* 9A */ { BxImmediate_IvIw | BxTraceEnd, &BX_CPU_C::CALL32_Ap }, + /* 9B */ { 0, &BX_CPU_C::FWAIT }, + /* 9C */ { 0, &BX_CPU_C::PUSHF_Fd }, + /* 9D */ { 0, &BX_CPU_C::POPF_Fd }, +@@ -1152,20 +1152,20 @@ + /* BF */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId }, + /* C0 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Eb }, + /* C1 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Ed }, +- /* C2 */ { BxImmediate_Iw, &BX_CPU_C::RETnear32_Iw }, +- /* C3 */ { 0, &BX_CPU_C::RETnear32 }, ++ /* C2 */ { BxImmediate_Iw | BxTraceEnd, &BX_CPU_C::RETnear32_Iw }, ++ /* C3 */ { BxTraceEnd, &BX_CPU_C::RETnear32 }, + /* C4 */ { BxAnother, &BX_CPU_C::LES_GvMp }, + /* C5 */ { BxAnother, &BX_CPU_C::LDS_GvMp }, + /* C6 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::MOV_EbIb }, + /* C7 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::MOV_EdId }, + /* C8 */ { BxImmediate_IwIb, &BX_CPU_C::ENTER_IwIb }, + /* C9 */ { 0, &BX_CPU_C::LEAVE }, +- /* CA */ { BxImmediate_Iw, &BX_CPU_C::RETfar32_Iw }, +- /* CB */ { 0, &BX_CPU_C::RETfar32 }, +- /* CC */ { 0, &BX_CPU_C::INT3 }, +- /* CD */ { BxImmediate_Ib, &BX_CPU_C::INT_Ib }, +- /* CE */ { 0, &BX_CPU_C::INTO }, +- /* CF */ { 0, &BX_CPU_C::IRET32 }, ++ /* CA */ { BxImmediate_Iw | BxTraceEnd, &BX_CPU_C::RETfar32_Iw }, ++ /* CB */ { BxTraceEnd, &BX_CPU_C::RETfar32 }, ++ /* CC */ { BxTraceEnd, &BX_CPU_C::INT3 }, ++ /* CD */ { BxImmediate_Ib | BxTraceEnd, &BX_CPU_C::INT_Ib }, ++ /* CE */ { BxTraceEnd, &BX_CPU_C::INTO }, ++ /* CF */ { BxTraceEnd, &BX_CPU_C::IRET32 }, + /* D0 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Eb }, + /* D1 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Ed }, + /* D2 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Eb }, +@@ -1194,27 +1194,27 @@ + /* DE */ { BxAnother, &BX_CPU_C::FPU_ESC }, + /* DF */ { BxAnother, &BX_CPU_C::FPU_ESC }, + #endif +- /* E0 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPNE_Jb }, +- /* E1 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPE_Jb }, +- /* E2 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOP_Jb }, +- /* E3 */ { BxImmediate_BrOff8, &BX_CPU_C::JCXZ_Jb }, ++ /* E0 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::LOOPNE_Jb }, ++ /* E1 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::LOOPE_Jb }, ++ /* E2 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::LOOP_Jb }, ++ /* E3 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCXZ_Jb }, + /* E4 */ { BxImmediate_Ib, &BX_CPU_C::IN_ALIb }, + /* E5 */ { BxImmediate_Ib, &BX_CPU_C::IN_EAXIb }, + /* E6 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbAL }, + /* E7 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbEAX }, +- /* E8 */ { BxImmediate_BrOff32, &BX_CPU_C::CALL_Ad }, +- /* E9 */ { BxImmediate_BrOff32, &BX_CPU_C::JMP_Jd }, +- /* EA */ { BxImmediate_IvIw, &BX_CPU_C::JMP_Ap }, +- /* EB */ { BxImmediate_BrOff8, &BX_CPU_C::JMP_Jd }, ++ /* E8 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::CALL_Ad }, ++ /* E9 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JMP_Jd }, ++ /* EA */ { BxImmediate_IvIw | BxTraceEnd, &BX_CPU_C::JMP_Ap }, ++ /* EB */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JMP_Jd }, + /* EC */ { 0, &BX_CPU_C::IN_ALDX }, + /* ED */ { 0, &BX_CPU_C::IN_EAXDX }, + /* EE */ { 0, &BX_CPU_C::OUT_DXAL }, + /* EF */ { 0, &BX_CPU_C::OUT_DXEAX }, + /* F0 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // LOCK: +- /* F1 */ { 0, &BX_CPU_C::INT1 }, ++ /* F1 */ { BxTraceEnd, &BX_CPU_C::INT1 }, + /* F2 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REPNE/REPNZ + /* F3 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REP,REPE/REPZ +- /* F4 */ { 0, &BX_CPU_C::HLT }, ++ /* F4 */ { BxTraceEnd, &BX_CPU_C::HLT }, + /* F5 */ { 0, &BX_CPU_C::CMC }, + /* F6 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfoG3Eb }, + /* F7 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfoG3Ed }, +@@ -1233,22 +1233,22 @@ + /* 0F 03 */ { BxAnother, &BX_CPU_C::LSL_GvEw }, + /* 0F 04 */ { 0, &BX_CPU_C::BxError }, + #if BX_SUPPORT_X86_64 +- /* 0F 05 */ { 0, &BX_CPU_C::SYSCALL }, ++ /* 0F 05 */ { BxTraceEnd, &BX_CPU_C::SYSCALL }, + #elif BX_CPU_LEVEL == 2 +- /* 0F 05 */ { 0, &BX_CPU_C::LOADALL }, ++ /* 0F 05 */ { BxTraceEnd, &BX_CPU_C::LOADALL }, + #else + /* 0F 05 */ { 0, &BX_CPU_C::BxError }, + #endif + /* 0F 06 */ { 0, &BX_CPU_C::CLTS }, + #if BX_SUPPORT_X86_64 +- /* 0F 07 */ { 0, &BX_CPU_C::SYSRET }, ++ /* 0F 07 */ { BxTraceEnd, &BX_CPU_C::SYSRET }, + #else + /* 0F 07 */ { 0, &BX_CPU_C::BxError }, + #endif +- /* 0F 08 */ { 0, &BX_CPU_C::INVD }, +- /* 0F 09 */ { 0, &BX_CPU_C::WBINVD }, ++ /* 0F 08 */ { BxTraceEnd, &BX_CPU_C::INVD }, ++ /* 0F 09 */ { BxTraceEnd, &BX_CPU_C::WBINVD }, + /* 0F 0A */ { 0, &BX_CPU_C::BxError }, +- /* 0F 0B */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode ++ /* 0F 0B */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode + /* 0F 0C */ { 0, &BX_CPU_C::BxError }, + #if BX_SUPPORT_X86_64 || BX_SUPPORT_3DNOW + /* 0F 0D */ { BxAnother, &BX_CPU_C::NOP }, // 3DNow! PREFETCH on AMD, NOP on Intel +@@ -1284,11 +1284,11 @@ + #endif + /* 0F 20 */ { BxAnother, &BX_CPU_C::MOV_RdCd }, + /* 0F 21 */ { BxAnother, &BX_CPU_C::MOV_RdDd }, +- /* 0F 22 */ { BxAnother, &BX_CPU_C::MOV_CdRd }, ++ /* 0F 22 */ { BxAnother | BxTraceEnd, &BX_CPU_C::MOV_CdRd }, + /* 0F 23 */ { BxAnother, &BX_CPU_C::MOV_DdRd }, +- /* 0F 24 */ { BxAnother, &BX_CPU_C::MOV_RdTd }, ++ /* 0F 24 */ { BxAnother | BxTraceEnd, &BX_CPU_C::MOV_RdTd }, + /* 0F 25 */ { 0, &BX_CPU_C::BxError }, +- /* 0F 26 */ { BxAnother, &BX_CPU_C::MOV_TdRd }, ++ /* 0F 26 */ { BxAnother | BxTraceEnd, &BX_CPU_C::MOV_TdRd }, + /* 0F 27 */ { 0, &BX_CPU_C::BxError }, + /* 0F 28 */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f28 }, + /* 0F 29 */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f29 }, +@@ -1298,12 +1298,12 @@ + /* 0F 2D */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f2d }, + /* 0F 2E */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f2e }, + /* 0F 2F */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f2f }, +- /* 0F 30 */ { 0, &BX_CPU_C::WRMSR }, ++ /* 0F 30 */ { BxTraceEnd, &BX_CPU_C::WRMSR }, + /* 0F 31 */ { 0, &BX_CPU_C::RDTSC }, + /* 0F 32 */ { 0, &BX_CPU_C::RDMSR }, + /* 0F 33 */ { 0, &BX_CPU_C::RDPMC }, +- /* 0F 34 */ { 0, &BX_CPU_C::SYSENTER }, +- /* 0F 35 */ { 0, &BX_CPU_C::SYSEXIT }, ++ /* 0F 34 */ { BxTraceEnd, &BX_CPU_C::SYSENTER }, ++ /* 0F 35 */ { BxTraceEnd, &BX_CPU_C::SYSEXIT }, + /* 0F 36 */ { 0, &BX_CPU_C::BxError }, + /* 0F 37 */ { 0, &BX_CPU_C::BxError }, + #if BX_SUPPORT_SSE3E || BX_SUPPORT_SSE >= 4 +@@ -1386,22 +1386,22 @@ + /* 0F 7D */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f7d }, + /* 0F 7E */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f7e }, + /* 0F 7F */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f7f }, +- /* 0F 80 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd }, +- /* 0F 81 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd }, +- /* 0F 82 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd }, +- /* 0F 83 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd }, +- /* 0F 84 */ { BxImmediate_BrOff32, &BX_CPU_C::JZ_Jd }, +- /* 0F 85 */ { BxImmediate_BrOff32, &BX_CPU_C::JNZ_Jd }, +- /* 0F 86 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd }, +- /* 0F 87 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd }, +- /* 0F 88 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd }, +- /* 0F 89 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd }, +- /* 0F 8A */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd }, +- /* 0F 8B */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd }, +- /* 0F 8C */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd }, +- /* 0F 8D */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd }, +- /* 0F 8E */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd }, +- /* 0F 8F */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd }, ++ /* 0F 80 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 0F 81 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 0F 82 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 0F 83 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 0F 84 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JZ_Jd }, ++ /* 0F 85 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JNZ_Jd }, ++ /* 0F 86 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 0F 87 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 0F 88 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 0F 89 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 0F 8A */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 0F 8B */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 0F 8C */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 0F 8D */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 0F 8E */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, ++ /* 0F 8F */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jd }, + /* 0F 90 */ { BxAnother, &BX_CPU_C::SETO_Eb }, + /* 0F 91 */ { BxAnother, &BX_CPU_C::SETNO_Eb }, + /* 0F 92 */ { BxAnother, &BX_CPU_C::SETB_Eb }, +@@ -1424,11 +1424,11 @@ + /* 0F A3 */ { BxAnother, &BX_CPU_C::BT_EdGd }, + /* 0F A4 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::SHLD_EdGd }, + /* 0F A5 */ { BxAnother, &BX_CPU_C::SHLD_EdGd }, +- /* 0F A6 */ { 0, &BX_CPU_C::CMPXCHG_XBTS }, +- /* 0F A7 */ { 0, &BX_CPU_C::CMPXCHG_IBTS }, ++ /* 0F A6 */ { BxTraceEnd, &BX_CPU_C::CMPXCHG_XBTS }, // Undefined Opcode ++ /* 0F A7 */ { BxTraceEnd, &BX_CPU_C::CMPXCHG_IBTS }, // Undefined Opcode + /* 0F A8 */ { 0, &BX_CPU_C::PUSH32_GS }, + /* 0F A9 */ { 0, &BX_CPU_C::POP32_GS }, +- /* 0F AA */ { 0, &BX_CPU_C::RSM }, ++ /* 0F AA */ { BxTraceEnd, &BX_CPU_C::RSM }, + /* 0F AB */ { BxAnother | BxLockable, &BX_CPU_C::BTS_EdGd }, + /* 0F AC */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::SHRD_EdGd }, + /* 0F AD */ { BxAnother, &BX_CPU_C::SHRD_EdGd }, +@@ -1443,7 +1443,7 @@ + /* 0F B6 */ { BxAnother, &BX_CPU_C::MOVZX_GdEb }, + /* 0F B7 */ { BxAnother, &BX_CPU_C::MOVZX_GdEw }, + /* 0F B8 */ { 0, &BX_CPU_C::BxError }, +- /* 0F B9 */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode ++ /* 0F B9 */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode + /* 0F BA */ { BxAnother | BxGroup8, NULL, BxOpcodeInfoG8EdIb }, + /* 0F BB */ { BxAnother | BxLockable, &BX_CPU_C::BTC_EdGd }, + /* 0F BC */ { BxAnother, &BX_CPU_C::BSF_GdEd }, +@@ -1642,6 +1642,10 @@ + + attr = BxOpcodeInfo[b1+offset].Attr; + ++#if BX_SUPPORT_ICACHE ++ if (attr & BxTraceEnd) instruction->setStopTraceAttr(); ++#endif ++ + #if BX_SUPPORT_SSE3E || BX_SUPPORT_SSE >= 4 + // handle 3-byte escape + if (attr & Bx3ByteOpcode) { +@@ -1862,6 +1866,9 @@ + } + + instruction->execute = OpcodeInfoPtr->ExecutePtr; ++#if BX_SUPPORT_ICACHE ++ if (attr & BxTraceEnd) instruction->setStopTraceAttr(); ++#endif + } + else { + // Opcode does not require a MODRM byte. +@@ -1876,7 +1883,8 @@ + // lock prefix not allowed or destination operand is not memory + 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 ++ instruction->execute = &BX_CPU_C::BxError; + } + } + +@@ -2005,6 +2013,13 @@ + if (BX_NULL_SEG_REG(instruction->seg())) + instruction->setSeg(BX_SEG_REG_DS); + ++#if BX_SUPPORT_ICACHE ++ // set stop-trace attribute for invalid instructions ++ if(instruction->execute == &BX_CPU_C::BxError) { ++ instruction->setStopTraceAttr(); ++ } ++#endif ++ + instruction->setB1(b1); + instruction->setILen(ilen); + return(1); +diff -u -r bochs-trace-cache-root/cpu/fetchdecode64.cc bochs-trace-cache/cpu/fetchdecode64.cc +--- bochs-trace-cache-root/cpu/fetchdecode64.cc 2007-01-28 23:27:30.000000000 +0200 ++++ bochs-trace-cache/cpu/fetchdecode64.cc 2007-03-07 21:34:39.109375000 +0200 +@@ -357,10 +357,10 @@ + // attributes defined in main area + /* 0 */ { BxLockable, &BX_CPU_C::INC_Ew }, + /* 1 */ { BxLockable, &BX_CPU_C::DEC_Ew }, +- /* 2 */ { 0, &BX_CPU_C::CALL_Ew }, +- /* 3 */ { 0, &BX_CPU_C::CALL16_Ep }, +- /* 4 */ { 0, &BX_CPU_C::JMP_Eq }, +- /* 5 */ { 0, &BX_CPU_C::JMP16_Ep }, ++ /* 2 */ { BxTraceEnd, &BX_CPU_C::CALL_Ew }, ++ /* 3 */ { BxTraceEnd, &BX_CPU_C::CALL16_Ep }, ++ /* 4 */ { BxTraceEnd, &BX_CPU_C::JMP_Eq }, ++ /* 5 */ { BxTraceEnd, &BX_CPU_C::JMP16_Ep }, + /* 6 */ { 0, &BX_CPU_C::PUSH_Ew }, + /* 7 */ { 0, &BX_CPU_C::BxError } + }; +@@ -369,10 +369,10 @@ + // attributes defined in main area + /* 0 */ { BxLockable, &BX_CPU_C::INC_Ed }, + /* 1 */ { BxLockable, &BX_CPU_C::DEC_Ed }, +- /* 2 */ { 0, &BX_CPU_C::CALL_Eq }, +- /* 3 */ { 0, &BX_CPU_C::CALL32_Ep }, +- /* 4 */ { 0, &BX_CPU_C::JMP_Eq }, +- /* 5 */ { 0, &BX_CPU_C::JMP32_Ep }, ++ /* 2 */ { BxTraceEnd, &BX_CPU_C::CALL_Eq }, ++ /* 3 */ { BxTraceEnd, &BX_CPU_C::CALL32_Ep }, ++ /* 4 */ { BxTraceEnd, &BX_CPU_C::JMP_Eq }, ++ /* 5 */ { BxTraceEnd, &BX_CPU_C::JMP32_Ep }, + /* 6 */ { 0, &BX_CPU_C::PUSH_Eq }, + /* 7 */ { 0, &BX_CPU_C::BxError } + }; +@@ -381,10 +381,10 @@ + // attributes defined in main area + /* 0 */ { BxLockable, &BX_CPU_C::INC_Eq }, + /* 1 */ { BxLockable, &BX_CPU_C::DEC_Eq }, +- /* 2 */ { 0, &BX_CPU_C::CALL_Eq }, +- /* 3 */ { 0, &BX_CPU_C::CALL64_Ep }, +- /* 4 */ { 0, &BX_CPU_C::JMP_Eq }, +- /* 5 */ { 0, &BX_CPU_C::JMP64_Ep }, ++ /* 2 */ { BxTraceEnd, &BX_CPU_C::CALL_Eq }, ++ /* 3 */ { BxTraceEnd, &BX_CPU_C::CALL64_Ep }, ++ /* 4 */ { BxTraceEnd, &BX_CPU_C::JMP_Eq }, ++ /* 5 */ { BxTraceEnd, &BX_CPU_C::JMP64_Ep }, + /* 6 */ { 0, &BX_CPU_C::PUSH_Eq }, + /* 7 */ { 0, &BX_CPU_C::BxError } + }; +@@ -428,12 +428,12 @@ + static const BxOpcodeInfo_t BxOpcodeInfo64G7[8] = { + /* 0 */ { 0, &BX_CPU_C::SGDT64_Ms }, + /* 1 */ { 0, &BX_CPU_C::SIDT64_Ms }, +- /* 2 */ { 0, &BX_CPU_C::LGDT64_Ms }, +- /* 3 */ { 0, &BX_CPU_C::LIDT64_Ms }, ++ /* 2 */ { BxTraceEnd, &BX_CPU_C::LGDT64_Ms }, ++ /* 3 */ { BxTraceEnd, &BX_CPU_C::LIDT64_Ms }, + /* 4 */ { 0, &BX_CPU_C::SMSW_Ew }, + /* 5 */ { 0, &BX_CPU_C::BxError }, +- /* 6 */ { 0, &BX_CPU_C::LMSW_Ew }, +- /* 7 */ { BxSplitMod11b, NULL, opcodesGroupModINVLPG } ++ /* 6 */ { BxTraceEnd, &BX_CPU_C::LMSW_Ew }, ++ /* 7 */ { BxSplitMod11b | BxTraceEnd, NULL, opcodesGroupModINVLPG } + }; + + static const BxOpcodeInfo_t BxOpcodeInfo64G8EwIb[8] = { +@@ -664,22 +664,22 @@ + /* 6D */ { 0, &BX_CPU_C::REP_INSW_YwDX }, + /* 6E */ { 0, &BX_CPU_C::REP_OUTSB_DXXb }, + /* 6F */ { 0, &BX_CPU_C::REP_OUTSW_DXXw }, +- /* 70 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 71 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 72 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 73 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 74 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 75 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 76 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 77 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 78 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 79 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7A */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7B */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7C */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7D */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7E */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7F */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, ++ /* 70 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 71 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 72 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 73 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 74 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 75 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 76 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 77 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 78 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 79 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7A */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7B */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7C */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7D */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7E */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7F */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, + /* 80 */ { BxAnother | BxGroup1, NULL, BxOpcodeInfo64G1EbIb }, + /* 81 */ { BxAnother | BxGroup1 | BxImmediate_Iv, NULL, BxOpcodeInfo64G1Ew }, + /* 82 */ { 0, &BX_CPU_C::BxError }, +@@ -746,20 +746,20 @@ + /* BF */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw }, + /* C0 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfo64G2Eb }, + /* C1 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfo64G2Ew }, +- /* C2 */ { BxImmediate_Iw, &BX_CPU_C::RETnear16_Iw }, +- /* C3 */ { 0, &BX_CPU_C::RETnear16 }, ++ /* C2 */ { BxImmediate_Iw | BxTraceEnd, &BX_CPU_C::RETnear16_Iw }, ++ /* C3 */ { BxTraceEnd, &BX_CPU_C::RETnear16 }, + /* C4 */ { 0, &BX_CPU_C::BxError }, + /* C5 */ { 0, &BX_CPU_C::BxError }, + /* C6 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::MOV_EbIb }, + /* C7 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::MOV_EwIw }, + /* C8 */ { BxImmediate_IwIb, &BX_CPU_C::ENTER_IwIb }, + /* C9 */ { 0, &BX_CPU_C::LEAVE }, +- /* CA */ { BxImmediate_Iw, &BX_CPU_C::RETfar16_Iw }, +- /* CB */ { 0, &BX_CPU_C::RETfar16 }, +- /* CC */ { 0, &BX_CPU_C::INT3 }, +- /* CD */ { BxImmediate_Ib, &BX_CPU_C::INT_Ib }, ++ /* CA */ { BxImmediate_Iw | BxTraceEnd, &BX_CPU_C::RETfar16_Iw }, ++ /* CB */ { BxTraceEnd, &BX_CPU_C::RETfar16 }, ++ /* CC */ { BxTraceEnd, &BX_CPU_C::INT3 }, ++ /* CD */ { BxImmediate_Ib | BxTraceEnd, &BX_CPU_C::INT_Ib }, + /* CE */ { 0, &BX_CPU_C::BxError }, +- /* CF */ { 0, &BX_CPU_C::IRET16 }, ++ /* CF */ { BxTraceEnd, &BX_CPU_C::IRET16 }, + /* D0 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfo64G2Eb }, + /* D1 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfo64G2Ew }, + /* D2 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfo64G2Eb }, +@@ -777,27 +777,27 @@ + /* DD */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupDD }, + /* DE */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupDE }, + /* DF */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupDF }, +- /* E0 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPNE64_Jb }, +- /* E1 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPE64_Jb }, +- /* E2 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOP64_Jb }, +- /* E3 */ { BxImmediate_BrOff8, &BX_CPU_C::JCXZ64_Jb }, ++ /* E0 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::LOOPNE64_Jb }, ++ /* E1 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::LOOPE64_Jb }, ++ /* E2 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::LOOP64_Jb }, ++ /* E3 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCXZ64_Jb }, + /* E4 */ { BxImmediate_Ib, &BX_CPU_C::IN_ALIb }, + /* E5 */ { BxImmediate_Ib, &BX_CPU_C::IN_AXIb }, + /* E6 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbAL }, + /* E7 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbAX }, +- /* E8 */ { BxImmediate_BrOff16, &BX_CPU_C::CALL_Aw }, +- /* E9 */ { BxImmediate_BrOff16, &BX_CPU_C::JMP_Jq }, ++ /* E8 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::CALL_Aw }, ++ /* E9 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JMP_Jq }, + /* EA */ { 0, &BX_CPU_C::BxError }, +- /* EB */ { BxImmediate_BrOff8, &BX_CPU_C::JMP_Jq }, ++ /* EB */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JMP_Jq }, + /* EC */ { 0, &BX_CPU_C::IN_ALDX }, + /* ED */ { 0, &BX_CPU_C::IN_AXDX }, + /* EE */ { 0, &BX_CPU_C::OUT_DXAL }, + /* EF */ { 0, &BX_CPU_C::OUT_DXAX }, + /* F0 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // LOCK +- /* F1 */ { 0, &BX_CPU_C::INT1 }, ++ /* F1 */ { BxTraceEnd, &BX_CPU_C::INT1 }, + /* F2 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REPNE/REPNZ + /* F3 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REP, REPE/REPZ +- /* F4 */ { 0, &BX_CPU_C::HLT }, ++ /* F4 */ { BxTraceEnd, &BX_CPU_C::HLT }, + /* F5 */ { 0, &BX_CPU_C::CMC }, + /* F6 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfo64G3Eb }, + /* F7 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfo64G3Ew }, +@@ -815,13 +815,13 @@ + /* 0F 02 */ { BxAnother, &BX_CPU_C::LAR_GvEw }, + /* 0F 03 */ { BxAnother, &BX_CPU_C::LSL_GvEw }, + /* 0F 04 */ { 0, &BX_CPU_C::BxError }, +- /* 0F 05 */ { 0, &BX_CPU_C::SYSCALL }, ++ /* 0F 05 */ { BxTraceEnd, &BX_CPU_C::SYSCALL }, + /* 0F 06 */ { 0, &BX_CPU_C::CLTS }, +- /* 0F 07 */ { 0, &BX_CPU_C::SYSRET }, +- /* 0F 08 */ { 0, &BX_CPU_C::INVD }, +- /* 0F 09 */ { 0, &BX_CPU_C::WBINVD }, ++ /* 0F 07 */ { BxTraceEnd, &BX_CPU_C::SYSRET }, ++ /* 0F 08 */ { BxTraceEnd, &BX_CPU_C::INVD }, ++ /* 0F 09 */ { BxTraceEnd, &BX_CPU_C::WBINVD }, + /* 0F 0A */ { 0, &BX_CPU_C::BxError }, +- /* 0F 0B */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode ++ /* 0F 0B */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode + /* 0F 0C */ { 0, &BX_CPU_C::BxError }, + /* 0F 0D */ { BxAnother, &BX_CPU_C::NOP }, // 3DNow! PREFETCH on AMD, NOP on Intel + #if BX_SUPPORT_3DNOW +@@ -849,7 +849,7 @@ + /* 0F 1F */ { BxAnother, &BX_CPU_C::NOP }, // multi-byte NOP + /* 0F 20 */ { BxAnother, &BX_CPU_C::MOV_RqCq }, + /* 0F 21 */ { BxAnother, &BX_CPU_C::MOV_RqDq }, +- /* 0F 22 */ { BxAnother, &BX_CPU_C::MOV_CqRq }, ++ /* 0F 22 */ { BxAnother | BxTraceEnd, &BX_CPU_C::MOV_CqRq }, + /* 0F 23 */ { BxAnother, &BX_CPU_C::MOV_DqRq }, + /* 0F 24 */ { 0, &BX_CPU_C::BxError }, + /* 0F 25 */ { 0, &BX_CPU_C::BxError }, +@@ -863,7 +863,7 @@ + /* 0F 2D */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f2d }, + /* 0F 2E */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f2e }, + /* 0F 2F */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f2f }, +- /* 0F 30 */ { 0, &BX_CPU_C::WRMSR }, ++ /* 0F 30 */ { BxTraceEnd, &BX_CPU_C::WRMSR }, + /* 0F 31 */ { 0, &BX_CPU_C::RDTSC }, + /* 0F 32 */ { 0, &BX_CPU_C::RDMSR }, + /* 0F 33 */ { 0, &BX_CPU_C::RDPMC }, +@@ -951,22 +951,22 @@ + /* 0F 7D */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f7d }, + /* 0F 7E */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f7e }, + /* 0F 7F */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f7f }, +- /* 0F 80 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, +- /* 0F 81 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, +- /* 0F 82 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, +- /* 0F 83 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, +- /* 0F 84 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, +- /* 0F 85 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, +- /* 0F 86 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, +- /* 0F 87 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, +- /* 0F 88 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, +- /* 0F 89 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, +- /* 0F 8A */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, +- /* 0F 8B */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, +- /* 0F 8C */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, +- /* 0F 8D */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, +- /* 0F 8E */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, +- /* 0F 8F */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jq }, ++ /* 0F 80 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 81 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 82 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 83 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 84 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 85 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 86 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 87 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 88 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 89 */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8A */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8B */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8C */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8D */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8E */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8F */ { BxImmediate_BrOff16 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, + /* 0F 90 */ { BxAnother, &BX_CPU_C::SETO_Eb }, + /* 0F 91 */ { BxAnother, &BX_CPU_C::SETNO_Eb }, + /* 0F 92 */ { BxAnother, &BX_CPU_C::SETB_Eb }, +@@ -993,7 +993,7 @@ + /* 0F A7 */ { 0, &BX_CPU_C::BxError }, + /* 0F A8 */ { 0, &BX_CPU_C::PUSH16_GS }, + /* 0F A9 */ { 0, &BX_CPU_C::POP16_GS }, +- /* 0F AA */ { 0, &BX_CPU_C::RSM }, ++ /* 0F AA */ { BxTraceEnd, &BX_CPU_C::RSM }, + /* 0F AB */ { BxAnother | BxLockable, &BX_CPU_C::BTS_EwGw }, + /* 0F AC */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::SHRD_EwGw }, + /* 0F AD */ { BxAnother, &BX_CPU_C::SHRD_EwGw }, +@@ -1008,7 +1008,7 @@ + /* 0F B6 */ { BxAnother, &BX_CPU_C::MOVZX_GwEb }, + /* 0F B7 */ { BxAnother | BxSplitMod11b, NULL, opcodesMOV_GwEw }, // MOVZX_GwEw + /* 0F B8 */ { 0, &BX_CPU_C::BxError }, +- /* 0F B9 */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode ++ /* 0F B9 */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode + /* 0F BA */ { BxAnother | BxGroup8, NULL, BxOpcodeInfo64G8EwIb }, + /* 0F BB */ { BxAnother | BxLockable, &BX_CPU_C::BTC_EwGw }, + /* 0F BC */ { BxAnother, &BX_CPU_C::BSF_GwEw }, +@@ -1193,22 +1193,22 @@ + /* 6D */ { 0, &BX_CPU_C::REP_INSD_YdDX }, + /* 6E */ { 0, &BX_CPU_C::REP_OUTSB_DXXb }, + /* 6F */ { 0, &BX_CPU_C::REP_OUTSD_DXXd }, +- /* 70 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 71 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 72 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 73 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 74 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 75 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 76 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 77 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 78 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 79 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7A */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7B */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7C */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7D */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7E */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7F */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, ++ /* 70 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 71 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 72 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 73 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 74 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 75 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 76 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 77 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 78 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 79 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7A */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7B */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7C */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7D */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7E */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7F */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, + /* 80 */ { BxAnother | BxGroup1, NULL, BxOpcodeInfo64G1EbIb }, + /* 81 */ { BxAnother | BxGroup1 | BxImmediate_Iv, NULL, BxOpcodeInfo64G1Ed }, + /* 82 */ { 0, &BX_CPU_C::BxError }, +@@ -1275,20 +1275,20 @@ + /* BF */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId }, + /* C0 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfo64G2Eb }, + /* C1 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfo64G2Ed }, +- /* C2 */ { BxImmediate_Iw, &BX_CPU_C::RETnear64_Iw }, +- /* C3 */ { 0, &BX_CPU_C::RETnear64 }, ++ /* C2 */ { BxImmediate_Iw | BxTraceEnd, &BX_CPU_C::RETnear64_Iw }, ++ /* C3 */ { BxTraceEnd, &BX_CPU_C::RETnear64 }, + /* C4 */ { 0, &BX_CPU_C::BxError }, + /* C5 */ { 0, &BX_CPU_C::BxError }, + /* C6 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::MOV_EbIb }, + /* C7 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::MOV_EdId }, + /* C8 */ { BxImmediate_IwIb, &BX_CPU_C::ENTER64_IwIb }, + /* C9 */ { 0, &BX_CPU_C::LEAVE64 }, +- /* CA */ { BxImmediate_Iw, &BX_CPU_C::RETfar32_Iw }, +- /* CB */ { 0, &BX_CPU_C::RETfar32 }, +- /* CC */ { 0, &BX_CPU_C::INT3 }, +- /* CD */ { BxImmediate_Ib, &BX_CPU_C::INT_Ib }, ++ /* CA */ { BxImmediate_Iw | BxTraceEnd, &BX_CPU_C::RETfar32_Iw }, ++ /* CB */ { BxTraceEnd, &BX_CPU_C::RETfar32 }, ++ /* CC */ { BxTraceEnd, &BX_CPU_C::INT3 }, ++ /* CD */ { BxImmediate_Ib | BxTraceEnd, &BX_CPU_C::INT_Ib }, + /* CE */ { 0, &BX_CPU_C::BxError }, +- /* CF */ { 0, &BX_CPU_C::IRET32 }, ++ /* CF */ { BxTraceEnd, &BX_CPU_C::IRET32 }, + /* D0 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfo64G2Eb }, + /* D1 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfo64G2Ed }, + /* D2 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfo64G2Eb }, +@@ -1306,27 +1306,27 @@ + /* DD */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupDD }, + /* DE */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupDE }, + /* DF */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupDF }, +- /* E0 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPNE64_Jb }, +- /* E1 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPE64_Jb }, +- /* E2 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOP64_Jb }, +- /* E3 */ { BxImmediate_BrOff8, &BX_CPU_C::JCXZ64_Jb }, ++ /* E0 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::LOOPNE64_Jb }, ++ /* E1 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::LOOPE64_Jb }, ++ /* E2 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::LOOP64_Jb }, ++ /* E3 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCXZ64_Jb }, + /* E4 */ { BxImmediate_Ib, &BX_CPU_C::IN_ALIb }, + /* E5 */ { BxImmediate_Ib, &BX_CPU_C::IN_EAXIb }, + /* E6 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbAL }, + /* E7 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbEAX }, +- /* E8 */ { BxImmediate_BrOff32, &BX_CPU_C::CALL_Aq }, +- /* E9 */ { BxImmediate_BrOff32, &BX_CPU_C::JMP_Jq }, ++ /* E8 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::CALL_Aq }, ++ /* E9 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JMP_Jq }, + /* EA */ { 0, &BX_CPU_C::BxError }, +- /* EB */ { BxImmediate_BrOff8, &BX_CPU_C::JMP_Jq }, ++ /* EB */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JMP_Jq }, + /* EC */ { 0, &BX_CPU_C::IN_ALDX }, + /* ED */ { 0, &BX_CPU_C::IN_EAXDX }, + /* EE */ { 0, &BX_CPU_C::OUT_DXAL }, + /* EF */ { 0, &BX_CPU_C::OUT_DXEAX }, + /* F0 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // LOCK: +- /* F1 */ { 0, &BX_CPU_C::INT1 }, ++ /* F1 */ { BxTraceEnd, &BX_CPU_C::INT1 }, + /* F2 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REPNE/REPNZ + /* F3 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REP,REPE/REPZ +- /* F4 */ { 0, &BX_CPU_C::HLT }, ++ /* F4 */ { BxTraceEnd, &BX_CPU_C::HLT }, + /* F5 */ { 0, &BX_CPU_C::CMC }, + /* F6 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfo64G3Eb }, + /* F7 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfo64G3Ed }, +@@ -1344,13 +1344,13 @@ + /* 0F 02 */ { BxAnother, &BX_CPU_C::LAR_GvEw }, + /* 0F 03 */ { BxAnother, &BX_CPU_C::LSL_GvEw }, + /* 0F 04 */ { 0, &BX_CPU_C::BxError }, +- /* 0F 05 */ { 0, &BX_CPU_C::SYSCALL }, ++ /* 0F 05 */ { BxTraceEnd, &BX_CPU_C::SYSCALL }, + /* 0F 06 */ { 0, &BX_CPU_C::CLTS }, +- /* 0F 07 */ { 0, &BX_CPU_C::SYSRET }, +- /* 0F 08 */ { 0, &BX_CPU_C::INVD }, +- /* 0F 09 */ { 0, &BX_CPU_C::WBINVD }, ++ /* 0F 07 */ { BxTraceEnd, &BX_CPU_C::SYSRET }, ++ /* 0F 08 */ { BxTraceEnd, &BX_CPU_C::INVD }, ++ /* 0F 09 */ { BxTraceEnd, &BX_CPU_C::WBINVD }, + /* 0F 0A */ { 0, &BX_CPU_C::BxError }, +- /* 0F 0B */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode ++ /* 0F 0B */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode + /* 0F 0C */ { 0, &BX_CPU_C::BxError }, + /* 0F 0D */ { BxAnother, &BX_CPU_C::NOP }, // 3DNow! PREFETCH on AMD, NOP on Intel + #if BX_SUPPORT_3DNOW +@@ -1378,7 +1378,7 @@ + /* 0F 1F */ { BxAnother, &BX_CPU_C::NOP }, // multi-byte NOP + /* 0F 20 */ { BxAnother, &BX_CPU_C::MOV_RqCq }, + /* 0F 21 */ { BxAnother, &BX_CPU_C::MOV_RqDq }, +- /* 0F 22 */ { BxAnother, &BX_CPU_C::MOV_CqRq }, ++ /* 0F 22 */ { BxAnother | BxTraceEnd, &BX_CPU_C::MOV_CqRq }, + /* 0F 23 */ { BxAnother, &BX_CPU_C::MOV_DqRq }, + /* 0F 24 */ { 0, &BX_CPU_C::BxError }, + /* 0F 25 */ { 0, &BX_CPU_C::BxError }, +@@ -1392,7 +1392,7 @@ + /* 0F 2D */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f2d }, + /* 0F 2E */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f2e }, + /* 0F 2F */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f2f }, +- /* 0F 30 */ { 0, &BX_CPU_C::WRMSR }, ++ /* 0F 30 */ { BxTraceEnd, &BX_CPU_C::WRMSR }, + /* 0F 31 */ { 0, &BX_CPU_C::RDTSC }, + /* 0F 32 */ { 0, &BX_CPU_C::RDMSR }, + /* 0F 33 */ { 0, &BX_CPU_C::RDPMC }, +@@ -1480,22 +1480,22 @@ + /* 0F 7D */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f7d }, + /* 0F 7E */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f7e }, + /* 0F 7F */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f7f }, +- /* 0F 80 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 81 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 82 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 83 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 84 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 85 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 86 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 87 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 88 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 89 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 8A */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 8B */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 8C */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 8D */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 8E */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 8F */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, ++ /* 0F 80 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 81 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 82 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 83 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 84 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 85 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 86 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 87 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 88 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 89 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8A */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8B */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8C */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8D */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8E */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8F */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, + /* 0F 90 */ { BxAnother, &BX_CPU_C::SETO_Eb }, + /* 0F 91 */ { BxAnother, &BX_CPU_C::SETNO_Eb }, + /* 0F 92 */ { BxAnother, &BX_CPU_C::SETB_Eb }, +@@ -1522,7 +1522,7 @@ + /* 0F A7 */ { 0, &BX_CPU_C::BxError }, + /* 0F A8 */ { 0, &BX_CPU_C::PUSH64_GS }, + /* 0F A9 */ { 0, &BX_CPU_C::POP64_GS }, +- /* 0F AA */ { 0, &BX_CPU_C::RSM }, ++ /* 0F AA */ { BxTraceEnd, &BX_CPU_C::RSM }, + /* 0F AB */ { BxAnother | BxLockable, &BX_CPU_C::BTS_EdGd }, + /* 0F AC */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::SHRD_EdGd }, + /* 0F AD */ { BxAnother, &BX_CPU_C::SHRD_EdGd }, +@@ -1537,7 +1537,7 @@ + /* 0F B6 */ { BxAnother, &BX_CPU_C::MOVZX_GdEb }, + /* 0F B7 */ { BxAnother, &BX_CPU_C::MOVZX_GdEw }, + /* 0F B8 */ { 0, &BX_CPU_C::BxError }, +- /* 0F B9 */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode ++ /* 0F B9 */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode + /* 0F BA */ { BxAnother | BxGroup8, NULL, BxOpcodeInfo64G8EdIb }, + /* 0F BB */ { BxAnother | BxLockable, &BX_CPU_C::BTC_EdGd }, + /* 0F BC */ { BxAnother, &BX_CPU_C::BSF_GdEd }, +@@ -1722,22 +1722,22 @@ + /* 6D */ { 0, &BX_CPU_C::REP_INSD_YdDX }, + /* 6E */ { 0, &BX_CPU_C::REP_OUTSB_DXXb }, + /* 6F */ { 0, &BX_CPU_C::REP_OUTSD_DXXd }, +- /* 70 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 71 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 72 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 73 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 74 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 75 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 76 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 77 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 78 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 79 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7A */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7B */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7C */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7D */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7E */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, +- /* 7F */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq }, ++ /* 70 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 71 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 72 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 73 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 74 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 75 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 76 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 77 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 78 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 79 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7A */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7B */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7C */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7D */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7E */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 7F */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, + /* 80 */ { BxAnother | BxGroup1, NULL, BxOpcodeInfo64G1EbIb }, + /* 81 */ { BxAnother | BxGroup1 | BxImmediate_Iv, NULL, BxOpcodeInfo64G1Eq }, + /* 82 */ { 0, &BX_CPU_C::BxError }, +@@ -1804,20 +1804,20 @@ + /* BF */ { BxImmediate_Iq, &BX_CPU_C::MOV_RRXIq }, + /* C0 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfo64G2Eb }, + /* C1 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfo64G2Eq }, +- /* C2 */ { BxImmediate_Iw, &BX_CPU_C::RETnear64_Iw }, +- /* C3 */ { 0, &BX_CPU_C::RETnear64 }, ++ /* C2 */ { BxImmediate_Iw | BxTraceEnd, &BX_CPU_C::RETnear64_Iw }, ++ /* C3 */ { BxTraceEnd, &BX_CPU_C::RETnear64 }, + /* C4 */ { 0, &BX_CPU_C::BxError }, + /* C5 */ { 0, &BX_CPU_C::BxError }, + /* C6 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::MOV_EbIb }, + /* C7 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::MOV_EqId }, + /* C8 */ { BxImmediate_IwIb, &BX_CPU_C::ENTER64_IwIb }, + /* C9 */ { 0, &BX_CPU_C::LEAVE64 }, +- /* CA */ { BxImmediate_Iw, &BX_CPU_C::RETfar64_Iw }, +- /* CB */ { 0, &BX_CPU_C::RETfar64 }, +- /* CC */ { 0, &BX_CPU_C::INT3 }, +- /* CD */ { BxImmediate_Ib, &BX_CPU_C::INT_Ib }, ++ /* CA */ { BxImmediate_Iw | BxTraceEnd, &BX_CPU_C::RETfar64_Iw }, ++ /* CB */ { BxTraceEnd, &BX_CPU_C::RETfar64 }, ++ /* CC */ { BxTraceEnd, &BX_CPU_C::INT3 }, ++ /* CD */ { BxImmediate_Ib | BxTraceEnd, &BX_CPU_C::INT_Ib }, + /* CE */ { 0, &BX_CPU_C::BxError }, +- /* CF */ { 0, &BX_CPU_C::IRET64 }, ++ /* CF */ { BxTraceEnd, &BX_CPU_C::IRET64 }, + /* D0 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfo64G2Eb }, + /* D1 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfo64G2Eq }, + /* D2 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfo64G2Eb }, +@@ -1835,27 +1835,27 @@ + /* DD */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupDD }, + /* DE */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupDE }, + /* DF */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupDF }, +- /* E0 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPNE64_Jb }, +- /* E1 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPE64_Jb }, +- /* E2 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOP64_Jb }, +- /* E3 */ { BxImmediate_BrOff8, &BX_CPU_C::JCXZ64_Jb }, ++ /* E0 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::LOOPNE64_Jb }, ++ /* E1 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::LOOPE64_Jb }, ++ /* E2 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::LOOP64_Jb }, ++ /* E3 */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JCXZ64_Jb }, + /* E4 */ { BxImmediate_Ib, &BX_CPU_C::IN_ALIb }, + /* E5 */ { BxImmediate_Ib, &BX_CPU_C::IN_EAXIb }, + /* E6 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbAL }, + /* E7 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbEAX }, +- /* E8 */ { BxImmediate_BrOff32, &BX_CPU_C::CALL_Aq }, +- /* E9 */ { BxImmediate_BrOff32, &BX_CPU_C::JMP_Jq }, ++ /* E8 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::CALL_Aq }, ++ /* E9 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JMP_Jq }, + /* EA */ { 0, &BX_CPU_C::BxError }, +- /* EB */ { BxImmediate_BrOff8, &BX_CPU_C::JMP_Jq }, ++ /* EB */ { BxImmediate_BrOff8 | BxTraceEnd, &BX_CPU_C::JMP_Jq }, + /* EC */ { 0, &BX_CPU_C::IN_ALDX }, + /* ED */ { 0, &BX_CPU_C::IN_EAXDX }, + /* EE */ { 0, &BX_CPU_C::OUT_DXAL }, + /* EF */ { 0, &BX_CPU_C::OUT_DXEAX }, + /* F0 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // LOCK: +- /* F1 */ { 0, &BX_CPU_C::INT1 }, ++ /* F1 */ { BxTraceEnd, &BX_CPU_C::INT1 }, + /* F2 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REPNE/REPNZ + /* F3 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REP,REPE/REPZ +- /* F4 */ { 0, &BX_CPU_C::HLT }, ++ /* F4 */ { BxTraceEnd, &BX_CPU_C::HLT }, + /* F5 */ { 0, &BX_CPU_C::CMC }, + /* F6 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfo64G3Eb }, + /* F7 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfo64G3Eq }, +@@ -1873,13 +1873,13 @@ + /* 0F 02 */ { BxAnother, &BX_CPU_C::LAR_GvEw }, + /* 0F 03 */ { BxAnother, &BX_CPU_C::LSL_GvEw }, + /* 0F 04 */ { 0, &BX_CPU_C::BxError }, +- /* 0F 05 */ { 0, &BX_CPU_C::SYSCALL }, ++ /* 0F 05 */ { BxTraceEnd, &BX_CPU_C::SYSCALL }, + /* 0F 06 */ { 0, &BX_CPU_C::CLTS }, +- /* 0F 07 */ { 0, &BX_CPU_C::SYSRET }, +- /* 0F 08 */ { 0, &BX_CPU_C::INVD }, +- /* 0F 09 */ { 0, &BX_CPU_C::WBINVD }, ++ /* 0F 07 */ { BxTraceEnd, &BX_CPU_C::SYSRET }, ++ /* 0F 08 */ { BxTraceEnd, &BX_CPU_C::INVD }, ++ /* 0F 09 */ { BxTraceEnd, &BX_CPU_C::WBINVD }, + /* 0F 0A */ { 0, &BX_CPU_C::BxError }, +- /* 0F 0B */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode ++ /* 0F 0B */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode + /* 0F 0C */ { 0, &BX_CPU_C::BxError }, + /* 0F 0D */ { BxAnother, &BX_CPU_C::NOP }, // 3DNow! PREFETCH on AMD, NOP on Intel + #if BX_SUPPORT_3DNOW +@@ -1907,7 +1907,7 @@ + /* 0F 1F */ { BxAnother, &BX_CPU_C::NOP }, // multi-byte NOP + /* 0F 20 */ { BxAnother, &BX_CPU_C::MOV_RqCq }, + /* 0F 21 */ { BxAnother, &BX_CPU_C::MOV_RqDq }, +- /* 0F 22 */ { BxAnother, &BX_CPU_C::MOV_CqRq }, ++ /* 0F 22 */ { BxAnother | BxTraceEnd, &BX_CPU_C::MOV_CqRq }, + /* 0F 23 */ { BxAnother, &BX_CPU_C::MOV_DqRq }, + /* 0F 24 */ { 0, &BX_CPU_C::BxError }, + /* 0F 25 */ { 0, &BX_CPU_C::BxError }, +@@ -1921,7 +1921,7 @@ + /* 0F 2D */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f2d }, + /* 0F 2E */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f2e }, + /* 0F 2F */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f2f }, +- /* 0F 30 */ { 0, &BX_CPU_C::WRMSR }, ++ /* 0F 30 */ { BxTraceEnd, &BX_CPU_C::WRMSR }, + /* 0F 31 */ { 0, &BX_CPU_C::RDTSC }, + /* 0F 32 */ { 0, &BX_CPU_C::RDMSR }, + /* 0F 33 */ { 0, &BX_CPU_C::RDPMC }, +@@ -2009,22 +2009,22 @@ + /* 0F 7D */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f7d }, + /* 0F 7E */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f7e }, + /* 0F 7F */ { BxAnother | BxPrefixSSE, NULL, BxOpcodeGroupSSE_0f7f }, +- /* 0F 80 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 81 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 82 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 83 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 84 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 85 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 86 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 87 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 88 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 89 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 8A */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 8B */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 8C */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 8D */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 8E */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, +- /* 0F 8F */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jq }, ++ /* 0F 80 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 81 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 82 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 83 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 84 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 85 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 86 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 87 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 88 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 89 */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8A */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8B */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8C */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8D */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8E */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, ++ /* 0F 8F */ { BxImmediate_BrOff32 | BxTraceEnd, &BX_CPU_C::JCC_Jq }, + /* 0F 90 */ { BxAnother, &BX_CPU_C::SETO_Eb }, + /* 0F 91 */ { BxAnother, &BX_CPU_C::SETNO_Eb }, + /* 0F 92 */ { BxAnother, &BX_CPU_C::SETB_Eb }, +@@ -2051,7 +2051,7 @@ + /* 0F A7 */ { 0, &BX_CPU_C::BxError }, + /* 0F A8 */ { 0, &BX_CPU_C::PUSH64_GS }, + /* 0F A9 */ { 0, &BX_CPU_C::POP64_GS }, +- /* 0F AA */ { 0, &BX_CPU_C::RSM }, ++ /* 0F AA */ { BxTraceEnd, &BX_CPU_C::RSM }, + /* 0F AB */ { BxAnother | BxLockable, &BX_CPU_C::BTS_EqGq }, + /* 0F AC */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::SHRD_EqGq }, + /* 0F AD */ { BxAnother, &BX_CPU_C::SHRD_EqGq }, +@@ -2066,7 +2066,7 @@ + /* 0F B6 */ { BxAnother, &BX_CPU_C::MOVZX_GqEb }, + /* 0F B7 */ { BxAnother, &BX_CPU_C::MOVZX_GqEw }, + /* 0F B8 */ { 0, &BX_CPU_C::BxError }, +- /* 0F B9 */ { 0, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode ++ /* 0F B9 */ { BxTraceEnd, &BX_CPU_C::UndefinedOpcode }, // UD2 opcode + /* 0F BA */ { BxAnother | BxGroup8, NULL, BxOpcodeInfo64G8EqIb }, + /* 0F BB */ { BxAnother | BxLockable, &BX_CPU_C::BTC_EqGq }, + /* 0F BC */ { BxAnother, &BX_CPU_C::BSF_GqEq }, +@@ -2283,6 +2283,10 @@ + + attr = BxOpcodeInfo64[b1+offset].Attr; + ++#if BX_SUPPORT_ICACHE ++ if (attr & BxTraceEnd) instruction->setStopTraceAttr(); ++#endif ++ + #if BX_SUPPORT_SSE3E || BX_SUPPORT_SSE >= 4 + // handle 3-byte escape + if (attr & Bx3ByteOpcode) { +@@ -2558,6 +2562,9 @@ + } + + instruction->execute = OpcodeInfoPtr->ExecutePtr; ++#if BX_SUPPORT_ICACHE ++ if (attr & BxTraceEnd) instruction->setStopTraceAttr(); ++#endif + } + else { + // Opcode does not require a MODRM byte. +@@ -2572,7 +2579,8 @@ + // lock prefix not allowed or destination operand is not memory + 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 ++ instruction->execute = &BX_CPU_C::BxError; + } + } + +@@ -2696,6 +2704,13 @@ + if (BX_NULL_SEG_REG(instruction->seg())) + instruction->setSeg(BX_SEG_REG_DS); + ++#if BX_SUPPORT_ICACHE ++ // set stop-trace attribute for invalid instructions ++ if(instruction->execute == &BX_CPU_C::BxError) { ++ instruction->setStopTraceAttr(); ++ } ++#endif ++ + instruction->setB1(b1); + instruction->setILen(ilen); + return(1); +diff -u -r bochs-trace-cache-root/cpu/icache.h bochs-trace-cache/cpu/icache.h +--- bochs-trace-cache-root/cpu/icache.h 2006-09-20 22:52:23.000000000 +0200 ++++ bochs-trace-cache/cpu/icache.h 2007-03-07 22:10:28.234375000 +0200 +@@ -115,12 +115,15 @@ + + #define BxICacheEntries (32 * 1024) // Must be a power of 2. + ++#define BX_MAX_TRACE_LENGTH 16 ++ + struct bxICacheEntry_c + { + bx_phy_address pAddr; // Physical address of the instruction + Bit32u writeStamp; // Generation ID. Each write to a physical page + // decrements this value +- bxInstruction_c i; // The instruction decode information ++ Bit32u ilen; // Trace length in instructions ++ bxInstruction_c i[BX_MAX_TRACE_LENGTH]; + }; + + class BOCHSAPI bxICache_c {