Index: trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm	(revision 96762)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm	(revision 96789)
@@ -5961,2 +5961,95 @@
         EPILOGUE_3_ARGS
 ENDPROC             iemAImpl_vcomisd_u128
+
+
+;;
+; Need to move this as well somewhere better?
+;
+struc IEMMEDIAF2XMMSRC
+    .uSrc1        resd 4
+    .uSrc2        resd 4
+endstruc
+
+
+;
+; CMPPS (SSE)
+;
+; @param    A0      Pointer to the MXCSR value (input/output).
+; @param    A1      Pointer to the first media register size operand (output).
+; @param    A2      Pointer to the two media register sized inputs - IEMMEDIAF2XMMSRC (input).
+; @param    A3      The 8-bit immediate (input).
+;
+BEGINPROC_FASTCALL iemAImpl_cmpps_u128, 16
+        PROLOGUE_4_ARGS
+        IEMIMPL_SSE_PROLOGUE
+        SSE_LD_FXSTATE_MXCSR_ONLY A0
+
+        movdqu  xmm0, [A2 + IEMMEDIAF2XMMSRC.uSrc1]
+        movdqu  xmm1, [A2 + IEMMEDIAF2XMMSRC.uSrc2]
+        lea     T0, [A3 + A3*4]         ; sizeof(cmpps+ret) == 5
+        lea     T1, [.imm0 xWrtRIP]
+        lea     T1, [T1 + T0]
+        call    T1
+        movdqu  [A1], xmm0
+
+        SSE_ST_FXSTATE_MXCSR_ONLY_NO_FXSTATE A0
+        IEMIMPL_SSE_EPILOGUE
+        EPILOGUE_4_ARGS
+ %assign bImm 0
+ %rep 256
+.imm %+ bImm:
+       cmpps xmm0, xmm1, bImm
+       ret
+  %assign bImm bImm + 1
+ %endrep
+.immEnd:                                ; 256*5 == 0x500
+dw 0xfaff  + (.immEnd - .imm0)          ; will cause warning if entries are too big.
+dw 0x104ff - (.immEnd - .imm0)          ; will cause warning if entries are too small.
+ENDPROC iemAImpl_cmpps_u128
+
+;;
+; SSE instructions with 8-bit immediates of the form
+;    xxx xmm1, xmm2, imm8.
+; where the instruction encoding takes up 5 bytes and we need to load and save the MXCSR
+; register.
+;
+; @param    1       The instruction name.
+;
+; @param    A0      Pointer to the MXCSR value (input/output).
+; @param    A1      Pointer to the first media register size operand (output).
+; @param    A2      Pointer to the two media register sized inputs - IEMMEDIAF2XMMSRC (input).
+; @param    A3      The 8-bit immediate (input).
+;
+%macro IEMIMPL_MEDIA_SSE_INSN_IMM8_MXCSR_5 1
+BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u128, 16
+        PROLOGUE_4_ARGS
+        IEMIMPL_SSE_PROLOGUE
+        SSE_LD_FXSTATE_MXCSR_ONLY A0
+
+        movdqu  xmm0, [A2 + IEMMEDIAF2XMMSRC.uSrc1]
+        movdqu  xmm1, [A2 + IEMMEDIAF2XMMSRC.uSrc2]
+        lea     T1, [.imm0 xWrtRIP]
+        lea     T0, [A3 + A3*2]         ; sizeof(pshufXX+ret) == 6: (A3 * 3) *2
+        lea     T1, [T1 + T0*2]
+        call    T1
+        movdqu  [A1], xmm0
+
+        SSE_ST_FXSTATE_MXCSR_ONLY_NO_FXSTATE A0
+        IEMIMPL_SSE_EPILOGUE
+        EPILOGUE_4_ARGS
+ %assign bImm 0
+ %rep 256
+.imm %+ bImm:
+       %1       xmm0, xmm1, bImm
+       ret
+  %assign bImm bImm + 1
+ %endrep
+.immEnd:                                ; 256*6 == 0x600
+dw 0xf9ff  + (.immEnd - .imm0)          ; will cause warning if entries are too big.
+dw 0x105ff - (.immEnd - .imm0)          ; will cause warning if entries are too small.
+ENDPROC iemAImpl_ %+ %1 %+ _u128
+%endmacro
+
+IEMIMPL_MEDIA_SSE_INSN_IMM8_MXCSR_5 cmppd
+IEMIMPL_MEDIA_SSE_INSN_IMM8_MXCSR_5 cmpss
+IEMIMPL_MEDIA_SSE_INSN_IMM8_MXCSR_5 cmpsd
Index: trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp	(revision 96762)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp	(revision 96789)
@@ -16346,2 +16346,168 @@
     iemAImpl_comisd_u128(pfMxcsr, pfEFlags, puSrc1, puSrc2);
 }
