VirtualBox

Changeset 102793 in vbox for trunk


Ignore:
Timestamp:
Jan 9, 2024 12:28:38 PM (13 months ago)
Author:
vboxsync
Message:

VMM/IEM: POP fix for ARM64. bugref:10371

File:
1 edited

Legend:

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

    r102791 r102793  
    1189411894
    1189511895DECL_FORCE_INLINE_THROW(uint32_t)
    11896 iemNativeEmitStackPopUse16Sp(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t idxRegRsp, uint8_t idxRegEffSp, uint8_t cbMem)
     11896iemNativeEmitStackPopUse16Sp(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t idxRegRsp, uint8_t idxRegEffSp, uint8_t cbMem,
     11897                             uint8_t idxRegTmp)
    1189711898{
    1189811899    /* Use16BitSp: */
     
    1190011901    off = iemNativeEmitLoadGprFromGpr16Ex(pCodeBuf, off, idxRegEffSp, idxRegRsp);
    1190111902    off = iemNativeEmitAddGpr16ImmEx(pCodeBuf, off, idxRegRsp, cbMem); /* ASSUMES this does NOT modify bits [63:16]! */
     11903    RT_NOREF(idxRegTmp);
    1190211904#else
    11903     /* bfi regrsp, regeff, #0, #16 - moves bits 15:0 from idxVarReg to idxGstTmpReg bits 15:0. */
    11904     pCodeBuf[off++] = Armv8A64MkInstrBfi(idxRegRsp, idxRegEffSp, 0, 16, false /*f64Bit*/);
    11905     /* add regeff, regrsp, #cbMem */
    11906     pCodeBuf[off++] = Armv8A64MkInstrAddUImm12(idxRegEffSp, idxRegRsp, cbMem, false /*f64Bit*/);
    11907     /* and regeff, regeff, #0xffff */
     11905    /* ubfiz regeff, regrsp, #0, #16 - copies bits 15:0 from RSP to EffSp bits 15:0, zeroing bits 63:16. */
     11906    pCodeBuf[off++] = Armv8A64MkInstrUbfiz(idxRegEffSp, idxRegRsp, 0, 16, false /*f64Bit*/);
     11907    /* add tmp, regrsp, #cbMem */
     11908    pCodeBuf[off++] = Armv8A64MkInstrAddUImm12(idxRegTmp, idxRegRsp, cbMem, false /*f64Bit*/);
     11909    /* and tmp, tmp, #0xffff */
    1190811910    Assert(Armv8A64ConvertImmRImmS2Mask32(15, 0) == 0xffff);
    11909     pCodeBuf[off++] = Armv8A64MkInstrAndImm(idxRegEffSp, idxRegEffSp, 15, 0,  false /*f64Bit*/);
     11911    pCodeBuf[off++] = Armv8A64MkInstrAndImm(idxRegTmp, idxRegTmp, 15, 0,  false /*f64Bit*/);
     11912    /* bfi regrsp, regeff, #0, #16 - moves bits 15:0 from tmp to RSP bits 15:0, keeping the other RSP bits as is. */
     11913    pCodeBuf[off++] = Armv8A64MkInstrBfi(idxRegRsp, idxRegTmp, 0, 16, false /*f64Bit*/);
    1191011914#endif
    1191111915    return off;
     
    1197211976     * (Code structure is very similar to that of PUSH)
    1197311977     */
    11974     uint8_t const cbMem       = RT_BYTE1(cBitsVarAndFlat) / 8;
    11975     uint8_t const cBitsFlat   = RT_BYTE2(cBitsVarAndFlat);      RT_NOREF(cBitsFlat);
    11976     uint8_t const idxRegRsp   = iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(X86_GREG_xSP),
    11977                                                                 kIemNativeGstRegUse_ForUpdate, true /*fNoVolatileRegs*/);
    11978     uint8_t const idxRegEffSp = cBitsFlat != 0 ? idxRegRsp : iemNativeRegAllocTmp(pReNative, &off);
     11978    uint8_t const cbMem           = RT_BYTE1(cBitsVarAndFlat) / 8;
     11979    uint8_t const cBitsFlat       = RT_BYTE2(cBitsVarAndFlat);      RT_NOREF(cBitsFlat);
     11980    uint8_t const idxRegRsp       = iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(X86_GREG_xSP),
     11981                                                                    kIemNativeGstRegUse_ForUpdate, true /*fNoVolatileRegs*/);
     11982    uint8_t const idxRegEffSp     = cBitsFlat != 0 ? idxRegRsp : iemNativeRegAllocTmp(pReNative, &off);
     11983    /** @todo can do a better job picking the register here. For cbMem >= 4 this
     11984     *        will be the resulting register value. */
     11985    uint8_t const idxRegMemResult = iemNativeRegAllocTmp(pReNative, &off); /* pointer then value; arm64 SP += 2/4 helper too.  */
     11986
    1197911987    uint32_t      offFixupJumpToUseOtherBitSp = UINT32_MAX;
    1198011988    if (cBitsFlat != 0)
     
    1200612014        {
    1200712015            off = iemNativeEmitJccToFixedEx(pCodeBuf, off, off /*8-bit suffices*/, kIemNativeInstrCond_ne); /* jump if not zero */
    12008             off = iemNativeEmitStackPopUse16Sp(pCodeBuf, off, idxRegRsp, idxRegEffSp, cbMem);
     12016            off = iemNativeEmitStackPopUse16Sp(pCodeBuf, off, idxRegRsp, idxRegEffSp, cbMem, idxRegMemResult);
    1200912017        }
    1201012018        IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     
    1202412032                                     ? iemNativeLabelCreate(pReNative, kIemNativeLabelType_TlbLookup, UINT32_MAX, uTlbSeqNo)
    1202512033                                     : UINT32_MAX;
    12026     /** @todo can do a better job picking the register here. For cbMem >= 4 this
    12027      *        will be the resulting register value. */
    12028     uint8_t const  idxRegMemResult   = iemNativeRegAllocTmp(pReNative, &off); /* pointer then value */
    1202912034
    1203012035    if (!TlbState.fSkip)
     
    1204512050        iemNativeFixupFixedJump(pReNative, offFixupJumpToUseOtherBitSp, off);
    1204612051        if ((pReNative->fExec & IEM_F_MODE_CPUMODE_MASK) == IEMMODE_32BIT)
    12047             off = iemNativeEmitStackPopUse16Sp(pCodeBuf, off, idxRegRsp, idxRegEffSp, cbMem);
     12052            off = iemNativeEmitStackPopUse16Sp(pCodeBuf, off, idxRegRsp, idxRegEffSp, cbMem, idxRegMemResult);
    1204812053        else
    1204912054            off = iemNativeEmitStackPopUse32Sp(pCodeBuf, off, idxRegRsp, idxRegEffSp, cbMem);
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