VirtualBox

Changeset 40143 in vbox


Ignore:
Timestamp:
Feb 16, 2012 10:08:06 AM (13 years ago)
Author:
vboxsync
Message:

fdiv - almost there...

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

Legend:

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

    r40141 r40143  
    3939 *
    4040 * The current code is very much work in progress. You've been warned!
     41 *
     42 *
     43 * @section sec_iem_fpu_instr   FPU Instructions
     44 *
     45 * On x86 and AMD64 hosts, the FPU instructions are implemented by executing the
     46 * same or equivalent instructions on the host FPU.  To make life easy, we also
     47 * let the FPU prioritize the unmasked exceptions for us.  This however, only
     48 * works reliably when CR0.NE is set, i.e. when using \#MF instead the IRQ 13
     49 * for FPU exception delivery, because with CR0.NE=0 there is a window where we
     50 * can trigger spurious FPU exceptions.
     51 *
    4152 *
    4253 */
     
    35293540
    35303541
     3542/**
     3543 * Stores a result in a FPU register and updates the FSW and FTW.
     3544 *
     3545 * @param   pIemCpu             The IEM per CPU data.
     3546 * @param   pResult             The result to store.
     3547 * @param   iStReg              Which FPU register to store it in.
     3548 * @param   pCtx                The CPU context.
     3549 */
     3550static void iemFpuStoreResultOnly(PIEMCPU pIemCpu, PIEMFPURESULT pResult, uint8_t iStReg, PCPUMCTX pCtx)
     3551{
     3552    Assert(iStReg < 8);
     3553    uint16_t  iReg = (X86_FSW_TOP_GET(pCtx->fpu.FSW) + iStReg) & X86_FSW_TOP_SMASK;
     3554    pCtx->fpu.FSW &= X86_FSW_C_MASK;
     3555    pCtx->fpu.FSW |= pResult->FSW & ~X86_FSW_TOP_MASK;
     3556    pCtx->fpu.FTW |= RT_BIT(iReg);
     3557    pCtx->fpu.aRegs[iStReg].r80 = pResult->r80Result;
     3558}
     3559
     3560
     3561/**
     3562 * Stores a result in a FPU register, updates the FSW, FTW, FPUIP, FPUCS, and
     3563 * FOP.
     3564 *
     3565 * @param   pIemCpu             The IEM per CPU data.
     3566 * @param   pResult             The result to store.
     3567 * @param   iStReg              Which FPU register to store it in.
     3568 * @param   pCtx                The CPU context.
     3569 */
    35313570static void iemFpuStoreResult(PIEMCPU pIemCpu, PIEMFPURESULT pResult, uint8_t iStReg)
    35323571{
    3533 }
    3534 
     3572    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     3573    iemFpuUpdateOpcodeAndIP(pIemCpu, pCtx);
     3574    iemFpuStoreResultOnly(pIemCpu, pResult, iStReg, pCtx);
     3575}
     3576
     3577
     3578/**
     3579 * Stores a result in a FPU register, updates the FSW, FTW, FPUIP, FPUCS, FOP,
     3580 * FPUDP, and FPUDS.
     3581 *
     3582 * @param   pIemCpu             The IEM per CPU data.
     3583 * @param   pResult             The result to store.
     3584 * @param   iStReg              Which FPU register to store it in.
     3585 * @param   pCtx                The CPU context.
     3586 */
    35353587static void iemFpuStoreResultWithMemOp(PIEMCPU pIemCpu, PIEMFPURESULT pResult, uint8_t iStReg, uint8_t iEffSeg, RTGCPTR GCPtrEff)
    35363588{
     3589    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
    35373590    iemFpuUpdateDP(pIemCpu, pIemCpu->CTX_SUFF(pCtx), iEffSeg, GCPtrEff);
    3538     //iemFpuStoreResult(pIemCpu, pResult);
     3591    iemFpuUpdateOpcodeAndIP(pIemCpu, pCtx);
     3592    iemFpuStoreResultOnly(pIemCpu, pResult, iStReg, pCtx);
    35393593}
    35403594
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm

    r40138 r40143  
    12811281        fninit
    12821282        movzx   T0, word [%1 + X86FXSTATE.FCW]
     1283        and     T0, X86_FCW_MASK_ALL | X86_FCW_PC_MASK | X86_FCW_RC_MASK
    12831284        or      T0, X86_FCW_MASK_ALL
    12841285        mov     [xSP], T0
     
    12871288
    12881289;;
     1290; Initialize the FPU for x87 operation, loading the guest's status word.
     1291;
     1292; @param    1       Expression giving the address of the FXSTATE of the guest.
     1293%macro FPU_INIT 1
     1294        fninit
     1295        movzx   T0, word [%1 + X86FXSTATE.FCW]
     1296        and     T0, X86_FCW_MASK_ALL | X86_FCW_PC_MASK | X86_FCW_RC_MASK
     1297        mov     [xSP], T0
     1298        fldcw   [xSP]
     1299%endmacro
     1300
     1301;;
    12891302; Need to move this as well somewhere better?
    12901303;
     
    13231336; @param    A0      FPU context (fxsave).
    13241337; @param    A1      Pointer to a IEMFPURESULT for the output.
    1325 ; @param    A2      Pointer to the 32-bit floating point value to convert.
     1338; @param    A2      Pointer to the 64-bit floating point value to convert.
    13261339;
    13271340BEGINPROC_FASTCALL iemAImpl_fpu_r64_to_r80, 12
     
    13391352ENDPROC iemAImpl_fpu_r64_to_r80
    13401353
     1354
     1355;;
     1356; FDIV with 64-bit floating point value.
     1357;
     1358; @param    A0      FPU context (fxsave).
     1359; @param    A1      Pointer to a IEMFPURESULT for the output.
     1360; @param    A2      Pointer to the 80-bit dividend.
     1361; @param    A3      Pointer to the 64-bit divisor.
     1362;
     1363BEGINPROC_FASTCALL iemAImpl_fpu_fdiv_r80_by_r64, 16
     1364        PROLOGUE_4_ARGS
     1365        sub     xSP, 20h
     1366
     1367        FPU_INIT A0
     1368        fdiv    qword [A3]
     1369
     1370        fnstsw  word  [A1 + IEMFPURESULT.FSW]
     1371        fnclex
     1372        fstp    tword [A1 + IEMFPURESULT.r80Result]
     1373
     1374        add     xSP, 20h
     1375        EPILOGUE_4_ARGS 8
     1376ENDPROC iemAImpl_fpu_fdiv_r80_by_r64
     1377
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r40141 r40143  
    1084210842    IEM_MC_MAYBE_RAISE_FPU_XCPT();
    1084310843    IEM_MC_FETCH_MEM_R64(r64Divisor, pIemCpu->iEffSeg, GCPtrEffSrc);
    10844     IEM_MC_REF_FPUREG_R80(pr80Dividend, 0);
    10845 //    IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fpu_fdiv_r80_by_r64, pFpuRes, pr80Dividend, pr64Divisor);
     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);
    1084610846
    1084710847    IEM_MC_STORE_FPU_RESULT_MEM_OP(FpuRes, 0, pIemCpu->iEffSeg, GCPtrEffSrc);
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r40093 r40143  
    718718/** @name FPU operations taking a 64-bit float argument
    719719 * @{ */
    720 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR64,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT64U pr64Val));
     720typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR64,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
     721                                                   PCRTFLOAT80U pr80Val1, PCRTFLOAT64U pr64Val2));
    721722typedef FNIEMAIMPLFPUR64  *PFNIEMAIMPLFPUR64;
    722 FNIEMAIMPLFPUR64 iemAImpl_fpu_r64_to_r80;
     723typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR64U,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT64U pr64Val));
     724typedef FNIEMAIMPLFPUR64U  *PFNIEMAIMPLFPUR64U;
     725FNIEMAIMPLFPUR64U iemAImpl_fpu_r64_to_r80;
     726FNIEMAIMPLFPUR64  iemAImpl_fpu_fdiv_r80_by_r64;
     727
    723728/** @} */
    724729
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r40141 r40143  
    402402
    403403#define IEM_MC_CALL_FPU_AIMPL_2(a_pfnAImpl, a0, a1)                     do { } while (0)
     404#define IEM_MC_CALL_FPU_AIMPL_3(a_pfnAImpl, a0, a1, a3)                 do { } while (0)
    404405#define IEM_MC_PUSH_FPU_RESULT(a_FpuData)                               do { } while (0)
    405406#define IEM_MC_PUSH_FPU_RESULT_MEM_OP(a_FpuData, a_iEffSeg, a_GCPtrEff) 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