Revision fd4a04eb

b/target-mips/cpu.h
81 81
#define FCR0_REV 0
82 82
    /* fcsr */
83 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 87
#define GET_FP_CAUSE(reg)        (((reg) >> 12) & 0x3f)
88 88
#define GET_FP_ENABLE(reg)       (((reg) >>  7) & 0x1f)
89 89
#define GET_FP_FLAGS(reg)        (((reg) >>  2) & 0x1f)
b/target-mips/exec.h
165 165
void cpu_mips_clock_init (CPUState *env);
166 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 239
#endif /* !defined(__QEMU_MIPS_EXEC_H__) */
b/target-mips/op.c
1609 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 1631
void op_cfc1 (void)
1654 1632
{
1655 1633
    switch (T1) {
......
1675 1653

  
1676 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 1657
    DEBUG_FPU_STATE();
1711 1658
    RETURN();
1712 1659
}
......
1762 1709

  
1763 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 1713
    DEBUG_FPU_STATE();
1769 1714
    RETURN();
1770 1715
}
1771 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 1719
    DEBUG_FPU_STATE();
1777 1720
    RETURN();
1778 1721
}
1779 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 1725
    DEBUG_FPU_STATE();
1785 1726
    RETURN();
1786 1727
}
1787 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 1731
    DEBUG_FPU_STATE();
1795 1732
    RETURN();
1796 1733
}
1797 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 1737
    DEBUG_FPU_STATE();
1805 1738
    RETURN();
1806 1739
}
......
1813 1746
}
1814 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 1750
    DEBUG_FPU_STATE();
1821 1751
    RETURN();
1822 1752
}
1823 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 1756
    DEBUG_FPU_STATE();
1832 1757
    RETURN();
1833 1758
}
1834 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 1762
    DEBUG_FPU_STATE();
1840 1763
    RETURN();
1841 1764
}
1842 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 1768
    DEBUG_FPU_STATE();
1848 1769
    RETURN();
1849 1770
}
1850 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 1774
    DEBUG_FPU_STATE();
1856 1775
    RETURN();
1857 1776
}
1858 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 1780
    DEBUG_FPU_STATE();
1864 1781
    RETURN();
1865 1782
}
1866 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 1786
    DEBUG_FPU_STATE();
1872 1787
    RETURN();
1873 1788
}
1874 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 1792
    DEBUG_FPU_STATE();
1882 1793
    RETURN();
1883 1794
}
1884 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 1798
    DEBUG_FPU_STATE();
1892 1799
    RETURN();
1893 1800
}
......
1917 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 1856
FLOAT_OP(movf, d)
2093 1857
{
......
2186 1950
#define FLOAT_BINOP(name) \
2187 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 1954
    DEBUG_FPU_STATE();    \
2193 1955
    RETURN();             \
2194 1956
}                         \
2195 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 1960
    DEBUG_FPU_STATE();    \
2201 1961
    RETURN();             \
2202 1962
}                         \
2203 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 1966
    DEBUG_FPU_STATE();    \
2210 1967
    RETURN();             \
2211 1968
}
......
2217 1974

  
2218 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 1978
    DEBUG_FPU_STATE();
2225 1979
    RETURN();
2226 1980
}
......
2390 2144

  
2391 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 2184
void op_bc1f (void)
2595 2185
{
2596
    T0 = !IS_FP_COND_SET(PARAM1, env);
2186
    T0 = !!(~GET_FP_COND(env) & (0x1 << PARAM1));
2597 2187
    DEBUG_FPU_STATE();
2598 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 2193
    DEBUG_FPU_STATE();
2605 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 2199
    DEBUG_FPU_STATE();
2614 2200
    RETURN();
2615 2201
}
2616 2202

  
2617 2203
void op_bc1t (void)
2618 2204
{
2619
    T0 = IS_FP_COND_SET(PARAM1, env);
2205
    T0 = !!(GET_FP_COND(env) & (0x1 << PARAM1));
2620 2206
    DEBUG_FPU_STATE();
2621 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 2212
    DEBUG_FPU_STATE();
2628 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 2218
    DEBUG_FPU_STATE();
2637 2219
    RETURN();
2638 2220
}
......
2808 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 2393
void op_interrupt_restart (void)
2823 2394
{
2824 2395
    if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
b/target-mips/op_helper.c
598 598
}
599 599

  
600 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))
b/target-mips/translate.c
491 491
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
492 492

  
493 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 495
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
496 496
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
497 497
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
......
511 511
};                                                                      \
512 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 517
FOP_CONDS(, d)
......
525 525
    struct TranslationBlock *tb;
526 526
    target_ulong pc, saved_pc;
527 527
    uint32_t opcode;
528
    uint32_t fp_status, saved_fp_status;
528
    uint32_t fp_status;
529 529
    /* Routine used to access memory */
530 530
    int mem_idx;
531 531
    uint32_t hflags, saved_hflags;
532
    uint32_t CP0_Status;
533 532
    int bstate;
534 533
    target_ulong btarget;
535 534
} DisasContext;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff