summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/VBox/VMM/VMMAll/IEMAllAImpl.asm47
-rw-r--r--src/VBox/VMM/VMMAll/IEMAllAImplC.cpp10
-rw-r--r--src/VBox/VMM/VMMAll/IEMAllInstructionsThree0f3a.cpp.h66
-rw-r--r--src/VBox/VMM/include/IEMInternal.h13
4 files changed, 135 insertions, 1 deletions
diff --git a/src/VBox/VMM/VMMAll/IEMAllAImpl.asm b/src/VBox/VMM/VMMAll/IEMAllAImpl.asm
index 12aa702296d..7b140e7f749 100644
--- a/src/VBox/VMM/VMMAll/IEMAllAImpl.asm
+++ b/src/VBox/VMM/VMMAll/IEMAllAImpl.asm
@@ -5181,3 +5181,50 @@ IEMIMPL_MEDIA_AVX_INSN_IMM8_6 vblendps
IEMIMPL_MEDIA_AVX_INSN_IMM8_6 vblendpd
IEMIMPL_MEDIA_AVX_INSN_IMM8_6 vpblendw
IEMIMPL_MEDIA_AVX_INSN_IMM8_6 vpalignr
+
+
+;;
+; Need to move this as well somewhere better?
+;
+struc IEMPCMPISTRISRC
+ .uSrc1 resd 4
+ .uSrc2 resd 4
+endstruc
+
+;;
+; The pcmpistri instruction.
+;
+; @param A0 Pointer to the ECX register to store the result to (output).
+; @param A1 Pointer to the EFLAGS register.
+; @param A2 Pointer to the structure containing the source operands (input).
+; @param A3 The 8-bit immediate
+;
+BEGINPROC_FASTCALL iemAImpl_pcmpistri_u128, 16
+ PROLOGUE_4_ARGS
+ IEMIMPL_SSE_PROLOGUE
+
+ movdqu xmm0, [A2 + IEMPCMPISTRISRC.uSrc1]
+ movdqu xmm1, [A2 + IEMPCMPISTRISRC.uSrc2]
+ mov T2, A0 ; A0 can be ecx/rcx in some calling conventions which gets overwritten later (T2 only available on AMD64)
+ lea T1, [.imm0 xWrtRIP]
+ lea T0, [A3 + A3*3] ; sizeof(insnX+ret) == 8: (A3 * 4) * 2
+ lea T1, [T1 + T0*2]
+ call T1
+
+ IEM_SAVE_FLAGS A1, X86_EFL_STATUS_BITS, 0
+ mov [T2], ecx
+
+ IEMIMPL_SSE_EPILOGUE
+ EPILOGUE_4_ARGS
+ %assign bImm 0
+ %rep 256
+.imm %+ bImm:
+ pcmpistri xmm0, xmm1, bImm
+ ret
+ int3
+ %assign bImm bImm + 1
+ %endrep
+.immEnd: ; 256*8 == 0x800
+dw 0xf7ff + (.immEnd - .imm0) ; will cause warning if entries are too big.
+dw 0x107ff - (.immEnd - .imm0) ; will cause warning if entries are too small.
+ENDPROC iemAImpl_pcmpistri_u128
diff --git a/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp b/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
index 44233a986d7..b970626ae05 100644
--- a/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
+++ b/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
@@ -15409,3 +15409,13 @@ IEM_DECL_IMPL_DEF(void, iemAImpl_vblendpd_u256_fallback,(PRTUINT256U puDst, PCRT
else
puDst->au64[i] = puSrc1->au64[i];
}
+
+
+/**
+ * [V]PCMPISTRI
+ */
+IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpistri_u128_fallback,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPISTRISRC pSrc, uint8_t bEvil))
+{
+ RT_NOREF(pu32Ecx, pEFlags, pSrc, bEvil);
+ AssertReleaseFailed();
+}
diff --git a/src/VBox/VMM/VMMAll/IEMAllInstructionsThree0f3a.cpp.h b/src/VBox/VMM/VMMAll/IEMAllInstructionsThree0f3a.cpp.h
index c7d946983c3..f57e0b3b300 100644
--- a/src/VBox/VMM/VMMAll/IEMAllInstructionsThree0f3a.cpp.h
+++ b/src/VBox/VMM/VMMAll/IEMAllInstructionsThree0f3a.cpp.h
@@ -374,8 +374,72 @@ FNIEMOP_STUB(iemOp_pcmpestrm_Vdq_Wdq_Ib);
FNIEMOP_STUB(iemOp_pcmpestri_Vdq_Wdq_Ib);
/** Opcode 0x66 0x0f 0x62. */
FNIEMOP_STUB(iemOp_pcmpistrm_Vdq_Wdq_Ib);
+
+
/** Opcode 0x66 0x0f 0x63*/
-FNIEMOP_STUB(iemOp_pcmpistri_Vdq_Wdq_Ib);
+FNIEMOP_DEF(iemOp_pcmpistri_Vdq_Wdq_Ib)
+{
+ 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, 1);
+ IEM_MC_ARG(uint32_t *, pu32Ecx, 0);
+ IEM_MC_ARG(uint32_t *, pEFlags, 1);
+ IEM_MC_LOCAL(IEMPCMPISTRISRC, Src);
+ IEM_MC_ARG_LOCAL_REF(PIEMPCMPISTRISRC, pSrc, Src, 2);
+ IEM_MC_ARG_CONST(uint8_t, bImmArg, /*=*/ bImm, 3);
+ IEM_MC_MAYBE_RAISE_SSE41_RELATED_XCPT();
+ IEM_MC_PREPARE_SSE_USAGE();
+ IEM_MC_REF_GREG_U32(pu32Ecx, X86_GREG_xCX);
+ IEM_MC_FETCH_XREG_U128(Src.uSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
+ IEM_MC_FETCH_XREG_U128(Src.uSrc2, IEM_GET_MODRM_RM(pVCpu, bRm));
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_4(IEM_SELECT_HOST_OR_FALLBACK(fSse41,
+ iemAImpl_pcmpistri_u128,
+ iemAImpl_pcmpistri_u128_fallback),
+ pu32Ecx, pEFlags, pSrc, bImmArg);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ else
+ {
+ /*
+ * Register, memory.
+ */
+ IEM_MC_BEGIN(4, 3);
+ IEM_MC_ARG(uint32_t *, pu32Ecx, 0);
+ IEM_MC_ARG(uint32_t *, pEFlags, 1);
+ IEM_MC_LOCAL(IEMPCMPISTRISRC, Src);
+ IEM_MC_ARG_LOCAL_REF(PIEMPCMPISTRISRC, 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_SSE41_RELATED_XCPT();
+ IEM_MC_FETCH_MEM_U128_ALIGN_SSE(Src.uSrc2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
+
+ IEM_MC_PREPARE_SSE_USAGE();
+ IEM_MC_REF_GREG_U32(pu32Ecx, X86_GREG_xCX);
+ IEM_MC_FETCH_XREG_U128(Src.uSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
+ IEM_MC_REF_EFLAGS(pEFlags);
+ IEM_MC_CALL_VOID_AIMPL_4(IEM_SELECT_HOST_OR_FALLBACK(fSse41,
+ iemAImpl_pcmpistri_u128,
+ iemAImpl_pcmpistri_u128_fallback),
+ pu32Ecx, pEFlags, pSrc, bImmArg);
+ IEM_MC_ADVANCE_RIP();
+ IEM_MC_END();
+ }
+ return VINF_SUCCESS;
+}
+
+
/* Opcode 0x66 0x0f 0x64 - invalid */
/* Opcode 0x66 0x0f 0x65 - invalid */
/* Opcode 0x66 0x0f 0x66 - invalid */
diff --git a/src/VBox/VMM/include/IEMInternal.h b/src/VBox/VMM/include/IEMInternal.h
index 8970716adda..8b9bfb19510 100644
--- a/src/VBox/VMM/include/IEMInternal.h
+++ b/src/VBox/VMM/include/IEMInternal.h
@@ -2229,6 +2229,19 @@ FNIEMAIMPLMEDIAOPTF3U256IMM8 iemAImpl_vpalignr_u256, iemAImpl_vpalignr_u256_fall
FNIEMAIMPLMEDIAOPTF3U256IMM8 iemAImpl_vpblendw_u256, iemAImpl_vpblendw_u256_fallback;
FNIEMAIMPLMEDIAOPTF3U256IMM8 iemAImpl_vblendps_u256, iemAImpl_vblendps_u256_fallback;
FNIEMAIMPLMEDIAOPTF3U256IMM8 iemAImpl_vblendpd_u256, iemAImpl_vblendpd_u256_fallback;
+
+
+typedef struct IEMPCMPISTRISRC
+{
+ RTUINT128U uSrc1;
+ RTUINT128U uSrc2;
+} IEMPCMPISTRISRC;
+typedef IEMPCMPISTRISRC *PIEMPCMPISTRISRC;
+typedef const IEMPCMPISTRISRC *PCIEMPCMPISTRISRC;
+
+IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpistri_u128,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPISTRISRC pSrc, uint8_t bEvil));
+IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpistri_u128_fallback,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPISTRISRC pSrc, uint8_t bEvil));
+
/** @} */
/** @name Media Odds and Ends