aboutsummaryrefslogtreecommitdiff
path: root/target-i386
diff options
context:
space:
mode:
authorDmitry Poletaev <poletaev-qemu@yandex.ru>2014-11-11 15:29:39 +0300
committerRichard Henderson <rth@twiddle.net>2014-12-14 16:34:29 -0600
commitea32aaf1a72af102b855317b47a22e75ac2965a9 (patch)
tree52bc0534b56cff7b08a76c788ba86493d6ccd3e4 /target-i386
parent99c9c3cb24e566258a0a141178934f9cb5198842 (diff)
downloadqemu-ea32aaf1a72af102b855317b47a22e75ac2965a9.zip
qemu-ea32aaf1a72af102b855317b47a22e75ac2965a9.tar.gz
qemu-ea32aaf1a72af102b855317b47a22e75ac2965a9.tar.bz2
target-i386: Wrong conversion infinity from float80 to int32/int64
Signed-off-by: Dmitry Poletaev <poletaev-qemu@yandex.ru> Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-i386')
-rw-r--r--target-i386/fpu_helper.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/target-i386/fpu_helper.c b/target-i386/fpu_helper.c
index 1d4eee3..8768e1c 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;
+ signed char old_exp_flags;
- val = floatx80_to_int64(ST0, &env->fp_status);
+ 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;
}