Index: trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 102423)
+++ trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 102424)
@@ -6577,4 +6577,27 @@
 }
 
+
+/**
+ * Rolls back the guest memory (conceptually only) and unmaps it.
+ *
+ * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
+ * @param   pvMem               The mapping.
+ * @param   fAccess             The kind of access.
+ */
+void iemMemRollbackAndUnmap(PVMCPUCC pVCpu, void *pvMem, uint32_t fAccess) RT_NOEXCEPT
+{
+    int iMemMap = iemMapLookup(pVCpu, pvMem, fAccess);
+    AssertReturnVoid(iMemMap >= 0);
+
+    /* Unlock it if necessary. */
+    if (!(pVCpu->iem.s.aMemMappings[iMemMap].fAccess & IEM_ACCESS_NOT_LOCKED))
+        PGMPhysReleasePageMappingLock(pVCpu->CTX_SUFF(pVM), &pVCpu->iem.s.aMemMappingLocks[iMemMap].Lock);
+
+    /* Free the entry. */
+    pVCpu->iem.s.aMemMappings[iMemMap].fAccess = IEM_ACCESS_INVALID;
+    Assert(pVCpu->iem.s.cActiveMappings != 0);
+    pVCpu->iem.s.cActiveMappings--;
+}
+
 #ifdef IEM_WITH_SETJMP
 
@@ -6951,4 +6974,12 @@
 }
 
+
+/** Fallback for iemMemRollbackAndUnmapWo.  */
+void iemMemRollbackAndUnmapWoSafe(PVMCPUCC pVCpu, const void *pvMem, uint8_t bMapInfo) RT_NOEXCEPT
+{
+    Assert(bMapInfo == (1 | (IEM_ACCESS_TYPE_READ << 4)) ); RT_NOREF_PV(bMapInfo);
+    iemMemRollbackAndUnmap(pVCpu, (void *)pvMem, IEM_ACCESS_DATA_R);
+}
+
 #endif /* IEM_WITH_SETJMP */
 
@@ -7062,4 +7093,14 @@
 #include "IEMAllMemRWTmpl.cpp.h"
 
+/* See IEMAllMemRWTmplInline.cpp.h */
+#define TMPL_MEM_BY_REF
+
+#define TMPL_MEM_TYPE       RTFLOAT80U
+#define TMPL_MEM_TYPE_ALIGN (sizeof(uint64_t) - 1)
+#define TMPL_MEM_FN_SUFF    R80
+#define TMPL_MEM_FMT_TYPE   "%.10Rhxs"
+#define TMPL_MEM_FMT_DESC   "tword"
+#include "IEMAllMemRWTmpl.cpp.h"
+
 
 /**
@@ -7117,50 +7158,4 @@
 #endif
     return rc;
-}
-#endif
-
-
-/**
- * Fetches a data tword.
- *
- * @returns Strict VBox status code.
- * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
- * @param   pr80Dst             Where to return the tword.
- * @param   iSegReg             The index of the segment register to use for
- *                              this access.  The base and limits are checked.
- * @param   GCPtrMem            The address of the guest memory.
- */
-VBOXSTRICTRC iemMemFetchDataR80(PVMCPUCC pVCpu, PRTFLOAT80U pr80Dst, uint8_t iSegReg, RTGCPTR GCPtrMem) RT_NOEXCEPT
-{
-    /* The lazy approach for now... */
-    PCRTFLOAT80U pr80Src;
-    VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&pr80Src, sizeof(*pr80Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R, 7);
-    if (rc == VINF_SUCCESS)
-    {
-        *pr80Dst = *pr80Src;
-        rc = iemMemCommitAndUnmap(pVCpu, (void *)pr80Src, IEM_ACCESS_DATA_R);
-        Log(("IEM RD tword %d|%RGv: %.10Rhxs\n", iSegReg, GCPtrMem, pr80Dst));
-    }
-    return rc;
-}
-
-
-#ifdef IEM_WITH_SETJMP
-/**
- * Fetches a data tword, longjmp on error.
- *
- * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
- * @param   pr80Dst             Where to return the tword.
- * @param   iSegReg             The index of the segment register to use for
- *                              this access.  The base and limits are checked.
- * @param   GCPtrMem            The address of the guest memory.
- */
-void iemMemFetchDataR80Jmp(PVMCPUCC pVCpu, PRTFLOAT80U pr80Dst, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
-{
-    /* The lazy approach for now... */
-    PCRTFLOAT80U pr80Src = (PCRTFLOAT80U)iemMemMapJmp(pVCpu, sizeof(*pr80Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R, 7);
-    *pr80Dst = *pr80Src;
-    iemMemCommitAndUnmapJmp(pVCpu, (void *)pr80Src, IEM_ACCESS_DATA_R);
-    Log(("IEM RD tword %d|%RGv: %.10Rhxs\n", iSegReg, GCPtrMem, pr80Dst));
 }
 #endif
Index: trunk/src/VBox/VMM/VMMAll/IEMAllInstOneByte.cpp.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllInstOneByte.cpp.h	(revision 102423)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllInstOneByte.cpp.h	(revision 102424)
@@ -9662,26 +9662,30 @@
 {
     IEMOP_MNEMONIC(fst_m32r, "fst m32r");
-    IEM_MC_BEGIN(3, 2, 0, 0);
+    IEM_MC_BEGIN(3, 3, 0, 0);
     IEM_MC_LOCAL(RTGCPTR,               GCPtrEffDst);
-    IEM_MC_LOCAL(uint16_t,              u16Fsw);
-    IEM_MC_ARG_LOCAL_REF(uint16_t *,    pu16Fsw,    u16Fsw, 0);
-    IEM_MC_ARG(PRTFLOAT32U,             pr32Dst,            1);
-    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value,          2);
-
     IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
+
     IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     IEM_MC_MAYBE_RAISE_FPU_XCPT();
-
-    IEM_MC_MEM_MAP(pr32Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
     IEM_MC_PREPARE_FPU_USAGE();
+
+    IEM_MC_LOCAL(uint8_t,               bUnmapInfo);
+    IEM_MC_ARG(PRTFLOAT32U,             pr32Dst,            1);
+    IEM_MC_MEM_MAP_R32_WO(pr32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
+
+    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value,          2);
     IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
+        IEM_MC_LOCAL(uint16_t,          u16Fsw);
+        IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw,    u16Fsw, 0);
         IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fst_r80_to_r32, pu16Fsw, pr32Dst, pr80Value);
-        IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pr32Dst, IEM_ACCESS_DATA_W, u16Fsw);
+        IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(pr32Dst, bUnmapInfo, u16Fsw);
         IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
     } IEM_MC_ELSE() {
         IEM_MC_IF_FCW_IM() {
             IEM_MC_STORE_MEM_NEG_QNAN_R32_BY_REF(pr32Dst);
-            IEM_MC_MEM_COMMIT_AND_UNMAP(pr32Dst, IEM_ACCESS_DATA_W);
+            IEM_MC_MEM_COMMIT_AND_UNMAP_WO(pr32Dst, bUnmapInfo);
+        } IEM_MC_ELSE() {
+            IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(pr32Dst, bUnmapInfo);
         } IEM_MC_ENDIF();
         IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
@@ -9697,26 +9701,30 @@
 {
     IEMOP_MNEMONIC(fstp_m32r, "fstp m32r");
-    IEM_MC_BEGIN(3, 2, 0, 0);
+    IEM_MC_BEGIN(3, 3, 0, 0);
     IEM_MC_LOCAL(RTGCPTR,               GCPtrEffDst);
-    IEM_MC_LOCAL(uint16_t,              u16Fsw);
-    IEM_MC_ARG_LOCAL_REF(uint16_t *,    pu16Fsw,    u16Fsw, 0);
-    IEM_MC_ARG(PRTFLOAT32U,             pr32Dst,            1);
-    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value,          2);
-
     IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
+
     IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     IEM_MC_MAYBE_RAISE_FPU_XCPT();
-
-    IEM_MC_MEM_MAP(pr32Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
     IEM_MC_PREPARE_FPU_USAGE();
+
+    IEM_MC_LOCAL(uint8_t,               bUnmapInfo);
+    IEM_MC_ARG(PRTFLOAT32U,             pr32Dst,            1);
+    IEM_MC_MEM_MAP_R32_WO(pr32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
+
+    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value,          2);
     IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
+        IEM_MC_LOCAL(uint16_t,          u16Fsw);
+        IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw,    u16Fsw, 0);
         IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fst_r80_to_r32, pu16Fsw, pr32Dst, pr80Value);
