Index: /trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h	(revision 100849)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h	(revision 100850)
@@ -47,4 +47,8 @@
 #endif
 
+#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.
+#endif
+
 /** @todo fix logging   */
 
@@ -71,5 +75,6 @@
     RTGCPTR GCPtrEff = iemMemApplySegmentToReadJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY((GCPtrEff & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
+    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) ))
 #  endif
     {
@@ -90,28 +95,13 @@
                           == pVCpu->iem.s.DataTlb.uTlbPhysRev))
             {
-#  if TMPL_MEM_TYPE_ALIGN != 0
-                /*
-                 * Alignment check:
-                 */
-                /** @todo check priority \#AC vs \#PF */
-                AssertCompile(X86_CR0_AM == X86_EFL_AC);
-                AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
-                if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
-                              || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
-                                   & pVCpu->cpum.GstCtx.eflags.u
-                                   & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
-                                   & X86_CR0_AM) ))
-#  endif
-                {
-                    /*
-                     * Fetch and return the dword
-                     */
-                    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));
-                    TMPL_MEM_TYPE const uRet = *(TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
-                    Log9(("IEM RD " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, uRet));
-                    return uRet;
-                }
+                /*
+                 * Fetch and return the data.
+                 */
+                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));
+                TMPL_MEM_TYPE const uRet = *(TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
+                Log9(("IEM RD " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, uRet));
+                return uRet;
             }
         }
@@ -137,5 +127,8 @@
      */
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY((GCPtrMem & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
+    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) ))
 #  endif
     {
@@ -156,28 +149,13 @@
                           == pVCpu->iem.s.DataTlb.uTlbPhysRev))
             {
-#  if TMPL_MEM_TYPE_ALIGN != 0
-                /*
-                 * Alignment check:
-                 */
-                /** @todo check priority \#AC vs \#PF */
-                AssertCompile(X86_CR0_AM == X86_EFL_AC);
-                AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
-                if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
-                              || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
-                                   & pVCpu->cpum.GstCtx.eflags.u
-                                   & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
-                                   & X86_CR0_AM) ))
-#  endif
-                {
-                    /*
-                     * Fetch and return the dword
-                     */
-                    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));
-                    TMPL_MEM_TYPE const uRet = *(TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
-                    Log9(("IEM RD " TMPL_MEM_FMT_DESC " %RGv: " TMPL_MEM_FMT_TYPE "\n", GCPtrMem, uRet));
-                    return uRet;
-                }
+                /*
+                 * Fetch and return the dword
+                 */
+                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));
+                TMPL_MEM_TYPE const uRet = *(TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
+                Log9(("IEM RD " TMPL_MEM_FMT_DESC " %RGv: " TMPL_MEM_FMT_TYPE "\n", GCPtrMem, uRet));
+                return uRet;
             }
         }
@@ -212,5 +190,8 @@
     RTGCPTR GCPtrEff = iemMemApplySegmentToWriteJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY((GCPtrEff & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
+    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) ))
 #  endif
     {
@@ -232,28 +213,13 @@
                           == pVCpu->iem.s.DataTlb.uTlbPhysRev))
             {
-#   if TMPL_MEM_TYPE_ALIGN != 0
-                /*
-                 * Alignment check:
-                 */
-                /** @todo check priority \#AC vs \#PF */
-                AssertCompile(X86_CR0_AM == X86_EFL_AC);
-                AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
-                if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
-                              || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
-                                   & pVCpu->cpum.GstCtx.eflags.u
-                                   & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
-                              & X86_CR0_AM) ))
-#   endif
-                {
-                    /*
-                     * 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));
-                    *(TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK] = uValue;
-                    Log9(("IEM WR " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, uValue));
-                    return;
-                }
+                /*
+                 * 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));
+                *(TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK] = uValue;
+                Log9(("IEM WR " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, uValue));
+                return;
             }
         }
@@ -280,5 +246,6 @@
      */
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY((GCPtrMem & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
+    if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
+                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrMem, TMPL_MEM_TYPE) ))
 #  endif
     {
@@ -300,28 +267,13 @@
                           == pVCpu->iem.s.DataTlb.uTlbPhysRev))
             {
-#   if TMPL_MEM_TYPE_ALIGN != 0
-                /*
-                 * Alignment check:
-                 */
-                /** @todo check priority \#AC vs \#PF */
-                AssertCompile(X86_CR0_AM == X86_EFL_AC);
-                AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
-                if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
-                              || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
-                                   & pVCpu->cpum.GstCtx.eflags.u
-                                   & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
-                                   & X86_CR0_AM) ))
-#   endif
-                {
-                    /*
-                     * 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));
-                    *(TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK] = uValue;
-                    Log9(("IEM WR " TMPL_MEM_FMT_DESC " %RGv: " TMPL_MEM_FMT_TYPE "\n", GCPtrMem, uValue));
-                    return;
-                }
+                /*
+                 * 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));
+                *(TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK] = uValue;
+                Log9(("IEM WR " TMPL_MEM_FMT_DESC " %RGv: " TMPL_MEM_FMT_TYPE "\n", GCPtrMem, uValue));
+                return;
             }
         }
@@ -356,5 +308,6 @@
     RTGCPTR GCPtrEff = iemMemApplySegmentToWriteJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY((GCPtrEff & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
+    if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
+                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ))
 #  endif
     {
@@ -377,29 +330,14 @@
                           == pVCpu->iem.s.DataTlb.uTlbPhysRev))
             {
-#   if TMPL_MEM_TYPE_ALIGN != 0
-                /*
-                 * Alignment check:
-                 */
-                /** @todo check priority \#AC vs \#PF */
-                AssertCompile(X86_CR0_AM == X86_EFL_AC);
-                AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
-                if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
-                              || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
-                                   & pVCpu->cpum.GstCtx.eflags.u
-                                   & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
-                                   & X86_CR0_AM) ))
-#   endif
-                {
-                    /*
-                     * Return the address.
-                     */
-                    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));
-                    *pbUnmapInfo = 0;
-                    Log8(("IEM RW/map " TMPL_MEM_FMT_DESC " %d|%RGv: %p\n",
-                          iSegReg, GCPtrMem, &pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK]));
-                    return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
-                }
+                /*
+                 * Return the address.
+                 */
+                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));
+                *pbUnmapInfo = 0;
+                Log8(("IEM RW/map " TMPL_MEM_FMT_DESC " %d|%RGv: %p\n",
+                      iSegReg, GCPtrMem, &pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK]));
+                return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
             }
         }
