Index: trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py	(revision 99298)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py	(revision 99299)
@@ -4575,6 +4575,4 @@
 
         #
-        # Complete and discard the current block.
-        #
         # HACK ALERT! For blocks orginating from macro expansion the start and
         #             end line will be the same, but the line has multiple
@@ -4601,4 +4599,36 @@
             asLines = [sLine + '\n' for sLine in sRawLine.split('\n')];
 
+        #
+        # Strip anything following the IEM_MC_END(); statement in the final line,
+        # so that we don't carry on any trailing 'break' after macro expansions
+        # like for iemOp_movsb_Xb_Yb.
+        #
+        while asLines[-1].strip() == '':
+            asLines.pop();
+        sFinal      = asLines[-1];
+        offFinalEnd = sFinal.find('IEM_MC_END');
+        if offFinalEnd < 0: self.raiseError('bogus IEM_MC_END: Not in final line: %s' % (sFinal,));
+        offFinalEnd += len('IEM_MC_END');
+
+        while sFinal[offFinalEnd].isspace():
+            offFinalEnd += 1;
+        if sFinal[offFinalEnd] != '(': self.raiseError('bogus IEM_MC_END: Expected "(" at %s: %s' % (offFinalEnd, sFinal,));
+        offFinalEnd += 1;
+
+        while sFinal[offFinalEnd].isspace():
+            offFinalEnd += 1;
+        if sFinal[offFinalEnd] != ')': self.raiseError('bogus IEM_MC_END: Expected ")" at %s: %s' % (offFinalEnd, sFinal,));
+        offFinalEnd += 1;
+
+        while sFinal[offFinalEnd].isspace():
+            offFinalEnd += 1;
+        if sFinal[offFinalEnd] != ';': self.raiseError('bogus IEM_MC_END: Expected ";" at %s: %s' % (offFinalEnd, sFinal,));
+        offFinalEnd += 1;
+
+        asLines[-1] = sFinal[: offFinalEnd];
+
+        #
+        # Complete and discard the current block.
+        #
         self.oCurMcBlock.complete(self.iLine, offEndStatementInLine, asLines);
         self.oCurMcBlock = None;
Index: trunk/src/VBox/VMM/VMMAll/IEMAllThreadedPython.py
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllThreadedPython.py	(revision 99298)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllThreadedPython.py	(revision 99299)
@@ -132,4 +132,6 @@
     ## @note Effective operand size is generally handled in the decoder, at present
     ##       we only do variations on addressing and memory accessing.
+    ## @todo Blocks without addressing should have 64-bit and 32-bit PC update
+    ##       variations to reduce code size (see iemRegAddToRip).
     ## @{
     ksVariation_Default     = '';               ##< No variations.
@@ -370,5 +372,5 @@
                             self.dParamRefs['u32Disp'][0].sNewName, self.dParamRefs['cbInstr'][0].sNewName,
                         ];
-                # ... and IEM_MC_ADVANCE_RIP_AND_FINISH into *_THREADED ...
+                # ... and IEM_MC_ADVANCE_RIP_AND_FINISH into *_THREADED and maybe *_LM64/_NOT64 ...
                 elif oNewStmt.sName in ('IEM_MC_ADVANCE_RIP_AND_FINISH', 'IEM_MC_REL_JMP_S8_AND_FINISH',
                                         'IEM_MC_REL_JMP_S16_AND_FINISH', 'IEM_MC_REL_JMP_S32_AND_FINISH'):
@@ -377,4 +379,8 @@
                         oNewStmt.asParams.append(self.dParamRefs['pVCpu->iem.s.enmEffOpSize'][0].sNewName);
                     oNewStmt.sName += '_THREADED';
+                    if self.sVariation in (self.ksVariation_Addr64, self.ksVariation_Addr64_32):
+                        oNewStmt.sName += '_LM64';
+                    elif self.sVariation != self.ksVariation_Default:
+                        oNewStmt.sName += '_NOT64';
 
                 # ... and IEM_MC_*_GREG_U8 into *_THREADED w/ reworked index taking REX into account
