aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/x86_emulate.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2007-12-05 10:34:15 +0000
committerKeir Fraser <keir.fraser@citrix.com>2007-12-05 10:34:15 +0000
commit184fc7781500b64586c94c50de6e61539046dbcd (patch)
tree6d490e45d1dd107887e4e030d6edce4af69be303 /xen/arch/x86/x86_emulate.c
parent2866a90337b6298cebb62fd9daba6927cc8ed904 (diff)
downloadxen-184fc7781500b64586c94c50de6e61539046dbcd.tar.gz
xen-184fc7781500b64586c94c50de6e61539046dbcd.tar.bz2
xen-184fc7781500b64586c94c50de6e61539046dbcd.zip
x86_emulate: EFLAGS.PF only reflects least-significant byte of result,
so even_parity() can return to its original prototype. Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen/arch/x86/x86_emulate.c')
-rw-r--r--xen/arch/x86/x86_emulate.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c
index 20f6cec5b5..66ea5a8454 100644
--- a/xen/arch/x86/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate.c
@@ -508,11 +508,14 @@ do { \
} \
})
-/* Given longword has even parity (even number of 1s)? */
-static int even_parity(unsigned long v)
+/*
+ * Given byte has even parity (even number of 1s)? SDM Vol. 1 Sec. 3.4.3.1,
+ * "Status Flags": EFLAGS.PF reflects parity of least-sig. byte of result only.
+ */
+static int even_parity(uint8_t v)
{
- asm ( "test %0,%0; setp %b0" : "=a" (v) : "0" (v) );
- return (uint8_t)v;
+ asm ( "test %b0,%b0; setp %b0" : "=a" (v) : "0" (v) );
+ return v;
}
/* Update address held in a register, based on addressing mode. */
@@ -1915,7 +1918,7 @@ x86_emulate(
_regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
_regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
_regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0;
- _regs.eflags |= even_parity((uint8_t)_regs.eax) ? EFLG_PF : 0;
+ _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0;
break;
}
@@ -1939,7 +1942,7 @@ x86_emulate(
_regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
_regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
_regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0;
- _regs.eflags |= even_parity((uint8_t)_regs.eax) ? EFLG_PF : 0;
+ _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0;
break;
}
@@ -2405,7 +2408,7 @@ x86_emulate(
_regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
_regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
_regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0;
- _regs.eflags |= even_parity((uint8_t)_regs.eax) ? EFLG_PF : 0;
+ _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0;
break;
}
@@ -2417,7 +2420,7 @@ x86_emulate(
_regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
_regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
_regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0;
- _regs.eflags |= even_parity((uint8_t)_regs.eax) ? EFLG_PF : 0;
+ _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0;
break;
}