Index: trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 36828)
+++ trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 36829)
@@ -45,6 +45,4 @@
 *   Header Files                                                               *
 *******************************************************************************/
-//#define RT_STRICT
-//#define LOG_ENABLED
 #define LOG_GROUP   LOG_GROUP_EM /** @todo add log group */
 #include <VBox/vmm/iem.h>
@@ -192,5 +190,5 @@
 /** Temporary hack to disable the double execution.  Will be removed in favor
  * of a dedicated execution mode in EM. */
-#define IEM_VERIFICATION_MODE_NO_REM
+//#define IEM_VERIFICATION_MODE_NO_REM
 
 /** Used to shut up GCC warnings about variables that 'may be used uninitialized'
@@ -516,5 +514,5 @@
 static VBOXSTRICTRC     iemRaiseSelectorNotPresent(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
 static VBOXSTRICTRC     iemRaisePageFault(PIEMCPU pIemCpu, RTGCPTR GCPtrWhere, uint32_t fAccess, int rc);
-#if defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_NO_REM)
+#ifdef IEM_VERIFICATION_MODE
 static PIEMVERIFYEVTREC iemVerifyAllocRecord(PIEMCPU pIemCpu);
 static VBOXSTRICTRC     iemVerifyFakeIOPortRead(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue);
@@ -1333,4 +1331,15 @@
     typedef int ignore_semicolon
 
+/** Stubs an opcode. */
+#define FNIEMOP_STUB_1(a_Name, a_Type0, a_Name0) \
+    FNIEMOP_DEF_1(a_Name, a_Type0, a_Name0) \
+    { \
+        RTAssertMsg1(NULL, __LINE__, __FILE__, __FUNCTION__); \
+        iemOpStubMsg2(pIemCpu); \
+        RTAssertPanic(); \
+        return VERR_NOT_IMPLEMENTED; \
+    } \
+    typedef int ignore_semicolon
+
 
 
@@ -2167,7 +2176,7 @@
 static int iemMemPageMap(PIEMCPU pIemCpu, RTGCPHYS GCPhysMem, uint32_t fAccess, void **ppvMem)
 {
-#if defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_NO_REM)
+#ifdef IEM_VERIFICATION_MODE
     /* Force the alternative path so we can ignore writes. */
-    if (fAccess & IEM_ACCESS_TYPE_WRITE)
+    if ((fAccess & IEM_ACCESS_TYPE_WRITE) && !pIemCpu->fNoRem)
         return VERR_PGM_PHYS_TLB_CATCH_ALL;
 #endif
@@ -2251,6 +2260,5 @@
      */
     int rc;
-#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM) /* No memory changes in verification mode. */
-    if (!pIemCpu->aMemBbMappings[iMemMap].fUnassigned)
+    if (!pIemCpu->aMemBbMappings[iMemMap].fUnassigned && IEM_VERIFICATION_ENABLED(pIemCpu))
     {
         uint16_t const  cbFirst  = pIemCpu->aMemBbMappings[iMemMap].cbFirst;
@@ -2283,34 +2291,36 @@
     }
     else
-#endif
         rc = VINF_SUCCESS;
 
-#if defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_NO_REM)
+#ifdef IEM_VERIFICATION_MODE
     /*
      * Record the write(s).
      */
-    PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
-    if (pEvtRec)
-    {
-        pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_WRITE;
-        pEvtRec->u.RamWrite.GCPhys  = pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst;
-        pEvtRec->u.RamWrite.cb      = pIemCpu->aMemBbMappings[iMemMap].cbFirst;
-        memcpy(pEvtRec->u.RamWrite.ab, &pIemCpu->aBounceBuffers[iMemMap].ab[0], pIemCpu->aMemBbMappings[iMemMap].cbFirst);
-        pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
-        *pIemCpu->ppIemEvtRecNext = pEvtRec;
-    }
-    if (pIemCpu->aMemBbMappings[iMemMap].cbSecond)
-    {
-        pEvtRec = iemVerifyAllocRecord(pIemCpu);
+    if (!pIemCpu->fNoRem)
+    {
+        PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
         if (pEvtRec)
         {
             pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_WRITE;
-            pEvtRec->u.RamWrite.GCPhys  = pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond;
-            pEvtRec->u.RamWrite.cb      = pIemCpu->aMemBbMappings[iMemMap].cbSecond;
-            memcpy(pEvtRec->u.RamWrite.ab,
-                   &pIemCpu->aBounceBuffers[iMemMap].ab[pIemCpu->aMemBbMappings[iMemMap].cbFirst],
-                   pIemCpu->aMemBbMappings[iMemMap].cbSecond);
+            pEvtRec->u.RamWrite.GCPhys  = pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst;
+            pEvtRec->u.RamWrite.cb      = pIemCpu->aMemBbMappings[iMemMap].cbFirst;
+            memcpy(pEvtRec->u.RamWrite.ab, &pIemCpu->aBounceBuffers[iMemMap].ab[0], pIemCpu->aMemBbMappings[iMemMap].cbFirst);
             pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
             *pIemCpu->ppIemEvtRecNext = pEvtRec;
+        }
+        if (pIemCpu->aMemBbMappings[iMemMap].cbSecond)
+        {
+            pEvtRec = iemVerifyAllocRecord(pIemCpu);
+            if (pEvtRec)
+            {
+                pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_WRITE;
+                pEvtRec->u.RamWrite.GCPhys  = pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond;
+                pEvtRec->u.RamWrite.cb      = pIemCpu->aMemBbMappings[iMemMap].cbSecond;
+                memcpy(pEvtRec->u.RamWrite.ab,
+                       &pIemCpu->aBounceBuffers[iMemMap].ab[pIemCpu->aMemBbMappings[iMemMap].cbFirst],
+                       pIemCpu->aMemBbMappings[iMemMap].cbSecond);
+                pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
+                *pIemCpu->ppIemEvtRecNext = pEvtRec;
+            }
         }
     }
@@ -2376,25 +2386,28 @@
         }
 
-#if defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_NO_REM)
-        /*
-         * Record the reads.
-         */
-        PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
-        if (pEvtRec)
-        {
-            pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_READ;
-            pEvtRec->u.RamRead.GCPhys  = GCPhysFirst;
-            pEvtRec->u.RamRead.cb      = cbFirstPage;
-            pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
-            *pIemCpu->ppIemEvtRecNext = pEvtRec;
-        }
-        pEvtRec = iemVerifyAllocRecord(pIemCpu);
-        if (pEvtRec)
-        {
-            pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_READ;
-            pEvtRec->u.RamRead.GCPhys  = GCPhysSecond;
-            pEvtRec->u.RamRead.cb      = cbSecondPage;
-            pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
-            *pIemCpu->ppIemEvtRecNext = pEvtRec;
+#ifdef IEM_VERIFICATION_MODE
+        if (!pIemCpu->fNoRem)
+        {
+            /*
+             * Record the reads.
+             */
+            PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
+            if (pEvtRec)
+            {
+                pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_READ;
+                pEvtRec->u.RamRead.GCPhys  = GCPhysFirst;
+                pEvtRec->u.RamRead.cb      = cbFirstPage;
+                pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
+                *pIemCpu->ppIemEvtRecNext = pEvtRec;
+            }
+            pEvtRec = iemVerifyAllocRecord(pIemCpu);
+            if (pEvtRec)
+            {
+                pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_READ;
+                pEvtRec->u.RamRead.GCPhys  = GCPhysSecond;
+                pEvtRec->u.RamRead.cb      = cbSecondPage;
+                pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
+                *pIemCpu->ppIemEvtRecNext = pEvtRec;
+            }
         }
 #endif
@@ -2463,16 +2476,19 @@
         }
 
-#if defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_NO_REM)
-        /*
-         * Record the read.
-         */
-        PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
-        if (pEvtRec)
-        {
-            pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_READ;
-            pEvtRec->u.RamRead.GCPhys  = GCPhysFirst;
-            pEvtRec->u.RamRead.cb      = cbMem;
-            pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
-            *pIemCpu->ppIemEvtRecNext = pEvtRec;
+#ifdef IEM_VERIFICATION_MODE
+        if (!pIemCpu->fNoRem)
+        {
+            /*
+             * Record the read.
+             */
+            PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
+            if (pEvtRec)
+            {
+                pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_READ;
+                pEvtRec->u.RamRead.GCPhys  = GCPhysFirst;
+                pEvtRec->u.RamRead.cb      = cbMem;
+                pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
+                *pIemCpu->ppIemEvtRecNext = pEvtRec;
+            }
         }
 #endif
@@ -4988,11 +5004,12 @@
     if (rcStrict == VINF_SUCCESS)
     {
-#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-        rcStrict = CPUMSetGuestGDTR(IEMCPU_TO_VMCPU(pIemCpu), GCPtrBase, cbLimit);
-#else
-        PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
-        pCtx->gdtr.cbGdt = cbLimit;
-        pCtx->gdtr.pGdt  = GCPtrBase;
-#endif
+        if (IEM_VERIFICATION_ENABLED(pIemCpu))
+            rcStrict = CPUMSetGuestGDTR(IEMCPU_TO_VMCPU(pIemCpu), GCPtrBase, cbLimit);
+        else
+        {
+            PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+            pCtx->gdtr.cbGdt = cbLimit;
+            pCtx->gdtr.pGdt  = GCPtrBase;
+        }
         if (rcStrict == VINF_SUCCESS)
             iemRegAddToRip(pIemCpu, cbInstr);
@@ -5023,11 +5040,12 @@
     if (rcStrict == VINF_SUCCESS)
     {
-#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-        rcStrict = CPUMSetGuestIDTR(IEMCPU_TO_VMCPU(pIemCpu), GCPtrBase, cbLimit);
-#else
-        PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
-        pCtx->idtr.cbIdt = cbLimit;
-        pCtx->idtr.pIdt  = GCPtrBase;
-#endif
+        if (IEM_VERIFICATION_ENABLED(pIemCpu))
+            rcStrict = CPUMSetGuestIDTR(IEMCPU_TO_VMCPU(pIemCpu), GCPtrBase, cbLimit);
+        else
+        {
+            PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+            pCtx->idtr.cbIdt = cbLimit;
+            pCtx->idtr.pIdt  = GCPtrBase;
+        }
         if (rcStrict == VINF_SUCCESS)
             iemRegAddToRip(pIemCpu, cbInstr);
@@ -5059,9 +5077,8 @@
         case 4: crX = pCtx->cr4; break;
         case 8:
-#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-            AssertFailedReturn(VERR_NOT_IMPLEMENTED); /** @todo implement CR8 reading and writing. */
-#else
-            crX = 0xff;
-#endif
+            if (IEM_VERIFICATION_ENABLED(pIemCpu))
+                AssertFailedReturn(VERR_NOT_IMPLEMENTED); /** @todo implement CR8 reading and writing. */
+            else
+                crX = 0xff;
             break;
         IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* call checks */
@@ -5166,10 +5183,11 @@
              * Change CR0.
              */
-#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-            rc = CPUMSetGuestCR0(pVCpu, NewCrX);
-            AssertRCSuccessReturn(rc, RT_FAILURE_NP(rc) ? rc : VERR_INTERNAL_ERROR_3);
-#else
-            pCtx->cr0 = NewCrX;
-#endif
+            if (IEM_VERIFICATION_ENABLED(pIemCpu))
+            {
+                rc = CPUMSetGuestCR0(pVCpu, NewCrX);
+                AssertRCSuccessReturn(rc, RT_FAILURE_NP(rc) ? rc : VERR_INTERNAL_ERROR_3);
+            }
+            else
+                pCtx->cr0 = NewCrX;
             Assert(pCtx->cr0 == NewCrX);
 
@@ -5186,28 +5204,28 @@
                     NewEFER &= ~MSR_K6_EFER_LME;
 
-#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-                CPUMSetGuestEFER(pVCpu, NewEFER);
-#else
-                pCtx->msrEFER = NewEFER;
-#endif
+                if (IEM_VERIFICATION_ENABLED(pIemCpu))
+                    CPUMSetGuestEFER(pVCpu, NewEFER);
+                else
+                    pCtx->msrEFER = NewEFER;
                 Assert(pCtx->msrEFER == NewEFER);
             }
 
-#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
             /*
              * Inform PGM.
              */
-            if (    (NewCrX & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE))
-                !=  (OldCrX & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE)) )
+            if (IEM_VERIFICATION_ENABLED(pIemCpu))
             {
-                rc = PGMFlushTLB(pVCpu, pCtx->cr3, true /* global */);
-                AssertRCReturn(rc, rc);
-                /* ignore informational status codes */
+                if (    (NewCrX & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE))
+                    !=  (OldCrX & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE)) )
+                {
+                    rc = PGMFlushTLB(pVCpu, pCtx->cr3, true /* global */);
+                    AssertRCReturn(rc, rc);
+                    /* ignore informational status codes */
+                }
+                rcStrict = PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER);
+                /** @todo Status code management.  */
             }