@@ -426,5 +364,6 @@
      */
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY((GCPtrMem & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
+    if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
+                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrMem, TMPL_MEM_TYPE) ))
 #  endif
     {
@@ -447,29 +386,14 @@
                           == pVCpu->iem.s.DataTlb.uTlbPhysRev))
             {
-#   if TMPL_MEM_TYPE_ALIGN != 0
-                /*
-                 * Alignment check:
-                 */
-                /** @todo check priority \#AC vs \#PF */
-                AssertCompile(X86_CR0_AM == X86_EFL_AC);
-                AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
-                if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
-                              || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
-                                   & pVCpu->cpum.GstCtx.eflags.u
-                                   & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
-                                   & X86_CR0_AM) ))
-#   endif
-                {
-                    /*
-                     * Return the address.
-                     */
-                    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));
-                    *pbUnmapInfo = 0;
-                    Log8(("IEM RW/map " TMPL_MEM_FMT_DESC " %RGv: %p\n",
-                          GCPtrMem, &pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK]));
-                    return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
-                }
+                /*
+                 * Return the address.
+                 */
+                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));
+                *pbUnmapInfo = 0;
+                Log8(("IEM RW/map " TMPL_MEM_FMT_DESC " %RGv: %p\n",
+                      GCPtrMem, &pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK]));
+                return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
             }
         }
@@ -497,5 +421,6 @@
     RTGCPTR GCPtrEff = iemMemApplySegmentToWriteJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY((GCPtrEff & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
+    if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
+                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ))
 #  endif
     {
@@ -518,29 +443,14 @@
                           == pVCpu->iem.s.DataTlb.uTlbPhysRev))
             {
-#   if TMPL_MEM_TYPE_ALIGN != 0
-                /*
-                 * Alignment check:
-                 */
-                /** @todo check priority \#AC vs \#PF */
-                AssertCompile(X86_CR0_AM == X86_EFL_AC);
-                AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
-                if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
-                              || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
-                                   & pVCpu->cpum.GstCtx.eflags.u
-                                   & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
-                                   & X86_CR0_AM) ))
-#   endif
-                {
-                    /*
-                     * Return the address.
-                     */
-                    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));
-                    *pbUnmapInfo = 0;
-                    Log8(("IEM WO/map " TMPL_MEM_FMT_DESC " %d|%RGv: %p\n",
-                          iSegReg, GCPtrMem, &pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK]));
-                    return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
-                }
+                /*
+                 * Return the address.
+                 */
+                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));
+                *pbUnmapInfo = 0;
+                Log8(("IEM WO/map " TMPL_MEM_FMT_DESC " %d|%RGv: %p\n",
+                      iSegReg, GCPtrMem, &pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK]));
+                return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
             }
         }
@@ -567,5 +477,6 @@
      */
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY((GCPtrMem & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
+    if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
+                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrMem, TMPL_MEM_TYPE) ))
 #  endif
     {
@@ -588,29 +499,14 @@
                           == pVCpu->iem.s.DataTlb.uTlbPhysRev))
             {
-#   if TMPL_MEM_TYPE_ALIGN != 0
-                /*
-                 * Alignment check:
-                 */
-                /** @todo check priority \#AC vs \#PF */
-                AssertCompile(X86_CR0_AM == X86_EFL_AC);
-                AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
-                if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
-                              || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
-                                   & pVCpu->cpum.GstCtx.eflags.u
-                                   & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
-                                   & X86_CR0_AM) ))
-#   endif
-                {
-                    /*
-                     * Return the address.
-                     */
-                    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));
-                    *pbUnmapInfo = 0;
-                    Log8(("IEM WO/map " TMPL_MEM_FMT_DESC " %RGv: %p\n",
-                          GCPtrMem, &pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK]));
-                    return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
-                }
+                /*
+                 * Return the address.
+                 */
+                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));
+                *pbUnmapInfo = 0;
+                Log8(("IEM WO/map " TMPL_MEM_FMT_DESC " %RGv: %p\n",
+                      GCPtrMem, &pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK]));
+                return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
             }
         }
