Revision 7c58044c target-ppc/translate.c

b/target-ppc/translate.c
32 32
//#define PPC_DEBUG_DISAS
33 33
//#define DEBUG_MEMORY_ACCESSES
34 34
//#define DO_PPC_STATISTICS
35
//#define OPTIMIZE_FPRF_UPDATE
35 36

  
36 37
/*****************************************************************************/
37 38
/* Code translation helpers                                                  */
......
50 51

  
51 52
static uint16_t *gen_opc_ptr;
52 53
static uint32_t *gen_opparam_ptr;
54
#if defined(OPTIMIZE_FPRF_UPDATE)
55
static uint16_t *gen_fprf_buf[OPC_BUF_SIZE];
56
static uint16_t **gen_fprf_ptr;
57
#endif
53 58

  
54 59
#include "gen-op.h"
55 60

  
......
117 122
GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
118 123
GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
119 124

  
120
/* Floating point condition and status register moves */
121
GEN8(gen_op_load_fpscr_T0, gen_op_load_fpscr_T0_fpscr);
122
GEN8(gen_op_store_T0_fpscr, gen_op_store_T0_fpscr_fpscr);
123
GEN8(gen_op_clear_fpscr, gen_op_clear_fpscr_fpscr);
124
static always_inline void gen_op_store_T0_fpscri (int n, uint8_t param)
125
{
126
    gen_op_set_T0(param);
127
    gen_op_store_T0_fpscr(n);
128
}
129

  
130 125
/* General purpose registers moves */
131 126
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
132 127
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
......
199 194
    gen_op_set_Rc0();
200 195
}
201 196

  
197
static always_inline void gen_reset_fpstatus (void)
198
{
199
#ifdef CONFIG_SOFTFLOAT
200
    gen_op_reset_fpstatus();
201
#endif
202
}
203

  
204
static always_inline void gen_compute_fprf (int set_fprf, int set_rc)
205
{
206
    if (set_fprf != 0) {
207
        /* This case might be optimized later */
208
#if defined(OPTIMIZE_FPRF_UPDATE)
209
        *gen_fprf_ptr++ = gen_opc_ptr;
210
#endif
211
        gen_op_compute_fprf(1);
212
        if (unlikely(set_rc))
213
            gen_op_store_T0_crf(1);
214
        gen_op_float_check_status();
215
    } else if (unlikely(set_rc)) {
216
        /* We always need to compute fpcc */
217
        gen_op_compute_fprf(0);
218
        gen_op_store_T0_crf(1);
219
        if (set_fprf)
220
            gen_op_float_check_status();
221
    }
222
}
223

  
224
static always_inline void gen_optimize_fprf (void)
225
{
226
#if defined(OPTIMIZE_FPRF_UPDATE)
227
    uint16_t **ptr;
228

  
229
    for (ptr = gen_fprf_buf; ptr != (gen_fprf_ptr - 1); ptr++)
230
        *ptr = INDEX_op_nop1;
231
    gen_fprf_ptr = gen_fprf_buf;
232
#endif
233
}
234

  
202 235
static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
203 236
{
204 237
#if defined(TARGET_PPC64)
......
497 530
    PPC_CACHE_DCBZ    = 0x0000400000000000ULL,
498 531
    /* dcbz instruction with tunable cache line size                         */
499 532
    PPC_CACHE_DCBZT   = 0x0000800000000000ULL,
533
    /* frsqrtes extension                                                    */
534
    PPC_FLOAT_FRSQRTES = 0x0001000000000000ULL,
500 535
};
501 536

  
502 537
/*****************************************************************************/
......
1656 1691
#endif
1657 1692

  
1658 1693
/***                       Floating-Point arithmetic                       ***/
1659
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, type)                     \
1694
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
1660 1695
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
1661 1696
{                                                                             \
1662 1697
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1663 1698
        GEN_EXCP_NO_FP(ctx);                                                  \
1664 1699
        return;                                                               \
1665 1700
    }                                                                         \
1666
    gen_op_reset_scrfx();                                                     \
1667 1701
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1668 1702
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1669 1703
    gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
1704
    gen_reset_fpstatus();                                                     \
1670 1705
    gen_op_f##op();                                                           \
