VirtualBox

Changeset 102510 in vbox


Ignore:
Timestamp:
Dec 6, 2023 9:39:10 PM (12 months ago)
Author:
vboxsync
Message:

VMM/IEM: 64-bit effective address calculation (IEM_MC_CALC_RM_EFF_ADDR_THREADED_64*). Some fixes to disassembly and iemNativeEmitGprByGprDisp. bugref:10371

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/armv8.h

    r102449 r102510  
    26562656
    26572657
     2658/** A64: Encodes an MOV instruction.
     2659 * This is an alias for "orr dst, xzr, src".  */
     2660DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrMov(uint32_t iRegResult, uint32_t idxRegSrc, bool f64Bit = true)
     2661{
     2662    return Armv8A64MkInstrOrr(iRegResult, ARMV8_A64_REG_XZR, idxRegSrc, f64Bit);
     2663}
     2664
     2665
    26582666/** A64: Encodes an ORN instruction.
    26592667 * @see Armv8A64MkInstrLogicalShiftedReg for parameter details.  */
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstCommon.cpp.h

    r102011 r102510  
    10331033            IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm, 0);
    10341034            IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     1035IEM_MC_NO_NATIVE_RECOMPILE(); /** @todo sort out the IEM_IS_GUEST_CPU_AMD stuff. */
    10351036            if (IEM_IS_GUEST_CPU_AMD(pVCpu)) /** @todo testcase: rev 3.15 of the amd manuals claims it only loads a 32-bit greg. */
    10361037                IEM_MC_FETCH_MEM_U32_SX_U64(offSeg, pVCpu->iem.s.iEffSeg, GCPtrEff);
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py

    r102447 r102510  
    6262    'IEM_MC_CALC_RM_EFF_ADDR_THREADED_16':                       (None, False, True,  ),
    6363    'IEM_MC_CALC_RM_EFF_ADDR_THREADED_32':                       (None, False, True,  ),
    64     'IEM_MC_CALC_RM_EFF_ADDR_THREADED_64_ADDR32':                (None, False, False, ),
    65     'IEM_MC_CALC_RM_EFF_ADDR_THREADED_64_FSGS':                  (None, False, False, ),
    66     'IEM_MC_CALC_RM_EFF_ADDR_THREADED_64':                       (None, False, False, ),
     64    'IEM_MC_CALC_RM_EFF_ADDR_THREADED_64_ADDR32':                (None, False, True, ),
     65    'IEM_MC_CALC_RM_EFF_ADDR_THREADED_64_FSGS':                  (None, False, True, ),
     66    'IEM_MC_CALC_RM_EFF_ADDR_THREADED_64':                       (None, False, True, ),
    6767
    6868    'IEM_MC_CALL_CIMPL_1_THREADED':                              (None, True,  True,  ),
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r102471 r102510  
    66 *      - Level 1  (Log)  : ...
    77 *      - Flow  (LogFlow) : ...
    8  *      - Level 2  (Log2) : ...
     8 *      - Level 2  (Log2) : Details calls as they're recompiled.
    99 *      - Level 3  (Log3) : Disassemble native code after recompiling.
    1010 *      - Level 4  (Log4) : ...
     
    34383438                      && enmIntendedUse != kIemNativeGstRegUse_ForFullWrite,
    34393439                      ("This shouldn't happen: idxReg=%d enmGstReg=%d enmIntendedUse=%s\n",
    3440                        idxReg, s_pszIntendedUse[enmIntendedUse]));
     3440                       idxReg, enmGstReg, s_pszIntendedUse[enmIntendedUse]));
    34413441
    34423442            /*
     
    87298729
    87308730#define IEM_MC_CALC_RM_EFF_ADDR_THREADED_64(a_GCPtrEff, a_bRmEx, a_uSibAndRspOffset, a_u32Disp, a_cbImm) \
    8731     off = iemNativeEmitCalcRmEffAddrThreadedAddr64(pReNative, off, a_bRmEx, a_uSibAndRspOffset, a_u32Disp, a_cbImm, a_GCPtrEff)
     8731    off = iemNativeEmitCalcRmEffAddrThreadedAddr64(pReNative, off, a_bRmEx, a_uSibAndRspOffset, \
     8732                                                   a_u32Disp, a_cbImm, a_GCPtrEff, true /*f64Bit*/)
    87328733
    87338734#define IEM_MC_CALC_RM_EFF_ADDR_THREADED_64_FSGS(a_GCPtrEff, a_bRmEx, a_uSibAndRspOffset, a_u32Disp, a_cbImm) \
    8734     off = iemNativeEmitCalcRmEffAddrThreadedAddr64(pReNative, off, a_bRmEx, a_uSibAndRspOffset, a_u32Disp, a_cbImm, a_GCPtrEff, 64)
     8735    off = iemNativeEmitCalcRmEffAddrThreadedAddr64(pReNative, off, a_bRmEx, a_uSibAndRspOffset, \
     8736                                                   a_u32Disp, a_cbImm, a_GCPtrEff, true /*f64Bit*/)
    87358737
    87368738#define IEM_MC_CALC_RM_EFF_ADDR_THREADED_64_ADDR32(a_GCPtrEff, a_bRmEx, a_uSibAndRspOffset, a_u32Disp, a_cbImm) \
    8737     off = iemNativeEmitCalcRmEffAddrThreadedAddr64(pReNative, off, a_bRmEx, a_uSibAndRspOffset, a_u32Disp, a_cbImm, a_GCPtrEff, 32)
     8739    off = iemNativeEmitCalcRmEffAddrThreadedAddr64(pReNative, off, a_bRmEx, a_uSibAndRspOffset, \
     8740                                                   a_u32Disp, a_cbImm, a_GCPtrEff, false /*f64Bit*/)
     8741
     8742/**
     8743 * Emit code for IEM_MC_CALC_RM_EFF_ADDR_THREADED_64*.
     8744 *
     8745 * @returns New off.
     8746 * @param   pReNative           .
     8747 * @param   off                 .
     8748 * @param   bRmEx               The ModRM byte but with bit 3 set to REX.B and
     8749 *                              bit 4 to REX.X.  The two bits are part of the
     8750 *                              REG sub-field, which isn't needed in this
     8751 *                              function.
     8752 * @param   uSibAndRspOffset    Two parts:
     8753 *                                - The first 8 bits make up the SIB byte.
     8754 *                                - The next 8 bits are the fixed RSP/ESP offset
     8755 *                                  in case of a pop [xSP].
     8756 * @param   u32Disp             The displacement byte/word/dword, if any.
     8757 * @param   cbInstr             The size of the fully decoded instruction. Used
     8758 *                              for RIP relative addressing.
     8759 * @param   idxVarRet           .
     8760 *
     8761 * @see iemOpHlpCalcRmEffAddrThreadedAddr64
     8762 */
     8763DECL_INLINE_THROW(uint32_t)
     8764iemNativeEmitCalcRmEffAddrThreadedAddr64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t bRmEx, uint32_t uSibAndRspOffset,
     8765                                         uint32_t u32Disp, uint8_t cbInstr, uint8_t idxVarRet, bool f64Bit)
     8766{
     8767    IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxVarRet);
     8768
     8769    /*
     8770     * Special case the rip + disp32 form first.
     8771     */
     8772    if ((bRmEx & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 5)
     8773    {
     8774        uint8_t const idxRegRet = iemNativeVarAllocRegister(pReNative, idxVarRet, &off);
     8775        uint8_t const idxRegPc  = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc,
     8776                                                                  kIemNativeGstRegUse_ReadOnly);
     8777#ifdef RT_ARCH_AMD64
     8778        if (f64Bit)
     8779        {
     8780            int64_t const offFinalDisp = (int64_t)(int32_t)u32Disp + cbInstr;
     8781            if ((int32_t)offFinalDisp == offFinalDisp)
     8782                off = iemNativeEmitLoadGprFromGprWithAddendMaybeZero(pReNative, off, idxRegRet, idxRegPc, (int32_t)offFinalDisp);
     8783            else
     8784            {
     8785                off = iemNativeEmitLoadGprFromGprWithAddend(pReNative, off, idxRegRet, idxRegPc, (int32_t)u32Disp);
     8786                off = iemNativeEmitAddGprImm8(pReNative, off, idxRegRet, cbInstr);
     8787            }
     8788        }
     8789        else
     8790            off = iemNativeEmitLoadGprFromGpr32WithAddendMaybeZero(pReNative, off, idxRegRet, idxRegPc, (int32_t)u32Disp + cbInstr);
     8791
     8792#elif defined(RT_ARCH_ARM64)
     8793        if (f64Bit)
     8794            off = iemNativeEmitLoadGprFromGprWithAddendMaybeZero(pReNative, off, idxRegRet, idxRegPc,
     8795                                                                 (int64_t)(int32_t)u32Disp + cbInstr);
     8796        else
     8797            off = iemNativeEmitLoadGprFromGpr32WithAddendMaybeZero(pReNative, off, idxRegRet, idxRegPc,
     8798                                                                   (int32_t)u32Disp + cbInstr);
     8799
     8800#else
     8801# error "Port me!"
     8802#endif
     8803        iemNativeRegFreeTmp(pReNative, idxRegPc);
     8804        return off;
     8805    }
     8806
     8807    /* Calculate the fixed displacement (more down in SIB.B=4 and SIB.B=5 on this). */
     8808    int64_t i64EffAddr = 0;
     8809    switch ((bRmEx >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK)
     8810    {
     8811        case 0: break;
     8812        case 1: i64EffAddr = (int8_t)u32Disp; break;
     8813        case 2: i64EffAddr = (int32_t)u32Disp; break;
     8814        default: AssertFailed();
     8815    }
     8816
     8817    /* Get the register (or SIB) value. */
     8818    uint8_t idxGstRegBase  = UINT8_MAX;
     8819    uint8_t idxGstRegIndex = UINT8_MAX;
     8820    uint8_t cShiftIndex    = 0;
     8821    if ((bRmEx & X86_MODRM_RM_MASK) != 4)
     8822        idxGstRegBase = bRmEx & (X86_MODRM_RM_MASK | 0x8); /* bRmEx[bit 3] = REX.B */
     8823    else /* SIB: */
     8824    {
     8825        /* index /w scaling . */
     8826        cShiftIndex    = (uSibAndRspOffset >> X86_SIB_SCALE_SHIFT) & X86_SIB_SCALE_SMASK;
     8827        idxGstRegIndex = ((uSibAndRspOffset >> X86_SIB_INDEX_SHIFT) & X86_SIB_INDEX_SMASK)
     8828                       | ((bRmEx & 0x10) >> 1); /* bRmEx[bit 4] = REX.X */
     8829        if (idxGstRegIndex == 4)
     8830        {
     8831            /* no index */
     8832            cShiftIndex    = 0;
     8833            idxGstRegIndex = UINT8_MAX;
     8834        }
     8835
     8836        /* base */
     8837        idxGstRegBase = (uSibAndRspOffset & X86_SIB_BASE_MASK) | (bRmEx & 0x8); /* bRmEx[bit 3] = REX.B */
     8838        if (idxGstRegBase == 4)
     8839        {
     8840            /* pop [rsp] hack */
     8841            i64EffAddr += uSibAndRspOffset >> 8; /* (this is why i64EffAddr must be 64-bit) */
     8842        }
     8843        else if (   (idxGstRegBase & X86_SIB_BASE_MASK) == 5
     8844                 && (bRmEx & X86_MODRM_MOD_MASK) == 0)
     8845        {
     8846            /* mod=0 and base=5 -> disp32, no base reg. */
     8847            Assert(i64EffAddr == 0);
     8848            i64EffAddr    = (int32_t)u32Disp;
     8849            idxGstRegBase = UINT8_MAX;
     8850        }
     8851    }
     8852
     8853    /*
     8854     * If no registers are involved (SIB.B=5, SIB.X=4) repeat what we did at
     8855     * the start of the function.
     8856     */
     8857    if (idxGstRegBase == UINT8_MAX && idxGstRegIndex == UINT8_MAX)
     8858    {
     8859        if (f64Bit)
     8860            iemNativeVarSetKindToConst(pReNative, idxVarRet, (uint64_t)i64EffAddr);
     8861        else
     8862            iemNativeVarSetKindToConst(pReNative, idxVarRet, (uint64_t)(int32_t)i64EffAddr);
     8863        return off;
     8864    }
     8865
     8866    /*
     8867     * Now emit code that calculates:
     8868     *      idxRegRet = (uint64_t)(i64EffAddr [+ idxGstRegBase] [+ (idxGstRegIndex << cShiftIndex)])
     8869     * or if !f64Bit:
     8870     *      idxRegRet = (uint32_t)(i64EffAddr [+ idxGstRegBase] [+ (idxGstRegIndex << cShiftIndex)])
     8871     */
     8872    uint8_t const idxRegRet   = iemNativeVarAllocRegister(pReNative, idxVarRet, &off);
     8873    uint8_t       idxRegBase  = idxGstRegBase == UINT8_MAX ? UINT8_MAX
     8874                              : iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(idxGstRegBase),
     8875                                                                kIemNativeGstRegUse_ReadOnly);
     8876    uint8_t       idxRegIndex = idxGstRegIndex == UINT8_MAX ? UINT8_MAX
     8877                              : iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(idxGstRegIndex),
     8878                                                               kIemNativeGstRegUse_ReadOnly);
     8879
     8880    /* If base is not given and there is no shifting, swap the registers to avoid code duplication. */
     8881    if (idxRegBase == UINT8_MAX && cShiftIndex == 0)
     8882    {
     8883        idxRegBase  = idxRegIndex;
     8884        idxRegIndex = UINT8_MAX;
     8885    }
     8886
     8887#ifdef RT_ARCH_AMD64
     8888    uint8_t bFinalAdj;
     8889    if (!f64Bit || (int32_t)i64EffAddr == i64EffAddr)
     8890        bFinalAdj = 0; /* likely */
     8891    else
     8892    {
     8893        /* pop [rsp] with a problematic disp32 value.  Split out the
     8894           RSP offset and add it separately afterwards (bFinalAdj). */
     8895        /** @todo testcase: pop [rsp] with problematic disp32 (mod4).   */
     8896        Assert(idxGstRegBase == X86_GREG_xSP);
     8897        Assert(((bRmEx >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK) == X86_MOD_MEM4);
     8898        bFinalAdj   = (uint8_t)(uSibAndRspOffset >> 8);
     8899        Assert(bFinalAdj != 0);
     8900        i64EffAddr -= bFinalAdj;
     8901        Assert((int32_t)i64EffAddr == i64EffAddr);
     8902    }
     8903    uint32_t const u32EffAddr = (uint32_t)i64EffAddr;
     8904//pReNative->pInstrBuf[off++] = 0xcc;
     8905
     8906    if (idxRegIndex == UINT8_MAX)
     8907    {
     8908        if (u32EffAddr == 0)
     8909        {
     8910            /* mov ret, base */
     8911            if (f64Bit)
     8912                off = iemNativeEmitLoadGprFromGpr(pReNative, off, idxRegRet, idxRegBase);
     8913            else
     8914                off = iemNativeEmitLoadGprFromGpr32(pReNative, off, idxRegRet, idxRegBase);
     8915        }
     8916        else
     8917        {
     8918            /* lea ret, [base + disp32] */
     8919            Assert(idxRegBase != X86_GREG_xSP /*SIB*/);
     8920            uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8);
     8921            if (f64Bit || idxRegRet >= 8 || idxRegBase >= 8)
     8922                pbCodeBuf[off++] = (idxRegRet  >= 8 ? X86_OP_REX_R : 0)
     8923                                 | (idxRegBase >= 8 ? X86_OP_REX_B : 0)
     8924                                 | (f64Bit          ? X86_OP_REX_W : 0);
     8925            pbCodeBuf[off++] = 0x8d;
     8926            uint8_t const bMod = (int8_t)u32EffAddr == (int32_t)u32EffAddr ? X86_MOD_MEM1 : X86_MOD_MEM4;
     8927            if (idxRegBase != X86_GREG_x12 /*SIB*/)
     8928                pbCodeBuf[off++] = X86_MODRM_MAKE(bMod, idxRegRet & 7, idxRegBase & 7);
     8929            else
     8930            {
     8931                pbCodeBuf[off++] = X86_MODRM_MAKE(bMod, idxRegRet & 7, 4 /*SIB*/);
     8932                pbCodeBuf[off++] = X86_SIB_MAKE(X86_GREG_x12 & 7, 4 /*no index*/, 0);
     8933            }
     8934            pbCodeBuf[off++] = RT_BYTE1(u32EffAddr);
     8935            if (bMod == X86_MOD_MEM4)
     8936            {
     8937                pbCodeBuf[off++] = RT_BYTE2(u32EffAddr);
     8938                pbCodeBuf[off++] = RT_BYTE3(u32EffAddr);
     8939                pbCodeBuf[off++] = RT_BYTE4(u32EffAddr);
     8940            }
     8941            IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     8942        }
     8943    }
     8944    else
     8945    {
     8946        Assert(idxRegIndex != X86_GREG_xSP /*no-index*/);
     8947        uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8);
     8948        if (idxRegBase == UINT8_MAX)
     8949        {
     8950            /* lea ret, [(index64 << cShiftIndex) + disp32] */
     8951            if (f64Bit || idxRegRet >= 8 || idxRegIndex >= 8)
     8952                pbCodeBuf[off++] = (idxRegRet   >= 8 ? X86_OP_REX_R : 0)
     8953                                 | (idxRegIndex >= 8 ? X86_OP_REX_X : 0)
     8954                                 | (f64Bit           ? X86_OP_REX_W : 0);
     8955            pbCodeBuf[off++] = 0x8d;
     8956            pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM0, idxRegRet & 7, 4 /*SIB*/);
     8957            pbCodeBuf[off++] = X86_SIB_MAKE(5 /*nobase/bp*/, idxRegIndex & 7, cShiftIndex);
     8958            pbCodeBuf[off++] = RT_BYTE1(u32EffAddr);
     8959            pbCodeBuf[off++] = RT_BYTE2(u32EffAddr);
     8960            pbCodeBuf[off++] = RT_BYTE3(u32EffAddr);
     8961            pbCodeBuf[off++] = RT_BYTE4(u32EffAddr);
     8962        }
     8963        else
     8964        {
     8965            /* lea ret, [(index64 << cShiftIndex) + base64 (+ disp32)] */
     8966            if (f64Bit || idxRegRet >= 8 || idxRegBase >= 8 || idxRegIndex >= 8)
     8967                pbCodeBuf[off++] = (idxRegRet   >= 8 ? X86_OP_REX_R : 0)
     8968                                 | (idxRegBase  >= 8 ? X86_OP_REX_B : 0)
     8969                                 | (idxRegIndex >= 8 ? X86_OP_REX_X : 0)
     8970                                 | (f64Bit           ? X86_OP_REX_W : 0);
     8971            pbCodeBuf[off++] = 0x8d;
     8972            uint8_t const bMod = u32EffAddr == 0 && (idxRegBase & 7) != X86_GREG_xBP ? X86_MOD_MEM0
     8973                               : (int8_t)u32EffAddr == (int32_t)u32EffAddr           ? X86_MOD_MEM1 : X86_MOD_MEM4;
     8974            pbCodeBuf[off++] = X86_MODRM_MAKE(bMod, idxRegRet & 7, 4 /*SIB*/);
     8975            pbCodeBuf[off++] = X86_SIB_MAKE(idxRegBase & 7, idxRegIndex & 7, cShiftIndex);
     8976            if (bMod != X86_MOD_MEM0)
     8977            {
     8978                pbCodeBuf[off++] = RT_BYTE1(u32EffAddr);
     8979                if (bMod == X86_MOD_MEM4)
     8980                {
     8981                    pbCodeBuf[off++] = RT_BYTE2(u32EffAddr);
     8982                    pbCodeBuf[off++] = RT_BYTE3(u32EffAddr);
     8983                    pbCodeBuf[off++] = RT_BYTE4(u32EffAddr);
     8984                }
     8985            }
     8986        }
     8987        IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     8988    }
     8989
     8990    if (!bFinalAdj)
     8991    { /* likely */ }
     8992    else
     8993    {
     8994        Assert(f64Bit);
     8995        off = iemNativeEmitAddGprImm8(pReNative, off, idxRegRet, bFinalAdj);
     8996    }
     8997
     8998#elif defined(RT_ARCH_ARM64)
     8999    if (i64EffAddr == 0)
     9000    {
     9001        uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     9002        if (idxRegIndex == UINT8_MAX)
     9003            pu32CodeBuf[off++] = Armv8A64MkInstrMov(idxRegRet, idxRegBase, f64Bit);
     9004        else if (idxRegBase != UINT8_MAX)
     9005            pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(false /*fSub*/, idxRegRet, idxRegBase, idxRegIndex,
     9006                                                          f64Bit, false /*fSetFlags*/, cShiftIndex);
     9007        else
     9008        {
     9009            Assert(cShiftIndex != 0); /* See base = index swap above when shift is 0 and we have no base reg. */
     9010            pu32CodeBuf[off++] = Armv8A64MkInstrLslImm(idxRegRet, idxRegIndex, cShiftIndex, f64Bit);
     9011        }
     9012    }
     9013    else
     9014    {
     9015        if (f64Bit)
     9016        { /* likely */ }
     9017        else
     9018            i64EffAddr = (int32_t)i64EffAddr;
     9019
     9020        if (i64EffAddr < 4096 && i64EffAddr >= 0 && idxRegBase != UINT8_MAX)
     9021        {
     9022            uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     9023            pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(false /*fSub*/, idxRegRet, idxRegBase, i64EffAddr, f64Bit);
     9024        }
     9025        else if (i64EffAddr > -4096 && i64EffAddr < 0 && idxRegBase != UINT8_MAX)
     9026        {
     9027            uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     9028            pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, idxRegRet, idxRegBase, (uint32_t)-i64EffAddr, f64Bit);
     9029        }
     9030        else
     9031        {
     9032            if (f64Bit)
     9033                off = iemNativeEmitLoadGprImm64(pReNative, off, idxRegRet, i64EffAddr);
     9034            else
     9035                off = iemNativeEmitLoadGprImm64(pReNative, off, idxRegRet, (uint32_t)i64EffAddr);
     9036            if (idxRegBase != UINT8_MAX)
     9037            {
     9038                uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     9039                pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(false /*fSub*/, idxRegRet, idxRegRet, idxRegBase, f64Bit);
     9040            }
     9041        }
     9042        if (idxRegIndex != UINT8_MAX)
     9043        {
     9044            uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     9045            pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(false /*fSub*/, idxRegRet, idxRegRet, idxRegIndex,
     9046                                                          f64Bit, false /*fSetFlags*/, cShiftIndex);
     9047        }
     9048    }
     9049
     9050#else
     9051# error "port me"
     9052#endif
     9053
     9054    if (idxRegIndex != UINT8_MAX)
     9055        iemNativeRegFreeTmp(pReNative, idxRegIndex);
     9056    if (idxRegBase != UINT8_MAX)
     9057        iemNativeRegFreeTmp(pReNative, idxRegBase);
     9058    return off;
     9059}
     9060
    87389061
    87399062
     
    92809603                                               (uintptr_t)iemNativeHlpMemFlatStoreDataU32, pCallEntry->idxInstr)
    92819604
    9282 #define IEM_MC_STORE_MEM_FLAT_U64_CONST(_GCPtrMem, a_u64ConstValue) \
     9605#define IEM_MC_STORE_MEM_FLAT_U64_CONST(a_GCPtrMem, a_u64ConstValue) \
    92839606    off = iemNativeEmitMemStoreConstDataCommon(pReNative, off, a_u64ConstValue, UINT8_MAX, a_GCPtrMem, sizeof(uint64_t), \
    92849607                                               (uintptr_t)iemNativeHlpMemFlatStoreDataU64, pCallEntry->idxInstr)
     
    1012510448        uint32_t                offRange         = 0;
    1012610449        uint32_t                offOpcodes       = 0;
     10450        uint32_t const          cbOpcodes        = pTb->cbOpcodes;
    1012710451        RTGCPHYS                GCPhysPc         = pTb->GCPhysPc;
    1012810452        uint32_t const          cDbgEntries      = pDbgInfo->cEntries;
     
    1016210486                               of ranges, or when some complicated interrupts/FFs are found to be pending or
    1016310487                               similar.  So, we just deal with it here rather than in the compiler code as it
    10164                                is a lot simpler to do up here. */
     10488                               is a lot simpler to do here. */
    1016510489                            if (   idxRange == UINT8_MAX
    1016610490                                || idxRange >= cRanges
     
    1016910493                                idxRange += 1;
    1017010494                                if (idxRange < cRanges)
    10171                                     offRange = 0;
     10495                                    offRange = !idxRange ? 0 : offRange - pTb->aRanges[idxRange - 1].cbOpcodes;
    1017210496                                else
    1017310497                                    continue;
    10174                                 Assert(offOpcodes == pTb->aRanges[idxRange].offOpcodes);
     10498                                Assert(offOpcodes == pTb->aRanges[idxRange].offOpcodes + offRange);
    1017510499                                GCPhysPc = pTb->aRanges[idxRange].offPhysPage
    1017610500                                         + (pTb->aRanges[idxRange].idxPhysPage == 0
     
    1018010504                                                idxRange, GCPhysPc, pTb->aRanges[idxRange].cbOpcodes,
    1018110505                                                pTb->aRanges[idxRange].idxPhysPage);
     10506                                GCPhysPc += offRange;
    1018210507                            }
    1018310508
    1018410509                            /* Disassemble the instruction. */
    10185                             uint8_t const cbInstrMax = RT_MIN(pTb->aRanges[idxRange].cbOpcodes - offRange, 15);
     10510                            //uint8_t const cbInstrMax = RT_MIN(pTb->aRanges[idxRange].cbOpcodes - offRange, 15);
     10511                            uint8_t const cbInstrMax = RT_MIN(cbOpcodes - offRange, 15);
    1018610512                            uint32_t      cbInstr    = 1;
    1018710513                            int rc = DISInstrWithPrefetchedBytes(GCPhysPc, enmGstCpuMode, DISOPTYPE_ALL,
     
    1022110547                        case kIemTbDbgEntryType_ThreadedCall:
    1022210548                            pHlp->pfnPrintf(pHlp,
    10223                                             "  Call #%u to %s (%u args)%s\n",
     10549                                            "  Call #%u to %s (%u args) - %s\n",
    1022410550                                            idxThreadedCall,
    1022510551                                            g_apszIemThreadedFunctions[pDbgInfo->aEntries[iDbgEntry].ThreadedCall.enmCall],
    1022610552                                            g_acIemThreadedFunctionUsedArgs[pDbgInfo->aEntries[iDbgEntry].ThreadedCall.enmCall],
    10227                                             pDbgInfo->aEntries[iDbgEntry].ThreadedCall.fRecompiled ? " - recompiled" : "");
     10553                                            pDbgInfo->aEntries[iDbgEntry].ThreadedCall.fRecompiled ? "recompiled" : "todo");
    1022810554                            idxThreadedCall++;
    1022910555                            continue;
     
    1033110657                    uint32_t const uInfo = *(uint32_t const *)&Dis.Instr.ab[3];
    1033210658                    if (RT_HIWORD(uInfo) < kIemThreadedFunc_End)
    10333                         pHlp->pfnPrintf(pHlp, "    %p: nop ; marker: call #%u to %s (%u args)%s\n",
     10659                        pHlp->pfnPrintf(pHlp, "    %p: nop ; marker: call #%u to %s (%u args) - %s\n",
    1033410660                                        pNativeCur, uInfo & 0x7fff, g_apszIemThreadedFunctions[RT_HIWORD(uInfo)],
    1033510661                                        g_acIemThreadedFunctionUsedArgs[RT_HIWORD(uInfo)],
    10336                                         uInfo & 0x8000 ? " - recompiled" : "");
     10662                                        uInfo & 0x8000 ? "recompiled" : "todo");
    1033710663                    else
    1033810664                        pHlp->pfnPrintf(pHlp, "    %p: nop ; unknown marker: %#x (%d)\n", pNativeCur, uInfo, uInfo);
     
    1041710743                            i, GCPhysPc, pTb->aRanges[i].cbOpcodes, pTb->aRanges[i].idxPhysPage);
    1041810744            unsigned       off       = pTb->aRanges[i].offOpcodes;
     10745            /** @todo this ain't working when crossing pages!   */
    1041910746            unsigned const cbOpcodes = pTb->aRanges[i].cbOpcodes + off;
    1042010747            while (off < cbOpcodes)
     
    1046010787                    uint32_t const uInfo = *(uint32_t const *)&Dis.Instr.ab[3];
    1046110788                    if (RT_HIWORD(uInfo) < kIemThreadedFunc_End)
    10462                         pHlp->pfnPrintf(pHlp, "\n    %p: nop ; marker: call #%u to %s (%u args)%s\n",
     10789                        pHlp->pfnPrintf(pHlp, "\n    %p: nop ; marker: call #%u to %s (%u args) - %s\n",
    1046310790                                        pNativeCur, uInfo & 0x7fff, g_apszIemThreadedFunctions[RT_HIWORD(uInfo)],
    1046410791                                        g_acIemThreadedFunctionUsedArgs[RT_HIWORD(uInfo)],
    10465                                         uInfo & 0x8000 ? " - recompiled" : "");
     10792                                        uInfo & 0x8000 ? "recompiled" : "todo");
    1046610793                    else
    1046710794                        pHlp->pfnPrintf(pHlp, "    %p: nop ; unknown marker: %#x (%d)\n", pNativeCur, uInfo, uInfo);
     
    1062510952             */
    1062610953            Log2(("%u[%u]: %s%s\n", pTb->Thrd.cCalls - cCallsLeft - 1, pCallEntry->idxInstr,
    10627                   g_apszIemThreadedFunctions[pCallEntry->enmFunction], pfnRecom ? "" : "(todo)"));
     10954                  g_apszIemThreadedFunctions[pCallEntry->enmFunction], pfnRecom ? "(recompiled)" : "(todo)"));
    1062810955            if (pfnRecom) /** @todo stats on this.   */
    1062910956            {
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdFuncs.cpp

    r102011 r102510  
    537537 * @param   uSibAndRspOffset    Two parts:
    538538 *                                - The first 8 bits make up the SIB byte.
    539  *                                - The next 8 bits are the fixed RSP/ESP offse
     539 *                                - The next 8 bits are the fixed RSP/ESP offset
    540540 *                                  in case of a pop [xSP].
    541541 * @param   u32Disp             The displacement byte/word/dword, if any.
  • trunk/src/VBox/VMM/include/IEMMc.h

    r102471 r102510  
    979979    iemMemFlatFetchDataR80Jmp(pVCpu, &(a_r80Dst), (a_GCPtrMem))
    980980# define IEM_MC_FETCH_MEM_FLAT_D80(a_d80Dst, a_GCPtrMem) \
    981     iemMemFetchDataD80Jmp(pVCpu, &(a_d80Dst), UINT8_MAX, (a_GCPtrMem))
     981    iemMemFlatFetchDataD80Jmp(pVCpu, &(a_d80Dst), (a_GCPtrMem))
    982982#endif
    983983
     
    10781078    (a_XmmDst).au32[(a_iDWord)] = iemMemFlatFetchDataU32Jmp(pVCpu, (a_GCPtrMem))
    10791079# define IEM_MC_FETCH_MEM_FLAT_XMM_U64(a_XmmDst, a_iQWord, a_GCPtrMem) \
    1080     (a_XmmDst).au64[(a_iQWord)] = iemMemFetchDataU64Jmp(pVCpu, UINT8_MAX, (a_GCPtrMem))
     1080    (a_XmmDst).au64[(a_iQWord)] = iemMemFlatFetchDataU64Jmp(pVCpu, (a_GCPtrMem))
    10811081
    10821082# define IEM_MC_FETCH_MEM_U128_AND_XREG_U128(a_Dst, a_iXReg1, a_iSeg2, a_GCPtrMem2) do { \
  • trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h

    r102447 r102510  
    105105*********************************************************************************************************************************/
    106106
     107#ifdef RT_ARCH_AMD64
     108/**
     109 * Common bit of iemNativeEmitLoadGprByGpr and friends.
     110 */
     111DECL_FORCE_INLINE(uint32_t)
     112iemNativeEmitGprByGprDisp(uint8_t *pbCodeBuf, uint32_t off, uint8_t iGprReg, uint8_t iGprBase, int32_t offDisp)
     113{
     114    if (offDisp == 0 && (iGprBase & 7) != X86_GREG_xBP) /* Can use encoding w/o displacement field. */
     115    {
     116        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM0, iGprReg & 7, iGprBase & 7);
     117        if ((iGprBase & 7) == X86_GREG_xSP) /* for RSP/R12 relative addressing we have to use a SIB byte. */
     118            pbCodeBuf[off++] = X86_SIB_MAKE(X86_GREG_xSP, X86_GREG_xSP, 0); /* -> [RSP/R12] */
     119    }
     120    else if (offDisp == (int8_t)offDisp)
     121    {
     122        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM1, iGprReg & 7, iGprBase & 7);
     123        if ((iGprBase & 7) == X86_GREG_xSP) /* for RSP/R12 relative addressing we have to use a SIB byte. */
     124            pbCodeBuf[off++] = X86_SIB_MAKE(X86_GREG_xSP, X86_GREG_xSP, 0); /* -> [RSP/R12] */
     125        pbCodeBuf[off++] = (uint8_t)offDisp;
     126    }
     127    else
     128    {
     129        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM4, iGprReg & 7, iGprBase & 7);
     130        if ((iGprBase & 7) == X86_GREG_xSP) /* for RSP/R12 relative addressing we have to use a SIB byte. */
     131            pbCodeBuf[off++] = X86_SIB_MAKE(X86_GREG_xSP, X86_GREG_xSP, 0); /* -> [RSP/R12] */
     132        pbCodeBuf[off++] = RT_BYTE1((uint32_t)offDisp);
     133        pbCodeBuf[off++] = RT_BYTE2((uint32_t)offDisp);
     134        pbCodeBuf[off++] = RT_BYTE3((uint32_t)offDisp);
     135        pbCodeBuf[off++] = RT_BYTE4((uint32_t)offDisp);
     136    }
     137    return off;
     138}
     139#endif /* RT_ARCH_AMD64 */
     140
    107141/**
    108142 * Emits setting a GPR to zero.
     
    889923/**
    890924 * Sign-extends 8-bit value in @a iGprSrc into a 32-bit value in @a iGprDst.
    891  * @note Bits 64 thru 32 are cleared.
     925 * @note Bits 63 thru 32 are cleared.
    892926 */
    893927DECL_INLINE_THROW(uint32_t)
     
    918952/**
    919953 * Sign-extends 8-bit value in @a iGprSrc into a 16-bit value in @a iGprDst.
    920  * @note Bits 64 thru 16 are cleared.
     954 * @note Bits 63 thru 16 are cleared.
    921955 */
    922956DECL_INLINE_THROW(uint32_t)
     
    957991/**
    958992 * Emits a gprdst = gprsrc + addend load.
    959  */
     993 * @note The added is 32-bit for AMD64 and 64-bit for ARM64.
     994 */
     995#ifdef RT_ARCH_AMD64
    960996DECL_INLINE_THROW(uint32_t)
    961997iemNativeEmitLoadGprFromGprWithAddend(PIEMRECOMPILERSTATE pReNative, uint32_t off,
     
    9641000    Assert(iAddend != 0);
    9651001
    966 #ifdef RT_ARCH_AMD64
    9671002    /* lea gprdst, [gprsrc + iAddend] */
    968     uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7);
    969     if ((iGprDst | iGprSrc) >= 8)
    970         pbCodeBuf[off++] = iGprDst < 8  ? X86_OP_REX_W | X86_OP_REX_B
    971                          : iGprSrc >= 8 ? X86_OP_REX_W | X86_OP_REX_R | X86_OP_REX_B
    972                          :                X86_OP_REX_W | X86_OP_REX_R;
    973     else
    974         pbCodeBuf[off++] = X86_OP_REX_W;
     1003    uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8);
     1004    pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst >= 8 ? X86_OP_REX_R : 0) | (iGprSrc >= 8 ? X86_OP_REX_B : 0);
    9751005    pbCodeBuf[off++] = 0x8d;
    976     if (iAddend >= -128 && iAddend < 128)
    977     {
    978         pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM1, iGprDst & 7, iGprSrc & 7);
    979         pbCodeBuf[off++] = (int8_t)iAddend;
    980     }
    981     else
    982     {
    983         pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM4, iGprDst & 7, iGprSrc & 7);
    984         pbCodeBuf[off++] = RT_BYTE1((uint32_t)iAddend);
    985         pbCodeBuf[off++] = RT_BYTE2((uint32_t)iAddend);
    986         pbCodeBuf[off++] = RT_BYTE3((uint32_t)iAddend);
    987         pbCodeBuf[off++] = RT_BYTE4((uint32_t)iAddend);
    988     }
    989 
    990 #elif defined(RT_ARCH_ARM64)
     1006    off = iemNativeEmitGprByGprDisp(pbCodeBuf, off, iGprDst, iGprSrc, iAddend);
     1007    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     1008    return off;
     1009}
     1010
     1011#elif defined(RT_ARCH_ARM64)
     1012DECL_INLINE_THROW(uint32_t)
     1013iemNativeEmitLoadGprFromGprWithAddend(PIEMRECOMPILERSTATE pReNative, uint32_t off,
     1014                                      uint8_t iGprDst, uint8_t iGprSrc, int64_t iAddend)
     1015{
    9911016    if ((uint32_t)iAddend < 4096)
    9921017    {
     
    10031028    else
    10041029    {
     1030        Assert(iGprSrc != iGprDst);
     1031        off = iemNativeEmitLoadGprImm64(pReNative, off, iGprDst, iAddend);
     1032        uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     1033        pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(false /*fSub*/, iGprDst, iGprSrc, iGprDst);
     1034    }
     1035    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     1036    return off;
     1037}
     1038#else
     1039# error "port me"
     1040#endif
     1041
     1042/**
     1043 * Emits a gprdst = gprsrc + addend load, accepting iAddend == 0.
     1044 * @note The added is 32-bit for AMD64 and 64-bit for ARM64.
     1045 */
     1046#ifdef RT_ARCH_AMD64
     1047DECL_INLINE_THROW(uint32_t)
     1048iemNativeEmitLoadGprFromGprWithAddendMaybeZero(PIEMRECOMPILERSTATE pReNative, uint32_t off,
     1049                                               uint8_t iGprDst, uint8_t iGprSrc, int32_t iAddend)
     1050#else
     1051DECL_INLINE_THROW(uint32_t)
     1052iemNativeEmitLoadGprFromGprWithAddendMaybeZero(PIEMRECOMPILERSTATE pReNative, uint32_t off,
     1053                                               uint8_t iGprDst, uint8_t iGprSrc, int64_t iAddend)
     1054#endif
     1055{
     1056    if (iAddend != 0)
     1057        return iemNativeEmitLoadGprFromGprWithAddend(pReNative, off, iGprDst, iGprSrc, iAddend);
     1058    return iemNativeEmitLoadGprFromGpr(pReNative, off, iGprDst, iGprSrc);
     1059}
     1060
     1061
     1062/**
     1063 * Emits a gprdst = gprsrc32 + addend load.
     1064 * @note Bits 63 thru 32 are cleared.
     1065 */
     1066DECL_INLINE_THROW(uint32_t)
     1067iemNativeEmitLoadGprFromGpr32WithAddend(PIEMRECOMPILERSTATE pReNative, uint32_t off,
     1068                                        uint8_t iGprDst, uint8_t iGprSrc, int32_t iAddend)
     1069{
     1070    Assert(iAddend != 0);
     1071
     1072#ifdef RT_ARCH_AMD64
     1073    /* a32 o32 lea gprdst, [gprsrc + iAddend] */
     1074    uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 9);
     1075    pbCodeBuf[off++] = X86_OP_PRF_SIZE_ADDR;
     1076    if ((iGprDst | iGprSrc) >= 8)
     1077        pbCodeBuf[off++] = (iGprDst >= 8 ? X86_OP_REX_R : 0) | (iGprSrc >= 8 ? X86_OP_REX_B : 0);
     1078    pbCodeBuf[off++] = 0x8d;
     1079    off = iemNativeEmitGprByGprDisp(pbCodeBuf, off, iGprDst, iGprSrc, iAddend);
     1080
     1081#elif defined(RT_ARCH_ARM64)
     1082    if ((uint32_t)iAddend < 4096)
     1083    {
     1084        /* add dst, src, uimm12 */
     1085        uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     1086        pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(false /*fSub*/, iGprDst, iGprSrc, (uint32_t)iAddend, false /*f64Bit*/);
     1087    }
     1088    else if ((uint32_t)-iAddend < 4096)
     1089    {
     1090        /* sub dst, src, uimm12 */
     1091        uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     1092        pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, iGprDst, iGprSrc, (uint32_t)-iAddend, false /*f64Bit*/);
     1093    }
     1094    else
     1095    {
     1096        Assert(iGprSrc != iGprDst);
    10051097        off = iemNativeEmitLoadGprImm64(pReNative, off, iGprDst, (int64_t)iAddend);
    10061098        uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
    1007         pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(false /*fSub*/, iGprDst, iGprSrc, iGprDst);
    1008     }
    1009 
    1010 #else
    1011 # error "port me"
    1012 #endif
    1013     IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
    1014     return off;
    1015 }
     1099        pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(false /*fSub*/, iGprDst, iGprSrc, iGprDst, false /*f64Bit*/);
     1100    }
     1101
     1102#else
     1103# error "port me"
     1104#endif
     1105    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     1106    return off;
     1107}
     1108
     1109
     1110/**
     1111 * Emits a gprdst = gprsrc32 + addend load, accepting iAddend == 0.
     1112 */
     1113DECL_INLINE_THROW(uint32_t)
     1114iemNativeEmitLoadGprFromGpr32WithAddendMaybeZero(PIEMRECOMPILERSTATE pReNative, uint32_t off,
     1115                                                 uint8_t iGprDst, uint8_t iGprSrc, int32_t iAddend)
     1116{
     1117    if (iAddend != 0)
     1118        return iemNativeEmitLoadGprFromGpr32WithAddend(pReNative, off, iGprDst, iGprSrc, iAddend);
     1119    return iemNativeEmitLoadGprFromGpr32(pReNative, off, iGprDst, iGprSrc);
     1120}
     1121
    10161122
    10171123
     
    13191425
    13201426
    1321 #ifdef RT_ARCH_AMD64
    1322 /**
    1323  * Common bit of iemNativeEmitLoadGprByGpr and friends.
    1324  */
    1325 DECL_FORCE_INLINE(uint32_t)
    1326 iemNativeEmitGprByGprDisp(uint8_t *pbCodeBuf, uint32_t off, uint8_t iGprReg, uint8_t iGprBase, int32_t offDisp)
    1327 {
    1328     if (offDisp == 0 && (iGprBase & 7) != X86_GREG_xBP) /* Can use encoding w/o displacement field. */
    1329     {
    1330         pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM0, iGprReg & 7, iGprBase & 7);
    1331         if ((iGprBase & 7) == X86_GREG_xSP) /* for RSP/R12 relative addressing we have to use a SIB byte. */
    1332             pbCodeBuf[off++] = X86_SIB_MAKE(X86_GREG_xSP, X86_GREG_xSP, 0); /* -> [RSP/R12] */
    1333     }
    1334     else if (offDisp == (int8_t)offDisp)
    1335     {
    1336         pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM1, iGprReg & 7, iGprBase & 7);
    1337         if ((iGprBase & 7) == X86_GREG_xSP) /* for RSP/R12 relative addressing we have to use a SIB byte. */
    1338             pbCodeBuf[off++] = X86_SIB_MAKE(X86_GREG_xSP, X86_GREG_xSP, 0); /* -> [RSP/R12] */
    1339         pbCodeBuf[off++] = (uint8_t)offDisp;
    1340     }
    1341     else
    1342     {
    1343         pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM1, iGprReg & 7, iGprBase & 7);
    1344         if ((iGprBase & 7) == X86_GREG_xSP) /* for RSP/R12 relative addressing we have to use a SIB byte. */
    1345             pbCodeBuf[off++] = X86_SIB_MAKE(X86_GREG_xSP, X86_GREG_xSP, 0); /* -> [RSP/R12] */
    1346         pbCodeBuf[off++] = RT_BYTE1((uint32_t)offDisp);
    1347         pbCodeBuf[off++] = RT_BYTE2((uint32_t)offDisp);
    1348         pbCodeBuf[off++] = RT_BYTE3((uint32_t)offDisp);
    1349         pbCodeBuf[off++] = RT_BYTE4((uint32_t)offDisp);
    1350     }
    1351     return off;
    1352 }
    1353 #elif defined(RT_ARCH_ARM64)
     1427#if defined(RT_ARCH_ARM64)
    13541428/**
    13551429 * Common bit of iemNativeEmitLoadGprFromVCpuU64 and friends.
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