diff options
-rw-r--r-- | src/VBox/VMM/VMMAll/IEMAllAImpl.asm | 47 | ||||
-rw-r--r-- | src/VBox/VMM/VMMAll/IEMAllAImplC.cpp | 10 | ||||
-rw-r--r-- | src/VBox/VMM/VMMAll/IEMAllInstructionsThree0f3a.cpp.h | 66 | ||||
-rw-r--r-- | src/VBox/VMM/include/IEMInternal.h | 13 |
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 |