VirtualBox

Changeset 60415 in vbox


Ignore:
Timestamp:
Apr 11, 2016 8:51:07 AM (8 years ago)
Author:
vboxsync
Message:

IEM: Implemented main characteristics of 8086, 80186 and 80286.

Location:
trunk/src/VBox/VMM
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r60384 r60415  
    23062306
    23072307    uint32_t fEfl = IEMMISC_GET_EFL(pIemCpu, pCtx);
     2308#if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
     2309    AssertCompile(IEMTARGETCPU_8086 <= IEMTARGETCPU_186 && IEMTARGETCPU_V20 <= IEMTARGETCPU_186 && IEMTARGETCPU_286 > IEMTARGETCPU_186);
     2310    if (pIemCpu->uTargetCpu <= IEMTARGETCPU_186)
     2311        fEfl |= UINT16_C(0xf000);
     2312#endif
    23082313    pu16Frame[2] = (uint16_t)fEfl;
    23092314    pu16Frame[1] = (uint16_t)pCtx->cs.Sel;
     
    86148619    } while (0)
    86158620#define IEM_MC_SUB_GREG_U64(a_iGReg, a_u64Value)        *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) -= (a_u64Value)
     8621#define IEM_MC_SUB_LOCAL_U16(a_u16Value, a_u16Const)   do { (a_u16Value) -= a_u16Const; } while (0)
    86168622
    86178623#define IEM_MC_ADD_GREG_U8_TO_LOCAL(a_u8Value, a_iGReg)    do { (a_u8Value)  += iemGRegFetchU8( pIemCpu, (a_iGReg)); } while (0)
     
    86338639
    86348640#define IEM_MC_OR_LOCAL_U8(a_u8Local, a_u8Mask)         do { (a_u8Local)  |= (a_u8Mask);  } while (0)
     8641#define IEM_MC_OR_LOCAL_U16(a_u16Local, a_u16Mask)      do { (a_u16Local) |= (a_u16Mask); } while (0)
    86358642#define IEM_MC_OR_LOCAL_U32(a_u32Local, a_u32Mask)      do { (a_u32Local) |= (a_u32Mask); } while (0)
    86368643
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r60188 r60415  
    553553
    554554    /*
    555      * Ok, clear RF and VM and push the flags.
     555     * Ok, clear RF and VM, adjust for ancient CPUs, and push the flags.
    556556     */
    557557    fEfl &= ~(X86_EFL_RF | X86_EFL_VM);
     
    561561    {
    562562        case IEMMODE_16BIT:
     563#if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
     564            AssertCompile(IEMTARGETCPU_8086 <= IEMTARGETCPU_186 && IEMTARGETCPU_V20 <= IEMTARGETCPU_186 && IEMTARGETCPU_286 > IEMTARGETCPU_186);
     565            if (pIemCpu->uTargetCpu <= IEMTARGETCPU_186)
     566                fEfl |= UINT16_C(0xf000);
     567#endif
    563568            rcStrict = iemMemStackPushU16(pIemCpu, (uint16_t)fEfl);
    564569            break;
     
    669674                    return rcStrict;
    670675                fEflNew = u16Value | (fEflOld & UINT32_C(0xffff0000));
     676
     677#if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
     678                /*
     679                 * Ancient CPU adjustments:
     680                 *  - 8086, 80186, V20/30:
     681                 *    Fixed bits 15:12 bits are not kept correctly internally, mostly for
     682                 *    practical reasons (masking below).  We add them when pushing flags.
     683                 *  - 80286:
     684                 *    The NT and IOPL flags cannot be popped from real mode and are
     685                 *    therefore always zero (since a 286 can never exit from PM and
     686                 *    their initial value is zero).  This changed on a 386 and can
     687                 *    therefore be used to detect 286 or 386 CPU in real mode.
     688                 */
     689                if (   pIemCpu->uTargetCpu == IEMTARGETCPU_286
     690                    && !(pCtx->cr0 & X86_CR0_PE) )
     691                    fEflNew &= ~(X86_EFL_NT | X86_EFL_IOPL);
     692#endif
    671693                break;
    672694            }
     
    27652787        /** @todo The intel pseudo code does not indicate what happens to
    27662788         *        reserved flags. We just ignore them. */
     2789#if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
     2790        /* Ancient CPU adjustments: See iemCImpl_popf. */
     2791        if (pIemCpu->uTargetCpu == IEMTARGETCPU_286)
     2792            uNewFlags &= ~(X86_EFL_NT | X86_EFL_IOPL);
     2793#endif
    27672794    }
    27682795    /** @todo Check how this is supposed to work if sp=0xfffe. */
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r60384 r60415  
    976976                IEM_MC_LOCAL(uint16_t, u16Tmp);
    977977                IEM_MC_FETCH_CR0_U16(u16Tmp);
     978#if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
     979                if (pIemCpu->uTargetCpu == IEMTARGETCPU_286)
     980                    IEM_MC_OR_LOCAL_U16(u16Tmp, 0xfff0); /* Reserved bits observed all set on real hw. */
     981#endif
    978982                IEM_MC_STORE_GREG_U16((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u16Tmp);
    979983                IEM_MC_ADVANCE_RIP();
     
    79907994{
    79917995    IEMOP_MNEMONIC("push rSP");
     7996#if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
     7997    if (pIemCpu->uTargetCpu == IEMTARGETCPU_8086)
     7998    {
     7999        IEM_MC_BEGIN(0, 1);
     8000        IEM_MC_LOCAL(uint16_t, u16Value);
     8001        IEM_MC_FETCH_GREG_U16(u16Value, X86_GREG_xSP);
     8002        IEM_MC_SUB_LOCAL_U16(u16Value, 2);
     8003        IEM_MC_PUSH_U16(u16Value);
     8004        IEM_MC_ADVANCE_RIP();
     8005        IEM_MC_END();
     8006    }
     8007#endif
    79928008    return FNIEMOP_CALL_1(iemOpCommonPushGReg, X86_GREG_xSP);
    79938009}
  • trunk/src/VBox/VMM/VMMR3/IEMR3.cpp

    r60384 r60415  
    7272         * Host and guest CPU information.
    7373         */
    74 #if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
    75         pVCpu->iem.s.uTargetCpu = IEMTARGETCPU_CURRENT;
    76 #endif
    7774        if (idCpu == 0)
    7875        {
    7976            pVCpu->iem.s.enmCpuVendor             = CPUMGetGuestCpuVendor(pVM);
    8077            pVCpu->iem.s.enmHostCpuVendor         = CPUMGetHostCpuVendor(pVM);
     78#if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
     79            switch (pVM->cpum.ro.GuestFeatures.enmMicroarch)
     80            {
     81                case kCpumMicroarch_Intel_8086:     pVCpu->iem.s.uTargetCpu = IEMTARGETCPU_8086; break;
     82                case kCpumMicroarch_Intel_80186:    pVCpu->iem.s.uTargetCpu = IEMTARGETCPU_186; break;
     83                case kCpumMicroarch_Intel_80286:    pVCpu->iem.s.uTargetCpu = IEMTARGETCPU_286; break;
     84                case kCpumMicroarch_Intel_80386:    pVCpu->iem.s.uTargetCpu = IEMTARGETCPU_386; break;
     85                case kCpumMicroarch_Intel_80486:    pVCpu->iem.s.uTargetCpu = IEMTARGETCPU_486; break;
     86                case kCpumMicroarch_Intel_P5:       pVCpu->iem.s.uTargetCpu = IEMTARGETCPU_PENTIUM; break;
     87                case kCpumMicroarch_Intel_P6:       pVCpu->iem.s.uTargetCpu = IEMTARGETCPU_PPRO; break;
     88                case kCpumMicroarch_NEC_V20:        pVCpu->iem.s.uTargetCpu = IEMTARGETCPU_V20; break;
     89                case kCpumMicroarch_NEC_V30:        pVCpu->iem.s.uTargetCpu = IEMTARGETCPU_V20; break;
     90                default:                            pVCpu->iem.s.uTargetCpu = IEMTARGETCPU_CURRENT; break;
     91            }
     92#endif
    8193        }
    8294        else
     
    8496            pVCpu->iem.s.enmCpuVendor             = pVM->aCpus[0].iem.s.enmCpuVendor;
    8597            pVCpu->iem.s.enmHostCpuVendor         = pVM->aCpus[0].iem.s.enmHostCpuVendor;
     98#if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
     99            pVCpu->iem.s.uTargetCpu               = pVM->aCpus[0].iem.s.uTargetCpu;
     100#endif
    86101        }
    87102
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r60384 r60415  
    5151
    5252/** @def IEM_CFG_TARGET_CPU
    53  * The minimum target CPU for the IEM emulation (IEMTARGETCPU_XXX value). The
    54  * default is the a "current" CPU, i.e. something newer than the pentium pro. By
    55  * twiddling this value, you can make IEM try behave like older CPUs which is
    56  * useful when checking software that needs to run on real old CPUs.
     53 * The minimum target CPU for the IEM emulation (IEMTARGETCPU_XXX value).
     54 *
     55 * By default we allow this to be configured by the user via the
     56 * CPUM/GuestCpuName config string, but this comes at a slight cost during
     57 * decoding.  So, for applications of this code where there is no need to
     58 * be dynamic wrt target CPU, just modify this define.
    5759 */
    5860#if !defined(IEM_CFG_TARGET_CPU) || defined(DOXYGEN_RUNNING)
    59 # define IEM_CFG_TARGET_CPU IEMTARGETCPU_CURRENT
    60 /*# define IEM_CFG_TARGET_CPU IEMTARGETCPU_DYNAMIC*/
     61# define IEM_CFG_TARGET_CPU     IEMTARGETCPU_DYNAMIC
    6162#endif
    6263
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r60384 r60415  
    427427#define IEM_MC_SUB_GREG_U32(a_iGReg, a_u32Value)        do { CHK_CONST(uint32_t, a_u32Value); } while (0)
    428428#define IEM_MC_SUB_GREG_U64(a_iGReg, a_u64Value)        do { CHK_CONST(uint64_t, a_u64Value); } while (0)
     429#define IEM_MC_SUB_LOCAL_U16(a_u16Value, a_u16Const)    do { CHK_CONST(uint16_t, a_u16Const); } while (0)
    429430
    430431#define IEM_MC_AND_GREG_U8(a_iGReg, a_u8Value)          do { CHK_CONST(uint8_t,  a_u8Value);  } while (0)
     
    459460#define IEM_MC_AND_ARG_U64(a_u64Arg, a_u64Mask)         do { (a_u64Arg)   &= (a_u64Mask); CHK_TYPE(uint64_t, a_u64Arg);   CHK_CONST(uint64_t, a_u64Mask); } while (0)
    460461#define IEM_MC_OR_LOCAL_U8(a_u8Local, a_u8Mask)         do { (a_u8Local)  |= (a_u8Mask);  CHK_TYPE(uint8_t,  a_u8Local);  CHK_CONST(uint8_t,  a_u8Mask);  } while (0)
     462#define IEM_MC_OR_LOCAL_U16(a_u16Local, a_u16Mask)      do { (a_u16Local) |= (a_u16Mask); CHK_TYPE(uint16_t, a_u16Local); CHK_CONST(uint16_t, a_u16Mask); } while (0)
    461463#define IEM_MC_OR_LOCAL_U32(a_u32Local, a_u32Mask)      do { (a_u32Local) |= (a_u32Mask); CHK_TYPE(uint32_t, a_u32Local); CHK_CONST(uint32_t, a_u32Mask); } while (0)
    462464#define IEM_MC_SAR_LOCAL_S16(a_i16Local, a_cShift)      do { (a_i16Local) >>= (a_cShift); CHK_TYPE(int16_t, a_i16Local);  CHK_CONST(uint8_t,  a_cShift);  } while (0)
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