Changeset 40251 in vbox
- Timestamp:
- Feb 24, 2012 9:24:23 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 76465
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm
r40250 r40251 2055 2055 2056 2056 ;; 2057 ; FPU instruction working on two 80-bit floating point values, 2058 ; returning FSW and EFLAGS (eax). 2059 ; 2060 ; @param 1 The instruction 2061 ; 2062 ; @returns EFLAGS in EAX. 2063 ; @param A0 FPU context (fxsave). 2064 ; @param A1 Pointer to a uint16_t for the resulting FSW. 2065 ; @param A2 Pointer to the first 80-bit value. 2066 ; @param A3 Pointer to the second 80-bit value. 2067 ; 2068 %macro IEMIMPL_FPU_R80_BY_R80_EFL 1 2069 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _r80_by_r80, 16 2070 PROLOGUE_4_ARGS 2071 sub xSP, 20h 2072 2073 fninit 2074 fld tword [A3] 2075 fld tword [A2] 2076 FPU_LD_FXSTATE_FCW_AND_SAFE_FSW A0 2077 %1 st1 2078 2079 fnstsw word [A1] 2080 pushf 2081 pop xAX 2082 2083 fninit 2084 add xSP, 20h 2085 EPILOGUE_4_ARGS 8 2086 ENDPROC iemAImpl_ %+ %1 %+ _r80_by_r80 2087 %endmacro 2088 2089 IEMIMPL_FPU_R80_BY_R80_EFL fcomi 2090 IEMIMPL_FPU_R80_BY_R80_EFL fucomi 2091 2092 2093 ;; 2057 2094 ; FPU instruction working on one 80-bit floating point value. 2058 2095 ; -
trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
r40244 r40251 4341 4341 pCtx->fpu.FSW = u16Fsw; 4342 4342 4343 iemRegAddToRip(pIemCpu, cbInstr); 4343 4344 return VINF_SUCCESS; 4344 4345 } 4345 4346 4346 4347 4348 /** 4349 * Implements 'FCOMI', 'FCOMIP', 'FUCOMI', and 'FUCOMIP'. 4350 * 4351 * @param cToAdd 1 or 7. 4352 */ 4353 IEM_CIMPL_DEF_3(iemCImpl_fcomi_fucomi, uint8_t, iStReg, PFNIEMAIMPLFPUR80EFL, pfnAImpl, bool, fPop) 4354 { 4355 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 4356 Assert(iStReg < 8); 4357 4358 /* 4359 * Raise exceptions. 4360 */ 4361 if (pCtx->cr0 & (X86_CR0_EM | X86_CR0_TS)) 4362 return iemRaiseDeviceNotAvailable(pIemCpu); 4363 uint16_t u16Fsw = pCtx->fpu.FSW; 4364 if (u16Fsw & X86_FSW_ES) 4365 return iemRaiseMathFault(pIemCpu); 4366 4367 /* 4368 * Check if any of the register accesses causes #SF + #IA. 4369 */ 4370 unsigned const iReg1 = X86_FSW_TOP_GET(u16Fsw); 4371 unsigned const iReg2 = (iReg1 + iStReg) & X86_FSW_TOP_SMASK; 4372 if ((pCtx->fpu.FTW & (RT_BIT(iReg1) | RT_BIT(iReg2))) == (RT_BIT(iReg1) | RT_BIT(iReg2))) 4373 { 4374 uint32_t u32Eflags = pfnAImpl(&pCtx->fpu, &u16Fsw, &pCtx->fpu.aRegs[0].r80, &pCtx->fpu.aRegs[iStReg].r80); 4375 pCtx->fpu.FSW &= ~X86_FSW_C1; 4376 pCtx->fpu.FSW |= u16Fsw & ~X86_FSW_TOP_MASK; 4377 if ( !(u16Fsw & X86_FSW_IE) 4378 || (pCtx->fpu.FCW & X86_FCW_IM) ) 4379 { 4380 pCtx->eflags.u &= ~(X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF); 4381 pCtx->eflags.u |= pCtx->eflags.u & (X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF); 4382 } 4383 } 4384 else if (pCtx->fpu.FCW & X86_FCW_IM) 4385 { 4386 /* Masked underflow. */ 4387 pCtx->fpu.FSW &= ~X86_FSW_C1; 4388 pCtx->fpu.FSW |= X86_FSW_IE | X86_FSW_SF; 4389 pCtx->eflags.u &= ~(X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF); 4390 pCtx->eflags.u |= X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF; 4391 } 4392 else 4393 { 4394 /* Raise underflow - don't touch EFLAGS or TOP. */ 4395 pCtx->fpu.FSW &= ~X86_FSW_C1; 4396 pCtx->fpu.FSW |= X86_FSW_IE | X86_FSW_SF | X86_FSW_ES | X86_FSW_B; 4397 fPop = false; 4398 } 4399 4400 /* 4401 * Pop if necessary. 4402 */ 4403 if (fPop) 4404 { 4405 pCtx->fpu.FTW &= ~RT_BIT(iReg1); 4406 pCtx->fpu.FSW &= X86_FSW_TOP_MASK; 4407 pCtx->fpu.FSW |= ((iReg1 + 7) & X86_FSW_TOP_SMASK) << X86_FSW_TOP_SHIFT; 4408 } 4409 4410 iemFpuUpdateOpcodeAndIpWorker(pIemCpu, pCtx); 4411 iemRegAddToRip(pIemCpu, cbInstr); 4412 return VINF_SUCCESS; 4413 } 4414 4347 4415 /** @} */ 4348 4416 -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
r40250 r40251 12050 12050 12051 12051 /** Opcode 0xdb 11/5. */ 12052 FNIEMOP_STUB_1(iemOp_fucomi_stN, uint8_t, bRm); 12052 FNIEMOP_DEF_1(iemOp_fucomi_stN, uint8_t, bRm) 12053 { 12054 IEMOP_MNEMONIC("fucomi st0,stN"); 12055 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_fcomi_fucomi, bRm & X86_MODRM_RM_MASK, iemAImpl_fucomi_r80_by_r80, false /*fPop*/); 12056 } 12057 12053 12058 12054 12059 /** Opcode 0xdb 11/6. */ 12055 FNIEMOP_STUB_1(iemOp_fcomi_stN, uint8_t, bRm); 12060 FNIEMOP_DEF_1(iemOp_fcomi_stN, uint8_t, bRm) 12061 { 12062 IEMOP_MNEMONIC("fcomi st0,stN"); 12063 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_fcomi_fucomi, bRm & X86_MODRM_RM_MASK, iemAImpl_fcomi_r80_by_r80, false /*fPop*/); 12064 } 12056 12065 12057 12066 … … 12595 12604 12596 12605 /** Opcode 0xdf 11/5. */ 12597 FNIEMOP_STUB_1(iemOp_fucomip_st0_stN, uint8_t, bRm); 12606 FNIEMOP_DEF_1(iemOp_fucomip_st0_stN, uint8_t, bRm) 12607 { 12608 IEMOP_MNEMONIC("fcomip st0,stN"); 12609 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_fcomi_fucomi, bRm & X86_MODRM_RM_MASK, iemAImpl_fcomi_r80_by_r80, true /*fPop*/); 12610 } 12611 12598 12612 12599 12613 /** Opcode 0xdf 11/6. */ 12600 FNIEMOP_STUB_1(iemOp_fcomip_st0_stN, uint8_t, bRm); 12614 FNIEMOP_DEF_1(iemOp_fcomip_st0_stN, uint8_t, bRm) 12615 { 12616 IEMOP_MNEMONIC("fcomip st0,stN"); 12617 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_fcomi_fucomi, bRm & X86_MODRM_RM_MASK, iemAImpl_fcomi_r80_by_r80, true /*fPop*/); 12618 } 12619 12601 12620 12602 12621 /** Opcode 0xdf !11/0. */ -
trunk/src/VBox/VMM/include/IEMInternal.h
r40250 r40251 812 812 FNIEMAIMPLFPUR80FSW iemAImpl_fucom_r80_by_r80; 813 813 814 typedef IEM_DECL_IMPL_TYPE(uint32_t, FNIEMAIMPLFPUR80EFL,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw, 815 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2)); 816 typedef FNIEMAIMPLFPUR80EFL *PFNIEMAIMPLFPUR80EFL; 817 FNIEMAIMPLFPUR80EFL iemAImpl_fcomi_r80_by_r80; 818 FNIEMAIMPLFPUR80EFL iemAImpl_fucomi_r80_by_r80; 819 814 820 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80UNARY,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val)); 815 821 typedef FNIEMAIMPLFPUR80UNARY *PFNIEMAIMPLFPUR80UNARY;
Note:
See TracChangeset
for help on using the changeset viewer.