1671 1706
    if (isfloat) {                                                            \
1672 1707
        gen_op_frsp();                                                        \
1673 1708
    }                                                                         \
1674 1709
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1675
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1676
        gen_op_set_Rc1();                                                     \
1710
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1677 1711
}
1678 1712

  
1679
#define GEN_FLOAT_ACB(name, op2, type)                                        \
1680
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, type);                               \
1681
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, type);
1713
#define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
1714
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
1715
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
1682 1716

  
1683
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat)                     \
1684
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
1717
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1718
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1685 1719
{                                                                             \
1686 1720
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1687 1721
        GEN_EXCP_NO_FP(ctx);                                                  \
1688 1722
        return;                                                               \
1689 1723
    }                                                                         \
1690
    gen_op_reset_scrfx();                                                     \
1691 1724
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1692 1725
    gen_op_load_fpr_FT1(rB(ctx->opcode));                                     \
1726
    gen_reset_fpstatus();                                                     \
1693 1727
    gen_op_f##op();                                                           \
1694 1728
    if (isfloat) {                                                            \
1695 1729
        gen_op_frsp();                                                        \
1696 1730
    }                                                                         \
1697 1731
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1698
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1699
        gen_op_set_Rc1();                                                     \
1732
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1700 1733
}
1701
#define GEN_FLOAT_AB(name, op2, inval)                                        \
1702
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0);                               \
1703
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
1734
#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
1735
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
1736
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1704 1737

  
1705
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat)                     \
1706
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
1738
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1739
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1707 1740
{                                                                             \
1708 1741
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1709 1742
        GEN_EXCP_NO_FP(ctx);                                                  \
1710 1743
        return;                                                               \
1711 1744
    }                                                                         \
1712
    gen_op_reset_scrfx();                                                     \
1713 1745
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1714 1746
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1747
    gen_reset_fpstatus();                                                     \
1715 1748
    gen_op_f##op();                                                           \
1716 1749
    if (isfloat) {                                                            \
1717 1750
        gen_op_frsp();                                                        \
1718 1751
    }                                                                         \
1719 1752
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1720
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1721
        gen_op_set_Rc1();                                                     \
1753
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1722 1754
}
1723
#define GEN_FLOAT_AC(name, op2, inval)                                        \
1724
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0);                               \
1725
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
1755
#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
1756
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
1757
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1726 1758

  
1727
#define GEN_FLOAT_B(name, op2, op3, type)                                     \
1759
#define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
1728 1760
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)                        \
1729 1761
{                                                                             \
1730 1762
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1731 1763
        GEN_EXCP_NO_FP(ctx);                                                  \
1732 1764
        return;                                                               \
1733 1765
    }                                                                         \
1734
    gen_op_reset_scrfx();                                                     \
1735 1766
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1767
    gen_reset_fpstatus();                                                     \
1736 1768
    gen_op_f##name();                                                         \
1737 1769
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1738
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1739
        gen_op_set_Rc1();                                                     \
1770
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1740 1771
}
1741 1772

  
1742
#define GEN_FLOAT_BS(name, op1, op2, type)                                    \
1773
#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
1743 1774
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
1744 1775
{                                                                             \
1745 1776
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1746 1777
        GEN_EXCP_NO_FP(ctx);                                                  \
1747 1778
        return;                                                               \
1748 1779
    }                                                                         \
1749
    gen_op_reset_scrfx();                                                     \
1750 1780
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1781
    gen_reset_fpstatus();                                                     \
1751 1782
    gen_op_f##name();                                                         \
1752 1783
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1753
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1754
        gen_op_set_Rc1();                                                     \