Index: trunk/src/VBox/VMM/VMMAll/IEMThreadedFunctions.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMThreadedFunctions.cpp	(revision 99298)
+++ trunk/src/VBox/VMM/VMMAll/IEMThreadedFunctions.cpp	(revision 99299)
@@ -80,60 +80,82 @@
 #define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED(a_cbInstr) \
     return iemRegAddToRipAndFinishingClearingRF(pVCpu, a_cbInstr)
-#undef IEM_MC_ADVANCE_RIP_AND_FINISH
+#undef  IEM_MC_ADVANCE_RIP_AND_FINISH
+
+/** Variant of IEM_MC_ADVANCE_RIP_AND_FINISH with instruction length as param
+ *  and only used when we're in 64-bit code. */
+#define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_LM64(a_cbInstr) \
+    return iemRegAddToRip64AndFinishingClearingRF(pVCpu, a_cbInstr)
+#undef  IEM_MC_ADVANCE_RIP_AND_FINISH
+
+/** Variant of IEM_MC_ADVANCE_RIP_AND_FINISH with instruction length as param
+ *  and never used in 64-bit code. */
+#define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_NOT64(a_cbInstr) \
+    return iemRegAddToEip32AndFinishingClearingRF(pVCpu, a_cbInstr)
+#undef  IEM_MC_ADVANCE_RIP_AND_FINISH
 
 /** Variant of IEM_MC_REL_JMP_S8_AND_FINISH with instruction length as param. */
 #define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED(a_i8, a_cbInstr, a_enmEffOpSize) \
     return iemRegRipRelativeJumpS8AndFinishClearingRF(pVCpu, a_cbInstr, (a_i8), a_enmEffOpSize)
-#undef IEM_MC_REL_JMP_S8_AND_FINISH
+#undef  IEM_MC_REL_JMP_S8_AND_FINISH
 
 /** Variant of IEM_MC_REL_JMP_S16_AND_FINISH with instruction length as param. */
 #define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED(a_i16, a_cbInstr) \
     return iemRegRipRelativeJumpS16AndFinishClearingRF(pVCpu, a_cbInstr, (a_i16))
-#undef IEM_MC_REL_JMP_S16_AND_FINISH
+#undef  IEM_MC_REL_JMP_S16_AND_FINISH
 
 /** Variant of IEM_MC_REL_JMP_S32_AND_FINISH with instruction length as param. */
 #define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED(a_i32, a_cbInstr, a_enmEffOpSize) \
     return iemRegRipRelativeJumpS32AndFinishClearingRF(pVCpu, a_cbInstr, (a_i32), a_enmEffOpSize)
-#undef IEM_MC_REL_JMP_S32_AND_FINISH
+#undef  IEM_MC_REL_JMP_S32_AND_FINISH
 
 /** Variant of IEM_MC_CALC_RM_EFF_ADDR with additional parameters. */
-# define IEM_MC_CALC_RM_EFF_ADDR_THREADED_ADDR16(a_GCPtrEff, a_bRm, a_u16Disp) \
+#define IEM_MC_CALC_RM_EFF_ADDR_THREADED_ADDR16(a_GCPtrEff, a_bRm, a_u16Disp) \
     (a_GCPtrEff) = iemOpHlpCalcRmEffAddrThreadedAddr16(pVCpu, a_bRm, a_u16Disp)
+#undef  IEM_MC_CALC_RM_EFF_ADDR
 
 /** Variant of IEM_MC_CALC_RM_EFF_ADDR with additional parameters. */
-# define IEM_MC_CALC_RM_EFF_ADDR_THREADED_ADDR32(a_GCPtrEff, a_bRm, a_bSib, a_u32Disp) \
+#define IEM_MC_CALC_RM_EFF_ADDR_THREADED_ADDR32(a_GCPtrEff, a_bRm, a_bSib, a_u32Disp) \
     (a_GCPtrEff) = iemOpHlpCalcRmEffAddrThreadedAddr32(pVCpu, a_bRm, a_bSib, a_u32Disp)
+#undef  IEM_MC_CALC_RM_EFF_ADDR
 
 /** Variant of IEM_MC_CALC_RM_EFF_ADDR with additional parameters. */