+
+
+/**
+ * CMPPS / CMPPD / CMPSS / CMPSD
+ */
+#ifdef IEM_WITHOUT_ASSEMBLY
+/**
+ * A compare truth table entry.
+ */
+typedef struct CMPTRUTHTBLENTRY
+{
+    /** Flag whether the \#IA is signalled when one of the source oeprans is a QNaN */
+    bool                fSignalsOnQNan;
+    /** The boolean result when the input operands are unordered. */
+    bool                fUnordered;
+    /** The boolean result when A = B. */
+    bool                fEqual;
+    /** The boolean result when A < B. */
+    bool                fLowerThan;
+    /** The boolean result when A > B. */
+    bool                fGreaterThan;
+} CMPTRUTHTBLENTRY;
+/** Pointer to a const truth table entry. */
+typedef const CMPTRUTHTBLENTRY *PCCMPTRUTHTBLENTRY;
+
+
+/** The compare truth table (indexed by immediate). */
+static const CMPTRUTHTBLENTRY g_aCmpTbl[] =
+{
+                            /* fSignalsOnQNan   fUnordered      fEqual      fLowerThan      fGreaterThan */
+    /* 00H (EQ_OQ)   */     {  false,           false,          true,       false,          false           },
+    /* 01H (LT_OS)   */     {  true,            false,          false,      true,           false           },
+    /* 02H (LE_OS)   */     {  true,            false,          true,       true,           false           },
+    /* 03H (UNORD_Q) */     {  false,           true,           false,      false,          false           },
+    /* 04H (NEQ_UQ)  */     {  false,           true,           false,      true,           true            },
+    /* 05H (NLT_US)  */     {  true,            true,           true,       false,          true            },
+    /* 06H (NLE_US)  */     {  true,            true,           false,      false,          true            },
+    /* 07H (ORQ_Q)   */     {  false,           false,          true,       true,           true            },
+    /** @todo AVX variants. */
+};
+
+
+static bool iemAImpl_cmp_worker_r32(uint32_t *pfMxcsr, PCRTFLOAT32U pr32Src1, PCRTFLOAT32U pr32Src2, uint8_t bEvil)
+{
+    AssertRelease(bEvil < RT_ELEMENTS(g_aCmpTbl));
+
+    if (RTFLOAT32U_IS_SIGNALLING_NAN(pr32Src1) || RTFLOAT32U_IS_SIGNALLING_NAN(pr32Src2))
+    {
+        *pfMxcsr |= X86_MXCSR_IE;
+        return g_aCmpTbl[bEvil].fUnordered;
+    }
+    else if (RTFLOAT32U_IS_QUIET_NAN(pr32Src1) || RTFLOAT32U_IS_QUIET_NAN(pr32Src2))
+    {
+        if (g_aCmpTbl[bEvil].fSignalsOnQNan)
+            *pfMxcsr |= X86_MXCSR_IE;
+        return g_aCmpTbl[bEvil].fUnordered;
+    }
+    else
+    {
+        softfloat_state_t SoftState = IEM_SOFTFLOAT_STATE_INITIALIZER_FROM_MXCSR(*pfMxcsr);
+
+        RTFLOAT32U r32Src1, r32Src2;
+        uint32_t fDe  = iemSsePrepareValueR32(&r32Src1, *pfMxcsr, pr32Src1);
+                 fDe |= iemSsePrepareValueR32(&r32Src2, *pfMxcsr, pr32Src2);
+
+        *pfMxcsr |= fDe;
+        float32_t f32Src1 = iemFpSoftF32FromIprt(&r32Src1);
+        float32_t f32Src2 = iemFpSoftF32FromIprt(&r32Src2);
+        if (f32_eq(f32Src1, f32Src2, &SoftState))
+            return g_aCmpTbl[bEvil].fEqual;
+        else if (f32_lt(f32Src1, f32Src2, &SoftState))
+            return g_aCmpTbl[bEvil].fLowerThan;
+        else
+            return g_aCmpTbl[bEvil].fGreaterThan;
+    }
+
+    AssertReleaseFailed();
+    return false;
+}
+
+
+static bool iemAImpl_cmp_worker_r64(uint32_t *pfMxcsr, PCRTFLOAT64U pr64Src1, PCRTFLOAT64U pr64Src2, uint8_t bEvil)
+{
+    AssertRelease(bEvil < RT_ELEMENTS(g_aCmpTbl));
+
+    if (RTFLOAT64U_IS_SIGNALLING_NAN(pr64Src1) || RTFLOAT64U_IS_SIGNALLING_NAN(pr64Src2))
+    {
+        *pfMxcsr |= X86_MXCSR_IE;
+        return g_aCmpTbl[bEvil].fUnordered;
+    }
+    else if (RTFLOAT64U_IS_QUIET_NAN(pr64Src1) || RTFLOAT64U_IS_QUIET_NAN(pr64Src2))
+    {
+        if (g_aCmpTbl[bEvil].fSignalsOnQNan)
+            *pfMxcsr |= X86_MXCSR_IE;
+        return g_aCmpTbl[bEvil].fUnordered;
+    }
+    else
+    {
+        softfloat_state_t SoftState = IEM_SOFTFLOAT_STATE_INITIALIZER_FROM_MXCSR(*pfMxcsr);
+
+        RTFLOAT64U r64Src1, r64Src2;
+        uint32_t fDe  = iemSsePrepareValueR64(&r64Src1, *pfMxcsr, pr64Src1);
+                 fDe |= iemSsePrepareValueR64(&r64Src2, *pfMxcsr, pr64Src2);
+
+        *pfMxcsr |= fDe;
+        float64_t f64Src1 = iemFpSoftF64FromIprt(&r64Src1);
+        float64_t f64Src2 = iemFpSoftF64FromIprt(&r64Src2);
+        if (f64_eq(f64Src1, f64Src2, &SoftState))
+            return g_aCmpTbl[bEvil].fEqual;
+        else if (f64_lt(f64Src1, f64Src2, &SoftState))
+            return g_aCmpTbl[bEvil].fLowerThan;
+        else
+            return g_aCmpTbl[bEvil].fGreaterThan;
+    }
+
+    AssertReleaseFailed();
+    return false;
+}
+
+
+IEM_DECL_IMPL_DEF(void, iemAImpl_cmpps_u128,(uint32_t *pfMxcsr, PX86XMMREG puDst, PCIEMMEDIAF2XMMSRC pSrc, uint8_t bEvil))
+{
+    for (uint8_t i = 0; i < RT_ELEMENTS(puDst->ar32); i++)
+    {
+        if (iemAImpl_cmp_worker_r32(pfMxcsr, &pSrc->uSrc1.ar32[i], &pSrc->uSrc2.ar32[i], bEvil & 0x7))
+            puDst->au32[i] = UINT32_MAX;
+        else
+            puDst->au32[i] = 0;
+    }
+}
+
+
+IEM_DECL_IMPL_DEF(void, iemAImpl_cmppd_u128,(uint32_t *pfMxcsr, PX86XMMREG puDst, PCIEMMEDIAF2XMMSRC pSrc, uint8_t bEvil))
+{
+    for (uint8_t i = 0; i < RT_ELEMENTS(puDst->ar64); i++)
+    {
+        if (iemAImpl_cmp_worker_r64(pfMxcsr, &pSrc->uSrc1.ar64[i], &pSrc->uSrc2.ar64[i], bEvil & 0x7))
+            puDst->au64[i] = UINT64_MAX;
+        else
+            puDst->au64[i] = 0;
+    }
+}
+
+
+IEM_DECL_IMPL_DEF(void, iemAImpl_cmpss_u128,(uint32_t *pfMxcsr, PX86XMMREG puDst, PCIEMMEDIAF2XMMSRC pSrc, uint8_t bEvil))
+{
+    if (iemAImpl_cmp_worker_r32(pfMxcsr, &pSrc->uSrc1.ar32[0], &pSrc->uSrc2.ar32[0], bEvil & 0x7))
+        puDst->au32[0] = UINT32_MAX;
+    else
+        puDst->au32[0] = 0;
+
+    puDst->au32[1] = pSrc->uSrc1.au32[1];
+    puDst->au64[1] = pSrc->uSrc1.au64[1];
+}
+
+
+IEM_DECL_IMPL_DEF(void, iemAImpl_cmpsd_u128,(uint32_t *pfMxcsr, PX86XMMREG puDst, PCIEMMEDIAF2XMMSRC pSrc, uint8_t bEvil))
+{
+    if (iemAImpl_cmp_worker_r64(pfMxcsr, &pSrc->uSrc1.ar64[0], &pSrc->uSrc2.ar64[0], bEvil & 0x7))
+        puDst->au64[0] = UINT64_MAX;
+    else
+        puDst->au64[0] = 0;
+
+    puDst->au64[1] = pSrc->uSrc1.au64[1];
+}
+#endif
Index: trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h	(revision 96762)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h	(revision 96789)
@@ -10955,11 +10955,289 @@
 
 /** Opcode      0x0f 0xc2 - cmpps Vps,Wps,Ib */
