IEMInternal.h revision b3fd8221d2ea88f01eed81751e7bd8f4212c8080
/* $Id$ */
/** @file
* IEM - Internal header file.
*/
/*
* Copyright (C) 2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#ifndef ___IEMInternal_h
#define ___IEMInternal_h
/** @defgroup grp_iem_int Internals
* @ingroup grp_iem
* @internal
* @{
*/
/**
* Operand or addressing mode.
*/
typedef enum IEMMODE
{
IEMMODE_16BIT = 0,
} IEMMODE;
/**
* Extended operand mode that includes a representation of 8-bit.
*
* This is used for packing down modes when invoking some C instruction
* implementations.
*/
typedef enum IEMMODEX
{
} IEMMODEX;
#ifdef IEM_VERIFICATION_MODE
/**
* Verification event type.
*/
typedef enum IEMVERIFYEVENT
{
/** Checks if the event type is a RAM read or write. */
# define IEMVERIFYEVENT_IS_RAM(a_enmType) ((a_enmType) == IEMVERIFYEVENT_RAM_WRITE || (a_enmType) == IEMVERIFYEVENT_RAM_READ)
/**
* Verification event record.
*/
typedef struct IEMVERIFYEVTREC
{
/** Pointer to the next record in the list. */
struct IEMVERIFYEVTREC *pNext;
/** The event type. */
/** The event data. */
union
{
/** IEMVERIFYEVENT_IOPORT_READ */
struct
{
} IOPortRead;
/** IEMVERIFYEVENT_IOPORT_WRITE */
struct
{
} IOPortWrite;
/** IEMVERIFYEVENT_RAM_READ */
struct
{
} RamRead;
/** IEMVERIFYEVENT_RAM_WRITE */
struct
{
} RamWrite;
} u;
/** Pointer to an IEM event verification records. */
typedef IEMVERIFYEVTREC *PIEMVERIFYEVTREC;
#endif /* IEM_VERIFICATION_MODE */
/**
* The per-CPU IEM state.
*/
typedef struct IEMCPU
{
/** Pointer to the CPU context - ring-3 contex. */
/** Pointer to the CPU context - ring-0 contex. */
/** Pointer to the CPU context - raw-mode contex. */
/** Offset of the VMCPU structure relative to this structure (negative). */
/** Offset of the VM structure relative to this structure (negative). */
/** Whether to bypass access handlers or not. */
bool fByPassHandlers;
/** Explicit alignment padding. */
bool afAlignment0[4];
/** Exception / interrupt recursion depth. */
/** The current exception / interrupt . */
/** The CPL. */
/** The current CPU execution mode (CS). */
/** @name Statistics
* @{ */
/** The number of instructions we've executed. */
/** The number of potential exits. */
#ifdef IEM_VERIFICATION_MODE
/** The Number of I/O port reads that has been performed. */
/** The Number of I/O port writes that has been performed. */
/** Set if no comparison to REM is currently performed.
* This is used to skip past really slow bits. */
bool fNoRem;
/** Indicates that RAX and RDX differences should be ignored since RDTSC
* and RDTSCP are timing sensitive. */
bool fIgnoreRaxRdx;
bool afAlignment1[2];
/** Mask of undefined eflags.
* The verifier will any difference in these flags. */
/** The physical address corresponding to abOpcodes[0]. */
#endif
/** @} */
/** @name Decoder state.
* @{ */
/** The default addressing mode . */
/** The effective addressing mode . */
/** The default operand mode . */
/** The effective operand mode . */
/** The prefix mask (IEM_OP_PRF_XXX). */
/** The extra REX ModR/M register field bit (REX.R << 3). */
/** The extra REX ModR/M r/m field, SIB base and opcode reg bit
* (REX.B << 3). */
/** The extra REX SIB index field bit (REX.X << 3). */
/** The effective segment register (X86_SREG_XXX). */
/** The current offset into abOpcodes. */
/** The size of what has currently been fetched into abOpcodes. */
/** The opcode bytes. */
/** @}*/
/** Alignment padding for aMemMappings. */
/** The number of active guest memory mappings. */
/** The next unused mapping index. */
/** Records for tracking guest memory mappings. */
struct
{
/** The address of the mapped bytes. */
void *pv;
#endif
/** The access flags (IEM_ACCESS_XXX).
* IEM_ACCESS_INVALID if the entry is unused. */
#if HC_ARCH_BITS == 64
#endif
} aMemMappings[3];
/** Bounce buffer info.
* This runs in parallel to aMemMappings. */
struct
{
/** The physical address of the first byte. */
/** The physical address of the second page. */
/** The number of bytes in the first page. */
/** The number of bytes in the second page. */
/** Whether it's unassigned memory. */
bool fUnassigned;
/** Explicit alignment padding. */
bool afAlignment5[3];
} aMemBbMappings[3];
/** Bounce buffer storage.
* This runs in parallel to aMemMappings and aMemBbMappings. */
struct
{
} aBounceBuffers[3];
#ifdef IEM_VERIFICATION_MODE
/** The event verification records for what IEM did (LIFO). */
/** Insertion point for pIemEvtRecHead. */
/** The event verification records for what the other party did (FIFO). */
/** Insertion point for pOtherEvtRecHead. */
/** List of free event records. */
#endif
} IEMCPU;
/** Pointer to the per-CPU IEM state. */
/** Converts a IEMCPU pointer to a VMCPU pointer.
* @returns VMCPU pointer.
* @param a_pIemCpu The IEM per CPU instance data.
*/
/** Converts a IEMCPU pointer to a VM pointer.
* @returns VM pointer.
* @param a_pIemCpu The IEM per CPU instance data.
*/
/** @name IEM_ACCESS_XXX - Access details.
* @{ */
/** Used in aMemMappings to indicate that the entry is bounce buffered. */
/** Read+write data alias. */
/** Write data alias. */
/** Read data alias. */
/** Instruction fetch alias. */
/** Stack write alias. */
/** Stack read alias. */
/** Stack read+write alias. */
/** @} */
/** @name Prefix constants (IEMCPU::fPrefixes)
* @{ */
#define IEM_OP_PRF_SEG_CS RT_BIT_32(0)
/** @} */
/**
* Tests if verification mode is enabled.
*
* This expands to @c false when IEM_VERIFICATION_MODE is not defined and
* should therefore cause the compiler to eliminate the verification branch
* of an if statement. */
#ifdef IEM_VERIFICATION_MODE
#else
# define IEM_VERIFICATION_ENABLED(a_pIemCpu) (false)
#endif
/**
* Indicates to the verifier that the given flag set is undefined.
*
* Can be invoked again to add more flags.
*
* This is a NOOP if the verifier isn't compiled in.
*/
#ifdef IEM_VERIFICATION_MODE
# define IEMOP_VERIFICATION_UNDEFINED_EFLAGS(a_fEfl) do { pIemCpu->fUndefinedEFlags |= (a_fEfl); } while (0)
#else
# define IEMOP_VERIFICATION_UNDEFINED_EFLAGS(a_fEfl) do { } while (0)
#endif
/** @def IEM_DECL_IMPL_TYPE
* For typedef'ing an instruction implementation function.
*
* @param a_RetType The return type.
* @param a_Name The name of the type.
* @param a_ArgList The argument list enclosed in parentheses.
*/
/** @def IEM_DECL_IMPL_DEF
* For defining an instruction implementation function.
*
* @param a_RetType The return type.
* @param a_Name The name of the type.
* @param a_ArgList The argument list enclosed in parentheses.
*/
#if defined(__GNUC__) && defined(RT_ARCH_X86)
#else
#endif
/** @name Arithmetic assignment operations on bytes (binary).
* @{ */
typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU8, (uint8_t *pu8Dst, uint8_t u8Src, uint32_t *pEFlags));
typedef FNIEMAIMPLBINU8 *PFNIEMAIMPLBINU8;
/** @} */
/** @name Arithmetic assignment operations on words (binary).
* @{ */
typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU16, (uint16_t *pu16Dst, uint16_t u16Src, uint32_t *pEFlags));
typedef FNIEMAIMPLBINU16 *PFNIEMAIMPLBINU16;
/** @} */
/** @name Arithmetic assignment operations on double words (binary).
* @{ */
typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU32, (uint32_t *pu32Dst, uint32_t u32Src, uint32_t *pEFlags));
typedef FNIEMAIMPLBINU32 *PFNIEMAIMPLBINU32;
/** @} */
/** @name Arithmetic assignment operations on quad words (binary).
* @{ */
typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLBINU64, (uint64_t *pu64Dst, uint64_t u64Src, uint32_t *pEFlags));
typedef FNIEMAIMPLBINU64 *PFNIEMAIMPLBINU64;
/** @} */
/** @name Compare operations (thrown in with the binary ops).
* @{ */
/** @} */
/** @name Test operations (thrown in with the binary ops).
* @{ */
/** @} */
/** @name Bit operations operations (thrown in with the binary ops).
* @{ */
/** @} */
/** @name Exchange memory with register operations.
* @{ */
/** @} */
/** @name Double precision shifts
* @{ */
typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU16,(uint16_t *pu16Dst, uint16_t u16Src, uint8_t cShift, uint32_t *pEFlags));
typedef FNIEMAIMPLSHIFTDBLU16 *PFNIEMAIMPLSHIFTDBLU16;
typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU32,(uint32_t *pu32Dst, uint32_t u32Src, uint8_t cShift, uint32_t *pEFlags));
typedef FNIEMAIMPLSHIFTDBLU32 *PFNIEMAIMPLSHIFTDBLU32;
typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTDBLU64,(uint64_t *pu64Dst, uint64_t u64Src, uint8_t cShift, uint32_t *pEFlags));
typedef FNIEMAIMPLSHIFTDBLU64 *PFNIEMAIMPLSHIFTDBLU64;
/** @} */
/** @name Bit search operations (thrown in with the binary ops).
* @{ */
/** @} */
/** @name Signed multiplication operations (thrown in with the binary ops).
* @{ */
/** @} */
/** @name Arithmetic assignment operations on bytes (unary).
* @{ */
typedef FNIEMAIMPLUNARYU8 *PFNIEMAIMPLUNARYU8;
/** @} */
/** @name Arithmetic assignment operations on words (unary).
* @{ */
typedef FNIEMAIMPLUNARYU16 *PFNIEMAIMPLUNARYU16;
/** @} */
/** @name Arithmetic assignment operations on double words (unary).
* @{ */
typedef FNIEMAIMPLUNARYU32 *PFNIEMAIMPLUNARYU32;
/** @} */
/** @name Arithmetic assignment operations on quad words (unary).
* @{ */
typedef FNIEMAIMPLUNARYU64 *PFNIEMAIMPLUNARYU64;
/** @} */
/** @name Shift operations on bytes (Group 2).
* @{ */
typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU8,(uint8_t *pu8Dst, uint8_t cShift, uint32_t *pEFlags));
typedef FNIEMAIMPLSHIFTU8 *PFNIEMAIMPLSHIFTU8;
/** @} */
/** @name Shift operations on words (Group 2).
* @{ */
typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU16,(uint16_t *pu16Dst, uint8_t cShift, uint32_t *pEFlags));
typedef FNIEMAIMPLSHIFTU16 *PFNIEMAIMPLSHIFTU16;
/** @} */
/** @name Shift operations on double words (Group 2).
* @{ */
typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU32,(uint32_t *pu32Dst, uint8_t cShift, uint32_t *pEFlags));
typedef FNIEMAIMPLSHIFTU32 *PFNIEMAIMPLSHIFTU32;
/** @} */
/** @name Shift operations on words (Group 2).
* @{ */
typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLSHIFTU64,(uint64_t *pu64Dst, uint8_t cShift, uint32_t *pEFlags));
typedef FNIEMAIMPLSHIFTU64 *PFNIEMAIMPLSHIFTU64;
/** @} */
/** @name Multiplication and division operations.
* @{ */
typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU8,(uint16_t *pu16AX, uint8_t u8FactorDivisor, uint32_t *pEFlags));
typedef FNIEMAIMPLMULDIVU8 *PFNIEMAIMPLMULDIVU8;
typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU16,(uint16_t *pu16AX, uint16_t *pu16DX, uint16_t u16FactorDivisor, uint32_t *pEFlags));
typedef FNIEMAIMPLMULDIVU16 *PFNIEMAIMPLMULDIVU16;
typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU32,(uint32_t *pu32EAX, uint32_t *pu32EDX, uint32_t u32FactorDivisor, uint32_t *pEFlags));
typedef FNIEMAIMPLMULDIVU32 *PFNIEMAIMPLMULDIVU32;
typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU64,(uint64_t *pu64RAX, uint64_t *pu64RDX, uint64_t u64FactorDivisor, uint32_t *pEFlags));
typedef FNIEMAIMPLMULDIVU64 *PFNIEMAIMPLMULDIVU64;
/** @} */
/** @name Function tables.
* @{
*/
/**
* Function table for a binary operator providing implementation based on
* operand size.
*/
typedef struct IEMOPBINSIZES
{
/** Pointer to a binary operator function table. */
typedef IEMOPBINSIZES const *PCIEMOPBINSIZES;
/**
* Function table for a unary operator providing implementation based on
* operand size.
*/
typedef struct IEMOPUNARYSIZES
{
/** Pointer to a unary operator function table. */
typedef IEMOPUNARYSIZES const *PCIEMOPUNARYSIZES;
/**
* Function table for a shift operator providing implementation based on
* operand size.
*/
typedef struct IEMOPSHIFTSIZES
{
/** Pointer to a shift operator function table. */
typedef IEMOPSHIFTSIZES const *PCIEMOPSHIFTSIZES;
/**
* Function table for a multiplication or division operation.
*/
typedef struct IEMOPMULDIVSIZES
{
/** Pointer to a multiplication or division operation function table. */
typedef IEMOPMULDIVSIZES const *PCIEMOPMULDIVSIZES;
/**
* Function table for a double precision shift operator providing implementation
* based on operand size.
*/
typedef struct IEMOPSHIFTDBLSIZES
{
/** Pointer to a double precision shift function table. */
typedef IEMOPSHIFTDBLSIZES const *PCIEMOPSHIFTDBLSIZES;
/** @} */
/** @name C instruction implementations for anything slightly complicated.
* @{ */
/**
* For typedef'ing or declaring a C instruction implementation function taking
* no extra arguments.
*
* @param a_Name The name of the type.
*/
# define IEM_CIMPL_DECL_TYPE_0(a_Name) \
/**
* For defining a C instruction implementation function taking no extra
* arguments.
*
* @param a_Name The name of the function
*/
# define IEM_CIMPL_DEF_0(a_Name) \
/**
* For calling a C instruction implementation function taking no extra
* arguments.
*
* This special call macro adds default arguments to the call and allow us to
* change these later.
*
* @param a_fn The name of the function.
*/
/**
* For typedef'ing or declaring a C instruction implementation function taking
* one extra argument.
*
* @param a_Name The name of the type.
* @param a_Type0 The argument type.
* @param a_Arg0 The argument name.
*/
/**
* For defining a C instruction implementation function taking one extra
* argument.
*
* @param a_Name The name of the function
* @param a_Type0 The argument type.
* @param a_Arg0 The argument name.
*/
/**
* For calling a C instruction implementation function taking one extra
* argument.
*
* This special call macro adds default arguments to the call and allow us to
* change these later.
*
* @param a_fn The name of the function.
* @param a0 The name of the 1st argument.
*/
/**
* For typedef'ing or declaring a C instruction implementation function taking
* two extra arguments.
*
* @param a_Name The name of the type.
* @param a_Type0 The type of the 1st argument
* @param a_Arg0 The name of the 1st argument.
* @param a_Type1 The type of the 2nd argument.
* @param a_Arg1 The name of the 2nd argument.
*/
IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1))
/**
* For defining a C instruction implementation function taking two extra
* arguments.
*
* @param a_Name The name of the function.
* @param a_Type0 The type of the 1st argument
* @param a_Arg0 The name of the 1st argument.
* @param a_Type1 The type of the 2nd argument.
* @param a_Arg1 The name of the 2nd argument.
*/
IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1))
/**
* For calling a C instruction implementation function taking two extra
* arguments.
*
* This special call macro adds default arguments to the call and allow us to
* change these later.
*
* @param a_fn The name of the function.
* @param a0 The name of the 1st argument.
* @param a1 The name of the 2nd argument.
*/
/**
* For typedef'ing or declaring a C instruction implementation function taking
* three extra arguments.
*
* @param a_Name The name of the type.
* @param a_Type0 The type of the 1st argument
* @param a_Arg0 The name of the 1st argument.
* @param a_Type1 The type of the 2nd argument.
* @param a_Arg1 The name of the 2nd argument.
* @param a_Type2 The type of the 3rd argument.
* @param a_Arg2 The name of the 3rd argument.
*/
IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2))
/**
* For defining a C instruction implementation function taking three extra
* arguments.
*
* @param a_Name The name of the function.
* @param a_Type0 The type of the 1st argument
* @param a_Arg0 The name of the 1st argument.
* @param a_Type1 The type of the 2nd argument.
* @param a_Arg1 The name of the 2nd argument.
* @param a_Type2 The type of the 3rd argument.
* @param a_Arg2 The name of the 3rd argument.
*/
IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2))
/**
* For calling a C instruction implementation function taking three extra
* arguments.
*
* This special call macro adds default arguments to the call and allow us to
* change these later.
*
* @param a_fn The name of the function.
* @param a0 The name of the 1st argument.
* @param a1 The name of the 2nd argument.
* @param a2 The name of the 3rd argument.
*/
/**
* For typedef'ing or declaring a C instruction implementation function taking
* four extra arguments.
*
* @param a_Name The name of the type.
* @param a_Type0 The type of the 1st argument
* @param a_Arg0 The name of the 1st argument.
* @param a_Type1 The type of the 2nd argument.
* @param a_Arg1 The name of the 2nd argument.
* @param a_Type2 The type of the 3rd argument.
* @param a_Arg2 The name of the 3rd argument.
* @param a_Type3 The type of the 4th argument.
* @param a_Arg3 The name of the 4th argument.
*/
# define IEM_CIMPL_DECL_TYPE_4(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3) \
IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, a_Type3 a_Arg3))
/**
* For defining a C instruction implementation function taking four extra
* arguments.
*
* @param a_Name The name of the function.
* @param a_Type0 The type of the 1st argument
* @param a_Arg0 The name of the 1st argument.
* @param a_Type1 The type of the 2nd argument.
* @param a_Arg1 The name of the 2nd argument.
* @param a_Type2 The type of the 3rd argument.
* @param a_Arg2 The name of the 3rd argument.
* @param a_Type3 The type of the 4th argument.
* @param a_Arg3 The name of the 4th argument.
*/
# define IEM_CIMPL_DEF_4(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, aArg3) \
IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, a_Type3 a_Arg3))
/**
* For calling a C instruction implementation function taking four extra
* arguments.
*
* This special call macro adds default arguments to the call and allow us to
* change these later.
*
* @param a_fn The name of the function.
* @param a0 The name of the 1st argument.
* @param a1 The name of the 2nd argument.
* @param a2 The name of the 3rd argument.
* @param a3 The name of the 4th argument.
*/
/**
* For typedef'ing or declaring a C instruction implementation function taking
* five extra arguments.
*
* @param a_Name The name of the type.
* @param a_Type0 The type of the 1st argument
* @param a_Arg0 The name of the 1st argument.
* @param a_Type1 The type of the 2nd argument.
* @param a_Arg1 The name of the 2nd argument.
* @param a_Type2 The type of the 3rd argument.
* @param a_Arg2 The name of the 3rd argument.
* @param a_Type3 The type of the 4th argument.
* @param a_Arg3 The name of the 4th argument.
* @param a_Type4 The type of the 5th argument.
* @param a_Arg4 The name of the 5th argument.
*/
# define IEM_CIMPL_DECL_TYPE_5(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3, a_Type4, a_Arg4) \
/**
* For defining a C instruction implementation function taking five extra
* arguments.
*
* @param a_Name The name of the function.
* @param a_Type0 The type of the 1st argument
* @param a_Arg0 The name of the 1st argument.
* @param a_Type1 The type of the 2nd argument.
* @param a_Arg1 The name of the 2nd argument.
* @param a_Type2 The type of the 3rd argument.
* @param a_Arg2 The name of the 3rd argument.
* @param a_Type3 The type of the 4th argument.
* @param a_Arg3 The name of the 4th argument.
* @param a_Type4 The type of the 5th argument.
* @param a_Arg4 The name of the 5th argument.
*/
# define IEM_CIMPL_DEF_5(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3, a_Type4, a_Arg4) \
/**
* For calling a C instruction implementation function taking five extra
* arguments.
*
* This special call macro adds default arguments to the call and allow us to
* change these later.
*
* @param a_fn The name of the function.
* @param a0 The name of the 1st argument.
* @param a1 The name of the 2nd argument.
* @param a2 The name of the 3rd argument.
* @param a3 The name of the 4th argument.
* @param a4 The name of the 5th argument.
*/
# define IEM_CIMPL_CALL_5(a_fn, a0, a1, a2, a3, a4) a_fn(pIemCpu, cbInstr, (a0), (a1), (a2), (a3), (a4))
/** @} */
/** @} */
#endif