Changeset 40209 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Feb 22, 2012 12:14:21 PM (13 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r40199 r40209 3401 3401 3402 3402 3403 #if 0 3404 /** 3403 /** 3404 * Pushes a FPU result onto the FPU stack if no pending exception prevents it. 3405 3405 * 3406 3406 * @param pIemCpu The IEM per CPU data. 3407 3407 * @param pResult The FPU operation result to push. 3408 3408 * @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 */ 3410 static 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. */ 3420 3419 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; 3455 3425 3456 3426 iemFpuRotateStackPush(pCtx); 3457 }3458 3459 3460 /**3461 * Writes a FPU result to the FPU stack after inspecting the resulting3462 * 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 else3486 {3487 AssertFailed();3488 }3489 }3490 #endif3491 3492 3493 /**3494 * Pushes a FPU result onto the FPU stack after inspecting the resulting3495 * 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 else3521 {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 else3535 {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 resulting3548 * 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);3559 3427 } 3560 3428 … … 3622 3490 3623 3491 /** 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 */ 3497 static 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 */ 3514 static 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 /** 3624 3524 * Stores a result in a FPU register, updates the FSW, FTW, FPUIP, FPUCS, and 3625 3525 * FOP. … … 3762 3662 3763 3663 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 */ 3764 3671 static void iemFpuStackUnderflowOnly(PIEMCPU pIemCpu, uint8_t iStReg, PCPUMCTX pCtx) 3765 3672 { 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); 3768 3674 if (pCtx->fpu.FCW & X86_FCW_IM) 3769 3675 { … … 3771 3677 pCtx->fpu.FSW &= ~(X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3); 3772 3678 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 } 3775 3685 } 3776 3686 else … … 3781 3691 } 3782 3692 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 */ 3783 3702 DECL_NO_INLINE(static, void) iemFpuStackUnderflow(PIEMCPU pIemCpu, uint8_t iStReg) 3784 3703 { … … 3819 3738 3820 3739 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 */ 3746 static 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 */ 3773 DECL_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 */ 3788 DECL_NO_INLINE(static, void) 3789 iemFpuStackPushOverflowWithMemOp(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 3798 static int iemFpuStRegNotEmpty(PIEMCPU pIemCpu, uint8_t iStReg) 3822 3799 { 3823 3800 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); … … 3829 3806 3830 3807 3831 static int iemFpuStRegNo nEmptyRef(PIEMCPU pIemCpu, uint8_t iStReg, PCRTFLOAT80U *ppRef)3808 static int iemFpuStRegNotEmptyRef(PIEMCPU pIemCpu, uint8_t iStReg, PCRTFLOAT80U *ppRef) 3832 3809 { 3833 3810 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); … … 3842 3819 3843 3820 3844 static int iemFpu2StRegsNo nEmptyRef(PIEMCPU pIemCpu, uint8_t iStReg0, PCRTFLOAT80U *ppRef0,3821 static int iemFpu2StRegsNotEmptyRef(PIEMCPU pIemCpu, uint8_t iStReg0, PCRTFLOAT80U *ppRef0, 3845 3822 uint8_t iStReg1, PCRTFLOAT80U *ppRef1) 3846 3823 { … … 5901 5878 IEM_MC_RETURN_ON_FAILURE(iemMemCommitAndUnmap(pIemCpu, (a_pvMem), (a_fAccess))) 5902 5879 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 5903 5890 /** Calculate efficient address from R/M. */ 5904 5891 #define IEM_MC_CALC_RM_EFF_ADDR(a_GCPtrEff, bRm) \ … … 6082 6069 iemFpuUpdateFSWWithMemOpThenPop(pIemCpu, a_u16FSW, a_iEffSeg, a_GCPtrEff) 6083 6070 6084 /** Raises a FPU stack underflow .Sets FPUIP, FPUCS and FOP. */6071 /** Raises a FPU stack underflow exception. Sets FPUIP, FPUCS and FOP. */ 6085 6072 #define IEM_MC_FPU_STACK_UNDERFLOW(a_iStDst) \ 6086 6073 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. */ 6088 6076 #define IEM_MC_FPU_STACK_UNDERFLOW_THEN_POP(a_iStDst) \ 6089 6077 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. */ 6091 6080 #define IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(a_iStDst, a_iEffSeg, a_GCPtrEff) \ 6092 6081 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. */ 6095 6084 #define IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP_THEN_POP(a_iStDst, a_iEffSeg, a_GCPtrEff) \ 6096 6085 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) 6097 6095 6098 6096 … … 6139 6137 #define IEM_MC_IF_GREG_BIT_SET(a_iGReg, a_iBitNo) if (*(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) & RT_BIT_64(a_iBitNo)) { 6140 6138 #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) { 6142 6142 #define IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(a_pr80Dst, a_iSt) \ 6143 if (iemFpuStRegNo nEmptyRef(pIemCpu, (a_iSt), &(a_pr80Dst)) == VINF_SUCCESS) {6143 if (iemFpuStRegNotEmptyRef(pIemCpu, (a_iSt), &(a_pr80Dst)) == VINF_SUCCESS) { 6144 6144 #define IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(a_pr80Dst0, a_iSt0, a_pr80Dst1, a_iSt1) \ 6145 if (iemFpu2StRegsNo nEmptyRef(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) { 6146 6146 6147 6147 #define IEM_MC_ELSE() } else { -
trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm
r40165 r40209 1278 1278 1279 1279 1280 %macro FPU_SAFE_INIT 11281 fninit1282 movzx T0, word [%1 + X86FXSTATE.FCW]1283 and T0, X86_FCW_MASK_ALL | X86_FCW_PC_MASK | X86_FCW_RC_MASK1284 or T0, X86_FCW_MASK_ALL1285 mov [xSP], T01286 fldcw [xSP]1287 %endmacro1288 1289 1280 ;; 1290 1281 ; Initialize the FPU for the actual instruction being emulated, this means … … 1324 1315 1325 1316 ;; 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, 121333 PROLOGUE_3_ARGS1334 sub xSP, 20h1335 1336 FPU_SAFE_INIT A01337 mov [xSP], A21338 fld dword [xSP]1339 1340 fnstsw word [A1 + IEMFPURESULT.FSW]1341 fstp tword [A1 + IEMFPURESULT.r80Result]1342 1343 add xSP, 20h1344 EPILOGUE_3_ARGS 01345 ENDPROC iemAImpl_fpu_r32_to_r801346 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, 121356 PROLOGUE_3_ARGS1357 sub xSP, 20h1358 1359 FPU_SAFE_INIT A01360 fld qword [A2]1361 1362 fnstsw word [A1 + IEMFPURESULT.FSW]1363 fstp tword [A1 + IEMFPURESULT.r80Result]1364 1365 add xSP, 20h1366 EPILOGUE_3_ARGS 01367 ENDPROC iemAImpl_fpu_r64_to_r801368 1369 ;;1370 1317 ; Converts a 80-bit floating point value to a 32-bit signed integer. 1371 1318 ; … … 1393 1340 1394 1341 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 ; 1353 BEGINPROC_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 1368 ENDPROC 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 ; 1379 BEGINPROC_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 1393 ENDPROC 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 1407 BEGINPROC_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 1423 ENDPROC iemAImpl_ %+ %1 %+ _r80_by_r32 1424 %endmacro 1425 1426 IEMIMPL_FPU_R80_BY_R32 fadd 1427 IEMIMPL_FPU_R80_BY_R32 fmul 1428 IEMIMPL_FPU_R80_BY_R32 fsub 1429 IEMIMPL_FPU_R80_BY_R32 fsubr 1430 IEMIMPL_FPU_R80_BY_R32 fdiv 1431 IEMIMPL_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 1446 BEGINPROC_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 1460 ENDPROC iemAImpl_ %+ %1 %+ _r80_by_r32 1461 %endmacro 1462 1463 IEMIMPL_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 ; 1478 BEGINPROC_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 1492 ENDPROC 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 ; 1503 BEGINPROC_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 1517 ENDPROC iemAImpl_fst_r80_to_r64 1518 1519 1395 1520 ;; 1396 1521 ; FPU instruction working on one 80-bit and one 64-bit floating point value. … … 1417 1542 fstp tword [A1 + IEMFPURESULT.r80Result] 1418 1543 1544 fninit 1419 1545 add xSP, 20h 1420 1546 EPILOGUE_4_ARGS 8 … … 1424 1550 IEMIMPL_FPU_R80_BY_R64 fadd 1425 1551 IEMIMPL_FPU_R80_BY_R64 fmul 1426 IEMIMPL_FPU_R80_BY_R64 fcom1427 1552 IEMIMPL_FPU_R80_BY_R64 fsub 1428 1553 IEMIMPL_FPU_R80_BY_R64 fsubr … … 1430 1555 IEMIMPL_FPU_R80_BY_R64 fdivr 1431 1556 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 1569 BEGINPROC_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 1583 ENDPROC iemAImpl_ %+ %1 %+ _r80_by_r64 1584 %endmacro 1585 1586 IEMIMPL_FPU_R80_BY_R64_FSW fcom 1587 1588 1589 1590 ; 1591 ;---------------------- 80-bit floating point operations ---------------------- 1592 ; 1432 1593 1433 1594 ;; … … 1456 1617 fstp tword [A1 + IEMFPURESULT.r80Result] 1457 1618 1619 fninit 1458 1620 add xSP, 20h 1459 1621 EPILOGUE_4_ARGS 8 … … 1467 1629 IEMIMPL_FPU_R80_BY_R80 fdiv 1468 1630 IEMIMPL_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 1645 BEGINPROC_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 1660 ENDPROC iemAImpl_ %+ %1 %+ _r80_by_r80 1661 %endmacro 1662 1663 IEMIMPL_FPU_R80_BY_R80_FSW fcom 1664 IEMIMPL_FPU_R80_BY_R80_FSW fucom 1665 -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
r40199 r40209 10261 10261 FNIEMOP_DEF_2(iemOpHlpFpu_st0_stN, uint8_t, bRm, PFNIEMAIMPLFPUR80, pfnAImpl) 10262 10262 { 10263 IEMOP_HLP_ NO_LOCK_PREFIX();10263 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); 10264 10264 10265 10265 IEM_MC_BEGIN(3, 1); … … 10284 10284 10285 10285 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 */ 10292 FNIEMOP_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 */ 10323 FNIEMOP_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 10286 10348 /** Opcode 0xd8 11/0. */ 10287 10349 FNIEMOP_DEF_1(iemOp_fadd_stN, uint8_t, bRm) … … 10303 10365 FNIEMOP_DEF_1(iemOp_fcom_stN, uint8_t, bRm) 10304 10366 { 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); 10308 10369 } 10309 10370 10310 10371 10311 10372 /** Opcode 0xd8 11/3. */ 10312 FNIEMOP_STUB_1(iemOp_fcomp_stN, uint8_t, bRm); 10373 FNIEMOP_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 10313 10379 10314 10380 /** Opcode 0xd8 11/4. */ … … 10344 10410 10345 10411 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 */ 10418 FNIEMOP_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 10346 10450 /** Opcode 0xd8 !11/0. */ 10347 FNIEMOP_STUB_1(iemOp_fadd_m32r, uint8_t, bRm); 10451 FNIEMOP_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 10348 10457 10349 10458 /** Opcode 0xd8 !11/1. */ 10350 FNIEMOP_STUB_1(iemOp_fmul_m32r, uint8_t, bRm); 10459 FNIEMOP_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 10351 10465 10352 10466 /** Opcode 0xd8 !11/2. */ 10353 FNIEMOP_STUB_1(iemOp_fcom_m32r, uint8_t, bRm); 10467 FNIEMOP_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 10354 10500 10355 10501 /** Opcode 0xd8 !11/3. */ 10356 FNIEMOP_STUB_1(iemOp_fcomp_m32r, uint8_t, bRm); 10502 FNIEMOP_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 10357 10535 10358 10536 /** Opcode 0xd8 !11/4. */ 10359 FNIEMOP_STUB_1(iemOp_fsub_m32r, uint8_t, bRm); 10537 FNIEMOP_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 10360 10543 10361 10544 /** Opcode 0xd8 !11/5. */ 10362 FNIEMOP_STUB_1(iemOp_fsubr_m32r, uint8_t, bRm); 10545 FNIEMOP_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 10363 10551 10364 10552 /** Opcode 0xd8 !11/6. */ 10365 FNIEMOP_STUB_1(iemOp_fdiv_m32r, uint8_t, bRm); 10553 FNIEMOP_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 10366 10559 10367 10560 /** Opcode 0xd8 !11/7. */ 10368 FNIEMOP_STUB_1(iemOp_fdivr_m32r, uint8_t, bRm); 10561 FNIEMOP_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 10369 10567 10370 10568 /** Opcode 0xd8. */ … … 10412 10610 { 10413 10611 IEMOP_MNEMONIC("fld m32r"); 10414 IEMOP_HLP_NO_LOCK_PREFIX(); 10415 10416 IEM_MC_BEGIN(2, 2); 10612 10613 IEM_MC_BEGIN(2, 3); 10417 10614 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc); 10418 10615 IEM_MC_LOCAL(IEMFPURESULT, FpuRes); 10616 IEM_MC_LOCAL(RTFLOAT32U, r32Val); 10419 10617 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); 10421 10619 10422 10620 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm); 10621 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); 10622 10423 10623 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE(); 10424 10624 IEM_MC_MAYBE_RAISE_FPU_XCPT(); 10425 10625 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(); 10429 10632 IEM_MC_ADVANCE_RIP(); 10430 10633 … … 10760 10963 10761 10964 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*/); 10763 10966 IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(pr80Value, 0) 10764 10967 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fpu_r80_to_i32, pu16FSW, pi32Dst, pr80Value); 10765 10968 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); 10767 10970 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); 10770 10973 IEM_MC_ENDIF(); 10771 10974 IEM_MC_ADVANCE_RIP(); … … 11078 11281 { 11079 11282 IEMOP_MNEMONIC("fld m64r"); 11080 IEMOP_HLP_NO_LOCK_PREFIX();11081 11283 11082 11284 IEM_MC_BEGIN(2, 3); … … 11085 11287 IEM_MC_LOCAL(RTFLOAT64U, r64Val); 11086 11288 IEM_MC_ARG_LOCAL_REF(PIEMFPURESULT, pFpuRes, FpuRes, 0); 11087 IEM_MC_ARG_LOCAL_REF(P RTFLOAT64U,pr64Val, r64Val, 1);11289 IEM_MC_ARG_LOCAL_REF(PCRTFLOAT64U, pr64Val, r64Val, 1); 11088 11290 11089 11291 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm); 11292 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); 11293 11090 11294 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE(); 11091 11295 IEM_MC_MAYBE_RAISE_FPU_XCPT(); 11092 11296 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(); 11096 11303 IEM_MC_ADVANCE_RIP(); 11097 11304 … … 11099 11306 return VINF_SUCCESS; 11100 11307 } 11308 11101 11309 11102 11310 /** Opcode 0xdd !11/0. */ -
trunk/src/VBox/VMM/include/IEMInternal.h
r40187 r40209 728 728 /** @name FPU operations taking a 32-bit float argument 729 729 * @{ */ 730 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR32,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, RTFLOAT32U r32Val)); 730 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR32U,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT32U pr32Val)); 731 typedef FNIEMAIMPLFPUR32U *PFNIEMAIMPLFPUR32U; 732 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR32FSW,(PCX86FXSTATE pFpuState, uint16_t *pFSW, 733 PCRTFLOAT80U pr80Val1, PCRTFLOAT32U pr32Val2)); 734 typedef FNIEMAIMPLFPUR32FSW *PFNIEMAIMPLFPUR32FSW; 735 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR32,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, 736 PCRTFLOAT80U pr80Val1, PCRTFLOAT32U pr32Val2)); 731 737 typedef FNIEMAIMPLFPUR32 *PFNIEMAIMPLFPUR32; 732 FNIEMAIMPLFPUR32 iemAImpl_fpu_r32_to_r80; 738 739 FNIEMAIMPLFPUR32U iemAImpl_fld_r32_to_r80; 740 FNIEMAIMPLFPUR32FSW iemAImpl_fcom_r80_by_r32; 741 FNIEMAIMPLFPUR32 iemAImpl_fadd_r80_by_r32; 742 FNIEMAIMPLFPUR32 iemAImpl_fmul_r80_by_r32; 743 FNIEMAIMPLFPUR32 iemAImpl_fsub_r80_by_r32; 744 FNIEMAIMPLFPUR32 iemAImpl_fsubr_r80_by_r32; 745 FNIEMAIMPLFPUR32 iemAImpl_fdiv_r80_by_r32; 746 FNIEMAIMPLFPUR32 iemAImpl_fdivr_r80_by_r32; 733 747 /** @} */ 734 748 … … 737 751 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR64,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, 738 752 PCRTFLOAT80U pr80Val1, PCRTFLOAT64U pr64Val2)); 739 typedef FNIEMAIMPLFPUR64 *PFNIEMAIMPLFPUR64;753 typedef FNIEMAIMPLFPUR64 *PFNIEMAIMPLFPUR64; 740 754 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR64U,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT64U pr64Val)); 741 755 typedef FNIEMAIMPLFPUR64U *PFNIEMAIMPLFPUR64U; 742 FNIEMAIMPLFPUR64U iemAImpl_fpu_r64_to_r80; 756 757 FNIEMAIMPLFPUR64U iemAImpl_fld_r64_to_r80; 743 758 FNIEMAIMPLFPUR64 iemAImpl_fadd_r80_by_r64; 744 759 FNIEMAIMPLFPUR64 iemAImpl_fmul_r80_by_r64; … … 748 763 FNIEMAIMPLFPUR64 iemAImpl_fdiv_r80_by_r64; 749 764 FNIEMAIMPLFPUR64 iemAImpl_fdivr_r80_by_r64; 750 751 765 /** @} */ 752 766 753 767 /** @name FPU operations taking a 80-bit float argument 754 768 * @{ */ 769 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80FSW,(PCX86FXSTATE pFpuState, uint16_t *pFSW, 770 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2)); 771 typedef FNIEMAIMPLFPUR80FSW *PFNIEMAIMPLFPUR80FSW; 755 772 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, 756 773 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 774 typedef FNIEMAIMPLFPUR80 *PFNIEMAIMPLFPUR80; 775 776 FNIEMAIMPLFPUR80FSW iemAImpl_fcom_r80_by_r80; 777 FNIEMAIMPLFPUR80 iemAImpl_fadd_r80_by_r80; 778 FNIEMAIMPLFPUR80 iemAImpl_fmul_r80_by_r80; 779 FNIEMAIMPLFPUR80 iemAImpl_fsub_r80_by_r80; 780 FNIEMAIMPLFPUR80 iemAImpl_fsubr_r80_by_r80; 781 FNIEMAIMPLFPUR80 iemAImpl_fdiv_r80_by_r80; 782 FNIEMAIMPLFPUR80 iemAImpl_fdivr_r80_by_r80; 766 783 /** @} */ 767 784 -
trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp
r40199 r40209 160 160 #define iemAImpl_imul_u8 ((PFNIEMAIMPLMULDIVU8)0) 161 161 #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 162 171 163 172 #define iemAImpl_fpu_r64_to_r80 NULL … … 407 416 #define IEM_MC_MEM_MAP_EX(a_pvMem, a_fAccess, a_cbMem, a_iSeg, a_GCPtrMem, a_iArg) do {} while (0) 408 417 #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) 409 419 #define IEM_MC_CALC_RM_EFF_ADDR(a_GCPtrEff, bRm) do { (a_GCPtrEff) = 0; CHK_GCPTR(a_GCPtrEff); } while (0) 410 420 #define IEM_MC_CALL_VOID_AIMPL_1(a_pfn, a0) do {} while (0) … … 436 446 #define IEM_MC_FPU_STACK_UNDERFLOW_MEM_OP(a_iStReg, a_iEffSeg, a_GCPtrEff) do { } while (0) 437 447 #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) 438 450 #define IEM_MC_UPDATE_FSW(a_u16FSW) do { } while (0) 439 451 #define IEM_MC_UPDATE_FSW_WITH_MEM_OP(a_u16FSW, a_iEffSeg, a_GCPtrEff) do { } while (0) … … 461 473 #define IEM_MC_IF_GREG_BIT_SET(a_iGReg, a_iBitNo) if (g_fRandom) { 462 474 #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) { 463 476 #define IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(a_pr80Dst, a_iSt) if (g_fRandom) { 464 477 #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 255 255 RTTestFailed(hTest, "x861_Test5 -> %d", rc); 256 256 257 #endif 257 258 RTTestSub(hTest, "Floating point exceptions ++"); 258 259 rc = x861_Test7(); 259 260 if (rc != 0) 260 261 RTTestFailed(hTest, "x861_Test6 -> %d", rc); 261 #endif262 262 263 263 rc = x861_TestFPUInstr1(); -
trunk/src/VBox/VMM/testcase/tstX86-1A.asm
r40199 r40209 165 165 %endif 166 166 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 167 183 ;; 168 184 ; Macro for recording a trapping instruction (simple). … … 288 304 ;; Checks that ST0 contains 3 & 1/3. 289 305 %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 290 308 291 309 … … 643 661 644 662 ;; 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. 646 664 ; 647 665 x861_LoadUniqueRegValuesSSE: … … 673 691 movdqu xmm15, [REF(._xmm15)] 674 692 %endif 675 call x861_LoadUniqueRegValues676 693 ret 677 694 ._mm0: times 8 db 040h … … 2325 2342 FpuShouldTrap X86_FSW_IE | X86_FSW_SF | X86_FSW_C1, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3, \ 2326 2343 fld dword [xSI] 2327 CheckSt0Value 0x00000000, 0x80000000, 0x40022344 CheckSt0Value_Eight 2328 2345 2329 2346 FpuShouldTrap X86_FSW_IE | X86_FSW_SF | X86_FSW_C1, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3, \ 2330 2347 fld dword [xSI] 2331 CheckSt0Value 0x00000000, 0x80000000, 0x40022348 CheckSt0Value_Eight 2332 2349 2333 2350 ; stack overflow vs #PF. … … 2338 2355 FpuShouldTrap X86_FSW_IE | X86_FSW_SF | X86_FSW_C1, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3, \ 2339 2356 fld dword [xSI] 2340 CheckSt0Value 0x00000000, 0x80000000, 0x40022357 CheckSt0Value_Eight 2341 2358 2342 2359 ; … … 2956 2973 FxSaveCheckStNValueConst xSP, 1, REF(g_r80_DnMax) 2957 2974 FxSaveCheckStNValueConst xSP, 0, REF(g_r80_DnMin) 2958 %endif2959 2975 2960 2976 ; … … 3045 3061 FxSaveCheckFSW xSP, X86_FSW_IE | X86_FSW_SF | X86_FSW_ES | X86_FSW_B, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 3046 3062 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 3047 3115 FxSaveCheckStNValueConst xSP, 1, REF(g_r80_3dot2) 3048 3116 FxSaveCheckStNValueConst xSP, 2, REF(g_r80_0dot1)
Note:
See TracChangeset
for help on using the changeset viewer.