VirtualBox

Ignore:
Timestamp:
Jun 2, 2023 2:49:14 PM (19 months ago)
Author:
vboxsync
Message:

VMM/IEM: Refactored the enmCpuMode, uCpl, fBypassHandlers, fDisregardLock and fPendingInstruction* IEMCPU members into a single fExec member and associated IEM_F_XXX flag defines. Added more flags needed for recompiled execution. The fExec value is maintained as code is executed, so it does not need to be recalculated in the instruction loops. bugref:10369

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r99988 r100052  
    539539typedef struct IEMTB *PIEMTB;
    540540
     541/** @name IEM_F_XXX - Execution mode flags (IEMCPU::fExec, IEMTB::fFlags).
     542 *
     543 * These flags are set when entering IEM and adjusted as code is executed, such
     544 * that they will always contain the current values as instructions are
     545 * finished.
     546 *
     547 * In recompiled execution mode, (most of) these flags are included in the
     548 * translation block selection key and stored in IEMTB::fFlags alongside the
     549 * IEMTB_F_XXX flags.  The latter flags uses bits 31 thru 24, which are all zero
     550 * in IEMCPU::fExec.
     551 *
     552 * @{ */
     553/** Mode: The block target mode mask. */
     554#define IEM_F_MODE_MASK                     UINT32_C(0x0000001f)
     555/** Mode: The IEMMODE part of the IEMTB_F_MODE_MASK value. */
     556#define IEM_F_MODE_CPUMODE_MASK             UINT32_C(0x00000003)
     557/** X86 Mode: Bit used to indicating pre-386 CPU in 16-bit mode (for eliminating
     558 * conditional in EIP/IP updating), and flat wide open CS, SS DS, and ES in
     559 * 32-bit mode (for simplifying most memory accesses). */
     560#define IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK UINT32_C(0x00000004)
     561/** X86 Mode: Bit indicating protected mode. */
     562#define IEM_F_MODE_X86_PROT_MASK            UINT32_C(0x00000008)
     563/** X86 Mode: Bit used to indicate virtual 8086 mode (only 16-bit). */
     564#define IEM_F_MODE_X86_V86_MASK             UINT32_C(0x00000010)
     565
     566/** X86 Mode: 16-bit on 386 or later. */
     567#define IEM_F_MODE_X86_16BIT                UINT32_C(0x00000000)
     568/** X86 Mode: 80286, 80186 and 8086/88 targetting blocks (EIP update opt). */
     569#define IEM_F_MODE_X86_16BIT_PRE_386        UINT32_C(0x00000004)
     570/** X86 Mode: 16-bit protected mode on 386 or later. */
     571#define IEM_F_MODE_X86_16BIT_PROT           UINT32_C(0x00000008)
     572/** X86 Mode: 16-bit protected mode on 386 or later. */
     573#define IEM_F_MODE_X86_16BIT_PROT_PRE_386   UINT32_C(0x0000000c)
     574/** X86 Mode: 16-bit virtual 8086 protected mode (on 386 or later). */
     575#define IEM_F_MODE_X86_16BIT_PROT_V86       UINT32_C(0x00000018)
     576
     577/** X86 Mode: 32-bit on 386 or later. */
     578#define IEM_F_MODE_X86_32BIT                UINT32_C(0x00000001)
     579/** X86 Mode: 32-bit mode with wide open flat CS, SS, DS and ES. */
     580#define IEM_F_MODE_X86_32BIT_FLAT           UINT32_C(0x00000005)
     581/** X86 Mode: 32-bit protected mode. */
     582#define IEM_F_MODE_X86_32BIT_PROT           UINT32_C(0x00000009)
     583/** X86 Mode: 32-bit protected mode with wide open flat CS, SS, DS and ES. */
     584#define IEM_F_MODE_X86_32BIT_PROT_FLAT      UINT32_C(0x0000000d)
     585
     586/** X86 Mode: 64-bit (includes protected, but not the flat bit). */
     587#define IEM_F_MODE_X86_64BIT                UINT32_C(0x0000000a)
     588
     589
     590/** Bypass access handlers when set. */
     591#define IEM_F_BYPASS_HANDLERS               UINT32_C(0x00010000)
     592/** Have pending hardware instruction breakpoints.   */
     593#define IEM_F_PENDING_BRK_INSTR             UINT32_C(0x00020000)
     594/** Have pending hardware data breakpoints.   */
     595#define IEM_F_PENDING_BRK_DATA              UINT32_C(0x00040000)
     596
     597/** X86: Have pending hardware I/O breakpoints. */
     598#define IEM_F_PENDING_BRK_X86_IO            UINT32_C(0x00000400)
     599/** X86: Disregard the lock prefix (implied or not) when set. */
     600#define IEM_F_X86_DISREGARD_LOCK            UINT32_C(0x00000800)
     601
     602/** Pending breakpoint mask (what iemCalcExecDbgFlags works out). */
     603#define IEM_F_PENDING_BRK_MASK              (IEM_F_PENDING_BRK_INSTR | IEM_F_PENDING_BRK_DATA | IEM_F_PENDING_BRK_X86_IO)
     604
     605/** Caller configurable options. */
     606#define IEM_F_USER_OPTS                     (IEM_F_BYPASS_HANDLERS | IEM_F_X86_DISREGARD_LOCK)
     607
     608/** X86: The current protection level (CPL) shift factor.   */
     609#define IEM_F_X86_CPL_SHIFT                 8
     610/** X86: The current protection level (CPL) mask. */
     611#define IEM_F_X86_CPL_MASK                  UINT32_C(0x00000300)
     612/** X86: The current protection level (CPL) shifted mask. */
     613#define IEM_F_X86_CPL_SMASK                 UINT32_C(0x00000003)
     614
     615/** X86 execution context.
     616 * The IEM_F_X86_CTX_XXX values are individual flags that can be combined (with
     617 * the exception of IEM_F_X86_CTX_NORMAL).  This allows running VMs from SMM
     618 * mode. */
     619#define IEM_F_X86_CTX_MASK                  UINT32_C(0x0000f000)
     620/** X86 context: Plain regular execution context. */
     621#define IEM_F_X86_CTX_NORMAL                UINT32_C(0x00000000)
     622/** X86 context: VT-x enabled. */
     623#define IEM_F_X86_CTX_VMX                   UINT32_C(0x00001000)
     624/** X86 context: AMD-V enabled. */
     625#define IEM_F_X86_CTX_SVM                   UINT32_C(0x00002000)
     626/** X86 context: In AMD-V or VT-x guest mode. */
     627#define IEM_F_X86_CTX_IN_GUEST              UINT32_C(0x00004000)
     628/** X86 context: System management mode (SMM). */
     629#define IEM_F_X86_CTX_SMM                   UINT32_C(0x00008000)
     630
     631/** @todo Add TF+RF+INHIBIT indicator(s), so we can eliminate the conditional in
     632 * iemRegFinishClearingRF() most for most situations (CPUMCTX_DBG_HIT_DRX_MASK
     633 * and CPUMCTX_DBG_DBGF_MASK are covered by the IEM_F_PENDING_BRK_XXX bits
     634 * alread). */
     635
     636/** @todo Add TF+RF+INHIBIT indicator(s), so we can eliminate the conditional in
     637 *        iemRegFinishClearingRF() most for most situations
     638 *        (CPUMCTX_DBG_HIT_DRX_MASK and CPUMCTX_DBG_DBGF_MASK are covered by
     639 *        the IEM_F_PENDING_BRK_XXX bits alread). */
     640
     641/** @} */
     642
     643
     644/** @name IEMTB_F_XXX - Translation block flags (IEMTB::fFlags).
     645 *
     646 * Extends the IEM_F_XXX flags (subject to IEMTB_F_IEM_F_MASK) to make up the
     647 * translation block flags.  The combined flag mask (subject to
     648 * IEMTB_F_KEY_MASK) is used as part of the lookup key for translation blocks.
     649 *
     650 * @{ */
     651/** Mask of IEM_F_XXX flags included in IEMTB_F_XXX. */
     652#define IEMTB_F_IEM_F_MASK              UINT32_C(0x00ffffff)
     653
     654/** Type: The block type mask. */
     655#define IEMTB_F_TYPE_MASK               UINT32_C(0x03000000)
     656/** Type: Purly threaded recompiler (via tables). */
     657#define IEMTB_F_TYPE_THREADED           UINT32_C(0x01000000)
     658/** Type: Native recompilation.  */
     659#define IEMTB_F_TYPE_NATIVE             UINT32_C(0x02000000)
     660
     661/** State mask.  */
     662#define IEMTB_F_STATE_MASK              UINT32_C(0x0c000000)
     663/** State: Compiling. */
     664#define IEMTB_F_STATE_COMPILING         UINT32_C(0x04000000)
     665/** State: Ready.  */
     666#define IEMTB_F_STATE_READY             UINT32_C(0x08000000)
     667/** State: Obsolete, can be deleted when we're sure it's not used any longer. */
     668#define IEMTB_F_STATE_OBSOLETE          UINT32_C(0x0c000000)
     669
     670/** Mask of the IEMTB_F_XXX flags that are part of the TB lookup key.
     671 * @note We don't   */
     672#define IEMTB_F_KEY_MASK                ((UINT32_C(0xffffffff) & ~IEM_F_X86_CTX_MASK) | IEM_F_X86_CTX_SMM)
     673/** @} */
     674
     675AssertCompile( (IEM_F_MODE_X86_16BIT              & IEM_F_MODE_CPUMODE_MASK) == IEMMODE_16BIT);
     676AssertCompile(!(IEM_F_MODE_X86_16BIT              & IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK));
     677AssertCompile(!(IEM_F_MODE_X86_16BIT              & IEM_F_MODE_X86_PROT_MASK));
     678AssertCompile(!(IEM_F_MODE_X86_16BIT              & IEM_F_MODE_X86_V86_MASK));
     679AssertCompile( (IEM_F_MODE_X86_16BIT_PRE_386      & IEM_F_MODE_CPUMODE_MASK) == IEMMODE_16BIT);
     680AssertCompile(  IEM_F_MODE_X86_16BIT_PRE_386      & IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK);
     681AssertCompile(!(IEM_F_MODE_X86_16BIT_PRE_386      & IEM_F_MODE_X86_PROT_MASK));
     682AssertCompile(!(IEM_F_MODE_X86_16BIT_PRE_386      & IEM_F_MODE_X86_V86_MASK));
     683AssertCompile( (IEM_F_MODE_X86_16BIT_PROT         & IEM_F_MODE_CPUMODE_MASK) == IEMMODE_16BIT);
     684AssertCompile(!(IEM_F_MODE_X86_16BIT_PROT         & IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK));
     685AssertCompile(  IEM_F_MODE_X86_16BIT_PROT         & IEM_F_MODE_X86_PROT_MASK);
     686AssertCompile(!(IEM_F_MODE_X86_16BIT_PROT         & IEM_F_MODE_X86_V86_MASK));
     687AssertCompile( (IEM_F_MODE_X86_16BIT_PROT_PRE_386 & IEM_F_MODE_CPUMODE_MASK) == IEMMODE_16BIT);
     688AssertCompile(  IEM_F_MODE_X86_16BIT_PROT_PRE_386 & IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK);
     689AssertCompile(  IEM_F_MODE_X86_16BIT_PROT_PRE_386 & IEM_F_MODE_X86_PROT_MASK);
     690AssertCompile(!(IEM_F_MODE_X86_16BIT_PROT_PRE_386 & IEM_F_MODE_X86_V86_MASK));
     691AssertCompile(  IEM_F_MODE_X86_16BIT_PROT_V86     & IEM_F_MODE_X86_PROT_MASK);
     692AssertCompile(!(IEM_F_MODE_X86_16BIT_PROT_V86     & IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK));
     693AssertCompile(  IEM_F_MODE_X86_16BIT_PROT_V86     & IEM_F_MODE_X86_V86_MASK);
     694
     695AssertCompile( (IEM_F_MODE_X86_32BIT              & IEM_F_MODE_CPUMODE_MASK) == IEMMODE_32BIT);
     696AssertCompile(!(IEM_F_MODE_X86_32BIT              & IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK));
     697AssertCompile(!(IEM_F_MODE_X86_32BIT              & IEM_F_MODE_X86_PROT_MASK));
     698AssertCompile( (IEM_F_MODE_X86_32BIT_FLAT         & IEM_F_MODE_CPUMODE_MASK) == IEMMODE_32BIT);
     699AssertCompile(  IEM_F_MODE_X86_32BIT_FLAT         & IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK);
     700AssertCompile(!(IEM_F_MODE_X86_32BIT_FLAT         & IEM_F_MODE_X86_PROT_MASK));
     701AssertCompile( (IEM_F_MODE_X86_32BIT_PROT         & IEM_F_MODE_CPUMODE_MASK) == IEMMODE_32BIT);
     702AssertCompile(!(IEM_F_MODE_X86_32BIT_PROT         & IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK));
     703AssertCompile(  IEM_F_MODE_X86_32BIT_PROT         & IEM_F_MODE_X86_PROT_MASK);
     704AssertCompile( (IEM_F_MODE_X86_32BIT_PROT_FLAT    & IEM_F_MODE_CPUMODE_MASK) == IEMMODE_32BIT);
     705AssertCompile(  IEM_F_MODE_X86_32BIT_PROT_FLAT    & IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK);
     706AssertCompile(  IEM_F_MODE_X86_32BIT_PROT_FLAT    & IEM_F_MODE_X86_PROT_MASK);
     707
     708AssertCompile( (IEM_F_MODE_X86_64BIT              & IEM_F_MODE_CPUMODE_MASK) == IEMMODE_64BIT);
     709AssertCompile(  IEM_F_MODE_X86_64BIT              & IEM_F_MODE_X86_PROT_MASK);
     710AssertCompile(!(IEM_F_MODE_X86_64BIT              & IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK));
     711
    541712
    542713/**
     
    551722     * source of these codes will perform appropriate sanity checks. */
    552723    int32_t                 rcPassUp;                                                                       /* 0x00 */
    553 
    554     /** The current CPU execution mode (CS). */
    555     IEMMODE                 enmCpuMode;                                                                     /* 0x04 */
    556     /** The CPL. */
    557     uint8_t                 uCpl;                                                                           /* 0x05 */
    558 
    559     /** Whether to bypass access handlers or not. */
    560     bool                    fBypassHandlers : 1;                                                            /* 0x06.0 */
    561     /** Whether to disregard the lock prefix (implied or not). */
    562     bool                    fDisregardLock : 1;                                                             /* 0x06.1 */
    563     /** Whether there are pending hardware instruction breakpoints. */
    564     bool                    fPendingInstructionBreakpoints : 1;                                             /* 0x06.2 */
    565     /** Whether there are pending hardware data breakpoints. */
    566     bool                    fPendingDataBreakpoints : 1;                                                    /* 0x06.3 */
    567     /** Whether there are pending hardware I/O breakpoints. */
    568     bool                    fPendingIoBreakpoints : 1;                                                      /* 0x06.4 */
    569 
    570     /* Unused/padding */
    571     bool                    fUnused;                                                                        /* 0x07 */
     724    /** Execution flag, IEM_F_XXX. */
     725    uint32_t                fExec;                                                                          /* 0x04 */
    572726
    573727    /** @name Decoder state.
     
    35153669
    35163670/**
     3671 * Gets the CPU mode (from fExec) as a IEMMODE value.
     3672 *
     3673 * @returns IEMMODE
     3674 * @param   a_pVCpu         The cross context virtual CPU structure of the calling thread.
     3675 */
     3676#define IEM_GET_CPU_MODE(a_pVCpu)           ((a_pVCpu)->iem.s.fExec & IEM_F_MODE_CPUMODE_MASK)
     3677
     3678/**
    35173679 * Check if we're currently executing in real or virtual 8086 mode.
    3518  *
    3519  * @returns @c true if it is, @c false if not.
    3520  * @param   a_pVCpu         The IEM state of the current CPU.
    3521  */
    3522 #define IEM_IS_REAL_OR_V86_MODE(a_pVCpu)    (CPUMIsGuestInRealOrV86ModeEx(IEM_GET_CTX(a_pVCpu)))
    3523 
    3524 /**
    3525  * Check if we're currently executing in virtual 8086 mode.
    35263680 *
    35273681 * @returns @c true if it is, @c false if not.
    35283682 * @param   a_pVCpu         The cross context virtual CPU structure of the calling thread.
    35293683 */
    3530 #define IEM_IS_V86_MODE(a_pVCpu)            (CPUMIsGuestInV86ModeEx(IEM_GET_CTX(a_pVCpu)))
    3531 
    3532 /**
    3533  * Check if we're currently executing in long mode.
     3684#define IEM_IS_REAL_OR_V86_MODE(a_pVCpu)    (CPUMIsGuestInRealOrV86ModeEx(IEM_GET_CTX(a_pVCpu)))
     3685
     3686/**
     3687 * Check if we're currently executing in virtual 8086 mode.
    35343688 *
    35353689 * @returns @c true if it is, @c false if not.
    35363690 * @param   a_pVCpu         The cross context virtual CPU structure of the calling thread.
    35373691 */
    3538 #define IEM_IS_LONG_MODE(a_pVCpu)           (CPUMIsGuestInLongModeEx(IEM_GET_CTX(a_pVCpu)))
    3539 
    3540 /**
    3541  * Check if we're currently executing in a 64-bit code segment.
     3692#define IEM_IS_V86_MODE(a_pVCpu)            (CPUMIsGuestInV86ModeEx(IEM_GET_CTX(a_pVCpu)))
     3693
     3694/**
     3695 * Check if we're currently executing in long mode.
    35423696 *
    35433697 * @returns @c true if it is, @c false if not.
    35443698 * @param   a_pVCpu         The cross context virtual CPU structure of the calling thread.
    35453699 */
    3546 #define IEM_IS_64BIT_CODE(a_pVCpu)          (CPUMIsGuestIn64BitCodeEx(IEM_GET_CTX(a_pVCpu)))
    3547 
    3548 /**
    3549  * Check if we're currently executing in real mode.
     3700#define IEM_IS_LONG_MODE(a_pVCpu)           (CPUMIsGuestInLongModeEx(IEM_GET_CTX(a_pVCpu)))
     3701
     3702/**
     3703 * Check if we're currently executing in a 16-bit code segment.
    35503704 *
    35513705 * @returns @c true if it is, @c false if not.
    35523706 * @param   a_pVCpu         The cross context virtual CPU structure of the calling thread.
    35533707 */
     3708#define IEM_IS_16BIT_CODE(a_pVCpu)          (IEM_GET_CPU_MODE(a_pVCpu) == IEMMODE_16BIT)
     3709
     3710/**
     3711 * Check if we're currently executing in a 32-bit code segment.
     3712 *
     3713 * @returns @c true if it is, @c false if not.
     3714 * @param   a_pVCpu         The cross context virtual CPU structure of the calling thread.
     3715 */
     3716#define IEM_IS_32BIT_CODE(a_pVCpu)          (IEM_GET_CPU_MODE(a_pVCpu) == IEMMODE_32BIT)
     3717
     3718/**
     3719 * Check if we're currently executing in a 64-bit code segment.
     3720 *
     3721 * @returns @c true if it is, @c false if not.
     3722 * @param   a_pVCpu         The cross context virtual CPU structure of the calling thread.
     3723 */
     3724#define IEM_IS_64BIT_CODE(a_pVCpu)          (IEM_GET_CPU_MODE(a_pVCpu) == IEMMODE_64BIT)
     3725
     3726/**
     3727 * Check if we're currently executing in real mode.
     3728 *
     3729 * @returns @c true if it is, @c false if not.
     3730 * @param   a_pVCpu         The cross context virtual CPU structure of the calling thread.
     3731 */
    35543732#define IEM_IS_REAL_MODE(a_pVCpu)           (CPUMIsGuestInRealModeEx(IEM_GET_CTX(a_pVCpu)))
     3733
     3734/**
     3735 * Gets the current protection level (CPL).
     3736 *
     3737 * @returns 0..3
     3738 * @param   a_pVCpu         The cross context virtual CPU structure of the calling thread.
     3739 */
     3740#define IEM_GET_CPL(a_pVCpu)                (((a_pVCpu)->iem.s.fExec >> IEM_F_X86_CPL_SHIFT) & IEM_F_X86_CPL_SMASK)
     3741
     3742/**
     3743 * Sets the current protection level (CPL).
     3744 *
     3745 * @param   a_pVCpu         The cross context virtual CPU structure of the calling thread.
     3746 */
     3747#define IEM_SET_CPL(a_pVCpu, a_uCpl) \
     3748    do { (a_pVCpu)->iem.s.fExec = ((a_pVCpu)->iem.s.fExec & ~IEM_F_X86_CPL_MASK) | ((a_uCpl) << IEM_F_X86_CPL_SHIFT); } while (0)
    35553749
    35563750/**
     
    36383832 */
    36393833#define IEM_GET_EFFECTIVE_VVVV(a_pVCpu) \
    3640     ((a_pVCpu)->iem.s.enmCpuMode == IEMMODE_64BIT ? (a_pVCpu)->iem.s.uVex3rdReg : (a_pVCpu)->iem.s.uVex3rdReg & 7)
     3834    (IEM_IS_64BIT_CODE(a_pVCpu) ? (a_pVCpu)->iem.s.uVex3rdReg : (a_pVCpu)->iem.s.uVex3rdReg & 7)
    36413835
    36423836
     
    38664060/** @} */
    38674061
    3868 void                    iemInitPendingBreakpointsSlow(PVMCPUCC pVCpu);
     4062uint32_t                iemCalcExecDbgFlagsSlow(PVMCPUCC pVCpu);
    38694063
    38704064
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette