Revision fd4a04eb target-mips/op.c

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)) &&

Also available in: Unified diff