Commit fd4a04ebb220b1ada72275297fc12cb85e89bbfb

Authored by ths
1 parent 34ae7b51

- Move FPU exception handling into helper functions, since they are big.

- Fix FP-conditional branches.
- Check FPU register mode at runtime, not translation time, as the F64
  status bit can change.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2828 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/cpu.h
@@ -81,9 +81,9 @@ struct CPUMIPSState { @@ -81,9 +81,9 @@ struct CPUMIPSState {
81 #define FCR0_REV 0 81 #define FCR0_REV 0
82 /* fcsr */ 82 /* fcsr */
83 uint32_t fcr31; 83 uint32_t fcr31;
84 -#define SET_FP_COND(num,env) do { (env->fcr31) |= ((num) ? (1 << ((num) + 24)) : (1 << ((num) + 23))); } while(0)  
85 -#define CLEAR_FP_COND(num,env) do { (env->fcr31) &= ~((num) ? (1 << ((num) + 24)) : (1 << ((num) + 23))); } while(0)  
86 -#define IS_FP_COND_SET(num,env) (((env->fcr31) & ((num) ? (1 << ((num) + 24)) : (1 << ((num) + 23)))) != 0) 84 +#define SET_FP_COND(num,env) do { ((env)->fcr31) |= ((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
  85 +#define CLEAR_FP_COND(num,env) do { ((env)->fcr31) &= ~((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
  86 +#define GET_FP_COND(env) ((((env)->fcr31 >> 24) & 0xfe) | (((env)->fcr31 >> 23) & 0x1))
87 #define GET_FP_CAUSE(reg) (((reg) >> 12) & 0x3f) 87 #define GET_FP_CAUSE(reg) (((reg) >> 12) & 0x3f)
88 #define GET_FP_ENABLE(reg) (((reg) >> 7) & 0x1f) 88 #define GET_FP_ENABLE(reg) (((reg) >> 7) & 0x1f)
89 #define GET_FP_FLAGS(reg) (((reg) >> 2) & 0x1f) 89 #define GET_FP_FLAGS(reg) (((reg) >> 2) & 0x1f)
target-mips/exec.h
@@ -165,4 +165,75 @@ void cpu_mips_update_irq (CPUState *env); @@ -165,4 +165,75 @@ void cpu_mips_update_irq (CPUState *env);
165 void cpu_mips_clock_init (CPUState *env); 165 void cpu_mips_clock_init (CPUState *env);
166 void cpu_mips_tlb_flush (CPUState *env, int flush_global); 166 void cpu_mips_tlb_flush (CPUState *env, int flush_global);
167 167
  168 +void do_ctc1 (void);
  169 +void do_float_cvtd_s(void);
  170 +void do_float_cvtd_w(void);
  171 +void do_float_cvtd_l(void);
  172 +void do_float_cvtl_d(void);
  173 +void do_float_cvtl_s(void);
  174 +void do_float_cvtps_pw(void);
  175 +void do_float_cvtpw_ps(void);
  176 +void do_float_cvts_d(void);
  177 +void do_float_cvts_w(void);
  178 +void do_float_cvts_l(void);
  179 +void do_float_cvts_pl(void);
  180 +void do_float_cvts_pu(void);
  181 +void do_float_cvtw_s(void);
  182 +void do_float_cvtw_d(void);
  183 +void do_float_roundl_d(void);
  184 +void do_float_roundl_s(void);
  185 +void do_float_roundw_d(void);
  186 +void do_float_roundw_s(void);
  187 +void do_float_truncl_d(void);
  188 +void do_float_truncl_s(void);
  189 +void do_float_truncw_d(void);
  190 +void do_float_truncw_s(void);
  191 +void do_float_ceill_d(void);
  192 +void do_float_ceill_s(void);
  193 +void do_float_ceilw_d(void);
  194 +void do_float_ceilw_s(void);
  195 +void do_float_floorl_d(void);
  196 +void do_float_floorl_s(void);
  197 +void do_float_floorw_d(void);
  198 +void do_float_floorw_s(void);
  199 +void do_float_add_d(void);
  200 +void do_float_add_s(void);
  201 +void do_float_add_ps(void);
  202 +void do_float_sub_d(void);
  203 +void do_float_sub_s(void);
  204 +void do_float_sub_ps(void);
  205 +void do_float_mul_d(void);
  206 +void do_float_mul_s(void);
  207 +void do_float_mul_ps(void);
  208 +void do_float_div_d(void);
  209 +void do_float_div_s(void);
  210 +void do_float_div_ps(void);
  211 +void do_float_addr_ps(void);
  212 +
  213 +#define CMP_OPS(op) \
  214 +void do_cmp_d_ ## op(long cc); \
  215 +void do_cmpabs_d_ ## op(long cc); \
  216 +void do_cmp_s_ ## op(long cc); \
  217 +void do_cmpabs_s_ ## op(long cc); \
  218 +void do_cmp_ps_ ## op(long cc); \
  219 +void do_cmpabs_ps_ ## op(long cc);
  220 +
  221 +CMP_OPS(f)
  222 +CMP_OPS(un)
  223 +CMP_OPS(eq)
  224 +CMP_OPS(ueq)
  225 +CMP_OPS(olt)
  226 +CMP_OPS(ult)
  227 +CMP_OPS(ole)
  228 +CMP_OPS(ule)
  229 +CMP_OPS(sf)
  230 +CMP_OPS(ngle)
  231 +CMP_OPS(seq)
  232 +CMP_OPS(ngl)
  233 +CMP_OPS(lt)
  234 +CMP_OPS(nge)
  235 +CMP_OPS(le)
  236 +CMP_OPS(ngt)
  237 +#undef CMP_OPS
  238 +
168 #endif /* !defined(__QEMU_MIPS_EXEC_H__) */ 239 #endif /* !defined(__QEMU_MIPS_EXEC_H__) */
target-mips/op.c
@@ -1609,47 +1609,25 @@ void op_cp1_enabled(void) @@ -1609,47 +1609,25 @@ void op_cp1_enabled(void)
1609 RETURN(); 1609 RETURN();
1610 } 1610 }
1611 1611
1612 -/* convert MIPS rounding mode in FCR31 to IEEE library */  
1613 -unsigned int ieee_rm[] = {  
1614 - float_round_nearest_even,  
1615 - float_round_to_zero,  
1616 - float_round_up,  
1617 - float_round_down  
1618 -};  
1619 -  
1620 -#define RESTORE_ROUNDING_MODE \  
1621 - set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)  
1622 -  
1623 -inline char ieee_ex_to_mips(char xcpt)  
1624 -{  
1625 - return (xcpt & float_flag_inexact) >> 5 |  
1626 - (xcpt & float_flag_underflow) >> 3 |  
1627 - (xcpt & float_flag_overflow) >> 1 |  
1628 - (xcpt & float_flag_divbyzero) << 1 |  
1629 - (xcpt & float_flag_invalid) << 4;  
1630 -}  
1631 -  
1632 -inline char mips_ex_to_ieee(char xcpt)  
1633 -{  
1634 - return (xcpt & FP_INEXACT) << 5 |  
1635 - (xcpt & FP_UNDERFLOW) << 3 |  
1636 - (xcpt & FP_OVERFLOW) << 1 |  
1637 - (xcpt & FP_DIV0) >> 1 |  
1638 - (xcpt & FP_INVALID) >> 4;  
1639 -}  
1640 -  
1641 -inline void update_fcr31(void) 1612 +/*
  1613 + * Verify if floating point register is valid; an operation is not defined
  1614 + * if bit 0 of any register specification is set and the FR bit in the
  1615 + * Status register equals zero, since the register numbers specify an
  1616 + * even-odd pair of adjacent coprocessor general registers. When the FR bit
  1617 + * in the Status register equals one, both even and odd register numbers
  1618 + * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
  1619 + *
  1620 + * Multiple 64 bit wide registers can be checked by calling
  1621 + * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
  1622 + */
  1623 +void op_cp1_registers(void)