-        IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pr32Dst, IEM_ACCESS_DATA_W, u16Fsw);
+        IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(pr32Dst, bUnmapInfo, u16Fsw);
         IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
     } IEM_MC_ELSE() {
         IEM_MC_IF_FCW_IM() {
             IEM_MC_STORE_MEM_NEG_QNAN_R32_BY_REF(pr32Dst);
-            IEM_MC_MEM_COMMIT_AND_UNMAP(pr32Dst, IEM_ACCESS_DATA_W);
+            IEM_MC_MEM_COMMIT_AND_UNMAP_WO(pr32Dst, bUnmapInfo);
+        } IEM_MC_ELSE() {
+            IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(pr32Dst, bUnmapInfo);
         } IEM_MC_ENDIF();
         IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
@@ -10779,26 +10787,30 @@
 {
     IEMOP_MNEMONIC(fisttp_m32i, "fisttp m32i");
-    IEM_MC_BEGIN(3, 2, 0, 0);
+    IEM_MC_BEGIN(3, 3, 0, 0);
     IEM_MC_LOCAL(RTGCPTR,               GCPtrEffDst);
-    IEM_MC_LOCAL(uint16_t,              u16Fsw);
-    IEM_MC_ARG_LOCAL_REF(uint16_t *,    pu16Fsw,    u16Fsw, 0);
-    IEM_MC_ARG(int32_t *,               pi32Dst,            1);
-    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value,          2);
-
     IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
+
     IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     IEM_MC_MAYBE_RAISE_FPU_XCPT();
-
-    IEM_MC_MEM_MAP(pi32Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
     IEM_MC_PREPARE_FPU_USAGE();
+
+    IEM_MC_LOCAL(uint8_t,               bUnmapInfo);
+    IEM_MC_ARG(int32_t *,               pi32Dst,            1);
+    IEM_MC_MEM_MAP_I32_WO(pi32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
+
+    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value,          2);
     IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
+        IEM_MC_LOCAL(uint16_t,          u16Fsw);
+        IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw,    u16Fsw, 0);
         IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fistt_r80_to_i32, pu16Fsw, pi32Dst, pr80Value);
-        IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pi32Dst, IEM_ACCESS_DATA_W, u16Fsw);
+        IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(pi32Dst, bUnmapInfo, u16Fsw);
         IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
     } IEM_MC_ELSE() {
         IEM_MC_IF_FCW_IM() {
             IEM_MC_STORE_MEM_I32_CONST_BY_REF(pi32Dst, INT32_MIN /* (integer indefinite) */);
-            IEM_MC_MEM_COMMIT_AND_UNMAP(pi32Dst, IEM_ACCESS_DATA_W);
+            IEM_MC_MEM_COMMIT_AND_UNMAP_WO(pi32Dst, bUnmapInfo);
+        } IEM_MC_ELSE() {
+            IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(pi32Dst, bUnmapInfo);
         } IEM_MC_ENDIF();
         IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
@@ -10814,26 +10826,30 @@
 {
     IEMOP_MNEMONIC(fist_m32i, "fist m32i");
-    IEM_MC_BEGIN(3, 2, 0, 0);
+    IEM_MC_BEGIN(3, 3, 0, 0);
     IEM_MC_LOCAL(RTGCPTR,               GCPtrEffDst);
-    IEM_MC_LOCAL(uint16_t,              u16Fsw);
-    IEM_MC_ARG_LOCAL_REF(uint16_t *,    pu16Fsw,    u16Fsw, 0);
-    IEM_MC_ARG(int32_t *,               pi32Dst,            1);
-    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value,          2);
-
     IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
+
     IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     IEM_MC_MAYBE_RAISE_FPU_XCPT();
-
-    IEM_MC_MEM_MAP(pi32Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
     IEM_MC_PREPARE_FPU_USAGE();
+
+    IEM_MC_LOCAL(uint8_t,               bUnmapInfo);
+    IEM_MC_ARG(int32_t *,               pi32Dst,            1);
+    IEM_MC_MEM_MAP_I32_WO(pi32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
+
+    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value,          2);
     IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
+        IEM_MC_LOCAL(uint16_t,          u16Fsw);
+        IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw,    u16Fsw, 0);
         IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fist_r80_to_i32, pu16Fsw, pi32Dst, pr80Value);
-        IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pi32Dst, IEM_ACCESS_DATA_W, u16Fsw);
+        IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(pi32Dst, bUnmapInfo, u16Fsw);
         IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
     } IEM_MC_ELSE() {
         IEM_MC_IF_FCW_IM() {
             IEM_MC_STORE_MEM_I32_CONST_BY_REF(pi32Dst, INT32_MIN /* (integer indefinite) */);
-            IEM_MC_MEM_COMMIT_AND_UNMAP(pi32Dst, IEM_ACCESS_DATA_W);
+            IEM_MC_MEM_COMMIT_AND_UNMAP_WO(pi32Dst, bUnmapInfo);
+        } IEM_MC_ELSE() {
+            IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(pi32Dst, bUnmapInfo);
         } IEM_MC_ENDIF();
         IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
@@ -10851,24 +10867,28 @@
     IEM_MC_BEGIN(3, 2, 0, 0);
     IEM_MC_LOCAL(RTGCPTR,               GCPtrEffDst);
-    IEM_MC_LOCAL(uint16_t,              u16Fsw);
-    IEM_MC_ARG_LOCAL_REF(uint16_t *,    pu16Fsw,    u16Fsw, 0);
-    IEM_MC_ARG(int32_t *,               pi32Dst,            1);
-    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value,          2);
-
     IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
+
     IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     IEM_MC_MAYBE_RAISE_FPU_XCPT();
-
-    IEM_MC_MEM_MAP(pi32Dst, IEM_ACCESS_DATA_W, pVCpu->iem.s.iEffSeg, GCPtrEffDst, 1 /*arg*/);
     IEM_MC_PREPARE_FPU_USAGE();
+
+    IEM_MC_LOCAL(uint8_t,               bUnmapInfo);
+    IEM_MC_ARG(int32_t *,               pi32Dst,            1);
+    IEM_MC_MEM_MAP_I32_WO(pi32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
+
+    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value,          2);
     IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
+        IEM_MC_LOCAL(uint16_t,          u16Fsw);
+        IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw,    u16Fsw, 0);
         IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fist_r80_to_i32, pu16Fsw, pi32Dst, pr80Value);
-        IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pi32Dst, IEM_ACCESS_DATA_W, u16Fsw);
+        IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(pi32Dst, bUnmapInfo, u16Fsw);
         IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
     } IEM_MC_ELSE() {
         IEM_MC_IF_FCW_IM() {
             IEM_MC_STORE_MEM_I32_CONST_BY_REF(pi32Dst, INT32_MIN /* (integer indefinite) */);
-            IEM_MC_MEM_COMMIT_AND_UNMAP(pi32Dst, IEM_ACCESS_DATA_W);
+            IEM_MC_MEM_COMMIT_AND_UNMAP_WO(pi32Dst, bUnmapInfo);
+        } IEM_MC_ELSE() {
+            IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(pi32Dst, bUnmapInfo);
         } IEM_MC_ENDIF();
         IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
@@ -10916,26 +10936,30 @@
 {
     IEMOP_MNEMONIC(fstp_m80r, "fstp m80r");
-    IEM_MC_BEGIN(3, 2, 0, 0);
+    IEM_MC_BEGIN(3, 3, 0, 0);
     IEM_MC_LOCAL(RTGCPTR,               GCPtrEffDst);
-    IEM_MC_LOCAL(uint16_t,              u16Fsw);
-    IEM_MC_ARG_LOCAL_REF(uint16_t *,    pu16Fsw,    u16Fsw, 0);
-    IEM_MC_ARG(PRTFLOAT80U,             pr80Dst,            1);
-    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value,          2);
-
     IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
+
     IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     IEM_MC_MAYBE_RAISE_FPU_XCPT();
-
-    IEM_MC_MEM_MAP_EX(pr80Dst, IEM_ACCESS_DATA_W, sizeof(*pr80Dst), pVCpu->iem.s.iEffSeg, GCPtrEffDst, 7 /*cbAlign*/, 1 /*arg*/);
     IEM_MC_PREPARE_FPU_USAGE();
+
+    IEM_MC_LOCAL(uint8_t,               bUnmapInfo);
+    IEM_MC_ARG(PRTFLOAT80U,             pr80Dst,            1);
+    IEM_MC_MEM_MAP_R80_WO(pr80Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst);
+
+    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value,          2);
     IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) {
+        IEM_MC_LOCAL(uint16_t,          u16Fsw);
+        IEM_MC_ARG_LOCAL_REF(uint16_t *,pu16Fsw,    u16Fsw, 0);
         IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fst_r80_to_r80, pu16Fsw, pr80Dst, pr80Value);
