diff mbox

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

Message ID 3654261406127876@web2h.yandex.ru
State New
Headers show

Commit Message

Dmitry Poletaev July 23, 2014, 3:04 p.m. UTC
I'm understood. So, am I right?

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

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

Comments

Peter Maydell July 23, 2014, 5:13 p.m. UTC | #1
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
Richard Henderson July 29, 2014, 7:06 p.m. UTC | #2
On 07/23/2014 05:04 AM, Dmitry Poletaev wrote:
> +    if (env->fp_status.float_exception_flags & FPUS_IE) {

Mixing bit masks.  s/FPUS_IE/float_status_invalid/


r~
Dmitry Poletaev Oct. 14, 2014, 10:38 a.m. UTC | #3
What do you mean?

29.07.2014, 23:07, "Richard Henderson" <rth@twiddle.net>:
> On 07/23/2014 05:04 AM, Dmitry Poletaev wrote:
>>  +    if (env->fp_status.float_exception_flags & FPUS_IE) {
>
> Mixing bit masks.  s/FPUS_IE/float_status_invalid/
>
> r~
Peter Maydell Oct. 14, 2014, 10:55 a.m. UTC | #4
On 14 October 2014 12:38, Dmitry Poletaev <poletaev-qemu@yandex.ru> wrote:
> 29.07.2014, 23:07, "Richard Henderson" <rth@twiddle.net>:
>> On 07/23/2014 05:04 AM, Dmitry Poletaev wrote:
>>>  +    if (env->fp_status.float_exception_flags & FPUS_IE) {
>>
>> Mixing bit masks.  s/FPUS_IE/float_status_invalid/

[Please don't top-post.]

> What do you mean?

Richard means that the set of defined flags for
float_exception_flags does not include "FPUS_IE"
(which is defining a symbolic constant for a bit
in an x86 register). You want to use "float_flag_invalid".
(The two happen to have the same value, 1, which is why
your code worked by accident.)

thanks
-- PMM
diff mbox

Patch

diff --git a/target-i386/fpu_helper.c b/target-i386/fpu_helper.c
index 1b2900d..c4fdad8 100644
--- a/target-i386/fpu_helper.c
+++ b/target-i386/fpu_helper.c
@@ -251,16 +251,31 @@  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 = env->fp_status.float_exception_flags;
+    env->fp_status.float_exception_flags = 0;
     val = floatx80_to_int32(ST0, &env->fp_status);
+    if (env->fp_status.float_exception_flags & FPUS_IE) {
+        val = 0x80000000;
+    }
+    env->fp_status.float_exception_flags |= old_exp_flags;
     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 = env->fp_status.float_exception_flags;
+    env->fp_status.float_exception_flags = 0;
+
+    val = floatx80_to_int64(ST0, &env->fp_status);    
+    if (env->fp_status.float_exception_flags & FPUS_IE) {
+        val = 0x8000000000000000;
+    }
+    env->fp_status.float_exception_flags |= old_exp_flags;
     return val;
 }