1784
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1755 1785
}
1756 1786

  
1757 1787
/* fadd - fadds */
1758
GEN_FLOAT_AB(add, 0x15, 0x000007C0);
1788
GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
1759 1789
/* fdiv - fdivs */
1760
GEN_FLOAT_AB(div, 0x12, 0x000007C0);
1790
GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
1761 1791
/* fmul - fmuls */
1762
GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
1792
GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
1763 1793

  
1764 1794
/* fre */
1765
GEN_FLOAT_BS(re, 0x3F, 0x18, PPC_FLOAT_EXT);
1795
GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
1766 1796

  
1767 1797
/* fres */
1768
GEN_FLOAT_BS(res, 0x3B, 0x18, PPC_FLOAT_FRES);
1798
GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
1769 1799

  
1770 1800
/* frsqrte */
1771
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, PPC_FLOAT_FRSQRTE);
1801
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
1802

  
1803
/* frsqrtes */
1804
static always_inline void gen_op_frsqrtes (void)
1805
{
1806
    gen_op_frsqrte();
1807
    gen_op_frsp();
1808
}
1809
GEN_FLOAT_BS(rsqrtes, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTES);
1772 1810

  
1773 1811
/* fsel */
1774
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, PPC_FLOAT_FSEL);
1812
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
1775 1813
/* fsub - fsubs */
1776
GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
1814
GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
1777 1815
/* Optional: */
1778 1816
/* fsqrt */
1779 1817
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
......
1782 1820
        GEN_EXCP_NO_FP(ctx);
1783 1821
        return;
1784 1822
    }
1785
    gen_op_reset_scrfx();
1786 1823
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1824
    gen_reset_fpstatus();
1787 1825
    gen_op_fsqrt();
1788 1826
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1789
    if (unlikely(Rc(ctx->opcode) != 0))
1790
        gen_op_set_Rc1();
1827
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1791 1828
}
1792 1829

  
1793 1830
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
......
1796 1833
        GEN_EXCP_NO_FP(ctx);
1797 1834
        return;
1798 1835
    }
1799
    gen_op_reset_scrfx();
1800 1836
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1837
    gen_reset_fpstatus();
1801 1838
    gen_op_fsqrt();
1802 1839
    gen_op_frsp();
1803 1840
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1804
    if (unlikely(Rc(ctx->opcode) != 0))
1805
        gen_op_set_Rc1();
1841
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1806 1842
}
1807 1843

  
1808 1844
/***                     Floating-Point multiply-and-add                   ***/
1809 1845
/* fmadd - fmadds */
1810
GEN_FLOAT_ACB(madd, 0x1D, PPC_FLOAT);
1846
GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
1811 1847
/* fmsub - fmsubs */
1812
GEN_FLOAT_ACB(msub, 0x1C, PPC_FLOAT);
1848
GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
1813 1849
/* fnmadd - fnmadds */
1814
GEN_FLOAT_ACB(nmadd, 0x1F, PPC_FLOAT);
1850
GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
1815 1851
/* fnmsub - fnmsubs */
1816
GEN_FLOAT_ACB(nmsub, 0x1E, PPC_FLOAT);
1852
GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
1817 1853

  
1818 1854
/***                     Floating-Point round & convert                    ***/
1819 1855
/* fctiw */
1820
GEN_FLOAT_B(ctiw, 0x0E, 0x00, PPC_FLOAT);
1856
GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
1821 1857
/* fctiwz */
1822
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, PPC_FLOAT);
1858
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
1823 1859
/* frsp */
1824
GEN_FLOAT_B(rsp, 0x0C, 0x00, PPC_FLOAT);
1860
GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
1825 1861
#if defined(TARGET_PPC64)
1826 1862
/* fcfid */
1827
GEN_FLOAT_B(cfid, 0x0E, 0x1A, PPC_64B);
1863
GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
1828 1864
/* fctid */
1829
GEN_FLOAT_B(ctid, 0x0E, 0x19, PPC_64B);
1865
GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
1830 1866
/* fctidz */
1831
GEN_FLOAT_B(ctidz, 0x0F, 0x19, PPC_64B);
1867
GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
1832 1868
#endif
1833 1869

  
1834 1870
/* frin */
1835
GEN_FLOAT_B(rin, 0x08, 0x0C, PPC_FLOAT_EXT);
1871
GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
1836 1872
/* friz */
1837
GEN_FLOAT_B(riz, 0x08, 0x0D, PPC_FLOAT_EXT);
1873
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
1838 1874
/* frip */
1839
GEN_FLOAT_B(rip, 0x08, 0x0E, PPC_FLOAT_EXT);
1875
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
1840 1876
/* frim */
1841
GEN_FLOAT_B(rim, 0x08, 0x0F, PPC_FLOAT_EXT);
1877
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
1842 1878

  
1843 1879
/***                         Floating-Point compare                        ***/
1844 1880
/* fcmpo */
......
1848 1884
        GEN_EXCP_NO_FP(ctx);
