- Timestamp:
- Apr 19, 2022 9:24:15 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
r94614 r94640 5043 5043 5044 5044 5045 /** Worker for iemAImpl_fdiv_r80_by_r80 & iemAImpl_fdivr_r80_by_r80. */ 5046 static uint16_t iemAImpl_fprem_fprem1_r80_by_r80_worker(PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2, PRTFLOAT80U pr80Result, 5047 uint16_t fFcw, uint16_t fFsw, PCRTFLOAT80U pr80Val1Org, bool fLegacyInstr) 5048 { 5049 if (!RTFLOAT80U_IS_ZERO(pr80Val2) || RTFLOAT80U_IS_NAN(pr80Val1) || RTFLOAT80U_IS_INF(pr80Val1)) 5050 { 5051 softfloat_state_t SoftState = IEM_SOFTFLOAT_STATE_INITIALIZER_FROM_FCW(fFcw); 5052 uint16_t fCxFlags = 0; 5053 extFloat80_t r80XResult = extF80_partialRem(iemFpuSoftF80FromIprt(pr80Val1), iemFpuSoftF80FromIprt(pr80Val2), 5054 fLegacyInstr ? softfloat_round_minMag : softfloat_round_near_even, 5055 &fCxFlags, &SoftState); 5056 Assert(!(fCxFlags & ~X86_FSW_C_MASK)); 5057 fFsw = iemFpuSoftStateAndF80ToFswAndIprtResult(&SoftState, r80XResult, pr80Result, fFcw, fFsw, pr80Val1Org); 5058 if ( !(fFsw & X86_FSW_IE) 5059 && !RTFLOAT80U_IS_NAN(pr80Result) 5060 && !RTFLOAT80U_IS_INDEFINITE(pr80Result)) 5061 { 5062 fFsw &= ~(uint16_t)X86_FSW_C_MASK; 5063 fFsw |= fCxFlags & X86_FSW_C_MASK; 5064 } 5065 return fFsw; 5066 } 5067 5068 /* Invalid operand */ 5069 if (fFcw & X86_FCW_IM) 5070 *pr80Result = g_r80Indefinite; 5071 else 5072 { 5073 *pr80Result = *pr80Val1Org; 5074 fFsw |= X86_FSW_ES | X86_FSW_B; 5075 } 5076 return fFsw | X86_FSW_IE; 5077 } 5078 5079 5080 static void iemAImpl_fprem_fprem1_r80_by_r80(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, 5081 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2, bool fLegacyInstr) 5082 { 5083 uint16_t const fFcw = pFpuState->FCW; 5084 uint16_t fFsw = (pFpuState->FSW & (X86_FSW_C0 /*| X86_FSW_C2*/ | X86_FSW_C3)) | (6 << X86_FSW_TOP_SHIFT); 5085 5086 /* SoftFloat does not check for Pseudo-Infinity, Pseudo-Nan and Unnormals. 5087 In addition, we'd like to handle zero ST(1) now as SoftFloat returns Inf instead 5088 of Indefinite. (Note! There is no #Z like the footnotes to tables 3-31 and 3-32 5089 for the FPREM1 & FPREM1 instructions in the intel reference manual claims!) */ 5090 if ( RTFLOAT80U_IS_387_INVALID(pr80Val1) || RTFLOAT80U_IS_387_INVALID(pr80Val2) 5091 || (RTFLOAT80U_IS_ZERO(pr80Val2) && !RTFLOAT80U_IS_NAN(pr80Val1) && !RTFLOAT80U_IS_INDEFINITE(pr80Val1))) 5092 { 5093 if (fFcw & X86_FCW_IM) 5094 pFpuRes->r80Result = g_r80Indefinite; 5095 else 5096 { 5097 pFpuRes->r80Result = *pr80Val1; 5098 fFsw |= X86_FSW_ES | X86_FSW_B; 5099 } 5100 fFsw |= X86_FSW_IE; 5101 } 5102 /* SoftFloat does not check for denormals and certainly not report them to us. NaNs & /0 trumps denormals. */ 5103 else if ( (RTFLOAT80U_IS_DENORMAL_OR_PSEUDO_DENORMAL(pr80Val1) && !RTFLOAT80U_IS_NAN(pr80Val2) && !RTFLOAT80U_IS_ZERO(pr80Val2)) 5104 || (RTFLOAT80U_IS_DENORMAL_OR_PSEUDO_DENORMAL(pr80Val2) && !RTFLOAT80U_IS_NAN(pr80Val1) && !RTFLOAT80U_IS_INF(pr80Val1)) ) 5105 { 5106 if (fFcw & X86_FCW_DM) 5107 { 5108 PCRTFLOAT80U const pr80Val1Org = pr80Val1; 5109 IEM_NORMALIZE_PSEUDO_DENORMAL(pr80Val1, r80Val1Normalized); 5110 IEM_NORMALIZE_PSEUDO_DENORMAL(pr80Val2, r80Val2Normalized); 5111 fFsw = iemAImpl_fprem_fprem1_r80_by_r80_worker(pr80Val1, pr80Val2, &pFpuRes->r80Result, fFcw, fFsw, 5112 pr80Val1Org, fLegacyInstr); 5113 } 5114 else 5115 { 5116 pFpuRes->r80Result = *pr80Val1; 5117 fFsw |= X86_FSW_ES | X86_FSW_B; 5118 } 5119 fFsw |= X86_FSW_DE; 5120 } 5121 /* SoftFloat can handle the rest: */ 5122 else 5123 fFsw = iemAImpl_fprem_fprem1_r80_by_r80_worker(pr80Val1, pr80Val2, &pFpuRes->r80Result, fFcw, fFsw, 5124 pr80Val1, fLegacyInstr); 5125 5126 pFpuRes->FSW = fFsw; 5127 } 5128 5129 5045 5130 IEM_DECL_IMPL_DEF(void, iemAImpl_fprem_r80_by_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, 5046 5131 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2)) 5047 5132 { 5048 RT_NOREF(pFpuState, pFpuRes, pr80Val1, pr80Val2); 5049 AssertReleaseFailed(); 5133 iemAImpl_fprem_fprem1_r80_by_r80(pFpuState, pFpuRes, pr80Val1, pr80Val2, true /*fLegacyInstr*/); 5050 5134 } 5051 5135 … … 5054 5138 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2)) 5055 5139 { 5056 RT_NOREF(pFpuState, pFpuRes, pr80Val1, pr80Val2); 5057 AssertReleaseFailed(); 5140 iemAImpl_fprem_fprem1_r80_by_r80(pFpuState, pFpuRes, pr80Val1, pr80Val2, false /*fLegacyInstr*/); 5058 5141 } 5059 5142
Note:
See TracChangeset
for help on using the changeset viewer.