[PATCH] target/i386: Clear OF, SF, and AF for fcomi/fucomi

Simon Scherer posted 1 patch 1 month, 3 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260806145224.184019-1-scherer.simon89@gmail.com
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, Richard Henderson <richard.henderson@linaro.org>
There is a newer version of this series
target/i386/tcg/fpu_helper.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
[PATCH] target/i386: Clear OF, SF, and AF for fcomi/fucomi
Posted by Simon Scherer 1 month, 3 weeks ago
helper_fcomi_ST0_FT0() and helper_fucomi_ST0_FT0() only cleared
CC_Z, CC_P, and CC_C before merging in the comparison result,
leaving CC_O, CC_S, and CC_A untouched from whatever they were
set to beforehand.

The Intel SDM documents FCOMI/FCOMIP/FUCOMI/FUCOMIP as setting OF,
SF, and AF to 0 unconditionally. The AMD manual doesn't mention them
at all. However, testing on multiple real Intel and AMD systems confirms
all three are unconditionally cleared regardless of the comparison
result or their prior value. Widen the mask so OF/SF/AF are cleared along
with CF/ZF/PF instead of being carried over from before the instruction.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4133
Signed-off-by: Simon Scherer <scherer.simon89@gmail.com>
---
 target/i386/tcg/fpu_helper.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index 978eb1411b..215547110a 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -554,7 +554,9 @@ void helper_fcomi_ST0_FT0(CPUX86State *env)
     FloatRelation ret;
 
     ret = floatx80_compare(ST0, FT0, &env->fp_status);
-    eflags = cpu_cc_compute_all(env) & ~(CC_Z | CC_P | CC_C);
+    /* OF, SF, and AF are unconditionally cleared to 0 */
+    eflags = cpu_cc_compute_all(env) &
+                 ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
     CC_SRC = eflags | fcomi_ccval[ret + 1];
     CC_OP = CC_OP_EFLAGS;
     merge_exception_flags(env, old_flags);
@@ -567,7 +569,9 @@ void helper_fucomi_ST0_FT0(CPUX86State *env)
     FloatRelation ret;
 
     ret = floatx80_compare_quiet(ST0, FT0, &env->fp_status);
-    eflags = cpu_cc_compute_all(env) & ~(CC_Z | CC_P | CC_C);
+    /* OF, SF, and AF are unconditionally cleared to 0 */
+    eflags = cpu_cc_compute_all(env) &
+                 ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
     CC_SRC = eflags | fcomi_ccval[ret + 1];
     CC_OP = CC_OP_EFLAGS;
     merge_exception_flags(env, old_flags);
-- 
2.53.0
Re: [PATCH] target/i386: Clear OF, SF, and AF for fcomi/fucomi
Posted by Richard Henderson 1 month, 3 weeks ago
On 8/6/26 07:52, Simon Scherer wrote:
> +    /* OF, SF, and AF are unconditionally cleared to 0 */
> +    eflags = cpu_cc_compute_all(env) &
> +                 ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);

There are only 6 flags, and you have cleared all of them.
Which means you don't need to compute any of them, just

-     CC_SRC = eflags | fcomi_ccval[ret + 1];
+     CC_SRC = fcomi_ccval[ret + 1];


r~
Re: [PATCH] target/i386: Clear OF, SF, and AF for fcomi/fucomi
Posted by Simon Scherer 1 month, 3 weeks ago
Good catch, sent as v2!

On Thu, Aug 6, 2026 at 6:28 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 8/6/26 07:52, Simon Scherer wrote:
> > +    /* OF, SF, and AF are unconditionally cleared to 0 */
> > +    eflags = cpu_cc_compute_all(env) &
> > +                 ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
>
> There are only 6 flags, and you have cleared all of them.
> Which means you don't need to compute any of them, just
>
> -     CC_SRC = eflags | fcomi_ccval[ret + 1];
> +     CC_SRC = fcomi_ccval[ret + 1];
>
>
> r~