1642 { 1624 {
1643 - int tmp = ieee_ex_to_mips(get_float_exception_flags(&env->fp_status));  
1644 -  
1645 - SET_FP_CAUSE(env->fcr31, tmp);  
1646 - if (GET_FP_ENABLE(env->fcr31) & tmp)  
1647 - CALL_FROM_TB1(do_raise_exception, EXCP_FPE);  
1648 - else  
1649 - UPDATE_FP_FLAGS(env->fcr31, tmp); 1625 + if (!(env->CP0_Status & (1 << CP0St_FR)) && (PARAM1 & 1)) {
  1626 + CALL_FROM_TB1(do_raise_exception, EXCP_RI);
  1627 + }
  1628 + RETURN();
1650 } 1629 }
1651 1630
1652 -  
1653 void op_cfc1 (void) 1631 void op_cfc1 (void)
1654 { 1632 {
1655 switch (T1) { 1633 switch (T1) {
@@ -1675,38 +1653,7 @@ void op_cfc1 (void) @@ -1675,38 +1653,7 @@ void op_cfc1 (void)
1675 1653
1676 void op_ctc1 (void) 1654 void op_ctc1 (void)
1677 { 1655 {
1678 - switch(T1) {  
1679 - case 25:  
1680 - if (T0 & 0xffffff00)  
1681 - goto leave;  
1682 - env->fcr31 = (env->fcr31 & 0x017fffff) | ((T0 & 0xfe) << 24) |  
1683 - ((T0 & 0x1) << 23);  
1684 - break;  
1685 - case 26:  
1686 - if (T0 & 0x007c0000)  
1687 - goto leave;  
1688 - env->fcr31 = (env->fcr31 & 0xfffc0f83) | (T0 & 0x0003f07c);  
1689 - break;  
1690 - case 28:  
1691 - if (T0 & 0x007c0000)  
1692 - goto leave;  
1693 - env->fcr31 = (env->fcr31 & 0xfefff07c) | (T0 & 0x00000f83) |  
1694 - ((T0 & 0x4) << 22);  
1695 - break;  
1696 - case 31:  
1697 - if (T0 & 0x007c0000)  
1698 - goto leave;  
1699 - env->fcr31 = T0;  
1700 - break;  
1701 - default:  
1702 - goto leave;  
1703 - }  
1704 - /* set rounding mode */  
1705 - RESTORE_ROUNDING_MODE;  
1706 - set_float_exception_flags(0, &env->fp_status);  
1707 - if ((GET_FP_ENABLE(env->fcr31) | 0x20) & GET_FP_CAUSE(env->fcr31))  
1708 - CALL_FROM_TB1(do_raise_exception, EXCP_FPE);  
1709 - leave: 1656 + CALL_FROM_TB0(do_ctc1);
1710 DEBUG_FPU_STATE(); 1657 DEBUG_FPU_STATE();
1711 RETURN(); 1658 RETURN();
1712 } 1659 }
@@ -1762,45 +1709,31 @@ void op_mthc1 (void) @@ -1762,45 +1709,31 @@ void op_mthc1 (void)
1762 1709
1763 FLOAT_OP(cvtd, s) 1710 FLOAT_OP(cvtd, s)
1764 { 1711 {
1765 - set_float_exception_flags(0, &env->fp_status);  
1766 - FDT2 = float32_to_float64(FST0, &env->fp_status);  
1767 - update_fcr31(); 1712 + CALL_FROM_TB0(do_float_cvtd_s);
1768 DEBUG_FPU_STATE(); 1713 DEBUG_FPU_STATE();
1769 RETURN(); 1714 RETURN();
1770 } 1715 }
1771 FLOAT_OP(cvtd, w) 1716 FLOAT_OP(cvtd, w)
1772 { 1717 {
1773 - set_float_exception_flags(0, &env->fp_status);  
1774 - FDT2 = int32_to_float64(WT0, &env->fp_status);  
1775 - update_fcr31(); 1718 + CALL_FROM_TB0(do_float_cvtd_w);
1776 DEBUG_FPU_STATE(); 1719 DEBUG_FPU_STATE();
1777 RETURN(); 1720 RETURN();
1778 } 1721 }
1779 FLOAT_OP(cvtd, l) 1722 FLOAT_OP(cvtd, l)
1780 { 1723 {
1781 - set_float_exception_flags(0, &env->fp_status);  
1782 - FDT2 = int64_to_float64(DT0, &env->fp_status);  
1783 - update_fcr31(); 1724 + CALL_FROM_TB0(do_float_cvtd_l);
1784 DEBUG_FPU_STATE(); 1725 DEBUG_FPU_STATE();
1785 RETURN(); 1726 RETURN();
1786 } 1727 }
1787 FLOAT_OP(cvtl, d) 1728 FLOAT_OP(cvtl, d)
1788 { 1729 {
1789 - set_float_exception_flags(0, &env->fp_status);  
1790 - DT2 = float64_to_int64(FDT0, &env->fp_status);  
1791 - update_fcr31();  
1792 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
1793 - DT2 = 0x7fffffffffffffffULL; 1730 + CALL_FROM_TB0(do_float_cvtl_d);
1794 DEBUG_FPU_STATE(); 1731 DEBUG_FPU_STATE();
1795 RETURN(); 1732 RETURN();
1796 } 1733 }
1797 FLOAT_OP(cvtl, s) 1734 FLOAT_OP(cvtl, s)
1798 { 1735 {
1799 - set_float_exception_flags(0, &env->fp_status);  
1800 - DT2 = float32_to_int64(FST0, &env->fp_status);  
1801 - update_fcr31();  
1802 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
1803 - DT2 = 0x7fffffffffffffffULL; 1736 + CALL_FROM_TB0(do_float_cvtl_s);
1804 DEBUG_FPU_STATE(); 1737 DEBUG_FPU_STATE();
1805 RETURN(); 1738 RETURN();
1806 } 1739 }
@@ -1813,81 +1746,55 @@ FLOAT_OP(cvtps, s) @@ -1813,81 +1746,55 @@ FLOAT_OP(cvtps, s)
1813 } 1746 }
1814 FLOAT_OP(cvtps, pw) 1747 FLOAT_OP(cvtps, pw)
1815 { 1748 {
1816 - set_float_exception_flags(0, &env->fp_status);  
1817 - FST2 = int32_to_float32(WT0, &env->fp_status);  
1818 - FSTH2 = int32_to_float32(WTH0, &env->fp_status);  
1819 - update_fcr31(); 1749 + CALL_FROM_TB0(do_float_cvtps_pw);
1820 DEBUG_FPU_STATE(); 1750 DEBUG_FPU_STATE();
1821 RETURN(); 1751 RETURN();
1822 } 1752 }
1823 FLOAT_OP(cvtpw, ps) 1753 FLOAT_OP(cvtpw, ps)
1824 { 1754 {
1825 - set_float_exception_flags(0, &env->fp_status);  
1826 - WT2 = float32_to_int32(FST0, &env->fp_status);  
1827 - WTH2 = float32_to_int32(FSTH0, &env->fp_status);  
1828 - update_fcr31();  
1829 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
1830 - WT2 = 0x7fffffff; 1755 + CALL_FROM_TB0(do_float_cvtpw_ps);
1831 DEBUG_FPU_STATE(); 1756 DEBUG_FPU_STATE();
1832 RETURN(); 1757 RETURN();
1833 } 1758 }
1834 FLOAT_OP(cvts, d) 1759 FLOAT_OP(cvts, d)
1835 { 1760 {
1836 - set_float_exception_flags(0, &env->fp_status);  
1837 - FST2 = float64_to_float32(FDT0, &env->fp_status);  
1838 - update_fcr31(); 1761 + CALL_FROM_TB0(do_float_cvts_d);
1839 DEBUG_FPU_STATE(); 1762 DEBUG_FPU_STATE();
1840 RETURN(); 1763 RETURN();
1841 } 1764 }
1842 FLOAT_OP(cvts, w) 1765 FLOAT_OP(cvts, w)
1843 { 1766 {
1844 - set_float_exception_flags(0, &env->fp_status);  
1845 - FST2 = int32_to_float32(WT0, &env->fp_status);  
1846 - update_fcr31(); 1767 + CALL_FROM_TB0(do_float_cvts_w);
1847 DEBUG_FPU_STATE(); 1768 DEBUG_FPU_STATE();
1848 RETURN(); 1769 RETURN();
1849 } 1770 }
1850 FLOAT_OP(cvts, l) 1771 FLOAT_OP(cvts, l)
1851 { 1772 {
1852 - set_float_exception_flags(0, &env->fp_status);  
1853 - FST2 = int64_to_float32(DT0, &env->fp_status);  
1854 - update_fcr31(); 1773 + CALL_FROM_TB0(do_float_cvts_l);
1855 DEBUG_FPU_STATE(); 1774 DEBUG_FPU_STATE();
1856 RETURN(); 1775 RETURN();
1857 } 1776 }
1858 FLOAT_OP(cvts, pl) 1777 FLOAT_OP(cvts, pl)
1859 { 1778 {
1860 - set_float_exception_flags(0, &env->fp_status);  
1861 - WT2 = WT0;  
1862 - update_fcr31(); 1779 + CALL_FROM_TB0(do_float_cvts_pl);
1863 DEBUG_FPU_STATE(); 1780 DEBUG_FPU_STATE();
1864 RETURN(); 1781 RETURN();
1865 } 1782 }
1866 FLOAT_OP(cvts, pu) 1783 FLOAT_OP(cvts, pu)
1867 { 1784 {
1868 - set_float_exception_flags(0, &env->fp_status);  
1869 - WT2 = WTH0;  
1870 - update_fcr31(); 1785 + CALL_FROM_TB0(do_float_cvts_pu);
1871 DEBUG_FPU_STATE(); 1786 DEBUG_FPU_STATE();
1872 RETURN(); 1787 RETURN();
1873 } 1788 }
1874 FLOAT_OP(cvtw, s) 1789 FLOAT_OP(cvtw, s)
1875 { 1790 {
1876 - set_float_exception_flags(0, &env->fp_status);  
1877 - WT2 = float32_to_int32(FST0, &env->fp_status);  
1878 - update_fcr31();  
1879 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
1880 - WT2 = 0x7fffffff; 1791 + CALL_FROM_TB0(do_float_cvtw_s);
1881 DEBUG_FPU_STATE(); 1792 DEBUG_FPU_STATE();
1882 RETURN(); 1793 RETURN();
1883 } 1794 }
1884 FLOAT_OP(cvtw, d) 1795 FLOAT_OP(cvtw, d)
1885 { 1796 {
1886 - set_float_exception_flags(0, &env->fp_status);  
1887 - WT2 = float64_to_int32(FDT0, &env->fp_status);  
1888 - update_fcr31();  
1889 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
1890 - WT2 = 0x7fffffff; 1797 + CALL_FROM_TB0(do_float_cvtw_d);
1891 DEBUG_FPU_STATE(); 1798 DEBUG_FPU_STATE();
1892 RETURN(); 1799 RETURN();
1893 } 1800 }
@@ -1917,177 +1824,34 @@ FLOAT_OP(puu, ps) @@ -1917,177 +1824,34 @@ FLOAT_OP(puu, ps)
1917 RETURN(); 1824 RETURN();
1918 } 1825 }
1919 1826
1920 -FLOAT_OP(roundl, d)  
1921 -{  
1922 - set_float_rounding_mode(float_round_nearest_even, &env->fp_status);  
1923 - DT2 = float64_round_to_int(FDT0, &env->fp_status);  
1924 - RESTORE_ROUNDING_MODE;  
1925 - update_fcr31();  
1926 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
1927 - DT2 = 0x7fffffffffffffffULL;  
1928 - DEBUG_FPU_STATE();  
1929 - RETURN();  
1930 -}  
1931 -FLOAT_OP(roundl, s)  
1932 -{  
1933 - set_float_rounding_mode(float_round_nearest_even, &env->fp_status);  
1934 - DT2 = float32_round_to_int(FST0, &env->fp_status);  
1935 - RESTORE_ROUNDING_MODE;  
1936 - update_fcr31();  
1937 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
1938 - DT2 = 0x7fffffffffffffffULL;  
1939 - DEBUG_FPU_STATE();  
1940 - RETURN();  
1941 -}  
1942 -FLOAT_OP(roundw, d)  
1943 -{  
1944 - set_float_rounding_mode(float_round_nearest_even, &env->fp_status);  
1945 - WT2 = float64_round_to_int(FDT0, &env->fp_status);  
1946 - RESTORE_ROUNDING_MODE;  
1947 - update_fcr31();  
1948 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
1949 - WT2 = 0x7fffffff;  
1950 - DEBUG_FPU_STATE();  
1951 - RETURN();  
1952 -}  
1953 -FLOAT_OP(roundw, s)  
1954 -{  
1955 - set_float_rounding_mode(float_round_nearest_even, &env->fp_status);  
1956 - WT2 = float32_round_to_int(FST0, &env->fp_status);  
1957 - RESTORE_ROUNDING_MODE;  
1958 - update_fcr31();  
1959 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
1960 - WT2 = 0x7fffffff;  
1961 - DEBUG_FPU_STATE();  
1962 - RETURN(); 1827 +#define FLOAT_ROUNDOP(op, ttype, stype) \
  1828 +FLOAT_OP(op ## ttype, stype) \
  1829 +{ \
  1830 + CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \
  1831 + DEBUG_FPU_STATE(); \
  1832 + RETURN(); \
1963 } 1833 }
1964 1834
1965 -FLOAT_OP(truncl, d)  
1966 -{  
1967 - DT2 = float64_to_int64_round_to_zero(FDT0, &env->fp_status);  
1968 - update_fcr31();  
1969 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
1970 - DT2 = 0x7fffffffffffffffULL;  
1971 - DEBUG_FPU_STATE();  
1972 - RETURN();  
1973 -}  
1974 -FLOAT_OP(truncl, s)  
1975 -{  
1976 - DT2 = float32_to_int64_round_to_zero(FST0, &env->fp_status);  
1977 - update_fcr31();  
1978 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
1979 - DT2 = 0x7fffffffffffffffULL;  
1980 - DEBUG_FPU_STATE();  
1981 - RETURN();  
1982 -}  
1983 -FLOAT_OP(truncw, d)  
1984 -{  
1985 - WT2 = float64_to_int32_round_to_zero(FDT0, &env->fp_status);  
1986 - update_fcr31();  
1987 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
1988 - WT2 = 0x7fffffff;  
1989 - DEBUG_FPU_STATE();  
1990 - RETURN();  
1991 -}  
1992 -FLOAT_OP(truncw, s)  
1993 -{  
1994 - WT2 = float32_to_int32_round_to_zero(FST0, &env->fp_status);  
1995 - update_fcr31();  
1996 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
1997 - WT2 = 0x7fffffff;  
1998 - DEBUG_FPU_STATE();  
1999 - RETURN();  
2000 -} 1835 +FLOAT_ROUNDOP(round, l, d)
  1836 +FLOAT_ROUNDOP(round, l, s)
  1837 +FLOAT_ROUNDOP(round, w, d)
  1838 +FLOAT_ROUNDOP(round, w, s)
2001 1839
2002 -FLOAT_OP(ceill, d)  
2003 -{  
2004 - set_float_rounding_mode(float_round_up, &env->fp_status);  
2005 - DT2 = float64_round_to_int(FDT0, &env->fp_status);  
2006 - RESTORE_ROUNDING_MODE;  
2007 - update_fcr31();  
2008 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
2009 - DT2 = 0x7fffffffffffffffULL;  
2010 - DEBUG_FPU_STATE();  
2011 - RETURN();  
2012 -}  
2013 -FLOAT_OP(ceill, s)  
2014 -{  
2015 - set_float_rounding_mode(float_round_up, &env->fp_status);  
2016 - DT2 = float32_round_to_int(FST0, &env->fp_status);  
2017 - RESTORE_ROUNDING_MODE;  
2018 - update_fcr31();  
2019 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
2020 - DT2 = 0x7fffffffffffffffULL;  
2021 - DEBUG_FPU_STATE();  
2022 - RETURN();  
2023 -}  
2024 -FLOAT_OP(ceilw, d)  
2025 -{  
2026 - set_float_rounding_mode(float_round_up, &env->fp_status);  
2027 - WT2 = float64_round_to_int(FDT0, &env->fp_status);  
2028 - RESTORE_ROUNDING_MODE;  
2029 - update_fcr31();  
2030 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
2031 - WT2 = 0x7fffffff;  
2032 - DEBUG_FPU_STATE();  
2033 - RETURN();  
2034 -}  
2035 -FLOAT_OP(ceilw, s)  
2036 -{  
2037 - set_float_rounding_mode(float_round_up, &env->fp_status);  
2038 - WT2 = float32_round_to_int(FST0, &env->fp_status);  
2039 - RESTORE_ROUNDING_MODE;  
2040 - update_fcr31();  
2041 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
2042 - WT2 = 0x7fffffff;  
2043 - DEBUG_FPU_STATE();  
2044 - RETURN();  
2045 -} 1840 +FLOAT_ROUNDOP(trunc, l, d)
  1841 +FLOAT_ROUNDOP(trunc, l, s)
  1842 +FLOAT_ROUNDOP(trunc, w, d)
  1843 +FLOAT_ROUNDOP(trunc, w, s)
2046 1844
2047 -FLOAT_OP(floorl, d)  
2048 -{  
2049 - set_float_rounding_mode(float_round_down, &env->fp_status);  
2050 - DT2 = float64_round_to_int(FDT0, &env->fp_status);  
2051 - RESTORE_ROUNDING_MODE;  
2052 - update_fcr31();  
2053 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
2054 - DT2 = 0x7fffffffffffffffULL;  
2055 - DEBUG_FPU_STATE();  
2056 - RETURN();  
2057 -}  
2058 -FLOAT_OP(floorl, s)  
2059 -{  
2060 - set_float_rounding_mode(float_round_down, &env->fp_status);  
2061 - DT2 = float32_round_to_int(FST0, &env->fp_status);  
2062 - RESTORE_ROUNDING_MODE;  
2063 - update_fcr31();  
2064 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
2065 - DT2 = 0x7fffffffffffffffULL;  
2066 - DEBUG_FPU_STATE();  
2067 - RETURN();  
2068 -}  
2069 -FLOAT_OP(floorw, d)  
2070 -{  
2071 - set_float_rounding_mode(float_round_down, &env->fp_status);  
2072 - WT2 = float64_round_to_int(FDT0, &env->fp_status);  
2073 - RESTORE_ROUNDING_MODE;  
2074 - update_fcr31();  
2075 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
2076 - WT2 = 0x7fffffff;  
2077 - DEBUG_FPU_STATE();  
2078 - RETURN();  
2079 -}  
2080 -FLOAT_OP(floorw, s)  
2081 -{  
2082 - set_float_rounding_mode(float_round_down, &env->fp_status);  
2083 - WT2 = float32_round_to_int(FST0, &env->fp_status);  
2084 - RESTORE_ROUNDING_MODE;  
2085 - update_fcr31();  
2086 - if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))  
2087 - WT2 = 0x7fffffff;  
2088 - DEBUG_FPU_STATE();  
2089 - RETURN();  
2090 -} 1845 +FLOAT_ROUNDOP(ceil, l, d)
  1846 +FLOAT_ROUNDOP(ceil, l, s)
  1847 +FLOAT_ROUNDOP(ceil, w, d)
  1848 +FLOAT_ROUNDOP(ceil, w, s)
  1849 +
  1850 +FLOAT_ROUNDOP(floor, l, d)
  1851 +FLOAT_ROUNDOP(floor, l, s)
  1852 +FLOAT_ROUNDOP(floor, w, d)
  1853 +FLOAT_ROUNDOP(floor, w, s)
  1854 +#undef FLOAR_ROUNDOP
