VirtualBox

Changeset 40256 in vbox


Ignore:
Timestamp:
Feb 25, 2012 1:09:31 AM (13 years ago)
Author:
vboxsync
Message:

IEM: fnstsw m16, ffree and ffreep, reimplemented fincstp and fdecstp.

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

Legend:

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

    r40255 r40256  
    36793679{
    36803680    iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pIemCpu->CTX_SUFF(pCtx));
     3681}
     3682
     3683
     3684/**
     3685 * Marks the specified stack register as free (for FFREE).
     3686 *
     3687 * @param   pIemCpu             The IEM per CPU data.
     3688 * @param   iStReg              The register to free.
     3689 */
     3690static void iemFpuStackFree(PIEMCPU pIemCpu, uint8_t iStReg)
     3691{
     3692    Assert(iStReg < 8);
     3693    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     3694    uint8_t iReg = (X86_FSW_TOP_GET(pCtx->fpu.FSW) + iStReg) & X86_FSW_TOP_SMASK;
     3695    pCtx->fpu.FTW &= ~RT_BIT(iReg);
     3696}
     3697
     3698
     3699/**
     3700 * Increments FSW.TOP, i.e. pops an item off the stack without freeing it.
     3701 *
     3702 * @param   pIemCpu             The IEM per CPU data.
     3703 */
     3704static void iemFpuStackIncTop(PIEMCPU pIemCpu)
     3705{
     3706    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     3707    uint16_t uFsw = pCtx->fpu.FSW;
     3708    uint16_t uTop = uFsw & X86_FSW_TOP_MASK;
     3709    uTop  = (uTop + (1 << X86_FSW_TOP_SHIFT)) & X86_FSW_TOP_MASK;
     3710    uFsw &= ~X86_FSW_TOP_MASK;
     3711    uFsw |= uTop;
     3712    pCtx->fpu.FSW = uFsw;
     3713}
     3714
     3715
     3716/**
     3717 * Decrements FSW.TOP, i.e. push an item off the stack without storing anything.
     3718 *
     3719 * @param   pIemCpu             The IEM per CPU data.
     3720 */
     3721static void iemFpuStackDecTop(PIEMCPU pIemCpu)
     3722{
     3723    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     3724    uint16_t uFsw = pCtx->fpu.FSW;
     3725    uint16_t uTop = uFsw & X86_FSW_TOP_MASK;
     3726    uTop  = (uTop + (7 << X86_FSW_TOP_SHIFT)) & X86_FSW_TOP_MASK;
     3727    uFsw &= ~X86_FSW_TOP_MASK;
     3728    uFsw |= uTop;
     3729    pCtx->fpu.FSW = uFsw;
    36813730}
    36823731
     
    63836432#define IEM_MC_UPDATE_FPU_OPCODE_IP() \
    63846433    iemFpuUpdateOpcodeAndIp(pIemCpu)
     6434/** Free a stack register (for FFREE and FFREEP). */
     6435#define IEM_MC_FPU_STACK_FREE(a_iStReg) \
     6436    iemFpuStackFree(pIemCpu, a_iStReg)
     6437/** Increment the FPU stack pointer. */
     6438#define IEM_MC_FPU_STACK_INC_TOP() \
     6439    iemFpuStackIncTop(pIemCpu)
     6440/** Decrement the FPU stack pointer. */
     6441#define IEM_MC_FPU_STACK_DEC_TOP() \
     6442    iemFpuStackDecTop(pIemCpu)
    63856443
    63866444/** Updates the FSW, FOP, FPUIP, and FPUCS. */
     
    64406498#define IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(a_iEffSeg, a_GCPtrEff) \
    64416499    iemFpuStackPushOverflowWithMemOp(pIemCpu, a_iEffSeg, a_GCPtrEff)
    6442 
    64436500
    64446501#define IEM_MC_IF_EFL_BIT_SET(a_fBit)                   if (pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit)) {
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r40251 r40256  
    43084308
    43094309/**
    4310  * Implements 'FINCSTP' and 'FDECSTP'.
     4310 * Implements 'FCOMI', 'FCOMIP', 'FUCOMI', and 'FUCOMIP'.
    43114311 *
    43124312 * @param   cToAdd              1 or 7.
    43134313 */
    4314 IEM_CIMPL_DEF_1(iemCImpl_fpu_AddToTop, uint8_t, cToAdd)
     4314IEM_CIMPL_DEF_3(iemCImpl_fcomi_fucomi, uint8_t, iStReg, PFNIEMAIMPLFPUR80EFL, pfnAImpl, bool, fPop)
    43154315{
    43164316    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     4317    Assert(iStReg < 8);
    43174318
    43184319    /*
     
    43264327
    43274328    /*
    4328      * Do the job.
    4329      *
    4330      * Note! The instructions are listed as control instructions and should
    4331      *       therefore not update FOP, FPUIP and FPUCS...
    4332      * Note! C0, C2 and C3 are documented as undefined, we clear them.
    4333      */
    4334     /** @todo Testcase: Check whether FOP, FPUIP and FPUCS are affected by
    4335      *        FINCSTP and FDECSTP. */
    4336     uint16_t iTop = X86_FSW_TOP_GET(u16Fsw);
    4337     iTop += cToAdd;
    4338     iTop &= X86_FSW_TOP_SMASK;
    4339     u16Fsw &= ~(X86_FSW_TOP_MASK | X86_FSW_C_MASK);
    4340     u16Fsw |= (iTop << X86_FSW_TOP_SHIFT);
    4341     pCtx->fpu.FSW = u16Fsw;
    4342 
    4343     iemRegAddToRip(pIemCpu, cbInstr);
    4344     return VINF_SUCCESS;
    4345 }
    4346 
    4347 
    4348 /**
    4349  * Implements 'FCOMI', 'FCOMIP', 'FUCOMI', and 'FUCOMIP'.
    4350  *
    4351  * @param   cToAdd              1 or 7.
    4352  */
    4353 IEM_CIMPL_DEF_3(iemCImpl_fcomi_fucomi, uint8_t, iStReg, PFNIEMAIMPLFPUR80EFL, pfnAImpl, bool, fPop)
    4354 {
    4355     PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
    4356     Assert(iStReg < 8);
    4357 
    4358     /*
    4359      * Raise exceptions.
    4360      */
    4361     if (pCtx->cr0 & (X86_CR0_EM | X86_CR0_TS))
    4362         return iemRaiseDeviceNotAvailable(pIemCpu);
    4363     uint16_t u16Fsw = pCtx->fpu.FSW;
    4364     if (u16Fsw & X86_FSW_ES)
    4365         return iemRaiseMathFault(pIemCpu);
    4366 
    4367     /*
    43684329     * Check if any of the register accesses causes #SF + #IA.
    43694330     */
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r40255 r40256  
    1117411174    IEMOP_MNEMONIC("fdecstp");
    1117511175    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    11176     return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_fpu_AddToTop, 7);
     11176    /* Note! C0, C2 and C3 are documented as undefined, we clear them. */
     11177    /** @todo Testcase: Check whether FOP, FPUIP and FPUCS are affected by
     11178     *        FINCSTP and FDECSTP. */
     11179
     11180    IEM_MC_BEGIN(0,0);
     11181
     11182    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     11183    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     11184
     11185    IEM_MC_FPU_STACK_DEC_TOP();
     11186    IEM_MC_UPDATE_FSW_CONST(0);
     11187
     11188    IEM_MC_END();
     11189    return VINF_SUCCESS;
    1117711190}
    1117811191
     
    1118311196    IEMOP_MNEMONIC("fincstp");
    1118411197    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    11185     return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_fpu_AddToTop, 1);
     11198    /* Note! C0, C2 and C3 are documented as undefined, we clear them. */
     11199    /** @todo Testcase: Check whether FOP, FPUIP and FPUCS are affected by
     11200     *        FINCSTP and FDECSTP. */
     11201
     11202    IEM_MC_BEGIN(0,0);
     11203
     11204    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     11205    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     11206
     11207    IEM_MC_FPU_STACK_INC_TOP();
     11208    IEM_MC_UPDATE_FSW_CONST(0);
     11209
     11210    IEM_MC_END();
     11211    return VINF_SUCCESS;
    1118611212}
    1118711213
     
    1254012566FNIEMOP_STUB_1(iemOp_fnsave,      uint8_t, bRm);
    1254112567
     12568
    1254212569/** Opcode 0xdd !11/0. */
    12543 FNIEMOP_STUB_1(iemOp_fnstsw,      uint8_t, bRm);
     12570FNIEMOP_DEF_1(iemOp_fnstsw,      uint8_t, bRm)
     12571{
     12572    IEMOP_MNEMONIC("fnstsw m16");
     12573
     12574    IEM_MC_BEGIN(0, 2);
     12575    IEM_MC_LOCAL(uint16_t, u16Tmp);
     12576    IEM_MC_LOCAL(RTGCPTR,  GCPtrEffDst);
     12577
     12578    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     12579    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     12580
     12581    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
     12582    IEM_MC_FETCH_FSW(u16Tmp);
     12583    IEM_MC_STORE_MEM_U16(pIemCpu->iEffSeg, GCPtrEffDst, u16Tmp);
     12584    IEM_MC_ADVANCE_RIP();
     12585
     12586    IEM_MC_END();
     12587    return VINF_SUCCESS;
     12588}
     12589
    1254412590
    1254512591/** Opcode 0xdd 11/0. */
    12546 FNIEMOP_STUB_1(iemOp_ffree_stN,   uint8_t, bRm);
     12592FNIEMOP_DEF_1(iemOp_ffree_stN,   uint8_t, bRm)
     12593{
     12594    IEMOP_MNEMONIC("ffree stN");
     12595    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     12596    /* Note! C0, C1, C2 and C3 are documented as undefined, we leave the
     12597             unmodified. */
     12598
     12599    IEM_MC_BEGIN(0, 0);
     12600
     12601    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     12602    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     12603
     12604    IEM_MC_FPU_STACK_FREE(bRm & X86_MODRM_RM_MASK);
     12605    IEM_MC_UPDATE_FPU_OPCODE_IP();
     12606
     12607    IEM_MC_ADVANCE_RIP();
     12608    IEM_MC_END();
     12609    return VINF_SUCCESS;
     12610}
    1254712611
    1254812612
     
    1287012934
    1287112935
    12872 /** Opcode 0xdf 11/0. */
    12873 FNIEMOP_STUB_1(iemOp_ffreep_stN, uint8_t, bRm);
     12936/** Opcode 0xdf 11/0.
     12937 * Undocument instruction, assumed to work like ffree + fincstp.  */
     12938FNIEMOP_DEF_1(iemOp_ffreep_stN, uint8_t, bRm)
     12939{
     12940    IEMOP_MNEMONIC("ffreep stN");
     12941    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     12942
     12943    IEM_MC_BEGIN(0, 0);
     12944
     12945    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     12946    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     12947
     12948    IEM_MC_FPU_STACK_FREE(bRm & X86_MODRM_RM_MASK);
     12949    IEM_MC_FPU_STACK_INC_TOP();
     12950    IEM_MC_UPDATE_FPU_OPCODE_IP();
     12951
     12952    IEM_MC_ADVANCE_RIP();
     12953    IEM_MC_END();
     12954    return VINF_SUCCESS;
     12955}
    1287412956
    1287512957
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r40255 r40256  
    510510#define IEM_MC_FPU_STACK_PUSH_OVERFLOW()                                                        do { } while (0)
    511511#define IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(a_iEffSeg, a_GCPtrEff)                            do { } while (0)
     512#define IEM_MC_UPDATE_FPU_OPCODE_IP()                                                           do { } while (0)
     513#define IEM_MC_FPU_STACK_DEC_TOP()                                                              do { } while (0)
     514#define IEM_MC_FPU_STACK_INC_TOP()                                                              do { } while (0)
     515#define IEM_MC_FPU_STACK_FREE(a_iStReg)                                                         do { } while (0)
    512516#define IEM_MC_UPDATE_FSW(a_u16FSW)                                                             do { } while (0)
    513517#define IEM_MC_UPDATE_FSW_CONST(a_u16FSW)                                                       do { } while (0)
     
    516520#define IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(a_u16FSW, a_iEffSeg, a_GCPtrEff)                 do { } while (0)
    517521#define IEM_MC_UPDATE_FSW_THEN_POP_POP(a_u16FSW)                                                do { } while (0)
    518 #define IEM_MC_UPDATE_FPU_OPCODE_IP()                                                           do { } while (0)
    519522
    520523#define IEM_MC_IF_EFL_BIT_SET(a_fBit)                                   if (g_fRandom) {
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