diff options
Diffstat (limited to 'src/VBox/VMM/include/IEMInternal.h')
| -rw-r--r-- | src/VBox/VMM/include/IEMInternal.h | 211 |
1 files changed, 195 insertions, 16 deletions
diff --git a/src/VBox/VMM/include/IEMInternal.h b/src/VBox/VMM/include/IEMInternal.h index 45803eaf..7b1b25a3 100644 --- a/src/VBox/VMM/include/IEMInternal.h +++ b/src/VBox/VMM/include/IEMInternal.h @@ -18,8 +18,9 @@ #ifndef ___IEMInternal_h #define ___IEMInternal_h -#include <VBox/vmm/stam.h> #include <VBox/vmm/cpum.h> +#include <VBox/vmm/iem.h> +#include <VBox/vmm/stam.h> #include <VBox/param.h> @@ -51,17 +52,6 @@ typedef RTFLOAT32U const *PCRTFLOAT32U; /** - * Operand or addressing mode. - */ -typedef enum IEMMODE -{ - IEMMODE_16BIT = 0, - IEMMODE_32BIT, - IEMMODE_64BIT -} IEMMODE; -AssertCompileSize(IEMMODE, 4); - -/** * Extended operand mode that includes a representation of 8-bit. * * This is used for packing down modes when invoking some C instruction @@ -213,8 +203,10 @@ typedef struct IEMCPU /** Whether to bypass access handlers or not. */ bool fBypassHandlers; + /** Indicates that we're interpreting patch code - RC only! */ + bool fInPatchCode; /** Explicit alignment padding. */ - bool afAlignment0[3]; + bool afAlignment0[2]; /** The flags of the current exception / interrupt. */ uint32_t fCurXcpt; @@ -268,10 +260,12 @@ typedef struct IEMCPU /** Indicates that a MOVS instruction with overlapping source and destination * was executed, causing the memory write records to be incorrrect. */ bool fOverlappingMovs; + /** Set if there are problematic memory accesses (MMIO, write monitored, ++). */ + bool fProblematicMemory; /** This is used to communicate a CPL changed caused by IEMInjectTrap that * CPUM doesn't yet reflect. */ uint8_t uInjectCpl; - bool afAlignment2[4]; + bool afAlignment2[3]; /** Mask of undefined eflags. * The verifier will any difference in these flags. */ uint32_t fUndefinedEFlags; @@ -376,6 +370,28 @@ typedef struct IEMCPU uint8_t ab[512]; } aBounceBuffers[3]; + /** @name Target CPU information. + * @{ */ + /** EDX value of CPUID(1). + * @remarks Some bits are subject to change and must be queried dynamically. */ + uint32_t fCpuIdStdFeaturesEdx; + /** ECX value of CPUID(1). + * @remarks Some bits are subject to change and must be queried dynamically. */ + uint32_t fCpuIdStdFeaturesEcx; + /** The CPU vendor. */ + CPUMCPUVENDOR enmCpuVendor; + /** @} */ + + /** @name Host CPU information. + * @{ */ + /** EDX value of CPUID(1). */ + uint32_t fHostCpuIdStdFeaturesEdx; + /** ECX value of CPUID(1). */ + uint32_t fHostCpuIdStdFeaturesEcx; + /** The CPU vendor. */ + CPUMCPUVENDOR enmHostCpuVendor; + /** @} */ + #ifdef IEM_VERIFICATION_MODE_FULL /** The event verification records for what IEM did (LIFO). */ R3PTRTYPE(PIEMVERIFYEVTREC) pIemEvtRecHead; @@ -391,6 +407,8 @@ typedef struct IEMCPU } IEMCPU; /** Pointer to the per-CPU IEM state. */ typedef IEMCPU *PIEMCPU; +/** Pointer to the const per-CPU IEM state. */ +typedef IEMCPU const *PCIEMCPU; /** Converts a IEMCPU pointer to a VMCPU pointer. * @returns VMCPU pointer. @@ -463,6 +481,44 @@ typedef IEMCPU *PIEMCPU; #define IEM_OP_PRF_REX_R RT_BIT_32(25) /**< REX.R prefix (0x44,0x45,0x46,0x47,0x4c,0x4d,0x4e,0x4f). */ #define IEM_OP_PRF_REX_B RT_BIT_32(26) /**< REX.B prefix (0x41,0x43,0x45,0x47,0x49,0x4b,0x4d,0x4f). */ #define IEM_OP_PRF_REX_X RT_BIT_32(27) /**< REX.X prefix (0x42,0x43,0x46,0x47,0x4a,0x4b,0x4e,0x4f). */ +/** Mask with all the REX prefix flags. + * This is generally for use when needing to undo the REX prefixes when they + * are followed legacy prefixes and therefore does not immediately preceed + * the first opcode byte. + * For testing whether any REX prefix is present, use IEM_OP_PRF_REX instead. */ +#define IEM_OP_PRF_REX_MASK (IEM_OP_PRF_REX | IEM_OP_PRF_REX_R | IEM_OP_PRF_REX_B | IEM_OP_PRF_REX_X | IEM_OP_PRF_SIZE_REX_W ) +/** @} */ + +/** @name Opcode forms + * @{ */ +/** ModR/M: reg, r/m */ +#define IEMOPFORM_RM 0 +/** ModR/M: reg, r/m (register) */ +#define IEMOPFORM_RM_REG (IEMOPFORM_RM | IEMOPFORM_MOD3) +/** ModR/M: reg, r/m (memory) */ +#define IEMOPFORM_RM_MEM (IEMOPFORM_RM | IEMOPFORM_NOT_MOD3) +/** ModR/M: r/m, reg */ +#define IEMOPFORM_MR 1 +/** ModR/M: r/m (register), reg */ +#define IEMOPFORM_MR_REG (IEMOPFORM_MR | IEMOPFORM_MOD3) +/** ModR/M: r/m (memory), reg */ +#define IEMOPFORM_MR_MEM (IEMOPFORM_MR | IEMOPFORM_NOT_MOD3) +/** ModR/M: r/m only */ +#define IEMOPFORM_M 2 +/** ModR/M: r/m only (register). */ +#define IEMOPFORM_M_REG (IEMOPFORM_M | IEMOPFORM_MOD3) +/** ModR/M: r/m only (memory). */ +#define IEMOPFORM_M_MEM (IEMOPFORM_M | IEMOPFORM_NOT_MOD3) +/** ModR/M: reg only */ +#define IEMOPFORM_R 3 + +/** Fixed register instruction, no R/M. */ +#define IEMOPFORM_FIXED 4 + +/** The r/m is a register. */ +#define IEMOPFORM_MOD3 RT_BIT_32(8) +/** The r/m is a memory access. */ +#define IEMOPFORM_NOT_MOD3 RT_BIT_32(9) /** @} */ /** @@ -482,7 +538,7 @@ typedef IEMCPU *PIEMCPU; /** * Tests if full verification mode is enabled. * - * This expands to @c false when IEM_VERIFICATION_MODE is not defined and + * This expands to @c false when IEM_VERIFICATION_MODE_FULL is not defined and * should therefore cause the compiler to eliminate the verification branch * of an if statement. */ #ifdef IEM_VERIFICATION_MODE_FULL @@ -491,6 +547,22 @@ typedef IEMCPU *PIEMCPU; # define IEM_FULL_VERIFICATION_ENABLED(a_pIemCpu) (false) #endif +/** + * Tests if full verification mode is enabled again REM. + * + * This expands to @c false when IEM_VERIFICATION_MODE_FULL is not defined and + * should therefore cause the compiler to eliminate the verification branch + * of an if statement. */ +#ifdef IEM_VERIFICATION_MODE_FULL +# ifdef IEM_VERIFICATION_MODE_FULL_HM +# define IEM_FULL_VERIFICATION_REM_ENABLED(a_pIemCpu) (!(a_pIemCpu)->fNoRem && !HMIsEnabled(IEMCPU_TO_VM(a_pIemCpu))) +# else +# define IEM_FULL_VERIFICATION_REM_ENABLED(a_pIemCpu) (!(a_pIemCpu)->fNoRem) +# endif +#else +# define IEM_FULL_VERIFICATION_REM_ENABLED(a_pIemCpu) (false) +#endif + /** @def IEM_VERIFICATION_MODE * Indicates that one of the verfication modes are enabled. */ @@ -677,6 +749,16 @@ IEM_DECL_IMPL_DEF(void, iemAImpl_cmpxchg16b_locked,(PRTUINT128U *pu128Dst, PRTUI uint32_t *pEFlags)); /** @} */ +/** @name Memory ordering + * @{ */ +typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEMFENCE,(void)); +typedef FNIEMAIMPLMEMFENCE *PFNIEMAIMPLMEMFENCE; +IEM_DECL_IMPL_DEF(void, iemAImpl_mfence,(void)); +IEM_DECL_IMPL_DEF(void, iemAImpl_sfence,(void)); +IEM_DECL_IMPL_DEF(void, iemAImpl_lfence,(void)); +IEM_DECL_IMPL_DEF(void, iemAImpl_alt_mem_fence,(void)); +/** @} */ + /** @name Double precision shifts * @{ */ typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU16,(uint16_t *pu16Dst, uint16_t u16Src, uint8_t cShift, uint32_t *pEFlags)); @@ -834,6 +916,11 @@ IEM_DECL_IMPL_TYPE(void, iemAImpl_bswap_u32,(uint32_t *pu32Dst)); IEM_DECL_IMPL_TYPE(void, iemAImpl_bswap_u64,(uint64_t *pu64Dst)); /** @} */ +/** @name Misc. + * @{ */ +FNIEMAIMPLBINU16 iemAImpl_arpl; +/** @} */ + /** @name FPU operations taking a 32-bit float argument * @{ */ @@ -1014,7 +1101,62 @@ IEM_DECL_IMPL_DEF(void, iemAImpl_fist_r80_to_i64,(PCX86FXSTATE pFpuState, uint16 int64_t *pi64Val, PCRTFLOAT80U pr80Val)); IEM_DECL_IMPL_DEF(void, iemAImpl_fistt_r80_to_i64,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW, int64_t *pi32Val, PCRTFLOAT80U pr80Val)); -/** @} */ +/** @} */ + + +/** Temporary type representing a 256-bit vector register. */ +typedef struct {uint64_t au64[4]; } IEMVMM256; +/** Temporary type pointing to a 256-bit vector register. */ +typedef IEMVMM256 *PIEMVMM256; +/** Temporary type pointing to a const 256-bit vector register. */ +typedef IEMVMM256 *PCIEMVMM256; + + +/** @name Media (SSE/MMX/AVX) operations: full1 + full2 -> full1. + * @{ */ +typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF2U64,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, uint64_t const *pu64Src)); +typedef FNIEMAIMPLMEDIAF2U64 *PFNIEMAIMPLMEDIAF2U64; +typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF2U128,(PCX86FXSTATE pFpuState, uint128_t *pu128Dst, uint128_t const *pu128Src)); +typedef FNIEMAIMPLMEDIAF2U128 *PFNIEMAIMPLMEDIAF2U128; +FNIEMAIMPLMEDIAF2U64 iemAImpl_pxor_u64, iemAImpl_pcmpeqb_u64, iemAImpl_pcmpeqw_u64, iemAImpl_pcmpeqd_u64; +FNIEMAIMPLMEDIAF2U128 iemAImpl_pxor_u128, iemAImpl_pcmpeqb_u128, iemAImpl_pcmpeqw_u128, iemAImpl_pcmpeqd_u128; +/** @} */ + +/** @name Media (SSE/MMX/AVX) operations: lowhalf1 + lowhalf1 -> full1. + * @{ */ +typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF1L1U64,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, uint32_t const *pu32Src)); +typedef FNIEMAIMPLMEDIAF1L1U64 *PFNIEMAIMPLMEDIAF1L1U64; +typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF1L1U128,(PCX86FXSTATE pFpuState, uint128_t *pu128Dst, uint64_t const *pu64Src)); +typedef FNIEMAIMPLMEDIAF1L1U128 *PFNIEMAIMPLMEDIAF1L1U128; +FNIEMAIMPLMEDIAF1L1U64 iemAImpl_punpcklbw_u64, iemAImpl_punpcklwd_u64, iemAImpl_punpckldq_u64; +FNIEMAIMPLMEDIAF1L1U128 iemAImpl_punpcklbw_u128, iemAImpl_punpcklwd_u128, iemAImpl_punpckldq_u128, iemAImpl_punpcklqdq_u128; +/** @} */ + +/** @name Media (SSE/MMX/AVX) operations: hihalf1 + hihalf2 -> full1. + * @{ */ +typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF1H1U64,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, uint64_t const *pu64Src)); +typedef FNIEMAIMPLMEDIAF2U64 *PFNIEMAIMPLMEDIAF1H1U64; +typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAF1H1U128,(PCX86FXSTATE pFpuState, uint128_t *pu128Dst, uint128_t const *pu128Src)); +typedef FNIEMAIMPLMEDIAF2U128 *PFNIEMAIMPLMEDIAF1H1U128; +FNIEMAIMPLMEDIAF1H1U64 iemAImpl_punpckhbw_u64, iemAImpl_punpckhwd_u64, iemAImpl_punpckhdq_u64; +FNIEMAIMPLMEDIAF1H1U128 iemAImpl_punpckhbw_u128, iemAImpl_punpckhwd_u128, iemAImpl_punpckhdq_u128, iemAImpl_punpckhqdq_u128; +/** @} */ + +/** @name Media (SSE/MMX/AVX) operation: Packed Shuffle Stuff (evil) + * @{ */ +typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLMEDIAPSHUF,(PCX86FXSTATE pFpuState, uint128_t *pu128Dst, + uint128_t const *pu128Src, uint8_t bEvil)); +typedef FNIEMAIMPLMEDIAPSHUF *PFNIEMAIMPLMEDIAPSHUF; +FNIEMAIMPLMEDIAPSHUF iemAImpl_pshufhw, iemAImpl_pshuflw, iemAImpl_pshufd; +IEM_DECL_IMPL_DEF(void, iemAImpl_pshufw,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, uint64_t const *pu64Src, uint8_t bEvil)); +/** @} */ + +/** @name Media (SSE/MMX/AVX) operation: Move Byte Mask + * @{ */ +IEM_DECL_IMPL_DEF(void, iemAImpl_pmovmskb_u64,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, uint64_t const *pu64Src)); +IEM_DECL_IMPL_DEF(void, iemAImpl_pmovmskb_u128,(PCX86FXSTATE pFpuState, uint64_t *pu64Dst, uint128_t const *pu128Src)); +/** @} */ + /** @name Function tables. @@ -1094,6 +1236,43 @@ typedef struct IEMOPSHIFTDBLSIZES typedef IEMOPSHIFTDBLSIZES const *PCIEMOPSHIFTDBLSIZES; +/** + * Function table for media instruction taking two full sized media registers, + * optionally the 2nd being a memory reference (only modifying the first op.) + */ +typedef struct IEMOPMEDIAF2 +{ + PFNIEMAIMPLMEDIAF2U64 pfnU64; + PFNIEMAIMPLMEDIAF2U128 pfnU128; +} IEMOPMEDIAF2; +/** Pointer to a media operation function table for full sized ops. */ +typedef IEMOPMEDIAF2 const *PCIEMOPMEDIAF2; + +/** + * Function table for media instruction taking taking one full and one lower + * half media register. + */ +typedef struct IEMOPMEDIAF1L1 +{ + PFNIEMAIMPLMEDIAF1L1U64 pfnU64; + PFNIEMAIMPLMEDIAF1L1U128 pfnU128; +} IEMOPMEDIAF1L1; +/** Pointer to a media operation function table for lowhalf+lowhalf -> full. */ +typedef IEMOPMEDIAF1L1 const *PCIEMOPMEDIAF1L1; + +/** + * Function table for media instruction taking taking one full and one high half + * media register. + */ +typedef struct IEMOPMEDIAF1H1 +{ + PFNIEMAIMPLMEDIAF1H1U64 pfnU64; + PFNIEMAIMPLMEDIAF1H1U128 pfnU128; +} IEMOPMEDIAF1H1; +/** Pointer to a media operation function table for hihalf+hihalf -> full. */ +typedef IEMOPMEDIAF1H1 const *PCIEMOPMEDIAF1H1; + + /** @} */ |
