VirtualBox

Changeset 106443 in vbox for trunk/src/VBox/VMM/include


Ignore:
Timestamp:
Oct 17, 2024 12:02:12 PM (7 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
165262
Message:

VMM/IEM: Reduced the number of arguments for iemNativeEmitTlbLookup. bugref:10720

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/include/IEMN8veRecompilerTlbLookup.h

    r106407 r106443  
    305305 * @param   pTlbState           .
    306306 * @param   iSegReg             .
    307  * @param   cbMem               .
    308  * @param   fAlignMaskAndCtl    The low 8-bit is the alignment mask, ie. a
     307 * @param   idxLabelTlbLookup   .
     308 * @param   idxLabelTlbMiss     .
     309 * @param   idxRegMemResult     .
     310 * @param   offDisp             .
     311 * @tparam  a_cbMem               .
     312 * @tparam  a_fAlignMaskAndCtl  The low 8-bit is the alignment mask, ie. a
    309313 *                              128-bit aligned access passes 15.  This is only
    310314 *                              applied to ring-3 code, when dictated by the
     
    318322 *                              tlbmiss on anything out of alignment according
    319323 *                              to the mask in the low 8 bits.
    320  * @param   fAccess             .
    321  * @param   idxLabelTlbLookup   .
    322  * @param   idxLabelTlbMiss     .
    323  * @param   idxRegMemResult     .
    324  * @param   offDisp             .
     324 * @tparam  a_fAccess            .
    325325 * @tparam  a_fDataTlb          .
    326326 * @tparam  a_fNoReturn         .
    327327 */
    328 template<bool const a_fDataTlb, bool const a_fNoReturn = false>
     328template<bool const a_fDataTlb, const uint8_t a_cbMem, uint32_t a_fAlignMaskAndCtl, uint32_t a_fAccess,
     329         bool const a_fNoReturn = false>
    329330DECL_INLINE_THROW(uint32_t)
    330331iemNativeEmitTlbLookup(PIEMRECOMPILERSTATE pReNative, uint32_t off, IEMNATIVEEMITTLBSTATE const * const pTlbState,
    331                        uint8_t iSegReg, uint8_t cbMem, uint32_t fAlignMaskAndCtl, uint32_t fAccess,
    332                        uint32_t idxLabelTlbLookup, uint32_t idxLabelTlbMiss, uint8_t idxRegMemResult,
     332                       uint8_t iSegReg, uint32_t idxLabelTlbLookup, uint32_t idxLabelTlbMiss, uint8_t idxRegMemResult,
    333333                       uint8_t offDisp = 0)
    334334{
     
    356356            off = iemNativeEmitCmpGpr32WithImmEx(pCodeBuf, off, pTlbState->idxRegSegLimit,
    357357                                                 (uint32_t)(pTlbState->uAbsPtr + offDisp));
    358         else if (cbMem == 1)
     358        else if RT_CONSTEXPR_IF(a_cbMem == 1)
    359359            off = iemNativeEmitCmpGpr32WithGprEx(pCodeBuf, off, pTlbState->idxRegSegLimit, pTlbState->idxReg2);
    360360        else
     
    378378        if (pTlbState->idxRegPtr != UINT8_MAX)
    379379            off = iemNativeEmitCmpGprWithGprEx(pCodeBuf, off, pTlbState->idxReg1,
    380                                                cbMem > 1 || offDisp != 0 ? pTlbState->idxReg2 : pTlbState->idxRegPtr);
     380                                               a_cbMem > 1 || offDisp != 0 ? pTlbState->idxReg2 : pTlbState->idxRegPtr);
    381381        else
    382382            off = iemNativeEmitCmpGpr32WithImmEx(pCodeBuf, off, pTlbState->idxReg1,
    383                                                  (uint32_t)(pTlbState->uAbsPtr + offDisp + cbMem - 1)); /* fSkip=true on overflow. */
     383                                                 (uint32_t)(pTlbState->uAbsPtr + offDisp + a_cbMem - 1)); /* fSkip=true on overflow. */
    384384        /* jbe  tlbmiss */
    385385        off = iemNativeEmitJccToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss, kIemNativeInstrCond_be);
     
    400400    uint8_t const idxRegFlatPtr = iSegReg != UINT8_MAX || pTlbState->idxRegPtr == UINT8_MAX || offDisp != 0
    401401                                ? idxRegMemResult : pTlbState->idxRegPtr; /* (not immediately ready for tlblookup use) */
    402     uint8_t const fAlignMask    = a_fDataTlb ? (uint8_t)fAlignMaskAndCtl : 0;
     402    RT_CONSTEXPR
     403    uint8_t const fAlignMask    = a_fDataTlb ? (uint8_t)(a_fAlignMaskAndCtl & 0xff) : 0;
    403404    if (a_fDataTlb)
    404405    {
    405         Assert(!(fAlignMaskAndCtl & ~(UINT32_C(0xff) | IEM_MEMMAP_F_ALIGN_SSE | IEM_MEMMAP_F_ALIGN_GP | IEM_MEMMAP_F_ALIGN_GP_OR_AC)));
     406        AssertCompile(!(a_fAlignMaskAndCtl & ~(UINT32_C(0xff) | IEM_MEMMAP_F_ALIGN_SSE | IEM_MEMMAP_F_ALIGN_GP | IEM_MEMMAP_F_ALIGN_GP_OR_AC)));
    406407        Assert(RT_IS_POWER_OF_TWO(fAlignMask + 1U));
    407         Assert(cbMem == fAlignMask + 1U || !(fAccess & IEM_ACCESS_ATOMIC));
    408         Assert(cbMem < 128); /* alignment test assumptions */
     408        Assert(a_cbMem == fAlignMask + 1U || !(a_fAccess & IEM_ACCESS_ATOMIC));
     409        Assert(a_cbMem < 128); /* alignment test assumptions */
    409410    }
    410411
     
    412413    uint32_t offFixupMisalignedAccessJmpBack = UINT32_MAX;
    413414    if (   a_fDataTlb
    414         && !(fAlignMaskAndCtl & ~UINT32_C(0xff))
    415         && !(fAccess & IEM_ACCESS_ATOMIC)
    416         && cbMem > 1
    417         && RT_IS_POWER_OF_TWO(cbMem)
     415        && !(a_fAlignMaskAndCtl & ~UINT32_C(0xff))
     416        && !(a_fAccess & IEM_ACCESS_ATOMIC)
     417        && a_cbMem > 1
     418        && RT_IS_POWER_OF_TWO(a_cbMem)
    418419        && !(pReNative->fExec & IEM_F_X86_AC))
    419420    {
     
    422423        /* reg1 = regflat & 0xfff */
    423424        off = iemNativeEmitGpr32EqGprAndImmEx(pCodeBuf, off, pTlbState->idxReg1,/*=*/ idxRegFlatPtr,/*&*/ GUEST_PAGE_OFFSET_MASK);
    424         /* cmp reg1, GUEST_PAGE_SIZE - cbMem */
    425         off = iemNativeEmitCmpGpr32WithImmEx(pCodeBuf, off, pTlbState->idxReg1, GUEST_PAGE_SIZE - cbMem);
     425        /* cmp reg1, GUEST_PAGE_SIZE - a_cbMem */
     426        off = iemNativeEmitCmpGpr32WithImmEx(pCodeBuf, off, pTlbState->idxReg1, GUEST_PAGE_SIZE - a_cbMem);
    426427        /* jbe short jmpback */
    427428        offFixupMisalignedAccessJmpBack = off;
     
    542543           For write access this means a writable data segment.
    543544           For read-only accesses this means a readable code segment or any data segment. */
    544         if (fAccess & IEM_ACCESS_TYPE_WRITE)
     545        if RT_CONSTEXPR_IF((a_fAccess & IEM_ACCESS_TYPE_WRITE) != 0)
    545546        {
    546547            uint32_t const fMustBe1 = X86DESCATTR_P        | X86DESCATTR_DT    | X86_SEL_TYPE_WRITE;
     
    589590        /* If we're accessing more than one byte or if we're working with a non-zero offDisp,
    590591           put the last address we'll be accessing in idxReg2 (64-bit). */
    591         if ((cbMem > 1 || offDisp != 0) && pTlbState->idxRegPtr != UINT8_MAX)
     592        if ((a_cbMem > 1 || offDisp != 0) && pTlbState->idxRegPtr != UINT8_MAX)
    592593        {
    593594            if (!offDisp)
    594                 /* reg2 = regptr + cbMem - 1; 64-bit result so we can fend of wraparounds/overflows. */
    595                 off = iemNativeEmitGprEqGprPlusImmEx(pCodeBuf, off, pTlbState->idxReg2,/*=*/ pTlbState->idxRegPtr,/*+*/ cbMem - 1);
     595                /* reg2 = regptr + a_cbMem - 1; 64-bit result so we can fend of wraparounds/overflows. */
     596                off = iemNativeEmitGprEqGprPlusImmEx(pCodeBuf, off,
     597                                                     pTlbState->idxReg2,/*=*/ pTlbState->idxRegPtr,/*+*/ a_cbMem - 1);
    596598            else
    597599            {
    598                 /* reg2 = (uint32_t)(regptr + offDisp) + cbMem - 1;. */
     600                /* reg2 = (uint32_t)(regptr + offDisp) + a_cbMem - 1;. */
    599601                off = iemNativeEmitGpr32EqGprPlusImmEx(pCodeBuf, off,
    600602                                                       pTlbState->idxReg2,/*=*/ pTlbState->idxRegPtr,/*+*/ + offDisp);
    601                 off = iemNativeEmitAddGprImmEx(pCodeBuf, off, pTlbState->idxReg2, cbMem - 1);
     603                off = iemNativeEmitAddGprImmEx(pCodeBuf, off, pTlbState->idxReg2, a_cbMem - 1);
    602604            }
    603605        }
     
    608610         * we need to check that code/data=0 and expanddown=1 before continuing.
    609611         */
    610         if (fAccess & IEM_ACCESS_TYPE_WRITE)
     612        if RT_CONSTEXPR_IF((a_fAccess & IEM_ACCESS_TYPE_WRITE) != 0)
    611613        {
    612614            /* test segattrs, X86_SEL_TYPE_DOWN */
     
    631633        if (pTlbState->idxRegPtr != UINT8_MAX)
    632634            off = iemNativeEmitCmpGprWithGprEx(pCodeBuf, off, pTlbState->idxRegSegLimit,
    633                                                cbMem > 1 || offDisp != 0 ? pTlbState->idxReg2 : pTlbState->idxRegPtr);
     635                                               a_cbMem > 1 || offDisp != 0 ? pTlbState->idxReg2 : pTlbState->idxRegPtr);
    634636        else
    635637            off = iemNativeEmitCmpGpr32WithImmEx(pCodeBuf, off, pTlbState->idxRegSegLimit,
    636                                                  (uint32_t)pTlbState->uAbsPtr + offDisp + cbMem - 1U); /* fSkip=true on overflow. */
     638                                                 (uint32_t)pTlbState->uAbsPtr + offDisp + a_cbMem - 1U); /* fSkip=true on overflow. */
    637639        /* jbe  tlbmiss */
    638640        off = iemNativeEmitJccToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss, kIemNativeInstrCond_be);
     
    699701     *
    700702     *    The caller informs us about about SSE/AVX aligned accesses via the
    701      *    upper bits of fAlignMaskAndCtl and atomic accesses via fAccess.
     703     *    upper bits of a_fAlignMaskAndCtl and atomic accesses via a_fAccess.
    702704     */
    703705    if (a_fDataTlb)
     
    706708        {
    707709#ifdef RT_ARCH_ARM64
    708             if (cbMem == 2)
     710            if RT_CONSTEXPR_IF(a_cbMem == 2)
    709711            {
    710712                /* tbnz regflatptr, #0, tlbmiss */
     
    715717            {
    716718                /* test regflat, fAlignMask */
    717                 off = iemNativeEmitTestAnyBitsInGpr8Ex(pCodeBuf, off, idxRegFlatPtr, cbMem - 1);
     719                off = iemNativeEmitTestAnyBitsInGpr8Ex(pCodeBuf, off, idxRegFlatPtr, a_cbMem - 1);
    718720                /* jnz tlbmiss */
    719721                off = iemNativeEmitJccToFixedEx(pCodeBuf, off, offMisalignedAccess, kIemNativeInstrCond_ne);
     
    729731             */
    730732            bool const fStrictAlignmentCheck = fAlignMask
    731                                             && (   (fAlignMaskAndCtl & ~UINT32_C(0xff))
    732                                                 || (fAccess & IEM_ACCESS_ATOMIC)
     733                                            && (   (a_fAlignMaskAndCtl & ~UINT32_C(0xff))
     734                                                || (a_fAccess & IEM_ACCESS_ATOMIC)
    733735                                                || (pReNative->fExec & IEM_F_X86_AC) );
    734736            if (fStrictAlignmentCheck)
     
    756758             *     alignment check above.
    757759             */
    758             if (   cbMem > 1
     760            if (   a_cbMem > 1
    759761                && (   !fStrictAlignmentCheck
    760                     || cbMem > fAlignMask + 1U))
     762                    || a_cbMem > fAlignMask + 1U))
    761763            {
    762764                /* reg1 = regflat & 0xfff */
    763765                off = iemNativeEmitGpr32EqGprAndImmEx(pCodeBuf, off, pTlbState->idxReg1,/*=*/ idxRegFlatPtr,/*&*/ GUEST_PAGE_OFFSET_MASK);
    764                 /* cmp reg1, GUEST_PAGE_SIZE - cbMem */
    765                 off = iemNativeEmitCmpGpr32WithImmEx(pCodeBuf, off, pTlbState->idxReg1, GUEST_PAGE_SIZE - cbMem);
     766                /* cmp reg1, GUEST_PAGE_SIZE - a_cbMem */
     767                off = iemNativeEmitCmpGpr32WithImmEx(pCodeBuf, off, pTlbState->idxReg1, GUEST_PAGE_SIZE - a_cbMem);
    766768#ifndef IEM_WITH_TLB_STATISTICS
    767769                /* ja  tlbmiss */
     
    780782    }
    781783    else
    782         Assert(fAlignMaskAndCtl == 0);
     784        Assert(a_fAlignMaskAndCtl == 0);
    783785
    784786    /*
     
    10031005    uint64_t       fTlbe   = IEMTLBE_F_PHYS_REV | IEMTLBE_F_NO_MAPPINGR3 | IEMTLBE_F_PG_UNASSIGNED | IEMTLBE_F_PT_NO_ACCESSED
    10041006                           | fNoUser;
    1005     if (fAccess & IEM_ACCESS_TYPE_EXEC)
     1007    if RT_CONSTEXPR_IF((a_fAccess & IEM_ACCESS_TYPE_EXEC) != 0)
    10061008        fTlbe |= IEMTLBE_F_PT_NO_EXEC /*| IEMTLBE_F_PG_NO_READ?*/;
    1007     if (fAccess & IEM_ACCESS_TYPE_READ)
     1009    if RT_CONSTEXPR_IF((a_fAccess & IEM_ACCESS_TYPE_READ) != 0)
    10081010        fTlbe |= IEMTLBE_F_PG_NO_READ;
    1009     if (fAccess & IEM_ACCESS_TYPE_WRITE)
     1011    if RT_CONSTEXPR_IF((a_fAccess & IEM_ACCESS_TYPE_WRITE) != 0)
    10101012        fTlbe |= IEMTLBE_F_PT_NO_WRITE | IEMTLBE_F_PG_NO_WRITE | IEMTLBE_F_PT_NO_DIRTY;
    10111013    off = iemNativeEmitLoadGprImmEx(pCodeBuf, off, pTlbState->idxReg1, fTlbe);
     
    11831185     *
    11841186     * It's like the state logging, so parameters are passed on the stack.
    1185      * iemNativeHlpAsmSafeWrapCheckTlbLookup(pVCpu, result, addr, seg | (cbMem << 8) | (fAccess << 16))
     1187     * iemNativeHlpAsmSafeWrapCheckTlbLookup(pVCpu, result, addr, seg | (a_cbMem << 8) | (a_fAccess << 16))
    11861188     */
    11871189    if (a_fDataTlb)
    11881190    {
    11891191#  ifdef RT_ARCH_AMD64
    1190         if (!offDisp && !(fAccess & 0x8000))
    1191         {
    1192             /* push     seg | (cbMem << 8) | (fAccess << 16) */
     1192        if (!offDisp && !(a_fAccess & 0x8000))
     1193        {
     1194            /* push     seg | (a_cbMem << 8) | (a_fAccess << 16) */
    11931195            pCodeBuf[off++] = 0x68;
    11941196            pCodeBuf[off++] = iSegReg;
    1195             pCodeBuf[off++] = cbMem;
    1196             pCodeBuf[off++] = RT_BYTE1(fAccess);
    1197             pCodeBuf[off++] = RT_BYTE2(fAccess);
    1198         }
    1199         else
    1200         {
    1201             /* mov   reg1, seg | (cbMem << 8) | (fAccess << 16) | (offDisp << 32) */
     1197            pCodeBuf[off++] = a_cbMem;
     1198            pCodeBuf[off++] = RT_BYTE1(a_fAccess);
     1199            pCodeBuf[off++] = RT_BYTE2(a_fAccess);
     1200        }
     1201        else
     1202        {
     1203            /* mov   reg1, seg | (a_cbMem << 8) | (a_fAccess << 16) | (offDisp << 32) */
    12021204            off = iemNativeEmitLoadGprImmEx(pCodeBuf, off, pTlbState->idxReg1,
    1203                                             iSegReg | ((uint32_t)cbMem << 8) | (fAccess << 16) | ((uint64_t)offDisp << 32));
     1205                                            iSegReg | ((uint32_t)a_cbMem << 8) | (a_fAccess << 16) | ((uint64_t)offDisp << 32));
    12041206            /* push   reg1 */
    12051207            if (pTlbState->idxReg1 >= 8)
     
    12331235#  elif defined(RT_ARCH_ARM64)
    12341236        /* Use the temporary registers for setting up the "call frame" and making the call. */
    1235         /* reg1 = seg | (cbMem << 8) | (fAccess << 16) */
    1236         pCodeBuf[off++] = Armv8A64MkInstrMovZ(pTlbState->idxReg1, RT_MAKE_U16(iSegReg, cbMem));
    1237         pCodeBuf[off++] = Armv8A64MkInstrMovK(pTlbState->idxReg1, RT_LO_U16(fAccess), 1);
     1237        /* reg1 = seg | (a_cbMem << 8) | (a_fAccess << 16) */
     1238        pCodeBuf[off++] = Armv8A64MkInstrMovZ(pTlbState->idxReg1, RT_MAKE_U16(iSegReg, a_cbMem));
     1239        pCodeBuf[off++] = Armv8A64MkInstrMovK(pTlbState->idxReg1, RT_LO_U16(a_fAccess), 1);
    12381240        if (offDisp)
    12391241            pCodeBuf[off++] = Armv8A64MkInstrMovK(pTlbState->idxReg1, offDisp, 2);
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