Commit d7e4b87e53923542c1a7220e08bcae2252f5a22e

Authored by j_mayer
1 parent 477023a6

Implement new floating-point instructions (fre, frin, friz, frip, frim)

as defined in the PowerPC 2.04 specification.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3281 c046a42c-6fe2-441c-8c8c-71466251a162
target-ppc/op.c
... ... @@ -1701,6 +1701,13 @@ void OPPROTO op_fsqrt (void)
1701 1701 RETURN();
1702 1702 }
1703 1703  
  1704 +/* fre - fre. */
  1705 +void OPPROTO op_fre (void)
  1706 +{
  1707 + do_fre();
  1708 + RETURN();
  1709 +}
  1710 +
1704 1711 /* fres - fres. */
1705 1712 void OPPROTO op_fres (void)
1706 1713 {
... ... @@ -1806,6 +1813,30 @@ void OPPROTO op_fctidz (void)
1806 1813 }
1807 1814 #endif
1808 1815  
  1816 +void OPPROTO op_frin (void)
  1817 +{
  1818 + do_frin();
  1819 + RETURN();
  1820 +}
  1821 +
  1822 +void OPPROTO op_friz (void)
  1823 +{
  1824 + do_friz();
  1825 + RETURN();
  1826 +}
  1827 +
  1828 +void OPPROTO op_frip (void)
  1829 +{
  1830 + do_frip();
  1831 + RETURN();
  1832 +}
  1833 +
  1834 +void OPPROTO op_frim (void)
  1835 +{
  1836 + do_frim();
  1837 + RETURN();
  1838 +}
  1839 +
1809 1840 /*** Floating-Point compare ***/
1810 1841 /* fcmpu */
1811 1842 void OPPROTO op_fcmpu (void)
... ...
target-ppc/op_helper.c
... ... @@ -700,6 +700,36 @@ void do_fctidz (void)
700 700  
701 701 #endif
702 702  
  703 +static inline void do_fri (int rounding_mode)
  704 +{
  705 + int curmode;
  706 +
  707 + curmode = env->fp_status.float_rounding_mode;
  708 + set_float_rounding_mode(rounding_mode, &env->fp_status);
  709 + FT0 = float64_round_to_int(FT0, &env->fp_status);
  710 + set_float_rounding_mode(curmode, &env->fp_status);
  711 +}
  712 +
  713 +void do_frin (void)
  714 +{
  715 + do_fri(float_round_nearest_even);
  716 +}
  717 +
  718 +void do_friz (void)
  719 +{
  720 + do_fri(float_round_to_zero);
  721 +}
  722 +
  723 +void do_frip (void)
  724 +{
  725 + do_fri(float_round_up);
  726 +}
  727 +
  728 +void do_frim (void)
  729 +{
  730 + do_fri(float_round_down);
  731 +}
  732 +
703 733 #if USE_PRECISE_EMULATION
704 734 void do_fmadd (void)
705 735 {
... ... @@ -789,6 +819,32 @@ void do_fsqrt (void)
789 819 FT0 = float64_sqrt(FT0, &env->fp_status);
790 820 }
791 821  
  822 +void do_fre (void)
  823 +{
  824 + union {
  825 + double d;
  826 + uint64_t i;
  827 + } p;
  828 +
  829 + if (likely(isnormal(FT0))) {
  830 + FT0 = float64_div(1.0, FT0, &env->fp_status);
  831 + } else {
  832 + p.d = FT0;
  833 + if (p.i == 0x8000000000000000ULL) {
  834 + p.i = 0xFFF0000000000000ULL;
  835 + } else if (p.i == 0x0000000000000000ULL) {
  836 + p.i = 0x7FF0000000000000ULL;
  837 + } else if (isnan(FT0)) {
  838 + p.i = 0x7FF8000000000000ULL;
  839 + } else if (FT0 < 0.0) {
  840 + p.i = 0x8000000000000000ULL;
  841 + } else {
  842 + p.i = 0x0000000000000000ULL;
  843 + }
  844 + FT0 = p.d;
  845 + }
  846 +}
  847 +
792 848 void do_fres (void)
793 849 {
794 850 union {
... ...
target-ppc/op_helper.h
... ... @@ -94,6 +94,7 @@ void do_popcntb_64 (void);
94 94  
95 95 /* Floating-point arithmetic helpers */
96 96 void do_fsqrt (void);
  97 +void do_fre (void);
97 98 void do_fres (void);
98 99 void do_frsqrte (void);
99 100 void do_fsel (void);
... ... @@ -110,6 +111,10 @@ void do_fcfid (void);
110 111 void do_fctid (void);
111 112 void do_fctidz (void);
112 113 #endif
  114 +void do_frin (void);
  115 +void do_friz (void);
  116 +void do_frip (void);
  117 +void do_frim (void);
113 118 void do_fcmpu (void);
114 119 void do_fcmpo (void);
115 120  
... ...
target-ppc/translate.c
... ... @@ -476,6 +476,8 @@ enum {
476 476 PPC_RFMCI = 0x0000020000000000ULL,
477 477 /* user-mode DCR access, implemented in PowerPC 460 */
478 478 PPC_DCRUX = 0x0000040000000000ULL,
  479 + /* New floating-point extensions (PowerPC 2.0x) */
  480 + PPC_FLOAT_EXT = 0x0000080000000000ULL,
479 481 };
480 482  
481 483 /*****************************************************************************/
... ... @@ -1660,6 +1662,9 @@ GEN_FLOAT_AB(div, 0x12, 0x000007C0);
1660 1662 /* fmul - fmuls */
1661 1663 GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
1662 1664  
  1665 +/* fre */
  1666 +GEN_FLOAT_BS(re, 0x3F, 0x18, PPC_FLOAT_EXT);
  1667 +
1663 1668 /* fres */
1664 1669 GEN_FLOAT_BS(res, 0x3B, 0x18, PPC_FLOAT_FRES);
1665 1670  
... ... @@ -1727,6 +1732,15 @@ GEN_FLOAT_B(ctid, 0x0E, 0x19, PPC_64B);
1727 1732 GEN_FLOAT_B(ctidz, 0x0F, 0x19, PPC_64B);
1728 1733 #endif
1729 1734  
  1735 +/* frin */
  1736 +GEN_FLOAT_B(rin, 0x08, 0x0C, PPC_FLOAT_EXT);
  1737 +/* friz */
  1738 +GEN_FLOAT_B(riz, 0x08, 0x0D, PPC_FLOAT_EXT);
  1739 +/* frip */
  1740 +GEN_FLOAT_B(rip, 0x08, 0x0E, PPC_FLOAT_EXT);
  1741 +/* frim */
  1742 +GEN_FLOAT_B(rim, 0x08, 0x0F, PPC_FLOAT_EXT);
  1743 +
1730 1744 /*** Floating-Point compare ***/
1731 1745 /* fcmpo */
1732 1746 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
... ...