VirtualBox

Changeset 103639 in vbox


Ignore:
Timestamp:
Mar 1, 2024 8:56:46 PM (9 months ago)
Author:
vboxsync
Message:

VMM/IEM: Moved iemNativeEmit_xor_r_r_efl and iemNativeEmitEFlagsForLogical into a separate file under the new target-x86 subdir. [missing file] bugref:10376

File:
1 edited

Legend:

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

    r103635 r103639  
    61886188
    61896189
    6190 /**
    6191  * This is an implementation of IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGICAL
    6192  * and friends.
    6193  *
    6194  * It takes liveness stuff into account.
    6195  */
    6196 DECL_INLINE_THROW(uint32_t)
    6197 iemNativeEmitEFlagsForLogical(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxVarEfl,
    6198                               uint8_t cOpBits, uint8_t idxRegResult)
    6199 {
    6200 #ifdef IEMNATIVE_WITH_LIVENESS_ANALYSIS
    6201     if (1) /** @todo check if all bits are clobbered. */
    6202 #endif
    6203     {
    6204 #ifdef RT_ARCH_AMD64
    6205         /*
    6206          * Collect flags and merge them with eflags.
    6207          */
    6208         /** @todo we could alternatively use SAHF here when host rax is free since,
    6209          *        OF is cleared. */
    6210         PIEMNATIVEINSTR pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
    6211         /* pushf - do this before any reg allocations as they may emit instructions too. */
    6212         pCodeBuf[off++] = 0x9c;
    6213 
    6214         uint8_t const idxRegEfl = iemNativeVarRegisterAcquire(pReNative, idxVarEfl, &off, true /*fInitialized*/);
    6215         uint8_t const idxTmpReg = iemNativeRegAllocTmp(pReNative, &off);
    6216         pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 2 + 7 + 7 + 3);
    6217         /* pop   tmp */
    6218         if (idxTmpReg >= 8)
    6219             pCodeBuf[off++] = X86_OP_REX_B;
    6220         pCodeBuf[off++] = 0x58 + (idxTmpReg & 7);
    6221         /* and  tmp, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF */
    6222         off = iemNativeEmitAndGpr32ByImmEx(pCodeBuf, off, idxTmpReg, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF);
    6223         /* Clear the status bits in EFLs. */
    6224         off = iemNativeEmitAndGpr32ByImmEx(pCodeBuf, off, idxRegEfl, ~X86_EFL_STATUS_BITS);
    6225         /* OR in the flags we collected. */
    6226         off = iemNativeEmitOrGpr32ByGprEx(pCodeBuf, off, idxRegEfl, idxTmpReg);
    6227         iemNativeVarRegisterRelease(pReNative, idxVarEfl);
    6228         iemNativeRegFreeTmp(pReNative, idxTmpReg);
    6229         RT_NOREF(cOpBits, idxRegResult);
    6230 
    6231 #elif defined(RT_ARCH_ARM64)
    6232         /*
    6233          * Calculate flags.
    6234          */
    6235         uint8_t const         idxRegEfl = iemNativeVarRegisterAcquire(pReNative, idxVarEfl, &off, true /*fInitialized*/);
    6236         uint8_t const         idxTmpReg = iemNativeRegAllocTmp(pReNative, &off);
    6237         PIEMNATIVEINSTR const pCodeBuf  = iemNativeInstrBufEnsure(pReNative, off, 15);
    6238 
    6239         /* Clear the status bits. ~0x8D5 (or ~0x8FD) can't be AND immediate, so use idxTmpReg for constant. */
    6240         off = iemNativeEmitLoadGpr32ImmEx(pCodeBuf, off, idxTmpReg, ~X86_EFL_STATUS_BITS);
    6241         off = iemNativeEmitAndGpr32ByGpr32Ex(pCodeBuf, off, idxRegEfl, idxTmpReg);
    6242 
    6243         /* Calculate zero: mov tmp, zf; cmp result,zero; csel.eq tmp,tmp,wxr */
    6244         if (cOpBits > 32)
    6245             off = iemNativeEmitCmpGprWithGprEx(pCodeBuf, off, idxRegResult, ARMV8_A64_REG_XZR);
    6246         else
    6247             off = iemNativeEmitCmpGpr32WithGprEx(pCodeBuf, off, idxRegResult, ARMV8_A64_REG_XZR);
    6248         pCodeBuf[off++] = Armv8A64MkInstrCSet(idxTmpReg, kArmv8InstrCond_Eq, false /*f64Bit*/);
    6249         pCodeBuf[off++] = Armv8A64MkInstrOrr(idxRegEfl, idxRegEfl, idxTmpReg, false /*f64Bit*/, X86_EFL_ZF_BIT);
    6250 
    6251         /* Calculate signed: We could use the native SF flag, but it's just as simple to calculate it by shifting. */
    6252         pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxTmpReg, idxRegResult, cOpBits - 1, cOpBits > 32 /*f64Bit*/);
    6253 # if 0 /* BFI and ORR hsould have the same performance characteristics, so use BFI like we'll have to do for SUB/ADD/++. */
    6254         pCodeBuf[off++] = Armv8A64MkInstrOrr(idxRegEfl, idxRegEfl, idxTmpReg, false /*f64Bit*/, X86_EFL_SF_BIT);
    6255 # else
    6256         pCodeBuf[off++] = Armv8A64MkInstrBfi(idxRegEfl, idxTmpReg, X86_EFL_SF_BIT, 1, false /*f64Bit*/);
    6257 # endif
    6258 
    6259         /* Calculate 8-bit parity of the result. */
    6260         pCodeBuf[off++] = Armv8A64MkInstrEor(idxTmpReg, idxRegResult, idxRegResult, false /*f64Bit*/,
    6261                                              4 /*offShift6*/, kArmv8A64InstrShift_Lsr);
    6262         pCodeBuf[off++] = Armv8A64MkInstrEor(idxTmpReg, idxTmpReg,    idxTmpReg,    false /*f64Bit*/,
    6263                                              2 /*offShift6*/, kArmv8A64InstrShift_Lsr);
    6264         pCodeBuf[off++] = Armv8A64MkInstrEor(idxTmpReg, idxTmpReg,    idxTmpReg,    false /*f64Bit*/,
    6265                                              1 /*offShift6*/, kArmv8A64InstrShift_Lsr);
    6266         Assert(Armv8A64ConvertImmRImmS2Mask32(0, 0) == 1);
    6267         pCodeBuf[off++] = Armv8A64MkInstrEorImm(idxTmpReg, idxTmpReg, 0, 0, false /*f64Bit*/);
    6268         pCodeBuf[off++] = Armv8A64MkInstrBfi(idxRegEfl, idxTmpReg, X86_EFL_PF_BIT, 1,  false /*f64Bit*/);
    6269 
    6270         iemNativeVarRegisterRelease(pReNative, idxVarEfl);
    6271         iemNativeRegFreeTmp(pReNative, idxTmpReg);
    6272 #else
    6273 # error "port me"
    6274 #endif
    6275         IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
    6276     }
    6277     return off;
    6278 }
    6279 
    6280 /** @todo move this somewhere else ... */
    6281 DECL_INLINE_THROW(uint32_t)
    6282 iemNativeEmit_xor_r_r_efl(PIEMRECOMPILERSTATE pReNative, uint32_t off,
    6283                           uint8_t idxVarDst, uint8_t idxVarSrc, uint8_t idxVarEfl, uint8_t cOpBits)
    6284 {
    6285     /*
    6286      * The XOR instruction will clear OF, CF and AF (latter is off undefined),
    6287      * so we don't need the initial destination value.
    6288      *
    6289      * On AMD64 we must use the correctly sizeed XOR instructions to get the
    6290      * right EFLAGS.SF value, while the rest will just lump 16-bit and 8-bit
    6291      * in the 32-bit ones.
    6292      */
    6293     uint8_t const idxRegDst = iemNativeVarRegisterAcquire(pReNative, idxVarDst, &off, true /*fInitialized*/);
    6294     uint8_t const idxRegSrc = iemNativeVarRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/);
    6295     //off = iemNativeEmitBrk(pReNative, off, 0x2222);
    6296     switch (cOpBits)
    6297     {
    6298         case 32:
    6299 #ifndef RT_ARCH_AMD64
    6300         case 16:
    6301         case 8:
    6302 #endif
    6303             off = iemNativeEmitXorGpr32ByGpr32(pReNative, off, idxRegDst, idxRegSrc);
    6304             break;
    6305 
    6306         default: AssertFailed(); RT_FALL_THRU();
    6307         case 64:
    6308             off = iemNativeEmitXorGprByGpr(pReNative, off, idxRegDst, idxRegSrc);
    6309             break;
    6310 
    6311 #ifdef RT_ARCH_AMD64
    6312         case 16:
    6313         {
    6314             PIEMNATIVEINSTR pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
    6315             pCodeBuf[off++] = X86_OP_PRF_SIZE_OP;
    6316             off = iemNativeEmitXorGpr32ByGpr32(pReNative, off, idxRegDst, idxRegSrc);
    6317             break;
    6318         }
    6319 
    6320         case 8:
    6321         {
    6322             PIEMNATIVEINSTR pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3);
    6323             if (idxRegDst >= 8 || idxRegSrc >= 8)
    6324                 pCodeBuf[off++] = (idxRegDst >= 8 ? X86_OP_REX_R : 0) | (idxRegSrc >= 8 ? X86_OP_REX_B : 0);
    6325             else if (idxRegDst >= 4 || idxRegSrc >= 4)
    6326                 pCodeBuf[off++] = X86_OP_REX;
    6327             pCodeBuf[off++] = 0x32;
    6328             pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxRegDst & 7, idxRegSrc & 7);
    6329             IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
    6330             break;
    6331         }
    6332 #endif
    6333     }
    6334     iemNativeVarRegisterRelease(pReNative, idxVarSrc);
    6335 
    6336     off = iemNativeEmitEFlagsForLogical(pReNative, off, idxVarEfl, cOpBits, idxRegDst);
    6337     iemNativeVarRegisterRelease(pReNative, idxVarDst);
    6338     return off;
    6339 }
    6340 
    63416190
    63426191/*********************************************************************************************************************************
     
    1363713486*********************************************************************************************************************************/
    1363813487
     13488/*
     13489 * Include instruction emitters.
     13490 */
     13491#include "target-x86/IEMAllN8veEmit-x86.h"
    1363913492
    1364013493/*
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