VirtualBox

Changeset 103744 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Mar 9, 2024 2:52:46 AM (9 months ago)
Author:
vboxsync
Message:

VMM/IEM: Implemented iemNativeEmit_adc_r_i_efl and enabled it for both hosts. bugref:10376

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

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

    r103743 r103744  
    13861386{
    13871387    IEMOP_MNEMONIC2(FIXED, ADC, adc, AL, Ib, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
    1388     IEMOP_BODY_BINARY_AL_Ib(adc, 0);
     1388    IEMOP_BODY_BINARY_AL_Ib(adc, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
    13891389}
    13901390
     
    13991399{
    14001400    IEMOP_MNEMONIC2(FIXED, ADC, adc, rAX, Iz, DISOPTYPE_HARMLESS, 0);
    1401     IEMOP_BODY_BINARY_rAX_Iz_RW(adc, 0);
     1401    IEMOP_BODY_BINARY_rAX_Iz_RW(adc, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
    14021402}
    14031403
     
    44044404{
    44054405    IEMOP_MNEMONIC(adc_Eb_Ib, "adc Eb,Ib");
    4406     IEMOP_BODY_BINARY_Eb_Ib_RW(adc, 0, 0);
     4406    IEMOP_BODY_BINARY_Eb_Ib_RW(adc, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64, 0);
    44074407}
    44084408
     
    49774977{
    49784978    IEMOP_MNEMONIC(adc_Ev_Iz, "adc Ev,Iz");
    4979     IEMOP_BODY_BINARY_Ev_Iz_RW(adc, 0, 0);
     4979    IEMOP_BODY_BINARY_Ev_Iz_RW(adc, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64, 0);
    49804980}
    49814981
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h

    r103743 r103744  
    851851                          uint8_t idxVarDst, uint64_t uImmOp, uint8_t idxVarEfl, uint8_t cOpBits, uint8_t cImmBits)
    852852{
    853     RT_NOREF(pReNative, off, idxVarDst, uImmOp, idxVarEfl, cOpBits, cImmBits);
     853    uint8_t const idxRegDst = iemNativeVarRegisterAcquire(pReNative, idxVarDst, &off, true /*fInitialized*/);
     854    uint8_t const idxRegEfl = iemNativeVarRegisterAcquire(pReNative, idxVarEfl, &off, true /*fInitialized*/);
     855
     856#ifdef RT_ARCH_AMD64
     857    /* On AMD64 we use BT to set EFLAGS.CF and then issue an ADC instruction
     858       with matching size to get the correct flags. */
     859    PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 12);
     860
     861    off = iemNativeEmitAmd64TwoByteModRmInstrRREx(pCodeBuf, off, 0x0f, 0x0b, 0xba, 32 /*cOpBits*/, 4, idxRegEfl);
     862    pCodeBuf[off++] = X86_EFL_CF_BIT;
     863
     864    off = iemNativeEmitAmd64OneByteModRmInstrRIEx(pCodeBuf, off, 0x80, 0x83, 0x81, cOpBits, cImmBits, 2, idxRegDst, uImmOp);
     865    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     866
     867    iemNativeVarRegisterRelease(pReNative, idxVarDst);
     868
     869    off = iemNativeEmitEFlagsForArithmetic(pReNative, off, UINT8_MAX, idxRegEfl);
     870
     871#elif defined(RT_ARCH_ARM64)
     872    /* On ARM64 we use the RMIF instructions to load PSTATE.CF from idxRegEfl
     873       and then ADCS for the calculation.  We need all inputs and result for
     874       the two flags (AF,PF) that can't be directly derived from PSTATE.NZCV. */
     875    uint8_t const         idxRegDstIn = iemNativeRegAllocTmp(pReNative, &off);
     876    uint8_t const         idxRegImm   = iemNativeRegAllocTmpImm(pReNative, &off, uImmOp);
     877    PIEMNATIVEINSTR const pCodeBuf    = iemNativeInstrBufEnsure(pReNative, off, 4);
     878
     879    pCodeBuf[off++] = Armv8A64MkInstrRmif(idxRegEfl, (X86_EFL_CF_BIT - 1) & 63, RT_BIT_32(1) /*fMask=C*/);
     880    off = iemNativeEmitLoadGprFromGprEx(pCodeBuf, off, idxRegDstIn, idxRegDst);
     881    if (cOpBits >= 32)
     882        pCodeBuf[off++] = Armv8A64MkInstrAdcs(idxRegDst, idxRegDst, idxRegImm, cOpBits > 32 /*f64Bit*/);
     883    else
     884    {
     885        /* Since we're also adding in the carry flag here, shifting operands up
     886           doesn't work. So, we have to calculate carry & overflow manually. */
     887        pCodeBuf[off++] = Armv8A64MkInstrAdc(idxRegDst, idxRegDst, idxRegImm, false /*f64Bit*/);
     888        pCodeBuf[off++] = Armv8A64MkInstrSetF8SetF16(idxRegDst, cOpBits > 8); /* NZ are okay, CV aren't.*/
     889    }
     890    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     891
     892    iemNativeRegFreeTmp(pReNative, idxRegImm);
     893
     894    off = iemNativeEmitEFlagsForArithmetic(pReNative, off, UINT8_MAX, idxRegEfl, cOpBits, idxRegDst,
     895                                           idxRegDstIn, UINT8_MAX, false /*fInvertCarry*/, uImmOp);
     896
     897    iemNativeRegFreeTmp(pReNative, idxRegDstIn);
     898    if (cOpBits < 32)
     899        off = iemNativeEmitAndGpr32ByImm(pReNative, off, idxRegDst, RT_BIT_32(cOpBits) - 1U);
     900    iemNativeVarRegisterRelease(pReNative, idxVarDst);
     901    RT_NOREF(cImmBits);
     902
     903#else
     904# error "port me"
     905#endif
     906    iemNativeVarRegisterRelease(pReNative, idxVarEfl);
    854907    return off;
    855908}
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