Lines Matching defs:pIemCpu

136 typedef VBOXSTRICTRC (__attribute__((__fastcall__)) * PFNIEMOP)(PIEMCPU pIemCpu);
138 static VBOXSTRICTRC __attribute__((__fastcall__, __nothrow__)) a_Name(PIEMCPU pIemCpu)
140 static VBOXSTRICTRC __attribute__((__fastcall__, __nothrow__)) a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0)
142 static VBOXSTRICTRC __attribute__((__fastcall__, __nothrow__)) a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0, a_Type1 a_Name1)
145 typedef VBOXSTRICTRC (__fastcall * PFNIEMOP)(PIEMCPU pIemCpu);
147 static /*__declspec(naked)*/ VBOXSTRICTRC __fastcall a_Name(PIEMCPU pIemCpu) RT_NO_THROW
149 static /*__declspec(naked)*/ VBOXSTRICTRC __fastcall a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0) RT_NO_THROW
151 static /*__declspec(naked)*/ VBOXSTRICTRC __fastcall a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0, a_Type1 a_Name1) RT_NO_THROW
154 typedef VBOXSTRICTRC (* PFNIEMOP)(PIEMCPU pIemCpu);
156 static VBOXSTRICTRC __attribute__((__nothrow__)) a_Name(PIEMCPU pIemCpu)
158 static VBOXSTRICTRC __attribute__((__nothrow__)) a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0)
160 static VBOXSTRICTRC __attribute__((__nothrow__)) a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0, a_Type1 a_Name1)
163 typedef VBOXSTRICTRC (* PFNIEMOP)(PIEMCPU pIemCpu);
165 static VBOXSTRICTRC a_Name(PIEMCPU pIemCpu) RT_NO_THROW
167 static VBOXSTRICTRC a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0) RT_NO_THROW
169 static VBOXSTRICTRC a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0, a_Type1 a_Name1) RT_NO_THROW
238 #define FNIEMOP_CALL(a_pfn) (a_pfn)(pIemCpu)
246 #define FNIEMOP_CALL_1(a_pfn, a0) (a_pfn)(pIemCpu, a0)
254 #define FNIEMOP_CALL_2(a_pfn, a0, a1) (a_pfn)(pIemCpu, a0, a1)
678 static VBOXSTRICTRC iemRaiseTaskSwitchFaultWithErr(PIEMCPU pIemCpu, uint16_t uErr);
679 static VBOXSTRICTRC iemRaiseTaskSwitchFaultCurrentTSS(PIEMCPU pIemCpu);
680 static VBOXSTRICTRC iemRaiseTaskSwitchFault0(PIEMCPU pIemCpu);
681 static VBOXSTRICTRC iemRaiseTaskSwitchFaultBySelector(PIEMCPU pIemCpu, uint16_t uSel);
682 /*static VBOXSTRICTRC iemRaiseSelectorNotPresent(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);*/
683 static VBOXSTRICTRC iemRaiseSelectorNotPresentBySelector(PIEMCPU pIemCpu, uint16_t uSel);
684 static VBOXSTRICTRC iemRaiseSelectorNotPresentWithErr(PIEMCPU pIemCpu, uint16_t uErr);
685 static VBOXSTRICTRC iemRaiseStackSelectorNotPresentBySelector(PIEMCPU pIemCpu, uint16_t uSel);
686 static VBOXSTRICTRC iemRaiseStackSelectorNotPresentWithErr(PIEMCPU pIemCpu, uint16_t uErr);
687 static VBOXSTRICTRC iemRaiseGeneralProtectionFault(PIEMCPU pIemCpu, uint16_t uErr);
688 static VBOXSTRICTRC iemRaiseGeneralProtectionFault0(PIEMCPU pIemCpu);
689 static VBOXSTRICTRC iemRaiseGeneralProtectionFaultBySelector(PIEMCPU pIemCpu, RTSEL uSel);
690 static VBOXSTRICTRC iemRaiseSelectorBounds(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
691 static VBOXSTRICTRC iemRaiseSelectorBoundsBySelector(PIEMCPU pIemCpu, RTSEL Sel);
692 static VBOXSTRICTRC iemRaiseSelectorInvalidAccess(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
693 static VBOXSTRICTRC iemRaisePageFault(PIEMCPU pIemCpu, RTGCPTR GCPtrWhere, uint32_t fAccess, int rc);
694 static VBOXSTRICTRC iemRaiseAlignmentCheckException(PIEMCPU pIemCpu);
695 static VBOXSTRICTRC iemMemMap(PIEMCPU pIemCpu, void **ppvMem, size_t cbMem, uint8_t iSegReg, RTGCPTR GCPtrMem, uint32_t fAccess);
696 static VBOXSTRICTRC iemMemCommitAndUnmap(PIEMCPU pIemCpu, void *pvMem, uint32_t fAccess);
697 static VBOXSTRICTRC iemMemFetchDataU32(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem);
698 static VBOXSTRICTRC iemMemFetchDataU64(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem);
699 static VBOXSTRICTRC iemMemFetchSysU8(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem);
700 static VBOXSTRICTRC iemMemFetchSysU16(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem);
701 static VBOXSTRICTRC iemMemFetchSysU32(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem);
702 static VBOXSTRICTRC iemMemFetchSysU64(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem);
703 static VBOXSTRICTRC iemMemFetchSelDescWithErr(PIEMCPU pIemCpu, PIEMSELDESC pDesc, uint16_t uSel, uint8_t uXcpt, uint16_t uErrorCode);
704 static VBOXSTRICTRC iemMemFetchSelDesc(PIEMCPU pIemCpu, PIEMSELDESC pDesc, uint16_t uSel, uint8_t uXcpt);
705 static VBOXSTRICTRC iemMemStackPushCommitSpecial(PIEMCPU pIemCpu, void *pvMem, uint64_t uNewRsp);
706 static VBOXSTRICTRC iemMemStackPushBeginSpecial(PIEMCPU pIemCpu, size_t cbMem, void **ppvMem, uint64_t *puNewRsp);
707 static VBOXSTRICTRC iemMemStackPushU32(PIEMCPU pIemCpu, uint32_t u32Value);
708 static VBOXSTRICTRC iemMemStackPushU16(PIEMCPU pIemCpu, uint16_t u16Value);
709 static VBOXSTRICTRC iemMemMarkSelDescAccessed(PIEMCPU pIemCpu, uint16_t uSel);
710 static uint16_t iemSRegFetchU16(PIEMCPU pIemCpu, uint8_t iSegReg);
713 static PIEMVERIFYEVTREC iemVerifyAllocRecord(PIEMCPU pIemCpu);
715 static VBOXSTRICTRC iemVerifyFakeIOPortRead(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue);
716 static VBOXSTRICTRC iemVerifyFakeIOPortWrite(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue);
724 * @param pIemCpu The per CPU IEM state of the calling thread.
728 static int iemSetPassUpStatus(PIEMCPU pIemCpu, VBOXSTRICTRC rcPassUp)
732 int32_t const rcOldPassUp = pIemCpu->rcPassUp;
734 pIemCpu->rcPassUp = VBOXSTRICTRC_VAL(rcPassUp);
742 pIemCpu->rcPassUp = VBOXSTRICTRC_VAL(rcPassUp);
751 pIemCpu->rcPassUp = VBOXSTRICTRC_VAL(rcPassUp);
763 * @param pIemCpu The per CPU IEM state.
766 DECLINLINE(void) iemInitExec(PIEMCPU pIemCpu, bool fBypassHandlers)
768 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
769 PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu);
785 pIemCpu->uCpl = CPUMGetGuestCPL(pVCpu);
791 pIemCpu->enmCpuMode = enmMode;
793 pIemCpu->enmDefAddrMode = (IEMMODE)0xc0fe;
794 pIemCpu->enmEffAddrMode = (IEMMODE)0xc0fe;
795 pIemCpu->enmDefOpSize = (IEMMODE)0xc0fe;
796 pIemCpu->enmEffOpSize = (IEMMODE)0xc0fe;
797 pIemCpu->fPrefixes = (IEMMODE)0xfeedbeef;
798 pIemCpu->uRexReg = 127;
799 pIemCpu->uRexB = 127;
800 pIemCpu->uRexIndex = 127;
801 pIemCpu->iEffSeg = 127;
802 pIemCpu->offOpcode = 127;
803 pIemCpu->cbOpcode = 127;
806 pIemCpu->cActiveMappings = 0;
807 pIemCpu->iNextMapping = 0;
808 pIemCpu->rcPassUp = VINF_SUCCESS;
809 pIemCpu->fBypassHandlers = fBypassHandlers;
811 pIemCpu->fInPatchCode = pIemCpu->uCpl == 0
814 && PATMIsPatchGCAddr(IEMCPU_TO_VM(pIemCpu), pCtx->eip);
815 if (!pIemCpu->fInPatchCode)
824 * @param pIemCpu The per CPU IEM state.
827 DECLINLINE(void) iemInitDecoder(PIEMCPU pIemCpu, bool fBypassHandlers)
829 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
830 PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu);
846 pIemCpu->uCpl = CPUMGetGuestCPL(pVCpu);
848 if (pIemCpu->uInjectCpl != UINT8_MAX)
849 pIemCpu->uCpl = pIemCpu->uInjectCpl;
856 pIemCpu->enmCpuMode = enmMode;
857 pIemCpu->enmDefAddrMode = enmMode; /** @todo check if this is correct... */
858 pIemCpu->enmEffAddrMode = enmMode;
861 pIemCpu->enmDefOpSize = enmMode; /** @todo check if this is correct... */
862 pIemCpu->enmEffOpSize = enmMode;
866 pIemCpu->enmDefOpSize = IEMMODE_32BIT;
867 pIemCpu->enmEffOpSize = IEMMODE_32BIT;
869 pIemCpu->fPrefixes = 0;
870 pIemCpu->uRexReg = 0;
871 pIemCpu->uRexB = 0;
872 pIemCpu->uRexIndex = 0;
873 pIemCpu->iEffSeg = X86_SREG_DS;
874 pIemCpu->offOpcode = 0;
875 pIemCpu->cbOpcode = 0;
876 pIemCpu->cActiveMappings = 0;
877 pIemCpu->iNextMapping = 0;
878 pIemCpu->rcPassUp = VINF_SUCCESS;
879 pIemCpu->fBypassHandlers = fBypassHandlers;
881 pIemCpu->fInPatchCode = pIemCpu->uCpl == 0
884 && PATMIsPatchGCAddr(IEMCPU_TO_VM(pIemCpu), pCtx->eip);
885 if (!pIemCpu->fInPatchCode)
893 RTTraceBufAddMsgF(pVCpu->CTX_SUFF(pVM)->CTX_SUFF(hTraceBuf), "I64/%u %08llx", pIemCpu->uCpl, pCtx->rip);
896 RTTraceBufAddMsgF(pVCpu->CTX_SUFF(pVM)->CTX_SUFF(hTraceBuf), "I32/%u %04x:%08x", pIemCpu->uCpl, pCtx->cs.Sel, pCtx->eip);
899 RTTraceBufAddMsgF(pVCpu->CTX_SUFF(pVM)->CTX_SUFF(hTraceBuf), "I16/%u %04x:%04x", pIemCpu->uCpl, pCtx->cs.Sel, pCtx->eip);
910 * @param pIemCpu The IEM state.
913 static VBOXSTRICTRC iemInitDecoderAndPrefetchOpcodes(PIEMCPU pIemCpu, bool fBypassHandlers)
916 uint8_t const cbOldOpcodes = pIemCpu->cbOpcode;
918 iemInitDecoder(pIemCpu, fBypassHandlers);
925 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
928 if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
933 return iemRaiseGeneralProtectionFault0(pIemCpu);
939 AssertMsg(!(GCPtrPC32 & ~(uint32_t)UINT16_MAX) || pIemCpu->enmCpuMode == IEMMODE_32BIT, ("%04x:%RX64\n", pCtx->cs.Sel, pCtx->rip));
941 return iemRaiseSelectorBounds(pIemCpu, X86_SREG_CS, IEM_ACCESS_INSTRUCTION);
955 if (pIemCpu->fInPatchCode)
958 int rc = PATMReadPatchCode(IEMCPU_TO_VM(pIemCpu), GCPtrPC, pIemCpu->abOpcode, sizeof(pIemCpu->abOpcode), &cbRead);
960 pIemCpu->cbOpcode = (uint8_t)cbRead; Assert(pIemCpu->cbOpcode == cbRead); Assert(cbRead > 0);
967 int rc = PGMGstGetPage(IEMCPU_TO_VMCPU(pIemCpu), GCPtrPC, &fFlags, &GCPhys);
971 return iemRaisePageFault(pIemCpu, GCPtrPC, IEM_ACCESS_INSTRUCTION, rc);
973 if (!(fFlags & X86_PTE_US) && pIemCpu->uCpl == 3)
976 return iemRaisePageFault(pIemCpu, GCPtrPC, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
981 return iemRaisePageFault(pIemCpu, GCPtrPC, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
994 RTGCPHYS const offPrevOpcodes = GCPhys - pIemCpu->GCPhysOpcodes;
995 pIemCpu->GCPhysOpcodes = GCPhys;
997 && PAGE_SIZE - (GCPhys & PAGE_OFFSET_MASK) > sizeof(pIemCpu->abOpcode))
1000 memmove(&pIemCpu->abOpcode[0], &pIemCpu->abOpcode[offPrevOpcodes], cbNew);
1001 pIemCpu->cbOpcode = cbNew;
1009 PVM pVM = IEMCPU_TO_VM(pIemCpu);
1013 && RT_SUCCESS(PATMR3ReadOrgInstr(pVM, GCPtrPC, pIemCpu->abOpcode, sizeof(pIemCpu->abOpcode), &cbActual)))
1017 pIemCpu->cbOpcode = (uint8_t)cbActual;
1025 if (cbToTryRead > sizeof(pIemCpu->abOpcode))
1026 cbToTryRead = sizeof(pIemCpu->abOpcode);
1028 if (!pIemCpu->fBypassHandlers)
1029 rc = PGMPhysRead(pVM, GCPhys, pIemCpu->abOpcode, cbToTryRead);
1031 rc = PGMPhysSimpleReadGCPhys(pVM, pIemCpu->abOpcode, GCPhys, cbToTryRead);
1039 pIemCpu->cbOpcode = cbToTryRead;
1051 * @param pIemCpu The IEM state.
1055 static VBOXSTRICTRC iemOpcodeFetchMoreBytes(PIEMCPU pIemCpu, size_t cbMin)
1062 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
1063 uint8_t cbLeft = pIemCpu->cbOpcode - pIemCpu->offOpcode; Assert(cbLeft < cbMin);
1066 if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
1069 GCPtrNext = pCtx->rip + pIemCpu->cbOpcode;
1071 return iemRaiseGeneralProtectionFault0(pIemCpu);
1076 Assert(!(GCPtrNext32 & ~(uint32_t)UINT16_MAX) || pIemCpu->enmCpuMode == IEMMODE_32BIT);
1077 GCPtrNext32 += pIemCpu->cbOpcode;
1079 return iemRaiseSelectorBounds(pIemCpu, X86_SREG_CS, IEM_ACCESS_INSTRUCTION);
1088 return iemRaiseSelectorBounds(pIemCpu, X86_SREG_CS, IEM_ACCESS_INSTRUCTION);
1097 if (cbToTryRead > sizeof(pIemCpu->abOpcode) - pIemCpu->cbOpcode)
1098 cbToTryRead = sizeof(pIemCpu->abOpcode) - pIemCpu->cbOpcode;
1105 if (pIemCpu->fInPatchCode)
1108 int rc = PATMReadPatchCode(IEMCPU_TO_VM(pIemCpu), GCPtrNext, pIemCpu->abOpcode, cbToTryRead, &cbRead);
1110 pIemCpu->cbOpcode = (uint8_t)cbRead; Assert(pIemCpu->cbOpcode == cbRead); Assert(cbRead > 0);
1117 int rc = PGMGstGetPage(IEMCPU_TO_VMCPU(pIemCpu), GCPtrNext, &fFlags, &GCPhys);
1121 return iemRaisePageFault(pIemCpu, GCPtrNext, IEM_ACCESS_INSTRUCTION, rc);
1123 if (!(fFlags & X86_PTE_US) && pIemCpu->uCpl == 3)
1126 return iemRaisePageFault(pIemCpu, GCPtrNext, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
1131 return iemRaisePageFault(pIemCpu, GCPtrNext, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
1134 Log5(("GCPtrNext=%RGv GCPhys=%RGp cbOpcodes=%#x\n", GCPtrNext, GCPhys, pIemCpu->cbOpcode));
1146 if (!pIemCpu->fBypassHandlers)
1147 rc = PGMPhysRead(IEMCPU_TO_VM(pIemCpu), GCPhys, &pIemCpu->abOpcode[pIemCpu->cbOpcode], cbToTryRead);
1149 rc = PGMPhysSimpleReadGCPhys(IEMCPU_TO_VM(pIemCpu), &pIemCpu->abOpcode[pIemCpu->cbOpcode], GCPhys, cbToTryRead);
1156 pIemCpu->cbOpcode += cbToTryRead;
1157 Log5(("%.*Rhxs\n", pIemCpu->cbOpcode, pIemCpu->abOpcode));
1167 * @param pIemCpu The IEM state.
1170 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU8Slow(PIEMCPU pIemCpu, uint8_t *pb)
1172 VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 1);
1175 uint8_t offOpcode = pIemCpu->offOpcode;
1176 *pb = pIemCpu->abOpcode[offOpcode];
1177 pIemCpu->offOpcode = offOpcode + 1;
1189 * @param pIemCpu The IEM state.
1192 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU8(PIEMCPU pIemCpu, uint8_t *pu8)
1194 uint8_t const offOpcode = pIemCpu->offOpcode;
1195 if (RT_LIKELY(offOpcode < pIemCpu->cbOpcode))
1197 *pu8 = pIemCpu->abOpcode[offOpcode];
1198 pIemCpu->offOpcode = offOpcode + 1;
1201 return iemOpcodeGetNextU8Slow(pIemCpu, pu8);
1209 * @remark Implicitly references pIemCpu.
1214 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU8(pIemCpu, (a_pu8)); \
1224 * @param pIemCpu The IEM state.
1227 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8(PIEMCPU pIemCpu, int8_t *pi8)
1229 return iemOpcodeGetNextU8(pIemCpu, (uint8_t *)pi8);
1238 * @remark Implicitly references pIemCpu.
1243 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8(pIemCpu, (a_pi8)); \
1253 * @param pIemCpu The IEM state.
1256 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextS8SxU16Slow(PIEMCPU pIemCpu, uint16_t *pu16)
1259 VBOXSTRICTRC rcStrict = iemOpcodeGetNextU8Slow(pIemCpu, &u8);
1271 * @param pIemCpu The IEM state.
1274 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU16(PIEMCPU pIemCpu, uint16_t *pu16)
1276 uint8_t const offOpcode = pIemCpu->offOpcode;
1277 if (RT_UNLIKELY(offOpcode >= pIemCpu->cbOpcode))
1278 return iemOpcodeGetNextS8SxU16Slow(pIemCpu, pu16);
1280 *pu16 = (int8_t)pIemCpu->abOpcode[offOpcode];
1281 pIemCpu->offOpcode = offOpcode + 1;
1291 * @remark Implicitly references pIemCpu.
1296 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU16(pIemCpu, (a_pu16)); \
1306 * @param pIemCpu The IEM state.
1309 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextS8SxU32Slow(PIEMCPU pIemCpu, uint32_t *pu32)
1312 VBOXSTRICTRC rcStrict = iemOpcodeGetNextU8Slow(pIemCpu, &u8);
1324 * @param pIemCpu The IEM state.
1327 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU32(PIEMCPU pIemCpu, uint32_t *pu32)
1329 uint8_t const offOpcode = pIemCpu->offOpcode;
1330 if (RT_UNLIKELY(offOpcode >= pIemCpu->cbOpcode))
1331 return iemOpcodeGetNextS8SxU32Slow(pIemCpu, pu32);
1333 *pu32 = (int8_t)pIemCpu->abOpcode[offOpcode];
1334 pIemCpu->offOpcode = offOpcode + 1;
1344 * @remark Implicitly references pIemCpu.
1349 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU32(pIemCpu, (a_pu32)); \
1359 * @param pIemCpu The IEM state.
1362 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextS8SxU64Slow(PIEMCPU pIemCpu, uint64_t *pu64)
1365 VBOXSTRICTRC rcStrict = iemOpcodeGetNextU8Slow(pIemCpu, &u8);
1377 * @param pIemCpu The IEM state.
1380 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU64(PIEMCPU pIemCpu, uint64_t *pu64)
1382 uint8_t const offOpcode = pIemCpu->offOpcode;
1383 if (RT_UNLIKELY(offOpcode >= pIemCpu->cbOpcode))
1384 return iemOpcodeGetNextS8SxU64Slow(pIemCpu, pu64);
1386 *pu64 = (int8_t)pIemCpu->abOpcode[offOpcode];
1387 pIemCpu->offOpcode = offOpcode + 1;
1397 * @remark Implicitly references pIemCpu.
1402 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU64(pIemCpu, (a_pu64)); \
1412 * @param pIemCpu The IEM state.
1415 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU16Slow(PIEMCPU pIemCpu, uint16_t *pu16)
1417 VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 2);
1420 uint8_t offOpcode = pIemCpu->offOpcode;
1421 *pu16 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]);
1422 pIemCpu->offOpcode = offOpcode + 2;
1434 * @param pIemCpu The IEM state.
1437 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16(PIEMCPU pIemCpu, uint16_t *pu16)
1439 uint8_t const offOpcode = pIemCpu->offOpcode;
1440 if (RT_UNLIKELY(offOpcode + 2 > pIemCpu->cbOpcode))
1441 return iemOpcodeGetNextU16Slow(pIemCpu, pu16);
1443 *pu16 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]);
1444 pIemCpu->offOpcode = offOpcode + 2;
1453 * @remark Implicitly references pIemCpu.
1458 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16(pIemCpu, (a_pu16)); \
1468 * @param pIemCpu The IEM state.
1471 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU16ZxU32Slow(PIEMCPU pIemCpu, uint32_t *pu32)
1473 VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 2);
1476 uint8_t offOpcode = pIemCpu->offOpcode;
1477 *pu32 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]);
1478 pIemCpu->offOpcode = offOpcode + 2;
1490 * @param pIemCpu The IEM state.
1493 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16ZxU32(PIEMCPU pIemCpu, uint32_t *pu32)
1495 uint8_t const offOpcode = pIemCpu->offOpcode;
1496 if (RT_UNLIKELY(offOpcode + 2 > pIemCpu->cbOpcode))
1497 return iemOpcodeGetNextU16ZxU32Slow(pIemCpu, pu32);
1499 *pu32 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]);
1500 pIemCpu->offOpcode = offOpcode + 2;
1510 * @remark Implicitly references pIemCpu.
1515 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16ZxU32(pIemCpu, (a_pu32)); \
1525 * @param pIemCpu The IEM state.
1528 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU16ZxU64Slow(PIEMCPU pIemCpu, uint64_t *pu64)
1530 VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 2);
1533 uint8_t offOpcode = pIemCpu->offOpcode;
1534 *pu64 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]);
1535 pIemCpu->offOpcode = offOpcode + 2;
1547 * @param pIemCpu The IEM state.
1550 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16ZxU64(PIEMCPU pIemCpu, uint64_t *pu64)
1552 uint8_t const offOpcode = pIemCpu->offOpcode;
1553 if (RT_UNLIKELY(offOpcode + 2 > pIemCpu->cbOpcode))
1554 return iemOpcodeGetNextU16ZxU64Slow(pIemCpu, pu64);
1556 *pu64 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]);
1557 pIemCpu->offOpcode = offOpcode + 2;
1567 * @remark Implicitly references pIemCpu.
1572 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16ZxU64(pIemCpu, (a_pu64)); \
1582 * @param pIemCpu The IEM state.
1585 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS16(PIEMCPU pIemCpu, int16_t *pi16)
1587 return iemOpcodeGetNextU16(pIemCpu, (uint16_t *)pi16);
1596 * @remark Implicitly references pIemCpu.
1601 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS16(pIemCpu, (a_pi16)); \
1611 * @param pIemCpu The IEM state.
1614 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU32Slow(PIEMCPU pIemCpu, uint32_t *pu32)
1616 VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 4);
1619 uint8_t offOpcode = pIemCpu->offOpcode;
1620 *pu32 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
1621 pIemCpu->abOpcode[offOpcode + 1],
1622 pIemCpu->abOpcode[offOpcode + 2],
1623 pIemCpu->abOpcode[offOpcode + 3]);
1624 pIemCpu->offOpcode = offOpcode + 4;
1636 * @param pIemCpu The IEM state.
1639 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU32(PIEMCPU pIemCpu, uint32_t *pu32)
1641 uint8_t const offOpcode = pIemCpu->offOpcode;
1642 if (RT_UNLIKELY(offOpcode + 4 > pIemCpu->cbOpcode))
1643 return iemOpcodeGetNextU32Slow(pIemCpu, pu32);
1645 *pu32 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
1646 pIemCpu->abOpcode[offOpcode + 1],
1647 pIemCpu->abOpcode[offOpcode + 2],
1648 pIemCpu->abOpcode[offOpcode + 3]);
1649 pIemCpu->offOpcode = offOpcode + 4;
1658 * @remark Implicitly references pIemCpu.
1663 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU32(pIemCpu, (a_pu32)); \
1673 * @param pIemCpu The IEM state.
1676 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU32ZxU64Slow(PIEMCPU pIemCpu, uint64_t *pu64)
1678 VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 4);
1681 uint8_t offOpcode = pIemCpu->offOpcode;
1682 *pu64 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
1683 pIemCpu->abOpcode[offOpcode + 1],
1684 pIemCpu->abOpcode[offOpcode + 2],
1685 pIemCpu->abOpcode[offOpcode + 3]);
1686 pIemCpu->offOpcode = offOpcode + 4;
1698 * @param pIemCpu The IEM state.
1701 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU32ZxU64(PIEMCPU pIemCpu, uint64_t *pu64)
1703 uint8_t const offOpcode = pIemCpu->offOpcode;
1704 if (RT_UNLIKELY(offOpcode + 4 > pIemCpu->cbOpcode))
1705 return iemOpcodeGetNextU32ZxU64Slow(pIemCpu, pu64);
1707 *pu64 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
1708 pIemCpu->abOpcode[offOpcode + 1],
1709 pIemCpu->abOpcode[offOpcode + 2],
1710 pIemCpu->abOpcode[offOpcode + 3]);
1711 pIemCpu->offOpcode = offOpcode + 4;
1721 * @remark Implicitly references pIemCpu.
1726 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU32ZxU64(pIemCpu, (a_pu64)); \
1736 * @param pIemCpu The IEM state.
1739 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32(PIEMCPU pIemCpu, int32_t *pi32)
1741 return iemOpcodeGetNextU32(pIemCpu, (uint32_t *)pi32);
1749 * @remark Implicitly references pIemCpu.
1754 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32(pIemCpu, (a_pi32)); \
1764 * @param pIemCpu The IEM state.
1767 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextS32SxU64Slow(PIEMCPU pIemCpu, uint64_t *pu64)
1769 VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 4);
1772 uint8_t offOpcode = pIemCpu->offOpcode;
1773 *pu64 = (int32_t)RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
1774 pIemCpu->abOpcode[offOpcode + 1],
1775 pIemCpu->abOpcode[offOpcode + 2],
1776 pIemCpu->abOpcode[offOpcode + 3]);
1777 pIemCpu->offOpcode = offOpcode + 4;
1789 * @param pIemCpu The IEM state.
1792 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32SxU64(PIEMCPU pIemCpu, uint64_t *pu64)
1794 uint8_t const offOpcode = pIemCpu->offOpcode;
1795 if (RT_UNLIKELY(offOpcode + 4 > pIemCpu->cbOpcode))
1796 return iemOpcodeGetNextS32SxU64Slow(pIemCpu, pu64);
1798 int32_t i32 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
1799 pIemCpu->abOpcode[offOpcode + 1],
1800 pIemCpu->abOpcode[offOpcode + 2],
1801 pIemCpu->abOpcode[offOpcode + 3]);
1803 pIemCpu->offOpcode = offOpcode + 4;
1813 * @remark Implicitly references pIemCpu.
1818 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32SxU64(pIemCpu, (a_pu64)); \
1828 * @param pIemCpu The IEM state.
1831 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU64Slow(PIEMCPU pIemCpu, uint64_t *pu64)
1833 VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 8);
1836 uint8_t offOpcode = pIemCpu->offOpcode;
1837 *pu64 = RT_MAKE_U64_FROM_U8(pIemCpu->abOpcode[offOpcode],
1838 pIemCpu->abOpcode[offOpcode + 1],
1839 pIemCpu->abOpcode[offOpcode + 2],
1840 pIemCpu->abOpcode[offOpcode + 3],
1841 pIemCpu->abOpcode[offOpcode + 4],
1842 pIemCpu->abOpcode[offOpcode + 5],
1843 pIemCpu->abOpcode[offOpcode + 6],
1844 pIemCpu->abOpcode[offOpcode + 7]);
1845 pIemCpu->offOpcode = offOpcode + 8;
1857 * @param pIemCpu The IEM state.
1860 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU64(PIEMCPU pIemCpu, uint64_t *pu64)
1862 uint8_t const offOpcode = pIemCpu->offOpcode;
1863 if (RT_UNLIKELY(offOpcode + 8 > pIemCpu->cbOpcode))
1864 return iemOpcodeGetNextU64Slow(pIemCpu, pu64);
1866 *pu64 = RT_MAKE_U64_FROM_U8(pIemCpu->abOpcode[offOpcode],
1867 pIemCpu->abOpcode[offOpcode + 1],
1868 pIemCpu->abOpcode[offOpcode + 2],
1869 pIemCpu->abOpcode[offOpcode + 3],
1870 pIemCpu->abOpcode[offOpcode + 4],
1871 pIemCpu->abOpcode[offOpcode + 5],
1872 pIemCpu->abOpcode[offOpcode + 6],
1873 pIemCpu->abOpcode[offOpcode + 7]);
1874 pIemCpu->offOpcode = offOpcode + 8;
1883 * @remark Implicitly references pIemCpu.
1888 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU64(pIemCpu, (a_pu64)); \
1903 * @param pIemCpu The IEM per CPU instance data.
1909 static VBOXSTRICTRC iemMiscValidateNewSS(PIEMCPU pIemCpu, PCCPUMCTX pCtx, RTSEL NewSS, uint8_t uCpl, PIEMSELDESC pDesc)
1918 return iemRaiseTaskSwitchFault0(pIemCpu);
1925 return iemRaiseTaskSwitchFaultBySelector(pIemCpu, NewSS);
1931 VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, pDesc, NewSS, X86_XCPT_TS);
1941 return iemRaiseTaskSwitchFaultBySelector(pIemCpu, NewSS);
1948 return iemRaiseTaskSwitchFaultBySelector(pIemCpu, NewSS);
1953 return iemRaiseTaskSwitchFaultBySelector(pIemCpu, NewSS);
1961 return iemRaiseSelectorNotPresentBySelector(pIemCpu, NewSS);
2038 * @param pIemCpu The IEM per CPU instance data.
2044 static VBOXSTRICTRC iemRaiseLoadStackFromTss32Or16(PIEMCPU pIemCpu, PCCPUMCTX pCtx, uint8_t uCpl,
2064 return iemRaiseTaskSwitchFaultCurrentTSS(pIemCpu);
2068 rcStrict = iemMemFetchSysU32(pIemCpu, &u32Tmp, UINT8_MAX, pCtx->tr.u64Base + off);
2088 return iemRaiseTaskSwitchFaultCurrentTSS(pIemCpu);
2092 rcStrict = iemMemFetchSysU64(pIemCpu, &u64Tmp, UINT8_MAX, pCtx->tr.u64Base + off);
2113 * @param pIemCpu The IEM per CPU instance data.
2119 static VBOXSTRICTRC iemRaiseLoadStackFromTss64(PIEMCPU pIemCpu, PCCPUMCTX pCtx, uint8_t uCpl, uint8_t uIst,
2136 return iemRaiseTaskSwitchFaultCurrentTSS(pIemCpu);
2139 return iemMemFetchSysU64(pIemCpu, puRsp, UINT8_MAX, pCtx->tr.u64Base + off);
2165 * @param pIemCpu The IEM per CPU instance data.
2175 iemRaiseXcptOrIntInRealMode(PIEMCPU pIemCpu,
2183 AssertReturn(pIemCpu->enmCpuMode == IEMMODE_16BIT, VERR_INTERNAL_ERROR_3);
2192 return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
2195 VBOXSTRICTRC rcStrict = iemMemFetchDataU32(pIemCpu, (uint32_t *)&Idte, UINT8_MAX,
2205 rcStrict = iemMemStackPushBeginSpecial(pIemCpu, 6, (void **)&pu16Frame, &uNewRsp);
2209 uint32_t fEfl = IEMMISC_GET_EFL(pIemCpu, pCtx);
2213 rcStrict = iemMemStackPushCommitSpecial(pIemCpu, pu16Frame, uNewRsp);
2228 IEMMISC_SET_EFL(pIemCpu, pCtx, fEfl);
2241 * @param pIemCpu The IEM per CPU instance data.
2244 static void iemHlpLoadNullDataSelectorOnV86Xcpt(PIEMCPU pIemCpu, PCPUMSELREG pSReg)
2248 if (IEM_IS_GUEST_CPU_INTEL(pIemCpu) && !IEM_FULL_VERIFICATION_REM_ENABLED(pIemCpu))
2267 * @param pIemCpu The IEM per CPU instance data.
2271 static void iemHlpLoadSelectorInV86Mode(PIEMCPU pIemCpu, PCPUMSELREG pSReg, uint16_t uSel)
2287 * @param pIemCpu The IEM state of the calling EMT.
2291 static void iemHlpLoadNullDataSelectorProt(PIEMCPU pIemCpu, PCPUMSELREG pSReg, RTSEL uRpl)
2298 if (IEM_IS_GUEST_CPU_INTEL(pIemCpu) && !IEM_FULL_VERIFICATION_REM_ENABLED(pIemCpu))
2301 pSReg->Attr.u = X86DESCATTR_UNUSABLE | X86DESCATTR_G | X86DESCATTR_D | (pIemCpu->uCpl << X86DESCATTR_DPL_SHIFT);
2319 * @param pIemCpu The IEM per CPU instance data.
2324 * @remarks This expects pIemCpu->uCpl to be up to date.
2326 static VBOXSTRICTRC iemHlpTaskSwitchLoadDataSelectorInProtMode(PIEMCPU pIemCpu, PCPUMSELREG pSReg, uint16_t uSel)
2328 Assert(pIemCpu->enmCpuMode != IEMMODE_64BIT);
2333 iemHlpLoadNullDataSelectorProt(pIemCpu, pSReg, uSel);
2334 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(IEMCPU_TO_VMCPU(pIemCpu), pSReg));
2335 CPUMSetChangedFlags(IEMCPU_TO_VMCPU(pIemCpu), CPUM_CHANGED_HIDDEN_SEL_REGS);
2341 VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, &Desc, uSel, X86_XCPT_TS);
2355 return iemRaiseTaskSwitchFaultWithErr(pIemCpu, uSel & X86_SEL_MASK_OFF_RPL);
2364 || (pIemCpu->uCpl > Desc.Legacy.Gen.u2Dpl))
2367 uSel, (uSel & X86_SEL_RPL), Desc.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
2368 return iemRaiseTaskSwitchFaultWithErr(pIemCpu, uSel & X86_SEL_MASK_OFF_RPL);
2376 return iemRaiseSelectorNotPresentWithErr(pIemCpu, uSel & X86_SEL_MASK_OFF_RPL);
2389 rcStrict = iemMemMarkSelDescAccessed(pIemCpu, uSel);
2402 if (IEM_IS_GUEST_CPU_INTEL(pIemCpu) && !IEM_FULL_VERIFICATION_REM_ENABLED(pIemCpu))
2405 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(IEMCPU_TO_VMCPU(pIemCpu), pSReg));
2406 CPUMSetChangedFlags(IEMCPU_TO_VMCPU(pIemCpu), CPUM_CHANGED_HIDDEN_SEL_REGS);
2424 * @param pIemCpu The IEM per CPU instance data.
2434 static VBOXSTRICTRC iemTaskSwitch(PIEMCPU pIemCpu,
2444 Assert(!IEM_IS_REAL_MODE(pIemCpu));
2445 Assert(pIemCpu->enmCpuMode != IEMMODE_64BIT);
2475 return iemRaiseTaskSwitchFaultWithErr(pIemCpu, SelTSS & X86_SEL_MASK_OFF_RPL);
2492 return iemRaiseTaskSwitchFaultWithErr(pIemCpu, SelTSS & X86_SEL_MASK_OFF_RPL);
2506 VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu, &pvNewTSS, cbNewTSS, UINT8_MAX, GCPtrNewTSS, IEM_ACCESS_SYS_RW);
2522 rcStrict = iemMemMap(pIemCpu, (void **)&pDescCurTSS, sizeof(*pDescCurTSS), UINT8_MAX,
2532 rcStrict = iemMemCommitAndUnmap(pIemCpu, pDescCurTSS, IEM_ACCESS_SYS_RW);
2569 rcStrict = iemMemMap(pIemCpu, &pvCurTSS32, cbCurTSS, UINT8_MAX, GCPtrCurTSS + offCurTSS, IEM_ACCESS_SYS_RW);
2596 rcStrict = iemMemCommitAndUnmap(pIemCpu, pvCurTSS32, IEM_ACCESS_SYS_RW);
2613 rcStrict = iemMemMap(pIemCpu, &pvCurTSS16, cbCurTSS, UINT8_MAX, GCPtrCurTSS + offCurTSS, IEM_ACCESS_SYS_RW);
2638 rcStrict = iemMemCommitAndUnmap(pIemCpu, pvCurTSS16, IEM_ACCESS_SYS_RW);
2719 rcStrict = iemMemCommitAndUnmap(pIemCpu, pvNewTSS, IEM_ACCESS_SYS_RW);
2731 rcStrict = iemMemMap(pIemCpu, (void **)&pNewDescTSS, sizeof(*pNewDescTSS), UINT8_MAX,
2746 rcStrict = iemMemCommitAndUnmap(pIemCpu, pNewDescTSS, IEM_ACCESS_SYS_RW);
2765 CPUMSetChangedFlags(IEMCPU_TO_VMCPU(pIemCpu), CPUM_CHANGED_TR);
2778 CPUMSetChangedFlags(IEMCPU_TO_VMCPU(pIemCpu), CPUM_CHANGED_CR0);
2792 IEMMISC_SET_EFL(pIemCpu, pCtx, uNewEflags);
2822 CPUMSetChangedFlags(IEMCPU_TO_VMCPU(pIemCpu), CPUM_CHANGED_HIDDEN_SEL_REGS);
2827 CPUMSetChangedFlags(IEMCPU_TO_VMCPU(pIemCpu), CPUM_CHANGED_LDTR);
2829 if (IEM_IS_GUEST_CPU_INTEL(pIemCpu) && !IEM_FULL_VERIFICATION_REM_ENABLED(pIemCpu))
2847 if (!IEM_FULL_VERIFICATION_ENABLED(pIemCpu))
2849 int rc = CPUMSetGuestCR3(IEMCPU_TO_VMCPU(pIemCpu), uNewCr3);
2856 if (!IEM_FULL_VERIFICATION_ENABLED(pIemCpu))
2858 int rc = PGMFlushTLB(IEMCPU_TO_VMCPU(pIemCpu), pCtx->cr3, !(pCtx->cr4 & X86_CR4_PGE));
2862 CPUMSetChangedFlags(IEMCPU_TO_VMCPU(pIemCpu), CPUM_CHANGED_CR3);
2869 iemHlpLoadNullDataSelectorProt(pIemCpu, &pCtx->ldtr, uNewLdt);
2875 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescNewLdt, uNewLdt, X86_XCPT_TS);
2888 return iemRaiseTaskSwitchFaultWithErr(pIemCpu, uNewLdt & X86_SEL_MASK_OFF_RPL);
2896 if (IEM_IS_GUEST_CPU_INTEL(pIemCpu) && !IEM_FULL_VERIFICATION_REM_ENABLED(pIemCpu))
2898 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(IEMCPU_TO_VMCPU(pIemCpu), &pCtx->ldtr));
2902 if (IEM_IS_V86_MODE(pIemCpu))
2904 pIemCpu->uCpl = 3;
2905 iemHlpLoadSelectorInV86Mode(pIemCpu, &pCtx->es, uNewES);
2906 iemHlpLoadSelectorInV86Mode(pIemCpu, &pCtx->cs, uNewCS);
2907 iemHlpLoadSelectorInV86Mode(pIemCpu, &pCtx->ss, uNewSS);
2908 iemHlpLoadSelectorInV86Mode(pIemCpu, &pCtx->ds, uNewDS);
2909 iemHlpLoadSelectorInV86Mode(pIemCpu, &pCtx->fs, uNewFS);
2910 iemHlpLoadSelectorInV86Mode(pIemCpu, &pCtx->gs, uNewGS);
2922 return iemRaiseTaskSwitchFaultWithErr(pIemCpu, uNewSS & X86_SEL_MASK_OFF_RPL);
2926 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescSS, uNewSS, X86_XCPT_TS);
2941 return iemRaiseTaskSwitchFaultWithErr(pIemCpu, uNewSS & X86_SEL_MASK_OFF_RPL);
2950 return iemRaiseTaskSwitchFaultWithErr(pIemCpu, uNewSS & X86_SEL_MASK_OFF_RPL);
2957 return iemRaiseSelectorNotPresentWithErr(pIemCpu, uNewSS & X86_SEL_MASK_OFF_RPL);
2966 rcStrict = iemMemMarkSelDescAccessed(pIemCpu, uNewSS);
2979 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(IEMCPU_TO_VMCPU(pIemCpu), &pCtx->ss));
2982 pIemCpu->uCpl = uNewCpl;
2987 rcStrict = iemHlpTaskSwitchLoadDataSelectorInProtMode(pIemCpu, &pCtx->es, uNewES);
2990 rcStrict = iemHlpTaskSwitchLoadDataSelectorInProtMode(pIemCpu, &pCtx->ds, uNewDS);
2993 rcStrict = iemHlpTaskSwitchLoadDataSelectorInProtMode(pIemCpu, &pCtx->fs, uNewFS);
2996 rcStrict = iemHlpTaskSwitchLoadDataSelectorInProtMode(pIemCpu, &pCtx->gs, uNewGS);
3006 return iemRaiseTaskSwitchFaultWithErr(pIemCpu, uNewCS & X86_SEL_MASK_OFF_RPL);
3011 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, uNewCS, X86_XCPT_TS);
3024 return iemRaiseTaskSwitchFaultWithErr(pIemCpu, uNewCS & X86_SEL_MASK_OFF_RPL);
3033 return iemRaiseTaskSwitchFaultWithErr(pIemCpu, uNewCS & X86_SEL_MASK_OFF_RPL);
3042 return iemRaiseTaskSwitchFaultWithErr(pIemCpu, uNewCS & X86_SEL_MASK_OFF_RPL);
3049 return iemRaiseSelectorNotPresentWithErr(pIemCpu, uNewCS & X86_SEL_MASK_OFF_RPL);
3058 rcStrict = iemMemMarkSelDescAccessed(pIemCpu, uNewCS);
3071 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(IEMCPU_TO_VMCPU(pIemCpu), &pCtx->cs));
3111 return iemRaiseStackSelectorNotPresentWithErr(pIemCpu, uExt);
3121 return iemRaiseStackSelectorNotPresentWithErr(pIemCpu, uExt);
3127 rcStrict = iemMemStackPushU32(pIemCpu, uErr);
3129 rcStrict = iemMemStackPushU16(pIemCpu, uErr);
3144 return iemRaiseGeneralProtectionFault(pIemCpu, uExt);
3156 * @param pIemCpu The IEM per CPU instance data.
3166 iemRaiseXcptOrIntInProtMode(PIEMCPU pIemCpu,
3180 return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
3183 VBOXSTRICTRC rcStrict = iemMemFetchSysU64(pIemCpu, &Idte.u, UINT8_MAX,
3198 return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
3220 return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
3247 if (pIemCpu->uCpl > Idte.Gate.u2Dpl)
3249 Log(("RaiseXcptOrIntInProtMode %#x - CPL (%d) > DPL (%d) -> #GP\n", u8Vector, pIemCpu->uCpl, Idte.Gate.u2Dpl));
3250 return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
3258 return iemRaiseSelectorNotPresentWithErr(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
3276 rcStrict = iemMemFetchSelDescWithErr(pIemCpu, &DescTSS, SelTSS, X86_XCPT_GP, (SelTSS & uSelMask) | uExt);
3291 return iemRaiseGeneralProtectionFault(pIemCpu, (SelTSS & uSelMask) | uExt);
3298 return iemRaiseSelectorNotPresentWithErr(pIemCpu, (SelTSS & uSelMask) | uExt);
3302 return iemTaskSwitch(pIemCpu, pCtx, IEMTASKSWITCH_INT_XCPT, pCtx->eip, fFlags, uErr, uCr2, SelTSS, &DescTSS);
3310 return iemRaiseGeneralProtectionFault0(pIemCpu);
3315 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, NewCS, X86_XCPT_GP); /** @todo correct exception? */
3326 return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & X86_SEL_MASK_OFF_RPL);
3331 return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & X86_SEL_MASK_OFF_RPL);
3339 if (DescCS.Legacy.Gen.u2Dpl > pIemCpu->uCpl)
3342 u8Vector, NewCS, DescCS.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
3343 return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & X86_SEL_MASK_OFF_RPL);
3350 return iemRaiseSelectorNotPresentBySelector(pIemCpu, NewCS);
3363 return iemRaiseGeneralProtectionFault(pIemCpu, 0);
3367 uint32_t fEfl = IEMMISC_GET_EFL(pIemCpu, pCtx);
3370 else if (!IEM_FULL_VERIFICATION_REM_ENABLED(pIemCpu))
3375 ? pIemCpu->uCpl : DescCS.Legacy.Gen.u2Dpl;
3379 return iemRaiseGeneralProtectionFault(pIemCpu, 0);
3386 if (uNewCpl != pIemCpu->uCpl)
3390 rcStrict = iemRaiseLoadStackFromTss32Or16(pIemCpu, pCtx, uNewCpl, &NewSS, &uNewEsp);
3395 rcStrict = iemMiscValidateNewSS(pIemCpu, pCtx, NewSS, uNewCpl, &DescSS);
3412 return iemRaiseSelectorBoundsBySelector(pIemCpu, NewSS);
3422 return iemRaiseSelectorBoundsBySelector(pIemCpu, NewSS);
3432 rcStrict = iemMemMap(pIemCpu, &uStackFrame.pv, cbStackFrame, UINT8_MAX,
3442 uStackFrame.pu32[1] = (pCtx->cs.Sel & ~X86_SEL_RPL) | pIemCpu->uCpl;
3460 uStackFrame.pu16[1] = (pCtx->cs.Sel & ~X86_SEL_RPL) | pIemCpu->uCpl;
3473 rcStrict = iemMemCommitAndUnmap(pIemCpu, pvStackFrame, IEM_ACCESS_STACK_W | IEM_ACCESS_WHAT_SYS);
3483 rcStrict = iemMemMarkSelDescAccessed(pIemCpu, NewCS);
3491 rcStrict = iemMemMarkSelDescAccessed(pIemCpu, NewSS);
3507 pIemCpu->uCpl = uNewCpl;
3511 iemHlpLoadNullDataSelectorOnV86Xcpt(pIemCpu, &pCtx->gs);
3512 iemHlpLoadNullDataSelectorOnV86Xcpt(pIemCpu, &pCtx->fs);
3513 iemHlpLoadNullDataSelectorOnV86Xcpt(pIemCpu, &pCtx->es);
3514 iemHlpLoadNullDataSelectorOnV86Xcpt(pIemCpu, &pCtx->ds);
3525 rcStrict = iemMemStackPushBeginSpecial(pIemCpu, cbStackFrame, &uStackFrame.pv, &uNewRsp);
3535 uStackFrame.pu32[1] = (pCtx->cs.Sel & ~X86_SEL_RPL) | pIemCpu->uCpl;
3543 uStackFrame.pu16[1] = (pCtx->cs.Sel & ~X86_SEL_RPL) | pIemCpu->uCpl;
3546 rcStrict = iemMemCommitAndUnmap(pIemCpu, pvStackFrame, IEM_ACCESS_STACK_W); /* don't use the commit here */
3553 rcStrict = iemMemMarkSelDescAccessed(pIemCpu, NewCS);
3575 IEMMISC_SET_EFL(pIemCpu, pCtx, fEfl);
3591 * @param pIemCpu The IEM per CPU instance data.
3601 iemRaiseXcptOrIntInLongMode(PIEMCPU pIemCpu,
3616 return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
3619 VBOXSTRICTRC rcStrict = iemMemFetchSysU64(pIemCpu, &Idte.au64[0], UINT8_MAX, pCtx->idtr.pIdt + offIdt);
3621 rcStrict = iemMemFetchSysU64(pIemCpu, &Idte.au64[1], UINT8_MAX, pCtx->idtr.pIdt + offIdt + 8);
3635 return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
3648 return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
3654 if (pIemCpu->uCpl > Idte.Gate.u2Dpl)
3656 Log(("iemRaiseXcptOrIntInLongMode %#x - CPL (%d) > DPL (%d) -> #GP\n", u8Vector, pIemCpu->uCpl, Idte.Gate.u2Dpl));
3657 return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
3665 return iemRaiseSelectorNotPresentWithErr(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
3673 return iemRaiseGeneralProtectionFault0(pIemCpu);
3678 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, NewCS, X86_XCPT_GP);
3689 return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & X86_SEL_MASK_OFF_RPL);
3697 return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & X86_SEL_MASK_OFF_RPL);
3706 if (DescCS.Legacy.Gen.u2Dpl > pIemCpu->uCpl)
3709 u8Vector, NewCS, DescCS.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
3710 return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & X86_SEL_MASK_OFF_RPL);
3718 return iemRaiseSelectorNotPresentBySelector(pIemCpu, NewCS);
3728 return iemRaiseGeneralProtectionFault0(pIemCpu);
3737 ? pIemCpu->uCpl : DescCS.Legacy.Gen.u2Dpl;
3738 if ( uNewCpl != pIemCpu->uCpl
3741 rcStrict = iemRaiseLoadStackFromTss64(pIemCpu, pCtx, uNewCpl, Idte.Gate.u3IST, &uNewRsp);
3752 uint32_t fEfl = IEMMISC_GET_EFL(pIemCpu, pCtx);
3755 else if (!IEM_FULL_VERIFICATION_REM_ENABLED(pIemCpu))
3765 rcStrict = iemMemMap(pIemCpu, &uStackFrame.pv, cbStackFrame, UINT8_MAX,
3774 uStackFrame.pu64[1] = (pCtx->cs.Sel & ~X86_SEL_RPL) | pIemCpu->uCpl; /* CPL paranoia */
3778 rcStrict = iemMemCommitAndUnmap(pIemCpu, pvStackFrame, IEM_ACCESS_STACK_W | IEM_ACCESS_WHAT_SYS);
3788 rcStrict = iemMemMarkSelDescAccessed(pIemCpu, NewCS);
3799 if (uNewCpl != pIemCpu->uCpl)
3816 pIemCpu->uCpl = uNewCpl;
3819 IEMMISC_SET_EFL(pIemCpu, pCtx, fEfl);
3837 * @param pIemCpu The IEM per CPU instance data.
3846 iemRaiseXcptOrInt(PIEMCPU pIemCpu,
3853 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
3855 int rc = HMR0EnsureCompleteBasicContext(IEMCPU_TO_VMCPU(pIemCpu), pCtx);
3873 RTTraceBufAddMsgF(IEMCPU_TO_VM(pIemCpu)->CTX_SUFF(hTraceBuf), "Xcpt/%u: %02x %u %x %x %llx %04x:%04llx %04x:%04llx",
3874 pIemCpu->cXcptRecursions, u8Vector, cbInstr, fFlags, uErr, uCr2,
3881 uint8_t const uPrevXcpt = pIemCpu->uCurXcpt;
3882 uint32_t const fPrevXcpt = pIemCpu->fCurXcpt;
3883 if (pIemCpu->cXcptRecursions == 0)
3889 u8Vector, pCtx->cs.Sel, pCtx->rip, cbInstr, fFlags, uErr, uCr2, pIemCpu->uCurXcpt, pIemCpu->cXcptRecursions + 1, fPrevXcpt));
3892 if (pIemCpu->cXcptRecursions >= 3)
3906 pIemCpu->cXcptRecursions++;
3907 pIemCpu->uCurXcpt = u8Vector;
3908 pIemCpu->fCurXcpt = fFlags;
3916 PVM pVM = IEMCPU_TO_VM(pIemCpu);
3917 PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu);
3959 rcStrict = iemRaiseXcptOrIntInRealMode( pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
3961 rcStrict = iemRaiseXcptOrIntInLongMode( pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
3963 rcStrict = iemRaiseXcptOrIntInProtMode( pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
3968 pIemCpu->cXcptRecursions--;
3969 pIemCpu->uCurXcpt = uPrevXcpt;
3970 pIemCpu->fCurXcpt = fPrevXcpt;
3972 VBOXSTRICTRC_VAL(rcStrict), u8Vector, pCtx->cs.Sel, pCtx->rip, pCtx->ss.Sel, pCtx->esp, pIemCpu->uCpl));
3978 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseDivideError(PIEMCPU pIemCpu)
3980 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_DE, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
3986 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseDebugException(PIEMCPU pIemCpu)
3989 pIemCpu->CTX_SUFF(pCtx)->dr[7] &= ~X86_DR7_GD;
3990 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_DB, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
3995 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseUndefinedOpcode(PIEMCPU pIemCpu)
3997 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_UD, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
4002 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseDeviceNotAvailable(PIEMCPU pIemCpu)
4004 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_NM, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
4009 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseTaskSwitchFaultWithErr(PIEMCPU pIemCpu, uint16_t uErr)
4011 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_TS, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, uErr, 0);
4016 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseTaskSwitchFaultCurrentTSS(PIEMCPU pIemCpu)
4018 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_TS, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
4019 pIemCpu->CTX_SUFF(pCtx)->tr.Sel, 0);
4024 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseTaskSwitchFault0(PIEMCPU pIemCpu)
4026 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_TS, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
4032 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseTaskSwitchFaultBySelector(PIEMCPU pIemCpu, uint16_t uSel)
4034 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_TS, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
4040 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseSelectorNotPresentWithErr(PIEMCPU pIemCpu, uint16_t uErr)
4042 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_NP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, uErr, 0);
4047 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseSelectorNotPresentBySegReg(PIEMCPU pIemCpu, uint32_t iSegReg)
4049 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_NP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
4050 iemSRegFetchU16(pIemCpu, iSegReg) & ~X86_SEL_RPL, 0);
4055 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseSelectorNotPresentBySelector(PIEMCPU pIemCpu, uint16_t uSel)
4057 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_NP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
4063 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseStackSelectorNotPresentBySelector(PIEMCPU pIemCpu, uint16_t uSel)
4065 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_SS, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
4071 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseStackSelectorNotPresentWithErr(PIEMCPU pIemCpu, uint16_t uErr)
4073 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_SS, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, uErr, 0);
4078 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseGeneralProtectionFault(PIEMCPU pIemCpu, uint16_t uErr)
4080 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, uErr, 0);
4085 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseGeneralProtectionFault0(PIEMCPU pIemCpu)
4087 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0);
4092 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseGeneralProtectionFaultBySelector(PIEMCPU pIemCpu, RTSEL Sel)
4094 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
4100 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseNotCanonical(PIEMCPU pIemCpu)
4102 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0);
4107 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseSelectorBounds(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess)
4110 return iemRaiseXcptOrInt(pIemCpu, 0, iSegReg == X86_SREG_SS ? X86_XCPT_SS : X86_XCPT_GP,
4116 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseSelectorBoundsBySelector(PIEMCPU pIemCpu, RTSEL Sel)
4119 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0);
4124 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseSelectorInvalidAccess(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess)
4127 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0);
4132 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaisePageFault(PIEMCPU pIemCpu, RTGCPTR GCPtrWhere, uint32_t fAccess, int rc)
4153 if (pIemCpu->uCpl == 3)
4157 && ( (pIemCpu->CTX_SUFF(pCtx)->cr4 & X86_CR4_PAE)
4158 && (pIemCpu->CTX_SUFF(pCtx)->msrEFER & MSR_K6_EFER_NXE) ) )
4170 if (!IEM_FULL_VERIFICATION_REM_ENABLED(pIemCpu) || !(fAccess & IEM_ACCESS_TYPE_READ))
4175 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_PF, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR | IEM_XCPT_FLAGS_CR2,
4181 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseMathFault(PIEMCPU pIemCpu)
4183 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_MF, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
4188 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseAlignmentCheckException(PIEMCPU pIemCpu)
4190 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_AC, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
4206 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_DE, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
4222 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_UD, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
4238 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_UD, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
4256 * @param pIemCpu The IEM state.
4258 static void iemRecalEffOpSize(PIEMCPU pIemCpu)
4260 switch (pIemCpu->enmCpuMode)
4263 pIemCpu->enmEffOpSize = pIemCpu->fPrefixes & IEM_OP_PRF_SIZE_OP ? IEMMODE_32BIT : IEMMODE_16BIT;
4266 pIemCpu->enmEffOpSize = pIemCpu->fPrefixes & IEM_OP_PRF_SIZE_OP ? IEMMODE_16BIT : IEMMODE_32BIT;
4269 switch (pIemCpu->fPrefixes & (IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP))
4272 pIemCpu->enmEffOpSize = pIemCpu->enmDefOpSize;
4275 pIemCpu->enmEffOpSize = IEMMODE_16BIT;
4279 pIemCpu->enmEffOpSize = IEMMODE_64BIT;
4293 * @param pIemCpu The IEM state.
4295 static void iemRecalEffOpSize64Default(PIEMCPU pIemCpu)
4297 Assert(pIemCpu->enmCpuMode == IEMMODE_64BIT);
4298 pIemCpu->enmDefOpSize = IEMMODE_64BIT;
4299 if ((pIemCpu->fPrefixes & (IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP)) != IEM_OP_PRF_SIZE_OP)
4300 pIemCpu->enmEffOpSize = IEMMODE_64BIT;
4302 pIemCpu->enmEffOpSize = IEMMODE_16BIT;
4317 * @param pIemCpu The IEM per CPU state.
4319 static void iemOpStubMsg2(PIEMCPU pIemCpu)
4322 PVM pVM = IEMCPU_TO_VM(pIemCpu);
4323 PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu);
4359 RTAssertMsg2Weak("cs:rip=%04x:%RX64\n", pIemCpu->CTX_SUFF(pCtx)->cs, pIemCpu->CTX_SUFF(pCtx)->rip);
4373 iemOpStubMsg2(pIemCpu); \
4428 * @param pIemCpu The per CPU data.
4431 static PCPUMSELREG iemSRegGetHid(PIEMCPU pIemCpu, uint8_t iSegReg)
4433 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
4447 if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(IEMCPU_TO_VMCPU(pIemCpu), pSReg))
4448 CPUMGuestLazyLoadHiddenSelectorReg(IEMCPU_TO_VMCPU(pIemCpu), pSReg);
4450 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(IEMCPU_TO_VMCPU(pIemCpu), pSReg));
4461 * @param pIemCpu The per CPU data.
4464 static uint16_t *iemSRegRef(PIEMCPU pIemCpu, uint8_t iSegReg)
4466 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
4484 * @param pIemCpu The per CPU data.
4487 static uint16_t iemSRegFetchU16(PIEMCPU pIemCpu, uint8_t iSegReg)
4489 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
4507 * @param pIemCpu The per CPU data.
4510 static void *iemGRegRef(PIEMCPU pIemCpu, uint8_t iReg)
4512 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
4542 * @param pIemCpu The per CPU data.
4545 static uint8_t *iemGRegRefU8(PIEMCPU pIemCpu, uint8_t iReg)
4547 if (pIemCpu->fPrefixes & IEM_OP_PRF_REX)
4548 return (uint8_t *)iemGRegRef(pIemCpu, iReg);
4550 uint8_t *pu8Reg = (uint8_t *)iemGRegRef(pIemCpu, iReg & 3);
4561 * @param pIemCpu The per CPU data.
4564 static uint8_t iemGRegFetchU8(PIEMCPU pIemCpu, uint8_t iReg)
4566 uint8_t const *pbSrc = iemGRegRefU8(pIemCpu, iReg);
4575 * @param pIemCpu The per CPU data.
4578 static uint16_t iemGRegFetchU16(PIEMCPU pIemCpu, uint8_t iReg)
4580 return *(uint16_t *)iemGRegRef(pIemCpu, iReg);
4588 * @param pIemCpu The per CPU data.
4591 static uint32_t iemGRegFetchU32(PIEMCPU pIemCpu, uint8_t iReg)
4593 return *(uint32_t *)iemGRegRef(pIemCpu, iReg);
4601 * @param pIemCpu The per CPU data.
4604 static uint64_t iemGRegFetchU64(PIEMCPU pIemCpu, uint8_t iReg)
4606 return *(uint64_t *)iemGRegRef(pIemCpu, iReg);
4616 * @param pIemCpu The per CPU data.
4619 static VBOXSTRICTRC iemRegRipRelativeJumpS8(PIEMCPU pIemCpu, int8_t offNextInstr)
4621 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
4622 switch (pIemCpu->enmEffOpSize)
4626 uint16_t uNewIp = pCtx->ip + offNextInstr + pIemCpu->offOpcode;
4628 && pIemCpu->enmCpuMode != IEMMODE_64BIT) /* no need to check for non-canonical. */
4629 return iemRaiseGeneralProtectionFault0(pIemCpu);
4637 Assert(pIemCpu->enmCpuMode != IEMMODE_64BIT);
4639 uint32_t uNewEip = pCtx->eip + offNextInstr + pIemCpu->offOpcode;
4641 return iemRaiseGeneralProtectionFault0(pIemCpu);
4648 Assert(pIemCpu->enmCpuMode == IEMMODE_64BIT);
4650 uint64_t uNewRip = pCtx->rip + offNextInstr + pIemCpu->offOpcode;
4652 return iemRaiseGeneralProtectionFault0(pIemCpu);
4672 * @param pIemCpu The per CPU data.
4675 static VBOXSTRICTRC iemRegRipRelativeJumpS16(PIEMCPU pIemCpu, int16_t offNextInstr)
4677 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
4678 Assert(pIemCpu->enmEffOpSize == IEMMODE_16BIT);
4680 uint16_t uNewIp = pCtx->ip + offNextInstr + pIemCpu->offOpcode;
4682 && pIemCpu->enmCpuMode != IEMMODE_64BIT) /* no need to check for non-canonical. */
4683 return iemRaiseGeneralProtectionFault0(pIemCpu);
4699 * @param pIemCpu The per CPU data.
4702 static VBOXSTRICTRC iemRegRipRelativeJumpS32(PIEMCPU pIemCpu, int32_t offNextInstr)
4704 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
4705 Assert(pIemCpu->enmEffOpSize != IEMMODE_16BIT);
4707 if (pIemCpu->enmEffOpSize == IEMMODE_32BIT)
4709 Assert(pCtx->rip <= UINT32_MAX); Assert(pIemCpu->enmCpuMode != IEMMODE_64BIT);
4711 uint32_t uNewEip = pCtx->eip + offNextInstr + pIemCpu->offOpcode;
4713 return iemRaiseGeneralProtectionFault0(pIemCpu);
4718 Assert(pIemCpu->enmCpuMode == IEMMODE_64BIT);
4720 uint64_t uNewRip = pCtx->rip + offNextInstr + pIemCpu->offOpcode;
4722 return iemRaiseGeneralProtectionFault0(pIemCpu);
4736 * @param pIemCpu The per CPU data.
4739 static VBOXSTRICTRC iemRegRipJump(PIEMCPU pIemCpu, uint64_t uNewRip)
4741 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
4742 switch (pIemCpu->enmEffOpSize)
4748 && pIemCpu->enmCpuMode != IEMMODE_64BIT) /* no need to check for non-canonical. */
4749 return iemRaiseGeneralProtectionFault0(pIemCpu);
4759 Assert(pIemCpu->enmCpuMode != IEMMODE_64BIT);
4762 return iemRaiseGeneralProtectionFault0(pIemCpu);
4769 Assert(pIemCpu->enmCpuMode == IEMMODE_64BIT);
4772 return iemRaiseGeneralProtectionFault0(pIemCpu);
4788 * @param pIemCpu The per CPU data.
4792 DECLINLINE(RTGCPTR) iemRegGetEffRsp(PCIEMCPU pIemCpu, PCCPUMCTX pCtx)
4794 if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
4807 * @param pIemCpu The per CPU data.
4810 static void iemRegAddToRipKeepRF(PIEMCPU pIemCpu, uint8_t cbInstr)
4812 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
4813 switch (pIemCpu->enmCpuMode)
4838 * @param pIemCpu The per CPU data.
4840 static void iemRegUpdateRipKeepRF(PIEMCPU pIemCpu)
4842 return iemRegAddToRipKeepRF(pIemCpu, pIemCpu->offOpcode);
4851 * @param pIemCpu The per CPU data.
4854 static void iemRegAddToRipAndClearRF(PIEMCPU pIemCpu, uint8_t cbInstr)
4856 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
4860 switch (pIemCpu->enmCpuMode)
4884 * @param pIemCpu The per CPU data.
4886 static void iemRegUpdateRipAndClearRF(PIEMCPU pIemCpu)
4888 return iemRegAddToRipAndClearRF(pIemCpu, pIemCpu->offOpcode);
4895 * @param pIemCpu The per CPU data.
4900 DECLINLINE(void) iemRegAddToRsp(PCIEMCPU pIemCpu, PCPUMCTX pCtx, uint8_t cbToAdd)
4902 if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
4914 * @param pIemCpu The per CPU data.
4919 DECLINLINE(void) iemRegSubFromRsp(PCIEMCPU pIemCpu, PCPUMCTX pCtx, uint8_t cbToSub)
4921 if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
4933 * @param pIemCpu The per CPU data.
4938 DECLINLINE(void) iemRegAddToRspEx(PCIEMCPU pIemCpu, PCCPUMCTX pCtx, PRTUINT64U pTmpRsp, uint16_t cbToAdd)
4940 if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
4952 * @param pIemCpu The per CPU data.
4959 DECLINLINE(void) iemRegSubFromRspEx(PCIEMCPU pIemCpu, PCCPUMCTX pCtx, PRTUINT64U pTmpRsp, uint16_t cbToSub)
4961 if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
4975 * @param pIemCpu The IEM per CPU data.
4980 DECLINLINE(RTGCPTR) iemRegGetRspForPush(PCIEMCPU pIemCpu, PCCPUMCTX pCtx, uint8_t cbItem, uint64_t *puNewRsp)
4986 if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
5002 * @param pIemCpu The per CPU data.
5007 DECLINLINE(RTGCPTR) iemRegGetRspForPop(PCIEMCPU pIemCpu, PCCPUMCTX pCtx, uint8_t cbItem, uint64_t *puNewRsp)
5013 if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
5038 * @param pIemCpu The per CPU data.
5043 DECLINLINE(RTGCPTR) iemRegGetRspForPushEx(PCIEMCPU pIemCpu, PCCPUMCTX pCtx, PRTUINT64U pTmpRsp, uint8_t cbItem)
5047 if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
5062 * @param pIemCpu The per CPU data.
5067 DECLINLINE(RTGCPTR) iemRegGetRspForPopEx(PCIEMCPU pIemCpu, PCCPUMCTX pCtx, PRTUINT64U pTmpRsp, uint8_t cbItem)
5070 if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
5102 * @param pIemCpu The IEM per CPU data.
5104 DECLINLINE(void) iemFpuPrepareUsage(PIEMCPU pIemCpu)
5107 NOREF(pIemCpu);
5120 * @param pIemCpu The IEM per CPU data.
5122 DECLINLINE(void) iemFpuPrepareUsageSse(PIEMCPU pIemCpu)
5124 iemFpuPrepareUsage(pIemCpu);
5144 * @param pIemCpu The IEM per CPU data.
5148 DECLINLINE(void) iemFpuUpdateOpcodeAndIpWorker(PIEMCPU pIemCpu, PCPUMCTX pCtx, PX86FXSTATE pFpuCtx)
5150 pFpuCtx->FOP = pIemCpu->abOpcode[pIemCpu->offFpuOpcode]
5151 | ((uint16_t)(pIemCpu->abOpcode[pIemCpu->offFpuOpcode - 1] & 0x7) << 8);
5153 if (IEM_IS_REAL_OR_V86_MODE(pIemCpu))
5171 * @param pIemCpu The IEM per CPU data.
5177 DECLINLINE(void) iemFpuUpdateDP(PIEMCPU pIemCpu, PCPUMCTX pCtx, PX86FXSTATE pFpuCtx, uint8_t iEffSeg, RTGCPTR GCPtrEff)
5193 if (IEM_IS_REAL_OR_V86_MODE(pIemCpu))
5252 * @param pIemCpu The IEM per CPU data.
5256 static void iemFpuMaybePushResult(PIEMCPU pIemCpu, PIEMFPURESULT pResult, PX86FXSTATE pFpuCtx)
5360 * @param pIemCpu The IEM per CPU data.
5363 static void iemFpuPushResult(PIEMCPU pIemCpu, PIEMFPURESULT pResult)
5365 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5367 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5368 iemFpuMaybePushResult(pIemCpu, pResult, pFpuCtx);
5376 * @param pIemCpu The IEM per CPU data.
5381 static void iemFpuPushResultWithMemOp(PIEMCPU pIemCpu, PIEMFPURESULT pResult, uint8_t iEffSeg, RTGCPTR GCPtrEff)
5383 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5385 iemFpuUpdateDP(pIemCpu, pCtx, pFpuCtx, iEffSeg, GCPtrEff);
5386 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5387 iemFpuMaybePushResult(pIemCpu, pResult, pFpuCtx);
5395 * @param pIemCpu The IEM per CPU data.
5398 static void iemFpuPushResultTwo(PIEMCPU pIemCpu, PIEMFPURESULTTWO pResult)
5400 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5402 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5449 * @param pIemCpu The IEM per CPU data.
5454 static void iemFpuStoreResult(PIEMCPU pIemCpu, PIEMFPURESULT pResult, uint8_t iStReg)
5456 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5458 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5467 * @param pIemCpu The IEM per CPU data.
5472 static void iemFpuStoreResultThenPop(PIEMCPU pIemCpu, PIEMFPURESULT pResult, uint8_t iStReg)
5474 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5476 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5486 * @param pIemCpu The IEM per CPU data.
5493 static void iemFpuStoreResultWithMemOp(PIEMCPU pIemCpu, PIEMFPURESULT pResult, uint8_t iStReg, uint8_t iEffSeg, RTGCPTR GCPtrEff)
5495 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5497 iemFpuUpdateDP(pIemCpu, pCtx, pFpuCtx, iEffSeg, GCPtrEff);
5498 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5507 * @param pIemCpu The IEM per CPU data.
5514 static void iemFpuStoreResultWithMemOpThenPop(PIEMCPU pIemCpu, PIEMFPURESULT pResult,
5517 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5519 iemFpuUpdateDP(pIemCpu, pCtx, pFpuCtx, iEffSeg, GCPtrEff);
5520 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5529 * @param pIemCpu The IEM per CPU data.
5531 static void iemFpuUpdateOpcodeAndIp(PIEMCPU pIemCpu)
5533 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5535 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5542 * @param pIemCpu The IEM per CPU data.
5545 static void iemFpuStackFree(PIEMCPU pIemCpu, uint8_t iStReg)
5548 PX86FXSTATE pFpuCtx = &pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87;
5557 * @param pIemCpu The IEM per CPU data.
5559 static void iemFpuStackIncTop(PIEMCPU pIemCpu)
5561 PX86FXSTATE pFpuCtx = &pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87;
5574 * @param pIemCpu The IEM per CPU data.
5576 static void iemFpuStackDecTop(PIEMCPU pIemCpu)
5578 PX86FXSTATE pFpuCtx = &pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87;
5591 * @param pIemCpu The IEM per CPU data.
5594 static void iemFpuUpdateFSW(PIEMCPU pIemCpu, uint16_t u16FSW)
5596 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5598 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5606 * @param pIemCpu The IEM per CPU data.
5609 static void iemFpuUpdateFSWThenPop(PIEMCPU pIemCpu, uint16_t u16FSW)
5611 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5613 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5622 * @param pIemCpu The IEM per CPU data.
5627 static void iemFpuUpdateFSWWithMemOp(PIEMCPU pIemCpu, uint16_t u16FSW, uint8_t iEffSeg, RTGCPTR GCPtrEff)
5629 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5631 iemFpuUpdateDP(pIemCpu, pCtx, pFpuCtx, iEffSeg, GCPtrEff);
5632 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5640 * @param pIemCpu The IEM per CPU data.
5643 static void iemFpuUpdateFSWThenPopPop(PIEMCPU pIemCpu, uint16_t u16FSW)
5645 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5647 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5657 * @param pIemCpu The IEM per CPU data.
5662 static void iemFpuUpdateFSWWithMemOpThenPop(PIEMCPU pIemCpu, uint16_t u16FSW, uint8_t iEffSeg, RTGCPTR GCPtrEff)
5664 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5666 iemFpuUpdateDP(pIemCpu, pCtx, pFpuCtx, iEffSeg, GCPtrEff);
5667 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5676 * @param pIemCpu The IEM per CPU data.
5680 static void iemFpuStackUnderflowOnly(PIEMCPU pIemCpu, PX86FXSTATE pFpuCtx, uint8_t iStReg)
5706 * @param pIemCpu The IEM per CPU data.
5711 DECL_NO_INLINE(static, void) iemFpuStackUnderflow(PIEMCPU pIemCpu, uint8_t iStReg)
5713 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5715 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5716 iemFpuStackUnderflowOnly(pIemCpu, pFpuCtx, iStReg);
5721 iemFpuStackUnderflowWithMemOp(PIEMCPU pIemCpu, uint8_t iStReg, uint8_t iEffSeg, RTGCPTR GCPtrEff)
5723 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5725 iemFpuUpdateDP(pIemCpu, pCtx, pFpuCtx, iEffSeg, GCPtrEff);
5726 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5727 iemFpuStackUnderflowOnly(pIemCpu, pFpuCtx, iStReg);
5731 DECL_NO_INLINE(static, void) iemFpuStackUnderflowThenPop(PIEMCPU pIemCpu, uint8_t iStReg)
5733 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5735 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5736 iemFpuStackUnderflowOnly(pIemCpu, pFpuCtx, iStReg);
5742 iemFpuStackUnderflowWithMemOpThenPop(PIEMCPU pIemCpu, uint8_t iStReg, uint8_t iEffSeg, RTGCPTR GCPtrEff)
5744 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5746 iemFpuUpdateDP(pIemCpu, pCtx, pFpuCtx, iEffSeg, GCPtrEff);
5747 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5748 iemFpuStackUnderflowOnly(pIemCpu, pFpuCtx, iStReg);
5753 DECL_NO_INLINE(static, void) iemFpuStackUnderflowThenPopPop(PIEMCPU pIemCpu)
5755 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5757 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5758 iemFpuStackUnderflowOnly(pIemCpu, pFpuCtx, UINT8_MAX);
5765 iemFpuStackPushUnderflow(PIEMCPU pIemCpu)
5767 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5769 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5792 iemFpuStackPushUnderflowTwo(PIEMCPU pIemCpu)
5794 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5796 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5849 * @param pIemCpu The IEM per CPU data.
5851 DECL_NO_INLINE(static, void) iemFpuStackPushOverflow(PIEMCPU pIemCpu)
5853 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5855 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5863 * @param pIemCpu The IEM per CPU data.
5868 iemFpuStackPushOverflowWithMemOp(PIEMCPU pIemCpu, uint8_t iEffSeg, RTGCPTR GCPtrEff)
5870 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
5872 iemFpuUpdateDP(pIemCpu, pCtx, pFpuCtx, iEffSeg, GCPtrEff);
5873 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx, pFpuCtx);
5878 static int iemFpuStRegNotEmpty(PIEMCPU pIemCpu, uint8_t iStReg)
5880 PX86FXSTATE pFpuCtx = &pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87;
5888 static int iemFpuStRegNotEmptyRef(PIEMCPU pIemCpu, uint8_t iStReg, PCRTFLOAT80U *ppRef)
5890 PX86FXSTATE pFpuCtx = &pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87;
5901 static int iemFpu2StRegsNotEmptyRef(PIEMCPU pIemCpu, uint8_t iStReg0, PCRTFLOAT80U *ppRef0,
5904 PX86FXSTATE pFpuCtx = &pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87;
5918 static int iemFpu2StRegsNotEmptyRefFirst(PIEMCPU pIemCpu, uint8_t iStReg0, PCRTFLOAT80U *ppRef0, uint8_t iStReg1)
5920 PX86FXSTATE pFpuCtx = &pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87;
6022 * @param pIemCpu The IEM per CPU data.
6026 DECL_FORCE_INLINE(void) iemMemUpdateWrittenCounter(PIEMCPU pIemCpu, uint32_t fAccess, size_t cbMem)
6030 pIemCpu->cbWritten += (uint32_t)cbMem;
6040 * @param pIemCpu The IEM per CPU data.
6047 static VBOXSTRICTRC iemMemSegCheckWriteAccessEx(PIEMCPU pIemCpu, PCCPUMSELREGHID pHid, uint8_t iSegReg, uint64_t *pu64BaseAddr)
6049 if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
6054 return iemRaiseSelectorNotPresentBySegReg(pIemCpu, iSegReg);
6058 && pIemCpu->enmCpuMode != IEMMODE_64BIT )
6059 return iemRaiseSelectorInvalidAccess(pIemCpu, iSegReg, IEM_ACCESS_DATA_W);
6072 * @param pIemCpu The IEM per CPU data.
6079 static VBOXSTRICTRC iemMemSegCheckReadAccessEx(PIEMCPU pIemCpu, PCCPUMSELREGHID pHid, uint8_t iSegReg, uint64_t *pu64BaseAddr)
6081 if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
6086 return iemRaiseSelectorNotPresentBySegReg(pIemCpu, iSegReg);
6089 return iemRaiseSelectorInvalidAccess(pIemCpu, iSegReg, IEM_ACCESS_DATA_R);
6103 * @param pIemCpu The IEM per CPU data.
6111 static VBOXSTRICTRC iemMemApplySegment(PIEMCPU pIemCpu, uint32_t fAccess, uint8_t iSegReg,
6117 PCPUMSELREGHID pSel = iemSRegGetHid(pIemCpu, iSegReg);
6118 switch (pIemCpu->enmCpuMode)
6132 return iemRaiseSelectorInvalidAccess(pIemCpu, iSegReg, fAccess);
6134 if (!IEM_IS_REAL_OR_V86_MODE(pIemCpu))
6146 return iemRaiseSelectorBounds(pIemCpu, iSegReg, fAccess);
6155 return iemRaiseSelectorBounds(pIemCpu, iSegReg, fAccess);
6169 && !IEM_IS_REAL_OR_V86_MODE(pIemCpu) )
6170 return iemRaiseSelectorInvalidAccess(pIemCpu, iSegReg, fAccess);
6174 return iemRaiseSelectorBounds(pIemCpu, iSegReg, fAccess);
6176 if (!IEM_IS_REAL_OR_V86_MODE(pIemCpu))
6201 * @param pIemCpu The IEM per CPU data.
6206 static VBOXSTRICTRC iemMemPageTranslateAndCheckAccess(PIEMCPU pIemCpu, RTGCPTR GCPtrMem, uint32_t fAccess,
6213 int rc = PGMGstGetPage(IEMCPU_TO_VMCPU(pIemCpu), GCPtrMem, &fFlags, &GCPhys);
6219 return iemRaisePageFault(pIemCpu, GCPtrMem, fAccess, rc);
6229 && ( pIemCpu->uCpl != 0
6230 || (pIemCpu->CTX_SUFF(pCtx)->cr0 & X86_CR0_WP)))
6234 return iemRaisePageFault(pIemCpu, GCPtrMem, fAccess & ~IEM_ACCESS_TYPE_READ, VERR_ACCESS_DENIED);
6239 && pIemCpu->uCpl == 3
6244 return iemRaisePageFault(pIemCpu, GCPtrMem, fAccess, VERR_ACCESS_DENIED);
6250 && (pIemCpu->CTX_SUFF(pCtx)->msrEFER & MSR_K6_EFER_NXE) )
6254 return iemRaisePageFault(pIemCpu, GCPtrMem, fAccess & ~(IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_WRITE),
6267 int rc2 = PGMGstModifyPage(IEMCPU_TO_VMCPU(pIemCpu), GCPtrMem, 1, fAccessedDirty, ~(uint64_t)fAccessedDirty);
6282 * @param pIemCpu The IEM per CPU data.
6288 static int iemMemPageMap(PIEMCPU pIemCpu, RTGCPHYS GCPhysMem, uint32_t fAccess, void **ppvMem, PPGMPAGEMAPLOCK pLock)
6292 if ((fAccess & IEM_ACCESS_TYPE_WRITE) && !pIemCpu->fNoRem)
6294 if (IEM_FULL_VERIFICATION_ENABLED(pIemCpu))
6296 int rc2 = PGMPhysIemQueryAccess(IEMCPU_TO_VM(pIemCpu), GCPhysMem,
6297 RT_BOOL(fAccess & IEM_ACCESS_TYPE_WRITE), pIemCpu->fBypassHandlers);
6299 pIemCpu->fProblematicMemory = true;
6316 int rc = PGMPhysIemGCPhys2Ptr(IEMCPU_TO_VM(pIemCpu), IEMCPU_TO_VMCPU(pIemCpu),
6319 pIemCpu->fBypassHandlers,
6326 if (RT_FAILURE(rc) && IEM_FULL_VERIFICATION_ENABLED(pIemCpu))
6327 pIemCpu->fProblematicMemory = true;
6336 * @param pIemCpu The IEM per CPU data.
6342 DECLINLINE(void) iemMemPageUnmap(PIEMCPU pIemCpu, RTGCPHYS GCPhysMem, uint32_t fAccess, const void *pvMem, PPGMPAGEMAPLOCK pLock)
6344 NOREF(pIemCpu);
6348 PGMPhysReleasePageMappingLock(IEMCPU_TO_VM(pIemCpu), pLock);
6356 * @param pIemCpu The IEM per CPU data.
6360 DECLINLINE(int) iemMapLookup(PIEMCPU pIemCpu, void *pvMem, uint32_t fAccess)
6363 if ( pIemCpu->aMemMappings[0].pv == pvMem
6364 && (pIemCpu->aMemMappings[0].fAccess & (IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_MASK)) == fAccess)
6366 if ( pIemCpu->aMemMappings[1].pv == pvMem
6367 && (pIemCpu->aMemMappings[1].fAccess & (IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_MASK)) == fAccess)
6369 if ( pIemCpu->aMemMappings[2].pv == pvMem
6370 && (pIemCpu->aMemMappings[2].fAccess & (IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_MASK)) == fAccess)
6380 * @param pIemCpu The IEM per CPU data.
6382 static unsigned iemMemMapFindFree(PIEMCPU pIemCpu)
6387 if (pIemCpu->cActiveMappings == 0)
6389 pIemCpu->iNextMapping = 1;
6394 AssertReturn(pIemCpu->cActiveMappings < RT_ELEMENTS(pIemCpu->aMemMappings), 1024);
6396 for (unsigned i = 0; i < RT_ELEMENTS(pIemCpu->aMemMappings); i++)
6397 if (pIemCpu->aMemMappings[i].fAccess == IEM_ACCESS_INVALID)
6408 * @param pIemCpu The IEM per CPU data.
6411 static VBOXSTRICTRC iemMemBounceBufferCommitAndUnmap(PIEMCPU pIemCpu, unsigned iMemMap)
6413 Assert(pIemCpu->aMemMappings[iMemMap].fAccess & IEM_ACCESS_BOUNCE_BUFFERED);
6414 Assert(pIemCpu->aMemMappings[iMemMap].fAccess & IEM_ACCESS_TYPE_WRITE);
6421 if ( !pIemCpu->aMemBbMappings[iMemMap].fUnassigned
6422 && !IEM_VERIFICATION_ENABLED(pIemCpu))
6424 uint16_t const cbFirst = pIemCpu->aMemBbMappings[iMemMap].cbFirst;
6425 uint16_t const cbSecond = pIemCpu->aMemBbMappings[iMemMap].cbSecond;
6426 uint8_t const *pbBuf = &pIemCpu->aBounceBuffers[iMemMap].ab[0];
6427 if (!pIemCpu->fBypassHandlers)
6429 rc = PGMPhysWrite(IEMCPU_TO_VM(pIemCpu),
6430 pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst,
6434 rc = PGMPhysWrite(IEMCPU_TO_VM(pIemCpu),
6435 pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond,
6441 rc = PGMPhysSimpleWriteGCPhys(IEMCPU_TO_VM(pIemCpu),
6442 pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst,
6446 rc = PGMPhysSimpleWriteGCPhys(IEMCPU_TO_VM(pIemCpu),
6447 pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond,
6455 pIemCpu->fBypassHandlers ? "PGMPhysWrite" : "PGMPhysSimpleWriteGCPhys",
6456 pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst, cbFirst,
6457 pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond, cbSecond, rc));
6468 if (!pIemCpu->fNoRem)
6470 PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
6474 pEvtRec->u.RamWrite.GCPhys = pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst;
6475 pEvtRec->u.RamWrite.cb = pIemCpu->aMemBbMappings[iMemMap].cbFirst;
6476 memcpy(pEvtRec->u.RamWrite.ab, &pIemCpu->aBounceBuffers[iMemMap].ab[0], pIemCpu->aMemBbMappings[iMemMap].cbFirst);
6477 AssertCompile(sizeof(pEvtRec->u.RamWrite.ab) == sizeof(pIemCpu->aBounceBuffers[0].ab));
6478 pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
6479 *pIemCpu->ppIemEvtRecNext = pEvtRec;
6481 if (pIemCpu->aMemBbMappings[iMemMap].cbSecond)
6483 pEvtRec = iemVerifyAllocRecord(pIemCpu);
6487 pEvtRec->u.RamWrite.GCPhys = pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond;
6488 pEvtRec->u.RamWrite.cb = pIemCpu->aMemBbMappings[iMemMap].cbSecond;
6490 &pIemCpu->aBounceBuffers[iMemMap].ab[pIemCpu->aMemBbMappings[iMemMap].cbFirst],
6491 pIemCpu->aMemBbMappings[iMemMap].cbSecond);
6492 pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
6493 *pIemCpu->ppIemEvtRecNext = pEvtRec;
6501 Log(("IEM Wrote %RGp: %.*Rhxs\n", pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst,
6502 RT_MAX(RT_MIN(pIemCpu->aMemBbMappings[iMemMap].cbFirst, 64), 1), &pIemCpu->aBounceBuffers[iMemMap].ab[0]));
6503 if (pIemCpu->aMemBbMappings[iMemMap].cbSecond)
6504 Log(("IEM Wrote %RGp: %.*Rhxs [2nd page]\n", pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond,
6505 RT_MIN(pIemCpu->aMemBbMappings[iMemMap].cbSecond, 64),
6506 &pIemCpu->aBounceBuffers[iMemMap].ab[pIemCpu->aMemBbMappings[iMemMap].cbFirst]));
6508 size_t cbWrote = pIemCpu->aMemBbMappings[iMemMap].cbFirst + pIemCpu->aMemBbMappings[iMemMap].cbSecond;
6510 memcpy(g_abIemWrote, &pIemCpu->aBounceBuffers[iMemMap].ab[0], RT_MIN(cbWrote, sizeof(g_abIemWrote)));
6517 pIemCpu->aMemMappings[iMemMap].fAccess = IEM_ACCESS_INVALID;
6518 Assert(pIemCpu->cActiveMappings != 0);
6519 pIemCpu->cActiveMappings--;
6527 static VBOXSTRICTRC iemMemBounceBufferMapCrossPage(PIEMCPU pIemCpu, int iMemMap, void **ppvMem,
6534 VBOXSTRICTRC rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, GCPtrFirst, fAccess, &GCPhysFirst);
6541 rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, GCPtrFirst + (cbMem - 1), fAccess, &GCPhysSecond);
6551 if (IEM_FULL_VERIFICATION_ENABLED(pIemCpu))
6553 int rc2 = PGMPhysIemQueryAccess(IEMCPU_TO_VM(pIemCpu), GCPhysFirst,
6554 RT_BOOL(fAccess & IEM_ACCESS_TYPE_WRITE), pIemCpu->fBypassHandlers);
6556 rc2 = PGMPhysIemQueryAccess(IEMCPU_TO_VM(pIemCpu), GCPhysSecond,
6557 RT_BOOL(fAccess & IEM_ACCESS_TYPE_WRITE), pIemCpu->fBypassHandlers);
6559 pIemCpu->fProblematicMemory = true;
6568 uint8_t *pbBuf = &pIemCpu->aBounceBuffers[iMemMap].ab[0];
6575 if (!pIemCpu->fBypassHandlers)
6577 rc = PGMPhysRead(IEMCPU_TO_VM(pIemCpu), GCPhysFirst, pbBuf, cbFirstPage);
6584 rc = PGMPhysRead(IEMCPU_TO_VM(pIemCpu), GCPhysSecond, pbBuf + cbFirstPage, cbSecondPage);
6594 rc = PGMPhysSimpleReadGCPhys(IEMCPU_TO_VM(pIemCpu), pbBuf, GCPhysFirst, cbFirstPage);
6601 rc = PGMPhysSimpleReadGCPhys(IEMCPU_TO_VM(pIemCpu), pbBuf + cbFirstPage, GCPhysSecond, cbSecondPage);
6611 if ( !pIemCpu->fNoRem
6617 PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
6623 pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
6624 *pIemCpu->ppIemEvtRecNext = pEvtRec;
6626 pEvtRec = iemVerifyAllocRecord(pIemCpu);
6632 pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
6633 *pIemCpu->ppIemEvtRecNext = pEvtRec;
6643 if (cbMem < sizeof(pIemCpu->aBounceBuffers[iMemMap].ab))
6644 memset(pbBuf + cbMem, 0xaa, sizeof(pIemCpu->aBounceBuffers[iMemMap].ab) - cbMem);
6650 pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst = GCPhysFirst;
6651 pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond = GCPhysSecond;
6652 pIemCpu->aMemBbMappings[iMemMap].cbFirst = (uint16_t)cbFirstPage;
6653 pIemCpu->aMemBbMappings[iMemMap].cbSecond = (uint16_t)cbSecondPage;
6654 pIemCpu->aMemBbMappings[iMemMap].fUnassigned = false;
6655 pIemCpu->aMemMappings[iMemMap].pv = pbBuf;
6656 pIemCpu->aMemMappings[iMemMap].fAccess = fAccess | IEM_ACCESS_BOUNCE_BUFFERED;
6657 pIemCpu->iNextMapping = iMemMap + 1;
6658 pIemCpu->cActiveMappings++;
6660 iemMemUpdateWrittenCounter(pIemCpu, fAccess, cbMem);
6669 static VBOXSTRICTRC iemMemBounceBufferMapPhys(PIEMCPU pIemCpu, unsigned iMemMap, void **ppvMem, size_t cbMem,
6682 pIemCpu->cPotentialExits++;
6688 uint8_t *pbBuf = &pIemCpu->aBounceBuffers[iMemMap].ab[0];
6696 if (!pIemCpu->fBypassHandlers)
6697 rc = PGMPhysRead(IEMCPU_TO_VM(pIemCpu), GCPhysFirst, pbBuf, cbMem);
6699 rc = PGMPhysSimpleReadGCPhys(IEMCPU_TO_VM(pIemCpu), pbBuf, GCPhysFirst, cbMem);
6704 pIemCpu->fBypassHandlers ? "PGMPhysRead" : "PGMPhysSimpleReadGCPhys", GCPhysFirst, rc));
6710 if ( !pIemCpu->fNoRem
6716 PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
6722 pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
6723 *pIemCpu->ppIemEvtRecNext = pEvtRec;
6733 if (cbMem < sizeof(pIemCpu->aBounceBuffers[iMemMap].ab))
6734 memset(pbBuf + cbMem, 0xaa, sizeof(pIemCpu->aBounceBuffers[iMemMap].ab) - cbMem);
6740 pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst = GCPhysFirst;
6741 pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond = NIL_RTGCPHYS;
6742 pIemCpu->aMemBbMappings[iMemMap].cbFirst = (uint16_t)cbMem;
6743 pIemCpu->aMemBbMappings[iMemMap].cbSecond = 0;
6744 pIemCpu->aMemBbMappings[iMemMap].fUnassigned = rcMap == VERR_PGM_PHYS_TLB_UNASSIGNED;
6745 pIemCpu->aMemMappings[iMemMap].pv = pbBuf;
6746 pIemCpu->aMemMappings[iMemMap].fAccess = fAccess | IEM_ACCESS_BOUNCE_BUFFERED;
6747 pIemCpu->iNextMapping = iMemMap + 1;
6748 pIemCpu->cActiveMappings++;
6750 iemMemUpdateWrittenCounter(pIemCpu, fAccess, cbMem);
6769 * @param pIemCpu The IEM per CPU data.
6786 static VBOXSTRICTRC iemMemMap(PIEMCPU pIemCpu, void **ppvMem, size_t cbMem, uint8_t iSegReg, RTGCPTR GCPtrMem, uint32_t fAccess)
6794 unsigned iMemMap = pIemCpu->iNextMapping;
6795 if ( iMemMap >= RT_ELEMENTS(pIemCpu->aMemMappings)
6796 || pIemCpu->aMemMappings[iMemMap].fAccess != IEM_ACCESS_INVALID)
6798 iMemMap = iemMemMapFindFree(pIemCpu);
6799 AssertReturn(iMemMap < RT_ELEMENTS(pIemCpu->aMemMappings), VERR_INTERNAL_ERROR_3);
6806 VBOXSTRICTRC rcStrict = iemMemApplySegment(pIemCpu, fAccess, iSegReg, cbMem, &GCPtrMem);
6811 return iemMemBounceBufferMapCrossPage(pIemCpu, iMemMap, ppvMem, cbMem, GCPtrMem, fAccess);
6814 rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, GCPtrMem, fAccess, &GCPhysFirst);
6819 rcStrict = iemMemPageMap(pIemCpu, GCPhysFirst, fAccess, &pvMem, &pIemCpu->aMemMappingLocks[iMemMap].Lock);
6821 return iemMemBounceBufferMapPhys(pIemCpu, iMemMap, ppvMem, cbMem, GCPhysFirst, fAccess, rcStrict);
6826 pIemCpu->aMemMappings[iMemMap].pv = pvMem;
6827 pIemCpu->aMemMappings[iMemMap].fAccess = fAccess;
6828 pIemCpu->iNextMapping = iMemMap + 1;
6829 pIemCpu->cActiveMappings++;
6831 iemMemUpdateWrittenCounter(pIemCpu, fAccess, cbMem);
6841 * @param pIemCpu The IEM per CPU data.
6845 static VBOXSTRICTRC iemMemCommitAndUnmap(PIEMCPU pIemCpu, void *pvMem, uint32_t fAccess)
6847 int iMemMap = iemMapLookup(pIemCpu, pvMem, fAccess);
6851 if (pIemCpu->aMemMappings[iMemMap].fAccess & IEM_ACCESS_BOUNCE_BUFFERED)
6853 if (pIemCpu->aMemMappings[iMemMap].fAccess & IEM_ACCESS_TYPE_WRITE)
6854 return iemMemBounceBufferCommitAndUnmap(pIemCpu, iMemMap);
6858 PGMPhysReleasePageMappingLock(IEMCPU_TO_VM(pIemCpu), &pIemCpu->aMemMappingLocks[iMemMap].Lock);
6861 pIemCpu->aMemMappings[iMemMap].fAccess = IEM_ACCESS_INVALID;
6862 Assert(pIemCpu->cActiveMappings != 0);
6863 pIemCpu->cActiveMappings--;
6874 * @param pIemCpu The IEM per CPU data.
6876 static void iemMemRollback(PIEMCPU pIemCpu)
6878 Assert(pIemCpu->cActiveMappings > 0);
6880 uint32_t iMemMap = RT_ELEMENTS(pIemCpu->aMemMappings);
6883 uint32_t fAccess = pIemCpu->aMemMappings[iMemMap].fAccess;
6886 pIemCpu->aMemMappings[iMemMap].fAccess = IEM_ACCESS_INVALID;
6888 PGMPhysReleasePageMappingLock(IEMCPU_TO_VM(pIemCpu), &pIemCpu->aMemMappingLocks[iMemMap].Lock);
6889 Assert(pIemCpu->cActiveMappings > 0);
6890 pIemCpu->cActiveMappings--;
6900 * @param pIemCpu The IEM per CPU data.
6906 static VBOXSTRICTRC iemMemFetchDataU8(PIEMCPU pIemCpu, uint8_t *pu8Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
6910 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu8Src, sizeof(*pu8Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
6914 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu8Src, IEM_ACCESS_DATA_R);
6924 * @param pIemCpu The IEM per CPU data.
6930 static VBOXSTRICTRC iemMemFetchDataU16(PIEMCPU pIemCpu, uint16_t *pu16Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
6934 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Src, sizeof(*pu16Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
6938 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu16Src, IEM_ACCESS_DATA_R);
6948 * @param pIemCpu The IEM per CPU data.
6954 static VBOXSTRICTRC iemMemFetchDataU32(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
6958 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Src, sizeof(*pu32Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
6962 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu32Src, IEM_ACCESS_DATA_R);
6973 * @param pIemCpu The IEM per CPU data.
6979 static VBOXSTRICTRC iemMemFetchDataS32SxU64(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
6983 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pi32Src, sizeof(*pi32Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
6987 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pi32Src, IEM_ACCESS_DATA_R);
7002 * @param pIemCpu The IEM per CPU data.
7008 static VBOXSTRICTRC iemMemFetchDataU64(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
7012 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Src, sizeof(*pu64Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
7016 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu64Src, IEM_ACCESS_DATA_R);
7026 * @param pIemCpu The IEM per CPU data.
7032 static VBOXSTRICTRC iemMemFetchDataU64AlignedU128(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
7037 return iemRaiseGeneralProtectionFault0(pIemCpu);
7040 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Src, sizeof(*pu64Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
7044 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu64Src, IEM_ACCESS_DATA_R);
7054 * @param pIemCpu The IEM per CPU data.
7060 static VBOXSTRICTRC iemMemFetchDataR80(PIEMCPU pIemCpu, PRTFLOAT80U pr80Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
7064 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pr80Src, sizeof(*pr80Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
7068 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pr80Src, IEM_ACCESS_DATA_R);
7078 * @param pIemCpu The IEM per CPU data.
7084 static VBOXSTRICTRC iemMemFetchDataU128(PIEMCPU pIemCpu, uint128_t *pu128Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
7088 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu128Src, sizeof(*pu128Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
7092 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu128Src, IEM_ACCESS_DATA_R);
7105 * @param pIemCpu The IEM per CPU data.
7111 static VBOXSTRICTRC iemMemFetchDataU128AlignedSse(PIEMCPU pIemCpu, uint128_t *pu128Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
7116 && !(pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.MXCSR & X86_MXSCR_MM)) /** @todo should probably check this *after* applying seg.u64Base... Check real HW. */
7117 return iemRaiseGeneralProtectionFault0(pIemCpu);
7120 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu128Src, sizeof(*pu128Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
7124 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu128Src, IEM_ACCESS_DATA_R);
7136 * @param pIemCpu The IEM per CPU data.
7144 static VBOXSTRICTRC iemMemFetchDataXdtr(PIEMCPU pIemCpu, uint16_t *pcbLimit, PRTGCPTR pGCPtrBase,
7148 VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu,
7176 rcStrict = iemMemCommitAndUnmap(pIemCpu, (void *)pu8Src, IEM_ACCESS_DATA_R);
7187 * @param pIemCpu The IEM per CPU data.
7193 static VBOXSTRICTRC iemMemStoreDataU8(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, uint8_t u8Value)
7197 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu8Dst, sizeof(*pu8Dst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W);
7201 rc = iemMemCommitAndUnmap(pIemCpu, pu8Dst, IEM_ACCESS_DATA_W);
7211 * @param pIemCpu The IEM per CPU data.
7217 static VBOXSTRICTRC iemMemStoreDataU16(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, uint16_t u16Value)
7221 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Dst, sizeof(*pu16Dst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W);
7225 rc = iemMemCommitAndUnmap(pIemCpu, pu16Dst, IEM_ACCESS_DATA_W);
7235 * @param pIemCpu The IEM per CPU data.
7241 static VBOXSTRICTRC iemMemStoreDataU32(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, uint32_t u32Value)
7245 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Dst, sizeof(*pu32Dst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W);
7249 rc = iemMemCommitAndUnmap(pIemCpu, pu32Dst, IEM_ACCESS_DATA_W);
7259 * @param pIemCpu The IEM per CPU data.
7265 static VBOXSTRICTRC iemMemStoreDataU64(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, uint64_t u64Value)
7269 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Dst, sizeof(*pu64Dst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W);
7273 rc = iemMemCommitAndUnmap(pIemCpu, pu64Dst, IEM_ACCESS_DATA_W);
7283 * @param pIemCpu The IEM per CPU data.
7289 static VBOXSTRICTRC iemMemStoreDataU128(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, uint128_t u128Value)
7293 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu128Dst, sizeof(*pu128Dst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W);
7297 rc = iemMemCommitAndUnmap(pIemCpu, pu128Dst, IEM_ACCESS_DATA_W);
7307 * @param pIemCpu The IEM per CPU data.
7313 static VBOXSTRICTRC iemMemStoreDataU128AlignedSse(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, uint128_t u128Value)
7317 && !(pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.MXCSR & X86_MXSCR_MM)) /** @todo should probably check this *after* applying seg.u64Base... Check real HW. */
7318 return iemRaiseGeneralProtectionFault0(pIemCpu);
7321 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu128Dst, sizeof(*pu128Dst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W);
7325 rc = iemMemCommitAndUnmap(pIemCpu, pu128Dst, IEM_ACCESS_DATA_W);
7335 * @param pIemCpu The IEM per CPU data.
7343 static VBOXSTRICTRC iemMemStoreDataXdtr(PIEMCPU pIemCpu, uint16_t cbLimit, RTGCPTR GCPtrBase,
7347 VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu,
7377 rcStrict = iemMemCommitAndUnmap(pIemCpu, (void *)pu8Src, IEM_ACCESS_DATA_W);
7387 * @param pIemCpu The IEM per CPU data.
7390 static VBOXSTRICTRC iemMemStackPushU16(PIEMCPU pIemCpu, uint16_t u16Value)
7394 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7395 RTGCPTR GCPtrTop = iemRegGetRspForPush(pIemCpu, pCtx, 2, &uNewRsp);
7399 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Dst, sizeof(*pu16Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
7403 rc = iemMemCommitAndUnmap(pIemCpu, pu16Dst, IEM_ACCESS_STACK_W);
7418 * @param pIemCpu The IEM per CPU data.
7421 static VBOXSTRICTRC iemMemStackPushU32(PIEMCPU pIemCpu, uint32_t u32Value)
7425 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7426 RTGCPTR GCPtrTop = iemRegGetRspForPush(pIemCpu, pCtx, 4, &uNewRsp);
7430 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Dst, sizeof(*pu32Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
7434 rc = iemMemCommitAndUnmap(pIemCpu, pu32Dst, IEM_ACCESS_STACK_W);
7449 * @param pIemCpu The IEM per CPU data.
7452 static VBOXSTRICTRC iemMemStackPushU32SReg(PIEMCPU pIemCpu, uint32_t u32Value)
7456 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7457 RTGCPTR GCPtrTop = iemRegGetRspForPush(pIemCpu, pCtx, 4, &uNewRsp);
7460 if (IEM_FULL_VERIFICATION_REM_ENABLED(pIemCpu))
7464 rc = iemMemMap(pIemCpu, (void **)&pu32Dst, sizeof(*pu32Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
7468 rc = iemMemCommitAndUnmap(pIemCpu, pu32Dst, IEM_ACCESS_STACK_W);
7481 rc = iemMemMap(pIemCpu, (void **)&pu16Dst, sizeof(uint32_t), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_RW);
7485 rc = iemMemCommitAndUnmap(pIemCpu, pu16Dst, IEM_ACCESS_STACK_RW);
7501 * @param pIemCpu The IEM per CPU data.
7504 static VBOXSTRICTRC iemMemStackPushU64(PIEMCPU pIemCpu, uint64_t u64Value)
7508 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7509 RTGCPTR GCPtrTop = iemRegGetRspForPush(pIemCpu, pCtx, 8, &uNewRsp);
7513 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Dst, sizeof(*pu64Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
7517 rc = iemMemCommitAndUnmap(pIemCpu, pu64Dst, IEM_ACCESS_STACK_W);
7532 * @param pIemCpu The IEM per CPU data.
7535 static VBOXSTRICTRC iemMemStackPopU16(PIEMCPU pIemCpu, uint16_t *pu16Value)
7539 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7540 RTGCPTR GCPtrTop = iemRegGetRspForPop(pIemCpu, pCtx, 2, &uNewRsp);
7544 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Src, sizeof(*pu16Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
7548 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu16Src, IEM_ACCESS_STACK_R);
7563 * @param pIemCpu The IEM per CPU data.
7566 static VBOXSTRICTRC iemMemStackPopU32(PIEMCPU pIemCpu, uint32_t *pu32Value)
7570 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7571 RTGCPTR GCPtrTop = iemRegGetRspForPop(pIemCpu, pCtx, 4, &uNewRsp);
7575 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Src, sizeof(*pu32Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
7579 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu32Src, IEM_ACCESS_STACK_R);
7594 * @param pIemCpu The IEM per CPU data.
7597 static VBOXSTRICTRC iemMemStackPopU64(PIEMCPU pIemCpu, uint64_t *pu64Value)
7601 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7602 RTGCPTR GCPtrTop = iemRegGetRspForPop(pIemCpu, pCtx, 8, &uNewRsp);
7606 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Src, sizeof(*pu64Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
7610 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu64Src, IEM_ACCESS_STACK_R);
7625 * @param pIemCpu The IEM per CPU data.
7629 static VBOXSTRICTRC iemMemStackPushU16Ex(PIEMCPU pIemCpu, uint16_t u16Value, PRTUINT64U pTmpRsp)
7632 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7634 RTGCPTR GCPtrTop = iemRegGetRspForPushEx(pIemCpu, pCtx, &NewRsp, 2);
7638 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Dst, sizeof(*pu16Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
7642 rc = iemMemCommitAndUnmap(pIemCpu, pu16Dst, IEM_ACCESS_STACK_W);
7657 * @param pIemCpu The IEM per CPU data.
7661 static VBOXSTRICTRC iemMemStackPushU32Ex(PIEMCPU pIemCpu, uint32_t u32Value, PRTUINT64U pTmpRsp)
7664 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7666 RTGCPTR GCPtrTop = iemRegGetRspForPushEx(pIemCpu, pCtx, &NewRsp, 4);
7670 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Dst, sizeof(*pu32Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
7674 rc = iemMemCommitAndUnmap(pIemCpu, pu32Dst, IEM_ACCESS_STACK_W);
7689 * @param pIemCpu The IEM per CPU data.
7693 static VBOXSTRICTRC iemMemStackPushU64Ex(PIEMCPU pIemCpu, uint64_t u64Value, PRTUINT64U pTmpRsp)
7696 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7698 RTGCPTR GCPtrTop = iemRegGetRspForPushEx(pIemCpu, pCtx, &NewRsp, 8);
7702 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Dst, sizeof(*pu64Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
7706 rc = iemMemCommitAndUnmap(pIemCpu, pu64Dst, IEM_ACCESS_STACK_W);
7721 * @param pIemCpu The IEM per CPU data.
7725 static VBOXSTRICTRC iemMemStackPopU16Ex(PIEMCPU pIemCpu, uint16_t *pu16Value, PRTUINT64U pTmpRsp)
7728 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7730 RTGCPTR GCPtrTop = iemRegGetRspForPopEx(pIemCpu, pCtx, &NewRsp, 2);
7734 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Src, sizeof(*pu16Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
7738 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu16Src, IEM_ACCESS_STACK_R);
7753 * @param pIemCpu The IEM per CPU data.
7757 static VBOXSTRICTRC iemMemStackPopU32Ex(PIEMCPU pIemCpu, uint32_t *pu32Value, PRTUINT64U pTmpRsp)
7760 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7762 RTGCPTR GCPtrTop = iemRegGetRspForPopEx(pIemCpu, pCtx, &NewRsp, 4);
7766 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Src, sizeof(*pu32Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
7770 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu32Src, IEM_ACCESS_STACK_R);
7785 * @param pIemCpu The IEM per CPU data.
7789 static VBOXSTRICTRC iemMemStackPopU64Ex(PIEMCPU pIemCpu, uint64_t *pu64Value, PRTUINT64U pTmpRsp)
7792 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7794 RTGCPTR GCPtrTop = iemRegGetRspForPopEx(pIemCpu, pCtx, &NewRsp, 8);
7798 VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu, (void **)&pu64Src, sizeof(*pu64Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
7802 rcStrict = iemMemCommitAndUnmap(pIemCpu, (void *)pu64Src, IEM_ACCESS_STACK_R);
7819 * @param pIemCpu The IEM per CPU data.
7830 static VBOXSTRICTRC iemMemStackPushBeginSpecial(PIEMCPU pIemCpu, size_t cbMem, void **ppvMem, uint64_t *puNewRsp)
7833 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7834 RTGCPTR GCPtrTop = iemRegGetRspForPush(pIemCpu, pCtx, (uint8_t)cbMem, puNewRsp);
7835 return iemMemMap(pIemCpu, ppvMem, cbMem, X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
7845 * @param pIemCpu The IEM per CPU data.
7851 static VBOXSTRICTRC iemMemStackPushCommitSpecial(PIEMCPU pIemCpu, void *pvMem, uint64_t uNewRsp)
7853 VBOXSTRICTRC rcStrict = iemMemCommitAndUnmap(pIemCpu, pvMem, IEM_ACCESS_STACK_W);
7855 pIemCpu->CTX_SUFF(pCtx)->rsp = uNewRsp;
7866 * @param pIemCpu The IEM per CPU data.
7874 static VBOXSTRICTRC iemMemStackPopBeginSpecial(PIEMCPU pIemCpu, size_t cbMem, void const **ppvMem, uint64_t *puNewRsp)
7877 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7878 RTGCPTR GCPtrTop = iemRegGetRspForPop(pIemCpu, pCtx, (uint8_t)cbMem, puNewRsp);
7879 return iemMemMap(pIemCpu, (void **)ppvMem, cbMem, X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
7889 * @param pIemCpu The IEM per CPU data.
7897 static VBOXSTRICTRC iemMemStackPopContinueSpecial(PIEMCPU pIemCpu, size_t cbMem, void const **ppvMem, uint64_t *puNewRsp)
7900 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
7903 RTGCPTR GCPtrTop = iemRegGetRspForPopEx(pIemCpu, pCtx, &NewRsp, 8);
7905 return iemMemMap(pIemCpu, (void **)ppvMem, cbMem, X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
7915 * @param pIemCpu The IEM per CPU data.
7921 static VBOXSTRICTRC iemMemStackPopCommitSpecial(PIEMCPU pIemCpu, void const *pvMem, uint64_t uNewRsp)
7923 VBOXSTRICTRC rcStrict = iemMemCommitAndUnmap(pIemCpu, (void *)pvMem, IEM_ACCESS_STACK_R);
7925 pIemCpu->CTX_SUFF(pCtx)->rsp = uNewRsp;
7937 * @param pIemCpu The IEM per CPU data.
7942 static VBOXSTRICTRC iemMemStackPopDoneSpecial(PIEMCPU pIemCpu, void const *pvMem)
7944 return iemMemCommitAndUnmap(pIemCpu, (void *)pvMem, IEM_ACCESS_STACK_R);
7952 * @param pIemCpu The IEM per CPU data.
7958 static VBOXSTRICTRC iemMemFetchSysU8(PIEMCPU pIemCpu, uint8_t *pbDst, uint8_t iSegReg, RTGCPTR GCPtrMem)
7962 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pbSrc, sizeof(*pbSrc), iSegReg, GCPtrMem, IEM_ACCESS_SYS_R);
7966 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pbSrc, IEM_ACCESS_SYS_R);
7976 * @param pIemCpu The IEM per CPU data.
7982 static VBOXSTRICTRC iemMemFetchSysU16(PIEMCPU pIemCpu, uint16_t *pu16Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
7986 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Src, sizeof(*pu16Src), iSegReg, GCPtrMem, IEM_ACCESS_SYS_R);
7990 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu16Src, IEM_ACCESS_SYS_R);
8000 * @param pIemCpu The IEM per CPU data.
8006 static VBOXSTRICTRC iemMemFetchSysU32(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
8010 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Src, sizeof(*pu32Src), iSegReg, GCPtrMem, IEM_ACCESS_SYS_R);
8014 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu32Src, IEM_ACCESS_SYS_R);
8024 * @param pIemCpu The IEM per CPU data.
8030 static VBOXSTRICTRC iemMemFetchSysU64(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
8034 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Src, sizeof(*pu64Src), iSegReg, GCPtrMem, IEM_ACCESS_SYS_R);
8038 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu64Src, IEM_ACCESS_SYS_R);
8048 * @param pIemCpu The IEM per CPU.
8054 static VBOXSTRICTRC iemMemFetchSelDescWithErr(PIEMCPU pIemCpu, PIEMSELDESC pDesc, uint16_t uSel, uint8_t uXcpt,
8058 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
8072 return iemRaiseXcptOrInt(pIemCpu, 0, uXcpt, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
8084 return iemRaiseXcptOrInt(pIemCpu, 0, uXcpt, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR,
8094 VBOXSTRICTRC rcStrict = iemMemFetchSysU64(pIemCpu, &pDesc->Legacy.u, UINT8_MAX, GCPtrBase + (uSel & X86_SEL_MASK));
8097 if ( !IEM_IS_LONG_MODE(pIemCpu)
8101 rcStrict = iemMemFetchSysU64(pIemCpu, &pDesc->Long.au64[1], UINT8_MAX, GCPtrBase + (uSel | X86_SEL_RPL_LDT) + 1);
8106 return iemRaiseXcptOrInt(pIemCpu, 0, uXcpt, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, uErrorCode, 0);
8117 * @param pIemCpu The IEM per CPU.
8122 static VBOXSTRICTRC iemMemFetchSelDesc(PIEMCPU pIemCpu, PIEMSELDESC pDesc, uint16_t uSel, uint8_t uXcpt)
8124 return iemMemFetchSelDescWithErr(pIemCpu, pDesc, uSel, uXcpt, uSel & X86_SEL_MASK_OFF_RPL);
8153 * @param pIemCpu The IEM per CPU.
8156 static VBOXSTRICTRC iemMemMarkSelDescAccessed(PIEMCPU pIemCpu, uint16_t uSel)
8158 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
8179 rcStrict = iemMemMap(pIemCpu, (void **)&pu32, 4, UINT8_MAX, GCPtr, IEM_ACCESS_SYS_RW);
8187 rcStrict = iemMemMap(pIemCpu, (void **)&pu32, 8, UINT8_MAX, GCPtr, IEM_ACCESS_SYS_RW);
8199 return iemMemCommitAndUnmap(pIemCpu, (void *)pu32, IEM_ACCESS_SYS_RW);
8233 #define IEM_MC_ADVANCE_RIP() iemRegUpdateRipAndClearRF(pIemCpu)
8234 #define IEM_MC_REL_JMP_S8(a_i8) IEM_MC_RETURN_ON_FAILURE(iemRegRipRelativeJumpS8(pIemCpu, a_i8))
8235 #define IEM_MC_REL_JMP_S16(a_i16) IEM_MC_RETURN_ON_FAILURE(iemRegRipRelativeJumpS16(pIemCpu, a_i16))
8236 #define IEM_MC_REL_JMP_S32(a_i32) IEM_MC_RETURN_ON_FAILURE(iemRegRipRelativeJumpS32(pIemCpu, a_i32))
8237 #define IEM_MC_SET_RIP_U16(a_u16NewIP) IEM_MC_RETURN_ON_FAILURE(iemRegRipJump((pIemCpu), (a_u16NewIP)))
8238 #define IEM_MC_SET_RIP_U32(a_u32NewIP) IEM_MC_RETURN_ON_FAILURE(iemRegRipJump((pIemCpu), (a_u32NewIP)))
8239 #define IEM_MC_SET_RIP_U64(a_u64NewIP) IEM_MC_RETURN_ON_FAILURE(iemRegRipJump((pIemCpu), (a_u64NewIP)))
8241 #define IEM_MC_RAISE_DIVIDE_ERROR() return iemRaiseDivideError(pIemCpu)
8244 if ((pIemCpu)->CTX_SUFF(pCtx)->cr0 & (X86_CR0_EM | X86_CR0_TS)) \
8245 return iemRaiseDeviceNotAvailable(pIemCpu); \
8249 if ((pIemCpu)->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.FSW & X86_FSW_ES) \
8250 return iemRaiseMathFault(pIemCpu); \
8254 if ( (pIemCpu->CTX_SUFF(pCtx)->cr0 & X86_CR0_EM) \
8255 || !(pIemCpu->CTX_SUFF(pCtx)->cr4 & X86_CR4_OSFXSR) \
8256 || !IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fSse2) \
8257 return iemRaiseUndefinedOpcode(pIemCpu); \
8258 if (pIemCpu->CTX_SUFF(pCtx)->cr0 & X86_CR0_TS) \
8259 return iemRaiseDeviceNotAvailable(pIemCpu); \
8263 if ( ((pIemCpu)->CTX_SUFF(pCtx)->cr0 & X86_CR0_EM) \
8264 || !IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fMmx) \
8265 return iemRaiseUndefinedOpcode(pIemCpu); \
8266 if (pIemCpu->CTX_SUFF(pCtx)->cr0 & X86_CR0_TS) \
8267 return iemRaiseDeviceNotAvailable(pIemCpu); \
8271 if ( ((pIemCpu)->CTX_SUFF(pCtx)->cr0 & X86_CR0_EM) \
8272 || ( !IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fSse \
8273 && !IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fAmdMmxExts) ) \
8274 return iemRaiseUndefinedOpcode(pIemCpu); \
8275 if (pIemCpu->CTX_SUFF(pCtx)->cr0 & X86_CR0_TS) \
8276 return iemRaiseDeviceNotAvailable(pIemCpu); \
8280 if (pIemCpu->uCpl != 0) \
8281 return iemRaiseGeneralProtectionFault0(pIemCpu); \
8295 do { (pIemCpu)->CTX_SUFF(pCtx)->eflags.u = (a_EFlags); Assert((pIemCpu)->CTX_SUFF(pCtx)->eflags.u & X86_EFL_1); } while (0)
8300 #define IEM_MC_FETCH_GREG_U8(a_u8Dst, a_iGReg) (a_u8Dst) = iemGRegFetchU8(pIemCpu, (a_iGReg))
8301 #define IEM_MC_FETCH_GREG_U8_ZX_U16(a_u16Dst, a_iGReg) (a_u16Dst) = iemGRegFetchU8(pIemCpu, (a_iGReg))
8302 #define IEM_MC_FETCH_GREG_U8_ZX_U32(a_u32Dst, a_iGReg) (a_u32Dst) = iemGRegFetchU8(pIemCpu, (a_iGReg))
8303 #define IEM_MC_FETCH_GREG_U8_ZX_U64(a_u64Dst, a_iGReg) (a_u64Dst) = iemGRegFetchU8(pIemCpu, (a_iGReg))
8304 #define IEM_MC_FETCH_GREG_U8_SX_U16(a_u16Dst, a_iGReg) (a_u16Dst) = (int8_t)iemGRegFetchU8(pIemCpu, (a_iGReg))
8305 #define IEM_MC_FETCH_GREG_U8_SX_U32(a_u32Dst, a_iGReg) (a_u32Dst) = (int8_t)iemGRegFetchU8(pIemCpu, (a_iGReg))
8306 #define IEM_MC_FETCH_GREG_U8_SX_U64(a_u64Dst, a_iGReg) (a_u64Dst) = (int8_t)iemGRegFetchU8(pIemCpu, (a_iGReg))
8307 #define IEM_MC_FETCH_GREG_U16(a_u16Dst, a_iGReg) (a_u16Dst) = iemGRegFetchU16(pIemCpu, (a_iGReg))
8308 #define IEM_MC_FETCH_GREG_U16_ZX_U32(a_u32Dst, a_iGReg) (a_u32Dst) = iemGRegFetchU16(pIemCpu, (a_iGReg))
8309 #define IEM_MC_FETCH_GREG_U16_ZX_U64(a_u64Dst, a_iGReg) (a_u64Dst) = iemGRegFetchU16(pIemCpu, (a_iGReg))
8310 #define IEM_MC_FETCH_GREG_U16_SX_U32(a_u32Dst, a_iGReg) (a_u32Dst) = (int16_t)iemGRegFetchU16(pIemCpu, (a_iGReg))
8311 #define IEM_MC_FETCH_GREG_U16_SX_U64(a_u64Dst, a_iGReg) (a_u64Dst) = (int16_t)iemGRegFetchU16(pIemCpu, (a_iGReg))
8312 #define IEM_MC_FETCH_GREG_U32(a_u32Dst, a_iGReg) (a_u32Dst) = iemGRegFetchU32(pIemCpu, (a_iGReg))
8313 #define IEM_MC_FETCH_GREG_U32_ZX_U64(a_u64Dst, a_iGReg) (a_u64Dst) = iemGRegFetchU32(pIemCpu, (a_iGReg))
8314 #define IEM_MC_FETCH_GREG_U32_SX_U64(a_u64Dst, a_iGReg) (a_u64Dst) = (int32_t)iemGRegFetchU32(pIemCpu, (a_iGReg))
8315 #define IEM_MC_FETCH_GREG_U64(a_u64Dst, a_iGReg) (a_u64Dst) = iemGRegFetchU64(pIemCpu, (a_iGReg))
8317 #define IEM_MC_FETCH_SREG_U16(a_u16Dst, a_iSReg) (a_u16Dst) = iemSRegFetchU16(pIemCpu, (a_iSReg))
8318 #define IEM_MC_FETCH_SREG_ZX_U32(a_u32Dst, a_iSReg) (a_u32Dst) = iemSRegFetchU16(pIemCpu, (a_iSReg))
8319 #define IEM_MC_FETCH_SREG_ZX_U64(a_u64Dst, a_iSReg) (a_u64Dst) = iemSRegFetchU16(pIemCpu, (a_iSReg))
8320 #define IEM_MC_FETCH_CR0_U16(a_u16Dst) (a_u16Dst) = (uint16_t)(pIemCpu)->CTX_SUFF(pCtx)->cr0
8321 #define IEM_MC_FETCH_CR0_U32(a_u32Dst) (a_u32Dst) = (uint32_t)(pIemCpu)->CTX_SUFF(pCtx)->cr0
8322 #define IEM_MC_FETCH_CR0_U64(a_u64Dst) (a_u64Dst) = (pIemCpu)->CTX_SUFF(pCtx)->cr0
8323 #define IEM_MC_FETCH_LDTR_U16(a_u16Dst) (a_u16Dst) = (pIemCpu)->CTX_SUFF(pCtx)->ldtr.Sel
8324 #define IEM_MC_FETCH_LDTR_U32(a_u32Dst) (a_u32Dst) = (pIemCpu)->CTX_SUFF(pCtx)->ldtr.Sel
8325 #define IEM_MC_FETCH_LDTR_U64(a_u64Dst) (a_u64Dst) = (pIemCpu)->CTX_SUFF(pCtx)->ldtr.Sel
8326 #define IEM_MC_FETCH_TR_U16(a_u16Dst) (a_u16Dst) = (pIemCpu)->CTX_SUFF(pCtx)->tr.Sel
8327 #define IEM_MC_FETCH_TR_U32(a_u32Dst) (a_u32Dst) = (pIemCpu)->CTX_SUFF(pCtx)->tr.Sel
8328 #define IEM_MC_FETCH_TR_U64(a_u64Dst) (a_u64Dst) = (pIemCpu)->CTX_SUFF(pCtx)->tr.Sel
8330 #define IEM_MC_FETCH_EFLAGS(a_EFlags) (a_EFlags) = (pIemCpu)->CTX_SUFF(pCtx)->eflags.u
8331 #define IEM_MC_FETCH_EFLAGS_U8(a_EFlags) (a_EFlags) = (uint8_t)(pIemCpu)->CTX_SUFF(pCtx)->eflags.u
8332 #define IEM_MC_FETCH_FSW(a_u16Fsw) (a_u16Fsw) = pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.FSW
8333 #define IEM_MC_FETCH_FCW(a_u16Fcw) (a_u16Fcw) = pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.FCW
8335 #define IEM_MC_STORE_GREG_U8(a_iGReg, a_u8Value) *iemGRegRefU8(pIemCpu, (a_iGReg)) = (a_u8Value)
8336 #define IEM_MC_STORE_GREG_U16(a_iGReg, a_u16Value) *(uint16_t *)iemGRegRef(pIemCpu, (a_iGReg)) = (a_u16Value)
8337 #define IEM_MC_STORE_GREG_U32(a_iGReg, a_u32Value) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) = (uint32_t)(a_u32Value) /* clear high bits. */
8338 #define IEM_MC_STORE_GREG_U64(a_iGReg, a_u64Value) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) = (a_u64Value)
8343 #define IEM_MC_CLEAR_HIGH_GREG_U64(a_iGReg) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) &= UINT32_MAX
8346 do { pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aRegs[a_iSt].r80 = *(a_pr80Src); } while (0)
8348 #define IEM_MC_REF_GREG_U8(a_pu8Dst, a_iGReg) (a_pu8Dst) = iemGRegRefU8(pIemCpu, (a_iGReg))
8349 #define IEM_MC_REF_GREG_U16(a_pu16Dst, a_iGReg) (a_pu16Dst) = (uint16_t *)iemGRegRef(pIemCpu, (a_iGReg))
8352 #define IEM_MC_REF_GREG_U32(a_pu32Dst, a_iGReg) (a_pu32Dst) = (uint32_t *)iemGRegRef(pIemCpu, (a_iGReg))
8353 #define IEM_MC_REF_GREG_U64(a_pu64Dst, a_iGReg) (a_pu64Dst) = (uint64_t *)iemGRegRef(pIemCpu, (a_iGReg))
8355 #define IEM_MC_REF_EFLAGS(a_pEFlags) (a_pEFlags) = &(pIemCpu)->CTX_SUFF(pCtx)->eflags.u
8357 #define IEM_MC_ADD_GREG_U8(a_iGReg, a_u8Value) *(uint8_t *)iemGRegRef(pIemCpu, (a_iGReg)) += (a_u8Value)
8358 #define IEM_MC_ADD_GREG_U16(a_iGReg, a_u16Value) *(uint16_t *)iemGRegRef(pIemCpu, (a_iGReg)) += (a_u16Value)
8361 uint32_t *pu32Reg = (uint32_t *)iemGRegRef(pIemCpu, (a_iGReg)); \
8365 #define IEM_MC_ADD_GREG_U64(a_iGReg, a_u64Value) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) += (a_u64Value)
8367 #define IEM_MC_SUB_GREG_U8(a_iGReg, a_u8Value) *(uint8_t *)iemGRegRef(pIemCpu, (a_iGReg)) -= (a_u8Value)
8368 #define IEM_MC_SUB_GREG_U16(a_iGReg, a_u16Value) *(uint16_t *)iemGRegRef(pIemCpu, (a_iGReg)) -= (a_u16Value)
8371 uint32_t *pu32Reg = (uint32_t *)iemGRegRef(pIemCpu, (a_iGReg)); \
8375 #define IEM_MC_SUB_GREG_U64(a_iGReg, a_u64Value) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) -= (a_u64Value)
8377 #define IEM_MC_ADD_GREG_U8_TO_LOCAL(a_u8Value, a_iGReg) do { (a_u8Value) += iemGRegFetchU8( pIemCpu, (a_iGReg)); } while (0)
8378 #define IEM_MC_ADD_GREG_U16_TO_LOCAL(a_u16Value, a_iGReg) do { (a_u16Value) += iemGRegFetchU16(pIemCpu, (a_iGReg)); } while (0)
8379 #define IEM_MC_ADD_GREG_U32_TO_LOCAL(a_u32Value, a_iGReg) do { (a_u32Value) += iemGRegFetchU32(pIemCpu, (a_iGReg)); } while (0)
8380 #define IEM_MC_ADD_GREG_U64_TO_LOCAL(a_u64Value, a_iGReg) do { (a_u64Value) += iemGRegFetchU64(pIemCpu, (a_iGReg)); } while (0)
8409 #define IEM_MC_AND_GREG_U8(a_iGReg, a_u8Value) *(uint8_t *)iemGRegRef(pIemCpu, (a_iGReg)) &= (a_u8Value)
8410 #define IEM_MC_AND_GREG_U16(a_iGReg, a_u16Value) *(uint16_t *)iemGRegRef(pIemCpu, (a_iGReg)) &= (a_u16Value)
8413 uint32_t *pu32Reg = (uint32_t *)iemGRegRef(pIemCpu, (a_iGReg)); \
8417 #define IEM_MC_AND_GREG_U64(a_iGReg, a_u64Value) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) &= (a_u64Value)
8419 #define IEM_MC_OR_GREG_U8(a_iGReg, a_u8Value) *(uint8_t *)iemGRegRef(pIemCpu, (a_iGReg)) |= (a_u8Value)
8420 #define IEM_MC_OR_GREG_U16(a_iGReg, a_u16Value) *(uint16_t *)iemGRegRef(pIemCpu, (a_iGReg)) |= (a_u16Value)
8423 uint32_t *pu32Reg = (uint32_t *)iemGRegRef(pIemCpu, (a_iGReg)); \
8427 #define IEM_MC_OR_GREG_U64(a_iGReg, a_u64Value) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) |= (a_u64Value)
8431 #define IEM_MC_SET_EFL_BIT(a_fBit) do { (pIemCpu)->CTX_SUFF(pCtx)->eflags.u |= (a_fBit); } while (0)
8433 #define IEM_MC_CLEAR_EFL_BIT(a_fBit) do { (pIemCpu)->CTX_SUFF(pCtx)->eflags.u &= ~(a_fBit); } while (0)
8435 #define IEM_MC_FLIP_EFL_BIT(a_fBit) do { (pIemCpu)->CTX_SUFF(pCtx)->eflags.u ^= (a_fBit); } while (0)
8437 #define IEM_MC_CLEAR_FSW_EX() do { (pIemCpu)->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.FSW &= X86_FSW_C_MASK | X86_FSW_TOP_MASK; } while (0)
8441 do { (a_u64Value) = pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aRegs[(a_iMReg)].mmx; } while (0)
8443 do { (a_u32Value) = pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aRegs[(a_iMReg)].au32[0]; } while (0)
8445 do { pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aRegs[(a_iMReg)].mmx = (a_u64Value); } while (0)
8447 do { pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aRegs[(a_iMReg)].mmx = (uint32_t)(a_u32Value); } while (0)
8449 (a_pu64Dst) = (&pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aRegs[(a_iMReg)].mmx)
8451 (a_pu64Dst) = ((uint64_t const *)&pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aRegs[(a_iMReg)].mmx)
8453 (a_pu32Dst) = ((uint32_t const *)&pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aRegs[(a_iMReg)].mmx)
8456 do { (a_u128Value) = pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aXMM[(a_iXReg)].xmm; } while (0)
8458 do { (a_u64Value) = pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aXMM[(a_iXReg)].au64[0]; } while (0)
8460 do { (a_u32Value) = pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aXMM[(a_iXReg)].au32[0]; } while (0)
8462 do { pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aXMM[(a_iXReg)].xmm = (a_u128Value); } while (0)
8464 do { pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aXMM[(a_iXReg)].au64[0] = (a_u64Value); \
8465 pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aXMM[(a_iXReg)].au64[1] = 0; \
8468 do { pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aXMM[(a_iXReg)].au64[0] = (uint32_t)(a_u32Value); \
8469 pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aXMM[(a_iXReg)].au64[1] = 0; \
8472 (a_pu128Dst) = (&pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aXMM[(a_iXReg)].xmm)
8474 (a_pu128Dst) = ((uint128_t const *)&pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aXMM[(a_iXReg)].xmm)
8476 (a_pu64Dst) = ((uint64_t const *)&pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.aXMM[(a_iXReg)].au64[0])
8479 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &(a_u8Dst), (a_iSeg), (a_GCPtrMem)))
8481 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &(a_u8Dst), (a_iSeg), (a_GCPtrMem16)))
8483 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &(a_u8Dst), (a_iSeg), (a_GCPtrMem32)))
8486 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU16(pIemCpu, &(a_u16Dst), (a_iSeg), (a_GCPtrMem)))
8488 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU16(pIemCpu, &(a_u16Dst), (a_iSeg), (a_GCPtrMem) + (a_offDisp)))
8490 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU16(pIemCpu, (uint16_t *)&(a_i16Dst), (a_iSeg), (a_GCPtrMem)))
8493 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU32(pIemCpu, &(a_u32Dst), (a_iSeg), (a_GCPtrMem)))
8495 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU32(pIemCpu, &(a_u32Dst), (a_iSeg), (a_GCPtrMem) + (a_offDisp)))
8497 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU32(pIemCpu, (uint32_t *)&(a_i32Dst), (a_iSeg), (a_GCPtrMem)))
8500 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataS32SxU64(pIemCpu, &(a_u64Dst), (a_iSeg), (a_GCPtrMem)))
8503 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU64(pIemCpu, &(a_u64Dst), (a_iSeg), (a_GCPtrMem)))
8505 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU64(pIemCpu, &(a_u64Dst), (a_iSeg), (a_GCPtrMem) + (a_offDisp)))
8507 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU64AlignedU128(pIemCpu, &(a_u128Dst), (a_iSeg), (a_GCPtrMem)))
8509 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU64(pIemCpu, (uint64_t *)&(a_i64Dst), (a_iSeg), (a_GCPtrMem)))
8512 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU32(pIemCpu, &(a_r32Dst).u32, (a_iSeg), (a_GCPtrMem)))
8514 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU64(pIemCpu, &(a_r64Dst).au64[0], (a_iSeg), (a_GCPtrMem)))
8516 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataR80(pIemCpu, &(a_r80Dst), (a_iSeg), (a_GCPtrMem)))
8519 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU128(pIemCpu, &(a_u128Dst), (a_iSeg), (a_GCPtrMem)))
8521 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU128AlignedSse(pIemCpu, &(a_u128Dst), (a_iSeg), (a_GCPtrMem)))
8528 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &u8Tmp, (a_iSeg), (a_GCPtrMem))); \
8534 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &u8Tmp, (a_iSeg), (a_GCPtrMem))); \
8540 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &u8Tmp, (a_iSeg), (a_GCPtrMem))); \
8546 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU16(pIemCpu, &u16Tmp, (a_iSeg), (a_GCPtrMem))); \
8552 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU16(pIemCpu, &u16Tmp, (a_iSeg), (a_GCPtrMem))); \
8558 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU32(pIemCpu, &u32Tmp, (a_iSeg), (a_GCPtrMem))); \
8565 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &u8Tmp, (a_iSeg), (a_GCPtrMem))); \
8571 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &u8Tmp, (a_iSeg), (a_GCPtrMem))); \
8577 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU8(pIemCpu, &u8Tmp, (a_iSeg), (a_GCPtrMem))); \
8583 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU16(pIemCpu, &u16Tmp, (a_iSeg), (a_GCPtrMem))); \
8589 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU16(pIemCpu, &u16Tmp, (a_iSeg), (a_GCPtrMem))); \
8595 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU32(pIemCpu, &u32Tmp, (a_iSeg), (a_GCPtrMem))); \
8600 IEM_MC_RETURN_ON_FAILURE(iemMemStoreDataU8(pIemCpu, (a_iSeg), (a_GCPtrMem), (a_u8Value)))
8602 IEM_MC_RETURN_ON_FAILURE(iemMemStoreDataU16(pIemCpu, (a_iSeg), (a_GCPtrMem), (a_u16Value)))
8604 IEM_MC_RETURN_ON_FAILURE(iemMemStoreDataU32(pIemCpu, (a_iSeg), (a_GCPtrMem), (a_u32Value)))
8606 IEM_MC_RETURN_ON_FAILURE(iemMemStoreDataU64(pIemCpu, (a_iSeg), (a_GCPtrMem), (a_u64Value)))
8609 IEM_MC_RETURN_ON_FAILURE(iemMemStoreDataU8(pIemCpu, (a_iSeg), (a_GCPtrMem), (a_u8C)))
8611 IEM_MC_RETURN_ON_FAILURE(iemMemStoreDataU16(pIemCpu, (a_iSeg), (a_GCPtrMem), (a_u16C)))
8613 IEM_MC_RETURN_ON_FAILURE(iemMemStoreDataU32(pIemCpu, (a_iSeg), (a_GCPtrMem), (a_u32C)))
8615 IEM_MC_RETURN_ON_FAILURE(iemMemStoreDataU64(pIemCpu, (a_iSeg), (a_GCPtrMem), (a_u64C)))
8630 IEM_MC_RETURN_ON_FAILURE(iemMemStoreDataU128(pIemCpu, (a_iSeg), (a_GCPtrMem), (a_u128Value)))
8632 IEM_MC_RETURN_ON_FAILURE(iemMemStoreDataU128AlignedSse(pIemCpu, (a_iSeg), (a_GCPtrMem), (a_u128Value)))
8636 IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU16(pIemCpu, (a_u16Value)))
8638 IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU32(pIemCpu, (a_u32Value)))
8640 IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU32SReg(pIemCpu, (a_u32Value)))
8642 IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU64(pIemCpu, (a_u64Value)))
8645 IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU16(pIemCpu, (a_pu16Value)))
8647 IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU32(pIemCpu, (a_pu32Value)))
8649 IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU64(pIemCpu, (a_pu64Value)))
8656 IEM_MC_RETURN_ON_FAILURE(iemMemMap(pIemCpu, (void **)&(a_pMem), sizeof(*(a_pMem)), (a_iSeg), (a_GCPtrMem), (a_fAccess)))
8663 IEM_MC_RETURN_ON_FAILURE(iemMemMap(pIemCpu, (void **)&(a_pvMem), (a_cbMem), (a_iSeg), (a_GCPtrMem), (a_fAccess)))
8669 IEM_MC_RETURN_ON_FAILURE(iemMemCommitAndUnmap(pIemCpu, (a_pvMem), (a_fAccess)))
8684 & ~(pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.FCW & X86_FCW_MASK_ALL) ) ) \
8685 IEM_MC_RETURN_ON_FAILURE(iemMemCommitAndUnmap(pIemCpu, (a_pvMem), (a_fAccess))); \
8690 IEM_MC_RETURN_ON_FAILURE(iemOpHlpCalcRmEffAddr(pIemCpu, (bRm), (cbImm), &(a_GCPtrEff)))
8707 #define IEM_MC_CALL_CIMPL_0(a_pfnCImpl) return (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode)
8716 #define IEM_MC_CALL_CIMPL_1(a_pfnCImpl, a0) return (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0)
8726 #define IEM_MC_CALL_CIMPL_2(a_pfnCImpl, a0, a1) return (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1)
8737 #define IEM_MC_CALL_CIMPL_3(a_pfnCImpl, a0, a1, a2) return (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1, a2)
8749 #define IEM_MC_CALL_CIMPL_4(a_pfnCImpl, a0, a1, a2, a3) return (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1, a2, a3)
8762 #define IEM_MC_CALL_CIMPL_5(a_pfnCImpl, a0, a1, a2, a3, a4) return (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1, a2, a3, a4)
8773 #define IEM_MC_DEFER_TO_CIMPL_0(a_pfnCImpl) (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode)
8784 #define IEM_MC_DEFER_TO_CIMPL_1(a_pfnCImpl, a0) (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0)
8796 #define IEM_MC_DEFER_TO_CIMPL_2(a_pfnCImpl, a0, a1) (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1)
8809 #define IEM_MC_DEFER_TO_CIMPL_3(a_pfnCImpl, a0, a1, a2) (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1, a2)
8819 iemFpuPrepareUsage(pIemCpu); \
8820 a_pfnAImpl(&pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87, (a0)); \
8832 iemFpuPrepareUsage(pIemCpu); \
8833 a_pfnAImpl(&pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87, (a0), (a1)); \
8846 iemFpuPrepareUsage(pIemCpu); \
8847 a_pfnAImpl(&pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87, (a0), (a1), (a2)); \
8858 iemFpuPushResult(pIemCpu, &a_FpuData)
8861 iemFpuPushResultWithMemOp(pIemCpu, &a_FpuData, a_iEffSeg, a_GCPtrEff)
8865 iemFpuPushResultTwo(pIemCpu, &a_FpuDataTwo)
8869 iemFpuStoreResult(pIemCpu, &a_FpuData, a_iStReg)
8872 iemFpuStoreResultThenPop(pIemCpu, &a_FpuData, a_iStReg)
8875 iemFpuStoreResultWithMemOp(pIemCpu, &a_FpuData, a_iStReg, a_iEffSeg, a_GCPtrEff)
8879 iemFpuStoreResultWithMemOpThenPop(pIemCpu, &a_FpuData, a_iStReg, a_iEffSeg, a_GCPtrEff)
8883 iemFpuUpdateOpcodeAndIp(pIemCpu)
8886 iemFpuStackFree(pIemCpu, a_iStReg)
8889 iemFpuStackIncTop(pIemCpu)
8892 iemFpuStackDecTop(pIemCpu)
8896 iemFpuUpdateFSW(pIemCpu, a_u16FSW)
8899 iemFpuUpdateFSW(pIemCpu, a_u16FSW)
8902 iemFpuUpdateFSWWithMemOp(pIemCpu, a_u16FSW, a_iEffSeg, a_GCPtrEff)
8905 iemFpuUpdateFSWThenPop(pIemCpu, a_u16FSW)
8909 iemFpuUpdateFSWWithMemOpThenPop(pIemCpu, a_u16FSW, a_iEffSeg, a_GCPtrEff)
8912 iemFpuUpdateFSWThenPop(pIemCpu, a_u16FSW)
8916 iemFpuStackUnderflow(pIemCpu, a_iStDst)
8920 iemFpuStackUnderflowThenPop(pIemCpu, a_iStDst)
8924 iemFpuStackUnderflowWithMemOp(pIemCpu, a_iStDst, a_iEffSeg, a_GCPtrEff)
8928 iemFpuStackUnderflowWithMemOpThenPop(pIemCpu, a_iStDst, a_iEffSeg, a_GCPtrEff)
8932 iemFpuStackUnderflowThenPopPop(pIemCpu)
8936 iemFpuStackPushUnderflow(pIemCpu)
8940 iemFpuStackPushUnderflowTwo(pIemCpu)
8945 iemFpuStackPushOverflow(pIemCpu)
8949 iemFpuStackPushOverflowWithMemOp(pIemCpu, a_iEffSeg, a_GCPtrEff)
8952 CPUMSetChangedFlags(IEMCPU_TO_VMCPU(pIemCpu), CPUM_CHANGED_FPU_REM)
8963 iemFpuPrepareUsage(pIemCpu); \
8964 a_pfnAImpl(&pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87, (a0), (a1)); \
8977 iemFpuPrepareUsage(pIemCpu); \
8978 a_pfnAImpl(&pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87, (a0), (a1), (a2)); \
8991 iemFpuPrepareUsageSse(pIemCpu); \
8992 a_pfnAImpl(&pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87, (a0), (a1)); \
9005 iemFpuPrepareUsageSse(pIemCpu); \
9006 a_pfnAImpl(&pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87, (a0), (a1), (a2)); \
9011 #define IEM_MC_IF_EFL_BIT_SET(a_fBit) if (pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit)) {
9013 #define IEM_MC_IF_EFL_BIT_NOT_SET(a_fBit) if (!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit))) {
9015 #define IEM_MC_IF_EFL_ANY_BITS_SET(a_fBits) if (pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBits)) {
9017 #define IEM_MC_IF_EFL_NO_BITS_SET(a_fBits) if (!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBits))) {
9020 if ( !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit1)) \
9021 != !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit2)) ) {
9024 if ( !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit1)) \
9025 == !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit2)) ) {
9028 if ( (pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit)) \
9029 || !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit1)) \
9030 != !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit2)) ) {
9033 if ( !(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit)) \
9034 && !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit1)) \
9035 == !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit2)) ) {
9036 #define IEM_MC_IF_CX_IS_NZ() if (pIemCpu->CTX_SUFF(pCtx)->cx != 0) {
9037 #define IEM_MC_IF_ECX_IS_NZ() if (pIemCpu->CTX_SUFF(pCtx)->ecx != 0) {
9038 #define IEM_MC_IF_RCX_IS_NZ() if (pIemCpu->CTX_SUFF(pCtx)->rcx != 0) {
9041 if ( pIemCpu->CTX_SUFF(pCtx)->cx != 0 \
9042 && (pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) {
9045 if ( pIemCpu->CTX_SUFF(pCtx)->ecx != 0 \
9046 && (pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) {
9049 if ( pIemCpu->CTX_SUFF(pCtx)->rcx != 0 \
9050 && (pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) {
9053 if ( pIemCpu->CTX_SUFF(pCtx)->cx != 0 \
9054 && !(pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) {
9057 if ( pIemCpu->CTX_SUFF(pCtx)->ecx != 0 \
9058 && !(pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) {
9061 if ( pIemCpu->CTX_SUFF(pCtx)->rcx != 0 \
9062 && !(pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) {
9064 #define IEM_MC_IF_GREG_BIT_SET(a_iGReg, a_iBitNo) if (*(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) & RT_BIT_64(a_iBitNo)) {
9066 if (iemFpuStRegNotEmpty(pIemCpu, (a_iSt)) == VINF_SUCCESS) {
9068 if (iemFpuStRegNotEmpty(pIemCpu, (a_iSt)) != VINF_SUCCESS) {
9070 if (iemFpuStRegNotEmptyRef(pIemCpu, (a_iSt), &(a_pr80Dst)) == VINF_SUCCESS) {
9072 if (iemFpu2StRegsNotEmptyRef(pIemCpu, (a_iSt0), &(a_pr80Dst0), (a_iSt1), &(a_pr80Dst1)) == VINF_SUCCESS) {
9074 if (iemFpu2StRegsNotEmptyRefFirst(pIemCpu, (a_iSt0), &(a_pr80Dst0), (a_iSt1)) == VINF_SUCCESS) {
9076 if (pIemCpu->CTX_SUFF(pCtx)->CTX_SUFF(pXState)->x87.FCW & X86_FCW_IM) {
9089 Log4(("decode - %04x:%RGv %s%s [#%u]\n", pIemCpu->CTX_SUFF(pCtx)->cs.Sel, pIemCpu->CTX_SUFF(pCtx)->rip, \
9090 pIemCpu->fPrefixes & IEM_OP_PRF_LOCK ? "lock " : "", a_szMnemonic, pIemCpu->cInstructions))
9092 Log4(("decode - %04x:%RGv %s%s %s [#%u]\n", pIemCpu->CTX_SUFF(pCtx)->cs.Sel, pIemCpu->CTX_SUFF(pCtx)->rip, \
9093 pIemCpu->fPrefixes & IEM_OP_PRF_LOCK ? "lock " : "", a_szMnemonic, a_szOps, pIemCpu->cInstructions))
9110 if (IEM_IS_REAL_OR_V86_MODE(pIemCpu)) \
9120 if (pIemCpu->fPrefixes & IEM_OP_PRF_LOCK) \
9129 if (pIemCpu->enmCpuMode == IEMMODE_64BIT) \
9138 if (pIemCpu->enmCpuMode != IEMMODE_64BIT) \
9146 if (pIemCpu->enmCpuMode == IEMMODE_64BIT) \
9147 iemRecalEffOpSize64Default(pIemCpu); \
9154 if (pIemCpu->enmCpuMode == IEMMODE_64BIT) \
9155 pIemCpu->enmEffOpSize = pIemCpu->enmDefOpSize = IEMMODE_64BIT; \
9163 if (RT_UNLIKELY(pIemCpu->fPrefixes & IEM_OP_PRF_REX)) \
9166 pIemCpu->CTX_SUFF(pCtx)->rip, pIemCpu->fPrefixes)); \
9167 pIemCpu->fPrefixes &= ~IEM_OP_PRF_REX_MASK; \
9168 pIemCpu->uRexB = 0; \
9169 pIemCpu->uRexIndex = 0; \
9170 pIemCpu->uRexReg = 0; \
9171 iemRecalEffOpSize(pIemCpu); \
9190 if (RT_LIKELY(!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))) \
9198 if (RT_LIKELY(!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))) \
9209 if (RT_LIKELY(!(pIemCpu->fPrefixes & IEM_OP_PRF_LOCK))) \
9224 if (RT_LIKELY(!(pIemCpu->fPrefixes & (IEM_OP_PRF_LOCK | IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ)))) \
9237 * @param pIemCpu The IEM per CPU data.
9244 static VBOXSTRICTRC iemOpHlpCalcRmEffAddr(PIEMCPU pIemCpu, uint8_t bRm, uint8_t cbImm, PRTGCPTR pGCPtrEff)
9247 PCCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
9251 if (!(pIemCpu->fPrefixes & IEM_OP_PRF_SEG_MASK)) \
9252 pIemCpu->iEffSeg = X86_SREG_SS; \
9255 if (pIemCpu->enmCpuMode != IEMMODE_64BIT)
9258 if (pIemCpu->enmEffAddrMode == IEMMODE_16BIT)
9294 Assert(pIemCpu->enmEffAddrMode == IEMMODE_32BIT);
9383 if (pIemCpu->enmEffAddrMode == IEMMODE_32BIT)
9387 Assert(pIemCpu->enmEffAddrMode == IEMMODE_16BIT);
9400 u64EffAddr += pCtx->rip + pIemCpu->offOpcode + cbImm;
9405 switch ((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB)
9428 switch (((bSib >> X86_SIB_INDEX_SHIFT) & X86_SIB_INDEX_SMASK) | pIemCpu->uRexIndex)
9451 switch ((bSib & X86_SIB_BASE_MASK) | pIemCpu->uRexB)
9472 if (!pIemCpu->uRexB)
9518 if (pIemCpu->enmEffAddrMode == IEMMODE_64BIT)
9522 Assert(pIemCpu->enmEffAddrMode == IEMMODE_32BIT);
9548 static void iemExecVerificationModeSetup(PIEMCPU pIemCpu)
9550 PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu);
9551 PCPUMCTX pOrgCtx = pIemCpu->CTX_SUFF(pCtx);
9556 pIemCpu->uOldCs = pOrgCtx->cs.Sel;
9557 pIemCpu->uOldRip = pOrgCtx->rip;
9644 if (fNewNoRem != pIemCpu->fNoRem)
9646 pIemCpu->fNoRem = fNewNoRem;
9659 if (IEM_VERIFICATION_ENABLED(pIemCpu))
9664 pIemCpu->CTX_SUFF(pCtx) = &s_DebugCtx;
9670 pIemCpu->uInjectCpl = UINT8_MAX;
9681 if (!IEM_VERIFICATION_ENABLED(pIemCpu))
9683 pIemCpu->uInjectCpl = pIemCpu->uCpl;
9689 pIemCpu->cIOReads = 0;
9690 pIemCpu->cIOWrites = 0;
9691 pIemCpu->fIgnoreRaxRdx = false;
9692 pIemCpu->fOverlappingMovs = false;
9693 pIemCpu->fProblematicMemory = false;
9694 pIemCpu->fUndefinedEFlags = 0;
9696 if (IEM_VERIFICATION_ENABLED(pIemCpu))
9701 PIEMVERIFYEVTREC pEvtRec = pIemCpu->pIemEvtRecHead;
9702 pIemCpu->pIemEvtRecHead = NULL;
9703 pIemCpu->ppIemEvtRecNext = &pIemCpu->pIemEvtRecHead;
9709 pEvtRec->pNext = pIemCpu->pFreeEvtRec;
9710 pIemCpu->pFreeEvtRec = pEvtRec;
9713 pEvtRec = pIemCpu->pOtherEvtRecHead;
9714 pIemCpu->pOtherEvtRecHead = NULL;
9715 pIemCpu->ppOtherEvtRecNext = &pIemCpu->pOtherEvtRecHead;
9725 static PIEMVERIFYEVTREC iemVerifyAllocRecord(PIEMCPU pIemCpu)
9727 if (!IEM_VERIFICATION_ENABLED(pIemCpu))
9730 PIEMVERIFYEVTREC pEvtRec = pIemCpu->pFreeEvtRec;
9732 pIemCpu->pFreeEvtRec = pEvtRec->pNext;
9735 if (!pIemCpu->ppIemEvtRecNext)
9738 pEvtRec = (PIEMVERIFYEVTREC)MMR3HeapAlloc(IEMCPU_TO_VM(pIemCpu), MM_TAG_EM /* lazy bird*/, sizeof(*pEvtRec));
9756 PIEMCPU pIemCpu = &pVCpu->iem.s;
9757 PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
9763 pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
9764 *pIemCpu->ppOtherEvtRecNext = pEvtRec;
9776 PIEMCPU pIemCpu = &pVCpu->iem.s;
9777 PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
9787 pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
9788 *pIemCpu->ppOtherEvtRecNext = pEvtRec;
9800 PIEMCPU pIemCpu = &pVCpu->iem.s;
9801 PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
9807 pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
9808 *pIemCpu->ppOtherEvtRecNext = pEvtRec;
9819 PIEMCPU pIemCpu = &pVCpu->iem.s;
9820 PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
9827 pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
9828 *pIemCpu->ppOtherEvtRecNext = pEvtRec;
9848 * @param pIemCpu The IEM per CPU data.
9853 static VBOXSTRICTRC iemVerifyFakeIOPortRead(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue)
9855 PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
9861 pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
9862 *pIemCpu->ppIemEvtRecNext = pEvtRec;
9864 pIemCpu->cIOReads++;
9874 * @param pIemCpu The IEM per CPU data.
9879 static VBOXSTRICTRC iemVerifyFakeIOPortWrite(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue)
9881 PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
9888 pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
9889 *pIemCpu->ppIemEvtRecNext = pEvtRec;
9891 pIemCpu->cIOWrites++;
9898 * @param pIemCpu The IEM per CPU state.
9900 static void iemVerifyAssertMsg2(PIEMCPU pIemCpu)
9902 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
9903 PVM pVM = IEMCPU_TO_VM(pIemCpu);
9904 PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu);
9934 DBGFR3DisasInstrEx(pVM->pUVM, pVCpu->idCpu, pIemCpu->uOldCs, pIemCpu->uOldRip,
9990 * @param pIemCpu The IEM per CPU data.
9995 static void iemVerifyAssertRecords(PIEMCPU pIemCpu, PIEMVERIFYEVTREC pEvtRec1, PIEMVERIFYEVTREC pEvtRec2, const char *pszMsg)
10000 iemVerifyAssertMsg2(pIemCpu);
10009 * @param pIemCpu The IEM per CPU data.
10013 static void iemVerifyAssertRecord(PIEMCPU pIemCpu, PIEMVERIFYEVTREC pEvtRec, const char *pszMsg)
10017 iemVerifyAssertMsg2(pIemCpu);
10025 * @param pIemCpu The IEM per CPU data.
10030 static void iemVerifyWriteRecord(PIEMCPU pIemCpu, PIEMVERIFYEVTREC pEvtRec, bool fRem)
10034 int rc = PGMPhysSimpleReadGCPhys(IEMCPU_TO_VM(pIemCpu), abBuf, pEvtRec->u.RamWrite.GCPhys, pEvtRec->u.RamWrite.cb);
10039 if ( !pIemCpu->cIOReads
10052 const char *pszWho = fRem ? "rem" : HMR3IsVmxEnabled(IEMCPU_TO_VM(pIemCpu)->pUVM) ? "vmx" : "svm";
10060 iemVerifyAssertMsg2(pIemCpu);
10072 static void iemExecVerificationModeCheck(PIEMCPU pIemCpu)
10074 if (!IEM_VERIFICATION_ENABLED(pIemCpu))
10080 PCPUMCTX pOrgCtx = CPUMQueryGuestCtxPtr(IEMCPU_TO_VMCPU(pIemCpu));
10081 PCPUMCTX pDebugCtx = pIemCpu->CTX_SUFF(pCtx);
10083 pIemCpu->CTX_SUFF(pCtx) = pOrgCtx;
10089 PVM pVM = IEMCPU_TO_VM(pIemCpu);
10090 PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu);
10094 && pIemCpu->cIOReads == 0
10095 && pIemCpu->cIOWrites == 0
10096 && !pIemCpu->fProblematicMemory)
10109 && pIemCpu->uInjectCpl != UINT8_MAX
10257 uint32_t fFlagsMask = UINT32_MAX & ~pIemCpu->fUndefinedEFlags;
10285 if (pIemCpu->cIOReads != 1 && !pIemCpu->fIgnoreRaxRdx)
10288 if (!pIemCpu->fIgnoreRaxRdx)
10315 if (pIemCpu->uOldCs == 0x1b && pIemCpu->uOldRip == 0x77f61ff3 && fRem)
10354 iemVerifyAssertMsg2(pIemCpu);
10365 if (cDiffs == 0 && !pIemCpu->fOverlappingMovs)
10371 PIEMVERIFYEVTREC pIemRec = pIemCpu->pIemEvtRecHead;
10372 PIEMVERIFYEVTREC pOtherRec = pIemCpu->pOtherEvtRecHead;
10382 iemVerifyWriteRecord(pIemCpu, pIemRec, fRem);
10389 iemVerifyAssertRecords(pIemCpu, pIemRec, pOtherRec, "Type mismatches");
10419 iemVerifyAssertRecords(pIemCpu, pIemRec, pOtherRec, "Mismatch");
10432 iemVerifyWriteRecord(pIemCpu, pIemRec, fRem);
10436 iemVerifyAssertRecord(pIemCpu, pIemRec, "Extra IEM record!");
10438 iemVerifyAssertRecord(pIemCpu, pOtherRec, "Extra Other record!");
10440 pIemCpu->CTX_SUFF(pCtx) = pOrgCtx;
10446 static VBOXSTRICTRC iemVerifyFakeIOPortRead(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue)
10448 NOREF(pIemCpu); NOREF(Port); NOREF(pu32Value); NOREF(cbValue);
10452 static VBOXSTRICTRC iemVerifyFakeIOPortWrite(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue)
10454 NOREF(pIemCpu); NOREF(Port); NOREF(u32Value); NOREF(cbValue);
10531 * @param pIemCpu The IEM per CPU data.
10534 DECL_FORCE_INLINE(VBOXSTRICTRC) iemExecStatusCodeFiddling(PIEMCPU pIemCpu, VBOXSTRICTRC rcStrict)
10549 int32_t const rcPassUp = pIemCpu->rcPassUp;
10551 pIemCpu->cRetInfStatuses++;
10557 pIemCpu->cRetPassUpStatus++;
10563 pIemCpu->cRetInfStatuses++;
10567 pIemCpu->cRetAspectNotImplemented++;
10569 pIemCpu->cRetInstrNotImplemented++;
10575 pIemCpu->cRetErrStatuses++;
10577 else if (pIemCpu->rcPassUp != VINF_SUCCESS)
10579 pIemCpu->cRetPassUpStatus++;
10580 rcStrict = pIemCpu->rcPassUp;
10593 * @param pIemCpu The IEM per CPU data.
10597 DECL_FORCE_INLINE(VBOXSTRICTRC) iemExecOneInner(PVMCPU pVCpu, PIEMCPU pIemCpu, bool fExecuteInhibit)
10602 pIemCpu->cInstructions++;
10603 if (pIemCpu->cActiveMappings > 0)
10604 iemMemRollback(pIemCpu);
10606 // AssertMsg(pIemCpu->offOpcode == cbInstr || rcStrict != VINF_SUCCESS, ("%u %u\n", pIemCpu->offOpcode, cbInstr));
10614 && EMGetInhibitInterruptsPC(pVCpu) == pIemCpu->CTX_SUFF(pCtx)->rip )
10616 rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, pIemCpu->fBypassHandlers);
10620 iemLogCurInstr(IEMCPU_TO_VMCPU(pIemCpu), pIemCpu->CTX_SUFF(pCtx), false);
10625 pIemCpu->cInstructions++;
10626 if (pIemCpu->cActiveMappings > 0)
10627 iemMemRollback(pIemCpu);
10635 rcStrict = iemExecStatusCodeFiddling(pIemCpu, rcStrict);
10637 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pIemCpu->CTX_SUFF(pCtx)->cs));
10638 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pIemCpu->CTX_SUFF(pCtx)->ss));
10640 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pIemCpu->CTX_SUFF(pCtx)->es));
10641 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pIemCpu->CTX_SUFF(pCtx)->ds));
10642 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pIemCpu->CTX_SUFF(pCtx)->fs));
10643 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pIemCpu->CTX_SUFF(pCtx)->gs));
10654 * @param pIemCpu The IEM CPU structure.
10659 DECLINLINE(VBOXSTRICTRC) iemRCRawMaybeReenter(PIEMCPU pIemCpu, PVMCPU pVCpu, PCPUMCTX pCtx, VBOXSTRICTRC rcStrict)
10661 if (!pIemCpu->fInPatchCode)
10676 PIEMCPU pIemCpu = &pVCpu->iem.s;
10679 iemExecVerificationModeSetup(pIemCpu);
10682 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
10689 VBOXSTRICTRC rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, false);
10691 rcStrict = iemExecOneInner(pVCpu, pIemCpu, true);
10697 iemExecVerificationModeCheck(pIemCpu);
10700 rcStrict = iemRCRawMaybeReenter(pIemCpu, pVCpu, pIemCpu->CTX_SUFF(pCtx), rcStrict);
10711 PIEMCPU pIemCpu = &pVCpu->iem.s;
10715 uint32_t const cbOldWritten = pIemCpu->cbWritten;
10716 VBOXSTRICTRC rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, false);
10719 rcStrict = iemExecOneInner(pVCpu, pIemCpu, true);
10721 *pcbWritten = pIemCpu->cbWritten - cbOldWritten;
10725 rcStrict = iemRCRawMaybeReenter(pIemCpu, pVCpu, pCtx, rcStrict);
10734 PIEMCPU pIemCpu = &pVCpu->iem.s;
10742 iemInitDecoder(pIemCpu, false);
10743 pIemCpu->cbOpcode = (uint8_t)RT_MIN(cbOpcodeBytes, sizeof(pIemCpu->abOpcode));
10744 memcpy(pIemCpu->abOpcode, pvOpcodeBytes, pIemCpu->cbOpcode);
10748 rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, false);
10751 rcStrict = iemExecOneInner(pVCpu, pIemCpu, true);
10755 rcStrict = iemRCRawMaybeReenter(pIemCpu, pVCpu, pCtx, rcStrict);
10763 PIEMCPU pIemCpu = &pVCpu->iem.s;
10767 uint32_t const cbOldWritten = pIemCpu->cbWritten;
10768 VBOXSTRICTRC rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, true);
10771 rcStrict = iemExecOneInner(pVCpu, pIemCpu, false);
10773 *pcbWritten = pIemCpu->cbWritten - cbOldWritten;
10777 rcStrict = iemRCRawMaybeReenter(pIemCpu, pVCpu, pCtx, rcStrict);
10786 PIEMCPU pIemCpu = &pVCpu->iem.s;
10794 iemInitDecoder(pIemCpu, true);
10795 pIemCpu->cbOpcode = (uint8_t)RT_MIN(cbOpcodeBytes, sizeof(pIemCpu->abOpcode));
10796 memcpy(pIemCpu->abOpcode, pvOpcodeBytes, pIemCpu->cbOpcode);
10800 rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, true);
10802 rcStrict = iemExecOneInner(pVCpu, pIemCpu, false);
10805 rcStrict = iemRCRawMaybeReenter(pIemCpu, pVCpu, pCtx, rcStrict);
10813 PIEMCPU pIemCpu = &pVCpu->iem.s;
10819 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
10821 pIemCpu->uInjectCpl = UINT8_MAX;
10833 if (!IEM_VERIFICATION_ENABLED(pIemCpu))
10837 iemExecVerificationModeSetup(pIemCpu);
10838 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
10851 VBOXSTRICTRC rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, false);
10853 rcStrict = iemExecOneInner(pVCpu, pIemCpu, true);
10859 iemExecVerificationModeCheck(pIemCpu);
10866 rcStrict = iemRCRawMaybeReenter(pIemCpu, pVCpu, pIemCpu->CTX_SUFF(pCtx), rcStrict);
11002 PIEMCPU pIemCpu = &pVCpu->iem.s;
11006 iemInitDecoder(pIemCpu);
11007 VBOXSTRICTRC rcStrict = iemCImpl_iret(pIemCpu, 1, pIemCpu->enmDefOpSize);
11056 PIEMCPU pIemCpu = &pVCpu->iem.s;
11057 iemInitExec(pIemCpu, false /*fBypassHandlers*/);
11070 case 1: rcStrict = iemCImpl_rep_outs_op8_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11071 case 2: rcStrict = iemCImpl_rep_outs_op16_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11072 case 4: rcStrict = iemCImpl_rep_outs_op32_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11081 case 1: rcStrict = iemCImpl_rep_outs_op8_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11082 case 2: rcStrict = iemCImpl_rep_outs_op16_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11083 case 4: rcStrict = iemCImpl_rep_outs_op32_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11092 case 1: rcStrict = iemCImpl_rep_outs_op8_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11093 case 2: rcStrict = iemCImpl_rep_outs_op16_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11094 case 4: rcStrict = iemCImpl_rep_outs_op32_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11111 case 1: rcStrict = iemCImpl_outs_op8_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11112 case 2: rcStrict = iemCImpl_outs_op16_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11113 case 4: rcStrict = iemCImpl_outs_op32_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11122 case 1: rcStrict = iemCImpl_outs_op8_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11123 case 2: rcStrict = iemCImpl_outs_op16_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11124 case 4: rcStrict = iemCImpl_outs_op32_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11133 case 1: rcStrict = iemCImpl_outs_op8_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11134 case 2: rcStrict = iemCImpl_outs_op16_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11135 case 4: rcStrict = iemCImpl_outs_op32_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
11146 return iemExecStatusCodeFiddling(pIemCpu, rcStrict);
11173 PIEMCPU pIemCpu = &pVCpu->iem.s;
11174 iemInitExec(pIemCpu, false /*fBypassHandlers*/);
11187 case 1: rcStrict = iemCImpl_rep_ins_op8_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11188 case 2: rcStrict = iemCImpl_rep_ins_op16_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11189 case 4: rcStrict = iemCImpl_rep_ins_op32_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11198 case 1: rcStrict = iemCImpl_rep_ins_op8_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11199 case 2: rcStrict = iemCImpl_rep_ins_op16_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11200 case 4: rcStrict = iemCImpl_rep_ins_op32_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11209 case 1: rcStrict = iemCImpl_rep_ins_op8_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11210 case 2: rcStrict = iemCImpl_rep_ins_op16_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11211 case 4: rcStrict = iemCImpl_rep_ins_op32_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11228 case 1: rcStrict = iemCImpl_ins_op8_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11229 case 2: rcStrict = iemCImpl_ins_op16_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11230 case 4: rcStrict = iemCImpl_ins_op32_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11239 case 1: rcStrict = iemCImpl_ins_op8_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11240 case 2: rcStrict = iemCImpl_ins_op16_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11241 case 4: rcStrict = iemCImpl_ins_op32_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11250 case 1: rcStrict = iemCImpl_ins_op8_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11251 case 2: rcStrict = iemCImpl_ins_op16_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11252 case 4: rcStrict = iemCImpl_ins_op32_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break;
11263 return iemExecStatusCodeFiddling(pIemCpu, rcStrict);
11285 PIEMCPU pIemCpu = &pVCpu->iem.s;
11286 iemInitExec(pIemCpu, false /*fBypassHandlers*/);
11288 return iemExecStatusCodeFiddling(pIemCpu, rcStrict);
11309 PIEMCPU pIemCpu = &pVCpu->iem.s;
11310 iemInitExec(pIemCpu, false /*fBypassHandlers*/);
11312 return iemExecStatusCodeFiddling(pIemCpu, rcStrict);
11329 PIEMCPU pIemCpu = &pVCpu->iem.s;
11330 iemInitExec(pIemCpu, false /*fBypassHandlers*/);
11332 return iemExecStatusCodeFiddling(pIemCpu, rcStrict);
11350 PIEMCPU pIemCpu = &pVCpu->iem.s;
11351 iemInitExec(pIemCpu, false /*fBypassHandlers*/);
11353 return iemExecStatusCodeFiddling(pIemCpu, rcStrict);
11373 PIEMCPU pIemCpu = &pVCpu->iem.s;
11374 iemInitExec(pIemCpu, false /*fBypassHandlers*/);
11376 return iemExecStatusCodeFiddling(pIemCpu, rcStrict);