From patchwork Mon Feb 15 12:00:54 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 8313991 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 8D68EC02AA for ; Mon, 15 Feb 2016 12:03:53 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7D34A2034C for ; Mon, 15 Feb 2016 12:03:52 +0000 (UTC) Received: from lists.xen.org (lists.xenproject.org [50.57.142.19]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5228C2039E for ; Mon, 15 Feb 2016 12:03:51 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aVHpx-0008OJ-7u; Mon, 15 Feb 2016 12:01:05 +0000 Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aVHpv-0008OD-B6 for xen-devel@lists.xenproject.org; Mon, 15 Feb 2016 12:01:03 +0000 Received: from [193.109.254.147] by server-5.bemta-14.messagelabs.com id 30/99-23366-EFDB1C65; Mon, 15 Feb 2016 12:01:02 +0000 X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-15.tower-27.messagelabs.com!1455537659!23899492!1 X-Originating-IP: [137.65.248.74] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 7.35.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 57607 invoked from network); 15 Feb 2016 12:01:01 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-15.tower-27.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 15 Feb 2016 12:01:01 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Mon, 15 Feb 2016 05:00:59 -0700 Message-Id: <56C1CC0602000078000D20EE@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.0 Date: Mon, 15 Feb 2016 05:00:54 -0700 From: "Jan Beulich" To: "xen-devel" Mime-Version: 1.0 Cc: Andrew Cooper , Keir Fraser Subject: [Xen-devel] [PATCH] x86emul: fold almost identical code X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 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 --- 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; Reviewed-by: Andrew Cooper --- 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;