    Bit32u writeStamp;    // Generation ID. Each write to a physical page
                          // decrements this value
 -  bxInstruction_c i;    // The instruction decode information
++#if BX_SUPPORT_TRACE_CACHE
 +  Bit32u ilen;          // Trace length in instructions
 +  bxInstruction_c i[BX_MAX_TRACE_LENGTH];
++#else
++  bxInstruction_c i;
++#endif
  };
  
  class BOCHSAPI bxICache_c {
+diff -ur bochs/main.cc bochs-trace-cache/main.cc
+--- bochs/main.cc	2007-11-20 20:36:26.000000000 +0200
++++ bochs-trace-cache/main.cc	2007-11-26 19:41:46.671875000 +0200
+@@ -1003,6 +1003,7 @@
+   BX_INFO(("  Guest2HostTLB support: %s",BX_SupportGuest2HostTLB?"yes":"no"));
+   BX_INFO(("  RepeatSpeedups support: %s",BX_SupportRepeatSpeedups?"yes":"no"));
+   BX_INFO(("  Icache support: %s",BX_SUPPORT_ICACHE?"yes":"no"));
++  BX_INFO(("  Trace cache support: %s",BX_SUPPORT_TRACE_CACHE?"yes":"no"));
+   BX_INFO(("  Fast function calls: %s",BX_FAST_FUNC_CALL?"yes":"no"));
+   BX_INFO(("Devices configuration"));
+   BX_INFO(("  ACPI support: %s",BX_SUPPORT_ACPI?"yes":"no"));

           (iCacheLookups-iCacheMisses) * 100.0 / iCacheLookups)); \
-    iCacheLookups = iCacheMisses = 0; \
+    iCacheLookups = iCacheMisses = iCacheMergeTraces = 0; \
   } \
 }
 #define InstrICache_Increment(v) (v)++
@@ -90,49 +93,125 @@
 #define RCX ECX
 #endif
 
-BX_CPP_INLINE bxInstruction_c* BX_CPU_C::fetchInstruction(bxInstruction_c *iStorage, bx_address eipBiased)
-{
-  unsigned ret;
-  bxInstruction_c *i = iStorage;
-
 #if BX_SUPPORT_ICACHE
+
+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;

   BX_SMF void UndefinedOpcode(bxInstruction_c *);
   BX_SMF void BxError(bxInstruction_c *i);
 
@@ -3756,6 +3771,12 @@
 #define BxLockable          0x0100 // bit  8
 #define Bx3ByteOpcode       0x0200 // bit  9
 
+#if BX_SUPPORT_TRACE_CACHE
+  #define BxTraceEnd        0x2000 // bit 13
+#else
+  #define BxTraceEnd        0
