VirtualBox

Changeset 40246 in vbox


Ignore:
Timestamp:
Feb 24, 2012 12:21:49 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
76457
Message:

IEM: Conditional FPU move instructions (FCMOV*).

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

Legend:

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

    r40242 r40246  
    39673967        *ppRef0 = &pCtx->fpu.aRegs[iStReg0].r80;
    39683968        *ppRef1 = &pCtx->fpu.aRegs[iStReg1].r80;
     3969        return VINF_SUCCESS;
     3970    }
     3971    return VERR_NOT_FOUND;
     3972}
     3973
     3974
     3975static int iemFpu2StRegsNotEmptyRefFirst(PIEMCPU pIemCpu, uint8_t iStReg0, PCRTFLOAT80U *ppRef0, uint8_t iStReg1)
     3976{
     3977    PCPUMCTX pCtx  = pIemCpu->CTX_SUFF(pCtx);
     3978    uint16_t iTop  = X86_FSW_TOP_GET(pCtx->fpu.FSW);
     3979    uint16_t iReg0 = (iTop + iStReg0) & X86_FSW_TOP_SMASK;
     3980    uint16_t iReg1 = (iTop + iStReg1) & X86_FSW_TOP_SMASK;
     3981    if ((pCtx->fpu.FTW & (RT_BIT(iReg0) | RT_BIT(iReg1))) == (RT_BIT(iReg0) | RT_BIT(iReg1)))
     3982    {
     3983        *ppRef0 = &pCtx->fpu.aRegs[iStReg0].r80;
    39693984        return VINF_SUCCESS;
    39703985    }
     
    62916306/** Updates the FSW, FOP, FPUIP, and FPUCS. */
    62926307#define IEM_MC_UPDATE_FSW(a_u16FSW) \
     6308    iemFpuUpdateFSW(pIemCpu, a_u16FSW)
     6309/** Updates the FSW with a constant value as well as FOP, FPUIP, and FPUCS. */
     6310#define IEM_MC_UPDATE_FSW_CONST(a_u16FSW) \
    62936311    iemFpuUpdateFSW(pIemCpu, a_u16FSW)
    62946312/** Updates the FSW, FOP, FPUIP, FPUCS, FPUDP, and FPUDS. */
     
    63866404#define IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(a_pr80Dst0, a_iSt0, a_pr80Dst1, a_iSt1) \
    63876405    if (iemFpu2StRegsNotEmptyRef(pIemCpu, (a_iSt0), &(a_pr80Dst0), (a_iSt1), &(a_pr80Dst1)) == VINF_SUCCESS) {
     6406#define IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(a_pr80Dst0, a_iSt0, a_iSt1) \
     6407    if (iemFpu2StRegsNotEmptyRefFirst(pIemCpu, (a_iSt0), &(a_pr80Dst0), (a_iSt1)) == VINF_SUCCESS) {
    63886408
    63896409#define IEM_MC_ELSE()                                   } else {
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r40244 r40246  
    1132411324
    1132511325/** Opcode 0xda 11/0. */
    11326 FNIEMOP_STUB_1(iemOp_fcmovb_stN,  uint8_t, bRm);
     11326FNIEMOP_DEF_1(iemOp_fcmovb_stN,  uint8_t, bRm)
     11327{
     11328    IEMOP_MNEMONIC("fcmovb st0,stN");
     11329    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     11330
     11331    IEM_MC_BEGIN(0, 2);
     11332    IEM_MC_LOCAL(IEMFPURESULT,      FpuRes);
     11333    IEM_MC_LOCAL(PCRTFLOAT80U,      pr80ValueN);
     11334
     11335    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     11336    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     11337
     11338    IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
     11339        IEM_MC_IF_EFL_BIT_SET(X86_EFL_CF)
     11340            IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
     11341        IEM_MC_ENDIF();
     11342        IEM_MC_UPDATE_FPU_OPCODE_IP();
     11343    IEM_MC_ELSE()
     11344        IEM_MC_FPU_STACK_UNDERFLOW(0);
     11345    IEM_MC_ENDIF();
     11346    IEM_MC_ADVANCE_RIP();
     11347
     11348    IEM_MC_END();
     11349    return VINF_SUCCESS;
     11350}
     11351
     11352
    1132711353/** Opcode 0xda 11/1. */
    11328 FNIEMOP_STUB_1(iemOp_fcmove_stN,  uint8_t, bRm);
     11354FNIEMOP_DEF_1(iemOp_fcmove_stN,  uint8_t, bRm)
     11355{
     11356    IEMOP_MNEMONIC("fcmove st0,stN");
     11357    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     11358
     11359    IEM_MC_BEGIN(0, 2);
     11360    IEM_MC_LOCAL(IEMFPURESULT,      FpuRes);
     11361    IEM_MC_LOCAL(PCRTFLOAT80U,      pr80ValueN);
     11362
     11363    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     11364    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     11365
     11366    IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
     11367        IEM_MC_IF_EFL_BIT_SET(X86_EFL_ZF)
     11368            IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
     11369        IEM_MC_ENDIF();
     11370        IEM_MC_UPDATE_FPU_OPCODE_IP();
     11371    IEM_MC_ELSE()
     11372        IEM_MC_FPU_STACK_UNDERFLOW(0);
     11373    IEM_MC_ENDIF();
     11374    IEM_MC_ADVANCE_RIP();
     11375
     11376    IEM_MC_END();
     11377    return VINF_SUCCESS;
     11378}
     11379
     11380
    1132911381/** Opcode 0xda 11/2. */
    11330 FNIEMOP_STUB_1(iemOp_fcmovbe_stN, uint8_t, bRm);
     11382FNIEMOP_DEF_1(iemOp_fcmovbe_stN, uint8_t, bRm)
     11383{
     11384    IEMOP_MNEMONIC("fcmovbe st0,stN");
     11385    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     11386
     11387    IEM_MC_BEGIN(0, 2);
     11388    IEM_MC_LOCAL(IEMFPURESULT,      FpuRes);
     11389    IEM_MC_LOCAL(PCRTFLOAT80U,      pr80ValueN);
     11390
     11391    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     11392    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     11393
     11394    IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
     11395        IEM_MC_IF_EFL_ANY_BITS_SET(X86_EFL_CF | X86_EFL_ZF)
     11396            IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
     11397        IEM_MC_ENDIF();
     11398        IEM_MC_UPDATE_FPU_OPCODE_IP();
     11399    IEM_MC_ELSE()
     11400        IEM_MC_FPU_STACK_UNDERFLOW(0);
     11401    IEM_MC_ENDIF();
     11402    IEM_MC_ADVANCE_RIP();
     11403
     11404    IEM_MC_END();
     11405    return VINF_SUCCESS;
     11406}
     11407
     11408
    1133111409/** Opcode 0xda 11/3. */
    11332 FNIEMOP_STUB_1(iemOp_fcmovu_stN,  uint8_t, bRm);
     11410FNIEMOP_DEF_1(iemOp_fcmovu_stN,  uint8_t, bRm)
     11411{
     11412    IEMOP_MNEMONIC("fcmovu st0,stN");
     11413    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     11414
     11415    IEM_MC_BEGIN(0, 2);
     11416    IEM_MC_LOCAL(IEMFPURESULT,      FpuRes);
     11417    IEM_MC_LOCAL(PCRTFLOAT80U,      pr80ValueN);
     11418
     11419    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     11420    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     11421
     11422    IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
     11423        IEM_MC_IF_EFL_BIT_SET(X86_EFL_PF)
     11424            IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
     11425        IEM_MC_ENDIF();
     11426        IEM_MC_UPDATE_FPU_OPCODE_IP();
     11427    IEM_MC_ELSE()
     11428        IEM_MC_FPU_STACK_UNDERFLOW(0);
     11429    IEM_MC_ENDIF();
     11430    IEM_MC_ADVANCE_RIP();
     11431
     11432    IEM_MC_END();
     11433    return VINF_SUCCESS;
     11434}
     11435
     11436
    1133311437/** Opcode 0xda 0xe9. */
    1133411438FNIEMOP_STUB(iemOp_fucompp);
     
    1143911543FNIEMOP_STUB_1(iemOp_fstp_r80, uint8_t, bRm);
    1144011544
     11545
    1144111546/** Opcode 0xdb 11/0. */
    11442 FNIEMOP_STUB_1(iemOp_fcmovnb_stN,  uint8_t, bRm);
     11547FNIEMOP_DEF_1(iemOp_fcmovnb_stN,  uint8_t, bRm)
     11548{
     11549    IEMOP_MNEMONIC("fcmovnb st0,stN");
     11550    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     11551
     11552    IEM_MC_BEGIN(0, 2);
     11553    IEM_MC_LOCAL(IEMFPURESULT,      FpuRes);
     11554    IEM_MC_LOCAL(PCRTFLOAT80U,      pr80ValueN);
     11555
     11556    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     11557    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     11558
     11559    IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
     11560        IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_CF)
     11561            IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
     11562        IEM_MC_ENDIF();
     11563        IEM_MC_UPDATE_FPU_OPCODE_IP();
     11564    IEM_MC_ELSE()
     11565        IEM_MC_FPU_STACK_UNDERFLOW(0);
     11566    IEM_MC_ENDIF();
     11567    IEM_MC_ADVANCE_RIP();
     11568
     11569    IEM_MC_END();
     11570    return VINF_SUCCESS;
     11571}
     11572
    1144311573
    1144411574/** Opcode 0xdb 11/1. */
    11445 FNIEMOP_STUB_1(iemOp_fcmovne_stN,  uint8_t, bRm);
     11575FNIEMOP_DEF_1(iemOp_fcmovne_stN,  uint8_t, bRm)
     11576{
     11577    IEMOP_MNEMONIC("fcmovne st0,stN");
     11578    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     11579
     11580    IEM_MC_BEGIN(0, 2);
     11581    IEM_MC_LOCAL(IEMFPURESULT,      FpuRes);
     11582    IEM_MC_LOCAL(PCRTFLOAT80U,      pr80ValueN);
     11583
     11584    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     11585    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     11586
     11587    IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
     11588        IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_ZF)
     11589            IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
     11590        IEM_MC_ENDIF();
     11591        IEM_MC_UPDATE_FPU_OPCODE_IP();
     11592    IEM_MC_ELSE()
     11593        IEM_MC_FPU_STACK_UNDERFLOW(0);
     11594    IEM_MC_ENDIF();
     11595    IEM_MC_ADVANCE_RIP();
     11596
     11597    IEM_MC_END();
     11598    return VINF_SUCCESS;
     11599}
     11600
    1144611601
    1144711602/** Opcode 0xdb 11/2. */
    11448 FNIEMOP_STUB_1(iemOp_fcmovnbe_stN, uint8_t, bRm);
     11603FNIEMOP_DEF_1(iemOp_fcmovnbe_stN, uint8_t, bRm)
     11604{
     11605    IEMOP_MNEMONIC("fcmovnbe st0,stN");
     11606    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     11607
     11608    IEM_MC_BEGIN(0, 2);
     11609    IEM_MC_LOCAL(IEMFPURESULT,      FpuRes);
     11610    IEM_MC_LOCAL(PCRTFLOAT80U,      pr80ValueN);
     11611
     11612    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     11613    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     11614
     11615    IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
     11616        IEM_MC_IF_EFL_NO_BITS_SET(X86_EFL_CF | X86_EFL_ZF)
     11617            IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
     11618        IEM_MC_ENDIF();
     11619        IEM_MC_UPDATE_FPU_OPCODE_IP();
     11620    IEM_MC_ELSE()
     11621        IEM_MC_FPU_STACK_UNDERFLOW(0);
     11622    IEM_MC_ENDIF();
     11623    IEM_MC_ADVANCE_RIP();
     11624
     11625    IEM_MC_END();
     11626    return VINF_SUCCESS;
     11627}
     11628
    1144911629
    1145011630/** Opcode 0xdb 11/3. */
    11451 FNIEMOP_STUB_1(iemOp_fcmovnnu_stN, uint8_t, bRm);
     11631FNIEMOP_DEF_1(iemOp_fcmovnnu_stN, uint8_t, bRm)
     11632{
     11633    IEMOP_MNEMONIC("fcmovnnu st0,stN");
     11634    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     11635
     11636    IEM_MC_BEGIN(0, 2);
     11637    IEM_MC_LOCAL(IEMFPURESULT,      FpuRes);
     11638    IEM_MC_LOCAL(PCRTFLOAT80U,      pr80ValueN);
     11639
     11640    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     11641    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     11642
     11643    IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(pr80ValueN, bRm & X86_MODRM_RM_MASK, 0)
     11644        IEM_MC_IF_EFL_BIT_NOT_SET(X86_EFL_PF)
     11645            IEM_MC_STORE_FPUREG_R80_SRC_REF(0, pr80ValueN);
     11646        IEM_MC_ENDIF();
     11647        IEM_MC_UPDATE_FPU_OPCODE_IP();
     11648    IEM_MC_ELSE()
     11649        IEM_MC_FPU_STACK_UNDERFLOW(0);
     11650    IEM_MC_ENDIF();
     11651    IEM_MC_ADVANCE_RIP();
     11652
     11653    IEM_MC_END();
     11654    return VINF_SUCCESS;
     11655}
    1145211656
    1145311657
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r40244 r40246  
    483483#define IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(a_iEffSeg, a_GCPtrEff)                            do { } while (0)
    484484#define IEM_MC_UPDATE_FSW(a_u16FSW)                                                             do { } while (0)
     485#define IEM_MC_UPDATE_FSW_CONST(a_u16FSW)                                                       do { } while (0)
    485486#define IEM_MC_UPDATE_FSW_WITH_MEM_OP(a_u16FSW, a_iEffSeg, a_GCPtrEff)                          do { } while (0)
    486487#define IEM_MC_UPDATE_FSW_THEN_POP(a_u16FSW)                                                    do { } while (0)
     
    516517    p1 = NULL; \
    517518    if (g_fRandom) {
     519#define IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80_FIRST(p0, i0, i1) \
     520    p0 = NULL; \
     521    if (g_fRandom) {
    518522#define IEM_MC_ELSE()                                                   } else {
    519523#define IEM_MC_ENDIF()                                                  } do {} while (0)
  • trunk/src/VBox/VMM/testcase/tstX86-1A.asm

    r40242 r40246  
    31153115        FxSaveCheckStNValueConst xSP, 1, REF(g_r80_3dot2)
    31163116        FxSaveCheckStNValueConst xSP, 2, REF(g_r80_0dot1)
    3117 %endif
    31183117
    31193118        ;
     
    31503149
    31513150        ;; @todo Finish FPTAN testcase.
     3151%endif
     3152
     3153        ;
     3154        ; FCMOVB - move if CF=1.
     3155        ;
     3156        SetSubTest "FCMOVB ST0,STn"
     3157
     3158        ; ## Normal operation. ##
     3159        fninit
     3160        fldz
     3161        fldpi
     3162        call    SetFSW_C0_thru_C3
     3163        stc
     3164        FpuCheckOpcodeCsIp     { fcmovb st0,st1 }
     3165        FxSaveCheckFSW xSP, X86_FSW_C0 | X86_FSW_C1 | X86_FSW_C2 | X86_FSW_C3, 0 ; seems to be preserved...
     3166        FxSaveCheckStNValueConst xSP, 0, REF(g_r80_Zero)
     3167        FxSaveCheckStNValueConst xSP, 1, REF(g_r80_Zero)
     3168
     3169        fninit
     3170        fldz
     3171        fld1
     3172        call    SetFSW_C0_thru_C3
     3173        clc
     3174        FpuCheckOpcodeCsIp     { fcmovb st0,st1 }
     3175        FxSaveCheckFSW xSP, X86_FSW_C0 | X86_FSW_C1 | X86_FSW_C2 | X86_FSW_C3, 0 ; seems to be preserved...
     3176        FxSaveCheckStNValueConst xSP, 0, REF(g_r80_One)
     3177        FxSaveCheckStNValueConst xSP, 1, REF(g_r80_Zero)
     3178
     3179        ; ## Masked exceptions. ##
     3180
     3181        ; Masked stack underflow - both.
     3182        ; Note! #IE triggers regardless of the test result!
     3183        fninit
     3184        stc
     3185        FpuCheckOpcodeCsIp     { fcmovb st0,st1 }
     3186        FxSaveCheckFSW xSP, X86_FSW_IE | X86_FSW_SF, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3
     3187        FxSaveCheckStNValue_QNaN(xSP, 0)
     3188        FxSaveCheckStNEmpty      xSP, 1
     3189
     3190        fninit
     3191        clc
     3192        FpuCheckOpcodeCsIp     { fcmovb st0,st1 }
     3193        FxSaveCheckFSW xSP, X86_FSW_IE | X86_FSW_SF, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3
     3194        FxSaveCheckStNValue_QNaN(xSP, 0)
     3195        FxSaveCheckStNEmpty      xSP, 1
     3196
     3197        ; Masked stack underflow - source.
     3198        fninit
     3199        fldz
     3200        stc
     3201        FpuCheckOpcodeCsIp     { fcmovb st0,st1 }
     3202        FxSaveCheckFSW xSP, X86_FSW_IE | X86_FSW_SF, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3
     3203        FxSaveCheckStNValue_QNaN(xSP, 0)
     3204        FxSaveCheckStNEmpty      xSP, 1
     3205
     3206        fninit
     3207        fldz
     3208        stc
     3209        FpuCheckOpcodeCsIp     { fcmovb st0,st1 }
     3210        FxSaveCheckFSW xSP, X86_FSW_IE | X86_FSW_SF, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3
     3211        FxSaveCheckStNValue_QNaN(xSP, 0)
     3212        FxSaveCheckStNEmpty      xSP, 1
     3213
     3214        ; Masked stack underflow - destination.
     3215        fninit
     3216        fldz
     3217        fldpi
     3218        ffree st0
     3219        stc
     3220        FpuCheckOpcodeCsIp     { fcmovb st0,st1 }
     3221        FxSaveCheckFSW xSP, X86_FSW_IE | X86_FSW_SF, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3
     3222        FxSaveCheckStNValue_QNaN(xSP, 0)
     3223        FxSaveCheckStNValueConst xSP, 1, REF(g_r80_Zero)
     3224
     3225        fninit
     3226        fldz
     3227        fldpi
     3228        ffree st0
     3229        clc
     3230        FpuCheckOpcodeCsIp     { fcmovb st0,st1 }
     3231        FxSaveCheckFSW xSP, X86_FSW_IE | X86_FSW_SF, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3
     3232        FxSaveCheckStNValue_QNaN(xSP, 0)
     3233        FxSaveCheckStNValueConst xSP, 1, REF(g_r80_Zero)
     3234
     3235        ;; @todo Finish FCMOVB testcase.
    31523236
    31533237
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