-            rcStrict = PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER);
-            /** @todo Status code management.  */
-#else
-            rcStrict = VINF_SUCCESS;
-#endif
+            else
+                rcStrict = VINF_SUCCESS;
             break;
         }
@@ -5256,21 +5274,23 @@
 
             /* Make the change. */
-#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-            rc = CPUMSetGuestCR3(pVCpu, NewCrX);
-            AssertRCSuccessReturn(rc, rc);
-#else
-            pCtx->cr3 = NewCrX;
-#endif
-
-#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
+            if (IEM_VERIFICATION_ENABLED(pIemCpu))
+            {
+                rc = CPUMSetGuestCR3(pVCpu, NewCrX);
+                AssertRCSuccessReturn(rc, rc);
+            }
+            else
+                pCtx->cr3 = NewCrX;
+
             /* Inform PGM. */
-            if (pCtx->cr0 & X86_CR0_PG)
+            if (IEM_VERIFICATION_ENABLED(pIemCpu))
             {
-                rc = PGMFlushTLB(pVCpu, pCtx->cr3, !(pCtx->cr3 & X86_CR4_PGE));
-                AssertRCReturn(rc, rc);
-                /* ignore informational status codes */
-                /** @todo status code management */
+                if (pCtx->cr0 & X86_CR0_PG)
+                {
+                    rc = PGMFlushTLB(pVCpu, pCtx->cr3, !(pCtx->cr3 & X86_CR4_PGE));
+                    AssertRCReturn(rc, rc);
+                    /* ignore informational status codes */
+                    /** @todo status code management */
+                }
             }
-#endif
             rcStrict = VINF_SUCCESS;
             break;
@@ -5315,10 +5335,11 @@
              * Change it.
              */
-#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-            rc = CPUMSetGuestCR4(pVCpu, NewCrX);
-            AssertRCSuccessReturn(rc, rc);
-#else
-            pCtx->cr4 = NewCrX;
-#endif
+            if (IEM_VERIFICATION_ENABLED(pIemCpu))
+            {
+                rc = CPUMSetGuestCR4(pVCpu, NewCrX);
+                AssertRCSuccessReturn(rc, rc);
+            }
+            else
+                pCtx->cr4 = NewCrX;
             Assert(pCtx->cr4 == NewCrX);
 
@@ -5326,22 +5347,23 @@
              * Notify SELM and PGM.
              */
-#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-            /* SELM - VME may change things wrt to the TSS shadowing. */
-            if ((NewCrX ^ OldCrX) & X86_CR4_VME)
-                VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
-
-            /* PGM - flushing and mode. */
-            if (    (NewCrX & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE))
-                !=  (OldCrX & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE)) )
+            if (IEM_VERIFICATION_ENABLED(pIemCpu))
             {
-                rc = PGMFlushTLB(pVCpu, pCtx->cr3, true /* global */);
-                AssertRCReturn(rc, rc);
-                /* ignore informational status codes */
+                /* SELM - VME may change things wrt to the TSS shadowing. */
+                if ((NewCrX ^ OldCrX) & X86_CR4_VME)
+                    VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+
+                /* PGM - flushing and mode. */
+                if (    (NewCrX & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE))
+                    !=  (OldCrX & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE)) )
+                {
+                    rc = PGMFlushTLB(pVCpu, pCtx->cr3, true /* global */);
+                    AssertRCReturn(rc, rc);
+                    /* ignore informational status codes */
+                }
+                rcStrict = PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER);
+                /** @todo Status code management.  */
             }
-            rcStrict = PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER);
-            /** @todo Status code management.  */
-#else
-            rcStrict = VINF_SUCCESS;
-#endif
+            else
+                rcStrict = VINF_SUCCESS;
             break;
         }
@@ -5351,9 +5373,8 @@
          */
         case 8:
-#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-            AssertFailedReturn(VERR_NOT_IMPLEMENTED); /** @todo implement CR8 reading and writing. */
-#else
-            rcStrict = VINF_SUCCESS;
-#endif
+            if (IEM_VERIFICATION_ENABLED(pIemCpu))
+                AssertFailedReturn(VERR_NOT_IMPLEMENTED); /** @todo implement CR8 reading and writing. */
+            else
+                rcStrict = VINF_SUCCESS;
             break;
 
@@ -5392,9 +5413,8 @@
      */
     uint32_t u32Value;
-#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-    rcStrict = IOMIOPortRead(IEMCPU_TO_VM(pIemCpu), u16Port, &u32Value, cbReg);
-#else
-    rcStrict = iemVerifyFakeIOPortRead(pIemCpu, u16Port, &u32Value, cbReg);
-#endif
+    if (IEM_VERIFICATION_ENABLED(pIemCpu))
+        rcStrict = IOMIOPortRead(IEMCPU_TO_VM(pIemCpu), u16Port, &u32Value, cbReg);
+    else
+        rcStrict = iemVerifyFakeIOPortRead(pIemCpu, u16Port, &u32Value, cbReg);
     if (IOM_SUCCESS(rcStrict))
     {
@@ -5457,9 +5477,9 @@
         default: AssertFailedReturn(VERR_INTERNAL_ERROR_3);
     }
