VirtualBox

Changeset 47307 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Jul 22, 2013 2:34:36 PM (12 years ago)
Author:
vboxsync
Message:

IEM: Implemented mfence, lfence, sfence.

Location:
trunk/src/VBox/VMM/VMMAll
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • 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))
  • 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
  • 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    }
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