-        IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(pr80Dst, IEM_ACCESS_DATA_W, u16Fsw);
+        IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(pr80Dst, bUnmapInfo, u16Fsw);
         IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16Fsw, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
     } IEM_MC_ELSE() {
         IEM_MC_IF_FCW_IM() {
             IEM_MC_STORE_MEM_NEG_QNAN_R80_BY_REF(pr80Dst);
-            IEM_MC_MEM_COMMIT_AND_UNMAP(pr80Dst, IEM_ACCESS_DATA_W);
+            IEM_MC_MEM_COMMIT_AND_UNMAP_WO(pr80Dst, bUnmapInfo);
+        } IEM_MC_ELSE() {
+            IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(pr80Dst, bUnmapInfo);
         } IEM_MC_ENDIF();
         IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pVCpu->iem.s.iEffSeg, GCPtrEffDst, pVCpu->iem.s.uFpuOpcode);
Index: trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py	(revision 102423)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py	(revision 102424)
@@ -3025,6 +3025,9 @@
     'IEM_MC_MEM_COMMIT_AND_UNMAP_WO':                            (McBlock.parseMcGeneric,           True,  False, ),
     'IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE':                 (McBlock.parseMcGeneric,           True,  False, ),
+    'IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO':              (McBlock.parseMcGeneric,           True,  False, ),
     'IEM_MC_MEM_MAP':                                            (McBlock.parseMcGeneric,           True,  False, ),
     'IEM_MC_MEM_MAP_EX':                                         (McBlock.parseMcGeneric,           True,  False, ),
+    'IEM_MC_MEM_MAP_I32_WO':                                     (McBlock.parseMcGeneric,           True,  False, ),
+    'IEM_MC_MEM_MAP_R32_WO':                                     (McBlock.parseMcGeneric,           True,  False, ),
     'IEM_MC_MEM_MAP_U8_RW':                                      (McBlock.parseMcGeneric,           True,  False, ),
     'IEM_MC_MEM_MAP_U8_RO':                                      (McBlock.parseMcGeneric,           True,  False, ),
@@ -3039,4 +3042,6 @@
     'IEM_MC_MEM_MAP_U64_RO':                                     (McBlock.parseMcGeneric,           True,  False, ),
     'IEM_MC_MEM_MAP_U64_WO':                                     (McBlock.parseMcGeneric,           True,  False, ),
+    'IEM_MC_MEM_MAP_R80_WO':                                     (McBlock.parseMcGeneric,           True,  False, ),
+    'IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO':                          (McBlock.parseMcGeneric,           True,  False, ),
     'IEM_MC_MERGE_YREG_U32_U96_ZX_VLMAX':                        (McBlock.parseMcGeneric,           True,  False, ),
     'IEM_MC_MERGE_YREG_U64_U64_ZX_VLMAX':                        (McBlock.parseMcGeneric,           True,  False, ),
Index: trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmpl.cpp.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmpl.cpp.h	(revision 102423)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmpl.cpp.h	(revision 102424)
@@ -72,10 +72,24 @@
  * Safe/fallback fetch function that longjmps on error.
  */
+# ifdef TMPL_MEM_BY_REF
+void
+RT_CONCAT3(iemMemFetchData,TMPL_MEM_FN_SUFF,SafeJmp)(PVMCPUCC pVCpu, TMPL_MEM_TYPE *pDst, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
+{
+#  if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
+    pVCpu->iem.s.DataTlb.cTlbSafeReadPath++;
+#  endif
+    TMPL_MEM_TYPE const *pSrc = (TMPL_MEM_TYPE const *)iemMemMapJmp(pVCpu, sizeof(*pSrc), iSegReg, GCPtrMem,
+                                                                    IEM_ACCESS_DATA_R, TMPL_MEM_TYPE_ALIGN);
+    *pDst = *pSrc;
+    iemMemCommitAndUnmapJmp(pVCpu, (void *)pSrc, IEM_ACCESS_DATA_R);
+    Log2(("IEM RD " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, pDst));
+}
+# else /* !TMPL_MEM_BY_REF */
 TMPL_MEM_TYPE
 RT_CONCAT3(iemMemFetchData,TMPL_MEM_FN_SUFF,SafeJmp)(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
 {
-# if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
+#  if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
     pVCpu->iem.s.DataTlb.cTlbSafeReadPath++;
-# endif
+#  endif
     TMPL_MEM_TYPE const *puSrc = (TMPL_MEM_TYPE const *)iemMemMapJmp(pVCpu, sizeof(*puSrc), iSegReg, GCPtrMem,
                                                                      IEM_ACCESS_DATA_R, TMPL_MEM_TYPE_ALIGN);
@@ -85,4 +99,5 @@
     return uRet;
 }
+# endif /* !TMPL_MEM_BY_REF */
 #endif /* IEM_WITH_SETJMP */
 
@@ -90,5 +105,5 @@
 
 /**
- * Standard fetch function.
+ * Standard store function.
  *
  * This is used by CImpl code, so it needs to be kept even when IEM_WITH_SETJMP
@@ -96,5 +111,9 @@
  */
 VBOXSTRICTRC RT_CONCAT(iemMemStoreData,TMPL_MEM_FN_SUFF)(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem,
+#ifdef TMPL_MEM_BY_REF
+                                                         TMPL_MEM_TYPE const *pValue) RT_NOEXCEPT
+#else
                                                          TMPL_MEM_TYPE uValue) RT_NOEXCEPT
+#endif
 {
     /* The lazy approach for now... */
@@ -103,7 +122,15 @@
     if (rc == VINF_SUCCESS)
     {
+#ifdef TMPL_MEM_BY_REF
+        *puDst = *pValue;
+#else
         *puDst = uValue;
+#endif
         rc = iemMemCommitAndUnmap(pVCpu, puDst, IEM_ACCESS_DATA_W);
+#ifdef TMPL_MEM_BY_REF
+        Log6(("IEM WR " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, pValue));
+#else
         Log6(("IEM WR " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, uValue));
+#endif
     }
     return rc;
@@ -119,16 +146,28 @@
  *                              this access.  The base and limits are checked.
  * @param   GCPtrMem            The address of the guest memory.
- * @param   u8Value             The value to store.
+ * @param   uValue              The value to store.
  */
 void RT_CONCAT3(iemMemStoreData,TMPL_MEM_FN_SUFF,SafeJmp)(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem,
+#ifdef TMPL_MEM_BY_REF
+                                                          TMPL_MEM_TYPE const *pValue) IEM_NOEXCEPT_MAY_LONGJMP
+#else
                                                           TMPL_MEM_TYPE uValue) IEM_NOEXCEPT_MAY_LONGJMP
+#endif
 {
 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
     pVCpu->iem.s.DataTlb.cTlbSafeWritePath++;
 # endif
+#ifdef TMPL_MEM_BY_REF
+    Log6(("IEM WR " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, pValue));
+#else
     Log6(("IEM WR " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, uValue));
+#endif
     TMPL_MEM_TYPE *puDst = (TMPL_MEM_TYPE *)iemMemMapJmp(pVCpu, sizeof(*puDst), iSegReg, GCPtrMem,
                                                          IEM_ACCESS_DATA_W, TMPL_MEM_TYPE_ALIGN);
+#ifdef TMPL_MEM_BY_REF
+    *puDst = *pValue;
+#else
     *puDst = uValue;
+#endif
     iemMemCommitAndUnmapJmp(pVCpu, puDst, IEM_ACCESS_DATA_W);
 }
@@ -461,4 +500,5 @@
 #undef TMPL_MEM_FMT_TYPE
 #undef TMPL_MEM_FMT_DESC
+#undef TMPL_MEM_BY_REF
 #undef TMPL_WITH_PUSH_SREG
 
Index: trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h	(revision 102423)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h	(revision 102424)
@@ -47,6 +47,32 @@
 #endif
 
+
+/** Helper for checking if @a a_GCPtr is acceptably aligned and fully within
+ *  the page for a TMPL_MEM_TYPE.  */
 #if TMPL_MEM_TYPE_ALIGN + 1 < TMPL_MEM_TYPE_SIZE
-# error Have not implemented TMPL_MEM_TYPE_ALIGN smaller than TMPL_MEM_TYPE_SIZE - 1.
+# define TMPL_MEM_ALIGN_CHECK(a_GCPtr) (   (   !((a_GCPtr) & TMPL_MEM_TYPE_ALIGN) \
+                                            && ((a_GCPtr) & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)) \
+                                        || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, (a_GCPtr), TMPL_MEM_TYPE))
+#else
+# define TMPL_MEM_ALIGN_CHECK(a_GCPtr) (   !((a_GCPtr) & TMPL_MEM_TYPE_ALIGN) /* If aligned, it will be within the page. */ \
+                                        || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, (a_GCPtr), TMPL_MEM_TYPE))
+#endif
+
+/**
+ * Values have to be passed by reference if larger than uint64_t.
+ *
+ * This is a restriction of the Visual C++ AMD64 calling convention,
+ * the gcc AMD64 and ARM64 ABIs can easily pass and return to 128-bit via
+ * registers.  For larger values like RTUINT256U, Visual C++ AMD and ARM64
+ * passes them by hidden reference, whereas the gcc AMD64 ABI will use stack.
+ *
+ * So, to avoid passing anything on the stack, we just explictly pass values by
+ * reference (pointer) if they are larger than uint64_t.  This ASSUMES 64-bit
+ * host.
+ */
+#if TMPL_MEM_TYPE_SIZE > 8
+# define TMPL_MEM_BY_REF
+#else
+# undef TMPL_MEM_BY_REF
 #endif
 
