Index: trunk/src/VBox/VMM/Makefile.kmk
===================================================================
--- trunk/src/VBox/VMM/Makefile.kmk	(revision 102470)
+++ trunk/src/VBox/VMM/Makefile.kmk	(revision 102471)
@@ -265,4 +265,5 @@
    VBoxVMM_LIBS.darwin += /opt/local/lib/libcapstone.dylib
   endif
+  VMMAll/IEMAllN8veRecompiler.cpp_CXXFLAGS.win = /bigobj
  endif
  VMMAll/IEMAllThrdFuncs.cpp_CXXFLAGS.win = /bigobj
Index: trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py	(revision 102470)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py	(revision 102471)
@@ -2817,5 +2817,5 @@
     'IEM_MC_ARG_LOCAL_EFLAGS':                                   (McBlock.parseMcArgLocalEFlags,    False, True,  ),
     'IEM_MC_ARG_LOCAL_REF':                                      (McBlock.parseMcArgLocalRef,       False, True,  ),
-    'IEM_MC_ASSIGN_TO_SMALLER':                                  (McBlock.parseMcGeneric,           False, False, ),
+    'IEM_MC_ASSIGN_TO_SMALLER':                                  (McBlock.parseMcGeneric,           False, True,  ),
     'IEM_MC_BEGIN':                                              (McBlock.parseMcBegin,             False, True,  ),
     'IEM_MC_BROADCAST_XREG_U16_ZX_VLMAX':                        (McBlock.parseMcGeneric,           True,  False, ),
Index: trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp	(revision 102470)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp	(revision 102471)
@@ -2949,6 +2949,6 @@
         Assert(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxReg));
 
+        pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxReg);
         pReNative->Core.bmGstRegShadows        &= ~pReNative->Core.aHstRegs[idxReg].fGstRegShadows;
-        pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxReg);
         pReNative->Core.aHstRegs[idxReg].fGstRegShadows = 0;
         return idxReg;
@@ -2989,7 +2989,9 @@
 
                 pReNative->Core.aVars[idxVar].idxReg    = UINT8_MAX;
+                pReNative->Core.bmHstRegs              &= ~RT_BIT_32(idxReg);
+
+                pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxReg);
                 pReNative->Core.bmGstRegShadows        &= ~pReNative->Core.aHstRegs[idxReg].fGstRegShadows;
-                pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxReg);
-                pReNative->Core.bmHstRegs              &= ~RT_BIT_32(idxReg);
+                pReNative->Core.aHstRegs[idxReg].fGstRegShadows = 0;
                 return idxReg;
             }
