    }
  };
  // <TAG-CLASS-INSTRUCTION-END>
-@@ -2917,7 +2927,12 @@
+@@ -2931,7 +2941,12 @@
  #if BX_SUPPORT_X86_64
    BX_SMF unsigned fetchDecode64(Bit8u *, bxInstruction_c *, unsigned);
  #endif
-+#if BX_SUPPORT_ICACHE
++#if BX_SUPPORT_TRACE_CACHE
 +  BX_SMF bxICacheEntry_c* fetchInstructionTrace(bxInstruction_c *, bx_address);
 +  BX_SMF bx_bool mergeTraces(bxICacheEntry_c *trace, bxInstruction_c *i, bx_phy_address pAddr);
 +#else

     }
   }
 
+#if BX_SUPPORT_ICACHE
+  if (attr & BxTraceEnd) instruction->setStopTraceAttr();
+#endif
+
   imm_mode = attr & BxImmediate;
   if (imm_mode) {
     switch (imm_mode) {
@@ -3889,6 +3894,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();

 // The CHECK_MAX_INSTRUCTIONS macro allows cpu_loop to execute a few
 // instructions and then return so that the other processors have a chance to
 // run.  This is used by bochs internal debugger or when simulating 
@@ -244,47 +359,67 @@
       eipBiased = RIP + BX_CPU_THIS_PTR eipPageBias;
     }
 
-    // fetch and decode next instruction
+#if BX_SUPPORT_TRACE_CACHE == 0
+    // fetch and decode single instruction
     bxInstruction_c *i = fetchInstruction(&iStorage, eipBiased);
+#else
+    unsigned n, length = 1;
+    bxInstruction_c *i = &iStorage;
+    bxICacheEntry_c *trace = fetchInstructionTrace(&iStorage, eipBiased);
+    if (trace) {
+      i = trace->i; // execute from first instruction in trace
+      length = trace->ilen;
+    }
+
+    for (n=0; n < length; n++, i++) {
+#endif
 
-    BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
+      BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