@@ -64,6 +90,11 @@
  * @note The @a iSegRef is not allowed to be UINT8_MAX!
  */
+#ifdef TMPL_MEM_BY_REF
+DECL_INLINE_THROW(void)
+RT_CONCAT3(iemMemFetchData,TMPL_MEM_FN_SUFF,Jmp)(PVMCPUCC pVCpu, TMPL_MEM_TYPE *pValue, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
+#else
 DECL_INLINE_THROW(TMPL_MEM_TYPE)
 RT_CONCAT3(iemMemFetchData,TMPL_MEM_FN_SUFF,Jmp)(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
+#endif
 {
     AssertCompile(sizeof(TMPL_MEM_TYPE) == TMPL_MEM_TYPE_SIZE);
@@ -74,6 +105,5 @@
     RTGCPTR GCPtrEff = iemMemApplySegmentToReadJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN) /* If aligned, it will be within the page. */
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ))
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(GCPtrEff)))
 #  endif
     {
@@ -100,8 +130,15 @@
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
+#  ifdef TMPL_MEM_BY_REF
+                *pValue = *(TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
+                LogEx(LOG_GROUP_IEM_MEM,("IEM RD " TMPL_MEM_FMT_DESC " %d|%RGv=%RGv: %." RT_XSTR(TMPL_MEM_TYPE_SIZE) "Rhxs\n",
+                                         iSegReg, GCPtrMem, GCPtrEff, pValue));
+                return;
+#  else
                 TMPL_MEM_TYPE const uRet = *(TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
                 LogEx(LOG_GROUP_IEM_MEM,("IEM RD " TMPL_MEM_FMT_DESC " %d|%RGv=%RGv: " TMPL_MEM_FMT_TYPE "\n",
                                          iSegReg, GCPtrMem, GCPtrEff, uRet));
                 return uRet;
+#  endif
             }
         }
@@ -112,5 +149,9 @@
     LogEx(LOG_GROUP_IEM_MEM,(LOG_FN_FMT ": %u:%RGv falling back\n", LOG_FN_NAME, iSegReg, GCPtrMem));
 # endif
+# ifdef TMPL_MEM_BY_REF
+    RT_CONCAT3(iemMemFetchData,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu, pValue, iSegReg, GCPtrMem);
+# else
     return RT_CONCAT3(iemMemFetchData,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu, iSegReg, GCPtrMem);
+# endif
 }
 
@@ -119,6 +160,11 @@
  * Inlined flat addressing fetch function that longjumps on error.
  */
+# ifdef TMPL_MEM_BY_REF
+DECL_INLINE_THROW(void)
+RT_CONCAT3(iemMemFlatFetchData,TMPL_MEM_FN_SUFF,Jmp)(PVMCPUCC pVCpu, TMPL_MEM_TYPE *pValue, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
+# else
 DECL_INLINE_THROW(TMPL_MEM_TYPE)
 RT_CONCAT3(iemMemFlatFetchData,TMPL_MEM_FN_SUFF,Jmp)(PVMCPUCC pVCpu, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
+# endif
 {
     AssertMsg(   (pVCpu->iem.s.fExec & IEM_F_MODE_MASK) == IEM_F_MODE_X86_64BIT
@@ -130,8 +176,5 @@
      */
 #  if TMPL_MEM_TYPE_SIZE > 1
-    AssertCompile(X86_CR0_AM == X86_EFL_AC);
-    AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
-    if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN) /* If aligned, it will be within the page. */
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrMem, TMPL_MEM_TYPE) ))
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(GCPtrMem)))
 #  endif
     {
@@ -158,7 +201,14 @@
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
+#  ifdef TMPL_MEM_BY_REF
+                *pValue = *(TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
+                LogEx(LOG_GROUP_IEM_MEM,("IEM RD " TMPL_MEM_FMT_DESC " %RGv: %." RT_XSTR(TMPL_MEM_TYPE_SIZE) "Rhxs\n",
+                                         GCPtrMem, pValue));
+                return;
+#  else
                 TMPL_MEM_TYPE const uRet = *(TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
                 LogEx(LOG_GROUP_IEM_MEM,("IEM RD " TMPL_MEM_FMT_DESC " %RGv: " TMPL_MEM_FMT_TYPE "\n", GCPtrMem, uRet));
                 return uRet;
+#  endif
             }
         }
@@ -169,5 +219,9 @@
     LogEx(LOG_GROUP_IEM_MEM,(LOG_FN_FMT ": %RGv falling back\n", LOG_FN_NAME, GCPtrMem));
 # endif
+# ifdef TMPL_MEM_BY_REF
+    RT_CONCAT3(iemMemFetchData,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu, pValue, UINT8_MAX, GCPtrMem);
+# else
     return RT_CONCAT3(iemMemFetchData,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu, UINT8_MAX, GCPtrMem);
+# endif
 }
 
@@ -185,5 +239,9 @@
 DECL_INLINE_THROW(void)
 RT_CONCAT3(iemMemStoreData,TMPL_MEM_FN_SUFF,Jmp)(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem,
+#  ifdef TMPL_MEM_BY_REF
+                                                 TMPL_MEM_TYPE const *pValue) IEM_NOEXCEPT_MAY_LONGJMP
+#  else
                                                  TMPL_MEM_TYPE uValue) IEM_NOEXCEPT_MAY_LONGJMP
+#  endif
 {
 #  if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3) && !defined(TMPL_MEM_NO_INLINE)
@@ -193,8 +251,5 @@
     RTGCPTR GCPtrEff = iemMemApplySegmentToWriteJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
 #  if TMPL_MEM_TYPE_SIZE > 1
-    AssertCompile(X86_CR0_AM == X86_EFL_AC);
-    AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
-    if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN) /* If aligned, it will be within the page. */
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ))
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(GCPtrEff)))
 #  endif
     {
@@ -217,12 +272,18 @@
             {
                 /*
-                 * Store the dword and return.
-                 */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
-                Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
-                Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
+                 * Store the value and return.
+                 */
+                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+                Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
+                Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
+#   ifdef TMPL_MEM_BY_REF
+                *(TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK] = *pValue;
+                Log5Ex(LOG_GROUP_IEM_MEM,("IEM WR " TMPL_MEM_FMT_DESC " %d|%RGv=%RGv: %." RT_XSTR(TMPL_MEM_TYPE_SIZE) "Rhxs (%04x:%RX64)\n",
+                                          iSegReg, GCPtrMem, GCPtrEff, pValue, pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip));
+#   else
                 *(TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK] = uValue;
                 Log5Ex(LOG_GROUP_IEM_MEM,("IEM WR " TMPL_MEM_FMT_DESC " %d|%RGv=%RGv: " TMPL_MEM_FMT_TYPE " (%04x:%RX64)\n",
                                           iSegReg, GCPtrMem, GCPtrEff, uValue, pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip));
+#   endif
                 return;
             }
@@ -234,5 +295,9 @@
     Log6Ex(LOG_GROUP_IEM_MEM,(LOG_FN_FMT ": %u:%RGv falling back\n", LOG_FN_NAME, iSegReg, GCPtrMem));
 #  endif
+#  ifdef TMPL_MEM_BY_REF
+    RT_CONCAT3(iemMemStoreData,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu, iSegReg, GCPtrMem, pValue);
+#  else
     RT_CONCAT3(iemMemStoreData,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu, iSegReg, GCPtrMem, uValue);
+#  endif
 }
 
