VirtualBox

Changeset 40209 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Feb 22, 2012 12:14:21 PM (13 years ago)
Author:
vboxsync
Message:

IEM: Implemented missing FPU instructions starting with 0xd8 and adjusted fld m32r and fld m64r.

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

Legend:

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

    r40199 r40209  
    34013401
    34023402
    3403 #if 0
    3404 /**
     3403/**
     3404 * Pushes a FPU result onto the FPU stack if no pending exception prevents it.
    34053405 *
    34063406 * @param   pIemCpu             The IEM per CPU data.
    34073407 * @param   pResult             The FPU operation result to push.
    34083408 * @param   pCtx                The CPU context.
    3409  * @param   iDstReg             The destination register,
    3410  * @param   cStackAdj           The stack adjustment on successful operation.
    3411  *                              Note that this is an unsigned value.
    3412  * @param   fFlags              Flags.
    3413  */
    3414 static void iemFpuPushResult(PIEMCPU pIemCpu, PIEMFPURESULT pResult, PCPUMCTX pCtx, uint16_t iDstReg,
    3415                              uint8_t cStackAdj, )
    3416 {
    3417     PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
    3418     iemFpuUpdateOpcodeAndIP(pIemCpu, pCtx);
    3419 
     3409 */
     3410static void iemFpuMaybePushResult(PIEMCPU pIemCpu, PIEMFPURESULT pResult, PCPUMCTX pCtx)
     3411{
     3412    /* Check pending exceptions. */
     3413    uint16_t uFSW = pCtx->fpu.FSW;
     3414    if (   (pCtx->fpu.FSW & (X86_FSW_IE | X86_FSW_ZE | X86_FSW_DE))
     3415        & ~(pCtx->fpu.FCW & (X86_FCW_IM | X86_FCW_ZM | X86_FCW_DM)))
     3416        return;
     3417
     3418    /* Push it. */
    34203419    uint16_t iNewTop = (X86_FSW_TOP_GET(pCtx->fpu.FSW) + 7) & X86_FSW_TOP_SMASK;
    3421     if (!(RT_BIT(iNewTop) & pCtx->fpu.FTW))
    3422     {
    3423         /* No stack error. */
    3424         uint16_t fXcpts = (pResult->FSW   & (X86_FSW_IE | X86_FSW_DE | X86_FSW_ZE | X86_FSW_OE | X86_FSW_UE | X86_FSW_PE))
    3425                         & ~(pCtx->fpu.FCW & (X86_FCW_IM | X86_FCW_DM | X86_FCW_ZM | X86_FCW_OM | X86_FCW_UM | X86_FCW_PM));
    3426         if (!fXcpts)
    3427         {
    3428             /* No unmasked exceptions, just store the result. */
    3429             pCtx->fpu.FSW &= X86_FSW_TOP_MASK | X86_FSW_C0 | X86_FSW_C1 | X86_FSW_C2 | X86_FSW_C3;
    3430             pCtx->fpu.FSW |= (iNewTop << X86_FSW_TOP_SHIFT) | (pResult->FSW & ~(X86_FSW_TOP_MASK | X86_FSW_B | X86_FSW_ES));
    3431             pCtx->fpu.FTW |= RT_BIT(iNewTop);
    3432             pCtx->fpu.aRegs[7].r80 = pResult->r80Result;
    3433         }
    3434         else
    3435         {
    3436             AssertFailed();
    3437         }
    3438 
    3439     }
    3440     else if (pCtx->fpu.FCW & X86_FCW_IM)
    3441     {
    3442         /* Masked stack overflow. */
    3443         pCtx->fpu.FSW &= X86_FSW_TOP_MASK | X86_FSW_C0 | X86_FSW_C1 | X86_FSW_C2 | X86_FSW_C3;
    3444         pCtx->fpu.FSW |= (iNewTop << X86_FSW_TOP_SHIFT) | X86_FSW_C1 | X86_FSW_IE | X86_FSW_SF;
    3445         pCtx->fpu.FTW |= RT_BIT(iNewTop);
    3446         iemFpuStoreQNan(&pCtx->fpu.aRegs[7].r80);
    3447     }
    3448     else
    3449     {
    3450         /* Stack overflow exception. */
    3451         pCtx->fpu.FSW &= X86_FSW_C0 | X86_FSW_C1 | X86_FSW_C2 | X86_FSW_C3;
    3452         pCtx->fpu.FSW |= X86_FSW_C1 | X86_FSW_IE | X86_FSW_SF | X86_FSW_ES | X86_FSW_B;
    3453         return;
    3454     }
     3420    pCtx->fpu.FSW &= ~(X86_FSW_TOP_MASK | X86_FSW_C_MASK);
     3421    pCtx->fpu.FSW |= pResult->FSW & ~X86_FSW_TOP_MASK;
     3422    pCtx->fpu.FSW |= iNewTop << X86_FSW_TOP_SHIFT;
     3423    pCtx->fpu.FTW |= RT_BIT(iNewTop);
     3424    pCtx->fpu.aRegs[7].r80 = pResult->r80Result;
    34553425
    34563426    iemFpuRotateStackPush(pCtx);
    3457 }
    3458 
    3459 
    3460 /**
    3461  * Writes a FPU result to the FPU stack after inspecting the resulting
    3462  * statuses.
    3463  *
    3464  * @param   pIemCpu             The IEM per CPU data.
    3465  * @param   pResult             The FPU operation result to push.
    3466  * @param   iReg                The stack relative FPU register number.
    3467  */
    3468 static void iemFpuStoreResult(PIEMCPU pIemCpu, PIEMFPURESULT pResult, uint8_t iReg)
    3469 {
    3470     PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
    3471     iemFpuUpdateOpcodeAndIP(pIemCpu, pCtx);
    3472 
    3473     uint16_t iReg = (X86_FSW_TOP_GET(pCtx->fpu.FSW) + iReg) & X86_FSW_TOP_SMASK;
    3474 
    3475     uint16_t fXcpts = (pResult->FSW   & (X86_FSW_IE | X86_FSW_DE | X86_FSW_ZE | X86_FSW_OE | X86_FSW_UE | X86_FSW_PE))
    3476                     & ~(pCtx->fpu.FCW & (X86_FCW_IM | X86_FCW_DM | X86_FCW_ZM | X86_FCW_OM | X86_FCW_UM | X86_FCW_PM));
    3477     if (!fXcpts)
    3478     {
    3479         /* No unmasked exceptions, just store the result. */
    3480         pCtx->fpu.FSW &= X86_FSW_C0 | X86_FSW_C1 | X86_FSW_C2 | X86_FSW_C3;
    3481         pCtx->fpu.FSW |= (pResult->FSW & ~(X86_FSW_TOP_MASK | X86_FSW_B | X86_FSW_ES));
    3482         pCtx->fpu.FTW |= RT_BIT(iNewTop);
    3483         pCtx->fpu.aRegs[7].r80 = pResult->r80Result;
    3484     }
    3485     else
    3486     {
    3487         AssertFailed();
    3488     }
    3489 }
    3490 #endif
    3491 
    3492 
    3493 /**
    3494  * Pushes a FPU result onto the FPU stack after inspecting the resulting
    3495  * statuses.
    3496  *
    3497  * @param   pIemCpu             The IEM per CPU data.
    3498  * @param   pResult             The FPU operation result to push.
    3499  */
    3500 static void iemFpuPushResult(PIEMCPU pIemCpu, PIEMFPURESULT pResult)
    3501 {
    3502     PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
    3503     iemFpuUpdateOpcodeAndIP(pIemCpu, pCtx);
    3504 
    3505     uint16_t iNewTop = (X86_FSW_TOP_GET(pCtx->fpu.FSW) + 7) & X86_FSW_TOP_SMASK;
    3506     if (!(RT_BIT(iNewTop) & pCtx->fpu.FTW))
    3507     {
    3508         /* No stack error. */
    3509         uint16_t fXcpts = (pResult->FSW   & (X86_FSW_IE | X86_FSW_DE | X86_FSW_ZE | X86_FSW_OE | X86_FSW_UE | X86_FSW_PE))
    3510                         & ~(pCtx->fpu.FCW & (X86_FCW_IM | X86_FCW_DM | X86_FCW_ZM | X86_FCW_OM | X86_FCW_UM | X86_FCW_PM));
    3511         if (!fXcpts)
    3512         {
    3513             /* No unmasked exceptions, just store the result. */
    3514             pCtx->fpu.FSW &= ~(X86_FSW_TOP_MASK | X86_FSW_C0 | X86_FSW_C1 | X86_FSW_C2 | X86_FSW_C3);
    3515             pCtx->fpu.FSW |= pResult->FSW & ~(X86_FSW_TOP_MASK | X86_FSW_B | X86_FSW_ES);
    3516             pCtx->fpu.FSW |= iNewTop << X86_FSW_TOP_SHIFT;
    3517             pCtx->fpu.FTW |= RT_BIT(iNewTop);
    3518             pCtx->fpu.aRegs[7].r80 = pResult->r80Result;
    3519         }
    3520         else
    3521         {
    3522             AssertFailed();
    3523         }
    3524 
    3525     }
    3526     else if (pCtx->fpu.FCW & X86_FCW_IM)
    3527     {
    3528         /* Masked stack overflow. */
    3529         pCtx->fpu.FSW &= ~(X86_FSW_TOP_MASK | X86_FSW_C0 | X86_FSW_C1 | X86_FSW_C2 | X86_FSW_C3);
    3530         pCtx->fpu.FSW |= (iNewTop << X86_FSW_TOP_SHIFT) | X86_FSW_C1 | X86_FSW_IE | X86_FSW_SF;
    3531         pCtx->fpu.FTW |= RT_BIT(iNewTop);
    3532         iemFpuStoreQNan(&pCtx->fpu.aRegs[7].r80);
    3533     }
    3534     else
    3535     {
    3536         /* Stack overflow exception. */
    3537         pCtx->fpu.FSW &= ~(X86_FSW_C0 | X86_FSW_C1 | X86_FSW_C2 | X86_FSW_C3);
    3538         pCtx->fpu.FSW |= X86_FSW_C1 | X86_FSW_IE | X86_FSW_SF | X86_FSW_ES | X86_FSW_B;
    3539         return;
    3540     }
    3541 
    3542     iemFpuRotateStackPush(pCtx);
    3543 }
    3544 
    3545 
    3546 /**
    3547  * Pushes a FPU result onto the FPU stack after inspecting the resulting
    3548  * statuses, and sets FPU.DS and FPUDP.
    3549  *
    3550  * @param   pIemCpu             The IEM per CPU data.
    3551  * @param   pResult             The FPU operation result to push.
    3552  * @param   iEffSeg             The effective segment register.
    3553  * @param   GCPtrEff            The effective address relative to @a iEffSeg.
    3554  */
    3555 static void iemFpuPushResultWithMemOp(PIEMCPU pIemCpu, PIEMFPURESULT pResult, uint8_t iEffSeg, RTGCPTR GCPtrEff)
    3556 {
    3557     iemFpuUpdateDP(pIemCpu, pIemCpu->CTX_SUFF(pCtx), iEffSeg, GCPtrEff);
    3558     iemFpuPushResult(pIemCpu, pResult);
    35593427}
    35603428
     
    36223490
    36233491/**
     3492 * Pushes a FPU result onto the FPU stack if no pending exception prevents it.
     3493 *
     3494 * @param   pIemCpu             The IEM per CPU data.
     3495 * @param   pResult             The FPU operation result to push.
     3496 */
     3497static void iemFpuPushResult(PIEMCPU pIemCpu, PIEMFPURESULT pResult)
     3498{
     3499    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     3500    iemFpuUpdateOpcodeAndIP(pIemCpu, pCtx);
     3501    iemFpuMaybePushResult(pIemCpu, pResult, pCtx);
     3502}
     3503
     3504
     3505/**
     3506 * Pushes a FPU result onto the FPU stack if no pending exception prevents it,
     3507 * and sets FPUDP and FPUDS.
     3508 *
     3509 * @param   pIemCpu             The IEM per CPU data.
     3510 * @param   pResult             The FPU operation result to push.
     3511 * @param   iEffSeg             The effective segment register.
     3512 * @param   GCPtrEff            The effective address relative to @a iEffSeg.
     3513 */
     3514static void iemFpuPushResultWithMemOp(PIEMCPU pIemCpu, PIEMFPURESULT pResult, uint8_t iEffSeg, RTGCPTR GCPtrEff)
     3515{
     3516    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     3517    iemFpuUpdateDP(pIemCpu, pCtx, iEffSeg, GCPtrEff);
     3518    iemFpuUpdateOpcodeAndIP(pIemCpu, pCtx);
     3519    iemFpuMaybePushResult(pIemCpu, pResult, pCtx);
     3520}
     3521
     3522
     3523/**
    36243524 * Stores a result in a FPU register, updates the FSW, FTW, FPUIP, FPUCS, and
    36253525 * FOP.
     
    37623662
    37633663
     3664/**
     3665 * Worker routine for raising an FPU stack underflow exception.
     3666 *
     3667 * @param   pIemCpu             The IEM per CPU data.
     3668 * @param   iStReg              The stack register being accessed.
     3669 * @param   pCtx                The CPU context.
     3670 */
    37643671static void iemFpuStackUnderflowOnly(PIEMCPU pIemCpu, uint8_t iStReg, PCPUMCTX pCtx)
    37653672{
    3766     Assert(iStReg < 8);
    3767     uint16_t iReg = (X86_FSW_TOP_GET(pCtx->fpu.FSW) + iStReg) & X86_FSW_TOP_SMASK;
     3673    Assert(iStReg < 8 || iStReg == UINT8_MAX);
    37683674    if (pCtx->fpu.FCW & X86_FCW_IM)
    37693675    {
     
    37713677        pCtx->fpu.FSW &= ~(X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3);
    37723678        pCtx->fpu.FSW |= X86_FSW_C1 | X86_FSW_IE | X86_FSW_SF;
    3773         pCtx->fpu.FTW |= RT_BIT(iReg);
    3774         iemFpuStoreQNan(&pCtx->fpu.aRegs[iStReg].r80);
     3679        uint16_t iReg = (X86_FSW_TOP_GET(pCtx->fpu.FSW) + iStReg) & X86_FSW_TOP_SMASK;
     3680        if (iStReg != UINT8_MAX)
     3681        {
     3682            pCtx->fpu.FTW |= RT_BIT(iReg);
     3683            iemFpuStoreQNan(&pCtx->fpu.aRegs[iStReg].r80);
     3684        }
    37753685    }
    37763686    else
     
    37813691}
    37823692
     3693
     3694/**
     3695 * Raises a FPU stack underflow exception.
     3696 *
     3697 * @param   pIemCpu             The IEM per CPU data.
     3698 * @param   iStReg              The destination register that should be loaded
     3699 *                              with QNaN if \#IS is not masked. Specify
     3700 *                              UINT8_MAX if none (like for fcom).
     3701 */
    37833702DECL_NO_INLINE(static, void) iemFpuStackUnderflow(PIEMCPU pIemCpu, uint8_t iStReg)
    37843703{
     
    38193738
    38203739
    3821 static int iemFpuStRegNonEmpty(PIEMCPU pIemCpu, uint8_t iStReg)
     3740/**
     3741 * Worker routine for raising an FPU stack overflow exception on a push.
     3742 *
     3743 * @param   pIemCpu             The IEM per CPU data.
     3744 * @param   pCtx                The CPU context.
     3745 */
     3746static void iemFpuStackPushOverflowOnly(PIEMCPU pIemCpu, PCPUMCTX pCtx)
     3747{
     3748    if (pCtx->fpu.FCW & X86_FCW_IM)
     3749    {
     3750        /* Masked overflow. */
     3751        uint16_t iNewTop = (X86_FSW_TOP_GET(pCtx->fpu.FSW) + 7) & X86_FSW_TOP_SMASK;
     3752        pCtx->fpu.FSW &= ~(X86_FSW_TOP_MASK | X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3);
     3753        pCtx->fpu.FSW |= X86_FSW_C1 | X86_FSW_IE | X86_FSW_SF;
     3754        pCtx->fpu.FSW |= iNewTop << X86_FSW_TOP_SHIFT;
     3755        pCtx->fpu.FTW |= RT_BIT(iNewTop);
     3756        iemFpuStoreQNan(&pCtx->fpu.aRegs[7].r80);
     3757        iemFpuRotateStackPush(pCtx);
     3758    }
     3759    else
     3760    {
     3761        /* Exception pending - don't change TOP or the register stack. */
     3762        pCtx->fpu.FSW &= ~(X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3);
     3763        pCtx->fpu.FSW |= X86_FSW_C1 | X86_FSW_IE | X86_FSW_SF | X86_FSW_ES | X86_FSW_B;
     3764    }
     3765}
     3766
     3767
     3768/**
     3769 * Raises a FPU stack overflow exception on a push.
     3770 *
     3771 * @param   pIemCpu             The IEM per CPU data.
     3772 */
     3773DECL_NO_INLINE(static, void) iemFpuStackPushOverflow(PIEMCPU pIemCpu)
     3774{
     3775    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     3776    iemFpuUpdateOpcodeAndIP(pIemCpu, pCtx);
     3777    iemFpuStackPushOverflowOnly(pIemCpu, pCtx);
     3778}
     3779
     3780
     3781/**
     3782 * Raises a FPU stack overflow exception on a push with a memory operand.
     3783 *
     3784 * @param   pIemCpu             The IEM per CPU data.
     3785 * @param   iEffSeg             The effective memory operand selector register.
     3786 * @param   GCPtrEff            The effective memory operand offset.
     3787 */
     3788DECL_NO_INLINE(static, void)
     3789iemFpuStackPushOverflowWithMemOp(PIEMCPU pIemCpu, uint8_t iEffSeg, RTGCPTR GCPtrEff)
     3790{
     3791    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     3792    iemFpuUpdateDP(pIemCpu, pCtx, iEffSeg, GCPtrEff);
     3793    iemFpuUpdateOpcodeAndIP(pIemCpu, pCtx);
     3794    iemFpuStackPushOverflowOnly(pIemCpu, pCtx);
     3795}
     3796
     3797
     3798static int iemFpuStRegNotEmpty(PIEMCPU pIemCpu, uint8_t iStReg)
    38223799{
    38233800    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     
    38293806
    38303807
    3831 static int iemFpuStRegNonEmptyRef(PIEMCPU pIemCpu, uint8_t iStReg, PCRTFLOAT80U *ppRef)
     3808static int iemFpuStRegNotEmptyRef(PIEMCPU pIemCpu, uint8_t iStReg, PCRTFLOAT80U *ppRef)
    38323809{
    38333810    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     
    38423819
    38433820
    3844 static int iemFpu2StRegsNonEmptyRef(PIEMCPU pIemCpu, uint8_t iStReg0, PCRTFLOAT80U *ppRef0,
     3821static int iemFpu2StRegsNotEmptyRef(PIEMCPU pIemCpu, uint8_t iStReg0, PCRTFLOAT80U *ppRef0,
    38453822                                    uint8_t iStReg1, PCRTFLOAT80U *ppRef1)
    38463823{
     
    59015878    IEM_MC_RETURN_ON_FAILURE(iemMemCommitAndUnmap(pIemCpu, (a_pvMem), (a_fAccess)))
    59025879
     5880/** Commits the memory and unmaps the guest memory unless the FPU status word
     5881 * indicates an exception (FSW.ES).
     5882 * @remarks     May return (for now anyway).
     5883 */
     5884#define IEM_MC_MEM_COMMIT_AND_UNMAP_UNLESS_FPU_XCPT(a_pvMem, a_fAccess, a_u16FSW) \
     5885    do { \
     5886        if (!(a_u16FSW & X86_FSW_ES)) \
     5887            IEM_MC_RETURN_ON_FAILURE(iemMemCommitAndUnmap(pIemCpu, (a_pvMem), (a_fAccess))); \
     5888    } while (0)
     5889
    59035890/** Calculate efficient address from R/M. */
    59045891#define IEM_MC_CALC_RM_EFF_ADDR(a_GCPtrEff, bRm) \
     
    60826069    iemFpuUpdateFSWWithMemOpThenPop(pIemCpu, a_u16FSW, a_iEffSeg, a_GCPtrEff)
    60836070
    6084 /** Raises a FPU stack underflow. Sets FPUIP, FPUCS and FOP. */
     6071/** Raises a FPU stack underflow exception. Sets FPUIP, FPUCS and FOP. */
    60856072#define IEM_MC_FPU_STACK_UNDERFLOW(a_iStDst) \
    60866073    iemFpuStackUnderflow(pIemCpu, a_iStDst)
    6087 /** Raises a FPU stack underflow. Sets FPUIP, FPUCS and FOP. Pops stack. */
     6074/** Raises a FPU stack underflow exception.  Sets FPUIP, FPUCS and FOP. Pops
     6075 *  stack. */
    60886076#define IEM_MC_FPU_STACK_UNDERFLOW_THEN_POP(a_iStDst) \
    60896077    iemFpuStackUnderflowThenPop(pIemCpu, a_iStDst)
    6090 /** Raises a FPU stack underflow. Sets FPUIP, FPUCS, FOP, FPUDP and FPUDS. */
     6078/** Raises a FPU stack underflow exception.  Sets FPUIP, FPUCS, FOP, FPUDP and
     6079 *  FPUDS. */
    60916080#define IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(a_iStDst, a_iEffSeg, a_GCPtrEff) \
    60926081    iemFpuStackUnderflowWithMemOp(pIemCpu, a_iStDst, a_iEffSeg, a_GCPtrEff)
    6093 /** Raises a FPU stack underflow. Sets FPUIP, FPUCS, FOP, FPUDP and FPUDS.
    6094  *  Pops stack. */
     6082/** Raises a FPU stack underflow exception.  Sets FPUIP, FPUCS, FOP, FPUDP and
     6083 *  FPUDS. Pops stack. */
    60956084#define IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(a_iStDst, a_iEffSeg, a_GCPtrEff) \
    60966085    iemFpuStackUnderflowWithMemOpThenPop(pIemCpu, a_iStDst, a_iEffSeg, a_GCPtrEff)
     6086
     6087/** Raises a FPU stack overflow exception as part of a push attempt.  Sets
     6088 *  FPUIP, FPUCS and FOP. */
     6089#define IEM_MC_FPU_STACK_PUSH_OVERFLOW() \
     6090    iemFpuStackPushOverflow(pIemCpu, a_iStDst)
     6091/** Raises a FPU stack overflow exception as part of a push attempt.  Sets
     6092 *  FPUIP, FPUCS, FOP, FPUDP and FPUDS. */
     6093#define IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(a_iEffSeg, a_GCPtrEff) \
     6094    iemFpuStackPushOverflowWithMemOp(pIemCpu, a_iEffSeg, a_GCPtrEff)
    60976095
    60986096
     
    61396137#define IEM_MC_IF_GREG_BIT_SET(a_iGReg, a_iBitNo)       if (*(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) & RT_BIT_64(a_iBitNo)) {
    61406138#define IEM_MC_IF_FPUREG_NOT_EMPTY(a_iSt) \
    6141     if (iemFpuStRegNonEmpty(pIemCpu, (a_iSt)) == VINF_SUCCESS) {
     6139    if (iemFpuStRegNotEmpty(pIemCpu, (a_iSt)) == VINF_SUCCESS) {
     6140#define IEM_MC_IF_FPUREG_IS_EMPTY(a_iSt) \
     6141    if (iemFpuStRegNotEmpty(pIemCpu, (a_iSt)) != VINF_SUCCESS) {
    61426142#define IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(a_pr80Dst, a_iSt) \
    6143     if (iemFpuStRegNonEmptyRef(pIemCpu, (a_iSt), &(a_pr80Dst)) == VINF_SUCCESS) {
     6143    if (iemFpuStRegNotEmptyRef(pIemCpu, (a_iSt), &(a_pr80Dst)) == VINF_SUCCESS) {
    61446144#define IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(a_pr80Dst0, a_iSt0, a_pr80Dst1, a_iSt1) \
    6145     if (iemFpu2StRegsNonEmptyRef(pIemCpu, (a_iSt0), &(a_pr80Dst0), (a_iSt1), &(a_pr80Dst1)) == VINF_SUCCESS) {
     6145    if (iemFpu2StRegsNotEmptyRef(pIemCpu, (a_iSt0), &(a_pr80Dst0), (a_iSt1), &(a_pr80Dst1)) == VINF_SUCCESS) {
    61466146
    61476147#define IEM_MC_ELSE()                                   } else {
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm

    r40165 r40209  
    12781278
    12791279
    1280 %macro FPU_SAFE_INIT 1
    1281         fninit
    1282         movzx   T0, word [%1 + X86FXSTATE.FCW]
    1283         and     T0, X86_FCW_MASK_ALL | X86_FCW_PC_MASK | X86_FCW_RC_MASK
    1284         or      T0, X86_FCW_MASK_ALL
    1285         mov     [xSP], T0
    1286         fldcw   [xSP]
    1287 %endmacro
    1288 
    12891280;;
    12901281; Initialize the FPU for the actual instruction being emulated, this means
     
    13241315
    13251316;;
    1326 ; Converts a 32-bit floating point value to a 80-bit one (fpu register).
    1327 ;
    1328 ; @param    A0      FPU context (fxsave).
    1329 ; @param    A1      Pointer to a IEMFPURESULT for the output.
    1330 ; @param    A2      The 32-bit floating point value to convert.
    1331 ;
    1332 BEGINPROC_FASTCALL iemAImpl_fpu_r32_to_r80, 12
    1333         PROLOGUE_3_ARGS
    1334         sub     xSP, 20h
    1335 
    1336         FPU_SAFE_INIT A0
    1337         mov     [xSP], A2
    1338         fld     dword [xSP]
    1339 
    1340         fnstsw  word  [A1 + IEMFPURESULT.FSW]
    1341         fstp    tword [A1 + IEMFPURESULT.r80Result]
    1342 
    1343         add     xSP, 20h
    1344         EPILOGUE_3_ARGS 0
    1345 ENDPROC iemAImpl_fpu_r32_to_r80
    1346 
    1347 
    1348 ;;
    1349 ; Converts a 64-bit floating point value to a 80-bit one (fpu register).
    1350 ;
    1351 ; @param    A0      FPU context (fxsave).
    1352 ; @param    A1      Pointer to a IEMFPURESULT for the output.
    1353 ; @param    A2      Pointer to the 64-bit floating point value to convert.
    1354 ;
    1355 BEGINPROC_FASTCALL iemAImpl_fpu_r64_to_r80, 12
    1356         PROLOGUE_3_ARGS
    1357         sub     xSP, 20h
    1358 
    1359         FPU_SAFE_INIT A0
    1360         fld     qword [A2]
    1361 
    1362         fnstsw  word  [A1 + IEMFPURESULT.FSW]
    1363         fstp    tword [A1 + IEMFPURESULT.r80Result]
    1364 
    1365         add     xSP, 20h
    1366         EPILOGUE_3_ARGS 0
    1367 ENDPROC iemAImpl_fpu_r64_to_r80
    1368 
    1369 ;;
    13701317; Converts a 80-bit floating point value to a 32-bit signed integer.
    13711318;
     
    13931340
    13941341
     1342;
     1343;---------------------- 32-bit floating point operations ----------------------
     1344;
     1345
     1346;;
     1347; Converts a 32-bit floating point value to a 80-bit one (fpu register).
     1348;
     1349; @param    A0      FPU context (fxsave).
     1350; @param    A1      Pointer to a IEMFPURESULT for the output.
     1351; @param    A2      Pointer to the 32-bit floating point value to convert.
     1352;
     1353BEGINPROC_FASTCALL iemAImpl_fld_r32_to_r80, 12
     1354        PROLOGUE_3_ARGS
     1355        sub     xSP, 20h
     1356
     1357        fninit
     1358        FPU_LD_FXSTATE_FCW_AND_SAFE_FSW A0
     1359        fld     dword [A2]
     1360
     1361        fnstsw  word  [A1 + IEMFPURESULT.FSW]
     1362        fnclex
     1363        fstp    tword [A1 + IEMFPURESULT.r80Result]
     1364
     1365        fninit
     1366        add     xSP, 20h
     1367        EPILOGUE_3_ARGS 0
     1368ENDPROC iemAImpl_fld_r32_to_r80
     1369
     1370
     1371;;
     1372; Store a 80-bit floating point value (register) as a 32-bit one (memory).
     1373;
     1374; @param    A0      FPU context (fxsave).
     1375; @param    A1      Where to return the output FSW.
     1376; @param    A2      Where to store the 32-bit value.
     1377; @param    A3      Pointer to the 80-bit value.
     1378;
     1379BEGINPROC_FASTCALL iemAImpl_fst_r80_to_r32, 12
     1380        PROLOGUE_3_ARGS
     1381        sub     xSP, 20h
     1382
     1383        fninit
     1384        fld     tword [A3]
     1385        FPU_LD_FXSTATE_FCW_AND_SAFE_FSW A0
     1386        fst     dword [A2]
     1387
     1388        fnstsw  word  [A1]
     1389
     1390        fninit
     1391        add     xSP, 20h
     1392        EPILOGUE_3_ARGS 0
     1393ENDPROC iemAImpl_fst_r80_to_r32
     1394
     1395
     1396;;
     1397; FPU instruction working on one 80-bit and one 32-bit floating point value.
     1398;
     1399; @param    1       The instruction
     1400;
     1401; @param    A0      FPU context (fxsave).
     1402; @param    A1      Pointer to a IEMFPURESULT for the output.
     1403; @param    A2      Pointer to the 80-bit value.
     1404; @param    A3      Pointer to the 32-bit value.
     1405;
     1406%macro IEMIMPL_FPU_R80_BY_R32 1
     1407BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _r80_by_r32, 16
     1408        PROLOGUE_4_ARGS
     1409        sub     xSP, 20h
     1410
     1411        fninit
     1412        fld     tword [A2]
     1413        FPU_LD_FXSTATE_FCW_AND_SAFE_FSW A0
     1414        %1      dword [A3]
     1415
     1416        fnstsw  word  [A1 + IEMFPURESULT.FSW]
     1417        fnclex
     1418        fstp    tword [A1 + IEMFPURESULT.r80Result]
     1419
     1420        fninit
     1421        add     xSP, 20h
     1422        EPILOGUE_4_ARGS 8
     1423ENDPROC iemAImpl_ %+ %1 %+ _r80_by_r32
     1424%endmacro
     1425
     1426IEMIMPL_FPU_R80_BY_R32 fadd
     1427IEMIMPL_FPU_R80_BY_R32 fmul
     1428IEMIMPL_FPU_R80_BY_R32 fsub
     1429IEMIMPL_FPU_R80_BY_R32 fsubr
     1430IEMIMPL_FPU_R80_BY_R32 fdiv
     1431IEMIMPL_FPU_R80_BY_R32 fdivr
     1432
     1433
     1434;;
     1435; FPU instruction working on one 80-bit and one 64-bit floating point value,
     1436; only returning FSW.
     1437;
     1438; @param    1       The instruction
     1439;
     1440; @param    A0      FPU context (fxsave).
     1441; @param    A1      Where to store the output FSW.
     1442; @param    A2      Pointer to the 80-bit value.
     1443; @param    A3      Pointer to the 64-bit value.
     1444;
     1445%macro IEMIMPL_FPU_R80_BY_R32_FSW 1
     1446BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _r80_by_r32, 16
     1447        PROLOGUE_4_ARGS
     1448        sub     xSP, 20h
     1449
     1450        fninit
     1451        fld     tword [A2]
     1452        FPU_LD_FXSTATE_FCW_AND_SAFE_FSW A0
     1453        %1      dword [A3]
     1454
     1455        fnstsw  word  [A1]
     1456
     1457        fninit
     1458        add     xSP, 20h
     1459        EPILOGUE_4_ARGS 8
     1460ENDPROC iemAImpl_ %+ %1 %+ _r80_by_r32
     1461%endmacro
     1462
     1463IEMIMPL_FPU_R80_BY_R32_FSW fcom
     1464
     1465
     1466
     1467;
     1468;---------------------- 64-bit floating point operations ----------------------
     1469;
     1470
     1471;;
     1472; Converts a 64-bit floating point value to a 80-bit one (fpu register).
     1473;
     1474; @param    A0      FPU context (fxsave).
     1475; @param    A1      Pointer to a IEMFPURESULT for the output.
     1476; @param    A2      Pointer to the 64-bit floating point value to convert.
     1477;
     1478BEGINPROC_FASTCALL iemAImpl_fld_r64_to_r80, 12
     1479        PROLOGUE_3_ARGS
     1480        sub     xSP, 20h
     1481
     1482        FPU_LD_FXSTATE_FCW_AND_SAFE_FSW A0
     1483        fld     qword [A2]
     1484
     1485        fnstsw  word  [A1 + IEMFPURESULT.FSW]
     1486        fnclex
     1487        fstp    tword [A1 + IEMFPURESULT.r80Result]
     1488
     1489        fninit
     1490        add     xSP, 20h
     1491        EPILOGUE_3_ARGS 0
     1492ENDPROC iemAImpl_fld_r64_to_r80
     1493
     1494
     1495;;
     1496; Store a 80-bit floating point value (register) as a 64-bit one (memory).
     1497;
     1498; @param    A0      FPU context (fxsave).
     1499; @param    A1      Where to return the output FSW.
     1500; @param    A2      Where to store the 64-bit value.
     1501; @param    A3      Pointer to the 80-bit value.
     1502;
     1503BEGINPROC_FASTCALL iemAImpl_fst_r80_to_r64, 12
     1504        PROLOGUE_3_ARGS
     1505        sub     xSP, 20h
     1506
     1507        fninit
     1508        fld     tword [A3]
     1509        FPU_LD_FXSTATE_FCW_AND_SAFE_FSW A0
     1510        fst     qword [A2]
     1511
     1512        fnstsw  word  [A1]
     1513
     1514        fninit
     1515        add     xSP, 20h
     1516        EPILOGUE_3_ARGS 0
     1517ENDPROC iemAImpl_fst_r80_to_r64
     1518
     1519
    13951520;;
    13961521; FPU instruction working on one 80-bit and one 64-bit floating point value.
     
    14171542        fstp    tword [A1 + IEMFPURESULT.r80Result]
    14181543
     1544        fninit
    14191545        add     xSP, 20h
    14201546        EPILOGUE_4_ARGS 8
     
    14241550IEMIMPL_FPU_R80_BY_R64 fadd
    14251551IEMIMPL_FPU_R80_BY_R64 fmul
    1426 IEMIMPL_FPU_R80_BY_R64 fcom
    14271552IEMIMPL_FPU_R80_BY_R64 fsub
    14281553IEMIMPL_FPU_R80_BY_R64 fsubr
     
    14301555IEMIMPL_FPU_R80_BY_R64 fdivr
    14311556
     1557;;
     1558; FPU instruction working on one 80-bit and one 64-bit floating point value,
     1559; only returning FSW.
     1560;
     1561; @param    1       The instruction
     1562;
     1563; @param    A0      FPU context (fxsave).
     1564; @param    A1      Where to store the output FSW.
     1565; @param    A2      Pointer to the 80-bit value.
     1566; @param    A3      Pointer to the 64-bit value.
     1567;
     1568%macro IEMIMPL_FPU_R80_BY_R64_FSW 1
     1569BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _r80_by_r64, 16
     1570        PROLOGUE_4_ARGS
     1571        sub     xSP, 20h
     1572
     1573        fninit
     1574        fld     tword [A2]
     1575        FPU_LD_FXSTATE_FCW_AND_SAFE_FSW A0
     1576        %1      qword [A3]
     1577
     1578        fnstsw  word  [A1]
     1579
     1580        fninit
     1581        add     xSP, 20h
     1582        EPILOGUE_4_ARGS 8
     1583ENDPROC iemAImpl_ %+ %1 %+ _r80_by_r64
     1584%endmacro
     1585
     1586IEMIMPL_FPU_R80_BY_R64_FSW fcom
     1587
     1588
     1589
     1590;
     1591;---------------------- 80-bit floating point operations ----------------------
     1592;
    14321593
    14331594;;
     
    14561617        fstp    tword [A1 + IEMFPURESULT.r80Result]
    14571618
     1619        fninit
    14581620        add     xSP, 20h
    14591621        EPILOGUE_4_ARGS 8
     
    14671629IEMIMPL_FPU_R80_BY_R80 fdiv
    14681630IEMIMPL_FPU_R80_BY_R80 fdivr
    1469 IEMIMPL_FPU_R80_BY_R80 fcom
    1470 IEMIMPL_FPU_R80_BY_R80 fucom
    1471 
     1631
     1632
     1633;;
     1634; FPU instruction working on two 80-bit floating point values, only
     1635; returning FSW.
     1636;
     1637; @param    1       The instruction
     1638;
     1639; @param    A0      FPU context (fxsave).
     1640; @param    A1      Pointer to a uint16_t for the resulting FSW.
     1641; @param    A2      Pointer to the first 80-bit value.
     1642; @param    A3      Pointer to the second 80-bit value.
     1643;
     1644%macro IEMIMPL_FPU_R80_BY_R80_FSW 1
     1645BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _r80_by_r80, 16
     1646        PROLOGUE_4_ARGS
     1647        sub     xSP, 20h
     1648
     1649        fninit
     1650        fld     tword [A3]
     1651        fld     tword [A2]
     1652        FPU_LD_FXSTATE_FCW_AND_SAFE_FSW A0
     1653        %1      st0, st1
     1654
     1655        fnstsw  word  [A1]
     1656
     1657        fninit
     1658        add     xSP, 20h
     1659        EPILOGUE_4_ARGS 8
     1660ENDPROC iemAImpl_ %+ %1 %+ _r80_by_r80
     1661%endmacro
     1662
     1663IEMIMPL_FPU_R80_BY_R80_FSW fcom
     1664IEMIMPL_FPU_R80_BY_R80_FSW fucom
     1665
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r40199 r40209  
    1026110261FNIEMOP_DEF_2(iemOpHlpFpu_st0_stN, uint8_t, bRm, PFNIEMAIMPLFPUR80, pfnAImpl)
    1026210262{
    10263     IEMOP_HLP_NO_LOCK_PREFIX();
     10263    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    1026410264
    1026510265    IEM_MC_BEGIN(3, 1);
     
    1028410284
    1028510285
     10286/**
     10287 * Common worker for FPU instructions working on ST0 and STn, and only affecting
     10288 * flags.
     10289 *
     10290 * @param   pfnAImpl    Pointer to the instruction implementation (assembly).
     10291 */
     10292FNIEMOP_DEF_2(iemOpHlpFpuNoStore_st0_stN, uint8_t, bRm, PFNIEMAIMPLFPUR80FSW, pfnAImpl)
     10293{
     10294    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     10295
     10296    IEM_MC_BEGIN(3, 1);
     10297    IEM_MC_LOCAL(uint16_t,              u16FSW);
     10298    IEM_MC_ARG_LOCAL_REF(uint16_t *,    pu16FSW,        u16FSW,     0);
     10299    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value1,                 1);
     10300    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value2,                 2);
     10301
     10302    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     10303    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     10304    IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, 0, pr80Value2, bRm & X86_MODRM_RM_MASK)
     10305        IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pu16FSW, pr80Value1, pr80Value2);
     10306        IEM_MC_UPDATE_FSW(u16FSW);
     10307    IEM_MC_ELSE()
     10308        IEM_MC_FPU_STACK_UNDERFLOW(UINT8_MAX);
     10309    IEM_MC_ENDIF();
     10310    IEM_MC_ADVANCE_RIP();
     10311
     10312    IEM_MC_END();
     10313    return VINF_SUCCESS;
     10314}
     10315
     10316
     10317/**
     10318 * Common worker for FPU instructions working on ST0 and STn, only affecting
     10319 * flags, and popping when done.
     10320 *
     10321 * @param   pfnAImpl    Pointer to the instruction implementation (assembly).
     10322 */
     10323FNIEMOP_DEF_2(iemOpHlpFpuNoStore_st0_stN_pop, uint8_t, bRm, PFNIEMAIMPLFPUR80FSW, pfnAImpl)
     10324{
     10325    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     10326
     10327    IEM_MC_BEGIN(3, 1);
     10328    IEM_MC_LOCAL(uint16_t,              u16FSW);
     10329    IEM_MC_ARG_LOCAL_REF(uint16_t *,    pu16FSW,        u16FSW,     0);
     10330    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value1,                 1);
     10331    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value2,                 2);
     10332
     10333    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     10334    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     10335    IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, 0, pr80Value2, bRm & X86_MODRM_RM_MASK)
     10336        IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pu16FSW, pr80Value1, pr80Value2);
     10337        IEM_MC_UPDATE_FSW_THEN_POP(u16FSW);
     10338    IEM_MC_ELSE()
     10339        IEM_MC_FPU_STACK_UNDERFLOW_THEN_POP(UINT8_MAX);
     10340    IEM_MC_ENDIF();
     10341    IEM_MC_ADVANCE_RIP();
     10342
     10343    IEM_MC_END();
     10344    return VINF_SUCCESS;
     10345}
     10346
     10347
    1028610348/** Opcode 0xd8 11/0. */
    1028710349FNIEMOP_DEF_1(iemOp_fadd_stN,   uint8_t, bRm)
     
    1030310365FNIEMOP_DEF_1(iemOp_fcom_stN,   uint8_t, bRm)
    1030410366{
    10305     IEMOP_MNEMONIC(" st0,stN");
    10306     /** @todo No need to store ST0! */
    10307     return FNIEMOP_CALL_2(iemOpHlpFpu_st0_stN, bRm, iemAImpl_fcom_r80_by_r80);
     10367    IEMOP_MNEMONIC("fcom st0,stN");
     10368    return FNIEMOP_CALL_2(iemOpHlpFpuNoStore_st0_stN, bRm, iemAImpl_fcom_r80_by_r80);
    1030810369}
    1030910370
    1031010371
    1031110372/** Opcode 0xd8 11/3. */
    10312 FNIEMOP_STUB_1(iemOp_fcomp_stN,  uint8_t, bRm);
     10373FNIEMOP_DEF_1(iemOp_fcomp_stN,  uint8_t, bRm)
     10374{
     10375    IEMOP_MNEMONIC("fcomp st0,stN");
     10376    return FNIEMOP_CALL_2(iemOpHlpFpuNoStore_st0_stN_pop, bRm, iemAImpl_fcom_r80_by_r80);
     10377}
     10378
    1031310379
    1031410380/** Opcode 0xd8 11/4. */
     
    1034410410
    1034510411
     10412/**
     10413 * Common worker for FPU instructions working on ST0 and an m32r, and storing
     10414 * the result in ST0.
     10415 *
     10416 * @param   pfnAImpl    Pointer to the instruction implementation (assembly).
     10417 */
     10418FNIEMOP_DEF_2(iemOpHlpFpu_st0_m32r, uint8_t, bRm, PFNIEMAIMPLFPUR32, pfnAImpl)
     10419{
     10420    IEM_MC_BEGIN(3, 3);
     10421    IEM_MC_LOCAL(RTGCPTR,               GCPtrEffSrc);
     10422    IEM_MC_LOCAL(IEMFPURESULT,          FpuRes);
     10423    IEM_MC_LOCAL(RTFLOAT32U,            r32Val2);
     10424    IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes,        FpuRes,     0);
     10425    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value1,                 1);
     10426    IEM_MC_ARG_LOCAL_REF(PCRTFLOAT32U,  pr32Val2,       r32Val2,    2);
     10427
     10428    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
     10429    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     10430
     10431    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     10432    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     10433    IEM_MC_FETCH_MEM_R32(r32Val2, pIemCpu->iEffSeg, GCPtrEffSrc);
     10434
     10435    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     10436    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     10437    IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0)
     10438        IEM_MC_CALL_FPU_AIMPL_3(pfnAImpl, pFpuRes, pr80Value1, pr32Val2);
     10439        IEM_MC_STORE_FPU_RESULT(FpuRes, 0);
     10440    IEM_MC_ELSE()
     10441        IEM_MC_FPU_STACK_UNDERFLOW(0);
     10442    IEM_MC_ENDIF();
     10443    IEM_MC_ADVANCE_RIP();
     10444
     10445    IEM_MC_END();
     10446    return VINF_SUCCESS;
     10447}
     10448
     10449
    1034610450/** Opcode 0xd8 !11/0. */
    10347 FNIEMOP_STUB_1(iemOp_fadd_m32r,  uint8_t, bRm);
     10451FNIEMOP_DEF_1(iemOp_fadd_m32r,  uint8_t, bRm)
     10452{
     10453    IEMOP_MNEMONIC("fadd st0,m32r");
     10454    return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fadd_r80_by_r32);
     10455}
     10456
    1034810457
    1034910458/** Opcode 0xd8 !11/1. */
    10350 FNIEMOP_STUB_1(iemOp_fmul_m32r,  uint8_t, bRm);
     10459FNIEMOP_DEF_1(iemOp_fmul_m32r,  uint8_t, bRm)
     10460{
     10461    IEMOP_MNEMONIC("fmul st0,m32r");
     10462    return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fmul_r80_by_r32);
     10463}
     10464
    1035110465
    1035210466/** Opcode 0xd8 !11/2. */
    10353 FNIEMOP_STUB_1(iemOp_fcom_m32r,  uint8_t, bRm);
     10467FNIEMOP_DEF_1(iemOp_fcom_m32r,  uint8_t, bRm)
     10468{
     10469    IEMOP_MNEMONIC("fcom st0,m32r");
     10470
     10471    IEM_MC_BEGIN(3, 3);
     10472    IEM_MC_LOCAL(RTGCPTR,               GCPtrEffSrc);
     10473    IEM_MC_LOCAL(uint16_t,              u16FSW);
     10474    IEM_MC_LOCAL(RTFLOAT32U,            r32Val2);
     10475    IEM_MC_ARG_LOCAL_REF(uint16_t *,    pu16FSW,        u16FSW,     0);
     10476    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value1,                 1);
     10477    IEM_MC_ARG_LOCAL_REF(PCRTFLOAT32U,  pr32Val2,       r32Val2,    2);
     10478
     10479    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
     10480    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     10481
     10482    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     10483    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     10484    IEM_MC_FETCH_MEM_R32(r32Val2, pIemCpu->iEffSeg, GCPtrEffSrc);
     10485
     10486    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     10487    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     10488    IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0)
     10489        IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fcom_r80_by_r32, pu16FSW, pr80Value1, pr32Val2);
     10490        IEM_MC_UPDATE_FSW_WITH_MEM_OP(u16FSW, pIemCpu->iEffSeg, GCPtrEffSrc);
     10491    IEM_MC_ELSE()
     10492        IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(UINT8_MAX, pIemCpu->iEffSeg, GCPtrEffSrc);
     10493    IEM_MC_ENDIF();
     10494    IEM_MC_ADVANCE_RIP();
     10495
     10496    IEM_MC_END();
     10497    return VINF_SUCCESS;
     10498}
     10499
    1035410500
    1035510501/** Opcode 0xd8 !11/3. */
    10356 FNIEMOP_STUB_1(iemOp_fcomp_m32r, uint8_t, bRm);
     10502FNIEMOP_DEF_1(iemOp_fcomp_m32r, uint8_t, bRm)
     10503{
     10504    IEMOP_MNEMONIC("fcomp st0,m32r");
     10505
     10506    IEM_MC_BEGIN(3, 3);
     10507    IEM_MC_LOCAL(RTGCPTR,               GCPtrEffSrc);
     10508    IEM_MC_LOCAL(uint16_t,              u16FSW);
     10509    IEM_MC_LOCAL(RTFLOAT32U,            r32Val2);
     10510    IEM_MC_ARG_LOCAL_REF(uint16_t *,    pu16FSW,        u16FSW,     0);
     10511    IEM_MC_ARG(PCRTFLOAT80U,            pr80Value1,                 1);
     10512    IEM_MC_ARG_LOCAL_REF(PCRTFLOAT32U,  pr32Val2,       r32Val2,    2);
     10513
     10514    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
     10515    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     10516
     10517    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     10518    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     10519    IEM_MC_FETCH_MEM_R32(r32Val2, pIemCpu->iEffSeg, GCPtrEffSrc);
     10520
     10521    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     10522    IEM_MC_MAYBE_RAISE_FPU_XCPT();
     10523    IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value1, 0)
     10524        IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fcom_r80_by_r32, pu16FSW, pr80Value1, pr32Val2);
     10525        IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16FSW, pIemCpu->iEffSeg, GCPtrEffSrc);
     10526    IEM_MC_ELSE()
     10527        IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pIemCpu->iEffSeg, GCPtrEffSrc);
     10528    IEM_MC_ENDIF();
     10529    IEM_MC_ADVANCE_RIP();
     10530
     10531    IEM_MC_END();
     10532    return VINF_SUCCESS;
     10533}
     10534
    1035710535
    1035810536/** Opcode 0xd8 !11/4. */
    10359 FNIEMOP_STUB_1(iemOp_fsub_m32r,  uint8_t, bRm);
     10537FNIEMOP_DEF_1(iemOp_fsub_m32r,  uint8_t, bRm)
     10538{
     10539    IEMOP_MNEMONIC("fsub st0,m32r");
     10540    return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fsub_r80_by_r32);
     10541}
     10542
    1036010543
    1036110544/** Opcode 0xd8 !11/5. */
    10362 FNIEMOP_STUB_1(iemOp_fsubr_m32r, uint8_t, bRm);
     10545FNIEMOP_DEF_1(iemOp_fsubr_m32r, uint8_t, bRm)
     10546{
     10547    IEMOP_MNEMONIC("fsubr st0,m32r");
     10548    return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fsubr_r80_by_r32);
     10549}
     10550
    1036310551
    1036410552/** Opcode 0xd8 !11/6. */
    10365 FNIEMOP_STUB_1(iemOp_fdiv_m32r,  uint8_t, bRm);
     10553FNIEMOP_DEF_1(iemOp_fdiv_m32r,  uint8_t, bRm)
     10554{
     10555    IEMOP_MNEMONIC("fdiv st0,m32r");
     10556    return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fdiv_r80_by_r32);
     10557}
     10558
    1036610559
    1036710560/** Opcode 0xd8 !11/7. */
    10368 FNIEMOP_STUB_1(iemOp_fdivr_m32r, uint8_t, bRm);
     10561FNIEMOP_DEF_1(iemOp_fdivr_m32r, uint8_t, bRm)
     10562{
     10563    IEMOP_MNEMONIC("fdivr st0,m32r");
     10564    return FNIEMOP_CALL_2(iemOpHlpFpu_st0_m32r, bRm, iemAImpl_fdivr_r80_by_r32);
     10565}
     10566
    1036910567
    1037010568/** Opcode 0xd8. */
     
    1041210610{
    1041310611    IEMOP_MNEMONIC("fld m32r");
    10414     IEMOP_HLP_NO_LOCK_PREFIX();
    10415 
    10416     IEM_MC_BEGIN(2, 2);
     10612
     10613    IEM_MC_BEGIN(2, 3);
    1041710614    IEM_MC_LOCAL(RTGCPTR,               GCPtrEffSrc);
    1041810615    IEM_MC_LOCAL(IEMFPURESULT,          FpuRes);
     10616    IEM_MC_LOCAL(RTFLOAT32U,            r32Val);
    1041910617    IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes,    FpuRes, 0);
    10420     IEM_MC_ARG(RTFLOAT32U,              r32Val,            1);
     10618    IEM_MC_ARG_LOCAL_REF(PCRTFLOAT32U,  pr32Val,    r32Val, 1);
    1042110619
    1042210620    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
     10621    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     10622
    1042310623    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
    1042410624    IEM_MC_MAYBE_RAISE_FPU_XCPT();
    1042510625    IEM_MC_FETCH_MEM_R32(r32Val, pIemCpu->iEffSeg, GCPtrEffSrc);
    10426     IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fpu_r32_to_r80, pFpuRes, r32Val);
    10427 
    10428     IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pIemCpu->iEffSeg, GCPtrEffSrc);
     10626    IEM_MC_IF_FPUREG_IS_EMPTY(7)
     10627        IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fld_r32_to_r80, pFpuRes, pr32Val);
     10628        IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pIemCpu->iEffSeg, GCPtrEffSrc);
     10629    IEM_MC_ELSE()
     10630        IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(pIemCpu->iEffSeg, GCPtrEffSrc);
     10631    IEM_MC_ENDIF();
    1042910632    IEM_MC_ADVANCE_RIP();
    1043010633
     
    1076010963
    1076110964    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
    10762     IEM_MC_MEM_MAP(pi32Dst, IEM_ACCESS_DATA_W, pIemCpu->iEffSeg, GCPtrEffDst, 0 /*arg*/);
     10965    IEM_MC_MEM_MAP(pi32Dst, IEM_ACCESS_DATA_W, pIemCpu->iEffSeg, GCPtrEffDst, 1 /*arg*/);
    1076310966    IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0)
    1076410967        IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fpu_r80_to_i32, pu16FSW, pi32Dst, pr80Value);
    1076510968        IEM_MC_MEM_COMMIT_AND_UNMAP(pi32Dst, IEM_ACCESS_DATA_W);
    10766         IEM_MC_UPDATE_FSW_THEN_POP(u16FSW);
     10969        IEM_MC_UPDATE_FSW_WITH_MEM_OP_THEN_POP(u16FSW, pIemCpu->iEffSeg, GCPtrEffDst);
    1076710970    IEM_MC_ELSE()
    10768         IEM_MC_MEM_COMMIT_AND_UNMAP(pi32Dst, IEM_ACCESS_DATA_W);
    10769         IEM_MC_FPU_STACK_UNDERFLOW_THEN_POP(0);
     10971        IEM_MC_MEM_COMMIT_AND_UNMAP_UNLESS_FPU_XCPT(pi32Dst, IEM_ACCESS_DATA_W, u16FSW);
     10972        IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(UINT8_MAX, pIemCpu->iEffSeg, GCPtrEffDst);
    1077010973    IEM_MC_ENDIF();
    1077110974    IEM_MC_ADVANCE_RIP();
     
    1107811281{
    1107911282    IEMOP_MNEMONIC("fld m64r");
    11080     IEMOP_HLP_NO_LOCK_PREFIX();
    1108111283
    1108211284    IEM_MC_BEGIN(2, 3);
     
    1108511287    IEM_MC_LOCAL(RTFLOAT64U,            r64Val);
    1108611288    IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes,    FpuRes, 0);
    11087     IEM_MC_ARG_LOCAL_REF(PRTFLOAT64U,   pr64Val,    r64Val, 1);
     11289    IEM_MC_ARG_LOCAL_REF(PCRTFLOAT64U,  pr64Val,    r64Val, 1);
    1108811290
    1108911291    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
     11292    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     11293
    1109011294    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
    1109111295    IEM_MC_MAYBE_RAISE_FPU_XCPT();
    1109211296    IEM_MC_FETCH_MEM_R64(r64Val, pIemCpu->iEffSeg, GCPtrEffSrc);
    11093     IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fpu_r64_to_r80, pFpuRes, pr64Val);
    11094 
    11095     IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pIemCpu->iEffSeg, GCPtrEffSrc);
     11297    IEM_MC_IF_FPUREG_IS_EMPTY(7)
     11298        IEM_MC_CALL_FPU_AIMPL_2(iemAImpl_fld_r64_to_r80, pFpuRes, pr64Val);
     11299        IEM_MC_PUSH_FPU_RESULT_MEM_OP(FpuRes, pIemCpu->iEffSeg, GCPtrEffSrc);
     11300    IEM_MC_ELSE()
     11301        IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(pIemCpu->iEffSeg, GCPtrEffSrc);
     11302    IEM_MC_ENDIF();
    1109611303    IEM_MC_ADVANCE_RIP();
    1109711304
     
    1109911306    return VINF_SUCCESS;
    1110011307}
     11308
    1110111309
    1110211310/** Opcode 0xdd !11/0. */
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r40187 r40209  
    728728/** @name FPU operations taking a 32-bit float argument
    729729 * @{ */
    730 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR32,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, RTFLOAT32U r32Val));
     730typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR32U,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT32U pr32Val));
     731typedef FNIEMAIMPLFPUR32U  *PFNIEMAIMPLFPUR32U;
     732typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR32FSW,(PCX86FXSTATE pFpuState, uint16_t *pFSW,
     733                                                      PCRTFLOAT80U pr80Val1, PCRTFLOAT32U pr32Val2));
     734typedef FNIEMAIMPLFPUR32FSW *PFNIEMAIMPLFPUR32FSW;
     735typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR32,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
     736                                                   PCRTFLOAT80U pr80Val1, PCRTFLOAT32U pr32Val2));
    731737typedef FNIEMAIMPLFPUR32  *PFNIEMAIMPLFPUR32;
    732 FNIEMAIMPLFPUR32 iemAImpl_fpu_r32_to_r80;
     738
     739FNIEMAIMPLFPUR32U   iemAImpl_fld_r32_to_r80;
     740FNIEMAIMPLFPUR32FSW iemAImpl_fcom_r80_by_r32;
     741FNIEMAIMPLFPUR32    iemAImpl_fadd_r80_by_r32;
     742FNIEMAIMPLFPUR32    iemAImpl_fmul_r80_by_r32;
     743FNIEMAIMPLFPUR32    iemAImpl_fsub_r80_by_r32;
     744FNIEMAIMPLFPUR32    iemAImpl_fsubr_r80_by_r32;
     745FNIEMAIMPLFPUR32    iemAImpl_fdiv_r80_by_r32;
     746FNIEMAIMPLFPUR32    iemAImpl_fdivr_r80_by_r32;
    733747/** @} */
    734748
     
    737751typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR64,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
    738752                                                   PCRTFLOAT80U pr80Val1, PCRTFLOAT64U pr64Val2));
    739 typedef FNIEMAIMPLFPUR64  *PFNIEMAIMPLFPUR64;
     753typedef FNIEMAIMPLFPUR64   *PFNIEMAIMPLFPUR64;
    740754typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR64U,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT64U pr64Val));
    741755typedef FNIEMAIMPLFPUR64U  *PFNIEMAIMPLFPUR64U;
    742 FNIEMAIMPLFPUR64U iemAImpl_fpu_r64_to_r80;
     756
     757FNIEMAIMPLFPUR64U iemAImpl_fld_r64_to_r80;
    743758FNIEMAIMPLFPUR64  iemAImpl_fadd_r80_by_r64;
    744759FNIEMAIMPLFPUR64  iemAImpl_fmul_r80_by_r64;
     
    748763FNIEMAIMPLFPUR64  iemAImpl_fdiv_r80_by_r64;
    749764FNIEMAIMPLFPUR64  iemAImpl_fdivr_r80_by_r64;
    750 
    751765/** @} */
    752766
    753767/** @name FPU operations taking a 80-bit float argument
    754768 * @{ */
     769typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80FSW,(PCX86FXSTATE pFpuState, uint16_t *pFSW,
     770                                                      PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2));
     771typedef FNIEMAIMPLFPUR80FSW *PFNIEMAIMPLFPUR80FSW;
    755772typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
    756773                                                   PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2));
    757 typedef FNIEMAIMPLFPUR80  *PFNIEMAIMPLFPUR80;
    758 FNIEMAIMPLFPUR80  iemAImpl_fadd_r80_by_r80;
    759 FNIEMAIMPLFPUR80  iemAImpl_fmul_r80_by_r80;
    760 FNIEMAIMPLFPUR80  iemAImpl_fcom_r80_by_r80;
    761 FNIEMAIMPLFPUR80  iemAImpl_fsub_r80_by_r80;
    762 FNIEMAIMPLFPUR80  iemAImpl_fsubr_r80_by_r80;
    763 FNIEMAIMPLFPUR80  iemAImpl_fdiv_r80_by_r80;
    764 FNIEMAIMPLFPUR80  iemAImpl_fdivr_r80_by_r80;
    765 
     774typedef FNIEMAIMPLFPUR80    *PFNIEMAIMPLFPUR80;
     775
     776FNIEMAIMPLFPUR80FSW iemAImpl_fcom_r80_by_r80;
     777FNIEMAIMPLFPUR80    iemAImpl_fadd_r80_by_r80;
     778FNIEMAIMPLFPUR80    iemAImpl_fmul_r80_by_r80;
     779FNIEMAIMPLFPUR80    iemAImpl_fsub_r80_by_r80;
     780FNIEMAIMPLFPUR80    iemAImpl_fsubr_r80_by_r80;
     781FNIEMAIMPLFPUR80    iemAImpl_fdiv_r80_by_r80;
     782FNIEMAIMPLFPUR80    iemAImpl_fdivr_r80_by_r80;
    766783/** @} */
    767784
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r40199 r40209  
    160160#define iemAImpl_imul_u8    ((PFNIEMAIMPLMULDIVU8)0)
    161161#define iemAImpl_mul_u8     ((PFNIEMAIMPLMULDIVU8)0)
     162
     163#define iemAImpl_fpu_r32_to_r80         NULL
     164#define iemAImpl_fcom_r80_by_r32        NULL
     165#define iemAImpl_fadd_r80_by_r32        NULL
     166#define iemAImpl_fmul_r80_by_r32        NULL
     167#define iemAImpl_fsub_r80_by_r32        NULL
     168#define iemAImpl_fsubr_r80_by_r32       NULL
     169#define iemAImpl_fdiv_r80_by_r32        NULL
     170#define iemAImpl_fdivr_r80_by_r32       NULL
    162171
    163172#define iemAImpl_fpu_r64_to_r80         NULL
     
    407416#define IEM_MC_MEM_MAP_EX(a_pvMem, a_fAccess, a_cbMem, a_iSeg, a_GCPtrMem, a_iArg)  do {} while (0)
    408417#define IEM_MC_MEM_COMMIT_AND_UNMAP(a_pvMem, a_fAccess)                 do {} while (0)
     418#define IEM_MC_MEM_COMMIT_AND_UNMAP_UNLESS_FPU_XCPT(a_pvMem, a_fAccess, a_u16FSW)   do {} while (0)
    409419#define IEM_MC_CALC_RM_EFF_ADDR(a_GCPtrEff, bRm)                        do { (a_GCPtrEff) = 0; CHK_GCPTR(a_GCPtrEff); } while (0)
    410420#define IEM_MC_CALL_VOID_AIMPL_1(a_pfn, a0)                             do {} while (0)
     
    436446#define IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(a_iStReg, a_iEffSeg, a_GCPtrEff)                      do { } while (0)
    437447#define IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(a_iStReg, a_iEffSeg, a_GCPtrEff)             do { } while (0)
     448#define IEM_MC_FPU_STACK_PUSH_OVERFLOW()                                                        do { } while (0)
     449#define IEM_MC_FPU_STACK_PUSH_OVERFLOW_MEM_OP(a_iEffSeg, a_GCPtrEff)                            do { } while (0)
    438450#define IEM_MC_UPDATE_FSW(a_u16FSW)                                                             do { } while (0)
    439451#define IEM_MC_UPDATE_FSW_WITH_MEM_OP(a_u16FSW, a_iEffSeg, a_GCPtrEff)                          do { } while (0)
     
    461473#define IEM_MC_IF_GREG_BIT_SET(a_iGReg, a_iBitNo)                       if (g_fRandom) {
    462474#define IEM_MC_IF_FPUREG_NOT_EMPTY(a_iSt)                               if (g_fRandom) {
     475#define IEM_MC_IF_FPUREG_IS_EMPTY(a_iSt)                                if (g_fRandom) {
    463476#define IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(a_pr80Dst, a_iSt)            if (g_fRandom) {
    464477#define IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(p0, i0, p1, i1)         if (g_fRandom) {
  • trunk/src/VBox/VMM/testcase/tstX86-1.cpp

    r40199 r40209  
    255255            RTTestFailed(hTest, "x861_Test5 -> %d", rc);
    256256
     257#endif
    257258        RTTestSub(hTest, "Floating point exceptions ++");
    258259        rc = x861_Test7();
    259260        if (rc != 0)
    260261            RTTestFailed(hTest, "x861_Test6 -> %d", rc);
    261 #endif
    262262
    263263        rc = x861_TestFPUInstr1();
  • trunk/src/VBox/VMM/testcase/tstX86-1A.asm

    r40199 r40209  
    165165%endif
    166166
     167
     168;;
     169; Macro for checking a memory value.
     170;
     171; @param        1       The size (byte, word, dword, etc)
     172; @param        2       The memory address expression.
     173; @param        3       The valued expected at the location.
     174%macro CheckMemoryValue 3
     175        cmp     %1 [%2], %3
     176        je      %%ok
     177        mov     eax, __LINE__
     178        jmp     .return
     179%%ok:
     180%endmacro
     181
     182
    167183;;
    168184; Macro for recording a trapping instruction (simple).
     
    288304;; Checks that ST0 contains 3 & 1/3.
    289305%define CheckSt0Value_3_and_two_3rds    CheckSt0Value 0xaaaaaaab, 0xeaaaaaaa, 0x4000
     306;; Checks that ST0 contains 8.0.
     307%define CheckSt0Value_Eight             CheckSt0Value 0x00000000, 0x80000000, 0x4002
    290308
    291309
     
    643661
    644662;;
    645 ; Loads all general, MMX and SSE registers except xBP and xSP with unique values.
     663; Loads all MMX and SSE registers except xBP and xSP with unique values.
    646664;
    647665x861_LoadUniqueRegValuesSSE:
     
    673691        movdqu  xmm15, [REF(._xmm15)]
    674692%endif
    675         call    x861_LoadUniqueRegValues
    676693        ret
    677694._mm0:   times 8  db 040h
     
    23252342        FpuShouldTrap  X86_FSW_IE | X86_FSW_SF | X86_FSW_C1, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3, \
    23262343                fld     dword [xSI]
    2327         CheckSt0Value 0x00000000, 0x80000000, 0x4002
     2344        CheckSt0Value_Eight
    23282345
    23292346        FpuShouldTrap  X86_FSW_IE | X86_FSW_SF | X86_FSW_C1, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3, \
    23302347                fld     dword [xSI]
    2331         CheckSt0Value 0x00000000, 0x80000000, 0x4002
     2348        CheckSt0Value_Eight
    23322349
    23332350        ; stack overflow vs #PF.
     
    23382355        FpuShouldTrap  X86_FSW_IE | X86_FSW_SF | X86_FSW_C1, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3, \
    23392356                fld     dword [xSI]
    2340         CheckSt0Value 0x00000000, 0x80000000, 0x4002
     2357        CheckSt0Value_Eight
    23412358
    23422359        ;
     
    29562973        FxSaveCheckStNValueConst xSP, 1, REF(g_r80_DnMax)
    29572974        FxSaveCheckStNValueConst xSP, 0, REF(g_r80_DnMin)
    2958 %endif
    29592975
    29602976        ;
     
    30453061        FxSaveCheckFSW xSP, X86_FSW_IE | X86_FSW_SF | X86_FSW_ES | X86_FSW_B, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3
    30463062        FxSaveCheckSt0Empty xSP
     3063        FxSaveCheckStNValueConst xSP, 1, REF(g_r80_3dot2)
     3064        FxSaveCheckStNValueConst xSP, 2, REF(g_r80_0dot1)
     3065%endif
     3066
     3067        ;
     3068        ; FISTP M32I, ST0
     3069        ;
     3070        SetSubTest "FISTP M32I, ST0"
     3071
     3072        mov     xBX, [REF_EXTERN(g_pbEfExecPage)]
     3073        lea     xBX, [xBX + PAGE_SIZE - 4]
     3074
     3075        ; ## Normal operation. ##
     3076        FpuInitWithCW X86_FCW_PC_64 | X86_FCW_RC_NEAREST
     3077        fld     tword [REF(g_r80_Ten)]
     3078        FpuCheckOpcodeCsIp     { fistp dword [xBX] }
     3079        FxSaveCheckFSW xSP, 0, 0
     3080        FxSaveCheckSt0Empty xSP
     3081        CheckMemoryValue dword, xBX, 10
     3082
     3083        ; ## Masked exceptions. ##
     3084
     3085        ; Masked stack underflow.
     3086        fninit
     3087        FpuCheckOpcodeCsIp     { fistp dword [xBX] }
     3088        FxSaveCheckFSW xSP, X86_FSW_IE | X86_FSW_SF, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3
     3089        CheckMemoryValue dword, xBX, 0x80000000
     3090
     3091        fninit
     3092        fld     tword [REF(g_r80_0dot1)]
     3093        fld     tword [REF(g_r80_3dot2)]
     3094        fld     tword [REF(g_r80_Ten)]
     3095        ffree   st0
     3096        FpuCheckOpcodeCsIp     { fistp dword [xBX] }
     3097        FxSaveCheckFSW xSP, X86_FSW_IE | X86_FSW_SF, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3
     3098        CheckMemoryValue dword, xBX, 0x80000000
     3099        FxSaveCheckStNValueConst xSP, 0, REF(g_r80_3dot2)
     3100        FxSaveCheckStNValueConst xSP, 1, REF(g_r80_0dot1)
     3101
     3102        ; ## Unmasked exceptions. ##
     3103
     3104        ; Stack underflow - no pop or change.
     3105        FpuInitWithCW X86_FCW_PC_64 | X86_FCW_RC_NEAREST
     3106        fld     tword [REF(g_r80_0dot1)]
     3107        fld     tword [REF(g_r80_3dot2)]
     3108        fld     tword [REF(g_r80_Ten)]
     3109        ffree   st0
     3110        mov     dword [xBX], 0xffeeddcc
     3111        FpuTrapOpcodeCsIp      { fistp dword [xBX] }
     3112        FxSaveCheckFSW xSP, X86_FSW_IE | X86_FSW_SF | X86_FSW_ES | X86_FSW_B, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3
     3113        FxSaveCheckSt0Empty xSP
     3114        CheckMemoryValue dword, xBX, 0xffeeddcc
    30473115        FxSaveCheckStNValueConst xSP, 1, REF(g_r80_3dot2)
    30483116        FxSaveCheckStNValueConst xSP, 2, REF(g_r80_0dot1)
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