-# if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-    VBOXSTRICTRC rc = IOMIOPortWrite(IEMCPU_TO_VM(pIemCpu), u16Port, u32Value, cbReg);
-# else
-    VBOXSTRICTRC rc = iemVerifyFakeIOPortWrite(pIemCpu, u16Port, u32Value, cbReg);
-# endif
+    VBOXSTRICTRC rc;
+    if (IEM_VERIFICATION_ENABLED(pIemCpu))
+        rc = IOMIOPortWrite(IEMCPU_TO_VM(pIemCpu), u16Port, u32Value, cbReg);
+    else
+        rc = iemVerifyFakeIOPortWrite(pIemCpu, u16Port, u32Value, cbReg);
     if (IOM_SUCCESS(rc))
     {
@@ -6310,14 +6330,16 @@
 {
     PCPUMCTX pOrgCtx = pIemCpu->CTX_SUFF(pCtx);
-
-# ifndef IEM_VERIFICATION_MODE_NO_REM
+    pIemCpu->fNoRem = !LogIsEnabled(); /* logging triggers the no-rem/rem verification stuff */
+
     /*
      * Switch state.
      */
-    static CPUMCTX  s_DebugCtx; /* Ugly! */
-
-    s_DebugCtx = *pOrgCtx;
-    pIemCpu->CTX_SUFF(pCtx) = &s_DebugCtx;
-# endif
+    if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+    {
+        static CPUMCTX  s_DebugCtx; /* Ugly! */
+
+        s_DebugCtx = *pOrgCtx;
+        pIemCpu->CTX_SUFF(pCtx) = &s_DebugCtx;
+    }
 
     /*
@@ -6332,7 +6354,6 @@
         Log(("Injecting trap %#x\n", TRPMGetTrapNo(pVCpu)));
         iemCImpl_int(pIemCpu, 0, TRPMGetTrapNo(pVCpu), false);
-# ifdef IEM_VERIFICATION_MODE_NO_REM
-        TRPMResetTrap(pVCpu);
-# endif
+        if (IEM_VERIFICATION_ENABLED(pIemCpu))
+            TRPMResetTrap(pVCpu);
     }
 
@@ -6345,29 +6366,29 @@
     pIemCpu->fShiftOfHack= false;
 
-# ifndef IEM_VERIFICATION_MODE_NO_REM
-    /*
-     * Free all verification records.
-     */
-    PIEMVERIFYEVTREC pEvtRec = pIemCpu->pIemEvtRecHead;
-    pIemCpu->pIemEvtRecHead = NULL;
-    pIemCpu->ppIemEvtRecNext = &pIemCpu->pIemEvtRecHead;
-    do
-    {
-        while (pEvtRec)
-        {
-            PIEMVERIFYEVTREC pNext = pEvtRec->pNext;
-            pEvtRec->pNext = pIemCpu->pFreeEvtRec;
-            pIemCpu->pFreeEvtRec = pEvtRec;
-            pEvtRec = pNext;
-        }
-        pEvtRec = pIemCpu->pOtherEvtRecHead;
-        pIemCpu->pOtherEvtRecHead = NULL;
-        pIemCpu->ppOtherEvtRecNext = &pIemCpu->pOtherEvtRecHead;
-    } while (pEvtRec);
-# endif
-}
-
-
-# ifndef IEM_VERIFICATION_MODE_NO_REM
+    if (!IEM_VERIFICATION_ENABLED(pIemCpu))
+    {
+        /*
+         * Free all verification records.
+         */
+        PIEMVERIFYEVTREC pEvtRec = pIemCpu->pIemEvtRecHead;
+        pIemCpu->pIemEvtRecHead = NULL;
+        pIemCpu->ppIemEvtRecNext = &pIemCpu->pIemEvtRecHead;
+        do
+        {
+            while (pEvtRec)
+            {
+                PIEMVERIFYEVTREC pNext = pEvtRec->pNext;
+                pEvtRec->pNext = pIemCpu->pFreeEvtRec;
+                pIemCpu->pFreeEvtRec = pEvtRec;
+                pEvtRec = pNext;
+            }
+            pEvtRec = pIemCpu->pOtherEvtRecHead;
+            pIemCpu->pOtherEvtRecHead = NULL;
+            pIemCpu->ppOtherEvtRecNext = &pIemCpu->pOtherEvtRecHead;
+        } while (pEvtRec);
+    }
+}
+
+
 /**
  * Allocate an event record.
@@ -6376,4 +6397,7 @@
 static PIEMVERIFYEVTREC iemVerifyAllocRecord(PIEMCPU pIemCpu)
 {
+    if (IEM_VERIFICATION_ENABLED(pIemCpu))
+        return NULL;
+
     PIEMVERIFYEVTREC pEvtRec = pIemCpu->pFreeEvtRec;
     if (pEvtRec)
@@ -6392,5 +6416,4 @@
     return pEvtRec;
 }
-# endif
 
 
@@ -6400,5 +6423,4 @@
 VMM_INT_DECL(void)   IEMNotifyMMIORead(PVM pVM, RTGCPHYS GCPhys, size_t cbValue)
 {
-# ifndef IEM_VERIFICATION_MODE_NO_REM
     PVMCPU              pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
@@ -6413,5 +6435,4 @@
     pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
     *pIemCpu->ppOtherEvtRecNext = pEvtRec;
-# endif
 }
 
@@ -6422,5 +6443,4 @@
 VMM_INT_DECL(void)   IEMNotifyMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue)
 {
-# ifndef IEM_VERIFICATION_MODE_NO_REM
     PVMCPU              pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
@@ -6439,5 +6459,4 @@
     pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
     *pIemCpu->ppOtherEvtRecNext = pEvtRec;
-# endif
 }
 
@@ -6448,5 +6467,4 @@
 VMM_INT_DECL(void)   IEMNotifyIOPortRead(PVM pVM, RTIOPORT Port, size_t cbValue)
 {
-# ifndef IEM_VERIFICATION_MODE_NO_REM
     PVMCPU              pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
@@ -6461,5 +6479,4 @@
     pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
     *pIemCpu->ppOtherEvtRecNext = pEvtRec;
-# endif
 }
 
@@ -6469,5 +6486,4 @@
 VMM_INT_DECL(void)   IEMNotifyIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value, size_t cbValue)
 {
-# ifndef IEM_VERIFICATION_MODE_NO_REM
     PVMCPU              pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
@@ -6483,5 +6499,4 @@
     pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
     *pIemCpu->ppOtherEvtRecNext = pEvtRec;
-# endif
 }
 
@@ -6498,5 +6513,4 @@
 }
 
-# ifndef IEM_VERIFICATION_MODE_NO_REM
 
 /**
@@ -6596,13 +6610,15 @@
  * a record dump attached.
  *
+ * @param   pIemCpu         The IEM per CPU data.
  * @param   pEvtRec1        The first record.
  * @param   pEvtRec2        The second record.
  * @param   pszMsg          The message explaining why we're asserting.
  */
-static void iemVerifyAssertRecords(PIEMVERIFYEVTREC pEvtRec1, PIEMVERIFYEVTREC pEvtRec2, const char *pszMsg)
+static void iemVerifyAssertRecords(PIEMCPU pIemCpu, PIEMVERIFYEVTREC pEvtRec1, PIEMVERIFYEVTREC pEvtRec2, const char *pszMsg)
 {
     RTAssertMsg1(pszMsg, __LINE__, __FILE__, __PRETTY_FUNCTION__);
     iemVerifyAssertAddRecordDump(pEvtRec1);
     iemVerifyAssertAddRecordDump(pEvtRec2);
+    iemOpStubMsg2(pIemCpu);
     RTAssertPanic();
 }
@@ -6613,11 +6629,13 @@
  * a record dump attached.
  *
+ * @param   pIemCpu         The IEM per CPU data.
  * @param   pEvtRec1        The first record.
  * @param   pszMsg          The message explaining why we're asserting.
  */
-static void iemVerifyAssertRecord(PIEMVERIFYEVTREC pEvtRec, const char *pszMsg)
+static void iemVerifyAssertRecord(PIEMCPU pIemCpu, PIEMVERIFYEVTREC pEvtRec, const char *pszMsg)
 {
     RTAssertMsg1(pszMsg, __LINE__, __FILE__, __PRETTY_FUNCTION__);
     iemVerifyAssertAddRecordDump(pEvtRec);
+    iemOpStubMsg2(pIemCpu);
     RTAssertPanic();
 }
@@ -6651,4 +6669,5 @@
                             pEvtRec->u.RamWrite.cb, pEvtRec->u.RamWrite.ab);
             iemVerifyAssertAddRecordDump(pEvtRec);
+            iemOpStubMsg2(pIemCpu);
             RTAssertPanic();
         }
@@ -6657,6 +6676,4 @@
 }
 