@@ -243,5 +308,9 @@
 DECL_INLINE_THROW(void)
 RT_CONCAT3(iemMemFlatStoreData,TMPL_MEM_FN_SUFF,Jmp)(PVMCPUCC pVCpu, RTGCPTR GCPtrMem,
-                                                     TMPL_MEM_TYPE uValue) IEM_NOEXCEPT_MAY_LONGJMP
+#  ifdef TMPL_MEM_BY_REF
+                                                    TMPL_MEM_TYPE const *pValue) IEM_NOEXCEPT_MAY_LONGJMP
+#  else
+                                                    TMPL_MEM_TYPE uValue) IEM_NOEXCEPT_MAY_LONGJMP
+#  endif
 {
     AssertMsg(   (pVCpu->iem.s.fExec & IEM_F_MODE_MASK) == IEM_F_MODE_X86_64BIT
@@ -253,6 +322,5 @@
      */
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrMem, TMPL_MEM_TYPE) ))
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(GCPtrMem)))
 #  endif
     {
@@ -275,11 +343,17 @@
             {
                 /*
-                 * Store the dword and return.
-                 */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
-                Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
-                Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
+                 * Store the value and return.
+                 */
+                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+                Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
+                Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
+#   ifdef TMPL_MEM_BY_REF
+                *(TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK] = *pValue;
+                Log5Ex(LOG_GROUP_IEM_MEM,("IEM WR " TMPL_MEM_FMT_DESC " %RGv: %." RT_XSTR(TMPL_MEM_TYPE_SIZE) "Rhxs\n",
+                                          GCPtrMem, pValue));
+#   else
                 *(TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK] = uValue;
                 Log5Ex(LOG_GROUP_IEM_MEM,("IEM WR " TMPL_MEM_FMT_DESC " %RGv: " TMPL_MEM_FMT_TYPE "\n", GCPtrMem, uValue));
+#   endif
                 return;
             }
@@ -291,5 +365,9 @@
     Log6Ex(LOG_GROUP_IEM_MEM,(LOG_FN_FMT ": %RGv falling back\n", LOG_FN_NAME, GCPtrMem));
 #  endif
+#  ifdef TMPL_MEM_BY_REF
+    RT_CONCAT3(iemMemStoreData,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu, UINT8_MAX, GCPtrMem, pValue);
+#  else
     RT_CONCAT3(iemMemStoreData,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu, UINT8_MAX, GCPtrMem, uValue);
+#  endif
 }
 
@@ -313,8 +391,7 @@
      * Convert from segmented to flat address and check that it doesn't cross a page boundrary.
      */
-    RTGCPTR GCPtrEff = iemMemApplySegmentToWriteJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
-#  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ))
+    RTGCPTR const GCPtrEff = iemMemApplySegmentToWriteJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
+#  if TMPL_MEM_TYPE_SIZE > 1
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(GCPtrEff)))
 #  endif
     {
@@ -371,6 +448,5 @@
      */
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrMem, TMPL_MEM_TYPE) ))
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(GCPtrMem)))
 #  endif
     {
@@ -426,8 +502,7 @@
      * Convert from segmented to flat address and check that it doesn't cross a page boundrary.
      */
-    RTGCPTR GCPtrEff = iemMemApplySegmentToWriteJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
-#  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ))
+    RTGCPTR const GCPtrEff = iemMemApplySegmentToWriteJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
+#  if TMPL_MEM_TYPE_SIZE > 1
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(GCPtrEff)))
 #  endif
     {
@@ -484,6 +559,5 @@
      */
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrMem, TMPL_MEM_TYPE) ))
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(GCPtrMem)))
 #  endif
     {
@@ -539,9 +613,8 @@
      * Convert from segmented to flat address and check that it doesn't cross a page boundrary.
      */
-    RTGCPTR GCPtrEff = iemMemApplySegmentToReadJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
-#  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ))
-#  endif
+    RTGCPTR const GCPtrEff = iemMemApplySegmentToReadJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
+#  if TMPL_MEM_TYPE_SIZE > 1
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(GCPtrEff)))
+#endif
     {
         /*
@@ -596,6 +669,5 @@
      */
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrMem, TMPL_MEM_TYPE) ))
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(GCPtrMem)))
 #  endif
     {
@@ -645,4 +717,10 @@
 *********************************************************************************************************************************/
 # ifdef TMPL_MEM_WITH_STACK
+#  if TMPL_MEM_TYPE_SIZE > 8
+#   error "Stack not supported for this type size - please #undef TMPL_MEM_WITH_STACK"
+#  endif
+#  if TMPL_MEM_TYPE_SIZE > 1 && TMPL_MEM_TYPE_ALIGN + 1 < TMPL_MEM_TYPE_SIZE
+#   error "Stack not supported for this alignment size - please #undef TMPL_MEM_WITH_STACK"
+#  endif
 #  ifdef IEM_WITH_SETJMP
 
@@ -662,6 +740,5 @@
     RTGCPTR const GCPtrEff = iemMemApplySegmentToWriteJmp(pVCpu, X86_SREG_SS, sizeof(TMPL_MEM_TYPE), GCPtrTop);
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ))
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(GCPtrEff)))
 #  endif
     {
@@ -722,6 +799,5 @@
     RTGCPTR const GCPtrEff = iemMemApplySegmentToWriteJmp(pVCpu, X86_SREG_SS, sizeof(TMPL_MEM_TYPE), GCPtrTop);
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ))
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(GCPtrEff)))
 #  endif
     {
@@ -847,6 +923,5 @@
     uint32_t const uNewEsp = pVCpu->cpum.GstCtx.esp - sizeof(TMPL_MEM_TYPE);
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY(   !(uNewEsp & TMPL_MEM_TYPE_ALIGN)
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, uNewEsp, TMPL_MEM_TYPE) ))
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(uNewEsp)))
 #  endif
     {
@@ -904,6 +979,5 @@
     uint32_t const uOldEsp = pVCpu->cpum.GstCtx.esp;
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY(   !(uOldEsp & TMPL_MEM_TYPE_ALIGN)
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, uOldEsp, TMPL_MEM_TYPE) ))
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(uOldEsp)))
 #  endif
     {
@@ -1021,6 +1095,5 @@
     uint64_t const uNewRsp = pVCpu->cpum.GstCtx.rsp - sizeof(TMPL_MEM_TYPE);
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY(   !(uNewRsp & TMPL_MEM_TYPE_ALIGN)
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, uNewRsp, TMPL_MEM_TYPE) ))
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(uNewRsp)))
 #  endif
     {
@@ -1078,6 +1151,5 @@
     uint64_t const uOldRsp = pVCpu->cpum.GstCtx.rsp;
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY(   !(uOldRsp & TMPL_MEM_TYPE_ALIGN)
-                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, uOldRsp, TMPL_MEM_TYPE) ))
+    if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(uOldRsp)))
 #  endif
     {
@@ -1136,3 +1208,5 @@
 #undef TMPL_MEM_FMT_DESC
 #undef TMPL_MEM_NO_STORE
-
+#undef TMPL_MEM_ALIGN_CHECK
+#undef TMPL_MEM_BY_REF
+
Index: trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py	(revision 102423)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py	(revision 102424)
@@ -150,8 +150,11 @@
     'IEM_MC_MEM_FLAT_MAP_U32_RO':                                (None, True,  False, ),
     'IEM_MC_MEM_FLAT_MAP_U32_RW':                                (None, True,  False, ),
+    'IEM_MC_MEM_FLAT_MAP_I32_WO':                                (None, True,  False, ),
+    'IEM_MC_MEM_FLAT_MAP_R32_WO':                                (None, True,  False, ),
     'IEM_MC_MEM_FLAT_MAP_U64_RO':                                (None, True,  False, ),
     'IEM_MC_MEM_FLAT_MAP_U64_RW':                                (None, True,  False, ),
     'IEM_MC_MEM_FLAT_MAP_U8_RO':                                 (None, True,  False, ),
     'IEM_MC_MEM_FLAT_MAP_U8_RW':                                 (None, True,  False, ),
+    'IEM_MC_MEM_FLAT_MAP_R80_WO':                                (None, True,  False, ),
     'IEM_MC_STORE_MEM_FLAT_U128_ALIGN_SSE':                      (None, True,  False, ),
     'IEM_MC_STORE_MEM_FLAT_U128':                                (None, True,  False, ),
Index: trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py	(revision 102423)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py	(revision 102424)
@@ -714,7 +714,10 @@
         'IEM_MC_MEM_MAP_U32_RO':                  (  2, 'IEM_MC_MEM_FLAT_MAP_U32_RO' ),
         'IEM_MC_MEM_MAP_U32_WO':                  (  2, 'IEM_MC_MEM_FLAT_MAP_U32_WO' ),
+        'IEM_MC_MEM_MAP_I32_WO':                  (  2, 'IEM_MC_MEM_FLAT_MAP_I32_WO' ),
+        'IEM_MC_MEM_MAP_R32_WO':                  (  2, 'IEM_MC_MEM_FLAT_MAP_R32_WO' ),
         'IEM_MC_MEM_MAP_U64_RW':                  (  2, 'IEM_MC_MEM_FLAT_MAP_U64_RW' ),
         'IEM_MC_MEM_MAP_U64_RO':                  (  2, 'IEM_MC_MEM_FLAT_MAP_U64_RO' ),
         'IEM_MC_MEM_MAP_U64_WO':                  (  2, 'IEM_MC_MEM_FLAT_MAP_U64_WO' ),
+        'IEM_MC_MEM_MAP_R80_WO':                  (  2, 'IEM_MC_MEM_FLAT_MAP_R80_WO' ),
         'IEM_MC_MEM_MAP_EX':                      (  3, 'IEM_MC_MEM_FLAT_MAP_EX' ),
     };