1849 1885
        return;
1850 1886
    }
1851
    gen_op_reset_scrfx();
1852 1887
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1853 1888
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1889
    gen_reset_fpstatus();
1854 1890
    gen_op_fcmpo();
1855 1891
    gen_op_store_T0_crf(crfD(ctx->opcode));
1892
    gen_op_float_check_status();
1856 1893
}
1857 1894

  
1858 1895
/* fcmpu */
......
1862 1899
        GEN_EXCP_NO_FP(ctx);
1863 1900
        return;
1864 1901
    }
1865
    gen_op_reset_scrfx();
1866 1902
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1867 1903
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1904
    gen_reset_fpstatus();
1868 1905
    gen_op_fcmpu();
1869 1906
    gen_op_store_T0_crf(crfD(ctx->opcode));
1907
    gen_op_float_check_status();
1870 1908
}
1871 1909

  
1872 1910
/***                         Floating-point move                           ***/
1873 1911
/* fabs */
1874
GEN_FLOAT_B(abs, 0x08, 0x08, PPC_FLOAT);
1912
/* XXX: beware that fabs never checks for NaNs nor update FPSCR */
1913
GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
1875 1914

  
1876 1915
/* fmr  - fmr. */
1916
/* XXX: beware that fmr never checks for NaNs nor update FPSCR */
1877 1917
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1878 1918
{
1879 1919
    if (unlikely(!ctx->fpu_enabled)) {
1880 1920
        GEN_EXCP_NO_FP(ctx);
1881 1921
        return;
1882 1922
    }
1883
    gen_op_reset_scrfx();
1884 1923
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1885 1924
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1886
    if (unlikely(Rc(ctx->opcode) != 0))
1887
        gen_op_set_Rc1();
1925
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
1888 1926
}
1889 1927

  
1890 1928
/* fnabs */
1891
GEN_FLOAT_B(nabs, 0x08, 0x04, PPC_FLOAT);
1929
/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
1930
GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
1892 1931
/* fneg */
1893
GEN_FLOAT_B(neg, 0x08, 0x01, PPC_FLOAT);
1932
/* XXX: beware that fneg never checks for NaNs nor update FPSCR */
1933
GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
1894 1934

  
1895 1935
/***                  Floating-Point status & ctrl register                ***/
1896 1936
/* mcrfs */
1897 1937
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1898 1938
{
1939
    int bfa;
1940

  
1899 1941
    if (unlikely(!ctx->fpu_enabled)) {
1900 1942
        GEN_EXCP_NO_FP(ctx);
1901 1943
        return;
1902 1944
    }
1903
    gen_op_load_fpscr_T0(crfS(ctx->opcode));
1945
    gen_optimize_fprf();
1946
    bfa = 4 * (7 - crfS(ctx->opcode));
1947
    gen_op_load_fpscr_T0(bfa);
1904 1948
    gen_op_store_T0_crf(crfD(ctx->opcode));
1905
    gen_op_clear_fpscr(crfS(ctx->opcode));
1949
    gen_op_fpscr_resetbit(~(0xF << bfa));
1906 1950
}
1907 1951

  
1908 1952
/* mffs */
......
1912 1956
        GEN_EXCP_NO_FP(ctx);
1913 1957
        return;
1914 1958
    }
1915
    gen_op_load_fpscr();
1959
    gen_optimize_fprf();
1960
    gen_reset_fpstatus();
1961
    gen_op_load_fpscr_FT0();
1916 1962
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1917
    if (unlikely(Rc(ctx->opcode) != 0))
1918
        gen_op_set_Rc1();
1963
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
1919 1964
}
1920 1965

  
1921 1966
/* mtfsb0 */
......
1927 1972
        GEN_EXCP_NO_FP(ctx);
1928 1973
        return;
1929 1974
    }
1930
    crb = crbD(ctx->opcode) >> 2;
1931
    gen_op_load_fpscr_T0(crb);
1932
    gen_op_andi_T0(~(1 << (crbD(ctx->opcode) & 0x03)));