-# endif /* !IEM_VERIFICATION_MODE_NO_REM */
-
 /**
  * Performs the post-execution verfication checks.
@@ -6664,5 +6681,7 @@
 static void iemExecVerificationModeCheck(PIEMCPU pIemCpu)
 {
-# if defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_NO_REM)
+    if (IEM_VERIFICATION_ENABLED(pIemCpu))
+        return;
+
     /*
      * Switch back the state.
@@ -6829,5 +6848,9 @@
 
         if (cDiffs != 0)
-            AssertFailed();
+        {
+            RTAssertMsg1(NULL, __LINE__, __FILE__, __FUNCTION__);
+            iemOpStubMsg2(pIemCpu);
+            RTAssertPanic();
+        }
 #  undef CHECK_FIELD
 #  undef CHECK_BIT_FIELD
@@ -6862,5 +6885,5 @@
             if (pIemRec->enmEvent != pOtherRec->enmEvent)
             {
-                iemVerifyAssertRecords(pIemRec, pOtherRec, "Type mismatches");
+                iemVerifyAssertRecords(pIemCpu, pIemRec, pOtherRec, "Type mismatches");
                 break;
             }
@@ -6892,5 +6915,5 @@
             if (!fEquals)
             {
-                iemVerifyAssertRecords(pIemRec, pOtherRec, "Mismatch");
+                iemVerifyAssertRecords(pIemCpu, pIemRec, pOtherRec, "Mismatch");
                 break;
             }
@@ -6909,10 +6932,9 @@
         }
         if (pIemRec != NULL)
-            iemVerifyAssertRecord(pIemRec, "Extra IEM record!");
+            iemVerifyAssertRecord(pIemCpu, pIemRec, "Extra IEM record!");
         else if (pOtherRec != NULL)
-            iemVerifyAssertRecord(pIemRec, "Extra Other record!");
+            iemVerifyAssertRecord(pIemCpu, pIemRec, "Extra Other record!");
     }
     pIemCpu->CTX_SUFF(pCtx) = pOrgCtx;
-# endif
 }
 
@@ -6935,5 +6957,5 @@
 #ifdef LOG_ENABLED
     PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
-    if (0)//LogIs2Enabled())
+    if (LogIs2Enabled())
     {
         char     szInstr[256];
Index: trunk/src/VBox/VMM/VMMAll/IEMAllCImplStrInstr.cpp.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllCImplStrInstr.cpp.h	(revision 36828)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllCImplStrInstr.cpp.h	(revision 36829)
@@ -54,4 +54,559 @@
 
 
+/**
+ * Implements 'REPE CMPS'.
+ */
+IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_repe_cmps_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg)
+{
+    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+    /*
+     * Setup.
+     */
+    ADDR_TYPE       uCounterReg = pCtx->ADDR_rCX;
+    if (uCounterReg == 0)
+        return VINF_SUCCESS;
+
+    PCCPUMSELREGHID pSrc1Hid = iemSRegGetHid(pIemCpu, iEffSeg);
+    VBOXSTRICTRC rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, pSrc1Hid, iEffSeg);
+    if (rcStrict != VINF_SUCCESS)
+        return rcStrict;
+
+    rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, &pCtx->esHid, X86_SREG_ES);
+    if (rcStrict != VINF_SUCCESS)
+        return rcStrict;
+
+    int8_t const    cbIncr      = pCtx->eflags.Bits.u1DF ? -(OP_SIZE / 8) : (OP_SIZE / 8);
+    ADDR_TYPE       uSrc1AddrReg = pCtx->ADDR_rSI;
+    ADDR_TYPE       uSrc2AddrReg = pCtx->ADDR_rDI;
+    uint32_t        uEFlags     = pCtx->eflags.u;
+
+    /*
+     * The loop.
+     */
+    do
+    {
+        /*
+         * Do segmentation and virtual page stuff.
+         */
+#if ADDR_SIZE != 64
+        ADDR2_TYPE  uVirtSrc1Addr = (uint32_t)pSrc1Hid->u64Base   + uSrc1AddrReg;
+        ADDR2_TYPE  uVirtSrc2Addr = (uint32_t)pCtx->esHid.u64Base + uSrc2AddrReg;
+#else
+        uint64_t    uVirtSrc1Addr = uSrc1AddrReg;
+        uint64_t    uVirtSrc2Addr = uSrc2AddrReg;
+#endif
+        uint32_t    cLeftSrc1Page = (PAGE_SIZE - (uVirtSrc1Addr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+        if (cLeftSrc1Page > uCounterReg)
+            cLeftSrc1Page = uCounterReg;
+        uint32_t    cLeftSrc2Page = (PAGE_SIZE - (uVirtSrc2Addr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+        uint32_t    cLeftPage = RT_MIN(cLeftSrc1Page, cLeftSrc2Page);
+
+        if (   cLeftPage > 0 /* can be null if unaligned, do one fallback round. */
+            && cbIncr > 0    /** @todo Implement reverse direction string ops. */
+#if ADDR_SIZE != 64
+            && uSrc1AddrReg < pSrc1Hid->u32Limit
+            && uSrc1AddrReg + (cLeftPage * (OP_SIZE / 8)) <= pSrc1Hid->u32Limit
+            && uSrc2AddrReg < pCtx->esHid.u32Limit
+            && uSrc2AddrReg + (cLeftPage * (OP_SIZE / 8)) <= pCtx->esHid.u32Limit
+#endif
+           )
+        {
+            RTGCPHYS GCPhysSrc1Mem;
+            rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtSrc1Addr, IEM_ACCESS_DATA_R, &GCPhysSrc1Mem);
+            if (rcStrict != VINF_SUCCESS)
+                break;
+
+            RTGCPHYS GCPhysSrc2Mem;
+            rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtSrc2Addr, IEM_ACCESS_DATA_R, &GCPhysSrc2Mem);
+            if (rcStrict != VINF_SUCCESS)
+                break;
+
+            /*
+             * If we can map the page without trouble, do a block processing
+             * until the end of the current page.
+             */
+            OP_TYPE const *puSrc2Mem;
+            rcStrict = iemMemPageMap(pIemCpu, GCPhysSrc2Mem, IEM_ACCESS_DATA_R, (void **)&puSrc2Mem);
+            if (rcStrict == VINF_SUCCESS)
+            {
+                OP_TYPE const *puSrc1Mem;
+                rcStrict = iemMemPageMap(pIemCpu, GCPhysSrc1Mem, IEM_ACCESS_DATA_R, (void **)&puSrc1Mem);
+                if (rcStrict == VINF_SUCCESS)
+                {
+                    if (!memcmp(puSrc2Mem, puSrc1Mem, cLeftPage * (OP_SIZE / 8)))
+                    {
+                        /* All matches, only compare the last itme to get the right eflags. */
+                        RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)&puSrc1Mem[cLeftPage-1], puSrc2Mem[cLeftPage-1], &uEFlags);
+                        uSrc1AddrReg += cLeftPage * cbIncr;
+                        uSrc2AddrReg += cLeftPage * cbIncr;
+                        uCounterReg -= cLeftPage;
+                    }
+                    else
+                    {
+                        /* Some mismatch, compare each item (and keep volatile
+                           memory in mind). */
+                        do
+                        {
+                            RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)puSrc1Mem, *puSrc2Mem, &uEFlags);
+                            uSrc1AddrReg += cbIncr;
+                            uSrc2AddrReg += cbIncr;
+                            uCounterReg--;
+                            puSrc1Mem++;
+                            puSrc2Mem++;
+                            cLeftPage--;
+                        } while (   (int32_t)cLeftPage > 0
+                                 && (uEFlags & X86_EFL_ZF));
+                    }
+                    continue;
+                }
+            }
+        }
+
+        /*
+         * Fallback - slow processing till the end of the current page.
+         * In the cross page boundrary case we will end up here with cLeftPage
+         * as 0, we execute one loop then.
+         */
+        do
+        {
+            OP_TYPE uValue1;
+            rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uValue1, iEffSeg, uSrc1AddrReg);
+            if (rcStrict != VINF_SUCCESS)
+                break;
+            OP_TYPE uValue2;
+            rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uValue2, X86_SREG_ES, uSrc2AddrReg);
+            if (rcStrict != VINF_SUCCESS)
+                break;
+            RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)(&uValue1, uValue2, &uEFlags);
+
+            uSrc1AddrReg += cbIncr;
+            uSrc2AddrReg += cbIncr;
+            uCounterReg--;
+            cLeftPage--;
+        } while (   (int32_t)cLeftPage > 0
+                 && (uEFlags & X86_EFL_ZF));
+        if (rcStrict != VINF_SUCCESS)
+            break;
+    } while (   uCounterReg != 0
+             && (uEFlags & X86_EFL_ZF));
+
+    /*
+     * Update the registers.
+     */
+    pCtx->ADDR_rCX = uCounterReg;
+    pCtx->ADDR_rSI = uSrc1AddrReg;
+    pCtx->ADDR_rDI = uSrc2AddrReg;
+    pCtx->eflags.u = uEFlags;
+    if (rcStrict == VINF_SUCCESS)
+        iemRegAddToRip(pIemCpu, cbInstr);
+
+    return rcStrict;
+}
+
+
+/**
+ * Implements 'REPNE CMPS'.
+ */
+IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_repne_cmps_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg)
+{
+    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+    /*
+     * Setup.
+     */
+    ADDR_TYPE       uCounterReg = pCtx->ADDR_rCX;
+    if (uCounterReg == 0)
+        return VINF_SUCCESS;
+
+    PCCPUMSELREGHID pSrc1Hid = iemSRegGetHid(pIemCpu, iEffSeg);
+    VBOXSTRICTRC rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, pSrc1Hid, iEffSeg);
+    if (rcStrict != VINF_SUCCESS)
+        return rcStrict;
+
+    rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, &pCtx->esHid, X86_SREG_ES);
+    if (rcStrict != VINF_SUCCESS)
+        return rcStrict;
+
+    int8_t const    cbIncr       = pCtx->eflags.Bits.u1DF ? -(OP_SIZE / 8) : (OP_SIZE / 8);
+    ADDR_TYPE       uSrc1AddrReg = pCtx->ADDR_rSI;
+    ADDR_TYPE       uSrc2AddrReg = pCtx->ADDR_rDI;
+    uint32_t        uEFlags      = pCtx->eflags.u;
+
+    /*
+     * The loop.
+     */
+    do
+    {
+        /*
+         * Do segmentation and virtual page stuff.
+         */
+#if ADDR_SIZE != 64
+        ADDR2_TYPE  uVirtSrc1Addr = (uint32_t)pSrc1Hid->u64Base   + uSrc1AddrReg;
+        ADDR2_TYPE  uVirtSrc2Addr = (uint32_t)pCtx->esHid.u64Base + uSrc2AddrReg;
+#else
+        uint64_t    uVirtSrc1Addr = uSrc1AddrReg;
+        uint64_t    uVirtSrc2Addr = uSrc2AddrReg;
+#endif
+        uint32_t    cLeftSrc1Page = (PAGE_SIZE - (uVirtSrc1Addr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+        if (cLeftSrc1Page > uCounterReg)
+            cLeftSrc1Page = uCounterReg;
+        uint32_t    cLeftSrc2Page = (PAGE_SIZE - (uVirtSrc2Addr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+        uint32_t    cLeftPage = RT_MIN(cLeftSrc1Page, cLeftSrc2Page);
+
+        if (   cLeftPage > 0 /* can be null if unaligned, do one fallback round. */
+            && cbIncr > 0    /** @todo Implement reverse direction string ops. */
+#if ADDR_SIZE != 64
+            && uSrc1AddrReg < pSrc1Hid->u32Limit
+            && uSrc1AddrReg + (cLeftPage * (OP_SIZE / 8)) <= pSrc1Hid->u32Limit
+            && uSrc2AddrReg < pCtx->esHid.u32Limit
+            && uSrc2AddrReg + (cLeftPage * (OP_SIZE / 8)) <= pCtx->esHid.u32Limit
+#endif
+           )
+        {
+            RTGCPHYS GCPhysSrc1Mem;
+            rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtSrc1Addr, IEM_ACCESS_DATA_R, &GCPhysSrc1Mem);
+            if (rcStrict != VINF_SUCCESS)
+                break;
+
+            RTGCPHYS GCPhysSrc2Mem;
+            rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtSrc2Addr, IEM_ACCESS_DATA_R, &GCPhysSrc2Mem);
+            if (rcStrict != VINF_SUCCESS)
+                break;
+
+            /*
+             * If we can map the page without trouble, do a block processing
+             * until the end of the current page.
+             */
+            OP_TYPE const *puSrc2Mem;
+            rcStrict = iemMemPageMap(pIemCpu, GCPhysSrc2Mem, IEM_ACCESS_DATA_R, (void **)&puSrc2Mem);
+            if (rcStrict == VINF_SUCCESS)
+            {
+                OP_TYPE const *puSrc1Mem;
+                rcStrict = iemMemPageMap(pIemCpu, GCPhysSrc1Mem, IEM_ACCESS_DATA_R, (void **)&puSrc1Mem);
+                if (rcStrict == VINF_SUCCESS)
+                {
+                    if (memcmp(puSrc2Mem, puSrc1Mem, cLeftPage * (OP_SIZE / 8)))
+                    {
+                        /* All matches, only compare the last itme to get the right eflags. */
+                        RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)&puSrc1Mem[cLeftPage-1], puSrc2Mem[cLeftPage-1], &uEFlags);
+                        uSrc1AddrReg += cLeftPage * cbIncr;
+                        uSrc2AddrReg += cLeftPage * cbIncr;
+                        uCounterReg -= cLeftPage;
+                    }
+                    else
+                    {
+                        /* Some mismatch, compare each item (and keep volatile
+                           memory in mind). */
+                        do
+                        {
+                            RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)puSrc1Mem, *puSrc2Mem, &uEFlags);
+                            uSrc1AddrReg += cbIncr;
+                            uSrc2AddrReg += cbIncr;
+                            uCounterReg--;
+                            puSrc1Mem++;
+                            puSrc2Mem++;
+                            cLeftPage--;
+                        } while (   (int32_t)cLeftPage > 0
+                                 && !(uEFlags & X86_EFL_ZF));
+                    }
+                    continue;
+                }
+            }
+        }
+
+        /*
+         * Fallback - slow processing till the end of the current page.
+         * In the cross page boundrary case we will end up here with cLeftPage
+         * as 0, we execute one loop then.
+         */
+        do
+        {
+            OP_TYPE uValue1;
+            rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uValue1, iEffSeg, uSrc1AddrReg);
+            if (rcStrict != VINF_SUCCESS)
+                break;
+            OP_TYPE uValue2;
+            rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uValue2, X86_SREG_ES, uSrc2AddrReg);
+            if (rcStrict != VINF_SUCCESS)
+                break;
+            RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)(&uValue1, uValue2, &uEFlags);
+
+            uSrc1AddrReg += cbIncr;
+            uSrc2AddrReg += cbIncr;
+            uCounterReg--;
+            cLeftPage--;
+        } while (   (int32_t)cLeftPage > 0
+                 && !(uEFlags & X86_EFL_ZF));
+        if (rcStrict != VINF_SUCCESS)
+            break;
+    } while (   uCounterReg != 0
+             && !(uEFlags & X86_EFL_ZF));
+
+    /*
+     * Update the registers.
+     */
+    pCtx->ADDR_rCX = uCounterReg;
+    pCtx->ADDR_rSI = uSrc1AddrReg;
+    pCtx->ADDR_rDI = uSrc2AddrReg;
+    pCtx->eflags.u = uEFlags;
+    if (rcStrict == VINF_SUCCESS)
+        iemRegAddToRip(pIemCpu, cbInstr);
+
+    return rcStrict;
+}
+
+
+/**
+ * Implements 'REPE SCAS'.
+ */
+IEM_CIMPL_DEF_0(RT_CONCAT4(iemCImpl_repe_scas_,OP_rAX,_m,ADDR_SIZE))
+{
+    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+    /*
+     * Setup.
+     */
+    ADDR_TYPE       uCounterReg = pCtx->ADDR_rCX;
+    if (uCounterReg == 0)
+        return VINF_SUCCESS;
+
+    VBOXSTRICTRC rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, &pCtx->esHid, X86_SREG_ES);
+    if (rcStrict != VINF_SUCCESS)
+        return rcStrict;
+
+    int8_t const    cbIncr      = pCtx->eflags.Bits.u1DF ? -(OP_SIZE / 8) : (OP_SIZE / 8);
+    OP_TYPE const   uValueReg   = pCtx->OP_rAX;
+    ADDR_TYPE       uAddrReg    = pCtx->ADDR_rDI;
+    uint32_t        uEFlags     = pCtx->eflags.u;
+
+    /*
+     * The loop.
+     */
+    do
+    {
+        /*
+         * Do segmentation and virtual page stuff.
+         */
+#if ADDR_SIZE != 64
+        ADDR2_TYPE  uVirtAddr = (uint32_t)pCtx->esHid.u64Base + uAddrReg;
+#else
+        uint64_t    uVirtAddr = uAddrReg;
+#endif
+        uint32_t    cLeftPage = (PAGE_SIZE - (uVirtAddr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+        if (cLeftPage > uCounterReg)
+            cLeftPage = uCounterReg;
+        if (   cLeftPage > 0 /* can be null if unaligned, do one fallback round. */
+            && cbIncr > 0    /** @todo Implement reverse direction string ops. */
+#if ADDR_SIZE != 64
+            && uAddrReg < pCtx->esHid.u32Limit
+            && uAddrReg + (cLeftPage * (OP_SIZE / 8)) <= pCtx->esHid.u32Limit
+#endif
+           )
+        {
+            RTGCPHYS GCPhysMem;
+            rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtAddr, IEM_ACCESS_DATA_R, &GCPhysMem);
+            if (rcStrict != VINF_SUCCESS)
+                break;
+
+            /*
+             * If we can map the page without trouble, do a block processing
+             * until the end of the current page.
+             */
+            OP_TYPE const *puMem;
+            rcStrict = iemMemPageMap(pIemCpu, GCPhysMem, IEM_ACCESS_DATA_R, (void **)&puMem);
+            if (rcStrict == VINF_SUCCESS)
+            {
+                /* Search till we find a mismatching item. */
+                OP_TYPE  uTmpValue;
+                bool     fQuit;
+                uint32_t i = 0;
+                do
+                {
+                    uTmpValue = puMem[i++];
+                    fQuit = uTmpValue != uValueReg;
+                } while (i < cLeftPage && !fQuit);
+
+                /* Update the regs. */
+                RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)&uValueReg, uTmpValue, &uEFlags);
+                uCounterReg -= i;
+                uAddrReg    += i * cbIncr;
+                Assert(!(uEFlags & X86_EFL_ZF) == (i < cLeftPage));
+                if (fQuit)
+                    break;
+
+
+                /* If unaligned, we drop thru and do the page crossing access
+                   below. Otherwise, do the next page. */
+                if (!(uVirtAddr & (OP_SIZE - 1)))
+                    continue;
+                if (uCounterReg == 0)
+                    break;
+                cLeftPage = 0;
+            }
+        }
+
+        /*
+         * Fallback - slow processing till the end of the current page.
+         * In the cross page boundrary case we will end up here with cLeftPage
+         * as 0, we execute one loop then.
+         */
+        do
+        {
+            OP_TYPE uTmpValue;
+            rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uTmpValue, X86_SREG_ES, uAddrReg);
+            if (rcStrict != VINF_SUCCESS)
+                break;
+            RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)&uValueReg, uTmpValue, &uEFlags);
+
+            uAddrReg += cbIncr;
+            uCounterReg--;
+            cLeftPage--;
+        } while (   (int32_t)cLeftPage > 0
+                 && (uEFlags & X86_EFL_ZF));
+        if (rcStrict != VINF_SUCCESS)
+            break;
+    } while (   uCounterReg != 0
+             && (uEFlags & X86_EFL_ZF));
+
+    /*
+     * Update the registers.
+     */
+    pCtx->ADDR_rCX = uCounterReg;
+    pCtx->ADDR_rDI = uAddrReg;
+    pCtx->eflags.u = uEFlags;
+    if (rcStrict == VINF_SUCCESS)
+        iemRegAddToRip(pIemCpu, cbInstr);
+
+    return rcStrict;
+}
+
+
+/**
+ * Implements 'REPNE SCAS'.
+ */
+IEM_CIMPL_DEF_0(RT_CONCAT4(iemCImpl_repne_scas_,OP_rAX,_m,ADDR_SIZE))
+{
+    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+    /*
+     * Setup.
+     */
+    ADDR_TYPE       uCounterReg = pCtx->ADDR_rCX;
+    if (uCounterReg == 0)
+        return VINF_SUCCESS;
+
+    VBOXSTRICTRC rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, &pCtx->esHid, X86_SREG_ES);
+    if (rcStrict != VINF_SUCCESS)
+        return rcStrict;
+
+    int8_t const    cbIncr      = pCtx->eflags.Bits.u1DF ? -(OP_SIZE / 8) : (OP_SIZE / 8);
+    OP_TYPE const   uValueReg   = pCtx->OP_rAX;
+    ADDR_TYPE       uAddrReg    = pCtx->ADDR_rDI;
+    uint32_t        uEFlags     = pCtx->eflags.u;
+
+    /*
+     * The loop.
+     */
+    do
+    {
+        /*
+         * Do segmentation and virtual page stuff.
+         */
+#if ADDR_SIZE != 64
+        ADDR2_TYPE  uVirtAddr = (uint32_t)pCtx->esHid.u64Base + uAddrReg;
+#else
+        uint64_t    uVirtAddr = uAddrReg;
+#endif
+        uint32_t    cLeftPage = (PAGE_SIZE - (uVirtAddr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
+        if (cLeftPage > uCounterReg)
+            cLeftPage = uCounterReg;
+        if (   cLeftPage > 0 /* can be null if unaligned, do one fallback round. */
+            && cbIncr > 0    /** @todo Implement reverse direction string ops. */
+#if ADDR_SIZE != 64
+            && uAddrReg < pCtx->esHid.u32Limit
+            && uAddrReg + (cLeftPage * (OP_SIZE / 8)) <= pCtx->esHid.u32Limit
+#endif
+           )
+        {
+            RTGCPHYS GCPhysMem;
+            rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtAddr, IEM_ACCESS_DATA_R, &GCPhysMem);
+            if (rcStrict != VINF_SUCCESS)
+                break;
+
+            /*
+             * If we can map the page without trouble, do a block processing
+             * until the end of the current page.
+             */
+            OP_TYPE const *puMem;
+            rcStrict = iemMemPageMap(pIemCpu, GCPhysMem, IEM_ACCESS_DATA_R, (void **)&puMem);
+            if (rcStrict == VINF_SUCCESS)
+            {
+                /* Search till we find a mismatching item. */
+                OP_TYPE  uTmpValue;
+                bool     fQuit;
+                uint32_t i = 0;
+                do
+                {
+                    uTmpValue = puMem[i++];
+                    fQuit = uTmpValue == uValueReg;
+                } while (i < cLeftPage && !fQuit);
+
+                /* Update the regs. */
+                RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)&uValueReg, uTmpValue, &uEFlags);
+                uCounterReg -= i;
+                uAddrReg    += i * cbIncr;
+                Assert(!(uEFlags & X86_EFL_ZF) != (i < cLeftPage));
+                if (fQuit)
+                    break;
+
+
+                /* If unaligned, we drop thru and do the page crossing access
+                   below. Otherwise, do the next page. */
+                if (!(uVirtAddr & (OP_SIZE - 1)))
+                    continue;
+                if (uCounterReg == 0)
+                    break;
+                cLeftPage = 0;
+            }
+        }
+
+        /*
+         * Fallback - slow processing till the end of the current page.
+         * In the cross page boundrary case we will end up here with cLeftPage
+         * as 0, we execute one loop then.
+         */
+        do
+        {
+            OP_TYPE uTmpValue;
+            rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uTmpValue, X86_SREG_ES, uAddrReg);
+            if (rcStrict != VINF_SUCCESS)
+                break;
+            RT_CONCAT(iemAImpl_cmp_u,OP_SIZE)((OP_TYPE *)&uValueReg, uTmpValue, &uEFlags);
+
+            uAddrReg += cbIncr;
+            uCounterReg--;
+            cLeftPage--;
+        } while (   (int32_t)cLeftPage > 0
+                 && !(uEFlags & X86_EFL_ZF));
+        if (rcStrict != VINF_SUCCESS)
+            break;
+    } while (   uCounterReg != 0
+             && !(uEFlags & X86_EFL_ZF));
+
+    /*
+     * Update the registers.
+     */
+    pCtx->ADDR_rCX = uCounterReg;
+    pCtx->ADDR_rDI = uAddrReg;
+    pCtx->eflags.u = uEFlags;
+    if (rcStrict == VINF_SUCCESS)
+        iemRegAddToRip(pIemCpu, cbInstr);
+
+    return rcStrict;
+}
+
+
+
 
 /**
@@ -132,5 +687,5 @@
             {
                 OP_TYPE const *puSrcMem;
-                rcStrict = iemMemPageMap(pIemCpu, GCPhysSrcMem, IEM_ACCESS_DATA_W, (void **)&puSrcMem);
+                rcStrict = iemMemPageMap(pIemCpu, GCPhysSrcMem, IEM_ACCESS_DATA_R, (void **)&puSrcMem);
                 if (rcStrict == VINF_SUCCESS)
                 {
@@ -179,4 +734,6 @@
     if (rcStrict == VINF_SUCCESS)
         iemRegAddToRip(pIemCpu, cbInstr);
+    else
+        AssertFailed();
 
     return rcStrict;
@@ -437,9 +994,8 @@
 
     uint32_t        u32Value;
-# if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-    rcStrict = IOMIOPortRead(pVM, pCtx->dx, &u32Value, OP_SIZE / 8);
-# else
-    iemVerifyFakeIOPortRead(pIemCpu, pCtx->dx, &u32Value, OP_SIZE / 8);
-# endif
+    if (IEM_VERIFICATION_ENABLED(pIemCpu))
+        rcStrict = IOMIOPortRead(pVM, pCtx->dx, &u32Value, OP_SIZE / 8);
+    else
+        rcStrict = iemVerifyFakeIOPortRead(pIemCpu, pCtx->dx, &u32Value, OP_SIZE / 8);
     if (IOM_SUCCESS(rcStrict))
     {
@@ -536,9 +1092,8 @@
                 {
                     uint32_t u32Value;
-# if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-                    rcStrict = IOMIOPortRead(pVM, u16Port, &u32Value, OP_SIZE / 8);
-# else
-                    rcStrict = iemVerifyFakeIOPortRead(pIemCpu, u16Port, &u32Value, OP_SIZE / 8);
-# endif
+                    if (IEM_VERIFICATION_ENABLED(pIemCpu))
+                        rcStrict = IOMIOPortRead(pVM, u16Port, &u32Value, OP_SIZE / 8);
+                    else
+                        rcStrict = iemVerifyFakeIOPortRead(pIemCpu, u16Port, &u32Value, OP_SIZE / 8);
                     if (!IOM_SUCCESS(rcStrict))
                         break;
@@ -584,9 +1139,8 @@
 
             uint32_t u32Value;
-# if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-            rcStrict = IOMIOPortRead(pVM, u16Port, &u32Value, OP_SIZE / 8);
-# else
-            rcStrict = iemVerifyFakeIOPortRead(pIemCpu, u16Port, &u32Value, OP_SIZE / 8);
-# endif
+            if (IEM_VERIFICATION_ENABLED(pIemCpu))
+                rcStrict = IOMIOPortRead(pVM, u16Port, &u32Value, OP_SIZE / 8);
+            else
+                rcStrict = iemVerifyFakeIOPortRead(pIemCpu, u16Port, &u32Value, OP_SIZE / 8);
             if (!IOM_SUCCESS(rcStrict))
                 break;
@@ -642,9 +1196,8 @@
     if (rcStrict == VINF_SUCCESS)
     {
-# if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-        rcStrict = IOMIOPortWrite(pVM, pCtx->dx, uValue, OP_SIZE / 8);
-# else
-        rcStrict = iemVerifyFakeIOPortWrite(pIemCpu, pCtx->dx, uValue, OP_SIZE / 8);
-# endif
+        if (IEM_VERIFICATION_ENABLED(pIemCpu))
+            rcStrict = IOMIOPortWrite(pVM, pCtx->dx, uValue, OP_SIZE / 8);
+        else
+            rcStrict = iemVerifyFakeIOPortWrite(pIemCpu, pCtx->dx, uValue, OP_SIZE / 8);
         if (IOM_SUCCESS(rcStrict))
         {
@@ -734,9 +1287,8 @@
                 {
                     uint32_t u32Value = *puMem++;
-# if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-                    rcStrict = IOMIOPortWrite(pVM, u16Port, u32Value, OP_SIZE / 8);
-# else
-                    rcStrict = iemVerifyFakeIOPortWrite(pIemCpu, u16Port, u32Value, OP_SIZE / 8);
-# endif
+                    if (IEM_VERIFICATION_ENABLED(pIemCpu))
+                        rcStrict = IOMIOPortWrite(pVM, u16Port, u32Value, OP_SIZE / 8);
+                    else
+                        rcStrict = iemVerifyFakeIOPortWrite(pIemCpu, u16Port, u32Value, OP_SIZE / 8);
                     if (!IOM_SUCCESS(rcStrict))
                         break;
@@ -780,9 +1332,8 @@
                 break;
 
-# if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
-            rcStrict = IOMIOPortWrite(pVM, u16Port, uValue, OP_SIZE / 8);
-# else
-            rcStrict = iemVerifyFakeIOPortWrite(pIemCpu, u16Port, uValue, OP_SIZE / 8);
-# endif
+            if (IEM_VERIFICATION_ENABLED(pIemCpu))
+                rcStrict = IOMIOPortWrite(pVM, u16Port, uValue, OP_SIZE / 8);
+            else
+                rcStrict = iemVerifyFakeIOPortWrite(pIemCpu, u16Port, uValue, OP_SIZE / 8);
             if (!IOM_SUCCESS(rcStrict))
                 break;
Index: trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h	(revision 36828)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h	(revision 36829)
@@ -1647,35 +1647,641 @@
 
 /** Opcode 0x0f 0x90. */