-FNIEMOP_STUB(iemOp_cmpps_Vps_Wps_Ib);
+FNIEMOP_DEF(iemOp_cmpps_Vps_Wps_Ib)
+{
+    IEMOP_MNEMONIC3(RMI, CMPPS, cmpps, Vps, Wps, Ib, DISOPTYPE_HARMLESS | DISOPTYPE_SSE, 0);
+
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+    if (IEM_IS_MODRM_REG_MODE(bRm))
+    {
+        /*
+         * Register, register.
+         */
+        uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm);
+        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
+        IEM_MC_BEGIN(4, 2);
+        IEM_MC_LOCAL(IEMMEDIAF2XMMSRC,              Src);
+        IEM_MC_LOCAL(X86XMMREG,                     Dst);
+        IEM_MC_ARG(uint32_t *,                      pfMxcsr,                0);
+        IEM_MC_ARG_LOCAL_REF(PX86XMMREG,            pDst,           Dst,    1);
+        IEM_MC_ARG_LOCAL_REF(PCIEMMEDIAF2XMMSRC,    pSrc,           Src,    2);
+        IEM_MC_ARG_CONST(uint8_t,                   bImmArg, /*=*/ bImm,    3);
+        IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
+        IEM_MC_PREPARE_SSE_USAGE();
+        IEM_MC_REF_MXCSR(pfMxcsr);
+        IEM_MC_FETCH_XREG_XMM(Src.uSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
+        IEM_MC_FETCH_XREG_XMM(Src.uSrc2, IEM_GET_MODRM_RM(pVCpu, bRm));
+        IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpps_u128, pfMxcsr, pDst, pSrc, bImmArg);
+        IEM_MC_IF_MXCSR_XCPT_PENDING()
+            IEM_MC_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
+        IEM_MC_ELSE()
+            IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), Dst);
+        IEM_MC_ENDIF();
+
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /*
+         * Register, memory.
+         */
+        IEM_MC_BEGIN(4, 3);
+        IEM_MC_LOCAL(IEMMEDIAF2XMMSRC,              Src);
+        IEM_MC_LOCAL(X86XMMREG,                     Dst);
+        IEM_MC_ARG(uint32_t *,                      pfMxcsr,                0);
+        IEM_MC_ARG_LOCAL_REF(PX86XMMREG,            pDst,           Dst,    1);
+        IEM_MC_ARG_LOCAL_REF(PCIEMMEDIAF2XMMSRC,    pSrc,           Src,    2);
+        IEM_MC_LOCAL(RTGCPTR,                       GCPtrEffSrc);
+
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
+        uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm);
+        IEM_MC_ARG_CONST(uint8_t,                   bImmArg, /*=*/ bImm,    3);
+        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
+        IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
+        IEM_MC_FETCH_MEM_XMM_ALIGN_SSE(Src.uSrc2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
+
+        IEM_MC_PREPARE_SSE_USAGE();
+        IEM_MC_REF_MXCSR(pfMxcsr);
+        IEM_MC_FETCH_XREG_XMM(Src.uSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
+        IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpps_u128, pfMxcsr, pDst, pSrc, bImmArg);
+        IEM_MC_IF_MXCSR_XCPT_PENDING()
+            IEM_MC_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
+        IEM_MC_ELSE()
+            IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), Dst);
+        IEM_MC_ENDIF();
+
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0x66 0x0f 0xc2 - cmppd Vpd,Wpd,Ib */
-FNIEMOP_STUB(iemOp_cmppd_Vpd_Wpd_Ib);
+FNIEMOP_DEF(iemOp_cmppd_Vpd_Wpd_Ib)
+{
+    IEMOP_MNEMONIC3(RMI, CMPPD, cmppd, Vpd, Wpd, Ib, DISOPTYPE_HARMLESS | DISOPTYPE_SSE, 0);
+
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+    if (IEM_IS_MODRM_REG_MODE(bRm))
+    {
+        /*
+         * Register, register.
+         */
+        uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm);
+        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
+        IEM_MC_BEGIN(4, 2);
+        IEM_MC_LOCAL(IEMMEDIAF2XMMSRC,              Src);
+        IEM_MC_LOCAL(X86XMMREG,                     Dst);
+        IEM_MC_ARG(uint32_t *,                      pfMxcsr,                0);
+        IEM_MC_ARG_LOCAL_REF(PX86XMMREG,            pDst,           Dst,    1);
+        IEM_MC_ARG_LOCAL_REF(PCIEMMEDIAF2XMMSRC,    pSrc,           Src,    2);
+        IEM_MC_ARG_CONST(uint8_t,                   bImmArg, /*=*/ bImm,    3);
+        IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
+        IEM_MC_PREPARE_SSE_USAGE();
+        IEM_MC_REF_MXCSR(pfMxcsr);
+        IEM_MC_FETCH_XREG_XMM(Src.uSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
+        IEM_MC_FETCH_XREG_XMM(Src.uSrc2, IEM_GET_MODRM_RM(pVCpu, bRm));
+        IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmppd_u128, pfMxcsr, pDst, pSrc, bImmArg);
+        IEM_MC_IF_MXCSR_XCPT_PENDING()
+            IEM_MC_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
+        IEM_MC_ELSE()
+            IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), Dst);
+        IEM_MC_ENDIF();
+
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /*
+         * Register, memory.
+         */
+        IEM_MC_BEGIN(4, 3);
+        IEM_MC_LOCAL(IEMMEDIAF2XMMSRC,              Src);
+        IEM_MC_LOCAL(X86XMMREG,                     Dst);
+        IEM_MC_ARG(uint32_t *,                      pfMxcsr,                0);
+        IEM_MC_ARG_LOCAL_REF(PX86XMMREG,            pDst,           Dst,    1);
+        IEM_MC_ARG_LOCAL_REF(PCIEMMEDIAF2XMMSRC,    pSrc,           Src,    2);
+        IEM_MC_LOCAL(RTGCPTR,                       GCPtrEffSrc);
+
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
+        uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm);
+        IEM_MC_ARG_CONST(uint8_t,                   bImmArg, /*=*/ bImm,    3);
+        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
+        IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
+        IEM_MC_FETCH_MEM_XMM_ALIGN_SSE(Src.uSrc2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
+
+        IEM_MC_PREPARE_SSE_USAGE();
+        IEM_MC_REF_MXCSR(pfMxcsr);
+        IEM_MC_FETCH_XREG_XMM(Src.uSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
+        IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmppd_u128, pfMxcsr, pDst, pSrc, bImmArg);
+        IEM_MC_IF_MXCSR_XCPT_PENDING()
+            IEM_MC_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
+        IEM_MC_ELSE()
+            IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), Dst);
+        IEM_MC_ENDIF();
+
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0xf3 0x0f 0xc2 - cmpss Vss,Wss,Ib */
-FNIEMOP_STUB(iemOp_cmpss_Vss_Wss_Ib);
+FNIEMOP_DEF(iemOp_cmpss_Vss_Wss_Ib)
+{
+    IEMOP_MNEMONIC3(RMI, CMPSS, cmpss, Vss, Wss, Ib, DISOPTYPE_HARMLESS | DISOPTYPE_SSE, 0);
+
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+    if (IEM_IS_MODRM_REG_MODE(bRm))
+    {
+        /*
+         * Register, register.
+         */
+        uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm);
+        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
+        IEM_MC_BEGIN(4, 2);
+        IEM_MC_LOCAL(IEMMEDIAF2XMMSRC,              Src);
+        IEM_MC_LOCAL(X86XMMREG,                     Dst);
+        IEM_MC_ARG(uint32_t *,                      pfMxcsr,                0);
+        IEM_MC_ARG_LOCAL_REF(PX86XMMREG,            pDst,           Dst,    1);
+        IEM_MC_ARG_LOCAL_REF(PCIEMMEDIAF2XMMSRC,    pSrc,           Src,    2);
+        IEM_MC_ARG_CONST(uint8_t,                   bImmArg, /*=*/ bImm,    3);
+        IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
+        IEM_MC_PREPARE_SSE_USAGE();
+        IEM_MC_REF_MXCSR(pfMxcsr);
+        IEM_MC_FETCH_XREG_XMM(Src.uSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
+        IEM_MC_FETCH_XREG_XMM(Src.uSrc2, IEM_GET_MODRM_RM(pVCpu, bRm));
+        IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpss_u128, pfMxcsr, pDst, pSrc, bImmArg);
+        IEM_MC_IF_MXCSR_XCPT_PENDING()
+            IEM_MC_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
+        IEM_MC_ELSE()
+            IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), Dst);
+        IEM_MC_ENDIF();
+
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /*
+         * Register, memory.
+         */
+        IEM_MC_BEGIN(4, 3);
+        IEM_MC_LOCAL(IEMMEDIAF2XMMSRC,              Src);
+        IEM_MC_LOCAL(X86XMMREG,                     Dst);
+        IEM_MC_ARG(uint32_t *,                      pfMxcsr,                0);
+        IEM_MC_ARG_LOCAL_REF(PX86XMMREG,            pDst,           Dst,    1);
+        IEM_MC_ARG_LOCAL_REF(PCIEMMEDIAF2XMMSRC,    pSrc,           Src,    2);
+        IEM_MC_LOCAL(RTGCPTR,                       GCPtrEffSrc);
+
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
+        uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm);
+        IEM_MC_ARG_CONST(uint8_t,                   bImmArg, /*=*/ bImm,    3);
+        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
+        IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
+        IEM_MC_FETCH_MEM_XMM_U32(Src.uSrc2, 0 /*a_iDword */, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
+
+        IEM_MC_PREPARE_SSE_USAGE();
+        IEM_MC_REF_MXCSR(pfMxcsr);
+        IEM_MC_FETCH_XREG_XMM(Src.uSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
+        IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpss_u128, pfMxcsr, pDst, pSrc, bImmArg);
+        IEM_MC_IF_MXCSR_XCPT_PENDING()
+            IEM_MC_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
+        IEM_MC_ELSE()
+            IEM_MC_STORE_XREG_XMM_U32(IEM_GET_MODRM_REG(pVCpu, bRm), 0 /*a_iDword*/, Dst);
+        IEM_MC_ENDIF();
+
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
+
+
 /** Opcode 0xf2 0x0f 0xc2 - cmpsd Vsd,Wsd,Ib */
-FNIEMOP_STUB(iemOp_cmpsd_Vsd_Wsd_Ib);
+FNIEMOP_DEF(iemOp_cmpsd_Vsd_Wsd_Ib)
+{
+    IEMOP_MNEMONIC3(RMI, CMPSD, cmpsd, Vsd, Wsd, Ib, DISOPTYPE_HARMLESS | DISOPTYPE_SSE, 0);
+
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+    if (IEM_IS_MODRM_REG_MODE(bRm))
+    {
+        /*
+         * Register, register.
+         */
+        uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm);
+        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
+        IEM_MC_BEGIN(4, 2);
+        IEM_MC_LOCAL(IEMMEDIAF2XMMSRC,              Src);
+        IEM_MC_LOCAL(X86XMMREG,                     Dst);
+        IEM_MC_ARG(uint32_t *,                      pfMxcsr,                0);
+        IEM_MC_ARG_LOCAL_REF(PX86XMMREG,            pDst,           Dst,    1);
+        IEM_MC_ARG_LOCAL_REF(PCIEMMEDIAF2XMMSRC,    pSrc,           Src,    2);
+        IEM_MC_ARG_CONST(uint8_t,                   bImmArg, /*=*/ bImm,    3);
+        IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
+        IEM_MC_PREPARE_SSE_USAGE();
+        IEM_MC_REF_MXCSR(pfMxcsr);
+        IEM_MC_FETCH_XREG_XMM(Src.uSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
+        IEM_MC_FETCH_XREG_XMM(Src.uSrc2, IEM_GET_MODRM_RM(pVCpu, bRm));
+        IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpsd_u128, pfMxcsr, pDst, pSrc, bImmArg);
+        IEM_MC_IF_MXCSR_XCPT_PENDING()
+            IEM_MC_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
+        IEM_MC_ELSE()
+            IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), Dst);
+        IEM_MC_ENDIF();
+
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    else
+    {
+        /*
+         * Register, memory.
+         */
+        IEM_MC_BEGIN(4, 3);
+        IEM_MC_LOCAL(IEMMEDIAF2XMMSRC,              Src);
+        IEM_MC_LOCAL(X86XMMREG,                     Dst);
+        IEM_MC_ARG(uint32_t *,                      pfMxcsr,                0);
+        IEM_MC_ARG_LOCAL_REF(PX86XMMREG,            pDst,           Dst,    1);
+        IEM_MC_ARG_LOCAL_REF(PCIEMMEDIAF2XMMSRC,    pSrc,           Src,    2);
+        IEM_MC_LOCAL(RTGCPTR,                       GCPtrEffSrc);
+
+        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
+        uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm);
+        IEM_MC_ARG_CONST(uint8_t,                   bImmArg, /*=*/ bImm,    3);
+        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
+        IEM_MC_MAYBE_RAISE_SSE2_RELATED_XCPT();
+        IEM_MC_FETCH_MEM_XMM_U32(Src.uSrc2, 0 /*a_iDword */, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
+
+        IEM_MC_PREPARE_SSE_USAGE();
+        IEM_MC_REF_MXCSR(pfMxcsr);
+        IEM_MC_FETCH_XREG_XMM(Src.uSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
+        IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpsd_u128, pfMxcsr, pDst, pSrc, bImmArg);
+        IEM_MC_IF_MXCSR_XCPT_PENDING()
+            IEM_MC_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
+        IEM_MC_ELSE()
+            IEM_MC_STORE_XREG_XMM_U32(IEM_GET_MODRM_REG(pVCpu, bRm), 0 /*a_iDword*/, Dst);
+        IEM_MC_ENDIF();
+
+        IEM_MC_ADVANCE_RIP();
+        IEM_MC_END();
+    }
+    return VINF_SUCCESS;
+}
 
 
Index: trunk/src/VBox/VMM/include/IEMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/IEMInternal.h	(revision 96762)
+++ trunk/src/VBox/VMM/include/IEMInternal.h	(revision 96789)
@@ -2346,4 +2346,22 @@
 FNIEMAIMPLF2EFLMXCSR128 iemAImpl_comisd_u128;
 FNIEMAIMPLF2EFLMXCSR128 iemAImpl_vcomisd_u128, iemAImpl_vcomisd_u128_fallback;
