VirtualBox

Changeset 102447 in vbox for trunk/src


Ignore:
Timestamp:
Dec 4, 2023 1:05:53 PM (18 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
160590
Message:

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

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py

    r102443 r102447  
    28742874    'IEM_MC_FETCH_FSW':                                          (McBlock.parseMcGeneric,           False, False, ),
    28752875    'IEM_MC_FETCH_GREG_U16':                                     (McBlock.parseMcGeneric,           False, True,  ),
    2876     'IEM_MC_FETCH_GREG_U16_SX_U32':                              (McBlock.parseMcGeneric,           False, False, ),
    2877     'IEM_MC_FETCH_GREG_U16_SX_U64':                              (McBlock.parseMcGeneric,           False, False, ),
    2878     'IEM_MC_FETCH_GREG_U16_ZX_U32':                              (McBlock.parseMcGeneric,           False, False, ),
    2879     'IEM_MC_FETCH_GREG_U16_ZX_U64':                              (McBlock.parseMcGeneric,           False, False, ),
     2876    'IEM_MC_FETCH_GREG_U16_SX_U32':                              (McBlock.parseMcGeneric,           False, True, ),
     2877    'IEM_MC_FETCH_GREG_U16_SX_U64':                              (McBlock.parseMcGeneric,           False, True, ),
     2878    'IEM_MC_FETCH_GREG_U16_ZX_U32':                              (McBlock.parseMcGeneric,           False, True, ),
     2879    'IEM_MC_FETCH_GREG_U16_ZX_U64':                              (McBlock.parseMcGeneric,           False, True, ),
    28802880    'IEM_MC_FETCH_GREG_U32':                                     (McBlock.parseMcGeneric,           False, True,  ),
    2881     'IEM_MC_FETCH_GREG_U32_SX_U64':                              (McBlock.parseMcGeneric,           False, False, ),
    2882     'IEM_MC_FETCH_GREG_U32_ZX_U64':                              (McBlock.parseMcGeneric,           False, False, ),
     2881    'IEM_MC_FETCH_GREG_U32_SX_U64':                              (McBlock.parseMcGeneric,           False, True, ),
     2882    'IEM_MC_FETCH_GREG_U32_ZX_U64':                              (McBlock.parseMcGeneric,           False, True, ),
    28832883    'IEM_MC_FETCH_GREG_U64':                                     (McBlock.parseMcGeneric,           False, False, ),
    28842884    'IEM_MC_FETCH_GREG_U64_ZX_U64':                              (McBlock.parseMcGeneric,           False, False, ),
    2885     'IEM_MC_FETCH_GREG_U8':                                      (McBlock.parseMcGeneric,           False, False, ),
    2886     'IEM_MC_FETCH_GREG_U8_SX_U16':                               (McBlock.parseMcGeneric,           False, False, ),
    2887     'IEM_MC_FETCH_GREG_U8_SX_U32':                               (McBlock.parseMcGeneric,           False, False, ),
    2888     'IEM_MC_FETCH_GREG_U8_SX_U64':                               (McBlock.parseMcGeneric,           False, False, ),
    2889     'IEM_MC_FETCH_GREG_U8_ZX_U16':                               (McBlock.parseMcGeneric,           False, False, ),
    2890     'IEM_MC_FETCH_GREG_U8_ZX_U32':                               (McBlock.parseMcGeneric,           False, False, ),
    2891     'IEM_MC_FETCH_GREG_U8_ZX_U64':                               (McBlock.parseMcGeneric,           False, False, ),
     2885    'IEM_MC_FETCH_GREG_U8':                                      (McBlock.parseMcGeneric,           False, True, ),
     2886    'IEM_MC_FETCH_GREG_U8_SX_U16':                               (McBlock.parseMcGeneric,           False, True, ),
     2887    'IEM_MC_FETCH_GREG_U8_SX_U32':                               (McBlock.parseMcGeneric,           False, True, ),
     2888    'IEM_MC_FETCH_GREG_U8_SX_U64':                               (McBlock.parseMcGeneric,           False, True, ),
     2889    'IEM_MC_FETCH_GREG_U8_ZX_U16':                               (McBlock.parseMcGeneric,           False, True, ),
     2890    'IEM_MC_FETCH_GREG_U8_ZX_U32':                               (McBlock.parseMcGeneric,           False, True, ),
     2891    'IEM_MC_FETCH_GREG_U8_ZX_U64':                               (McBlock.parseMcGeneric,           False, True, ),
    28922892    'IEM_MC_FETCH_GREG_PAIR_U32':                                (McBlock.parseMcGeneric,           False, False, ),
    28932893    'IEM_MC_FETCH_GREG_PAIR_U64':                                (McBlock.parseMcGeneric,           False, False, ),
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py

    r102444 r102447  
    9393    'IEM_MC_STORE_GREG_U8_CONST_THREADED':                       (None, True,  True,  ),
    9494    'IEM_MC_FETCH_GREG_U8_THREADED':                             (None, False, True,  ),
    95     'IEM_MC_FETCH_GREG_U8_SX_U16_THREADED':                      (None, False, False, ),
    96     'IEM_MC_FETCH_GREG_U8_SX_U32_THREADED':                      (None, False, False, ),
    97     'IEM_MC_FETCH_GREG_U8_SX_U64_THREADED':                      (None, False, False, ),
    98     'IEM_MC_FETCH_GREG_U8_ZX_U16_THREADED':                      (None, False, False, ),
    99     'IEM_MC_FETCH_GREG_U8_ZX_U32_THREADED':                      (None, False, False, ),
    100     'IEM_MC_FETCH_GREG_U8_ZX_U64_THREADED':                      (None, False, False, ),
     95    'IEM_MC_FETCH_GREG_U8_SX_U16_THREADED':                      (None, False, True, ),
     96    'IEM_MC_FETCH_GREG_U8_SX_U32_THREADED':                      (None, False, True, ),
     97    'IEM_MC_FETCH_GREG_U8_SX_U64_THREADED':                      (None, False, True, ),
     98    'IEM_MC_FETCH_GREG_U8_ZX_U16_THREADED':                      (None, False, True, ),
     99    'IEM_MC_FETCH_GREG_U8_ZX_U32_THREADED':                      (None, False, True, ),
     100    'IEM_MC_FETCH_GREG_U8_ZX_U64_THREADED':                      (None, False, True, ),
    101101    'IEM_MC_REF_GREG_U8_THREADED':                               (None, True,  True,  ),
    102102
  • 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
  • trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h

    r102444 r102447  
    770770    uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
    771771    pu32CodeBuf[off++] = Armv8A64MkInstrUbfx(iGprDst, iGprSrc, 8, 8, false /*f64Bit*/);
     772
     773#else
     774# error "port me"
     775#endif
     776    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     777    return off;
     778}
     779
     780
     781/**
     782 * Sign-extends 32-bit value in @a iGprSrc into a 64-bit value in @a iGprDst.
     783 */
     784DECL_INLINE_THROW(uint32_t)
     785iemNativeEmitLoadGprSignExtendedFromGpr32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc)
     786{
     787#ifdef RT_ARCH_AMD64
     788    /* movsxd r64, r/m32 */
     789    uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3);
     790    pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B);
     791    pbCodeBuf[off++] = 0x63;
     792    pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7);
     793
     794#elif defined(RT_ARCH_ARM64)
     795    /* sxtw dst, src */
     796    uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     797    pu32CodeBuf[off++] = Armv8A64MkInstrSxtw(iGprDst, iGprSrc);
     798
     799#else
     800# error "port me"
     801#endif
     802    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     803    return off;
     804}
     805
     806
     807/**
     808 * Sign-extends 16-bit value in @a iGprSrc into a 64-bit value in @a iGprDst.
     809 */
     810DECL_INLINE_THROW(uint32_t)
     811iemNativeEmitLoadGprSignExtendedFromGpr16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc)
     812{
     813#ifdef RT_ARCH_AMD64
     814    /* movsx r64, r/m16 */
     815    uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4);
     816    pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B);
     817    pbCodeBuf[off++] = 0x0f;
     818    pbCodeBuf[off++] = 0xbf;
     819    pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7);
     820
     821#elif defined(RT_ARCH_ARM64)
     822    /* sxth dst, src */
     823    uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     824    pu32CodeBuf[off++] = Armv8A64MkInstrSxth(iGprDst, iGprSrc);
     825
     826#else
     827# error "port me"
     828#endif
     829    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     830    return off;
     831}
     832
     833
     834/**
     835 * Sign-extends 16-bit value in @a iGprSrc into a 32-bit value in @a iGprDst.
     836 */
     837DECL_INLINE_THROW(uint32_t)
     838iemNativeEmitLoadGpr32SignExtendedFromGpr16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc)
     839{
     840#ifdef RT_ARCH_AMD64
     841    /* movsx r64, r/m16 */
     842    uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4);
     843    if (iGprDst >= 8 || iGprSrc >= 8)
     844        pbCodeBuf[off++] = (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B);
     845    pbCodeBuf[off++] = 0x0f;
     846    pbCodeBuf[off++] = 0xbf;
     847    pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7);
     848
     849#elif defined(RT_ARCH_ARM64)
     850    /* sxth dst32, src */
     851    uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     852    pu32CodeBuf[off++] = Armv8A64MkInstrSxth(iGprDst, iGprSrc, false /*f64Bit*/);
     853
     854#else
     855# error "port me"
     856#endif
     857    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     858    return off;
     859}
     860
     861
     862/**
     863 * Sign-extends 8-bit value in @a iGprSrc into a 64-bit value in @a iGprDst.
     864 */
     865DECL_INLINE_THROW(uint32_t)
     866iemNativeEmitLoadGprSignExtendedFromGpr8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc)
     867{
     868#ifdef RT_ARCH_AMD64
     869    /* movsx r64, r/m8 */
     870    uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4);
     871    pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B);
     872    pbCodeBuf[off++] = 0x0f;
     873    pbCodeBuf[off++] = 0xbe;
     874    pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7);
     875
     876#elif defined(RT_ARCH_ARM64)
     877    /* sxtb dst, src */
     878    uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     879    pu32CodeBuf[off++] = Armv8A64MkInstrSxtb(iGprDst, iGprSrc);
     880
     881#else
     882# error "port me"
     883#endif
     884    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     885    return off;
     886}
     887
     888
     889/**
     890 * Sign-extends 8-bit value in @a iGprSrc into a 32-bit value in @a iGprDst.
     891 * @note Bits 64 thru 32 are cleared.
     892 */
     893DECL_INLINE_THROW(uint32_t)
     894iemNativeEmitLoadGpr32SignExtendedFromGpr8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc)
     895{
     896#ifdef RT_ARCH_AMD64
     897    /* movsx r32, r/m8 */
     898    uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4);
     899    if (iGprDst >= 8 || iGprSrc >= 8)
     900        pbCodeBuf[off++] = (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B);
     901    pbCodeBuf[off++] = 0x0f;
     902    pbCodeBuf[off++] = 0xbe;
     903    pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7);
     904
     905#elif defined(RT_ARCH_ARM64)
     906    /* sxtb dst32, src32 */
     907    uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     908    pu32CodeBuf[off++] = Armv8A64MkInstrSxtb(iGprDst, iGprSrc, false /*f64Bit*/);
     909
     910#else
     911# error "port me"
     912#endif
     913    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     914    return off;
     915}
     916
     917
     918/**
     919 * Sign-extends 8-bit value in @a iGprSrc into a 16-bit value in @a iGprDst.
     920 * @note Bits 64 thru 16 are cleared.
     921 */
     922DECL_INLINE_THROW(uint32_t)
     923iemNativeEmitLoadGpr16SignExtendedFromGpr8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc)
     924{
     925#ifdef RT_ARCH_AMD64
     926    /* movsx r16, r/m8 */
     927    uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 9);
     928    pbCodeBuf[off++] = X86_OP_PRF_SIZE_OP;
     929    if (iGprDst >= 8 || iGprSrc >= 8)
     930        pbCodeBuf[off++] = (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B);
     931    pbCodeBuf[off++] = 0x0f;
     932    pbCodeBuf[off++] = 0xbe;
     933    pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7);
     934
     935    /* movzx r32, r/m16 */
     936    if (iGprDst >= 8)
     937        pbCodeBuf[off++] = X86_OP_REX_R | X86_OP_REX_B;
     938    pbCodeBuf[off++] = 0x0f;
     939    pbCodeBuf[off++] = 0xb7;
     940    pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprDst & 7);
     941
     942#elif defined(RT_ARCH_ARM64)
     943    /* sxtb dst32, src32;  and dst32, dst32, #0xffff */
     944    uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 2);
     945    pu32CodeBuf[off++] = Armv8A64MkInstrSxtb(iGprDst, iGprSrc, false /*f64Bit*/);
     946    Assert(Armv8A64ConvertImmRImmS2Mask32(15, 0) == 0xffff);
     947    pu32CodeBuf[off++] = Armv8A64MkInstrAndImm(iGprDst, iGprDst, 15, 0, false /*f64Bit*/);
    772948
    773949#else
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