Changeset 40224 in vbox
- Timestamp:
- Feb 23, 2012 1:33:53 AM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 76401
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r40223 r40224 5769 5769 #define IEM_MC_CLEAR_HIGH_GREG_U64(a_iGReg) *(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) &= UINT32_MAX 5770 5770 #define IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(a_pu32Dst) do { (a_pu32Dst)[1] = 0; } while (0) 5771 #define IEM_MC_STORE_FPUREG_R80_SRC_REF(a_iSt, a_pr80Src) \ 5772 do { pIemCpu->CTX_SUFF(pCtx)->fpu.aRegs[a_iSt].r80 = *(a_pr80Src); } while (0) 5771 5773 5772 5774 #define IEM_MC_REF_GREG_U8(a_pu8Dst, a_iGReg) (a_pu8Dst) = iemGRegRefU8(pIemCpu, (a_iGReg)) -
trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
r40222 r40224 4258 4258 4259 4259 4260 4261 /** 4262 * Implements the underflow case of fxch. 4263 * 4264 * @param iStReg The other stack register. 4265 */ 4266 IEM_CIMPL_DEF_1(iemCImpl_fxch_underflow, uint8_t, iStReg) 4267 { 4268 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 4269 4270 unsigned const iReg1 = X86_FSW_TOP_GET(pCtx->fpu.FSW); 4271 unsigned const iReg2 = (iReg1 + iStReg) & X86_FSW_TOP_SMASK; 4272 Assert(!(RT_BIT(iReg1) & pCtx->fpu.FTW) || !(RT_BIT(iReg2) & pCtx->fpu.FTW)); 4273 4274 /** @todo Testcase: fxch underflow. Making assumptions that underflowed 4275 * registers are read as QNaN and then exchanged. This could be 4276 * wrong... */ 4277 if (pCtx->fpu.FCW & X86_FCW_IM) 4278 { 4279 if (RT_BIT(iReg1) & pCtx->fpu.FTW) 4280 { 4281 if (RT_BIT(iReg2) & pCtx->fpu.FTW) 4282 iemFpuStoreQNan(&pCtx->fpu.aRegs[0].r80); 4283 else 4284 pCtx->fpu.aRegs[0].r80 = pCtx->fpu.aRegs[iStReg].r80; 4285 iemFpuStoreQNan(&pCtx->fpu.aRegs[iStReg].r80); 4286 } 4287 else 4288 { 4289 pCtx->fpu.aRegs[iStReg].r80 = pCtx->fpu.aRegs[0].r80; 4290 iemFpuStoreQNan(&pCtx->fpu.aRegs[0].r80); 4291 } 4292 pCtx->fpu.FSW &= ~X86_FSW_C_MASK; 4293 pCtx->fpu.FSW |= X86_FSW_C1 | X86_FSW_IE | X86_FSW_SF; 4294 } 4295 else 4296 { 4297 /* raise underflow exception, don't change anything. */ 4298 pCtx->fpu.FSW &= ~(X86_FSW_TOP_MASK | X86_FSW_XCPT_MASK); 4299 pCtx->fpu.FSW |= X86_FSW_C1 | X86_FSW_IE | X86_FSW_SF | X86_FSW_ES | X86_FSW_B; 4300 } 4301 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx); 4302 4303 iemRegAddToRip(pIemCpu, cbInstr); 4304 return VINF_SUCCESS; 4305 } 4306 4260 4307 /** @} */ 4261 4308 -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
r40223 r40224 10808 10808 10809 10809 /** Opcode 0xd9 11/3 stN */ 10810 FNIEMOP_STUB_1(iemOp_fxch_stN, uint8_t, bRm); 10810 FNIEMOP_DEF_1(iemOp_fxch_stN, uint8_t, bRm) 10811 { 10812 IEMOP_MNEMONIC("fxch stN"); 10813 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); 10814 10815 /** @todo Testcase: Check if this raises \#MF? Intel mentioned it not. AMD 10816 * indicates that it does. */ 10817 IEM_MC_BEGIN(1, 3); 10818 IEM_MC_LOCAL(PCRTFLOAT80U, pr80Value1); 10819 IEM_MC_LOCAL(PCRTFLOAT80U, pr80Value2); 10820 IEM_MC_LOCAL(IEMFPURESULT, FpuRes); 10821 IEM_MC_ARG_CONST(uint8_t, iStReg, /*=*/ bRm & X86_MODRM_RM_MASK, 0); 10822 IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE(); 10823 IEM_MC_MAYBE_RAISE_FPU_XCPT(); 10824 IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(pr80Value1, 0, pr80Value2, bRm & X86_MODRM_RM_MASK) 10825 IEM_MC_SET_FPU_RESULT(FpuRes, X86_FSW_C1, pr80Value2); 10826 IEM_MC_STORE_FPUREG_R80_SRC_REF(bRm & X86_MODRM_RM_MASK, pr80Value1); 10827 IEM_MC_STORE_FPU_RESULT(FpuRes, 0); 10828 IEM_MC_ELSE() 10829 IEM_MC_CALL_CIMPL_1(iemCImpl_fxch_underflow, iStReg); 10830 IEM_MC_ENDIF(); 10831 IEM_MC_ADVANCE_RIP(); 10832 IEM_MC_END(); 10833 10834 return VINF_SUCCESS; 10835 } 10811 10836 10812 10837 -
trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp
r40223 r40224 306 306 #define IEM_MC_STORE_GREG_U32_CONST(a_iGReg, a_u32C) do { AssertCompile((uint32_t)(a_u32C) == (a_u32C)); } while (0) 307 307 #define IEM_MC_STORE_GREG_U64_CONST(a_iGReg, a_u64C) do { AssertCompile((uint64_t)(a_u64C) == (a_u64C)); } while (0) 308 #define IEM_MC_STORE_FPUREG_R80_SRC_REF(a_iSt, a_pr80Src) do { CHK_PTYPE(PCRTFLOAT80U, a_pr80Src); Assert((a_iSt) < 8); } while (0) 308 309 #define IEM_MC_CLEAR_HIGH_GREG_U64(a_iGReg) do { } while (0) 309 310 #define IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(a_pu32Dst) do { CHK_PTYPE(uint32_t *, a_pu32Dst); } while (0) … … 476 477 #define IEM_MC_IF_FPUREG_NOT_EMPTY(a_iSt) if (g_fRandom) { 477 478 #define IEM_MC_IF_FPUREG_IS_EMPTY(a_iSt) if (g_fRandom) { 478 #define IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(a_pr80Dst, a_iSt) if (g_fRandom) { 479 #define IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(p0, i0, p1, i1) if (g_fRandom) { 479 #define IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(a_pr80Dst, a_iSt) \ 480 a_pr80Dst = NULL; \ 481 if (g_fRandom) { 482 #define IEM_MC_IF_TWO_FPUREGS_NOT_EMPTY_REF_R80(p0, i0, p1, i1) \ 483 p0 = NULL; \ 484 p1 = NULL; \ 485 if (g_fRandom) { 480 486 #define IEM_MC_ELSE() } else { 481 487 #define IEM_MC_ENDIF() } do {} while (0)
Note:
See TracChangeset
for help on using the changeset viewer.