2091 1855
2092 FLOAT_OP(movf, d) 1856 FLOAT_OP(movf, d)
2093 { 1857 {
@@ -2186,26 +1950,19 @@ FLOAT_OP(movn, ps) @@ -2186,26 +1950,19 @@ FLOAT_OP(movn, ps)
2186 #define FLOAT_BINOP(name) \ 1950 #define FLOAT_BINOP(name) \
2187 FLOAT_OP(name, d) \ 1951 FLOAT_OP(name, d) \
2188 { \ 1952 { \
2189 - set_float_exception_flags(0, &env->fp_status); \  
2190 - FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status); \  
2191 - update_fcr31(); \ 1953 + CALL_FROM_TB0(do_float_ ## name ## _d); \
2192 DEBUG_FPU_STATE(); \ 1954 DEBUG_FPU_STATE(); \
2193 RETURN(); \ 1955 RETURN(); \
2194 } \ 1956 } \
2195 FLOAT_OP(name, s) \ 1957 FLOAT_OP(name, s) \
2196 { \ 1958 { \
2197 - set_float_exception_flags(0, &env->fp_status); \  
2198 - FST2 = float32_ ## name (FST0, FST1, &env->fp_status); \  
2199 - update_fcr31(); \ 1959 + CALL_FROM_TB0(do_float_ ## name ## _s); \
2200 DEBUG_FPU_STATE(); \ 1960 DEBUG_FPU_STATE(); \
2201 RETURN(); \ 1961 RETURN(); \
2202 } \ 1962 } \
2203 FLOAT_OP(name, ps) \ 1963 FLOAT_OP(name, ps) \
2204 { \ 1964 { \
2205 - set_float_exception_flags(0, &env->fp_status); \  
2206 - FST2 = float32_ ## name (FST0, FST1, &env->fp_status); \  
2207 - FSTH2 = float32_ ## name (FSTH0, FSTH1, &env->fp_status); \  
2208 - update_fcr31(); \ 1965 + CALL_FROM_TB0(do_float_ ## name ## _ps); \
2209 DEBUG_FPU_STATE(); \ 1966 DEBUG_FPU_STATE(); \
2210 RETURN(); \ 1967 RETURN(); \
2211 } 1968 }
@@ -2217,10 +1974,7 @@ FLOAT_BINOP(div) @@ -2217,10 +1974,7 @@ FLOAT_BINOP(div)
2217 1974
2218 FLOAT_OP(addr, ps) 1975 FLOAT_OP(addr, ps)
2219 { 1976 {
2220 - set_float_exception_flags(0, &env->fp_status);  
2221 - FST2 = float32_add (FST0, FSTH0, &env->fp_status);  
2222 - FSTH2 = float32_add (FST1, FSTH1, &env->fp_status);  
2223 - update_fcr31(); 1977 + CALL_FROM_TB0(do_float_addr_ps);
2224 DEBUG_FPU_STATE(); 1978 DEBUG_FPU_STATE();
2225 RETURN(); 1979 RETURN();
2226 } 1980 }
@@ -2390,249 +2144,77 @@ FLOAT_OP(alnv, ps) @@ -2390,249 +2144,77 @@ FLOAT_OP(alnv, ps)
2390 2144
2391 extern void dump_fpu_s(CPUState *env); 2145 extern void dump_fpu_s(CPUState *env);
2392 2146
2393 -#define FOP_COND_D(op, cond) \  
2394 -void op_cmp_d_ ## op (void) \  
2395 -{ \  
2396 - int c = cond; \  
2397 - update_fcr31(); \  
2398 - if (c) \  
2399 - SET_FP_COND(PARAM1, env); \  
2400 - else \  
2401 - CLEAR_FP_COND(PARAM1, env); \  
2402 - DEBUG_FPU_STATE(); \  
2403 - RETURN(); \  
2404 -} \  
2405 -void op_cmpabs_d_ ## op (void) \  
2406 -{ \  
2407 - int c; \  
2408 - FDT0 &= ~(1ULL << 63); \  
2409 - FDT1 &= ~(1ULL << 63); \  
2410 - c = cond; \  
2411 - update_fcr31(); \  
2412 - if (c) \  
2413 - SET_FP_COND(PARAM1, env); \  
2414 - else \  
2415 - CLEAR_FP_COND(PARAM1, env); \  
2416 - DEBUG_FPU_STATE(); \  
2417 - RETURN(); \  
2418 -}  
2419 -  
2420 -int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)  
2421 -{  
2422 - if (float64_is_signaling_nan(a) ||  
2423 - float64_is_signaling_nan(b) ||  
2424 - (sig && (float64_is_nan(a) || float64_is_nan(b)))) {  
2425 - float_raise(float_flag_invalid, status);  
2426 - return 1;  
2427 - } else if (float64_is_nan(a) || float64_is_nan(b)) {  
2428 - return 1;  
2429 - } else {  
2430 - return 0;  
2431 - }  
2432 -}  
2433 -  
2434 -/* NOTE: the comma operator will make "cond" to eval to false,  
2435 - * but float*_is_unordered() is still called. */  
2436 -FOP_COND_D(f, (float64_is_unordered(0, FDT1, FDT0, &env->fp_status), 0))  
2437 -FOP_COND_D(un, float64_is_unordered(0, FDT1, FDT0, &env->fp_status))  
2438 -FOP_COND_D(eq, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_eq(FDT0, FDT1, &env->fp_status))  
2439 -FOP_COND_D(ueq, float64_is_unordered(0, FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))  
2440 -FOP_COND_D(olt, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_lt(FDT0, FDT1, &env->fp_status))  
2441 -FOP_COND_D(ult, float64_is_unordered(0, FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))  
2442 -FOP_COND_D(ole, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_le(FDT0, FDT1, &env->fp_status))  
2443 -FOP_COND_D(ule, float64_is_unordered(0, FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))  
2444 -/* NOTE: the comma operator will make "cond" to eval to false,  
2445 - * but float*_is_unordered() is still called. */  
2446 -FOP_COND_D(sf, (float64_is_unordered(1, FDT1, FDT0, &env->fp_status), 0))  
2447 -FOP_COND_D(ngle,float64_is_unordered(1, FDT1, FDT0, &env->fp_status))  
2448 -FOP_COND_D(seq, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_eq(FDT0, FDT1, &env->fp_status))  
2449 -FOP_COND_D(ngl, float64_is_unordered(1, FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))  
2450 -FOP_COND_D(lt, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_lt(FDT0, FDT1, &env->fp_status))  
2451 -FOP_COND_D(nge, float64_is_unordered(1, FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))  
2452 -FOP_COND_D(le, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_le(FDT0, FDT1, &env->fp_status))  
2453 -FOP_COND_D(ngt, float64_is_unordered(1, FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))  
2454 -  
2455 -#define FOP_COND_S(op, cond) \  
2456 -void op_cmp_s_ ## op (void) \  
2457 -{ \  
2458 - int c = cond; \  
2459 - update_fcr31(); \  
2460 - if (c) \  
2461 - SET_FP_COND(PARAM1, env); \  
2462 - else \  
2463 - CLEAR_FP_COND(PARAM1, env); \  
2464 - DEBUG_FPU_STATE(); \  
2465 - RETURN(); \  
2466 -} \  
2467 -void op_cmpabs_s_ ## op (void) \  
2468 -{ \  
2469 - int c; \  
2470 - FST0 &= ~(1 << 31); \  
2471 - FST1 &= ~(1 << 31); \  
2472 - c = cond; \  
2473 - update_fcr31(); \  
2474 - if (c) \  
2475 - SET_FP_COND(PARAM1, env); \  
2476 - else \  
2477 - CLEAR_FP_COND(PARAM1, env); \  
2478 - DEBUG_FPU_STATE(); \  
2479 - RETURN(); \  
2480 -}  
2481 -  
2482 -flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)  
2483 -{  
2484 - extern flag float32_is_nan(float32 a);  
2485 - if (float32_is_signaling_nan(a) ||  
2486 - float32_is_signaling_nan(b) ||  
2487 - (sig && (float32_is_nan(a) || float32_is_nan(b)))) {  
2488 - float_raise(float_flag_invalid, status);  
2489 - return 1;  
2490 - } else if (float32_is_nan(a) || float32_is_nan(b)) {  
2491 - return 1;  
2492 - } else {  
2493 - return 0;  
2494 - }  
2495 -}  
2496 -  
2497 -/* NOTE: the comma operator will make "cond" to eval to false,  
2498 - * but float*_is_unordered() is still called. */  
2499 -FOP_COND_S(f, (float32_is_unordered(0, FST1, FST0, &env->fp_status), 0))  
2500 -FOP_COND_S(un, float32_is_unordered(0, FST1, FST0, &env->fp_status))  
2501 -FOP_COND_S(eq, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status))  
2502 -FOP_COND_S(ueq, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))  
2503 -FOP_COND_S(olt, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status))  
2504 -FOP_COND_S(ult, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))  
2505 -FOP_COND_S(ole, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status))  
2506 -FOP_COND_S(ule, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))  
2507 -/* NOTE: the comma operator will make "cond" to eval to false,  
2508 - * but float*_is_unordered() is still called. */  
2509 -FOP_COND_S(sf, (float32_is_unordered(1, FST1, FST0, &env->fp_status), 0))  
2510 -FOP_COND_S(ngle,float32_is_unordered(1, FST1, FST0, &env->fp_status))  
2511 -FOP_COND_S(seq, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status))  
2512 -FOP_COND_S(ngl, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))  
2513 -FOP_COND_S(lt, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status))  
2514 -FOP_COND_S(nge, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))  
2515 -FOP_COND_S(le, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status))  
2516 -FOP_COND_S(ngt, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))  
2517 -  
2518 -#define FOP_COND_PS(op, condl, condh) \  
2519 -void op_cmp_ps_ ## op (void) \  
2520 -{ \  
2521 - int cl = condl; \  
2522 - int ch = condh; \  
2523 - update_fcr31(); \  
2524 - if (cl) \  
2525 - SET_FP_COND(PARAM1, env); \  
2526 - else \  
2527 - CLEAR_FP_COND(PARAM1, env); \  
2528 - if (ch) \  
2529 - SET_FP_COND(PARAM1 + 1, env); \  
2530 - else \  
2531 - CLEAR_FP_COND(PARAM1 + 1, env); \  
2532 - DEBUG_FPU_STATE(); \  
2533 - RETURN(); \  
2534 -} \  
2535 -void op_cmpabs_ps_ ## op (void) \  
2536 -{ \  
2537 - int cl, ch; \  
2538 - FST0 &= ~(1 << 31); \  
2539 - FSTH0 &= ~(1 << 31); \  
2540 - FST1 &= ~(1 << 31); \  
2541 - FSTH1 &= ~(1 << 31); \  
2542 - cl = condl; \  
2543 - ch = condh; \  
2544 - update_fcr31(); \  
2545 - if (cl) \  
2546 - SET_FP_COND(PARAM1, env); \  
2547 - else \  
2548 - CLEAR_FP_COND(PARAM1, env); \  
2549 - if (ch) \  
2550 - SET_FP_COND(PARAM1 + 1, env); \  
2551 - else \  
2552 - CLEAR_FP_COND(PARAM1 + 1, env); \  
2553 - DEBUG_FPU_STATE(); \  
2554 - RETURN(); \  
2555 -}  
2556 -  
2557 -/* NOTE: the comma operator will make "cond" to eval to false,  
2558 - * but float*_is_unordered() is still called. */  
2559 -FOP_COND_PS(f, (float32_is_unordered(0, FST1, FST0, &env->fp_status), 0),  
2560 - (float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status), 0))  
2561 -FOP_COND_PS(un, float32_is_unordered(0, FST1, FST0, &env->fp_status),  
2562 - float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status))  
2563 -FOP_COND_PS(eq, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status),  
2564 - !float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_eq(FSTH0, FSTH1, &env->fp_status))  
2565 -FOP_COND_PS(ueq, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status),  
2566 - float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) || float32_eq(FSTH0, FSTH1, &env->fp_status))  
2567 -FOP_COND_PS(olt, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status),  
2568 - !float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_lt(FSTH0, FSTH1, &env->fp_status))  
2569 -FOP_COND_PS(ult, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status),  
2570 - float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) || float32_lt(FSTH0, FSTH1, &env->fp_status))  
2571 -FOP_COND_PS(ole, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status),  
2572 - !float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_le(FSTH0, FSTH1, &env->fp_status))  
2573 -FOP_COND_PS(ule, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status),  
2574 - float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) || float32_le(FSTH0, FSTH1, &env->fp_status))  
2575 -/* NOTE: the comma operator will make "cond" to eval to false,  
2576 - * but float*_is_unordered() is still called. */  
2577 -FOP_COND_PS(sf, (float32_is_unordered(1, FST1, FST0, &env->fp_status), 0),  
2578 - (float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status), 0))  
2579 -FOP_COND_PS(ngle,float32_is_unordered(1, FST1, FST0, &env->fp_status),  
2580 - float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status))  
2581 -FOP_COND_PS(seq, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status),  
2582 - !float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_eq(FSTH0, FSTH1, &env->fp_status))  
2583 -FOP_COND_PS(ngl, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status),  
2584 - float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) || float32_eq(FSTH0, FSTH1, &env->fp_status))  
2585 -FOP_COND_PS(lt, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status),  
2586 - !float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_lt(FSTH0, FSTH1, &env->fp_status))  
2587 -FOP_COND_PS(nge, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status),  
2588 - float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) || float32_lt(FSTH0, FSTH1, &env->fp_status))  
2589 -FOP_COND_PS(le, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status),  
2590 - !float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_le(FSTH0, FSTH1, &env->fp_status))  
2591 -FOP_COND_PS(ngt, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status),  
2592 - float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) || float32_le(FSTH0, FSTH1, &env->fp_status)) 2147 +#define CMP_OP(fmt, op) \
  2148 +void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void) \
  2149 +{ \
  2150 + CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \
  2151 + DEBUG_FPU_STATE(); \
  2152 + RETURN(); \
  2153 +} \
  2154 +void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void) \
  2155 +{ \
  2156 + CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \
  2157 + DEBUG_FPU_STATE(); \
  2158 + RETURN(); \
  2159 +}
  2160 +#define CMP_OPS(op) \
  2161 +CMP_OP(d, op) \
  2162 +CMP_OP(s, op) \
  2163 +CMP_OP(ps, op)
  2164 +
  2165 +CMP_OPS(f)
  2166 +CMP_OPS(un)
  2167 +CMP_OPS(eq)
  2168 +CMP_OPS(ueq)
  2169 +CMP_OPS(olt)
  2170 +CMP_OPS(ult)
  2171 +CMP_OPS(ole)
  2172 +CMP_OPS(ule)
  2173 +CMP_OPS(sf)
  2174 +CMP_OPS(ngle)
  2175 +CMP_OPS(seq)
  2176 +CMP_OPS(ngl)
  2177 +CMP_OPS(lt)
  2178 +CMP_OPS(nge)
  2179 +CMP_OPS(le)
  2180 +CMP_OPS(ngt)
  2181 +#undef CMP_OPS
  2182 +#undef CMP_OP