+
+
+typedef struct IEMMEDIAF2XMMSRC
+{
+    X86XMMREG               uSrc1;
+    X86XMMREG               uSrc2;
+} IEMMEDIAF2XMMSRC;
+typedef IEMMEDIAF2XMMSRC *PIEMMEDIAF2XMMSRC;
+typedef const IEMMEDIAF2XMMSRC *PCIEMMEDIAF2XMMSRC;
+
+typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMXCSRF2XMMIMM8,(uint32_t *pfMxcsr, PX86XMMREG puDst, PCIEMMEDIAF2XMMSRC puSrc, uint8_t bEvil));
+typedef FNIEMAIMPLMXCSRF2XMMIMM8 *PFNIEMAIMPLMXCSRF2XMMIMM8;
+
+FNIEMAIMPLMXCSRF2XMMIMM8 iemAImpl_cmpps_u128;
+FNIEMAIMPLMXCSRF2XMMIMM8 iemAImpl_cmppd_u128;
+FNIEMAIMPLMXCSRF2XMMIMM8 iemAImpl_cmpss_u128;
+FNIEMAIMPLMXCSRF2XMMIMM8 iemAImpl_cmpsd_u128;
+
 /** @} */
 
Index: trunk/src/VBox/VMM/include/IEMMc.h
===================================================================
--- trunk/src/VBox/VMM/include/IEMMc.h	(revision 96762)
+++ trunk/src/VBox/VMM/include/IEMMc.h	(revision 96789)
@@ -452,4 +452,8 @@
          (a_u128Value).au64[1] = pVCpu->cpum.GstCtx.XState.x87.aXMM[(a_iXReg)].au64[1]; \
     } while (0)