@@ -3031,5 +3033,6 @@
     if (fGstRegShadows)
     {
-        pReNative->Core.bmHstRegsWithGstShadow |= RT_BIT_32(idxRegNew);
+        pReNative->Core.bmHstRegsWithGstShadow = (pReNative->Core.bmHstRegsWithGstShadow & ~RT_BIT_32(idxRegOld))
+                                               | RT_BIT_32(idxRegNew);
         while (fGstRegShadows)
         {
@@ -3109,6 +3112,6 @@
     pReNative->Core.aVars[idxVar].idxReg    = UINT8_MAX;
     pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxRegOld);
+    pReNative->Core.bmHstRegs              &= ~RT_BIT_32(idxRegOld);
     pReNative->Core.bmGstRegShadows        &= ~pReNative->Core.aHstRegs[idxRegOld].fGstRegShadows;
-    pReNative->Core.bmHstRegs              &= ~RT_BIT_32(idxRegOld);
     pReNative->Core.aHstRegs[idxRegOld].fGstRegShadows = 0;
     return off;
@@ -3202,8 +3205,9 @@
 {
     Assert(!(pReNative->Core.bmGstRegShadows & RT_BIT_64(enmGstReg)));
+    Assert(!pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows);
     Assert((unsigned)enmGstReg < (unsigned)kIemNativeGstReg_End);
 
     pReNative->Core.aidxGstRegShadows[enmGstReg]       = idxHstReg;
-    pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows = RT_BIT_64(enmGstReg);
+    pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows = RT_BIT_64(enmGstReg); /** @todo why? not OR? */
     pReNative->Core.bmGstRegShadows                   |= RT_BIT_64(enmGstReg);
     pReNative->Core.bmHstRegsWithGstShadow            |= RT_BIT_32(idxHstReg);
@@ -3328,4 +3332,5 @@
 {
     Assert(pReNative->Core.aHstRegs[idxRegFrom].fGstRegShadows & RT_BIT_64(enmGstReg));
+    Assert(pReNative->Core.aidxGstRegShadows[enmGstReg] == idxRegFrom);
     Assert(      (pReNative->Core.bmGstRegShadows & pReNative->Core.aHstRegs[idxRegFrom].fGstRegShadows)
               == pReNative->Core.aHstRegs[idxRegFrom].fGstRegShadows
@@ -3625,5 +3630,6 @@
                 Assert(   (pReNative->Core.aHstRegs[idxReg].fGstRegShadows & pReNative->Core.bmGstRegShadows)
                        == pReNative->Core.aHstRegs[idxReg].fGstRegShadows);
-                pReNative->Core.bmGstRegShadows &= ~pReNative->Core.aHstRegs[idxReg].fGstRegShadows;
+                pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxReg);
+                pReNative->Core.bmGstRegShadows        &= ~pReNative->Core.aHstRegs[idxReg].fGstRegShadows;
                 pReNative->Core.aHstRegs[idxReg].fGstRegShadows = 0;
             }
@@ -3726,7 +3732,8 @@
     {
         pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxHstReg);
-        uint64_t const fGstRegShadowsOld = pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows;
+        uint64_t const fGstRegShadowsOld        = pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows;
+        pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows = 0;
         pReNative->Core.bmGstRegShadows        &= ~fGstRegShadowsOld;
-        uint64_t       fGstRegShadows    = fGstRegShadowsOld;
+        uint64_t       fGstRegShadows           = fGstRegShadowsOld;
         while (fGstRegShadows)
         {
@@ -3865,11 +3872,12 @@
      * Reduce the mask by what's currently shadowed
      */
-    fGstRegs &= pReNative->Core.bmGstRegShadows;
+    uint64_t const bmGstRegShadowsOld = pReNative->Core.bmGstRegShadows;
+    fGstRegs &= bmGstRegShadowsOld;
     if (fGstRegs)
     {
-        Log12(("iemNativeRegFlushGuestShadows: flushing %#RX64 (%#RX64 -> %#RX64)\n",
-               fGstRegs, pReNative->Core.bmGstRegShadows, pReNative->Core.bmGstRegShadows & ~fGstRegs));
-        pReNative->Core.bmGstRegShadows &= ~fGstRegs;
-        if (pReNative->Core.bmGstRegShadows)
+        uint64_t const bmGstRegShadowsNew = bmGstRegShadowsOld & ~fGstRegs;
+        Log12(("iemNativeRegFlushGuestShadows: flushing %#RX64 (%#RX64 -> %#RX64)\n", fGstRegs, bmGstRegShadowsOld, bmGstRegShadowsNew));
+        pReNative->Core.bmGstRegShadows = bmGstRegShadowsNew;
+        if (bmGstRegShadowsNew)
         {
             /*
@@ -3886,6 +3894,7 @@
                 uint64_t const fInThisHstReg = (pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows & fGstRegs) | RT_BIT_64(idxGstReg);
                 fGstRegs &= ~fInThisHstReg;
-                pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows &= ~fInThisHstReg;
-                if (!pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows)
+                uint64_t const fGstRegShadowsNew = pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows & ~fInThisHstReg;
+                pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows = fGstRegShadowsNew;
+                if (!fGstRegShadowsNew)
                     pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxHstReg);
             } while (fGstRegs != 0);
@@ -6270,4 +6279,5 @@
     {
         idxReg = g_aidxIemNativeCallRegs[uArgNo];
+        iemNativeRegClearGstRegShadowing(pReNative, idxReg, *poff);
         Log11(("iemNativeVarAllocRegister: idxVar=%u idxReg=%u (matching arg %u)\n", idxVar, idxReg, uArgNo));
     }
@@ -6598,4 +6608,66 @@
 
 
+#define IEM_MC_ASSIGN_TO_SMALLER(a_VarDst, a_VarSrcEol) off = iemNativeVarAssignToSmaller(pReNative, off, a_VarDst, a_VarSrcEol)
+
+/**
+ * This is called by IEM_MC_ASSIGN_TO_SMALLER.
+ */
+DECL_INLINE_THROW(uint32_t)
+iemNativeVarAssignToSmaller(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxVarDst, uint8_t idxVarSrc)
+{
+    IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxVarDst);
+    AssertStmt(pReNative->Core.aVars[idxVarDst].enmKind == kIemNativeVarKind_Invalid,
+               IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_UNEXPECTED_KIND));
+    Assert(   pReNative->Core.aVars[idxVarDst].cbVar == sizeof(uint16_t)
+           || pReNative->Core.aVars[idxVarDst].cbVar == sizeof(uint32_t));
+
+    IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxVarSrc);
+    AssertStmt(   pReNative->Core.aVars[idxVarSrc].enmKind == kIemNativeVarKind_Stack
+               || pReNative->Core.aVars[idxVarSrc].enmKind == kIemNativeVarKind_Immediate,
+               IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_UNEXPECTED_KIND));
+
+    Assert(pReNative->Core.aVars[idxVarDst].cbVar < pReNative->Core.aVars[idxVarSrc].cbVar);
+
+    /*
+     * Special case for immediates.
+     */
+    if (pReNative->Core.aVars[idxVarSrc].enmKind == kIemNativeVarKind_Immediate)
+    {
+        switch (pReNative->Core.aVars[idxVarDst].cbVar)
+        {
+            case sizeof(uint16_t):
+                iemNativeVarSetKindToConst(pReNative, idxVarDst, (uint16_t)pReNative->Core.aVars[idxVarSrc].u.uValue);
+                break;
+            case sizeof(uint32_t):
+                iemNativeVarSetKindToConst(pReNative, idxVarDst, (uint32_t)pReNative->Core.aVars[idxVarSrc].u.uValue);
+                break;
+            default: AssertFailed(); break;
+        }
+    }
+    else
+    {
+        /*
+         * The generic solution for now.
+         */
+        /** @todo optimize this by having the python script make sure the source
+         *        variable passed to IEM_MC_ASSIGN_TO_SMALLER is not used after the
+         *        statement.   Then we could just transfer the register assignments. */
+        uint8_t const idxRegDst = iemNativeVarAllocRegister(pReNative, idxVarDst, &off);
+        uint8_t const idxRegSrc = iemNativeVarAllocRegister(pReNative, idxVarSrc, &off);
+        switch (pReNative->Core.aVars[idxVarDst].cbVar)
+        {
+            case sizeof(uint16_t):
+                off = iemNativeEmitLoadGprFromGpr16(pReNative, off, idxRegDst, idxRegSrc);
+                break;
+            case sizeof(uint32_t):
+                off = iemNativeEmitLoadGprFromGpr32(pReNative, off, idxRegDst, idxRegSrc);
+                break;
+            default: AssertFailed(); break;
+        }
+    }
+    return off;
+}
+
+
 
 /*********************************************************************************************************************************
@@ -6712,4 +6784,5 @@
         Assert(pReNative->Core.bmVars & RT_BIT_32(pReNative->Core.aidxArgVars[i]));
     }
+    iemNativeRegAssertSanity(pReNative);
 #endif
 
@@ -6720,4 +6793,5 @@
     uint32_t bmVars = pReNative->Core.bmVars;
     if (bmVars)
+    {
         do
         {
@@ -6744,4 +6818,8 @@
             }
         } while (bmVars != 0);
+#if 0 //def VBOX_STRICT
+        iemNativeRegAssertSanity(pReNative);
+#endif
+    }
 
     uint8_t const cRegArgs = RT_MIN(cArgs, RT_ELEMENTS(g_aidxIemNativeCallRegs));
@@ -6752,4 +6830,5 @@
      */
     if (pReNative->Core.bmHstRegs & g_afIemNativeCallRegs[cRegArgs])
+    {
         for (uint32_t i = 0; i < cRegArgs; i++)
         {
@@ -6801,4 +6880,8 @@
             }
         }
+#if 0 //def VBOX_STRICT
+        iemNativeRegAssertSanity(pReNative);
+#endif
+    }
 
     Assert(!(pReNative->Core.bmHstRegs & g_afIemNativeCallRegs[cHiddenArgs])); /* No variables for hidden arguments. */