1933
    gen_op_store_T0_fpscr(crb);
1934
    if (unlikely(Rc(ctx->opcode) != 0))
1935
        gen_op_set_Rc1();
1975
    crb = 32 - (crbD(ctx->opcode) >> 2);
1976
    gen_optimize_fprf();
1977
    gen_reset_fpstatus();
1978
    if (likely(crb != 30 && crb != 29))
1979
        gen_op_fpscr_resetbit(~(1 << crb));
1980
    if (unlikely(Rc(ctx->opcode) != 0)) {
1981
        gen_op_load_fpcc();
1982
        gen_op_set_Rc0();
1983
    }
1936 1984
}
1937 1985

  
1938 1986
/* mtfsb1 */
......
1944 1992
        GEN_EXCP_NO_FP(ctx);
1945 1993
        return;
1946 1994
    }
1947
    crb = crbD(ctx->opcode) >> 2;
1948
    gen_op_load_fpscr_T0(crb);
1949
    gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1950
    gen_op_store_T0_fpscr(crb);
1951
    if (unlikely(Rc(ctx->opcode) != 0))
1952
        gen_op_set_Rc1();
1995
    crb = 32 - (crbD(ctx->opcode) >> 2);
1996
    gen_optimize_fprf();
1997
    gen_reset_fpstatus();
1998
    /* XXX: we pretend we can only do IEEE floating-point computations */
1999
    if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI))
2000
        gen_op_fpscr_setbit(crb);
2001
    if (unlikely(Rc(ctx->opcode) != 0)) {
2002
        gen_op_load_fpcc();
2003
        gen_op_set_Rc0();
2004
    }
2005
    /* We can raise a differed exception */
2006
    gen_op_float_check_status();
1953 2007
}
1954 2008

  
1955 2009
/* mtfsf */
......
1959 2013
        GEN_EXCP_NO_FP(ctx);
1960 2014
        return;
1961 2015
    }
2016
    gen_optimize_fprf();
1962 2017
    gen_op_load_fpr_FT0(rB(ctx->opcode));
2018
    gen_reset_fpstatus();
1963 2019
    gen_op_store_fpscr(FM(ctx->opcode));
1964
    if (unlikely(Rc(ctx->opcode) != 0))
1965
        gen_op_set_Rc1();
2020
    if (unlikely(Rc(ctx->opcode) != 0)) {
2021
        gen_op_load_fpcc();
2022
        gen_op_set_Rc0();
2023
    }
2024
    /* We can raise a differed exception */
2025
    gen_op_float_check_status();
1966 2026
}
1967 2027

  
1968 2028
/* mtfsfi */
1969 2029
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1970 2030
{
2031
    int bf, sh;
2032

  
1971 2033
    if (unlikely(!ctx->fpu_enabled)) {
1972 2034
        GEN_EXCP_NO_FP(ctx);
1973 2035
        return;
1974 2036
    }
1975
    gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
1976
    if (unlikely(Rc(ctx->opcode) != 0))
1977
        gen_op_set_Rc1();
2037
    bf = crbD(ctx->opcode) >> 2;
2038
    sh = 7 - bf;
2039
    gen_optimize_fprf();
2040
    gen_op_set_FT0(FPIMM(ctx->opcode) << (4 * sh));
2041
    gen_reset_fpstatus();
2042
    gen_op_store_fpscr(1 << sh);
2043
    if (unlikely(Rc(ctx->opcode) != 0)) {
2044
        gen_op_load_fpcc();
2045
        gen_op_set_Rc0();
2046
    }
2047
    /* We can raise a differed exception */
2048
    gen_op_float_check_status();
1978 2049
}
1979 2050

  
1980 2051
/***                           Addressing modes                            ***/
......
6717 6788
    gen_opc_ptr = gen_opc_buf;
6718 6789
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6719 6790
    gen_opparam_ptr = gen_opparam_buf;
6791
#if defined(OPTIMIZE_FPRF_UPDATE)
6792
    gen_fprf_ptr = gen_fprf_buf;
6793
#endif
6720 6794
    nb_gen_labels = 0;
6721 6795
    ctx.nip = pc_start;
6722 6796
    ctx.tb = tb;

Also available in: Unified diff