From patchwork Tue Feb 19 17:40:18 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 221890 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B05AC2C0297 for ; Wed, 20 Feb 2013 08:07:20 +1100 (EST) Received: from localhost ([::1]:56900 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U7riD-0000wP-Hj for incoming@patchwork.ozlabs.org; Tue, 19 Feb 2013 13:14:41 -0500 Received: from eggs.gnu.org ([208.118.235.92]:57626) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U7ri0-0000tF-MU for qemu-devel@nongnu.org; Tue, 19 Feb 2013 13:14:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1U7rht-000338-Q0 for qemu-devel@nongnu.org; Tue, 19 Feb 2013 13:14:28 -0500 Received: from mail-da0-f44.google.com ([209.85.210.44]:56527) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U7rCY-0008I0-Vz for qemu-devel@nongnu.org; Tue, 19 Feb 2013 12:41:59 -0500 Received: by mail-da0-f44.google.com with SMTP id z20so3075815dae.3 for ; Tue, 19 Feb 2013 09:41:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:sender:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references; bh=ylxHi+qTQ/vUAeyyX6ZaBi345BpFtU2beALiCRLMyHA=; b=RZxaZk6pk9882JddDqSa0pyW1LPaE/m16uYnXNneULw4+KyoJIMcH8oph9jbse7F7Q KAM1AnkNXj3YWs9wtZRH/TNVvcZKVw244vRRjiDYAnGXkF+0jY34IyHUEffVskcPHQQx X495hUwwZ1TQne4JEryKy6FcwXaKuhkJYpLID6uDeNfyAOkuNGzIt8oTeo28rWBHBHBE 0LqcscQqoQqlQ2EicQ0COMhTEJ2ma0yuWhO3XhWfDpDdQ+bVKcrjLR+I6kz2d6ilX8VD D0BIUpup8xMD6CqY5kLzZNO0N5f+ia3bsQeUuDASM+IcvmT17Tw4OaI6UijPSUNXQ8f/ YKGg== X-Received: by 10.66.76.41 with SMTP id h9mr47796217paw.1.1361295718302; Tue, 19 Feb 2013 09:41:58 -0800 (PST) Received: from anchor.twiddle.net (50-194-63-110-static.hfc.comcastbusiness.net. [50.194.63.110]) by mx.google.com with ESMTPS id 1sm18659295pbg.18.2013.02.19.09.41.56 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 19 Feb 2013 09:41:57 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Tue, 19 Feb 2013 09:40:18 -0800 Message-Id: <1361295631-21316-45-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1361295631-21316-1-git-send-email-rth@twiddle.net> References: <1361295631-21316-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.210.44 Cc: blauwirbel@gmail.com, pbonzini@redhat.com, afaerber@suse.de, aurelien@aurel32.net Subject: [Qemu-devel] [PATCH 44/57] target-i386: Decode the VEX prefixes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org No actual required uses of these encodings yet. Signed-off-by: Richard Henderson --- target-i386/translate.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/target-i386/translate.c b/target-i386/translate.c index e5cda94..f824b99 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -37,6 +37,7 @@ #define PREFIX_LOCK 0x04 #define PREFIX_DATA 0x08 #define PREFIX_ADR 0x10 +#define PREFIX_VEX 0x20 #ifdef TARGET_X86_64 #define CODE64(s) ((s)->code64) @@ -98,6 +99,8 @@ typedef struct DisasContext { int code64; /* 64 bit code segment */ int rex_x, rex_b; #endif + int vex_l; /* vex vector length */ + int vex_v; /* vex vvvv register, without 1's compliment. */ int ss32; /* 32 bit stack segment */ CCOp cc_op; /* current CC operation */ bool cc_op_dirty; @@ -4264,6 +4267,8 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, x86_64_hregs = 0; #endif s->rip_offset = 0; /* for relative ip address */ + s->vex_l = 0; + s->vex_v = 0; next_byte: b = cpu_ldub_code(env, s->pc); s->pc++; @@ -4315,6 +4320,63 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, } break; #endif + case 0xc5: /* 2-byte VEX */ + case 0xc4: /* 3-byte VEX */ + /* VEX prefixes cannot be used except in 32-bit mode. + Otherwise the instruction is LES or LDS. */ + if (s->code32 && !s->vm86) { + static const int pp_prefix[4] = { + 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ + }; + int vex3, vex2 = cpu_ldub_code(env, s->pc); + + if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) { + /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b, + otherwise the instruction is LES or LDS. */ + break; + } + s->pc++; + + /* 4.1.1-4.1.3: No preceeding lock, 66, f2, f3, or rex prefixes. */ + if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ + | PREFIX_LOCK | PREFIX_DATA)) { + goto illegal_op; + } +#ifdef TARGET_X86_64 + if (x86_64_hregs) { + goto illegal_op; + } +#endif + rex_r = (~vex2 >> 4) & 8; + if (b == 0xc5) { + vex3 = vex2; + b = cpu_ldub_code(env, s->pc++); + } else { +#ifdef TARGET_X86_64 + s->rex_x = (~vex2 >> 3) & 8; + s->rex_b = (~vex2 >> 2) & 8; +#endif + vex3 = cpu_ldub_code(env, s->pc++); + rex_w = (vex3 >> 7) & 1; + switch (vex2 & 0x1f) { + case 0x01: /* Implied 0f leading opcode bytes. */ + b = cpu_ldub_code(env, s->pc++) | 0x100; + break; + case 0x02: /* Implied 0f 38 leading opcode bytes. */ + b = 0x138; + break; + case 0x03: /* Implied 0f 3a leading opcode bytes. */ + b = 0x13a; + break; + default: /* Reserved for future use. */ + goto illegal_op; + } + } + s->vex_v = (~vex3 >> 3) & 0xf; + s->vex_l = (vex3 >> 2) & 1; + prefixes |= pp_prefix[vex3 & 3] | PREFIX_VEX; + } + break; } /* Post-process prefixes. */ @@ -5461,13 +5523,11 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, } break; case 0xc4: /* les Gv */ - if (CODE64(s)) - goto illegal_op; + /* In CODE64 this is VEX3; see above. */ op = R_ES; goto do_lxx; case 0xc5: /* lds Gv */ - if (CODE64(s)) - goto illegal_op; + /* In CODE64 this is VEX2; see above. */ op = R_DS; goto do_lxx; case 0x1b2: /* lss Gv */