+#define IEM_MC_FETCH_XREG_XMM(a_XmmValue, a_iXReg) \
+    do { (a_XmmValue).au64[0] = pVCpu->cpum.GstCtx.XState.x87.aXMM[(a_iXReg)].au64[0]; \
+         (a_XmmValue).au64[1] = pVCpu->cpum.GstCtx.XState.x87.aXMM[(a_iXReg)].au64[1]; \
+    } while (0)
 #define IEM_MC_FETCH_XREG_U64(a_u64Value, a_iXReg) \
     do { (a_u64Value) = pVCpu->cpum.GstCtx.XState.x87.aXMM[(a_iXReg)].au64[0]; } while (0)
@@ -462,4 +466,12 @@
          pVCpu->cpum.GstCtx.XState.x87.aXMM[(a_iXReg)].au64[1] = (a_u128Value).au64[1]; \
     } while (0)
+#define IEM_MC_STORE_XREG_XMM(a_iXReg, a_XmmValue) \
+    do { pVCpu->cpum.GstCtx.XState.x87.aXMM[(a_iXReg)].au64[0] = (a_XmmValue).au64[0]; \
+         pVCpu->cpum.GstCtx.XState.x87.aXMM[(a_iXReg)].au64[1] = (a_XmmValue).au64[1]; \
+    } while (0)
+#define IEM_MC_STORE_XREG_XMM_U32(a_iXReg, a_iDword, a_XmmValue) \
+    do { pVCpu->cpum.GstCtx.XState.x87.aXMM[(a_iXReg)].au32[(a_iDword)] = (a_XmmValue).au32[(a_iDword)]; } while (0)
+#define IEM_MC_STORE_XREG_XMM_U64(a_iXReg, a_iQword, a_XmmValue) \
+    do { pVCpu->cpum.GstCtx.XState.x87.aXMM[(a_iXReg)].au64[(a_iQword)] = (a_XmmValue).au64[(a_iQword)]; } while (0)
 #define IEM_MC_STORE_XREG_U64(a_iXReg, a_u64Value) \
     do { pVCpu->cpum.GstCtx.XState.x87.aXMM[(a_iXReg)].au64[0] = (a_u64Value); } while (0)
