Changeset 103683 in vbox for trunk/src/VBox/VMM/VMMAll/target-x86
- Timestamp:
- Mar 5, 2024 3:02:10 PM (14 months ago)
- svn:sync-xref-src-repo-rev:
- 162048
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h
r103682 r103683 168 168 iemNativeEmitEFlagsForArithmetic(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxVarEfl 169 169 #ifndef RT_ARCH_AMD64 170 , uint8_t cOpBits, uint8_t idxRegResult, uint8_t idxRegDstIn, uint8_t idxRegSrc, bool fNativeFlags 170 , uint8_t cOpBits, uint8_t idxRegResult, uint8_t idxRegDstIn, uint8_t idxRegSrc 171 , bool fNativeFlags, bool fInvertCarry 171 172 #endif 172 173 ) … … 211 212 { 212 213 /* Invert CF (stored inved on ARM) and load the flags into the temporary register. */ 213 pCodeBuf[off++] = ARMV8_A64_INSTR_CFINV; 214 if (fInvertCarry) 215 pCodeBuf[off++] = ARMV8_A64_INSTR_CFINV; 214 216 pCodeBuf[off++] = Armv8A64MkInstrMrs(idxTmpReg, ARMV8_AARCH64_SYSREG_NZCV); /* Bits: 31=N; 30=Z; 29=C; 28=V; */ 215 217 … … 418 420 419 421 422 /** 423 * The ADD instruction will set all status flags. 424 */ 420 425 DECL_INLINE_THROW(uint32_t) 421 426 iemNativeEmit_add_r_r_efl(PIEMRECOMPILERSTATE pReNative, uint32_t off, 427 uint8_t idxVarDst, uint8_t idxVarSrc, uint8_t idxVarEfl, uint8_t cOpBits) 428 { 429 uint8_t const idxRegDst = iemNativeVarRegisterAcquire(pReNative, idxVarDst, &off, true /*fInitialized*/); 430 uint8_t const idxRegSrc = iemNativeVarRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/); 431 432 #ifdef RT_ARCH_AMD64 433 /* On AMD64 we just use the correctly sized ADD instruction to get the right EFLAGS.SF value. */ 434 off = iemNativeEmitAmd64ModRmInstrRREx(iemNativeInstrBufEnsure(pReNative, off, 4), off, 435 0x02, 0x03, cOpBits, idxRegDst, idxRegSrc); 436 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 437 438 iemNativeVarRegisterRelease(pReNative, idxVarSrc); 439 iemNativeVarRegisterRelease(pReNative, idxVarDst); 440 441 off = iemNativeEmitEFlagsForArithmetic(pReNative, off, idxVarEfl); 442 443 #elif defined(RT_ARCH_ARM64) 444 /* On ARM64 we'll need the two input operands as well as the result in order 445 to calculate the right flags, even if we use ADDS and translates NZCV into 446 OF, CF, ZF and SF. */ 447 uint8_t const idxRegDstIn = iemNativeRegAllocTmp(pReNative, &off); 448 PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 5); 449 if (cOpBits >= 32) 450 { 451 off = iemNativeEmitLoadGprFromGprEx(pCodeBuf, off, idxRegDstIn, idxRegDst); 452 pCodeBuf[off++] = Armv8A64MkInstrAddReg(idxRegDst, idxRegDst, idxRegSrc, cOpBits > 32 /*f64Bit*/, true /*fSetFlags*/); 453 } 454 else 455 { 456 /* Shift the operands up so we can perform a 32-bit operation and get all four flags. */ 457 uint32_t const cShift = 32 - cOpBits; 458 pCodeBuf[off++] = Armv8A64MkInstrOrr(idxRegDstIn, ARMV8_A64_REG_XZR, idxRegDst, false /*f64Bit*/, cShift); 459 pCodeBuf[off++] = Armv8A64MkInstrAddReg(idxRegDst, idxRegDstIn, idxRegSrc, false /*f64Bit*/, 460 true /*fSetFlags*/, cShift); 461 pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxRegDstIn, idxRegDstIn, cShift, false /*f64Bit*/); 462 pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxRegDst, idxRegDst, cShift, false /*f64Bit*/); 463 cOpBits = 32; 464 } 465 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 466 467 /** @todo Explain why the carry flag shouldn't be inverted for ADDS. */ 468 off = iemNativeEmitEFlagsForArithmetic(pReNative, off, idxVarEfl, cOpBits, idxRegDst, 469 idxRegDstIn, idxRegSrc, true /*fNativeFlags*/, false /*fInvertCarry*/); 470 471 iemNativeRegFreeTmp(pReNative, idxRegDstIn); 472 iemNativeVarRegisterRelease(pReNative, idxVarSrc); 473 iemNativeVarRegisterRelease(pReNative, idxVarDst); 474 475 #else 476 # error "port me" 477 #endif 478 return off; 479 } 480 481 482 DECL_INLINE_THROW(uint32_t) 483 iemNativeEmit_adc_r_r_efl(PIEMRECOMPILERSTATE pReNative, uint32_t off, 422 484 uint8_t idxVarDst, uint8_t idxVarSrc, uint8_t idxVarEfl, uint8_t cOpBits) 423 485 { … … 428 490 429 491 430 DECL_INLINE_THROW(uint32_t) 431 iemNativeEmit_adc_r_r_efl(PIEMRECOMPILERSTATE pReNative, uint32_t off, 432 uint8_t idxVarDst, uint8_t idxVarSrc, uint8_t idxVarEfl, uint8_t cOpBits) 433 { 434 RT_NOREF(idxVarDst, idxVarSrc, idxVarEfl, cOpBits); 435 AssertFailed(); 436 return iemNativeEmitBrk(pReNative, off, 0x666); 437 } 438 439 492 /** 493 * The SUB instruction will set all status flags. 494 */ 440 495 DECL_INLINE_THROW(uint32_t) 441 496 iemNativeEmit_sub_r_r_efl(PIEMRECOMPILERSTATE pReNative, uint32_t off, 442 497 uint8_t idxVarDst, uint8_t idxVarSrc, uint8_t idxVarEfl, uint8_t cOpBits) 443 498 { 444 /*445 * The SUB instruction will set all flags.446 */447 499 uint8_t const idxRegDst = iemNativeVarRegisterAcquire(pReNative, idxVarDst, &off, true /*fInitialized*/); 448 500 uint8_t const idxRegSrc = iemNativeVarRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/); … … 475 527 uint32_t const cShift = 32 - cOpBits; 476 528 pCodeBuf[off++] = Armv8A64MkInstrOrr(idxRegDstIn, ARMV8_A64_REG_XZR, idxRegDst, false /*f64Bit*/, cShift); 477 pCodeBuf[off++] = Armv8A64MkInstrSubReg(idxRegDst, idxRegDstIn, idxRegSrc, cOpBits > 32/*f64Bit*/,529 pCodeBuf[off++] = Armv8A64MkInstrSubReg(idxRegDst, idxRegDstIn, idxRegSrc, false /*f64Bit*/, 478 530 true /*fSetFlags*/, cShift); 479 531 pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxRegDstIn, idxRegDstIn, cShift, false /*f64Bit*/); … … 484 536 485 537 off = iemNativeEmitEFlagsForArithmetic(pReNative, off, idxVarEfl, cOpBits, idxRegDst, 486 idxRegDstIn, idxRegSrc, true /*fNativeFlags*/ );538 idxRegDstIn, idxRegSrc, true /*fNativeFlags*/, true /*fInvertCarry*/); 487 539 488 540 iemNativeRegFreeTmp(pReNative, idxRegDstIn); … … 497 549 498 550 551 /** 552 * The CMP instruction will set all status flags, but modifies no registers. 553 */ 499 554 DECL_INLINE_THROW(uint32_t) 500 555 iemNativeEmit_cmp_r_r_efl(PIEMRECOMPILERSTATE pReNative, uint32_t off, 501 556 uint8_t idxVarDst, uint8_t idxVarSrc, uint8_t idxVarEfl, uint8_t cOpBits) 502 557 { 503 /*504 * The SUB instruction will set all flags.505 */506 558 uint8_t const idxRegDst = iemNativeVarRegisterAcquire(pReNative, idxVarDst, &off, true /*fInitialized*/); 507 559 uint8_t const idxRegSrc = iemNativeVarRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/); … … 531 583 uint32_t const cShift = 32 - cOpBits; 532 584 pCodeBuf[off++] = Armv8A64MkInstrOrr(idxRegResult, ARMV8_A64_REG_XZR, idxRegDst, false /*f64Bit*/, cShift); 533 pCodeBuf[off++] = Armv8A64MkInstrSubReg(idxRegResult, idxRegResult, idxRegSrc, cOpBits > 32/*f64Bit*/,585 pCodeBuf[off++] = Armv8A64MkInstrSubReg(idxRegResult, idxRegResult, idxRegSrc, false /*f64Bit*/, 534 586 true /*fSetFlags*/, cShift); 535 587 pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxRegResult, idxRegResult, cShift, false /*f64Bit*/); … … 539 591 540 592 off = iemNativeEmitEFlagsForArithmetic(pReNative, off, idxVarEfl, cOpBits, idxRegResult, 541 idxRegDst, idxRegSrc, true /*fNativeFlags*/ );593 idxRegDst, idxRegSrc, true /*fNativeFlags*/, true /*fInvertCarry*/); 542 594 543 595 iemNativeRegFreeTmp(pReNative, idxRegResult);
Note:
See TracChangeset
for help on using the changeset viewer.