-# define IEM_MC_CALC_RM_EFF_ADDR_THREADED_ADDR32FLAT(a_GCPtrEff, a_bRm, a_bSib, a_u32Disp) \
+#define IEM_MC_CALC_RM_EFF_ADDR_THREADED_ADDR32FLAT(a_GCPtrEff, a_bRm, a_bSib, a_u32Disp) \
     (a_GCPtrEff) = iemOpHlpCalcRmEffAddrThreadedAddr32(pVCpu, a_bRm, a_bSib, a_u32Disp)
+#undef  IEM_MC_CALC_RM_EFF_ADDR
 
 /** Variant of IEM_MC_CALC_RM_EFF_ADDR with additional parameters. */
-# define IEM_MC_CALC_RM_EFF_ADDR_THREADED_ADDR64(a_GCPtrEff, a_bRmEx, a_bSib, a_u32Disp, a_cbImm) \
+#define IEM_MC_CALC_RM_EFF_ADDR_THREADED_ADDR64(a_GCPtrEff, a_bRmEx, a_bSib, a_u32Disp, a_cbImm) \
     (a_GCPtrEff) = iemOpHlpCalcRmEffAddrThreadedAddr64(pVCpu, a_bRmEx, a_bSib, a_u32Disp, a_cbImm)
+#undef  IEM_MC_CALC_RM_EFF_ADDR
 
 /** Variant of IEM_MC_CALC_RM_EFF_ADDR with additional parameters. */
-# define IEM_MC_CALC_RM_EFF_ADDR_THREADED_ADDR6432(a_GCPtrEff, a_bRmEx, a_bSib, a_u32Disp, a_cbImm) \
+#define IEM_MC_CALC_RM_EFF_ADDR_THREADED_ADDR6432(a_GCPtrEff, a_bRmEx, a_bSib, a_u32Disp, a_cbImm) \
     (a_GCPtrEff) = (uint32_t)iemOpHlpCalcRmEffAddrThreadedAddr64(pVCpu, a_bRmEx, a_bSib, a_u32Disp, a_cbImm)
+#undef  IEM_MC_CALC_RM_EFF_ADDR
 
 /** Variant of IEM_MC_CALL_CIMPL_1 with explicit instruction length parameter. */
-# define IEM_MC_CALL_CIMPL_1_THREADED(a_cbInstr, a_pfnCImpl, a0) \
+#define IEM_MC_CALL_CIMPL_1_THREADED(a_cbInstr, a_pfnCImpl, a0) \
     return (a_pfnCImpl)(pVCpu, (a_cbInstr), a0)
+#undef  IEM_MC_CALL_CIMPL_1
 
 /** Variant of IEM_MC_CALL_CIMPL_2 with explicit instruction length parameter. */
-# define IEM_MC_CALL_CIMPL_2_THREADED(a_cbInstr, a_pfnCImpl, a0, a1) \
+#define IEM_MC_CALL_CIMPL_2_THREADED(a_cbInstr, a_pfnCImpl, a0, a1) \
     return (a_pfnCImpl)(pVCpu, (a_cbInstr), a0, a1)
+#undef  IEM_MC_CALL_CIMPL_2
 
 /** Variant of IEM_MC_CALL_CIMPL_3 with explicit instruction length parameter. */
-# define IEM_MC_CALL_CIMPL_3_THREADED(a_cbInstr, a_pfnCImpl, a0, a1, a2) \
+#define IEM_MC_CALL_CIMPL_3_THREADED(a_cbInstr, a_pfnCImpl, a0, a1, a2) \
     return (a_pfnCImpl)(pVCpu, (a_cbInstr), a0, a1, a2)
+#undef  IEM_MC_CALL_CIMPL_3
 
 /** Variant of IEM_MC_CALL_CIMPL_4 with explicit instruction length parameter. */
-# define IEM_MC_CALL_CIMPL_4_THREADED(a_cbInstr, a_pfnCImpl, a0, a1, a2, a3) \
+#define IEM_MC_CALL_CIMPL_4_THREADED(a_cbInstr, a_pfnCImpl, a0, a1, a2, a3) \
     return (a_pfnCImpl)(pVCpu, (a_cbInstr), a0, a1, a2, a3)