2593 2183
2594 void op_bc1f (void) 2184 void op_bc1f (void)
2595 { 2185 {
2596 - T0 = !IS_FP_COND_SET(PARAM1, env); 2186 + T0 = !!(~GET_FP_COND(env) & (0x1 << PARAM1));
2597 DEBUG_FPU_STATE(); 2187 DEBUG_FPU_STATE();
2598 RETURN(); 2188 RETURN();
2599 } 2189 }
2600 -void op_bc1fany2 (void) 2190 +void op_bc1any2f (void)
2601 { 2191 {
2602 - T0 = (!IS_FP_COND_SET(PARAM1, env) ||  
2603 - !IS_FP_COND_SET(PARAM1 + 1, env)); 2192 + T0 = !!(~GET_FP_COND(env) & (0x3 << PARAM1));
2604 DEBUG_FPU_STATE(); 2193 DEBUG_FPU_STATE();
2605 RETURN(); 2194 RETURN();
2606 } 2195 }
2607 -void op_bc1fany4 (void) 2196 +void op_bc1any4f (void)
2608 { 2197 {
2609 - T0 = (!IS_FP_COND_SET(PARAM1, env) ||  
2610 - !IS_FP_COND_SET(PARAM1 + 1, env) ||  
2611 - !IS_FP_COND_SET(PARAM1 + 2, env) ||  
2612 - !IS_FP_COND_SET(PARAM1 + 3, env)); 2198 + T0 = !!(~GET_FP_COND(env) & (0xf << PARAM1));
2613 DEBUG_FPU_STATE(); 2199 DEBUG_FPU_STATE();
2614 RETURN(); 2200 RETURN();
2615 } 2201 }
2616 2202
2617 void op_bc1t (void) 2203 void op_bc1t (void)
2618 { 2204 {
2619 - T0 = IS_FP_COND_SET(PARAM1, env); 2205 + T0 = !!(GET_FP_COND(env) & (0x1 << PARAM1));
2620 DEBUG_FPU_STATE(); 2206 DEBUG_FPU_STATE();
2621 RETURN(); 2207 RETURN();
2622 } 2208 }
2623 -void op_bc1tany2 (void) 2209 +void op_bc1any2t (void)
2624 { 2210 {
2625 - T0 = (IS_FP_COND_SET(PARAM1, env) ||  
2626 - IS_FP_COND_SET(PARAM1 + 1, env)); 2211 + T0 = !!(GET_FP_COND(env) & (0x3 << PARAM1));
2627 DEBUG_FPU_STATE(); 2212 DEBUG_FPU_STATE();
2628 RETURN(); 2213 RETURN();
2629 } 2214 }
2630 -void op_bc1tany4 (void) 2215 +void op_bc1any4t (void)
2631 { 2216 {
2632 - T0 = (IS_FP_COND_SET(PARAM1, env) ||  
2633 - IS_FP_COND_SET(PARAM1 + 1, env) ||  
2634 - IS_FP_COND_SET(PARAM1 + 2, env) ||  
2635 - IS_FP_COND_SET(PARAM1 + 3, env)); 2217 + T0 = !!(GET_FP_COND(env) & (0xf << PARAM1));
2636 DEBUG_FPU_STATE(); 2218 DEBUG_FPU_STATE();
2637 RETURN(); 2219 RETURN();
2638 } 2220 }
@@ -2808,17 +2390,6 @@ void op_save_pc (void) @@ -2808,17 +2390,6 @@ void op_save_pc (void)
2808 RETURN(); 2390 RETURN();
2809 } 2391 }
2810 2392
2811 -void op_save_fp_status (void)  
2812 -{  
2813 - union fps {  
2814 - uint32_t i;  
2815 - float_status f;  
2816 - } fps;  
2817 - fps.i = PARAM1;  
2818 - env->fp_status = fps.f;  
2819 - RETURN();  
2820 -}  
2821 -  
2822 void op_interrupt_restart (void) 2393 void op_interrupt_restart (void)
2823 { 2394 {
2824 if (!(env->CP0_Status & (1 << CP0St_EXL)) && 2395 if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
target-mips/op_helper.c
@@ -598,3 +598,544 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) @@ -598,3 +598,544 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
598 } 598 }
599 599
600 #endif 600 #endif
  601 +
  602 +/* Complex FPU operations which may need stack space. */
  603 +
  604 +/* convert MIPS rounding mode in FCR31 to IEEE library */
  605 +unsigned int ieee_rm[] = {
  606 + float_round_nearest_even,
  607 + float_round_to_zero,
  608 + float_round_up,
  609 + float_round_down
  610 +};
  611 +
  612 +#define RESTORE_ROUNDING_MODE \
  613 + set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)
  614 +
  615 +void do_ctc1 (void)
  616 +{
  617 + switch(T1) {
  618 + case 25:
  619 + if (T0 & 0xffffff00)
  620 + return;
  621 + env->fcr31 = (env->fcr31 & 0x017fffff) | ((T0 & 0xfe) << 24) |
  622 + ((T0 & 0x1) << 23);
  623 + break;
  624 + case 26:
  625 + if (T0 & 0x007c0000)
  626 + return;
  627 + env->fcr31 = (env->fcr31 & 0xfffc0f83) | (T0 & 0x0003f07c);
  628 + break;
  629 + case 28:
  630 + if (T0 & 0x007c0000)
  631 + return;
  632 + env->fcr31 = (env->fcr31 & 0xfefff07c) | (T0 & 0x00000f83) |
  633 + ((T0 & 0x4) << 22);
  634 + break;
  635 + case 31:
  636 + if (T0 & 0x007c0000)
  637 + return;
  638 + env->fcr31 = T0;
  639 + break;
  640 + default:
  641 + return;
  642 + }
  643 + /* set rounding mode */
  644 + RESTORE_ROUNDING_MODE;
  645 + set_float_exception_flags(0, &env->fp_status);
  646 + if ((GET_FP_ENABLE(env->fcr31) | 0x20) & GET_FP_CAUSE(env->fcr31))
  647 + do_raise_exception(EXCP_FPE);
  648 +}
  649 +
  650 +inline char ieee_ex_to_mips(char xcpt)
  651 +{
  652 + return (xcpt & float_flag_inexact) >> 5 |
  653 + (xcpt & float_flag_underflow) >> 3 |
  654 + (xcpt & float_flag_overflow) >> 1 |
  655 + (xcpt & float_flag_divbyzero) << 1 |
  656 + (xcpt & float_flag_invalid) << 4;
  657 +}
  658 +
  659 +inline char mips_ex_to_ieee(char xcpt)
  660 +{
  661 + return (xcpt & FP_INEXACT) << 5 |
  662 + (xcpt & FP_UNDERFLOW) << 3 |
  663 + (xcpt & FP_OVERFLOW) << 1 |
  664 + (xcpt & FP_DIV0) >> 1 |
  665 + (xcpt & FP_INVALID) >> 4;
  666 +}
  667 +
  668 +inline void update_fcr31(void)
  669 +{
  670 + int tmp = ieee_ex_to_mips(get_float_exception_flags(&env->fp_status));
  671 +
  672 + SET_FP_CAUSE(env->fcr31, tmp);
  673 + if (GET_FP_ENABLE(env->fcr31) & tmp)
  674 + do_raise_exception(EXCP_FPE);
  675 + else
  676 + UPDATE_FP_FLAGS(env->fcr31, tmp);
  677 +}
  678 +
  679 +#define FLOAT_OP(name, p) void do_float_##name##_##p(void)
  680 +
  681 +FLOAT_OP(cvtd, s)
  682 +{
  683 + set_float_exception_flags(0, &env->fp_status);
  684 + FDT2 = float32_to_float64(FST0, &env->fp_status);
  685 + update_fcr31();
  686 +}
  687 +FLOAT_OP(cvtd, w)
  688 +{
  689 + set_float_exception_flags(0, &env->fp_status);
  690 + FDT2 = int32_to_float64(WT0, &env->fp_status);
  691 + update_fcr31();
  692 +}
  693 +FLOAT_OP(cvtd, l)
  694 +{
  695 + set_float_exception_flags(0, &env->fp_status);
  696 + FDT2 = int64_to_float64(DT0, &env->fp_status);
  697 + update_fcr31();
  698 +}
  699 +FLOAT_OP(cvtl, d)
  700 +{
  701 + set_float_exception_flags(0, &env->fp_status);
  702 + DT2 = float64_to_int64(FDT0, &env->fp_status);
  703 + update_fcr31();
  704 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  705 + DT2 = 0x7fffffffffffffffULL;
  706 +}
  707 +FLOAT_OP(cvtl, s)
  708 +{
  709 + set_float_exception_flags(0, &env->fp_status);
  710 + DT2 = float32_to_int64(FST0, &env->fp_status);
  711 + update_fcr31();
  712 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  713 + DT2 = 0x7fffffffffffffffULL;
  714 +}
  715 +
  716 +FLOAT_OP(cvtps, pw)
  717 +{
  718 + set_float_exception_flags(0, &env->fp_status);
  719 + FST2 = int32_to_float32(WT0, &env->fp_status);
  720 + FSTH2 = int32_to_float32(WTH0, &env->fp_status);
  721 + update_fcr31();
  722 +}
  723 +FLOAT_OP(cvtpw, ps)
  724 +{
  725 + set_float_exception_flags(0, &env->fp_status);
  726 + WT2 = float32_to_int32(FST0, &env->fp_status);
  727 + WTH2 = float32_to_int32(FSTH0, &env->fp_status);
  728 + update_fcr31();
  729 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  730 + WT2 = 0x7fffffff;
  731 +}
  732 +FLOAT_OP(cvts, d)
  733 +{
  734 + set_float_exception_flags(0, &env->fp_status);
  735 + FST2 = float64_to_float32(FDT0, &env->fp_status);
  736 + update_fcr31();
  737 +}
  738 +FLOAT_OP(cvts, w)
  739 +{
  740 + set_float_exception_flags(0, &env->fp_status);
  741 + FST2 = int32_to_float32(WT0, &env->fp_status);
  742 + update_fcr31();
  743 +}
  744 +FLOAT_OP(cvts, l)
  745 +{
  746 + set_float_exception_flags(0, &env->fp_status);
  747 + FST2 = int64_to_float32(DT0, &env->fp_status);
  748 + update_fcr31();
  749 +}
  750 +FLOAT_OP(cvts, pl)
  751 +{
  752 + set_float_exception_flags(0, &env->fp_status);
  753 + WT2 = WT0;
  754 + update_fcr31();
  755 +}
  756 +FLOAT_OP(cvts, pu)
  757 +{
  758 + set_float_exception_flags(0, &env->fp_status);
  759 + WT2 = WTH0;
  760 + update_fcr31();
  761 +}
  762 +FLOAT_OP(cvtw, s)
  763 +{
  764 + set_float_exception_flags(0, &env->fp_status);
  765 + WT2 = float32_to_int32(FST0, &env->fp_status);
  766 + update_fcr31();
  767 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  768 + WT2 = 0x7fffffff;
  769 +}
  770 +FLOAT_OP(cvtw, d)
  771 +{
  772 + set_float_exception_flags(0, &env->fp_status);
  773 + WT2 = float64_to_int32(FDT0, &env->fp_status);
  774 + update_fcr31();
  775 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  776 + WT2 = 0x7fffffff;
  777 +}
  778 +
  779 +FLOAT_OP(roundl, d)
  780 +{
  781 + set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
  782 + DT2 = float64_round_to_int(FDT0, &env->fp_status);
  783 + RESTORE_ROUNDING_MODE;
  784 + update_fcr31();
  785 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  786 + DT2 = 0x7fffffffffffffffULL;
  787 +}
  788 +FLOAT_OP(roundl, s)
  789 +{
  790 + set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
  791 + DT2 = float32_round_to_int(FST0, &env->fp_status);
  792 + RESTORE_ROUNDING_MODE;
  793 + update_fcr31();
  794 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  795 + DT2 = 0x7fffffffffffffffULL;
  796 +}
  797 +FLOAT_OP(roundw, d)
  798 +{
  799 + set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
  800 + WT2 = float64_round_to_int(FDT0, &env->fp_status);
  801 + RESTORE_ROUNDING_MODE;
  802 + update_fcr31();
  803 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  804 + WT2 = 0x7fffffff;
  805 +}
  806 +FLOAT_OP(roundw, s)
  807 +{
  808 + set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
  809 + WT2 = float32_round_to_int(FST0, &env->fp_status);
  810 + RESTORE_ROUNDING_MODE;
  811 + update_fcr31();
  812 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  813 + WT2 = 0x7fffffff;
  814 +}
  815 +
  816 +FLOAT_OP(truncl, d)
  817 +{
  818 + DT2 = float64_to_int64_round_to_zero(FDT0, &env->fp_status);
  819 + update_fcr31();
  820 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  821 + DT2 = 0x7fffffffffffffffULL;
  822 +}
  823 +FLOAT_OP(truncl, s)
  824 +{
  825 + DT2 = float32_to_int64_round_to_zero(FST0, &env->fp_status);
  826 + update_fcr31();
  827 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  828 + DT2 = 0x7fffffffffffffffULL;
  829 +}
  830 +FLOAT_OP(truncw, d)
  831 +{
  832 + WT2 = float64_to_int32_round_to_zero(FDT0, &env->fp_status);
  833 + update_fcr31();
  834 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  835 + WT2 = 0x7fffffff;
  836 +}
  837 +FLOAT_OP(truncw, s)
  838 +{
  839 + WT2 = float32_to_int32_round_to_zero(FST0, &env->fp_status);
  840 + update_fcr31();
  841 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  842 + WT2 = 0x7fffffff;
  843 +}
  844 +
  845 +FLOAT_OP(ceill, d)
  846 +{
  847 + set_float_rounding_mode(float_round_up, &env->fp_status);
  848 + DT2 = float64_round_to_int(FDT0, &env->fp_status);
  849 + RESTORE_ROUNDING_MODE;
  850 + update_fcr31();
  851 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  852 + DT2 = 0x7fffffffffffffffULL;
  853 +}
  854 +FLOAT_OP(ceill, s)
  855 +{
  856 + set_float_rounding_mode(float_round_up, &env->fp_status);
  857 + DT2 = float32_round_to_int(FST0, &env->fp_status);
  858 + RESTORE_ROUNDING_MODE;
  859 + update_fcr31();
  860 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  861 + DT2 = 0x7fffffffffffffffULL;
  862 +}
  863 +FLOAT_OP(ceilw, d)
  864 +{
  865 + set_float_rounding_mode(float_round_up, &env->fp_status);
  866 + WT2 = float64_round_to_int(FDT0, &env->fp_status);
  867 + RESTORE_ROUNDING_MODE;
  868 + update_fcr31();
  869 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  870 + WT2 = 0x7fffffff;
  871 +}
  872 +FLOAT_OP(ceilw, s)
  873 +{
  874 + set_float_rounding_mode(float_round_up, &env->fp_status);
  875 + WT2 = float32_round_to_int(FST0, &env->fp_status);
  876 + RESTORE_ROUNDING_MODE;
  877 + update_fcr31();
  878 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  879 + WT2 = 0x7fffffff;
  880 +}
  881 +
  882 +FLOAT_OP(floorl, d)
  883 +{
  884 + set_float_rounding_mode(float_round_down, &env->fp_status);
  885 + DT2 = float64_round_to_int(FDT0, &env->fp_status);
  886 + RESTORE_ROUNDING_MODE;
  887 + update_fcr31();
  888 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  889 + DT2 = 0x7fffffffffffffffULL;
  890 +}
  891 +FLOAT_OP(floorl, s)
  892 +{
  893 + set_float_rounding_mode(float_round_down, &env->fp_status);
  894 + DT2 = float32_round_to_int(FST0, &env->fp_status);
  895 + RESTORE_ROUNDING_MODE;
  896 + update_fcr31();
  897 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  898 + DT2 = 0x7fffffffffffffffULL;
  899 +}
  900 +FLOAT_OP(floorw, d)
  901 +{
  902 + set_float_rounding_mode(float_round_down, &env->fp_status);
  903 + WT2 = float64_round_to_int(FDT0, &env->fp_status);
  904 + RESTORE_ROUNDING_MODE;
  905 + update_fcr31();
  906 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  907 + WT2 = 0x7fffffff;
  908 +}
  909 +FLOAT_OP(floorw, s)
  910 +{
  911 + set_float_rounding_mode(float_round_down, &env->fp_status);
  912 + WT2 = float32_round_to_int(FST0, &env->fp_status);
  913 + RESTORE_ROUNDING_MODE;
  914 + update_fcr31();
  915 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  916 + WT2 = 0x7fffffff;
  917 +}
  918 +
  919 +/* binary operations */
  920 +#define FLOAT_BINOP(name) \
  921 +FLOAT_OP(name, d) \
  922 +{ \
  923 + set_float_exception_flags(0, &env->fp_status); \
  924 + FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status); \
  925 + update_fcr31(); \
  926 +} \
  927 +FLOAT_OP(name, s) \
  928 +{ \
  929 + set_float_exception_flags(0, &env->fp_status); \
  930 + FST2 = float32_ ## name (FST0, FST1, &env->fp_status); \
  931 + update_fcr31(); \
  932 +} \
  933 +FLOAT_OP(name, ps) \
  934 +{ \
  935 + set_float_exception_flags(0, &env->fp_status); \
  936 + FST2 = float32_ ## name (FST0, FST1, &env->fp_status); \
  937 + FSTH2 = float32_ ## name (FSTH0, FSTH1, &env->fp_status); \
  938 + update_fcr31(); \
  939 +}
  940 +FLOAT_BINOP(add)
  941 +FLOAT_BINOP(sub)
  942 +FLOAT_BINOP(mul)
  943 +FLOAT_BINOP(div)
  944 +#undef FLOAT_BINOP
  945 +
  946 +FLOAT_OP(addr, ps)
  947 +{
  948 + set_float_exception_flags(0, &env->fp_status);
  949 + FST2 = float32_add (FST0, FSTH0, &env->fp_status);
  950 + FSTH2 = float32_add (FST1, FSTH1, &env->fp_status);
  951 + update_fcr31();
  952 +}
  953 +
  954 +#define FOP_COND_D(op, cond) \
  955 +void do_cmp_d_ ## op (long cc) \
  956 +{ \
  957 + int c = cond; \
  958 + update_fcr31(); \
  959 + if (c) \
  960 + SET_FP_COND(cc, env); \
  961 + else \
  962 + CLEAR_FP_COND(cc, env); \
  963 +} \
  964 +void do_cmpabs_d_ ## op (long cc) \
  965 +{ \
  966 + int c; \
  967 + FDT0 &= ~(1ULL << 63); \
  968 + FDT1 &= ~(1ULL << 63); \
  969 + c = cond; \
  970 + update_fcr31(); \
  971 + if (c) \
  972 + SET_FP_COND(cc, env); \
  973 + else \
  974 + CLEAR_FP_COND(cc, env); \
  975 +}
  976 +
  977 +int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
  978 +{
  979 + if (float64_is_signaling_nan(a) ||
  980 + float64_is_signaling_nan(b) ||
  981 + (sig && (float64_is_nan(a) || float64_is_nan(b)))) {
  982 + float_raise(float_flag_invalid, status);
  983 + return 1;
  984 + } else if (float64_is_nan(a) || float64_is_nan(b)) {
  985 + return 1;
  986 + } else {
  987 + return 0;
  988 + }
  989 +}
  990 +
  991 +/* NOTE: the comma operator will make "cond" to eval to false,
  992 + * but float*_is_unordered() is still called. */
  993 +FOP_COND_D(f, (float64_is_unordered(0, FDT1, FDT0, &env->fp_status), 0))
  994 +FOP_COND_D(un, float64_is_unordered(0, FDT1, FDT0, &env->fp_status))
  995 +FOP_COND_D(eq, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_eq(FDT0, FDT1, &env->fp_status))
  996 +FOP_COND_D(ueq, float64_is_unordered(0, FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
  997 +FOP_COND_D(olt, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_lt(FDT0, FDT1, &env->fp_status))
  998 +FOP_COND_D(ult, float64_is_unordered(0, FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
  999 +FOP_COND_D(ole, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_le(FDT0, FDT1, &env->fp_status))
  1000 +FOP_COND_D(ule, float64_is_unordered(0, FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
  1001 +/* NOTE: the comma operator will make "cond" to eval to false,
  1002 + * but float*_is_unordered() is still called. */
  1003 +FOP_COND_D(sf, (float64_is_unordered(1, FDT1, FDT0, &env->fp_status), 0))
  1004 +FOP_COND_D(ngle,float64_is_unordered(1, FDT1, FDT0, &env->fp_status))
  1005 +FOP_COND_D(seq, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_eq(FDT0, FDT1, &env->fp_status))
  1006 +FOP_COND_D(ngl, float64_is_unordered(1, FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
  1007 +FOP_COND_D(lt, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_lt(FDT0, FDT1, &env->fp_status))
  1008 +FOP_COND_D(nge, float64_is_unordered(1, FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
  1009 +FOP_COND_D(le, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_le(FDT0, FDT1, &env->fp_status))
  1010 +FOP_COND_D(ngt, float64_is_unordered(1, FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
  1011 +
  1012 +#define FOP_COND_S(op, cond) \
  1013 +void do_cmp_s_ ## op (long cc) \
  1014 +{ \
  1015 + int c = cond; \
  1016 + update_fcr31(); \
  1017 + if (c) \
  1018 + SET_FP_COND(cc, env); \
  1019 + else \
  1020 + CLEAR_FP_COND(cc, env); \
  1021 +} \
  1022 +void do_cmpabs_s_ ## op (long cc) \
  1023 +{ \
  1024 + int c; \
  1025 + FST0 &= ~(1 << 31); \
  1026 + FST1 &= ~(1 << 31); \
  1027 + c = cond; \
  1028 + update_fcr31(); \
  1029 + if (c) \
  1030 + SET_FP_COND(cc, env); \
  1031 + else \
  1032 + CLEAR_FP_COND(cc, env); \
  1033 +}
  1034 +
  1035 +flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
  1036 +{
  1037 + extern flag float32_is_nan(float32 a);
  1038 + if (float32_is_signaling_nan(a) ||
  1039 + float32_is_signaling_nan(b) ||
  1040 + (sig && (float32_is_nan(a) || float32_is_nan(b)))) {
  1041 + float_raise(float_flag_invalid, status);
  1042 + return 1;
  1043 + } else if (float32_is_nan(a) || float32_is_nan(b)) {
  1044 + return 1;
  1045 + } else {
  1046 + return 0;
  1047 + }
  1048 +}
  1049 +
  1050 +/* NOTE: the comma operator will make "cond" to eval to false,
  1051 + * but float*_is_unordered() is still called. */
  1052 +FOP_COND_S(f, (float32_is_unordered(0, FST1, FST0, &env->fp_status), 0))
  1053 +FOP_COND_S(un, float32_is_unordered(0, FST1, FST0, &env->fp_status))
  1054 +FOP_COND_S(eq, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status))
  1055 +FOP_COND_S(ueq, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
  1056 +FOP_COND_S(olt, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status))
  1057 +FOP_COND_S(ult, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
  1058 +FOP_COND_S(ole, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status))
  1059 +FOP_COND_S(ule, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
  1060 +/* NOTE: the comma operator will make "cond" to eval to false,
  1061 + * but float*_is_unordered() is still called. */
  1062 +FOP_COND_S(sf, (float32_is_unordered(1, FST1, FST0, &env->fp_status), 0))
  1063 +FOP_COND_S(ngle,float32_is_unordered(1, FST1, FST0, &env->fp_status))
  1064 +FOP_COND_S(seq, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status))
  1065 +FOP_COND_S(ngl, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
  1066 +FOP_COND_S(lt, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status))
  1067 +FOP_COND_S(nge, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
  1068 +FOP_COND_S(le, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status))
  1069 +FOP_COND_S(ngt, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
  1070 +
  1071 +#define FOP_COND_PS(op, condl, condh) \
  1072 +void do_cmp_ps_ ## op (long cc) \
  1073 +{ \
  1074 + int cl = condl; \
  1075 + int ch = condh; \
  1076 + update_fcr31(); \
  1077 + if (cl) \
  1078 + SET_FP_COND(cc, env); \
  1079 + else \
  1080 + CLEAR_FP_COND(cc, env); \
  1081 + if (ch) \
  1082 + SET_FP_COND(cc + 1, env); \
  1083 + else \
  1084 + CLEAR_FP_COND(cc + 1, env); \
  1085 +} \
  1086 +void do_cmpabs_ps_ ## op (long cc) \
  1087 +{ \
  1088 + int cl, ch; \
  1089 + FST0 &= ~(1 << 31); \
  1090 + FSTH0 &= ~(1 << 31); \
  1091 + FST1 &= ~(1 << 31); \
  1092 + FSTH1 &= ~(1 << 31); \
  1093 + cl = condl; \
  1094 + ch = condh; \
  1095 + update_fcr31(); \
  1096 + if (cl) \
  1097 + SET_FP_COND(cc, env); \
  1098 + else \
  1099 + CLEAR_FP_COND(cc, env); \
  1100 + if (ch) \
  1101 + SET_FP_COND(cc + 1, env); \
  1102 + else \
  1103 + CLEAR_FP_COND(cc + 1, env); \
  1104 +}
  1105 +
  1106 +/* NOTE: the comma operator will make "cond" to eval to false,
  1107 + * but float*_is_unordered() is still called. */
  1108 +FOP_COND_PS(f, (float32_is_unordered(0, FST1, FST0, &env->fp_status), 0),
  1109 + (float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status), 0))
  1110 +FOP_COND_PS(un, float32_is_unordered(0, FST1, FST0, &env->fp_status),
  1111 + float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status))
  1112 +FOP_COND_PS(eq, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status),
  1113 + !float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_eq(FSTH0, FSTH1, &env->fp_status))
  1114 +FOP_COND_PS(ueq, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status),
  1115 + float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) || float32_eq(FSTH0, FSTH1, &env->fp_status))
  1116 +FOP_COND_PS(olt, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status),
  1117 + !float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_lt(FSTH0, FSTH1, &env->fp_status))
  1118 +FOP_COND_PS(ult, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status),
  1119 + float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) || float32_lt(FSTH0, FSTH1, &env->fp_status))
  1120 +FOP_COND_PS(ole, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status),
  1121 + !float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_le(FSTH0, FSTH1, &env->fp_status))
  1122 +FOP_COND_PS(ule, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status),
  1123 + float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) || float32_le(FSTH0, FSTH1, &env->fp_status))
  1124 +/* NOTE: the comma operator will make "cond" to eval to false,
  1125 + * but float*_is_unordered() is still called. */
  1126 +FOP_COND_PS(sf, (float32_is_unordered(1, FST1, FST0, &env->fp_status), 0),
  1127 + (float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status), 0))
  1128 +FOP_COND_PS(ngle,float32_is_unordered(1, FST1, FST0, &env->fp_status),
  1129 + float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status))
  1130 +FOP_COND_PS(seq, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status),
  1131 + !float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_eq(FSTH0, FSTH1, &env->fp_status))
  1132 +FOP_COND_PS(ngl, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status),
  1133 + float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) || float32_eq(FSTH0, FSTH1, &env->fp_status))
  1134 +FOP_COND_PS(lt, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status),
  1135 + !float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_lt(FSTH0, FSTH1, &env->fp_status))
  1136 +FOP_COND_PS(nge, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status),
  1137 + float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) || float32_lt(FSTH0, FSTH1, &env->fp_status))
  1138 +FOP_COND_PS(le, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status),
  1139 + !float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_le(FSTH0, FSTH1, &env->fp_status))
  1140 +FOP_COND_PS(ngt, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status),
  1141 + float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) || float32_le(FSTH0, FSTH1, &env->fp_status))