@@ -1350,6 +1353,6 @@
                 self.analyzeFindVariablesAndCallArgs(oStmt.aoIfBranch);
                 self.analyzeFindVariablesAndCallArgs(oStmt.aoElseBranch);
-                if len(self.dVariables) != cBefore:
-                    raise Exception('Variables/arguments defined in conditional branches!');
+                #if len(self.dVariables) != cBefore:
+                #    raise Exception('Variables/arguments defined in conditional branches!');
         return True;
 
Index: trunk/src/VBox/VMM/include/IEMInline.h
===================================================================
--- trunk/src/VBox/VMM/include/IEMInline.h	(revision 102423)
+++ trunk/src/VBox/VMM/include/IEMInline.h	(revision 102424)
@@ -3744,4 +3744,13 @@
 }
 
+DECLINLINE(void) iemMemRollbackAndUnmapWo(PVMCPUCC pVCpu, const void *pvMem, uint8_t bMapInfo) RT_NOEXCEPT
+{
+# if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
+    if (RT_LIKELY(bMapInfo == 0))
+        return;
+# endif
+    iemMemRollbackAndUnmapWoSafe(pVCpu, pvMem, bMapInfo);
+}
+
 #endif /* IEM_WITH_SETJMP */
 
@@ -3819,4 +3828,15 @@
 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
 
+#undef TMPL_MEM_NO_STORE
+#undef TMPL_MEM_NO_MAPPING
+
+#define TMPL_MEM_TYPE       RTFLOAT80U
+#define TMPL_MEM_TYPE_ALIGN 7
+#define TMPL_MEM_TYPE_SIZE  10
+#define TMPL_MEM_FN_SUFF    R80
+#define TMPL_MEM_FMT_TYPE   "%.10Rhxs"
+#define TMPL_MEM_FMT_DESC   "tword"
+#include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
+
 #undef TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK
 
Index: trunk/src/VBox/VMM/include/IEMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/IEMInternal.h	(revision 102423)
+++ trunk/src/VBox/VMM/include/IEMInternal.h	(revision 102424)
@@ -5045,4 +5045,5 @@
 VBOXSTRICTRC    iemMemCommitAndUnmapPostponeTroubleToR3(PVMCPUCC pVCpu, void *pvMem, uint32_t fAccess) RT_NOEXCEPT;
 #endif
+void            iemMemRollbackAndUnmap(PVMCPUCC pVCpu, void *pvMem, uint32_t fAccess) RT_NOEXCEPT;
 void            iemMemRollback(PVMCPUCC pVCpu) RT_NOEXCEPT;
 VBOXSTRICTRC    iemMemApplySegment(PVMCPUCC pVCpu, uint32_t fAccess, uint8_t iSegReg, size_t cbMem, PRTGCPTR pGCPtrMem) RT_NOEXCEPT;
