VirtualBox

Ignore:
Timestamp:
Dec 4, 2023 1:05:53 PM (14 months ago)
Author:
vboxsync
Message:

VMM/IEM: movsx & movzx from registers. bugref:10371

File:
1 edited

Legend:

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

    r102444 r102447  
    72567256
    72577257#define IEM_MC_FETCH_GREG_U8_THREADED(a_u8Dst, a_iGRegEx) \
    7258     off = iemNativeEmitFetchGregU8(pReNative, off, a_u8Dst, a_iGRegEx)
    7259 
    7260 /** Emits code for IEM_MC_FETCH_GREG_U8. */
     7258    off = iemNativeEmitFetchGregU8(pReNative, off, a_u8Dst,  a_iGRegEx, sizeof(uint8_t) /*cbZeroExtended*/)
     7259
     7260#define IEM_MC_FETCH_GREG_U8_ZX_U16_THREADED(a_u16Dst, a_iGRegEx) \
     7261    off = iemNativeEmitFetchGregU8(pReNative, off, a_u16Dst, a_iGRegEx, sizeof(uint16_t) /*cbZeroExtended*/)
     7262
     7263#define IEM_MC_FETCH_GREG_U8_ZX_U32_THREADED(a_u32Dst, a_iGRegEx) \
     7264    off = iemNativeEmitFetchGregU8(pReNative, off, a_u32Dst, a_iGRegEx, sizeof(uint32_t) /*cbZeroExtended*/)
     7265
     7266#define IEM_MC_FETCH_GREG_U8_ZX_U64_THREADED(a_u64Dst, a_iGRegEx) \
     7267    off = iemNativeEmitFetchGregU8(pReNative, off, a_u64Dst, a_iGRegEx, sizeof(uint64_t) /*cbZeroExtended*/)
     7268
     7269
     7270/** Emits code for IEM_MC_FETCH_GREG_U8_THREADED and
     7271 *  IEM_MC_FETCH_GREG_U8_ZX_U16/32/64_THREADED. */
    72617272DECL_INLINE_THROW(uint32_t)
    7262 iemNativeEmitFetchGregU8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGRegEx)
     7273iemNativeEmitFetchGregU8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGRegEx, int8_t cbZeroExtended)
    72637274{
    72647275    Assert(idxDstVar < RT_ELEMENTS(pReNative->Core.aVars) && (pReNative->Core.bmVars & RT_BIT_32(idxDstVar)));
    7265     Assert(pReNative->Core.aVars[idxDstVar].cbVar == sizeof(uint8_t));
     7276    Assert(pReNative->Core.aVars[idxDstVar].cbVar == cbZeroExtended); RT_NOREF(cbZeroExtended);
    72667277    Assert(iGRegEx < 20);
    72677278
     
    72737284    uint8_t const idxVarReg = iemNativeVarAllocRegister(pReNative, idxDstVar, &off);
    72747285
     7286    /* The value is zero-extended to the full 64-bit host register width. */
    72757287    if (iGRegEx < 16)
    72767288        off = iemNativeEmitLoadGprFromGpr8(pReNative, off, idxVarReg, idxGstFullReg);
     
    72837295
    72847296
     7297#define IEM_MC_FETCH_GREG_U8_SX_U16_THREADED(a_u16Dst, a_iGRegEx) \
     7298    off = iemNativeEmitFetchGregU8Sx(pReNative, off, a_u16Dst, a_iGRegEx, sizeof(uint16_t))
     7299
     7300#define IEM_MC_FETCH_GREG_U8_SX_U32_THREADED(a_u32Dst, a_iGRegEx) \
     7301    off = iemNativeEmitFetchGregU8Sx(pReNative, off, a_u32Dst, a_iGRegEx, sizeof(uint32_t))
     7302
     7303#define IEM_MC_FETCH_GREG_U8_SX_U64_THREADED(a_u64Dst, a_iGRegEx) \
     7304    off = iemNativeEmitFetchGregU8Sx(pReNative, off, a_u64Dst, a_iGRegEx, sizeof(uint64_t))
     7305
     7306/** Emits code for IEM_MC_FETCH_GREG_U8_SX_U16/32/64_THREADED. */
     7307DECL_INLINE_THROW(uint32_t)
     7308iemNativeEmitFetchGregU8Sx(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGRegEx, uint8_t cbSignExtended)
     7309{
     7310    Assert(idxDstVar < RT_ELEMENTS(pReNative->Core.aVars) && (pReNative->Core.bmVars & RT_BIT_32(idxDstVar)));
     7311    Assert(pReNative->Core.aVars[idxDstVar].cbVar == cbSignExtended);
     7312    Assert(iGRegEx < 20);
     7313
     7314    /* Same discussion as in iemNativeEmitFetchGregU16 */
     7315    uint8_t const idxGstFullReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(iGRegEx & 15),
     7316                                                                  kIemNativeGstRegUse_ReadOnly);
     7317
     7318    iemNativeVarSetKindToStack(pReNative, idxDstVar);
     7319    uint8_t const idxVarReg = iemNativeVarAllocRegister(pReNative, idxDstVar, &off);
     7320
     7321    if (iGRegEx < 16)
     7322    {
     7323        switch (cbSignExtended)
     7324        {
     7325            case sizeof(uint16_t):
     7326                off = iemNativeEmitLoadGpr16SignExtendedFromGpr8(pReNative, off, idxVarReg, idxGstFullReg);
     7327                break;
     7328            case sizeof(uint32_t):
     7329                off = iemNativeEmitLoadGpr32SignExtendedFromGpr8(pReNative, off, idxVarReg, idxGstFullReg);
     7330                break;
     7331            case sizeof(uint64_t):
     7332                off = iemNativeEmitLoadGprSignExtendedFromGpr8(pReNative, off, idxVarReg, idxGstFullReg);
     7333                break;
     7334            default: AssertFailed(); break;
     7335        }
     7336    }
     7337    else
     7338    {
     7339        off = iemNativeEmitLoadGprFromGpr8Hi(pReNative, off, idxVarReg, idxGstFullReg);
     7340        switch (cbSignExtended)
     7341        {
     7342            case sizeof(uint16_t):
     7343                off = iemNativeEmitLoadGpr16SignExtendedFromGpr8(pReNative, off, idxVarReg, idxVarReg);
     7344                break;
     7345            case sizeof(uint32_t):
     7346                off = iemNativeEmitLoadGpr32SignExtendedFromGpr8(pReNative, off, idxVarReg, idxVarReg);
     7347                break;
     7348            case sizeof(uint64_t):
     7349                off = iemNativeEmitLoadGprSignExtendedFromGpr8(pReNative, off, idxVarReg, idxVarReg);
     7350                break;
     7351            default: AssertFailed(); break;
     7352        }
     7353    }
     7354
     7355    iemNativeRegFreeTmp(pReNative, idxGstFullReg);
     7356    return off;
     7357}
     7358
     7359
     7360
    72857361#define IEM_MC_FETCH_GREG_U16(a_u16Dst, a_iGReg) \
    7286     off = iemNativeEmitFetchGregU16(pReNative, off, a_u16Dst, a_iGReg)
    7287 
    7288 /** Emits code for IEM_MC_FETCH_GREG_U16. */
     7362    off = iemNativeEmitFetchGregU16(pReNative, off, a_u16Dst, a_iGReg, sizeof(uint16_t))
     7363
     7364#define IEM_MC_FETCH_GREG_U16_ZX_U32(a_u16Dst, a_iGReg) \
     7365    off = iemNativeEmitFetchGregU16(pReNative, off, a_u16Dst, a_iGReg, sizeof(uint32_t))
     7366
     7367#define IEM_MC_FETCH_GREG_U16_ZX_U64(a_u16Dst, a_iGReg) \
     7368    off = iemNativeEmitFetchGregU16(pReNative, off, a_u16Dst, a_iGReg, sizeof(uint64_t))
     7369
     7370/** Emits code for IEM_MC_FETCH_GREG_U16 and IEM_MC_FETCH_GREG_U16_ZX_U32/64. */
    72897371DECL_INLINE_THROW(uint32_t)
    7290 iemNativeEmitFetchGregU16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGReg)
     7372iemNativeEmitFetchGregU16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGReg, uint8_t cbZeroExtended)
    72917373{
    72927374    Assert(idxDstVar < RT_ELEMENTS(pReNative->Core.aVars) && (pReNative->Core.bmVars & RT_BIT_32(idxDstVar)));
    7293     Assert(pReNative->Core.aVars[idxDstVar].cbVar == sizeof(uint16_t));
     7375    Assert(pReNative->Core.aVars[idxDstVar].cbVar == cbZeroExtended); RT_NOREF(cbZeroExtended);
    72947376    Assert(iGReg < 16);
    72957377
     
    73137395
    73147396
    7315 #define IEM_MC_FETCH_GREG_U32(a_u32Dst, a_iGReg) \
    7316     off = iemNativeEmitFetchGregU32(pReNative, off, a_u32Dst, a_iGReg)
    7317 
    7318 /** Emits code for IEM_MC_FETCH_GREG_U32. */
     7397#define IEM_MC_FETCH_GREG_U16_SX_U32(a_u16Dst, a_iGReg) \
     7398    off = iemNativeEmitFetchGregU16Sx(pReNative, off, a_u16Dst, a_iGReg, sizeof(uint32_t))
     7399
     7400#define IEM_MC_FETCH_GREG_U16_SX_U64(a_u16Dst, a_iGReg) \
     7401    off = iemNativeEmitFetchGregU16Sx(pReNative, off, a_u16Dst, a_iGReg, sizeof(uint64_t))
     7402
     7403/** Emits code for IEM_MC_FETCH_GREG_U16_SX_U32/64. */
    73197404DECL_INLINE_THROW(uint32_t)
    7320 iemNativeEmitFetchGregU32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGReg)
     7405iemNativeEmitFetchGregU16Sx(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGReg, uint8_t cbSignExtended)
    73217406{
    73227407    Assert(idxDstVar < RT_ELEMENTS(pReNative->Core.aVars) && (pReNative->Core.bmVars & RT_BIT_32(idxDstVar)));
    7323     Assert(pReNative->Core.aVars[idxDstVar].cbVar == sizeof(uint32_t));
     7408    Assert(pReNative->Core.aVars[idxDstVar].cbVar == cbSignExtended);
    73247409    Assert(iGReg < 16);
    73257410
     
    73367421    iemNativeVarSetKindToStack(pReNative, idxDstVar);
    73377422    uint8_t const idxVarReg = iemNativeVarAllocRegister(pReNative, idxDstVar, &off);
     7423    if (cbSignExtended == sizeof(uint32_t))
     7424        off = iemNativeEmitLoadGpr32SignExtendedFromGpr16(pReNative, off, idxVarReg, idxGstFullReg);
     7425    else
     7426    {
     7427        Assert(cbSignExtended == sizeof(uint64_t));
     7428        off = iemNativeEmitLoadGprSignExtendedFromGpr16(pReNative, off, idxVarReg, idxGstFullReg);
     7429    }
     7430
     7431    iemNativeRegFreeTmp(pReNative, idxGstFullReg);
     7432    return off;
     7433}
     7434
     7435
     7436#define IEM_MC_FETCH_GREG_U32(a_u32Dst, a_iGReg) \
     7437    off = iemNativeEmitFetchGregU32(pReNative, off, a_u32Dst, a_iGReg, sizeof(uint32_t))
     7438
     7439#define IEM_MC_FETCH_GREG_U32_ZX_U64(a_u32Dst, a_iGReg) \
     7440    off = iemNativeEmitFetchGregU32(pReNative, off, a_u32Dst, a_iGReg, sizeof(uint64_t))
     7441
     7442/** Emits code for IEM_MC_FETCH_GREG_U32. */
     7443DECL_INLINE_THROW(uint32_t)
     7444iemNativeEmitFetchGregU32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGReg, uint8_t cbZeroExtended)
     7445{
     7446    Assert(idxDstVar < RT_ELEMENTS(pReNative->Core.aVars) && (pReNative->Core.bmVars & RT_BIT_32(idxDstVar)));
     7447    Assert(pReNative->Core.aVars[idxDstVar].cbVar == cbZeroExtended); RT_NOREF_PV(cbZeroExtended);
     7448    Assert(iGReg < 16);
     7449
     7450    /*
     7451     * We can either just load the low 16-bit of the GPR into a host register
     7452     * for the variable, or we can do so via a shadow copy host register. The
     7453     * latter will avoid having to reload it if it's being stored later, but
     7454     * will waste a host register if it isn't touched again.  Since we don't
     7455     * know what going to happen, we choose the latter for now.
     7456     */
     7457    uint8_t const idxGstFullReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(iGReg),
     7458                                                                  kIemNativeGstRegUse_ReadOnly);
     7459
     7460    iemNativeVarSetKindToStack(pReNative, idxDstVar);
     7461    uint8_t const idxVarReg = iemNativeVarAllocRegister(pReNative, idxDstVar, &off);
    73387462    off = iemNativeEmitLoadGprFromGpr32(pReNative, off, idxVarReg, idxGstFullReg);
     7463
     7464    iemNativeRegFreeTmp(pReNative, idxGstFullReg);
     7465    return off;
     7466}
     7467
     7468
     7469#define IEM_MC_FETCH_GREG_U32_SX_U64(a_u32Dst, a_iGReg) \
     7470    off = iemNativeEmitFetchGregU32SxU64(pReNative, off, a_u32Dst, a_iGReg)
     7471
     7472/** Emits code for IEM_MC_FETCH_GREG_U32. */
     7473DECL_INLINE_THROW(uint32_t)
     7474iemNativeEmitFetchGregU32SxU64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGReg)
     7475{
     7476    Assert(idxDstVar < RT_ELEMENTS(pReNative->Core.aVars) && (pReNative->Core.bmVars & RT_BIT_32(idxDstVar)));
     7477    Assert(pReNative->Core.aVars[idxDstVar].cbVar == sizeof(uint64_t));
     7478    Assert(iGReg < 16);
     7479
     7480    /*
     7481     * We can either just load the low 16-bit of the GPR into a host register
     7482     * for the variable, or we can do so via a shadow copy host register. The
     7483     * latter will avoid having to reload it if it's being stored later, but
     7484     * will waste a host register if it isn't touched again.  Since we don't
     7485     * know what going to happen, we choose the latter for now.
     7486     */
     7487    uint8_t const idxGstFullReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(iGReg),
     7488                                                                  kIemNativeGstRegUse_ReadOnly);
     7489
     7490    iemNativeVarSetKindToStack(pReNative, idxDstVar);
     7491    uint8_t const idxVarReg = iemNativeVarAllocRegister(pReNative, idxDstVar, &off);
     7492    off = iemNativeEmitLoadGprSignExtendedFromGpr32(pReNative, off, idxVarReg, idxGstFullReg);
    73397493
    73407494    iemNativeRegFreeTmp(pReNative, idxGstFullReg);
     
    94229576     */
    94239577//pReNative->pInstrBuf[off++] = 0xcc;
     9578    RT_NOREF(fAccess);
    94249579
    94259580#ifdef RT_ARCH_AMD64
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