+#undef  IEM_MC_CALL_CIMPL_4
 
 /** Variant of IEM_MC_CALL_CIMPL_5 with explicit instruction length parameter. */
-# define IEM_MC_CALL_CIMPL_5_THREADED(a_cbInstr, a_pfnCImpl, a0, a1, a2, a3, a4) \
+#define IEM_MC_CALL_CIMPL_5_THREADED(a_cbInstr, a_pfnCImpl, a0, a1, a2, a3, a4) \
     return (a_pfnCImpl)(pVCpu, (a_cbInstr), a0, a1, a2, a3, a4)
+#undef  IEM_MC_CALL_CIMPL_5
 
 /** Variant of IEM_MC_FETCH_GREG_U8 with extended (20) register index. */
@@ -160,40 +182,50 @@
 #define IEM_MC_FETCH_GREG_U8_SX_U32_THREADED(a_u32Dst, a_iGRegEx) \
     (a_u32Dst) = (int8_t)iemGRegFetchU8Ex(pVCpu, (a_iGRegEx))
+#undef IEM_MC_FETCH_GREG_U8_SX_U32
 
 /** Variant of IEM_MC_FETCH_GREG_U8_SX_U64 with extended (20) register index. */
 #define IEM_MC_FETCH_GREG_U8_SX_U64_THREADED(a_u64Dst, a_iGRegEx) \
     (a_u64Dst) = (int8_t)iemGRegFetchU8Ex(pVCpu, (a_iGRegEx))
+#undef IEM_MC_FETCH_GREG_U8_SX_U64
 
 /** Variant of IEM_MC_STORE_GREG_U8 with extended (20) register index. */
 #define IEM_MC_STORE_GREG_U8_THREADED(a_iGRegEx, a_u8Value) \
     *iemGRegRefU8Ex(pVCpu, (a_iGRegEx)) = (a_u8Value)
+#undef IEM_MC_STORE_GREG_U8
 
 /** Variant of IEM_MC_STORE_GREG_U8 with extended (20) register index. */
 #define IEM_MC_STORE_GREG_U8_CONST_THREADED(a_iGRegEx, a_u8Value) \
     *iemGRegRefU8Ex(pVCpu, (a_iGRegEx)) = (a_u8Value)
+#undef IEM_MC_STORE_GREG_U8
 
 /** Variant of IEM_MC_REF_GREG_U8 with extended (20) register index. */
 #define IEM_MC_REF_GREG_U8_THREADED(a_pu8Dst, a_iGRegEx) \
     (a_pu8Dst) = iemGRegRefU8Ex(pVCpu, (a_iGRegEx))
+#undef IEM_MC_REF_GREG_U8
 
 /** Variant of IEM_MC_ADD_GREG_U8 with extended (20) register index. */
 #define IEM_MC_ADD_GREG_U8_THREADED(a_iGRegEx, a_u8Value) \
     *iemGRegRefU8Ex(pVCpu, (a_iGRegEx)) += (a_u8Value)
+#undef IEM_MC_ADD_GREG_U8
 
 /** Variant of IEM_MC_SUB_GREG_U8 with extended (20) register index. */
 #define IEM_MC_SUB_GREG_U8_THREADED(a_iGRegEx,  a_u8Value) \
     *iemGRegRefU8Ex(pVCpu, (a_iGRegEx)) -= (a_u8Value)
+#undef IEM_MC_SUB_GREG_U8
 
 /** Variant of IEM_MC_ADD_GREG_U8_TO_LOCAL with extended (20) register index. */
 #define IEM_MC_ADD_GREG_U8_TO_LOCAL_THREADED(a_u8Value, a_iGRegEx) \
-    do { (a_u8Value)  += iemGRegFetchU8Ex(pVCpu, (a_iGRegEx)); } while (0)
+    do { (a_u8Value) += iemGRegFetchU8Ex(pVCpu, (a_iGRegEx)); } while (0)
+#undef IEM_MC_ADD_GREG_U8_TO_LOCAL
 
 /** Variant of IEM_MC_AND_GREG_U8 with extended (20) register index. */
 #define IEM_MC_AND_GREG_U8_THREADED(a_iGRegEx, a_u8Value) \
     *iemGRegRefU8Ex(pVCpu, (a_iGRegEx)) &= (a_u8Value)
