VirtualBox

Changeset 40251 in vbox


Ignore:
Timestamp:
Feb 24, 2012 9:24:23 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
76465
Message:

fcomi, fcomip, fucomi and fucomip.

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm

    r40250 r40251  
    20552055
    20562056;;
     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
     2069BEGINPROC_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
     2086ENDPROC iemAImpl_ %+ %1 %+ _r80_by_r80
     2087%endmacro
     2088
     2089IEMIMPL_FPU_R80_BY_R80_EFL fcomi
     2090IEMIMPL_FPU_R80_BY_R80_EFL fucomi
     2091
     2092
     2093;;
    20572094; FPU instruction working on one 80-bit floating point value.
    20582095;
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r40244 r40251  
    43414341    pCtx->fpu.FSW = u16Fsw;
    43424342
     4343    iemRegAddToRip(pIemCpu, cbInstr);
    43434344    return VINF_SUCCESS;
    43444345}
    43454346
    43464347
     4348/**
     4349 * Implements 'FCOMI', 'FCOMIP', 'FUCOMI', and 'FUCOMIP'.
     4350 *
     4351 * @param   cToAdd              1 or 7.
     4352 */
     4353IEM_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
    43474415/** @} */
    43484416
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r40250 r40251  
    1205012050
    1205112051/** Opcode 0xdb 11/5. */
    12052 FNIEMOP_STUB_1(iemOp_fucomi_stN, uint8_t, bRm);
     12052FNIEMOP_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
    1205312058
    1205412059/** Opcode 0xdb 11/6. */
    12055 FNIEMOP_STUB_1(iemOp_fcomi_stN,  uint8_t, bRm);
     12060FNIEMOP_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}
    1205612065
    1205712066
     
    1259512604
    1259612605/** Opcode 0xdf 11/5. */
    12597 FNIEMOP_STUB_1(iemOp_fucomip_st0_stN, uint8_t, bRm);
     12606FNIEMOP_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
    1259812612
    1259912613/** Opcode 0xdf 11/6. */
    12600 FNIEMOP_STUB_1(iemOp_fcomip_st0_stN,  uint8_t, bRm);
     12614FNIEMOP_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
    1260112620
    1260212621/** Opcode 0xdf !11/0. */
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r40250 r40251  
    812812FNIEMAIMPLFPUR80FSW         iemAImpl_fucom_r80_by_r80;
    813813
     814typedef IEM_DECL_IMPL_TYPE(uint32_t, FNIEMAIMPLFPUR80EFL,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw,
     815                                                          PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2));
     816typedef FNIEMAIMPLFPUR80EFL *PFNIEMAIMPLFPUR80EFL;
     817FNIEMAIMPLFPUR80EFL         iemAImpl_fcomi_r80_by_r80;
     818FNIEMAIMPLFPUR80EFL         iemAImpl_fucomi_r80_by_r80;
     819
    814820typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPUR80UNARY,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val));
    815821typedef FNIEMAIMPLFPUR80UNARY *PFNIEMAIMPLFPUR80UNARY;
Note: See TracChangeset for help on using the changeset viewer.

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