target-mips/translate.c
@@ -491,7 +491,7 @@ FGEN32(gen_op_load_fpr_WTH2, gen_op_load_fpr_WTH2_fpr); @@ -491,7 +491,7 @@ FGEN32(gen_op_load_fpr_WTH2, gen_op_load_fpr_WTH2_fpr);
491 FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr); 491 FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
492 492
493 #define FOP_CONDS(type, fmt) \ 493 #define FOP_CONDS(type, fmt) \
494 -static GenOpFunc1 * cond ## type ## _ ## fmt ## _table[16] = { \ 494 +static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = { \
495 gen_op_cmp ## type ## _ ## fmt ## _f, \ 495 gen_op_cmp ## type ## _ ## fmt ## _f, \
496 gen_op_cmp ## type ## _ ## fmt ## _un, \ 496 gen_op_cmp ## type ## _ ## fmt ## _un, \
497 gen_op_cmp ## type ## _ ## fmt ## _eq, \ 497 gen_op_cmp ## type ## _ ## fmt ## _eq, \
@@ -511,7 +511,7 @@ static GenOpFunc1 * cond ## type ## _ ## fmt ## _table[16] = { \ @@ -511,7 +511,7 @@ static GenOpFunc1 * cond ## type ## _ ## fmt ## _table[16] = { \
511 }; \ 511 }; \
512 static inline void gen_cmp ## type ## _ ## fmt(int n, long cc) \ 512 static inline void gen_cmp ## type ## _ ## fmt(int n, long cc) \
513 { \ 513 { \
514 - cond ## type ## _ ## fmt ## _table[n](cc); \ 514 + gen_op_cmp ## type ## _ ## fmt ## _table[n](cc); \
515 } 515 }
516 516
517 FOP_CONDS(, d) 517 FOP_CONDS(, d)
@@ -525,11 +525,10 @@ typedef struct DisasContext { @@ -525,11 +525,10 @@ typedef struct DisasContext {
525 struct TranslationBlock *tb; 525 struct TranslationBlock *tb;
526 target_ulong pc, saved_pc; 526 target_ulong pc, saved_pc;
527 uint32_t opcode; 527 uint32_t opcode;
528 - uint32_t fp_status, saved_fp_status; 528 + uint32_t fp_status;
529 /* Routine used to access memory */ 529 /* Routine used to access memory */
530 int mem_idx; 530 int mem_idx;
531 uint32_t hflags, saved_hflags; 531 uint32_t hflags, saved_hflags;
532 - uint32_t CP0_Status;  
533 int bstate; 532 int bstate;
534 target_ulong btarget; 533 target_ulong btarget;
535 } DisasContext; 534 } DisasContext;
@@ -628,11 +627,21 @@ static inline void save_cpu_state (DisasContext *ctx, int do_save_pc) @@ -628,11 +627,21 @@ static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
628 } 627 }
629 } 628 }
630 629
631 -static inline void save_fpu_state (DisasContext *ctx) 630 +static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
632 { 631 {
633 - if (ctx->fp_status != ctx->saved_fp_status) {  
634 - gen_op_save_fp_status(ctx->fp_status);  
635 - ctx->saved_fp_status = ctx->fp_status; 632 + ctx->saved_hflags = ctx->hflags;
  633 + switch (ctx->hflags & MIPS_HFLAG_BMASK) {
  634 + case MIPS_HFLAG_BR:
  635 + gen_op_restore_breg_target();
  636 + break;
  637 + case MIPS_HFLAG_B:
  638 + ctx->btarget = env->btarget;
  639 + break;
  640 + case MIPS_HFLAG_BC:
  641 + case MIPS_HFLAG_BL:
  642 + ctx->btarget = env->btarget;
  643 + gen_op_restore_bcond();
  644 + break;
636 } 645 }
637 } 646 }
638 647
@@ -4293,20 +4302,20 @@ static void gen_compute_branch1 (DisasContext *ctx, uint32_t op, @@ -4293,20 +4302,20 @@ static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4293 gen_op_save_bcond(); 4302 gen_op_save_bcond();
4294 break; 4303 break;
4295 case OPC_BC1FANY2: 4304 case OPC_BC1FANY2:
4296 - gen_op_bc1fany2(cc);  
4297 - opn = "bc1fany2"; 4305 + gen_op_bc1any2f(cc);
  4306 + opn = "bc1any2f";
4298 goto not_likely; 4307 goto not_likely;
4299 case OPC_BC1TANY2: 4308 case OPC_BC1TANY2:
4300 - gen_op_bc1tany2(cc);  
4301 - opn = "bc1tany2"; 4309 + gen_op_bc1any2t(cc);
  4310 + opn = "bc1any2t";
4302 goto not_likely; 4311 goto not_likely;
4303 case OPC_BC1FANY4: 4312 case OPC_BC1FANY4:
4304 - gen_op_bc1fany4(cc);  
4305 - opn = "bc1fany4"; 4313 + gen_op_bc1any4f(cc);
  4314 + opn = "bc1any4f";
4306 goto not_likely; 4315 goto not_likely;
4307 case OPC_BC1TANY4: 4316 case OPC_BC1TANY4:
4308 - gen_op_bc1tany4(cc);  
4309 - opn = "bc1tany4"; 4317 + gen_op_bc1any4t(cc);
  4318 + opn = "bc1any4t";
4310 not_likely: 4319 not_likely:
4311 ctx->hflags |= MIPS_HFLAG_BC; 4320 ctx->hflags |= MIPS_HFLAG_BC;
4312 gen_op_set_bcond(); 4321 gen_op_set_bcond();
@@ -4323,27 +4332,6 @@ static void gen_compute_branch1 (DisasContext *ctx, uint32_t op, @@ -4323,27 +4332,6 @@ static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4323 4332
4324 /* Coprocessor 1 (FPU) */ 4333 /* Coprocessor 1 (FPU) */
4325 4334
4326 -/* verify if floating point register is valid; an operation is not defined  
4327 - * if bit 0 of any register specification is set and the FR bit in the  
4328 - * Status register equals zero, since the register numbers specify an  
4329 - * even-odd pair of adjacent coprocessor general registers. When the FR bit  
4330 - * in the Status register equals one, both even and odd register numbers  
4331 - * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.  
4332 - *  
4333 - * Multiple 64 bit wide registers can be checked by calling  
4334 - * CHECK_FR(ctx, freg1 | freg2 | ... | fregN);  
4335 - *  
4336 - * FIXME: This is broken for R2, it needs to be checked at runtime, not  
4337 - * at translation time.  
4338 - */  
4339 -#define CHECK_FR(ctx, freg) do { \  
4340 - if (!((ctx)->CP0_Status & (1 << CP0St_FR)) && ((freg) & 1)) { \  
4341 - MIPS_INVAL("FPU mode"); \  
4342 - generate_exception (ctx, EXCP_RI); \  
4343 - return; \  
4344 - } \  
4345 - } while(0)  
4346 -  
4347 #define FOP(func, fmt) (((fmt) << 21) | (func)) 4335 #define FOP(func, fmt) (((fmt) << 21) | (func))
4348 4336
4349 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) 4337 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
@@ -4388,14 +4376,14 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) @@ -4388,14 +4376,14 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4388 opn = "dmtc1"; 4376 opn = "dmtc1";
4389 break; 4377 break;
4390 case OPC_MFHC1: 4378 case OPC_MFHC1:
4391 - CHECK_FR(ctx, fs); 4379 + gen_op_cp1_registers(fs);
4392 GEN_LOAD_FREG_FTN(WTH0, fs); 4380 GEN_LOAD_FREG_FTN(WTH0, fs);
4393 gen_op_mfhc1(); 4381 gen_op_mfhc1();
4394 GEN_STORE_TN_REG(rt, T0); 4382 GEN_STORE_TN_REG(rt, T0);
4395 opn = "mfhc1"; 4383 opn = "mfhc1";
4396 break; 4384 break;
4397 case OPC_MTHC1: 4385 case OPC_MTHC1:
4398 - CHECK_FR(ctx, fs); 4386 + gen_op_cp1_registers(fs);
4399 GEN_LOAD_REG_TN(T0, rt); 4387 GEN_LOAD_REG_TN(T0, rt);
4400 gen_op_mthc1(); 4388 gen_op_mthc1();
4401 GEN_STORE_FTN_FREG(fs, WTH0); 4389 GEN_STORE_FTN_FREG(fs, WTH0);
@@ -4546,28 +4534,28 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4546,28 +4534,28 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4546 opn = "neg.s"; 4534 opn = "neg.s";
4547 break; 4535 break;
4548 case FOP(8, 16): 4536 case FOP(8, 16):
4549 - CHECK_FR(ctx, fs); 4537 + gen_op_cp1_registers(fs);
4550 GEN_LOAD_FREG_FTN(WT0, fs); 4538 GEN_LOAD_FREG_FTN(WT0, fs);
4551 gen_op_float_roundl_s(); 4539 gen_op_float_roundl_s();
4552 GEN_STORE_FTN_FREG(fd, DT2); 4540 GEN_STORE_FTN_FREG(fd, DT2);
4553 opn = "round.l.s"; 4541 opn = "round.l.s";
4554 break; 4542 break;
4555 case FOP(9, 16): 4543 case FOP(9, 16):
4556 - CHECK_FR(ctx, fs); 4544 + gen_op_cp1_registers(fs);
4557 GEN_LOAD_FREG_FTN(WT0, fs); 4545 GEN_LOAD_FREG_FTN(WT0, fs);
4558 gen_op_float_truncl_s(); 4546 gen_op_float_truncl_s();
4559 GEN_STORE_FTN_FREG(fd, DT2); 4547 GEN_STORE_FTN_FREG(fd, DT2);
4560 opn = "trunc.l.s"; 4548 opn = "trunc.l.s";
4561 break; 4549 break;
4562 case FOP(10, 16): 4550 case FOP(10, 16):
4563 - CHECK_FR(ctx, fs); 4551 + gen_op_cp1_registers(fs);
4564 GEN_LOAD_FREG_FTN(WT0, fs); 4552 GEN_LOAD_FREG_FTN(WT0, fs);
4565 gen_op_float_ceill_s(); 4553 gen_op_float_ceill_s();
4566 GEN_STORE_FTN_FREG(fd, DT2); 4554 GEN_STORE_FTN_FREG(fd, DT2);
4567 opn = "ceil.l.s"; 4555 opn = "ceil.l.s";
4568 break; 4556 break;
4569 case FOP(11, 16): 4557 case FOP(11, 16):
4570 - CHECK_FR(ctx, fs); 4558 + gen_op_cp1_registers(fs);
4571 GEN_LOAD_FREG_FTN(WT0, fs); 4559 GEN_LOAD_FREG_FTN(WT0, fs);
4572 gen_op_float_floorl_s(); 4560 gen_op_float_floorl_s();
4573 GEN_STORE_FTN_FREG(fd, DT2); 4561 GEN_STORE_FTN_FREG(fd, DT2);
@@ -4622,7 +4610,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4622,7 +4610,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4622 opn = "movn.s"; 4610 opn = "movn.s";
4623 break; 4611 break;
4624 case FOP(33, 16): 4612 case FOP(33, 16):
4625 - CHECK_FR(ctx, fd); 4613 + gen_op_cp1_registers(fd);
4626 GEN_LOAD_FREG_FTN(WT0, fs); 4614 GEN_LOAD_FREG_FTN(WT0, fs);
4627 gen_op_float_cvtd_s(); 4615 gen_op_float_cvtd_s();
4628 GEN_STORE_FTN_FREG(fd, DT2); 4616 GEN_STORE_FTN_FREG(fd, DT2);
@@ -4635,14 +4623,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4635,14 +4623,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4635 opn = "cvt.w.s"; 4623 opn = "cvt.w.s";
4636 break; 4624 break;
4637 case FOP(37, 16): 4625 case FOP(37, 16):
4638 - CHECK_FR(ctx, fs | fd); 4626 + gen_op_cp1_registers(fs | fd);
4639 GEN_LOAD_FREG_FTN(WT0, fs); 4627 GEN_LOAD_FREG_FTN(WT0, fs);
4640 gen_op_float_cvtl_s(); 4628 gen_op_float_cvtl_s();
4641 GEN_STORE_FTN_FREG(fd, DT2); 4629 GEN_STORE_FTN_FREG(fd, DT2);
4642 opn = "cvt.l.s"; 4630 opn = "cvt.l.s";
4643 break; 4631 break;
4644 case FOP(38, 16): 4632 case FOP(38, 16):
4645 - CHECK_FR(ctx, fs | ft | fd); 4633 + gen_op_cp1_registers(fs | ft | fd);
4646 GEN_LOAD_FREG_FTN(WT1, fs); 4634 GEN_LOAD_FREG_FTN(WT1, fs);
4647 GEN_LOAD_FREG_FTN(WT0, ft); 4635 GEN_LOAD_FREG_FTN(WT0, ft);
4648 gen_op_float_cvtps_s(); 4636 gen_op_float_cvtps_s();
@@ -4676,7 +4664,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4676,7 +4664,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4676 } 4664 }
4677 break; 4665 break;
4678 case FOP(0, 17): 4666 case FOP(0, 17):
4679 - CHECK_FR(ctx, fs | ft | fd); 4667 + gen_op_cp1_registers(fs | ft | fd);
4680 GEN_LOAD_FREG_FTN(DT0, fs); 4668 GEN_LOAD_FREG_FTN(DT0, fs);
4681 GEN_LOAD_FREG_FTN(DT1, ft); 4669 GEN_LOAD_FREG_FTN(DT1, ft);
4682 gen_op_float_add_d(); 4670 gen_op_float_add_d();
@@ -4685,7 +4673,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4685,7 +4673,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4685 optype = BINOP; 4673 optype = BINOP;
4686 break; 4674 break;
4687 case FOP(1, 17): 4675 case FOP(1, 17):
4688 - CHECK_FR(ctx, fs | ft | fd); 4676 + gen_op_cp1_registers(fs | ft | fd);
4689 GEN_LOAD_FREG_FTN(DT0, fs); 4677 GEN_LOAD_FREG_FTN(DT0, fs);
4690 GEN_LOAD_FREG_FTN(DT1, ft); 4678 GEN_LOAD_FREG_FTN(DT1, ft);
4691 gen_op_float_sub_d(); 4679 gen_op_float_sub_d();
@@ -4694,7 +4682,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4694,7 +4682,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4694 optype = BINOP; 4682 optype = BINOP;
4695 break; 4683 break;
4696 case FOP(2, 17): 4684 case FOP(2, 17):
4697 - CHECK_FR(ctx, fs | ft | fd); 4685 + gen_op_cp1_registers(fs | ft | fd);
4698 GEN_LOAD_FREG_FTN(DT0, fs); 4686 GEN_LOAD_FREG_FTN(DT0, fs);
4699 GEN_LOAD_FREG_FTN(DT1, ft); 4687 GEN_LOAD_FREG_FTN(DT1, ft);
4700 gen_op_float_mul_d(); 4688 gen_op_float_mul_d();
@@ -4703,7 +4691,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4703,7 +4691,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4703 optype = BINOP; 4691 optype = BINOP;
4704 break; 4692 break;
4705 case FOP(3, 17): 4693 case FOP(3, 17):
4706 - CHECK_FR(ctx, fs | ft | fd); 4694 + gen_op_cp1_registers(fs | ft | fd);
4707 GEN_LOAD_FREG_FTN(DT0, fs); 4695 GEN_LOAD_FREG_FTN(DT0, fs);
4708 GEN_LOAD_FREG_FTN(DT1, ft); 4696 GEN_LOAD_FREG_FTN(DT1, ft);
4709 gen_op_float_div_d(); 4697 gen_op_float_div_d();
@@ -4712,84 +4700,84 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4712,84 +4700,84 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4712 optype = BINOP; 4700 optype = BINOP;
4713 break; 4701 break;
4714 case FOP(4, 17): 4702 case FOP(4, 17):
4715 - CHECK_FR(ctx, fs | fd); 4703 + gen_op_cp1_registers(fs | fd);
4716 GEN_LOAD_FREG_FTN(DT0, fs); 4704 GEN_LOAD_FREG_FTN(DT0, fs);
4717 gen_op_float_sqrt_d(); 4705 gen_op_float_sqrt_d();
4718 GEN_STORE_FTN_FREG(fd, DT2); 4706 GEN_STORE_FTN_FREG(fd, DT2);
4719 opn = "sqrt.d"; 4707 opn = "sqrt.d";
4720 break; 4708 break;
4721 case FOP(5, 17): 4709 case FOP(5, 17):
4722 - CHECK_FR(ctx, fs | fd); 4710 + gen_op_cp1_registers(fs | fd);
4723 GEN_LOAD_FREG_FTN(DT0, fs); 4711 GEN_LOAD_FREG_FTN(DT0, fs);
4724 gen_op_float_abs_d(); 4712 gen_op_float_abs_d();
4725 GEN_STORE_FTN_FREG(fd, DT2); 4713 GEN_STORE_FTN_FREG(fd, DT2);
4726 opn = "abs.d"; 4714 opn = "abs.d";
4727 break; 4715 break;
4728 case FOP(6, 17): 4716 case FOP(6, 17):
4729 - CHECK_FR(ctx, fs | fd); 4717 + gen_op_cp1_registers(fs | fd);
4730 GEN_LOAD_FREG_FTN(DT0, fs); 4718 GEN_LOAD_FREG_FTN(DT0, fs);
4731 gen_op_float_mov_d(); 4719 gen_op_float_mov_d();
4732 GEN_STORE_FTN_FREG(fd, DT2); 4720 GEN_STORE_FTN_FREG(fd, DT2);
4733 opn = "mov.d"; 4721 opn = "mov.d";
4734 break; 4722 break;
4735 case FOP(7, 17): 4723 case FOP(7, 17):
4736 - CHECK_FR(ctx, fs | fd); 4724 + gen_op_cp1_registers(fs | fd);
4737 GEN_LOAD_FREG_FTN(DT0, fs); 4725 GEN_LOAD_FREG_FTN(DT0, fs);
4738 gen_op_float_chs_d(); 4726 gen_op_float_chs_d();
4739 GEN_STORE_FTN_FREG(fd, DT2); 4727 GEN_STORE_FTN_FREG(fd, DT2);
4740 opn = "neg.d"; 4728 opn = "neg.d";
4741 break; 4729 break;
4742 case FOP(8, 17): 4730 case FOP(8, 17):
4743 - CHECK_FR(ctx, fs); 4731 + gen_op_cp1_registers(fs);
4744 GEN_LOAD_FREG_FTN(DT0, fs); 4732 GEN_LOAD_FREG_FTN(DT0, fs);
4745 gen_op_float_roundl_d(); 4733 gen_op_float_roundl_d();
4746 GEN_STORE_FTN_FREG(fd, DT2); 4734 GEN_STORE_FTN_FREG(fd, DT2);
4747 opn = "round.l.d"; 4735 opn = "round.l.d";
4748 break; 4736 break;
4749 case FOP(9, 17): 4737 case FOP(9, 17):
4750 - CHECK_FR(ctx, fs); 4738 + gen_op_cp1_registers(fs);
4751 GEN_LOAD_FREG_FTN(DT0, fs); 4739 GEN_LOAD_FREG_FTN(DT0, fs);
4752 gen_op_float_truncl_d(); 4740 gen_op_float_truncl_d();
4753 GEN_STORE_FTN_FREG(fd, DT2); 4741 GEN_STORE_FTN_FREG(fd, DT2);
4754 opn = "trunc.l.d"; 4742 opn = "trunc.l.d";
4755 break; 4743 break;
4756 case FOP(10, 17): 4744 case FOP(10, 17):
4757 - CHECK_FR(ctx, fs); 4745 + gen_op_cp1_registers(fs);
4758 GEN_LOAD_FREG_FTN(DT0, fs); 4746 GEN_LOAD_FREG_FTN(DT0, fs);
4759 gen_op_float_ceill_d(); 4747 gen_op_float_ceill_d();
4760 GEN_STORE_FTN_FREG(fd, DT2); 4748 GEN_STORE_FTN_FREG(fd, DT2);
4761 opn = "ceil.l.d"; 4749 opn = "ceil.l.d";
4762 break; 4750 break;
4763 case FOP(11, 17): 4751 case FOP(11, 17):
4764 - CHECK_FR(ctx, fs); 4752 + gen_op_cp1_registers(fs);
4765 GEN_LOAD_FREG_FTN(DT0, fs); 4753 GEN_LOAD_FREG_FTN(DT0, fs);
4766 gen_op_float_floorl_d(); 4754 gen_op_float_floorl_d();
4767 GEN_STORE_FTN_FREG(fd, DT2); 4755 GEN_STORE_FTN_FREG(fd, DT2);
4768 opn = "floor.l.d"; 4756 opn = "floor.l.d";
4769 break; 4757 break;
4770 case FOP(12, 17): 4758 case FOP(12, 17):
4771 - CHECK_FR(ctx, fs); 4759 + gen_op_cp1_registers(fs);
4772 GEN_LOAD_FREG_FTN(DT0, fs); 4760 GEN_LOAD_FREG_FTN(DT0, fs);
4773 gen_op_float_roundw_d(); 4761 gen_op_float_roundw_d();
4774 GEN_STORE_FTN_FREG(fd, WT2); 4762 GEN_STORE_FTN_FREG(fd, WT2);
4775 opn = "round.w.d"; 4763 opn = "round.w.d";
4776 break; 4764 break;
4777 case FOP(13, 17): 4765 case FOP(13, 17):
4778 - CHECK_FR(ctx, fs); 4766 + gen_op_cp1_registers(fs);
4779 GEN_LOAD_FREG_FTN(DT0, fs); 4767 GEN_LOAD_FREG_FTN(DT0, fs);
4780 gen_op_float_truncw_d(); 4768 gen_op_float_truncw_d();
4781 GEN_STORE_FTN_FREG(fd, WT2); 4769 GEN_STORE_FTN_FREG(fd, WT2);
4782 opn = "trunc.w.d"; 4770 opn = "trunc.w.d";
4783 break; 4771 break;
4784 case FOP(14, 17): 4772 case FOP(14, 17):
4785 - CHECK_FR(ctx, fs); 4773 + gen_op_cp1_registers(fs);
4786 GEN_LOAD_FREG_FTN(DT0, fs); 4774 GEN_LOAD_FREG_FTN(DT0, fs);
4787 gen_op_float_ceilw_d(); 4775 gen_op_float_ceilw_d();
4788 GEN_STORE_FTN_FREG(fd, WT2); 4776 GEN_STORE_FTN_FREG(fd, WT2);
4789 opn = "ceil.w.d"; 4777 opn = "ceil.w.d";
4790 break; 4778 break;
4791 case FOP(15, 17): 4779 case FOP(15, 17):
4792 - CHECK_FR(ctx, fs); 4780 + gen_op_cp1_registers(fs);
4793 GEN_LOAD_FREG_FTN(DT0, fs); 4781 GEN_LOAD_FREG_FTN(DT0, fs);
4794 gen_op_float_floorw_d(); 4782 gen_op_float_floorw_d();
4795 GEN_STORE_FTN_FREG(fd, WT2); 4783 GEN_STORE_FTN_FREG(fd, WT2);
@@ -4835,7 +4823,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4835,7 +4823,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4835 case FOP(61, 17): 4823 case FOP(61, 17):
4836 case FOP(62, 17): 4824 case FOP(62, 17):
4837 case FOP(63, 17): 4825 case FOP(63, 17):
4838 - CHECK_FR(ctx, fs | ft); 4826 + gen_op_cp1_registers(fs | ft);
4839 GEN_LOAD_FREG_FTN(DT0, fs); 4827 GEN_LOAD_FREG_FTN(DT0, fs);
4840 GEN_LOAD_FREG_FTN(DT1, ft); 4828 GEN_LOAD_FREG_FTN(DT1, ft);
4841 if (ctx->opcode & (1 << 6)) { 4829 if (ctx->opcode & (1 << 6)) {
@@ -4847,21 +4835,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4847,21 +4835,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4847 } 4835 }
4848 break; 4836 break;
4849 case FOP(32, 17): 4837 case FOP(32, 17):
4850 - CHECK_FR(ctx, fs); 4838 + gen_op_cp1_registers(fs);
4851 GEN_LOAD_FREG_FTN(DT0, fs); 4839 GEN_LOAD_FREG_FTN(DT0, fs);
4852 gen_op_float_cvts_d(); 4840 gen_op_float_cvts_d();
4853 GEN_STORE_FTN_FREG(fd, WT2); 4841 GEN_STORE_FTN_FREG(fd, WT2);
4854 opn = "cvt.s.d"; 4842 opn = "cvt.s.d";
4855 break; 4843 break;
4856 case FOP(36, 17): 4844 case FOP(36, 17):
4857 - CHECK_FR(ctx, fs); 4845 + gen_op_cp1_registers(fs);
4858 GEN_LOAD_FREG_FTN(DT0, fs); 4846 GEN_LOAD_FREG_FTN(DT0, fs);
4859 gen_op_float_cvtw_d(); 4847 gen_op_float_cvtw_d();
4860 GEN_STORE_FTN_FREG(fd, WT2); 4848 GEN_STORE_FTN_FREG(fd, WT2);
4861 opn = "cvt.w.d"; 4849 opn = "cvt.w.d";
4862 break; 4850 break;
4863 case FOP(37, 17): 4851 case FOP(37, 17):
4864 - CHECK_FR(ctx, fs | fd); 4852 + gen_op_cp1_registers(fs | fd);
4865 GEN_LOAD_FREG_FTN(DT0, fs); 4853 GEN_LOAD_FREG_FTN(DT0, fs);
4866 gen_op_float_cvtl_d(); 4854 gen_op_float_cvtl_d();
4867 GEN_STORE_FTN_FREG(fd, DT2); 4855 GEN_STORE_FTN_FREG(fd, DT2);
@@ -4874,21 +4862,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4874,21 +4862,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4874 opn = "cvt.s.w"; 4862 opn = "cvt.s.w";
4875 break; 4863 break;
4876 case FOP(33, 20): 4864 case FOP(33, 20):
4877 - CHECK_FR(ctx, fd); 4865 + gen_op_cp1_registers(fd);
4878 GEN_LOAD_FREG_FTN(WT0, fs); 4866 GEN_LOAD_FREG_FTN(WT0, fs);
4879 gen_op_float_cvtd_w(); 4867 gen_op_float_cvtd_w();
4880 GEN_STORE_FTN_FREG(fd, DT2); 4868 GEN_STORE_FTN_FREG(fd, DT2);
4881 opn = "cvt.d.w"; 4869 opn = "cvt.d.w";
4882 break; 4870 break;
4883 case FOP(32, 21): 4871 case FOP(32, 21):
4884 - CHECK_FR(ctx, fs); 4872 + gen_op_cp1_registers(fs);
4885 GEN_LOAD_FREG_FTN(DT0, fs); 4873 GEN_LOAD_FREG_FTN(DT0, fs);
4886 gen_op_float_cvts_l(); 4874 gen_op_float_cvts_l();
4887 GEN_STORE_FTN_FREG(fd, WT2); 4875 GEN_STORE_FTN_FREG(fd, WT2);
4888 opn = "cvt.s.l"; 4876 opn = "cvt.s.l";
4889 break; 4877 break;
4890 case FOP(33, 21): 4878 case FOP(33, 21):
4891 - CHECK_FR(ctx, fs | fd); 4879 + gen_op_cp1_registers(fs | fd);
4892 GEN_LOAD_FREG_FTN(DT0, fs); 4880 GEN_LOAD_FREG_FTN(DT0, fs);
4893 gen_op_float_cvtd_l(); 4881 gen_op_float_cvtd_l();
4894 GEN_STORE_FTN_FREG(fd, DT2); 4882 GEN_STORE_FTN_FREG(fd, DT2);
@@ -4896,7 +4884,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4896,7 +4884,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4896 break; 4884 break;
4897 case FOP(38, 20): 4885 case FOP(38, 20):
4898 case FOP(38, 21): 4886 case FOP(38, 21):
4899 - CHECK_FR(ctx, fs | fd); 4887 + gen_op_cp1_registers(fs | fd);
4900 GEN_LOAD_FREG_FTN(WT0, fs); 4888 GEN_LOAD_FREG_FTN(WT0, fs);
4901 GEN_LOAD_FREG_FTN(WTH0, fs); 4889 GEN_LOAD_FREG_FTN(WTH0, fs);
4902 gen_op_float_cvtps_pw(); 4890 gen_op_float_cvtps_pw();
@@ -4905,7 +4893,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4905,7 +4893,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4905 opn = "cvt.ps.pw"; 4893 opn = "cvt.ps.pw";
4906 break; 4894 break;
4907 case FOP(0, 22): 4895 case FOP(0, 22):
4908 - CHECK_FR(ctx, fs | ft | fd); 4896 + gen_op_cp1_registers(fs | ft | fd);
4909 GEN_LOAD_FREG_FTN(WT0, fs); 4897 GEN_LOAD_FREG_FTN(WT0, fs);
4910 GEN_LOAD_FREG_FTN(WTH0, fs); 4898 GEN_LOAD_FREG_FTN(WTH0, fs);
4911 GEN_LOAD_FREG_FTN(WT1, ft); 4899 GEN_LOAD_FREG_FTN(WT1, ft);
@@ -4916,7 +4904,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4916,7 +4904,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4916 opn = "add.ps"; 4904 opn = "add.ps";
4917 break; 4905 break;
4918 case FOP(1, 22): 4906 case FOP(1, 22):
4919 - CHECK_FR(ctx, fs | ft | fd); 4907 + gen_op_cp1_registers(fs | ft | fd);
4920 GEN_LOAD_FREG_FTN(WT0, fs); 4908 GEN_LOAD_FREG_FTN(WT0, fs);
4921 GEN_LOAD_FREG_FTN(WTH0, fs); 4909 GEN_LOAD_FREG_FTN(WTH0, fs);
4922 GEN_LOAD_FREG_FTN(WT1, ft); 4910 GEN_LOAD_FREG_FTN(WT1, ft);
@@ -4927,7 +4915,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4927,7 +4915,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4927 opn = "sub.ps"; 4915 opn = "sub.ps";
4928 break; 4916 break;
4929 case FOP(2, 22): 4917 case FOP(2, 22):
4930 - CHECK_FR(ctx, fs | ft | fd); 4918 + gen_op_cp1_registers(fs | ft | fd);
4931 GEN_LOAD_FREG_FTN(WT0, fs); 4919 GEN_LOAD_FREG_FTN(WT0, fs);
4932 GEN_LOAD_FREG_FTN(WTH0, fs); 4920 GEN_LOAD_FREG_FTN(WTH0, fs);
4933 GEN_LOAD_FREG_FTN(WT1, ft); 4921 GEN_LOAD_FREG_FTN(WT1, ft);
@@ -4938,7 +4926,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4938,7 +4926,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4938 opn = "mul.ps"; 4926 opn = "mul.ps";
4939 break; 4927 break;
4940 case FOP(5, 22): 4928 case FOP(5, 22):
4941 - CHECK_FR(ctx, fs | fd); 4929 + gen_op_cp1_registers(fs | fd);
4942 GEN_LOAD_FREG_FTN(WT0, fs); 4930 GEN_LOAD_FREG_FTN(WT0, fs);
4943 GEN_LOAD_FREG_FTN(WTH0, fs); 4931 GEN_LOAD_FREG_FTN(WTH0, fs);
4944 gen_op_float_abs_ps(); 4932 gen_op_float_abs_ps();
@@ -4947,7 +4935,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4947,7 +4935,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4947 opn = "abs.ps"; 4935 opn = "abs.ps";
4948 break; 4936 break;
4949 case FOP(6, 22): 4937 case FOP(6, 22):
4950 - CHECK_FR(ctx, fs | fd); 4938 + gen_op_cp1_registers(fs | fd);
4951 GEN_LOAD_FREG_FTN(WT0, fs); 4939 GEN_LOAD_FREG_FTN(WT0, fs);
4952 GEN_LOAD_FREG_FTN(WTH0, fs); 4940 GEN_LOAD_FREG_FTN(WTH0, fs);
4953 gen_op_float_mov_ps(); 4941 gen_op_float_mov_ps();
@@ -4956,7 +4944,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4956,7 +4944,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4956 opn = "mov.ps"; 4944 opn = "mov.ps";
4957 break; 4945 break;
4958 case FOP(7, 22): 4946 case FOP(7, 22):
4959 - CHECK_FR(ctx, fs | fd); 4947 + gen_op_cp1_registers(fs | fd);
4960 GEN_LOAD_FREG_FTN(WT0, fs); 4948 GEN_LOAD_FREG_FTN(WT0, fs);
4961 GEN_LOAD_FREG_FTN(WTH0, fs); 4949 GEN_LOAD_FREG_FTN(WTH0, fs);
4962 gen_op_float_chs_ps(); 4950 gen_op_float_chs_ps();
@@ -4998,7 +4986,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4998,7 +4986,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4998 opn = "movn.ps"; 4986 opn = "movn.ps";
4999 break; 4987 break;
5000 case FOP(24, 22): 4988 case FOP(24, 22):
5001 - CHECK_FR(ctx, fs | fd | ft); 4989 + gen_op_cp1_registers(fs | fd | ft);
5002 GEN_LOAD_FREG_FTN(WT0, fs); 4990 GEN_LOAD_FREG_FTN(WT0, fs);
5003 GEN_LOAD_FREG_FTN(WTH0, fs); 4991 GEN_LOAD_FREG_FTN(WTH0, fs);
5004 GEN_LOAD_FREG_FTN(WT1, ft); 4992 GEN_LOAD_FREG_FTN(WT1, ft);
@@ -5009,14 +4997,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -5009,14 +4997,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
5009 opn = "addr.ps"; 4997 opn = "addr.ps";
5010 break; 4998 break;
5011 case FOP(32, 22): 4999 case FOP(32, 22):
5012 - CHECK_FR(ctx, fs); 5000 + gen_op_cp1_registers(fs);
5013 GEN_LOAD_FREG_FTN(WTH0, fs); 5001 GEN_LOAD_FREG_FTN(WTH0, fs);
5014 gen_op_float_cvts_pu(); 5002 gen_op_float_cvts_pu();
5015 GEN_STORE_FTN_FREG(fd, WT2); 5003 GEN_STORE_FTN_FREG(fd, WT2);
5016 opn = "cvt.s.pu"; 5004 opn = "cvt.s.pu";
5017 break; 5005 break;
5018 case FOP(36, 22): 5006 case FOP(36, 22):
5019 - CHECK_FR(ctx, fs | fd); 5007 + gen_op_cp1_registers(fs | fd);
5020 GEN_LOAD_FREG_FTN(WT0, fs); 5008 GEN_LOAD_FREG_FTN(WT0, fs);
5021 GEN_LOAD_FREG_FTN(WTH0, fs); 5009 GEN_LOAD_FREG_FTN(WTH0, fs);
5022 gen_op_float_cvtpw_ps(); 5010 gen_op_float_cvtpw_ps();
@@ -5025,14 +5013,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -5025,14 +5013,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
5025 opn = "cvt.pw.ps"; 5013 opn = "cvt.pw.ps";
5026 break; 5014 break;
5027 case FOP(40, 22): 5015 case FOP(40, 22):
5028 - CHECK_FR(ctx, fs); 5016 + gen_op_cp1_registers(fs);
5029 GEN_LOAD_FREG_FTN(WT0, fs); 5017 GEN_LOAD_FREG_FTN(WT0, fs);
5030 gen_op_float_cvts_pl(); 5018 gen_op_float_cvts_pl();
5031 GEN_STORE_FTN_FREG(fd, WT2); 5019 GEN_STORE_FTN_FREG(fd, WT2);
5032 opn = "cvt.s.pl"; 5020 opn = "cvt.s.pl";
5033 break; 5021 break;
5034 case FOP(44, 22): 5022 case FOP(44, 22):
5035 - CHECK_FR(ctx, fs | ft | fd); 5023 + gen_op_cp1_registers(fs | ft | fd);
5036 GEN_LOAD_FREG_FTN(WT0, fs); 5024 GEN_LOAD_FREG_FTN(WT0, fs);
5037 GEN_LOAD_FREG_FTN(WT1, ft); 5025 GEN_LOAD_FREG_FTN(WT1, ft);
5038 gen_op_float_pll_ps(); 5026 gen_op_float_pll_ps();
@@ -5040,7 +5028,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -5040,7 +5028,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
5040 opn = "pll.ps"; 5028 opn = "pll.ps";
5041 break; 5029 break;
5042 case FOP(45, 22): 5030 case FOP(45, 22):
5043 - CHECK_FR(ctx, fs | ft | fd); 5031 + gen_op_cp1_registers(fs | ft | fd);
5044 GEN_LOAD_FREG_FTN(WT0, fs); 5032 GEN_LOAD_FREG_FTN(WT0, fs);
5045 GEN_LOAD_FREG_FTN(WTH1, ft); 5033 GEN_LOAD_FREG_FTN(WTH1, ft);
5046 gen_op_float_plu_ps(); 5034 gen_op_float_plu_ps();
@@ -5048,7 +5036,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -5048,7 +5036,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
5048 opn = "plu.ps"; 5036 opn = "plu.ps";
5049 break; 5037 break;
5050 case FOP(46, 22): 5038 case FOP(46, 22):
5051 - CHECK_FR(ctx, fs | ft | fd); 5039 + gen_op_cp1_registers(fs | ft | fd);
5052 GEN_LOAD_FREG_FTN(WTH0, fs); 5040 GEN_LOAD_FREG_FTN(WTH0, fs);
5053 GEN_LOAD_FREG_FTN(WT1, ft); 5041 GEN_LOAD_FREG_FTN(WT1, ft);
5054 gen_op_float_pul_ps(); 5042 gen_op_float_pul_ps();
@@ -5056,7 +5044,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -5056,7 +5044,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
5056 opn = "pul.ps"; 5044 opn = "pul.ps";
5057 break; 5045 break;
5058 case FOP(47, 22): 5046 case FOP(47, 22):
5059 - CHECK_FR(ctx, fs | ft | fd); 5047 + gen_op_cp1_registers(fs | ft | fd);
5060 GEN_LOAD_FREG_FTN(WTH0, fs); 5048 GEN_LOAD_FREG_FTN(WTH0, fs);
5061 GEN_LOAD_FREG_FTN(WTH1, ft); 5049 GEN_LOAD_FREG_FTN(WTH1, ft);
5062 gen_op_float_puu_ps(); 5050 gen_op_float_puu_ps();
@@ -5079,7 +5067,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -5079,7 +5067,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
5079 case FOP(61, 22): 5067 case FOP(61, 22):
5080 case FOP(62, 22): 5068 case FOP(62, 22):
5081 case FOP(63, 22): 5069 case FOP(63, 22):
5082 - CHECK_FR(ctx, fs | ft); 5070 + gen_op_cp1_registers(fs | ft);
5083 GEN_LOAD_FREG_FTN(WT0, fs); 5071 GEN_LOAD_FREG_FTN(WT0, fs);
5084 GEN_LOAD_FREG_FTN(WTH0, fs); 5072 GEN_LOAD_FREG_FTN(WTH0, fs);
5085 GEN_LOAD_FREG_FTN(WT1, ft); 5073 GEN_LOAD_FREG_FTN(WT1, ft);
@@ -5166,7 +5154,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd, @@ -5166,7 +5154,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
5166 const char *opn = "flt3_arith"; 5154 const char *opn = "flt3_arith";
5167 5155
5168 /* All of those work only on 64bit FPUs. */ 5156 /* All of those work only on 64bit FPUs. */
5169 - CHECK_FR(ctx, fd | fr | fs | ft); 5157 + gen_op_cp1_registers(fd | fr | fs | ft);
5170 switch (opc) { 5158 switch (opc) {
5171 case OPC_ALNV_PS: 5159 case OPC_ALNV_PS:
5172 GEN_LOAD_REG_TN(T0, fr); 5160 GEN_LOAD_REG_TN(T0, fr);
@@ -5874,26 +5862,12 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, @@ -5874,26 +5862,12 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5874 ctx.bstate = BS_NONE; 5862 ctx.bstate = BS_NONE;
5875 /* Restore delay slot state from the tb context. */ 5863 /* Restore delay slot state from the tb context. */
5876 ctx.hflags = tb->flags; 5864 ctx.hflags = tb->flags;
5877 - ctx.saved_hflags = ctx.hflags;  
5878 - switch (ctx.hflags & MIPS_HFLAG_BMASK) {  
5879 - case MIPS_HFLAG_BR:  
5880 - gen_op_restore_breg_target();  
5881 - break;  
5882 - case MIPS_HFLAG_B:  
5883 - ctx.btarget = env->btarget;  
5884 - break;  
5885 - case MIPS_HFLAG_BC:  
5886 - case MIPS_HFLAG_BL:  
5887 - ctx.btarget = env->btarget;  
5888 - gen_op_restore_bcond();  
5889 - break;  
5890 - } 5865 + restore_cpu_state(env, &ctx);
5891 #if defined(CONFIG_USER_ONLY) 5866 #if defined(CONFIG_USER_ONLY)
5892 ctx.mem_idx = 0; 5867 ctx.mem_idx = 0;
5893 #else 5868 #else
5894 ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM); 5869 ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
5895 #endif 5870 #endif
5896 - ctx.CP0_Status = env->CP0_Status;  
5897 #ifdef DEBUG_DISAS 5871 #ifdef DEBUG_DISAS
5898 if (loglevel & CPU_LOG_TB_CPU) { 5872 if (loglevel & CPU_LOG_TB_CPU) {
5899 fprintf(logfile, "------------------------------------------------\n"); 5873 fprintf(logfile, "------------------------------------------------\n");