VirtualBox

Ignore:
Timestamp:
Mar 2, 2024 2:08:22 AM (14 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
162005
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette