Commit b5b38f61b8d5f4fb900472bade38e7ff610223aa
1 parent
dbd02bdf
converted more helpers to TCG
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4447 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
498 additions
and
647 deletions
target-i386/exec.h
| ... | ... | @@ -95,10 +95,6 @@ extern int loglevel; |
| 95 | 95 | #define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d) |
| 96 | 96 | #define ST1 ST(1) |
| 97 | 97 | |
| 98 | -#ifdef USE_FP_CONVERT | |
| 99 | -#define FP_CONVERT (env->fp_convert) | |
| 100 | -#endif | |
| 101 | - | |
| 102 | 98 | #include "cpu.h" |
| 103 | 99 | #include "exec-all.h" |
| 104 | 100 | |
| ... | ... | @@ -109,15 +105,13 @@ typedef struct CCTable { |
| 109 | 105 | |
| 110 | 106 | extern CCTable cc_table[]; |
| 111 | 107 | |
| 112 | -void load_seg(int seg_reg, int selector); | |
| 108 | +void helper_load_seg(int seg_reg, int selector); | |
| 113 | 109 | void helper_ljmp_protected_T0_T1(int next_eip); |
| 114 | 110 | void helper_lcall_real_T0_T1(int shift, int next_eip); |
| 115 | 111 | void helper_lcall_protected_T0_T1(int shift, int next_eip); |
| 116 | 112 | void helper_iret_real(int shift); |
| 117 | 113 | void helper_iret_protected(int shift, int next_eip); |
| 118 | 114 | void helper_lret_protected(int shift, int addend); |
| 119 | -void helper_lldt_T0(void); | |
| 120 | -void helper_ltr_T0(void); | |
| 121 | 115 | void helper_movl_crN_T0(int reg); |
| 122 | 116 | void helper_movl_drN_T0(int reg); |
| 123 | 117 | void helper_invlpg(target_ulong addr); |
| ... | ... | @@ -150,27 +144,7 @@ void OPPROTO op_movl_T0_eflags(void); |
| 150 | 144 | void helper_mulq_EAX_T0(void); |
| 151 | 145 | void helper_imulq_EAX_T0(void); |
| 152 | 146 | void helper_imulq_T0_T1(void); |
| 153 | -void helper_divq_EAX_T0(void); | |
| 154 | -void helper_idivq_EAX_T0(void); | |
| 155 | -void helper_bswapq_T0(void); | |
| 156 | 147 | void helper_cmpxchg8b(void); |
| 157 | -void helper_single_step(void); | |
| 158 | -void helper_cpuid(void); | |
| 159 | -void helper_enter_level(int level, int data32); | |
| 160 | -void helper_enter64_level(int level, int data64); | |
| 161 | -void helper_sysenter(void); | |
| 162 | -void helper_sysexit(void); | |
| 163 | -void helper_syscall(int next_eip_addend); | |
| 164 | -void helper_sysret(int dflag); | |
| 165 | -void helper_rdtsc(void); | |
| 166 | -void helper_rdpmc(void); | |
| 167 | -void helper_rdmsr(void); | |
| 168 | -void helper_wrmsr(void); | |
| 169 | -void helper_lsl(void); | |
| 170 | -void helper_lar(void); | |
| 171 | -void helper_verr(void); | |
| 172 | -void helper_verw(void); | |
| 173 | -void helper_rsm(void); | |
| 174 | 148 | |
| 175 | 149 | void check_iob_T0(void); |
| 176 | 150 | void check_iow_T0(void); |
| ... | ... | @@ -183,46 +157,6 @@ void check_iol_DX(void); |
| 183 | 157 | |
| 184 | 158 | #include "softmmu_exec.h" |
| 185 | 159 | |
| 186 | -static inline double ldfq(target_ulong ptr) | |
| 187 | -{ | |
| 188 | - union { | |
| 189 | - double d; | |
| 190 | - uint64_t i; | |
| 191 | - } u; | |
| 192 | - u.i = ldq(ptr); | |
| 193 | - return u.d; | |
| 194 | -} | |
| 195 | - | |
| 196 | -static inline void stfq(target_ulong ptr, double v) | |
| 197 | -{ | |
| 198 | - union { | |
| 199 | - double d; | |
| 200 | - uint64_t i; | |
| 201 | - } u; | |
| 202 | - u.d = v; | |
| 203 | - stq(ptr, u.i); | |
| 204 | -} | |
| 205 | - | |
| 206 | -static inline float ldfl(target_ulong ptr) | |
| 207 | -{ | |
| 208 | - union { | |
| 209 | - float f; | |
| 210 | - uint32_t i; | |
| 211 | - } u; | |
| 212 | - u.i = ldl(ptr); | |
| 213 | - return u.f; | |
| 214 | -} | |
| 215 | - | |
| 216 | -static inline void stfl(target_ulong ptr, float v) | |
| 217 | -{ | |
| 218 | - union { | |
| 219 | - float f; | |
| 220 | - uint32_t i; | |
| 221 | - } u; | |
| 222 | - u.f = v; | |
| 223 | - stl(ptr, u.i); | |
| 224 | -} | |
| 225 | - | |
| 226 | 160 | #endif /* !defined(CONFIG_USER_ONLY) */ |
| 227 | 161 | |
| 228 | 162 | #ifdef USE_X86LDOUBLE |
| ... | ... | @@ -429,20 +363,6 @@ extern const CPU86_LDouble f15rk[7]; |
| 429 | 363 | void fpu_raise_exception(void); |
| 430 | 364 | void restore_native_fp_state(CPUState *env); |
| 431 | 365 | void save_native_fp_state(CPUState *env); |
| 432 | -float approx_rsqrt(float a); | |
| 433 | -float approx_rcp(float a); | |
| 434 | -void update_fp_status(void); | |
| 435 | -void helper_hlt(void); | |
| 436 | -void helper_monitor(void); | |
| 437 | -void helper_mwait(void); | |
| 438 | -void helper_vmrun(target_ulong addr); | |
| 439 | -void helper_vmmcall(void); | |
| 440 | -void helper_vmload(target_ulong addr); | |
| 441 | -void helper_vmsave(target_ulong addr); | |
| 442 | -void helper_stgi(void); | |
| 443 | -void helper_clgi(void); | |
| 444 | -void helper_skinit(void); | |
| 445 | -void helper_invlpga(void); | |
| 446 | 366 | void vmexit(uint64_t exit_code, uint64_t exit_info_1); |
| 447 | 367 | |
| 448 | 368 | extern const uint8_t parity_table[256]; | ... | ... |
target-i386/helper.c
| ... | ... | @@ -1609,7 +1609,79 @@ int32_t idiv32(int64_t *q_ptr, int64_t num, int32_t den) |
| 1609 | 1609 | } |
| 1610 | 1610 | #endif |
| 1611 | 1611 | |
| 1612 | -void helper_divl_EAX_T0(target_ulong t0) | |
| 1612 | +/* division, flags are undefined */ | |
| 1613 | + | |
| 1614 | +void helper_divb_AL(target_ulong t0) | |
| 1615 | +{ | |
| 1616 | + unsigned int num, den, q, r; | |
| 1617 | + | |
| 1618 | + num = (EAX & 0xffff); | |
| 1619 | + den = (t0 & 0xff); | |
| 1620 | + if (den == 0) { | |
| 1621 | + raise_exception(EXCP00_DIVZ); | |
| 1622 | + } | |
| 1623 | + q = (num / den); | |
| 1624 | + if (q > 0xff) | |
| 1625 | + raise_exception(EXCP00_DIVZ); | |
| 1626 | + q &= 0xff; | |
| 1627 | + r = (num % den) & 0xff; | |
| 1628 | + EAX = (EAX & ~0xffff) | (r << 8) | q; | |
| 1629 | +} | |
| 1630 | + | |
| 1631 | +void helper_idivb_AL(target_ulong t0) | |
| 1632 | +{ | |
| 1633 | + int num, den, q, r; | |
| 1634 | + | |
| 1635 | + num = (int16_t)EAX; | |
| 1636 | + den = (int8_t)t0; | |
| 1637 | + if (den == 0) { | |
| 1638 | + raise_exception(EXCP00_DIVZ); | |
| 1639 | + } | |
| 1640 | + q = (num / den); | |
| 1641 | + if (q != (int8_t)q) | |
| 1642 | + raise_exception(EXCP00_DIVZ); | |
| 1643 | + q &= 0xff; | |
| 1644 | + r = (num % den) & 0xff; | |
| 1645 | + EAX = (EAX & ~0xffff) | (r << 8) | q; | |
| 1646 | +} | |
| 1647 | + | |
| 1648 | +void helper_divw_AX(target_ulong t0) | |
| 1649 | +{ | |
| 1650 | + unsigned int num, den, q, r; | |
| 1651 | + | |
| 1652 | + num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); | |
| 1653 | + den = (t0 & 0xffff); | |
| 1654 | + if (den == 0) { | |
| 1655 | + raise_exception(EXCP00_DIVZ); | |
| 1656 | + } | |
| 1657 | + q = (num / den); | |
| 1658 | + if (q > 0xffff) | |
| 1659 | + raise_exception(EXCP00_DIVZ); | |
| 1660 | + q &= 0xffff; | |
| 1661 | + r = (num % den) & 0xffff; | |
| 1662 | + EAX = (EAX & ~0xffff) | q; | |
| 1663 | + EDX = (EDX & ~0xffff) | r; | |
| 1664 | +} | |
| 1665 | + | |
| 1666 | +void helper_idivw_AX(target_ulong t0) | |
| 1667 | +{ | |
| 1668 | + int num, den, q, r; | |
| 1669 | + | |
| 1670 | + num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); | |
| 1671 | + den = (int16_t)t0; | |
| 1672 | + if (den == 0) { | |
| 1673 | + raise_exception(EXCP00_DIVZ); | |
| 1674 | + } | |
| 1675 | + q = (num / den); | |
| 1676 | + if (q != (int16_t)q) | |
| 1677 | + raise_exception(EXCP00_DIVZ); | |
| 1678 | + q &= 0xffff; | |
| 1679 | + r = (num % den) & 0xffff; | |
| 1680 | + EAX = (EAX & ~0xffff) | q; | |
| 1681 | + EDX = (EDX & ~0xffff) | r; | |
| 1682 | +} | |
| 1683 | + | |
| 1684 | +void helper_divl_EAX(target_ulong t0) | |
| 1613 | 1685 | { |
| 1614 | 1686 | unsigned int den, r; |
| 1615 | 1687 | uint64_t num, q; |
| ... | ... | @@ -1631,7 +1703,7 @@ void helper_divl_EAX_T0(target_ulong t0) |
| 1631 | 1703 | EDX = (uint32_t)r; |
| 1632 | 1704 | } |
| 1633 | 1705 | |
| 1634 | -void helper_idivl_EAX_T0(target_ulong t0) | |
| 1706 | +void helper_idivl_EAX(target_ulong t0) | |
| 1635 | 1707 | { |
| 1636 | 1708 | int den, r; |
| 1637 | 1709 | int64_t num, q; |
| ... | ... | @@ -1653,6 +1725,138 @@ void helper_idivl_EAX_T0(target_ulong t0) |
| 1653 | 1725 | EDX = (uint32_t)r; |
| 1654 | 1726 | } |
| 1655 | 1727 | |
| 1728 | +/* bcd */ | |
| 1729 | + | |
| 1730 | +/* XXX: exception */ | |
| 1731 | +void helper_aam(int base) | |
| 1732 | +{ | |
| 1733 | + int al, ah; | |
| 1734 | + al = EAX & 0xff; | |
| 1735 | + ah = al / base; | |
| 1736 | + al = al % base; | |
| 1737 | + EAX = (EAX & ~0xffff) | al | (ah << 8); | |
| 1738 | + CC_DST = al; | |
| 1739 | +} | |
| 1740 | + | |
| 1741 | +void helper_aad(int base) | |
| 1742 | +{ | |
| 1743 | + int al, ah; | |
| 1744 | + al = EAX & 0xff; | |
| 1745 | + ah = (EAX >> 8) & 0xff; | |
| 1746 | + al = ((ah * base) + al) & 0xff; | |
| 1747 | + EAX = (EAX & ~0xffff) | al; | |
| 1748 | + CC_DST = al; | |
| 1749 | +} | |
| 1750 | + | |
| 1751 | +void helper_aaa(void) | |
| 1752 | +{ | |
| 1753 | + int icarry; | |
| 1754 | + int al, ah, af; | |
| 1755 | + int eflags; | |
| 1756 | + | |
| 1757 | + eflags = cc_table[CC_OP].compute_all(); | |
| 1758 | + af = eflags & CC_A; | |
| 1759 | + al = EAX & 0xff; | |
| 1760 | + ah = (EAX >> 8) & 0xff; | |
| 1761 | + | |
| 1762 | + icarry = (al > 0xf9); | |
| 1763 | + if (((al & 0x0f) > 9 ) || af) { | |
| 1764 | + al = (al + 6) & 0x0f; | |
| 1765 | + ah = (ah + 1 + icarry) & 0xff; | |
| 1766 | + eflags |= CC_C | CC_A; | |
| 1767 | + } else { | |
| 1768 | + eflags &= ~(CC_C | CC_A); | |
| 1769 | + al &= 0x0f; | |
| 1770 | + } | |
| 1771 | + EAX = (EAX & ~0xffff) | al | (ah << 8); | |
| 1772 | + CC_SRC = eflags; | |
| 1773 | + FORCE_RET(); | |
| 1774 | +} | |
| 1775 | + | |
| 1776 | +void helper_aas(void) | |
| 1777 | +{ | |
| 1778 | + int icarry; | |
| 1779 | + int al, ah, af; | |
| 1780 | + int eflags; | |
| 1781 | + | |
| 1782 | + eflags = cc_table[CC_OP].compute_all(); | |
| 1783 | + af = eflags & CC_A; | |
| 1784 | + al = EAX & 0xff; | |
| 1785 | + ah = (EAX >> 8) & 0xff; | |
| 1786 | + | |
| 1787 | + icarry = (al < 6); | |
| 1788 | + if (((al & 0x0f) > 9 ) || af) { | |
| 1789 | + al = (al - 6) & 0x0f; | |
| 1790 | + ah = (ah - 1 - icarry) & 0xff; | |
| 1791 | + eflags |= CC_C | CC_A; | |
| 1792 | + } else { | |
| 1793 | + eflags &= ~(CC_C | CC_A); | |
| 1794 | + al &= 0x0f; | |
| 1795 | + } | |
| 1796 | + EAX = (EAX & ~0xffff) | al | (ah << 8); | |
| 1797 | + CC_SRC = eflags; | |
| 1798 | + FORCE_RET(); | |
| 1799 | +} | |
| 1800 | + | |
| 1801 | +void helper_daa(void) | |
| 1802 | +{ | |
| 1803 | + int al, af, cf; | |
| 1804 | + int eflags; | |
| 1805 | + | |
| 1806 | + eflags = cc_table[CC_OP].compute_all(); | |
| 1807 | + cf = eflags & CC_C; | |
| 1808 | + af = eflags & CC_A; | |
| 1809 | + al = EAX & 0xff; | |
| 1810 | + | |
| 1811 | + eflags = 0; | |
| 1812 | + if (((al & 0x0f) > 9 ) || af) { | |
| 1813 | + al = (al + 6) & 0xff; | |
| 1814 | + eflags |= CC_A; | |
| 1815 | + } | |
| 1816 | + if ((al > 0x9f) || cf) { | |
| 1817 | + al = (al + 0x60) & 0xff; | |
| 1818 | + eflags |= CC_C; | |
| 1819 | + } | |
| 1820 | + EAX = (EAX & ~0xff) | al; | |
| 1821 | + /* well, speed is not an issue here, so we compute the flags by hand */ | |
| 1822 | + eflags |= (al == 0) << 6; /* zf */ | |
| 1823 | + eflags |= parity_table[al]; /* pf */ | |
| 1824 | + eflags |= (al & 0x80); /* sf */ | |
| 1825 | + CC_SRC = eflags; | |
| 1826 | + FORCE_RET(); | |
| 1827 | +} | |
| 1828 | + | |
| 1829 | +void helper_das(void) | |
| 1830 | +{ | |
| 1831 | + int al, al1, af, cf; | |
| 1832 | + int eflags; | |
| 1833 | + | |
| 1834 | + eflags = cc_table[CC_OP].compute_all(); | |
| 1835 | + cf = eflags & CC_C; | |
| 1836 | + af = eflags & CC_A; | |
| 1837 | + al = EAX & 0xff; | |
| 1838 | + | |
| 1839 | + eflags = 0; | |
| 1840 | + al1 = al; | |
| 1841 | + if (((al & 0x0f) > 9 ) || af) { | |
| 1842 | + eflags |= CC_A; | |
| 1843 | + if (al < 6 || cf) | |
| 1844 | + eflags |= CC_C; | |
| 1845 | + al = (al - 6) & 0xff; | |
| 1846 | + } | |
| 1847 | + if ((al1 > 0x99) || cf) { | |
| 1848 | + al = (al - 0x60) & 0xff; | |
| 1849 | + eflags |= CC_C; | |
| 1850 | + } | |
| 1851 | + EAX = (EAX & ~0xff) | al; | |
| 1852 | + /* well, speed is not an issue here, so we compute the flags by hand */ | |
| 1853 | + eflags |= (al == 0) << 6; /* zf */ | |
| 1854 | + eflags |= parity_table[al]; /* pf */ | |
| 1855 | + eflags |= (al & 0x80); /* sf */ | |
| 1856 | + CC_SRC = eflags; | |
| 1857 | + FORCE_RET(); | |
| 1858 | +} | |
| 1859 | + | |
| 1656 | 1860 | void helper_cmpxchg8b(void) |
| 1657 | 1861 | { |
| 1658 | 1862 | uint64_t d; |
| ... | ... | @@ -1845,15 +2049,14 @@ void helper_enter64_level(int level, int data64) |
| 1845 | 2049 | } |
| 1846 | 2050 | #endif |
| 1847 | 2051 | |
| 1848 | -void helper_lldt_T0(void) | |
| 2052 | +void helper_lldt(int selector) | |
| 1849 | 2053 | { |
| 1850 | - int selector; | |
| 1851 | 2054 | SegmentCache *dt; |
| 1852 | 2055 | uint32_t e1, e2; |
| 1853 | 2056 | int index, entry_limit; |
| 1854 | 2057 | target_ulong ptr; |
| 1855 | 2058 | |
| 1856 | - selector = T0 & 0xffff; | |
| 2059 | + selector &= 0xffff; | |
| 1857 | 2060 | if ((selector & 0xfffc) == 0) { |
| 1858 | 2061 | /* XXX: NULL selector case: invalid LDT */ |
| 1859 | 2062 | env->ldt.base = 0; |
| ... | ... | @@ -1893,15 +2096,14 @@ void helper_lldt_T0(void) |
| 1893 | 2096 | env->ldt.selector = selector; |
| 1894 | 2097 | } |
| 1895 | 2098 | |
| 1896 | -void helper_ltr_T0(void) | |
| 2099 | +void helper_ltr(int selector) | |
| 1897 | 2100 | { |
| 1898 | - int selector; | |
| 1899 | 2101 | SegmentCache *dt; |
| 1900 | 2102 | uint32_t e1, e2; |
| 1901 | 2103 | int index, type, entry_limit; |
| 1902 | 2104 | target_ulong ptr; |
| 1903 | 2105 | |
| 1904 | - selector = T0 & 0xffff; | |
| 2106 | + selector &= 0xffff; | |
| 1905 | 2107 | if ((selector & 0xfffc) == 0) { |
| 1906 | 2108 | /* NULL selector case: invalid TR */ |
| 1907 | 2109 | env->tr.base = 0; |
| ... | ... | @@ -1950,7 +2152,7 @@ void helper_ltr_T0(void) |
| 1950 | 2152 | } |
| 1951 | 2153 | |
| 1952 | 2154 | /* only works if protected mode and not VM86. seg_reg must be != R_CS */ |
| 1953 | -void load_seg(int seg_reg, int selector) | |
| 2155 | +void helper_load_seg(int seg_reg, int selector) | |
| 1954 | 2156 | { |
| 1955 | 2157 | uint32_t e1, e2; |
| 1956 | 2158 | int cpl, dpl, rpl; |
| ... | ... | @@ -2916,14 +3118,14 @@ void helper_rdmsr(void) |
| 2916 | 3118 | } |
| 2917 | 3119 | #endif |
| 2918 | 3120 | |
| 2919 | -void helper_lsl(void) | |
| 3121 | +void helper_lsl(uint32_t selector) | |
| 2920 | 3122 | { |
| 2921 | - unsigned int selector, limit; | |
| 3123 | + unsigned int limit; | |
| 2922 | 3124 | uint32_t e1, e2, eflags; |
| 2923 | 3125 | int rpl, dpl, cpl, type; |
| 2924 | 3126 | |
| 3127 | + selector &= 0xffff; | |
| 2925 | 3128 | eflags = cc_table[CC_OP].compute_all(); |
| 2926 | - selector = T0 & 0xffff; | |
| 2927 | 3129 | if (load_segment(&e1, &e2, selector) != 0) |
| 2928 | 3130 | goto fail; |
| 2929 | 3131 | rpl = selector & 3; |
| ... | ... | @@ -2959,14 +3161,13 @@ void helper_lsl(void) |
| 2959 | 3161 | CC_SRC = eflags | CC_Z; |
| 2960 | 3162 | } |
| 2961 | 3163 | |
| 2962 | -void helper_lar(void) | |
| 3164 | +void helper_lar(uint32_t selector) | |
| 2963 | 3165 | { |
| 2964 | - unsigned int selector; | |
| 2965 | 3166 | uint32_t e1, e2, eflags; |
| 2966 | 3167 | int rpl, dpl, cpl, type; |
| 2967 | 3168 | |
| 3169 | + selector &= 0xffff; | |
| 2968 | 3170 | eflags = cc_table[CC_OP].compute_all(); |
| 2969 | - selector = T0 & 0xffff; | |
| 2970 | 3171 | if ((selector & 0xfffc) == 0) |
| 2971 | 3172 | goto fail; |
| 2972 | 3173 | if (load_segment(&e1, &e2, selector) != 0) |
| ... | ... | @@ -3006,14 +3207,13 @@ void helper_lar(void) |
| 3006 | 3207 | CC_SRC = eflags | CC_Z; |
| 3007 | 3208 | } |
| 3008 | 3209 | |
| 3009 | -void helper_verr(void) | |
| 3210 | +void helper_verr(uint32_t selector) | |
| 3010 | 3211 | { |
| 3011 | - unsigned int selector; | |
| 3012 | 3212 | uint32_t e1, e2, eflags; |
| 3013 | 3213 | int rpl, dpl, cpl; |
| 3014 | 3214 | |
| 3215 | + selector &= 0xffff; | |
| 3015 | 3216 | eflags = cc_table[CC_OP].compute_all(); |
| 3016 | - selector = T0 & 0xffff; | |
| 3017 | 3217 | if ((selector & 0xfffc) == 0) |
| 3018 | 3218 | goto fail; |
| 3019 | 3219 | if (load_segment(&e1, &e2, selector) != 0) |
| ... | ... | @@ -3040,14 +3240,13 @@ void helper_verr(void) |
| 3040 | 3240 | CC_SRC = eflags | CC_Z; |
| 3041 | 3241 | } |
| 3042 | 3242 | |
| 3043 | -void helper_verw(void) | |
| 3243 | +void helper_verw(uint32_t selector) | |
| 3044 | 3244 | { |
| 3045 | - unsigned int selector; | |
| 3046 | 3245 | uint32_t e1, e2, eflags; |
| 3047 | 3246 | int rpl, dpl, cpl; |
| 3048 | 3247 | |
| 3248 | + selector &= 0xffff; | |
| 3049 | 3249 | eflags = cc_table[CC_OP].compute_all(); |
| 3050 | - selector = T0 & 0xffff; | |
| 3051 | 3250 | if ((selector & 0xfffc) == 0) |
| 3052 | 3251 | goto fail; |
| 3053 | 3252 | if (load_segment(&e1, &e2, selector) != 0) |
| ... | ... | @@ -3484,6 +3683,44 @@ uint32_t helper_fnstcw(void) |
| 3484 | 3683 | return env->fpuc; |
| 3485 | 3684 | } |
| 3486 | 3685 | |
| 3686 | +static void update_fp_status(void) | |
| 3687 | +{ | |
| 3688 | + int rnd_type; | |
| 3689 | + | |
| 3690 | + /* set rounding mode */ | |
| 3691 | + switch(env->fpuc & RC_MASK) { | |
| 3692 | + default: | |
| 3693 | + case RC_NEAR: | |
| 3694 | + rnd_type = float_round_nearest_even; | |
| 3695 | + break; | |
| 3696 | + case RC_DOWN: | |
| 3697 | + rnd_type = float_round_down; | |
| 3698 | + break; | |
| 3699 | + case RC_UP: | |
| 3700 | + rnd_type = float_round_up; | |
| 3701 | + break; | |
| 3702 | + case RC_CHOP: | |
| 3703 | + rnd_type = float_round_to_zero; | |
| 3704 | + break; | |
| 3705 | + } | |
| 3706 | + set_float_rounding_mode(rnd_type, &env->fp_status); | |
| 3707 | +#ifdef FLOATX80 | |
| 3708 | + switch((env->fpuc >> 8) & 3) { | |
| 3709 | + case 0: | |
| 3710 | + rnd_type = 32; | |
| 3711 | + break; | |
| 3712 | + case 2: | |
| 3713 | + rnd_type = 64; | |
| 3714 | + break; | |
| 3715 | + case 3: | |
| 3716 | + default: | |
| 3717 | + rnd_type = 80; | |
| 3718 | + break; | |
| 3719 | + } | |
| 3720 | + set_floatx80_rounding_precision(rnd_type, &env->fp_status); | |
| 3721 | +#endif | |
| 3722 | +} | |
| 3723 | + | |
| 3487 | 3724 | void helper_fldcw(uint32_t val) |
| 3488 | 3725 | { |
| 3489 | 3726 | env->fpuc = val; |
| ... | ... | @@ -4207,38 +4444,33 @@ void helper_imulq_T0_T1(void) |
| 4207 | 4444 | CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63)); |
| 4208 | 4445 | } |
| 4209 | 4446 | |
| 4210 | -void helper_divq_EAX_T0(void) | |
| 4447 | +void helper_divq_EAX(target_ulong t0) | |
| 4211 | 4448 | { |
| 4212 | 4449 | uint64_t r0, r1; |
| 4213 | - if (T0 == 0) { | |
| 4450 | + if (t0 == 0) { | |
| 4214 | 4451 | raise_exception(EXCP00_DIVZ); |
| 4215 | 4452 | } |
| 4216 | 4453 | r0 = EAX; |
| 4217 | 4454 | r1 = EDX; |
| 4218 | - if (div64(&r0, &r1, T0)) | |
| 4455 | + if (div64(&r0, &r1, t0)) | |
| 4219 | 4456 | raise_exception(EXCP00_DIVZ); |
| 4220 | 4457 | EAX = r0; |
| 4221 | 4458 | EDX = r1; |
| 4222 | 4459 | } |
| 4223 | 4460 | |
| 4224 | -void helper_idivq_EAX_T0(void) | |
| 4461 | +void helper_idivq_EAX(target_ulong t0) | |
| 4225 | 4462 | { |
| 4226 | 4463 | uint64_t r0, r1; |
| 4227 | - if (T0 == 0) { | |
| 4464 | + if (t0 == 0) { | |
| 4228 | 4465 | raise_exception(EXCP00_DIVZ); |
| 4229 | 4466 | } |
| 4230 | 4467 | r0 = EAX; |
| 4231 | 4468 | r1 = EDX; |
| 4232 | - if (idiv64(&r0, &r1, T0)) | |
| 4469 | + if (idiv64(&r0, &r1, t0)) | |
| 4233 | 4470 | raise_exception(EXCP00_DIVZ); |
| 4234 | 4471 | EAX = r0; |
| 4235 | 4472 | EDX = r1; |
| 4236 | 4473 | } |
| 4237 | - | |
| 4238 | -void helper_bswapq_T0(void) | |
| 4239 | -{ | |
| 4240 | - T0 = bswap64(T0); | |
| 4241 | -} | |
| 4242 | 4474 | #endif |
| 4243 | 4475 | |
| 4244 | 4476 | void helper_hlt(void) |
| ... | ... | @@ -4249,7 +4481,7 @@ void helper_hlt(void) |
| 4249 | 4481 | cpu_loop_exit(); |
| 4250 | 4482 | } |
| 4251 | 4483 | |
| 4252 | -void helper_monitor(void) | |
| 4484 | +void helper_monitor(target_ulong ptr) | |
| 4253 | 4485 | { |
| 4254 | 4486 | if ((uint32_t)ECX != 0) |
| 4255 | 4487 | raise_exception(EXCP0D_GPF); |
| ... | ... | @@ -4269,52 +4501,90 @@ void helper_mwait(void) |
| 4269 | 4501 | } |
| 4270 | 4502 | } |
| 4271 | 4503 | |
| 4272 | -float approx_rsqrt(float a) | |
| 4504 | +void helper_debug(void) | |
| 4273 | 4505 | { |
| 4274 | - return 1.0 / sqrt(a); | |
| 4506 | + env->exception_index = EXCP_DEBUG; | |
| 4507 | + cpu_loop_exit(); | |
| 4275 | 4508 | } |
| 4276 | 4509 | |
| 4277 | -float approx_rcp(float a) | |
| 4510 | +void helper_raise_interrupt(int intno, int next_eip_addend) | |
| 4278 | 4511 | { |
| 4279 | - return 1.0 / a; | |
| 4512 | + raise_interrupt(intno, 1, 0, next_eip_addend); | |
| 4280 | 4513 | } |
| 4281 | 4514 | |
| 4282 | -void update_fp_status(void) | |
| 4515 | +void helper_raise_exception(int exception_index) | |
| 4283 | 4516 | { |
| 4284 | - int rnd_type; | |
| 4517 | + raise_exception(exception_index); | |
| 4518 | +} | |
| 4285 | 4519 | |
| 4286 | - /* set rounding mode */ | |
| 4287 | - switch(env->fpuc & RC_MASK) { | |
| 4288 | - default: | |
| 4289 | - case RC_NEAR: | |
| 4290 | - rnd_type = float_round_nearest_even; | |
| 4291 | - break; | |
| 4292 | - case RC_DOWN: | |
| 4293 | - rnd_type = float_round_down; | |
| 4294 | - break; | |
| 4295 | - case RC_UP: | |
| 4296 | - rnd_type = float_round_up; | |
| 4297 | - break; | |
| 4298 | - case RC_CHOP: | |
| 4299 | - rnd_type = float_round_to_zero; | |
| 4300 | - break; | |
| 4301 | - } | |
| 4302 | - set_float_rounding_mode(rnd_type, &env->fp_status); | |
| 4303 | -#ifdef FLOATX80 | |
| 4304 | - switch((env->fpuc >> 8) & 3) { | |
| 4305 | - case 0: | |
| 4306 | - rnd_type = 32; | |
| 4307 | - break; | |
| 4308 | - case 2: | |
| 4309 | - rnd_type = 64; | |
| 4310 | - break; | |
| 4311 | - case 3: | |
| 4312 | - default: | |
| 4313 | - rnd_type = 80; | |
| 4314 | - break; | |
| 4520 | +void helper_cli(void) | |
| 4521 | +{ | |
| 4522 | + env->eflags &= ~IF_MASK; | |
| 4523 | +} | |
| 4524 | + | |
| 4525 | +void helper_sti(void) | |
| 4526 | +{ | |
| 4527 | + env->eflags |= IF_MASK; | |
| 4528 | +} | |
| 4529 | + | |
| 4530 | +#if 0 | |
| 4531 | +/* vm86plus instructions */ | |
| 4532 | +void helper_cli_vm(void) | |
| 4533 | +{ | |
| 4534 | + env->eflags &= ~VIF_MASK; | |
| 4535 | +} | |
| 4536 | + | |
| 4537 | +void helper_sti_vm(void) | |
| 4538 | +{ | |
| 4539 | + env->eflags |= VIF_MASK; | |
| 4540 | + if (env->eflags & VIP_MASK) { | |
| 4541 | + raise_exception(EXCP0D_GPF); | |
| 4315 | 4542 | } |
| 4316 | - set_floatx80_rounding_precision(rnd_type, &env->fp_status); | |
| 4543 | +} | |
| 4317 | 4544 | #endif |
| 4545 | + | |
| 4546 | +void helper_set_inhibit_irq(void) | |
| 4547 | +{ | |
| 4548 | + env->hflags |= HF_INHIBIT_IRQ_MASK; | |
| 4549 | +} | |
| 4550 | + | |
| 4551 | +void helper_reset_inhibit_irq(void) | |
| 4552 | +{ | |
| 4553 | + env->hflags &= ~HF_INHIBIT_IRQ_MASK; | |
| 4554 | +} | |
| 4555 | + | |
| 4556 | +void helper_boundw(void) | |
| 4557 | +{ | |
| 4558 | + int low, high, v; | |
| 4559 | + low = ldsw(A0); | |
| 4560 | + high = ldsw(A0 + 2); | |
| 4561 | + v = (int16_t)T0; | |
| 4562 | + if (v < low || v > high) { | |
| 4563 | + raise_exception(EXCP05_BOUND); | |
| 4564 | + } | |
| 4565 | + FORCE_RET(); | |
| 4566 | +} | |
| 4567 | + | |
| 4568 | +void helper_boundl(void) | |
| 4569 | +{ | |
| 4570 | + int low, high, v; | |
| 4571 | + low = ldl(A0); | |
| 4572 | + high = ldl(A0 + 4); | |
| 4573 | + v = T0; | |
| 4574 | + if (v < low || v > high) { | |
| 4575 | + raise_exception(EXCP05_BOUND); | |
| 4576 | + } | |
| 4577 | + FORCE_RET(); | |
| 4578 | +} | |
| 4579 | + | |
| 4580 | +static float approx_rsqrt(float a) | |
| 4581 | +{ | |
| 4582 | + return 1.0 / sqrt(a); | |
| 4583 | +} | |
| 4584 | + | |
| 4585 | +static float approx_rcp(float a) | |
| 4586 | +{ | |
| 4587 | + return 1.0 / a; | |
| 4318 | 4588 | } |
| 4319 | 4589 | |
| 4320 | 4590 | #if !defined(CONFIG_USER_ONLY) |
| ... | ... | @@ -4391,10 +4661,10 @@ void helper_clgi(void) |
| 4391 | 4661 | |
| 4392 | 4662 | #if defined(CONFIG_USER_ONLY) |
| 4393 | 4663 | |
| 4394 | -void helper_vmrun(target_ulong addr) { } | |
| 4664 | +void helper_vmrun(void) { } | |
| 4395 | 4665 | void helper_vmmcall(void) { } |
| 4396 | -void helper_vmload(target_ulong addr) { } | |
| 4397 | -void helper_vmsave(target_ulong addr) { } | |
| 4666 | +void helper_vmload(void) { } | |
| 4667 | +void helper_vmsave(void) { } | |
| 4398 | 4668 | void helper_skinit(void) { } |
| 4399 | 4669 | void helper_invlpga(void) { } |
| 4400 | 4670 | void vmexit(uint64_t exit_code, uint64_t exit_info_1) { } |
| ... | ... | @@ -4421,11 +4691,13 @@ static inline uint16_t cpu2vmcb_attrib(uint32_t cpu_attrib) |
| 4421 | 4691 | | ((cpu_attrib & 0xf00000) >> 12); /* AVL, L, DB, G */ |
| 4422 | 4692 | } |
| 4423 | 4693 | |
| 4424 | -void helper_vmrun(target_ulong addr) | |
| 4694 | +void helper_vmrun(void) | |
| 4425 | 4695 | { |
| 4696 | + target_ulong addr; | |
| 4426 | 4697 | uint32_t event_inj; |
| 4427 | 4698 | uint32_t int_ctl; |
| 4428 | 4699 | |
| 4700 | + addr = EAX; | |
| 4429 | 4701 | if (loglevel & CPU_LOG_TB_IN_ASM) |
| 4430 | 4702 | fprintf(logfile,"vmrun! " TARGET_FMT_lx "\n", addr); |
| 4431 | 4703 | |
| ... | ... | @@ -4592,8 +4864,10 @@ void helper_vmmcall(void) |
| 4592 | 4864 | fprintf(logfile,"vmmcall!\n"); |
| 4593 | 4865 | } |
| 4594 | 4866 | |
| 4595 | -void helper_vmload(target_ulong addr) | |
| 4867 | +void helper_vmload(void) | |
| 4596 | 4868 | { |
| 4869 | + target_ulong addr; | |
| 4870 | + addr = EAX; | |
| 4597 | 4871 | if (loglevel & CPU_LOG_TB_IN_ASM) |
| 4598 | 4872 | fprintf(logfile,"vmload! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n", |
| 4599 | 4873 | addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)), |
| ... | ... | @@ -4616,8 +4890,10 @@ void helper_vmload(target_ulong addr) |
| 4616 | 4890 | env->sysenter_eip = ldq_phys(addr + offsetof(struct vmcb, save.sysenter_eip)); |
| 4617 | 4891 | } |
| 4618 | 4892 | |
| 4619 | -void helper_vmsave(target_ulong addr) | |
| 4893 | +void helper_vmsave(void) | |
| 4620 | 4894 | { |
| 4895 | + target_ulong addr; | |
| 4896 | + addr = EAX; | |
| 4621 | 4897 | if (loglevel & CPU_LOG_TB_IN_ASM) |
| 4622 | 4898 | fprintf(logfile,"vmsave! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n", |
| 4623 | 4899 | addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)), | ... | ... |
target-i386/helper.h
| 1 | 1 | #define TCG_HELPER_PROTO |
| 2 | 2 | |
| 3 | -void TCG_HELPER_PROTO helper_divl_EAX_T0(target_ulong t0); | |
| 4 | -void TCG_HELPER_PROTO helper_idivl_EAX_T0(target_ulong t0); | |
| 3 | +void helper_divb_AL(target_ulong t0); | |
| 4 | +void helper_idivb_AL(target_ulong t0); | |
| 5 | +void helper_divw_AX(target_ulong t0); | |
| 6 | +void helper_idivw_AX(target_ulong t0); | |
| 7 | +void helper_divl_EAX(target_ulong t0); | |
| 8 | +void helper_idivl_EAX(target_ulong t0); | |
| 9 | +#ifdef TARGET_X86_64 | |
| 10 | +void helper_divq_EAX(target_ulong t0); | |
| 11 | +void helper_idivq_EAX(target_ulong t0); | |
| 12 | +#endif | |
| 13 | + | |
| 14 | +void helper_aam(int base); | |
| 15 | +void helper_aad(int base); | |
| 16 | +void helper_aaa(void); | |
| 17 | +void helper_aas(void); | |
| 18 | +void helper_daa(void); | |
| 19 | +void helper_das(void); | |
| 20 | + | |
| 21 | +void helper_lsl(uint32_t selector); | |
| 22 | +void helper_lar(uint32_t selector); | |
| 23 | +void helper_verr(uint32_t selector); | |
| 24 | +void helper_verw(uint32_t selector); | |
| 25 | +void helper_lldt(int selector); | |
| 26 | +void helper_ltr(int selector); | |
| 27 | +void helper_load_seg(int seg_reg, int selector); | |
| 28 | +void helper_ljmp_protected_T0_T1(int next_eip); | |
| 29 | +void helper_lcall_real_T0_T1(int shift, int next_eip); | |
| 30 | +void helper_lcall_protected_T0_T1(int shift, int next_eip); | |
| 31 | +void helper_iret_real(int shift); | |
| 32 | +void helper_iret_protected(int shift, int next_eip); | |
| 33 | +void helper_lret_protected(int shift, int addend); | |
| 34 | +void helper_movl_crN_T0(int reg); | |
| 35 | +void helper_movl_drN_T0(int reg); | |
| 36 | +void helper_invlpg(target_ulong addr); | |
| 37 | + | |
| 38 | +void helper_enter_level(int level, int data32); | |
| 39 | +#ifdef TARGET_X86_64 | |
| 40 | +void helper_enter64_level(int level, int data64); | |
| 41 | +#endif | |
| 42 | +void helper_sysenter(void); | |
| 43 | +void helper_sysexit(void); | |
| 44 | +#ifdef TARGET_X86_64 | |
| 45 | +void helper_syscall(int next_eip_addend); | |
| 46 | +void helper_sysret(int dflag); | |
| 47 | +#endif | |
| 48 | +void helper_hlt(void); | |
| 49 | +void helper_monitor(target_ulong ptr); | |
| 50 | +void helper_mwait(void); | |
| 51 | +void helper_debug(void); | |
| 52 | +void helper_raise_interrupt(int intno, int next_eip_addend); | |
| 53 | +void helper_raise_exception(int exception_index); | |
| 54 | +void helper_cli(void); | |
| 55 | +void helper_sti(void); | |
| 56 | +void helper_set_inhibit_irq(void); | |
| 57 | +void helper_reset_inhibit_irq(void); | |
| 58 | +void helper_boundw(void); | |
| 59 | +void helper_boundl(void); | |
| 60 | +void helper_rsm(void); | |
| 61 | +void helper_single_step(void); | |
| 62 | +void helper_cpuid(void); | |
| 63 | +void helper_rdtsc(void); | |
| 64 | +void helper_rdpmc(void); | |
| 65 | +void helper_rdmsr(void); | |
| 66 | +void helper_wrmsr(void); | |
| 67 | + | |
| 68 | +void helper_vmrun(void); | |
| 69 | +void helper_vmmcall(void); | |
| 70 | +void helper_vmload(void); | |
| 71 | +void helper_vmsave(void); | |
| 72 | +void helper_stgi(void); | |
| 73 | +void helper_clgi(void); | |
| 74 | +void helper_skinit(void); | |
| 75 | +void helper_invlpga(void); | |
| 5 | 76 | |
| 6 | 77 | /* x86 FPU */ |
| 7 | 78 | ... | ... |
target-i386/op.c
| ... | ... | @@ -290,90 +290,6 @@ void OPPROTO op_imulq_T0_T1(void) |
| 290 | 290 | } |
| 291 | 291 | #endif |
| 292 | 292 | |
| 293 | -/* division, flags are undefined */ | |
| 294 | - | |
| 295 | -void OPPROTO op_divb_AL_T0(void) | |
| 296 | -{ | |
| 297 | - unsigned int num, den, q, r; | |
| 298 | - | |
| 299 | - num = (EAX & 0xffff); | |
| 300 | - den = (T0 & 0xff); | |
| 301 | - if (den == 0) { | |
| 302 | - raise_exception(EXCP00_DIVZ); | |
| 303 | - } | |
| 304 | - q = (num / den); | |
| 305 | - if (q > 0xff) | |
| 306 | - raise_exception(EXCP00_DIVZ); | |
| 307 | - q &= 0xff; | |
| 308 | - r = (num % den) & 0xff; | |
| 309 | - EAX = (EAX & ~0xffff) | (r << 8) | q; | |
| 310 | -} | |
| 311 | - | |
| 312 | -void OPPROTO op_idivb_AL_T0(void) | |
| 313 | -{ | |
| 314 | - int num, den, q, r; | |
| 315 | - | |
| 316 | - num = (int16_t)EAX; | |
| 317 | - den = (int8_t)T0; | |
| 318 | - if (den == 0) { | |
| 319 | - raise_exception(EXCP00_DIVZ); | |
| 320 | - } | |
| 321 | - q = (num / den); | |
| 322 | - if (q != (int8_t)q) | |
| 323 | - raise_exception(EXCP00_DIVZ); | |
| 324 | - q &= 0xff; | |
| 325 | - r = (num % den) & 0xff; | |
| 326 | - EAX = (EAX & ~0xffff) | (r << 8) | q; | |
| 327 | -} | |
| 328 | - | |
| 329 | -void OPPROTO op_divw_AX_T0(void) | |
| 330 | -{ | |
| 331 | - unsigned int num, den, q, r; | |
| 332 | - | |
| 333 | - num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); | |
| 334 | - den = (T0 & 0xffff); | |
| 335 | - if (den == 0) { | |
| 336 | - raise_exception(EXCP00_DIVZ); | |
| 337 | - } | |
| 338 | - q = (num / den); | |
| 339 | - if (q > 0xffff) | |
| 340 | - raise_exception(EXCP00_DIVZ); | |
| 341 | - q &= 0xffff; | |
| 342 | - r = (num % den) & 0xffff; | |
| 343 | - EAX = (EAX & ~0xffff) | q; | |
| 344 | - EDX = (EDX & ~0xffff) | r; | |
| 345 | -} | |
| 346 | - | |
| 347 | -void OPPROTO op_idivw_AX_T0(void) | |
| 348 | -{ | |
| 349 | - int num, den, q, r; | |
| 350 | - | |
| 351 | - num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); | |
| 352 | - den = (int16_t)T0; | |
| 353 | - if (den == 0) { | |
| 354 | - raise_exception(EXCP00_DIVZ); | |
| 355 | - } | |
| 356 | - q = (num / den); | |
| 357 | - if (q != (int16_t)q) | |
| 358 | - raise_exception(EXCP00_DIVZ); | |
| 359 | - q &= 0xffff; | |
| 360 | - r = (num % den) & 0xffff; | |
| 361 | - EAX = (EAX & ~0xffff) | q; | |
| 362 | - EDX = (EDX & ~0xffff) | r; | |
| 363 | -} | |
| 364 | - | |
| 365 | -#ifdef TARGET_X86_64 | |
| 366 | -void OPPROTO op_divq_EAX_T0(void) | |
| 367 | -{ | |
| 368 | - helper_divq_EAX_T0(); | |
| 369 | -} | |
| 370 | - | |
| 371 | -void OPPROTO op_idivq_EAX_T0(void) | |
| 372 | -{ | |
| 373 | - helper_idivq_EAX_T0(); | |
| 374 | -} | |
| 375 | -#endif | |
| 376 | - | |
| 377 | 293 | /* constant load & misc op */ |
| 378 | 294 | |
| 379 | 295 | /* XXX: consistent names */ |
| ... | ... | @@ -423,42 +339,6 @@ void OPPROTO op_addq_A0_AL(void) |
| 423 | 339 | |
| 424 | 340 | #endif |
| 425 | 341 | |
| 426 | -void OPPROTO op_hlt(void) | |
| 427 | -{ | |
| 428 | - helper_hlt(); | |
| 429 | -} | |
| 430 | - | |
| 431 | -void OPPROTO op_monitor(void) | |
| 432 | -{ | |
| 433 | - helper_monitor(); | |
| 434 | -} | |
| 435 | - | |
| 436 | -void OPPROTO op_mwait(void) | |
| 437 | -{ | |
| 438 | - helper_mwait(); | |
| 439 | -} | |
| 440 | - | |
| 441 | -void OPPROTO op_debug(void) | |
| 442 | -{ | |
| 443 | - env->exception_index = EXCP_DEBUG; | |
| 444 | - cpu_loop_exit(); | |
| 445 | -} | |
| 446 | - | |
| 447 | -void OPPROTO op_raise_interrupt(void) | |
| 448 | -{ | |
| 449 | - int intno, next_eip_addend; | |
| 450 | - intno = PARAM1; | |
| 451 | - next_eip_addend = PARAM2; | |
| 452 | - raise_interrupt(intno, 1, 0, next_eip_addend); | |
| 453 | -} | |
| 454 | - | |
| 455 | -void OPPROTO op_raise_exception(void) | |
| 456 | -{ | |
| 457 | - int exception_index; | |
| 458 | - exception_index = PARAM1; | |
| 459 | - raise_exception(exception_index); | |
| 460 | -} | |
| 461 | - | |
| 462 | 342 | void OPPROTO op_into(void) |
| 463 | 343 | { |
| 464 | 344 | int eflags; |
| ... | ... | @@ -469,83 +349,11 @@ void OPPROTO op_into(void) |
| 469 | 349 | FORCE_RET(); |
| 470 | 350 | } |
| 471 | 351 | |
| 472 | -void OPPROTO op_cli(void) | |
| 473 | -{ | |
| 474 | - env->eflags &= ~IF_MASK; | |
| 475 | -} | |
| 476 | - | |
| 477 | -void OPPROTO op_sti(void) | |
| 478 | -{ | |
| 479 | - env->eflags |= IF_MASK; | |
| 480 | -} | |
| 481 | - | |
| 482 | -void OPPROTO op_set_inhibit_irq(void) | |
| 483 | -{ | |
| 484 | - env->hflags |= HF_INHIBIT_IRQ_MASK; | |
| 485 | -} | |
| 486 | - | |
| 487 | -void OPPROTO op_reset_inhibit_irq(void) | |
| 488 | -{ | |
| 489 | - env->hflags &= ~HF_INHIBIT_IRQ_MASK; | |
| 490 | -} | |
| 491 | - | |
| 492 | -void OPPROTO op_rsm(void) | |
| 493 | -{ | |
| 494 | - helper_rsm(); | |
| 495 | -} | |
| 496 | - | |
| 497 | -#if 0 | |
| 498 | -/* vm86plus instructions */ | |
| 499 | -void OPPROTO op_cli_vm(void) | |
| 500 | -{ | |
| 501 | - env->eflags &= ~VIF_MASK; | |
| 502 | -} | |
| 503 | - | |
| 504 | -void OPPROTO op_sti_vm(void) | |
| 505 | -{ | |
| 506 | - env->eflags |= VIF_MASK; | |
| 507 | - if (env->eflags & VIP_MASK) { | |
| 508 | - EIP = PARAM1; | |
| 509 | - raise_exception(EXCP0D_GPF); | |
| 510 | - } | |
| 511 | - FORCE_RET(); | |
| 512 | -} | |
| 513 | -#endif | |
| 514 | - | |
| 515 | -void OPPROTO op_boundw(void) | |
| 516 | -{ | |
| 517 | - int low, high, v; | |
| 518 | - low = ldsw(A0); | |
| 519 | - high = ldsw(A0 + 2); | |
| 520 | - v = (int16_t)T0; | |
| 521 | - if (v < low || v > high) { | |
| 522 | - raise_exception(EXCP05_BOUND); | |
| 523 | - } | |
| 524 | - FORCE_RET(); | |
| 525 | -} | |
| 526 | - | |
| 527 | -void OPPROTO op_boundl(void) | |
| 528 | -{ | |
| 529 | - int low, high, v; | |
| 530 | - low = ldl(A0); | |
| 531 | - high = ldl(A0 + 4); | |
| 532 | - v = T0; | |
| 533 | - if (v < low || v > high) { | |
| 534 | - raise_exception(EXCP05_BOUND); | |
| 535 | - } | |
| 536 | - FORCE_RET(); | |
| 537 | -} | |
| 538 | - | |
| 539 | 352 | void OPPROTO op_cmpxchg8b(void) |
| 540 | 353 | { |
| 541 | 354 | helper_cmpxchg8b(); |
| 542 | 355 | } |
| 543 | 356 | |
| 544 | -void OPPROTO op_single_step(void) | |
| 545 | -{ | |
| 546 | - helper_single_step(); | |
| 547 | -} | |
| 548 | - | |
| 549 | 357 | /* multiple size ops */ |
| 550 | 358 | |
| 551 | 359 | #define ldul ldl |
| ... | ... | @@ -680,197 +488,36 @@ void OPPROTO op_decq_ECX(void) |
| 680 | 488 | } |
| 681 | 489 | #endif |
| 682 | 490 | |
| 683 | -void OPPROTO op_rdtsc(void) | |
| 684 | -{ | |
| 685 | - helper_rdtsc(); | |
| 686 | -} | |
| 687 | - | |
| 688 | -void OPPROTO op_rdpmc(void) | |
| 689 | -{ | |
| 690 | - helper_rdpmc(); | |
| 691 | -} | |
| 692 | - | |
| 693 | -void OPPROTO op_cpuid(void) | |
| 694 | -{ | |
| 695 | - helper_cpuid(); | |
| 696 | -} | |
| 697 | - | |
| 698 | -void OPPROTO op_enter_level(void) | |
| 699 | -{ | |
| 700 | - helper_enter_level(PARAM1, PARAM2); | |
| 701 | -} | |
| 702 | - | |
| 703 | -#ifdef TARGET_X86_64 | |
| 704 | -void OPPROTO op_enter64_level(void) | |
| 705 | -{ | |
| 706 | - helper_enter64_level(PARAM1, PARAM2); | |
| 707 | -} | |
| 708 | -#endif | |
| 709 | - | |
| 710 | -void OPPROTO op_sysenter(void) | |
| 711 | -{ | |
| 712 | - helper_sysenter(); | |
| 713 | -} | |
| 714 | - | |
| 715 | -void OPPROTO op_sysexit(void) | |
| 716 | -{ | |
| 717 | - helper_sysexit(); | |
| 718 | -} | |
| 719 | - | |
| 720 | -#ifdef TARGET_X86_64 | |
| 721 | -void OPPROTO op_syscall(void) | |
| 722 | -{ | |
| 723 | - helper_syscall(PARAM1); | |
| 724 | -} | |
| 725 | - | |
| 726 | -void OPPROTO op_sysret(void) | |
| 727 | -{ | |
| 728 | - helper_sysret(PARAM1); | |
| 729 | -} | |
| 730 | -#endif | |
| 731 | - | |
| 732 | -void OPPROTO op_rdmsr(void) | |
| 733 | -{ | |
| 734 | - helper_rdmsr(); | |
| 735 | -} | |
| 736 | - | |
| 737 | -void OPPROTO op_wrmsr(void) | |
| 738 | -{ | |
| 739 | - helper_wrmsr(); | |
| 740 | -} | |
| 741 | - | |
| 742 | 491 | /* bcd */ |
| 743 | 492 | |
| 744 | -/* XXX: exception */ | |
| 745 | 493 | void OPPROTO op_aam(void) |
| 746 | 494 | { |
| 747 | - int base = PARAM1; | |
| 748 | - int al, ah; | |
| 749 | - al = EAX & 0xff; | |
| 750 | - ah = al / base; | |
| 751 | - al = al % base; | |
| 752 | - EAX = (EAX & ~0xffff) | al | (ah << 8); | |
| 753 | - CC_DST = al; | |
| 495 | + helper_aam(PARAM1); | |
| 754 | 496 | } |
| 755 | 497 | |
| 756 | 498 | void OPPROTO op_aad(void) |
| 757 | 499 | { |
| 758 | - int base = PARAM1; | |
| 759 | - int al, ah; | |
| 760 | - al = EAX & 0xff; | |
| 761 | - ah = (EAX >> 8) & 0xff; | |
| 762 | - al = ((ah * base) + al) & 0xff; | |
| 763 | - EAX = (EAX & ~0xffff) | al; | |
| 764 | - CC_DST = al; | |
| 500 | + helper_aad(PARAM1); | |
| 765 | 501 | } |
| 766 | 502 | |
| 767 | 503 | void OPPROTO op_aaa(void) |
| 768 | 504 | { |
| 769 | - int icarry; | |
| 770 | - int al, ah, af; | |
| 771 | - int eflags; | |
| 772 | - | |
| 773 | - eflags = cc_table[CC_OP].compute_all(); | |
| 774 | - af = eflags & CC_A; | |
| 775 | - al = EAX & 0xff; | |
| 776 | - ah = (EAX >> 8) & 0xff; | |
| 777 | - | |
| 778 | - icarry = (al > 0xf9); | |
| 779 | - if (((al & 0x0f) > 9 ) || af) { | |
| 780 | - al = (al + 6) & 0x0f; | |
| 781 | - ah = (ah + 1 + icarry) & 0xff; | |
| 782 | - eflags |= CC_C | CC_A; | |
| 783 | - } else { | |
| 784 | - eflags &= ~(CC_C | CC_A); | |
| 785 | - al &= 0x0f; | |
| 786 | - } | |
| 787 | - EAX = (EAX & ~0xffff) | al | (ah << 8); | |
| 788 | - CC_SRC = eflags; | |
| 789 | - FORCE_RET(); | |
| 505 | + helper_aaa(); | |
| 790 | 506 | } |
| 791 | 507 | |
| 792 | 508 | void OPPROTO op_aas(void) |
| 793 | 509 | { |
| 794 | - int icarry; | |
| 795 | - int al, ah, af; | |
| 796 | - int eflags; | |
| 797 | - | |
| 798 | - eflags = cc_table[CC_OP].compute_all(); | |
| 799 | - af = eflags & CC_A; | |
| 800 | - al = EAX & 0xff; | |
| 801 | - ah = (EAX >> 8) & 0xff; | |
| 802 | - | |
| 803 | - icarry = (al < 6); | |
| 804 | - if (((al & 0x0f) > 9 ) || af) { | |
| 805 | - al = (al - 6) & 0x0f; | |
| 806 | - ah = (ah - 1 - icarry) & 0xff; | |
| 807 | - eflags |= CC_C | CC_A; | |
| 808 | - } else { | |
| 809 | - eflags &= ~(CC_C | CC_A); | |
| 810 | - al &= 0x0f; | |
| 811 | - } | |
| 812 | - EAX = (EAX & ~0xffff) | al | (ah << 8); | |
| 813 | - CC_SRC = eflags; | |
| 814 | - FORCE_RET(); | |
| 510 | + helper_aas(); | |
| 815 | 511 | } |
| 816 | 512 | |
| 817 | 513 | void OPPROTO op_daa(void) |
| 818 | 514 | { |
| 819 | - int al, af, cf; | |
| 820 | - int eflags; | |
| 821 | - | |
| 822 | - eflags = cc_table[CC_OP].compute_all(); | |
| 823 | - cf = eflags & CC_C; | |
| 824 | - af = eflags & CC_A; | |
| 825 | - al = EAX & 0xff; | |
| 826 | - | |
| 827 | - eflags = 0; | |
| 828 | - if (((al & 0x0f) > 9 ) || af) { | |
| 829 | - al = (al + 6) & 0xff; | |
| 830 | - eflags |= CC_A; | |
| 831 | - } | |
| 832 | - if ((al > 0x9f) || cf) { | |
| 833 | - al = (al + 0x60) & 0xff; | |
| 834 | - eflags |= CC_C; | |
| 835 | - } | |
| 836 | - EAX = (EAX & ~0xff) | al; | |
| 837 | - /* well, speed is not an issue here, so we compute the flags by hand */ | |
| 838 | - eflags |= (al == 0) << 6; /* zf */ | |
| 839 | - eflags |= parity_table[al]; /* pf */ | |
| 840 | - eflags |= (al & 0x80); /* sf */ | |
| 841 | - CC_SRC = eflags; | |
| 842 | - FORCE_RET(); | |
| 515 | + helper_daa(); | |
| 843 | 516 | } |
| 844 | 517 | |
| 845 | 518 | void OPPROTO op_das(void) |
| 846 | 519 | { |
| 847 | - int al, al1, af, cf; | |
| 848 | - int eflags; | |
| 849 | - | |
| 850 | - eflags = cc_table[CC_OP].compute_all(); | |
| 851 | - cf = eflags & CC_C; | |
| 852 | - af = eflags & CC_A; | |
| 853 | - al = EAX & 0xff; | |
| 854 | - | |
| 855 | - eflags = 0; | |
| 856 | - al1 = al; | |
| 857 | - if (((al & 0x0f) > 9 ) || af) { | |
| 858 | - eflags |= CC_A; | |
| 859 | - if (al < 6 || cf) | |
| 860 | - eflags |= CC_C; | |
| 861 | - al = (al - 6) & 0xff; | |
| 862 | - } | |
| 863 | - if ((al1 > 0x99) || cf) { | |
| 864 | - al = (al - 0x60) & 0xff; | |
| 865 | - eflags |= CC_C; | |
| 866 | - } | |
| 867 | - EAX = (EAX & ~0xff) | al; | |
| 868 | - /* well, speed is not an issue here, so we compute the flags by hand */ | |
| 869 | - eflags |= (al == 0) << 6; /* zf */ | |
| 870 | - eflags |= parity_table[al]; /* pf */ | |
| 871 | - eflags |= (al & 0x80); /* sf */ | |
| 872 | - CC_SRC = eflags; | |
| 873 | - FORCE_RET(); | |
| 520 | + helper_das(); | |
| 874 | 521 | } |
| 875 | 522 | |
| 876 | 523 | /* segment handling */ |
| ... | ... | @@ -878,7 +525,7 @@ void OPPROTO op_das(void) |
| 878 | 525 | /* never use it with R_CS */ |
| 879 | 526 | void OPPROTO op_movl_seg_T0(void) |
| 880 | 527 | { |
| 881 | - load_seg(PARAM1, T0); | |
| 528 | + helper_load_seg(PARAM1, T0); | |
| 882 | 529 | } |
| 883 | 530 | |
| 884 | 531 | /* faster VM86 version */ |
| ... | ... | @@ -901,22 +548,22 @@ void OPPROTO op_movl_T0_seg(void) |
| 901 | 548 | |
| 902 | 549 | void OPPROTO op_lsl(void) |
| 903 | 550 | { |
| 904 | - helper_lsl(); | |
| 551 | + helper_lsl(T0); | |
| 905 | 552 | } |
| 906 | 553 | |
| 907 | 554 | void OPPROTO op_lar(void) |
| 908 | 555 | { |
| 909 | - helper_lar(); | |
| 556 | + helper_lar(T0); | |
| 910 | 557 | } |
| 911 | 558 | |
| 912 | 559 | void OPPROTO op_verr(void) |
| 913 | 560 | { |
| 914 | - helper_verr(); | |
| 561 | + helper_verr(T0); | |
| 915 | 562 | } |
| 916 | 563 | |
| 917 | 564 | void OPPROTO op_verw(void) |
| 918 | 565 | { |
| 919 | - helper_verw(); | |
| 566 | + helper_verw(T0); | |
| 920 | 567 | } |
| 921 | 568 | |
| 922 | 569 | void OPPROTO op_arpl(void) |
| ... | ... | @@ -969,16 +616,6 @@ void OPPROTO op_lret_protected(void) |
| 969 | 616 | helper_lret_protected(PARAM1, PARAM2); |
| 970 | 617 | } |
| 971 | 618 | |
| 972 | -void OPPROTO op_lldt_T0(void) | |
| 973 | -{ | |
| 974 | - helper_lldt_T0(); | |
| 975 | -} | |
| 976 | - | |
| 977 | -void OPPROTO op_ltr_T0(void) | |
| 978 | -{ | |
| 979 | - helper_ltr_T0(); | |
| 980 | -} | |
| 981 | - | |
| 982 | 619 | /* CR registers access. */ |
| 983 | 620 | void OPPROTO op_movl_crN_T0(void) |
| 984 | 621 | { |
| ... | ... | @@ -1046,11 +683,6 @@ void OPPROTO op_lmsw_T0(void) |
| 1046 | 683 | helper_movl_crN_T0(0); |
| 1047 | 684 | } |
| 1048 | 685 | |
| 1049 | -void OPPROTO op_invlpg_A0(void) | |
| 1050 | -{ | |
| 1051 | - helper_invlpg(A0); | |
| 1052 | -} | |
| 1053 | - | |
| 1054 | 686 | void OPPROTO op_movl_T0_env(void) |
| 1055 | 687 | { |
| 1056 | 688 | T0 = *(uint32_t *)((char *)env + PARAM1); |
| ... | ... | @@ -1282,16 +914,6 @@ void OPPROTO op_movl_T0_eflags_vm(void) |
| 1282 | 914 | } |
| 1283 | 915 | #endif |
| 1284 | 916 | |
| 1285 | -void OPPROTO op_cld(void) | |
| 1286 | -{ | |
| 1287 | - DF = 1; | |
| 1288 | -} | |
| 1289 | - | |
| 1290 | -void OPPROTO op_std(void) | |
| 1291 | -{ | |
| 1292 | - DF = -1; | |
| 1293 | -} | |
| 1294 | - | |
| 1295 | 917 | void OPPROTO op_clc(void) |
| 1296 | 918 | { |
| 1297 | 919 | int eflags; |
| ... | ... | @@ -1422,45 +1044,3 @@ void OPPROTO op_com_dummy(void) |
| 1422 | 1044 | { |
| 1423 | 1045 | T0 = 0; |
| 1424 | 1046 | } |
| 1425 | - | |
| 1426 | -/* Secure Virtual Machine ops */ | |
| 1427 | - | |
| 1428 | -void OPPROTO op_vmrun(void) | |
| 1429 | -{ | |
| 1430 | - helper_vmrun(EAX); | |
| 1431 | -} | |
| 1432 | - | |
| 1433 | -void OPPROTO op_vmmcall(void) | |
| 1434 | -{ | |
| 1435 | - helper_vmmcall(); | |
| 1436 | -} | |
| 1437 | - | |
| 1438 | -void OPPROTO op_vmload(void) | |
| 1439 | -{ | |
| 1440 | - helper_vmload(EAX); | |
| 1441 | -} | |
| 1442 | - | |
| 1443 | -void OPPROTO op_vmsave(void) | |
| 1444 | -{ | |
| 1445 | - helper_vmsave(EAX); | |
| 1446 | -} | |
| 1447 | - | |
| 1448 | -void OPPROTO op_stgi(void) | |
| 1449 | -{ | |
| 1450 | - helper_stgi(); | |
| 1451 | -} | |
| 1452 | - | |
| 1453 | -void OPPROTO op_clgi(void) | |
| 1454 | -{ | |
| 1455 | - helper_clgi(); | |
| 1456 | -} | |
| 1457 | - | |
| 1458 | -void OPPROTO op_skinit(void) | |
| 1459 | -{ | |
| 1460 | - helper_skinit(); | |
| 1461 | -} | |
| 1462 | - | |
| 1463 | -void OPPROTO op_invlpga(void) | |
| 1464 | -{ | |
| 1465 | - helper_invlpga(); | |
| 1466 | -} | ... | ... |
target-i386/translate.c
| ... | ... | @@ -2275,7 +2275,10 @@ static void gen_enter(DisasContext *s, int esp_addend, int level) |
| 2275 | 2275 | gen_op_mov_TN_reg(OT_LONG, 0, R_EBP); |
| 2276 | 2276 | gen_op_st_T0_A0(ot + s->mem_index); |
| 2277 | 2277 | if (level) { |
| 2278 | - gen_op_enter64_level(level, (ot == OT_QUAD)); | |
| 2278 | + /* XXX: must save state */ | |
| 2279 | + tcg_gen_helper_0_2(helper_enter64_level, | |
| 2280 | + tcg_const_i32(level), | |
| 2281 | + tcg_const_i32((ot == OT_QUAD))); | |
| 2279 | 2282 | } |
| 2280 | 2283 | gen_op_mov_reg_T1(ot, R_EBP); |
| 2281 | 2284 | gen_op_addl_T1_im( -esp_addend + (-opsize * level) ); |
| ... | ... | @@ -2297,7 +2300,10 @@ static void gen_enter(DisasContext *s, int esp_addend, int level) |
| 2297 | 2300 | gen_op_mov_TN_reg(OT_LONG, 0, R_EBP); |
| 2298 | 2301 | gen_op_st_T0_A0(ot + s->mem_index); |
| 2299 | 2302 | if (level) { |
| 2300 | - gen_op_enter_level(level, s->dflag); | |
| 2303 | + /* XXX: must save state */ | |
| 2304 | + tcg_gen_helper_0_2(helper_enter_level, | |
| 2305 | + tcg_const_i32(level), | |
| 2306 | + tcg_const_i32(s->dflag)); | |
| 2301 | 2307 | } |
| 2302 | 2308 | gen_op_mov_reg_T1(ot, R_EBP); |
| 2303 | 2309 | gen_op_addl_T1_im( -esp_addend + (-opsize * level) ); |
| ... | ... | @@ -2310,7 +2316,7 @@ static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip) |
| 2310 | 2316 | if (s->cc_op != CC_OP_DYNAMIC) |
| 2311 | 2317 | gen_op_set_cc_op(s->cc_op); |
| 2312 | 2318 | gen_jmp_im(cur_eip); |
| 2313 | - gen_op_raise_exception(trapno); | |
| 2319 | + tcg_gen_helper_0_1(helper_raise_exception, tcg_const_i32(trapno)); | |
| 2314 | 2320 | s->is_jmp = 3; |
| 2315 | 2321 | } |
| 2316 | 2322 | |
| ... | ... | @@ -2322,7 +2328,9 @@ static void gen_interrupt(DisasContext *s, int intno, |
| 2322 | 2328 | if (s->cc_op != CC_OP_DYNAMIC) |
| 2323 | 2329 | gen_op_set_cc_op(s->cc_op); |
| 2324 | 2330 | gen_jmp_im(cur_eip); |
| 2325 | - gen_op_raise_interrupt(intno, (int)(next_eip - cur_eip)); | |
| 2331 | + tcg_gen_helper_0_2(helper_raise_interrupt, | |
| 2332 | + tcg_const_i32(intno), | |
| 2333 | + tcg_const_i32(next_eip - cur_eip)); | |
| 2326 | 2334 | s->is_jmp = 3; |
| 2327 | 2335 | } |
| 2328 | 2336 | |
| ... | ... | @@ -2331,7 +2339,7 @@ static void gen_debug(DisasContext *s, target_ulong cur_eip) |
| 2331 | 2339 | if (s->cc_op != CC_OP_DYNAMIC) |
| 2332 | 2340 | gen_op_set_cc_op(s->cc_op); |
| 2333 | 2341 | gen_jmp_im(cur_eip); |
| 2334 | - gen_op_debug(); | |
| 2342 | + tcg_gen_helper_0_0(helper_debug); | |
| 2335 | 2343 | s->is_jmp = 3; |
| 2336 | 2344 | } |
| 2337 | 2345 | |
| ... | ... | @@ -2342,12 +2350,12 @@ static void gen_eob(DisasContext *s) |
| 2342 | 2350 | if (s->cc_op != CC_OP_DYNAMIC) |
| 2343 | 2351 | gen_op_set_cc_op(s->cc_op); |
| 2344 | 2352 | if (s->tb->flags & HF_INHIBIT_IRQ_MASK) { |
| 2345 | - gen_op_reset_inhibit_irq(); | |
| 2353 | + tcg_gen_helper_0_0(helper_reset_inhibit_irq); | |
| 2346 | 2354 | } |
| 2347 | 2355 | if (s->singlestep_enabled) { |
| 2348 | - gen_op_debug(); | |
| 2356 | + tcg_gen_helper_0_0(helper_debug); | |
| 2349 | 2357 | } else if (s->tf) { |
| 2350 | - gen_op_single_step(); | |
| 2358 | + tcg_gen_helper_0_0(helper_single_step); | |
| 2351 | 2359 | } else { |
| 2352 | 2360 | tcg_gen_exit_tb(0); |
| 2353 | 2361 | } |
| ... | ... | @@ -3659,26 +3667,21 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 3659 | 3667 | switch(ot) { |
| 3660 | 3668 | case OT_BYTE: |
| 3661 | 3669 | gen_jmp_im(pc_start - s->cs_base); |
| 3662 | - gen_op_divb_AL_T0(); | |
| 3670 | + tcg_gen_helper_0_1(helper_divb_AL, cpu_T[0]); | |
| 3663 | 3671 | break; |
| 3664 | 3672 | case OT_WORD: |
| 3665 | 3673 | gen_jmp_im(pc_start - s->cs_base); |
| 3666 | - gen_op_divw_AX_T0(); | |
| 3674 | + tcg_gen_helper_0_1(helper_divw_AX, cpu_T[0]); | |
| 3667 | 3675 | break; |
| 3668 | 3676 | default: |
| 3669 | 3677 | case OT_LONG: |
| 3670 | 3678 | gen_jmp_im(pc_start - s->cs_base); |
| 3671 | -#ifdef MACRO_TEST | |
| 3672 | - /* XXX: this is just a test */ | |
| 3673 | - tcg_gen_macro_2(cpu_T[0], cpu_T[0], MACRO_TEST); | |
| 3674 | -#else | |
| 3675 | - tcg_gen_helper_0_1(helper_divl_EAX_T0, cpu_T[0]); | |
| 3676 | -#endif | |
| 3679 | + tcg_gen_helper_0_1(helper_divl_EAX, cpu_T[0]); | |
| 3677 | 3680 | break; |
| 3678 | 3681 | #ifdef TARGET_X86_64 |
| 3679 | 3682 | case OT_QUAD: |
| 3680 | 3683 | gen_jmp_im(pc_start - s->cs_base); |
| 3681 | - gen_op_divq_EAX_T0(); | |
| 3684 | + tcg_gen_helper_0_1(helper_divq_EAX, cpu_T[0]); | |
| 3682 | 3685 | break; |
| 3683 | 3686 | #endif |
| 3684 | 3687 | } |
| ... | ... | @@ -3687,21 +3690,21 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 3687 | 3690 | switch(ot) { |
| 3688 | 3691 | case OT_BYTE: |
| 3689 | 3692 | gen_jmp_im(pc_start - s->cs_base); |
| 3690 | - gen_op_idivb_AL_T0(); | |
| 3693 | + tcg_gen_helper_0_1(helper_idivb_AL, cpu_T[0]); | |
| 3691 | 3694 | break; |
| 3692 | 3695 | case OT_WORD: |
| 3693 | 3696 | gen_jmp_im(pc_start - s->cs_base); |
| 3694 | - gen_op_idivw_AX_T0(); | |
| 3697 | + tcg_gen_helper_0_1(helper_idivw_AX, cpu_T[0]); | |
| 3695 | 3698 | break; |
| 3696 | 3699 | default: |
| 3697 | 3700 | case OT_LONG: |
| 3698 | 3701 | gen_jmp_im(pc_start - s->cs_base); |
| 3699 | - tcg_gen_helper_0_1(helper_idivl_EAX_T0, cpu_T[0]); | |
| 3702 | + tcg_gen_helper_0_1(helper_idivl_EAX, cpu_T[0]); | |
| 3700 | 3703 | break; |
| 3701 | 3704 | #ifdef TARGET_X86_64 |
| 3702 | 3705 | case OT_QUAD: |
| 3703 | 3706 | gen_jmp_im(pc_start - s->cs_base); |
| 3704 | - gen_op_idivq_EAX_T0(); | |
| 3707 | + tcg_gen_helper_0_1(helper_idivq_EAX, cpu_T[0]); | |
| 3705 | 3708 | break; |
| 3706 | 3709 | #endif |
| 3707 | 3710 | } |
| ... | ... | @@ -4088,7 +4091,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 4088 | 4091 | /* If several instructions disable interrupts, only the |
| 4089 | 4092 | _first_ does it */ |
| 4090 | 4093 | if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK)) |
| 4091 | - gen_op_set_inhibit_irq(); | |
| 4094 | + tcg_gen_helper_0_0(helper_set_inhibit_irq); | |
| 4092 | 4095 | s->tf = 0; |
| 4093 | 4096 | } |
| 4094 | 4097 | if (s->is_jmp) { |
| ... | ... | @@ -4164,7 +4167,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 4164 | 4167 | /* If several instructions disable interrupts, only the |
| 4165 | 4168 | _first_ does it */ |
| 4166 | 4169 | if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK)) |
| 4167 | - gen_op_set_inhibit_irq(); | |
| 4170 | + tcg_gen_helper_0_0(helper_set_inhibit_irq); | |
| 4168 | 4171 | s->tf = 0; |
| 4169 | 4172 | } |
| 4170 | 4173 | if (s->is_jmp) { |
| ... | ... | @@ -5471,10 +5474,12 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 5471 | 5474 | s->cc_op = CC_OP_EFLAGS; |
| 5472 | 5475 | break; |
| 5473 | 5476 | case 0xfc: /* cld */ |
| 5474 | - gen_op_cld(); | |
| 5477 | + tcg_gen_movi_i32(cpu_tmp2, 1); | |
| 5478 | + tcg_gen_st_i32(cpu_tmp2, cpu_env, offsetof(CPUState, df)); | |
| 5475 | 5479 | break; |
| 5476 | 5480 | case 0xfd: /* std */ |
| 5477 | - gen_op_std(); | |
| 5481 | + tcg_gen_movi_i32(cpu_tmp2, -1); | |
| 5482 | + tcg_gen_st_i32(cpu_tmp2, cpu_env, offsetof(CPUState, df)); | |
| 5478 | 5483 | break; |
| 5479 | 5484 | |
| 5480 | 5485 | /************************/ |
| ... | ... | @@ -5670,13 +5675,13 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 5670 | 5675 | case 0xfa: /* cli */ |
| 5671 | 5676 | if (!s->vm86) { |
| 5672 | 5677 | if (s->cpl <= s->iopl) { |
| 5673 | - gen_op_cli(); | |
| 5678 | + tcg_gen_helper_0_0(helper_cli); | |
| 5674 | 5679 | } else { |
| 5675 | 5680 | gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); |
| 5676 | 5681 | } |
| 5677 | 5682 | } else { |
| 5678 | 5683 | if (s->iopl == 3) { |
| 5679 | - gen_op_cli(); | |
| 5684 | + tcg_gen_helper_0_0(helper_cli); | |
| 5680 | 5685 | } else { |
| 5681 | 5686 | gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); |
| 5682 | 5687 | } |
| ... | ... | @@ -5686,12 +5691,12 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 5686 | 5691 | if (!s->vm86) { |
| 5687 | 5692 | if (s->cpl <= s->iopl) { |
| 5688 | 5693 | gen_sti: |
| 5689 | - gen_op_sti(); | |
| 5694 | + tcg_gen_helper_0_0(helper_sti); | |
| 5690 | 5695 | /* interruptions are enabled only the first insn after sti */ |
| 5691 | 5696 | /* If several instructions disable interrupts, only the |
| 5692 | 5697 | _first_ does it */ |
| 5693 | 5698 | if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK)) |
| 5694 | - gen_op_set_inhibit_irq(); | |
| 5699 | + tcg_gen_helper_0_0(helper_set_inhibit_irq); | |
| 5695 | 5700 | /* give a chance to handle pending irqs */ |
| 5696 | 5701 | gen_jmp_im(s->pc - s->cs_base); |
| 5697 | 5702 | gen_eob(s); |
| ... | ... | @@ -5719,9 +5724,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 5719 | 5724 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
| 5720 | 5725 | gen_jmp_im(pc_start - s->cs_base); |
| 5721 | 5726 | if (ot == OT_WORD) |
| 5722 | - gen_op_boundw(); | |
| 5727 | + tcg_gen_helper_0_0(helper_boundw); | |
| 5723 | 5728 | else |
| 5724 | - gen_op_boundl(); | |
| 5729 | + tcg_gen_helper_0_0(helper_boundl); | |
| 5725 | 5730 | break; |
| 5726 | 5731 | case 0x1c8 ... 0x1cf: /* bswap reg */ |
| 5727 | 5732 | reg = (b & 7) | REX_B(s); |
| ... | ... | @@ -5800,10 +5805,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 5800 | 5805 | int retval = 0; |
| 5801 | 5806 | if (b & 2) { |
| 5802 | 5807 | retval = gen_svm_check_intercept_param(s, pc_start, SVM_EXIT_MSR, 0); |
| 5803 | - gen_op_rdmsr(); | |
| 5808 | + tcg_gen_helper_0_0(helper_rdmsr); | |
| 5804 | 5809 | } else { |
| 5805 | 5810 | retval = gen_svm_check_intercept_param(s, pc_start, SVM_EXIT_MSR, 1); |
| 5806 | - gen_op_wrmsr(); | |
| 5811 | + tcg_gen_helper_0_0(helper_wrmsr); | |
| 5807 | 5812 | } |
| 5808 | 5813 | if(retval) |
| 5809 | 5814 | gen_eob(s); |
| ... | ... | @@ -5813,11 +5818,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 5813 | 5818 | if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_RDTSC)) |
| 5814 | 5819 | break; |
| 5815 | 5820 | gen_jmp_im(pc_start - s->cs_base); |
| 5816 | - gen_op_rdtsc(); | |
| 5821 | + tcg_gen_helper_0_0(helper_rdtsc); | |
| 5817 | 5822 | break; |
| 5818 | 5823 | case 0x133: /* rdpmc */ |
| 5819 | 5824 | gen_jmp_im(pc_start - s->cs_base); |
| 5820 | - gen_op_rdpmc(); | |
| 5825 | + tcg_gen_helper_0_0(helper_rdpmc); | |
| 5821 | 5826 | break; |
| 5822 | 5827 | case 0x134: /* sysenter */ |
| 5823 | 5828 | if (CODE64(s)) |
| ... | ... | @@ -5830,7 +5835,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 5830 | 5835 | s->cc_op = CC_OP_DYNAMIC; |
| 5831 | 5836 | } |
| 5832 | 5837 | gen_jmp_im(pc_start - s->cs_base); |
| 5833 | - gen_op_sysenter(); | |
| 5838 | + tcg_gen_helper_0_0(helper_sysenter); | |
| 5834 | 5839 | gen_eob(s); |
| 5835 | 5840 | } |
| 5836 | 5841 | break; |
| ... | ... | @@ -5845,7 +5850,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 5845 | 5850 | s->cc_op = CC_OP_DYNAMIC; |
| 5846 | 5851 | } |
| 5847 | 5852 | gen_jmp_im(pc_start - s->cs_base); |
| 5848 | - gen_op_sysexit(); | |
| 5853 | + tcg_gen_helper_0_0(helper_sysexit); | |
| 5849 | 5854 | gen_eob(s); |
| 5850 | 5855 | } |
| 5851 | 5856 | break; |
| ... | ... | @@ -5857,7 +5862,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 5857 | 5862 | s->cc_op = CC_OP_DYNAMIC; |
| 5858 | 5863 | } |
| 5859 | 5864 | gen_jmp_im(pc_start - s->cs_base); |
| 5860 | - gen_op_syscall(s->pc - pc_start); | |
| 5865 | + tcg_gen_helper_0_1(helper_syscall, tcg_const_i32(s->pc - pc_start)); | |
| 5861 | 5866 | gen_eob(s); |
| 5862 | 5867 | break; |
| 5863 | 5868 | case 0x107: /* sysret */ |
| ... | ... | @@ -5869,7 +5874,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 5869 | 5874 | s->cc_op = CC_OP_DYNAMIC; |
| 5870 | 5875 | } |
| 5871 | 5876 | gen_jmp_im(pc_start - s->cs_base); |
| 5872 | - gen_op_sysret(s->dflag); | |
| 5877 | + tcg_gen_helper_0_1(helper_sysret, tcg_const_i32(s->dflag)); | |
| 5873 | 5878 | /* condition codes are modified only in long mode */ |
| 5874 | 5879 | if (s->lma) |
| 5875 | 5880 | s->cc_op = CC_OP_EFLAGS; |
| ... | ... | @@ -5880,7 +5885,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 5880 | 5885 | case 0x1a2: /* cpuid */ |
| 5881 | 5886 | if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_CPUID)) |
| 5882 | 5887 | break; |
| 5883 | - gen_op_cpuid(); | |
| 5888 | + tcg_gen_helper_0_0(helper_cpuid); | |
| 5884 | 5889 | break; |
| 5885 | 5890 | case 0xf4: /* hlt */ |
| 5886 | 5891 | if (s->cpl != 0) { |
| ... | ... | @@ -5891,7 +5896,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 5891 | 5896 | if (s->cc_op != CC_OP_DYNAMIC) |
| 5892 | 5897 | gen_op_set_cc_op(s->cc_op); |
| 5893 | 5898 | gen_jmp_im(s->pc - s->cs_base); |
| 5894 | - gen_op_hlt(); | |
| 5899 | + tcg_gen_helper_0_0(helper_hlt); | |
| 5895 | 5900 | s->is_jmp = 3; |
| 5896 | 5901 | } |
| 5897 | 5902 | break; |
| ... | ... | @@ -5921,7 +5926,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 5921 | 5926 | break; |
| 5922 | 5927 | gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0); |
| 5923 | 5928 | gen_jmp_im(pc_start - s->cs_base); |
| 5924 | - gen_op_lldt_T0(); | |
| 5929 | + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]); | |
| 5930 | + tcg_gen_helper_0_1(helper_lldt, cpu_tmp2); | |
| 5925 | 5931 | } |
| 5926 | 5932 | break; |
| 5927 | 5933 | case 1: /* str */ |
| ... | ... | @@ -5945,7 +5951,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 5945 | 5951 | break; |
| 5946 | 5952 | gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0); |
| 5947 | 5953 | gen_jmp_im(pc_start - s->cs_base); |
| 5948 | - gen_op_ltr_T0(); | |
| 5954 | + tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]); | |
| 5955 | + tcg_gen_helper_0_1(helper_ltr, cpu_tmp2); | |
| 5949 | 5956 | } |
| 5950 | 5957 | break; |
| 5951 | 5958 | case 4: /* verr */ |
| ... | ... | @@ -6008,7 +6015,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 6008 | 6015 | gen_op_andl_A0_ffff(); |
| 6009 | 6016 | } |
| 6010 | 6017 | gen_add_A0_ds_seg(s); |
| 6011 | - gen_op_monitor(); | |
| 6018 | + tcg_gen_helper_0_1(helper_monitor, cpu_A0); | |
| 6012 | 6019 | break; |
| 6013 | 6020 | case 1: /* mwait */ |
| 6014 | 6021 | if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || |
| ... | ... | @@ -6021,7 +6028,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 6021 | 6028 | if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_MWAIT)) |
| 6022 | 6029 | break; |
| 6023 | 6030 | gen_jmp_im(s->pc - s->cs_base); |
| 6024 | - gen_op_mwait(); | |
| 6031 | + tcg_gen_helper_0_0(helper_mwait); | |
| 6025 | 6032 | gen_eob(s); |
| 6026 | 6033 | break; |
| 6027 | 6034 | default: |
| ... | ... | @@ -6050,7 +6057,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 6050 | 6057 | if (s->cc_op != CC_OP_DYNAMIC) |
| 6051 | 6058 | gen_op_set_cc_op(s->cc_op); |
| 6052 | 6059 | gen_jmp_im(s->pc - s->cs_base); |
| 6053 | - gen_op_vmrun(); | |
| 6060 | + tcg_gen_helper_0_0(helper_vmrun); | |
| 6054 | 6061 | s->cc_op = CC_OP_EFLAGS; |
| 6055 | 6062 | gen_eob(s); |
| 6056 | 6063 | break; |
| ... | ... | @@ -6058,37 +6065,37 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 6058 | 6065 | if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMMCALL)) |
| 6059 | 6066 | break; |
| 6060 | 6067 | /* FIXME: cause #UD if hflags & SVM */ |
| 6061 | - gen_op_vmmcall(); | |
| 6068 | + tcg_gen_helper_0_0(helper_vmmcall); | |
| 6062 | 6069 | break; |
| 6063 | 6070 | case 2: /* VMLOAD */ |
| 6064 | 6071 | if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMLOAD)) |
| 6065 | 6072 | break; |
| 6066 | - gen_op_vmload(); | |
| 6073 | + tcg_gen_helper_0_0(helper_vmload); | |
| 6067 | 6074 | break; |
| 6068 | 6075 | case 3: /* VMSAVE */ |
| 6069 | 6076 | if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMSAVE)) |
| 6070 | 6077 | break; |
| 6071 | - gen_op_vmsave(); | |
| 6078 | + tcg_gen_helper_0_0(helper_vmsave); | |
| 6072 | 6079 | break; |
| 6073 | 6080 | case 4: /* STGI */ |
| 6074 | 6081 | if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_STGI)) |
| 6075 | 6082 | break; |
| 6076 | - gen_op_stgi(); | |
| 6083 | + tcg_gen_helper_0_0(helper_stgi); | |
| 6077 | 6084 | break; |
| 6078 | 6085 | case 5: /* CLGI */ |
| 6079 | 6086 | if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_CLGI)) |
| 6080 | 6087 | break; |
| 6081 | - gen_op_clgi(); | |
| 6088 | + tcg_gen_helper_0_0(helper_clgi); | |
| 6082 | 6089 | break; |
| 6083 | 6090 | case 6: /* SKINIT */ |
| 6084 | 6091 | if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_SKINIT)) |
| 6085 | 6092 | break; |
| 6086 | - gen_op_skinit(); | |
| 6093 | + tcg_gen_helper_0_0(helper_skinit); | |
| 6087 | 6094 | break; |
| 6088 | 6095 | case 7: /* INVLPGA */ |
| 6089 | 6096 | if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_INVLPGA)) |
| 6090 | 6097 | break; |
| 6091 | - gen_op_invlpga(); | |
| 6098 | + tcg_gen_helper_0_0(helper_invlpga); | |
| 6092 | 6099 | break; |
| 6093 | 6100 | default: |
| 6094 | 6101 | goto illegal_op; |
| ... | ... | @@ -6153,7 +6160,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 6153 | 6160 | if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_INVLPG)) |
| 6154 | 6161 | break; |
| 6155 | 6162 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
| 6156 | - gen_op_invlpg_A0(); | |
| 6163 | + tcg_gen_helper_0_1(helper_invlpg, cpu_A0); | |
| 6157 | 6164 | gen_jmp_im(s->pc - s->cs_base); |
| 6158 | 6165 | gen_eob(s); |
| 6159 | 6166 | } |
| ... | ... | @@ -6458,7 +6465,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 6458 | 6465 | s->cc_op = CC_OP_DYNAMIC; |
| 6459 | 6466 | } |
| 6460 | 6467 | gen_jmp_im(s->pc - s->cs_base); |
| 6461 | - gen_op_rsm(); | |
| 6468 | + tcg_gen_helper_0_0(helper_rsm); | |
| 6462 | 6469 | gen_eob(s); |
| 6463 | 6470 | break; |
| 6464 | 6471 | case 0x10e ... 0x10f: |
| ... | ... | @@ -6855,9 +6862,6 @@ void optimize_flags_init(void) |
| 6855 | 6862 | cpu_A0 = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "A0"); |
| 6856 | 6863 | cpu_tmp1 = tcg_global_reg2_new_hack(TCG_TYPE_I64, TCG_AREG1, TCG_AREG2, "tmp1"); |
| 6857 | 6864 | #endif |
| 6858 | - /* the helpers are only registered to print debug info */ | |
| 6859 | - TCG_HELPER(helper_divl_EAX_T0); | |
| 6860 | - TCG_HELPER(helper_idivl_EAX_T0); | |
| 6861 | 6865 | } |
| 6862 | 6866 | |
| 6863 | 6867 | /* CPU flags computation optimization: we move backward thru the | ... | ... |