diff mbox

[V2,2/9] target-ppc: Bug: VSX Convert to Integer Should Truncate

Message ID 1396299843-7313-3-git-send-email-tommusta@gmail.com
State New
Headers show

Commit Message

Tom Musta March 31, 2014, 9:03 p.m. UTC
The various VSX Convert to Integer instructions should truncate the
floating point number to an integer value, which is equivalent to
a round-to-zero rounding mode.  The existing VSX floating point to
integer conversion helpers are erroneously using the rounding mode set
int the PowerPC Floating Point Status and Control Register (FPSCR).
This change corrects this defect by using the appropriate
float*_to_*_round_to_zero() routines fro the softfloat library.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Tested-by: Tom Musta <tommusta@gmail.com>
---
This bug was discovered when running wget, which does this:

    double maxtime;
    struct timeval tmout;
    ...
    tmout.tv_usec = 1000000 * (maxtime - (long) maxtime);

The newest PowerPC 64-bit gcc's are now using xscvdpsxds to perform the cast of
the double to long.  A timeout of 0.95 was erroneously rounding up to 1 and
hence computing a negative timeout value.

It would be great if we could still get this into 2.0.

This patch was previously included in a different thread.  These were the
changes in that thread:

V2: Restored rounding mode prior to checking exceptions per Peter Maydell's
review.

V3: Changed to use float*_to_*_round_to_zero() routines from softfloat instead
of directly tweaking and restoring the rounding mode (per Peter's review).

 target-ppc/fpu_helper.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
diff mbox

Patch

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index fd91239..691d572 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2568,7 +2568,8 @@  void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0);            \
             xt.tfld = rnan;                                                  \
         } else {                                                             \
-            xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status);              \
+            xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld,                \
+                          &env->fp_status);                                  \
             if (env->fp_status.float_exception_flags & float_flag_invalid) { \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0);        \
             }                                                                \