diff mbox

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

Message ID 185941415708979@web10m.yandex.ru
State New
Headers show

Commit Message

Dmitry Poletaev Nov. 11, 2014, 12:29 p.m. UTC
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(-)

Comments

Richard Henderson Nov. 12, 2014, 7:47 a.m. UTC | #1
On 11/11/2014 01:29 PM, Dmitry Poletaev wrote:
> 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(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~
diff mbox

Patch

diff --git a/target-i386/fpu_helper.c b/target-i386/fpu_helper.c
index ab19b71..fc25a03 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) & float_flag_invalid) {
+        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) & float_flag_invalid) {
+        val = 0x8000000000000000ULL;
+    }
+    set_float_exception_flags(get_float_exception_flags(&env->fp_status)
+                                | old_exp_flags, &env->fp_status);
     return val;
 }