[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] Restore FPU round state after loading the VM state
From: |
Pavel Dovgaluk |
Subject: |
[Qemu-devel] [PATCH] Restore FPU round state after loading the VM state |
Date: |
Wed, 20 Jun 2012 14:24:22 +0400 |
Restore FPU round state after loading the VM state.
This patch fixes different behavior after loading VM state
with different FPU flags set.
Signed-off-by: Pavel Dovgalyuk<address@hidden>
---
target-i386/cpu.c | 1 +
target-i386/cpu.h | 2 ++
target-i386/machine.c | 2 +-
target-i386/op_helper.c | 16 ++++++++++------
4 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index fdd95be..68d10ba 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1675,6 +1675,7 @@ static void x86_cpu_reset(CPUState *s)
env->fptags[i] = 1;
}
env->fpuc = 0x37f;
+ update_fp_status(env);
env->mxcsr = 0x1f80;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index bcf663e..6500cc8 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1086,4 +1086,6 @@ uint32_t cpu_cc_compute_all(CPUX86State *env1, int op);
void cpu_report_tpr_access(CPUX86State *env, TPRAccess access);
+void update_fp_status(CPUState *env1);
+
#endif /* CPU_I386_H */
diff --git a/target-i386/machine.c b/target-i386/machine.c
index a8be058..e79d98d 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -255,7 +255,7 @@ static int cpu_post_load(void *opaque, int version_id)
CPUX86State *env = opaque;
int i;
- /* XXX: restore FPU round state */
+ update_fp_status(env);
env->fpstt = (env->fpus_vmstate >> 11) & 7;
env->fpus = env->fpus_vmstate & ~0x3800;
env->fptag_vmstate ^= 0xff;
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index bc3b94e..552f089 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4018,12 +4018,12 @@ uint32_t helper_fnstcw(void)
return env->fpuc;
}
-static void update_fp_status(void)
+void update_fp_status(CPUState *env1)
{
int rnd_type;
/* set rounding mode */
- switch(env->fpuc & FPU_RC_MASK) {
+ switch (env1->fpuc & FPU_RC_MASK) {
default:
case FPU_RC_NEAR:
rnd_type = float_round_nearest_even;
@@ -4038,8 +4038,8 @@ static void update_fp_status(void)
rnd_type = float_round_to_zero;
break;
}
- set_float_rounding_mode(rnd_type, &env->fp_status);
- switch((env->fpuc >> 8) & 3) {
+ set_float_rounding_mode(rnd_type, &env1->fp_status);
+ switch ((env1->fpuc >> 8) & 3) {
case 0:
rnd_type = 32;
break;
@@ -4051,13 +4051,13 @@ static void update_fp_status(void)
rnd_type = 80;
break;
}
- set_floatx80_rounding_precision(rnd_type, &env->fp_status);
+ set_floatx80_rounding_precision(rnd_type, &env1->fp_status);
}
void helper_fldcw(uint32_t val)
{
env->fpuc = val;
- update_fp_status();
+ update_fp_status(env);
}
void helper_fclex(void)
@@ -4076,6 +4076,7 @@ void helper_fninit(void)
env->fpus = 0;
env->fpstt = 0;
env->fpuc = 0x37f;
+ update_fp_status(env);
env->fptags[0] = 1;
env->fptags[1] = 1;
env->fptags[2] = 1;
@@ -4494,6 +4495,7 @@ void helper_fldenv(target_ulong ptr, int data32)
fpus = lduw(ptr + 2);
fptag = lduw(ptr + 4);
}
+ update_fp_status(env);
env->fpstt = (fpus >> 11) & 7;
env->fpus = fpus & ~0x3800;
for(i = 0;i < 8; i++) {
@@ -4520,6 +4522,7 @@ void helper_fsave(target_ulong ptr, int data32)
env->fpus = 0;
env->fpstt = 0;
env->fpuc = 0x37f;
+ update_fp_status(env);
env->fptags[0] = 1;
env->fptags[1] = 1;
env->fptags[2] = 1;
@@ -4661,6 +4664,7 @@ void helper_fxrstor(target_ulong ptr, int data64)
}
env->fpuc = lduw(ptr);
+ update_fp_status(env);
fpus = lduw(ptr + 2);
fptag = lduw(ptr + 4);
env->fpstt = (fpus >> 11) & 7;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [PATCH] Restore FPU round state after loading the VM state,
Pavel Dovgaluk <=