summaryrefslogtreecommitdiffstats
path: root/target-ppc/op_helper.c
diff options
context:
space:
mode:
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-09-30 01:11:48 +0000
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-09-30 01:11:48 +0000
commitd7e4b87e53923542c1a7220e08bcae2252f5a22e (patch)
tree0d29076ef6fd68674772fcefa0382a6921f0889c /target-ppc/op_helper.c
parent477023a6038e8f457c604b138198f76d093b9a87 (diff)
downloadhqemu-d7e4b87e53923542c1a7220e08bcae2252f5a22e.zip
hqemu-d7e4b87e53923542c1a7220e08bcae2252f5a22e.tar.gz
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
Diffstat (limited to 'target-ppc/op_helper.c')
-rw-r--r--target-ppc/op_helper.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 9a79953..08441ca 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -700,6 +700,36 @@ void do_fctidz (void)
#endif
+static inline void do_fri (int rounding_mode)
+{
+ int curmode;
+
+ curmode = env->fp_status.float_rounding_mode;
+ set_float_rounding_mode(rounding_mode, &env->fp_status);
+ FT0 = float64_round_to_int(FT0, &env->fp_status);
+ set_float_rounding_mode(curmode, &env->fp_status);
+}
+
+void do_frin (void)
+{
+ do_fri(float_round_nearest_even);
+}
+
+void do_friz (void)
+{
+ do_fri(float_round_to_zero);
+}
+
+void do_frip (void)
+{
+ do_fri(float_round_up);
+}
+
+void do_frim (void)
+{
+ do_fri(float_round_down);
+}
+
#if USE_PRECISE_EMULATION
void do_fmadd (void)
{
@@ -789,6 +819,32 @@ void do_fsqrt (void)
FT0 = float64_sqrt(FT0, &env->fp_status);
}
+void do_fre (void)
+{
+ union {
+ double d;
+ uint64_t i;
+ } p;
+
+ if (likely(isnormal(FT0))) {
+ FT0 = float64_div(1.0, FT0, &env->fp_status);
+ } else {
+ p.d = FT0;
+ if (p.i == 0x8000000000000000ULL) {
+ p.i = 0xFFF0000000000000ULL;
+ } else if (p.i == 0x0000000000000000ULL) {
+ p.i = 0x7FF0000000000000ULL;
+ } else if (isnan(FT0)) {
+ p.i = 0x7FF8000000000000ULL;
+ } else if (FT0 < 0.0) {
+ p.i = 0x8000000000000000ULL;
+ } else {
+ p.i = 0x0000000000000000ULL;
+ }
+ FT0 = p.d;
+ }
+}
+
void do_fres (void)
{
union {
OpenPOWER on IntegriCloud