IEMAll.cpp revision 0e87e61329b2583263eee1893c5ec83bb12097d6
199767f8919635c4928607450d9e0abb932109ceToomas Soome * IEM - Interpreted Execution Manager - All Contexts.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (C) 2011 Oracle Corporation
199767f8919635c4928607450d9e0abb932109ceToomas Soome * This file is part of VirtualBox Open Source Edition (OSE), as
199767f8919635c4928607450d9e0abb932109ceToomas Soome * available from http://www.virtualbox.org. This file is free software;
199767f8919635c4928607450d9e0abb932109ceToomas Soome * you can redistribute it and/or modify it under the terms of the GNU
199767f8919635c4928607450d9e0abb932109ceToomas Soome * General Public License (GPL) as published by the Free Software
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Foundation, in version 2 as it comes in the "COPYING" file of the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** @page pg_iem IEM - Interpreted Execution Manager
199767f8919635c4928607450d9e0abb932109ceToomas Soome * The interpreted exeuction manager (IEM) is for executing short guest code
199767f8919635c4928607450d9e0abb932109ceToomas Soome * sequences that are causing too many exits / virtualization traps. It will
199767f8919635c4928607450d9e0abb932109ceToomas Soome * also be used to interpret single instructions, thus replacing the selective
199767f8919635c4928607450d9e0abb932109ceToomas Soome * interpreters in EM and IOM.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Design goals:
199767f8919635c4928607450d9e0abb932109ceToomas Soome * - Relatively small footprint, although we favour speed and correctness
199767f8919635c4928607450d9e0abb932109ceToomas Soome * over size.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * - Reasonably fast.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * - Correctly handle lock prefixed instructions.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * - Complete instruction set - eventually.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * - Refactorable into a recompiler, maybe.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * - Replace EMInterpret*.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Using the existing disassembler has been considered, however this is thought
199767f8919635c4928607450d9e0abb932109ceToomas Soome * to conflict with speed as the disassembler chews things a bit too much while
199767f8919635c4928607450d9e0abb932109ceToomas Soome * leaving us with a somewhat complicated state to interpret afterwards.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * The current code is very much work in progress. You've been warned!
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*******************************************************************************
199767f8919635c4928607450d9e0abb932109ceToomas Soome* Header Files *
199767f8919635c4928607450d9e0abb932109ceToomas Soome*******************************************************************************/
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define LOG_GROUP LOG_GROUP_EM /** @todo add log group */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*******************************************************************************
199767f8919635c4928607450d9e0abb932109ceToomas Soome* Structures and Typedefs *
199767f8919635c4928607450d9e0abb932109ceToomas Soome*******************************************************************************/
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** @typedef PFNIEMOP
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Pointer to an opcode decoder function.
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** @def FNIEMOP_DEF
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Define an opcode decoder function.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * We're using macors for this so that adding and removing parameters as well as
199767f8919635c4928607450d9e0abb932109ceToomas Soome * tweaking compiler specific attributes becomes easier. See FNIEMOP_CALL
199767f8919635c4928607450d9e0abb932109ceToomas Soome * @param a_Name The function name.
199767f8919635c4928607450d9e0abb932109ceToomas Soometypedef VBOXSTRICTRC (__attribute__((__fastcall__)) * PFNIEMOP)(PIEMCPU pIemCpu);
199767f8919635c4928607450d9e0abb932109ceToomas Soome static VBOXSTRICTRC __attribute__((__fastcall__, __nothrow__)) a_Name (PIEMCPU pIemCpu)
199767f8919635c4928607450d9e0abb932109ceToomas Soome# define FNIEMOP_DEF_1(a_Name, a_Type0, a_Name0) \
199767f8919635c4928607450d9e0abb932109ceToomas Soome static VBOXSTRICTRC __attribute__((__fastcall__, __nothrow__)) a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0) RT_NO_THROW
199767f8919635c4928607450d9e0abb932109ceToomas Soome# define FNIEMOP_DEF_2(a_Name, a_Type0, a_Name0, a_Type1, a_Name1) \
199767f8919635c4928607450d9e0abb932109ceToomas Soome static VBOXSTRICTRC __attribute__((__fastcall__, __nothrow__)) a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0, a_Type1 a_Name1) RT_NO_THROW
199767f8919635c4928607450d9e0abb932109ceToomas Soometypedef VBOXSTRICTRC (__fastcall * PFNIEMOP)(PIEMCPU pIemCpu);
199767f8919635c4928607450d9e0abb932109ceToomas Soome static /*__declspec(naked)*/ VBOXSTRICTRC __fastcall a_Name(PIEMCPU pIemCpu) RT_NO_THROW
199767f8919635c4928607450d9e0abb932109ceToomas Soome# define FNIEMOP_DEF_1(a_Name, a_Type0, a_Name0) \
199767f8919635c4928607450d9e0abb932109ceToomas Soome static /*__declspec(naked)*/ VBOXSTRICTRC __fastcall a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0) RT_NO_THROW
199767f8919635c4928607450d9e0abb932109ceToomas Soome# define FNIEMOP_DEF_2(a_Name, a_Type0, a_Name0, a_Type1, a_Name1) \
199767f8919635c4928607450d9e0abb932109ceToomas Soome static /*__declspec(naked)*/ VBOXSTRICTRC __fastcall a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0, a_Type1 a_Name1) RT_NO_THROW
199767f8919635c4928607450d9e0abb932109ceToomas Soometypedef VBOXSTRICTRC (* PFNIEMOP)(PIEMCPU pIemCpu);
199767f8919635c4928607450d9e0abb932109ceToomas Soome static VBOXSTRICTRC a_Name(PIEMCPU pIemCpu) RT_NO_THROW
199767f8919635c4928607450d9e0abb932109ceToomas Soome# define FNIEMOP_DEF_1(a_Name, a_Type0, a_Name0) \
199767f8919635c4928607450d9e0abb932109ceToomas Soome static VBOXSTRICTRC a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0) RT_NO_THROW
199767f8919635c4928607450d9e0abb932109ceToomas Soome# define FNIEMOP_DEF_2(a_Name, a_Type0, a_Name0, a_Type1, a_Name1) \
199767f8919635c4928607450d9e0abb932109ceToomas Soome static VBOXSTRICTRC a_Name(PIEMCPU pIemCpu, a_Type0 a_Name0, a_Type1 a_Name1) RT_NO_THROW
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Function table for a binary operator providing implementation based on
199767f8919635c4928607450d9e0abb932109ceToomas Soome * operand size.
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Pointer to a binary operator function table. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Function table for a unary operator providing implementation based on
199767f8919635c4928607450d9e0abb932109ceToomas Soome * operand size.
199767f8919635c4928607450d9e0abb932109ceToomas Soome PFNIEMAIMPLUNARYU16 pfnNormalU16, pfnLockedU16;
199767f8919635c4928607450d9e0abb932109ceToomas Soome PFNIEMAIMPLUNARYU32 pfnNormalU32, pfnLockedU32;
199767f8919635c4928607450d9e0abb932109ceToomas Soome PFNIEMAIMPLUNARYU64 pfnNormalU64, pfnLockedU64;
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Pointer to a unary operator function table. */
199767f8919635c4928607450d9e0abb932109ceToomas Soometypedef IEMOPUNARYSIZES const *PCIEMOPUNARYSIZES;
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Function table for a shift operator providing implementation based on
199767f8919635c4928607450d9e0abb932109ceToomas Soome * operand size.
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Pointer to a shift operator function table. */
199767f8919635c4928607450d9e0abb932109ceToomas Soometypedef IEMOPSHIFTSIZES const *PCIEMOPSHIFTSIZES;
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Function table for a multiplication or division operation.
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Pointer to a multiplication or division operation function table. */
199767f8919635c4928607450d9e0abb932109ceToomas Soometypedef IEMOPMULDIVSIZES const *PCIEMOPMULDIVSIZES;
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Selector descriptor table entry as fetched by iemMemFetchSelDesc.
199767f8919635c4928607450d9e0abb932109ceToomas Soome /** The legacy view. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /** The long mode view. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Pointer to a selector descriptor table entry. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*******************************************************************************
199767f8919635c4928607450d9e0abb932109ceToomas Soome* Defined Constants And Macros *
199767f8919635c4928607450d9e0abb932109ceToomas Soome*******************************************************************************/
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Temporary hack to disable the double execution. Will be removed in favor
199767f8919635c4928607450d9e0abb932109ceToomas Soome * of a dedicated execution mode in EM. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Used to shut up GCC warnings about variables that 'may be used uninitialized'
199767f8919635c4928607450d9e0abb932109ceToomas Soome * due to GCC lacking knowledge about the value range of a switch. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define IEM_NOT_REACHED_DEFAULT_CASE_RET() default: AssertFailedReturn(VERR_INTERNAL_ERROR_4)
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Call an opcode decoder function.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * We're using macors for this so that adding and removing parameters can be
199767f8919635c4928607450d9e0abb932109ceToomas Soome * done as we please. See FNIEMOP_DEF.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Call a common opcode decoder function taking one extra argument.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * We're using macors for this so that adding and removing parameters can be
199767f8919635c4928607450d9e0abb932109ceToomas Soome * done as we please. See FNIEMOP_DEF_1.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define FNIEMOP_CALL_1(a_pfn, a0) (a_pfn)(pIemCpu, a0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Call a common opcode decoder function taking one extra argument.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * We're using macors for this so that adding and removing parameters can be
199767f8919635c4928607450d9e0abb932109ceToomas Soome * done as we please. See FNIEMOP_DEF_1.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define FNIEMOP_CALL_2(a_pfn, a0, a1) (a_pfn)(pIemCpu, a0, a1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Check if we're currently executing in real or virtual 8086 mode.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * @returns @c true if it is, @c false if not.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * @param a_pIemCpu The IEM state of the current CPU.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define IEM_IS_REAL_OR_V86_MODE(a_pIemCpu) (CPUMIsGuestInRealOrV86ModeEx((a_pIemCpu)->CTX_SUFF(pCtx)))
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Check if we're currently executing in long mode.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * @returns @c true if it is, @c false if not.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * @param a_pIemCpu The IEM state of the current CPU.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define IEM_IS_LONG_MODE(a_pIemCpu) (CPUMIsGuestInLongModeEx((a_pIemCpu)->CTX_SUFF(pCtx)))
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Check if we're currently executing in real mode.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * @returns @c true if it is, @c false if not.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * @param a_pIemCpu The IEM state of the current CPU.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define IEM_IS_REAL_MODE(a_pIemCpu) (CPUMIsGuestInRealModeEx((a_pIemCpu)->CTX_SUFF(pCtx)))
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Tests if an AMD CPUID feature (extended) is marked present - ECX.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define IEM_IS_AMD_CPUID_FEATURE_PRESENT_ECX(a_fEcx) iemRegIsAmdCpuIdFeaturePresent(pIemCpu, 0, (a_fEcx))
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Check if the address is canonical.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define IEM_IS_CANONICAL(a_u64Addr) ((uint64_t)(a_u64Addr) + UINT64_C(0x800000000000) < UINT64_C(0x1000000000000))
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*******************************************************************************
199767f8919635c4928607450d9e0abb932109ceToomas Soome* Global Variables *
199767f8919635c4928607450d9e0abb932109ceToomas Soome*******************************************************************************/
199767f8919635c4928607450d9e0abb932109ceToomas Soomeextern const PFNIEMOP g_apfnOneByteMap[256]; /* not static since we need to forward declare it. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the ADD instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the ADC instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the SUB instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the SBB instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the OR instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the XOR instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the AND instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the CMP instruction.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * @remarks Making operand order ASSUMPTIONS.
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the TEST instruction.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * @remarks Making operand order ASSUMPTIONS.
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Group 1 /r lookup table. */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic const PCIEMOPBINSIZES g_apIemImplGrp1[8] =
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the INC instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the DEC instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the NEG instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the NOT instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the ROL instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the ROR instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the RCL instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the RCR instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the SHL instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the SHR instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the SAR instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the MUL instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the IMUL instruction working implicitly on rAX. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the DIV instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** Function table for the MUL instruction. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*******************************************************************************
199767f8919635c4928607450d9e0abb932109ceToomas Soome* Internal Functions *
199767f8919635c4928607450d9e0abb932109ceToomas Soome*******************************************************************************/
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic VBOXSTRICTRC iemRaiseGeneralProtectionFault0(PIEMCPU pIemCpu);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic VBOXSTRICTRC iemRaiseSelectorBounds(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic VBOXSTRICTRC iemRaiseSelectorInvalidAccess(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic VBOXSTRICTRC iemRaiseSelectorNotPresent(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic VBOXSTRICTRC iemRaisePageFault(PIEMCPU pIemCpu, RTGCPTR GCPtrWhere, uint32_t fAccess, int rc);
199767f8919635c4928607450d9e0abb932109ceToomas Soome#if defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_NO_REM)
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic PIEMVERIFYEVTREC iemVerifyAllocRecord(PIEMCPU pIemCpu);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic VBOXSTRICTRC iemVerifyFakeIOPortRead(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic VBOXSTRICTRC iemVerifyFakeIOPortWrite(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue);
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Initializes the decoder state.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * @param pIemCpu The per CPU IEM state.
199767f8919635c4928607450d9e0abb932109ceToomas Soome pIemCpu->uCpl = CPUMGetGuestCPL(IEMCPU_TO_VMCPU(pIemCpu), CPUMCTX2CORE(pCtx));
199767f8919635c4928607450d9e0abb932109ceToomas Soome IEMMODE enmMode = CPUMIsGuestIn64BitCodeEx(pCtx)
199767f8919635c4928607450d9e0abb932109ceToomas Soome : pCtx->csHid.Attr.n.u1DefBig /** @todo check if this is correct... */
199767f8919635c4928607450d9e0abb932109ceToomas Soome pIemCpu->enmDefAddrMode = enmMode; /** @todo check if this is correct... */
199767f8919635c4928607450d9e0abb932109ceToomas Soome pIemCpu->enmDefOpSize = enmMode; /** @todo check if this is correct... */
* What we're doing here is very similar to iemMemMap/iemMemBounceBufferMap.
return rc;
return VINF_SUCCESS;
* What we're doing here is very similar to iemMemMap/iemMemBounceBufferMap.
rc = PGMPhysRead(IEMCPU_TO_VM(pIemCpu), GCPhys, &pIemCpu->abOpcode[pIemCpu->cbOpcode], cbToTryRead);
rc = PGMPhysSimpleReadGCPhys(IEMCPU_TO_VM(pIemCpu), &pIemCpu->abOpcode[pIemCpu->cbOpcode], GCPhys, cbToTryRead);
return rc;
return VINF_SUCCESS;
*pb = 0;
return rcStrict;
return rcStrict;
*pu16 = 0;
return rcStrict;
*pu32 = 0;
return rcStrict;
*pu64 = 0;
return rcStrict;
*pu64 = 0;
return rcStrict;
return VINF_SUCCESS;
return rcStrict2; \
return rcStrict2; \
return VINF_SUCCESS;
return rcStrict2; \
return VINF_SUCCESS;
return rcStrict2; \
return VINF_SUCCESS;
return rcStrict2; \
return VINF_SUCCESS;
return rcStrict2; \
return VINF_SUCCESS;
return rcStrict2; \
return VERR_NOT_IMPLEMENTED;
return VERR_NOT_IMPLEMENTED;
return VERR_NOT_IMPLEMENTED;
return VERR_NOT_IMPLEMENTED;
return VERR_NOT_IMPLEMENTED;
static VBOXSTRICTRC iemRaiseSelectorInvalidAccess(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess)
return VERR_NOT_IMPLEMENTED;
return VERR_NOT_IMPLEMENTED;
return VERR_NOT_IMPLEMENTED;
static VBOXSTRICTRC iemRaisePageFault(PIEMCPU pIemCpu, RTGCPTR GCPtrWhere, uint32_t fAccess, int rc)
return VERR_NOT_IMPLEMENTED;
AssertFailed();
return VERR_NOT_IMPLEMENTED;
AssertFailed();
return VERR_NOT_IMPLEMENTED;
case IEMMODE_16BIT:
case IEMMODE_32BIT:
case IEMMODE_64BIT:
case IEM_OP_PRF_SIZE_OP:
case IEM_OP_PRF_SIZE_REX_W:
AssertFailed();
return VERR_NOT_IMPLEMENTED; \
typedef int ignore_semicolon
switch (iSegReg)
switch (iSegReg)
switch (iSegReg)
switch (iReg)
pu8Reg++;
return pu8Reg;
return *pbSrc;
case IEMMODE_16BIT:
case IEMMODE_32BIT:
case IEMMODE_64BIT:
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
case IEMMODE_16BIT:
case IEMMODE_32BIT:
case IEMMODE_64BIT:
return VINF_SUCCESS;
case IEMMODE_16BIT:
case IEMMODE_32BIT:
case IEMMODE_64BIT:
default: AssertFailed();
return GCPtrTop;
return GCPtrTop;
return GCPtrTop;
return GCPtrTop;
static VBOXSTRICTRC iemMemSegCheckWriteAccessEx(PIEMCPU pIemCpu, PCCPUMSELREGHID pHid, uint8_t iSegReg)
return VINF_SUCCESS;
static VBOXSTRICTRC iemMemSegCheckReadAccessEx(PIEMCPU pIemCpu, PCCPUMSELREGHID pHid, uint8_t iSegReg)
return VINF_SUCCESS;
return VINF_SUCCESS;
case IEMMODE_16BIT:
case IEMMODE_32BIT:
return VERR_NOT_IMPLEMENTED;
return VINF_SUCCESS;
case IEMMODE_64BIT:
return VINF_SUCCESS;
static VBOXSTRICTRC iemMemPageTranslateAndCheckAccess(PIEMCPU pIemCpu, RTGCPTR GCPtrMem, uint32_t fAccess,
return VINF_SUCCESS;
return VERR_PGM_PHYS_TLB_CATCH_ALL;
ppvMem);
return VERR_NOT_FOUND;
int rc;
#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM) /* No memory changes in verification mode. */
cbFirst);
cbSecond);
cbFirst);
cbSecond);
if (pEvtRec)
memcpy(pEvtRec->u.RamWrite.ab, &pIemCpu->aBounceBuffers[iMemMap].ab[0], pIemCpu->aMemBbMappings[iMemMap].cbFirst);
if (pEvtRec)
return rc;
VBOXSTRICTRC rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, GCPtrFirst, fAccess, &GCPhysFirst);
return rcStrict;
rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, GCPtrFirst + (cbMem - 1), fAccess, &GCPhysSecond);
return rcStrict;
int rc;
return rc;
return rc;
return rc;
rc = PGMPhysSimpleReadGCPhys(IEMCPU_TO_VM(pIemCpu), pbBuf + cbFirstPage, GCPhysSecond, cbSecondPage);
return rc;
if (pEvtRec)
if (pEvtRec)
#ifdef VBOX_STRICT
#ifdef VBOX_STRICT
return VINF_SUCCESS;
static VBOXSTRICTRC iemMemBounceBufferMapPhys(PIEMCPU pIemCpu, unsigned iMemMap, void **ppvMem, size_t cbMem,
return rcMap;
int rc;
return rc;
if (pEvtRec)
#ifdef VBOX_STRICT
#ifdef VBOX_STRICT
return VINF_SUCCESS;
static VBOXSTRICTRC iemMemMap(PIEMCPU pIemCpu, void **ppvMem, size_t cbMem, uint8_t iSegReg, RTGCPTR GCPtrMem, uint32_t fAccess)
return rcStrict;
return rcStrict;
void *pvMem;
return VINF_SUCCESS;
if ( (pIemCpu->aMemMappings[iMemMap].fAccess & (IEM_ACCESS_BOUNCE_BUFFERED | IEM_ACCESS_TYPE_WRITE))
return VINF_SUCCESS;
static VBOXSTRICTRC iemMemFetchDataU8(PIEMCPU pIemCpu, uint8_t *pu8Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu8Src, sizeof(*pu8Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
return rc;
static VBOXSTRICTRC iemMemFetchDataU16(PIEMCPU pIemCpu, uint16_t *pu16Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Src, sizeof(*pu16Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
return rc;
static VBOXSTRICTRC iemMemFetchDataU32(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Src, sizeof(*pu32Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
return rc;
static VBOXSTRICTRC iemMemFetchDataS32SxU64(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pi32Src, sizeof(*pi32Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
*pu64Dst = 0;
return rc;
static VBOXSTRICTRC iemMemFetchDataU64(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem)
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Src, sizeof(*pu64Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
return rc;
(void **)&pu8Src,
switch (enmOpSize)
case IEMMODE_16BIT:
case IEMMODE_32BIT:
case IEMMODE_64BIT:
return rcStrict;
static VBOXSTRICTRC iemMemStoreDataU8(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, uint8_t u8Value)
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu8Dst, sizeof(*pu8Dst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W);
return rc;
static VBOXSTRICTRC iemMemStoreDataU16(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, uint16_t u16Value)
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Dst, sizeof(*pu16Dst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W);
return rc;
static VBOXSTRICTRC iemMemStoreDataU32(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, uint32_t u32Value)
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Dst, sizeof(*pu32Dst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W);
return rc;
static VBOXSTRICTRC iemMemStoreDataU64(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem, uint64_t u64Value)
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Dst, sizeof(*pu64Dst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W);
return rc;
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Dst, sizeof(*pu16Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
return rc;
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Dst, sizeof(*pu32Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
return rc;
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Dst, sizeof(*pu64Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
return rc;
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Src, sizeof(*pu16Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
return rc;
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Src, sizeof(*pu32Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
return rc;
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Src, sizeof(*pu64Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
return rc;
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Dst, sizeof(*pu16Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
return rc;
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Dst, sizeof(*pu32Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
return rc;
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu64Dst, sizeof(*pu64Dst), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_W);
return rc;
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Src, sizeof(*pu16Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
return rc;
VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu32Src, sizeof(*pu32Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
return rc;
VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu, (void **)&pu64Src, sizeof(*pu64Src), X86_SREG_SS, GCPtrTop, IEM_ACCESS_STACK_R);
return rcStrict;
static VBOXSTRICTRC iemMemStackPushBeginSpecial(PIEMCPU pIemCpu, size_t cbMem, void **ppvMem, uint64_t *puNewRsp)
return rcStrict;
static VBOXSTRICTRC iemMemStackPopBeginSpecial(PIEMCPU pIemCpu, size_t cbMem, void const **ppvMem, uint64_t *puNewRsp)
static VBOXSTRICTRC iemMemStackPopCommitSpecial(PIEMCPU pIemCpu, void const *pvMem, uint64_t uNewRsp)
return rcStrict;
VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pIemCpu, &pDesc->Legacy.u, UINT8_MAX, GCPtrBase + (uSel & X86_SEL_MASK));
else if ((uint32_t)(uSel & X86_SEL_MASK) + 15 < (uSel & X86_SEL_LDT ? pCtx->ldtrHid.u32Limit : pCtx->gdtr.cbGdt))
rcStrict = iemMemFetchDataU64(pIemCpu, &pDesc->Legacy.u, UINT8_MAX, GCPtrBase + (uSel & X86_SEL_MASK));
return rcStrict;
VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu, (void **)&pu32, 4, UINT8_MAX, GCPtr, IEM_ACCESS_DATA_RW);
return rcStrict;
DECLINLINE(VBOXSTRICTRC) iemHlpCheckPortIOPermission(PIEMCPU pIemCpu, PCCPUMCTX pCtx, uint16_t u16Port, uint8_t cbOperand)
return VINF_SUCCESS;
return rcStrict;
return rcStrict;
GCPtrBottom--;
return rcStrict;
GCPtrBottom--;
return rcStrict;
switch (enmEffOpSize)
case IEMMODE_16BIT:
case IEMMODE_32BIT:
case IEMMODE_64BIT:
return rcStrict;
return VINF_SUCCESS;
switch (enmEffOpSize)
case IEMMODE_16BIT:
return rcStrict;
case IEMMODE_32BIT:
return rcStrict;
return rcStrict;
switch (enmEffOpSize)
case IEMMODE_16BIT:
return rcStrict;
case IEMMODE_32BIT:
case IEMMODE_64BIT:
return rcStrict;
return VINF_SUCCESS;
return rcStrict;
return VINF_SUCCESS;
return rcStrict;
return VINF_SUCCESS;
return rcStrict;
return VINF_SUCCESS;
#ifdef IEM_VERIFICATION_MODE
return VINF_SUCCESS;
return rcStrict;
Log(("jmpf %04x:%08x -> not a code selector (u4Type=%#x).\n", uSel, offSeg, Desc.Legacy.Gen.u4Type));
Log(("jmpf %04x:%08x -> CPL != DPL; DPL=%d CPL=%u\n", uSel, offSeg, Desc.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
Log(("jmpf %04x:%08x -> RPL > DPL; RPL=%d CPL=%u\n", uSel, offSeg, (uSel & X86_SEL_RPL), pIemCpu->uCpl));
u64Base = 0;
return rcStrict;
return VINF_SUCCESS;
case AMD64_SEL_TYPE_SYS_LDT:
case X86_SEL_TYPE_SYS_LDT:
void *pvRet;
return rcStrict;
return rcStrict;
#ifdef IEM_VERIFICATION_MODE
return VINF_SUCCESS;
return rcStrict;
return rcStrict;
if (cbPop)
return VINF_SUCCESS;
AssertFailed();
return VERR_NOT_IMPLEMENTED;
switch (enmEffOpSize)
case IEMMODE_16BIT:
NewRip.u = 0;
case IEMMODE_32BIT:
NewRip.u = 0;
case IEMMODE_64BIT:
return rcStrict;
if (cbPop)
return VINF_SUCCESS;
return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Int << X86_TRAP_ERR_SEL_SHIFT));
rcStrict = iemMemFetchDataU32(pIemCpu, (uint32_t *)&Idte, UINT8_MAX, pCtx->idtr.pIdt + UINT32_C(4) * u8Int);
return rcStrict;
return rcStrict;
return rcStrict;
return VINF_SUCCESS;
AssertFailed();
return VERR_NOT_IMPLEMENTED;
void const *pv;
} uFrame;
return rcStrict;
| X86_EFL_ID;
return rcStrict;
return rcStrict;
return VINF_SUCCESS;
AssertFailed();
return VERR_NOT_IMPLEMENTED;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return rcStrict;
Log(("load sreg SS, %#x - DPL (%d) and CPL (%d) differs -> #GP\n", uSel, Desc.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
u64Base = 0;
return rcStrict;
pHid->Attr.u = (Desc.Legacy.u >> (16+16+8)) & UINT32_C(0xf0ff); /** @todo do we have a define for 0xf0ff? */
return VINF_SUCCESS;
switch (enmEffOpSize)
case IEMMODE_16BIT:
case IEMMODE_32BIT:
case IEMMODE_64BIT:
return rcStrict;
switch (enmEffOpSize)
case IEMMODE_16BIT:
case IEMMODE_32BIT:
case IEMMODE_64BIT:
return rcStrict;
VBOXSTRICTRC rcStrict = iemMemFetchDataXdtr(pIemCpu, &cbLimit, &GCPtrBase, iEffSeg, GCPtrEffSrc, enmEffOpSize);
return rcStrict;
VBOXSTRICTRC rcStrict = iemMemFetchDataXdtr(pIemCpu, &cbLimit, &GCPtrBase, iEffSeg, GCPtrEffSrc, enmEffOpSize);
return rcStrict;
switch (iCrReg)
return VINF_SUCCESS;
int rc;
switch (iCrReg)
Log(("Trying to set reserved CR0 bits: NewCR0=%#llx InvalidBits=%#llx\n", NewCrX, NewCrX & ~(uint64_t)fValid));
Log(("Trying to set reserved CR4 bits: NewCR4=%#llx InvalidBits=%#llx\n", NewCrX, NewCrX & ~(uint64_t)fValid));
return rcStrict;
return rcStrict;
switch (cbReg)
return rcStrict;
switch (cbReg)
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_EM_HALT;
#include "IEMAllCImplStrInstr.cpp.h"
#include "IEMAllCImplStrInstr.cpp.h"
#include "IEMAllCImplStrInstr.cpp.h"
#include "IEMAllCImplStrInstr.cpp.h"
#include "IEMAllCImplStrInstr.cpp.h"
#include "IEMAllCImplStrInstr.cpp.h"
#include "IEMAllCImplStrInstr.cpp.h"
#include "IEMAllCImplStrInstr.cpp.h"
#include "IEMAllCImplStrInstr.cpp.h"
#include "IEMAllCImplStrInstr.cpp.h"
#include "IEMAllCImplStrInstr.cpp.h"
#define IEM_MC_END() }
#define IEM_MC_PAUSE() do {} while (0)
#define IEM_MC_CONTINUE() do {} while (0)
return rcStrict2; \
#define IEM_MC_REL_JMP_S16(a_i16) IEM_MC_RETURN_ON_FAILURE(iemRegRipRelativeJumpS16(pIemCpu, a_i16))
#define IEM_MC_REL_JMP_S32(a_i32) IEM_MC_RETURN_ON_FAILURE(iemRegRipRelativeJumpS32(pIemCpu, a_i32))
#define IEM_MC_SET_RIP_U16(a_u16NewIP) IEM_MC_RETURN_ON_FAILURE(iemRegRipJump((pIemCpu), (a_u16NewIP)))
#define IEM_MC_SET_RIP_U32(a_u32NewIP) IEM_MC_RETURN_ON_FAILURE(iemRegRipJump((pIemCpu), (a_u32NewIP)))
#define IEM_MC_SET_RIP_U64(a_u64NewIP) IEM_MC_RETURN_ON_FAILURE(iemRegRipJump((pIemCpu), (a_u64NewIP)))
do { (pIemCpu)->CTX_SUFF(pCtx)->eflags.u = (a_EFlags); Assert((pIemCpu)->CTX_SUFF(pCtx)->eflags.u & X86_EFL_1); } while (0)
#define IEM_MC_FETCH_GREG_U8_ZX_U16(a_u16Dst, a_iGReg) (a_u16Dst) = iemGRegFetchU8(pIemCpu, (a_iGReg))
#define IEM_MC_FETCH_GREG_U8_ZX_U32(a_u32Dst, a_iGReg) (a_u32Dst) = iemGRegFetchU8(pIemCpu, (a_iGReg))
#define IEM_MC_FETCH_GREG_U8_ZX_U64(a_u64Dst, a_iGReg) (a_u64Dst) = iemGRegFetchU8(pIemCpu, (a_iGReg))
#define IEM_MC_FETCH_GREG_U16_ZX_U32(a_u32Dst, a_iGReg) (a_u32Dst) = iemGRegFetchU16(pIemCpu, (a_iGReg))
#define IEM_MC_FETCH_GREG_U16_ZX_U64(a_u64Dst, a_iGReg) (a_u64Dst) = iemGRegFetchU16(pIemCpu, (a_iGReg))
#define IEM_MC_FETCH_GREG_U32_ZX_U64(a_u64Dst, a_iGReg) (a_u64Dst) = iemGRegFetchU32(pIemCpu, (a_iGReg))
#define IEM_MC_FETCH_SREG_ZX_U32(a_u32Dst, a_iSReg) (a_u32Dst) = iemSRegFetchU16(pIemCpu, (a_iSReg))
#define IEM_MC_FETCH_SREG_ZX_U64(a_u64Dst, a_iSReg) (a_u64Dst) = iemSRegFetchU16(pIemCpu, (a_iSReg))
#define IEM_MC_STORE_GREG_U16(a_iGReg, a_u16Value) *(uint16_t *)iemGRegRef(pIemCpu, (a_iGReg)) = (a_u16Value)
#define IEM_MC_STORE_GREG_U32(a_iGReg, a_u32Value) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) = (uint32_t)(a_u32Value) /* clear high bits. */
#define IEM_MC_STORE_GREG_U64(a_iGReg, a_u64Value) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) = (a_u64Value)
#define IEM_MC_REF_GREG_U16(a_pu16Dst, a_iGReg) (a_pu16Dst) = (uint16_t *)iemGRegRef(pIemCpu, (a_iGReg))
#define IEM_MC_REF_GREG_U32(a_pu32Dst, a_iGReg) (a_pu32Dst) = (uint32_t *)iemGRegRef(pIemCpu, (a_iGReg))
#define IEM_MC_REF_GREG_U64(a_pu64Dst, a_iGReg) (a_pu64Dst) = (uint64_t *)iemGRegRef(pIemCpu, (a_iGReg))
#define IEM_MC_ADD_GREG_U8(a_iGReg, a_u16Value) *(uint8_t *)iemGRegRef(pIemCpu, (a_iGReg)) += (a_u8Value)
#define IEM_MC_ADD_GREG_U16(a_iGReg, a_u16Value) *(uint16_t *)iemGRegRef(pIemCpu, (a_iGReg)) += (a_u16Value)
#define IEM_MC_ADD_GREG_U64(a_iGReg, a_u64Value) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) += (a_u64Value)
#define IEM_MC_SUB_GREG_U8(a_iGReg, a_u8Value) *(uint8_t *)iemGRegRef(pIemCpu, (a_iGReg)) -= (a_u8Value)
#define IEM_MC_SUB_GREG_U16(a_iGReg, a_u16Value) *(uint16_t *)iemGRegRef(pIemCpu, (a_iGReg)) -= (a_u16Value)
#define IEM_MC_SUB_GREG_U64(a_iGReg, a_u64Value) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) -= (a_u64Value)
#define IEM_MC_SET_EFL_BIT(a_fBit) do { (pIemCpu)->CTX_SUFF(pCtx)->eflags.u |= (a_fBit); } while (0)
#define IEM_MC_CLEAR_EFL_BIT(a_fBit) do { (pIemCpu)->CTX_SUFF(pCtx)->eflags.u &= ~(a_fBit); } while (0)
IEM_MC_RETURN_ON_FAILURE(iemMemMap(pIemCpu, (void **)&(a_pMem), sizeof(*(a_pMem)), (a_iSeg), (a_GCPtrMem), (a_fAccess)))
IEM_MC_RETURN_ON_FAILURE(iemMemMap(pIemCpu, (void **)&(a_pvMem), (a_cbMem), (a_iSeg), (a_GCPtrMem), (a_fAccess)))
#define IEM_MC_CALL_CIMPL_2(a_pfnCImpl, a0, a1) return (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1)
#define IEM_MC_CALL_CIMPL_3(a_pfnCImpl, a0, a1, a2) return (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1, a2)
#define IEM_MC_CALL_CIMPL_5(a_pfnCImpl, a0, a1, a2, a3, a4) return (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1, a2, a3, a4)
#define IEM_MC_DEFER_TO_CIMPL_2(a_pfnCImpl, a0, a1) (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1)
#define IEM_MC_IF_GREG_BIT_SET(a_iGReg, a_iBitNo) if (*(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) & RT_BIT_64(a_iBitNo)) {
#define IEM_MC_ELSE() } else {
#define IEM_MC_ENDIF() } do {} while (0)
#ifdef DEBUG
Log2(("decode - %04x:%08RGv %s\n", pIemCpu->CTX_SUFF(pCtx)->cs, pIemCpu->CTX_SUFF(pCtx)->rip, a_szMnemonic))
Log2(("decode - %04x:%08RGv %s %s\n", pIemCpu->CTX_SUFF(pCtx)->cs, pIemCpu->CTX_SUFF(pCtx)->rip, a_szMnemonic, a_szOps))
#define IEMOP_HLP_NO_LOCK_PREFIX() \
return IEMOP_RAISE_INVALID_LOCK_PREFIX(); \
#define IEMOP_HLP_NO_64BIT() \
return IEMOP_RAISE_INVALID_OPCODE(); \
#define IEMOP_HLP_DEFAULT_64BIT_OP_SIZE() \
#define SET_SS_DEF() \
case IEMMODE_16BIT:
case 0: u16EffAddr = 0; break;
return VINF_SUCCESS;
case IEMMODE_32BIT:
SET_SS_DEF();
return VINF_SUCCESS;
case IEMMODE_64BIT:
SET_SS_DEF();
return VINF_SUCCESS;
#include "IEMAllInstructions.cpp.h"
# ifndef IEM_VERIFICATION_MODE_NO_REM
while (pEvtRec)
} while (pEvtRec);
# ifndef IEM_VERIFICATION_MODE_NO_REM
if (pEvtRec)
pEvtRec = (PIEMVERIFYEVTREC)MMR3HeapAlloc(IEMCPU_TO_VM(pIemCpu), MM_TAG_EM /* lazy bird*/, sizeof(*pEvtRec));
if (!pEvtRec)
return NULL;
return pEvtRec;
# ifndef IEM_VERIFICATION_MODE_NO_REM
if (!pVCpu)
if (!pEvtRec)
# ifndef IEM_VERIFICATION_MODE_NO_REM
if (!pVCpu)
if (!pEvtRec)
# ifndef IEM_VERIFICATION_MODE_NO_REM
if (!pVCpu)
if (!pEvtRec)
# ifndef IEM_VERIFICATION_MODE_NO_REM
if (!pVCpu)
if (!pEvtRec)
VMM_INT_DECL(void) IEMNotifyIOPortReadString(PVM pVM, RTIOPORT Port, RTGCPTR GCPtrDst, RTGCUINTREG cTransfers, size_t cbValue)
AssertFailed();
VMM_INT_DECL(void) IEMNotifyIOPortWriteString(PVM pVM, RTIOPORT Port, RTGCPTR GCPtrSrc, RTGCUINTREG cTransfers, size_t cbValue)
AssertFailed();
# ifndef IEM_VERIFICATION_MODE_NO_REM
static VBOXSTRICTRC iemVerifyFakeIOPortRead(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue)
if (pEvtRec)
return VINF_SUCCESS;
static VBOXSTRICTRC iemVerifyFakeIOPortWrite(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue)
if (pEvtRec)
return VINF_SUCCESS;
case IEMVERIFYEVENT_RAM_READ:
case IEMVERIFYEVENT_RAM_WRITE:
static void iemVerifyAssertRecords(PIEMVERIFYEVTREC pEvtRec1, PIEMVERIFYEVTREC pEvtRec2, const char *pszMsg)
int rc = PGMPhysSimpleReadGCPhys(IEMCPU_TO_VM(pIemCpu), abBuf, pEvtRec->u.RamWrite.GCPhys, pEvtRec->u.RamWrite.cb);
unsigned cDiffs = 0;
case 1: RTAssertMsg2Weak(" %8s differs - iem=%02x - rem=%02x\n", #a_Field, pDebugCtx->a_Field, pOrgCtx->a_Field); break; \
case 2: RTAssertMsg2Weak(" %8s differs - iem=%04x - rem=%04x\n", #a_Field, pDebugCtx->a_Field, pOrgCtx->a_Field); break; \
case 4: RTAssertMsg2Weak(" %8s differs - iem=%08x - rem=%08x\n", #a_Field, pDebugCtx->a_Field, pOrgCtx->a_Field); break; \
case 8: RTAssertMsg2Weak(" %8s differs - iem=%016llx - rem=%016llx\n", #a_Field, pDebugCtx->a_Field, pOrgCtx->a_Field); break; \
cDiffs++; \
RTAssertMsg2Weak(" %8s differs - iem=%02x - rem=%02x\n", #a_Field, pDebugCtx->a_Field, pOrgCtx->a_Field); \
cDiffs++; \
cDiffs++;
RTAssertMsg2Weak(" rflags differs - iem=%08llx rem=%08llx\n", pDebugCtx->rflags.u, pOrgCtx->rflags.u);
if (cDiffs != 0)
AssertFailed();
if (cDiffs == 0)
bool fEquals;
case IEMVERIFYEVENT_RAM_READ:
case IEMVERIFYEVENT_RAM_WRITE:
fEquals = false;
if (!fEquals)
#ifdef LOG_ENABLED
szInstr));
return rcStrict;
// AssertMsg(pIemCpu->offOpcode == cbInstr || rcStrict != VINF_SUCCESS, ("%u %u\n", pIemCpu->offOpcode, cbInstr));
return rcStrict;