Changeset 101537 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Oct 21, 2023 2:16:05 AM (16 months ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py
r101484 r101537 2889 2889 'IEM_MC_IF_EFL_BIT_NOT_SET': (McBlock.parseMcGenericCond, True, False, ), 2890 2890 'IEM_MC_IF_EFL_BIT_NOT_SET_AND_BITS_EQ': (McBlock.parseMcGenericCond, True, False, ), 2891 'IEM_MC_IF_EFL_BIT_SET': (McBlock.parseMcGenericCond, True, False, ),2891 'IEM_MC_IF_EFL_BIT_SET': (McBlock.parseMcGenericCond, True, False,), #True, ), 2892 2892 'IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE': (McBlock.parseMcGenericCond, True, False, ), 2893 2893 'IEM_MC_IF_EFL_BITS_EQ': (McBlock.parseMcGenericCond, True, False, ), -
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r101536 r101537 1587 1587 pReNative->bmHstRegsWithGstShadow = 0; 1588 1588 pReNative->bmGstRegShadows = 0; 1589 pReNative->cCondDepth = 0; 1590 pReNative->uCondSeqNo = 0; 1589 1591 pReNative->bmVars = 0; 1590 1592 pReNative->u64ArgVars = UINT64_MAX; … … 1934 1936 /* [kIemNativeGstReg_GprFirst + X86_GREG_x15] = */ { CPUMCTX_OFF_AND_SIZE(r15), "r15", }, 1935 1937 /* [kIemNativeGstReg_Pc] = */ { CPUMCTX_OFF_AND_SIZE(rip), "rip", }, 1936 /* [kIemNativeGstReg_ Rflags] = */ { CPUMCTX_OFF_AND_SIZE(rflags), "rflags", },1938 /* [kIemNativeGstReg_EFlags] = */ { CPUMCTX_OFF_AND_SIZE(eflags), "eflags", }, 1937 1939 /* [18] = */ { UINT32_C(0xfffffff7), 0, NULL, }, 1938 1940 /* [19] = */ { UINT32_C(0xfffffff5), 0, NULL, }, … … 3569 3571 { 3570 3572 3573 /** We have to get to the end in recompilation mode, as otherwise we won't 3574 * generate code for all the IEM_MC_IF_XXX branches. */ 3571 3575 #define IEM_MC_END() \ 3572 } AssertFailedReturn(UINT32_MAX /* shouldn't be reached! */) 3573 3576 } return off 3577 3578 3579 /* 3580 * Standalone CImpl deferals. 3581 */ 3574 3582 3575 3583 #define IEM_MC_DEFER_TO_CIMPL_0_RET_THREADED(a_cbInstr, a_fFlags, a_pfnCImpl) \ … … 3612 3620 3613 3621 #define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC64(a_cbInstr) \ 3614 return iemNativeEmitAddToRip64AndFinishingNoFlags(pReNative, off, (a_cbInstr)) 3622 off = iemNativeEmitAddToRip64AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \ 3623 AssertReturn(off != UINT32_MAX, UINT32_MAX) 3615 3624 3616 3625 /** Same as iemRegAddToRip64AndFinishingNoFlags. */ … … 3633 3642 3634 3643 #define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC32(a_cbInstr) \ 3635 return iemNativeEmitAddToEip32AndFinishingNoFlags(pReNative, off, (a_cbInstr)) 3644 off = iemNativeEmitAddToEip32AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \ 3645 AssertReturn(off != UINT32_MAX, UINT32_MAX) 3636 3646 3637 3647 /** Same as iemRegAddToEip32AndFinishingNoFlags. */ … … 3654 3664 3655 3665 #define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC16(a_cbInstr) \ 3656 return iemNativeEmitAddToIp16AndFinishingNoFlags(pReNative, off, (a_cbInstr)) 3666 off = iemNativeEmitAddToIp16AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \ 3667 AssertReturn(off != UINT32_MAX, UINT32_MAX) 3657 3668 3658 3669 /** Same as iemRegAddToIp16AndFinishingNoFlags. */ … … 3680 3691 3681 3692 #define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC64(a_i8, a_cbInstr, a_enmEffOpSize) \ 3682 return iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), (a_enmEffOpSize), pCallEntry->idxInstr) 3693 off = iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), \ 3694 (a_enmEffOpSize), pCallEntry->idxInstr); \ 3695 AssertReturn(off != UINT32_MAX, UINT32_MAX) 3696 3683 3697 3684 3698 #define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC64(a_i16, a_cbInstr) \ 3685 return iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), IEMMODE_16BIT, pCallEntry->idxInstr) 3699 off = iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), \ 3700 IEMMODE_16BIT, pCallEntry->idxInstr); \ 3701 AssertReturn(off != UINT32_MAX, UINT32_MAX) 3686 3702 3687 3703 #define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC64(a_i32, a_cbInstr) \ 3688 return iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), IEMMODE_64BIT, pCallEntry->idxInstr) 3704 off = iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), \ 3705 IEMMODE_64BIT, pCallEntry->idxInstr); \ 3706 AssertReturn(off != UINT32_MAX, UINT32_MAX) 3689 3707 3690 3708 /** Same as iemRegRip64RelativeJumpS8AndFinishNoFlags, … … 3728 3746 3729 3747 #define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC32(a_i8, a_cbInstr, a_enmEffOpSize) \ 3730 return iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), (a_enmEffOpSize), pCallEntry->idxInstr) 3748 off = iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), \ 3749 (a_enmEffOpSize), pCallEntry->idxInstr); \ 3750 AssertReturn(off != UINT32_MAX, UINT32_MAX) 3731 3751 3732 3752 #define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC32(a_i16, a_cbInstr) \ 3733 return iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), IEMMODE_16BIT, pCallEntry->idxInstr) 3753 off = iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), \ 3754 IEMMODE_16BIT, pCallEntry->idxInstr); \ 3755 AssertReturn(off != UINT32_MAX, UINT32_MAX) 3734 3756 3735 3757 #define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC32(a_i32, a_cbInstr) \ 3736 return iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), IEMMODE_32BIT, pCallEntry->idxInstr) 3758 off = iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), \ 3759 IEMMODE_32BIT, pCallEntry->idxInstr); \ 3760 AssertReturn(off != UINT32_MAX, UINT32_MAX) 3737 3761 3738 3762 /** Same as iemRegEip32RelativeJumpS8AndFinishNoFlags, … … 3775 3799 3776 3800 #define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC16(a_i8, a_cbInstr) \ 3777 return iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), pCallEntry->idxInstr) 3801 off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), pCallEntry->idxInstr); \ 3802 AssertReturn(off != UINT32_MAX, UINT32_MAX) 3778 3803 3779 3804 #define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC16(a_i16, a_cbInstr) \ 3780 return iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), pCallEntry->idxInstr) 3805 off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), pCallEntry->idxInstr); \ 3806 AssertReturn(off != UINT32_MAX, UINT32_MAX) 3781 3807 3782 3808 #define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC16(a_i32, a_cbInstr) \ 3783 return iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), pCallEntry->idxInstr) 3809 off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), pCallEntry->idxInstr); \ 3810 AssertReturn(off != UINT32_MAX, UINT32_MAX) 3784 3811 3785 3812 /** Same as iemRegIp16RelativeJumpS8AndFinishNoFlags. */ … … 3802 3829 /* Free but don't flush the PC register. */ 3803 3830 iemNativeRegFreeTmp(pReNative, idxPcReg); 3831 3832 return off; 3833 } 3834 3835 3836 /* 3837 * Conditionals. 3838 */ 3839 3840 /** 3841 * Pushes an IEM_MC_IF_XXX onto the condition stack. 3842 * 3843 * @returns Pointer to the condition stack entry on success, NULL on failure 3844 * (too many nestings) 3845 */ 3846 DECLINLINE(PIEMNATIVECOND) iemNativeCondPushIf(PIEMRECOMPILERSTATE pReNative) 3847 { 3848 uint32_t const idxStack = pReNative->cCondDepth; 3849 AssertReturn(idxStack < RT_ELEMENTS(pReNative->aCondStack), NULL); 3850 3851 PIEMNATIVECOND const pEntry = &pReNative->aCondStack[idxStack]; 3852 pReNative->cCondDepth = (uint8_t)(idxStack + 1); 3853 3854 uint16_t const uCondSeqNo = ++pReNative->uCondSeqNo; 3855 pEntry->fInElse = false; 3856 pEntry->idxLabelElse = iemNativeMakeLabel(pReNative, kIemNativeLabelType_Else, UINT32_MAX /*offWhere*/, uCondSeqNo); 3857 AssertReturn(pEntry->idxLabelElse != UINT32_MAX, NULL); 3858 pEntry->idxLabelEndIf = iemNativeMakeLabel(pReNative, kIemNativeLabelType_Endif, UINT32_MAX /*offWhere*/, uCondSeqNo); 3859 AssertReturn(pEntry->idxLabelEndIf != UINT32_MAX, NULL); 3860 3861 return pEntry; 3862 } 3863 3864 3865 #define IEM_MC_ELSE() } while (0); \ 3866 off = iemNativeEmitElse(pReNative, off); \ 3867 AssertReturn(off != UINT32_MAX, UINT32_MAX); \ 3868 do { 3869 3870 /** Emits code related to IEM_MC_ELSE. */ 3871 DECLINLINE(uint32_t) iemNativeEmitElse(PIEMRECOMPILERSTATE pReNative, uint32_t off) 3872 { 3873 /* Check sanity and get the conditional stack entry. */ 3874 Assert(off != UINT32_MAX); 3875 Assert(pReNative->cCondDepth > 0 && pReNative->cCondDepth <= RT_ELEMENTS(pReNative->aCondStack)); 3876 PIEMNATIVECOND const pEntry = &pReNative->aCondStack[pReNative->cCondDepth - 1]; 3877 Assert(!pEntry->fInElse); 3878 3879 /* Jump to the endif */ 3880 off = iemNativeEmitJmpToLabel(pReNative, off, pEntry->idxLabelEndIf); 3881 3882 /* Define the else label and enter the else part of the condition. */ 3883 pReNative->paLabels[pEntry->idxLabelElse].off = off; 3884 pEntry->fInElse = true; 3885 3886 return off; 3887 } 3888 3889 3890 #define IEM_MC_ENDIF() } while (0); \ 3891 off = iemNativeEmitEndIf(pReNative, off); \ 3892 AssertReturn(off != UINT32_MAX, UINT32_MAX) 3893 3894 /** Emits code related to IEM_MC_ENDIF. */ 3895 DECLINLINE(uint32_t) iemNativeEmitEndIf(PIEMRECOMPILERSTATE pReNative, uint32_t off) 3896 { 3897 /* Check sanity and get the conditional stack entry. */ 3898 Assert(off != UINT32_MAX); 3899 Assert(pReNative->cCondDepth > 0 && pReNative->cCondDepth <= RT_ELEMENTS(pReNative->aCondStack)); 3900 PIEMNATIVECOND const pEntry = &pReNative->aCondStack[pReNative->cCondDepth - 1]; 3901 3902 /* Define the endif label and maybe the else one if we're still in the 'if' part. */ 3903 if (!pEntry->fInElse) 3904 pReNative->paLabels[pEntry->idxLabelElse].off = off; 3905 else 3906 Assert(pReNative->paLabels[pEntry->idxLabelElse].off <= off); 3907 pReNative->paLabels[pEntry->idxLabelEndIf].off = off; 3908 3909 /* Pop the conditional stack.*/ 3910 pReNative->cCondDepth -= 1; 3911 3912 return off; 3913 } 3914 3915 3916 #define IEM_MC_IF_EFL_BIT_SET(a_fBit) \ 3917 off = iemNativeEmitIfEflagsBitSet(pReNative, off, (a_fBit)); \ 3918 AssertReturn(off != UINT32_MAX, UINT32_MAX); \ 3919 do { 3920 3921 /** Emits code for IEM_MC_IF_EFL_BIT_SET. */ 3922 DECLINLINE(uint32_t) iemNativeEmitIfEflagsBitSet(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t fBitInEfl) 3923 { 3924 PIEMNATIVECOND pEntry = iemNativeCondPushIf(pReNative); 3925 AssertReturn(pEntry, UINT32_MAX); 3926 3927 /* Get the eflags. */ 3928 uint8_t const idxEflReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_EFlags, 3929 kIemNativeGstRegUse_ReadOnly); 3930 AssertReturn(idxEflReg != UINT8_MAX, UINT32_MAX); 3931 3932 unsigned const iBitNo = ASMBitFirstSetU32(fBitInEfl) - 1; 3933 Assert(RT_BIT_32(iBitNo) == fBitInEfl); 3934 3935 /* Test and jump. */ 3936 off = iemNativeEmitTestBitInGprAndJmpToLabelIfSet(pReNative, off, idxEflReg, iBitNo, pEntry->idxLabelElse); 3937 3938 /* Free but don't flush the EFlags register. */ 3939 iemNativeRegFreeTmp(pReNative, idxEflReg); 3804 3940 3805 3941 return off; … … 3895 4031 off = iemNativeEmitThreadedCall(pReNative, off, pCallEntry); 3896 4032 AssertReturn(off != UINT32_MAX, pTb); 4033 Assert(pReNative->cCondDepth == 0); 3897 4034 3898 4035 pCallEntry++; -
trunk/src/VBox/VMM/include/IEMN8veRecompiler.h
r101535 r101537 257 257 kIemNativeLabelType_Invalid = 0, 258 258 kIemNativeLabelType_Return, 259 kIemNativeLabelType_Else, 260 kIemNativeLabelType_Endif, 259 261 kIemNativeLabelType_NonZeroRetOrPassUp, 260 262 kIemNativeLabelType_RaiseGp0, … … 285 287 kIemNativeFixupType_Rel32, 286 288 #elif defined(RT_ARCH_ARM64) 287 /** ARM64 fixup: PC relative offset at bits 23:5 (CBZ, CBNZ ). */289 /** ARM64 fixup: PC relative offset at bits 23:5 (CBZ, CBNZ, B, B.CC). */ 288 290 kIemNativeFixupType_RelImm19At5, 291 /** ARM64 fixup: PC relative offset at bits 18:5 (TBZ, TBNZ). */ 292 kIemNativeFixupType_RelImm14At5, 289 293 #endif 290 294 kIemNativeFixupType_End … … 315 319 kIemNativeGstReg_GprLast = 15, 316 320 kIemNativeGstReg_Pc, 317 kIemNativeGstReg_ Rflags,321 kIemNativeGstReg_EFlags, /**< This one is problematic since the higher bits are used internally. */ 318 322 /* gap: 18..23 */ 319 323 kIemNativeGstReg_SegSelFirst = 24, … … 466 470 467 471 /** 472 * Conditional stack entry. 473 */ 474 typedef struct IEMNATIVECOND 475 { 476 /** Set if we're in the "else" part, clear if we're in the "if" before it. */ 477 bool fInElse; 478 /** The label for the IEM_MC_ELSE. */ 479 uint32_t idxLabelElse; 480 /** The label for the IEM_MC_ENDIF. */ 481 uint32_t idxLabelEndIf; 482 } IEMNATIVECOND; 483 /** Pointer to a condition stack entry. */ 484 typedef IEMNATIVECOND *PIEMNATIVECOND; 485 486 487 /** 468 488 * Native recompiler state. 469 489 */ … … 510 530 uint64_t bmGstRegShadows; 511 531 532 /** The current condition stack depth (aCondStack). */ 533 uint8_t cCondDepth; 534 uint8_t bPadding; 535 /** Condition sequence number (for generating unique labels). */ 536 uint16_t uCondSeqNo; 537 512 538 /** Allocation bitmap for aVars. */ 513 539 uint32_t bmVars; 514 uint32_t u32Align;515 540 union 516 541 { … … 528 553 * there are no duplicate copies or ambiguities like that). */ 529 554 uint8_t aidxGstRegShadows[kIemNativeGstReg_End]; 555 556 /** The condition nesting stack. */ 557 IEMNATIVECOND aCondStack[4]; 558 530 559 /** Variables and arguments. */ 531 560 IEMNATIVEVAR aVars[16]; … … 658 687 } 659 688 689 690 /********************************************************************************************************************************* 691 * Loads, Stores and Related Stuff. * 692 *********************************************************************************************************************************/ 660 693 661 694 /** … … 1298 1331 1299 1332 1333 /********************************************************************************************************************************* 1334 * Subtraction and Additions * 1335 *********************************************************************************************************************************/ 1336 1337 1300 1338 #ifdef RT_ARCH_AMD64 1301 1339 /** … … 1563 1601 1564 1602 1603 1604 /********************************************************************************************************************************* 1605 * Bit Operations * 1606 *********************************************************************************************************************************/ 1607 1565 1608 /** 1566 1609 * Emits code for clearing bits 16 thru 63 in the GPR. … … 1622 1665 1623 1666 1667 /********************************************************************************************************************************* 1668 * Compare and Testing * 1669 *********************************************************************************************************************************/ 1670 1671 1624 1672 #ifdef RT_ARCH_ARM64 1625 1673 /** … … 1691 1739 } 1692 1740 1741 1742 1743 /********************************************************************************************************************************* 1744 * Branching * 1745 *********************************************************************************************************************************/ 1693 1746 1694 1747 /** … … 1764 1817 /** Condition type. */ 1765 1818 #ifdef RT_ARCH_AMD64 1766 typedef uint8_t IEMNATIVEINSTRCOND; 1819 typedef enum IEMNATIVEINSTRCOND : uint8_t 1820 { 1821 kIemNativeInstrCond_o = 0, 1822 kIemNativeInstrCond_no, 1823 kIemNativeInstrCond_c, 1824 kIemNativeInstrCond_nc, 1825 kIemNativeInstrCond_e, 1826 kIemNativeInstrCond_ne, 1827 kIemNativeInstrCond_be, 1828 kIemNativeInstrCond_nbe, 1829 kIemNativeInstrCond_s, 1830 kIemNativeInstrCond_ns, 1831 kIemNativeInstrCond_p, 1832 kIemNativeInstrCond_np, 1833 kIemNativeInstrCond_l, 1834 kIemNativeInstrCond_nl, 1835 kIemNativeInstrCond_le, 1836 kIemNativeInstrCond_nle 1837 } IEMNATIVEINSTRCOND; 1767 1838 #elif defined(RT_ARCH_ARM64) 1768 1839 typedef ARMV8INSTRCOND IEMNATIVEINSTRCOND; … … 1785 1856 AssertReturn(pbCodeBuf, UINT32_MAX); 1786 1857 pbCodeBuf[off++] = 0x0f; 1787 pbCodeBuf[off++] = enmCond | 0x80;1858 pbCodeBuf[off++] = (uint8_t)enmCond | 0x80; 1788 1859 AssertReturn(iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_Rel32, -4), UINT32_MAX); 1789 1860 pbCodeBuf[off++] = 0x00; … … 1819 1890 1820 1891 /** 1892 * Emits a JZ/JE rel32 / B.EQ imm19 to the given label. 1893 */ 1894 DECLINLINE(uint32_t) iemNativeEmitJzToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel) 1895 { 1896 #ifdef RT_ARCH_AMD64 1897 return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kIemNativeInstrCond_e); 1898 #elif defined(RT_ARCH_ARM64) 1899 return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kArmv8InstrCond_Eq); 1900 #else 1901 # error "Port me!" 1902 #endif 1903 } 1904 1905 /** 1821 1906 * Emits a JZ/JE rel32 / B.EQ imm19 to a new label. 1822 1907 */ … … 1825 1910 { 1826 1911 #ifdef RT_ARCH_AMD64 1827 return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, 0x4);1912 return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kIemNativeInstrCond_e); 1828 1913 #elif defined(RT_ARCH_ARM64) 1829 1914 return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kArmv8InstrCond_Eq); … … 1833 1918 } 1834 1919 1920 1921 /** 1922 * Emits a JNZ/JNE rel32 / B.NE imm19 to the given label. 1923 */ 1924 DECLINLINE(uint32_t) iemNativeEmitJnzToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel) 1925 { 1926 #ifdef RT_ARCH_AMD64 1927 return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kIemNativeInstrCond_ne); 1928 #elif defined(RT_ARCH_ARM64) 1929 return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kArmv8InstrCond_Ne); 1930 #else 1931 # error "Port me!" 1932 #endif 1933 } 1835 1934 1836 1935 /** … … 1841 1940 { 1842 1941 #ifdef RT_ARCH_AMD64 1843 return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, 0x5);1942 return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kIemNativeInstrCond_ne); 1844 1943 #elif defined(RT_ARCH_ARM64) 1845 1944 return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kArmv8InstrCond_Ne); … … 1849 1948 } 1850 1949 1950 1951 /** 1952 * Emits a JBE/JNA rel32 / B.LS imm19 to the given label. 1953 */ 1954 DECLINLINE(uint32_t) iemNativeEmitJbeToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel) 1955 { 1956 #ifdef RT_ARCH_AMD64 1957 return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kIemNativeInstrCond_be); 1958 #elif defined(RT_ARCH_ARM64) 1959 return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kArmv8InstrCond_Ls); 1960 #else 1961 # error "Port me!" 1962 #endif 1963 } 1851 1964 1852 1965 /** … … 1857 1970 { 1858 1971 #ifdef RT_ARCH_AMD64 1859 return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, 0x6);1972 return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kIemNativeInstrCond_be); 1860 1973 #elif defined(RT_ARCH_ARM64) 1861 1974 return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kArmv8InstrCond_Ls); … … 1865 1978 } 1866 1979 1980 1981 /** 1982 * Emits a JA/JNBE rel32 / B.HI imm19 to the given label. 1983 */ 1984 DECLINLINE(uint32_t) iemNativeEmitJaToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel) 1985 { 1986 #ifdef RT_ARCH_AMD64 1987 return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kIemNativeInstrCond_nbe); 1988 #elif defined(RT_ARCH_ARM64) 1989 return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kArmv8InstrCond_Hi); 1990 #else 1991 # error "Port me!" 1992 #endif 1993 } 1867 1994 1868 1995 /** … … 1873 2000 { 1874 2001 #ifdef RT_ARCH_AMD64 1875 return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, 0x7);2002 return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kIemNativeInstrCond_nbe); 1876 2003 #elif defined(RT_ARCH_ARM64) 1877 2004 return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kArmv8InstrCond_Hi); … … 1895 2022 if (offTarget < 128 && offTarget >= -128) 1896 2023 { 1897 pbCodeBuf[off++] = enmCond | 0x70;2024 pbCodeBuf[off++] = (uint8_t)enmCond | 0x70; 1898 2025 pbCodeBuf[off++] = RT_BYTE1((uint32_t)offTarget); 1899 2026 } … … 1901 2028 { 1902 2029 pbCodeBuf[off++] = 0x0f; 1903 pbCodeBuf[off++] = enmCond | 0x80;2030 pbCodeBuf[off++] = (uint8_t)enmCond | 0x80; 1904 2031 pbCodeBuf[off++] = RT_BYTE1((uint32_t)offTarget); 1905 2032 pbCodeBuf[off++] = RT_BYTE2((uint32_t)offTarget); … … 1928 2055 { 1929 2056 #ifdef RT_ARCH_AMD64 1930 return iemNativeEmitJccToFixed(pReNative, off, offTarget, 0x4);2057 return iemNativeEmitJccToFixed(pReNative, off, offTarget, kIemNativeInstrCond_e); 1931 2058 #elif defined(RT_ARCH_ARM64) 1932 2059 return iemNativeEmitJccToFixed(pReNative, off, offTarget, kArmv8InstrCond_Eq); … … 1944 2071 { 1945 2072 #ifdef RT_ARCH_AMD64 1946 return iemNativeEmitJccToFixed(pReNative, off, offTarget, 0x5);2073 return iemNativeEmitJccToFixed(pReNative, off, offTarget, kIemNativeInstrCond_ne); 1947 2074 #elif defined(RT_ARCH_ARM64) 1948 2075 return iemNativeEmitJccToFixed(pReNative, off, offTarget, kArmv8InstrCond_Ne); … … 1960 2087 { 1961 2088 #ifdef RT_ARCH_AMD64 1962 return iemNativeEmitJccToFixed(pReNative, off, offTarget, 0x6);2089 return iemNativeEmitJccToFixed(pReNative, off, offTarget, kIemNativeInstrCond_be); 1963 2090 #elif defined(RT_ARCH_ARM64) 1964 2091 return iemNativeEmitJccToFixed(pReNative, off, offTarget, kArmv8InstrCond_Ls); … … 1976 2103 { 1977 2104 #ifdef RT_ARCH_AMD64 1978 return iemNativeEmitJccToFixed(pReNative, off, offTarget, 0x7);2105 return iemNativeEmitJccToFixed(pReNative, off, offTarget, kIemNativeInstrCond_nbe); 1979 2106 #elif defined(RT_ARCH_ARM64) 1980 2107 return iemNativeEmitJccToFixed(pReNative, off, offTarget, kArmv8InstrCond_Hi); … … 2020 2147 2021 2148 /** 2149 * Internal helper, don't call directly. 2150 */ 2151 DECLINLINE(uint32_t) iemNativeEmitTestBitInGprAndJmpToLabelIfCc(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2152 uint8_t iGprSrc, uint8_t iBitNo, uint32_t idxLabel, 2153 bool fJmpIfSet) 2154 { 2155 Assert(iBitNo < 64); 2156 #ifdef RT_ARCH_AMD64 2157 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 5); 2158 AssertReturn(pbCodeBuf, UINT32_MAX); 2159 if (iBitNo < 8) 2160 { 2161 /* test Eb, imm8 */ 2162 if (iGprSrc >= 8) 2163 pbCodeBuf[off++] = X86_OP_REX_B; 2164 pbCodeBuf[off++] = 0xf6; 2165 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprSrc & 7); 2166 pbCodeBuf[off++] = (uint8_t)1 << iBitNo; 2167 off = iemNativeEmitJccToLabel(pReNative, off, idxLabel, fJmpIfSet ? kIemNativeInstrCond_ne : kIemNativeInstrCond_e); 2168 } 2169 else 2170 { 2171 /* bt Ev, imm8 */ 2172 if (iBitNo >= 32) 2173 pbCodeBuf[off++] = X86_OP_REX_W | (iGprSrc < 8 ? 0 : X86_OP_REX_B); 2174 else if (iGprSrc >= 8) 2175 pbCodeBuf[off++] = X86_OP_REX_B; 2176 pbCodeBuf[off++] = 0x0f; 2177 pbCodeBuf[off++] = 0xba; 2178 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 4, iGprSrc & 7); 2179 pbCodeBuf[off++] = iBitNo; 2180 off = iemNativeEmitJccToLabel(pReNative, off, idxLabel, fJmpIfSet ? kIemNativeInstrCond_c : kIemNativeInstrCond_nc); 2181 } 2182 2183 #elif defined(RT_ARCH_ARM64) 2184 /* Use the TBNZ instruction here. */ 2185 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2186 AssertReturn(pu32CodeBuf, UINT32_MAX); 2187 AssertReturn(iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_RelImm14At5), UINT32_MAX); 2188 pu32CodeBuf[off++] = Armv8A64MkInstrTbzTbnz(fJmpIfSet, 0, iGprSrc, iBitNo); 2189 2190 #else 2191 # error "Port me!" 2192 #endif 2193 return off; 2194 } 2195 2196 2197 /** 2198 * Emits a jump to @a idxLabel con the condition that bit@a iBitNo _is_ _set_ in 2199 * @a iGprSrc. 2200 * 2201 * @note On ARM64 the range is only +/-8191 instructions. 2202 */ 2203 DECLINLINE(uint32_t) iemNativeEmitTestBitInGprAndJmpToLabelIfSet(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2204 uint8_t iGprSrc, uint8_t iBitNo, uint32_t idxLabel) 2205 { 2206 return iemNativeEmitTestBitInGprAndJmpToLabelIfCc(pReNative, off, iGprSrc, iBitNo, idxLabel, false /*fJmpIfSet*/); 2207 } 2208 2209 2210 /** 2211 * Emits a jump to @a idxLabel con the condition that bit@a iBitNo _is_ _not_ 2212 * _set_ in @a iGprSrc. 2213 * 2214 * @note On ARM64 the range is only +/-8191 instructions. 2215 */ 2216 DECLINLINE(uint32_t) iemNativeEmitTestBitInGprAndJmpToLabelIfNotSet(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2217 uint8_t iGprSrc, uint8_t iBitNo, uint32_t idxLabel) 2218 { 2219 return iemNativeEmitTestBitInGprAndJmpToLabelIfCc(pReNative, off, iGprSrc, iBitNo, idxLabel, true /*fJmpIfSet*/); 2220 } 2221 2222 2223 /** 2022 2224 * Emits a call to a 64-bit address. 2023 2225 */
Note:
See TracChangeset
for help on using the changeset viewer.