@@ -5110,6 +5111,6 @@
 uint64_t        iemMemFetchDataU64Jmp(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP;
 uint64_t        iemMemFetchDataU64AlignedU128Jmp(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP;
+void            iemMemFetchDataR80Jmp(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, PRTFLOAT80U pr80Dst) IEM_NOEXCEPT_MAY_LONGJMP;
 # endif
-void            iemMemFetchDataR80Jmp(PVMCPUCC pVCpu, PRTFLOAT80U pr80Dst, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP;
 void            iemMemFetchDataD80Jmp(PVMCPUCC pVCpu, PRTPBCD80U pd80Dst, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP;
 void            iemMemFetchDataU128Jmp(PVMCPUCC pVCpu, PRTUINT128U pu128Dst, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP;
@@ -5143,4 +5144,5 @@
 void            iemMemStoreDataU256SafeJmp(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, PCRTUINT256U pu256Value) IEM_NOEXCEPT_MAY_LONGJMP;
 void            iemMemStoreDataU256AlignedAvxSafeJmp(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, PCRTUINT256U pu256Value) IEM_NOEXCEPT_MAY_LONGJMP;
+void            iemMemStoreDataR80SafeJmp(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, PCRTFLOAT80U pr80Value) IEM_NOEXCEPT_MAY_LONGJMP;
 #if 0
 void            iemMemStoreDataU8Jmp(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, uint8_t u8Value) IEM_NOEXCEPT_MAY_LONGJMP;
@@ -5168,8 +5170,12 @@
 uint64_t       *iemMemMapDataU64WoSafeJmp(PVMCPUCC pVCpu, uint8_t *pbUnmapInfo, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP;
 uint64_t const *iemMemMapDataU64RoSafeJmp(PVMCPUCC pVCpu, uint8_t *pbUnmapInfo, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP;
+PRTFLOAT80U     iemMemMapDataR80RwSafeJmp(PVMCPUCC pVCpu, uint8_t *pbUnmapInfo, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP;
+PRTFLOAT80U     iemMemMapDataR80WoSafeJmp(PVMCPUCC pVCpu, uint8_t *pbUnmapInfo, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP;
+PCRTFLOAT80U    iemMemMapDataR80RoSafeJmp(PVMCPUCC pVCpu, uint8_t *pbUnmapInfo, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP;
 
 void            iemMemCommitAndUnmapRwSafeJmp(PVMCPUCC pVCpu, void *pvMem, uint8_t bMapInfo) IEM_NOEXCEPT_MAY_LONGJMP;
 void            iemMemCommitAndUnmapWoSafeJmp(PVMCPUCC pVCpu, void *pvMem, uint8_t bMapInfo) IEM_NOEXCEPT_MAY_LONGJMP;
 void            iemMemCommitAndUnmapRoSafeJmp(PVMCPUCC pVCpu, const void *pvMem, uint8_t bMapInfo) IEM_NOEXCEPT_MAY_LONGJMP;
+void            iemMemRollbackAndUnmapWoSafe(PVMCPUCC pVCpu, const void *pvMem, uint8_t bMapInfo) RT_NOEXCEPT;
 #endif
 
Index: trunk/src/VBox/VMM/include/IEMMc.h
===================================================================
--- trunk/src/VBox/VMM/include/IEMMc.h	(revision 102423)
+++ trunk/src/VBox/VMM/include/IEMMc.h	(revision 102424)
@@ -981,5 +981,5 @@
     ((a_r64Dst).u = iemMemFlatFetchDataU64Jmp(pVCpu, (a_GCPtrMem)))
 # define IEM_MC_FETCH_MEM_FLAT_R80(a_r80Dst, a_GCPtrMem) \
-    iemMemFetchDataR80Jmp(pVCpu, &(a_r80Dst), UINT8_MAX, (a_GCPtrMem))
+    iemMemFlatFetchDataR80Jmp(pVCpu, &(a_r80Dst), (a_GCPtrMem))
 # define IEM_MC_FETCH_MEM_FLAT_D80(a_d80Dst, a_GCPtrMem) \
     iemMemFetchDataD80Jmp(pVCpu, &(a_d80Dst), UINT8_MAX, (a_GCPtrMem))
@@ -1932,4 +1932,40 @@
 #endif
 
+/** int32_t alias. */
+#ifndef IEM_WITH_SETJMP
+# define IEM_MC_MEM_MAP_I32_WO(a_pi32Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem) \
+         IEM_MC_MEM_MAP_U32_WO(a_pi32Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem)
+#else
+# define IEM_MC_MEM_MAP_I32_WO(a_pi32Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem) \
+    (a_pi32Mem) = (int32_t *)iemMemMapDataU32WoJmp(pVCpu, &(a_bUnmapInfo), (a_iSeg), (a_GCPtrMem))
+#endif
+
+/** Flat int32_t alias. */
+#ifndef IEM_WITH_SETJMP
+# define IEM_MC_MEM_FLAT_MAP_I32_WO(a_pi32Mem, a_bUnmapInfo, a_GCPtrMem) \
+         IEM_MC_MEM_FLAT_MAP_U32_WO(a_pi32Mem, a_bUnmapInfo, a_GCPtrMem)
+#else
+# define IEM_MC_MEM_FLAT_MAP_I32_WO(a_pi32Mem, a_bUnmapInfo, a_GCPtrMem) \
+    (a_pi32Mem) = (int32_t *)iemMemFlatMapDataU32WoJmp(pVCpu, &(a_bUnmapInfo), (a_GCPtrMem))
+#endif
+
+/** RTFLOAT32U alias. */
+#ifndef IEM_WITH_SETJMP
+# define IEM_MC_MEM_MAP_R32_WO(a_pr32Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem) \
+         IEM_MC_MEM_MAP_U32_WO(a_pr32Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem)
+#else
+# define IEM_MC_MEM_MAP_R32_WO(a_pr32Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem) \
+    (a_pr32Mem) = (PRTFLOAT32U)iemMemMapDataU32WoJmp(pVCpu, &(a_bUnmapInfo), (a_iSeg), (a_GCPtrMem))
+#endif
+
+/** Flat RTFLOAT32U alias. */
+#ifndef IEM_WITH_SETJMP
+# define IEM_MC_MEM_FLAT_MAP_R32_WO(a_pr32Mem, a_bUnmapInfo, a_GCPtrMem) \
+         IEM_MC_MEM_FLAT_MAP_U32_WO(a_pr32Mem, a_bUnmapInfo, a_GCPtrMem)
+#else
+# define IEM_MC_MEM_FLAT_MAP_R32_WO(a_pr32Mem, a_bUnmapInfo, a_GCPtrMem) \
+    (a_pr32Mem) = (PRTFLOAT32U)iemMemFlatMapDataU32WoJmp(pVCpu, &(a_bUnmapInfo), (a_GCPtrMem))
+#endif
+
 
 /* 64-bit */
@@ -2062,4 +2098,48 @@
 
 
+/* misc */
+
+/**
+ * Maps guest memory for 80-bit float writeonly direct (or bounce) buffer acccess.
+ *
+ * @param[out] a_pr80Mem    Where to return the pointer to the mapping.
+ * @param[out] a_bUnmapInfo Where to return umapping instructions. uint8_t.
+ * @param[in]  a_iSeg       The segment register to access via. No UINT8_MAX!
+ * @param[in]  a_GCPtrMem   The memory address.
+ * @remarks Will return/long jump on errors.
+ * @see     IEM_MC_MEM_COMMIT_AND_UNMAP_WO
+ */
+#ifndef IEM_WITH_SETJMP
+# define IEM_MC_MEM_MAP_R80_WO(a_pr80Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem) do { \
+        IEM_MC_RETURN_ON_FAILURE(iemMemMap(pVCpu, (void **)&(a_pr80Mem), sizeof(RTFLOAT80U), (a_iSeg), \
+                                           (a_GCPtrMem), IEM_ACCESS_DATA_W, sizeof(uint64_t) - 1)); \
+        a_bUnmapInfo = 1 | (IEM_ACCESS_TYPE_WRITE << 4); \
+    } while (0)
+#else
+# define IEM_MC_MEM_MAP_R80_WO(a_pr80Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem) \
+    (a_pr80Mem) = iemMemMapDataR80WoJmp(pVCpu, &(a_bUnmapInfo), (a_iSeg), (a_GCPtrMem))
+#endif
+
+/**
+ * Maps guest memory for 80-bit float writeonly direct (or bounce) buffer acccess.
+ *
+ * @param[out] a_pr80Mem    Where to return the pointer to the mapping.
+ * @param[out] a_bUnmapInfo Where to return umapping instructions. uint8_t.
+ * @param[in]  a_GCPtrMem   The memory address.
+ * @remarks Will return/long jump on errors.
+ * @see     IEM_MC_MEM_COMMIT_AND_UNMAP_WO
+ */
+#ifndef IEM_WITH_SETJMP
+# define IEM_MC_MEM_FLAT_MAP_R80_WO(a_pr80Mem, a_bUnmapInfo, a_GCPtrMem) do { \
+        IEM_MC_RETURN_ON_FAILURE(iemMemMap(pVCpu, (void **)&(a_pr80Mem), sizeof(RTFLOAT80U), UINT8_MAX, \
+                                           (a_GCPtrMem), IEM_ACCESS_DATA_W, sizeof(uint64_t) - 1)); \
+        a_bUnmapInfo = 1 | (IEM_ACCESS_TYPE_WRITE << 4); \
+    } while (0)
+#else
+# define IEM_MC_MEM_FLAT_MAP_R80_WO(a_pr80Mem, a_bUnmapInfo, a_GCPtrMem) \
+    (a_pr80Mem) = iemMemFlatMapDataR80WoJmp(pVCpu, &(a_bUnmapInfo), (a_GCPtrMem))
+#endif
+
+
 /* commit + unmap */
 
@@ -2112,4 +2192,6 @@
  *
  * @remarks     May in theory return - for now.
+ *
+ * @deprecated
  */
 #define IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(a_pvMem, a_fAccess, a_u16FSW) \
@@ -2120,4 +2202,46 @@
             IEM_MC_RETURN_ON_FAILURE(iemMemCommitAndUnmap(pVCpu, (a_pvMem), (a_fAccess))); \
     } while (0)
+
+
+/** Commits the memory and unmaps the guest memory unless the FPU status word
+ * indicates (@a a_u16FSW) and FPU control word indicates a pending exception
+ * that would cause FLD not to store.
+ *
+ * The current understanding is that \#O, \#U, \#IA and \#IS will prevent a
+ * store, while \#P will not.
+ *
+ * @remarks     May in theory return - for now.
+ */
+#ifndef IEM_WITH_SETJMP
+# define IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(a_pvMem, a_bMapInfo, a_u16FSW) do { \
+        RT_NOREF_PV(a_bMapInfo); Assert(a_bMapInfo == (1 | (IEM_ACCESS_TYPE_WRITE << 4)) ); \
+        if (   !(a_u16FSW & X86_FSW_ES) \
+            || !(  (a_u16FSW & (X86_FSW_UE | X86_FSW_OE | X86_FSW_IE)) \
+                 & ~(pVCpu->cpum.GstCtx.XState.x87.FCW & X86_FCW_MASK_ALL) ) ) \
+            IEM_MC_RETURN_ON_FAILURE(iemMemCommitAndUnmap(pVCpu, (a_pvMem), IEM_ACCESS_DATA_W)); \
+        else \
+            iemMemRollbackAndUnmap(pVCpu, (a_pvMem), IEM_ACCESS_DATA_W); \
+    } while (0)
+#else
+# define IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(a_pvMem, a_bMapInfo, a_u16FSW) do { \
+        if (   !(a_u16FSW & X86_FSW_ES) \
+            || !(  (a_u16FSW & (X86_FSW_UE | X86_FSW_OE | X86_FSW_IE)) \
+                 & ~(pVCpu->cpum.GstCtx.XState.x87.FCW & X86_FCW_MASK_ALL) ) ) \
+            iemMemCommitAndUnmapWoJmp(pVCpu, (a_pvMem), a_bMapInfo); \
+        else \
+            iemMemRollbackAndUnmapWo(pVCpu, (a_pvMem), a_bMapInfo); \
+    } while (0)
+#endif
+
+/** Rolls back (conceptually only, assumes no writes) and unmaps the guest  memory. */
+#ifndef IEM_WITH_SETJMP
+# define IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(a_pvMem, a_bMapInfo) do { \
+        RT_NOREF_PV(a_bMapInfo); Assert(a_bMapInfo == (1 | (IEM_ACCESS_TYPE_WRITE << 4)) ); \
+        iemMemRollbackAndUnmap(pVCpu, (a_pvMem), IEM_ACCESS_DATA_W); \
+    } while (0)
+#else
+# define IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(a_pvMem, a_bMapInfo) \
+        iemMemRollbackAndUnmapWo(pVCpu, (a_pvMem), a_bMapInfo)
+#endif
 
 
Index: trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp
===================================================================
--- trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp	(revision 102423)
+++ trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp	(revision 102424)
@@ -939,11 +939,15 @@
 #define IEM_MC_MEM_MAP_U32_RO(a_pu32Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem) do { CHK_VAR(a_pu32Mem); (a_pu32Mem) = NULL; CHK_PTYPE(uint32_t const *, a_pu32Mem); CHK_VAR(a_bUnmapInfo); CHK_TYPE(uint8_t, a_bUnmapInfo); a_bUnmapInfo = 1; CHK_GCPTR(a_GCPtrMem); CHK_VAR(a_GCPtrMem); CHK_SEG_IDX(a_iSeg); (void)fMcBegin; } while (0)
 #define IEM_MC_MEM_MAP_U32_WO(a_pu32Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem) do { CHK_VAR(a_pu32Mem); (a_pu32Mem) = NULL; CHK_PTYPE(uint32_t *,       a_pu32Mem); CHK_VAR(a_bUnmapInfo); CHK_TYPE(uint8_t, a_bUnmapInfo); a_bUnmapInfo = 1; CHK_GCPTR(a_GCPtrMem); CHK_VAR(a_GCPtrMem); CHK_SEG_IDX(a_iSeg); (void)fMcBegin; } while (0)
+#define IEM_MC_MEM_MAP_I32_WO(a_pi32Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem) do { CHK_VAR(a_pi32Mem); (a_pi32Mem) = NULL; CHK_PTYPE(int32_t *,        a_pi32Mem); CHK_VAR(a_bUnmapInfo); CHK_TYPE(uint8_t, a_bUnmapInfo); a_bUnmapInfo = 1; CHK_GCPTR(a_GCPtrMem); CHK_VAR(a_GCPtrMem); CHK_SEG_IDX(a_iSeg); (void)fMcBegin; } while (0)
+#define IEM_MC_MEM_MAP_R32_WO(a_pr32Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem) do { CHK_VAR(a_pr32Mem); (a_pr32Mem) = NULL; CHK_PTYPE(RTFLOAT32U *,     a_pr32Mem); CHK_VAR(a_bUnmapInfo); CHK_TYPE(uint8_t, a_bUnmapInfo); a_bUnmapInfo = 1; CHK_GCPTR(a_GCPtrMem); CHK_VAR(a_GCPtrMem); CHK_SEG_IDX(a_iSeg); (void)fMcBegin; } while (0)
 #define IEM_MC_MEM_MAP_U64_RW(a_pu64Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem) do { CHK_VAR(a_pu64Mem); (a_pu64Mem) = NULL; CHK_PTYPE(uint64_t *,       a_pu64Mem); CHK_VAR(a_bUnmapInfo); CHK_TYPE(uint8_t, a_bUnmapInfo); a_bUnmapInfo = 1; CHK_GCPTR(a_GCPtrMem); CHK_VAR(a_GCPtrMem); CHK_SEG_IDX(a_iSeg); (void)fMcBegin; } while (0)
 #define IEM_MC_MEM_MAP_U64_RO(a_pu64Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem) do { CHK_VAR(a_pu64Mem); (a_pu64Mem) = NULL; CHK_PTYPE(uint64_t const *, a_pu64Mem); CHK_VAR(a_bUnmapInfo); CHK_TYPE(uint8_t, a_bUnmapInfo); a_bUnmapInfo = 1; CHK_GCPTR(a_GCPtrMem); CHK_VAR(a_GCPtrMem); CHK_SEG_IDX(a_iSeg); (void)fMcBegin; } while (0)
 #define IEM_MC_MEM_MAP_U64_WO(a_pu64Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem) do { CHK_VAR(a_pu64Mem); (a_pu64Mem) = NULL; CHK_PTYPE(uint64_t *,       a_pu64Mem); CHK_VAR(a_bUnmapInfo); CHK_TYPE(uint8_t, a_bUnmapInfo); a_bUnmapInfo = 1; CHK_GCPTR(a_GCPtrMem); CHK_VAR(a_GCPtrMem); CHK_SEG_IDX(a_iSeg); (void)fMcBegin; } while (0)
+#define IEM_MC_MEM_MAP_R80_WO(a_pr80Mem, a_bUnmapInfo, a_iSeg, a_GCPtrMem) do { CHK_VAR(a_pr80Mem); (a_pr80Mem) = NULL; CHK_PTYPE(RTFLOAT80U *,     a_pr80Mem); CHK_VAR(a_bUnmapInfo); CHK_TYPE(uint8_t, a_bUnmapInfo); a_bUnmapInfo = 1; CHK_GCPTR(a_GCPtrMem); CHK_VAR(a_GCPtrMem); CHK_SEG_IDX(a_iSeg); (void)fMcBegin; } while (0)
 
 #define IEM_MC_MEM_COMMIT_AND_UNMAP_RW(a_pvMem, a_bMapInfo)                do { CHK_VAR(a_pvMem); CHK_VAR(a_bMapInfo); CHK_TYPE(uint8_t, a_bMapInfo); (void)fMcBegin; } while (0)
 #define IEM_MC_MEM_COMMIT_AND_UNMAP_RO(a_pvMem, a_bMapInfo)                do { CHK_VAR(a_pvMem); CHK_VAR(a_bMapInfo); CHK_TYPE(uint8_t, a_bMapInfo); (void)fMcBegin; } while (0)
 #define IEM_MC_MEM_COMMIT_AND_UNMAP_WO(a_pvMem, a_bMapInfo)                do { CHK_VAR(a_pvMem); CHK_VAR(a_bMapInfo); CHK_TYPE(uint8_t, a_bMapInfo); (void)fMcBegin; } while (0)
+#define IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(a_pvMem, a_bMapInfo)              do { CHK_VAR(a_pvMem); CHK_VAR(a_bMapInfo); CHK_TYPE(uint8_t, a_bMapInfo); (void)fMcBegin; } while (0)
 
 #define IEM_MC_MEM_MAP(a_pMem, a_fAccess, a_iSeg, a_GCPtrMem, a_iArg)                          do { CHK_VAR(a_pMem);  CHK_VAR(a_GCPtrMem); CHK_SEG_IDX(a_iSeg); (void)fMcBegin; } while (0)
@@ -951,4 +955,5 @@
 #define IEM_MC_MEM_COMMIT_AND_UNMAP(a_pvMem, a_fAccess)                                        do { CHK_VAR(a_pvMem); (void)fMcBegin; } while (0)
 #define IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(a_pvMem, a_fAccess, a_u16FSW)                do { CHK_VAR(a_pvMem); (void)fMcBegin; } while (0)
+#define IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO(a_pvMem, a_bMapInfo, a_u16FSW)            do { CHK_VAR(a_pvMem); CHK_VAR(a_bMapInfo); CHK_VAR(a_u16FSW); (void)fMcBegin; } while (0)
 #define IEM_MC_CALC_RM_EFF_ADDR(a_GCPtrEff, a_bRm, a_cbImmAndRspOffset) do { (a_GCPtrEff) = 0; CHK_GCPTR(a_GCPtrEff); (void)fMcBegin; } while (0)
 #define IEM_MC_CALL_VOID_AIMPL_0(a_pfn)                                 do { (void)fMcBegin; } while (0)