-FNIEMOP_STUB(iemOp_seto_Jv);
+FNIEMOP_DEF(iemOp_seto_Eb)
+{
+    IEMOP_MNEMONIC("seto Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x0f 0x91. */
-FNIEMOP_STUB(iemOp_setno_Jv);
+FNIEMOP_DEF(iemOp_setno_Eb)
+{
+    IEMOP_MNEMONIC("setno Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_OF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x0f 0x92. */
-FNIEMOP_STUB(iemOp_setc_Jv);
+FNIEMOP_DEF(iemOp_setc_Eb)
+{
+    IEMOP_MNEMONIC("setc Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x0f 0x93. */
-FNIEMOP_STUB(iemOp_setnc_Jv);
+FNIEMOP_DEF(iemOp_setnc_Eb)
+{
+    IEMOP_MNEMONIC("setnc Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x0f 0x94. */
-FNIEMOP_STUB(iemOp_sete_Jv);
+FNIEMOP_DEF(iemOp_sete_Eb)
+{
+    IEMOP_MNEMONIC("sete Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x0f 0x95. */
-FNIEMOP_STUB(iemOp_setne_Jv);
+FNIEMOP_DEF(iemOp_setne_Eb)
+{
+    IEMOP_MNEMONIC("setne Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x0f 0x96. */
-FNIEMOP_STUB(iemOp_setbe_Jv);
+FNIEMOP_DEF(iemOp_setbe_Eb)
+{
+    IEMOP_MNEMONIC("setbe Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x0f 0x97. */
-FNIEMOP_STUB(iemOp_setnbe_Jv);
+FNIEMOP_DEF(iemOp_setnbe_Eb)
+{
+    IEMOP_MNEMONIC("setnbe Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x0f 0x98. */
-FNIEMOP_STUB(iemOp_sets_Jv);
+FNIEMOP_DEF(iemOp_sets_Eb)
+{
+    IEMOP_MNEMONIC("sets Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x0f 0x99. */
-FNIEMOP_STUB(iemOp_setns_Jv);
+FNIEMOP_DEF(iemOp_setns_Eb)
+{
+    IEMOP_MNEMONIC("setns Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_SF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x0f 0x9a. */
-FNIEMOP_STUB(iemOp_setp_Jv);
+FNIEMOP_DEF(iemOp_setp_Eb)
+{
+    IEMOP_MNEMONIC("setnp Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x0f 0x9b. */
-FNIEMOP_STUB(iemOp_setnp_Jv);
+FNIEMOP_DEF(iemOp_setnp_Eb)
+{
+    IEMOP_MNEMONIC("setnp Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x0f 0x9c. */
-FNIEMOP_STUB(iemOp_setl_Jv);
+FNIEMOP_DEF(iemOp_setl_Eb)
+{
+    IEMOP_MNEMONIC("setl Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x0f 0x9d. */
-FNIEMOP_STUB(iemOp_setnl_Jv);
+FNIEMOP_DEF(iemOp_setnl_Eb)
+{
+    IEMOP_MNEMONIC("setnl Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_BITS_NE(X86_EFL_SF, X86_EFL_OF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x0f 0x9e. */
-FNIEMOP_STUB(iemOp_setle_Jv);
+FNIEMOP_DEF(iemOp_setle_Eb)
+{
+    IEMOP_MNEMONIC("setle Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x0f 0x9f. */
-FNIEMOP_STUB(iemOp_setnle_Jv);
+FNIEMOP_DEF(iemOp_setnle_Eb)
+{
+    IEMOP_MNEMONIC("setnle Eb");
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
+    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo too early? */
+
+    /** @todo Encoding test: Check if the 'reg' field is ignored or decoded in
+     *        any way. AMD says it's "unused", whatever that means.  We're
+     *        ignoring for now. */
+    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        /* register target */
+        IEM_MC_BEGIN(0, 0);
+        IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_GREG_U8((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /* memory target */
+        IEM_MC_BEGIN(0, 1);
+        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
+        IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(X86_EFL_ZF, X86_EFL_SF, X86_EFL_OF) {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 0);
+        } IEM_MC_ELSE() {
+            IEM_MC_STORE_MEM_U8(pIemCpu->iEffSeg, GCPtrEffDst, 1);
+        } IEM_MC_ENDIF();
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
 
 
@@ -2270,8 +2876,8 @@
     /* 0x88 */  iemOp_js_Jv,            iemOp_jns_Jv,           iemOp_jp_Jv,            iemOp_jnp_Jv,
     /* 0x8c */  iemOp_jl_Jv,            iemOp_jnl_Jv,           iemOp_jle_Jv,           iemOp_jnle_Jv,
-    /* 0x90 */  iemOp_seto_Jv,          iemOp_setno_Jv,         iemOp_setc_Jv,          iemOp_setnc_Jv,
-    /* 0x94 */  iemOp_sete_Jv,          iemOp_setne_Jv,         iemOp_setbe_Jv,         iemOp_setnbe_Jv,
-    /* 0x98 */  iemOp_sets_Jv,          iemOp_setns_Jv,         iemOp_setp_Jv,          iemOp_setnp_Jv,
-    /* 0x9c */  iemOp_setl_Jv,          iemOp_setnl_Jv,         iemOp_setle_Jv,         iemOp_setnle_Jv,
+    /* 0x90 */  iemOp_seto_Eb,          iemOp_setno_Eb,         iemOp_setc_Eb,          iemOp_setnc_Eb,
+    /* 0x94 */  iemOp_sete_Eb,          iemOp_setne_Eb,         iemOp_setbe_Eb,         iemOp_setnbe_Eb,
+    /* 0x98 */  iemOp_sets_Eb,          iemOp_setns_Eb,         iemOp_setp_Eb,          iemOp_setnp_Eb,
+    /* 0x9c */  iemOp_setl_Eb,          iemOp_setnl_Eb,         iemOp_setle_Eb,         iemOp_setnle_Eb,
     /* 0xa0 */  iemOp_push_fs,          iemOp_pop_fs,           iemOp_cpuid,            iemOp_bt_Ev_Gv,
     /* 0xa4 */  iemOp_shld_Ev_Gv_Ib,    iemOp_shld_Ev_Gv_CL,    iemOp_Invalid,          iemOp_Invalid,
@@ -5804,6 +6410,5 @@
         } IEM_MC_ENDIF(); \
         IEM_MC_ADVANCE_RIP(); \
-        IEM_MC_END(); \
-
+        IEM_MC_END();
 
 /** Opcode 0xa4. */
@@ -5813,5 +6418,5 @@
 
     /*
-     * Use the C implementation if a repeate prefix is encountered.
+     * Use the C implementation if a repeat prefix is encountered.
      */
     if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
@@ -5848,5 +6453,5 @@
 
     /*
-     * Use the C implementation if a repeate prefix is encountered.
+     * Use the C implementation if a repeat prefix is encountered.
      */
     if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
@@ -5927,9 +6532,198 @@
 #undef IEM_MOVS_CASE
 
+/** Macro used by iemOp_cmpsb_Xb_Yb and iemOp_cmpswd_Xv_Yv */
+#define IEM_CMPS_CASE(ValBits, AddrBits) \
+        IEM_MC_BEGIN(3, 3); \
+        IEM_MC_ARG(uint##ValBits##_t *, puValue1, 0); \
+        IEM_MC_ARG(uint##ValBits##_t,   uValue2,  1); \
+        IEM_MC_ARG(uint32_t *,          pEFlags,  2); \
+        IEM_MC_LOCAL(uint##ValBits##_t, uValue1); \
+        IEM_MC_LOCAL(uint##AddrBits##_t, uAddr); \
+        \
+        IEM_MC_FETCH_GREG_U##AddrBits(uAddr, X86_GREG_xSI); \
+        IEM_MC_FETCH_MEM_U##ValBits(uValue1, pIemCpu->iEffSeg, uAddr); \
+        IEM_MC_FETCH_GREG_U##AddrBits(uAddr, X86_GREG_xDI); \
+        IEM_MC_FETCH_MEM_U##ValBits(uValue2, X86_SREG_ES, uAddr); \
+        IEM_MC_REF_LOCAL(puValue1, uValue1); \
+        IEM_MC_REF_EFLAGS(pEFlags); \
+        IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_cmp_u##ValBits, puValue1, uValue2, pEFlags); \
+        \
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
+            IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
+            IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
+        } IEM_MC_ELSE() { \
+            IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
+            IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
+        } IEM_MC_ENDIF(); \
+        IEM_MC_ADVANCE_RIP(); \
+        IEM_MC_END(); \
+
 /** Opcode 0xa6. */
-FNIEMOP_STUB(iemOp_cmpsb_Xb_Yb);
+FNIEMOP_DEF(iemOp_cmpsb_Xb_Yb)
+{
+    IEMOP_HLP_NO_LOCK_PREFIX();
+
+    /*
+     * Use the C implementation if a repeat prefix is encountered.
+     */
+    if (pIemCpu->fPrefixes & IEM_OP_PRF_REPZ)
+    {
+        IEMOP_MNEMONIC("repe cmps Xb,Yb");
+        switch (pIemCpu->enmEffAddrMode)
+        {
+            case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op8_addr16, pIemCpu->iEffSeg);
+            case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op8_addr32, pIemCpu->iEffSeg);
+            case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op8_addr64, pIemCpu->iEffSeg);
+            IEM_NOT_REACHED_DEFAULT_CASE_RET();
+        }
+    }
+    if (pIemCpu->fPrefixes & IEM_OP_PRF_REPNZ)
+    {
+        IEMOP_MNEMONIC("repe cmps Xb,Yb");
+        switch (pIemCpu->enmEffAddrMode)
+        {
+            case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op8_addr16, pIemCpu->iEffSeg);
+            case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op8_addr32, pIemCpu->iEffSeg);
+            case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op8_addr64, pIemCpu->iEffSeg);
+            IEM_NOT_REACHED_DEFAULT_CASE_RET();
+        }
+    }
+    IEMOP_MNEMONIC("cmps Xb,Yb");
+
+    /*
+     * Sharing case implementation with cmps[wdq] below.
+     */
+    switch (pIemCpu->enmEffAddrMode)
+    {
+        case IEMMODE_16BIT: IEM_CMPS_CASE(8, 16); break;
+        case IEMMODE_32BIT: IEM_CMPS_CASE(8, 32); break;
+        case IEMMODE_64BIT: IEM_CMPS_CASE(8, 64); break;
+        IEM_NOT_REACHED_DEFAULT_CASE_RET();
+    }
+    return VINF_SUCCESS;
+
+}
+
+
 /** Opcode 0xa7. */
-FNIEMOP_STUB(iemOp_cmpswd_Xv_Yv);
-
+FNIEMOP_DEF(iemOp_cmpswd_Xv_Yv)
+{
+    IEMOP_HLP_NO_LOCK_PREFIX();
+
+    /*
+     * Use the C implementation if a repeat prefix is encountered.
+     */
+    if (pIemCpu->fPrefixes & IEM_OP_PRF_REPZ)
+    {
+        IEMOP_MNEMONIC("repe cmps Xv,Yv");
+        switch (pIemCpu->enmEffOpSize)
+        {
+            case IEMMODE_16BIT:
+                switch (pIemCpu->enmEffAddrMode)
+                {
+                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op16_addr16, pIemCpu->iEffSeg);
+                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op16_addr32, pIemCpu->iEffSeg);
+                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op16_addr64, pIemCpu->iEffSeg);
+                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
+                }
+                break;
+            case IEMMODE_32BIT:
+                switch (pIemCpu->enmEffAddrMode)
+                {
+                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op32_addr16, pIemCpu->iEffSeg);
+                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op32_addr32, pIemCpu->iEffSeg);
+                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op32_addr64, pIemCpu->iEffSeg);
+                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
+                }
+            case IEMMODE_64BIT:
+                switch (pIemCpu->enmEffAddrMode)
+                {
+                    case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_3);
+                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op64_addr32, pIemCpu->iEffSeg);
+                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repe_cmps_op64_addr64, pIemCpu->iEffSeg);
+                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
+                }
+            IEM_NOT_REACHED_DEFAULT_CASE_RET();
+        }
+    }
+
+    if (pIemCpu->fPrefixes & IEM_OP_PRF_REPNZ)
+    {
+        IEMOP_MNEMONIC("repne cmps Xv,Yv");
+        switch (pIemCpu->enmEffOpSize)
+        {
+            case IEMMODE_16BIT:
+                switch (pIemCpu->enmEffAddrMode)
+                {
+                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op16_addr16, pIemCpu->iEffSeg);
+                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op16_addr32, pIemCpu->iEffSeg);
+                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op16_addr64, pIemCpu->iEffSeg);
+                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
+                }
+                break;
+            case IEMMODE_32BIT:
+                switch (pIemCpu->enmEffAddrMode)
+                {
+                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op32_addr16, pIemCpu->iEffSeg);
+                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op32_addr32, pIemCpu->iEffSeg);
+                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op32_addr64, pIemCpu->iEffSeg);
+                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
+                }
+            case IEMMODE_64BIT:
+                switch (pIemCpu->enmEffAddrMode)
+                {
+                    case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_3);
+                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op64_addr32, pIemCpu->iEffSeg);
+                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_repne_cmps_op64_addr64, pIemCpu->iEffSeg);
+                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
+                }
+            IEM_NOT_REACHED_DEFAULT_CASE_RET();
+        }
+    }
+
+    IEMOP_MNEMONIC("cmps Xv,Yv");
+
+    /*
+     * Annoying double switch here.
+     * Using ugly macro for implementing the cases, sharing it with cmpsb.
+     */
+    switch (pIemCpu->enmEffOpSize)
+    {
+        case IEMMODE_16BIT:
+            switch (pIemCpu->enmEffAddrMode)
+            {
+                case IEMMODE_16BIT: IEM_CMPS_CASE(16, 16); break;
+                case IEMMODE_32BIT: IEM_CMPS_CASE(16, 32); break;
+                case IEMMODE_64BIT: IEM_CMPS_CASE(16, 64); break;
+                IEM_NOT_REACHED_DEFAULT_CASE_RET();
+            }
+            break;
+
+        case IEMMODE_32BIT:
+            switch (pIemCpu->enmEffAddrMode)
+            {
+                case IEMMODE_16BIT: IEM_CMPS_CASE(32, 16); break;
+                case IEMMODE_32BIT: IEM_CMPS_CASE(32, 32); break;
+                case IEMMODE_64BIT: IEM_CMPS_CASE(32, 64); break;
+                IEM_NOT_REACHED_DEFAULT_CASE_RET();
+            }
+            break;
+
+        case IEMMODE_64BIT:
+            switch (pIemCpu->enmEffAddrMode)
+            {
+                case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_4); /* cannot be encoded */ break;
+                case IEMMODE_32BIT: IEM_CMPS_CASE(64, 32); break;
+                case IEMMODE_64BIT: IEM_CMPS_CASE(64, 64); break;
+                IEM_NOT_REACHED_DEFAULT_CASE_RET();
+            }
+            break;
+        IEM_NOT_REACHED_DEFAULT_CASE_RET();
+    }
+    return VINF_SUCCESS;
+
+}
+
+#undef IEM_CMPS_CASE
 
 /** Opcode 0xa8. */
@@ -5971,5 +6765,5 @@
 
     /*
-     * Use the C implementation if a repeate prefix is encountered.
+     * Use the C implementation if a repeat prefix is encountered.
      */
     if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
@@ -6006,5 +6800,5 @@
 
     /*
-     * Use the C implementation if a repeate prefix is encountered.
+     * Use the C implementation if a repeat prefix is encountered.
      */
     if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
@@ -6107,5 +6901,5 @@
 
     /*
-     * Use the C implementation if a repeate prefix is encountered.
+     * Use the C implementation if a repeat prefix is encountered.
      */
     if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
@@ -6142,5 +6936,5 @@
 
     /*
-     * Use the C implementation if a repeate prefix is encountered.
+     * Use the C implementation if a repeat prefix is encountered.
      */
     if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
@@ -6221,8 +7015,189 @@
 #undef IEM_LODS_CASE
 
+/** Macro used by iemOp_scasb_AL_Xb and iemOp_scaswd_eAX_Xv */
+#define IEM_SCAS_CASE(ValBits, AddrBits) \
+        IEM_MC_BEGIN(1, 2); \
+        IEM_MC_ARG(uint##ValBits##_t *, puRax,   0); \
+        IEM_MC_ARG(uint##ValBits##_t,   uValue,  1); \
+        IEM_MC_ARG(uint32_t *,          pEFlags, 2); \
+        IEM_MC_LOCAL(uint##AddrBits##_t, uAddr); \
+        \
+        IEM_MC_FETCH_GREG_U##AddrBits(uAddr, X86_GREG_xDI); \
+        IEM_MC_FETCH_MEM_U##ValBits(uValue, X86_SREG_ES, uAddr); \
+        IEM_MC_REF_GREG_U##ValBits(puRax, X86_GREG_xAX); \
+        IEM_MC_REF_EFLAGS(pEFlags); \
+        IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_cmp_u##ValBits, puRax, uValue, pEFlags); \
+        \
+        IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
+            IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
+        } IEM_MC_ELSE() { \
+            IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xDI, ValBits / 8); \
+        } IEM_MC_ENDIF(); \
+        IEM_MC_ADVANCE_RIP(); \
+        IEM_MC_END();
+
 /** Opcode 0xae. */
-FNIEMOP_STUB(iemOp_scasb_AL_Xb);
+FNIEMOP_DEF(iemOp_scasb_AL_Xb)
+{
+    IEMOP_HLP_NO_LOCK_PREFIX();
+
+    /*
+     * Use the C implementation if a repeat prefix is encountered.
+     */
+    if (pIemCpu->fPrefixes & IEM_OP_PRF_REPZ)
+    {
+        IEMOP_MNEMONIC("repe scasb al,Xb");
+        switch (pIemCpu->enmEffAddrMode)
+        {
+            case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_al_m16);
+            case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_al_m32);
+            case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_al_m64);
+            IEM_NOT_REACHED_DEFAULT_CASE_RET();
+        }
+    }
+    if (pIemCpu->fPrefixes & IEM_OP_PRF_REPNZ)
+    {
+        IEMOP_MNEMONIC("repne scasb al,Xb");
+        switch (pIemCpu->enmEffAddrMode)
+        {
+            case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_al_m16);
+            case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_al_m32);
+            case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repne_scas_al_m64);
+            IEM_NOT_REACHED_DEFAULT_CASE_RET();
+        }
+    }
+    IEMOP_MNEMONIC("scasb al,Xb");
+
+    /*
+     * Sharing case implementation with stos[wdq] below.
+     */
+    switch (pIemCpu->enmEffAddrMode)
+    {
+        case IEMMODE_16BIT: IEM_SCAS_CASE(8, 16); break;
+        case IEMMODE_32BIT: IEM_SCAS_CASE(8, 32); break;
+        case IEMMODE_64BIT: IEM_SCAS_CASE(8, 64); break;
+        IEM_NOT_REACHED_DEFAULT_CASE_RET();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0xaf. */
-FNIEMOP_STUB(iemOp_scaswd_eAX_Xv);
+FNIEMOP_DEF(iemOp_scaswd_eAX_Xv)
+{
+    IEMOP_HLP_NO_LOCK_PREFIX();
+
+    /*
+     * Use the C implementation if a repeat prefix is encountered.
+     */
+    if (pIemCpu->fPrefixes & IEM_OP_PRF_REPZ)
+    {
+        IEMOP_MNEMONIC("repe scas rAX,Xv");
+        switch (pIemCpu->enmEffOpSize)
+        {
+            case IEMMODE_16BIT:
+                switch (pIemCpu->enmEffAddrMode)
+                {
+                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_ax_m16);
+                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_ax_m32);
+                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_ax_m64);
+                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
+                }
+                break;
+            case IEMMODE_32BIT:
+                switch (pIemCpu->enmEffAddrMode)
+                {
+                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_eax_m16);
+                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_eax_m32);
+                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_eax_m64);
+                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
+                }
+            case IEMMODE_64BIT:
+                switch (pIemCpu->enmEffAddrMode)
+                {
+                    case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_3); /** @todo It's this wrong, we can do 16-bit addressing in 64-bit mode, but not 32-bit. right? */
+                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_rax_m32);
+                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_rax_m64);
+                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
+                }
+            IEM_NOT_REACHED_DEFAULT_CASE_RET();
+        }
+    }
+    if (pIemCpu->fPrefixes & IEM_OP_PRF_REPNZ)
+    {
+        IEMOP_MNEMONIC("repne scas rAX,Xv");
+        switch (pIemCpu->enmEffOpSize)
+        {
+            case IEMMODE_16BIT:
+                switch (pIemCpu->enmEffAddrMode)
+                {
+                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_ax_m16);
+                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_ax_m32);
+                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_ax_m64);
+                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
+                }
+                break;
+            case IEMMODE_32BIT:
+                switch (pIemCpu->enmEffAddrMode)
+                {
+                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_eax_m16);
+                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_eax_m32);
+                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_eax_m64);
+                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
+                }
+            case IEMMODE_64BIT:
+                switch (pIemCpu->enmEffAddrMode)
+                {
+                    case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_3);
+                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_rax_m32);
+                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_repe_scas_rax_m64);
+                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
+                }
+            IEM_NOT_REACHED_DEFAULT_CASE_RET();
+        }
+    }
+    IEMOP_MNEMONIC("scas rAX,Xv");
+
+    /*
+     * Annoying double switch here.
+     * Using ugly macro for implementing the cases, sharing it with scasb.
+     */
+    switch (pIemCpu->enmEffOpSize)
+    {
+        case IEMMODE_16BIT:
+            switch (pIemCpu->enmEffAddrMode)
+            {
+                case IEMMODE_16BIT: IEM_SCAS_CASE(16, 16); break;
+                case IEMMODE_32BIT: IEM_SCAS_CASE(16, 32); break;
+                case IEMMODE_64BIT: IEM_SCAS_CASE(16, 64); break;
+                IEM_NOT_REACHED_DEFAULT_CASE_RET();
+            }
+            break;
+
+        case IEMMODE_32BIT:
+            switch (pIemCpu->enmEffAddrMode)
+            {
+                case IEMMODE_16BIT: IEM_SCAS_CASE(32, 16); break;
+                case IEMMODE_32BIT: IEM_SCAS_CASE(32, 32); break;
+                case IEMMODE_64BIT: IEM_SCAS_CASE(32, 64); break;
+                IEM_NOT_REACHED_DEFAULT_CASE_RET();
+            }
+            break;
+
+        case IEMMODE_64BIT:
+            switch (pIemCpu->enmEffAddrMode)
+            {
+                case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_4); /* cannot be encoded */ break;
+                case IEMMODE_32BIT: IEM_SCAS_CASE(64, 32); break;
+                case IEMMODE_64BIT: IEM_SCAS_CASE(64, 64); break;
+                IEM_NOT_REACHED_DEFAULT_CASE_RET();
+            }
+            break;
+        IEM_NOT_REACHED_DEFAULT_CASE_RET();
+    }
+    return VINF_SUCCESS;
+}
+
+#undef IEM_SCAS_CASE
 
 /**
@@ -8678,10 +9653,10 @@
  * @param   bRm             The RM byte.
  */
