diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2007-12-05 10:34:15 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2007-12-05 10:34:15 +0000 |
commit | 184fc7781500b64586c94c50de6e61539046dbcd (patch) | |
tree | 6d490e45d1dd107887e4e030d6edce4af69be303 /xen/arch/x86/x86_emulate.c | |
parent | 2866a90337b6298cebb62fd9daba6927cc8ed904 (diff) | |
download | xen-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.c | 19 |
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; } |