[i386] Parity Flag Not Set On xor %eax,%eax

Bug #1267955 reported by Chris P
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
QEMU
Fix Released
Undecided
Unassigned

Bug Description

Tested against qemu-1.7.0 as well as qemu-1.7.50 on Debian Sid

Steps To Reproduce

$ cat > prog.hex << EOF

7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
02 00 03 00 01 00 00 00 54 80 04 08 34 00 00 00
00 00 00 00 00 00 00 00 34 00 20 00 01 00 28 00
00 00 00 00 01 00 00 00 00 00 00 00 00 80 04 08
00 80 04 08 76 00 00 00 76 00 00 00 05 00 00 00
00 10 00 00

31 c0
9c

b8 04 00 00 00
bb 01 00 00 00
89 e1
ba 04 00 00 00
cd 80

b8 01 00 00 00
bb 00 00 00 00
cd 80

EOF

$ xxd -p -r prog.hex > prog
$ chmod 700 prog

$ ./prog | hexdump -vC
00000000 46 02 00 00 |F...|
00000004

$ qemu-i386 ./prog | hexdump -vC
00000000 42 02 00 00 |B...|
00000004

On the other hand if [xor %eax, %eax] (31 c0) is replaced with sub %eax,%eax (29 c0), then the parity flag is set correctly.

Revision history for this message
Richard Henderson (rth) wrote : [PATCH] target-i386: Fix CC_OP_CLR vs PF

Parity should be set for a zero result.

Signed-off-by: Richard Henderson <email address hidden>
---
 target-i386/cc_helper.c | 2 +-
 target-i386/translate.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-i386/cc_helper.c b/target-i386/cc_helper.c
index ee04092..05dd12b 100644
--- a/target-i386/cc_helper.c
+++ b/target-i386/cc_helper.c
@@ -103,7 +103,7 @@ target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1,
     case CC_OP_EFLAGS:
         return src1;
     case CC_OP_CLR:
- return CC_Z;
+ return CC_Z | CC_P;

     case CC_OP_MULB:
         return compute_all_mulb(dst, src1);
diff --git a/target-i386/translate.c b/target-i386/translate.c
index b0f2279..34f35e7 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -748,7 +748,7 @@ static void gen_compute_eflags(DisasContext *s)
         return;
     }
     if (s->cc_op == CC_OP_CLR) {
- tcg_gen_movi_tl(cpu_cc_src, CC_Z);
+ tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P);
         set_cc_op(s, CC_OP_EFLAGS);
         return;
     }
--
1.8.4.2

Revision history for this message
Edgar E. Iglesias (edgar-iglesias) wrote : Re: [Qemu-devel] [PATCH] target-i386: Fix CC_OP_CLR vs PF

On Fri, Jan 10, 2014 at 12:39:56PM -0800, Richard Henderson wrote:
> Parity should be set for a zero result.
>
> Signed-off-by: Richard Henderson <email address hidden>

Reviewed-by: Edgar E. Iglesias <email address hidden>

> ---
> target-i386/cc_helper.c | 2 +-
> target-i386/translate.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/target-i386/cc_helper.c b/target-i386/cc_helper.c
> index ee04092..05dd12b 100644
> --- a/target-i386/cc_helper.c
> +++ b/target-i386/cc_helper.c
> @@ -103,7 +103,7 @@ target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1,
> case CC_OP_EFLAGS:
> return src1;
> case CC_OP_CLR:
> - return CC_Z;
> + return CC_Z | CC_P;
>
> case CC_OP_MULB:
> return compute_all_mulb(dst, src1);
> diff --git a/target-i386/translate.c b/target-i386/translate.c
> index b0f2279..34f35e7 100644
> --- a/target-i386/translate.c
> +++ b/target-i386/translate.c
> @@ -748,7 +748,7 @@ static void gen_compute_eflags(DisasContext *s)
> return;
> }
> if (s->cc_op == CC_OP_CLR) {
> - tcg_gen_movi_tl(cpu_cc_src, CC_Z);
> + tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P);
> set_cc_op(s, CC_OP_EFLAGS);
> return;
> }
> --
> 1.8.4.2
>
>

Revision history for this message
Michael Roth (mdroth) wrote :

Quoting Richard Henderson (2014-01-10 14:39:56)
> Parity should be set for a zero result.
>
> Signed-off-by: Richard Henderson <email address hidden>

ping for 1.7.1

> ---
> target-i386/cc_helper.c | 2 +-
> target-i386/translate.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/target-i386/cc_helper.c b/target-i386/cc_helper.c
> index ee04092..05dd12b 100644
> --- a/target-i386/cc_helper.c
> +++ b/target-i386/cc_helper.c
> @@ -103,7 +103,7 @@ target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1,
> case CC_OP_EFLAGS:
> return src1;
> case CC_OP_CLR:
> - return CC_Z;
> + return CC_Z | CC_P;
>
> case CC_OP_MULB:
> return compute_all_mulb(dst, src1);
> diff --git a/target-i386/translate.c b/target-i386/translate.c
> index b0f2279..34f35e7 100644
> --- a/target-i386/translate.c
> +++ b/target-i386/translate.c
> @@ -748,7 +748,7 @@ static void gen_compute_eflags(DisasContext *s)
> return;
> }
> if (s->cc_op == CC_OP_CLR) {
> - tcg_gen_movi_tl(cpu_cc_src, CC_Z);
> + tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P);
> set_cc_op(s, CC_OP_EFLAGS);
> return;
> }
> --
> 1.8.4.2

Revision history for this message
Thomas Huth (th-huth) wrote :
Changed in qemu:
status: New → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.