Index: trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp
===================================================================
--- trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp	(revision 96762)
+++ trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp	(revision 96789)
@@ -50,4 +50,5 @@
 uint8_t volatile    g_bRandom;
 RTUINT128U          g_u128Zero;
+X86XMMREG           g_XmmZero;
 
 
@@ -736,8 +737,12 @@
 
 #define IEM_MC_FETCH_XREG_U128(a_u128Value, a_iXReg)        do { (a_u128Value) = g_u128Zero; CHK_TYPE(RTUINT128U, a_u128Value); (void)fSseRead;  (void)fMcBegin; } while (0)
+#define IEM_MC_FETCH_XREG_XMM(a_XmmValue, a_iXReg)          do { (a_XmmValue) = g_XmmZero; CHK_TYPE(X86XMMREG, a_XmmValue); (void)fSseRead;  (void)fMcBegin; } while (0)
 #define IEM_MC_FETCH_XREG_U64(a_u64Value, a_iXReg)          do { (a_u64Value) = 0; CHK_TYPE(uint64_t, a_u64Value); (void)fSseRead; (void)fMcBegin; } while (0)
 #define IEM_MC_FETCH_XREG_U32(a_u32Value, a_iXReg)          do { (a_u32Value) = 0; CHK_TYPE(uint32_t, a_u32Value); (void)fSseRead; (void)fMcBegin; } while (0)
 #define IEM_MC_FETCH_XREG_HI_U64(a_u64Value, a_iXReg)       do { (a_u64Value) = 0; CHK_TYPE(uint64_t, a_u64Value); (void)fSseRead; (void)fMcBegin; } while (0)
 #define IEM_MC_STORE_XREG_U128(a_iXReg, a_u128Value)        do { CHK_TYPE(RTUINT128U, a_u128Value); (void)fSseWrite; (void)fMcBegin; } while (0)
