VirtualBox

Changeset 96671 in vbox


Ignore:
Timestamp:
Sep 9, 2022 12:50:06 PM (2 years ago)
Author:
vboxsync
Message:

VMM/IEM: Emulation of fsin, fcos and fsincos instructions, ​bugref:9898

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp

    r96668 r96671  
    61656165
    61666166#ifdef IEM_WITHOUT_ASSEMBLY
     6167
     6168static uint16_t iemAImpl_fsin_r80_normal(PCRTFLOAT80U pr80Val, PRTFLOAT80U pr80Result, uint16_t fFcw, uint16_t fFsw)
     6169{
     6170    softfloat_state_t SoftState = SOFTFLOAT_STATE_INIT_DEFAULTS();
     6171    extFloat80_t x = iemFpuSoftF80FromIprt(pr80Val);
     6172    extFloat80_t v;
     6173    (void)fFcw;
     6174
     6175    v = extF80_sin(x, &SoftState);
     6176
     6177    iemFpuSoftF80ToIprt(pr80Result, v);
     6178
     6179    return fFsw;
     6180}
     6181
    61676182IEM_DECL_IMPL_DEF(void, iemAImpl_fsin_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val))
    61686183{
    6169     RT_NOREF(pFpuState, pFpuRes, pr80Val);
    6170     AssertReleaseFailed();
     6184    uint16_t const fFcw = pFpuState->FCW;
     6185    uint16_t fFsw       = (pFpuState->FSW & (X86_FSW_C0 | /*X86_FSW_C2 |*/ X86_FSW_C3)) | (7 << X86_FSW_TOP_SHIFT);
     6186
     6187    if (RTFLOAT80U_IS_ZERO(pr80Val))
     6188    {
     6189        pFpuRes->r80Result = *pr80Val;
     6190    }
     6191    else if (RTFLOAT80U_IS_NORMAL(pr80Val))
     6192    {
     6193        if (pr80Val->s.uExponent >= RTFLOAT80U_EXP_BIAS + 63)
     6194        {
     6195            fFsw |= X86_FSW_C2;
     6196            pFpuRes->r80Result = *pr80Val;
     6197        }
     6198        else
     6199        {
     6200            if (pr80Val->s.uExponent <= RTFLOAT80U_EXP_BIAS - 63)
     6201            {
     6202                pFpuRes->r80Result = *pr80Val;
     6203
     6204            }
     6205            else
     6206            {
     6207                fFsw = iemAImpl_fsin_r80_normal(pr80Val, &pFpuRes->r80Result, fFcw, fFsw);
     6208            }
     6209            fFsw |= X86_FSW_PE;
     6210            if (!(fFcw & X86_FCW_PM))
     6211                fFsw |= X86_FSW_ES | X86_FSW_B;
     6212        }
     6213    }
     6214    else if (RTFLOAT80U_IS_INF(pr80Val))
     6215    {
     6216        fFsw |= X86_FSW_IE;
     6217        if (!(fFcw & X86_FCW_IM))
     6218        {
     6219            fFsw |= X86_FSW_ES | X86_FSW_B;
     6220            pFpuRes->r80Result = *pr80Val;
     6221        }
     6222        else
     6223        {
     6224            pFpuRes->r80Result = g_r80Indefinite;
     6225        }
     6226    }
     6227    else if (RTFLOAT80U_IS_DENORMAL(pr80Val))
     6228    {
     6229        pFpuRes->r80Result = *pr80Val;
     6230        fFsw |= X86_FSW_DE;
     6231
     6232        if (fFcw & X86_FCW_DM)
     6233        {
     6234            fFsw |= X86_FSW_UE | X86_FSW_PE;
     6235
     6236            if (!(fFcw & X86_FCW_UM) || !(fFcw & X86_FCW_PM))
     6237            {
     6238                fFsw |= X86_FSW_ES | X86_FSW_B;
     6239            }
     6240        }
     6241        else
     6242        {
     6243            fFsw |= X86_FSW_ES | X86_FSW_B;
     6244        }
     6245    }
     6246    else if (RTFLOAT80U_IS_PSEUDO_DENORMAL(pr80Val))
     6247    {
     6248        pFpuRes->r80Result = *pr80Val;
     6249        fFsw |= X86_FSW_DE;
     6250
     6251        if (fFcw & X86_FCW_DM)
     6252        {
     6253            if (fFcw & X86_FCW_PM)
     6254            {
     6255                fFsw |= X86_FSW_PE;
     6256            }
     6257            else
     6258            {
     6259                fFsw |= X86_FSW_ES | X86_FSW_B | X86_FSW_PE;
     6260            }
     6261
     6262            pFpuRes->r80Result.sj64.uExponent = 1;
     6263        }
     6264        else
     6265        {
     6266            fFsw |= X86_FSW_ES | X86_FSW_B;
     6267        }
     6268    } else if (   RTFLOAT80U_IS_QUIET_NAN(pr80Val)
     6269             || RTFLOAT80U_IS_INDEFINITE(pr80Val))
     6270    {
     6271        pFpuRes->r80Result = *pr80Val;
     6272    } else {
     6273        if (   (   RTFLOAT80U_IS_UNNORMAL(pr80Val)
     6274                || RTFLOAT80U_IS_PSEUDO_NAN(pr80Val))
     6275            && (fFcw & X86_FCW_IM))
     6276            pFpuRes->r80Result = g_r80Indefinite;
     6277        else
     6278        {
     6279            pFpuRes->r80Result = *pr80Val;
     6280            if (RTFLOAT80U_IS_SIGNALLING_NAN(pr80Val) && (fFcw & X86_FCW_IM))
     6281                pFpuRes->r80Result.s.uMantissa |= RT_BIT_64(62); /* make it quiet */
     6282        }
     6283
     6284        fFsw |= X86_FSW_IE;
     6285        if (!(fFcw & X86_FCW_IM))
     6286            fFsw |= X86_FSW_ES | X86_FSW_B;
     6287    }
     6288
     6289    pFpuRes->FSW = fFsw;
    61716290}
    61726291#endif /* IEM_WITHOUT_ASSEMBLY */
     
    61836302
    61846303#ifdef IEM_WITHOUT_ASSEMBLY
     6304
     6305static uint16_t iemAImpl_fcos_r80_normal(PCRTFLOAT80U pr80Val, PRTFLOAT80U pr80Result, uint16_t fFcw, uint16_t fFsw)
     6306{
     6307    softfloat_state_t SoftState = SOFTFLOAT_STATE_INIT_DEFAULTS();
     6308    extFloat80_t x = iemFpuSoftF80FromIprt(pr80Val);
     6309    extFloat80_t v;
     6310    (void)fFcw;
     6311
     6312    v = extF80_cos(x, &SoftState);
     6313
     6314    iemFpuSoftF80ToIprt(pr80Result, v);
     6315
     6316    return fFsw;
     6317}
     6318
     6319IEM_DECL_IMPL_DEF(void, iemAImpl_fcos_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val))
     6320{
     6321    uint16_t const fFcw = pFpuState->FCW;
     6322    uint16_t fFsw       = (pFpuState->FSW & (X86_FSW_C0 | /*X86_FSW_C2 |*/ X86_FSW_C3)) | (7 << X86_FSW_TOP_SHIFT);
     6323
     6324    if (RTFLOAT80U_IS_ZERO(pr80Val))
     6325    {
     6326        pFpuRes->r80Result = g_ar80One[0];
     6327    }
     6328    else if (RTFLOAT80U_IS_NORMAL(pr80Val))
     6329    {
     6330        if (pr80Val->s.uExponent >= RTFLOAT80U_EXP_BIAS + 63)
     6331        {
     6332            fFsw |= X86_FSW_C2;
     6333            pFpuRes->r80Result = *pr80Val;
     6334        }
     6335        else
     6336        {
     6337            if (pr80Val->s.uExponent <= RTFLOAT80U_EXP_BIAS - 63)
     6338            {
     6339                pFpuRes->r80Result = g_ar80One[0];
     6340
     6341            }
     6342            else
     6343            {
     6344                fFsw = iemAImpl_fcos_r80_normal(pr80Val, &pFpuRes->r80Result, fFcw, fFsw);
     6345                fFsw |= X86_FSW_C1; // TBD: If the inexact result was rounded up (C1 is set) or “not rounded up” (C1 is cleared).
     6346            }
     6347            fFsw |= X86_FSW_PE;
     6348            if (!(fFcw & X86_FCW_PM))
     6349                fFsw |= X86_FSW_ES | X86_FSW_B;
     6350        }
     6351    }
     6352    else if (RTFLOAT80U_IS_INF(pr80Val))
     6353    {
     6354        fFsw |= X86_FSW_IE;
     6355        if (!(fFcw & X86_FCW_IM))
     6356        {
     6357            fFsw |= X86_FSW_ES | X86_FSW_B;
     6358            pFpuRes->r80Result = *pr80Val;
     6359        }
     6360        else
     6361        {
     6362            pFpuRes->r80Result = g_r80Indefinite;
     6363        }
     6364    }
     6365    else if (RTFLOAT80U_IS_DENORMAL(pr80Val) || RTFLOAT80U_IS_PSEUDO_DENORMAL(pr80Val))
     6366    {
     6367        fFsw |= X86_FSW_DE;
     6368
     6369        if (fFcw & X86_FCW_DM)
     6370        {
     6371            pFpuRes->r80Result = g_ar80One[0];
     6372
     6373            if (fFcw & X86_FCW_PM)
     6374            {
     6375                fFsw |= X86_FSW_PE;
     6376            }
     6377            else
     6378            {
     6379                fFsw |= X86_FSW_PE | X86_FSW_ES | X86_FSW_B;
     6380            }
     6381        }
     6382        else
     6383        {
     6384            pFpuRes->r80Result = *pr80Val;
     6385            fFsw |= X86_FSW_ES | X86_FSW_B;
     6386        }
     6387    } else if (   RTFLOAT80U_IS_QUIET_NAN(pr80Val)
     6388             || RTFLOAT80U_IS_INDEFINITE(pr80Val))
     6389    {
     6390        pFpuRes->r80Result = *pr80Val;
     6391    } else {
     6392        if (   (   RTFLOAT80U_IS_UNNORMAL(pr80Val)
     6393                || RTFLOAT80U_IS_PSEUDO_NAN(pr80Val))
     6394            && (fFcw & X86_FCW_IM))
     6395            pFpuRes->r80Result = g_r80Indefinite;
     6396        else
     6397        {
     6398            pFpuRes->r80Result = *pr80Val;
     6399            if (RTFLOAT80U_IS_SIGNALLING_NAN(pr80Val) && (fFcw & X86_FCW_IM))
     6400                pFpuRes->r80Result.s.uMantissa |= RT_BIT_64(62); /* make it quiet */
     6401        }
     6402
     6403        fFsw |= X86_FSW_IE;
     6404        if (!(fFcw & X86_FCW_IM))
     6405            fFsw |= X86_FSW_ES | X86_FSW_B;
     6406    }
     6407
     6408    pFpuRes->FSW = fFsw;
     6409}
     6410#endif /* IEM_WITHOUT_ASSEMBLY */
     6411
     6412IEM_DECL_IMPL_DEF(void, iemAImpl_fcos_r80_amd,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val))
     6413{
     6414    iemAImpl_fcos_r80(pFpuState, pFpuRes, pr80Val);
     6415}
     6416
     6417IEM_DECL_IMPL_DEF(void, iemAImpl_fcos_r80_intel,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val))
     6418{
     6419    iemAImpl_fcos_r80(pFpuState, pFpuRes, pr80Val);
     6420}
     6421
     6422#ifdef IEM_WITHOUT_ASSEMBLY
     6423
     6424static uint16_t iemAImpl_fsincos_r80_r80_normal(PIEMFPURESULTTWO pFpuResTwo, PCRTFLOAT80U pr80Val, uint16_t fFcw, uint16_t fFsw)
     6425{
     6426    softfloat_state_t SoftState = SOFTFLOAT_STATE_INIT_DEFAULTS();
     6427    extFloat80_t x = iemFpuSoftF80FromIprt(pr80Val);
     6428    extFloat80_t r80Sin, r80Cos;
     6429    (void)fFcw;
     6430
     6431    extF80_sincos(x, &r80Sin, &r80Cos, &SoftState);
     6432
     6433    iemFpuSoftF80ToIprt(&pFpuResTwo->r80Result1, r80Sin);
     6434    iemFpuSoftF80ToIprt(&pFpuResTwo->r80Result2, r80Cos);
     6435
     6436    return fFsw;
     6437}
     6438
    61856439IEM_DECL_IMPL_DEF(void, iemAImpl_fsincos_r80_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULTTWO pFpuResTwo, PCRTFLOAT80U pr80Val))
    61866440{
    6187     RT_NOREF(pFpuState, pFpuResTwo, pr80Val);
    6188     AssertReleaseFailed();
     6441    uint16_t const fFcw = pFpuState->FCW;
     6442    uint16_t fFsw       = (pFpuState->FSW & (X86_FSW_C0 | /*X86_FSW_C2 |*/ X86_FSW_C3)) | (7 << X86_FSW_TOP_SHIFT);
     6443
     6444    if (RTFLOAT80U_IS_ZERO(pr80Val))
     6445    {
     6446        pFpuResTwo->r80Result1 = *pr80Val;
     6447        pFpuResTwo->r80Result2 = g_ar80One[0];
     6448        fFsw &= ~X86_FSW_TOP_MASK | (6 << X86_FSW_TOP_SHIFT);
     6449    }
     6450    else if (RTFLOAT80U_IS_NORMAL(pr80Val))
     6451    {
     6452        if (pr80Val->s.uExponent >= RTFLOAT80U_EXP_BIAS + 63)
     6453        {
     6454            fFsw |= X86_FSW_C2;
     6455
     6456            if (fFcw & X86_FCW_IM)
     6457            {
     6458                pFpuResTwo->r80Result1 = g_r80Indefinite;
     6459            }
     6460            else
     6461            {
     6462                pFpuResTwo->r80Result1 = g_ar80Zero[0];
     6463            }
     6464
     6465            pFpuResTwo->r80Result2 = *pr80Val;
     6466        }
     6467        else
     6468        {
     6469            fFsw &= ~X86_FSW_TOP_MASK | (6 << X86_FSW_TOP_SHIFT);
     6470
     6471            if (pr80Val->s.uExponent <= RTFLOAT80U_EXP_BIAS - 63)
     6472            {
     6473                pFpuResTwo->r80Result1 = *pr80Val;
     6474                pFpuResTwo->r80Result2 = g_ar80One[0];
     6475            }
     6476            else
     6477            {
     6478                fFsw = iemAImpl_fsincos_r80_r80_normal(pFpuResTwo, pr80Val, fFcw, fFsw);
     6479                fFsw |= X86_FSW_C1; // TBD: If the inexact result was rounded up (C1 is set) or “not rounded up” (C1 is cleared).
     6480            }
     6481            fFsw |= X86_FSW_PE;
     6482            if (!(fFcw & X86_FCW_PM))
     6483                fFsw |= X86_FSW_ES | X86_FSW_B;
     6484        }
     6485    }
     6486    else if (RTFLOAT80U_IS_PSEUDO_DENORMAL(pr80Val))
     6487    {
     6488        fFsw |= X86_FSW_DE;
     6489
     6490        if (fFcw & X86_FCW_DM)
     6491        {
     6492            pFpuResTwo->r80Result1 = *pr80Val;
     6493            pFpuResTwo->r80Result2 = g_ar80One[0];
     6494            fFsw &= ~X86_FSW_TOP_MASK | (6 << X86_FSW_TOP_SHIFT);
     6495
     6496            if (fFcw & X86_FCW_PM)
     6497            {
     6498                fFsw |= X86_FSW_PE;
     6499            }
     6500            else
     6501            {
     6502                fFsw |= X86_FSW_PE | X86_FSW_ES | X86_FSW_B;
     6503            }
     6504
     6505            pFpuResTwo->r80Result1.sj64.uExponent = 1;
     6506        }
     6507        else
     6508        {
     6509            pFpuResTwo->r80Result1 = g_ar80Zero[0];
     6510            pFpuResTwo->r80Result2 = *pr80Val;
     6511            fFsw |= X86_FSW_ES | X86_FSW_B;
     6512        }
     6513    }
     6514    else if (RTFLOAT80U_IS_DENORMAL(pr80Val))
     6515    {
     6516        fFsw |= X86_FSW_DE;
     6517
     6518        if (fFcw & X86_FCW_DM)
     6519        {
     6520            pFpuResTwo->r80Result1 = *pr80Val;
     6521            pFpuResTwo->r80Result2 = g_ar80One[0];
     6522
     6523            fFsw &= ~X86_FSW_TOP_MASK | (6 << X86_FSW_TOP_SHIFT);
     6524            fFsw |= X86_FSW_UE | X86_FSW_PE;
     6525
     6526            if (fFcw & X86_FCW_PM)
     6527            {
     6528                if (!(fFcw & X86_FCW_UM))
     6529                    fFsw |= X86_FSW_ES | X86_FSW_B;
     6530            }
     6531            else
     6532            {
     6533                fFsw |= X86_FSW_ES | X86_FSW_B;
     6534            }
     6535        }
     6536        else
     6537        {
     6538            pFpuResTwo->r80Result1 = g_ar80Zero[0];
     6539            pFpuResTwo->r80Result2 = *pr80Val;
     6540            fFsw |= X86_FSW_ES | X86_FSW_B;
     6541        }
     6542    }
     6543    else if (RTFLOAT80U_IS_QUIET_NAN(pr80Val) || RTFLOAT80U_IS_INDEFINITE(pr80Val))
     6544    {
     6545        pFpuResTwo->r80Result1 = *pr80Val;
     6546        pFpuResTwo->r80Result2 = *pr80Val;
     6547        fFsw &= ~X86_FSW_TOP_MASK | (6 << X86_FSW_TOP_SHIFT);
     6548    }
     6549    else if (RTFLOAT80U_IS_UNNORMAL(pr80Val) || RTFLOAT80U_IS_PSEUDO_NAN(pr80Val))
     6550    {
     6551        if (fFcw & X86_FCW_IM)
     6552        {
     6553            pFpuResTwo->r80Result1 = g_r80Indefinite;
     6554            pFpuResTwo->r80Result2 = g_r80Indefinite;
     6555            fFsw &= ~X86_FSW_TOP_MASK | (6 << X86_FSW_TOP_SHIFT);
     6556        }
     6557        else
     6558        {
     6559            pFpuResTwo->r80Result1 = g_ar80Zero[0];
     6560            pFpuResTwo->r80Result2 = *pr80Val;
     6561        }
     6562
     6563        fFsw |= X86_FSW_IE;
     6564        if (!(fFcw & X86_FCW_IM))
     6565            fFsw |= X86_FSW_ES | X86_FSW_B;
     6566    }
     6567    else if (RTFLOAT80U_IS_SIGNALLING_NAN(pr80Val))
     6568    {
     6569        pFpuResTwo->r80Result1 = *pr80Val;
     6570        pFpuResTwo->r80Result2 = *pr80Val;
     6571
     6572        if (fFcw & X86_FCW_IM)
     6573        {
     6574            pFpuResTwo->r80Result1.s.uMantissa |= RT_BIT_64(62); /* make it quiet */
     6575            pFpuResTwo->r80Result2.s.uMantissa |= RT_BIT_64(62);
     6576            fFsw &= ~X86_FSW_TOP_MASK | (6 << X86_FSW_TOP_SHIFT);
     6577        }
     6578        else
     6579        {
     6580            pFpuResTwo->r80Result1 = g_ar80Zero[0];
     6581            pFpuResTwo->r80Result2 = *pr80Val;
     6582        }
     6583
     6584        fFsw |= X86_FSW_IE;
     6585        if (!(fFcw & X86_FCW_IM))
     6586            fFsw |= X86_FSW_ES | X86_FSW_B;
     6587    }
     6588    else if (RTFLOAT80U_IS_INF(pr80Val))
     6589    {
     6590        if (fFcw & X86_FCW_IM)
     6591        {
     6592            pFpuResTwo->r80Result1 = g_r80Indefinite;
     6593            pFpuResTwo->r80Result2 = g_r80Indefinite;
     6594            fFsw &= ~X86_FSW_TOP_MASK | (6 << X86_FSW_TOP_SHIFT);
     6595        }
     6596        else
     6597        {
     6598            pFpuResTwo->r80Result1 = g_ar80Zero[0];
     6599            pFpuResTwo->r80Result2 = *pr80Val;
     6600        }
     6601
     6602        fFsw |= X86_FSW_IE;
     6603        if (!(fFcw & X86_FCW_IM))
     6604            fFsw |= X86_FSW_ES | X86_FSW_B;
     6605    }
     6606
     6607    pFpuResTwo->FSW = fFsw;
    61896608}
    61906609#endif /* IEM_WITHOUT_ASSEMBLY */
     
    61986617{
    61996618    iemAImpl_fsincos_r80_r80(pFpuState, pFpuResTwo, pr80Val);
    6200 }
    6201 
    6202 
    6203 #ifdef IEM_WITHOUT_ASSEMBLY
    6204 IEM_DECL_IMPL_DEF(void, iemAImpl_fcos_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val))
    6205 {
    6206     RT_NOREF(pFpuState, pFpuRes, pr80Val);
    6207     AssertReleaseFailed();
    6208 }
    6209 #endif /* IEM_WITHOUT_ASSEMBLY */
    6210 
    6211 IEM_DECL_IMPL_DEF(void, iemAImpl_fcos_r80_amd,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val))
    6212 {
    6213     iemAImpl_fcos_r80(pFpuState, pFpuRes, pr80Val);
    6214 }
    6215 
    6216 IEM_DECL_IMPL_DEF(void, iemAImpl_fcos_r80_intel,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val))
    6217 {
    6218     iemAImpl_fcos_r80(pFpuState, pFpuRes, pr80Val);
    62196619}
    62206620
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette