- Timestamp:
- Oct 24, 2023 9:40:58 AM (16 months ago)
- svn:sync-xref-src-repo-rev:
- 159657
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py
r101570 r101576 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, ), 2894 'IEM_MC_IF_EFL_BITS_NE': (McBlock.parseMcGenericCond, True, False, ),2894 'IEM_MC_IF_EFL_BITS_NE': (McBlock.parseMcGenericCond, True, True, ), 2895 2895 'IEM_MC_IF_EFL_NO_BITS_SET': (McBlock.parseMcGenericCond, True, True, ), 2896 2896 'IEM_MC_IF_FCW_IM': (McBlock.parseMcGenericCond, True, False, ), -
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r101570 r101576 4375 4375 4376 4376 4377 #define IEM_MC_IF_EFL_BITS_EQ(a_fBit1, a_fBit2) \ 4378 off = iemNativeEmitIfEflagsTwoBitsComp(pReNative, off, a_fBit1, a_fBit2, false /*fNotEqual*/); \ 4379 AssertReturn(off != UINT32_MAX, UINT32_MAX); \ 4380 do { 4381 4382 #define IEM_MC_IF_EFL_BITS_NE(a_fBit1, a_fBit2) \ 4383 off = iemNativeEmitIfEflagsTwoBitsComp(pReNative, off, a_fBit1, a_fBit2, true /*fNotEqual*/); \ 4384 AssertReturn(off != UINT32_MAX, UINT32_MAX); \ 4385 do { 4386 4387 /** Emits code for IEM_MC_IF_EFL_BITS_EQ and IEM_MC_IF_EFL_BITS_NE. */ 4388 DECLINLINE(uint32_t) iemNativeEmitIfEflagsTwoBitsComp(PIEMRECOMPILERSTATE pReNative, uint32_t off, 4389 uint32_t fBit1InEfl, uint32_t fBit2InEfl, bool fNotEqual) 4390 { 4391 PIEMNATIVECOND pEntry = iemNativeCondPushIf(pReNative); 4392 AssertReturn(pEntry, UINT32_MAX); 4393 4394 /* Get the eflags. */ 4395 uint8_t const idxEflReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_EFlags, 4396 kIemNativeGstRegUse_ReadOnly); 4397 AssertReturn(idxEflReg != UINT8_MAX, UINT32_MAX); 4398 4399 unsigned const iBitNo1 = ASMBitFirstSetU32(fBit1InEfl) - 1; 4400 Assert(RT_BIT_32(iBitNo1) == fBit1InEfl); 4401 4402 unsigned const iBitNo2 = ASMBitFirstSetU32(fBit2InEfl) - 1; 4403 Assert(RT_BIT_32(iBitNo2) == fBit2InEfl); 4404 Assert(iBitNo1 != iBitNo2); 4405 4406 #ifdef RT_ARCH_AMD64 4407 uint8_t const idxTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, fBit1InEfl); 4408 AssertReturn(idxTmpReg != UINT8_MAX, UINT32_MAX); 4409 4410 off = iemNativeEmitAndGpr32ByGpr32(pReNative, off, idxTmpReg, idxEflReg); 4411 if (iBitNo1 > iBitNo2) 4412 off = iemNativeEmitShiftGpr32Right(pReNative, off, idxTmpReg, iBitNo1 - iBitNo2); 4413 else 4414 off = iemNativeEmitShiftGpr32Left(pReNative, off, idxTmpReg, iBitNo2 - iBitNo1); 4415 off = iemNativeEmitXorGpr32ByGpr32(pReNative, off, idxTmpReg, idxEflReg); 4416 4417 /* Test and jump. */ 4418 if (fNotEqual) 4419 off = iemNativeEmitTestBitInGprAndJmpToLabelIfSet(pReNative, off, idxTmpReg, iBitNo1, pEntry->idxLabelElse); 4420 else 4421 off = iemNativeEmitTestBitInGprAndJmpToLabelIfNotSet(pReNative, off, idxTmpReg, iBitNo1, pEntry->idxLabelElse); 4422 4423 iemNativeRegFreeTmp(pReNative, idxTmpReg); 4424 4425 #elif defined(RT_ARCH_ARM64) 4426 uint8_t const idxTmpReg = iemNativeRegAllocTmp(pReNative, &off); 4427 AssertReturn(idxTmpReg != UINT8_MAX, UINT32_MAX); 4428 4429 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 2); 4430 AssertReturn(pu32CodeBuf, UINT32_MAX); 4431 4432 /* and tmpreg, eflreg, #1<<iBitNo1 */ 4433 pu32CodeBuf[off++] = Armv8A64MkInstrAndImm(idxTmpReg, idxEflReg, 0 /*uImm7SizeLen -> 32*/, 32 - iBitNo1, false /*f64Bit*/); 4434 4435 /* eeyore tmpreg, eflreg, LSL/LSR, #abs(iBitNo2 - iBitNo1) */ 4436 if (iBitNo1 > iBitNo2) 4437 pu32CodeBuf[off++] = Armv8A64MkInstrEor(idxTmpReg, idxTmpReg, idxEflReg, false /*64bit*/, 4438 iBitNo1 - iBitNo2, kArmv8A64InstrShift_Lsl); 4439 else 4440 pu32CodeBuf[off++] = Armv8A64MkInstrEor(idxTmpReg, idxTmpReg, idxEflReg, false /*64bit*/, 4441 iBitNo2 - iBitNo1, kArmv8A64InstrShift_Lsr); 4442 4443 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 4444 4445 /* Test and jump. */ 4446 if (fNotEqual) 4447 off = iemNativeEmitTestBitInGprAndJmpToLabelIfSet(pReNative, off, idxTmpReg, iBitNo1, pEntry->idxLabelElse); 4448 else 4449 off = iemNativeEmitTestBitInGprAndJmpToLabelIfNotSet(pReNative, off, idxTmpReg, iBitNo1, pEntry->idxLabelElse); 4450 4451 iemNativeRegFreeTmp(pReNative, idxTmpReg); 4452 4453 #else 4454 # error "Port me" 4455 #endif 4456 4457 /* Free but don't flush the EFlags register. */ 4458 iemNativeRegFreeTmp(pReNative, idxEflReg); 4459 4460 /* Make a copy of the core state now as we start the if-block. */ 4461 iemNativeCondStartIfBlock(pReNative, off); 4462 4463 return off; 4464 } 4465 4466 4377 4467 4378 4468 /********************************************************************************************************************************* -
trunk/src/VBox/VMM/include/IEMN8veRecompiler.h
r101568 r101576 1683 1683 1684 1684 /** 1685 * Emits code for AND'ing two 64-bit GPRs. 1686 */ 1687 DECLINLINE(uint32_t ) iemNativeEmitAndGprByGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 1688 { 1689 #if defined(RT_ARCH_AMD64) 1690 /* and Gv, Ev */ 1691 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 1692 AssertReturn(pbCodeBuf, UINT32_MAX); 1693 pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B); 1694 pbCodeBuf[off++] = 0x23; 1695 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7); 1696 1697 #elif defined(RT_ARCH_ARM64) 1698 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1699 AssertReturn(pu32CodeBuf, UINT32_MAX); 1700 pu32CodeBuf[off++] = Armv8A64MkInstrAnd(iGprDst, iGprDst, iGprSrc); 1701 1702 #else 1703 # error "Port me" 1704 #endif 1705 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 1706 return off; 1707 } 1708 1709 1710 /** 1711 * Emits code for AND'ing two 32-bit GPRs. 1712 */ 1713 DECLINLINE(uint32_t ) iemNativeEmitAndGpr32ByGpr32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 1714 { 1715 #if defined(RT_ARCH_AMD64) 1716 /* and Gv, Ev */ 1717 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 1718 AssertReturn(pbCodeBuf, UINT32_MAX); 1719 if (iGprDst >= 8 || iGprSrc >= 8) 1720 pbCodeBuf[off++] = (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B); 1721 pbCodeBuf[off++] = 0x23; 1722 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7); 1723 1724 #elif defined(RT_ARCH_ARM64) 1725 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1726 AssertReturn(pu32CodeBuf, UINT32_MAX); 1727 pu32CodeBuf[off++] = Armv8A64MkInstrAnd(iGprDst, iGprDst, iGprSrc, false /*f64Bit*/); 1728 1729 #else 1730 # error "Port me" 1731 #endif 1732 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 1733 return off; 1734 } 1735 1736 1737 /** 1738 * Emits code for XOR'ing two 64-bit GPRs. 1739 */ 1740 DECLINLINE(uint32_t ) iemNativeEmitXorGprByGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 1741 { 1742 #if defined(RT_ARCH_AMD64) 1743 /* and Gv, Ev */ 1744 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 1745 AssertReturn(pbCodeBuf, UINT32_MAX); 1746 pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B); 1747 pbCodeBuf[off++] = 0x33; 1748 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7); 1749 1750 #elif defined(RT_ARCH_ARM64) 1751 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1752 AssertReturn(pu32CodeBuf, UINT32_MAX); 1753 pu32CodeBuf[off++] = Armv8A64MkInstrEor(iGprDst, iGprDst, iGprSrc); 1754 1755 #else 1756 # error "Port me" 1757 #endif 1758 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 1759 return off; 1760 } 1761 1762 1763 /** 1764 * Emits code for XOR'ing two 32-bit GPRs. 1765 */ 1766 DECLINLINE(uint32_t ) iemNativeEmitXorGpr32ByGpr32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 1767 { 1768 #if defined(RT_ARCH_AMD64) 1769 /* and Gv, Ev */ 1770 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 1771 AssertReturn(pbCodeBuf, UINT32_MAX); 1772 if (iGprDst >= 8 || iGprSrc >= 8) 1773 pbCodeBuf[off++] = (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B); 1774 pbCodeBuf[off++] = 0x33; 1775 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7); 1776 1777 #elif defined(RT_ARCH_ARM64) 1778 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1779 AssertReturn(pu32CodeBuf, UINT32_MAX); 1780 pu32CodeBuf[off++] = Armv8A64MkInstrEor(iGprDst, iGprDst, iGprSrc, false /*f64Bit*/); 1781 1782 #else 1783 # error "Port me" 1784 #endif 1785 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 1786 return off; 1787 } 1788 1789 1790 /********************************************************************************************************************************* 1791 * Shifting * 1792 *********************************************************************************************************************************/ 1793 1794 /** 1795 * Emits code for shifting a GPR a fixed number of bits to the left. 1796 */ 1797 DECLINLINE(uint32_t ) iemNativeEmitShiftGprLeft(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t cShift) 1798 { 1799 Assert(cShift > 0 && cShift < 64); 1800 1801 #if defined(RT_ARCH_AMD64) 1802 /* shl dst, cShift */ 1803 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 1804 AssertReturn(pbCodeBuf, UINT32_MAX); 1805 pbCodeBuf[off++] = iGprDst < 8 ? X86_OP_REX_W : X86_OP_REX_W | X86_OP_REX_B; 1806 if (cShift != 1) 1807 { 1808 pbCodeBuf[off++] = 0xc1; 1809 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 4, iGprDst & 7); 1810 pbCodeBuf[off++] = cShift; 1811 } 1812 else 1813 { 1814 pbCodeBuf[off++] = 0xd1; 1815 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 4, iGprDst & 7); 1816 } 1817 1818 #elif defined(RT_ARCH_ARM64) 1819 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1820 AssertReturn(pu32CodeBuf, UINT32_MAX); 1821 pu32CodeBuf[off++] = Armv8A64MkInstrLslImm(iGprDst, iGprDst, cShift); 1822 1823 #else 1824 # error "Port me" 1825 #endif 1826 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 1827 return off; 1828 } 1829 1830 1831 /** 1832 * Emits code for shifting a 32-bit GPR a fixed number of bits to the left. 1833 */ 1834 DECLINLINE(uint32_t ) iemNativeEmitShiftGpr32Left(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t cShift) 1835 { 1836 Assert(cShift > 0 && cShift < 32); 1837 1838 #if defined(RT_ARCH_AMD64) 1839 /* shl dst, cShift */ 1840 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 1841 AssertReturn(pbCodeBuf, UINT32_MAX); 1842 if (iGprDst >= 8) 1843 pbCodeBuf[off++] = X86_OP_REX_B; 1844 if (cShift != 1) 1845 { 1846 pbCodeBuf[off++] = 0xc1; 1847 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 4, iGprDst & 7); 1848 pbCodeBuf[off++] = cShift; 1849 } 1850 else 1851 { 1852 pbCodeBuf[off++] = 0xd1; 1853 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 4, iGprDst & 7); 1854 } 1855 1856 #elif defined(RT_ARCH_ARM64) 1857 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1858 AssertReturn(pu32CodeBuf, UINT32_MAX); 1859 pu32CodeBuf[off++] = Armv8A64MkInstrLslImm(iGprDst, iGprDst, cShift, false /*64Bit*/); 1860 1861 #else 1862 # error "Port me" 1863 #endif 1864 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 1865 return off; 1866 } 1867 1868 1869 /** 1685 1870 * Emits code for (unsigned) shifting a GPR a fixed number of bits to the right. 1686 1871 */ 1687 1872 DECLINLINE(uint32_t ) iemNativeEmitShiftGprRight(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t cShift) 1688 1873 { 1874 Assert(cShift > 0 && cShift < 64); 1875 1689 1876 #if defined(RT_ARCH_AMD64) 1690 1877 /* shr dst, cShift */ … … 1692 1879 AssertReturn(pbCodeBuf, UINT32_MAX); 1693 1880 pbCodeBuf[off++] = iGprDst < 8 ? X86_OP_REX_W : X86_OP_REX_W | X86_OP_REX_B; 1694 pbCodeBuf[off++] = 0xc0; 1695 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 5, iGprDst & 7); 1696 pbCodeBuf[off++] = cShift; 1697 Assert(cShift > 0 && cShift < 64); 1881 if (cShift != 1) 1882 { 1883 pbCodeBuf[off++] = 0xc1; 1884 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 5, iGprDst & 7); 1885 pbCodeBuf[off++] = cShift; 1886 } 1887 else 1888 { 1889 pbCodeBuf[off++] = 0xd1; 1890 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 5, iGprDst & 7); 1891 } 1698 1892 1699 1893 #elif defined(RT_ARCH_ARM64) … … 1701 1895 AssertReturn(pu32CodeBuf, UINT32_MAX); 1702 1896 pu32CodeBuf[off++] = Armv8A64MkInstrLsrImm(iGprDst, iGprDst, cShift); 1897 1703 1898 #else 1704 1899 # error "Port me" … … 1707 1902 return off; 1708 1903 } 1904 1905 1906 /** 1907 * Emits code for (unsigned) shifting a 32-bit GPR a fixed number of bits to the 1908 * right. 1909 */ 1910 DECLINLINE(uint32_t ) iemNativeEmitShiftGpr32Right(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t cShift) 1911 { 1912 Assert(cShift > 0 && cShift < 32); 1913 1914 #if defined(RT_ARCH_AMD64) 1915 /* shr dst, cShift */ 1916 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 1917 AssertReturn(pbCodeBuf, UINT32_MAX); 1918 if (iGprDst >= 8) 1919 pbCodeBuf[off++] = X86_OP_REX_B; 1920 if (cShift != 1) 1921 { 1922 pbCodeBuf[off++] = 0xc1; 1923 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 5, iGprDst & 7); 1924 pbCodeBuf[off++] = cShift; 1925 } 1926 else 1927 { 1928 pbCodeBuf[off++] = 0xd1; 1929 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 5, iGprDst & 7); 1930 } 1931 1932 #elif defined(RT_ARCH_ARM64) 1933 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1934 AssertReturn(pu32CodeBuf, UINT32_MAX); 1935 pu32CodeBuf[off++] = Armv8A64MkInstrLsrImm(iGprDst, iGprDst, cShift, false /*64Bit*/); 1936 1937 #else 1938 # error "Port me" 1939 #endif 1940 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 1941 return off; 1942 } 1943 1709 1944 1710 1945
Note:
See TracChangeset
for help on using the changeset viewer.