@@ -6812,4 +6895,5 @@
      */
     if (cArgs > IEMNATIVE_CALL_ARG_GREG_COUNT)
+    {
         for (unsigned i = IEMNATIVE_CALL_ARG_GREG_COUNT; i < cArgs; i++)
         {
@@ -6876,4 +6960,8 @@
             }
         }
+# if 0 //def VBOX_STRICT
+        iemNativeRegAssertSanity(pReNative);
+# endif
+    }
 #else
     AssertCompile(IEMNATIVE_CALL_MAX_ARG_COUNT <= IEMNATIVE_CALL_ARG_GREG_COUNT);
@@ -6888,4 +6976,5 @@
      */
     if (~pReNative->Core.bmHstRegs & (g_afIemNativeCallRegs[cRegArgs] & ~g_afIemNativeCallRegs[cHiddenArgs]))
+    {
         for (unsigned i = cHiddenArgs; i < cRegArgs; i++)
         {
@@ -6956,4 +7045,8 @@
             }
         }
+#if 0 //def VBOX_STRICT
+        iemNativeRegAssertSanity(pReNative);
+#endif
+    }
 #ifdef VBOX_STRICT
     else
@@ -7624,5 +7717,5 @@
     else
     {
-        AssertStmt(pReNative->Core.aVars[idxValueVar].enmKind != kIemNativeVarKind_Immediate,
+        AssertStmt(pReNative->Core.aVars[idxValueVar].enmKind == kIemNativeVarKind_Immediate,
                    IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_UNEXPECTED_KIND));
         return iemNativeEmitStoreGregU8Const(pReNative, off, iGRegEx, (uint8_t)pReNative->Core.aVars[idxValueVar].u.uValue);
@@ -7756,5 +7849,5 @@
     else
     {
-        AssertStmt(pReNative->Core.aVars[idxValueVar].enmKind != kIemNativeVarKind_Immediate,
+        AssertStmt(pReNative->Core.aVars[idxValueVar].enmKind == kIemNativeVarKind_Immediate,
                    IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_UNEXPECTED_KIND));
         return iemNativeEmitStoreGregU16Const(pReNative, off, iGReg, (uint16_t)pReNative->Core.aVars[idxValueVar].u.uValue);
@@ -7839,5 +7932,5 @@
     else
     {
-        AssertStmt(pReNative->Core.aVars[idxValueVar].enmKind != kIemNativeVarKind_Immediate,
+        AssertStmt(pReNative->Core.aVars[idxValueVar].enmKind == kIemNativeVarKind_Immediate,
                    IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_UNEXPECTED_KIND));
         return iemNativeEmitStoreGregU32Const(pReNative, off, iGReg, (uint32_t)pReNative->Core.aVars[idxValueVar].u.uValue);
@@ -7892,5 +7985,5 @@
     else
     {
-        AssertStmt(pReNative->Core.aVars[idxValueVar].enmKind != kIemNativeVarKind_Immediate,
+        AssertStmt(pReNative->Core.aVars[idxValueVar].enmKind == kIemNativeVarKind_Immediate,
                    IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_UNEXPECTED_KIND));
         return iemNativeEmitStoreGregU64Const(pReNative, off, iGReg, pReNative->Core.aVars[idxValueVar].u.uValue);
Index: trunk/src/VBox/VMM/include/IEMMc.h
===================================================================
--- trunk/src/VBox/VMM/include/IEMMc.h	(revision 102470)
+++ trunk/src/VBox/VMM/include/IEMMc.h	(revision 102471)
@@ -208,5 +208,6 @@
    do { pVCpu->cpum.GstCtx.eflags.u = (a_EFlags); Assert(pVCpu->cpum.GstCtx.eflags.u & X86_EFL_1); } while (0)
 
-#define IEM_MC_ASSIGN_TO_SMALLER(a_VarOrArg, a_CVariableOrConst) (a_VarOrArg) = (a_CVariableOrConst)
+/** ASSUMES the source variable not used after this statement. */
+#define IEM_MC_ASSIGN_TO_SMALLER(a_VarDst, a_VarSrcEol) (a_VarDst) = (a_VarSrcEol)
 
 #define IEM_MC_FETCH_GREG_U8(a_u8Dst, a_iGReg)          (a_u8Dst)  = iemGRegFetchU8(pVCpu, (a_iGReg))
