VirtualBox

Changeset 47307 in vbox


Ignore:
Timestamp:
Jul 22, 2013 2:34:36 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
87447
Message:

IEM: Implemented mfence, lfence, sfence.

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

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/src/VBox/VMM/Makefile.kmk

    r46814 r47307  
    703703endif
    704704
    705 ifneq ($(USERNAME),bird) # Not opts for me atm.
    706705#
    707706# Always optimize the interpreter.
     
    718717 VMMAll/IEMAll.cpp_CXXFLAGS += -fomit-frame-pointer # Omitting the frame pointer results in larger code, but it might be worth it. (esp addressing vs ebp?)
    719718endif
    720 endif # No optimizations for me atm.
    721719
    722720include $(FILE_KBUILD_SUB_FOOTER)
  • TabularUnified trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r47291 r47307  
    303303
    304304/**
     305 * Checks if an Intel CPUID feature is present in the host CPU.
     306 */
     307#define IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX_ON_HOST(a_fEdx)  \
     308    ( (a_fEdx) & pIemCpu->fHostCpuIdStdFeaturesEdx )
     309
     310/**
    305311 * Evaluates to true if we're presenting an Intel CPU to the guest.
    306312 */
    307 #define IEM_IS_GUEST_CPU_INTEL(a_pIemCpu)  (true) /** @todo determin this once and store it the CPU structure */
     313#define IEM_IS_GUEST_CPU_INTEL(a_pIemCpu)   ( (a_pIemCpu)->enmCpuVendor == CPUMCPUVENDOR_INTEL )
    308314
    309315/**
    310316 * Evaluates to true if we're presenting an AMD CPU to the guest.
    311317 */
    312 #define IEM_IS_GUEST_CPU_AMD(a_pIemCpu)    (false) /** @todo determin this once and store it the CPU structure */
     318#define IEM_IS_GUEST_CPU_AMD(a_pIemCpu)     ( (a_pIemCpu)->enmCpuVendor == CPUMCPUVENDOR_AMD )
    313319
    314320/**
     
    70127018    IEM_MC_RETURN_ON_FAILURE(iemOpHlpCalcRmEffAddr(pIemCpu, (bRm), (cbImm), &(a_GCPtrEff)))
    70137019
     7020#define IEM_MC_CALL_VOID_AIMPL_0(a_pfn)                   (a_pfn)()
    70147021#define IEM_MC_CALL_VOID_AIMPL_1(a_pfn, a0)               (a_pfn)((a0))
    70157022#define IEM_MC_CALL_VOID_AIMPL_2(a_pfn, a0, a1)           (a_pfn)((a0), (a1))
  • TabularUnified trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm

    r47173 r47307  
    10351035IEMIMPL_UNARY_OP neg, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
    10361036IEMIMPL_UNARY_OP not, 0, 0
     1037
     1038
     1039;;
     1040; Macro for implementing memory fence operation.
     1041;
     1042; No return value, no operands or anything.
     1043;
     1044; @param        1      The instruction.
     1045;
     1046%macro IEMIMPL_MEM_FENCE 1
     1047BEGINCODE
     1048BEGINPROC_FASTCALL iemAImpl_ %+ %1, 0
     1049        %1
     1050        ret
     1051ENDPROC iemAImpl_ %+ %1
     1052%endmacro
     1053
     1054IEMIMPL_MEM_FENCE lfence
     1055IEMIMPL_MEM_FENCE sfence
     1056IEMIMPL_MEM_FENCE mfence
     1057
     1058;;
     1059; Alternative for non-SSE2 host.
     1060;
     1061BEGINPROC_FASTCALL iemAImpl_alt_mem_fence, 0
     1062        push    xAX
     1063        xchg    xAX, [xSP]
     1064        add     xSP, xCB
     1065        ret
     1066ENDPROC iemAImpl_alt_mem_fence
    10371067
    10381068
  • TabularUnified trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r47292 r47307  
    13841384        /* The lock prefix can be used to encode CR8 accesses on some CPUs. */
    13851385        if (!IEM_IS_AMD_CPUID_FEATURE_PRESENT_ECX(X86_CPUID_AMD_FEATURE_ECX_CR8L))
    1386             return IEMOP_RAISE_INVALID_LOCK_PREFIX(); /* #UD takes precedence over #GP(), see test. */
     1386            return IEMOP_RAISE_INVALID_OPCODE(); /* #UD takes precedence over #GP(), see test. */
    13871387        iCrReg |= 8;
    13881388    }
     
    14301430        /* The lock prefix can be used to encode CR8 accesses on some CPUs. */
    14311431        if (!IEM_IS_AMD_CPUID_FEATURE_PRESENT_ECX(X86_CPUID_AMD_FEATURE_ECX_CR8L))
    1432             return IEMOP_RAISE_INVALID_LOCK_PREFIX(); /* #UD takes precedence over #GP(), see test. */
     1432            return IEMOP_RAISE_INVALID_OPCODE(); /* #UD takes precedence over #GP(), see test. */
    14331433        iCrReg |= 8;
    14341434    }
     
    38443844    IEMOP_HLP_NO_LOCK_PREFIX();
    38453845    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_FXSR))
    3846         return IEMOP_RAISE_INVALID_LOCK_PREFIX();
     3846        return IEMOP_RAISE_INVALID_OPCODE();
    38473847
    38483848    IEM_MC_BEGIN(3, 1);
     
    38633863    IEMOP_HLP_NO_LOCK_PREFIX();
    38643864    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_FXSR))
    3865         return IEMOP_RAISE_INVALID_LOCK_PREFIX();
     3865        return IEMOP_RAISE_INVALID_OPCODE();
    38663866
    38673867    IEM_MC_BEGIN(3, 1);
     
    38943894FNIEMOP_STUB_1(iemOp_Grp15_clflush,  uint8_t, bRm);
    38953895
     3896
    38963897/** Opcode 0x0f 0xae 11b/5. */
    3897 FNIEMOP_STUB_1(iemOp_Grp15_lfence,   uint8_t, bRm);
     3898FNIEMOP_DEF_1(iemOp_Grp15_lfence,   uint8_t, bRm)
     3899{
     3900    IEMOP_MNEMONIC("lfence");
     3901    IEMOP_HLP_NO_LOCK_PREFIX();
     3902    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_SSE2))
     3903        return IEMOP_RAISE_INVALID_OPCODE();
     3904
     3905    IEM_MC_BEGIN(0, 0);
     3906    if (IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX_ON_HOST(X86_CPUID_FEATURE_EDX_SSE2))
     3907        IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_lfence);
     3908    else
     3909        IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_alt_mem_fence);
     3910    IEM_MC_ADVANCE_RIP();
     3911    IEM_MC_END();
     3912    return VINF_SUCCESS;
     3913}
     3914
    38983915
    38993916/** Opcode 0x0f 0xae 11b/6. */
    3900 FNIEMOP_STUB_1(iemOp_Grp15_mfence,   uint8_t, bRm);
     3917FNIEMOP_DEF_1(iemOp_Grp15_mfence,   uint8_t, bRm)
     3918{
     3919    IEMOP_MNEMONIC("mfence");
     3920    IEMOP_HLP_NO_LOCK_PREFIX();
     3921    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_SSE2))
     3922        return IEMOP_RAISE_INVALID_OPCODE();
     3923
     3924    IEM_MC_BEGIN(0, 0);
     3925    if (IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX_ON_HOST(X86_CPUID_FEATURE_EDX_SSE2))
     3926        IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_mfence);
     3927    else
     3928        IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_alt_mem_fence);
     3929    IEM_MC_ADVANCE_RIP();
     3930    IEM_MC_END();
     3931    return VINF_SUCCESS;
     3932}
     3933
    39013934
    39023935/** Opcode 0x0f 0xae 11b/7. */
    3903 FNIEMOP_STUB_1(iemOp_Grp15_sfence,   uint8_t, bRm);
     3936FNIEMOP_DEF_1(iemOp_Grp15_sfence,   uint8_t, bRm)
     3937{
     3938    IEMOP_MNEMONIC("sfence");
     3939    IEMOP_HLP_NO_LOCK_PREFIX();
     3940    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_SSE2))
     3941        return IEMOP_RAISE_INVALID_OPCODE();
     3942
     3943    IEM_MC_BEGIN(0, 0);
     3944    if (IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX_ON_HOST(X86_CPUID_FEATURE_EDX_SSE2))
     3945        IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_sfence);
     3946    else
     3947        IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_alt_mem_fence);
     3948    IEM_MC_ADVANCE_RIP();
     3949    IEM_MC_END();
     3950    return VINF_SUCCESS;
     3951}
     3952
    39043953
    39053954/** Opcode 0xf3 0x0f 0xae 11b/0. */
     
    87368785    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
    87378786    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
    8738         return IEMOP_RAISE_INVALID_LOCK_PREFIX(); /* no register form */
     8787        return IEMOP_RAISE_INVALID_OPCODE(); /* no register form */
    87398788
    87408789    switch (pIemCpu->enmEffOpSize)
     
    1043910488        case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC("shr Eb,Ib"); break;
    1044010489        case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC("sar Eb,Ib"); break;
    10441         case 6: return IEMOP_RAISE_INVALID_LOCK_PREFIX();
     10490        case 6: return IEMOP_RAISE_INVALID_OPCODE();
    1044210491        IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe stupid */
    1044310492    }
     
    1049910548        case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC("shr Ev,Ib"); break;
    1050010549        case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC("sar Ev,Ib"); break;
    10501         case 6: return IEMOP_RAISE_INVALID_LOCK_PREFIX();
     10550        case 6: return IEMOP_RAISE_INVALID_OPCODE();
    1050210551        IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe stupid */
    1050310552    }
     
    1087010919        case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC("shr Eb,1"); break;
    1087110920        case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC("sar Eb,1"); break;
    10872         case 6: return IEMOP_RAISE_INVALID_LOCK_PREFIX();
     10921        case 6: return IEMOP_RAISE_INVALID_OPCODE();
    1087310922        IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe, well... */
    1087410923    }
     
    1092810977        case 5: pImpl = &g_iemAImpl_shr; IEMOP_MNEMONIC("shr Ev,1"); break;
    1092910978        case 7: pImpl = &g_iemAImpl_sar; IEMOP_MNEMONIC("sar Ev,1"); break;
    10930         case 6: return IEMOP_RAISE_INVALID_LOCK_PREFIX();
     10979        case 6: return IEMOP_RAISE_INVALID_OPCODE();
    1093110980        IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* gcc maybe, well... */
    1093210981    }
  • TabularUnified trunk/src/VBox/VMM/VMMR3/IEMR3.cpp

    r44529 r47307  
    2121#define LOG_GROUP LOG_GROUP_EM
    2222#include <VBox/vmm/iem.h>
     23#include <VBox/vmm/cpum.h>
    2324#include "IEMInternal.h"
    2425#include <VBox/vmm/vm.h>
    2526#include <VBox/err.h>
    2627
     28#include <iprt/asm-amd64-x86.h>
    2729#include <iprt/assert.h>
    2830
    2931
     32
     33/**
     34 * Initializes the interpreted execution manager.
     35 *
     36 * This must be called after CPUM as we're quering information from CPUM about
     37 * the guest and host CPUs.
     38 *
     39 * @returns VBox status code.
     40 * @param   pVM                 The cross context VM structure.
     41 */
    3042VMMR3DECL(int)      IEMR3Init(PVM pVM)
    3143{
     
    3951        pVCpu->iem.s.pCtxRC   = VM_RC_ADDR(pVM, pVCpu->iem.s.pCtxR3);
    4052
    41         STAMR3RegisterF(pVM, &pVCpu->iem.s.cInstructions,               STAMTYPE_U32,       STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     53        STAMR3RegisterF(pVM, &pVCpu->iem.s.cInstructions,             STAMTYPE_U32,       STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
    4254                        "Instructions interpreted",          "/IEM/CPU%u/cInstructions", idCpu);
    43         STAMR3RegisterF(pVM, &pVCpu->iem.s.cPotentialExits,             STAMTYPE_U32,       STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     55        STAMR3RegisterF(pVM, &pVCpu->iem.s.cPotentialExits,           STAMTYPE_U32,       STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
    4456                        "Potential exists",                  "/IEM/CPU%u/cPotentialExits", idCpu);
    45         STAMR3RegisterF(pVM, &pVCpu->iem.s.cRetAspectNotImplemented,    STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     57        STAMR3RegisterF(pVM, &pVCpu->iem.s.cRetAspectNotImplemented,  STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
    4658                        "VERR_IEM_ASPECT_NOT_IMPLEMENTED",   "/IEM/CPU%u/cRetAspectNotImplemented", idCpu);
    47         STAMR3RegisterF(pVM, &pVCpu->iem.s.cRetInstrNotImplemented,     STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     59        STAMR3RegisterF(pVM, &pVCpu->iem.s.cRetInstrNotImplemented,   STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
    4860                        "VERR_IEM_INSTR_NOT_IMPLEMENTED",    "/IEM/CPU%u/cRetInstrNotImplemented", idCpu);
    49         STAMR3RegisterF(pVM, &pVCpu->iem.s.cRetInfStatuses,             STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     61        STAMR3RegisterF(pVM, &pVCpu->iem.s.cRetInfStatuses,           STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
    5062                        "Informational statuses returned",   "/IEM/CPU%u/cRetInfStatuses", idCpu);
    51         STAMR3RegisterF(pVM, &pVCpu->iem.s.cRetErrStatuses,             STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     63        STAMR3RegisterF(pVM, &pVCpu->iem.s.cRetErrStatuses,           STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
    5264                        "Error statuses returned",           "/IEM/CPU%u/cRetErrStatuses", idCpu);
    53         STAMR3RegisterF(pVM, &pVCpu->iem.s.cbWritten,                   STAMTYPE_U32,       STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,
     65        STAMR3RegisterF(pVM, &pVCpu->iem.s.cbWritten,                 STAMTYPE_U32,       STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,
    5466                        "Approx bytes written",              "/IEM/CPU%u/cbWritten", idCpu);
     67
     68        /*
     69         * Host and guest CPU information.
     70         */
     71        if (idCpu == 0)
     72        {
     73            uint32_t uIgnored;
     74            CPUMGetGuestCpuId(pVCpu, 1, &uIgnored, &uIgnored,
     75                              &pVCpu->iem.s.fCpuIdStdFeaturesEcx, &pVCpu->iem.s.fCpuIdStdFeaturesEdx);
     76            pVCpu->iem.s.enmCpuVendor             = CPUMGetGuestCpuVendor(pVM);
     77
     78            ASMCpuId_ECX_EDX(1, &pVCpu->iem.s.fHostCpuIdStdFeaturesEcx, &pVCpu->iem.s.fHostCpuIdStdFeaturesEdx);
     79            pVCpu->iem.s.enmHostCpuVendor         = CPUMGetHostCpuVendor(pVM);
     80        }
     81        else
     82        {
     83            pVCpu->iem.s.fCpuIdStdFeaturesEcx     = pVM->aCpus[0].iem.s.fCpuIdStdFeaturesEcx;
     84            pVCpu->iem.s.fCpuIdStdFeaturesEdx     = pVM->aCpus[0].iem.s.fCpuIdStdFeaturesEdx;
     85            pVCpu->iem.s.enmCpuVendor             = pVM->aCpus[0].iem.s.enmCpuVendor;
     86            pVCpu->iem.s.fHostCpuIdStdFeaturesEcx = pVM->aCpus[0].iem.s.fHostCpuIdStdFeaturesEcx;
     87            pVCpu->iem.s.fHostCpuIdStdFeaturesEdx = pVM->aCpus[0].iem.s.fHostCpuIdStdFeaturesEdx;
     88            pVCpu->iem.s.enmHostCpuVendor         = pVM->aCpus[0].iem.s.enmHostCpuVendor;
     89        }
    5590    }
    5691    return VINF_SUCCESS;
  • TabularUnified trunk/src/VBox/VMM/include/IEMInternal.h

    r46168 r47307  
    379379    } aBounceBuffers[3];
    380380
     381    /** @name Target CPU information.
     382     * @{ */
     383    /** EDX value of CPUID(1).
     384     * @remarks Some bits are subject to change and must be queried dynamically. */
     385    uint32_t                fCpuIdStdFeaturesEdx;
     386    /** ECX value of CPUID(1).
     387     * @remarks Some bits are subject to change and must be queried dynamically. */
     388    uint32_t                fCpuIdStdFeaturesEcx;
     389    /** The CPU vendor. */
     390    CPUMCPUVENDOR           enmCpuVendor;
     391    /** @} */
     392
     393    /** @name Host CPU information.
     394     * @{ */
     395    /** EDX value of CPUID(1). */
     396    uint32_t                fHostCpuIdStdFeaturesEdx;
     397    /** ECX value of CPUID(1). */
     398    uint32_t                fHostCpuIdStdFeaturesEcx;
     399    /** The CPU vendor. */
     400    CPUMCPUVENDOR           enmHostCpuVendor;
     401    /** @} */
     402
    381403#ifdef IEM_VERIFICATION_MODE_FULL
    382404    /** The event verification records for what IEM did (LIFO). */
     
    680702/** @} */
    681703
     704/** @name Memory ordering
     705 * @{ */
     706typedef IEM_DECL_IMPL_DEF(void, FNIEMAIMPLMEMFENCE,(void));
     707typedef FNIEMAIMPLMEMFENCE *PFNIEMAIMPLMEMFENCE;
     708IEM_DECL_IMPL_DEF(void, iemAImpl_mfence,(void));
     709IEM_DECL_IMPL_DEF(void, iemAImpl_sfence,(void));
     710IEM_DECL_IMPL_DEF(void, iemAImpl_lfence,(void));
     711IEM_DECL_IMPL_DEF(void, iemAImpl_alt_mem_fence,(void));
     712/** @} */
     713
    682714/** @name Double precision shifts
    683715 * @{ */
  • TabularUnified trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r47284 r47307  
    134134#define IEM_IS_AMD_CPUID_FEATURES_ANY_PRESENT(a_fEdx, a_fEcx) (g_fRandom)
    135135#define IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(a_fEdx)      (g_fRandom)
     136#define IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX_ON_HOST(a_fEdx) (g_fRandom)
    136137#define IEM_IS_GUEST_CPU_AMD(a_pIemCpu)                     (g_fRandom)
    137138#define IEM_IS_GUEST_CPU_INTEL(a_pIemCpu)                   (g_fRandom)
     
    501502#define IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE(a_pvMem, a_fAccess, a_u16FSW)     do {} while (0)
    502503#define IEM_MC_CALC_RM_EFF_ADDR(a_GCPtrEff, bRm, cbImm)                 do { (a_GCPtrEff) = 0; CHK_GCPTR(a_GCPtrEff); } while (0)
     504#define IEM_MC_CALL_VOID_AIMPL_0(a_pfn)                                 do {} while (0)
    503505#define IEM_MC_CALL_VOID_AIMPL_1(a_pfn, a0)                             do {} while (0)
    504506#define IEM_MC_CALL_VOID_AIMPL_2(a_pfn, a0, a1)                         do {} while (0)
Note: See TracChangeset for help on using the changeset viewer.

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