VirtualBox

Ignore:
Timestamp:
Jan 9, 2024 1:41:28 AM (13 months ago)
Author:
vboxsync
Message:

VMM/IEM: Emit TLB lookup for POP GPR instructions. bugref:10371

File:
1 edited

Legend:

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

    r102785 r102790  
    14271427
    14281428
     1429/**
     1430 * Emits a gprdst[15:0] = gprsrc[15:0], preserving all other bits in the
     1431 * destination.
     1432 */
     1433DECL_FORCE_INLINE(uint32_t)
     1434iemNativeEmitGprMergeInGpr16Ex(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t idxDst, uint8_t idxSrc)
     1435{
     1436#ifdef RT_ARCH_AMD64
     1437    /* mov reg16, r/m16 */
     1438    pCodeBuf[off++] = X86_OP_PRF_SIZE_OP;
     1439    if (idxDst >= 8 || idxSrc >= 8)
     1440        pCodeBuf[off++] = (idxDst < 8 ? 0 : X86_OP_REX_R) | (idxSrc < 8 ? 0 : X86_OP_REX_B);
     1441    pCodeBuf[off++] = 0x8b;
     1442    pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxDst & 7, idxSrc & 7);
     1443
     1444#elif defined(RT_ARCH_ARM64)
     1445    /* bfi w1, w2, 0, 16 - moves bits 15:0 from idxSrc to idxDst bits 15:0. */
     1446    pCodeBuf[off++] = Armv8A64MkInstrBfi(idxDst, idxSrc, 0, 16);
     1447
     1448#else
     1449# error "Port me!"
     1450#endif
     1451    return off;
     1452}
     1453
     1454
     1455/**
     1456 * Emits a gprdst[15:0] = gprsrc[15:0], preserving all other bits in the
     1457 * destination.
     1458 */
     1459DECL_INLINE_THROW(uint32_t)
     1460iemNativeEmitGprMergeInGpr16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDst, uint8_t idxSrc)
     1461{
     1462#ifdef RT_ARCH_AMD64
     1463    off = iemNativeEmitGprMergeInGpr16Ex(iemNativeInstrBufEnsure(pReNative, off, 4), off, idxDst, idxSrc);
     1464#elif defined(RT_ARCH_ARM64)
     1465    off = iemNativeEmitGprMergeInGpr16Ex(iemNativeInstrBufEnsure(pReNative, off, 1), off, idxDst, idxSrc);
     1466#else
     1467# error "Port me!"
     1468#endif
     1469    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     1470    return off;
     1471}
     1472
    14291473
    14301474#ifdef RT_ARCH_AMD64
     
    28142858 * so not suitable as a base for conditional jumps.
    28152859 *
     2860 * @note AMD64: Will only update the lower 16 bits of the register.
    28162861 * @note ARM64: Will update the entire register.
    2817  * @note AMD64: May perhaps only update the lower 16 bits of the register.
    28182862 * @note ARM64: Larger constants will require a temporary register.  Failing to
    28192863 *       specify one when needed will trigger fatal assertion / throw.
     
    33263370    return off;
    33273371}
     3372
     3373
     3374/**
     3375 * Emits a 16-bit GPR add with a signed immediate addend.
     3376 *
     3377 * This will optimize using INC/DEC/whatever and ARM64 will not set flags,
     3378 * so not suitable as a base for conditional jumps.
     3379 *
     3380 * @note AMD64: Will only update the lower 16 bits of the register.
     3381 * @note ARM64: Will update the entire register.
     3382 * @note ARM64: Larger constants will require a temporary register.  Failing to
     3383 *       specify one when needed will trigger fatal assertion / throw.
     3384 * @sa   iemNativeEmitSubGpr16ImmEx
     3385 */
     3386DECL_FORCE_INLINE_THROW(uint32_t)
     3387iemNativeEmitAddGpr16ImmEx(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t iGprDst, int16_t iAddend,
     3388                           uint8_t iGprTmp = UINT8_MAX)
     3389{
     3390#ifdef RT_ARCH_AMD64
     3391    pCodeBuf[off++] = X86_OP_PRF_SIZE_OP;
     3392    if (iGprDst >= 8)
     3393        pCodeBuf[off++] = X86_OP_REX_B;
     3394    if (iAddend == 1)
     3395    {
     3396        /* inc r/m16 */
     3397        pCodeBuf[off++] = 0xff;
     3398        pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprDst & 7);
     3399    }
     3400    else if (iAddend == -1)
     3401    {
     3402        /* dec r/m16 */
     3403        pCodeBuf[off++] = 0xff;
     3404        pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 1, iGprDst & 7);
     3405    }
     3406    else if ((int8_t)iAddend == iAddend)
     3407    {
     3408        /* add r/m16, imm8 */
     3409        pCodeBuf[off++] = 0x83;
     3410        pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprDst & 7);
     3411        pCodeBuf[off++] = (uint8_t)iAddend;
     3412    }
     3413    else
     3414    {
     3415        /* add r/m16, imm16 */
     3416        pCodeBuf[off++] = 0x81;
     3417        pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprDst & 7);
     3418        pCodeBuf[off++] = RT_BYTE1((uint16_t)iAddend);
     3419        pCodeBuf[off++] = RT_BYTE2((uint16_t)iAddend);
     3420    }
     3421    RT_NOREF(iGprTmp);
     3422
     3423#elif defined(RT_ARCH_ARM64)
     3424    uint32_t uAbsAddend = RT_ABS(iAddend);
     3425    if (uAbsAddend < 4096)
     3426    {
     3427        if (iAddend >= 0)
     3428            pCodeBuf[off++] = Armv8A64MkInstrAddUImm12(iGprDst, iGprDst, uAbsAddend, false /*f64Bit*/);
     3429        else
     3430            pCodeBuf[off++] = Armv8A64MkInstrSubUImm12(iGprDst, iGprDst, uAbsAddend, false /*f64Bit*/);
     3431    }
     3432    else if (uAbsAddend <= 0xfff000 && !(uAbsAddend & 0xfff))
     3433    {
     3434        if (iAddend >= 0)
     3435            pCodeBuf[off++] = Armv8A64MkInstrAddUImm12(iGprDst, iGprDst, uAbsAddend >> 12,
     3436                                                       false /*f64Bit*/, false /*fSetFlags*/, true /*fShift*/);
     3437        else
     3438            pCodeBuf[off++] = Armv8A64MkInstrSubUImm12(iGprDst, iGprDst, uAbsAddend >> 12,
     3439                                                       false /*f64Bit*/, false /*fSetFlags*/, true /*fShift*/);
     3440    }
     3441    else if (iGprTmp != UINT8_MAX)
     3442    {
     3443        off = iemNativeEmitLoadGpr32ImmEx(pCodeBuf, off, iGprTmp, (uint32_t)iAddend);
     3444        pCodeBuf[off++] = Armv8A64MkInstrAddReg(iGprDst, iGprDst, iGprTmp, false /*f64Bit*/);
     3445    }
     3446    else
     3447# ifdef IEM_WITH_THROW_CATCH
     3448        AssertFailedStmt(IEMNATIVE_DO_LONGJMP(NULL, VERR_IEM_IPE_9));
     3449# else
     3450        AssertReleaseFailedStmt(off = UINT32_MAX);
     3451# endif
     3452    pCodeBuf[off++] = Armv8A64MkInstrAndImm(iGprDst, iGprDst, 15, 0, false /*f64Bit*/);
     3453
     3454#else
     3455# error "Port me"
     3456#endif
     3457    return off;
     3458}
     3459
    33283460
    33293461
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