+#define IEM_MC_STORE_XREG_XMM(a_iXReg, a_XmmValue)          do { CHK_TYPE(X86XMMREG, a_XmmValue); (void)fSseWrite; (void)fMcBegin; } while (0)
+#define IEM_MC_STORE_XREG_XMM_U32(a_iXReg, a_iDword, a_XmmValue)      do { CHK_TYPE(X86XMMREG, a_XmmValue);  AssertCompile((a_iDword) < RT_ELEMENTS((a_XmmValue).au32)); (void)fSseWrite; (void)fMcBegin; } while (0)
+#define IEM_MC_STORE_XREG_XMM_U64(a_iXReg, a_iQword, a_XmmValue)      do { CHK_TYPE(X86XMMREG, a_XmmValue);  AssertCompile((a_iQword) < RT_ELEMENTS((a_XmmValue).au64)); (void)fSseWrite; (void)fMcBegin; } while (0)
 #define IEM_MC_STORE_XREG_U64(a_iXReg, a_u64Value)          do { CHK_TYPE(uint64_t,  a_u64Value);  (void)fSseWrite; (void)fMcBegin; } while (0)
 #define IEM_MC_STORE_XREG_U64_ZX_U128(a_iXReg, a_u64Value)  do { CHK_TYPE(uint64_t,  a_u64Value);  (void)fSseWrite; (void)fMcBegin; } while (0)
