Changeset 103648 in vbox for trunk/src/VBox/VMM/VMMAll/target-x86
- Timestamp:
- Mar 3, 2024 2:20:46 AM (14 months ago)
- svn:sync-xref-src-repo-rev:
- 162008
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h
r103646 r103648 129 129 { 130 130 /* 131 * The AND instruction will clear OF, CF and AF (latter is offundefined),131 * The AND instruction will clear OF, CF and AF (latter is undefined), 132 132 * so we don't need the initial destination value. 133 133 * … … 191 191 uint8_t idxVarDst, uint8_t idxVarSrc, uint8_t idxVarEfl, uint8_t cOpBits) 192 192 { 193 RT_NOREF(idxVarDst, idxVarSrc, idxVarEfl, cOpBits); 194 AssertFailed(); 195 return iemNativeEmitBrk(pReNative, off, 0x666); 193 /* 194 * The TESTS instruction will clear OF, CF and AF (latter is undefined), 195 * so we don't need the initial destination value. 196 * 197 * On AMD64 we use the matching native instruction. 198 * 199 * On ARM64 we need a real register for the AND result so we can calculate 200 * PF correctly for it. This means that we have to use a three operand 201 * AND variant, which makes the code widely different from AMD64. 202 */ 203 /** @todo we could use ANDS on ARM64 and get the ZF for free for all 204 * variants, and SF for 32-bit and 64-bit. */ 205 uint8_t const idxRegDst = iemNativeVarRegisterAcquire(pReNative, idxVarDst, &off, true /*fInitialized*/); 206 uint8_t const idxRegSrc = iemNativeVarRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/); 207 #ifndef RT_ARCH_AMD64 208 uint8_t const idxRegResult = iemNativeRegAllocTmp(pReNative, &off); 209 #endif 210 // off = iemNativeEmitBrk(pReNative, off, 0x2222); 211 PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, RT_ARCH_VAL == RT_ARCH_VAL_AMD64 ? 4 : 1); 212 #ifdef RT_ARCH_ARM64 213 pCodeBuf[off++] = Armv8A64MkInstrAnd(idxRegResult, idxRegDst, idxRegSrc, cOpBits > 32 /*f64Bit*/); 214 215 #elif defined(RT_ARCH_AMD64) 216 switch (cOpBits) 217 { 218 case 16: 219 pCodeBuf[off++] = X86_OP_PRF_SIZE_OP; 220 RT_FALL_THRU(); 221 case 32: 222 if (idxRegDst >= 8 || idxRegSrc >= 8) 223 pCodeBuf[off++] = (idxRegDst >= 8 ? X86_OP_REX_B : 0) | (idxRegSrc >= 8 ? X86_OP_REX_R : 0); 224 pCodeBuf[off++] = 0x85; 225 break; 226 227 default: AssertFailed(); RT_FALL_THRU(); 228 case 64: 229 pCodeBuf[off++] = X86_OP_REX_W | (idxRegDst >= 8 ? X86_OP_REX_B : 0) | (idxRegSrc >= 8 ? X86_OP_REX_R : 0); 230 pCodeBuf[off++] = 0x85; 231 break; 232 233 case 8: 234 if (idxRegDst >= 8 || idxRegSrc >= 8) 235 pCodeBuf[off++] = (idxRegDst >= 8 ? X86_OP_REX_B : 0) | (idxRegSrc >= 8 ? X86_OP_REX_R : 0); 236 else if (idxRegDst >= 4 || idxRegSrc >= 4) 237 pCodeBuf[off++] = X86_OP_REX; 238 pCodeBuf[off++] = 0x84; 239 break; 240 } 241 pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxRegSrc & 7, idxRegDst & 7); 242 #else 243 # error "port me" 244 #endif 245 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 246 iemNativeVarRegisterRelease(pReNative, idxVarSrc); 247 iemNativeVarRegisterRelease(pReNative, idxVarDst); 248 249 #ifdef RT_ARCH_AMD64 250 off = iemNativeEmitEFlagsForLogical(pReNative, off, idxVarEfl, cOpBits, UINT8_MAX); 251 #else 252 off = iemNativeEmitEFlagsForLogical(pReNative, off, idxVarEfl, cOpBits, idxRegResult); 253 iemNativeRegFreeTmp(pReNative, idxRegResult); 254 #endif 255 return off; 196 256 } 197 257 … … 202 262 { 203 263 /* 204 * The OR instruction will clear OF, CF and AF (latter is offundefined),264 * The OR instruction will clear OF, CF and AF (latter is undefined), 205 265 * so we don't need the initial destination value. 206 266 * … … 263 323 { 264 324 /* 265 * The XOR instruction will clear OF, CF and AF (latter is offundefined),325 * The XOR instruction will clear OF, CF and AF (latter is undefined), 266 326 * so we don't need the initial destination value. 267 327 *
Note:
See TracChangeset
for help on using the changeset viewer.