+#undef IEM_MC_AND_GREG_U8
 
 /** Variant of IEM_MC_OR_GREG_U8 with extended (20) register index. */
 #define IEM_MC_OR_GREG_U8_THREADED(a_iGRegEx, a_u8Value) \
     *iemGRegRefU8Ex(pVCpu, (a_iGRegEx)) |= (a_u8Value)
+#undef IEM_MC_OR_GREG_U8
 
 /**
@@ -278,4 +310,7 @@
     /* Get the register (or SIB) value. */
     uint32_t u32EffAddr;
+#ifdef _MSC_VER
+    u32EffAddr = 0;/* MSC uninitialized variable analysis is too simple, it seems. */
+#endif
     switch (bRm & X86_MODRM_RM_MASK)
     {
@@ -372,6 +407,10 @@
     {
         /* Get the register (or SIB) value. */
+#ifdef _MSC_VER
+        u64EffAddr = 0; /* MSC uninitialized variable analysis is too simple, it seems. */
+#endif
         switch (bRmEx & (X86_MODRM_RM_MASK | 0x8)) /* bRmEx[bit 3] = REX.B */
         {
+            default:
             case  0: u64EffAddr = pVCpu->cpum.GstCtx.rax; break;
             case  1: u64EffAddr = pVCpu->cpum.GstCtx.rcx; break;
Index: trunk/src/VBox/VMM/include/IEMInline.h
===================================================================
--- trunk/src/VBox/VMM/include/IEMInline.h	(revision 99298)
+++ trunk/src/VBox/VMM/include/IEMInline.h	(revision 99299)
@@ -1771,4 +1771,23 @@
 
 /**
+ * Updates the EIP/IP to point to the next instruction - only for 32-bit and
+ * 16-bit code.
+ *
+ * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
+ * @param   cbInstr             The number of bytes to add.
+ */
+DECL_FORCE_INLINE(void) iemRegAddToEip32(PVMCPUCC pVCpu, uint8_t cbInstr) RT_NOEXCEPT
+{
+    /* See comment in iemRegAddToRip. */
+    uint32_t const uEipPrev = pVCpu->cpum.GstCtx.eip;
+    uint32_t const uEipNext = uEipPrev + cbInstr;
+    if (IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_386)
+        pVCpu->cpum.GstCtx.rip = (uint32_t)uEipNext;
+    else
+        pVCpu->cpum.GstCtx.rip = (uint16_t)uEipNext;
+}
+
+
+/**
  * Called by iemRegAddToRipAndFinishingClearingRF and others when any of the
  * following EFLAGS bits are set:
@@ -1871,7 +1890,39 @@
  * @param   cbInstr             The number of bytes to add.
  */
-DECLINLINE(VBOXSTRICTRC) iemRegAddToRipAndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr) RT_NOEXCEPT
+DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToRipAndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr) RT_NOEXCEPT
 {
     iemRegAddToRip(pVCpu, cbInstr);
+    return iemRegFinishClearingRF(pVCpu);
+}
+
+
+/**
+ * Updates the RIP to point to the next instruction and clears EFLAGS.RF
+ * and CPUMCTX_INHIBIT_SHADOW.
+ * 
+ * Only called from 64-code code.
+ *
+ * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
+ * @param   cbInstr             The number of bytes to add.
+ */
+DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToRip64AndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr) RT_NOEXCEPT
+{
+    pVCpu->cpum.GstCtx.rip = pVCpu->cpum.GstCtx.rip + cbInstr;
+    return iemRegFinishClearingRF(pVCpu);
+}
+
+
+/**
+ * Updates the EIP to point to the next instruction and clears EFLAGS.RF and
+ * CPUMCTX_INHIBIT_SHADOW. 
+ *
+ * This is never from 64-code code.
+ *
+ * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
+ * @param   cbInstr             The number of bytes to add.
+ */
+DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToEip32AndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr) RT_NOEXCEPT
+{
+    iemRegAddToEip32(pVCpu, cbInstr);
     return iemRegFinishClearingRF(pVCpu);
 }
