Patchwork [10/20] target-i386: fix helper_fscale() wrt softfloat

login
register
mail settings
Submitter Aurelien Jarno
Date April 18, 2011, 9 p.m.
Message ID <1303160412-8107-11-git-send-email-aurelien@aurel32.net>
Download mbox | patch
Permalink /patch/91856/
State New
Headers show

Comments

Aurelien Jarno - April 18, 2011, 9 p.m.
Use the scalbn softfloat function to implement helper_fscale(). This
fixes corner cases (e.g. NaN) and makes a few more GNU libc math tests
to pass.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/exec.h      |    4 ++++
 target-i386/op_helper.c |    7 ++++++-
 2 files changed, 10 insertions(+), 1 deletions(-)
Peter Maydell - April 19, 2011, 4:57 p.m.
On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Use the scalbn softfloat function to implement helper_fscale(). This
> fixes corner cases (e.g. NaN) and makes a few more GNU libc math tests
> to pass.
>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

-- PMM

Patch

diff --git a/target-i386/exec.h b/target-i386/exec.h
index ae6b947..211cc8c 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -115,9 +115,11 @@  static inline void svm_check_intercept(uint32_t type)
 #define floatx_sub floatx80_sub
 #define floatx_abs floatx80_abs
 #define floatx_chs floatx80_chs
+#define floatx_scalbn floatx80_scalbn
 #define floatx_round_to_int floatx80_round_to_int
 #define floatx_compare floatx80_compare
 #define floatx_compare_quiet floatx80_compare_quiet
+#define floatx_is_any_nan floatx80_is_any_nan
 #else
 #define floatx_to_int32 float64_to_int32
 #define floatx_to_int64 float64_to_int64
@@ -134,9 +136,11 @@  static inline void svm_check_intercept(uint32_t type)
 #define floatx_sub float64_sub
 #define floatx_abs float64_abs
 #define floatx_chs float64_chs
+#define floatx_scalbn float64_scalbn
 #define floatx_round_to_int float64_round_to_int
 #define floatx_compare float64_compare
 #define floatx_compare_quiet float64_compare_quiet
+#define floatx_is_any_nan float64_is_any_nan
 #endif
 
 #define RC_MASK         0xc00
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index a73427f..f614893 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4174,7 +4174,12 @@  void helper_frndint(void)
 
 void helper_fscale(void)
 {
-    ST0 = ldexp (ST0, (int)(ST1));
+    if (floatx_is_any_nan(ST1)) {
+        ST0 = ST1;
+    } else {
+        int n = floatx_to_int32_round_to_zero(ST1, &env->fp_status);
+        ST0 = floatx_scalbn(ST0, n, &env->fp_status);
+    }
 }
 
 void helper_fsin(void)