@@ -638,5 +534,6 @@
     RTGCPTR GCPtrEff = iemMemApplySegmentToReadJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY((GCPtrEff & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
+    if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
+                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ))
 #  endif
     {
@@ -658,29 +555,14 @@
                           == pVCpu->iem.s.DataTlb.uTlbPhysRev))
             {
-#   if TMPL_MEM_TYPE_ALIGN != 0
-                /*
-                 * Alignment check:
-                 */
-                /** @todo check priority \#AC vs \#PF */
-                AssertCompile(X86_CR0_AM == X86_EFL_AC);
-                AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
-                if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
-                              || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
-                                   & pVCpu->cpum.GstCtx.eflags.u
-                                   & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
-                                   & X86_CR0_AM) ))
-#   endif
-                {
-                    /*
-                     * Return the address.
-                     */
-                    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));
-                    *pbUnmapInfo = 0;
-                    Log9(("IEM RO/map " TMPL_MEM_FMT_DESC " %d|%RGv: %p\n",
-                          iSegReg, GCPtrMem, &pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK]));
-                    return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
-                }
+                /*
+                 * Return the address.
+                 */
+                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));
+                *pbUnmapInfo = 0;
+                Log9(("IEM RO/map " TMPL_MEM_FMT_DESC " %d|%RGv: %p\n",
+                      iSegReg, GCPtrMem, &pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK]));
+                return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
             }
         }
@@ -707,5 +589,6 @@
      */
 #  if TMPL_MEM_TYPE_SIZE > 1
-    if (RT_LIKELY((GCPtrMem & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
+    if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
+                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrMem, TMPL_MEM_TYPE) ))
 #  endif
     {
@@ -727,29 +610,14 @@
                           == pVCpu->iem.s.DataTlb.uTlbPhysRev))
             {
-#   if TMPL_MEM_TYPE_ALIGN != 0
-                /*
-                 * Alignment check:
-                 */
-                /** @todo check priority \#AC vs \#PF */
-                AssertCompile(X86_CR0_AM == X86_EFL_AC);
-                AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
-                if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
-                              || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
-                                   & pVCpu->cpum.GstCtx.eflags.u
-                                   & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
-                                   & X86_CR0_AM) ))
-#   endif
-                {
-                    /*
-                     * Return the address.
-                     */
-                    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));
-                    *pbUnmapInfo = 0;
-                    Log8(("IEM RO/map " TMPL_MEM_FMT_DESC " %RGv: %p\n",
-                          GCPtrMem, &pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK]));
-                    return (TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
-                }
+                /*
+                 * Return the address.
+                 */
+                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));
+                *pbUnmapInfo = 0;
+                Log8(("IEM RO/map " TMPL_MEM_FMT_DESC " %RGv: %p\n",
+                      GCPtrMem, &pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK]));
+                return (TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
             }
         }
Index: /trunk/src/VBox/VMM/include/IEMInline.h
===================================================================
--- /trunk/src/VBox/VMM/include/IEMInline.h	(revision 100849)
+++ /trunk/src/VBox/VMM/include/IEMInline.h	(revision 100850)
@@ -3454,4 +3454,26 @@
  * Instantiate R/W inline templates.
  */
+
+/** @def TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK
+ * Used to check if an unaligned access is if within the page and won't
+ * trigger an #AC.
+ *
+ * This can be used to deal with misaligned accesses on platforms that are
+ * senstive to such if desires.
+ */
+AssertCompile(X86_CR0_AM == X86_EFL_AC);
+AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
+#if 1
+# define TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(a_pVCpu, a_GCPtrEff, a_TmplMemType) \
+    (   ((a_GCPtrEff) & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(a_TmplMemType) \
+     && !(  (uint32_t)(a_pVCpu)->cpum.GstCtx.cr0 \
+          & (a_pVCpu)->cpum.GstCtx.eflags.u \
+          & ((IEM_GET_CPL((a_pVCpu)) + 1U) << 16) /* IEM_GET_CPL(a_pVCpu) == 3 ? X86_CR0_AM : 0 */ \
+          & X86_CR0_AM) )
+#else
+# define TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(a_pVCpu, a_GCPtrEff, a_TmplMemType) 0
+#endif
+
+
 #define TMPL_MEM_TYPE       uint8_t
 #define TMPL_MEM_TYPE_ALIGN 0
@@ -3496,4 +3518,5 @@
 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
 
+#undef TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK
 /** @} */
 
