VirtualBox

Changeset 103657 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Mar 4, 2024 9:53:49 AM (9 months ago)
Author:
vboxsync
Message:

VMM/IEM: A little 'test' optimization, saving a register alloc+fetch when both 'test' operands refers to the same register. bugref:10376

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

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

    r103648 r103657  
    145145
    146146/**
    147  * Body for instructions like TEST & CMP, ++ with a byte memory/registers as
     147 * Body for instructions like TEST & CMP with a byte memory/registers as
    148148 * operands.
    149149 */
    150 #define IEMOP_BODY_BINARY_rm_r8_RO(a_fnNormalU8, a_EmitterBasename, a_fNativeArchs) \
    151     uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); \
    152     \
     150#define IEMOP_BODY_BINARY_rm_r8_RO(a_bRm, a_fnNormalU8, a_EmitterBasename, a_fNativeArchs) \
    153151    /* \
    154152     * If rm is denoting a register, no more instruction bytes. \
    155153     */ \
    156     if (IEM_IS_MODRM_REG_MODE(bRm)) \
     154    if (IEM_IS_MODRM_REG_MODE(a_bRm)) \
    157155    { \
    158156        IEM_MC_BEGIN(3, 0, 0, 0); \
    159157        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
    160158        IEM_MC_ARG(uint8_t,         u8Src,   1); \
    161         IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
     159        IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
    162160        IEM_MC_NATIVE_IF(a_fNativeArchs) { \
    163161            IEM_MC_LOCAL(uint8_t,   u8Dst); \
    164             IEM_MC_FETCH_GREG_U8(u8Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
     162            IEM_MC_FETCH_GREG_U8(u8Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
    165163            /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
    166164            IEM_MC_LOCAL(uint32_t,  uEFlags); \
     
    170168        } IEM_MC_NATIVE_ELSE() { \
    171169            IEM_MC_ARG(uint8_t *,   pu8Dst,  0); \
    172             IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
     170            IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
    173171            IEM_MC_ARG(uint32_t *,  pEFlags, 2); \
    174172            IEM_MC_REF_EFLAGS(pEFlags); \
     
    189187            IEM_MC_BEGIN(3, 3, 0, 0); \
    190188            IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
    191             IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
     189            IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, a_bRm, 0); \
    192190            IEMOP_HLP_DONE_DECODING(); \
    193191            IEM_MC_NATIVE_IF(0) { \
     
    195193                IEM_MC_FETCH_MEM_U8(u8Dst, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
    196194                IEM_MC_LOCAL(uint8_t,       u8SrcEmit); \
    197                 IEM_MC_FETCH_GREG_U8(u8SrcEmit, IEM_GET_MODRM_REG(pVCpu, bRm)); \
     195                IEM_MC_FETCH_GREG_U8(u8SrcEmit, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
    198196                /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
    199197                IEM_MC_LOCAL(uint32_t,      uEFlags); \
     
    206204                IEM_MC_MEM_MAP_U8_RO(pu8Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
    207205                IEM_MC_ARG(uint8_t,         u8Src,           1); \
    208                 IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
     206                IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
    209207                IEM_MC_ARG_LOCAL_EFLAGS(    pEFlags, EFlags, 2); \
    210208                IEM_MC_FETCH_EFLAGS(EFlags); \
     
    543541 * memory/register as the destination.
    544542 */
    545 #define IEMOP_BODY_BINARY_rm_rv_RO(a_fnNormalU16, a_fnNormalU32, a_fnNormalU64, a_EmitterBasename, a_fNativeArchs) \
    546     uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); \
    547     \
     543#define IEMOP_BODY_BINARY_rm_rv_RO(a_bRm, a_fnNormalU16, a_fnNormalU32, a_fnNormalU64, a_EmitterBasename, a_fNativeArchs) \
    548544    /* \
    549545     * If rm is denoting a register, no more instruction bytes. \
    550546     */ \
    551     if (IEM_IS_MODRM_REG_MODE(bRm)) \
     547    if (IEM_IS_MODRM_REG_MODE(a_bRm)) \
    552548    { \
    553549        switch (pVCpu->iem.s.enmEffOpSize) \
     
    557553                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
    558554                IEM_MC_ARG(uint16_t,   u16Src,  1); \
    559                 IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
     555                IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
    560556                IEM_MC_NATIVE_IF(a_fNativeArchs) { \
    561557                    IEM_MC_LOCAL(uint16_t,   u16Dst); \
    562                     IEM_MC_FETCH_GREG_U16(u16Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
     558                    IEM_MC_FETCH_GREG_U16(u16Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
    563559                    /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
    564560                    IEM_MC_LOCAL(uint32_t,  uEFlags); \
     
    568564                } IEM_MC_NATIVE_ELSE() { \
    569565                    IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
    570                     IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
     566                    IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
    571567                    IEM_MC_ARG(uint32_t *, pEFlags, 2); \
    572568                    IEM_MC_REF_EFLAGS(pEFlags); \
     
    581577                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
    582578                IEM_MC_ARG(uint32_t,   u32Src,  1); \
    583                 IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
     579                IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
    584580                IEM_MC_NATIVE_IF(a_fNativeArchs) { \
    585581                    IEM_MC_LOCAL(uint32_t,   u32Dst); \
    586                     IEM_MC_FETCH_GREG_U32(u32Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
     582                    IEM_MC_FETCH_GREG_U32(u32Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
    587583                    /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
    588584                    IEM_MC_LOCAL(uint32_t,  uEFlags); \
     
    592588                } IEM_MC_NATIVE_ELSE() { \
    593589                    IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
    594                     IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
     590                    IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
    595591                    IEM_MC_ARG(uint32_t *, pEFlags, 2); \
    596592                    IEM_MC_REF_EFLAGS(pEFlags); \
     
    605601                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
    606602                IEM_MC_ARG(uint64_t,        u64Src,  1); \
    607                 IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
     603                IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
    608604                IEM_MC_NATIVE_IF(a_fNativeArchs) { \
    609605                    IEM_MC_LOCAL(uint64_t,  u64Dst); \
    610                     IEM_MC_FETCH_GREG_U64(u64Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
     606                    IEM_MC_FETCH_GREG_U64(u64Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
    611607                    /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
    612608                    IEM_MC_LOCAL(uint32_t,  uEFlags); \
     
    616612                } IEM_MC_NATIVE_ELSE() { \
    617613                    IEM_MC_ARG(uint64_t *,  pu64Dst, 0); \
    618                     IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
     614                    IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
    619615                    IEM_MC_ARG(uint32_t *,  pEFlags, 2); \
    620616                    IEM_MC_REF_EFLAGS(pEFlags); \
     
    642638                    IEM_MC_BEGIN(3, 3, 0, 0); \
    643639                    IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
    644                     IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
     640                    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, a_bRm, 0); \
    645641                    IEMOP_HLP_DONE_DECODING(); \
    646642                    IEM_MC_NATIVE_IF(a_fNativeArchs) { \
     
    648644                        IEM_MC_FETCH_MEM_U16(u16Dst, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
    649645                        IEM_MC_LOCAL(uint16_t,      u16SrcEmit); \
    650                         IEM_MC_FETCH_GREG_U16(u16SrcEmit, IEM_GET_MODRM_REG(pVCpu, bRm)); \
     646                        IEM_MC_FETCH_GREG_U16(u16SrcEmit, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
    651647                        /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
    652648                        IEM_MC_LOCAL(uint32_t,  uEFlags); \
     
    659655                        IEM_MC_MEM_MAP_U16_RO(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
    660656                        IEM_MC_ARG(uint16_t,         u16Src,          1); \
    661                         IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
     657                        IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
    662658                        IEM_MC_ARG_LOCAL_EFLAGS(     pEFlags, EFlags, 2); \
    663659                        IEM_MC_FETCH_EFLAGS(EFlags); \
     
    673669                    IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_386, 0); \
    674670                    IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
    675                     IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
     671                    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, a_bRm, 0); \
    676672                    IEMOP_HLP_DONE_DECODING(); \
    677673                    IEM_MC_NATIVE_IF(a_fNativeArchs) { \
     
    679675                        IEM_MC_FETCH_MEM_U32(u32Dst, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
    680676                        IEM_MC_LOCAL(uint32_t,      u32SrcEmit); \
    681                         IEM_MC_FETCH_GREG_U32(u32SrcEmit, IEM_GET_MODRM_REG(pVCpu, bRm)); \
     677                        IEM_MC_FETCH_GREG_U32(u32SrcEmit, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
    682678                        /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
    683679                        IEM_MC_LOCAL(uint32_t,  uEFlags); \
     
    690686                        IEM_MC_MEM_MAP_U32_RO(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
    691687                        IEM_MC_ARG(uint32_t,         u32Src,          1); \
    692                         IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
     688                        IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
    693689                        IEM_MC_ARG_LOCAL_EFLAGS(     pEFlags, EFlags, 2); \
    694690                        IEM_MC_FETCH_EFLAGS(EFlags); \
     
    704700                    IEM_MC_BEGIN(3, 3, IEM_MC_F_64BIT, 0); \
    705701                    IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
    706                     IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
     702                    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, a_bRm, 0); \
    707703                    IEMOP_HLP_DONE_DECODING(); \
    708704                    IEM_MC_NATIVE_IF(a_fNativeArchs) { \
     
    710706                        IEM_MC_FETCH_MEM_U64(u64Dst, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
    711707                        IEM_MC_LOCAL(uint64_t,      u64SrcEmit); \
    712                         IEM_MC_FETCH_GREG_U64(u64SrcEmit, IEM_GET_MODRM_REG(pVCpu, bRm)); \
     708                        IEM_MC_FETCH_GREG_U64(u64SrcEmit, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
    713709                        /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
    714710                        IEM_MC_LOCAL(uint32_t,  uEFlags); \
     
    721717                        IEM_MC_MEM_MAP_U64_RO(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
    722718                        IEM_MC_ARG(uint64_t,         u64Src,          1); \
    723                         IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
     719                        IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
    724720                        IEM_MC_ARG_LOCAL_EFLAGS(     pEFlags, EFlags, 2); \
    725721                        IEM_MC_FETCH_EFLAGS(EFlags); \
     
    17791775{
    17801776    IEMOP_MNEMONIC(cmp_Eb_Gb, "cmp Eb,Gb");
    1781     IEMOP_BODY_BINARY_rm_r8_RO(iemAImpl_cmp_u8, cmp, 0);
     1777    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
     1778    IEMOP_BODY_BINARY_rm_r8_RO(bRm, iemAImpl_cmp_u8, cmp, 0);
    17821779}
    17831780
     
    17901787{
    17911788    IEMOP_MNEMONIC(cmp_Ev_Gv, "cmp Ev,Gv");
    1792     IEMOP_BODY_BINARY_rm_rv_RO(iemAImpl_cmp_u16, iemAImpl_cmp_u32, iemAImpl_cmp_u64, cmp, 0);
     1789    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
     1790    IEMOP_BODY_BINARY_rm_rv_RO(bRm, iemAImpl_cmp_u16, iemAImpl_cmp_u32, iemAImpl_cmp_u64, cmp, 0);
    17931791}
    17941792
     
    53615359    IEMOP_MNEMONIC(test_Eb_Gb, "test Eb,Gb");
    53625360    IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
    5363     IEMOP_BODY_BINARY_rm_r8_RO(iemAImpl_test_u8, test, RT_ARCH_VAL_AMD64);
     5361
     5362    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
     5363
     5364    /*
     5365     * Deal with special case of 'test rN, rN' which is frequently used for testing for zero/non-zero registers.
     5366     * This block only makes a differences when emitting native code, where we'll save a register fetch.
     5367     */
     5368    if (   (bRm >> X86_MODRM_REG_SHIFT) == ((bRm & X86_MODRM_RM_MASK) | (X86_MOD_REG << X86_MODRM_REG_SHIFT))
     5369        && pVCpu->iem.s.uRexReg == pVCpu->iem.s.uRexB)
     5370    {
     5371        IEM_MC_BEGIN(3, 0, 0, 0);
     5372        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     5373        IEM_MC_ARG(uint8_t,         u8Src,   1);
     5374        IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, bRm));
     5375        IEM_MC_NATIVE_IF(RT_ARCH_VAL_AMD64) {
     5376            /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */
     5377            IEM_MC_LOCAL(uint32_t,  uEFlags);
     5378            IEM_MC_FETCH_EFLAGS(uEFlags);
     5379            IEM_MC_NATIVE_EMIT_4(iemNativeEmit_test_r_r_efl, u8Src, u8Src, uEFlags, 8);
     5380            IEM_MC_COMMIT_EFLAGS(uEFlags);
     5381        } IEM_MC_NATIVE_ELSE() {
     5382            IEM_MC_ARG(uint8_t *,   pu8Dst,  0);
     5383            IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
     5384            IEM_MC_ARG(uint32_t *,  pEFlags, 2);
     5385            IEM_MC_REF_EFLAGS(pEFlags);
     5386            IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u8, pu8Dst, u8Src, pEFlags);
     5387        } IEM_MC_NATIVE_ENDIF();
     5388        IEM_MC_ADVANCE_RIP_AND_FINISH();
     5389        IEM_MC_END();
     5390    }
     5391
     5392    IEMOP_BODY_BINARY_rm_r8_RO(bRm, iemAImpl_test_u8, test, RT_ARCH_VAL_AMD64);
    53645393}
    53655394
     
    53735402    IEMOP_MNEMONIC(test_Ev_Gv, "test Ev,Gv");
    53745403    IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
    5375     IEMOP_BODY_BINARY_rm_rv_RO(iemAImpl_test_u16, iemAImpl_test_u32, iemAImpl_test_u64, test, RT_ARCH_VAL_AMD64);
     5404
     5405    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
     5406
     5407    /*
     5408     * Deal with special case of 'test rN, rN' which is frequently used for testing for zero/non-zero registers.
     5409     * This block only makes a differences when emitting native code, where we'll save a register fetch.
     5410     */
     5411    if (   (bRm >> X86_MODRM_REG_SHIFT) == ((bRm & X86_MODRM_RM_MASK) | (X86_MOD_REG << X86_MODRM_REG_SHIFT))
     5412        && pVCpu->iem.s.uRexReg == pVCpu->iem.s.uRexB)
     5413    {
     5414        switch (pVCpu->iem.s.enmEffOpSize)
     5415        {
     5416            case IEMMODE_16BIT:
     5417                IEM_MC_BEGIN(3, 0, 0, 0);
     5418                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     5419                IEM_MC_ARG(uint16_t,   u16Src,  1);
     5420                IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, bRm));
     5421                IEM_MC_NATIVE_IF(RT_ARCH_VAL_AMD64) {
     5422                    /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */
     5423                    IEM_MC_LOCAL(uint32_t,  uEFlags);
     5424                    IEM_MC_FETCH_EFLAGS(uEFlags);
     5425                    IEM_MC_NATIVE_EMIT_4(iemNativeEmit_test_r_r_efl, u16Src, u16Src, uEFlags, 16);
     5426                    IEM_MC_COMMIT_EFLAGS(uEFlags);
     5427                } IEM_MC_NATIVE_ELSE() {
     5428                    IEM_MC_ARG(uint16_t *, pu16Dst, 0);
     5429                    IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
     5430                    IEM_MC_ARG(uint32_t *, pEFlags, 2);
     5431                    IEM_MC_REF_EFLAGS(pEFlags);
     5432                    IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u16, pu16Dst, u16Src, pEFlags);
     5433                } IEM_MC_NATIVE_ENDIF();
     5434                IEM_MC_ADVANCE_RIP_AND_FINISH();
     5435                IEM_MC_END();
     5436                break;
     5437
     5438            case IEMMODE_32BIT:
     5439                IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_386, 0);
     5440                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     5441                IEM_MC_ARG(uint32_t,   u32Src,  1);
     5442                IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, bRm));
     5443                IEM_MC_NATIVE_IF(RT_ARCH_VAL_AMD64) {
     5444                    /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */
     5445                    IEM_MC_LOCAL(uint32_t,  uEFlags);
     5446                    IEM_MC_FETCH_EFLAGS(uEFlags);
     5447                    IEM_MC_NATIVE_EMIT_4(iemNativeEmit_test_r_r_efl, u32Src, u32Src, uEFlags, 32);
     5448                    IEM_MC_COMMIT_EFLAGS(uEFlags);
     5449                } IEM_MC_NATIVE_ELSE() {
     5450                    IEM_MC_ARG(uint32_t *, pu32Dst, 0);
     5451                    IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
     5452                    IEM_MC_ARG(uint32_t *, pEFlags, 2);
     5453                    IEM_MC_REF_EFLAGS(pEFlags);
     5454                    IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u32, pu32Dst, u32Src, pEFlags);
     5455                } IEM_MC_NATIVE_ENDIF();
     5456                IEM_MC_ADVANCE_RIP_AND_FINISH();
     5457                IEM_MC_END();
     5458                break;
     5459
     5460            case IEMMODE_64BIT:
     5461                IEM_MC_BEGIN(3, 0, IEM_MC_F_64BIT, 0);
     5462                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     5463                IEM_MC_ARG(uint64_t,        u64Src,  1);
     5464                IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, bRm));
     5465                IEM_MC_NATIVE_IF(RT_ARCH_VAL_AMD64) {
     5466                    /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */
     5467                    IEM_MC_LOCAL(uint32_t,  uEFlags);
     5468                    IEM_MC_FETCH_EFLAGS(uEFlags);
     5469                    IEM_MC_NATIVE_EMIT_4(iemNativeEmit_test_r_r_efl, u64Src, u64Src, uEFlags, 64);
     5470                    IEM_MC_COMMIT_EFLAGS(uEFlags);
     5471                } IEM_MC_NATIVE_ELSE() {
     5472                    IEM_MC_ARG(uint64_t *,  pu64Dst, 0);
     5473                    IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
     5474                    IEM_MC_ARG(uint32_t *,  pEFlags, 2);
     5475                    IEM_MC_REF_EFLAGS(pEFlags);
     5476                    IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u64, pu64Dst, u64Src, pEFlags);
     5477                } IEM_MC_NATIVE_ENDIF();
     5478                IEM_MC_ADVANCE_RIP_AND_FINISH();
     5479                IEM_MC_END();
     5480                break;
     5481
     5482            IEM_NOT_REACHED_DEFAULT_CASE_RET();
     5483        }
     5484    }
     5485
     5486    IEMOP_BODY_BINARY_rm_rv_RO(bRm, iemAImpl_test_u16, iemAImpl_test_u32, iemAImpl_test_u64, test, RT_ARCH_VAL_AMD64);
    53765487}
    53775488
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h

    r103648 r103657  
    204204     *        variants, and SF for 32-bit and 64-bit.  */
    205205    uint8_t const         idxRegDst    = iemNativeVarRegisterAcquire(pReNative, idxVarDst, &off, true /*fInitialized*/);
    206     uint8_t const         idxRegSrc    = iemNativeVarRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/);
     206    uint8_t const         idxRegSrc    = idxVarSrc == idxVarDst ? idxRegDst /* special case of 'test samereg,samereg' */
     207                                       : iemNativeVarRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/);
    207208#ifndef RT_ARCH_AMD64
    208209    uint8_t const         idxRegResult = iemNativeRegAllocTmp(pReNative, &off);
     
    244245#endif
    245246    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
    246     iemNativeVarRegisterRelease(pReNative, idxVarSrc);
     247    if (idxVarSrc != idxVarDst)
     248        iemNativeVarRegisterRelease(pReNative, idxVarSrc);
    247249    iemNativeVarRegisterRelease(pReNative, idxVarDst);
    248250
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