VirtualBox

Changeset 40154 in vbox


Ignore:
Timestamp:
Feb 16, 2012 3:57:34 PM (13 years ago)
Author:
vboxsync
Message:

IEM: fdiv implemented but untested.

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

Legend:

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

    r40143 r40154  
    35943594
    35953595
     3596static void iemFpuStackUnderflowOnly(PIEMCPU pIemCpu, uint8_t iStReg, PCPUMCTX pCtx)
     3597{
     3598    Assert(iStReg < 8);
     3599    uint16_t iReg = (X86_FSW_TOP_GET(pCtx->fpu.FSW) + iStReg) & X86_FSW_TOP_SMASK;
     3600    if (pCtx->fpu.FCW & X86_FCW_IM)
     3601    {
     3602        /* Masked underflow. */
     3603        pCtx->fpu.FSW &= X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3;
     3604        pCtx->fpu.FSW |= X86_FSW_C1 | X86_FSW_IE | X86_FSW_SF;
     3605        pCtx->fpu.FTW |= RT_BIT(iReg);
     3606        iemFpuStoreQNan(&pCtx->fpu.aRegs[iStReg].r80);
     3607    }
     3608    else
     3609    {
     3610        pCtx->fpu.FSW &= X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3;
     3611        pCtx->fpu.FSW |= X86_FSW_C1 | X86_FSW_IE | X86_FSW_SF | X86_FSW_ES | X86_FSW_B;
     3612    }
     3613}
     3614
     3615static void iemFpuStackUnderflow(PIEMCPU pIemCpu, uint8_t iStReg)
     3616{
     3617    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     3618    iemFpuUpdateOpcodeAndIP(pIemCpu, pCtx);
     3619    iemFpuStackUnderflowOnly(pIemCpu, iStReg, pCtx);
     3620}
     3621
     3622static void iemFpuStackUnderflowWithMemOp(PIEMCPU pIemCpu, uint8_t iStReg, uint8_t iEffSeg, RTGCPTR GCPtrEff)
     3623{
     3624    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     3625    iemFpuUpdateDP(pIemCpu, pIemCpu->CTX_SUFF(pCtx), iEffSeg, GCPtrEff);
     3626    iemFpuUpdateOpcodeAndIP(pIemCpu, pCtx);
     3627    iemFpuStackUnderflowOnly(pIemCpu, iStReg, pCtx);
     3628}
     3629
     3630static int iemFpuStRegNonEmptyRef(PIEMCPU pIemCpu, uint8_t iStReg, PCRTFLOAT80U *ppRef)
     3631{
     3632    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     3633    uint16_t iReg = (X86_FSW_TOP_GET(pCtx->fpu.FSW) + iStReg) & X86_FSW_TOP_SMASK;
     3634    if (pCtx->fpu.FTW & RT_BIT(iReg))
     3635    {
     3636        *ppRef = &pCtx->fpu.aRegs[iStReg].r80;
     3637        return VINF_SUCCESS;
     3638    }
     3639    return VERR_NOT_FOUND;
     3640}
     3641
    35963642/** @}  */
    35973643
     
    53805426#define IEM_MC_REF_GREG_U64(a_pu64Dst, a_iGReg)         (a_pu64Dst) = (uint64_t *)iemGRegRef(pIemCpu, (a_iGReg))
    53815427#define IEM_MC_REF_EFLAGS(a_pEFlags)                    (a_pEFlags) = &(pIemCpu)->CTX_SUFF(pCtx)->eflags.u
    5382 #define IEM_MC_REF_FPUREG_R80(a_pr80Dst, a_iSt)         (a_pr80Dst) = &(pIemCpu)->CTX_SUFF(pCtx)->fpu.aRegs[a_iSt].r80
    53835428
    53845429#define IEM_MC_ADD_GREG_U8(a_iGReg, a_u8Value)          *(uint8_t  *)iemGRegRef(pIemCpu, (a_iGReg)) += (a_u8Value)
     
    57675812#define IEM_MC_STORE_FPU_RESULT_MEM_OP(a_FpuData, a_iStReg, a_iEffSeg, a_GCPtrEff) \
    57685813    iemFpuStoreResultWithMemOp(pIemCpu, &a_FpuData, a_iStReg, a_iEffSeg, a_GCPtrEff)
     5814
     5815/** Raises a FPU stack underflow. Sets FPUIP, FPUCS and FOP. */
     5816#define IEM_MC_FPU_STACK_UNDERFLOW(a_iSt) \
     5817    iemFpuStackUnderflow(pIemCpu, a_iSt)
     5818/** Raises a FPU stack underflow. Sets FPUIP, FPUCS, FOP, FPUDP and FPUDS. */
     5819#define IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(a_iSt, a_iEffSeg, a_GCPtrEff) \
     5820    iemFpuStackUnderflowWithMemOp(pIemCpu, a_iSt, a_iEffSeg, a_GCPtrEff)
    57695821
    57705822
     
    58105862#define IEM_MC_IF_LOCAL_IS_Z(a_Local)                   if ((a_Local) == 0) {
    58115863#define IEM_MC_IF_GREG_BIT_SET(a_iGReg, a_iBitNo)       if (*(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) & RT_BIT_64(a_iBitNo)) {
     5864#define IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(a_pr80Dst, a_iSt) \
     5865    if (iemFpuStRegNonEmptyRef(pIemCpu, (a_iSt), &(a_pr80Dst)) == VINF_SUCCESS) {
     5866
    58125867#define IEM_MC_ELSE()                                   } else {
    58135868#define IEM_MC_ENDIF()                                  } do {} while (0)
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r40143 r40154  
    1082410824FNIEMOP_STUB_1(iemOp_fsubr_m64r, uint8_t, bRm);
    1082510825
     10826
    1082610827/** Opcode 0xdc !11/6. */
    1082710828FNIEMOP_DEF_1(iemOp_fdiv_m64r,  uint8_t, bRm)
     
    1084210843    IEM_MC_MAYBE_RAISE_FPU_XCPT();
    1084310844    IEM_MC_FETCH_MEM_R64(r64Divisor, pIemCpu->iEffSeg, GCPtrEffSrc);
    10844     IEM_MC_REF_FPUREG_R80(pr80Dividend, 0); /** @todo Check for and handle stack underflow! */
    10845     IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fpu_fdiv_r80_by_r64, pFpuRes, pr80Dividend, pr64Divisor);
    10846 
    10847     IEM_MC_STORE_FPU_RESULT_MEM_OP(FpuRes, 0, pIemCpu->iEffSeg, GCPtrEffSrc);
     10845    IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Dividend, 0)
     10846        IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fpu_fdiv_r80_by_r64, pFpuRes, pr80Dividend, pr64Divisor);
     10847        IEM_MC_STORE_FPU_RESULT_MEM_OP(FpuRes, 0, pIemCpu->iEffSeg, GCPtrEffSrc);
     10848    IEM_MC_ELSE()
     10849        IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(0, pIemCpu->iEffSeg, GCPtrEffSrc);
     10850    IEM_MC_ENDIF();
    1084810851    IEM_MC_ADVANCE_RIP();
    1084910852
     
    1085110854    return VINF_SUCCESS;
    1085210855}
     10856
    1085310857
    1085410858/** Opcode 0xdc !11/7. */
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r40143 r40154  
    282282#define IEM_MC_REF_GREG_U64(a_pu64Dst, a_iGReg)         do { (a_pu64Dst) = (uint64_t *)((uintptr_t)0); CHK_PTYPE(uint64_t *, a_pu64Dst); } while (0)
    283283#define IEM_MC_REF_EFLAGS(a_pEFlags)                    do { (a_pEFlags) = (uint32_t *)((uintptr_t)0); CHK_PTYPE(uint32_t *, a_pEFlags); } while (0)
    284 #define IEM_MC_REF_FPUREG_R80(a_pr80Dst, a_iSt)         do { (a_pr80Dst) = (PCRTFLOAT80U)((uintptr_t)0); CHK_PTYPE(PCRTFLOAT80U, a_pr80Dst); } while (0)
    285284
    286285#define IEM_MC_ADD_GREG_U8(a_iGReg, a_u8Value)          do { CHK_CONST(uint8_t,  a_u8Value);  } while (0)
     
    407406#define IEM_MC_STORE_FPU_RESULT(a_FpuData, a_iStReg)                    do { } while (0)
    408407#define IEM_MC_STORE_FPU_RESULT_MEM_OP(a_FpuData, a_iStReg, a_iEffSeg, a_GCPtrEff)  do { } while (0)
     408#define IEM_MC_FPU_STACK_UNDERFLOW(a_iStReg)                            do { } while (0)
     409#define IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(a_iStReg, a_iEffSeg, a_GCPtrEff) do { } while (0)
    409410
    410411#define IEM_MC_IF_EFL_BIT_SET(a_fBit)                                   if (g_fRandom) {
     
    427428#define IEM_MC_IF_LOCAL_IS_Z(a_Local)                                   if ((a_Local) == 0) {
    428429#define IEM_MC_IF_GREG_BIT_SET(a_iGReg, a_iBitNo)                       if (g_fRandom) {
     430#define IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(a_pr80Dst, a_iSt)            if (g_fRandom) {
    429431#define IEM_MC_ELSE()                                                   } else {
    430432#define IEM_MC_ENDIF()                                                  } do {} 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