diff mbox

target-i386/FPU: wrong conversion infinity from float80 to int32/int64

Message ID 14098881406199446@web16j.yandex.ru
State New
Headers show

Commit Message

Dmitry Poletaev July 24, 2014, 10:57 a.m. UTC
23.07.2014, 21:13, "Peter Maydell" <peter.maydell@linaro.org>:
>  On 23 July 2014 16:04, Dmitry Poletaev <poletaev-qemu@yandex.ru> wrote:
>>   I'm understood. So, am I right?
>  Pretty much, except it's better to use the accessor functions
>  get_float_exception_flags() and set_float_exception_flags().
>>   +    if (env->fp_status.float_exception_flags & FPUS_IE) {
>>   +        val = 0x8000000000000000;
>  Also this constant needs a "ULL" suffix or it won't build on
>  32 bit hosts.
>
>  thanks
>  -- PMM

Done.

From: Dmitry Poletaev <poletaev-qemu@yandex.ru>
Signed-off-by: Dmitry Poletaev <poletaev-qemu@yandex.ru>

---
 target-i386/fpu_helper.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/target-i386/fpu_helper.c b/target-i386/fpu_helper.c
index 1b2900d..e3543a8 100644
--- a/target-i386/fpu_helper.c
+++ b/target-i386/fpu_helper.c
@@ -251,16 +251,34 @@  int32_t helper_fist_ST0(CPUX86State *env)
 int32_t helper_fistl_ST0(CPUX86State *env)
 {
     int32_t val;
-
+    signed char old_exp_flags;
+    
+    old_exp_flags = get_float_exception_flags(&env->fp_status);
+    set_float_exception_flags(0, &env->fp_status);
+    
     val = floatx80_to_int32(ST0, &env->fp_status);
+    if (get_float_exception_flags(&env->fp_status) & FPUS_IE) {
+        val = 0x80000000;
+    }
+    set_float_exception_flags(get_float_exception_flags(&env->fp_status)
+                                | old_exp_flags, &env->fp_status);
     return val;
 }
 
 int64_t helper_fistll_ST0(CPUX86State *env)
 {
     int64_t val;
-
-    val = floatx80_to_int64(ST0, &env->fp_status);
+    signed char old_exp_flags;
+    
+    old_exp_flags = get_float_exception_flags(&env->fp_status);
+    set_float_exception_flags(0, &env->fp_status);
+    
+    val = floatx80_to_int32(ST0, &env->fp_status);
+    if (get_float_exception_flags(&env->fp_status) & FPUS_IE) {
+        val = 0x8000000000000000ULL;
+    }
+    set_float_exception_flags(get_float_exception_flags(&env->fp_status)
+                                | old_exp_flags, &env->fp_status);
     return val;
 }