Index: trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmpl.cpp.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmpl.cpp.h	(revision 100821)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmpl.cpp.h	(revision 100822)
@@ -75,4 +75,7 @@
 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)
+    pVCpu->iem.s.DataTlb.cTlbSafeReadPath++;
+# endif
     TMPL_MEM_TYPE const *puSrc = (TMPL_MEM_TYPE const *)iemMemMapJmp(pVCpu, sizeof(*puSrc), iSegReg, GCPtrMem,
                                                                      IEM_ACCESS_DATA_R, TMPL_MEM_TYPE_ALIGN);
@@ -121,4 +124,7 @@
                                                           TMPL_MEM_TYPE uValue) IEM_NOEXCEPT_MAY_LONGJMP
 {
+# if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
+    pVCpu->iem.s.DataTlb.cTlbSafeWritePath++;
+# endif
     Log8(("IEM WR " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, uValue));
     TMPL_MEM_TYPE *puDst = (TMPL_MEM_TYPE *)iemMemMapJmp(pVCpu, sizeof(*puDst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W, 0);
Index: trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h	(revision 100821)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h	(revision 100822)
@@ -31,6 +31,9 @@
 # error "TMPL_MEM_TYPE is undefined"
 #endif
+#ifndef TMPL_MEM_TYPE_SIZE
+# error "TMPL_MEM_TYPE_SIZE is undefined"
+#endif
 #ifndef TMPL_MEM_TYPE_ALIGN
-# define TMPL_MEM_TYPE_ALIGN     (sizeof(TMPL_MEM_TYPE) - 1)
+# error "TMPL_MEM_TYPE_ALIGN is undefined"
 #endif
 #ifndef TMPL_MEM_FN_SUFF
@@ -56,4 +59,5 @@
 RT_CONCAT3(iemMemFetchData,TMPL_MEM_FN_SUFF,Jmp)(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
 {
+    AssertCompile(sizeof(TMPL_MEM_TYPE) == TMPL_MEM_TYPE_SIZE);
 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3) && !defined(TMPL_MEM_NO_INLINE)
     /*
@@ -61,5 +65,7 @@
      */
     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)))
+#  endif
     {
         /*
@@ -81,4 +87,5 @@
                 STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
 
+#  if TMPL_MEM_TYPE_ALIGN != 0
                 /*
                  * Alignment check:
@@ -86,7 +93,11 @@
                 /** @todo check priority \#AC vs \#PF */
                 AssertCompile(X86_CR0_AM == X86_EFL_AC);
+                AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
                 if (   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
-                    || !((uint32_t)pVCpu->cpum.GstCtx.cr0 & pVCpu->cpum.GstCtx.eflags.u & X86_CR0_AM)
-                    || IEM_GET_CPL(pVCpu) != 3)
+                    || !(  (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
                 {
                     /*
@@ -99,6 +110,8 @@
                     return uRet;
                 }
+#  if TMPL_MEM_TYPE_ALIGN != 0
                 Log10Func(("Raising #AC for %RGv\n", GCPtrEff));
                 iemRaiseAlignmentCheckExceptionJmp(pVCpu);
+#  endif
             }
         }
@@ -123,5 +136,7 @@
      * Check that it doesn't cross a page boundrary.
      */
+#  if TMPL_MEM_TYPE_SIZE > 1
     if (RT_LIKELY((GCPtrMem & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
+#  endif
     {
         /*
@@ -143,4 +158,5 @@
                 STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
 
+#  if TMPL_MEM_TYPE_ALIGN != 0
                 /*
                  * Alignment check:
@@ -148,7 +164,11 @@
                 /** @todo check priority \#AC vs \#PF */
                 AssertCompile(X86_CR0_AM == X86_EFL_AC);
+                AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
                 if (   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
-                    || !((uint32_t)pVCpu->cpum.GstCtx.cr0 & pVCpu->cpum.GstCtx.eflags.u & X86_CR0_AM)
-                    || IEM_GET_CPL(pVCpu) != 3)
+                    || !(  (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
                 {
                     /*
@@ -161,6 +181,8 @@
                     return uRet;
                 }
+#  if TMPL_MEM_TYPE_ALIGN != 0
                 Log10Func(("Raising #AC for %RGv\n", GCPtrMem));
                 iemRaiseAlignmentCheckExceptionJmp(pVCpu);
+#  endif
             }
         }
@@ -190,5 +212,7 @@
      */
     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)))
+#  endif
     {
         /*
@@ -211,4 +235,5 @@
                 STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
 
+#   if TMPL_MEM_TYPE_ALIGN != 0
                 /*
                  * Alignment check:
@@ -216,7 +241,11 @@
                 /** @todo check priority \#AC vs \#PF */
                 AssertCompile(X86_CR0_AM == X86_EFL_AC);
+                AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
                 if (   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
-                    || !((uint32_t)pVCpu->cpum.GstCtx.cr0 & pVCpu->cpum.GstCtx.eflags.u & X86_CR0_AM)
-                    || IEM_GET_CPL(pVCpu) != 3)
+                    || !(  (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
                 {
                     /*
@@ -229,6 +258,8 @@
                     return;
                 }
+#   if TMPL_MEM_TYPE_ALIGN != 0
                 Log10Func(("Raising #AC for %RGv\n", GCPtrEff));
                 iemRaiseAlignmentCheckExceptionJmp(pVCpu);
+#   endif
             }
         }
@@ -254,5 +285,7 @@
      * Check that it doesn't cross a page boundrary.
      */
+#  if TMPL_MEM_TYPE_SIZE > 1
     if (RT_LIKELY((GCPtrMem & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
+#  endif
     {
         /*
@@ -275,4 +308,5 @@
                 STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
 
+#   if TMPL_MEM_TYPE_ALIGN != 0
                 /*
                  * Alignment check:
@@ -280,7 +314,11 @@
                 /** @todo check priority \#AC vs \#PF */
                 AssertCompile(X86_CR0_AM == X86_EFL_AC);
+                AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
                 if (   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
-                    || !((uint32_t)pVCpu->cpum.GstCtx.cr0 & pVCpu->cpum.GstCtx.eflags.u & X86_CR0_AM)
-                    || IEM_GET_CPL(pVCpu) != 3)
+                    || !(  (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
                 {
                     /*
@@ -293,6 +331,8 @@
                     return;
                 }
+#   if TMPL_MEM_TYPE_ALIGN != 0
                 Log10Func(("Raising #AC for %RGv\n", GCPtrMem));
                 iemRaiseAlignmentCheckExceptionJmp(pVCpu);
+#   endif
             }
         }
@@ -312,6 +352,8 @@
 #undef TMPL_MEM_TYPE
 #undef TMPL_MEM_TYPE_ALIGN
+#undef TMPL_MEM_TYPE_SIZE
 #undef TMPL_MEM_FN_SUFF
 #undef TMPL_MEM_FMT_TYPE
 #undef TMPL_MEM_FMT_DESC
-
+#undef TMPL_MEM_NO_STORE
+
