----------------------------------------------------------------------
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<max_length;len++)
+  {
+#if BX_SUPPORT_X86_64
+    if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64)
+      ret = fetchDecode64(fetchPtr, i, maxFetch);
+    else
 #endif
+      ret = fetchDecode32(fetchPtr, i, maxFetch);
+
+    if (ret==0) {
+      // Fetching instruction on segment/page boundary
+      if (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 {
