* [PATCH] x86emul: fold almost identical code
@ 2016-02-15 12:00 Jan Beulich
2016-02-15 13:31 ` Andrew Cooper
0 siblings, 1 reply; 2+ messages in thread
From: Jan Beulich @ 2016-02-15 12:00 UTC (permalink / raw)
To: xen-devel; +Cc: Andrew Cooper, Keir Fraser
[-- Attachment #1: Type: text/plain, Size: 3911 bytes --]
AAM/AAD as well as DAA/DAS emulation code is respectively almost
identical. Fold each pair, following what's already the case for
AAA/AAS.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -2053,46 +2053,25 @@ x86_emulate(
src.val = x86_seg_ds;
goto pop_seg;
- case 0x27: /* daa */ {
- uint8_t al = _regs.eax;
- unsigned long eflags = _regs.eflags;
- generate_exception_if(mode_64bit(), EXC_UD, -1);
- _regs.eflags &= ~(EFLG_CF|EFLG_AF);
- if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) )
- {
- *(uint8_t *)&_regs.eax += 6;
- _regs.eflags |= EFLG_AF;
- }
- if ( (al > 0x99) || (eflags & EFLG_CF) )
- {
- *(uint8_t *)&_regs.eax += 0x60;
- _regs.eflags |= EFLG_CF;
- }
- _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(_regs.eax) ? EFLG_PF : 0;
- break;
- }
-
+ case 0x27: /* daa */
case 0x2f: /* das */ {
uint8_t al = _regs.eax;
unsigned long eflags = _regs.eflags;
+
generate_exception_if(mode_64bit(), EXC_UD, -1);
- _regs.eflags &= ~(EFLG_CF|EFLG_AF);
+ _regs.eflags &= ~(EFLG_CF|EFLG_AF|EFLG_SF|EFLG_ZF|EFLG_PF);
if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) )
{
_regs.eflags |= EFLG_AF;
- if ( (al < 6) || (eflags & EFLG_CF) )
+ if ( b == 0x2f && (al < 6 || (eflags & EFLG_CF)) )
_regs.eflags |= EFLG_CF;
- *(uint8_t *)&_regs.eax -= 6;
+ *(uint8_t *)&_regs.eax += (b == 0x27) ? 6 : -6;
}
if ( (al > 0x99) || (eflags & EFLG_CF) )
{
- *(uint8_t *)&_regs.eax -= 0x60;
+ *(uint8_t *)&_regs.eax += (b == 0x27) ? 0x60 : -0x60;
_regs.eflags |= EFLG_CF;
}
- _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(_regs.eax) ? EFLG_PF : 0;
@@ -2833,24 +2812,24 @@ x86_emulate(
src.val = _regs.ecx;
goto grp2;
- case 0xd4: /* aam */ {
- unsigned int base = insn_fetch_type(uint8_t);
- uint8_t al = _regs.eax;
- generate_exception_if(mode_64bit(), EXC_UD, -1);
- generate_exception_if(base == 0, EXC_DE, -1);
- *(uint16_t *)&_regs.eax = ((al / base) << 8) | (al % base);
- _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(_regs.eax) ? EFLG_PF : 0;
- break;
- }
-
+ case 0xd4: /* aam */
case 0xd5: /* aad */ {
unsigned int base = insn_fetch_type(uint8_t);
- uint16_t ax = _regs.eax;
+
generate_exception_if(mode_64bit(), EXC_UD, -1);
- *(uint16_t *)&_regs.eax = (uint8_t)(ax + ((ax >> 8) * base));
+ if ( b & 0x01 )
+ {
+ uint16_t ax = _regs.eax;
+
+ *(uint16_t *)&_regs.eax = (uint8_t)(ax + ((ax >> 8) * base));
+ }
+ else
+ {
+ uint8_t al = _regs.eax;
+
+ generate_exception_if(!base, EXC_DE, -1);
+ *(uint16_t *)&_regs.eax = ((al / base) << 8) | (al % base);
+ }
_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;
[-- Attachment #2: x86emul-fold-code.patch --]
[-- Type: text/plain, Size: 3944 bytes --]
x86emul: fold almost identical code
AAM/AAD as well as DAA/DAS emulation code is respectively almost
identical. Fold each pair, following what's already the case for
AAA/AAS.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -2053,46 +2053,25 @@ x86_emulate(
src.val = x86_seg_ds;
goto pop_seg;
- case 0x27: /* daa */ {
- uint8_t al = _regs.eax;
- unsigned long eflags = _regs.eflags;
- generate_exception_if(mode_64bit(), EXC_UD, -1);
- _regs.eflags &= ~(EFLG_CF|EFLG_AF);
- if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) )
- {
- *(uint8_t *)&_regs.eax += 6;
- _regs.eflags |= EFLG_AF;
- }
- if ( (al > 0x99) || (eflags & EFLG_CF) )
- {
- *(uint8_t *)&_regs.eax += 0x60;
- _regs.eflags |= EFLG_CF;
- }
- _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(_regs.eax) ? EFLG_PF : 0;
- break;
- }
-
+ case 0x27: /* daa */
case 0x2f: /* das */ {
uint8_t al = _regs.eax;
unsigned long eflags = _regs.eflags;
+
generate_exception_if(mode_64bit(), EXC_UD, -1);
- _regs.eflags &= ~(EFLG_CF|EFLG_AF);
+ _regs.eflags &= ~(EFLG_CF|EFLG_AF|EFLG_SF|EFLG_ZF|EFLG_PF);
if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) )
{
_regs.eflags |= EFLG_AF;
- if ( (al < 6) || (eflags & EFLG_CF) )
+ if ( b == 0x2f && (al < 6 || (eflags & EFLG_CF)) )
_regs.eflags |= EFLG_CF;
- *(uint8_t *)&_regs.eax -= 6;
+ *(uint8_t *)&_regs.eax += (b == 0x27) ? 6 : -6;
}
if ( (al > 0x99) || (eflags & EFLG_CF) )
{
- *(uint8_t *)&_regs.eax -= 0x60;
+ *(uint8_t *)&_regs.eax += (b == 0x27) ? 0x60 : -0x60;
_regs.eflags |= EFLG_CF;
}
- _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(_regs.eax) ? EFLG_PF : 0;
@@ -2833,24 +2812,24 @@ x86_emulate(
src.val = _regs.ecx;
goto grp2;
- case 0xd4: /* aam */ {
- unsigned int base = insn_fetch_type(uint8_t);
- uint8_t al = _regs.eax;
- generate_exception_if(mode_64bit(), EXC_UD, -1);
- generate_exception_if(base == 0, EXC_DE, -1);
- *(uint16_t *)&_regs.eax = ((al / base) << 8) | (al % base);
- _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(_regs.eax) ? EFLG_PF : 0;
- break;
- }
-
+ case 0xd4: /* aam */
case 0xd5: /* aad */ {
unsigned int base = insn_fetch_type(uint8_t);
- uint16_t ax = _regs.eax;
+
generate_exception_if(mode_64bit(), EXC_UD, -1);
- *(uint16_t *)&_regs.eax = (uint8_t)(ax + ((ax >> 8) * base));
+ if ( b & 0x01 )
+ {
+ uint16_t ax = _regs.eax;
+
+ *(uint16_t *)&_regs.eax = (uint8_t)(ax + ((ax >> 8) * base));
+ }
+ else
+ {
+ uint8_t al = _regs.eax;
+
+ generate_exception_if(!base, EXC_DE, -1);
+ *(uint16_t *)&_regs.eax = ((al / base) << 8) | (al % base);
+ }
_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;
[-- Attachment #3: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] x86emul: fold almost identical code
2016-02-15 12:00 [PATCH] x86emul: fold almost identical code Jan Beulich
@ 2016-02-15 13:31 ` Andrew Cooper
0 siblings, 0 replies; 2+ messages in thread
From: Andrew Cooper @ 2016-02-15 13:31 UTC (permalink / raw)
To: Jan Beulich, xen-devel; +Cc: Keir Fraser
On 15/02/16 12:00, Jan Beulich wrote:
> AAM/AAD as well as DAA/DAS emulation code is respectively almost
> identical. Fold each pair, following what's already the case for
> AAA/AAS.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-02-15 13:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-15 12:00 [PATCH] x86emul: fold almost identical code Jan Beulich
2016-02-15 13:31 ` Andrew Cooper
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.