-FNIEMOP_DEF_1(iemOp_Grp5_jmpf_Ep, uint8_t, bRm)
-{
-    /* decode and use a C worker.  */
-    AssertFailed(); // FNIEMOP_STUB
-    return VERR_NOT_IMPLEMENTED;
-}
+FNIEMOP_STUB_1(iemOp_Grp5_jmpf_Ep, uint8_t, bRm);
+//{
+//    /* decode and use a C worker.  */
+//    AssertFailed(); // FNIEMOP_STUB
+//    return VERR_NOT_IMPLEMENTED;
+//}
 
 
Index: trunk/src/VBox/VMM/include/IEMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/IEMInternal.h	(revision 36828)
+++ trunk/src/VBox/VMM/include/IEMInternal.h	(revision 36829)
@@ -171,5 +171,8 @@
      * than what AMD and REM does. */
     bool                    fShiftOfHack;
-    bool                    afAlignment1[6];
+    /** Set if no comparison to REM is currently performed.
+     * This is used to skip past really slow bits.  */
+    bool                    fNoRem;
+    bool                    afAlignment1[5];
     /** The physical address corresponding to abOpcodes[0]. */
     RTGCPHYS                GCPhysOpcodes;
@@ -338,5 +341,15 @@
 /** @} */
 
-
+/**
+ * Tests if verification mode is enabled.
+ *
+ * This expands to @c false when IEM_VERIFICATION_MODE is not defined and
+ * should therefore cause the compiler to eliminate the verification branch
+ * of an if statement.  */
+#ifdef IEM_VERIFICATION_MODE
+# define IEM_VERIFICATION_ENABLED(a_pIemCpu)    ((a_pIemCpu)->fNoRem)
+#else
+# define IEM_VERIFICATION_ENABLED(a_pIemCpu)    (false)
+#endif
 
 
