Changeset 103639 in vbox
- Timestamp:
- Mar 1, 2024 8:56:46 PM (9 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r103635 r103639 6188 6188 6189 6189 6190 /**6191 * This is an implementation of IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGICAL6192 * 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_ANALYSIS6201 if (1) /** @todo check if all bits are clobbered. */6202 #endif6203 {6204 #ifdef RT_ARCH_AMD646205 /*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 else6247 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 # else6256 pCodeBuf[off++] = Armv8A64MkInstrBfi(idxRegEfl, idxTmpReg, X86_EFL_SF_BIT, 1, false /*f64Bit*/);6257 # endif6258 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 #else6273 # error "port me"6274 #endif6275 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 the6290 * right EFLAGS.SF value, while the rest will just lump 16-bit and 8-bit6291 * 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_AMD646300 case 16:6301 case 8:6302 #endif6303 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_AMD646312 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 #endif6333 }6334 iemNativeVarRegisterRelease(pReNative, idxVarSrc);6335 6336 off = iemNativeEmitEFlagsForLogical(pReNative, off, idxVarEfl, cOpBits, idxRegDst);6337 iemNativeVarRegisterRelease(pReNative, idxVarDst);6338 return off;6339 }6340 6341 6190 6342 6191 /********************************************************************************************************************************* … … 13637 13486 *********************************************************************************************************************************/ 13638 13487 13488 /* 13489 * Include instruction emitters. 13490 */ 13491 #include "target-x86/IEMAllN8veEmit-x86.h" 13639 13492 13640 13493 /*
Note:
See TracChangeset
for help on using the changeset viewer.