Changeset 40143 in vbox
- Timestamp:
- Feb 16, 2012 10:08:06 AM (13 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r40141 r40143 39 39 * 40 40 * The current code is very much work in progress. You've been warned! 41 * 42 * 43 * @section sec_iem_fpu_instr FPU Instructions 44 * 45 * On x86 and AMD64 hosts, the FPU instructions are implemented by executing the 46 * same or equivalent instructions on the host FPU. To make life easy, we also 47 * let the FPU prioritize the unmasked exceptions for us. This however, only 48 * works reliably when CR0.NE is set, i.e. when using \#MF instead the IRQ 13 49 * for FPU exception delivery, because with CR0.NE=0 there is a window where we 50 * can trigger spurious FPU exceptions. 51 * 41 52 * 42 53 */ … … 3529 3540 3530 3541 3542 /** 3543 * Stores a result in a FPU register and updates the FSW and FTW. 3544 * 3545 * @param pIemCpu The IEM per CPU data. 3546 * @param pResult The result to store. 3547 * @param iStReg Which FPU register to store it in. 3548 * @param pCtx The CPU context. 3549 */ 3550 static void iemFpuStoreResultOnly(PIEMCPU pIemCpu, PIEMFPURESULT pResult, uint8_t iStReg, PCPUMCTX pCtx) 3551 { 3552 Assert(iStReg < 8); 3553 uint16_t iReg = (X86_FSW_TOP_GET(pCtx->fpu.FSW) + iStReg) & X86_FSW_TOP_SMASK; 3554 pCtx->fpu.FSW &= X86_FSW_C_MASK; 3555 pCtx->fpu.FSW |= pResult->FSW & ~X86_FSW_TOP_MASK; 3556 pCtx->fpu.FTW |= RT_BIT(iReg); 3557 pCtx->fpu.aRegs[iStReg].r80 = pResult->r80Result; 3558 } 3559 3560 3561 /** 3562 * Stores a result in a FPU register, updates the FSW, FTW, FPUIP, FPUCS, and 3563 * FOP. 3564 * 3565 * @param pIemCpu The IEM per CPU data. 3566 * @param pResult The result to store. 3567 * @param iStReg Which FPU register to store it in. 3568 * @param pCtx The CPU context. 3569 */ 3531 3570 static void iemFpuStoreResult(PIEMCPU pIemCpu, PIEMFPURESULT pResult, uint8_t iStReg) 3532 3571 { 3533 } 3534 3572 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 3573 iemFpuUpdateOpcodeAndIP(pIemCpu, pCtx); 3574 iemFpuStoreResultOnly(pIemCpu, pResult, iStReg, pCtx); 3575 } 3576 3577 3578 /** 3579 * Stores a result in a FPU register, updates the FSW, FTW, FPUIP, FPUCS, FOP, 3580 * FPUDP, and FPUDS. 3581 * 3582 * @param pIemCpu The IEM per CPU data. 3583 * @param pResult The result to store. 3584 * @param iStReg Which FPU register to store it in. 3585 * @param pCtx The CPU context. 3586 */ 3535 3587 static void iemFpuStoreResultWithMemOp(PIEMCPU pIemCpu, PIEMFPURESULT pResult, uint8_t iStReg, uint8_t iEffSeg, RTGCPTR GCPtrEff) 3536 3588 { 3589 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 3537 3590 iemFpuUpdateDP(pIemCpu, pIemCpu->CTX_SUFF(pCtx), iEffSeg, GCPtrEff); 3538 //iemFpuStoreResult(pIemCpu, pResult); 3591 iemFpuUpdateOpcodeAndIP(pIemCpu, pCtx); 3592 iemFpuStoreResultOnly(pIemCpu, pResult, iStReg, pCtx); 3539 3593 } 3540 3594 -
trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm
r40138 r40143 1281 1281 fninit 1282 1282 movzx T0, word [%1 + X86FXSTATE.FCW] 1283 and T0, X86_FCW_MASK_ALL | X86_FCW_PC_MASK | X86_FCW_RC_MASK 1283 1284 or T0, X86_FCW_MASK_ALL 1284 1285 mov [xSP], T0 … … 1287 1288 1288 1289 ;; 1290 ; Initialize the FPU for x87 operation, loading the guest's status word. 1291 ; 1292 ; @param 1 Expression giving the address of the FXSTATE of the guest. 1293 %macro FPU_INIT 1 1294 fninit 1295 movzx T0, word [%1 + X86FXSTATE.FCW] 1296 and T0, X86_FCW_MASK_ALL | X86_FCW_PC_MASK | X86_FCW_RC_MASK 1297 mov [xSP], T0 1298 fldcw [xSP] 1299 %endmacro 1300 1301 ;; 1289 1302 ; Need to move this as well somewhere better? 1290 1303 ; … … 1323 1336 ; @param A0 FPU context (fxsave). 1324 1337 ; @param A1 Pointer to a IEMFPURESULT for the output. 1325 ; @param A2 Pointer to the 32-bit floating point value to convert.1338 ; @param A2 Pointer to the 64-bit floating point value to convert. 1326 1339 ; 1327 1340 BEGINPROC_FASTCALL iemAImpl_fpu_r64_to_r80, 12 … … 1339 1352 ENDPROC iemAImpl_fpu_r64_to_r80 1340 1353 1354 1355 ;; 1356 ; FDIV with 64-bit floating point value. 1357 ; 1358 ; @param A0 FPU context (fxsave). 1359 ; @param A1 Pointer to a IEMFPURESULT for the output. 1360 ; @param A2 Pointer to the 80-bit dividend. 1361 ; @param A3 Pointer to the 64-bit divisor. 1362 ; 1363 BEGINPROC_FASTCALL iemAImpl_fpu_fdiv_r80_by_r64, 16 1364 PROLOGUE_4_ARGS 1365 sub xSP, 20h 1366 1367 FPU_INIT A0 1368 fdiv qword [A3] 1369 1370 fnstsw word [A1 + IEMFPURESULT.FSW] 1371 fnclex 1372 fstp tword [A1 + IEMFPURESULT.r80Result] 1373 1374 add xSP, 20h 1375 EPILOGUE_4_ARGS 8 1376 ENDPROC iemAImpl_fpu_fdiv_r80_by_r64 1377 -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
r40141 r40143 10842 10842 IEM_MC_MAYBE_RAISE_FPU_XCPT(); 10843 10843 IEM_MC_FETCH_MEM_R64(r64Divisor, pIemCpu->iEffSeg, GCPtrEffSrc); 10844 IEM_MC_REF_FPUREG_R80(pr80Dividend, 0); 10845 //IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fpu_fdiv_r80_by_r64, pFpuRes, pr80Dividend, pr64Divisor);10844 IEM_MC_REF_FPUREG_R80(pr80Dividend, 0); /** @todo Check for and handle stack underflow! */ 10845 IEM_MC_CALL_FPU_AIMPL_3(iemAImpl_fpu_fdiv_r80_by_r64, pFpuRes, pr80Dividend, pr64Divisor); 10846 10846 10847 10847 IEM_MC_STORE_FPU_RESULT_MEM_OP(FpuRes, 0, pIemCpu->iEffSeg, GCPtrEffSrc); -
trunk/src/VBox/VMM/include/IEMInternal.h
r40093 r40143 718 718 /** @name FPU operations taking a 64-bit float argument 719 719 * @{ */ 720 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR64,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT64U pr64Val)); 720 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR64,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, 721 PCRTFLOAT80U pr80Val1, PCRTFLOAT64U pr64Val2)); 721 722 typedef FNIEMAIMPLFPUR64 *PFNIEMAIMPLFPUR64; 722 FNIEMAIMPLFPUR64 iemAImpl_fpu_r64_to_r80; 723 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR64U,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT64U pr64Val)); 724 typedef FNIEMAIMPLFPUR64U *PFNIEMAIMPLFPUR64U; 725 FNIEMAIMPLFPUR64U iemAImpl_fpu_r64_to_r80; 726 FNIEMAIMPLFPUR64 iemAImpl_fpu_fdiv_r80_by_r64; 727 723 728 /** @} */ 724 729 -
trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp
r40141 r40143 402 402 403 403 #define IEM_MC_CALL_FPU_AIMPL_2(a_pfnAImpl, a0, a1) do { } while (0) 404 #define IEM_MC_CALL_FPU_AIMPL_3(a_pfnAImpl, a0, a1, a3) do { } while (0) 404 405 #define IEM_MC_PUSH_FPU_RESULT(a_FpuData) do { } while (0) 405 406 #define IEM_MC_PUSH_FPU_RESULT_MEM_OP(a_FpuData, a_iEffSeg, a_GCPtrEff) do { } while (0)
Note:
See TracChangeset
for help on using the changeset viewer.