- Timestamp:
- Mar 11, 2022 1:43:59 PM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 150426
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
r94169 r94170 1631 1631 * MUL 1632 1632 */ 1633 # define EMIT_MUL (a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnMul) \1634 IEM_DECL_IMPL_DEF(int, iemAImpl_mul_u ## a_cBitsWidth, a_Args) \1633 # define EMIT_MUL_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnMul, a_Suffix, a_fIntelFlags) \ 1634 IEM_DECL_IMPL_DEF(int, RT_CONCAT3(iemAImpl_mul_u,a_cBitsWidth,a_Suffix), a_Args) \ 1635 1635 { \ 1636 1636 RTUINT ## a_cBitsWidth2x ## U Result; \ … … 1638 1638 a_fnStore(Result); \ 1639 1639 \ 1640 /* MUL EFLAGS according to Skylake (similar to IMUL). */ \ 1641 uint32_t fEfl = *pfEFlags & ~(X86_EFL_SF | X86_EFL_CF | X86_EFL_OF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_PF); \ 1642 if (Result.s.Lo & RT_BIT_64(a_cBitsWidth - 1)) \ 1643 fEfl |= X86_EFL_SF; \ 1644 fEfl |= g_afParity[Result.s.Lo & 0xff]; \ 1645 if (Result.s.Hi != 0) \ 1646 fEfl |= X86_EFL_CF | X86_EFL_OF; \ 1640 /* Calc EFLAGS: */ \ 1641 uint32_t fEfl = *pfEFlags; \ 1642 if (a_fIntelFlags) \ 1643 { /* Intel: 6700K and 10980XE behavior */ \ 1644 fEfl &= ~(X86_EFL_SF | X86_EFL_CF | X86_EFL_OF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_PF); \ 1645 if (Result.s.Lo & RT_BIT_64(a_cBitsWidth - 1)) \ 1646 fEfl |= X86_EFL_SF; \ 1647 fEfl |= g_afParity[Result.s.Lo & 0xff]; \ 1648 if (Result.s.Hi != 0) \ 1649 fEfl |= X86_EFL_CF | X86_EFL_OF; \ 1650 } \ 1651 else \ 1652 { /* AMD: 3990X */ \ 1653 if (Result.s.Hi != 0) \ 1654 fEfl |= X86_EFL_CF | X86_EFL_OF; \ 1655 else \ 1656 fEfl &= ~(X86_EFL_CF | X86_EFL_OF); \ 1657 } \ 1647 1658 *pfEFlags = fEfl; \ 1648 1659 return 0; \ 1649 1660 } \ 1650 IEM_DECL_IMPL_DEF(int, iemAImpl_mul_u ## a_cBitsWidth ## _intel, a_Args) \ 1651 { \ 1652 return iemAImpl_mul_u ## a_cBitsWidth a_CallArgs; \ 1653 } \ 1654 IEM_DECL_IMPL_DEF(int, iemAImpl_mul_u ## a_cBitsWidth ## _amd, a_Args) \ 1655 { \ 1656 RTUINT ## a_cBitsWidth2x ## U Result; \ 1657 a_fnMul(Result, a_fnLoadF1(), uFactor, a_cBitsWidth2x); \ 1658 a_fnStore(Result); \ 1659 \ 1660 /* MUL EFLAGS according to Skylake (similar to IMUL). */ \ 1661 uint32_t fEfl = *pfEFlags & ~(X86_EFL_SF | X86_EFL_CF | X86_EFL_OF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_PF); \ 1662 if (Result.s.Lo & RT_BIT_64(a_cBitsWidth - 1)) \ 1663 fEfl |= X86_EFL_SF; \ 1664 fEfl |= g_afParity[Result.s.Lo & 0xff]; /* (Skylake behaviour) */ \ 1665 if (Result.s.Hi != 0) \ 1666 fEfl |= X86_EFL_CF | X86_EFL_OF; \ 1667 *pfEFlags = fEfl; \ 1668 return 0; \ 1669 } 1661 1662 # define EMIT_MUL(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnMul) \ 1663 EMIT_MUL_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnMul, RT_NOTHING, 1) \ 1664 EMIT_MUL_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnMul, _intel, 1) \ 1665 EMIT_MUL_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnMul, _amd, 0) \ 1670 1666 1671 1667 EMIT_MUL(64, 128, (uint64_t *puA, uint64_t *puD, uint64_t uFactor, uint32_t *pfEFlags), (puA, puD, uFactor, pfEFlags), … … 1689 1685 * as per the lower half of the result. 1690 1686 */ 1691 # define EMIT_IMUL(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnNeg, a_fnMul) \ 1692 IEM_DECL_IMPL_DEF(int, iemAImpl_imul_u ## a_cBitsWidth,a_Args) \ 1687 # define EMIT_IMUL_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnNeg, a_fnMul, \ 1688 a_Suffix, a_fIntelFlags) \ 1689 IEM_DECL_IMPL_DEF(int, RT_CONCAT3(iemAImpl_imul_u,a_cBitsWidth,a_Suffix),a_Args) \ 1693 1690 { \ 1694 1691 RTUINT ## a_cBitsWidth2x ## U Result; \ … … 1734 1731 a_fnStore(Result); \ 1735 1732 \ 1736 fEfl &= ~(X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_PF); \ 1737 if (Result.s.Lo & RT_BIT_64(a_cBitsWidth - 1)) \ 1738 fEfl |= X86_EFL_SF; \ 1739 fEfl |= g_afParity[Result.s.Lo & 0xff]; \ 1733 if (a_fIntelFlags) \ 1734 { \ 1735 fEfl &= ~(X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_PF); \ 1736 if (Result.s.Lo & RT_BIT_64(a_cBitsWidth - 1)) \ 1737 fEfl |= X86_EFL_SF; \ 1738 fEfl |= g_afParity[Result.s.Lo & 0xff]; \ 1739 } \ 1740 1740 *pfEFlags = fEfl; \ 1741 1741 return 0; \ 1742 } \ 1743 \ 1744 IEM_DECL_IMPL_DEF(int, iemAImpl_imul_u ## a_cBitsWidth ## _intel,a_Args) \ 1745 { \ 1746 return iemAImpl_imul_u ## a_cBitsWidth a_CallArgs; \ 1747 } \ 1748 \ 1749 IEM_DECL_IMPL_DEF(int, iemAImpl_imul_u ## a_cBitsWidth ## _amd,a_Args) \ 1750 { \ 1751 RTUINT ## a_cBitsWidth2x ## U Result; \ 1752 /* The SF, ZF, AF and PF flags are "undefined". AMD (3990x) leaves these \ 1753 flags as is - at least for the two op version. Whereas Intel skylake \ 1754 always clear AF and ZF and calculates SF and PF as per the lower half \ 1755 of the result. */ \ 1756 uint32_t fEfl = *pfEFlags & ~(X86_EFL_CF | X86_EFL_OF); \ 1757 \ 1758 uint ## a_cBitsWidth ## _t const uFactor1 = a_fnLoadF1(); \ 1759 if (!(uFactor1 & RT_BIT_64(a_cBitsWidth - 1))) \ 1760 { \ 1761 if (!(uFactor2 & RT_BIT_64(a_cBitsWidth - 1))) \ 1762 { \ 1763 a_fnMul(Result, uFactor1, uFactor2, a_cBitsWidth2x); \ 1764 if (Result.s.Hi != 0 || Result.s.Lo >= RT_BIT_64(a_cBitsWidth - 1)) \ 1765 fEfl |= X86_EFL_CF | X86_EFL_OF; \ 1766 } \ 1767 else \ 1768 { \ 1769 uint ## a_cBitsWidth ## _t const uPositiveFactor2 = UINT ## a_cBitsWidth ## _C(0) - uFactor2; \ 1770 a_fnMul(Result, uFactor1, uPositiveFactor2, a_cBitsWidth2x); \ 1771 if (Result.s.Hi != 0 || Result.s.Lo > RT_BIT_64(a_cBitsWidth - 1)) \ 1772 fEfl |= X86_EFL_CF | X86_EFL_OF; \ 1773 a_fnNeg(Result, a_cBitsWidth2x); \ 1774 } \ 1775 } \ 1776 else \ 1777 { \ 1778 if (!(uFactor2 & RT_BIT_64(a_cBitsWidth - 1))) \ 1779 { \ 1780 uint ## a_cBitsWidth ## _t const uPositiveFactor1 = UINT ## a_cBitsWidth ## _C(0) - uFactor1; \ 1781 a_fnMul(Result, uPositiveFactor1, uFactor2, a_cBitsWidth2x); \ 1782 if (Result.s.Hi != 0 || Result.s.Lo > RT_BIT_64(a_cBitsWidth - 1)) \ 1783 fEfl |= X86_EFL_CF | X86_EFL_OF; \ 1784 a_fnNeg(Result, a_cBitsWidth2x); \ 1785 } \ 1786 else \ 1787 { \ 1788 uint ## a_cBitsWidth ## _t const uPositiveFactor1 = UINT ## a_cBitsWidth ## _C(0) - uFactor1; \ 1789 uint ## a_cBitsWidth ## _t const uPositiveFactor2 = UINT ## a_cBitsWidth ## _C(0) - uFactor2; \ 1790 a_fnMul(Result, uPositiveFactor1, uPositiveFactor2, a_cBitsWidth2x); \ 1791 if (Result.s.Hi != 0 || Result.s.Lo >= RT_BIT_64(a_cBitsWidth - 1)) \ 1792 fEfl |= X86_EFL_CF | X86_EFL_OF; \ 1793 } \ 1794 } \ 1795 a_fnStore(Result); \ 1796 *pfEFlags = fEfl; \ 1797 return 0; \ 1798 } 1742 } 1743 # define EMIT_IMUL(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnNeg, a_fnMul) \ 1744 EMIT_IMUL_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnNeg, a_fnMul, RT_NOTHING, 1) \ 1745 EMIT_IMUL_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnNeg, a_fnMul, _intel, 1) \ 1746 EMIT_IMUL_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnNeg, a_fnMul, _amd, 0) 1747 1799 1748 EMIT_IMUL(64, 128, (uint64_t *puA, uint64_t *puD, uint64_t uFactor2, uint32_t *pfEFlags), (puA, puD, uFactor2, pfEFlags), 1800 1749 MUL_LOAD_F1, MUL_STORE, MULDIV_NEG_U128, MULDIV_MUL_U128) … … 1842 1791 * DIV 1843 1792 */ 1844 # define EMIT_DIV(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnDivRem) \ 1845 IEM_DECL_IMPL_DEF(int, iemAImpl_div_u ## a_cBitsWidth,a_Args) \ 1793 # define EMIT_DIV_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnDivRem, \ 1794 a_Suffix, a_fIntelFlags) \ 1795 IEM_DECL_IMPL_DEF(int, RT_CONCAT3(iemAImpl_div_u,a_cBitsWidth,a_Suffix),a_Args) \ 1846 1796 { \ 1847 /* Note! Skylake leaves all flags alone. */ \1848 RT_NOREF_PV(pfEFlags); \1849 \1850 1797 RTUINT ## a_cBitsWidth2x ## U Dividend; \ 1851 1798 a_fnLoad(Dividend); \ … … 1856 1803 a_fnDivRem(Quotient, Remainder, Dividend, uDivisor); \ 1857 1804 a_fnStore(Quotient.s.Lo, Remainder.s.Lo); \ 1858 /** @todo research the undefined DIV flags. */ \ 1805 \ 1806 /* Calc EFLAGS: Intel 6700K and 10980XE leaves them alone. AMD 3990X sets AF and clears PF, ZF and SF. */ \ 1807 if (!a_fIntelFlags) \ 1808 *pfEFlags = (*pfEFlags & ~(X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF)) | X86_EFL_AF; \ 1859 1809 return 0; \ 1860 1810 } \ 1861 1811 /* #DE */ \ 1862 1812 return -1; \ 1863 } \ 1864 \ 1865 IEM_DECL_IMPL_DEF(int, iemAImpl_div_u ## a_cBitsWidth ## _intel,a_Args) \ 1866 { \ 1867 return iemAImpl_div_u ## a_cBitsWidth a_CallArgs; \ 1868 } \ 1869 \ 1870 IEM_DECL_IMPL_DEF(int, iemAImpl_div_u ## a_cBitsWidth ## _amd,a_Args) \ 1871 { \ 1872 /* Note! Skylake leaves all flags alone. */ \ 1873 RT_NOREF_PV(pfEFlags); \ 1874 \ 1875 RTUINT ## a_cBitsWidth2x ## U Dividend; \ 1876 a_fnLoad(Dividend); \ 1877 if ( uDivisor != 0 \ 1878 && Dividend.s.Hi < uDivisor) \ 1879 { \ 1880 RTUINT ## a_cBitsWidth2x ## U Remainder, Quotient; \ 1881 a_fnDivRem(Quotient, Remainder, Dividend, uDivisor); \ 1882 a_fnStore(Quotient.s.Lo, Remainder.s.Lo); \ 1883 /** @todo research the undefined DIV flags. */ \ 1884 return 0; \ 1885 } \ 1886 /* #DE */ \ 1887 return -1; \ 1888 } 1813 } 1814 # define EMIT_DIV(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnDivRem) \ 1815 EMIT_DIV_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnDivRem, RT_NOTHING, 1) \ 1816 EMIT_DIV_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnDivRem, _intel, 1) \ 1817 EMIT_DIV_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnDivRem, _amd, 0) 1818 1889 1819 EMIT_DIV(64,128,(uint64_t *puA, uint64_t *puD, uint64_t uDivisor, uint32_t *pfEFlags), (puA, puD, uDivisor, pfEFlags), 1890 1820 DIV_LOAD, DIV_STORE, MULDIV_MODDIV_U128) … … 1901 1831 /* 1902 1832 * IDIV 1903 */ 1904 # define EMIT_IDIV(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnNeg, a_fnDivRem) \ 1905 IEM_DECL_IMPL_DEF(int, iemAImpl_idiv_u ## a_cBitsWidth,a_Args) \ 1833 * 1834 * EFLAGS are ignored and left as-is by Intel 6700K and 10980XE. AMD 3990X will 1835 * set AF and clear PF, ZF and SF just like it does for DIV. 1836 * 1837 */ 1838 # define EMIT_IDIV_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnNeg, a_fnDivRem, \ 1839 a_Suffix, a_fIntelFlags) \ 1840 IEM_DECL_IMPL_DEF(int, RT_CONCAT3(iemAImpl_idiv_u,a_cBitsWidth,a_Suffix),a_Args) \ 1906 1841 { \ 1907 1842 /* Note! Skylake leaves all flags alone. */ \ 1908 RT_NOREF_PV(pfEFlags); \1909 1843 \ 1910 1844 /** @todo overflow checks */ \ … … 1940 1874 { \ 1941 1875 a_fnStore(Quotient.s.Lo, Remainder.s.Lo); \ 1876 if (!a_fIntelFlags) \ 1877 *pfEFlags = (*pfEFlags & ~(X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF)) | X86_EFL_AF; \ 1942 1878 return 0; \ 1943 1879 } \ … … 1949 1885 { \ 1950 1886 a_fnStore(UINT ## a_cBitsWidth ## _C(0) - Quotient.s.Lo, UINT ## a_cBitsWidth ## _C(0) - Remainder.s.Lo); \ 1887 if (!a_fIntelFlags) \ 1888 *pfEFlags = (*pfEFlags & ~(X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF)) | X86_EFL_AF; \ 1951 1889 return 0; \ 1952 1890 } \ … … 1961 1899 { \ 1962 1900 a_fnStore(UINT ## a_cBitsWidth ## _C(0) - Quotient.s.Lo, Remainder.s.Lo); \ 1901 if (!a_fIntelFlags) \ 1902 *pfEFlags = (*pfEFlags & ~(X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF)) | X86_EFL_AF; \ 1963 1903 return 0; \ 1964 1904 } \ … … 1970 1910 { \ 1971 1911 a_fnStore(Quotient.s.Lo, UINT ## a_cBitsWidth ## _C(0) - Remainder.s.Lo); \ 1912 if (!a_fIntelFlags) \ 1913 *pfEFlags = (*pfEFlags & ~(X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF)) | X86_EFL_AF; \ 1972 1914 return 0; \ 1973 1915 } \ … … 1977 1919 /* #DE */ \ 1978 1920 return -1; \ 1979 } \ 1980 \ 1981 IEM_DECL_IMPL_DEF(int, iemAImpl_idiv_u ## a_cBitsWidth ## _intel,a_Args) \ 1982 { \ 1983 return iemAImpl_idiv_u ## a_cBitsWidth a_CallArgs; \ 1984 } \ 1985 \ 1986 IEM_DECL_IMPL_DEF(int, iemAImpl_idiv_u ## a_cBitsWidth ## _amd,a_Args) \ 1987 { \ 1988 /* Note! Skylake leaves all flags alone. */ \ 1989 RT_NOREF_PV(pfEFlags); \ 1990 \ 1991 /** @todo overflow checks */ \ 1992 if (uDivisor != 0) \ 1993 { \ 1994 /* \ 1995 * Convert to unsigned division. \ 1996 */ \ 1997 RTUINT ## a_cBitsWidth2x ## U Dividend; \ 1998 a_fnLoad(Dividend); \ 1999 bool const fSignedDividend = RT_BOOL(Dividend.s.Hi & RT_BIT_64(a_cBitsWidth - 1)); \ 2000 if (fSignedDividend) \ 2001 a_fnNeg(Dividend, a_cBitsWidth2x); \ 2002 \ 2003 uint ## a_cBitsWidth ## _t uDivisorPositive; \ 2004 if (!(uDivisor & RT_BIT_64(a_cBitsWidth - 1))) \ 2005 uDivisorPositive = uDivisor; \ 2006 else \ 2007 uDivisorPositive = UINT ## a_cBitsWidth ## _C(0) - uDivisor; \ 2008 \ 2009 RTUINT ## a_cBitsWidth2x ## U Remainder, Quotient; \ 2010 a_fnDivRem(Quotient, Remainder, Dividend, uDivisorPositive); \ 2011 \ 2012 /* \ 2013 * Setup the result, checking for overflows. \ 2014 */ \ 2015 if (!(uDivisor & RT_BIT_64(a_cBitsWidth - 1))) \ 2016 { \ 2017 if (!fSignedDividend) \ 2018 { \ 2019 /* Positive divisor, positive dividend => result positive. */ \ 2020 if (Quotient.s.Hi == 0 && Quotient.s.Lo <= (uint ## a_cBitsWidth ## _t)INT ## a_cBitsWidth ## _MAX) \ 2021 { \ 2022 a_fnStore(Quotient.s.Lo, Remainder.s.Lo); \ 2023 return 0; \ 2024 } \ 2025 } \ 2026 else \ 2027 { \ 2028 /* Positive divisor, negative dividend => result negative. */ \ 2029 if (Quotient.s.Hi == 0 && Quotient.s.Lo <= RT_BIT_64(a_cBitsWidth - 1)) \ 2030 { \ 2031 a_fnStore(UINT ## a_cBitsWidth ## _C(0) - Quotient.s.Lo, UINT ## a_cBitsWidth ## _C(0) - Remainder.s.Lo); \ 2032 return 0; \ 2033 } \ 2034 } \ 2035 } \ 2036 else \ 2037 { \ 2038 if (!fSignedDividend) \ 2039 { \ 2040 /* Negative divisor, positive dividend => negative quotient, positive remainder. */ \ 2041 if (Quotient.s.Hi == 0 && Quotient.s.Lo <= RT_BIT_64(a_cBitsWidth - 1)) \ 2042 { \ 2043 a_fnStore(UINT ## a_cBitsWidth ## _C(0) - Quotient.s.Lo, Remainder.s.Lo); \ 2044 return 0; \ 2045 } \ 2046 } \ 2047 else \ 2048 { \ 2049 /* Negative divisor, negative dividend => positive quotient, negative remainder. */ \ 2050 if (Quotient.s.Hi == 0 && Quotient.s.Lo <= (uint ## a_cBitsWidth ## _t)INT ## a_cBitsWidth ## _MAX) \ 2051 { \ 2052 a_fnStore(Quotient.s.Lo, UINT ## a_cBitsWidth ## _C(0) - Remainder.s.Lo); \ 2053 return 0; \ 2054 } \ 2055 } \ 2056 } \ 2057 } \ 2058 /* #DE */ \ 2059 return -1; \ 2060 } 1921 } 1922 # define EMIT_IDIV(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnNeg, a_fnDivRem) \ 1923 EMIT_IDIV_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnNeg, a_fnDivRem, RT_NOTHING, 1) \ 1924 EMIT_IDIV_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnNeg, a_fnDivRem, _intel, 1) \ 1925 EMIT_IDIV_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnNeg, a_fnDivRem, _amd, 0) 2061 1926 2062 1927 EMIT_IDIV(64,128,(uint64_t *puA, uint64_t *puD, uint64_t uDivisor, uint32_t *pfEFlags), (puA, puD, uDivisor, pfEFlags), -
trunk/src/VBox/VMM/testcase/tstIEMAImpl.cpp
r94169 r94170 1556 1556 X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF), 1557 1557 ENTRY_INTEL_EX(imul_u8, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF, 0), 1558 ENTRY_AMD_EX(div_u8, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF, 1559 X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF), 1558 ENTRY_AMD_EX(div_u8, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF, 0), 1560 1559 ENTRY_INTEL_EX(div_u8, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF, 0), 1561 ENTRY_AMD_EX(idiv_u8, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF, 1562 X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF), 1560 ENTRY_AMD_EX(idiv_u8, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF, 0), 1563 1561 ENTRY_INTEL_EX(idiv_u8, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF, 0), 1564 1562 }; … … 1594 1592 for (size_t iFn = 0; iFn < RT_ELEMENTS(g_aMulDivU8); iFn++) 1595 1593 { 1596 if ( g_aMulDivU8[iFn].idxCpuEflFlavour != IEMTARGETCPU_EFL_BEHAVIOR_NATIVE1597 && g_aMulDivU8[iFn].idxCpuEflFlavour != g_idxCpuEflFlavour)1598 continue;1599 1600 1594 RTTestSub(g_hTest, g_aMulDivU8[iFn].pszName); 1601 1595 MULDIVU8_TEST_T const * const paTests = g_aMulDivU8[iFn].paTests; 1602 1596 uint32_t const cTests = g_aMulDivU8[iFn].cTests; 1603 1597 uint32_t const fEflIgn = g_aMulDivU8[iFn].uExtra; 1604 for (uint32_t iTest = 0; iTest < cTests; iTest++ ) 1598 PFNIEMAIMPLMULDIVU8 pfn = g_aMulDivU8[iFn].pfn; 1599 uint32_t const cVars = 1 + (g_aMulDivU8[iFn].idxCpuEflFlavour == g_idxCpuEflFlavour && g_aMulDivU8[iFn].pfnNative); 1600 for (uint32_t iVar = 0; iVar < cVars; iVar++) 1605 1601 { 1606 uint32_t fEfl = paTests[iTest].fEflIn; 1607 uint16_t uDst = paTests[iTest].uDstIn; 1608 int rc = g_aMulDivU8[iFn].pfn(&uDst, paTests[iTest].uSrcIn, &fEfl); 1609 if ( uDst != paTests[iTest].uDstOut 1610 || (fEfl | fEflIgn) != (paTests[iTest].fEflOut | fEflIgn) 1611 || rc != paTests[iTest].rc) 1612 RTTestFailed(g_hTest, "#%02u: efl=%#08x dst=%#06RX16 src=%#04RX8\n" 1613 " -> efl=%#08x dst=%#06RX16 rc=%d\n" 1614 "expected %#08x %#06RX16 %d%s\n", 1615 iTest, paTests[iTest].fEflIn, paTests[iTest].uDstIn, paTests[iTest].uSrcIn, 1616 fEfl, uDst, rc, paTests[iTest].fEflOut, paTests[iTest].uDstOut, paTests[iTest].rc, 1617 EFlagsDiff(fEfl | fEflIgn, paTests[iTest].fEflOut | fEflIgn)); 1618 else 1602 for (uint32_t iTest = 0; iTest < cTests; iTest++ ) 1619 1603 { 1620 *g_pu16 = paTests[iTest].uDstIn; 1621 *g_pfEfl = paTests[iTest].fEflIn; 1622 rc = g_aMulDivU8[iFn].pfn(g_pu16, paTests[iTest].uSrcIn, g_pfEfl); 1623 RTTEST_CHECK(g_hTest, *g_pu16 == paTests[iTest].uDstOut); 1624 RTTEST_CHECK(g_hTest, (*g_pfEfl | fEflIgn) == (paTests[iTest].fEflOut | fEflIgn)); 1625 RTTEST_CHECK(g_hTest, rc == paTests[iTest].rc); 1604 uint32_t fEfl = paTests[iTest].fEflIn; 1605 uint16_t uDst = paTests[iTest].uDstIn; 1606 int rc = g_aMulDivU8[iFn].pfn(&uDst, paTests[iTest].uSrcIn, &fEfl); 1607 if ( uDst != paTests[iTest].uDstOut 1608 || (fEfl | fEflIgn) != (paTests[iTest].fEflOut | fEflIgn) 1609 || rc != paTests[iTest].rc) 1610 RTTestFailed(g_hTest, "#%02u%s: efl=%#08x dst=%#06RX16 src=%#04RX8\n" 1611 " %s-> efl=%#08x dst=%#06RX16 rc=%d\n" 1612 "%sexpected %#08x %#06RX16 %d%s\n", 1613 iTest, iVar ? "/n" : "", paTests[iTest].fEflIn, paTests[iTest].uDstIn, paTests[iTest].uSrcIn, 1614 iVar ? " " : "", fEfl, uDst, rc, 1615 iVar ? " " : "", paTests[iTest].fEflOut, paTests[iTest].uDstOut, paTests[iTest].rc, 1616 EFlagsDiff(fEfl | fEflIgn, paTests[iTest].fEflOut | fEflIgn)); 1617 else 1618 { 1619 *g_pu16 = paTests[iTest].uDstIn; 1620 *g_pfEfl = paTests[iTest].fEflIn; 1621 rc = g_aMulDivU8[iFn].pfn(g_pu16, paTests[iTest].uSrcIn, g_pfEfl); 1622 RTTEST_CHECK(g_hTest, *g_pu16 == paTests[iTest].uDstOut); 1623 RTTEST_CHECK(g_hTest, (*g_pfEfl | fEflIgn) == (paTests[iTest].fEflOut | fEflIgn)); 1624 RTTEST_CHECK(g_hTest, rc == paTests[iTest].rc); 1625 } 1626 1626 } 1627 pfn = g_aMulDivU8[iFn].pfnNative; 1627 1628 } 1628 1629 } … … 1672 1673 } a_aSubTests [] = \ 1673 1674 { \ 1674 ENTRY_AMD_EX(mul_u ## a_cBits, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF, \ 1675 X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF /** @todo check out AMD flags */ ), \ 1675 ENTRY_AMD_EX(mul_u ## a_cBits, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF, 0), \ 1676 1676 ENTRY_INTEL_EX(mul_u ## a_cBits, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF, 0), \ 1677 ENTRY_AMD_EX(imul_u ## a_cBits, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF, \ 1678 X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF), \ 1677 ENTRY_AMD_EX(imul_u ## a_cBits, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF, 0), \ 1679 1678 ENTRY_INTEL_EX(imul_u ## a_cBits, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF, 0), \ 1680 ENTRY_AMD_EX(div_u ## a_cBits, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF, \ 1681 X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF), \ 1679 ENTRY_AMD_EX(div_u ## a_cBits, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF, 0), \ 1682 1680 ENTRY_INTEL_EX(div_u ## a_cBits, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF, 0), \ 1683 ENTRY_AMD_EX(idiv_u ## a_cBits, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF, \ 1684 X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF), \ 1681 ENTRY_AMD_EX(idiv_u ## a_cBits, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF, 0), \ 1685 1682 ENTRY_INTEL_EX(idiv_u ## a_cBits, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF | X86_EFL_OF, 0), \ 1686 1683 }; \
Note:
See TracChangeset
for help on using the changeset viewer.