VirtualBox

Changeset 103740 in vbox


Ignore:
Timestamp:
Mar 9, 2024 1:42:20 AM (9 months ago)
Author:
vboxsync
Message:

VMM/IEM: Implemented iemNativeEmit_sub_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

    r103739 r103740  
    17241724{
    17251725    IEMOP_MNEMONIC2(FIXED, SUB, sub, AL, Ib, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
    1726     IEMOP_BODY_BINARY_AL_Ib(sub, 0);
     1726    IEMOP_BODY_BINARY_AL_Ib(sub, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
    17271727}
    17281728
     
    17361736{
    17371737    IEMOP_MNEMONIC2(FIXED, SUB, sub, rAX, Iz, DISOPTYPE_HARMLESS, 0);
    1738     IEMOP_BODY_BINARY_rAX_Iz_RW(sub, 0);
     1738    IEMOP_BODY_BINARY_rAX_Iz_RW(sub, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
    17391739}
    17401740
     
    44404440{
    44414441    IEMOP_MNEMONIC(sub_Eb_Ib, "sub Eb,Ib");
    4442     IEMOP_BODY_BINARY_Eb_Ib_RW(sub, 0, 0);
     4442    IEMOP_BODY_BINARY_Eb_Ib_RW(sub, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64, 0);
    44434443}
    44444444
     
    50135013{
    50145014    IEMOP_MNEMONIC(sub_Ev_Iz, "sub Ev,Iz");
    5015     IEMOP_BODY_BINARY_Ev_Iz_RW(sub, 0, 0);
     5015    IEMOP_BODY_BINARY_Ev_Iz_RW(sub, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64, 0);
    50165016}
    50175017
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h

    r103739 r103740  
    732732        else
    733733        {
    734             uint8_t const idxTmpImmReg = iemNativeRegAllocTmpImm(pReNative, &off, uImmOp);
     734            uint8_t const idxRegTmpImm = iemNativeRegAllocTmpImm(pReNative, &off, uImmOp);
    735735            pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
    736             pCodeBuf[off++] = Armv8A64MkInstrAddReg(idxRegDst, idxRegDst, idxTmpImmReg, cOpBits > 32 /*f64Bit*/, true /*fSetFlags*/);
    737             iemNativeRegFreeTmpImm(pReNative, idxTmpImmReg);
     736            pCodeBuf[off++] = Armv8A64MkInstrAddReg(idxRegDst, idxRegDst, idxRegTmpImm, cOpBits > 32 /*f64Bit*/, true /*fSetFlags*/);
     737            iemNativeRegFreeTmpImm(pReNative, idxRegTmpImm);
    738738        }
    739739    }
     
    742742        /* Shift the operands up so we can perform a 32-bit operation and get all four flags. */
    743743        uint32_t const cShift = 32 - cOpBits;
    744         uint8_t const idxTmpImmReg = iemNativeRegAllocTmpImm(pReNative, &off, uImmOp << cShift);
     744        uint8_t const idxRegTmpImm = iemNativeRegAllocTmpImm(pReNative, &off, uImmOp << cShift);
    745745        pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 2);
    746         pCodeBuf[off++] = Armv8A64MkInstrAddReg(idxRegDst, idxTmpImmReg, idxRegDstIn, false /*f64Bit*/, true /*fSetFlags*/, cShift);
     746        pCodeBuf[off++] = Armv8A64MkInstrAddReg(idxRegDst, idxRegTmpImm, idxRegDstIn, false /*f64Bit*/, true /*fSetFlags*/, cShift);
    747747        pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxRegDst, idxRegDst, cShift, false /*f64Bit*/);
    748748        cOpBits = 32;
    749         iemNativeRegFreeTmpImm(pReNative, idxTmpImmReg);
     749        iemNativeRegFreeTmpImm(pReNative, idxRegTmpImm);
    750750    }
    751751    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     
    908908                          uint8_t idxVarDst, uint64_t uImmOp, uint8_t idxVarEfl, uint8_t cOpBits, uint8_t cImmBits)
    909909{
    910     RT_NOREF(pReNative, off, idxVarDst, uImmOp, idxVarEfl, cOpBits, cImmBits);
     910    uint8_t const idxRegDst = iemNativeVarRegisterAcquire(pReNative, idxVarDst, &off, true /*fInitialized*/);
     911
     912#ifdef RT_ARCH_AMD64
     913    /* On AMD64 we just use the correctly sized SUB instruction to get the right EFLAGS.SF value. */
     914    PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8);
     915    off = iemNativeEmitAmd64OneByteModRmInstrRIEx(pCodeBuf, off, 0x80, 0x83, 0x81, cOpBits, cImmBits, 5, idxRegDst, uImmOp);
     916    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     917
     918    iemNativeVarRegisterRelease(pReNative, idxVarDst);
     919
     920    off = iemNativeEmitEFlagsForArithmetic(pReNative, off, idxVarEfl, UINT8_MAX);
     921
     922#elif defined(RT_ARCH_ARM64)
     923    /* On ARM64 we'll need the two input operands as well as the result in order
     924       to calculate the right flags, even if we use SUBS and translates NZCV into
     925       OF, CF, ZF and SF. */
     926    uint8_t const   idxRegDstIn  = iemNativeRegAllocTmp(pReNative, &off);
     927    PIEMNATIVEINSTR pCodeBuf     = iemNativeInstrBufEnsure(pReNative, off, 8);
     928    off = iemNativeEmitLoadGprFromGprEx(pCodeBuf, off, idxRegDstIn, idxRegDst);
     929    if (cOpBits >= 32)
     930    {
     931        if (uImmOp <= 0xfffU)
     932            pCodeBuf[off++] = Armv8A64MkInstrSubUImm12(idxRegDst, idxRegDst, uImmOp, cOpBits > 32 /*f64Bit*/, true /*fSetFlags*/);
     933        else if (uImmOp <= 0xfff000U && !(uImmOp & 0xfff))
     934            pCodeBuf[off++] = Armv8A64MkInstrSubUImm12(idxRegDst, idxRegDst, uImmOp, cOpBits > 32 /*f64Bit*/, true /*fSetFlags*/,
     935                                                       true /*fShift12*/);
     936        else
     937        {
     938            uint8_t const idxRegTmpImm = iemNativeRegAllocTmpImm(pReNative, &off, uImmOp);
     939            pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     940            pCodeBuf[off++] = Armv8A64MkInstrSubReg(idxRegDst, idxRegDst, idxRegTmpImm, cOpBits > 32 /*f64Bit*/, true /*fSetFlags*/);
     941            iemNativeRegFreeTmpImm(pReNative, idxRegTmpImm);
     942        }
     943    }
     944    else
     945    {
     946        /* Shift the operands up so we can perform a 32-bit operation and get all four flags. */
     947        uint32_t const cShift       = 32 - cOpBits;
     948        uint8_t const  idxRegTmpImm = iemNativeRegAllocTmpImm(pReNative, &off, uImmOp);
     949        pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4);
     950        pCodeBuf[off++] = Armv8A64MkInstrLslImm(idxRegDstIn, idxRegDstIn, cShift, false /*f64Bit*/);
     951        pCodeBuf[off++] = Armv8A64MkInstrSubReg(idxRegDst,   idxRegDstIn, idxRegTmpImm, false /*f64Bit*/, true /*fSetFlags*/, cShift);
     952        pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxRegDstIn, idxRegDstIn, cShift, false /*f64Bit*/);
     953        pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxRegDst,   idxRegDst,   cShift, false /*f64Bit*/);
     954        cOpBits = 32;
     955        iemNativeRegFreeTmpImm(pReNative, idxRegTmpImm);
     956    }
     957    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     958
     959    off = iemNativeEmitEFlagsForArithmetic(pReNative, off, idxVarEfl, UINT8_MAX, cOpBits, idxRegDst,
     960                                           idxRegDstIn, UINT8_MAX, true /*fInvertCarry*/, uImmOp);
     961
     962    iemNativeRegFreeTmp(pReNative, idxRegDstIn);
     963    iemNativeVarRegisterRelease(pReNative, idxVarDst);
     964    RT_NOREF(cImmBits);
     965
     966#else
     967# error "port me"
     968#endif
    911969    return off;
    912970}
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