From: Simon Scherer <[email protected]>

FXCH ST(i) exchanges the contents of ST(0) and ST(i). Both registers
receive a new value, so both should end up marked valid in the FPU tag
word, regardless of what they were tagged before the swap.

helper_fxchg_ST0_STN() swaps the two values but never touches either
register's tag. So if either register happened to be tagged empty
beforehand, it is still wrongly tagged empty afterwards.

Mark both ST0 and ST(st_index) valid after the swap.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4400
Signed-off-by: Simon Scherer <[email protected]>
Link: 
https://lore.kernel.org/r/[email protected]
Signed-off-by: Paolo Bonzini <[email protected]>
---
 target/i386/tcg/fpu_helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index f42448ab206..2149f4b1d20 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -521,6 +521,9 @@ void helper_fxchg_ST0_STN(CPUX86State *env, int st_index)
     ST(st_index) = ST0;
     ST0 = tmp;
 
+    env->fptags[env->fpstt] = 0;
+    env->fptags[(env->fpstt + st_index) & 7] = 0;
+
     /* C1 is unconditionally cleared to 0 */
     env->fpus &= ~0x0200;
 }
-- 
2.55.0


Reply via email to