VirtualBox

Changeset 103645 in vbox


Ignore:
Timestamp:
Mar 2, 2024 2:08:22 AM (9 months ago)
Author:
vboxsync
Message:

VMM/IEM: Implemented iemNativeEmit_and_r_r_efl and enabled it for AMD64 hosts. bugref:10376

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

Legend:

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

    r103644 r103645  
    13161316    IEMOP_MNEMONIC2(MR, AND, and, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED);
    13171317    IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
    1318     IEMOP_BODY_BINARY_rm_r8_RW(iemAImpl_and_u8, iemAImpl_and_u8_locked, and, 0, 0);
     1318    IEMOP_BODY_BINARY_rm_r8_RW(iemAImpl_and_u8, iemAImpl_and_u8_locked, and, RT_ARCH_VAL_AMD64, 0);
    13191319}
    13201320
     
    13291329    IEMOP_MNEMONIC2(MR, AND, and, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED);
    13301330    IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
    1331     IEMOP_BODY_BINARY_rm_rv_RW(    iemAImpl_and_u16,        iemAImpl_and_u32,        iemAImpl_and_u64,       and, 0, 0);
     1331    IEMOP_BODY_BINARY_rm_rv_RW(    iemAImpl_and_u16,        iemAImpl_and_u32,        iemAImpl_and_u64,       and, RT_ARCH_VAL_AMD64, 0);
    13321332    IEMOP_BODY_BINARY_rm_rv_LOCKED(iemAImpl_and_u16_locked, iemAImpl_and_u32_locked, iemAImpl_and_u64_locked);
    13331333}
     
    13431343    IEMOP_MNEMONIC2(RM, AND, and, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES);
    13441344    IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
    1345     IEMOP_BODY_BINARY_r8_rm(iemAImpl_and_u8, and, 0);
     1345    IEMOP_BODY_BINARY_r8_rm(iemAImpl_and_u8, and, RT_ARCH_VAL_AMD64);
    13461346}
    13471347
     
    13571357    IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
    13581358    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
    1359     IEMOP_BODY_BINARY_rv_rm(bRm, iemAImpl_and_u16, iemAImpl_and_u32, iemAImpl_and_u64, 1, 0, and, 0);
     1359    IEMOP_BODY_BINARY_rv_rm(bRm, iemAImpl_and_u16, iemAImpl_and_u32, iemAImpl_and_u64, 1, 0, and, RT_ARCH_VAL_AMD64);
    13601360}
    13611361
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h

    r103640 r103645  
    128128                          uint8_t idxVarDst, uint8_t idxVarSrc, uint8_t idxVarEfl, uint8_t cOpBits)
    129129{
    130     RT_NOREF(idxVarDst, idxVarSrc, idxVarEfl, cOpBits);
    131     AssertFailed();
    132     return iemNativeEmitBrk(pReNative, off, 0x666);
     130    /*
     131     * The AND instruction will clear OF, CF and AF (latter is off undefined),
     132     * so we don't need the initial destination value.
     133     *
     134     * On AMD64 we must use the correctly sized AND instructions to get the
     135     * right EFLAGS.SF value, while the rest will just lump 16-bit and 8-bit
     136     * in the 32-bit ones.
     137     */
     138    /** @todo we could use ANDS on ARM64 and get the ZF for free for all
     139     *        variants, and SF for 32-bit and 64-bit.  */
     140    uint8_t const idxRegDst = iemNativeVarRegisterAcquire(pReNative, idxVarDst, &off, true /*fInitialized*/);
     141    uint8_t const idxRegSrc = iemNativeVarRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/);
     142    //off = iemNativeEmitBrk(pReNative, off, 0x2222);
     143    switch (cOpBits)
     144    {
     145        case 32:
     146#ifndef RT_ARCH_AMD64
     147        case 16:
     148        case 8:
     149#endif
     150            off = iemNativeEmitAndGpr32ByGpr32(pReNative, off, idxRegDst, idxRegSrc);
     151            break;
     152
     153        default: AssertFailed(); RT_FALL_THRU();
     154        case 64:
     155            off = iemNativeEmitAndGprByGpr(pReNative, off, idxRegDst, idxRegSrc);
     156            break;
     157
     158#ifdef RT_ARCH_AMD64
     159        case 16:
     160        {
     161            PIEMNATIVEINSTR pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     162            pCodeBuf[off++] = X86_OP_PRF_SIZE_OP;
     163            off = iemNativeEmitAndGpr32ByGpr32(pReNative, off, idxRegDst, idxRegSrc);
     164            break;
     165        }
     166
     167        case 8:
     168        {
     169            PIEMNATIVEINSTR pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3);
     170            if (idxRegDst >= 8 || idxRegSrc >= 8)
     171                pCodeBuf[off++] = (idxRegDst >= 8 ? X86_OP_REX_R : 0) | (idxRegSrc >= 8 ? X86_OP_REX_B : 0);
     172            else if (idxRegDst >= 4 || idxRegSrc >= 4)
     173                pCodeBuf[off++] = X86_OP_REX;
     174            pCodeBuf[off++] = 0x22;
     175            pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxRegDst & 7, idxRegSrc & 7);
     176            IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     177            break;
     178        }
     179#endif
     180    }
     181    iemNativeVarRegisterRelease(pReNative, idxVarSrc);
     182
     183    off = iemNativeEmitEFlagsForLogical(pReNative, off, idxVarEfl, cOpBits, idxRegDst);
     184    iemNativeVarRegisterRelease(pReNative, idxVarDst);
     185    return off;
    133186}
    134187
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